소스 검색

feat(check): 添加设备状态监控功能

- 在检测界面添加查看设备状态按钮
- 实现设备状态对话框显示相机、转盘等设备运行状态
- 集成MCU信息获取接口实时监控设备状态
- 添加状态文本映射和样式标识不同设备状态
- 优化检测按钮布局增加间距提升用户体验
- 修复摄影检测页面加载状态设置问题
- 清理多余的IPC监听器释放资源
panqiuyao 1 일 전
부모
커밋
a28d9d19ae
2개의 변경된 파일180개의 추가작업 그리고 4개의 파일을 삭제
  1. 179 1
      frontend/src/components/check/index.vue
  2. 1 3
      frontend/src/views/Photography/check.vue

+ 179 - 1
frontend/src/components/check/index.vue

@@ -51,20 +51,45 @@
     </div>
     <template #footer v-if="!checkLoading">
         <div class="flex" v-if="!checkSuccess">
-            <div class="check-btn cu-p"  style="width: 160px" @click="reCheck">重新监测一次</div>
+            <div class="check-btn cu-p" style="width: 160px; margin-right: 10px;" @click="reCheck">重新监测一次</div>
+            <div class="check-btn check-btn-secondary cu-p" style="width: 160px;" @click="openStatusDialog">查看设备状态</div>
         </div>
         <div class="flex" v-else>
             <div class="check-btn cu-p" style="width: 180px" @click="confirm()">检测成功,继续操作!</div>
         </div>
     </template>
   </el-dialog>
+
+  <!-- 设备状态对话框 -->
+  <el-dialog
+    v-model="showStatusDialog"
+    title="设备运行状态"
+    width="600px"
+    :close-on-click-modal="false"
+  >
+    <div class="status-content">
+      <div class="status-item" v-for="(status, key) in deviceStatus" :key="key">
+        <span class="status-label">{{ getStatusLabel(key) }}:</span>
+        <span class="status-value" :class="getStatusClass(status)">{{ getStatusText(status) }}</span>
+      </div>
+    </div>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="showStatusDialog = false">取消</el-button>
+        <el-button type="primary" :loading="statusLoading" @click="getDeviceStatus">刷新</el-button>
+      </span>
+    </template>
+  </el-dialog>
 </template>
 
 <script setup>
 import { ref, computed, watch, onBeforeUnmount, nextTick, watchEffect } from 'vue';
+import { ElMessage, ElDialog, ElButton } from 'element-plus';
 import useUserInfo from "@/stores/modules/user";
 import checkInfo from "@/stores/modules/check";
 import client from "@/stores/modules/client";
