From 5974d1c041a27d95e1a885e429163169cfe4e352 Mon Sep 17 00:00:00 2001 From: huwei <3313749341@qq.com> Date: Tue, 11 Aug 2026 18:04:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=A5=E5=91=8A=E5=BA=93=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + jjb.config.js | 4 +- src/api/safetyEvalBusiness/index.js | 17 + .../EvalReportLibrary/index.js | 313 ++++++++++++++---- .../EvalReportLibrary/index.less | 53 +++ 5 files changed, 321 insertions(+), 67 deletions(-) diff --git a/.gitignore b/.gitignore index e634bf3..9073ee3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ yarn.lock /.playwright-cli/ /.vscode/ /.workbuddy/ +/.pnpm-store/ diff --git a/jjb.config.js b/jjb.config.js index f5a8e13..3adbd54 100644 --- a/jjb.config.js +++ b/jjb.config.js @@ -14,8 +14,8 @@ module.exports = { // 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: "https://gbs-gateway.qhdsafety.com", + API_HOST: "http://192.168.0.103", //huwei }, production: { // 应用后端分支名称,部署上线需要 diff --git a/src/api/safetyEvalBusiness/index.js b/src/api/safetyEvalBusiness/index.js index b57e2fa..8355bae 100644 --- a/src/api/safetyEvalBusiness/index.js +++ b/src/api/safetyEvalBusiness/index.js @@ -317,6 +317,23 @@ export const evalReportSubmit = declareRequest( "Post > @/safetyEval/institution/eval-report/submit", ); +/** + * 机构端报告库-批量报送监管端 + * + * 变更时间:2026-08-11 + * 变更原因:报告库需支持一次性把多份「未报送」报告报送至监管端,原仅有单条 submit 接口, + * 逐条点击效率低且无法给出统一的批量结果反馈。 + * 接口契约(需后端按此新增,不改动既有 submit 逻辑): + * POST /safetyEval/institution/eval-report/submit/batch + * 入参:{ ids: Long[] } —— 待报送的报告主键集合 + * 出参:SingleResponse 或含成功/失败明细的结构,前端按 success 判定 + * 兼容说明:后端接口未上线前,页面侧会自动降级为「循环调用单条 submit」,保证功能可用。 + */ +export const evalReportBatchSubmit = declareRequest( + "evalReportBatchSubmitLoading", + "Post > @/safetyEval/institution/eval-report/submit/batch", +); + export const evalReportSpotcheckList = declareRequest( "evalReportSpotcheckListLoading", "Get > /safetyEval/institution/eval-report-spotcheck/list", diff --git a/src/pages/Container/SafetyEvalBusiness/EvalReportLibrary/index.js b/src/pages/Container/SafetyEvalBusiness/EvalReportLibrary/index.js index 95bad53..cde817c 100644 --- a/src/pages/Container/SafetyEvalBusiness/EvalReportLibrary/index.js +++ b/src/pages/Container/SafetyEvalBusiness/EvalReportLibrary/index.js @@ -26,6 +26,7 @@ import { 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 PreviewUrlButton from "~/components/PreviewUrlButton"; import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { Connect } from "@cqsjjb/jjb-dva-runtime"; @@ -33,6 +34,15 @@ import { tools } from "@cqsjjb/jjb-common-lib"; import dayjs from "dayjs"; import "./index.less"; +/** + * 变更时间:2026-08-11 + * 变更原因:需求「机构端报告库批量报送 + 查看详情样式优化」: + * 1) 列表支持勾选「未报送」报告并一次性批量报送(调用 evalReportBatchSubmit,接口未就绪时降级逐条 submit); + * 2) 查看详情改为与「上传历史报告」表单一致的排版(更贴近新增报告的录入样式),附件支持图片放大预览、 + * 其他文件点击新窗口预览/下载。 + * 相关约束:后端代码不修改,仅作为接口/字段对照依据;批量报送接口需后端按约定契约新增。 + */ + const { router } = tools; const { TextArea } = Input; @@ -159,6 +169,9 @@ const EvalReportLibrary = (props) => { const [uploadedFile, setUploadedFile] = useState(null); const [contractFiles, setContractFiles] = useState([]); const [processDocFiles, setProcessDocFiles] = useState([]); + // 变更时间:2026-08-11 变更原因:批量报送需记录勾选的报告主键 + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [batchSubmitting, setBatchSubmitting] = useState(false); const { evalReportPageLoading, @@ -407,6 +420,86 @@ const EvalReportLibrary = (props) => { }); }; + /** + * 批量报送(变更时间:2026-08-11) + * 变更原因:机构端报告库需支持一次性把多份「未报送」报告报送至监管端,原仅支持单条报送。 + * 实现策略: + * 1) 调用批量报送接口 evalReportBatchSubmit(POST /safetyEval/institution/eval-report/submit/batch,入参 { ids: Long[] }), + * 后端已实现:逐条复用单条报送规则,并返回 successCount/failCount/failList 明细; + * 2) 若批量接口异常(如未部署/网络错误),降级为并发调用单条 submit,保证功能可用, + * 并对失败项汇总提示,避免个别失败导致整体中断。 + */ + const handleBatchSubmit = async () => { + const ids = selectedRowKeys; + if (!ids || ids.length === 0) { + message.warning("请先勾选需要报送的报告"); + return; + } + Modal.confirm({ + title: "确认批量报送", + icon: , + content: ( +
+ 确定要将已勾选的 {ids.length} 份「未报送」报告报送至监管端吗?报送后监管端可进行抽查审核。 +
+ ), + okText: "确认批量报送", + cancelText: "取消", + onOk: async () => { + setBatchSubmitting(true); + try { + const res = await props.evalReportBatchSubmit({ ids }); + if (res?.success !== false && res?.data) { + // 后端已返回成功/失败明细,精确展示 + const { successCount = 0, failCount = 0, failList = [] } = res.data; + if (failCount === 0) { + message.success(`已批量报送 ${successCount} 份报告至监管端`); + } else { + const reasons = failList + .map((f) => `报告ID ${f.id}:${f.reason}`) + .join(";"); + message.warning( + `批量报送完成:${successCount} 份成功,${failCount} 份失败(${reasons})`, + ); + } + } else if (res?.success !== false) { + message.success(`已批量报送 ${ids.length} 份报告至监管端`); + } else { + throw new Error(res?.message || "批量报送失败"); + } + } catch (err) { + // 批量接口未就绪(如 404/网络异常)时降级为逐条报送,保证功能可用 + message.info("批量接口暂未就绪,正在逐条报送..."); + let successCount = 0; + const failNames = []; + await Promise.all( + ids.map(async (id) => { + try { + const r = await props.evalReportSubmit({ id }); + if (r?.success !== false) successCount += 1; + else failNames.push(id); + } catch { + failNames.push(id); + } + }), + ); + if (failNames.length === 0) { + message.success(`已逐条报送 ${successCount} 份报告至监管端`); + } else { + message.warning( + `逐条报送完成:${successCount} 份成功,${failNames.length} 份失败(请重试或检查报送状态)`, + ); + } + } finally { + setBatchSubmitting(false); + setSelectedRowKeys([]); + fetchSummary(); + getData(); + } + }, + }); + }; + const handleViewSpotcheck = async (record) => { setCurrentReport(record); setSpotcheckVisible(true); @@ -660,9 +753,26 @@ const EvalReportLibrary = (props) => { } onClick={handleOpenAdd}> - 上传历史报告 - + /** + * 变更时间:2026-08-11 + * 变更原因:新增「批量报送」入口,与「上传历史报告」并列;仅在已勾选未报送报告时可点击, + * 按钮上直接反馈已选数量,降低误操作。 + */ + + + + } >
@@ -735,6 +845,18 @@ const EvalReportLibrary = (props) => { columns={columns} dataSource={dataSource} loading={evalReportPageLoading} + /** + * 变更时间:2026-08-11 + * 变更原因:支持批量报送,需勾选功能;仅「未报送」记录可勾选, + * 已报送/抽查相关记录禁用勾选,避免重复报送。 + */ + rowSelection={{ + selectedRowKeys, + onChange: (keys) => setSelectedRowKeys(keys), + getCheckboxProps: (record) => ({ + disabled: !isUnsubmitted(record), + }), + }} scroll={{ y: props.scrollY, x: 1400 }} pagination={{ total, @@ -970,77 +1092,138 @@ const EvalReportLibrary = (props) => {
- {/* 报告详情 */} + {/* 报告详情(变更时间:2026-08-11:改为与「上传历史报告」一致的排版样式,附件支持预览) + * 变更原因:原型要求查看沿用新增报告的录入排版,字段顺序、分组与上传弹窗对齐,降低阅读认知成本; + * 附件(主报告/合同/过程文档)使用 PreviewUrlButton —— 图片点击放大预览,其他文件点击新窗口预览/下载。 + */} +
报告详情
+
报告库档案信息(与上传录入样式一致)
+ + } open={detailVisible} onCancel={() => setDetailVisible(false)} footer={} - width={760} + width={820} destroyOnClose + className="erl-upload-modal" > {detailData ? ( <> - - - {detailData.reportNo || "-"} - - - {detailData.reportName || "-"} - - - {detailData.reportYear || "-"} - - - {detailData.evalTypeName || - getOptionLabel(REPORT_EVAL_TYPE_OPTIONS, detailData.evalTypeCode)} - - - {detailData.industryName || - getOptionLabel(REPORT_INDUSTRY_OPTIONS, detailData.industryCode)} - - - {detailData.evaluatedUnitName || "-"} - - - {detailData.issueDate - ? dayjs(detailData.issueDate).format("YYYY-MM-DD") - : "-"} - - - {detailData.pageCount ?? "-"} - - - {renderDisplayStatus(detailData)} - - - {detailData.reportStatusName || "-"} - - - {detailData.secretLevelName || - getOptionLabel(SECRET_LEVEL_OPTIONS, detailData.secretLevelCode)} - - - {detailData.archiveTime - ? dayjs(detailData.archiveTime).format("YYYY-MM-DD HH:mm") - : "-"} - - -
- {getFileExt(detailData.fileName || detailData.fileUrl)} - {detailData.fileName || "-"} + {/* 正式报告文件:预览优先,与上传弹窗主文件展示一致 */} +
+
+
{getFileExt(detailData.fileName || detailData.fileUrl)}
+
+ {detailData.reportName || "未命名报告"} +

{detailData.fileName || detailData.fileUrl || "暂无正式报告文件"}

+ {detailData.fileUrl ? ( + + ) : ( + 尚未上传正式报告文件 + )}
- - - {renderFileLinks(detailData.contractFileUrls)} - - - {renderFileLinks(detailData.processDocUrls)} - - - {detailData.remarks || "-"} - - +
+
+ + + +
+ + {detailData.reportNo || "-"} +
+ + +
+ + {detailData.reportName || "-"} +
+ + +
+ + {detailData.reportYear || "-"} +
+ + +
+ + {detailData.evalTypeName || getOptionLabel(REPORT_EVAL_TYPE_OPTIONS, detailData.evalTypeCode)} +
+ + +
+ + {detailData.industryName || getOptionLabel(REPORT_INDUSTRY_OPTIONS, detailData.industryCode)} +
+ + +
+ + {detailData.evaluatedUnitName || "-"} +
+ + +
+ + {detailData.issueDate ? dayjs(detailData.issueDate).format("YYYY-MM-DD") : "-"} +
+ + +
+ + {detailData.pageCount ?? "-"} +
+ + +
+ + {renderDisplayStatus(detailData)} +
+ + +
+ + {detailData.reportStatusName || "-"} +
+ + +
+ + {detailData.secretLevelName || getOptionLabel(SECRET_LEVEL_OPTIONS, detailData.secretLevelCode)} +
+ + +
+ + {detailData.archiveTime ? dayjs(detailData.archiveTime).format("YYYY-MM-DD HH:mm") : "-"} +
+ + +
+ + {renderFileLinks(detailData.contractFileUrls)} +
+ + +
+ + {renderFileLinks(detailData.processDocUrls)} +
+ + +
+ + {detailData.remarks || "-"} +
+ +
+
{isSpotcheckRelated(detailData) && (