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 {}