341 lines
12 KiB
TypeScript
341 lines
12 KiB
TypeScript
![]() |
import React, {useState} from 'react';
|
|||
|
import { Form, Input, Select, Button, Spin, message } from 'antd';
|
|||
|
const { Option } = Select;
|
|||
|
import { useLocation } from 'umi';
|
|||
|
import {createContract, updateContract} from "./ContractService";
|
|||
|
import {history} from "@@/core/history";
|
|||
|
|
|||
|
|
|||
|
// 模拟行业选项
|
|||
|
const industryOptions = [
|
|||
|
{ label: '制造业', value:'0' },
|
|||
|
{ label: '服务业', value:'service' },
|
|||
|
{ label: '零售业', value:'retail' },
|
|||
|
];
|
|||
|
|
|||
|
const StepOne: React.FC = () => {
|
|||
|
const [form] = Form.useForm();
|
|||
|
let readOnly = false;
|
|||
|
const location = useLocation();
|
|||
|
const contractType = location.state?.contractType;
|
|||
|
const contractInfo = location.state?.contractInfo;
|
|||
|
const opt = location.state?.opt;
|
|||
|
const [loading, setLoading] = useState<boolean>(false);
|
|||
|
if(opt){
|
|||
|
form.setFieldsValue({
|
|||
|
...contractInfo
|
|||
|
});
|
|||
|
if(opt === 'detail'){
|
|||
|
readOnly = true;
|
|||
|
}else if (opt ==='edit'){
|
|||
|
readOnly = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 表单提交处理函数
|
|||
|
const onFinish = (values: any) => {
|
|||
|
values.contractType = contractType;
|
|||
|
if(opt === 'detail'){
|
|||
|
history.push({
|
|||
|
pathname: '/stepTwo',
|
|||
|
state: {
|
|||
|
contractInfo: contractInfo,
|
|||
|
opt: opt
|
|||
|
}
|
|||
|
});
|
|||
|
}else{
|
|||
|
try {
|
|||
|
if (values.id) {
|
|||
|
setLoading(true)
|
|||
|
updateContract(values).then((res: any) => {
|
|||
|
if(res.code === 200){
|
|||
|
// message.success("当前数据更新成功").then(() => {
|
|||
|
history.push({
|
|||
|
pathname: '/stepTwo',
|
|||
|
state: {
|
|||
|
contractInfo: res.data,
|
|||
|
opt: opt
|
|||
|
}
|
|||
|
});
|
|||
|
// }).then( () => {
|
|||
|
setLoading(false)
|
|||
|
// })
|
|||
|
}else {
|
|||
|
message.error('更新失败');
|
|||
|
}
|
|||
|
})
|
|||
|
} else {
|
|||
|
createContract(values).then( (res: any) => {
|
|||
|
if(res.code === 200){
|
|||
|
history.push({
|
|||
|
pathname: '/stepTwo',
|
|||
|
state: {
|
|||
|
contractInfo: res.data
|
|||
|
}
|
|||
|
});
|
|||
|
}else {
|
|||
|
message.error('更新失败');
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
} catch (error) {
|
|||
|
message.error(error.message || '操作失败');
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
// @ts-ignore
|
|||
|
const validateCreditCode = (value: string) => {
|
|||
|
// 基本格式校验
|
|||
|
if (!value || value.length !== 18) {
|
|||
|
return '统一社会信用代码必须为18位';
|
|||
|
}
|
|||
|
|
|||
|
// 正则校验(允许数字和大写字母,不包括I、O、Z、S、V)
|
|||
|
const pattern = /^[0-9A-HJ-NPQRTUWXY]{18}$/;
|
|||
|
if (!pattern.test(value)) {
|
|||
|
return '统一社会信用代码格式不正确';
|
|||
|
}
|
|||
|
|
|||
|
// 校验码计算
|
|||
|
const weightFactor = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
|
|||
|
const codePoint = {
|
|||
|
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
|
|||
|
'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18,
|
|||
|
'K': 19, 'L': 20, 'M': 21, 'N': 22, 'P': 23, 'Q': 24, 'R': 25, 'T': 26, 'U': 27,
|
|||
|
'W': 28, 'X': 29, 'Y': 30
|
|||
|
};
|
|||
|
const checkCodeDict = {
|
|||
|
0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9',
|
|||
|
10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F', 16: 'G', 17: 'H', 18: 'J',
|
|||
|
19: 'K', 20: 'L', 21: 'M', 22: 'N', 23: 'P', 24: 'Q', 25: 'R', 26: 'T', 27: 'U',
|
|||
|
28: 'W', 29: 'X', 30: 'Y'
|
|||
|
};
|
|||
|
|
|||
|
let sum = 0;
|
|||
|
for (let i = 0; i < 17; i++) {
|
|||
|
sum += codePoint[value[i]] * weightFactor[i];
|
|||
|
}
|
|||
|
|
|||
|
const mod = sum % 31;
|
|||
|
const checkCode = checkCodeDict[mod];
|
|||
|
|
|||
|
if (checkCode !== value[17]) {
|
|||
|
return '统一社会信用代码校验位不正确';
|
|||
|
}
|
|||
|
|
|||
|
return null; // 校验通过
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
// 表单提交失败处理函数
|
|||
|
const onFinishFailed = (errorInfo: any) => {
|
|||
|
// console.log('Form submission failed:', errorInfo);
|
|||
|
message.error('表单提交失败,请检查输入');
|
|||
|
};
|
|||
|
|
|||
|
return (
|
|||
|
<div style={{ padding: '10px' }}>
|
|||
|
{/* 添加全局遮罩 */}
|
|||
|
{loading && (
|
|||
|
<Spin
|
|||
|
tip="加载中..."
|
|||
|
style={{
|
|||
|
position: 'fixed',
|
|||
|
top: 0,
|
|||
|
left: 0,
|
|||
|
width: '100%',
|
|||
|
height: '100%',
|
|||
|
zIndex: 9999,
|
|||
|
background: 'rgba(255, 255, 255, 0.8)',
|
|||
|
}}
|
|||
|
/>
|
|||
|
)}
|
|||
|
<Form
|
|||
|
form={form}
|
|||
|
labelCol={{span:4}}
|
|||
|
wrapperCol={{span:20}}
|
|||
|
|
|||
|
initialValues={{
|
|||
|
status: 0
|
|||
|
}}
|
|||
|
onFinish={onFinish}
|
|||
|
onFinishFailed={onFinishFailed}
|
|||
|
>
|
|||
|
{/* 项目基本信息部分 */}
|
|||
|
<div style={{ borderLeft: '4px solid #0066cc', paddingLeft: 8, marginBottom: 16 }}>
|
|||
|
<span style={{ fontSize: 16, fontWeight: 'bold' }}>基本信息</span>
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item hidden={true} name="id"></Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="status"
|
|||
|
label="合同状态"
|
|||
|
hidden={true}
|
|||
|
>
|
|||
|
<Input value={0}/>
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="projectName"
|
|||
|
label="项目名称"
|
|||
|
rules={[{ required: true, message: '请输入项目名称' }]}
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入项目名称" readOnly={readOnly}/>
|
|||
|
</Form.Item>
|
|||
|
<Form.Item name="projectSelect" label="" style={{ width: '80%' }}>
|
|||
|
<Button type="primary" hidden={readOnly}>选择项目</Button>
|
|||
|
</Form.Item>
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item
|
|||
|
name="biddingName"
|
|||
|
label="标段名称"
|
|||
|
rules={[{ required: true, message: '请输入标段名称' }]}
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入标段名称" readOnly={readOnly}/>
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="biddingCode"
|
|||
|
label="标段编号"
|
|||
|
rules={[{ required: true, message: '请输入标段编号' }]}
|
|||
|
style={{ width: '45%' }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入标段编号" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
</div>
|
|||
|
<Form.Item name="sectionSelect" label="" style={{ width: '20%' }}>
|
|||
|
<Button type="primary" hidden={readOnly}>选择标段</Button>
|
|||
|
</Form.Item>
|
|||
|
|
|||
|
{/* 我方签约主体信息部分 */}
|
|||
|
<div style={{ borderLeft: '4px solid #0066cc', paddingLeft: 8, marginBottom: 16, marginTop: 16 }}>
|
|||
|
<span style={{ fontSize: 16, fontWeight: 'bold' }}>我方签约主体信息</span>
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item
|
|||
|
name="purchaserName"
|
|||
|
label="采购单位"
|
|||
|
rules={[{ required: true, message: '请输入采购单位' }]}
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入采购单位" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="purchaserCode"
|
|||
|
label="统一社会信用代码"
|
|||
|
rules={[{ required: true, message: '请输入统一社会信用代码' },
|
|||
|
// ({ getFieldValue }) => ({
|
|||
|
// validator(rule, value) {
|
|||
|
// const errorMessage = validateCreditCode(value);
|
|||
|
// if (errorMessage) {
|
|||
|
// return Promise.reject(errorMessage);
|
|||
|
// }
|
|||
|
// return Promise.resolve();
|
|||
|
// },
|
|||
|
// })
|
|||
|
]}
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入统一社会信用代码" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="industryCode"
|
|||
|
label="所属主要行业"
|
|||
|
rules={[{ required: true, message: '请选择所属主要行业' }]}
|
|||
|
style={{ width: '45%' }}
|
|||
|
>
|
|||
|
<Select placeholder="请选择" disabled={readOnly}>
|
|||
|
{industryOptions.map(({ label, value }) => (
|
|||
|
<Option key={value} value={value}>
|
|||
|
{label}
|
|||
|
</Option>
|
|||
|
))}
|
|||
|
</Select>
|
|||
|
</Form.Item>
|
|||
|
</div>
|
|||
|
|
|||
|
{/* 对方签约主体信息部分 */}
|
|||
|
<div style={{ borderLeft: '4px solid #0066cc', paddingLeft: 8, marginBottom: 16, marginTop: 16 }}>
|
|||
|
<span style={{ fontSize: 16, fontWeight: 'bold' }}>对方签约主体信息</span>
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item
|
|||
|
name="supplierName"
|
|||
|
label="供应商公司名称"
|
|||
|
rules={[{ required: true, message: '请输入供应商公司名称' }]}
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入供应商公司名称" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="supplierCode"
|
|||
|
label="统一社会信用代码"
|
|||
|
rules={[
|
|||
|
{ required: true, message: '请输入统一社会信用代码' },
|
|||
|
// ({ getFieldValue }) => ({
|
|||
|
// validator(rule, value) {
|
|||
|
// const errorMessage = validateCreditCode(value);
|
|||
|
// if (errorMessage) {
|
|||
|
// return Promise.reject(errorMessage);
|
|||
|
// }
|
|||
|
// return Promise.resolve();
|
|||
|
// },
|
|||
|
// })
|
|||
|
]}
|
|||
|
style={{ width: '45%' }}
|
|||
|
>
|
|||
|
<Input placeholder="请输入统一社会信用代码" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item name="supplierSelect" label="" style={{ width: '20%' }}>
|
|||
|
<Button type="primary" hidden={readOnly}>选择供应商</Button>
|
|||
|
</Form.Item>
|
|||
|
{/*<Form.Item*/}
|
|||
|
{/* name="supplierName"*/}
|
|||
|
{/* label="供应商公司名称"*/}
|
|||
|
{/* rules={[{ required: true, message: '请输入供应商公司名称' }]}*/}
|
|||
|
{/* style={{ width: '50%', marginRight: 16 }}*/}
|
|||
|
{/*>*/}
|
|||
|
{/* <Input placeholder="请输入供应商公司名称" readOnly={readOnly} />*/}
|
|||
|
{/*</Form.Item>*/}
|
|||
|
|
|||
|
</div>
|
|||
|
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|||
|
<Form.Item
|
|||
|
name="signerName"
|
|||
|
label="供应商签约人"
|
|||
|
style={{ width: '50%', marginRight: 16 }}
|
|||
|
rules={[{ min: 2, message: '姓名长度不能少于2个字符' },
|
|||
|
{ max: 20, message: '姓名长度不能超过20个字符' },
|
|||
|
{ pattern: /^[\u4e00-\u9fa5a-zA-Z\s·]{2,20}$/, message: '请输入正确的姓名' }]}
|
|||
|
>
|
|||
|
<Input placeholder="" readOnly={readOnly}/>
|
|||
|
</Form.Item>
|
|||
|
<Form.Item
|
|||
|
name="signerContact"
|
|||
|
label="供应商联系方式"
|
|||
|
style={{ width: '50%' }}
|
|||
|
rules={ [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }]}
|
|||
|
>
|
|||
|
<Input placeholder="" readOnly={readOnly} />
|
|||
|
</Form.Item>
|
|||
|
</div>
|
|||
|
|
|||
|
{/* 居中显示的下一步按钮 */}
|
|||
|
<div style={{ display: 'flex', justifyContent: 'center', marginTop: 24 }}>
|
|||
|
<Form.Item>
|
|||
|
<Button type="primary" htmlType="submit" style={{ width: 200 }} onClick={ () => {}}>
|
|||
|
下一步,合同信息
|
|||
|
</Button>
|
|||
|
</Form.Item>
|
|||
|
</div>
|
|||
|
</Form>
|
|||
|
</div>
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
export default StepOne;
|