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

284 lines
8.2 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 React, { useState, useEffect } from "react";
import { Tabs, Tag, Flex, message } from "antd";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import WpsEditor from "~/pages/Container/WpsEditor";
import RiskAnalysisContent from "./RiskAnalysisContent";
import ContractContent from "./ContractContent";
import TeamContent from "./TeamContent";
import SurveyContent from "./SurveyContent";
import InternalReviewContent from "./InternalReviewContent";
import TechnicalReviewContent from "./TechnicalReviewContent";
import ControlContent from "./ControlContent";
import ArchiveContent from "./ArchiveContent";
import "./index.less";
const PROCESS_TABS = [
{
key: "risk",
index: "1",
label: "风险分析",
role: "市场部经办人 / 市场部经理",
},
{
key: "contract",
index: "2",
label: "业务合同",
role: "机构管理员 / 项目负责人",
},
{ key: "team", index: "3", label: "项目组", role: "评价部经理 / 机构主账号" },
{ key: "survey", index: "4", label: "现场踏勘", role: "项目组成员" },
{ key: "report", index: "5", label: "报告编制", role: "报告编制人" },
{ key: "internal", index: "6", label: "内部审核", role: "内部审核人" },
{ key: "technical", index: "7", label: "技术审核", role: "技术负责人" },
{ key: "control", index: "8", label: "过程控制", role: "过程控制负责人" },
{ key: "archive", index: "9", label: "项目归档", role: "档案管理员" },
];
const { router } = tools;
const TYPE_TO_TAB_KEY = {
RISK_ANALYSIS: "risk",
BUSINESS_CONTRACT: "contract",
PROJECT_GROUP: "team",
SITE_SURVEY: "survey",
REPORT_PREPARATION: "report",
INTERNAL_REVIEW: "internal",
TECHNICAL_REVIEW: "technical",
PROCESS_CONTROL: "control",
};
const parseProjectNode = (data) => {
if (Array.isArray(data)) return data;
try {
return JSON.parse(data || "[]");
} catch {
return [];
}
};
const buildProcessTabs = (projectNode, archiveFlag) => {
const nodes = parseProjectNode(projectNode);
const nodeMap = {};
nodes.forEach((n) => {
nodeMap[n.type] = n;
});
const allPrevDone = (idx) => {
for (let i = 0; i < idx; i++) {
const key = PROCESS_TABS[i].key;
const type = Object.keys(TYPE_TO_TAB_KEY).find(
(k) => TYPE_TO_TAB_KEY[k] === key,
);
if (!type) continue;
const node = nodeMap[type];
if (!node || node.state !== 1) return false;
}
return true;
};
const isNodeDone = (tabIdx) => {
const tabKey = PROCESS_TABS[tabIdx].key;
const tabType = Object.keys(TYPE_TO_TAB_KEY).find(
(k) => TYPE_TO_TAB_KEY[k] === tabKey,
);
const n = tabType ? nodeMap[tabType] : null;
return !!n && n.state === 1;
};
return PROCESS_TABS.map((item, idx) => {
const type = Object.keys(TYPE_TO_TAB_KEY).find(
(k) => TYPE_TO_TAB_KEY[k] === item.key,
);
const node = type ? nodeMap[type] : null;
if (idx === 2) {
// 项目组:业务合同完成后才解锁
const unlocked = isNodeDone(1);
return {
...item,
state: unlocked ? (node?.state === 1 ? "已完成" : "待办理") : "前置未完成",
stateType: unlocked ? (node?.state === 1 ? "success" : "default") : "warning",
locked: !unlocked,
};
}
if (idx === 3) {
// 现场踏勘:业务合同、项目组均完成后才解锁(串联)
const unlocked = isNodeDone(1) && isNodeDone(2);
return {
...item,
state: unlocked ? (node?.state === 1 ? "已完成" : "待办理") : "前置未完成",
stateType: unlocked ? (node?.state === 1 ? "success" : "default") : "warning",
locked: !unlocked,
};
}
if (idx === 7) {
// 过程控制前7个全部完成才解锁
const unlocked = allPrevDone(7);
return {
...item,
state: unlocked ? node.state === 1 ? "已完成" : "待办理" : "前置未完成",
stateType: unlocked ? node.state === 1 ? "success" : "default" : "warning",
locked: !unlocked,
};
}
if (idx === 8) {
// 项目归档前8个全部完成才解锁
const unlocked = allPrevDone(8);
const archived = archiveFlag === 1;
return {
...item,
state: unlocked ? (archived ? "已完成" : "待办理") : "前置未完成",
stateType: unlocked ? (archived ? "success" : "default") : "warning",
locked: !unlocked,
};
}
if (node) {
return {
...item,
state: node.state === 1 ? "已完成" : "待办理",
stateType: node.state === 1 ? "success" : "default",
locked: false,
};
}
return { ...item, locked: false };
});
};
const ProjectFlow = (props) => {
const [activeKey, setActiveKey] = useState("risk");
const [visible, setVisible] = useState(false);
const { wpsDoc, evalProjectDetailData } = props.safetyEvalBusiness || {};
const projectId = router.query?.id;
const readOnly = router.query?.readOnly === '1';
const processTabs = buildProcessTabs(
evalProjectDetailData?.projectNode,
evalProjectDetailData?.archiveFlag,
);
const handleTabChange = (key) => {
if (key === "report") {
openReportEditor();
return;
}
setActiveKey(key);
};
const openReportEditor = async () => {
if (!wpsDoc?.fileId) {
message.warning("报告文档尚未生成,请先创建报告后再查看");
return;
}
setVisible(true);
};
const getDetail = () => {
props.evalProjectDetail({
id: projectId,
});
};
useEffect(() => {
props.queryMyOrCreateDoc({
docxUrl: "",
projectId,
});
}, []);
useEffect(()=>{
if(!visible){
getDetail();
}
}, [visible])
const tabItems = processTabs.map((item) => {
let children = null;
switch (item.key) {
case "risk":
children = <RiskAnalysisContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "contract":
children = <ContractContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "team":
children = <TeamContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "survey":
children = <SurveyContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "internal":
children = <InternalReviewContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "technical":
children = <TechnicalReviewContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "control":
children = <ControlContent getDetail={getDetail} readOnly={readOnly} />;
break;
case "archive":
children = <ArchiveContent getDetail={getDetail} readOnly={readOnly} />;
break;
default:
children = null;
}
return {
key: item.key,
disabled: item.locked,
label: (
<Flex align="center" gap={6}>
{item.index} {item.label}
<Tag color={item.stateType} className="pf-tag">
{item.state}
</Tag>
</Flex>
),
children,
};
});
return (
<PageLayout
history={props.history}
previous
footer={<div id="pf-footer-slot" />}
title={
<div>
<span>项目工作台</span>
<div className="pageLayout-extra">
{evalProjectDetailData?.projectName} |{" "}
{evalProjectDetailData?.evalTypeName} |{" "}
{evalProjectDetailData?.projectNo}
</div>
</div>
}
>
<Tabs
activeKey={activeKey}
onChange={handleTabChange}
items={tabItems}
className="pf-tabs"
destroyOnHidden
/>
{visible && (
<WpsEditor onCancel={() => setVisible(false)} fileId={wpsDoc?.fileId} fileName={wpsDoc?.name} readOnly={readOnly || evalProjectDetailData?.archiveFlag === 1} />
)}
</PageLayout>
);
};
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(AntdTableFuncControl(ProjectFlow));