2025-06-26 18:14:41 +08:00
|
|
|
|
import { message } from 'antd';
|
|
|
|
|
import { addTask, getTaskDetail } from '@/servers/api/supplierEvaluate';
|
|
|
|
|
import type {
|
|
|
|
|
TaskDetailData,
|
|
|
|
|
TaskAddRequest,
|
|
|
|
|
TaskDetailResponse
|
|
|
|
|
} from '@/servers/dao/supplierEvaluateTask';
|
|
|
|
|
import type { TaskNotifyLowerUnits } from '@/dicts/supplierTaskDict';
|
2025-06-27 11:38:36 +08:00
|
|
|
|
import type { PersonnelItem, IndicatorItem, SupplierItem } from '@/servers/dao/supplierEvaluateTask';
|
2025-06-26 18:14:41 +08:00
|
|
|
|
|
|
|
|
|
// 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 Reducer<S> = (state: S, action: { payload: any }) => S;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 供应商任务管理模型状态接口
|
|
|
|
|
* 定义了整个模型的状态结构
|
|
|
|
|
*/
|
|
|
|
|
export interface SupplierTaskModelState {
|
|
|
|
|
currentStep: number; // 当前步骤索引,从0开始
|
|
|
|
|
loading: boolean; // 提交加载状态
|
|
|
|
|
detailLoading: boolean; // 详情数据加载状态
|
|
|
|
|
taskFormData: Partial<TaskAddRequest>; // 任务表单数据
|
|
|
|
|
taskDetail: TaskDetailData | null; // 任务详情数据
|
2025-06-27 11:38:36 +08:00
|
|
|
|
mode: 'add' | 'edit' | 'division'; // 模式
|
2025-06-26 18:14:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 供应商任务管理模型类型接口
|
|
|
|
|
* 定义了模型的命名空间、状态、副作用和reducers
|
|
|
|
|
*/
|
|
|
|
|
export interface SupplierTaskModelType {
|
|
|
|
|
namespace: 'supplierTaskManage'; // 模型命名空间
|
|
|
|
|
state: SupplierTaskModelState; // 模型状态
|
|
|
|
|
effects: {
|
|
|
|
|
fetchTaskDetail: Effect; // 获取任务详情
|
|
|
|
|
submitTaskData: Effect; // 提交任务数据
|
|
|
|
|
updateFormData: Effect; // 更新表单数据
|
|
|
|
|
nextStep: Effect; // 下一步
|
|
|
|
|
prevStep: Effect; // 上一步
|
|
|
|
|
resetState: Effect; // 重置状态
|
2025-06-27 11:38:36 +08:00
|
|
|
|
setCurrentStep: Effect; // 设置当前步骤
|
|
|
|
|
setMode: Effect; // 设置模式
|
|
|
|
|
deleteUser: Effect; // 删除用户
|
2025-06-26 18:14:41 +08:00
|
|
|
|
};
|
|
|
|
|
reducers: {
|
|
|
|
|
saveCurrentStep: Reducer<SupplierTaskModelState>; // 保存当前步骤
|
|
|
|
|
saveLoading: Reducer<SupplierTaskModelState>; // 保存加载状态
|
|
|
|
|
saveDetailLoading: Reducer<SupplierTaskModelState>; // 保存详情加载状态
|
|
|
|
|
saveTaskFormData: Reducer<SupplierTaskModelState>; // 保存任务表单数据
|
|
|
|
|
saveTaskDetail: Reducer<SupplierTaskModelState>; // 保存任务详情数据
|
2025-06-27 11:38:36 +08:00
|
|
|
|
saveMode: Reducer<SupplierTaskModelState>; // 保存模式
|
2025-06-26 18:14:41 +08:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 供应商任务管理模型
|
|
|
|
|
* 用于管理供应商评价任务的添加、编辑流程和数据
|
|
|
|
|
*/
|
|
|
|
|
const SupplierTaskModel: SupplierTaskModelType = {
|
|
|
|
|
namespace: 'supplierTaskManage',
|
|
|
|
|
|
|
|
|
|
// 初始状态
|
|
|
|
|
state: {
|
|
|
|
|
currentStep: 0, // 当前步骤,默认为第一步
|
|
|
|
|
loading: false, // 提交加载状态
|
|
|
|
|
detailLoading: false, // 详情数据加载状态
|
|
|
|
|
taskFormData: {}, // 任务表单数据
|
|
|
|
|
taskDetail: null, // 任务详情数据
|
2025-06-27 11:38:36 +08:00
|
|
|
|
mode: 'add', // 模式
|
2025-06-26 18:14:41 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 副作用处理函数
|
|
|
|
|
effects: {
|
|
|
|
|
/**
|
|
|
|
|
* 获取任务详情
|
|
|
|
|
* @param payload.taskId 任务ID
|
|
|
|
|
*/
|
|
|
|
|
*fetchTaskDetail({ payload }: { payload: { taskId: string } }, { call, put }: { call: any; put: any }) {
|
|
|
|
|
const { taskId } = payload;
|
|
|
|
|
yield put({ type: 'saveDetailLoading', payload: true });
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 调用API获取任务详情
|
|
|
|
|
const response = (yield call(getTaskDetail, taskId)) as TaskDetailResponse;
|
|
|
|
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
const detail: TaskDetailData = response.data;
|
|
|
|
|
|
|
|
|
|
// 转换任务详情数据为表单数据结构
|
|
|
|
|
const taskFormData: Partial<TaskAddRequest> = {
|
|
|
|
|
id: detail.id || '',
|
|
|
|
|
evaluateTheme: detail.evaluateTheme || '',
|
|
|
|
|
startTime: detail.startTime || '',
|
|
|
|
|
endTime: detail.endTime || '',
|
|
|
|
|
templateId: detail.templateId || '',
|
|
|
|
|
categoryLimitation: detail.categoryLimitation || '0',
|
|
|
|
|
evaluateYear: detail.evaluateYear || '',
|
|
|
|
|
categoryId: detail.categoryId || undefined,
|
|
|
|
|
|
2025-06-27 11:38:36 +08:00
|
|
|
|
|
2025-06-26 18:14:41 +08:00
|
|
|
|
// 供应商数据转换,添加id和name字段用于UI展示
|
|
|
|
|
selectedSuppliers: detail.blackSupplierVos.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
id: item.supplierId,
|
|
|
|
|
name: item.supplierName,
|
|
|
|
|
evaluators: item.userList,
|
|
|
|
|
})),
|
|
|
|
|
|
|
|
|
|
// 指标列表
|
|
|
|
|
indicatorList: detail.indicatorList || [],
|
|
|
|
|
|
|
|
|
|
// 供应商IDs与用户IDs
|
|
|
|
|
supplierIds: detail.supplierIds || [],
|
|
|
|
|
|
|
|
|
|
// 部门权重
|
|
|
|
|
taskDeptWeightList: detail.taskDeptWeightList || [],
|
|
|
|
|
//设置评价分工table回显 需处理
|
2025-06-27 11:38:36 +08:00
|
|
|
|
userList: detail.userList.map((user) => {
|
2025-06-26 18:14:41 +08:00
|
|
|
|
const matchedIndicator = detail.indicatorList?.find(
|
|
|
|
|
(indicator) => indicator.userId === user.userId
|
|
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
...user,
|
|
|
|
|
name: user.userName,
|
|
|
|
|
id: user.userId,
|
|
|
|
|
indicatorIds: matchedIndicator?.indicatorIds || [],
|
|
|
|
|
};
|
|
|
|
|
}),
|
|
|
|
|
|
2025-06-27 11:38:36 +08:00
|
|
|
|
|
2025-06-26 18:14:41 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 保存数据到状态
|
|
|
|
|
yield put({ type: 'saveTaskFormData', payload: taskFormData });
|
|
|
|
|
yield put({ type: 'saveTaskDetail', payload: detail });
|
|
|
|
|
} else {
|
|
|
|
|
message.error(response.message || '获取任务详情失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('获取任务详情失败:', error);
|
|
|
|
|
message.error('获取任务详情失败');
|
|
|
|
|
} finally {
|
|
|
|
|
yield put({ type: 'saveDetailLoading', payload: false });
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交任务数据
|
|
|
|
|
* @param payload.taskStatus 任务状态
|
|
|
|
|
* @param payload.isEditMode 是否为编辑模式
|
|
|
|
|
* @param payload.taskId 任务ID(编辑模式必须)
|
|
|
|
|
* @param payload.onSuccess 成功回调函数
|
|
|
|
|
*/
|
|
|
|
|
*submitTaskData(
|
|
|
|
|
{ payload }: { payload: { taskStatus: TaskNotifyLowerUnits | null; isEditMode: boolean; taskId: string; onSuccess?: () => void } },
|
|
|
|
|
{ call, put, select }: { call: any; put: any; select: any }
|
|
|
|
|
) {
|
|
|
|
|
const { taskStatus, isEditMode, taskId, onSuccess } = payload;
|
|
|
|
|
yield put({ type: 'saveLoading', payload: true });
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 获取表单数据
|
|
|
|
|
const { taskFormData } = (yield select((state: any) => state.supplierTaskManage)) as { taskFormData: TaskAddRequest };
|
|
|
|
|
|
|
|
|
|
// 构建提交数据
|
|
|
|
|
let submitData: TaskAddRequest = {
|
|
|
|
|
evaluateTheme: taskFormData.evaluateTheme || '',
|
|
|
|
|
startTime: taskFormData.startTime || '',
|
|
|
|
|
endTime: taskFormData.endTime || '',
|
|
|
|
|
templateId: taskFormData.templateId || '',
|
|
|
|
|
categoryLimitation: taskFormData.categoryLimitation || '0',
|
|
|
|
|
evaluateYear: taskFormData.evaluateYear || '',
|
|
|
|
|
categoryId: taskFormData.categoryId || '',
|
|
|
|
|
taskStatus: taskStatus || null,
|
|
|
|
|
|
|
|
|
|
// 供应商IDs与评价人员IDs
|
|
|
|
|
supplierIds:
|
|
|
|
|
taskFormData.selectedSuppliers?.map((supplier: any) => {
|
|
|
|
|
// 从供应商的evaluators中提取用户ID
|
|
|
|
|
const userIds = supplier.evaluators?.map((evaluator: any) => evaluator.id) || [];
|
|
|
|
|
return {
|
|
|
|
|
id: supplier.id,
|
|
|
|
|
userIds,
|
|
|
|
|
};
|
|
|
|
|
}) || [],
|
|
|
|
|
|
|
|
|
|
// 指标列表
|
|
|
|
|
indicatorList:
|
|
|
|
|
taskFormData.indicatorList?.map((item: any) => ({
|
|
|
|
|
userId: item.userId,
|
|
|
|
|
// 评价类型:如果用户关联了指标则为1(按指标),否则为0(按评价单)
|
|
|
|
|
type: item.indicatorIds && item.indicatorIds.length > 0 ? 1 : 0,
|
|
|
|
|
indicatorIds: item.indicatorIds || [],
|
|
|
|
|
})) || [],
|
|
|
|
|
|
|
|
|
|
// 部门权重列表,过滤掉权重为0的
|
|
|
|
|
taskDeptWeightList:
|
|
|
|
|
taskFormData.taskDeptWeightList?.filter((item: any) => {
|
|
|
|
|
return item.weightValue && item.weightValue !== '0';
|
|
|
|
|
}) || [],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isEditMode) {
|
|
|
|
|
// 编辑模式,添加ID字段
|
|
|
|
|
submitData = {
|
|
|
|
|
...submitData,
|
|
|
|
|
id: taskId,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
const response = (yield call(addTask, submitData)) as API.Response;
|
|
|
|
|
if (response.success) {
|
|
|
|
|
message.success(isEditMode ? '任务更新成功' : '任务创建成功');
|
|
|
|
|
if (onSuccess) {
|
|
|
|
|
onSuccess();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
message.error(response.message || '提交失败');
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('提交失败:', error);
|
|
|
|
|
message.error('提交失败');
|
|
|
|
|
} finally {
|
|
|
|
|
yield put({ type: 'saveLoading', payload: false });
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 更新表单数据
|
|
|
|
|
* 处理不同步骤表单数据的变化,保持数据一致性
|
|
|
|
|
* @param payload 表单数据
|
|
|
|
|
*/
|
|
|
|
|
*updateFormData({ payload }: { payload: any }, { put, select }: { put: any; select: any }) {
|
|
|
|
|
// 获取当前表单数据
|
|
|
|
|
const { taskFormData } = (yield select((state: any) => state.supplierTaskManage)) as { taskFormData: TaskAddRequest };
|
|
|
|
|
// 合并新的表单数据
|
|
|
|
|
const updatedFormData = { ...taskFormData, ...payload };
|
|
|
|
|
// 处理供应商选择更新
|
|
|
|
|
if (payload.selectedSuppliers) {
|
|
|
|
|
// 确保每个供应商都有evaluators字段
|
|
|
|
|
const suppliersWithEvaluators = payload.selectedSuppliers.map((supplier: any) => ({
|
|
|
|
|
...supplier,
|
|
|
|
|
evaluators: supplier.evaluators || [], // 确保evaluators字段存在
|
|
|
|
|
}));
|
|
|
|
|
updatedFormData.selectedSuppliers = suppliersWithEvaluators;
|
|
|
|
|
}
|
2025-06-27 11:38:36 +08:00
|
|
|
|
// 处理评价人员更新 - 更新后要保留原有对象中的indicatorIds
|
|
|
|
|
if (payload.userList) {
|
|
|
|
|
const existingUserMap = new Map(
|
|
|
|
|
(taskFormData.userList || []).map((user: PersonnelItem) => [user.id || user.userId, user])
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
updatedFormData.userList = payload.userList.map((newUser: PersonnelItem) => {
|
|
|
|
|
const userId = newUser.id || newUser.userId;
|
|
|
|
|
const existing = existingUserMap.get(userId);
|
|
|
|
|
|
|
|
|
|
const indicatorIds =
|
|
|
|
|
newUser.indicatorIds && newUser.indicatorIds.length > 0
|
|
|
|
|
? newUser.indicatorIds
|
|
|
|
|
: existing?.indicatorIds || [];
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...newUser,
|
|
|
|
|
indicatorIds,
|
|
|
|
|
};
|
|
|
|
|
});
|
2025-06-26 18:14:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 11:38:36 +08:00
|
|
|
|
|
2025-06-26 18:14:41 +08:00
|
|
|
|
// 处理部门权重
|
|
|
|
|
if (payload.taskDeptWeightList) {
|
|
|
|
|
updatedFormData.taskDeptWeightList = payload.taskDeptWeightList;
|
|
|
|
|
}
|
|
|
|
|
console.log(updatedFormData)
|
|
|
|
|
|
|
|
|
|
// 保存更新后的表单数据
|
|
|
|
|
yield put({ type: 'saveTaskFormData', payload: updatedFormData });
|
|
|
|
|
},
|
2025-06-27 11:38:36 +08:00
|
|
|
|
/**
|
|
|
|
|
* 删除用户
|
|
|
|
|
* @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 });
|
|
|
|
|
},
|
|
|
|
|
|
2025-06-26 18:14:41 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下一步
|
|
|
|
|
* 将当前步骤索引加1
|
|
|
|
|
*/
|
|
|
|
|
*nextStep(_: any, { put, select }: { put: any; select: any }) {
|
|
|
|
|
const { currentStep } = (yield select((state: any) => state.supplierTaskManage)) as { currentStep: number };
|
|
|
|
|
yield put({ type: 'saveCurrentStep', payload: currentStep + 1 });
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 上一步
|
|
|
|
|
* 将当前步骤索引减1
|
|
|
|
|
*/
|
|
|
|
|
*prevStep(_: any, { put, select }: { put: any; select: any }) {
|
|
|
|
|
const { currentStep } = (yield select((state: any) => state.supplierTaskManage)) as { currentStep: number };
|
|
|
|
|
yield put({ type: 'saveCurrentStep', payload: currentStep - 1 });
|
|
|
|
|
},
|
2025-06-27 11:38:36 +08:00
|
|
|
|
/*
|
|
|
|
|
设置当前步骤
|
|
|
|
|
*/
|
|
|
|
|
*setCurrentStep({ payload }: { payload: number }, { put }: { put: any }) {
|
|
|
|
|
yield put({ type: 'saveCurrentStep', payload });
|
|
|
|
|
},
|
2025-06-26 18:14:41 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 重置状态
|
|
|
|
|
* 清空表单数据并将步骤重置为第一步
|
|
|
|
|
*/
|
|
|
|
|
*resetState(_: any, { put }: { put: any }) {
|
|
|
|
|
// 重置表单数据
|
|
|
|
|
yield put({
|
|
|
|
|
type: 'saveTaskFormData',
|
|
|
|
|
payload: {}
|
|
|
|
|
});
|
|
|
|
|
// 重置步骤到第一步
|
|
|
|
|
yield put({
|
|
|
|
|
type: 'saveCurrentStep',
|
|
|
|
|
payload: 0
|
|
|
|
|
});
|
|
|
|
|
},
|
2025-06-27 11:38:36 +08:00
|
|
|
|
/**
|
|
|
|
|
* 设置模式
|
|
|
|
|
*/
|
|
|
|
|
*setMode({ payload }: { payload: 'add' | 'edit' | 'division' }, { put }: { put: any }) {
|
|
|
|
|
yield put({ type: 'saveMode', payload });
|
|
|
|
|
},
|
2025-06-26 18:14:41 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// reducers用于更新状态
|
|
|
|
|
reducers: {
|
|
|
|
|
/**
|
|
|
|
|
* 保存当前步骤
|
|
|
|
|
*/
|
|
|
|
|
saveCurrentStep(state, { payload }) {
|
|
|
|
|
return { ...state, currentStep: payload };
|
|
|
|
|
},
|
2025-06-27 11:38:36 +08:00
|
|
|
|
/**
|
|
|
|
|
* 保存模式
|
|
|
|
|
*/
|
|
|
|
|
saveMode(state, { payload }) {
|
|
|
|
|
return { ...state, mode: payload };
|
|
|
|
|
},
|
2025-06-26 18:14:41 +08:00
|
|
|
|
/**
|
|
|
|
|
* 保存加载状态
|
|
|
|
|
*/
|
|
|
|
|
saveLoading(state, { payload }) {
|
|
|
|
|
return { ...state, loading: payload };
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 保存详情加载状态
|
|
|
|
|
*/
|
|
|
|
|
saveDetailLoading(state, { payload }) {
|
|
|
|
|
return { ...state, detailLoading: payload };
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 保存任务表单数据
|
|
|
|
|
*/
|
|
|
|
|
saveTaskFormData(state, { payload }) {
|
|
|
|
|
return { ...state, taskFormData: payload };
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 保存任务详情数据
|
|
|
|
|
*/
|
|
|
|
|
saveTaskDetail(state, { payload }) {
|
|
|
|
|
return { ...state, taskDetail: payload };
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default SupplierTaskModel;
|