master
LiuJiaNan 2026-04-29 14:35:53 +08:00
parent 8a3fc9d40b
commit 6e38a7100c
65 changed files with 2201 additions and 74 deletions

View File

@ -25,13 +25,15 @@
"@cqsjjb/jjb-common-lib": "latest",
"@cqsjjb/jjb-dva-runtime": "latest",
"@cqsjjb/jjb-react-admin-component": "latest",
"@rc-component/virtual-list": "^1.0.2",
"ahooks": "^3.9.5",
"antd": "^5.27.6",
"dayjs": "^1.11.7",
"immer": "^11.1.4",
"lodash-es": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"zy-react-library": "^1.2.32"
"zy-react-library": "^1.2.39"
},
"devDependencies": {
"@antfu/eslint-config": "^5.4.1",

View File

@ -10,6 +10,7 @@
<meta name="renderer" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,viewport-fit=cover">
<meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/>
<% for (const item of $links) { %>
<link type="text/css" rel="stylesheet" href="<%= item %>"></link>
<% } %>

View File

@ -80,6 +80,8 @@
`/emergencyRescue/container/enterprise/emergencyRescue/duty/schedulingRegistration/list`
- 应急救援/应急接报/事件接报
`/emergencyRescue/container/enterprise/emergencyRescue/emergencyReporting/eventReport/list`
- 应急救援/救援
`/emergencyRescue/container/enterprise/emergencyRescue/rescue/list`
- 应急救援/应急知识库/案例库
`/emergencyRescue/container/enterprise/emergencyRescue/emergencyKnowledgeLibrary/case/list`
- 应急救援/应急知识库/危险货物库

View File

@ -4,6 +4,10 @@ export const closedCardPortList = declareRequest(
"closedCardPortLoading",
"Post > @/emergencyRescue/closedCheckpointInfo/list",
);
export const closedCardPortListAll = declareRequest(
"closedCardPortLoading",
"Get > /emergencyRescue/closedCheckpointInfo/listAll",
);
export const closedCardPortInfo = declareRequest(
"closedCardPortLoading",
"Get > /emergencyRescue/closedCheckpointInfo/{id}",

View File

@ -4,6 +4,10 @@ export const communicationGuaranteeOrganizationList = declareRequest(
"communicationGuaranteeOrganizationLoading",
"Post > @/emergencyRescue/communicationSecurityAgency/list",
);
export const communicationGuaranteeOrganizationListAll = declareRequest(
"communicationGuaranteeOrganizationLoading",
"Get > /emergencyRescue/communicationSecurityAgency/listAll",
);
export const communicationGuaranteeOrganizationInfo = declareRequest(
"communicationGuaranteeOrganizationLoading",
"Get > /emergencyRescue/communicationSecurityAgency/{id}",

View File

@ -4,6 +4,10 @@ export const drainageWellList = declareRequest(
"drainageWellLoading",
"Post > @/emergencyRescue/drainageWellInfo/list",
);
export const drainageWellListAll = declareRequest(
"drainageWellLoading",
"Get > /emergencyRescue/drainageWellInfo/listAll",
);
export const drainageWellInfo = declareRequest(
"drainageWellLoading",
"Get > /emergencyRescue/drainageWellInfo/{id}",

View File

@ -4,6 +4,10 @@ export const emergencyEquipmentList = declareRequest(
"emergencyEquipmentLoading",
"Post > @/emergencyRescue/emergencyEquipmentManagement/list",
);
export const emergencyEquipmentListAll = declareRequest(
"emergencyEquipmentLoading",
"Get > /emergencyRescue/emergencyEquipmentManagement/listAll",
);
export const emergencyEquipmentInfo = declareRequest(
"emergencyEquipmentLoading",
"Get > /emergencyRescue/emergencyEquipmentManagement/{id}",

View File

@ -4,6 +4,10 @@ export const emergencyShelterList = declareRequest(
"emergencyShelterLoading",
"Post > @/emergencyRescue/placeInfo/list",
);
export const emergencyShelterListAll = declareRequest(
"emergencyShelterLoading",
"Get > /emergencyRescue/placeInfo/listAll",
);
export const emergencyShelterInfo = declareRequest(
"emergencyShelterLoading",
"Get > /emergencyRescue/placeInfo/{id}",

View File

@ -4,6 +4,10 @@ export const enterpriseEmergencyPersonnelList = declareRequest(
"enterpriseEmergencyPersonnelLoading",
"Post > @/emergencyRescue/enterpriseEmergencyPersonnel/list",
);
export const enterpriseEmergencyPersonnelListAll = declareRequest(
"enterpriseEmergencyPersonnelLoading",
"Get > /emergencyRescue/enterpriseEmergencyPersonnel/listAll",
);
export const enterpriseEmergencyPersonnelInfo = declareRequest(
"enterpriseEmergencyPersonnelLoading",
"Get > /emergencyRescue/enterpriseEmergencyPersonnel/{id}",

View File

@ -4,6 +4,10 @@ export const enterprisePlanBasicInfoList = declareRequest(
"enterprisePlanBasicInfoLoading",
"Post > @/emergencyRescue/enterprisePlanBasicInfo/list",
);
export const enterprisePlanBasicInfoListAll = declareRequest(
"enterprisePlanBasicInfoLoading",
"Get > /emergencyRescue/enterprisePlanBasicInfo/listAll",
);
export const enterprisePlanBasicInfoInfo = declareRequest(
"enterprisePlanBasicInfoLoading",
"Get > /emergencyRescue/enterprisePlanBasicInfo/{id}",
@ -76,6 +80,10 @@ export const enterprisePlanOrganizationPersonnelList = declareRequest(
"enterprisePlanOrganizationPersonnelLoading",
"Post > @/emergencyRescue/enterprisePlanOrganizationPersonnel/list",
);
export const enterprisePlanOrganizationPersonnelListAll = declareRequest(
"enterprisePlanOrganizationPersonnelLoading",
"Get > /emergencyRescue/enterprisePlanOrganizationPersonnel/listAll",
);
export const enterprisePlanOrganizationPersonnelInfo = declareRequest(
"enterprisePlanOrganizationPersonnelLoading",
"Get > /emergencyRescue/enterprisePlanOrganizationPersonnel/{id}",

View File

@ -16,7 +16,3 @@ export const eventReportRescue = declareRequest(
"eventReportLoading",
"Post > @/emergencyRescue/eventReport/triggerRescue",
);
export const eventReportSpecialReportSave = declareRequest(
"eventReportSpecialReportLoading",
"Post > @/emergencyRescue/eventReportSpecial/save",
);

View File

@ -4,6 +4,10 @@ export const expertEmergencyRescueExpertGroupList = declareRequest(
"expertEmergencyRescueExpertGroupLoading",
"Post > @/emergencyRescue/emergencyRescueExpertGroup/list",
);
export const expertEmergencyRescueExpertGroupListAll = declareRequest(
"expertEmergencyRescueExpertGroupLoading",
"Get > /emergencyRescue/emergencyRescueExpertGroup/listAll",
);
export const expertEmergencyRescueExpertGroupInfo = declareRequest(
"expertEmergencyRescueExpertGroupLoading",
"Get > /emergencyRescue/emergencyRescueExpertGroup/{id}",

View File

@ -4,6 +4,10 @@ export const expertEmergencyRescueTeamList = declareRequest(
"expertEmergencyRescueTeamLoading",
"Post > @/emergencyRescue/emergencyRescueTeam/list",
);
export const expertEmergencyRescueTeamListAll = declareRequest(
"expertEmergencyRescueTeamLoading",
"Get > /emergencyRescue/emergencyRescueTeam/listAll",
);
export const expertEmergencyRescueTeamInfo = declareRequest(
"expertEmergencyRescueTeamLoading",
"Get > /emergencyRescue/emergencyRescueTeam/{id}",

View File

@ -4,6 +4,10 @@ export const firefightingEquipmentList = declareRequest(
"firefightingEquipmentLoading",
"Post > @/emergencyRescue",
);
export const firefightingEquipmentListAll = declareRequest(
"firefightingEquipmentLoading",
"Get > /emergencyRescue",
);
export const fireAreaListAll = declareRequest(
"firefightingEquipmentLoading",
"Get > /fireCheck/fireRegion/listAll",

View File

@ -4,6 +4,10 @@ export const materialEquipmentList = declareRequest(
"materialEquipmentLoading",
"Post > @/emergencyRescue/materialEquipmentWarehouse/list",
);
export const materialEquipmentListAll = declareRequest(
"materialEquipmentLoading",
"Get > /emergencyRescue/materialEquipmentWarehouse/listAll",
);
export const materialEquipmentInfo = declareRequest(
"materialEquipmentLoading",
"Get > /emergencyRescue/materialEquipmentWarehouse/{id}",

View File

@ -4,6 +4,10 @@ export const medicalGuaranteeOrganizationList = declareRequest(
"medicalGuaranteeOrganizationLoading",
"Post > @/emergencyRescue/medicalSecurityAgency/list",
);
export const medicalGuaranteeOrganizationListAll = declareRequest(
"medicalGuaranteeOrganizationLoading",
"Get > /emergencyRescue/medicalSecurityAgency/listAll",
);
export const medicalGuaranteeOrganizationInfo = declareRequest(
"medicalGuaranteeOrganizationLoading",
"Get > /emergencyRescue/medicalSecurityAgency/{id}",

42
src/api/rescue/index.js Normal file
View File

@ -0,0 +1,42 @@
import { declareRequest } from "@cqsjjb/jjb-dva-runtime";
export const rescueUpdateStatus = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/eventReport/endRescue",
);
export const eventReportSpecialReportSave = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/eventReportSpecial/save",
);
export const eventReportSpecialReportInfo = declareRequest(
"rescueLoading",
"Get > /emergencyRescue/eventReportSpecial/{id}",
);
export const rescueExecutionRecordList = declareRequest(
"rescueLoading",
"Get > /emergencyRescue/rescueInstructionExecutorFeedback/queryByRescueIdList/{id}",
);
export const rescueEventHandlingRecordList = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/rescueHandlingRecord/list",
);
export const rescueEventHandlingRecordListAll = declareRequest(
"rescueLoading",
"Get > /emergencyRescue/rescueHandlingRecord/listAll/{id}",
);
export const rescueCommandUsePlan = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/rescueInstruction/addBatch",
);
export const rescueCommandFeedbackRecords = declareRequest(
"rescueLoading",
"Get > /emergencyRescue/rescueInstructionExecutorFeedback/queryByRescueId/{id}",
);
export const rescueCommandSendCommand = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/rescueInstruction/save",
);
export const rescueCommandEventHandlingRecordsAdd = declareRequest(
"rescueLoading",
"Post > @/emergencyRescue/rescueHandlingRecord/save",
);

View File

@ -4,6 +4,10 @@ export const technicalSupportGuaranteeOrganizationList = declareRequest(
"technicalSupportGuaranteeOrganizationLoading",
"Post > @/emergencyRescue/technicalSupportAgency/list",
);
export const technicalSupportGuaranteeOrganizationListAll = declareRequest(
"technicalSupportGuaranteeOrganizationLoading",
"Get > /emergencyRescue/technicalSupportAgency/listAll",
);
export const technicalSupportGuaranteeOrganizationInfo = declareRequest(
"technicalSupportGuaranteeOrganizationLoading",
"Get > /emergencyRescue/technicalSupportAgency/{id}",

View File

@ -4,6 +4,10 @@ export const transportGuaranteeOrganizationList = declareRequest(
"transportGuaranteeOrganizationLoading",
"Post > @/emergencyRescue/transportSecurityAgency/list",
);
export const transportGuaranteeOrganizationListAll = declareRequest(
"transportGuaranteeOrganizationLoading",
"Get > /emergencyRescue/transportSecurityAgency/listAll",
);
export const transportGuaranteeOrganizationInfo = declareRequest(
"transportGuaranteeOrganizationLoading",
"Get > /emergencyRescue/transportSecurityAgency/{id}",

View File

@ -30,3 +30,4 @@ export const NS_DUTY_LOG = defineNamespace("dutyLog");
export const NS_EVENT_REPORT = defineNamespace("eventReport");
export const NS_EMERGENCY_KNOWLEDGE_LIBRARY = defineNamespace("emergencyKnowledgeLibrary");
export const NS_SCHEDULING_REGISTRATION = defineNamespace("schedulingRegistration");
export const NS_RESUE = defineNamespace("rescue");

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["expertEmergencyRescueTeamInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["expertEmergencyRescueTeamInfo"]({ id: query.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.expertEmergencyRescueTeam.expertEmergencyRescueTeamLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "救援队名称", children: info.teamName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["enterpriseEmergencyOrganizationInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["enterpriseEmergencyOrganizationInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.enterpriseEmergencyOrganization.enterpriseEmergencyOrganizationLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "机构名称", children: info.agencyName, span: 2 },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["communicationGuaranteeOrganizationInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["communicationGuaranteeOrganizationInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.communicationGuaranteeOrganization.communicationGuaranteeOrganizationLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "通讯机构名称", children: info.agencyName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["medicalGuaranteeOrganizationInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["medicalGuaranteeOrganizationInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.medicalGuaranteeOrganization.medicalGuaranteeOrganizationLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "医疗机构名称", children: info.agencyName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["technicalSupportGuaranteeOrganizationInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["technicalSupportGuaranteeOrganizationInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.technicalSupportGuaranteeOrganization.technicalSupportGuaranteeOrganizationLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "机构名称", children: info.agencyName, span: 2 },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["transportGuaranteeOrganizationInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["transportGuaranteeOrganizationInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.transportGuaranteeOrganization.transportGuaranteeOrganizationLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "运输机构名称", children: info.agencyName },

View File

@ -41,9 +41,11 @@ function Add(props) {
{ name: "accessModeName", label: "接入方式名称", onlyForLabel: true },
{ name: "ownerName", label: "机主姓名" },
{ name: "incomingCall", label: "呼入电话", rules: [{ pattern: PHONE, message: "请输入正确的电话号码" }] },
{ name: "eventTitle", label: "事件标题" },
{ name: "eventType", label: "事件类型" },
{ name: "reportTime", label: "接报时间", render: FORM_ITEM_RENDER_ENUM.DATETIME },
{ name: "occurrenceTime", label: "发生时间", render: FORM_ITEM_RENDER_ENUM.DATETIME },
{ name: "locationAddress", label: "所在地址" },
{ key: "map", customizeRender: true, span: 24, render: (<Map type="cesium" />) },
]}
form={form}

View File

@ -22,7 +22,7 @@ function List(props) {
occurrenceStartTime: formData.occurrenceTime?.[0],
occurrenceEndTime: formData.occurrenceTime?.[1],
}),
params: { corpId: query.corpinfoId },
params: { corpId: query.corpinfoId, isEventOrRescue: 1 },
});
const onRescue = async (id) => {
@ -104,28 +104,6 @@ function List(props) {
查看
</Button>
)}
{(!props.isRecord && props.permission("qyd-event-report-special-report")) && (
<Button
type="link"
onClick={() => {
const params = new URLSearchParams({
id: record.id,
accessMode: record.accessMode,
accessModeName: record.accessModeName,
ownerName: record.ownerName,
incomingCall: record.incomingCall,
eventType: record.eventType,
reportTime: record.reportTime,
occurrenceTime: record.occurrenceTime,
longitude: record.longitude,
latitude: record.latitude,
});
props.history.push(`./specialReport?${params.toString()}`);
}}
>
生成专报
</Button>
)}
</Space>
),
},

View File

@ -30,9 +30,11 @@ function View(props) {
{ label: "接入方式", children: info.accessModeName },
{ label: "机主姓名", children: info.ownerName },
{ label: "呼入电话", children: info.incomingCall },
{ label: "事件标题", children: info.eventTitle },
{ label: "事件类型", children: info.eventType },
{ label: "接报时间", children: info.reportTime },
{ label: "发生时间", children: info.occurrenceTime },
{ label: "所在地址", children: info.locationAddress },
{ label: "经度", children: info.longitude },
{ label: "纬度", children: info.latitude },
]}

View File

@ -0,0 +1,204 @@
export const getPosition = (x, y, z = 0.0) => {
return window.Cesium.Cartesian3.fromDegrees(x, y, z);
};
export const createId = () => {
return window.Cesium.createGuid();
};
export const filterNull = (arr = [], longitudeKey = "longitude", latitudeKey = "latitude") => {
return arr.filter(item => item[longitudeKey] && item[latitudeKey]);
};
export const createTextCanvas = (text) => {
return new Promise((resolve) => {
if (!text) {
resolve(null);
return;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const ratio = window.devicePixelRatio || 1;
const fontSize = 14 * ratio;
const fontFamily = "Arial, sans-serif";
const paddingX = Math.round(7 * ratio);
const paddingY = Math.round(5 * ratio);
ctx.font = `${fontSize}px ${fontFamily}`;
const textMetrics = ctx.measureText(text);
const textWidth = textMetrics.width;
const canvasWidth = Math.ceil(textWidth + paddingX * 2);
const canvasHeight = Math.ceil(fontSize + paddingY * 2);
canvas.style.width = `${canvasWidth / ratio}px`;
canvas.style.height = `${canvasHeight / ratio}px`;
canvas.width = canvasWidth * ratio;
canvas.height = canvasHeight * ratio;
ctx.scale(ratio, ratio);
ctx.font = `${fontSize}px ${fontFamily}`;
ctx.fillStyle = "rgba(20, 58, 142, 1)";
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.fillStyle = "#ffffff";
ctx.textBaseline = "top";
ctx.textRendering = "geometricPrecision";
const drawX = Math.round(paddingX);
const drawY = Math.round(paddingY);
ctx.fillText(text, drawX, drawY);
resolve({
base64: canvas.toDataURL(),
width: canvasWidth,
height: canvasHeight,
});
});
};
export const createImgCanvas = (imageUrl) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "Anonymous";
img.src = imageUrl;
img.onload = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
resolve({
base64: canvas.toDataURL(),
width: img.width,
height: img.height,
});
};
img.onerror = (error) => {
reject(new Error(`Failed to load image: ${error}`));
};
});
};
const imgCanvasCache = new Map();
export const getBillboardCanvases = async (imageUrl, text, spacing = 5) => {
let imgPromise;
if (imgCanvasCache.has(imageUrl)) {
imgPromise = imgCanvasCache.get(imageUrl);
}
else {
imgPromise = createImgCanvas(imageUrl);
imgCanvasCache.set(imageUrl, imgPromise);
}
const [imgResult, textResult] = await Promise.all([
imgPromise,
createTextCanvas(text),
]);
if (!textResult) {
return {
base64: imgResult.base64,
width: imgResult.width,
height: imgResult.height,
};
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const maxWidth = Math.max(imgResult.width, textResult.width);
const totalHeight = textResult.height + imgResult.height + spacing;
canvas.width = maxWidth;
canvas.height = totalHeight;
const loadImage = base64 =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = base64;
});
const [image, textImage] = await Promise.all([
loadImage(imgResult.base64),
loadImage(textResult.base64),
]);
const textX = (maxWidth - textResult.width) / 2;
const imageX = (maxWidth - imgResult.width) / 2;
ctx.drawImage(textImage, textX, 0);
ctx.drawImage(
image,
imageX,
textResult.height + spacing,
imgResult.width,
imgResult.height,
);
return {
base64: canvas.toDataURL(),
width: maxWidth,
height: totalHeight,
};
};
export const getBillboard = async ({ image, name = "" }) => {
const { base64, width, height } = await getBillboardCanvases(image, name);
return {
image: base64,
width,
height,
verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
heightReference: window.Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
clampToGround: true,
};
};
export const createEntityCollection = (name) => {
return new window.Cesium.CustomDataSource(`${name}_${createId()}`);
};
export const removeEntityCollection = (viewer, name) => {
viewer.dataSources._dataSources
.filter(ds => ds.name.startsWith(`${name}_`))
.forEach((item) => {
viewer.dataSources.remove(item);
});
};
export const createMergedEntityCollection = (viewer, name) => {
const mergedDataSource = createEntityCollection(name);
viewer.dataSources._dataSources
.filter(ds =>
ds.name.startsWith(`${name.substring(0, name.indexOf("Merged"))}_`),
)
.forEach((dataSource) => {
dataSource.entities.values.forEach((entity) => {
mergedDataSource.entities.add(entity);
});
});
return mergedDataSource;
};
export const addMergedEntityCollection = async (viewer, firstName, lastName = "") => {
const mergedDataSource = createMergedEntityCollection(viewer, `${firstName}Merged${lastName ? `_${lastName}` : ""}`);
await viewer.dataSources.add(mergedDataSource);
removeEntityCollection(viewer, `${firstName}${lastName ? `_${lastName}` : ""}`);
return mergedDataSource;
};
export const chunkedLoad = async (dataArray, chunkSize = 10, processItem) => {
const results = [];
for (let i = 0; i < dataArray.length; i += chunkSize) {
const chunk = dataArray.slice(i, i + chunkSize);
const chunkResults = await Promise.all(chunk.map(processItem));
results.push(...chunkResults.filter(Boolean));
}
return results;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,132 @@
import { useEventEmitter, useMount } from "ahooks";
import { Button, Descriptions, Modal } from "antd";
import { useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import ExpertEmergencyRescueTeamView from "~/pages/Container/Enterprise/EmergencyOrganization/EmergencyExpertTeam/ExpertEmergencyRescueTeam/View";
import EnterpriseEmergencyOrganizationView from "~/pages/Container/Enterprise/EmergencyOrganization/EmergencyManagementOrganization/EnterpriseEmergencyOrganization/View";
import CommunicationGuaranteeOrganizationView from "~/pages/Container/Enterprise/EmergencyOrganization/ProfessionalGuaranteeOrganization/CommunicationGuaranteeOrganization/View";
import MedicalGuaranteeOrganizationView from "~/pages/Container/Enterprise/EmergencyOrganization/ProfessionalGuaranteeOrganization/MedicalGuaranteeOrganization/View";
import TechnicalSupportGuaranteeOrganizationView from "~/pages/Container/Enterprise/EmergencyOrganization/ProfessionalGuaranteeOrganization/TechnicalSupportGuaranteeOrganization/View";
import TransportGuaranteeOrganizationView from "~/pages/Container/Enterprise/EmergencyOrganization/ProfessionalGuaranteeOrganization/TransportGuaranteeOrganization/View";
import ClosedCardPortView from "~/pages/Container/Enterprise/EmergencyResource/ClosedCardPort/View";
import DrainageWellView from "~/pages/Container/Enterprise/EmergencyResource/DrainageWell/View";
import EmergencyShelterView from "~/pages/Container/Enterprise/EmergencyResource/EmergencyShelter/View";
import MaterialEquipmentView from "~/pages/Container/Enterprise/EmergencyResource/MaterialEquipment/View";
import MarkOptions from "../MarkOptions";
import { useCesiumMap } from "./useCesiumMap";
function Cesium(props) {
const [modalVisible, setModalVisible] = useState(false);
const [modalType, setModalType] = useState("");
const [modalTitle, setModalTitle] = useState("");
const [modalInfo, setModalInfo] = useState({});
const [form] = FormBuilder.useForm();
const mackClickEvent = useEventEmitter();
mackClickEvent.useSubscription((value) => {
setModalVisible(true);
setModalType(value.mapType);
setModalTitle(value.data.modalTitle);
if (value.mapType === "default") {
setModalInfo(props.urlState);
}
else {
setModalInfo(value.data);
}
});
const { loadCesiumMap, initCesiumMap, drawScope, addMarkPoint, removeMarkPoint } = useCesiumMap(mackClickEvent);
useMount(async () => {
await loadCesiumMap();
initCesiumMap();
});
const onDrawScope = (values) => {
drawScope(values.scope);
};
return (
<div className="cesium">
<div className="form">
<FormBuilder
showActionButtons={false}
labelCol={{ span: 6 }}
options={[
{ name: "scope", label: "事故影响范围", render: FORM_ITEM_RENDER_ENUM.NUMBER, componentProps: { suffix: "米" } },
{ key: "button", customizeRender: true, render: <Button type="primary" onClick={form.submit}>确定</Button> },
]}
form={form}
onFinish={onDrawScope}
/>
</div>
<div id="map_container" style={{ width: "100%", height: 564 }}></div>
<MarkOptions addMarkPoint={addMarkPoint} removeMarkPoint={removeMarkPoint} />
{
modalVisible && (
<MarkModal
title={modalTitle}
type={modalType}
info={modalInfo}
onCancel={() => {
setModalVisible(false);
setModalType("");
setModalTitle("");
setModalInfo({});
}}
/>
)
}
</div>
);
}
const MarkModal = (props) => {
const info = props.info;
const id = props.info.id;
const type = props.type;
return (
<Modal
title={props.title}
open
width={800}
maskClosable={false}
onCancel={props.onCancel}
footer={[
<Button key="cancel" onClick={props.onCancel}>取消</Button>,
]}
>
{
type === "default" && (
<Descriptions
bordered
column={1}
styles={{ label: { width: 200 } }}
items={[
{ label: "事件标题", children: info.eventTitle },
{ label: "事件类型", children: info.eventType },
{ label: "发生时间", children: info.occurrenceTime },
{ label: "所在地址", children: info.locationAddress },
]}
/>
)
}
{type === "materialEquipment" && <MaterialEquipmentView isShowAllAction={false} id={id} />}
{type === "emergencyShelter" && <EmergencyShelterView isShowAllAction={false} id={id} />}
{type === "drainageWell" && <DrainageWellView isShowAllAction={false} id={id} />}
{type === "closedCardPort" && <ClosedCardPortView isShowAllAction={false} id={id} />}
{type === "expertEmergencyRescueTeam" && <ExpertEmergencyRescueTeamView isShowAllAction={false} id={id} />}
{type === "transportGuaranteeOrganization" && <TransportGuaranteeOrganizationView isShowAllAction={false} id={id} />}
{type === "medicalGuaranteeOrganization" && <MedicalGuaranteeOrganizationView isShowAllAction={false} id={id} />}
{type === "communicationGuaranteeOrganization" && <CommunicationGuaranteeOrganizationView isShowAllAction={false} id={id} />}
{type === "technicalSupportGuaranteeOrganization" && <TechnicalSupportGuaranteeOrganizationView isShowAllAction={false} id={id} />}
{type === "enterpriseEmergencyOrganization" && <EnterpriseEmergencyOrganizationView isShowAllAction={false} id={id} />}
</Modal>
);
};
export default Cesium;

View File

@ -0,0 +1,140 @@
import { useRef } from "react";
import CesiumMap from "zy-react-library/components/Map/CesiumMap";
import { dynamicLoadCss, dynamicLoadJs } from "zy-react-library/utils";
import {
addMergedEntityCollection,
chunkedLoad,
createEntityCollection,
createId,
filterNull,
getBillboard,
getPosition,
removeEntityCollection,
} from "./cesiumUtils";
import defaultBillboardImage from "./images/h.png";
export const useCesiumMap = (mackClickEvent) => {
const mapInstanceRef = useRef(null);
const loadCesiumMap = async () => {
if (!window.Cesium) {
if (window?.base?.loadDynamicResource) {
await window.base.loadDynamicResource({
url: "https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Cesium.js",
type: "script",
attr: { type: "text/javascript" },
});
await window.base.loadDynamicResource({
url: "https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Widgets/widgets.css",
type: "link",
attr: { rel: "stylesheet", type: "text/css" },
});
}
else {
await dynamicLoadJs("https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Cesium.js");
await dynamicLoadCss("https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Widgets/widgets.css");
}
}
};
const flyTo = ({ longitude, latitude, height }) => {
mapInstanceRef.current.camera.flyTo({
destination: getPosition(longitude, latitude, height),
duration: 2,
});
};
const registerClickEvent = () => {
mapInstanceRef.current.cesiumWidget.screenSpaceEventHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
mapInstanceRef.current.cesiumWidget.screenSpaceEventHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
const screenSpaceEventHandler = new window.Cesium.ScreenSpaceEventHandler(mapInstanceRef.current.scene.canvas);
screenSpaceEventHandler.setInputAction((movement) => {
const pick = mapInstanceRef.current.scene.pick(movement.position);
if (window.Cesium.defined(pick) && pick.id?.id && pick.id?.monitorItems) {
const data = pick.id.monitorItems.data;
const mapType = data.mapType.substring(data.mapType.indexOf("_") + 1);
mackClickEvent.emit({ mapType, data: pick.id.monitorItems.data });
}
}, window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
const addMarkPoint = async (pointList, options) => {
await chunkedLoad(filterNull(pointList), 10, async (item) => {
const entityCollection = createEntityCollection(
`markEntityCollection_${options.mapType}`,
);
const name = item[options.nameKey] || "";
entityCollection.entities.add(
new window.Cesium.Entity({
id: createId(),
name,
position: getPosition(item.longitude, item.latitude),
billboard: await getBillboard({ image: options.mapIcon || defaultBillboardImage, name }),
monitorItems: {
data: { ...item, mapType: `标记点_${options.mapType}`, modalTitle: options.modalTitle },
},
}),
);
mapInstanceRef.current.dataSources.add(entityCollection);
});
await addMergedEntityCollection(
mapInstanceRef.current,
"markEntityCollection",
options.mapType,
);
};
const removeMarkPoint = (mapType) => {
removeEntityCollection(mapInstanceRef.current, `markEntityCollectionMerged${mapType ? `_${mapType}` : ""}`);
};
const initCesiumMap = () => {
const { init } = new CesiumMap();
const { viewer } = init();
mapInstanceRef.current = viewer;
flyTo({ longitude: window.mapLongitude, latitude: window.mapLatitude, height: 2000 });
addMarkPoint([{ longitude: window.mapLongitude, latitude: window.mapLatitude }], { mapType: "default", modalTitle: "事件" });
registerClickEvent();
return viewer;
};
const getViewer = () => {
return mapInstanceRef.current;
};
const drawScope = (radius) => {
const viewer = mapInstanceRef.current;
if (!viewer || !radius)
return;
const existingEntity = viewer.entities.getById("scopeCircle");
if (existingEntity) {
viewer.entities.remove(existingEntity);
}
viewer.entities.add({
id: "scopeCircle",
position: getPosition(window.mapLongitude, window.mapLatitude),
ellipse: {
semiMinorAxis: radius,
semiMajorAxis: radius,
material: window.Cesium.Color.RED.withAlpha(0.3),
outline: true,
outlineColor: window.Cesium.Color.RED,
outlineWidth: 2,
},
});
flyTo({ longitude: window.mapLongitude, latitude: window.mapLatitude, height: radius * 3 });
};
return {
viewer: mapInstanceRef.current,
loadCesiumMap,
initCesiumMap,
getViewer,
drawScope,
addMarkPoint,
removeMarkPoint,
};
};

View File

@ -0,0 +1,110 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import VirtualList from "@rc-component/virtual-list";
import { useInterval } from "ahooks";
import { Image, Space } from "antd";
import { useEffect, useState } from "react";
import { NS_RESUE } from "~/enumerate/namespace";
import circle from "../../images/circle.png";
function CommandFeedbackRecords(props) {
const [list, setList] = useState([]);
const getData = async () => {
const { data } = await props["rescueCommandFeedbackRecords"]({ id: props.id });
setList(data || []);
};
props.getCommandEvent.useSubscription(() => {
getData();
});
useInterval(() => {
getData();
}, 5000);
useEffect(() => {
getData();
}, []);
return (
<div className="command-feedback-records">
<div className="title">
<img src={circle} alt="" />
<span>预案指令反馈记录</span>
</div>
<div className="container">
{list.length > 0
? (
<VirtualList
data={list}
height={364}
itemHeight={110}
itemKey="id"
>
{item => (
<div key={item.id}>
<div className="timeline-item">
<div className="timeline-dot" />
<div className="parent">
<div style={{ color: "#FF0000" }}>
<span>指令编号</span>
<span>{item.commandNumber}</span>
</div>
<div>
<span className="label">发送时间</span>
<span>{item.sendTime}</span>
</div>
<div>
<span className="label">指令类型</span>
<span>{item.commandType}</span>
</div>
<div>
<span className="label">指令内容</span>
<span>{item.commandContent}</span>
</div>
</div>
</div>
{item.rescueInstructionExecutorFeedbackCOList.map((feedback, feedbackIndex) => (
<div key={feedback.id} className="timeline-item">
<div className="timeline-dot" />
<div className="child">
<div style={{ color: "#5EA629" }}>
<span>指令反馈</span>
<span>{String(item.rescueInstructionExecutorFeedbackCOList.length - feedbackIndex).padStart(2, "0")}</span>
</div>
<div>
<span className="label">反馈时间</span>
<span>{feedback.feedbackTime}</span>
</div>
<div>
<span className="label">指令执行状态</span>
<span>{feedback.commandStatus}</span>
</div>
<div>
<span className="label">反馈内容</span>
<span>{feedback.feedbackContent}</span>
</div>
<div>
<span className="label">现场图片</span>
<div>
<Space wrap={true}>
{(feedback.feedbackImageUrl ? feedback.feedbackImageUrl.split(",") : []).map((img, imgIndex) => (
<Image key={imgIndex} src={img} alt="feedback" width={60} height={60} />
))}
</Space>
</div>
</div>
</div>
</div>
))}
</div>
)}
</VirtualList>
)
: <div style={{ height: 364, display: "flex", alignItems: "center", justifyContent: "center" }}>暂无数据</div>}
</div>
</div>
);
}
export default Connect([NS_RESUE], true)(CommandFeedbackRecords);

View File

@ -0,0 +1,91 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import VirtualList from "@rc-component/virtual-list";
import { Button, Input, message, Space } from "antd";
import { useEffect, useState } from "react";
import { NS_RESUE } from "~/enumerate/namespace";
import circle from "~/pages/Container/Enterprise/EmergencyRescue/Rescue/Command/images/circle.png";
function EventHandlingRecords(props) {
const [list, setList] = useState([]);
const [value, setValue] = useState("");
const getData = async () => {
const { data } = await props["rescueEventHandlingRecordListAll"]({ id: props.id });
setList(data || []);
};
useEffect(() => {
getData();
}, []);
const onSubmit = async () => {
if (!value) {
message.error("请输入内容");
return;
}
const { success } = await props["rescueCommandEventHandlingRecordsAdd"]({
rescueId: props.id,
handlingContent: value,
});
if (success) {
message.success("添加成功");
setValue("");
getData();
}
};
return (
<div className="event-handling-records">
<div className="title">
<img src={circle} alt="" />
<span>事件处置记录</span>
</div>
<div className="container">
{list.length > 0
? (
<VirtualList
data={list}
height={props.planId ? 103 : 241}
itemHeight={66}
itemKey="id"
>
{item => (
<div key={item.id} className="timeline-item">
<div className="timeline-dot" />
<div className="time">{item.handlingTime}</div>
<div className="content">{item.handlingContent}</div>
</div>
)}
</VirtualList>
)
: (
<div style={{
height: props.planId ? 103 : 241,
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
暂无数据
</div>
)}
<div style={{ marginTop: 16 }}>
<Input.TextArea
value={value}
onChange={e => setValue(e.target.value)}
maxLength={500}
showCount={true}
rows={3}
/>
<div style={{ textAlign: "center", marginTop: 16 }}>
<Space>
<Button type="primary" onClick={onSubmit}>添加记录</Button>
</Space>
</div>
</div>
</div>
</div>
);
}
export default Connect([NS_RESUE], true)(EventHandlingRecords);

View File

@ -0,0 +1,255 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { produce } from "immer";
import { useState } from "react";
import {
NS_CLOSED_CARD_PORT,
NS_COMMUNICATION_GUARANTEE_ORGANIZATION,
NS_DRAINAGE_WELL,
NS_EMERGENCY_EQUIPMENT,
NS_EMERGENCY_SHELTER,
NS_ENTERPRISE_EMERGENCY_ORGANIZATION,
NS_EXPERT_EMERGENCY_RESCUE_EXPERT_GROUP,
NS_EXPERT_EMERGENCY_RESCUE_TEAM,
NS_FIREFIGHTING_EQUIPMENT,
NS_MATERIAL_EQUIPMENT,
NS_MEDICAL_GUARANTEE_ORGANIZATION,
NS_TECHNICAL_SUPPORT_GUARANTEE_ORGANIZATION,
NS_TRANSPORT_GUARANTEE_ORGANIZATION,
} from "~/enumerate/namespace";
// import ico1 from "../../images/ico1.png";
import ico2 from "../../images/ico2.png";
import ico3 from "../../images/ico3.png";
import ico4 from "../../images/ico4.png";
import ico5 from "../../images/ico5.png";
import ico6 from "../../images/ico6.png";
import ico7 from "../../images/ico7.png";
// import ico8 from "../../images/ico8.png";
import ico9 from "../../images/ico9.png";
import ico10 from "../../images/ico10.png";
import ico11 from "../../images/ico11.png";
import ico12 from "../../images/ico12.png";
import ico13 from "../../images/ico13.png";
import option_bg from "../../images/option_bg.png";
function MarkOptions(props) {
const [list, setList] = useState([
{
title: "应急救援物资",
checked: false,
children: [
// {
// title: "应急装备",
// checked: false,
// icon: ico1,
// nameKey: "equipmentName",
// action: props["emergencyEquipmentListAll"],
// type: "emergencyEquipment",
// },
{
title: "物资装备库",
checked: false,
icon: ico2,
nameKey: "warehouseName",
action: props["materialEquipmentListAll"],
type: "materialEquipment",
},
{
title: "应急避难场所",
checked: false,
icon: ico3,
nameKey: "placeName",
action: props["emergencyShelterListAll"],
type: "emergencyShelter",
},
{
title: "消防物资",
checked: false,
icon: ico4,
action: props["firefightingEquipmentListAll"],
type: "firefightingEquipment",
},
{
title: "排水井",
checked: false,
icon: ico5,
nameKey: "wellName",
action: props["drainageWellListAll"],
type: "drainageWell",
},
{
title: "封闭卡口",
checked: false,
icon: ico6,
nameKey: "checkpointName",
action: props["closedCardPortListAll"],
type: "closedCardPort",
},
],
},
{
title: "应急专家队伍",
checked: false,
children: [
{
title: "应急救援队伍",
checked: false,
icon: ico7,
nameKey: "teamName",
action: props["expertEmergencyRescueTeamListAll"],
type: "expertEmergencyRescueTeam",
},
// {
// title: "应急救援专家组",
// checked: false,
// icon: ico8,
// nameKey: "groupName",
// action: props["expertEmergencyRescueExpertGroupListAll"],
// type: "expertEmergencyRescueExpertGroup",
// },
],
},
{
title: "专业保障机构",
checked: false,
children: [
{
title: "运输保障机构",
checked: false,
icon: ico9,
nameKey: "agencyName",
action: props["transportGuaranteeOrganizationListAll"],
type: "transportGuaranteeOrganization",
},
{
title: "医疗保障机构",
checked: false,
icon: ico10,
nameKey: "agencyName",
action: props["medicalGuaranteeOrganizationListAll"],
type: "medicalGuaranteeOrganization",
},
{
title: "通讯保障机构",
checked: false,
icon: ico11,
nameKey: "agencyName",
action: props["communicationGuaranteeOrganizationListAll"],
type: "communicationGuaranteeOrganization",
},
{
title: "技术支持机构",
checked: false,
icon: ico12,
nameKey: "agencyName",
action: props["technicalSupportGuaranteeOrganizationListAll"],
type: "technicalSupportGuaranteeOrganization",
},
],
},
{
title: "企业应急机构",
checked: false,
icon: ico13,
nameKey: "agencyName",
action: props["enterpriseEmergencyOrganizationListAll"],
type: "enterpriseEmergencyOrganization",
},
]);
const onClickFirst = async (item, index) => {
setList(produce((draft) => {
draft.forEach((draftItem, draftIndex) => {
(draftIndex !== index && draftItem.children) && (draftItem.checked = false);
});
draft[index].checked = !draft[index].checked;
}));
if (item.action) {
if (item.checked) {
props.removeMarkPoint(item.type);
return;
}
const { data } = await item.action();
props.addMarkPoint(data, {
mapType: item.type,
mapIcon: item.icon,
modalTitle: item.title,
nameKey: item.nameKey,
});
}
};
const onClickLast = async (parentIndex, item, index) => {
setList(produce((draft) => {
draft[parentIndex].children[index].checked = !draft[parentIndex].children[index].checked;
}));
if (item.action) {
if (item.checked) {
props.removeMarkPoint(item.type);
return;
}
const { data } = await item.action();
props.addMarkPoint(data, {
mapType: item.type,
mapIcon: item.icon,
modalTitle: item.title,
nameKey: item.nameKey,
});
}
};
return (
<div className="mark-options">
{
list.map((item, index) => (
<div
key={index}
className="mark-options-item"
style={{ backgroundImage: `url(${option_bg})` }}
>
<div
className="mark-options-item-title"
onClick={() => {
onClickFirst(item, index);
}}
>
<div>{item.title}</div>
</div>
{item.checked && item.children && (
<div className="mark-options-item-children">
{
item.children.map((child, childIndex) => (
<div
key={childIndex}
className={`mark-options-item-children-item ${child.checked ? "active" : ""}`}
onClick={() => {
onClickLast(index, child, childIndex);
}}
>
<div>{child.title}</div>
</div>
))
}
</div>
)}
</div>
))
}
</div>
);
}
export default Connect([
NS_EMERGENCY_EQUIPMENT,
NS_MATERIAL_EQUIPMENT,
NS_EMERGENCY_SHELTER,
NS_FIREFIGHTING_EQUIPMENT,
NS_DRAINAGE_WELL,
NS_CLOSED_CARD_PORT,
NS_EXPERT_EMERGENCY_RESCUE_TEAM,
NS_EXPERT_EMERGENCY_RESCUE_EXPERT_GROUP,
NS_TRANSPORT_GUARANTEE_ORGANIZATION,
NS_MEDICAL_GUARANTEE_ORGANIZATION,
NS_COMMUNICATION_GUARANTEE_ORGANIZATION,
NS_TECHNICAL_SUPPORT_GUARANTEE_ORGANIZATION,
NS_ENTERPRISE_EMERGENCY_ORGANIZATION,
], true)(MarkOptions);

View File

@ -0,0 +1,239 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import VirtualList from "@rc-component/virtual-list";
import { message, Modal } from "antd";
import { useEffect, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder";
import Table from "zy-react-library/components/Table";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useTable from "zy-react-library/hooks/useTable";
import { NS_ENTERPRISE_EMERGENCY_PERSONNEL, NS_ENTERPRISE_PLAN, NS_RESUE } from "~/enumerate/namespace";
import circle from "~/pages/Container/Enterprise/EmergencyRescue/Rescue/Command/images/circle.png";
function NonContingencyInstructions(props) {
const [sendCommandModalVisible, setSendCommandModalVisible] = useState(false);
const [currentInfo, setCurrentInfo] = useState({});
const [modalSubTitle, setModalSubTitle] = useState("");
const {
tableProps: enterprisePlanOrganizationPersonnelTableProps,
getData: enterprisePlanOrganizationPersonnelGetData,
} = useTable(props["enterprisePlanOrganizationPersonnelListAll"], {
params: { planId: props.planId },
usePagination: false,
useStorageQueryCriteria: false,
manual: true,
});
const { tableProps: enterpriseEmergencyPersonnelTableProps } = useTable(props["enterpriseEmergencyPersonnelListAll"], {
usePagination: false,
useStorageQueryCriteria: false,
});
useEffect(() => {
props.planId && enterprisePlanOrganizationPersonnelGetData();
}, [props.planId]);
return (
<div className="non-contingency-instructions">
<div className="title">
<img src={circle} alt="" />
<span>非预案指令发送</span>
</div>
<div className="container">
{
props.planId && (
<>
<div className="subtitle">预案应急救援机构人员</div>
<div className="table">
<div className="header">
<div className="title">姓名</div>
<div className="title">组内岗位</div>
<div className="title">联系电话</div>
<div className="title">操作</div>
</div>
<div
className="body"
style={{ border: `1px solid ${enterprisePlanOrganizationPersonnelTableProps.dataSource.length > 0 ? "transparent" : "#fff"}` }}
>
{
enterprisePlanOrganizationPersonnelTableProps.dataSource.length > 0
? (
<VirtualList
data={enterprisePlanOrganizationPersonnelTableProps.dataSource}
height={88}
itemHeight={23}
itemKey="id"
>
{item => (
<div className="row" key={item.id}>
<div className="cell">{item.userName}</div>
<div className="cell">{item.groupPost}</div>
<div className="cell">{item.contactPhone}</div>
<div className="cell">
<a
onClick={() => {
setSendCommandModalVisible(true);
setCurrentInfo(item);
setModalSubTitle("预案应急救援机构人员");
}}
>
发送
</a>
</div>
</div>
)}
</VirtualList>
)
: (
<div style={{
height: 88,
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
暂无数据
</div>
)
}
</div>
</div>
</>
)
}
<div style={{ marginTop: 10 }}>
<div className="subtitle">企业应急救援机构人员</div>
<div className="table">
<div className="header">
<div className="title">姓名</div>
<div className="title">行政职务</div>
<div className="title">联系电话</div>
<div className="title">操作</div>
</div>
<div
className="body"
style={{ border: `1px solid ${enterpriseEmergencyPersonnelTableProps.dataSource.length > 0 ? "transparent" : "#fff"}` }}
>
{
enterpriseEmergencyPersonnelTableProps.dataSource.length > 0
? (
<VirtualList
data={enterpriseEmergencyPersonnelTableProps.dataSource}
height={88}
itemHeight={23}
itemKey="id"
>
{item => (
<div className="row" key={item.id}>
<div className="cell">{item.userName}</div>
<div className="cell">{item.administrativePosition}</div>
<div className="cell">{item.contactPhone}</div>
<div className="cell">
<a
onClick={() => {
setSendCommandModalVisible(true);
setCurrentInfo(item);
setModalSubTitle("企业应急救援机构人员");
}}
>
发送
</a>
</div>
</div>
)}
</VirtualList>
)
: (
<div
style={{ height: 88, display: "flex", alignItems: "center", justifyContent: "center" }}
>
暂无数据
</div>
)
}
</div>
</div>
</div>
{
sendCommandModalVisible && (
<SendCommandModal
info={currentInfo}
subTitle={modalSubTitle}
id={props.id}
getCommandEvent={props.getCommandEvent}
onCancel={() => {
setSendCommandModalVisible(false);
setCurrentInfo({});
}}
/>
)
}
</div>
</div>
);
}
const SendCommandModalComponent = (props) => {
const [form] = FormBuilder.useForm();
const onSubmit = async (values) => {
const { success } = await props["rescueCommandSendCommand"]({
...values,
rescueId: props.id,
userId: props.info.id,
});
if (success) {
message.success("发送成功");
props.onCancel();
props.getCommandEvent.emit();
}
};
return (
<Modal
open
title="发送指令"
width={600}
maskClosable={false}
onCancel={props.onCancel}
onOk={form.submit}
okText="发送指令"
confirmLoading={props.rescue.rescueLoading}
>
<Table
headerTitle={<div style={{ fontSize: 14 }}>{props.subTitle}</div>}
options={false}
disabledResizer={true}
pagination={false}
columns={props.subTitle === "预案应急救援机构人员"
? [
{ title: "所属机构", dataIndex: "organizationName" },
{ title: "姓名", dataIndex: "userName" },
{ title: "职务", dataIndex: "position" },
{ title: "组内岗位", dataIndex: "groupPost" },
{ title: "联系电话", dataIndex: "contactPhone" },
]
: [
{ title: "姓名", dataIndex: "userName" },
{ title: "行政职务", dataIndex: "administrativePosition" },
{ title: "行政级别", dataIndex: "administrativeLevel" },
{ title: "联系电话", dataIndex: "contactPhone" },
]}
dataSource={[props.info]}
/>
<FormBuilder
style={{ marginTop: 10 }}
span={24}
showActionButtons={false}
labelCol={{ span: 8 }}
options={[
{ name: "commandContent", label: "指令内容", render: FORM_ITEM_RENDER_ENUM.TEXTAREA },
]}
form={form}
onFinish={onSubmit}
/>
</Modal>
);
};
const SendCommandModal = Connect([NS_RESUE], true)(SendCommandModalComponent);
export default Connect([NS_RESUE, NS_ENTERPRISE_EMERGENCY_PERSONNEL, NS_ENTERPRISE_PLAN], true)(NonContingencyInstructions);

View File

@ -0,0 +1,163 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Space } from "antd";
import { useEffect, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import { getLabelName } from "zy-react-library/utils";
import { NS_ENTERPRISE_PLAN, NS_RESUE } from "~/enumerate/namespace";
function SelectEmergencyPlan(props) {
const [form] = FormBuilder.useForm();
const [enterprisePlanList, setEnterprisePlanList] = useState([]);
const [responseLevelList, setResponseLevelList] = useState([]);
const [isActivatePlan, setIsActivatePlan] = useState(false);
const [info, setInfo] = useState({});
const getEnterprisePlanList = async () => {
const { data } = await props["enterprisePlanBasicInfoListAll"]({ auditFlag: 2 });
setEnterprisePlanList(data);
};
const getResponseLevelList = async (planId) => {
const { data } = await props["enterprisePlanLevelResponseListAll"]({ planId });
setResponseLevelList(data);
};
useEffect(() => {
getEnterprisePlanList();
}, []);
useEffect(() => {
if (props.urlState.planId) {
setIsActivatePlan(true);
setInfo(props.urlState);
props.setUrlState({
planId: props.urlState.planId,
planName: props.urlState.planName,
responseLevel: props.urlState.responseLevel,
responseLevelName: props.urlState.responseLevelName,
});
props.getCommandEvent.emit();
}
}, [props.urlState]);
useEffect(() => {
props.urlState.planId && getResponseLevelList(props.urlState.planId);
}, [props.urlState.planId]);
const onActivatePlan = async (values) => {
const { success } = await props["rescueCommandUsePlan"]({ rescueId: props.id, ...values });
if (success) {
setIsActivatePlan(true);
setInfo(values);
props.setUrlState({
planId: values.planId,
planName: values.planName,
responseLevel: values.responseLevel,
responseLevelName: values.responseLevelName,
});
props.getCommandEvent.emit();
}
};
const onChangePlan = () => {
setIsActivatePlan(false);
form.setFieldsValue(info);
};
return (
<div className="select-emergency-plan">
<div className="container">
{
!isActivatePlan
? (
<>
<FormBuilder
span={24}
labelCol={{ span: 16 }}
options={[
{
name: "planId",
label: "企业预案",
render: FORM_ITEM_RENDER_ENUM.SELECT,
items: enterprisePlanList,
itemsField: {
labelKey: "planName",
valueKey: "id",
},
componentProps: {
disabled: Object.keys(info).length > 0,
onChange: (value) => {
if (value) {
getResponseLevelList(value);
form.setFieldValue("planName", getLabelName({
list: enterprisePlanList,
status: value,
nameKey: "planName",
idKey: "id",
}));
}
else {
setResponseLevelList([]);
}
},
},
},
{ name: "planName", label: "企业预案名称", onlyForLabel: true },
{
name: "responseLevel",
label: "响应级别",
render: FORM_ITEM_RENDER_ENUM.SELECT,
items: responseLevelList,
itemsField: { labelKey: "levelName", valueKey: "id" },
componentProps: {
onChange: (value) => {
form.setFieldValue("responseLevelName", getLabelName({
list: responseLevelList,
status: value,
nameKey: "levelName",
idKey: "id",
}));
},
},
},
{ name: "responseLevelName", label: "响应级别名称", onlyForLabel: true },
]}
form={form}
onFinish={onActivatePlan}
showActionButtons={false}
/>
<div style={{ textAlign: "center" }}>
<Space>
<Button type="primary" onClick={form.submit}>启用预案</Button>
</Space>
</div>
</>
)
: (
<div style={{ height: 144 }}>
<div>
<div>
<span>预案名称</span>
<span>{info.planName}</span>
</div>
<div>
<span>响应级别</span>
<span>{info.responseLevelName}</span>
</div>
</div>
<div style={{ textAlign: "center", marginTop: 16 }}>
<Space>
<Button type="primary" danger onClick={onChangePlan}>变更响应等级</Button>
</Space>
</div>
</div>
)
}
</div>
</div>
);
}
export default Connect([NS_ENTERPRISE_PLAN, NS_RESUE], true)(SelectEmergencyPlan);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -0,0 +1,56 @@
import useUrlState from "@ahooksjs/use-url-state";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { useEventEmitter } from "ahooks";
import { Button, message } from "antd";
import Page from "zy-react-library/components/Page";
import { NS_RESUE } from "~/enumerate/namespace";
import Cesium from "./components/Cesium";
import CommandFeedbackRecords from "./components/CommandFeedbackRecords";
import EventHandlingRecords from "./components/EventHandlingRecords";
import NonContingencyInstructions from "./components/NonContingencyInstructions";
import SelectEmergencyPlan from "./components/SelectEmergencyPlan";
import top from "./images/top.png";
import "./index.less";
function Command(props) {
const [urlState, setUrlState] = useUrlState({
id: "",
planId: "",
planName: "",
responseLevel: "",
responseLevelName: "",
}, { navigateMode: "replace" });
const getCommandEvent = useEventEmitter();
const onComplete = async () => {
const { success } = await props["rescueUpdateStatus"]({ id: urlState.id, isRescueExecuted: 4 });
if (success) {
message.success("完成救援成功");
props.history.goBack();
}
};
return (
<Page headerTitle="救援指挥" extraActionButtons={<Button type="primary" onClick={onComplete}>完成救援</Button>}>
<div className="command">
<div style={{ backgroundImage: `url(${top})` }} className="top">应急指挥台</div>
<div style={{ padding: "15px 10px", display: "flex", justifyContent: "space-between", gap: 10 }}>
<div style={{ width: 360 }}>
<SelectEmergencyPlan id={urlState.id} setUrlState={setUrlState} urlState={urlState} getCommandEvent={getCommandEvent} />
<CommandFeedbackRecords id={urlState.id} getCommandEvent={getCommandEvent} />
</div>
<div style={{ flex: 1, position: "relative" }}>
<Cesium urlState={urlState} />
</div>
<div style={{ width: 360 }}>
<NonContingencyInstructions id={urlState.id} planId={urlState.planId} getCommandEvent={getCommandEvent} />
<EventHandlingRecords id={urlState.id} planId={urlState.planId} />
</div>
</div>
</div>
</Page>
);
}
export default Connect([NS_RESUE], true)(Command);

View File

@ -0,0 +1,329 @@
.command {
background-color: #E5EDFD;
margin: -20px -20px -31px -20px;
.top {
background-size: 100% 100%;
background-repeat: no-repeat;
height: 66px;
width: 100%;
font-size: 36px;
color: #fff;
text-align: center;
line-height: 66px;
font-weight: bold;
}
.select-emergency-plan {
border-radius: 0 0 4px 4px;
background-image: linear-gradient(to bottom, #DAE9FA, #CFE5FF);
padding: 10px;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D1E1F9) 1;
.container {
border-radius: 2px;
background-color: #E4F0FF;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D9EFFD) 1;
box-shadow: inset 0 0 3px 0 rgba(49, 122, 202, 0.48);
padding: 15px;
}
}
.command-feedback-records {
margin-top: 10px;
border-radius: 0 0 4px 4px;
background-image: linear-gradient(to bottom, #DAE9FA, #CFE5FF);
padding: 10px;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D1E1F9) 1;
.title {
img {
width: 18px;
height: 18px;
}
span {
padding-left: 6px;
color: #222222;
font-size: 14px;
font-weight: bold;
}
}
.container {
padding-left: 20px;
.timeline-item {
position: relative;
padding-left: 20px;
margin-top: 10px;
&::before {
content: '';
position: absolute;
left: 10px;
top: 0;
bottom: -10px;
width: 2px;
background-color: #5B8CFF;
}
&:last-child::before {
bottom: 0;
}
.timeline-dot {
position: absolute;
left: 6px;
top: 15px;
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #5B8CFF;
background-color: #fff;
z-index: 1;
}
.parent {
.timeline-dot {
top: 15px;
}
}
}
.parent, .child {
margin-top: 10px;
border-radius: 2px;
background-color: rgb(255 255 255 / 0.41);
border-width: 1px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D9EFFD) 1;
padding: 10px;
.label {
color: #666666;
font-size: 14px;
}
}
}
}
.non-contingency-instructions {
border-radius: 0 0 4px 4px;
background-image: linear-gradient(to bottom, #DAE9FA, #CFE5FF);
padding: 5px;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D1E1F9) 1;
.title {
img {
width: 18px;
height: 18px;
}
span {
padding-left: 6px;
color: #222222;
font-size: 14px;
font-weight: bold;
}
}
.container {
.subtitle {
margin-left: 10px;
color: #3B445C;
font-size: 14px;
position: relative;
&::before {
content: '';
position: absolute;
left: -10px;
top: 7px;
bottom: 0;
width: 3px;
height: 13px;
background-color: #3796FF;
}
}
.table {
font-size: 13px;
margin-top: 5px;
text-align: center;
.header {
font-weight: bold;
display: grid;
grid-template-columns: 0.8fr 1fr 1fr 0.6fr;
.title {
color: #3B445C;
border: 1px solid #fff;
background-color: #C4E2F8;
}
}
.body {
border-top: none !important;
.row {
display: grid;
grid-template-columns: 0.8fr 1fr 1fr 0.6fr;
.cell {
border: 1px solid #fff;
}
}
}
}
}
}
.event-handling-records {
margin-top: 10px;
border-radius: 0 0 4px 4px;
background-image: linear-gradient(to bottom, #DAE9FA, #CFE5FF);
padding: 5px;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to top, #FFFFFF, #D1E1F9) 1;
.title {
img {
width: 18px;
height: 18px;
}
span {
padding-left: 6px;
color: #222222;
font-size: 14px;
font-weight: bold;
}
}
.container {
margin-top: 10px;
.time {
color: #222222;
font-weight: bold;
}
.content {
color: #444444;
}
.timeline-item {
position: relative;
padding-left: 20px;
margin-top: 10px;
&::before {
content: '';
position: absolute;
left: 10px;
top: 0;
bottom: -10px;
width: 2px;
background-color: #5B8CFF;
}
&:last-child::before {
bottom: 0;
}
.timeline-dot {
position: absolute;
left: 6px;
top: 7px;
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #5B8CFF;
background-color: #fff;
z-index: 1;
}
}
}
}
.cesium {
.form {
position: absolute;
top: 20px;
left: 20px;
z-index: 1;
width: 100%;
label {
color: #fff;
}
}
.mark-options {
display: flex;
justify-content: space-around;
gap: 25px;
position: absolute;
width: 100%;
bottom: 0;
&-item {
text-align: center;
cursor: pointer;
padding: 10px;
width: 194px;
height: 48px;
color: #3796FF;
font-size: 16px;
font-weight: bold;
position: relative;
background-size: 100% 100%;
background-repeat: no-repeat;
&-children {
position: absolute;
bottom: 55px;
left: 50%;
transform: translateX(-50%);
background-color: #D3E7FF;
width: 80%;
padding: 10px;
border-radius: 0 0 4px 4px;
border-width: 1px;
border-style: solid;
border-image: linear-gradient(to top, #1F89E3, #A2C3EA) 1;
&-item {
text-align: center;
cursor: pointer;
padding: 5px;
font-size: 14px;
font-weight: normal;
color: #000;
border: 1px solid transparent;
&.active{
color: #fff;
background-color: #3796FF;
border-radius: 0 0 4px 4px;
border-width: 1px;
border-style: solid;
border-image: linear-gradient(to top, #1F89E3, #A2C3EA) 1;
}
}
}
}
}
}
}

View File

@ -0,0 +1,147 @@
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Space } from "antd";
import dayjs from "dayjs";
import Page from "zy-react-library/components/Page";
import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table";
import useTable from "zy-react-library/hooks/useTable";
import { getLabelName } from "zy-react-library/utils";
import { NS_EVENT_REPORT, NS_RESUE } from "~/enumerate/namespace";
function List(props) {
const [form] = Search.useForm();
const { tableProps, getData } = useTable(props["eventReportList"], {
form,
params: { isEventOrRescue: 2 },
});
return (
<Page isShowAllAction={false}>
<Search
options={[
{ name: "ownerName", label: "机主姓名" },
]}
form={form}
onFinish={getData}
/>
<Table
columns={[
{ title: "接入电话", dataIndex: "incomingCall" },
{ title: "机主姓名", dataIndex: "ownerName" },
{ title: "接入方式", dataIndex: "accessModeName" },
{ title: "事件类型", dataIndex: "eventType" },
{ title: "接报时间", dataIndex: "reportTime" },
{
title: "救援状态",
dataIndex: "isRescueExecuted",
render: (_, record) => getLabelName({ list: [
{ bianma: 1, name: "未执行" },
{ bianma: 2, name: "未开始" },
{ bianma: 3, name: "进行中" },
{ bianma: 4, name: "已完成" },
], status: record.isRescueExecuted }),
},
{
title: "操作",
width: 200,
fixed: "right",
render: (_, record) => (
<Space>
{(record.isEventReportSpecial === 2 && props.permission("qyd-rescue-view")) && (
<Button
type="link"
onClick={() => {
props.history.push(`./view?id=${record.id}`);
}}
>
查看专报
</Button>
)}
{
(record.isRescueExecuted !== 4 && props.permission("qyd-rescue-command")) && (
<Button
type="link"
onClick={async () => {
const { success } = await props["rescueUpdateStatus"]({ id: record.id, isRescueExecuted: 3 });
if (success) {
const params = new URLSearchParams({
id: record.id || "",
planId: record.planId || "",
planName: record.planName || "",
responseLevel: record.responseLevel || "",
responseLevelName: record.responseLevelName || "",
eventTitle: record.eventTitle || "",
eventType: record.eventType || "",
occurrenceTime: record.occurrenceTime || "",
locationAddress: record.locationAddress || "",
});
props.history.push(`./command?${params.toString()}`);
}
}}
>
指挥
</Button>
)
}
{
(record.isRescueExecuted === 4 && props.permission("qyd-rescue-rescue-record")) && (
<Button
type="link"
onClick={() => {
const params = new URLSearchParams({
id: record.id || "",
eventTitle: record.eventTitle || "",
executorDeptName: record.executorDeptName || "",
executorName: record.executorName || "",
executionTime: record.executionTime ? dayjs(record.executionTime).format("YYYY-MM-DD HH:mm:ss") : "",
updateTime: record.updateTime ? dayjs(record.updateTime).format("YYYY-MM-DD HH:mm:ss") : "",
});
props.history.push(`./rescueRecord?${params.toString()}`);
}}
>
救援记录
</Button>
)
}
{
(record.isRescueExecuted === 4 && record.isEventReportSpecial === 1 && props.permission("qyd-rescue-special-report")) && (
<Button
type="link"
onClick={() => {
const params = new URLSearchParams({
id: record.id,
eventTitle: record.eventTitle,
accessMode: record.accessMode,
accessModeName: record.accessModeName,
ownerName: record.ownerName,
incomingCall: record.incomingCall,
eventType: record.eventType,
reportTime: record.reportTime,
occurrenceTime: record.occurrenceTime,
locationAddress: record.locationAddress,
longitude: record.longitude,
latitude: record.latitude,
});
props.history.push(`./specialReport?${params.toString()}`);
}}
>
生成专报
</Button>
)
}
</Space>
),
},
]}
{...
tableProps
}
/>
</Page>
)
;
}
export default Connect([NS_EVENT_REPORT, NS_RESUE], true)(Permission(List));

View File

@ -0,0 +1,69 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Divider } from "antd";
import Page from "zy-react-library/components/Page";
import Table from "zy-react-library/components/Table";
import TooltipPreviewImg from "zy-react-library/components/TooltipPreviewImg";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
import useTable from "zy-react-library/hooks/useTable";
import { NS_RESUE } from "~/enumerate/namespace";
function RescueRecord(props) {
const query = useGetUrlQuery();
const { tableProps: executionRecordTableProps } = useTable(props["rescueExecutionRecordList"], {
params: { id: query.id },
useStorageQueryCriteria: false,
});
const { tableProps: eventHandlingRecordTableProps } = useTable(props["rescueEventHandlingRecordList"], {
params: { id: query.id },
useStorageQueryCriteria: false,
});
return (
<Page headerTitle="救援记录" contentPadding="0 20px 20px 20px">
<Divider orientation="left">指挥相关数据</Divider>
<Descriptions
bordered
column={2}
styles={{ label: { width: 200 } }}
items={[
{ label: "事件标题", children: query.eventTitle, span: 2 },
{ label: "救援开始时间", children: query.executionTime },
{ label: "救援结束时间", children: query.updateTime },
{ label: "指挥人员部门", children: query.executorDeptName },
{ label: "指挥人员", children: query.executorName },
]}
/>
<Divider orientation="left">执行记录</Divider>
<Table
showIndexColumn={false}
columns={[
{ title: "编号", dataIndex: "commandNumber" },
{ title: "指令类型", dataIndex: "commandType" },
{ title: "指令内容", dataIndex: "commandContent" },
{ title: "执行机构", dataIndex: "executingAgencyName" },
{ title: "发布时间", dataIndex: "sendTime" },
{ title: "反馈时间", dataIndex: "feedbackTime" },
{ title: "反馈内容", dataIndex: "feedbackContent" },
{
title: "反馈照片",
dataIndex: "feedbackImageUrl",
render: (_, record) => (<TooltipPreviewImg files={record.feedbackImageUrl ? record.feedbackImageUrl.split(",") : []} />),
},
{ title: "完成状态", dataIndex: "commandStatus" },
]}
{...executionRecordTableProps}
/>
<Divider orientation="left">事件处置记录</Divider>
<Table
columns={[
{ title: "记录时间", dataIndex: "handlingTime" },
{ title: "记录内容", dataIndex: "handlingContent" },
]}
{...eventHandlingRecordTableProps}
/>
</Page>
);
}
export default Connect([NS_RESUE], true)(RescueRecord);

View File

@ -9,7 +9,7 @@ import DictionarySelect from "zy-react-library/components/Select/Dictionary";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
import { PHONE } from "zy-react-library/regular";
import { NS_EVENT_REPORT } from "~/enumerate/namespace";
import { NS_RESUE } from "~/enumerate/namespace";
function Add(props) {
const query = useGetUrlQuery();
@ -23,7 +23,7 @@ function Add(props) {
const { success } = await props["eventReportSpecialReportSave"]({
...values,
eventReportId: query.id,
regionCode: values.regionCode.join(","),
regionCode: values.regionCode?.join(","),
});
if (success) {
message.success("新增成功");
@ -34,10 +34,10 @@ function Add(props) {
return (
<Page headerTitle="生成专报" isShowFooter={false}>
<FormBuilder
loading={props.eventReport.eventReportSpecialReportLoading}
loading={props.rescue.rescueLoading}
useAutoGenerateRequired={false}
options={[
{ name: "eventTitle", label: "事件标题", span: 24 },
{ name: "eventTitle", label: "事件标题", span: 24, componentProps: { disabled: true } },
{ name: "ownerName", label: "机主姓名", componentProps: { disabled: true } },
{ name: "incomingCall", label: "呼入电话", componentProps: { disabled: true } },
{ name: "callerAddress", label: "主叫地址" },
@ -79,7 +79,7 @@ function Add(props) {
{ name: "reportTime", label: "接报时间", render: FORM_ITEM_RENDER_ENUM.DATETIME, componentProps: { disabled: true } },
{ name: "occurrenceTime", label: "发生时间", render: FORM_ITEM_RENDER_ENUM.DATETIME, componentProps: { disabled: true } },
{ name: "eventType", label: "事件类型", componentProps: { disabled: true } },
{ name: "locationAddress", label: "所在地址" },
{ name: "locationAddress", label: "所在地址", componentProps: { disabled: true } },
{ key: "map", customizeRender: true, span: 24, render: (<Map type="cesium" required={false} disable />) },
{ name: "reportType", label: "接报类型" },
{ name: "accidentTitle", label: "事故标题" },
@ -110,4 +110,4 @@ function Add(props) {
);
}
export default Connect([NS_EVENT_REPORT], true)(Add);
export default Connect([NS_RESUE], true)(Add);

View File

@ -0,0 +1,71 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Descriptions, Spin } from "antd";
import { useEffect, useState } from "react";
import Page from "zy-react-library/components/Page";
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
import { NS_RESUE } from "~/enumerate/namespace";
function View(props) {
const query = useGetUrlQuery();
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["eventReportSpecialReportInfo"]({ id: query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
return (
<Page headerTitle="查看">
<Spin spinning={props.rescue.rescueLoading}>
<Descriptions
bordered
column={2}
styles={{ label: { width: 200 } }}
items={[
{ label: "事件标题", children: info.eventTitle, span: 2 },
{ label: "机主姓名", children: info.ownerName },
{ label: "呼入电话", children: info.incomingCall },
{ label: "主叫地址", children: info.callerAddress },
{ label: "接入方式", children: info.accessModeName },
{ label: "姓名", children: info.personName },
{ label: "联系电话", children: info.contactPhone },
{ label: "其他信息", children: info.otherInfo, span: 2 },
{ label: "单位名称", children: info.unitName },
{ label: "所在区域", children: info.regionCodeName },
{ label: "单位地址", children: info.unitAddress },
{ label: "行业类型", children: info.industryType },
{ label: "经济类型", children: info.economyType },
{ label: "重大危险源", children: info.majorHazardSource },
{ label: "接报时间", children: info.reportTime },
{ label: "发生时间", children: info.occurrenceTime },
{ label: "事件类型", children: info.eventType },
{ label: "所在地址", children: info.locationAddress },
{ label: "经度", children: info.longitude },
{ label: "纬度", children: info.latitude },
{ label: "接报类型", children: info.reportType },
{ label: "事故标题", children: info.accidentTitle },
{ label: "事故级别", children: info.accidentLevel },
{ label: "伤害类型", children: info.injuryType },
{ label: "事故类型", children: info.accidentType },
{ label: "被困人数", children: info.trappedCount },
{ label: "失踪人数", children: info.missingCount },
{ label: "死亡人数", children: info.deathCount },
{ label: "重伤人数", children: info.seriouslyInjuredCount },
{ label: "轻伤人数", children: info.minorInjuryCount },
{ label: "中毒人数", children: info.poisonedCount },
{ label: "直接经济损失(万元)", children: info.directEconomicLoss },
{ label: "简要经过", children: info.briefProcess, span: 2 },
{ label: "处置情况", children: info.disposalSituation, span: 2 },
]}
/>
</Spin>
</Page>
);
}
export default Connect([NS_RESUE], true)(View);

View File

@ -0,0 +1,5 @@
function Rescue(props) {
return props.children;
}
export default Rescue;

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["closedCardPortInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["closedCardPortInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.closedCardPort.closedCardPortLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "卡口名称", children: info.checkpointName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["drainageWellInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["drainageWellInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.drainageWell.drainageWellLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "排水井名称", children: info.wellName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["emergencyShelterInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["emergencyShelterInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.emergencyShelter.emergencyShelterLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "避难所名称", children: info.placeName },

View File

@ -11,20 +11,23 @@ function View(props) {
const [info, setInfo] = useState({});
const getData = async () => {
const { data } = await props["materialEquipmentInfo"]({ id: query.id });
if (!props.id && !query.id)
return;
const { data } = await props["materialEquipmentInfo"]({ id: props.id || query.id });
setInfo(data);
};
useEffect(() => {
getData();
}, []);
}, [props.id]);
return (
<Page headerTitle="查看">
<Page headerTitle="查看" isShowAllAction={props.isShowAllAction}>
<Spin spinning={props.materialEquipment.materialEquipmentLoading}>
<Descriptions
bordered
column={2}
column={props.isShowAllAction === false ? 1 : 2}
styles={{ label: { width: 200 } }}
items={[
{ label: "资源库名称", children: info.warehouseName },