From 89380e6260a75d1d3b94de687ebcc2f50d50659d Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Tue, 03 Feb 2026 15:44:33 +0800
Subject: [PATCH] feat:环境变量配置调整
---
applications/drone-command/src/views/dataCockpit/components/RightContainer.vue | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 279 insertions(+), 2 deletions(-)
diff --git a/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue b/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
index f59947f..af0b83f 100644
--- a/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
+++ b/applications/drone-command/src/views/dataCockpit/components/RightContainer.vue
@@ -1,13 +1,290 @@
+<!--
+ * @Author : yuan
+ * @Date : 2026-01-07 15:17:54
+ * @LastEditors : yuan
+ * @LastEditTime : 2026-01-31 15:47:40
+ * @FilePath : \applications\drone-command\src\views\dataCockpit\components\RightContainer.vue
+ * @Description :
+ * Copyright 2026 OBKoro1, All Rights Reserved.
+ * 2026-01-07 15:17:54
+-->
<template>
- <div>
+ <div class="right-container" :class="{ collapsed: collapsedModel }">
+ <div class="wrapper">
+ <TitleTemplate>侦测反制设备</TitleTemplate>
+ <div class="category-container">
+ <div class="category-item" v-for="(item, ind) in categoryList" :key="ind">
+ <div class="category-item-logo">
+ <img :src="item.logo" alt="">
+ </div>
+
+ <div class="category-item-content">
+ <span class="name">{{ item.name }}</span>
+ <span class="val">{{ item.val }}</span>
+ </div>
+ </div>
+ </div>
+
+ <div
+ class="content"
+ v-loading="loading"
+ element-loading-background="rgba(5, 5, 15, 0.6)"
+ element-loading-text="加载中..."
+ >
+ <EmptyState v-if="!counterDeviceStatusList.length" />
+ <RealEquipmentTemplate
+ v-else
+ v-for="item in counterDeviceStatusList"
+ :key="item.id"
+ :data="item"
+ @history="onHistory"
+ @click="onCardClick"
+ />
+ </div>
+ </div>
+
+ <div class="collapse-btn" @click="toggleCollapse">
+ <span class="arrow" :class="collapsedModel ? 'left' : 'right'"></span>
+ </div>
+
+ <DeviceHistoryDialog v-model="historyVisible" :device="historyDevice" />
</div>
</template>
<script setup>
+import TitleTemplate from './templateComponents/TitleTemplate.vue'
+import RealEquipmentTemplate from './templateComponents/RealEquipmentTemplate.vue'
+import DeviceHistoryDialog from './DeviceHistoryDialog.vue'
+import EmptyState from './EmptyState.vue'
+import zcsbLogo from '@/assets/images/dataCockpit/zcsb.png'
+import fzsbLogo from '@/assets/images/dataCockpit/fzsb.png'
+import { deviceSearchApi, deviceStatisticsApi } from '@/api/dataCockpit'
+const props = defineProps({
+ collapsed: {
+ type: Boolean,
+ default: false
+ }
+})
+
+const emit = defineEmits(['update:collapsed', 'update:allDevices'])
+
+const collapsedModel = computed({
+ get: () => props.collapsed,
+ set: (val) => emit('update:collapsed', val)
+})
+
+const categoryList = ref([
+ {
+ id: 1,
+ name: '侦测设备',
+ val: 0,
+ logo: zcsbLogo
+ },
+ {
+ id: 2,
+ name: '反制设备',
+ val: 0,
+ logo: fzsbLogo
+ }
+])
+
+const counterDeviceStatusList = ref([])
+
+const historyVisible = ref(false)
+const historyDevice = ref(null)
+const loading = ref(true)
+const minLoadingMs = 400
+
+const onHistory = (item) => {
+ historyDevice.value = item
+ historyVisible.value = true
+ console.log('历史数据:', item.id)
+}
+
+const onCardClick = (item) => {
+ console.log('点击卡片:', item.id)
+}
+const toggleCollapse = () => {
+ collapsedModel.value = !collapsedModel.value
+}
+
+const statusMap = {
+ 0: { text: '在线', actionType: 'detecting' },
+ 1: { text: '离线', actionType: '' },
+ 2: { text: '故障', actionType: 'jamming' },
+ 3: { text: '报废', actionType: '' }
+}
+const deviceTypeMap = {
+ 1: '便捷侦测箱',
+ 2: '反制枪',
+ 3: '察打一体'
+}
+
+const formatDeviceItem = (item) => {
+ const statusInfo = statusMap[item?.status] || { text: '-', actionType: '' }
+ return {
+ id: item.id,
+ name: item.deviceName || item.deviceModel || '-',
+ actionText: statusInfo.text,
+ actionType: statusInfo.actionType,
+ type: deviceTypeMap[item.deviceType] || item.deviceType || '-',
+ batteryPct: item.batteryPct ?? 0,
+ azimuth: item.azimuth ?? 0,
+ elevation: item.elevation ?? 0,
+ status: item.status ?? '-',
+ workMode: item.workMode ?? '-',
+ manufacturer: item.manufacturer || '-',
+ detectTargetCnt: item.detectTargetCnt ?? 0,
+ effectiveRangeKm: item.effectiveRangeKm ?? 0
+ }
+}
+
+const fetchDeviceList = async () => {
+ const startAt = Date.now()
+ loading.value = true
+ try {
+ const params = { current: 1, size: 9999, deviceStatusList: '0,1,2' }
+ const res = await deviceSearchApi(params)
+ const records = res?.data?.data?.records ?? []
+ let onlineData = records.filter(item => String(item.status) === '0')
+ counterDeviceStatusList.value = onlineData.map(formatDeviceItem)
+ emit('update:allDevices', records)
+ } finally {
+ const elapsed = Date.now() - startAt
+ if (elapsed < minLoadingMs) {
+ await new Promise((resolve) => setTimeout(resolve, minLoadingMs - elapsed))
+ }
+ loading.value = false
+ }
+}
+
+onMounted(() => {
+ fetchDeviceList()
+ fetchDeviceStatistics()
+})
+
+const normalizeType = (value) => {
+ if (value === 1 || value === '1') return '侦测设备'
+ if (value === 2 || value === '2') return '反制设备'
+ if (value === 'detect') return '侦测设备'
+ if (value === 'counter') return '反制设备'
+ return value
+}
+
+const fetchDeviceStatistics = async () => {
+ const res = await deviceStatisticsApi()
+ const list = res?.data?.data ?? []
+ const map = new Map(list.map((item) => [normalizeType(item.type), item.count]))
+ categoryList.value = categoryList.value.map((item) => ({
+ ...item,
+ val: map.has(item.name) ? map.get(item.name) : item.val
+ }))
+}
</script>
<style lang="scss" scoped>
+.category-container {
+ margin-top: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 28px;
+ box-sizing: border-box;
-</style>
\ No newline at end of file
+ .category-item {
+ position: relative;
+ width: 0;
+ flex: 1;
+ display: flex;
+ height: 64px;
+
+ &-logo {
+ display: flex;
+ align-items: center;
+
+ img {
+ width: 40px;
+ height: 40px;
+ }
+ }
+
+ &-content {
+ width: 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ border-bottom: 1px solid #6C6C89;
+
+ span {
+ margin-left: 8px;
+ }
+
+ .name {
+ font-family: Open Sans, Open Sans;
+ font-weight: 400;
+ font-size: 16px;
+ color: #C3C3DD;
+ line-height: 20px;
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+ }
+
+ .val {
+ margin-top: 10px;
+ font-family: DinAB;
+ font-weight: bold;
+ font-size: 22px;
+ color: #FFFFFF;
+ line-height: 20px;
+ text-align: left;
+ font-style: normal;
+ text-transform: none;
+ }
+ }
+ }
+}
+
+.content {
+ height: 0;
+ flex: 1;
+ margin-top: 20px;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+
+.right-container {
+ transition: transform 0.3s ease-in-out;
+ position: relative;
+
+ &.collapsed {
+ transform: translateX(calc(100% + 17px + 32px));
+ }
+}
+
+.collapse-btn {
+ position: absolute;
+ bottom: 454px;
+ right: 300px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ z-index: 10;
+ transform: translateY(50%);
+
+ .arrow {
+ width: 36px;
+ height: 36px;
+ background: url('@/assets/images/dataCockpit/right-btn.png') center / 100% 100% no-repeat;
+ }
+
+ &:hover {
+ background: rgba(40, 79, 227, 0.6);
+ }
+}
+</style>
--
Gitblit v1.9.3