@@ -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 >
< 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 = "code-line" @tap ="copy" > < text > { { invite . code ? '我的邀请码' : '登录领取专属邀请码' } } < / text > < text class = "code" > { { invite . code } } < / text > < text v-if = "invite.code" > 复制 < / 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 : 24 rpx 32 rpx ; padding : 28 rpx ; background : # eaf0e7 ; border : 1 rpx solid # d9e3d4 ; border - radius : 26 rpx ; color : # 435 b4c ; }
. invite - heading { display : flex ; justify - content : space - between ; align - items : center ; }
. invite - entry { margin : 16 rpx 32 rpx ; padding : 0 ; background : # eaf0e7 ; border : 1 rpx solid # d9e3d4 ; border - radius : 20 rpx ; color : # 435 b4c ; }
. invite - heading { width : 100 % ; min - height : 120 rpx ; box - sizing : border - box ; margin : 0 ; padding : 18 rpx 24 rpx ; background : transparent ; border - radius : 20 rpx ; color : inherit ; display : flex ; gap : 20 rpx ; 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 : 28 rpx ; font - weight : 500 ; }
. entry - caption { display : block ; margin - top : 6 rpx ; font - size : 21 rpx ; color : # 6 b7d65 ; }
. invite - count { flex - shrink : 0 ; text - align : right ; }
. count - number { display : block ; font - family : Georgia , serif ; font - size : 34 rpx ; line - height : 1.2 ; font - variant - numeric : tabular - nums ; text { font - size : 20 rpx ; } }
. count - label { display : block ; margin - top : 5 rpx ; font - size : 19 rpx ; color : # 6 b7d65 ; }
. entry - arrow { flex - shrink : 0 ; font - size : 30 rpx ; color : # 87967 f ; }
. eyebrow { display : block ; font - size : 19 rpx ; letter - spacing : 3 rpx ; color : # 788976 ; }
. entry - title { display : block ; font - size : 29 rpx ; margin - top : 12 rpx ; font - weight : 500 ; }
. gift { display : flex ; flex - direction : column ; align - items : center ; font - size : 18 rpx ; } . gift - number { font - family : Georgia , serif ; font - size : 56 rpx ; line - height : 1 ; }
. code - line { display : flex ; align - items : center ; gap : 18 rpx ; border - top : 1 rpx solid # d2dece ; padding - top : 20 rpx ; margin - top : 22 rpx ; font - size : 21 rpx ; } . code { flex : 1 ; letter - spacing : 4 rpx ; font - family : monospace ; font - size : 27 rpx ; }
. veil { position : fixed ; inset : 0 ; z - index : 400 ; background : rgba ( 32 , 43 , 35 , .48 ) ; display : flex ; align - items : center ; padding : 30 rpx ; }
. sheet { position : relative ; width : 100 % ; max - height : 85 vh ; overflow - y : auto ; box - sizing : border - box ; padding : 48 rpx 34 rpx 32 rpx ; border - radius : 32 rpx ; background : # fcfaf5 ; } . close { position : absolute ; right : 18 rpx ; top : 12 rpx ; margin : 0 ; background : transparent ; color : # 7 b8477 ; font - size : 36 rpx ; } . close : : after , . share : : after { border : none ; }
. headline { display : block ; margin - top : 20 rpx ; font - family : 'Songti SC' , serif ; font - size : 46 rpx ; } . subtitle { display : block ; margin - top : 12 rpx ; font - size : 23 rpx ; color : # 87907 f ; }