fix(booking): 修复二维码已核销时取消预约按钮仍显示的问题
- qrCode 组件添加状态变化事件通知机制 - 预约详情页监听状态变化并刷新订单信息 - 订单已核销时显示禁用提示而非取消按钮 - 移除未使用的导入和变量,修复 ESLint 警告 问题详情: - 二维码轮询更新状态时只更新组件内部状态 - 父组件订单信息未同步更新导致取消按钮不消失 解决方案: - qrCode 组件状态改变时触发 status-change 事件 - 父组件接收到事件后调用 billInfoAPI 刷新订单 - 订单状态更新为 USED 后自动隐藏取消按钮 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Showing
2 changed files
with
45 additions
and
3 deletions
| ... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment