zhoule
7 months ago
7 changed files with 652 additions and 42 deletions
@ -0,0 +1,184 @@ |
|||
<template> |
|||
<Dialog v-model="modelVisible" :title="title" width="910px"> |
|||
<div class="DeviceControlDialog"> |
|||
<div class="headSearch"> |
|||
<p>时间范围:</p> |
|||
<el-radio-group v-model="radio1" @input="onChangeRadio"> |
|||
<el-radio-button label="1">日</el-radio-button> |
|||
<el-radio-button label="2">月度</el-radio-button> |
|||
<el-radio-button label="3">年度</el-radio-button> |
|||
</el-radio-group> |
|||
<el-date-picker style="width:140px;" v-model="time" :type="pickerType" placeholder="请选择" :format="valueFormat" |
|||
value-format="yyyy-MM-dd" :clearable="false" @change="initData"> |
|||
</el-date-picker> |
|||
</div> |
|||
<div v-if="chartVisible" class='chart LineChart' ref="LineChartRef" /> |
|||
</div> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import * as echarts from "echarts"; |
|||
import { lineChartOption } from "./chart" |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import request from "@/utils/request"; |
|||
import { throttle } from "lodash" |
|||
import { Message } from "element-ui"; |
|||
|
|||
export default { |
|||
name: "DeviceControlDialog", |
|||
components: { |
|||
Dialog, |
|||
}, |
|||
model: { |
|||
prop: "visible", |
|||
event: "update:value", |
|||
}, |
|||
props: { |
|||
visible: Boolean, |
|||
deviceName: String, |
|||
btnType: Number, |
|||
}, |
|||
data() { |
|||
return { |
|||
submitting: false, |
|||
chartVisible: true, |
|||
title: '气温变化趋势', |
|||
pickerType: 'date', |
|||
valueFormat: 'yyyy-MM-dd', |
|||
radio1: '1', |
|||
time: '' |
|||
}; |
|||
}, |
|||
computed: { |
|||
modelVisible: { |
|||
get() { |
|||
return this.visible; |
|||
}, |
|||
set(val) { |
|||
this.$emit("update:value", val); |
|||
}, |
|||
}, |
|||
}, |
|||
watch: { |
|||
visible: { |
|||
immediate: true, |
|||
handler(bool) { |
|||
if (bool) { |
|||
if (this.btnType == 1) { |
|||
this.title = '气温变化趋势' |
|||
} else { |
|||
this.title = '能见度变化趋势' |
|||
} |
|||
this.initData(); |
|||
} |
|||
|
|||
}, |
|||
}, |
|||
}, |
|||
mounted() { |
|||
this.time = new Date().format('yyyy-MM-dd') |
|||
}, |
|||
methods: { |
|||
async initData() { |
|||
console.log('ll', this.radio1, this.time) |
|||
|
|||
let lastPath = 'deviceHour' |
|||
if (this.pickerType == 'date') { |
|||
lastPath = 'deviceHour' |
|||
} else if (this.pickerType == 'month') { |
|||
lastPath = 'deviceDay' |
|||
} else if (this.pickerType == 'year') { |
|||
lastPath = 'deviceYears' |
|||
} |
|||
|
|||
let qsData = await request({ |
|||
url: `/dc/system/meteorologicalDetector/${lastPath}?deviceName=${this.deviceName}&specificDate=${this.time}`, |
|||
method: "get", |
|||
}) |
|||
if (qsData.code !== 200) { |
|||
return Message.error('查询气象变化趋势数据失败'); |
|||
} |
|||
let times = [], datas = []; |
|||
qsData.rows.forEach(item => { |
|||
if (lastPath == 'deviceHour') { |
|||
times.push(item.timeSlot); |
|||
} else if (lastPath == 'deviceDay') { |
|||
times.push(new Date(item.date).format('dd')); |
|||
} else if (lastPath == 'deviceYears') { |
|||
times.push(new Date(item.month).format('MM')); |
|||
} |
|||
|
|||
datas.push(this.btnType == 1 ? item.avgTemperature : item.avgVisibility) |
|||
}) |
|||
// console.log('datas',datas) |
|||
|
|||
if (lastPath == 'deviceHour') { |
|||
lineChartOption.xAxis.name = '时' |
|||
} else if (lastPath == 'deviceDay') { |
|||
lineChartOption.xAxis.name = '日' |
|||
} else if (lastPath == 'deviceYears') { |
|||
lineChartOption.xAxis.name = '月' |
|||
} |
|||
lineChartOption.xAxis.data = times; |
|||
lineChartOption.yAxis.name = this.btnType == 1 ? '℃' : '米'; |
|||
lineChartOption.series[0].name = this.btnType == 1 ? '温度(℃)' : '能见度(米)' |
|||
lineChartOption.series[0].data = datas; |
|||
|
|||
const chartIns = echarts.init(this.$refs.LineChartRef); |
|||
chartIns.setOption(lineChartOption); |
|||
}, |
|||
async handleSubmit() { |
|||
this.$refs.DeviceParam?.handleSubmit(); |
|||
}, |
|||
onChangeRadio(value) { |
|||
this.time = ''; |
|||
if (value == '1') { |
|||
this.pickerType = 'date' |
|||
this.valueFormat = 'yyyy-MM-dd' |
|||
} else if (value == '2') { |
|||
this.pickerType = 'month' |
|||
this.valueFormat = 'yyyy-MM' |
|||
} else if (value == '3') { |
|||
this.pickerType = 'year' |
|||
this.valueFormat = 'yyyy' |
|||
} |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.DeviceControlDialog { |
|||
width: 860px; |
|||
max-height: 78vh; |
|||
height: 410px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
|
|||
.headSearch { |
|||
display: flex; |
|||
|
|||
p { |
|||
margin-right: 10px; |
|||
} |
|||
|
|||
::v-deep { |
|||
.el-input__prefix { |
|||
top: -5px |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.tips { |
|||
font-size: 12px; |
|||
} |
|||
|
|||
.LineChart { |
|||
flex: 1; |
|||
height: 100%; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,114 @@ |
|||
import * as echarts from "echarts"; |
|||
|
|||
export const lineChartOption = { |
|||
color: ["#2AD9FD"], |
|||
xAxis: { |
|||
name: "时", |
|||
type: "category", |
|||
// boundaryGap: ["15%", "15%"],
|
|||
nameTextStyle: { |
|||
color: "#2AD9FD", |
|||
align: "right", |
|||
fontSize: 15, |
|||
padding: [0, -15, 0, 0], |
|||
}, |
|||
boundaryGap: false, |
|||
data: ['00:00','02:00','04:00','06:00'], |
|||
axisTick: { |
|||
show: false, |
|||
}, |
|||
axisLabel: { |
|||
color: "#fff", |
|||
fontSize: 12, |
|||
}, |
|||
axisLine: { |
|||
lineStyle: { |
|||
color: "#668598", |
|||
}, |
|||
}, |
|||
}, |
|||
yAxis: { |
|||
name: "辆", |
|||
type: "value", |
|||
nameTextStyle: { |
|||
color: "#2AD9FD", |
|||
// align: "right",
|
|||
fontSize: 15, |
|||
// padding: [0, -15, 0, 0],
|
|||
}, |
|||
// nameGap: 24,
|
|||
splitLine: { |
|||
lineStyle: { |
|||
type: [6, 9], |
|||
color: "rgba(255,255,255, .3)", |
|||
// dashOffset: [10, 10],
|
|||
// cap: 21,
|
|||
// width: 2
|
|||
}, |
|||
}, |
|||
axisLabel: { |
|||
color: "#fff", |
|||
fontSize: 12, |
|||
formatter: "{value}", |
|||
}, |
|||
}, |
|||
grid: { |
|||
left: 33, |
|||
top: 33, |
|||
bottom: 24, |
|||
right: 36, |
|||
}, |
|||
tooltip: { |
|||
trigger: "axis", |
|||
backgroundColor: "rgba(0,0,0,0.36)", |
|||
borderWidth: 0, |
|||
textStyle: { |
|||
color: "#fff", |
|||
}, |
|||
formatter: "{b}:{c}", |
|||
// formatter: function([axisData]) {
|
|||
// console.log(axisData)
|
|||
// let str = axisData.name + ' ' + axisData.data + '辆</br>';
|
|||
// // params.forEach(item => {
|
|||
// // if (item.seriesName === '供温' || item.seriesName === '回温') {
|
|||
// // str += item.marker + item.seriesName + ' : ' + item.data.value + ' ℃' + '</br>';
|
|||
// // } else if (item.seriesName === '压力值(Mpa)') {
|
|||
// // // 柱状图渐变时设置marker
|
|||
// // item.marker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#6C50F3;"></span>';
|
|||
// // str += item.marker + item.seriesName + ' : ' + item.data.value + ' m';
|
|||
// // }
|
|||
// // });
|
|||
// return str;
|
|||
// }
|
|||
}, |
|||
legend: { |
|||
textStyle: { |
|||
color: '#2AD9FD' |
|||
} |
|||
}, |
|||
series: [ |
|||
{ |
|||
data: [1,2,3,4], |
|||
type: "line", |
|||
showSymbol: false, |
|||
smooth: true, |
|||
name: '温度(℃)', |
|||
lineStyle: { |
|||
color: "#2AD9FD", |
|||
}, |
|||
areaStyle: { |
|||
opacity: 0.8, |
|||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
|||
{ |
|||
offset: 0, |
|||
color: "rgb(90, 227, 255, .9)", |
|||
}, |
|||
{ |
|||
offset: 1, |
|||
color: "rgba(42,217,253,0)", |
|||
}, |
|||
]), |
|||
}, |
|||
}, |
|||
], |
|||
}; |
@ -0,0 +1,221 @@ |
|||
<template> |
|||
<Dialog v-model="obverseVisible" title="气象设备" width="470px"> |
|||
<div class="MeteorologicalDetection"> |
|||
<Video class="video-stream" :pileNum="dialogData.stakeMark" /> |
|||
<ElTabs v-model="activeName" @tab-click="handleClickTabs" class="tabs"> |
|||
<ElTabPane label="基本信息" name="first"> |
|||
<Descriptions labelWidth="72px" :list="list" :data="data" style="gap: 18px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="气象情况" name="second"> |
|||
<Descriptions labelWidth="104px" :list="weatherList" :data="weatherData" style="gap: 14px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="联动策略" name="third"> |
|||
<!-- <LineChart v-if="activeName === 'third'" :productId="dialogData.id" style="height: 180px" /> --> |
|||
</ElTabPane> |
|||
</ElTabs> |
|||
</div> |
|||
|
|||
<template #footer> |
|||
<Button @click.native="deviceControlVisible = true; btnType = 1">气温变化趋势</Button> |
|||
<Button @click.native="deviceControlVisible = true; btnType = 2">能见度变化趋势</Button> |
|||
</template> |
|||
|
|||
<!-- 设备操作弹窗 --> |
|||
<DeviceControlDialog v-model="deviceControlVisible" :deviceName="dialogData.deviceName" :btnType="btnType" /> |
|||
|
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import Descriptions from "@screen/components/Descriptions.vue"; |
|||
import Button from "@screen/components/Buttons/Button.vue"; |
|||
import { |
|||
getRoadInfoByStakeMark, |
|||
getProduct, |
|||
getMeteorologicalDetector |
|||
} from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js"; |
|||
import Video from "@screen/components/Video"; |
|||
import DeviceControlDialog from "./components/DeviceControlDialog.vue"; |
|||
|
|||
import request from "@/utils/request"; |
|||
import { dialogDelayVisible } from "./../mixin"; |
|||
import LineChart from "../../LineChart/index.vue"; |
|||
|
|||
// 疲劳唤醒弹窗 |
|||
export default { |
|||
name: "MeteorologicalDetection", |
|||
mixins: [dialogDelayVisible], |
|||
components: { |
|||
Dialog, |
|||
Descriptions, |
|||
Video, |
|||
DeviceControlDialog, |
|||
Button, |
|||
LineChart, |
|||
}, |
|||
data() { |
|||
return { |
|||
activeName: "first", |
|||
deviceControlVisible: false, |
|||
data: { |
|||
deviceType: "行车诱导", |
|||
deviceStation: "k094+079", |
|||
roadName: "G35济泽高速", |
|||
direction: "1", |
|||
deviceState: "0", |
|||
deviceVendors: "XXX厂家", |
|||
}, |
|||
btnType: 1, |
|||
weatherData: {}, |
|||
list: [ |
|||
{ |
|||
label: "设备名称", |
|||
key: "deviceName", |
|||
}, |
|||
{ |
|||
label: "设备桩号", |
|||
key: "stakeMark", |
|||
}, |
|||
{ |
|||
label: "道路名称", |
|||
key: "roadName", |
|||
}, |
|||
{ |
|||
label: "设备方向", |
|||
key: "direction", |
|||
enum: "CameraDirectionEnum", |
|||
}, |
|||
{ |
|||
label: "设备状态", |
|||
key: "deviceState", |
|||
enum: "DeviceTypeEnum", |
|||
}, |
|||
{ |
|||
label: "设备厂商", |
|||
key: "manufacturer", |
|||
}, |
|||
], |
|||
weatherList: [ |
|||
{ |
|||
label: "路面状态", |
|||
key: "remoteRoadSurfaceStatus", |
|||
enum: "remoteRoadSurfaceStatus", |
|||
}, |
|||
{ |
|||
label: "路表温度(℃)", |
|||
key: "remoteRoadSurfaceTemperature", |
|||
}, |
|||
{ |
|||
label: "下雨类型", |
|||
key: "precipitationType", |
|||
enum: "precipitationType", |
|||
}, |
|||
{ |
|||
label: "雨量(mm)", |
|||
key: "rainfall", |
|||
}, |
|||
{ |
|||
label: "能见度类型", |
|||
key: "visibilityType", |
|||
enum: "visibilityType", |
|||
}, |
|||
{ |
|||
label: "能见度(km)", |
|||
key: "visibility", |
|||
}, |
|||
{ |
|||
label: "温度(℃)", |
|||
key: "temperature", |
|||
}, |
|||
{ |
|||
label: "湿度", |
|||
key: "humidity", |
|||
}, |
|||
{ |
|||
label: "风向", |
|||
key: "windDirection", |
|||
}, |
|||
{ |
|||
label: "风速(m/s)", |
|||
key: "windSpeed", |
|||
}, |
|||
{ |
|||
label: "水膜厚度(mm)", |
|||
key: "waterFilmlceSnowValue", |
|||
}, |
|||
{ |
|||
label: "大气压力(hPa)", |
|||
key: "atmosphericPressure", |
|||
}, |
|||
{ |
|||
label: "时间", |
|||
key: "createTime", |
|||
gridColumn: 2, |
|||
}, |
|||
] |
|||
}; |
|||
}, |
|||
async created() { |
|||
this.data = { ...this.dialogData }; |
|||
|
|||
getProduct(this.dialogData.productId).then((data) => { |
|||
this.dialogData.brand = data.brand; |
|||
}); |
|||
|
|||
const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMark); |
|||
|
|||
if (roadInfo) this.$set(this.data, "roadName", roadInfo.roadName); |
|||
|
|||
const weatherInfo = await getMeteorologicalDetector(this.dialogData.deviceName) |
|||
this.weatherData = { ...weatherInfo } |
|||
}, |
|||
methods: { |
|||
handleClickTabs() { }, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.MeteorologicalDetection { |
|||
width: 420px; |
|||
color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 12px; |
|||
// padding-bottom: 24px; |
|||
|
|||
.camera-video { |
|||
flex: 1.5; |
|||
} |
|||
|
|||
.tabs { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
::v-deep { |
|||
.el-tabs__content { |
|||
flex: 1; |
|||
|
|||
.el-tab-pane { |
|||
height: 100%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.bottom { |
|||
margin-top: 12px; |
|||
display: flex; |
|||
gap: 9px; |
|||
align-items: center; |
|||
justify-content: end; |
|||
|
|||
>div { |
|||
font-size: 16px; |
|||
padding: 6px 12px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
Loading…
Reference in new issue