app.js
7.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-17 12:14:16
* @FilePath: /xyxBooking-weapp/src/app.js
* @Description: 应用入口文件
*/
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './utils/polyfill'
import './app.less'
import { saveCurrentPagePath, hasAuth, silentAuth, navigateToAuth } from '@/utils/authRedirect'
import Taro from '@tarojs/taro'
import { refresh_offline_booking_cache, has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
import { is_usable_network, get_network_type } from '@/utils/network'
import { enable_offline_booking_cache_polling } from '@/composables/useOfflineBookingCachePolling'
import { weak_network_text, get_weak_network_modal_use_cache_options } from '@/utils/uiText'
// 记录是否已展示过网络异常提示弹窗
let has_shown_network_modal = false
// 记录上一次网络是否可用,用于识别“从可用变为不可用”的场景
let last_network_usable = null
const App = createApp({
// 对应 onLaunch
async onLaunch(options) {
const path = options?.path || ''
const query = options?.query || {}
const query_string = Object.keys(query)
.map((key) => `${key}=${encodeURIComponent(query[key])}`)
.join('&')
const full_path = query_string ? `${path}?${query_string}` : path
// 保存当前页面路径,用于授权后跳转回原页面
if (full_path) {
saveCurrentPagePath(full_path)
}
/**
* 预加载离线预约记录数据(列表+详情)
* - 仅在有授权且网络可用时调用
* - 成功后将数据存储到本地缓存(key: OFFLINE_BOOKING_DATA)
*/
const preloadBookingData = async () => {
try {
await refresh_offline_booking_cache()
} catch (e) {
console.error('Preload booking cache failed', e)
}
}
/**
* 判断是否应该跳过网络异常提示弹窗
* - 仅在当前页面为离线预约列表/详情/核销码页时返回 true
*/
const should_skip_network_prompt = () => {
const pages = Taro.getCurrentPages ? Taro.getCurrentPages() : []
const current_page = pages && pages.length ? pages[pages.length - 1] : null
const current_route = String(current_page?.route || '')
if (!current_route) return false
if (current_route.includes('pages/offlineBookingList/index')) return true
if (current_route.includes('pages/offlineBookingDetail/index')) return true
if (current_route.includes('pages/offlineBookingCode/index')) return true
return false
}
/**
* 处理不良网络情况
* - 仅在当前页面未跳过提示弹窗时调用
* - 若有离线预约缓存,则展示弹窗询问是否使用缓存数据
* - 否则展示简单提示弹窗
*/
const handle_bad_network = async (network_type) => {
if (has_shown_network_modal) return false
if (should_skip_network_prompt()) return false
const is_none_network = network_type === 'none'
const is_weak_network = !is_usable_network(network_type)
if (!is_weak_network) return false
has_shown_network_modal = true
if (has_offline_booking_cache()) {
try {
const modal_res = await Taro.showModal(get_weak_network_modal_use_cache_options())
if (modal_res?.confirm) {
await Taro.reLaunch({ url: '/pages/offlineBookingList/index' })
return true
}
} catch (e) {
return is_none_network
}
} else {
try {
await Taro.showToast({ title: weak_network_text.toast_title, icon: 'none', duration: 2000 })
} catch (e) {
return is_none_network
}
}
return is_none_network
}
/**
* 监听网络状态变化
* - 当网络连接且有授权时,预加载离线预约记录数据
*/
Taro.onNetworkStatusChange((res) => {
const is_connected = res?.isConnected !== false
const network_type = res?.networkType || 'none'
const network_usable = is_connected && is_usable_network(network_type)
if (network_usable) {
has_shown_network_modal = false
last_network_usable = true
if (hasAuth()) preloadBookingData()
return
}
const should_prompt = last_network_usable === true || last_network_usable === null
last_network_usable = false
if (should_prompt) {
handle_bad_network(network_type)
}
return
})
/**
* 处理在启动时出现的不良网络情况
* - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式
* - 当网络连接不良且无缓存时,提示用户网络连接不畅
* @returns {Promise<boolean>} 如果用户选择进入离线模式,则返回 true;否则返回 false
*/
const handle_bad_network_on_launch = async () => {
/**
* 避免重复提示用户
* - 仅在首次启动时检查网络情况
* - 如果用户已展示过提示弹窗,则直接返回 false
*/
if (has_shown_network_modal) return false
const network_type = await get_network_type()
last_network_usable = is_usable_network(network_type)
return handle_bad_network(network_type)
}
/**
* 尝试在网络可用时预加载离线预约记录数据
* - 仅在有授权时调用
* @returns {Promise<void>}
*/
const try_preload_when_online = () => {
if (!hasAuth()) return
Taro.getNetworkType({
success: (res) => {
if (is_usable_network(res.networkType)) {
preloadBookingData()
}
}
})
}
/**
* @description: 授权成功后的共用启动逻辑
* - 尝试在网络可用时预加载离线预约数据
* - 启动离线预约缓存轮询(会自行处理网络可用性与引用计数)
*/
const bootstrap_after_auth = () => {
try_preload_when_online()
enable_offline_booking_cache_polling({ interval_ms: 2 * 1000 * 60 })
}
// 处理在启动时出现的不良网络情况
const should_stop = await handle_bad_network_on_launch()
// 如果用户选择进入离线模式,则直接返回
if (should_stop) return
/**
* 尝试在有授权时预加载离线预约记录数据
* - 若无授权,则尝试静默授权
* - 授权成功后调用 bootstrap_after_auth 启动共用逻辑
* - 授权失败则跳转至授权页面
*/
// 如果用户已授权,则直接调用 bootstrap_after_auth 启动共用逻辑
if (hasAuth()) {
bootstrap_after_auth()
return
}
if (path === 'pages/auth/index') return
try {
// 尝试静默授权
await silentAuth()
// 授权成功后调用 bootstrap_after_auth 启动共用逻辑
bootstrap_after_auth()
} catch (error) {
console.error('静默授权失败:', error)
// 授权失败则跳转至授权页面
navigateToAuth(full_path || undefined)
}
return
},
onShow() {
},
});
App.use(createPinia())
export default App