app.js
5.9 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
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 13:55:59
* @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'
let has_shown_network_modal = false
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)
}
}
/**
* 监听网络状态变化
* - 当网络连接且有授权时,预加载离线预约记录数据
*/
Taro.onNetworkStatusChange((res) => {
if (res.isConnected && hasAuth()) {
preloadBookingData()
}
})
const is_usable_network = (network_type) => {
return ['wifi', '4g', '5g', '3g'].includes(network_type)
}
/**
* 获取当前网络类型
* @returns {string} 当前网络类型,如 wifi、4g、5g、3g、none 等
*/
const get_network_type = async () => {
try {
const result = await new Promise((resolve, reject) => {
Taro.getNetworkType({
success: resolve,
fail: reject,
})
})
return result?.networkType || 'unknown'
} catch (e) {
return 'unknown'
}
}
/**
* 处理在启动时出现的不良网络情况
* - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式
* - 当网络连接不良且无缓存时,提示用户网络连接不畅
* @returns {Promise<boolean>} 如果用户选择进入离线模式,则返回 true;否则返回 false
*/
const handle_bad_network_on_launch = async () => {
/**
* 避免重复提示用户
* - 仅在首次启动时检查网络情况
*/
if (has_shown_network_modal) return false
const network_type = await get_network_type()
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({
title: '网络连接不畅',
content: '当前网络信号较弱,可使用已缓存的预约记录进入离线模式',
confirmText: '预约记录',
cancelText: '知道了',
})
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: '网络连接不畅', icon: 'none', duration: 2000 })
} catch (e) {
return is_none_network
}
}
return is_none_network
}
const should_stop = await handle_bad_network_on_launch()
if (should_stop) return
/**
* 尝试在网络可用时预加载离线预约记录数据
* - 仅在有授权时调用
* @returns {Promise<void>}
*/
const try_preload_when_online = () => {
if (!hasAuth()) return
Taro.getNetworkType({
success: (res) => {
if (is_usable_network(res.networkType)) {
preloadBookingData()
}
}
})
}
/**
* 尝试在有授权时预加载二维码数据
* - 若无授权,则尝试静默授权
* - 授权成功后调用 try_preload_when_online 预加载数据
* - 授权失败则跳转至授权页面
*/
if (hasAuth()) {
try_preload_when_online()
return
}
if (path === 'pages/auth/index') return
try {
// 尝试静默授权
await silentAuth()
// 授权成功后预加载数据
try_preload_when_online()
} catch (error) {
console.error('静默授权失败:', error)
// 授权失败则跳转至授权页面
navigateToAuth(full_path || undefined)
}
},
onShow() {
},
// 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
});
App.use(createPinia())
export default App