feat(微信): 添加扫码测试页面并重构微信JSSDK初始化逻辑
将微信JSSDK初始化逻辑移至App.vue全局处理 新增wxScanTest页面用于测试微信扫码功能 移除verificationResult.vue中冗余的初始化代码
Showing
4 changed files
with
205 additions
and
24 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2023-06-13 13:26:46 | 2 | * @Date: 2023-06-13 13:26:46 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-12-26 11:07:25 | 4 | + * @LastEditTime: 2026-01-22 14:41:27 |
| 5 | * @FilePath: /xysBooking/src/App.vue | 5 | * @FilePath: /xysBooking/src/App.vue |
| 6 | * @Description: 启动页 | 6 | * @Description: 启动页 |
| 7 | --> | 7 | --> |
| ... | @@ -40,16 +40,35 @@ setToastDefaultOptions({ | ... | @@ -40,16 +40,35 @@ setToastDefaultOptions({ |
| 40 | className: 'zIndex' | 40 | className: 'zIndex' |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | +const init_wx_global = async () => { | ||
| 44 | + try { | ||
| 45 | + const url = window.location.href.split('#')[0] | ||
| 46 | + const cfg_res = await wxJsAPI({ url }) | ||
| 47 | + if (!cfg_res || !cfg_res?.data) return false | ||
| 48 | + | ||
| 49 | + const cfg = { ...cfg_res.data, jsApiList: apiList } | ||
| 50 | + return new Promise((resolve) => { | ||
| 51 | + wx.config(cfg) | ||
| 52 | + wx.ready(() => { | ||
| 53 | + wx.showAllNonBaseMenuItem() | ||
| 54 | + resolve(true) | ||
| 55 | + }) | ||
| 56 | + wx.error((err) => { | ||
| 57 | + console.warn(err) | ||
| 58 | + resolve(false) | ||
| 59 | + }) | ||
| 60 | + }) | ||
| 61 | + } catch (err) { | ||
| 62 | + console.warn(err) | ||
| 63 | + return false | ||
| 64 | + } | ||
| 65 | +} | ||
| 66 | + | ||
| 43 | onMounted(async () => { | 67 | onMounted(async () => { |
| 44 | - // const { data } = await wxJsAPI({ url: '/f/reserve/#/' }); | 68 | + if (!window.__wx_ready_promise) { |
| 45 | - // data.jsApiList = apiList; | 69 | + window.__wx_ready_promise = init_wx_global() |
| 46 | - // wx.config(data); | 70 | + } |
| 47 | - // wx.ready(() => { | 71 | + await window.__wx_ready_promise |
| 48 | - // wx.showAllNonBaseMenuItem(); | ||
| 49 | - // }); | ||
| 50 | - // wx.error((err) => { | ||
| 51 | - // console.warn(err); | ||
| 52 | - // }); | ||
| 53 | // 正式环境 | 72 | // 正式环境 |
| 54 | // TAG:检查是否更新 | 73 | // TAG:检查是否更新 |
| 55 | if (import.meta.env.PROD) { | 74 | if (import.meta.env.PROD) { | ... | ... |
| ... | @@ -137,4 +137,11 @@ export default [ | ... | @@ -137,4 +137,11 @@ export default [ |
| 137 | title: '核销', | 137 | title: '核销', |
| 138 | }, | 138 | }, |
| 139 | }, | 139 | }, |
| 140 | + { | ||
| 141 | + path: '/wxScanTest', | ||
| 142 | + component: () => import('@/views/wxScanTest.vue'), | ||
| 143 | + meta: { | ||
| 144 | + title: '扫码测试', | ||
| 145 | + }, | ||
| 146 | + }, | ||
| 140 | ]; | 147 | ]; | ... | ... |
| ... | @@ -71,8 +71,6 @@ import { computed, onMounted, ref, watch } from 'vue' | ... | @@ -71,8 +71,6 @@ import { computed, onMounted, ref, watch } from 'vue' |
| 71 | import { useRoute, useRouter } from 'vue-router' | 71 | import { useRoute, useRouter } from 'vue-router' |
| 72 | import wx from 'weixin-js-sdk' | 72 | import wx from 'weixin-js-sdk' |
| 73 | import { showToast } from 'vant' | 73 | import { showToast } from 'vant' |
| 74 | -import { apiList } from '@/api/wx/jsApiList' | ||
| 75 | -import { wxJsAPI } from '@/api/wx/config' | ||
| 76 | import { mainStore } from '@/store' | 74 | import { mainStore } from '@/store' |
| 77 | import { checkRedeemPermissionAPI, verifyTicketAPI } from '@/api/redeem' | 75 | import { checkRedeemPermissionAPI, verifyTicketAPI } from '@/api/redeem' |
| 78 | import { wxInfo } from '@/utils/tools' | 76 | import { wxInfo } from '@/utils/tools' |
| ... | @@ -164,19 +162,8 @@ const verify_ticket = async (code) => { | ... | @@ -164,19 +162,8 @@ const verify_ticket = async (code) => { |
| 164 | verify_info.value = {} | 162 | verify_info.value = {} |
| 165 | } | 163 | } |
| 166 | 164 | ||
| 167 | -const init_wx_scan = async () => { | ||
| 168 | - const cfg_res = await wxJsAPI({ url: window.location.href.split('#')[0] }) | ||
| 169 | - if (!cfg_res || cfg_res?.code !== 1 || !cfg_res?.data) return false | ||
| 170 | - const cfg = { ...cfg_res.data, jsApiList: apiList } | ||
| 171 | - return new Promise((resolve) => { | ||
| 172 | - wx.config(cfg) | ||
| 173 | - wx.ready(() => resolve(true)) | ||
| 174 | - wx.error(() => resolve(false)) | ||
| 175 | - }) | ||
| 176 | -} | ||
| 177 | - | ||
| 178 | const scan_in_wechat = async () => { | 165 | const scan_in_wechat = async () => { |
| 179 | - const ok = await init_wx_scan() | 166 | + const ok = await window.__wx_ready_promise |
| 180 | if (!ok) return '' | 167 | if (!ok) return '' |
| 181 | return new Promise((resolve) => { | 168 | return new Promise((resolve) => { |
| 182 | wx.scanQRCode({ | 169 | wx.scanQRCode({ | ... | ... |
src/views/wxScanTest.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="scan-test-page"> | ||
| 3 | + <div class="card"> | ||
| 4 | + <div class="row"> | ||
| 5 | + <div class="label">环境</div> | ||
| 6 | + <div class="value">{{ in_wechat ? '微信内' : '非微信' }}</div> | ||
| 7 | + </div> | ||
| 8 | + <div class="row last"> | ||
| 9 | + <div class="label">JSSDK</div> | ||
| 10 | + <div class="value" :class="{ ok: wx_ready === true, fail: wx_ready === false }"> | ||
| 11 | + {{ wx_ready_text }} | ||
| 12 | + </div> | ||
| 13 | + </div> | ||
| 14 | + </div> | ||
| 15 | + | ||
| 16 | + <div class="card"> | ||
| 17 | + <div class="card-title">扫码结果</div> | ||
| 18 | + <van-field | ||
| 19 | + v-model="scan_result" | ||
| 20 | + type="textarea" | ||
| 21 | + rows="3" | ||
| 22 | + autosize | ||
| 23 | + readonly | ||
| 24 | + placeholder="点击下方按钮开始扫码" | ||
| 25 | + /> | ||
| 26 | + <div class="btn-wrap"> | ||
| 27 | + <van-button | ||
| 28 | + block | ||
| 29 | + color="#A67939" | ||
| 30 | + :loading="scanning" | ||
| 31 | + :disabled="scanning" | ||
| 32 | + @click="start_scan" | ||
| 33 | + > | ||
| 34 | + 调起扫码 | ||
| 35 | + </van-button> | ||
| 36 | + </div> | ||
| 37 | + </div> | ||
| 38 | + </div> | ||
| 39 | +</template> | ||
| 40 | + | ||
| 41 | +<script setup> | ||
| 42 | +import { computed, onMounted, ref } from 'vue' | ||
| 43 | +import wx from 'weixin-js-sdk' | ||
| 44 | +import { showToast } from 'vant' | ||
| 45 | +import { wxInfo } from '@/utils/tools' | ||
| 46 | + | ||
| 47 | +const scan_result = ref('') | ||
| 48 | +const scanning = ref(false) | ||
| 49 | +const wx_ready = ref(null) | ||
| 50 | + | ||
| 51 | +const in_wechat = computed(() => wxInfo().isTable === true) | ||
| 52 | + | ||
| 53 | +const wx_ready_text = computed(() => { | ||
| 54 | + if (!in_wechat.value) return '非微信环境无需初始化' | ||
| 55 | + if (wx_ready.value === true) return '已就绪' | ||
| 56 | + if (wx_ready.value === false) return '初始化失败' | ||
| 57 | + return '未检测' | ||
| 58 | +}) | ||
| 59 | + | ||
| 60 | +const ensure_wx_ready = async () => { | ||
| 61 | + if (!window.__wx_ready_promise) return false | ||
| 62 | + const ok = await window.__wx_ready_promise | ||
| 63 | + return ok === true | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +const start_scan = async () => { | ||
| 67 | + if (!in_wechat.value) { | ||
| 68 | + showToast('请在微信内打开该页面') | ||
| 69 | + return | ||
| 70 | + } | ||
| 71 | + if (scanning.value) return | ||
| 72 | + | ||
| 73 | + scanning.value = true | ||
| 74 | + try { | ||
| 75 | + const ok = await ensure_wx_ready() | ||
| 76 | + wx_ready.value = ok | ||
| 77 | + if (!ok) { | ||
| 78 | + showToast('wx 初始化失败') | ||
| 79 | + return | ||
| 80 | + } | ||
| 81 | + const result = await new Promise((resolve) => { | ||
| 82 | + wx.scanQRCode({ | ||
| 83 | + needResult: 1, | ||
| 84 | + scanType: ['qrCode', 'barCode'], | ||
| 85 | + success: (res) => resolve(res?.resultStr || ''), | ||
| 86 | + fail: () => resolve(''), | ||
| 87 | + cancel: () => resolve(''), | ||
| 88 | + }) | ||
| 89 | + }) | ||
| 90 | + scan_result.value = String(result || '') | ||
| 91 | + if (!scan_result.value) showToast('未获取到二维码内容') | ||
| 92 | + } finally { | ||
| 93 | + scanning.value = false | ||
| 94 | + } | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +onMounted(async () => { | ||
| 98 | + if (!in_wechat.value) { | ||
| 99 | + wx_ready.value = false | ||
| 100 | + return | ||
| 101 | + } | ||
| 102 | + wx_ready.value = await ensure_wx_ready() | ||
| 103 | +}) | ||
| 104 | +</script> | ||
| 105 | + | ||
| 106 | +<style lang="less" scoped> | ||
| 107 | +.scan-test-page { | ||
| 108 | + min-height: 100vh; | ||
| 109 | + background-color: #F6F6F6; | ||
| 110 | + padding: 16px; | ||
| 111 | + box-sizing: border-box; | ||
| 112 | + | ||
| 113 | + .card { | ||
| 114 | + background: #fff; | ||
| 115 | + border-radius: 12px; | ||
| 116 | + padding: 16px; | ||
| 117 | + box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + .card + .card { | ||
| 121 | + margin-top: 12px; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + .card-title { | ||
| 125 | + font-size: 14px; | ||
| 126 | + color: #6B7280; | ||
| 127 | + margin-bottom: 12px; | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + .row { | ||
| 131 | + display: flex; | ||
| 132 | + align-items: center; | ||
| 133 | + justify-content: space-between; | ||
| 134 | + padding: 10px 0; | ||
| 135 | + border-bottom: 1px solid #F3F4F6; | ||
| 136 | + | ||
| 137 | + .label { | ||
| 138 | + font-size: 14px; | ||
| 139 | + color: #6B7280; | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + .value { | ||
| 143 | + font-size: 16px; | ||
| 144 | + color: #111827; | ||
| 145 | + font-weight: 600; | ||
| 146 | + margin-left: 12px; | ||
| 147 | + word-break: break-all; | ||
| 148 | + text-align: right; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + .ok { | ||
| 152 | + color: #16A34A; | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + .fail { | ||
| 156 | + color: #E24A4A; | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + .row.last { | ||
| 161 | + border-bottom: 0; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + .btn-wrap { | ||
| 165 | + margin-top: 12px; | ||
| 166 | + } | ||
| 167 | +} | ||
| 168 | +</style> |
-
Please register or login to post a comment