diff --git a/config/router.config.ts b/config/router.config.ts index 9804ec2..abc2e93 100644 --- a/config/router.config.ts +++ b/config/router.config.ts @@ -79,7 +79,51 @@ export default [ path: '/friendLinkManage', component: '@/pages/friendLinkManage/friendLinkManage', }, - + { + name: 'supplierTemplateManage', + path: '/supplierTemplateManage', + component: '@/pages/supplierEvaluateManage/supplierTemplateManage/supplierTemplateManage', + }, + { + name: 'supplierTaskManage', + path: '/supplierTaskManage', + component: '@/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage', + }, + { + name: 'supplierEvaluateScore', + path: '/supplierEvaluateScore', + component: '@/pages/supplierEvaluateManage/supplierEvaluateScore/supplierEvaluateScore', + }, + { + name: 'supplierEvaluateResult', + path: '/supplierEvaluateResult', + component: '@/pages/supplierEvaluateManage/supplierEvaluateResult/supplierEvaluateResult', + }, + { + name: 'supplierEvaluateResultApproval', + path: '/supplierEvaluateResultApproval', + component: '@/pages/supplierEvaluateManage/supplierEvaluateResultApproval/supplierEvaluateResultApproval', + }, + { + name: 'supplierAnnualTemplateManage', + path: '/supplierAnnualTemplateManage', + component: '@/pages/supplierAnnualManage/supplierAnnualTemplateManage/supplierAnnualTemplateManage', + }, + { + name: 'supplierAnnualTaskManage', + path: '/supplierAnnualTaskManage', + component: '@/pages/supplierAnnualManage/supplierAnnualTaskManage/supplierAnnualTaskManage', + }, + { + name: 'supplierAnnualQuery', + path: '/supplierAnnualQuery', + component: '@/pages/supplierAnnualManage/supplierAnnualQuery/supplierAnnualQuery', + }, + { + name: 'supplierAnnualResult', + path: '/supplierAnnualResult', + component: '@/pages/supplierAnnualManage/supplierAnnualResult/supplierAnnualResult', + }, ] }, diff --git a/package.json b/package.json index f2bbe2c..0c3845e 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,8 @@ "description": "An out-of-box UI solution for enterprise applications", "scripts": { "start-dev": "cross-env UMI_UI=none UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi dev --port=3000", - "start-UAT": "cross-env NODE_OPTIONS=--openssl-legacy-provider UMI_UI=none UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi dev --port=3000", - "start-sim": "cross-env UMI_UI=none UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi dev --port=3000", "start-prod": "cross-env UMI_UI=none UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi dev --port=3000", "build-dev": "cross-env UMI_ENV=dev LOGIN_PATH=ebtp-frontend umi build", - "build-UAT": "cross-env UMI_ENV=UAT LOGIN_PATH=ebtp-frontend umi build", - "build-sim": "cross-env UMI_ENV=sim LOGIN_PATH=ebtp-frontend umi build", "build-prod": "cross-env UMI_ENV=prod LOGIN_PATH=prod/ebtp-frontend umi build", "analyze": "cross-env ANALYZE=1 umi build", "build": "umi build", diff --git a/src/dicts/supplierTaskDict.ts b/src/dicts/supplierTaskDict.ts new file mode 100644 index 0000000..331da2a --- /dev/null +++ b/src/dicts/supplierTaskDict.ts @@ -0,0 +1,32 @@ +// 任务状态枚举 +export enum TaskStatus { + DRAFT = '0', // 未开始 + PROCESSING = '1', // 进行中 + COMPLETED = '2', // 已结束 +} + +// 任务类型枚举 +export enum TaskType { + REGULAR = '1', // 常规评价 + SPECIAL = '2', // 专项评价 +} + +// 任务状态文本映射 +export const TaskStatusText = { + [TaskStatus.DRAFT]: '未开始', + [TaskStatus.PROCESSING]: '进行中', + [TaskStatus.COMPLETED]: '已结束', +}; + +// 任务状态颜色映射 +export const TaskStatusColor = { + [TaskStatus.DRAFT]: 'default', + [TaskStatus.PROCESSING]: 'processing', + [TaskStatus.COMPLETED]: 'success', +}; + +// 任务类型文本映射 +export const TaskTypeText = { + [TaskType.REGULAR]: '常规评价', + [TaskType.SPECIAL]: '专项评价', +}; diff --git a/src/layouts/SiderMenu.tsx b/src/layouts/SiderMenu.tsx index d7f8f36..aa2dfb4 100644 --- a/src/layouts/SiderMenu.tsx +++ b/src/layouts/SiderMenu.tsx @@ -92,6 +92,74 @@ const items: IMenuItem[] = [ }, ], }, + { + label: 'menu.供应商评价', + key: 'supplierEvaluateManage', + icon: 'icon-youqinglianjie', + children: [ + { + label: 'menu.模板管理', + key: 'supplierTemplateManage', + icon: 'icon-fenlei', + path: '/supplierTemplateManage', + }, + { + label: 'menu.任务管理', + key: 'supplierTaskManage', + icon: 'icon-liebiaomoshi', + path: '/supplierTaskManage', + }, + { + label: 'menu.评价打分', + key: 'supplierEvaluateScore', + icon: 'icon-liebiaomoshi', + path: '/supplierEvaluateScore', + }, + { + label: 'menu.评价结果', + key: 'supplierEvaluateResult', + icon: 'icon-liebiaomoshi', + path: '/supplierEvaluateResult', + }, + { + label: 'menu.评价结果审批', + key: 'supplierEvaluateResultApproval', + icon: 'icon-liebiaomoshi', + path: '/supplierEvaluateResultApproval', + }, + ], + }, + { + label: 'menu.供应商年审', + key: 'supplierAnnualManage', + icon: 'icon-youqinglianjie', + children: [ + { + label: 'menu.年审模板管理', + key: 'supplierAnnualTemplateManage', + icon: 'icon-fenlei', + path: '/supplierAnnualTemplateManage', + }, + { + label: 'menu.年审任务管理', + key: 'supplierAnnualTaskManage', + icon: 'icon-liebiaomoshi', + path: '/supplierAnnualTaskManage', + }, + { + label: 'menu.年度查询', + key: 'supplierAnnualQuery', + icon: 'icon-liebiaomoshi', + path: '/supplierAnnualQuery', + }, + { + label: 'menu.年审结果', + key: 'supplierAnnualResult', + icon: 'icon-liebiaomoshi', + path: '/supplierAnnualResult', + }, + ], + }, ]; const SiderMenu: React.FC = (props) => { diff --git a/src/locales/en-US/common.ts b/src/locales/en-US/common.ts index d879327..af39d55 100644 --- a/src/locales/en-US/common.ts +++ b/src/locales/en-US/common.ts @@ -13,6 +13,19 @@ export default { 'menu.友情链接管理': 'Friendly Links Management', 'menu.友情链接分类': 'Friendly Links Category', 'menu.友情链接列表': 'Friendly Links List', + // Supplier Evaluation Management + 'menu.供应商评价': 'Supplier Evaluation', + 'menu.模板管理': 'Template Management', + 'menu.任务管理': 'Task Management', + 'menu.评价打分': 'Evaluation Scoring', + 'menu.评价结果': 'Evaluation Results', + 'menu.评价结果审批': 'Results Approval', + // Supplier Annual Review Management + 'menu.供应商年审': 'Supplier Annual Review', + 'menu.年审模板管理': 'Review Template Management', + 'menu.年审任务管理': 'Review Task Management', + 'menu.年度查询': 'Annual Query', + 'menu.年审结果': 'Review Results', // Common Text "查看": "Info", diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index 1df02a3..0854aaf 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -13,6 +13,19 @@ export default { 'menu.友情链接管理': '友情链接管理', 'menu.友情链接分类': '友情链接分类', 'menu.友情链接列表': '友情链接列表', + // 供应商评价管理 + 'menu.供应商评价': '供应商评价', + 'menu.模板管理': '模板管理', + 'menu.任务管理': '任务管理', + 'menu.评价打分': '评价打分', + 'menu.评价结果': '评价结果', + 'menu.评价结果审批': '评价结果审批', + // 供应商年审管理 + 'menu.供应商年审': '供应商年审', + 'menu.年审模板管理': '年审模板管理', + 'menu.年审任务管理': '年审任务管理', + 'menu.年度查询': '年度查询', + 'menu.年审结果': '年审结果', // 通用文本 "查看": "查看", diff --git a/src/locales/zh-CN/userQuestion.ts b/src/locales/zh-CN/userQuestion.ts index 2a6c241..efe9a70 100644 --- a/src/locales/zh-CN/userQuestion.ts +++ b/src/locales/zh-CN/userQuestion.ts @@ -40,6 +40,9 @@ export default { 'userQuestion.confirmEdit': '确认保存修改', 'userQuestion.submitConfirmText': '确定要提交这个回答吗?提交后将变为已回答状态。', 'userQuestion.editConfirmText': '确定要保存对此回答的修改吗?', + 'userQuestion.all': '全部', + 'userQuestion.selectCategory': '请选择分类', + 'userQuestion.selectAnswerStatus': '请选择回答状态', // 问题分类选项 'questionCategory.biddingProcess': '招标流程', @@ -90,6 +93,9 @@ export default { 'readQuestion.batchDeleteSuccess': '批量删除成功', 'readQuestion.batchDeleteFailed': '批量删除失败', 'readQuestion.selectedCount': '已选择 {count} 项', + 'readQuestion.all': '全部', + 'readQuestion.selectCategory': '请选择分类', + 'readQuestion.selectAnswerStatus': '请选择回答状态', // 未阅问题页面 'unreadQuestion.title': '未阅问题管理', @@ -127,6 +133,8 @@ export default { 'unreadQuestion.batchDeleteSuccess': '批量删除成功', 'unreadQuestion.batchDeleteFailed': '批量删除失败', 'unreadQuestion.selectedCount': '已选择 {count} 项', + 'unreadQuestion.all': '全部', + 'unreadQuestion.selectCategory': '请选择分类', // 问题详情组件 'questionDetail.title': '标题', diff --git a/src/pages/helpManage/helpManage.less b/src/pages/helpManage/helpManage.less index 01fc169..dbc0109 100644 --- a/src/pages/helpManage/helpManage.less +++ b/src/pages/helpManage/helpManage.less @@ -17,48 +17,12 @@ } .common-container { - background: #fff; border-radius: 4px; - padding: 24px; min-height: calc(100vh - 144px); - .filter-action-row { - display: flex; - justify-content: space-between; - margin-bottom: 16px; - - .filter-form { - flex: 1; - display: flex; - flex-wrap: wrap; - gap: 8px; - } - - .filter-btns { - display: flex; - gap: 8px; - } - - .right-buttons { - display: flex; - align-items: center; - gap: 8px; - - .selected-count { - color: #ff4d4f; - font-size: 14px; - } - } - } - - .content-area { - margin-top: 16px; - } - :global { .ant-form-item { margin-bottom: 16px; } } } - \ No newline at end of file diff --git a/src/pages/supplierAnnualManage/supplierAnnualQuery/supplierAnnualQuery.tsx b/src/pages/supplierAnnualManage/supplierAnnualQuery/supplierAnnualQuery.tsx new file mode 100644 index 0000000..b029eab --- /dev/null +++ b/src/pages/supplierAnnualManage/supplierAnnualQuery/supplierAnnualQuery.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierAnnualQuery: React.FC = () => { + return ( + +
供应商年度查询模块
+
+ ); +}; + +export default SupplierAnnualQuery; diff --git a/src/pages/supplierAnnualManage/supplierAnnualResult/supplierAnnualResult.tsx b/src/pages/supplierAnnualManage/supplierAnnualResult/supplierAnnualResult.tsx new file mode 100644 index 0000000..3c6c1a8 --- /dev/null +++ b/src/pages/supplierAnnualManage/supplierAnnualResult/supplierAnnualResult.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierAnnualResult: React.FC = () => { + return ( + +
供应商年度结果模块
+
+ ); +}; + +export default SupplierAnnualResult; diff --git a/src/pages/supplierAnnualManage/supplierAnnualTaskManage/supplierAnnualTaskManage.tsx b/src/pages/supplierAnnualManage/supplierAnnualTaskManage/supplierAnnualTaskManage.tsx new file mode 100644 index 0000000..8c11536 --- /dev/null +++ b/src/pages/supplierAnnualManage/supplierAnnualTaskManage/supplierAnnualTaskManage.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierAnnualTaskManage: React.FC = () => { + return ( + +
供应商年度任务管理模块
+
+ ); +}; + +export default SupplierAnnualTaskManage; diff --git a/src/pages/supplierAnnualManage/supplierAnnualTemplateManage/supplierAnnualTemplateManage.tsx b/src/pages/supplierAnnualManage/supplierAnnualTemplateManage/supplierAnnualTemplateManage.tsx new file mode 100644 index 0000000..e8fcaa8 --- /dev/null +++ b/src/pages/supplierAnnualManage/supplierAnnualTemplateManage/supplierAnnualTemplateManage.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierAnnualTemplateManage: React.FC = () => { + return ( + +
供应商年度模板管理模块
+
+ ); +}; + +export default SupplierAnnualTemplateManage; diff --git a/src/pages/supplierEvaluateManage/supplierEvaluateResult/supplierEvaluateResult.tsx b/src/pages/supplierEvaluateManage/supplierEvaluateResult/supplierEvaluateResult.tsx new file mode 100644 index 0000000..8934dac --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierEvaluateResult/supplierEvaluateResult.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierEvaluateResult: React.FC = () => { + return ( + +
供应商评价结果模块
+
+ ); +}; + +export default SupplierEvaluateResult; diff --git a/src/pages/supplierEvaluateManage/supplierEvaluateResultApproval/supplierEvaluateResultApproval.tsx b/src/pages/supplierEvaluateManage/supplierEvaluateResultApproval/supplierEvaluateResultApproval.tsx new file mode 100644 index 0000000..e7ae805 --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierEvaluateResultApproval/supplierEvaluateResultApproval.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierEvaluateResultApproval: React.FC = () => { + return ( + +
供应商评价结果审批模块
+
+ ); +}; + +export default SupplierEvaluateResultApproval; diff --git a/src/pages/supplierEvaluateManage/supplierEvaluateScore/supplierEvaluateScore.tsx b/src/pages/supplierEvaluateManage/supplierEvaluateScore/supplierEvaluateScore.tsx new file mode 100644 index 0000000..b74f2f6 --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierEvaluateScore/supplierEvaluateScore.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierEvaluateScore: React.FC = () => { + return ( + +
供应商评价打分模块
+
+ ); +}; + +export default SupplierEvaluateScore; diff --git a/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.less b/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.less new file mode 100644 index 0000000..20c7908 --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.less @@ -0,0 +1,23 @@ + +.supplier-task-manage-container { + // 使用公共容器样式,不需要重复定义padding和background-color + + .task-detail { + padding: 16px; + + .detail-item { + margin-bottom: 16px; + line-height: 22px; + + .label { + font-weight: bold; + margin-right: 8px; + color: #666; + } + + .content { + color: #333; + } + } + } +} diff --git a/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.tsx b/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.tsx new file mode 100644 index 0000000..a0ff989 --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierTaskManage/supplierTaskManage.tsx @@ -0,0 +1,623 @@ +import React, { useState, useEffect } from 'react'; +import { + Button, + Table, + Space, + Modal, + message, + Input, + Select, + Form, + Tooltip, + Tag, + TablePaginationConfig, + DatePicker, + Row, + Col, +} from 'antd'; +import { + PlusOutlined, + DeleteOutlined, + ExclamationCircleOutlined, + SearchOutlined, + EditOutlined, + EyeOutlined, +} from '@ant-design/icons'; +import { TaskStatus, TaskType, TaskStatusText, TaskStatusColor, TaskTypeText } from '@/dicts/supplierTaskDict'; +import './supplierTaskManage.less'; + +const { Option } = Select; +const { RangePicker } = DatePicker; + +// 任务记录类型 +interface TaskRecord { + id: string; + taskName: string; + taskCode: string; + taskType: string; + templateName: string; + status: string; + startTime: string; + endTime: string; + createBy: string; + createTime: string; + updateBy?: string; + updateTime?: string; + key: string; +} + +interface SearchParams { + taskName?: string; + status?: string; + dateRange?: [string, string]; +} + +const SupplierTaskManage: React.FC = () => { + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [loading, setLoading] = useState(false); + const [form] = Form.useForm(); + const [modalVisible, setModalVisible] = useState(false); + const [isEdit, setIsEdit] = useState(false); + const [isViewMode, setIsViewMode] = useState(false); + const [currentId, setCurrentId] = useState(''); + + // 查看详情数据 + const [viewData, setViewData] = useState(null); + const [taskData, setTaskData] = useState([]); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 10, + total: 0, + showSizeChanger: true, + showQuickJumper: true, + showTotal: (total) => `共 ${total} 条记录`, + }); + const [searchParams, setSearchParams] = useState({}); + + // 模拟获取任务列表 + const fetchTaskList = async ( + current = 1, + pageSize = 10, + params: SearchParams = searchParams, + ) => { + // 更新搜索参数状态 + if (params !== searchParams) { + setSearchParams(params); + } + + setLoading(true); + try { + // 模拟API请求 + setTimeout(() => { + // 模拟数据 + const mockData: TaskRecord[] = Array.from({ length: 35 }).map((_, index) => { + const id = `${index + 1}`; + const status = Object.values(TaskStatus)[Math.floor(Math.random() * 3)]; + const taskType = Math.random() > 0.5 ? TaskType.REGULAR : TaskType.SPECIAL; + + // 生成随机单位名称 + const units = ['中山市合创展包装材料有限公司', '广州市科技发展有限公司', '深圳市创新科技有限公司', '东莞市制造业有限公司']; + const unitIndex = Math.floor(Math.random() * units.length); + + return { + id, + key: id, + taskName: `供应商评价任务${index + 1}`, + taskCode: `TASK${String(index + 1).padStart(4, '0')}`, + taskType, + templateName: `${TaskTypeText[taskType]}模板${Math.floor(Math.random() * 5) + 1}`, + status, + startTime: '2023-01-01', + endTime: '2023-12-31', + createBy: units[unitIndex], + createTime: '2023-01-01 12:00:00', + }; + }); + + // 根据搜索条件过滤 + let filteredData = [...mockData]; + if (params.taskName) { + filteredData = filteredData.filter(item => + item.taskName.includes(params.taskName || '') + ); + } + if (params.status) { + filteredData = filteredData.filter(item => + item.status === params.status + ); + } + + // 分页 + const startIndex = (current - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedData = filteredData.slice(startIndex, endIndex); + + setTaskData(paginatedData); + setPagination({ + ...pagination, + current, + pageSize, + total: filteredData.length, + }); + + setLoading(false); + }, 500); + } catch (error) { + console.error('获取任务列表失败:', error); + message.error('获取任务列表失败'); + setLoading(false); + } + }; + + // 首次加载获取数据 + useEffect(() => { + fetchTaskList(pagination.current, pagination.pageSize, {}); + }, []); + + // 处理查看 + const handleView = (record: TaskRecord) => { + setCurrentId(record.id); + setIsViewMode(true); + setViewData(record); + setModalVisible(true); + }; + + // 处理编辑 + const handleEdit = (record: TaskRecord) => { + setIsEdit(true); + setIsViewMode(false); + setCurrentId(record.id); + setViewData(record); + setModalVisible(true); + }; + + // 处理删除 + const showDeleteConfirm = (record: TaskRecord) => { + Modal.confirm({ + title: '确认删除', + icon: , + content: `确定要删除任务: ${record.taskName}?`, + okText: '确定', + okType: 'danger', + cancelText: '取消', + maskClosable: false, + onOk: async () => { + try { + // 模拟删除请求 + setTimeout(() => { + message.success('删除成功'); + fetchTaskList(pagination.current, pagination.pageSize, searchParams); + }, 500); + } catch (error) { + console.error('删除任务失败:', error); + message.error('删除任务失败'); + } + }, + }); + }; + + // 处理发布/取消 + const handlePublishStatus = (record: TaskRecord) => { + const isInProgress = record.status === TaskStatus.PROCESSING; + const actionText = isInProgress ? '取消' : '开始'; + + Modal.confirm({ + title: `确认${actionText}`, + icon: , + content: `确定要${actionText}任务: ${record.taskName}?`, + okText: '确定', + cancelText: '取消', + maskClosable: false, + onOk: async () => { + try { + // 模拟请求 + setTimeout(() => { + message.success(`${actionText}成功`); + fetchTaskList(pagination.current, pagination.pageSize, searchParams); + }, 500); + } catch (error) { + console.error(`${actionText}失败:`, error); + message.error(`${actionText}失败`); + } + }, + }); + }; + + // 获取状态标签 + const getStatusTag = (status: string) => { + const color = TaskStatusColor[status as keyof typeof TaskStatusColor] || 'default'; + const text = TaskStatusText[status as keyof typeof TaskStatusText] || '未知状态'; + return {text}; + }; + + // 处理表格分页变化 + const handleTableChange = (newPagination: TablePaginationConfig) => { + fetchTaskList(newPagination.current, newPagination.pageSize, searchParams); + }; + + const columns = [ + { + title: '序号', + render: (_: any, __: TaskRecord, index: number) => + (pagination.current! - 1) * pagination.pageSize! + index + 1, + width: 80, + }, + { + title: '评价主题', + dataIndex: 'taskName', + key: 'taskName', + width: 200, + ellipsis: { + showTitle: false, + }, + render: (taskName: string) => ( + + {taskName} + + ), + }, + { + title: '发起单位', + dataIndex: 'createBy', + key: 'createBy', + width: 150, + }, + { + title: '评价开始时间', + dataIndex: 'startTime', + key: 'startTime', + width: 120, + }, + { + title: '评价结束时间', + dataIndex: 'endTime', + key: 'endTime', + width: 120, + }, + { + title: '评价状态', + dataIndex: 'status', + key: 'status', + width: 100, + render: (status: string) => getStatusTag(status), + }, + { + title: '操作', + key: 'action', + width: 180, + align: 'center' as const, + render: (_: unknown, record: TaskRecord) => ( + + + + + + ), + }, + ]; + + const onSelectChange = (newSelectedRowKeys: React.Key[]) => { + setSelectedRowKeys(newSelectedRowKeys); + }; + + const rowSelection = { + selectedRowKeys, + onChange: onSelectChange, + }; + + const hasSelected = selectedRowKeys.length > 0; + + // 处理添加 + const handleAdd = () => { + setIsEdit(false); + setIsViewMode(false); + setCurrentId(''); + setViewData(null); + setModalVisible(true); + }; + + // 处理批量删除 + const handleBatchDelete = () => { + Modal.confirm({ + title: '确认批量删除', + icon: , + content: '确定要删除选中的任务吗?此操作不可恢复。', + okText: '删除', + okType: 'danger', + cancelText: '取消', + maskClosable: false, + onOk: async () => { + setLoading(true); + try { + // 模拟批量删除 + setTimeout(() => { + setSelectedRowKeys([]); + message.success('批量删除成功'); + fetchTaskList(pagination.current, pagination.pageSize, searchParams); + setLoading(false); + }, 1000); + } catch (error) { + console.error('批量删除失败:', error); + message.error('批量删除失败'); + setLoading(false); + } + }, + }); + }; + + // 处理搜索 + const handleSearch = (values: any) => { + const { dateRange, ...rest } = values; + const params: SearchParams = { ...rest }; + + if (dateRange && dateRange.length === 2) { + params.dateRange = [dateRange[0].format('YYYY-MM-DD'), dateRange[1].format('YYYY-MM-DD')]; + } + + fetchTaskList(1, pagination.pageSize, params); + }; + + // 处理模态框取消 + const handleModalCancel = () => { + setModalVisible(false); + setIsViewMode(false); + setViewData(null); + }; + + // 渲染任务详情 + const renderTaskDetail = () => { + if (!viewData) return null; + + return ( +
+ + +
+ 任务名称: + {viewData.taskName} +
+ + +
+ 任务编号: + {viewData.taskCode} +
+ + +
+ 任务类型: + + {TaskTypeText[viewData.taskType as keyof typeof TaskTypeText] || '未知类型'} + +
+ + +
+ 使用模板: + {viewData.templateName} +
+ + +
+ 状态: + {getStatusTag(viewData.status)} +
+ + +
+ 开始时间: + {viewData.startTime} +
+ + +
+ 结束时间: + {viewData.endTime} +
+ + +
+ 创建人: + {viewData.createBy} +
+ + +
+ 创建时间: + {viewData.createTime} +
+ + {viewData.updateBy && ( + +
+ 更新人: + {viewData.updateBy} +
+ + )} + {viewData.updateTime && ( + +
+ 更新时间: + {viewData.updateTime} +
+ + )} +
+
+ ); + }; + + // 渲染任务表单 + const renderTaskForm = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ ); + }; + + return ( +
+
+
+ + + + + + + + + +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ + + + {/* 新增/编辑/查看模态框 */} + + 关闭 + , + ] + : null + } + > + {isViewMode ? renderTaskDetail() : renderTaskForm()} + + + ); +}; + +export default SupplierTaskManage; diff --git a/src/pages/supplierEvaluateManage/supplierTemplateManage/supplierTemplateManage.tsx b/src/pages/supplierEvaluateManage/supplierTemplateManage/supplierTemplateManage.tsx new file mode 100644 index 0000000..a9b97a5 --- /dev/null +++ b/src/pages/supplierEvaluateManage/supplierTemplateManage/supplierTemplateManage.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Card } from 'antd'; + +const SupplierTemplateManage: React.FC = () => { + return ( + +
供应商评价模板管理模块
+
+ ); +}; + +export default SupplierTemplateManage; diff --git a/src/pages/userQuestionManage/readQuestionManage.tsx b/src/pages/userQuestionManage/readQuestionManage.tsx index e74d375..31f2fb7 100644 --- a/src/pages/userQuestionManage/readQuestionManage.tsx +++ b/src/pages/userQuestionManage/readQuestionManage.tsx @@ -401,12 +401,12 @@ const ReadQuestionManage: React.FC = () => { - {getCategoryOptions()} - diff --git a/src/pages/userQuestionManage/unreadQuestionManage.tsx b/src/pages/userQuestionManage/unreadQuestionManage.tsx index d27dc5b..5ed9494 100644 --- a/src/pages/userQuestionManage/unreadQuestionManage.tsx +++ b/src/pages/userQuestionManage/unreadQuestionManage.tsx @@ -89,8 +89,8 @@ const UnreadQuestionManage: React.FC = () => { })); setQuestionData(formattedData); - setPagination({ - ...pagination, + setPagination({ + ...pagination, current: currentPage, pageSize: size, total, @@ -102,7 +102,7 @@ const UnreadQuestionManage: React.FC = () => { console.error('获取问题列表失败:', error); message.error(intl.formatMessage({ id: 'unreadQuestion.fetchFailed' })); } finally { - setLoading(false); + setLoading(false); } }; @@ -124,8 +124,8 @@ const UnreadQuestionManage: React.FC = () => { const response = await markQuestionSeeEdit(record.id); if (!response || !response.success) { message.error(response?.message || intl.formatMessage({ id: 'userQuestion.replyFailed' })); - return; - } + return; + } // 获取问题详情 const detailResponse = await getQuestionDetail(record.id); @@ -327,7 +327,7 @@ const UnreadQuestionManage: React.FC = () => { + @@ -351,7 +351,7 @@ const UnreadQuestionManage: React.FC = () => { diff --git a/src/pages/userQuestionManage/userQuestionManage.less b/src/pages/userQuestionManage/userQuestionManage.less index 6cea128..39e3f03 100644 --- a/src/pages/userQuestionManage/userQuestionManage.less +++ b/src/pages/userQuestionManage/userQuestionManage.less @@ -1,240 +1,9 @@ +// 扩展公共容器样式 .common-container { - padding: 24px; - background-color: #fff; border-radius: 2px; min-height: calc(100vh - 184px); - .filter-action-row { - display: flex; - justify-content: space-between; - margin-bottom: 16px; - - .filter-form { - flex: 1; - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-bottom: 16px; - - .filter-btns { - margin-right: 0; - - button { - margin-left: 8px; - } - } - } - - .right-buttons { - display: flex; - align-items: center; - - button { - margin-left: 8px; - } - - .selected-count { - margin-left: 8px; - color: rgba(0, 0, 0, 0.45); - } - } - } - - .content-area { - margin-top: 16px; - } - - .card-container { - display: flex; - flex-wrap: wrap; - gap: 24px; - margin-top: 24px; - - .stat-card { - width: calc(25% - 18px); - min-width: 250px; - height: 120px; - border-radius: 8px; - padding: 16px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); - display: flex; - flex-direction: column; - justify-content: space-between; - cursor: pointer; - transition: all 0.3s; - - &:hover { - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); - transform: translateY(-2px); - } - - .card-title { - font-size: 16px; - color: rgba(0, 0, 0, 0.85); - margin-bottom: 8px; - } - - .card-value { - font-size: 28px; - font-weight: bold; - color: #1890ff; - } - - .card-footer { - display: flex; - justify-content: space-between; - align-items: center; - margin-top: 8px; - - .card-label { - font-size: 14px; - color: rgba(0, 0, 0, 0.45); - } - } - } - } - - // 问题详情样式 - .question-detail-header { - margin-bottom: 24px; - border-bottom: 1px solid #f0f0f0; - padding-bottom: 16px; - - h2 { - margin-bottom: 8px; - font-size: 18px; - font-weight: 500; - } - - .question-meta { - display: flex; - flex-wrap: wrap; - - span { - margin-right: 16px; - color: rgba(0, 0, 0, 0.65); - } - } - } - - .question-detail-section { - margin-bottom: 24px; - - h3 { - margin-bottom: 8px; - font-size: 16px; - font-weight: 500; - } - - .question-detail-content { - padding: 16px; - background-color: #f5f5f5; - border-radius: 4px; - white-space: pre-wrap; - word-break: break-all; - } - - .answer-content-wrapper { - border: 1px solid #f0f0f0; - border-radius: 4px; - padding: 16px; - min-height: 200px; - - .answer-content { - line-height: 1.6; - - p { - margin-bottom: 12px; - } - - ul, ol { - padding-left: 20px; - margin-bottom: 12px; - } - } - } - } - - .question-detail-footer { - margin-top: 16px; - padding-top: 16px; - border-top: 1px solid #f0f0f0; - - .question-settings { - display: flex; - margin-bottom: 16px; - - .setting-item { - display: flex; - align-items: center; - margin-right: 24px; - - span { - margin-right: 8px; - } - - .switch-wrapper { - display: flex; - align-items: center; - - .status-indicator { - width: 8px; - height: 8px; - border-radius: 50%; - margin-right: 4px; - - &.published { - background-color: #52c41a; - } - - &.unpublished { - background-color: #faad14; - } - - &.top { - background-color: #f5222d; - } - - &.not-top { - background-color: #d9d9d9; - } - } - } - } - } - - .answer-info { - display: flex; - - span { - margin-right: 16px; - color: rgba(0, 0, 0, 0.45); - } - } - } - - .answer-form-container { - margin-bottom: 24px; - - .question-settings { - display: flex; - margin-top: 16px; - - .ant-form-item { - margin-right: 24px; - } - } - - .answer-content { - min-height: 100px; - } - } - - :global { - .ant-form-item { - margin-bottom: 16px; - } - } + // 这里只保留与公共样式不同的部分 } // 问题查看容器 @@ -253,6 +22,193 @@ } } +// 卡片容器样式 +.card-container { + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 24px; + + .stat-card { + width: calc(25% - 18px); + min-width: 250px; + height: 120px; + border-radius: 8px; + padding: 16px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09); + display: flex; + flex-direction: column; + justify-content: space-between; + cursor: pointer; + transition: all 0.3s; + + &:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); + transform: translateY(-2px); + } + + .card-title { + font-size: 16px; + color: rgba(0, 0, 0, 0.85); + margin-bottom: 8px; + } + + .card-value { + font-size: 28px; + font-weight: bold; + color: #1890ff; + } + + .card-footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + + .card-label { + font-size: 14px; + color: rgba(0, 0, 0, 0.45); + } + } + } +} + +// 问题详情样式 +.question-detail-header { + margin-bottom: 24px; + border-bottom: 1px solid #f0f0f0; + padding-bottom: 16px; + + h2 { + margin-bottom: 8px; + font-size: 18px; + font-weight: 500; + } + + .question-meta { + display: flex; + flex-wrap: wrap; + + span { + margin-right: 16px; + color: rgba(0, 0, 0, 0.65); + } + } +} + +.question-detail-section { + margin-bottom: 24px; + + h3 { + margin-bottom: 8px; + font-size: 16px; + font-weight: 500; + } + + .question-detail-content { + padding: 16px; + background-color: #f5f5f5; + border-radius: 4px; + white-space: pre-wrap; + word-break: break-all; + } + + .answer-content-wrapper { + border: 1px solid #f0f0f0; + border-radius: 4px; + padding: 16px; + min-height: 200px; + + .answer-content { + line-height: 1.6; + + p { + margin-bottom: 12px; + } + + ul, ol { + padding-left: 20px; + margin-bottom: 12px; + } + } + } +} + +.question-detail-footer { + margin-top: 16px; + padding-top: 16px; + border-top: 1px solid #f0f0f0; + + .question-settings { + display: flex; + margin-bottom: 16px; + + .setting-item { + display: flex; + align-items: center; + margin-right: 24px; + + span { + margin-right: 8px; + } + + .switch-wrapper { + display: flex; + align-items: center; + + .status-indicator { + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 4px; + + &.published { + background-color: #52c41a; + } + + &.unpublished { + background-color: #faad14; + } + + &.top { + background-color: #f5222d; + } + + &.not-top { + background-color: #d9d9d9; + } + } + } + } + } + + .answer-info { + display: flex; + + span { + margin-right: 16px; + color: rgba(0, 0, 0, 0.45); + } + } +} + +.answer-form-container { + margin-bottom: 24px; + + .question-settings { + display: flex; + margin-top: 16px; + + .ant-form-item { + margin-right: 24px; + } + } + + .answer-content { + min-height: 100px; + } +} + // 新增问题详情查看样式 .question-detail-view { .ant-descriptions { diff --git a/src/servers/api/typings.d.ts b/src/servers/api/typings.d.ts index 5108702..000981d 100644 --- a/src/servers/api/typings.d.ts +++ b/src/servers/api/typings.d.ts @@ -506,4 +506,56 @@ declare namespace API { remark?: string; basePageRequest?: null; } + + // 供应商评价任务状态枚举 + export enum TaskStatus { + DRAFT = '0', // 草稿 + PUBLISHED = '1', // 已发布 + PROCESSING = '2', // 进行中 + COMPLETED = '3', // 已完成 + CANCELED = '4', // 已取消 + } + + // 供应商评价任务类型枚举 + export enum TaskType { + REGULAR = '1', // 常规评价 + SPECIAL = '2', // 专项评价 + } + + // 供应商评价任务记录类型 + export interface TaskRecord { + id: string; + taskName: string; + taskCode: string; + taskType: string; + templateName: string; + status: string; + startTime: string; + endTime: string; + createBy: string; + createTime: string; + updateBy?: string; + updateTime?: string; + key?: string; + } + + // 供应商评价任务查询参数 + export interface TaskSearchParams { + taskName?: string; + taskCode?: string; + taskType?: string; + status?: string; + dateRange?: [string, string]; + } + + // 供应商评价任务请求参数 + export interface TaskRequest { + id?: string; + taskName: string; + taskCode: string; + taskType: string; + templateId: string; + startTime: string; + endTime: string; + } } diff --git a/src/utils/componentStyle.less b/src/utils/componentStyle.less index 2a3310b..822bc6d 100644 --- a/src/utils/componentStyle.less +++ b/src/utils/componentStyle.less @@ -48,6 +48,11 @@ .filter-form { flex: 1; + display: flex; + flex-wrap: wrap; + gap: 10px; + max-width: 100%; + .filter-btns { button { margin-right: 8px; @@ -71,3 +76,34 @@ } } } + +// 按钮行样式 - 用于搜索按钮和操作按钮的两端对齐 +.button-row { + display: flex; + justify-content: space-between; + margin-bottom: 15px; + + .left-buttons { + display: flex; + gap: 8px; + } + + .right-buttons { + display: flex; + gap: 8px; + align-items: center; + } +} + +// 响应式调整 +@media screen and (max-width: 768px) { + .button-row { + flex-direction: column; + gap: 16px; + + .left-buttons, .right-buttons { + width: 100%; + justify-content: flex-start; + } + } +}