276 lines
11 KiB
Vue
276 lines
11 KiB
Vue
<template>
|
|
<view class="member-card-section">
|
|
<view class="member-card-section__inner">
|
|
<view class="member-card-section__head">
|
|
<view class="member-card-section__head-inner">
|
|
<text class="member-card-section__title">
|
|
我的会员卡
|
|
</text>
|
|
<view
|
|
class="member-card-section__count"
|
|
>
|
|
<text class="member-card-section__count-num">{{ cardInfo.activeCount || 0 }}</text>
|
|
<text class="member-card-section__count-text">张有效</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
class="member-card-preview"
|
|
hover-class="mi-tap-card--hover"
|
|
:hover-stay-time="150"
|
|
@tap="$emit('view-all')"
|
|
>
|
|
<view class="member-card-preview__inner">
|
|
<view class="member-card-preview__head">
|
|
<view class="member-card-preview__head-inner">
|
|
<view
|
|
class="member-card-preview__type-row"
|
|
>
|
|
<view
|
|
class="member-card-preview__icon-wrap"
|
|
>
|
|
<view
|
|
class="member-card-preview__icon-border"
|
|
>
|
|
<view
|
|
class="member-card-preview__icon-bg"
|
|
></view>
|
|
<view
|
|
class="member-card-preview__icon-stroke"
|
|
></view>
|
|
</view>
|
|
<image class="member-card-preview__icon-line" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Line_2_468.png" mode="aspectFill" />
|
|
</view>
|
|
<text
|
|
class="member-card-preview__name"
|
|
>
|
|
{{ cardInfo.hasActiveCard ? cardInfo.name : '暂无会员卡' }}
|
|
</text>
|
|
</view>
|
|
<view
|
|
class="member-card-preview__tag"
|
|
:class="getTagClass()"
|
|
v-if="cardInfo.hasActiveCard"
|
|
>
|
|
<text class="member-card-preview__tag-text">
|
|
{{ getTagText() }}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<text class="member-card-preview__expire" v-if="cardInfo.hasActiveCard && cardInfo.expireDate">
|
|
有效期至 {{ cardInfo.expireDate }}
|
|
</text>
|
|
<view class="member-card-preview__footer">
|
|
<view class="member-card-preview__footer-inner">
|
|
<view
|
|
class="member-card-preview__days"
|
|
v-if="cardInfo.hasActiveCard"
|
|
>
|
|
<text
|
|
class="member-card-preview__days-num"
|
|
:class="getDaysClass()"
|
|
>
|
|
{{ getDisplayDays() }}
|
|
</text>
|
|
<text
|
|
class="member-card-preview__days-unit"
|
|
>
|
|
{{ getDaysUnit() }}
|
|
</text>
|
|
</view>
|
|
<view
|
|
class="member-card-preview__purchase"
|
|
hover-class="mi-tap-btn--hover"
|
|
:hover-stay-time="150"
|
|
@tap.stop="$emit('purchase')"
|
|
>
|
|
<text
|
|
class="member-card-preview__purchase-text"
|
|
>
|
|
购买新卡
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { reactive, onMounted } from 'vue'
|
|
import { getPrimaryMemberCard, getMyMemberCardsWithStatus } from '@/api/main.js'
|
|
import { getMemberId } from '@/utils/request.js'
|
|
|
|
defineEmits(['view-all', 'purchase'])
|
|
|
|
const cardInfo = reactive({
|
|
name: '',
|
|
type: '',
|
|
remainingTimes: 0,
|
|
remainingDays: 0,
|
|
expireDate: '',
|
|
activeCount: 0,
|
|
isExpiring: false,
|
|
isExpired: false,
|
|
isUsedUp: false,
|
|
hasActiveCard: false
|
|
})
|
|
|
|
let isLoading = false
|
|
|
|
// 格式化日期
|
|
function formatDate(dateStr) {
|
|
if (!dateStr) return ''
|
|
try {
|
|
const date = new Date(dateStr)
|
|
const year = date.getFullYear()
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
return `${year}-${month}-${day}`
|
|
} catch (e) {
|
|
return dateStr
|
|
}
|
|
}
|
|
|
|
// 加载会员卡数据
|
|
async function loadMemberCard() {
|
|
if (isLoading) {
|
|
console.log('[MemberInfoMemberCard] 正在加载中,跳过重复请求')
|
|
return
|
|
}
|
|
isLoading = true
|
|
try {
|
|
// 使用统一的 getMemberId 方法获取会员ID
|
|
const memberId = getMemberId()
|
|
console.log('[MemberInfoMemberCard] memberId:', memberId)
|
|
|
|
if (!memberId) {
|
|
console.log('[MemberInfoMemberCard] 未登录,无会员ID')
|
|
return
|
|
}
|
|
|
|
console.log('[MemberInfoMemberCard] 加载会员卡数据, memberId:', memberId)
|
|
|
|
// 并行获取主要会员卡和有效卡列表
|
|
const [primaryCardRes, activeCardsRes] = await Promise.all([
|
|
getPrimaryMemberCard(memberId),
|
|
getMyMemberCardsWithStatus(memberId, 'active')
|
|
])
|
|
|
|
console.log('[MemberInfoMemberCard] getPrimaryMemberCard 返回:', JSON.stringify(primaryCardRes, null, 2))
|
|
console.log('[MemberInfoMemberCard] getMyMemberCardsWithStatus(active) 返回:', JSON.stringify(activeCardsRes, null, 2))
|
|
|
|
// 解析主要会员卡数据
|
|
let displayCard = null
|
|
if (primaryCardRes?.data) {
|
|
displayCard = primaryCardRes.data
|
|
} else if (primaryCardRes?.value) {
|
|
displayCard = primaryCardRes.value
|
|
} else if (primaryCardRes && typeof primaryCardRes === 'object') {
|
|
displayCard = primaryCardRes
|
|
}
|
|
|
|
// 计算有效会员卡数量(过滤储值卡)
|
|
let activeCount = 0
|
|
let allActiveCards = []
|
|
if (activeCardsRes?.value) {
|
|
allActiveCards = activeCardsRes.value
|
|
} else if (Array.isArray(activeCardsRes)) {
|
|
allActiveCards = activeCardsRes
|
|
} else if (activeCardsRes?.data) {
|
|
allActiveCards = Array.isArray(activeCardsRes.data) ? activeCardsRes.data : (activeCardsRes.data.value || [])
|
|
}
|
|
// 过滤储值卡
|
|
allActiveCards = allActiveCards.filter(card => card.memberCardType !== 'STORED_VALUE_CARD')
|
|
activeCount = allActiveCards.length
|
|
|
|
// 计算卡片状态
|
|
let diffDays = 0
|
|
let isExpiring = false
|
|
let isExpired = false
|
|
let isUsedUp = false
|
|
let displayDays = 0
|
|
|
|
if (displayCard) {
|
|
if (displayCard.status === 'USED_UP') {
|
|
isUsedUp = true
|
|
displayDays = displayCard.remainingTimes || 0
|
|
} else if (displayCard.expireTime) {
|
|
const expireTime = new Date(displayCard.expireTime)
|
|
const now = new Date()
|
|
diffDays = Math.ceil((expireTime - now) / (1000 * 60 * 60 * 24))
|
|
isExpiring = diffDays > 0 && diffDays <= 3
|
|
isExpired = diffDays <= 0
|
|
displayDays = Math.abs(diffDays)
|
|
}
|
|
}
|
|
console.log(displayCard)
|
|
|
|
// 更新数据
|
|
cardInfo.name = displayCard?.memberCardName || '暂无会员卡'
|
|
cardInfo.type = displayCard?.memberCardType || ''
|
|
cardInfo.remainingTimes = displayCard?.remainingTimes || displayCard?.remainingAmount || 0
|
|
cardInfo.remainingDays = displayDays
|
|
cardInfo.expireDate = displayCard?.expireTime ? formatDate(displayCard.expireTime) : ''
|
|
cardInfo.activeCount = activeCount
|
|
cardInfo.isExpiring = isExpiring
|
|
cardInfo.isExpired = isExpired
|
|
cardInfo.isUsedUp = isUsedUp
|
|
cardInfo.hasActiveCard = activeCount > 0
|
|
|
|
console.log('[MemberInfoMemberCard] 更新后的 cardInfo:', JSON.stringify(cardInfo, null, 2))
|
|
} catch (e) {
|
|
console.error('[MemberInfoMemberCard] 加载会员卡数据失败:', e)
|
|
cardInfo.hasActiveCard = false
|
|
} finally {
|
|
isLoading = false
|
|
}
|
|
}
|
|
|
|
// 组件挂载时加载数据
|
|
onMounted(() => {
|
|
console.log('[MemberInfoMemberCard] 组件已挂载,开始加载数据')
|
|
loadMemberCard()
|
|
})
|
|
|
|
function getTagClass() {
|
|
if (cardInfo.isExpiring) return 'member-card-preview__tag--expiring'
|
|
if (cardInfo.isExpired) return 'member-card-preview__tag--expired'
|
|
if (cardInfo.isUsedUp) return 'member-card-preview__tag--expired'
|
|
return 'member-card-preview__tag--active'
|
|
}
|
|
|
|
function getTagText() {
|
|
if (cardInfo.isUsedUp) return '已用完'
|
|
if (cardInfo.isExpired) return '已失效'
|
|
if (cardInfo.isExpiring) return '临期'
|
|
return '有效'
|
|
}
|
|
|
|
function getDaysClass() {
|
|
if (cardInfo.isExpiring) return 'member-card-preview__days-num--expiring'
|
|
if (cardInfo.isExpired) return 'member-card-preview__days-num--expired'
|
|
if (cardInfo.isUsedUp) return 'member-card-preview__days-num--expired'
|
|
return ''
|
|
}
|
|
|
|
function getDisplayDays() {
|
|
if (cardInfo.isUsedUp) return cardInfo.remainingTimes || 0
|
|
return cardInfo.remainingDays || 0
|
|
}
|
|
|
|
function getDaysUnit() {
|
|
if (cardInfo.isUsedUp) return '次剩余'
|
|
return '天剩余'
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import '@/common/style/memberInfo/member-info-component-reset.css';
|
|
@import '@/common/style/memberInfo/member-info-member-card.css';
|
|
@import '@/common/style/memberInfo/member-info-tap.css';
|
|
</style>
|