Files
gym-manage/gym-manage-uniapp/components/memberInfo/MemberInfoMemberCard.vue
T
2026-06-28 14:49:21 +08:00

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>