app.js 5.01 KB
/*
 * @Date: 2025-06-28 10:33:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-13 00:28:35
 * @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 { qrcodeListAPI } from '@/api/index'
import { formatDatetime } from '@/utils/tools'

/**
 * 格式化支付记录,按 pay_id 分组,相同 pay_id 下的记录 sort 为 0,否则为 1
 * @param {*} data 支付记录数组
 * @returns 格式化后的支付记录数组
 */
const formatGroup = (data) => {
    let lastPayId = null;
    for (let i = 0; i < data.length; i++) {
        if (data[i].pay_id !== lastPayId) {
            data[i].sort = 1;
            lastPayId = data[i].pay_id;
        } else {
            data[i].sort = 0;
        }
    }
    return data;
}

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_QR_DATA)
         * - 失败则移除缓存
         */
        const preloadQrData = async () => {
            try {
                const { code, data } = await qrcodeListAPI();
                if (code && data) {
                    data.forEach(item => {
                        item.datetime = formatDatetime({ begin_time: item.begin_time, end_time: item.end_time })
                        item.sort = 0;
                    });
                    const validData = data.filter(item => item.qr_code !== '');
                    if (validData.length > 0) {
                        const processed = formatGroup(validData);
                        const offline_data = processed.map(item => ({
                            name: item.name,
                            id_number: item.id_number,
                            qr_code: item.qr_code,
                            begin_time: item.begin_time,
                            end_time: item.end_time,
                            datetime: item.datetime,
                            pay_id: item.pay_id,
                            sort: item.sort,
                        }));
                        Taro.setStorageSync('OFFLINE_QR_DATA', offline_data);
                    } else {
                        Taro.removeStorageSync('OFFLINE_QR_DATA');
                    }
                }
            } catch (e) {
                console.error('Preload QR failed', e);
            }
        };

        /**
         * 监听网络状态变化
         * - 当网络连接且有授权时,调用 preloadQrData 预加载二维码数据
         */
        Taro.onNetworkStatusChange((res) => {
            if (res.isConnected && hasAuth()) {
                preloadQrData()
            }
        })

        const is_usable_network = (network_type) => {
            return ['wifi', '4g', '5g', '3g'].includes(network_type)
        }

        /**
         * 尝试在网络可用时预加载二维码数据
         * - 仅在有授权时调用
         * - 成功后将数据存储到本地缓存(key: OFFLINE_QR_DATA)
         * - 失败则移除缓存
         * @returns {Promise<void>}
         */
        const try_preload_when_online = () => {
            if (!hasAuth()) return
            Taro.getNetworkType({
                success: (res) => {
                    if (is_usable_network(res.networkType)) {
                        preloadQrData()
                    }
                }
            })
        }

        /**
         * 尝试在有授权时预加载二维码数据
         * - 若无授权,则尝试静默授权
         * - 授权成功后调用 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