hookehuyr

feat(离线预约): 添加离线预约缓存轮询功能

实现离线预约缓存自动轮询刷新机制,提升离线状态下的数据同步能力
移除不再使用的支付相关API和等待页面
1 /* 1 /*
2 * @Date: 2023-08-24 09:42:27 2 * @Date: 2023-08-24 09:42:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-13 20:55:13 4 + * @LastEditTime: 2026-01-13 23:13:04
5 * @FilePath: /xyxBooking-weapp/src/api/index.js 5 * @FilePath: /xyxBooking-weapp/src/api/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -14,8 +14,8 @@ const Api = { ...@@ -14,8 +14,8 @@ const Api = {
14 ADD_PERSON: '/srv/?a=api&t=add_person', 14 ADD_PERSON: '/srv/?a=api&t=add_person',
15 DEL_PERSON: '/srv/?a=api&t=del_person', 15 DEL_PERSON: '/srv/?a=api&t=del_person',
16 ADD_RESERVE: '/srv/?a=api&t=add_reserve', 16 ADD_RESERVE: '/srv/?a=api&t=add_reserve',
17 - PAY_PREPARE: '/srv/?a=api&t=pay_prepare', 17 + // PAY_PREPARE: '/srv/?a=api&t=pay_prepare',
18 - PAY_CALLBACK: '/srv/?a=api&t=pay_callback', 18 + // PAY_CALLBACK: '/srv/?a=api&t=pay_callback',
19 BILL_INFO: '/srv/?a=api&t=bill_info', 19 BILL_INFO: '/srv/?a=api&t=bill_info',
20 ON_AUTH_BILL_INFO: '/srv/?a=no_auth_api&t=bill_info', 20 ON_AUTH_BILL_INFO: '/srv/?a=no_auth_api&t=bill_info',
21 QRCODE_LIST: '/srv/?a=api&t=qrcode_list', 21 QRCODE_LIST: '/srv/?a=api&t=qrcode_list',
...@@ -24,7 +24,7 @@ const Api = { ...@@ -24,7 +24,7 @@ const Api = {
24 BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_all_info', 24 BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_all_info',
25 ICBC_REFUND: '/srv/?a=icbc_refund', 25 ICBC_REFUND: '/srv/?a=icbc_refund',
26 BILL_PREPARE: '/srv/?a=api&t=bill_person', 26 BILL_PREPARE: '/srv/?a=api&t=bill_person',
27 - BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status', 27 + // BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status',
28 QUERY_QR_CODE: '/srv/?a=api&t=id_number_query_qr_code', 28 QUERY_QR_CODE: '/srv/?a=api&t=id_number_query_qr_code',
29 ICBC_ORDER_QRY: '/srv/?a=icbc_orderqry', 29 ICBC_ORDER_QRY: '/srv/?a=icbc_orderqry',
30 WX_PAY: '/srv/?a=icbc_pay_wxamp', 30 WX_PAY: '/srv/?a=icbc_pay_wxamp',
...@@ -109,7 +109,7 @@ export const addReserveAPI = (params) => fn(fetch.post(Api.ADD_RESERVE, params)) ...@@ -109,7 +109,7 @@ export const addReserveAPI = (params) => fn(fetch.post(Api.ADD_RESERVE, params))
109 * @param {String} bill_id 109 * @param {String} bill_id
110 * @returns {String} bill_id 预约单id 110 * @returns {String} bill_id 预约单id
111 */ 111 */
112 -export const payPrepareAPI = (params) => fn(fetch.post(Api.PAY_PREPARE, params)); 112 +// export const payPrepareAPI = (params) => fn(fetch.post(Api.PAY_PREPARE, params));
113 113
114 /** 114 /**
115 * @description: 支付回调(模拟) 115 * @description: 支付回调(模拟)
...@@ -117,7 +117,7 @@ export const payPrepareAPI = (params) => fn(fetch.post(Api.PAY_PREPARE, params)) ...@@ -117,7 +117,7 @@ export const payPrepareAPI = (params) => fn(fetch.post(Api.PAY_PREPARE, params))
117 * @param {String} pay_status 支付状态,1为成功,0为失败(缺省) 117 * @param {String} pay_status 支付状态,1为成功,0为失败(缺省)
118 * @returns {String} bill_id 预约单id 118 * @returns {String} bill_id 预约单id
119 */ 119 */
120 -export const payCallbackAPI = (params) => fn(fetch.post(Api.PAY_CALLBACK, params)); 120 +// export const payCallbackAPI = (params) => fn(fetch.post(Api.PAY_CALLBACK, params));
121 121
122 /** 122 /**
123 * @description: 预约单详情,参观者列表 123 * @description: 预约单详情,参观者列表
...@@ -193,7 +193,7 @@ export const billPersonAPI = (params) => fn(fetch.get(Api.BILL_PREPARE, params)) ...@@ -193,7 +193,7 @@ export const billPersonAPI = (params) => fn(fetch.get(Api.BILL_PREPARE, params))
193 * @param {String} 193 * @param {String}
194 * @returns {String} 194 * @returns {String}
195 */ 195 */
196 -export const billPayStatusAPI = (params) => fn(fetch.get(Api.BILL_PAY_STATUS, params)); 196 +// export const billPayStatusAPI = (params) => fn(fetch.get(Api.BILL_PAY_STATUS, params));
197 197
198 /** 198 /**
199 * @description: 身份证查询预约码 199 * @description: 身份证查询预约码
......
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-13 14:56:43 4 + * @LastEditTime: 2026-01-13 23:19:52
5 * @FilePath: /xyxBooking-weapp/src/app.config.js 5 * @FilePath: /xyxBooking-weapp/src/app.config.js
6 * @Description: 小程序配置文件 6 * @Description: 小程序配置文件
7 */ 7 */
...@@ -17,7 +17,6 @@ const pages = [ ...@@ -17,7 +17,6 @@ const pages = [
17 'pages/bookingList/index', 17 'pages/bookingList/index',
18 'pages/bookingDetail/index', 18 'pages/bookingDetail/index',
19 'pages/me/index', 19 'pages/me/index',
20 - 'pages/waiting/index',
21 'pages/callback/index', 20 'pages/callback/index',
22 'pages/search/index', 21 'pages/search/index',
23 'pages/visitorList/index', 22 'pages/visitorList/index',
......
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-13 15:22:40 4 + * @LastEditTime: 2026-01-13 23:30:40
5 * @FilePath: /xyxBooking-weapp/src/app.js 5 * @FilePath: /xyxBooking-weapp/src/app.js
6 * @Description: 应用入口文件 6 * @Description: 应用入口文件
7 */ 7 */
...@@ -13,6 +13,7 @@ import { saveCurrentPagePath, hasAuth, silentAuth, navigateToAuth } from '@/util ...@@ -13,6 +13,7 @@ import { saveCurrentPagePath, hasAuth, silentAuth, navigateToAuth } from '@/util
13 import Taro from '@tarojs/taro' 13 import Taro from '@tarojs/taro'
14 import { refresh_offline_booking_cache, has_offline_booking_cache } from '@/composables/useOfflineBookingCache' 14 import { refresh_offline_booking_cache, has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
15 import { is_usable_network, get_network_type } from '@/utils/network' 15 import { is_usable_network, get_network_type } from '@/utils/network'
16 +import { start_offline_booking_cache_polling } from '@/composables/useOfflineBookingCachePolling'
16 import { weak_network_text, get_weak_network_modal_use_cache_options } from '@/utils/uiText' 17 import { weak_network_text, get_weak_network_modal_use_cache_options } from '@/utils/uiText'
17 18
18 let has_shown_network_modal = false 19 let has_shown_network_modal = false
...@@ -124,7 +125,10 @@ const App = createApp({ ...@@ -124,7 +125,10 @@ const App = createApp({
124 * - 授权失败则跳转至授权页面 125 * - 授权失败则跳转至授权页面
125 */ 126 */
126 if (hasAuth()) { 127 if (hasAuth()) {
128 + // 有授权时预加载数据
127 try_preload_when_online() 129 try_preload_when_online()
130 + // 启动离线预约缓存轮询
131 + start_offline_booking_cache_polling()
128 return 132 return
129 } 133 }
130 134
...@@ -135,6 +139,8 @@ const App = createApp({ ...@@ -135,6 +139,8 @@ const App = createApp({
135 await silentAuth() 139 await silentAuth()
136 // 授权成功后预加载数据 140 // 授权成功后预加载数据
137 try_preload_when_online() 141 try_preload_when_online()
142 + // 启动离线预约缓存轮询
143 + start_offline_booking_cache_polling()
138 } catch (error) { 144 } catch (error) {
139 console.error('静默授权失败:', error) 145 console.error('静默授权失败:', error)
140 // 授权失败则跳转至授权页面 146 // 授权失败则跳转至授权页面
......
1 +import { ref, onMounted, onUnmounted } from 'vue'
2 +import { refresh_offline_booking_cache } from '@/composables/useOfflineBookingCache'
3 +
4 +let polling_timer_id = null
5 +let polling_running = false
6 +let polling_in_flight = false
7 +let polling_ref_count = 0
8 +
9 +/**
10 + * @description: 刷新离线预约缓存一次
11 + * @param {Object} options 选项
12 + * @param {Boolean} options.force 是否强制刷新
13 + */
14 +
15 +const run_refresh_once = async (options) => {
16 + if (polling_in_flight) return
17 + polling_in_flight = true
18 + try {
19 + await refresh_offline_booking_cache({ force: !!options?.force })
20 + } finally {
21 + polling_in_flight = false
22 + }
23 +}
24 +
25 +/**
26 + * @description: 启动离线预约缓存轮询
27 + * @param {Object} options 选项
28 + * @param {Number} options.interval_ms 轮询间隔,单位毫秒
29 + * @param {Boolean} options.immediate 是否立即刷新一次
30 + */
31 +
32 +export const start_offline_booking_cache_polling = (options) => {
33 + const interval_ms = Number(options?.interval_ms || 60000)
34 + if (polling_running) return
35 +
36 + polling_running = true
37 +
38 + if (options?.immediate !== false) {
39 + run_refresh_once(options)
40 + }
41 +
42 + polling_timer_id = setInterval(() => {
43 + run_refresh_once(options)
44 + }, interval_ms)
45 +}
46 +
47 +/**
48 + * @description: 停止离线预约缓存轮询
49 + */
50 +
51 +export const stop_offline_booking_cache_polling = () => {
52 + if (!polling_timer_id) {
53 + polling_running = false
54 + return
55 + }
56 + clearInterval(polling_timer_id)
57 + polling_timer_id = null
58 + polling_running = false
59 +}
60 +
61 +/**
62 + * @description: 用于管理离线预约缓存轮询的组合式函数
63 + * @param {Object} options 选项
64 + * @param {Boolean} options.enabled 是否启用轮询
65 + * @param {Boolean} options.auto 是否自动启动轮询
66 + * @param {Number} options.interval_ms 轮询间隔,单位毫秒
67 + * @param {Boolean} options.immediate 是否立即刷新一次
68 + */
69 +
70 +export const use_offline_booking_cache_polling = (options) => {
71 + const is_running = ref(false)
72 + const enabled = options?.enabled !== false
73 +
74 + const start = () => {
75 + if (!enabled) return
76 + polling_ref_count += 1
77 + start_offline_booking_cache_polling(options)
78 + is_running.value = true
79 + }
80 +
81 + const stop = () => {
82 + if (!is_running.value) return
83 + polling_ref_count = Math.max(0, polling_ref_count - 1)
84 + if (polling_ref_count === 0) {
85 + stop_offline_booking_cache_polling()
86 + }
87 + is_running.value = false
88 + }
89 +
90 + onMounted(() => {
91 + if (options?.auto !== false) start()
92 + })
93 +
94 + onUnmounted(() => {
95 + stop()
96 + })
97 +
98 + return {
99 + is_running,
100 + start,
101 + stop,
102 + }
103 +}
1 <!-- 1 <!--
2 * @Date: 2023-06-21 10:23:09 2 * @Date: 2023-06-21 10:23:09
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-13 21:23:30 4 + * @LastEditTime: 2026-01-13 23:26:08
5 * @FilePath: /xyxBooking-weapp/src/pages/index/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/index/index.vue
6 * @Description: 预约页首页 6 * @Description: 预约页首页
7 --> 7 -->
...@@ -58,6 +58,7 @@ import { ref } from 'vue' ...@@ -58,6 +58,7 @@ import { ref } from 'vue'
58 import { useGo } from '@/hooks/useGo' 58 import { useGo } from '@/hooks/useGo'
59 import { get_network_type, is_usable_network } from '@/utils/network' 59 import { get_network_type, is_usable_network } from '@/utils/network'
60 import { weak_network_text } from '@/utils/uiText' 60 import { weak_network_text } from '@/utils/uiText'
61 +
61 import icon_1 from '@/assets/images/立即预约@2x.png' 62 import icon_1 from '@/assets/images/立即预约@2x.png'
62 import icon_3 from '@/assets/images/首页02@2x.png' 63 import icon_3 from '@/assets/images/首页02@2x.png'
63 import icon_4 from '@/assets/images/二维码icon.png' 64 import icon_4 from '@/assets/images/二维码icon.png'
......
1 <!-- 1 <!--
2 * @Date: 2024-01-15 18:28:25 2 * @Date: 2024-01-15 18:28:25
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-01-30 15:18:54 4 + * @LastEditTime: 2026-01-13 23:20:10
5 * @FilePath: /xyxBooking-weapp/src/pages/success/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/success/index.vue
6 * @Description: 预约成功提示页面 6 * @Description: 预约成功提示页面
7 --> 7 -->
...@@ -58,6 +58,7 @@ useDidShow(async () => { ...@@ -58,6 +58,7 @@ useDidShow(async () => {
58 data.datetime = data && formatDatetime(data); 58 data.datetime = data && formatDatetime(data);
59 billInfo.value = data; 59 billInfo.value = data;
60 } 60 }
61 + // 刷新离线预约缓存
61 refresh_offline_booking_cache({ force: true }) 62 refresh_offline_booking_cache({ force: true })
62 }) 63 })
63 </script> 64 </script>
......