2025-06-27 19:55:19 +08:00
|
|
|
|
import React, { useRef, useEffect } from 'react';
|
|
|
|
|
import { Card, Steps, Button, message, Space, Row, Col, Modal } from 'antd';
|
|
|
|
|
import { connect, ConnectProps, history, Dispatch } from 'umi';
|
|
|
|
|
import { ArrowLeftOutlined, SaveOutlined } from '@ant-design/icons';
|
|
|
|
|
import BasicInfoStep from './components/BasicInfoStep';
|
|
|
|
|
import SupplierSelectStep from './components/SupplierSelectStep';
|
|
|
|
|
import EvaluatorSelectStep from './components/EvaluatorSelectStep';
|
|
|
|
|
import styles from './supplierAnnualTaskManageAdd.less';
|
|
|
|
|
import { TaskNotifyLowerUnits } from '@/dicts/supplierTaskDict';
|
|
|
|
|
import { SupplierTaskModelState } from '@/models/supplierAnnualTaskManage';
|
|
|
|
|
|
|
|
|
|
const { Step } = Steps;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取URL参数
|
|
|
|
|
* 解析URL中的id和mode参数,用于判断是否为编辑模式
|
|
|
|
|
* @returns {object} 包含id和mode的对象
|
|
|
|
|
*/
|
|
|
|
|
const getUrlParams = () => {
|
|
|
|
|
const location = window.location.href;
|
|
|
|
|
const url = new URL(location);
|
|
|
|
|
return {
|
|
|
|
|
id: url.searchParams.get('id'),
|
|
|
|
|
mode: url.searchParams.get('mode'),
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 页面组件Props接口定义
|
|
|
|
|
* 继承了ConnectProps,添加了supplierTaskManage和dispatch
|
|
|
|
|
*/
|
|
|
|
|
interface PageProps extends ConnectProps {
|
|
|
|
|
supplierAnnualTaskManage: SupplierTaskModelState; // dva model状态
|
|
|
|
|
dispatch: Dispatch; // dva dispatch方法
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 供应商任务管理添加/编辑组件
|
|
|
|
|
* 使用步骤式表单引导用户完成添加或编辑任务的流程
|
|
|
|
|
*/
|
|
|
|
|
const SupplierTaskManageAdd: React.FC<PageProps> = ({ supplierAnnualTaskManage, dispatch }) => {
|
|
|
|
|
// 获取dva model中的状态
|
|
|
|
|
const { currentStep, loading, detailLoading } = supplierAnnualTaskManage;
|
|
|
|
|
|
|
|
|
|
// 判断是否为编辑模式
|
|
|
|
|
const urlParams = getUrlParams();
|
|
|
|
|
const isEditMode = urlParams.mode === 'edit' && urlParams.id;
|
|
|
|
|
const isDivisionMode = urlParams.mode === 'division' && urlParams.id;
|
|
|
|
|
const taskId = urlParams.id || '';
|
|
|
|
|
|
|
|
|
|
// 创建表单引用,用于访问子组件的表单方法(主要用于验证)
|
|
|
|
|
const basicFormRef = useRef<any>(null); // 基本信息表单引用
|
|
|
|
|
const supplierFormRef = useRef<any>(null); // 供应商选择表单引用
|
|
|
|
|
const evaluatorFormRef = useRef<any>(null); // 评价人员表单引用
|
|
|
|
|
const divisionFormRef = useRef<any>(null); // 评价分工表单引用
|
|
|
|
|
|
|
|
|
|
// 确认对话框可见性状态
|
|
|
|
|
const [confirmModalVisible, setConfirmModalVisible] = React.useState(false);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 编辑模式下获取任务详情,或新建模式下重置状态
|
|
|
|
|
* 利用useEffect在组件挂载或依赖项变化时触发
|
|
|
|
|
*/
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if ((isEditMode || isDivisionMode) && taskId && dispatch) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/saveMode',
|
|
|
|
|
payload: 'edit',
|
|
|
|
|
});
|
|
|
|
|
// 编辑模式,获取任务详情
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/fetchTaskDetail',
|
|
|
|
|
payload: { taskId },
|
|
|
|
|
});
|
|
|
|
|
if (isDivisionMode) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/saveMode',
|
|
|
|
|
payload: 'division',
|
|
|
|
|
});
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/setCurrentStep',
|
|
|
|
|
payload: 2,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else if (dispatch) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/setMode',
|
|
|
|
|
payload: 'add',
|
|
|
|
|
});
|
|
|
|
|
// 新建模式,重置状态
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/resetState',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, [isEditMode, isDivisionMode, taskId, dispatch]);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 组件卸载时重置状态
|
|
|
|
|
*/
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
return () => {
|
|
|
|
|
if (dispatch) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/resetState',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}, [dispatch]);
|
|
|
|
|
|
|
|
|
|
// 步骤配置,定义每个步骤的标题、描述和内容组件
|
|
|
|
|
const steps = [
|
|
|
|
|
{
|
|
|
|
|
title: '基本信息', // 步骤标题
|
|
|
|
|
description: '请填写基本信息', // 步骤描述
|
|
|
|
|
content: (
|
|
|
|
|
<BasicInfoStep
|
|
|
|
|
ref={basicFormRef}
|
|
|
|
|
/>
|
|
|
|
|
), // 步骤内容组件
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '选择供应商',
|
|
|
|
|
description: '请选择参加评价的供应商',
|
|
|
|
|
content: (
|
|
|
|
|
<SupplierSelectStep
|
|
|
|
|
ref={supplierFormRef}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '选择评价人员',
|
|
|
|
|
description: '请选择供应商评价人员',
|
|
|
|
|
content: (
|
|
|
|
|
<EvaluatorSelectStep
|
|
|
|
|
ref={evaluatorFormRef}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理返回按钮点击事件
|
|
|
|
|
* 返回上一页
|
|
|
|
|
*/
|
|
|
|
|
const handleBack = () => {
|
|
|
|
|
history.goBack();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理下一步按钮点击事件
|
|
|
|
|
* 验证当前步骤的表单数据,通过后进入下一步
|
|
|
|
|
*/
|
|
|
|
|
const handleNext = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// 根据当前步骤验证相应的表单
|
|
|
|
|
if (currentStep === 0 && basicFormRef.current) {
|
|
|
|
|
// 验证基本信息
|
|
|
|
|
await basicFormRef.current.validateFields();
|
|
|
|
|
} else if (currentStep === 1 && supplierFormRef.current) {
|
|
|
|
|
// 验证供应商选择
|
|
|
|
|
await supplierFormRef.current.validateFields();
|
|
|
|
|
} else if (currentStep === 2 && evaluatorFormRef.current) {
|
|
|
|
|
// 验证评价人员选择
|
|
|
|
|
await evaluatorFormRef.current.validateFields();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证通过,进入下一步
|
|
|
|
|
if (dispatch) {
|
|
|
|
|
dispatch({ type: 'supplierAnnualTaskManage/nextStep' });
|
|
|
|
|
}
|
|
|
|
|
} catch (errorInfo: any) {
|
|
|
|
|
// 表单验证失败
|
|
|
|
|
console.log('表单验证失败:', errorInfo);
|
|
|
|
|
if (typeof errorInfo === 'string') {
|
|
|
|
|
message.error(errorInfo);
|
|
|
|
|
} else if (errorInfo && errorInfo.errorFields) {
|
|
|
|
|
message.error('请完成必填项');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理上一步按钮点击事件
|
|
|
|
|
* 返回上一个步骤
|
|
|
|
|
*/
|
|
|
|
|
const handlePrev = () => {
|
|
|
|
|
if (dispatch) {
|
|
|
|
|
dispatch({ type: 'supplierAnnualTaskManage/prevStep' });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交任务数据
|
|
|
|
|
* @param taskStatus 任务状态,决定是否需要下级单位完善
|
|
|
|
|
*/
|
|
|
|
|
const submitTaskData = (taskStatus: TaskNotifyLowerUnits | null) => {
|
|
|
|
|
if (dispatch) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: 'supplierAnnualTaskManage/submitTaskData',
|
|
|
|
|
payload: {
|
|
|
|
|
taskStatus,
|
|
|
|
|
isEditMode,
|
|
|
|
|
taskId,
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
history.goBack();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理提交按钮点击事件
|
|
|
|
|
* 验证评价分工表单,通过后根据是否为编辑模式决定提交方式
|
|
|
|
|
*/
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
|
|
// 验证评价分工
|
|
|
|
|
if (divisionFormRef.current) {
|
|
|
|
|
const result = divisionFormRef.current.validate();
|
|
|
|
|
if (!result.valid) {
|
|
|
|
|
message.error(result.message);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 如果是编辑模式,则直接提交 提示是否确认后直接提交
|
|
|
|
|
if (isEditMode) {
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
title: '提示',
|
|
|
|
|
content: '是否确认提交',
|
|
|
|
|
onOk: () => {
|
|
|
|
|
submitTaskData(null);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新增模式下,显示确认对话框询问是否需要下级单位完善
|
|
|
|
|
setConfirmModalVisible(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理确认对话框的取消按钮点击事件
|
|
|
|
|
*/
|
|
|
|
|
const handleConfirmCancel = () => {
|
|
|
|
|
setConfirmModalVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理确认对话框的"是"选项点击事件
|
|
|
|
|
* 提交任务,并设置状态为需要下级单位完善
|
|
|
|
|
*/
|
|
|
|
|
const handleConfirmYes = () => {
|
|
|
|
|
submitTaskData(TaskNotifyLowerUnits.YES); // 未开始状态,需要下级单位完善
|
|
|
|
|
setConfirmModalVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理确认对话框的"否"选项点击事件
|
|
|
|
|
* 提交任务,并设置状态为不需要下级单位完善
|
|
|
|
|
*/
|
|
|
|
|
const handleConfirmNo = () => {
|
|
|
|
|
submitTaskData(TaskNotifyLowerUnits.NO); // 进行中状态,不需要下级单位完善
|
|
|
|
|
setConfirmModalVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="common-container">
|
|
|
|
|
{/* 卡片容器,显示加载状态 */}
|
|
|
|
|
<Card bordered={false} loading={detailLoading}>
|
|
|
|
|
{/* 页面头部,包含标题和返回按钮 */}
|
|
|
|
|
<div className="page-header">
|
|
|
|
|
<h2>{isEditMode ? '修改评价任务' : '新增评价任务'}</h2>
|
|
|
|
|
<Button type="link" icon={<ArrowLeftOutlined />} onClick={handleBack}>
|
|
|
|
|
返回
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* 步骤式表单布局 */}
|
|
|
|
|
<Row gutter={24} className={styles.stepsLayout}>
|
|
|
|
|
{/* 左侧步骤导航 */}
|
|
|
|
|
<Col span={6} className={styles.stepsLeft}>
|
|
|
|
|
<Steps direction="vertical" current={currentStep} className={styles.verticalSteps}>
|
|
|
|
|
{steps.map((item) => (
|
|
|
|
|
<Step key={item.title} title={item.title} description={item.description} />
|
|
|
|
|
))}
|
|
|
|
|
</Steps>
|
|
|
|
|
</Col>
|
|
|
|
|
{/* 右侧表单内容 */}
|
|
|
|
|
<Col span={18} className={styles.stepsRight}>
|
|
|
|
|
<div className={styles.stepsContent}>{steps[currentStep].content}</div>
|
|
|
|
|
|
|
|
|
|
{/* 步骤操作按钮 */}
|
|
|
|
|
<div className={styles.stepsAction}>
|
|
|
|
|
<Space>
|
|
|
|
|
{/* 如果当前是评价分工步骤,则不显示上一步按钮 */}
|
|
|
|
|
{currentStep > (isDivisionMode ? 2 : 0) && <Button onClick={handlePrev}>上一步</Button>}
|
|
|
|
|
{currentStep < steps.length - 1 && (
|
|
|
|
|
<Button type="primary" onClick={handleNext}>
|
|
|
|
|
下一步
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
{currentStep === steps.length - 1 && (
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
loading={loading}
|
|
|
|
|
icon={<SaveOutlined />}
|
|
|
|
|
onClick={handleSubmit}
|
|
|
|
|
>
|
|
|
|
|
{isEditMode ? '保存' : '提交'}
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</Space>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
{/* 确认对话框 - 询问是否需要下级单位完善 */}
|
|
|
|
|
<Modal
|
|
|
|
|
title="提交确认"
|
|
|
|
|
visible={confirmModalVisible}
|
|
|
|
|
onCancel={handleConfirmCancel}
|
|
|
|
|
footer={null}
|
|
|
|
|
>
|
|
|
|
|
<p>是否提示给下级单位继续完善评价人及评价分工?</p>
|
|
|
|
|
<div style={{ textAlign: 'right', marginTop: 24 }}>
|
|
|
|
|
<Space>
|
|
|
|
|
<Button type="primary" onClick={handleConfirmYes}>
|
|
|
|
|
是
|
|
|
|
|
</Button>
|
|
|
|
|
<Button onClick={handleConfirmNo}>否</Button>
|
|
|
|
|
<Button onClick={handleConfirmCancel}>取消</Button>
|
|
|
|
|
</Space>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 将dva model中的状态映射到组件props
|
|
|
|
|
export default connect(({ supplierAnnualTaskManage }: { supplierAnnualTaskManage: SupplierTaskModelState }) => ({
|
|
|
|
|
supplierAnnualTaskManage,
|
|
|
|
|
}))(SupplierTaskManageAdd);
|