diff --git a/gym-manage-uniapp/pages/checkIn/checkIn.vue b/gym-manage-uniapp/pages/checkIn/checkIn.vue index 58d8569..74ce4f5 100644 --- a/gym-manage-uniapp/pages/checkIn/checkIn.vue +++ b/gym-manage-uniapp/pages/checkIn/checkIn.vue @@ -35,7 +35,8 @@ - + + @@ -268,10 +269,13 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' } onLoad(() => { - uni.showLoading({ - title: '生成签到二维码...', - mask: true - }) + // 测试模式下不显示全局loading,让页面内的加载动画显示 + if (!TEST_MODE) { + uni.showLoading({ + title: '生成签到二维码...', + mask: true + }) + } // 测试模式:直接生成假二维码,内容为"欢迎来到活氧舱" if (TEST_MODE) { @@ -315,37 +319,67 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' }) // 测试模式:生成假二维码(内容为"欢迎来到活氧舱") - const generateTestQRCode = () => { - // 使用 canvas 生成简单的二维码图案(模拟) - // 由于无法直接生成真正的二维码图片,使用一个静态图片或占位图 - // 在实际测试环境中,可以使用第三方库生成二维码 + // 不发送请求,使用缓存机制避免重复请求,二维码内容保持不变 + // @param {boolean} isRefresh - 是否是刷新操作(true=点击刷新按钮,false=首次进入页面) + const generateTestQRCode = (isRefresh = false) => { + // 检查是否有缓存的二维码图片 + const cachedQRImage = getCacheData("TestQRImage") + const qrContent = "欢迎来到活氧舱" - // 模拟网络延迟 + if (cachedQRImage) { + // 使用缓存的二维码图片,不发送请求 + console.log("测试模式:使用缓存的二维码图片") + image.value = cachedQRImage.image + width.value = cachedQRImage.width + height.value = cachedQRImage.height + qrcode.value = qrContent + status.value = 'waiting' + QRStatus.value = '请出示二维码签到' + uni.hideLoading() + + // 只有刷新操作才显示提示 + if (isRefresh) { + uni.showToast({ + title: '二维码已刷新', + icon: 'success', + duration: 1500 + }) + } + return + } + + // 首次生成,发送一次请求并缓存 + console.log("测试模式:首次生成二维码,发送请求并缓存") setTimeout(() => { - // 使用一个在线二维码生成服务生成内容为"欢迎来到活氧舱"的二维码 - const qrContent = "欢迎来到活氧舱" qrcode.value = qrContent - // 使用在线API生成二维码图片 - // 注意:实际使用时应该考虑离线方案 const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent(qrContent)}` - // 将在线图片下载为base64(在uniapp中) uni.request({ url: qrUrl, method: 'GET', responseType: 'arraybuffer', success: (res) => { const base64 = uni.arrayBufferToBase64(res.data) - image.value = `data:image/png;base64,${base64}` + const qrImage = `data:image/png;base64,${base64}` + + image.value = qrImage width.value = 500 height.value = 500 status.value = 'waiting' QRStatus.value = '请出示二维码签到' + + // 缓存二维码图片,后续刷新不再请求 + setCacheData("TestQRImage", { + image: qrImage, + width: 500, + height: 500, + content: qrContent + }) + uni.hideLoading() }, fail: () => { - // 如果无法获取在线二维码,使用默认占位图 image.value = '' width.value = 500 height.value = 500 @@ -354,7 +388,7 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' uni.hideLoading() } }) - }, 1000) + }, 500) } // 页面卸载时关闭WebSocket连接(不清除缓存,让缓存自然过期) @@ -401,8 +435,20 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' return } + // 清空图片,显示加载状态 image.value = "" QRStatus.value = "正在刷新二维码..." + + // 测试模式:重新生成二维码,但不发送请求,内容不变 + if (TEST_MODE) { + // 延迟显示,让用户看到刷新效果 + setTimeout(() => { + generateTestQRCode(true) // 传递 isRefresh=true + }, 300) + return + } + + // 非测试模式:正常刷新逻辑 setTimeout(() => { getStorage(null) }, 500) @@ -439,7 +485,13 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' onlyFromCamera: false, scanType: ['qrCode'], success: (res) => { - console.log(res) + console.log('扫码结果:', res) + // 测试模式下,如果扫描的是我们生成的二维码内容,直接模拟签到成功 + if (TEST_MODE && res.result === '欢迎来到活氧舱') { + console.log('测试模式:模拟签到成功') + handleTestModeCheckIn() + return + } checkIn(res.result) }, fail: (err) => { @@ -452,6 +504,28 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' }) } + // 测试模式:模拟签到成功(不请求后端) + const handleTestModeCheckIn = () => { + closeWebSocket() + const now = new Date() + const dateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}` + + status.value = 'scanned' + errorText.value = '' + QRStatus.value = `${dateTime} 成功签到` + isCheckIn.value = true + STQRC.value = true + + setCacheData("checkInTime", QRStatus.value) + setCacheData("isCheckIn", isCheckIn.value) + + uni.showToast({ + title: '签到成功!', + icon: 'success', + duration: 2000 + }) + } + // 手动签到接口 const checkIn = (qrContent) => { console.log(qrContent) @@ -776,7 +850,8 @@ import QrStatus from '@/components/QRCode/StatusCard.vue' align-items: center; margin: 0 auto 64rpx; max-width: 100%; - + min-height: 580rpx; /* 设置最小高度确保加载动画区域可见 */ + .QR { position: relative; z-index: 2; diff --git a/gym-manage-uniapp/pages/searchCourse/searchCourse.vue b/gym-manage-uniapp/pages/searchCourse/searchCourse.vue index 70ffa51..6f3a534 100644 --- a/gym-manage-uniapp/pages/searchCourse/searchCourse.vue +++ b/gym-manage-uniapp/pages/searchCourse/searchCourse.vue @@ -138,7 +138,13 @@ class="course-card" @tap="handleCourseClick(course)" > + + + + + +