Просмотр исходного кода

Merge branch 'lixin' of gitadmin/tuoheng_lc_web into develop

tags/v1.2.0
lixin 1 год назад
Родитель
Сommit
43cf25a99b
11 измененных файлов: 282 добавлений и 37 удалений
  1. +1
    -1
      .env.localhost
  2. +20
    -4
      src/api/dashboard/index.js
  3. Двоичные данные
      src/assets/gis/images/fire.png
  4. Двоичные данные
      src/assets/gis/images/measure.png
  5. Двоичные данные
      src/assets/gis/images/power.png
  6. Двоичные данные
      src/assets/gis/images/range.png
  7. +1
    -2
      src/views/dashboard/components/AirInfo.vue
  8. +108
    -19
      src/views/dashboard/components/FireAlarm.vue
  9. +150
    -10
      src/views/dashboard/components/OneMap.vue
  10. +1
    -0
      src/views/dashboard/components/ProblemInfo.vue
  11. +1
    -1
      src/views/dashboard/index.vue

+ 1
- 1
.env.localhost Просмотреть файл

@@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/'
VITE_APP_USE_MOCK = false

# proxy
VITE_PROXY = [["/api-local","http://127.0.0.1:8002/api"],["/api-mock","http://127.0.0.1:8003"]]
VITE_PROXY = [["/api-local","https://lcxj-test.t-aaron.com/api"],["/api-mock","http://127.0.0.1:8003"]]

# base api
VITE_APP_GLOB_BASE_API = '/api-local'

+ 20
- 4
src/api/dashboard/index.js Просмотреть файл

