forked from drone/command-center-dashboard

罗广辉
2025-04-03 c45531e760a5f4cc69dd2314a4f5bbcdc881d30a
Merge remote-tracking branch 'origin/master'
6 files modified
1 files added
321 ■■■■■ changed files
.env.development 14 ●●●●● patch | view | raw | blame | history
package.json 3 ●●●● patch | view | raw | blame | history
src/store/modules/home.js 125 ●●●● patch | view | raw | blame | history
src/views/SignMachineNest/SignMachineNest.vue 31 ●●●●● patch | view | raw | blame | history
src/views/SignMachineNest/components/MachineLeft/MachineData.vue 45 ●●●●● patch | view | raw | blame | history
src/views/SignMachineNest/components/MachineRight/MachineStatus.vue 18 ●●●● patch | view | raw | blame | history
src/views/SignMachineNest/components/MachineRight/components/MachineTableDetails.vue 85 ●●●●● patch | view | raw | blame | history
.env.development
@@ -3,5 +3,17 @@
VITE_APP_ENV = 'development'
#接口地址
# VITE_APP_API_URL = https://wrj.shuixiongit.com/api
VITE_APP_API = /api
VITE_APP_API_URL = https://wrj.shuixiongit.com/api
# 连接本地服务器
# VITE_APP_API_URL = http://192.168.1.204
#调试参数
VITE_APP_DEBUG_KEY = saber
VITE_APP_DEBUG_SWITCH = false
#页面基础路径
VITE_APP_BASE = /command-center-dashboard/
# ws地址
VITE_APP_WS_API_URL = wss://wrj.shuixiongit.com/drone-wss/api/v1/ws
package.json
@@ -39,8 +39,7 @@
    "vue-i18n": "^9.1.9",
    "vue-router": "^4.3.2",
    "vue3-clipboard": "^1.0.0",
    "vuex": "^4.1.0",
    "@turf/turf": "^6.5.0"
    "vuex": "^4.1.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
