fix
parent
fd3b1f291e
commit
81209bb537
|
|
@ -12,10 +12,10 @@ module.exports = {
|
||||||
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
|
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
|
||||||
//API_HOST: "http://localhost:80",
|
//API_HOST: "http://localhost:80",
|
||||||
|
|
||||||
// API_HOST: "http://192.168.0.134",
|
API_HOST: "http://192.168.0.134",
|
||||||
// API_HOST: "http://192.168.0.150", //太浅
|
// API_HOST: "http://192.168.0.150", //太浅
|
||||||
// API_HOST: "https://gbs-gateway.qhdsafety.com",
|
// API_HOST: "https://gbs-gateway.qhdsafety.com",
|
||||||
API_HOST: "http://192.168.0.103", //huwei
|
//API_HOST: "http://192.168.0.103", //huwei
|
||||||
},
|
},
|
||||||
production: {
|
production: {
|
||||||
// 应用后端分支名称,部署上线需要
|
// 应用后端分支名称,部署上线需要
|
||||||
|
|
|
||||||
|
|
@ -41,3 +41,9 @@ export const regulatorSpotcheckDetail = declareRequest(
|
||||||
"regulatorSpotcheckDetailLoading",
|
"regulatorSpotcheckDetailLoading",
|
||||||
"Get > /safetyEval/regulator/eval-report-spotcheck/get",
|
"Get > /safetyEval/regulator/eval-report-spotcheck/get",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const regulatorSpotCheckReport = declareRequest(
|
||||||
|
"regulatorSpotCheckReportLoading",
|
||||||
|
"Post > @/safetyEval/regulator/eval-report/spotCheckReport",
|
||||||
|
"data: [] | res.data || []",
|
||||||
|
);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -6,20 +6,25 @@ import {
|
||||||
Modal,
|
Modal,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
|
InputNumber,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
message,
|
message,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
Space,
|
Space,
|
||||||
ConfigProvider,
|
ConfigProvider,
|
||||||
|
Card,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import {
|
import {
|
||||||
DownloadOutlined,
|
DownloadOutlined,
|
||||||
ExportOutlined,
|
ExportOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
import { NS_REGULATOR_EVAL_REPORT } from "~/enumerate/namespace";
|
import { NS_REGULATOR_EVAL_REPORT, NS_ORG_INFO } from "~/enumerate/namespace";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
@ -50,6 +55,13 @@ const INDUSTRY_OPTIONS = [
|
||||||
{ label: "建筑施工", value: "CONSTRUCTION" },
|
{ label: "建筑施工", value: "CONSTRUCTION" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** 抽检-检查类型(对齐原型) */
|
||||||
|
const CHECK_TYPE_OPTIONS = [
|
||||||
|
{ label: "安全评价报告质量抽查", value: "QUALITY" },
|
||||||
|
{ label: "专项监督检查", value: "SPECIAL" },
|
||||||
|
{ label: "年度随机抽查", value: "ANNUAL" },
|
||||||
|
];
|
||||||
|
|
||||||
const getYearOptions = () => {
|
const getYearOptions = () => {
|
||||||
const year = dayjs().year();
|
const year = dayjs().year();
|
||||||
return [0, 1, 2].map((offset) => {
|
return [0, 1, 2].map((offset) => {
|
||||||
|
|
@ -247,12 +259,19 @@ const EvalReportDatabase = (props) => {
|
||||||
const [reviewRecord, setReviewRecord] = useState(null);
|
const [reviewRecord, setReviewRecord] = useState(null);
|
||||||
const [currentReport, setCurrentReport] = useState(null);
|
const [currentReport, setCurrentReport] = useState(null);
|
||||||
|
|
||||||
|
// 抽检
|
||||||
|
const [spotCheckVisible, setSpotCheckVisible] = useState(false);
|
||||||
|
const [spotCheckData, setSpotCheckData] = useState([]);
|
||||||
|
const [orgOptions, setOrgOptions] = useState([]);
|
||||||
|
const [spotCheckForm] = Form.useForm();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
regulatorEvalReportPageLoading,
|
regulatorEvalReportPageLoading,
|
||||||
regulatorEvalReportDetailLoading,
|
regulatorEvalReportDetailLoading,
|
||||||
regulatorSpotcheckListLoading,
|
regulatorSpotcheckListLoading,
|
||||||
regulatorSpotcheckStartLoading,
|
regulatorSpotcheckStartLoading,
|
||||||
regulatorSpotcheckReviewLoading,
|
regulatorSpotcheckReviewLoading,
|
||||||
|
regulatorSpotCheckReportLoading,
|
||||||
} = props.regulatorEvalReport || {};
|
} = props.regulatorEvalReport || {};
|
||||||
|
|
||||||
const fetchSummary = async () => {
|
const fetchSummary = async () => {
|
||||||
|
|
@ -290,8 +309,58 @@ const EvalReportDatabase = (props) => {
|
||||||
searchForm.setFieldsValue(q);
|
searchForm.setFieldsValue(q);
|
||||||
fetchSummary();
|
fetchSummary();
|
||||||
getData();
|
getData();
|
||||||
|
loadOrgOptions();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const loadOrgOptions = async () => {
|
||||||
|
try {
|
||||||
|
const res = await props.registeredOrgList({ current: 1, size: 200 });
|
||||||
|
const list = res?.data || [];
|
||||||
|
setOrgOptions(
|
||||||
|
list.map((item) => ({
|
||||||
|
label:
|
||||||
|
item.unitName ||
|
||||||
|
item.orgName ||
|
||||||
|
item.name ||
|
||||||
|
item.enterpriseName ||
|
||||||
|
String(item.id),
|
||||||
|
value: String(item.id),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
setOrgOptions([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenSpotCheck = () => {
|
||||||
|
spotCheckForm.resetFields();
|
||||||
|
spotCheckForm.setFieldsValue({
|
||||||
|
randomNumber: 2,
|
||||||
|
checkType: "QUALITY",
|
||||||
|
planCheckDate: dayjs(),
|
||||||
|
});
|
||||||
|
setSpotCheckData([]);
|
||||||
|
setSpotCheckVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSpotCheck = async () => {
|
||||||
|
const values = await spotCheckForm.validateFields().catch(() => null);
|
||||||
|
if (!values) return;
|
||||||
|
const res = await props.regulatorSpotCheckReport({
|
||||||
|
orgId: values.orgId,
|
||||||
|
randomNumber: values.randomNumber,
|
||||||
|
});
|
||||||
|
if (res?.success !== false) {
|
||||||
|
setSpotCheckData(res?.data || []);
|
||||||
|
message.success(`已随机抽取 ${res?.data?.length || 0} 份报告`);
|
||||||
|
setTimeout(() => {
|
||||||
|
document
|
||||||
|
.querySelector(".redb-modal .micro-temp-modal-body")
|
||||||
|
?.scrollTo({ top: 999999, behavior: "smooth" });
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSearch = (values) => {
|
const handleSearch = (values) => {
|
||||||
const next = { ...values, current: 1, size: router.query.size || 20 };
|
const next = { ...values, current: 1, size: router.query.size || 20 };
|
||||||
if (next.archiveTimeRange?.length === 2) {
|
if (next.archiveTimeRange?.length === 2) {
|
||||||
|
|
@ -523,7 +592,7 @@ const EvalReportDatabase = (props) => {
|
||||||
title: "报告编号",
|
title: "报告编号",
|
||||||
dataIndex: "reportNo",
|
dataIndex: "reportNo",
|
||||||
width: 150,
|
width: 150,
|
||||||
render: (val) => <span className="redb-mono">{val || "-"}</span>,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "报告名称",
|
title: "报告名称",
|
||||||
|
|
@ -570,14 +639,14 @@ const EvalReportDatabase = (props) => {
|
||||||
width: 200,
|
width: 200,
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
render: (_, record) => (
|
render: (_, record) => (
|
||||||
<Space size={4} wrap>
|
<TableAction size={4} wrap>
|
||||||
<Button type="primary" size="small" onClick={() => handleViewDetail(record)}>
|
<a onClick={() => handleViewDetail(record)}>
|
||||||
查看报告
|
查看报告
|
||||||
</Button>
|
</a>
|
||||||
<Button size="small" onClick={() => handleOpenAi(record)}>
|
<a onClick={() => handleOpenAi(record)}>
|
||||||
AI分析
|
AI分析
|
||||||
</Button>
|
</a>
|
||||||
</Space>
|
</TableAction>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -641,9 +710,9 @@ const EvalReportDatabase = (props) => {
|
||||||
// 有整改反馈且尚未复核时可复核
|
// 有整改反馈且尚未复核时可复核
|
||||||
if (record.rectifyFeedback && !record.reviewResultCode) {
|
if (record.rectifyFeedback && !record.reviewResultCode) {
|
||||||
return (
|
return (
|
||||||
<Button type="link" size="small" onClick={() => handleOpenReview(record)}>
|
<a onClick={() => handleOpenReview(record)}>
|
||||||
复核
|
复核
|
||||||
</Button>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return "-";
|
return "-";
|
||||||
|
|
@ -739,6 +808,9 @@ const EvalReportDatabase = (props) => {
|
||||||
<span className="redb-total">共 {total} 条报告记录</span>
|
<span className="redb-total">共 {total} 条报告记录</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="redb-toolbar-right">
|
<div className="redb-toolbar-right">
|
||||||
|
<Button type="primary" size="small" onClick={handleOpenSpotCheck}>
|
||||||
|
抽检
|
||||||
|
</Button>
|
||||||
<Button size="small" icon={<DownloadOutlined />} onClick={handleBatchDownload}>
|
<Button size="small" icon={<DownloadOutlined />} onClick={handleBatchDownload}>
|
||||||
批量下载
|
批量下载
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -1177,12 +1249,147 @@ const EvalReportDatabase = (props) => {
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
{/* 抽检 - 随机抽取并生成检查单 */}
|
||||||
|
<Modal
|
||||||
|
title="安评报告随机抽检"
|
||||||
|
open={spotCheckVisible}
|
||||||
|
onCancel={() => setSpotCheckVisible(false)}
|
||||||
|
footer={
|
||||||
|
<Space>
|
||||||
|
<Button onClick={() => setSpotCheckVisible(false)}>关闭</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
loading={regulatorSpotCheckReportLoading}
|
||||||
|
onClick={handleSpotCheck}
|
||||||
|
>
|
||||||
|
随机抽取并生成检查单
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
width={980}
|
||||||
|
destroyOnHidden
|
||||||
|
className="redb-modal"
|
||||||
|
>
|
||||||
|
<div className="redb-modal-section">
|
||||||
|
<h4>抽检设置</h4>
|
||||||
|
<p>从选定评价机构已报送的安全评价报告中随机抽取,生成监督检查单。</p>
|
||||||
|
</div>
|
||||||
|
<Form form={spotCheckForm} layout="vertical" preserve={false}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item
|
||||||
|
name="orgId"
|
||||||
|
label="评价机构"
|
||||||
|
rules={[{ required: true, message: "请选择评价机构" }]}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="label"
|
||||||
|
placeholder="请选择评价机构"
|
||||||
|
options={orgOptions}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item
|
||||||
|
name="randomNumber"
|
||||||
|
label="检查份数"
|
||||||
|
rules={[{ required: true, message: "请输入检查份数" }]}
|
||||||
|
>
|
||||||
|
<InputNumber min={1} max={10} style={{ width: "100%" }} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item name="checkType" label="检查类型">
|
||||||
|
<Select options={CHECK_TYPE_OPTIONS} />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item name="planCheckDate" label="计划检查日期">
|
||||||
|
<DatePicker style={{ width: "100%" }} placeholder="选择日期" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Form.Item name="checkLeader" label="检查负责人">
|
||||||
|
<Input placeholder="请输入检查负责人" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item name="checkLocation" label="检查地点">
|
||||||
|
<Input placeholder="请输入检查地点" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item name="checkMembers" label="检查组成员">
|
||||||
|
<Input placeholder="请输入检查组成员" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<Form.Item name="checkBasis" label="补充检查依据">
|
||||||
|
<TextArea rows={2} placeholder="可填写本次专项检查、年度计划或属地监管文件依据" />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
{spotCheckData.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="redb-modal-section">
|
||||||
|
<h4>随机抽取结果</h4>
|
||||||
|
<p>
|
||||||
|
本次从"
|
||||||
|
{orgOptions.find(
|
||||||
|
(o) => o.value === spotCheckForm.getFieldValue("orgId"),
|
||||||
|
)?.label || ""}
|
||||||
|
"报告库中随机抽取 {spotCheckData.length}{" "}
|
||||||
|
份,抽取结果已写入检查单。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="redb-modal-section">
|
||||||
|
<div className="redb-spotcheck-header">
|
||||||
|
<div>
|
||||||
|
<h4 style={{ margin: 0 }}>随机抽取报告</h4>
|
||||||
|
</div>
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
loading={regulatorSpotCheckReportLoading}
|
||||||
|
onClick={handleSpotCheck}
|
||||||
|
>
|
||||||
|
重新抽取
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
size="small"
|
||||||
|
columns={[
|
||||||
|
{ title: "报告名称", dataIndex: "reportName", ellipsis: true },
|
||||||
|
{ title: "被检查机构", dataIndex: "orgName", width: 200, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 90,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Button type="primary" size="small" onClick={() => handleViewDetail(record)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={spotCheckData}
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Connect(
|
export default Connect(
|
||||||
[NS_REGULATOR_EVAL_REPORT],
|
[NS_REGULATOR_EVAL_REPORT, NS_ORG_INFO],
|
||||||
true,
|
true,
|
||||||
)(AntdTableFuncControl(EvalReportDatabase));
|
)(AntdTableFuncControl(EvalReportDatabase));
|
||||||
|
|
|
||||||
|
|
@ -79,40 +79,7 @@
|
||||||
color: #991b1b;
|
color: #991b1b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 原型 modal:宽 980、圆角 12、头/底部分割线 */
|
|
||||||
.redb-modal {
|
|
||||||
.micro-temp-modal-content {
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.micro-temp-modal-header {
|
|
||||||
padding: 1rem 1.5rem;
|
|
||||||
border-bottom: 1px solid #e2e8f0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.micro-temp-modal-body {
|
|
||||||
padding: 1.5rem;
|
|
||||||
max-height: 72vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-width: none;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.micro-temp-modal-footer {
|
|
||||||
padding: 1rem 1.5rem;
|
|
||||||
border-top: 1px solid #e2e8f0;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 原型 .reg-modal-section */
|
/* 原型 .reg-modal-section */
|
||||||
.redb-modal-section {
|
.redb-modal-section {
|
||||||
|
|
@ -220,3 +187,18 @@
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.redb-spotcheck-desc {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #64748b;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.redb-spotcheck-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue