From 826c2d1a763dbca1ebac2f27218c60ed602d88b6 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 12 Nov 2025 22:46:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=A0=81=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E8=A1=A8=E5=8D=95=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../List/components/TemplateEditor.tsx | 27 +-- .../List/components/TestTemplateDialog.tsx | 161 +++++++----------- 2 files changed, 80 insertions(+), 108 deletions(-) diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/TemplateEditor.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/TemplateEditor.tsx index a3d64e6c..892f70a4 100644 --- a/frontend/src/pages/Deploy/NotificationTemplate/List/components/TemplateEditor.tsx +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/TemplateEditor.tsx @@ -4,7 +4,6 @@ */ import React, { useEffect, useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; -import { Badge } from '@/components/ui/badge'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Dialog, @@ -14,27 +13,35 @@ import { DialogBody, DialogFooter, } from '@/components/ui/dialog'; -import { Plus, Info, Settings } from 'lucide-react'; +import { Settings } from 'lucide-react'; import { FormDesigner, FormRenderer, type FormSchema } from '@/components/FormDesigner'; import Editor from '@/components/Editor'; import { NotificationChannelType } from '../../../NotificationChannel/List/types'; import type { editor } from 'monaco-editor'; +// 模板变量类型(可选) +export interface TemplateVariable { + name: string; + description?: string; + type?: string; + required?: boolean; +} + interface TemplateEditorProps { value: string; onChange: (value: string) => void; channelType: NotificationChannelType; - variables: TemplateVariable[]; - onVariableInsert: (variable: TemplateVariable) => void; - onFormDataChange?: (data: Record) => void; // 新增:表单数据变化回调 - mode?: 'create' | 'edit'; // 新增:模式标识 + variables?: TemplateVariable[]; // 可选 + onVariableInsert?: (variable: TemplateVariable) => void; // 可选 + onFormDataChange?: (data: Record) => void; // 表单数据变化回调 + mode?: 'create' | 'edit'; // 模式标识 } export const TemplateEditor: React.FC = ({ value, onChange, channelType, - variables, + variables = [], onVariableInsert, onFormDataChange, mode = 'edit', @@ -167,12 +174,12 @@ export const TemplateEditor: React.FC = ({ })), // 变量建议 - ...variables.map(variable => ({ + ...(variables || []).map(variable => ({ label: `\${${variable.name}}`, kind: monaco.languages.CompletionItemKind.Variable, insertText: `\${${variable.name}}`, documentation: variable.description, - detail: `${variable.type} - ${variable.required ? 'Required' : 'Optional'}` + detail: `${variable.type ?? ''} ${variable.required ? '- Required' : ''}` })) ]; @@ -288,14 +295,12 @@ export const TemplateEditor: React.FC = ({
- {console.log('formSchema:', formSchema)} {formSchema ? (
{ - console.log('FormRenderer onChange called with data:', data); setFormData(data); }} showSubmit={false} diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/TestTemplateDialog.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/TestTemplateDialog.tsx index 5d210afd..49d59b5d 100644 --- a/frontend/src/pages/Deploy/NotificationTemplate/List/components/TestTemplateDialog.tsx +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/TestTemplateDialog.tsx @@ -19,11 +19,12 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { useToast } from '@/components/ui/use-toast'; -import { Loader2, Send, TestTube } from 'lucide-react'; -import type { NotificationTemplateDTO, TemplateRenderRequest } from '../types'; +import { Loader2, Send, TestTube, Settings } from 'lucide-react'; +import type { NotificationTemplateDTO } from '../types'; import type { NotificationChannelDTO } from '../../../NotificationChannel/List/types'; import { getChannelsPage } from '../../../NotificationChannel/List/service'; -import { sendTestMessage, renderTemplate, type TestMessageRequest } from '../service'; +import { sendTestMessage, type TestMessageRequest } from '../service'; +import { FormDesigner, FormRenderer, type FormSchema } from '@/components/FormDesigner'; interface TestTemplateDialogProps { open: boolean; @@ -41,23 +42,21 @@ const TestTemplateDialog: React.FC = ({ const [loading, setLoading] = useState(false); const [channels, setChannels] = useState([]); const [selectedChannelId, setSelectedChannelId] = useState(''); - const [params, setParams] = useState>({}); - const [renderedContent, setRenderedContent] = useState(''); + const [formSchema, setFormSchema] = useState(null); + const [formData, setFormData] = useState>({}); + const [designerOpen, setDesignerOpen] = useState(false); // 加载渠道列表 useEffect(() => { if (open) { loadChannels(); - initParams(); + // 打开时清空上次数据,用户可通过表单设计器自定义参数 + setFormSchema(null); + setFormData({}); } }, [open, template]); - // 当参数变化时重新渲染模板 - useEffect(() => { - if (template?.code && Object.keys(params).length > 0) { - renderTemplateContent(); - } - }, [params, template?.code]); + // 参数变化不再触发后端渲染(此页面不调用渲染接口) const loadChannels = async () => { try { @@ -77,60 +76,9 @@ const TestTemplateDialog: React.FC = ({ }; // 渲染模板内容 - const renderTemplateContent = async () => { - if (!template?.code) return; - - try { - const renderRequest: TemplateRenderRequest = { - templateCode: template.code, - params: params, - }; - - const result = await renderTemplate(renderRequest); - setRenderedContent(result.content || ''); - } catch (error: any) { - console.error('渲染模板失败:', error); - setRenderedContent(template.contentTemplate || ''); - } - }; + // 不再调用后端渲染接口,此处保留占位以说明设计意图 - // 初始化参数 - const initParams = () => { - if (!template?.contentTemplate) return; - - // 从模板内容中提取变量 ${variableName} - const variableRegex = /\$\{([^}]+)\}/g; - const variables = new Set(); - let match; - - while ((match = variableRegex.exec(template.contentTemplate)) !== null) { - variables.add(match[1]); - } - - // 初始化参数对象 - const initialParams: Record = {}; - variables.forEach(variable => { - initialParams[variable] = getDefaultValue(variable); - }); - - setParams(initialParams); - }; - - // 获取变量的默认值 - const getDefaultValue = (variable: string): string => { - const defaultValues: Record = { - projectName: '测试项目', - buildNumber: '123', - environment: 'test', - status: 'success', - message: '这是一条测试消息', - time: new Date().toLocaleString(), - url: 'https://example.com', - user: '测试用户', - }; - - return defaultValues[variable] || `测试${variable}`; - }; + // 不再基于正则推断参数,改为表单设计器动态定义 // 发送测试消息 const handleSend = async () => { @@ -147,7 +95,7 @@ const TestTemplateDialog: React.FC = ({ const request: TestMessageRequest = { channelId: parseInt(selectedChannelId), notificationTemplateId: template.id, - params: params, + params: formData || {}, }; await sendTestMessage(request); @@ -172,8 +120,8 @@ const TestTemplateDialog: React.FC = ({ // 重置状态 const handleClose = () => { setSelectedChannelId(''); - setParams({}); - setRenderedContent(''); + setFormSchema(null); + setFormData({}); onOpenChange(false); }; @@ -217,43 +165,37 @@ const TestTemplateDialog: React.FC = ({
- {/* 模板参数 */} - {Object.keys(params).length > 0 && ( -
+ {/* 模板参数(动态表单) */} +
+
-
- {Object.entries(params).map(([key, value]) => ( -
- - setParams(prev => ({ - ...prev, - [key]: e.target.value - }))} - placeholder={`请输入${key}`} - /> -
- ))} -
+
- )} + {formSchema ? ( +
+ setFormData(data)} + showSubmit={false} + showCancel={false} + /> +
+ ) : ( +
未定义参数表单,点击右上角按钮进行设计。
+ )} +
- {/* 模板内容预览 */} + {/* 模板内容 */}
- +