index.vue 5.42 KB
<!--
 * @Date: 2026-01-08 13:01:20
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-16 16:14:06
 * @FilePath: /xyxBooking-weapp/src/pages/verificationResult/index.vue
 * @Description: 核销结果页面
-->
<template>
    <view class="min-h-screen bg-gray-100 p-4 verify-page">
        <view class="rounded-2xl bg-white p-4 shadow-sm">
            <view class="flex items-center">
                <view class="flex h-11 w-11 items-center justify-center rounded-full bg-amber-50">
                    <icon :type="status_icon_type" size="24" :color="status_icon_color" />
                </view>
                <view class="ml-4 flex-1">
                    <view class="text-sm font-semibold text-gray-900">{{ status_title }}</view>
                    <view class="mt-1 text-xs text-gray-500">{{ msg }}</view>
                </view>
            </view>
        </view>

        <view class="mt-4 rounded-2xl bg-white p-5 shadow-sm">
            <view class="text-xs text-gray-500">核销权限</view>
            <view class="mt-2 text-sm font-medium text-gray-900">{{ can_redeem_text }}</view>
        </view>

        <view class="mt-4 rounded-2xl bg-white p-5 shadow-sm">
            <view class="text-xs text-gray-500">最近一次扫码内容</view>
            <view v-if="verify_code" class="mt-2 break-all whitespace-pre-wrap text-sm font-medium text-gray-900">{{ verify_code }}</view>
            <view v-else class="mt-2 text-sm text-gray-400">暂无扫码内容</view>
        </view>

        <view class="verify-footer">
            <nut-button
                block
                color="#A67939"
                :loading="verify_status === 'verifying'"
                :disabled="verify_status === 'verifying'"
                class="verify-btn"
                @tap="start_scan_and_verify"
            >
                核销
            </nut-button>
            <view class="mt-4 text-center text-xs text-gray-400">扫描预约码二维码进行核销</view>
        </view>
    </view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useRouter } from '@tarojs/taro'
import { verifyTicketAPI, checkRedeemPermissionAPI } from '@/api/index'
import Taro, { useDidShow } from '@tarojs/taro'
import { mainStore } from '@/stores/main'
import { useReplace } from '@/hooks/useGo'

const router = useRouter()
const verify_code = ref('')
const verify_status = ref('idle')
const msg = ref('请点击下方按钮进行核销')
const store = mainStore()
const replace = useReplace()

// TODO: 还没有真实字段信息, 如果有需要修改, 这个页面涉及verify_status的功能都要注意
const status_title = computed(() => {
    if (verify_status.value === 'verifying') return '核销中'
    if (verify_status.value === 'success') return '核销成功'
    if (verify_status.value === 'fail') return '核销失败'
    return '核销'
})

const status_icon_type = computed(() => {
    if (verify_status.value === 'verifying') return 'waiting'
    if (verify_status.value === 'success') return 'success'
    if (verify_status.value === 'fail') return 'cancel'
    return 'info'
})

const status_icon_color = computed(() => {
    if (verify_status.value === 'fail') return '#E24A4A'
    return '#A67939'
})

const can_redeem_text = computed(() => {
    if (store?.appUserInfo?.can_redeem === true) return '已授权'
    return '未授权'
})

/**
 * @description: 核销预约码
 * @param {string} code
 * @return {void}
 */

const verify_ticket = async (code) => {
    if (!code) return
    if (verify_status.value === 'verifying') return

    verify_code.value = code
    verify_status.value = 'verifying'
    msg.value = '核销中...'

    Taro.showLoading({ title: '核销中...' })
    try {
        const res = await verifyTicketAPI({ qr_code: code })
        if (res?.code === 1) {
            verify_status.value = 'success'
            msg.value = res?.msg || '核销成功'
            return
        }
        verify_status.value = 'fail'
        msg.value = res?.msg || '核销失败'
    } catch (e) {
        verify_status.value = 'fail'
        msg.value = '核销失败'
        Taro.showToast({ title: msg.value, icon: 'none' })
    } finally {
        Taro.hideLoading()
    }
}

useDidShow(async () => {
    const permission_res = await checkRedeemPermissionAPI()
    if (permission_res?.code !== 1) {
        replace('volunteerLogin')
        return
    }

    if (permission_res?.data) store.changeUserInfo(permission_res.data)
    if (permission_res?.data?.can_redeem !== true) {
        replace('volunteerLogin')
        return
    }

    const code = router?.params?.result || ''
    if (!code) {
        verify_code.value = ''
        verify_status.value = 'idle'
        msg.value = '请点击下方按钮进行核销'
        return
    }
    await verify_ticket(code)
})

const start_scan_and_verify = () => {
    Taro.scanCode({
        success: (res) => {
            verify_ticket(res?.result || '')
        },
        fail: () => {
        }
    })
}
</script>

<style lang="less">
.verify-page {
    padding-bottom: 220rpx;
}

.verify-footer {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 750rpx;
    padding: 24rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
    background-color: #FFFFFF;
    box-sizing: border-box;
    box-shadow: 0 -10rpx 8rpx 0 rgba(0,0,0,0.08);
}

.verify-btn {
    font-size: 32rpx;
    height: 104rpx;
    line-height: 104rpx;
    border-radius: 16rpx;
    font-weight: 600;
}
</style>