safety-eval-service-frontend/src/pages/Container/WpsEditor/index.js

354 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { useState, useEffect, useRef } from "react";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import {
Flex,
Button,
Tabs,
Input,
Tag,
Progress,
Typography,
message,
} from "antd";
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, 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("文档尚未加载完成");
return;
}
await sdkRef.current.save();
message.success("保存成功");
};
const toggleExpand = (index) => {
setExpandedMap((prev) => ({ ...prev, [index]: !prev[index] }));
};
useEffect(() => {
(async function () {
const instance = WebOfficeSDK.init({
// 必填项
officeType: WebOfficeSDK.OfficeType.Writer,
appId: "SX20260724JJYTBX",
mount: document.getElementById("app-sbsb"),
fileId: fileId,
token: sessionStorage.getItem("token"),
});
await instance.ready();
sdkRef.current = instance;
})();
}, [fileId]);
return (
<div className="WpsEditor-container">
<PageLayout
title={
<Flex align="center" gap={8}>
<ArrowLeftOutlined
onClick={() => {
console.log("点击了返回按钮");
onCancel();
}}
/>
<span>安全评价报告编制</span>
</Flex>
}
extra={
<Flex gap={12}>
<Button onClick={handleSave}>保存</Button>
<Button>下载报告</Button>
</Flex>
}
>
<div className="WpsEditor-flexContainer">
<div id="app-sbsb" className="WpsEditor-editorArea"></div>
<div className="WpsEditor-sidePanel">
<Tabs
type="card"
tabPlacement="top"
items={[
{
label: "知识库",
key: "1",
children: (
<div className="WpsEditor-dock">
<Input.Search placeholder="搜索法规、案例、措施" />
<Flex gap={4} className="WpsEditor-dock-cats">
{[
"推荐",
"法规标准",
"危险因素",
"评价方法",
"事故案例",
].map((cat) => (
<Button
key={cat}
size="small"
type={cat === "推荐" ? "primary" : "default"}
>
{cat}
</Button>
))}
</Flex>
<div className="WpsEditor-dock-list">
{[
{
cat: "法规标准",
title: "中华人民共和国安全生产法",
desc: "2021年修正当前有效。可引用至评价依据章节发多少个给梵蒂换个房间官方电话冈的是非观大使馆反对给多少给多少规范化的。",
},
{
cat: "危险因素",
title: "液氨泄漏事故场景",
desc: "包含泄漏扩散、中毒窒息、次生火灾及应急处置要点。",
},
{
cat: "评价方法",
title: "安全检查表法",
desc: "适用于法规符合性、设施状态和安全管理制度逐项检查。",
},
{
cat: "评价方法",
title: "安全检查表法",
desc: "适用于法规符合性、设施状态和安全管理制度逐项检查。",
},
{
cat: "评价方法",
title: "安全检查表法",
desc: "适用于法规符合性、设施状态和安全管理制度逐项检查。",
},
{
cat: "评价方法",
title: "安全检查表法",
desc: "适用于法规符合性、设施状态和安全管理制度逐项检查。",
},
{
cat: "评价方法",
title: "安全检查表法",
desc: "适用于法规符合性、设施状态和安全管理制度逐项检查。",
},
].map((item, i) => {
const expanded = expandedMap[i];
return (
<div key={i} className="WpsEditor-resourceCard">
<Tag color="blue">{item.cat}</Tag>
<Typography.Text
strong
className="WpsEditor-resourceTitle"
>
{item.title}
</Typography.Text>
<Typography.Paragraph
type="secondary"
className="WpsEditor-resourceDesc"
ellipsis={expanded ? false : { rows: 2 }}
>
{item.desc}
</Typography.Paragraph>
<Button
type="link"
size="small"
onClick={() => toggleExpand(i)}
>
{expanded ? "收起" : "展开"}
</Button>
</div>
);
})}
</div>
</div>
),
},
{
label: "模板",
key: "2",
children: (
<div className="WpsEditor-dock">
<Flex
justify="space-between"
align="center"
className="WpsEditor-dock-heading"
>
<Typography.Text strong>机构报告模板</Typography.Text>
<Button type="link" size="small">
管理
</Button>
</Flex>
<div className="WpsEditor-dock-list">
{templateMap.map(({ name, url }, i) => (
<div key={i} className="WpsEditor-templateCard">
<div>
<Typography.Text strong>{name}</Typography.Text>
{/* <Typography.Paragraph
type="secondary"
style={{ margin: 0, fontSize: 12 }}
>
{url}
</Typography.Paragraph> */}
</div>
<Button
loading={createDocLoading}
size="small"
onClick={() => {
props
.createWpsDoc({ docxUrl: url })
.then((res) => {
const fileId = res?.data?.fileId;
if (!fileId) {
return;
}
setFileId(fileId);
});
}}
>
应用
</Button>
</div>
))}
</div>
<div className="WpsEditor-templateNote">
<Typography.Text strong>模板包含</Typography.Text>
<Typography.Paragraph
type="secondary"
style={{ margin: 0, fontSize: 12 }}
>
封面责任页目录章节结构页眉页脚表格样式附件与附图目录
</Typography.Paragraph>
</div>
</div>
),
},
{
label: "签字",
key: "3",
children: (
<div className="WpsEditor-dock">
<Flex
justify="space-between"
align="center"
className="WpsEditor-dock-heading"
>
<Typography.Text strong>责任页签字</Typography.Text>
<span className="WpsEditor-signProgress">
1 / 5 已完成
</span>
</Flex>
<Progress percent={20} size="small" />
<div className="WpsEditor-dock-list">
{[
{
initial: "张",
name: "张建国",
role: "项目负责人",
status: "signed",
},
{
initial: "李",
name: "李明华",
role: "报告编制人",
status: "pending",
},
{
initial: "王",
name: "王丽萍",
role: "内部审核人",
status: "locked",
},
{
initial: "陈",
name: "陈志强",
role: "技术负责人",
status: "locked",
},
{
initial: "王",
name: "王丽萍",
role: "过程控制负责人",
status: "locked",
},
].map((signer, i) => (
<div
key={i}
className={`WpsEditor-signer ${signer.status}`}
>
<div className="WpsEditor-signerAvatar">
{signer.initial}
</div>
<div className="WpsEditor-signerInfo">
<Typography.Text strong>
{signer.name}
</Typography.Text>
<Typography.Paragraph
type="secondary"
style={{ margin: 0, fontSize: 12 }}
>
{signer.role}
</Typography.Paragraph>
</div>
{signer.status === "signed" && (
<Tag color="success">已签字</Tag>
)}
{signer.status === "pending" && (
<Button size="small" type="primary" ghost>
下发APP签字
</Button>
)}
{signer.status === "locked" && <Tag>待内审</Tag>}
</div>
))}
</div>
<div className="WpsEditor-signRule">
<Typography.Paragraph
type="secondary"
style={{ margin: 0, fontSize: 12 }}
>
签字由 PC 端下发至本人
APP手写签署后自动回传各版本签字独立留痕
</Typography.Paragraph>
</div>
</div>
),
},
]}
/>
</div>
</div>
</PageLayout>
</div>
);
};
export default function WpsEditor(props) {
return createPortal(<ConnectApp {...props} />, document.body);
}
const ConnectApp = Connect([NS_SAFETY_EVAL_BUSINESS], true)(App);