Parcourir la source

修复邮件部分中英文适配与提示

pm il y a 3 mois
Parent
commit
3db2e44618

+ 52 - 46
src/components/mailTemplate/MailTemplateForm.tsx

@@ -1,4 +1,5 @@
 import React, { useState, useImperativeHandle, forwardRef } from 'react';
+import { useTranslation } from 'react-i18next';
 import { Modal, Form, Input, InputNumber, Select, Row, Col, message } from 'antd';
 import { emailTemplateApi, MailTemplateVO } from '../../api/emailTemplate';
 
@@ -13,6 +14,7 @@ export interface MailTemplateFormRef {
 }
 
 const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(({ onSuccess }, ref) => {
+  const { t } = useTranslation();
   const [dialogVisible, setDialogVisible] = useState(false);
   const [dialogTitle, setDialogTitle] = useState('');
   const [formLoading, setFormLoading] = useState(false);
@@ -22,7 +24,7 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
   // 打开弹窗
   const open = async (type: string, id?: number) => {
     setDialogVisible(true);
-    setDialogTitle(type === 'create' ? '新增邮件模板' : '编辑邮件模板');
+    setDialogTitle(type === 'create' ? t('mailTemplate.create') : t('mailTemplate.edit'));
     setFormType(type as 'create' | 'update');
     form.resetFields();
 
@@ -44,7 +46,7 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
           remark: data.remark,
         });
       } catch (error: any) {
-        message.error(error.message || '获取邮件模板详情失败');
+        message.error(error.message || t('mailTemplate.detailFailed'));
       } finally {
         setFormLoading(false);
       }
@@ -73,15 +75,15 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
 
         if (formType === 'create') {
           await emailTemplateApi.createMailTemplate(data);
-          message.success('创建成功');
+          message.success(t('common.createSuccess'));
         } else {
           await emailTemplateApi.updateMailTemplate(data);
-          message.success('更新成功');
+          message.success(t('common.updateSuccess'));
         }
         setDialogVisible(false);
         onSuccess?.();
       } catch (error: any) {
-        message.error(error.message || '操作失败');
+        message.error(error.message || t('common.operationFailed'));
       } finally {
         setFormLoading(false);
       }
@@ -97,8 +99,9 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
       onCancel={() => setDialogVisible(false)}
       onOk={submitForm}
       confirmLoading={formLoading}
-      width={800}
+      width={1000}
       destroyOnClose
+      style={{ top: 20 }}
     >
       <Form
         form={form}
@@ -111,20 +114,20 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
         <Row gutter={16}>
           <Col span={12}>
             <Form.Item
-              label="模板名称"
+              label={t('mailTemplate.name')}
               name="name"
-              rules={[{ required: true, message: '模板名称不能为空' }]}
+              rules={[{ required: true, message: t('mailTemplate.nameRequired') }]}
             >
-              <Input placeholder="请输入模板名称" />
+              <Input placeholder={t('mailTemplate.namePlaceholder')} />
             </Form.Item>
           </Col>
           <Col span={12}>
             <Form.Item
-              label="模板编码"
+              label={t('mailTemplate.code')}
               name="code"
-              rules={[{ required: true, message: '模板编码不能为空' }]}
+              rules={[{ required: true, message: t('mailTemplate.codeRequired') }]}
             >
-              <Input placeholder="请输入模板编码" />
+              <Input placeholder={t('mailTemplate.codePlaceholder')} />
             </Form.Item>
           </Col>
         </Row>
@@ -132,59 +135,62 @@ const MailTemplateForm = forwardRef<MailTemplateFormRef, MailTemplateFormProps>(
         <Row gutter={16}>
           <Col span={12}>
             <Form.Item
-              label="账号ID"
+              label={t('mailTemplate.accountId')}
               name="accountId"
-              rules={[{ required: true, message: '账号ID不能为空' }]}
+              rules={[{ required: true, message: t('mailTemplate.accountIdRequired') }]}
             >
-              <InputNumber placeholder="请输入账号ID" style={{ width: '100%' }} />
+              <InputNumber placeholder={t('mailTemplate.accountIdPlaceholder')} style={{ width: '100%' }} />
             </Form.Item>
           </Col>
           <Col span={12}>
-            <Form.Item label="昵称" name="nickname">
-              <Input placeholder="请输入昵称" />
+            <Form.Item label={t('mailTemplate.nickname')} name="nickname">
+              <Input placeholder={t('mailTemplate.nicknamePlaceholder')} />
             </Form.Item>
           </Col>
         </Row>
 
         <Row gutter={16}>
           <Col span={12}>
-            <Form.Item label="标题" name="title">
-              <Input placeholder="请输入标题" />
+            <Form.Item label={t('mailTemplate.title')} name="title">
+              <Input placeholder={t('common.pleaseEnter')} />
             </Form.Item>
           </Col>
           <Col span={12}>
-            <Form.Item label="状态" name="status">
-              <Select placeholder="请选择状态">
-                <Select.Option value={1}>启用</Select.Option>
-                <Select.Option value={0}>禁用</Select.Option>
+            <Form.Item label={t('mailTemplate.status')} name="status">
+              <Select placeholder={t('mailTemplate.statusPlaceholder')}>
+                <Select.Option value={1}>{t('mailTemplate.enable')}</Select.Option>
+                <Select.Option value={0}>{t('mailTemplate.disable')}</Select.Option>
               </Select>
             </Form.Item>
           </Col>
         </Row>
 
-        <Row gutter={16}>
-          <Col span={24}>
-            <Form.Item label="模板内容" name="content">
-              <TextArea rows={6} placeholder="请输入模板内容" />
-            </Form.Item>
-          </Col>
-        </Row>
-
-        <Row gutter={16}>
-          <Col span={24}>
-            <Form.Item label="参数" name="params">
-              <Input placeholder="请输入参数,多个参数用逗号分隔,如:name,code" />
-            </Form.Item>
-          </Col>
-        </Row>
-
-        <Row gutter={16}>
-          <Col span={24}>
-            <Form.Item label="备注" name="remark">
-              <TextArea rows={3} placeholder="请输入备注" />
-            </Form.Item>
-          </Col>
-        </Row>
+        <Form.Item
+          label={t('mailTemplate.content')}
+          name="content"
+          labelCol={{ span: 4 }}
+          wrapperCol={{ span: 20 }}
+        >
+          <TextArea rows={6} placeholder={t('mailTemplate.contentPlaceholder')} />
+        </Form.Item>
+
+        <Form.Item
+          label={t('mailTemplate.params')}
+          name="params"
+          labelCol={{ span: 4 }}
+          wrapperCol={{ span: 20 }}
+        >
+          <Input placeholder={t('mailTemplate.paramsPlaceholder')} />
+        </Form.Item>
+
+        <Form.Item
+          label={t('mailTemplate.remark')}
+          name="remark"
+          labelCol={{ span: 4 }}
+          wrapperCol={{ span: 20 }}
+        >
+          <TextArea rows={3} placeholder={t('common.pleaseEnter')} />
+        </Form.Item>
       </Form>
     </Modal>
   );

+ 32 - 30
src/components/mailTemplate/MailTemplateManagement.tsx

@@ -1,4 +1,5 @@
 import React, { useState, useEffect, useRef } from 'react';
+import { useTranslation } from 'react-i18next';
 import { Search, Plus, RefreshCw, ArrowLeft, Edit2, Trash2 } from 'lucide-react';
 import { emailTemplateApi, MailTemplateVO } from '../../api/emailTemplate';
 import { toast } from 'sonner';
@@ -14,6 +15,7 @@ interface MailTemplateManagementProps {
 }
 
 export default function MailTemplateManagement(props: MailTemplateManagementProps = {}) {
+  const { t } = useTranslation();
   const { onBack } = props;
   const [loading, setLoading] = useState(true);
   const [list, setList] = useState<MailTemplateVO[]>([]);
@@ -39,7 +41,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
       setList(response.list || []);
       setTotal(response.total || 0);
     } catch (error: any) {
-      toast.error(error.message || '获取邮件模板列表失败');
+      toast.error(error.message || t('mailTemplate.fetchListFailed'));
     } finally {
       setLoading(false);
     }
@@ -83,19 +85,19 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
   // 删除
   const handleDelete = (id: number) => {
     Modal.confirm({
-      title: '确认删除',
+      title: t('common.confirmDelete'),
       icon: <ExclamationCircleOutlined />,
-      content: '确定要删除这条邮件模板吗?',
-      okText: '确定',
+      content: t('notificationManagement.deleteEmailConfirmContent'),
+      okText: t('common.confirm'),
       okType: 'danger',
-      cancelText: '取消',
+      cancelText: t('common.cancel'),
       onOk: async () => {
         try {
           await emailTemplateApi.deleteMailTemplate(id);
-          toast.success('删除成功');
+          toast.success(t('common.deleteSuccess'));
           await getList();
         } catch (error: any) {
-          toast.error(error.message || '删除失败');
+          toast.error(error.message || t('common.deleteFailed'));
         }
       },
     });
@@ -104,7 +106,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
   // 表格列配置
   const columns: ColumnsType<MailTemplateVO> = [
     {
-      title: '序号',
+      title: t('common.serialNumber'),
       width: 80,
       align: 'center',
       render: (_: any, __: MailTemplateVO, index: number) => {
@@ -112,42 +114,42 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
       },
     },
     {
-      title: '模板名称',
+      title: t('mailTemplate.name'),
       dataIndex: 'name',
       key: 'name',
       align: 'center',
     },
     {
-      title: '模板编码',
+      title: t('mailTemplate.code'),
       dataIndex: 'code',
       key: 'code',
       align: 'center',
     },
     {
-      title: '标题',
+      title: t('mailTemplate.title'),
       dataIndex: 'title',
       key: 'title',
       align: 'center',
       render: (text: string) => text || '-',
     },
     {
-      title: '状态',
+      title: t('mailTemplate.status'),
       dataIndex: 'status',
       width: 100,
       align: 'center',
       render: (status: number | undefined) => {
-        return status === 1 ? '启用' : '禁用';
+        return status === 1 ? t('mailTemplate.enable') : t('mailTemplate.disable');
       },
     },
     {
-      title: '备注',
+      title: t('mailTemplate.remark'),
       dataIndex: 'remark',
       key: 'remark',
       align: 'center',
       render: (text: string) => text || '-',
     },
     {
-      title: '操作',
+      title: t('common.operation'),
       width: 200,
       align: 'center',
       fixed: 'right',
@@ -161,7 +163,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
               className="h-8 px-2 transition-colors hover:text-[#1677ff] hover:underline"
             >
               <Search className="w-4 h-4" />
-              <span className="ml-1">测试</span>
+              <span className="ml-1">{t('mailTemplate.test')}</span>
             </UIButton>
             <UIButton
               variant="ghost"
@@ -170,7 +172,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
               className="h-8 px-2 transition-colors hover:text-[#1677ff] hover:underline"
             >
               <Edit2 className="w-4 h-4" />
-              <span className="ml-1">编辑</span>
+              <span className="ml-1">{t('common.edit')}</span>
             </UIButton>
             <UIButton
               variant="ghost"
@@ -179,7 +181,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
               className="h-8 px-2 text-red-600 hover:text-[#1677ff] transition-colors hover:underline"
             >
               <Trash2 className="w-4 h-4" />
-              <span className="ml-1">删除</span>
+              <span className="ml-1">{t('common.delete')}</span>
             </UIButton>
           </div>
         );
@@ -193,9 +195,9 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
       <div className="bg-white rounded-2xl border border-gray-200/50 shadow-sm p-6">
         <div className="flex items-center gap-4 flex-wrap">
           <div className="flex items-center gap-2 flex-1 min-w-[200px]">
-            <label className="text-sm text-gray-700 whitespace-nowrap">模板名称:</label>
+            <label className="text-sm text-gray-700 whitespace-nowrap">{t('mailTemplate.name')}:</label>
             <Input
-              placeholder="请输入模板名称"
+              placeholder={t('mailTemplate.namePlaceholder')}
               value={queryParams.name}
               onChange={(e) => setQueryParams({ ...queryParams, name: e.target.value })}
               onPressEnter={handleQuery}
@@ -204,9 +206,9 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
             />
           </div>
           <div className="flex items-center gap-2 flex-1 min-w-[200px]">
-            <label className="text-sm text-gray-700 whitespace-nowrap">模板编码:</label>
+            <label className="text-sm text-gray-700 whitespace-nowrap">{t('mailTemplate.code')}:</label>
             <Input
-              placeholder="请输入模板编码"
+              placeholder={t('mailTemplate.codePlaceholder')}
               value={queryParams.code}
               onChange={(e) => setQueryParams({ ...queryParams, code: e.target.value })}
               onPressEnter={handleQuery}
@@ -220,24 +222,24 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
               icon={<Search className="w-4 h-4" />}
               onClick={handleQuery}
             >
-              搜索
+              {t('common.search')}
             </Button>
             <Button icon={<RefreshCw className="w-4 h-4" />} onClick={resetQuery}>
-              重置
+              {t('common.reset')}
             </Button>
             <Button
               type="primary"
               icon={<Plus className="w-4 h-4" />}
               onClick={() => openForm('create')}
             >
-              新增
+              {t('common.addNew')}
             </Button>
             {onBack && (
               <Button
                 icon={<ArrowLeft className="w-4 h-4" />}
                 onClick={onBack}
               >
-                返回邮件提醒
+                {t('mailTemplate.backToEmailNotify')}
               </Button>
             )}
           </div>
@@ -259,7 +261,7 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
           <div className="bg-white rounded-lg border border-gray-200 px-6 py-4">
             <div className="flex items-center justify-between">
               <div className="text-sm text-gray-600">
-                共 <span className="text-blue-600 font-medium">{total}</span> 条记录
+                {t('common.total')} <span className="text-blue-600 font-medium">{total}</span> {t('common.records')}
               </div>
               <div className="flex items-center gap-2">
                 <Button
@@ -267,17 +269,17 @@ export default function MailTemplateManagement(props: MailTemplateManagementProp
                   disabled={queryParams.pageNo === 1}
                   onClick={() => setQueryParams({ ...queryParams, pageNo: queryParams.pageNo - 1 })}
                 >
-                  上一页
+                  {t('common.prevPage')}
                 </Button>
                 <span className="text-sm text-gray-600">
-                  {queryParams.pageNo} / {Math.ceil(total / queryParams.pageSize)}
+                  {queryParams.pageNo} / {Math.ceil(total / queryParams.pageSize) || 1}
                 </span>
                 <Button
                   size="small"
                   disabled={queryParams.pageNo >= Math.ceil(total / queryParams.pageSize)}
                   onClick={() => setQueryParams({ ...queryParams, pageNo: queryParams.pageNo + 1 })}
                 >
-                  下一页
+                  {t('common.nextPage')}
                 </Button>
               </div>
             </div>

+ 17 - 17
src/components/notification/EmailNotifyForm.tsx

@@ -23,10 +23,10 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
 
   // 时间单位配置
   const timeUnits = [
-    { name: 'days', label: '天', options: Array.from({ length: 31 }, (_, i) => i) },
-    { name: 'hours', label: '小时', options: Array.from({ length: 24 }, (_, i) => i) },
-    { name: 'minutes', label: '分钟', options: Array.from({ length: 60 }, (_, i) => i) },
-    { name: 'seconds', label: '秒', options: Array.from({ length: 60 }, (_, i) => i) },
+    { name: 'days', label: t('common.day'), options: Array.from({ length: 31 }, (_, i) => i) },
+    { name: 'hours', label: t('common.hour'), options: Array.from({ length: 24 }, (_, i) => i) },
+    { name: 'minutes', label: t('common.minute'), options: Array.from({ length: 60 }, (_, i) => i) },
+    { name: 'seconds', label: t('common.second'), options: Array.from({ length: 60 }, (_, i) => i) },
   ];
 
   const [timeValues, setTimeValues] = useState({
@@ -39,7 +39,7 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
   // 打开弹窗
   const open = async (type: string, id?: number) => {
     setDialogVisible(true);
-    setDialogTitle(type === 'create' ? '新增邮件提醒' : '编辑邮件提醒');
+    setDialogTitle(type === 'create' ? t('notificationManagement.addEmailNotify') : t('notificationManagement.editEmailNotify'));
     setFormType(type as 'create' | 'update');
     form.resetFields();
     setTimeValues({ days: 0, hours: 0, minutes: 0, seconds: 0 });
@@ -57,7 +57,7 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
         }))
       );
     } catch (error) {
-      console.error('加载邮件模板列表失败:', error);
+      console.error(t('mailTemplate.fetchListFailed'), error);
       setTemplateList([]);
     }
 
@@ -82,7 +82,7 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
           seconds: totalSeconds % 60,
         });
       } catch (error: any) {
-        message.error(error.message || '获取邮件提醒详情失败');
+        message.error(error.message || t('notificationManagement.getEmailListFailed'));
       } finally {
         setFormLoading(false);
       }
