diff --git a/agent/app/service/website_template.go b/agent/app/service/website_template.go index ce2ee1d154e6..0a2103045cde 100644 --- a/agent/app/service/website_template.go +++ b/agent/app/service/website_template.go @@ -75,6 +75,9 @@ func (w WebsiteTemplateService) PageTemplate(req request.WebsiteTemplateSearch) } func (w WebsiteTemplateService) CreateTemplate(req request.WebsiteTemplateCreate) error { + if err := validateWebsiteTemplateFile(req.Type, req.FilePath); err != nil { + return err + } if exist, _ := websiteTemplateRepo.GetFirst(repo.WithByName(req.Name)); exist != nil { return buserr.New("ErrNameIsExist") } @@ -94,6 +97,9 @@ func (w WebsiteTemplateService) UpdateTemplate(req request.WebsiteTemplateUpdate if err != nil { return err } + if err := validateWebsiteTemplateFile(req.Type, req.FilePath); err != nil { + return err + } if exist, _ := websiteTemplateRepo.GetFirst(repo.WithByName(req.Name), repo.WithByNOTID(req.ID)); exist != nil { return buserr.New("ErrNameIsExist") } @@ -109,6 +115,22 @@ func (w WebsiteTemplateService) UpdateTemplate(req request.WebsiteTemplateUpdate return websiteTemplateRepo.Save(template) } +func validateWebsiteTemplateFile(templateType, filePath string) error { + if templateType != "multi" { + return nil + } + if filePath == "" { + return buserr.WithName("ErrFileNotFound", "ZIP") + } + if _, err := os.Stat(filePath); err != nil { + if os.IsNotExist(err) { + return buserr.WithName("ErrFileNotFound", "ZIP") + } + return err + } + return nil +} + func (w WebsiteTemplateService) DeleteTemplate(id uint) error { template, err := websiteTemplateRepo.GetFirst(repo.WithByID(id)) if err != nil { @@ -297,7 +319,7 @@ func renderToDir(template *model.WebsiteTemplate, values map[string]string, outp func unzipAndRender(zipPath, outputDir string, values map[string]string) error { if zipPath == "" { - return buserr.New("ErrFileNotFound") + return buserr.WithName("ErrFileNotFound", "ZIP") } reader, err := zip.OpenReader(zipPath) if err != nil { @@ -348,7 +370,7 @@ func isTextFile(name string) bool { func renderMainHTMLFromZip(zipPath string, values map[string]string) (string, error) { if zipPath == "" { - return "", buserr.New("ErrFileNotFound") + return "", buserr.WithName("ErrFileNotFound", "ZIP") } reader, err := zip.OpenReader(zipPath) if err != nil { @@ -368,7 +390,7 @@ func renderMainHTMLFromZip(zipPath string, values map[string]string) (string, er } } if mainFile == nil { - return "", buserr.New("ErrFileNotFound") + return "", buserr.WithName("ErrFileNotFound", "index.html") } rc, err := mainFile.Open() if err != nil { @@ -416,4 +438,3 @@ func copyFile(src, dst string) error { _, err = io.Copy(dstFile, srcFile) return err } - diff --git a/core/constant/common.go b/core/constant/common.go index e70b0e7ab21a..168215c5756e 100644 --- a/core/constant/common.go +++ b/core/constant/common.go @@ -151,6 +151,7 @@ var WebUrlMap = map[string]struct{}{ "/toolbox/clean": {}, "/websites": {}, + "/websites/templates": {}, "/websites/ssl": {}, "/websites/runtimes/php": {}, "/websites/runtimes/node": {}, diff --git a/frontend/src/views/ai/agents/model/add/index.vue b/frontend/src/views/ai/agents/model/add/index.vue index d1f1ea8362cb..68bf3d5ac2b0 100644 --- a/frontend/src/views/ai/agents/model/add/index.vue +++ b/frontend/src/views/ai/agents/model/add/index.vue @@ -72,7 +72,7 @@ - {{ $t('aiTools.agents.validateAvailability') }} + {{ $t('aiTools.agents.validateAvailability') }} {{ isImageAPIType diff --git a/frontend/src/views/website/template/operate/index.vue b/frontend/src/views/website/template/operate/index.vue index 50dcdc32307f..73e76f74d4d5 100644 --- a/frontend/src/views/website/template/operate/index.vue +++ b/frontend/src/views/website/template/operate/index.vue @@ -25,7 +25,7 @@ /> {{ $t('template.autoDetectHelper') }} - + {{ $t('template.upload') }} @@ -140,6 +140,18 @@ const form = reactive(initForm()); const rules = { name: [{ required: true, message: i18n.global.t('commons.rule.requiredInput'), trigger: 'blur' }], type: [{ required: true, message: i18n.global.t('commons.rule.requiredSelect'), trigger: 'change' }], + filePath: [ + { + validator: (_rule, value, callback) => { + if (form.type === 'multi' && !value) { + callback(new Error(i18n.global.t('commons.rule.requiredSelect'))); + return; + } + callback(); + }, + trigger: 'change', + }, + ], }; const variables = ref([]); @@ -178,6 +190,7 @@ const handleUpload = async (file: globalThis.File) => { try { const res = await uploadTemplateZip(file); form.filePath = res.data.filePath; + formRef.value?.clearValidate('filePath'); mergeDetectedKeys(res.data.variables || []); MsgSuccess(i18n.global.t('commons.msg.uploadSuccess')); } catch {}