Forráskód Böngészése

fix(photography): 解决点位选择和拍照状态管理问题

- 添加刷新点位按钮,解决设置页修改相机配置后点位列表无法更新的问题
- 实现点位自动校验和回退功能,当选中的点位不再可用时自动切换到第一个可用点位
- 添加硬件检测确认回调,当设备断连时强制释放锁定的UI状态并重置拍照加载状态
- 优化点位变更事件触发逻辑,确保预览按最新点位正确刷新
- 修复resetStatus方法中缺少takePictureLoading重置的问题
panqiuyao 3 hete
szülő
commit
c633a9e3d8

+ 31 - 0
frontend/src/views/Photography/components/editRow.vue

@@ -15,6 +15,7 @@
         <el-select v-model="editRowData.point_name" placeholder="请选择点位" style="width: 170px;" @focus="refreshPointList">
           <el-option v-for="point in availablePoints" :key="point" :label="'点位 ' + point" :value="point"/>
         </el-select>
+        <el-button size="small" plain style="margin-left: 8px;" @click="onRefreshPointList" v-log="{ describe: { action: '点击刷新点位列表' } }">刷新点位</el-button>
       </el-form-item>
 
       <!-- 多相机模式 - 仅拍照模式 -->
@@ -123,6 +124,7 @@ const isMultiCameraMode = computed(() => userInfoStore.isMultiCameraMode)
 const availablePoints = ref<string[]>(['A'])
 
 // 刷新点位列表(从 getAllUserConfigs API 获取已绑定相机的点位)
+// 同时会校验当前选中的点位:若该点位已不再可用,自动回退到第一个可用点位
 const refreshPointList = async () => {
   try {
     const result = await getAllUserConfigs({})
@@ -139,6 +141,35 @@ const refreshPointList = async () => {
   if (availablePoints.value.length === 0) {
     availablePoints.value = ['A']
   }
+
+  // 若当前选中的点位已经不在可用列表里(例如在设置页修改相机配置后),
+  // 自动回退到第一个可用点位,避免下拉框停留在一个无效值上
+  if (
+    isMultiCameraMode.value &&
+    initStatus.value &&
+    editRowData.value.point_name &&
+    !availablePoints.value.includes(editRowData.value.point_name)
+  ) {
+    editRowData.value.point_name = availablePoints.value[0]
+    ElMessage.warning(`原点位相机不可用,已自动切换到点位 ${availablePoints.value[0]}`)
+  }
+}
+
+/**
+ * 点击「刷新点位」按钮:重新拉取点位列表,并强制通知父组件按当前选中的点位刷新预览。
+ * 解决:在设置页修改相机配置后,因 el-select 单选项不展开 / @focus 不触发,
+ *       导致 availablePoints 无法更新、当前点位可能已无效。
+ */
+const onRefreshPointList = async () => {
+  const previousPoint = editRowData.value.point_name
+  await refreshPointList()
+  // 即便点位没变也 emit 一次,确保父组件预览按最新点位重新打开
+  // (watch 监听 point_name 在新旧值相同时不会触发,这里手动补一次)
+  if (editRowData.value.point_name) {
+    emit('onPointChange', editRowData.value.point_name)
+  } else if (previousPoint !== editRowData.value.point_name && availablePoints.value[0]) {
+    emit('onPointChange', availablePoints.value[0])
+  }
 }
 
 // 定义 props

+ 2 - 0
frontend/src/views/Photography/mixin/usePhotography.ts

@@ -415,6 +415,7 @@ export default function usePhotography() {
 
     const resetStatus = () => {
       runLoading.value = false;
+      takePictureLoading.value = false;
       reNosObj.value.goods_art_no = ''
       reNosObj.value.action = ''
       runAction.value.goods_art_no = '';
@@ -984,6 +985,7 @@ const onRemoteControl = async (type) => {
       onGenerateCLick,
       initEventListeners,
       cleanupEventListeners,
+      resetStatus,
     }
 }
 

+ 12 - 2
frontend/src/views/Photography/shot.vue

@@ -6,7 +6,7 @@
       :menu="menu"
   />
 
-  <hardware-check/>
+  <hardware-check @confirm="onHardwareCheckConfirm"/>
 
   <div class="photography-page flex-col">
     <div class="main-container">
@@ -223,7 +223,7 @@ import RemoteControl from '@/views/RemoteControl/index.vue'
 import usePhotography from './mixin/usePhotography'
 import { useThumbnails } from './composables/useThumbnails'
 import generate from '@/utils/menus/generate'
-import { ElMessageBox } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
 
 const {
   loading,
@@ -250,6 +250,7 @@ const {
   onGenerateCLick,
   initEventListeners,
   cleanupEventListeners,
+  resetStatus,
   pageSize,
   currentPage,
   totalPages,
@@ -364,6 +365,15 @@ const handleDeleteAll = async () => {
   }
 }
 
+// 硬件检测通过后的回调:若拍照正在进行中但设备已断连(socket 丢失响应),强制释放锁定的 UI 状态
+const onHardwareCheckConfirm = () => {
+  // runLoading 为 true 说明正在执行 run_mcu 但没有收到停止/完成回调
+  if (runLoading.value || takePictureLoading.value) {
+    ElMessage.warning('检测通过,拍照流程已终止,请重新启动拍摄')
+    resetStatus()
+  }
+}
+
 // 获取预览图片列表(只包含有图片路径的,保持原始顺序)
 const getPreviewImageList = (item: any) => {
   if (!item || !item.items) return []