import React, { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react'; import { Card, Button, Space, Form } from 'antd'; import styles from '../supplierAnnualTaskManageAdd.less'; import { SupplierTable, BatchEvaluatorModal, SupplierEvaluatorModal, WeightSettingModal, } from './EvaluatorComponents'; import { ModalMode } from '@/servers/types/evaluator'; import type { PersonnelItem, SupplierItem } from '@/servers/types/evaluator'; import type { DeptWeightItem } from '@/servers/dao/supplierEvaluateTask'; import type { Dispatch } from 'umi'; import { connect } from 'umi'; import type { SupplierTaskModelState } from '@/models/supplierAnnualTaskManage'; /** * 组件接收的Props接口 * supplierAnnualTaskManage: Dva model 状态 * dispatch: Dva 的 dispatch 函数,用于触发 action * innerRef: 内部 ref 用于暴露方法给父组件 */ interface EvaluatorSelectStepProps { supplierAnnualTaskManage: SupplierTaskModelState; dispatch: Dispatch; innerRef?: any; // 使用 innerRef 作为属性名 } /** * 评价人员选择步骤组件 * 主要功能:选择供应商评价人员,设置评分单位权重 * 数据流转: * 1. 从上一步获取供应商数据(通过 model.taskFormData) * 2. 组织评价人员列表并维护到本地状态 * 3. 通过 dispatch 将更新的数据同步回 model */ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => { const { supplierAnnualTaskManage, dispatch, innerRef } = props; // 从 model 获取表单数据,避免通过 props 层层传递 const { taskFormData, mode } = supplierAnnualTaskManage; // 选中的供应商行的key列表,用于批量操作 const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 供应商列表数据,包含评价人员信息(从Dva model获取初始数据,维护在本地状态) const [suppliers, setSuppliers] = useState([]); // 批量选择模态框的可见性控制 const [batchSelectModalVisible, setBatchSelectModalVisible] = useState(false); // 权重设置模态框的可见性控制 const [weightSettingModalVisible, setWeightSettingModalVisible] = useState(false); // 评价人员选择/查看模态框的可见性控制 const [evaluatorModalVisible, setEvaluatorModalVisible] = useState(false); // 当前操作的供应商对象,用于评价人员的选择和查看 const [currentSupplier, setCurrentSupplier] = useState(null); // 模态框模式:SELECT(选择模式) 或 VIEW(查看模式) const [modalMode, setModalMode] = useState(ModalMode.SELECT); // 权重单位列表,根据评价人员部门动态生成 const [taskDeptWeightList, setTaskDeptWeightList] = useState([]); // 表单实例,用于权重设置 const [form] = Form.useForm(); const [filterUserIds, setFilterUserIds] = useState([]); useEffect(() => { if (mode === 'division' && taskFormData.userList && taskFormData.userList.length > 0) { const filterUserIdsaa = taskFormData.userList .map((user: PersonnelItem) => (user.isSelected === true ? user.id : null)) .filter((id: string | null) => id !== null); setFilterUserIds(filterUserIdsaa); } }, [mode, taskFormData.userList]); /** * 暴露表单方法给父组件 * 包含验证、获取和设置表单数据的方法 */ useImperativeHandle(innerRef, () => ({ validateFields: () => { // 自定义验证逻辑 if (suppliers.length === 0) { return Promise.reject('请至少添加一个供应商'); } // 检查是否每个供应商都有评价人员 const hasNoEvaluator = suppliers.some( (supplier) => !supplier.evaluators || supplier.evaluators.length === 0, ); if (hasNoEvaluator) { return Promise.reject('存在未分配评价人员的供应商'); } return Promise.resolve(); } })); /** * 从上一步获取供应商数据 * 使用 useEffect 监听 taskFormData 变化,确保任何来自 model 的数据变更都能被捕获 */ useEffect(() => { // 从Dva model中获取上一步选择的供应商数据 if (taskFormData.selectedSuppliers && taskFormData.selectedSuppliers.length > 0) { // 转换上一步的供应商数据,添加评价人员数量字段 const suppliersWithEvaluators = taskFormData.selectedSuppliers.map( (supplier) => { // 确保evaluators字段存在且为数组 const evaluators = supplier.evaluators || []; return { ...supplier, userDept: supplier.userDept || '采购部', // 设置默认部门 evaluatorCount: evaluators.length, evaluators: evaluators, }; }, ); // 更新本地供应商状态 setSuppliers(suppliersWithEvaluators); } else { // 没有选择供应商,清空供应商列表 setSuppliers([]); } }, [taskFormData]); // 依赖于 taskFormData,当 model 数据变化时重新计算 /** * 当选择的人员变化时,更新权重单位列表 * 根据所有评价人员的部门信息,动态生成权重单位列表 */ useEffect(() => { // 从所有供应商的评价人员中提取部门信息 const allDepartments: PersonnelItem[] = []; suppliers.forEach((supplier) => { if (supplier.evaluators && supplier.evaluators.length > 0) { supplier.evaluators.forEach((evaluator) => { if (evaluator.userDept) { allDepartments.push(evaluator); } }); } }); // 去重部门列表 - 根据部门ID去重 const departmentMap = new Map(); allDepartments.forEach((dept) => { if (dept.userDeptId && !departmentMap.has(dept.userDeptId)) { departmentMap.set(dept.userDeptId, dept); } }); const uniqueDepartments = Array.from(departmentMap.values()); // 如果有部门数据,生成权重单位列表 if (uniqueDepartments.length > 0) { const newTaskDeptWeightList: DeptWeightItem[] = uniqueDepartments.map((dept) => ({ weightDept: dept.userDeptId || '', weightValue: '0', // 默认权重为0 weightDeptName: dept.userDept || '', })); // 更新权重单位列表,保留原有权重值 setTaskDeptWeightList((prevList) => { const prevValuesMap = new Map(prevList.map((item) => [item.weightDept, item.weightValue])); return newTaskDeptWeightList.map((item) => ({ ...item, weightValue: prevValuesMap.get(item.weightDept) || '0', // 如果有原来的权重值则保留 })); }); } }, [suppliers]); // 依赖于suppliers,当选择的供应商或其评价人员变化时重新计算 /** * 更新表单数据 * 将本地状态同步到 Dva model * @param updatedData 要更新的部分数据 */ const updateFormData = (updatedData: any) => { // 结构 更新数据中的suppliersWithEvaluators const { suppliersWithEvaluators }: { suppliersWithEvaluators: SupplierItem[] } = updatedData; // 构建供应商ID列表 const supplierIds = suppliersWithEvaluators.map((supplier) => ({ id: supplier.id, userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [], })); // 构建userList 并去重,确保保留 isSelected 为 true 的对象 const userMap = new Map(); suppliersWithEvaluators .flatMap((s) => s.evaluators || []) .forEach((user) => { // 如果已存在此ID的用户且当前用户isSelected为true,或者Map中不存在此用户,则更新/添加 if (!userMap.has(user.id) || user.isSelected) { userMap.set(user.id, user); } }); // 通过dispatch更新model中的数据 // 这是组件与Dva model交互的关键 dispatch({ type: 'supplierAnnualTaskManage/updateFormData', // action类型 payload: { // action数据 ...updatedData, supplierIds, selectedSuppliers: suppliersWithEvaluators, }, }); }; /** * 处理批量选择按钮点击事件 * 打开批量选择评价人员模态框 */ const handleBatchSelect = () => { if (selectedRowKeys.length === 0) return; setBatchSelectModalVisible(true); }; /** * 处理设置评分单位权重按钮点击事件 * 打开权重设置模态框 */ const handleWeightSetting = () => { // 将权重数据转换为表单初始值 form.setFieldsValue({ taskDeptWeightList: taskDeptWeightList.reduce((acc, item) => { acc[item.weightDept] = parseInt(item.weightValue, 10) || 0; return acc; }, {} as Record), }); setWeightSettingModalVisible(true); }; /** * 保存权重设置 * 更新本地权重数据并同步到 Dva model */ const handleSaveWeights = () => { form.validateFields().then((values) => { // 将表单值转换回权重列表格式 const updatedTaskDeptWeightList = taskDeptWeightList.map((item) => ({ ...item, weightValue: values.taskDeptWeightList[item.weightDept].toString(), })); // 更新本地状态 setTaskDeptWeightList(updatedTaskDeptWeightList); // 同步到Dva model updateFormData({ suppliersWithEvaluators: suppliers, taskDeptWeightList: updatedTaskDeptWeightList, }); setWeightSettingModalVisible(false); }); }; /** * 处理选择评价人员按钮点击事件 * 打开评价人员选择模态框 * @param supplier 当前选中的供应商 */ const handleSelectEvaluators = (supplier: SupplierItem) => { setCurrentSupplier(supplier); setModalMode(ModalMode.SELECT); setEvaluatorModalVisible(true); }; /** * 处理查看评价人员按钮点击事件 * 打开评价人员查看模态框 * @param supplier 当前选中的供应商 */ const handleViewEvaluators = (supplier: SupplierItem) => { // 查找完整的供应商数据(包括evaluators) const fullSupplier = suppliers.find((s) => s.id === supplier.id); if (fullSupplier) { setCurrentSupplier(fullSupplier); } else { setCurrentSupplier(supplier); } setModalMode(ModalMode.VIEW); setEvaluatorModalVisible(true); }; /** * 处理评价人员选择确认 * 更新供应商的评价人员列表并同步到 Dva model * @param selectedEvaluators 选中的评价人员列表 */ const handleEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => { if (!currentSupplier) return; // 更新当前供应商的评价人员列表 const updatedSuppliers = suppliers.map((supplier) => { if (supplier.id === currentSupplier.id) { const updated = { ...supplier, evaluators: selectedEvaluators, evaluatorCount: selectedEvaluators.length, }; return updated; } return supplier; }); // 更新本地状态 setSuppliers(updatedSuppliers); // 同步到Dva model updateFormData({ suppliersWithEvaluators: updatedSuppliers }); // 关闭模态框 setEvaluatorModalVisible(false); }; /** * 处理批量选择评价人员确认 * 批量更新供应商的评价人员列表并同步到 Dva model * @param selectedEvaluators 选中的评价人员列表 */ const handleBatchEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => { if (selectedRowKeys.length === 0) return; // 更新所有选中供应商的评价人员列表 const updatedSuppliers = suppliers.map((supplier) => { if (selectedRowKeys.includes(supplier.id)) { return { ...supplier, evaluators: selectedEvaluators, evaluatorCount: selectedEvaluators.length, }; } return supplier; }); // 更新本地状态 setSuppliers(updatedSuppliers); // 同步到Dva model updateFormData({ suppliersWithEvaluators: updatedSuppliers }); // 关闭模态框 setBatchSelectModalVisible(false); }; /** * 处理删除供应商 * 从供应商列表中删除指定供应商并同步到 Dva model * @param key 供应商ID */ const handleDeleteSupplier = (key: string) => { // 过滤掉要删除的供应商 const updatedSuppliers = suppliers.filter((item) => item.id !== key); // 更新本地状态 setSuppliers(updatedSuppliers); // 同步到Dva model updateFormData({ suppliersWithEvaluators: updatedSuppliers }); // 更新选中行,移除已删除的供应商 setSelectedRowKeys((prevKeys) => prevKeys.filter((k) => k !== key)); }; // 渲染组件 return (
{/* 工具栏区域 */} {mode !== 'division' && (
)} {/* 供应商表格区域 */} {suppliers.length === 0 ? (
请先在上一步选择供应商
) : ( )} {/* 批量选择评价人员弹窗 */} setBatchSelectModalVisible(false)} filter={mode === 'division'} filterUserIds={filterUserIds} onSelect={handleBatchEvaluatorSelect} /> {/* 单个供应商评价人员弹窗 */} setEvaluatorModalVisible(false)} filter={mode === 'division'} filterUserIds={filterUserIds} onSelect={handleEvaluatorSelect} currentSupplier={currentSupplier} mode={modalMode} /> {/* 权重设置弹窗 */} setWeightSettingModalVisible(false)} onOk={handleSaveWeights} taskDeptWeightList={taskDeptWeightList} form={form} />
); }; /** * 连接 Dva model * 将 model 中的状态映射到组件 props */ const ConnectedComponent = connect( ({ supplierAnnualTaskManage }: { supplierAnnualTaskManage: SupplierTaskModelState }) => ({ supplierAnnualTaskManage, }), )(EvaluatorSelectStepComponent); /** * 外层转发 ref 到 innerRef */ const EvaluatorSelectStep = forwardRef((props: any, ref) => ( )); export default EvaluatorSelectStep;