1122 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="scan-result">
<!-- 已失效状态 -->
<template v-if="errorType === 'expired' || info.qrcode.qrcodeStatus == 2">
<view class="scan-result__header">
<image src="/static/information.svg" class="scan-result__icon"></image>
<text class="scan-result__title">该二维码无法领取品牌返利</text>
<text class="scan-result__desc">失效原因{{ info.qrcode.remark}}</text>
</view>
<view class="scan-result__content">
<view class="scan-result__section">
<text class="scan-result__section-title">商品详细</text>
<view class="product-card" v-if="beer">
<view class="product-card__image">
<image :src="beer.cover" mode="aspectFill"></image>
</view>
<view class="product-card__info">
<text class="product-card__name">{{ beer.beerName }}</text>
<text class="product-card__brand">{{ beer.brandName }}</text>
<view class="product-card__detail">
<text class="product-card__label">生产日期</text>
<text class="product-card__value">{{ beer.launchDate }}</text>
</view>
<view class="product-card__detail">
<text class="product-card__label">净含量</text>
<text class="product-card__value">{{ beer.netContent }}</text>
</view>
<view class="product-card__rating">
<view class="rating-stars">
<text class="cuIcon-favorfill"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{ beer.beerReviewsCount }} 条评论</text>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__footer">
<button class="scan-result__btn scan-result__btn--back" @click="back">
<image src="/static/undo.svg"></image>
<text>返回</text>
</button>
<button class="scan-result__btn scan-result__btn--share" @click="share">
<image src="/static/send-2.svg"></image>
<text>分享上新</text>
</button>
</view>
</template>
<!-- 领取成功状态 - 刚刚领取成功 -->
<template v-if="info.qrcode.qrcodeStatus == 1 && isJustReceived">
<view class="scan-result__header scan-result__header--success">
<image src="/static/tick-circle.svg" class="scan-result__icon"></image>
<text class="scan-result__title">领取成功</text>
</view>
<view class="scan-result__content">
<view class="scan-result__section">
<text class="scan-result__section-title">领取信息</text>
<view class="benefit-card">
<view class="benefit-card__title">{{ beer.scanCoinCount }}{{beer.brandName}}品牌啤酒币已到账</view>
<text class="benefit-card__subtitle">品牌啤酒币可用于兑换好礼</text>
</view>
<view class="activity-info" v-if="selectedActivity">
<text class="activity-info__progress">距离目标达成还剩 {{ selectedActivity.remainingBeerCount }} </text>
</view>
</view>
<view class="scan-result__section">
<text class="scan-result__section-title">商品详细</text>
<view class="product-card" v-if="beer">
<view class="product-card__image">
<image :src="beer.cover" mode="aspectFill"></image>
</view>
<view class="product-card__info">
<text class="product-card__name">{{ beer.beerName }}</text>
<text class="product-card__brand">{{ beer.brandName }}</text>
<view class="product-card__detail">
<text class="product-card__label">生产日期</text>
<text class="product-card__value">{{ beer.launchDate }}</text>
</view>
<view class="product-card__detail">
<text class="product-card__label">净含量</text>
<text class="product-card__value">{{ beer.netContent }}</text>
</view>
<view class="product-card__rating">
<view class="rating-stars">
<text class="cuIcon-favorfill"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{ beer.beerReviewsCount }} 条评论</text>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__footer">
<button class="scan-result__btn scan-result__btn--back" @click="toWinelist">
<image src="@/static/document.png"></image>
<text>生成酒单</text>
</button>
<button class="scan-result__btn scan-result__btn--share" @click="share">
<image src="/static/send-2.svg"></image>
<text>分享上新</text>
</button>
</view>
</template>
<!-- 再次扫码已领取的商品 -->
<template v-if="info.qrcode.qrcodeStatus == 1 && !isJustReceived">
<view class="scan-result__header">
<image src="/static/information.svg" class="scan-result__icon"></image>
<text class="scan-result__title">该桶产品已于 {{ info.qrcode.verifyTime }} 扫码领取成功</text>
</view>
<view class="scan-result__content">
<view class="scan-result__section">
<text class="scan-result__section-title">商品详细</text>
<view class="product-card" v-if="beer">
<view class="product-card__image">
<image :src="beer.cover" mode="aspectFill"></image>
</view>
<view class="product-card__info">
<text class="product-card__name">{{ beer.beerName }}</text>
<text class="product-card__brand">{{ beer.brandName }}</text>
<view class="product-card__detail">
<text class="product-card__label">生产日期</text>
<text class="product-card__value">{{ beer.launchDate }}</text>
</view>
<view class="product-card__detail">
<text class="product-card__label">净含量</text>
<text class="product-card__value">{{ beer.netContent }}</text>
</view>
<view class="product-card__rating">
<view class="rating-stars">
<text class="cuIcon-favorfill"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{ beer.beerReviewsCount }} 条评论</text>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__footer">
<button class="scan-result__btn scan-result__btn--back" @click="toWinelist">
<image src="@/static/document.png"></image>
<text>生成酒单</text>
</button>
<button class="scan-result__btn scan-result__btn--share" @click="share">
<image src="/static/send-2.svg"></image>
<text>分享上新</text>
</button>
</view>
</template>
<!-- 待领取状态 -->
<template v-if="info.qrcode.qrcodeStatus == 0">
<view class="scan-result__header scan-result__header--success">
<image src="/static/tick-circle.svg" class="scan-result__icon"></image>
<text class="scan-result__title">扫码成功</text>
</view>
<view class="scan-result__content">
<view class="scan-result__section">
<text class="scan-result__section-title">商品详细</text>
<view class="product-card" v-if="beer">
<view class="product-card__image">
<image :src="beer.cover" mode="aspectFill"></image>
</view>
<view class="product-card__info">
<text class="product-card__name">{{ beer.beerName }}</text>
<text class="product-card__brand">{{ beer.brandName }}</text>
<view class="product-card__detail">
<text class="product-card__label">生产日期</text>
<text class="product-card__value">{{ beer.launchDate }}</text>
</view>
<view class="product-card__detail">
<text class="product-card__label">净含量</text>
<text class="product-card__value">{{ beer.netContent }}</text>
</view>
<view class="product-card__rating">
<view class="rating-stars">
<text class="cuIcon-favorfill"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{ beer.beerReviewsCount }} 条评论</text>
</view>
</view>
</view>
</view>
<view class="scan-result__section">
<text class="scan-result__section-title">品牌福利</text>
<view class="benefit-card">
<view class="benefit-card__title">可获得 {{ beer.scanCoinCount }}{{beer.brandName}}品牌啤酒币</view>
<text class="benefit-card__subtitle">品牌啤酒币可用于兑换好礼</text>
</view>
</view>
<view class="activity-notice" v-if="activitySum > 1">
<image src="/static/warning-2.png" mode="aspectFit"></image>
<text>该产品有多个进行中活动可选请选择要计入的活动</text>
</view>
<view class="scan-result__section" v-if="activity && activity.length > 0">
<text class="scan-result__section-title">品牌活动</text>
<view class="activity-list">
<view
class="activity-item"
v-for="(item, index) in activity"
:key="index"
:class="{'activity-item--selected': activityId === item.id}"
@click="selectPPF(item)"
>
<!-- <view class="activity-item__header">
<text class="activity-item__title">{{ item.breweryName }}</text>
</view> -->
<view class="activity-item__tag-container">
<text class="activity-item__tag activity-item__tag--time" v-if="item.endDate">剩余{{getRemainingDays(item.endDate)}}</text>
</view>
<view class="activity-item__content">
<view class="activity-item__progress">
<text>距离累计目标达成还剩</text>
<text class="activity-item__remaining-count">{{item.remainingBeerCount}}</text>
</view>
<view class="activity-item__time">
<text>时间首次扫码开始累计</text>
<text class="activity-item__duration">{{item.duration}}天内</text>
</view>
<view class="activity-item__target">
<text>目标{{item.beerScope === 0 ? '品牌全系' : '以下'}}酒款累积扫码 </text>
<text class="activity-item__count">{{ item.activityTarget}}</text>
</view>
<scroll-view v-if="item.beers && item.beers.length > 0"
scroll-x="true"
class="activity-item__beers"
enhanced
show-scrollbar="false"
>
<view
class="activity-item__beer"
v-for="(beer, beerIndex) in item.beers"
:key="beerIndex"
>
<image v-if="beer.cover" :src="beer.cover" mode="aspectFit"></image>
</view>
</scroll-view>
<view class="activity-item__reward">
<text class="activity-item__reward-tag"></text>
<view class="activity-item__reward-content" v-if="item.activityRewardType == 1 && item.activityRewardGoods">
<image
v-if="item.activityRewardGoods.cover"
:src="item.activityRewardGoods.cover"
class="activity-item__reward-image"
mode="aspectFit"
></image>
<view class="activity-item__reward-info">
<text class="activity-item__reward-name">{{item.activityRewardGoods.goodsName}}</text>
<text class="activity-item__reward-specs">规格{{item.activityRewardGoods.specs}}</text>
<text class="activity-item__reward-count">数量{{item.activityRewardCount}}</text>
</view>
</view>
<view class="activity-item__reward-content" v-if="item.activityRewardType == 2">
<image
src="/static/coin.png"
class="activity-item__reward-image"
mode="aspectFit"
></image>
<view class="activity-item__reward-info">
<text class="activity-item__reward-name">品牌啤酒币</text>
<text class="activity-item__reward-count">数量{{item.activityRewardCount}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__section" v-if="platformActivity && platformActivity.length > 0">
<text class="scan-result__section-title">平台活动</text>
<view class="activity-list">
<view
class="activity-item"
v-for="(item, index) in platformActivity"
:key="index"
:class="{'activity-item--selected': platformActivityId === item.id}"
@click="selectPlatform(item)"
>
<view class="activity-item__header">
<text class="activity-item__title">{{ item.activityName }}</text>
</view>
<view class="activity-item__tag-container">
<text class="activity-item__tag activity-item__tag--time" v-if="item.endDate">剩余{{getRemainingDays(item.endDate)}}</text>
</view>
<view class="activity-item__content">
<view class="activity-item__progress">
<text>距离达成还剩</text>
<text class="activity-item__remaining-count">{{item.remainingBeerCount}}</text>
</view>
<view class="activity-item__time">
<text>时间首次扫码开始累计</text>
<text class="activity-item__duration">{{item.duration}}天内</text>
</view>
<view class="activity-item__target">
<text>目标{{item.beerScope === 0 ? '品牌全系' : '以下'}}酒款累积扫码 </text>
<text class="activity-item__count">{{ item.activityTarget}}</text>
</view>
<view class="activity-item__reward">
<text class="activity-item__reward-tag"></text>
<view class="activity-item__reward-content" v-if="item.activityRewardType == 1 && item.activityRewardGoods">
<image
v-if="item.activityRewardGoods.cover"
:src="item.activityRewardGoods.cover"
class="activity-item__reward-image"
mode="aspectFit"
></image>
<view class="activity-item__reward-info">
<text class="activity-item__reward-name">{{item.activityRewardGoods.goodsName}}</text>
<text class="activity-item__reward-specs">规格{{item.activityRewardGoods.specs}}</text>
<text class="activity-item__reward-count">数量{{item.activityRewardCount}}</text>
</view>
</view>
<view class="activity-item__reward-content" v-if="item.activityRewardType == 2">
<image
src="/static/coin.png"
class="activity-item__reward-image"
mode="aspectFit"
></image>
<view class="activity-item__reward-info">
<text class="activity-item__reward-name">品牌啤酒币</text>
<text class="activity-item__reward-count">数量{{item.activityRewardCount}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__footer">
<button class="scan-result__btn scan-result__btn--back" @click="back">
<image src="/static/undo.svg"></image>
<text>回头再说</text>
</button>
<button class="scan-result__btn scan-result__btn--share" @click="showConfirmPopup">
<image src="/static/send-2.svg"></image>
<text>立即领取</text>
</button>
</view>
<!-- 确认弹窗 -->
<uni-popup ref="confirmPopup" type="dialog">
<uni-popup-dialog
type="info"
title="领取确认"
content="每桶产品仅可领取一次,是否确认领取?"
:before-close="true"
@confirm="confirmReceive"
@close="closePopup"
></uni-popup-dialog>
</uni-popup>
</template>
<!-- 位置错误状态 -->
<template v-if="errorType === 'location'">
<view class="scan-result__header scan-result__header--error">
<image src="/static/information.png" class="scan-result__icon"></image>
<text class="scan-result__title">位置错误</text>
<text class="scan-result__desc">请在酒吧附近100米范围内扫码</text>
</view>
<view class="scan-result__content">
<view class="scan-result__section">
<text class="scan-result__section-title">商品详细</text>
<view class="product-card" v-if="beer">
<view class="product-card__image">
<image :src="beer.cover" mode="aspectFill"></image>
</view>
<view class="product-card__info">
<text class="product-card__name">{{ beer.beerName }}</text>
<text class="product-card__brand">{{ beer.brandName }}</text>
<view class="product-card__detail">
<text class="product-card__label">生产日期</text>
<text class="product-card__value">{{ beer.launchDate }}</text>
</view>
<view class="product-card__detail">
<text class="product-card__label">净含量</text>
<text class="product-card__value">{{ beer.netContent }}</text>
</view>
<view class="product-card__rating">
<view class="rating-stars">
<text class="cuIcon-favorfill"></text>
<text class="rating-value">{{ beer.beerOverallRating }}</text>
</view>
<text class="rating-count">{{ beer.beerReviewsCount }} 条评论</text>
</view>
</view>
</view>
</view>
</view>
<view class="scan-result__footer">
<button class="scan-result__btn scan-result__btn--back" @click="back">
<image src="/static/undo.svg"></image>
<text>返回</text>
</button>
<button class="scan-result__btn scan-result__btn--share" @click="share">
<image src="/static/send-2.svg"></image>
<text>分享上新</text>
</button>
</view>
</template>
</view>
</template>
<script>
import {
consumeCode,
getQrcodeInfo
} from '@/api/bar.js'
import BeerCard from '@/components/BeerCard.vue'
export default {
components: {
BeerCard
},
data() {
return {
showError: false,
info: {
qrcode: {
qrcodeStatus: null, // 0: 待领取, 1: 领取成功, 2: 已失效, 3: 转为赠品
},
},
activity: [], // 活动列表
platformActivity: [], // 平台活动
activityList: [],
activitySum: 0, // 活动数量
beer: null,
result: null, // 扫码结果 code
activityId: null, // 活动id
platformActivityId: null, // 平台活动id
latitude: null,
longitude: null,
errorType: null, // 错误类型: location-位置错误, expired-已失效
isJustReceived: false, // 是否刚刚领取成功
selectedActivity: null, // 选中的活动
};
},
onLoad({
result,
latitude,
longitude
}) {
this.result = result
this.latitude = latitude
this.longitude = longitude
this.isJustReceived = false // 重置领取状态
// 查询二维码信息
this.getQrcodeInfoFun(result)
},
methods: {
// 查询二维码信息
getQrcodeInfoFun(code) {
getQrcodeInfo({
code,
latitude: this.latitude,
longitude: this.longitude
}).then(res => {
console.log(res.data)
this.showError = false // 重置错误状态
this.errorType = null // 重置错误类型
this.info = res.data
this.beer = res.data.beer
this.activity = res.data.activity || []
this.platformActivity = res.data.platformActivity || []
this.activitySum = 0 // 重置活动数量
if (this.activity && this.activity.length > 0) {
this.activitySum += this.activity.length
this.activityId = this.activity[0].id
}
if (this.platformActivity && this.platformActivity.length > 0) {
this.activitySum += this.platformActivity.length
this.platformActivityId = this.platformActivity[0].id
}
}).catch(err => {
console.error('获取二维码信息失败:', err)
this.showError = true
if (err.code === 500 && err.msg === '请在酒吧附近100米范围内扫码') {
this.errorType = 'location'
} else if (err.code === 500 && err.msg.includes('已失效')) {
this.errorType = 'expired'
} else {
this.errorType = 'expired'
uni.showToast({
title: err.msg || '获取信息失败',
icon: 'none'
})
}
})
},
// 显示确认弹窗
showConfirmPopup() {
this.$refs.confirmPopup.open();
},
// 关闭弹窗
closePopup() {
this.$refs.confirmPopup.close();
},
// 确认领取
confirmReceive() {
this.handleReceive();
this.closePopup();
},
// 立即领取
handleReceive() {
const data = {
code: this.result,
latitude: this.latitude,
longitude: this.longitude
}
if (this.activityId) {
data.activityId = this.activityId
}
if (this.platformActivityId) {
data.platformActivityId = this.platformActivityId
}
// 显示加载提示
uni.showLoading({
title: '领取中...',
mask: true
})
consumeCode(data).then(res => {
console.log('领取响应:', res)
// 验证响应数据
if (res.code === 200) {
uni.hideLoading()
uni.showToast({
title: '领取成功',
icon: 'success'
})
// 设置刚刚领取成功状态
this.isJustReceived = true
// 延迟刷新数据,确保后端数据已更新
setTimeout(() => {
this.getQrcodeInfoFun(this.result)
}, 1000)
} else {
throw new Error(res.msg || '领取失败')
}
}).catch(err => {
console.error('领取失败:', err)
uni.hideLoading()
if (err.code === 500 && err.msg === '请在酒吧附近100米范围内扫码') {
this.showError = true
this.errorType = 'location'
} else if (err.code === 500 && err.msg.includes('reward_sn')) {
uni.showToast({
title: '系统维护中,请稍后再试',
icon: 'none',
duration: 2000
})
} else if (err.code === 500 && err.msg.includes('已领取')) {
uni.showToast({
title: '该酒品已领取过,请勿重复领取',
icon: 'none',
duration: 2000
})
} else {
uni.showToast({
title: err.msg || '领取失败,请重试',
icon: 'none',
duration: 2000
})
}
})
},
back() {
if (this.info.qrcode.qrcodeStatus == 1) {
// 领取成功时返回首页
uni.switchTab({
url: '/pages/index/index'
})
} else {
// 其他情况正常返回上一页
uni.navigateBack()
}
},
// 选择品牌方活动
selectPPF(item) {
this.activityId = item.id
this.selectedActivity = item
},
// 选择平台活动
selectPlatform(item) {
this.platformActivityId = item.id
},
// 生成酒单
toWinelist() {
uni.navigateTo({
url: '/pagesActivity/winelist?beerId=' + this.beer.id
})
},
share() {
uni.downloadFile({
url: this.beer.cover,
success: (res) => {
console.log(res)
// #ifdef MP-WEIXIN
uni.showShareImageMenu({
provider: 'weixin',
path: res.tempFilePath,
shareType: 0,
success: (res) => {
console.log(res)
},
fail: (err) => {
console.log(err)
}
})
// #endif
}
})
},
formatTime(timestamp) {
const date = new Date(timestamp);
return date.toLocaleString();
},
// 计算剩余天数
getRemainingDays(endDate) {
if(!endDate) return 0;
const targetDate = new Date(endDate);
const currentDate = new Date();
const timeDiff = targetDate.getTime() - currentDate.getTime();
const remainingDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
return Math.max(remainingDays, 0); // 确保不会显示负数天数
}
}
}
</script>
<style lang="scss" scoped>
.scan-result {
min-height: 100vh;
background: #F5F7FA;
padding: 32rpx 26rpx 160rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
position: relative;
&__header {
text-align: center;
margin-bottom: 40rpx;
padding-top: 40rpx;
&--success {
display: flex;
align-items: center;
justify-content: center;
gap: 20rpx;
}
&--error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16rpx;
}
}
&__icon {
width: 120rpx;
height: 120rpx;
margin-bottom: 24rpx;
}
&__title {
display: block;
font-size: 32rpx;
color: #333;
font-weight: 500;
margin-bottom: 16rpx;
}
&__desc {
display: block;
font-size: 28rpx;
color: #666;
}
&__content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding-bottom: 40rpx;
}
&__section {
background: #FFF;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 24rpx;
}
&__section-title {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 24rpx;
display: block;
position: relative;
padding-left: 24rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 32rpx;
background: linear-gradient(180deg, #D42E78 0%, #19367A 100%);
border-radius: 3rpx;
}
}
&__footer {
margin-top: auto;
display: flex;
justify-content: space-between;
gap: 24rpx;
padding: 24rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
background: #fff;
position: fixed;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
z-index: 100;
}
&__btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
border: none;
padding: 0;
image {
width: 40rpx;
height: 40rpx;
margin-right: 8rpx;
}
&--back {
background: #F7F8FA;
color: #4E63E0;
}
&--share {
background: #19367A;
color: #FFF;
}
&:active {
transform: scale(0.98);
opacity: 0.9;
}
}
&__icon-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 16rpx;
}
&__icon {
width: 120rpx;
height: 120rpx;
margin-bottom: 16rpx;
&--info {
width: 80rpx;
height: 80rpx;
margin-bottom: 8rpx;
}
}
.activity-info {
margin-top: 24rpx;
padding: 24rpx;
background: #F7F8FA;
border-radius: 16rpx;
&__progress {
font-size: 28rpx;
color: #19367A;
font-weight: 500;
}
}
}
.product-card {
display: flex;
gap: 24rpx;
&__image {
width: 200rpx;
height: 280rpx;
border-radius: 12rpx;
overflow: hidden;
image {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__info {
flex: 1;
}
&__name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
display: block;
}
&__brand {
font-size: 28rpx;
color: #666;
margin-bottom: 16rpx;
display: block;
}
&__detail {
display: flex;
margin-bottom: 8rpx;
}
&__label {
font-size: 26rpx;
color: #999;
}
&__value {
font-size: 26rpx;
color: #333;
}
&__rating {
display: flex;
align-items: center;
margin-top: 16rpx;
.rating-stars {
display: flex;
align-items: center;
margin-right: 16rpx;
.cuIcon-favorfill {
color: #FFBC11;
margin-right: 4rpx;
}
.rating-value {
font-size: 28rpx;
color: #333;
}
}
.rating-count {
font-size: 24rpx;
color: #999;
}
}
}
.benefit-card {
background: #FFF;
padding: 0 24rpx;
border-radius: 16rpx;
&__title {
font-size: 32rpx;
font-weight: 600;
color: #3D3D3D;
margin-top: 8rpx;
// margin-bottom: 24rpx;
display: block;
}
&__subtitle {
font-size: 24rpx;
color: rgba(151, 151, 151, 0.75);
font-weight: 400;
}
}
.activity-notice {
display: flex;
align-items: center;
background: #FFF9E6;
padding: 20rpx 24rpx;
border-radius: 12rpx;
margin-bottom: 24rpx;
image {
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
}
text {
font-size: 26rpx;
color: #FF9900;
}
}
.activity-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.activity-item {
background: #FFFFFF;
border-radius: 20rpx;
padding: 32rpx;
border: 1px solid #EFEDE9;
box-shadow: 0 8rpx 16rpx rgba(0, 0, 0, 0.08);
transition: all 0.3s;
position: relative;
&--selected {
border-color: #19367A;
background: rgba(25, 54, 122, 0.05);
}
&__header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
&__title {
font-size: 36rpx;
font-weight: bold;
color: #0B0E26;
}
&__tag-container {
position: absolute;
top: 32rpx;
left: 32rpx;
display: flex;
gap: 8rpx;
z-index: 1;
}
&__tag {
font-size: 20rpx;
color: #FFFFFF;
padding: 6rpx 16rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.3);
&--time {
background-color: #D42E78;
}
}
&__content {
padding-top: 48rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
}
&__progress {
font-size: 28rpx;
font-weight: 500;
color: #0B0E26;
line-height: 44rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
&__time, &__target {
font-size: 28rpx;
font-weight: 500;
color: #0B0E26;
line-height: 44rpx;
}
&__duration, &__count {
color: #D42E78;
font-weight: bold;
}
&__beers {
width: 100%;
display: flex;
flex-direction: row;
white-space: nowrap;
height: 200rpx;
margin: 4rpx 0 24rpx;
overflow-x: auto;
}
&__beer {
width: 120rpx;
height: 170rpx;
background: #FFFFFF;
margin-right: 8rpx;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 12rpx;
overflow: hidden;
image {
width: 100%;
height: 100%;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
object-fit: contain;
}
}
&__deadline {
font-size: 28rpx;
font-weight: 500;
color: #0B0E26;
line-height: 44rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
&__remaining-days {
color: #FF6B35;
font-weight: bold;
}
&__remaining-count {
color: #19367A;
font-weight: bold;
font-size: 32rpx;
}
&__reward {
background: #F7F8FA;
border-radius: 16rpx;
padding: 24rpx;
margin-top: 20rpx;
}
&__reward-content {
display: flex;
align-items: center;
gap: 20rpx;
margin-top: 16rpx;
}
&__reward-image {
width: 120rpx;
height: 120rpx;
border-radius: 12rpx;
background: #FFFFFF;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
&__reward-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
}
&__reward-name {
font-size: 28rpx;
font-weight: 500;
color: #0B0E26;
}
&__reward-specs {
font-size: 24rpx;
color: #666666;
}
&__reward-count {
font-size: 24rpx;
color: #D42E78;
font-weight: 500;
}
}
</style>