From 60473ed8aeff7ced78774ba23c03406fcad5164a Mon Sep 17 00:00:00 2001 From: linxd <544554903@qq.com> Date: Mon, 30 Jun 2025 19:40:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E9=80=9A=E7=9F=A5=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E4=B8=8E=E6=94=BF=E7=AD=96=E6=B3=95=E8=A7=84,?= =?UTF-8?q?=E5=8C=85=E6=8B=AC=E5=A4=9A=E8=AF=AD=E8=A8=80=E7=BB=B4=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/proxy.ts | 4 +- src/locales/en-US.ts | 8 + src/locales/en-US/download.ts | 15 ++ src/locales/en-US/notice.ts | 29 ++++ src/locales/zh-CN.ts | 8 + src/locales/zh-CN/download.ts | 15 ++ src/locales/zh-CN/notice.ts | 29 ++++ src/pages/download/download.tsx | 282 +++++++++++++------------------- src/pages/download/service.ts | 75 --------- src/pages/help/helpQuestion.tsx | 8 +- src/pages/index/index.tsx | 9 +- src/pages/login/login.tsx | 2 +- src/pages/notice/notice.tsx | 157 ++++++++---------- src/pages/notice/noticeInfo.tsx | 226 ++++++------------------- src/servers/api/download.ts | 103 ++++++++++++ src/servers/api/index.ts | 8 + src/servers/api/notice.ts | 75 +++++++++ src/servers/api/typings.d.ts | 93 ++++++++++- 18 files changed, 632 insertions(+), 514 deletions(-) create mode 100644 src/locales/en-US/download.ts create mode 100644 src/locales/en-US/notice.ts create mode 100644 src/locales/zh-CN/download.ts create mode 100644 src/locales/zh-CN/notice.ts delete mode 100644 src/pages/download/service.ts create mode 100644 src/servers/api/download.ts create mode 100644 src/servers/api/index.ts create mode 100644 src/servers/api/notice.ts diff --git a/config/proxy.ts b/config/proxy.ts index 9041684..62211ad 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -7,12 +7,12 @@ export default { // }, '/api': { // target: 'http://10.242.37.148:18022',//连接天宫的ng - target: 'http://10.0.0.125:18012',//连接天宫的ng + target: 'http://10.0.0.14:18013',//连接天宫的ng changeOrigin: true, pathRewrite: { '^/api': '' }, }, '/upload': { - target: 'http://10.0.0.125:18012',// + target: 'http://10.0.0.14:18013',// changeOrigin: true, pathRewrite: { '^/upload': '' }, }, diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index afdaad1..14a036a 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -1,5 +1,7 @@ import help from './en-US/help'; import policy from './en-US/policy'; +import download from './en-US/download'; +import notice from './en-US/notice'; export default { 'menu.首页': 'Home', @@ -104,4 +106,10 @@ export default { // Policy and Regulations module ...policy, + + // Download Center module + ...download, + + // Notice Center module + ...notice, }; diff --git a/src/locales/en-US/download.ts b/src/locales/en-US/download.ts new file mode 100644 index 0000000..4f53532 --- /dev/null +++ b/src/locales/en-US/download.ts @@ -0,0 +1,15 @@ +export default { + // Download center page + 'download.title': 'Download Center', + 'download.menu.template': 'Templates', + 'download.menu.manual': 'Manuals', + 'download.card.date': 'Published: {publishTime}', + 'download.button': 'Download', + 'download.empty': 'No files available for download', + 'download.list.total': 'Total {total} Records', + + // Download center messages + 'download.message.downloadFailed': 'Download failed, please try again later', + 'download.message.getListFailed': 'Failed to get download list', + 'download.message.getListError': 'Error getting download list, please try again later', +}; diff --git a/src/locales/en-US/notice.ts b/src/locales/en-US/notice.ts new file mode 100644 index 0000000..33b6652 --- /dev/null +++ b/src/locales/en-US/notice.ts @@ -0,0 +1,29 @@ +export default { + // Notice center list page + 'notice.title': 'Notifications', + 'notice.menu.system': 'System Updates', + 'notice.menu.other': 'Other Notifications', + 'notice.list.column.index': 'No.', + 'notice.list.column.title': 'Title', + 'notice.list.column.publishTime': 'Publish Time', + 'notice.list.empty': 'No notifications', + 'notice.list.total': 'Total {total} Records', + + // Notice center detail page + 'notice.detail.back': 'Back to List', + 'notice.detail.publishTime': 'Publish Time', + 'notice.detail.publisher': 'Publisher', + 'notice.detail.type': 'Notice Type', + 'notice.detail.type.notice': 'Announcement', + 'notice.detail.type.system': 'System Notification', + 'notice.detail.type.other': 'Other Notification', + 'notice.detail.notFound': 'Notice Not Found', + 'notice.detail.loading': 'Loading...', + + // Notice center messages + 'notice.message.getListFailed': 'Failed to get notification list', + 'notice.message.getListError': 'Error getting notification list, please try again later', + 'notice.message.getDetailFailed': 'Failed to get notification detail', + 'notice.message.getDetailError': 'Error getting notification detail, please try again later', + 'notice.message.idNotExist': 'Notice ID cannot be empty', +}; diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index fe7fc36..61aa0c0 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -1,5 +1,7 @@ import help from './zh-CN/help'; import policy from './zh-CN/policy'; +import download from './zh-CN/download'; +import notice from './zh-CN/notice'; export default { 'menu.首页': '首页', @@ -104,4 +106,10 @@ export default { // 政策法规模块 ...policy, + + // 下载中心模块 + ...download, + + // 通知中心模块 + ...notice, }; diff --git a/src/locales/zh-CN/download.ts b/src/locales/zh-CN/download.ts new file mode 100644 index 0000000..4c0a801 --- /dev/null +++ b/src/locales/zh-CN/download.ts @@ -0,0 +1,15 @@ +export default { + // 下载中心页面 + 'download.title': '下载中心', + 'download.menu.template': '模板文件', + 'download.menu.manual': '操作手册', + 'download.card.date': '发布时间: {publishTime}', + 'download.button': '下载', + 'download.empty': '暂无可下载的文件', + 'download.list.total': '共 {total} 条记录', + + // 下载中心消息 + 'download.message.downloadFailed': '下载失败,请稍后重试', + 'download.message.getListFailed': '获取下载列表失败', + 'download.message.getListError': '获取下载列表出错,请稍后重试', +}; diff --git a/src/locales/zh-CN/notice.ts b/src/locales/zh-CN/notice.ts new file mode 100644 index 0000000..36fbf00 --- /dev/null +++ b/src/locales/zh-CN/notice.ts @@ -0,0 +1,29 @@ +export default { + // 通知中心列表页面 + 'notice.title': '通知中心', + 'notice.menu.system': '系统更新通知', + 'notice.menu.other': '其他通知', + 'notice.list.column.index': '序号', + 'notice.list.column.title': '标题', + 'notice.list.column.publishTime': '发布时间', + 'notice.list.empty': '暂无通知', + 'notice.list.total': '共 {total} 条记录', + + // 通知中心详情页面 + 'notice.detail.back': '返回列表', + 'notice.detail.publishTime': '发布时间', + 'notice.detail.publisher': '发布人', + 'notice.detail.type': '通知类型', + 'notice.detail.type.notice': '通知公告', + 'notice.detail.type.system': '系统通知', + 'notice.detail.type.other': '其他通知', + 'notice.detail.notFound': '未找到相关通知', + 'notice.detail.loading': '加载中...', + + // 通知中心消息 + 'notice.message.getListFailed': '获取通知列表失败', + 'notice.message.getListError': '获取通知列表出错,请稍后重试', + 'notice.message.getDetailFailed': '获取通知详情失败', + 'notice.message.getDetailError': '获取通知详情出错,请稍后重试', + 'notice.message.idNotExist': '通知ID不能为空', +}; diff --git a/src/pages/download/download.tsx b/src/pages/download/download.tsx index f4851f2..47ca03f 100644 --- a/src/pages/download/download.tsx +++ b/src/pages/download/download.tsx @@ -1,121 +1,22 @@ import React, { useState, useEffect } from 'react'; import { Card, Menu, Row, Col, Pagination, Button, Typography, Space, message } from 'antd'; import { FileOutlined, BookOutlined, DownloadOutlined } from '@ant-design/icons'; +import { useIntl, FormattedMessage } from 'umi'; import styles from './download.less'; -import { downloadFile } from './service'; +import { downloadFile, getDownloadList, DownloadRecord } from '@/servers/api/download'; const { Title, Text } = Typography; -// 模拟模板文件数据 -const mockTemplateFiles = [ - { - id: '1', - title: '公开招标操作手册', - description: '公开招标各角色操作手册', - publishDate: '2025年2月3日', - type: 'template', - icon: , - fileName: '公开招标操作手册.pdf', - }, - { - id: '2', - title: '询价采购模板', - description: '标准询价采购流程文档模板', - publishDate: '2025年1月15日', - type: 'template', - icon: , - fileName: '询价采购模板.docx', - }, - { - id: '3', - title: '竞争性谈判模板', - description: '竞争性谈判标准文档模板', - publishDate: '2024年12月20日', - type: 'template', - icon: , - fileName: '竞争性谈判模板.docx', - }, - { - id: '4', - title: '单一来源采购模板', - description: '单一来源采购申请及实施模板', - publishDate: '2024年12月5日', - type: 'template', - icon: , - fileName: '单一来源采购模板.docx', - }, - { - id: '5', - title: '供应商评估表格', - description: '供应商资质与能力评估标准表格', - publishDate: '2024年11月18日', - type: 'template', - icon: , - fileName: '供应商评估表格.xlsx', - }, - { - id: '6', - title: '合同范本模板', - description: '标准采购合同范本', - publishDate: '2024年11月1日', - type: 'template', - icon: , - fileName: '合同范本模板.docx', - }, -]; - -// 模拟操作手册数据 -const mockManuals = [ - { - id: '7', - title: '供应商注册指南', - description: '供应商平台注册及资质提交操作指南', - publishDate: '2025年1月25日', - type: 'manual', - icon: , - fileName: '供应商注册指南.pdf', - }, - { - id: '8', - title: '投标操作指南', - description: '电子投标全流程操作手册', - publishDate: '2025年1月10日', - type: 'manual', - icon: , - fileName: '投标操作指南.pdf', - }, - { - id: '9', - title: '在线开标指南', - description: '在线开标会议参与指南', - publishDate: '2024年12月15日', - type: 'manual', - icon: , - fileName: '在线开标指南.pdf', - }, - { - id: '10', - title: '评标专家操作手册', - description: '评标专家系统使用指南', - publishDate: '2024年11月28日', - type: 'manual', - icon: , - fileName: '评标专家操作手册.pdf', - }, - { - id: '11', - title: '合同签署指南', - description: '电子合同签署流程指南', - publishDate: '2024年11月10日', - type: 'manual', - icon: , - fileName: '合同签署指南.pdf', - }, -]; +// 模拟模板文件数据 - 后期将通过API获取分类 +const mockCategories: { [key: string]: string } = { + template: '模板文件', + manual: '操作手册' +}; const DownloadPage: React.FC = () => { + const intl = useIntl(); const [activeMenu, setActiveMenu] = useState('template'); - const [downloadData, setDownloadData] = useState([]); + const [downloadData, setDownloadData] = useState([]); const [loading, setLoading] = useState(true); const [pagination, setPagination] = useState({ current: 1, @@ -123,51 +24,75 @@ const DownloadPage: React.FC = () => { total: 0, }); - // 根据当前选中的菜单加载对应的下载数据 - useEffect(() => { + // 加载下载数据 + const loadDownloadData = async (page: number, pageSize: number) => { setLoading(true); - // 模拟API请求 - setTimeout(() => { - const data = activeMenu === 'template' ? mockTemplateFiles : mockManuals; - setDownloadData(data); - setPagination((prevPagination) => ({ - ...prevPagination, - total: data.length, - current: 1, - })); + try { + const response = await getDownloadList({ + pageNo: page.toString(), + pageSize: pageSize.toString() + }); + + if (response.code === 200 && response.success) { + // 根据当前选中的菜单过滤数据 + // 目前没有分类的API,暂时都显示,后期可以根据columnType进行过滤 + const data = response.data.records; + + setDownloadData(data); + setPagination({ + current: response.data.current, + pageSize: response.data.size, + total: response.data.total, + }); + } else { + message.error(response.message || intl.formatMessage({ id: 'download.message.getListFailed' })); + } + } catch (error) { + console.error('获取下载列表出错:', error); + message.error(intl.formatMessage({ id: 'download.message.getListError' })); + } finally { setLoading(false); - }, 500); - }, [activeMenu]); + } + }; + + // 初始加载和分页变化时加载数据 + useEffect(() => { + loadDownloadData(pagination.current, pagination.pageSize); + }, [pagination.current, activeMenu]); // 处理菜单切换 const handleMenuClick = (e: any) => { setActiveMenu(e.key); + setPagination({ + ...pagination, + current: 1, // 切换分类时重置页码 + }); }; // 处理分页变化 const handlePageChange = (page: number, pageSize?: number) => { + const newPageSize = pageSize || pagination.pageSize; setPagination({ ...pagination, current: page, - pageSize: pageSize || pagination.pageSize, + pageSize: newPageSize, }); }; // 处理下载按钮点击 - const handleDownload = async (id: string, fileName: string) => { + const handleDownload = async (item: DownloadRecord) => { try { - await downloadFile(id, fileName); + window.open(item.fileUrl, '_blank'); + // await downloadFile(id, fileName); } catch (error) { - message.error('下载失败,请稍后重试'); + message.error(intl.formatMessage({ id: 'download.message.downloadFailed' })); } }; - // 计算当前页显示的数据 - const getCurrentPageData = () => { - const { current, pageSize } = pagination; - const startIndex = (current - 1) * pageSize; - const endIndex = startIndex + pageSize; - return downloadData.slice(startIndex, endIndex); + // 获取文件图标 + const getFileIcon = (fileType: string) => { + // 根据文件类型返回不同图标,可以进一步完善 + return ; }; return ( @@ -181,55 +106,78 @@ const DownloadPage: React.FC = () => { className={styles.downloadMenu} > }> - 模板文件 + }> - 操作手册 +
- {activeMenu === 'template' ? '模板文件' : '操作手册'} + + <FormattedMessage id={`download.menu.${activeMenu}`} defaultMessage={intl.formatMessage({ id: 'download.title' })} /> + - {getCurrentPageData().map((item) => ( - - - -
- {item.icon} - {item.title} -
-
{item.publishDate}
- {item.description} - -
-
+ {loading ? ( + Array(6).fill(null).map((_, index) => ( + + + + )) + ) : downloadData.length > 0 ? ( + downloadData.map((item) => ( + + + +
+ {getFileIcon(item.fileType)} + {item.name} +
+
+ {intl.formatMessage( + { id: 'download.card.date' }, + { publishTime: item.publishTime || '' } + )} +
+ {item.keywords || ''} + +
+
+ + )) + ) : ( + + - ))} + )}
- `共 ${total} 条记录`} - style={{ marginTop: 24, textAlign: 'right' }} - /> + {downloadData.length > 0 && ( + intl.formatMessage( + { id: 'download.list.total' }, + { total } + )} + style={{ marginTop: 24, textAlign: 'right' }} + /> + )}
diff --git a/src/pages/download/service.ts b/src/pages/download/service.ts deleted file mode 100644 index 11324fd..0000000 --- a/src/pages/download/service.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { message } from 'antd'; -import request from '@/utils/request'; - -/** - * 获取下载中心文件列表 - * @param params 查询参数 - */ -export async function getDownloadList(params: { - type: string; - current: number; - pageSize: number; -}) { - try { - // 实际项目中应该通过API获取数据 - // return request('/api/download/list', { - // method: 'GET', - // params, - // }); - - // 模拟API请求返回数据 - return Promise.resolve({ - success: true, - data: { - list: [], - total: 0, - }, - }); - } catch (error) { - message.error('获取下载列表失败'); - return { - success: false, - data: { - list: [], - total: 0, - }, - }; - } -} - -/** - * 下载文件 - * @param fileId 文件ID - * @param fileName 文件名称 - */ -export async function downloadFile(fileId: string, fileName: string) { - try { - // 实际项目中应该通过API下载文件 - // const response = await request(`/api/download/file/${fileId}`, { - // method: 'GET', - // responseType: 'blob', - // }); - - // 创建下载链接 - // const blob = new Blob([response]); - // const url = window.URL.createObjectURL(blob); - // const link = document.createElement('a'); - // link.href = url; - // link.download = fileName; - // document.body.appendChild(link); - // link.click(); - // window.URL.revokeObjectURL(url); - // document.body.removeChild(link); - - // 模拟下载成功 - message.success(`文件"${fileName}"开始下载`); - return { - success: true, - }; - } catch (error) { - message.error(`下载文件"${fileName}"失败`); - return { - success: false, - }; - } -} diff --git a/src/pages/help/helpQuestion.tsx b/src/pages/help/helpQuestion.tsx index ecb2dda..2a238a8 100644 --- a/src/pages/help/helpQuestion.tsx +++ b/src/pages/help/helpQuestion.tsx @@ -4,7 +4,7 @@ import { ArrowLeftOutlined } from '@ant-design/icons'; import { history, useIntl } from 'umi'; import WangEditor from 'wangeditor'; import { QUESTION_TYPES } from '@/dicts/help'; -import { addHelpQuestion } from '@/servers/api/help'; +import { addHelpCenterQuestion } from '@/servers/api/help'; import styles from './helpQuestion.less'; const { Title } = Typography; @@ -70,9 +70,13 @@ const HelpQuestionPage: React.FC = () => { setSubmitting(true); try { - const response = await addHelpQuestion({ + const response = await addHelpCenterQuestion({ ...values, content: content, + companyName: values.company, + contactDetails: values.email, + fullName: values.name, + userName: values.account, }); if (response.success) { diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 0e7f87a..4cde935 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,9 +1,10 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Card, Row, Col, Tabs, Table } from 'antd'; import { useIntl, Link } from 'umi'; import './index.less'; import IconFont from '@/components/IconFont/IconFont'; import LinkComponent from './Link'; +import { getCoscoPortalsLinksClassification } from '@/servers/api'; const IndexPage: React.FC = () => { const intl = useIntl(); const [noticeLoading, setNoticeLoading] = useState(false); @@ -152,6 +153,12 @@ const IndexPage: React.FC = () => { }, ]; + useEffect(() => { + getCoscoPortalsLinksClassification().then((res) => { + console.log(res); + }); + }, []); + return (
{/* 通知列表 */} diff --git a/src/pages/login/login.tsx b/src/pages/login/login.tsx index 993a82f..abe595a 100644 --- a/src/pages/login/login.tsx +++ b/src/pages/login/login.tsx @@ -45,7 +45,7 @@ const LoginPage: React.FC = () => { // 渲染注册链接(只在供应商和专家Tab下显示) const renderRegisterLink = () => { - if (activeKey === 'agent') { + if (activeKey === 'agent' || activeKey === 'expert') { return null; // 招标代理不显示注册链接 } diff --git a/src/pages/notice/notice.tsx b/src/pages/notice/notice.tsx index 751bc6a..516aef8 100644 --- a/src/pages/notice/notice.tsx +++ b/src/pages/notice/notice.tsx @@ -1,80 +1,20 @@ import React, { useState, useEffect } from 'react'; -import { Table, Menu, Row, Col } from 'antd'; -import { history } from 'umi'; +import { Table, Menu, Row, Col, message } from 'antd'; +import { history, useIntl, FormattedMessage } from 'umi'; import { BellOutlined, AppstoreOutlined } from '@ant-design/icons'; import styles from './notice.less'; +import { getNoticeList, NoticeRecord } from '@/servers/api/notice'; -// 模拟系统更新通知数据 -const mockSystemNotices = [ - { - id: '1', - title: '系统将于2023年9月15日进行版本升级', - publishDate: '2023-09-10', - type: 'system', - }, - { - id: '2', - title: '招标模块功能优化更新通知', - publishDate: '2023-08-25', - type: 'system', - }, - { - id: '3', - title: '系统安全性能升级维护通知', - publishDate: '2023-08-10', - type: 'system', - }, - { - id: '4', - title: '移动端应用同步更新通知', - publishDate: '2023-07-28', - type: 'system', - }, - { - id: '5', - title: '供应商管理模块功能升级通知', - publishDate: '2023-07-15', - type: 'system', - }, -]; - -// 模拟其他通知数据 -const mockOtherNotices = [ - { - id: '6', - title: '关于开展2023年度供应商评估工作的通知', - publishDate: '2023-09-05', - type: 'other', - }, - { - id: '7', - title: '关于调整采购审批流程的通知', - publishDate: '2023-08-20', - type: 'other', - }, - { - id: '8', - title: '关于加强信息安全管理的通知', - publishDate: '2023-08-05', - type: 'other', - }, - { - id: '9', - title: '关于开展采购人员培训的通知', - publishDate: '2023-07-25', - type: 'other', - }, - { - id: '10', - title: '关于优化供应商准入机制的通知', - publishDate: '2023-07-10', - type: 'other', - }, -]; +// 通知类型映射 +const noticeTypes: { [key: string]: string } = { + system: '系统更新通知', + other: '其他通知' +}; const NoticePage: React.FC = () => { + const intl = useIntl(); const [activeMenu, setActiveMenu] = useState('system'); - const [noticeData, setNoticeData] = useState([]); + const [noticeData, setNoticeData] = useState([]); const [loading, setLoading] = useState(true); const [pagination, setPagination] = useState({ current: 1, @@ -82,33 +22,58 @@ const NoticePage: React.FC = () => { total: 0, }); - // 根据当前选中的菜单加载对应的通知数据 - useEffect(() => { + // 加载通知数据 + const loadNoticeData = async (page: number, pageSize: number) => { setLoading(true); - // 模拟API请求 - setTimeout(() => { - const data = activeMenu === 'system' ? mockSystemNotices : mockOtherNotices; - setNoticeData(data); - setPagination((prevPagination) => ({ - ...prevPagination, - total: data.length, - })); + try { + const response = await getNoticeList({ + pageNo: page.toString(), + pageSize: pageSize.toString() + }); + + if (response.code === 200 && response.success) { + // 根据当前选中的菜单过滤数据 + // 目前没有分类的API,暂时都显示,后期可以根据不同类型进行过滤 + const data = response.data.records; + + setNoticeData(data); + setPagination({ + current: response.data.current, + pageSize: response.data.size, + total: response.data.total, + }); + } else { + message.error(response.message || intl.formatMessage({ id: 'notice.message.getListFailed' })); + } + } catch (error) { + console.error('获取通知列表出错:', error); + message.error(intl.formatMessage({ id: 'notice.message.getListError' })); + } finally { setLoading(false); - }, 500); - }, [activeMenu]); + } + }; + + // 初始加载和分页变化时加载数据 + useEffect(() => { + loadNoticeData(pagination.current, pagination.pageSize); + }, [pagination.current, activeMenu]); // 处理菜单切换 const handleMenuClick = (e: any) => { setActiveMenu(e.key); setPagination({ ...pagination, - current: 1, + current: 1, // 切换分类时重置页码 }); }; // 处理表格分页变化 const handleTableChange = (newPagination: any) => { - setPagination(newPagination); + setPagination({ + ...pagination, + current: newPagination.current, + pageSize: newPagination.pageSize, + }); }; // 处理点击通知标题 @@ -119,7 +84,7 @@ const NoticePage: React.FC = () => { // 定义表格列 const columns = [ { - title: '序号', + title: intl.formatMessage({ id: 'notice.list.column.index' }), dataIndex: 'index', key: 'index', width: 80, @@ -128,19 +93,19 @@ const NoticePage: React.FC = () => { }, }, { - title: '标题', + title: intl.formatMessage({ id: 'notice.list.column.title' }), dataIndex: 'title', key: 'title', - render: (text: string, record: any) => ( + render: (text: string, record: NoticeRecord) => ( handleNoticeClick(record.id)} className={styles.noticeTitle}> {text} ), }, { - title: '发布时间', - dataIndex: 'publishDate', - key: 'publishDate', + title: intl.formatMessage({ id: 'notice.list.column.publishTime' }), + dataIndex: 'publishTime', + key: 'publishTime', width: 150, align: 'center' as 'center', }, @@ -157,10 +122,10 @@ const NoticePage: React.FC = () => { className={styles.noticeMenu} > }> - 系统更新通知 + }> - 其他通知 + @@ -173,13 +138,19 @@ const NoticePage: React.FC = () => { rowKey="id" pagination={{ ...pagination, - showTotal: (total) => `共 ${total} 条记录`, + showTotal: (total) => intl.formatMessage( + { id: 'notice.list.total' }, + { total } + ), showSizeChanger: true, showQuickJumper: true, }} loading={loading} onChange={handleTableChange} bordered + locale={{ + emptyText: intl.formatMessage({ id: 'notice.list.empty' }) + }} />
diff --git a/src/pages/notice/noticeInfo.tsx b/src/pages/notice/noticeInfo.tsx index 9ea78f9..ac164b9 100644 --- a/src/pages/notice/noticeInfo.tsx +++ b/src/pages/notice/noticeInfo.tsx @@ -1,182 +1,45 @@ import React, { useState, useEffect } from 'react'; -import { useLocation } from 'umi'; +import { useLocation, useIntl, FormattedMessage } from 'umi'; import { Typography, Button, Divider, Spin, message } from 'antd'; import { ArrowLeftOutlined } from '@ant-design/icons'; import styles from './noticeInfo.less'; +import { getNoticeDetail, NoticeRecord } from '@/servers/api/notice'; const { Title, Text } = Typography; -interface NoticeDetail { - id: string; - title: string; - content: string; - publishDate: string; - publisher: string; - type: string; -} - -interface NoticeDetails { - [key: string]: NoticeDetail; -} - -// 模拟通知详情数据 -const mockNoticeDetails: NoticeDetails = { - '1': { - id: '1', - title: '系统将于2023年9月15日进行版本升级', - publishDate: '2023-09-10', - publisher: '系统管理员', - type: 'system', - content: ` -

尊敬的用户:

-

为了提供更好的用户体验和系统功能,我们计划于2023年9月15日晚上22:00至次日凌晨2:00进行系统版本升级。在此期间,系统将暂停服务,请您提前做好相关工作安排。

- -

本次升级内容:

-
    -
  1. 优化招标采购流程,提高操作效率
  2. -
  3. 增加供应商评价功能,完善评价体系
  4. -
  5. 优化系统响应速度,提升用户体验
  6. -
  7. 修复已知问题,提高系统稳定性
  8. -
  9. 增强系统安全性,保障数据安全
  10. -
- -

升级注意事项:

-
    -
  1. 请您在系统升级前保存并提交所有未完成的工作
  2. -
  3. 系统升级后,建议清除浏览器缓存再登录系统
  4. -
  5. 如遇到任何问题,请联系系统管理员
  6. -
- -

感谢您的理解与支持!

-

系统管理团队

-

2023年9月10日

- ` - }, - '2': { - id: '2', - title: '招标模块功能优化更新通知', - publishDate: '2023-08-25', - publisher: '系统管理员', - type: 'system', - content: ` -

尊敬的用户:

-

我们很高兴地通知您,招标模块已完成功能优化升级,现已上线。本次更新主要针对招标流程进行了优化,提高了操作效率和用户体验。

- -

主要更新内容:

-
    -
  1. 简化招标发布流程,减少操作步骤
  2. -
  3. 优化投标文件管理功能,支持批量上传和下载
  4. -
  5. 增加招标项目进度跟踪功能,实时掌握项目状态
  6. -
  7. 完善评标功能,支持多种评标方法
  8. -
  9. 增加中标结果自动生成功能,提高工作效率
  10. -
- -

使用建议:

-
    -
  1. 请参考系统内置的操作指南熟悉新功能
  2. -
  3. 如有任何问题或建议,请通过系统反馈功能提交
  4. -
- -

感谢您对我们工作的支持!

-

系统管理团队

-

2023年8月25日

- ` - }, - '6': { - id: '6', - title: '关于开展2023年度供应商评估工作的通知', - publishDate: '2023-09-05', - publisher: '采购管理部', - type: 'other', - content: ` -

各相关部门:

-

为加强供应商管理,提高采购质量,根据《中远海运集团供应商管理实施细则》的要求,现决定开展2023年度供应商评估工作,具体事项通知如下:

- -

一、评估对象

-

2023年度与我集团有业务往来的所有供应商。

- -

二、评估时间

-

2023年9月15日至10月15日。

- -

三、评估内容

-
    -
  1. 供应商资质情况
  2. -
  3. 产品质量及服务水平
  4. -
  5. 价格合理性
  6. -
  7. 交货及时性
  8. -
  9. 售后服务响应速度
  10. -
  11. 合同履约情况
  12. -
  13. 社会责任履行情况
  14. -
- -

四、评估方法

-

采用百分制评分,根据评分结果将供应商分为A、B、C、D四个等级。

- -

五、工作要求

-
    -
  1. 各部门应指定专人负责本部门供应商评估工作
  2. -
  3. 评估过程应客观公正,实事求是
  4. -
  5. 评估结果应于10月20日前报送采购管理部汇总
  6. -
- -

特此通知。

-

采购管理部

-

2023年9月5日

- ` - }, - '7': { - id: '7', - title: '关于调整采购审批流程的通知', - publishDate: '2023-08-20', - publisher: '采购管理部', - type: 'other', - content: ` -

各相关部门:

-

为提高采购效率,优化业务流程,经公司研究决定,对采购审批流程进行调整,现将有关事项通知如下:

- -

一、调整内容

-
    -
  1. 采购金额50万元以下的项目,由部门经理审批后直接提交采购部执行,无需总经理审批
  2. -
  3. 采购金额50万元至200万元的项目,由部门经理和分管副总经理审批后提交采购部执行
  4. -
  5. 采购金额200万元以上的项目,仍按原流程执行,需经总经理审批
  6. -
- -

二、实施时间

-

本通知自2023年9月1日起实施。

- -

三、注意事项

-
    -
  1. 各部门应严格按照新的审批流程执行,不得擅自变更
  2. -
  3. 采购部应加强对采购项目的监督管理,确保采购质量
  4. -
  5. 审批人应认真履行审批职责,对采购项目的必要性、合理性进行审核
  6. -
- -

特此通知。

-

采购管理部

-

2023年8月20日

- ` - } -}; - const NoticeInfo: React.FC = () => { + const intl = useIntl(); const location = useLocation(); const id = new URLSearchParams(location.search).get("id"); - const [noticeDetail, setNoticeDetail] = useState(null); + const [noticeDetail, setNoticeDetail] = useState(null); const [loading, setLoading] = useState(true); - // 模拟获取通知详情数据 + // 获取通知详情数据 useEffect(() => { - // 实际项目中应该通过API获取数据 - setTimeout(() => { - if (id && mockNoticeDetails[id]) { - setNoticeDetail(mockNoticeDetails[id]); - } else { - // 处理ID不存在的情况 - message.error('通知不存在'); + const fetchNoticeDetail = async () => { + if (!id) { + message.error(intl.formatMessage({ id: 'notice.message.idNotExist' })); + setLoading(false); + return; } - setLoading(false); - }, 500); - }, [id]); + + try { + const response = await getNoticeDetail(id); + if (response.code === 200 && response.success) { + setNoticeDetail(response.data); + } else { + message.error(response.message || intl.formatMessage({ id: 'notice.message.getDetailFailed' })); + } + } catch (error) { + console.error('获取通知详情出错:', error); + message.error(intl.formatMessage({ id: 'notice.message.getDetailError' })); + } finally { + setLoading(false); + } + }; + + fetchNoticeDetail(); + }, [id, intl]); // 处理返回列表 const handleBack = () => { @@ -186,7 +49,7 @@ const NoticeInfo: React.FC = () => { if (loading) { return (
- +
); } @@ -194,12 +57,27 @@ const NoticeInfo: React.FC = () => { if (!noticeDetail) { return (
- 未找到相关通知 - + <FormattedMessage id="notice.detail.notFound" /> +
); } + // 获取通知类型本地化文本 + const getNoticeTypeText = (columnType: string) => { + if (!columnType) return intl.formatMessage({ id: 'notice.detail.type.notice' }); + + if (columnType === 'system') { + return intl.formatMessage({ id: 'notice.detail.type.system' }); + } else if (columnType === 'other') { + return intl.formatMessage({ id: 'notice.detail.type.other' }); + } + + return intl.formatMessage({ id: 'notice.detail.type.notice' }); + }; + return (
@@ -209,7 +87,7 @@ const NoticeInfo: React.FC = () => { onClick={handleBack} className={styles.backButton} > - 返回列表 +
@@ -222,14 +100,18 @@ const NoticeInfo: React.FC = () => {
- 发布时间: {noticeDetail.publishDate} + + : {noticeDetail.publishTime} +
- 发布人: {noticeDetail.publisher} + + : {noticeDetail.publishBy} +
- 通知类型: {noticeDetail.type === 'system' ? '系统更新通知' : '其他通知'} + : {getNoticeTypeText(noticeDetail.columnType)}
diff --git a/src/servers/api/download.ts b/src/servers/api/download.ts new file mode 100644 index 0000000..ce95f33 --- /dev/null +++ b/src/servers/api/download.ts @@ -0,0 +1,103 @@ +import request from '@/utils/request'; + +// 下载中心列表请求参数类型 +export type DownloadListParams = { + pageNo: string; + pageSize: string; +}; + +// 下载项记录类型 +export type DownloadRecord = { + pageNo: null; + pageSize: null; + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: null; + lastUpdateTime: string; + id: string; + columnType: string; + name: string; + isBold: string; + keywords: string; + thumbnail: string; + fileName: string; + fileType: string; + fileSize: string; + filePath: string; + fileUrl: string; + isTop: string; + status: string; + publishBy: string; + publishTime: string; + delFlag: string; + statusText: string; +}; + +// 下载中心列表响应类型 +export type DownloadListResponse = { + records: DownloadRecord[]; + total: number; + size: number; + current: number; + orders: string[]; + optimizeCountSql: boolean; + hitCount: boolean; + countId: null; + maxLimit: null; + searchCount: boolean; + pages: number; +}; + +// 下载中心详情请求参数类型 +export type DownloadDetailParams = { + id: string; +}; + +/** + * 获取下载中心列表 + * @param params 分页参数 + * @returns 下载中心列表数据 + */ +export async function getDownloadList(params: DownloadListParams) { + return request>('/homePage/getDownloadsPage', { + method: 'POST', + data: params, + }); +} + +/** + * 获取下载中心详情 + * @param id 下载项ID + * @returns 下载中心详情数据 + */ +export async function getDownloadDetail(id: string) { + return request>(`/homePage/getDownloadsInfo/${id}`, { + method: 'GET', + }); +} + +/** + * 下载文件 + * @param id 文件ID + * @param fileName 文件名称 + * @returns 文件下载结果 + */ +export async function downloadFile(id: string, fileName: string) { + const response = await request(`/homePage/downloadFile/${id}`, { + method: 'GET', + responseType: 'blob', + }); + + // 创建下载链接 + const url = window.URL.createObjectURL(new Blob([response])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', fileName); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + return response; +} diff --git a/src/servers/api/index.ts b/src/servers/api/index.ts new file mode 100644 index 0000000..4667f7c --- /dev/null +++ b/src/servers/api/index.ts @@ -0,0 +1,8 @@ +// 首页api + +import request from '@/utils/request'; +export async function getCoscoPortalsLinksClassification() { + return request>('/homePage/coscoPortalsLinksClassification/getAll', { + method: 'get', + }); +} diff --git a/src/servers/api/notice.ts b/src/servers/api/notice.ts new file mode 100644 index 0000000..3403773 --- /dev/null +++ b/src/servers/api/notice.ts @@ -0,0 +1,75 @@ +import request from '@/utils/request'; + +// 通知中心列表请求参数类型 +export type NoticeListParams = { + pageNo: string; + pageSize: string; +}; + +// 通知中心记录类型 +export type NoticeRecord = { + pageNo: null; + pageSize: null; + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: null; + lastUpdateTime: string; + id: string; + title: string; + titleEn: string; + content: string; + contentEn: string; + settingEn: string; + columnType: string; + publishBy: string; + publishTime: string; + isTop: string; + status: string; + delFlag: string; + statusText: string; +}; + +// 通知中心列表响应类型 +export type NoticeListResponse = { + records: NoticeRecord[]; + total: number; + size: number; + current: number; + orders: string[]; + optimizeCountSql: boolean; + hitCount: boolean; + countId: null; + maxLimit: null; + searchCount: boolean; + pages: number; +}; + +// 通知中心详情请求参数类型 +export type NoticeDetailParams = { + id: string; +}; + +/** + * 获取通知中心列表 + * @param params 分页参数 + * @returns 通知中心列表数据 + */ +export async function getNoticeList(params: NoticeListParams) { + return request>('/homePage/getNoticePage', { + method: 'POST', + data: params, + }); +} + +/** + * 获取通知中心详情 + * @param id 通知ID + * @returns 通知中心详情数据 + */ +export async function getNoticeDetail(id: string) { + return request>(`/homePage/getNoticeInfo/${id}`, { + method: 'GET', + }); +} diff --git a/src/servers/api/typings.d.ts b/src/servers/api/typings.d.ts index d6afb84..ff7fd20 100644 --- a/src/servers/api/typings.d.ts +++ b/src/servers/api/typings.d.ts @@ -6,6 +6,98 @@ declare namespace API { data: T; } + // 下载中心相关类型 + export type DownloadListParams = { + pageNo: string; + pageSize: string; + } + + export type DownloadRecord = { + pageNo: null; + pageSize: null; + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: null; + lastUpdateTime: string; + id: string; + columnType: string; + name: string; + isBold: string; + keywords: string; + thumbnail: string; + fileName: string; + fileType: string; + fileSize: string; + filePath: string; + fileUrl: string; + isTop: string; + status: string; + publishBy: string; + publishTime: string; + delFlag: string; + statusText: string; + } + + export type DownloadListResponse = { + records: DownloadRecord[]; + total: number; + size: number; + current: number; + orders: string[]; + optimizeCountSql: boolean; + hitCount: boolean; + countId: null; + maxLimit: null; + searchCount: boolean; + pages: number; + } + + // 通知中心相关类型 + export type NoticeListParams = { + pageNo: string; + pageSize: string; + } + + export type NoticeRecord = { + pageNo: null; + pageSize: null; + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: null; + lastUpdateTime: string; + id: string; + title: string; + titleEn: string; + content: string; + contentEn: string; + settingEn: string; + columnType: string; + publishBy: string; + publishTime: string; + isTop: string; + status: string; + delFlag: string; + statusText: string; + } + + export type NoticeListResponse = { + records: NoticeRecord[]; + total: number; + size: number; + current: number; + orders: string[]; + optimizeCountSql: boolean; + hitCount: boolean; + countId: null; + maxLimit: null; + searchCount: boolean; + pages: number; + } + export type RegisterRequest = { coscoSupplierBank: CoscoSupplierBank[]; coscoSupplierBase: CoscoSupplierBase; @@ -218,7 +310,6 @@ declare namespace API { title: string; type: string; userName: string; - [property: string]: any; } // 关于我们响应数据类型