Files
uni-fans-score/pages/my/card.vue
T

243 lines
5.3 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="my-card-page">
<!-- 会员卡列表 -->
<view class="card-list" v-if="cardList.length > 0">
<view v-for="card in cardList" :key="card.id" class="card-item" @click="viewCardDetail(card)">
<view class="card-header">
<text class="card-name">{{ card.name }}</text>
<view class="card-status" :class="getStatusClass(card.status)">
<text class="status-text">{{ getStatusText(card.status) }}</text>
</view>
</view>
<view class="card-info">
<text class="info-label">{{ $t('myCard.type') }}</text>
<text class="info-value">{{ card.cardType === 'COUNT' ? $t('myCard.timesCard') :
$t('myCard.durationCard') }}</text>
</view>
<view class="card-info" v-if="card.type === 'times'">
<text class="info-label">{{ $t('myCard.remainingTimes') }}</text>
<text class="info-value highlight">{{ card.remainingTimes }}/{{ card.totalTimes }}</text>
</view>
<view class="card-info" v-if="card.type === 'duration'">
<text class="info-label">{{ $t('myCard.remainingDuration') }}</text>
<text class="info-value highlight">{{ card.remainingDuration }}{{ $t('myCard.hours') }}</text>
</view>
<view class="card-info">
<text class="info-label">{{ $t('myCard.validPeriod') }}</text>
<text class="info-value">{{ card.startDate }} - {{ card.endDate }}</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-else>
<image class="empty-icon" src="/static/empty-card.png" mode="aspectFit"></image>
<text class="empty-text">{{ $t('myCard.noCards') }}</text>
<view class="buy-btn" @click="goToBuy">
<text class="buy-text">{{ $t('myCard.buyNow') }}</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useI18n } from '@/utils/i18n.js'
import {
getMemberCardsByStatus
} from '@/config/api/member.js'
const { t: $t } = useI18n()
// 会员卡列表
const cardList = ref([])
// 获取会员卡列表
const getCardList = async () => {
try {
const response = await getMemberCardsByStatus()
// 处理API返回的数据,转换为模板需要的格式
if (response.code === 200 && response.data) {
cardList.value = response.data.map(item => ({
id: item.id,
name: item.cardName,
cardType: item.cardType, // TIME -> time
totalTimes: item.totalCount,
remainingTimes: item.remainingCount,
remainingDuration: item.singleLimitMinutes,
status: item.status,
startDate: item.startTime,
endDate: item.endTime,
positionName: item.positionName,
purchasePrice: item.purchasePrice,
// 添加可能的其他字段
...item
}))
} else {
cardList.value = []
}
} catch (error) {
console.error('获取会员卡列表失败:', error)
uni.showToast({
title: $t('myCard.getListFailed'),
icon: 'none'
})
}
}
// 获取状态类名
const getStatusClass = (status) => {
const statusMap = {
'unused': 'active',
'expired': 'expired',
'used': 'used',
'active': 'active' // 兼容原始状态
}
return statusMap[status] || 'active' // 默认为active
}
// 获取状态文本
const getStatusText = (status) => {
const statusMap = {
'unused': $t('myCard.active'), // unused表示未使用,即活跃状态
'expired': $t('myCard.expired'),
'used': $t('myCard.used'),
'active': $t('myCard.active') // 兼容原始状态
}
return statusMap[status] || $t('myCard.active') // 默认为active
}
// 查看卡详情
const viewCardDetail = (card) => {
// TODO: 跳转到卡详情页面
// uni.showToast({
// title: $t('common.functionDeveloping'),
// icon: 'none'
// })
}
// 去购买
const goToBuy = () => {
uni.navigateTo({
url: '/pages/purchase/index'
})
}
onMounted(() => {
uni.setNavigationBarTitle({
title: $t('user.myCards')
})
getCardList()
})
</script>
<style lang="scss" scoped>
.my-card-page {
min-height: 100vh;
background-color: #f5f5f5;
padding: 20rpx;
}
.card-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.card-item {
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.card-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.card-status {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 22rpx;
&.active {
background-color: #e8f5e8;
color: #4caf50;
}
&.expired {
background-color: #ffeaea;
color: #f44336;
}
&.used {
background-color: #f0f0f0;
color: #999;
}
}
.card-info {
display: flex;
align-items: center;
margin-bottom: 12rpx;
.info-label {
font-size: 26rpx;
color: #666;
}
.info-value {
font-size: 26rpx;
color: #333;
&.highlight {
color: #FF6B00;
font-weight: 600;
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 0;
.empty-icon {
width: 200rpx;
height: 200rpx;
margin-bottom: 40rpx;
opacity: 0.5;
}
.empty-text {
font-size: 28rpx;
color: #999;
margin-bottom: 40rpx;
}
.buy-btn {
padding: 20rpx 60rpx;
background-color: #B8741A;
border-radius: 48rpx;
.buy-text {
font-size: 28rpx;
color: #ffffff;
font-weight: 500;
}
}
}
</style>