waring
parent
892d154b03
commit
bdec681206
|
|
@ -101,14 +101,21 @@ export const evalProjectProgressPage = declareRequest(
|
|||
"Get > /safetyEval/institution/eval-project/progress-page",
|
||||
);
|
||||
|
||||
export const evalProjectRiskWarningStat = declareRequest(
|
||||
// ===== 机构端-险预警 =====
|
||||
|
||||
export const evalProjectOrgWaringStat = declareRequest(
|
||||
"riskWarningStatLoading",
|
||||
"Get > /safetyEval/institution/eval-project/risk-warning-stat",
|
||||
"Get > /safetyEval/eval-project-org-waring/org/stat",
|
||||
);
|
||||
|
||||
export const evalProjectRiskWarningPage = declareRequest(
|
||||
export const evalProjectOrgWaringPage = declareRequest(
|
||||
"riskWarningPageLoading",
|
||||
"Get > /safetyEval/institution/eval-project/risk-warning-page",
|
||||
"Get > /safetyEval/eval-project-org-waring/list/org/waring/page",
|
||||
);
|
||||
|
||||
export const evalProjectOrgWaringHandle = declareRequest(
|
||||
"riskWarningHandleLoading",
|
||||
"Post > @/safetyEval/eval-project-org-waring/handle",
|
||||
);
|
||||
|
||||
export const evalRiskAnalysisGet = declareRequest(
|
||||
|
|
|
|||
|
|
@ -390,17 +390,26 @@ export const MATERIAL_TYPE_MAP = MATERIAL_TYPE_OPTIONS.reduce((acc, cur) => {
|
|||
return acc;
|
||||
}, {});
|
||||
|
||||
/** 风险预警 — 风险等级映射 */
|
||||
export const RISK_LEVEL_MAP = {
|
||||
HIGH: { color: "error", text: "高风险" },
|
||||
MIDDLE: { color: "warning", text: "中风险" },
|
||||
LOW: { color: "default", text: "低风险" },
|
||||
/** 机构端-险预警 — 预警类型映射 */
|
||||
export const ORG_WARNING_TYPE_MAP = {
|
||||
not_archived: { color: "warning", text: "未归档" },
|
||||
report_overdue: { color: "error", text: "报告超期" },
|
||||
CORPORATE_RECTIFICATION: { color: "processing", text: "企业整改" },
|
||||
MAJOR_HAZARD: { color: "error", text: "重大隐患" },
|
||||
};
|
||||
|
||||
/** 风险预警 — 处理状态映射 */
|
||||
export const RISK_STATUS_MAP = {
|
||||
UNHANDLED: { color: "error", text: "未处理" },
|
||||
PROCESSING: { color: "warning", text: "处理中" },
|
||||
/** 机构端-险预警 — 预警类型筛选选项 */
|
||||
export const ORG_WARNING_TYPE_OPTIONS = [
|
||||
{ label: "未归档", value: "not_archived" },
|
||||
{ label: "报告超期", value: "report_overdue" },
|
||||
{ label: "企业整改", value: "CORPORATE_RECTIFICATION" },
|
||||
{ label: "重大隐患", value: "MAJOR_HAZARD" },
|
||||
];
|
||||
|
||||
/** 机构端-险预警 — 处理状态映射 */
|
||||
export const ORG_WARNING_HANDLE_STATUS_MAP = {
|
||||
none: { color: "error", text: "未处理" },
|
||||
done: { color: "success", text: "已处理" },
|
||||
};
|
||||
|
||||
/** 项目进度 — 进度状态映射 */
|
||||
|
|
|
|||
|
|
@ -2,22 +2,29 @@ import React, { useState, useEffect } from "react";
|
|||
import {
|
||||
Form,
|
||||
Table,
|
||||
Button,
|
||||
Tag,
|
||||
Modal,
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
Statistic,
|
||||
Space,
|
||||
Button,
|
||||
Modal,
|
||||
Upload,
|
||||
Flex,
|
||||
Input,
|
||||
message,
|
||||
} from "antd";
|
||||
import { UploadOutlined } from "@ant-design/icons";
|
||||
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||
import SearchForm from "~/components/SearchForm";
|
||||
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import { RISK_LEVEL_MAP, RISK_STATUS_MAP } from "~/enumerate/constant";
|
||||
import {
|
||||
ORG_WARNING_TYPE_MAP,
|
||||
ORG_WARNING_TYPE_OPTIONS,
|
||||
ORG_WARNING_HANDLE_STATUS_MAP,
|
||||
} from "~/enumerate/constant";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
import "./index.less";
|
||||
|
|
@ -29,12 +36,18 @@ const RiskWarning = (props) => {
|
|||
const [dataSource, setDataSource] = useState([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [statData, setStatData] = useState({});
|
||||
const [handleModalOpen, setHandleModalOpen] = useState(false);
|
||||
const [currentRecord, setCurrentRecord] = useState(null);
|
||||
const [modalForm] = Form.useForm();
|
||||
const [uploading, setUploading] = useState(false);
|
||||
|
||||
|
||||
const { riskWarningPageLoading } = props.safetyEvalBusiness;
|
||||
const {
|
||||
riskWarningPageLoading,
|
||||
riskWarningHandleLoading,
|
||||
} = props.safetyEvalBusiness;
|
||||
|
||||
const getStat = async () => {
|
||||
const res = await props.evalProjectRiskWarningStat();
|
||||
const res = await props.evalProjectOrgWaringStat();
|
||||
if (res?.success !== false) {
|
||||
setStatData(res?.data || {});
|
||||
}
|
||||
|
|
@ -46,7 +59,7 @@ const RiskWarning = (props) => {
|
|||
current: router.query.current || 1,
|
||||
size: router.query.size || 10,
|
||||
};
|
||||
const res = await props.evalProjectRiskWarningPage(params);
|
||||
const res = await props.evalProjectOrgWaringPage(params);
|
||||
if (res?.success !== false) {
|
||||
setDataSource(res?.data || []);
|
||||
setTotal(res?.total || 0);
|
||||
|
|
@ -79,10 +92,8 @@ const RiskWarning = (props) => {
|
|||
getData();
|
||||
};
|
||||
|
||||
|
||||
|
||||
const columns = [
|
||||
{ title: "项目编号", dataIndex: "projectNo", width: 130 },
|
||||
{ title: "项目编号", dataIndex: "projectNo", width: 140 },
|
||||
{
|
||||
title: "项目/客户",
|
||||
width: 240,
|
||||
|
|
@ -94,39 +105,75 @@ const RiskWarning = (props) => {
|
|||
),
|
||||
},
|
||||
{
|
||||
title: "风险等级",
|
||||
dataIndex: "riskLevelCode",
|
||||
width: 100,
|
||||
title: "预警类型",
|
||||
dataIndex: "warningType",
|
||||
width: 110,
|
||||
render: (code) => {
|
||||
const cfg = RISK_LEVEL_MAP[code];
|
||||
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : "";
|
||||
const cfg = ORG_WARNING_TYPE_MAP[code];
|
||||
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : code || "";
|
||||
},
|
||||
},
|
||||
{ title: "预警类型", dataIndex: "warningTypeName", width: 100 },
|
||||
{
|
||||
title: "触发条件",
|
||||
dataIndex: "triggerCondition",
|
||||
ellipsis: true,
|
||||
width: 260,
|
||||
},
|
||||
{ title: "责任人", dataIndex: "responsiblePerson", width: 90 },
|
||||
{ title: "预警时间", dataIndex: "warningTime", width: 120 },
|
||||
{ title: "业务负责人", dataIndex: "projectLeaderName", width: 110 },
|
||||
{ title: "创建时间", dataIndex: "createTime", width: 170 },
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "statusCode",
|
||||
width: 90,
|
||||
title: "处理状态",
|
||||
dataIndex: "handleStatus",
|
||||
width: 100,
|
||||
render: (code) => {
|
||||
const cfg = RISK_STATUS_MAP[code];
|
||||
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : "";
|
||||
const cfg = ORG_WARNING_HANDLE_STATUS_MAP[code];
|
||||
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : code || "";
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "操作",
|
||||
width: 90,
|
||||
fixed: "right",
|
||||
render: (_, record) =>
|
||||
record.handleStatus === "none" ? (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setCurrentRecord(record);
|
||||
setHandleModalOpen(true);
|
||||
}}
|
||||
>
|
||||
处理
|
||||
</Button>
|
||||
) : null,
|
||||
},
|
||||
];
|
||||
|
||||
const handleModalOk = async () => {
|
||||
const values = await modalForm.validateFields();
|
||||
const res = await props.evalProjectOrgWaringHandle({
|
||||
id: currentRecord?.id,
|
||||
...values,
|
||||
});
|
||||
if (res?.success !== false) {
|
||||
message.success("处理成功");
|
||||
setHandleModalOpen(false);
|
||||
modalForm.resetFields();
|
||||
getStat();
|
||||
getData();
|
||||
}
|
||||
};
|
||||
|
||||
const handleModalCancel = () => {
|
||||
setHandleModalOpen(false);
|
||||
modalForm.resetFields();
|
||||
};
|
||||
|
||||
return (
|
||||
<PageLayout title="风险预警管理">
|
||||
<Row gutter={16} className="rw-stat-row">
|
||||
<Col span={6}>
|
||||
<Col span={12}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title="预警总数"
|
||||
|
|
@ -135,27 +182,7 @@ const RiskWarning = (props) => {
|
|||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title="高风险"
|
||||
value={statData.highRiskCount ?? "-"}
|
||||
valueStyle={{ color: "#ff4d4f" }}
|
||||
suffix={<span className="rw-stat-suffix">延期、逾期、重大整改</span>}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title="处理中"
|
||||
value={statData.processingCount ?? "-"}
|
||||
valueStyle={{ color: "#faad14" }}
|
||||
suffix={<span className="rw-stat-suffix">已分派但未闭环</span>}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Col span={12}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title="本周新增"
|
||||
|
|
@ -167,44 +194,24 @@ const RiskWarning = (props) => {
|
|||
</Col>
|
||||
</Row>
|
||||
|
||||
|
||||
|
||||
<SearchForm
|
||||
form={searchForm}
|
||||
loading={false}
|
||||
style={{ marginBottom: 16 }}
|
||||
formLine={[
|
||||
<Form.Item key="projectOrCustomer" name="projectOrCustomer">
|
||||
<Form.Item key="keyword" name="keyword">
|
||||
<ControlWrapper.Input
|
||||
label="项目/客户"
|
||||
placeholder="项目或客户名称"
|
||||
allowClear
|
||||
/>
|
||||
</Form.Item>,
|
||||
<Form.Item key="riskLevel" name="riskLevel">
|
||||
<ControlWrapper.Select
|
||||
label="风险等级"
|
||||
placeholder="全部"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "高风险", value: "HIGH" },
|
||||
{ label: "中风险", value: "MIDDLE" },
|
||||
{ label: "低风险", value: "LOW" },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>,
|
||||
<Form.Item key="warningType" name="warningType">
|
||||
<ControlWrapper.Select
|
||||
label="预警类型"
|
||||
placeholder="全部"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "进度风险", value: "PROGRESS" },
|
||||
{ label: "周期风险", value: "CYCLE" },
|
||||
{ label: "质量风险", value: "QUALITY" },
|
||||
{ label: "人员风险", value: "PERSONNEL" },
|
||||
{ label: "归档风险", value: "ARCHIVE" },
|
||||
]}
|
||||
options={ORG_WARNING_TYPE_OPTIONS}
|
||||
/>
|
||||
</Form.Item>,
|
||||
]}
|
||||
|
|
@ -212,14 +219,12 @@ const RiskWarning = (props) => {
|
|||
onReset={handleReset}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
loading={riskWarningPageLoading}
|
||||
scroll={{ y: props.scrollY, x: 1300 }}
|
||||
scroll={{ y: props.scrollY, x: 1130 }}
|
||||
pagination={{
|
||||
total,
|
||||
current: router.query.current || 1,
|
||||
|
|
@ -231,7 +236,49 @@ const RiskWarning = (props) => {
|
|||
onChange={handlePageChange}
|
||||
/>
|
||||
|
||||
|
||||
<Modal
|
||||
title="处理预警"
|
||||
open={handleModalOpen}
|
||||
onOk={handleModalOk}
|
||||
onCancel={handleModalCancel}
|
||||
confirmLoading={riskWarningHandleLoading}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form form={modalForm} layout="vertical">
|
||||
<Form.Item label="项目编号">
|
||||
<span className="rw-modal-project-no">
|
||||
{currentRecord?.projectNo}
|
||||
</span>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="证明材料"
|
||||
name="evidenceFileUrl"
|
||||
rules={[
|
||||
{ required: true, message: "请上传证明材料" },
|
||||
]}
|
||||
>
|
||||
<UploadButtonField
|
||||
uploading={uploading}
|
||||
setUploading={setUploading}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="备注处理说明"
|
||||
name="remarks"
|
||||
rules={[
|
||||
{ required: true, message: "请输入备注处理说明" },
|
||||
{ max: 255, message: "备注处理说明不能超过255个字符" },
|
||||
]}
|
||||
>
|
||||
<Input.TextArea
|
||||
placeholder="请输入处理说明"
|
||||
maxLength={255}
|
||||
showCount
|
||||
rows={4}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</PageLayout>
|
||||
);
|
||||
};
|
||||
|
|
@ -240,3 +287,46 @@ export default Connect(
|
|||
[NS_SAFETY_EVAL_BUSINESS],
|
||||
true,
|
||||
)(AntdTableFuncControl(RiskWarning));
|
||||
|
||||
/** 证明材料上传字段 - 上传后回填 url */
|
||||
const UploadButtonField = ({ value, onChange, uploading, setUploading }) => {
|
||||
const fileName =
|
||||
typeof value === "string" && value.includes("/")
|
||||
? value.split("/").pop()
|
||||
: value;
|
||||
|
||||
return (
|
||||
<Flex gap={8} align="center">
|
||||
{fileName && (
|
||||
<span className="rw-file-name" title={fileName}>
|
||||
{fileName}
|
||||
</span>
|
||||
)}
|
||||
<Upload
|
||||
showUploadList={false}
|
||||
action={`${window.process.env.app.API_HOST}/safetyEval/file/upload`}
|
||||
headers={{ token: sessionStorage.getItem("token") }}
|
||||
onChange={(info) => {
|
||||
if (info.file.status === "uploading") {
|
||||
setUploading(true);
|
||||
} else if (info.file.status === "done") {
|
||||
setUploading(false);
|
||||
const url = info.file.response?.data?.url;
|
||||
if (url) {
|
||||
onChange?.(url);
|
||||
} else {
|
||||
message.error("上传失败");
|
||||
}
|
||||
} else if (info.file.status === "error") {
|
||||
setUploading(false);
|
||||
message.error("上传失败");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button icon={<UploadOutlined />} loading={uploading} size="small">
|
||||
选择文件
|
||||
</Button>
|
||||
</Upload>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,4 +26,17 @@
|
|||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&-file-name {
|
||||
max-width: 160px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&-modal-project-no {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue