From 0ebd1c06992539ea717c11a01c36b5d500ea78b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Mon, 1 Dec 2025 23:31:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BD=91=E7=AB=99=E9=87=8D=E6=9E=842?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/data/website.go | 19 +- internal/http/request/website.go | 5 +- internal/service/website.go | 2 +- pkg/webserver/nginx/vhost.go | 2 +- .../{BulkCreate.vue => BulkCreateModal.vue} | 6 +- web/src/views/website/CreateModal.vue | 245 ++++++++++++++++++ web/src/views/website/IndexView.vue | 15 +- web/src/views/website/ListView.vue | 224 +--------------- 8 files changed, 288 insertions(+), 230 deletions(-) rename web/src/views/website/{BulkCreate.vue => BulkCreateModal.vue} (98%) create mode 100644 web/src/views/website/CreateModal.vue diff --git a/internal/data/website.go b/internal/data/website.go index 857cb1c7..da531ebb 100644 --- a/internal/data/website.go +++ b/internal/data/website.go @@ -295,9 +295,26 @@ func (r *websiteRepo) Create(req *request.WebsiteCreate) (*biz.Website, error) { return nil, err } + // 创建配置文件目录 + if err = os.MkdirAll(filepath.Join(app.Root, "sites", req.Name, "config", "vhost"), 0644); err != nil { + return nil, err + } + if err = os.MkdirAll(filepath.Join(app.Root, "sites", req.Name, "config", "global"), 0644); err != nil { + return nil, err + } + // 创建日志目录 + if err = os.MkdirAll(filepath.Join(app.Root, "sites", req.Name, "log"), 0644); err != nil { + return nil, err + } + // 反向代理支持 if proxyVhost, ok := vhost.(webservertypes.ProxyVhost); ok { - if err = proxyVhost.SetProxies([]webservertypes.Proxy{req.Proxy}); err != nil { + if err = proxyVhost.SetProxies([]webservertypes.Proxy{ + { + Location: "^~ /", + Pass: req.Proxy, + }, + }); err != nil { return nil, err } } diff --git a/internal/http/request/website.go b/internal/http/request/website.go index cfeb98e1..5e1cd56e 100644 --- a/internal/http/request/website.go +++ b/internal/http/request/website.go @@ -2,7 +2,6 @@ package request import ( "github.com/acepanel/panel/pkg/types" - webservertypes "github.com/acepanel/panel/pkg/webserver/types" ) type WebsiteDefaultConfig struct { @@ -28,8 +27,8 @@ type WebsiteCreate struct { DBPassword string `form:"db_password" json:"db_password" validate:"requiredIf:DB,true"` Remark string `form:"remark" json:"remark"` - PHP uint `form:"php" json:"php" validate:"requiredIf:Type,php"` // 仅 PHP 网站需要 - Proxy webservertypes.Proxy `form:"proxy" json:"proxy" validate:"requiredIf:Type,proxy"` // 仅反向代理网站需要 + PHP uint `form:"php" json:"php" validate:"requiredIf:Type,php"` // 仅 PHP 网站需要 + Proxy string `form:"proxy" json:"proxy" validate:"requiredIf:Type,proxy"` // 仅反向代理网站需要 } type WebsiteDelete struct { diff --git a/internal/service/website.go b/internal/service/website.go index 260a946e..a1a2c506 100644 --- a/internal/service/website.go +++ b/internal/service/website.go @@ -112,7 +112,7 @@ func (s *WebsiteService) Create(w http.ResponseWriter, r *http.Request) { if len(req.Path) == 0 { req.Path, _ = s.settingRepo.Get(biz.SettingKeyWebsitePath) - req.Path = filepath.Join(req.Path, req.Name) + req.Path = filepath.Join(req.Path, req.Name, "public") } if _, err = s.websiteRepo.Create(req); err != nil { diff --git a/pkg/webserver/nginx/vhost.go b/pkg/webserver/nginx/vhost.go index 36df3996..6e1b5665 100644 --- a/pkg/webserver/nginx/vhost.go +++ b/pkg/webserver/nginx/vhost.go @@ -254,7 +254,7 @@ func (v *baseVhost) Save() error { } func (v *baseVhost) Reload() error { - parts := strings.Fields("systemctl reload openresty") + parts := strings.Fields("systemctl reload nginx") if err := exec.Command(parts[0], parts[1:]...).Run(); err != nil { if testErr := exec.Command("nginx", "-t").Run(); testErr != nil { return fmt.Errorf("nginx config test failed: %w", testErr) diff --git a/web/src/views/website/BulkCreate.vue b/web/src/views/website/BulkCreateModal.vue similarity index 98% rename from web/src/views/website/BulkCreate.vue rename to web/src/views/website/BulkCreateModal.vue index e53ab301..79453491 100644 --- a/web/src/views/website/BulkCreate.vue +++ b/web/src/views/website/BulkCreateModal.vue @@ -1,11 +1,13 @@ + + + + diff --git a/web/src/views/website/IndexView.vue b/web/src/views/website/IndexView.vue index 3437be4e..3bc20da4 100644 --- a/web/src/views/website/IndexView.vue +++ b/web/src/views/website/IndexView.vue @@ -3,10 +3,15 @@ defineOptions({ name: 'website-index' }) +import BulkCreateModal from '@/views/website/BulkCreateModal.vue' +import CreateModal from '@/views/website/CreateModal.vue' import ListView from '@/views/website/ListView.vue' import SettingView from '@/views/website/SettingView.vue' const currentTab = ref('proxy') + +const createModal = ref(false) +const bulkCreateModal = ref(false) - + + + + diff --git a/web/src/views/website/ListView.vue b/web/src/views/website/ListView.vue index fe063712..c390a583 100644 --- a/web/src/views/website/ListView.vue +++ b/web/src/views/website/ListView.vue @@ -2,13 +2,13 @@ import { NButton, NCheckbox, NDataTable, NFlex, NInput, NPopconfirm, NSwitch, NTag } from 'naive-ui' import { useGettext } from 'vue3-gettext' -import home from '@/api/panel/home' import website from '@/api/panel/website' import { useFileStore } from '@/store' -import { generateRandomString, isNullOrUndef } from '@/utils' -import BulkCreate from '@/views/website/BulkCreate.vue' +import { isNullOrUndef } from '@/utils' const type = defineModel('type', { type: String, required: true }) // 网站类型 +const createModal = defineModel('createModal', { type: Boolean, required: true }) // 创建网站 +const bulkCreateModal = defineModel('bulkCreateModal', { type: Boolean, required: true }) // 批量创建网站 const fileStore = useFileStore() const { $gettext } = useGettext() @@ -203,44 +203,11 @@ const columns: any = [ } ] -const createModal = ref(false) -const bulkCreateModal = ref(false) - -const createModel = ref({ - name: '', - listens: [] as Array, - domains: [] as Array, - path: '', - php: 0, - db: false, - db_type: '0', - db_name: '', - db_user: '', - db_password: '', - remark: '' -}) const deleteModel = ref({ path: true, db: false }) -const { data: installedDbAndPhp } = useRequest(home.installedDbAndPhp, { - initialData: { - php: [ - { - label: $gettext('Not used'), - value: 0 - } - ], - db: [ - { - label: '', - value: '' - } - ] - } -}) - const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination( (page, pageSize) => website.list(type.value, page, pageSize), { @@ -288,38 +255,6 @@ const handleDelete = (id: number) => { }) } -const handleCreate = async () => { - // 去除空的域名和端口 - createModel.value.domains = createModel.value.domains.filter((item) => item !== '') - createModel.value.listens = createModel.value.listens.filter((item) => item !== '') - // 端口为空自动添加 80 端口 - if (createModel.value.listens.length === 0) { - createModel.value.listens.push('80') - } - // 端口中去掉 443 端口,nginx 不允许在未配置证书下监听 443 端口 - createModel.value.listens = createModel.value.listens.filter((item) => item !== '443') - useRequest(website.create(createModel.value)).onSuccess(() => { - refresh() - window.$message.success( - $gettext('Website %{ name } created successfully', { name: createModel.value.name }) - ) - createModal.value = false - createModel.value = { - name: '', - domains: [] as Array, - listens: [] as Array, - php: 0, - db: false, - db_type: '0', - db_name: '', - db_user: '', - db_password: '', - path: '', - remark: '' - } - }) -} - const bulkDelete = async () => { if (selectedRowKeys.value.length === 0) { window.$message.info($gettext('Please select the websites to delete')) @@ -334,16 +269,6 @@ const bulkDelete = async () => { window.$message.success($gettext('Deleted successfully')) } -const formatDbValue = (value: string) => { - value = value.replace(/\./g, '_') - value = value.replace(/-/g, '_') - if (value.length > 16) { - value = value.substring(0, 16) - } - - return value -} - onMounted(() => { refresh() window.$bus.on('website:refresh', refresh) @@ -394,147 +319,4 @@ onMounted(() => { }" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ $gettext('Create') }} - - -