diff --git a/models/message_template.go b/models/message_template.go index a604893..fe0723f 100644 --- a/models/message_template.go +++ b/models/message_template.go @@ -45,7 +45,11 @@ func (t *Template) Add() error { // Update 更新消息模板 func (t *Template) Update() error { - if err := db.Model(&Template{}).Where("id = ?", t.ID).Updates(t).Error; err != nil { + // 使用 Select 明确指定要更新的字段,包括布尔值字段,排除不应更新的时间戳字段 + if err := db.Model(&Template{}).Where("id = ?", t.ID). + Select("name", "description", "text_template", "html_template", "markdown_template", + "placeholders", "at_mobiles", "at_user_ids", "is_at_all", "status", "modified_by"). + Updates(t).Error; err != nil { return err } return nil diff --git a/web/package-lock.json b/web/package-lock.json index 176995c..1cb6db1 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -10,13 +10,13 @@ "dependencies": { "@tailwindcss/vite": "^4.1.11", "@tanstack/vue-table": "^8.21.3", - "@vueuse/core": "^13.6.0", + "@vueuse/core": "^13.9.0", "axios": "^1.12.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-vue-next": "^0.536.0", "pinia": "^3.0.3", - "reka-ui": "^2.4.1", + "reka-ui": "^2.6.1", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.11", "tw-animate-css": "^1.3.6", @@ -1605,14 +1605,14 @@ } }, "node_modules/@vueuse/core": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-13.6.0.tgz", - "integrity": "sha512-DJbD5fV86muVmBgS9QQPddVX7d9hWYswzlf4bIyUD2dj8GC46R1uNClZhVAmsdVts4xb2jwp1PbpuiA50Qee1A==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-13.9.0.tgz", + "integrity": "sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==", "license": "MIT", "dependencies": { "@types/web-bluetooth": "^0.0.21", - "@vueuse/metadata": "13.6.0", - "@vueuse/shared": "13.6.0" + "@vueuse/metadata": "13.9.0", + "@vueuse/shared": "13.9.0" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -1622,9 +1622,9 @@ } }, "node_modules/@vueuse/core/node_modules/@vueuse/shared": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-13.6.0.tgz", - "integrity": "sha512-pDykCSoS2T3fsQrYqf9SyF0QXWHmcGPQ+qiOVjlYSzlWd9dgppB2bFSM1GgKKkt7uzn0BBMV3IbJsUfHG2+BCg==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-13.9.0.tgz", + "integrity": "sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" @@ -1634,9 +1634,9 @@ } }, "node_modules/@vueuse/metadata": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.6.0.tgz", - "integrity": "sha512-rnIH7JvU7NjrpexTsl2Iwv0V0yAx9cw7+clymjKuLSXG0QMcLD0LDgdNmXic+qL0SGvgSVPEpM9IDO/wqo1vkQ==", + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.9.0.tgz", + "integrity": "sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" @@ -2632,9 +2632,9 @@ "license": "MIT" }, "node_modules/reka-ui": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.4.1.tgz", - "integrity": "sha512-NB7DrCsODN8MH02BWtgiExygfFcuuZ5/PTn6fMgjppmFHqePvNhmSn1LEuF35nel6PFbA4v+gdj0IoGN1yZ+vw==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.6.1.tgz", + "integrity": "sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.6.13", diff --git a/web/package.json b/web/package.json index 0f7c7e3..491ebed 100644 --- a/web/package.json +++ b/web/package.json @@ -13,13 +13,13 @@ "dependencies": { "@tailwindcss/vite": "^4.1.11", "@tanstack/vue-table": "^8.21.3", - "@vueuse/core": "^13.6.0", + "@vueuse/core": "^13.9.0", "axios": "^1.12.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-vue-next": "^0.536.0", "pinia": "^3.0.3", - "reka-ui": "^2.4.1", + "reka-ui": "^2.6.1", "tailwind-merge": "^3.3.1", "tailwindcss": "^4.1.11", "tw-animate-css": "^1.3.6", @@ -37,4 +37,4 @@ "vite": "^7.0.4", "vue-tsc": "^2.2.12" } -} \ No newline at end of file +} diff --git a/web/src/components/pages/messageTemplate/MessageTemplate.vue b/web/src/components/pages/messageTemplate/MessageTemplate.vue index 10f7561..67ae56d 100644 --- a/web/src/components/pages/messageTemplate/MessageTemplate.vue +++ b/web/src/components/pages/messageTemplate/MessageTemplate.vue @@ -7,6 +7,7 @@ import { Badge } from '@/components/ui/badge' import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import EmptyTableState from '@/components/ui/EmptyTableState.vue' import Pagination from '@/components/ui/Pagination.vue' +import ClickableTruncate from '@/components/ui/ClickableTruncate.vue' import TemplateApiViewer from './TemplateApiViewer.vue' import TemplateInstanceConfig from './TemplateInstanceConfig.vue' import TemplateEditor from './TemplateEditor.vue' @@ -201,9 +202,11 @@ onMounted(async () => { {{ item.id }} - {{ item.name }} -
{{ item.description || '-' }}
+ +
+ +
diff --git a/web/src/components/pages/messageTemplate/TemplateEditor.vue b/web/src/components/pages/messageTemplate/TemplateEditor.vue index 69af023..e4da45a 100644 --- a/web/src/components/pages/messageTemplate/TemplateEditor.vue +++ b/web/src/components/pages/messageTemplate/TemplateEditor.vue @@ -7,6 +7,7 @@ import { Textarea } from '@/components/ui/textarea' import { Label } from '@/components/ui/label' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' +import { Checkbox } from '@/components/ui/checkbox' import { toast } from 'vue-sonner' import { request } from '@/api/api' @@ -219,7 +220,7 @@ const loadTemplateData = (template: TemplateData) => { placeholders: template.placeholders, at_mobiles: template.at_mobiles || '', at_user_ids: template.at_user_ids || '', - is_at_all: template.is_at_all || false, + is_at_all: Boolean(template.is_at_all), status: template.status } @@ -243,18 +244,28 @@ const saveTemplate = async () => { toast.error('请输入模板名称') return } + + // 验证至少填写一种格式的模板内容 + if (!formData.value.text_template && !formData.value.html_template && !formData.value.markdown_template) { + toast.error('至少需要填写一种格式的模板内容') + return + } // 同步占位符数据 formData.value.placeholders = JSON.stringify(placeholdersList.value) try { const url = props.isEditing ? '/templates/edit' : '/templates/add' - await request.post(url, formData.value) - toast.success(props.isEditing ? '更新模板成功' : '添加模板成功') - emit('update:open', false) - emit('saved') + const response = await request.post(url, formData.value) + if (response.data.code === 200) { + toast.success(props.isEditing ? '更新模板成功' : '添加模板成功') + emit('update:open', false) + emit('saved') + } else { + toast.error(response.data.msg || '操作失败') + } } catch (error: any) { - toast.error(error.response?.data?.message || '操作失败') + toast.error(error.response?.data?.msg || error.response?.data?.message || '操作失败') } } @@ -278,9 +289,25 @@ watch(() => props.open, (newVal) => {
-
- - +
+
+ + +
+
+ + +
@@ -288,21 +315,6 @@ watch(() => props.open, (newVal) => {