safety-eval-service-frontend/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ContractContent.js

547 lines
19 KiB
JavaScript
Raw Normal View History

2026-07-22 16:06:26 +08:00
import React, { useEffect, useState } from "react";
2026-07-20 15:03:26 +08:00
import {
Tag,
Button,
Card,
Form,
Input,
2026-07-22 17:59:55 +08:00
InputNumber,
2026-07-20 15:03:26 +08:00
Select,
DatePicker,
Row,
Col,
Flex,
2026-07-22 16:06:26 +08:00
message,
Spin,
2026-07-20 15:03:26 +08:00
} from "antd";
2026-07-22 16:06:26 +08:00
import dayjs from "dayjs";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
2026-07-22 17:59:55 +08:00
import { district } from "~/enumerate/constant";
import { phoneRule } from "~/utils/validators";
2026-07-22 16:06:26 +08:00
import { tools } from "@cqsjjb/jjb-common-lib";
2026-07-20 15:03:26 +08:00
import AttachmentUpload from "~/components/AttachmentUpload";
2026-07-22 16:06:26 +08:00
const { router } = tools;
2026-07-20 15:03:26 +08:00
const { TextArea } = Input;
2026-07-22 16:06:26 +08:00
const PROJECT_TYPE_OPTIONS = [
{ label: "新建项目", value: "NEW" },
{ label: "续评项目", value: "RENEW" },
{ label: "变更项目", value: "CHANGE" },
];
const EVAL_TYPE_OPTIONS = [
{ label: "安全预评价", value: "PRE" },
{ label: "安全验收评价", value: "ACCEPT" },
{ label: "安全现状评价", value: "STATUS" },
];
const YES_NO_OPTIONS = [
{ label: "是", value: 1 },
{ label: "否", value: 2 },
];
const ContractContent = (props) => {
2026-07-20 15:03:26 +08:00
const [form] = Form.useForm();
2026-07-22 16:06:26 +08:00
const projectId = router.query?.id;
2026-07-22 17:59:55 +08:00
const {
safetyEvalBusiness,
evalContractGet,
evalContractSave,
customerDetail,
} = props;
const { contractLoading, contractSaveLoading, evalProjectDetailData } =
safetyEvalBusiness || {};
2026-07-22 16:06:26 +08:00
const fetchData = async () => {
if (!projectId) return;
2026-07-22 17:59:55 +08:00
const res = await evalContractGet({ projectId });
if (res?.success !== false && res?.data) {
form.setFieldsValue({
...res.data,
2026-07-23 17:41:28 +08:00
scanFileUrl: res.data.scanFileUrl? JSON.parse(res.data.scanFileUrl) :undefined,
2026-07-22 17:59:55 +08:00
contractStartDate: res.data.contractStartDate
? dayjs(res.data.contractStartDate)
: undefined,
contractEndDate: res.data.contractEndDate
? dayjs(res.data.contractEndDate)
: undefined,
});
} else {
const orgInfo = JSON.parse(sessionStorage.getItem("orgInfo"));
form.setFieldsValue({
orgName: orgInfo?.unitName,
projectName: evalProjectDetailData?.projectName,
evalTypeCode: evalProjectDetailData?.evalTypeCode,
projectRegion: evalProjectDetailData?.districtCode,
});
const customerRes = await customerDetail({
id: evalProjectDetailData.customerId,
});
if (customerRes?.success && customerRes?.data) {
2026-07-22 16:06:26 +08:00
form.setFieldsValue({
2026-07-22 17:59:55 +08:00
enterpriseName: customerRes.data.customerName,
officeAddress: customerRes.data.businessAddress,
creditCode: customerRes.data.creditCode,
legalPerson: customerRes.data.legalRepresentative,
contactName: customerRes.data.principalName,
contactPhone: customerRes.data.principalPhone,
2026-07-22 16:06:26 +08:00
});
}
}
};
useEffect(() => {
2026-07-22 17:59:55 +08:00
if (evalProjectDetailData?.id) {
fetchData();
}
}, [projectId, evalProjectDetailData?.id]);
2026-07-22 16:06:26 +08:00
const handleSave = async () => {
try {
const values = await form.validateFields();
const { contractStartDate, contractEndDate, ...rest } = values;
const res = await evalContractSave({
...rest,
projectId,
2026-07-22 17:59:55 +08:00
contractStartDate: contractStartDate
? contractStartDate.format("YYYY-MM-DD")
: undefined,
contractEndDate: contractEndDate
? contractEndDate.format("YYYY-MM-DD")
: undefined,
scanFileUrl: rest.scanFileUrl? JSON.stringify(rest.scanFileUrl) :undefined,
2026-07-22 16:06:26 +08:00
});
if (res?.success !== false) {
message.success("合同保存成功");
2026-07-23 17:41:28 +08:00
props.getDetail();
2026-07-22 16:06:26 +08:00
}
} finally {
}
};
2026-07-20 15:03:26 +08:00
return (
2026-07-22 17:59:55 +08:00
<Spin spinning={contractLoading}>
2026-07-22 16:06:26 +08:00
<div>
<div className="pf-permission">
<Tag color="blue" className="pf-tag">
机构管理员 / 项目负责人
</Tag>
<span className="pf-desc">
按照已批准的风险分析结论录入项目合同和被评价企业信息上传PDF格式的正式合同扫描件
</span>
</div>
<Card title="项目合同信息" styles={{ header: { textAlign: "center" } }}>
<Form form={form} layout="vertical">
2026-07-22 17:59:55 +08:00
<Card
type="inner"
size="small"
title="项目合同信息"
extra={<Tag color="blue">合同基本信息</Tag>}
className="pf-section"
>
2026-07-22 16:06:26 +08:00
<Row gutter={16}>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="机构名称"
name="orgName"
rules={[{ required: true, message: "请填写机构名称" }]}
>
<Input
placeholder="请输入机构名称"
maxLength={100}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="合同编号"
name="contractNo"
rules={[{ required: true, message: "请填写合同编号" }]}
>
<Input
placeholder="请输入合同编号"
maxLength={50}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目名称"
name="projectName"
rules={[{ required: true, message: "请填写项目名称" }]}
>
<Input
placeholder="请输入项目名称"
maxLength={100}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目简介"
name="projectIntro"
rules={[{ required: true, message: "请填写项目简介" }]}
>
<TextArea
rows={3}
maxLength={500}
showCount
placeholder="请输入项目简介"
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="合同金额(万元)" name="amount">
2026-07-22 17:59:55 +08:00
<InputNumber style={{width: '100%'}} placeholder="请输入合同金额" min={0} precision={2} max={9999999} />
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目类型"
name="projectTypeCode"
rules={[{ required: true, message: "请选择项目类型" }]}
>
2026-07-22 16:06:26 +08:00
<Select placeholder="请选择项目类型" allowClear>
{PROJECT_TYPE_OPTIONS.map((opt) => (
2026-07-22 17:59:55 +08:00
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
2026-07-22 16:06:26 +08:00
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目风险分析"
name="riskSummary"
rules={[{ required: true, message: "请填写项目风险分析" }]}
>
<TextArea
rows={3}
maxLength={500}
showCount
placeholder="自动带入风险分析结论,可补充说明"
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目所在地"
name="projectRegion"
rules={[{ required: true, message: "请填写项目所在地" }]}
>
<Select
placeholder="请选择"
allowClear
showSearch
optionFilterProp="label"
>
{district.map((opt) => (
<Select.Option key={opt.code} value={opt.code}>
{opt.name}
</Select.Option>
))}
</Select>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目详细地址"
name="projectAddress"
rules={[{ required: true, message: "请填写项目详细地址" }]}
>
<Input
placeholder="请输入项目详细地址"
maxLength={200}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="合同开始时间"
name="contractStartDate"
2026-07-27 11:54:30 +08:00
rules={[
{ required: true, message: "请选择合同开始时间" },
{
validator: (_, value) => {
const end = form.getFieldValue("contractEndDate");
if (value && end && value.isAfter(end)) {
return Promise.reject(
"合同开始时间不能晚于合同结束时间",
);
}
return Promise.resolve();
},
},
]}
2026-07-22 17:59:55 +08:00
>
2026-07-27 11:54:30 +08:00
<DatePicker
className="pf-w-full"
allowClear
onChange={() =>
form.validateFields(["contractEndDate"])
}
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="合同结束时间"
name="contractEndDate"
2026-07-27 11:54:30 +08:00
rules={[
{ required: true, message: "请选择合同结束时间" },
{
validator: (_, value) => {
const start =
form.getFieldValue("contractStartDate");
if (value && start && value.isBefore(start)) {
return Promise.reject(
"合同结束时间不能早于合同开始时间",
);
}
return Promise.resolve();
},
},
]}
2026-07-22 17:59:55 +08:00
>
2026-07-27 11:54:30 +08:00
<DatePicker
className="pf-w-full"
allowClear
onChange={() =>
form.validateFields(["contractStartDate"])
}
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="评价类型"
name="evalTypeCode"
rules={[{ required: true, message: "请选择评价类型" }]}
>
2026-07-22 16:06:26 +08:00
<Select placeholder="请选择评价类型" allowClear>
{EVAL_TYPE_OPTIONS.map((opt) => (
2026-07-22 17:59:55 +08:00
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
2026-07-22 16:06:26 +08:00
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="是否生产剧毒化学品"
name="toxicFlag"
rules={[{ required: true, message: "请选择" }]}
>
2026-07-22 16:06:26 +08:00
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
2026-07-22 17:59:55 +08:00
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
2026-07-22 16:06:26 +08:00
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="是否生产易制毒化学品"
name="precursorFlag"
rules={[{ required: true, message: "请选择" }]}
>
2026-07-22 16:06:26 +08:00
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
2026-07-22 17:59:55 +08:00
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
2026-07-22 16:06:26 +08:00
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="是否跨省建设项目"
name="crossProvinceFlag"
rules={[{ required: true, message: "请选择" }]}
>
2026-07-22 16:06:26 +08:00
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
2026-07-22 17:59:55 +08:00
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
2026-07-22 16:06:26 +08:00
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="项目业务范围"
name="businessScope"
rules={[{ required: true, message: "请填写项目业务范围" }]}
>
<Input
placeholder="请输入项目业务范围"
maxLength={200}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
</Row>
</Card>
2026-07-20 15:03:26 +08:00
2026-07-22 17:59:55 +08:00
<Card
type="inner"
size="small"
title="被评价企业信息"
extra={<Tag color="blue">合同服务对象</Tag>}
className="pf-section"
>
2026-07-22 16:06:26 +08:00
<Row gutter={16}>
<Col span={24}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="企业名称"
name="enterpriseName"
rules={[{ required: true, message: "请填写企业名称" }]}
>
<Input
placeholder="请输入企业名称"
maxLength={100}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="国民经济行业类别" name="industryCategory">
2026-07-22 17:59:55 +08:00
<TextArea
rows={2}
maxLength={200}
showCount
placeholder="请输入国民经济行业类别"
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="办公地址" name="officeAddress">
2026-07-22 17:59:55 +08:00
<Input
placeholder="请输入办公地址"
maxLength={200}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="社会统一信用代码" name="creditCode">
2026-07-22 17:59:55 +08:00
<Input
placeholder="请输入社会统一信用代码"
maxLength={18}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="邮政编码" name="postCode">
2026-07-22 17:59:55 +08:00
<Input
placeholder="请输入邮政编码"
maxLength={10}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item label="企业电话" name="enterprisePhone"
rules={[phoneRule("企业电话", false)]}
>
<Input
placeholder="请输入企业电话"
maxLength={20}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="传真" name="fax">
<Input placeholder="请输入传真" maxLength={20} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="法人代表" name="legalPerson">
2026-07-22 17:59:55 +08:00
<Input
placeholder="请输入法人代表"
maxLength={20}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item
label="联系人"
name="contactName"
rules={[{ required: true, message: "请填写联系人" }]}
>
<Input
placeholder="请输入联系人"
maxLength={20}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item label="联系人电话" name="contactPhone"
rules={[phoneRule("联系人电话")]}
>
<Input
placeholder="请输入联系人电话"
maxLength={20}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
<Col span={12}>
2026-07-22 17:59:55 +08:00
<Form.Item label="职工人数" name="staffCount">
<Input
placeholder="请输入职工人数"
maxLength={10}
allowClear
/>
2026-07-22 16:06:26 +08:00
</Form.Item>
</Col>
</Row>
</Card>
2026-07-20 15:03:26 +08:00
2026-07-22 16:06:26 +08:00
<AttachmentUpload
name="scanFileUrl"
label="项目合同扫描件"
accept=".pdf"
maxCount={10}
extra="请上传PDF文件大小不应超过500MB不超过10个文件。"
/>
</Form>
2026-07-20 15:03:26 +08:00
2026-07-22 16:06:26 +08:00
<Flex justify="flex-end" gap={8}>
<Button onClick={() => props.history.goBack()}>取消</Button>
2026-07-22 17:59:55 +08:00
<Button
type="primary"
onClick={handleSave}
loading={contractSaveLoading}
>
完成合同录入并保存
</Button>
2026-07-22 16:06:26 +08:00
</Flex>
</Card>
</div>
</Spin>
2026-07-20 15:03:26 +08:00
);
};
2026-07-22 17:59:55 +08:00
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(ContractContent);