From 305208d91b4d9be9bfb02b769e43e15e74274793 Mon Sep 17 00:00:00 2001 From: tangjie <122778500@qq.com> Date: Tue, 21 Jul 2026 13:33:42 +0800 Subject: [PATCH] feat --- jjb.config.js | 2 +- src/api/qualReview/index.js | 43 +- src/enumerate/constant/index.js | 8 + .../SiteReviewNotice/index.js | 369 ++++++++++-------- src/pages/Container/WpsEditor/index.js | 19 +- 5 files changed, 250 insertions(+), 191 deletions(-) diff --git a/jjb.config.js b/jjb.config.js index 0bef932..db76147 100644 --- a/jjb.config.js +++ b/jjb.config.js @@ -11,7 +11,7 @@ module.exports = { // 本地联调 safetyEval-service(context-path: /safetyEval,默认端口 8095) // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 API_HOST: "https://gbs-gateway.qhdsafety.com", - //API_HOST: "http://192.168.0.150", //太浅 + //API_HOST: "http://192.168.0.150", //太浅 //API_HOST: "http://192.168.0.152", }, production: { diff --git a/src/api/qualReview/index.js b/src/api/qualReview/index.js index 7765492..4b5c2a4 100644 --- a/src/api/qualReview/index.js +++ b/src/api/qualReview/index.js @@ -83,18 +83,43 @@ export const queryQualMonitoringPageStatistics = declareRequest( "monitorStats: {} | res.data || {}", ); -export const querySiteReviewNoticePage = declareRequest( +// ─── 资质现场核查 ─── + +export const queryQualOnSiteReviewPage = declareRequest( "siteReviewNoticeLoading", - "Get > /safetyEval/site-review-notice/page", - 'siteReviewNoticeList: [] | res.data?.records || [] & siteReviewNoticeTotal: 0 | res.data?.total || 0', + "Get > /safetyEval/qual-on-site-review/monitor/page", + 'qualOnSiteReviewList: [] | res.data || [] & qualOnSiteReviewTotal: 0 | res.total || 0', ); -export const siteReviewNoticeSave = declareRequest( - "siteReviewNoticeSaveLoading", - "Post > @/safetyEval/site-review-notice/save", +export const queryQualOnSiteReviewStatistics = declareRequest( + "siteReviewStatisticsLoading", + "Get > /safetyEval/qual-on-site-review/monitor/page/statistics", + 'qualOnSiteReviewStats: {} | res.data || {}', ); -export const siteReviewResultSave = declareRequest( - "siteReviewResultSaveLoading", - "Post > @/safetyEval/site-review-result/save", +export const fetchQualOnSiteReviewDetail = declareRequest( + "siteReviewDetailLoading", + "Get > /safetyEval/qual-on-site-review/{id}", + 'qualOnSiteReviewDetail: {} | res.data || {}', +); + +export const addQualOnSiteReview = declareRequest( + "siteReviewSaveLoading", + "Post > @/safetyEval/qual-on-site-review", +); + +export const updateQualOnSiteReview = declareRequest( + "siteReviewSaveLoading", + "Put > @/safetyEval/qual-on-site-review", +); + +export const uploadQualOnSiteReviewResult = declareRequest( + "siteReviewResultLoading", + "Post > @/safetyEval/qual-on-site-review/result-upload", +); + +export const queryOrgSelectList = declareRequest( + "orgSelectLoading", + "Get > /safetyEval/org-info/select/list", + 'orgSelectList: [] | res.data || []', ); \ No newline at end of file diff --git a/src/enumerate/constant/index.js b/src/enumerate/constant/index.js index a775319..8c96ea7 100644 --- a/src/enumerate/constant/index.js +++ b/src/enumerate/constant/index.js @@ -67,6 +67,14 @@ export const QUAL_MONITOR_STATUS_MAP = { person_rate: { label: "人员比例预警", color: "warning" }, }; +/** 资质现场核查状态 */ +export const ON_SITE_REVIEW_STATUS_MAP = { + AGENCY_PENDING_CONFIRMATION: { label: "机构待确认", color: "processing" }, + AGENCY_CONFIRMED: { label: "机构已确认", color: "blue" }, + REVIEW_PASSED: { label: "核查通过", color: "success" }, + REVIEW_FAILED: { label: "核查不通过", color: "error" }, +}; + /** 性别 */ export const GENDER_OPTIONS = [ { label: "男", value: 1 }, diff --git a/src/pages/Container/QualificationReview/SiteReviewNotice/index.js b/src/pages/Container/QualificationReview/SiteReviewNotice/index.js index 740f46c..2752c8c 100644 --- a/src/pages/Container/QualificationReview/SiteReviewNotice/index.js +++ b/src/pages/Container/QualificationReview/SiteReviewNotice/index.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } 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"; @@ -6,175 +6,191 @@ 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 { tools } from "@cqsjjb/jjb-common-lib"; import { NS_QUAL_REVIEW } from "~/enumerate/namespace"; import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { ON_SITE_REVIEW_STATUS_MAP } from "~/enumerate/constant"; 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 { router } = tools; 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 [currentEditId, setCurrentEditId] = useState(null); 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 { + qualReview, + queryQualOnSiteReviewPage, + queryQualOnSiteReviewStatistics, + addQualOnSiteReview, + updateQualOnSiteReview, + uploadQualOnSiteReviewResult, + fetchQualOnSiteReviewDetail, + queryOrgSelectList, + resetModelState, + } = props; + + const { + qualOnSiteReviewList = [], + qualOnSiteReviewTotal = 0, + qualOnSiteReviewStats = {}, + orgSelectList = [], + siteReviewNoticeLoading, + siteReviewStatisticsLoading, + siteReviewSaveLoading, + siteReviewResultLoading, + } = qualReview || {}; + + useEffect(() => { + queryQualOnSiteReviewStatistics(); + queryOrgSelectList(); + searchForm.setFieldsValue(router.query); + handleSearch(); + }, []); + + useEffect(() => { + if (!noticeModalOpen) { + resetModelState(NS_QUAL_REVIEW, { siteReviewSaveLoading: false }); + } + }, [noticeModalOpen]); + + useEffect(() => { + if (!resultModalOpen) { + resetModelState(NS_QUAL_REVIEW, { siteReviewResultLoading: false }); + } + }, [resultModalOpen]); + + const handleSearch = () => { + + queryQualOnSiteReviewPage({ + ...router.query, + }); }; - 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 handleSearchSubmit = (values) => { + const { dateRange, ...rest } = values; + router.query = { + ...router.query, + ...rest, + ...(dateRange && dateRange[0] && { reviewDateStartBegin: dateRange[0].format("YYYY-MM-DD") }), + ...(dateRange && dateRange[1] && { reviewDateStartEnd: dateRange[1].format("YYYY-MM-DD") }), + current: 1, + size: 10, + }; + handleSearch(); }; - const handleReset = () => { - searchForm.resetFields(); - setDataSource(MOCK_LIST); + const handleReset = (values) => { + router.query = { ...values, current: 1, size: 10 }; + handleSearch(); }; - // 下发通知 const handleOpenNoticeModal = () => { - setViewMode(false); + setCurrentEditId(null); 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, + const handleEditNotice = (record) => { + setCurrentEditId(record.id); + fetchQualOnSiteReviewDetail({ id: record.id }).then((res) => { + if (res?.success !== false) { + const detail = res.data; + noticeForm.setFieldsValue({ + orgId: detail.orgId, + reviewDateStart: detail.reviewDateStart ? dayjs(detail.reviewDateStart) : null, + reviewLocation: detail.reviewLocation, + reviewMembers: detail.reviewMembers, + reviewLeader: detail.reviewLeader, + materialRequirements: detail.materialRequirements, + supervisorContact: detail.supervisorContact, + contactPhone: detail.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 || "", + const payload = { + ...values, + reviewDateStart: values.reviewDateStart.format("YYYY-MM-DD HH:mm:ss"), + status: "AGENCY_PENDING_CONFIRMATION", }; - setDataSource((prev) => [newNotice, ...prev]); - setNoticeModalOpen(false); - message.success("现场审查通知已下发机构端"); + + const action = currentEditId + ? updateQualOnSiteReview({ ...payload, id: currentEditId }) + : addQualOnSiteReview(payload); + + action.then((res) => { + if (res?.success !== false) { + setNoticeModalOpen(false); + message.success(currentEditId ? "现场审查通知已修改" : "现场审查通知已下发机构端"); + queryQualOnSiteReviewStatistics(); + handleSearch(); + } + }); }).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 || "", + institution: record.unitName, + reviewDateStart: record.reviewDateStart, + reviewLeader: record.reviewLeader || "", + reviewOpinion: record.reviewOpinion || "", }); 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("审查结果已保存并上传"); + + + const payload = { + id: currentResultRow.id, + ...values, + }; + + uploadQualOnSiteReviewResult(payload).then((res) => { + if (res?.success !== false) { + setResultModalOpen(false); + message.success("审查结果已保存并上传"); + queryQualOnSiteReviewStatistics(); + handleSearch(); + } + }); }).catch(() => {}); }; const columns = [ - { title: "机构名称", dataIndex: "institution", ellipsis: true }, + { title: "机构名称", dataIndex: "unitName", ellipsis: true }, { - title: "现场审查时间", dataIndex: "date", width: 180, - render: (date, record) => `${date} ${record.time}`, + title: "现场审查时间", dataIndex: "reviewDateStart", width: 180, + render: (val) => val ? dayjs(val).format("YYYY-MM-DD HH:mm") : "-", }, - { title: "审查地点", dataIndex: "address", width: 200, ellipsis: true }, - { title: "审查组", dataIndex: "team", width: 140 }, + { title: "审查地点", dataIndex: "reviewLocation", width: 200, ellipsis: true }, + { title: "审查组成员", dataIndex: "reviewMembers", width: 140, ellipsis: true }, { - title: "状态", dataIndex: "status", width: 100, - render: (status) => - status === "done" ? 已完成 : 待开展审查, + title: "状态", dataIndex: "status", width: 120, + render: (status) => { + const cfg = ON_SITE_REVIEW_STATUS_MAP[status]; + return cfg ? {cfg.label} : (status || "-"); + }, }, { title: "操作", width: 220, fixed: "right", render: (_, record) => ( - handleViewNotice(record)}> + handleEditNotice(record)}> 修改 handleOpenResultModal(record)}> @@ -200,20 +216,20 @@ const SiteReviewNotice = (props) => { - - - 本年度累计 + + + {qualOnSiteReviewStats.annualCumulativeCount ?? 0} 条本年度累计 - - + + 未来30日内 - - + + 审查结果已归档 @@ -221,22 +237,23 @@ const SiteReviewNotice = (props) => { + , - 待开展审查 - 已完成 + {Object.entries(ON_SITE_REVIEW_STATUS_MAP).map(([value, cfg]) => ( + {cfg.label} + ))} , - - + + , ]} - onFinish={handleSearch} + onFinish={handleSearchSubmit} onReset={handleReset} style={{ marginBottom: 16 }} /> @@ -244,79 +261,84 @@ const SiteReviewNotice = (props) => { `共 ${total} 条`, - pageSize: 10, + current: Number(router.query.current) || 1, + pageSize: Number(router.query.size) || 10, + onChange: (page, pageSize) => { + router.query = { ...router.query, current: page, size: pageSize }; + handleSearch(); + }, }} /> - {/* 下发现场审查通知 / 保存查看 弹窗 */} + {/* 下发现场审查通知 弹窗 */} setNoticeModalOpen(false)} - onOk={viewMode ? () => setNoticeModalOpen(false) : handleSubmitNotice} - okText={viewMode ? "关闭" : "确认下发"} + onOk={handleSubmitNotice} + okText={currentEditId ? "保存修改" : "确认下发"} + confirmLoading={siteReviewSaveLoading} width={760} destroyOnHidden > - - - - - - - - {INSTITUTION_OPTIONS.map((name) => ( - {name} + + + {(orgSelectList || []).map((item) => ( + + {item.unitName} + ))} + + + + + - - + + - - - + {/* + + - + */} - - + + - - - - + - - + + - - + + @@ -330,6 +352,7 @@ const SiteReviewNotice = (props) => { onCancel={() => setResultModalOpen(false)} onOk={handleSubmitResult} okText="保存审查结果" + confirmLoading={siteReviewResultLoading} width={760} destroyOnHidden > @@ -344,35 +367,35 @@ const SiteReviewNotice = (props) => { - + - + - 审查通过 - 补正材料后通过 - 不通过 + 审查通过 + 补正材料后通过 + 不通过 - - + + - + diff --git a/src/pages/Container/WpsEditor/index.js b/src/pages/Container/WpsEditor/index.js index f8fc487..54ddcb5 100644 --- a/src/pages/Container/WpsEditor/index.js +++ b/src/pages/Container/WpsEditor/index.js @@ -19,7 +19,7 @@ import "./index.less"; const App = (props) => { const { onCancel, safetyEvalBusiness } = props; - const {createDocLoading }=safetyEvalBusiness; + const { createDocLoading } = safetyEvalBusiness; const [expandedMap, setExpandedMap] = useState({}); const [fileId, setFileId] = useState(props.fileId); const [templateMap, setTemplateMap] = useState([]); @@ -59,6 +59,7 @@ const App = (props) => { mount: document.getElementById("app-sbsb"), fileId: fileId, token: sessionStorage.getItem("token"), + }); await instance.ready(); sdkRef.current = instance; @@ -217,13 +218,15 @@ const App = (props) => { loading={createDocLoading} size="small" onClick={() => { - props.createWpsDoc({docxUrl:url}).then((res) => { - const fileId = res?.data?.fileId; - if(!fileId){ - return; - } - setFileId(fileId); - }); + props + .createWpsDoc({ docxUrl: url }) + .then((res) => { + const fileId = res?.data?.fileId; + if (!fileId) { + return; + } + setFileId(fileId); + }); }} > 应用