2026-07-22 10:46:56 +08:00
|
|
|
import React, { useState, useEffect } from "react";
|
|
|
|
|
import {
|
|
|
|
|
Form,
|
|
|
|
|
Table,
|
|
|
|
|
Button,
|
|
|
|
|
Tag,
|
|
|
|
|
Modal,
|
|
|
|
|
Row,
|
|
|
|
|
Col,
|
|
|
|
|
Card,
|
|
|
|
|
Statistic,
|
|
|
|
|
Space,
|
|
|
|
|
message,
|
|
|
|
|
} from "antd";
|
|
|
|
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
|
|
|
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
|
|
|
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/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 { Connect } from "@cqsjjb/jjb-dva-runtime";
|
|
|
|
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
|
|
|
|
import "./index.less";
|
|
|
|
|
|
|
|
|
|
const { router } = tools;
|
|
|
|
|
|
|
|
|
|
const RiskWarning = (props) => {
|
|
|
|
|
const [searchForm] = Form.useForm();
|
|
|
|
|
const [dataSource, setDataSource] = useState([]);
|
|
|
|
|
const [total, setTotal] = useState(0);
|
|
|
|
|
const [statData, setStatData] = useState({});
|
2026-07-27 18:06:06 +08:00
|
|
|
|
2026-07-22 10:46:56 +08:00
|
|
|
|
|
|
|
|
const { riskWarningPageLoading } = props.safetyEvalBusiness;
|
|
|
|
|
|
|
|
|
|
const getStat = async () => {
|
|
|
|
|
const res = await props.evalProjectRiskWarningStat();
|
|
|
|
|
if (res?.success !== false) {
|
|
|
|
|
setStatData(res?.data || {});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getData = async () => {
|
|
|
|
|
const params = {
|
|
|
|
|
...router.query,
|
|
|
|
|
current: router.query.current || 1,
|
|
|
|
|
size: router.query.size || 10,
|
|
|
|
|
};
|
|
|
|
|
const res = await props.evalProjectRiskWarningPage(params);
|
|
|
|
|
if (res?.success !== false) {
|
|
|
|
|
setDataSource(res?.data || []);
|
|
|
|
|
setTotal(res?.total || 0);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
searchForm.setFieldsValue(router.query);
|
|
|
|
|
getStat();
|
|
|
|
|
getData();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleSearch = (values) => {
|
|
|
|
|
router.query = { ...router.query, ...values, current: 1, size: 10 };
|
|
|
|
|
getData();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleReset = (values) => {
|
|
|
|
|
searchForm.resetFields();
|
|
|
|
|
router.query = { ...values, current: 1, size: 10 };
|
|
|
|
|
getData();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handlePageChange = (pagination) => {
|
|
|
|
|
router.query = {
|
|
|
|
|
...router.query,
|
|
|
|
|
current: pagination.current,
|
|
|
|
|
size: pagination.pageSize,
|
|
|
|
|
};
|
|
|
|
|
getData();
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-28 16:45:46 +08:00
|
|
|
|
2026-07-22 10:46:56 +08:00
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
{ title: "项目编号", dataIndex: "projectNo", width: 130 },
|
|
|
|
|
{
|
|
|
|
|
title: "项目/客户",
|
|
|
|
|
width: 240,
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<div>
|
|
|
|
|
<div className="rw-project-name">{record.projectName}</div>
|
|
|
|
|
<div className="rw-customer-name">{record.customerName}</div>
|
|
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: "风险等级",
|
|
|
|
|
dataIndex: "riskLevelCode",
|
|
|
|
|
width: 100,
|
|
|
|
|
render: (code) => {
|
|
|
|
|
const cfg = RISK_LEVEL_MAP[code];
|
2026-07-23 17:41:28 +08:00
|
|
|
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : "";
|
2026-07-22 10:46:56 +08:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ title: "预警类型", dataIndex: "warningTypeName", width: 100 },
|
|
|
|
|
{
|
|
|
|
|
title: "触发条件",
|
|
|
|
|
dataIndex: "triggerCondition",
|
|
|
|
|
ellipsis: true,
|
|
|
|
|
width: 260,
|
|
|
|
|
},
|
|
|
|
|
{ title: "责任人", dataIndex: "responsiblePerson", width: 90 },
|
2026-07-23 17:41:28 +08:00
|
|
|
{ title: "预警时间", dataIndex: "warningTime", width: 120 },
|
2026-07-22 10:46:56 +08:00
|
|
|
{
|
|
|
|
|
title: "状态",
|
|
|
|
|
dataIndex: "statusCode",
|
|
|
|
|
width: 90,
|
|
|
|
|
render: (code) => {
|
|
|
|
|
const cfg = RISK_STATUS_MAP[code];
|
2026-07-23 17:41:28 +08:00
|
|
|
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : "";
|
2026-07-22 10:46:56 +08:00
|
|
|
},
|
|
|
|
|
},
|
2026-07-28 16:45:46 +08:00
|
|
|
|
2026-07-22 10:46:56 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<PageLayout title="风险预警管理">
|
|
|
|
|
<Row gutter={16} className="rw-stat-row">
|
|
|
|
|
<Col span={6}>
|
|
|
|
|
<Card size="small">
|
|
|
|
|
<Statistic
|
|
|
|
|
title="预警总数"
|
|
|
|
|
value={statData.totalCount ?? "-"}
|
|
|
|
|
suffix={<span className="rw-stat-suffix">来自项目过程控制与周期规则</span>}
|
|
|
|
|
/>
|
|
|
|
|
</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}>
|
|
|
|
|
<Card size="small">
|
|
|
|
|
<Statistic
|
|
|
|
|
title="本周新增"
|
|
|
|
|
value={statData.weekNewCount ?? "-"}
|
|
|
|
|
valueStyle={{ color: "#52c41a" }}
|
|
|
|
|
suffix={<span className="rw-stat-suffix">需在周例会确认</span>}
|
|
|
|
|
/>
|
|
|
|
|
</Card>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<SearchForm
|
|
|
|
|
form={searchForm}
|
|
|
|
|
loading={false}
|
|
|
|
|
style={{ marginBottom: 16 }}
|
|
|
|
|
formLine={[
|
|
|
|
|
<Form.Item key="projectOrCustomer" name="projectOrCustomer">
|
|
|
|
|
<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" },
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
</Form.Item>,
|
|
|
|
|
]}
|
|
|
|
|
onFinish={handleSearch}
|
|
|
|
|
onReset={handleReset}
|
|
|
|
|
/>
|
|
|
|
|
|
2026-07-23 17:41:28 +08:00
|
|
|
|
2026-07-22 10:46:56 +08:00
|
|
|
|
|
|
|
|
<Table
|
|
|
|
|
rowKey="id"
|
|
|
|
|
columns={columns}
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
loading={riskWarningPageLoading}
|
|
|
|
|
scroll={{ y: props.scrollY, x: 1300 }}
|
|
|
|
|
pagination={{
|
|
|
|
|
total,
|
|
|
|
|
current: router.query.current || 1,
|
|
|
|
|
pageSize: router.query.size || 10,
|
|
|
|
|
showSizeChanger: true,
|
|
|
|
|
showQuickJumper: true,
|
|
|
|
|
showTotal: (total) => `共 ${total} 条`,
|
|
|
|
|
}}
|
|
|
|
|
onChange={handlePageChange}
|
|
|
|
|
/>
|
|
|
|
|
|
2026-07-27 18:06:06 +08:00
|
|
|
|
2026-07-22 10:46:56 +08:00
|
|
|
</PageLayout>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default Connect(
|
|
|
|
|
[NS_SAFETY_EVAL_BUSINESS],
|
|
|
|
|
true,
|
|
|
|
|
)(AntdTableFuncControl(RiskWarning));
|