消防管控地图标点弹窗

master
LiuJiaNan 2026-07-21 16:48:02 +08:00
parent 0b690d010c
commit e84b4191a6
17 changed files with 528 additions and 43 deletions

View File

@ -0,0 +1,26 @@
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
export const fireRescueTeamInfo = declareRequest(
"biFullLoading",
`Get > /fireResource/rescueTeam/{id}`,
);
export const fireControlRoomInfo = declareRequest(
"biFullLoading",
`Get > /fireResource/controlRoom/{id}`,
);
export const firePumpRoomInfo = declareRequest(
"biFullLoading",
`Get > /fireResource/pumpRoom/{id}`,
);
export const fireWaterSourceInfo = declareRequest(
"biFullLoading",
`Get > /fireResource/waterSource/{id}`,
);
export const firePointInfo = declareRequest(
"biFullLoading",
`Get > /fireCheck/firePoint/getInfoById/{id}`,
);
export const sensorDeviceInfo = declareRequest(
"biFullLoading",
`Get > /iotalarm/sensorDevice/{id}`,
);

View File

@ -8,3 +8,4 @@ export const NS_GLOBAL = defineNamespace("global");
export const NS_BI_STATISTICS = defineNamespace("biStatistics");
export const NS_BI_MARK = defineNamespace("biMark");
export const NS_BI_MARK_INFO = defineNamespace("biMarkInfo");

View File

