import jsQR from '../utils/jsQR'; Page({ data: { // 相机相关配置 cameraContext: null, devicePosition: 'back', // 后置摄像头, 'front' : 'back'; flashMode: 'off', // 闪光灯默认关闭,'off' : 'torch' // 扫码框相关配置 scanBoxWidth: 580, // 扫码框宽度(rpx) scanBoxHeight: 580, // 扫码框高度(rpx) scanLineTop: 0, // 扫描线初始位置 scanLineSpeed: 2, // 扫描线移动速度 // 屏幕适配相关 windowWidth: 375, // 屏幕宽度(rpx) windowHeight: 667, // 屏幕高度(rpx) scanBoxLeft: 0, // 扫码框左侧偏移 scanBoxTop: 0, // 扫码框顶部偏移 isScanning: false, // 扫描状态标记,防止重复扫描 }, // 页面每次显示时(包括跳转返回后)触发 onShow() { // 强制重置扫描状态,避免返回后无法扫码 this.setData({ isScanning: false }); this.scanLock = false; // 同步释放全局锁 }, onLoad(options) { const sis = wx.getWindowInfo(); // 初始化相机上下文 this.setData({ cameraContext: wx.createCameraContext(this), // 获取屏幕尺寸用于适配 windowWidth: 750, windowHeight: sis.windowHeight / sis.windowWidth * 750, }, () => { // 计算扫码框位置(居中显示) this.calcScanBoxPosition(); // 启动扫描线动画 this.startScanLineAnimation(); }); }, // 计算扫码框居中位置 calcScanBoxPosition() { const { windowWidth, windowHeight, scanBoxWidth, scanBoxHeight } = this.data; const scanBoxLeft = (windowWidth - scanBoxWidth) / 2; const scanBoxTop = (windowHeight - scanBoxHeight) / 2 - 100; // 向上偏移100rpx this.setData({ scanBoxLeft, scanBoxTop }); }, // 扫描线动画 startScanLineAnimation() { const { scanBoxHeight, scanLineSpeed } = this.data; let scanLineTop = 0; this.animationInterval = setInterval(() => { scanLineTop += scanLineSpeed; if (scanLineTop >= scanBoxHeight) { scanLineTop = 0; } this.setData({ scanLineTop }); }, 30); }, // 打开/关闭闪光灯 toggleFlash() { this.setData({ flashMode: this.data.flashMode === 'torch' ? 'off' : 'torch', }); }, /** * 扫码结果 * @param {*} e */ handleScanCode(e) { // 记录当前时间戳 const now = Date.now(); // 限制 2 秒内只能处理一次扫码 if (this.lastScanTime && now - this.lastScanTime < 2000) { return; } this.lastScanTime = now; // 双重锁机制确保不会重复处理 if (this.data.isScanning || this.scanLock) { return; } this.setData({ isScanning: true }); this.scanLock = true; console.log("扫码结果123-------", e); // 处理扫码逻辑 this.triggerEvent('scancode', e.detail); this.onCode(e.detail.result) }, /** * 点击跳转到我的二维码页面 * @param {*} e */ goCode(e) { wx.showToast({ title: "跳转到我的二维码页面" }); wx.reLaunch({ url: '/subpackages/qr/qr-code/qr-code', }) }, /** * 手动选择照片后扫码 */ chooseImageFirst() { const that = this; wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['album'], maxDuration: 30, camera: 'back', fail(){ wx.showToast({ title: "请选择二维码" }); }, success(res) { const src = res.tempFiles[0].tempFilePath that.setData({ imgPath :src }) wx.showLoading({ title: '识别中...', }) console.log("图片地址",src); wx.getImageInfo({ src: src, success(res) { console.log("图片信息",res); // 转Canvas像素数据 const canvas = wx.createOffscreenCanvas({ type: '2d', width: res.width, height: res.height }); const canvasCtx = canvas.getContext('2d'); const img = canvas.createImage(); img.onload = () => { canvasCtx.drawImage(img, 0, 0, res.width, res.height); const imageData = canvasCtx.getImageData(0, 0, res.width, res.height); // jsQR识别 const code = jsQR(imageData.data, res.width, res.height); console.log('识别结果', code); if(code){ wx.hideLoading() that.onCode(code.data) }else{ wx.showToast({ title: "未识别到二维码" }); } }; img.src = src; } }) } }) }, /** * 扫码后获得的二维码内容 * @param {*} data */ onCode(data){ try { console.log("扫码结果:", data); if(!data || !data.startsWith('FINDME:')){ wx.showToast({ title: '无效的二维码,这不是FindMe的用户二维码', icon:"none" }) setTimeout(()=>this.setData({imgPath : "" }) ,1500) this.setData({isScanning:false}); this.scanLock = false; // 同步释放全局锁 return } const customId = data.split(':')[1] console.log('dataJson',customId); this.handleCode(customId) } catch (error) { wx.showToast({ title: "无法解析二维码内容"}); console.log("无法解析二维码内容",error); }finally{ this.setData({isScanning:false}); this.scanLock = false; // 同步释放全局锁 } }, async handleCode(customId){ let userInfo = wx.getStorageSync('userInfo'); if(customId == userInfo.customId){ wx.showToast({ title: '不能添加自己为好友', icon:'none' }) setTimeout(()=>this.setData({imgPath : "" }) ,1500) this.setData({isScanning:false}); this.scanLock = false; // 同步释放全局锁 return } // 检查是否是好友关系 await this.checkFriendRelationFromScan(customId); }, // 检查好友关系(从扫码调用) async checkFriendRelationFromScan(customId) { const friendAPI = require('../../../utils/friend-api.js'); wx.showLoading({ title: '加载中...', mask: true }); const friendDetailResponse = await friendAPI.getFriendDetail(customId).catch(() => null); wx.hideLoading(); const isFriend = friendDetailResponse?.code === 0 && friendDetailResponse?.data; this.navigateToUserDetail(customId, isFriend); }, // 跳转到用户详情页面 navigateToUserDetail(customId, isFriend = false) { const url = isFriend ? `/subpackages/social/friend-detail/friend-detail?customId=${customId}` : `/subpackages/social/user-preview/user-preview?customId=${customId}`; wx.navigateTo({ url: url, success: () => { this.setData({ imgPath: "" }); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); this.setData({ imgPath: "",isScanning: false}); this.scanLock = false; // 同步释放全局锁 } }); }, onUnload() { // 页面卸载时停止扫码和动画 if (this.animationInterval) { clearInterval(this.animationInterval); } }, // 授权回调 handleGetUserInfo(e) { if (e.detail.userInfo) { // 授权成功后重新初始化 this.onLoad(); } else { wx.showToast({ title: '需要授权相机权限才能使用扫码功能', icon: 'none' }); } } });