feat: 双端题库统一与 PDP/DISC 结果文案、测评 API 与企测上下文
1、修复了测评/结果页与个人中心展示不一致问题;废弃独立 questions.js,统一使用 questionBank;结果格式与详情解析相关问题。 2、新增了 PdpDiscResultText(PDP+DISC 双类型摘要文案)、抖音 questionBank 与 enterpriseContext;扩展 api/Test 与路由、管理端 Order 与 ExtractsTestResults。 3、优化了 resultFormat 与 questionBank 组织方式、UserDetailDialog;移除不再使用的 mbti_test_results 恢复 SQL/脚本。 Made-with: Cursor
This commit is contained in:
@@ -3,6 +3,17 @@ const app = getApp()
|
||||
const { getTypeOnly } = require('../../utils/resultFormat')
|
||||
const { request } = require('../../utils/request')
|
||||
|
||||
/** recent 单条:优先用 resultMeta 与结果页一致的「双项」文案 */
|
||||
function summaryFromRecentRecord(rec, testType) {
|
||||
if (!rec) return ''
|
||||
const meta = rec.resultMeta
|
||||
if (meta && typeof meta === 'object') {
|
||||
const t = getTypeOnly(meta, testType)
|
||||
if (t) return t
|
||||
}
|
||||
return String(rec.resultText || '').trim()
|
||||
}
|
||||
|
||||
Page({
|
||||
data: {
|
||||
hasLogin: false,
|
||||
@@ -47,19 +58,18 @@ Page({
|
||||
permPdp: true,
|
||||
permDisc: true,
|
||||
permDistribution: true,
|
||||
/** 最新测试横滑区:仅有已出结果的卡片时才显示,避免禁权或未测评占位 */
|
||||
showLatestTestCards: false,
|
||||
/** 最新测试横滑区:有问卷/面相权限即显示;无记录时卡片灰阶占位,不隐藏 */
|
||||
showLatestTestRow: false,
|
||||
/** 用户卡片下性格标签:在「当前权限下无任何问卷结果」时显示灰色提示 */
|
||||
showEmptyPersonalityTags: true
|
||||
},
|
||||
|
||||
_computeShowLatestTestCards(d) {
|
||||
_computeShowLatestTestRow(d) {
|
||||
const rm = !!(d.reviewMode)
|
||||
if (d.permMbti && d.mbtiType) return true
|
||||
if (d.permPdp && d.pdpType) return true
|
||||
if (d.permDisc && d.discType) return true
|
||||
if (!rm && d.permFace && (d.gallupPreview || d.aiType)) return true
|
||||
return false
|
||||
if (rm) {
|
||||
return !!(d.permMbti || d.permPdp || d.permDisc)
|
||||
}
|
||||
return !!(d.permMbti || d.permPdp || d.permDisc || d.permFace)
|
||||
},
|
||||
|
||||
_computeShowEmptyPersonalityTags(d) {
|
||||
@@ -83,7 +93,7 @@ Page({
|
||||
const d = { ...this.data, ...next }
|
||||
this.setData({
|
||||
...next,
|
||||
showLatestTestCards: this._computeShowLatestTestCards(d),
|
||||
showLatestTestRow: this._computeShowLatestTestRow(d),
|
||||
showEmptyPersonalityTags: this._computeShowEmptyPersonalityTags(d)
|
||||
})
|
||||
},
|
||||
@@ -203,8 +213,7 @@ Page({
|
||||
const { records = {}, totalCount = 0 } = payload.data
|
||||
const r = records
|
||||
|
||||
// DISC resultText 后端已含「型」,type badge 只显示字母,去掉「型」
|
||||
const discType = r.disc ? r.disc.resultText.replace(/型$/, '') : ''
|
||||
const discType = summaryFromRecentRecord(r.disc, 'disc')
|
||||
|
||||
const gallupPreview = (r.ai && r.ai.gallupPreview) ? String(r.ai.gallupPreview) : ''
|
||||
const patch = {
|
||||
@@ -212,7 +221,7 @@ Page({
|
||||
hasResults: !!(r.mbti || r.disc || r.pdp || r.ai),
|
||||
mbtiType: r.mbti ? r.mbti.resultText : '',
|
||||
discType,
|
||||
pdpType: r.pdp ? r.pdp.resultText : '',
|
||||
pdpType: summaryFromRecentRecord(r.pdp, 'pdp'),
|
||||
aiType: r.ai ? r.ai.resultText : '',
|
||||
gallupPreview,
|
||||
mbtiTime: r.mbti ? r.mbti.testTime : '',
|
||||
@@ -227,7 +236,7 @@ Page({
|
||||
const d = { ...this.data, ...patch }
|
||||
this.setData({
|
||||
...patch,
|
||||
showLatestTestCards: this._computeShowLatestTestCards(d),
|
||||
showLatestTestRow: this._computeShowLatestTestRow(d),
|
||||
showEmptyPersonalityTags: this._computeShowEmptyPersonalityTags(d)
|
||||
})
|
||||
},
|
||||
@@ -303,7 +312,7 @@ Page({
|
||||
const d = { ...this.data, ...patch }
|
||||
this.setData({
|
||||
...patch,
|
||||
showLatestTestCards: this._computeShowLatestTestCards(d),
|
||||
showLatestTestRow: this._computeShowLatestTestRow(d),
|
||||
showEmptyPersonalityTags: this._computeShowEmptyPersonalityTags(d)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<text class="tag-text">{{mbtiType}}</text>
|
||||
</view>
|
||||
<view class="tag tag-blue" wx:if="{{discType && permDisc}}">
|
||||
<text class="tag-text">{{discType}}型</text>
|
||||
<text class="tag-text">{{discType}}</text>
|
||||
</view>
|
||||
<view class="tag tag-orange" wx:if="{{pdpType && permPdp}}">
|
||||
<text class="tag-text">{{pdpType}}</text>
|
||||
@@ -79,56 +79,56 @@
|
||||
<text class="depth-header-chevron">›</text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view wx:if="{{showLatestTestCards}}" scroll-x class="cards-scroll cards-scroll--in-card" enhanced show-scrollbar="{{false}}">
|
||||
<scroll-view wx:if="{{showLatestTestRow}}" scroll-x class="cards-scroll cards-scroll--in-card" enhanced show-scrollbar="{{false}}">
|
||||
<view class="cards-row cards-row--in-card">
|
||||
<view class="result-card card-purple" bindtap="viewMBTI" wx:if="{{permMbti && mbtiType}}">
|
||||
<view class="result-card card-purple {{mbtiType ? '' : 'result-card--placeholder'}}" bindtap="viewMBTI" wx:if="{{permMbti}}">
|
||||
<view class="card-deco"></view>
|
||||
<view class="card-icon-wrap card-icon-purple">
|
||||
<text class="card-icon">🧠</text>
|
||||
</view>
|
||||
<text class="card-label">MBTI性格</text>
|
||||
<text class="card-value">{{mbtiType}}</text>
|
||||
<text class="card-time">{{mbtiTime}}</text>
|
||||
<text class="card-value">{{mbtiType || '未测评'}}</text>
|
||||
<text class="card-time">{{mbtiTime || '—'}}</text>
|
||||
</view>
|
||||
<view class="result-card card-orange" bindtap="viewPDP" wx:if="{{permPdp && pdpType}}">
|
||||
<view class="result-card card-orange {{pdpType ? '' : 'result-card--placeholder'}}" bindtap="viewPDP" wx:if="{{permPdp}}">
|
||||
<view class="card-deco"></view>
|
||||
<view class="card-icon-wrap card-icon-orange">
|
||||
<text class="card-icon">🦁</text>
|
||||
</view>
|
||||
<text class="card-label">PDP行为</text>
|
||||
<text class="card-value">{{pdpType}}</text>
|
||||
<text class="card-time">{{pdpTime}}</text>
|
||||
<text class="card-value">{{pdpType || '未测评'}}</text>
|
||||
<text class="card-time">{{pdpTime || '—'}}</text>
|
||||
</view>
|
||||
<view class="result-card card-blue" bindtap="viewDISC" wx:if="{{permDisc && discType}}">
|
||||
<view class="result-card card-blue {{discType ? '' : 'result-card--placeholder'}}" bindtap="viewDISC" wx:if="{{permDisc}}">
|
||||
<view class="card-deco"></view>
|
||||
<view class="card-icon-wrap card-icon-blue">
|
||||
<text class="card-icon">📊</text>
|
||||
</view>
|
||||
<text class="card-label">DISC测评</text>
|
||||
<text class="card-value">{{discType + '型'}}</text>
|
||||
<text class="card-time">{{discTime}}</text>
|
||||
<text class="card-value">{{discType || '未测评'}}</text>
|
||||
<text class="card-time">{{discTime || '—'}}</text>
|
||||
</view>
|
||||
<view class="result-card card-teal" bindtap="viewGallup" wx:if="{{!reviewMode && permFace && (gallupPreview || aiType)}}">
|
||||
<view class="result-card card-teal {{(gallupPreview || aiType) ? '' : 'result-card--placeholder'}}" bindtap="viewGallup" wx:if="{{!reviewMode && permFace}}">
|
||||
<view class="card-deco"></view>
|
||||
<view class="card-icon-wrap card-icon-teal">
|
||||
<text class="card-icon">⭐</text>
|
||||
</view>
|
||||
<text class="card-label">盖洛普优势</text>
|
||||
<text class="card-value card-value--small">{{gallupPreview || '见面相报告'}}</text>
|
||||
<text class="card-time">{{aiTime}}</text>
|
||||
<text class="card-value card-value--small">{{gallupPreview || (aiType ? '见面相报告' : '未测评')}}</text>
|
||||
<text class="card-time">{{aiTime || '—'}}</text>
|
||||
</view>
|
||||
<view class="result-card card-rose" bindtap="viewAI" wx:if="{{!reviewMode && permFace && aiType}}">
|
||||
<view class="result-card card-rose {{aiType ? '' : 'result-card--placeholder'}}" bindtap="viewAI" wx:if="{{!reviewMode && permFace}}">
|
||||
<view class="card-deco"></view>
|
||||
<view class="card-icon-wrap card-icon-rose">
|
||||
<text class="card-icon">👁️</text>
|
||||
</view>
|
||||
<text class="card-label">面相分析</text>
|
||||
<text class="card-value">{{aiType}}</text>
|
||||
<text class="card-time">{{aiTime}}</text>
|
||||
<text class="card-value">{{aiType || '未测评'}}</text>
|
||||
<text class="card-time">{{aiTime || '—'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view wx:if="{{showLatestTestCards}}" class="depth-empty-hint depth-empty-hint--compact">
|
||||
<view wx:if="{{showLatestTestRow}}" class="depth-empty-hint depth-empty-hint--compact">
|
||||
<text>点击卡片查看详情;右上方可查看全部测试记录。</text>
|
||||
</view>
|
||||
<view class="depth-inner-divider"></view>
|
||||
|
||||
@@ -467,6 +467,15 @@ custom-tab-bar {
|
||||
letter-spacing: -1rpx;
|
||||
}
|
||||
|
||||
/* 与 MBTI 同字号;长文案(如 PDP/DISC 双项)最多两行 */
|
||||
.result-card .card-value {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.card-purple .card-value { color: #7C3AED; }
|
||||
.card-blue .card-value { color: #2563EB; }
|
||||
.card-orange .card-value { color: #D97706; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// pages/result/disc.js - DISC结果页(支持付费墙 + 历史详情拉取)
|
||||
const app = getApp()
|
||||
const payment = require('../../utils/payment')
|
||||
const { getTypeOnly } = require('../../utils/resultFormat')
|
||||
|
||||
function toIntPercent(v) {
|
||||
if (v == null) return 0
|
||||
@@ -24,6 +25,8 @@ function withPercentagesInt(data) {
|
||||
Page({
|
||||
data: {
|
||||
result: null,
|
||||
/** 主+次高权重展示(如 S+I型),与接口摘要一致 */
|
||||
typeSummaryLine: '',
|
||||
typeList: [
|
||||
{ type: 'D', label: 'D型 - 支配型', colorClass: 'fill-d' },
|
||||
{ type: 'I', label: 'I型 - 影响型', colorClass: 'fill-i' },
|
||||
@@ -45,7 +48,8 @@ Page({
|
||||
}
|
||||
const result = wx.getStorageSync('discResult')
|
||||
if (result) {
|
||||
this.setData({ result: withPercentagesInt(result) })
|
||||
const r = withPercentagesInt(result)
|
||||
this.setData({ result: r, typeSummaryLine: getTypeOnly(result, 'disc') })
|
||||
this.initPayInfoFromRuntime('disc')
|
||||
} else {
|
||||
wx.showToast({ title: '暂无测试结果', icon: 'none' })
|
||||
@@ -71,7 +75,11 @@ Page({
|
||||
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 r = withPercentagesInt(data)
|
||||
this.setData({
|
||||
result: r,
|
||||
typeSummaryLine: getTypeOnly(data, 'disc')
|
||||
})
|
||||
const payInfo = {
|
||||
requiresPayment: needPaymentToUnlock,
|
||||
isPaid,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<view class="type-card">
|
||||
<view class="type-header">
|
||||
<text class="type-label">您的DISC性格类型</text>
|
||||
<text class="type-value">{{result.dominantType}}{{result.secondaryType ? ' + ' + result.secondaryType : ''}}</text>
|
||||
<text class="type-value">{{typeSummaryLine}}</text>
|
||||
<text class="type-description" wx:if="{{result.description && result.description.description}}">{{result.description.description}}</text>
|
||||
</view>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// pages/result/pdp.js - PDP结果页(支持付费墙 + 历史详情拉取)
|
||||
const app = getApp()
|
||||
const payment = require('../../utils/payment')
|
||||
const { getTypeOnly } = require('../../utils/resultFormat')
|
||||
|
||||
const PDP_KEYS = ['Tiger', 'Peacock', 'Koala', 'Owl', 'Chameleon']
|
||||
|
||||
@@ -23,6 +24,7 @@ function withPercentagesInt(data) {
|
||||
Page({
|
||||
data: {
|
||||
result: null,
|
||||
typeSummaryLine: '',
|
||||
typeList: [
|
||||
{ type: 'Tiger', emoji: '🐅', label: '老虎型', colorClass: 'fill-tiger' },
|
||||
{ type: 'Peacock', emoji: '🦚', label: '孔雀型', colorClass: 'fill-peacock' },
|
||||
@@ -45,7 +47,10 @@ Page({
|
||||
}
|
||||
const result = wx.getStorageSync('pdpResult')
|
||||
if (result) {
|
||||
this.setData({ result: withPercentagesInt(result) })
|
||||
this.setData({
|
||||
result: withPercentagesInt(result),
|
||||
typeSummaryLine: getTypeOnly(result, 'pdp')
|
||||
})
|
||||
this.initPayInfoFromRuntime('pdp')
|
||||
} else {
|
||||
wx.showToast({ title: '暂无测试结果', icon: 'none' })
|
||||
@@ -71,7 +76,10 @@ Page({
|
||||
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) })
|
||||
this.setData({
|
||||
result: withPercentagesInt(data),
|
||||
typeSummaryLine: getTypeOnly(data, 'pdp')
|
||||
})
|
||||
const payInfo = {
|
||||
requiresPayment: needPaymentToUnlock,
|
||||
isPaid,
|
||||
@@ -138,19 +146,19 @@ Page({
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
const result = this.data.result
|
||||
const line = this.data.typeSummaryLine || this.data.result?.description?.type || ''
|
||||
const { getSharePathByScope } = require('../../utils/share')
|
||||
return {
|
||||
title: `我的PDP类型是${result?.description?.type}${result?.description?.emoji},来测测你的吧!`,
|
||||
title: `我的PDP类型是${line},来测测你的吧!`,
|
||||
path: getSharePathByScope('/pages/index/index')
|
||||
}
|
||||
},
|
||||
|
||||
onShareTimeline() {
|
||||
const result = this.data.result
|
||||
const line = this.data.typeSummaryLine || this.data.result?.description?.type || ''
|
||||
const { buildShareQuery } = require('../../utils/share')
|
||||
return {
|
||||
title: `我的PDP类型是${result?.description?.type}${result?.description?.emoji},来测测你的吧!`,
|
||||
title: `我的PDP类型是${line},来测测你的吧!`,
|
||||
query: buildShareQuery()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<view class="type-card">
|
||||
<view class="type-header">
|
||||
<text class="type-label">PDP性格类型</text>
|
||||
<text class="type-value">{{result.description.type || result.dominantType}}{{result.description.emoji || ''}}</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>
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
// pages/test/disc.js
|
||||
const { discQuestions, shuffleQuestions } = require('../../utils/questions')
|
||||
const { loadQuestions } = require('../../utils/questionBank')
|
||||
const { discDescriptions } = require('../../utils/descriptions')
|
||||
const app = getApp()
|
||||
|
||||
const DISC_TIME_SEC = 15 * 60
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loading: true,
|
||||
questions: [],
|
||||
currentIndex: 0,
|
||||
currentQuestion: null,
|
||||
answers: {},
|
||||
selectedAnswer: null,
|
||||
total: discQuestions.length,
|
||||
total: 0,
|
||||
answeredCount: 0,
|
||||
progress: 0,
|
||||
timeRemaining: 15 * 60,
|
||||
timeRemaining: DISC_TIME_SEC,
|
||||
_initialSeconds: DISC_TIME_SEC,
|
||||
formatTime: '15:00',
|
||||
isSubmitting: false
|
||||
},
|
||||
@@ -21,10 +25,31 @@ Page({
|
||||
timer: null,
|
||||
|
||||
onLoad() {
|
||||
const questions = shuffleQuestions(discQuestions)
|
||||
this.setData({ questions, currentQuestion: questions[0] })
|
||||
try { require('../../utils/analytics').track('test_start', { type: 'disc', total: questions.length }) } catch (e) {}
|
||||
this.startTimer()
|
||||
loadQuestions('disc', {})
|
||||
.then((questions) => {
|
||||
if (!questions.length) {
|
||||
wx.showToast({ title: '暂无题目', icon: 'none' })
|
||||
this.setData({ loading: false })
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
loading: false,
|
||||
questions,
|
||||
currentQuestion: questions[0],
|
||||
total: questions.length,
|
||||
timeRemaining: DISC_TIME_SEC,
|
||||
_initialSeconds: DISC_TIME_SEC,
|
||||
formatTime: '15:00'
|
||||
})
|
||||
try {
|
||||
require('../../utils/analytics').track('test_start', { type: 'disc', total: questions.length })
|
||||
} catch (e) {}
|
||||
this.startTimer()
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: (err && err.message) || '加载失败', icon: 'none' })
|
||||
})
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
@@ -148,7 +173,7 @@ Page({
|
||||
dominantType,
|
||||
secondaryType,
|
||||
description: discDescriptions[dominantType],
|
||||
testDuration: 15 * 60 - this.data.timeRemaining,
|
||||
testDuration: (this.data._initialSeconds || DISC_TIME_SEC) - this.data.timeRemaining,
|
||||
completedAt: new Date().toISOString(),
|
||||
// 便于后端留存完整答题过程
|
||||
answers: this.data.answers
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<!--pages/test/disc.wxml - DISC测试页面(按旧版模板重构)-->
|
||||
<view class="test-page">
|
||||
<view wx:if="{{loading}}" class="test-loading">
|
||||
<text class="test-loading-text">加载题目…</text>
|
||||
</view>
|
||||
<block wx:elif="{{currentQuestion}}">
|
||||
<view class="progress-section">
|
||||
<view class="progress-info">
|
||||
<text class="question-count">问题 {{currentIndex + 1}}/{{total}}</text>
|
||||
@@ -45,4 +49,5 @@
|
||||
<text class="submit-text">{{isSubmitting ? '计算中...' : '完成测试,查看结果'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.test-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx;
|
||||
}
|
||||
|
||||
.test-loading-text {
|
||||
font-size: 30rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
// pages/test/mbti.js - MBTI测试页面逻辑
|
||||
const { mbtiQuestions, shuffleQuestions } = require('../../utils/questions')
|
||||
const { loadQuestions } = require('../../utils/questionBank')
|
||||
const { mbtiDescriptions } = require('../../utils/descriptions')
|
||||
const payment = require('../../utils/payment')
|
||||
const app = getApp()
|
||||
|
||||
const MBTI_TIME_SEC = 30 * 60 // 30 分钟
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loading: true,
|
||||
questions: [],
|
||||
currentIndex: 0,
|
||||
currentQuestion: null,
|
||||
answers: {},
|
||||
selectedAnswer: null,
|
||||
total: mbtiQuestions.length,
|
||||
total: 0,
|
||||
answeredCount: 0,
|
||||
progress: 0,
|
||||
timeRemaining: 30 * 60, // 30分钟
|
||||
timeRemaining: MBTI_TIME_SEC,
|
||||
_initialSeconds: MBTI_TIME_SEC,
|
||||
formatTime: '30:00',
|
||||
isSubmitting: false,
|
||||
canAccess: false
|
||||
@@ -23,17 +27,34 @@ Page({
|
||||
timer: null,
|
||||
|
||||
onLoad() {
|
||||
const questions = shuffleQuestions(mbtiQuestions)
|
||||
const total = questions.length
|
||||
this.setData({
|
||||
questions,
|
||||
currentQuestion: questions[0],
|
||||
canAccess: true,
|
||||
total,
|
||||
progress: total ? Math.round((1 / total) * 100) : 0
|
||||
})
|
||||
try { require('../../utils/analytics').track('test_start', { type: 'mbti', total }) } catch (e) {}
|
||||
this.startTimer()
|
||||
loadQuestions('mbti', {})
|
||||
.then((questions) => {
|
||||
const total = questions.length
|
||||
if (!total) {
|
||||
wx.showToast({ title: '暂无题目', icon: 'none' })
|
||||
this.setData({ loading: false })
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
loading: false,
|
||||
questions,
|
||||
currentQuestion: questions[0],
|
||||
canAccess: true,
|
||||
total,
|
||||
progress: Math.round((1 / total) * 100),
|
||||
timeRemaining: MBTI_TIME_SEC,
|
||||
_initialSeconds: MBTI_TIME_SEC,
|
||||
formatTime: '30:00'
|
||||
})
|
||||
try {
|
||||
require('../../utils/analytics').track('test_start', { type: 'mbti', total })
|
||||
} catch (e) {}
|
||||
this.startTimer()
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: (err && err.message) || '加载失败', icon: 'none' })
|
||||
})
|
||||
},
|
||||
|
||||
// 检查访问权限
|
||||
@@ -197,7 +218,7 @@ Page({
|
||||
const resultData = {
|
||||
...result,
|
||||
answers: this.data.answers,
|
||||
testDuration: 30 * 60 - this.data.timeRemaining,
|
||||
testDuration: (this.data._initialSeconds || MBTI_TIME_SEC) - this.data.timeRemaining,
|
||||
completedAt: new Date().toISOString(),
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<!--pages/test/mbti.wxml - MBTI测试页面(按旧版模板重构)-->
|
||||
<view class="test-page">
|
||||
<view wx:if="{{loading}}" class="test-loading">
|
||||
<text class="test-loading-text">加载题目…</text>
|
||||
</view>
|
||||
<block wx:elif="{{currentQuestion}}">
|
||||
<view class="progress-section">
|
||||
<view class="progress-info">
|
||||
<text class="question-count">问题 {{currentIndex + 1}}/{{total}}</text>
|
||||
@@ -45,4 +49,5 @@
|
||||
<text class="button-text button-text-on-primary">{{isSubmitting ? '正在生成…' : '查看结果'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.test-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx;
|
||||
}
|
||||
|
||||
.test-loading-text {
|
||||
font-size: 30rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
// pages/test/pdp.js
|
||||
const { pdpQuestions, shuffleQuestions } = require('../../utils/questions')
|
||||
const { loadQuestions } = require('../../utils/questionBank')
|
||||
const { pdpDescriptions } = require('../../utils/descriptions')
|
||||
const app = getApp()
|
||||
|
||||
const PDP_TIME_SEC = 15 * 60
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loading: true,
|
||||
questions: [],
|
||||
currentIndex: 0,
|
||||
currentQuestion: null,
|
||||
answers: {},
|
||||
selectedAnswer: null,
|
||||
total: pdpQuestions.length,
|
||||
total: 0,
|
||||
answeredCount: 0,
|
||||
progress: 0,
|
||||
timeRemaining: 15 * 60,
|
||||
timeRemaining: PDP_TIME_SEC,
|
||||
_initialSeconds: PDP_TIME_SEC,
|
||||
formatTime: '15:00',
|
||||
isSubmitting: false
|
||||
},
|
||||
@@ -21,10 +25,31 @@ Page({
|
||||
timer: null,
|
||||
|
||||
onLoad() {
|
||||
const questions = shuffleQuestions(pdpQuestions)
|
||||
this.setData({ questions, currentQuestion: questions[0] })
|
||||
try { require('../../utils/analytics').track('test_start', { type: 'pdp', total: questions.length }) } catch (e) {}
|
||||
this.startTimer()
|
||||
loadQuestions('pdp', {})
|
||||
.then((questions) => {
|
||||
if (!questions.length) {
|
||||
wx.showToast({ title: '暂无题目', icon: 'none' })
|
||||
this.setData({ loading: false })
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
loading: false,
|
||||
questions,
|
||||
currentQuestion: questions[0],
|
||||
total: questions.length,
|
||||
timeRemaining: PDP_TIME_SEC,
|
||||
_initialSeconds: PDP_TIME_SEC,
|
||||
formatTime: '15:00'
|
||||
})
|
||||
try {
|
||||
require('../../utils/analytics').track('test_start', { type: 'pdp', total: questions.length })
|
||||
} catch (e) {}
|
||||
this.startTimer()
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: (err && err.message) || '加载失败', icon: 'none' })
|
||||
})
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
@@ -151,7 +176,7 @@ Page({
|
||||
dominantType,
|
||||
secondaryType,
|
||||
description: pdpDescriptions[dominantType],
|
||||
testDuration: 15 * 60 - this.data.timeRemaining,
|
||||
testDuration: (this.data._initialSeconds || PDP_TIME_SEC) - this.data.timeRemaining,
|
||||
completedAt: new Date().toISOString(),
|
||||
// 便于后端留存完整答题过程
|
||||
answers: this.data.answers
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<!--pages/test/pdp.wxml - PDP测试页面(按旧版模板重构)-->
|
||||
<view class="test-page">
|
||||
<view wx:if="{{loading}}" class="test-loading">
|
||||
<text class="test-loading-text">加载题目…</text>
|
||||
</view>
|
||||
<block wx:elif="{{currentQuestion}}">
|
||||
<view class="progress-section">
|
||||
<view class="progress-info">
|
||||
<text class="question-count">问题 {{currentIndex + 1}}/{{total}}</text>
|
||||
@@ -45,4 +49,5 @@
|
||||
<text class="submit-text">{{isSubmitting ? '计算中...' : '完成测试,查看结果'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.test-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx;
|
||||
}
|
||||
|
||||
.test-loading-text {
|
||||
font-size: 30rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
|
||||
Reference in New Issue
Block a user