refactor: 重构扫码结果页面状态展示

This commit is contained in:
davy 2025-04-09 14:04:46 +08:00
parent 9671183043
commit 912ec5f693
4 changed files with 698 additions and 402 deletions

View File

@ -5,8 +5,15 @@
<view class="section"> <view class="section">
<view class="section-title">累计进度</view> <view class="section-title">累计进度</view>
<view class="progress-content"> <view class="progress-content">
<!-- 状态提示信息 -->
<view class="status-tip" v-if="activity.activityStatus >= 2">
<text class="tip-text" v-if="activity.activityStatus == 2">累计目标已完成请耐心等待品牌方兑付奖励</text>
<text class="tip-text" v-if="activity.activityStatus == 3">品牌方已发起兑付奖励快递单号{{activity.expressNo || '暂无'}}请注意查收</text>
<text class="tip-text" v-if="activity.activityStatus == 4">累计活动已结束兑付时间{{activity.claimTime || '-'}}</text>
</view>
<!-- 剩余目标显示 --> <!-- 剩余目标显示 -->
<view class="target-display"> <view class="target-display" v-if="activity.activityStatus < 2">
<text class="target-label">剩余累计目标</text> <text class="target-label">剩余累计目标</text>
<view class="target-number"> <view class="target-number">
<text class="number">{{activity.remainingBeerCount || 0}}</text> <text class="number">{{activity.remainingBeerCount || 0}}</text>
@ -15,7 +22,7 @@
</view> </view>
<!-- 倒计时区域 --> <!-- 倒计时区域 -->
<view class="countdown-container"> <view class="countdown-container" v-if="activity.activityStatus < 2">
<view class="countdown-item"> <view class="countdown-item">
<text class="number">{{remainingDays}}</text> <text class="number">{{remainingDays}}</text>
<text class="unit"></text> <text class="unit"></text>
@ -154,22 +161,29 @@
<view class="status-info"> <view class="status-info">
<text class="label">活动状态</text> <text class="label">活动状态</text>
<text class="status" :class="{ <text class="status" :class="{
'status-ongoing': !reward, 'status-ongoing': activity.activityStatus == 1,
'status-pending': reward && reward.rewardStatus == 0, 'status-pending': activity.activityStatus == 2 || activity.activityStatus == 3,
'status-completed': reward && reward.rewardStatus == 1 'status-completed': activity.activityStatus == 4
}"> }">
{{!reward ? '累计中' : (reward.rewardStatus == 0 ? '待确认' : '已确认')}} {{activity.activityStatus == 0 ? '未参与' :
activity.activityStatus == 1 ? '累计中' :
activity.activityStatus == 2 ? '待兑付' :
activity.activityStatus == 3 ? '待确认' : '已完成'}}
</text> </text>
</view> </view>
<view class="action-button" <view class="action-button"
:class="{ :class="{
'scan-btn': !reward, 'scan-btn': activity.activityStatus == 1,
'confirm-btn': reward && reward.rewardStatus == 0, 'confirm-btn': activity.activityStatus == 3,
'completed-btn': reward && reward.rewardStatus == 1 'completed-btn': activity.activityStatus == 2 || activity.activityStatus == 4
}" }"
@click="!reward ? toScan() : (reward.rewardStatus == 0 ? confirmPay() : null)"> @click="activity.activityStatus == 1 ? toScan() :
<text class="cuIcon-qr_code" v-if="!reward"></text> activity.activityStatus == 3 ? confirmPay() : null">
<text>{{!reward ? '扫码累计' : (reward.rewardStatus == 0 ? '确认兑付完成' : '兑付已确认')}}</text> <text class="cuIcon-qr_code" v-if="activity.activityStatus == 1"></text>
<text>{{activity.activityStatus == 0 ? '未参与' :
activity.activityStatus == 1 ? '扫码累计' :
activity.activityStatus == 2 ? '累计目标已完成' :
activity.activityStatus == 3 ? '确认兑付完成' : '已完成'}}</text>
</view> </view>
</view> </view>
</view> </view>
@ -299,18 +313,17 @@
content: '确认兑付完成?', content: '确认兑付完成?',
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
confirmPayApi(this.reward.id).then(res => { confirmPayApi(this.reward.id).then(res => {
uni.showToast({ uni.showToast({
title: '确认成功', title: '确认成功',
icon: 'success', icon: 'success',
}) })
this.init() // 4
this.activity.activityStatus = 4
}) })
} }
}, },
}) })
}, },
toScan() { toScan() {
uni.switchTab({ uni.switchTab({
@ -392,6 +405,21 @@
padding: 32rpx; padding: 32rpx;
} }
.status-tip {
text-align: center;
margin-bottom: 32rpx;
padding: 24rpx;
background: rgba(25, 54, 122, 0.05);
border-radius: 12rpx;
.tip-text {
font-size: 28rpx;
color: #19367A;
line-height: 1.5;
display: block;
}
}
.target-display { .target-display {
text-align: center; text-align: center;
margin-bottom: 32rpx; margin-bottom: 32rpx;

View File

@ -5,19 +5,25 @@
<view class="error-page"> <view class="error-page">
<!-- 位置错误 --> <!-- 位置错误 -->
<template v-if="errorType === 'location'"> <template v-if="errorType === 'location'">
<image src="/static/location.svg" class="status-icon"></image> <image src="/static/information.svg" class="status-icon"></image>
<view class="status-title">超出门店范围</view> <view class="status-title">您现在未在您门店定位的范围</view>
<view class="status-desc">您现在未在您门店定位的范围</view>
<view class="status-desc">请在门店范围100米内重新扫码</view> <view class="status-desc">请在门店范围100米内重新扫码</view>
</template> </template>
<!-- 已失效 --> <!-- 已失效 -->
<template v-if="errorType === 'expired' || info.qrcode.qrcodeStatus == 2"> <template v-if="errorType === 'expired' || info.qrcode.qrcodeStatus == 2">
<image src="/static/warning-2.png" class="status-icon"></image> <image src="/static/information.svg" class="status-icon"></image>
<view class="status-title">{{ info.qrcode.statusDesc || '二维码已失效' }}</view> <view class="status-title">{{ info.qrcode.statusDesc || '二维码已失效' }}</view>
<view class="status-desc">{{ info.qrcode.statusMessage || '该二维码已超出可用范围' }}</view> <view class="status-desc">{{ info.qrcode.statusMessage || '该二维码已超出可用范围' }}</view>
</template> </template>
<!-- 识别产品 -->
<view class="product-section">
<view class="section-header">
<image src="/static/scan.svg" class="section-icon"></image>
<text>识别产品</text>
</view>
<!-- 商品信息卡片 --> <!-- 商品信息卡片 -->
<view v-if="beer" class="product-card"> <view v-if="beer" class="product-card">
<view class="product-content"> <view class="product-content">
@ -27,14 +33,9 @@
<view class="product-info"> <view class="product-info">
<view class="product-name">{{ beer.beerName }}</view> <view class="product-name">{{ beer.beerName }}</view>
<view class="product-brand">{{ beer.brandName }}</view> <view class="product-brand">{{ beer.brandName }}</view>
<view class="product-details"> <view class="product-rating">
<view class="detail-item"> <text class="rating-value">{{ beer.beerOverallRating || '4.9' }}</text>
<text class="detail-label">生产日期</text> <text class="rating-count">{{ beer.beerReviewsCount || '20' }} reviews</text>
<text class="detail-value">{{ beer.createTime ? beer.createTime.split(' ')[0] : '' }}</text>
</view>
<view class="detail-item">
<text class="detail-label">净含量</text>
<text class="detail-value">{{ beer.netContent }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -53,25 +54,17 @@
<!-- 正常状态页面 --> <!-- 正常状态页面 -->
<template v-else> <template v-else>
<!-- 待领取状态 -->
<template v-if="info.qrcode.qrcodeStatus == 0">
<view class="flex-1" style="overflow-y: auto;"> <view class="flex-1" style="overflow-y: auto;">
<!-- 已领取 --> <!-- 扫码成功提示 -->
<view v-if="info.qrcode.qrcodeStatus == 1 && false" class="lq-state-box"> <view class="scs-state-box">
<image src="@/static/information.png" class="img"></image>
<text>该桶产品已于 {{ info.qrcode.verifyTime }} 扫码领取返利</text>
</view>
<!-- 转为赠品 -->
<view v-if="info.qrcode.qrcodeStatus == 3" class="lq-state-box gift-state">
<image src="@/static/gift.png" class="img"></image>
<text>该桶产品已转为赠品</text>
</view>
<!-- 领取成功 -->
<view v-if="info.qrcode.qrcodeStatus == 1" class="scs-state-box">
<image src="/static/tick-circle.svg" class="img"></image> <image src="/static/tick-circle.svg" class="img"></image>
<text>领取成功</text> <text>扫码成功</text>
</view> </view>
<!-- 产品信息卡片 --> <!-- 产品信息卡片 -->
<view v-if="beer && info.qrcode.qrcodeStatus == 0" class="product-card"> <view v-if="beer" class="product-card">
<view class="section-title"> <view class="section-title">
<text>商品详细</text> <text>商品详细</text>
</view> </view>
@ -103,8 +96,210 @@
</view> </view>
</view> </view>
<!-- 品牌福利卡片领取成功状态 --> <!-- 品牌福利卡片 -->
<view v-if="info.qrcode.qrcodeStatus == 1" class="benefit-card"> <view v-if="beer && beer.scanCoinCount" class="benefit-card">
<view class="section-title">
<text>品牌福利</text>
</view>
<view class="benefit-content">
<view class="benefit-title">{{ beer.scanCoinCount}} {{beer.brandName}} 啤酒币待领取</view>
<text class="benefit-subtitle">品牌啤酒币可用于兑换好礼</text>
</view>
</view>
<!-- 活动选择提示 -->
<view v-if="activitySum > 1" class="activity-tip">
<text class="tip-icon">!</text>
<text class="tip-text">该产品有多个进行中活动重叠<text class="highlight">选择要计入的活动</text></text>
</view>
<!-- 待领取状态活动列表 -->
<template>
<!-- 品牌活动 -->
<view v-for="(it, index) in activity" :key="index"
class="activity-card"
:class="{'activity-card-active': activityId === it.id}"
@click="selectPPF(it)">
<view class="activity-content">
<view class="activity-left">
<view v-if="it.brandLogo" class="brand-logo-container">
<image :src="it.brandLogo" class="brand-logo"></image>
</view>
<view v-else class="brand-logo-placeholder">
<text class="placeholder-text">品牌图标</text>
</view>
<view class="progress-info">
<text class="progress-label">距离达成差</text>
<view class="progress-value">
<text v-if="it.remainingBeerCount <= 0" class="completed">已达标</text>
<text v-else class="remaining">{{ it.remainingBeerCount}}</text>
</view>
</view>
</view>
<view class="activity-right">
<view class="activity-header">
<view class="activity-name">{{ it.breweryName }}</view>
<view class="activity-tag" v-if="it.activityType == 1">指定门店</view>
<view class="activity-tag" v-if="it.activityType == 2">招募活动</view>
</view>
<view class="activity-details">
<view class="detail-row">
<text class="detail-label">活动时间</text>
<text class="detail-value">首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></text>
</view>
<view class="detail-row">
<text class="detail-label">活动目标</text>
<text class="detail-value">{{ it.beer_scope === 0 ? '全系列酒款' : '指定酒款' }}累计扫码{{ it.activityTarget}}</text>
</view>
</view>
<scroll-view v-if="it.beers" scroll-x="true" class="beer-scroll">
<view class="beer-item" v-for="(beer, beerIndex) in it.beers" :key="beerIndex">
<image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image>
</view>
</scroll-view>
<view v-else class="beer-scroll-placeholder">
<text class="placeholder-text">暂无酒款信息</text>
</view>
<view class="reward-info">
<text class="reward-label"></text>
<text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value">
{{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}}
</text>
<text v-else-if="it.activityRewardType == 2" class="reward-value">
啤酒币 * {{it.activityRewardCount}}
</text>
<text v-else class="reward-value error-text">奖励内容获取失败</text>
</view>
</view>
</view>
</view>
<!-- 平台活动 -->
<view v-for="(it, index) in platformActivity" :key="index"
class="activity-card"
:class="{'activity-card-active': platformActivityId === it.id}"
@click="selectPlatform(it)">
<view class="activity-content">
<view class="activity-left">
<view v-if="it.brandLogo" class="brand-logo-container">
<image :src="it.brandLogo" class="brand-logo"></image>
</view>
<view v-else class="brand-logo-placeholder">
<text class="placeholder-text">品牌图标</text>
</view>
<view class="progress-info">
<text class="progress-label">距离达成还剩</text>
<view class="progress-value">
<text v-if="it.remainingBeerCount <= 0" class="completed">已达标</text>
<text v-else class="remaining">{{ it.remainingBeerCount}}</text>
</view>
</view>
</view>
<view class="activity-right">
<view class="activity-header">
<view class="activity-name">{{ it.breweryName }}</view>
<view class="activity-tag" v-if="it.activityRewardType == 1">实物奖励</view>
<view class="activity-tag" v-if="it.activityRewardType == 2">啤酒币</view>
</view>
<view class="activity-details">
<view class="detail-row">
<text class="detail-label">活动时间</text>
<text class="detail-value">首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></text>
</view>
<view class="detail-row">
<text class="detail-label">活动目标</text>
<text class="detail-value">{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累计扫码 {{ it.activityTarget}}</text>
</view>
</view>
<scroll-view scroll-x="true" class="beer-scroll">
<view class="beer-item" v-for="(beer, beerIndex) in it.beers" :key="beerIndex">
<image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image>
</view>
</scroll-view>
<view v-else class="beer-scroll-placeholder">
<text class="placeholder-text">暂无酒款信息</text>
</view>
<view class="reward-info">
<text class="reward-label">奖励</text>
<text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value">
{{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}}
</text>
<text v-else-if="it.activityRewardType == 2" class="reward-value">
啤酒币 * {{it.activityRewardCount}}
</text>
<text v-else class="reward-value error-text">奖励内容获取失败</text>
</view>
</view>
</view>
</view>
</template>
</view>
<!-- 待领取状态底部操作区 -->
<view class="footer">
<view class="action-buttons">
<view class="action-btn cancel-btn" @click="back">
<image src="/static/undo.svg" class="btn-icon"></image>
<text>回头再说</text>
</view>
<view class="action-btn primary-btn" @click="handleReceive">
<image src="/static/send-2.svg" class="btn-icon"></image>
<text>立即领取</text>
</view>
</view>
</view>
</template>
<!-- 领取成功状态 -->
<template v-if="info.qrcode.qrcodeStatus == 1">
<view class="flex-1" style="overflow-y: auto;">
<!-- 领取成功提示 -->
<view class="lq-state-box">
<image src="/static/information.svg" class="img"></image>
<text>该桶产品已于 {{ info.qrcode.verifyTime }} 扫码领取返利</text>
</view>
<!-- 领取成功状态提示 -->
<view class="scs-state-box">
<image src="/static/tick-circle.svg" class="img"></image>
<text>领取成功</text>
</view>
<!-- 产品信息卡片 -->
<view v-if="beer" class="product-card">
<view class="section-title">
<text>商品详细</text>
</view>
<view class="product-content">
<view class="product-image">
<image :src="beer.cover" class="cover"></image>
</view>
<view class="product-info">
<view class="product-name">{{ beer.beerName }}</view>
<view class="product-brand">{{ beer.brandName }}</view>
<view class="product-details">
<view class="detail-item">
<text class="detail-label">生产日期</text>
<text class="detail-value">{{ beer.launchDate }}</text>
</view>
<view class="detail-item">
<text class="detail-label">净含量</text>
<text class="detail-value">{{ beer.netContent }}</text>
</view>
</view>
<view class="product-rating">
<view class="rating-stars">
<text class="cuIcon-favorfill" style="color: #FFBC11;"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{beer.beerReviewsCount}} 条评论</text>
</view>
</view>
</view>
</view>
<!-- 品牌福利卡片 -->
<view class="benefit-card">
<view class="section-title"> <view class="section-title">
<text>品牌福利已领取</text> <text>品牌福利已领取</text>
</view> </view>
@ -114,15 +309,9 @@
</view> </view>
</view> </view>
<!-- 活动选择提示 --> <!-- 已选择的活动列表 -->
<view v-if="activitySum > 1 && info.qrcode.qrcodeStatus == 0" class="activity-tip"> <template>
<text class="tip-icon">!</text> <!-- 已选择的品牌活动 -->
<text class="tip-text">该产品有多个进行中活动重叠<text class="highlight">选择要计入的活动</text></text>
</view>
<!-- 活动列表领取成功状态 -->
<template v-if="info.qrcode.qrcodeStatus == 1">
<!-- 品牌活动 -->
<view v-for="(it, index) in activity.filter(item => item.id === activityId)" :key="index" <view v-for="(it, index) in activity.filter(item => item.id === activityId)" :key="index"
class="activity-card"> class="activity-card">
<view class="activity-content"> <view class="activity-content">
@ -137,16 +326,28 @@
</view> </view>
</view> </view>
<view class="activity-right"> <view class="activity-right">
<view class="activity-name">{{ it.activityName }}</view> <view class="activity-header">
<view class="activity-detail">时间首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></view> <view class="activity-name">{{ it.breweryName }}</view>
<view class="activity-detail">目标{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累计扫码 {{ it.activityTarget}}</view> <view class="activity-tag" v-if="it.activityRewardType == 1">实物奖励</view>
<view class="activity-tag" v-if="it.activityRewardType == 2">啤酒币</view>
</view>
<view class="activity-details">
<view class="detail-row">
<text class="detail-label">活动时间</text>
<text class="detail-value">首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></text>
</view>
<view class="detail-row">
<text class="detail-label">活动目标</text>
<text class="detail-value">{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累计扫码 {{ it.activityTarget}}</text>
</view>
</view>
<scroll-view v-if="it.beers" scroll-x="true" class="beer-scroll"> <scroll-view v-if="it.beers" scroll-x="true" class="beer-scroll">
<view class="beer-item" v-for="(beer, index) in it.beers" :key="index"> <view class="beer-item" v-for="(beer, beerIndex) in it.beers" :key="beerIndex">
<image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image> <image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image>
</view> </view>
</scroll-view> </scroll-view>
<view class="reward-info"> <view class="reward-info">
<text class="reward-label"></text> <text class="reward-label">奖励</text>
<text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value"> <text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value">
{{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}} {{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}}
</text> </text>
@ -158,7 +359,7 @@
</view> </view>
</view> </view>
<!-- 平台活动 --> <!-- 已选择的平台活动 -->
<view v-for="(it, index) in platformActivity.filter(item => item.id === platformActivityId)" :key="index" <view v-for="(it, index) in platformActivity.filter(item => item.id === platformActivityId)" :key="index"
class="activity-card"> class="activity-card">
<view class="activity-content"> <view class="activity-content">
@ -173,16 +374,28 @@
</view> </view>
</view> </view>
<view class="activity-right"> <view class="activity-right">
<view class="activity-name">{{ it.activityName }}</view> <view class="activity-header">
<view class="activity-detail">时间首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></view> <view class="activity-name">{{ it.breweryName }}</view>
<view class="activity-detail">目标{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累计扫码 {{ it.activityTarget}}</view> <view class="activity-tag" v-if="it.activityRewardType == 1">实物奖励</view>
<view class="activity-tag" v-if="it.activityRewardType == 2">啤酒币</view>
</view>
<view class="activity-details">
<view class="detail-row">
<text class="detail-label">活动时间</text>
<text class="detail-value">首次扫码开始计时 <text class="highlight">{{it.duration}}天内</text></text>
</view>
<view class="detail-row">
<text class="detail-label">活动目标</text>
<text class="detail-value">{{ it.beer_scope === 0 ? '全系列酒款' : '以下酒款' }}累计扫码 {{ it.activityTarget}}</text>
</view>
</view>
<scroll-view scroll-x="true" class="beer-scroll"> <scroll-view scroll-x="true" class="beer-scroll">
<view class="beer-item" v-for="(beer, index) in it.beers" :key="index"> <view class="beer-item" v-for="(beer, beerIndex) in it.beers" :key="beerIndex">
<image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image> <image v-if="beer.cover" :src="beer.cover" class="beer-cover"></image>
</view> </view>
</scroll-view> </scroll-view>
<view class="reward-info"> <view class="reward-info">
<text class="reward-label"></text> <text class="reward-label">奖励</text>
<text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value"> <text v-if="it.activityRewardType == 1 && it.activityRewardGoods" class="reward-value">
{{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}} {{it.activityRewardGoods.goodsName}} * {{it.activityRewardCount}}
</text> </text>
@ -196,39 +409,79 @@
</template> </template>
</view> </view>
<!-- 底部操作区 --> <!-- 领取成功状态底部操作区 -->
<view class="footer"> <view class="footer">
<view v-if="info.qrcode.qrcodeStatus == 2" class="warning-tip">
<image src="@/static/warning-2.png" class="warning-icon"></image>
<text>所有酒款只可领取一次请确认后操作</text>
</view>
<view class="action-buttons"> <view class="action-buttons">
<view v-if="info.qrcode.qrcodeStatus != 1 && info.qrcode.qrcodeStatus != 3" <view class="action-btn cancel-btn" @click="toWinelist">
class="action-btn cancel-btn" @click="back">
<image src="/static/undo.svg" class="btn-icon"></image>
<text>回头再说</text>
</view>
<view v-else class="action-btn cancel-btn" @click="toWinelist">
<image src="@/static/document.png" class="btn-icon"></image> <image src="@/static/document.png" class="btn-icon"></image>
<text>生成酒单</text> <text>生成酒单</text>
</view> </view>
<view class="action-btn primary-btn" @click="share">
<view v-if="info.qrcode.qrcodeStatus == 0" class="action-btn primary-btn" @click="handleReceive">
<image src="/static/send-2.svg" class="btn-icon"></image>
<text>立即领取</text>
</view>
<view v-else-if="info.qrcode.qrcodeStatus == 3" class="action-btn gift-btn" @click="share">
<image src="/static/send-2.svg" class="btn-icon"></image>
<text>分享赠品</text>
</view>
<view v-else class="action-btn primary-btn" @click="share">
<image src="/static/send-2.svg" class="btn-icon"></image> <image src="/static/send-2.svg" class="btn-icon"></image>
<text>分享上新</text> <text>分享上新</text>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<!-- 转为赠品状态 -->
<template v-if="info.qrcode.qrcodeStatus == 3">
<view class="flex-1" style="overflow-y: auto;">
<!-- 赠品状态提示 -->
<view class="lq-state-box gift-state">
<image src="/static/gift.png" class="img"></image>
<text>该桶产品已转为赠品</text>
</view>
<!-- 产品信息卡片 -->
<view v-if="beer" class="product-card">
<view class="section-title">
<text>商品详细</text>
</view>
<view class="product-content">
<view class="product-image">
<image :src="beer.cover" class="cover"></image>
</view>
<view class="product-info">
<view class="product-name">{{ beer.beerName }}</view>
<view class="product-brand">{{ beer.brandName }}</view>
<view class="product-details">
<view class="detail-item">
<text class="detail-label">生产日期</text>
<text class="detail-value">{{ beer.launchDate }}</text>
</view>
<view class="detail-item">
<text class="detail-label">净含量</text>
<text class="detail-value">{{ beer.netContent }}</text>
</view>
</view>
<view class="product-rating">
<view class="rating-stars">
<text class="cuIcon-favorfill" style="color: #FFBC11;"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{beer.beerReviewsCount}} 条评论</text>
</view>
</view>
</view>
</view>
</view>
<!-- 赠品状态底部操作区 -->
<view class="footer">
<view class="action-buttons">
<view class="action-btn cancel-btn" @click="toWinelist">
<image src="@/static/document.png" class="btn-icon"></image>
<text>生成酒单</text>
</view>
<view class="action-btn gift-btn" @click="share">
<image src="/static/send-2.svg" class="btn-icon"></image>
<text>分享赠品</text>
</view>
</view>
</view>
</template>
</template>
</view> </view>
</template> </template>
@ -284,10 +537,13 @@
longitude: this.longitude longitude: this.longitude
}).then(res => { }).then(res => {
console.log(res.data) console.log(res.data)
this.showError = false //
this.errorType = null //
this.info = res.data this.info = res.data
this.beer = res.data.beer this.beer = res.data.beer
this.activity = res.data.activity || [] this.activity = res.data.activity || []
this.platformActivity = res.data.platformActivity || [] this.platformActivity = res.data.platformActivity || []
this.activitySum = 0 //
if (this.activity && this.activity.length > 0) { if (this.activity && this.activity.length > 0) {
this.activitySum += this.activity.length this.activitySum += this.activity.length
this.activityId = this.activity[0].id this.activityId = this.activity[0].id
@ -298,12 +554,13 @@
} }
}).catch(err => { }).catch(err => {
console.error('获取二维码信息失败:', err) console.error('获取二维码信息失败:', err)
if (err.code === 500 && err.msg === '请在酒吧附近100米范围内扫码') {
this.showError = true this.showError = true
if (err.code === 500 && err.msg === '请在酒吧附近100米范围内扫码') {
this.errorType = 'location' this.errorType = 'location'
} else if (err.code === 500 && err.msg.includes('已失效')) { } else if (err.code === 500 && err.msg.includes('已失效')) {
this.errorType = 'expired' this.errorType = 'expired'
} else { } else {
this.errorType = 'expired'
uni.showToast({ uni.showToast({
title: err.msg || '获取信息失败', title: err.msg || '获取信息失败',
icon: 'none' icon: 'none'
@ -403,128 +660,147 @@
padding: 0rpx 26rpx 60rpx; padding: 0rpx 26rpx 60rpx;
.error-page { .error-page {
padding: 120rpx 32rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-top: 120rpx;
.status-icon { .status-icon {
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
margin-bottom: 40rpx; margin-bottom: 32rpx;
} }
.status-title { .status-title {
font-size: 36rpx; font-size: 36rpx;
color: #3D3D3D; color: #333333;
font-weight: 600; font-weight: 600;
margin-bottom: 16rpx; margin-bottom: 16rpx;
text-align: center;
} }
.status-desc { .status-desc {
font-size: 28rpx; font-size: 28rpx;
color: #5F5F63; color: #666666;
font-weight: 400; margin-bottom: 8rpx;
margin-bottom: 12rpx;
text-align: center; text-align: center;
}
}
&:last-of-type { .product-section {
margin-bottom: 60rpx; margin-top: 48rpx;
padding: 0 32rpx;
.section-header {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 24rpx;
.section-icon {
width: 40rpx;
height: 40rpx;
}
text {
font-size: 32rpx;
color: #333333;
font-weight: 500;
}
} }
} }
.product-card { .product-card {
width: 100%;
background: #FFFFFF; background: #FFFFFF;
border-radius: 24rpx; border-radius: 16rpx;
box-shadow: 0px 8rpx 24rpx rgba(0, 0, 0, 0.08); padding: 24rpx;
padding: 36rpx; box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
margin-bottom: 40rpx; margin-bottom: 32rpx;
.product-content { .product-content {
display: flex; display: flex;
gap: 24rpx;
.product-image { .product-image {
margin-right: 28rpx; width: 160rpx;
height: 240rpx;
border-radius: 12rpx;
overflow: hidden;
flex-shrink: 0;
.cover { .cover {
width: 200rpx; width: 100%;
height: 300rpx; height: 100%;
border-radius: 16rpx; object-fit: cover;
box-shadow: 0px 8rpx 16rpx rgba(0, 0, 0, 0.12);
} }
} }
.product-info { .product-info {
flex: 1; flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.product-name { .product-name {
font-size: 40rpx; font-size: 32rpx;
color: #141415; color: #333333;
font-weight: 600; font-weight: 600;
margin-bottom: 16rpx; margin-bottom: 12rpx;
} }
.product-brand { .product-brand {
font-size: 30rpx; font-size: 28rpx;
color: #5F5F63; color: #666666;
font-weight: 500;
margin-bottom: 16rpx; margin-bottom: 16rpx;
} }
.product-details { .product-details {
margin-bottom: 28rpx; margin-bottom: 16rpx;
.detail-item { .detail-item {
display: flex; display: flex;
margin-bottom: 12rpx; align-items: center;
font-size: 28rpx; margin-bottom: 8rpx;
.detail-label { .detail-label {
color: #3D3D3D; font-size: 26rpx;
color: #999999;
margin-right: 8rpx; margin-right: 8rpx;
font-weight: 500;
} }
.detail-value { .detail-value {
color: #5F5F63; font-size: 26rpx;
font-weight: 400; color: #333333;
}
}
}
} }
} }
} }
.error-action { .product-rating {
width: 100%;
padding: 0 40rpx;
margin-top: 40rpx;
.action-btn {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; gap: 12rpx;
width: 100%;
height: 96rpx; .rating-stars {
background: #D42E78; display: flex;
border-radius: 12rpx; align-items: center;
font-size: 28rpx; gap: 8rpx;
color: #FFFFFF;
.rating-value {
font-size: 26rpx;
color: #333333;
font-weight: 500; font-weight: 500;
box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.1); }
}
.btn-icon { .rating-count {
width: 40rpx; font-size: 24rpx;
height: 40rpx; color: #999999;
margin-right: 12rpx; }
filter: brightness(0) invert(1);
} }
} }
} }
} }
/* 状态提示样式 */
.lq-state-box { .lq-state-box {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -587,96 +863,6 @@
} }
} }
/* 产品卡片样式 */
.product-card {
background: #FFFFFF;
border-radius: 24rpx;
box-shadow: 0px 8rpx 24rpx rgba(0, 0, 0, 0.08);
padding: 36rpx;
margin-bottom: 40rpx;
.product-content {
display: flex;
.product-image {
margin-right: 28rpx;
.cover {
width: 200rpx;
height: 300rpx;
border-radius: 16rpx;
box-shadow: 0px 8rpx 16rpx rgba(0, 0, 0, 0.12);
}
}
.product-info {
flex: 1;
.product-name {
font-size: 40rpx;
color: #141415;
font-weight: 600;
margin-bottom: 16rpx;
}
.product-brand {
font-size: 30rpx;
color: #5F5F63;
font-weight: 600;
margin-bottom: 16rpx;
}
.product-details {
margin-bottom: 28rpx;
.detail-item {
display: flex;
margin-bottom: 12rpx;
font-size: 28rpx;
.detail-label {
color: #3D3D3D;
margin-right: 8rpx;
font-weight: 500;
}
.detail-value {
color: #5F5F63;
font-weight: 400;
}
}
}
.product-rating {
display: flex;
align-items: center;
.rating-stars {
display: flex;
align-items: center;
background: #F5F5F5;
padding: 8rpx 16rpx;
border-radius: 16rpx;
margin-right: 16rpx;
.rating-value {
font-size: 28rpx;
color: #5F5F63;
font-weight: 400;
margin-left: 8rpx;
}
}
.rating-count {
font-size: 28rpx;
color: #5F5F63;
font-weight: 400;
}
}
}
}
}
/* 福利卡片样式 */ /* 福利卡片样式 */
.benefit-card { .benefit-card {
background: #FFFFFF; background: #FFFFFF;
@ -766,34 +952,62 @@
margin-right: 28rpx; margin-right: 28rpx;
box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.05); box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.05);
.brand-logo { .brand-logo-container {
width: 140rpx; width: 140rpx;
height: 140rpx; height: 140rpx;
border-radius: 16rpx; border-radius: 16rpx;
margin-bottom: 20rpx; margin-bottom: 20rpx;
overflow: hidden;
.brand-logo {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.brand-logo-placeholder {
width: 140rpx;
height: 140rpx;
border-radius: 16rpx;
margin-bottom: 20rpx;
background: #EEEEEE;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx dashed #CCCCCC;
.placeholder-text {
font-size: 24rpx;
color: #999999;
}
} }
.progress-info { .progress-info {
display: flex;
flex-direction: column;
align-items: center;
text-align: center; text-align: center;
.progress-label { .progress-label {
margin-top: 12rpx;
font-size: 24rpx; font-size: 24rpx;
color: #9E9E9E; color: #9E9E9E;
font-weight: 400; font-weight: 400;
margin-bottom: 8rpx; margin-bottom: 32rpx;
} }
.progress-value { .progress-value {
.completed { .completed {
font-size: 32rpx; font-size: 32rpx;
color: #DE3C4B; color: #DE3C4B;
font-weight: 500; font-weight: 600;
} }
.remaining { .remaining {
font-size: 40rpx; font-size: 40rpx;
color: #DE3C4B; color: #DE3C4B;
font-weight: 500; font-weight: 600;
} }
} }
} }
@ -802,24 +1016,56 @@
.activity-right { .activity-right {
flex: 1; flex: 1;
.activity-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
.activity-name { .activity-name {
font-size: 32rpx; font-size: 32rpx;
font-weight: 600; font-weight: 600;
color: #0B0E26; color: #0B0E26;
margin-bottom: 20rpx;
} }
.activity-detail { .activity-tag {
font-size: 24rpx;
color: #FFFFFF;
background: #DE3C4B;
padding: 4rpx 12rpx;
border-radius: 8rpx;
}
}
.activity-details {
margin-bottom: 20rpx;
.detail-row {
display: flex;
align-items: center;
margin-bottom: 12rpx;
.detail-label {
font-size: 26rpx; font-size: 26rpx;
color: #0B0E26; color: #999999;
font-weight: 400; margin-right: 8rpx;
margin-bottom: 16rpx; flex-shrink: 0;
}
.detail-value {
font-size: 26rpx;
color: #333333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.highlight { .highlight {
color: #DE3C4B; color: #DE3C4B;
font-weight: 500; font-weight: 500;
} }
} }
}
}
.beer-scroll { .beer-scroll {
width: 100%; width: 100%;
@ -839,6 +1085,22 @@
} }
} }
.beer-scroll-placeholder {
width: 100%;
height: 144rpx;
background: #F5F5F5;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
.placeholder-text {
font-size: 24rpx;
color: #999999;
}
}
.reward-info { .reward-info {
display: flex; display: flex;
align-items: center; align-items: center;
@ -859,6 +1121,11 @@
font-weight: 400; font-weight: 400;
} }
} }
.error-text {
color: #DE3C4B;
font-style: italic;
}
} }
} }
} }

1
static/information.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB