EmailNotifyForm.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import React, { useState, useImperativeHandle, forwardRef, useEffect } from 'react';
  2. import { Modal, Form, Input, Select, Row, Col, message } from 'antd';
  3. import { mailNotifyConfigApi, MailNotifyConfigVO } from '../../api/mailNotifyConfig';
  4. import { emailTemplateApi } from '../../api/emailTemplate';
  5. import { useTranslation } from 'react-i18next';
  6. interface EmailNotifyFormProps {
  7. onSuccess?: () => void;
  8. }
  9. export interface EmailNotifyFormRef {
  10. open: (type: string, id?: number) => void;
  11. }
  12. // 提醒时长下拉选项:天 0-30,时 0-23,分 0-59,秒 0-59
  13. const DURATION_DAYS_OPTIONS = Array.from({ length: 31 }, (_, i) => i);
  14. const DURATION_HOURS_OPTIONS = Array.from({ length: 24 }, (_, i) => i);
  15. const DURATION_MINUTES_OPTIONS = Array.from({ length: 60 }, (_, i) => i);
  16. const DURATION_SECONDS_OPTIONS = Array.from({ length: 60 }, (_, i) => i);
  17. const EmailNotifyForm = forwardRef<EmailNotifyFormRef, EmailNotifyFormProps>(({ onSuccess }, ref) => {
  18. const { t } = useTranslation();
  19. const [dialogVisible, setDialogVisible] = useState(false);
  20. const [dialogTitle, setDialogTitle] = useState('');
  21. const [formLoading, setFormLoading] = useState(false);
  22. const [formType, setFormType] = useState<'create' | 'update'>('create');
  23. const [form] = Form.useForm();
  24. const [templateList, setTemplateList] = useState<Array<{ label: string; value: string }>>([]);
  25. const timeUnits = [
  26. { name: 'days', label: t('common.day'), options: DURATION_DAYS_OPTIONS },
  27. { name: 'hours', label: t('common.hour'), options: DURATION_HOURS_OPTIONS },
  28. { name: 'minutes', label: t('common.minute'), options: DURATION_MINUTES_OPTIONS },
  29. { name: 'seconds', label: t('common.second'), options: DURATION_SECONDS_OPTIONS },
  30. ];
  31. const [timeValues, setTimeValues] = useState({
  32. days: 0,
  33. hours: 0,
  34. minutes: 0,
  35. seconds: 0,
  36. });
  37. // 打开弹窗
  38. const open = async (type: string, id?: number) => {
  39. setDialogVisible(true);
  40. setDialogTitle(type === 'create' ? t('notificationManagement.addEmailNotify') : t('notificationManagement.editEmailNotify'));
  41. setFormType(type as 'create' | 'update');
  42. form.resetFields();
  43. setTimeValues({ days: 0, hours: 0, minutes: 0, seconds: 0 });
  44. // 先加载邮件模板列表(编辑时回显模板依赖该列表)
  45. let templates: Array<{ label: string; value: string }> = [];
  46. try {
  47. const response = await emailTemplateApi.getMailTemplatePage({
  48. pageNo: 1,
  49. pageSize: -1,
  50. });
  51. templates = (response.list || []).map((item) => ({
  52. label: item.name,
  53. value: item.code,
  54. }));
  55. setTemplateList(templates);
  56. } catch (error) {
  57. console.error(t('mailTemplate.fetchListFailed'), error);
  58. setTemplateList([]);
  59. }
  60. // 修改时,拉取详情并回显(调用 iscs/mail-notify-config/selectMailNotifyConfigById?id=xxx)
  61. if (type === 'update' && (id == null || id === undefined)) {
  62. message.warning(t('notificationManagement.getEmailListFailed') || '缺少记录 ID,无法加载详情');
  63. return;
  64. }
  65. if (id) {
  66. setFormLoading(true);
  67. try {
  68. const data = await mailNotifyConfigApi.getIsMailNotifyConfigById(id);
  69. if (!data) {
  70. message.error(t('notificationManagement.getEmailListFailed'));
  71. return;
  72. }
  73. const recordId = (data as any).id ?? data.configId;
  74. const name = data.name ?? data.configName ?? '';
  75. let templateCode = data.templateCode ?? (data as any).templateCode ?? '';
  76. if (!templateCode && (data as any).templateName && templates.length > 0) {
  77. const byName = templates.find((t) => t.label === (data as any).templateName);
  78. if (byName) templateCode = byName.value;
  79. }
  80. const status = data.status != null ? String(data.status) : '1';
  81. form.setFieldsValue({
  82. id: recordId,
  83. name,
  84. templateCode,
  85. status,
  86. });
  87. const totalSeconds = Number(data.reminderTime) || 0;
  88. setTimeValues({
  89. days: Math.floor(totalSeconds / (24 * 60 * 60)),
  90. hours: Math.floor((totalSeconds % (24 * 60 * 60)) / (60 * 60)),
  91. minutes: Math.floor((totalSeconds % (60 * 60)) / 60),
  92. seconds: totalSeconds % 60,
  93. });
  94. } catch (error: any) {
  95. message.error(error?.message || t('notificationManagement.getEmailListFailed'));
  96. } finally {
  97. setFormLoading(false);
  98. }
  99. }
  100. };
  101. useImperativeHandle(ref, () => ({
  102. open,
  103. }));
  104. // 提交表单
  105. const submitForm = async () => {
  106. try {
  107. const values = await form.validateFields();
  108. setFormLoading(true);
  109. try {
  110. // 计算总秒数
  111. const totalSeconds =
  112. ((timeValues.days * 24 + timeValues.hours) * 60 + timeValues.minutes) * 60 + timeValues.seconds;
  113. const data: MailNotifyConfigVO = {
  114. ...values,
  115. reminderTime: totalSeconds,
  116. };
  117. if (formType === 'create') {
  118. await mailNotifyConfigApi.addIsMailNotifyConfig(data);
  119. message.success(t('notificationManagement.addEmailNotifySuccess') || '邮件提醒新增成功');
  120. } else {
  121. await mailNotifyConfigApi.updateIsMailNotifyConfig(data);
  122. message.success(t('notificationManagement.updateEmailNotifySuccess') || '邮件提醒保存成功');
  123. }
  124. setDialogVisible(false);
  125. onSuccess?.();
  126. } catch (error: any) {
  127. message.error(error.message || t('common.operationFailed'));
  128. } finally {
  129. setFormLoading(false);
  130. }
  131. } catch (error) {
  132. // 表单验证失败
  133. }
  134. };
  135. return (
  136. <Modal
  137. title={dialogTitle}
  138. open={dialogVisible}
  139. onCancel={() => setDialogVisible(false)}
  140. onOk={submitForm}
  141. okText={t('common.save')}
  142. cancelText={t('common.cancel')}
  143. confirmLoading={formLoading}
  144. width={800}
  145. destroyOnHidden
  146. >
  147. <Form
  148. form={form}
  149. labelCol={{ span: 6 }}
  150. wrapperCol={{ span: 18 }}
  151. initialValues={{
  152. status: '1',
  153. }}
  154. >
  155. <Form.Item name="id" hidden>
  156. <Input type="hidden" />
  157. </Form.Item>
  158. <Form.Item
  159. label={t('notificationManagement.reminderItem')}
  160. name="name"
  161. rules={[{ required: true, message: t('notificationManagement.reminderItemRequired') }]}
  162. >
  163. <Input placeholder={t('notificationManagement.placeholderReminderItem')} />
  164. </Form.Item>
  165. <Form.Item
  166. label={t('notificationManagement.setMailTemplate')}
  167. name="templateCode"
  168. rules={[{ required: true, message: t('notificationManagement.mailTemplateRequired') }]}
  169. >
  170. <Select placeholder={t('common.pleaseSelect')} options={templateList} />
  171. </Form.Item>
  172. <Form.Item label={t('notificationManagement.reminderDuration')} required>
  173. <Row gutter={[16, 0]}>
  174. {timeUnits.map((unit, index) => (
  175. <Col key={index} span={6}>
  176. <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
  177. <Select
  178. value={timeValues[unit.name as keyof typeof timeValues]}
  179. onChange={(value) => {
  180. setTimeValues((prev) => ({
  181. ...prev,
  182. [unit.name]: value,
  183. }));
  184. }}
  185. style={{ width: '100%', minWidth: 100 }}
  186. >
  187. {unit.options.map((option) => (
  188. <Select.Option key={option} value={option}>
  189. {option}
  190. </Select.Option>
  191. ))}
  192. </Select>
  193. <span style={{ fontSize: '14px', color: '#333', whiteSpace: 'nowrap' }}>{unit.label}</span>
  194. </div>
  195. </Col>
  196. ))}
  197. </Row>
  198. </Form.Item>
  199. </Form>
  200. </Modal>
  201. );
  202. });
  203. EmailNotifyForm.displayName = 'EmailNotifyForm';
  204. export default EmailNotifyForm;