diff --git a/src/dicts/noticeManageDict.ts b/src/dicts/noticeManageDict.ts index 2c59afe..6ec2674 100644 --- a/src/dicts/noticeManageDict.ts +++ b/src/dicts/noticeManageDict.ts @@ -1,4 +1,7 @@ // 通知管理字典 +// setting_en int 是 0 是否设置英文内容(0.否、1.是) +// is_top int 是 0 是否置顶(0.否、1.是) +// status int 是 0 状态(0.草稿、1.上架、2.下架) // 通知状态枚举 export enum NoticeStatus { diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index a2e1dcd..72e972c 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -6,6 +6,7 @@ import aboutManage from './en-US/aboutManage'; import policyManage from './en-US/policyManage'; import userQuestion from './en-US/userQuestion'; import friendLink from './en-US/friendLink'; +import downloadManage from './en-US/downloadManage'; export default { ...common, @@ -16,4 +17,5 @@ export default { ...policyManage, ...userQuestion, ...friendLink, + ...downloadManage, }; diff --git a/src/locales/en-US/downloadManage.ts b/src/locales/en-US/downloadManage.ts new file mode 100644 index 0000000..9923c50 --- /dev/null +++ b/src/locales/en-US/downloadManage.ts @@ -0,0 +1,81 @@ +export default { + // Page title + 'download.title': 'Download Center', + + // Form and table fields + 'download.field.name': 'Name', + 'download.field.column': 'Category', + 'download.field.keyword': 'Keywords', + 'download.field.status': 'Status', + 'download.field.thumbnail': 'Thumbnail', + 'download.field.uploadTime': 'Upload Time', + 'download.field.uploader': 'Uploader', + 'download.field.operation': 'Actions', + 'download.field.file': 'File Upload', + 'download.field.isBold': 'Bold', + 'download.field.isTop': 'Top', + + // Status + 'download.status.draft': 'Draft', + 'download.status.published': 'Published', + 'download.status.unpublished': 'Unpublished', + + // Buttons and actions + 'download.button.add': 'Add', + 'download.button.edit': 'Edit', + 'download.button.delete': 'Delete', + 'download.button.publish': 'Publish', + 'download.button.unpublish': 'Unpublish', + 'download.button.download': 'Download', + 'download.button.search': 'Search', + 'download.button.reset': 'Reset', + 'download.button.submit': 'Submit', + 'download.button.cancel': 'Cancel', + + // Prompts and confirmation + 'download.confirm.delete': 'Are you sure you want to delete this file?', + 'download.confirm.batchDelete': 'Are you sure you want to delete the selected files?', + 'download.confirm.batchDelete.content': 'You are about to delete {count} files, which cannot be recovered after deletion', + 'download.confirm.publish': 'Are you sure you want to publish this file?', + 'download.confirm.unpublish': 'Are you sure you want to unpublish this file?', + 'download.confirm.submit': 'Are you sure you want to {action} this file?', + + // Form prompts + 'download.form.name.placeholder': 'Please enter name', + 'download.form.name.required': 'Please enter name', + 'download.form.column.placeholder': 'Please select category', + 'download.form.column.required': 'Please select category', + 'download.form.keyword.placeholder': 'Please enter keywords, separate multiple keywords with commas', + 'download.form.keyword.required': 'Please enter keywords', + 'download.form.file.required': 'Please upload a file', + 'download.form.file.tip': 'Supported formats: PDF, Office documents, compressed packages, etc., single file not exceeding 20MB', + 'download.form.thumbnail.tip': 'Supported formats: jpg, png, gif and other image formats, size not exceeding 2MB', + + // Success and failure prompts + 'download.message.get.success': 'Get list successful', + 'download.message.get.fail': 'Failed to get list', + 'download.message.detail.success': 'Get details successful', + 'download.message.detail.fail': 'Failed to get details', + 'download.message.add.success': 'Added successfully', + 'download.message.add.fail': 'Failed to add', + 'download.message.update.success': 'Updated successfully', + 'download.message.update.fail': 'Failed to update', + 'download.message.delete.success': 'Deleted successfully', + 'download.message.delete.fail': 'Failed to delete', + 'download.message.batchDelete.success': 'Batch deletion successful', + 'download.message.batchDelete.fail': 'Batch deletion failed', + 'download.message.publish.success': 'Published successfully', + 'download.message.publish.fail': 'Failed to publish', + 'download.message.unpublish.success': 'Unpublished successfully', + 'download.message.unpublish.fail': 'Failed to unpublish', + 'download.message.upload.fail': 'File upload failed', + + // Others + 'download.total.count': 'Total {total} records', + 'download.selected.count': 'Selected {count} items', + 'download.no.thumbnail': 'None', + 'download.edit.title': 'Edit File', + 'download.add.title': 'Add New File', + 'download.yes': 'Yes', + 'download.no': 'No', +}; diff --git a/src/locales/en-US/noticeManage.ts b/src/locales/en-US/noticeManage.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 4f72490..90526ec 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -6,6 +6,7 @@ import aboutManage from './zh-CN/aboutManage'; import policyManage from './zh-CN/policyManage'; import userQuestion from './zh-CN/userQuestion'; import friendLink from './zh-CN/friendLink'; +import downloadManage from './zh-CN/downloadManage'; export default { ...common, @@ -16,4 +17,5 @@ export default { ...policyManage, ...userQuestion, ...friendLink, + ...downloadManage, }; diff --git a/src/locales/zh-CN/downloadManage.ts b/src/locales/zh-CN/downloadManage.ts new file mode 100644 index 0000000..2ceb801 --- /dev/null +++ b/src/locales/zh-CN/downloadManage.ts @@ -0,0 +1,81 @@ +export default { + // 页面标题 + 'download.title': '下载中心', + + // 表单和表格字段 + 'download.field.name': '名称', + 'download.field.column': '栏目', + 'download.field.keyword': '关键词', + 'download.field.status': '状态', + 'download.field.thumbnail': '缩略图', + 'download.field.uploadTime': '上传时间', + 'download.field.uploader': '上传人', + 'download.field.operation': '操作', + 'download.field.file': '文件上传', + 'download.field.isBold': '是否加粗', + 'download.field.isTop': '是否置顶', + + // 状态 + 'download.status.draft': '草稿', + 'download.status.published': '已发布', + 'download.status.unpublished': '已下架', + + // 按钮和操作 + 'download.button.add': '新增', + 'download.button.edit': '编辑', + 'download.button.delete': '删除', + 'download.button.publish': '发布', + 'download.button.unpublish': '下架', + 'download.button.download': '下载', + 'download.button.search': '搜索', + 'download.button.reset': '重置', + 'download.button.submit': '提交', + 'download.button.cancel': '取消', + + // 提示和确认框 + 'download.confirm.delete': '确定要删除该文件吗?', + 'download.confirm.batchDelete': '确定要删除选中的文件吗?', + 'download.confirm.batchDelete.content': '将要删除 {count} 个文件,删除后无法恢复', + 'download.confirm.publish': '确定要发布该文件吗?', + 'download.confirm.unpublish': '确定要下架该文件吗?', + 'download.confirm.submit': '确定要{action}该文件吗?', + + // 表单提示 + 'download.form.name.placeholder': '请输入名称', + 'download.form.name.required': '请输入名称', + 'download.form.column.placeholder': '请选择栏目', + 'download.form.column.required': '请选择栏目', + 'download.form.keyword.placeholder': '请输入关键词,多个关键词用逗号分隔', + 'download.form.keyword.required': '请输入关键词', + 'download.form.file.required': '请上传文件', + 'download.form.file.tip': '支持格式:PDF、Office文档、压缩包等,单个文件不能超过20MB', + 'download.form.thumbnail.tip': '支持jpg、png、gif等图片格式,大小不超过2MB', + + // 成功和失败提示 + 'download.message.get.success': '获取列表成功', + 'download.message.get.fail': '获取列表失败', + 'download.message.detail.success': '获取详情成功', + 'download.message.detail.fail': '获取详情失败', + 'download.message.add.success': '添加成功', + 'download.message.add.fail': '添加失败', + 'download.message.update.success': '更新成功', + 'download.message.update.fail': '更新失败', + 'download.message.delete.success': '删除成功', + 'download.message.delete.fail': '删除失败', + 'download.message.batchDelete.success': '批量删除成功', + 'download.message.batchDelete.fail': '批量删除失败', + 'download.message.publish.success': '发布成功', + 'download.message.publish.fail': '发布失败', + 'download.message.unpublish.success': '下架成功', + 'download.message.unpublish.fail': '下架失败', + 'download.message.upload.fail': '文件上传失败', + + // 其他 + 'download.total.count': '共 {total} 条记录', + 'download.selected.count': '已选择 {count} 项', + 'download.no.thumbnail': '无', + 'download.edit.title': '编辑文件', + 'download.add.title': '新增文件', + 'download.yes': '是', + 'download.no': '否', +}; diff --git a/src/locales/zh-CN/noticeManage.ts b/src/locales/zh-CN/noticeManage.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/downloadManage/DownloadManageForm.tsx b/src/pages/downloadManage/DownloadManageForm.tsx new file mode 100644 index 0000000..f9e8a66 --- /dev/null +++ b/src/pages/downloadManage/DownloadManageForm.tsx @@ -0,0 +1,293 @@ +import React, { useState, useEffect } from 'react'; +import { Form, Input, Select, message, Button } from 'antd'; +import { useIntl } from 'umi'; +import FileUpload from '@/components/FileUpload/FileUpload'; +import { + DownloadIsBold, + DownloadIsTop, + DownloadColumnTypeOptions, +} from '@/dicts/download'; +import { addDownload, updateDownload, getDownloadDetail } from '@/servers/api/download'; +import type { UploadFile } from 'antd/es/upload/interface'; +import styles from './downloadManage.less'; + +const { Option } = Select; + +interface DownloadManageFormProps { + id?: string; + isEdit: boolean; + onSuccess: () => void; + onCancel?: () => void; +} + +const DownloadManageForm: React.FC = ({ id, isEdit, onSuccess, onCancel }) => { + const intl = useIntl(); + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + const [fileList, setFileList] = useState([]); + const [thumbnailList, setThumbnailList] = useState([]); + + // 获取详情数据 + useEffect(() => { + const fetchDownloadDetail = async (downloadId: string) => { + setLoading(true); + try { + const response = await getDownloadDetail(downloadId); + if (response && response.success) { + const detail = response.data; + + // 设置表单数据 + form.setFieldsValue({ + ...detail, + isBold: detail.isBold.toString(), // 确保是字符串 + isTop: detail.isTop.toString(), // 确保是字符串 + }); + + // 设置文件信息 + if (detail.fileUrl) { + const fileInfo = { + uid: '-1', + name: detail.fileName || '文件', + status: 'done', + url: detail.fileUrl, + type: detail.fileType || '', + } as UploadFile; + setFileList([fileInfo]); + } + + // 设置缩略图 + if (detail.thumbnail) { + const thumbnailInfo = { + uid: '-1', + name: '缩略图', + status: 'done', + url: detail.thumbnail, + type: 'image/jpeg', + } as UploadFile; + setThumbnailList([thumbnailInfo]); + } + } else { + message.error(response.message || intl.formatMessage({ id: 'download.message.detail.fail' })); + } + } catch (error) { + console.error('获取下载详情失败:', error); + message.error(intl.formatMessage({ id: 'download.message.detail.fail' })); + } finally { + setLoading(false); + } + }; + + if (isEdit && id) { + fetchDownloadDetail(id); + } + }, [isEdit, id, form]); + + // 处理文件上传变化 + const handleFileChange = (uploadFiles: UploadFile[]) => { + setFileList(uploadFiles); + }; + + // 处理缩略图上传变化 + const handleThumbnailChange = (uploadFiles: UploadFile[]) => { + setThumbnailList(uploadFiles); + }; + + // 提交表单 + const handleSubmit = async () => { + setLoading(true); + try { + const values = await form.validateFields(); + + // 检查文件上传 + if (fileList.length === 0 && !isEdit) { + message.error(intl.formatMessage({ id: 'download.form.file.required' })); + setLoading(false); + return; + } + + // 获取文件和缩略图信息 + const fileInfo = fileList.length > 0 ? fileList[0] : null; + const thumbnailInfo = thumbnailList.length > 0 ? thumbnailList[0] : null; + + if (!fileInfo && !isEdit) { + message.error(intl.formatMessage({ id: 'download.message.upload.fail' })); + setLoading(false); + return; + } + + // 构建请求参数 + const requestData: API.DownloadRequest = { + name: values.name, + columnType: values.columnType, + keywords: values.keywords, + isBold: parseInt(values.isBold), // 转换为数字类型 + isTop: parseInt(values.isTop), // 转换为数字类型 + thumbnail: thumbnailInfo?.url || thumbnailInfo?.response?.data?.url || '', + fileName: fileInfo?.name || '', + fileType: fileInfo?.type || '', + fileSize: fileInfo?.size?.toString() || '0', + filePath: fileInfo?.response?.data?.filePath || '', + fileUrl: fileInfo?.url || fileInfo?.response?.data?.url || '', + }; + + if (isEdit && id) { + requestData.id = id; + } + + // 执行添加或更新操作 + const response = isEdit + ? await updateDownload(requestData) + : await addDownload(requestData); + + if (response && response.success) { + message.success( + isEdit + ? intl.formatMessage({ id: 'download.message.update.success' }) + : intl.formatMessage({ id: 'download.message.add.success' }) + ); + onSuccess(); // 回调父组件 + } else { + message.error( + response.message || + (isEdit + ? intl.formatMessage({ id: 'download.message.update.fail' }) + : intl.formatMessage({ id: 'download.message.add.fail' }) + ) + ); + } + + } catch (error: any) { + console.error('表单验证或提交失败:', error); + message.error( + isEdit + ? intl.formatMessage({ id: 'download.message.update.fail' }) + : intl.formatMessage({ id: 'download.message.add.fail' }) + ); + } finally { + setLoading(false); + } + }; + + return ( +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ ); +}; + +export default DownloadManageForm; diff --git a/src/pages/downloadManage/downloadManage.less b/src/pages/downloadManage/downloadManage.less index 4d77c6e..7166d9a 100644 --- a/src/pages/downloadManage/downloadManage.less +++ b/src/pages/downloadManage/downloadManage.less @@ -5,3 +5,42 @@ font-size: 12px; } } + +.formActions { + margin-top: 24px; + text-align: right; + + button { + margin-left: 8px; + } +} + +.downloadDetailView { + padding: 12px; + + .fileInfoCard, + .thumbnailCard { + margin: 12px 0; + } + + .fileInfo { + p { + margin-bottom: 8px; + } + + .downloadButton { + margin-top: 16px; + } + } + + .thumbnailContainer { + display: flex; + justify-content: center; + padding: 8px; + + img { + max-height: 300px; + object-fit: contain; + } + } +} diff --git a/src/pages/downloadManage/downloadManage.tsx b/src/pages/downloadManage/downloadManage.tsx index f59b8e9..6a0d53a 100644 --- a/src/pages/downloadManage/downloadManage.tsx +++ b/src/pages/downloadManage/downloadManage.tsx @@ -1,21 +1,18 @@ import React, { useState, useEffect } from 'react'; import { useIntl } from 'umi'; -import { Button, Table, Space, Modal, message, Input, Select, Form, Tooltip, Tag } from 'antd'; +import { Button, Table, Modal, message, Input, Select, Form, Tooltip, Tag } from 'antd'; import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, SearchOutlined, } from '@ant-design/icons'; -import FileUpload from '@/components/FileUpload/FileUpload'; import { getDownloadList, - getDownloadDetail, - addDownload, - updateDownload, updateDownloadStatus, batchDeleteDownload, } from '@/servers/api/download'; +import DownloadManageForm from './DownloadManageForm'; import { DownloadStatus, DownloadIsTop, @@ -23,12 +20,10 @@ import { DownloadColumnType, DownloadColumnTypeOptions, DownloadStatusLabels, - DownloadColumnTypeLabels, getDownloadStatusText, getDownloadColumnTypeText, } from '@/dicts/download'; -import styles from './downloadManage.less'; -import type { UploadFile } from 'antd/es/upload/interface'; + const { Option } = Select; @@ -42,9 +37,6 @@ const DownloadManage: React.FC = () => { const [modalVisible, setModalVisible] = useState(false); const [isEdit, setIsEdit] = useState(false); const [currentId, setCurrentId] = useState(''); - const [modalForm] = Form.useForm(); - const [fileList, setFileList] = useState([]); - const [thumbnailList, setThumbnailList] = useState([]); const [downloadData, setDownloadData] = useState([]); const [pagination, setPagination] = useState({ current: 1, @@ -52,7 +44,10 @@ const DownloadManage: React.FC = () => { total: 0, showSizeChanger: true, showQuickJumper: true, - showTotal: (total: number) => `共 ${total} 条记录`, + showTotal: (total: number) => intl.formatMessage( + { id: 'download.total.count' }, + { total } + ), }); const [searchParams, setSearchParams] = useState({}); @@ -79,11 +74,11 @@ const DownloadManage: React.FC = () => { total: res.data.total, }); } else { - message.error(res.message || '获取列表失败'); + message.error(res.message || intl.formatMessage({ id: 'download.message.get.fail' })); } } catch (error) { console.error('获取下载中心列表失败:', error); - message.error('获取列表失败'); + message.error(intl.formatMessage({ id: 'download.message.get.fail' })); } finally { setLoading(false); } @@ -94,103 +89,35 @@ const DownloadManage: React.FC = () => { fetchDownloadList(); }, []); - // 获取详情 - const fetchDownloadDetail = async (id: string) => { - try { - const res = await getDownloadDetail(id); - if (res.success) { - return res.data; - } else { - message.error(res.message || '获取详情失败'); - return null; - } - } catch (error) { - console.error('获取下载详情失败:', error); - message.error('获取详情失败'); - return null; - } - }; - // 处理编辑 - const handleEdit = async (record: DownloadType) => { + const handleEdit = (record: DownloadType) => { setIsEdit(true); setCurrentId(record.id); setModalVisible(true); - setLoading(true); - - try { - // 获取详细数据 - const detailData = await fetchDownloadDetail(record.id); - if (!detailData) { - setModalVisible(false); - return; - } - - // 先设置基本表单数据 - modalForm.setFieldsValue({ - ...detailData - }); - - // 设置文件信息 - let fileInfo = null; - if (detailData.fileUrl) { - fileInfo = { - uid: '-1', - name: detailData.fileName || '文件', - status: 'done', - url: detailData.fileUrl, - type: detailData.fileType || '', - } as UploadFile; - setFileList([fileInfo]); - } else { - setFileList([]); - } - - // 设置缩略图 - let thumbnailInfo = null; - if (detailData.thumbnail) { - thumbnailInfo = { - uid: '-1', - name: '缩略图', - status: 'done', - url: detailData.thumbnail, - type: 'image/jpeg', - } as UploadFile; - setThumbnailList([thumbnailInfo]); - } else { - setThumbnailList([]); - } - - } catch (error) { - console.error('加载详情数据失败:', error); - message.error('加载详情数据失败'); - } finally { - setLoading(false); - } }; // 处理删除 const showDeleteConfirm = (record: DownloadType) => { Modal.confirm({ - title: '确定要删除该文件吗?', + title: intl.formatMessage({ id: 'download.confirm.delete' }), icon: , - content: `名称: ${record.name}`, - okText: '确定', + content: `${intl.formatMessage({ id: 'download.field.name' })}: ${record.name}`, + okText: intl.formatMessage({ id: 'download.button.submit' }), okType: 'danger', - cancelText: '取消', + cancelText: intl.formatMessage({ id: 'download.button.cancel' }), maskClosable: false, onOk: async () => { try { const res = await batchDeleteDownload([record.id]); if (res.success) { - message.success('删除成功'); + message.success(intl.formatMessage({ id: 'download.message.delete.success' })); fetchDownloadList(pagination.current, pagination.pageSize); } else { - message.error(res.message || '删除失败'); + message.error(res.message || intl.formatMessage({ id: 'download.message.delete.fail' })); } } catch (error) { console.error('删除文件失败:', error); - message.error('删除失败'); + message.error(intl.formatMessage({ id: 'download.message.delete.fail' })); } }, }); @@ -200,39 +127,50 @@ const DownloadManage: React.FC = () => { const handlePublishStatus = async (record: DownloadType) => { // 状态: 0-草稿,1-已发布,2-已下架 let newStatus: string; - let actionText: string; + let actionKey: string; if (record.status === DownloadStatus.DRAFT) { newStatus = DownloadStatus.ON_SHELF; - actionText = '发布'; + actionKey = 'download.button.publish'; } else if (record.status === DownloadStatus.ON_SHELF) { newStatus = DownloadStatus.OFF_SHELF; - actionText = '下架'; + actionKey = 'download.button.unpublish'; } else { newStatus = DownloadStatus.ON_SHELF; - actionText = '上架'; + actionKey = 'download.button.publish'; } + const actionText = intl.formatMessage({ id: actionKey }); + // 添加确认提示 Modal.confirm({ - title: `确定要${actionText}该文件吗?`, + title: intl.formatMessage({ id: 'download.confirm.submit' }, { action: actionText }), icon: , - content: `文件名称: ${record.name}`, - okText: '确定', - cancelText: '取消', + content: `${intl.formatMessage({ id: 'download.field.name' })}: ${record.name}`, + okText: intl.formatMessage({ id: 'download.button.submit' }), + cancelText: intl.formatMessage({ id: 'download.button.cancel' }), maskClosable: false, onOk: async () => { try { const res = await updateDownloadStatus(record.id, newStatus); if (res.success) { - message.success(`${actionText}成功`); + const successKey = actionKey === 'download.button.publish' + ? 'download.message.publish.success' + : 'download.message.unpublish.success'; + message.success(intl.formatMessage({ id: successKey })); fetchDownloadList(pagination.current, pagination.pageSize); } else { - message.error(res.message || `${actionText}失败`); + const failKey = actionKey === 'download.button.publish' + ? 'download.message.publish.fail' + : 'download.message.unpublish.fail'; + message.error(res.message || intl.formatMessage({ id: failKey })); } } catch (error) { + const failKey = actionKey === 'download.button.publish' + ? 'download.message.publish.fail' + : 'download.message.unpublish.fail'; console.error(`${actionText}失败:`, error); - message.error(`${actionText}失败`); + message.error(intl.formatMessage({ id: failKey })); } }, }); @@ -272,7 +210,7 @@ const DownloadManage: React.FC = () => { const columns = [ { - title: '序号', + title: '#', dataIndex: 'id', key: 'id', width: 80, @@ -280,18 +218,22 @@ const DownloadManage: React.FC = () => { (pagination.current - 1) * pagination.pageSize + index + 1, }, { - title: '缩略图', + title: intl.formatMessage({ id: 'download.field.thumbnail' }), dataIndex: 'thumbnail', key: 'thumbnail', render: (thumbnail: string) => thumbnail ? ( - 缩略图 + {intl.formatMessage({ ) : ( - '无' + intl.formatMessage({ id: 'download.no.thumbnail' }) ), }, { - title: '名称', + title: intl.formatMessage({ id: 'download.field.name' }), dataIndex: 'name', key: 'name', ellipsis: { @@ -306,13 +248,13 @@ const DownloadManage: React.FC = () => { ), }, { - title: '栏目', + title: intl.formatMessage({ id: 'download.field.column' }), dataIndex: 'columnType', key: 'columnType', render: (columnType: string) => getColumnTypeTag(columnType), }, { - title: '关键词', + title: intl.formatMessage({ id: 'download.field.keyword' }), dataIndex: 'keywords', key: 'keywords', ellipsis: { @@ -325,49 +267,49 @@ const DownloadManage: React.FC = () => { ), }, { - title: '状态', + title: intl.formatMessage({ id: 'download.field.status' }), dataIndex: 'status', key: 'status', render: (status: string) => getStatusTag(status), }, { - title: '上传时间', + title: intl.formatMessage({ id: 'download.field.uploadTime' }), dataIndex: 'createTime', key: 'createTime', }, { - title: '上传人', + title: intl.formatMessage({ id: 'download.field.uploader' }), dataIndex: 'createBy', align: 'center' as const, key: 'createBy', }, { - title: '操作', + title: intl.formatMessage({ id: 'download.field.operation' }), key: 'action', width: 300, align: 'center' as const, render: (_: unknown, record: DownloadType) => ( <> {record.status === DownloadStatus.ON_SHELF ? ( ) : ( <> )} {record.status !== DownloadStatus.ON_SHELF && ( )} @@ -375,10 +317,6 @@ const DownloadManage: React.FC = () => { }, ]; - // 行选择限制 - const checkSelectable = (record: DownloadType) => { - return record.status !== DownloadStatus.ON_SHELF; // 已发布的不能选择 - }; const onSelectChange = (newSelectedRowKeys: React.Key[]) => { setSelectedRowKeys(newSelectedRowKeys); @@ -398,21 +336,21 @@ const DownloadManage: React.FC = () => { const handleAdd = () => { setIsEdit(false); setCurrentId(''); - modalForm.resetFields(); - setFileList([]); - setThumbnailList([]); setModalVisible(true); }; // 处理批量删除 const handleBatchDelete = () => { Modal.confirm({ - title: '确定要删除选中的文件吗?', + title: intl.formatMessage({ id: 'download.confirm.batchDelete' }), icon: , - content: `将要删除 ${selectedRowKeys.length} 个文件,删除后无法恢复`, - okText: '确定', + content: intl.formatMessage( + { id: 'download.confirm.batchDelete.content' }, + { count: selectedRowKeys.length } + ), + okText: intl.formatMessage({ id: 'download.button.submit' }), okType: 'danger', - cancelText: '取消', + cancelText: intl.formatMessage({ id: 'download.button.cancel' }), maskClosable: false, onOk: async () => { setLoading(true); @@ -420,14 +358,14 @@ const DownloadManage: React.FC = () => { const res = await batchDeleteDownload(selectedRowKeys as string[]); if (res.success) { setSelectedRowKeys([]); - message.success('批量删除成功'); + message.success(intl.formatMessage({ id: 'download.message.batchDelete.success' })); fetchDownloadList(pagination.current, pagination.pageSize); } else { - message.error(res.message || '批量删除失败'); + message.error(res.message || intl.formatMessage({ id: 'download.message.batchDelete.fail' })); } } catch (error) { console.error('批量删除失败:', error); - message.error('批量删除失败'); + message.error(intl.formatMessage({ id: 'download.message.batchDelete.fail' })); } finally { setLoading(false); } @@ -443,111 +381,15 @@ const DownloadManage: React.FC = () => { fetchDownloadList(1, pagination.pageSize, values); }; - // 使用useEffect监听fileList和thumbnailList的变化,更新表单值 - useEffect(() => { - if (isEdit && fileList.length > 0) { - modalForm.setFieldsValue({ file: fileList }); - } - }, [fileList, isEdit]); - - useEffect(() => { - if (isEdit && thumbnailList.length > 0) { - modalForm.setFieldsValue({ thumbnail: thumbnailList }); - } - }, [thumbnailList, isEdit]); - - // 处理文件上传变化 - const handleFileChange = (uploadFiles: UploadFile[]) => { - setFileList(uploadFiles); - - // 更新表单中的文件值,支持多文件 - modalForm.setFieldsValue({ file: uploadFiles }); - }; - - // 处理缩略图上传变化 - const handleThumbnailChange = (uploadFiles: UploadFile[]) => { - setThumbnailList(uploadFiles); - - // 更新表单中的缩略图值,支持多文件 - modalForm.setFieldsValue({ thumbnail: uploadFiles }); - }; - - // 处理模态框提交 - const handleModalSubmit = async () => { - try { - const values = await modalForm.validateFields(); - - // 检查文件上传 - if (fileList.length === 0 && !isEdit) { - message.error('请上传文件'); - return; - } - - // 获取文件和缩略图信息 - const fileInfo = fileList.length > 0 ? fileList[0] : null; - const thumbnailInfo = thumbnailList.length > 0 ? thumbnailList[0] : null; - - if (!fileInfo && !isEdit) { - message.error('文件上传失败'); - return; - } - - // 构建请求参数 - 注意这里我们仍然只使用第一个文件,因为API可能不支持多文件 - const requestData: API.DownloadRequest = { - name: values.name, - columnType: values.columnType, - keywords: values.keywords, - isBold: parseInt(values.isBold), // 转换为数字类型 - isTop: parseInt(values.isTop), // 转换为数字类型 - thumbnail: thumbnailInfo?.url || thumbnailInfo?.response?.data?.url || '', - fileName: fileInfo?.name || '', - fileType: fileInfo?.type || '', - fileSize: fileInfo?.size?.toString() || '0', - filePath: fileInfo?.response?.data?.filePath || '', - fileUrl: fileInfo?.url || fileInfo?.response?.data?.url || '', - }; - - if (isEdit) { - requestData.id = currentId; - } - - // 添加确认提示 - Modal.confirm({ - title: isEdit ? '确定要保存修改吗?' : '确定要添加该文件吗?', - icon: , - content: `文件名称: ${values.name}`, - okText: '确定', - cancelText: '取消', - maskClosable: false, - onOk: async () => { - // 区分新增和修改操作 - const res = isEdit - ? await updateDownload(requestData) - : await addDownload(requestData); - - if (res.success) { - message.success(isEdit ? '更新成功' : '添加成功'); - setModalVisible(false); - modalForm.resetFields(); - setFileList([]); - setThumbnailList([]); - fetchDownloadList(pagination.current, pagination.pageSize); - } else { - message.error(res.message || (isEdit ? '更新失败' : '添加失败')); - } - }, - }); - } catch (info) { - console.log('表单验证失败:', info); - } + // 处理表单成功提交 + const handleFormSuccess = () => { + setModalVisible(false); + fetchDownloadList(pagination.current, pagination.pageSize); }; // 处理模态框取消 const handleModalCancel = () => { setModalVisible(false); - modalForm.resetFields(); - setFileList([]); - setThumbnailList([]); }; return ( @@ -560,11 +402,11 @@ const DownloadManage: React.FC = () => { layout="inline" className="filter-form" > - - + + - - {DownloadColumnTypeOptions.map((option) => ( - - @@ -587,7 +429,7 @@ const DownloadManage: React.FC = () => {
{hasSelected && ( - 已选择 {selectedRowKeys.length} 项 + + {intl.formatMessage( + { id: 'download.selected.count' }, + { count: selectedRowKeys.length } + )} + )}
@@ -637,86 +484,22 @@ const DownloadManage: React.FC = () => { {/* 新增/编辑模态框 */} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
); diff --git a/src/pages/noticeManage/NoticeManageForm.tsx b/src/pages/noticeManage/NoticeManageForm.tsx index 9729bb1..8d932d8 100644 --- a/src/pages/noticeManage/NoticeManageForm.tsx +++ b/src/pages/noticeManage/NoticeManageForm.tsx @@ -32,6 +32,7 @@ const NoticeManageForm: React.FC = ({ id, isEdit, onSucce titleEn: detail.titleEn, contentZh: detail.content, contentEn: detail.contentEn, + settingEn: detail.settingEn === '1', }); } else { message.error(response.message || '获取详情失败'); @@ -90,7 +91,7 @@ const NoticeManageForm: React.FC = ({ id, isEdit, onSucce content: values.contentZh, contentEn: values.contentEn || '', isTop: values.isTop ? TopStatus.YES : TopStatus.NO, - settingEn: values.titleEn && values.contentEn ? EnglishSetting.YES : EnglishSetting.NO, + settingEn: values.settingEn ? EnglishSetting.YES : EnglishSetting.NO, }; let response; @@ -121,6 +122,10 @@ const NoticeManageForm: React.FC = ({ id, isEdit, onSucce
+ + + + = ({ id, isEdit, onSucce @@ -151,7 +156,7 @@ const NoticeManageForm: React.FC = ({ id, isEdit, onSucce { // 处理发布/下架 const handlePublishStatus = async (record: NoticeType) => { - // 状态: 0-草稿,1-已发布 + // 状态: 0-草稿,1-已发布,2-已下架 const isPublished = record.status === NoticeStatus.PUBLISHED; const actionText = isPublished ? '下架' : '发布'; const newStatus = isPublished ? NoticeStatus.UNPUBLISHED : NoticeStatus.PUBLISHED; - try { - // 调用API更新状态 - const response = await updateNoticeStatus(record.id, newStatus); - if (response && response.success) { - message.success(`${actionText}成功`); - fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 - } else { - message.error(response.message || `${actionText}失败`); - } - } catch (error) { - console.error(`${actionText}失败:`, error); - message.error(`${actionText}失败`); - } + Modal.confirm({ + title: `确定要${actionText}该通知吗?`, + icon: , + content: `标题: ${record.title}`, + okText: '确定', + okType: isPublished ? 'danger' : 'primary', + cancelText: '取消', + maskClosable: false, + onOk: async () => { + try { + // 调用API更新状态 + const response = await updateNoticeStatus(record.id, newStatus); + if (response && response.success) { + message.success(`${actionText}成功`); + fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 + } else { + message.error(response.message || `${actionText}失败`); + } + } catch (error) { + console.error(`${actionText}失败:`, error); + message.error(`${actionText}失败`); + } + }, + }); }; // 处理置顶/取消置顶 @@ -201,19 +212,30 @@ const NoticeManage: React.FC = () => { const actionText = isTop ? '取消置顶' : '置顶'; const newIsTop = isTop ? TopStatus.NO : TopStatus.YES; - try { - // 调用API更新置顶状态 - const response = await updateNoticeTopStatus(record.id, newIsTop); - if (response && response.success) { - message.success(`${actionText}成功`); - fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 - } else { - message.error(response.message || `${actionText}失败`); - } - } catch (error) { - console.error(`${actionText}失败:`, error); - message.error(`${actionText}失败`); - } + Modal.confirm({ + title: `确定要${actionText}该通知吗?`, + icon: , + content: `标题: ${record.title}`, + okText: '确定', + okType: 'primary', + cancelText: '取消', + maskClosable: false, + onOk: async () => { + try { + // 调用API更新置顶状态 + const response = await updateNoticeTopStatus(record.id, newIsTop); + if (response && response.success) { + message.success(`${actionText}成功`); + fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 + } else { + message.error(response.message || `${actionText}失败`); + } + } catch (error) { + console.error(`${actionText}失败:`, error); + message.error(`${actionText}失败`); + } + }, + }); }; // 获取状态标签 @@ -310,12 +332,6 @@ const NoticeManage: React.FC = () => { > 删除 - )} @@ -353,8 +369,23 @@ const NoticeManage: React.FC = () => { // 处理批量删除 const handleBatchDelete = () => { + if (selectedRowKeys.length === 0) { + message.warning('请选择需要删除的记录'); + return; + } + + // 检查所选项中是否有已发布的通知 + const hasPublished = noticeData.some( + (item) => selectedRowKeys.includes(item.key) && item.status === NoticeStatus.PUBLISHED + ); + + if (hasPublished) { + message.warning('已发布的通知不能删除'); + return; + } + Modal.confirm({ - title: '确定要删除选中的通知吗?', + title: `确定要删除选中的 ${selectedRowKeys.length} 条通知吗?`, icon: , content: '删除后无法恢复', okText: '确定', @@ -362,32 +393,20 @@ const NoticeManage: React.FC = () => { 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 !== NoticeStatus.PUBLISHED; - }) as string[]; - - if (deleteIds.length > 0) { - // 调用批量删除API - const response = await batchDeleteNotice(deleteIds); - if (response && response.success) { - setSelectedRowKeys([]); - message.success('删除成功'); - fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 - } else { - message.error(response.message || '批量删除失败'); - } + const ids = selectedRowKeys.map(key => key.toString()); + // 调用批量删除API + const response = await batchDeleteNotice(ids); + if (response && response.success) { + message.success('批量删除成功'); + setSelectedRowKeys([]); // 清空选择 + fetchNoticeList(pagination.current, pagination.pageSize, searchParams); // 重新加载数据 } else { - message.warning('没有可删除的通知'); + message.error(response.message || '批量删除失败'); } } catch (error) { console.error('批量删除失败:', error); message.error('批量删除失败'); - } finally { - setLoading(false); } }, }); diff --git a/src/servers/api/notice.ts b/src/servers/api/notice.ts index 2b3d785..61f0974 100644 --- a/src/servers/api/notice.ts +++ b/src/servers/api/notice.ts @@ -2,62 +2,74 @@ import request from '@/utils/request'; // 获取通知列表 export async function getNoticeList(params: API.NoticeSearchParams & { pageNo?: number; pageSize?: number }) { - return request('/notices', { - method: 'GET', - params, + return request('/portals/notice/getPage', { + method: 'POST', + data: { + pageNo: params.pageNo || 1, + pageSize: params.pageSize || 10, + title: params.title || '', + columnType: 'notice', + status: params.status || '', + }, }); } // 获取通知详情 export async function getNoticeDetail(id: string) { - return request(`/notices/${id}`, { + return request(`/portals/notice/${id}`, { method: 'GET', }); } // 新增通知 export async function addNotice(params: API.NoticeRequest) { - return request('/notices', { + return request('/portals/notice', { method: 'POST', - data: params, + data: { + ...params, + columnType: 'notice', + }, }); } // 更新通知 export async function updateNotice(id: string, params: API.NoticeRequest) { - return request(`/notices/${id}`, { + return request('/portals/notice/', { method: 'PUT', - data: params, + data: { + ...params, + id, + columnType: 'notice', + }, }); } // 删除通知 export async function deleteNotice(id: string) { - return request(`/notices/${id}`, { + return request(`/portals/notice/${id}`, { method: 'DELETE', }); } // 批量删除通知 export async function batchDeleteNotice(ids: string[]) { - return request('/notices/batch', { + return request(`/portals/notice/${ids.join(',')}`, { method: 'DELETE', - data: { ids }, }); } // 发布/下架通知 export async function updateNoticeStatus(id: string, status: string) { - return request(`/notices/${id}/status`, { + return request('/portals/notice/', { method: 'PUT', - data: { status }, + data: { id, status }, }); } // 置顶/取消置顶通知 export async function updateNoticeTopStatus(id: string, isTop: string) { - return request(`/notices/${id}/top`, { + return request('/portals/notice/', { method: 'PUT', - data: { isTop }, + data: { id, isTop }, }); }