需求修改
parent
31234feaf2
commit
69c5a16b59
|
|
@ -29,6 +29,7 @@
|
||||||
"@rc-component/util": "^1.11.1",
|
"@rc-component/util": "^1.11.1",
|
||||||
"antd": "^6.6.1",
|
"antd": "^6.6.1",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
|
"docx-preview": "^0.4.0",
|
||||||
"docxtemplater": "latest",
|
"docxtemplater": "latest",
|
||||||
"echarts": "^6.1.0",
|
"echarts": "^6.1.0",
|
||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
|
|
|
||||||
2046
pnpm-lock.yaml
2046
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1 +1,3 @@
|
||||||
export { default as OrgInfoGuard } from "./OrgInfoGuard";
|
export { default as OrgInfoGuard } from "./OrgInfoGuard";
|
||||||
|
export { default as PreviewUrlButton } from "./PreviewUrlButton";
|
||||||
|
export { default as OfficePreview } from "./OfficePreview";
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import {
|
||||||
Image,
|
Image,
|
||||||
Popover,
|
Popover,
|
||||||
Button,
|
Button,
|
||||||
|
message,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
|
@ -19,7 +20,7 @@ import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
import { EVAL_TYPE_MAP, ROLE_DEFINITIONS_MAP } from "~/enumerate/constant";
|
import { EVAL_TYPE_MAP, ROLE_DEFINITIONS_MAP } from "~/enumerate/constant";
|
||||||
import { PROJECT_TYPE_MAP } from "~/enumerate/constant";
|
import { PROJECT_TYPE_MAP } from "~/enumerate/constant";
|
||||||
import WpsEditor from "~/pages/Container/WpsEditor";
|
import { OfficePreview } from "~/components";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
|
||||||
const { router } = tools;
|
const { router } = tools;
|
||||||
|
|
@ -368,7 +369,8 @@ const EvalProjectMonitorDetail = (props) => {
|
||||||
const [surveyPersonnel, setSurveyPersonnel] = useState([]);
|
const [surveyPersonnel, setSurveyPersonnel] = useState([]);
|
||||||
const [surveyAttachments, setSurveyAttachments] = useState({});
|
const [surveyAttachments, setSurveyAttachments] = useState({});
|
||||||
const [activeKey, setActiveKey] = useState("BUSINESS_CONTRACT");
|
const [activeKey, setActiveKey] = useState("BUSINESS_CONTRACT");
|
||||||
const [wpsVisible, setWpsVisible] = useState(false);
|
const [previewOpen, setPreviewOpen] = useState(false);
|
||||||
|
const [previewUrl, setPreviewUrl] = useState("");
|
||||||
|
|
||||||
const fetchContract = async () => {
|
const fetchContract = async () => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
|
|
@ -470,7 +472,14 @@ const EvalProjectMonitorDetail = (props) => {
|
||||||
activeKey={activeKey}
|
activeKey={activeKey}
|
||||||
onChange={(key) => {
|
onChange={(key) => {
|
||||||
if (key === "REPORT_PREPARATION") {
|
if (key === "REPORT_PREPARATION") {
|
||||||
setWpsVisible(true);
|
// 2026-08-18 监管端报告改用本地 OfficePreview 预览,避免 WPS SDK 内部空指针报错
|
||||||
|
const url = wpsDoc?.wpsUrl;
|
||||||
|
if (!url) {
|
||||||
|
message.warning("暂无报告文档,请先在机构端生成报告后再查看");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPreviewUrl(url);
|
||||||
|
setPreviewOpen(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setActiveKey(key);
|
setActiveKey(key);
|
||||||
|
|
@ -507,13 +516,13 @@ const EvalProjectMonitorDetail = (props) => {
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{wpsVisible && (
|
<OfficePreview
|
||||||
<WpsEditor
|
mode="modal"
|
||||||
onCancel={() => setWpsVisible(false)}
|
open={previewOpen}
|
||||||
fileId={wpsDoc?.fileId}
|
onCancel={() => setPreviewOpen(false)}
|
||||||
readOnly
|
url={previewUrl}
|
||||||
/>
|
width={1100}
|
||||||
)}
|
/>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Tabs, Tag, Flex } from "antd";
|
import { Tabs, Tag, Flex, message } from "antd";
|
||||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
|
|
@ -173,6 +173,11 @@ const ProjectFlow = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const openReportEditor = async () => {
|
const openReportEditor = async () => {
|
||||||
|
// 2026-08-18 前置拦截:报告文档 fileId 缺省(文档尚未生成/加载完成)时提示,不打开编辑器,避免 SDK 报错
|
||||||
|
if (!wpsDoc?.fileId) {
|
||||||
|
message.warning("报告文档尚未生成,请先创建报告后再查看");
|
||||||
|
return;
|
||||||
|
}
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
import ErrorBoundary from "./ErrorBoundary";
|
||||||
|
|
||||||
const { router } = tools;
|
const { router } = tools;
|
||||||
|
|
||||||
|
|
@ -82,24 +83,58 @@ const App = (props) => {
|
||||||
setExpandedMap((prev) => ({ ...prev, [index]: !prev[index] }));
|
setExpandedMap((prev) => ({ ...prev, [index]: !prev[index] }));
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// 2026-08-18 前置拦截:fileId 缺失时(如报告尚未生成、后端未返回文档ID),
|
||||||
|
// 直接提示而不初始化 SDK,避免 WebOfficeSDK 内部因缺省参数抛
|
||||||
|
// "Cannot read properties of undefined (reading 'officeType')" 未捕获异常。
|
||||||
|
if (!fileId) {
|
||||||
|
message.warning("暂无报告文档,请先在机构端生成报告后再查看");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 2026-08-18 全局兜底:SDK 在收到 "open.result" 事件时内部会读取
|
||||||
|
// o.fileInfo.officeType,若后端未返回 fileInfo(文档文件信息缺失),会抛
|
||||||
|
// "Cannot read properties of undefined (reading 'officeType')" 的异步未捕获异常。
|
||||||
|
// 该异常发生在 SDK 事件回调中,非本组件的 try/catch 可拦截,
|
||||||
|
// 故挂载期间通过 window error/unhandledrejection 监听统一转为友好提示。
|
||||||
|
const onWindowError = (event) => {
|
||||||
|
const err = event?.error || event?.reason;
|
||||||
|
const msg = err?.message || event?.message || "";
|
||||||
|
if (msg.includes("officeType")) {
|
||||||
|
// 阻止冒泡,防止 webpack-dev-server runtime error overlay 显示红屏
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
event.stopPropagation();
|
||||||
|
message.error("报告文档加载失败(文档文件信息缺失),请稍后重试或联系管理员");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("error", onWindowError, { capture: true });
|
||||||
|
window.addEventListener("unhandledrejection", onWindowError, { capture: true });
|
||||||
(async function () {
|
(async function () {
|
||||||
const instance = WebOfficeSDK.init({
|
// 2026-08-18 兜底保护:用 try/catch 包裹 SDK 初始化与 ready 流程,
|
||||||
// 必填项
|
// SDK 内部同步阶段任何缺省参数导致的异常,统一捕获并转为友好提示。
|
||||||
officeType: WebOfficeSDK.OfficeType.Writer,
|
try {
|
||||||
appId: "AK20260805KPWYZJ",
|
const instance = WebOfficeSDK.init({
|
||||||
mount: document.getElementById("app-wps"),
|
// 必填项
|
||||||
fileId: fileId,
|
officeType: WebOfficeSDK.OfficeType.Writer,
|
||||||
token: sessionStorage.getItem("token"),
|
appId: "AK20260805KPWYZJ",
|
||||||
customArgs: {
|
mount: document.getElementById("app-wps"),
|
||||||
readOnly,
|
fileId: fileId,
|
||||||
},
|
token: sessionStorage.getItem("token"),
|
||||||
...(readOnly ? { commonOptions: { isBrowserViewMode: true } } : {}),
|
customArgs: {
|
||||||
});
|
readOnly,
|
||||||
await instance.ready();
|
},
|
||||||
sdkRef.current = instance;
|
...(readOnly ? { commonOptions: { isBrowserViewMode: true } } : {}),
|
||||||
|
});
|
||||||
|
await instance.ready();
|
||||||
|
sdkRef.current = instance;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("WebOfficeSDK 初始化失败", e);
|
||||||
|
message.error("报告文档加载失败,请稍后重试或联系管理员");
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
return () => {
|
return () => {
|
||||||
sdkRef.current?.destroy();
|
sdkRef.current?.destroy();
|
||||||
|
window.removeEventListener("error", onWindowError, { capture: true });
|
||||||
|
window.removeEventListener("unhandledrejection", onWindowError, { capture: true });
|
||||||
};
|
};
|
||||||
}, [fileId]);
|
}, [fileId]);
|
||||||
|
|
||||||
|
|
@ -386,7 +421,15 @@ const App = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function WpsEditor(props) {
|
export default function WpsEditor(props) {
|
||||||
return createPortal(<ConnectApp {...props} />, document.body);
|
// 2026-08-18:用 ErrorBoundary 包裹渲染树,兜底第三方 SDK(WebOfficeSDK)在
|
||||||
|
// 渲染期或事件回调中抛出的 "Cannot read properties of undefined (reading 'officeType')"
|
||||||
|
// 等未捕获异常,渲染降级 UI,避免 React DevTools runtime error overlay 弹出红屏。
|
||||||
|
return createPortal(
|
||||||
|
<ErrorBoundary message="报告文档加载失败或文件不存在">
|
||||||
|
<ConnectApp {...props} />
|
||||||
|
</ErrorBoundary>,
|
||||||
|
document.body,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConnectApp = Connect([NS_SAFETY_EVAL_BUSINESS], true)(App);
|
const ConnectApp = Connect([NS_SAFETY_EVAL_BUSINESS], true)(App);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue