hookehuyr

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

重构离线预约缓存处理逻辑,增强数据提取和格式化能力
更新API端点并完善文档注释
移除离线预约详情页中冗余的状态显示代码
1 /* 1 /*
2 * @Date: 2023-08-24 09:42:27 2 * @Date: 2023-08-24 09:42:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-13 14:52:29 4 + * @LastEditTime: 2026-01-13 18:30:30
5 * @FilePath: /xyxBooking-weapp/src/api/index.js 5 * @FilePath: /xyxBooking-weapp/src/api/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -21,7 +21,7 @@ const Api = { ...@@ -21,7 +21,7 @@ const Api = {
21 QRCODE_LIST: '/srv/?a=api&t=qrcode_list', 21 QRCODE_LIST: '/srv/?a=api&t=qrcode_list',
22 QRCODE_STATUS: '/srv/?a=api&t=qrcode_status', 22 QRCODE_STATUS: '/srv/?a=api&t=qrcode_status',
23 BILL_LIST: '/srv/?a=api&t=bill_list', 23 BILL_LIST: '/srv/?a=api&t=bill_list',
24 - BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_offline_all', 24 + BILL_OFFLINE_ALL: '/srv/?a=api&t=bill_all_info',
25 ICBC_REFUND: '/srv/?a=icbc_refund', 25 ICBC_REFUND: '/srv/?a=icbc_refund',
26 BILL_PREPARE: '/srv/?a=api&t=bill_person', 26 BILL_PREPARE: '/srv/?a=api&t=bill_person',
27 BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status', 27 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 ...@@ -183,8 +183,22 @@ export const qrcodeStatusAPI = (params) => fn(fetch.get(Api.QRCODE_STATUS, param
183 export const billListAPI = (params) => fn(fetch.get(Api.BILL_LIST, params)); 183 export const billListAPI = (params) => fn(fetch.get(Api.BILL_LIST, params));
184 184
185 /** 185 /**
186 - * @description: 离线预约记录全量数据(列表+详情) 186 + * @description: 所有预约单的详情(用于离线缓存:列表+详情)
187 - * @returns {String} 187 + * @method: GET
188 + * @returns: {Object}
189 + * @returns: {Number} code
190 + * @returns: {String} msg
191 + * @returns: {Array} data
192 + * @returns: {Number} data[].bill_id 预约单id
193 + * @returns: {String} data[].begin_time 时段起始时间
194 + * @returns: {String} data[].end_time 时段结束时间
195 + * @returns: {Number} data[].total_qty 预约人数
196 + * @returns: {String} data[].total_amt 金额
197 + * @returns: {String} data[].status 状态(1/2/3/5/7/9/11)
198 + * @returns: {String} data[].created_time 下单时间
199 + * @returns: {String} data[].pay_id 订单编号/支付凭证
200 + * @returns: {Object} data[].list 列表字段集合
201 + * @returns: {Number} data[].list.show_cancel_reserve 显示“取消预约”按钮(1=显示)
188 */ 202 */
189 export const billOfflineAllAPI = (params) => fn(fetch.get(Api.BILL_OFFLINE_ALL, params)); 203 export const billOfflineAllAPI = (params) => fn(fetch.get(Api.BILL_OFFLINE_ALL, params));
190 204
......
...@@ -16,18 +16,60 @@ export const OFFLINE_BOOKING_CACHE_KEY = 'OFFLINE_BOOKING_DATA' ...@@ -16,18 +16,60 @@ export const OFFLINE_BOOKING_CACHE_KEY = 'OFFLINE_BOOKING_DATA'
16 16
17 let refresh_promise = null 17 let refresh_promise = null
18 18
19 +const extract_bill_payload = (bill) => {
20 + if (!bill) return {}
21 +
22 + const data = { ...bill }
23 + const list = data.list
24 +
25 + if (list && typeof list === 'object' && !Array.isArray(list)) {
26 + return { ...list, ...data }
27 + }
28 +
29 + return data
30 +}
31 +
32 +const extract_person_list = (bill) => {
33 + if (!bill) return []
34 +
35 + /**
36 + * 从预约记录中提取人员列表
37 + * - 考虑不同字段名的情况(如 person_list, bill_person_list, persons, qrcode_list, qr_list, detail_list)
38 + * - 确保返回的是数组类型
39 + */
40 + const candidate =
41 + (Array.isArray(bill.list) ? bill.list : null) ||
42 + (Array.isArray(bill?.list?.list) ? bill.list.list : null) ||
43 + bill.person_list ||
44 + bill.bill_person_list ||
45 + bill.persons ||
46 + bill.qrcode_list ||
47 + bill.qr_list ||
48 + bill.detail_list ||
49 + []
50 +
51 + return Array.isArray(candidate) ? candidate : []
52 +}
53 +
19 /** 54 /**
20 * 格式化预约记录项 55 * 格式化预约记录项
21 * @param {Object} item - 原始预约记录项 56 * @param {Object} item - 原始预约记录项
22 * @returns {Object} 格式化后的预约记录项 57 * @returns {Object} 格式化后的预约记录项
23 */ 58 */
24 const normalize_bill_item = (item) => { 59 const normalize_bill_item = (item) => {
25 - const data = item ? { ...item } : {} 60 + const data = extract_bill_payload(item)
26 61
27 data.datetime = data.datetime || formatDatetime(data) 62 data.datetime = data.datetime || formatDatetime(data)
28 data.booking_time = data.booking_time || data.datetime 63 data.booking_time = data.booking_time || data.datetime
29 data.order_time = data.order_time || (data.created_time ? data.created_time.slice(0, -3) : '') 64 data.order_time = data.order_time || (data.created_time ? data.created_time.slice(0, -3) : '')
30 65
66 + if (!data.person_name) {
67 + const person_list = extract_person_list(item)
68 + const first = person_list[0]
69 + const name = first?.name || first?.person_name
70 + if (name) data.person_name = name
71 + }
72 +
31 return data 73 return data
32 } 74 }
33 75
...@@ -70,17 +112,7 @@ export const get_offline_booking_by_pay_id = (pay_id) => { ...@@ -70,17 +112,7 @@ export const get_offline_booking_by_pay_id = (pay_id) => {
70 * @returns {Array} 人员列表(包含姓名、身份证号、二维码等信息) 112 * @returns {Array} 人员列表(包含姓名、身份证号、二维码等信息)
71 */ 113 */
72 export const get_offline_bill_person_list = (bill) => { 114 export const get_offline_bill_person_list = (bill) => {
73 - if (!bill) return [] 115 + return extract_person_list(bill)
74 - const candidate =
75 - bill.person_list ||
76 - bill.bill_person_list ||
77 - bill.persons ||
78 - bill.qrcode_list ||
79 - bill.qr_list ||
80 - bill.detail_list ||
81 - []
82 -
83 - return Array.isArray(candidate) ? candidate : []
84 } 116 }
85 117
86 /** 118 /**
...@@ -93,14 +125,17 @@ export const build_offline_qr_list = (bill) => { ...@@ -93,14 +125,17 @@ export const build_offline_qr_list = (bill) => {
93 const datetime = bill?.datetime || formatDatetime(bill || {}) 125 const datetime = bill?.datetime || formatDatetime(bill || {})
94 126
95 return list 127 return list
96 - .filter((item) => item && item.qr_code !== '') 128 + .filter((item) => item && (item.qr_code || item.qrcode || item.qrCode) && (item.qr_code || item.qrcode || item.qrCode) !== '')
97 .map((item) => { 129 .map((item) => {
98 const begin_time = item.begin_time || bill?.begin_time 130 const begin_time = item.begin_time || bill?.begin_time
99 const end_time = item.end_time || bill?.end_time 131 const end_time = item.end_time || bill?.end_time
132 + const qr_code = item.qr_code || item.qrcode || item.qrCode
133 + const name = item.name || item.person_name || item.real_name
134 + const id_number = item.id_number || item.idcard || item.idCard || item.id
100 return { 135 return {
101 - name: item.name, 136 + name,
102 - id_number: item.id_number, 137 + id_number,
103 - qr_code: item.qr_code, 138 + qr_code,
104 begin_time, 139 begin_time,
105 end_time, 140 end_time,
106 datetime: item.datetime || (begin_time && end_time ? formatDatetime({ begin_time, end_time }) : datetime), 141 datetime: item.datetime || (begin_time && end_time ? formatDatetime({ begin_time, end_time }) : datetime),
......
1 <!-- 1 <!--
2 * @Date: 2024-01-16 13:19:23 2 * @Date: 2024-01-16 13:19:23
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-01-30 16:10:10 4 + * @LastEditTime: 2026-01-13 18:36:58
5 * @FilePath: /xyxBooking-weapp/src/pages/bookingDetail/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/bookingDetail/index.vue
6 * @Description: 预约记录详情 6 * @Description: 预约记录详情
7 --> 7 -->
...@@ -48,6 +48,7 @@ import { useGo } from '@/hooks/useGo' ...@@ -48,6 +48,7 @@ import { useGo } from '@/hooks/useGo'
48 import qrCode from '@/components/qrCode'; 48 import qrCode from '@/components/qrCode';
49 import { billInfoAPI, icbcRefundAPI } from '@/api/index' 49 import { billInfoAPI, icbcRefundAPI } from '@/api/index'
50 import { formatDatetime } from '@/utils/tools'; 50 import { formatDatetime } from '@/utils/tools';
51 +import { refresh_offline_booking_cache } from '@/composables/useOfflineBookingCache'
51 52
52 const router = useTaroRouter(); 53 const router = useTaroRouter();
53 const go = useGo(); 54 const go = useGo();
...@@ -90,6 +91,9 @@ const cancelBooking = async () => { ...@@ -90,6 +91,9 @@ const cancelBooking = async () => {
90 Taro.hideLoading(); 91 Taro.hideLoading();
91 if (code) { 92 if (code) {
92 Taro.showToast({ title: '取消成功' }); 93 Taro.showToast({ title: '取消成功' });
94 + try {
95 + await refresh_offline_booking_cache({ force: true })
96 + } catch (e) {}
93 Taro.navigateBack(); 97 Taro.navigateBack();
94 } else { 98 } else {
95 Taro.showToast({ title: '取消失败', icon: 'none' }); 99 Taro.showToast({ title: '取消失败', icon: 'none' });
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
29 <view>订单编号:</view> 29 <view>订单编号:</view>
30 <view>{{ bill_info.pay_id }}</view> 30 <view>{{ bill_info.pay_id }}</view>
31 </view> 31 </view>
32 - <view class="detail-item"> 32 + <!-- <view class="detail-item">
33 <view>订单状态:</view> 33 <view>订单状态:</view>
34 <view>{{ status_text }}</view> 34 <view>{{ status_text }}</view>
35 - </view> 35 + </view> -->
36 </view> 36 </view>
37 </view> 37 </view>
38 38
...@@ -53,29 +53,29 @@ const router = useTaroRouter() ...@@ -53,29 +53,29 @@ const router = useTaroRouter()
53 const bill_info = ref(null) 53 const bill_info = ref(null)
54 const qr_list = ref([]) 54 const qr_list = ref([])
55 55
56 -const CodeStatus = { 56 +// const CodeStatus = {
57 - APPLY: '1', 57 +// APPLY: '1',
58 - PAYING: '2', 58 +// PAYING: '2',
59 - SUCCESS: '3', 59 +// SUCCESS: '3',
60 - CANCEL: '5', 60 +// CANCEL: '5',
61 - CANCELED: '7', 61 +// CANCELED: '7',
62 - USED: '9', 62 +// USED: '9',
63 - REFUNDING: '11' 63 +// REFUNDING: '11'
64 -} 64 +// }
65 - 65 +
66 -const status_text = computed(() => { 66 +// const status_text = computed(() => {
67 - const status = bill_info.value?.status 67 +// const status = bill_info.value?.status
68 - switch (status) { 68 +// switch (status) {
69 - case CodeStatus.APPLY: return '待支付' 69 +// case CodeStatus.APPLY: return '待支付'
70 - case CodeStatus.PAYING: return '支付中' 70 +// case CodeStatus.PAYING: return '支付中'
71 - case CodeStatus.SUCCESS: return '预约成功' 71 +// case CodeStatus.SUCCESS: return '预约成功'
72 - case CodeStatus.CANCEL: return '已取消' 72 +// case CodeStatus.CANCEL: return '已取消'
73 - case CodeStatus.CANCELED: return '已取消' 73 +// case CodeStatus.CANCELED: return '已取消'
74 - case CodeStatus.USED: return '已使用' 74 +// case CodeStatus.USED: return '已使用'
75 - case CodeStatus.REFUNDING: return '退款中' 75 +// case CodeStatus.REFUNDING: return '退款中'
76 - default: return '未知状态' 76 +// default: return '未知状态'
77 - } 77 +// }
78 -}) 78 +// })
79 79
80 const toList = () => { 80 const toList = () => {
81 Taro.navigateBack({ 81 Taro.navigateBack({
...@@ -170,4 +170,3 @@ useDidShow(() => { ...@@ -170,4 +170,3 @@ useDidShow(() => {
170 } 170 }
171 } 171 }
172 </style> 172 </style>
173 -
......