@@ -111,15 +111,15 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
 
         if (formType === 'create') {
           await mailNotifyConfigApi.addIsMailNotifyConfig(data);
-          message.success('创建成功');
+          message.success(t('common.createSuccess'));
         } else {
           await mailNotifyConfigApi.updateIsMailNotifyConfig(data);
-          message.success('更新成功');
+          message.success(t('common.updateSuccess'));
         }
         setDialogVisible(false);
         onSuccess?.();
       } catch (error: any) {
-        message.error(error.message || '操作失败');
+        message.error(error.message || t('common.operationFailed'));
       } finally {
         setFormLoading(false);
       }
@@ -149,22 +149,22 @@ const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({
         }}
       >
         <Form.Item
-          label="提醒事项"
+          label={t('notificationManagement.reminderItem')}
           name="name"
-          rules={[{ required: true, message: '提醒事项不能为空' }]}
+          rules={[{ required: true, message: t('notificationManagement.reminderItemRequired') }]}
         >
-          <Input placeholder="请输入提醒事项" />
+          <Input placeholder={t('notificationManagement.placeholderReminderItem')} />
         </Form.Item>
 
         <Form.Item
-          label="邮件模板"
+          label={t('notificationManagement.setMailTemplate')}
           name="templateCode"
-          rules={[{ required: true, message: '邮件模板不能为空' }]}
+          rules={[{ required: true, message: t('notificationManagement.mailTemplateRequired') }]}
         >