src/store/modules/home.js
@@ -2,67 +2,70 @@
import { EDeviceTypeName } from '@/utils/staticData/enums'
const home = {
    state: {
        singleUavHome: {},
        // 项目id
        selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
        wsMessage: {},
        deviceState: {
            gatewayInfo: {},
            deviceInfo: {},
            timestamp: '',
            dockInfo: {},
            currentSn: '',
            currentType: -1,
            drone_charge_state_new: {},
            psdk_widget_values: {},
            speakerAudioPlayStartProgress: {},
        },
        osdVisible: {
            // osd 显示设备相关信息
            sn: '',
            callsign: '',
            model: '',
            visible: false,
            gateway_sn: '',
            is_dock: false,
            payloads: null,
            device_domain: '',
            device_sub_type: '',
            device_type: '',
        },
    },
    actions: {},
    mutations: {
        setSingleUavHome: (state, data) => {
            state.singleUavHome = data
        },
        setSelectedWorkSpaceId: (state, id) => {
            state.selectedWorkSpaceId = id
            window.localStorage.setItem('bs_workspace_id', id)
        },
        setOsdVisibleInfo: (state, info) => {
            console.log(info, '哒哒哒')
            state.osdVisible = Object.assign({}, info)
            window.localStorage.setItem('bs_osd', JSON.stringify(info))
        },
        setWsMessage: (state, data) => {
            state.wsMessage = data.host
        },
        setDeviceInfo: (state, data) => {
            const info = data.data
            state.deviceState.timestamp = data.timestamp
            state.deviceState.deviceInfo[info.sn] = info.host
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Aircraft
        },
        setGatewayInfo: (state, info) => {
            state.deviceState.gatewayInfo[info.sn] = info.host
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Gateway
        },
        setDockOnfo: (state, info) => {
            if (Object.keys(info.host).length === 0) return
  state: {
    singleUavHome: {},
    singleTotal: {}, // 统计单个机巢数据
    // 项目id
    selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
    wsMessage: {},
    deviceState: {
      gatewayInfo: {},
      deviceInfo: {},
      timestamp: '',
      dockInfo: {},
      currentSn: '',
      currentType: -1,
      drone_charge_state_new: {},
      psdk_widget_values: {},
      speakerAudioPlayStartProgress: {},
    },
    osdVisible: {
      // osd 显示设备相关信息
      sn: '',
      callsign: '',
      model: '',
      visible: false,
      gateway_sn: '',
      is_dock: false,
      payloads: null,
      device_domain: '',
      device_sub_type: '',
      device_type: '',
    },
  },
  actions: {},
  mutations: {
    setSingleUavHome: (state, data) => {
      state.singleUavHome = data;
    },
    setSingleTotal: (state, data) => {
      state.singleTotal = data;
    },
    setSelectedWorkSpaceId: (state, id) => {
      state.selectedWorkSpaceId = id
      window.localStorage.setItem('bs_workspace_id', id)
    },
    setOsdVisibleInfo: (state, info) => {
      state.osdVisible = Object.assign({}, info)
      window.localStorage.setItem('bs_osd', JSON.stringify(info))
    },
    setWsMessage: (state, data) => {
      state.wsMessage = data.host;
    },
    setDeviceInfo: (state, data) => {
      const info = data.data
      state.deviceState.timestamp = data.timestamp
      state.deviceState.deviceInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Aircraft
    },
    setGatewayInfo: (state, info) => {
      state.deviceState.gatewayInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Gateway
    },
    setDockOnfo: (state, info) => {
      if (Object.keys(info.host).length === 0) return
            if (!state.deviceState.dockInfo[info.sn]) {
                state.deviceState.dockInfo[info.sn] = {}
src/views/SignMachineNest/SignMachineNest.vue
@@ -11,7 +11,7 @@
import { EBizCode } from '@/utils/staticData/enums.js';
import { EModeCode } from '@/utils/staticData/device.js';
import { useStore } from 'vuex';
import { getDeviceDetail } from '@/api/home/machineNest';
import { getDeviceDetail, getFlightStatistics } from '@/api/home/machineNest';
const store = useStore();
@@ -59,25 +59,6 @@
    const result = res.data.data;
    const child = result.children;
    // 对应store 里面数据结构
    // const device = {
    //   visible: true,
    //   is_dock: true,
    //   model: child?.device_name,
    //   callsign: child?.nickname,
    //   sn: child?.device_sn,
    //   mode: EModeCode.Disconnected,
    //   latest_wayline_job: result.latest_wayline_job,
    //   gateway: {
    //     model: result?.device_name,
    //     callsign: result?.nickname,
    //     sn: result?.device_sn,
    //     domain: result?.domain,
    //     device_domain: child.domain,
    //     device_type: child.type,
    //     device_sub_type: child.sub_type,
    //   },
    //   payload: child.payloads_list || [],
    // };
    osdVisible.value.sn = child?.device_sn || ''
    osdVisible.value.callsign = child?.nickname || '--'
    osdVisible.value.model = EModeCode.Disconnected || ''
@@ -97,8 +78,18 @@
  });
};
// 获取机巢统计数据 提供给左右侧组件使用
const getMachineData = () => {
  getFlightStatistics(singleUavHome.value.device_sn).then(res => {
    if (res.data.code !== 0) return;
    const result = res.data.data;
    store.commit('setSingleTotal', result);
  })
};
onMounted(() => {
  getSingleDetails();
  getMachineData();
});
onUnmounted(() => {
src/views/SignMachineNest/components/MachineLeft/MachineData.vue
@@ -13,9 +13,9 @@
</template>
<script setup>
import { getFlightStatistics } from '@/api/home/machineNest.js'
import { pxToRem } from '@/utils/rem';
import CommonTitle from '@/components/CommonTitle.vue';
import { useStore } from 'vuex';
import rwcs from '@/assets/images/signMachineNest/machineLeft/rwcs.png';
import sjs from '@/assets/images/signMachineNest/machineLeft/sjs.png';
import jscb from '@/assets/images/signMachineNest/machineLeft/jscb.png';
@@ -23,33 +23,26 @@
import fxlc from '@/assets/images/signMachineNest/machineLeft/fxlc.png';
import fxsc from '@/assets/images/signMachineNest/machineLeft/fxsc.png';
const statisticsList = ref([
  { imgurl: rwcs, num: 1314, text: '任务次数(次)' },
  { imgurl: sjs, num: 1314, text: '事件数(件)' },
  { imgurl: jscb, num: 1314, text: '节省成本(万元)' },
  { imgurl: rwcg, num: 1314, text: '任务成果(个)' },
  { imgurl: fxlc, num: 1314, text: '飞行里程(公里)' },
  { imgurl: fxsc, num: 1314, text: '飞行时长' },
]);
const store = useStore();
// 获取机巢统计数据
const getMachineData = () => {
  let dockSn = ref('4TADKCM0010016');
  getFlightStatistics(dockSn.value).then(res => {
    if (res.data.code !== 0) return;
    const result = res.data.data;
    statisticsList.value[0].num = result.fly_count || 0;
    statisticsList.value[1].num = result.event_count || 0;
    statisticsList.value[2].num = result.total_cost_saved || 0;
    statisticsList.value[3].num = result.achievement_count || 0;
    statisticsList.value[4].num = result.flight_mileage || 0;
    statisticsList.value[5].num = `${result.hour_count}:${result.min_count}` || 0;
  })
};
const statisticsList = ref([]);
onMounted(() => {
  getMachineData();
});
// 添加监听
watch(
  () => store.state.home.singleTotal,
  (newValue) => {
    if (!newValue) return;
    statisticsList.value = [
      { imgurl: rwcs, num: newValue.fly_count || 0, text: '任务次数(次)' },
      { imgurl: sjs, num: newValue.event_count || 0, text: '事件数(件)' },
      { imgurl: jscb, num: newValue.total_cost_saved || 0, text: '节省成本(万元)' },
      { imgurl: rwcg, num: newValue.achievement_count || 0, text: '任务成果(个)' },
      { imgurl: fxlc, num: newValue.flight_mileage || 0, text: '飞行里程(公里)' },
      { imgurl: fxsc, num: newValue.hour_count || 0, text: '飞行时长(H)' }
    ];
  },
  { immediate: true, deep: true }
);
</script>
<style lang="scss" scoped>
src/views/SignMachineNest/components/MachineRight/MachineStatus.vue
@@ -1,6 +1,6 @@
<!-- 机巢状态 -->
<template>
  <CommonTitle title="机巢状态" />
  <CommonTitle title="机巢状态" @details="detailsFun" />
  <div :style="{ marginLeft: pxToRem(14) }">
    <div class="machine-status">
      <div class="info">
@@ -54,18 +54,19 @@
            <img src="@/assets/images/signMachineNest/machineRight/distance.png" alt="">
            <span class="text">飞行距离</span>
          </div>
          <div class="text-data">98<span class="text">km</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">188<span class="text">min</span></div>
          <div class="text-data">{{ singleTotal.hour_count }}<span class="text">h</span></div>
        </div>
      </div>
    </div>
  </div>
  <!-- <MachineTableDetails :dialogVisible="isShowDetails" /> -->
</template>
<script setup>
@@ -76,7 +77,13 @@
import { useStore } from 'vuex';
const store = useStore();
// 获取机巢信息
let osdVisible = computed(() => store.state.home.osdVisible);
// 单个机巢统计数据
const singleTotal = computed(() => store.state.home.singleTotal);
// 是否展示机机巢状态详情
let isShowDetails = ref(false);
let str = '--';
let drone_charge_state = ref({
  capacity_percent: '--',
@@ -243,6 +250,11 @@
  }
  return theFinheight.toFixed(1);
};
// 详情
const detailsFun = () => {
  isShowDetails.value = true;
};
</script>
<style lang="scss" scoped>
src/views/SignMachineNest/components/MachineRight/components/MachineTableDetails.vue
New file
@@ -0,0 +1,85 @@
<!-- 机巢列表详情 -->
<template>
  <div>
  </div>
  <el-dialog
    v-model="dialogVisible"
    title="机巢详情"
    width="800px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
  >
    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="value" label="数值" />
      <el-table-column prop="status" label="状态" />
      <el-table-column prop="time" label="时间" />
    </el-table>
  </el-dialog>
</template>
<script setup>
const props = defineProps({
  dialogVisible: {
    type: Boolean,
    default: false,
  },
});
// const dialogVisible = ref(false);
const tableData = ref([
  {
    name: '机巢1号',
    value: '98%',
    status: '正常',
    time: '2024-03-20 10:00:00'
  },
  {
    name: '电池状态',
    value: '95%',
    status: '正常',
    time: '2024-03-20 10:00:00'
  },
  {
    name: '信号强度',
    value: '强',
    status: '正常',
    time: '2024-03-20 10:00:00'
  }
]);
</script>
<style lang="scss" scoped>
// ... 其他样式 ...
:deep(.el-dialog) {
  background: linear-gradient(
    270deg,
    #1f3e7a 0%,
    rgba(31, 62, 122, 0.95) 79%,
    rgba(31, 62, 122, 0.9) 100%
  );
  .el-dialog__header {
    color: #fff;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    margin: 0;
    padding: 15px 20px;
    .el-dialog__title {
      color: #fff;
    }
  }
  .el-dialog__body {
    color: #fff;
    padding: 20px;
  }
  .el-table {
    background-color: transparent;
    --el-table-tr-bg-color: transparent;
    --el-table-border-color: rgba(255, 255, 255, 0.1);
    --el-table-header-bg-color: rgba(31, 62, 122, 0.5);
    --el-table-header-text-color: #fff;
    --el-table-text-color: #fff;
  }
}
</style>