diff --git a/src/mixins/sharing-page.js b/src/mixins/sharing-page.js index 703d7b3..6ce8561 100644 --- a/src/mixins/sharing-page.js +++ b/src/mixins/sharing-page.js @@ -6,10 +6,11 @@ import {renderSharingCover, renderSharingPoster, storeSharingCode, saveSharingPo export default function sharingPage(kind) { return { - data:{profile:{id:0,nickname:'',photo:'',details:'',introduction:'',idealMate:''},profileLoading:true,profileReady:false,profileError:'',canvasReady:false,poster:'',cover:'',generating:false,posterError:'',posterStage:'正在准备海报',cacheNote:'',cached:false,saving:false}, + data:{profile:{id:0,nickname:'',photo:'',details:'',introduction:'',idealMate:''},profileLoading:true,profileReady:false,profileError:'',canvasReady:false,poster:'',cover:'',generating:false,posterError:'',posterStage:'正在准备海报',posterProgress:0,cacheNote:'',cached:false,saving:false}, onReady(){this.canvasReady=true;this.ensurePoster()}, onUnload(){this._sharingDisposed=true;if(this._sharingJob)this._sharingJob.cancelled=true}, methods:{ + setPosterProgress(percent,stage){if(this._sharingDisposed)return;this.posterProgress=percent;this.posterStage=stage}, async startSharing(){ this._sharingDisposed=false const id=currentSharingUser() @@ -20,14 +21,16 @@ export default function sharingPage(kind) { } if(!this._sharingDisposed)await this.loadSharingProfile() }, - applySharingCache(cache){this.poster=cache.poster;this.cover=cache.cover;this.cached=true;this.posterError='';this.cacheNote='已缓存,下次打开可直接使用'}, + applySharingCache(cache){this.poster=cache.poster;this.cover=cache.cover;this.cached=true;this.posterError='';this.setPosterProgress(100,'海报已准备好');this.cacheNote='已缓存,下次打开可直接使用'}, async loadSharingProfile(force=false){ if(this._sharingDisposed)return this.profileLoading=true;this.profileError='' + this.posterError='';this.setPosterProgress(5,'正在读取个人资料') try{ const data=await sharingRequest(`${service.user}/sharing/profile`) if(this._sharingDisposed)return const profile=displayProfile(data) + this.setPosterProgress(15,kind==='personal'?'正在选择适合的生活照':'正在准备专属邀请') if(kind==='personal')profile.photo=await selectSharingPhoto(profile.photos) const cache=force?null:await readSharingCache(profile.id,kind,profile) if(this._sharingDisposed)return @@ -35,29 +38,32 @@ export default function sharingPage(kind) { if(cache)this.applySharingCache(cache) else{this.poster='';this.cover='';this.cached=false;this.cacheNote=''} this.profileLoading=false + if(!cache)this.setPosterProgress(25,'正在准备分享封面') await this.ensurePoster(force) }catch(error){if(!this._sharingDisposed)this.profileError=error.message||'资料加载失败,请重试'} finally{if(!this._sharingDisposed)this.profileLoading=false} }, async ensurePoster(force=false){ if(this._sharingDisposed||this.generating||!this.canvasReady||!this.profileReady||(!force&&this.poster))return - this.generating=true;this.posterError='';this.cacheNote='';this.posterStage='正在准备分享图片' + this.generating=true;this.posterError='';this.cacheNote='';this.setPosterProgress(25,'正在绘制分享封面') const job={cancelled:false};this._sharingJob=job const active=()=>{if(job.cancelled||this._sharingDisposed)throw new Error('已停止生成,请重试')} const profile={...this.profile} const generate=async()=>{ const cover=await renderSharingCover(this,profile,kind==='personal',job) - active();this.cover=cover;this.posterStage='正在生成专属海报' + active();this.cover=cover;this.setPosterProgress(45,'正在获取专属小程序码') const data=await sharingRequest(`${service.user}/sharing/code`,'POST',{kind}) - active();profile.qrcode=await storeSharingCode(data,kind,profile.id) - active();const poster=await renderSharingPoster(this,profile,kind==='personal',job) + active();this.setPosterProgress(65,'正在准备小程序码');profile.qrcode=await storeSharingCode(data,kind,profile.id) + active();this.setPosterProgress(75,'正在绘制高清海报');const poster=await renderSharingPoster(this,profile,kind==='personal',job) active();const assets={poster,cover,qrcode:profile.qrcode} + this.setPosterProgress(90,'正在保存到本地') try{const cache=await writeSharingCache(profile,kind,assets);active();return {...cache,cached:true}} catch(error){active();return {...assets,cached:false}} } try{ const result=await boundedCall((resolve,reject)=>{generate().then(resolve,reject);return()=>{job.cancelled=true}},'生成超时,请检查网络后重试',30000) active();this.poster=result.poster;this.cover=result.cover;this.cached=result.cached + this.setPosterProgress(100,'海报已准备好') this.cacheNote=result.cached?'已缓存,下次打开可直接使用':'海报已生成,暂未能缓存到本地' }catch(error){if(!this._sharingDisposed)this.posterError=error.message||'海报生成失败,请重试'} finally{job.cancelled=true;if(!this._sharingDisposed)this.generating=false} diff --git a/src/pages/users/assets/invitation-share-cover.png b/src/pages/users/assets/invitation-share-cover.png new file mode 100644 index 0000000..3cc75ba Binary files /dev/null and b/src/pages/users/assets/invitation-share-cover.png differ diff --git a/src/pages/users/assets/personal-share-cover.png b/src/pages/users/assets/personal-share-cover.png new file mode 100644 index 0000000..c7a71e2 Binary files /dev/null and b/src/pages/users/assets/personal-share-cover.png differ diff --git a/src/pages/users/myShare.wpy b/src/pages/users/myShare.wpy index 11d24af..8cd111b 100644 --- a/src/pages/users/myShare.wpy +++ b/src/pages/users/myShare.wpy @@ -7,13 +7,18 @@ 我的专属邀请 + + {{posterStage}}{{posterProgress}}% + + 首次生成需要下载图片,完成后会缓存到本地 + - 邀请你加入福恋上福恋认真找对象 + - 点击海报 · 查看大图 + {{poster ? '点击海报 · 查看大图' : '邀请封面预览 · 海报生成后可保存'}} {{profileLoading ? '正在准备你的邀请' : posterStage}} {{posterError || profileError}} {{cacheNote}} @@ -34,7 +39,7 @@ 邀请订单婚恋使者专属 · 暂未开放 邀请用户 - {{item.initial}}{{item.nickname || '福恋用户'}}{{item.verified ? '真人认证已通过' : '待完成真人认证'}} + {{item.initial}}{{item.nickname || '福恋用户'}}{{item.verified ? '真人认证已通过' : '待完成真人认证'}}› 第一份邀请,从你开始在“专属邀请”分享海报给朋友,邀请记录会展示在这里。 列表加载失败,请重试 正在加载邀请用户… @@ -58,8 +63,13 @@ wepy.page({ data:{activeTab:'poster',overviewReady:false,overviewError:false,total:0,verified:0,remaining:7,progressPercent:0,invitees:[],page:0,hasMore:true,listLoading:false,listError:false,canApply:false,checkingEligibility:false,eligibilityError:false,showApplication:false,savingContact:false,contactImage:'/pages/users/assets/ambassador-contact.jpg'}, onLoad(){this.startSharing();this.loadOverview();this.loadMore()}, onShow(){if(this.overviewReady)this.refreshEligibility()}, - onShareAppMessage(){return {title:'邀请你加入福恋,上福恋认真找对象',path:this.profile.id?sharingPath(this.profile.id,false):'/pages/tabBar/welcome',imageUrl:this.cover||'/pages/users/assets/fulian-logo.png'}}, + onShareAppMessage(){return {title:'邀请你加入福恋,上福恋认真找对象',path:this.profile.id?sharingPath(this.profile.id,false):'/pages/tabBar/welcome',imageUrl:this.cover||'/pages/users/assets/invitation-share-cover.png'}}, methods:{ + openInvitee(value){ + const id=Number(value) + if(!Number.isSafeInteger(id)||id<=0)return + wx.navigateTo({url:`/pages/home/information?id=${id}`,fail(){wx.showToast({title:'暂时无法打开用户详情,请重试',icon:'none'})}}) + }, showPosterTab(){this.activeTab='poster'}, showResultsTab(){this.activeTab='results'}, setOverview(data){this.total=Number(data.total)||0;this.verified=Number(data.verified)||0;this.remaining=Math.max(0,7-this.verified);this.progressPercent=Math.min(100,Math.max(0,this.verified/7*100));this.canApply=data.can_apply===true&&this.verified>=7;this.overviewReady=true}, diff --git a/src/pages/users/shareCard.wpy b/src/pages/users/shareCard.wpy index 46995d1..becd0dd 100644 --- a/src/pages/users/shareCard.wpy +++ b/src/pages/users/shareCard.wpy @@ -2,6 +2,11 @@