hookehuyr

feat(offline): 添加离线模式支持并优化网络检测功能

新增离线预约记录页面和网络工具函数
将网络检测逻辑提取到独立工具模块
优化页面跳转时的网络状态检查
/*
* @Date: 2023-08-24 09:42:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-12 18:38:52
* @LastEditTime: 2026-01-13 14:52:29
* @FilePath: /xyxBooking-weapp/src/api/index.js
* @Description: 文件描述
*/
......@@ -21,6 +21,7 @@ const Api = {
QRCODE_LIST: '/srv/?a=api&t=qrcode_list',
QRCODE_STATUS: '/srv/?a=api&t=qrcode_status',
BILL_LIST: '/srv/?a=api&t=bill_list',
BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_offline_all',
ICBC_REFUND: '/srv/?a=icbc_refund',
BILL_PREPARE: '/srv/?a=api&t=bill_person',
BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status',
......@@ -182,6 +183,12 @@ export const qrcodeStatusAPI = (params) => fn(fetch.get(Api.QRCODE_STATUS, param
export const billListAPI = (params) => fn(fetch.get(Api.BILL_LIST, params));
/**
* @description: 离线预约记录全量数据(列表+详情)
* @returns {String}
*/
export const billOfflineAllAPI = (params) => fn(fetch.get(Api.BILL_OFFLINE_ALL, params));
/**
* @description: 取消预约
* @param {String} pay_id
* @returns {String}
......
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 13:55:59
* @LastEditTime: 2026-01-13 15:22:40
* @FilePath: /xyxBooking-weapp/src/app.js
* @Description: 应用入口文件
*/
......@@ -12,6 +12,7 @@ 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
......@@ -54,28 +55,6 @@ const App = createApp({
}
})
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'
}
}
/**
* 处理在启动时出现的不良网络情况
* - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式
......
......@@ -10,33 +10,12 @@ import Taro from '@tarojs/taro'
import { billOfflineAllAPI } from '@/api/index'
import { hasAuth } from '@/utils/authRedirect'
import { formatDatetime } from '@/utils/tools'
import { is_usable_network, get_network_type } from '@/utils/network'
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 - 原始预约记录项
......
<!--
* @Date: 2024-01-16 10:06:47
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 15:19:11
* @LastEditTime: 2026-01-13 15:24:06
* @FilePath: /xyxBooking-weapp/src/pages/bookingCode/index.vue
* @Description: 文件描述
* @Description: 预约码页面
-->
<template>
<view class="booking-code-page">
......@@ -42,13 +42,14 @@ import icon_4 from '@/assets/images/二维码icon.png'
import icon_5 from '@/assets/images/我的01@2x.png'
import { useGo } from '@/hooks/useGo'
import { has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
import { is_usable_network } from '@/utils/network'
const go = useGo();
useDidShow(() => {
Taro.getNetworkType({
success: (res) => {
const isConnected = ['wifi', '4g', '5g', '3g'].includes(res.networkType);
const isConnected = is_usable_network(res.networkType);
if (!isConnected) {
if (has_offline_booking_cache()) {
Taro.redirectTo({ url: '/pages/offlineBookingList/index' })
......
<!--
* @Date: 2023-06-21 10:23:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-09 18:08:03
* @LastEditTime: 2026-01-13 15:35:17
* @FilePath: /xyxBooking-weapp/src/pages/index/index.vue
* @Description: 预约页首页
-->
......
<template>
<view class="my-page">
<view v-for="(item, index) in menu_list" :key="index" class="my-item" @tap="go(item.to)">
<view v-for="(item, index) in menu_list" :key="index" class="my-item" @tap="on_menu_tap(item)">
<view class="left">
<image :src="item.icon" style="width: 38rpx; height: 38rpx; margin-right: 16rpx;" />
{{ item.name }}
......@@ -35,6 +35,8 @@ import { IconFont } from '@nutui/icons-vue-taro'
import icon_3 from '@/assets/images/首页01@2x.png'
import icon_4 from '@/assets/images/二维码icon.png'
import icon_5 from '@/assets/images/我的02@2x.png'
import { has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
import { is_usable_network, get_network_type } from '@/utils/network'
import icon_booking from '@/assets/images/预约记录@2x.png'
import icon_visitor from '@/assets/images/我的01@2x.png'
......@@ -42,6 +44,33 @@ import icon_invite from '@/assets/images/二维码@2x2.png'
const go = useGo();
const on_menu_tap = async (item) => {
if (!item?.to) return
if (item.to === '/pages/bookingList/index') {
const network_type = await get_network_type()
const is_weak_network = !is_usable_network(network_type)
if (is_weak_network) {
if (has_offline_booking_cache()) {
const modal_res = await Taro.showModal({
title: '网络连接不畅',
content: '当前网络信号较弱,是否进入离线预约记录?',
confirmText: '离线记录',
cancelText: '知道了',
})
if (modal_res?.confirm) {
go('/pages/offlineBookingList/index')
}
return
}
Taro.showToast({ title: '网络连接不畅', icon: 'none', duration: 2000 })
return
}
}
go(item.to)
}
const toCode = () => { // 跳转到预约码
Taro.redirectTo({
url: '/pages/bookingCode/index'
......
<!--
* @Date: 2026-01-13 14:55:05
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 15:25:25
* @FilePath: /xyxBooking-weapp/src/pages/offlineBookingList/index.vue
* @Description: 离线预约记录页面
-->
<template>
<view class="offline-booking-list-page">
<view class="header-tip">
<IconFont name="tips" size="15" color="#A67939" />
<IconFont name="tips" size="15" color="#A67939" /> &nbsp;
<text>您当前处于离线模式,仅展示本地缓存的预约记录</text>
</view>
......@@ -83,7 +90,7 @@ useDidShow(() => {
color: #FFF;
border-radius: 16rpx;
font-size: 32rpx;
padding: 22rpx 0;
padding: 12rpx 0;
}
}
}
......
/*
* @Date: 2026-01-13 15:34:47
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 15:36:37
* @FilePath: /xyxBooking-weapp/src/utils/network.js
* @Description: 网络相关工具函数
*/
import Taro from '@tarojs/taro'
/**
* @description: 判断网络是否可用(wifi, 4g, 5g, 3g)
* @param {string} network_type - 网络类型
* @returns {boolean} 是否可用
*/
export const is_usable_network = (network_type) => {
return ['wifi', '4g', '5g', '3g'].includes(network_type)
}
/**
* @description: 获取当前网络类型
* @returns {Promise<string>} 网络类型(wifi, 4g, 5g, 3g, unknown)
*/
export 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'
}
}