任务管理新增修改添加分工功能

This commit is contained in:
linxd
2025-06-27 11:38:36 +08:00
parent 527637cce3
commit db4533592f
15 changed files with 428 additions and 325 deletions

View File

@ -14,7 +14,10 @@ const { Search } = Input;
*/ */
interface EvaluateTaskPersonnelSelectorProps { interface EvaluateTaskPersonnelSelectorProps {
onSelect: (personnel: API.PersonnelItem[]) => void; // 选择确认后的回调函数 onSelect: (personnel: API.PersonnelItem[]) => void; // 选择确认后的回调函数
onClose: () => void; // 关闭回调函数
selectedPersonnel?: API.PersonnelItem[]; // 已选择的人员列表(用于回显) selectedPersonnel?: API.PersonnelItem[]; // 已选择的人员列表(用于回显)
filter?: boolean; // 是否过滤评价人员
filterUserIds?: string[]; // 过滤评价人员ID列表
} }
/** /**
@ -32,7 +35,10 @@ interface EvaluateTaskPersonnelSelectorProps {
*/ */
const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps> = ({ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps> = ({
onSelect, onSelect,
selectedPersonnel = [] selectedPersonnel = [],
filter = false,
filterUserIds = [],
onClose,
}) => { }) => {
// 搜索关键词 // 搜索关键词
const [keyword, setKeyword] = useState<string>(''); const [keyword, setKeyword] = useState<string>('');
@ -66,6 +72,8 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
pageSize: 100, // 获取足够多的数据 pageSize: 100, // 获取足够多的数据
}, },
keyword: keyword || undefined, keyword: keyword || undefined,
filter,
userIds: filter ? filterUserIds : undefined,
}; };
const response = await getUserList(params); const response = await getUserList(params);
@ -80,6 +88,7 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
userDept: user.userDept, // 用户部门 userDept: user.userDept, // 用户部门
userDeptId: user.userDeptId, // 用户部门ID userDeptId: user.userDeptId, // 用户部门ID
position: '', // API中没有提供职位信息 position: '', // API中没有提供职位信息
isSelected: user.isSelected,
})); }));
setPersonnel(personnelData); setPersonnel(personnelData);
@ -119,6 +128,9 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
setSelectedKeys(selectedRowKeys as string[]); setSelectedKeys(selectedRowKeys as string[]);
}; };
const onCancel = () => {
onClose();
};
/** /**
* 处理确认选择 * 处理确认选择
*/ */
@ -141,7 +153,7 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
title: '部门', title: '部门',
dataIndex: 'userDept', dataIndex: 'userDept',
key: 'userDept', key: 'userDept',
}, }
]; ];
@ -160,9 +172,14 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
</div> </div>
</div> </div>
<Table <Table
// 如果 isSelected = true 则禁用勾选
rowSelection={{ rowSelection={{
selectedRowKeys: selectedKeys, selectedRowKeys: selectedKeys,
onChange: handleSelectChange, onChange: handleSelectChange,
getCheckboxProps: (record) => ({
// 如果 isSelected = true 则禁用勾选
disabled: record.isSelected === true,
}),
}} }}
columns={columns} columns={columns}
dataSource={personnel} dataSource={personnel}
@ -173,7 +190,7 @@ const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps
/> />
<div className="selector-footer"> <div className="selector-footer">
<Space> <Space>
<Button onClick={() => setSelectedKeys([])}></Button> <Button onClick={onCancel}></Button>
<Button type="primary" onClick={handleConfirm}> <Button type="primary" onClick={handleConfirm}>
</Button> </Button>

View File

