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

188 lines
9.7 KiB
JavaScript
Raw Normal View History

2026-07-20 11:16:32 +08:00
import { useState, useEffect } from "react";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import { Flex, Button, Tabs, Input, Tag, Progress, Typography } from "antd";
2026-07-20 13:38:09 +08:00
import { ArrowLeftOutlined } from "@ant-design/icons";
2026-07-20 11:16:32 +08:00
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 "./index.less";
2026-07-20 13:38:09 +08:00
const App = (props) => {
const { onCancel } = props;
2026-07-20 11:16:32 +08:00
const [expandedMap, setExpandedMap] = useState({});
const toggleExpand = (index) => {
setExpandedMap((prev) => ({ ...prev, [index]: !prev[index] }));
};
useEffect(() => {
(async function () {
const instance = WebOfficeSDK.init({
// 必填项
officeType: WebOfficeSDK.OfficeType.Writer,
appId: "SX20260717TSGKEA",
mount: document.getElementById("app-sbsb"),
fileId: "123",
token: sessionStorage.getItem("token"),
});
await instance.ready();
const app = instance.Application;
})();
}, []);
return (
<div className="WpsEditor-container">
<PageLayout
2026-07-20 13:38:09 +08:00
title={
<Flex align="center" gap={8}>
<ArrowLeftOutlined onClick={() => {
console.log("点击了返回按钮");
onCancel()
}} />
<span>安全评价报告编制</span>
</Flex>
}
2026-07-20 11:16:32 +08:00
extra={
<Flex gap={12}>
<Button>保存</Button>
<Button>下载报告</Button>
<Button type="primary">提交内审</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">
{[
{ name: "安全预评价报告", desc: "AQ 8001 / AQ 8002 · V3.2", active: true },
{ name: "安全验收评价报告", desc: "AQ 8001 / AQ 8003 · V2.8", active: false },
{ name: "安全现状评价报告", desc: "机构标准模板 · V4.1", active: false },
].map((tmpl, i) => (
<div key={i} className={`WpsEditor-templateCard${tmpl.active ? " active" : ""}`}>
<div>
<Typography.Text strong>{tmpl.name}</Typography.Text>
<Typography.Paragraph type="secondary" style={{ margin: 0, fontSize: 12 }}>{tmpl.desc}</Typography.Paragraph>
</div>
{tmpl.active ? <Tag color="blue">使用中</Tag> : <Button size="small"></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>
);
};
2026-07-20 13:38:09 +08:00
export default function WpsEditor(props) {
return createPortal(<App {...props} />, document.body);
2026-07-20 11:16:32 +08:00
}