From 79b6f4bade5768762c0ff6b4419a74d5de6fe5e0 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 12 Nov 2025 20:25:03 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=B6=88=E6=81=AF=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/NotificationTemplateDialog.tsx | 30 ++++++++++ .../EmailTemplateConfigForm.tsx | 60 +++++++++++++++++++ .../TemplateConfigFormFactory.tsx | 46 ++++++++++++++ .../WeworkTemplateConfigForm.tsx | 39 ++++++++++++ .../template-config-strategies/types.ts | 43 +++++++++++++ .../Deploy/NotificationTemplate/List/types.ts | 50 ++++++++++++++++ 6 files changed, 268 insertions(+) create mode 100644 frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/EmailTemplateConfigForm.tsx create mode 100644 frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/TemplateConfigFormFactory.tsx create mode 100644 frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/WeworkTemplateConfigForm.tsx create mode 100644 frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-strategies/types.ts diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/NotificationTemplateDialog.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/NotificationTemplateDialog.tsx index 0ec5f5cd..ee13ebe2 100644 --- a/frontend/src/pages/Deploy/NotificationTemplate/List/components/NotificationTemplateDialog.tsx +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/NotificationTemplateDialog.tsx @@ -27,6 +27,7 @@ import { Textarea } from '@/components/ui/textarea'; import { useToast } from '@/components/ui/use-toast'; import { Loader2, Eye, Code } from 'lucide-react'; import { NotificationChannelType } from '../../../NotificationChannel/List/types'; +import { TemplateConfigFormFactory } from './template-config-forms/TemplateConfigFormFactory'; import type { NotificationTemplateDTO, ChannelTypeOption, @@ -58,6 +59,13 @@ const formSchema = z.object({ description: z.string().max(500, '描述不能超过500个字符').optional(), channelType: z.nativeEnum(NotificationChannelType), contentTemplate: z.string().min(1, '请输入模板内容'), + templateConfig: z.object({ + // 企业微信配置 + messageType: z.enum(['TEXT', 'MARKDOWN', 'FILE']).optional(), + // 邮件配置 + contentType: z.enum(['TEXT', 'HTML']).optional(), + priority: z.enum(['LOW', 'NORMAL', 'HIGH']).optional(), + }).optional(), }); type FormValues = z.infer; @@ -165,6 +173,7 @@ export const NotificationTemplateDialog: React.FC + {/* 模板配置 */} + {watchedChannelType && ( +
+ +
+ {TemplateConfigFormFactory.createConfigForm( + watchedChannelType as NotificationChannelType, + { + register, + errors, + setValue, + configState: {}, + updateConfigState: () => {}, + } + )} +
+
+ )} + {/* 模板编辑器区域 */}
{/* 编辑器 */} diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/EmailTemplateConfigForm.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/EmailTemplateConfigForm.tsx new file mode 100644 index 00000000..8d9edf5b --- /dev/null +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/EmailTemplateConfigForm.tsx @@ -0,0 +1,60 @@ +/** + * 邮件模板配置表单 + */ +import React from 'react'; +import { Label } from '@/components/ui/label'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import type { TemplateConfigComponentProps } from '../template-config-strategies/types'; + +export const EmailTemplateConfigForm: React.FC = ({ + register, + errors, + setValue, +}) => { + return ( +
+
+ + + {errors?.templateConfig?.contentType && ( +

+ {errors.templateConfig.contentType.message} +

+ )} +
+ +
+ + + {errors?.templateConfig?.priority && ( +

+ {errors.templateConfig.priority.message} +

+ )} +
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/TemplateConfigFormFactory.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/TemplateConfigFormFactory.tsx new file mode 100644 index 00000000..36d87627 --- /dev/null +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/TemplateConfigFormFactory.tsx @@ -0,0 +1,46 @@ +/** + * 模板配置表单工厂 + */ +import React from 'react'; +import { NotificationChannelType } from '../../../../NotificationChannel/List/types'; +import type { TemplateConfigComponentProps } from '../template-config-strategies/types'; +import { WeworkTemplateConfigForm } from './WeworkTemplateConfigForm'; +import { EmailTemplateConfigForm } from './EmailTemplateConfigForm'; + +export class TemplateConfigFormFactory { + static createConfigForm( + type: NotificationChannelType, + props: TemplateConfigComponentProps + ): React.ReactElement | null { + switch (type) { + case NotificationChannelType.WEWORK: + return ; + + case NotificationChannelType.EMAIL: + return ; + + default: + return null; + } + } + + static getSupportedTypes(): NotificationChannelType[] { + return [ + NotificationChannelType.WEWORK, + NotificationChannelType.EMAIL, + ]; + } + + static getDefaultConfig(type: NotificationChannelType): any { + switch (type) { + case NotificationChannelType.WEWORK: + return { messageType: 'TEXT' }; + + case NotificationChannelType.EMAIL: + return { contentType: 'TEXT', priority: 'NORMAL' }; + + default: + return {}; + } + } +} diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/WeworkTemplateConfigForm.tsx b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/WeworkTemplateConfigForm.tsx new file mode 100644 index 00000000..a2df1298 --- /dev/null +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-forms/WeworkTemplateConfigForm.tsx @@ -0,0 +1,39 @@ +/** + * 企业微信模板配置表单 + */ +import React from 'react'; +import { Label } from '@/components/ui/label'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import type { TemplateConfigComponentProps } from '../template-config-strategies/types'; + +export const WeworkTemplateConfigForm: React.FC = ({ + register, + errors, + setValue, +}) => { + return ( +
+
+ + + {errors?.templateConfig?.messageType && ( +

+ {errors.templateConfig.messageType.message} +

+ )} +
+
+ ); +}; diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-strategies/types.ts b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-strategies/types.ts new file mode 100644 index 00000000..7b2f0328 --- /dev/null +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/components/template-config-strategies/types.ts @@ -0,0 +1,43 @@ +/** + * 模板配置策略类型定义 + */ +import { NotificationChannelType } from '../../../../NotificationChannel/List/types'; + +export interface TemplateConfigStrategy { + /** 渠道类型 */ + type: NotificationChannelType; + + /** 获取默认配置 */ + getDefaultConfig(): any; + + /** 验证配置 */ + validateConfig(config: any): boolean; + + /** 从API数据加载配置到表单状态 */ + loadFromData(data: any): TemplateConfigState; + + /** 从表单状态构建API配置 */ + buildConfig(state: TemplateConfigState, formConfig: any): any; +} + +export interface TemplateConfigState { + /** 额外的状态数据 */ + [key: string]: any; +} + +export interface TemplateConfigComponentProps { + /** 表单注册函数 */ + register: any; + + /** 表单错误 */ + errors: any; + + /** 设置表单值 */ + setValue: any; + + /** 配置状态 */ + configState: TemplateConfigState; + + /** 更新配置状态 */ + updateConfigState: (updates: Partial) => void; +} diff --git a/frontend/src/pages/Deploy/NotificationTemplate/List/types.ts b/frontend/src/pages/Deploy/NotificationTemplate/List/types.ts index 19974cd0..6ced4e1c 100644 --- a/frontend/src/pages/Deploy/NotificationTemplate/List/types.ts +++ b/frontend/src/pages/Deploy/NotificationTemplate/List/types.ts @@ -22,6 +22,9 @@ export interface NotificationTemplateDTO extends BaseResponse { /** 内容模板(FreeMarker格式) */ contentTemplate: string; + + /** 模板配置(根据 channelType 不同而不同) */ + templateConfig?: WeworkTemplateConfig | EmailTemplateConfig; } // ============================================ @@ -51,6 +54,53 @@ export interface ChannelTypeOption { description: string; } +// ============================================ +// 5. 模板配置类型 +// ============================================ + +/** 模板配置基类 */ +export interface BaseTemplateConfig { + // 运行时通过 channelType 判断具体类型 +} + +/** 企业微信模板配置 */ +export interface WeworkTemplateConfig extends BaseTemplateConfig { + /** 消息类型 */ + messageType: 'TEXT' | 'MARKDOWN' | 'FILE'; +} + +/** 邮件模板配置 */ +export interface EmailTemplateConfig extends BaseTemplateConfig { + /** 内容类型 */ + contentType: 'TEXT' | 'HTML'; + /** 优先级 */ + priority: 'LOW' | 'NORMAL' | 'HIGH'; +} + +// ============================================ +// 6. 类型守卫函数 +// ============================================ + +/** + * 判断是否为企业微信模板配置 + */ +export function isWeworkTemplateConfig( + config: BaseTemplateConfig, + channelType: NotificationChannelType +): config is WeworkTemplateConfig { + return channelType === 'WEWORK' && 'messageType' in config; +} + +/** + * 判断是否为邮件模板配置 + */ +export function isEmailTemplateConfig( + config: BaseTemplateConfig, + channelType: NotificationChannelType +): config is EmailTemplateConfig { + return channelType === 'EMAIL' && 'contentType' in config && 'priority' in config; +} + // ============================================ // 7. 模板渲染参数 // ============================================