dev-tmp1
tangjie 2026-08-12 14:37:45 +08:00
parent fd3b1f291e
commit 81209bb537
5 changed files with 863 additions and 590 deletions

View File

@ -12,10 +12,10 @@ module.exports = {
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
//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: "https://gbs-gateway.qhdsafety.com",
API_HOST: "http://192.168.0.103", //huwei
//API_HOST: "http://192.168.0.103", //huwei
},
production: {
// 应用后端分支名称,部署上线需要

View File

@ -41,3 +41,9 @@ export const regulatorSpotcheckDetail = declareRequest(
"regulatorSpotcheckDetailLoading",
"Get > /safetyEval/regulator/eval-report-spotcheck/get",
);
export const regulatorSpotCheckReport = declareRequest(
"regulatorSpotCheckReportLoading",
"Post > @/safetyEval/regulator/eval-report/spotCheckReport",
"data: [] | res.data || []",
);

View File

@ -6,20 +6,25 @@ import {
Modal,
Input,
Select,
InputNumber,
Row,
Col,
message,
DatePicker,
Space,
ConfigProvider,
Card,
} from "antd";
import {
DownloadOutlined,
ExportOutlined,
} from "@ant-design/icons";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
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 { 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 { tools } from "@cqsjjb/jjb-common-lib";
import dayjs from "dayjs";
@ -50,6 +55,13 @@ const INDUSTRY_OPTIONS = [
{ label: "建筑施工", value: "CONSTRUCTION" },
];
/** 抽检-检查类型(对齐原型) */
const CHECK_TYPE_OPTIONS = [
{ label: "安全评价报告质量抽查", value: "QUALITY" },
{ label: "专项监督检查", value: "SPECIAL" },
{ label: "年度随机抽查", value: "ANNUAL" },
];
const getYearOptions = () => {
const year = dayjs().year();
return [0, 1, 2].map((offset) => {
@ -247,12 +259,19 @@ const EvalReportDatabase = (props) => {
const [reviewRecord, setReviewRecord] = 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 {
regulatorEvalReportPageLoading,
regulatorEvalReportDetailLoading,
regulatorSpotcheckListLoading,
regulatorSpotcheckStartLoading,
regulatorSpotcheckReviewLoading,
regulatorSpotCheckReportLoading,
} = props.regulatorEvalReport || {};
const fetchSummary = async () => {
@ -290,8 +309,58 @@ const EvalReportDatabase = (props) => {
searchForm.setFieldsValue(q);
fetchSummary();
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 next = { ...values, current: 1, size: router.query.size || 20 };
if (next.archiveTimeRange?.length === 2) {
@ -523,7 +592,7 @@ const EvalReportDatabase = (props) => {
title: "报告编号",
dataIndex: "reportNo",
width: 150,
render: (val) => <span className="redb-mono">{val || "-"}</span>,
},
{
title: "报告名称",
@ -570,14 +639,14 @@ const EvalReportDatabase = (props) => {
width: 200,
fixed: "right",
render: (_, record) => (
<Space size={4} wrap>
<Button type="primary" size="small" onClick={() => handleViewDetail(record)}>
<TableAction size={4} wrap>
<a onClick={() => handleViewDetail(record)}>
查看报告
</Button>
<Button size="small" onClick={() => handleOpenAi(record)}>
</a>
<a onClick={() => handleOpenAi(record)}>
AI分析
</Button>
</Space>
</a>
</TableAction>
),
},
];
@ -641,9 +710,9 @@ const EvalReportDatabase = (props) => {
// 有整改反馈且尚未复核时可复核
if (record.rectifyFeedback && !record.reviewResultCode) {
return (
<Button type="link" size="small" onClick={() => handleOpenReview(record)}>
<a onClick={() => handleOpenReview(record)}>
复核
</Button>
</a>
);
}
return "-";
@ -739,6 +808,9 @@ const EvalReportDatabase = (props) => {
<span className="redb-total"> {total} 条报告记录</span>
</div>
<div className="redb-toolbar-right">
<Button type="primary" size="small" onClick={handleOpenSpotCheck}>
抽检
</Button>
<Button size="small" icon={<DownloadOutlined />} onClick={handleBatchDownload}>
批量下载
</Button>
@ -1177,12 +1249,147 @@ const EvalReportDatabase = (props) => {
</Form.Item>
</Form>
</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>
</ConfigProvider>
);
};
export default Connect(
[NS_REGULATOR_EVAL_REPORT],
[NS_REGULATOR_EVAL_REPORT, NS_ORG_INFO],
true,
)(AntdTableFuncControl(EvalReportDatabase));

View File

@ -79,40 +79,7 @@
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 */
.redb-modal-section {
@ -220,3 +187,18 @@
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;
}