任务修改回显

This commit is contained in:
linxd
2025-06-26 12:06:47 +08:00
parent 09c67189b5
commit 4ec07e3633
12 changed files with 598 additions and 255 deletions

View File

@ -30,3 +30,9 @@ export const TaskTypeText = {
[TaskType.REGULAR]: '常规评价', [TaskType.REGULAR]: '常规评价',
[TaskType.SPECIAL]: '专项评价', [TaskType.SPECIAL]: '专项评价',
}; };
// 任务是否通知下级单位完善评价人及评价分工
export enum TaskNotifyLowerUnits {
NO = 0,
YES = 1,
}

View File

@ -5,12 +5,13 @@ import { getAllTemplates } from '@/servers/api/supplierEvaluate';
import CategorySelector from '@/components/CategorySelector'; import CategorySelector from '@/components/CategorySelector';
import styles from '../supplierTaskManageAdd.less'; import styles from '../supplierTaskManageAdd.less';
import { CategoryLimitationType } from '@/dicts/supplierTemplateDict'; import { CategoryLimitationType } from '@/dicts/supplierTemplateDict';
import type { TaskAddRequest } from '@/servers/types/supplierEvaluateTask';
const { Option } = Select; const { Option } = Select;
interface BasicInfoStepProps { interface BasicInfoStepProps {
formData: Partial<SupplierEvaluate.TaskAddRequest>; formData: Partial<TaskAddRequest>;
onFormDataChange: (data: Partial<SupplierEvaluate.TaskAddRequest>) => void; onFormDataChange: (data: TaskAddRequest) => void;
} }
interface TemplateItem { interface TemplateItem {

View File

@ -1,10 +1,32 @@
import React, { useState, useEffect, forwardRef, useImperativeHandle, useMemo, useCallback } from 'react'; import React, {
import { Card, Table, Tag, Switch, Space, Button, message, Modal, Radio, Checkbox, Row, Col, Spin } from 'antd'; useState,
useEffect,
forwardRef,
useImperativeHandle,
useMemo,
useCallback,
useRef,
} from 'react';
import {
Card,
Table,
Tag,
Switch,
Space,
Button,
message,
Modal,
Radio,
Checkbox,
Row,
Col,
Spin,
} from 'antd';
import type { PersonnelItem } from '@/servers/types/evaluator'; import type { PersonnelItem } from '@/servers/types/evaluator';
import type { ColumnsType } from 'antd/es/table'; import type { ColumnsType } from 'antd/es/table';
import type { CheckboxValueType } from 'antd/es/checkbox/Group';
import EvaluateTemplateTable from '@/components/EvaluateTemplateTable'; import EvaluateTemplateTable from '@/components/EvaluateTemplateTable';
import { getTemplateDetail } from '@/servers/api/supplierEvaluate'; import { getTemplateDetail } from '@/servers/api/supplierEvaluate';
import type { TaskAddRequest } from '@/servers/types/supplierEvaluateTask';
// 评价指标类型定义 // 评价指标类型定义
interface IndicatorItem { interface IndicatorItem {
@ -15,8 +37,8 @@ interface IndicatorItem {
// 组件接收的Props定义 // 组件接收的Props定义
interface DivisionStepProps { interface DivisionStepProps {
formData: any; formData: Partial<TaskAddRequest>;
onFormDataChange?: (values: any) => void; onFormDataChange?: (values: Partial<TaskAddRequest>) => void;
} }
// 评价方式枚举 // 评价方式枚举
@ -27,26 +49,23 @@ enum EvaluateType {
INDICATOR = 1, // 按指标评价(部分指标) INDICATOR = 1, // 按指标评价(部分指标)
} }
// 模拟的评价指标数据 - 仅作为备用
const mockIndicators: IndicatorItem[] = [
{ id: 'I001', name: '产品质量', description: '评估供应商产品质量' },
{ id: 'I002', name: '交货及时性', description: '评估供应商交货的及时性' },
{ id: 'I003', name: '服务水平', description: '评估供应商提供的服务水平' },
{ id: 'I004', name: '价格竞争力', description: '评估供应商产品价格的竞争力' },
{ id: 'I005', name: '技术能力', description: '评估供应商的技术创新能力' },
];
const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataChange }, ref) => { const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataChange }, ref) => {
// 从上一步获取的评价人员列表 // 从上一步获取的评价人员列表
const [evaluators, setEvaluators] = useState<PersonnelItem[]>([]); const [evaluators, setEvaluators] = useState<PersonnelItem[]>([]);
// 评价人员指标分配数据 // 评价人员指标分配数据
const [indicatorAssignments, setIndicatorAssignments] = useState<{ const indicatorAssignments = useRef<{
[userId: string]: { [userId: string]: {
type: EvaluateType; type: EvaluateType;
indicatorIds: string[]; indicatorIds: string[];
}; };
}>({}); }>({});
// const [indicatorAssignments, setIndicatorAssignments] = useState<{
// [userId: string]: {
// type: EvaluateType;
// indicatorIds: string[];
// };
// }>({});
// 选中的行keys // 选中的行keys
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
@ -78,8 +97,66 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 选中的指标项 // 选中的指标项
const [selectedTemplateItems, setSelectedTemplateItems] = useState<any[]>([]); const [selectedTemplateItems, setSelectedTemplateItems] = useState<any[]>([]);
// 查看指标分工弹窗可见性
const [viewModalVisible, setViewModalVisible] = useState(false);
// 查看模式下的过滤后指标数据
const [filteredIndicators, setFilteredIndicators] = useState<any[]>([]);
// 统一获取用户指标ID的函数
const getUserIndicatorIds = useCallback((userId: string) => {
if (!userId) return [];
const assignment = indicatorAssignments.current[userId];
if (!assignment) return [];
// 如果是按评价单评价(全部指标),返回空数组
if (assignment.type == EvaluateType.ALL) {
return [];
}
// 如果是按指标评价返回指标ID列表
return assignment.indicatorIds || [];
}, []);
// 获取当前用户的已分配指标ID
const getCurrentUserSelectedIds = useCallback(() => {
// 使用统一的getUserIndicatorIds函数获取当前用户的指标ID
return getUserIndicatorIds(currentUserId);
}, [currentUserId, getUserIndicatorIds]);
// 根据指标ID过滤模板数据
const filterTemplateDataByIds = useCallback((data: any[], indicatorIds: string[]) => {
// 如果indicatorIds为空表示显示所有模板数据(按评价单评价)
if (!indicatorIds || indicatorIds.length === 0) {
return data;
}
// 按指标ID过滤
const filtered = [];
for (const stItem of data) {
const ndItems = [];
if (stItem.indicatorNdList) {
for (const ndItem of stItem.indicatorNdList) {
const matched = indicatorIds.some((id) => String(id) === String(ndItem.id));
if (matched) {
ndItems.push(ndItem);
}
}
}
if (ndItems.length > 0) {
filtered.push({
...stItem,
indicatorNdList: ndItems,
});
}
}
return filtered;
}, []);
// 获取模板详情 先写死 "1937123786334322688" 省的一步一步操作 // 获取模板详情 先写死 "1937123786334322688" 省的一步一步操作
const fetchTemplateDetail = async (templateId: string = "1937123786334322688") => { const fetchTemplateDetail = async (templateId: string) => {
if (!templateId) return; if (!templateId) return;
try { try {
@ -113,7 +190,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 监听templateId变化获取模板详情 // 监听templateId变化获取模板详情
useEffect(() => { useEffect(() => {
fetchTemplateDetail(formData.templateId); fetchTemplateDetail(formData.templateId as string);
}, []); }, []);
// 处理行选择变化 // 处理行选择变化
@ -147,15 +224,15 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 批量设置指标分工 // 批量设置指标分工
const handleBatchSetDivision = () => { const handleBatchSetDivision = () => {
// 获取选中的评价人员 // 获取选中的评价人员
const selectedEvaluators = evaluators.filter( const selectedEvaluators = evaluators.filter((evaluator) =>
evaluator => selectedRowKeys.includes(evaluator.id) selectedRowKeys.includes(evaluator.id),
); );
// 提取所有选中指标的ID // 提取所有选中指标的ID
const selectedIndicatorIds: string[] = []; const selectedIndicatorIds: string[] = [];
// 从选中的模板项中提取所有指标ID // 从选中的模板项中提取所有指标ID
batchSelectedTemplateItems.forEach(stItem => { batchSelectedTemplateItems.forEach((stItem) => {
// 添加二级指标ID // 添加二级指标ID
if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) { if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) {
stItem.indicatorNdList.forEach((ndItem: any) => { stItem.indicatorNdList.forEach((ndItem: any) => {
@ -165,9 +242,9 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
}); });
// 更新指标分配数据 // 更新指标分配数据
const newAssignments = { ...indicatorAssignments }; const newAssignments = { ...indicatorAssignments.current };
selectedEvaluators.forEach(evaluator => { selectedEvaluators.forEach((evaluator) => {
newAssignments[evaluator.id] = { newAssignments[evaluator.id] = {
// 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单) // 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单)
type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL, type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL,
@ -175,7 +252,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
}; };
}); });
setIndicatorAssignments(newAssignments); indicatorAssignments.current = newAssignments;
setBatchTemplateModalVisible(false); setBatchTemplateModalVisible(false);
message.success(`已为${selectedRowKeys.length}名评价人员设置分工`); message.success(`已为${selectedRowKeys.length}名评价人员设置分工`);
}; };
@ -197,23 +274,10 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 处理模板指标选择 // 处理模板指标选择
const handleTemplateItemsSelect = (selectedItems: any[]) => { const handleTemplateItemsSelect = (selectedItems: any[]) => {
console.log(selectedItems) console.log(selectedItems);
setSelectedTemplateItems(selectedItems); setSelectedTemplateItems(selectedItems);
}; };
// 获取当前用户的已分配指标ID
const getCurrentUserSelectedIds = useCallback(() => {
if (!currentUserId) return [];
const userAssignment = indicatorAssignments[currentUserId];
if (userAssignment && userAssignment.type === EvaluateType.INDICATOR) {
const selectedIds = userAssignment.indicatorIds || [];
return selectedIds;
}
return [];
}, [currentUserId, indicatorAssignments]);
// 保存指标分配 // 保存指标分配
const handleSaveIndicatorAssignment = () => { const handleSaveIndicatorAssignment = () => {
if (!currentUserId) { if (!currentUserId) {
@ -225,7 +289,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
const selectedIndicatorIds: string[] = []; const selectedIndicatorIds: string[] = [];
// 从选中的模板项中提取所有指标ID // 从选中的模板项中提取所有指标ID
selectedTemplateItems.forEach(stItem => { selectedTemplateItems.forEach((stItem) => {
// 添加二级指标ID // 添加二级指标ID
if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) { if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) {
stItem.indicatorNdList.forEach((ndItem: any) => { stItem.indicatorNdList.forEach((ndItem: any) => {
@ -235,46 +299,43 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
}); });
// 更新指标分配 // 更新指标分配
const newAssignments = { ...indicatorAssignments }; const newAssignments = { ...indicatorAssignments.current };
newAssignments[currentUserId] = { newAssignments[currentUserId] = {
// 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单) // 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单)
type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL, type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL,
indicatorIds: selectedIndicatorIds, indicatorIds: selectedIndicatorIds,
}; };
setIndicatorAssignments(newAssignments); indicatorAssignments.current = newAssignments;
setTemplateViewModalVisible(false); setTemplateViewModalVisible(false);
message.success('已设置评价人员指标分工'); message.success('已设置评价人员指标分工');
}; };
// 查看评价人员的指标分工 // 查看评价人员的指标分工
const handleViewAssignment = (userId: string) => { const handleViewAssignment = (userId: string) => {
const assignment = indicatorAssignments[userId]; const assignment = indicatorAssignments.current[userId];
if (!assignment) { if (!assignment) {
message.info('该评价人员尚未设置分工'); message.info('该评价人员尚未设置分工');
return; return;
} }
const assignedIndicators = indicators.filter(ind => setCurrentUserId(userId);
assignment.type === EvaluateType.ALL || setLoading(true);
assignment.indicatorIds.includes(ind.id)
);
Modal.info({ // 获取该评价人员的指标ID
title: '查看评价指标分工', const indicatorIds = getUserIndicatorIds(userId);
content: (
<div> // 过滤模板数据
<p>: {assignment.type === EvaluateType.ALL ? '按评价单评价' : '按指标评价'}</p> const filtered = filterTemplateDataByIds(templateData, indicatorIds);
<p>: </p> setFilteredIndicators(filtered);
<ul>
{assignedIndicators.map(ind => ( setLoading(false);
<li key={ind.id}>{ind.name}</li> setViewModalVisible(true);
))} };
</ul>
</div> // 关闭查看模态框
), const handleCloseViewModal = () => {
okText: '确定', setViewModalVisible(false);
});
}; };
// 删除评价人员 // 删除评价人员
@ -286,12 +347,12 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
cancelText: '取消', cancelText: '取消',
onOk: () => { onOk: () => {
// 更新评价人员列表 // 更新评价人员列表
setEvaluators(prev => prev.filter(e => e.id !== userId)); setEvaluators((prev) => prev.filter((e) => e.id !== userId));
// 更新指标分配数据 // 更新指标分配数据
const newAssignments = { ...indicatorAssignments }; const newAssignments = { ...indicatorAssignments.current };
delete newAssignments[userId]; delete newAssignments[userId];
setIndicatorAssignments(newAssignments); indicatorAssignments.current = newAssignments;
message.success('已删除评价人员'); message.success('已删除评价人员');
}, },
@ -300,7 +361,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 初始化从formData中提取指标分配数据 // 初始化从formData中提取指标分配数据
useEffect(() => { useEffect(() => {
if (formData.indicatorList) { if (formData.indicatorList && formData.indicatorList.length > 0) {
// 如果已有指标分配数据,直接使用 // 如果已有指标分配数据,直接使用
const assignments: any = {}; const assignments: any = {};
formData.indicatorList.forEach((item: any) => { formData.indicatorList.forEach((item: any) => {
@ -309,7 +370,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
indicatorIds: item.indicatorIds || [], indicatorIds: item.indicatorIds || [],
}; };
}); });
setIndicatorAssignments(assignments); indicatorAssignments.current = assignments;
} }
}, [formData.indicatorList]); }, [formData.indicatorList]);
@ -324,7 +385,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
if (supplier.evaluators && supplier.evaluators.length > 0) { if (supplier.evaluators && supplier.evaluators.length > 0) {
supplier.evaluators.forEach((evaluator: PersonnelItem) => { supplier.evaluators.forEach((evaluator: PersonnelItem) => {
// 检查是否已存在(避免重复) // 检查是否已存在(避免重复)
if (!allEvaluators.some(e => e.id === evaluator.id)) { if (!allEvaluators.some((e) => e.id === evaluator.id)) {
allEvaluators.push({ allEvaluators.push({
...evaluator, ...evaluator,
// 添加单位和员工编号,假设这些字段可能不存在 // 添加单位和员工编号,假设这些字段可能不存在
@ -343,11 +404,11 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 为评价人员初始化指标分配数据 - 作为单独的效果处理 // 为评价人员初始化指标分配数据 - 作为单独的效果处理
useEffect(() => { useEffect(() => {
// 检查是否有新的评价人员需要初始化 // 检查是否有新的评价人员需要初始化
const newAssignments = { ...indicatorAssignments }; const newAssignments = { ...indicatorAssignments.current };
let hasNewAssignments = false; let hasNewAssignments = false;
evaluators.forEach(evaluator => { evaluators.forEach((evaluator) => {
if (!indicatorAssignments[evaluator.id]) { if (!indicatorAssignments.current[evaluator.id]) {
newAssignments[evaluator.id] = { newAssignments[evaluator.id] = {
type: EvaluateType.ALL, type: EvaluateType.ALL,
indicatorIds: [], indicatorIds: [],
@ -355,22 +416,26 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
hasNewAssignments = true; hasNewAssignments = true;
} }
}); });
if (hasNewAssignments) { if (hasNewAssignments) {
setIndicatorAssignments(newAssignments); indicatorAssignments.current = newAssignments;
} }
}, [evaluators, indicatorAssignments]); }, [evaluators, indicatorAssignments]);
// 同步数据回表单 - 使用防抖确保不会频繁触发 // 同步数据回表单 - 使用防抖确保不会频繁触发
const previousValueRef = React.useRef<string>(""); const previousValueRef = React.useRef<string>('');
useEffect(() => { useEffect(() => {
// 若当前还未初始化完成(没有任何指标数据),不应向父组件同步
if (evaluators.length === 0 || Object.keys(indicatorAssignments.current).length === 0) {
return;
}
// 将评价人员列表和指标分配数据同步回表单 // 将评价人员列表和指标分配数据同步回表单
const indicatorList = evaluators.map(evaluator => ({ const indicatorList = evaluators.map((evaluator) => ({
userId: evaluator.id, userId: evaluator.id,
userName: evaluator.name, userName: evaluator.name,
type: indicatorAssignments[evaluator.id]?.type || EvaluateType.ALL, type: indicatorAssignments.current[evaluator.id]?.type ?? EvaluateType.ALL,
indicatorIds: indicatorAssignments[evaluator.id]?.indicatorIds || [], indicatorIds: indicatorAssignments.current[evaluator.id]?.indicatorIds ?? [],
})); }));
// 使用JSON字符串比较确保只有在真正变化时才更新 // 使用JSON字符串比较确保只有在真正变化时才更新
@ -382,7 +447,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
indicatorList, indicatorList,
}); });
} }
}, [evaluators, indicatorAssignments, formData, onFormDataChange]); }, [evaluators, formData, onFormDataChange]);
// 暴露给父组件的方法 // 暴露给父组件的方法
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
@ -397,6 +462,12 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
}, },
})); }));
// 获取当前评价人员名称
const getCurrentEvaluatorName = () => {
const evaluator = evaluators.find((e) => e.id === currentUserId);
return evaluator ? evaluator.name : currentUserId;
};
// 表格列定义 // 表格列定义
const columns: ColumnsType<PersonnelItem> = [ const columns: ColumnsType<PersonnelItem> = [
{ {
@ -404,27 +475,23 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
}, },
{
title: '所属单位',
dataIndex: 'company',
key: 'company',
},
{ {
title: '所属部门', title: '所属部门',
dataIndex: 'department', dataIndex: 'userDept',
key: 'department', key: 'userDept',
}, },
{ {
title: '员工编号', title: '员工编号',
dataIndex: 'employeeNumber', dataIndex: 'id',
key: 'employeeNumber', key: 'id',
}, },
{ {
title: '是否设置分工', title: '是否设置分工',
key: 'hasDivision', key: 'hasDivision',
render: (_: any, record: PersonnelItem) => { render: (_: any, record: PersonnelItem) => {
const assignment = indicatorAssignments[record.id]; const assignment = indicatorAssignments.current[record.id];
if (!assignment) return <Tag color="red"></Tag>; if (!assignment || assignment.indicatorIds.length === 0)
return <Tag color="red"></Tag>;
return <Tag color="green"></Tag>; return <Tag color="green"></Tag>;
}, },
}, },
@ -433,9 +500,15 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
key: 'action', key: 'action',
render: (_: any, record: PersonnelItem) => ( render: (_: any, record: PersonnelItem) => (
<Space size="middle"> <Space size="middle">
<Button type="link" onClick={() => handleAssignIndicators(record.id)}></Button> <Button type="link" onClick={() => handleAssignIndicators(record.id)}>
<Button type="link" onClick={() => handleViewAssignment(record.id)}></Button>
<Button type="link" onClick={() => handleRemoveEvaluator(record.id)}></Button> </Button>
<Button type="link" onClick={() => handleViewAssignment(record.id)}>
</Button>
<Button type="link" onClick={() => handleRemoveEvaluator(record.id)}>
</Button>
</Space> </Space>
), ),
}, },
@ -469,14 +542,14 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
title={`批量设置评价指标分工 (已选择 ${selectedRowKeys.length} 名评价人员)`} title={`批量设置评价指标分工 (已选择 ${selectedRowKeys.length} 名评价人员)`}
visible={batchTemplateModalVisible} visible={batchTemplateModalVisible}
onCancel={handleCloseBatchTemplateModal} onCancel={handleCloseBatchTemplateModal}
width={800} width={1200}
footer={[ footer={[
<Button key="cancel" onClick={handleCloseBatchTemplateModal}> <Button key="cancel" onClick={handleCloseBatchTemplateModal}>
</Button>, </Button>,
<Button key="save" type="primary" onClick={handleBatchSetDivision}> <Button key="save" type="primary" onClick={handleBatchSetDivision}>
</Button> </Button>,
]} ]}
> >
<Spin spinning={loading}> <Spin spinning={loading}>
@ -507,7 +580,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
</Button>, </Button>,
<Button key="save" type="primary" onClick={handleSaveIndicatorAssignment}> <Button key="save" type="primary" onClick={handleSaveIndicatorAssignment}>
</Button> </Button>,
]} ]}
> >
<Spin spinning={loading}> <Spin spinning={loading}>
@ -527,6 +600,29 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
)} )}
</Spin> </Spin>
</Modal> </Modal>
{/* 查看评价人员指标分工弹窗 */}
<Modal
title={`评价人员 ${getCurrentEvaluatorName()} 的指标分工`}
visible={viewModalVisible}
onCancel={handleCloseViewModal}
width={1200}
footer={[
<Button key="close" onClick={handleCloseViewModal}>
</Button>,
]}
>
<Spin spinning={loading}>
{filteredIndicators.length > 0 ? (
<EvaluateTemplateTable value={filteredIndicators} isDetail={true} />
) : (
<div style={{ textAlign: 'center', padding: '20px 0' }}>
{loading ? '加载中...' : '暂无指标分工数据'}
</div>
)}
</Spin>
</Modal>
</div> </div>
); );
}); });

