feat: 第三方渠道上下文与开放平台服务接入

1、修复了企业版/个人版在第三方入口下的人脸与测评跳转问题。

2、新增 ThirdPartyChannel/OpenPlatformService 及上下文 thirdPartyContext,补充相关迁移。

3、调整 Analyze/Auth/Test 等接口与小程序入口逻辑。

Made-with: Cursor
This commit is contained in:
Ghost
2026-04-03 14:18:34 +08:00
parent 48c4d551d2
commit 1a66e77ab7
25 changed files with 1401 additions and 368 deletions

View File

@@ -68,6 +68,11 @@ App({
// 记录场景值供埋点使用
this.globalData.scene = launchOptions && launchOptions.scene ? launchOptions.scene : ''
try {
const { mergeThirdPartyFromQuery } = require('./utils/thirdPartyContext.js')
mergeThirdPartyFromQuery((launchOptions && launchOptions.query) || {})
} catch (e) {}
// 加载本地存储的数据
this.loadStoredData()
@@ -223,12 +228,21 @@ App({
const eid = getEffectiveEnterpriseId()
if (eid) loginData.enterpriseId = eid
} catch (e) {}
try {
const { getThirdPartyForLoginBody } = require('./utils/thirdPartyContext.js')
Object.assign(loginData, getThirdPartyForLoginBody())
} catch (e) {}
wx.request({
url,
method: 'POST',
header: { 'Content-Type': 'application/json' },
data: loginData,
success: (response) => {
if (response.statusCode === 200 && response.data && response.data.code === 409 && response.data.message) {
try {
wx.showToast({ title: String(response.data.message), icon: 'none', duration: 3000 })
} catch (e) {}
}
if (response.statusCode === 200 && response.data && response.data.code === 200) {
const data = response.data.data || {}
const { token, user } = data

View File

@@ -48,6 +48,10 @@ Page({
eid
})
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
if (eid > 0) app.globalData.enterpriseIdFromScene = eid
// 企业版分销绑定uid > 0 且 eid > 0 时触发

View File

@@ -17,7 +17,10 @@ Page({
return !!(app.globalData.reviewMode || app.globalData.maintenanceMode)
},
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
this.setData({ reviewMode: this._audit() })
const tc = app.globalData.textConfig
if (tc && tc.aiAnalysisText) {

View File

@@ -75,6 +75,10 @@ Page({
})
}
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
const uid = parseInt(sceneParams.uid || (options && options.uid) || 0, 10)
const eid = parseInt(sceneParams.eid || (options && options.eid) || 0, 10)

View File

@@ -19,7 +19,10 @@ Page({
aiAnalysisText: '分析'
},
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
const tc = app.globalData.textConfig
if (tc && tc.aiAnalysisText) {
this.setData({ aiAnalysisText: tc.aiAnalysisText })

View File

@@ -41,7 +41,7 @@ Page({
],
payInfo: { requiresPayment: false, isPaid: false, amountYuan: 0 },
testResultId: null,
hasReloadedAfterPay: false
hasReloadedAfterPay: false,
},
onLoad(options) {

View File

@@ -1,91 +1,91 @@
<!--pages/result/disc.wxml - DISC结果按旧版模板重构-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">您的DISC性格类型</text>
<text class="type-value">{{typeSummaryLine}}</text>
<text class="type-description" wx:if="{{result.description && result.description.description}}">{{result.description.description}}</text>
</view>
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整DISC报告</text>
<text class="paywall-fake-line">• 四维得分详情</text>
<text class="paywall-fake-line">• 性格特征与优劣势</text>
<text class="paywall-fake-line">• 职业匹配建议</text>
</view>
<view class="paywall-mask"></view>
<view class="paywall-btn" bindtap="unlockFullReport">
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</view>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整 DISC 报告。</text>
<view class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</view>
</view>
</view>
<view class="scores-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="section-title">DISC得分详情</text>
<view class="score-item" wx:for="{{typeList}}" wx:key="type">
<view class="score-header">
<text class="score-label">{{item.label}}</text>
<text class="score-value">{{result.percentagesInt[item.type] != null ? result.percentagesInt[item.type] + '%' : '0%'}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar {{item.colorClass}}" style="width: {{result.percentages[item.type]}}%"></view>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">主要性格特征分析</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{result.description.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{result.description.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">职业匹配度分析</text>
<view class="career-item" wx:for="{{result.description.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>
<!--pages/result/disc.wxml - DISC结果按旧版模板重构-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">您的DISC性格类型</text>
<text class="type-value">{{typeSummaryLine}}</text>
<text class="type-description" wx:if="{{result.description && result.description.description}}">{{result.description.description}}</text>
</view>
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整DISC报告</text>
<text class="paywall-fake-line">• 四维得分详情</text>
<text class="paywall-fake-line">• 性格特征与优劣势</text>
<text class="paywall-fake-line">• 职业匹配建议</text>
</view>
<view class="paywall-mask"></view>
<view class="paywall-btn" bindtap="unlockFullReport">
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</view>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整 DISC 报告。</text>
<view class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</view>
</view>
</view>
<view class="scores-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="section-title">DISC得分详情</text>
<view class="score-item" wx:for="{{typeList}}" wx:key="type">
<view class="score-header">
<text class="score-label">{{item.label}}</text>
<text class="score-value">{{result.percentagesInt[item.type] != null ? result.percentagesInt[item.type] + '%' : '0%'}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar {{item.colorClass}}" style="width: {{result.percentages[item.type]}}%"></view>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">主要性格特征分析</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{result.description.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{result.description.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">职业匹配度分析</text>
<view class="career-item" wx:for="{{result.description.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>

View File

@@ -27,7 +27,7 @@ Page({
},
testResultId: null,
hasReloadedAfterPay: false,
hasPhone: false
hasPhone: false,
},
onLoad(options) {

View File

@@ -1,117 +1,117 @@
<!--pages/result/mbti.wxml - MBTI结果页面支持付费墙-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">您的MBTI性格类型</text>
<text class="type-value">{{result.mbtiType}}</text>
<text class="type-title">{{mbtiDesc.title}}</text>
<text class="type-description">{{mbtiDesc.description}}</text>
</view>
<!-- 付费墙:未解锁时显示 -->
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整性格分析</text>
<text class="paywall-fake-line">• 四维得分与主导倾向</text>
<text class="paywall-fake-line">• 优势与需要注意的方面</text>
<text class="paywall-fake-line">• 职业匹配与人际关系建议</text>
</view>
<view class="paywall-mask"></view>
<!-- 未有手机号:使用微信系统手机号授权 -->
<button
class="paywall-btn"
wx:if="{{!hasPhone}}"
open-type="getPhoneNumber"
bindgetphonenumber="onGetPhoneNumberForMbtiPay"
>
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</button>
<!-- 已有手机号:普通按钮,直接解锁 -->
<button
class="paywall-btn"
wx:elif="{{hasPhone}}"
bindtap="unlockFullReport"
>
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</button>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整性格分析。</text>
<button class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</button>
</view>
</view>
<view class="dimensions-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<view class="dimension-item" wx:for="{{dimensions}}" wx:key="key">
<view class="dimension-labels">
<text class="label-left">{{item.left}}</text>
<text class="label-right">{{item.right}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar" style="width: {{item.percentage}}%"></view>
</view>
<view class="dimension-values">
<text class="value-left">{{item.dominant}}</text>
<text class="value-right">{{item.percentage}}%</text>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">性格特征分析</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{mbtiDesc.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{mbtiDesc.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{!payInfo.requiresPayment || payInfo.isPaid}}">
<text class="card-title">职业匹配度分析</text>
<view class="career-item" wx:for="{{mbtiDesc.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid) && mbtiDesc.relationships}}">
<text class="card-title">人际关系分析</text>
<text class="relationship-text">{{mbtiDesc.relationships}}</text>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>
<!--pages/result/mbti.wxml - MBTI结果页面支持付费墙-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">您的MBTI性格类型</text>
<text class="type-value">{{result.mbtiType}}</text>
<text class="type-title">{{mbtiDesc.title}}</text>
<text class="type-description">{{mbtiDesc.description}}</text>
</view>
<!-- 付费墙:未解锁时显示 -->
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整性格分析</text>
<text class="paywall-fake-line">• 四维得分与主导倾向</text>
<text class="paywall-fake-line">• 优势与需要注意的方面</text>
<text class="paywall-fake-line">• 职业匹配与人际关系建议</text>
</view>
<view class="paywall-mask"></view>
<!-- 未有手机号:使用微信系统手机号授权 -->
<button
class="paywall-btn"
wx:if="{{!hasPhone}}"
open-type="getPhoneNumber"
bindgetphonenumber="onGetPhoneNumberForMbtiPay"
>
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</button>
<!-- 已有手机号:普通按钮,直接解锁 -->
<button
class="paywall-btn"
wx:elif="{{hasPhone}}"
bindtap="unlockFullReport"
>
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</button>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整性格分析。</text>
<button class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</button>
</view>
</view>
<view class="dimensions-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<view class="dimension-item" wx:for="{{dimensions}}" wx:key="key">
<view class="dimension-labels">
<text class="label-left">{{item.left}}</text>
<text class="label-right">{{item.right}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar" style="width: {{item.percentage}}%"></view>
</view>
<view class="dimension-values">
<text class="value-left">{{item.dominant}}</text>
<text class="value-right">{{item.percentage}}%</text>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">性格特征分析</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{mbtiDesc.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{mbtiDesc.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{!payInfo.requiresPayment || payInfo.isPaid}}">
<text class="card-title">职业匹配度分析</text>
<view class="career-item" wx:for="{{mbtiDesc.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid) && mbtiDesc.relationships}}">
<text class="card-title">人际关系分析</text>
<text class="relationship-text">{{mbtiDesc.relationships}}</text>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>

View File

@@ -44,7 +44,7 @@ Page({
],
payInfo: { requiresPayment: false, isPaid: false, amountYuan: 0 },
testResultId: null,
hasReloadedAfterPay: false
hasReloadedAfterPay: false,
},
onLoad(options) {

View File

@@ -1,97 +1,97 @@
<!--pages/result/pdp.wxml - PDP结果按旧版模板重构-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">PDP性格类型</text>
<text class="type-value">{{typeSummaryLine}}</text>
<text class="type-title" wx:if="{{result.description.title}}">{{result.description.title}}</text>
<text class="type-description" wx:if="{{result.description.description}}">{{result.description.description}}</text>
</view>
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整PDP报告</text>
<text class="paywall-fake-line">• 五维得分详情</text>
<text class="paywall-fake-line">• 性格特征与团队角色</text>
<text class="paywall-fake-line">• 推荐职业</text>
</view>
<view class="paywall-mask"></view>
<view class="paywall-btn" bindtap="unlockFullReport">
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</view>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整 PDP 报告。</text>
<view class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</view>
</view>
</view>
<view class="scores-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="section-title">PDP得分详情</text>
<view class="score-item" wx:for="{{typeList}}" wx:key="type">
<view class="score-header">
<text class="score-label">{{item.emoji}} {{item.label}}</text>
<text class="score-value">{{result.percentagesInt && result.percentagesInt[item.type] != null ? result.percentagesInt[item.type] + '%' : '0%'}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar {{item.colorClass}}" style="width: {{result.percentages[item.type]}}%"></view>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">性格特征</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{result.description.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{result.description.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">团队角色</text>
<text class="relationship-text">{{result.description.teamRole}}</text>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">推荐职业</text>
<view class="career-item" wx:for="{{result.description.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>
<!--pages/result/pdp.wxml - PDP结果按旧版模板重构-->
<view class="result-page">
<scroll-view class="content-scroll" scroll-y>
<view class="content-container">
<view class="type-card">
<view class="type-header">
<text class="type-label">PDP性格类型</text>
<text class="type-value">{{typeSummaryLine}}</text>
<text class="type-title" wx:if="{{result.description.title}}">{{result.description.title}}</text>
<text class="type-description" wx:if="{{result.description.description}}">{{result.description.description}}</text>
</view>
<view class="paywall-card" wx:if="{{payInfo.requiresPayment && !payInfo.isPaid}}">
<view class="paywall-content">
<view class="paywall-blur">
<text class="paywall-fake-title">完整PDP报告</text>
<text class="paywall-fake-line">• 五维得分详情</text>
<text class="paywall-fake-line">• 性格特征与团队角色</text>
<text class="paywall-fake-line">• 推荐职业</text>
</view>
<view class="paywall-mask"></view>
<view class="paywall-btn" bindtap="unlockFullReport">
<text class="paywall-btn-main">解锁完整报告</text>
<text class="paywall-btn-price">¥{{payInfo.amountYuan}} / 次</text>
</view>
</view>
</view>
<view class="paywall-card" wx:elif="{{result && result.locked}}">
<view class="paywall-content">
<text class="paywall-fake-title">完整报告需完善资料</text>
<text class="paywall-fake-line">请补全头像、昵称并绑定手机号后查看完整 PDP 报告。</text>
<view class="paywall-btn" bindtap="goCompleteProfile">
<text class="paywall-btn-main">去完善资料</text>
</view>
</view>
</view>
<view class="scores-section" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="section-title">PDP得分详情</text>
<view class="score-item" wx:for="{{typeList}}" wx:key="type">
<view class="score-header">
<text class="score-label">{{item.emoji}} {{item.label}}</text>
<text class="score-value">{{result.percentagesInt && result.percentagesInt[item.type] != null ? result.percentagesInt[item.type] + '%' : '0%'}}</text>
</view>
<view class="progress-bar-container">
<view class="progress-bar {{item.colorClass}}" style="width: {{result.percentages[item.type]}}%"></view>
</view>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">性格特征</text>
<view class="trait-section">
<text class="trait-title">优势</text>
<view class="trait-item" wx:for="{{result.description.strengths}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
<view class="trait-section">
<text class="trait-title">需要注意的方面</text>
<view class="trait-item" wx:for="{{result.description.weaknesses}}" wx:key="*this">
<text class="trait-bullet">•</text>
<text class="trait-text">{{item}}</text>
</view>
</view>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">团队角色</text>
<text class="relationship-text">{{result.description.teamRole}}</text>
</view>
<view class="analysis-card" wx:if="{{result && !result.locked && (!payInfo.requiresPayment || payInfo.isPaid)}}">
<text class="card-title">推荐职业</text>
<view class="career-item" wx:for="{{result.description.careers}}" wx:key="*this">
<view class="career-dot"></view>
<text class="career-text">{{item}}</text>
</view>
</view>
<!-- <view class="action-section">
<button class="btn btn-primary" open-type="share">
<text class="btn-text">分享结果</text>
</button>
<view class="btn btn-outline" bindtap="retakeTest">
<text class="btn-text-outline">重新测试</text>
</view>
<view class="btn btn-outline" bindtap="goHome">
<text class="btn-text-outline">返回首页</text>
</view>
</view> -->
</view>
</scroll-view>
</view>

View File

@@ -9,7 +9,10 @@ Page({
permDisc: true
},
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
this._syncPerms()
},

View File

@@ -24,7 +24,10 @@ Page({
timer: null,
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
loadQuestions('disc', {})
.then((questions) => {
if (!questions.length) {

View File

@@ -26,7 +26,10 @@ Page({
timer: null,
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
loadQuestions('mbti', {})
.then((questions) => {
const total = questions.length

View File

@@ -24,7 +24,10 @@ Page({
timer: null,
onLoad() {
onLoad(options) {
try {
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
} catch (e) {}
loadQuestions('pdp', {})
.then((questions) => {
if (!questions.length) {

View File

@@ -1,34 +1,41 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "Mbti",
"setting": {
"compileHotReLoad": true
},
"condition": {
"miniprogram": {
"list": [
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=uid%253D6%2526eid%253D6",
"launchMode": "default",
"scene": null
},
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=e_6",
"launchMode": "default",
"scene": null
},
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=e_6",
"launchMode": "default",
"scene": null
}
]
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "Mbti",
"setting": {
"compileHotReLoad": true
},
"condition": {
"miniprogram": {
"list": [
{
"name": "MBTI",
"pathName": "pages/test/mbti",
"query": "phone=18649947301",
"scene": null,
"launchMode": "default"
},
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=uid%253D6%2526eid%253D6",
"launchMode": "default",
"scene": null
},
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=e_6",
"launchMode": "default",
"scene": null
},
{
"name": "pages/enterprise/index",
"pathName": "pages/enterprise/index",
"query": "scene=e_6",
"launchMode": "default",
"scene": null
}
]
}
}
}

View File

@@ -0,0 +1,126 @@
/**
* 第三方渠道参数query / scene 中的 userid、phone、tid与分销 uid 分流)
* 仅存 globalData登录时透传 thirdParty
*/
function safeDecode(v) {
if (v == null || v === '') return ''
const s = String(v).trim()
if (!s) return ''
try {
return decodeURIComponent(s)
} catch (e) {
return s
}
}
function ensureChannel(app) {
if (!app.globalData.thirdPartyChannel) {
app.globalData.thirdPartyChannel = {
userid: '',
phone: '',
tid: '',
capturedAt: 0,
}
}
return app.globalData.thirdPartyChannel
}
/**
* 从 query 对象合并(同字段以首次非空为准)
*/
function mergeThirdPartyFromQuery(q) {
if (!q || typeof q !== 'object') return false
const app = getApp()
const ch = ensureChannel(app)
let changed = false
const touch = (key, raw) => {
const v = safeDecode(raw)
if (!v) return
if (!ch[key]) {
ch[key] = v
changed = true
}
}
touch('userid', q.userid)
touch('phone', q.phone)
touch('tid', q.tid)
if (changed) ch.capturedAt = Date.now()
return changed
}
/** App.onLaunch 使用 */
function ingestThirdPartyFromLaunch(launchOptions) {
const q = (launchOptions && launchOptions.query) || {}
mergeThirdPartyFromQuery(q)
}
/**
* 页面 onLoad合并 options + 已解码的 sceneParams
* @returns {boolean} 是否有新字段写入(便于触发二次 silentLogin
*/
function mergeFromPageOptions(options, sceneParams) {
const o = {}
if (options && typeof options === 'object') {
if (options.userid != null) o.userid = options.userid
if (options.phone != null) o.phone = options.phone
if (options.tid != null) o.tid = options.tid
}
const c1 = mergeThirdPartyFromQuery(o)
const c2 = mergeThirdPartyFromQuery(sceneParams || {})
return !!(c1 || c2)
}
/**
* 任意可作为外链入口的页面 onLoad 首行调用:解析 options.query + options.scene合并第三方参数并视情况 silentLogin
* @param {object} [options] Page.onLoad 第一个参数
* @param {object} [appInst] App 实例,默认 getApp()
*/
function ingestThirdPartyOnPageLoad(options, appInst) {
options = options || {}
let rawScene = ''
try {
rawScene = options.scene ? decodeURIComponent(String(options.scene)) : ''
} catch (e) {
rawScene = options.scene ? String(options.scene) : ''
}
const sceneParams = {}
if (rawScene) {
rawScene.split('&').forEach((pair) => {
const [k, v] = pair.split('=')
if (k) sceneParams[k] = v || ''
})
}
const changed = mergeFromPageOptions(options, sceneParams)
const app = appInst || getApp()
if (changed && app && typeof app.silentLogin === 'function') {
app.silentLogin().catch(() => {})
}
}
/** 登录 POST 体片段 */
function getThirdPartyForLoginBody() {
try {
const app = getApp()
const ch = app.globalData.thirdPartyChannel || {}
const userid = String(ch.userid || '').trim()
const phone = String(ch.phone || '').trim()
const tid = String(ch.tid || '').trim()
if (!userid && !phone && !tid) return {}
const thirdParty = {}
if (userid) thirdParty.userid = userid
if (phone) thirdParty.phone = phone
if (tid) thirdParty.tid = tid
return { thirdParty }
} catch (e) {
return {}
}
}
module.exports = {
ingestThirdPartyFromLaunch,
ingestThirdPartyOnPageLoad,
mergeFromPageOptions,
mergeThirdPartyFromQuery,
getThirdPartyForLoginBody,
}