ソースを参照

Merge branch 'lixin' of gitadmin/tuoheng_lc_web into develop

tags/v1.2.0
lixin 1年前
コミット
4fb16438d4
6個のファイルの変更1823行の追加87行の削除
  1. +1523
    -3
      package-lock.json
  2. +1
    -0
      package.json
  3. +25
    -0
      src/api/dashboard/index.js
  4. +255
    -76
      src/views/dashboard/components/FireAlarm.vue
  5. +18
    -1
      src/views/dashboard/components/OneMap.vue
  6. +1
    -7
      src/views/dashboard/index.vue

+ 1523
- 3
package-lock.json
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1
- 0
package.json ファイルの表示

@@ -11,6 +11,7 @@
"dependencies": {
"@easydarwin/easyplayer": "^5.0.5",
"@tinymce/tinymce-vue": "^4.0.5",
"@turf/turf": "^6.5.0",
"@vicons/antd": "^0.10.0",
"@vicons/ionicons5": "^0.10.0",
"ali-oss": "^6.17.1",

+ 25
- 0
src/api/dashboard/index.js ファイルの表示

@@ -120,3 +120,28 @@ export function getWarningRecord(params) {
})
}

// 根据ID查询预警信息
export function getWarningInfo(id) {
return request({
url: `/warning/${id}`,
method: 'GET'
})
}

// 忽略预警
export function ignoreWarning(id) {
return request({
url: `/warning/ignore/${id}`,
method: 'POST'
})
}

// 预警已确认
export function confirmWarning(params) {
return request({
url: `/warning/confirm`,
method: 'POST',
params
})
}


+ 255
- 76
src/views/dashboard/components/FireAlarm.vue ファイルの表示

@@ -1,14 +1,15 @@

<template>
<div class="fire-alarm">
<div v-if="warningShow" class="fire-alarm">
<span class="close-content" @click="closeWarning">x</span>
<div class="fire-details">
<p class="alarm-title">火灾详情</p>
<div style="width: 100%; height: 210px">
视频位置
<div class="pic-content">
<img :src="warningPic" class="warning-pic">
</div>
<p class="alarm-detail">
<span>火灾位置:</span>
<span>{{ fireDetail.location }}</span>
<span style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">{{ fireDetail.location }}</span>
</p>
<p class="alarm-detail">
<span>发现方式:</span>
@@ -24,68 +25,77 @@
<p class="alarm-title">机场调度</p>
<p class="dispatch-detail">
<span>选择机场:</span>
<!-- <n-select v-model:value="value" :options="airpotOptions" /> -->
<a>可用机场列表</a>
<n-select v-model:value="airValue" placeholder="请选择机场" :options="airpotOptions" />
<a @click="checkAirport">可用机场列表</a>
</p>
<p class="dispatch-detail">
<span>飞行高度:</span>
<!-- <n-slider v-model:value="value" :default-value="100" :format-tooltip="formatHeight" :max="600" :show-tooltip="true" placement="bottom" /> -->
<n-slider v-model:value="flyHeight" :default-value="100" :format-tooltip="formatHeight" :max="600" :show-tooltip="true" />
</p>
<p class="execute-btn" @click="handleExecute">立即执行</p>
<p class="task-log">
<span>任务记录</span>
<p class="execute-btn" @click="test">立即执行</p>
<p class="alarm-title">任务记录</p>
<div class="task-log">
<ul>
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 执行中</li>
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 已完成</li>
<li> 2023-01-23 10:00:00 XXXXX机场执行任务 已完成</li>
<li v-for="(item, index) in recoedList" :key="index">
<span class="task-time">{{ item.time }}</span>
<span class="task-name">{{ item.name }}</span>
<span v-if="item.statusNum === 1" class="task-status on-fly">{{ item.status }}</span>
<span v-else class="task-status">{{ item.status }}</span>
</li>
</ul>
</p>
</div>
</div>
<p class="dividing-line" />
<div class="fire-verify">
<p class="alarm-title">火灾核实</p>
<!-- <n-input
v-model:value="value"
<n-input
v-model:value="warningDesc"
type="textarea"
placeholder="请输入火灾核实描述"
/> -->
<p class="verify-btns">
<span>忽略</span>
<span>已处理</span>
<span @click="ignore">忽略</span>
<span @click="confirm">已处理</span>
</p>
</div>
</div>

