评价任务 改为dva数据流转模式

This commit is contained in:
linxd
2025-06-26 18:14:41 +08:00
parent f41639fd39
commit 527637cce3
14 changed files with 1698 additions and 970 deletions

View File

@ -3,30 +3,17 @@ import React, {
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 { Table, Tag, Space, Button, message, Modal, Spin } from 'antd';
import type { PersonnelItem } from '@/servers/types/evaluator';
import type { ColumnsType } from 'antd/es/table';
import EvaluateTemplateTable from '@/components/EvaluateTemplateTable';
import { getTemplateDetail } from '@/servers/api/supplierEvaluate';
import type { TaskAddRequest } from '@/servers/types/supplierEvaluateTask';
import type { Dispatch } from 'umi';
import { connect } from 'umi';
import type { SupplierTaskModelState } from '@/models/supplierTaskManage';
// 评价指标类型定义
interface IndicatorItem {
@ -37,8 +24,9 @@ interface IndicatorItem {
// 组件接收的Props定义
interface DivisionStepProps {
formData: Partial<TaskAddRequest>;
onFormDataChange?: (values: Partial<TaskAddRequest>) => void;
supplierTaskManage: SupplierTaskModelState;
dispatch: Dispatch;
innerRef?: any; // 使用 innerRef 作为属性名
}
// 评价方式枚举
@ -49,7 +37,13 @@ enum EvaluateType {
INDICATOR = 1, // 按指标评价(部分指标)
}
const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataChange }, ref) => {
// 定义组件,使用 innerRef 代替直接的 ref
const DivisionStepComponent = (props: DivisionStepProps) => {
const { supplierTaskManage, dispatch, innerRef } = props;
// 从 model 获取表单数据,避免通过 props 层层传递
const { taskFormData } = supplierTaskManage;
// 从上一步获取的评价人员列表
const [evaluators, setEvaluators] = useState<PersonnelItem[]>([]);
@ -60,12 +54,6 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
indicatorIds: string[];
};
}>({});
// const [indicatorAssignments, setIndicatorAssignments] = useState<{
// [userId: string]: {
// type: EvaluateType;
// indicatorIds: string[];
// };
// }>({});
// 选中的行keys
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
@ -79,9 +67,6 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 批量指标设置弹窗可见性
const [batchTemplateModalVisible, setBatchTemplateModalVisible] = useState(false);
// 批量选择的指标
const [batchSelectedIndicators, setBatchSelectedIndicators] = useState<string[]>([]);
// 批量选择的模板项
const [batchSelectedTemplateItems, setBatchSelectedTemplateItems] = useState<any[]>([]);
@ -187,10 +172,23 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
setLoading(false);
}
};
/**
* 更新表单数据
* 将本地状态同步到 Dva model
* @param updatedData 要更新的部分数据
*/
const updateFormData = (updatedData: any) => {
// 通过dispatch更新model中的数据
dispatch({
type: 'supplierTaskManage/updateFormData', // action类型
payload: {
...updatedData,
},
});
};
// 监听templateId变化获取模板详情
useEffect(() => {
fetchTemplateDetail(formData.templateId as string);
fetchTemplateDetail(taskFormData.templateId as string);
}, []);
// 处理行选择变化
@ -220,39 +218,42 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
const handleCloseBatchTemplateModal = () => {
setBatchTemplateModalVisible(false);
};
// 批量设置指标分工
const handleBatchSetDivision = () => {
// 获取选中的评价人员
const selectedEvaluators = evaluators.filter((evaluator) =>
selectedRowKeys.includes(evaluator.id),
// 处理指标选择 提取二级指标id
const getIndicatorNdListIds = (selectedItems: any[]) => {
const indicatorNdList = selectedItems.map((item) => item.indicatorNdList);
const indicatorNdListIds = indicatorNdList.flatMap((item) =>
item.map((ndItem: any) => ndItem.id),
);
// 提取所有选中指标的ID
const selectedIndicatorIds: string[] = [];
// 从选中的模板项中提取所有指标ID
batchSelectedTemplateItems.forEach((stItem) => {
// 添加二级指标ID
if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) {
stItem.indicatorNdList.forEach((ndItem: any) => {
selectedIndicatorIds.push(ndItem.id);
});
return indicatorNdListIds;
};
// 处理指标,将处理后的指标放到dva中,同步处理userList,展示table
const handleIndicatorAssignment = (indicatorNdListIds: string[]) => {
// 读取dva中的indicatorList
const indicatorList = JSON.parse(JSON.stringify(taskFormData?.indicatorList));
// 将指标id塞到当前激活的评价人员中
indicatorList?.map((item: any) => {
// 判断当前激活的评价人员和选择评价人构建的userId一直
if (item.userId === currentUserId) {
item.indicatorIds = [...new Set([...item.indicatorIds, ...indicatorNdListIds])];
}
});
// 更新指标分配数据
const newAssignments = { ...indicatorAssignments.current };
selectedEvaluators.forEach((evaluator) => {
newAssignments[evaluator.id] = {
// 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单)
type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL,
indicatorIds: selectedIndicatorIds,
};
// 构建userList带指标id 为了表单回显
const userList = JSON.parse(JSON.stringify(taskFormData?.userList));
userList?.map((item: any) => {
if (item.id === currentUserId) {
item.indicatorIds = indicatorNdListIds;
}
});
indicatorAssignments.current = newAssignments;
updateFormData({
indicatorList,
userList,
});
};
// 批量设置指标分工
const handleBatchSetDivision = () => {
// 将选择回来的指标提取二级指标id
const indicatorNdListIds = getIndicatorNdListIds(batchSelectedTemplateItems);
handleIndicatorAssignment(indicatorNdListIds);
setBatchTemplateModalVisible(false);
message.success(`已为${selectedRowKeys.length}名评价人员设置分工`);
};
@ -274,7 +275,6 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 处理模板指标选择
const handleTemplateItemsSelect = (selectedItems: any[]) => {
console.log(selectedItems);
setSelectedTemplateItems(selectedItems);
};
@ -284,49 +284,29 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
message.warning('未选择评价人员');
return;
}
// 提取所有选中指标的ID
const selectedIndicatorIds: string[] = [];
// 从选中的模板项中提取所有指标ID
selectedTemplateItems.forEach((stItem) => {
// 添加二级指标ID
if (stItem.indicatorNdList && stItem.indicatorNdList.length > 0) {
stItem.indicatorNdList.forEach((ndItem: any) => {
selectedIndicatorIds.push(ndItem.id);
});
}
});
// 更新指标分配
const newAssignments = { ...indicatorAssignments.current };
newAssignments[currentUserId] = {
// 评价类型如果用户关联了指标则为1(按指标)否则为0(按评价单)
type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL,
indicatorIds: selectedIndicatorIds,
};
indicatorAssignments.current = newAssignments;
// 将选择回来的指标提取二级指标id
const indicatorNdListIds = getIndicatorNdListIds(selectedTemplateItems);
handleIndicatorAssignment(indicatorNdListIds);
setTemplateViewModalVisible(false);
message.success('已设置评价人员指标分工');
};
// 查看评价人员的指标分工
const handleViewAssignment = (userId: string) => {
const assignment = indicatorAssignments.current[userId];
const handleViewAssignment = (person: PersonnelItem) => {
const assignment = person.indicatorIds;
if (!assignment) {
message.info('该评价人员尚未设置分工');
return;
}
setCurrentUserId(userId);
setCurrentUserId(person.id);
setLoading(true);
// 获取该评价人员的指标ID
const indicatorIds = getUserIndicatorIds(userId);
const indicatorIds = person.indicatorIds;
// 过滤模板数据
const filtered = filterTemplateDataByIds(templateData, indicatorIds);
const filtered = filterTemplateDataByIds(templateData, indicatorIds || []);
setFilteredIndicators(filtered);
setLoading(false);
@ -361,10 +341,10 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
// 初始化从formData中提取指标分配数据
useEffect(() => {
if (formData.indicatorList && formData.indicatorList.length > 0) {
if (taskFormData.indicatorList && taskFormData.indicatorList.length > 0) {
// 如果已有指标分配数据,直接使用
const assignments: any = {};
formData.indicatorList.forEach((item: any) => {
taskFormData.indicatorList.forEach((item: any) => {
assignments[item.userId] = {
type: item.type,
indicatorIds: item.indicatorIds || [],
@ -372,85 +352,16 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
});
indicatorAssignments.current = assignments;
}
}, [formData.indicatorList]);
}, [taskFormData.indicatorList]);
// 从上一步获取评价人员列表 - 避免频繁更新
useEffect(() => {
if (!formData.suppliersWithEvaluators) return;
// 从所有供应商中提取评价人员列表
const allEvaluators: PersonnelItem[] = [];
formData.suppliersWithEvaluators.forEach((supplier: any) => {
if (supplier.evaluators && supplier.evaluators.length > 0) {
supplier.evaluators.forEach((evaluator: PersonnelItem) => {
// 检查是否已存在(避免重复)
if (!allEvaluators.some((e) => e.id === evaluator.id)) {
allEvaluators.push({
...evaluator,
// 添加单位和员工编号,假设这些字段可能不存在
company: evaluator.company || supplier.supplierName || '未知单位',
employeeNumber: evaluator.employeeNumber || `EMP${evaluator.id.slice(-4)}`,
department: evaluator.department || '未知部门',
});
}
});
}
});
setEvaluators(allEvaluators);
}, [formData.suppliersWithEvaluators]);
// 为评价人员初始化指标分配数据 - 作为单独的效果处理
useEffect(() => {
// 检查是否有新的评价人员需要初始化
const newAssignments = { ...indicatorAssignments.current };
let hasNewAssignments = false;
evaluators.forEach((evaluator) => {
if (!indicatorAssignments.current[evaluator.id]) {
newAssignments[evaluator.id] = {
type: EvaluateType.ALL,
indicatorIds: [],
};
hasNewAssignments = true;
}
});
if (hasNewAssignments) {
indicatorAssignments.current = newAssignments;
}
}, [evaluators, indicatorAssignments]);
// 同步数据回表单 - 使用防抖确保不会频繁触发
const previousValueRef = React.useRef<string>('');
useEffect(() => {
// 若当前还未初始化完成(没有任何指标数据),不应向父组件同步
if (evaluators.length === 0 || Object.keys(indicatorAssignments.current).length === 0) {
return;
}
// 将评价人员列表和指标分配数据同步回表单
const indicatorList = evaluators.map((evaluator) => ({
userId: evaluator.id,
userName: evaluator.name,
type: indicatorAssignments.current[evaluator.id]?.type ?? EvaluateType.ALL,
indicatorIds: indicatorAssignments.current[evaluator.id]?.indicatorIds ?? [],
}));
// 使用JSON字符串比较确保只有在真正变化时才更新
const currentValue = JSON.stringify(indicatorList);
if (currentValue !== previousValueRef.current) {
previousValueRef.current = currentValue;
onFormDataChange?.({
...formData,
indicatorList,
});
}
}, [evaluators, formData, onFormDataChange]);
if (!taskFormData.userList) return;
setEvaluators(taskFormData.userList);
}, [taskFormData.userList]);
// 暴露给父组件的方法
useImperativeHandle(ref, () => ({
useImperativeHandle(innerRef, () => ({
validate: () => {
if (evaluators.length === 0) {
return {
@ -462,6 +373,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
},
}));
// 选择完
// 获取当前评价人员名称
const getCurrentEvaluatorName = () => {
const evaluator = evaluators.find((e) => e.id === currentUserId);
@ -503,7 +415,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
<Button type="link" onClick={() => handleAssignIndicators(record.id)}>
</Button>
<Button type="link" onClick={() => handleViewAssignment(record.id)}>
<Button type="link" onClick={() => handleViewAssignment(record)}>
</Button>
<Button type="link" onClick={() => handleRemoveEvaluator(record.id)}>
@ -568,7 +480,7 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
</Spin>
</Modal>
{/* 评价指标模板查看弹窗 */}
{/* 设置评价指标分工 */}
<Modal
title="设置评价指标分工"
visible={templateViewModalVisible}
@ -625,6 +537,22 @@ const DivisionStep = forwardRef<any, DivisionStepProps>(({ formData, onFormDataC
</Modal>
</div>
);
});
};
/**
* 连接 Dva model
*/
const ConnectedComponent = connect(
({ supplierTaskManage }: { supplierTaskManage: SupplierTaskModelState }) => ({
supplierTaskManage,
}),
)(DivisionStepComponent);
/**
* 外层转发 ref 到 innerRef
*/
const DivisionStep = forwardRef((props: any, ref) => (
<ConnectedComponent {...props} innerRef={ref} />
));
export default DivisionStep;