useOfflineBookingCache.js 5.04 KB
/**
 * 刷新离线预约记录缓存
 * - 仅在有授权且网络可用时调用
 * - 成功后将数据存储到本地缓存(key: OFFLINE_BOOKING_DATA)
 * @param {boolean} force - 是否强制刷新,默认为 false
 * @returns {Promise<void>}
 */

import Taro from '@tarojs/taro'
import { billOfflineAllAPI } from '@/api/index'
import { hasAuth } from '@/utils/authRedirect'
import { formatDatetime } from '@/utils/tools'

export const OFFLINE_BOOKING_CACHE_KEY = 'OFFLINE_BOOKING_DATA'

let refresh_promise = null

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

/**
 * 获取当前网络类型
 * @returns {Promise<string>} 网络类型(wifi, 4g, 5g, 3g, unknown)
 */
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'
    }
}

/**
 * 格式化预约记录项
 * @param {Object} item - 原始预约记录项
 * @returns {Object} 格式化后的预约记录项
 */
const normalize_bill_item = (item) => {
    const data = item ? { ...item } : {}

    data.datetime = data.datetime || formatDatetime(data)
    data.booking_time = data.booking_time || data.datetime
    data.order_time = data.order_time || (data.created_time ? data.created_time.slice(0, -3) : '')

    return data
}

/**
 * 获取离线预约记录缓存
 * @returns {Array} 格式化后的预约记录项列表
 */
export const get_offline_booking_cache = () => {
    try {
        const data = Taro.getStorageSync(OFFLINE_BOOKING_CACHE_KEY)
        return Array.isArray(data) ? data : []
    } catch (e) {
        return []
    }
}

/**
 * 检查是否存在离线预约记录缓存
 * @returns {boolean} 是否存在缓存且非空
 */
export const has_offline_booking_cache = () => {
    const list = get_offline_booking_cache()
    return Array.isArray(list) && list.length > 0
}

/**
 * 根据支付ID获取离线预约记录
 * @param {*} pay_id 支付ID
 * @returns {Object|null} 匹配的预约记录项或 null
 */
export const get_offline_booking_by_pay_id = (pay_id) => {
    const list = get_offline_booking_cache()
    const target_pay_id = String(pay_id || '')
    return list.find((item) => String(item?.pay_id || '') === target_pay_id) || null
}

/**
 * 获取预约记录中的人员列表
 * @param {Object} bill - 预约记录项
 * @returns {Array} 人员列表(包含姓名、身份证号、二维码等信息)
 */
export const get_offline_bill_person_list = (bill) => {
    if (!bill) return []
    const candidate =
        bill.person_list ||
        bill.bill_person_list ||
        bill.persons ||
        bill.qrcode_list ||
        bill.qr_list ||
        bill.detail_list ||
        []

    return Array.isArray(candidate) ? candidate : []
}

/**
 * 构建预约记录中的二维码列表
 * @param {Object} bill - 预约记录项
 * @returns {Array} 二维码列表(包含姓名、身份证号、二维码、预约时间等信息)
 */
export const build_offline_qr_list = (bill) => {
    const list = get_offline_bill_person_list(bill)
    const datetime = bill?.datetime || formatDatetime(bill || {})

    return list
        .filter((item) => item && item.qr_code !== '')
        .map((item) => {
            const begin_time = item.begin_time || bill?.begin_time
            const end_time = item.end_time || bill?.end_time
            return {
                name: item.name,
                id_number: item.id_number,
                qr_code: item.qr_code,
                begin_time,
                end_time,
                datetime: item.datetime || (begin_time && end_time ? formatDatetime({ begin_time, end_time }) : datetime),
                pay_id: bill?.pay_id,
                sort: 0,
            }
        })
}

/**
 * 刷新离线预约记录缓存
 * - 仅在有授权且网络可用时调用
 * - 成功后将数据存储到本地缓存(key: OFFLINE_BOOKING_DATA)
 * @param {boolean} force - 是否强制刷新,默认为 false
 * @returns {Promise<void>}
 */
export const refresh_offline_booking_cache = async ({ force = false } = {}) => {
    if (!hasAuth()) return { code: 0, data: null, msg: '未授权' }

    if (refresh_promise && !force) return refresh_promise

    refresh_promise = (async () => {
        const network_type = await get_network_type()
        if (!is_usable_network(network_type)) {
            return { code: 0, data: null, msg: '网络不可用' }
        }

        const { code, data, msg } = await billOfflineAllAPI()
        if (code && Array.isArray(data)) {
            const normalized = data.map(normalize_bill_item).filter((item) => item && item.pay_id)
            if (normalized.length > 0) {
                Taro.setStorageSync(OFFLINE_BOOKING_CACHE_KEY, normalized)
            }
        }
        return { code, data, msg }
    })()

    try {
        return await refresh_promise
    } finally {
        refresh_promise = null
    }
}