index.vue 4.94 KB
<!--
 * @Date: 2026-01-08 13:01:20
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-14 10:07:56
 * @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 v-if="result_content" class="mt-4 rounded-2xl bg-white p-5 shadow-sm">
            <view class="text-xs text-gray-500">核销结果</view>
            <view class="mt-2 break-all text-sm font-medium text-gray-900">{{ result_content }}</view>
        </view>
        <view v-else 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 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 } from '@/api/index'
import Taro, { useDidShow } from '@tarojs/taro'

const router = useRouter()
const result_content = ref('')
const verify_status = ref('idle')
const msg = ref('请点击下方按钮进行核销')

// 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'
})
/******************* END **********************/

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

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

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

useDidShow(async () => {
    /**
     * 现在主要用于:外部渠道如果手动带参进入则自动核销;正常业务流程(从义工登录进入)是不会带参的,会走缺省态 + 点击“核销”扫码。
     */
    const code = router?.params?.result || ''
    if (!code) {
        result_content.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: 36rpx;
    height: 104rpx;
    line-height: 104rpx;
    border-radius: 16rpx;
    font-weight: 600;
}
</style>