2467 lines
68 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-17 11:34:00
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2025-01-21 11:32:51
* @FilePath: \znxjxt-ui\src\views\big-screen\index.vue
* @Description: 大屏首页
-->
<template>
<div class="screen-content">
<div class="screen-header">
<div class="header-weather">
<!-- <iframe
width="150"
scrolling="no"
height="45"
frameborder="0"
allowtransparency="true"
src="https://i.tianqi.com?c=code&id=12&icon=1&color=%2389C5E8&py=shenyang&num=1&site=12"
></iframe> -->
</div>
<div class="header-time">
<!-- 消息中心 -->
<div class="header-news">
<el-popover
placement="bottom-end"
width="400"
popper-class="screen-message-popover"
trigger="hover"
>
<div class="screen-message-content">
<div class="message-content">
<fssm-scroll style="max-height: 12rem">
<div
class="message-item"
v-for="(item, index) in messageList"
:key="`message-item-${index}`"
>
<div
class="item-top"
@click="handleMessageItemClick(item.notificationType)"
>
<div class="index">
<!-- <i v-if="item.title === '成功'" style="color: #67c23a" class="el-icon-success"></i> -->
<i
v-if="item.notificationType === 'REMIND'"
style="color: #e6a23c"
class="el-icon-info"
></i>
<i
v-if="item.notificationType === 'WARNING'"
style="color: #909399"
class="el-icon-warning"
></i>
<!-- <i v-if="item.title === '错误'" style="color: #f56c6c" class="el-icon-error"></i> -->
</div>
<div class="time">
<span>{{ item.createdTime }}</span>
</div>
<div class="carNo">
<span>{{ item.title }}</span>
</div>
</div>
<div class="item-content">
{{ item.content }}
</div>
</div>
</fssm-scroll>
</div>
<div class="message-footer">
<el-button
@click="handleMessageClick"
icon="el-icon-d-arrow-right"
type="text"
>查看更多</el-button
>
</div>
</div>
<el-badge
slot="reference"
:value="noticeNum"
:max="99"
class="item"
>
<i class="el-icon-message-solid"> </i>
</el-badge>
<!-- <i slot="reference" class="el-icon-message-solid">
<div class="num">{{ noticeNum }}</div>
</i> -->
</el-popover>
</div>
<div class="header-data">{{ dataTime }}</div>
<div class="header-week">
<span>{{ weekTime }}</span>
<span>{{ yearTime }}</span>
</div>
<div class="header-home">
<div class="home" @click="goIndex"></div>
</div>
</div>
</div>
<div class="screen-middle">
<div class="screen-left">
<module-block
v-for="(item, index) in leftModuleList"
:key="`left-module-list-${index}`"
:width="item.width"
:height="item.height"
:title="item.title"
:class="item.class"
>
<template>
<component
class="animate__animated animate__slideInLeft"
:select="item.select"
:is="item.component"
:bottomTipClick="bottomTipClick"
:companyId="companyId"
></component>
</template>
<template slot="operation" v-if="item.selectIsShow">
<el-radio-group class="screen-checkBox" v-model="item.select">
<el-radio-button
v-for="(item, index) in selectTypeArr"
:label="item.value"
:key="`left-screen-${index}`"
>{{ item.label }}</el-radio-button
>
</el-radio-group>
</template>
</module-block>
</div>
<div class="screen-right">
<module-block
v-for="(item, index) in rightModuleList"
:key="`right-module-list-${index}`"
:width="item.width"
:height="item.height"
:title="item.title"
:class="item.class"
>
<template>
<component
class="animate__animated animate__slideInRight"
:select="item.select"
:is="item.component"
:bottomTipClick="bottomTipClick"
:companyId="companyId"
:eventType="defectSelectList"
@imagePoint="getimagePoint"
></component>
</template>
<template slot="operation" v-if="item.selectIsShow">
<el-radio-group class="screen-checkBox" v-model="item.select">
<el-radio-button
v-for="(item, index) in selectTypeArr"
:label="item.value"
:key="`right-screen-${index}`"
>{{ item.label }}</el-radio-button
>
</el-radio-group>
</template>
</module-block>
</div>
<div class="road-content">
<!-- 地图右上角多选框切换坐标类型 -->
<div class="road-checkBox" v-if="showIconList">
<fssm-scroll class="road-scroll">
<el-checkbox-group v-model="iconType" @change="handleChecked">
<el-checkbox
v-for="(item, index) in iconTypeList"
:label="item.value"
:key="`check-${index}`"
>{{ item.label }}</el-checkbox
>
</el-checkbox-group>
</fssm-scroll>
</div>
<!-- 大屏工单数据 -->
<!-- && !showMap -->
<div class="work-order" v-if="elementDiv === 'OverviewScreen'">
<div class="work-order-right">
<div
class="loop-div"
v-for="(item, index) in workOrderList"
:key="`loop-div-${index}`"
>
<div class="value">
<!-- <span>{{ item.value }}</span
> -->
<CountTo
ref="refcountofore"
:start-val="1000"
:end-val="item.value"
:duration="500"
></CountTo>
</div>
<div class="name">{{ item.name }}</div>
</div>
</div>
<div class="work-order-left">
<div
class="btn-time"
:class="workOrderType === 'week' ? 'btn-time-click' : ''"
size="mini"
@click="changeOrder('week')"
>
本周
</div>
<div
class="btn-time"
:class="workOrderType === 'month' ? 'btn-time-click' : ''"
size="mini"
@click="changeOrder('month')"
>
本月
</div>
<div
class="btn-time"
:class="workOrderType === 'year' ? 'btn-time-click' : ''"
size="mini"
@click="changeOrder('year')"
>
本年
</div>
</div>
</div>
<!-- 地图图例 -->
<div class="map-legend" v-if="elementDiv != 'RoadScreen'">
<span>{{ mapLegendList.s1 }}</span>
<span>{{ mapLegendList.s2 }}</span>
<span>{{ mapLegendList.s3 }}</span>
<span>{{ mapLegendList.s4 }}</span>
<span>>{{ mapLegendList.s4 }}</span>
</div>
<!-- 病害筛选下拉框 -->
<!-- || showMap -->
<div class="map-image-select" v-if="elementDiv != 'RoadScreen'">
<!-- <span>病害类型筛选</span> -->
<!-- v-if="elementDiv === 'DiseaseScreen' || showMap" -->
<el-cascader
v-if="elementDiv === 'OverviewScreen'"
ref="screenCascader"
v-model="mapCareSelect"
popper-class="screen-index-cascader"
placeholder="请选择病害类型"
:options="dieaseOptions"
:props="{
checkStrictly: true,
emitPath: true,
children: 'subTypes',
}"
@change="changeMapCareSelect"
clearable
></el-cascader>
<el-select
v-if="elementDiv === 'DiseaseScreen'"
v-model="defectSelect"
popper-class="screen-select"
placeholder="请选择病害类型"
clearable
@change="getLinePoint"
>
<el-option
v-for="item in defectSelectList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<!-- 图片背景返回 -->
<div
class="return-image"
v-if="showMap && elementDiv === 'OverviewScreen'"
>
<el-button type="info" size="mini" round @click="disabledMapCompany"
>返回</el-button
>
</div>
<!-- 图片背景 -->
<div
class="disease-content"
v-if="elementDiv === 'OverviewScreen' && !showMap"
>
<!-- <div class="disease-title"></div> -->
<div class="map-care">
<div
class="map-care-div"
:class="`map-care-div-${item.status}`"
v-for="(item, index) in mapCareList"
:key="`map-care-${index}`"
:style="{ left: item.left, top: item.top }"
>
<el-popover
popper-class="screen-map-popover"
placement="right-start"
width="auto"
trigger="hover"
:visible-arrow="false"
>
<div class="screen-map-popover-content">
<div class="item">
<div>
<span class="name" style="color: #18f7ff"
>{{ screenMapPopoverName }}病害数</span
><span class="value">{{ item.all }}</span
>
</div>
<div>
<span class="name" style="color: #18f7ff"
>每公里平均病害</span
><span class="value">{{ item.per }}</span
>
</div>
</div>
</div>
<span slot="reference" @click="showMapByCompany(item)">{{
item.name
}}</span>
</el-popover>
</div>
</div>
</div>
<!-- 总览地图 -->
<!-- <fssm-map ref="overViewMap" v-if="showMap"> </fssm-map> -->
<!-- 病害巡检道路资产地图 -->
<fssm-map
v-if="showMap"
ref="roadMap"
:showChange="false"
:controlStyle="{ top: '20%', left: '26%' }"
@feature-select="featureSelect"
@map-zoom="getZoom"
></fssm-map>
</div>
</div>
<div class="screen-footer">
<!-- 病害巡检4种类型按钮 -->
<div class="footer-change-map">
<template v-if="elementDiv === 'DiseaseScreen'">
<div
class="change-map-div"
:class="bottomTipClick === item.click ? 'change-map-click' : ''"
v-for="(item, index) in changeMapBtn"
:key="`btn-${index}`"
@click="changeIconType(item.click)"
>
{{ item.name }}
</div>
</template>
</div>
<!-- 切换3种导航栏按钮 -->
<div class="footer-change-vue">
<div
:class="
elementDiv === item.component
? `change-vue-click-${item.component}`
: `change-vue-${item.component}`
"
v-for="(item, index) in elementList"
:key="`footer-${index}`"
@click="changeElement(item)"
></div>
</div>
</div>
<!-- 详情图片弹窗 -->
<el-dialog
:title="imgTitle"
:visible.sync="imgVisible"
width="95rem"
append-to-body
fullscreen
:close-on-click-modal="false"
destroy-on-close
@close="imgCancel"
>
<img-dialog
v-if="imgTitle === '查看'"
:imageItem="imageItem"
:bottomTipClick="bottomTipClick"
></img-dialog>
</el-dialog>
<!-- 查看点位图片弹窗 -->
<el-dialog
title="查看点位"
:visible.sync="showImageDialog"
width="90rem"
append-to-body
:close-on-click-modal="false"
destroy-on-close
@close="screenImgCancel"
>
<div class="view-image-container" ref="imageContainer">
<img
:src="screenImage.imageUrl"
alt="Main Image"
ref="mainImage"
@load="updateScreenRects"
/>
<div
v-for="(rect, index) in screenRects"
:key="index"
class="rect-overlay"
:style="getScreenRectStyle(rect)"
></div>
<div class="rect-image">
采集时间:
{{ screenImage.createTime }} 起始桩号
{{ screenImage.stakeStart || "暂无数据" }} 终止桩号
{{ screenImage.stakeEnd || "暂无数据" }}
{{ `${this.elementDiv === "RoadScreen" ? "路产" : "病害"}类型:` }}
{{ screenImage.iconTypeName || "暂无数据" }}
<span v-if="this.elementDiv === 'DiseaseScreen'">
病害面积{{ screenImage.targetArea }}平方米 病害长度{{
screenImage.targetLen * 1 <= 0
? "暂无数据"
: `${screenImage.targetLen}`
}}
</span>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
// 地图
import FssmMap from "@/components/map/fssm-map.vue";
import { Feature } from "ol";
import { Point } from "ol/geom";
import { Style, Icon, Fill, Stroke, Circle, Text } from "ol/style";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import * as geomExports from "ol/geom";
import Cluster from "ol/source/Cluster";
import logo from "@/assets/xc.png";
import { getCenter } from "ol/extent";
import MultiLineString from "ol/geom/MultiLineString";
// 组件
import ModuleBlock from "./module-block.vue";
import TodayInspection from "./overview-components/today-inspection.vue";
import DiseaseTrends from "./overview-components/disease-trends.vue";
import DiseaseCurrent from "./overview-components/disease-current.vue";
import PatrolOrder from "./overview-components/patrol-order.vue";
import InspectionVehicles from "./overview-components/inspection-vehicles.vue";
import RoadStatistic from "./road-components/road-statistic.vue";
import ManageMaintain from "./road-components/manage-maintain.vue";
import AnomalyFacilities from "./road-components/anomaly-facilities";
import AncillaryFacilities from "./road-components/ancillary-facilities.vue";
import TrafficSafety from "./disease-components/traffic-safety.vue";
import TrafficTrend from "./disease-components/traffic-trend.vue";
import TrafficStatistic from "./disease-components/traffic-statistic.vue";
import TrafficLog from "./disease-components/traffic-log.vue";
import ImgDialog from "./components/img-dialog.vue";
import FssmScroll from "@/components/scroll/fssm-scroll.vue";
import CountTo from "vue-count-to";
import "animate.css";
import debounce from "lodash/debounce";
// 接口
import {
selectTypeList,
mapPointList,
mapLineList,
comppanyImg,
getItemTypes,
getDefectTypes,
getNoticeList,
getWorkOrderList,
} from "@/api/xj/screen/index";
import { DefectType } from "@/api/xj/screen/traffic-screen";
export default {
name: "BigScreen",
components: {
FssmMap,
ModuleBlock,
TodayInspection,
DiseaseTrends,
DiseaseCurrent,
PatrolOrder,
InspectionVehicles,
RoadStatistic,
ManageMaintain,
AnomalyFacilities,
AncillaryFacilities,
TrafficSafety,
TrafficTrend,
TrafficStatistic,
ImgDialog,
FssmScroll,
TrafficLog,
CountTo,
},
data() {
return {
// 计时器标识
timeFlag: null,
// 时间
dataTime: "",
// 星期
weekTime: "",
// 年
yearTime: "",
// 预警中心数据条数
noticeNum: 0,
// 预警中心消息数据
messageList: [],
// 预警中心定时器
messageTimer: null,
// 数据栏右上角选择框
selectTypeArr: [],
// 左侧切换模块
leftModuleList: [
{
width: "100%",
height: "27%",
title: "今日巡查",
component: TodayInspection,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "27%",
title: "主要病害趋势",
component: DiseaseTrends,
selectIsShow: false,
class: "twe",
},
{
width: "100%",
height: "29%",
title: "病害统计",
component: DiseaseCurrent,
selectIsShow: true,
select: "",
class: "twe",
},
],
// 右侧切换模块
rightModuleList: [
{
width: "100%",
height: "18%",
title: "巡查里程",
component: PatrolOrder,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "65%",
title: "今日巡检车辆",
component: InspectionVehicles,
selectIsShow: false,
class: "twe",
},
],
// 顶端工单数据
workOrderList: [
{ name: "生成工单数", value: 100 },
{ name: "未完成工单数", value: 100 },
{ name: "已完成工单数", value: 100 },
],
// 工单时间选择绑定
workOrderType: "",
// 图片背景下打点坐标数据
mapCareList: [],
// 图例循环数据
mapLegendList: { s1: "0", s2: "20", s3: "40", s4: "60", s5: "80" },
// 具体icon类别
iconTypeList: [],
// icon类别绑定
iconType: [],
// 地图右上角多选显隐控制
showIconList: false,
// 图片背景下病害类型下拉选择绑定
mapCareSelect: [],
// 图片背景下病害类型下拉选择数据
dieaseOptions: [],
// 地图打点-路段绑定
roadSelect: "",
// 是否展示地图显隐控制
showMap: false,
// 图片背景下popover弹窗病害名称
screenMapPopoverName: "",
// 图片背景下点击得公司id
companyId: null,
// 图标类别切换标识
bottomTipClick: "1",
// 对应病害类别细类
defectSelectList: [],
// 对应病害类别系类绑定
defectSelect: "",
// 切换地图图标类别按钮
changeMapBtn: [
{ name: "路面", click: "1" },
{ name: "交安", click: "2" },
{ name: "桥隧", click: "3" },
{ name: "绿化", click: "4" },
],
// 中间展示的动态组件绑定
elementDiv: "OverviewScreen",
// 下方三个按钮数据
elementList: [
{ name: "总览", component: "OverviewScreen" },
{ name: "病害巡检", component: "DiseaseScreen" },
{ name: "道路资产", component: "RoadScreen" },
],
// 中心点集合(过滤后得点位)
centerPiont: [],
// 中心点集合(所有点位)
drawPointList: [],
// 点位图标map
mapLogeList: {},
// 线段点集合
lineString: [],
// 地图放大缩小层级
mapZoom: "",
// 聚合图层
clusters: null,
// 线段图层
markLayerLines: null,
// 是否需要修改地图中心点
isCenterCalculated: false,
// 线段点击保存得参数
defectMapPiont: {},
// 图层标识
shouldLoadClusters: false,
// 图片弹窗标题
imgTitle: "查看",
// 图片弹窗显隐控制
imgVisible: false,
// 传图片弹窗数据
imageItem: {},
// 查看大图点位图片数据
screenImage: {},
// 查看大图点位图片弹窗显隐控制
showImageDialog: false,
// 查看大图点位图片弹窗红框数据
screenRects: [],
// 小车地图点位数据源
carMapPointSource: null,
// 小车地图点位数组
carPointList: [],
// 小车地图点位features数组
mapPointFeatures: [],
// websocket监听事件id
indexListenerId: Symbol("index-listener"),
};
},
created() {
this.setTime();
},
mounted() {
this.getSelect();
this.getMapCare();
this.getDieaseTypeList();
this.getMessageList();
this.changeOrder("week");
this.getAllDefectType();
},
methods: {
/**
* @description: 获取当前时间
* @return {*}
*/
setTime() {
this.timeFlag = setInterval(() => {
const weekMap = [
"星期天",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
];
const date = new Date();
const year = date.getFullYear();
const month =
date.getMonth() + 1 < 10
? `0${date.getMonth() + 1}`
: date.getMonth() + 1;
const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate();
const hours =
date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
const minutes =
date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
const seconds =
date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
const week = date.getDay();
// this.currentTime = `${year}-${month}-${day}\t\t${hours}:${minutes}:${seconds}\t\t${weekMap[week]}`;
this.yearTime = `${year}.${month}.${day}`;
this.weekTime = `${weekMap[week]}`;
this.dataTime = `${hours}:${minutes}:${seconds}`;
}, 1000);
},
/**
* @description: 获取消息中心数据
* @return {void}
*/
getMessageList() {
this.messageTimer = setInterval(() => {
getNoticeList({ read: 1 }).then(({ code, rows, total }) => {
if (code === 200) {
this.messageList = rows;
this.noticeNum = total;
if(total > 99){
clearInterval(this.messageTimer);
}
}
});
}, 120000);
getNoticeList({ read: 1 }).then(({ code, rows, total }) => {
if (code === 200) {
this.messageList = rows;
this.noticeNum = total;
}
});
},
/**
* @description: 消息中心点击具体数据事件
* @return {*}
*/
handleMessageItemClick(value) {
this.$router.push({
name: "Warning-center",
params: { title: value },
});
},
/**
* @description: 消息中心查看更多事件
* @return {*}
*/
handleMessageClick() {
this.$router.push("/inspection_warn/warning-center");
},
/**
* @description: 获取数据栏右上角选项数据
* @return {void}
*/
getSelect() {
selectTypeList().then(({ code, data }) => {
if (code === 200) {
this.selectTypeArr = data;
// 初始化 leftModuleList 和 rightModuleList 中的 select 值
if (this.selectTypeArr.length > 0) {
this.leftModuleList = this.leftModuleList.map((item) => ({
...item,
select: item.selectIsShow
? this.selectTypeArr[0].value
: item.select,
}));
this.rightModuleList = this.rightModuleList.map((item) => ({
...item,
select: item.selectIsShow
? this.selectTypeArr[0].value
: item.select,
}));
}
}
});
},
/**
* @description: 获取图片背景级联病害类型下拉
* @return {void}
*/
getDieaseTypeList() {
getDefectTypes().then(({ code, data }) => {
if (code === 200) {
this.dieaseOptions = data;
}
});
},
/**
* @description: 图片背景级联病害类型下拉修改
* @return {void}
*/
changeMapCareSelect(value) {
this.changeOrder(this.workOrderType);
if (this.elementDiv === "OverviewScreen" && !this.showMap) {
const [node] = this.$refs.screenCascader.getCheckedNodes();
this.screenMapPopoverName = node?.label;
this.getMapCare(value);
} else if (this.elementDiv != "OverviewScreen" || this.showMap) {
this.getLinePoint();
}
},
/**
* @description: 获取病害类型select下拉数据
* @param {*}
* @return {*}
*/
getAllDefectType() {
DefectType({ classType: this.bottomTipClick }).then(({ code, data }) => {
if (code === 200) {
this.defectSelectList = data;
}
});
},
/**
* @description: 工单修改时间事件
* @return {void}
*/
changeOrder(val) {
this.workOrderType = val;
getWorkOrderList({
companyId: this.companyId,
type: val,
classType: this.mapCareSelect.length > 0 ? this.mapCareSelect[0] : "",
defectType: this.mapCareSelect.length > 1 ? this.mapCareSelect[1] : "",
}).then(({ code, data }) => {
if (code === 200) {
this.workOrderList = [
{ name: "生成工单数", value: data.createdCount },
{ name: "未完成工单数", value: data.unFinishedCount },
{ name: "已完成工单数", value: data.finishedCount },
];
}
});
},
/**
* @description: 获取图片背景下坐标数据以及图例数据
* @return {void}
*/
getMapCare(value) {
const data = {
classType: value ? value[0] : "",
type: value ? (value.length > 1 ? value[1] : "") : "",
};
comppanyImg(data).then(({ code, data }) => {
if (code === 200) {
this.mapLegendList = data.basLinetypeSetting;
this.mapCareList = data.company;
}
});
},
/**
* @description: 点击图片背景下公司名称切换地图
* @return {void}
*/
showMapByCompany(val) {
this.companyId = val.id;
this.showMap = true;
this.getLinePoint();
this.changeOrder(this.workOrderType);
},
/**
* @description: 点击公司地图下返回按钮
* @return {void}
*/
disabledMapCompany() {
this.showMap = false;
this.markLayerLines = null;
this.companyId = null;
this.isCenterCalculated = false;
this.mapCareSelect = [];
this.getMapCare([]);
this.changeOrder(this.workOrderType);
},
/**
* @description: 点击病害日志详情打开弹窗进行地图打点
* @return {void}
*/
getimagePoint(item) {
this.imgTitle = "查看";
this.imageItem = item;
this.imgVisible = true;
// 清除点击得线段参数
this.defectMapPiont = {};
// 地图右上角多选按钮显示
this.getIconType();
this.showIconList = true;
// 地图打点\改变地图层级
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
this.$refs.roadMap.removeSelectClick();
map.getView().setCenter(item.tablePoint);
map.getView().setZoom(16);
});
this.shouldLoadClusters = false;
this.getCenterPiont();
},
/**
* @description: 关闭图片查看弹窗
* @return {void}
*/
imgCancel() {
this.imgTitle = "";
this.imageItem = {};
this.imgVisible = false;
},
/**
* @description: 关闭查看点位大图弹窗
* @return {void}
*/
screenImgCancel() {
this.$refs.roadMap.removeSelectClick();
this.showImageDialog = false;
},
/**
* @description: 切换icon类型多选框事件
* @return {void}
*/
handleChecked(value) {
this.centerPiont = this.drawPointList.filter(
(item) => value.indexOf(item.iconType) > -1
);
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.clusters);
this.clusters = null;
this.drawPoint();
});
},
/**
* @description: 获取地图点位信息
* @return {void}
*/
getCenterPiont() {
// 如果当前已经有打点坐标
if (this.clusters) {
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.clusters);
this.clusters = null;
});
}
mapPointList({
type: this.elementDiv,
classType: this.bottomTipClick,
...this.imageItem,
...this.defectMapPiont,
}).then(({ code, data }) => {
if (code === 200) {
this.drawPointList = data.map((item) => {
if (item.geometry) {
return {
...item,
geometry: [item.geometry[0], item.geometry[1]],
};
}
return [];
});
this.centerPiont = data.map((item) => {
if (item.geometry) {
return {
...item,
geometry: [item.geometry[0], item.geometry[1]],
};
}
return [];
});
// 如果不是病害巡检,则绘制点位
// 如果图片弹窗打开,则绘制点位
// if (!this.shouldLoadClusters) {
// 修改地图中心点位
const pointArray = data.map((item) => {
if (item.geometry) {
return [item.geometry[0], item.geometry[1]];
}
return [];
});
this.fitMapToPoints(pointArray);
this.drawPoint();
// }
}
});
},
/**
* @description: 根据点位计算地图中心点
* @return {void}
*/
fitMapToPoints(points) {
if (points.length > 0) {
// 创建一个空的 extent
let extent = [Infinity, Infinity, -Infinity, -Infinity];
// 计算所有点的边界框extent
points.forEach((point) => {
extent = [
Math.min(extent[0], point[0]),
Math.min(extent[1], point[1]),
Math.max(extent[2], point[0]),
Math.max(extent[3], point[1]),
];
});
// 获取地图实例
const map = this.$refs.roadMap.instance.get("map");
// 使用 fit 方法根据边界框计算最佳缩放级别
map.getView().fit(extent, {
duration: 500, // 动画持续时间
padding: [80, 500, 80, 500], // 边缘填充
});
}
},
/**
* @description: 绘制地图点位
* @return {void}
*/
drawPoint() {
const features = [];
this.centerPiont.forEach((element) => {
// 修改坐标样式
const point = new Point(element.geometry);
const feature = new Feature({
geometry: point,
data: element,
// 自己设置一个标识
type: "icon",
});
features.push(feature);
});
const clusterSource = new Cluster({
distance: this.mapZoom > 15 ? 0 : 100,
minDistance: this.mapZoom > 15 ? 0 : 100,
source: new VectorSource({
features,
}),
type: "Cluster",
});
this.clusters = new VectorLayer({
source: clusterSource,
name: "clusterLayer",
zIndex: 1,
style: (feature) => {
const count = feature.get("features").length;
if (count > 1) {
return new Style({
image: new Icon({
crossOrigin: "anonymous",
src: require(`@/assets/screen/index/龟裂.png`),
// 图标缩放比例
scale: 0.5,
displacement: [0, 30],
// 0.3为30度
// rotation: 0.3,
}),
text: new Text({
textAlign: "center", //位置
textBaseline: "middle",
font: "normal 14px 微软雅黑",
offsetY: -40,
fill: new Fill({
color: "#ffffff",
}),
text: count.toString(),
}),
});
} else {
return new Style({
image: new Icon({
crossOrigin: "anonymous",
src: require(`@/assets/screen/index/${
this.mapLogeList[
feature.getProperties().features[0].get("data").iconType
] || "龟裂"
}.png`),
// 图标缩放比例
scale: 0.5,
displacement: [0, 30],
// 0.3为30度
// rotation: 0.3,
}),
text: new Text({
textAlign: "center", //位置
textBaseline: "middle",
font: "normal 14px 微软雅黑",
offsetY: -40,
fill: new Fill({
color: "#ffffff",
}),
text: "",
}),
});
}
},
});
if (!this.shouldLoadClusters) {
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.addLayer(this.clusters);
});
}
},
/**
* @description: 获取地图线段点位信息
* @return {void}
*/
getLinePoint() {
// if (this.markLayerLines) {
// // 清除线段图层
// this.$nextTick(() => {
// const map = this.$refs.roadMap.instance.get("map");
// map.removeLayer(this.markLayerLines);
// this.markLayerLines = null;
// });
// }
let data = {};
if (this.elementDiv === "OverviewScreen") {
data = {
companyId: this.companyId,
classType: this.mapCareSelect.length > 0 ? this.mapCareSelect[0] : "",
defectType:
this.mapCareSelect.length > 1 ? this.mapCareSelect[1] : "",
};
} else {
data = {
companyId: this.companyId,
classType: this.bottomTipClick,
defectType: this.defectSelect,
};
}
mapLineList(data).then(({ code, data }) => {
if (code === 200 && data.lines.length > 0) {
this.mapLegendList = data.basLinetypeSetting;
this.lineString = data.lines;
this.drawLine();
// 修改地图中心点
if (!this.isCenterCalculated) {
const lineArray = data.lines.map((item) => {
return JSON.parse(item.line).map((it) => {
return [it.lon, it.lat];
});
});
// 创建 MultiLineString 对象
const multiLine = new MultiLineString(lineArray);
// 获取 MultiLineString 的边界框extent
const extent = multiLine.getExtent();
// 计算边界框的中心点
const center = getCenter(extent);
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
// map.getView().setCenter(center);
map.getView().animate({
center,
duration: 500,
});
map.getView().fit(extent, {
duration: 500,
padding: [80, 500, 80, 500], // 边缘填充(可选)
});
});
this.isCenterCalculated = true;
}
}
});
},
/**
* @description: 绘制地图线段
* @return {void}
*/
drawLine() {
this.shouldLoadClusters = true;
const features = [];
this.lineString.forEach((element) => {
const lines = JSON.parse(element.line).map((it) => {
return [it.lon, it.lat];
});
const line = new Feature({
geometry: new geomExports.LineString(lines),
data: {
name: element.segmentName,
count: element.defectCount,
segmentId: element.segmentId,
stakeEnd: element.stakeEnd,
stakeStart: element.stakeStart,
inspectDirection: element.inspectDirection,
},
type: "line",
});
line.setStyle([
new Style({
// 填充色
fill: new Fill({
color: "red",
}),
// 边线颜色
stroke: new Stroke({
color: this.getLineColor(element.status),
width: 3,
}),
// 形状
image: new Circle({
radius: 17,
fill: new Fill({
color: "#ffffff",
}),
}),
}),
]);
features.push(line);
});
const lineSource = new VectorSource({
features,
});
if (!this.markLayerLines) {
this.markLayerLines = new VectorLayer({
source: lineSource,
properties: {
type: "line",
},
});
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.addLayer(this.markLayerLines);
});
} else {
this.markLayerLines.setSource(lineSource);
}
},
/**
* @description: 地图线段颜色区分
* @param {number} value
* @return {string}
*/
getLineColor(value) {
if (value === 1) {
return "#0ABE67";
} else if (value === 2) {
return "#19C1E6";
} else if (value === 3) {
return "#E5CA18";
} else if (value === 4) {
return "#D47F07";
} else {
return "#E55557";
}
},
/**
* @description: 地图下方4图标类别切换点击事件
* @param {string} value
* @return {void}
*/
changeIconType(value) {
if (this.bottomTipClick !== value) {
this.defectSelect = "";
this.bottomTipClick = value;
this.getAllDefectType();
// 清空打点图层
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.clusters);
this.clusters = null;
// map.getView().setZoom(10);
// map.getView().setCenter([123.30297096718999, 41.87942945541742]);
});
// 地图右上角多选按钮隐藏
this.showIconList = false;
// this.getIconType();
// 绘制线段
this.getLinePoint();
}
},
/**
* @description: 获取icon多选数据
* @return {void}
*/
getIconType() {
this.mapLogeList = {};
getItemTypes({
classType: this.bottomTipClick,
type: this.elementDiv,
}).then(({ code, data }) => {
if (code === 200) {
this.iconTypeList = data;
this.iconType = data.map((item) => {
return item.value;
});
data.forEach((item) => {
this.mapLogeList[item.value] = item.label;
});
}
});
},
/**
* @description: 传回来的地图图层
* @param {number} zoom
* @return {void}
*/
getZoom(zoom) {
this.mapZoom = zoom;
if (this.clusters && zoom * 1 > 15) {
this.clusters.getSource().setDistance(0);
} else if (this.clusters && zoom * 1 <= 15) {
this.clusters.getSource().setDistance(100);
}
},
/**
* @description: 地图选中feature事件
* @param {object} e
* @return {void}
*/
featureSelect(e) {
const map = this.$refs.roadMap.instance.get("map");
const selectedFeatures = e.selected;
if (selectedFeatures.length > 0) {
let feature = selectedFeatures[0];
let features = feature.get("features");
// 点击线段事件
if (feature.getProperties().type === "line") {
// console.log(feature.get("data"), "线段参数");
this.drawDefectPoint(feature.get("data"));
} else if (feature.getProperties().type === "carPoint") {
console.log(feature, "小车点位");
} else {
if (features.length === 1) {
// 单个点位
// 执行之前的业务逻辑
// 获取点击的图层信息
const selectFeature = feature.getProperties().features[0];
console.log(selectFeature, "点位");
// 获取点位数据
this.screenImage = selectFeature.get("data");
this.showImageDialog = true;
// console.log(selectFeature.get("data"));
} else {
// 聚合点
// 放大地图层级
map.getView().animate({
center: feature.getGeometry().getCoordinates(),
zoom: map.getView().getZoom() + 1,
});
}
}
}
},
/**
* @description: 地图点击线段进行打点
* @param {object}
* @return {void}
*/
drawDefectPoint(item) {
this.defectMapPiont = item;
// 地图右上角多选按钮显示
// this.getIconType();
// this.showIconList = true;
// 地图打点\改变地图层级
// this.$nextTick(() => {
// const map = this.$refs.roadMap.instance.get("map");
// map.getView().setZoom(16);
// });
// this.roadSelect = item.segmentId;
this.shouldLoadClusters = false;
this.getCenterPiont();
},
/**
* @description: 数据栏切换事件
* @param {object} item
* @return {void}
*/
changeElement(item) {
if (this.elementDiv !== item.component) {
this.elementDiv = item.component;
// 清除点击得线段参数
this.defectMapPiont = {};
this.changeMapElement(item);
}
},
/**
* @description: 数据栏切换两侧数据和地图事件
* @param {object} item
* @return {void}
*/
changeMapElement: debounce(function (item) {
if (item.component === "OverviewScreen") {
this.leftModuleList = [
{
width: "100%",
height: "27%",
title: "今日巡查",
component: TodayInspection,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "27%",
title: "病害趋势",
component: DiseaseTrends,
selectIsShow: false,
class: "twe",
},
{
width: "100%",
height: "29%",
title: "病害统计",
component: DiseaseCurrent,
selectIsShow: true,
select: this.selectTypeArr[0].value,
class: "twe",
},
];
this.rightModuleList = [
{
width: "100%",
height: "18%",
title: "巡查里程",
component: PatrolOrder,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "65%",
title: "今日巡检车辆",
component: InspectionVehicles,
selectIsShow: false,
class: "twe",
},
];
// 清除已经点击的公司
this.companyId = null;
// 将线段中心点修改标识置为false
this.isCenterCalculated = false;
/* 清空线段图层 */
this.markLayerLines = null;
// 不展示地图
this.showMap = false;
// 不接收小车位置消息
const data = { type: "carLocation", status: false };
this.$ws.send(data);
this.$ws.removeEventListener("message", this.indexListenerId);
this.carPointList = [];
this.mapPointFeatures = [];
// 地图右上角多选按钮隐藏
this.showIconList = false;
// 图层恢复
this.mapZoom = "";
} else if (item.component === "RoadScreen") {
this.leftModuleList = [
{
width: "100%",
height: "17%",
title: "管养道路统计",
component: ManageMaintain,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "55%",
title: "附属设施分布",
component: AncillaryFacilities,
selectIsShow: false,
class: "twe",
},
];
this.rightModuleList = [
{
width: "100%",
height: "29%",
title: "附属设施异常统计",
component: AnomalyFacilities,
selectIsShow: true,
select: this.selectTypeArr[0].value,
class: "one",
},
{
width: "100%",
height: "57%",
title: "路产统计",
component: RoadStatistic,
selectIsShow: true,
select: this.selectTypeArr[0].value,
class: "twe",
},
];
// 清除已经点击的公司
this.companyId = null;
// 将线段中心点修改标识置为false
this.isCenterCalculated = false;
// 隐藏总览地图
this.showMap = true;
// 发送小车位置消息
const data = { type: "carLocation", status: true };
this.$ws.send(data);
this.$ws.on("message", this.handleMessage, this.indexListenerId);
// 地图右上角多选按钮显示
this.getIconType();
this.showIconList = true;
// 清除线段图层
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.markLayerLines);
this.markLayerLines = null;
});
this.shouldLoadClusters = false;
// 进行地图打点
this.getCenterPiont();
} else if (item.component === "DiseaseScreen") {
this.leftModuleList = [
{
width: "100%",
height: "27%",
title: "今日巡查",
component: TrafficSafety,
selectIsShow: false,
class: "one",
},
{
width: "100%",
height: "27%",
title: "主要病害趋势",
component: TrafficTrend,
selectIsShow: true,
select: this.selectTypeArr[0].value,
class: "twe",
},
{
width: "100%",
height: "33%",
title: "病害统计",
component: TrafficStatistic,
selectIsShow: true,
select: this.selectTypeArr[0].value,
class: "twe",
},
];
this.rightModuleList = [
{
width: "100%",
height: "85%",
title: "病害日志",
component: TrafficLog,
selectIsShow: false,
select: this.selectTypeArr[0].value,
class: "one",
},
];
// 清除已经点击的公司
this.companyId = null;
// 将线段中心点修改标识置为false
this.isCenterCalculated = false;
//隐藏总览地图
this.showMap = true;
// 发送小车位置消息
const data = { type: "carLocation", status: true };
this.$ws.send(data);
this.$ws.on("message", this.handleMessage, this.indexListenerId);
// 地图右上角多选按钮隐藏
this.showIconList = false;
// 图层恢复
this.mapZoom = "";
// 清除打点图层
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.clusters);
this.clusters = null;
});
this.getLinePoint();
}
}, 500),
/**
* @description: 处理websocket消息
* @return {*}
*/
handleMessage(itemMessage) {
if (itemMessage.type === "carPosition") {
if (this.carPointList.includes(itemMessage.data.entityId)) {
// 获取当前位置和目标位置
this.carMapPointSource.getFeatures().forEach((item) => {
if (item.get("data") === itemMessage.data.entityId) {
const currentLocation = item.getGeometry().getCoordinates();
const targetLocation = itemMessage.data.location;
// 计算两点之间的差值
const dx = (targetLocation[0] * 1 - currentLocation[0] * 1) / 20;
const dy = (targetLocation[1] * 1 - currentLocation[1] * 1) / 20;
// 设置计数器
let count = 0;
// 创建定时器,每50ms移动一次,总共移动20次,约1秒完成
const timer = setInterval(() => {
count++;
if (count >= 20) {
clearInterval(timer);
return;
}
// 计算当前帧的位置
const x = currentLocation[0] * 1 + dx * count;
const y = currentLocation[1] * 1 + dy * count;
// 更新小车位置
// const [features] = this.carMapPointSource.getFeatures();
item.setGeometry(new Point([x, y]));
item.setStyle([
new Style({
image: new Icon({
crossOrigin: "anonymous",
src: logo,
// 图标缩放比例
scale: 0.5,
// 将角度转换为弧度,并除以180*π
rotation:
(itemMessage.data.direction - 90) * (Math.PI / 180),
}),
}),
]);
}, 50);
}
});
} else {
this.carPointList.push(itemMessage.data.entityId);
this.drawCarMapPoint(itemMessage.data);
}
}
},
/**
* @description: 绘制小车地图点位
* @param {object} item
* @return {void}
*/
drawCarMapPoint(item) {
// const features = [];
const feature = new Feature({
geometry: new Point(item.location),
data: item.entityId,
type: "carPoint",
});
// 可以给点位设置样式
feature.setStyle([
new Style({
image: new Icon({
crossOrigin: "anonymous",
src: logo,
// 图标缩放比例
scale: 0.5,
// 将角度转换为弧度,并除以180*π
rotation: item.direction * (Math.PI / 180),
}),
}),
]);
this.mapPointFeatures.push(feature);
this.carMapPointSource = new VectorSource({
features: this.mapPointFeatures,
});
const carMapPointLayer = new VectorLayer({
source: this.carMapPointSource,
properties: {
type: "carPoint",
},
zIndex: 2,
});
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.addLayer(carMapPointLayer);
});
},
/**
* @description: 跳转系统首页
* @return {void}
*/
goIndex() {
this.$router.push("/index");
},
/**
* @description: 图片位置信息获取
* @return {void}
*/
updateScreenRects() {
1;
this.screenRects = [];
const image = this.$refs.mainImage;
const rects = this.screenImage?.rect?.split(",").map(Number) || [];
this.screenRects = [
{
left: rects[0],
top: rects[1],
width: rects[2],
height: rects[3],
},
];
},
/**
* @description: 图片红框位置
* @param {object} left
* @param {object} top
* @param {object} width
* @param {object} height
* @return {object}
*/
getScreenRectStyle({ left, top, width, height }) {
const image = this.$refs.mainImage;
const container = this.$refs.imageContainer;
if (!image || !container) return {};
const scaleX = container.clientWidth / image.naturalWidth;
const scaleY = container.clientHeight / image.naturalHeight;
const scale = Math.min(scaleX, scaleY);
const renderedWidth = image.naturalWidth * scale;
const renderedHeight = image.naturalHeight * scale;
const offsetX = (container.clientWidth - renderedWidth) / 2;
const offsetY = (container.clientHeight - renderedHeight) / 2;
return {
position: "absolute",
left: `${left * scale + offsetX}px`,
top: `${top * scale + offsetY}px`,
width: `${width * scale}px`,
height: `${height * scale}px`,
border: "2px solid #FF0000",
boxSizing: "border-box",
};
},
},
beforeDestroy() {
clearInterval(this.messageTimer);
clearInterval(this.timeFlag);
// 发送停止接收小车位置
const data = { type: "carLocation", status: false };
this.$ws.send(data);
},
};
</script>
<style lang="scss" scoped>
.screen-content {
width: 100%;
height: 100%;
}
// 中间样式
.screen-middle {
width: 100%;
height: 100%;
.screen-left {
width: 25.5%;
height: calc(100% - 5rem);
padding-left: 3.5rem;
position: fixed;
top: 5rem;
z-index: 1;
background-image: url("../../assets/screen/index/bg-left.png");
background-repeat: no-repeat;
background-size: 100% 100%;
::v-deep .screen-checkBox {
.el-radio-button__inner {
background-color: transparent;
padding: 0 0.3rem;
border: none;
font-size: 0.7rem;
font-family: "DouYu";
color: #ffffff;
}
.el-radio-button__orig-radio:checked + .el-radio-button__inner {
color: #1cb6ff;
}
}
}
.screen-right {
width: 25.5%;
height: calc(100% - 5rem);
top: 5rem;
padding-right: 3.5rem;
position: fixed;
right: 0;
z-index: 1;
background-image: url("../../assets/screen/index/bg-right.png");
background-repeat: no-repeat;
background-size: 100% 100%;
::v-deep .screen-checkBox {
.el-radio-button__inner {
background-color: transparent;
padding: 0 0.3rem;
border: none;
font-size: 0.7rem;
font-family: "DouYu";
color: #ffffff;
}
.el-radio-button__orig-radio:checked + .el-radio-button__inner {
color: #1cb6ff;
}
}
}
.road-content {
width: 100%;
height: 100%;
position: relative;
// 筛选病害类型下拉
.map-image-select {
position: absolute;
top: 13%;
left: 26%;
font-size: 0.9rem;
position: absolute;
color: #ffffff;
font-family: "DouYu";
z-index: 1;
.el-select {
width: 10rem;
}
}
// 返回图片背景下拉
.return-image {
position: absolute;
left: 26%;
top: 9%;
z-index: 1;
}
// 大屏工单数据部分
.work-order {
width: 35%;
height: 12%;
left: 34.5%;
top: 10%;
display: flex;
position: absolute;
z-index: 1;
.work-order-left {
width: 20%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
.btn-time {
cursor: pointer;
width: 5rem;
height: 1.8rem;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
background: url("~@/assets/screen/index/btn-time.png") no-repeat;
background-size: 100% 100%;
border-color: transparent;
color: #ffffff;
font-size: 0.7rem;
font-family: "DouYu";
&:hover {
background: url("~@/assets/screen/index/btn-time-click.png")
no-repeat;
background-size: 100% 100%;
}
}
.btn-time-click {
cursor: pointer;
background: url("~@/assets/screen/index/btn-time-click.png") no-repeat;
background-size: 100% 100%;
}
}
.work-order-right {
width: 80%;
height: 100%;
display: flex;
justify-content: space-around;
.loop-div {
width: 30%;
height: 100%;
padding-top: 0.5rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
background: url("~@/assets/screen/index/loop-div.svg") no-repeat;
background-size: 70% 70%;
background-position: center 80%;
.value {
font-size: 0.7rem;
font-family: "DouYu";
color: #ffffff;
span {
font-size: 1.4rem;
font-family: "DouYu";
background: linear-gradient(
to bottom,
rgba(0, 240, 255, 0.64),
rgba(89, 255, 235, 1)
);
/*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text;
/*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent;
/*给文字设置成透明*/
}
}
.name {
font-size: 0.7rem;
font-family: "DouYu";
color: #ffffff;
}
}
}
}
// 图例
.map-legend {
height: 7rem;
width: 2.5rem;
position: absolute;
bottom: 16%;
right: 27%;
padding-left: 0.5rem;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
font-size: 0.8rem;
color: #ffffff;
user-select: none;
background-image: url("~@/assets/screen/index/map-legend.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
// 右上角切换图标样式多选框
.road-checkBox {
width: 8rem;
height: 10rem;
position: absolute;
right: 26%;
top: 10%;
padding: 0.4rem;
border-radius: 0.4rem;
border: 1px solid #193dae;
background-color: #082843;
z-index: 1;
.road-scroll {
overflow-x: hidden;
}
::v-deep .el-checkbox__label {
color: #9aadd8;
}
}
// 图片背景样式
.disease-content {
width: 100%;
height: 100%;
background-image: url("../../assets/screen/index/map-liaoning.png");
background-repeat: no-repeat;
background-size: 100% 100%;
position: relative;
// 标题
.disease-title {
width: 20rem;
height: 2.8rem;
position: absolute;
// top: 5rem;
left: 50%;
transform: translate(-50%, 5rem);
background-image: url("../../assets/screen/index/disease-title.png");
background-repeat: no-repeat;
background-size: 100%;
}
// 打点部分
.map-care {
width: 48%;
height: 73%;
position: absolute;
left: 26%;
top: 13%;
.map-care-div {
height: 2rem;
min-width: 3.5rem;
display: flex;
justify-content: center;
line-height: 1.6rem;
font-size: 0.7rem;
color: #ffffff;
position: absolute;
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
cursor: pointer;
height: 1rem;
}
}
.map-care-div-1 {
background-image: url("~@/assets/screen/index/map-care-div-1.png");
}
.map-care-div-2 {
background-image: url("~@/assets/screen/index/map-care-div-2.png");
}
.map-care-div-3 {
background-image: url("~@/assets/screen/index/map-care-div-3.png");
}
.map-care-div-4 {
background-image: url("~@/assets/screen/index/map-care-div-4.png");
}
.map-care-div-5 {
background-image: url("~@/assets/screen/index/map-care-div-5.png");
}
.map-care-div-6 {
background-image: url("~@/assets/screen/index/map-care-div-6.png");
}
}
}
// 内网不需要 外网需要
::v-deep .baseLayerClass {
filter: grayscale(200%) invert(200%) sepia(50%) hue-rotate(175deg)
brightness(80%) saturate(550%);
}
}
}
// 头部样式
.screen-header {
width: 100%;
height: 5rem;
padding: 1rem 3rem;
position: fixed;
top: 0;
display: flex;
justify-content: space-between;
z-index: 1;
background-image: url("../../assets/screen/index/bg-top.png");
background-repeat: no-repeat;
background-size: 100% 120%;
background-position-x: 50%;
.header-weather {
display: flex;
align-items: flex-end;
font-size: 1rem;
color: #89c5e8;
}
.header-time {
display: flex;
color: #89c5e8;
font-size: 1rem;
> div {
margin: 0 0.5rem;
display: flex;
align-items: flex-end;
}
// 消息中心样式
.header-news {
margin-right: 1rem;
i {
position: relative;
cursor: pointer;
font-size: 1.5rem;
.num {
min-width: 0.9rem;
position: absolute;
top: -0.2rem;
right: -0.5rem;
padding: 0.2rem;
font-size: 0.6rem;
border-radius: 0.5rem;
color: #ffffff;
background-color: red;
}
}
}
.header-data {
font-size: 1.8rem;
}
.header-week {
display: flex;
align-items: flex-start;
justify-content: flex-end;
flex-direction: column;
}
.header-home {
.home {
cursor: pointer;
height: 1.5rem;
width: 1.2rem;
background-image: url("../../assets/screen/index/exit.png");
background-repeat: no-repeat;
background-size: 100%;
}
}
}
}
// 大屏下方样式
.screen-footer {
width: 49%;
height: 7.55rem;
position: fixed;
bottom: 0;
left: 25.5%;
background-image: url("../../assets/screen/index/bg-foot.png");
background-repeat: no-repeat;
background-size: 100.1% 99%;
.footer-change-map {
width: 100%;
height: 40%;
display: flex;
justify-content: center;
align-items: center;
color: #8deeff;
font-style: italic;
font-size: 0.7rem;
.change-map-div {
cursor: pointer;
margin: 0 2rem;
}
.change-map-click {
color: #fffed2;
}
}
.footer-change-vue {
width: 100%;
height: 60%;
display: flex;
justify-content: center;
align-items: center;
> div {
height: 100%;
width: 37.5%;
}
> div:nth-child(2) {
height: 100%;
width: 25%;
}
// 未点击样式
.change-vue-OverviewScreen {
background-image: url("../../assets/screen/index/button-overview.png");
background-repeat: no-repeat;
background-size: 95% 60%;
background-position: 75% 15%;
}
.change-vue-click-OverviewScreen {
background-image: url("../../assets/screen/index/button-overview-click.png");
background-repeat: no-repeat;
background-size: 95% 60%;
background-position: 75% 15%;
}
.change-vue-DiseaseScreen {
background-image: url("../../assets/screen/index/button-disease.png");
background-repeat: no-repeat;
background-size: 99% 60%;
background-position: 50% 13%;
}
.change-vue-click-DiseaseScreen {
background-image: url("../../assets/screen/index/button-disease-click.png");
background-repeat: no-repeat;
background-size: 99% 60%;
background-position: 50% 13%;
}
.change-vue-RoadScreen {
background-image: url("../../assets/screen/index/button-road.png");
background-repeat: no-repeat;
background-size: 93% 60%;
background-position: 15% 15%;
}
.change-vue-click-RoadScreen {
background-image: url("../../assets/screen/index/button-road-click.png");
background-repeat: no-repeat;
background-size: 93% 60%;
background-position: 15% 15%;
}
// .change-vue-click {
// color: red;
// }
}
}
/* 修改弹窗样式 */
::v-deep .el-dialog {
background-color: transparent;
}
::v-deep .el-dialog__header {
padding: 10px;
background-color: #113463;
span,
i {
color: #ffffff;
}
}
::v-deep .el-dialog__body {
padding: 0;
background-color: #113463;
/* 查看点位大图弹窗 */
.view-image-container {
position: relative;
width: 100%;
height: 50rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
.view-image-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.rect-overlay {
position: absolute;
// pointer-events: none;
border: 2px solid red;
}
}
// 图片信息
.rect-image {
width: 90%;
position: absolute;
top: 0;
font-size: 1.2rem;
color: #ffffff;
background-color: rgba(0, 0, 0, 0.5);
}
// 大屏下拉框样式
::v-deep .el-select {
width: 6.5rem;
.el-input .el-select__caret {
line-height: 1.5rem;
}
.el-input--medium .el-input__inner {
height: 1.5rem;
background-color: transparent;
color: #89c5e8;
border-color: #6991cd;
}
}
// 修改级联样式
::v-deep .el-cascader {
width: 10rem;
.el-input--medium .el-input__inner {
height: 1.5rem;
background-color: rgba(38, 38, 38, 0.7);
color: #89c5e8;
border-color: #6991cd;
}
}
</style>
<style lang="scss">
// 下拉样式
.screen-select {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.el-select-dropdown__item {
color: #aaabb8;
}
.el-select-dropdown__item:hover {
background-color: #2b4c7e;
}
.el-select-dropdown__item.selected {
background-color: #2b4c7e;
}
.el-select-dropdown__item.hover {
background-color: #2b4c7e;
}
}
.el-select-dropdown__list {
background-color: #102649;
}
}
}
}
// 级联样式
.screen-index-cascader {
background-color: #102649;
border-color: #08204f;
.el-cascader-node__label {
color: #aaabb8;
}
.el-cascader-node:hover {
background-color: #2b4c7e;
}
.el-cascader-node:active {
background-color: #2b4c7e;
}
.el-cascader-node:focus {
background-color: #2b4c7e;
}
}
// 大屏消息弹出框样式
.screen-message-popover {
background-color: rgba(0, 0, 0, 0.8);
border: none;
.screen-message-content {
width: 100%;
color: #ffffff;
.message-content {
width: 100%;
max-height: 12rem;
.message-item {
padding: 0.5rem 0;
border-bottom: 1px dashed rgb(115, 115, 116);
.item-top {
width: 100%;
display: flex;
&:hover {
span {
color: rgb(113, 179, 255);
}
}
.time {
width: 40%;
}
}
.item-content {
padding-left: 1rem;
}
}
}
.message-footer {
display: flex;
justify-content: flex-end;
}
}
}
// 大屏总览地图坐标弹出层样式
.screen-map-popover {
background: url("~@/assets/screen/index/screen-map-popover.png") no-repeat;
background-size: 100% 100%;
border: none;
// 图片地图打点popover弹窗
.screen-map-popover-content {
font-family: "DouYu";
font-size: 0.6rem;
color: #cccccc;
.item {
.name {
width: 7rem;
line-height: 1rem;
display: inline-block;
}
.value {
color: rgb(227, 164, 27);
}
}
}
}
</style>