import React, { useState, useEffect, forwardRef, useImperativeHandle, useMemo, useCallback } 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 type { CheckboxValueType } from 'antd/es/checkbox/Group'; import EvaluateTemplateTable from '@/components/EvaluateTemplateTable'; import { getTemplateDetail } from '@/servers/api/supplierEvaluate'; // 评价指标类型定义 interface IndicatorItem { id: string; name: string; description: string; } // 组件接收的Props定义 interface DivisionStepProps { formData: any; onFormDataChange?: (values: any) => void; } // 评价方式枚举 // 注意:type值是根据用户是否关联了指标自动计算的,不是由用户直接选择的 // 默认为0(按评价单),当用户关联了指标则为1(按指标) enum EvaluateType { ALL = 0, // 按评价单评价(全部指标) 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(({ formData, onFormDataChange }, ref) => { // 从上一步获取的评价人员列表 const [evaluators, setEvaluators] = useState([]); // 评价人员指标分配数据 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([]); // 获取模板详情 先写死 "1937123786334322688" 省的一步一步操作 const fetchTemplateDetail = async (templateId: string = "1937123786334322688") => { 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); }, []); // 处理行选择变化 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 }; selectedEvaluators.forEach(evaluator => { newAssignments[evaluator.id] = { // 评价类型:如果用户关联了指标则为1(按指标),否则为0(按评价单) type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL, indicatorIds: selectedIndicatorIds, }; }); setIndicatorAssignments(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); }; // 获取当前用户的已分配指标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 = () => { 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 }; newAssignments[currentUserId] = { // 评价类型:如果用户关联了指标则为1(按指标),否则为0(按评价单) type: selectedIndicatorIds.length > 0 ? EvaluateType.INDICATOR : EvaluateType.ALL, indicatorIds: selectedIndicatorIds, }; setIndicatorAssignments(newAssignments); setTemplateViewModalVisible(false); message.success('已设置评价人员指标分工'); }; // 查看评价人员的指标分工 const handleViewAssignment = (userId: string) => { const assignment = indicatorAssignments[userId]; if (!assignment) { message.info('该评价人员尚未设置分工'); return; } const assignedIndicators = indicators.filter(ind => assignment.type === EvaluateType.ALL || assignment.indicatorIds.includes(ind.id) ); Modal.info({ title: '查看评价指标分工', content: (

评价方式: {assignment.type === EvaluateType.ALL ? '按评价单评价' : '按指标评价'}

评价指标:

    {assignedIndicators.map(ind => (
  • {ind.name}
  • ))}
), okText: '确定', }); }; // 删除评价人员 const handleRemoveEvaluator = (userId: string) => { Modal.confirm({ title: '确认删除', content: '确定要删除该评价人员吗?', okText: '确定', cancelText: '取消', onOk: () => { // 更新评价人员列表 setEvaluators(prev => prev.filter(e => e.id !== userId)); // 更新指标分配数据 const newAssignments = { ...indicatorAssignments }; delete newAssignments[userId]; setIndicatorAssignments(newAssignments); message.success('已删除评价人员'); }, }); }; // 初始化:从formData中提取指标分配数据 useEffect(() => { if (formData.indicatorList) { // 如果已有指标分配数据,直接使用 const assignments: any = {}; formData.indicatorList.forEach((item: any) => { assignments[item.userId] = { type: item.type, indicatorIds: item.indicatorIds || [], }; }); setIndicatorAssignments(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 }; let hasNewAssignments = false; evaluators.forEach(evaluator => { if (!indicatorAssignments[evaluator.id]) { newAssignments[evaluator.id] = { type: EvaluateType.ALL, indicatorIds: [], }; hasNewAssignments = true; } }); if (hasNewAssignments) { setIndicatorAssignments(newAssignments); } }, [evaluators, indicatorAssignments]); // 同步数据回表单 - 使用防抖确保不会频繁触发 const previousValueRef = React.useRef(""); useEffect(() => { // 将评价人员列表和指标分配数据同步回表单 const indicatorList = evaluators.map(evaluator => ({ userId: evaluator.id, userName: evaluator.name, type: indicatorAssignments[evaluator.id]?.type || EvaluateType.ALL, indicatorIds: indicatorAssignments[evaluator.id]?.indicatorIds || [], })); // 使用JSON字符串比较确保只有在真正变化时才更新 const currentValue = JSON.stringify(indicatorList); if (currentValue !== previousValueRef.current) { previousValueRef.current = currentValue; onFormDataChange?.({ ...formData, indicatorList, }); } }, [evaluators, indicatorAssignments, formData, onFormDataChange]); // 暴露给父组件的方法 useImperativeHandle(ref, () => ({ validate: () => { if (evaluators.length === 0) { return { valid: false, message: '请先分配评价人员', }; } return { valid: true }; }, })); // 表格列定义 const columns: ColumnsType = [ { title: '姓名', dataIndex: 'name', key: 'name', }, { title: '所属单位', dataIndex: 'company', key: 'company', }, { title: '所属部门', dataIndex: 'department', key: 'department', }, { title: '员工编号', dataIndex: 'employeeNumber', key: 'employeeNumber', }, { title: '是否设置分工', key: 'hasDivision', render: (_: any, record: PersonnelItem) => { const assignment = indicatorAssignments[record.id]; if (!assignment) return 未设置; return 已设置; }, }, { title: '操作', key: 'action', render: (_: any, record: PersonnelItem) => ( ), }, ]; return (
{/* 批量选择指标模板弹窗 */} 取消 , ]} > {templateData.length > 0 ? ( ) : (
{loading ? '加载中...' : '暂无模板数据'}
)}
{/* 评价指标模板查看弹窗 */} 取消 , ]} > {templateData.length > 0 ? ( ) : (
{loading ? '加载中...' : '暂无模板数据'}
)}
); }); export default DivisionStep;