报告库修改
parent
aee28c4af4
commit
5974d1c041
|
|
@ -21,3 +21,4 @@ yarn.lock
|
|||
/.playwright-cli/
|
||||
/.vscode/
|
||||
/.workbuddy/
|
||||
/.pnpm-store/
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
// 应用后端分支名称,部署上线需要
|
||||
|
|
|
|||
|
|
@ -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<Boolean> 或含成功/失败明细的结构,前端按 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",
|
||||
|
|
|
|||
|
|
@ -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: <SendOutlined style={{ color: "#1677ff" }} />,
|
||||
content: (
|
||||
<div style={{ fontSize: 14, color: "#333", lineHeight: 1.8, padding: "8px 0" }}>
|
||||
确定要将已勾选的 <strong>{ids.length}</strong> 份「未报送」报告报送至监管端吗?报送后监管端可进行抽查审核。
|
||||
</div>
|
||||
),
|
||||
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) => {
|
|||
<PageLayout
|
||||
title="报告库管理"
|
||||
extra={
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={handleOpenAdd}>
|
||||
上传历史报告
|
||||
</Button>
|
||||
/**
|
||||
* 变更时间:2026-08-11
|
||||
* 变更原因:新增「批量报送」入口,与「上传历史报告」并列;仅在已勾选未报送报告时可点击,
|
||||
* 按钮上直接反馈已选数量,降低误操作。
|
||||
*/
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
icon={<SendOutlined />}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
loading={batchSubmitting}
|
||||
onClick={handleBatchSubmit}
|
||||
>
|
||||
批量报送{selectedRowKeys.length > 0 ? `(${selectedRowKeys.length})` : ""}
|
||||
</Button>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={handleOpenAdd}>
|
||||
上传历史报告
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<div className="erl-page">
|
||||
|
|
@ -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) => {
|
|||
</div>
|
||||
</Modal>
|
||||
|
||||
{/* 报告详情 */}
|
||||
{/* 报告详情(变更时间:2026-08-11:改为与「上传历史报告」一致的排版样式,附件支持预览)
|
||||
* 变更原因:原型要求查看沿用新增报告的录入排版,字段顺序、分组与上传弹窗对齐,降低阅读认知成本;
|
||||
* 附件(主报告/合同/过程文档)使用 PreviewUrlButton —— 图片点击放大预览,其他文件点击新窗口预览/下载。
|
||||
*/}
|
||||
<Modal
|
||||
title="报告详情"
|
||||
title={
|
||||
<div className="erl-modal-title">
|
||||
<div>报告详情</div>
|
||||
<div className="erl-modal-subtitle">报告库档案信息(与上传录入样式一致)</div>
|
||||
</div>
|
||||
}
|
||||
open={detailVisible}
|
||||
onCancel={() => setDetailVisible(false)}
|
||||
footer={<Button onClick={() => setDetailVisible(false)}>关闭</Button>}
|
||||
width={760}
|
||||
width={820}
|
||||
destroyOnClose
|
||||
className="erl-upload-modal"
|
||||
>
|
||||
{detailData ? (
|
||||
<>
|
||||
<Descriptions bordered column={{ xs: 1, sm: 1, md: 2 }} size="small">
|
||||
<Descriptions.Item label="报告编号">
|
||||
<span className="erl-report-no">{detailData.reportNo || "-"}</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="报告名称">
|
||||
{detailData.reportName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="报告年度">
|
||||
{detailData.reportYear || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="评价类型">
|
||||
{detailData.evalTypeName ||
|
||||
getOptionLabel(REPORT_EVAL_TYPE_OPTIONS, detailData.evalTypeCode)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="所属行业">
|
||||
{detailData.industryName ||
|
||||
getOptionLabel(REPORT_INDUSTRY_OPTIONS, detailData.industryCode)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="被评价单位">
|
||||
{detailData.evaluatedUnitName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="签发日期">
|
||||
{detailData.issueDate
|
||||
? dayjs(detailData.issueDate).format("YYYY-MM-DD")
|
||||
: "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="报告页数">
|
||||
{detailData.pageCount ?? "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="报送状态">
|
||||
{renderDisplayStatus(detailData)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="报告状态">
|
||||
{detailData.reportStatusName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="保密属性">
|
||||
{detailData.secretLevelName ||
|
||||
getOptionLabel(SECRET_LEVEL_OPTIONS, detailData.secretLevelCode)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="归档时间">
|
||||
{detailData.archiveTime
|
||||
? dayjs(detailData.archiveTime).format("YYYY-MM-DD HH:mm")
|
||||
: "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="文件名称" span={2}>
|
||||
<div className="erl-file-cell">
|
||||
<i>{getFileExt(detailData.fileName || detailData.fileUrl)}</i>
|
||||
<span>{detailData.fileName || "-"}</span>
|
||||
{/* 正式报告文件:预览优先,与上传弹窗主文件展示一致 */}
|
||||
<div className="erl-upload-box erl-upload-box-view">
|
||||
<div className="erl-upload-box-inner">
|
||||
<div className="erl-upload-icon">{getFileExt(detailData.fileName || detailData.fileUrl)}</div>
|
||||
<div className="erl-upload-text">
|
||||
<strong>{detailData.reportName || "未命名报告"}</strong>
|
||||
<p>{detailData.fileName || detailData.fileUrl || "暂无正式报告文件"}</p>
|
||||
{detailData.fileUrl ? (
|
||||
<PreviewUrlButton
|
||||
url={detailData.fileUrl}
|
||||
children={detailData.fileName || "预览报告"}
|
||||
/>
|
||||
) : (
|
||||
<span>尚未上传正式报告文件</span>
|
||||
)}
|
||||
</div>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="合同文件" span={2}>
|
||||
{renderFileLinks(detailData.contractFileUrls)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="过程文档" span={2}>
|
||||
{renderFileLinks(detailData.processDocUrls)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="备注" span={2}>
|
||||
{detailData.remarks || "-"}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Row gutter={16} className="erl-detail-form">
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告编号</label>
|
||||
<span className="erl-report-no">{detailData.reportNo || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告名称</label>
|
||||
<span>{detailData.reportName || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告年度</label>
|
||||
<span>{detailData.reportYear || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>评价类型</label>
|
||||
<span>{detailData.evalTypeName || getOptionLabel(REPORT_EVAL_TYPE_OPTIONS, detailData.evalTypeCode)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>所属行业</label>
|
||||
<span>{detailData.industryName || getOptionLabel(REPORT_INDUSTRY_OPTIONS, detailData.industryCode)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>被评价单位</label>
|
||||
<span>{detailData.evaluatedUnitName || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告签发日期</label>
|
||||
<span>{detailData.issueDate ? dayjs(detailData.issueDate).format("YYYY-MM-DD") : "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告页数</label>
|
||||
<span>{detailData.pageCount ?? "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报送状态</label>
|
||||
<span>{renderDisplayStatus(detailData)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>报告状态</label>
|
||||
<span>{detailData.reportStatusName || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>保密属性</label>
|
||||
<span>{detailData.secretLevelName || getOptionLabel(SECRET_LEVEL_OPTIONS, detailData.secretLevelCode)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div className="erl-detail-item">
|
||||
<label>归档时间</label>
|
||||
<span>{detailData.archiveTime ? dayjs(detailData.archiveTime).format("YYYY-MM-DD HH:mm") : "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<div className="erl-detail-item">
|
||||
<label>合同文件</label>
|
||||
<span>{renderFileLinks(detailData.contractFileUrls)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<div className="erl-detail-item">
|
||||
<label>其他过程文档</label>
|
||||
<span>{renderFileLinks(detailData.processDocUrls)}</span>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<div className="erl-detail-item">
|
||||
<label>备注</label>
|
||||
<span>{detailData.remarks || "-"}</span>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div className="erl-detail-actions">
|
||||
{isSpotcheckRelated(detailData) && (
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -276,6 +276,59 @@
|
|||
margin-top: 16px;
|
||||
}
|
||||
|
||||
/* 变更时间:2026-08-11 查看详情改为与「上传历史报告」一致的排版样式 */
|
||||
.erl-detail-form {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.erl-detail-item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
padding: 8px 10px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #eef2f7;
|
||||
border-radius: 8px;
|
||||
min-height: 40px;
|
||||
|
||||
label {
|
||||
flex: 0 0 84px;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
color: #1f2937;
|
||||
font-size: 14px;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
/* 只读查看态的正式报告文件框:弱化边框,去掉上传交互 */
|
||||
.erl-upload-box-view {
|
||||
border-style: solid;
|
||||
border-color: #e2e8f0;
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
.erl-detail-attachments {
|
||||
margin-top: 16px;
|
||||
|
||||
.erl-detail-attachments-block {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.erl-detail-attachments-title {
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ant-btn-link {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.erl-loading {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue