263 lines
8.3 KiB
JavaScript
263 lines
8.3 KiB
JavaScript
|
|
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' });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|