From 181b262a616ba02ed4cfb49c2b581d7bc7b15f95 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 20:04:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(website):=20=E6=B7=BB=E5=8A=A0"=E5=85=A8?= =?UTF-8?q?=E9=83=A8"=E5=88=86=E7=B1=BB=E3=80=81=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E6=A8=A1=E6=80=81=E6=A1=86=E6=A0=87=E9=A2=98=E5=92=8C=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=9B=E5=BB=BA=E7=B1=BB=E5=9E=8B=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20(#1329)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial plan * feat(website): 添加"全部"分类、动态模态框标题和批量创建类型支持 Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com> * refactor: 修复代码审查问题,提取正则常量和接口定义 Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: devhaozi <115467771+devhaozi@users.noreply.github.com> --- web/.gitignore | 1 + web/src/views/website/BulkCreateModal.vue | 106 +++++++++++++++++----- web/src/views/website/CreateModal.vue | 82 +++++++++++++++-- web/src/views/website/IndexView.vue | 3 +- 4 files changed, 163 insertions(+), 29 deletions(-) diff --git a/web/.gitignore b/web/.gitignore index c9b45b70..121d8eb4 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -13,6 +13,7 @@ dist dist-ssr coverage *.local +package-lock.json # Editor directories and files diff --git a/web/src/views/website/BulkCreateModal.vue b/web/src/views/website/BulkCreateModal.vue index 42c8848e..2a3f8dcf 100644 --- a/web/src/views/website/BulkCreateModal.vue +++ b/web/src/views/website/BulkCreateModal.vue @@ -5,11 +5,73 @@ import { useGettext } from 'vue3-gettext' import website from '@/api/panel/website' const show = defineModel('show', { type: Boolean, required: true }) +const type = defineModel('type', { type: String, required: true }) const { $gettext } = useGettext() const bulkCreate = ref('') +// 内部选择的类型(当外部 type 为 'all' 时使用) +const selectedType = ref('proxy') + +// 实际使用的网站类型 +const effectiveType = computed(() => { + if (type.value === 'all') { + return selectedType.value + } + return type.value +}) + +// 批量创建网站请求模型 +interface BulkCreateModel { + type: string + name: string + listens: Array + domains: Array + path: string + proxy: string + remark: string +} + +// 类型选项 +const typeOptions = computed(() => [ + { label: $gettext('Reverse Proxy'), value: 'proxy' }, + { label: $gettext('PHP'), value: 'php' }, + { label: $gettext('Pure Static'), value: 'static' } +]) + +// 获取模态框标题 +const modalTitle = computed(() => { + switch (effectiveType.value) { + case 'proxy': + return $gettext('Bulk Create Reverse Proxy Website') + case 'php': + return $gettext('Bulk Create PHP Website') + case 'static': + return $gettext('Bulk Create Pure Static Website') + default: + return $gettext('Bulk Create Website') + } +}) + +// 获取占位符文本(根据类型不同显示不同格式) +const placeholderText = computed(() => { + if (effectiveType.value === 'proxy') { + return $gettext('name|domain|port|proxy_target|remark') + } + return $gettext('name|domain|port|path|remark') +}) + +// 获取第四列的说明文本 +const fourthColumnHelp = computed(() => { + if (effectiveType.value === 'proxy') { + return $gettext( + 'Proxy Target: The target address for reverse proxy (e.g., http://127.0.0.1:3000).' + ) + } + return $gettext('Path: The path of the website, can be empty to use the default path.') +}) + const handleCreate = async () => { // 按行分割 const lines = bulkCreate.value.split('\n') @@ -32,20 +94,20 @@ const handleCreate = async () => { .trim() .split(',') .map((item) => item.trim()) - const path = (parts[3] ?? '').trim() + const fourthColumn = (parts[3] ?? '').trim() const remark = parts[4] ? parts[4].trim() : '' - let model = { - name: '', - listens: [] as Array, - domains: [] as Array, - path: '', - remark: '' + + // 构建请求模型 + const model: BulkCreateModel = { + type: effectiveType.value, + name: name, + listens: listens, + domains: domains, + path: effectiveType.value === 'proxy' ? '' : fourthColumn, + proxy: effectiveType.value === 'proxy' ? fourthColumn : '', + remark: remark } - model.name = name - model.domains = domains - model.listens = listens - model.path = path - model.remark = remark + // 去除空的域名和端口 model.domains = model.domains.filter((item) => item !== '') model.listens = model.listens.filter((item) => item !== '') @@ -59,13 +121,6 @@ const handleCreate = async () => { window.$message.success( $gettext('Website %{ name } created successfully', { name: model.name }) ) - model = { - name: '', - domains: [] as Array, - listens: [] as Array, - path: '', - remark: '' - } window.$bus.emit('website:refresh') }) } @@ -75,7 +130,7 @@ const handleCreate = async () => {