feat: 优化个人中心邀请卡片
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<view class="invite-entry">
|
||||
<view class="invite-heading" @tap="open">
|
||||
<view><text class="eyebrow">好友享 95 折 · 一起变好</text><text class="entry-title">邀请好友领课时 <text>↗</text></text></view>
|
||||
<view class="gift"><text class="gift-number">1</text><text>节免费课</text></view>
|
||||
</view>
|
||||
<view class="code-line" @tap="copy"><text>{{ invite.code ? '我的邀请码' : '登录领取专属邀请码' }}</text><text class="code">{{ invite.code }}</text><text v-if="invite.code">复制</text></view>
|
||||
<button class="invite-heading" :disabled="opening" @tap="open" aria-label="邀请好友,查看邀请码与邀请权益">
|
||||
<view class="entry-copy">
|
||||
<text class="entry-title">邀请好友领课时</text>
|
||||
<text class="entry-caption">好友享 95 折 · {{ user.loggedIn && invite.activity ? `已获 ${invite.activity.rewardedTimes} 节赠课` : '一起练,得赠课' }}</text>
|
||||
</view>
|
||||
<view class="invite-count">
|
||||
<text class="count-number">{{ user.loggedIn && invite.activity ? invite.activity.referrals.length : '—' }}<text v-if="user.loggedIn"> 人</text></text>
|
||||
<text class="count-label">{{ user.loggedIn ? '已邀请' : '登录查看' }}</text>
|
||||
</view>
|
||||
<text class="entry-arrow">›</text>
|
||||
</button>
|
||||
<view v-if="visible" class="veil" @tap="visible = false" @touchmove.stop.prevent>
|
||||
<view class="sheet" @tap.stop>
|
||||
<button class="close" @tap="visible = false" aria-label="关闭">×</button>
|
||||
@@ -29,12 +35,16 @@ import { getErrorMessage } from '../utils/auth'
|
||||
const invite = useInviteStore()
|
||||
const user = useUserStore()
|
||||
const visible = ref(false)
|
||||
const opening = ref(false)
|
||||
async function open() {
|
||||
if (opening.value) return
|
||||
opening.value = true
|
||||
try {
|
||||
if (!user.loggedIn) await user.login()
|
||||
await invite.refresh()
|
||||
await Promise.all([invite.refresh(), invite.refreshActivity().catch(() => {})])
|
||||
visible.value = true
|
||||
} catch (err) { uni.showToast({ title: getErrorMessage(err, '暂时无法获取邀请码,请重试'), icon: 'none' }) }
|
||||
finally { opening.value = false }
|
||||
}
|
||||
function copy() {
|
||||
if (!invite.code) { open(); return }
|
||||
@@ -42,12 +52,16 @@ function copy() {
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.invite-entry { margin: 24rpx 32rpx; padding: 28rpx; background: #eaf0e7; border: 1rpx solid #d9e3d4; border-radius: 26rpx; color: #435b4c; }
|
||||
.invite-heading { display: flex; justify-content: space-between; align-items: center; }
|
||||
.invite-entry { margin: 16rpx 32rpx; padding: 0; background: #eaf0e7; border: 1rpx solid #d9e3d4; border-radius: 20rpx; color: #435b4c; }
|
||||
.invite-heading { width: 100%; min-height: 120rpx; box-sizing: border-box; margin: 0; padding: 18rpx 24rpx; background: transparent; border-radius: 20rpx; color: inherit; display: flex; gap: 20rpx; text-align: left; align-items: center; line-height: 1.5; &::after { border: none; } &:active { background: #e2eadf; } }
|
||||
.entry-copy { flex: 1; min-width: 0; }
|
||||
.entry-title { display: block; font-size: 28rpx; font-weight: 500; }
|
||||
.entry-caption { display: block; margin-top: 6rpx; font-size: 21rpx; color: #6b7d65; }
|
||||
.invite-count { flex-shrink: 0; text-align: right; }
|
||||
.count-number { display: block; font-family: Georgia, serif; font-size: 34rpx; line-height: 1.2; font-variant-numeric: tabular-nums; text { font-size: 20rpx; } }
|
||||
.count-label { display: block; margin-top: 5rpx; font-size: 19rpx; color: #6b7d65; }
|
||||
.entry-arrow { flex-shrink: 0; font-size: 30rpx; color: #87967f; }
|
||||
.eyebrow { display: block; font-size: 19rpx; letter-spacing: 3rpx; color: #788976; }
|
||||
.entry-title { display: block; font-size: 29rpx; margin-top: 12rpx; font-weight: 500; }
|
||||
.gift { display: flex; flex-direction: column; align-items: center; font-size: 18rpx; }.gift-number { font-family: Georgia, serif; font-size: 56rpx; line-height: 1; }
|
||||
.code-line { display: flex; align-items: center; gap: 18rpx; border-top: 1rpx solid #d2dece; padding-top: 20rpx; margin-top: 22rpx; font-size: 21rpx; }.code { flex: 1; letter-spacing: 4rpx; font-family: monospace; font-size: 27rpx; }
|
||||
.veil { position: fixed; inset: 0; z-index: 400; background: rgba(32,43,35,.48); display: flex; align-items: center; padding: 30rpx; }
|
||||
.sheet { position: relative; width: 100%; max-height: 85vh; overflow-y: auto; box-sizing: border-box; padding: 48rpx 34rpx 32rpx; border-radius: 32rpx; background: #fcfaf5; }.close { position: absolute; right: 18rpx; top: 12rpx; margin: 0; background: transparent; color: #7b8477; font-size: 36rpx; }.close::after,.share::after { border: none; }
|
||||
.headline { display: block; margin-top: 20rpx; font-family: 'Songti SC',serif; font-size: 46rpx; }.subtitle { display: block; margin-top: 12rpx; font-size: 23rpx; color: #87907f; }
|
||||
|
||||
Reference in New Issue
Block a user