mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-02 17:06:36 +08:00
添加屏蔽协议到面板,免去手动操作
This commit is contained in:
@@ -4,7 +4,7 @@ export type SiteConfig = typeof siteConfig;
|
||||
|
||||
// 缓存相关常量
|
||||
const CACHE_PREFIX = 'vite_config_';
|
||||
const VERSION = "1.4.0";
|
||||
const VERSION = "1.4.1";
|
||||
const APP_VERSION = "1.0.3";
|
||||
|
||||
const getInitialConfig = () => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Input } from "@heroui/input";
|
||||
import { Textarea } from "@heroui/input";
|
||||
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/modal";
|
||||
import { Chip } from "@heroui/chip";
|
||||
import { Switch } from "@heroui/switch";
|
||||
import { Spinner } from "@heroui/spinner";
|
||||
import { Alert } from "@heroui/alert";
|
||||
import { Progress } from "@heroui/progress";
|
||||
@@ -28,6 +29,9 @@ interface Node {
|
||||
portSta: number;
|
||||
portEnd: number;
|
||||
version?: string;
|
||||
http?: number; // 0 关 1 开
|
||||
tls?: number; // 0 关 1 开
|
||||
socks?: number; // 0 关 1 开
|
||||
status: number; // 1: 在线, 0: 离线
|
||||
connectionStatus: 'online' | 'offline';
|
||||
systemInfo?: {
|
||||
@@ -49,6 +53,9 @@ interface NodeForm {
|
||||
serverIp: string;
|
||||
portSta: number;
|
||||
portEnd: number;
|
||||
http: number; // 0 关 1 开
|
||||
tls: number; // 0 关 1 开
|
||||
socks: number; // 0 关 1 开
|
||||
}
|
||||
|
||||
export default function NodePage() {
|
||||
@@ -61,13 +68,18 @@ export default function NodePage() {
|
||||
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
|
||||
const [deleteLoading, setDeleteLoading] = useState(false);
|
||||
const [nodeToDelete, setNodeToDelete] = useState<Node | null>(null);
|
||||
const [protocolDisabled, setProtocolDisabled] = useState(false);
|
||||
const [protocolDisabledReason, setProtocolDisabledReason] = useState('');
|
||||
const [form, setForm] = useState<NodeForm>({
|
||||
id: null,
|
||||
name: '',
|
||||
ipString: '',
|
||||
serverIp: '',
|
||||
portSta: 1000,
|
||||
portEnd: 65535
|
||||
portEnd: 65535,
|
||||
http: 0,
|
||||
tls: 0,
|
||||
socks: 0
|
||||
});
|
||||
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||
|
||||
@@ -404,6 +416,8 @@ export default function NodePage() {
|
||||
setIsEdit(false);
|
||||
setDialogVisible(true);
|
||||
resetForm();
|
||||
setProtocolDisabled(true);
|
||||
setProtocolDisabledReason('节点未在线,等待节点上线后再设置');
|
||||
};
|
||||
|
||||
// 编辑节点
|
||||
@@ -416,8 +430,14 @@ export default function NodePage() {
|
||||
ipString: node.ip ? node.ip.split(',').map(ip => ip.trim()).join('\n') : '',
|
||||
serverIp: node.serverIp || '',
|
||||
portSta: node.portSta,
|
||||
portEnd: node.portEnd
|
||||
portEnd: node.portEnd,
|
||||
http: typeof node.http === 'number' ? node.http : 1,
|
||||
tls: typeof node.tls === 'number' ? node.tls : 1,
|
||||
socks: typeof node.socks === 'number' ? node.socks : 1
|
||||
});
|
||||
const offline = node.connectionStatus !== 'online';
|
||||
setProtocolDisabled(offline);
|
||||
setProtocolDisabledReason(offline ? '节点未在线,等待节点上线后再设置' : '');
|
||||
setDialogVisible(true);
|
||||
};
|
||||
|
||||
@@ -514,7 +534,10 @@ export default function NodePage() {
|
||||
ip: ipString,
|
||||
serverIp: form.serverIp,
|
||||
portSta: form.portSta,
|
||||
portEnd: form.portEnd
|
||||
portEnd: form.portEnd,
|
||||
http: form.http,
|
||||
tls: form.tls,
|
||||
socks: form.socks
|
||||
};
|
||||
|
||||
const res = await apiCall(data);
|
||||
@@ -530,7 +553,10 @@ export default function NodePage() {
|
||||
ip: ipString,
|
||||
serverIp: form.serverIp,
|
||||
portSta: form.portSta,
|
||||
portEnd: form.portEnd
|
||||
portEnd: form.portEnd,
|
||||
http: form.http,
|
||||
tls: form.tls,
|
||||
socks: form.socks
|
||||
} : n
|
||||
));
|
||||
} else {
|
||||
@@ -554,7 +580,10 @@ export default function NodePage() {
|
||||
ipString: '',
|
||||
serverIp: '',
|
||||
portSta: 1000,
|
||||
portEnd: 65535
|
||||
portEnd: 65535,
|
||||
http: 0,
|
||||
tls: 0,
|
||||
socks: 0
|
||||
});
|
||||
setErrors({});
|
||||
};
|
||||
@@ -869,8 +898,83 @@ export default function NodePage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 屏蔽协议 */}
|
||||
<div className="mt-1">
|
||||
<div className="text-sm font-medium text-default-700">屏蔽协议</div>
|
||||
<div className="text-xs text-default-500 mb-2">开启开关以屏蔽对应协议</div>
|
||||
{protocolDisabled && (
|
||||
<Alert
|
||||
color="warning"
|
||||
variant="flat"
|
||||
description={protocolDisabledReason || '等待节点上线后再设置'}
|
||||
className="mb-2"
|
||||
/>
|
||||
)}
|
||||
<div className={`grid grid-cols-1 sm:grid-cols-3 gap-3 bg-default-50 dark:bg-default-100 p-3 rounded-md border border-default-200 dark:border-default-100/30 ${protocolDisabled ? 'opacity-70' : ''}`}>
|
||||
{/* HTTP tile */}
|
||||
<div className="px-3 py-3 rounded-lg bg-white dark:bg-default-50 border border-default-200 dark:border-default-100/30 hover:border-primary-200 transition-colors">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<svg className="w-4 h-4 text-default-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M2 10h20"/></svg>
|
||||
<div className="text-sm font-medium text-default-700">HTTP</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-xs text-default-500">禁用/启用</div>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={form.http === 1}
|
||||
isDisabled={protocolDisabled}
|
||||
onValueChange={(v) => setForm(prev => ({ ...prev, http: v ? 1 : 0 }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-default-400">{form.http === 1 ? '已开启' : '已关闭'}</div>
|
||||
</div>
|
||||
|
||||
{/* TLS tile */}
|
||||
<div className="px-3 py-3 rounded-lg bg-white dark:bg-default-50 border border-default-200 dark:border-default-100/30 hover:border-primary-200 transition-colors">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<svg className="w-4 h-4 text-default-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 10V7a6 6 0 1 1 12 0v3"/><rect x="4" y="10" width="16" height="10" rx="2"/></svg>
|
||||
<div className="text-sm font-medium text-default-700">TLS</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-xs text-default-500">禁用/启用</div>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={form.tls === 1}
|
||||
isDisabled={protocolDisabled}
|
||||
onValueChange={(v) => setForm(prev => ({ ...prev, tls: v ? 1 : 0 }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-default-400">{form.tls === 1 ? '已开启' : '已关闭'}</div>
|
||||
</div>
|
||||
|
||||
{/* SOCKS tile */}
|
||||
<div className="px-3 py-3 rounded-lg bg-white dark:bg-default-50 border border-default-200 dark:border-default-100/30 hover:border-primary-200 transition-colors">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<svg className="w-4 h-4 text-default-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
<div className="text-sm font-medium text-default-700">SOCKS</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-xs text-default-500">禁用/启用</div>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={form.socks === 1}
|
||||
isDisabled={protocolDisabled}
|
||||
onValueChange={(v) => setForm(prev => ({ ...prev, socks: v ? 1 : 0 }))}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-default-400">{form.socks === 1 ? '已开启' : '已关闭'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<Alert
|
||||
color="danger"
|
||||
variant="flat"
|
||||
description="请不要在出口节点执行屏蔽协议,否则可能影响转发;屏蔽协议仅需在入口节点执行。"
|
||||
className="mt-3"
|
||||
/>
|
||||
|
||||
<Alert
|
||||
color="primary"
|
||||
|
||||
Reference in New Issue
Block a user