From a7729ab954c949489fd6888fdecdd361d617c39e Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Mon, 21 Apr 2025 08:33:38 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/drone/command-center-dashboard
---
src/components/UserOperate.vue | 2
src/assets/images/home/homeRight/leftTriangle.png | 0
src/views/Home/RSide.vue | 2
.env.test | 4
src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue | 738 +++++++++++++-------------
src/components/CurrentTaskDetails/CurrentTaskDetails.vue | 82 +-
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceEvent.vue | 5
src/components/DeviceJobDetails/JobRelatedEvents.vue | 40
src/components/CurrentTaskDetails/RealTimeMap.vue | 61 --
src/layout/Header.vue | 2
src/views/Home/HomeRight/EventOverview.vue | 6
src/assets/images/aiNowFly/event/hover.png | 0
src/components/DeviceJobDetails/DeviceJobDetails.vue | 7
src/hooks/useTaskWayline/useTaskWayline.js | 258 ++++++++-
src/const/drc.js | 9
.env | 2
src/api/payload.js | 4
src/components/CurrentTaskDetails/TaskDetailsLeft.vue | 16
src/styles/element-ui.scss | 90 ++
src/views/Home/AINowFly.vue | 14
src/assets/images/aiNowFly/event/startRecord.png | 0
src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue | 6
.env.development | 4
/dev/null | 81 --
src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue | 8
.env.production | 2
src/views/SignMachineNest/MachineRight/InspectionRaskList.vue | 141 ----
src/assets/images/aiNowFly/event/takePhoto.png | 0
src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue | 11
src/components/CurrentTaskDetails/TaskDetailsRight.vue | 29
30 files changed, 841 insertions(+), 783 deletions(-)
diff --git a/.env b/.env
index ef69cd4..b109a58 100644
--- a/.env
+++ b/.env
@@ -1,3 +1,5 @@
+#开发、测试、生产环境共用环境配置
+
VITE_APP_API = /api
#调试参数
VITE_APP_DEBUG_KEY = saber
diff --git a/.env.development b/.env.development
index c1b7c39..6a9bca3 100644
--- a/.env.development
+++ b/.env.development
@@ -11,5 +11,5 @@
# 航线文件地址
VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
-#系统运维
-VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage'
+#管理后台地址
+VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage/wel/index'
diff --git a/.env.production b/.env.production
index 4e96c25..1ea534b 100644
--- a/.env.production
+++ b/.env.production
@@ -6,4 +6,4 @@
# ws地址
VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com/drone-wss/api/v1/ws
# 管理后台地址
-VITE_APP_ADMIN_URL = 'https://aisky.org.cn/manage'
+VITE_APP_ADMIN_URL = 'https://aisky.org.cn/manage/wel/index'
diff --git a/.env.test b/.env.test
index 1518c99..39adca1 100644
--- a/.env.test
+++ b/.env.test
@@ -6,5 +6,5 @@
# 航线文件地址
VITE_APP_AIRLINE_URL = https://wrj.shuixiongit.com/minio/cloud-bucket
-#系统运维
-VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage'
+#管理后台地址
+VITE_APP_ADMIN_URL = 'https://wrj.shuixiongit.com/manage/wel/index'
diff --git a/src/api/payload.js b/src/api/payload.js
index 1d9d374..c85f540 100644
--- a/src/api/payload.js
+++ b/src/api/payload.js
@@ -59,9 +59,9 @@
})
}
-export function getLiveCapacityApi(workspace_id,params) {
+export function getLiveCapacityApi(params) {
return request({
- url:`/drone-device-core/manage/api/v1/live/capacity${workspace_id}`,
+ url:`/drone-device-core/manage/api/v1/live/capacity`,
method:'get',
params
})
diff --git a/src/assets/images/aiNowFly/stop.png b/src/assets/images/aiNowFly/event/hover.png
similarity index 100%
rename from src/assets/images/aiNowFly/stop.png
rename to src/assets/images/aiNowFly/event/hover.png
Binary files differ
diff --git a/src/assets/images/aiNowFly/picture-recording.png b/src/assets/images/aiNowFly/event/startRecord.png
similarity index 100%
rename from src/assets/images/aiNowFly/picture-recording.png
rename to src/assets/images/aiNowFly/event/startRecord.png
Binary files differ
diff --git a/src/assets/images/aiNowFly/photo.png b/src/assets/images/aiNowFly/event/takePhoto.png
similarity index 100%
rename from src/assets/images/aiNowFly/photo.png
rename to src/assets/images/aiNowFly/event/takePhoto.png
Binary files differ
diff --git a/src/assets/images/home/homeRight/leftTriangle.png b/src/assets/images/home/homeRight/leftTriangle.png
new file mode 100644
index 0000000..574073a
--- /dev/null
+++ b/src/assets/images/home/homeRight/leftTriangle.png
Binary files differ
diff --git a/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue b/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
index 37bc32a..51dd9dc 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/BaseControl.vue
@@ -31,22 +31,24 @@
import EventBus from '@/event-bus'
const isAutoControl = inject('isAutoControl')
+const isBackDock = inject('isBackDock')
const list3 = computed(() => [
- { name: '自动控制', svg: 'autoControl', style: { top: '-70%' }, active: isAutoControl.value, handle: autoControl },
+ { name: '自动控制', svg: 'autoControl', style: { top: '-70%' }, active: isAutoControl.value && !isBackDock.value, handle: autoControl },
+ //如果是返航, 继续任务 就是自动任务
+ //如果是取消返航, 继续任务 就是自动任务
{ name: '继续任务', svg: 'continueTask', style: { left: '70%' }, active: false, handle: autoControl },
{
name: '手动控制',
svg: 'manualControl',
style: { top: '70%' },
- active: !isAutoControl.value,
+ active: !isAutoControl.value && !isBackDock.value,
handle: manualControl,
},
- { name: '返航/取消返航', svg: 'turnBack', style: { left: '-70%' }, active: false, handle: turnBack },
+ { name: '返航/取消返航', svg: 'turnBack', style: { left: '-70%' }, active: isBackDock.value, handle: turnBack },
])
function autoControl() {
- isAutoControl.value = true
EventBus.emit('controlPanel-cancelControl')
}
@@ -55,7 +57,6 @@
}
function turnBack() {
- isAutoControl.value = true
EventBus.emit('controlPanel-returnOrCancelReturn')
}
</script>
diff --git a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
index 36da55e..cf4331e 100644
--- a/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
+++ b/src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -158,6 +158,7 @@
const droneSn = inject('droneSn')
const trueAltitude = inject('trueAltitude')
const client_id = inject('client_id')
+const isBackDock = inject('isBackDock')
const deviceTopicInfo = ref({
pubTopic: '',
@@ -324,9 +325,10 @@
function cancelControl() {
exitController({ client_id: client_id.value, dock_sn: dockSn.value })
.then(res => {
- flightController.value = false
deviceTopicInfo.value.subTopic = ''
deviceTopicInfo.value.pubTopic = ''
+ flightController.value = false
+ isAutoControl.value = true
ElMessage.success('退出飞行控制成功')
})
.catch(e => {})
@@ -358,13 +360,14 @@
})
}
-const isBackDock = ref(false)
+
// 返航
async function onBackDock() {
await returnHome(dockSn?.value)
ElMessage.success('返航操作成功')
isBackDock.value = true
+ isAutoControl.value = true
}
// 取消返航
@@ -372,6 +375,7 @@
await returnHomeCancel({ dock_sn: dockSn?.value, client_id: client_id.value })
ElMessage.success('取消返航成功')
isBackDock.value = false
+ isAutoControl.value = false
}
// 创建mqtt连接
diff --git a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
index 66c13cd..ea92bd8 100644
--- a/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
+++ b/src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -41,8 +41,6 @@
import { pxToRem } from '@/utils/rem'
import LiveVideo from '@/components/LiveVideo.vue'
import { liveStart } from '@/api/home/machineNest'
-import { getJobDetails } from '@/api/home/task'
-
import RealTimeMap from '@/components/CurrentTaskDetails/RealTimeMap.vue'
import ControlPanel from '@/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue'
import TaskDetailsHead from '@/components/CurrentTaskDetails/TaskDetailsHead.vue'
@@ -60,9 +58,8 @@
const isAutoControl = ref(true) //是否自动控制
const lineQuality = ref(1) //1流畅,2标清
const taskDetailsViewer = ref(null) //地图实例
-const deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
-const dockSn = computed(() => taskDetails?.value?.device_sns?.[0])
-const droneSn = computed(() => deviceOsdInfo?.value?.data?.sn)
+const dockSn = computed(() => taskDetails?.value?.device_sns?.[0]) //机巢sn
+const droneSn = computed(() => wsInfo.value?.device_osd?.data?.sn) //无人机sn
const trueAltitude = ref('') // 真实高度
const isAiLive = ref(false) // 是ai直播
const video_id = ref('') // 直播视频id
@@ -71,29 +68,16 @@
const currentLiveUrl = ref('') // 当前直播地址
const isTakeOff = ref(false) // 是在飞行中
const isMaxMap = ref(false) //是大地图
-const client_id = ref('') //是大地图
-
-// 获取机巢直播
-const getDeviceLiveUrl = async () => {
- const res = await liveStart(dockSn.value, 2)
- currentLiveUrl.value = res.data.data.rtcs_url
-}
-
-//获取相机能力
-async function getLiveCapacity() {
- const res = await getLiveCapacityApi(workspace_id.value,{ sn: dockSn.value})
-}
-const useTaskDetailsCallBack = () => {
- console.log(workspace_id.value,66666666)
- getDeviceLiveUrl()
-}
-
-let { taskDetails, workspace_id, getTaskDetails } = useTaskDetails(useTaskDetailsCallBack)
-let { wsInfo, removeWS } = useDroneWS(workspace_id) //ws信息,是一个ref对象
+const client_id = ref('') //mqtt id
+const hasIr = ref(false) //有红外能力
+let once = true //第一次触发
+const isBackDock = ref(false)
+let { taskDetails, workspace_id, getTaskDetails:initTaskDetails } = useTaskDetails(()=> getDeviceLiveUrl())
+let { wsInfo } = useDroneWS(workspace_id) //ws信息,是一个ref对象
provide('wsInfo', wsInfo)
+provide('isBackDock', isBackDock)
provide('workspace_id', workspace_id)
-provide('deviceOsdInfo', deviceOsdInfo)
provide('dockOsdInfo', wsInfo?.value?.dock_osd)
provide('dockSn', dockSn)
provide('droneSn', droneSn)
@@ -105,24 +89,33 @@
provide('isAiLive', isAiLive)
provide('video_id', video_id)
provide('client_id', client_id)
+provide('hasIr', hasIr)
-let once = true
-watch(deviceOsdInfo,()=>{
- if (once){
- // getLiveCapacity()
- once =false
- }
-})
+// 获取机巢直播
+const getDeviceLiveUrl = async () => {
+ const res = await liveStart(dockSn.value, 2)
+ currentLiveUrl.value = res.data.data.rtcs_url
+}
-watch(
- wsInfo,
- () => {
- // wsInfo 变化触发
- setCurrentLiveUrl()
- },
- { deep: true }
-)
+//获取是否有红外功能
+async function getLiveCapacity() {
+ if (!once) return
+ once = false
+ const res = await getLiveCapacityApi({ sn: droneSn.value })
+ res?.data?.data?.forEach(item => {
+ item?.cameras_list?.forEach(item1 => {
+ item1?.videos_list?.forEach(item2 => {
+ item2?.switch_video_types?.forEach(item3 => {
+ if (item3 === 'ir') {
+ hasIr.value = true
+ }
+ })
+ })
+ })
+ })
+}
+// set Ai直播
const getAiLiveUrl = async () => {
const res = await getLiveAiLinkApi({
original_stream_url: `${CURRENT_CONFIG.rtmpURL}${video_id.value.replace(/\//g, '-')}`,
@@ -146,13 +139,13 @@
// 无人机直播画质切换
const changeLineQuality = async () => {
- const res = await updateDroneQualityApi({ video_id: video_id.value, video_quality: lineQuality.value })
+ await updateDroneQualityApi({ video_id: video_id.value, video_quality: lineQuality.value })
ElMessage.success('切换画质成功')
}
// 设置当前直播地址
const setCurrentLiveUrl = async () => {
- const deviceInfo = deviceOsdInfo.value?.data?.host
+ const deviceInfo = wsInfo.value?.device_osd?.data?.host
if (!deviceInfo) return
const currentIsTakeOff = ![14, 0].includes(deviceInfo?.mode_code)
// 如果还是之前的状态,不切换
@@ -161,8 +154,11 @@
isTakeOff.value ? await getDroneLiveUrl() : await getDeviceLiveUrl()
}
+watch(() => wsInfo.value?.device_osd, getLiveCapacity)
+watch(wsInfo, setCurrentLiveUrl, { deep: true })
+
onMounted(() => {
- getTaskDetails(props?.id)
+ initTaskDetails(props?.id)
EventBus.on('CurrentTaskDetails-timeStop', changeLineQuality)
EventBus.on('CurrentTaskDetails-getAiLiveUrl', getAiLiveUrl)
EventBus.on('CurrentTaskDetails-getDroneLiveUrl', getDroneLiveUrl)
diff --git a/src/components/CurrentTaskDetails/RealTimeMap.vue b/src/components/CurrentTaskDetails/RealTimeMap.vue
index 207d811..4e25ebb 100644
--- a/src/components/CurrentTaskDetails/RealTimeMap.vue
+++ b/src/components/CurrentTaskDetails/RealTimeMap.vue
@@ -6,9 +6,9 @@
import AmapMercatorTilingScheme from '@/utils/cesium/AmapMercatorTilingScheme'
import { Cartesian3, Terrain, Viewer } from 'cesium'
import { addBlueFilter } from '@/utils/cesium/common'
-import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
-import aircraftGltf from '@/assets/gltf/aircraft.gltf'
import { useTaskWayline } from '@/hooks/useTaskWayline/useTaskWayline'
+
+const { init: initTaskWayline } = useTaskWayline()
const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
@@ -25,7 +25,7 @@
const taskDetailsViewer = inject('taskDetailsViewer')
const taskDetails = inject('taskDetails')
-const deviceOsdInfo = inject('deviceOsdInfo')
+const wsInfo = inject('wsInfo')
const initMap = () => {
taskDetailsViewer.value = new Viewer('currentTaskMap', {
@@ -55,60 +55,9 @@
taskDetailsViewer?.value.camera.setView({
destination: Cartesian3.fromDegrees(115.763819, 28.787374, 5000),
})
+
+ initTaskWayline(taskDetailsViewer.value, wsInfo, taskDetails)
}
-
-let viewInfoFrustum
-// 设置视椎
-const setCreateFrustum = () => {
- const host = deviceOsdInfo.value?.data?.host
- if (!host) return
- viewInfoFrustum?.clear()
- if ([14, 0].includes(host.mode_code)) return
- const attitude_head = 180 + host.attitude_head
- const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
- viewInfoFrustum = new CreateFrustum(taskDetailsViewer?.value, {
- position: {
- longitude: host.longitude,
- latitude: host.latitude,
- altitude: host.height,
- },
- width: 30,
- height: 30,
- fov: 20.0,
- near: 3.0,
- far: 250.0,
- roll: gimbal_pitch,
- pitch: 0,
- heading: attitude_head,
- })
-}
-
-function setAircraftGltf() {
- const host = deviceOsdInfo.value?.data?.host
- const aircraftEntity = taskDetailsViewer.value.entities.getById('aircraftGltf')
- const position = Cesium.Cartesian3.fromDegrees(host.longitude, host.latitude, host.height)
- if (aircraftEntity) {
- aircraftEntity.position = new Cesium.ConstantPositionProperty(position)
- return
- }
- taskDetailsViewer.value.entities.add({
- id: 'aircraftGltf',
- position,
- model: {
- uri: aircraftGltf, // 或 .glb
- scale: 1.0, // 缩放比例
- minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见)
- maximumScale: 128, // 最大缩放(可选)
- },
- })
-}
-
-watch(deviceOsdInfo, () => {
- setCreateFrustum()
- setAircraftGltf()
-})
-
-useTaskWayline(taskDetailsViewer, taskDetails)
const removeMap = () => {
taskDetailsViewer?.value.entities.removeAll()
diff --git a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
index f0745fb..336d9f1 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsLeft.vue
@@ -3,7 +3,7 @@
<div class="title">负载控制</div>
<div
class="singleCol"
- v-for="item in list1"
+ v-for="item in list1.filter(i => i.show)"
@click="cameraType(item)"
:key="item.key"
:class="{ active: item.key === cameraParams.camera_type }"
@@ -106,12 +106,14 @@
// 初始化喊话
let globalShout = null
const isRecording = ref(false)
-
-const list1 = ref([
- { name: '广角', key: 'wide' },
- { name: '变焦', key: 'zoom' },
- { name: '红外', key: 'ir' },
-])
+const hasIr = inject('hasIr')
+const list1 = computed(() => {
+ return [
+ { name: '广角', key: 'wide',show:true },
+ { name: '变焦', key: 'zoom', show: true },
+ { name: '红外', key: 'ir',show: hasIr.value },
+ ]
+})
const cameraParams = ref({
zoom_factor: 0,
camera_type: 'wide',
diff --git a/src/components/CurrentTaskDetails/TaskDetailsRight.vue b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
index 34a7ce1..47d2c31 100644
--- a/src/components/CurrentTaskDetails/TaskDetailsRight.vue
+++ b/src/components/CurrentTaskDetails/TaskDetailsRight.vue
@@ -7,7 +7,10 @@
<div class="taskInfo">
<div v-for="item in list" class="itemBox">
<div class="itemName">{{ item.name }}:</div>
- <div class="itemValue">{{ item.value }}</div>
+ <div class="itemValue" v-if="item.name !== '飞行事件'">{{ item.value }}</div>
+ <div class="flightEvents" v-else>
+ <img v-for="item in flightEvents" alt="" :src="item.img" :title="item.name"></img>
+ </div>
</div>
</div>
@@ -17,6 +20,7 @@
<script setup>
import droneImg from '@/assets/images/taskManagement/taskIntermediateContent/droneImg.png'
import BaseControl from '@/components/CurrentTaskDetails/ControlPanel/BaseControl.vue'
+import { droneEventList } from '@/const/drc'
const taskDetails = inject('taskDetails')
const workspace_id = inject('workspace_id')
@@ -32,6 +36,7 @@
{ name: '关联算法', value: '', field: 'ai_type_str' },
{ name: '任务描述', value: '', field: 'remark' },
])
+const flightEvents = ref([])
watch(
taskDetails,
@@ -41,6 +46,12 @@
if (item.name === '任务频次') {
const { rep_rule_type = '', rep_rule_val = '' } = taskDetails?.value || {}
item.value = rep_rule_type + ' -- ' + rep_rule_val
+ }
+ if (item.name === '飞行事件') {
+ const { action_modes = [] } = taskDetails?.value || {}
+ flightEvents.value = action_modes.flatMap(({ actionActuatorFunc }) =>
+ droneEventList.filter(({ value }) => actionActuatorFunc === value)
+ )
}
})
},
@@ -89,7 +100,7 @@
}
.taskInfo {
- width: 220px;
+ width: 230px;
height: 520px;
display: flex;
overflow: auto;
@@ -111,8 +122,18 @@
.itemValue {
font-weight: bold;
color: #ffffff;
- word-break: break-all; /* 强制在任意字符断行 */
- white-space: normal; /* 允许正常换行 */
+ word-break: break-all; /* 强制在任意字符断行 */
+ white-space: normal; /* 允许正常换行 */
+ }
+
+ .flightEvents{
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px 10px;
+ img {
+ width: 30px;
+ height: 30px;
+ }
}
}
}
diff --git a/src/components/DeviceJobDetails/DeviceJobDetails.vue b/src/components/DeviceJobDetails/DeviceJobDetails.vue
index 007edb7..0b219d6 100644
--- a/src/components/DeviceJobDetails/DeviceJobDetails.vue
+++ b/src/components/DeviceJobDetails/DeviceJobDetails.vue
@@ -69,14 +69,14 @@
import DeviceJobDetailsMap from './DeviceJobDetailsMap.vue'
const isShow = defineModel('show')
const infoList = ref([
- { name: '任务编号', value: '', field: 'job info num' },
+ { name: '任务编号', value: '', field: 'job_info_num' },
{ name: '任务所属机巢', value: '', field: 'device_names' },
{ name: '任务名称', value: '', field: 'name' },
{ name: '所属单位', value: '', field: 'dept_name' },
{ name: '任务类型', value: '', field: 'industry_type_str' },
{ name: '任务时间', value: '', field: 'begin_time' + ' - ' + 'end_time' },
{ name: '飞行事件', value: '', field: 'event_number' },
- { name: '任务频次', value: '', field: 'rep_rule_type' + ' - ' + 'rep_rule_val' },
+ { name: '任务频次', value: '', field: 'rep_rule_type rep_rule_val' },
{ name: '任务描述', value: '', field: 'remark' },
])
// 机巢状态
@@ -128,7 +128,8 @@
if (item.name === '任务时间') {
item.value = detailsData.value.begin_time.slice(0, 10) + '-' + detailsData.value.end_time.slice(0, 10)
} else if (item.name === '任务频次') {
- item.value ===undefined ? '' : detailsData.value.rep_rule_type + ' -- ' + detailsData.value.rep_rule_val
+ const { rep_rule_type = '', rep_rule_val = '' } = detailsData?.value || {}
+ item.value = rep_rule_type + ' -- ' + rep_rule_val
} else {
item.value = detailsData.value?.[item.field] || ''
}
diff --git a/src/components/DeviceJobDetails/JobRelatedEvents.vue b/src/components/DeviceJobDetails/JobRelatedEvents.vue
index f2bd341..980e4c3 100644
--- a/src/components/DeviceJobDetails/JobRelatedEvents.vue
+++ b/src/components/DeviceJobDetails/JobRelatedEvents.vue
@@ -2,7 +2,7 @@
<div class="machineTableDetailsTitle"><span>关联事件</span></div>
<div class="ztzf-table">
<el-table
- :row-class-name="tableRowClassName"
+ :row-class-name="tableRowClassName"
:data="list"
style="width: 100%"
:row-style="{ height: '38px', fontSize: '14px', 'text-align': 'center' }"
@@ -20,7 +20,6 @@
<div class="processing" v-if="scope.row.status === 3">处理中</div>
<div class="done" v-if="scope.row.status === 4">已完成</div>
<div class="ended" v-if="scope.row.status === 5">已完结</div>
-
</template>
</el-table-column>
<el-table-column label="操作" width="80">
@@ -31,7 +30,7 @@
</el-table>
</div>
<el-pagination
- class="ztzf-pagination"
+ class="ztzf-pagination"
background
:page-sizes="[10, 20, 30, 50]"
v-model:current-page="sizeParams.current"
@@ -49,7 +48,7 @@
const list = ref()
const params = ref({
- wayLineJodInfoId: null,
+ way_line_jod_info_id: null,
})
const sizeParams = ref({
current: 1,
@@ -58,18 +57,17 @@
const store = useStore()
const child_sn = computed(() => store.state.home.singleUavHome.child_sn)
const total = ref(10)
-
-const distribution = row => {
- ElMessage.warning('正在加急开发中...')
-}
const examine = row => {
- ElMessage.warning('正在加急开发中...')
+ const orderNumber = row.event_num
+ const adminUrl = import.meta.env.VITE_APP_ADMIN_URL
+ const targetPath = `/tickets/ticket?orderNumber=${orderNumber}`;
+ window.open(`${adminUrl}?redirect=${encodeURIComponent(targetPath)}`, '_blank');
}
const wayLineJodInfoId = inject('wayLineJodInfoId')
-
const getList = () => {
- params.value.wayLineJodInfoId = wayLineJodInfoId.value
+ params.value.way_line_jod_info_id = wayLineJodInfoId.value
+
getDeviceEventList(params.value, sizeParams.value).then(res => {
const resData = res?.data?.data || {}
list.value = resData.records
@@ -111,23 +109,23 @@
}
// 待处理
-.pending{
-color: #FF7411;
+.pending {
+ color: #ff7411;
}
// 待审核
-.reviewed{
-color: #8CFEA7;
+.reviewed {
+ color: #8cfea7;
}
// 处理中
-.processing{
-color: #FFC398;
+.processing {
+ color: #ffc398;
}
// 已完成
-.done{
-color: #AFD9FB;
+.done {
+ color: #afd9fb;
}
// 已完结
-.ended{
-color: #11C4FF;
+.ended {
+ color: #11c4ff;
}
</style>
diff --git a/src/components/UserOperate.vue b/src/components/UserOperate.vue
index 5f07fff..6cab918 100644
--- a/src/components/UserOperate.vue
+++ b/src/components/UserOperate.vue
@@ -1,6 +1,7 @@
<script setup>
import { fullscreenToggel } from '@/utils/util';
import { useStore } from 'vuex';
+import { ElMessage } from 'element-plus'
const router = useRouter();
const store = useStore();
const dropdownClick = val => {
@@ -20,6 +21,7 @@
}
const info = () =>{
+ ElMessage.warning('加急开发中...')
console.log('点击了个人信息');
}
</script>
diff --git a/src/const/drc.js b/src/const/drc.js
index 77cb05a..29c7a56 100644
--- a/src/const/drc.js
+++ b/src/const/drc.js
@@ -29,3 +29,12 @@
{ min: 315, max: 360, value: '北偏西' },
{ min: 360, max: 360, value: '正北' }
];
+
+import hoverImg from '@/assets/images/aiNowFly/event/hover.png'
+import startRecordImg from '@/assets/images/aiNowFly/event/startRecord.png'
+import takePhotoImg from '@/assets/images/aiNowFly/event/takePhoto.png'
+export const droneEventList = [
+ {name:'开始录像',value:'startRecord',img:startRecordImg},
+ {name:'悬停',value:'hover',img:hoverImg},
+ {name:'拍照',value:'takePhoto',img:takePhotoImg},
+]
diff --git a/src/hooks/useTaskViewInfo/useTaskViewInfo.js b/src/hooks/useTaskViewInfo/useTaskViewInfo.js
deleted file mode 100644
index 54d4e18..0000000
--- a/src/hooks/useTaskViewInfo/useTaskViewInfo.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import * as Cesium from 'cesium'
-import aircraftGltf from '@/assets/gltf/aircraft.gltf'
-import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
-
-export function useTaskViewInfo (viewer, wsInfo, removeEntitys) {
- const newViewer = unref(viewer)
-
- let viewInfoFrustum
- // 设置视椎
- const setCreateFrustum = (host) => {
- if (!host) return
- viewInfoFrustum?.clear()
-
- const attitude_head = 180 + host.attitude_head
- const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
-
- viewInfoFrustum = new CreateFrustum(newViewer, {
- position: {
- longitude: host.longitude,
- latitude: host.latitude,
- altitude: host.height,
- },
- width: 30,
- height: 30,
- fov: 20.0,
- near: 3.0,
- far: 250.0,
- roll: gimbal_pitch,
- pitch: 0,
- heading: attitude_head,
- })
- }
-
- function setAircraftGltf () {
- const host = deviceOsdInfo.value?.data?.host
- const aircraftEntity = newViewer.entities.getById('aircraftGltf')
- const position = Cesium.Cartesian3.fromDegrees(host.longitude, host.latitude, host.height)
- if (aircraftEntity) {
- aircraftEntity.position = new Cesium.ConstantPositionProperty(position)
- return
- }
-
- newViewer.entities.add({
- id: 'aircraftGltf',
- position,
- model: {
- uri: aircraftGltf, // 或 .glb
- scale: 1.0, // 缩放比例
- minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见)
- maximumScale: 128, // 最大缩放(可选)
- },
- })
- }
-
- // 视椎加载处理
- const deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
-
- watch(deviceOsdInfo, () => {
- const host = deviceOsdInfo.value?.data?.host
-
- if ([14, 0].includes(host.mode_code)) {
- mapEntityRemove()
- return
- }
-
- setCreateFrustum(host)
- setAircraftGltf()
- })
-
- const mapEntityRemove = () => {
- viewInfoFrustum?.clear()
-
- newViewer.entities.removeById('aircraftGltf')
-
- removeEntitys && removeEntitys()
- }
-
- onUnmounted(() => {
- mapEntityRemove()
- })
-}
\ No newline at end of file
diff --git a/src/hooks/useTaskWayline/useTaskWayline.js b/src/hooks/useTaskWayline/useTaskWayline.js
index 200de38..bd9214d 100644
--- a/src/hooks/useTaskWayline/useTaskWayline.js
+++ b/src/hooks/useTaskWayline/useTaskWayline.js
@@ -2,11 +2,11 @@
* @Author: shuishen 1109946754@qq.com
* @Date: 2025-04-19 14:24:34
* @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2025-04-19 15:23:57
+ * @LastEditTime: 2025-04-20 17:53:08
* @FilePath: \command-center-dashboard\src\hooks\useTaskWayline\useTaskWayline.js
- * @Description:
- *
- * Copyright (c) 2025 by shuishen, All Rights Reserved.
+ * @Description:
+ *
+ * Copyright (c) 2025 by shuishen, All Rights Reserved.
*/
import lineImg from '@/assets/images/arrow-right-blue.png'
import rwqfdImg from '@/assets/images/signMachineNest/rwqfd.png'
@@ -18,9 +18,24 @@
import * as Cesium from 'cesium'
import { Cartesian3 } from 'cesium'
+import aircraftGltf from '@/assets/gltf/aircraft.gltf'
+import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
-export function useTaskWayline (viewer, taskDetails) {
- const newViewer = unref(viewer)
+export function useTaskWayline () {
+ let viewer = null
+ let deviceOsdInfo = null
+ let flighttaskProgressInfo = null
+
+ // watch
+ let taskWatch = null
+ let flighttaskWatch = null
+ let deviceWatch = null
+
+ // 航线位置
+ let currentWaylinePostions = []
+ // 当前航点 下标
+ let currentWaypointIndex = null
+ let droneSpeedArr = []
// 解析kmz文件
const parsingFiles = async url => {
@@ -29,20 +44,23 @@
const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
const waylinesXMLObj = removeTextKey(waylinesXMLJSON.Folder)
if (!waylinesXMLObj.Placemark.length) return
- const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
- flyVisual(allPoint, newViewer)
+ // const allPoint = waylinesXMLObj.Placemark.map(item => item.Point.coordinates.split(','))
+ // flyVisual(allPoint, viewer)
drawWayline(waylinesXMLObj)
}
const drawWayline = lineObj => {
- const positions = lineObj.Placemark.map(item => {
+ currentWaylinePostions = lineObj.Placemark.map(item => {
const [lon, lat] = item.Point.coordinates.split(',')
return Cartesian3.fromDegrees(Number(lon), Number(lat))
})
+
+ removeEntitys()
+
// 起点
- newViewer.entities.add({
+ viewer.entities.add({
id: 'drone-job-wayline-start',
- position: positions[0],
+ position: currentWaylinePostions[0],
billboard: {
image: new Cesium.ConstantProperty(rwqfdImg),
width: 70,
@@ -51,9 +69,9 @@
})
// 终点
- newViewer.entities.add({
+ viewer.entities.add({
id: 'drone-job-wayline-end',
- position: positions[positions.length - 1],
+ position: currentWaylinePostions[currentWaylinePostions.length - 1],
billboard: {
image: new Cesium.ConstantProperty(endPointImg),
width: 30,
@@ -63,11 +81,11 @@
})
// 路径线
- newViewer.entities.add({
+ let polylineEntity = viewer.entities.add({
id: 'drone-job-wayline-polyline',
polyline: {
width: 4,
- positions: positions,
+ positions: currentWaylinePostions,
material: new ImageTrailMaterial({
color: { alpha: 1, blue: 1, green: 1, red: 1 },
speed: 20,
@@ -77,27 +95,209 @@
clampToGround: false,
},
})
- }
- watch(taskDetails, () => {
- if (taskDetails.value?.way_lines?.length) {
- parsingFiles(taskDetails.value.way_lines[0].url)
- }
- }, { immediate: true })
-
- const removeEntitys = () => {
- const entitiesIDs = newViewer?.entities.values.map(i => i.id)
-
- entitiesIDs.forEach(item => {
- item.includes('drone-job-wayline-') && newViewer?.entities.removeById(item)
+ viewer.flyTo(polylineEntity, {
+ offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-60), 0),
+ duration: 0.5,
})
}
+ let viewInfoFrustum
+ // 设置视椎
+ const setCreateFrustum = (host) => {
+ if (!host) return
+ viewInfoFrustum?.clear()
+
+ const attitude_head = 180 + host?.attitude_head
+ const gimbal_pitch = 90 - Number(host?.payloads[0]?.gimbal_pitch) || 0
+
+ viewInfoFrustum = new CreateFrustum(viewer, {
+ position: {
+ longitude: host?.longitude,
+ latitude: host?.latitude,
+ altitude: host?.height,
+ },
+ width: 30,
+ height: 30,
+ fov: 20.0,
+ near: 3.0,
+ far: 250.0,
+ roll: gimbal_pitch,
+ pitch: 0,
+ heading: attitude_head,
+ })
+ }
+
+ function setAircraftGltf () {
+ const host = deviceOsdInfo.value?.data?.host
+
+ const aircraftEntity = viewer?.entities.getById('aircraftGltf')
+ const position = Cesium.Cartesian3.fromDegrees(host?.longitude, host?.latitude, host?.height)
+
+ if (aircraftEntity) {
+ aircraftEntity.position = new Cesium.ConstantPositionProperty(position)
+
+ const homeDistance = Math.floor(host?.home_distance) || 0
+
+ // 距离下一个航点
+ const nextPoint = currentWaylinePostions[currentWaypointIndex]
+
+ if (!nextPoint) {
+ aircraftEntity.label = {}
+ return
+ }
+
+ const devicePosition = Cesium.Cartesian3.fromDegrees(
+ Number(host.longitude),
+ Number(host.latitude),
+ 0,
+ )
+
+ // 距离下个点位的距离
+ let distance = Cesium.Cartesian3.distance(
+ devicePosition,
+ nextPoint,
+ )
+
+ // 本次航线平面里程
+ let totalDistance = 0
+ currentWaylinePostions.map((cartesian3, index) => {
+ // 两点之间的距离
+ let deviceCurPosition = null
+ if (index === 0) {
+ deviceCurPosition = devicePosition
+ } else {
+ deviceCurPosition = currentWaylinePostions[index - 1]
+ }
+
+ let distance = Cesium.Cartesian3.distance(
+ deviceCurPosition,
+ cartesian3,
+ )
+ totalDistance += distance
+ return Math.round(distance)
+ })
+
+ // 速度
+ let horizontalSpeed = host.horizontal_speed || 0
+ if (
+ !droneSpeedArr.includes(horizontalSpeed) &&
+ horizontalSpeed > 1
+ ) {
+ droneSpeedArr.push(horizontalSpeed)
+ }
+ if (horizontalSpeed < 5) {
+ horizontalSpeed = 10
+ }
+
+ // 预计到达下一个航点时间
+ let arrivalTime = distance / horizontalSpeed
+ if (arrivalTime === Infinity || isNaN(arrivalTime)) {
+ arrivalTime = 0
+ }
+ if (arrivalTime > 60) {
+ const minute = Math.floor(arrivalTime / 60)
+ const second = Math.round(arrivalTime % 60)
+ arrivalTime = `${minute}m${second}s`
+ } else {
+ arrivalTime = Math.round(arrivalTime) + 's'
+ }
+
+ aircraftEntity.label = new Cesium.LabelGraphics({
+ text: `距离机场水平距离:${homeDistance}m\n距离下一个航点:${Math.round(distance)}m\n预计到达下一航点时间:${arrivalTime}\n本次航线平面里程:${Math.round(totalDistance)}m`,
+ font: '13px monospace',
+ showBackground: true,
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ pixelOffset: new Cesium.Cartesian2(0, -40),
+ show: true,
+ })
+
+ return
+ }
+
+ viewer?.entities.add({
+ id: 'aircraftGltf',
+ position,
+ label: {},
+ model: {
+ uri: aircraftGltf, // 或 .glb
+ scale: 1.0, // 缩放比例
+ minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见)
+ maximumScale: 128, // 最大缩放(可选)
+ },
+ })
+ }
+
+ const mapEntityRemove = () => {
+ viewInfoFrustum?.clear()
+
+ viewer?.entities.removeById('aircraftGltf')
+ }
+
+ const removeEntitys = () => {
+ const entitiesIDs = viewer?.entities.values.map(i => i.id)
+
+ Array.isArray(entitiesIDs) && entitiesIDs.forEach(item => {
+ item.includes('drone-job-wayline-') && viewer?.entities.removeById(item)
+ })
+ }
+
+ const removeWatchs = () => {
+ taskWatch?.()
+ flighttaskWatch?.()
+ deviceWatch?.()
+ }
+
+ const init = (v, wsInfo, taskDetails) => {
+ viewer = v
+ deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
+ flighttaskProgressInfo = computed(() => wsInfo.value?.flighttask_progress)
+
+ removeWatchs()
+
+ taskWatch = watch(taskDetails,
+ () => {
+ if (taskDetails.value?.way_lines?.length) {
+ parsingFiles(taskDetails.value.way_lines[0].url)
+ }
+ },
+ { immediate: true }
+ )
+
+ flighttaskWatch = watch(flighttaskProgressInfo, async () => {
+ const output = flighttaskProgressInfo.value?.data?.output
+
+ currentWaypointIndex = output.ext['current_waypoint_index']
+ })
+
+ deviceWatch = watch(deviceOsdInfo, () => {
+ const host = deviceOsdInfo.value?.data?.host
+
+ if (!host) return
+
+ if ([14, 0].includes(host?.mode_code)) {
+ mapEntityRemove()
+ return
+ }
+
+ setCreateFrustum(host)
+ setAircraftGltf()
+ }
+ )
+ }
+
onBeforeUnmount(() => {
+ mapEntityRemove()
removeEntitys()
+
+ removeWatchs()
})
return {
- removeEntitys
+ init,
+ removeEntitys,
+ mapEntityRemove,
}
-}
\ No newline at end of file
+}
diff --git a/src/layout/Header.vue b/src/layout/Header.vue
index 8bdf2ca..fad0241 100644
--- a/src/layout/Header.vue
+++ b/src/layout/Header.vue
@@ -52,7 +52,7 @@
const handleClick = ({ path, name }) => {
if (['系统运维'].includes(name)) {
- window.open(import.meta.env.VITE_APP_ADMIN_URL + '?token=' + localStorage.getItem(ELocalStorageKey.Token), '_blank');
+ window.open(import.meta.env.VITE_APP_ADMIN_URL, '_blank');
return;
}
if (!['首页', '任务管理'].includes(name)) return ElMessage.warning('正在加急开发中...');
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index 5668e7c..5f68843 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -245,7 +245,6 @@
border: 1px solid !important;
border-radius: 0px 0px 8px 8px;
border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
- /* 修改箭头样式 */
.el-popper__arrow {
&::before {
background: #0d3556 !important;
@@ -253,23 +252,23 @@
box-sizing: border-box;
}
}
- /* 修改头部背景色 */
+
.custom-date-picker .el-picker-panel__header {
background: linear-gradient(180deg, rgba(13, 53, 86, 0.85) 0%, rgba(1, 35, 80, 0.85) 100%) !important;
color: #fff !important;
}
.el-date-table {
th {
- color: #fff !important; /* 星期标题颜色 */
+ color: #fff !important;
}
}
- /* 修改日期单元格悬停/选中状态 */
+
.custom-date-picker .el-date-table td:hover,
.custom-date-picker .el-date-table td.current:not(.disabled) {
background: rgba(60, 121, 202) !important;
color: white !important;
}
- // 头部按钮
+
.el-date-table td.start-date span,
.el-date-table td.start-date span,
.el-date-table td.end-date span {
@@ -337,33 +336,33 @@
overflow-x: hidden !important;
margin-right: 0 !important;
}
- /* 箭头样式 */
+
.el-popper__arrow::before {
background: #0d3556 !important;
border: 1px solid #0d3556 !important;
}
.el-select {
--el-select-border-color-hover: rgb(0, 162, 255) !important;
- /* // 修改下拉框hover的默认样式 */
+
}
.el-input {
--el-border-color: rgb(0, 162, 255);
- /* // 修改下拉框的边框 */
+
}
.el-select .el-input__wrapper {
background-color: #012350 !important;
- /* // 外层下拉框背景 */
+
}
.el-input__wrapper {
- --el-input-text-color: #012350 !important; /* // 修改外层下拉框的颜色 */
+ --el-input-text-color: #012350 !important;
}
.el-select__popper.el-popper {
border: rgba(0, 27, 63) !important;
- /* // 修改内部下拉框的边框颜色 */
+
}
.el-select-dropdown__wrap {
@@ -371,11 +370,11 @@
border-radius: 0px 0px 8px 8px;
border: 1px solid;
border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1;
- /* // 下拉框背景色 */
+
}
.el-select-dropdown__item {
- background: rgba(0, 27, 63) !important; /* // 下拉框选项的颜色 */
+ background: #012350 !important;
}
.el-select-dropdown__item {
@@ -447,11 +446,11 @@
text-transform: none;
background: linear-gradient(90deg, #fbfdff 0%, #86d4ff 100%);
margin-left: 16px;
- -webkit-background-clip: text; /* 背景被裁剪成文字的前景色 */
- -webkit-text-fill-color: transparent; /* 文字填充颜色变透明 */
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
}
.el-dialog .el-dialog__header {
- /* margin: 0px !important; */
+
padding: 0px !important;
padding-left: 0px !important;
}
@@ -459,4 +458,63 @@
background: #13c6ff !important;
}
}
+/* 时间选择器下拉面板 */
+.custom-time-picker {
+ /* 整体背景和边框 */
+background: linear-gradient( 180deg, rgba(13,53,86,0.85) 0%, rgba(1,35,80,0.85) 100%) !important;
+border-radius: 0px 0px 8px 8px;
+border: 1px solid !important;
+border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1 !important;
+ /* 修改箭头样式 */
+ .el-popper__arrow::before {
+ background: #0D3556 !important;
+ border: 1px solid #479DFF !important;
+ }
+
+ /* 时间面板头部 */
+ .el-time-panel__header {
+ background: #012350 !important;
+ color: #FFFFFF !important;
+ border-bottom: 1px solid rgba(71, 157, 255, 0.3) !important;
+ }
+
+ /* 时间选择区域 */
+ .el-time-panel__content {
+ background: #012350 !important;
+
+ /* 时间数字项 */
+ .el-time-spinner__item {
+ color: #E6E6E6 !important;
+
+ &:hover {
+ background: rgba(71, 157, 255, 0.3) !important;
+ }
+
+ &.active {
+ color: #479DFF !important;
+ font-weight: bold;
+ }
+ }
+ }
+
+
+ .el-time-panel__footer {
+ background: #012350 !important;
+ border-top: 1px solid rgba(71, 157, 255, 0.3) !important;
+
+ .el-button {
+ color: #fff !important;
+ &:hover {
+ color: #479DFF !important;
+ }
+ }
+
+ .el-time-panel__btn.cancel {
+ color: #fff !important;
+ &:hover {
+ color: #fff !important;
+ }
+ }
+ }
+}
diff --git a/src/views/Home/AINowFly.vue b/src/views/Home/AINowFly.vue
index dbad17b..f56f39e 100644
--- a/src/views/Home/AINowFly.vue
+++ b/src/views/Home/AINowFly.vue
@@ -16,14 +16,14 @@
<!-- todo-->
<el-form-item label="飞行事件">
<div class="event">
- <img src="@/assets/images/aiNowFly/picture-recording.png" alt="">
+ <img src="../../assets/images/aiNowFly/event/startRecord.png" alt="">
<div class="img-close" v-show="isPhoto">
<img @click="isPhoto=false" class="close" src="@/assets/images/aiNowFly/close.png" alt="">
- <img src="@/assets/images/aiNowFly/photo.png" alt="">
+ <img src="../../assets/images/aiNowFly/event/takePhoto.png" alt="">
</div>
<div class="img-close" v-show="isStop">
<img @click="isStop=false" class="close" src="@/assets/images/aiNowFly/close.png" alt="">
- <img src="@/assets/images/aiNowFly/stop.png" alt="">
+ <img src="../../assets/images/aiNowFly/event/hover.png" alt="">
</div>
<div class="add-event" @click="isShowEvent = !isShowEvent">+
<div class="event-select" v-show="isShowEvent">
@@ -159,7 +159,7 @@
label: {
text: `预计${item.minute}分钟`,
font: 'bold 16px Source Han Sans CN', // 加粗并增大字号
- // fillColor: new Cesium.Color(27/255, 179/255, 255/255, 1.0),
+ // fillColor: new Cesium.Color(27/255, 179/255, 255/255, 1.0),
// fillColor: Cesium.Color.WHITE,
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
// verticalOrigin: Cesium.VerticalOrigin.CENTER,
@@ -354,12 +354,12 @@
:deep(.el-select__wrapper) {
background-color: #021740;
box-shadow: 0 0 0 1px #026AD6;
-
+
&.is-focus {
box-shadow: 0 0 0 1px #026AD6;
}
}
-
+
:deep(.el-input__wrapper.is-disabled) {
background-color: #021740;
box-shadow: 0 0 0 1px #026AD6;
@@ -440,7 +440,7 @@
white-space: nowrap;
}
}
-
+
.btn-submit {
cursor: pointer;
margin-left: 88px;
diff --git a/src/views/Home/HomeRight/EventOverview.vue b/src/views/Home/HomeRight/EventOverview.vue
index d87301b..7f5f1c5 100644
--- a/src/views/Home/HomeRight/EventOverview.vue
+++ b/src/views/Home/HomeRight/EventOverview.vue
@@ -40,7 +40,7 @@
<img class="completion-left-img" :src="completionLeft" alt="" />
<div class="completion-text">事件类型完成率情况</div>
<div class="completion-separator"></div>
- <img class="completion-left-img" :src="completionLeft" alt="" />
+ <img class="completion-left-img" :src="leftTriangle" alt="" />
</div>
<div class="chart" ref="echartsRef"></div>
@@ -56,6 +56,7 @@
import overviewImg5 from '@/assets/images/home/homeRight/overview5.png'
import overviewImg6 from '@/assets/images/home/homeRight/overview6.png'
import completionLeft from '@/assets/images/home/homeRight/completionLeft.png'
+import leftTriangle from '@/assets/images/home/homeRight/leftTriangle.png'
import * as echarts from 'echarts'
import CommonDateTime from '@/components/CommonDateTime.vue'
import VSelectLoad from '@/directive/selectLoad'
@@ -153,6 +154,9 @@
width: 2, // 线条宽度
type: 'solid', // 线条类型
},
+ tooltip: {
+ valueFormatter: (value) => value + '%'
+ },
symbol: 'circle', // 数据点符号
symbolSize: 6, // 数据点符号大小
emphasis: {
diff --git a/src/views/Home/RSide.vue b/src/views/Home/RSide.vue
index 7e41a56..98c980d 100644
--- a/src/views/Home/RSide.vue
+++ b/src/views/Home/RSide.vue
@@ -40,6 +40,7 @@
import tc from '@/assets/images/rSide/tc.png'
import tc1 from '@/assets/images/rSide/tc1.png'
import cesiumOperation from '@/utils/cesium-tsa'
+import { ElMessage } from 'element-plus'
let logIndex = ref(3)
const enterHover = value => {
@@ -61,6 +62,7 @@
activeIndex.value = activeIndex.value === 1 ? null : value
}
if (value === 2) {
+ ElMessage.warning('加急开发中...')
activeIndex.value = activeIndex.value === 2 ? null : value
}
}
diff --git a/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue b/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
index f9f9890..d2ff6e6 100644
--- a/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
+++ b/src/views/SignMachineNest/MachineLeft/InspectionRaskDetails.vue
@@ -109,7 +109,7 @@
},
],
}
-
+import _ from 'lodash'
// chart.setOption(option);
const pieOption = {
@@ -138,7 +138,7 @@
tarValue = data[i].value
}
}
- let percentage = ((tarValue / total) * 100).toFixed(1)
+ let percentage = total ? _.round(((tarValue / total) * 100),1) : 0
return `${name} ${percentage}%`
},
},
@@ -167,7 +167,7 @@
{ value: 0, name: '处理中', itemStyle: { color: '#FFC398' } },
{ value: 0, name: '已完成', itemStyle: { color: '#AFD9FB' } },
// { value: 0, name: '待分拨', itemStyle: { color: '#E9C81A' } },
-
+
{ value: 0, name: '已完结', itemStyle: { color: '#11C4FF' } },
],
},
diff --git a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
index 895f350..1b87b17 100644
--- a/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
+++ b/src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
@@ -24,7 +24,6 @@
:infinite-scroll-disabled="busy"
infinite-scroll-immediate="true"
>
- >
<div class="item" v-for="(item, index) in tableList">
<div class="left" @click="taskClick(item)">
<div class="left-t">
@@ -78,7 +77,6 @@
import { useStore } from 'vuex'
import { useTaskWayline } from '@/hooks/useTaskWayline/useTaskWayline'
import { useTaskDetails } from '@/hooks/useTaskDetails/useTaskDetails'
-import { useTaskViewInfo } from '@/hooks/useTaskViewInfo/useTaskViewInfo'
import { useDroneWS } from '@/hooks/useDroneWS'
let viewer = null
@@ -211,142 +209,21 @@
}
}
+watch([() => tabIndex.value, () => tableList.value], async ([newTabIndex, newTableList]) => {
+ if (newTabIndex == 1 && newTableList.length > 0) {
+ await getTaskDetails(newTableList[0].wayline_job_info_id)
+ }
+})
+
+const { init: initTaskWayline, removeEntitys } = useTaskWayline()
+
onMounted(async () => {
viewer = window.$viewer
await getJobList()
- // tableList.value = [
- // {
- // id: 11563,
- // status: 5,
- // begin_time: '2025/04/19 05:46:25',
- // end_time: '2025/04/19 05:46:25',
- // create_time: '2025-04-19T05:46:36.032+00:00',
- // name: '智引即飞202504191252',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 340,
- // job_id: '484a7846-60e0-4ec3-b9fb-272a055c6938',
- // },
- // {
- // id: 11559,
- // status: 5,
- // begin_time: '2025/04/19 05:39:42',
- // end_time: '2025/04/19 05:39:42',
- // create_time: '2025-04-19T05:39:52.022+00:00',
- // name: '智引即飞202504191252',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 340,
- // job_id: 'b8c58bfb-4352-47c5-ba33-242eec8df188',
- // },
- // {
- // id: 11558,
- // status: 3,
- // begin_time: '2025/04/19 05:39:17',
- // end_time: '2025/04/19 05:39:17',
- // create_time: '2025-04-19T05:39:27.407+00:00',
- // name: '智引即飞202504191252',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 340,
- // job_id: '839773ce-bd46-4947-a2ef-d859eaea82f6',
- // },
- // {
- // id: 11557,
- // status: 5,
- // begin_time: '2025/04/19 04:52:04',
- // end_time: '2025/04/19 04:52:04',
- // create_time: '2025-04-19T04:52:14.503+00:00',
- // name: '智引即飞202504191252',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 340,
- // job_id: '58366fd4-8361-456f-8ad9-3b881f933620',
- // },
- // {
- // id: 11556,
- // status: 5,
- // begin_time: '2025/04/19 03:45:06',
- // end_time: '2025/04/19 03:45:06',
- // create_time: '2025-04-19T03:45:16.522+00:00',
- // name: '智引即飞202504191145',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 338,
- // job_id: '39c60fb8-e5c4-4474-912a-c3af3f1b9054',
- // },
- // {
- // id: 11555,
- // status: 5,
- // begin_time: '2025/04/19 03:27:55',
- // end_time: '2025/04/19 03:27:55',
- // create_time: '2025-04-19T03:28:05.196+00:00',
- // name: '智引即飞202504191127',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 336,
- // job_id: '78c42532-45e4-4a01-b698-69bca19286ff',
- // },
- // {
- // id: 11554,
- // status: 5,
- // begin_time: '2025/04/19 02:58:53',
- // end_time: '2025/04/19 02:58:53',
- // create_time: '2025-04-19T02:59:03.602+00:00',
- // name: '智引即飞202504191058',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 335,
- // job_id: 'd3b25edc-ec23-4ad6-800a-0f659a72bff3',
- // },
- // {
- // id: 11553,
- // status: 5,
- // begin_time: '2025/04/19 02:52:21',
- // end_time: '2025/04/19 02:52:21',
- // create_time: '2025-04-19T02:52:31.415+00:00',
- // name: '智引即飞202504191052',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 334,
- // job_id: 'e27090f1-e740-4ae4-8d4d-301354eb0bbc',
- // },
- // {
- // id: 11548,
- // status: 5,
- // begin_time: '2025/04/19 02:23:06',
- // end_time: '2025/04/19 02:23:06',
- // create_time: '2025-04-19T02:23:16.151+00:00',
- // name: '智引即飞202504191023',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 332,
- // job_id: '9e1f7283-fe34-4cfd-b468-cd2b34a96d34',
- // },
- // {
- // id: 11547,
- // status: 3,
- // begin_time: '2025/04/19 02:18:24',
- // end_time: '2025/04/19 02:18:24',
- // create_time: '2025-04-19T02:18:34.590+00:00',
- // name: '智引即飞202504191018',
- // event_number: 0,
- // dock_sn: '7CTDLCR00BQBM2',
- // wayline_job_info_id: 331,
- // job_id: '7aa5222c-2f8b-401e-b6ba-d6a550398829',
- // },
- // ]
-
- if (tableList.value.length > 0) {
- await getTaskDetails(tableList.value[0].wayline_job_info_id)
- }
+ initTaskWayline(viewer, wsInfo, taskDetails)
})
-
-const { removeEntitys } = useTaskWayline(viewer || window.$viewer, taskDetails)
-
-useTaskViewInfo(viewer || window.$viewer, wsInfo, removeEntitys)
</script>
<style lang="scss" scoped>
diff --git a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue
index 3f40360..ad8534a 100644
--- a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue
@@ -1,393 +1,403 @@
<!-- 机巢状态 -->
<template>
- <CommonTitle title="机巢状态" @details="detailsFun" />
- <div :style="{ marginLeft: pxToRem(14) }">
- <div class="machine-status">
- <div class="info">
- <img src="../../../../assets/images/signMachineNest/machineRight/wrj.png" alt="">
- <div class="info-right">
- <!-- <div class="name">{{ osdVisible?.callsign || '--' }}</div> -->
- <div class="name">{{ osdVisible?.nickname || '--' }}</div>
- <div class="wz">
- <span class="left">当前位置:</span>
- <span class="right">{{ detailInfo.longitude }},{{ detailInfo.latitude }}</span>
- </div>
- <div class="close-wb">
- <div class="close" :class="AircraftStatus == undefined ? '' : 'other'">
- {{ AircraftStatus == undefined ? '舱内关机' : AircraftStatus }}
- </div>
- <!-- <div class="wb">需要维保</div> -->
- </div>
- </div>
- </div>
- <div class="status">
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/height.png" alt="">
- <span class="text">实时真高</span>
- </div>
- <div class="text-data">{{ detailInfo.height || '--' }}<span class="text">米</span></div>
- </div>
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/speed.png" alt="">
- <span class="text">飞行速度</span>
- </div>
- <div class="text-data">{{ detailInfo.horizontal_speed }}<span class="text">米/秒</span></div>
- </div>
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/signal.png" alt="">
- <span class="text">信号强度</span>
- </div>
- <div class="text-data">{{ detailInfo.quality }}</div>
- </div>
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/electricity.png" alt="">
- <span class="text">电池电量</span>
- </div>
- <div v-if="drone_charge_state.capacity_percent != 0" class="text-data">
- {{ drone_charge_state.capacity_percent }}<span class="text">%</span>
- </div>
- <div v-else class="text-data">{{ detailInfo.capacity_percent }}<span class="text">%</span></div>
- </div>
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/distance.png" alt="">
- <span class="text">飞行距离</span>
- </div>
- <div class="text-data">{{ singleTotal.flight_mileage }}<span class="text">km</span></div>
- </div>
- <div class="card">
- <div>
- <img src="../../../../assets/images/signMachineNest/machineRight/duration.png" alt="">
- <span class="text">飞行时长</span>
- </div>
- <div class="text-data">{{ singleTotal.hour_count }}<span class="text">h</span></div>
- </div>
- </div>
- </div>
- </div>
- <MachineTableDetails v-model:show="isShowDetails"/>
+ <CommonTitle title="机巢状态" @details="detailsFun" />
+ <div :style="{ marginLeft: pxToRem(14) }">
+ <div class="machine-status">
+ <div class="info">
+ <img src="../../../../assets/images/signMachineNest/machineRight/wrj.png" alt="" />
+ <div class="info-right">
+ <!-- <div class="name">{{ osdVisible?.callsign || '--' }}</div> -->
+ <div class="name">{{ osdVisible?.nickname || '--' }}</div>
+ <div class="wz">
+ <span class="left">当前位置:</span>
+ <span class="right">{{ detailInfo.longitude }},{{ detailInfo.latitude }}</span>
+ </div>
+ <div class="close-wb">
+ <div class="close" :class="AircraftStatus == undefined ? '' : 'other'">
+ {{ AircraftStatus == undefined ? '舱内关机' : AircraftStatus }}
+ </div>
+ <!-- <div class="wb">需要维保</div> -->
+ </div>
+ </div>
+ </div>
+ <div class="status">
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/height.png" alt="" />
+ <span class="text">实时真高</span>
+ </div>
+ <div class="text-data">
+ {{ detailInfo.height || '--' }}
+ <span class="text">米</span>
+ </div>
+ </div>
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/speed.png" alt="" />
+ <span class="text">飞行速度</span>
+ </div>
+ <div class="text-data">
+ {{ detailInfo.horizontal_speed }}
+ <span class="text">米/秒</span>
+ </div>
+ </div>
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/signal.png" alt="" />
+ <span class="text">信号强度</span>
+ </div>
+ <div class="text-data">{{ detailInfo.quality }}</div>
+ </div>
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/electricity.png" alt="" />
+ <span class="text">电池电量</span>
+ </div>
+ <div v-if="drone_charge_state.capacity_percent != 0" class="text-data">
+ {{ drone_charge_state.capacity_percent }}
+ <span class="text">%</span>
+ </div>
+ <div v-else class="text-data">
+ {{ detailInfo.capacity_percent }}
+ <span class="text">%</span>
+ </div>
+ </div>
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/distance.png" alt="" />
+ <span class="text">飞行距离</span>
+ </div>
+ <div class="text-data">
+ {{ singleTotal.flight_mileage }}
+ <span class="text">km</span>
+ </div>
+ </div>
+ <div class="card">
+ <div>
+ <img src="../../../../assets/images/signMachineNest/machineRight/duration.png" alt="" />
+ <span class="text">飞行时长</span>
+ </div>
+ <div class="text-data">
+ {{ singleTotal.hour_count }}
+ <span class="text">h</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <MachineTableDetails v-model:show="isShowDetails" />
</template>
<script setup>
-import CommonTitle from '@/components/CommonTitle.vue';
-import { EDeviceTypeName } from '@/utils/staticData/enums.js';
-import { EModeCode, EDockModeText, EModeText } from '@/utils/staticData/device';
-import { getLnglatAltitude } from '@/utils/cesium/mapUtil.js';
-import { useStore } from 'vuex';
-import MachineTableDetails from '@/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/MachineTableDetails.vue';
+import CommonTitle from '@/components/CommonTitle.vue'
+import { EDeviceTypeName } from '@/utils/staticData/enums.js'
+import { EModeCode, EDockModeText, EModeText } from '@/utils/staticData/device'
+import { getLnglatAltitude } from '@/utils/cesium/mapUtil.js'
+import { useStore } from 'vuex'
+import MachineTableDetails from '@/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/MachineTableDetails.vue'
-const store = useStore();
+const store = useStore()
// 获取机巢信息
-let osdVisible = ref({});//computed(() => store.state.home.osdVisible);
-const singleUavHome = computed(() => store.state.home.singleUavHome);
+let osdVisible = ref({}) //computed(() => store.state.home.osdVisible);
+const singleUavHome = computed(() => store.state.home.singleUavHome)
// 单个机巢统计数据
-const singleTotal = computed(() => store.state.home.singleTotal);
+const singleTotal = computed(() => store.state.home.singleTotal)
// 是否展示机机巢状态详情
-let isShowDetails = ref(false);
+let isShowDetails = ref(false)
-let str = '--';
+let str = '--'
let drone_charge_state = ref({
- capacity_percent: '--',
- state: 0
+ capacity_percent: '--',
+ state: 0,
})
-let AircraftStatus = ref(null);
+let AircraftStatus = ref(null)
let detailInfo = ref({
- longitude: '--',
- latitude: '--',
- home_distance: '--',
- quality: '--',
- horizontal_speed: '--',
- height: '--',
- remain_flight_time: '--',
- capacity_percent: '--',
-});
-let quality = ref(['弱', '较弱', '中等', '较强', '强']);
+ longitude: '--',
+ latitude: '--',
+ home_distance: '--',
+ quality: '--',
+ horizontal_speed: '--',
+ height: '--',
+ remain_flight_time: '--',
+ capacity_percent: '--',
+})
+let quality = ref(['弱', '较弱', '中等', '较强', '强'])
let deviceInfo = ref({
- gateway: {
- capacity_percent: str,
- transmission_signal_quality: str,
- },
- dock: {},
- device: {
- gear: -1,
- mode_code: EModeCode.Disconnected,
- height: str,
- home_distance: str,
- horizontal_speed: str,
- vertical_speed: str,
- wind_speed: str,
- wind_direction: str,
- elevation: str,
- position_state: {
- gps_number: str,
- is_fixed: 0,
- rtk_number: str,
- },
- battery: {
- capacity_percent: str,
- landing_power: str,
- remain_flight_time: 0,
- return_home_power: str,
- },
- latitude: 0,
- longitude: 0,
- },
-});
-let mode_code = ref('已断开连接');
+ gateway: {
+ capacity_percent: str,
+ transmission_signal_quality: str,
+ },
+ dock: {},
+ device: {
+ gear: -1,
+ mode_code: EModeCode.Disconnected,
+ height: str,
+ home_distance: str,
+ horizontal_speed: str,
+ vertical_speed: str,
+ wind_speed: str,
+ wind_direction: str,
+ elevation: str,
+ position_state: {
+ gps_number: str,
+ is_fixed: 0,
+ rtk_number: str,
+ },
+ battery: {
+ capacity_percent: str,
+ landing_power: str,
+ remain_flight_time: 0,
+ return_home_power: str,
+ },
+ latitude: 0,
+ longitude: 0,
+ },
+})
+let mode_code = ref('已断开连接')
-watch(() => store.state.home.osdVisible, (newValue) => {
- osdVisible.value = newValue;
-});
+watch(
+ () => store.state.home.osdVisible,
+ newValue => {
+ osdVisible.value = newValue
+ }
+)
// 监听实时信息
watch(
- () => store.state.home.wsMessage,
- (newValue) => {
- if (newValue.mode_code === 14) return
- if (Object.keys(newValue).length === 0) return
- detailInfo.value.longitude = newValue?.longitude.toFixed(6) || '--';
- detailInfo.value.latitude = newValue?.latitude.toFixed(6) || '--';
- // console.log(window.$viewer)
- getLnglatAltitude(Number(detailInfo.value.longitude), Number(detailInfo.value.latitude),window.$viewer).then((res) => {
- const height = newValue?.height - res?.height;
- //针对西安实时高度进行降低
- const wId = localStorage.getItem('bs_workspace_id');
- if (wId === 'f47ac10b-58cc-4372-a567-0e02b2c3d479') {
- detailInfo.value.height = reduceHeight(height);
- } else {
- detailInfo.value.height = height.toFixed(1) || '--';
- }
+ () => store.state.home.wsMessage,
+ newValue => {
+ if (newValue.mode_code === 14) return
+ if (Object.keys(newValue).length === 0) return
+ detailInfo.value.longitude = newValue?.longitude.toFixed(6) || '--'
+ detailInfo.value.latitude = newValue?.latitude.toFixed(6) || '--'
+ // console.log(window.$viewer)
+ getLnglatAltitude(Number(detailInfo.value.longitude), Number(detailInfo.value.latitude), window.$viewer).then(
+ res => {
+ const height = newValue?.height - res?.height
+ //针对西安实时高度进行降低
+ const wId = localStorage.getItem('bs_workspace_id')
+ if (wId === 'f47ac10b-58cc-4372-a567-0e02b2c3d479') {
+ detailInfo.value.height = reduceHeight(height)
+ } else {
+ detailInfo.value.height = height.toFixed(1) || '--'
+ }
- detailInfo.value.quality = quality.value[newValue?.position_state.quality - 1] || '--';
- detailInfo.value.horizontal_speed = newValue?.horizontal_speed.toFixed(1) || '--';
- detailInfo.value.remain_flight_time = (newValue?.battery.remain_flight_time / 60).toFixed(0) || '--';
- detailInfo.value.capacity_percent = (newValue?.battery.capacity_percent).toFixed(0) || '--';
- });
- },
- { immediate: true, deep: true }
-);
+ detailInfo.value.quality = quality.value[newValue?.position_state.quality - 1] || '--'
+ detailInfo.value.horizontal_speed = newValue?.horizontal_speed.toFixed(1) || '--'
+ detailInfo.value.remain_flight_time = (newValue?.battery.remain_flight_time / 60).toFixed(0) || '--'
+ detailInfo.value.capacity_percent = (newValue?.battery.capacity_percent).toFixed(0) || '--'
+ }
+ )
+ },
+ { immediate: true, deep: true }
+)
// 获取最新机场状态
-watch(store.state.home.deviceState, (newValue) => {
- // console.log('newValue', newValue);
- if (newValue.currentType === EDeviceTypeName.Dock && newValue?.dockInfo[newValue.currentSn]) {
- // 机场状态
- mode_code.value = EDockModeText[newValue?.dockInfo[newValue.currentSn]?.basic_osd?.mode_code];
- // this.$emit('updateModeCode', mode_code.value);
- // 舱内状态
- AircraftStatus.value =
- EModeText[newValue.deviceInfo[
- deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ??
- osdVisible.sn
- ]?.mode_code
- ];
- // 舱内关机时显示的电量
- let child_sn = newValue?.dockInfo[newValue.currentSn].basic_osd.sub_device?.device_sn;
- // 飞机在线时取飞机中的电量
- if(newValue.deviceInfo[child_sn]) {
- drone_charge_state.value = {
- capacity_percent: newValue.deviceInfo[child_sn].battery.capacity_percent,
- state: newValue.deviceInfo[child_sn].battery.landing_power
- }
- } else{
- // 遥控器这里拿不到值data.drone_charge_state_new == undefined 会一直报错
- if (newValue.drone_charge_state_new) {
- drone_charge_state.value = newValue.drone_charge_state_new;
- }
- }
- if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') {
- deviceInfo.value.dock = newValue.dockInfo[osdVisible.value.gateway_sn];
- deviceInfo.value.device =
- newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ??
- osdVisible.value.sn
- ];
- // 设备关机即不显示信息
- // 兼容遥控器 关闭无人机 mode_code返回的是14 不是undefined
- if (
- newValue.deviceInfo[
- deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ??
- osdVisible.value.sn
- ]?.mode_code === undefined || newValue.deviceInfo[
- deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ??
- osdVisible.value .sn
- ]?.mode_code == 14
- ) {
- detailInfo.value = {
- longitude: '--',
- latitude: '--',
- home_distance: '--',
- quality: '--',
- horizontal_speed: '--',
- remain_flight_time: '--',
- height: '--',
- capacity_percent: '--',
- };
- }
- }
- }
- },
- { immediate: true, deep: true }
-);
+watch(
+ store.state.home.deviceState,
+ newValue => {
+ // console.log('newValue', newValue);
+ if (newValue.currentType === EDeviceTypeName.Dock && newValue?.dockInfo[newValue.currentSn]) {
+ // 机场状态
+ mode_code.value = EDockModeText[newValue?.dockInfo[newValue.currentSn]?.basic_osd?.mode_code]
+ // this.$emit('updateModeCode', mode_code.value);
+ // 舱内状态
+ AircraftStatus.value =
+ EModeText[
+ newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.sn]?.mode_code
+ ]
+ // 舱内关机时显示的电量
+ let child_sn = newValue?.dockInfo[newValue.currentSn].basic_osd?.sub_device?.device_sn
+ // 飞机在线时取飞机中的电量
+ if (newValue.deviceInfo[child_sn]) {
+ drone_charge_state.value = {
+ capacity_percent: newValue.deviceInfo[child_sn].battery.capacity_percent,
+ state: newValue.deviceInfo[child_sn].battery.landing_power,
+ }
+ } else {
+ // 遥控器这里拿不到值data.drone_charge_state_new == undefined 会一直报错
+ if (newValue.drone_charge_state_new) {
+ drone_charge_state.value = newValue.drone_charge_state_new
+ }
+ }
+ if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') {
+ deviceInfo.value.dock = newValue.dockInfo[osdVisible.value.gateway_sn]
+ deviceInfo.value.device =
+ newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
+ // 设备关机即不显示信息
+ // 兼容遥控器 关闭无人机 mode_code返回的是14 不是undefined
+ if (
+ newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
+ ?.mode_code === undefined ||
+ newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
+ ?.mode_code == 14
+ ) {
+ detailInfo.value = {
+ longitude: '--',
+ latitude: '--',
+ home_distance: '--',
+ quality: '--',
+ horizontal_speed: '--',
+ remain_flight_time: '--',
+ height: '--',
+ capacity_percent: '--',
+ }
+ }
+ }
+ }
+ },
+ { immediate: true, deep: true }
+)
-const reduceHeight = (height) => {
- if (!Number(height)) return '--';
- let theFinheight = 0;
- if (height < 120) {
- theFinheight = height;
- } else if (height > 220) {
- theFinheight = height - 110;
- } else if (height > 210) {
- theFinheight = height - 100;
- } else if (height > 200) {
- theFinheight = height - 90;
- } else if (height > 190) {
- theFinheight = height - 80;
- } else if (height > 180) {
- theFinheight = height - 70;
- } else if (height > 170) {
- theFinheight = height - 60;
- } else if (height > 160) {
- theFinheight = height - 50;
- } else if (height > 150) {
- theFinheight = height - 40;
- } else if (height > 140) {
- theFinheight = height - 30;
- } else if (height > 130) {
- theFinheight = height - 20;
- } else if (height > 120) {
- theFinheight = height - 10;
- }
- return theFinheight.toFixed(1);
-};
+const reduceHeight = height => {
+ if (!Number(height)) return '--'
+ let theFinheight = 0
+ if (height < 120) {
+ theFinheight = height
+ } else if (height > 220) {
+ theFinheight = height - 110
+ } else if (height > 210) {
+ theFinheight = height - 100
+ } else if (height > 200) {
+ theFinheight = height - 90
+ } else if (height > 190) {
+ theFinheight = height - 80
+ } else if (height > 180) {
+ theFinheight = height - 70
+ } else if (height > 170) {
+ theFinheight = height - 60
+ } else if (height > 160) {
+ theFinheight = height - 50
+ } else if (height > 150) {
+ theFinheight = height - 40
+ } else if (height > 140) {
+ theFinheight = height - 30
+ } else if (height > 130) {
+ theFinheight = height - 20
+ } else if (height > 120) {
+ theFinheight = height - 10
+ }
+ return theFinheight.toFixed(1)
+}
// 详情
const detailsFun = () => {
- isShowDetails.value = true;
-};
+ isShowDetails.value = true
+}
</script>
<style lang="scss" scoped>
- .machine-status {
- width: 390px;
- height: 230px;
- background: linear-gradient(
- 270deg,
- #1f3e7a 0%,
- rgba(31, 62, 122, 0.35) 79%,
- rgba(31, 62, 122, 0) 100%
- );
- opacity: 0.85;
- margin: 2px 0 13 0;
+.machine-status {
+ width: 390px;
+ height: 230px;
+ background: linear-gradient(270deg, #1f3e7a 0%, rgba(31, 62, 122, 0.35) 79%, rgba(31, 62, 122, 0) 100%);
+ opacity: 0.85;
+ margin: 2px 0 13 0;
- padding: 8px 0px 20px 18px;
- .info {
- display: flex;
- // justify-content: ce;
- height: 88px;
- display: flex;
- align-items: center;
- img {
- width: 94px;
- height: 88px;
- margin-right: 22px;
- }
- .info-right {
- .name {
- width: 184px;
- height: 31px;
- font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
- font-weight: 400;
- font-size: 24px;
- color: #0BE5F5;
- line-height: 28px;
- overflow: hidden; // 添加溢出隐藏
- text-overflow: ellipsis; // 显示省略号
- white-space: nowrap; // 不换行
- }
- .wz {
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-size: 14px;
- color: #FFFFFF;
- line-height: 16px;
- .left {
- width: 70px;
- height: 21px;
- font-weight: 400;
- opacity: 0.6;
- }
- .right {
- width: 100px;
- height: 21px;
- font-weight: bold;
- }
- }
- .close-wb {
- display: flex;
- margin-top: 10px;
- text-align: center;
- line-height: 16px;
- .close {
- width: 60px;
- height: 20px;
- line-height: 20px;
- background: rgba(255,178,106,0.2);
- border-radius: 4px 4px 4px 4px;
- border: 1px solid #FFB26A;
- color: #FFB26A;
- margin-right: 10px;
- }
- .other {
- border: 1px solid #8EFFAC;
- color: #8EFFAC;
- }
- .wb {
- width: 60px;
- height: 20px;
- background: rgba(255,106,106,0.2);
- border-radius: 4px 4px 4px 4px;
- border: 1px solid #FF6A6A;
- color: #FF6A6A;
- }
- }
-
- }
- }
- .status {
- display: flex;
- flex-wrap: wrap;
- gap: 10px 20px;
- margin-top: 18px;
- .card {
- width: calc(33.33% - 14px);
- }
- img {
- width: 16px;
- height: 16px;
- // margin-right: 0px;
- // margin-top: 2px;
- }
- .text {
- width: 56px;
- height: 21px;
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 14px;
- color: #FFFFFF;
- line-height: 16px;
- }
- .text-data {
- // width: 40px;
- margin-left: 20px;
- height: 23px;
- font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
- font-weight: 400;
- font-size: 18px;
- color: #0BE5F5;
- line-height: 21px;
- }
- }
- }
+ padding: 8px 0px 20px 18px;
+ .info {
+ display: flex;
+ // justify-content: ce;
+ height: 88px;
+ display: flex;
+ align-items: center;
+ img {
+ width: 94px;
+ height: 88px;
+ margin-right: 22px;
+ }
+ .info-right {
+ .name {
+ width: 184px;
+ height: 31px;
+ font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
+ font-weight: 400;
+ font-size: 24px;
+ color: #0be5f5;
+ line-height: 28px;
+ overflow: hidden; // 添加溢出隐藏
+ text-overflow: ellipsis; // 显示省略号
+ white-space: nowrap; // 不换行
+ }
+ .wz {
+ font-family: Source Han Sans CN, Source Han Sans CN;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 16px;
+ .left {
+ width: 70px;
+ height: 21px;
+ font-weight: 400;
+ opacity: 0.6;
+ }
+ .right {
+ width: 100px;
+ height: 21px;
+ font-weight: bold;
+ }
+ }
+ .close-wb {
+ display: flex;
+ margin-top: 10px;
+ text-align: center;
+ line-height: 16px;
+ .close {
+ width: 60px;
+ height: 20px;
+ line-height: 20px;
+ background: rgba(255, 178, 106, 0.2);
+ border-radius: 4px 4px 4px 4px;
+ border: 1px solid #ffb26a;
+ color: #ffb26a;
+ margin-right: 10px;
+ }
+ .other {
+ border: 1px solid #8effac;
+ color: #8effac;
+ }
+ .wb {
+ width: 60px;
+ height: 20px;
+ background: rgba(255, 106, 106, 0.2);
+ border-radius: 4px 4px 4px 4px;
+ border: 1px solid #ff6a6a;
+ color: #ff6a6a;
+ }
+ }
+ }
+ }
+ .status {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px 20px;
+ margin-top: 18px;
+ .card {
+ width: calc(33.33% - 14px);
+ }
+ img {
+ width: 16px;
+ height: 16px;
+ // margin-right: 0px;
+ // margin-top: 2px;
+ }
+ .text {
+ width: 56px;
+ height: 21px;
+ font-family: Source Han Sans CN, Source Han Sans CN;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 16px;
+ }
+ .text-data {
+ // width: 40px;
+ margin-left: 20px;
+ height: 23px;
+ font-family: YouSheBiaoTiHei, YouSheBiaoTiHei;
+ font-weight: 400;
+ font-size: 18px;
+ color: #0be5f5;
+ line-height: 21px;
+ }
+ }
+}
</style>
diff --git a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceEvent.vue b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceEvent.vue
index 0edf424..934d9d2 100644
--- a/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceEvent.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/DeviceEvent.vue
@@ -70,7 +70,10 @@
const total = ref(0)
const distribution = row => {
- ElMessage.warning('正在加急开发中...')
+ const orderNumber = row.event_num
+ const adminUrl = import.meta.env.VITE_APP_ADMIN_URL
+ const targetPath = `/tickets/ticket?orderNumber=${orderNumber}`;
+ window.open(`${adminUrl}?redirect=${encodeURIComponent(targetPath)}`, '_blank');
}
const examine = row => {
ElMessage.warning('正在加急开发中...')
--
Gitblit v1.9.3