feat
parent
6156138a55
commit
c755e472bc
|
|
@ -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
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Modal, Button, Descriptions, Table, Tag } from "antd";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import {
|
||||
ENTERPRISE_STATUS_OPTIONS,
|
||||
ENTERPRISE_SCALE_OPTIONS,
|
||||
EVAL_TYPE_MAP,
|
||||
} from "~/enumerate/constant";
|
||||
import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions";
|
||||
|
||||
const CustomerDetailModal = ({ open, customerId, onCancel, ...props }) => {
|
||||
const [detail, setDetail] = useState(null);
|
||||
const { customerDetailLoading } = props.safetyEvalBusiness || {};
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || !customerId) {
|
||||
setDetail(null);
|
||||
return;
|
||||
}
|
||||
props.customerDetail({ id: customerId }).then((res) => {
|
||||
if (res?.success !== false) {
|
||||
setDetail(res?.data || null);
|
||||
}
|
||||
});
|
||||
}, [open, customerId]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={`客户详情 - ${detail?.customerName || ""}`}
|
||||
open={open}
|
||||
loading={customerDetailLoading}
|
||||
onCancel={onCancel}
|
||||
footer={<Button onClick={onCancel}>关闭</Button>}
|
||||
width={700}
|
||||
destroyOnHidden
|
||||
>
|
||||
{detail && (
|
||||
<>
|
||||
<Descriptions
|
||||
column={2}
|
||||
bordered
|
||||
size="small"
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
<Descriptions.Item label="客户名称">
|
||||
{detail.customerName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="统一社会信用代码">
|
||||
{detail.creditCode}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="企业状态">
|
||||
{(() => {
|
||||
const statusOption = ENTERPRISE_STATUS_OPTIONS.find(
|
||||
(opt) => opt.value === detail.enterpriseStatusCode,
|
||||
);
|
||||
return statusOption?.label || detail.enterpriseStatusName;
|
||||
})()}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="企业规模">
|
||||
{(() => {
|
||||
const scaleOption = ENTERPRISE_SCALE_OPTIONS.find(
|
||||
(opt) => opt.value === detail.enterpriseScaleCode,
|
||||
);
|
||||
return scaleOption?.label || detail.enterpriseScaleName;
|
||||
})()}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="所属行业">
|
||||
{detail.industryCode
|
||||
?.split(",")
|
||||
.map(
|
||||
(code) =>
|
||||
QUALIFICATION_INDUSTRY_OPTIONS_MAP[code.trim()] ||
|
||||
code.trim(),
|
||||
)
|
||||
.join("、")}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="属地">
|
||||
{detail.districtName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="联系人">
|
||||
{detail.principalName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="联系电话">
|
||||
{detail.principalPhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="主要负责人">
|
||||
{detail.principalName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人电话">
|
||||
{detail.principalPhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="法定代表人">
|
||||
{detail.legalRepresentative}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="法人电话">
|
||||
{detail.legalRepresentativePhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="经营地址" span={2}>
|
||||
{detail.businessAddress}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="经度">
|
||||
{detail.longitude}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="纬度">
|
||||
{detail.latitude}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
<h4 style={{ margin: "12px 0 8px" }}>安全评价项目列表</h4>
|
||||
<Table
|
||||
rowKey="id"
|
||||
dataSource={detail.projects || []}
|
||||
columns={[
|
||||
{ title: "项目名称", dataIndex: "projectName" },
|
||||
{
|
||||
title: "评价类型",
|
||||
dataIndex: "evalTypeCode",
|
||||
width: 120,
|
||||
render: (s) => EVAL_TYPE_MAP[s] || s || "",
|
||||
},
|
||||
{ title: "报告完成日期", dataIndex: "planEndDate", width: 130 },
|
||||
{
|
||||
title: "项目状态",
|
||||
dataIndex: "status",
|
||||
width: 100,
|
||||
fixed: "right",
|
||||
render: (phase, record) => {
|
||||
if (record.archiveFlag === 1) {
|
||||
return <Tag color="success">已归档</Tag>;
|
||||
}
|
||||
if (record.projectPhaseCode === "NORMAL") {
|
||||
return <Tag color="success">正常</Tag>;
|
||||
}
|
||||
if (record.projectPhaseCode === "DELAY") {
|
||||
return <Tag color="error">已延期</Tag>;
|
||||
}
|
||||
return record.projectPhaseName;
|
||||
},
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default Connect(
|
||||
[NS_SAFETY_EVAL_BUSINESS],
|
||||
true,
|
||||
)(CustomerDetailModal);
|
||||
|
|
@ -373,20 +373,22 @@ export const PROGRESS_STATUS_MAP = {
|
|||
|
||||
/** 安评业务提醒 — 提醒等级映射 */
|
||||
export const WARING_STATUS_MAP = {
|
||||
first: { color: "success", text: "首次预警" },
|
||||
second: { color: "warning", text: "二次提醒" },
|
||||
urgent: { color: "error", text: "紧急预警" },
|
||||
overdue: { color: "default", text: "已逾期" },
|
||||
normal: { color: "default", text: "正常" },
|
||||
first_waring: { color: "success", text: "首次预警" },
|
||||
second_waring: { color: "warning", text: "二次预警" },
|
||||
emergency_waring: { color: "error", text: "紧急预警" },
|
||||
overdue_warning: { color: "default", text: "逾期预警" },
|
||||
end_warning: { color: "default", text: "结束预警" },
|
||||
non_warn: { color: "default", text: "暂时不预警" },
|
||||
};
|
||||
|
||||
/** 安评业务提醒 — 提醒等级筛选选项 */
|
||||
export const WARING_STATUS_OPTIONS = [
|
||||
{ label: "首次预警(6个月)", value: "first" },
|
||||
{ label: "二次提醒(3个月)", value: "second" },
|
||||
{ label: "紧急预警(1个月)", value: "urgent" },
|
||||
{ label: "已逾期", value: "overdue" },
|
||||
{ label: "正常", value: "normal" },
|
||||
{ label: "暂时不预警", value: "non_warn" },
|
||||
{ label: "首次预警", value: "first_waring" },
|
||||
{ label: "二次预警", value: "second_waring" },
|
||||
{ label: "紧急预警", value: "emergency_waring" },
|
||||
{ label: "逾期预警", value: "overdue_warning" },
|
||||
{ label: "结束预警", value: "end_warning" },
|
||||
];
|
||||
|
||||
export const NODE_LABELS = {
|
||||
|
|
|
|||
|
|
@ -137,11 +137,6 @@ const menuItems = [
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/MonitorManage/RiskCenter",
|
||||
label: "风险预警中心",
|
||||
icon: <ExperimentOutlined />,
|
||||
},
|
||||
{
|
||||
key: "/safetyEval/container/Supervision/InspectionNotice",
|
||||
label: "监督检查告知",
|
||||
|
|
|
|||
|
|
@ -16,24 +16,24 @@ 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 { WARING_STATUS_MAP, WARING_STATUS_OPTIONS } from "~/enumerate/constant";
|
||||
import {
|
||||
QUALIFICATION_INDUSTRY_OPTIONS,
|
||||
QUALIFICATION_INDUSTRY_OPTIONS_MAP,
|
||||
} from "~/enumerate/enterpriseOptions";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
import CustomerDetailModal from "~/components/CustomerDetailModal";
|
||||
import "./index.less";
|
||||
|
||||
const { router } = tools;
|
||||
|
||||
const INDUSTRY_OPTIONS = [
|
||||
{ label: "危险化学品", value: "DANGEROUS_CHEMICAL" },
|
||||
{ label: "非煤矿山", value: "NON_COAL_MINE" },
|
||||
{ label: "城镇燃气", value: "URBAN_GAS" },
|
||||
{ label: "一般工贸", value: "GENERAL_TRADE" },
|
||||
];
|
||||
|
||||
const BusinessReminder = (props) => {
|
||||
const [searchForm] = Form.useForm();
|
||||
const [dataSource, setDataSource] = useState([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [statData, setStatData] = useState({});
|
||||
const [customerDetailOpen, setCustomerDetailOpen] = useState(false);
|
||||
const [customerId, setCustomerId] = useState(null);
|
||||
|
||||
const { projectWaringRemindPageLoading } = props.safetyEvalBusiness;
|
||||
|
||||
|
|
@ -84,7 +84,8 @@ const BusinessReminder = (props) => {
|
|||
};
|
||||
|
||||
const handleViewCustomer = (record) => {
|
||||
// TODO: 查看企业资料
|
||||
setCustomerId(record.customerId);
|
||||
setCustomerDetailOpen(true);
|
||||
};
|
||||
|
||||
const formatCycle = (days) => {
|
||||
|
|
@ -99,19 +100,22 @@ const BusinessReminder = (props) => {
|
|||
const renderWaringStatus = (status) => {
|
||||
const cfg = WARING_STATUS_MAP[status];
|
||||
if (!cfg) return <Tag>{status}</Tag>;
|
||||
const labelMap = {
|
||||
first: "首次预警 · 6个月",
|
||||
second: "二次提醒 · 3个月",
|
||||
urgent: "紧急预警 · 1个月",
|
||||
overdue: "已逾期",
|
||||
normal: "正常",
|
||||
};
|
||||
return <Tag color={cfg.color}>{labelMap[status] || cfg.text}</Tag>;
|
||||
return <Tag color={cfg.color}>{cfg.text}</Tag>;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: "客户名称", dataIndex: "customerName", width: 180, ellipsis: true },
|
||||
{ title: "行业 / 场景", dataIndex: "industryCode", width: 160, ellipsis: true },
|
||||
{
|
||||
title: "业务范围",
|
||||
dataIndex: "industryCode",
|
||||
width: 160,
|
||||
ellipsis: true,
|
||||
render: (val) =>
|
||||
val
|
||||
?.split(",")
|
||||
.map((code) => QUALIFICATION_INDUSTRY_OPTIONS_MAP[code])
|
||||
.join("、"),
|
||||
},
|
||||
{ title: "最近报告完成日", dataIndex: "archiveDate", width: 140 },
|
||||
{
|
||||
title: "周期",
|
||||
|
|
@ -203,16 +207,16 @@ const BusinessReminder = (props) => {
|
|||
</Form.Item>,
|
||||
<Form.Item key="industryCode" name="industryCode">
|
||||
<ControlWrapper.Select
|
||||
label="行业 / 场景"
|
||||
placeholder="全部"
|
||||
label="业务范围"
|
||||
placeholder="请选择业务范围"
|
||||
allowClear
|
||||
options={INDUSTRY_OPTIONS}
|
||||
options={QUALIFICATION_INDUSTRY_OPTIONS}
|
||||
/>
|
||||
</Form.Item>,
|
||||
<Form.Item key="waringStatus" name="waringStatus">
|
||||
<ControlWrapper.Select
|
||||
label="提醒等级"
|
||||
placeholder="全部"
|
||||
placeholder="请选择提醒等级"
|
||||
allowClear
|
||||
options={WARING_STATUS_OPTIONS}
|
||||
/>
|
||||
|
|
@ -227,8 +231,8 @@ const BusinessReminder = (props) => {
|
|||
下一次应开展日期 = 最近一次正式报告完成日期 + 对应行业评价周期
|
||||
</span>
|
||||
<Space>
|
||||
<Button>导出清单</Button>
|
||||
<Button type="primary">批量提醒</Button>
|
||||
{/* <Button>导出清单</Button>
|
||||
<Button type="primary">批量提醒</Button> */}
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
|
|
@ -248,6 +252,12 @@ const BusinessReminder = (props) => {
|
|||
}}
|
||||
onChange={handlePageChange}
|
||||
/>
|
||||
|
||||
<CustomerDetailModal
|
||||
open={customerDetailOpen}
|
||||
customerId={customerId}
|
||||
onCancel={() => setCustomerDetailOpen(false)}
|
||||
/>
|
||||
</PageLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ import {
|
|||
Row,
|
||||
Col,
|
||||
message,
|
||||
Descriptions,
|
||||
Flex,
|
||||
Tag,
|
||||
Space,
|
||||
Tooltip,
|
||||
} from "antd";
|
||||
|
||||
import { PlusOutlined } from "@ant-design/icons";
|
||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||
|
|
@ -22,12 +23,14 @@ import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
|||
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import BaiduMapPicker from "~/components/BaiduMapPicker";
|
||||
import AttachmentUpload from "~/components/AttachmentUpload";
|
||||
import CustomerDetailModal from "~/components/CustomerDetailModal";
|
||||
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||
import {
|
||||
district,
|
||||
ENTERPRISE_STATUS_OPTIONS,
|
||||
ENTERPRISE_SCALE_OPTIONS,
|
||||
EVAL_TYPE_MAP,
|
||||
NODE_LABELS
|
||||
} from "~/enumerate/constant";
|
||||
import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
|
||||
import { phoneRule, creditCodeRule } from "~/utils/validators";
|
||||
|
|
@ -42,10 +45,16 @@ const CustomerManage = (props) => {
|
|||
const [mapPickerVisible, setMapPickerVisible] = useState(false);
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
const [detailCustomerId, setDetailCustomerId] = useState(null);
|
||||
const [projectModalOpen, setProjectModalOpen] = useState(false);
|
||||
const [currentDetail, setCurrentDetail] = useState(null);
|
||||
const [editingId, setEditingId] = useState(null);
|
||||
const { customerLoading, customerModifyLoading, customerSaveLoading } =
|
||||
props.safetyEvalBusiness;
|
||||
const {
|
||||
customerLoading,
|
||||
customerModifyLoading,
|
||||
customerSaveLoading,
|
||||
customerDetailLoading,
|
||||
} = props.safetyEvalBusiness;
|
||||
|
||||
const getData = async (pagination) => {
|
||||
const params = {
|
||||
|
|
@ -103,22 +112,32 @@ const CustomerManage = (props) => {
|
|||
setModalOpen(true);
|
||||
};
|
||||
|
||||
const handleOpenEdit = async (record) => {
|
||||
const res = await props.customerDetail({ id: record.id });
|
||||
if (res?.success !== false) {
|
||||
const handleOpenEdit = (record) => {
|
||||
setEditingId(record.id);
|
||||
setCurrentDetail(null);
|
||||
modalForm.resetFields();
|
||||
setModalOpen(true);
|
||||
props.customerDetail({ id: record.id }).then((res) => {
|
||||
if (res?.success !== false) {
|
||||
setCurrentDetail(res?.data || {});
|
||||
modalForm.setFieldsValue(res?.data || {});
|
||||
setModalOpen(true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleViewDetail = async (record) => {
|
||||
const res = await props.customerDetail({ id: record.id });
|
||||
const handleViewDetail = (record) => {
|
||||
setDetailCustomerId(record.id);
|
||||
setDetailOpen(true);
|
||||
};
|
||||
|
||||
const handleViewProjects = (record) => {
|
||||
setCurrentDetail(null);
|
||||
setProjectModalOpen(true);
|
||||
props.customerDetail({ id: record.id }).then((res) => {
|
||||
if (res?.success !== false) {
|
||||
setCurrentDetail(res?.data || {});
|
||||
setDetailOpen(true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleDelete = async (record) => {
|
||||
|
|
@ -182,8 +201,13 @@ const CustomerManage = (props) => {
|
|||
title: "服务项目数",
|
||||
dataIndex: "projectCount",
|
||||
width: 110,
|
||||
render: (count) => (
|
||||
<Button type="link" size="small" style={{ padding: 0 }}>
|
||||
render: (count, record) => (
|
||||
<Button
|
||||
type="link"
|
||||
|
||||
size="small"
|
||||
onClick={() => handleViewProjects(record)}
|
||||
>
|
||||
{count || 0}
|
||||
</Button>
|
||||
),
|
||||
|
|
@ -197,7 +221,6 @@ const CustomerManage = (props) => {
|
|||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
|
||||
onClick={() => handleViewDetail(record)}
|
||||
>
|
||||
查看
|
||||
|
|
@ -223,6 +246,14 @@ const CustomerManage = (props) => {
|
|||
),
|
||||
},
|
||||
];
|
||||
const parseProjectNode = (data) => {
|
||||
if (Array.isArray(data)) return data;
|
||||
try {
|
||||
return JSON.parse(data || "[]");
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
|
|
@ -300,6 +331,7 @@ const CustomerManage = (props) => {
|
|||
<Modal
|
||||
title={editingId ? "编辑客户" : "新建客户"}
|
||||
open={modalOpen}
|
||||
loading={editingId ? customerDetailLoading : false}
|
||||
onCancel={() => setModalOpen(false)}
|
||||
onOk={handleCreateSubmit}
|
||||
confirmLoading={editingId ? customerModifyLoading : customerSaveLoading}
|
||||
|
|
@ -440,123 +472,107 @@ const CustomerManage = (props) => {
|
|||
</Modal>
|
||||
|
||||
{/* 客户详情弹窗 */}
|
||||
<Modal
|
||||
title={`客户详情 - ${currentDetail?.customerName || ""}`}
|
||||
<CustomerDetailModal
|
||||
open={detailOpen}
|
||||
customerId={detailCustomerId}
|
||||
onCancel={() => setDetailOpen(false)}
|
||||
footer={<Button onClick={() => setDetailOpen(false)}>关闭</Button>}
|
||||
width={700}
|
||||
destroyOnHidden
|
||||
>
|
||||
{currentDetail && (
|
||||
<>
|
||||
<Descriptions
|
||||
column={2}
|
||||
bordered
|
||||
size="small"
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
<Descriptions.Item label="客户名称">
|
||||
{currentDetail.customerName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="统一社会信用代码">
|
||||
{currentDetail.creditCode}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="企业状态">
|
||||
{(() => {
|
||||
const statusOption = ENTERPRISE_STATUS_OPTIONS.find(
|
||||
(opt) => opt.value === currentDetail.enterpriseStatusCode,
|
||||
);
|
||||
return (
|
||||
statusOption?.label || currentDetail.enterpriseStatusName
|
||||
);
|
||||
})()}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="企业规模">
|
||||
{(() => {
|
||||
const scaleOption = ENTERPRISE_SCALE_OPTIONS.find(
|
||||
(opt) => opt.value === currentDetail.enterpriseScaleCode,
|
||||
);
|
||||
return (
|
||||
scaleOption?.label || currentDetail.enterpriseScaleName
|
||||
);
|
||||
})()}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="所属行业">
|
||||
{currentDetail.industryName || currentDetail.industryCode}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="属地">
|
||||
{currentDetail.districtName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="联系人">
|
||||
{currentDetail.principalName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="联系电话">
|
||||
{currentDetail.principalPhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="主要负责人">
|
||||
{currentDetail.principalName}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人电话">
|
||||
{currentDetail.principalPhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="法定代表人">
|
||||
{currentDetail.legalRepresentative}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="法人电话">
|
||||
{currentDetail.legalRepresentativePhone}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="经营地址" span={2}>
|
||||
{currentDetail.businessAddress}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="经度">
|
||||
{currentDetail.longitude}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="纬度">
|
||||
{currentDetail.latitude}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
<h4 style={{ margin: "12px 0 8px" }}>安全评价项目列表</h4>
|
||||
<Table
|
||||
rowKey="id"
|
||||
dataSource={currentDetail.projects || []}
|
||||
columns={[
|
||||
{ title: "项目名称", dataIndex: "projectName" },
|
||||
{
|
||||
title: "评价类型",
|
||||
dataIndex: "evalTypeCode",
|
||||
width: 120,
|
||||
render: (s) => EVAL_TYPE_MAP[s] || s || "",
|
||||
},
|
||||
{ title: "报告完成日期", dataIndex: "planEndDate", width: 130 },
|
||||
{
|
||||
title: "项目状态",
|
||||
dataIndex: "status",
|
||||
width: 100,
|
||||
fixed: "right",
|
||||
render: (phase) => {
|
||||
const color =
|
||||
phase === "延期"
|
||||
? "error"
|
||||
: phase === "正常"
|
||||
? "success"
|
||||
: undefined;
|
||||
return <Tag color={color}>{phase || "-"}</Tag>;
|
||||
},
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
<BaiduMapPicker
|
||||
visible={mapPickerVisible}
|
||||
onCancel={() => setMapPickerVisible(false)}
|
||||
onConfirm={handleMapConfirm}
|
||||
/>
|
||||
|
||||
{/* 服务项目列表弹窗 */}
|
||||
<Modal
|
||||
title={`服务项目列表 - ${currentDetail?.customerName || ""}`}
|
||||
open={projectModalOpen}
|
||||
loading={customerDetailLoading}
|
||||
onCancel={() => setProjectModalOpen(false)}
|
||||
footer={
|
||||
<Button onClick={() => setProjectModalOpen(false)}>关闭</Button>
|
||||
}
|
||||
width={800}
|
||||
|
||||
destroyOnHidden
|
||||
>
|
||||
<Table
|
||||
rowKey="id"
|
||||
dataSource={currentDetail?.projects || []}
|
||||
columns={[
|
||||
{ title: "项目名称", dataIndex: "projectName" },
|
||||
{
|
||||
title: "状态",
|
||||
width: 200,
|
||||
render: (_, record) => {
|
||||
const nodes = parseProjectNode(record.projectNode);
|
||||
if (nodes.length === 0)
|
||||
return <span className="mp-progress-empty">暂无</span>;
|
||||
const total = nodes.length;
|
||||
const done = nodes.filter((n) => n.state === 1).length;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mp-progress-dots">
|
||||
{nodes.map((n, idx) => (
|
||||
<Tooltip
|
||||
key={n.type || idx}
|
||||
title={NODE_LABELS[n.type] || n.type}
|
||||
>
|
||||
<span
|
||||
className={`mp-progress-dot ${n.state === 1 ? "mp-progress-dot-done" : "mp-progress-dot-wait"}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
<div className="mp-progress-text">
|
||||
{done}/{total} · {Math.round((done / total) * 100)}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{ title: "负责人", dataIndex: "projectLeaderName", width: 130 },
|
||||
{
|
||||
title: "项目状态",
|
||||
dataIndex: "status",
|
||||
width: 100,
|
||||
fixed: "right",
|
||||
render: (phase, record) => {
|
||||
if (record.archiveFlag === 1) {
|
||||
return <Tag color="success">已归档</Tag>;
|
||||
}
|
||||
if (record.projectPhaseCode === "NORMAL") {
|
||||
return <Tag color="success">正常</Tag>;
|
||||
}
|
||||
if (record.projectPhaseCode === "DELAY") {
|
||||
return <Tag color="error">已延期</Tag>;
|
||||
}
|
||||
return record.projectPhaseName;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 100,
|
||||
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => {
|
||||
props.history.push(`/container/safetyEvalBusiness/ProjectFlow?id=${record.id}`)
|
||||
}}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
</Space>
|
||||
),
|
||||
}
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</Modal>
|
||||
</PageLayout>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -79,17 +79,7 @@ const RiskWarning = (props) => {
|
|||
getData();
|
||||
};
|
||||
|
||||
const handleCloseRisk = async (record) => {
|
||||
Modal.confirm({
|
||||
title: "确认闭环",
|
||||
content: `确定将"${record.projectName}"的风险标记为闭环吗?`,
|
||||
onOk: async () => {
|
||||
// TODO: 调用闭环接口
|
||||
message.success("已闭环");
|
||||
getData();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const columns = [
|
||||
{ title: "项目编号", dataIndex: "projectNo", width: 130 },
|
||||
|
|
@ -130,18 +120,7 @@ const RiskWarning = (props) => {
|
|||
return cfg ? <Tag color={cfg.color}>{cfg.text}</Tag> : "";
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 130,
|
||||
fixed: "right",
|
||||
render: (_, record) => (
|
||||
<Space>
|
||||
<Button type="link" size="small" onClick={() => handleCloseRisk(record)}>
|
||||
闭环
|
||||
</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
|
|
|
|||
Loading…
Reference in New Issue