+import socket from "@/stores/modules/socket";
+import icpList from '@/utils/ipc';
 const clientStore = client();
 
 /**
@@ -88,6 +113,7 @@ const props = defineProps({
 // 初始化用户信息状态管理
 const useUserInfoStore = useUserInfo()
 const checkInfoStore = checkInfo()
+const socketStore = socket()
 
 // 检测是否成功的状态
 const checkSuccess = ref(false);
@@ -95,6 +121,17 @@ const checkSuccess = ref(false);
 // 检测加载状态
 const checkLoading = ref(true);
 
+// 设备状态相关
+const showStatusDialog = ref(false);
+const statusLoading = ref(false);
+const deviceStatus = ref({
+  state_camera_motor: 0,
+  state_camera_steering: 0,
+  state_turntable_steering: 0,
+  state_move_turntable_steering: 0,
+  state_overturn_steering: 0
+});
+
 // 定义事件发射器,用于更新父组件的 modelValue 和触发 confirm 事件
 const emit = defineEmits([ 'confirm']);
 
@@ -194,6 +231,98 @@ function confirm(){
   emit('confirm')
 }
 
+onBeforeUnmount(() => {
+  clientStore.ipc.removeAllListeners(icpList.socket.message + '_get_mcu_info')
+})
+
+// 状态文本映射
+const stateTextMap = {
+  0: "未初始化",
+  1: "运动中",
+  2: "已停止",
+  3: "未在线",
+  4: "堵转"
+}
+
+// 获取状态标签
+function getStatusLabel(key) {
+  const labelMap = {
+    state_camera_motor: '相机高度状态',
+    state_camera_steering: '相机角度状态',
+    state_turntable_steering: '转盘状态',
+    state_move_turntable_steering: '转盘前后移动状态',
+    state_overturn_steering: '翻板状态'
+  }
+  return labelMap[key] || key
+}
+
+// 获取状态文本
+function getStatusText(status) {
+  return stateTextMap[status] || '未知状态'
+}
+
+// 获取状态样式类
+function getStatusClass(status) {
+  const classMap = {
+    0: 'status-uninit',
+    1: 'status-moving',
+    2: 'status-stopped',
+    3: 'status-offline',
+    4: 'status-blocked'
+  }
+  return classMap[status] || 'status-unknown'
+}
+
+// 打开状态对话框
+function openStatusDialog() {
+  showStatusDialog.value = true
+  getDeviceStatus()
+}
+
+// 获取设备状态
+function getDeviceStatus() {
+  statusLoading.value = true
+
+  // 移除之前的监听器
+  clientStore.ipc.removeAllListeners(icpList.socket.message + '_get_mcu_info')
+
+  // 发送获取MCU信息的消息
+  socketStore.sendMessage({
+    type: 'get_mcu_info',
+    data: null
+  })
+
+  // 监听MCU信息响应
+  clientStore.ipc.on(icpList.socket.message + '_get_mcu_info', (event, result) => {
+    console.log('_get_mcu_info')
+    console.log(result)
+    statusLoading.value = false
+
+    if (result.code === 0 && result.data.data_state) {
+      deviceStatus.value = {
+        state_camera_motor: result.data.data_state.state_camera_motor || 0,
+        state_camera_steering: result.data.data_state.state_camera_steering || 0,
+        state_turntable_steering: result.data.data_state.state_turntable_steering || 0,
+        state_move_turntable_steering: result.data.data_state.state_move_turntable_steering || 0,
+        state_overturn_steering: result.data.data_state.state_overturn_steering || 0
+      }
+    } else {
+      ElMessage.error(result.msg || '获取设备状态失败')
+    }
+
+    clientStore.ipc.removeAllListeners(icpList.socket.message + '_get_mcu_info')
+  })
+
+  // 设置超时
+  setTimeout(() => {
+    if (statusLoading.value) {
+      statusLoading.value = false
+      ElMessage.error('获取设备状态超时')
+      clientStore.ipc.removeAllListeners(icpList.socket.message + '_get_mcu_info')
+    }
+  }, 10000)
+}
+
 </script>
 
 
@@ -254,4 +383,53 @@ color: #000000;
     text-align: left;
     color: #FF4C00;
 }
+
+.check-btn-secondary {
+    background: linear-gradient(135deg, #909399 0%, #C0C4CC 100%);
+}
+
+// 设备状态对话框样式
+.status-content {
+  .status-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+    padding: 8px 12px;
+    background: #f5f5f5;
+    border-radius: 4px;
+
+    .status-label {
+      font-weight: 500;
+      min-width: 120px;
+    }
+
+    .status-value {
+      font-weight: bold;
+
+      &.status-uninit {
+        color: #909399;
+      }
+
+      &.status-moving {
+        color: #e6a23c;
+      }
+
+      &.status-stopped {
+        color: #67c23a;
+      }
+
+      &.status-offline {
+        color: #f56c6c;
+      }
+
+      &.status-blocked {
+        color: #f56c6c;
+      }
+
+      &.status-unknown {
+        color: #909399;
+      }
+    }
+  }
+}
 </style>

+ 1 - 3
frontend/src/views/Photography/check.vue

@@ -289,7 +289,7 @@ clientStore.ipc.on(icpList.socket.message+'_run_mcu_single', async (event, resul
     step.value = 2
     loading.value = false;
   }else {
- //   loading.value = false;
+    loading.value = false;
     showVideo()
     if(result.code !== 0 && result.msg) ElMessage.error(result.msg)
   }
@@ -331,8 +331,6 @@ onBeforeUnmount(() => {
   clientStore.ipc.removeAllListeners(icpList.camera.PreviewShow);
   clientStore.ipc.removeAllListeners(icpList.socket.message+'_run_mcu_single');
   clientStore.ipc.removeAllListeners(icpList.socket.message+'_smart_shooter_photo_take');
-
-
 })
 </script>
 <style scoped lang="scss">