211 lines
8.1 KiB
Vue
211 lines
8.1 KiB
Vue
<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="/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="/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>
|
||
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
|
||
import { memberCardMock } from '@/common/memberInfo/mockData.js'
|
||
import {
|
||
loadMemberStore,
|
||
computeRemainingDays,
|
||
renewMemberCard
|
||
} from '@/common/memberInfo/store.js'
|
||
import { subPageMixin } from '@/common/memberInfo/mixins.js'
|
||
|
||
export default {
|
||
components: { MemberInfoSubNav },
|
||
mixins: [subPageMixin],
|
||
data() {
|
||
return {
|
||
card: {},
|
||
recordTabs: memberCardMock.recordTabs,
|
||
records: [],
|
||
rules: memberCardMock.rules,
|
||
activeFilter: 'all'
|
||
}
|
||
},
|
||
computed: {
|
||
filteredRecords() {
|
||
if (this.activeFilter === 'all') {
|
||
return this.records
|
||
}
|
||
return this.records.filter((item) => item.type === this.activeFilter)
|
||
},
|
||
remainingDays() {
|
||
return computeRemainingDays(this.card.validityEnd)
|
||
}
|
||
},
|
||
onShow() {
|
||
this.refreshFromStore()
|
||
},
|
||
methods: {
|
||
refreshFromStore() {
|
||
const store = loadMemberStore()
|
||
this.card = { ...store.card }
|
||
this.records = store.records.map((item) => ({ ...item }))
|
||
},
|
||
switchFilter(filter) {
|
||
this.activeFilter = filter
|
||
},
|
||
renewCard() {
|
||
uni.showModal({
|
||
title: '续费会员卡',
|
||
content: '确认续费 90 天?',
|
||
success: (res) => {
|
||
if (!res.confirm) return
|
||
const store = loadMemberStore()
|
||
renewMemberCard(store, 90)
|
||
this.activeFilter = 'all'
|
||
this.refreshFromStore()
|
||
uni.showToast({ title: '续费成功', icon: 'success' })
|
||
}
|
||
})
|
||
},
|
||
showRecordDetail(item) {
|
||
uni.showModal({
|
||
title: item.title,
|
||
content: `${item.time}\n变动:${item.value}`,
|
||
showCancel: false
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
@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>
|