hookehuyr

feat(离线预约): 优化离线预约缓存逻辑和API

重构离线预约缓存处理逻辑,增强数据提取和格式化能力
更新API端点并完善文档注释
移除离线预约详情页中冗余的状态显示代码
/*
* @Date: 2023-08-24 09:42:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-13 14:52:29
* @LastEditTime: 2026-01-13 18:30:30
* @FilePath: /xyxBooking-weapp/src/api/index.js
* @Description: 文件描述
*/
......@@ -21,7 +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',
BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_all_info',
ICBC_REFUND: '/srv/?a=icbc_refund',
BILL_PREPARE: '/srv/?a=api&t=bill_person',
BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status',
......@@ -183,8 +183,22 @@ 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}
* @description: 所有预约单的详情(用于离线缓存:列表+详情)
* @method: GET
* @returns: {Object}
* @returns: {Number} code
* @returns: {String} msg
* @returns: {Array} data
* @returns: {Number} data[].bill_id 预约单id
* @returns: {String} data[].begin_time 时段起始时间
* @returns: {String} data[].end_time 时段结束时间
* @returns: {Number} data[].total_qty 预约人数
* @returns: {String} data[].total_amt 金额
* @returns: {String} data[].status 状态(1/2/3/5/7/9/11)
* @returns: {String} data[].created_time 下单时间
* @returns: {String} data[].pay_id 订单编号/支付凭证
* @returns: {Object} data[].list 列表字段集合
* @returns: {Number} data[].list.show_cancel_reserve 显示“取消预约”按钮(1=显示)
*/
export const billOfflineAllAPI = (params) => fn(fetch.get(Api.BILL_OFFLINE_ALL, params));
......
......@@ -16,18 +16,60 @@ export const OFFLINE_BOOKING_CACHE_KEY = 'OFFLINE_BOOKING_DATA'
let refresh_promise = null
const extract_bill_payload = (bill) => {
if (!bill) return {}
const data = { ...bill }
const list = data.list
if (list && typeof list === 'object' && !Array.isArray(list)) {
return { ...list, ...data }
}
return data
}
const extract_person_list = (bill) => {
if (!bill) return []
/**
* 从预约记录中提取人员列表
* - 考虑不同字段名的情况(如 person_list, bill_person_list, persons, qrcode_list, qr_list, detail_list)
* - 确保返回的是数组类型
*/
const candidate =
(Array.isArray(bill.list) ? bill.list : null) ||
(Array.isArray(bill?.list?.list) ? bill.list.list : null) ||
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} item - 原始预约记录项
* @returns {Object} 格式化后的预约记录项
*/
const normalize_bill_item = (item) => {
const data = item ? { ...item } : {}
const data = extract_bill_payload(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) : '')
if (!data.person_name) {
const person_list = extract_person_list(item)
const first = person_list[0]
const name = first?.name || first?.person_name
if (name) data.person_name = name
}
return data
}
......@@ -70,17 +112,7 @@ export const get_offline_booking_by_pay_id = (pay_id) => {
* @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 : []
return extract_person_list(bill)
}
/**
......@@ -93,14 +125,17 @@ export const build_offline_qr_list = (bill) => {
const datetime = bill?.datetime || formatDatetime(bill || {})
return list
.filter((item) => item && item.qr_code !== '')
.filter((item) => item && (item.qr_code || item.qrcode || item.qrCode) && (item.qr_code || item.qrcode || item.qrCode) !== '')
.map((item) => {
const begin_time = item.begin_time || bill?.begin_time
const end_time = item.end_time || bill?.end_time
const qr_code = item.qr_code || item.qrcode || item.qrCode
const name = item.name || item.person_name || item.real_name
const id_number = item.id_number || item.idcard || item.idCard || item.id
return {
name: item.name,
id_number: item.id_number,
qr_code: item.qr_code,
name,
id_number,
qr_code,
begin_time,
end_time,
datetime: item.datetime || (begin_time && end_time ? formatDatetime({ begin_time, end_time }) : datetime),
......
<!--
* @Date: 2024-01-16 13:19:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-30 16:10:10
* @LastEditTime: 2026-01-13 18:36:58
* @FilePath: /xyxBooking-weapp/src/pages/bookingDetail/index.vue
* @Description: 预约记录详情
-->
......@@ -48,6 +48,7 @@ import { useGo } from '@/hooks/useGo'
import qrCode from '@/components/qrCode';
import { billInfoAPI, icbcRefundAPI } from '@/api/index'
import { formatDatetime } from '@/utils/tools';
import { refresh_offline_booking_cache } from '@/composables/useOfflineBookingCache'
const router = useTaroRouter();
const go = useGo();
......@@ -90,6 +91,9 @@ const cancelBooking = async () => {
Taro.hideLoading();
if (code) {
Taro.showToast({ title: '取消成功' });
try {
await refresh_offline_booking_cache({ force: true })
} catch (e) {}
Taro.navigateBack();
} else {
Taro.showToast({ title: '取消失败', icon: 'none' });
......
......@@ -29,10 +29,10 @@
<view>订单编号:</view>
<view>{{ bill_info.pay_id }}</view>
</view>
<view class="detail-item">
<!-- <view class="detail-item">
<view>订单状态:</view>
<view>{{ status_text }}</view>
</view>
</view> -->
</view>
</view>
......@@ -53,29 +53,29 @@ 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 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({
......@@ -170,4 +170,3 @@ useDidShow(() => {
}
}
</style>
......