@ -6,7 +6,7 @@ import type {
TaskDetailResponse TaskDetailResponse
} from '@/servers/dao/supplierEvaluateTask'; } from '@/servers/dao/supplierEvaluateTask';
import type { TaskNotifyLowerUnits } from '@/dicts/supplierTaskDict'; import type { TaskNotifyLowerUnits } from '@/dicts/supplierTaskDict';
import type { PersonnelItem } from '@/servers/dao/supplierEvaluateTask'; import type { PersonnelItem, IndicatorItem, SupplierItem } from '@/servers/dao/supplierEvaluateTask';
// Define the types for dva effects and reducers // Define the types for dva effects and reducers
type Effect = (action: { payload: any }, effects: { call: any; put: any; select: any }) => Generator<any, void, unknown>; type Effect = (action: { payload: any }, effects: { call: any; put: any; select: any }) => Generator<any, void, unknown>;
@ -22,7 +22,7 @@ export interface SupplierTaskModelState {
detailLoading: boolean; // 详情数据加载状态 detailLoading: boolean; // 详情数据加载状态
taskFormData: Partial<TaskAddRequest>; // 任务表单数据 taskFormData: Partial<TaskAddRequest>; // 任务表单数据
taskDetail: TaskDetailData | null; // 任务详情数据 taskDetail: TaskDetailData | null; // 任务详情数据
userList: PersonnelItem[]; // 用户列表 mode: 'add' | 'edit' | 'division'; // 模式
} }
/** /**
@ -39,6 +39,9 @@ export interface SupplierTaskModelType {
nextStep: Effect; // 下一步 nextStep: Effect; // 下一步
prevStep: Effect; // 上一步 prevStep: Effect; // 上一步
resetState: Effect; // 重置状态 resetState: Effect; // 重置状态
setCurrentStep: Effect; // 设置当前步骤
setMode: Effect; // 设置模式
deleteUser: Effect; // 删除用户
}; };
reducers: { reducers: {
saveCurrentStep: Reducer<SupplierTaskModelState>; // 保存当前步骤 saveCurrentStep: Reducer<SupplierTaskModelState>; // 保存当前步骤
@ -46,6 +49,7 @@ export interface SupplierTaskModelType {
saveDetailLoading: Reducer<SupplierTaskModelState>; // 保存详情加载状态 saveDetailLoading: Reducer<SupplierTaskModelState>; // 保存详情加载状态
saveTaskFormData: Reducer<SupplierTaskModelState>; // 保存任务表单数据 saveTaskFormData: Reducer<SupplierTaskModelState>; // 保存任务表单数据
saveTaskDetail: Reducer<SupplierTaskModelState>; // 保存任务详情数据 saveTaskDetail: Reducer<SupplierTaskModelState>; // 保存任务详情数据
saveMode: Reducer<SupplierTaskModelState>; // 保存模式
}; };
} }
@ -63,7 +67,7 @@ const SupplierTaskModel: SupplierTaskModelType = {
detailLoading: false, // 详情数据加载状态 detailLoading: false, // 详情数据加载状态
taskFormData: {}, // 任务表单数据 taskFormData: {}, // 任务表单数据
taskDetail: null, // 任务详情数据 taskDetail: null, // 任务详情数据
userList: [], // 用户列表 mode: 'add', // 模式
}, },
// 副作用处理函数 // 副作用处理函数
@ -94,6 +98,7 @@ const SupplierTaskModel: SupplierTaskModelType = {
evaluateYear: detail.evaluateYear || '', evaluateYear: detail.evaluateYear || '',
categoryId: detail.categoryId || undefined, categoryId: detail.categoryId || undefined,
// 供应商数据转换添加id和name字段用于UI展示 // 供应商数据转换添加id和name字段用于UI展示
selectedSuppliers: detail.blackSupplierVos.map((item) => ({ selectedSuppliers: detail.blackSupplierVos.map((item) => ({
...item, ...item,
@ -110,9 +115,8 @@ const SupplierTaskModel: SupplierTaskModelType = {
// 部门权重 // 部门权重
taskDeptWeightList: detail.taskDeptWeightList || [], taskDeptWeightList: detail.taskDeptWeightList || [],
//设置评价分工table回显 需处理 //设置评价分工table回显 需处理
userList: detail.userList.map((user) => { userList: detail.userList.map((user) => {
const matchedIndicator = detail.indicatorList?.find( const matchedIndicator = detail.indicatorList?.find(
(indicator) => indicator.userId === user.userId (indicator) => indicator.userId === user.userId
); );
@ -124,21 +128,7 @@ const SupplierTaskModel: SupplierTaskModelType = {
}; };
}), }),
// 供应商与评价人员关联,用于分工步骤 需要以userList[]人员为维度,
// 关联出 indicatorList[]指标中的 userId,
// 关联出来的对象中的indicatorIds[]为指标id,
// 对象中的type不需要关注,只在保存时动态修改即可
suppliersWithEvaluators: detail.userList.map((user) => {
const matchedIndicator = detail.indicatorList?.find(
(indicator) => indicator.userId === user.userId
);
return {
...user,
name: user.userName,
id: user.userId,
indicatorIds: matchedIndicator?.indicatorIds || [],
};
}),
}; };
// 保存数据到状态 // 保存数据到状态
@ -255,14 +245,29 @@ const SupplierTaskModel: SupplierTaskModelType = {
})); }));
updatedFormData.selectedSuppliers = suppliersWithEvaluators; updatedFormData.selectedSuppliers = suppliersWithEvaluators;
} }
// 处理评价人员更新 - 更新后要保留原有对象中的indicatorIds
if (payload.userList) {
const existingUserMap = new Map(
(taskFormData.userList || []).map((user: PersonnelItem) => [user.id || user.userId, user])
);
// 处理评价人员更新 - 保持suppliersWithEvaluators和selectedSuppliers同步 updatedFormData.userList = payload.userList.map((newUser: PersonnelItem) => {
if (payload.suppliersWithEvaluators) { const userId = newUser.id || newUser.userId;
const evaluatedSuppliers = payload.suppliersWithEvaluators; const existing = existingUserMap.get(userId);
updatedFormData.suppliersWithEvaluators = evaluatedSuppliers;
updatedFormData.selectedSuppliers = evaluatedSuppliers; // 同步更新selectedSuppliers const indicatorIds =
newUser.indicatorIds && newUser.indicatorIds.length > 0
? newUser.indicatorIds
: existing?.indicatorIds || [];
return {
...newUser,
indicatorIds,
};
});
} }
// 处理部门权重 // 处理部门权重
if (payload.taskDeptWeightList) { if (payload.taskDeptWeightList) {
updatedFormData.taskDeptWeightList = payload.taskDeptWeightList; updatedFormData.taskDeptWeightList = payload.taskDeptWeightList;
@ -272,6 +277,49 @@ const SupplierTaskModel: SupplierTaskModelType = {
// 保存更新后的表单数据 // 保存更新后的表单数据
yield put({ type: 'saveTaskFormData', payload: updatedFormData }); yield put({ type: 'saveTaskFormData', payload: updatedFormData });
}, },
/**
* 删除用户
* @param payload.userId 用户ID
*/
*deleteUser({ payload }: { payload: { userIds: string[] } }, { put, select }: { put: any; select: any }) {
const { userIds } = payload;
if (!userIds || userIds.length === 0) return;
const userIdSet = new Set(userIds.filter(Boolean).map(String));
const { taskFormData } = (yield select((state: any) => state.supplierTaskManage)) as {
taskFormData: TaskAddRequest;
};
const updatedFormData = { ...taskFormData };
// 1. 删除 userList 中的用户
updatedFormData.userList = (updatedFormData.userList || []).filter(
(user: PersonnelItem) => !userIdSet.has(String(user.id || user.userId))
);
// 2. 删除 indicatorList(指标对象) 中该用户的指标
updatedFormData.indicatorList = (updatedFormData.indicatorList || []).filter(
(item: IndicatorItem) => !userIdSet.has(String(item.userId))
);
// 3. 删除 selectedSuppliers(供应商对象) 中 evaluator(评价人员对象) 对象
updatedFormData.selectedSuppliers = (updatedFormData.selectedSuppliers || [])
.map((supplier: SupplierItem) => {
const newEvaluators = (supplier.evaluators || []).filter(
(evaluator: PersonnelItem) => !userIdSet.has(String(evaluator.id))
);
return {
...supplier,
evaluators: newEvaluators,
};
})
.filter((supplier) => (supplier.evaluators || []).length > 0);
// 保存更新
yield put({ type: 'saveTaskFormData', payload: updatedFormData });
},
/** /**
* 下一步 * 下一步
@ -290,6 +338,12 @@ const SupplierTaskModel: SupplierTaskModelType = {
const { currentStep } = (yield select((state: any) => state.supplierTaskManage)) as { currentStep: number }; const { currentStep } = (yield select((state: any) => state.supplierTaskManage)) as { currentStep: number };
yield put({ type: 'saveCurrentStep', payload: currentStep - 1 }); yield put({ type: 'saveCurrentStep', payload: currentStep - 1 });
}, },
/*
设置当前步骤
*/
*setCurrentStep({ payload }: { payload: number }, { put }: { put: any }) {
yield put({ type: 'saveCurrentStep', payload });
},
/** /**
* 重置状态 * 重置状态
@ -307,6 +361,12 @@ const SupplierTaskModel: SupplierTaskModelType = {
payload: 0 payload: 0
}); });
}, },
/**
* 设置模式
*/
*setMode({ payload }: { payload: 'add' | 'edit' | 'division' }, { put }: { put: any }) {
yield put({ type: 'saveMode', payload });
},
}, },
// reducers用于更新状态 // reducers用于更新状态
@ -317,6 +377,12 @@ const SupplierTaskModel: SupplierTaskModelType = {
saveCurrentStep(state, { payload }) { saveCurrentStep(state, { payload }) {
return { ...state, currentStep: payload }; return { ...state, currentStep: payload };
}, },
/**
* 保存模式
*/
saveMode(state, { payload }) {
return { ...state, mode: payload };
},
/** /**
* 保存加载状态 * 保存加载状态
*/ */

View File

@ -36,8 +36,7 @@ const BasicInfoStepComponent = (props: BasicInfoStepProps) => {
// 暴露表单方法给父组件,使用 innerRef // 暴露表单方法给父组件,使用 innerRef
useImperativeHandle(innerRef, () => ({ useImperativeHandle(innerRef, () => ({
validateFields: () => form.validateFields(), validateFields: () => form.validateFields(),
getFieldsValue: () => form.getFieldsValue(), // 删除不必要的方法因为现在使用Dva管理数据
setFieldsValue: (values: any) => form.setFieldsValue(values),
})); }));
// 获取模板列表 // 获取模板列表

View File

@ -14,13 +14,7 @@ import { getTemplateDetail } from '@/servers/api/supplierEvaluate';
import type { Dispatch } from 'umi'; import type { Dispatch } from 'umi';
import { connect } from 'umi'; import { connect } from 'umi';
import type { SupplierTaskModelState } from '@/models/supplierTaskManage'; import type { SupplierTaskModelState } from '@/models/supplierTaskManage';
import type { IndicatorItem } from '@/servers/dao/supplierEvaluateTask';
// 评价指标类型定义
interface IndicatorItem {
id: string;
name: string;
description: string;
}
// 组件接收的Props定义 // 组件接收的Props定义
interface DivisionStepProps { interface DivisionStepProps {
@ -42,19 +36,11 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
const { supplierTaskManage, dispatch, innerRef } = props; const { supplierTaskManage, dispatch, innerRef } = props;
// 从 model 获取表单数据,避免通过 props 层层传递 // 从 model 获取表单数据,避免通过 props 层层传递
const { taskFormData } = supplierTaskManage; const { taskFormData, mode } = supplierTaskManage;
// 从上一步获取的评价人员列表 // 从上一步获取的评价人员列表
const [evaluators, setEvaluators] = useState<PersonnelItem[]>([]); const [evaluators, setEvaluators] = useState<PersonnelItem[]>([]);
// 评价人员指标分配数据
const indicatorAssignments = useRef<{
[userId: string]: {
type: EvaluateType;
indicatorIds: string[];
};
}>({});
// 选中的行keys // 选中的行keys
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
@ -88,27 +74,14 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
// 查看模式下的过滤后指标数据 // 查看模式下的过滤后指标数据
const [filteredIndicators, setFilteredIndicators] = useState<any[]>([]); 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 // 获取当前用户的已分配指标ID
const getCurrentUserSelectedIds = useCallback(() => { const getCurrentUserSelectedIds = useCallback(() => {
// 使用统一的getUserIndicatorIds函数获取当前用户的指标ID if (!currentUserId) return [];
return getUserIndicatorIds(currentUserId);
}, [currentUserId, getUserIndicatorIds]); // 直接从 taskFormData.userList 中获取当前用户的指标ID
const currentUser = taskFormData.userList?.find((user: any) => user.id === currentUserId);
return currentUser?.indicatorIds || [];
}, [currentUserId, taskFormData.userList]);
// 根据指标ID过滤模板数据 // 根据指标ID过滤模板数据
const filterTemplateDataByIds = useCallback((data: any[], indicatorIds: string[]) => { const filterTemplateDataByIds = useCallback((data: any[], indicatorIds: string[]) => {
@ -226,34 +199,55 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
); );
return indicatorNdListIds; return indicatorNdListIds;
}; };
// 处理指标,将处理后的指标放到dva中,同步处理userList,展示table // 处理指标,将处理后的指标放到dva中,同步处理userList,展示table 第二个参数是判断是否是批量设置,
const handleIndicatorAssignment = (indicatorNdListIds: string[]) => { // 如果批量则取 selectedRowKeys(table选中所有user)
// 读取dva中的indicatorList const handleIndicatorAssignment = (indicatorNdListIds: string[], userIds: string[]) => {
const indicatorList = JSON.parse(JSON.stringify(taskFormData?.indicatorList)); // 读取dva中的数据只克隆一次
// 将指标id塞到当前激活的评价人员中 const indicatorList = JSON.parse(JSON.stringify(taskFormData?.indicatorList || []));
indicatorList?.map((item: any) => { const userList = JSON.parse(JSON.stringify(taskFormData?.userList || []));
// 判断当前激活的评价人员和选择评价人构建的userId一直
if (item.userId === currentUserId) { // 批量更新indicatorList和userList
item.indicatorIds = [...new Set([...item.indicatorIds, ...indicatorNdListIds])]; userIds.forEach((userId) => {
} // 更新indicatorList
}); indicatorList.forEach((item: IndicatorItem) => {
// 构建userList带指标id 为了表单回显 if (item.userId === userId) {
const userList = JSON.parse(JSON.stringify(taskFormData?.userList)); item.indicatorIds = [...new Set([...(item.indicatorIds || []), ...indicatorNdListIds])];
userList?.map((item: any) => { }
if (item.id === currentUserId) { });
item.indicatorIds = indicatorNdListIds;
} // 更新userList
userList.forEach((item: PersonnelItem) => {
if (item.id === userId) {
item.indicatorIds = indicatorNdListIds;
}
});
}); });
// 只调用一次updateFormData
updateFormData({ updateFormData({
indicatorList, indicatorList,
userList, userList,
}); });
}; };
// 保存指标分配
const handleSaveIndicatorAssignment = () => {
if (!currentUserId) {
message.warning('未选择评价人员');
return;
}
// 将选择回来的指标提取二级指标id
const indicatorNdListIds = getIndicatorNdListIds(selectedTemplateItems);
handleIndicatorAssignment(indicatorNdListIds, [currentUserId]);
setTemplateViewModalVisible(false);
message.success('已设置评价人员指标分工');
};
// 批量设置指标分工 // 批量设置指标分工
const handleBatchSetDivision = () => { const handleBatchSetDivision = () => {
// 将选择回来的指标提取二级指标id // 将选择回来的指标提取二级指标id
const indicatorNdListIds = getIndicatorNdListIds(batchSelectedTemplateItems); const indicatorNdListIds = getIndicatorNdListIds(batchSelectedTemplateItems);
handleIndicatorAssignment(indicatorNdListIds); const userIds = selectedRowKeys.map((key) => key.toString());
handleIndicatorAssignment(indicatorNdListIds, userIds);
setBatchTemplateModalVisible(false); setBatchTemplateModalVisible(false);
message.success(`已为${selectedRowKeys.length}名评价人员设置分工`); message.success(`已为${selectedRowKeys.length}名评价人员设置分工`);
}; };
@ -278,19 +272,6 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
setSelectedTemplateItems(selectedItems); setSelectedTemplateItems(selectedItems);
}; };
// 保存指标分配
const handleSaveIndicatorAssignment = () => {
if (!currentUserId) {
message.warning('未选择评价人员');
return;
}
// 将选择回来的指标提取二级指标id
const indicatorNdListIds = getIndicatorNdListIds(selectedTemplateItems);
handleIndicatorAssignment(indicatorNdListIds);
setTemplateViewModalVisible(false);
message.success('已设置评价人员指标分工');
};
// 查看评价人员的指标分工 // 查看评价人员的指标分工
const handleViewAssignment = (person: PersonnelItem) => { const handleViewAssignment = (person: PersonnelItem) => {
const assignment = person.indicatorIds; const assignment = person.indicatorIds;
@ -329,35 +310,23 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
// 更新评价人员列表 // 更新评价人员列表
setEvaluators((prev) => prev.filter((e) => e.id !== userId)); setEvaluators((prev) => prev.filter((e) => e.id !== userId));
// 更新指标分配数据 //更新dva中的userList
const newAssignments = { ...indicatorAssignments.current }; dispatch({
delete newAssignments[userId]; type: 'supplierTaskManage/deleteUser',
indicatorAssignments.current = newAssignments; payload: {
userIds: [userId],
},
});
message.success('已删除评价人员'); message.success('已删除评价人员');
}, },
}); });
}; };
// 初始化从formData中提取指标分配数据
useEffect(() => {
if (taskFormData.indicatorList && taskFormData.indicatorList.length > 0) {
// 如果已有指标分配数据,直接使用
const assignments: any = {};
taskFormData.indicatorList.forEach((item: any) => {
assignments[item.userId] = {
type: item.type,
indicatorIds: item.indicatorIds || [],
};
});
indicatorAssignments.current = assignments;
}
}, [taskFormData.indicatorList]);
// 从上一步获取评价人员列表 - 避免频繁更新 // 从上一步获取评价人员列表 - 避免频繁更新
useEffect(() => { useEffect(() => {
if (!taskFormData.userList) return; if (!taskFormData.userList) return;
setEvaluators(taskFormData.userList); setEvaluators(taskFormData.userList as PersonnelItem[]);
}, [taskFormData.userList]); }, [taskFormData.userList]);
// 暴露给父组件的方法 // 暴露给父组件的方法
@ -401,8 +370,7 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
title: '是否设置分工', title: '是否设置分工',
key: 'hasDivision', key: 'hasDivision',
render: (_: any, record: PersonnelItem) => { render: (_: any, record: PersonnelItem) => {
const assignment = indicatorAssignments.current[record.id]; if (!record.indicatorIds || record.indicatorIds.length === 0)
if (!assignment || assignment.indicatorIds.length === 0)
return <Tag color="red"></Tag>; return <Tag color="red"></Tag>;
return <Tag color="green"></Tag>; return <Tag color="green"></Tag>;
}, },
@ -412,38 +380,45 @@ const DivisionStepComponent = (props: DivisionStepProps) => {
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)}> {!record.isSelected && (
<>
</Button> <Button type="link" onClick={() => handleAssignIndicators(record.id)}>
</Button>
<Button type="link" onClick={() => handleRemoveEvaluator(record.id)}>
</Button>
</>
)}
<Button type="link" onClick={() => handleViewAssignment(record)}> <Button type="link" onClick={() => handleViewAssignment(record)}>
</Button> </Button>
<Button type="link" onClick={() => handleRemoveEvaluator(record.id)}>
</Button>
</Space> </Space>
), ),
}, },
]; ];
const rowSelection = {
selectedRowKeys,
onChange: handleSelectChange,
};
return ( return (
<div> <div>
<div style={{ marginBottom: 16 }}> {mode !== 'division' && (
<Button <div style={{ marginBottom: 16 }}>
type="primary" <Button
onClick={handleOpenDivisionModal} type="primary"
disabled={selectedRowKeys.length === 0} onClick={handleOpenDivisionModal}
> disabled={selectedRowKeys.length === 0}
>
</Button>
</div> </Button>
</div>
)}
<Table <Table
rowKey="id" rowKey="id"
rowSelection={{ rowSelection={mode === 'division' ? undefined : rowSelection}
selectedRowKeys,
onChange: handleSelectChange,
}}
columns={columns} columns={columns}
dataSource={evaluators} dataSource={evaluators}
pagination={false} pagination={false}

View File

@ -8,6 +8,8 @@ interface BatchEvaluatorModalProps {
onCancel: () => void; onCancel: () => void;
onSelect: (selectedEvaluators: PersonnelItem[]) => void; onSelect: (selectedEvaluators: PersonnelItem[]) => void;
selectedPersonnel?: PersonnelItem[]; selectedPersonnel?: PersonnelItem[];
filter?: boolean;
filterUserIds?: string[];
} }
const BatchEvaluatorModal: React.FC<BatchEvaluatorModalProps> = ({ const BatchEvaluatorModal: React.FC<BatchEvaluatorModalProps> = ({
@ -15,6 +17,8 @@ const BatchEvaluatorModal: React.FC<BatchEvaluatorModalProps> = ({
onCancel, onCancel,
onSelect, onSelect,
selectedPersonnel = [], selectedPersonnel = [],
filter,
filterUserIds,
}) => { }) => {
return ( return (
<Modal <Modal
@ -28,6 +32,9 @@ const BatchEvaluatorModal: React.FC<BatchEvaluatorModalProps> = ({
<EvaluateTaskPersonnelSelector <EvaluateTaskPersonnelSelector
onSelect={onSelect} onSelect={onSelect}
selectedPersonnel={selectedPersonnel} selectedPersonnel={selectedPersonnel}
filter={filter}
filterUserIds={filterUserIds}
onClose={onCancel}
/> />
</Modal> </Modal>
); );

View File

@ -10,6 +10,8 @@ interface SupplierEvaluatorModalProps {
onSelect: (personnel: PersonnelItem[]) => void; // 选择人员后的回调函数 onSelect: (personnel: PersonnelItem[]) => void; // 选择人员后的回调函数
currentSupplier: SupplierItem | null; // 当前操作的供应商对象 currentSupplier: SupplierItem | null; // 当前操作的供应商对象
mode: ModalMode; // 弹窗模式SELECT(选择) 或 VIEW(查看) mode: ModalMode; // 弹窗模式SELECT(选择) 或 VIEW(查看)
filter?: boolean; // 是否过滤评价人员
filterUserIds?: string[]; // 过滤评价人员ID列表
} }
const SupplierEvaluatorModal: React.FC<SupplierEvaluatorModalProps> = ({ const SupplierEvaluatorModal: React.FC<SupplierEvaluatorModalProps> = ({
@ -18,6 +20,8 @@ const SupplierEvaluatorModal: React.FC<SupplierEvaluatorModalProps> = ({
onSelect, onSelect,
currentSupplier, currentSupplier,
mode, mode,
filter,
filterUserIds,
}) => { }) => {
// 本地保存当前选中的人员,确保在弹窗打开/关闭时能正确处理数据 // 本地保存当前选中的人员,确保在弹窗打开/关闭时能正确处理数据
const [localSelectedPersonnel, setLocalSelectedPersonnel] = useState<PersonnelItem[]>([]); const [localSelectedPersonnel, setLocalSelectedPersonnel] = useState<PersonnelItem[]>([]);
@ -95,7 +99,10 @@ const SupplierEvaluatorModal: React.FC<SupplierEvaluatorModalProps> = ({
<EvaluateTaskPersonnelSelector <EvaluateTaskPersonnelSelector
key={`personnel-selector-${currentSupplier?.id || 'new'}-${visible}`} key={`personnel-selector-${currentSupplier?.id || 'new'}-${visible}`}
onSelect={handleSelect} onSelect={handleSelect}
filter={filter}
filterUserIds={filterUserIds}
selectedPersonnel={localSelectedPersonnel} selectedPersonnel={localSelectedPersonnel}
onClose={onCancel}
/> />
) : ( ) : (
renderEvaluatorList() renderEvaluatorList()

View File

@ -1,14 +1,15 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Table, Space, Button, Tag, Modal,Tooltip } from 'antd'; import { Table, Space, Button, Tag, Modal, Tooltip } from 'antd';
import type { SupplierItem } from '@/servers/types/evaluator'; import type { SupplierItem } from '@/servers/types/evaluator';
interface SupplierTableProps { interface SupplierTableProps {
suppliers: SupplierItem[]; // 供应商数据列表 suppliers: SupplierItem[]; // 供应商数据列表
selectedRowKeys: React.Key[]; // 选中的行keys selectedRowKeys: React.Key[]; // 选中的行keys
onSelectChange: (selectedRowKeys: React.Key[]) => void; // 选择行变化的回调 onSelectChange: (selectedRowKeys: React.Key[]) => void; // 选择行变化的回调
onViewEvaluators: (supplier: SupplierItem) => void; // 查看评价人员的回调 onViewEvaluators: (supplier: SupplierItem) => void; // 查看评价人员的回调
onSelectEvaluators: (supplier: SupplierItem) => void; // 选择评价人员的回调 onSelectEvaluators: (supplier: SupplierItem) => void; // 选择评价人员的回调
onDeleteSupplier: (key: string) => void; // 删除供应商的回调 onDeleteSupplier: (key: string) => void; // 删除供应商的回调
mode?: string; // 模式
} }
const SupplierTable: React.FC<SupplierTableProps> = ({ const SupplierTable: React.FC<SupplierTableProps> = ({
@ -18,6 +19,7 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
onViewEvaluators, onViewEvaluators,
onSelectEvaluators, onSelectEvaluators,
onDeleteSupplier, onDeleteSupplier,
mode,
}) => { }) => {
// 表格行选择配置 // 表格行选择配置
const rowSelection = { const rowSelection = {
@ -42,9 +44,9 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
// 表格列定义 // 表格列定义
const columns = [ const columns = [
{ {
title: '供应商名称', // 列标题 title: '供应商名称', // 列标题
dataIndex: 'supplierName', // 数据字段名 dataIndex: 'supplierName', // 数据字段名
key: 'supplierName', // 列的唯一标识 key: 'supplierName', // 列的唯一标识
}, },
{ {
title: '统一社会信用代码', title: '统一社会信用代码',
@ -68,8 +70,8 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
}, },
{ {
title: '评价人员数', title: '评价人员数',
align: 'center' as const, // 列对齐方式 align: 'center' as const, // 列对齐方式
dataIndex: 'evaluatorCount', // 评价人员数量字段 dataIndex: 'evaluatorCount', // 评价人员数量字段
key: 'evaluatorCount', key: 'evaluatorCount',
}, },
{ {
@ -88,9 +90,13 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
<Button type="link" onClick={() => onSelectEvaluators(record)}> <Button type="link" onClick={() => onSelectEvaluators(record)}>
</Button> </Button>
<Button type="link" onClick={() => showDeleteConfirm(record)}> {mode !== 'division' && (
<>
</Button> <Button type="link" onClick={() => showDeleteConfirm(record)}>
</Button>
</>
)}
</Space> </Space>
), ),
}, },
@ -98,11 +104,11 @@ const SupplierTable: React.FC<SupplierTableProps> = ({
return ( return (
<Table <Table
rowSelection={rowSelection} // 行选择配置 rowSelection={mode === 'division' ? undefined : rowSelection} // 行选择配置
columns={columns} // 列配置 columns={columns} // 列配置
dataSource={suppliers} // 数据源 dataSource={suppliers} // 数据源
pagination={false} // 分页配置,这里禁用了分页 pagination={false} // 分页配置,这里禁用了分页
rowKey="id" // 行的唯一标识字段 rowKey="id" // 行的唯一标识字段
/> />
); );
}; };

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import React, { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react';
import { Card, Button, Space, Form } from 'antd'; import { Card, Button, Space, Form } from 'antd';
import styles from '../supplierTaskManageAdd.less'; import styles from '../supplierTaskManageAdd.less';
import { import {
@ -38,7 +38,7 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
const { supplierTaskManage, dispatch, innerRef } = props; const { supplierTaskManage, dispatch, innerRef } = props;
// 从 model 获取表单数据,避免通过 props 层层传递 // 从 model 获取表单数据,避免通过 props 层层传递
const { taskFormData } = supplierTaskManage; const { taskFormData, mode } = supplierTaskManage;
// 选中的供应商行的key列表用于批量操作 // 选中的供应商行的key列表用于批量操作
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
@ -66,7 +66,15 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
// 表单实例,用于权重设置 // 表单实例,用于权重设置
const [form] = Form.useForm(); const [form] = Form.useForm();
const [filterUserIds, setFilterUserIds] = useState<string[]>([]);
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]);
/** /**
* 暴露表单方法给父组件 * 暴露表单方法给父组件
* 包含验证、获取和设置表单数据的方法 * 包含验证、获取和设置表单数据的方法
@ -88,44 +96,7 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
} }
return Promise.resolve(); return Promise.resolve();
}, }
// 获取表单数据的方法,返回处理后的数据结构
getFieldsValue: () => {
// 构建评价人员列表
const indicatorList = suppliers.flatMap(
(supplier) =>
supplier.evaluators?.map((evaluator: PersonnelItem) => ({
userId: evaluator.id,
type: 0, // type 评价类型(默认0 按评价单 ,当用户关联了指标则为 :1 按指标)
indicatorIds: [],
})) || [],
);
// 构建供应商ID列表
const supplierIds = suppliers.map((supplier) => ({
id: supplier.id,
userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [],
}));
// 返回完整的表单数据
return {
indicatorList,
supplierIds,
suppliersWithEvaluators: suppliers,
taskDeptWeightList,
};
},
// 设置表单数据的方法,通常在编辑模式下使用
setFieldsValue: (values: any) => {
if (values.suppliersWithEvaluators) {
setSuppliers(values.suppliersWithEvaluators);
}
if (values.taskDeptWeightList) {
setTaskDeptWeightList(values.taskDeptWeightList);
}
},
})); }));
/** /**
@ -137,7 +108,7 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
if (taskFormData.selectedSuppliers && taskFormData.selectedSuppliers.length > 0) { if (taskFormData.selectedSuppliers && taskFormData.selectedSuppliers.length > 0) {
// 转换上一步的供应商数据,添加评价人员数量字段 // 转换上一步的供应商数据,添加评价人员数量字段
const suppliersWithEvaluators = taskFormData.selectedSuppliers.map( const suppliersWithEvaluators = taskFormData.selectedSuppliers.map(
(supplier: SupplierItem) => { (supplier) => {
// 确保evaluators字段存在且为数组 // 确保evaluators字段存在且为数组
const evaluators = supplier.evaluators || []; const evaluators = supplier.evaluators || [];
return { return {
@ -226,20 +197,25 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [], userIds: supplier.evaluators?.map((e: PersonnelItem) => e.id) || [],
})); }));
// 构建userList 并去重 // 构建userList 并去重,确保保留 isSelected 为 true 的对象
const userList = Array.from( const userMap = new Map();
new Map( suppliersWithEvaluators
suppliersWithEvaluators .flatMap((s) => s.evaluators || [])
.flatMap(s => s.evaluators || []) .forEach((user) => {
.map(user => [user.id, user]) // 如果已存在此ID的用户且当前用户isSelected为true或者Map中不存在此用户则更新/添加
).values() if (!userMap.has(user.id) || user.isSelected) {
); userMap.set(user.id, user);
// 构建评价人员列表 }
const indicatorList = userList.map((user) => ({ });
userId: user.id, const userList = Array.from(userMap.values());
type: 0, // 默认按评价单评价 (没有指派分工),如果指派了 (就 1 按指标)
indicatorIds: [], // 指标id集合 // 构建评价人员列表
})); const indicatorList = userList.map((user) => ({
...user,
userId: user.id,
type: 0, // 默认按评价单评价 (没有指派分工),如果指派了 (就 1 按指标)
indicatorIds: user.indicatorIds || [], // 指标id集合
}));
// 通过dispatch更新model中的数据 // 通过dispatch更新model中的数据
// 这是组件与Dva model交互的关键 // 这是组件与Dva model交互的关键
@ -251,7 +227,7 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
indicatorList, indicatorList,
userList, userList,
supplierIds, supplierIds,
suppliersWithEvaluators: suppliersWithEvaluators, selectedSuppliers: suppliersWithEvaluators,
}, },
}); });
}; };
@ -342,7 +318,6 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
*/ */
const handleEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => { const handleEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => {
if (!currentSupplier) return; if (!currentSupplier) return;
// 更新当前供应商的评价人员列表 // 更新当前供应商的评价人员列表
const updatedSuppliers = suppliers.map((supplier) => { const updatedSuppliers = suppliers.map((supplier) => {
if (supplier.id === currentSupplier.id) { if (supplier.id === currentSupplier.id) {
@ -420,20 +395,22 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
<div className={styles.evaluatorSelectStep}> <div className={styles.evaluatorSelectStep}>
<Card title="选择评价人员" bordered={false} className="inner-card"> <Card title="选择评价人员" bordered={false} className="inner-card">
{/* 工具栏区域 */} {/* 工具栏区域 */}
<div className={styles.toolbar}> {mode !== 'division' && (
<Space> <div className={styles.toolbar}>
<Button <Space>
type="primary" <Button
onClick={handleBatchSelect} type="primary"
disabled={selectedRowKeys.length === 0} onClick={handleBatchSelect}
> disabled={selectedRowKeys.length === 0}
>
</Button>
<Button onClick={handleWeightSetting} disabled={taskDeptWeightList.length === 0}> </Button>
<Button onClick={handleWeightSetting} disabled={taskDeptWeightList.length === 0}>
</Button>
</Space> </Button>
</div> </Space>
</div>
)}
{/* 供应商表格区域 */} {/* 供应商表格区域 */}
{suppliers.length === 0 ? ( {suppliers.length === 0 ? (
@ -443,6 +420,7 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
) : ( ) : (
<SupplierTable <SupplierTable
suppliers={suppliers} suppliers={suppliers}
mode={mode}
selectedRowKeys={selectedRowKeys} selectedRowKeys={selectedRowKeys}
onSelectChange={setSelectedRowKeys} onSelectChange={setSelectedRowKeys}
onViewEvaluators={handleViewEvaluators} onViewEvaluators={handleViewEvaluators}
@ -455,6 +433,8 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
<BatchEvaluatorModal <BatchEvaluatorModal
visible={batchSelectModalVisible} visible={batchSelectModalVisible}
onCancel={() => setBatchSelectModalVisible(false)} onCancel={() => setBatchSelectModalVisible(false)}
filter={mode === 'division'}
filterUserIds={filterUserIds}
onSelect={handleBatchEvaluatorSelect} onSelect={handleBatchEvaluatorSelect}
/> />
@ -462,6 +442,8 @@ const EvaluatorSelectStepComponent = (props: EvaluatorSelectStepProps) => {
<SupplierEvaluatorModal <SupplierEvaluatorModal
visible={evaluatorModalVisible} visible={evaluatorModalVisible}
onCancel={() => setEvaluatorModalVisible(false)} onCancel={() => setEvaluatorModalVisible(false)}
filter={mode === 'division'}
filterUserIds={filterUserIds}
onSelect={handleEvaluatorSelect} onSelect={handleEvaluatorSelect}
currentSupplier={currentSupplier} currentSupplier={currentSupplier}
mode={modalMode} mode={modalMode}

View File

@ -36,17 +36,7 @@ const SupplierSelectStepComponent = (props: SupplierSelectStepProps) => {
// 这里可以添加自定义验证逻辑 // 这里可以添加自定义验证逻辑
return Promise.resolve(); return Promise.resolve();
}, },
getFieldsValue: () => { // 删除不必要的方法因为现在使用Dva管理数据
return {
selectedSuppliers,
supplierIds: selectedSuppliers.map((supplier: SupplierItem) => ({ id: supplier.id }))
};
},
setFieldsValue: (values: any) => {
if (values.selectedSuppliers) {
setSelectedSuppliers(values.selectedSuppliers);
}
},
})); }));
// 处理供应商选择 // 处理供应商选择

View File

@ -1,32 +1,13 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { import { Button, Table, Space, message, Input, Select, Form, Tooltip, Tag, DatePicker } from 'antd';
Button, import type { TablePaginationConfig } from 'antd/es/table';
Table, import { PlusOutlined, DeleteOutlined, SearchOutlined } from '@ant-design/icons';
Space,
Modal,
message,
Input,
Select,
Form,
Tooltip,
Tag,
TablePaginationConfig,
DatePicker,
Row,
Col,
} from 'antd';
import {
PlusOutlined,
DeleteOutlined,
ExclamationCircleOutlined,
SearchOutlined,
EditOutlined,
EyeOutlined,
} from '@ant-design/icons';
import { history } from 'umi'; import { history } from 'umi';
import { TaskStatus, TaskType, TaskStatusText, TaskStatusColor, TaskTypeText } from '@/dicts/supplierTaskDict'; import { TaskStatus, TaskStatusText, TaskStatusColor } from '@/dicts/supplierTaskDict';
import { getTaskList } from '@/servers/api/supplierEvaluate'; import { getTaskList } from '@/servers/api/supplierEvaluate';
import styles from './supplierTaskManage.less'; import styles from './supplierTaskManage.less';
import type { TaskRequest, TaskRecord, TaskItem } from '@/servers/dao/supplierEvaluateTask';
import type { TaskSearchParams } from '@/servers/dao/supplierEvaluateTask';
const { Option } = Select; const { Option } = Select;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
@ -34,7 +15,7 @@ const { RangePicker } = DatePicker;
const SupplierTaskManage: React.FC = () => { const SupplierTaskManage: React.FC = () => {
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const [taskData, setTaskData] = useState<SupplierEvaluate.TaskRecord[]>([]); const [taskData, setTaskData] = useState<TaskItem[]>([]);
const [pagination, setPagination] = useState<TablePaginationConfig>({ const [pagination, setPagination] = useState<TablePaginationConfig>({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
@ -43,13 +24,18 @@ const SupplierTaskManage: React.FC = () => {
showQuickJumper: true, showQuickJumper: true,
showTotal: (total) => `${total} 条记录`, showTotal: (total) => `${total} 条记录`,
}); });
const [searchParams, setSearchParams] = useState<SupplierEvaluate.TaskSearchParams>({}); const [searchParams, setSearchParams] = useState<TaskSearchParams>({
basePageRequest: {
pageNo: 1,
pageSize: 10,
},
});
// 获取任务列表 // 获取任务列表
const fetchTaskList = async ( const fetchTaskList = async (
current = 1, current = 1,
pageSize = 10, pageSize = 10,
params: SupplierEvaluate.TaskSearchParams = searchParams, params: TaskSearchParams = searchParams,
) => { ) => {
// 更新搜索参数状态 // 更新搜索参数状态
if (params !== searchParams) { if (params !== searchParams) {
@ -59,7 +45,7 @@ const SupplierTaskManage: React.FC = () => {
setLoading(true); setLoading(true);
try { try {
// 构造请求参数 // 构造请求参数
const requestParams: SupplierEvaluate.TaskRequest = { const requestParams: TaskSearchParams = {
basePageRequest: { basePageRequest: {
pageNo: current, pageNo: current,
pageSize: pageSize, pageSize: pageSize,
@ -83,24 +69,7 @@ const SupplierTaskManage: React.FC = () => {
if (response.success) { if (response.success) {
// 处理返回的数据 // 处理返回的数据
const { records, total, current: currentPage, size } = response.data; const { records, total, current: currentPage, size } = response.data;
setTaskData(records);
// 转换数据结构以适应组件
const formattedData = records.map(item => ({
id: item.id || '',
key: item.id || '',
taskName: item.evaluateTheme || '',
taskCode: item.id || '', // 使用id作为临时的taskCode
status: item.status || '',
startTime: item.startTime || '',
endTime: item.endTime || '',
createBy: item.tenantName || '',
// 添加必要的字段以符合TaskRecord类型
taskType: TaskType.REGULAR, // 默认值实际应从API获取
templateName: '评价模板', // 默认值实际应从API获取
createTime: item.startTime || '', // 使用开始时间作为创建时间
}));
setTaskData(formattedData);
setPagination({ setPagination({
...pagination, ...pagination,
current: currentPage, current: currentPage,
@ -120,21 +89,26 @@ const SupplierTaskManage: React.FC = () => {
// 首次加载获取数据 // 首次加载获取数据
useEffect(() => { useEffect(() => {
fetchTaskList(pagination.current, pagination.pageSize, {}); fetchTaskList(pagination.current, pagination.pageSize, searchParams);
}, []); }, []);
// 处理查看 // 处理查看
const handleView = (record: SupplierEvaluate.TaskRecord) => { const handleView = (record: TaskItem) => {
// 跳转到详情页面 // 跳转到详情页面
history.push(`supplierTaskManageDetail?id=${record.id}`); history.push(`supplierTaskManageDetail?id=${record.id}`);
}; };
// 处理编辑 // 处理编辑
const handleEdit = (record: SupplierEvaluate.TaskRecord) => { const handleEdit = (record: TaskItem) => {
// 跳转到编辑页面(复用新增页面) // 跳转到编辑页面(复用新增页面)
history.push(`supplierTaskManageAdd?id=${record.id}&mode=edit`); history.push(`supplierTaskManageAdd?id=${record.id}&mode=edit`);
}; };
// 处理分工
const handleDivision = (record: TaskItem) => {
// 跳转到分工页面
history.push(`supplierTaskManageAdd?id=${record.id}&mode=division`);
};
// 获取状态标签 // 获取状态标签
const getStatusTag = (status: string) => { const getStatusTag = (status: string) => {
@ -151,28 +125,28 @@ const SupplierTaskManage: React.FC = () => {
const columns = [ const columns = [
{ {
title: '序号', title: '序号',
render: (_: any, __: SupplierEvaluate.TaskRecord, index: number) => render: (_: any, __: TaskItem, index: number) =>
(pagination.current! - 1) * pagination.pageSize! + index + 1, (pagination.current! - 1) * pagination.pageSize! + index + 1,
width: 80, width: 80,
}, },
{ {
title: '评价主题', title: '评价主题',
dataIndex: 'taskName', dataIndex: 'evaluateTheme',
key: 'taskName', key: 'evaluateTheme',
width: 200, width: 200,
ellipsis: { ellipsis: {
showTitle: false, showTitle: false,
}, },
render: (taskName: string) => ( render: (evaluateTheme: string) => (
<Tooltip placement="topLeft" title={taskName}> <Tooltip placement="topLeft" title={evaluateTheme}>
{taskName} {evaluateTheme}
</Tooltip> </Tooltip>
), ),
}, },
{ {
title: '发起单位', title: '发起单位',
dataIndex: 'createBy', dataIndex: 'tenantName',
key: 'createBy', key: 'tenantName',
width: 150, width: 150,
}, },
{ {
@ -199,11 +173,17 @@ const SupplierTaskManage: React.FC = () => {
key: 'action', key: 'action',
width: 150, width: 150,
align: 'center' as const, align: 'center' as const,
render: (_: unknown, record: SupplierEvaluate.TaskRecord) => ( render: (_: unknown, record: TaskItem) => (
<Space size="middle"> <Space size="middle">
<Button type="link" onClick={() => handleView(record)}> <Button type="link" onClick={() => handleView(record)}>
</Button> </Button>
{record.division == '1' && (
<Button type="link" onClick={() => handleDivision(record)}>
</Button>
)}
<Button type="link" onClick={() => handleEdit(record)}> <Button type="link" onClick={() => handleEdit(record)}>
</Button> </Button>
@ -227,7 +207,7 @@ const SupplierTaskManage: React.FC = () => {
params.dateRange = [dateRange[0].format('YYYY-MM-DD'), dateRange[1].format('YYYY-MM-DD')]; params.dateRange = [dateRange[0].format('YYYY-MM-DD'), dateRange[1].format('YYYY-MM-DD')];
} }
fetchTaskList(1, pagination.pageSize, params); fetchTaskList(1, pagination.pageSize, searchParams);
}; };
return ( return (
@ -263,7 +243,13 @@ const SupplierTaskManage: React.FC = () => {
icon={<DeleteOutlined />} icon={<DeleteOutlined />}
onClick={() => { onClick={() => {
form.resetFields(); form.resetFields();
fetchTaskList(1, pagination.pageSize, {}); setSearchParams({
basePageRequest: {
pageNo: 1,
pageSize: 10,
},
});
fetchTaskList(1, pagination.pageSize, searchParams);
}} }}
> >
@ -280,6 +266,7 @@ const SupplierTaskManage: React.FC = () => {
<div className={styles.contentArea}> <div className={styles.contentArea}>
<Table <Table
columns={columns} columns={columns}
rowKey="id"
dataSource={taskData} dataSource={taskData}
pagination={pagination} pagination={pagination}
loading={loading} loading={loading}

View File

@ -46,6 +46,7 @@ const SupplierTaskManageAdd: React.FC<PageProps> = ({ supplierTaskManage, dispat
// 判断是否为编辑模式 // 判断是否为编辑模式
const urlParams = getUrlParams(); const urlParams = getUrlParams();
const isEditMode = urlParams.mode === 'edit' && urlParams.id; const isEditMode = urlParams.mode === 'edit' && urlParams.id;
const isDivisionMode = urlParams.mode === 'division' && urlParams.id;
const taskId = urlParams.id || ''; const taskId = urlParams.id || '';
// 创建表单引用,用于访问子组件的表单方法(主要用于验证) // 创建表单引用,用于访问子组件的表单方法(主要用于验证)
@ -62,19 +63,50 @@ const SupplierTaskManageAdd: React.FC<PageProps> = ({ supplierTaskManage, dispat
* 利用useEffect在组件挂载或依赖项变化时触发 * 利用useEffect在组件挂载或依赖项变化时触发
*/ */
useEffect(() => { useEffect(() => {
if (isEditMode && taskId && dispatch) { if ((isEditMode || isDivisionMode) && taskId && dispatch) {
dispatch({
type: 'supplierTaskManage/saveMode',
payload: 'edit',
});
// 编辑模式,获取任务详情 // 编辑模式,获取任务详情
dispatch({ dispatch({
type: 'supplierTaskManage/fetchTaskDetail', type: 'supplierTaskManage/fetchTaskDetail',
payload: { taskId }, payload: { taskId },
}); });
if (isDivisionMode) {
dispatch({
type: 'supplierTaskManage/saveMode',
payload: 'division',
});
dispatch({
type: 'supplierTaskManage/setCurrentStep',
payload: 2,
});
}
} else if (dispatch) { } else if (dispatch) {
dispatch({
type: 'supplierTaskManage/setMode',
payload: 'add',
});
// 新建模式,重置状态 // 新建模式,重置状态
dispatch({ dispatch({
type: 'supplierTaskManage/resetState', type: 'supplierTaskManage/resetState',
}); });
} }
}, [isEditMode, taskId, dispatch]); }, [isEditMode, isDivisionMode, taskId, dispatch]);
/**
* 组件卸载时重置状态
*/
useEffect(() => {
return () => {
if (dispatch) {
dispatch({
type: 'supplierTaskManage/resetState',
});
}
};
}, [dispatch]);
// 步骤配置,定义每个步骤的标题、描述和内容组件 // 步骤配置,定义每个步骤的标题、描述和内容组件
const steps = [ const steps = [
@ -277,7 +309,8 @@ const SupplierTaskManageAdd: React.FC<PageProps> = ({ supplierTaskManage, dispat
{/* 步骤操作按钮 */} {/* 步骤操作按钮 */}
<div className={styles.stepsAction}> <div className={styles.stepsAction}>
<Space> <Space>
{currentStep > 0 && <Button onClick={handlePrev}></Button>} {/* 如果当前是评价分工步骤,则不显示上一步按钮 */}
{currentStep > (isDivisionMode ? 2 : 0) && <Button onClick={handlePrev}></Button>}
{currentStep < steps.length - 1 && ( {currentStep < steps.length - 1 && (
<Button type="primary" onClick={handleNext}> <Button type="primary" onClick={handleNext}>

View File

@ -7,7 +7,7 @@ import type {
TemplateAddRequest, TemplateAddRequest,
TemplateUpdateRequest, TemplateUpdateRequest,
CategoryTreeResponse, CategoryTreeResponse,
TaskRequest, TaskSearchParams,
TaskResponse, TaskResponse,
EvaluateTaskRequest, EvaluateTaskRequest,
EvaluateTaskData, EvaluateTaskData,
@ -151,7 +151,7 @@ export async function getDepartmentList() {
* @param params 查询参数 * @param params 查询参数
* @returns Promise * @returns Promise
*/ */
export async function getTaskList(params: TaskRequest) { export async function getTaskList(params: TaskSearchParams) {
return request<TaskResponse>('/coscoEvaluate/task/getPage', { return request<TaskResponse>('/coscoEvaluate/task/getPage', {
method: 'POST', method: 'POST',
data: params, data: params,

View File

@ -29,6 +29,7 @@ declare namespace API {
userDeptId: string; userDeptId: string;
position?: string; position?: string;
selected?: boolean; selected?: boolean;
isSelected?: boolean;
} }
export interface Department { export interface Department {

View File

@ -140,6 +140,23 @@ export interface CategoryTreeItem {
/** /**
* 任务查询请求 * 任务查询请求
*/ */
// 供应商评价任务记录类型
export interface TaskRecord {
id: string;
taskName: string;
taskCode: string;
taskType: string;
templateName: string;
status: string;
startTime: string;
endTime: string;
createBy: string;
createTime: string;
updateBy?: string;
updateTime?: string;
key?: string;
}
export interface TaskRequest { export interface TaskRequest {
current?: number; current?: number;
pageSize?: number; pageSize?: number;
@ -150,6 +167,15 @@ export interface TaskRequest {
categoryId?: string; categoryId?: string;
status?: string; status?: string;
} }
// 供应商评价任务查询参数
export interface TaskSearchParams {
basePageRequest: API.BasePageRequest;
evaluateTheme?: string;
status?: string;
dateRange?: string[];
startTime?: string;
endTime?: string;
}
/** /**
* 任务查询响应 * 任务查询响应
@ -185,16 +211,7 @@ export interface TaskItem {
createBy: string; createBy: string;
[key: string]: any; [key: string]: any;
} }
/*
人员信息
*/
export interface PersonnelItem {
id: string;
name: string;
position: string;
userDept: string;
userDeptId: string;
}
// 评价结果相关类型 // 评价结果相关类型
/** /**
@ -385,16 +402,24 @@ export interface EvaluateRuleUpdateRequest {
/** /**
* 供应商评价任务详情接口类型定义 * 供应商评价任务详情接口类型定义
*/ */
export interface IndicatorList { export interface IndicatorItem {
indicatorIds: string[]; indicatorIds: string[];
type: number; type: number;
userId: string; userId: string;
} }
export interface User {
/*
人员信息
*/
export interface PersonnelItem {
id: string;
name: string;
userId: string; userId: string;
userName: string; userName: string;
position: string;
userDept: string; userDept: string;
userDeptId: string; userDeptId: string;
indicatorIds?: string[];
} }
/** /**
* 任务详情数据 * 任务详情数据
@ -412,7 +437,7 @@ export interface TaskDetailData {
evaluateTheme: string | null; evaluateTheme: string | null;
evaluateYear: string | null; evaluateYear: string | null;
id: string | null; id: string | null;
indicatorList: IndicatorList[] | null; indicatorList: IndicatorItem[] | null;
lastUpdateTime: string | null; lastUpdateTime: string | null;
startTime: string | null; startTime: string | null;
status: string; status: string;
@ -420,7 +445,7 @@ export interface TaskDetailData {
id: string; id: string;
userIds: string[]; userIds: string[];
}[] | null; }[] | null;
userList: User[]; userList: PersonnelItem[];
suppliers: { suppliers: {
id: string; id: string;
supplierName: string; supplierName: string;
@ -449,7 +474,7 @@ export interface TaskDetailData {
deptName: string; deptName: string;
supplierId: string; supplierId: string;
supplierName: string; supplierName: string;
userList: User[]; userList: PersonnelItem[];
}[], }[],
[property: string]: any; [property: string]: any;
} }
@ -475,6 +500,7 @@ export interface TaskDetailResponse {
// 新增评价任务和修改 请求参数定义 // 新增评价任务和修改 请求参数定义
export type TaskAddRequest = { export type TaskAddRequest = {
id?: string;
/** /**
* 品类限制类型0.通用不限品类、1.限制品类) * 品类限制类型0.通用不限品类、1.限制品类)
*/ */
@ -491,7 +517,7 @@ export type TaskAddRequest = {
* 评价年度 * 评价年度
*/ */
evaluateYear: string; evaluateYear: string;
indicatorList: IndicatorList[]; indicatorList: IndicatorItem[];
/** /**
* 评价开始时间 * 评价开始时间
*/ */
@ -508,7 +534,11 @@ export type TaskAddRequest = {
* 是否下级部门可以添加评价信息 0否1是 * 是否下级部门可以添加评价信息 0否1是
*/ */
taskStatus?: TaskNotifyLowerUnits | null; taskStatus?: TaskNotifyLowerUnits | null;
[property: string]: any; /*
供应商列表
*/
selectedSuppliers?: SupplierItem[];
userList?: PersonnelItem[];
} }
/** /**
* 供应商项 * 供应商项
@ -516,11 +546,13 @@ export type TaskAddRequest = {
export interface SupplierItem { export interface SupplierItem {
id: string; // 供应商ID id: string; // 供应商ID
supplierName: string; // 供应商名称 supplierName: string; // 供应商名称
supplierId?: string; // 供应商ID
socialCreditCode?: string; // 统一社会信用代码 socialCreditCode?: string; // 统一社会信用代码
category?: string; // 品类 category?: string; // 品类
department?: string; // 准入部门 department?: string; // 准入部门
evaluatorCount: number; // 评价人员数量 evaluatorCount?: number; // 评价人员数量
evaluators: User[]; // 评价人员列表 evaluators: PersonnelItem[]; // 评价人员列表
deptName?: string; // 部门名称
// 其他可能的字段 // 其他可能的字段
[key: string]: any; [key: string]: any;
} }

View File

@ -14,6 +14,7 @@ export interface PersonnelItem {
position?: string; // 职位(可选) position?: string; // 职位(可选)
selected?: boolean; // 是否被选中用于UI显示 selected?: boolean; // 是否被选中用于UI显示
indicatorIds?: string[]; // 指标ID列表 indicatorIds?: string[]; // 指标ID列表
isSelected?: boolean; // 是否被选中用于UI显示
// 其他可能的API字段 // 其他可能的API字段
} }