Guide friend tasks and default membership carousel to quarterly plan
This commit is contained in:
parent
2135ca78e2
commit
48793491c3
@ -758,7 +758,7 @@ page {
|
|||||||
<image class="u_apply_img" mode="widthFix" src="https://images.ufutx.com/202105/31/37e0eda3fe1fcc0af2cb3ca2a51d2291.png"></image>
|
<image class="u_apply_img" mode="widthFix" src="https://images.ufutx.com/202105/31/37e0eda3fe1fcc0af2cb3ca2a51d2291.png"></image>
|
||||||
<view class="font_34 color333 bold">打个招呼吧</view>
|
<view class="font_34 color333 bold">打个招呼吧</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="font_28 color666 ui-pt-16" v-if="!friendEligibility.unlimited">完善资料并完成真人认证和学历认证后,每天可免费加好友3次</view>
|
<view class="font_28 color666 ui-pt-16" v-if="!friendEligibility.unlimited">真人认证、真人头像审核通过、完善资料、学历认证,每完成一项每天可免费加好友1次,最多4次</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-left ff ui-pt-30 ui-pl-36 ui-pr-36">
|
<view class="text-left ff ui-pt-30 ui-pl-36 ui-pr-36">
|
||||||
<textarea type="text" disabled show-confirm-bar="{{false}}" placeholder="输入打招呼内容" class="inputStyle" v-model="message" @input="typing" maxlength="60"/>
|
<textarea type="text" disabled show-confirm-bar="{{false}}" placeholder="输入打招呼内容" class="inputStyle" v-model="message" @input="typing" maxlength="60"/>
|
||||||
@ -771,7 +771,7 @@ page {
|
|||||||
<view class="u_apply_can f-fcc font_32 color999" @tap="modalName = ''">取消</view>
|
<view class="u_apply_can f-fcc font_32 color999" @tap="modalName = ''">取消</view>
|
||||||
<view class="font_30 u_apply_btn white f-fcc" @tap="sendMsg">发送</view>
|
<view class="font_30 u_apply_btn white f-fcc" @tap="sendMsg">发送</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="font_28 color999 text-center ui-pt-40" v-if="!friendEligibility.unlimited">今日还剩{{friendEligibility.remaining}}次,<text class="color-theme" @tap="jumpPath('vip')">成为会员</text>将不限制打招呼</view>
|
<view class="font_28 color999 text-center ui-pt-40" v-if="!friendEligibility.unlimited">已获得每天{{friendEligibility.daily_limit}}次免费机会,今日还剩{{friendEligibility.remaining}}次</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -827,7 +827,7 @@ wepy.page({
|
|||||||
modalName: '', // 弹框
|
modalName: '', // 弹框
|
||||||
pairedScore: 0,
|
pairedScore: 0,
|
||||||
userData: {}, // 自己的数据信息
|
userData: {}, // 自己的数据信息
|
||||||
friendEligibility: {unlimited: false, remaining: 0},
|
friendEligibility: {unlimited: false, remaining: 0, daily_limit: 0},
|
||||||
checkingFriendEligibility: false,
|
checkingFriendEligibility: false,
|
||||||
userInfo: {}, // 当前用户详情数据
|
userInfo: {}, // 当前用户详情数据
|
||||||
profile_courtship: {},
|
profile_courtship: {},
|
||||||
@ -1256,7 +1256,7 @@ wepy.page({
|
|||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
vm.modalName = ''
|
vm.modalName = ''
|
||||||
vm.$showToast('消息已发送')
|
vm.$showToast('消息已发送')
|
||||||
// Refresh authoritative quota; the third successful request opens membership checkout.
|
// Refresh quota; guide unfinished tasks before offering membership.
|
||||||
vm.ensureFriendEligibility()
|
vm.ensureFriendEligibility()
|
||||||
}
|
}
|
||||||
vm.throttle = true
|
vm.throttle = true
|
||||||
@ -1282,7 +1282,7 @@ wepy.page({
|
|||||||
// 联系朋友
|
// 联系朋友
|
||||||
async contactFriendFn() {
|
async contactFriendFn() {
|
||||||
let vm = this
|
let vm = this
|
||||||
// 登录后由服务端依次检查完整资料、认证及剩余次数。
|
// 登录后由服务端计算四项任务奖励及当日剩余次数。
|
||||||
if (!wx.getStorageSync('token')) {
|
if (!wx.getStorageSync('token')) {
|
||||||
vm.loginShow = true
|
vm.loginShow = true
|
||||||
return
|
return
|
||||||
@ -1297,30 +1297,36 @@ wepy.page({
|
|||||||
const {code, data} = await this.$get({url: `${service.host}/friend/request/eligibility`})
|
const {code, data} = await this.$get({url: `${service.host}/friend/request/eligibility`})
|
||||||
if (code !== 0 || !data) return false
|
if (code !== 0 || !data) return false
|
||||||
this.friendEligibility = data
|
this.friendEligibility = data
|
||||||
if (data.action === 'profile') {
|
if (data.allowed === true) return true
|
||||||
this.modalName = ''
|
this.modalName = ''
|
||||||
|
const tasks = {
|
||||||
|
real: {name: '真人认证', url: '/pages/users/realName'},
|
||||||
|
photo: {name: '上传真人头像并通过审核', url: '/pages/users/unmarriV2?progressShow=false'},
|
||||||
|
profile: {name: '完善资料', url: '/pages/users/unmarriV2?progressShow=false'},
|
||||||
|
education: {name: '学历认证', url: '/pages/users/degreeCertificate'}
|
||||||
|
}
|
||||||
|
const required = (data.required || []).filter(key => tasks[key])
|
||||||
|
if (required.length) {
|
||||||
wx.showModal({
|
wx.showModal({
|
||||||
title: '请先完善个人资料',
|
title: '领取更多免费机会',
|
||||||
content: '完善个人资料后,再完成真人认证和学历认证,即可获得每天3次免费加好友机会。',
|
content: '当前免费次数已用完。尚未完成:' + required.map(key => tasks[key].name).join('、') + '。每完成一项,每天增加1次免费加好友机会,最多4次/天。',
|
||||||
confirmText: '去完善',
|
confirmText: '去完成',
|
||||||
success: res => { if (res.confirm) wx.navigateTo({url: '/pages/users/unmarriV2?progressShow=false'}) }
|
success: res => {
|
||||||
|
if (!res.confirm) return
|
||||||
|
wx.showActionSheet({
|
||||||
|
itemList: required.map(key => tasks[key].name),
|
||||||
|
success: choice => { const task = tasks[required[choice.tapIndex]]; if (task) wx.navigateTo({url: task.url}) }
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (data.action === 'purchase') {
|
if (data.action === 'purchase') {
|
||||||
this.modalName = ''
|
|
||||||
wx.navigateTo({url: '/pages/users/upgradeVIP'})
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (data.action === 'verify') {
|
|
||||||
this.modalName = ''
|
|
||||||
const required = data.required || []
|
|
||||||
const real = required.indexOf('real') !== -1
|
|
||||||
wx.showModal({
|
wx.showModal({
|
||||||
title: '完成认证领取免费机会',
|
title: '今日免费次数已用完',
|
||||||
content: real ? (required.indexOf('education') !== -1 ? '完成真人认证和学历认证后,每天可免费加好友3次。请先完成真人认证。' : '完成真人认证后,每天可免费加好友3次。') : '完成学历认证后,每天可免费加好友3次。',
|
content: '四项任务已全部完成,今天的4次免费机会已用完。升级会员可无限次加好友。',
|
||||||
confirmText: real ? '真人认证' : '学历认证',
|
confirmText: '升级会员',
|
||||||
success: res => { if (res.confirm) wx.navigateTo({url: real ? '/pages/users/realName' : '/pages/users/degreeCertificate'}) }
|
success: res => { if (res.confirm) wx.navigateTo({url: '/pages/users/upgradeVIP'}) }
|
||||||
})
|
})
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,14 +23,17 @@
|
|||||||
<view class="font_24 white flo_l" style="color: #f7e4ad;width: 70%; ">
|
<view class="font_24 white flo_l" style="color: #f7e4ad;width: 70%; ">
|
||||||
{{ user.deadline_str ? user.deadline_str + ' 到期' : '未激活' }}
|
{{ user.deadline_str ? user.deadline_str + ' 到期' : '未激活' }}
|
||||||
</view>
|
</view>
|
||||||
<swiper class="card-swiper" circular="true" @change="cardSwiper">
|
<view class="plan-heading">选择适合你的会员</view>
|
||||||
<swiper-item v-for="(item,index) in rankList" :key="index" class="{{cardCur==index?'cur':''}}"
|
<view class="plan-hint">左右滑动或点击卡片,比较套餐价格</view>
|
||||||
@tap="showFn(index)">
|
<view class="membership-carousel" @touchstart="planTouchStart" @touchend="planTouchEnd">
|
||||||
<view class="swiper-item radius shadow " style="border-radius: 0">
|
<view v-for="(item,index) in rankList" :key="item.id" class="membership-plan {{item.position}}" @tap="selectPlan(index)">
|
||||||
<image :src="item.pic" mode="aspectFit"></image>
|
<view class="plan-badge">{{cardCur == index ? '✓ 已选套餐' : '点击选择'}}</view>
|
||||||
|
<image class="plan-picture" v-if="item.pic" :src="item.pic" mode="aspectFit"></image>
|
||||||
|
<view class="plan-name">{{item.name}}</view>
|
||||||
|
<view class="plan-price"><text class="plan-currency" v-if="item.displayPrice != '待确认'">¥</text>{{item.displayPrice}}</view>
|
||||||
|
<view class="plan-duration">{{item.month}}个月</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
|
||||||
</swiper>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="mainWrapper animation-slide-bottom bg_f">
|
<view class="mainWrapper animation-slide-bottom bg_f">
|
||||||
<view class="title _vipRights">会员套餐权益:</view>
|
<view class="title _vipRights">会员套餐权益:</view>
|
||||||
@ -75,7 +78,7 @@ background: linear-gradient(270deg, #E6C7AB 0%, #F5E6D8 100%);">
|
|||||||
<view class="payBtn" @tap="showFn()">
|
<view class="payBtn" @tap="showFn()">
|
||||||
<view class="l_text">
|
<view class="l_text">
|
||||||
<span>
|
<span>
|
||||||
{{purchaseEnabled ? '点击查看当前套餐价格' : '会员购买暂不可用'}}
|
{{selectedPlan.name || '请选择套餐'}} · {{selectedPlan.displayPrice == '待确认' ? '价格待确认' : '¥' + selectedPlan.displayPrice}}
|
||||||
</span>
|
</span>
|
||||||
</view>
|
</view>
|
||||||
<view class="r_text">
|
<view class="r_text">
|
||||||
@ -166,6 +169,7 @@ import https from '../../mixins/https'
|
|||||||
import base from '../../mixins/base'
|
import base from '../../mixins/base'
|
||||||
import {service} from '../../config.js'
|
import {service} from '../../config.js'
|
||||||
import {buyMembership} from '../../utils/virtual-payment'
|
import {buyMembership} from '../../utils/virtual-payment'
|
||||||
|
import {membershipPlans, planPrice, defaultPlanIndex} from '../../utils/membership-plans'
|
||||||
|
|
||||||
const app = getApp().$wepy.$options
|
const app = getApp().$wepy.$options
|
||||||
|
|
||||||
@ -179,6 +183,8 @@ wepy.page({
|
|||||||
activeV2: false,
|
activeV2: false,
|
||||||
swiperList: [],
|
swiperList: [],
|
||||||
cardCur: 0,
|
cardCur: 0,
|
||||||
|
planTouchX: 0,
|
||||||
|
planTouchY: 0,
|
||||||
specialVIP: [],
|
specialVIP: [],
|
||||||
payData: {
|
payData: {
|
||||||
coin: '',
|
coin: '',
|
||||||
@ -211,6 +217,7 @@ wepy.page({
|
|||||||
loginShow: false
|
loginShow: false
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
selectedPlan() { return this.rankList[this.cardCur] || {name: '', displayPrice: '待确认'} },
|
||||||
residue() {
|
residue() {
|
||||||
return (this.score - (this.price - this.my_rank_price)).toFixed(2)
|
return (this.score - (this.price - this.my_rank_price)).toFixed(2)
|
||||||
}
|
}
|
||||||
@ -258,13 +265,39 @@ wepy.page({
|
|||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
cardCur() {
|
cardCur() {
|
||||||
this.payData.title = `超级会员(${this.rankList[this.cardCur].name})`
|
this.syncSelectedPlan()
|
||||||
this.payData.price = this.rankList[this.cardCur].price
|
|
||||||
this.payData.discount_price = this.rankList[this.cardCur].discount_price
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
syncSelectedPlan() {
|
||||||
|
const item = this.rankList[this.cardCur]
|
||||||
|
if (!item) return
|
||||||
|
this.rankList = this.rankList.map((plan, index) => ({...plan,
|
||||||
|
displayPrice: planPrice(plan, this.virtualProducts),
|
||||||
|
position: index === this.cardCur ? 'is-selected' : index === (this.cardCur + this.rankList.length - 1) % this.rankList.length ? 'is-left' : 'is-right'
|
||||||
|
}))
|
||||||
|
this.payData.title = `超级会员(${item.name})`
|
||||||
|
this.payData.price = item.price
|
||||||
|
this.payData.discount_price = this.rankList[this.cardCur].displayPrice
|
||||||
|
this.shareId = item.id
|
||||||
|
},
|
||||||
|
selectPlan(index) {
|
||||||
|
if (this.purchasing || !this.rankList[index]) return
|
||||||
|
this.cardSwiper({$wx: {detail: {current: index}}})
|
||||||
|
this.syncSelectedPlan()
|
||||||
|
},
|
||||||
|
planTouchStart(e) {
|
||||||
|
const touch = (e.$wx || e).touches[0]
|
||||||
|
this.planTouchX = touch.clientX
|
||||||
|
this.planTouchY = touch.clientY
|
||||||
|
},
|
||||||
|
planTouchEnd(e) {
|
||||||
|
const touch = (e.$wx || e).changedTouches[0]
|
||||||
|
const dx = touch.clientX - this.planTouchX, dy = touch.clientY - this.planTouchY
|
||||||
|
if (Math.abs(dx) < 40 || Math.abs(dx) <= Math.abs(dy) || this.rankList.length < 2) return
|
||||||
|
this.selectPlan((this.cardCur + (dx < 0 ? 1 : -1) + this.rankList.length) % this.rankList.length)
|
||||||
|
},
|
||||||
pendingStorageKey() {const u = wx.getStorageSync('userInfo') || {}; return 'virtual-member-order:' + (u.id || u.user_id || 'anonymous')},
|
pendingStorageKey() {const u = wx.getStorageSync('userInfo') || {}; return 'virtual-member-order:' + (u.id || u.user_id || 'anonymous')},
|
||||||
async checkRecentOrder() {
|
async checkRecentOrder() {
|
||||||
const orderNo = wx.getStorageSync(this.pendingStorageKey())
|
const orderNo = wx.getStorageSync(this.pendingStorageKey())
|
||||||
@ -282,6 +315,7 @@ wepy.page({
|
|||||||
async refreshPurchase() {
|
async refreshPurchase() {
|
||||||
this.purchaseEnabled = false
|
this.purchaseEnabled = false
|
||||||
try {const status = await this.paymentAPI().get('/rank/purchase/status'); this.virtualProducts = status.products || []; this.purchaseEnabled = status.enabled === true} catch (e) {this.virtualProducts = []}
|
try {const status = await this.paymentAPI().get('/rank/purchase/status'); this.virtualProducts = status.products || []; this.purchaseEnabled = status.enabled === true} catch (e) {this.virtualProducts = []}
|
||||||
|
this.syncSelectedPlan()
|
||||||
},
|
},
|
||||||
gotoApp(item) {
|
gotoApp(item) {
|
||||||
let URL = `https://love.ufutx.com/h5/#/serviceAgreementV3?title=${item}`
|
let URL = `https://love.ufutx.com/h5/#/serviceAgreementV3?title=${item}`
|
||||||
@ -294,14 +328,10 @@ wepy.page({
|
|||||||
vm.user = data.rank_info
|
vm.user = data.rank_info
|
||||||
let {type, is_subscribe} = wx.getStorageSync('userInfo')
|
let {type, is_subscribe} = wx.getStorageSync('userInfo')
|
||||||
vm.specialVIP = data.ranks
|
vm.specialVIP = data.ranks
|
||||||
vm.rankList = []
|
vm.rankList = membershipPlans(data.ranks.sub_ranks)
|
||||||
data.ranks.sub_ranks.forEach((item) => {
|
vm.cardCur = defaultPlanIndex(vm.rankList)
|
||||||
vm.rankList.push(item)
|
|
||||||
})
|
|
||||||
if (!vm.rankList.length) {wx.hideLoading();return}
|
if (!vm.rankList.length) {wx.hideLoading();return}
|
||||||
vm.payData.title = `超级会员(${vm.rankList[0].name})`
|
vm.syncSelectedPlan()
|
||||||
vm.payData.price = `${vm.rankList[0].price}`
|
|
||||||
vm.payData.discount_price = `${vm.rankList[0].discount_price}`
|
|
||||||
vm.payData.pay_type = data.pay_type
|
vm.payData.pay_type = data.pay_type
|
||||||
vm.shareId = vm.rankList[vm.cardCur].id
|
vm.shareId = vm.rankList[vm.cardCur].id
|
||||||
if (wx.getStorageSync('from_user_id')) {
|
if (wx.getStorageSync('from_user_id')) {
|
||||||
@ -429,8 +459,10 @@ page {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
background: #171718;
|
background: #171718;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 70vw;
|
min-height: 610rpx;
|
||||||
|
height: auto;
|
||||||
padding-top: 6vw;
|
padding-top: 6vw;
|
||||||
|
padding-bottom: 24rpx;
|
||||||
|
|
||||||
.userinfo-avatar {
|
.userinfo-avatar {
|
||||||
width: 110rpx;
|
width: 110rpx;
|
||||||
@ -535,13 +567,23 @@ page {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-swiper {
|
.plan-heading { clear: both; padding: 34rpx 32rpx 0; color: #fff; font-size: 32rpx; font-weight: 600; }
|
||||||
width: 100% !important;
|
.plan-hint { padding: 10rpx 32rpx 0; color: #cbbdc1; font-size: 23rpx; }
|
||||||
|
.membership-carousel { position: relative; height: 386rpx; margin: 18rpx 20rpx 0; }
|
||||||
.swiper-item {
|
.membership-plan { position: absolute; box-sizing: border-box; width: 28%; top: 30rpx; height: 316rpx; padding: 18rpx 10rpx 12rpx; border: 2rpx solid #EED3DB; border-radius: 24rpx; background: #FFF9F5; text-align: center; color: #4E4145; transition: left .25s, width .25s, top .25s, height .25s; }
|
||||||
border-radius: 22rpx;
|
.membership-plan.is-left { left: 0; }
|
||||||
}
|
.membership-plan.is-right { left: 72%; }
|
||||||
}
|
.membership-plan.is-selected { left: 30%; top: 0; width: 40%; height: 376rpx; border: 4rpx solid #D92554; background: #FFF1F4; box-shadow: 0 12rpx 30rpx rgba(217,37,84,.2); z-index: 2; }
|
||||||
|
.plan-badge { color: #97717D; font-size: 20rpx; height: 30rpx; }
|
||||||
|
.is-selected .plan-badge { color: #D92554; font-weight: 600; }
|
||||||
|
.plan-picture { width: 100%; height: 80rpx; display: block; margin: 6rpx auto 8rpx; }
|
||||||
|
.is-selected .plan-picture { height: 102rpx; }
|
||||||
|
.plan-name { color: #A3294D; font-size: 28rpx; font-weight: 600; }
|
||||||
|
.is-selected .plan-name { font-size: 34rpx; }
|
||||||
|
.plan-price { color: #A3294D; font-size: 42rpx; line-height: 1.4; font-weight: 700; white-space: nowrap; }
|
||||||
|
.is-selected .plan-price { color: #D92554; font-size: 60rpx; }
|
||||||
|
.plan-currency { font-size: 24rpx; margin-right: 2rpx; }
|
||||||
|
.plan-duration { font-size: 22rpx; color: #97717D; }
|
||||||
|
|
||||||
.iconV2 {
|
.iconV2 {
|
||||||
height: 36rpx;
|
height: 36rpx;
|
||||||
|
|||||||
17
src/utils/membership-plans.js
Normal file
17
src/utils/membership-plans.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Only show durations supplied by the API; never manufacture a missing plan or price.
|
||||||
|
export function membershipPlans(rows) {
|
||||||
|
const plans = [1, 3, 12].map(month => (rows || []).find(item => Number(item.month) === month)).filter(Boolean)
|
||||||
|
return plans.map(item => ({...item, displayPrice: '待确认', position: ''}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function planPrice(item, products) {
|
||||||
|
const product = (products || []).find(p => Number(p.sub_rank_id) === Number(item.id))
|
||||||
|
const raw = product ? Number(product.price_fen) / 100 : (item.discount_price == null ? item.price : item.discount_price)
|
||||||
|
if (raw === '' || raw == null || !Number.isFinite(Number(raw)) || Number(raw) < 0) return '待确认'
|
||||||
|
return Number(raw).toFixed(2).replace(/\.00$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function defaultPlanIndex(plans) {
|
||||||
|
const quarter = plans.findIndex(item => Number(item.month) === 3)
|
||||||
|
return quarter < 0 ? 0 : quarter
|
||||||
|
}
|
||||||
@ -1,19 +1,20 @@
|
|||||||
const fs=require('fs'),vm=require('vm'),assert=require('assert');
|
const fs=require('fs'),vm=require('vm'),assert=require('assert');
|
||||||
const source=fs.readFileSync('ufutx_love_mp/src/pages/home/information.wpy','utf8').match(/<script>([\s\S]*?)<\/script>/)[1].replace(/^import .*$/gm,'');
|
const source=fs.readFileSync('ufutx_love_mp/src/pages/home/information.wpy','utf8').match(/<script>([\s\S]*?)<\/script>/)[1].replace(/^import .*$/gm,'');
|
||||||
let options,modal,navigations=[];
|
let options,modal,sheet,navigations=[];
|
||||||
const wx={getStorageSync:()=> 'synthetic-token',showModal:o=>{modal=o},navigateTo:o=>navigations.push(o.url)};
|
const wx={getStorageSync:()=> 'synthetic-token',showModal:o=>{modal=o},showActionSheet:o=>{sheet=o},navigateTo:o=>navigations.push(o.url)};
|
||||||
vm.runInNewContext(source,{wepy:{page:o=>{options=o}},https:{},base:{},service:{host:'https://synthetic.invalid'},wx,console});
|
vm.runInNewContext(source,{wepy:{page:o=>{options=o}},https:{},base:{},service:{host:'https://synthetic.invalid'},wx,console});
|
||||||
const allow={allowed:true,action:'allow',remaining:1,unlimited:false};
|
const allow={allowed:true,action:'allow',remaining:1,unlimited:false,required:['education']};
|
||||||
function page(statuses){let gets=0,posts=0,greetings=0;return Object.assign({},options.methods,{id:123,message:'synthetic',throttle:true,modalName:'',checkingFriendEligibility:false,$signInVerify:()=>true,$showToast:()=>{},$get:async()=>({code:0,data:statuses[Math.min(gets++,statuses.length-1)]}),$post:async()=>{posts++;return {code:0}},getGreet:()=>{greetings++},counts:()=>({gets,posts,greetings})})}
|
function page(statuses){let gets=0,posts=0,greetings=0;return Object.assign({},options.methods,{id:123,message:'synthetic',throttle:true,modalName:'',checkingFriendEligibility:false,$signInVerify:()=>true,$showToast:()=>{},$get:async()=>({code:0,data:statuses[Math.min(gets++,statuses.length-1)]}),$post:async()=>{posts++;return {code:0}},getGreet:()=>{greetings++},counts:()=>({gets,posts,greetings})})}
|
||||||
(async()=>{
|
(async()=>{
|
||||||
let incomplete=page([{action:'profile',required:['profile'],allowed:false,remaining:0}]);incomplete.$signInVerify=()=>false;await incomplete.contactFriendFn();assert.equal(incomplete.counts().greetings,0);assert.equal(modal.title,'请先完善个人资料');modal.success({confirm:true});assert.equal(navigations.pop(),'/pages/users/unmarriV2?progressShow=false');await incomplete.sendMsg();assert.equal(incomplete.counts().posts,0);
|
for(const [key,url] of Object.entries({real:'/pages/users/realName',photo:'/pages/users/unmarriV2?progressShow=false',profile:'/pages/users/unmarriV2?progressShow=false',education:'/pages/users/degreeCertificate'})) {
|
||||||
let p=page([{action:'verify',required:['real','education'],allowed:false}]);await p.contactFriendFn();assert.equal(p.counts().greetings,0);modal.success({confirm:true});assert.equal(navigations.pop(),'/pages/users/realName');
|
const p=page([{action:'tasks',required:[key],allowed:false,remaining:0}]);await p.contactFriendFn();assert.equal(p.counts().greetings,0);assert(!modal.content.includes('升级会员'));modal.success({confirm:false});assert.equal(navigations.length,0);modal.success({confirm:true});sheet.success({tapIndex:0});assert.equal(navigations.pop(),url);await p.sendMsg();assert.equal(p.counts().posts,0);
|
||||||
p=page([{action:'verify',required:['education'],allowed:false}]);await p.contactFriendFn();modal.success({confirm:true});assert.equal(navigations.pop(),'/pages/users/degreeCertificate');
|
}
|
||||||
p=page([{action:'purchase',remaining:0,allowed:false}]);await p.contactFriendFn();assert.equal(navigations.pop(),'/pages/users/upgradeVIP');assert.equal(p.counts().greetings,0);
|
let p=page([{action:'tasks',required:['real','photo','profile','education'],allowed:false}]);await p.contactFriendFn();modal.success({confirm:true});assert.equal(sheet.itemList.length,4);
|
||||||
|
p=page([{action:'purchase',required:[],remaining:0,allowed:false}]);await p.contactFriendFn();assert.equal(navigations.length,0);assert(modal.content.includes('无限次'));modal.success({confirm:true});assert.equal(navigations.pop(),'/pages/users/upgradeVIP');
|
||||||
p=page([allow]);await p.contactFriendFn();assert.equal(p.counts().greetings,1);
|
p=page([allow]);await p.contactFriendFn();assert.equal(p.counts().greetings,1);
|
||||||
p=page([allow,{action:'purchase',remaining:0,allowed:false}]);await p.sendMsg();await new Promise(setImmediate);assert.equal(p.counts().posts,1);assert.equal(navigations.pop(),'/pages/users/upgradeVIP');
|
p=page([allow,{action:'tasks',required:['photo'],remaining:0,allowed:false}]);await p.sendMsg();await new Promise(setImmediate);assert.equal(p.counts().posts,1);assert(modal.content.includes('真人头像'));assert.equal(navigations.length,0);
|
||||||
p=page([{action:'verify',required:['real'],allowed:false}]);await p.sendMsg();assert.equal(p.counts().posts,0);
|
p=page([allow,{action:'purchase',required:[],remaining:0,allowed:false}]);await p.sendMsg();await new Promise(setImmediate);assert.equal(p.counts().posts,1);assert.equal(modal.confirmText,'升级会员');
|
||||||
p=page([{allowed:true,unlimited:true,remaining:-1,action:'allow'}]);await p.sendMsg();await new Promise(setImmediate);assert.equal(navigations.length,0);
|
p=page([{allowed:true,unlimited:true,remaining:-1,action:'allow'}]);await p.sendMsg();await new Promise(setImmediate);assert.equal(navigations.length,0);
|
||||||
p=page([]);p.$get=async()=>{throw Error('synthetic offline')};await p.sendMsg();assert.equal(p.counts().posts,0);assert(p.throttle);
|
p=page([]);p.$get=async()=>{throw Error('synthetic offline')};await p.sendMsg();assert.equal(p.counts().posts,0);assert(p.throttle);
|
||||||
console.log('PASS: real/education guidance, verified entry, exhausted redirect, third successful request redirect, direct-send gating, member unchanged, network failure closed; no real requests');
|
console.log('PASS task choice, four independent rewards, exhausted guidance, membership confirmation, post-send refresh, member bypass, network failure; no real requests');
|
||||||
})().catch(e=>{console.error(e);process.exitCode=1});
|
})().catch(e=>{console.error(e);process.exitCode=1});
|
||||||
|
|||||||
12
tools/local-acceptance/membership-plans.test.cjs
Normal file
12
tools/local-acceptance/membership-plans.test.cjs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const fs=require('fs'),vm=require('vm'),assert=require('assert');
|
||||||
|
const helpers={};vm.createContext(helpers);vm.runInContext(fs.readFileSync('ufutx_love_mp/src/utils/membership-plans.js','utf8').replace(/export /g,''),helpers);
|
||||||
|
const rows=[{id:12,month:12,name:'年卡',discount_price:388},{id:15,month:0,name:'隐藏测试'},{id:10,month:1,name:'月卡',discount_price:78},{id:11,month:3,name:'季卡',discount_price:108}];
|
||||||
|
const plans=helpers.membershipPlans(rows);assert.equal(plans.length,3);assert.equal(plans[helpers.defaultPlanIndex(plans)].id,11);assert.equal(plans[0].id,10);assert.equal(plans[2].id,12);
|
||||||
|
assert.equal(helpers.planPrice(plans[1],[]),'108');assert.equal(helpers.planPrice(plans[1],[{sub_rank_id:11,price_fen:10999}]),'109.99');assert.equal(helpers.planPrice({id:99},[]),'待确认');assert.equal(helpers.defaultPlanIndex([]),0);
|
||||||
|
let options;const wx={getStorageSync:()=>''};const source=fs.readFileSync('ufutx_love_mp/src/pages/users/upgradeVIP.wpy','utf8').match(/<script>([\s\S]*?)<\/script>/)[1].replace(/^import .*$/gm,'');
|
||||||
|
vm.runInNewContext(source,{...helpers,membershipPlans:helpers.membershipPlans,planPrice:helpers.planPrice,defaultPlanIndex:helpers.defaultPlanIndex,wepy:{page:o=>options=o},https:{},base:{},service:{},buyMembership:()=>{},wx,getApp:()=>({$wepy:{$options:{}}}),setTimeout:()=>0,clearTimeout:()=>{}});
|
||||||
|
const p=Object.assign({},options.methods,{rankList:plans,cardCur:1,payData:{},virtualProducts:[],purchasing:false});p.syncSelectedPlan();assert.equal(p.rankList[1].position,'is-selected');assert.equal(p.rankList[0].position,'is-left');assert.equal(p.rankList[2].position,'is-right');assert.equal(p.payData.discount_price,'108');
|
||||||
|
p.selectPlan(0);assert.equal(p.shareId,10);assert.equal(p.rankList[0].position,'is-selected');
|
||||||
|
p.planTouchStart({touches:[{clientX:200,clientY:20}]});p.planTouchEnd({changedTouches:[{clientX:100,clientY:25}]});assert.equal(p.cardCur,1);assert.equal(p.shareId,11);
|
||||||
|
p.planTouchStart({touches:[{clientX:100,clientY:20}]});p.planTouchEnd({changedTouches:[{clientX:103,clientY:120}]});assert.equal(p.cardCur,1);
|
||||||
|
console.log('PASS quarter default, duration order, live prices, unknown price, selection, swipe and vertical-scroll guard');
|
||||||
Loading…
Reference in New Issue
Block a user