Merge remote-tracking branch 'origin/dev' into dev

pull/3/head
chenxinying 2024-02-29 08:47:15 +08:00
commit 3915c76463
42 changed files with 2014 additions and 1586 deletions

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
<title>危化安全生产管理平台</title>
<title>安全生产信息化平台</title>
</head>
<body>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 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.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -13,10 +13,10 @@ export const MODEL = {
export const MENU = [
{ title: "双重预防", model: MODEL["1"] },
{ title: "教育培训", model: MODEL["2"] },
{ title: "高危作业管理", model: MODEL["3"] },
{ title: "特殊作业", model: MODEL["3"] },
{ title: "监测预警", model: MODEL["4"] },
{ title: "综合管理", model: MODEL["5"] },
{ title: "定位管理", model: MODEL["6"] },
{ title: "人员定位", model: MODEL["6"] },
];
export const PRINT_STYLE =
'<style type="text/css" media="print">\n' +

View File

@ -4,10 +4,10 @@
<el-descriptions :column="1" border>
<el-descriptions-item label="隐患来源">
<span v-if="data.info.SOURCE === '1'"> </span>
<span v-else-if="data.info.SOURCE === '2'"> 隐患排</span>
<span v-else-if="data.info.SOURCE === '3'"> 隐患排</span>
<span v-else-if="data.info.SOURCE === '4'"> 安全环保检</span>
<span v-else-if="data.info.SOURCE === '5'"> 安全环保检</span>
<span v-if="data.info.SOURCE === '2'"> </span>
<span v-if="data.info.SOURCE === '3'"> </span>
<span v-if="data.info.SOURCE === '4'"> </span>
<span v-if="data.info.SOURCE === '5'"> </span>
</el-descriptions-item>
<template v-if="data.info.SOURCE === '2' && listType === '1'">
<el-descriptions-item label="风险点(单元)">
@ -252,38 +252,43 @@
</el-descriptions>
</template>
</template>
<template v-if="(data.info.SOURCE === '4' || data.info.SOURCE === '5') && data.info.FINAL_CHECK">
<template
v-if="
(data.info.SOURCE === '4' || data.info.SOURCE === '5') &&
data.info.FINAL_CHECK
"
>
<el-divider content-position="left">安全环保验收信息</el-divider>
<el-descriptions :column="1" border class="mt-10">
<el-descriptions-item label="验收描述">
{{ data.info.FINAL_CHECKDESCR }}
</el-descriptions-item>
<el-descriptions-item label="是否合格">
<span v-if="data.info.FINAL_CHECK === '1'"> </span>
<span v-else-if="data.info.FINAL_CHECK === '0'"> </span>
</el-descriptions-item>
<el-descriptions-item label="验收部门">
{{ data.info.FINAL_CHECKOR_NDEPTNAME }}
</el-descriptions-item>
<el-descriptions-item label="验收人">
{{ data.info.FINAL_CHECKOR_NAME }}
</el-descriptions-item>
<el-descriptions-item label="验收时间">
{{ data.info.FINAL_CHECKTIME }}
</el-descriptions-item>
<el-descriptions-item label="验收图片">
<img
v-for="item1 in data.yImgs"
:key="item1.IMGFILES_ID"
v-viewer
:src="VITE_FILE_URL + item1.FILEPATH"
alt=""
width="100"
height="100"
class="ml-10"
/>
</el-descriptions-item>
</el-descriptions>
<el-descriptions :column="1" border class="mt-10">
<el-descriptions-item label="验收描述">
{{ data.info.FINAL_CHECKDESCR }}
</el-descriptions-item>
<el-descriptions-item label="是否合格">
<span v-if="data.info.FINAL_CHECK === '1'"> </span>
<span v-else-if="data.info.FINAL_CHECK === '2'"> </span>
</el-descriptions-item>
<el-descriptions-item label="验收部门">
{{ data.info.FINAL_CHECKOR_NDEPTNAME }}
</el-descriptions-item>
<el-descriptions-item label="验收人">
{{ data.info.FINAL_CHECKOR_NAME }}
</el-descriptions-item>
<el-descriptions-item label="验收时间">
{{ data.info.FINAL_CHECKTIME }}
</el-descriptions-item>
<el-descriptions-item label="验收图片">
<img
v-for="item1 in data.yImgs"
:key="item1.IMGFILES_ID"
v-viewer
:src="VITE_FILE_URL + item1.FILEPATH"
alt=""
width="100"
height="100"
class="ml-10"
/>
</el-descriptions-item>
</el-descriptions>
</template>
</div>
</template>

View File

@ -0,0 +1,84 @@
<template>
<div id="bi_container">
<div id="map" class="map_bg"></div>
</div>
</template>
<script setup>
import { onBeforeUnmount, onMounted } from "vue";
import { initMap, handleViewAlarm, handleMouseClick } from "./map";
import { useUserStore } from "@/pinia/user.js";
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
const props = defineProps({
alarm: {
type: Object,
required: true,
default: null,
},
userList: {
type: Array,
required: true,
default: () => [],
},
});
const userStore = useUserStore();
const CORPINFO_ID = userStore.getUserInfo.CORPINFO_ID;
onMounted(async () => {
const corp = await getEnterpriseInfo({ CORPINFO_ID });
initMap(corp.pd);
handleMouseClick();
handleViewAlarm(props.alarm, props.userList);
});
onBeforeUnmount(() => {
window.$scene = null;
window.$icy = null;
window.$carmer = null;
});
</script>
<style scoped lang="scss">
#bi_container {
width: 100%;
height: 600px;
color: #ffffff;
position: relative;
font-size: 14px;
.map_bg {
width: 100%;
height: 540px;
}
.options {
margin-top: 10px;
display: flex;
align-items: center;
padding: 10px;
.option {
margin-right: 20px;
cursor: pointer;
text-align: center;
img {
width: 46px;
height: 46px;
}
.label {
margin-top: 10px;
font-size: 12px;
}
}
.id {
background-color: #1b284a;
padding: 10px;
border-radius: 4px;
height: 37px;
}
}
}
</style>