<div class="available-airports">
<p class="alarm-title">可用机场列表</p>
<div class="airport-params">
<p>
<span class="airport-name">机场1</span>
<span class="airport-find">发现隐患的机场</span>
</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>
</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 v-show="airportShow" class="available-airports">
<span class="close-content" @click="closeAirport">x</span>
<p class="alarm-title">可用机场列表
</p>
<div class="airport-list">
<div v-for="(item, index) in usableAirport" :key="index" class="airport-params">
<p>
<span class="airport-name">{{ item?.airName }}</span>
<span v-show="item.find" class="airport-find">发现隐患的机场</span>
</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>
</p>
<p class="uav-params" style="width: 252px">
<img src="@/assets/gis/images/measure.png">
<span style="width: 130px">{{ item.distance }}km</span>
<span style="width: 130px">机场距离火灾隐患点</span>
</p>
</div>
</div>
</div>
</template>
<script>

import { reactive, toRefs, watch } from 'vue'
import { EARLY_SOURCE } from '@/utils/dictionary.js'
import { getWarningRecord } from '@/api/dashboard/index.js'
import { EARLY_SOURCE, TASK_STATUS } from '@/utils/dictionary.js'
import { getWarningRecord, getWarningInfo, ignoreWarning, confirmWarning } from '@/api/dashboard/index.js'
// turf 用于简单的空间计算
import * as turf from '@turf/turf'
export default {
name: 'FireAlarm',
components: { },
@@ -93,28 +103,37 @@ export default {
data: {
type: Object,
default: () => { }
},
airport: {
type: Object,
default: () => { }
}
},
emits: ['start'],
setup(props, { emit }) {
const data = reactive({
airpotOptions: [
{
label: '机场1',
value: 'airport1'
},
{
label: '机场2',
value: 'airport2'
}
],
fireDetail: {}
airpotOptions: [],
airport: {},
fireDetail: {},
warningDesc: '',
flyHeight: 100,
usableAirport: [],
airportShow: false,
warningInfo: {},
airportSelect: '',
airValue: 0,
warningPic: null,
recoedList: [],
warningShow: false
})

watch(() => props.data, (value) => {
if (JSON.stringify(value) !== '{}') {
data.warningList = props.data
showDetail(data.warningList)
data.warningInfo = props.data
data.airport = props.airport
showDetail(data.warningInfo)
data.warningShow = true
closeAirport()
}
})

@@ -126,12 +145,99 @@ export default {
data.fireDetail.discoveryWay = item.label
}
})
data.fireDetail.time = value?.updateTime
data.fireDetail.time = value?.createTime

Promise.all([await getWarningInfo(value.id), await getWarningRecord({ warningId: value.id })])
.then(([info, record]) => {
data.warningPic = info?.data?.fileMarkerUrl
showUsableAirport(info)
showWarningRecord(record)
})
.catch(err => {
console.log(err)
})
}

// 预警记录列表
const showWarningRecord = (record) => {
data.recoedList.length = 0
var status = ''
var statusNum = 0
record?.data?.map((item) => {
TASK_STATUS?.forEach((val) => {
if (val.value === item.status) {
status = val.label
statusNum = item.status
}
})
data.recoedList.push({
time: item.createTime,
name: item.name,
status: status,
statusNum: statusNum
})
})
}

// 可用机场列表
const showUsableAirport = (info) => {
data.usableAirport.length = 0
data.airpotOptions.length = 0
const warningLngLat = turf.point([parseFloat(info?.data?.lng), parseFloat(info?.data?.lat)])
data.airport?.map((item) => {
var airportFind = false
if (parseInt(info?.data?.airportId) === item.id) {
airportFind = true
}
const airLngLat = turf.point([parseFloat(item.longitude), parseFloat(item.latitude)])
data.usableAirport.push({
id: item.id,
airName: item.name,
distance: turf.distance(warningLngLat, airLngLat).toFixed(2),
find: airportFind
})
data.airpotOptions.push({
value: item.id,
label: item.name
})
})
data.airValue = data.airpotOptions[0]?.value || null
}

