feat: 大方县山林生态安全监控平台大屏

This commit is contained in:
Tony 2023-10-25 14:36:00 +08:00
parent ba4fa74b93
commit 4a39159ac0
29 changed files with 903 additions and 0 deletions

BIN
god-ui/public/images/ii.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -205,4 +205,5 @@
</div>
</div>
</body>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=e8722adaace412f3d9d531a5cb019756"></script>
</html>

View File

@ -66,6 +66,11 @@ export const constantRoutes = [
component: () => import('@/views/bigscreen/index.vue'),
hidden: true
},
{
path: '/bigscreen1',
component: () => import('@/views/bigscreen1/index.vue'),
hidden: true
},
{
path: '',
component: Layout,

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,13 @@
const modulesFiles = require.context('./', true, /\.png$/)
const ImageMap = new Map()
modulesFiles.keys().forEach(key => {
const filename = key.split('/').pop();
const url = modulesFiles(key);
ImageMap.set(filename, url);
})
export {
ImageMap
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

View File

@ -0,0 +1,86 @@
@font-face {
font-family: 'BigScreenFont';
src: url(./biaoti.ttf);
}
.background-frame {
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.bigscreen-wrapper {
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #000;
.header-wrapper {
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: space-between;
align-items: center;
height: 8vh;
.time-wrapper, .weather-wrapper {
width: 20vw;
height: 100%;
}
.main-title {
width: 60vw;
text-align: center;
font-size: 34px;
letter-spacing: 4px;
font-family: "BigScreenFont";
background-image: linear-gradient(to top, #a5dfff, white);
-webkit-background-clip: text;
color: transparent;
}
}
.content-wrapper {
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
height: 92vh;
}
.footer-wrapper {
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
height: 0vh;
}
}
.table-wrapper {
position: relative;
width: 100%;
height: 100%;
.table-header-row {
width: 100%;
display: flex;
position: sticky;
padding: 5px 0;
top: 0;
background: linear-gradient(to top, #1C3B68, #1C3B6800);
.table-header-cell {
padding: 4px 0;
text-align: center;
font-size: 14px;
color: #dbdbdb;
}
}
.table-data-row {
display: flex;
width: 100%;
font-size: 13px;
.table-data-cell {
padding: 10px 0;
font-size: 14px;
color: #dbdbdb;
text-align: center;
}
}
}

View File

@ -0,0 +1,798 @@
<template>
<div class="bigscreen-wrapper background-frame">
<div class="header-wrapper background-frame">
<div class="time-wrapper">
<span style="display: flex;">
<span>{{ dateDay }}</span>
<span style="padding-left: 20px;">{{ dateTime }}</span>
</span>
</div>
<div class="main-title">大方县山林生态安全监控平台</div>
<div class="weather-wrapper">
</div>
</div>
<div class="content-wrapper">
<div class="content-item" style="grid-row: span 2;">
<div class="content-header">野生动物种类红外检测</div>
<div class="content-inner table-wrapper">
<div class="table-header">
<div
class="table-header-cell"
v-for="column in columns1"
:style="`width:${column.width};`"
>{{ column.label }}</div>
</div>
<div class="table-row" v-for="item in data1">
<div
class="table-row-cell"
v-for="column in columns1"
:style="`width:${column.width};`"
>{{ item[column.key] }}</div>
</div>
</div>
</div>
<div
class="content-item middle-map-wrapper"
style="grid-row: span 3;grid-column: span 2;"
id="middleMap"
>
<div class="middle-tool-tip" style="display: none;">
<div class="middle-tool-title"></div>
</div>
</div>
<div class="content-item">
<div class="content-header">森林环境监测</div>
<div class="content-inner forest-wrapper">
<div class="forest-item">
<i></i>
<div class="forest-info">山洪可能性</div>
<div class="forest-level">较低</div>
</div>
<div class="forest-item">
<i></i>
<div class="forest-info">降水量</div>
<div class="forest-level">1.2mm</div>
</div>
<div class="forest-item">
<i></i>
<div class="forest-info">植被覆盖率</div>
<div class="forest-level">54.33%</div>
</div>
<div class="forest-item">
<i></i>
<div class="forest-info">温度</div>
<div class="forest-level">16°C</div>
</div>
<div class="forest-item">
<i></i>
<div class="forest-info">湿度</div>
<div class="forest-level">75%</div>
</div>
<div class="forest-item">
<i></i>
<div class="forest-info">地表径流量</div>
<div class="forest-level"> 11.108 mm</div>
</div>
</div>
</div>
<div
class="content-item"
style="grid-row: span 2;"
>
<div class="content-header">季节性河流监测</div>
<div class="content-inner table-wrapper">
<div class="table-header">
<div
class="table-header-cell"
v-for="column in columns3"
:style="`width:${column.width};`"
>{{ column.label }}</div>
</div>
<div class="table-row" v-for="item in data3">
<div
class="table-row-cell"
v-for="column in columns3"
:style="`width:${column.width};`"
>{{ item[column.key] }}</div>
</div>
</div>
</div>
<div class="content-item">
<div class="content-header">山林虫情预防</div>
<div class="content-inner table-wrapper">
<div class="table-header">
<div
class="table-header-cell"
v-for="column in columns2"
:style="`width:${column.width};`"
>{{ column.label }}</div>
</div>
<div class="table-row" v-for="item in data2">
<div
class="table-row-cell"
v-for="column in columns2"
:style="`width:${column.width};`"
>{{ item[column.key] }}</div>
</div>
</div>
</div>
<div
class="content-item"
style="grid-column: span 2;"
>
<div class="content-header content-header1">病虫害分析统计图</div>
<div class="content-inner" id="weakSomeChart"></div>
</div>
<div
class="content-item"
style="grid-column: span 2;"
>
<div class="content-header content-header1">林植被覆盖分析</div>
<div class="content-inner" id="treeChart"></div>
</div>
</div>
<div class="footer-wrapper"></div>
</div>
</template>
<script>
import { ImageMap } from './assets/index'
import * as echarts from 'echarts'
window._AMapSecurityConfig = {
securityJsCode:'289153494763707d55b03878ace1cb08',
}
export default {
data() {
return {
map: null,
ImageMap,
dateDay: '',
dateTime: '',
timeTimer: null,
columns1: [
{
key: 'name',
label: '名称',
width: '25%'
},
{
key: 'level',
label: '级别',
width: '25%'
},
{
key: 'this',
label: '今年数量',
width: '25%'
},
{
key: 'last',
label: '去年数量',
width: '25%'
},
],
data1: [
{
name: '黔金丝猴',
level: '国家一级',
this: '713',
last: '683'
},
{
name: '黔金丝猴',
level: '国家一级',
this: '713',
last: '683'
},
{
name: '黔金丝猴',
level: '国家一级',
this: '713',
last: '683'
},
{
name: '黔金丝猴',
level: '国家一级',
this: '713',
last: '683'
},
{
name: '黔金丝猴',
level: '国家一级',
this: '713',
last: '683'
},
],
columns2: [
{
key: 'read',
label: '监测因子',
width: '33%'
},
{
key: 'multi',
label: '多发季节',
width: '33%'
},
{
key: 'operate',
label: '预防措施',
width: '34%'
},
],
data2: [
{
read: '松线虫',
multi: '秋季',
operate: '提前航化洒药',
},
{
read: '美国白蛾',
multi: '秋冬季',
operate: '提前航化洒药',
},
{
read: '草原蝗虫',
multi: '秋季',
operate: '生物农药治理',
},
],
columns3: [
{
key: 'name',
label: '河流名称',
width: '33%'
},
{
key: 'water',
label: '水量丰沛程度',
width: '34%'
},
{
key: 'floor',
label: '流量',
width: '33%'
},
],
data3: [
{
name: '白水河',
water: '丰水期',
floor: '6.2m³/s',
},
{
name: '牛兰江',
water: '枯水期',
floor: '6.5m³/s',
},
{
name: '林麝',
water: '丰水期',
floor: '7.5m³/s',
},
{
name: '黑颈鹤',
water: '丰水期',
floor: '31.2m³/s',
},
{
name: '穿山甲',
water: '丰水期',
floor: '44m³/s',
},
],
}
},
created() {
this.getNowTime();
this.timeTimer = setInterval(() => {
this.getNowTime();
}, 1000);
},
beforeDestroy() {
clearInterval(this.timeTimer)
},
mounted() {
this.initChart();
this.initPieChart();
this.initMap();
},
methods: {
initChart() {
const chart = document.getElementById("weakSomeChart");
const chartInstance = echarts.init(chart, 'default');
chartInstance.setOption({
title: {
text: "",
textStyle: {
fontSize: 16
},
},
textStyle: {
color: '#fff'
},
color: [
'#306fff',
'#30c9c9',
'#f7ad08',
'#93beff'
],
tooltip: {
show: true
},
xAxis: {
show: true,
name: "",
nameLocation: "end", // startmiddle
nameTextStyle: {
//
color: "#9b9ba4",
},
nameGap: 15, // 线
inverse: false, //
axisLabel: {
//
hideOverlap: true, //
color: "#9b9ba4",
},
axisLine: {
show: false,
},
position: "bottom",
offset: 0, //
type: "category", // time value log
data: ['松线虫', '美国白蛾', '松墨天牛', '松赤枯病', '桃缩叶病', '松斑蛾', '茶袋蛾'],
},
yAxis: {
name: "单位:万亩",
nameTextStyle: {
//
color: "#9b9ba4",
},
axisLabel: {
//
hideOverlap: true, //
color: "#9b9ba4",
},
axisLine: {
show: false,
},
minorTick: {
// 线
show: false,
},
splitLine: {
// grid线
show: true,
lineStyle: {
type: 'dashed',
color: 'rgba(255, 255, 255, 0.3)'
}
},
},
series: [
{
name: '2022',
data: [8.2, 7.0, 5.85, 4.19, 2.23, 7.00, 8.20],
type: 'bar',
barWidth: 20,
showBackground: true,
itemStyle: {
color: '#0f9f98'
},
areaStyle: {
normal: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: "#226dc0" // 0%
}, {
offset: 0.7,
color: "#226dc040" // 100%
}],
globalCoord: false // false
}
}
},
},
{
name: '2023',
data: [6.39, 8.32, 6.39, 4.65, 6.80, 5.79, 2.39],
type: 'bar',
barWidth: 20,
showBackground: true,
itemStyle: {
color: '#0aa473'
},
areaStyle: {
normal: {
color: {
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: "#226dc0" // 0%
}, {
offset: 0.7,
color: "#226dc040" // 100%
}],
globalCoord: false // false
}
}
},
}
],
legend: {
show: true,
//
orient: "horizontal", // horizontal vertical
right: "10", //
top: "10", //
// backgroundColor: "#000000",
// borderColor: "#ccc",
// borderWidth: 0,
padding: 5,
itemGap: 10, // item
itemWidth: 10, //
itemHeight: 10, //
borderRadius: 10,
textStyle: {
color: "#d7d8db",
fontSize: 9,
},
lineStyle: {
type: 'dotted',
opacity: 0
}
},
grid: {
left: '6%',
top: '19%',
right: '2%',
bottom: '13%'
}
}, true, true);
window.addEventListener("resize", () => {
this.$nextTick(() => {
chartInstance && chartInstance.resize();
})
})
},
initPieChart() {
const chart = document.getElementById("treeChart");
const chartInstance = echarts.init(chart, 'default');
chartInstance.setOption({
textStyle: {
color: '#7a8898'
},
color: [
'#37A2DA',
'#9FE6B8',
'#FFDB5C',
'#ff9f7f',
'#fb7293',
'#E062AE',
'#32C5E9',
'#67E0E3',
'#E690D1',
'#e7bcf3',
'#9d96f5',
'#8378EA',
'#96BFFF'
],
tooltip: {
trigger: 'item'
},
legend: {
//
orient: "vertical",
right: 50,
itemGap: 20,
top: 'center',
textStyle: {
color: '#fff'
},
},
series: [
{
name: "",
type: "pie",
radius: ["36%", "65%"],
center: ["30%", "50%"],
data: [
{ name: '阔叶林', value: 204 },
{ name: '针叶林', value: 166 },
{ name: '灌从和灌草从', value: 47 },
{ name: '沼泽与水生植被', value: 34 },
{ name: '竹林', value: 25 },
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
label: {
show: true,
formatter: "{d}%"
}
}
],
grid: {
x: 80,
x2: 80,
y: 80,
y2: 60,
//
backgroundColor: "rgba(0,0,0,0)",
borderWidth: 2,
borderColor: "#fff232",
},
polor: {
center: ["30%", "50%"],
},
}, true, true);
window.addEventListener("resize", () => {
this.$nextTick(() => {
chartInstance && chartInstance.resize();
})
})
},
getNowTime() {
const date = new Date();
let year = date.getFullYear(); //
let month = date.getMonth() + 1; //+1
month = month < 10 ? '0' + month.toString() : month.toString();
let dates = date.getDate(); //
dates = dates < 10 ? '0' + dates.toString() : dates.toString();
let day = date.getDay();
const arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
this.dateDay = year + '-' + month + '-' + dates + ' ' + arr[day];
this.dateTime = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours())
+ ':' +
(date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
+ ':' +
(date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
},
initMap() {
this.map = new AMap.Map("middleMap", {
zoom: 11,//
center: [105.60178899809716, 27.14450662262202], //
mapStyle: 'amap://styles/blue',
});
//
// AMap.plugin([
// 'AMap.MapType',
// 'AMap.ToolBar',
// 'AMap.Scale'
// ], () => {//
// const mapType = new AMap.MapType();
// this.map.addControl(mapType);
// const toolbar = new AMap.ToolBar();
// this.map.addControl(toolbar);
// const scale = new AMap.Scale();
// this.map.addControl(scale);
// });
this.map.on('mapmove', () => {})
this.map.on('click', (e) => {
navigator.clipboard.writeText(`[${e.lnglat.R.toString()}, ${e.lnglat.Q.toString()}],`)
})
// const layers = [
// new AMap.TileLayer.Satellite(),
// new AMap.TileLayer.RoadNet()
// ]
// this.map.setLayers(layers);
const markers = [
{
position: [105.62449121519921, 27.136754069705578],
info: {
plantareaAddress: '烟雾传感器',
dataList: [
{
label: '编号',
value: 'EH09801'
},
{
label: '烟雾浓度',
value: '4.3ug/m³'
},
{
label: '状态',
value: ' 正常'
},
{
label: '负责人',
value: ' 祁星'
},
{
label: '联系方式',
value: ' 15844596255'
},
]
}
}
]
markers.forEach(item => {
this.addMapMarker(
item.position,
'ii',
item.info
)
})
},
//
addMapMarker(sourceData = [], type = 'red', info = {}) {
const marker = new AMap.Marker({
position: new AMap.LngLat(sourceData[0], sourceData[1]),
offset: new AMap.Pixel(-30, -52),
icon: `/images/${type}.png`, // Icon URL
title: ''
});
this.map.add(marker);
marker.on('click', (e) => {
this.showInfoWindow(sourceData[0], sourceData[1], { type: '#304156', ...info })
})
},
//
showInfoWindow(lng, lat, sourceInfo) {
let content = `
<div style="padding: 6px;background-color: #05121390;border: 1px solid #18fefe;">
<div style="color: white;text-align:center;padding: 6px 10px;letter-spacing:1px;font-weight:bold;">
${sourceInfo.plantareaAddress || '监控点'}
</div>
<div style="padding: 3px 10px 0 10px;font-size: 12px;color:#fff;">
${
sourceInfo.dataList.map(item => (`
<div style="margin-bottom: 4px;padding: 4px 10px;display:flex;justify-content:space-between;align-items:center;background-color:#063f3f;">
<div>${item.label}</div>
<div style="padding-left: 10px;">${item.value}</div>
</div>
`)).join('')
}
</div>
</div>
`;
const infoWindow = new AMap.InfoWindow({
content,
anchor: 'middle-left',
isCustom: true
});
infoWindow.open(this.map, [lng, lat])
},
}
}
</script>
<style scoped lang="scss">
@import url(./bigscreen.scss);
.bigscreen-wrapper {
background-image: url(./assets/bg.png);
.header-wrapper {
position: relative;
background-image: url(./assets/headerBg.png);
.time-wrapper {
font-family: "BigScreenFont";
background-image: linear-gradient(to top, #a5dfff, white);
-webkit-background-clip: text;
color: transparent;
position: relative;
top: 10px;
left: 16px;
}
.main-title {
position: relative;
top: -.5vh;
}
}
.content-wrapper {
display: grid;
grid-template-columns: 2fr 2fr 2fr 2fr;
grid-template-rows: 6fr 2fr 6fr 7fr;
padding: 16px;
gap: 14px;
.content-item {
.content-header {
height: 40px;
padding-left: 50px;
padding-top: 9px;
font-family: 'BigScreenFont';
color: white;
background-image: url(./assets/titleBg.png);
background-size: 100% 100%;
}
.content-header1 {
background-image: url(./assets/titleBg1.png) !important;
}
.content-inner {
margin-top: 6px;
height: calc(100% - 46px);
background-image: url(./assets/contentInner.png);
background-size: 100% 100%;
}
}
}
}
/**森林环境 */
.forest-wrapper {
padding: 12px 18px;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
gap: 16px;
.forest-item {
background-color: #0b292f;
display: flex;
align-items: center;
padding: 0 14px;
i {
background-image: url(./assets/rect.png);
width: 20px;
height: 20px;
background-size: 100% 100%;
}
.forest-info {
color: #dbdbdb;
width: 130px;
padding: 0 12px;
}
.forest-level {
color: white;
padding: 0 8px;
}
}
}
.table-wrapper {
padding: 10px;
.table-header {
display: flex;
color: #56d8d9;
padding: 8px 0 10px 0;
.table-header-cell {
text-align: center;
font-size: 14px;
}
}
.table-row {
display: flex;
align-items: center;
color: #d4d5d5;
padding: 8px 0 10px 0;
border: 1px solid #3890919a;
.table-row-cell {
text-align: center;
}
}
.table-row:nth-child(odd) {
background-color: #031015;
}
.table-row:nth-child(even) {
background-color: #0a2329;
}
}
/**山林中央地图 */
.middle-map-wrapper {
position: relative;
.middle-tool-tip {
position: absolute;
top: 10px;
left: 10px;
padding: 10px;
z-index: 99;
.middle-tool-title {
font-family: 'BigScreenFont';
}
}
}
</style>