feat
parent
c96233c0a1
commit
6ad6475911
|
|
@ -13,8 +13,8 @@ module.exports = {
|
|||
//API_HOST: "https://gbs-gateway.qhdsafety.com",
|
||||
|
||||
//API_HOST: "http://192.168.0.152",
|
||||
//API_HOST: "http://192.168.0.150", //太浅
|
||||
API_HOST: "http://192.168.0.152",
|
||||
API_HOST: "http://192.168.0.150", //太浅
|
||||
//API_HOST: "http://192.168.0.152",
|
||||
//API_HOST: "http://192.168.0.103", //huwei
|
||||
},
|
||||
production: {
|
||||
|
|
|
|||
|
|
@ -165,4 +165,74 @@ export const evalSurveyList = declareRequest(
|
|||
export const evalSurveySaveAttach = declareRequest(
|
||||
"evalSurveySaveAttachLoading",
|
||||
"Post > @/safetyEval/institution/eval-survey/saveSurveyAttach",
|
||||
);
|
||||
|
||||
// ===== 内部审核 =====
|
||||
|
||||
export const evalInternalReviewDetail = declareRequest(
|
||||
"internalReviewDetailLoading",
|
||||
"Get > /safetyEval/institution/eval-internal-review/detail",
|
||||
"internalReviewDetail: {} | res.data || {}",
|
||||
);
|
||||
|
||||
export const evalInternalReviewConfirm = declareRequest(
|
||||
"internalReviewConfirmLoading",
|
||||
"Post > @/safetyEval/institution/eval-internal-review/confirm",
|
||||
);
|
||||
|
||||
export const evalInternalReviewAssign = declareRequest(
|
||||
"internalReviewAssignLoading",
|
||||
"Post > @/safetyEval/institution/eval-internal-review/assign",
|
||||
);
|
||||
|
||||
// ===== 技术审核 =====
|
||||
|
||||
export const evalTechReviewDetail = declareRequest(
|
||||
"techReviewDetailLoading",
|
||||
"Get > /safetyEval/institution/eval-tech-review/detail",
|
||||
"techReviewDetail: {} | res.data || {}",
|
||||
);
|
||||
|
||||
export const evalTechReviewConfirm = declareRequest(
|
||||
"techReviewConfirmLoading",
|
||||
"Post > @/safetyEval/institution/eval-tech-review/confirm",
|
||||
);
|
||||
|
||||
export const evalTechReviewAssign = declareRequest(
|
||||
"techReviewAssignLoading",
|
||||
"Post > @/safetyEval/institution/eval-tech-review/assign",
|
||||
);
|
||||
|
||||
// ===== 过程控制 =====
|
||||
|
||||
export const evalProcessControlDetail = declareRequest(
|
||||
"processControlDetailLoading",
|
||||
"Get > /safetyEval/institution/eval-process-control/detail",
|
||||
"processControlDetail: {} | res.data || {}",
|
||||
);
|
||||
|
||||
export const evalProcessControlConfirm = declareRequest(
|
||||
"processControlConfirmLoading",
|
||||
"Post > @/safetyEval/institution/eval-process-control/confirm",
|
||||
);
|
||||
|
||||
export const evalProcessControlAssign = declareRequest(
|
||||
"processControlAssignLoading",
|
||||
"Post > @/safetyEval/institution/eval-process-control/assign",
|
||||
);
|
||||
|
||||
export const evalProcessControlGenerateHandover = declareRequest(
|
||||
"processControlHandoverLoading",
|
||||
"Post > @/safetyEval/institution/eval-process-control/generate-handover-form",
|
||||
);
|
||||
|
||||
export const evalProcessControlArchive = declareRequest(
|
||||
"processControlArchiveLoading",
|
||||
"Post > @/safetyEval/institution/eval-process-control/archive",
|
||||
);
|
||||
|
||||
export const evalProcessControlFiles = declareRequest(
|
||||
"processControlFilesLoading",
|
||||
"Get > /safetyEval/institution/eval-process-control/process-files",
|
||||
"processControlFiles: [] | res.data || []",
|
||||
);
|
||||
|
|
@ -1,26 +1,423 @@
|
|||
import React from "react";
|
||||
import { Card, Empty, Table } from "antd";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Tag, Button, Card, Row, Col, Table, Select, Input, Flex, Typography, message } from "antd";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
|
||||
const ControlContent = () => (
|
||||
<Card title="过程控制审核与归档">
|
||||
<Empty description="过程控制审核须校验前7个节点全部完成并形成有效签字记录后才可办理" />
|
||||
<Table
|
||||
dataSource={[
|
||||
{ id: 1, item: "风险分析", content: "合同前完成并审批签字", result: "完整" },
|
||||
{ id: 2, item: "项目实施计划", content: "人员、进度、设备和分工", result: "完整" },
|
||||
{ id: 3, item: "从业告知与现场", content: "告知盖章件、打卡、检查表、整改复查", result: "完整" },
|
||||
{ id: 4, item: "审核签字", content: "内审、技审修改闭环及独立签字", result: "待技审" },
|
||||
]}
|
||||
columns={[
|
||||
{ title: "程序审核项", dataIndex: "item" },
|
||||
{ title: "核查内容", dataIndex: "content" },
|
||||
{ title: "结果", dataIndex: "result" },
|
||||
]}
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
className="pf-table-mt"
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
const { TextArea } = Input;
|
||||
const { router } = tools;
|
||||
|
||||
export default ControlContent;
|
||||
const CONCLUSION_OPTIONS = [
|
||||
{ value: "conform_to", label: "符合" },
|
||||
{ value: "not_conform_to", label: "需修改" },
|
||||
];
|
||||
|
||||
const ControlContent = (props) => {
|
||||
const projectId = router.query?.id;
|
||||
const { processControlDetail, processControlFiles } = props.safetyEvalBusiness || {};
|
||||
const { processControl, controllers, reviewItems } = processControlDetail || {};
|
||||
|
||||
// 当前步骤:1-过程控制审核 2-机构负责人签发 3-项目归档
|
||||
const [step, setStep] = useState(1);
|
||||
|
||||
// 过程控制审核
|
||||
const [rows, setRows] = useState([]);
|
||||
const [opinionContent, setOpinionContent] = useState("");
|
||||
|
||||
// 项目归档
|
||||
const [files, setFiles] = useState([]);
|
||||
|
||||
const fetchDetail = () => {
|
||||
props.evalProcessControlDetail({ projectId });
|
||||
};
|
||||
|
||||
const fetchFiles = () => {
|
||||
props.evalProcessControlFiles({ projectId });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (projectId) {
|
||||
fetchDetail();
|
||||
fetchFiles();
|
||||
}
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (reviewItems) {
|
||||
setRows(
|
||||
reviewItems.map((item) => ({
|
||||
...item,
|
||||
_key: item.id || item.reviewDimensionCode,
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (processControl?.opinionContent) {
|
||||
setOpinionContent(processControl.opinionContent);
|
||||
}
|
||||
}, [processControlDetail]);
|
||||
|
||||
useEffect(() => {
|
||||
if (processControlFiles) {
|
||||
setFiles(processControlFiles);
|
||||
}
|
||||
}, [processControlFiles]);
|
||||
|
||||
const updateRow = (index, field, value) => {
|
||||
const next = [...rows];
|
||||
next[index] = { ...next[index], [field]: value };
|
||||
setRows(next);
|
||||
};
|
||||
|
||||
const controllerName = processControl?.controllerName || "";
|
||||
const isDispatched = processControl?.reviewerSignatureTaskStatus !== "non_dispatched";
|
||||
const isSignatureCompleted = processControl?.reviewerSignatureTaskStatus === "completed";
|
||||
const hasHandoverForm = !!processControl?.handoverFormUrl;
|
||||
const problemCount = rows.filter((r) => r.reviewConclusion === "not_conform_to").length;
|
||||
const canArchive = isSignatureCompleted && hasHandoverForm;
|
||||
|
||||
// 过程控制签字提交(confirm)
|
||||
const handleConfirm = async (resultCode) => {
|
||||
if (!projectId) return;
|
||||
const payload = {
|
||||
id: processControl?.id,
|
||||
projectId,
|
||||
resultCode,
|
||||
opinionContent,
|
||||
reviewItems: rows.map((r) => ({
|
||||
bizType: "eval_process_control",
|
||||
bizId: processControl?.id,
|
||||
reviewDimensionCode: r.reviewDimensionCode,
|
||||
reviewDimensionName: r.reviewDimensionName,
|
||||
reviewFocus: r.reviewFocus,
|
||||
reviewConclusion: r.reviewConclusion,
|
||||
reviewOpinion: r.reviewOpinion,
|
||||
})),
|
||||
};
|
||||
const res = await props.evalProcessControlConfirm(payload);
|
||||
if (res?.success !== false) {
|
||||
message.success(resultCode === "passed" ? "已提交通过审核" : "已提交退回修改");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
// 下发签字任务(assign)
|
||||
const handleAssign = async () => {
|
||||
if (!projectId) return;
|
||||
const res = await props.evalProcessControlAssign({ projectId });
|
||||
if (res?.success !== false) {
|
||||
message.success("已下发签字任务");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
// 生成归档交接单
|
||||
const handleGenerateHandover = async () => {
|
||||
if (!projectId) return;
|
||||
const res = await props.evalProcessControlGenerateHandover({ projectId });
|
||||
if (res?.success !== false) {
|
||||
message.success("归档交接单已生成");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
// 归档项目并入库
|
||||
const handleArchive = async () => {
|
||||
if (!projectId) return;
|
||||
const res = await props.evalProcessControlArchive({ projectId });
|
||||
if (res?.success !== false) {
|
||||
message.success("项目已归档入库");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const reviewColumns = [
|
||||
{ title: "审核维度", dataIndex: "reviewDimensionName", width: 120 },
|
||||
{ title: "审核重点", dataIndex: "reviewFocus", width: 200 },
|
||||
{
|
||||
title: "结论",
|
||||
dataIndex: "reviewConclusion",
|
||||
width: 120,
|
||||
render: (val, _, idx) => (
|
||||
<Select
|
||||
value={val}
|
||||
size="small"
|
||||
style={{ width: 100 }}
|
||||
onChange={(v) => updateRow(idx, "reviewConclusion", v)}
|
||||
>
|
||||
{CONCLUSION_OPTIONS.map((opt) => (
|
||||
<Select.Option key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "审核意见",
|
||||
dataIndex: "reviewOpinion",
|
||||
render: (val, _, idx) => (
|
||||
<Input
|
||||
size="small"
|
||||
value={val}
|
||||
onChange={(e) => updateRow(idx, "reviewOpinion", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const fileColumns = [
|
||||
{ title: "流程名称", dataIndex: "processName", width: 100 },
|
||||
{ title: "条目名称", dataIndex: "itemName", width: 120 },
|
||||
{ title: "文件名称", dataIndex: "materialName", width: 200 },
|
||||
{
|
||||
title: "文件地址",
|
||||
dataIndex: "projectDocUrl",
|
||||
width: 200,
|
||||
render: (url) =>
|
||||
url ? (
|
||||
<a href={url} target="_blank" rel="noreferrer">
|
||||
查看文件
|
||||
</a>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
},
|
||||
{ title: "资料类型", dataIndex: "materialType", width: 100 },
|
||||
];
|
||||
|
||||
const STEP_ITEMS = [
|
||||
{ key: 1, label: "过程控制审核" },
|
||||
{ key: 2, label: "机构负责人签发" },
|
||||
{ key: 3, label: "项目归档" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Flex gap={0} style={{ marginBottom: 16, borderBottom: "1px solid #e8e8e8" }}>
|
||||
{STEP_ITEMS.map((item) => (
|
||||
<Button
|
||||
key={item.key}
|
||||
type="text"
|
||||
onClick={() => setStep(item.key)}
|
||||
style={{
|
||||
minWidth: 128,
|
||||
borderBottom: step === item.key ? "3px solid #1677ff" : "3px solid transparent",
|
||||
borderRadius: 0,
|
||||
fontWeight: step === item.key ? 700 : 400,
|
||||
color: step === item.key ? "#1677ff" : undefined,
|
||||
background: step === item.key ? "#e6f4ff" : "transparent",
|
||||
}}
|
||||
>
|
||||
{item.label}
|
||||
</Button>
|
||||
))}
|
||||
</Flex>
|
||||
|
||||
{step === 1 && (
|
||||
<Card
|
||||
title="过程控制审核"
|
||||
style={{ marginBottom: 16 }}
|
||||
styles={{ body: { paddingBottom: 0 } }}
|
||||
>
|
||||
<div className="pf-permission">
|
||||
<Tag color="blue" className="pf-tag">
|
||||
过程控制负责人
|
||||
</Tag>
|
||||
<span className="pf-desc">过程控制负责人核验前7节点完成及签字记录</span>
|
||||
</div>
|
||||
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">过程控制负责人</Typography.Text>
|
||||
<div>
|
||||
<strong>{controllerName || "-"}</strong>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">审核项</Typography.Text>
|
||||
<div>
|
||||
<strong>{rows.length}项</strong>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">问题</Typography.Text>
|
||||
<div>
|
||||
<Typography.Text strong type={problemCount > 0 ? "warning" : undefined}>
|
||||
{problemCount}项
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
dataSource={rows}
|
||||
columns={reviewColumns}
|
||||
rowKey="_key"
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<div style={{ margin: "12px 0" }}>
|
||||
<Typography.Text strong>总体过程控制意见</Typography.Text>
|
||||
<TextArea
|
||||
rows={2}
|
||||
value={opinionContent}
|
||||
onChange={(e) => setOpinionContent(e.target.value)}
|
||||
style={{ marginTop: 4 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 10, paddingBottom: 16 }}>
|
||||
<Flex gap={8} align="center">
|
||||
<Typography.Text type="secondary">过程控制负责人签字</Typography.Text>
|
||||
<strong>{controllerName}</strong>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={handleAssign}
|
||||
loading={props.safetyEvalBusiness?.processControlAssignLoading}
|
||||
disabled={isDispatched}
|
||||
>
|
||||
{isDispatched ? "已下发APP签字" : "下发APP签字"}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Flex gap={8}>
|
||||
<Button onClick={() => handleConfirm("not_passed")}>退回修改</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => handleConfirm("passed")}
|
||||
loading={props.safetyEvalBusiness?.processControlConfirmLoading}
|
||||
>
|
||||
通过
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{step === 2 && (
|
||||
<Card
|
||||
title="机构负责人签发"
|
||||
style={{ marginBottom: 16 }}
|
||||
styles={{ body: { paddingBottom: 0 } }}
|
||||
>
|
||||
<div className="pf-permission">
|
||||
<Tag color="blue" className="pf-tag">
|
||||
评价机构负责人
|
||||
</Tag>
|
||||
<span className="pf-desc">机构负责人终审并签发,确认项目成果</span>
|
||||
</div>
|
||||
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
{controllers?.map((c) => (
|
||||
<Col span={8} key={c.id || c.personnelId}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">机构负责人</Typography.Text>
|
||||
<div>
|
||||
<strong>{c.personnelName}</strong>
|
||||
</div>
|
||||
{c.deptName && (
|
||||
<div>
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||
{c.deptName}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
{(!controllers || controllers.length === 0) && (
|
||||
<Col span={24}>
|
||||
<Typography.Text type="secondary">暂无机构负责人信息</Typography.Text>
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
<Flex justify="flex-end" style={{ paddingBottom: 16 }}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleAssign}
|
||||
loading={props.safetyEvalBusiness?.processControlAssignLoading}
|
||||
>
|
||||
终审并签发
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{step === 3 && (
|
||||
<Card
|
||||
title="项目归档"
|
||||
style={{ marginBottom: 16 }}
|
||||
styles={{ body: { paddingBottom: 0 } }}
|
||||
>
|
||||
<div className="pf-permission">
|
||||
<Tag color="blue" className="pf-tag">
|
||||
项目归档
|
||||
</Tag>
|
||||
<span className="pf-desc">项目过程文件清单,确认签字完成后归档入库</span>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
dataSource={files}
|
||||
columns={fileColumns}
|
||||
rowKey={(record) => `${record.processName}-${record.materialName}-${record.itemName}`}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 12, paddingBottom: 16 }}>
|
||||
<Flex gap={8} align="center">
|
||||
{!hasHandoverForm && (
|
||||
<Button
|
||||
size="small"
|
||||
onClick={handleGenerateHandover}
|
||||
loading={props.safetyEvalBusiness?.processControlHandoverLoading}
|
||||
>
|
||||
生成归档交接单
|
||||
</Button>
|
||||
)}
|
||||
{hasHandoverForm && (
|
||||
<Typography.Text type="success">
|
||||
归档交接单已生成
|
||||
{processControl?.handoverFormUrl && (
|
||||
<a
|
||||
href={processControl.handoverFormUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
style={{ marginLeft: 8 }}
|
||||
>
|
||||
查看
|
||||
</a>
|
||||
)}
|
||||
</Typography.Text>
|
||||
)}
|
||||
</Flex>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleArchive}
|
||||
loading={props.safetyEvalBusiness?.processControlArchiveLoading}
|
||||
disabled={!canArchive}
|
||||
title={
|
||||
!canArchive
|
||||
? !isSignatureCompleted
|
||||
? "需签字完成后才可归档"
|
||||
: "需生成归档交接单后才可归档"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
双方签字并确认入库
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(ControlContent);
|
||||
|
|
@ -1,20 +1,63 @@
|
|||
import React, { useState } from "react";
|
||||
import { Tag, Button, Card, Table, Select, Input, Flex, Typography, Row, Col } from "antd";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
Tag,
|
||||
Button,
|
||||
Card,
|
||||
Table,
|
||||
Select,
|
||||
Input,
|
||||
Flex,
|
||||
Typography,
|
||||
Row,
|
||||
Col,
|
||||
message,
|
||||
} from "antd";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
|
||||
const { TextArea } = Input;
|
||||
const { router } = tools;
|
||||
|
||||
const INITIAL_ROWS = [
|
||||
{ dim: "评价依据", focus: "充分、有效", result: "符合", opinion: "补充地方标准有效版本", feedback: "已验证", feedbackType: "success" },
|
||||
{ dim: "危险辨识", focus: "全面、无遗漏", result: "需修改", opinion: "补充液氨装卸泄漏场景", feedback: "待反馈", feedbackType: "warning" },
|
||||
{ dim: "单元划分", focus: "科学合理", result: "符合", opinion: "划分合理", feedback: "—", feedbackType: "default" },
|
||||
{ dim: "评价方法", focus: "适用、过程正确", result: "符合", opinion: "方法适用", feedback: "—", feedbackType: "default" },
|
||||
{ dim: "对策措施", focus: "针对性、可操作性", result: "需修改", opinion: "细化报警联锁措施", feedback: "已验证", feedbackType: "success" },
|
||||
{ dim: "评价结论", focus: "客观、正确", result: "符合", opinion: "结论客观", feedback: "—", feedbackType: "default" },
|
||||
{ dim: "报告规范", focus: "格式、文字、数据逻辑", result: "符合", opinion: "统一图表编号", feedback: "—", feedbackType: "default" },
|
||||
const CONCLUSION_OPTIONS = [
|
||||
{ value: "conform_to", label: "符合" },
|
||||
{ value: "not_conform_to", label: "需修改" },
|
||||
];
|
||||
|
||||
const InternalReviewContent = () => {
|
||||
const [rows, setRows] = useState(INITIAL_ROWS);
|
||||
const InternalReviewContent = (props) => {
|
||||
const projectId = router.query?.id;
|
||||
const {
|
||||
internalReviewDetail,
|
||||
internalReviewAssignLoading,
|
||||
internalReviewConfirmLoading,
|
||||
internalReviewDetailLoading,
|
||||
} = props.safetyEvalBusiness || {};
|
||||
const { internalReview, reviewers, reviewItems } = internalReviewDetail || {};
|
||||
|
||||
const [rows, setRows] = useState([]);
|
||||
const [overallOpinion, setOverallOpinion] = useState("");
|
||||
|
||||
const fetchDetail = () => {
|
||||
props.evalInternalReviewDetail({ projectId });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (projectId) fetchDetail();
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (reviewItems) {
|
||||
setRows(
|
||||
reviewItems.map((item) => ({
|
||||
...item,
|
||||
_key: item.id || item.reviewDimensionCode,
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (internalReview?.opinionContent) {
|
||||
setOverallOpinion(internalReview.opinionContent);
|
||||
}
|
||||
}, [internalReviewDetail]);
|
||||
|
||||
const updateRow = (index, field, value) => {
|
||||
const next = [...rows];
|
||||
|
|
@ -22,74 +65,179 @@ const InternalReviewContent = () => {
|
|||
setRows(next);
|
||||
};
|
||||
|
||||
const reviewerName = internalReview?.reviewerName || "";
|
||||
const isDispatched =
|
||||
internalReview?.reviewerSignatureTaskStatus === "dispatched";
|
||||
const problemCount = rows.filter(
|
||||
(r) => r.reviewConclusion === "not_conform_to",
|
||||
).length;
|
||||
|
||||
const handleAssign = async () => {
|
||||
if (!projectId) return;
|
||||
const res = await props.evalInternalReviewAssign({ projectId });
|
||||
if (res?.success !== false) {
|
||||
message.success("已下发签字任务");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = async (resultCode) => {
|
||||
if (!projectId) return;
|
||||
const payload = {
|
||||
id: internalReview?.id,
|
||||
projectId,
|
||||
resultCode,
|
||||
opinionContent: overallOpinion,
|
||||
reviewItems: rows.map((r) => ({
|
||||
bizType: "eval_internal_review",
|
||||
bizId: internalReview?.id,
|
||||
reviewDimensionCode: r.reviewDimensionCode,
|
||||
reviewDimensionName: r.reviewDimensionName,
|
||||
reviewFocus: r.reviewFocus,
|
||||
reviewConclusion: r.reviewConclusion,
|
||||
reviewOpinion: r.reviewOpinion,
|
||||
})),
|
||||
};
|
||||
const res = await props.evalInternalReviewConfirm(payload);
|
||||
if (res?.success !== false) {
|
||||
message.success(
|
||||
resultCode === "passed" ? "已提交" : "已保存",
|
||||
);
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: "审核维度", dataIndex: "reviewDimensionName", width: 100 },
|
||||
{ title: "审核重点", dataIndex: "reviewFocus", width: 160 },
|
||||
{
|
||||
title: "结论",
|
||||
dataIndex: "reviewConclusion",
|
||||
width: 120,
|
||||
render: (val, _, idx) => (
|
||||
<Select
|
||||
value={val}
|
||||
size="small"
|
||||
style={{ width: 100 }}
|
||||
onChange={(v) => updateRow(idx, "reviewConclusion", v)}
|
||||
>
|
||||
{CONCLUSION_OPTIONS.map((opt) => (
|
||||
<Select.Option key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "审核意见",
|
||||
dataIndex: "reviewOpinion",
|
||||
width: 180,
|
||||
render: (val, _, idx) => (
|
||||
<Input
|
||||
size="small"
|
||||
value={val}
|
||||
allowClear
|
||||
placeholder="请输入审核意见"
|
||||
maxLength={80}
|
||||
onChange={(e) => updateRow(idx, "reviewOpinion", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="pf-permission">
|
||||
<Tag color="blue" className="pf-tag">内部审核人</Tag>
|
||||
<Tag color="blue" className="pf-tag">
|
||||
内部审核人
|
||||
</Tag>
|
||||
<span className="pf-desc">审核、修改、反馈、验证闭环</span>
|
||||
</div>
|
||||
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">审核版本</Typography.Text><div><strong>V1.3</strong></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">内审人</Typography.Text><div><strong>王丽萍</strong></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">审核项</Typography.Text><div><strong>7项</strong></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">问题</Typography.Text><div><Typography.Text strong type="warning">2项</Typography.Text></div></Card></Col>
|
||||
</Row>
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">内审人</Typography.Text>
|
||||
<div>
|
||||
<strong>{reviewerName || "-"}</strong>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">审核项</Typography.Text>
|
||||
<div>
|
||||
<strong>{rows.length}项</strong>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">问题</Typography.Text>
|
||||
<div>
|
||||
<Typography.Text
|
||||
strong
|
||||
type={problemCount > 0 ? "warning" : undefined}
|
||||
>
|
||||
{problemCount}项
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
dataSource={rows}
|
||||
columns={[
|
||||
{ title: "审核维度", dataIndex: "dim", width: 100 },
|
||||
{ title: "审核重点", dataIndex: "focus", width: 160 },
|
||||
{
|
||||
title: "结论", dataIndex: "result", width: 120,
|
||||
render: (val, _, idx) => (
|
||||
<Select value={val} size="small" style={{ width: 100 }} onChange={(v) => updateRow(idx, "result", v)}>
|
||||
<Select.Option value="符合">符合</Select.Option>
|
||||
<Select.Option value="需修改">需修改</Select.Option>
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "审核意见", dataIndex: "opinion", width: 180,
|
||||
render: (val, _, idx) => (
|
||||
<Input size="small" value={val} onChange={(e) => updateRow(idx, "opinion", e.target.value)} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "修改反馈", dataIndex: "feedback", width: 120,
|
||||
render: (val, record) => {
|
||||
if (record.feedbackType === "success") return <Tag color="success">已验证</Tag>;
|
||||
if (record.feedbackType === "warning") return <Tag color="warning">待反馈</Tag>;
|
||||
return <span style={{ color: "#999" }}>—</span>;
|
||||
},
|
||||
},
|
||||
]}
|
||||
rowKey="dim"
|
||||
pagination={false}
|
||||
size="small"
|
||||
<Table
|
||||
dataSource={rows}
|
||||
columns={columns}
|
||||
rowKey="_key"
|
||||
pagination={false}
|
||||
loading={internalReviewDetailLoading}
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<div style={{ marginTop: 12 }}>
|
||||
<Typography.Text strong>总体审核意见</Typography.Text>
|
||||
<TextArea
|
||||
rows={2}
|
||||
value={overallOpinion}
|
||||
onChange={(e) => setOverallOpinion(e.target.value)}
|
||||
style={{ marginTop: 4 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 12 }}>
|
||||
<Typography.Text strong>总体审核意见</Typography.Text>
|
||||
<TextArea rows={2} defaultValue="完成危险辨识修改后通过内部审核。" style={{ marginTop: 4 }} />
|
||||
</div>
|
||||
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 10 }}>
|
||||
<Flex gap={8} align="center">
|
||||
<Typography.Text type="secondary">内审人独立签字</Typography.Text>
|
||||
<strong>王丽萍</strong>
|
||||
<Button size="small">下发APP签字</Button>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 10 }}>
|
||||
<Flex gap={8} align="center">
|
||||
<Typography.Text type="secondary">内审人独立签字</Typography.Text>
|
||||
<strong>{reviewerName}</strong>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={handleAssign}
|
||||
loading={internalReviewAssignLoading}
|
||||
disabled={isDispatched}
|
||||
>
|
||||
{isDispatched ? "已下发APP签字" : "下发APP签字"}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Flex justify="flex-end" gap={8} style={{ marginTop: 16 }}>
|
||||
<Button>保存意见</Button>
|
||||
<Button type="primary">确认修改并提交技审</Button>
|
||||
</Flex>
|
||||
|
||||
<Flex justify="flex-end" gap={8} style={{ marginTop: 16 }}>
|
||||
<Button
|
||||
loading={props.safetyEvalBusiness?.internalReviewConfirmLoading}
|
||||
onClick={() => handleConfirm("not_passed")}
|
||||
>
|
||||
保存意见
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => handleConfirm("passed")}
|
||||
loading={props.safetyEvalBusiness?.internalReviewConfirmLoading}
|
||||
>
|
||||
确认修改并提交技审
|
||||
</Button>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InternalReviewContent;
|
||||
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(InternalReviewContent);
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ const RiskAnalysisContent = (props) => {
|
|||
const values = await form.validateFields();
|
||||
|
||||
const { analysisDate, ...rest } = values;
|
||||
if (!rest.participants?.length) {
|
||||
message.warning("请选择风险分析人员");
|
||||
return;
|
||||
}
|
||||
const res = await evalRiskAnalysisSave({
|
||||
...rest,
|
||||
projectId,
|
||||
|
|
|
|||
|
|
@ -74,6 +74,14 @@ const TeamContent = (props) => {
|
|||
if (selectedPersons.length === 0) { message.warning("请至少选择1名人员"); return; }
|
||||
const role = ROLE_DEFINITIONS.find((r) => r.value === selectedRole);
|
||||
if (role?.unique && selectedPersons.length > 1) { message.warning("该角色为单人唯一角色,只能选择1名人员"); return; }
|
||||
// 唯一角色校验:检查是否已有人担任该角色
|
||||
if (role?.unique) {
|
||||
const existing = teamMembers.some((m) => m.roles.some((r) => r.role === selectedRole));
|
||||
if (existing) {
|
||||
message.warning(`"${role.name}"已配置,不可重复添加`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const newEntries = selectedPersons.map((personId) => {
|
||||
const p = participants.find((item) => item.id === personId);
|
||||
|
|
@ -110,6 +118,15 @@ const TeamContent = (props) => {
|
|||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
const allRoles = teamMembers.flatMap((m) => m.roles.map((r) => r.role));
|
||||
if (!allRoles.includes("PROJECT_LEAD")) {
|
||||
message.warning("请先配置项目负责人(项目组组长)");
|
||||
return;
|
||||
}
|
||||
if (!allRoles.includes("PROCESS_CONTROL_LEAD")) {
|
||||
message.warning("请先配置过程控制负责人");
|
||||
return;
|
||||
}
|
||||
const payload = teamMembers.map((m) => ({
|
||||
id: m.id,
|
||||
projectId,
|
||||
|
|
@ -124,6 +141,7 @@ const TeamContent = (props) => {
|
|||
if (res?.success !== false) {
|
||||
message.success("保存成功");
|
||||
fetchData();
|
||||
props.getDetail();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -134,10 +152,16 @@ const TeamContent = (props) => {
|
|||
{ title: "部门/岗位", dataIndex: "deptName", width: 200, ellipsis: true },
|
||||
{
|
||||
title: "项目角色", dataIndex: "roles", width: 350,
|
||||
render: (roles) => (
|
||||
render: (roles, record) => (
|
||||
<div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
|
||||
{roles.map((r) => (
|
||||
<Tag key={r.role} color="blue">
|
||||
<Tag key={r.role} color="blue" closable onClose={() => {
|
||||
setTeamMembers((prev) => prev.map((m) => {
|
||||
if (m.personnelId !== record.personnelId) return m;
|
||||
const updated = m.roles.filter((role) => role.role !== r.role);
|
||||
return updated.length > 0 ? { ...m, roles: updated } : null;
|
||||
}).filter(Boolean));
|
||||
}}>
|
||||
{ROLE_DEFINITIONS.find((d) => d.value === r.role)?.name || r.role}
|
||||
</Tag>
|
||||
))}
|
||||
|
|
@ -216,7 +240,7 @@ const TeamContent = (props) => {
|
|||
<Flex justify="flex-end" gap={8} className="pf-bottom-actions">
|
||||
|
||||
<Button>生成项目组任命文件</Button>
|
||||
<Button type="primary" onClick={handleSave}>确认项目组</Button>
|
||||
<Button type="primary" loading={memberSaveLoading} onClick={handleSave}>确认项目组</Button>
|
||||
</Flex>
|
||||
|
||||
<Modal title="添加项目人员与角色" open={modalOpen} onCancel={() => setModalOpen(false)} width={700}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,46 @@
|
|||
import React, { useState } from "react";
|
||||
import { Tag, Button, Card, Row, Col, Table, Select, Input, Flex, Typography } from "antd";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Tag, Button, Card, Row, Col, Table, Select, Input, Flex, Typography, message } from "antd";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
|
||||
const { TextArea } = Input;
|
||||
const { router } = tools;
|
||||
|
||||
const INITIAL_ROWS = [
|
||||
{ dim: "资料有效性", focus: "现场资料和检测报告齐全有效", result: "符合", opinion: "资料有效" },
|
||||
{ dim: "危险辨识", focus: "辨识充分、规律准确", result: "符合", opinion: "辨识充分" },
|
||||
{ dim: "评价方法", focus: "选型合理、计算正确", result: "需修改", opinion: "补充事故模拟参数来源" },
|
||||
{ dim: "对策措施", focus: "针对性和可行性", result: "符合", opinion: "措施可行" },
|
||||
{ dim: "评价结论", focus: "结论正确、反映风险", result: "符合", opinion: "结论正确" },
|
||||
const CONCLUSION_OPTIONS = [
|
||||
{ value: "conform_to", label: "符合" },
|
||||
{ value: "not_conform_to", label: "需修改" },
|
||||
];
|
||||
|
||||
const TechnicalReviewContent = () => {
|
||||
const [rows, setRows] = useState(INITIAL_ROWS);
|
||||
const TechnicalReviewContent = (props) => {
|
||||
const projectId = router.query?.id;
|
||||
const { techReviewDetail } = props.safetyEvalBusiness || {};
|
||||
const { techReview, reviewers, reviewItems } = techReviewDetail || {};
|
||||
|
||||
const [rows, setRows] = useState([]);
|
||||
const [overallOpinion, setOverallOpinion] = useState("");
|
||||
|
||||
const fetchDetail = () => {
|
||||
props.evalTechReviewDetail({ projectId });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (projectId) fetchDetail();
|
||||
}, [projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (reviewItems) {
|
||||
setRows(
|
||||
reviewItems.map((item) => ({
|
||||
...item,
|
||||
_key: item.id || item.reviewDimensionCode,
|
||||
})),
|
||||
);
|
||||
}
|
||||
if (techReview?.opinionContent) {
|
||||
setOverallOpinion(techReview.opinionContent);
|
||||
}
|
||||
}, [techReviewDetail]);
|
||||
|
||||
const updateRow = (index, field, value) => {
|
||||
const next = [...rows];
|
||||
|
|
@ -20,68 +48,166 @@ const TechnicalReviewContent = () => {
|
|||
setRows(next);
|
||||
};
|
||||
|
||||
const reviewerName = techReview?.reviewerName || "";
|
||||
const isDispatched = techReview?.reviewerSignatureTaskStatus !== "non_dispatched";
|
||||
const staffMatch = techReview?.staffMatchCode === 1 ? "满足" : "不满足";
|
||||
const inBizScope = techReview?.inBizScopeFlag === 1 ? "在范围内" : "不在范围内";
|
||||
|
||||
const handleAssign = async () => {
|
||||
if (!projectId) return;
|
||||
const res = await props.evalTechReviewAssign({ projectId });
|
||||
if (res?.success !== false) {
|
||||
message.success("已下发签字任务");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = async (resultCode) => {
|
||||
if (!projectId) return;
|
||||
const payload = {
|
||||
id: techReview?.id,
|
||||
projectId,
|
||||
resultCode,
|
||||
opinionContent: overallOpinion,
|
||||
reviewItems: rows.map((r) => ({
|
||||
bizType: "eval_tech_review",
|
||||
bizId: techReview?.id,
|
||||
reviewDimensionCode: r.reviewDimensionCode,
|
||||
reviewDimensionName: r.reviewDimensionName,
|
||||
reviewFocus: r.reviewFocus,
|
||||
reviewConclusion: r.reviewConclusion,
|
||||
reviewOpinion: r.reviewOpinion,
|
||||
})),
|
||||
};
|
||||
const res = await props.evalTechReviewConfirm(payload);
|
||||
if (res?.success !== false) {
|
||||
message.success(resultCode === "1" ? "已确认技审并提交过程控制" : "已保存");
|
||||
fetchDetail();
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: "审核维度", dataIndex: "reviewDimensionName", width: 120 },
|
||||
{ title: "技术审核重点", dataIndex: "reviewFocus", width: 200 },
|
||||
{
|
||||
title: "结论",
|
||||
dataIndex: "reviewConclusion",
|
||||
width: 120,
|
||||
render: (val, _, idx) => (
|
||||
<Select
|
||||
value={val}
|
||||
size="small"
|
||||
style={{ width: 100 }}
|
||||
onChange={(v) => updateRow(idx, "reviewConclusion", v)}
|
||||
>
|
||||
{CONCLUSION_OPTIONS.map((opt) => (
|
||||
<Select.Option key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "技术意见",
|
||||
dataIndex: "reviewOpinion",
|
||||
render: (val, _, idx) => (
|
||||
<Input
|
||||
size="small"
|
||||
placeholder="请输入技术意见"
|
||||
maxLength={80}
|
||||
value={val}
|
||||
onChange={(e) => updateRow(idx, "reviewOpinion", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="pf-permission">
|
||||
<Tag color="blue" className="pf-tag">技术负责人</Tag>
|
||||
<Tag color="blue" className="pf-tag">
|
||||
技术负责人
|
||||
</Tag>
|
||||
<span className="pf-desc">技术负责人独立审核技术路线和结论</span>
|
||||
</div>
|
||||
|
||||
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">审核版本</Typography.Text><div><strong>V1.4</strong></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">技术负责人</Typography.Text><div><strong>陈志强</strong></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">专业匹配</Typography.Text><div><Typography.Text strong type="success">化工安全</Typography.Text></div></Card></Col>
|
||||
<Col span={6}><Card size="small"><Typography.Text type="secondary">备案校验</Typography.Text><div><Typography.Text strong type="success">有效</Typography.Text></div></Card></Col>
|
||||
</Row>
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">技术负责人</Typography.Text>
|
||||
<div>
|
||||
<strong>{reviewerName || "-"}</strong>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">专业匹配</Typography.Text>
|
||||
<div>
|
||||
<Typography.Text strong type={techReview?.staffMatchCode === 1 ? "success" : "warning"}>
|
||||
{staffMatch}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Card size="small">
|
||||
<Typography.Text type="secondary">资质范围</Typography.Text>
|
||||
<div>
|
||||
<Typography.Text strong type={techReview?.inBizScopeFlag === 1 ? "success" : "warning"}>
|
||||
{inBizScope}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
dataSource={rows}
|
||||
columns={[
|
||||
{ title: "审核维度", dataIndex: "dim", width: 120 },
|
||||
{ title: "技术审核重点", dataIndex: "focus", width: 200 },
|
||||
{
|
||||
title: "结论", dataIndex: "result", width: 120,
|
||||
render: (val, _, idx) => (
|
||||
<Select value={val} size="small" style={{ width: 100 }} onChange={(v) => updateRow(idx, "result", v)}>
|
||||
<Select.Option value="符合">符合</Select.Option>
|
||||
<Select.Option value="需修改">需修改</Select.Option>
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "技术意见", dataIndex: "opinion",
|
||||
render: (val, _, idx) => (
|
||||
<Input size="small" value={val} onChange={(e) => updateRow(idx, "opinion", e.target.value)} />
|
||||
),
|
||||
},
|
||||
]}
|
||||
rowKey="dim"
|
||||
pagination={false}
|
||||
size="small"
|
||||
<Table
|
||||
dataSource={rows}
|
||||
columns={columns}
|
||||
rowKey="_key"
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
|
||||
<div style={{ marginTop: 12 }}>
|
||||
<Typography.Text strong>技术审核意见</Typography.Text>
|
||||
<TextArea
|
||||
rows={2}
|
||||
value={overallOpinion}
|
||||
onChange={(e) => setOverallOpinion(e.target.value)}
|
||||
style={{ marginTop: 4 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 12 }}>
|
||||
<Typography.Text strong>技术审核意见</Typography.Text>
|
||||
<TextArea rows={2} defaultValue="补充定量评价参数来源后通过技术审核。" style={{ marginTop: 4 }} />
|
||||
</div>
|
||||
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 10 }}>
|
||||
<Flex gap={8} align="center">
|
||||
<Typography.Text type="secondary">技术负责人签字</Typography.Text>
|
||||
<strong>陈志强</strong>
|
||||
<Button size="small">下发APP签字</Button>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center" style={{ marginTop: 10 }}>
|
||||
<Flex gap={8} align="center">
|
||||
<Typography.Text type="secondary">技术负责人签字</Typography.Text>
|
||||
<strong>{reviewerName}</strong>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={handleAssign}
|
||||
loading={props.safetyEvalBusiness?.techReviewAssignLoading}
|
||||
disabled={isDispatched}
|
||||
>
|
||||
{isDispatched ? "已下发APP签字" : "下发APP签字"}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Flex justify="flex-end" gap={8} style={{ marginTop: 16 }}>
|
||||
<Button>保存意见</Button>
|
||||
<Button>查看修改反馈</Button>
|
||||
<Button type="primary">确认技审并提交过程控制</Button>
|
||||
</Flex>
|
||||
|
||||
<Flex justify="flex-end" gap={8} style={{ marginTop: 16 }}>
|
||||
<Button onClick={() => handleConfirm("2")}>保存意见</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => handleConfirm("1")}
|
||||
loading={props.safetyEvalBusiness?.techReviewConfirmLoading}
|
||||
>
|
||||
确认技审并提交过程控制
|
||||
</Button>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TechnicalReviewContent;
|
||||
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(TechnicalReviewContent);
|
||||
Loading…
Reference in New Issue