瀏覽代碼

优化扫描仪连接机制逻辑

dengshaobo 1 月之前
父節點
當前提交
ab44b7fbbd
共有 2 個文件被更改,包括 120 次插入86 次删除
  1. 18 2
      src/utils/scanCommon.ts
  2. 102 84
      src/views/exam/question.vue

+ 18 - 2
src/utils/scanCommon.ts

@@ -38,12 +38,16 @@ class ScanCommonService {
   private intervalClose: number = 5000; // 等待5秒未收到pong则判定断开
   
   private isManuallyStopped: boolean = false; // 是否手动停止,防止重复连接
+  private scanCallback: ScanCallback | null = null;//传入的回调函数
 
   /**
    * 初始化 WebSocket 连接
    * @param callback - 接收扫描结果的回调函数
    */
   init(callback?: ScanCallback): void {
+    if (callback) {
+      this.scanCallback = callback;
+    }
     // 如果已经连接且未手动停止,不重复初始化
     if (this.ws && this.ws.readyState === WebSocket.OPEN && !this.isManuallyStopped) {
       return;
@@ -123,11 +127,23 @@ class ScanCommonService {
                 }
               } else {
                 // 其他业务数据回调
-                if (callback) callback(objectData);
+                if (this.scanCallback) this.scanCallback(objectData);
               }
             } else {
               // 未检测到纸张或卡纸
-              if (callback) callback(objectData);
+              
+              console.log("未检测到纸张或者卡纸:", callback);
+              if (this.scanCallback)
+              {
+                this.scanCallback(objectData);
+              } 
+              else
+              {
+                ElMessage({
+                  type: 'error',
+                  message: '未检测到纸张或者卡纸'
+                });
+              }
             }
             
           } catch (error) {

+ 102 - 84
src/views/exam/question.vue

@@ -3,7 +3,7 @@
     <div class="question_header">
         <div class="item_title">
             <div class="item_step">1</div>
-            扫描标准答案:<el-button type="primary"  @click="GotoScan()" :loading="scanLoading" style="width: 88px;">开始扫描</el-button>  
+            扫描标准答案:<el-button type="primary"  @click="GotoScan()" :loading="scanLoading" style="width: 88px;">{{scanText}}</el-button>  
             <!-- <span class="preview_btn">预览</span> -->
             <!-- <el-button style="margin-left: 10px;width: 116px;">引用试题结构</el-button> -->
         </div>
@@ -201,6 +201,7 @@ const queryParams= ref({
 })
 
 const templateName=ref('机读卡');
+const scanText=ref('开始扫描');
 const templateQuestionCount=ref(0);//模板题目总数量
 const showChooseTemplate=ref(false);// 弹出选择模板的弹窗
 const tableData = ref<QuestionItem[]>([])
@@ -217,6 +218,7 @@ const examSubjectCode=ref('');//扫描答案的科目编号
 const showScanAnswer=ref(false);//扫描答案预览
 const imageFilesList=ref<any[]>([]);//扫描答案的图片列表
 const scanAnswerLoading=ref(false);//确定扫描答案loading
+const scanClientConnected=ref(false);//扫描客户端的连接状态
 // 考试科目 ID
 const examSubjectId = computed(() => {
   return examStore.currentExam?.id
@@ -436,93 +438,21 @@ const EditorSingle=(item:any)=>{
 // 打开扫描仪器
 const GotoScan = useThrottleFn(() => {
 //   showSelectType.value = 'scan';
-  scanLoading.value = true;
-//   showScanAnswer.value=true;
-  StartScan();
+    console.log("打印打开扫描仪器",scanCommon.isClientConnected())
+    if (!scanClientConnected.value) {
+        ElMessage.warning('请先打开扫描客户端');
+        return;
+    }
+  
+    scanLoading.value = true;
+    scanText.value='扫描中...';
+    //   showScanAnswer.value=true;
+    StartScan();
 }, 5000);
 
 // 启动扫描
 const StartScan = () => {
-    scanCommon.init(async (res:any) => {
-        console.log("打印扫描返回的res", res);
-
-        if (res.action === 'scanTemplate') {
-            const img = new Image();
-            img.crossOrigin = 'Anonymous';
-
-            img.onload = () => {
-                console.log('图片宽度:', img.width);
-                console.log('图片高度:', img.height);
-
-                const paperInfo = {
-                    width: img.width,
-                    height: img.height
-                };
-
-                // 创建 canvas 来获取图片数据并转换为 File 对象
-                const canvas = document.createElement('canvas');
-                canvas.width = img.width;
-                canvas.height = img.height;
-                const ctx = canvas.getContext('2d');
-                console.log("加载图片ctx", ctx);
-                if (ctx) {
-                    ctx.drawImage(img, 0, 0);
-
-                    canvas.toBlob(async (blob) => {
-                        if (blob) {
-                            // 创建 File 对象
-                            const file = new File([blob], res.name, {
-                                type: blob.type || 'image/jpeg'
-                            });
-
-                            // 创建预览 URL
-                            const imageUrl = URL.createObjectURL(file);
-
-                            const fileObj = {
-                                url: imageUrl,
-                                file: file,
-                                name: res.name,
-                                pageInfo: JSON.stringify(paperInfo),
-                                rotateAngle: 0
-                            };
-
-                            // 更新响应式数据
-                            imageFilesList.value.push(fileObj);
-                            showScanAnswer.value=true;
-                            // paperInfoStr.value = JSON.stringify(paperInfo); // 假设你有一个 ref 叫 paperInfoStr
-                            console.log("打印 imageFilesList", imageFilesList.value);
-                            scanLoading.value = false;
-                        }
-                    }, 'image/jpeg');
-                } else {
-                    ElMessage.error('无法获取画布上下文');
-                    scanLoading.value = false;
-                }
-            };
-
-            img.onerror = (error) => {
-                console.error('图片加载失败:', error);
-                ElMessage.error('图片加载失败');
-                scanLoading.value = false;
-            };
-
-            img.src = res.url;
-            
-        }
-
-        if (res.action === 'startScanTemplate') {
-            if (res.code === 502) {
-
-                scanLoading.value = false;
-                ElMessage.error(res.msg);
-
-            }
-
-            if (res.code === 200) {
-                ElMessage.success("扫描仪启动成功");
-            }
-        }
-    }); // 跟扫描仪插件 websocket 连接
+    scanCommon.init(HandleScanResult); // 跟扫描仪插件 websocket 连接
 
     console.log("打印 VUE_APP_BASE_API", import.meta.env.VITE_APP_BASE_API); // Vue3/Vite 环境变量获取方式
     console.log("打印上传图片地址", uploadUrl.value);
@@ -620,12 +550,100 @@ const EnterSetQuestion=()=>{
     })
 }
 
+//扫描结果回调处理函数
+const HandleScanResult=(res:any)=>{ 
+    console.log("打印扫描返回的res", res);
+
+    if (res.action === 'scanTemplate') {
+        const img = new Image();
+        img.crossOrigin = 'Anonymous';
+
+        img.onload = () => {
+            console.log('图片宽度:', img.width);
+            console.log('图片高度:', img.height);
+
+            const paperInfo = {
+                width: img.width,
+                height: img.height
+            };
+
+            // 创建 canvas 来获取图片数据并转换为 File 对象
+            const canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            const ctx = canvas.getContext('2d');
+            console.log("加载图片ctx", ctx);
+            if (ctx) {
+                ctx.drawImage(img, 0, 0);
+
+                canvas.toBlob(async (blob) => {
+                    if (blob) {
+                        // 创建 File 对象
+                        const file = new File([blob], res.name, {
+                            type: blob.type || 'image/jpeg'
+                        });
+
+                        // 创建预览 URL
+                        const imageUrl = URL.createObjectURL(file);
+
+                        const fileObj = {
+                            url: imageUrl,
+                            file: file,
+                            name: res.name,
+                            pageInfo: JSON.stringify(paperInfo),
+                            rotateAngle: 0
+                        };
+
+                        // 更新响应式数据
+                        imageFilesList.value.push(fileObj);
+                        showScanAnswer.value=true;
+                        console.log("打印 imageFilesList", imageFilesList.value);
+                        scanLoading.value = false;
+                        scanText.value='开始扫描';
+                    }
+                }, 'image/jpeg');
+            } else {
+                ElMessage.error('无法获取画布上下文');
+                scanLoading.value = false;
+                scanText.value='开始扫描';
+            }
+        };
+
+        img.onerror = (error) => {
+            console.error('图片加载失败:', error);
+            ElMessage.error('图片加载失败');
+            scanLoading.value = false;
+            scanText.value='开始扫描';
+        };
+
+        img.src = res.url;
+        
+    }
+
+    if (res.action === 'startScanTemplate') {
+        if (res.code === 502) {
+            scanLoading.value = false;
+            scanText.value='开始扫描';
+            ElMessage.error(res.msg);
+        }
+
+        if (res.code === 200) {
+            ElMessage.success("扫描仪启动成功");
+        }
+    }
+}
+
 onMounted(() => {
   
     if (!examStore.currentExam) {
         console.warn('当前没有选中的考试信息')
         // 可选:如果没有数据,可以重定向回列表页或提示用户
     }
+    scanCommon.init(HandleScanResult);
+    scanCommon.watchConnection((isOnline, clientVersion) => {
+        scanClientConnected.value = isOnline;
+        // console.log('扫描客户端连接状态:', isOnline, '版本号:', clientVersion);
+    });
     GetSmartQuestionList();
     GetTemplateInfo();
     // 初始化计算