hookehuyr

fix(booking): 修复二维码已核销时取消预约按钮仍显示的问题

- qrCode 组件添加状态变化事件通知机制
- 预约详情页监听状态变化并刷新订单信息
- 订单已核销时显示禁用提示而非取消按钮
- 移除未使用的导入和变量,修复 ESLint 警告

问题详情:
- 二维码轮询更新状态时只更新组件内部状态
- 父组件订单信息未同步更新导致取消按钮不消失

解决方案:
- qrCode 组件状态改变时触发 status-change 事件
- 父组件接收到事件后调用 billInfoAPI 刷新订单
- 订单状态更新为 USED 后自动隐藏取消按钮

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -62,7 +62,6 @@ ...@@ -62,7 +62,6 @@
62 62
63 <script setup> 63 <script setup>
64 import { ref, computed, watch, onMounted, onUnmounted } from 'vue' 64 import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
65 -import Taro from '@tarojs/taro'
66 import { formatDatetime, mask_id_number, get_qrcode_status_text } from '@/utils/tools' 65 import { formatDatetime, mask_id_number, get_qrcode_status_text } from '@/utils/tools'
67 import { qrcodeListAPI, qrcodeStatusAPI, billPersonAPI } from '@/api/index' 66 import { qrcodeListAPI, qrcodeStatusAPI, billPersonAPI } from '@/api/index'
68 import { useGo } from '@/hooks/useGo' 67 import { useGo } from '@/hooks/useGo'
...@@ -86,6 +85,8 @@ const props = defineProps({ ...@@ -86,6 +85,8 @@ const props = defineProps({
86 } 85 }
87 }) 86 })
88 87
88 +const emit = defineEmits(['status-change'])
89 +
89 const select_index = ref(0) 90 const select_index = ref(0)
90 const userList = ref([]) 91 const userList = ref([])
91 92
...@@ -158,6 +159,7 @@ const STATUS_CODE = { ...@@ -158,6 +159,7 @@ const STATUS_CODE = {
158 /** 159 /**
159 * @description 刷新当前选中二维码状态 160 * @description 刷新当前选中二维码状态
160 * - 仅在当前选中用户存在时请求 161 * - 仅在当前选中用户存在时请求
162 + * - 状态改变时通知父组件刷新订单信息
161 * @returns {Promise<void>} 无返回值 163 * @returns {Promise<void>} 无返回值
162 */ 164 */
163 const refreshBtn = async () => { 165 const refreshBtn = async () => {
...@@ -168,7 +170,13 @@ const refreshBtn = async () => { ...@@ -168,7 +170,13 @@ const refreshBtn = async () => {
168 qr_code: userList.value[select_index.value].qr_code 170 qr_code: userList.value[select_index.value].qr_code
169 }) 171 })
170 if (code) { 172 if (code) {
173 + const oldStatus = useStatus.value
171 useStatus.value = data.status 174 useStatus.value = data.status
175 +
176 + // 当状态发生改变时,通知父组件刷新订单信息
177 + if (oldStatus !== data.status) {
178 + emit('status-change', data.status)
179 + }
172 } 180 }
173 } 181 }
174 182
......
...@@ -7,7 +7,13 @@ ...@@ -7,7 +7,13 @@
7 --> 7 -->
8 <template> 8 <template>
9 <view class="booking-detail-page"> 9 <view class="booking-detail-page">
10 - <qrCode ref="qr_code_ref" :status="qrCodeStatus" type="detail" :payId="pay_id"></qrCode> 10 + <qrCode
11 + ref="qr_code_ref"
12 + :status="qrCodeStatus"
13 + type="detail"
14 + :payId="pay_id"
15 + @status-change="handleQrCodeStatusChange"
16 + ></qrCode>
11 <view v-if="billInfo.pay_id" class="detail-wrapper"> 17 <view v-if="billInfo.pay_id" class="detail-wrapper">
12 <view class="detail-item"> 18 <view class="detail-item">
13 <view>参访时间:</view> 19 <view>参访时间:</view>
...@@ -41,6 +47,9 @@ ...@@ -41,6 +47,9 @@
41 > 47 >
42 <view @tap="cancelBooking" class="cancel-btn">取消预约</view> 48 <view @tap="cancelBooking" class="cancel-btn">取消预约</view>
43 </view> 49 </view>
50 + <view v-else-if="billInfo.status === CodeStatus.USED" class="cancel-wrapper">
51 + <view class="cancel-btn disabled">订单已核销,无法取消</view>
52 + </view>
44 </view> 53 </view>
45 </template> 54 </template>
46 55
...@@ -82,6 +91,24 @@ const qrCodeStatusText = computed(() => { ...@@ -82,6 +91,24 @@ const qrCodeStatusText = computed(() => {
82 }) 91 })
83 92
84 /** 93 /**
94 + * @description 处理二维码状态变化
95 + * - 当二维码被核销时,刷新订单信息以更新页面状态
96 + * @param {string} newStatus 新的二维码状态
97 + * @returns {Promise<void>} 无返回值
98 + */
99 +const handleQrCodeStatusChange = async newStatus => {
100 + // 当二维码状态变为已使用时,刷新订单信息
101 + if (newStatus === CodeStatus.USED && pay_id.value) {
102 + const { code, data } = await billInfoAPI({ pay_id: pay_id.value })
103 + if (code) {
104 + data.datetime = data && formatDatetime(data)
105 + data.order_time = data.created_time ? data.created_time.slice(0, -3) : ''
106 + billInfo.value = data
107 + }
108 + }
109 +}
110 +
111 +/**
85 * @description 取消预约 112 * @description 取消预约
86 * - 成功后刷新离线缓存(保证弱网/离线模式数据一致) 113 * - 成功后刷新离线缓存(保证弱网/离线模式数据一致)
87 * @returns {Promise<void>} 无返回值 114 * @returns {Promise<void>} 无返回值
...@@ -95,12 +122,13 @@ const cancelBooking = async () => { ...@@ -95,12 +122,13 @@ const cancelBooking = async () => {
95 122
96 if (confirm) { 123 if (confirm) {
97 Taro.showLoading({ title: '取消中...' }) 124 Taro.showLoading({ title: '取消中...' })
98 - const { code, data } = await icbcRefundAPI({ pay_id: pay_id.value }) 125 + const { code } = await icbcRefundAPI({ pay_id: pay_id.value })
99 Taro.hideLoading() 126 Taro.hideLoading()
100 if (code) { 127 if (code) {
101 Taro.showToast({ title: '取消成功' }) 128 Taro.showToast({ title: '取消成功' })
102 try { 129 try {
103 await refresh_offline_booking_cache({ force: true }) 130 await refresh_offline_booking_cache({ force: true })
131 + // eslint-disable-next-line no-empty
104 } catch (e) {} 132 } catch (e) {}
105 Taro.navigateBack() 133 Taro.navigateBack()
106 } else { 134 } else {
...@@ -179,6 +207,12 @@ useDidHide(() => { ...@@ -179,6 +207,12 @@ useDidHide(() => {
179 padding: 26rpx 0; 207 padding: 26rpx 0;
180 border-radius: 16rpx; 208 border-radius: 16rpx;
181 font-size: 35rpx; 209 font-size: 35rpx;
210 +
211 + &.disabled {
212 + color: #999;
213 + border-color: #999;
214 + background-color: #f5f5f5;
215 + }
182 } 216 }
183 } 217 }
184 } 218 }
......