维护通知中心多语言

This commit is contained in:
linxd
2025-06-30 19:00:57 +08:00
parent 3a69b8922e
commit 29f08b3657
7 changed files with 332 additions and 89 deletions

View File

@ -7,6 +7,7 @@ import policyManage from './en-US/policyManage';
import userQuestion from './en-US/userQuestion';
import friendLink from './en-US/friendLink';
import downloadManage from './en-US/downloadManage';
import noticeManage from './en-US/noticeManage';
export default {
...common,
@ -18,4 +19,5 @@ export default {
...userQuestion,
...friendLink,
...downloadManage,
...noticeManage,
};

View File

@ -0,0 +1,92 @@
export default {
// Page Title
'notice.title': 'Notification Center',
'notice.selected.count': 'Selected {count} items',
'notice.warning.select.required': 'Please select records to delete',
'notice.warning.published.delete': 'Published notices cannot be deleted',
'notice.confirm.batchDelete': 'Are you sure you want to delete {count} selected notices?',
'notice.confirm.batchDelete.content': 'This cannot be undone',
'notice.form.status.placeholder': 'Please select status',
// Form and Table Fields
'notice.field.title': 'Title',
'notice.field.titleEn': 'Title (English)',
'notice.field.content': 'Content',
'notice.field.contentEn': 'Content (English)',
'notice.field.status': 'Status',
'notice.field.date': 'Date',
'notice.field.publisher': 'Publisher',
'notice.field.operation': 'Operation',
'notice.field.isTop': 'Pin to Top',
'notice.field.settingEn': 'Set English Content',
// Status
'notice.status.draft': 'Draft',
'notice.status.published': 'Published',
'notice.status.unpublished': 'Unpublished',
// Buttons and Actions
'notice.button.add': 'Add',
'notice.button.edit': 'Edit',
'notice.button.delete': 'Delete',
'notice.button.view': 'View',
'notice.button.publish': 'Publish',
'notice.button.unpublish': 'Unpublish',
'notice.button.top': 'Pin to Top',
'notice.button.untop': 'Unpin',
'notice.button.search': 'Search',
'notice.button.reset': 'Reset',
'notice.button.submit': 'Submit',
'notice.button.cancel': 'Cancel',
'notice.button.close': 'Close',
// Confirmations
'notice.confirm.delete': 'Are you sure you want to delete this notice?',
'notice.confirm.publish': 'Are you sure you want to publish this notice?',
'notice.confirm.unpublish': 'Are you sure you want to unpublish this notice?',
'notice.confirm.top': 'Are you sure you want to pin this notice to top?',
'notice.confirm.untop': 'Are you sure you want to unpin this notice?',
// Form Hints
'notice.form.title.placeholder': 'Please enter title',
'notice.form.title.required': 'Please enter title',
'notice.form.titleEn.placeholder': 'Please enter English title',
'notice.form.titleEn.required': 'Please enter English title',
'notice.form.content.placeholder': 'Please enter content',
'notice.form.content.required': 'Please enter content',
'notice.form.contentEn.placeholder': 'Please enter English content',
'notice.form.contentEn.required': 'Please enter English content',
// Success and Failure Messages
'notice.message.get.success': 'Successfully retrieved list',
'notice.message.get.fail': 'Failed to retrieve list',
'notice.message.detail.success': 'Successfully retrieved details',
'notice.message.detail.fail': 'Failed to retrieve details',
'notice.message.add.success': 'Successfully added',
'notice.message.add.fail': 'Failed to add',
'notice.message.update.success': 'Successfully updated',
'notice.message.update.fail': 'Failed to update',
'notice.message.delete.success': 'Successfully deleted',
'notice.message.delete.fail': 'Failed to delete',
'notice.message.publish.success': 'Successfully published',
'notice.message.publish.fail': 'Failed to publish',
'notice.message.unpublish.success': 'Successfully unpublished',
'notice.message.unpublish.fail': 'Failed to unpublish',
'notice.message.top.success': 'Successfully pinned to top',
'notice.message.top.fail': 'Failed to pin to top',
'notice.message.untop.success': 'Successfully unpinned',
'notice.message.untop.fail': 'Failed to unpin',
// Options
'notice.option.yes': 'Yes',
'notice.option.no': 'No',
// Tabs
'notice.tab.chinese': 'Chinese Version',
'notice.tab.english': 'English Version',
// Form Titles
'notice.view.title': 'View Notice',
'notice.edit.title': 'Edit Notice',
'notice.add.title': 'Add Notice',
};

View File

@ -7,6 +7,7 @@ import policyManage from './zh-CN/policyManage';
import userQuestion from './zh-CN/userQuestion';
import friendLink from './zh-CN/friendLink';
import downloadManage from './zh-CN/downloadManage';
import noticeManage from './zh-CN/noticeManage';
export default {
...common,
@ -18,4 +19,5 @@ export default {
...userQuestion,
...friendLink,
...downloadManage,
...noticeManage,
};

View File

@ -0,0 +1,92 @@
export default {
// 页面标题
'notice.title': '通知中心',
'notice.selected.count': '已选择 {count} 项',
'notice.warning.select.required': '请选择需要删除的记录',
'notice.warning.published.delete': '已发布的通知不能删除',
'notice.confirm.batchDelete': '确定要删除选中的 {count} 条通知吗?',
'notice.confirm.batchDelete.content': '删除后无法恢复',
'notice.form.status.placeholder': '请选择状态',
// 表单和表格字段
'notice.field.title': '标题',
'notice.field.titleEn': '标题(英文)',
'notice.field.content': '内容',
'notice.field.contentEn': '内容(英文)',
'notice.field.status': '状态',
'notice.field.date': '日期',
'notice.field.publisher': '发布人',
'notice.field.operation': '操作',
'notice.field.isTop': '是否置顶',
'notice.field.settingEn': '是否设置英文内容',
// 状态
'notice.status.draft': '草稿',
'notice.status.published': '已发布',
'notice.status.unpublished': '已下架',
// 按钮和操作
'notice.button.add': '新增',
'notice.button.edit': '编辑',
'notice.button.delete': '删除',
'notice.button.view': '查看',
'notice.button.publish': '发布',
'notice.button.unpublish': '下架',
'notice.button.top': '置顶',
'notice.button.untop': '取消置顶',
'notice.button.search': '搜索',
'notice.button.reset': '重置',
'notice.button.submit': '提交',
'notice.button.cancel': '取消',
'notice.button.close': '关闭',
// 提示和确认框
'notice.confirm.delete': '确定要删除该通知吗?',
'notice.confirm.publish': '确定要发布该通知吗?',
'notice.confirm.unpublish': '确定要下架该通知吗?',
'notice.confirm.top': '确定要置顶该通知吗?',
'notice.confirm.untop': '确定要取消置顶该通知吗?',
// 表单提示
'notice.form.title.placeholder': '请输入标题',
'notice.form.title.required': '请输入标题',
'notice.form.titleEn.placeholder': '请输入英文标题',
'notice.form.titleEn.required': '请输入英文标题',
'notice.form.content.placeholder': '请输入通知内容',
'notice.form.content.required': '请输入通知内容',
'notice.form.contentEn.placeholder': '请输入英文通知内容',
'notice.form.contentEn.required': '请输入英文通知内容',
// 成功和失败提示
'notice.message.get.success': '获取列表成功',
'notice.message.get.fail': '获取列表失败',
'notice.message.detail.success': '获取详情成功',
'notice.message.detail.fail': '获取详情失败',
'notice.message.add.success': '添加成功',
'notice.message.add.fail': '添加失败',
'notice.message.update.success': '更新成功',
'notice.message.update.fail': '更新失败',
'notice.message.delete.success': '删除成功',
'notice.message.delete.fail': '删除失败',
'notice.message.publish.success': '发布成功',
'notice.message.publish.fail': '发布失败',
'notice.message.unpublish.success': '下架成功',
'notice.message.unpublish.fail': '下架失败',
'notice.message.top.success': '置顶成功',
'notice.message.top.fail': '置顶失败',
'notice.message.untop.success': '取消置顶成功',
'notice.message.untop.fail': '取消置顶失败',
// 选项
'notice.option.yes': '是',
'notice.option.no': '否',
// 标签页
'notice.tab.chinese': '中文版',
'notice.tab.english': '英文版',
// 表单标题
'notice.view.title': '查看通知',
'notice.edit.title': '编辑通知',
'notice.add.title': '新增通知',
};

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import { Form, Input, Switch, Tabs, message, Button } from 'antd';
import { useIntl } from 'umi';
import WangEditor from '@/components/WangEidtor/WangEidtor';
import { TopStatus, EnglishSetting } from '@/dicts/noticeManageDict';
import { addNotice, updateNotice, getNoticeDetail } from '@/servers/api/notice';
@ -14,6 +15,7 @@ interface NoticeManageFormProps {
}
const NoticeManageForm: React.FC<NoticeManageFormProps> = ({ id, isEdit, onSuccess }) => {
const intl = useIntl();
const [form] = Form.useForm();
const [activeTabKey, setActiveTabKey] = useState<string>('zh');
const [loading, setLoading] = useState<boolean>(false);
@ -78,6 +80,7 @@ const NoticeManageForm: React.FC<NoticeManageFormProps> = ({ id, isEdit, onSucce
}
}
message.error(intl.formatMessage({ id: 'notice.message.validate.fail' }));
throw error;
}
@ -102,10 +105,14 @@ const NoticeManageForm: React.FC<NoticeManageFormProps> = ({ id, isEdit, onSucce
}
if (response && response.success) {
message.success(isEdit ? '更新成功' : '添加成功');
message.success(intl.formatMessage({
id: isEdit ? 'notice.message.update.success' : 'notice.message.add.success'
}));
onSuccess(); // 回调父组件
} else {
message.error(response.message || (isEdit ? '更新失败' : '添加失败'));
message.error(response.message || intl.formatMessage({
id: isEdit ? 'notice.message.update.fail' : 'notice.message.add.fail'
}));
}
} catch (error: any) {
console.error('表单验证或提交失败:', error);
@ -118,63 +125,69 @@ const NoticeManageForm: React.FC<NoticeManageFormProps> = ({ id, isEdit, onSucce
return (
<div>
<Form form={form} layout="vertical" name="noticeForm" preserve={false}>
<Form.Item name="isTop" label="是否置顶" valuePropName="checked">
<Form.Item name="isTop" label={intl.formatMessage({ id: 'notice.field.isTop' })} valuePropName="checked">
<Switch />
</Form.Item>
<Form.Item name="settingEn" label="是否设置英文内容" valuePropName="checked">
<Form.Item name="settingEn" label={intl.formatMessage({ id: 'notice.field.settingEn' })} valuePropName="checked">
<Switch />
</Form.Item>
<Tabs activeKey={activeTabKey} onChange={handleTabChange}>
<TabPane tab="中文版" key="zh" forceRender={true}>
<TabPane tab={intl.formatMessage({ id: 'notice.tab.chinese' })} key="zh" forceRender={true}>
<Form.Item
name="titleZh"
label="标题(中文)"
rules={[{ required: true, message: '请输入中文标题' }]}
label={intl.formatMessage({ id: 'notice.field.title' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'notice.form.title.required' }) }]}
>
<Input placeholder="请输入中文标题" />
<Input placeholder={intl.formatMessage({ id: 'notice.form.title.placeholder' })} />
</Form.Item>
<Form.Item
name="contentZh"
label="内容(中文)"
rules={[{ required: true, message: '请输入中文内容' }]}
label={intl.formatMessage({ id: 'notice.field.content' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'notice.form.content.required' }) }]}
>
<WangEditor language="zh-CN" height="300px" placeholder="请输入通知内容..." />
<WangEditor
language="zh-CN"
height="300px"
placeholder={intl.formatMessage({ id: 'notice.form.content.placeholder' })}
/>
</Form.Item>
</TabPane>
<TabPane tab="英文版" key="en" forceRender={true}>
<TabPane tab={intl.formatMessage({ id: 'notice.tab.english' })} key="en" forceRender={true}>
<Form.Item
name="titleEn"
label="标题(英文)"
rules={[{ required: form.getFieldValue('settingEn'), message: 'Please enter title in English' }]}
label={intl.formatMessage({ id: 'notice.field.titleEn' })}
rules={[{ required: form.getFieldValue('settingEn'), message: intl.formatMessage({ id: 'notice.form.titleEn.required' }) }]}
>
<Input placeholder="Please enter title in English" />
<Input placeholder={intl.formatMessage({ id: 'notice.form.titleEn.placeholder' })} />
</Form.Item>
<Form.Item
name="contentEn"
label="内容(英文)"
rules={[{ required: form.getFieldValue('settingEn'), message: 'Please enter content in English' }]}
label={intl.formatMessage({ id: 'notice.field.contentEn' })}
rules={[{ required: form.getFieldValue('settingEn'), message: intl.formatMessage({ id: 'notice.form.contentEn.required' }) }]}
>
<WangEditor
language="en"
height="300px"
placeholder="Please enter notice content..."
placeholder={intl.formatMessage({ id: 'notice.form.contentEn.placeholder' })}
/>
</Form.Item>
</TabPane>
</Tabs>
</Form>
<div className={styles.formActions}>
<Button onClick={() => onSuccess()}></Button>
<Button onClick={() => onSuccess()}>
{intl.formatMessage({ id: 'notice.button.cancel' })}
</Button>
<Button
type="primary"
loading={loading}
onClick={handleSubmit}
>
{intl.formatMessage({ id: 'notice.button.submit' })}
</Button>
</div>
</div>

View File

@ -1,4 +1,5 @@
import React from 'react';
import { useIntl } from 'umi';
import { Descriptions, Divider, Card, Tag } from 'antd';
import { NoticeStatus, NoticeStatusText, NoticeStatusColor } from '@/dicts/noticeManageDict';
import styles from './noticeManage.less';
@ -16,33 +17,39 @@ const getStatusTag = (status: string) => {
};
const NoticeManageInfo: React.FC<NoticeManageInfoProps> = ({ data }) => {
const intl = useIntl();
if (!data) return null;
return (
<div className={styles.noticeDetailView}>
<Descriptions bordered column={2} size="small">
<Descriptions.Item label="标题" span={2}>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.title' })} span={2}>
{data.title}
</Descriptions.Item>
{data.titleEn && (
<Descriptions.Item label="英文标题" span={2}>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.titleEn' })} span={2}>
{data.titleEn}
</Descriptions.Item>
)}
<Descriptions.Item label="是否置顶">{data.isTop === '1' ? '是' : '否'}</Descriptions.Item>
<Descriptions.Item label="状态">{getStatusTag(data.status)}</Descriptions.Item>
<Descriptions.Item label="创建人">{data.createBy}</Descriptions.Item>
<Descriptions.Item label="创建时间">{data.createTime}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.isTop' })}>
{data.isTop === '1'
? intl.formatMessage({ id: 'notice.option.yes' })
: intl.formatMessage({ id: 'notice.option.no' })
}
</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.status' })}>{getStatusTag(data.status)}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.publisher' })}>{data.createBy}</Descriptions.Item>
<Descriptions.Item label={intl.formatMessage({ id: 'notice.field.date' })}>{data.createTime}</Descriptions.Item>
</Descriptions>
<Divider orientation="left"></Divider>
<Divider orientation="left">{intl.formatMessage({ id: 'notice.tab.chinese' })}</Divider>
<Card size="small" bordered={false} className={styles.contentCard}>
<div className={styles.noticeContent} dangerouslySetInnerHTML={{ __html: data.content }} />
</Card>
{data.contentEn && (
<>
<Divider orientation="left"></Divider>
<Divider orientation="left">{intl.formatMessage({ id: 'notice.tab.english' })}</Divider>
<Card size="small" bordered={false} className={styles.contentCard}>
<div className={styles.noticeContent} dangerouslySetInnerHTML={{ __html: data.contentEn }} />
</Card>

View File

@ -52,7 +52,7 @@ const NoticeManage: React.FC = () => {
total: 0,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total: number) => `${total} 条记录`,
showTotal: (total: number) => `${total}`,
});
const [searchParams, setSearchParams] = useState<SearchParams>({});
@ -103,6 +103,11 @@ const NoticeManage: React.FC = () => {
// 首次加载时获取数据
useEffect(() => {
fetchNoticeList(1, pagination.pageSize, {});
// 设置表格分页显示总数的文本
setPagination({
...pagination,
showTotal: (total: number) => intl.formatMessage({ id: 'notice.total.count' }, { total }),
});
}, []);
// 处理查看
@ -129,7 +134,7 @@ const NoticeManage: React.FC = () => {
const handleEdit = (record: NoticeType) => {
// 检查是否为已发布状态
if (record.status === NoticeStatus.PUBLISHED) {
message.warning('已发布的通知不能编辑');
message.warning(intl.formatMessage({ id: 'notice.warning.published.edit' }));
return;
}
@ -148,22 +153,22 @@ const NoticeManage: React.FC = () => {
}
Modal.confirm({
title: '确定要删除该通知吗?',
title: intl.formatMessage({ id: 'notice.confirm.delete' }),
icon: <ExclamationCircleOutlined />,
content: `标题: ${record.title}`,
okText: '确定',
content: `${intl.formatMessage({ id: 'notice.field.title' })}: ${record.title}`,
okText: intl.formatMessage({ id: 'notice.button.submit' }),
okType: 'danger',
cancelText: '取消',
cancelText: intl.formatMessage({ id: 'notice.button.cancel' }),
maskClosable: false,
onOk: async () => {
try {
// 调用删除API
const response = await deleteNotice(record.id);
if (response && response.success) {
message.success('删除成功');
message.success(intl.formatMessage({ id: 'notice.message.delete.success' }));
fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
} else {
message.error(response.message || '删除失败');
message.error(response.message || intl.formatMessage({ id: 'notice.message.delete.fail' }));
}
} catch (error) {
console.error('删除通知失败:', error);
@ -177,30 +182,39 @@ const NoticeManage: React.FC = () => {
const handlePublishStatus = async (record: NoticeType) => {
// 状态: 0-草稿1-已发布2-已下架
const isPublished = record.status === NoticeStatus.PUBLISHED;
const actionText = isPublished ? '下架' : '发布';
const actionText = isPublished
? intl.formatMessage({ id: 'notice.button.unpublish' })
: intl.formatMessage({ id: 'notice.button.publish' });
const actionMessageKey = isPublished ? 'notice.confirm.unpublish' : 'notice.confirm.publish';
const newStatus = isPublished ? NoticeStatus.UNPUBLISHED : NoticeStatus.PUBLISHED;
Modal.confirm({
title: `确定要${actionText}该通知吗?`,
title: intl.formatMessage({ id: actionMessageKey }),
icon: <ExclamationCircleOutlined />,
content: `标题: ${record.title}`,
okText: '确定',
content: `${intl.formatMessage({ id: 'notice.field.title' })}: ${record.title}`,
okText: intl.formatMessage({ id: 'notice.button.submit' }),
okType: isPublished ? 'danger' : 'primary',
cancelText: '取消',
cancelText: intl.formatMessage({ id: 'notice.button.cancel' }),
maskClosable: false,
onOk: async () => {
try {
// 调用API更新状态
const response = await updateNoticeStatus(record.id, newStatus);
if (response && response.success) {
message.success(`${actionText}成功`);
message.success(intl.formatMessage({
id: isPublished ? 'notice.message.unpublish.success' : 'notice.message.publish.success'
}));
fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
} else {
message.error(response.message || `${actionText}失败`);
message.error(response.message || intl.formatMessage({
id: isPublished ? 'notice.message.unpublish.fail' : 'notice.message.publish.fail'
}));
}
} catch (error) {
console.error(`${actionText}失败:`, error);
message.error(`${actionText}失败`);
console.error(`${actionText} failed:`, error);
message.error(intl.formatMessage({
id: isPublished ? 'notice.message.unpublish.fail' : 'notice.message.publish.fail'
}));
}
},
});
@ -209,30 +223,39 @@ const NoticeManage: React.FC = () => {
// 处理置顶/取消置顶
const handleToggleTop = async (record: NoticeType) => {
const isTop = record.isTop === TopStatus.YES;
const actionText = isTop ? '取消置顶' : '置顶';
const actionText = isTop
? intl.formatMessage({ id: 'notice.button.untop' })
: intl.formatMessage({ id: 'notice.button.top' });
const actionMessageKey = isTop ? 'notice.confirm.untop' : 'notice.confirm.top';
const newIsTop = isTop ? TopStatus.NO : TopStatus.YES;
Modal.confirm({
title: `确定要${actionText}该通知吗?`,
title: intl.formatMessage({ id: actionMessageKey }),
icon: <ExclamationCircleOutlined />,
content: `标题: ${record.title}`,
okText: '确定',
content: `${intl.formatMessage({ id: 'notice.field.title' })}: ${record.title}`,
okText: intl.formatMessage({ id: 'notice.button.submit' }),
okType: 'primary',
cancelText: '取消',
cancelText: intl.formatMessage({ id: 'notice.button.cancel' }),
maskClosable: false,
onOk: async () => {
try {
// 调用API更新置顶状态
const response = await updateNoticeTopStatus(record.id, newIsTop);
if (response && response.success) {
message.success(`${actionText}成功`);
message.success(intl.formatMessage({
id: isTop ? 'notice.message.untop.success' : 'notice.message.top.success'
}));
fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
} else {
message.error(response.message || `${actionText}失败`);
message.error(response.message || intl.formatMessage({
id: isTop ? 'notice.message.untop.fail' : 'notice.message.top.fail'
}));
}
} catch (error) {
console.error(`${actionText}失败:`, error);
message.error(`${actionText}失败`);
console.error(`${actionText} failed:`, error);
message.error(intl.formatMessage({
id: isTop ? 'notice.message.untop.fail' : 'notice.message.top.fail'
}));
}
},
});
@ -253,13 +276,13 @@ const NoticeManage: React.FC = () => {
const columns = [
{
title: '序号',
title: '#',
render: (text: string, record: NoticeType, index: number) => index + 1,
width: 80,
align: 'center' as const,
},
{
title: '标题',
title: intl.formatMessage({ id: 'notice.field.title' }),
dataIndex: 'title',
key: 'title',
ellipsis: {
@ -268,69 +291,76 @@ const NoticeManage: React.FC = () => {
render: (title: string, record: NoticeType) => (
<Tooltip placement="topLeft" title={title}>
<span>
{record.isTop === TopStatus.YES && <Tag color="red" style={{ marginRight: 8 }}></Tag>}
{record.isTop === TopStatus.YES && (
<Tag color="red" style={{ marginRight: 8 }}>
{intl.formatMessage({ id: 'notice.button.top' })}
</Tag>
)}
{title}
</span>
</Tooltip>
),
},
{
title: '日期',
title: intl.formatMessage({ id: 'notice.field.date' }),
dataIndex: 'createTime',
key: 'createTime',
align: 'center' as const,
},
{
title: '状态',
title: intl.formatMessage({ id: 'notice.field.status' }),
dataIndex: 'status',
key: 'status',
align: 'center' as const,
render: (status: string) => getStatusTag(status),
},
{
title: '发布人',
title: intl.formatMessage({ id: 'notice.field.publisher' }),
dataIndex: 'createBy',
key: 'createBy',
align: 'center' as const,
},
{
title: '操作',
title: intl.formatMessage({ id: 'notice.field.operation' }),
key: 'action',
width: 300,
align: 'center' as const,
render: (_: unknown, record: NoticeType) => (
<>
<Button type="link" onClick={() => handleView(record)}>
{intl.formatMessage({ id: 'notice.button.view' })}
</Button>
{record.status === NoticeStatus.PUBLISHED ? (
<>
<Button type="link" onClick={() => handlePublishStatus(record)}>
{intl.formatMessage({ id: 'notice.button.unpublish' })}
</Button>
<Button
type="link"
onClick={() => handleToggleTop(record)}
>
{record.isTop === TopStatus.YES ? '取消置顶' : '置顶'}
{record.isTop === TopStatus.YES
? intl.formatMessage({ id: 'notice.button.untop' })
: intl.formatMessage({ id: 'notice.button.top' })
}
</Button>
</>
) : (
<>
<Button type="link" onClick={() => handleEdit(record)}>
{intl.formatMessage({ id: 'notice.button.edit' })}
</Button>
<Button
type="link"
onClick={() => handlePublishStatus(record)}
>
{intl.formatMessage({ id: 'notice.button.publish' })}
</Button>
<Button
type="link"
onClick={() => showDeleteConfirm(record)}
>
{intl.formatMessage({ id: 'notice.button.delete' })}
</Button>
</>
)}
@ -370,7 +400,7 @@ const NoticeManage: React.FC = () => {
// 处理批量删除
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择需要删除的记录');
message.warning(intl.formatMessage({ id: 'notice.warning.select.required' }));
return;
}
@ -380,17 +410,17 @@ const NoticeManage: React.FC = () => {
);
if (hasPublished) {
message.warning('已发布的通知不能删除');
message.warning(intl.formatMessage({ id: 'notice.warning.published.delete' }));
return;
}
Modal.confirm({
title: `确定要删除选中的 ${selectedRowKeys.length} 条通知吗?`,
title: intl.formatMessage({ id: 'notice.confirm.batchDelete' }, { count: selectedRowKeys.length }),
icon: <ExclamationCircleOutlined />,
content: '删除后无法恢复',
okText: '确定',
content: intl.formatMessage({ id: 'notice.confirm.batchDelete.content' }),
okText: intl.formatMessage({ id: 'notice.button.submit' }),
okType: 'danger',
cancelText: '取消',
cancelText: intl.formatMessage({ id: 'notice.button.cancel' }),
maskClosable: false,
onOk: async () => {
try {
@ -398,11 +428,11 @@ const NoticeManage: React.FC = () => {
// 调用批量删除API
const response = await batchDeleteNotice(ids);
if (response && response.success) {
message.success('批量删除成功');
message.success(intl.formatMessage({ id: 'notice.message.batchDelete.success' }));
setSelectedRowKeys([]); // 清空选择
fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据
} else {
message.error(response.message || '批量删除失败');
message.error(response.message || intl.formatMessage({ id: 'notice.message.batchDelete.fail' }));
}
} catch (error) {
console.error('批量删除失败:', error);
@ -434,19 +464,19 @@ const NoticeManage: React.FC = () => {
layout="inline"
className="filter-form"
>
<Form.Item name="title" label="标题">
<Input placeholder="请输入标题关键词" allowClear />
<Form.Item name="title" label={intl.formatMessage({ id: 'notice.field.title' })}>
<Input placeholder={intl.formatMessage({ id: 'notice.form.title.placeholder' })} allowClear />
</Form.Item>
<Form.Item name="status" label="状态">
<Select placeholder="请选择状态" allowClear>
<Option value={NoticeStatus.DRAFT}>稿</Option>
<Option value={NoticeStatus.PUBLISHED}></Option>
<Option value={NoticeStatus.UNPUBLISHED}></Option>
<Form.Item name="status" label={intl.formatMessage({ id: 'notice.field.status' })}>
<Select placeholder={intl.formatMessage({ id: 'notice.form.status.placeholder' })} allowClear>
<Option value={NoticeStatus.DRAFT}>{intl.formatMessage({ id: 'notice.status.draft' })}</Option>
<Option value={NoticeStatus.PUBLISHED}>{intl.formatMessage({ id: 'notice.status.published' })}</Option>
<Option value={NoticeStatus.UNPUBLISHED}>{intl.formatMessage({ id: 'notice.status.unpublished' })}</Option>
</Select>
</Form.Item>
<Form.Item className="filter-btns">
<Button type="primary" htmlType="submit" icon={<SearchOutlined />}>
{intl.formatMessage({ id: 'notice.button.search' })}
</Button>
<Button
type="primary"
@ -457,7 +487,7 @@ const NoticeManage: React.FC = () => {
fetchNoticeList(1, pagination.pageSize, {});
}}
>
{intl.formatMessage({ id: 'notice.button.reset' })}
</Button>
</Form.Item>
</Form>
@ -469,7 +499,7 @@ const NoticeManage: React.FC = () => {
icon={<PlusOutlined />}
onClick={handleAdd}
>
{intl.formatMessage({ id: 'notice.button.add' })}
</Button>
<Button
danger
@ -478,11 +508,11 @@ const NoticeManage: React.FC = () => {
disabled={!hasSelected}
loading={loading}
>
{intl.formatMessage({ id: 'notice.button.delete' })}
</Button>
{hasSelected && (
<span className="selected-count">
{selectedRowKeys.length}
{intl.formatMessage({ id: 'notice.selected.count' }, { count: selectedRowKeys.length })}
</span>
)}
</div>
@ -501,7 +531,12 @@ const NoticeManage: React.FC = () => {
{/* 新增/编辑/查看模态框 */}
<Modal
title={isViewMode ? "查看通知" : isEdit ? "编辑通知" : "新增通知"}
title={isViewMode
? intl.formatMessage({ id: 'notice.view.title' })
: isEdit
? intl.formatMessage({ id: 'notice.edit.title' })
: intl.formatMessage({ id: 'notice.add.title' })
}
visible={modalVisible}
onCancel={handleModalCancel}
width={900}
@ -511,7 +546,7 @@ const NoticeManage: React.FC = () => {
isViewMode
? [
<Button key="close" onClick={handleModalCancel}>
{intl.formatMessage({ id: 'notice.button.close' })}
</Button>,
]
: null