From 13ce70842529b77aaab6d7ec681076fbc5391678 Mon Sep 17 00:00:00 2001 From: tangjie <122778500@qq.com> Date: Mon, 20 Jul 2026 18:31:32 +0800 Subject: [PATCH] feat --- src/api/qualReview/index.js | 16 + src/api/safetyEvalBusiness/index.js | 12 + src/components/BaiduMapPicker/index.js | 2 +- src/pages/Container/Layout/menuConfig.js | 6 +- .../MonitorManage/RiskCenter/index.js | 4 +- .../SiteReviewNotice/index.js | 384 ++++++++++++++++++ .../CustomerManage/index.js | 2 +- src/pages/Container/WpsEditor/index.js | 80 ++-- src/pages/Container/WpsEditor/index.less | 3 +- 9 files changed, 467 insertions(+), 42 deletions(-) create mode 100644 src/pages/Container/QualificationReview/SiteReviewNotice/index.js diff --git a/src/api/qualReview/index.js b/src/api/qualReview/index.js index 8b9e887..7765492 100644 --- a/src/api/qualReview/index.js +++ b/src/api/qualReview/index.js @@ -81,4 +81,20 @@ export const queryQualMonitoringPageStatistics = declareRequest( "qualReviewLoading", "Get > /safetyEval/qual-filing/qualificationMonitoringPageStatistics", "monitorStats: {} | res.data || {}", +); + +export const querySiteReviewNoticePage = declareRequest( + "siteReviewNoticeLoading", + "Get > /safetyEval/site-review-notice/page", + 'siteReviewNoticeList: [] | res.data?.records || [] & siteReviewNoticeTotal: 0 | res.data?.total || 0', +); + +export const siteReviewNoticeSave = declareRequest( + "siteReviewNoticeSaveLoading", + "Post > @/safetyEval/site-review-notice/save", +); + +export const siteReviewResultSave = declareRequest( + "siteReviewResultSaveLoading", + "Post > @/safetyEval/site-review-result/save", ); \ No newline at end of file diff --git a/src/api/safetyEvalBusiness/index.js b/src/api/safetyEvalBusiness/index.js index d736c14..ef2c2d0 100644 --- a/src/api/safetyEvalBusiness/index.js +++ b/src/api/safetyEvalBusiness/index.js @@ -4,4 +4,16 @@ export const queryMyOrCreateDoc = declareRequest( "docLoading", "Get > /safetyEval-h5/wsp/doc/my-or-create", 'wpsDoc: {} | res.data || {}', +); + +export const fetchWpsDocTemplate = declareRequest( + "docTemplateLoading", + "Post > @/safetyEval-h5/wsp/doc/template", + 'docTemplate: {} | res.data || {}', +); + +export const createWpsDoc = declareRequest( + "createDocLoading", + "Post > @/safetyEval-h5/wsp/doc/create", + 'wpsDoc: {} | res.data || {}', ); \ No newline at end of file diff --git a/src/components/BaiduMapPicker/index.js b/src/components/BaiduMapPicker/index.js index cc01e97..bf70154 100644 --- a/src/components/BaiduMapPicker/index.js +++ b/src/components/BaiduMapPicker/index.js @@ -121,7 +121,7 @@ const BaiduMapPicker = ({ visible, onCancel, onConfirm }) => { width={800} okText="确认" cancelText="取消" - destroyOnClose + destroyOnHidden > , }, - + { + key: "/safetyEval/container/QualificationReview/SiteReviewNotice", + label: "现场审查通知", + icon: , + }, ], }, ] diff --git a/src/pages/Container/MonitorManage/RiskCenter/index.js b/src/pages/Container/MonitorManage/RiskCenter/index.js index e1e0829..f896f04 100644 --- a/src/pages/Container/MonitorManage/RiskCenter/index.js +++ b/src/pages/Container/MonitorManage/RiskCenter/index.js @@ -311,7 +311,7 @@ const RiskCenter = (props) => { } width={760} - destroyOnClose + destroyOnHidden >
风险预警中心统一办理监管处置:确认来源、选择处置方式、发送机构消息、等待机构反馈、复核并闭环。 @@ -362,7 +362,7 @@ const RiskCenter = (props) => { } width={760} - destroyOnClose + destroyOnHidden >
机构端提交的说明和附件进入本环节复核,监管人员可通过、退回补正或办结。 diff --git a/src/pages/Container/QualificationReview/SiteReviewNotice/index.js b/src/pages/Container/QualificationReview/SiteReviewNotice/index.js new file mode 100644 index 0000000..740f46c --- /dev/null +++ b/src/pages/Container/QualificationReview/SiteReviewNotice/index.js @@ -0,0 +1,384 @@ +import React, { useState } from "react"; +import dayjs from "dayjs"; +import { Form, Table, Button, Modal, Input, Select, DatePicker, Card, Row, Col, Statistic, message, Tag } 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_QUAL_REVIEW } from "~/enumerate/namespace"; +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import AttachmentUpload from "~/components/AttachmentUpload"; + +const MOCK_LIST = [ + { + id: 1, institution: "重庆安评技术研究院有限公司", date: "2026-07-22", time: "09:30", + address: "机构办公场所及档案室", team: "王立军等4人", status: "pending", + application: "安全评价机构资质延续", department: "重庆市应急管理局", + materials: "12 / 14", noticeNo: "SC-2026-018", + materialsReq: "机构资质申请材料原件、人员档案、社保材料、办公场所和档案室证明、设备清单、过程控制制度及项目档案等资料。", + contact: "李科长", contactPhone: "023-6751****", + conclusion: "", resultFile: "", opinion: "", + }, + { + id: 2, institution: "重庆恒安安全评价有限公司", date: "2026-07-19", time: "14:00", + address: "机构会议室", team: "赵强等3人", status: "pending", + application: "新增业务范围申请", department: "重庆市应急管理局", + materials: "8 / 10", noticeNo: "SC-2026-021", + materialsReq: "新申请业务范围的技术人员证书、装备清单、能力证明等材料。", + contact: "李科长", contactPhone: "023-6751****", + conclusion: "", resultFile: "", opinion: "", + }, + { + id: 3, institution: "重庆渝安风险评估中心", date: "2025-11-18", time: "14:00", + address: "机构会议室", team: "李建军等3人", status: "done", + application: "安全生产评价机构资质备案", department: "重庆市应急管理局", + materials: "14 / 14", noticeNo: "SC-2025-031", + materialsReq: "—", + contact: "—", contactPhone: "—", + conclusion: "审查通过", resultFile: "现场审查结果报告.pdf", opinion: "整改项2项均已闭环,审查结论:通过", + }, +]; + +const APPLICATION_OPTIONS = [ + { label: "资质延续申请 SQ-2026-018", value: "SQ-2026-018" }, + { label: "新增业务范围申请 SQ-2026-021", value: "SQ-2026-021" }, +]; + +const INSTITUTION_OPTIONS = [ + "重庆安评技术研究院有限公司", + "重庆恒安安全评价有限公司", + "重庆渝安风险评估中心", +]; + +const SiteReviewNotice = (props) => { + const [searchForm] = Form.useForm(); + const [noticeForm] = Form.useForm(); + const [resultForm] = Form.useForm(); + const [dataSource, setDataSource] = useState(MOCK_LIST); + const [noticeModalOpen, setNoticeModalOpen] = useState(false); + const [resultModalOpen, setResultModalOpen] = useState(false); + const [currentResultRow, setCurrentResultRow] = useState(null); + const [viewMode, setViewMode] = useState(false); // true=保存查看, false=下发 + + const stats = { + total: dataSource.length, + pending: dataSource.filter((d) => d.status === "pending").length, + done: dataSource.filter((d) => d.status === "done").length, + }; + + const handleSearch = (values) => { + const { institution, status, date } = values || {}; + setDataSource(MOCK_LIST.filter((item) => { + if (institution && !item.institution.includes(institution)) return false; + if (status && item.status !== status) return false; + return true; + })); + }; + + const handleReset = () => { + searchForm.resetFields(); + setDataSource(MOCK_LIST); + }; + + // 下发通知 + const handleOpenNoticeModal = () => { + setViewMode(false); + noticeForm.resetFields(); + setNoticeModalOpen(true); + }; + + // 保存查看 + const handleViewNotice = (record) => { + setViewMode(true); + noticeForm.setFieldsValue({ + application: record.application, + institution: record.institution, + date: record.date ? dayjs(record.date) : null, + time: record.time, + address: record.address, + team: record.team, + materials: record.materialsReq, + contact: record.contact, + contactPhone: record.contactPhone, + }); + setNoticeModalOpen(true); + }; + + const handleSubmitNotice = () => { + noticeForm.validateFields().then((values) => { + const newNotice = { + id: dataSource.length + 1, + institution: values.institution, + date: values.date ? values.date.format("YYYY-MM-DD") : "2026-07-25", + time: values.time || "09:30", + address: values.address || "", + team: values.team || "", + status: "pending", + application: values.application || "", + department: "重庆市应急管理局", + materials: "—", + noticeNo: `SC-2026-${String(dataSource.length + 20).padStart(3, "0")}`, + materialsReq: values.materials || "", + contact: values.contact || "", + contactPhone: values.contactPhone || "", + }; + setDataSource((prev) => [newNotice, ...prev]); + setNoticeModalOpen(false); + message.success("现场审查通知已下发机构端"); + }).catch(() => {}); + }; + + // 审查结果上传 + const handleOpenResultModal = (record) => { + setCurrentResultRow(record); + resultForm.resetFields(); + resultForm.setFieldsValue({ + institution: record.institution, + date: record.date, + conclusion: record.conclusion || undefined, + leader: record.team ? record.team.split("等")[0] : "王立军", + opinion: record.opinion || "", + }); + setResultModalOpen(true); + }; + + const handleSubmitResult = () => { + resultForm.validateFields().then((values) => { + setDataSource((prev) => + prev.map((item) => + item.id === currentResultRow?.id + ? { ...item, status: "done", conclusion: values.conclusion, opinion: values.opinion } + : item + ) + ); + setResultModalOpen(false); + message.success("审查结果已保存并上传"); + }).catch(() => {}); + }; + + const columns = [ + { title: "机构名称", dataIndex: "institution", ellipsis: true }, + { + title: "现场审查时间", dataIndex: "date", width: 180, + render: (date, record) => `${date} ${record.time}`, + }, + { title: "审查地点", dataIndex: "address", width: 200, ellipsis: true }, + { title: "审查组", dataIndex: "team", width: 140 }, + { + title: "状态", dataIndex: "status", width: 100, + render: (status) => + status === "done" ? 已完成 : 待开展审查, + }, + { + title: "操作", width: 220, fixed: "right", + render: (_, record) => ( + + + + + ), + }, + ]; + + return ( + + 下发现场审查通知 + + } + > +
+ 向安全评价机构下发现场审查时间、地点和审查组安排,并接收审查结果文件。 +
+ + + + + +
本年度累计
+
+ + + + +
未来30日内
+
+ + + + +
审查结果已归档
+
+ +
+ + + + , + + + 待开展审查 + 已完成 + + , + + + , + ]} + onFinish={handleSearch} + onReset={handleReset} + style={{ marginBottom: 16 }} + /> + + `共 ${total} 条`, + pageSize: 10, + }} + /> + + {/* 下发现场审查通知 / 保存查看 弹窗 */} + setNoticeModalOpen(false)} + onOk={viewMode ? () => setNoticeModalOpen(false) : handleSubmitNotice} + okText={viewMode ? "关闭" : "确认下发"} + width={760} + destroyOnHidden + > +
+ +
+ + + {INSTITUTION_OPTIONS.map((name) => ( + {name} + ))} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* 审查结果上传弹窗 */} + setResultModalOpen(false)} + onOk={handleSubmitResult} + okText="保存审查结果" + width={760} + destroyOnHidden + > +
+ 上传现场审查结果文件,并保存审查结论和意见。 +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default Connect([NS_QUAL_REVIEW], true)(AntdTableFuncControl(SiteReviewNotice)); \ No newline at end of file diff --git a/src/pages/Container/SafetyEvalBusiness/CustomerManage/index.js b/src/pages/Container/SafetyEvalBusiness/CustomerManage/index.js index e881010..f90c3b4 100644 --- a/src/pages/Container/SafetyEvalBusiness/CustomerManage/index.js +++ b/src/pages/Container/SafetyEvalBusiness/CustomerManage/index.js @@ -211,7 +211,7 @@ const CustomerManage = (props) => { onCancel={() => setModalOpen(false)} onOk={handleCreateSubmit} width={800} - destroyOnClose + destroyOnHidden >
优先从平台企业库选择;平台没有时可新建客户信息。 diff --git a/src/pages/Container/WpsEditor/index.js b/src/pages/Container/WpsEditor/index.js index a3613e6..f8fc487 100644 --- a/src/pages/Container/WpsEditor/index.js +++ b/src/pages/Container/WpsEditor/index.js @@ -13,13 +13,30 @@ import { import { ArrowLeftOutlined } from "@ant-design/icons"; import WebOfficeSDK from "~/web-office-sdk-solution-v2.0.7/web-office-sdk-solution-v2.0.7.es.js"; import { createPortal } from "react-dom"; +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import "./index.less"; const App = (props) => { - const { onCancel, fileId } = props; + const { onCancel, safetyEvalBusiness } = props; + const {createDocLoading }=safetyEvalBusiness; const [expandedMap, setExpandedMap] = useState({}); + const [fileId, setFileId] = useState(props.fileId); + const [templateMap, setTemplateMap] = useState([]); const sdkRef = useRef(null); + useEffect(() => { + props.fetchWpsDocTemplate().then((res) => { + if (res?.data) { + const list = Object.entries(res.data).map(([name, url]) => ({ + name, + url, + })); + setTemplateMap(list); + } + }); + }, []); + const handleSave = async () => { if (!sdkRef.current) { message.warning("文档尚未加载完成"); @@ -40,13 +57,13 @@ const App = (props) => { officeType: WebOfficeSDK.OfficeType.Writer, appId: "SX20260717TSGKEA", mount: document.getElementById("app-sbsb"), - fileId: fileId || "123", + fileId: fileId, token: sessionStorage.getItem("token"), }); await instance.ready(); sdkRef.current = instance; })(); - }, []); + }, [fileId]); return (
@@ -185,43 +202,32 @@ const App = (props) => {
- {[ - { - name: "安全预评价报告", - desc: "AQ 8001 / AQ 8002 · V3.2", - active: true, - }, - { - name: "安全验收评价报告", - desc: "AQ 8001 / AQ 8003 · V2.8", - active: false, - }, - { - name: "安全现状评价报告", - desc: "机构标准模板 · V4.1", - active: false, - }, - ].map((tmpl, i) => ( -
+ {templateMap.map(({ name, url }, i) => ( +
- - {tmpl.name} - - {name} + {/* - {tmpl.desc} - + {url} + */}
- {tmpl.active ? ( - 使用中 - ) : ( - - )} +
))}
@@ -338,5 +344,7 @@ const App = (props) => { }; export default function WpsEditor(props) { - return createPortal(, document.body); + return createPortal(, document.body); } + +const ConnectApp = Connect([NS_SAFETY_EVAL_BUSINESS], true)(App); diff --git a/src/pages/Container/WpsEditor/index.less b/src/pages/Container/WpsEditor/index.less index 24854d6..1358764 100644 --- a/src/pages/Container/WpsEditor/index.less +++ b/src/pages/Container/WpsEditor/index.less @@ -31,8 +31,9 @@ } .WpsEditor-dock-cats { - margin: 8px 0; + margin: 7px 0; overflow-x: auto; + padding-bottom: 2px; scrollbar-width: thin; }