import React, { useState, useEffect } from 'react'; import { useIntl } from 'umi'; import { Button, Table, Modal, message, Input, Select, Form, Tooltip, Switch, Tag, Tabs } from 'antd'; import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, SearchOutlined, VerticalAlignTopOutlined, } from '@ant-design/icons'; import { getNoticeList, addNotice, updateNotice, deleteNotice, batchDeleteNotice, updateNoticeStatus, updateNoticeTopStatus } from '@/servers/api/notice'; import './noticeManage.less'; // 引入封装的WangEditor组件 import WangEditor from '@/components/WangEidtor/WangEidtor'; const { Option } = Select; const { TextArea } = Input; const { TabPane } = Tabs; type NoticeType = API.NoticeRecord & { key: string; }; const NoticeManage: React.FC = () => { const intl = useIntl(); const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [loading, setLoading] = useState(false); const [form] = Form.useForm(); const [modalVisible, setModalVisible] = useState(false); const [isEdit, setIsEdit] = useState(false); const [currentId, setCurrentId] = useState(''); const [modalForm] = Form.useForm(); // 富文本内容状态 const [htmlZh, setHtmlZh] = useState(''); const [htmlEn, setHtmlEn] = useState(''); const [noticeData, setNoticeData] = useState([ { key: '1', id: '1', title: '系统维护通知', titleEn: 'System Maintenance Notice', content: '系统将于2023年7月1日进行例行维护,请提前做好准备。', contentEn: 'The system will undergo routine maintenance on July 1, 2023. Please prepare in advance.', createTime: '2023-06-25 10:30:00', createBy: 'admin', status: '1', // 已发布 isTop: '1', // 已置顶 settingEn: 1, // 设置英文 }, { key: '2', id: '2', title: '新功能上线通知', titleEn: 'New Feature Launch', content: '系统新增了XXXX功能,欢迎使用。', contentEn: 'The system has added XXXX function, welcome to use.', createTime: '2023-06-20 14:45:00', createBy: 'admin', status: '0', // 草稿 isTop: '0', // 未置顶 settingEn: 1, }, { key: '3', id: '3', title: '用户反馈调查', titleEn: '', content: '为了提升用户体验,我们正在收集用户反馈...', contentEn: '', createTime: '2023-06-18 09:15:00', createBy: 'admin', status: '1', // 已发布 isTop: '0', // 未置顶 settingEn: 0, }, ]); const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 3, showSizeChanger: true, showQuickJumper: true, showTotal: (total: number) => `共 ${total} 条记录`, }); const [searchParams, setSearchParams] = useState({}); const [activeTabKey, setActiveTabKey] = useState('zh'); // 获取通知列表(模拟数据) const fetchNoticeList = (current: number = 1, pageSize: number = 10) => { setLoading(true); // 实际项目中应调用API getNoticeList({ ...searchParams, }) .then(res => { // 此处为模拟数据,实际项目中应使用API返回的数据 setNoticeData([ { key: '1', id: '1', title: '系统维护通知', titleEn: 'System Maintenance Notice', content: '系统将于2023年7月1日进行例行维护,请提前做好准备。', contentEn: 'The system will undergo routine maintenance on July 1, 2023. Please prepare in advance.', createTime: '2023-06-25 10:30:00', createBy: 'admin', status: '1', // 已发布 isTop: '1', // 已置顶 settingEn: 1, }, { key: '2', id: '2', title: '新功能上线通知', titleEn: 'New Feature Launch', content: '系统新增了XXXX功能,欢迎使用。', contentEn: 'The system has added XXXX function, welcome to use.', createTime: '2023-06-20 14:45:00', createBy: 'admin', status: '0', // 草稿 isTop: '0', // 未置顶 settingEn: 1, }, { key: '3', id: '3', title: '用户反馈调查', titleEn: '', content: '为了提升用户体验,我们正在收集用户反馈...', contentEn: '', createTime: '2023-06-18 09:15:00', createBy: 'admin', status: '1', // 已发布 isTop: '0', // 未置顶 settingEn: 0, }, ]); setPagination({ ...pagination, current, pageSize, total: 3, // 应该是res.total }); }) .catch(error => { console.error('获取通知列表失败:', error); message.error('获取通知列表失败'); }) .finally(() => { setLoading(false); }); }; // 首次加载时获取数据 useEffect(() => { fetchNoticeList(); }, []); // 处理编辑 const handleEdit = (record: NoticeType) => { // 检查是否为已发布状态 if (record.status === '1') { message.warning('已发布的通知不能编辑'); return; } setIsEdit(true); setCurrentId(record.id); setModalVisible(true); setActiveTabKey('zh'); // 填充表单数据 modalForm.setFieldsValue({ isTop: record.isTop === '1', titleZh: record.title, titleEn: record.titleEn, contentZh: record.content, contentEn: record.contentEn || '', }); }; // 处理删除 const showDeleteConfirm = (record: NoticeType) => { // 检查是否为已发布状态 if (record.status === '1') { message.warning('已发布的通知不能删除'); return; } Modal.confirm({ title: '确定要删除该通知吗?', icon: , content: `标题: ${record.title}`, okText: '确定', okType: 'danger', cancelText: '取消', maskClosable: false, onOk: async () => { try { // 调用删除API await deleteNotice(record.id); // 更新本地数据 const newData = noticeData.filter(item => item.id !== record.id); setNoticeData(newData); message.success('删除成功'); } catch (error) { console.error('删除通知失败:', error); message.error('删除失败'); } }, }); }; // 处理发布/下架 const handlePublishStatus = async (record: NoticeType) => { // 状态: 0-草稿,1-已发布 const isPublished = record.status === '1'; const actionText = isPublished ? '下架' : '发布'; const newStatus = isPublished ? '0' : '1'; try { // 调用API更新状态 await updateNoticeStatus(record.id, newStatus); // 更新本地数据 const newData = noticeData.map(item => item.id === record.id ? { ...item, status: newStatus } : item ); setNoticeData(newData); message.success(`${actionText}成功`); } catch (error) { console.error(`${actionText}失败:`, error); message.error(`${actionText}失败`); } }; // 处理置顶/取消置顶 const handleToggleTop = async (record: NoticeType) => { const isTop = record.isTop === '1'; const actionText = isTop ? '取消置顶' : '置顶'; const newIsTop = isTop ? '0' : '1'; try { // 调用API更新置顶状态 await updateNoticeTopStatus(record.id, newIsTop); // 更新本地数据 const newData = noticeData.map(item => item.id === record.id ? { ...item, isTop: newIsTop } : item ); setNoticeData(newData); message.success(`${actionText}成功`); } catch (error) { console.error(`${actionText}失败:`, error); message.error(`${actionText}失败`); } }; // 获取状态标签 const getStatusTag = (status: string) => { switch (status) { case '0': return 草稿; case '1': return 已发布; case '2': return 已下架; default: return 未知; } }; // 处理表格分页变化 const handleTableChange = (newPagination: any) => { fetchNoticeList(newPagination.current, newPagination.pageSize); }; const columns = [ { title: '序号', dataIndex: 'id', key: 'id', align: 'center' as const, width: 80, }, { title: '标题', dataIndex: 'title', key: 'title', ellipsis: { showTitle: false, }, render: (title: string, record: NoticeType) => ( {record.isTop === '1' && 置顶} {title} ), }, { title: '日期', dataIndex: 'createTime', key: 'createTime', align: 'center' as const, }, { title: '状态', dataIndex: 'status', key: 'status', align: 'center' as const, render: (status: string) => getStatusTag(status), }, { title: '发布人', dataIndex: 'createBy', key: 'createBy', align: 'center' as const, }, { title: '操作', key: 'action', width: 300, align: 'center' as const, render: (_: unknown, record: NoticeType) => ( <> {record.status === '1' ? ( <> ) : ( <> )} ), }, ]; // 行选择限制 const checkSelectable = (record: NoticeType) => { return record.status !== '1'; // 已发布的不能选择 }; const onSelectChange = (newSelectedRowKeys: React.Key[]) => { setSelectedRowKeys(newSelectedRowKeys); }; const rowSelection = { selectedRowKeys, onChange: onSelectChange, getCheckboxProps: (record: NoticeType) => ({ disabled: record.status === '1', // 已发布的不能选择 }), }; const hasSelected = selectedRowKeys.length > 0; // 处理添加 const handleAdd = () => { setIsEdit(false); setCurrentId(''); modalForm.resetFields(); setModalVisible(true); setActiveTabKey('zh'); }; // 处理批量删除 const handleBatchDelete = () => { Modal.confirm({ title: '确定要删除选中的通知吗?', icon: , content: '删除后无法恢复', okText: '确定', okType: 'danger', cancelText: '取消', maskClosable: false, onOk: async () => { setLoading(true); try { // 获取可删除的ID(非已发布状态) const deleteIds = selectedRowKeys.filter(key => { const record = noticeData.find(item => item.key === key); return record && record.status !== '1'; }) as string[]; if (deleteIds.length > 0) { // 调用批量删除API await batchDeleteNotice(deleteIds); // 更新本地数据 const newData = noticeData.filter(item => !deleteIds.includes(item.key)); setNoticeData(newData); setSelectedRowKeys([]); message.success('删除成功'); } else { message.warning('没有可删除的通知'); } } catch (error) { console.error('批量删除失败:', error); message.error('批量删除失败'); } finally { setLoading(false); } }, }); }; // 处理搜索 const handleSearch = (values: API.NoticeSearchParams) => { setSearchParams(values); fetchNoticeList(1, pagination.pageSize); }; // 处理模态框提交 const handleModalSubmit = () => { // 先触发所有字段的验证 modalForm.validateFields() .then(async values => { try { const noticeParams: API.NoticeRequest = { title: values.titleZh, titleEn: values.titleEn || '', content: values.contentZh, contentEn: values.contentEn || '', isTop: values.isTop ? '1' : '0', settingEn: values.titleEn && values.contentEn ? 1 : 0, }; if (isEdit) { // 编辑模式,调用更新API await updateNotice(currentId, noticeParams); message.success('更新成功'); } else { // 新增模式,调用添加API await addNotice(noticeParams); message.success('添加成功'); } setModalVisible(false); modalForm.resetFields(); // 刷新列表 fetchNoticeList(pagination.current, pagination.pageSize); } catch (error) { console.error(isEdit ? '更新通知失败:' : '添加通知失败:', error); message.error(isEdit ? '更新失败' : '添加失败'); } }) .catch(errorInfo => { // 获取所有字段的错误信息 const errorFields = errorInfo.errorFields || []; // 检查是否有中文标题或内容的错误 const hasZhError = errorFields.some((field: any) => { if (!field.name) return false; const fieldName = Array.isArray(field.name) ? field.name.join('.') : String(field.name); return fieldName.includes('titleZh') || fieldName.includes('contentZh'); }); // 检查是否有英文标题或内容的错误 const hasEnError = errorFields.some((field: any) => { if (!field.name) return false; const fieldName = Array.isArray(field.name) ? field.name.join('.') : String(field.name); return fieldName.includes('titleEn') || fieldName.includes('contentEn'); }); // 如果有中文字段错误,切换到中文Tab if (hasZhError) { setActiveTabKey('zh'); } // 如果只有英文字段错误,切换到英文Tab else if (hasEnError && !hasZhError) { setActiveTabKey('en'); } console.log('表单验证失败:', errorInfo); }); }; // 处理Tab切换 const handleTabChange = (key: string) => { setActiveTabKey(key); }; // 处理模态框取消 const handleModalCancel = () => { setModalVisible(false); modalForm.resetFields(); }; return (
{hasSelected && ( 已选择 {selectedRowKeys.length} 项 )}
{/* 新增/编辑模态框 */}
); }; export default NoticeManage;