@ -130,14 +130,14 @@ export const branchOfficeUtilsList = [
label: "消防救援队",
check: false,
markIcon: pointIco4,
type: "xfjyd01",
type: "fireRescueTeam",
request: "getRescueTeamScreenList",
titleKey: "teamName",
},
{
label: "消防控制室",
check: false,
type: "xfkzs01",
type: "fireControlRoom",
markIcon: pointIco5,
request: "getControlRoomScreenList",
titleKey: "roomName",
@ -145,7 +145,7 @@ export const branchOfficeUtilsList = [
{
label: "消防泵房",
check: false,
type: "xfbf01",
type: "firePumpRoom",
markIcon: pointIco6,
request: "getPumpRoomScreenList",
titleKey: "pumpRoomName",
@ -153,7 +153,7 @@ export const branchOfficeUtilsList = [
{
label: "消防水源",
check: false,
type: "xfsy01",
type: "fireWaterSource",
markIcon: pointIco7,
request: "getWaterSourceScreenList",
titleKey: "waterSourceName",
@ -161,7 +161,7 @@ export const branchOfficeUtilsList = [
{
label: "消防点位",
check: false,
type: "point",
type: "firePointLocation",
markIcon: pointIco8,
request: "getFirePointDeviceList",
titleKey: "firePointName",
@ -169,7 +169,7 @@ export const branchOfficeUtilsList = [
{
label: "报警设备",
check: false,
type: "alarm",
type: "alarmEquipment",
markIcon: pointIco32,
request: "getSensorDeviceScreenList",
titleKey: "sensorName",

View File

@ -152,14 +152,14 @@ export const portUtilsList = [
img: ico4,
checkImg: ico4On,
markIcon: pointIco4,
type: "xfjyd01",
type: "fireRescueTeam",
request: "getRescueTeamScreenList",
titleKey: "teamName",
},
{
label: "消防控制室",
check: false,
type: "xfkzs01",
type: "fireControlRoom",
img: ico5,
checkImg: ico5On,
markIcon: pointIco5,
@ -169,7 +169,7 @@ export const portUtilsList = [
{
label: "消防泵房",
check: false,
type: "xfbf01",
type: "firePumpRoom",
img: ico6,
checkImg: ico6On,
markIcon: pointIco6,
@ -179,7 +179,7 @@ export const portUtilsList = [
{
label: "消防水源",
check: false,
type: "xfsy01",
type: "fireWaterSource",
img: ico7,
checkImg: ico7On,
markIcon: pointIco7,
@ -189,7 +189,7 @@ export const portUtilsList = [
{
label: "消防点位",
check: false,
type: "point",
type: "firePointLocation",
img: ico8,
checkImg: ico8On,
markIcon: pointIco8,
@ -199,7 +199,7 @@ export const portUtilsList = [
{
label: "报警设备",
check: false,
type: "alarm",
type: "alarmEquipment",
img: ico28,
checkImg: ico28On,
markIcon: pointIco32,

View File

@ -54,7 +54,7 @@ function Camera() {
width={1500}
onCancel={setFalse}
title="视频巡屏"
wrapClassName="map_content_branch_office_camera_modal map_bi_model"
classNames={{ wrapper: "map_content_branch_office_camera_modal map_bi_model" }}
>
<div className="container">
<div className="parent_tabs">

View File

@ -1,7 +1,5 @@
.map_content_branch_office_camera_modal {
.container {
padding: 27px 14px;
.parent_tabs {
display: flex;
align-items: center;

View File

@ -0,0 +1,57 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions } from "antd";
import { useEffect, useState } from "react";
import { getLabelName } from "zy-react-library/utils";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const SENSOR_ATTR_OPTIONS = [
{ bianma: "NUMBER", name: "数值类" },
{ bianma: "SWITCH", name: "开关类" },
];
const YES_NO_OPTIONS = [
{ bianma: 1, name: "是" },
{ bianma: 0, name: "否" },
];
const SENSOR_STATUS_OPTIONS = [
{ bianma: "NORMAL", name: "正常" },
{ bianma: "FAULT", name: "故障" },
{ bianma: "OFFLINE", name: "离线" },
{ bianma: "deactivate", name: "停用" },
];
const FireRescueTeam = (props) => {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.sensorDeviceInfo({ id: props.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Descriptions
bordered
column={1}
items={[
{ label: "传感器编码", children: info.sensorCode },
{ label: "传感器名称", children: info.sensorName },
{ label: "传感器类型", children: info.sensorTypeName },
{ label: "传感器属性", children: getLabelName({ status: info.sensorAttr, list: SENSOR_ATTR_OPTIONS }) },
{ label: "传感器状态", children: getLabelName({ status: info.sensorStatus, list: SENSOR_STATUS_OPTIONS }) },
{ label: "安装位置", children: info.installPosition },
{ label: "出厂日期", children: info.factoryDate },
{ label: "是否阈值设定", children: getLabelName({ status: info.thresholdFlag, list: YES_NO_OPTIONS }) },
]}
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -0,0 +1,89 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Divider } from "antd";
import { useEffect, useState } from "react";
import PreviewImg from "zy-react-library/components/PreviewImg";
import Table from "zy-react-library/components/Table";
import { UPLOAD_FILE_TYPE_ENUM } from "zy-react-library/enum/uploadFile/gwj";
import useDictionary from "zy-react-library/hooks/useDictionary";
import useGetFile from "zy-react-library/hooks/useGetFile";
import { getLabelName } from "zy-react-library/utils";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const FireRescueTeam = (props) => {
const { getDictionary } = useDictionary();
const { getFile } = useGetFile();
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.fireControlRoomInfo({ id: props.id });
const dictionaryData = await getDictionary({ dictValue: "fire_resource_contro_root_type" });
const files = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM[302],
eqForeignKey: data.roomId,
});
setInfo({
...data,
roomImages: files,
roomStatusName: getLabelName({
list: dictionaryData,
status: data.roomStatus,
idKey: "dictValue",
nameKey: "dictLabel",
}),
});
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Divider titlePlacement="start">基本信息</Divider>
<Descriptions
bordered
column={1}
items={[
{ label: "消防控制室名称", children: info.roomName },
{ label: "消防控制室状态", children: info.roomStatusName },
{ label: "负责人", children: info.principalName },
{ label: "负责人手机号", children: info.principalPhone },
{ label: "经度", children: info.lng },
{ label: "纬度", children: info.lat },
{
label: "消防控制室图片",
children: info.roomImages && info.roomImages.length > 0 && (<PreviewImg files={info.roomImages} />),
},
]}
/>
<Divider titlePlacement="start">设备信息</Divider>
<Table
columns={[
{ title: "设备名称", dataIndex: "deviceName" },
{ title: "设备型号", dataIndex: "deviceModel" },
{ title: "设备数量", dataIndex: "deviceQty" },
{ title: "设备位置", dataIndex: "deviceLocation" },
]}
dataSource={info.devices || []}
pagination={false}
options={false}
disabledResizer
/>
<Divider titlePlacement="start">人员信息</Divider>
<Table
columns={[
{ title: "人员姓名", dataIndex: "personName" },
{ title: "人员手机号", dataIndex: "personPhone" },
{ title: "人员值班情况", dataIndex: "dutyDesc" },
]}
dataSource={info.persons || []}
pagination={false}
options={false}
disabledResizer
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -0,0 +1,41 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions } from "antd";
import { useEffect, useState } from "react";
import PreviewImg from "zy-react-library/components/PreviewImg";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const FireRescueTeam = (props) => {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.firePointInfo({ id: props.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Descriptions
bordered
column={1}
items={[
{ label: "消防区域", children: info.fireRegionName },
{ label: "负责部门", children: info.departmentName },
{ label: "点位负责人", children: info.userName },
{ label: "消防点位", children: info.firePointName },
{ label: "消防点位编码", children: info.firePointCode },
{ label: "经度", children: info.longitude },
{ label: "维度", children: info.latitude },
{ label: "是否关联NFC", children: info.nfcFlag === 1 ? "是" : info.nfcFlag === 0 ? "否" : "" },
{ label: "点检照片", children: (<PreviewImg files={info.urlList} />) },
]}
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -0,0 +1,79 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Divider } from "antd";
import { useEffect, useState } from "react";
import PreviewImg from "zy-react-library/components/PreviewImg";
import Table from "zy-react-library/components/Table";
import { UPLOAD_FILE_TYPE_ENUM } from "zy-react-library/enum/uploadFile/gwj";
import useDictionary from "zy-react-library/hooks/useDictionary";
import useGetFile from "zy-react-library/hooks/useGetFile";
import { getLabelName } from "zy-react-library/utils";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const FireRescueTeam = (props) => {
const { getDictionary } = useDictionary();
const { getFile } = useGetFile();
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.firePumpRoomInfo({ id: props.id });
const dictionaryData = await getDictionary({ dictValue: "fire_resource_contro_root_type" });
const files = await getFile({
eqType: UPLOAD_FILE_TYPE_ENUM[302],
eqForeignKey: data.pumpRoomId,
});
setInfo({
...data,
roomImages: files,
pumpStatusName: getLabelName({
list: dictionaryData,
status: data.pumpRoomStatus,
idKey: "dictValue",
nameKey: "dictLabel",
}),
});
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Divider titlePlacement="start">基本信息</Divider>
<Descriptions
bordered
column={1}
items={[
{ label: "消防泵房名称", children: info.pumpRoomName },
{ label: "消防泵房状态", children: info.pumpStatusName },
{ label: "负责人", children: info.principalName },
{ label: "负责人手机号", children: info.principalPhone },
{ label: "经度", children: info.lng },
{ label: "纬度", children: info.lat },
{
label: "消防泵房图片",
children: info.roomImages && info.roomImages.length > 0 && <PreviewImg files={info.roomImages} />,
},
]}
/>
<Divider titlePlacement="start">设备信息</Divider>
<Table
columns={[
{ title: "设备编号", dataIndex: "deviceCode" },
{ title: "设备名称", dataIndex: "deviceName" },
{ title: "设备分类", dataIndex: "deviceCategory" },
{ title: "负责单位", dataIndex: "chargeUnit" },
{ title: "具体位置", dataIndex: "deviceLocation" },
{ title: "设备参数和规格", dataIndex: "paramsSpec" },
]}
dataSource={info.devices || []}
pagination={false}
options={false}
disabledResizer
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -0,0 +1,52 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Divider } from "antd";
import { useEffect, useState } from "react";
import Table from "zy-react-library/components/Table";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const FireRescueTeam = (props) => {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.fireRescueTeamInfo({ id: props.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Divider titlePlacement="start">基本信息</Divider>
<Descriptions
bordered
column={1}
items={[
{ label: "救援队名称", children: info.teamName },
{ label: "类型", children: info.teamTypeName },
{ label: "负责人单位或部门", children: info.chargeOrgDept },
{ label: "队长", children: info.captainName },
{ label: "队长电话", children: info.captainPhone },
{ label: "指挥人员", children: info.commandCrew },
{ label: "建立日期", children: info.establishDate },
{ label: "所属区域或范围", children: info.regionScopeName },
{ label: "职责和任务范围", children: info.dutyScope },
]}
/>
<Divider titlePlacement="start">队员信息</Divider>
<Table
columns={[
{ title: "队员", dataIndex: "personName" },
{ title: "队员电话", dataIndex: "personPhone" },
]}
dataSource={info.rescueMembers || []}
pagination={false}
options={false}
disabledResizer
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -0,0 +1,58 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Divider } from "antd";
import { useEffect, useState } from "react";
import useDictionary from "zy-react-library/hooks/useDictionary";
import { getLabelName } from "zy-react-library/utils";
import { NS_BI_MARK_INFO } from "~/enumerate/namespace";
const FireRescueTeam = (props) => {
const { getDictionary } = useDictionary();
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props.fireWaterSourceInfo({ id: props.id });
const dictionaryData = await getDictionary({ dictValue: "fire_resource_water_type" });
setInfo({
...data,
waterSourceStatusName: getLabelName({
list: dictionaryData,
status: data.waterSourceStatus,
idKey: "dictValue",
nameKey: "dictLabel",
}),
});
};
useEffect(() => {
getData();
}, []);
return (
<div>
<Divider titlePlacement="start">基本信息</Divider>
<Descriptions
bordered
column={1}
items={[
{ label: "消防水源名称", children: info.waterSourceName },
{ label: "消防水源状态", children: info.waterSourceStatusName },
{ label: "经度", children: info.lng },
{ label: "纬度", children: info.lat },
{ label: "水源位置", children: info.waterLocation },
{ label: "所属单位或部门", children: info.belongOrgDept },
{ label: "接口形式", children: info.interfaceForm },
{ label: "水源类型", children: info.waterType },
{ label: "水源编号", children: info.waterCode },
{ label: "吸水口规格", children: info.suctionSpec },
{ label: "水源容量", children: info.capacity },
{ label: "供水能力", children: info.supplyAbility },
{ label: "设备清单", children: info.equipmentList },
]}
/>
</div>
);
};
export default Connect([NS_BI_MARK_INFO], true)(FireRescueTeam);

View File

@ -1,26 +1,46 @@
import { Modal } from "antd";
import { Button, Modal } from "antd";
import { useContext } from "react";
import { Context } from "~/pages/Container/Map/js/context";
import AlarmEquipment from "./AlarmEquipment";
import FireControlRoom from "./FireControlRoom";
import FirePointLocation from "./FirePointLocation";
import FirePumpRoom from "./FirePumpRoom";
import FireRescueTeam from "./FireRescueTeam";
import FireWaterSource from "./FireWaterSource";
import MeteorologicalMonitoring from "./MeteorologicalMonitoring";
const CustomModal = () => {
const { modalVisible, modalData, actions } = useContext(Context);
const renderContent = () => {
return {
meteorologicalMonitoring: <MeteorologicalMonitoring />, // 气象监测
fireRescueTeam: <FireRescueTeam id={modalData.id} />, // 消防救援队
fireControlRoom: <FireControlRoom id={modalData.id} />, // 消防控制室
firePumpRoom: <FirePumpRoom id={modalData.id} />, // 消防泵房
fireWaterSource: <FireWaterSource id={modalData.id} />, // 消防水源
firePointLocation: <FirePointLocation id={modalData.id} />, // 消防点位
alarmEquipment: <AlarmEquipment id={modalData.id} />, // 报警设备
}[modalData.markType?.replace("标记点_", "")];
};
return (
<Modal
open={modalVisible}
mask={{ closable: false }}
footer={null}
footer={[
<Button key="cancel" onClick={() => actions.resetMark()}>取消</Button>,
]}
width={1500}
onCancel={() => {
actions.resetMark();
}}
title={modalData.title || ""}
wrapClassName="map_bi_model"
classNames={{ root: "map_bi_model" }}
>
{
modalData.markType === "meteorologicalMonitoring" && <MeteorologicalMonitoring />
}
<div key={modalData.id}>
{renderContent()}
</div>
</Modal>
);
};

View File

@ -4,7 +4,7 @@ import { message, Spin } from "antd";
import autoFit from "autofit.js";
import { useEffect, useMemo, useReducer, useRef, useState } from "react";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
import { NS_BI_MARK } from "~/enumerate/namespace";
import { NS_BI_MARK, NS_BI_MARK_INFO } from "~/enumerate/namespace";
import BottomUtils from "./components/BottomUtils";
import CenterUtils from "./components/CenterUtils";
import Content from "./components/Content";
@ -138,4 +138,4 @@ function Map(props) {
);
}
export default Connect([NS_BI_MARK], true)(Map);
export default Connect([NS_BI_MARK, NS_BI_MARK_INFO], true)(Map);

View File

@ -34,24 +34,94 @@
}
}
.map_bi_model{
.@{ant-prefix}-modal {
.@{ant-prefix}-modal-header {
background-color: #06103b;
padding: 16px 20px;
.map_bi_model {
.@{ant-prefix} {
&-modal {
.@{ant-prefix}-modal-title {
&-close {
color: #fff;
}
&-header {
background-color: #06103b;
padding: 16px 20px;
}
&-title {
color: #fff;
}
&-container {
padding: 0;
background-color: #020828;
}
&-body {
padding: 20px 24px;
}
&-footer {
padding: 0 20px 16px 20px;
}
}
.@{ant-prefix}-modal-body,.@{ant-prefix}-modal-container {
padding: 0;
background-color: #020828;
&-divider {
&-inner-text {
color: #fff;
}
&-rail {
background-color: #0c1957;
}
}
.@{ant-prefix}-modal-close {
color: #fff;
&-descriptions {
&-item-label {
width: 200px;
color: #fff !important;
border: 1px solid #0c1957 !important;
background-color: #0b1544 !important;
}
&-item-content {
color: #fff;
border: 1px solid #0c1957 !important;
}
}
&-table {
background-color: #020828;
&-container {
border-inline-start: 1px solid #0c1957 !important;
border-top: 1px solid #0c1957 !important;
}
&-thead {
th {
background-color: #0b1544 !important;
color: #fff !important;
border-inline-end: 1px solid #0c1957 !important;
border-bottom: 1px solid #0c1957 !important;
}
}
&-tbody {
td {
background-color: #020828 !important;
color: #fff !important;
border-inline-end: 1px solid #0c1957 !important;
border-bottom: 1px solid #0c1957 !important;
span {
color: #fff !important;
}
}
}
}
&-empty-description {
color: #fff !important;
}
}
}

View File

@ -354,8 +354,6 @@ export default function useMapMethods(viewerRef, request) {
throw new Error("请传入markType扎点类型");
if (!options.markIcon)
throw new Error("请传入markIcon扎点图标");
if (!options.titleKey)
throw new Error("请传入titleKey标题键");
mitt.emit(changeCoverMaskVisibleMittKey, true);
await chunkedLoad(filterNull(pointList), 10, async (item) => {
const entityCollection = createEntityCollection(
@ -366,7 +364,7 @@ export default function useMapMethods(viewerRef, request) {
new Cesium.Entity({
id: createId(),
name,
position: getPosition(item.longitude, item.latitude),
position: getPosition(item.longitude || item.lng, item.latitude || item.lat),
billboard: await getBillboard({ image: options.markIcon, name }),
monitorItems: {
data: { ...item, markType: `标记点_${options.markType}`, title: options.subLabel },

View File

@ -1,10 +1,6 @@
// 过滤掉无经纬度的数据
export const filterNull = (
arr = [],
longitudeKey = "longitude",
latitudeKey = "latitude",
) => {
return arr.filter(item => item[longitudeKey] && item[latitudeKey]);
export const filterNull = (arr = []) => {
return arr.filter(item => (item.longitude || item.lng) && (item.latitude || item.lat));
};
// 格式化多边形