<template>
|
<view class="page">
|
<view class="navigation-bar">
|
<view class="back-button" @tap="goBack"><image class="back-icon" src="/static/icons/lucide/back-left.svg" mode="aspectFit"></image></view>
|
<text class="navigation-title">核销输入</text>
|
</view>
|
<scroll-view class="content" scroll-y="true" :show-scrollbar="false">
|
<view class="talent-card">
|
<view class="card-decoration"></view>
|
<view class="talent-head"><text class="talent-name">{{customerName}}</text><text class="talent-level">{{cardLevel}}</text></view>
|
<text class="talent-mobile">{{displayMobile(customerMobile)}}</text>
|
<view class="current-benefit"><text class="benefit-label">当前权益</text><text class="benefit-text">免费入住{{totalCount}}天</text><text v-if="discountText.length > 0" class="benefit-text benefit-extra">超过天数{{discountText}}</text></view>
|
</view>
|
<view class="method-card">
|
<text class="section-label">优惠方式</text>
|
<view class="tag-list"><text class="benefit-tag">免费入住{{totalCount}}天</text><text v-if="discountText.length > 0" class="benefit-tag">{{discountText}}</text></view>
|
</view>
|
<view class="stay-ticket">
|
<view class="ticket-left"><text class="ticket-vertical">入<br/>住<br/>券</text></view>
|
<view class="ticket-divider"></view>
|
<view class="ticket-right"><text class="ticket-count">一天</text><text class="ticket-free">免费</text></view>
|
<view class="ticket-notch ticket-notch-left"></view><view class="ticket-notch ticket-notch-right"></view>
|
</view>
|
<view class="content-bottom-space"></view>
|
</scroll-view>
|
<view class="bottom-bar"><view class="confirm-button" :class="submitting || loadError.length > 0 ? 'button-disabled' : ''" @tap="confirm"><text>{{submitting ? '核销中...' : '确认核销'}}</text></view></view>
|
</view>
|
</template>
|
|
<script setup lang="uts">
|
import { confirmVerificationCode } from '../../services/verification.uts'
|
|
const verificationId = ref('')
|
const customerName = ref('持卡人')
|
const customerMobile = ref('')
|
const cardLevel = ref('人才卡')
|
const totalCount = ref(5)
|
const discountText = ref('')
|
const loadError = ref('')
|
const submitting = ref(false)
|
|
const textOption = (options: any, name: string, fallback: string): string => options != null && options[name] != null && ('' + options[name]).length > 0 ? decodeURIComponent('' + options[name]) : fallback
|
const displayMobile = (mobile: string): string => mobile.length < 7 ? mobile : mobile.substring(0, 3) + '****' + mobile.substring(mobile.length - 4)
|
const goBack = () => uni.navigateBack()
|
|
const parseDiscount = (value: string): string => {
|
if (value.length == 0 || value.indexOf('折') < 0) return ''
|
const end = value.indexOf('折') + 1
|
const parts = value.substring(0, end).split(';')
|
return parts[parts.length - 1].split(',')[0].trim()
|
}
|
|
const confirm = () => {
|
if (submitting.value || verificationId.value.length == 0 || loadError.value.length > 0) return
|
uni.showModal({
|
title: '确认核销',
|
content: '确认核销本次免费入住券吗?',
|
confirmText: '确认核销',
|
confirmColor: '#FF6B2C',
|
success: (modal: any) => {
|
if (!modal.confirm) return
|
submitting.value = true
|
confirmVerificationCode(verificationId.value, 'merchant-free-stay-' + verificationId.value + '-' + Date.now(), (result: any, _traceId: string) => {
|
submitting.value = false
|
const verifyNo = result != null && result.verifyNo != null ? '' + result.verifyNo : ''
|
uni.redirectTo({ url: '/pages/verification-success/verification-success?orderNo=' + encodeURIComponent(verifyNo) + '&credentialType=FREE_STAY_CODE' })
|
}, (error: any) => {
|
submitting.value = false
|
uni.showToast({ title: error != null && error.message != null ? '' + error.message : '核销失败,请重试', icon: 'none' })
|
})
|
}
|
})
|
}
|
|
onLoad((options: any) => {
|
verificationId.value = textOption(options, 'verificationId', '')
|
customerName.value = textOption(options, 'customerName', '持卡人')
|
customerMobile.value = textOption(options, 'customerMobile', '')
|
cardLevel.value = textOption(options, 'cardLevel', '人才卡')
|
totalCount.value = Math.max(Number(textOption(options, 'freeStayTotalCount', '5')), 1)
|
// 优先用服务端按门店到店消费折扣算出来的文案;老版本没带这个参数时,仍从权益文案里兜底解析。
|
discountText.value = textOption(options, 'discountText', '')
|
if (discountText.value.length == 0) discountText.value = parseDiscount(textOption(options, 'benefitText', ''))
|
if (verificationId.value.length == 0) loadError.value = '核销凭证无效,请返回重新扫码'
|
})
|
</script>
|
|
<style>
|
page { background-color: #F7F8FA; }
|
.page { display: flex; width: 100%; height: 100vh; flex-direction: column; overflow: hidden; background-color: #F7F8FA; }
|
.navigation-bar { display: flex; height: 174rpx; flex: none; justify-content: center; align-items: flex-end; padding-bottom: 25rpx; box-sizing: border-box; position: relative; }
|
/* 标题绝对定位居中:bottom 取值让标题中线与返回按钮/胶囊中线对齐(与核销输入页保持一致)。 */
|
.navigation-title { position: absolute; right: 0; bottom: 30rpx; left: 0; z-index: 1; color: #1F2937; font-size: 35rpx; line-height: 49rpx; font-weight: 700; text-align: center; }
|
.back-button { display: flex; width: 72rpx; height: 72rpx; justify-content: center; align-items: center; position: absolute; top: 82rpx; left: 28rpx; }
|
.back-icon { width: 40rpx; height: 40rpx; }
|
.content { height: 0; flex: 1; padding: 20rpx 34rpx 0; box-sizing: border-box; }
|
.talent-card { min-height: 238rpx; padding: 34rpx 34rpx 28rpx; border-radius: 38rpx; background-image: linear-gradient(135deg, #C99D32 0%, #F7E69D 55%, #E5BD4E 100%); box-shadow: 0 18rpx 38rpx rgba(188, 139, 37, 0.2); box-sizing: border-box; position: relative; overflow: hidden; }
|
.card-decoration { width: 220rpx; height: 220rpx; border: 1rpx solid rgba(255, 255, 255, 0.35); border-radius: 110rpx; position: absolute; top: -72rpx; right: -12rpx; }
|
.talent-head { display: flex; flex-direction: row; justify-content: space-between; align-items: center; position: relative; }
|
.talent-name { color: #FFFFFF; font-size: 39rpx; line-height: 55rpx; font-weight: 700; }
|
.talent-level { padding: 9rpx 20rpx; border-radius: 24rpx; color: #FFFFFF; font-size: 22rpx; line-height: 31rpx; font-weight: 600; background-color: rgba(149, 104, 22, 0.46); }
|
.talent-mobile { display: block; margin-top: 15rpx; color: #FFFFFF; font-size: 29rpx; line-height: 41rpx; font-weight: 600; position: relative; }
|
.current-benefit { display: flex; margin-top: 22rpx; flex-direction: row; align-items: center; position: relative; }
|
.benefit-label { color: rgba(255, 255, 255, 0.78); font-size: 23rpx; line-height: 33rpx; }
|
.benefit-text { margin-left: 18rpx; color: #FFFFFF; font-size: 23rpx; line-height: 33rpx; font-weight: 600; }
|
/* 「超过天数门市价X折 / 立减X元」跟在免费额度后面,间隔比标签再大一点。 */
|
.benefit-extra { margin-left: 14rpx; font-weight: 500; }
|
.method-card { padding: 31rpx 34rpx; margin-top: 22rpx; border-radius: 30rpx; background-color: #FFFFFF; box-shadow: 0 14rpx 30rpx rgba(57, 67, 80, 0.06); }
|
.section-label { display: block; color: #8D99AA; font-size: 27rpx; line-height: 38rpx; }
|
.tag-list { display: flex; margin-top: 20rpx; flex-direction: row; flex-wrap: wrap; }
|
.benefit-tag { display: flex; min-height: 48rpx; padding: 7rpx 18rpx; margin-right: 12rpx; margin-bottom: 4rpx; justify-content: center; align-items: center; border-radius: 24rpx; color: #FF772C; font-size: 23rpx; line-height: 33rpx; background-color: #FFF0E5; box-sizing: border-box; }
|
.stay-ticket { display: flex; height: 210rpx; margin: 40rpx 42rpx 0; flex-direction: row; align-items: center; border-radius: 32rpx; background-image: linear-gradient(100deg, #FF5D25 0%, #FF8A27 100%); box-shadow: 0 18rpx 34rpx rgba(255, 98, 35, 0.23); position: relative; overflow: hidden; }
|
.ticket-left { display: flex; width: 134rpx; justify-content: center; align-items: center; }
|
.ticket-vertical { color: #FFFFFF; font-size: 28rpx; line-height: 37rpx; font-weight: 700; text-align: center; }
|
.ticket-divider { width: 2rpx; height: 144rpx; background-color: rgba(255, 255, 255, 0.3); }
|
.ticket-right { display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center; }
|
.ticket-count { color: #FFFFFF; font-size: 43rpx; line-height: 60rpx; font-weight: 700; }
|
.ticket-free { color: #FFFFFF; font-size: 43rpx; line-height: 60rpx; font-weight: 700; }
|
.ticket-notch { width: 34rpx; height: 34rpx; border-radius: 20rpx; background-color: #F7F8FA; position: absolute; top: 88rpx; }
|
.ticket-notch-left { left: -17rpx; }
|
.ticket-notch-right { right: -17rpx; }
|
.remaining-hint { margin-top: 20rpx; color: #98A2B1; font-size: 23rpx; line-height: 33rpx; text-align: center; }
|
.content-bottom-space { height: 180rpx; }
|
.bottom-bar { display: flex; height: 154rpx; padding: 20rpx 96rpx 34rpx; background-color: #FFFFFF; box-sizing: border-box; position: fixed; right: 0; bottom: 0; left: 0; z-index: 10; }
|
.confirm-button { display: flex; height: 94rpx; flex: 1; justify-content: center; align-items: center; border-radius: 48rpx; color: #FFFFFF; font-size: 29rpx; line-height: 41rpx; font-weight: 700; background-image: linear-gradient(90deg, #FF7625 0%, #FF962F 100%); box-shadow: 0 12rpx 24rpx rgba(255, 107, 36, 0.22); }
|
.button-disabled { opacity: 0.6; box-shadow: none; }
|
</style>
|