Files
smart-crop-ui/crop-x/src/app/(app)/central-config/message/template/page.tsx

269 lines
8.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'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>
);
}