子仓库提交
This commit is contained in:
269
src/app/(app)/central-config/message/template/page.tsx
Normal file
269
src/app/(app)/central-config/message/template/page.tsx
Normal file
@@ -0,0 +1,269 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import { MessageTemplate as MessageTemplateType } from './types';
|
||||
import {
|
||||
MessageTemplateList,
|
||||
MessageTemplateSearch,
|
||||
MessageTemplateHeader,
|
||||
MessageTemplateDialog,
|
||||
MessageTemplateTestDialog,
|
||||
MessageTemplateInfo
|
||||
} from './components';
|
||||
|
||||
export default function MessageTemplatePage() {
|
||||
const [templates, setTemplates] = useState<MessageTemplateType[]>([]);
|
||||
const [searchKeyword, setSearchKeyword] = useState('');
|
||||
const [typeFilter, setTypeFilter] = useState<string>('all');
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
const [showTestDialog, setShowTestDialog] = useState(false);
|
||||
const [editingTemplate, setEditingTemplate] = useState<MessageTemplateType | null>(null);
|
||||
const [testTemplate, setTestTemplate] = useState<MessageTemplateType | null>(null);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
loadTemplates();
|
||||
}, []);
|
||||
|
||||
const loadTemplates = () => {
|
||||
// 清除旧的localStorage数据,确保使用最新的mock数据
|
||||
localStorage.removeItem('smart_agriculture_message_templates');
|
||||
|
||||
const data = localStorage.getItem('smart_agriculture_message_templates');
|
||||
if (data) {
|
||||
try {
|
||||
const parsedData = JSON.parse(data);
|
||||
console.log('Loaded templates from localStorage:', parsedData);
|
||||
// 确保数据是数组格式
|
||||
if (Array.isArray(parsedData)) {
|
||||
setTemplates(parsedData);
|
||||
} else {
|
||||
console.error('Loaded data is not an array:', parsedData);
|
||||
setTemplates([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing templates from localStorage:', error);
|
||||
setTemplates([]);
|
||||
}
|
||||
} else {
|
||||
const mockTemplates: MessageTemplateType[] = [
|
||||
{
|
||||
id: 'tpl-1',
|
||||
code: 'TASK_ASSIGNED',
|
||||
name: '任务分配通知',
|
||||
type: 'internal',
|
||||
subject: '新任务分配',
|
||||
content: '您好,{{username}}!您有新的作业任务:{{taskName}},计划执行时间:{{executeTime}}。请及时查看并准备。',
|
||||
variables: ['username', 'taskName', 'executeTime'],
|
||||
isActive: true,
|
||||
description: '当任务分配给驾驶员时发送',
|
||||
createdAt: '2024-01-01T00:00:00',
|
||||
updatedAt: '2024-01-01T00:00:00',
|
||||
createdBy: 'admin',
|
||||
},
|
||||
{
|
||||
id: 'tpl-2',
|
||||
code: 'EQUIPMENT_WARNING',
|
||||
name: '设备预警通知',
|
||||
type: 'sms',
|
||||
content: '【智慧农业】设备预警:{{equipmentName}}检测到异常,{{warningType}},请及时处理。',
|
||||
variables: ['equipmentName', 'warningType'],
|
||||
isActive: true,
|
||||
description: '设备出现异常时发送短信通知',
|
||||
createdAt: '2024-01-01T00:00:00',
|
||||
updatedAt: '2024-01-01T00:00:00',
|
||||
createdBy: 'admin',
|
||||
},
|
||||
{
|
||||
id: 'tpl-3',
|
||||
code: 'MAINTENANCE_REMINDER',
|
||||
name: '保养提醒',
|
||||
type: 'email',
|
||||
subject: '设备保养提醒',
|
||||
content: '尊敬的用户:\n\n您的设备{{equipmentName}}(编号:{{equipmentCode}})已使用{{hours}}小时,建议进行保养维护。\n\n保养周期:{{maintenanceCycle}}\n上次保养时间:{{lastMaintenanceTime}}\n\n请及时安排保养,确保设备正常运行。\n\n智慧农业管理系统',
|
||||
variables: ['equipmentName', 'equipmentCode', 'hours', 'maintenanceCycle', 'lastMaintenanceTime'],
|
||||
isActive: true,
|
||||
description: '设备到达保养周期时发送邮件提醒',
|
||||
createdAt: '2024-01-01T00:00:00',
|
||||
updatedAt: '2024-01-01T00:00:00',
|
||||
createdBy: 'admin',
|
||||
},
|
||||
{
|
||||
id: 'tpl-4',
|
||||
code: 'TASK_COMPLETED',
|
||||
name: '任务完成通知',
|
||||
type: 'push',
|
||||
subject: '任务完成',
|
||||
content: '作业任务{{taskName}}已完成,作业面积:{{area}}亩,耗时:{{duration}}。',
|
||||
variables: ['taskName', 'area', 'duration'],
|
||||
isActive: true,
|
||||
description: '任务完成后推送通知',
|
||||
createdAt: '2024-01-01T00:00:00',
|
||||
updatedAt: '2024-01-01T00:00:00',
|
||||
createdBy: 'admin',
|
||||
},
|
||||
];
|
||||
console.log('Created mock templates:', mockTemplates);
|
||||
localStorage.setItem('smart_agriculture_message_templates', JSON.stringify(mockTemplates));
|
||||
setTemplates(mockTemplates);
|
||||
}
|
||||
};
|
||||
|
||||
const saveTemplates = (newTemplates: MessageTemplateType[]) => {
|
||||
localStorage.setItem('smart_agriculture_message_templates', JSON.stringify(newTemplates));
|
||||
setTemplates(newTemplates);
|
||||
};
|
||||
|
||||
const filteredTemplates = templates.filter(tpl => {
|
||||
const matchKeyword = !searchKeyword ||
|
||||
tpl.name.includes(searchKeyword) ||
|
||||
tpl.code.includes(searchKeyword) ||
|
||||
tpl.content.includes(searchKeyword);
|
||||
const matchType = typeFilter === 'all' || tpl.type === typeFilter;
|
||||
return matchKeyword && matchType;
|
||||
});
|
||||
|
||||
// 调试日志
|
||||
console.log('Original templates:', templates);
|
||||
console.log('Filtered templates:', filteredTemplates);
|
||||
console.log('Search keyword:', searchKeyword);
|
||||
console.log('Type filter:', typeFilter);
|
||||
|
||||
const handleAdd = () => {
|
||||
setEditingTemplate(null);
|
||||
setShowDialog(true);
|
||||
};
|
||||
|
||||
const handleEdit = (template: MessageTemplateType) => {
|
||||
setEditingTemplate(template);
|
||||
setShowDialog(true);
|
||||
};
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
const updated = templates.filter(t => t.id !== id);
|
||||
saveTemplates(updated);
|
||||
toast.success('删除成功');
|
||||
};
|
||||
|
||||
const handleSave = (formData: any) => {
|
||||
if (!formData.code.trim() || !formData.name.trim() || !formData.content.trim()) {
|
||||
toast.error('请填写必填项');
|
||||
return;
|
||||
}
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
// 提取变量
|
||||
const variableRegex = /\{\{(\w+)\}\}/g;
|
||||
const matches = formData.content.matchAll(variableRegex);
|
||||
const extractedVars = Array.from(new Set(Array.from(matches, m => m[1])));
|
||||
|
||||
if (editingTemplate) {
|
||||
const updated = templates.map(t =>
|
||||
t.id === editingTemplate.id
|
||||
? {
|
||||
...t,
|
||||
...formData,
|
||||
variables: extractedVars,
|
||||
updatedAt: now,
|
||||
}
|
||||
: t
|
||||
);
|
||||
saveTemplates(updated);
|
||||
toast.success('更新成功');
|
||||
} else {
|
||||
const newTemplate: MessageTemplateType = {
|
||||
id: `tpl-${Date.now()}`,
|
||||
...formData,
|
||||
variables: extractedVars,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
createdBy: 'admin',
|
||||
};
|
||||
saveTemplates([...templates, newTemplate]);
|
||||
toast.success('添加成功');
|
||||
}
|
||||
|
||||
setShowDialog(false);
|
||||
};
|
||||
|
||||
const handleTest = (template: MessageTemplateType) => {
|
||||
setTestTemplate(template);
|
||||
setShowTestDialog(true);
|
||||
};
|
||||
|
||||
const handleSendTest = (testData: any) => {
|
||||
if (!testData.recipient.trim()) {
|
||||
toast.error('请输入接收人');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查变量是否都填写了
|
||||
const emptyVars = Object.entries(testData.variables).filter(([k, v]) => !v.trim());
|
||||
if (emptyVars.length > 0) {
|
||||
toast.error('请填写变量:' + emptyVars.map(([k]) => k).join(', '));
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success('测试消息发送成功');
|
||||
setShowTestDialog(false);
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
const dataStr = JSON.stringify(filteredTemplates, null, 2);
|
||||
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(dataBlob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `message_templates_${new Date().getTime()}.json`;
|
||||
link.click();
|
||||
toast.success('导出成功');
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* 页面头部 */}
|
||||
<MessageTemplateHeader
|
||||
onExport={handleExport}
|
||||
onAdd={handleAdd}
|
||||
/>
|
||||
|
||||
{/* 搜索和筛选 */}
|
||||
<MessageTemplateSearch
|
||||
searchKeyword={searchKeyword}
|
||||
onSearchChange={setSearchKeyword}
|
||||
typeFilter={typeFilter}
|
||||
onTypeFilterChange={setTypeFilter}
|
||||
/>
|
||||
|
||||
{/* 模版列表 */}
|
||||
<MessageTemplateList
|
||||
templates={filteredTemplates}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
onTest={handleTest}
|
||||
/>
|
||||
|
||||
{/* 编辑对话框 */}
|
||||
<MessageTemplateDialog
|
||||
open={showDialog}
|
||||
onOpenChange={setShowDialog}
|
||||
editingTemplate={editingTemplate}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
|
||||
{/* 测试对话框 */}
|
||||
<MessageTemplateTestDialog
|
||||
open={showTestDialog}
|
||||
onOpenChange={setShowTestDialog}
|
||||
testTemplate={testTemplate}
|
||||
onSendTest={handleSendTest}
|
||||
/>
|
||||
|
||||
{/* 使用说明 */}
|
||||
<MessageTemplateInfo />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user