View File

@ -138,7 +138,7 @@ export const handleMouseClick = (model_id) => {
// 隐藏逻辑
$mouse.mouseLeft((model) => {
if (model._name === "建筑") {
model_id.value = model._id;
if (model_id) model_id.value = model._id;
clickBuilding(model);
}
});
@ -333,3 +333,72 @@ const addEntity = (id, name, lon, lat, height) => {
};
entities.add(obj);
};
export const handleViewAlarm = (alarm, userList) => {
const canvas = document.createElement("canvas");
const width = 100;
const height = 30;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = "#ff0000";
ctx.font = "normal bold 20px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("聚集告警", width / 2, height / 2);
// 聚集圆锥特效
const Cone = new window.CustomCesium.Cone(window.$icy);
Cone.add(
[alarm.lon, alarm.lat, alarm.alt], // 坐标
alarm.color, // 圆锥颜色
{ width: 20, height: 40 }, // 圆锥的宽高
canvas, // 圆锥铭牌
"100201", // 圆锥实体id
"10020101" // 铭牌实体id
);
const labelPixelOffset = new window.Cesium.Cartesian2(0, -55);
userList.forEach((user) => {
const obj = {};
obj.entity = window.$icy.viewer.entities.add(
new window.Cesium.Entity({
id: "user_" + user.card,
name: user.psnName,
position: window.Cesium.Cartesian3.fromDegrees(
user.lon,
user.lat,
user.alt
),
billboard: {
image: "src/assets/images/map/peoIcon_blueImg.png",
height: 36,
width: 30,
verticalOrigin: window.Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: window.Cesium.HorizontalOrigin.CENTER,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
label: {
text: user.psnName,
font: "13px sans-serif",
pixelOffset: labelPixelOffset,
showBackground: true,
// 地图上扎点的名字背景色
// eslint-disable-next-line new-cap
backgroundColor: new window.Cesium.Color.fromCssColorString(
"rgba(20, 58, 142, 1)"
),
backgroundPadding: new window.Cesium.Cartesian2(7, 5),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
})
);
obj.show = (e) => {
obj.entity.show = e;
};
obj.destroy = () => {
window.$icy.viewer.entities.remove(obj.entity);
};
});
};

View File

@ -4,7 +4,7 @@
<div class="logo" />
<div class="menu">
<ul>
<li @click="router.push({ path: '/large_screen_data_display' })">
<li @click="fnNavigationBI">
<div class="title">BI</div>
</li>
<template v-for="(item, index) in MENU" :key="index">
@ -79,6 +79,7 @@ defineOptions({
name: "LayoutHeader",
});
const FILE_URL = import.meta.env.VITE_FILE_URL;
let notify;
const router = useRouter();
const menuStore = useMenuStore();
const userStore = useUserStore();
@ -156,7 +157,7 @@ const fnSignOut = async () => {
const fnSpecialOperationsWarnAmount = async () => {
const resData = await getSpecialOperationsWarnAmount();
if (resData.message) {
ElNotification({
notify = ElNotification({
title: "温馨提示",
dangerouslyUseHTMLString: true,
message: resData.message,
@ -166,6 +167,10 @@ const fnSpecialOperationsWarnAmount = async () => {
}
};
fnSpecialOperationsWarnAmount();
const fnNavigationBI = () => {
notify && notify.close();
router.push({ path: "/large_screen_data_display" });
};
</script>
<style lang="scss" scoped>

View File

@ -2,9 +2,13 @@ import { post } from "@/request/axios.js";
export const getGatheringAlarmRecordsList = (params) =>
post("/positAlarm/getAlarmRecordList", params); // 聚集告警记录列表
export const getGatheringAlarmRecordViewList = (params) =>
post("/positAlarm/alarmRecordgoEdit", params); // 聚集告警记录详情
export const getAggregationAlarmTrend = (params) =>
post("/positAlarm/aggregateAlarmTrends", params); // 聚集报警趋势
export const getAggregatedDataStatistics = (params) =>
post("/positAlarm/aggregateDataStatistics", params); // 聚集区域统计
export const getAggregationAreaStatistics = (params) =>
post("/positAlarm/aggregateDataStatisticsByGroup", params); // 聚集数据统计
export const getAlarmGatherPsnInfo = (params) =>
post("/positAlarm/getAlarmGatherPsnInfo", params); // 聚集告警内人员列表

View File

@ -20,7 +20,7 @@ export const getEnterpriseReport2 = (params) =>
export const getEnterpriseReport3 = (params) =>
post("/studytask/list?showCount=100&currentPage=1", params);
export const getEnterpriseReport4 = (params) =>
post("/confinedspace/getDiagnosis", params);
post("/eightWork/getDiagnosis", params);
export const getEnterpriseReport5 = (params) =>
post("/performanceexamine_dept/listAll", params);
export const getEnterpriseReport6 = (params) =>

View File

@ -154,7 +154,7 @@ const bottomOptionsList = [
img: new URL("/src/assets/images/map/bico2.png", import.meta.url).href,
imgSelect: new URL("/src/assets/images/map/bico2_on.png", import.meta.url)
.href,
title: "安全作业",
title: "特殊作业",
type: "workSafely",
check: false,
components: [markRaw(WorkSafely)],

View File

@ -129,7 +129,8 @@ const {
currentData[0],
currentData[1]
)
: undefined
: undefined,
1000 / data.speed
);
},
});
@ -156,10 +157,10 @@ const fnGetData = async () => {
ElMessage.warning("请选择时间");
return;
}
hadleDestroy();
data.positions = [];
pause();
reset();
hadleDestroy();
await getTrajectoriesData(
data.searchForm.personnel,
data.searchForm.dates[0],
@ -209,7 +210,7 @@ const fnPause = () => {
};
onBeforeUnmount(() => {
console.log("onBeforeUnmount");
pause();
hadleDestroy();
});
</script>

View File

@ -76,44 +76,7 @@ const data = reactive({
},
],
eleType: 0,
block2OptionsList: [
{
label: "滞留报警",
count: 0,
},
{
label: "越界报警",
count: 235,
},
{
label: "超员报警",
count: 569,
},
{
label: "缺员报警",
count: 569,
},
{
label: "静止报警",
count: 423,
},
{
label: "串岗报警",
count: 789,
},
{
label: "一键告警",
count: 236,
},
{
label: "聚集告警",
count: 214,
},
{
label: "作业告警",
count: 852,
},
],
block2OptionsList: [],
block3List: [
{
name: "赵一诺",

View File

@ -16,7 +16,7 @@
</template>
<script setup>
import { reactive } from "vue";
import { reduction } from "../js/map";
import { flyTo, reduction } from "../js/map";
import { useFullscreen, useVModel } from "@vueuse/core";
const props = defineProps({
@ -53,6 +53,7 @@ const data = reactive({
.href,
check: false,
label: "返回中心点",
action: flyTo,
},
{
img: new URL("/src/assets/images/map/rico4.png", import.meta.url).href,

View File

@ -1,7 +1,7 @@
<template>
<div class="container">
<div class="block1">
<layout-title title="安全作业状态统计" />
<layout-title title="特殊作业状态统计" />
<div class="option">
<div
v-for="(item, index) in data.block1OptionsList"
@ -18,11 +18,11 @@
</div>
<div class="block2">
<layout-title title="安全作业情况统计" />
<layout-title title="特殊作业情况统计" />
<div id="main1" class="option"></div>
</div>
<div class="block3">
<layout-title title="安全作业记录" />
<layout-title title="特殊作业记录" />
<div class="option">
<div class="table">
<div class="tr">

View File

@ -57,10 +57,8 @@ function echarts1(id, legend, echartCount) {
type: "shadow",
},
axisLabel: {
textStyle: {
color: "#B3CFFF", // x轴文本颜色
fontSize: 10,
},
color: "#B3CFFF", // x轴文本颜色
fontSize: 10,
formatter(params) {
// const res = xWrapText(params, 6);
xWrapText(params, 6);
@ -84,10 +82,8 @@ function echarts1(id, legend, echartCount) {
},
axisLabel: {
formatter: "{value}%",
textStyle: {
color: "#B3CFFF", // x轴文本颜色
fontSize: 12,
},
color: "#B3CFFF", // x轴文本颜色
fontSize: 12,
},
name: "",
nameTextStyle: {
@ -119,7 +115,7 @@ function echarts1(id, legend, echartCount) {
opacity: 1,
},
]),
barBorderRadius: [0, 0, 0, 0],
borderRadius: [0, 0, 0, 0],
},
data: echartCount,
},
@ -148,7 +144,7 @@ function echarts1(id, legend, echartCount) {
opacity: 1,
},
]),
barBorderRadius: [0, 0, 0, 0],
borderRadius: [0, 0, 0, 0],
},
data: echartCount,
barGap: 0,

View File

@ -34,10 +34,8 @@ function echarts2(id, month, accumulated, currentMonth) {
},
axisLabel: {
// 坐标轴刻度标签的相关设置
textStyle: {
color: "#d1e6eb",
margin: 15,
},
color: "#d1e6eb",
margin: 15,
interval: 0,
rotate: 30,
},
@ -60,13 +58,11 @@ function echarts2(id, month, accumulated, currentMonth) {
},
},
axisLine: {
show: false,
show: true,
},
axisLabel: {
margin: 20,
textStyle: {
color: "#d1e6eb",
},
color: "#d1e6eb",
},
axisTick: {
show: false,
@ -120,7 +116,7 @@ function echarts2(id, month, accumulated, currentMonth) {
type: "bar",
barWidth: 20,
tooltip: {
show: false,
show: true,
},
itemStyle: {
color: "#1492FF",

View File

@ -52,12 +52,8 @@ function echarts4(id) {
axisLabel: {
show: true,
// rotate: -1,
textStyle: {
fontSize: 14,
// fontFamily: PangMenZhengDao,
color: "#fff",
},
fontSize: 14,
color: "#fff",
},
axisTick: {
show: false,
@ -93,11 +89,8 @@ function echarts4(id) {
},
axisLabel: {
show: true,
textStyle: {
fontSize: 12,
// fontFamily: PangMenZhengDao,
color: "#ffffff",
},
fontSize: 12,
color: "#ffffff",
},
splitArea: {
areaStyle: {
@ -187,8 +180,9 @@ function echarts4(id) {
return colorList[params.dataIndex];
},
opacity: 0.7,
// 鼠标移入柱子上 透明度变为 1
emphasis: {
},
emphasis: {
itemStyle: {
opacity: 1,
},
},

View File

@ -41,10 +41,8 @@ function echarts2(id, data) {
},
axisLabel: {
// 坐标轴刻度标签的相关设置
textStyle: {
color: "#d1e6eb",
margin: 15,
},
color: "#d1e6eb",
margin: 15,
},
axisTick: {
show: false,
@ -69,9 +67,7 @@ function echarts2(id, data) {
},
axisLabel: {
margin: 20,
textStyle: {
color: "#d1e6eb",
},
color: "#d1e6eb",
},
axisTick: {
show: false,

View File

@ -30,11 +30,11 @@ const showHotworkList = async () => {
hotworkList,
HOTWORK_ID,
"动火作业",
CHECK_NO,
'动火作业:'+CHECK_NO,
WORK_POSITION.split(",")[0],
WORK_POSITION.split(",")[1],
WORK_POSITION.split(",")[2],
"/src/assets/images/map/bottom/ico4_on.png"
"/src/assets/images/map/bottom/ico1_select.png"
);
});
hotworkList.show(true);
@ -61,11 +61,11 @@ const showConfinedspaceWorkList = async () => {
confinedspaceList,
CONFINEDSPACE_ID,
"受限空间作业",
CHECK_NO,
'受限空间作业:'+CHECK_NO,
WORK_POSITION.split(",")[0],
WORK_POSITION.split(",")[1],
WORK_POSITION.split(",")[2],
"/src/assets/images/map/bottom/ico5_on.png"
"/src/assets/images/map/bottom/ico2_select.png"
);
});
confinedspaceList.show(true);
@ -92,11 +92,11 @@ const showHighWorkList = async () => {
highWorkList,
HIGHWORK_ID,
"高处作业",
CHECK_NO,
'高处作业:'+CHECK_NO,
WORK_POSITION.split(",")[0],
WORK_POSITION.split(",")[1],
WORK_POSITION.split(",")[2],
"/src/assets/images/map/bottom/ico7_on.png"
"/src/assets/images/map/bottom/ico4_select.png"
);
});
highWorkList.show(true);

View File

@ -100,16 +100,16 @@ export const showLine = (positions) => {
* entityArr 接收人物模型分组
* billboardArr 接收人物铭牌分组
*/
export const peoMovement = (id, lon, lat, height, alt) => {
export const peoMovement = (id, lon, lat, height, alt,speed) => {
entityArr.children.forEach((b, m) => {
if (b.entity._id === id) {
b.updateAngle([alt, 0, 0]); // 改变人物朝向
b.animationMove(lon, lat, height, 1000, () => {}); // 人物平滑移动
b.animationMove(lon, lat, height, speed, () => {}); // 人物平滑移动
billboardArr.children[m].animationMove(
lon,
lat,
Number(Number(height) + 2.05),
1000
speed
); // 人物铭牌平滑移动
} else {
console.log(`人物移动数据错误`);

View File

@ -18,6 +18,8 @@ import { getVideoManagerView } from "@/request/video_manager.js";
const loadMap = 3;
let $entityTransparent = [];
const clickModel = new Map();
let centerLon = 0;
let centerLat = 0;
export const initMap = (corp) => {
window.$scene = new window.CustomCesium.Scene(
"map",
@ -36,7 +38,9 @@ export const initMap = (corp) => {
),
});
const [wgsLat, wgsLon] = bd09ToWgs84(corp.LATITUDE, corp.LONGITUDE);
flyTo(wgsLon, wgsLat);
centerLon = wgsLon;
centerLat = wgsLat;
flyTo();
// 亮度设置
const stages = window.$icy.viewer.scene.postProcessStages;
window.$icy.viewer.scene.brightness =
@ -127,13 +131,12 @@ const transformlng = (lng, lat) => {
return ret;
};
// eslint-disable-next-line no-unused-vars
const flyTo = (lng, lat) => {
export const flyTo = () => {
window.$carmer.flyTo({
// 视角飞入
maxHeight: 1500,
time: 1,
position: [lng, lat, 200],
position: [centerLon, centerLat, 200],
angle: [0, -60, 0],
});
};

View File

@ -25,6 +25,11 @@ const { open, close } = useWebSocket(
const msg = unzip(event.data);
const decodedMsg = JSON.parse(decodeURIComponent(msg));
if (decodedMsg.msg === "000") {
console.log(decodedMsg.data);
// decodedMsg.data = [
// "8379,119.447708695738,39.918422294137,-232.39015608699566,0.12000000000000001,,1,0,大大",
// "9979,119.447611105937,39.918443403627,-343.76932562302534,0.12000000000000001,9979,1,0,测试一",
// ];
peoMovement(decodedMsg.data);
}
if (decodedMsg.msg === "006") {
@ -32,7 +37,7 @@ const { open, close } = useWebSocket(
}
},
onDisconnected: () => {
if (entityArr) {
if (entityArr && entityArr.children) {
entityArr.children.forEach((e) => {
e.destroy();
});
@ -159,25 +164,32 @@ const unzip = (b64Data) => {
function peoMovement(moveData) {
const map = new Map();
moveData.forEach((i, n) => {
let addFlag = false;
map.set(i.split(",")[0], n);
if (!entityArr || !entityArr.children) {
addFlag = true;
entityArr = new window.CustomCesium.GroupModel("人物模型");
billboardArr = new window.CustomCesium.GroupModel("人物姓名");
const entity = i.split(",");
console.log(entity[0], 111111);
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
}
entityArr.children.forEach((b, m) => {
if (!b.entity) {
addFlag = true;
const entity = i.split(",");
console.log(entity[0], 2222222);
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
return;
}
const index = map.get(b.entity._id);
const item = moveData[index];
if (index !== undefined) {
const entity = i.split(",");
if (index !== undefined && entity[0] === b.entity._id) {
addFlag = true;
const itData = item.split(","); // itData下标0=【卡号】1,24=【lonlatalt】3=【人物朝向角度】5=【工号】6=【当前楼层】
if (itData[4] != null && itData.length >= 6) {
b.updateAngle([itData[3], 0, 0]); // 改变人物朝向
@ -185,24 +197,27 @@ function peoMovement(moveData) {
itData[1],
itData[2],
Number(itData[4]),
2000,
1000,
() => {}
); // 人物平滑移动
billboardArr.children[m].animationMove(
itData[1],
itData[2],
Number(Number(itData[4]) + 2.05),
2000
1000
); // 人物铭牌平滑移动
} else {
console.log(`人物移动数据错误,错误参数:'${item}'`);
}
} else {
const entity = i.split(",");
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
}
});
if (!addFlag) {
const entity = i.split(",");
console.log(entity[0], 333333);
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
}
});
}

View File

@ -0,0 +1,42 @@
<template>
<el-dialog v-model="visible" title="告警信息" :on-close="fnClose">
<alarmView
v-if="visible"
:alarm="props.alarm"
:user-list="props.userList"
/>
<template #footer>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import { useVModels } from "@vueuse/core";
import alarmView from "@/components/map_tools/alarm_view";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
alarm: {
type: Object,
required: true,
default: null,
},
userList: {
type: Array,
required: true,
default: () => [],
},
});
const emits = defineEmits(["update:visible", "get-data"]);
const { visible } = useVModels(props, emits);
const fnClose = () => {
visible.value = false;
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,157 @@
<template>
<el-dialog v-model="visible" title="详情" :on-close="fnClose" width="80%">
<el-form
:model="searchForm"
label-width="80px"
@submit.prevent="fnResetPaginationTransfer"
>
<el-row>
<el-col :span="6">
<el-form-item label="检查周期" prop="dates">
<el-date-picker
v-model="searchForm.dates"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD HH:mm:ss"
time-format="A hh:mm:ss"
range-separator="至"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPaginationTransfer">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
<layout-card>
<layout-table
v-model:pagination="pagination"
:data="list"
@get-data="fnGetDataTransfer"
>
<el-table-column label="序号" width="70">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column label="聚集等级" prop="level">
<template #default="{ row }">
<span v-if="row.level === '1'"></span>
</template>
</el-table-column>
<el-table-column label="聚集人员" prop="psnName" />
<el-table-column label="时间" prop="alarmTime" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button type="primary" text link @click="fnViewLocation(row)"
>查看位置</el-button
>
</template>
</el-table-column>
</layout-table>
</layout-card>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"></el-button>
</template>
</el-dialog>
<alarm_dialog
v-model:visible="data.alarmDialogDialog.visible"
:alarm="data.alarmDialogDialog.alarm"
:user-list="data.alarmDialogDialog.userList"
@get-data="fnResetPagination"
/>
</template>
<script setup>
import { useVModels } from "@vueuse/core";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import { serialNumber } from "@/assets/js/utils.js";
import useListData from "@/assets/js/useListData.js";
import {
getAlarmGatherPsnInfo,
getGatheringAlarmRecordViewList,
} from "@/request/aggregation_management.js";
import alarm_dialog from "./alarmDialog.vue";
import { reactive } from "vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
});
const data = reactive({
alarmDialogDialog: {
alarm: null,
userList: null,
visible: false,
},
});
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
const { visible } = useVModels(props, emits);
const { list, searchForm, pagination, fnGetData, fnResetPagination } =
useListData(getGatheringAlarmRecordViewList, {
otherParams: {
gatherId: props.form.id,
STARTTIME: props.form.startTime,
ENDTIME: props.form.endTime,
},
key: "rows",
});
const fnClose = () => {
visible.value = false;
};
const fnGetDataTransfer = () => {
fnGetData({
STARTTIME: searchForm.value.dates[0]
? searchForm.value.dates[0]
: props.form.value.dates[0],
ENDTIME: searchForm.value.dates?.[1]
? searchForm.value.dates[1]
: props.form.value.dates[1],
gatherId: props.form.id,
});
};
const fnViewLocation = async (row) => {
const res = await getAlarmGatherPsnInfo({ id: row.id });
data.alarmDialogDialog.alarm = row;
data.alarmDialogDialog.userList = res.data;
data.alarmDialogDialog.visible = true;
};
const fnResetPaginationTransfer = () => {
fnResetPagination({
STARTTIME: searchForm.value.dates?.[0],
ENDTIME: searchForm.value.dates?.[1],
gatherId: props.form.id,
});
};
const fnSubmit = debounce(
1000,
async () => {
ElMessage.success("处理成功");
fnClose();
emits("get-data");
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -34,30 +34,56 @@
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column label="聚集地点" prop="regName" />
<el-table-column label="开始时间" prop="regName" />
<el-table-column label="结束时间" prop="regName" />
<el-table-column label="状态" prop="regName" />
<el-table-column label="状态" prop="status">
<template #default="{ row }">
{{ row.status === "1" ? "已处理" : "待处理" }}
</template>
</el-table-column>
<el-table-column label="聚集地点" prop="layerGroup" />
<el-table-column label="开始时间" prop="startTime" />
<el-table-column label="结束时间" prop="endTime" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
{{ row }}
<el-button type="primary" text link @click="fnShowInfo(row)"
>查看详情</el-button
>
</template>
</el-table-column>
</layout-table>
</layout-card>
</div>
<view-info
v-if="data.viewDialog.visible"
v-model:visible="data.viewDialog.visible"
v-model:form="data.viewDialog.form"
/>
</template>
<script setup>
import useListData from "@/assets/js/useListData.js";
import ViewInfo from "./components/viewInfo.vue";
import { serialNumber } from "@/assets/js/utils.js";
import { getGatheringAlarmRecordsList } from "@/request/aggregation_management.js";
import { reactive } from "vue";
const { list, searchForm, pagination, fnGetData, fnResetPagination } =
useListData(getGatheringAlarmRecordsList, {
otherParams: { status: "" },
key: "rows",
});
const data = reactive({
viewDialog: {
visible: false,
form: {
dates:[]
},
},
});
const fnShowInfo = (row) => {
data.viewDialog.visible = true;
data.viewDialog.form = row;
};
</script>
<style scoped lang="scss"></style>

View File

@ -234,13 +234,13 @@
<el-radio v-model="data.form.FOURTYPE" :label="1">
平面四色图
</el-radio>
<el-radio
v-model="data.form.FOURTYPE"
:label="2"
@change="fnProhibitSelect"
>
3D图
</el-radio>
<!-- <el-radio-->
<!-- v-model="data.form.FOURTYPE"-->
<!-- :label="2"-->
<!-- @change="fnProhibitSelect"-->
<!-- >-->
<!-- 3D图-->
<!-- </el-radio>-->
</el-form-item>
</el-col>
<el-col v-if="data.form.FOURTYPE === 1" :span="24">

View File

@ -32,14 +32,6 @@ const fnInitEcharts = (data) => {
type: "shadow",
},
},
legend: {
data: ["各培训类型学习人数"],
top: "15",
textStyle: {
color: "#2aaef2",
},
orient: "horizontal",
},
grid: {
top: "25%",
right: "3%",

View File

@ -65,9 +65,7 @@ const fnInitEcharts = (data) => {
},
axisLabel: {
interval: 0,
textStyle: {
color: "#fff",
},
color: "#fff",
fontSize: 12,
margin: 15,
},
@ -87,9 +85,7 @@ const fnInitEcharts = (data) => {
},
},
axisLabel: {
textStyle: {
color: "#fff",
},
color: "#fff",
},
splitLine: {
show: false,

View File

@ -29,17 +29,46 @@
<div>
<div class="dunpai1" />
<div class="bottom_title">现场排查数</div>
<div id="main1" />
<el-progress
:percentage="
typeList.filter((item) => item.NAME === '现场清单')[0].percentage
"
color="#ec2c26"
text-inside
:stroke-width="20"
>
{{ typeList.filter((item) => item.NAME === "现场清单")[0].count }}
</el-progress>
</div>
<div>
<div class="dunpai2" />
<div class="bottom_title">基础排查数</div>
<div id="main2" />
<el-progress
:percentage="
typeList.filter((item) => item.NAME === '基础类清单')[0]
.percentage
"
color="#ea4e26"
text-inside
:stroke-width="20"
>
{{ typeList.filter((item) => item.NAME === "基础类清单")[0].count }}
</el-progress>
</div>
<div>
<div class="dunpai3" />
<div class="bottom_title">综合排查数</div>
<div id="main3" />
<el-progress
:percentage="
typeList.filter((item) => item.NAME === '综合类清单')[0]
.percentage
"
color="#ea6e27"
text-inside
:stroke-width="20"
>
{{ typeList.filter((item) => item.NAME === "综合类清单")[0].count }}
</el-progress>
</div>
</div>
</div>
@ -47,18 +76,21 @@
</template>
<script setup>
import { onMounted, ref } from "vue";
import { ref } from "vue";
import {
getTroubleshootingTypeEcharts,
getTroubleshootingTypeNumber,
} from "@/request/large_screen_data_display.js";
import { sumBy } from "lodash-es";
import { arrayObjectDeduplication } from "@/assets/js/utils.js";
import * as echarts from "echarts";
import CountTo from "vue-countup-v3";
const info = ref({});
const typeList = ref([
{ count: 0, percentage: 0, NAME: "现场清单" },
{ count: 0, percentage: 0, NAME: "基础类清单" },
{ count: 0, percentage: 0, NAME: "综合类清单" },
]);
const fnGetData = async () => {
const resDataNumber = await getTroubleshootingTypeNumber();
resDataNumber.typeList.forEach((item) => {
@ -66,73 +98,15 @@ const fnGetData = async () => {
});
const resDataEcharts = await getTroubleshootingTypeEcharts();
const total = sumBy(resDataEcharts.typeList, (item) => item.count);
const key = {
现场清单: { color: "#ec2c26", el: "#main1" },
基础类清单: { color: "#ea4e26", el: "#main2" },
综合类清单: { color: "#ea6e27", el: "#main3" },
};
const typeList = [
...resDataEcharts.typeList,
{ count: 0, NAME: "现场清单" },
{ count: 0, NAME: "基础类清单" },
{ count: 0, NAME: "综合类清单" },
];
arrayObjectDeduplication(typeList, "NAME").forEach((item) => {
fnInitEcharts(item.count, total, key[item.NAME].color, key[item.NAME].el);
resDataEcharts.typeList.forEach((item) => {
item.percentage = (item.count / total) * 100;
});
typeList.value = arrayObjectDeduplication(
[...resDataEcharts.typeList, ...typeList.value],
"NAME"
);
};
onMounted(() => {
fnGetData();
});
const fnInitEcharts = (count, total, color, el) => {
const myChart = echarts.init(document.querySelector(el));
const option = {
grid: {
left: "10%",
right: "0%",
bottom: "0%",
top: "100%",
containLabel: true,
},
xAxis: {
show: false,
type: "value",
},
yAxis: {
type: "category",
show: false,
},
series: [
{
name: "次数",
type: "bar",
zlevel: 1,
itemStyle: {
barBorderRadius: 0,
color,
},
label: {
show: true,
position: "inside",
},
barWidth: 15,
data: [count],
},
{
name: "背景",
type: "bar",
barWidth: 15,
barGap: "-100%",
data: [total],
itemStyle: {
color: "#101f48",
barBorderRadius: 0,
},
},
],
};
myChart.setOption(option);
};
fnGetData();
</script>
<style scoped lang="scss">
@ -199,11 +173,9 @@ const fnInitEcharts = (count, total, color, el) => {
}
}
#main1,
#main2,
#main3 {
.el-progress {
margin-left: 10px;
flex: 1;
height: 20px;
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<div class="login">
<div class="main">
<div class="title">危化安全生产管理平台</div>
<div class="title">安全生产信息化平台</div>
<div class="form">
<el-form
ref="formRef"

View File

@ -148,11 +148,9 @@ import { ElMessage, ElMessageBox } from "element-plus";
import { nextTick, reactive } from "vue";
import LayoutImportFile from "@/components/import_file/index.vue";
import Add from "./components/add.vue";
// import { useRouter } from "vue-router";
import QrCode from "./components/qr_code.vue";
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
// const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
useListData(getIdentifyingPartsList);
const data = reactive({