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:
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* 从服务端拉取启用题库,失败或为空时回落本地 questions.js;顺序由 shuffleQuestions 随机。
|
||||
* 仅从服务端拉取启用题库(/api/test/questions),无本地题目保底。
|
||||
* enterpriseId:未传时与 test/submit 一致,见 enterpriseContext.getEnterpriseIdForApiPayload()
|
||||
*/
|
||||
const { requestPromise } = require('./request')
|
||||
const { shuffleQuestions } = require('./questions')
|
||||
|
||||
function getAppSafe() {
|
||||
try {
|
||||
@@ -12,7 +12,45 @@ function getAppSafe() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 与 runtime 一致:>0 时在乱序后截取前 N 题 */
|
||||
/**
|
||||
* Fisher-Yates:打乱题目顺序,并随机每题选项顺序(深拷贝)
|
||||
* @param {Array} questions
|
||||
* @returns {Array}
|
||||
*/
|
||||
function shuffleQuestions(questions) {
|
||||
const arr = (questions || []).map(q => ({
|
||||
...q,
|
||||
options: (q.options || []).slice().sort(() => Math.random() - 0.5)
|
||||
}))
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
;[arr[i], arr[j]] = [arr[j], arr[i]]
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ enterpriseId?: number|null }} opts
|
||||
* @returns {number|null}
|
||||
*/
|
||||
function resolveEnterpriseIdForQuestionBank(opts) {
|
||||
const o = opts || {}
|
||||
if (Object.prototype.hasOwnProperty.call(o, 'enterpriseId')) {
|
||||
const v = o.enterpriseId
|
||||
if (v == null || v === '') {
|
||||
return null
|
||||
}
|
||||
const n = Number(v)
|
||||
return Number.isFinite(n) && n > 0 ? n : null
|
||||
}
|
||||
try {
|
||||
const { getEnterpriseIdForApiPayload } = require('./enterpriseContext')
|
||||
return getEnterpriseIdForApiPayload()
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function getTestQuestionDrawCount() {
|
||||
const app = getAppSafe()
|
||||
const n = app && app.globalData && app.globalData.testQuestionDrawCount
|
||||
@@ -60,23 +98,21 @@ function fetchQuestionBank(type, enterpriseId) {
|
||||
|
||||
/**
|
||||
* @param {'mbti'|'disc'|'pdp'} type
|
||||
* @param {Array} localQuestions
|
||||
* @param {{ enterpriseId?: number|null }} opts
|
||||
* @returns {Promise<Array>}
|
||||
* @returns {Promise<Array>} 乱序后的题目;接口无题或失败则 reject
|
||||
*/
|
||||
function loadQuestionsWithFallback(type, localQuestions, opts = {}) {
|
||||
const { enterpriseId } = opts
|
||||
return fetchQuestionBank(type, enterpriseId)
|
||||
.then((list) => {
|
||||
if (!list.length) {
|
||||
return applyDrawCountAfterShuffle(shuffleQuestions(localQuestions))
|
||||
}
|
||||
return shuffleQuestions(list)
|
||||
})
|
||||
.catch(() => applyDrawCountAfterShuffle(shuffleQuestions(localQuestions)))
|
||||
function loadQuestions(type, opts = {}) {
|
||||
const enterpriseId = resolveEnterpriseIdForQuestionBank(opts)
|
||||
return fetchQuestionBank(type, enterpriseId).then((list) => {
|
||||
if (!list.length) {
|
||||
throw new Error('暂无启用题目')
|
||||
}
|
||||
return applyDrawCountAfterShuffle(shuffleQuestions(list))
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchQuestionBank,
|
||||
loadQuestionsWithFallback
|
||||
loadQuestions,
|
||||
shuffleQuestions
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user