app.js 5.26 KB
/*
 * @Date: 2025-06-28 10:33:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-13 15:22:40
 * @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'

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()
            }
        })

        /**
         * 处理在启动时出现的不良网络情况
         * - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式
         * - 当网络连接不良且无缓存时,提示用户网络连接不畅
         * @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