import React, { 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 { ColumnsType } from 'antd/es/table'; import EvaluateTemplateTable from '@/components/EvaluateTemplateTable'; import { getTemplateDetail } from '@/servers/api/supplierEvaluate'; import type { TaskAddRequest } from '@/servers/types/supplierEvaluateTask'; // 评价指标类型定义 interface IndicatorItem { id: string; name: string; description: string; } // 组件接收的Props定义 interface DivisionStepProps { formData: Partial; onFormDataChange?: (values: Partial) => void; } // 评价方式枚举 // 注意:type值是根据用户是否关联了指标自动计算的,不是由用户直接选择的 // 默认为0(按评价单),当用户关联了指标则为1(按指标) enum EvaluateType { ALL = 0, // 按评价单评价(全部指标) INDICATOR = 1, // 按指标评价(部分指标) } const DivisionStep = forwardRef(({ formData, onFormDataChange }, ref) => { // 从上一步获取的评价人员列表 const [evaluators, setEvaluators] = useState([]); // 评价人员指标分配数据 const indicatorAssignments = useRef<{ [userId: string]: { type: EvaluateType; indicatorIds: string[]; }; }>({}); // const [indicatorAssignments, setIndicatorAssignments] = useState<{ // [userId: string]: { // type: EvaluateType; // indicatorIds: string[]; // }; // }>({}); // 选中的行keys const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 指标列表 - 不再直接使用mockIndicators,而是从templateData派生 const [indicators, setIndicators] = useState([]); // 评价指标模板查看弹窗可见性 const [templateViewModalVisible, setTemplateViewModalVisible] = useState(false); // 批量指标设置弹窗可见性 const [batchTemplateModalVisible, setBatchTemplateModalVisible] = useState(false); // 批量选择的指标 const [batchSelectedIndicators, setBatchSelectedIndicators] = useState([]); // 批量选择的模板项 const [batchSelectedTemplateItems, setBatchSelectedTemplateItems] = useState([]); // 当前查看的用户ID const [currentUserId, setCurrentUserId] = useState(''); // 模板数据 const [templateData, setTemplateData] = useState([]); // 加载状态 const [loading, setLoading] = useState(false); // 选中的指标项 const [selectedTemplateItems, setSelectedTemplateItems] = useState([]); // 查看指标分工弹窗可见性 const [viewModalVisible, setViewModalVisible] = useState(false); // 查看模式下的过滤后指标数据 const [filteredIndicators, setFilteredIndicators] = useState([]); // 统一获取用户指标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" 省的一步一步操作 const fetchTemplateDetail = async (templateId: string) => { if (!templateId) return; try { setLoading(true); const res = await getTemplateDetail(templateId); if (res.success && res.data) { // 直接设置指标数据,无需转换 if (res.data.indicatorStList && res.data.indicatorStList.length > 0) { setTemplateData(res.data.indicatorStList); // 更新指标列表 const newIndicators = res.data.indicatorStList.map((item: any) => ({ id: item.id, name: item.baseIndicator, description: item.descIndicator || '', })); // 更新indicators状态 setIndicators(newIndicators); } } else { message.error(res.message || '获取模板详情失败'); } } catch (error) { console.error('获取模板详情失败:', error); message.error('获取模板详情失败'); } finally { setLoading(false); } }; // 监听templateId变化,获取模板详情 useEffect(() => { fetchTemplateDetail(formData.templateId as string); }, []); // 处理行选择变化 const handleSelectChange = (newSelectedRowKeys: React.Key[]) => { setSelectedRowKeys(newSelectedRowKeys); }; // 打开指标分工弹窗 const handleOpenDivisionModal = () => { if (selectedRowKeys.length === 0) { message.warning('请先选择评价人员'); return; } // 直接显示批量模板选择弹窗 setBatchTemplateModalVisible(true); // 重置已选中的模板项 setBatchSelectedTemplateItems([]); }; // 处理批量模板指标选择 const handleBatchTemplateItemsSelect = (selectedItems: any[]) => { setBatchSelectedTemplateItems(selectedItems); }; // 关闭批量模板选择弹窗 const handleCloseBatchTemplateModal = () => { setBatchTemplateModalVisible(false); }; // 批量设置指标分工 const handleBatchSetDivision = () => { // 获取选中的评价人员 const selectedEvaluators = evaluators.filter((evaluator) => selectedRowKeys.includes(evaluator.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); }); } }); // 更新指标分配数据 const newAssignments = { ...indicatorAssignments.current }; selectedEvaluators.forEach((evaluator) => { newAssignments[evaluator.id] = { // 评价类型:如果用户关联了指标则为1(按指标),否则为0(按评价单) type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL, indicatorIds: selectedIndicatorIds, }; }); indicatorAssignments.current = newAssignments; setBatchTemplateModalVisible(false); message.success(`已为${selectedRowKeys.length}名评价人员设置分工`); }; // 处理单个评价人员的指标分工 const handleAssignIndicators = (userId: string) => { setCurrentUserId(userId); // 重置已选中的指标项 setSelectedTemplateItems([]); // 打开模态框 setTemplateViewModalVisible(true); }; // 关闭模板查看模态框 const handleCloseTemplateViewModal = () => { setTemplateViewModalVisible(false); }; // 处理模板指标选择 const handleTemplateItemsSelect = (selectedItems: any[]) => { console.log(selectedItems); setSelectedTemplateItems(selectedItems); }; // 保存指标分配 const handleSaveIndicatorAssignment = () => { if (!currentUserId) { 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; setTemplateViewModalVisible(false); message.success('已设置评价人员指标分工'); }; // 查看评价人员的指标分工 const handleViewAssignment = (userId: string) => { const assignment = indicatorAssignments.current[userId]; if (!assignment) { message.info('该评价人员尚未设置分工'); return; } setCurrentUserId(userId); setLoading(true); // 获取该评价人员的指标ID const indicatorIds = getUserIndicatorIds(userId); // 过滤模板数据 const filtered = filterTemplateDataByIds(templateData, indicatorIds); setFilteredIndicators(filtered); setLoading(false); setViewModalVisible(true); }; // 关闭查看模态框 const handleCloseViewModal = () => { setViewModalVisible(false); }; // 删除评价人员 const handleRemoveEvaluator = (userId: string) => { Modal.confirm({ title: '确认删除', content: '确定要删除该评价人员吗?', okText: '确定', cancelText: '取消', onOk: () => { // 更新评价人员列表 setEvaluators((prev) => prev.filter((e) => e.id !== userId)); // 更新指标分配数据 const newAssignments = { ...indicatorAssignments.current }; delete newAssignments[userId]; indicatorAssignments.current = newAssignments; message.success('已删除评价人员'); }, }); }; // 初始化:从formData中提取指标分配数据 useEffect(() => { if (formData.indicatorList && formData.indicatorList.length > 0) { // 如果已有指标分配数据,直接使用 const assignments: any = {}; formData.indicatorList.forEach((item: any) => { assignments[item.userId] = { type: item.type, indicatorIds: item.indicatorIds || [], }; }); indicatorAssignments.current = assignments; } }, [formData.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(''); 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]); // 暴露给父组件的方法 useImperativeHandle(ref, () => ({ validate: () => { if (evaluators.length === 0) { return { valid: false, message: '请先分配评价人员', }; } return { valid: true }; }, })); // 获取当前评价人员名称 const getCurrentEvaluatorName = () => { const evaluator = evaluators.find((e) => e.id === currentUserId); return evaluator ? evaluator.name : currentUserId; }; // 表格列定义 const columns: ColumnsType = [ { title: '姓名', dataIndex: 'name', key: 'name', }, { title: '所属部门', dataIndex: 'userDept', key: 'userDept', }, { title: '员工编号', dataIndex: 'id', key: 'id', }, { title: '是否设置分工', key: 'hasDivision', render: (_: any, record: PersonnelItem) => { const assignment = indicatorAssignments.current[record.id]; if (!assignment || assignment.indicatorIds.length === 0) return 未设置; return 已设置; }, }, { title: '操作', key: 'action', render: (_: any, record: PersonnelItem) => ( ), }, ]; return (
{/* 批量选择指标模板弹窗 */} 取消 , , ]} > {templateData.length > 0 ? ( ) : (
{loading ? '加载中...' : '暂无模板数据'}
)}
{/* 评价指标模板查看弹窗 */} 取消 , , ]} > {templateData.length > 0 ? ( ) : (
{loading ? '加载中...' : '暂无模板数据'}
)}
{/* 查看评价人员指标分工弹窗 */} 关闭 , ]} > {filteredIndicators.length > 0 ? ( ) : (
{loading ? '加载中...' : '暂无指标分工数据'}
)}
); }); export default DivisionStep;