dev_1.2
tangjie 2026-07-22 16:06:26 +08:00
parent bd0739f37f
commit ff0fbb2093
6 changed files with 815 additions and 731 deletions

View File

@ -62,6 +62,7 @@ export const evalProjectSave = declareRequest(
export const evalProjectDetail = declareRequest(
"evalProjectDetailLoading",
"Get > /safetyEval/institution/eval-project/get",
'evalProjectDetail: {} | res.data || {}',
);
export const evalProjectDelete = declareRequest(
@ -97,4 +98,29 @@ export const evalProjectRiskWarningStat = declareRequest(
export const evalProjectRiskWarningPage = declareRequest(
"riskWarningPageLoading",
"Get > /safetyEval/institution/eval-project/risk-warning-page",
);
export const evalRiskAnalysisGet = declareRequest(
"riskAnalysisLoading",
"Get > /safetyEval/institution/eval-risk-analysis/get",
);
export const evalRiskAnalysisSave = declareRequest(
"riskAnalysisSaveLoading",
"Post > @/safetyEval/institution/eval-risk-analysis/save",
);
export const evalContractGet = declareRequest(
"contractLoading",
"Get > /safetyEval/institution/eval-contract/get",
);
export const evalContractSave = declareRequest(
"contractSaveLoading",
"Post > @/safetyEval/institution/eval-contract/save",
);
export const evalRiskAnalysisPeopleSave = declareRequest(
"riskAnalysisSaveLoading",
"Post > @/safetyEval/institution/eval-risk-analysis/participant/save",
);

View File

@ -184,7 +184,7 @@ const SiteReviewNotice = (props) => {
{ title: "机构名称", dataIndex: "unitName", ellipsis: true },
{
title: "现场审查时间", dataIndex: "reviewDateStart",
render: (val) => val ? dayjs(val).format("YYYY-MM-DD HH:mm") : "-",
},
{ title: "审查地点", dataIndex: "reviewLocation", ellipsis: true },
{ title: "审查组成员", dataIndex: "reviewMembers", ellipsis: true },
@ -384,7 +384,7 @@ const SiteReviewNotice = (props) => {
<Form.Item name="reviewResult" label="审查结论" rules={[{ required: true, message: "请选择" }]}>
<Select placeholder="请选择">
<Select.Option value={true}>审查通过</Select.Option>
<Select.Option value={true}>补正材料后通过</Select.Option>
<Select.Option value={false}>不通过</Select.Option>
</Select>
</Form.Item>

View File

@ -1,38 +1,69 @@
import React from "react";
import { Form, Table, Tag, Button, Card, Row, Col, Statistic, Select } from "antd";
import React, { useState, useEffect } from "react";
import {
Form, Table, Tag, Button, Card, Row, Col, Statistic, Select, Modal, message,
} from "antd";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { tools } from "@cqsjjb/jjb-common-lib";
const MOCK_LIST = [
{
id: 1, projectName: "华安化工园区安全预评价", projectCode: "XP-2026-001",
myRole: "项目负责人", leader: "张建国",
startDate: "2026-03-01", endDate: "2026-09-30", phase: "正常",
},
{
id: 2, projectName: "鼎信建设安全验收评价", projectCode: "XP-2026-002",
myRole: "报告编制人", leader: "李明华",
startDate: "2026-05-15", endDate: "2026-11-15", phase: "正常",
},
{
id: 3, projectName: "安环检测年度安全现状评价", projectCode: "XP-2025-045",
myRole: "过程控制负责人", leader: "陈志强",
startDate: "2025-08-01", endDate: "2026-05-30", phase: "延期",
},
];
const { router } = tools;
const MyProject = (props) => {
const [form] = Form.useForm();
const [searchForm] = Form.useForm();
const [dataSource, setDataSource] = useState([]);
const [total, setTotal] = useState(0);
const { evalProjectLoading } = props.safetyEvalBusiness;
const getData = async (pagination) => {
const params = {
...router.query,
myProject: true,
current: pagination?.current || router.query.current || 1,
size: pagination?.size || router.query.size || 10,
};
const res = await props.evalProjectPage(params);
if (res?.success !== false) {
setDataSource(res?.data || []);
setTotal(res?.total || 0);
}
};
useEffect(() => {
searchForm.setFieldsValue(router.query);
getData();
}, []);
const handleSearch = (values) => {
router.query = { ...router.query, ...values, current: 1, size: 10 };
getData();
};
const handleReset = (values) => {
searchForm.resetFields();
router.query = { ...values, current: 1, size: 10 };
getData();
};
const handlePageChange = (pagination) => {
router.query = {
...router.query,
current: pagination.current,
size: pagination.pageSize,
};
getData(pagination);
};
const columns = [
{
title: "序号", dataIndex: "id", width: 60, fixed: "left",
title: "序号", width: 60, fixed: "left",
render: (_, __, index) => index + 1,
},
{
@ -40,26 +71,30 @@ const MyProject = (props) => {
render: (text, record) => (
<div>
<div>{text}</div>
<div style={{ fontSize: 12, color: "#999" }}>{record.projectCode}</div>
<div style={{ fontSize: 12, color: "#999" }}>
{record.projectNo} · {record.evalTypeName}
</div>
</div>
),
},
{ title: "我的角色", dataIndex: "myRole", width: 130 },
{ title: "项目负责人", dataIndex: "leader", width: 100 },
{ title: "项目开始时间", dataIndex: "startDate", width: 120 },
{ title: "项目结束时间", dataIndex: "endDate", width: 120 },
{ title: "项目负责人", dataIndex: "projectLeaderName", width: 100 },
{ title: "项目开始时间", dataIndex: "planStartDate", width: 120 },
{ title: "项目结束时间", dataIndex: "planEndDate", width: 120 },
{
title: "项目阶段", dataIndex: "phase", width: 100,
render: (phase) => (
<Tag color={phase === "延期" ? "error" : "success"}>{phase}</Tag>
),
title: "项目阶段", dataIndex: "projectPhaseName", width: 100,
render: (phase) => {
const color = phase === "延期" ? "error" : phase === "正常" ? "success" : undefined;
return phase ? <Tag color={color}>{phase}</Tag> : "";
},
},
{
title: "操作", width: 140, fixed: "right",
render: (_, record) => (
<TableAction>
<Button type="link" size="small" onClick={() => props.history.push(`ProjectFlow?id=${record.id}`)}>编辑</Button>
<Button type="link" size="small" danger>作废</Button>
<Button type="link" size="small" onClick={() =>
props.history.push(`ProjectFlow?id=${record.id}`)}>编辑</Button>
</TableAction>
),
},
@ -70,7 +105,7 @@ const MyProject = (props) => {
<Row gutter={16} style={{ marginBottom: 16 }}>
<Col span={6}>
<Card size="small">
<Statistic title="参与项目" value={8} suffix="个" />
<Statistic title="参与项目" value={total} suffix="个" />
<div style={{ fontSize: 12, color: "#999", marginTop: 4 }}>负责人/编制人/审核人</div>
</Card>
</Col>
@ -95,52 +130,40 @@ const MyProject = (props) => {
</Row>
<SearchForm
form={form}
form={searchForm}
loading={false}
formLine={[
<Form.Item key="projectName" name="projectName">
<ControlWrapper.Input label="评价项目名称" placeholder="请输入" allowClear />
</Form.Item>,
<Form.Item key="myRole" name="myRole">
<ControlWrapper.Select label="我的角色" placeholder="请选择" allowClear style={{ width: "100%" }}>
<Select.Option value="项目负责人">项目负责人</Select.Option>
<Select.Option value="报告编制人">报告编制人</Select.Option>
<Select.Option value="技术负责人">技术负责人</Select.Option>
<Select.Option value="过程控制负责人">过程控制负责人</Select.Option>
</ControlWrapper.Select>
</Form.Item>,
<Form.Item key="phase" name="phase">
<ControlWrapper.Select label="项目阶段" placeholder="请选择" allowClear style={{ width: "100%" }}>
<Select.Option value="正常">正常</Select.Option>
<Select.Option value="延期">延期</Select.Option>
<Select.Option value="作废">作废</Select.Option>
</ControlWrapper.Select>
</Form.Item>,
]}
onFinish={() => {}}
onReset={() => form.resetFields()}
onFinish={handleSearch}
onReset={handleReset}
style={{ marginBottom: 24 }}
/>
<Table
rowKey="id"
columns={columns}
dataSource={MOCK_LIST}
scroll={{ y: props.scrollY }}
loading={false}
dataSource={dataSource}
scroll={{ y: props.scrollY, x: 1100 }}
loading={evalProjectLoading}
pagination={{
total: MOCK_LIST.length,
total,
current: router.query.current || 1,
pageSize: router.query.size || 10,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `${total}`,
pageSize: 10,
}}
onChange={handlePageChange}
/>
</PageLayout>
);
};
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect, useState } from "react";
import {
Tag,
Button,
@ -10,348 +10,283 @@ import {
Row,
Col,
Flex,
message,
Spin,
} from "antd";
import dayjs from "dayjs";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import AttachmentUpload from "~/components/AttachmentUpload";
const { router } = tools;
const { TextArea } = Input;
const ContractContent = () => {
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) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [saving, setSaving] = useState(false);
const projectId = router.query?.id;
const { safetyEvalBusiness, evalContractGet, evalContractSave } = props;
const { contractLoading } = safetyEvalBusiness || {};
const fetchData = async () => {
if (!projectId) return;
setLoading(true);
try {
const res = await evalContractGet({ projectId });
if (res?.success !== false && res?.data) {
form.setFieldsValue({
...res.data,
contractStartDate: res.data.contractStartDate ? dayjs(res.data.contractStartDate) : undefined,
contractEndDate: res.data.contractEndDate ? dayjs(res.data.contractEndDate) : undefined,
});
}
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, [projectId]);
const handleSave = async () => {
try {
const values = await form.validateFields();
setSaving(true);
const { contractStartDate, contractEndDate, ...rest } = values;
const res = await evalContractSave({
...rest,
projectId,
contractStartDate: contractStartDate ? contractStartDate.format("YYYY-MM-DD") : undefined,
contractEndDate: contractEndDate ? contractEndDate.format("YYYY-MM-DD") : undefined,
});
if (res?.success !== false) {
message.success("合同保存成功");
}
} finally {
setSaving(false);
}
};
return (
<div>
<div className="pf-permission">
<Tag color="blue" className="pf-tag">
机构管理员 / 项目负责人
</Tag>
<span className="pf-desc">
按照已批准的风险分析结论录入项目合同和被评价企业信息上传PDF格式的正式合同扫描件
</span>
<Spin spinning={loading || contractLoading}>
<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">
<Card type="inner" size="small" title="项目合同信息" extra={<Tag color="blue">合同基本信息</Tag>} className="pf-section">
<Row gutter={16}>
<Col span={24}>
<Form.Item label="机构名称" name="orgName" rules={[{ required: true, message: "请填写机构名称" }]}>
<Input placeholder="请输入机构名称" maxLength={100} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="合同编号" name="contractNo" rules={[{ required: true, message: "请填写合同编号" }]}>
<Input placeholder="请输入合同编号" maxLength={50} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目名称" name="projectName" rules={[{ required: true, message: "请填写项目名称" }]}>
<Input placeholder="请输入项目名称" maxLength={100} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目简介" name="projectIntro" rules={[{ required: true, message: "请填写项目简介" }]}>
<TextArea rows={3} maxLength={500} showCount placeholder="请输入项目简介" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="合同金额(万元)" name="amount">
<Input placeholder="请输入合同金额" maxLength={20} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="项目类型" name="projectTypeCode" rules={[{ required: true, message: "请选择项目类型" }]}>
<Select placeholder="请选择项目类型" allowClear>
{PROJECT_TYPE_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>{opt.label}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目风险分析" name="riskSummary" rules={[{ required: true, message: "请填写项目风险分析" }]}>
<TextArea rows={3} maxLength={500} showCount placeholder="自动带入风险分析结论,可补充说明" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目所在地" name="projectRegion" rules={[{ required: true, message: "请填写项目所在地" }]}>
<TextArea rows={2} maxLength={200} showCount placeholder="请输入项目所在地" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目详细地址" name="projectAddress" rules={[{ required: true, message: "请填写项目详细地址" }]}>
<Input placeholder="请输入项目详细地址" maxLength={200} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="合同开始时间" name="contractStartDate" rules={[{ required: true, message: "请选择合同开始时间" }]}>
<DatePicker className="pf-w-full" allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="合同结束时间" name="contractEndDate" rules={[{ required: true, message: "请选择合同结束时间" }]}>
<DatePicker className="pf-w-full" allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="评价类型" name="evalTypeCode" rules={[{ required: true, message: "请选择评价类型" }]}>
<Select placeholder="请选择评价类型" allowClear>
{EVAL_TYPE_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>{opt.label}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="是否生产剧毒化学品" name="toxicFlag" rules={[{ required: true, message: "请选择" }]}>
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>{opt.label}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="是否生产易制毒化学品" name="precursorFlag" rules={[{ required: true, message: "请选择" }]}>
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>{opt.label}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="是否跨省建设项目" name="crossProvinceFlag" rules={[{ required: true, message: "请选择" }]}>
<Select placeholder="请选择" allowClear>
{YES_NO_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>{opt.label}</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="项目业务范围" name="businessScope" rules={[{ required: true, message: "请填写项目业务范围" }]}>
<Input placeholder="请输入项目业务范围" maxLength={200} allowClear />
</Form.Item>
</Col>
</Row>
</Card>
<Card type="inner" size="small" title="被评价企业信息" extra={<Tag color="blue">合同服务对象</Tag>} className="pf-section">
<Row gutter={16}>
<Col span={24}>
<Form.Item label="企业名称" name="enterpriseName" rules={[{ required: true, message: "请填写企业名称" }]}>
<Input placeholder="请输入企业名称" maxLength={100} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="国民经济行业类别" name="industryCategory">
<TextArea rows={2} maxLength={200} showCount placeholder="请输入国民经济行业类别" />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="办公地址" name="officeAddress">
<Input placeholder="请输入办公地址" maxLength={200} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="社会统一信用代码" name="creditCode">
<Input placeholder="请输入社会统一信用代码" maxLength={18} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="邮政编码" name="postCode">
<Input placeholder="请输入邮政编码" maxLength={10} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="企业电话" name="enterprisePhone">
<Input placeholder="请输入企业电话" maxLength={20} allowClear />
</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">
<Input placeholder="请输入法人代表" maxLength={20} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="联系人" name="contactName" rules={[{ required: true, message: "请填写联系人" }]}>
<Input placeholder="请输入联系人" maxLength={20} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="职工人数" name="staffCount">
<Input placeholder="请输入职工人数" maxLength={10} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="联系人电话" name="contactPhone" rules={[{ required: true, message: "请填写联系人电话" }]}>
<Input placeholder="请输入联系人电话" maxLength={20} allowClear />
</Form.Item>
</Col>
</Row>
</Card>
<AttachmentUpload
name="scanFileUrl"
label="项目合同扫描件"
accept=".pdf"
maxCount={10}
extra="请上传PDF文件大小不应超过500MB不超过10个文件。"
/>
</Form>
<Flex justify="flex-end" gap={8}>
<Button onClick={() => props.history.goBack()}>取消</Button>
<Button type="primary" onClick={handleSave} loading={saving}>完成合同录入并保存</Button>
</Flex>
</Card>
</div>
<Card title="项目合同信息" styles={{ header: { textAlign: "center" } }}>
<Form
form={form}
layout="vertical"
initialValues={{
orgName: "重庆市安全生产科学研究有限公司",
contractCode: "HT00000000000000000001",
projectName: "重庆市安全生产科学研究有限公司工程项目安全预评价",
projectIntro: "项目简介",
amount: 3,
projectType: "新建项目",
riskAnalysis:
"火灾、爆炸、中毒、触电、高处坠落、坍塌等,风险程度为中度,具备签约基础。",
location: "重庆市",
address: "重庆市渝北区",
startDate: null,
endDate: null,
evalType: "预评价",
toxicChem: "否",
precursorChem: "否",
crossProvince: "否",
bizScope: "金属冶炼",
enterpriseName: "重庆市安全生产科学研究有限公司",
industryCategory: "科学研究和技术服务业",
officeAddress: "重庆市渝北区",
creditCode: "915001072028699512",
postCode: "401120",
phone: "023-68705577",
fax: "023-68705577",
legalPerson: "刘先生",
contactPerson: "刘先生",
employeeCount: 5500,
contactPhone: "18070969727",
}}
>
<Card
type="inner"
size="small"
title="项目合同信息"
extra={<Tag color="blue">合同基本信息</Tag>}
className="pf-section"
>
<Row gutter={16}>
<Col span={24}>
<Form.Item
label="机构名称"
name="orgName"
rules={[{ required: true, message: "请填写机构名称" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="合同编号"
name="contractCode"
rules={[{ required: true, message: "请填写合同编号" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目名称"
name="projectName"
rules={[{ required: true, message: "请填写项目名称" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目简介"
name="projectIntro"
rules={[{ required: true, message: "请填写项目简介" }]}
>
<TextArea
rows={3}
maxLength={150}
showCount
placeholder="请输入项目简介"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="合同金额(万元)" name="amount">
<Input type="number" min={0} step={0.01} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="项目类型"
name="projectType"
rules={[{ required: true, message: "请选择项目类型" }]}
>
<Select>
<Select.Option value="新建项目">新建项目</Select.Option>
<Select.Option value="续评项目">续评项目</Select.Option>
<Select.Option value="变更项目">变更项目</Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目风险分析"
name="riskAnalysis"
rules={[{ required: true, message: "请填写项目风险分析" }]}
>
<TextArea
rows={3}
maxLength={150}
showCount
placeholder="自动带入风险分析结论,可补充说明"
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目所在地"
name="location"
rules={[{ required: true, message: "请填写项目所在地" }]}
>
<TextArea
rows={2}
maxLength={150}
showCount
placeholder="请输入项目所在地"
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目详细地址"
name="address"
rules={[{ required: true, message: "请填写项目详细地址" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="合同开始时间"
name="startDate"
rules={[{ required: true, message: "请选择合同开始时间" }]}
>
<DatePicker className="pf-w-full" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="合同结束时间"
name="endDate"
rules={[{ required: true, message: "请选择合同结束时间" }]}
>
<DatePicker className="pf-w-full" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="评价类型"
name="evalType"
rules={[{ required: true, message: "请选择评价类型" }]}
>
<Select>
<Select.Option value="预评价">预评价</Select.Option>
<Select.Option value="验收评价">验收评价</Select.Option>
<Select.Option value="现状评价">现状评价</Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="是否生产剧毒化学品"
name="toxicChem"
rules={[
{ required: true, message: "请选择是否生产剧毒化学品" },
]}
>
<Select>
<Select.Option value="否"></Select.Option>
<Select.Option value="是"></Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="是否生产易制毒化学品"
name="precursorChem"
rules={[
{ required: true, message: "请选择是否生产易制毒化学品" },
]}
>
<Select>
<Select.Option value="否"></Select.Option>
<Select.Option value="是"></Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="是否跨省建设项目"
name="crossProvince"
rules={[
{ required: true, message: "请选择是否跨省建设项目" },
]}
>
<Select>
<Select.Option value="否"></Select.Option>
<Select.Option value="是"></Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="项目业务范围"
name="bizScope"
rules={[{ required: true, message: "请填写项目业务范围" }]}
>
<Input />
</Form.Item>
</Col>
</Row>
</Card>
<Card
type="inner"
size="small"
title="被评价企业信息"
extra={<Tag color="blue">合同服务对象</Tag>}
className="pf-section"
>
<Row gutter={16}>
<Col span={24}>
<Form.Item
label="企业名称"
name="enterpriseName"
rules={[{ required: true, message: "请填写企业名称" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="国民经济行业类别" name="industryCategory">
<TextArea
rows={2}
maxLength={150}
showCount
placeholder="请输入国民经济行业类别"
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="办公地址" name="officeAddress">
<Input />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item label="社会统一信用代码" name="creditCode">
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="邮政编码" name="postCode">
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="企业电话" name="phone">
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="传真" name="fax">
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="法人代表" name="legalPerson">
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="联系人"
name="contactPerson"
rules={[{ required: true, message: "请填写联系人" }]}
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="职工人数" name="employeeCount">
<Input type="number" min={0} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="联系人电话"
name="contactPhone"
rules={[{ required: true, message: "请填写联系人电话" }]}
>
<Input />
</Form.Item>
</Col>
</Row>
</Card>
<AttachmentUpload
name="contractFiles"
label="项目合同扫描件"
accept=".pdf"
maxCount={10}
extra={"请上传PDF文件并且大小不应超过500MB不超过10个文件。"}
/>
</Form>
<Flex justify="flex-end" gap={8}>
<Button>取消</Button>
<Button type="primary">完成合同录入并保存</Button>
</Flex>
</Card>
</div>
</Spin>
);
};
export default ContractContent;
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(ContractContent);

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect, useState } from "react";
import {
Tag,
Button,
@ -12,356 +12,450 @@ import {
Radio,
DatePicker,
Flex,
message,
Spin,
} from "antd";
import dayjs from "dayjs";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
import { tools } from "@cqsjjb/jjb-common-lib";
const { router } = tools;
const { TextArea } = Input;
const RiskAnalysisContent = () => {
const EVAL_TYPE_OPTIONS = [
{ label: "安全预评价", value: "PRE" },
{ label: "安全验收评价", value: "ACCEPT" },
{ label: "安全现状评价", value: "STATUS" },
];
const RiskAnalysisContent = (props) => {
const [form] = Form.useForm();
const projectId = router.query?.id;
const {
safetyEvalBusiness,
evalRiskAnalysisGet,
evalRiskAnalysisSave,
evalProjectDetail,
evalRiskAnalysisPeopleSave,
} = props;
const {
riskAnalysisLoading,
evalProjectDetailLoading,
riskAnalysisSaveLoading,
} = safetyEvalBusiness || {};
// 查询风险分析数据回显
const fetchData = async () => {
if (!projectId) return;
const res = await evalRiskAnalysisGet({ projectId });
if (res?.success !== false && res?.data) {
form.setFieldsValue({
...res.data,
analysisDate: res.data.analysisDate
? dayjs(res.data.analysisDate)
: undefined,
});
} else {
form.setFieldsValue({
evalTypeCode: r.data.evalTypeCode,
projectName: r.data.projectName,
industryName: r.data.industryCode,
});
}
};
useEffect(() => {
if (evalProjectDetail?.id) {
fetchData();
}
}, [projectId, evalProjectDetail?.id]);
// 保存
const handleSave = async (statusCode) => {
const values = await form.validateFields();
const { analysisDate, ...rest } = values;
const res = await evalRiskAnalysisSave({
...rest,
projectId,
statusCode,
analysisDate: analysisDate
? analysisDate.format("YYYY-MM-DD")
: undefined,
});
if (res?.success && res.data && rest.participants?.length) {
const result = await evalRiskAnalysisPeopleSave(
rest.participants.map((item) => {
return {
...item,
riskId: res.data.id,
};
}),
);
if (result.success) {
message.success(statusCode === 2 ? "风险分析已完成" : "已暂存");
}
}
};
return (
<div>
<div className="pf-permission">
<Tag color="blue" className="pf-tag">
市场部经办人 / 市场部经理
</Tag>
<span className="pf-desc">
市场部组织前置条件调查和风险分析相关职能部门参与市场部经理依据分析结果决定是否签订技术服务合同
</span>
</div>
<Card
title="安全评价风险分析记录表受控编号QAPJ-CX-1-JL01"
styles={{ header: { textAlign: "center" } }}
>
<Form
form={form}
layout="vertical"
initialValues={{
projectName: "华安化工园区安全预评价",
evalType: "安全预评价",
industry: "危险化学品",
scope: "华安化工园区建设项目及配套生产装置、公用工程、安全设施。",
inScope: "yes",
overview:
"重庆华安安全科技有限公司拟建设化工园区配套项目,项目位于重庆市渝北区。评价范围包括主要生产装置、储存设施、公用工程及配套安全设施,周边环境和外部安全防护距离需进一步核查。",
hazard:
"火灾、爆炸、中毒和窒息、化学灼伤、触电、机械伤害、车辆伤害、高处坠落等。",
staffQualified: "yes",
needExpert: "no",
ability: "yes",
feasible: "yes",
economic: "yes",
riskLevel: "middle",
contract: "sign",
participants: [
{
name: "张建国",
dept: "市场部",
opinion: "同意承接,按中度风险组织评价。",
},
{
name: "李明华",
dept: "评价部",
opinion: "人员专业和评价周期能够满足要求。",
},
],
}}
<Spin spinning={evalProjectDetailLoading || riskAnalysisLoading}>
<div>
<div className="pf-permission">
<Tag color="blue" className="pf-tag">
市场部经办人 / 市场部经理
</Tag>
<span className="pf-desc">
市场部组织前置条件调查和风险分析相关职能部门参与市场部经理依据分析结果决定是否签订技术服务合同
</span>
</div>
<Card
title="安全评价风险分析记录表受控编号QAPJ-CX-1-JL01"
styles={{ header: { textAlign: "center" } }}
>
<Form form={form} layout="vertical">
<Row gutter={16}>
<Col span={12}>
<Form.Item label="风险分析时间" name="analysisDate">
<DatePicker className="pf-w-full" allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="评价项目名称" name="projectName">
<Input
placeholder="请输入评价项目名称"
maxLength={50}
allowClear
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="评价类别" name="evalTypeCode">
<Select placeholder="请选择评价类别" allowClear>
{EVAL_TYPE_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="所属行业" name="industryName">
<Select placeholder="请选择所属行业" allowClear>
{QUALIFICATION_INDUSTRY_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}>
{opt.label}
</Select.Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
<Form.Item label="评价范围" name="evalScope">
<TextArea
rows={2}
placeholder="明确本项目安全评价对象、装置、区域及委托范围"
maxLength={200}
showCount
/>
</Form.Item>
<Form.Item label="是否在公司资质业务范围内" name="inBizScopeFlag">
<Radio.Group>
<Radio value={1}></Radio>
<Radio value={2}></Radio>
</Radio.Group>
</Form.Item>
<Card
type="inner"
size="small"
title="一、被评价单位基本概况"
className="pf-section"
>
<Form.Item name="unitOverview">
<TextArea
rows={4}
placeholder="填写项目简介、投资规模、地理位置、周边环境、主要设施及客户要求"
maxLength={500}
showCount
/>
</Form.Item>
</Card>
<Card
type="inner"
size="small"
title="二、项目行业风险特性分析"
className="pf-section"
>
<Form.Item name="industryRiskDesc">
<TextArea
rows={3}
placeholder="分析项目所属行业的主要危险、有害因素"
maxLength={500}
showCount
/>
</Form.Item>
<div className="pf-hint-blue">
应结合项目行业特点地理位置周边环境和评价类别填写非常规项目应通过风险分析会议形成记录
</div>
</Card>
<Card
type="inner"
size="small"
title="三、评价机构符合情况"
className="pf-section"
>
<Form.Item
label="1评价人员专业构成是否满足该项目的评价需求"
name="staffMatchCode"
>
<Radio.Group>
<Radio value={1}>满足</Radio>
<Radio value={2}>不满足</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
label="2是否需要聘请相关技术专家"
name="needExpertCode"
>
<Radio.Group>
<Radio value={2}>不需要</Radio>
<Radio value={1}>需要</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
label="3是否有能力承担该项目的评价风险"
name="capabilityCode"
>
<Radio.Group>
<Radio value={1}></Radio>
<Radio value={2}></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="4项目的可行性分析" name="feasibleCode">
<Radio.Group>
<Radio value={1}>可行</Radio>
<Radio value={2}>不可行</Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="5项目的经济性分析" name="economicCode">
<Radio.Group>
<Radio value={1}>有经济效益</Radio>
<Radio value={2}>无经济效益</Radio>
</Radio.Group>
</Form.Item>
</Card>
<Card
type="inner"
size="small"
title="风险分析结论"
className="pf-section"
>
<Form.Item label="风险程度" name="riskLevelCode">
<Radio.Group>
<Radio value={1}>低度</Radio>
<Radio value={2}>中度</Radio>
<Radio value={3}>高度</Radio>
</Radio.Group>
</Form.Item>
<div className="pf-risk-note">
中度化工金属非金属矿山金属冶炼陆地油气开采等行业评价项目
</div>
<Form.Item label="合同签订" name="signContractCode">
<Radio.Group>
<Radio value={1}>签合同</Radio>
<Radio value={2}>不签合同</Radio>
</Radio.Group>
</Form.Item>
<div className="pf-hint-blue">
系统建议当前条件具备签约基础最终结论由市场部经理批准
</div>
</Card>
<Card type="inner" size="small" title="参与风险分析人员签字">
<Form.List name="participants">
{(fields, { add, remove }) => (
<>
<Table
dataSource={fields}
columns={[
{
title: "姓名",
dataIndex: "name",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "personnelName"]}
noStyle
>
<Input
placeholder="姓名"
maxLength={20}
allowClear
/>
</Form.Item>
);
},
},
{
title: "部门/岗位",
dataIndex: "deptName",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "deptName"]}
noStyle
>
<Input
placeholder="部门/岗位"
maxLength={20}
allowClear
/>
</Form.Item>
);
},
},
{
title: "分析意见",
dataIndex: "opinion",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "opinion"]}
noStyle
>
<Input
placeholder="填写分析意见"
maxLength={30}
allowClear
/>
</Form.Item>
);
},
},
{
title: "签字状态",
render: (_, field) => (
<Button size="small">发起APP签字</Button>
),
},
{
title: "操作",
render: (_, field) =>
fields.length > 1 ? (
<Button
type="link"
danger
size="small"
onClick={() => remove(field.name)}
>
删除
</Button>
) : null,
},
]}
rowKey={(_, index) => index}
pagination={false}
/>
<Button
type="dashed"
size="small"
style={{ marginTop: 8 }}
onClick={() =>
add({ personnelName: "", deptName: "", opinion: "" })
}
>
添加参与人员
</Button>
</>
)}
</Form.List>
</Card>
</Form>
</Card>
<Card
title="管理办法判定提示"
size="small"
className="pf-rule-card pf-section"
>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="风险分析时间" name="analysisDate">
<DatePicker className="pf-w-full" />
</Form.Item>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>低度风险</strong>
</div>
<div className="pf-risk-card">
小型露天采石场加油站以及机构熟悉且开展过类似评价工作的常规项目
</div>
</Card>
</Col>
<Col span={12}>
<Form.Item label="评价项目名称" name="projectName">
<Input />
</Form.Item>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>中度风险</strong>
</div>
<div className="pf-risk-card">
化工生产金属非金属矿山金属冶炼陆地石油和天然气开采行业的评价项目
</div>
</Card>
</Col>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>高度风险</strong>
</div>
<div className="pf-risk-card">
机构未开展过的非常规项目原则上组织专项风险分析会议必要时总经理参加
</div>
</Card>
</Col>
</Row>
<div className="pf-reject-note">
<strong>不签合同重点条件</strong>
超出资质范围无法提供合法有效资料客户提出违法或不合理要求经济性达不到预期评价时间不能满足机构与被评价对象存在投资咨询设计监理物资供应等利益关系
</div>
</Card>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="评价类别" name="evalType">
<Select>
<Select.Option value="安全预评价">安全预评价</Select.Option>
<Select.Option value="安全验收评价">
安全验收评价
</Select.Option>
<Select.Option value="安全现状评价">
安全现状评价
</Select.Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="所属行业" name="industry">
<Input placeholder="请输入项目所属行业" />
</Form.Item>
</Col>
</Row>
<Form.Item label="评价范围" name="scope">
<TextArea
rows={2}
placeholder="明确本项目安全评价对象、装置、区域及委托范围"
/>
</Form.Item>
<Form.Item label="是否在公司资质业务范围内" name="inScope">
<Radio.Group>
<Radio value="yes"></Radio>
<Radio value="no"></Radio>
</Radio.Group>
</Form.Item>
<Card
type="inner"
size="small"
title="一、被评价单位基本概况"
className="pf-section"
<Flex justify="flex-end" gap={8}>
<Button
onClick={() => handleSave(1)}
loading={riskAnalysisSaveLoading}
>
<Form.Item name="overview">
<TextArea
rows={4}
placeholder="填写项目简介、投资规模、地理位置、周边环境、主要设施及客户要求"
/>
</Form.Item>
</Card>
<Card
type="inner"
size="small"
title="二、项目行业风险特性分析"
className="pf-section"
>
<Form.Item name="hazard">
<TextArea
rows={3}
placeholder="分析项目所属行业的主要危险、有害因素"
/>
</Form.Item>
<div className="pf-hint-blue">
应结合项目行业特点地理位置周边环境和评价类别填写非常规项目应通过风险分析会议形成记录
</div>
</Card>
<Card
type="inner"
size="small"
title="三、评价机构符合情况"
className="pf-section"
>
<Form.Item
label="1评价人员专业构成是否满足该项目的评价需求"
name="staffQualified"
>
<Radio.Group>
<Radio value="yes">满足</Radio>
<Radio value="no">不满足</Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="2是否需要聘请相关技术专家" name="needExpert">
<Radio.Group>
<Radio value="no">不需要</Radio>
<Radio value="yes">需要</Radio>
</Radio.Group>
</Form.Item>
<Form.Item
label="3是否有能力承担该项目的评价风险"
name="ability"
>
<Radio.Group>
<Radio value="yes"></Radio>
<Radio value="no"></Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="4项目的可行性分析" name="feasible">
<Radio.Group>
<Radio value="yes">可行</Radio>
<Radio value="no">不可行</Radio>
</Radio.Group>
</Form.Item>
<Form.Item label="5项目的经济性分析" name="economic">
<Radio.Group>
<Radio value="yes">有经济效益</Radio>
<Radio value="no">无经济效益</Radio>
</Radio.Group>
</Form.Item>
</Card>
<Card
type="inner"
size="small"
title="风险分析结论"
className="pf-section"
>
<Form.Item label="风险程度" name="riskLevel">
<Radio.Group>
<Radio value="low">低度</Radio>
<Radio value="middle">中度</Radio>
<Radio value="high">高度</Radio>
</Radio.Group>
</Form.Item>
<div className="pf-risk-note">
中度化工金属非金属矿山金属冶炼陆地油气开采等行业评价项目
</div>
<Form.Item label="合同签订" name="contract">
<Radio.Group>
<Radio value="sign">签合同</Radio>
<Radio value="reject">不签合同</Radio>
</Radio.Group>
</Form.Item>
<div className="pf-hint-blue">
系统建议当前条件具备签约基础最终结论由市场部经理批准
</div>
</Card>
<Card
type="inner"
size="small"
title="参与风险分析人员签字"
>
<Form.List name="participants">
{(fields, { add, remove }) => (
<>
<Table
dataSource={fields}
columns={[
{
title: "姓名",
dataIndex: "name",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "name"]}
noStyle
>
<Input placeholder="姓名" />
</Form.Item>
);
},
},
{
title: "部门/岗位",
dataIndex: "dept",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "dept"]}
noStyle
>
<Input placeholder="部门/岗位" />
</Form.Item>
);
},
},
{
title: "分析意见",
dataIndex: "opinion",
render: (_, field) => {
const { key, ...fieldProps } = field;
return (
<Form.Item
{...fieldProps}
name={[field.name, "opinion"]}
noStyle
>
<Input placeholder="填写分析意见" />
</Form.Item>
);
},
},
{
title: "签字状态",
render: (_, field) => (
<Button size="small">发起APP签字</Button>
),
},
{
title: "操作",
render: (_, field) =>
fields.length > 1 ? (
<Button
type="link"
danger
size="small"
onClick={() => remove(field.name)}
>
删除
</Button>
) : null,
},
]}
rowKey={(_, index) => index}
pagination={false}
/>
<Button
type="dashed"
size="small"
style={{ marginTop: 8 }}
onClick={() => add({ name: "", dept: "", opinion: "" })}
>
添加参与人员
</Button>
</>
)}
</Form.List>
</Card>
</Form>
</Card>
<Card title="管理办法判定提示" size="small" className="pf-rule-card pf-section">
<Row gutter={16}>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>低度风险</strong>
</div>
<div className="pf-risk-card">
小型露天采石场加油站以及机构熟悉且开展过类似评价工作的常规项目
</div>
</Card>
</Col>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>中度风险</strong>
</div>
<div className="pf-risk-card">
化工生产金属非金属矿山金属冶炼陆地石油和天然气开采行业的评价项目
</div>
</Card>
</Col>
<Col span={8}>
<Card size="small" type="inner">
<div>
<strong>高度风险</strong>
</div>
<div className="pf-risk-card">
机构未开展过的非常规项目原则上组织专项风险分析会议必要时总经理参加
</div>
</Card>
</Col>
</Row>
<div className="pf-reject-note">
<strong>不签合同重点条件</strong>
超出资质范围无法提供合法有效资料客户提出违法或不合理要求经济性达不到预期评价时间不能满足机构与被评价对象存在投资咨询设计监理物资供应等利益关系
</div>
</Card>
<Flex justify="flex-end" gap={8}>
<Button>暂存</Button>
暂存
</Button>
<Button>打印记录表</Button>
<Button type="primary">完成分析并保存</Button>
<Button
type="primary"
onClick={() => handleSave(2)}
loading={riskAnalysisSaveLoading}
>
完成分析并保存
</Button>
</Flex>
</div>
</div>
</Spin>
);
};
export default RiskAnalysisContent;
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(RiskAnalysisContent);

View File

@ -4,6 +4,7 @@ import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import WpsEditor from "~/pages/Container/WpsEditor";
import RiskAnalysisContent from "./RiskAnalysisContent";
import ContractContent from "./ContractContent";
@ -82,11 +83,13 @@ const PROCESS_TABS = [
locked: true,
},
];
const { router } = tools;
const ProjectFlow = (props) => {
const [activeKey, setActiveKey] = useState("risk");
const [visible, setVisible] = useState(false);
const { wpsDoc } = props.safetyEvalBusiness || {};
const projectId = router.query?.id;
const handleTabChange = (key) => {
if (key === "report") {
@ -102,8 +105,11 @@ const ProjectFlow = (props) => {
useEffect(() => {
props.queryMyOrCreateDoc({
docxUrl: ''
});
docxUrl: "",
});
props.evalProjectDetail({
id: projectId,
});
}, []);
const tabItems = PROCESS_TABS.map((item) => {