const res = await getWarningRecord({
warningId: value.id
const checkAirport = () => {
data.airportShow = true
}

const closeAirport = () => {
data.airportShow = false
}

const closeWarning = () => {
closeAirport()
data.warningShow = false
}

const test = () => {
handleExecute()
}

// 忽略预警
const ignore = async() => {
const res = await ignoreWarning(data.warningInfo.id)
if (res.code === 0) {
closeWarning()
}
}

// 已处理
const confirm = async() => {
const res = await confirmWarning({
id: data.warningInfo.id,
checkResult: data.warningDesc
})
console.log(res)
if (res.code === 0) {
closeWarning()
}
}

const formatHeight = (value) => {
@@ -145,6 +251,12 @@ export default {
return {
...toRefs(data),
formatHeight,
checkAirport,
closeAirport,
test,
closeWarning,
ignore,
confirm,
handleExecute
}
}
@@ -154,7 +266,7 @@ export default {
<style lang="scss" scoped>
.fire-alarm {
position: absolute;
left: 1345px;
right: 20px;
top: 10px;
width: 407px;
height: 925px;
@@ -163,6 +275,18 @@ export default {
background: rgba(0, 0, 0, 1);
}

.close-content {
width: 34px;
height: 34px;
position: relative;
color: #fff;
font-size: 20px;
cursor: pointer;
float: right;
text-align: center;
line-height: 34px;
}

.alarm-title {
width: 200px;
height: 30px;
@@ -174,6 +298,18 @@ export default {
display: inline-block;
}

.pic-content {
width: 360px;
height: 195px;
position: relative;
left: 24px;
}

.warning-pic {
width: 360px;
height: 195px;
}

.alarm-detail {
width: 100%;
height: 30px;
@@ -181,7 +317,8 @@ export default {
width: 85px;
height: 30px;
line-height: 30px;
display: inline-block;
// display: inline-block;
float: left;
color: rgba(139, 139, 139, 1);
font-size: 14px;
text-align: right;
@@ -258,22 +395,50 @@ export default {
text-align: center;
margin-left: 30px;
cursor: pointer;
}

.task-log {
width: 100%;
height: 90px;
overflow: auto;
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
.task-time {
width: 150px;
height: 30px;
line-height: 30px;
color: #fff;
font-size: 12px;
text-align: center;
float: left;
}
.task-name {
width: 200px;
height: 30px;
display: inline-block;
line-height: 30px;
color: #fff;
font-size: 12px;
text-align: left;
}
.task-status {
width: 50px;
height: 30px;
display: inline-block;
line-height: 30px;
color: rgba(24, 144, 255, 1);
font-size: 12px;
text-align: left;
cursor: pointer;

.task-log {
width: 100%;
margin-top: 30px;
span {
width: 100%;
height: 30px;
display: inline-block;
line-height: 30px;
color: #fff;
font-size: 14px;
padding-left: 25px;
&.on-fly {
color: rgba(34, 211, 61, 1);
}

}
}

::v-deep(.fire-verify){
width: 100%;
@@ -310,8 +475,8 @@ export default {

.available-airports {
position: absolute;
left: 764px;
top: 91px;
right: 432px;
top: 350px;
width: 285px;
height: 449px;
opacity: 0.85;
@@ -319,6 +484,15 @@ export default {
background: rgba(0, 0, 0, 1);
}

::v-deep(.airport-list) {
height: 410px;
overflow: auto;
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
.airport-params {
width: 278px;
height: 191px;
@@ -365,9 +539,14 @@ export default {
height: 30px;
line-height: 30px;
text-align: center;
color: #fff;
font-size: 12px;
}
span:nth-child(2){
color: #fff;
}
span:nth-child(3){
color: rgba(171, 171, 171, 1);
}
}

</style>

+ 18
- 1
src/views/dashboard/components/OneMap.vue ファイルの表示

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

<FireAlarm :data="warningDetail" @start="handleExecute" />
<fire-alarm ref="Warning" :data="warningDetail" :airport="airportsAll" @start="handleExecute" />

<WarningDrawer v-model:visible="drawerShow" />

@@ -74,6 +74,7 @@ export default {
},
setup(props) {
const monitorVideo = ref()
const Warning = ref()
const data = reactive({
map: null,
// 机场数组
@@ -449,6 +450,8 @@ export default {
removeVectorLayer()
// 清除火灾预警中overlays
removeAllOverlays()
// 清除预警
removeWarning()

if (res.ops === 'query') {
removeProblemLayer()
@@ -548,6 +551,15 @@ export default {
data.warningLayers.length = 0
}

const removeWarning = () => {
removeWarningLayer()
Warning.value.closeWarning()
if (data.warningTimer !== null) {
clearInterval(data.warningTimer)
data.warningTimer = null
}
}

/**
* 添加问题图层
* @param {*} item
@@ -676,6 +688,10 @@ export default {

onBeforeUnmount(() => {
monitorVideo.value?.disposeVideo()
if (data.warningTimer !== null) {
clearInterval(data.warningTimer)
data.warningTimer = null
}
})

return {
@@ -693,6 +709,7 @@ export default {
removeProblemLayer,
hideProblemInfo,
getMaxZOverlay,
Warning,
handleExecute
}
}

+ 1
- 7
src/views/dashboard/index.vue ファイルの表示

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

<RemoateSensing
class="remoate-sensing-extrinsic"
@command="setCommandAndLog"
/>
</div>
</template>

@@ -15,10 +10,9 @@ import { useRouter } from 'vue-router'
import OneMap from './components/OneMap.vue'
import Extend from './components/Extend.vue'
import { ref, onMounted } from 'vue'
import RemoateSensing from './components/RemoateSensing.vue'
export default {
name: 'HomePage',
components: { OneMap, Extend, RemoateSensing },
components: { OneMap, Extend },
setup(props) {
const router = useRouter()
const extendRef = ref()

読み込み中…
キャンセル
保存