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:
Ghost
2026-03-31 15:26:21 +08:00
parent 3fdf9b6ed2
commit e672ad4ede
48 changed files with 1455 additions and 627 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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;

View File

@@ -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()
}

View File

@@ -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>

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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;