Files
MBTI_wang/miniprogram/pages/result/disc.js
Ghost 3317c84b5e feat: 管理端与用户端批量更新(订单/邀请双码/tabBar/审核与分销等)
- 管理端:用户详情、企业看板双小程序码、超管设置与用户列表等
- 后端:订单接口、邀请码企业版+个人版、分析与测试相关调整
- 微信小程序/抖音:自定义 tabBar 居中与拍摄钮上移、相机页与结果页、订单页、支付与统计
- 新增 faceResultDetail 工具与 mp 分析迁移脚本

Made-with: Cursor
2026-03-28 16:46:00 +08:00

158 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/result/disc.js - DISC结果页支持付费墙 + 历史详情拉取)
const app = getApp()
const payment = require('../../utils/payment')
function toIntPercent(v) {
if (v == null) return 0
const n = typeof v === 'number' ? v : Number(v)
return Number.isFinite(n) ? Math.round(n) : 0
}
function withPercentagesInt(data) {
if (!data) return data
const p = data.percentages || {}
const out = { ...data }
out.percentagesInt = {
D: toIntPercent(p.D ?? p.d),
I: toIntPercent(p.I ?? p.i),
S: toIntPercent(p.S ?? p.s),
C: toIntPercent(p.C ?? p.c)
}
return out
}
Page({
data: {
result: null,
typeList: [
{ type: 'D', label: 'D型 - 支配型', colorClass: 'fill-d' },
{ type: 'I', label: 'I型 - 影响型', colorClass: 'fill-i' },
{ type: 'S', label: 'S型 - 稳健型', colorClass: 'fill-s' },
{ type: 'C', label: 'C型 - 谨慎型', colorClass: 'fill-c' }
],
payInfo: { requiresPayment: false, isPaid: false, amountYuan: 0 },
testResultId: null,
hasReloadedAfterPay: false
},
onLoad(options) {
const id = options && options.id
const type = options && options.type
if (id && type === 'disc') {
this.setData({ testResultId: id })
this.loadDetail(id)
return
}
const result = wx.getStorageSync('discResult')
if (result) {
this.setData({ result: withPercentagesInt(result) })
this.initPayInfoFromRuntime('disc')
} else {
wx.showToast({ title: '暂无测试结果', icon: 'none' })
setTimeout(() => wx.navigateBack(), 1500)
}
},
loadDetail(id) {
const apiBase = app.globalData?.apiBase || ''
const token = app.globalData?.token || wx.getStorageSync('token') || ''
if (!apiBase) { wx.showToast({ title: '配置异常', icon: 'none' }); return }
wx.showLoading({ title: '加载中...' })
wx.request({
url: `${apiBase}/api/test/detail`,
method: 'GET',
header: token ? { Authorization: `Bearer ${token}` } : {},
data: { id },
success: (res) => {
if (res.statusCode === 200 && res.data && res.data.code === 200) {
const payload = res.data.data || {}
const data = payload.data || payload
const isPaid = !!payload.isPaid
const paidAmount = payload.paidAmount != null ? Number(payload.paidAmount) : 0
const amountYuan = payload.amountYuan != null ? Number(payload.amountYuan) : (paidAmount > 0 ? paidAmount / 100 : 0)
const needPaymentToUnlock = payload.needPaymentToUnlock === true || (!!payload.requiresPayment && !isPaid && paidAmount > 0)
this.setData({ result: withPercentagesInt(data) })
const payInfo = {
requiresPayment: needPaymentToUnlock,
isPaid,
amountYuan: needPaymentToUnlock ? amountYuan : 0
}
this.setData({ payInfo })
} else {
wx.showToast({ title: res.data?.message || '加载失败', icon: 'none' })
}
},
fail: () => wx.showToast({ title: '网络错误', icon: 'none' }),
complete: () => wx.hideLoading()
})
},
initPayInfoFromRuntime(testType) {
app.getRuntimeConfig()
.then((cfg) => {
const reportRequires = cfg.reportRequiresPayment || {}
const pricing = cfg.pricing || {}
const requiresPayment = !!(reportRequires && reportRequires[testType])
const amountYuan = Number(pricing[testType]) || (requiresPayment ? 1.98 : 0)
this.setData({
payInfo: { requiresPayment, isPaid: false, amountYuan }
})
})
.catch(() => this.setData({ payInfo: { requiresPayment: false, isPaid: false, amountYuan: 0 } }))
},
unlockFullReport() {
const { payInfo, testResultId, hasReloadedAfterPay } = this.data
if (!payInfo.requiresPayment || payInfo.isPaid) return
app.ensureLogin && app.ensureLogin().then((logged) => {
if (!logged) { wx.showToast({ title: '请先登录', icon: 'none' }); return }
payment.purchaseDiscTest({
testResultId: testResultId || undefined,
success: () => {
wx.showToast({ title: '已解锁完整报告', icon: 'success' })
this.setData({ 'payInfo.isPaid': true })
if (testResultId && !hasReloadedAfterPay) {
this.setData({ hasReloadedAfterPay: true })
setTimeout(() => this.loadDetail(testResultId), 500)
}
},
fail: () => {}
})
})
},
retakeTest() {
if (!this.data.testResultId) {
wx.removeStorageSync('discResult')
}
wx.navigateTo({ url: '/pages/test/disc' })
},
goHome() {
const scope = (getApp().globalData && getApp().globalData.appScope) || 'personal'
if (scope === 'enterprise') {
wx.navigateTo({ url: '/pages/enterprise/index' })
} else {
wx.switchTab({ url: '/pages/index/index' })
}
},
onShareAppMessage() {
const result = this.data.result
const { getSharePathByScope } = require('../../utils/share')
return {
title: `我的DISC类型是${result?.dominantType}型(${result?.description?.title}),来测测你的吧!`,
path: getSharePathByScope('/pages/index/index')
}
},
onShareTimeline() {
const result = this.data.result
const { buildShareQuery } = require('../../utils/share')
return {
title: `我的DISC类型是${result?.dominantType}型(${result?.description?.title}),来测测你的吧!`,
query: buildShareQuery()
}
}
})