From cf24755375c2c123e11559db5ffeadaa1c849664 Mon Sep 17 00:00:00 2001 From: im0o <0ojixueseno0@gmail.com> Date: Mon, 10 Aug 2026 12:27:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E9=A1=B5=E5=81=9A=E5=AE=8C?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E3=80=81=E7=BC=96=E8=BE=91=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=85=A5=E7=AB=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 弹窗用原生 ,焦点捕获和 Esc 关闭是浏览器自带的,自己实现只会更差。 表单字段由那张从内核源码提取的字段表驱动:公共字段加当前类型的必填项。 20 种类型合计 398 个字段,全铺出来没人填得完,冷门的留给配置文件手写。 默认入站不再显示出站选择块——那一整块对它都是不可选的,画出来只是噪音, 换成一行说明。另外去掉了行里那根装饰线,导航把仪表盘挪到路由前面。 --- web/api.ts | 17 ++ web/nav.ts | 5 +- web/views/InboundDetail.vue | 60 ++++++- web/views/InboundForm.vue | 319 ++++++++++++++++++++++++++++++++++++ web/views/RouterPage.vue | 140 +++++++++++----- 5 files changed, 491 insertions(+), 50 deletions(-) create mode 100644 web/views/InboundForm.vue diff --git a/web/api.ts b/web/api.ts index 6388925..10d0e7b 100644 --- a/web/api.ts +++ b/web/api.ts @@ -89,6 +89,20 @@ export function latestDelay(info: ProxyInfo | undefined): number | null { return last === undefined || last === 0 ? null : last } +export interface FieldSpec { + key: string + type: 'string' | 'number' | 'boolean' | 'string[]' | 'number[]' | 'object' | 'object[]' + required: boolean + default: unknown + enum: (string | number)[] | null + note: string +} + +export interface ListenerFields { + common: FieldSpec[] + types: Record +} + export const api = { readConfig: () => request('GET', '/api/config'), @@ -102,6 +116,9 @@ export const api = { kernel: () => request<{ online: boolean; version?: string }>('GET', '/api/kernel'), + /** 入站类型的字段表,从内核源码提取,用来驱动表单。 */ + listenerFields: () => request('GET', '/api/meta/listener-fields'), + /** * 所有出站的运行时状态:协议类型、策略组当前选中了谁、最近一次延迟。 * 这些配置文件里都没有,只能问运行中的内核。 diff --git a/web/nav.ts b/web/nav.ts index 4fcee59..28631b3 100644 --- a/web/nav.ts +++ b/web/nav.ts @@ -1,8 +1,7 @@ /** * 左侧导航。 * - * 顺序按使用频率排:路由是这个工具存在的理由,放在最上面;仪表盘和连接是「看一眼」 - * 类的,中间;设置很少动,垫底。 + * 仪表盘打头(打开先看一眼状态),路由紧随其后(这个工具存在的理由),设置垫底。 */ import IconRoute from '~icons/ri/route-line' import IconDashboard from '~icons/ri/dashboard-line' @@ -21,8 +20,8 @@ export interface NavItem { } export const NAV: NavItem[] = [ - { key: 'router', label: '路由', icon: IconRoute }, { key: 'dashboard', label: '仪表盘', icon: IconDashboard, pending: true }, + { key: 'router', label: '路由', icon: IconRoute }, { key: 'config', label: '配置', icon: IconConfig, pending: true }, { key: 'requests', label: '请求', icon: IconRequests, pending: true }, { key: 'connections', label: '连接', icon: IconConnections, pending: true }, diff --git a/web/views/InboundDetail.vue b/web/views/InboundDetail.vue index 813d83f..a7044e5 100644 --- a/web/views/InboundDetail.vue +++ b/web/views/InboundDetail.vue @@ -3,8 +3,9 @@ import { computed } from 'vue' import type { Inbound, OutboundMode } from '@shared/inbounds.ts' import { latestDelay } from '../api' import type { ProxyInfo } from '../api' -import IconLock from '~icons/ri/lock-line' import IconOffline from '~icons/ri/cloud-off-line' +import IconEdit from '~icons/ri/edit-line' +import IconDelete from '~icons/ri/delete-bin-line' const props = defineProps<{ inbound: Inbound @@ -17,7 +18,7 @@ const props = defineProps<{ saving: boolean }>() -const emit = defineEmits<{ pick: [mode: OutboundMode] }>() +const emit = defineEmits<{ pick: [mode: OutboundMode]; edit: []; remove: [] }>() interface Option { key: string @@ -111,6 +112,13 @@ function delayClass(ms: number | null): string { {{ inbound.port }} {{ inbound.name }} +
+ + +
+
类型
{{ inbound.type }}
@@ -121,13 +129,12 @@ function delayClass(ms: number | null): string {
-
-

出站

+

+ 由 {{ inbound.legacyKey }} 声明,这种写法没有 proxy 字段,出站固定是 RULE +

-

- - 由 {{ inbound.legacyKey }} 声明,没有 proxy 字段,只能走 RULE -

+
+

出站