hookehuyr

fix(auth): 优化授权逻辑和离线数据存储

重构授权检查函数从 needAuth 改为 hasAuth 以更清晰表达意图
优化离线数据存储结构,只保存必要字段
简化网络状态检查和预加载逻辑
1 /* 1 /*
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-08 19:36:25 4 + * @LastEditTime: 2026-01-12 23:48:04
5 * @FilePath: /xyxBooking-weapp/src/app.js 5 * @FilePath: /xyxBooking-weapp/src/app.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -9,7 +9,7 @@ import { createApp } from 'vue' ...@@ -9,7 +9,7 @@ import { createApp } from 'vue'
9 import { createPinia } from 'pinia' 9 import { createPinia } from 'pinia'
10 import './utils/polyfill' 10 import './utils/polyfill'
11 import './app.less' 11 import './app.less'
12 -import { saveCurrentPagePath, needAuth, silentAuth, navigateToAuth } from '@/utils/authRedirect' 12 +import { saveCurrentPagePath, hasAuth, silentAuth, navigateToAuth } from '@/utils/authRedirect'
13 import Taro from '@tarojs/taro' 13 import Taro from '@tarojs/taro'
14 import { qrcodeListAPI } from '@/api/index' 14 import { qrcodeListAPI } from '@/api/index'
15 import { formatDatetime } from '@/utils/tools' 15 import { formatDatetime } from '@/utils/tools'
...@@ -59,14 +59,23 @@ const App = createApp({ ...@@ -59,14 +59,23 @@ const App = createApp({
59 const { code, data } = await qrcodeListAPI(); 59 const { code, data } = await qrcodeListAPI();
60 if (code && data) { 60 if (code && data) {
61 data.forEach(item => { 61 data.forEach(item => {
62 - item.qr_code_url = '/admin?m=srv&a=get_qrcode&key=' + item.qr_code;
63 item.datetime = formatDatetime({ begin_time: item.begin_time, end_time: item.end_time }) 62 item.datetime = formatDatetime({ begin_time: item.begin_time, end_time: item.end_time })
64 item.sort = 0; 63 item.sort = 0;
65 }); 64 });
66 const validData = data.filter(item => item.qr_code !== ''); 65 const validData = data.filter(item => item.qr_code !== '');
67 if (validData.length > 0) { 66 if (validData.length > 0) {
68 const processed = formatGroup(validData); 67 const processed = formatGroup(validData);
69 - Taro.setStorageSync('OFFLINE_QR_DATA', processed); 68 + const offline_data = processed.map(item => ({
69 + name: item.name,
70 + id_number: item.id_number,
71 + qr_code: item.qr_code,
72 + begin_time: item.begin_time,
73 + end_time: item.end_time,
74 + datetime: item.datetime,
75 + pay_id: item.pay_id,
76 + sort: item.sort,
77 + }));
78 + Taro.setStorageSync('OFFLINE_QR_DATA', offline_data);
70 } else { 79 } else {
71 Taro.removeStorageSync('OFFLINE_QR_DATA'); 80 Taro.removeStorageSync('OFFLINE_QR_DATA');
72 } 81 }
...@@ -77,47 +86,58 @@ const App = createApp({ ...@@ -77,47 +86,58 @@ const App = createApp({
77 }; 86 };
78 87
79 /** 88 /**
80 - * 检查网络状态并预加载二维码数据 89 + * 监听网络状态变化
81 - * - 仅在有网络连接时调用 90 + * - 当网络连接且有授权时,调用 preloadQrData 预加载二维码数据
91 + */
92 + Taro.onNetworkStatusChange((res) => {
93 + if (res.isConnected && hasAuth()) {
94 + preloadQrData()
95 + }
96 + })
97 +
98 + const is_usable_network = (network_type) => {
99 + return ['wifi', '4g', '5g', '3g'].includes(network_type)
100 + }
101 +
102 + /**
103 + * 尝试在网络可用时预加载二维码数据
104 + * - 仅在有授权时调用
82 * - 成功后将数据存储到本地缓存(key: OFFLINE_QR_DATA) 105 * - 成功后将数据存储到本地缓存(key: OFFLINE_QR_DATA)
83 * - 失败则移除缓存 106 * - 失败则移除缓存
107 + * @returns {Promise<void>}
84 */ 108 */
85 - const checkNetworkAndPreload = () => { 109 + const try_preload_when_online = () => {
110 + if (!hasAuth()) return
86 Taro.getNetworkType({ 111 Taro.getNetworkType({
87 success: (res) => { 112 success: (res) => {
88 - const isConnected = ['wifi', '4g', '5g', '3g'].includes(res.networkType); 113 + if (is_usable_network(res.networkType)) {
89 - if (isConnected) { 114 + preloadQrData()
90 - preloadQrData();
91 } 115 }
92 } 116 }
93 - }); 117 + })
94 - }; 118 + }
95 119
96 /** 120 /**
97 - * 监听网络状态变化 121 + * 尝试在有授权时预加载二维码数据
98 - * - 网络连接时预加载二维码数据 122 + * - 若无授权,则尝试静默授权
123 + * - 授权成功后调用 try_preload_when_online 预加载数据
124 + * - 授权失败则跳转至授权页面
99 */ 125 */
100 - Taro.onNetworkStatusChange((res) => { 126 + if (hasAuth()) {
101 - if (res.isConnected) { 127 + try_preload_when_online()
102 - preloadQrData(); 128 + return
103 } 129 }
104 - });
105 -
106 - // 初始检查网络状态并预加载二维码数据
107 - checkNetworkAndPreload();
108 -
109 - if (!needAuth()) return
110 130
111 if (path === 'pages/auth/index') return 131 if (path === 'pages/auth/index') return
112 132
113 try { 133 try {
114 - // 静默授权 134 + // 尝试静默授权
115 await silentAuth() 135 await silentAuth()
116 - // 授权成功后检查网络状态并预加载二维码数据 136 + // 授权成功后预加载数据
117 - checkNetworkAndPreload(); 137 + try_preload_when_online()
118 } catch (error) { 138 } catch (error) {
119 console.error('静默授权失败:', error) 139 console.error('静默授权失败:', error)
120 - // 授权失败后跳转到授权页,携带当前页路径作为回跳目标 140 + // 授权失败则跳转至授权页面
121 navigateToAuth(full_path || undefined) 141 navigateToAuth(full_path || undefined)
122 } 142 }
123 }, 143 },
......
...@@ -188,7 +188,17 @@ const init = async () => { ...@@ -188,7 +188,17 @@ const init = async () => {
188 if (validData.length > 0) { 188 if (validData.length > 0) {
189 userList.value = formatGroup(validData); 189 userList.value = formatGroup(validData);
190 // 缓存数据供离线模式使用 190 // 缓存数据供离线模式使用
191 - Taro.setStorageSync('OFFLINE_QR_DATA', userList.value); 191 + const offline_data = userList.value.map(item => ({
192 + name: item.name,
193 + id_number: item.id_number,
194 + qr_code: item.qr_code,
195 + begin_time: item.begin_time,
196 + end_time: item.end_time,
197 + datetime: item.datetime,
198 + pay_id: item.pay_id,
199 + sort: item.sort,
200 + }));
201 + Taro.setStorageSync('OFFLINE_QR_DATA', offline_data);
192 refreshBtn(); 202 refreshBtn();
193 } else { 203 } else {
194 userList.value = []; 204 userList.value = [];
......
1 <!-- 1 <!--
2 * @Date: 2024-01-15 16:25:51 2 * @Date: 2024-01-15 16:25:51
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-12 18:54:33 4 + * @LastEditTime: 2026-01-12 22:23:03
5 * @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue
6 * @Description: 预约人员信息 6 * @Description: 预约人员信息
7 --> 7 -->
...@@ -113,6 +113,9 @@ const goToVisitor = () => { ...@@ -113,6 +113,9 @@ const goToVisitor = () => {
113 go('/addVisitor'); 113 go('/addVisitor');
114 } 114 }
115 115
116 +// 待支付订单ID
117 +const pending_pay_id = ref(null);
118 +
116 const submitBtn = async () => { 119 const submitBtn = async () => {
117 if (!checked_visitors.value.length) { 120 if (!checked_visitors.value.length) {
118 Taro.showToast({ title: '请先添加参观者', icon: 'none' }) 121 Taro.showToast({ title: '请先添加参观者', icon: 'none' })
...@@ -121,8 +124,7 @@ const submitBtn = async () => { ...@@ -121,8 +124,7 @@ const submitBtn = async () => {
121 124
122 let pay_id = pending_pay_id.value; 125 let pay_id = pending_pay_id.value;
123 126
124 - if (!pay_id) { 127 + if (!pay_id) { // TAG: 提交订单, 如果没有待支付订单ID, 则创建一个新的订单
125 - // TAG: 提交订单跳转到支付页面
126 Taro.showLoading({ title: '提交中...' }); 128 Taro.showLoading({ title: '提交中...' });
127 const { code, data, msg } = await addReserveAPI({ 129 const { code, data, msg } = await addReserveAPI({
128 reserve_date: date.value, 130 reserve_date: date.value,
...@@ -144,19 +146,19 @@ const submitBtn = async () => { ...@@ -144,19 +146,19 @@ const submitBtn = async () => {
144 // 如果金额大于零, 走微信支付, 如果等于零直接跳转成功页 146 // 如果金额大于零, 走微信支付, 如果等于零直接跳转成功页
145 if (total.value > 0) { 147 if (total.value > 0) {
146 Taro.showLoading({ title: '支付准备中...' }); 148 Taro.showLoading({ title: '支付准备中...' });
147 - const payParams = await wxPayAPI({ pay_id: pay_id }); // 参数接口 149 + const payParams = await wxPayAPI({ pay_id }); // 参数接口
148 Taro.hideLoading(); 150 Taro.hideLoading();
149 151
150 if (payParams.code) { 152 if (payParams.code) {
151 - let pay = payParams.data; 153 + let pay_params = payParams.data;
152 Taro.requestPayment({ 154 Taro.requestPayment({
153 - timeStamp: pay.timeStamp, 155 + timeStamp: pay_params.timeStamp,
154 - nonceStr: pay.nonceStr, 156 + nonceStr: pay_params.nonceStr,
155 - package: pay.package, 157 + package: pay_params.package,
156 - signType: pay.signType, 158 + signType: pay_params.signType,
157 - paySign: pay.paySign, 159 + paySign: pay_params.paySign,
158 success (res) { 160 success (res) {
159 - go('/success', { pay_id: pay_id }); 161 + go('/success', { pay_id });
160 }, 162 },
161 fail (res) { 163 fail (res) {
162 // 支付取消或失败,保留 pending_pay_id,允许用户再次点击按钮尝试支付同一订单 164 // 支付取消或失败,保留 pending_pay_id,允许用户再次点击按钮尝试支付同一订单
...@@ -170,7 +172,7 @@ const submitBtn = async () => { ...@@ -170,7 +172,7 @@ const submitBtn = async () => {
170 } 172 }
171 } else { 173 } else {
172 // 金额等于零, 直接跳转成功页 174 // 金额等于零, 直接跳转成功页
173 - go('/success', { pay_id: pay_id }); 175 + go('/success', { pay_id });
174 } 176 }
175 } 177 }
176 178
......
...@@ -40,16 +40,16 @@ export const saveCurrentPagePath = (custom_path) => { ...@@ -40,16 +40,16 @@ export const saveCurrentPagePath = (custom_path) => {
40 } 40 }
41 41
42 /** 42 /**
43 - * 判断是否需要授权 43 + * 判断是否授权
44 - * @returns {boolean} true=需要授权,false=已存在 sessionid 44 + * @returns {boolean} true=已存在 sessionid,false=需要授权
45 */ 45 */
46 -export const needAuth = () => { 46 +export const hasAuth = () => {
47 try { 47 try {
48 const sessionid = Taro.getStorageSync('sessionid') 48 const sessionid = Taro.getStorageSync('sessionid')
49 - return !sessionid || sessionid === '' 49 + return !!sessionid && sessionid !== ''
50 } catch (error) { 50 } catch (error) {
51 console.error('检查授权状态失败:', error) 51 console.error('检查授权状态失败:', error)
52 - return true 52 + return false
53 } 53 }
54 } 54 }
55 55
...@@ -96,7 +96,7 @@ export const refreshSession = async (options) => { ...@@ -96,7 +96,7 @@ export const refreshSession = async (options) => {
96 96
97 // 开发环境可按需手动传 openid(仅用于本地联调) 97 // 开发环境可按需手动传 openid(仅用于本地联调)
98 if (process.env.NODE_ENV === 'development') { 98 if (process.env.NODE_ENV === 'development') {
99 - // request_data.openid = 'h-008'; 99 + // request_data.openid = 'waj';
100 // request_data.openid = 'h-009'; 100 // request_data.openid = 'h-009';
101 // request_data.openid = 'h-010'; 101 // request_data.openid = 'h-010';
102 // request_data.openid = 'h-011'; 102 // request_data.openid = 'h-011';
...@@ -112,7 +112,7 @@ export const refreshSession = async (options) => { ...@@ -112,7 +112,7 @@ export const refreshSession = async (options) => {
112 112
113 // 换取后端会话(服务端通过 Set-Cookie 返回会话信息) 113 // 换取后端会话(服务端通过 Set-Cookie 返回会话信息)
114 const response = await Taro.request({ 114 const response = await Taro.request({
115 - url: `${BASE_URL}/srv/?a=openid&f=${encodeURIComponent(REQUEST_DEFAULT_PARAMS.f)}&client_name=${encodeURIComponent(REQUEST_DEFAULT_PARAMS.client_name)}`, 115 + url: `${BASE_URL}/srv/?a=openid_wxapp&f=${encodeURIComponent(REQUEST_DEFAULT_PARAMS.f)}&client_name=${encodeURIComponent(REQUEST_DEFAULT_PARAMS.client_name)}`,
116 method: 'POST', 116 method: 'POST',
117 data: request_data, 117 data: request_data,
118 }) 118 })
...@@ -154,7 +154,7 @@ export const refreshSession = async (options) => { ...@@ -154,7 +154,7 @@ export const refreshSession = async (options) => {
154 154
155 const do_silent_auth = async (show_loading) => { 155 const do_silent_auth = async (show_loading) => {
156 // 已有 sessionid 时直接视为已授权 156 // 已有 sessionid 时直接视为已授权
157 - if (!needAuth()) { 157 + if (hasAuth()) {
158 return { code: 1, msg: '已授权' } 158 return { code: 1, msg: '已授权' }
159 } 159 }
160 160
...@@ -212,9 +212,9 @@ export const navigateToAuth = (return_path) => { ...@@ -212,9 +212,9 @@ export const navigateToAuth = (return_path) => {
212 } 212 }
213 213
214 // TAG: navigateTo 失败时(例如页面栈满),降级为 redirectTo 214 // TAG: navigateTo 失败时(例如页面栈满),降级为 redirectTo
215 - Taro.navigateTo({ url: '/pages/auth/index' }).catch(() => { 215 + // Taro.navigateTo({ url: '/pages/auth/index' }).catch(() => {
216 - return Taro.redirectTo({ url: '/pages/auth/index' }) 216 + // return Taro.redirectTo({ url: '/pages/auth/index' })
217 - }) 217 + // })
218 } 218 }
219 219
220 /** 220 /**
...@@ -279,7 +279,7 @@ export const isFromShare = (options) => { ...@@ -279,7 +279,7 @@ export const isFromShare = (options) => {
279 * @returns {Promise<boolean>} true=已处理且可继续,false=授权失败 279 * @returns {Promise<boolean>} true=已处理且可继续,false=授权失败
280 */ 280 */
281 export const handleSharePageAuth = async (options, callback) => { 281 export const handleSharePageAuth = async (options, callback) => {
282 - if (!needAuth()) { 282 + if (hasAuth()) {
283 if (typeof callback === 'function') callback() 283 if (typeof callback === 'function') callback()
284 return true 284 return true
285 } 285 }
......