完成一键登录和支付功能
This commit is contained in:
@@ -89,6 +89,48 @@
|
||||
|
||||
<view class="member-page__body">
|
||||
<view class="member-page__sections">
|
||||
<!-- 快过期会员卡提醒 -->
|
||||
<view class="expiring-cards-section" v-if="expiringCards.length > 0">
|
||||
<view class="expiring-cards__inner">
|
||||
<view class="expiring-cards__header">
|
||||
<view class="expiring-cards__header-inner">
|
||||
<view class="expiring-cards__title-row">
|
||||
<image class="expiring-cards__warn-icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock1.png" mode="aspectFit" />
|
||||
<text class="expiring-cards__title">会员卡即将到期</text>
|
||||
</view>
|
||||
<view class="expiring-cards__link" hover-class="mi-tap--hover" :hover-stay-time="150" @tap="goMemberCard">
|
||||
<text class="expiring-cards__link-text">查看全部</text>
|
||||
<image class="expiring-cards__link-arrow" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright12.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="expiring-cards__list">
|
||||
<view
|
||||
v-for="(card, index) in expiringCards"
|
||||
:key="card.id || index"
|
||||
class="expiring-card-item"
|
||||
hover-class="mi-tap-row--hover"
|
||||
:hover-stay-time="150"
|
||||
@tap="goMemberCard"
|
||||
>
|
||||
<view class="expiring-card-item__inner">
|
||||
<view class="expiring-card-item__icon-wrap">
|
||||
<image class="expiring-card-item__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/ticket.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="expiring-card-item__info">
|
||||
<text class="expiring-card-item__name">{{ card.name }}</text>
|
||||
<text class="expiring-card-item__validity">{{ card.validity }}</text>
|
||||
</view>
|
||||
<view class="expiring-card-item__days">
|
||||
<text class="expiring-card-item__days-num">{{ computeRemainingDays(card.validityEnd) }}</text>
|
||||
<text class="expiring-card-item__days-unit">天后到期</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 会员卡区域 -->
|
||||
<view class="member-card-section">
|
||||
<view class="member-card-section__inner">
|
||||
@@ -470,14 +512,18 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { PAGE, navigateToPage } from '@/common/constants/routes.js'
|
||||
import { loadMemberStore, getCenterPageData, renewMemberCard } from '@/common/memberInfo/store.js'
|
||||
import { getCenterPageData, renewMemberCard, computeRemainingDays, saveMemberStore } from '@/common/memberInfo/store.js'
|
||||
import { getMemberId } from '@/utils/request.js'
|
||||
import { getMyMemberCards } from '@/api/main.js'
|
||||
import TabBar from '@/components/TabBar.vue'
|
||||
|
||||
// 页面数据
|
||||
const userInfo = ref({})
|
||||
const stats = ref({})
|
||||
const cardInfo = ref({})
|
||||
const expiringCards = ref([])
|
||||
const bookingPreview = ref([])
|
||||
const checkIns = ref([])
|
||||
const bodyReport = ref({})
|
||||
@@ -579,6 +625,7 @@ function refreshFromStore() {
|
||||
userInfo.value = pageData.userInfo
|
||||
stats.value = pageData.stats
|
||||
cardInfo.value = pageData.cardInfo
|
||||
expiringCards.value = pageData.expiringCards || []
|
||||
bookingPreview.value = pageData.bookingPreview
|
||||
checkIns.value = pageData.checkIns
|
||||
bodyReport.value = pageData.bodyReport
|
||||
@@ -586,6 +633,64 @@ function refreshFromStore() {
|
||||
referral.value = pageData.referral
|
||||
}
|
||||
|
||||
async function refreshCardsFromServer() {
|
||||
const memberId = getMemberId()
|
||||
if (!memberId) return
|
||||
|
||||
try {
|
||||
const res = await getMyMemberCards(memberId)
|
||||
let cards = []
|
||||
if (Array.isArray(res)) {
|
||||
cards = res
|
||||
} else if (res.code === 200 && res.data) {
|
||||
cards = res.data
|
||||
} else if (Array.isArray(res.data)) {
|
||||
cards = res.data
|
||||
}
|
||||
|
||||
if (cards.length > 0) {
|
||||
const allCards = cards.map(myCard => {
|
||||
const cardName = myCard.memberCardName || myCard.cardName || myCard.name || `会员卡#${myCard.memberCardId || myCard.id}`
|
||||
const validityEnd = myCard.validityEnd || myCard.expireTime
|
||||
const validityStart = myCard.validityStart || myCard.purchaseTime || myCard.createdAt
|
||||
return {
|
||||
id: myCard.id,
|
||||
name: cardName,
|
||||
status: myCard.status || 'active',
|
||||
validity: validityEnd ? `有效期至 ${validityEnd}` : '永久有效',
|
||||
validityEnd: validityEnd,
|
||||
validityStart: validityStart
|
||||
}
|
||||
})
|
||||
|
||||
store.cards = allCards
|
||||
|
||||
const myCard = cards[0]
|
||||
const cardName = myCard.memberCardName || myCard.cardName || myCard.name || `会员卡#${myCard.memberCardId || myCard.id}`
|
||||
const validityEnd = myCard.validityEnd || myCard.expireTime
|
||||
const validityStart = myCard.validityStart || myCard.purchaseTime || myCard.createdAt
|
||||
|
||||
store.card = {
|
||||
id: myCard.id,
|
||||
name: cardName,
|
||||
status: myCard.status || 'active',
|
||||
validity: validityEnd ? `有效期至 ${validityEnd}` : '永久有效',
|
||||
validityEnd: validityEnd,
|
||||
validityStart: validityStart
|
||||
}
|
||||
store.cardInfo = {
|
||||
expireDate: validityEnd ? `有效期至 ${validityEnd}` : '永久有效',
|
||||
remainingDays: computeRemainingDays(validityEnd)
|
||||
}
|
||||
|
||||
saveMemberStore(store)
|
||||
refreshFromStore()
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[MemberCenter] 刷新会员卡数据失败:', e)
|
||||
}
|
||||
}
|
||||
|
||||
function goUserInfo() {
|
||||
navigateToPage(PAGE.USER_INFO)
|
||||
}
|
||||
@@ -717,6 +822,10 @@ onMounted(() => {
|
||||
syncNavSafeArea()
|
||||
refreshFromStore()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
refreshCardsFromServer()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -755,4 +864,126 @@ onMounted(() => {
|
||||
font-size: 14px;
|
||||
color: #8A99B4;
|
||||
}
|
||||
|
||||
.expiring-cards-section {
|
||||
margin: 0 16px 12px;
|
||||
background: linear-gradient(135deg, #FFF7E6 0%, #FFE4CC 100%);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.expiring-cards__inner {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.expiring-cards__header {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.expiring-cards__header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.expiring-cards__title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.expiring-cards__warn-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.expiring-cards__title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #D46B08;
|
||||
}
|
||||
|
||||
.expiring-cards__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.expiring-cards__link-text {
|
||||
font-size: 13px;
|
||||
color: #D46B08;
|
||||
}
|
||||
|
||||
.expiring-cards__link-arrow {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.expiring-cards__list {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-radius: 12px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.expiring-card-item {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.expiring-card-item__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.expiring-card-item__icon-wrap {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.expiring-card-item__icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.expiring-card-item__info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.expiring-card-item__name {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1A202C;
|
||||
}
|
||||
|
||||
.expiring-card-item__validity {
|
||||
font-size: 12px;
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
.expiring-card-item__days {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.expiring-card-item__days-num {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #E74C3C;
|
||||
}
|
||||
|
||||
.expiring-card-item__days-unit {
|
||||
font-size: 11px;
|
||||
color: #E74C3C;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user