dev_1.2
tangjie 2026-07-27 14:10:33 +08:00
parent 93a6c55b10
commit 12b5d7b7a6
7 changed files with 762 additions and 267 deletions

View File

@ -12,8 +12,8 @@ module.exports = {
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
//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
},

View File

@ -196,7 +196,7 @@ const menuItems = [
icon: <BarChartOutlined />,
},
{
key: "/safetyEval/container/MonitorManage/EvalProjectMonitor",
key: "/safetyEval/container/MonitorManage/EvalProjectMonitor/List",
label: "安评项目实时监控",
icon: <FileTextOutlined />,
},

View File

@ -0,0 +1,430 @@
import React, { useState, useEffect } from "react";
import {
Tabs,
Descriptions,
Table,
Tag,
Card,
Spin,
Empty,
Typography,
} 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 { EVAL_TYPE_MAP, ROLE_DEFINITIONS_MAP } from "~/enumerate/constant";
import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions";
import "./index.less";
const { router } = tools;
const PROJECT_TYPE_MAP = {
NEW: "新建项目",
RENEW: "续评项目",
CHANGE: "变更项目",
};
const YES_NO_MAP = { 1: "是", 2: "否" };
const ATTACH_TYPE_LABELS = {
PRACTICE_NOTIFICATION: "从业告知书",
SITE_INSPECTION_FORM: "现场安全检查表",
RECTIFICATION_NOTICE: "整改通知单",
ENTERPRISE_RECTIFICATION: "企业整改报告",
RECTIFICATION_REVIEW: "整改复查单",
};
/** 解析 JSON 格式的文件列表 */
const parseFileList = (raw) => {
if (!raw) return [];
try {
const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
};
// ===== 合同面板 =====
const ContractPanel = ({ data, loading }) => {
if (!data?.id) return <Spin><Empty description="暂无合同数据" /></Spin>;
const scanFiles = parseFileList(data?.scanFileUrl);
return (
<div className="epm-detail-panel">
<Descriptions title="合同基本信息" bordered column={2} size="small">
<Descriptions.Item label="合同编号">
{data.contractNo || "-"}
</Descriptions.Item>
<Descriptions.Item label="合同金额(万元)">
{data.amount ?? "-"}
</Descriptions.Item>
<Descriptions.Item label="合同期限">
{data.contractStartDate || "-"} ~ {data.contractEndDate || "-"}
</Descriptions.Item>
<Descriptions.Item label="评价类型">
{EVAL_TYPE_MAP[data.evalTypeCode] || data.evalTypeCode || "-"}
</Descriptions.Item>
<Descriptions.Item label="项目名称" span={2}>
{data.projectName || "-"}
</Descriptions.Item>
<Descriptions.Item label="项目类型">
{PROJECT_TYPE_MAP[data.projectTypeCode] ||
data.projectTypeCode ||
"-"}
</Descriptions.Item>
<Descriptions.Item label="项目业务范围">
{data.businessScope || "-"}
</Descriptions.Item>
<Descriptions.Item label="项目详细地址" span={2}>
{data.projectAddress || "-"}
</Descriptions.Item>
<Descriptions.Item label="项目简介" span={2}>
{data.projectIntro || "-"}
</Descriptions.Item>
</Descriptions>
<Descriptions
title="被评价企业信息"
bordered
column={2}
size="small"
className="epm-detail-section"
>
<Descriptions.Item label="企业名称">
{data.enterpriseName || "-"}
</Descriptions.Item>
<Descriptions.Item label="统一信用代码">
{data.creditCode || "-"}
</Descriptions.Item>
<Descriptions.Item label="法人代表">
{data.legalPerson || "-"}
</Descriptions.Item>
<Descriptions.Item label="联系人">
{data.contactName || "-"}
</Descriptions.Item>
<Descriptions.Item label="联系电话">
{data.contactPhone || "-"}
</Descriptions.Item>
<Descriptions.Item label="办公地址">
{data.officeAddress || "-"}
</Descriptions.Item>
</Descriptions>
{scanFiles.length > 0 && (
<Card
type="inner"
size="small"
title="合同扫描件"
className="epm-detail-section"
>
{scanFiles.map((file, idx) => (
<Typography.Link
key={file.uid || idx}
href={file.url}
target="_blank"
className="epm-detail-file"
>
{file.name || `附件${idx + 1}`}
</Typography.Link>
))}
</Card>
)}
</div>
);
};
// ===== 项目组人员面板 =====
const TeamPanel = ({ data, loading }) => {
if (!data || data.length === 0)
return <Empty description="暂无项目组人员数据" />;
const columns = [
{ title: "姓名", dataIndex: "personnelName", width: 100 },
{ title: "部门/岗位", dataIndex: "deptName", width: 160, ellipsis: true },
{
title: "项目角色",
dataIndex: "role",
width: 200,
render: (roles) =>
(Array.isArray(roles) ? roles : [roles])
.map((r) => ROLE_DEFINITIONS_MAP[r] || r)
.join("、"),
},
{
title: "资质与专业",
dataIndex: "capacity",
width: 200,
ellipsis: true,
},
{
title: "主要职责",
dataIndex: "responsibility",
ellipsis: true,
},
];
return (
<Table
dataSource={data}
columns={columns}
rowKey="personnelId"
pagination={false}
size="small"
scroll={{ x: 800 }}
/>
);
};
// ===== 踏勘情况面板 =====
const SurveyPanel = ({ personnel, attachments, loading, detailData }) => {
if (loading) return <Empty />;
const personnelColumns = [
{ title: "人员", dataIndex: "personnelName", width: 100 },
{
title: "项目角色",
dataIndex: "role",
width: 160,
ellipsis: true,
render: (v) =>
Array.isArray(v)
? v.map((r) => ROLE_DEFINITIONS_MAP[r] || r).join("、")
: v || "-",
},
{
title: "人脸识别",
dataIndex: "faceState",
width: 90,
render: (v) => (
<Tag color={v === 1 ? "success" : "error"}>
{v === 1 ? "通过" : "未通过"}
</Tag>
),
},
{
title: "GPS定位",
dataIndex: "gpsState",
width: 90,
render: (v) => (
<Tag color={v === 1 ? "success" : "error"}>
{v === 1 ? "正常" : "异常"}
</Tag>
),
},
{ title: "签到时间", dataIndex: "singInTime", width: 140 },
{ title: "签退时间", dataIndex: "signOutTime", width: 140 },
{
title: "现场照片",
dataIndex: "sceneUrl",
width: 80,
render: (v) => {
const count = v ? v.split(",").filter(Boolean).length : 0;
return count > 0 ? `${count}` : "-";
},
},
{
title: "本人签字",
dataIndex: "signatureUrl",
width: 90,
render: (v) => (
<Tag color={v ? "success" : "default"}>{v ? "已签字" : "未签字"}</Tag>
),
},
];
return (
<div className="epm-detail-panel">
{detailData && (
<div className="epm-detail-info-bar">
<span>打卡企业地址{detailData?.customerAddress || "-"}</span>
<span>
允许打卡范围企业地址周边
{detailData?.checkinRadiusMeters || "-"}
</span>
</div>
)}
<Card type="inner" size="small" title="人员现场打卡情况">
{personnel && personnel.length > 0 ? (
<Table
dataSource={personnel}
columns={personnelColumns}
rowKey="id"
pagination={false}
size="small"
scroll={{ x: 900 }}
/>
) : (
<Empty description="暂无打卡记录" />
)}
</Card>
{Object.keys(ATTACH_TYPE_LABELS).map((typeCode) => {
const files = parseFileList(attachments[typeCode]);
if (files.length === 0) return null;
return (
<Card
key={typeCode}
type="inner"
size="small"
title={ATTACH_TYPE_LABELS[typeCode]}
className="epm-detail-section"
>
{files.map((file, idx) => (
<Typography.Link
key={file.uid || idx}
href={file.url}
target="_blank"
className="epm-detail-file"
>
{file.name || `附件${idx + 1}`}
</Typography.Link>
))}
</Card>
);
})}
</div>
);
};
// ===== 主页面 =====
const EvalProjectMonitorDetail = (props) => {
const projectId = router.query?.id;
const {
safetyEvalBusiness,
evalContractGet,
evalProjectMemberPage,
evalSurveyList,
evalSurveyPage,
evalProjectDetail,
} = props;
const {
contractLoading,
memberLoading,
evalSurveyListLoading,
evalSurveyPageLoading,
evalProjectDetailData,
} = safetyEvalBusiness || {};
const [contractData, setContractData] = useState(null);
const [teamMembers, setTeamMembers] = useState([]);
const [surveyPersonnel, setSurveyPersonnel] = useState([]);
const [surveyAttachments, setSurveyAttachments] = useState({});
const [activeKey, setActiveKey] = useState("contract");
const fetchContract = async () => {
if (!projectId) return;
const res = await evalContractGet({ projectId });
if (res?.success !== false && res?.data) {
setContractData(res.data);
}
};
const fetchTeam = async () => {
if (!projectId) return;
const res = await evalProjectMemberPage({ projectId });
if (res?.success !== false && res?.data) {
setTeamMembers(res.data);
}
};
const fetchSurvey = async () => {
if (!projectId) return;
const [listRes, pageRes] = await Promise.all([
evalSurveyList({ projectId }),
evalSurveyPage({ projectId, size: 100 }),
]);
if (listRes?.success !== false) {
const map = {};
(listRes?.data || []).forEach((item) => {
map[item.attachTypeCode] = item.fileUrl;
});
setSurveyAttachments(map);
}
if (pageRes?.success !== false) {
setSurveyPersonnel(pageRes?.data || []);
}
};
useEffect(() => {
if (projectId) {
evalProjectDetail({ id: projectId });
}
fetchContract();
fetchTeam();
fetchSurvey();
}, []);
const projectInfo = (
<div className="epm-detail-band">
<div className="epm-detail-band-item">
<span>项目名称</span>
<strong>
{evalProjectDetailData?.projectName ||
contractData?.projectName ||
"-"}
</strong>
</div>
<div className="epm-detail-band-item">
<span>项目编号</span>
<strong>{evalProjectDetailData?.projectNo || "-"}</strong>
</div>
<div className="epm-detail-band-item">
<span>评价机构</span>
<strong>
{contractData?.orgName || evalProjectDetailData?.orgName || "-"}
</strong>
</div>
<div className="epm-detail-band-item">
<span>项目负责人</span>
<strong>{evalProjectDetailData?.leaderName || "-"}</strong>
</div>
</div>
);
return (
<PageLayout history={props.history} previous title="安评项目监管详情">
{projectInfo}
<Tabs
activeKey={activeKey}
onChange={setActiveKey}
items={[
{
key: "contract",
label: "项目合同",
children: (
<ContractPanel data={contractData} loading={contractLoading} />
),
},
{
key: "team",
label: "项目组人员",
children: <TeamPanel data={teamMembers} loading={memberLoading} />,
},
{
key: "survey",
label: "踏勘情况",
children: (
<SurveyPanel
personnel={surveyPersonnel}
attachments={surveyAttachments}
loading={evalSurveyListLoading || evalSurveyPageLoading}
detailData={safetyEvalBusiness?.evalProjectDetailData}
/>
),
},
]}
/>
</PageLayout>
);
};
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(AntdTableFuncControl(EvalProjectMonitorDetail));

View File

@ -0,0 +1,45 @@
.epm-detail-band {
display: flex;
gap: 32px;
padding: 12px 16px;
background: #fafafa;
border-radius: 6px;
margin-bottom: 16px;
border: 1px solid #f0f0f0;
.epm-detail-band-item {
display: flex;
flex-direction: column;
gap: 4px;
span {
font-size: 12px;
color: #8c8c8c;
}
strong {
font-size: 14px;
color: #262626;
}
}
}
.epm-detail-panel {
.epm-detail-section {
margin-top: 16px;
}
.epm-detail-info-bar {
display: flex;
gap: 24px;
margin-bottom: 12px;
font-size: 13px;
color: #6b7280;
}
.epm-detail-file {
display: inline-block;
margin-right: 12px;
margin-bottom: 4px;
}
}

View File

@ -0,0 +1,279 @@
import React, { useState, useEffect } from "react";
import {
Row,
Col,
Card,
Statistic,
Table,
Tag,
Button,
Form,
Space,
Tooltip,
} from "antd";
import dayjs from "dayjs";
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 { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import {
EVAL_TYPE_OPTIONS,
EVAL_TYPE_MAP,
MONITOR_WARING_STATUS_OPTIONS,
} from "~/enumerate/constant";
import {
QUALIFICATION_INDUSTRY_OPTIONS,
QUALIFICATION_INDUSTRY_OPTIONS_MAP,
} from "~/enumerate/enterpriseOptions";
import "./index.less";
const { router } = tools;
const STAT_ITEMS = [
{ key: "monitoringCount", title: "在监项目", color: "#1677ff" },
{ key: "normalCount", title: "正常执行", color: "#52c41a" },
{ key: "warningCount", title: "进度/人员预警", color: "#faad14" },
{ key: "monthPlanCompleteCount", title: "本月计划完成", color: "#722ed1" },
];
const EvalProjectMonitor = (props) => {
const [searchForm] = Form.useForm();
const [dataSource, setDataSource] = useState([]);
const [total, setTotal] = useState(0);
const { safetyEvalBusiness, evalProjectMonitorStat, evalProjectMonitorPage } =
props;
const { evalProjectMonitorStatLoading, evalProjectMonitorPageLoading } =
safetyEvalBusiness || {};
const statData = safetyEvalBusiness?.evalProjectMonitorStat || {};
const getStat = async () => {
evalProjectMonitorStat();
};
const getData = async () => {
const params = {
...router.query,
current: router.query.current || 1,
size: router.query.size || 10,
};
const res = await evalProjectMonitorPage(params);
if (res?.success !== false) {
setDataSource(res?.data || []);
setTotal(res?.total || 0);
}
};
useEffect(() => {
searchForm.setFieldsValue({
...router.query,
planEndDateRange:
router.query.planEndDateStart && router.query.planEndDateEnd
? [
dayjs(router.query.planEndDateStart),
dayjs(router.query.planEndDateEnd),
]
: undefined,
});
getStat();
getData();
}, []);
const handleSearch = (values) => {
const { planEndDateRange, ...rest } = values;
router.query = {
...rest,
planEndDateStart:
planEndDateRange?.[0]?.format?.("YYYY-MM-DD") || undefined,
planEndDateEnd:
planEndDateRange?.[1]?.format?.("YYYY-MM-DD") || undefined,
current: 1,
size: 10,
};
getData();
};
const handleReset = (values) => {
searchForm.resetFields();
values.planEndDateStart = undefined;
values.planEndDateEnd = undefined;
router.query = { ...values, current: 1, size: 10 };
getData();
};
const handlePageChange = (pagination) => {
router.query = {
...router.query,
current: pagination.current,
size: pagination.pageSize,
};
getData();
};
const renderWaringStatus = (_, record) => {
if (record.waringStatus === "NORMAL") {
return <Tag color="success">正常</Tag>;
}
const tags = [];
if (record.processWaringMsg) {
tags.push(
<Tooltip key="process" title={record.processWaringMsg}>
<Tag color="warning">进度预警</Tag>
</Tooltip>,
);
}
if (record.personnelWaringMsg) {
tags.push(
<Tooltip key="personnel" title={record.personnelWaringMsg}>
<Tag color="error">人员异常</Tag>
</Tooltip>,
);
}
return <Space size={4}>{tags}</Space>;
};
const columns = [
{ title: "项目编号", dataIndex: "projectNo", width: 140 },
{ title: "项目名称", dataIndex: "projectName", ellipsis: true, width: 220 },
{ title: "评价机构", dataIndex: "orgName", ellipsis: true, width: 200 },
{
title: "评价类型",
dataIndex: "evalTypeCode",
width: 120,
render: (code) => EVAL_TYPE_MAP[code] || code,
},
{
title: "行业",
dataIndex: "industryCode",
width: 140,
ellipsis: true,
render: (code) => QUALIFICATION_INDUSTRY_OPTIONS_MAP[code] || code,
},
{ title: "负责人", dataIndex: "leaderName", width: 90 },
{ title: "计划完成", dataIndex: "planEndDate", width: 120 },
{
title: "状态",
width: 100,
render: renderWaringStatus,
},
{
title: "操作",
width: 120,
fixed: "right",
render: (_, record) => (
<Button
type="link"
size="small"
onClick={() => {
props.history.push(
`Detail?id=${record.id}`,
);
}}
>
查看过程
</Button>
),
},
];
return (
<PageLayout title="安评项目实时监控">
<Row gutter={16} className="epm-stat-row">
{STAT_ITEMS.map((item) => (
<Col span={6} key={item.key}>
<Card size="small">
<Statistic
title={item.title}
value={statData[item.key] ?? "-"}
valueStyle={{ color: item.color }}
/>
</Card>
</Col>
))}
</Row>
<SearchForm
form={searchForm}
loading={false}
style={{ marginBottom: 16 }}
formLine={[
<Form.Item key="projectNameOrNo" name="projectNameOrNo">
<ControlWrapper.Input
label="项目名称/编号"
placeholder="请输入"
allowClear
/>
</Form.Item>,
<Form.Item key="evalTypeCode" name="evalTypeCode">
<ControlWrapper.Select
label="评价类型"
placeholder="全部"
allowClear
options={EVAL_TYPE_OPTIONS}
/>
</Form.Item>,
<Form.Item key="industryCode" name="industryCode">
<ControlWrapper.Select
label="行业类别"
placeholder="全部"
allowClear
options={QUALIFICATION_INDUSTRY_OPTIONS}
showSearch
optionFilterProp="label"
/>
</Form.Item>,
<Form.Item key="leaderName" name="leaderName">
<ControlWrapper.Input
label="项目负责人"
placeholder="请输入"
allowClear
/>
</Form.Item>,
<Form.Item key="waringStatus" name="waringStatus">
<ControlWrapper.Select
label="监管状态"
placeholder="全部"
allowClear
options={MONITOR_WARING_STATUS_OPTIONS}
/>
</Form.Item>,
<Form.Item key="planEndDateRange" name="planEndDateRange">
<ControlWrapper.DatePicker.RangePicker
label="计划完成时间"
style={{ width: "100%" }}
/>
</Form.Item>,
]}
onFinish={handleSearch}
onReset={handleReset}
/>
<Table
rowKey="id"
columns={columns}
dataSource={dataSource}
loading={evalProjectMonitorPageLoading}
scroll={{ y: props.scrollY, x: 1200 }}
pagination={{
total,
current: Number(router.query.current) || 1,
pageSize: Number(router.query.size) || 10,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (t) => `${t}`,
}}
onChange={handlePageChange}
/>
</PageLayout>
);
};
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(AntdTableFuncControl(EvalProjectMonitor));

View File

@ -1,271 +1,12 @@
import React, { useState, useEffect } from "react";
import {
Row,
Col,
Card,
Statistic,
Table,
Tag,
Form,
Space,
Tooltip,
} from "antd";
import dayjs from "dayjs";
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 { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import {
EVAL_TYPE_OPTIONS,
EVAL_TYPE_MAP,
MONITOR_WARING_STATUS_OPTIONS,
} from "~/enumerate/constant";
import {
QUALIFICATION_INDUSTRY_OPTIONS,
QUALIFICATION_INDUSTRY_OPTIONS_MAP,
} from "~/enumerate/enterpriseOptions";
import "./index.less";
const { router } = tools;
const STAT_ITEMS = [
{ key: "monitoringCount", title: "在监项目", color: "#1677ff" },
{ key: "normalCount", title: "正常执行", color: "#52c41a" },
{ key: "warningCount", title: "进度/人员预警", color: "#faad14" },
{ key: "monthPlanCompleteCount", title: "本月计划完成", color: "#722ed1" },
];
const EvalProjectMonitor = (props) => {
const [searchForm] = Form.useForm();
const [dataSource, setDataSource] = useState([]);
const [total, setTotal] = useState(0);
const { safetyEvalBusiness, evalProjectMonitorStat, evalProjectMonitorPage } =
props;
const { evalProjectMonitorStatLoading, evalProjectMonitorPageLoading } =
safetyEvalBusiness || {};
const statData = safetyEvalBusiness?.evalProjectMonitorStat || {};
const getStat = async () => {
evalProjectMonitorStat();
};
const getData = async () => {
const params = {
...router.query,
current: router.query.current || 1,
size: router.query.size || 10,
};
const res = await evalProjectMonitorPage(params);
if (res?.success !== false) {
setDataSource(res?.data || []);
setTotal(res?.total || 0);
}
};
useEffect(() => {
searchForm.setFieldsValue({
...router.query,
planEndDateRange:
router.query.planEndDateStart && router.query.planEndDateEnd
? [
dayjs(router.query.planEndDateStart),
dayjs(router.query.planEndDateEnd),
]
: undefined,
});
getStat();
getData();
}, []);
const handleSearch = (values) => {
const { planEndDateRange, ...rest } = values;
router.query = {
...rest,
planEndDateStart:
planEndDateRange?.[0]?.format?.("YYYY-MM-DD") || undefined,
planEndDateEnd:
planEndDateRange?.[1]?.format?.("YYYY-MM-DD") || undefined,
current: 1,
size: 10,
};
getData();
};
const handleReset = (values) => {
searchForm.resetFields();
values.planEndDateStart = undefined;
values.planEndDateEnd = undefined;
router.query = { ...values, current: 1, size: 10 };
getData();
};
const handlePageChange = (pagination) => {
router.query = {
...router.query,
current: pagination.current,
size: pagination.pageSize,
};
getData();
};
const renderWaringStatus = (_, record) => {
if (record.waringStatus === "NORMAL") {
return <Tag color="success">正常</Tag>;
}
const tags = [];
if (record.processWaringMsg) {
tags.push(
<Tooltip key="process" title={record.processWaringMsg}>
<Tag color="warning">进度预警</Tag>
</Tooltip>,
);
}
if (record.personnelWaringMsg) {
tags.push(
<Tooltip key="personnel" title={record.personnelWaringMsg}>
<Tag color="error">人员异常</Tag>
</Tooltip>,
);
}
return <Space size={4}>{tags}</Space>;
};
const columns = [
{ title: "项目编号", dataIndex: "projectNo", width: 140 },
{ title: "项目名称", dataIndex: "projectName", ellipsis: true, width: 220 },
{ title: "评价机构", dataIndex: "orgName", ellipsis: true, width: 200 },
{
title: "评价类型",
dataIndex: "evalTypeCode",
width: 120,
render: (code) => EVAL_TYPE_MAP[code] || code,
},
{
title: "行业",
dataIndex: "industryCode",
width: 140,
ellipsis: true,
render: (code) => QUALIFICATION_INDUSTRY_OPTIONS_MAP[code] || code,
},
{ title: "负责人", dataIndex: "leaderName", width: 90 },
{ title: "计划完成", dataIndex: "planEndDate", width: 120 },
{
title: "状态",
width: 100,
render: renderWaringStatus,
},
{
title: "操作",
width: 180,
fixed: "right",
render: (_, record) => (
<Space size={4}>
<Button type="primary" onClick={()=>{}}>
查看过程
</Button>
</Space>
),
}
];
import React from "react";
function MonitorManage(props) {
return (
<PageLayout title="安评项目实时监控">
<Row gutter={16} className="epm-stat-row">
{STAT_ITEMS.map((item) => (
<Col span={6} key={item.key}>
<Card size="small">
<Statistic
title={item.title}
value={statData[item.key] ?? "-"}
valueStyle={{ color: item.color }}
/>
</Card>
</Col>
))}
</Row>
<SearchForm
form={searchForm}
loading={false}
style={{ marginBottom: 16 }}
formLine={[
<Form.Item key="projectNameOrNo" name="projectNameOrNo">
<ControlWrapper.Input
label="项目名称/编号"
placeholder="请输入"
allowClear
/>
</Form.Item>,
<Form.Item key="evalTypeCode" name="evalTypeCode">
<ControlWrapper.Select
label="评价类型"
placeholder="全部"
allowClear
options={EVAL_TYPE_OPTIONS}
/>
</Form.Item>,
<Form.Item key="industryCode" name="industryCode">
<ControlWrapper.Select
label="行业类别"
placeholder="全部"
allowClear
options={QUALIFICATION_INDUSTRY_OPTIONS}
showSearch
optionFilterProp="label"
/>
</Form.Item>,
<Form.Item key="leaderName" name="leaderName">
<ControlWrapper.Input
label="项目负责人"
placeholder="请输入"
allowClear
/>
</Form.Item>,
<Form.Item key="waringStatus" name="waringStatus">
<ControlWrapper.Select
label="监管状态"
placeholder="全部"
allowClear
options={MONITOR_WARING_STATUS_OPTIONS}
/>
</Form.Item>,
<Form.Item key="planEndDateRange" name="planEndDateRange">
<ControlWrapper.DatePicker.RangePicker
label="计划完成时间"
style={{ width: "100%" }}
/>
</Form.Item>,
]}
onFinish={handleSearch}
onReset={handleReset}
/>
props.children
<Table
rowKey="id"
columns={columns}
dataSource={dataSource}
loading={evalProjectMonitorPageLoading}
scroll={{ y: props.scrollY, x: 1200 }}
pagination={{
total,
current: Number(router.query.current) || 1,
pageSize: Number(router.query.size) || 10,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (t) => `${t}`,
}}
onChange={handlePageChange}
/>
</PageLayout>
);
};
}
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(AntdTableFuncControl(EvalProjectMonitor));
export default MonitorManage;