View File

@ -64,7 +64,7 @@ const SupplierEvaluatorModal: React.FC<SupplierEvaluatorModalProps> = ({
<List.Item> <List.Item>
<List.Item.Meta <List.Item.Meta
title={item.name} title={item.name}
description={`${item.department || '未知部门'}`} description={`${item.userDept || '未知部门'}`}
/> />
</List.Item> </List.Item>
)} )}

View File

@ -43,8 +43,8 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
const columns = [ const columns = [
{ {
title: '供应商名称', // 列标题 title: '供应商名称', // 列标题
dataIndex: 'name', // 数据字段名 dataIndex: 'supplierName', // 数据字段名
key: 'name', // 列的唯一标识 key: 'supplierName', // 列的唯一标识
}, },
{ {
title: '统一社会信用代码', title: '统一社会信用代码',
@ -63,8 +63,8 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
}, },
{ {
title: '准入部门', title: '准入部门',
dataIndex: 'department', dataIndex: 'deptName',
key: 'department', key: 'deptName',
}, },
{ {
title: '评价人员数', title: '评价人员数',

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { Modal, Form, Row, Col, InputNumber } from 'antd'; import { Modal, Form, Row, Col, InputNumber } from 'antd';
import type { WeightUnit } from '@/servers/types/evaluator'; import type { DeptWeightItem } from '@/servers/types/supplierEvaluateTask';
interface WeightSettingModalProps { interface WeightSettingModalProps {
visible: boolean; visible: boolean;
onCancel: () => void; onCancel: () => void;
onOk: () => void; onOk: () => void;
weightUnits: WeightUnit[]; taskDeptWeightList: DeptWeightItem[];
form: any; form: any;
} }
@ -14,7 +14,7 @@ const WeightSettingModal: React.FC<WeightSettingModalProps> = ({
visible, visible,
onCancel, onCancel,
onOk, onOk,
weightUnits, taskDeptWeightList,
form, form,
}) => { }) => {
return ( return (
@ -26,12 +26,12 @@ const WeightSettingModal: React.FC<WeightSettingModalProps> = ({
> >
<Form form={form} layout="horizontal"> <Form form={form} layout="horizontal">
<Row gutter={16}> <Row gutter={16}>
{weightUnits.map((unit) => ( {taskDeptWeightList.map((item) => (
<Col span={12} key={unit.id}> <Col span={12} key={item.weightDept}>
<Form.Item <Form.Item
key={unit.id} key={item.weightDept}
label={unit.name} label={item.weightDeptName}
name={['weightUnits', unit.id]} name={['taskDeptWeightList', item.weightDept]}
rules={[ rules={[
{ required: true, message: '请输入权重值' }, { required: true, message: '请输入权重值' },
{ type: 'number', min: 0, message: '请输入大于等于0的数值' }, { type: 'number', min: 0, message: '请输入大于等于0的数值' },

View File

@ -8,11 +8,12 @@ import {
WeightSettingModal, WeightSettingModal,
} from './EvaluatorComponents'; } from './EvaluatorComponents';
import { ModalMode } from '@/servers/types/evaluator'; import { ModalMode } from '@/servers/types/evaluator';
import type { PersonnelItem, SupplierItem, WeightUnit } from '@/servers/types/evaluator'; import type { PersonnelItem, SupplierItem } from '@/servers/types/evaluator';
import type { DeptWeightItem,TaskAddRequest } from '@/servers/types/supplierEvaluateTask';
interface EvaluatorSelectStepProps { interface EvaluatorSelectStepProps {
formData: any; // 从上层组件传递过来的表单数据 formData: Partial<TaskAddRequest>; // 从上层组件传递过来的表单数据
onFormDataChange: (data: any) => void; // 表单数据变更回调函数 onFormDataChange: (data: Partial<TaskAddRequest>) => void; // 表单数据变更回调函数
} }
const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>( const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
@ -39,7 +40,7 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
const [modalMode, setModalMode] = useState<ModalMode>(ModalMode.SELECT); const [modalMode, setModalMode] = useState<ModalMode>(ModalMode.SELECT);
// 权重单位列表,根据评价人员部门动态生成 // 权重单位列表,根据评价人员部门动态生成
const [weightUnits, setWeightUnits] = useState<WeightUnit[]>([]); const [taskDeptWeightList, setTaskDeptWeightList] = useState<DeptWeightItem[]>([]);
// 表单实例,用于权重设置 // 表单实例,用于权重设置
const [form] = Form.useForm(); const [form] = Form.useForm();
@ -84,24 +85,25 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
indicatorList, indicatorList,
supplierIds, supplierIds,
suppliersWithEvaluators: suppliers, suppliersWithEvaluators: suppliers,
weightUnits, taskDeptWeightList,
}; };
}, },
setFieldsValue: (values: any) => { setFieldsValue: (values: any) => {
if (values.suppliersWithEvaluators) { if (values.suppliersWithEvaluators) {
setSuppliers(values.suppliersWithEvaluators); setSuppliers(values.suppliersWithEvaluators);
} }
if (values.weightUnits) { if (values.taskDeptWeightList) {
setWeightUnits(values.weightUnits); setTaskDeptWeightList(values.taskDeptWeightList);
} }
}, },
})); }));
// 从上一步获取供应商数据 // 从上一步获取供应商数据
useEffect(() => { useEffect(() => {
console.log(formData.selectedSuppliers)
if (formData.selectedSuppliers && formData.selectedSuppliers.length > 0) { if (formData.selectedSuppliers && formData.selectedSuppliers.length > 0) {
// 转换上一步的供应商数据,添加评价人员数量字段 // 转换上一步的供应商数据,添加评价人员数量字段
const suppliersWithEvaluators = formData.selectedSuppliers.map((supplier: any) => { const suppliersWithEvaluators = formData.selectedSuppliers.map((supplier: SupplierItem) => {
// 确保evaluators字段存在且为数组 // 确保evaluators字段存在且为数组
const evaluators = supplier.evaluators || []; const evaluators = supplier.evaluators || [];
return { return {
@ -118,11 +120,11 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
} }
// 初始化权重数据(如果有) // 初始化权重数据(如果有)
if (formData.WeightUnit && formData.WeightUnit.length > 0) { if (formData.taskDeptWeightList && formData.taskDeptWeightList.length > 0) {
setWeightUnits(formData.WeightUnit); setTaskDeptWeightList(formData.taskDeptWeightList);
} else { } else {
// 没有权重数据将在下面的useEffect中根据人员部门计算 // 没有权重数据将在下面的useEffect中根据人员部门计算
setWeightUnits([]); setTaskDeptWeightList([]);
} }
}, [formData]); }, [formData]);
@ -152,19 +154,19 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
// 如果有部门数据,生成权重单位列表 // 如果有部门数据,生成权重单位列表
if (uniqueDepartments.length > 0) { if (uniqueDepartments.length > 0) {
const newWeightUnits: WeightUnit[] = uniqueDepartments.map((dept, index) => ({ const newTaskDeptWeightList: DeptWeightItem[] = uniqueDepartments.map((dept) => ({
id: dept.userDeptId, weightDept: dept.userDeptId || '',
name: dept.userDept, weightValue: '0', // 默认权重为0
weight: 0, // 默认权重为0 weightDeptName: dept.userDept || '',
})); }));
// 更新权重单位列表,保留原有权重值 // 更新权重单位列表,保留原有权重值
setWeightUnits((prevUnits) => { setTaskDeptWeightList((prevList) => {
const prevUnitsMap = new Map(prevUnits.map((unit) => [unit.id, unit.weight])); const prevValuesMap = new Map(prevList.map((item) => [item.weightDept, item.weightValue]));
return newWeightUnits.map((unit) => ({ return newTaskDeptWeightList.map((item) => ({
...unit, ...item,
weight: prevUnitsMap.get(unit.id) || 0, // 如果有原来的权重值则保留 weightValue: prevValuesMap.get(item.weightDept) || '0', // 如果有原来的权重值则保留
})); }));
}); });
} }
@ -187,12 +189,23 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
id: supplier.id, id: supplier.id,
userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [], userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [],
})); }));
onFormDataChange({
...updatedData, // 如果有taskDeptWeightList数据直接使用
indicatorList, if (updatedData.taskDeptWeightList) {
supplierIds, onFormDataChange({
weightUnits, ...updatedData,
}); indicatorList,
supplierIds,
});
} else {
// 否则包含当前的taskDeptWeightList
onFormDataChange({
...updatedData,
indicatorList,
supplierIds,
taskDeptWeightList,
});
}
}; };
// 处理批量选择 // 处理批量选择
@ -205,8 +218,8 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
const handleWeightSetting = () => { const handleWeightSetting = () => {
// 设置初始表单值 // 设置初始表单值
form.setFieldsValue({ form.setFieldsValue({
weightUnits: weightUnits.reduce((acc, unit) => { taskDeptWeightList: taskDeptWeightList.reduce((acc, item) => {
acc[unit.id] = unit.weight; acc[item.weightDept] = parseInt(item.weightValue, 10) || 0;
return acc; return acc;
}, {} as Record<string, number>), }, {} as Record<string, number>),
}); });
@ -217,23 +230,16 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
// 保存权重设置 // 保存权重设置
const handleSaveWeights = () => { const handleSaveWeights = () => {
form.validateFields().then((values) => { form.validateFields().then((values) => {
const updatedWeightUnits = weightUnits.map((unit) => ({ const updatedTaskDeptWeightList = taskDeptWeightList.map((item) => ({
...unit, ...item,
weight: values.weightUnits[unit.id], weightValue: values.taskDeptWeightList[item.weightDept].toString(),
})); }));
setWeightUnits(updatedWeightUnits); setTaskDeptWeightList(updatedTaskDeptWeightList);
// 将更新后的权重数据传递给父组件
// 同时转换为taskDeptWeightList格式
const taskDeptWeightList = updatedWeightUnits.map(unit => ({
weightDept: unit.name, // 使用部门名称
weightValue: unit.weight.toString(), // 转换为字符串格式
}));
updateFormData({ updateFormData({
weightUnits: updatedWeightUnits, suppliersWithEvaluators: suppliers,
taskDeptWeightList: taskDeptWeightList, taskDeptWeightList: updatedTaskDeptWeightList,
}); });
setWeightSettingModalVisible(false); setWeightSettingModalVisible(false);
@ -321,7 +327,7 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
> >
</Button> </Button>
<Button onClick={handleWeightSetting} disabled={weightUnits.length === 0}> <Button onClick={handleWeightSetting} disabled={taskDeptWeightList.length === 0}>
</Button> </Button>
</Space> </Space>
@ -363,7 +369,7 @@ const EvaluatorSelectStep = forwardRef<any, EvaluatorSelectStepProps>(
visible={weightSettingModalVisible} visible={weightSettingModalVisible}
onCancel={() => setWeightSettingModalVisible(false)} onCancel={() => setWeightSettingModalVisible(false)}
onOk={handleSaveWeights} onOk={handleSaveWeights}
weightUnits={weightUnits} taskDeptWeightList={taskDeptWeightList}
form={form} form={form}
/> />
</Card> </Card>

View File

@ -1,21 +1,25 @@
import React, { forwardRef, useImperativeHandle } from 'react'; import React, { forwardRef, useImperativeHandle, useEffect, useState } from 'react';
import { Card, Form } from 'antd'; import { Card, Form } from 'antd';
import styles from '../supplierTaskManageAdd.less'; import styles from '../supplierTaskManageAdd.less';
import SupplierSelector from '@/components/SupplierSelector'; import SupplierSelector from '@/components/SupplierSelector';
import type { TaskAddRequest,SupplierItem } from '@/servers/types/supplierEvaluateTask';
interface SupplierSelectStepProps { interface SupplierSelectStepProps {
formData: any; // 从父组件传递的表单数据 formData: Partial<TaskAddRequest>; // 从父组件传递的表单数据
onFormDataChange: (data: any) => void; // 表单数据变更的回调函数 onFormDataChange: (data: Partial<TaskAddRequest>) => void; // 表单数据变更的回调函数
}
interface SupplierItem {
id: string; // 供应商ID
name: string; // 供应商名称
supplierType: string; // 供应商类型
[key: string]: any; // 其他可能的字段
} }
const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData, onFormDataChange }, ref) => { const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData, onFormDataChange }, ref) => {
// 内部状态避免直接操作formData导致循环更新
const [selectedSuppliers, setSelectedSuppliers] = useState<SupplierItem[]>([]);
// 当formData.selectedSuppliers更新时同步到本地状态
useEffect(() => {
if (formData.selectedSuppliers && formData.selectedSuppliers.length > 0) {
setSelectedSuppliers(formData.selectedSuppliers);
}
}, [formData.selectedSuppliers]); // 只在表单ID变化时更新编辑模式加载时
// 暴露表单方法给父组件 // 暴露表单方法给父组件
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
validateFields: () => { validateFields: () => {
@ -24,23 +28,19 @@ const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData,
}, },
getFieldsValue: () => { getFieldsValue: () => {
return { return {
selectedSuppliers: formData.selectedSuppliers || [], selectedSuppliers,
supplierIds: (formData.selectedSuppliers || []).map((supplier: SupplierItem) => ({ id: supplier.id })) supplierIds: selectedSuppliers.map((supplier: SupplierItem) => ({ id: supplier.id }))
}; };
}, },
setFieldsValue: (values: any) => { setFieldsValue: (values: any) => {
if (values.selectedSuppliers) { if (values.selectedSuppliers) {
onFormDataChange({ setSelectedSuppliers(values.selectedSuppliers);
...formData,
selectedSuppliers: values.selectedSuppliers
});
} }
}, },
})); }));
// 处理供应商选择 // 处理供应商选择
const handleSupplierSelect = (suppliers: SupplierItem[]) => { const handleSupplierSelect = (suppliers: SupplierItem[]) => {
// 确保每个供应商都有evaluators字段 // 确保每个供应商都有evaluators字段
const suppliersWithEvaluators = suppliers.map(supplier => ({ const suppliersWithEvaluators = suppliers.map(supplier => ({
...supplier, ...supplier,
@ -48,9 +48,11 @@ const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData,
evaluatorCount: supplier.evaluators?.length || 0 // 计算评价人员数量 evaluatorCount: supplier.evaluators?.length || 0 // 计算评价人员数量
})); }));
// 更新本地状态
setSelectedSuppliers(suppliersWithEvaluators);
// 通知父组件
onFormDataChange({ onFormDataChange({
...formData,
selectedSuppliers: suppliersWithEvaluators, selectedSuppliers: suppliersWithEvaluators,
supplierIds: suppliersWithEvaluators.map(supplier => ({ id: supplier.id })) supplierIds: suppliersWithEvaluators.map(supplier => ({ id: supplier.id }))
}); });
@ -61,7 +63,7 @@ const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData,
<Card title="供应商选择" bordered={false} className="inner-card"> <Card title="供应商选择" bordered={false} className="inner-card">
<SupplierSelector <SupplierSelector
onSelect={handleSupplierSelect} onSelect={handleSupplierSelect}
selectedSuppliers={formData.selectedSuppliers || []} selectedSuppliers={selectedSuppliers}
/> />
</Card> </Card>
</div> </div>

View File

@ -1,16 +1,32 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { Card, Steps, Button, message, Space, Row, Col, Form } from 'antd'; import { Card, Steps, Button, message, Space, Row, Col, Form, Modal } from 'antd';
import { history } from 'umi'; import { history } from 'umi';
import { ArrowLeftOutlined, SaveOutlined } from '@ant-design/icons'; import { ArrowLeftOutlined, SaveOutlined } from '@ant-design/icons';
import { addTask } from '@/servers/api/supplierEvaluate'; import { addTask, getTaskDetail, updateTask } from '@/servers/api/supplierEvaluate';
import BasicInfoStep from './components/BasicInfoStep'; import BasicInfoStep from './components/BasicInfoStep';
import SupplierSelectStep from './components/SupplierSelectStep'; import SupplierSelectStep from './components/SupplierSelectStep';
import EvaluatorSelectStep from './components/EvaluatorSelectStep'; import EvaluatorSelectStep from './components/EvaluatorSelectStep';
import DivisionStep from './components/DivisionStep'; import DivisionStep from './components/DivisionStep';
import styles from './supplierTaskManageAdd.less'; import styles from './supplierTaskManageAdd.less';
import type {
DeptWeightItem,
TaskAddRequest,
TaskDetailData,
} from '@/servers/types/supplierEvaluateTask';
import { TaskNotifyLowerUnits } from '@/dicts/supplierTaskDict';
const { Step } = Steps; const { Step } = Steps;
// 获取URL参数
const getUrlParams = () => {
const location = window.location.href;
const url = new URL(location);
return {
id: url.searchParams.get('id'),
mode: url.searchParams.get('mode'),
};
};
const SupplierTaskManageAdd: React.FC = () => { const SupplierTaskManageAdd: React.FC = () => {
// 当前步骤索引从0开始 // 当前步骤索引从0开始
const [currentStep, setCurrentStep] = useState<number>(0); const [currentStep, setCurrentStep] = useState<number>(0);
@ -18,11 +34,91 @@ const SupplierTaskManageAdd: React.FC = () => {
// 提交加载状态 // 提交加载状态
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
// 判断是否为编辑模式
const urlParams = getUrlParams();
const isEditMode = urlParams.mode === 'edit' && urlParams.id;
const taskId = urlParams.id || '';
// 整个表单的数据,包含所有步骤的数据 // 整个表单的数据,包含所有步骤的数据
const [formData, setFormData] = useState<Partial<SupplierEvaluate.TaskAddRequest>>({}); const [formData, setFormData] = useState<Partial<TaskAddRequest>>({});
// 加载状态
const [detailLoading, setDetailLoading] = useState<boolean>(false);
// 创建表单引用,用于访问子组件的表单方法(仅用于验证)
const basicFormRef = useRef<any>(null); // 基本信息表单引用
const supplierFormRef = useRef<any>(null); // 供应商选择表单引用
const evaluatorFormRef = useRef<any>(null); // 评价人员表单引用
const divisionFormRef = useRef<any>(null); // 评价分工表单引用
// 确认对话框可见性状态
const [confirmModalVisible, setConfirmModalVisible] = useState(false);
// 获取任务详情
const fetchTaskDetail = async (id: string) => {
setDetailLoading(true);
try {
const response = await getTaskDetail(id);
if (response.success) {
const detail: TaskDetailData = response.data;
// 转换任务详情数据为表单数据结构
const taskFormData: Partial<TaskAddRequest> = {
id: detail.id || '',
evaluateTheme: detail.evaluateTheme || '',
startTime: detail.startTime || '',
endTime: detail.endTime || '',
templateId: detail.templateId || '',
categoryLimitation: detail.categoryLimitation || '0',
evaluateYear: detail.evaluateYear || '',
categoryId: detail.categoryId || undefined,
// 供应商数据回显转换
selectedSuppliers: detail.blackSupplierVos.map((item) => ({
...item,
id: item.supplierId,
name: item.supplierName,
evaluators: item.userList,
})),
// 接口返回的人员分配的指标,以人员userId 为维度 indicatorIds[string] 指标id
indicatorList: detail.indicatorList || [],
// 后台用供应商集合,包含供应商id 并且关联 userIds
supplierIds: detail.supplierIds || [],
// 部门权重设置
taskDeptWeightList: detail.taskDeptWeightList || [],
// 分配指标分工回显
suppliersWithEvaluators: detail.blackSupplierVos.map((item) => ({
...item,
id: item.supplierId,
name: item.supplierName,
evaluators: item.userList,
})),
};
// 更新表单数据 - 子组件通过props获取
setFormData(taskFormData);
} else {
message.error(response.message || '获取任务详情失败');
}
} catch (error) {
console.error('获取任务详情失败:', error);
message.error('获取任务详情失败');
} finally {
setDetailLoading(false);
}
};
// 编辑模式下获取任务详情
useEffect(() => {
if (isEditMode) {
fetchTaskDetail(taskId);
}
}, [isEditMode, taskId]);
// 处理表单数据变更 // 处理表单数据变更
const handleFormDataChange = (data: any) => { const handleFormDataChange = (data: Partial<TaskAddRequest>) => {
// 第一步:基本信息 // 第一步:基本信息
if (data) { if (data) {
setFormData((prev) => ({ ...prev, ...data })); setFormData((prev) => ({ ...prev, ...data }));
@ -46,53 +142,64 @@ const SupplierTaskManageAdd: React.FC = () => {
setFormData((prev) => ({ setFormData((prev) => ({
...prev, ...prev,
suppliersWithEvaluators: evaluatedSuppliers, suppliersWithEvaluators: evaluatedSuppliers,
selectedSuppliers: evaluatedSuppliers // 同步更新selectedSuppliers selectedSuppliers: evaluatedSuppliers, // 同步更新selectedSuppliers
})); }));
} }
// 更新权重单位 // 处理部门权重列表 taskDeptWeightList
if (data.weightUnits) {
// 将 weightUnits 存储在 formData.WeightUnit 中
setFormData((prev) => ({ ...prev, WeightUnit: data.weightUnits }));
}
// 处理部门权重列表
if (data.taskDeptWeightList) { if (data.taskDeptWeightList) {
setFormData((prev) => ({ setFormData((prev) => ({
...prev, ...prev,
taskDeptWeightList: data.taskDeptWeightList, taskDeptWeightList: data.taskDeptWeightList,
// weightStatus: data.weightStatus || 0
})); }));
} }
}; };
// 创建表单引用,用于访问子组件的表单方法
const basicFormRef = useRef<any>(null); // 基本信息表单引用
const supplierFormRef = useRef<any>(null); // 供应商选择表单引用
const evaluatorFormRef = useRef<any>(null); // 评价人员表单引用
const divisionFormRef = useRef<any>(null); // 评价分工表单引用
// 步骤配置 // 步骤配置
const steps = [ const steps = [
{ {
title: '基本信息', // 步骤标题 title: '基本信息', // 步骤标题
description: '请填写基本信息', // 步骤描述 description: '请填写基本信息', // 步骤描述
content: <BasicInfoStep formData={formData} onFormDataChange={handleFormDataChange} ref={basicFormRef} />, // 步骤内容组件 content: (
<BasicInfoStep
formData={formData}
onFormDataChange={handleFormDataChange}
ref={basicFormRef}
/>
), // 步骤内容组件
}, },
{ {
title: '选择供应商', title: '选择供应商',
description: '请选择参加评价的供应商', description: '请选择参加评价的供应商',
content: <SupplierSelectStep formData={formData} onFormDataChange={handleFormDataChange} ref={supplierFormRef} />, content: (
<SupplierSelectStep
formData={formData}
onFormDataChange={handleFormDataChange}
ref={supplierFormRef}
/>
),
}, },
{ {
title: '选择评价人员', title: '选择评价人员',
description: '请选择供应商评价人员', description: '请选择供应商评价人员',
content: <EvaluatorSelectStep formData={formData} onFormDataChange={handleFormDataChange} ref={evaluatorFormRef} />, content: (
<EvaluatorSelectStep
formData={formData}
onFormDataChange={handleFormDataChange}
ref={evaluatorFormRef}
/>
),
}, },
{ {
title: '设置评价分工', title: '设置评价分工',
description: '不设置按默认全部指标评价', description: '不设置按默认全部指标评价',
content: <DivisionStep formData={formData} onFormDataChange={handleFormDataChange} ref={divisionFormRef} />, content: (
<DivisionStep
formData={formData}
onFormDataChange={handleFormDataChange}
ref={divisionFormRef}
/>
),
}, },
]; ];
@ -141,60 +248,65 @@ const SupplierTaskManageAdd: React.FC = () => {
setCurrentStep(currentStep - 1); setCurrentStep(currentStep - 1);
}; };
// 提交表单 // 实际提交数据的函数
const handleSubmit = async () => { const submitTaskData = async (taskStatus: TaskNotifyLowerUnits) => {
setLoading(true); setLoading(true);
try { try {
// 验证评价分工 // 构建提交数据,确保必填字段有值
if (divisionFormRef.current) { const submitData = {
const result = divisionFormRef.current.validate(); evaluateTheme: formData.evaluateTheme || '', // 评价主题
if (!result.valid) { startTime: formData.startTime || '', // 开始时间
message.error(result.message); endTime: formData.endTime || '', // 结束时间
setLoading(false); templateId: formData.templateId || '', // 模板ID
return;
}
}
// 构建提交数据
const submitData: SupplierEvaluate.TaskAddRequest = {
evaluateTheme: formData.evaluateTheme || '', // 评价主题
startTime: formData.startTime || '', // 开始时间
endTime: formData.endTime || '', // 结束时间
templateId: formData.templateId || '', // 模板ID
categoryLimitation: formData.categoryLimitation || '0', // 品类限制 categoryLimitation: formData.categoryLimitation || '0', // 品类限制
evaluateYear: formData.evaluateYear || '', // 评价年份 evaluateYear: formData.evaluateYear || '', // 评价年份
// weightStatus: formData.weightStatus || 0, // 权重状态 categoryId: formData.categoryId || '', // 品类ID
taskStatus: taskStatus, // 任务状态,根据用户的选择决定
// 修复供应商ID列表格式,确保包含 userIds 字段 // 供应商ID列表包含评价人员ID
supplierIds: formData.selectedSuppliers?.map((supplier: any) => { supplierIds:
// 从供应商的evaluators中提取用户ID formData.selectedSuppliers?.map((supplier: any) => {
const userIds = supplier.evaluators?.map((evaluator: any) => evaluator.id) || []; // 从供应商的evaluators中提取用户ID
return { const userIds = supplier.evaluators?.map((evaluator: any) => evaluator.id) || [];
id: supplier.id, return {
userIds id: supplier.id,
}; userIds,
}) || [], };
}) || [],
// 确保指标列表中的每个项目都有正确的type值 // 评价指标列表
indicatorList: formData.indicatorList?.map((item: any) => ({ indicatorList:
userId: item.userId, formData.indicatorList?.map((item: any) => ({
// 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单) userId: item.userId,
type: item.indicatorIds && item.indicatorIds.length > 0 ? 1 : 0, // 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单)
indicatorIds: item.indicatorIds || [], type: item.indicatorIds && item.indicatorIds.length > 0 ? 1 : 0,
})) || [], indicatorIds: item.indicatorIds || [],
})) || [],
// 部门权重列表过滤掉权重为0的 // 部门权重列表过滤掉权重为0的
taskDeptWeightList: formData.taskDeptWeightList?.filter((item: any) => { taskDeptWeightList:
return item.weightValue && item.weightValue !== '0'; formData.taskDeptWeightList?.filter((item: any) => {
}) || [], return item.weightValue && item.weightValue !== '0';
}) || [],
}; };
// 调用API提交数据 let response;
const response = await addTask(submitData);
if (isEditMode) {
// 编辑模式添加ID字段
const updateData = {
...submitData,
id: taskId,
};
response = await updateTask(updateData);
} else {
// 新增模式
response = await addTask(submitData);
}
if (response.success) { if (response.success) {
message.success('任务创建成功'); message.success(isEditMode ? '任务更新成功' : '任务创建成功');
// 创建成功后直接返回列表页面 // 成功后直接返回列表页面
history.push('/supplier/supplierTaskManage'); history.push('/supplier/supplierTaskManage');
} else { } else {
message.error(response.message || '提交失败'); message.error(response.message || '提交失败');
@ -207,11 +319,43 @@ const SupplierTaskManageAdd: React.FC = () => {
} }
}; };
// 提交表单
const handleSubmit = async () => {
// 验证评价分工
if (divisionFormRef.current) {
const result = divisionFormRef.current.validate();
if (!result.valid) {
message.error(result.message);
return;
}
}
// 显示确认对话框
setConfirmModalVisible(true);
};
// 处理确认对话框的取消
const handleConfirmCancel = () => {
setConfirmModalVisible(false);
};
// 处理确认对话框的"是"选项
const handleConfirmYes = () => {
submitTaskData(TaskNotifyLowerUnits.YES); // 未开始状态,需要下级单位完善
setConfirmModalVisible(false);
};
// 处理确认对话框的"否"选项
const handleConfirmNo = () => {
submitTaskData(TaskNotifyLowerUnits.NO); // 进行中状态,不需要下级单位完善
setConfirmModalVisible(false);
};
return ( return (
<div className="common-container"> <div className="common-container">
<Card bordered={false}> <Card bordered={false} loading={detailLoading}>
<div className="page-header"> <div className="page-header">
<h2></h2> <h2>{isEditMode ? '修改评价任务' : '新增评价任务'}</h2>
<Button type="link" icon={<ArrowLeftOutlined />} onClick={handleBack}> <Button type="link" icon={<ArrowLeftOutlined />} onClick={handleBack}>
</Button> </Button>
@ -220,21 +364,17 @@ const SupplierTaskManageAdd: React.FC = () => {
<Row gutter={24} className={styles.stepsLayout}> <Row gutter={24} className={styles.stepsLayout}>
<Col span={6} className={styles.stepsLeft}> <Col span={6} className={styles.stepsLeft}>
<Steps direction="vertical" current={currentStep} className={styles.verticalSteps}> <Steps direction="vertical" current={currentStep} className={styles.verticalSteps}>
{steps.map(item => ( {steps.map((item) => (
<Step key={item.title} title={item.title} description={item.description} /> <Step key={item.title} title={item.title} description={item.description} />
))} ))}
</Steps> </Steps>
</Col> </Col>
<Col span={18} className={styles.stepsRight}> <Col span={18} className={styles.stepsRight}>
<div className={styles.stepsContent}> <div className={styles.stepsContent}>{steps[currentStep].content}</div>
{steps[currentStep].content}
</div>
<div className={styles.stepsAction}> <div className={styles.stepsAction}>
<Space> <Space>
{currentStep > 0 && ( {currentStep > 0 && <Button onClick={handlePrev}></Button>}
<Button onClick={handlePrev}></Button>
)}
{currentStep < steps.length - 1 && ( {currentStep < steps.length - 1 && (
<Button type="primary" onClick={handleNext}> <Button type="primary" onClick={handleNext}>
@ -247,7 +387,7 @@ const SupplierTaskManageAdd: React.FC = () => {
icon={<SaveOutlined />} icon={<SaveOutlined />}
onClick={handleSubmit} onClick={handleSubmit}
> >
{isEditMode ? '保存' : '提交'}
</Button> </Button>
)} )}
</Space> </Space>
@ -255,6 +395,25 @@ const SupplierTaskManageAdd: React.FC = () => {
</Col> </Col>
</Row> </Row>
</Card> </Card>
{/* 确认对话框 */}
<Modal
title="提交确认"
visible={confirmModalVisible}
onCancel={handleConfirmCancel}
footer={null}
>
<p></p>
<div style={{ textAlign: 'right', marginTop: 24 }}>
<Space>
<Button type="primary" onClick={handleConfirmYes}>
</Button>
<Button onClick={handleConfirmNo}></Button>
<Button onClick={handleConfirmCancel}></Button>
</Space>
</div>
</Modal>
</div> </div>
); );
}; };

View File

@ -165,7 +165,7 @@ export async function addTask(params: SupplierEvaluate.TaskAddRequest) {
* @param params 任务数据 * @param params 任务数据
* @returns Promise * @returns Promise
*/ */
export async function updateTask(params: SupplierEvaluate.TaskUpdateRequest) { export async function updateTask(params: SupplierEvaluate.TaskAddRequest) {
return request<API.APIResponse<any>>('/coscoEvaluate/task', { return request<API.APIResponse<any>>('/coscoEvaluate/task', {
method: 'PUT', method: 'PUT',
data: params, data: params,

View File

@ -60,13 +60,24 @@ export interface TaskDetailData {
weightDept: string | null; weightDept: string | null;
weightStatus: number | null; weightStatus: number | null;
weightValue: string | null; weightValue: string | null;
taskDeptWeightList: { taskDeptWeightList: DeptWeightItem[] | null;
weightDept: string; blackSupplierVos: {
weightValue: string; deptName: string;
}[] | null; supplierId: string;
supplierName: string;
userList: User[];
}[],
[property: string]: any; [property: string]: any;
} }
// 部门配置权重
export interface DeptWeightItem {
//部门id
weightDept: string;
// 部门权重值
weightValue: string;
// 部门名称
weightDeptName: string;
}
/** /**
* 任务详情响应 * 任务详情响应
*/ */
@ -77,3 +88,61 @@ export interface TaskDetailResponse {
success: boolean; success: boolean;
[property: string]: any; [property: string]: any;
} }
// 新增评价任务和修改 请求参数定义
export type TaskAddRequest = {
/**
* 品类限制类型0.通用不限品类、1.限制品类)
*/
categoryLimitation?: string;
/**
* 评价结束时间
*/
endTime: string;
/**
* 评价主题
*/
evaluateTheme: string;
/**
* 评价年度
*/
evaluateYear: string;
indicatorList: IndicatorList[];
/**
* 评价开始时间
*/
startTime: string;
supplierIds: SupplierId[];
taskDeptWeightList: DeptWeightItem[];
/**
* 评价表模板id(cosco_evaluate_template表主键)
*/
templateId: string;
// 品类id
categoryId?: string;
[property: string]: any;
}
/**
* 供应商项
*/
export interface SupplierItem {
id: string; // 供应商ID
supplierName: string; // 供应商名称
socialCreditCode?: string; // 统一社会信用代码
category?: string; // 品类
department?: string; // 准入部门
evaluatorCount: number; // 评价人员数量
evaluators: User[]; // 评价人员列表
// 其他可能的字段
[key: string]: any;
}
export type SupplierId = {
/**
* 供应商id
*/
id: string;
/**
* 用户集合
*/
userIds?: string[];
}

4
src/typings.d.ts vendored
View File

@ -497,6 +497,10 @@ declare namespace SupplierEvaluate {
* 权重启用状态(0.不启用、1.启用) * 权重启用状态(0.不启用、1.启用)
*/ */
// weightStatus: number; // weightStatus: number;
/**
* 是否通知下级单位完善评价人及评价分工 0否1是
*/
taskStatus: number;
[property: string]: any; [property: string]: any;
} }