-          <Select placeholder="请选择邮件模板" options={templateList} />
+          <Select placeholder={t('common.pleaseSelect')} options={templateList} />
         </Form.Item>
 
-        <Form.Item label="提醒时长" required>
+        <Form.Item label={t('notificationManagement.reminderDuration')} required>
           <Row gutter={[16, 0]}>
             {timeUnits.map((unit, index) => (
               <Col key={index} span={6}>

+ 33 - 0
src/locales/en.json

@@ -84,9 +84,13 @@
     "app": "App",
     "reminderItem": "Reminder Item",
     "placeholderReminderItem": "Enter reminder item",
+    "reminderItemRequired": "Reminder item cannot be empty",
+    "mailTemplateRequired": "Mail template cannot be empty",
     "isActive": "Active",
     "templateCode": "Template Code",
     "reminderDuration": "Reminder Duration",
+    "addEmailNotify": "Add Email Notification",
+    "editEmailNotify": "Edit Email Notification",
     "getEmailListFailed": "Failed to load email reminder list",
     "deleteEmailConfirmContent": "Are you sure you want to delete this email reminder config?",
     "activateSuccess": "Activated successfully",
@@ -173,6 +177,35 @@
     "readLabel": "Read",
     "detailLabel": "Detail"
   },
+  "mailTemplate": {
+    "name": "Template Name",
+    "namePlaceholder": "Enter template name",
+    "code": "Template Code",
+    "codePlaceholder": "Enter template code",
+    "title": "Title",
+    "status": "Status",
+    "remark": "Remark",
+    "test": "Test",
+    "backToEmailNotify": "Back to Email Notification",
+    "fetchListFailed": "Failed to load mail template list",
+    "detailFailed": "Failed to load mail template detail",
+    "create": "Create Mail Template",
+    "edit": "Edit Mail Template",
+    "content": "Template Content",
+    "contentPlaceholder": "Enter template content",
+    "params": "Parameters",
+    "paramsPlaceholder": "Enter parameters, separated by commas, e.g.: name,code",
+    "accountId": "Account ID",
+    "accountIdPlaceholder": "Enter account ID",
+    "accountIdRequired": "Account ID cannot be empty",
+    "nameRequired": "Template name cannot be empty",
+    "codeRequired": "Template code cannot be empty",
+    "nickname": "Nickname",
+    "nicknamePlaceholder": "Enter nickname",
+    "statusPlaceholder": "Select status",
+    "enable": "Enabled",
+    "disable": "Disabled"
+  },
   "hardwareManagement": {
     "cabinet": "Cabinet",
     "key": "Key",

+ 33 - 0
src/locales/zh.json

@@ -84,9 +84,13 @@
     "app": "APP通知",
     "reminderItem": "提醒事项",
     "placeholderReminderItem": "请输入提醒事项",
+    "reminderItemRequired": "提醒事项不能为空",
+    "mailTemplateRequired": "邮件模板不能为空",
     "isActive": "是否激活",
     "templateCode": "邮件模板编码",
     "reminderDuration": "提醒时长",
+    "addEmailNotify": "新增邮件提醒",
+    "editEmailNotify": "编辑邮件提醒",
     "getEmailListFailed": "获取邮件提醒列表失败",
     "deleteEmailConfirmContent": "确定要删除这条邮件提醒配置吗?",
     "activateSuccess": "激活成功",
@@ -173,6 +177,35 @@
     "readLabel": "阅读",
     "detailLabel": "详情"
   },
+  "mailTemplate": {
+    "name": "模板名称",
+    "namePlaceholder": "请输入模板名称",
+    "code": "模板编码",
+    "codePlaceholder": "请输入模板编码",
+    "title": "标题",
+    "status": "状态",
+    "remark": "备注",
+    "test": "测试",
+    "backToEmailNotify": "返回邮件提醒",
+    "fetchListFailed": "获取邮件模板列表失败",
+    "detailFailed": "获取邮件模板详情失败",
+    "create": "新增邮件模板",
+    "edit": "编辑邮件模板",
+    "content": "模板内容",
+    "contentPlaceholder": "请输入模板内容",
+    "params": "参数",
+    "paramsPlaceholder": "请输入参数,多个参数用逗号分隔,如:name,code",
+    "accountId": "账号ID",
+    "accountIdPlaceholder": "请输入账号ID",
+    "accountIdRequired": "账号ID不能为空",
+    "nameRequired": "模板名称不能为空",
+    "codeRequired": "模板编码不能为空",
+    "nickname": "昵称",
+    "nicknamePlaceholder": "请输入昵称",
+    "statusPlaceholder": "请选择状态",
+    "enable": "启用",
+    "disable": "禁用"
+  },
   "hardwareManagement": {
     "cabinet": "机柜",
     "key": "钥匙",