浏览代码

局域网——用户扫码登录后返回信息

XW 4 月之前
父节点
当前提交
1905fc09f0

+ 1 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/ClientApp/package.json

@@ -10,6 +10,7 @@
   "dependencies": {
     "@azure/storage-blob": "^12.26.0",
     "@fingerprintjs/fingerprintjs": "^4.5.1",
+    "@microsoft/signalr": "^8.0.7",
     "axios": "^1.7.9",
     "clean-webpack-plugin": "^4.0.0",
     "compression-webpack-plugin": "^11.1.0",

+ 68 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/ClientApp/src/utils/signalR.js

@@ -0,0 +1,68 @@
+import * as signalR from '@microsoft/signalr'
+
+export default class SignalRService {
+    // option 为调用 SignalRService 类传进来的参数
+    constructor(option) {
+        // 初始化 SignalR 连接对象为 null
+        this.connection = null
+        // 初始化重试次数为 0
+        this.retryCount = 0
+        // 最大重试次数
+        this.maxRetryAttempts = 5
+        // 重试间隔(毫秒)
+        this.retryInterval = 5000
+    }
+
+    // 初始化 SignalR 连接的方法
+    initSignalR(url) {
+        // 创建 SignalR 连接对象,并指定后端的 url
+        this.connection = new signalR.HubConnectionBuilder().withUrl(url).configureLogging(signalR.LogLevel.Information).build()
+
+        // 调用启动连接的方法
+        this.startConnection()
+    }
+
+    // 实际启动连接的方法
+    startConnection() {
+        // 尝试启动连接
+        this.connection.start().then(() => {
+            // 连接成功,打印日志并重置重试次数
+            console.log('Connected to SignalR successfully!');
+            this.retryCount = 0
+        }).catch(err => {
+            // 连接失败,打印错误日志
+            console.error('Error connecting to SignalR:', err);
+            // 如果重试次数 < 最大重试次数
+            if(this.retryCount < this.maxRetryAttempts) {
+                // 设置一个定时器,在指定间隔后重试连接,并增加重试次数
+                setTimeout(() => {
+                    this.retryCount++
+                    this.startConnection()
+                }, this.retryInterval)
+            }
+        })
+    }
+
+    // 用于注册消息接收回调函数的方法
+    onMessageReceived(callback) {
+        // .net 在连接对象上注册消息接收事件的回调函数
+        this.connection.on("ReceiveMessage", callback)
+
+        // java 在连接对象上注册消息接收事件的回调函数
+        // this.connection.on('message', callback)
+    }
+
+    onReceiveConnection(callback) {
+        this.connection.on('ReceiveConnection', callback)
+    }
+
+    // 停止 SignalR 连接的方法
+    stopSignalR() {
+        // 如果存在连接对象
+        if(this.connection) {
+            // 停止连接,并打印日志
+            this.connection.stop()
+            console.log('Disconnected from SignalR.');
+        }
+    }
+}

+ 33 - 6
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/ClientApp/src/view/login/Admin.vue

@@ -25,9 +25,9 @@
                     <div class="right-input" v-show="isQRCode">
                         <h1 style="margin-bottom: 20px;">HiTA扫码登录</h1>
                         <div style="text-align: center;">
-                            <img :src="qrCodeImg" alt="" style="width: 230px;">
+                            <img :src="qrCodeImg.qrcode" alt="" style="width: 230px;">
                         </div>
-                        <el-button type="primary" size="medium" @click="showPrivacy('qrcode')">登录</el-button>
+                        <el-button type="primary" size="medium" v-show="qrCodeToken" @click="showPrivacy('qrcode')">扫码成功,请登录</el-button>
                     </div>
                     <!-- 未联网时使用 -->
                     <div style="display: flex; justify-content: space-between;">
@@ -125,7 +125,7 @@
 </template>
 
 <script>
-import { h } from 'vue';
+import SignalRService from '@/utils/signalR';
 
 export default {
     data() {
@@ -138,7 +138,7 @@ export default {
             hybridType: 0, //是否连接云端服务器
             isDeviceDrawer: false,
             deviceInfo: undefined,
-            qrCodeImg: '',
+            qrCodeImg: {qrcode: ''},
             isBindSchool: false,
             schoolInfo: {
                 id: '',
@@ -147,6 +147,8 @@ export default {
             isPrivacy: false,
             schoolList: [],
             loginType: '',
+            signalR: null,
+            qrCodeToken: undefined,
         }
     },
     mounted() {
@@ -206,7 +208,8 @@ export default {
                             type: 'success'
                         });
                     } else {
-                        this.qrCodeImg = res.qrcode
+                        this.qrCodeImg = res
+                        this.createConn()
                     }
                 }
             })
@@ -231,7 +234,7 @@ export default {
                 params.pin_code = this.loginForm.smspin
                 params.account = `+86-${this.loginForm.phone}`
             } else if(type === 'qrcode') {
-                params.randomCode = ''
+                params.randomCode = this.qrCodeImg.randomCode
             }
             this.$api.loginCheck(params).then(res => {
                 if(res.code === 200) {
@@ -276,6 +279,7 @@ export default {
                     res.data.server.cpuInfos.forEach(item => {
                         item.showHZ = item.hz ? (item.hz / 1000) : 0
                     });
+                    localStorage.setItem('deviceId', res.data.device)
                     this.deviceInfo = res.data
                     this.hybridType = res.data?.hybrid
                     this.isBindSchool = false
@@ -291,12 +295,35 @@ export default {
                 }
             })
         },
+        createConn() {
+            /* 
+                grant_type取值:
+                public static readonly string _Message_grant_type_check_file = "check_file"; //检查文件
+                public static readonly string _Message_grant_type_ies_qrcode_login = "ies_qrcode_login"; //二维码扫描登陆
+                public static readonly string _Message_grant_type_download_file = "download_file"; //下载评测试卷
+                public static readonly string _Message_grant_type_upload_data = "upload_data"; //推送学生作答
+            */
+            this.signalR = new SignalRService()
+            this.signalR.initSignalR(`/signalr/exam?grant_type=ies_qrcode_login&clientid=${this.deviceInfo.device}`)
+            this.signalR.onReceiveConnection((message) => {
+                console.log('222222222', message);
+            })
+            this.signalR.onMessageReceived((message) => {
+                // status: -1 error(红),0 info(黑、白),1 success(绿),2 warning(黄)
+                if(message.status === 1) {
+                    this.qrCodeToken = JSON.parse(message.content)
+                }
+            })
+        },
     },
     computed: {
         bindSchoolType() {
             return !!this.deviceInfo?.server.school
         },
     },
+    beforeDestroy() {
+        this.signalR.stopSignalR()
+    },
 }
 </script>