From be7996969a594320491437bbcf393d5fb1a78935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Thu, 29 Jan 2026 23:14:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B8=85=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/common/KeyValueEditor.vue | 118 ++++ web/src/views/website/EditView.vue | 536 ++++--------------- 2 files changed, 232 insertions(+), 422 deletions(-) create mode 100644 web/src/components/common/KeyValueEditor.vue diff --git a/web/src/components/common/KeyValueEditor.vue b/web/src/components/common/KeyValueEditor.vue new file mode 100644 index 00000000..c5914d6b --- /dev/null +++ b/web/src/components/common/KeyValueEditor.vue @@ -0,0 +1,118 @@ + + + diff --git a/web/src/views/website/EditView.vue b/web/src/views/website/EditView.vue index b53562d6..cfc10ae6 100644 --- a/web/src/views/website/EditView.vue +++ b/web/src/views/website/EditView.vue @@ -11,6 +11,7 @@ import draggable from 'vuedraggable' import cert from '@/api/panel/cert' import home from '@/api/panel/home' import website from '@/api/panel/website' +import KeyValueEditor from '@/components/common/KeyValueEditor.vue' const { $gettext } = useGettext() let messageReactive: MessageReactive | null = null @@ -248,15 +249,6 @@ const removeUpstream = (index: number) => { } } -// 为上游添加服务器 -const addServerToUpstream = (index: number) => { - const upstream = setting.value.upstreams[index] - if (!upstream.servers) { - upstream.servers = {} - } - upstream.servers[`127.0.0.1:${8080 + Object.keys(upstream.servers).length}`] = '' -} - // 更新上游超时时间值 const updateUpstreamTimeoutValue = (upstream: any, value: number) => { const parsed = parseDuration(upstream.resolver_timeout) @@ -373,61 +365,6 @@ const isCacheEnabled = (proxy: any) => { return proxy.cache !== null && proxy.cache !== undefined } -// 添加缓存有效期规则 -const addCacheValidRule = (proxy: any) => { - if (!proxy.cache) return - if (!proxy.cache.valid) proxy.cache.valid = {} - proxy.cache.valid[`any`] = '5m' -} - -// 删除缓存有效期规则 -const removeCacheValidRule = (proxy: any, codes: string) => { - if (proxy.cache?.valid) { - delete proxy.cache.valid[codes] - } -} - -// 不缓存条件选项 -const noCacheConditionOptions = [ - { label: '$cookie_nocache', value: '$cookie_nocache' }, - { label: '$arg_nocache', value: '$arg_nocache' }, - { label: '$http_pragma', value: '$http_pragma' }, - { label: '$http_authorization', value: '$http_authorization' }, - { label: '$http_cache_control', value: '$http_cache_control' } -] - -// 过期缓存使用策略选项 -const useStaleOptions = [ - { label: 'error', value: 'error' }, - { label: 'timeout', value: 'timeout' }, - { label: 'updating', value: 'updating' }, - { label: 'http_500', value: 'http_500' }, - { label: 'http_502', value: 'http_502' }, - { label: 'http_503', value: 'http_503' }, - { label: 'http_504', value: 'http_504' } -] - -// 缓存方法选项 -const cacheMethodOptions = [ - { label: 'GET', value: 'GET' }, - { label: 'HEAD', value: 'HEAD' }, - { label: 'POST', value: 'POST' } -] - -// HTTP 协议版本选项 -const httpVersionOptions = [ - { label: 'HTTP/1.0', value: '1.0' }, - { label: 'HTTP/1.1', value: '1.1' }, - { label: 'HTTP/2', value: '2' } -] - -// 大小单位选项 -const sizeUnitOptions = [ - { label: 'KB', value: 'k' }, - { label: 'MB', value: 'm' }, - { label: 'GB', value: 'g' } -] - // 从字节解析为 {value, unit} 格式 const parseSize = (bytes: number): { value: number; unit: string } => { if (!bytes || bytes <= 0) return { value: 0, unit: 'm' } @@ -459,30 +396,6 @@ const buildSize = (value: number, unit: string): number => { } } -// 重试条件选项 -const retryConditionOptions = [ - { label: 'error', value: 'error' }, - { label: 'timeout', value: 'timeout' }, - { label: 'invalid_header', value: 'invalid_header' }, - { label: 'http_500', value: 'http_500' }, - { label: 'http_502', value: 'http_502' }, - { label: 'http_503', value: 'http_503' }, - { label: 'http_504', value: 'http_504' }, - { label: 'http_429', value: 'http_429' }, - { label: 'non_idempotent', value: 'non_idempotent' }, - { label: 'off', value: 'off' } -] - -// 常见隐藏响应头选项 -const hideHeaderOptions = [ - { label: 'X-Powered-By', value: 'X-Powered-By' }, - { label: 'Server', value: 'Server' }, - { label: 'X-AspNet-Version', value: 'X-AspNet-Version' }, - { label: 'X-AspNetMvc-Version', value: 'X-AspNetMvc-Version' }, - { label: 'X-Runtime', value: 'X-Runtime' }, - { label: 'X-Version', value: 'X-Version' } -] - // 创建默认超时配置 const createDefaultTimeoutConfig = () => ({ connect: 60 * SECOND, @@ -601,13 +514,6 @@ const updateRetryTimeoutUnit = (proxy: any, unit: string) => { proxy.retry.timeout = buildDuration(parsed.value, unit) } -// 添加响应头 -const addResponseHeader = (proxy: any) => { - if (!proxy.response_headers) return - if (!proxy.response_headers.add) proxy.response_headers.add = {} - proxy.response_headers.add['X-Custom-Header'] = 'value' -} - // 删除代理 const removeProxy = (index: number) => { if (setting.value.proxies) { @@ -781,39 +687,7 @@ const realIPEnabled = computed({ } }) -// 真实 IP Header 选项 -const realIPHeaderOptions = [ - { label: 'X-Real-IP', value: 'X-Real-IP' }, - { label: 'X-Forwarded-For', value: 'X-Forwarded-For' }, - { label: 'CF-Connecting-IP', value: 'CF-Connecting-IP' }, - { label: 'True-Client-IP', value: 'True-Client-IP' }, - { label: 'Ali-Cdn-Real-Ip', value: 'Ali-Cdn-Real-Ip' }, - { label: 'EO-Connecting-IP', value: 'EO-Connecting-IP' } -] - -// 添加基本认证用户 -const addBasicAuthUser = () => { - if (!setting.value.basic_auth) { - setting.value.basic_auth = {} - } - const index = Object.keys(setting.value.basic_auth).length + 1 - setting.value.basic_auth[`user${index}`] = '' -} - -// 删除基本认证用户 -const removeBasicAuthUser = (username: string) => { - if (setting.value.basic_auth) { - delete setting.value.basic_auth[username] - } -} - // ========== 自定义配置相关 ========== -// 作用域选项 -const scopeOptions = [ - { label: $gettext('This Website'), value: 'site' }, - { label: $gettext('Global'), value: 'shared' } -] - // 添加自定义配置 const addCustomConfig = () => { if (!setting.value.custom_configs) { @@ -1007,47 +881,13 @@ const removeCustomConfig = (index: number) => { - - - - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add Server') }} - - + @@ -1178,59 +1018,26 @@ const removeCustomConfig = (index: number) => { - - - - = - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add Cache Valid Rule') }} - - + { @@ -1269,7 +1084,11 @@ const removeCustomConfig = (index: number) => { @@ -1288,58 +1107,13 @@ const removeCustomConfig = (index: number) => { - - - - = - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add Request Header') }} - - + @@ -1347,58 +1121,15 @@ const removeCustomConfig = (index: number) => { :title="$gettext('Response Content Replacement')" name="replaces" > - - - - => - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add Replacement Rule') }} - - + @@ -1412,7 +1143,11 @@ const removeCustomConfig = (index: number) => { @@ -1437,7 +1172,11 @@ const removeCustomConfig = (index: number) => { :value=" parseSize(proxy.client_max_body_size || 1024 * 1024).unit || 'm' " - :options="sizeUnitOptions" + :options="[ + { label: 'KB', value: 'k' }, + { label: 'MB', value: 'm' }, + { label: 'GB', value: 'g' } + ]" style="width: 80px" @update:value="(v: string) => updateClientMaxBodySizeUnit(proxy, v)" /> @@ -1558,7 +1297,18 @@ const removeCustomConfig = (index: number) => { @@ -1629,7 +1379,14 @@ const removeCustomConfig = (index: number) => { { /> - - - - = - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add Response Header') }} - - + @@ -2046,7 +1763,14 @@ const removeCustomConfig = (index: number) => { @@ -2065,53 +1789,15 @@ const removeCustomConfig = (index: number) => { - - - - - - {{ $gettext('Remove') }} - - - - {{ $gettext('Add User') }} - - + @@ -2156,7 +1842,13 @@ const removeCustomConfig = (index: number) => { /> - +