@@ -62,11 +62,10 @@ export function missionLive(id) {
* @description:获取机场详细信息
* @param id 机场id
*/
export function getAirportInfo(data) {
export function getAirportInfo(id) {
return request({
url: `/index/getAirportDetail/${data.airportId}`,
method: 'POST',
data
url: `/index/getAirportDetail/${id}`,
method: 'GET'
})
}
/**
@@ -104,3 +103,20 @@ export function getQuestionList(data) {
})
}

// 预警列表
export function getWarning() {
return request({
url: `/warning/list?status=1`,
method: 'GET'
})
}

// 根据预警ID获取预警记录列表
export function getWarningRecord(params) {
return request({
url: `/warning/record/list/by/warningid`,
method: 'GET',
params
})
}


Двоичные данные
src/assets/gis/images/fire.png Просмотреть файл

Before After
Width: 70  |  Height: 70  |  Size: 858B

Двоичные данные
src/assets/gis/images/measure.png Просмотреть файл

Before After
Width: 34  |  Height: 34  |  Size: 507B

Двоичные данные
src/assets/gis/images/power.png Просмотреть файл

Before After
Width: 34  |  Height: 34  |  Size: 400B

Двоичные данные
src/assets/gis/images/range.png Просмотреть файл

Before After
Width: 34  |  Height: 34  |  Size: 566B

+ 1
- 2
src/views/dashboard/components/AirInfo.vue Просмотреть файл

@@ -107,8 +107,7 @@ export default {

watch(() => props.data, (value) => {
if (JSON.stringify(value) !== '{}') {
// console.log(props.data)
data.detail = props.data
data.detail = value
innerVideoRef.value?.disposeVideo()
outVideoRef.value?.disposeVideo()
initPlayer(data.detail.internalMonitorUrl, data.detail.externalMonitorUrl)

+ 108
- 19
src/views/dashboard/components/FireAlarm.vue Просмотреть файл

@@ -8,15 +8,15 @@
</div>
<p class="alarm-detail">
<span>火灾位置:</span>
<span>xxxxxxxxxxxxxx位置</span>
<span>{{ fireDetail.location }}</span>
</p>
<p class="alarm-detail">
<span>发现方式:</span>
<span>监控摄像、无人机巡检、人工巡检</span>
<span>{{ fireDetail.discoveryWay }}</span>
</p>
<p class="alarm-detail">
<span>上报时间:</span>
<span>2023-01-28 10:00:00</span>
<span>{{ fireDetail.time }}</span>
</p>
</div>
<p class="dividing-line" />
@@ -25,6 +25,7 @@
<p class="dispatch-detail">
<span>选择机场:</span>
<n-select v-model:value="value" :options="airpotOptions" />
<a>可用机场列表</a>
</p>
<p class="dispatch-detail">
<span>飞行高度:</span>
@@ -56,16 +57,26 @@
</div>

<div class="available-airports">
<p>可用机场列表</p>
<div>
<p class="alarm-title">可用机场列表</p>
<div class="airport-params">
<p>
<span>机场1</span>
<span>发现隐患的机场</span>
<span class="airport-name">机场1</span>
<span class="airport-find">发现隐患的机场</span>
</p>
<p>
<p class="uav-params">
<img src="@/assets/gis/images/range.png">
<span>6km</span>
<span>续航里程</span>
</p>
<p class="uav-params">
<img src="@/assets/gis/images/power.png">
<span>60%</span>
<span>无人机电量</span>
<span>机场距离火灾隐患点</span>
</p>
<p class="uav-params" style="width: 252px">
<img src="@/assets/gis/images/measure.png">
<span style="width: 130px">3km</span>
<span style="width: 130px">机场距离火灾隐患点</span>
</p>
</div>
</div>
@@ -73,7 +84,8 @@
<script>

import { reactive, toRefs, watch } from 'vue'

import { EARLY_SOURCE } from '@/utils/dictionary.js'
import { getWarningRecord } from '@/api/dashboard/index.js'
export default {
name: 'FireAlarm',
components: { },
@@ -95,13 +107,33 @@ export default {
label: '机场2',
value: 'airport2'
}
]
],
fireDetail: {}
})

watch(() => props.data, (value) => {

if (JSON.stringify(value) !== '{}') {
data.warningList = props.data
showDetail(data.warningList)
}
})

const showDetail = async(value) => {
data.fireDetail.location = value?.location
data.fireDetail.discoveryWay = ''
EARLY_SOURCE?.map((item) => {
if (item.value === parseInt(value?.discoveryWay)) {
data.fireDetail.discoveryWay = item.label
}
})
data.fireDetail.time = value?.updateTime

const res = await getWarningRecord({
warningId: value.id
})
console.log(res)
}

const formatHeight = (value) => {
return value + 'm'
}
@@ -127,19 +159,21 @@ export default {
}

.alarm-title {
width: 100%;
width: 200px;
height: 30px;
line-height: 30px;
font-size: 14px;
color: #fff;
padding-left: 6px;
margin-top: 10px;
display: inline-block;
}

.alarm-detail {
width: 100%;
height: 30px;
span:first-child {
width: 90px;
width: 85px;
height: 30px;
line-height: 30px;
display: inline-block;
@@ -148,7 +182,7 @@ export default {
text-align: right;
}
span:nth-child(2){
width: 310px;
width: 320px;
height: 30px;
line-height: 30px;
display: inline-block;
@@ -165,7 +199,7 @@ export default {
opacity: 1;
background: rgba(112, 112, 112, 1);
border: 0.2px solid rgba(107, 107, 107, 1);
margin: 15px 0;
margin: 15px 0 0 0;
}

::v-deep(.dispatch-detail) {
@@ -195,9 +229,13 @@ export default {
display: inline-block;
margin-left: 6px;
vertical-align: middle;
.n-slider-handle-indicator--top {
margin-bottom: 0;
}
}

a {
color: rgba(0, 119, 255, 1);
font-size: 10px;
margin-left: 6px;
cursor: pointer;
}

}
@@ -276,5 +314,56 @@ export default {
background: rgba(0, 0, 0, 1);
}

.airport-params {
width: 278px;
height: 191px;
display: inline-block;
border-radius: 3px;
background: rgba(44, 44, 44, 1);
margin-left: 3px;
margin-top: 10px;
}

.airport-name {
width: 180px;
height: 30px;
display: inline-block;
line-height: 30px;
color: #fff;
font-size: 14px;
padding-left: 5px;
}

.airport-find {
width: 80px;
height: 30px;
font-size: 12px;
color: rgba(255, 141, 26, 1);
}

.uav-params {
width: 121px;
height: 64px;
border-radius: 3px;
background: rgba(66, 66, 66, 1);
float: left;
margin: 10px 0 0 13px;
img {
width: 34px;
height: 34px;
margin: 16px 0 14px 10px;
float: left;
}
span {
width: 60px;
display: inline-block;
height: 30px;
line-height: 30px;
text-align: center;
color: #fff;
font-size: 12px;
}
}

</style>


+ 150
- 10
src/views/dashboard/components/OneMap.vue Просмотреть файл

@@ -29,7 +29,7 @@
/>
</div>

<!-- <fire-alarm /> -->
<fire-alarm :data="warningDetail" />

</template>

@@ -46,14 +46,11 @@ import { transform, fromLonLat } from 'ol/proj'
import { Style, Icon, Text, Fill } from 'ol/style'
import * as control from 'ol/control'
import uav_icon from '@/assets/images/airport.png'
import personnel_icon from '@/assets/images/personnelActivities.png'
import problemSpot_icon from '@/assets/images/problemSpot.png'
import deadTree_icon from '@/assets/images/deadTree.png'
import fireHazard_icon from '@/assets/images/fireHazard.png'
import warningIcon from '@/assets/gis/images/fire.png'
import { reactive, toRefs, onMounted, computed, ref, watch, onBeforeUnmount } from 'vue'
import { Point } from 'ol/geom'
import {
airportList
airportList, getWarning
} from '@/api/dashboard/index.js'
import { getQuestions } from '@/api/task/index.js'
import { gcj02towgs84 } from '@/utils/coordinate-util.js'
@@ -102,7 +99,12 @@ export default {
suppliesOverlay: null,
suppliesDetail: {},
monitorOverlay: null,
montiorName: null
montiorName: null,
// 预警定时器
warningTimer: null,
warningList: [],
warningLayers: [],
warningDetail: {}
})

const getMapOptions = computed(() => {
@@ -179,6 +181,13 @@ export default {
data.map.on('click', (evt) => {
click2ShowInfo(evt)
})

// 鼠标移到要素上时改变鼠标样式,由箭头变成小手
data.map.on('pointermove', function(evt) {
data.map.getTargetElement().style.cursor = data.map.hasFeatureAtPixel(evt.pixel)
? 'pointer'
: ''
})
}

/**
@@ -284,6 +293,8 @@ export default {
const coord = properties.coordinate
data.map.addOverlay(data.airOverlay)
data.airOverlay.setPosition(coord)
// 设置z-index
data.airOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
}
// 监控视频
if (properties.type === 'camera') {
@@ -300,6 +311,8 @@ export default {
source: properties.props.flvUrl,
isLive: true
})
// 设置z-index
data.monitorOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
}
// 监控视频
if (properties.type === 'materials') {
@@ -309,16 +322,43 @@ export default {
data.suppliesOverlay.setPosition(coord)
// 设置属性
data.suppliesOverlay.setProperties({ 'type': properties.type })
// 设置z-index
data.suppliesOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
}
// 问题
if (properties.type === 'question') {
data.problemDetail = properties.pros
data.problemDetail = properties.props
const coord = properties.geometry.flatCoordinates
data.problemPopupShow = true
data.map.addOverlay(data.problemOverlay)
data.problemOverlay.setPosition(coord)
// 设置属性
data.problemOverlay.setProperties({ 'code': properties.props.type })
// 设置z-index
data.problemOverlay.getElement().parentElement.style.zIndex = getMaxZOverlay() + 1
}
// 预警
if (properties.type === 'warning') {
data.warningDetail = properties.props
}
}
}

/**
* 获取打开overlay中最大的 z-index
*/
const getMaxZOverlay = () => {
let maxZIndex = 0
const overlays = data.map.getOverlays().array_
if (overlays.length) {
overlays.forEach((item) => {
const zIndex = item.getElement().parentElement.style.zIndex
if (zIndex > maxZIndex) {
maxZIndex = zIndex
}
})
}
return maxZIndex
}

/**
@@ -348,12 +388,23 @@ export default {
}
}

/**
* 关闭显示问题图层信息
*/
const hideProblemInfo = () => {
if (data.map.getOverlayById('problem_overlay')) {
data.problemDetail = {}
data.map.removeOverlay(data.problemOverlay)
}
}

const addPonit = (res) => {
// 火灾预警
if (res.tabs === 0) {
// 清除问题图层
removeProblemLayer()

// 移除问题弹窗
hideProblemInfo()
if (data.vectorLayers.length === 0) {
res.data?.map((item) => {
addVectorLayer(item)
@@ -375,6 +426,9 @@ export default {
if (layer.getProperties().type === 'camera') {
monitorVideo.value?.disposeVideo()
}
if (layer.getProperties().type === 'materials') {
data.suppliesDetail = {}
}
})
}
} else {
@@ -382,6 +436,9 @@ export default {
}
})
}

// 展示预警
showWarning()
} else { // 森林巡检
// 清除火灾预警中所有已加载的图层
removeVectorLayer()
@@ -390,6 +447,7 @@ export default {

if (res.ops === 'query') {
removeProblemLayer()
hideProblemInfo()
if (res.data.length) {
addProblemLayer(res.data)
}
@@ -397,6 +455,18 @@ export default {
data.problemLayers?.map((layer) => {
if (res.type.indexOf(layer.getProperties().code) === -1) {
layer.setVisible(false)
// 若问题图层 某种类型对应的弹框打开, 则将其关闭
// 获取所有打开的overlay
const overlays = data.map.getOverlays().array_
if (overlays.length) {
overlays.forEach((item) => {
// 遍历 找到图层对应的overlay一并移除
if (layer.getProperties().code === item.values_.code) {
data.map.removeOverlay(item)
data.problemDetail = {}
}
})
}
} else {
layer.setVisible(true)
}
@@ -405,6 +475,74 @@ export default {
}
}

const showWarning = () => {
data.warningTimer = setInterval(() => {
getWarningList().then((warningList) => {
removeWarningLayer()
addWarninglayer(warningList)
})
}, 2000)
}

const getWarningList = async() => {
const res = await getWarning()
if (res.code === 0) {
const warningList = res.data
data.warningList = warningList
return warningList
}
}

const addWarninglayer = (warningList) => {
const Features = []
warningList?.map((item) => {
const lngLat =
[parseFloat(item.lng),
parseFloat(item.lat)]
const feature = new Feature({
geometry: new Point(fromLonLat(lngLat))
})
// 要素设置样式
feature.setStyle(
new Style({
// 图标
image: new Icon({
src: warningIcon,
crossOrigin: 'anonymous'
})
})
)
// 要素设置属性
feature.setProperties({
// 类型设为 预警
type: 'warning',
// 属性
props: item
})
Features.push(feature)
})

// 添加图层
const warningLayer = new VectorLayer({
source: new VectorSource({
features: Features
}),
visible: true
})
// 添加图层
data.map.addLayer(warningLayer)
data.warningLayers.push(warningLayer)
}

const removeWarningLayer = () => {
data.warningLayers.map((layer) => {
if (layer !== null) {
data.map.removeLayer(layer)
}
})
data.warningLayers.length = 0
}

/**
* 添加问题图层
* @param {*} item
@@ -543,7 +681,9 @@ export default {
monitorVideo,
hideMonitor,
removeAllOverlays,
removeProblemLayer
removeProblemLayer,
hideProblemInfo,
getMaxZOverlay
}
}
}

+ 1
- 0
src/views/dashboard/components/ProblemInfo.vue Просмотреть файл

@@ -66,6 +66,7 @@ export default {
})

watch(() => props.detail, (value) => {
console.log(value)
if (JSON.stringify(value) !== '{}') {
const fileImageList = value.fileMarkerUrl.split(',')
data.fileImageList = []

+ 1
- 1
src/views/dashboard/index.vue Просмотреть файл

@@ -1,6 +1,6 @@
<template>
<div class="basic">
<OneMap ref="Map"/>
<OneMap ref="Map" />
<Extend ref="extendRef" class="extend" @send="getmessage" />
</div>
</template>

Загрузка…
Отмена
Сохранить