155 lines
3.6 KiB
Vue
155 lines
3.6 KiB
Vue
<template>
|
||
<!-- 会员卡片:等级徽标 + 期限丝带叠加绑定,整体放大 -->
|
||
<view class="vip-card">
|
||
<view class="vip-card-inner">
|
||
<view class="vip-badge-combo">
|
||
<image
|
||
v-if="levelBadge"
|
||
class="vip-level"
|
||
:src="levelBadge"
|
||
mode="aspectFit"
|
||
/>
|
||
<image
|
||
v-if="durationBadge"
|
||
class="vip-ribbon"
|
||
:src="durationBadge"
|
||
mode="aspectFit"
|
||
/>
|
||
<view v-if="!durationBadge && !levelBadge" class="vip-badge-placeholder">
|
||
<text class="vip-badge-placeholder-text">V</text>
|
||
</view>
|
||
</view>
|
||
<view class="vip-info">
|
||
<text class="vip-title">{{ levelName }}</text>
|
||
<text class="vip-sub">{{ durationLabel }} · {{ levelCode }}</text>
|
||
<text class="vip-expire">{{ expireText }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
/**
|
||
* 诊所管理员「我的」页会员卡片
|
||
* 期限图为透明丝带,叠在等级徽标上绑定展示
|
||
*/
|
||
export default {
|
||
name: 'VipMemberCard',
|
||
props: {
|
||
vip: {
|
||
type: Object,
|
||
default: null,
|
||
},
|
||
},
|
||
computed: {
|
||
durationBadge() {
|
||
return (this.vip && this.vip.duration_badge_url) || ''
|
||
},
|
||
levelBadge() {
|
||
return (this.vip && this.vip.badge_url) || ''
|
||
},
|
||
durationLabel() {
|
||
return (this.vip && this.vip.duration_label) || '普通会员'
|
||
},
|
||
levelName() {
|
||
return (this.vip && this.vip.level_name) || '普通会员'
|
||
},
|
||
levelCode() {
|
||
return (this.vip && this.vip.level_code) || 'V0'
|
||
},
|
||
expireText() {
|
||
if (!this.vip) return '默认会员'
|
||
if (this.vip.is_lifetime) return '永久有效'
|
||
const expireAt = Number(this.vip.expire_at || 0)
|
||
if (!expireAt) {
|
||
if (this.levelCode === 'V0') return '默认会员'
|
||
return '永久有效'
|
||
}
|
||
if (typeof this.vip.expire_at === 'string' && this.vip.expire_at.indexOf('-') > -1) {
|
||
return '有效期至 ' + this.vip.expire_at
|
||
}
|
||
const d = new Date(expireAt * 1000)
|
||
const y = d.getFullYear()
|
||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||
const day = String(d.getDate()).padStart(2, '0')
|
||
return '有效期至 ' + y + '-' + m + '-' + day
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.vip-card {
|
||
margin: 0 24rpx 24rpx;
|
||
}
|
||
.vip-card-inner {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 36rpx 32rpx;
|
||
border-radius: 20rpx;
|
||
background: linear-gradient(135deg, #2c3e50 0%, #4a6741 55%, #6acdbb 100%);
|
||
box-shadow: 0 8rpx 24rpx rgba(44, 62, 80, 0.18);
|
||
}
|
||
/* 组合徽标容器:等级在下,丝带叠在中下部 */
|
||
.vip-badge-combo {
|
||
position: relative;
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
flex-shrink: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.vip-level {
|
||
width: 140rpx;
|
||
height: 140rpx;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
.vip-ribbon {
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: 10rpx;
|
||
transform: translateX(-50%);
|
||
width: 200rpx;
|
||
height: 72rpx;
|
||
z-index: 2;
|
||
}
|
||
.vip-badge-placeholder {
|
||
width: 140rpx;
|
||
height: 140rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.vip-badge-placeholder-text {
|
||
color: #fff;
|
||
font-size: 52rpx;
|
||
font-weight: 700;
|
||
}
|
||
.vip-info {
|
||
margin-left: 24rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-width: 0;
|
||
flex: 1;
|
||
}
|
||
.vip-title {
|
||
color: #ffffff;
|
||
font-size: 34rpx;
|
||
font-weight: 700;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.vip-sub {
|
||
color: rgba(255, 255, 255, 0.88);
|
||
font-size: 24rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.vip-expire {
|
||
color: rgba(255, 255, 255, 0.75);
|
||
font-size: 22rpx;
|
||
}
|
||
</style>
|