fix:页面新修改,重新分类,大屏样式修改

This commit is contained in:
SunTao 2024-11-11 14:40:40 +08:00
parent 867fd802fe
commit b029559c73
30 changed files with 6231 additions and 505 deletions

View File

@ -2,22 +2,30 @@
* @Author: SunTao 328867980@qq.com * @Author: SunTao 328867980@qq.com
* @Date: 2024-10-22 15:30:25 * @Date: 2024-10-22 15:30:25
* @LastEditors: SunTao 328867980@qq.com * @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-04 15:19:03 * @LastEditTime: 2024-11-11 14:37:32
* @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue * @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue
* @Description: 大屏查看图片弹窗 * @Description: 大屏查看图片弹窗
--> -->
<template> <template>
<div class="app"> <div class="app">
<div class="sidebar" ref="sidebar" @scroll="handleScroll"> <div class="left-list">
<img <div class="img-top">
v-for="(item, index) in defectData" <el-radio-group v-model="labelCheck" size="small">
:key="item.id" <el-radio-button label="left">目标维度</el-radio-button>
:src="item.media[0].img" <el-radio-button label="right">空间维度</el-radio-button>
:alt="'Image ' + (index + 1)" </el-radio-group>
@click="showImage(index)" </div>
:class="{ selected: currentIndex === index }" <div class="sidebar" ref="sidebar" @scroll="handleScroll">
/> <img
v-for="(item, index) in defectData"
:key="item.id"
:src="item.media[0].img"
:alt="'Image ' + (index + 1)"
@click="showImage(index)"
:class="{ selected: currentIndex === index }"
/>
</div>
</div> </div>
<div class="main-content"> <div class="main-content">
@ -30,73 +38,64 @@
:inline="true" :inline="true"
label-width="5rem" label-width="5rem"
> >
<el-row :gutter="24"> <el-form-item label="路段名称">
<el-col :span="7"> <el-select
<el-form-item label="路段名称"> v-model="imgForm.segmentId"
<el-select placeholder="请选择路段名称"
v-model="imgForm.segmentId" :popper-append-to-body="false"
placeholder="请选择路段名称" clearable
:popper-append-to-body="false" >
clearable <el-option
> v-for="item in roadTypeList"
<el-option :key="item.value"
v-for="item in roadTypeList" :label="item.label"
:key="item.value" :value="item.value"
:label="item.label" />
:value="item.value" </el-select>
/> </el-form-item>
</el-select>
</el-form-item> <el-form-item label="病害类型">
</el-col> <el-select
<el-col :span="7"> v-model="imgForm.defectType"
<el-form-item label="病害类型"> placeholder="请选择路段名称"
<el-select :popper-append-to-body="false"
v-model="imgForm.defectType" clearable
placeholder="请选择路段名称" >
:popper-append-to-body="false" <el-option
clearable v-for="item in defectTypeList"
> :key="item.value"
<el-option :label="item.label"
v-for="item in defectTypeList" :value="item.value"
:key="item.value" />
:label="item.label" </el-select>
:value="item.value" </el-form-item>
/>
</el-select> <el-form-item label="公里桩">
</el-form-item> <el-input
</el-col> v-model="imgForm.stakeStart"
<el-col :span="10"> placeholder="起始公里桩"
<el-form-item label="公里桩"> style="width: 8rem"
<el-input clearable
v-model="imgForm.stakeStart" />
placeholder="起始公里桩" <span style="margin: 0 5px">-</span>
style="width: 8rem" <el-input
clearable v-model="imgForm.stakeEnd"
/> placeholder="终止公里桩"
<span style="margin: 0 5px">-</span> style="width: 8rem"
<el-input clearable
v-model="imgForm.stakeEnd" />
placeholder="终止公里桩" </el-form-item>
style="width: 8rem"
clearable <el-button
/> type="primary"
</el-form-item> icon="el-icon-search"
</el-col> size="mini"
</el-row> @click="handleQuery"
<el-row> >搜索</el-button
<el-col :span="6"> >
<el-button <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
type="primary" >重置</el-button
icon="el-icon-search" >
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-col>
</el-row>
</el-form> </el-form>
</div> </div>
<!-- 图片展示 --> <!-- 图片展示 -->
@ -114,12 +113,13 @@
:key="index" :key="index"
:style="getRectStyle(rect)" :style="getRectStyle(rect)"
></div> ></div>
</div> <div class="image-info">
<div class="image-info"> 采集时间:
采集时间: {{ new Date(rectsItem.createdTime).toLocaleString() }}<br /> {{ new Date(rectsItem.createdTime).toLocaleString() }} 起始桩号:
起始桩号: {{ rectsItem.stakeStart || "暂无数据" }} 终止桩号: {{ rectsItem.stakeStart || "暂无数据" }} 终止桩号:
{{ rectsItem.stakeEnd || "暂无数据" }}<br /> {{ rectsItem.stakeEnd || "暂无数据" }}
路产状态: {{ filterState(rectsItem.state) }} 路产状态: {{ filterState(rectsItem.state) }}
</div>
</div> </div>
</div> </div>
<!-- 小图展示 --> <!-- 小图展示 -->
@ -144,6 +144,9 @@ export default {
name: "ImgDialog", name: "ImgDialog",
data() { data() {
return { return {
//
labelCheck: "left",
// //
defectData: [], defectData: [],
// index // index
@ -192,9 +195,9 @@ export default {
}, },
}, },
created() { created() {
this.getSegmentList(); // this.getSegmentList();
this.getDefectStatusList(); // this.getDefectStatusList();
this.getDefectType(); // this.getDefectType();
}, },
methods: { methods: {
/* 查询病害状态下拉数据 */ /* 查询病害状态下拉数据 */
@ -319,18 +322,13 @@ export default {
if (currentImageElement) { if (currentImageElement) {
currentImageElement.scrollIntoView({ currentImageElement.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "nearest", block: "center",
}); });
} }
}, },
/* 滚动触发事件 */ /* 滚动触发事件 */
handleScroll() { handleScroll() {
// + if (this.currentIndex === this.defectData.length - 1) {
const sidebar = this.$refs.sidebar;
if (
sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 &&
!this.loading
) {
this.loadMoreImages(); this.loadMoreImages();
} }
}, },
@ -342,6 +340,7 @@ export default {
/* 键盘事件 */ /* 键盘事件 */
handleKeydown(event) { handleKeydown(event) {
if (event.key === "ArrowUp") { if (event.key === "ArrowUp") {
event.preventDefault();
if (this.currentIndex > 0) { if (this.currentIndex > 0) {
this.currentIndex--; this.currentIndex--;
this.selectedThumbnail = 0; // Reset when changing main images via keyboard this.selectedThumbnail = 0; // Reset when changing main images via keyboard
@ -349,6 +348,7 @@ export default {
this.updateRects(); this.updateRects();
} }
} else if (event.key === "ArrowDown") { } else if (event.key === "ArrowDown") {
event.preventDefault();
if (this.currentIndex <= this.defectData.length - 1) { if (this.currentIndex <= this.defectData.length - 1) {
this.currentIndex === this.defectData.length - 1 this.currentIndex === this.defectData.length - 1
? this.currentIndex ? this.currentIndex
@ -433,43 +433,65 @@ export default {
background-color: #2e3a46; background-color: #2e3a46;
} }
.sidebar { .left-list {
width: 250px; width: 16rem;
background-color: #1f292e; height: 100%;
padding: 10px;
overflow-y: auto;
}
.sidebar::-webkit-scrollbar { .img-top {
width: 8px; width: 100%;
} height: 2.5rem;
display: flex;
justify-content: center;
.sidebar::-webkit-scrollbar-track { ::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
background: #2e3a46; background-color: #467198;
border-radius: 10px; }
}
.sidebar::-webkit-scrollbar-thumb { ::v-deep .el-radio-button__inner{
background: #444c51; color: #ffffff;
border-radius: 10px; background-color: transparent;
} }
}
.sidebar::-webkit-scrollbar-thumb:hover { .sidebar {
background: #00aaff; width: 15.5rem;
} height: calc(100% - 2.5rem);
background-color: #1f292e;
padding: 10px;
overflow-y: auto;
}
.sidebar img { .sidebar::-webkit-scrollbar {
width: 100%; width: 8px;
margin-bottom: 5px; }
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.sidebar img.selected { .sidebar::-webkit-scrollbar-track {
border: 3px solid #00aaff; background: #2e3a46;
transform: scale(1.05); border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb {
background: #444c51;
border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: #00aaff;
}
.sidebar img {
width: 100%;
margin-bottom: 5px;
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.sidebar img.selected {
border: 3px solid #00aaff;
transform: scale(1.05);
}
} }
.main-content { .main-content {
@ -482,7 +504,7 @@ export default {
.toolbar { .toolbar {
width: 100%; width: 100%;
height: 6rem; height: 4rem;
display: flex; display: flex;
align-items: center; align-items: center;
background-color: #333c42; background-color: #333c42;
@ -544,11 +566,18 @@ export default {
.image-container { .image-container {
position: relative; position: relative;
width: 100%; width: 100%;
height: 80%; height: 95%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden; overflow: hidden;
.image-info {
position: absolute;
color: red;
bottom: 0;
left: 10%;
}
} }
.image-container img { .image-container img {
@ -564,7 +593,7 @@ export default {
} }
.image-viewer { .image-viewer {
height: 32rem; height: 34rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;

View File

@ -0,0 +1,376 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-11-08 11:56:02
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-08 14:53:32
* @FilePath: \znxjxt-ui\src\views\big-screen\traffic-components\traffic-log.vue
* @Description: 病害巡检-交安事件日志
-->
<template>
<div class="content">
<!-- 搜索表单 -->
<div class="traffic-form">
<el-form
:model="trafficForm"
ref="trafficForm"
size="small"
:inline="true"
label-position="left"
label-width="5rem"
>
<el-form-item class="form-item" label="道路名称" prop="segmentName">
<el-select
v-model="trafficForm.segmentName"
:popper-append-to-body="false"
placeholder="请选择道路名称"
clearable
>
<el-option
v-for="item in segmentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item class="form-item" label="上下行" prop="inspectDirection">
<el-select
v-model="trafficForm.inspectDirection"
:popper-append-to-body="false"
placeholder="请选择"
clearable
>
<el-option label="上行" value="0" />
<el-option label="下行" value="1" />
</el-select>
</el-form-item>
<el-form-item class="form-item" label="公里桩" prop="stakeRange">
<el-input
v-model="trafficForm.stakeStart"
placeholder="起始公里桩"
style="width: 9rem"
clearable
/>
<span style="margin: 0 5px; color: #ffffff">-</span>
<el-input
v-model="trafficForm.stakeEnd"
placeholder="终止公里桩"
style="width: 9rem"
clearable
/>
<el-tooltip
class="item"
effect="dark"
content="格式为K0000+000"
placement="top"
>
<i :style="{ color: '#ffffff' }" class="el-icon-info"></i>
</el-tooltip>
</el-form-item>
<el-form-item class="form-item" label="事件类型" prop="equipmentType">
<el-select
v-model="trafficForm.equipmentType"
:popper-append-to-body="false"
placeholder="请选择事件类型"
clearable
>
<el-option
v-for="item in eventType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item class="form-item" label="事件状态" prop="state">
<el-select
v-model="trafficForm.state"
:popper-append-to-body="false"
placeholder="请选择事件状态"
clearable
>
<el-option
v-for="item in defectStatus"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
</div>
<div class="form-btn">
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</div>
<div class="traffic-title">
<div class="emergency-type">事件类型</div>
<div class="emergency-name">段路名称</div>
<div class="emergency-status">事件状态</div>
<div class="emergency-operation">操作</div>
</div>
<div class="traffic-table">
<vue-seamless-scroll
class="vue-scroll"
:class-option="defaultOption"
:data="emergencyList"
>
<div
class="emergency-bottom-div"
v-for="(item, index) in emergencyList"
:key="`emergency-${index}`"
>
<div class="emergency-type">{{ item.type }}</div>
<div class="emergency-name">{{ item.segmentName }}</div>
<div class="emergency-status"><a></a>{{ item.status }}</div>
<div class="emergency-operation">操作</div>
</div>
</vue-seamless-scroll>
</div>
</div>
</template>
<script>
import { emergencyData } from "@/api/xj/screen/traffic-screen";
import vueSeamlessScroll from "vue-seamless-scroll";
export default {
name: "TrafficLog",
components: { vueSeamlessScroll },
props: {
// 4
bottomTipClick: {
type: String,
default: "",
},
},
data() {
return {
//
trafficForm: {
//
segmentName: "",
//
inspectDirection: "",
//
stakeStart: "",
stakeEnd: "",
//
equipmentType: "",
//
state: "",
},
//
segmentList: [],
//
eventType: [],
//
defectStatus: [],
//
defaultOption: {
step: 0.2, //
limitMoveNum: 1,
hoverStop: true, // stop
direction: 1, // 0 1 2 3
openWatch: true, // dom
singleHeight: 0, // (0)direction => 0/1
singleWidth: 0, // (0) direction => 2/3
waitTime: 2000, // (1000ms)
},
//
emergencyList: [],
};
},
created() {
this.getData();
},
methods: {
/* 点击搜索事件 */
handleQuery() {},
/* 点击重置事件 */
resetQuery() {},
/* 获取事件列表数据 */
getData() {
emergencyData().then(({ code, data }) => {
if (code === 200) {
this.emergencyList = data;
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
.traffic-form {
width: calc(100% - 0.5rem);
height: 38%;
padding: 0.5rem;
.form-item {
width: 100%;
::v-deep .el-form-item__content {
width: calc(100% - 5rem);
.el-select {
width: 100%;
}
}
::v-deep .el-form-item__label {
color: #ffffff;
}
}
::v-deep .el-input__inner {
color: #ffffff;
border-color: #47536f;
background-color: transparent;
}
::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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
}
.form-btn {
height: 4%;
width: 100%;
display: flex;
justify-content: flex-end;
}
.traffic-title {
width: 100%;
height: 7%;
display: flex;
align-items: center;
// border: 1px solid #0b7ecf;
color: #e6fcfe;
font-size: 0.9rem;
padding: 0 0.5rem;
background-image: url("../../../assets/screen/traffic/emergency-top.png");
background-repeat: no-repeat;
background-size: 100% 90%;
background-position: 50% 100%;
.emergency-type {
width: 30%;
}
.emergency-name {
width: 30%;
}
.emergency-status {
width: 30%;
}
.emergency-operation {
width: 10%;
}
}
.traffic-table {
width: 100%;
height: 51%;
overflow: hidden;
.emergency-bottom-div {
height: 2rem;
font-size: 0.8rem;
display: flex;
&:nth-child(2n + 1) {
background-color: rgba(17, 52, 99, 0.3);
}
> div {
margin: 0 0.3rem;
line-height: 2rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #808c9f;
}
.emergency-type {
width: 27%;
}
.emergency-name {
width: 27%;
}
.emergency-status {
width: 27%;
a {
display: inline-block;
width: 0.5rem;
height: 0.5rem;
margin-right: 0.5rem;
background-color: #f7da15;
border-radius: 0.25rem;
}
}
.emergency-operation {
width: 10%;
color: #0d9ee2;
}
}
}
}
</style>

View File

@ -0,0 +1,161 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-21 09:59:32
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-28 11:42:15
* @FilePath: \znxjxt-ui\src\views\big-screen\traffic-components\traffic-safety.vue
* @Description: 病害巡检大屏-交安事件
-->
<template>
<div class="content">
<div class="traffic-left">
<span>{{ today }}</span>
</div>
<div class="traffic-right">
<div class="right-sum">
<span>{{ all }}</span
>
</div>
<div class="right-rate">
<span> {{ scale }} </span>%
</div>
</div>
</div>
</template>
<script>
import { safetyData } from "@/api/xj/screen/traffic-screen";
export default {
name: "TrafficSafety",
props: {
// 4
bottomTipClick: {
type: String,
default: "",
},
},
data() {
return {
today: 0,
all: 0,
scale: 0,
};
},
created() {
this.getData();
},
methods: {
getData() {
safetyData().then(({ code, data }) => {
if (code === 200) {
this.today = data.today;
this.all = data.all;
this.scale = data.scale;
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
display: flex;
.traffic-left {
width: 45%;
height: 100%;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
padding-left: 1.5rem;
font-size: 2rem;
background-image: url("../../../assets/screen/traffic/traffic-left.png");
background-repeat: no-repeat;
background-size: 85%;
background-position: 100% 60%;
span {
font-family: "DouYu";
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.traffic-right {
width: 55%;
height: 100%;
padding: 1rem;
display: flex;
flex-direction: column;
justify-content: space-around;
color: #ffffff;
.right-sum {
width: 100%;
height: 4rem;
display: flex;
padding-left: 1rem;
justify-content: center;
line-height: 3rem;
background-image: url("../../../assets/screen/traffic/right-sum.png");
background-repeat: no-repeat;
background-size: 100%;
background-position: 100% 50%;
color: #aac6c7;
font-size: 0.9rem;
span {
margin-right: 0.5rem;
font-size: 1.2rem;
font-family: "DouYu";
background: linear-gradient(
to bottom,
#ffffff,
#21f1e1
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.right-rate {
width: 100%;
height: 4rem;
display: flex;
justify-content: center;
padding-left: 1rem;
line-height: 3rem;
background-image: url("../../../assets/screen/traffic/right-rate.png");
background-repeat: no-repeat;
background-size: 100%;
background-position: 100% 50%;
color: #aac6c7;
font-size: 0.9rem;
span {
margin-right: 0.5rem;
font-size: 1.2rem;
font-family: "DouYu";
background: linear-gradient(
to bottom,
#ffffff,
#e9bc5c
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
}
}
</style>

View File

@ -0,0 +1,309 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-21 10:06:24
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-11 10:08:56
* @FilePath: \znxjxt-ui\src\views\big-screen\traffic-components\traffic-statistic.vue
* @Description: 病害巡检大屏-交安事件统计
-->
<template>
<div class="content">
<div class="statistic-select">
<el-select
:popper-append-to-body="false"
v-model="itemSelect"
placeholder="请选择"
>
<el-option
v-for="item in currentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div ref="statisticChart" class="statistic-chart"></div>
<div class="statistic-lenged">
<div
class="lenged-item"
v-for="(item, index) in echartList"
:key="`static-${index}`"
>
<div class="index" :style="{ backgroundColor: colorList[index] }"></div>
<div class="name">{{ item.name }}</div>
<div class="rate">{{ item.rate }}</div>
<div class="value">{{ item.value }}</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { getDropList } from "@/api/xj/screen/disease-screen";
import { statisticData } from "@/api/xj/screen/traffic-screen";
export default {
name: "TrafficStatistic",
props: {
select: {
type: String,
default: "",
},
// 4
bottomTipClick: {
type: String,
default: "",
},
},
data() {
return {
//
itemSelect: "",
//
currentList: [],
//
colorList: [
"#18F7FF",
"#6FC36F",
"#4C83FF",
"#FFEA68",
"#FF8F5F",
"#FC5976",
"#AE74F3",
"#4C21D5",
"#6669DB",
],
// echart
echartList: [],
//
sum: 0,
// echart
echart: null,
};
},
watch: {
select: {
handler(val) {
if (val) {
this.itemSelect = "";
this.getCurrentList();
this.getChartData();
}
},
},
itemSelect: {
handler() {
this.getChartData();
},
},
},
created() {
this.getChartData();
},
methods: {
/* 获取右上角下拉框数据 */
getCurrentList() {
getDropList({ type: this.select }).then(({ data, code }) => {
if (code === 200) {
this.currentList = data;
}
});
},
/* 获取echart图数据 */
getChartData() {
const data = {
itemName: this.itemSelect,
type: this.select,
};
statisticData(data).then(({ data, code }) => {
if (code === 200) {
this.sum = 0;
data.forEach((element) => {
this.sum += element.value;
});
this.echartList = data.map((item) => {
return {
...item,
name: item.typeName,
};
});
this.$nextTick(() => {
this.drawChart();
});
}
});
},
/* 绘制echart图 */
drawChart() {
if (this.echart) {
this.echart.dispose();
}
this.echart = echarts.init(this.$refs.statisticChart);
this.echart.setOption({
color: this.colorList,
tooltip: {
confine: true,
backgroundColor: "rgba(9, 24, 48, 0.5)",
borderColor: "rgba(75, 253, 238, 0.4)",
textStyle: {
fontSize: 12,
color: "#808C9F",
},
},
title: [
//
{
text: "交安事件总数",
left: "center",
top: "50%",
textStyle: {
fontFamily: "DinBm",
fontSize: 12,
color: "#ffffff",
},
},
{
text: this.sum,
left: "center",
top: "40%",
textStyle: {
fontFamily: "DouYu",
fontSize: 20,
color: "rgba(255, 183, 89, 0.8)",
},
},
],
grid: {
top: "0%",
left: "0%",
right: "0%",
bottom: "0%",
containLabel: true,
},
legend: {
show: false,
orient: "horizontal",
// itemWidth: 16,
itemHeight: 16,
icon: "circle",
right: 40,
bottom: "0%",
textStyle: {
color: "rgba(0,0,0,0.65)",
},
height: 10,
formatter: (name) => {
const value = this.echartList.find(
(item) => item.name === name
).value;
return `${name}${value}`;
},
},
series: [
{
type: "pie",
radius: ["45%", "60%"],
center: ["50%", "50%"],
label: {
//
show: false,
position: "center",
formatter: (params) => {
return `{a|${params.percent.toFixed()}%}\n{b|${params.name}}`;
},
rich: {
a: {
fontFamily: "DouYu",
fontSize: 28,
color: "rgba(255, 183, 89, 0.8)",
},
b: {
fontFamily: "DinBm",
fontSize: 12,
color: "#ffffff",
},
},
},
emphasis: {
label: {
show: false,
fontSize: 20,
fontWeight: "bold",
},
},
data: this.echartList,
},
],
});
window.addEventListener("resize", () => {
this.echart.resize();
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
display: flex;
position: relative;
.statistic-select {
position: absolute;
z-index: 1;
right: 0;
top: 0.2rem;
}
.statistic-chart {
width: 50%;
height: 100%;
z-index: 0;
background-image: url("../../../assets/screen/traffic/statistic-chart.png");
background-repeat: no-repeat;
background-position: 100%;
background-size: 100%;
}
.statistic-lenged {
width: 50%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
z-index: 0;
.lenged-item {
width: 100%;
height: 1rem;
margin: 0.1rem 0;
display: flex;
align-items: center;
color: #808c9f;
font-size: 0.7rem;
.index {
width: 0.8rem;
height: 0.5rem;
margin-right: 0.5rem;
}
.name {
width: 5rem;
}
.rate {
font-size: 0.8rem;
width: 2.5rem;
}
.value {
font-size: 0.8rem;
width: 3rem;
}
}
}
}
</style>

View File

@ -0,0 +1,332 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-21 10:03:08
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-11 10:08:41
* @FilePath: \znxjxt-ui\src\views\big-screen\traffic-components\traffic-trend.vue
* @Description: 病害巡检大屏-交安事件趋势
-->
<template>
<div class="content">
<div class="traffic-select">
<el-select
:popper-append-to-body="false"
v-model="itemSelect"
placeholder="请选择"
>
<el-option
v-for="item in trafficList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div ref="trafficChart" class="traffic-echart"></div>
</div>
</template>
<script>
import { getDropList } from "@/api/xj/screen/disease-screen";
import { eventLog } from "@/api/xj/screen/traffic-screen";
import * as echarts from "echarts";
export default {
name: "TrafficTrend",
props: {
//
select: {
type: String,
default: "",
},
// 4
bottomTipClick: {
type: String,
default: "",
},
},
data() {
return {
//
itemSelect: "",
//
trafficList: [],
// echart
echartData: [],
// echart
chart: null,
};
},
watch: {
select: {
handler(val) {
if (val) {
this.itemSelect = "";
this.getCurrentList();
this.getChartData();
}
},
},
itemSelect: {
handler() {
this.getChartData();
},
},
},
created() {
this.getChartData();
},
methods: {
/* 获取右上角下拉框数据 */
getCurrentList() {
getDropList({ type: this.select }).then(({ data, code }) => {
if (code === 200) {
this.trafficList = data;
}
});
},
/* 获取柱状图数据 */
getChartData() {
const data = {
id: this.itemSelect,
type: this.select,
};
eventLog(data).then(({ data, code }) => {
if (code === 200) {
this.echartData = data;
this.$nextTick(() => {
this.drawChart();
});
}
});
},
/* 绘制echart */
drawChart() {
if (this.chart) {
this.chart.dispose();
}
const xData = this.echartData.map((item) => {
return item.label;
});
const yData = this.echartData.map((item, index) => {
if (index % 2 == 0) {
return {
...item,
itemStyle: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
type: "linear",
global: false,
colorStops: [
{
//
offset: 0,
color: "#033E43",
},
{
offset: 1,
color: "#00FFEA",
},
],
},
},
};
} else {
return {
...item,
itemStyle: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
type: "linear",
global: false,
colorStops: [
{
//
offset: 0,
color: "#034299",
},
{
offset: 1,
color: "#35F0FF",
},
],
},
},
};
}
});
this.chart = echarts.init(this.$refs.trafficChart);
this.chart.setOption({
// backgroundColor: "#041139",
tooltip: {
trigger: "axis",
backgroundColor: "rgba(9, 24, 48, 0.5)",
borderColor: "rgba(75, 253, 238, 0.4)",
textStyle: {
fontSize: 12,
color: "#808C9F",
},
},
legend: {
show: false,
},
grid: {
top: "20%",
left: "10%",
right: 0,
bottom: "20%",
},
xAxis: [
{
data: xData,
axisLabel: {
color: "#808C9F",
fontSize: 12,
interval: 0,
},
axisLine: {
show: false, //x
lineStyle: {
color: "rgba(53,65,95,1)",
},
},
axisTick: {
show: false, //
},
boundaryGap: true,
splitLine: {
show: false,
},
},
],
yAxis: [
{
name: "数量",
nameTextStyle: {
color: "#C7DAF2",
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false, //x
lineStyle: {
color: "rgba(53,65,95,1)",
},
},
axisLabel: {
show: true,
color: "#808C9F",
fontSize: 12,
},
},
],
series: [
//
{
name: "数量",
type: "bar",
barWidth: 10,
itemStyle: {
borderColor: "#08B4A6",
borderWidth: 1,
},
showBackground: true,
backgroundStyle: {
color: "rgba(105,160,231,0.1)",
},
label: {
show: false, //
formatter: "{c}",
position: "top",
color: "#fff",
fontSize: 14,
},
data: yData,
},
],
dataZoom: [
{
//
show: false,
//
type: "slider",
//
backgroundColor: "rgba(225,225,225,0.2)",
//
fillerColor: "#ccc",
//
borderColor: "rgba(225,225,225,0.2)",
// detail
showDetail: false,
//
startValue: 0,
//
endValue: 6,
// empty
//
filterMode: "empty",
//
width: "80%",
//
height: 5,
//
left: "center",
//
zoomLoxk: true,
//
handleSize: 10,
// dataZoom-slider
bottom: 0,
},
{
//
//
type: "inside",
//
zoomOnMouseWheel: false,
//
moveOnMouseMove: true,
moveOnMouseWheel: true,
},
],
});
window.addEventListener("resize", () => {
this.chart.resize();
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
position: relative;
.traffic-select {
position: absolute;
z-index: 1;
right: 0;
top: 0.2rem;
}
.traffic-echart {
width: 100%;
height: 100%;
overflow: hidden;
}
}
</style>

View File

@ -2,7 +2,7 @@
* @Author: SunTao 328867980@qq.com * @Author: SunTao 328867980@qq.com
* @Date: 2024-10-17 11:34:00 * @Date: 2024-10-17 11:34:00
* @LastEditors: SunTao 328867980@qq.com * @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-07 12:48:21 * @LastEditTime: 2024-11-11 10:58:06
* @FilePath: \znxjxt-ui\src\views\big-screen\index.vue * @FilePath: \znxjxt-ui\src\views\big-screen\index.vue
* @Description: 大屏首页 * @Description: 大屏首页
--> -->
@ -41,7 +41,11 @@
:class="item.class" :class="item.class"
> >
<template <template
><component :select="item.select" :is="item.component"></component ><component
:select="item.select"
:is="item.component"
:bottomTipClick="bottomTipClick"
></component
></template> ></template>
<template slot="operation" v-if="item.selectIsShow"> <template slot="operation" v-if="item.selectIsShow">
<el-radio-group class="screen-checkBox" v-model="item.select"> <el-radio-group class="screen-checkBox" v-model="item.select">
@ -65,7 +69,11 @@
:class="item.class" :class="item.class"
> >
<template <template
><component :select="item.select" :is="item.component"></component ><component
:select="item.select"
:is="item.component"
:bottomTipClick="bottomTipClick"
></component
></template> ></template>
<template slot="operation" v-if="item.selectIsShow"> <template slot="operation" v-if="item.selectIsShow">
<el-radio-group class="screen-checkBox" v-model="item.select"> <el-radio-group class="screen-checkBox" v-model="item.select">
@ -80,23 +88,8 @@
</module-block> </module-block>
</div> </div>
<div class="road-content"> <div class="road-content">
<!-- 左侧控制 --> <!-- 地图右上角多选框切换坐标类型 -->
<div class="road-select"> <!-- <div class="road-checkBox">
<!-- 左上角病害筛查 -->
<div class="road-div" v-if="mapClick === 'defect'" @click="clickImg">
<span>病害筛查</span>
</div>
<!-- 返回图片底图 -->
<div
class="road-return"
v-if="!showImgBk"
@click="changeMap(true, '')"
>
返回
</div>
</div>
<!-- 右上角切换坐标类型多选框 -->
<div class="road-checkBox" v-if="!showImgBk">
<fssm-scroll class="road-scroll"> <fssm-scroll class="road-scroll">
<el-checkbox-group v-model="iconType" @change="handleChecked"> <el-checkbox-group v-model="iconType" @change="handleChecked">
<el-checkbox <el-checkbox
@ -107,27 +100,29 @@
> >
</el-checkbox-group> </el-checkbox-group>
</fssm-scroll> </fssm-scroll>
</div> </div> -->
<!-- 切换路段选项框 --> <!-- 地图图例 -->
<div class="road-checkBox-twe" v-if="!showImgBk"> <div class="map-legend"></div>
<el-select
:popper-append-to-body="false"
v-model="roadSelect"
placeholder="请选择路段"
@change="getCenterPiont"
>
<el-option
v-for="item in roadList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<!-- 图片背景 --> <!-- 图片背景 -->
<div class="disease-content" v-if="showImgBk"> <div class="disease-content" v-if="elementDiv === 'OverviewScreen'">
<div class="disease-title"></div> <div class="disease-title"></div>
<div class="map-legend"></div> <!-- 图背景下选择框 -->
<div class="map-image-select">
病害类型筛选
<el-select
:popper-append-to-body="false"
v-model="mapCareSelect"
placeholder="请选择"
@change="getMapCare"
>
<el-option
v-for="item in dieaseTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="map-care"> <div class="map-care">
<div <div
class="map-care-div" class="map-care-div"
@ -136,19 +131,16 @@
:key="`map-care-${index}`" :key="`map-care-${index}`"
:style="{ left: item.left, top: item.top }" :style="{ left: item.left, top: item.top }"
> >
<span @click="item.lat ? changeMap(false, item) : ''">{{ <span>{{ item.name }}</span>
item.name
}}</span>
</div> </div>
</div> </div>
</div> </div>
<!-- 地图 --> <!-- 地图 -->
<fssm-map <fssm-map
v-if="!showImgBk" v-if="elementDiv !== 'OverviewScreen'"
ref="roadMap" ref="roadMap"
:showChange="true" :showChange="true"
:controlStyle="{ top: '23%', left: '27%' }" :controlStyle="{ top: '10%', left: '26%' }"
:centerPoint="mapCenterPoint"
@map-moveend="mapMoveend" @map-moveend="mapMoveend"
@map-zoom="getZoom" @map-zoom="getZoom"
@feature-select="featureSelect" @feature-select="featureSelect"
@ -156,11 +148,12 @@
</div> </div>
</div> </div>
<div class="screen-footer"> <div class="screen-footer">
<!-- 病害巡检4种类型按钮 -->
<div class="footer-change-map"> <div class="footer-change-map">
<template v-if="!showImgBk"> <template v-if="elementDiv === 'DiseaseScreen'">
<div <div
class="change-map-div" class="change-map-div"
:class="mapClick === item.click ? 'change-map-click' : ''" :class="bottomTipClick === item.click ? 'change-map-click' : ''"
v-for="(item, index) in changeMapBtn" v-for="(item, index) in changeMapBtn"
:key="`btn-${index}`" :key="`btn-${index}`"
@click="changeIconType(item.click)" @click="changeIconType(item.click)"
@ -169,6 +162,7 @@
</div> </div>
</template> </template>
</div> </div>
<!-- 切换3种导航栏按钮 -->
<div class="footer-change-vue"> <div class="footer-change-vue">
<div <div
:class=" :class="
@ -186,7 +180,7 @@
<el-dialog <el-dialog
:title="imgTitle" :title="imgTitle"
:visible.sync="imgVisible" :visible.sync="imgVisible"
width="80rem" width="85rem"
append-to-body append-to-body
:close-on-click-modal="false" :close-on-click-modal="false"
destroy-on-close destroy-on-close
@ -205,7 +199,7 @@
destroy-on-close destroy-on-close
@close="screenImgCancel" @close="screenImgCancel"
> >
<div class="image-container" ref="imageContainer"> <div class="view-image-container" ref="imageContainer">
<img <img
:src="screenImage.imageUrl" :src="screenImage.imageUrl"
alt="Main Image" alt="Main Image"
@ -235,21 +229,19 @@ import * as geomExports from "ol/geom";
import Cluster from "ol/source/Cluster"; import Cluster from "ol/source/Cluster";
// //
import ModuleBlock from "./module-block.vue"; import ModuleBlock from "./module-block.vue";
import TodayInspection from "./disease-components/today-inspection.vue"; import TodayInspection from "./overview-components/today-inspection.vue";
import DiseaseTrends from "./disease-components/disease-trends.vue"; import DiseaseTrends from "./overview-components/disease-trends.vue";
import DiseaseCurrent from "./disease-components/disease-current.vue"; import DiseaseCurrent from "./overview-components/disease-current.vue";
import WorkOrder from "./disease-components/work-order.vue"; import PatrolOrder from "./overview-components/patrol-order.vue";
import PicRank from "./disease-components/pic-rank.vue"; import InspectionVehicles from "./overview-components/inspection-vehicles.vue";
import RoadRank from "./disease-components/road-rank.vue";
import RoadStatistic from "./road-components/road-statistic.vue"; import RoadStatistic from "./road-components/road-statistic.vue";
import ManageMaintain from "./road-components/manage-maintain.vue"; import ManageMaintain from "./road-components/manage-maintain.vue";
import AnomalyFacilities from "./road-components/anomaly-facilities"; import AnomalyFacilities from "./road-components/anomaly-facilities";
import AncillaryFacilities from "./road-components/ancillary-facilities.vue"; import AncillaryFacilities from "./road-components/ancillary-facilities.vue";
import TrafficSafety from "./traffic-components/traffic-safety.vue"; import TrafficSafety from "./disease-components/traffic-safety.vue";
import TrafficTrend from "./traffic-components/traffic-trend.vue"; import TrafficTrend from "./disease-components/traffic-trend.vue";
import TrafficStatistic from "./traffic-components/traffic-statistic.vue"; import TrafficStatistic from "./disease-components/traffic-statistic.vue";
import TrafficRank from "./traffic-components/traffic-rank.vue"; import TrafficLog from "./disease-components/traffic-log.vue";
import TrafficEmergency from "./traffic-components/traffic-emergency.vue";
import ImgDialog from "./components/img-dialog.vue"; import ImgDialog from "./components/img-dialog.vue";
import FssmScroll from "@/components/scroll/fssm-scroll.vue"; import FssmScroll from "@/components/scroll/fssm-scroll.vue";
// //
@ -269,9 +261,8 @@ export default {
TodayInspection, TodayInspection,
DiseaseTrends, DiseaseTrends,
DiseaseCurrent, DiseaseCurrent,
WorkOrder, PatrolOrder,
PicRank, InspectionVehicles,
RoadRank,
RoadStatistic, RoadStatistic,
ManageMaintain, ManageMaintain,
AnomalyFacilities, AnomalyFacilities,
@ -279,10 +270,9 @@ export default {
TrafficSafety, TrafficSafety,
TrafficTrend, TrafficTrend,
TrafficStatistic, TrafficStatistic,
TrafficRank,
TrafficEmergency,
ImgDialog, ImgDialog,
FssmScroll, FssmScroll,
TrafficLog,
}, },
data() { data() {
return { return {
@ -328,61 +318,52 @@ export default {
rightModuleList: [ rightModuleList: [
{ {
width: "100%", width: "100%",
height: "25%", height: "23%",
title: "工单统计", title: "巡查里程",
component: WorkOrder, component: PatrolOrder,
selectIsShow: false, selectIsShow: false,
class: "one", class: "one",
}, },
{ {
width: "100%", width: "100%",
height: "33%", height: "60%",
title: "PIC排名", title: "巡检车辆",
component: PicRank, component: InspectionVehicles,
selectIsShow: false, selectIsShow: false,
class: "twe", class: "twe",
}, },
{
width: "100%",
height: "25%",
title: "路面状况排名",
component: RoadRank,
selectIsShow: true,
select: "",
class: "twe",
},
], ],
//
showImgBk: true,
// //
mapCareList: [], mapCareList: [],
// //
changeMapBtn: [ changeMapBtn: [
{ name: "巡查车", click: "1" }, { name: "路面", click: "1" },
{ name: "病害", click: "defect" }, { name: "道桥", click: "defect" },
{ name: "路产", click: "equipment" }, { name: "交安", click: "equipment" },
{ name: "事件", click: "event" }, { name: "绿化", click: "event" },
], ],
// icon // icon
iconTypeList: [], iconTypeList: [],
// icon // icon
iconType: [], iconType: [],
//
mapCareSelect: "",
//
dieaseTypeList: [],
// //
roadList: [], roadList: [],
// //
roadSelect: "", roadSelect: "",
// //
mapClick: "", bottomTipClick: "1",
// //
elementDiv: "DiseaseScreen", elementDiv: "OverviewScreen",
// //
elementList: [ elementList: [
{ name: "病害巡检", component: "DiseaseScreen" }, { name: "总览", component: "OverviewScreen" },
{ name: "道路资产", component: "RoadScreen" }, { name: "道路资产", component: "RoadScreen" },
{ name: "交安事件", component: "TrafficScreen" }, { name: "病害巡检", component: "DiseaseScreen" },
], ],
//
mapCenterPoint: {},
// () // ()
centerPiont: [], centerPiont: [],
// //
@ -400,7 +381,7 @@ export default {
// //
imgTitle: "查看", imgTitle: "查看",
// //
imgVisible: false, imgVisible: true,
// //
screenImage: {}, screenImage: {},
// //
@ -414,6 +395,7 @@ export default {
this.getSelect(); this.getSelect();
this.getMapCare(); this.getMapCare();
this.getRoadList(); this.getRoadList();
this.getDieaseTypeList();
}, },
methods: { methods: {
/* 获取当前时间 */ /* 获取当前时间 */
@ -467,6 +449,11 @@ export default {
}); });
}, },
/* 获取图片背景左上角病害类型下拉 */
getDieaseTypeList() {
this.dieaseTypeList = [];
},
/* 获取图片背景下坐标数据 */ /* 获取图片背景下坐标数据 */
getMapCare() { getMapCare() {
comppanyImg().then(({ code, data }) => { comppanyImg().then(({ code, data }) => {
@ -504,23 +491,6 @@ export default {
}); });
}, },
/* 点击图片点位切换地图事件 */
changeMap(boolen, item) {
this.showImgBk = boolen;
this.mapCenterPoint = { lat: item.lat * 1, lon: item.lon * 1 };
if (!boolen) {
//
this.changeIconType("defect");
} else {
this.mapClick = "";
this.mapZoom = "";
this.clusters = null;
this.markLayerLines = null;
this.mapCenterPoint = {};
this.roadSelect = "";
}
},
/* 获取地图点位信息 */ /* 获取地图点位信息 */
getCenterPiont() { getCenterPiont() {
// //
@ -531,31 +501,32 @@ export default {
this.clusters = null; this.clusters = null;
}); });
} }
mapPointList({ type: this.mapClick, segmentId: this.roadSelect }).then( mapPointList({
({ code, data }) => { type: this.bottomTipClick,
if (code === 200) { segmentId: this.roadSelect,
this.drawPointList = data.map((item) => { }).then(({ code, data }) => {
if (item.geometry) { if (code === 200) {
return { this.drawPointList = data.map((item) => {
...item, if (item.geometry) {
geometry: [item.geometry[0], item.geometry[1]], return {
}; ...item,
} geometry: [item.geometry[0], item.geometry[1]],
return []; };
}); }
this.centerPiont = data.map((item) => { return [];
if (item.geometry) { });
return { this.centerPiont = data.map((item) => {
...item, if (item.geometry) {
geometry: [item.geometry[0], item.geometry[1]], return {
}; ...item,
} geometry: [item.geometry[0], item.geometry[1]],
return []; };
}); }
this.drawPoint(); return [];
} });
this.drawPoint();
} }
); });
}, },
/* 绘制地图点位 */ /* 绘制地图点位 */
@ -718,25 +689,8 @@ export default {
/* 地图下方4图标类别切换点击事件 */ /* 地图下方4图标类别切换点击事件 */
changeIconType(value) { changeIconType(value) {
this.mapZoom = ""; if (this.bottomTipClick !== value) {
this.roadSelect = ""; this.bottomTipClick = value;
if (this.mapClick !== value) {
this.mapClick = value;
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.removeLayer(this.markLayerLines);
map.removeLayer(this.clusters);
this.clusters = null;
this.markLayerLines = null;
});
// icon
this.getIconType(value);
// /线
if (!this.mapZoom) {
this.getZoom("11");
} else {
this.getZoom(this.mapZoom);
}
} }
}, },
@ -823,7 +777,7 @@ export default {
changeElement(item) { changeElement(item) {
if (this.elementDiv !== item) { if (this.elementDiv !== item) {
this.elementDiv = item.component; this.elementDiv = item.component;
if (item.component === "DiseaseScreen") { if (item.component === "OverviewScreen") {
this.leftModuleList = [ this.leftModuleList = [
{ {
width: "100%", width: "100%",
@ -855,28 +809,19 @@ export default {
{ {
width: "100%", width: "100%",
height: "25%", height: "25%",
title: "工单统计", title: "巡查里程",
component: WorkOrder, component: PatrolOrder,
selectIsShow: false, selectIsShow: false,
class: "one", class: "one",
}, },
{ {
width: "100%", width: "100%",
height: "33%", height: "60%",
title: "PIC排名", title: "巡检车辆",
component: PicRank, component: InspectionVehicles,
selectIsShow: false, selectIsShow: false,
class: "twe", class: "twe",
}, },
{
width: "100%",
height: "25%",
title: "路面状况排名",
component: RoadRank,
selectIsShow: true,
select: "",
class: "twe",
},
]; ];
} else if (item.component === "RoadScreen") { } else if (item.component === "RoadScreen") {
this.leftModuleList = [ this.leftModuleList = [
@ -917,7 +862,7 @@ export default {
class: "twe", class: "twe",
}, },
]; ];
} else if (item.component === "TrafficScreen") { } else if (item.component === "DiseaseScreen") {
this.leftModuleList = [ this.leftModuleList = [
{ {
width: "100%", width: "100%",
@ -948,21 +893,13 @@ export default {
this.rightModuleList = [ this.rightModuleList = [
{ {
width: "100%", width: "100%",
height: "50%", height: "85%",
title: "交安事件排名", title: "交安事件日志",
component: TrafficRank, component: TrafficLog,
selectIsShow: true, selectIsShow: true,
select: "", select: "",
class: "one", class: "one",
}, },
{
width: "100%",
height: "29%",
title: "交安突发事件",
component: TrafficEmergency,
selectIsShow: false,
class: "twe",
},
]; ];
} }
} }
@ -1087,96 +1024,17 @@ export default {
height: 100%; height: 100%;
position: relative; position: relative;
// //
.road-select { .map-legend {
width: 4rem; height: 7rem;
height: 6.5rem; width: 2rem;
display: flex;
flex-direction: column;
align-items: center;
position: absolute; position: absolute;
left: 27%; top: 17%;
top: 10%; left: 26%;
z-index: 1;
.road-div { background-image: url("../../assets/screen/index/map-legend.png");
width: 100%; background-repeat: no-repeat;
height: 5rem; background-size: 100% 100%;
margin-bottom: 0.5rem;
display: flex;
justify-content: center;
align-items: flex-end;
cursor: pointer;
color: #8deeff;
background-image: url("../../assets/screen/road/road-select.png");
background-repeat: no-repeat;
background-size: 80%;
background-position: 50% 0;
z-index: 1;
span {
font-size: 0.8rem;
}
::v-deep .el-select {
width: 8rem;
.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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
}
//
.road-return {
cursor: pointer;
width: 4rem;
height: 1.5rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8rem;
color: #ffffff;
background-color: #395569;
border: 1px #1cb6ff solid;
border-radius: 0.5rem;
z-index: 1;
&:hover {
background-color: #2b4367;
}
}
} }
// //
@ -1201,57 +1059,6 @@ export default {
} }
} }
// 线
.road-checkBox-twe {
position: absolute;
left: 31.5%;
top: 10%;
padding: 0.4rem;
border-radius: 0.4rem;
z-index: 1;
::v-deep .el-select {
width: 15rem;
.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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
}
// //
.disease-content { .disease-content {
width: 100%; width: 100%;
@ -1274,17 +1081,12 @@ export default {
background-size: 100%; background-size: 100%;
} }
// //
.map-legend { .map-image-select {
height: 7rem;
width: 2rem;
position: absolute;
top: 13%;
left: 28%; left: 28%;
z-index: 1; top: 10%;
background-image: url("../../assets/screen/index/map-legend.png"); position: absolute;
background-repeat: no-repeat; color:#ffffff;
background-size: 100% 100%;
} }
// //
@ -1310,7 +1112,6 @@ export default {
span { span {
height: 1rem; height: 1rem;
cursor: pointer;
} }
} }
@ -1417,7 +1218,6 @@ export default {
.footer-change-map { .footer-change-map {
width: 100%; width: 100%;
height: 40%; height: 40%;
padding-right: 0.5rem;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -1453,14 +1253,14 @@ export default {
} }
// //
.change-vue-DiseaseScreen { .change-vue-OverviewScreen {
background-image: url("../../assets//screen/index/button-disease.png"); background-image: url("../../assets//screen/index/button-disease.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 97% 65%; background-size: 97% 65%;
background-position: 100% 15%; background-position: 100% 15%;
} }
.change-vue-click-DiseaseScreen { .change-vue-click-OverviewScreen {
background-image: url("../../assets//screen/index/button-disease-click.png"); background-image: url("../../assets//screen/index/button-disease-click.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 98% 65%; background-size: 98% 65%;
@ -1480,14 +1280,14 @@ export default {
background-position: 70% 15%; background-position: 70% 15%;
} }
.change-vue-TrafficScreen { .change-vue-DiseaseScreen {
background-image: url("../../assets//screen/index/button-traffic.png"); background-image: url("../../assets//screen/index/button-traffic.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 95% 60%; background-size: 95% 60%;
background-position: 15% 15%; background-position: 15% 15%;
} }
.change-vue-click-TrafficScreen { .change-vue-click-DiseaseScreen {
background-image: url("../../assets//screen/index/button-traffic-click.png"); background-image: url("../../assets//screen/index/button-traffic-click.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 95% 60%; background-size: 95% 60%;
@ -1501,6 +1301,7 @@ export default {
/* 修改弹窗样式 */ /* 修改弹窗样式 */
::v-deep .el-dialog__header { ::v-deep .el-dialog__header {
padding: 10px;
background-color: #113463; background-color: #113463;
span, span,
@ -1510,10 +1311,11 @@ export default {
} }
::v-deep .el-dialog__body { ::v-deep .el-dialog__body {
padding: 0;
background-color: #113463; background-color: #113463;
/* 查看点位大图弹窗 */ /* 查看点位大图弹窗 */
.image-container { .view-image-container {
position: relative; position: relative;
width: 100%; width: 100%;
height: 80%; height: 80%;
@ -1523,7 +1325,7 @@ export default {
overflow: hidden; overflow: hidden;
} }
.image-container img { .view-image-container img {
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
object-fit: contain; object-fit: contain;
@ -1535,4 +1337,46 @@ export default {
border: 2px solid red; border: 2px solid red;
} }
} }
//
::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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
</style> </style>

View File

@ -0,0 +1,419 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 10:19:56
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-11 10:07:23
* @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\disease-current.vue
* @Description: 总览大屏-病害三维饼图
-->
<template>
<div class="content">
<div class="content-select">
<el-select
:popper-append-to-body="false"
v-model="itemSelect"
placeholder="请选择"
>
<el-option
v-for="item in currentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="echart" ref="currentChart"></div>
<div class="food-legend">
<div
class="legend-div"
v-for="(item, index) in dataList"
:key="`chart-${index}`"
>
<div class="index" :style="{ backgroundColor: colorList[index] }"></div>
<div class="name">{{ item.typeName }}</div>
<div class="rate">{{ item.rate }}%</div>
<div class="value">{{ item.value }}</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import "echarts-gl";
import { roadCurrent, getDropList } from "@/api/xj/screen/disease-screen";
export default {
name: "DiseaseCurrent",
props: {
select: {
type: String,
default: "",
},
},
data() {
return {
//
itemSelect: "",
//
currentList: [],
//
options: {},
//
colorList: [
"#18F7FF",
"#FFEA68",
"#AE74F3",
"#6FC36F",
"#FF8F5F",
"#6FC36F",
"#4C83FF",
"#FC5976",
"#5B40B6",
],
// echart
dataList: [],
// echart
chart: "",
};
},
watch: {
select: {
handler(val) {
if (val) {
this.itemSelect = "";
this.getCurrentList();
this.getChartList();
}
},
immediate: true,
},
itemSelect: {
handler() {
this.getChartList();
},
},
},
created() {
this.getChartList();
},
methods: {
/* 获取右上角下拉框数据 */
getCurrentList() {
getDropList({ type: this.select }).then(({ data, code }) => {
if (code === 200) {
this.currentList = data;
}
});
},
/* 获取echart数据 */
getChartList() {
const data = {
type: this.select,
itemName: this.itemSelect,
};
roadCurrent(data).then(({ code, data }) => {
if (code === 200) {
let allSum = 0;
data?.forEach((element) => {
allSum += element.value;
});
this.dataList = data.map((item) => {
return {
...item,
rate: ((item.value / allSum) * 100).toFixed(1),
};
});
}
this.$nextTick(() => {
//echartoptions
this.drawChart();
});
});
},
/* 绘制echart图 */
drawChart() {
const data = this.dataList;
if (this.$refs.currentChart) {
if (this.chart) {
this.chart.dispose();
}
this.chart = echarts.init(this.$refs.currentChart);
this.chart.setOption({
legend: {
show: false,
},
animation: false,
tooltip: {
show: true,
confine: false,
backgroundColor: "rgba(9, 24, 48, 0.5)",
borderColor: "rgba(75, 253, 238, 0.4)",
textStyle: {
fontSize: 12,
color: "#ffffff",
},
formatter: (params) => {
return `${params.marker}${params.seriesName}${
data[params.seriesIndex].value
}`;
},
},
labelLine: {
show: false,
},
label: {
show: false,
},
xAxis3D: {
min: -1,
max: 1,
},
yAxis3D: {
min: -1,
max: 1,
},
zAxis3D: {
min: -1,
max: 1,
},
grid3D: {
show: false,
width: "250%",
height: "250%",
// boxWidth: 100,
boxHeight: 2,
top: "-75%",
left: "-75%",
viewControl: {
//
autoRotate: true,
//
alpha: 25,
rotateSensitivity: 0, //0
zoomSensitivity: 0, //0
panSensitivity: 0, //0
},
},
//series
series: this.getPie3D(this.dataList, 0.8),
});
window.addEventListener("resize", () => {
this.chart.resize();
});
}
},
/* 绘制3d饼图配置项 */
getPie3D(pieData, internalDiameterRatio) {
const series = [];
let sumValue = 0;
let startValue = 0;
let endValue = 0;
const legendData = [];
const k =
typeof internalDiameterRatio !== "undefined"
? (1 - internalDiameterRatio) / (1 + internalDiameterRatio * 1)
: 1 / 3;
// series-surface
for (let i = 0; i < pieData.length; i++) {
sumValue += pieData[i].value;
const seriesItem = {
name:
typeof pieData[i].typeName === "undefined"
? `series${i}`
: pieData[i].typeName,
type: "surface",
parametric: true,
wireframe: {
show: false,
},
pieData: pieData[i],
pieStatus: {
selected: false,
hovered: false,
k: 1 / 10,
},
};
seriesItem.itemStyle = { color: this.colorList[i] };
series.push(seriesItem);
}
// 使 sumValue getParametricEquation
// series-surface series-surface.parametricEquation
for (let i = 0; i < series.length; i++) {
endValue = startValue + series[i].pieData.value * 1;
series[i].pieData.startRatio = startValue / sumValue;
series[i].pieData.endRatio = endValue / sumValue;
//3d
series[i].parametricEquation = this.getParametricEquation(
series[i].pieData.startRatio,
series[i].pieData.endRatio,
false,
false,
k,
//
series[i].pieData.value / 1000
);
startValue = endValue;
legendData.push(series[i].typeName);
}
return series;
},
/* 配置项参数 */
getParametricEquation(
startRatio,
endRatio,
isSelectedValue,
isHovered,
kk,
height
) {
//
const midRatio = (startRatio + endRatio) / 2;
const startRadian = startRatio * Math.PI * 2;
const endRadian = endRatio * Math.PI * 2;
const midRadian = midRatio * Math.PI * 2;
let isSelected = isSelectedValue;
//
if (startRatio === 0 && endRatio === 1) {
isSelected = false;
}
// / k 1/3
const k = typeof kk !== "undefined" ? kk : 1 / 3;
// x y 0
const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
// const offsetZ = i == 1 ? 2 : 0;
// 1
const hoverRate = isHovered ? 1.05 : 1;
//
return {
u: {
min: -Math.PI,
max: Math.PI * 3,
step: Math.PI / 32,
},
v: {
min: 0,
max: Math.PI * 2,
step: Math.PI / 20,
},
x: (u, v) => {
if (u < startRadian) {
return (
offsetX +
Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
);
}
if (u > endRadian) {
return (
offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
);
}
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
},
y: (u, v) => {
if (u < startRadian) {
return (
offsetY +
Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
);
}
if (u > endRadian) {
return (
offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
);
}
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
},
z: (u, v) => {
if (u < -Math.PI * 0.5) {
return Math.sin(u);
}
if (u > Math.PI * 2.5) {
return Math.sin(u);
}
return Math.sin(v) > 0 ? 1 * height : -1;
},
};
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
.content-select {
position: absolute;
z-index: 1;
right: 0;
top: 0.2rem;
}
.echart {
width: 100%;
height: 70%;
z-index: 0;
}
.food-legend {
height: 30%;
width: 100%;
display: flex;
flex-wrap: wrap;
.legend-div {
width: 32%;
height: 30%;
display: flex;
align-items: center;
.index {
width: 0.5rem;
height: 0.5rem;
}
.name {
width: 4.5rem;
padding-left: 0.3rem;
color: #aac6c7;
font-size: 0.7rem;
}
.rate {
width: 2rem;
color: #808c9f;
font-size: 0.65rem;
}
.value {
width: 2rem;
color: #808c9f;
font-size: 0.65rem;
}
}
}
}
</style>

View File

@ -0,0 +1,348 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 10:16:30
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-24 17:09:27
* @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\disease-trends.vue
* @Description: 总览大屏-病害趋势
-->
<template>
<div class="content" ref="trendsChart"></div>
</template>
<script>
import * as echarts from "echarts";
import { roadTrends } from "@/api/xj/screen/disease-screen";
export default {
name: "DiseaseTrends",
data() {
return {
// echart
echartList: [],
};
},
created() {
this.geteEhartList();
},
methods: {
/* 获取折线图数据 */
geteEhartList() {
roadTrends().then(({ data, code }) => {
if (code === 200) {
this.echartList = data;
this.$nextTick(() => {
this.drawChart();
});
}
});
},
/* 绘制折线图 */
drawChart() {
const xData = this.echartList.map((item) => {
return item.date;
});
const yData1 = this.echartList.map((item) => {
return item.A1000;
});
const yData2 = this.echartList.map((item) => {
return item.A2001;
});
const yData3 = this.echartList.map((item) => {
return item.A2000;
});
const yData4 = this.echartList.map((item) => {
return item.A0;
});
const yData5 = this.echartList.map((item) => {
return item.A1;
});
const chart = echarts.init(this.$refs.trendsChart);
chart.setOption({
//
title: {
text: "",
textStyle: {
color: "#fff",
fontSize: 12,
},
},
legend: {
top: "top",
icon: "roundRect",
itemWidth: 15,
itemHeight: 10,
textStyle: {
color: "#808C9F",
},
},
grid: {
top: "25%",
left: "0%",
right: "10%",
bottom: "10%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "line",
},
backgroundColor: "rgba(9, 24, 48, 0.5)",
borderColor: "rgba(75, 253, 238, 0.4)",
textStyle: {
fontSize: 12,
color: "#808C9F",
},
confine: true,
},
xAxis: {
type: "category",
data: ["8:00", "9:00", "10:00", "11:00", "12:00", "13:00"],
axisLine: {
lineStyle: {
color: "rgba(60,132,163,0.4)", // x线
},
},
axisTick: {
show: false, // x
},
axisLabel: {
interval: 0,
color: "#808C9F",
fontSize: 12,
},
boundaryGap: false, // true线x false线线
data: xData,
},
yAxis: {
type: "value",
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
color: "#808C9F",
fontSize: 12,
formatter: function (value) {
return value + "";
},
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
color: "rgba(60,132,163,0.2)",
},
},
},
series: [
{
name: "坑槽",
type: "line",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#FFC100",
},
{
offset: 1,
color: "rgba(98,74,0,0)",
},
]),
},
lineStyle: {
width: 1,
color: "#FFC100",
},
//
showSymbol: false,
symbol: "circle", // circle, diamond, pin
symbolSize: 10, //
itemStyle: {
color: "#FFC100", //
},
data: yData1,
},
{
name: "块状修补(沥青)",
type: "line",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#08B4A6",
},
{
offset: 1,
color: "rgba(8,180,166,0)",
},
]),
},
lineStyle: {
width: 1,
color: "#08B4A6",
},
//
showSymbol: false,
symbol: "circle", // circle, diamond, pin
symbolSize: 10, //
itemStyle: {
color: "#08B4A6",
},
data: yData2,
},
{
name: "条状修补(沥青)",
type: "line",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#146fd7",
},
{
offset: 1,
color: "rgba(20, 111, 215,0)",
},
]),
},
lineStyle: {
width: 1,
color: "#146fd7",
},
//
showSymbol: false,
symbol: "circle", // circle, diamond, pin
symbolSize: 10, //
itemStyle: {
color: "#146fd7",
},
data: yData3,
},
{
name: "横向裂缝",
type: "line",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#994EFF",
},
{
offset: 1,
color: "rgba(153,78,255,0)",
},
]),
},
lineStyle: {
width: 1,
color: "#994EFF",
},
//
showSymbol: false,
symbol: "circle", // circle, diamond, pin
symbolSize: 10, //
itemStyle: {
color: "#994EFF",
},
data: yData4,
},
{
name: "纵向裂缝",
type: "line",
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#994EFF",
},
{
offset: 1,
color: "rgba(153,78,255,0)",
},
]),
},
lineStyle: {
width: 1,
color: "#994EFF",
},
//
showSymbol: false,
symbol: "circle", // circle, diamond, pin
symbolSize: 10, //
itemStyle: {
color: "#994EFF",
},
data: yData5,
},
],
dataZoom: [
{
//
show: false,
//
type: "slider",
//
backgroundColor: "rgba(225,225,225,0.2)",
//
fillerColor: "#ccc",
//
borderColor: "rgba(225,225,225,0.2)",
// detail
showDetail: false,
//
startValue: 0,
//
endValue: 6,
// empty
//
filterMode: "empty",
//
width: "80%",
//
height: 5,
//
left: "center",
//
zoomLoxk: true,
//
handleSize: 10,
// dataZoom-slider
bottom: 0,
},
{
//
//
type: "inside",
//
zoomOnMouseWheel: false,
//
moveOnMouseMove: true,
moveOnMouseWheel: true,
},
],
});
window.addEventListener("resize", () => {
chart.resize();
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,245 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-11-08 09:40:18
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-08 11:59:06
* @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\inspection-vehicles.vue
* @Description: 总览大屏-巡检车辆
-->
<template>
<div class="content">
<div class="inspection-top">
<div class="top-div">
<span>车辆总数</span>
<div>{{ carNum }}<span></span></div>
</div>
<div class="top-div">
<span>在线车辆数</span>
<div>{{ onlineNum }}<span></span></div>
</div>
</div>
<div class="inspection-bottom">
<el-input placeholder="请输入车牌号" v-model="tableInput">
<template slot="append"
><el-button slot="append" icon="el-icon-search"></el-button
></template>
</el-input>
<!-- 列表 -->
<el-table :data="inspectionTableData" style="width: 100%" height="210">
<el-table-column prop="date" label="车牌号码"> </el-table-column>
<el-table-column prop="name" label="状态"> </el-table-column>
<el-table-column prop="pci" label="操作">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="detailDefect(scope.row)"
>详情
</el-button>
<el-button
size="mini"
type="text"
@click="followCar(scope.row)"
v-hasPermi="['system:defect:edit']"
>跟车
</el-button>
<el-button
size="mini"
type="text"
@click="videoDelete(scope.row)"
v-hasPermi="['system:defect:remove']"
>视频
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<div class="pagination-part">
<el-pagination
background
:pager-count="5"
:current-page.sync="pagination.page"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size.sync="pagination.size"
layout="prev, pager, next"
:total="tableTotal"
>
</el-pagination>
</div>
</div>
</div>
</template>
<script>
export default {
name: "InspectionVehicles",
data() {
return {
//
carNum: 11,
// 线
onlineNum: 60,
//
tableInput: "",
//
inspectionTableData: [],
//
pagination: {
page: 1,
size: 10,
},
//
tableTotal: 100,
};
},
created() {
this.getTableData();
},
methods: {
/* 获取表格数据 */
getTableData() {
this.inspectionTableData = [
{
date: "S225",
name: "99.52",
pci: "优",
},
{
date: "G107",
name: "98.6",
pci: "优",
},
{
date: "G105",
name: "100",
pci: "优",
},
{
date: "S225",
name: "99.52",
pci: "优",
},
{
date: "G107",
name: "98.6",
pci: "优",
},
{
date: "G105",
name: "100",
pci: "优",
},
];
},
/* 表格详情事件 */
detailDefect(val) {},
/* 表格跟车事件 */
followCar(val) {},
/* 表格视频事件 */
videoDelete(val) {},
/* 页码修改事件 */
handleCurrentChange(arg) {
this.pagination.page = arg;
this.getTableData();
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
color: #ffffff;
.inspection-top {
width: 100%;
height: 30%;
padding: 0.5rem;
display: flex;
justify-content: space-around;
.top-div {
width: 45%;
height: 100%;
padding-bottom: 2rem;
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-around;
border:1px solid red;
}
}
.inspection-bottom {
width: 100%;
height: 70%;
padding: 1rem 0.5rem;
::v-deep .el-input {
margin-bottom: 0.5rem;
.el-input__inner {
color: #ffffff;
background-color: transparent;
border-color: rgb(69, 109, 211);
}
.el-input-group__append {
background-color: transparent;
color: #ffffff;
border-color: rgb(69, 109, 211);
&:hover {
background-color: #3c5a8a;
}
}
}
::v-deep .el-table {
th {
color: #ffffff;
background-color: #214175;
}
tr {
color: #ffffff;
background-color: #16395a;
&:hover > td {
background-color: transparent;
}
}
}
::v-deep .el-table td.el-table__cell {
border-color: rgb(82, 141, 229);
}
::v-deep .el-table th.el-table__cell {
border-color: rgb(0, 102, 255);
}
}
}
/* 分页样式 */
.pagination-part {
width: 100%;
display: flex;
padding-top: 0.5rem;
justify-content: flex-end;
::v-deep .el-pagination {
color: #ffffff;
.btn-prev,
.btn-next {
background-color: #6481aa;
}
}
::v-deep .el-pager li {
background: transparent;
}
}
</style>

View File

@ -0,0 +1,65 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 10:25:29
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-08 09:33:25
* @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\work-order.vue
* @Description: 总览大屏-巡查里程
-->
<template>
<div class="content">
<div class="patrol-div">
<div class="value"><span>{{ patrolObject.mileage }}</span>km</div>
<div class="name">累计里程</div>
</div>
<div class="patrol-div">
<div class="value"><span>{{ patrolObject.time }}</span>h</div>
<div class="name">累计时长</div>
</div>
</div>
</template>
<script>
export default {
name: "PatrolOrder",
data() {
return {
//
patrolObject: {
mileage: 365,
time: 12,
},
};
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
color: #ffffff;
.patrol-div{
width: 40%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.value{
span{
font-family: "DouYu";
font-size: 1.8rem;
}
}
}
}
</style>

View File

@ -0,0 +1,465 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 09:42:49
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-11 09:45:51
* @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\today-inspection.vue
* @Description: 总览大屏-今日巡查
-->
<template>
<div class="content">
<div class="today-left">
<span>{{ today }}</span>
</div>
<div class="today-right" @click="showDialog">
<div class="right-sum">
<span>{{ all }}</span
>
</div>
<div class="right-rate">
<span> {{ scale }}</span
>%
</div>
</div>
<!-- 病害总览弹窗 -->
<el-dialog
title="当前病害总览"
:visible.sync="showDialogVisible"
width="75rem"
append-to-body
:close-on-click-modal="false"
destroy-on-close
@close="screenCancel"
>
<div class="today-content">
<div ref="leftChart" class="dialog-div"></div>
<div ref="rightChart" class="dialog-div"></div>
</div>
</el-dialog>
</div>
</template>
<script>
import * as echarts from "echarts";
import { roadToday } from "@/api/xj/screen/disease-screen";
export default {
name: "TodayInspection",
data() {
return {
//
today: "0",
//
all: "0",
//
scale: "0",
//
showDialogVisible: false,
//
leftChartData: [],
//
rightChartData: [],
};
},
created() {
this.getData();
},
methods: {
/* 获取数据 */
getData() {
roadToday().then(({ data, code }) => {
if (code === 200) {
this.today = data.today;
this.all = data.all;
this.scale = (data.scale * 1).toFixed(2);
}
});
},
/* 点击打开弹窗 */
showDialog() {
this.showDialogVisible = true;
this.getChartData()
},
/* 请求弹窗数据 */
getChartData() {
this.leftChartData = [];
this.rightChartData = [];
this.$nextTick(() => {
this.drawLeftChart();
this.drawRightChart();
});
},
/* 绘制左侧echart图 */
drawLeftChart() {
if (this.$refs.leftChart) {
const chart = echarts.init(this.$refs.leftChart);
chart.setOption({
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#8DF2FF" }, // 0%
{ offset: 1, color: "#82B3FD" }, // 100%
],
},
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#8087FF" }, // 0%
{ offset: 1, color: "#532EFF" }, // 100%
],
},
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#FFB3B3" }, // 0%
{ offset: 1, color: "#FF2E2E" }, // 100%
],
},
],
title: {
text: "",
},
tooltip: {
trigger: "item",
},
grid: {
left: "3%",
right: "%",
bottom: "3%",
containLabel: true,
},
legend: {
orient: "horizontal",
left: "right",
data: ["分类A", "分类B", "分类C"],
textStyle: {
color: "#fff",
},
itemWidth: 8,
itemHeight: 8,
},
xAxis: {
type: "category",
data: ["类别1", "类别2", "类别3"],
axisLabel: {
color: "#fff",
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
yAxis: {
type: "value",
axisLabel: {
color: "rgba(255,255,255,0.65)",
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.2)",
},
},
name: "单位:个",
nameTextStyle: {
color: "rgba(255,255,255,0.65)",
},
},
series: [
{
barWidth: 10,
name: "分类A",
type: "bar",
data: [120, 200, 150],
},
{
barWidth: 10,
name: "分类B",
type: "bar",
data: [220, 182, 191],
},
{
barWidth: 10,
name: "分类C",
type: "bar",
data: [150, 232, 201],
},
],
});
window.addEventListener("resize", () => {
chart.resize();
});
}
},
/* 绘制右侧echart图 */
drawRightChart() {
if (this.$refs.rightChart) {
const chart = echarts.init(this.$refs.rightChart);
chart.setOption({
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#8DF2FF" }, // 0%
{ offset: 1, color: "#82B3FD" }, // 100%
],
},
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#8087FF" }, // 0%
{ offset: 1, color: "#532EFF" }, // 100%
],
},
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: "#FFB3B3" }, // 0%
{ offset: 1, color: "#FF2E2E" }, // 100%
],
},
],
title: {
text: "",
},
tooltip: {
trigger: "item",
},
grid: {
left: "3%",
right: "%",
bottom: "3%",
containLabel: true,
},
legend: {
orient: "horizontal",
left: "right",
data: ["分类A", "分类B", "分类C"],
textStyle: {
color: "#fff",
},
itemWidth: 8,
itemHeight: 8,
},
xAxis: {
type: "category",
data: ["类别1", "类别2", "类别3"],
axisLabel: {
color: "#fff",
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
yAxis: {
type: "value",
axisLabel: {
color: "rgba(255,255,255,0.65)",
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.2)",
},
},
name: "单位:个",
nameTextStyle: {
color: "rgba(255,255,255,0.65)",
},
},
series: [
{
barWidth: 10,
name: "分类A",
type: "bar",
data: [120, 200, 150],
},
{
barWidth: 10,
name: "分类B",
type: "bar",
data: [220, 182, 191],
},
{
barWidth: 10,
name: "分类C",
type: "bar",
data: [150, 232, 201],
},
],
});
window.addEventListener("resize", () => {
chart.resize();
});
}
},
/* 关闭 弹窗事件 */
screenCancel() {
this.showDialogVisible = false;
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
display: flex;
.today-left {
width: 45%;
height: 100%;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
padding-left: 1.5rem;
background-image: url("../../../assets/screen/disease/today-left.png");
background-repeat: no-repeat;
background-size: 85%;
background-position: 100% 60%;
span {
font-size: 2rem;
font-weight: 800;
font-family: "DouYu";
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.today-right {
width: 55%;
height: 100%;
padding: 1rem;
display: flex;
flex-direction: column;
justify-content: space-around;
color: #ffffff;
.right-sum {
width: 100%;
height: 45%;
cursor: pointer;
display: flex;
padding-left: 1rem;
justify-content: center;
line-height: 3rem;
background-image: url("../../../assets/screen/disease/right-sum.png");
background-repeat: no-repeat;
background-size: 100%;
background-position: 100% 50%;
color: #aac6c7;
span {
font-size: 1.2rem;
font-weight: 800;
font-family: "DouYu";
margin-right: 0.5rem;
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.right-rate {
width: 100%;
height: 45%;
padding-left: 1rem;
display: flex;
justify-content: center;
line-height: 3rem;
background-image: url("../../../assets/screen/disease/right-rate.png");
background-repeat: no-repeat;
background-size: 100%;
background-position: 100% 50%;
color: #aac6c7;
span {
font-size: 1.2rem;
font-weight: 800;
font-family: "DouYu";
margin-right: 0.5rem;
background: linear-gradient(
to bottom,
#ffffff,
#e9bc5c
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
}
}
//
.today-content {
height: 30rem;
display: flex;
.dialog-div {
width: 50%;
height: 100%;
margin: 0 1rem;
}
}
/* 修改弹窗样式 */
::v-deep .el-dialog__header {
padding: 10px;
background-color: #113463;
span,
i {
color: #ffffff;
}
}
::v-deep .el-dialog__body {
padding: 0;
background-color: #113463;
}
</style>

View File

@ -315,46 +315,6 @@ export default {
right: 0; right: 0;
top: 0.2rem; top: 0.2rem;
::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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
} }
.anomaly-echart { .anomaly-echart {

View File

@ -0,0 +1,597 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-22 15:30:25
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-11-04 15:19:03
* @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue
* @Description: 大屏查看图片弹窗
-->
<template>
<div class="app">
<div class="sidebar" ref="sidebar" @scroll="handleScroll">
<img
v-for="(item, index) in defectData"
:key="item.id"
:src="item.media[0].img"
:alt="'Image ' + (index + 1)"
@click="showImage(index)"
:class="{ selected: currentIndex === index }"
/>
</div>
<div class="main-content">
<!-- 搜索表单 -->
<div class="toolbar">
<el-form
:model="imgForm"
ref="imgForm"
size="small"
:inline="true"
label-width="5rem"
>
<el-row :gutter="24">
<el-col :span="7">
<el-form-item label="路段名称">
<el-select
v-model="imgForm.segmentId"
placeholder="请选择路段名称"
:popper-append-to-body="false"
clearable
>
<el-option
v-for="item in roadTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="病害类型">
<el-select
v-model="imgForm.defectType"
placeholder="请选择路段名称"
:popper-append-to-body="false"
clearable
>
<el-option
v-for="item in defectTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="公里桩">
<el-input
v-model="imgForm.stakeStart"
placeholder="起始公里桩"
style="width: 8rem"
clearable
/>
<span style="margin: 0 5px">-</span>
<el-input
v-model="imgForm.stakeEnd"
placeholder="终止公里桩"
style="width: 8rem"
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-col>
</el-row>
</el-form>
</div>
<!-- 图片展示 -->
<div class="image-viewer">
<div class="image-container" ref="imageContainer">
<img
:src="currentImage"
alt="Main Image"
ref="mainImage"
@load="updateRects"
/>
<div
class="rect-overlay"
v-for="(rect, index) in rects"
:key="index"
:style="getRectStyle(rect)"
></div>
</div>
<div class="image-info">
采集时间: {{ new Date(rectsItem.createdTime).toLocaleString() }}<br />
起始桩号: {{ rectsItem.stakeStart || "暂无数据" }} 终止桩号:
{{ rectsItem.stakeEnd || "暂无数据" }}<br />
路产状态: {{ filterState(rectsItem.state) }}
</div>
</div>
<!-- 小图展示 -->
<div class="thumbnail-row">
<img
v-for="(mediaItem, index) in currentThumbnails"
:key="'thumb-' + index"
:src="mediaItem.img"
:alt="'Thumb ' + (index + 1)"
@click="showThumbnailImage(index)"
:class="{ selected: selectedThumbnail === index }"
/>
</div>
</div>
</div>
</template>
<script>
import { getDefectStatus } from "@/api/xj/disease";
import { defeaseList, getSegment, getItemTypes } from "@/api/xj/screen/index";
export default {
name: "ImgDialog",
data() {
return {
//
defectData: [],
// index
currentIndex: 0,
// index
selectedThumbnail: null,
//
loading: false,
//
imgForm: {
//
segmentId: "",
//
defectType: "",
//
stakeStart: "",
//
stakeEnd: "",
},
//
roadTypeList: [],
//
defectTypeList: [],
//
params: {
page: 1,
size: 10,
},
//
rects: [],
//
rectsItem: {},
//
defectStatus: [],
};
},
computed: {
currentImage() {
const thumbnails = this.currentThumbnails;
return (
thumbnails[this.selectedThumbnail]?.img || thumbnails[0]?.img || ""
);
},
currentThumbnails() {
return this.defectData[this.currentIndex]?.media || [];
},
},
created() {
this.getSegmentList();
this.getDefectStatusList();
this.getDefectType();
},
methods: {
/* 查询病害状态下拉数据 */
getDefectStatusList() {
getDefectStatus().then(({ data, code }) => {
if (code === 200) {
this.defectStatus = data;
}
});
},
/* 过滤列表病害状态 */
filterState(value) {
let a = null;
[a] = this.defectStatus.filter((item) => {
return item.value === value;
});
if (a) {
return a.label;
}
},
/* 获取路段下拉数据 */
getSegmentList() {
getSegment().then(({ code, data }) => {
if (code === 200) {
this.roadTypeList = data;
}
});
},
/* 获取病害类型下拉数据 */
getDefectType() {
getItemTypes({ type: "defect" }).then(({ code, data }) => {
if (code === 200) {
this.defectTypeList = data;
}
});
},
/* 获取图片列表/点击搜索事件 */
getList() {
this.loading = true;
const data = {
...this.imgForm,
...this.params,
};
defeaseList(data)
.then((response) => {
this.defectData.push(...response.data);
this.loading = false;
})
.catch(() => {
this.loading = false;
});
},
/* 点击搜索事件 */
handleQuery() {
const stakeReg = /^K\d{4}\+\d{3}$/;
if (this.imgForm.stakeStart) {
if (stakeReg.test(this.imgForm.stakeStart)) {
this.defectData = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
} else {
this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
}
} else if (this.imgForm.stakeEnd) {
if (stakeReg.test(this.imgForm.stakeEnd)) {
this.defectData = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
} else {
this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改");
}
} else {
this.defectData = [];
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
}
},
/* 重置事件 */
resetQuery() {
this.defectData = [];
this.imgForm = {
segmentId: "",
defectType: "",
stakeStart: "",
stakeEnd: "",
};
this.params = {
page: 1,
size: 10,
};
this.getList();
this.showImage(0);
},
/* 左侧点击图片事件 */
showImage(index) {
this.currentIndex = index;
this.selectedThumbnail = 0; // Reset to the first thumbnail when changing the main item
this.scrollToCurrentImage();
this.$nextTick(() => {
this.updateRects();
});
},
showThumbnailImage(index) {
this.selectedThumbnail = index;
this.updateRects();
},
scrollToCurrentImage() {
const sidebarImages = this.$refs.sidebar.querySelectorAll("img");
const currentImageElement = sidebarImages[this.currentIndex];
if (currentImageElement) {
currentImageElement.scrollIntoView({
behavior: "smooth",
block: "nearest",
});
}
},
/* 滚动触发事件 */
handleScroll() {
// +
const sidebar = this.$refs.sidebar;
if (
sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 &&
!this.loading
) {
this.loadMoreImages();
}
},
/* 加载更多图片方法 */
loadMoreImages() {
this.params.page += 1;
this.getList();
},
/* 键盘事件 */
handleKeydown(event) {
if (event.key === "ArrowUp") {
if (this.currentIndex > 0) {
this.currentIndex--;
this.selectedThumbnail = 0; // Reset when changing main images via keyboard
this.scrollToCurrentImage();
this.updateRects();
}
} else if (event.key === "ArrowDown") {
if (this.currentIndex <= this.defectData.length - 1) {
this.currentIndex === this.defectData.length - 1
? this.currentIndex
: this.currentIndex++;
this.selectedThumbnail = 0; // Reset when changing main images via keyboard
this.scrollToCurrentImage();
this.updateRects();
} else {
this.loadMoreImages();
}
}
},
/* 图片位置信息获取 */
updateRects() {
this.rects = [];
this.rectsItem = {};
if (this.defectData.length > 0) {
const image = this.$refs.mainImage;
const rects =
this.defectData[this.currentIndex]?.media[
this.selectedThumbnail
]?.rect
?.split(",")
.map(Number) || [];
this.rects = [
{
left: rects[0],
top: rects[1],
width: rects[2],
height: rects[3],
},
];
this.rectsItem = this.defectData[this.currentIndex];
}
},
/* 图片红框位置 */
getRectStyle({ 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",
};
},
},
mounted() {
this.getList();
this.showImage(0);
window.addEventListener("keydown", this.handleKeydown);
window.addEventListener("resize", this.updateRects);
},
beforeDestroy() {
window.removeEventListener("keydown", this.handleKeydown);
window.removeEventListener("resize", this.updateRects);
},
};
</script>
<style lang="scss" scoped>
.app {
width: 100%;
display: flex;
flex-direction: row;
height: 45rem;
background-color: #2e3a46;
}
.sidebar {
width: 250px;
background-color: #1f292e;
padding: 10px;
overflow-y: auto;
}
.sidebar::-webkit-scrollbar {
width: 8px;
}
.sidebar::-webkit-scrollbar-track {
background: #2e3a46;
border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb {
background: #444c51;
border-radius: 10px;
}
.sidebar::-webkit-scrollbar-thumb:hover {
background: #00aaff;
}
.sidebar img {
width: 100%;
margin-bottom: 5px;
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.sidebar img.selected {
border: 3px solid #00aaff;
transform: scale(1.05);
}
.main-content {
width: calc(100% - 250px);
background-color: #1b2126;
padding: 10px;
display: flex;
flex-direction: column;
}
.toolbar {
width: 100%;
height: 6rem;
display: flex;
align-items: center;
background-color: #333c42;
padding: 5px;
border-bottom: 1px solid #333c42;
::v-deep .el-form {
width: 100%;
.el-form-item--small .el-form-item__label {
color: #ffffff;
}
.el-select {
width: 10rem;
.el-input--small .el-input__inner {
color: #ffffff;
background-color: #333c42;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.el-select-dropdown__item {
color: #ffffff;
}
.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: #333c42;
}
}
}
}
}
.el-input--small .el-input__inner {
color: #ffffff;
background-color: #333c42;
}
}
}
.image-container {
position: relative;
width: 100%;
height: 80%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.rect-overlay {
position: absolute;
pointer-events: none;
border: 2px solid red;
}
.image-viewer {
height: 32rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #22272b;
position: relative;
}
.thumbnail-row {
display: flex;
justify-content: center;
overflow-x: auto;
padding: 10px;
background-color: #333c42;
gap: 10px;
}
.thumbnail-row img {
width: 100px;
height: 60px;
cursor: pointer;
border-radius: 3px;
transition: transform 0.2s, border 0.2s;
box-sizing: border-box;
}
.thumbnail-row img.selected {
border: 3px solid #00aaff;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 09:29:51
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-21 18:00:45
* @FilePath: \znxjxt-ui\src\views\big-screen\module-block.vue
* @Description: 大屏数据栏
-->
<template>
<div class="module-block" :style="{ width, height }">
<div class="module-block__header">
<div class="header-title">
<span>{{ title }}</span>
</div>
<div class="header-operation" v-if="$slots.operation">
<slot name="operation"></slot>
</div>
</div>
<!-- 内容 -->
<div v-if="$slots.default" class="module-block__body">
<fssm-scroll full>
<slot></slot>
</fssm-scroll>
</div>
</div>
</template>
<script>
import FssmScroll from "@/components/scroll/fssm-scroll.vue";
export default {
name: "ModuleBlock",
components: { FssmScroll },
props: {
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "",
},
title: {
type: String,
default: "",
},
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped>
.module-block {
.module-block__header {
width: 100%;
height: 2.5rem;
display: flex;
background-image: url("../../assets/screen/index/title.png");
background-repeat: no-repeat;
background-size: 100% 100%;
.header-title {
width: 75%;
height: 100%;
padding-left: 6rem;
line-height: 2rem;
color: #ffffff;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-family: "ys";
font-size: 1.4rem;
}
.header-operation {
width: 25%;
height: 2.5rem;
line-height: 2rem;
}
}
.module-block__body {
width: 100%;
height: calc(100% - 2.5rem);
}
}
</style>

View File

@ -0,0 +1,218 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 15:18:03
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-25 16:27:10
* @FilePath: \znxjxt-ui\src\views\big-screen\road-components\ancillary-facilities.vue
* @Description: 道路资产大屏-附属设施分布
-->
<template>
<div class="content">
<div class="ancillary-top"><span>{{sum}}</span></div>
<div class="ancillary-bottom">
<div
:class="`ancillary-bottom-${index}`"
v-for="(item, index) in ancillaryList"
:key="`ancillary-${index}`"
>
<div>{{ item.label }}</div>
<div>
<span>{{ item.value }}</span
><a></a>
</div>
</div>
</div>
</div>
</template>
<script>
import { ancillaryList, ancillaryCount } from "@/api/xj/screen/road-screen";
export default {
name: "AncillaryFacilities",
data() {
return {
//
sum: 0,
//
ancillaryList: [],
};
},
created() {
this.getAncillaryList();
this.getSum();
},
methods: {
/* 获取附属设施分总数 */
getSum() {
ancillaryCount().then(({ code, data }) => {
if (code === 200) {
this.sum = data.count;
}
});
},
/* 获取附属设施分布数据 */
getAncillaryList() {
ancillaryList().then(({ code, data }) => {
if (code === 200) {
this.ancillaryList = data;
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
color: #ffffff;
.ancillary-top {
height: 9rem;
width: 100%;
display: flex;
justify-content: center;
line-height: 8rem;
padding-right: 2rem;
background-image: url("../../../assets/screen/road/ancillary-top.png");
background-repeat: no-repeat;
background-size: 90% 80%;
background-position: 50%;
span {
font-size: 1.5rem;
font-weight: 800;
font-family: "DouYu";
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.ancillary-bottom {
height: calc(100% - 9rem);
width: 100%;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
> div {
width: 45%;
height: 22%;
display: flex;
justify-content: center;
flex-direction: column;
padding-left: 3.5rem;
font-size: 0.8rem;
span {
font-size: 0.8rem;
font-weight: 800;
font-family: "DouYu";
}
a {
font-size: 0.7rem;
color: #aac6c7;
padding-left: 0.5rem;
}
}
.ancillary-bottom-0 {
background-image: url("../../../assets/screen/road/ancillary-bottom-0.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #ac8018;
}
}
.ancillary-bottom-1 {
background-image: url("../../../assets/screen/road/ancillary-bottom-1.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #ac8018;
}
}
.ancillary-bottom-2 {
background-image: url("../../../assets/screen/road/ancillary-bottom-2.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #08afa3;
}
}
.ancillary-bottom-3 {
background-image: url("../../../assets/screen/road/ancillary-bottom-3.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #08afa3;
}
}
.ancillary-bottom-4 {
background-image: url("../../../assets/screen/road/ancillary-bottom-4.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #3f84e3;
}
}
.ancillary-bottom-5 {
background-image: url("../../../assets/screen/road/ancillary-bottom-5.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #3f84e3;
}
}
.ancillary-bottom-6 {
background-image: url("../../../assets/screen/road/ancillary-bottom-6.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #ac8018;
}
}
.ancillary-bottom-7 {
background-image: url("../../../assets/screen/road/ancillary-bottom-7.png");
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
span {
color: #ac8018;
}
}
}
}
</style>

View File

@ -0,0 +1,366 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 15:21:24
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-31 14:24:19
* @FilePath: \znxjxt-ui\src\views\big-screen\road-components\anomaly-facilities.vue
* @Description: 附属设施异常统计
-->
<template>
<div class="content">
<div class="anomaly-select">
<el-select
:popper-append-to-body="false"
v-model="itemSelect"
placeholder="请选择"
>
<el-option
v-for="item in currentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div ref="anomalyChart" class="anomaly-echart"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { getDropList } from "@/api/xj/screen/disease-screen";
import { anomalyList } from "@/api/xj/screen/road-screen";
export default {
name: "AnomalyFacilities",
props: {
select: {
type: String,
default: "",
},
},
data() {
return {
//
itemSelect: "",
//
currentList: [],
// echart
anomalyData: [],
// echart
chart: null,
};
},
watch: {
select: {
handler(val) {
if (val) {
this.itemSelect = "";
this.getCurrentList();
this.getChartData();
}
},
immediate: true,
},
itemSelect: {
handler() {
this.getChartData();
},
},
},
created() {
this.getChartData();
},
methods: {
/* 获取右上角下拉框数据 */
getCurrentList() {
getDropList({ type: this.select }).then(({ data, code }) => {
if (code === 200) {
this.currentList = data;
}
});
},
/* 获取柱状图数据 */
getChartData() {
const data = {
id: this.itemSelect,
type: this.select,
};
anomalyList(data).then(({ code, data }) => {
if (code === 200) {
this.anomalyData = data;
this.$nextTick(() => {
this.drawChart();
});
}
});
},
/* 绘制echart */
drawChart() {
if (this.chart) {
this.chart.dispose();
}
const xData = this.anomalyData.map((item) => {
return item.label;
});
const yData = this.anomalyData.map((item, index) => {
if (index % 2 == 0) {
return {
...item,
itemStyle: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
type: "linear",
global: false,
colorStops: [
{
//
offset: 0,
color: "#033E43",
},
{
offset: 1,
color: "#00FFEA",
},
],
},
},
};
} else {
return {
...item,
itemStyle: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
type: "linear",
global: false,
colorStops: [
{
//
offset: 0,
color: "#034299",
},
{
offset: 1,
color: "#35F0FF",
},
],
},
},
};
}
});
this.chart = echarts.init(this.$refs.anomalyChart);
this.chart.setOption({
// backgroundColor: "#041139",
tooltip: {
trigger: "axis",
backgroundColor: "rgba(9, 24, 48, 0.5)",
borderColor: "rgba(75, 253, 238, 0.4)",
textStyle: {
fontSize: 12,
color: "#808C9F",
},
},
legend: {
show: false,
},
grid: {
top: "20%",
left: "10%",
right: 0,
bottom: "20%",
},
xAxis: [
{
data: xData,
axisLabel: {
color: "#808C9F",
fontSize: 12,
interval: 0,
},
axisLine: {
show: false, //x
lineStyle: {
color: "rgba(53,65,95,1)",
},
},
axisTick: {
show: false, //
},
boundaryGap: true,
splitLine: {
show: false,
},
},
],
yAxis: [
{
name: "数量",
nameTextStyle: {
color: "#C7DAF2",
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false, //x
lineStyle: {
color: "rgba(53,65,95,1)",
},
},
axisLabel: {
show: true,
color: "#808C9F",
fontSize: 12,
},
},
],
series: [
//
{
name: "数量",
type: "bar",
barWidth: 10,
itemStyle: {
borderColor: "#08B4A6",
borderWidth: 1,
},
showBackground: true,
backgroundStyle: {
color: "rgba(105,160,231,0.1)",
},
label: {
show: false, //
formatter: "{c}",
position: "top",
color: "#fff",
fontSize: 14,
},
data: yData,
},
],
dataZoom: [
{
//
show: false,
//
type: "slider",
//
backgroundColor: "rgba(225,225,225,0.2)",
//
fillerColor: "#ccc",
//
borderColor: "rgba(225,225,225,0.2)",
// detail
showDetail: false,
//
startValue: 0,
//
endValue: 10,
// empty
//
filterMode: "empty",
//
width: "80%",
//
height: 5,
//
left: "center",
//
zoomLoxk: true,
//
handleSize: 10,
// dataZoom-slider
bottom: 0,
},
{
//
//
type: "inside",
//
zoomOnMouseWheel: false,
//
moveOnMouseMove: true,
moveOnMouseWheel: true,
},
],
});
window.addEventListener("resize", () => {
this.chart.resize();
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
position: relative;
.anomaly-select {
position: absolute;
z-index: 1;
right: 0;
top: 0.2rem;
::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;
}
.el-select-dropdown {
background-color: #102649;
border-color: #08204f;
.el-scrollbar {
.el-select-dropdown__wrap {
.el-scrollbar__view {
.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;
}
}
}
}
}
}
.anomaly-echart {
width: 100%;
height: 100%;
}
}
</style>

View File

@ -0,0 +1,111 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 15:15:04
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-18 15:47:15
* @FilePath: \znxjxt-ui\src\views\big-screen\road-components\manage-maintain.vue
* @Description: 道路资产大屏-管养道路统计
-->
<template>
<div class="content">
<div class="maintain-left">
<span>{{ mileage }}</span
>km
</div>
<div class="maintain-right">
<span>{{ count }}</span
>
</div>
</div>
</template>
<script>
import { roadRankStatistics } from "@/api/xj/screen/road-screen";
export default {
name: "ManageMaintain",
data() {
return {
//
mileage: "0",
//
count: "0",
};
},
created() {
this.getRoadList();
},
methods: {
getRoadList() {
roadRankStatistics().then(({ code, data }) => {
if (code === 200) {
this.mileage = (data.mileage / 1000).toFixed();
this.count = data.count;
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
display: flex;
justify-content: space-around;
color: #ffffff;
> div {
width: 47%;
height: 100%;
padding-left: 3rem;
line-height: 5rem;
display: flex;
justify-content: center;
font-size: 1rem;
color: #aac6c7;
span {
padding-right: 0.5rem;
font-weight: 800;
font-family: "DouYu";
font-size: 1.2rem;
}
}
.maintain-left {
background-image: url("../../../assets/screen/road/maintain-left.png");
background-repeat: no-repeat;
background-position: 100%;
background-size: 100% 65%;
span {
background: linear-gradient(
to bottom,
#ffffff,
#e9bc5c
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
.maintain-right {
background-image: url("../../../assets/screen/road/maintain-right.png");
background-repeat: no-repeat;
background-position: 100%;
background-size: 100% 65%;
span {
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
}
}
</style>

View File

@ -0,0 +1,255 @@
<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-18 15:22:31
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2024-10-30 16:04:22
* @FilePath: \znxjxt-ui\src\views\big-screen\road-components\road-statistic.vue
* @Description: 道路资产大屏-路产统计
-->
<template>
<div class="content">
<vue-seamless-scroll
class="vue-scroll"
:class-option="defaultOption"
:data="roadList"
v-if="roadList.length > 9"
>
<div
class="road-div"
v-for="(item, index) in roadList"
:key="`road-${index}`"
>
<div class="road-top">
<div class="road-top-name">
<a>{{ index + 1 < 10 ? "0" + (index + 1) : index + 1 }}</a
>{{ item.label }}
</div>
<div class="road-top-value">
<span>{{ item.value }}</span
><a></a>
</div>
</div>
<div class="road-bottom">
<div
class="road-bottom-div"
:style="{ width: `${item.rate * 100}%` }"
:class="`bottom-${index}`"
></div>
</div>
</div>
</vue-seamless-scroll>
<template v-else>
<div
class="road-div"
v-for="(item, index) in roadList"
:key="`road-${index}`"
>
<div class="road-top">
<div class="road-top-name">
<a>{{ index + 1 < 10 ? "0" + (index + 1) : index + 1 }}</a
>{{ item.label }}
</div>
<div class="road-top-value">
<span>{{ item.value }}</span
><a></a>
</div>
</div>
<div class="road-bottom">
<div
class="road-bottom-div"
:style="{ width: `${item.rate * 100}%` }"
:class="`bottom-${index}`"
></div>
</div>
</div>
</template>
</div>
</template>
<script>
import { roadStatisticList } from "@/api/xj/screen/road-screen";
import vueSeamlessScroll from "vue-seamless-scroll";
export default {
name: "RoadStatistic",
components: {
vueSeamlessScroll,
},
props: {
select: {
type: String,
default: "",
},
},
data() {
return {
//
defaultOption: {
step: 0.2, //
limitMoveNum: 1,
hoverStop: true, // stop
direction: 1, // 0 1 2 3
openWatch: true, // dom
singleHeight: 0, // (0)direction => 0/1
singleWidth: 0, // (0) direction => 2/3
waitTime: 2000, // (1000ms)
},
//
roadList: [],
};
},
watch: {
select: {
handler() {
this.getRoadList();
},
immediate: true,
},
},
created() {},
methods: {
/* 获取路产统计信息 */
getRoadList() {
roadStatisticList({ type: this.select }).then(({ code, data }) => {
if (code === 200) {
let sum = 0;
data.forEach((element) => {
sum += element.value;
});
this.roadList = data.map((item) => {
return {
...item,
rate: item.value / sum,
};
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
overflow: hidden;
color: #ffffff;
.road-div {
height: 2.5rem;
width: 100%;
padding: 0 1.5rem;
display: flex;
flex-direction: column;
justify-content: center;
> div {
display: flex;
align-items: center;
justify-content: space-between;
}
.index {
width: 4.5rem;
}
.name {
width: 5rem;
}
.value {
width: 6.5rem;
}
.road-top {
.road-top-name {
line-height: 1.5rem;
color: #c7daf2;
a {
display: inline-block;
width: 1.5rem;
color: #808c9f;
}
}
.road-top-value {
span {
font-family: "DouYu";
color: #c7daf2;
background: linear-gradient(
to bottom,
#ffffff,
#2773d0
); /*设置渐变的方向从左到右 颜色从ff0000到ffff00*/
background-clip: text; /*将设置的背景颜色限制在文字中*/
-webkit-text-fill-color: transparent; /*给文字设置成透明*/
}
a {
margin-left: 0.5rem;
font-size: 0.8rem;
color: #808c9f;
}
}
}
.road-bottom {
width: 100%;
height: 0.5rem;
background-color: rgba(50, 72, 127, 0.3);
position: relative;
.img {
position: absolute;
width: 100%;
height: 100%;
}
.road-bottom-div {
width: 100%;
height: 100%;
display: flex;
background: linear-gradient(90deg, #0e183e 0%, #4087e8 100%);
}
.bottom-0 {
background: linear-gradient(90deg, #0e183e 0%, #4087e8 100%);
}
.bottom-1 {
background: linear-gradient(90deg, #0e183e 0%, #08b4a6 100%);
}
.bottom-2 {
background: linear-gradient(90deg, #0e183e 0%, #be8b13 100%);
}
.bottom-3 {
background: linear-gradient(90deg, #0e183e 0%, #4087e8 100%);
}
.bottom-4 {
background: linear-gradient(90deg, #0e183e 0%, #08b4a6 100%);
}
.bottom-5 {
background: linear-gradient(90deg, #0e183e 0%, #be8b13 100%);
}
.bottom-6 {
background: linear-gradient(90deg, #0e183e 0%, #4087e8 100%);
}
.bottom-7 {
background: linear-gradient(90deg, #0e183e 0%, #08b4a6 100%);
}
.bottom-8 {
background: linear-gradient(90deg, #0e183e 0%, #be8b13 100%);
}
.bottom-9 {
background: linear-gradient(90deg, #0e183e 0%, #4087e8 100%);
}
}
}
}
</style>