<template>
|
<div class="dataScreen-container" :class="currentTheme">
|
<div class="dataScreen-content" ref="dataScreenRef" style="padding: 0; margin: 0; border: none">
|
<Mars3DMap
|
ref="marsMap"
|
v-if="configLoaded"
|
:mapconfig="mapConfigs"
|
@map-loaded="onMapLoaded"
|
:showfence="marsHome.showfence"
|
:showanchor="marsHome.showanchor"
|
:showlayer="marsHome.layer"
|
:mapcolor="marsHome.mapcolor"
|
:showthree-map="marsHome.threemap"
|
class="map"
|
/>
|
<div class="dataScreen-header">
|
<div class="header-lf">
|
<el-text checked style="display: inline-block; height: 14px; margin-top: 35px; margin-left: 50px">
|
<span class="gradient-text celltext" style="z-index: 9">{{ $t("screen.engineTime") }}:{{ time }}</span>
|
</el-text>
|
</div>
|
<div class="header-ct">
|
<div class="header-ct-title cellTitle">
|
<span>{{ systemName }}</span>
|
</div>
|
</div>
|
<div class="header-rg">
|
<el-text checked style="display: inline-block; height: 14px; margin-top: 35px; margin-right: 25px">
|
<el-icon class="gradient-icon celltext" style="margin-right: 5px"><Avatar /></el-icon>
|
<span style="position: relative; top: -2px" class="gradient-text celltext">
|
{{ $t("screen.user") }}:{{ user.username }}
|
</span>
|
</el-text>
|
<el-dropdown
|
@command="handleCommand"
|
style="position: relative; top: 38px; margin-right: 45px; cursor: pointer; border: none"
|
>
|
<el-text checked style="height: 14px">
|
<el-icon class="gradient-icon celltext" style="margin-right: 5px"><Menu /></el-icon>
|
<span style="" class="gradient-text celltext">{{ $t("screen.backend") }}</span>
|
<el-icon class="gradient-icon celltext" style="margin-left: 5px"><ArrowDown /></el-icon>
|
</el-text>
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item command="backend">
|
<el-icon><Menu /></el-icon>
|
{{ $t("screen.enterBackend") }}
|
</el-dropdown-item>
|
<el-dropdown-item command="logout" divided>
|
<el-icon><SwitchButton /></el-icon>
|
{{ $t("header.logout") }}
|
</el-dropdown-item>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
</div>
|
</div>
|
<div class="dataScreen-main">
|
<div class="dataScreen-lf" style="z-index: 999">
|
<div class="dataScreen-top" v-if="Panel">
|
<div class="dataScreen-main-title">
|
<span>
|
<span><el-image style="position: relative; top: 10px; width: 30px; height: 30px" :src="warninfo" /></span>
|
<span style="margin: 0 10px" class="cellhead">{{ $t("screen.alarmInfo") }}</span>
|
<span style="float: right" @click="dialogVisibleWarning = true">
|
<el-tooltip :content="$t('screen.more')" placement="top" effect="light">
|
<el-image
|
style="position: relative; top: -7px; right: 20px; width: 30px; height: 8px; cursor: pointer"
|
:src="gengduo"
|
/>
|
</el-tooltip>
|
</span>
|
</span>
|
</div>
|
<div class="dataScreen-main-chart">
|
<warningInfo />
|
</div>
|
</div>
|
<div class="dataScreen-bottom" v-if="Panel">
|
<div class="dataScreen-main-title">
|
<span>
|
<span><el-image style="position: relative; top: 10px; width: 30px; height: 30px" :src="personinfo" /></span>
|
<span style="margin: 0 10px" class="cellhead">{{ $t("screen.personStats") }}</span>
|
<span style="float: right" @click="dialogVisiblePerson = true">
|
<el-tooltip :content="$t('screen.more')" placement="top" effect="light">
|
<el-image
|
style="position: relative; top: -7px; right: 20px; width: 30px; height: 8px; cursor: pointer"
|
:src="gengduo"
|
/>
|
</el-tooltip>
|
</span>
|
</span>
|
</div>
|
<div class="dataScreen-main-chart">
|
<messageInfo @personPostionClick="handlePersonPositionClick" />
|
</div>
|
</div>
|
</div>
|
|
<div class="dataScreen-rg" style="z-index: 999">
|
<div class="dataScreen-top" v-if="Panel">
|
<div class="dataScreen-main-title">
|
<span>
|
<span><el-image style="position: relative; top: 10px; width: 30px; height: 30px" :src="countinfo" /></span>
|
<span style="margin: 0 10px" class="cellhead">{{ $t("screen.realTimeStats") }}</span>
|
<span style="float: right" @click="dialogVisibleWarning = true">
|
<el-tooltip :content="$t('screen.more')" placement="top" effect="light">
|
<el-image
|
style="position: relative; top: -7px; right: 20px; width: 30px; height: 8px; cursor: pointer"
|
:src="gengduo"
|
/>
|
</el-tooltip>
|
</span>
|
</span>
|
</div>
|
<div class="dataScreen-main-chart">
|
<dayCount />
|
</div>
|
</div>
|
|
<div class="dataScreen-bottom" v-if="Panel">
|
<div class="dataScreen-main-title">
|
<span>
|
<span><el-image style="position: relative; top: 10px; width: 30px; height: 30px" :src="kaoqininfo" /></span>
|
<span style="margin: 0 10px" class="cellhead">{{ $t("screen.areaStats") }}</span>
|
<span style="float: right">
|
<el-image
|
style="position: relative; top: -7px; right: 20px; width: 30px; height: 8px; cursor: pointer"
|
:src="gengduo"
|
/>
|
</span>
|
</span>
|
</div>
|
<div class="dataScreen-main-chart">
|
<attendsCount />
|
</div>
|
</div>
|
</div>
|
<p class="infoBottomF">
|
<span class="infoButton" @click="toggleFullscreen">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="quanping" />
|
<br />
|
{{ $t("screen.fullScreen") }}
|
</span>
|
<span @click="Panel = !Panel" class="infoButton">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="yincang" /> <br />{{
|
Panel ? $t("screen.hidePanel") : $t("screen.showPanel")
|
}}
|
</span>
|
<span @click="dialogVisible = true" class="infoButton">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="JiChuGn" />
|
<br />{{ $t("screen.moreFeatures") }}
|
</span>
|
<span class="infoButton" @click="toogleThreeMap">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="qhmodel" />
|
<br />{{ MapTitle }}
|
</span>
|
<span @click="Home" class="infoButton">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="ChuShiHome" /> <br />{{
|
$t("screen.homePosition")
|
}}
|
</span>
|
<span class="infoButton" @click="dialogVisibleGuangBo = true">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="yingji" />
|
<br />{{ $t("screen.emergencyBroadcast") }}
|
</span>
|
<span class="infoButton" @click="toggleTheme" style="display: none">
|
<el-image style="width: 20px; height: 20px; margin-top: 15px" :src="yingji" />
|
<br />
|
<span style="position: relative; top: -2px">
|
{{ currentTheme === "light" ? $t("screen.lightTheme") : $t("screen.darkTheme") }}
|
</span>
|
</span>
|
<!-- 更多功能 -->
|
<el-dialog v-model="dialogVisible" width="520" draggable style="background-size: 100% 100%">
|
<template #header="">
|
<div class="my-header" style="color: white">{{ $t("screen.moreFeatures") }}</div>
|
</template>
|
<div class="settings-container">
|
<div style="display: flex; align-items: center; margin-bottom: 15px; color: #e6a23c">
|
<el-icon style="margin-right: 8px"><Warning /></el-icon>
|
<span>{{ $t("screen.tempOperationNote") }}</span>
|
</div>
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showGlobe") }}:</span>
|
<el-switch v-model="marsHome.showmap" />
|
</div>
|
</div>
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.satelliteMap") }}:</span>
|
<el-switch v-model="marsHome.weixing" />
|
</div>
|
</div>
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showOffOnLine") }}:</span>
|
<el-switch v-model="marsHome.showOffOnLine" />
|
</div>
|
</div>
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showFence") }}:</span>
|
<el-switch v-model="marsHome.showfence" />
|
</div>
|
</div>
|
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showAnchor") }}:</span>
|
<el-switch v-model="marsHome.showanchor" />
|
</div>
|
</div>
|
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.enableVoice") }}:</span>
|
<el-switch v-model="marsHome.voice" />
|
</div>
|
</div>
|
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showMonitor") }}:</span>
|
<el-switch v-model="marsHome.jiankong" />
|
</div>
|
</div>
|
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.show3DModel") }}:</span>
|
<el-switch v-model="marsHome.threemap" />
|
</div>
|
</div>
|
|
<div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.showTileMap") }}:</span>
|
<el-switch v-model="marsHome.layer" />
|
</div>
|
</div>
|
|
<!-- <div class="settings-row">
|
<div class="settings-item">
|
<span class="settings-label">{{ $t("screen.mapColor") }}:</span>
|
<el-color-picker v-model="marsHome.mapColor" />
|
</div>
|
</div> -->
|
</div>
|
</el-dialog>
|
<!-- 应急广播 -->
|
<el-dialog v-model="dialogVisibleGuangBo" width="520" draggable style="background-size: 100% 100%">
|
<template #header="">
|
<div class="my-header" style="color: white">{{ $t("screen.emergencyBroadcast") }}</div>
|
</template>
|
<Dialog />
|
<template #footer>
|
<div class="dialog-footer"></div>
|
</template>
|
</el-dialog>
|
<!-- 告警信息 -->
|
<el-dialog v-model="dialogVisibleWarning" width="820" draggable style="height: 620px; background-size: 100% 100%">
|
<template #header="">
|
<div class="my-header" style="color: white">{{ $t("screen.alarmInfo") }}</div>
|
</template>
|
<WarningInfo @warningPostionClick="handleWarningPositionClick" />
|
</el-dialog>
|
<!-- 人员统计 -->
|
<el-dialog v-model="dialogVisiblePerson" width="820" style="height: 620px; background-size: 100% 100%">
|
<template #header="">
|
<div class="my-header" style="font-weight: bold; color: white">{{ $t("screen.personStats") }}</div>
|
</template>
|
<personInfo />
|
</el-dialog>
|
<!-- 人员详细信息 -->
|
<PersonInfoCard ref="viewRef" style="color: white; background-size: 100% 100%" />
|
</p>
|
<p class="infoBottom"></p>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts" name="dataScreen">
|
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
|
import dayjs from "dayjs";
|
import { useRouter } from "vue-router";
|
import { useI18n } from "vue-i18n";
|
import Mars3DMap from "./components/screen/Mars3DMap.vue";
|
import { getThreeMapConfig } from "@/api/modules/hxzk/map/threemap";
|
import { getUserName } from "@/api/modules/hxzk/user/user";
|
import messageInfo from "./components/messageInfo.vue";
|
import dayCount from "./components/dayCount.vue";
|
import warningInfo from "./components/warningInfo.vue";
|
import attendsCount from "./components/attendsCount.vue";
|
import { FindCompanyName } from "@/api/modules/hxzk/user/company";
|
import { PersonPosition, RealPosition, FindOnePersonInfo } from "@/api/modules/hxzk/person/person";
|
import { ElNotification, ElMessageBox, ElMessage } from "element-plus";
|
import { FindCSDATE } from "@/api/modules/hxzk/count/count";
|
import Dialog from "./components/screen/Dialog.vue";
|
import WarningInfo from "./components/tableInfo/warningInfo.vue";
|
import personInfo from "./components/tableInfo/personInfo.vue";
|
import { AddVideoMap } from "@/api/modules/hxzk/video/video";
|
import PersonInfoCard from "@/views/proTable/components/hxzk/person/PersonInfoCardScreen.vue";
|
import { logoutApi } from "@/api/modules/login";
|
import quanping from "@/views/hxzk/images/map/quangping0.png";
|
import yincang from "@/views/hxzk/images/map/yincang.png";
|
import JiChuGn from "@/views/hxzk/images/map/JiChuGn.png";
|
import qhmodel from "@/views/hxzk/images/map/qhmodel.png";
|
import ChuShiHome from "@/views/hxzk/images/map/ChuShiHome.png";
|
import yingji from "@/views/hxzk/images/map/yingji.png";
|
import warninfo from "@/views/hxzk/images/map/warninfo.png";
|
import personinfo from "@/views/hxzk/images/map/personinfo.png";
|
import kaoqininfo from "@/views/hxzk/images/map/kaoqininfo.png";
|
import countinfo from "@/views/hxzk/images/map/countinfo.png";
|
import gengduo from "@/views/hxzk/images/map/gengduo.png";
|
import { useUserStore } from "@/stores/modules/user";
|
import positionIcon from "@/views/hxzk/images/map/position.png";
|
import { setLanguage } from "@/api/modules/hxzk/util/util";
|
|
const { t } = useI18n();
|
const systemName = ref("");
|
const userStore = useUserStore();
|
const router = useRouter();
|
const user = ref({
|
username: "",
|
companyname: ""
|
});
|
let Map;
|
|
const configLoaded = ref(false);
|
const baseColor = ref("");
|
// 地图配置
|
const mapConfigs = ref({});
|
const MapTitle = ref(t("screen.threeDView"));
|
|
const dataScreenRef = ref<HTMLElement | null>(null);
|
const widths = ref(window.innerWidth);
|
const heights = ref(window.innerHeight);
|
const Panel = ref(true); //面板
|
const dialogVisible = ref(false); //更多功能
|
const dialogVisibleGuangBo = ref(false); //应急广播
|
const dialogVisibleWarning = ref(false); //更多告警信息
|
const dialogVisiblePerson = ref(false); //更多人员信息
|
const dialogPersonInfo = ref(false);
|
import { useGlobalStore } from "@/stores/modules/global";
|
let addedCarIds1 = {}; //在线离线集合
|
let graphicLayer;
|
let graphicLayerCamera; //监控
|
let graphicLayerWarning; //告警坐标
|
|
// 更新尺寸的函数
|
const updateDimensions = () => {
|
if (dataScreenRef.value) {
|
widths.value = window.innerWidth;
|
heights.value = window.innerHeight;
|
dataScreenRef.value.style.width = `${widths.value}px`;
|
dataScreenRef.value.style.height = `${heights.value}px`;
|
}
|
};
|
|
// 处理窗口大小变化的函数
|
const handleResize = () => {
|
updateDimensions();
|
applyScaling();
|
};
|
|
// 应用缩放比例的函数
|
const applyScaling = () => {
|
if (dataScreenRef.value) {
|
const scale = calculateScale();
|
dataScreenRef.value.style.transform = `scale(${scale}) translate(-50%, -50%)`;
|
}
|
};
|
|
// 计算缩放比例的函数
|
const calculateScale = () => {
|
const ww = window.innerWidth / widths.value;
|
const wh = window.innerHeight / heights.value;
|
return ww < wh ? ww : wh;
|
};
|
const marsHome = ref({
|
id: 0,
|
showmap: false,
|
offlinehide: false, //离线消失
|
voice: false, //语音告警
|
showfence: false, //围栏
|
showOffOnLine: false,
|
showanchor: false, //基站
|
threemap: false, //三维模型
|
layer: false, //瓦片图
|
image: false, //平面图
|
jiankong: true,
|
weixing: false,
|
mapColor: "", // 默认颜色
|
pinlv: 0
|
});
|
// 添加一个标志变量来控制 watch 的执行
|
// 添加主题状态
|
const currentTheme = ref(localStorage.getItem("theme") || "dark");
|
const globalStore = useGlobalStore();
|
const lang = globalStore.language;
|
// 主题切换函数
|
const toggleTheme = () => {
|
currentTheme.value = currentTheme.value === "light" ? "dark" : "dark";
|
localStorage.setItem("theme", currentTheme.value);
|
};
|
const shouldWatch = ref(false);
|
onMounted(() => {
|
try {
|
// 先调用后端接口设置语言
|
const response = setLanguage({ lang });
|
console.log("后端语言设置结果:", response);
|
} catch (error) {
|
console.error("设置语言失败:", error);
|
}
|
//获取用户名
|
const savedTheme = localStorage.getItem("theme");
|
if (savedTheme) {
|
currentTheme.value = savedTheme;
|
}
|
if (dataScreenRef.value) {
|
// 初始设置
|
updateDimensions();
|
applyScaling();
|
|
// 添加事件监听
|
window.addEventListener("resize", handleResize);
|
|
//获取用户名
|
getUserName().then(TbUser => {
|
user.value.username = TbUser.username;
|
user.value.companyname = TbUser.companyname;
|
});
|
//获取系统名称
|
FindCompanyName().then(name => {
|
systemName.value = name;
|
});
|
//地图初始化
|
getThreeMapConfig().then(mapConfig => {
|
mapConfigs.value = mapConfig;
|
marsHome.value.id = mapConfig.id;
|
if (mapConfig.showfence == "1") {
|
marsHome.value.showfence = true;
|
}
|
if (mapConfig.layer == "1") {
|
marsHome.value.layer = true;
|
}
|
if (mapConfig.showanchor == "1") {
|
marsHome.value.showanchor = true;
|
}
|
if (mapConfig.threemap == "1") {
|
marsHome.value.threemap = true;
|
}
|
if (mapConfig.voice == "1") {
|
marsHome.value.voice = true;
|
}
|
if (mapConfig.showmap == "1") {
|
marsHome.value.showmap = true;
|
}
|
|
baseColor.value = mapConfig.mapcolor;
|
configLoaded.value = true;
|
|
marsHome.value.pinlv = mapConfig.pinlv;
|
window.addEventListener("resize", resize);
|
AddPersonPosition(); //开始播放实时轨迹
|
//每 10 秒执行一次 AddPersonPosition 函数
|
setInterval(AddPersonPosition, 10000);
|
setInterval(AddRealPosition, marsHome.value.pinlv);
|
});
|
}
|
});
|
// 监听 marsHome 的属性变化
|
// 监听props变化
|
|
watch(
|
[() => marsHome.value.jiankong, () => marsHome.value.mapColor, () => marsHome.value.weixing, () => marsHome.value.showmap],
|
([newJianKong, newMapColor, newWeiXing, newShow], [oldJianKong, oldMapColor, oldWeiXing, oldShow]) => {
|
if (!shouldWatch.value) return;
|
if (newJianKong !== oldJianKong) {
|
if (newJianKong) {
|
//处理 围栏显示
|
AddCamera();
|
} else {
|
graphicLayerCamera.clear();
|
}
|
}
|
if (newWeiXing !== oldWeiXing) {
|
if (newWeiXing) {
|
//处理 卫星显示
|
Map.basemap = 8890;
|
} else {
|
Map.basemap = 2017;
|
}
|
}
|
if (newMapColor !== oldMapColor) {
|
if (newMapColor) {
|
marsHome.value.mapColor = newMapColor;
|
|
Map.basemap = 10; //设置无底图
|
Map.basemap = 2017; //设置无底图
|
}
|
}
|
if (newShow !== oldShow) {
|
if (newShow || marsHome.value.showmap == "1") {
|
//显示地球
|
Map.scene.globe.show = true;
|
} else {
|
Map.scene.globe.show = false;
|
}
|
}
|
}
|
);
|
//地图初始化
|
const onMapLoaded = (mapInstance: any) => {
|
Map = mapInstance;
|
|
marsHome.value.mapColor = baseColor.value;
|
graphicLayer = new mars3d.layer.GraphicLayer();
|
Map.addLayer(graphicLayer);
|
graphicLayerCamera = new mars3d.layer.GraphicLayer();
|
Map.addLayer(graphicLayerCamera);
|
graphicLayerWarning = new mars3d.layer.GraphicLayer();
|
Map.addLayer(graphicLayerWarning);
|
AddCamera();
|
GraphicLayerClick();
|
|
if (marsHome.value.showmap == "1") {
|
Map.scene.globe.show = true;
|
}
|
// 在所有初始化完成后,才允许 watch 执行
|
shouldWatch.value = true;
|
Map.scene.color;
|
};
|
|
// 获取添加定位的人员
|
const AddPersonPosition = () => {
|
PersonPosition().then(PersonsList => {
|
const currentOnlineIds = new Set();
|
const currentNoOnlineIds = new Set();
|
|
PersonsList.data.forEach(item => {
|
// 记录在线和不在线人员的ID
|
if (item.ponline === "1" || marsHome.value.showOffOnLine) {
|
currentOnlineIds.add(item.ptagid);
|
if (!addedCarIds1.hasOwnProperty(item.ptagid)) {
|
let car = new mars3d.graphic.Route({
|
billboard: {
|
image: item.pimage,
|
width: 40,
|
height: 40,
|
clampToGround: true
|
},
|
id: item.ptagid,
|
name: item.pname,
|
maxCacheCount: 1,
|
circle: {
|
radius: 3,
|
materialType: mars3d.MaterialType.CircleWave,
|
speed: 10,
|
count: 3,
|
gradient: 0.1,
|
clampToGround: true,
|
show: false
|
},
|
style: {
|
label: {
|
background: true,
|
backgroundColor: item.baoliu8,
|
backgroundOpacity: 0.5,
|
text: item.pname + " " + item.ptagid,
|
font_size: 14,
|
color: "#ffffff",
|
font_weight: "bold",
|
outlineWidth: 3,
|
outline: true,
|
pixelOffsetY: -30,
|
outlineColor: "#black"
|
}
|
},
|
attr: item
|
});
|
// 将模型添加到图层中
|
graphicLayer.addGraphic(car);
|
// 打开模型弹窗
|
// car.openPopup();
|
// 将已添加模型的ID记录到集合中
|
addedCarIds1[item.ptagid] = item.online;
|
}
|
} else {
|
currentNoOnlineIds.add(item.ptagid);
|
// 移除不在线人员的模型
|
if (addedCarIds1.hasOwnProperty(item.ptagid)) {
|
// 通过 ID 查找对应的图形并移除
|
graphicLayer.getGraphics().forEach(graphic => {
|
if (graphic.id === item.ptagid) {
|
graphicLayer.removeGraphic(graphic);
|
currentNoOnlineIds.delete(item.ptagid);
|
}
|
});
|
delete addedCarIds1[item.ptagid];
|
}
|
}
|
});
|
});
|
};
|
//获取实时位置的人员
|
const AddRealPosition = () => {
|
RealPosition().then(personList => {
|
graphicLayer.eachGraphic(car => {
|
let path = personList.data.filter(item => item.ptagid === car.id);
|
path.forEach(item => {
|
if (item.company == "ABIX" || item.baoliu2 < 50) {
|
item.baoliu2 = -item.baoliu2;
|
item.baoliu3 = -item.baoliu3;
|
}
|
let point = new mars3d.LngLatPoint(item.baoliu2, item.baoliu3, item.baoliu4 / 100);
|
car.addDynamicPosition(point, item.paddtiem);
|
});
|
});
|
});
|
};
|
|
// 添加监控
|
const AddCamera = () => {
|
AddVideoMap().then(Camera => {
|
for (let i = 0; i < Camera.length; i++) {
|
let graphic = new mars3d.graphic.BillboardEntity({
|
position: [Camera[i].posx, Camera[i].posy, Camera[i].baoliu2],
|
style: {
|
image: Camera[i].baoliu3,
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
scale: 0.15,
|
label: {
|
text: "设备:" + Camera[i].name,
|
font_size: 14,
|
color: "#ffffff",
|
font_weight: "bold",
|
outlineWidth: 3,
|
outline: true,
|
pixelOffsetY: -40,
|
outlineColor: "#black"
|
}
|
},
|
attr: Camera[i]
|
});
|
graphicLayerCamera.addGraphic(graphic); // 还可以另外一种写法: graphic.addTo(graphicLayer)
|
graphic.bindPopup(
|
function (event) {
|
let attr = event.graphic?.attr;
|
let inthtml = `<table style="width: auto;overflow: hidden">
|
<tr>
|
<th scope="col" colspan="0" style="text-align:center;font-size:15px;">${attr.name}</th>
|
</tr>
|
<tr>
|
<td>
|
<div id="video-contianer" style="width: 300px;height: 150px;">
|
<video style="width: 300px;height: 150px;" class="video${attr.id}" id="video" preload="auto"autoplay="autoplay"muted></video>
|
<div class="mask${attr.id}" id="mask"></div>
|
</div>
|
</td>
|
</tr>
|
</table>`;
|
return inthtml;
|
},
|
{
|
autoClose: false,
|
closeOnClick: false
|
}
|
);
|
}
|
});
|
};
|
|
// 人员查询定位位置
|
const handlePersonPositionClick = personData => {
|
Map.setCameraView({ lat: personData.baoliu3, lng: personData.baoliu2, alt: 100, heading: 360, pitch: -90 });
|
if (personData.ponline == "0") {
|
//离线图标
|
let graphicWarning = new mars3d.graphic.BillboardEntity({
|
position: new mars3d.LngLatPoint(personData.baoliu2, personData.baoliu3),
|
style: {
|
image: positionIcon,
|
clampToGround: true,
|
outlineWidth: 0,
|
scale: 1, // 设置图片的大小为原来的50%
|
label: {
|
text: personData.ptagid + " - " + personData.pname,
|
pixelOffsetY: -20,
|
addHeight: 9,
|
font_size: 14,
|
color: "#ffffff",
|
font_weight: "bold",
|
outlineWidth: 3,
|
outline: true,
|
pixelOffsetY: -30,
|
outlineColor: "#black"
|
}
|
}
|
});
|
graphicLayerWarning.addGraphic(graphicWarning);
|
setTimeout(function () {
|
graphicLayerWarning.clear();
|
}, 10000);
|
}
|
ElNotification({
|
title: t("screen.quickPosition", { tagid: personData.ptagid, name: personData.pname }),
|
type: "success"
|
});
|
};
|
// 告警人员查询定位位置
|
const handleWarningPositionClick = personData => {
|
graphicLayerWarning.clear();
|
const position = personData.baoliu1.split(";");
|
Map.setCameraView({ lat: position[1], lng: position[0], alt: 100, heading: 360, pitch: -90 });
|
ElNotification({
|
title: t("screen.alarmPosition", { type: personData.type, objectid: personData.objectid, name: personData.baoliu2 }),
|
type: "success"
|
});
|
let graphicWarning = new mars3d.graphic.BillboardEntity({
|
position: new mars3d.LngLatPoint(position[0], position[1]),
|
style: {
|
image: positionIcon,
|
clampToGround: true,
|
outlineWidth: 0,
|
scale: 1,
|
label: {
|
text: personData.objectid + " - " + personData.baoliu2 + " - " + personData.type,
|
pixelOffsetY: -20,
|
addHeight: 9,
|
font_size: 14,
|
color: "#ffffff",
|
font_weight: "bold",
|
outlineWidth: 3,
|
outline: true,
|
pixelOffsetY: -30,
|
outlineColor: "#black"
|
}
|
}
|
});
|
graphicLayerWarning.addGraphic(graphicWarning);
|
setTimeout(function () {
|
graphicLayerWarning.clear();
|
}, 10000);
|
};
|
|
// 设置响应式
|
const resize = () => {
|
if (dataScreenRef.value) {
|
dataScreenRef.value.style.transform = `scale(${getScale()}) translate(-50%, -50%)`;
|
}
|
};
|
|
// 定义切换全屏的函数
|
const toggleFullscreen = () => {
|
const elem = document.documentElement;
|
if (document.fullscreenElement) {
|
if (document.exitFullscreen) {
|
document.exitFullscreen();
|
} else if (document.webkitExitFullscreen) {
|
document.webkitExitFullscreen();
|
} else if (document.msExitFullscreen) {
|
document.msExitFullscreen();
|
}
|
} else {
|
if (elem.requestFullscreen) {
|
elem.requestFullscreen();
|
} else if ((elem as any).webkitRequestFullscreen) {
|
(elem as any).webkitRequestFullscreen();
|
} else if ((elem as any).msRequestFullscreen) {
|
(elem as any).msRequestFullscreen();
|
}
|
}
|
};
|
|
const GraphicLayerClick = () => {
|
// 绑定点击事件
|
graphicLayer.on(mars3d.EventType.click, event => {
|
let car = event.graphic;
|
const params = {
|
ptagid: car.attr.ptagid
|
};
|
FindOnePersonInfo(params).then(data => {
|
viewDrawer("查看", data);
|
dialogPersonInfo.value = true;
|
});
|
// car.openPopup();
|
});
|
};
|
|
const viewRef = ref<InstanceType<typeof UserDrawer> | null>(null);
|
const viewDrawer = (title: string, row: Partial<User.ResUserList> = {}) => {
|
const params = {
|
title,
|
isView: title === "查看",
|
row: { ...row },
|
api: title === "新增" ? null : title === "编辑" ? null : undefined
|
};
|
|
viewRef.value?.acceptParams(params);
|
};
|
// 根据浏览器大小推断缩放比例
|
const getScale = (width = widths.value, height = heights.value) => {
|
let ww = window.innerWidth / width;
|
let wh = window.innerHeight / height;
|
return ww < wh ? ww : wh;
|
};
|
// 获取当前时间
|
let timer: NodeJS.Timer | null = null;
|
let time = ref<string>(dayjs().format("YYYY-MM-DD HH:mm:ss"));
|
timer = setInterval(() => {
|
FindCSDATE().then(data => {
|
time.value = data;
|
});
|
}, 1000);
|
// 进入后台
|
const Join = async () => {
|
try {
|
const url = router.resolve("/hxzk/count/count");
|
window.open(url.href, "_blank");
|
} finally {
|
// 可选的清理逻辑
|
}
|
};
|
|
// 处理下拉菜单命令
|
const handleCommand = (command: string) => {
|
if (command === "backend") {
|
Join(); // 进入后台
|
} else if (command === "logout") {
|
logout(); // 退出登录
|
}
|
};
|
|
// 退出登录
|
const logout = () => {
|
ElMessageBox.confirm(t("HandleData.confirmMessage", { message: t("header.logout") }), t("HandleData.confirmTitle"), {
|
confirmButtonText: t("HandleData.confirmButton"),
|
cancelButtonText: t("HandleData.cancelButton"),
|
type: "warning"
|
})
|
.then(async () => {
|
await logoutApi();
|
userStore.setToken("");
|
router.replace(LOGIN_URL);
|
ElMessage.success(t("HandleData.successMessage", { action: t("header.logout") }));
|
})
|
.catch(() => {
|
// 用户取消退出
|
});
|
};
|
|
//起始位置
|
const Home = () => {
|
Map.flyHome();
|
};
|
// 切换2D/3D视图
|
const toogleThreeMap = () => {
|
if (Map) {
|
if (Map.scene.mode === Cesium.SceneMode.SCENE2D) {
|
Map.scene.morphTo3D(0);
|
MapTitle.value = t("screen.threeDView");
|
} else {
|
Map.scene.morphTo2D(0);
|
MapTitle.value = t("screen.twoDView");
|
}
|
}
|
ElNotification.success(MapTitle.value);
|
};
|
|
onBeforeUnmount(() => {
|
if (Map) {
|
Map.destroy();
|
Map = null; // 关键:重置引用
|
}
|
window.removeEventListener("resize", resize);
|
clearInterval(timer as unknown as number);
|
});
|
</script>
|
<style lang="scss" scoped>
|
// 基础样式保持不变
|
@import "../dataScreen/index";
|
|
// 主题变量
|
$light-bg: #f5f7fa;
|
$dark-bg: #1a1a1a;
|
$light-text: #ffffff;
|
$light-cell-text: #000000;
|
$dark-cell-text: #ffffff;
|
$dark-text: #ffffff;
|
$light-title: #030303;
|
$dark-title: #ffffff;
|
$light-maptitle-bg: url("./images/map/maptitle1.png");
|
$dark-maptitle-bg: url("./images/map/maptitle.png");
|
$light-title-bg: url("./images/map/infoTitle1.png");
|
$dark-title-bg: url("./images/map/infoTitle.png");
|
$light-chart-bg: url("./images/map/infoBack1.png");
|
$dark-chart-bg: url("./images/map/infoBack.png");
|
$light-button-bg: url("./images/map/infoButton1.png");
|
$dark-button-bg: url("./images/map/infoButton.png");
|
|
// 通用样式
|
.dataScreen-container {
|
.dataScreen-content {
|
.dataScreen-header {
|
background-size: 100% 130%;
|
}
|
.dataScreen-main {
|
.dataScreen-main-title {
|
z-index: 9;
|
}
|
.dataScreen-main-chart {
|
position: relative;
|
top: -20px;
|
left: 8px;
|
width: 98.5%;
|
padding-top: 30px;
|
}
|
}
|
}
|
.infoButton {
|
font-weight: bold;
|
background-size: 100% 100%;
|
}
|
}
|
|
// 浅色主题
|
.dataScreen-container.light {
|
:deep(.cell) {
|
font-weight: normal;
|
color: $light-cell-text;
|
text-shadow: none;
|
}
|
.celltext {
|
color: $light-text;
|
}
|
.cellTitle {
|
color: $light-title;
|
}
|
.cellhead {
|
color: #1663c6;
|
}
|
.dataScreen-content {
|
background-color: #d7e9fd;
|
.dataScreen-header {
|
background: $light-maptitle-bg no-repeat;
|
background-size: 100% 130%;
|
}
|
.dataScreen-main {
|
.dataScreen-main-title {
|
background: $light-title-bg no-repeat;
|
}
|
.dataScreen-main-chart {
|
background: $light-chart-bg;
|
background-size: 100% 100%;
|
}
|
}
|
}
|
:deep(.el-dialog) {
|
background: linear-gradient(to bottom, rgb(221 230 243 / 80.6%), rgb(255 255 255));
|
background-size: 100% 100%;
|
}
|
.infoButton {
|
color: #1663c6;
|
background: $light-button-bg;
|
background-size: 100% 100%;
|
}
|
}
|
|
// 深色主题
|
.dataScreen-container.dark {
|
.cell {
|
font-weight: normal;
|
color: $dark-cell-text;
|
text-shadow: none;
|
}
|
.celltext {
|
color: $dark-text;
|
}
|
.cellTitle {
|
color: $dark-title;
|
}
|
.cellhead {
|
position: relative;
|
top: 5px;
|
color: #4a90e2;
|
}
|
.dataScreen-content {
|
background-color: #000000;
|
.dataScreen-header {
|
background: $dark-maptitle-bg no-repeat;
|
background-size: 100% 130%;
|
}
|
.dataScreen-main {
|
.dataScreen-main-title {
|
background: $dark-title-bg no-repeat;
|
}
|
.dataScreen-main-chart {
|
background: $dark-chart-bg;
|
background-size: 100% 100%;
|
}
|
}
|
}
|
:deep(.el-dialog) {
|
background: linear-gradient(to bottom, rgb(1 5 22 / 80%), transparent);
|
background: $dark-chart-bg;
|
background-size: 100% 100%;
|
}
|
.infoButton {
|
color: $dark-text;
|
background: $dark-button-bg;
|
background-size: 100% 100%;
|
}
|
}
|
</style>
|