hookehuyr

feat(离线预约): 新增离线预约记录和详情功能

添加离线预约记录列表和详情页面,重构离线数据缓存逻辑
修改弱网页面跳转逻辑,移除旧的离线预约码功能
新增离线预约缓存管理工具函数
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-06-28 11:05:47
* @FilePath: /myApp/src/app.config.js
* @Description: 文件描述
* @LastEditTime: 2026-01-13 14:56:43
* @FilePath: /xyxBooking-weapp/src/app.config.js
* @Description: 小程序配置文件
*/
export default {
pages: [
......@@ -26,6 +26,8 @@ export default {
'pages/verificationResult/index',
'pages/weakNetwork/index',
'pages/offlineBookingCode/index',
'pages/offlineBookingList/index',
'pages/offlineBookingDetail/index',
'pages/nfcTest/index',
'pages/tailwindTest/index',
],
......
......@@ -11,29 +11,10 @@ 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'
import { refresh_offline_booking_cache, has_offline_booking_cache } from '@/composables/useOfflineBookingCache'
let has_shown_network_modal = false
/**
* 格式化支付记录,按 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) {
......@@ -51,49 +32,25 @@ const App = createApp({
}
/**
* 预加载二维码数据
* - 仅在有网络连接时调用
* - 成功后将数据存储到本地缓存(key: OFFLINE_QR_DATA)
* - 失败则移除缓存
* 预加载离线预约记录数据(列表+详情)
* - 仅在有授权且网络可用时调用
* - 成功后将数据存储到本地缓存(key: OFFLINE_BOOKING_DATA)
*/
const preloadQrData = async () => {
const preloadBookingData = 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');
}
}
await refresh_offline_booking_cache()
} catch (e) {
console.error('Preload QR failed', e);
console.error('Preload booking cache failed', e)
}
};
}
/**
* 监听网络状态变化
* - 当网络连接且有授权时,调用 preloadQrData 预加载二维码数据
* - 当网络连接且有授权时,预加载离线预约记录数据
*/
Taro.onNetworkStatusChange((res) => {
if (res.isConnected && hasAuth()) {
preloadQrData()
preloadBookingData()
}
})
......@@ -120,23 +77,10 @@ const App = createApp({
}
/**
* 检查是否有离线预约码缓存
* @returns {boolean} 如果有离线预约码缓存且有效,则返回 true;否则返回 false
*/
const has_offline_qr_cache = () => {
try {
const data = Taro.getStorageSync('OFFLINE_QR_DATA')
return Array.isArray(data) && data.length > 0
} catch (e) {
return false
}
}
/**
* 处理在启动时出现的不良网络情况
* - 当网络连接不良且有离线预约码缓存时,提示用户是否使用缓存预约码进入离线模式
* - 当网络连接不良且无离线预约码缓存时,提示用户网络连接不畅
* @returns {Promise<boolean>} 如果用户选择使用缓存预约码进入离线模式,则返回 true;否则返回 false
* - 当网络连接不良且有离线预约记录缓存时,提示用户是否使用缓存进入离线模式
* - 当网络连接不良且无缓存时,提示用户网络连接不畅
* @returns {Promise<boolean>} 如果用户选择进入离线模式,则返回 true;否则返回 false
*/
const handle_bad_network_on_launch = async () => {
/**
......@@ -153,16 +97,16 @@ const App = createApp({
has_shown_network_modal = true
if (has_offline_qr_cache()) {
if (has_offline_booking_cache()) {
try {
const modal_res = await Taro.showModal({
title: '网络连接不畅',
content: '当前网络信号较弱,可使用已缓存的预约进入离线模式',
confirmText: '预约',
content: '当前网络信号较弱,可使用已缓存的预约记录进入离线模式',
confirmText: '预约记录',
cancelText: '知道了',
})
if (modal_res?.confirm) {
await Taro.reLaunch({ url: '/pages/offlineBookingCode/index' })
await Taro.reLaunch({ url: '/pages/offlineBookingList/index' })
return true
}
} catch (e) {
......@@ -183,10 +127,8 @@ const App = createApp({
if (should_stop) return
/**
* 尝试在网络可用时预加载二维码数据
* 尝试在网络可用时预加载离线预约记录数据
* - 仅在有授权时调用
* - 成功后将数据存储到本地缓存(key: OFFLINE_QR_DATA)
* - 失败则移除缓存
* @returns {Promise<void>}
*/
const try_preload_when_online = () => {
......@@ -194,7 +136,7 @@ const App = createApp({
Taro.getNetworkType({
success: (res) => {
if (is_usable_network(res.networkType)) {
preloadQrData()
preloadBookingData()
}
}
})
......
<!--
* @Date: 2024-01-16 10:06:47
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-08 16:02:07
* @LastEditTime: 2026-01-13 15:18:07
* @FilePath: /xyxBooking-weapp/src/components/qrCode.vue
* @Description: 预约码卡组件
-->
......@@ -187,23 +187,9 @@ const init = async () => {
if (validData.length > 0) {
userList.value = formatGroup(validData);
// 缓存数据供离线模式使用
const offline_data = userList.value.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);
refreshBtn();
} else {
userList.value = [];
// 清空缓存
Taro.removeStorageSync('OFFLINE_QR_DATA');
}
}
} catch (err) {
......
<!--
* @Date: 2024-01-24 16:38:13
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-30 15:19:44
* @LastEditTime: 2026-01-13 15:04:21
* @FilePath: /xyxBooking-weapp/src/components/reserveCard.vue
* @Description: 预约记录卡组件
-->
......@@ -9,7 +9,8 @@
<view class="booking-list-item" @tap="goToDetail(reserve_info)">
<view class="booking-list-item-header">
<view>{{ reserve_info.booking_time }}</view>
<view :class="[formatStatus(reserve_info.status)?.key, 'status']">{{ formatStatus(reserve_info.status)?.value }}</view>
<view v-if="is_offline" class="status offline">离线</view>
<view v-else :class="[status_info.key, 'status']">{{ status_info.value }}</view>
</view>
<view class="booking-list-item-body">
<view class="booking-num">
......@@ -39,10 +40,20 @@ const props = defineProps({
type: Object,
default: () => ({}),
},
detail_path: {
type: String,
default: '/bookingDetail',
},
is_offline: {
type: Boolean,
default: false,
},
});
const reserve_info = computed(() => props.data);
const is_offline = computed(() => props.is_offline);
const CodeStatus = {
APPLY: '1',
PAYING: '2',
......@@ -95,10 +106,14 @@ const formatStatus = (status) => {
}
}
const status_info = computed(() => {
return formatStatus(reserve_info.value?.status) || { key: '', value: '' }
})
const goToDetail = (item) => {
// 只有成功、已使用、已取消(退款成功)才跳转详情
if (item.status === CodeStatus.SUCCESS || item.status === CodeStatus.USED || item.status === CodeStatus.CANCEL) {
go('/bookingDetail', { pay_id: item.pay_id });
go(props.detail_path, { pay_id: item.pay_id });
}
}
</script>
......@@ -128,6 +143,11 @@ const goToDetail = (item) => {
padding: 4rpx 12rpx;
border-radius: 8rpx;
&.offline {
color: #999;
background-color: #EEE;
}
&.success {
color: #A67939;
background-color: #FBEEDC;
......
/**
* 刷新离线预约记录缓存
* - 仅在有授权且网络可用时调用
* - 成功后将数据存储到本地缓存(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
}
}
<!--
* @Date: 2024-01-16 10:06:47
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-07 22:27:24
* @LastEditTime: 2026-01-13 15:19:11
* @FilePath: /xyxBooking-weapp/src/pages/bookingCode/index.vue
* @Description: 文件描述
-->
......@@ -41,6 +41,7 @@ import icon_3 from '@/assets/images/首页01@2x.png'
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'
const go = useGo();
......@@ -49,9 +50,11 @@ useDidShow(() => {
success: (res) => {
const isConnected = ['wifi', '4g', '5g', '3g'].includes(res.networkType);
if (!isConnected) {
Taro.redirectTo({
url: '/pages/weakNetwork/index'
})
if (has_offline_booking_cache()) {
Taro.redirectTo({ url: '/pages/offlineBookingList/index' })
} else {
Taro.redirectTo({ url: '/pages/weakNetwork/index' })
}
}
}
});
......
......@@ -6,121 +6,26 @@
* @Description: 线下预约码页面
-->
<template>
<view class="offline-booking-code-page">
<view class="header-tip">
<IconFont name="tips" size="15" color="#A67939" />
<text>您当前处于离线模式,仅展示本地缓存的预约码</text>
</view>
<view style="padding: 32rpx;">
<offlineQrCode :list="qrList"></offlineQrCode>
<view class="warning">
<view style="display: flex; align-items: center; justify-content: center;"><IconFont name="tips" /><text style="margin-left: 10rpx;">温馨提示</text></view>
<view style="margin-top: 16rpx;">一人一码,扫码或识别身份证成功后进入</view>
</view>
</view>
<view class="action-area">
<button class="home-btn" @tap="toHome">返回首页</button>
</view>
</view>
<view class="offline-booking-code-page"></view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { onMounted } from 'vue'
import Taro from '@tarojs/taro'
import offlineQrCode from '@/components/offlineQrCode';
import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
const go = useGo();
const qrList = ref([]);
const toHome = () => {
Taro.reLaunch({ url: '/pages/index/index' });
}
// TODO: Mock Data as per requirement
const getMockData = () => {
return [
{
name: '测试用户1',
id_number: '110101199003078888',
qr_code: 'OFFLINE_MOCK_QR_001',
datetime: '2026-01-08 08:30-10:30',
sort: 0
},
{
name: '测试用户2',
id_number: '110101199205126666',
qr_code: 'OFFLINE_MOCK_QR_002',
datetime: '2026-01-08 08:30-10:30',
sort: 0
}
];
}
onMounted(() => {
try {
const cachedData = Taro.getStorageSync('OFFLINE_QR_DATA');
if (cachedData && cachedData.length > 0) {
qrList.value = cachedData;
} else {
// Requirement 4: Mock data if no data
console.log('No cached data found, using mock data');
qrList.value = getMockData();
}
} catch (e) {
console.error('Read storage failed', e);
qrList.value = getMockData();
}
Taro.nextTick(() => {
go('/pages/offlineBookingList/index')
})
});
</script>
<style lang="less">
.offline-booking-code-page {
position: relative;
min-height: 100vh;
background-color: #F6F6F6;
.header-tip {
background-color: #FEF8E8;
color: #A67939;
padding: 20rpx 32rpx;
font-size: 26rpx;
display: flex;
align-items: center;
text {
margin-left: 10rpx;
}
}
.warning {
text-align: center;
color: #A67939;
margin-top: 32rpx;
}
.action-area {
position: fixed;
bottom: 60rpx;
left: 0;
width: 100%;
display: flex;
justify-content: center;
.home-btn {
width: 600rpx;
height: 88rpx;
line-height: 88rpx;
background: #fff;
color: #A67939;
border: 2rpx solid #A67939;
border-radius: 44rpx;
font-size: 32rpx;
}
}
}
</style>
......
export default {
navigationBarTitleText: '离线预约详情'
}
<template>
<view class="offline-booking-detail-page">
<view class="header-tip">
<IconFont name="tips" size="15" color="#A67939" />
<text>您当前处于离线模式,仅展示本地缓存的数据</text>
</view>
<view class="content">
<offlineQrCode :list="qr_list" />
<view v-if="bill_info && bill_info.pay_id" class="detail-wrapper">
<view class="detail-item">
<view>参访时间:</view>
<view>{{ bill_info.datetime }}</view>
</view>
<view class="detail-item">
<view>参访人数:</view>
<view>{{ bill_info.total_qty }} 人</view>
</view>
<view class="detail-item">
<view>支付金额:</view>
<view>¥ {{ bill_info.total_amt }}</view>
</view>
<view class="detail-item">
<view>下单时间:</view>
<view>{{ bill_info.order_time }}</view>
</view>
<view class="detail-item">
<view>订单编号:</view>
<view>{{ bill_info.pay_id }}</view>
</view>
<view class="detail-item">
<view>订单状态:</view>
<view>{{ status_text }}</view>
</view>
</view>
</view>
<view class="action-area">
<button class="back-btn" @tap="toList">返回列表</button>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import Taro, { useDidShow, useRouter as useTaroRouter } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import offlineQrCode from '@/components/offlineQrCode.vue'
import { get_offline_booking_by_pay_id, build_offline_qr_list } from '@/composables/useOfflineBookingCache'
const router = useTaroRouter()
const bill_info = ref(null)
const qr_list = ref([])
const CodeStatus = {
APPLY: '1',
PAYING: '2',
SUCCESS: '3',
CANCEL: '5',
CANCELED: '7',
USED: '9',
REFUNDING: '11'
}
const status_text = computed(() => {
const status = bill_info.value?.status
switch (status) {
case CodeStatus.APPLY: return '待支付'
case CodeStatus.PAYING: return '支付中'
case CodeStatus.SUCCESS: return '预约成功'
case CodeStatus.CANCEL: return '已取消'
case CodeStatus.CANCELED: return '已取消'
case CodeStatus.USED: return '已使用'
case CodeStatus.REFUNDING: return '退款中'
default: return '未知状态'
}
})
const toList = () => {
Taro.navigateBack({
fail: () => {
Taro.reLaunch({ url: '/pages/offlineBookingList/index' })
}
})
}
const load_cache = () => {
const pay_id = router.params.pay_id
const data = get_offline_booking_by_pay_id(pay_id)
if (!data) {
Taro.showToast({ title: '本地无该订单缓存', icon: 'none' })
Taro.reLaunch({ url: '/pages/offlineBookingList/index' })
return
}
bill_info.value = data
qr_list.value = build_offline_qr_list(data)
}
useDidShow(() => {
load_cache()
})
</script>
<style lang="less">
.offline-booking-detail-page {
min-height: 100vh;
background-color: #F6F6F6;
.header-tip {
display: flex;
align-items: center;
padding: 20rpx 32rpx;
color: #A67939;
font-size: 26rpx;
background: #FFF;
}
.content {
padding: 32rpx;
padding-bottom: 180rpx;
}
.detail-wrapper {
background-color: #FFF;
border-radius: 16rpx;
padding: 32rpx;
margin-top: 32rpx;
box-shadow: 0 0 29rpx 0 rgba(106,106,106,0.1);
.detail-item {
display: flex;
justify-content: space-between;
margin-bottom: 26rpx;
color: #333;
font-size: 30rpx;
&:last-child {
margin-bottom: 0;
}
view:first-child {
color: #999;
width: 160rpx;
}
view:last-child {
flex: 1;
text-align: right;
}
}
}
.action-area {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 24rpx 32rpx;
background: #FFF;
box-sizing: border-box;
box-shadow: 0 -10rpx 8rpx 0 rgba(0,0,0,0.06);
.back-btn {
background-color: #A67939;
color: #FFF;
border-radius: 16rpx;
font-size: 32rpx;
padding: 22rpx 0;
}
}
}
</style>
export default {
navigationBarTitleText: '离线预约记录'
}
<template>
<view class="offline-booking-list-page">
<view class="header-tip">
<IconFont name="tips" size="15" color="#A67939" />
<text>您当前处于离线模式,仅展示本地缓存的预约记录</text>
</view>
<view class="list-wrapper">
<view v-for="(item, index) in booking_list" :key="index">
<reserveCard :data="item" detail_path="/offlineBookingDetail" is_offline />
</view>
<view v-if="!booking_list.length" class="empty">
<text>本地无缓存预约记录</text>
</view>
</view>
<view class="action-area">
<button class="home-btn" @tap="toHome">返回首页</button>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import Taro, { useDidShow } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import reserveCard from '@/components/reserveCard.vue'
import { get_offline_booking_cache } from '@/composables/useOfflineBookingCache'
const booking_list = ref([])
const toHome = () => {
Taro.reLaunch({ url: '/pages/index/index' })
}
const load_cache = () => {
booking_list.value = get_offline_booking_cache()
}
useDidShow(() => {
load_cache()
})
</script>
<style lang="less">
.offline-booking-list-page {
min-height: 100vh;
background-color: #F6F6F6;
.header-tip {
display: flex;
align-items: center;
padding: 20rpx 32rpx;
color: #A67939;
font-size: 26rpx;
background: #FFF;
}
.list-wrapper {
padding: 32rpx;
}
.empty {
padding: 120rpx 0;
text-align: center;
color: #A67939;
font-size: 32rpx;
}
.action-area {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 24rpx 32rpx;
background: #FFF;
box-sizing: border-box;
box-shadow: 0 -10rpx 8rpx 0 rgba(0,0,0,0.06);
.home-btn {
background-color: #A67939;
color: #FFF;
border-radius: 16rpx;
font-size: 32rpx;
padding: 22rpx 0;
}
}
}
</style>
......@@ -37,6 +37,7 @@ import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
import { billInfoAPI } from '@/api/index'
import { formatDatetime } from '@/utils/tools';
import { refresh_offline_booking_cache } from '@/composables/useOfflineBookingCache'
const router = useTaroRouter();
const go = useGo();
......@@ -57,6 +58,7 @@ useDidShow(async () => {
data.datetime = data && formatDatetime(data);
billInfo.value = data;
}
refresh_offline_booking_cache({ force: true })
})
</script>
......
......@@ -17,7 +17,7 @@
<view class="offline-entry" @tap="toOfflineCode">
<view class="circle-btn">
<image :src="icon_invite" style="width: 60rpx; height: 60rpx; margin-bottom: 16rpx;" />
<text>预约</text>
<text>预约记录</text>
</view>
</view>
......@@ -38,7 +38,7 @@ import icon_invite from '@/assets/images/二维码@2x2.png'
const go = useGo();
const toOfflineCode = () => {
go('/pages/offlineBookingCode/index');
go('/pages/offlineBookingList/index');
}
const retry = () => {
......