Files
gym-manage/gym-manage-uniapp/pages/memberInfo/memberCard.vue
T

208 lines
7.8 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="scroll-container theme-light">
<view class="member-card-page">
<MemberInfoSubNav title="我的会员卡" @back="goBack" />
<view class="member-card-page__body">
<view class="mc-hero">
<view class="mc-hero__top">
<view class="mc-hero__title-row">
<image
class="mc-hero__crown"
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/crown.png"
mode="aspectFit"
/>
<text class="mc-hero__name">{{ card.name }}</text>
</view>
<view class="mc-hero__badge">
<text class="mc-hero__badge-text">{{ card.status }}</text>
</view>
</view>
<text class="mc-hero__validity">有效期{{ card.validity }}</text>
<view class="mc-hero__bottom">
<view class="mc-hero__days">
<text class="mc-hero__days-num">{{ remainingDays }}</text>
<text class="mc-hero__days-unit"></text>
</view>
<view
class="mc-hero__renew"
hover-class="mi-tap-btn--hover"
:hover-stay-time="150"
@tap="renewCard"
>
<image
class="mc-hero__renew-icon"
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/refreshcw.png"
mode="aspectFit"
/>
<text class="mc-hero__renew-text">立即续费</text>
</view>
</view>
</view>
<view class="mc-records">
<view class="mc-records__header">
<text class="mc-records__title">使用记录</text>
<view class="mc-records__tabs">
<view
v-for="tab in recordTabs"
:key="tab.key"
class="mc-records__tab"
:class="{ 'mc-records__tab--active': activeFilter === tab.key }"
hover-class="mi-tap-tab--hover"
:hover-stay-time="150"
@tap="switchFilter(tab.key)"
>
<text
class="mc-records__tab-text"
:class="{ 'mc-records__tab-text--active': activeFilter === tab.key }"
>
{{ tab.label }}
</text>
</view>
</view>
</view>
<view class="mc-records__divider"></view>
<view
v-for="(item, index) in filteredRecords"
:key="item.id"
class="mc-records__item"
>
<view v-if="index > 0" class="mc-records__divider"></view>
<view
class="mc-records__item-inner"
hover-class="mi-tap-row--hover"
:hover-stay-time="150"
@tap="showRecordDetail(item)"
>
<view
class="mc-records__icon-wrap"
:class="'mc-records__icon-wrap--' + item.iconTheme"
>
<image
class="mc-records__icon"
:src="item.icon"
mode="aspectFit"
/>
</view>
<view class="mc-records__info">
<text class="mc-records__item-title">{{ item.title }}</text>
<text class="mc-records__item-time">{{ item.time }}</text>
</view>
<text
class="mc-records__value"
:class="'mc-records__value--' + item.valueType"
>
{{ item.value }}
</text>
</view>
</view>
<view v-if="!filteredRecords.length" class="mc-records__empty">
<text class="mc-records__empty-text">暂无记录</text>
</view>
</view>
<view class="mc-rules">
<text class="mc-rules__title">使用规则</text>
<view
v-for="(rule, index) in rules"
:key="index"
class="mc-rules__item"
>
<view class="mc-rules__bullet"></view>
<text class="mc-rules__text">{{ rule }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
import {
loadMemberStore,
computeRemainingDays,
renewMemberCard
} from '@/common/memberInfo/store.js'
import { backToMemberCenter } from '@/common/constants/routes.js'
const card = ref({})
const recordTabs = ref([])
const records = ref([])
const rules = ref([])
const activeFilter = ref('all')
const filteredRecords = computed(() => {
if (activeFilter.value === 'all') {
return records.value
}
return records.value.filter((item) => item.type === activeFilter.value)
})
const remainingDays = computed(() => {
return computeRemainingDays(card.value.validityEnd)
})
function refreshFromStore() {
const store = loadMemberStore()
card.value = { ...store.card }
records.value = store.records.map((item) => ({ ...item }))
}
function goBack() {
backToMemberCenter()
}
function switchFilter(filter) {
activeFilter.value = filter
}
function renewCard() {
uni.showModal({
title: '续费会员卡',
content: '确认续费 90 天?',
success: (res) => {
if (!res.confirm) return
const store = loadMemberStore()
renewMemberCard(store, 90)
activeFilter.value = 'all'
refreshFromStore()
uni.showToast({ title: '续费成功', icon: 'success' })
}
})
}
function showRecordDetail(item) {
uni.showModal({
title: item.title,
content: `${item.time}\n变动:${item.value}`,
showCancel: false
})
}
refreshFromStore()
</script>
<style lang="scss">
@import '@/common/style/base.css';
@import '@/common/style/memberInfo/pages/page-reset.css';
@import '@/common/style/memberInfo/pages/sub-page-base.css';
@import '@/common/style/memberInfo/member-info-component-reset.css';
@import '@/common/style/memberInfo/member-info-sub-nav.css';
@import '@/common/style/memberInfo/member-info-tap.css';
@import '@/common/style/memberInfo/pages/member-card-page.css';
.mc-records__empty {
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px;
}
.mc-records__empty-text {
font-size: 14px;
color: #8A99B4;
}
</style>