高考版优化
审核模式优化
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
const gaokaoApi = require('../../utils/gaokao')
|
||||
const app = getApp()
|
||||
const { isAuditHideAiMode, redirectIfMiniprogramAudit } = require('../../utils/miniprogramAuditGate.js')
|
||||
|
||||
/** 科类/选科备选项:首项为占位,不可作为有效保存值 */
|
||||
const SUBJECT_PLACEHOLDER = '请选择科类/选科'
|
||||
@@ -121,18 +119,7 @@ Page({
|
||||
|
||||
/** 每次页面展示拉取(含从上级页返回),避免栈内页面不触发 onLoad 时看不到已保存内容 */
|
||||
onShow() {
|
||||
const run = () => {
|
||||
if (isAuditHideAiMode(app.globalData)) {
|
||||
redirectIfMiniprogramAudit('版本审核中暂不可用')
|
||||
return
|
||||
}
|
||||
this.loadFormFromServer()
|
||||
}
|
||||
if (app.getRuntimeConfig) {
|
||||
app.getRuntimeConfig().finally(run)
|
||||
} else {
|
||||
run()
|
||||
}
|
||||
this.loadFormFromServer()
|
||||
},
|
||||
|
||||
loadFormFromServer() {
|
||||
|
||||
@@ -1,120 +1,146 @@
|
||||
const gaokaoApi = require('../../utils/gaokao')
|
||||
const app = getApp()
|
||||
const { isAuditHideAiMode, redirectIfMiniprogramAudit } = require('../../utils/miniprogramAuditGate.js')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loading: false,
|
||||
tasks: {
|
||||
mbti: { code: 'mbti', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'mbti', typeName: 'MBTI性格', emoji: '🧠', testTime: '' },
|
||||
pdp: { code: 'pdp', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'pdp', typeName: 'PDP行为', emoji: '🦁', testTime: '' },
|
||||
disc: { code: 'disc', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'disc', typeName: 'DISC测评', emoji: '📊', testTime: '' },
|
||||
face: { code: 'face', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'ai', typeName: '拍照面相', emoji: '📷', testTime: '', recordTestType: 'ai' },
|
||||
form: { code: 'form', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'form', typeName: '高考信息表单', emoji: '📝', testTime: '' }
|
||||
},
|
||||
canAnalyze: false,
|
||||
missingItems: [],
|
||||
analyzing: false
|
||||
statusBarHeight: 0,
|
||||
navbarHeight: 88,
|
||||
siteTitle: '高考版AI性格测试',
|
||||
startButtonGaokao: '开始面部测试',
|
||||
aiAnalysisText: '智能分析',
|
||||
maintenanceMode: false,
|
||||
reviewMode: false,
|
||||
permFace: true,
|
||||
showVersionPicker: false
|
||||
},
|
||||
|
||||
_navigateByVersion(version) {
|
||||
try {
|
||||
getApp().globalData.appScope = version || 'personal'
|
||||
getApp().globalData.selectedHomeVersion = version || 'personal'
|
||||
} catch (e) {}
|
||||
if (version === 'enterprise') {
|
||||
wx.navigateTo({ url: '/pages/enterprise/index' })
|
||||
return
|
||||
}
|
||||
if (version === 'gaokao') {
|
||||
wx.navigateTo({ url: '/pages/gaokao/index' })
|
||||
return
|
||||
}
|
||||
wx.switchTab({ url: '/pages/index/index' })
|
||||
},
|
||||
|
||||
openVersionPicker() {
|
||||
this.setData({ showVersionPicker: true })
|
||||
},
|
||||
|
||||
closeVersionPicker() {
|
||||
this.setData({ showVersionPicker: false })
|
||||
},
|
||||
|
||||
noop() {},
|
||||
|
||||
selectVersion(e) {
|
||||
const version = String(e.currentTarget.dataset.version || '')
|
||||
this.setData({ showVersionPicker: false })
|
||||
if (!version) return
|
||||
this._navigateByVersion(version)
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
try {
|
||||
app.globalData.appScope = 'gaokao'
|
||||
app.globalData.selectedHomeVersion = 'gaokao'
|
||||
} catch (e) {}
|
||||
try {
|
||||
require('../../utils/thirdPartyContext.js').ingestThirdPartyOnPageLoad(options || {}, app)
|
||||
} catch (e) {}
|
||||
const systemInfo = wx.getSystemInfoSync()
|
||||
const statusBarHeight = systemInfo.statusBarHeight || 0
|
||||
const screenWidth = systemInfo.screenWidth || 375
|
||||
const statusBarHeightRpx = (statusBarHeight * 750) / screenWidth
|
||||
const navbarHeightRpx = statusBarHeightRpx + 88
|
||||
const gd = app.globalData
|
||||
const maintenanceMode = !!(gd.reviewMode || gd.maintenanceMode)
|
||||
const ep = gd.enterprisePermissions
|
||||
const pf = !ep || ep.face !== false
|
||||
this.setData({
|
||||
statusBarHeight: statusBarHeightRpx,
|
||||
navbarHeight: navbarHeightRpx,
|
||||
siteTitle: gd.siteTitle || '高考版AI性格测试',
|
||||
startButtonGaokao: (maintenanceMode || !pf) ? '开始性格测试' : ((gd.textConfig && gd.textConfig.startButtonEnterprise) || '开始面部测试'),
|
||||
aiAnalysisText: (gd.textConfig && gd.textConfig.aiAnalysisText) || '智能分析',
|
||||
maintenanceMode,
|
||||
reviewMode: maintenanceMode,
|
||||
permFace: pf
|
||||
})
|
||||
},
|
||||
|
||||
onShow() {
|
||||
const run = () => {
|
||||
if (isAuditHideAiMode(app.globalData)) {
|
||||
redirectIfMiniprogramAudit('版本审核中暂不可用')
|
||||
return
|
||||
}
|
||||
this.refreshStatus()
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
const tabBar = this.getTabBar()
|
||||
if (typeof tabBar.updateSelected === 'function') tabBar.updateSelected()
|
||||
}
|
||||
if (app.getRuntimeConfig) {
|
||||
app.getRuntimeConfig().finally(run)
|
||||
} else {
|
||||
run()
|
||||
}
|
||||
},
|
||||
|
||||
refreshStatus() {
|
||||
this.setData({ loading: true })
|
||||
gaokaoApi
|
||||
.getTaskStatus({ scene: 'gaokao_hub' })
|
||||
.then((data) => {
|
||||
try {
|
||||
getApp().globalData.appScope = 'gaokao'
|
||||
getApp().globalData.selectedHomeVersion = 'gaokao'
|
||||
} catch (e) {}
|
||||
app.ensureLogin()
|
||||
.then(() => app.getRuntimeConfig())
|
||||
.then((cfg) => {
|
||||
if (cfg && cfg.siteTitle) {
|
||||
app.globalData.siteTitle = cfg.siteTitle
|
||||
}
|
||||
const gd = app.globalData
|
||||
const maintenanceMode = !!(gd.reviewMode || gd.maintenanceMode)
|
||||
const ep = gd.enterprisePermissions
|
||||
const pf = !ep || ep.face !== false
|
||||
this.setData({
|
||||
tasks: data.tasks || this.data.tasks,
|
||||
canAnalyze: !!data.canAnalyze,
|
||||
missingItems: data.missingItems || []
|
||||
siteTitle: gd.siteTitle || '高考版AI性格测试',
|
||||
startButtonGaokao: (maintenanceMode || !pf) ? '开始性格测试' : ((gd.textConfig && gd.textConfig.startButtonEnterprise) || '开始面部测试'),
|
||||
aiAnalysisText: (gd.textConfig && gd.textConfig.aiAnalysisText) || '智能分析',
|
||||
maintenanceMode,
|
||||
reviewMode: maintenanceMode,
|
||||
permFace: pf
|
||||
})
|
||||
})
|
||||
.catch((e) => {
|
||||
wx.showToast({ title: e.message || '加载失败', icon: 'none' })
|
||||
})
|
||||
.finally(() => this.setData({ loading: false }))
|
||||
.catch(() => {})
|
||||
},
|
||||
|
||||
goTask(e) {
|
||||
const code = e.currentTarget.dataset.code
|
||||
const resultId = Number(e.currentTarget.dataset.resultId || 0)
|
||||
const done = (e.currentTarget.dataset.status || '') === 'done'
|
||||
if (code === 'mbti') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/mbti?id=${resultId}&type=mbti` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/mbti' })
|
||||
}
|
||||
switchVersion() {
|
||||
const versions = (getApp().globalData.availableVersions || []).filter((v) => v === 'personal' || v === 'enterprise' || v === 'gaokao')
|
||||
if (versions.length >= 3) {
|
||||
this.openVersionPicker()
|
||||
return
|
||||
}
|
||||
if (code === 'pdp') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/pdp?id=${resultId}&type=pdp` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/pdp' })
|
||||
}
|
||||
this._navigateByVersion('personal')
|
||||
},
|
||||
|
||||
startAITest() {
|
||||
const ep = getApp().globalData.enterprisePermissions
|
||||
if (this.data.maintenanceMode || (ep && ep.face === false)) {
|
||||
wx.navigateTo({ url: '/pages/test-select/index' })
|
||||
return
|
||||
}
|
||||
if (code === 'disc') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/disc?id=${resultId}&type=disc` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/disc' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'face') {
|
||||
const recType = String(e.currentTarget.dataset.recordType || 'ai').toLowerCase()
|
||||
const typeParam = recType === 'face' ? 'face' : 'ai'
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/index/result?id=${resultId}&type=${typeParam}` })
|
||||
} else {
|
||||
wx.switchTab({ url: '/pages/index/camera' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'form') {
|
||||
wx.navigateTo({ url: '/pages/gaokao/form' })
|
||||
wx.switchTab({ url: '/pages/index/camera' })
|
||||
},
|
||||
|
||||
openTaskCenter() {
|
||||
wx.navigateTo({ url: '/pages/gaokao/task-center' })
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
const { getSharePath } = require('../../utils/share')
|
||||
return {
|
||||
title: '神仙团队AI性格测试 (高考版)',
|
||||
path: getSharePath('/pages/gaokao/index')
|
||||
}
|
||||
},
|
||||
|
||||
onAnalyzeTap() {
|
||||
if (!this.data.canAnalyze) {
|
||||
const nameMap = {
|
||||
mbti: 'MBTI测试',
|
||||
pdp: 'PDP测试',
|
||||
disc: 'DISC测试',
|
||||
face: '拍照面相',
|
||||
form: '高考信息表单'
|
||||
}
|
||||
const msg = (this.data.missingItems || []).map((k) => nameMap[k] || k).join('、')
|
||||
wx.showToast({
|
||||
title: msg ? `请先完成:${msg}` : '请先完成全部任务',
|
||||
icon: 'none',
|
||||
duration: 2500
|
||||
})
|
||||
return
|
||||
onShareTimeline() {
|
||||
const { buildShareQuery } = require('../../utils/share')
|
||||
return {
|
||||
title: '神仙团队AI性格测试 (高考版)',
|
||||
query: buildShareQuery()
|
||||
}
|
||||
this.setData({ analyzing: true })
|
||||
wx.navigateTo({
|
||||
url: '/pages/gaokao/report?pendingAnalyze=1',
|
||||
complete: () => {
|
||||
this.setData({ analyzing: false })
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"navigationBarTitleText": "高考志愿"
|
||||
"navigationStyle": "custom",
|
||||
"usingComponents": {
|
||||
"custom-tab-bar": "/custom-tab-bar/index"
|
||||
},
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +1,100 @@
|
||||
<view class="page">
|
||||
<view class="container">
|
||||
<view class="header">
|
||||
<view class="title">高考志愿任务中心</view>
|
||||
<view class="desc">完成 MBTI、PDP、DISC、拍照面相与高考信息表单后,即可生成综合分析;若定价非 0,请在报告页解锁全文(与问卷类测评一致)。</view>
|
||||
</view>
|
||||
|
||||
<view class="task-list">
|
||||
<view class="task-card" data-code="mbti" data-status="{{tasks.mbti.status}}" data-result-id="{{tasks.mbti.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.mbti.emoji}}</text>
|
||||
<text class="name">{{tasks.mbti.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.mbti.status==='done'}}">{{tasks.mbti.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.mbti.status==='done' && tasks.mbti.testTime}}">{{tasks.mbti.testTime}}</view>
|
||||
<view class="container" style="padding-top: {{navbarHeight}}px;">
|
||||
<view class="custom-navbar" style="padding-top: {{statusBarHeight}}rpx;">
|
||||
<view class="navbar-content">
|
||||
<view class="switch-version-btn" bindtap="switchVersion">
|
||||
<text class="switch-version-icon">🎓</text>
|
||||
<text class="switch-version-text">高考版</text>
|
||||
</view>
|
||||
<view class="status {{tasks.mbti.status==='done'?'done':''}}">{{tasks.mbti.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="pdp" data-status="{{tasks.pdp.status}}" data-result-id="{{tasks.pdp.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.pdp.emoji}}</text>
|
||||
<text class="name">{{tasks.pdp.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.pdp.status==='done'}}">{{tasks.pdp.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.pdp.status==='done' && tasks.pdp.testTime}}">{{tasks.pdp.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.pdp.status==='done'?'done':''}}">{{tasks.pdp.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="disc" data-status="{{tasks.disc.status}}" data-result-id="{{tasks.disc.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.disc.emoji}}</text>
|
||||
<text class="name">{{tasks.disc.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.disc.status==='done'}}">{{tasks.disc.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.disc.status==='done' && tasks.disc.testTime}}">{{tasks.disc.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.disc.status==='done'?'done':''}}">{{tasks.disc.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="face" data-status="{{tasks.face.status}}" data-result-id="{{tasks.face.testResultId}}" data-record-type="{{tasks.face.recordTestType}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.face.emoji}}</text>
|
||||
<text class="name">{{tasks.face.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.face.status==='done'}}">{{tasks.face.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去拍摄</view>
|
||||
<view class="task-time" wx:if="{{tasks.face.status==='done' && tasks.face.testTime}}">{{tasks.face.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.face.status==='done'?'done':''}}">{{tasks.face.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="form" data-status="{{tasks.form.status}}" data-result-id="{{tasks.form.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.form.emoji}}</text>
|
||||
<text class="name">{{tasks.form.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.form.status==='done'}}">
|
||||
<block wx:if="{{tasks.form.resultText}}">已填写:{{tasks.form.resultText}}</block>
|
||||
<block wx:else>已完成</block>
|
||||
</view>
|
||||
<view class="result todo" wx:else>未完成,请先填写</view>
|
||||
<view class="task-time" wx:if="{{tasks.form.status==='done' && tasks.form.testTime}}">{{tasks.form.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.form.status==='done'?'done':''}}">{{tasks.form.status==='done'?'查看结果':'去完成'}}</view>
|
||||
<view class="navbar-title">{{siteTitle || '高考版AI性格测试'}}</view>
|
||||
<view class="navbar-placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-decoration bg-top-right"></view>
|
||||
<view class="bg-decoration bg-bottom-left"></view>
|
||||
|
||||
<view class="top-image-section">
|
||||
<view class="image-container">
|
||||
<view class="image-wrapper">
|
||||
<image class="main-image" src="/images/mbti-team-image.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="float-tag tag-1" wx:if="{{!reviewMode && permFace}}">面相分析</view>
|
||||
<view class="float-tag tag-2" wx:if="{{!reviewMode && permFace}}">骨相分析</view>
|
||||
<view class="float-tag tag-3">性格测评</view>
|
||||
<view class="float-tag tag-1" wx:if="{{reviewMode}}">MBTI</view>
|
||||
<view class="float-tag tag-2" wx:if="{{reviewMode}}">DISC</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-actions">
|
||||
<button
|
||||
class="action-btn {{canAnalyze ? 'action-btn--primary' : 'action-btn--disabled'}}"
|
||||
loading="{{analyzing}}"
|
||||
bindtap="onAnalyzeTap"
|
||||
disabled="{{analyzing}}"
|
||||
>
|
||||
{{canAnalyze ? '开始综合分析' : '综合分析(未完成)'}}
|
||||
</button>
|
||||
<view class="process-section">
|
||||
<view class="section-title">测试流程</view>
|
||||
<view class="process-steps" wx:if="{{!reviewMode && permFace}}">
|
||||
<view class="step-item">
|
||||
<view class="step-circle active">1</view>
|
||||
<text class="step-label">STEP1</text>
|
||||
<text class="step-text">拍摄照片</text>
|
||||
</view>
|
||||
<view class="step-line"></view>
|
||||
<view class="step-item">
|
||||
<view class="step-circle">2</view>
|
||||
<text class="step-label">STEP2</text>
|
||||
<text class="step-text">{{aiAnalysisText || '分析'}}</text>
|
||||
</view>
|
||||
<view class="step-line"></view>
|
||||
<view class="step-item">
|
||||
<view class="step-circle">3</view>
|
||||
<text class="step-label">STEP3</text>
|
||||
<text class="step-text">生成报告</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="process-steps" wx:if="{{reviewMode || !permFace}}">
|
||||
<view class="step-item">
|
||||
<view class="step-circle active">1</view>
|
||||
<text class="step-label">STEP1</text>
|
||||
<text class="step-text">选择测试</text>
|
||||
</view>
|
||||
<view class="step-line"></view>
|
||||
<view class="step-item">
|
||||
<view class="step-circle">2</view>
|
||||
<text class="step-label">STEP2</text>
|
||||
<text class="step-text">回答问题</text>
|
||||
</view>
|
||||
<view class="step-line"></view>
|
||||
<view class="step-item">
|
||||
<view class="step-circle">3</view>
|
||||
<text class="step-label">STEP3</text>
|
||||
<text class="step-text">查看结果</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="start-button" bindtap="startAITest">
|
||||
<text class="button-text">{{startButtonGaokao || '开始性格测试'}}</text>
|
||||
</view>
|
||||
<view class="task-center-entry" bindtap="openTaskCenter">
|
||||
<text class="task-center-entry__icon">🗂️</text>
|
||||
<text class="task-center-entry__text">进入高考志愿任务中心(含历史记录)</text>
|
||||
<text class="task-center-entry__arrow">›</text>
|
||||
</view>
|
||||
|
||||
<view class="version-picker-mask" wx:if="{{showVersionPicker}}" bindtap="closeVersionPicker">
|
||||
<view class="version-picker-dialog" catchtap="noop">
|
||||
<view class="version-picker-head">
|
||||
<view class="version-picker-badge">版本选择</view>
|
||||
<view class="version-picker-close" bindtap="closeVersionPicker">×</view>
|
||||
</view>
|
||||
<view class="version-picker-title">请选择使用版本</view>
|
||||
<view class="version-picker-desc">当前企业支持三种版本,选择后将进入对应流程</view>
|
||||
<view class="version-picker-actions">
|
||||
<button class="version-btn version-btn-personal" data-version="personal" bindtap="selectVersion">个人版</button>
|
||||
<button class="version-btn version-btn-enterprise" data-version="enterprise" bindtap="selectVersion">企业版</button>
|
||||
<button class="version-btn version-btn-gaokao" data-version="gaokao" bindtap="selectVersion">高考版</button>
|
||||
</view>
|
||||
<view class="version-picker-foot">
|
||||
<button class="version-cancel-btn" bindtap="closeVersionPicker">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<custom-tab-bar />
|
||||
</view>
|
||||
|
||||
|
||||
@@ -1,142 +1,380 @@
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100%;
|
||||
background: #f7f8fc;
|
||||
padding: 32rpx 24rpx;
|
||||
/* 底部固定操作条占位(单主按钮 + 安全区) */
|
||||
padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.task-list {
|
||||
min-height: 100vh;
|
||||
width: 100vw;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background: #f3f6fb;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
padding-bottom: calc(100rpx + env(safe-area-inset-bottom) + 40rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.task-card {
|
||||
/* 背景装饰圆形 */
|
||||
.bg-decoration {
|
||||
position: absolute;
|
||||
width: 600rpx;
|
||||
height: 600rpx;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.bg-top-right {
|
||||
top: -200rpx;
|
||||
right: -200rpx;
|
||||
background: radial-gradient(circle, rgba(37, 99, 235, 0.08) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.bg-bottom-left {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: radial-gradient(circle, rgba(37, 99, 235, 0.05) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.custom-navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #ffffff;
|
||||
z-index: 10000;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navbar-content {
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 40rpx;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 22rpx 20rpx;
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
.navbar-title {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #1e3a8a;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.navbar-placeholder {
|
||||
width: 140rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.switch-version-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
background: #e8f0ff;
|
||||
border-radius: 30rpx;
|
||||
border: 1rpx solid rgba(37, 99, 235, 0.3);
|
||||
flex-shrink: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.switch-version-icon {
|
||||
font-size: 24rpx;
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.switch-version-text {
|
||||
font-size: 24rpx;
|
||||
color: #2563eb;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.top-image-section {
|
||||
width: 100%;
|
||||
padding: 15rpx 40rpx 20rpx;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-top: 100%;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.main-image {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 85%;
|
||||
height: 85%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.float-tag {
|
||||
position: absolute;
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 30rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #2563eb;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 4rpx 14rpx rgba(37, 99, 235, 0.12);
|
||||
white-space: nowrap;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.tag-1 {
|
||||
top: 15%;
|
||||
right: 10rpx;
|
||||
}
|
||||
|
||||
.tag-2 {
|
||||
bottom: 25%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.tag-3 {
|
||||
bottom: 25%;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.process-section {
|
||||
padding: 15rpx 40rpx 20rpx;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #2563eb;
|
||||
text-align: center;
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
.process-steps {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.step-circle {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 50%;
|
||||
background: #b8b9bc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.step-circle.active {
|
||||
background: #2563eb;
|
||||
}
|
||||
|
||||
.step-label {
|
||||
font-size: 20rpx;
|
||||
color: #9ca3af;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.step-text {
|
||||
font-size: 24rpx;
|
||||
color: #374151;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-line {
|
||||
width: 50rpx;
|
||||
height: 4rpx;
|
||||
background: #e0e0e0;
|
||||
margin: 0 6rpx 50rpx;
|
||||
}
|
||||
|
||||
.start-button {
|
||||
margin: 20rpx 40rpx 0;
|
||||
background: #2563eb;
|
||||
border-radius: 50rpx;
|
||||
padding: 24rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 8rpx 24rpx rgba(37, 99, 235, 0.2);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.task-center-entry {
|
||||
margin: 18rpx 36rpx 0;
|
||||
background: #ffffff;
|
||||
border: 1rpx solid #dbeafe;
|
||||
border-radius: 18rpx;
|
||||
padding: 22rpx 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 8rpx 18rpx rgba(37, 99, 235, 0.08);
|
||||
}
|
||||
|
||||
.task-center-entry__icon {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.task-center-entry__text {
|
||||
flex: 1;
|
||||
margin-left: 12rpx;
|
||||
color: #1e3a8a;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.task-center-entry__arrow {
|
||||
color: #93c5fd;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.button-text {
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.version-picker-mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(10, 15, 30, 0.52);
|
||||
z-index: 20000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.version-picker-dialog {
|
||||
width: 100%;
|
||||
max-width: 640rpx;
|
||||
background: #fff;
|
||||
border-radius: 30rpx;
|
||||
padding: 26rpx 30rpx 24rpx;
|
||||
box-shadow: 0 24rpx 70rpx rgba(16, 24, 40, 0.28);
|
||||
}
|
||||
|
||||
.version-picker-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.task-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
.version-picker-badge {
|
||||
padding: 8rpx 18rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #e8f0ff;
|
||||
color: #1d4ed8;
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.task-emoji {
|
||||
font-size: 36rpx;
|
||||
.version-picker-close {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 50%;
|
||||
background: #f3f4f6;
|
||||
color: #6b7280;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 34rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 30rpx;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
.version-picker-title {
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.task-time {
|
||||
margin-top: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 8rpx;
|
||||
.version-picker-desc {
|
||||
margin-top: 12rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
color: #6b7280;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.result--value {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #4f46e5;
|
||||
}
|
||||
|
||||
.result.todo {
|
||||
color: #d04848;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
.status.done {
|
||||
color: #1f9d55;
|
||||
}
|
||||
|
||||
/* 底部悬浮:全宽主操作 */
|
||||
.bottom-actions {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 200;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 16rpx 24rpx;
|
||||
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
box-shadow: 0 -8rpx 32rpx rgba(15, 23, 42, 0.08);
|
||||
border-top: 1rpx solid #eef0f4;
|
||||
.version-picker-actions {
|
||||
margin-top: 28rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100% !important;
|
||||
margin: 0;
|
||||
padding: 24rpx 32rpx;
|
||||
line-height: 1.35;
|
||||
border-radius: 16rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.action-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.action-btn--primary {
|
||||
background: #7c3aed;
|
||||
.version-btn {
|
||||
height: 84rpx;
|
||||
line-height: 84rpx;
|
||||
border-radius: 999rpx;
|
||||
color: #fff;
|
||||
font-size: 29rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
box-shadow: 0 6rpx 16rpx rgba(37, 99, 235, 0.16);
|
||||
}
|
||||
|
||||
.action-btn--disabled {
|
||||
background: #e5e7eb;
|
||||
color: #9ca3af;
|
||||
.version-btn-personal { background: #2563eb; }
|
||||
.version-btn-enterprise { background: #2563eb; }
|
||||
.version-btn-gaokao { background: #2563eb; }
|
||||
|
||||
.version-picker-foot {
|
||||
margin-top: 14rpx;
|
||||
}
|
||||
|
||||
.version-cancel-btn {
|
||||
height: 76rpx;
|
||||
line-height: 76rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #f3f4f6;
|
||||
color: #4b5563;
|
||||
font-size: 27rpx;
|
||||
font-weight: 600;
|
||||
border: 1rpx solid #d1d5db;
|
||||
}
|
||||
|
||||
custom-tab-bar {
|
||||
display: block;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ const inviteCodeGate = require('../../utils/inviteCodeGate.js')
|
||||
const { openTimelineShareHint } = require('../../utils/resultProfileGate.js')
|
||||
const { computeJourney, markShared } = require('../../utils/gaokaoJourneyState.js')
|
||||
const { getEnterpriseIdForApiPayload } = require('../../utils/enterpriseContext.js')
|
||||
const { isAuditHideAiMode, redirectIfMiniprogramAudit } = require('../../utils/miniprogramAuditGate.js')
|
||||
|
||||
/** GET /api/test/detail | share-detail 返回体 -> mergeApiReport 入参 */
|
||||
function mapTestDetailToReportPayload(detail) {
|
||||
@@ -242,60 +241,55 @@ Page({
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const bootstrap = () => {
|
||||
if (isAuditHideAiMode(app.globalData)) {
|
||||
redirectIfMiniprogramAudit('版本审核中暂不可用')
|
||||
return
|
||||
}
|
||||
try {
|
||||
wx.showShareMenu({ withShareTicket: true, menus: ['shareAppMessage', 'shareTimeline'] })
|
||||
} catch (e) {}
|
||||
try {
|
||||
wx.showShareMenu({ withShareTicket: true, menus: ['shareAppMessage', 'shareTimeline'] })
|
||||
} catch (e) {}
|
||||
|
||||
const fromShareFs = options && (String(options.fs) === '1' || options.from === 'share')
|
||||
const sid = options && options.id != null && options.id !== '' ? String(options.id) : ''
|
||||
const st = options && options.st ? String(options.st).trim() : ''
|
||||
const fromShareFs = options && (String(options.fs) === '1' || options.from === 'share')
|
||||
const sid = options && options.id != null && options.id !== '' ? String(options.id) : ''
|
||||
const st = options && options.st ? String(options.st).trim() : ''
|
||||
|
||||
if (sid && st) {
|
||||
this.setData({ fromShare: true })
|
||||
this.loadShareDetail(sid, st)
|
||||
return
|
||||
}
|
||||
|
||||
const ec =
|
||||
typeof this.getOpenerEventChannel === 'function' ? this.getOpenerEventChannel() : null
|
||||
if (ec && typeof ec.once === 'function') {
|
||||
ec.once('gaokaoAnalyzeReport', (payload) => {
|
||||
if (payload && payload.report) {
|
||||
this.applyPayloadOnly({
|
||||
id: payload.id,
|
||||
createdAt: payload.createdAt || 0,
|
||||
overview: payload.overview || '',
|
||||
report: payload.report
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const pendingAnalyze = options && String(options.pendingAnalyze) === '1'
|
||||
if (pendingAnalyze) {
|
||||
// 等 runtime 后再跑;用微任务启动分析,避免原 onReady 与异步 onLoad 竞态
|
||||
setTimeout(() => this.beginAnalyzeFlow(), 0)
|
||||
return
|
||||
}
|
||||
|
||||
const rid = options && options.id != null ? parseInt(String(options.id), 10) : 0
|
||||
this._detailReportId = rid > 0 && !Number.isNaN(rid) ? rid : 0
|
||||
if (fromShareFs) {
|
||||
this.setData({ fromShare: true })
|
||||
}
|
||||
|
||||
const delay = options && options.fromAnalyze === '1' ? 400 : 0
|
||||
setTimeout(() => this.load(), delay)
|
||||
if (sid && st) {
|
||||
this.setData({ fromShare: true })
|
||||
this.loadShareDetail(sid, st)
|
||||
return
|
||||
}
|
||||
if (app.getRuntimeConfig) {
|
||||
app.getRuntimeConfig().then(bootstrap).catch(bootstrap)
|
||||
} else {
|
||||
bootstrap()
|
||||
|
||||
const ec =
|
||||
typeof this.getOpenerEventChannel === 'function' ? this.getOpenerEventChannel() : null
|
||||
if (ec && typeof ec.once === 'function') {
|
||||
ec.once('gaokaoAnalyzeReport', (payload) => {
|
||||
if (payload && payload.report) {
|
||||
this.applyPayloadOnly({
|
||||
id: payload.id,
|
||||
createdAt: payload.createdAt || 0,
|
||||
overview: payload.overview || '',
|
||||
report: payload.report
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const pendingAnalyze = options && String(options.pendingAnalyze) === '1'
|
||||
if (pendingAnalyze) {
|
||||
this._pendingAnalyze = true
|
||||
return
|
||||
}
|
||||
|
||||
const rid = options && options.id != null ? parseInt(String(options.id), 10) : 0
|
||||
this._detailReportId = rid > 0 && !Number.isNaN(rid) ? rid : 0
|
||||
if (fromShareFs) {
|
||||
this.setData({ fromShare: true })
|
||||
}
|
||||
|
||||
const delay = options && options.fromAnalyze === '1' ? 400 : 0
|
||||
setTimeout(() => this.load(), delay)
|
||||
},
|
||||
|
||||
onReady() {
|
||||
if (this._pendingAnalyze) {
|
||||
this._pendingAnalyze = false
|
||||
this.beginAnalyzeFlow()
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
116
miniprogram/pages/gaokao/task-center.js
Normal file
116
miniprogram/pages/gaokao/task-center.js
Normal file
@@ -0,0 +1,116 @@
|
||||
const gaokaoApi = require('../../utils/gaokao')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loading: false,
|
||||
tasks: {
|
||||
mbti: { code: 'mbti', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'mbti', typeName: 'MBTI性格', emoji: '🧠', testTime: '' },
|
||||
pdp: { code: 'pdp', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'pdp', typeName: 'PDP行为', emoji: '🦁', testTime: '' },
|
||||
disc: { code: 'disc', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'disc', typeName: 'DISC测评', emoji: '📊', testTime: '' },
|
||||
face: { code: 'face', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'ai', typeName: '拍照面相', emoji: '📷', testTime: '', recordTestType: 'ai' },
|
||||
form: { code: 'form', status: 'todo', resultText: '', testResultId: 0, id: 0, testType: 'form', typeName: '高考信息表单', emoji: '📝', testTime: '' }
|
||||
},
|
||||
canAnalyze: false,
|
||||
missingItems: [],
|
||||
analyzing: false
|
||||
},
|
||||
|
||||
onShow() {
|
||||
try {
|
||||
const app = getApp()
|
||||
app.globalData.appScope = 'gaokao'
|
||||
app.globalData.selectedHomeVersion = 'gaokao'
|
||||
} catch (e) {}
|
||||
this.refreshStatus()
|
||||
},
|
||||
|
||||
refreshStatus() {
|
||||
this.setData({ loading: true })
|
||||
gaokaoApi
|
||||
.getTaskStatus({ scene: 'gaokao_hub' })
|
||||
.then((res) => {
|
||||
this.setData({
|
||||
tasks: res.tasks || this.data.tasks,
|
||||
canAnalyze: !!res.canAnalyze,
|
||||
missingItems: res.missingItems || []
|
||||
})
|
||||
})
|
||||
.catch((e) => {
|
||||
wx.showToast({ title: e.message || '加载失败', icon: 'none' })
|
||||
})
|
||||
.finally(() => this.setData({ loading: false }))
|
||||
},
|
||||
|
||||
goTask(e) {
|
||||
const code = e.currentTarget.dataset.code
|
||||
const resultId = Number(e.currentTarget.dataset.resultId || 0)
|
||||
const done = (e.currentTarget.dataset.status || '') === 'done'
|
||||
if (code === 'mbti') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/mbti?id=${resultId}&type=mbti&vscope=gaokao` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/mbti' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'pdp') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/pdp?id=${resultId}&type=pdp&vscope=gaokao` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/pdp' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'disc') {
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/result/disc?id=${resultId}&type=disc&vscope=gaokao` })
|
||||
} else {
|
||||
wx.navigateTo({ url: '/pages/test/disc' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'face') {
|
||||
const recType = String(e.currentTarget.dataset.recordType || 'ai').toLowerCase()
|
||||
const typeParam = recType === 'face' ? 'face' : 'ai'
|
||||
if (done && resultId > 0) {
|
||||
wx.navigateTo({ url: `/pages/index/result?id=${resultId}&type=${typeParam}&vscope=gaokao` })
|
||||
} else {
|
||||
wx.switchTab({ url: '/pages/index/camera' })
|
||||
}
|
||||
return
|
||||
}
|
||||
if (code === 'form') {
|
||||
wx.navigateTo({ url: '/pages/gaokao/form' })
|
||||
}
|
||||
},
|
||||
|
||||
onAnalyzeTap() {
|
||||
if (!this.data.canAnalyze) {
|
||||
const nameMap = {
|
||||
mbti: 'MBTI测试',
|
||||
pdp: 'PDP测试',
|
||||
disc: 'DISC测试',
|
||||
face: '拍照面相',
|
||||
form: '高考信息表单'
|
||||
}
|
||||
const msg = (this.data.missingItems || []).map((k) => nameMap[k] || k).join('、')
|
||||
wx.showToast({
|
||||
title: msg ? `请先完成:${msg}` : '请先完成全部任务',
|
||||
icon: 'none',
|
||||
duration: 2500
|
||||
})
|
||||
return
|
||||
}
|
||||
this.setData({ analyzing: true })
|
||||
wx.navigateTo({
|
||||
url: '/pages/gaokao/report?pendingAnalyze=1',
|
||||
complete: () => {
|
||||
this.setData({ analyzing: false })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
goHistoryTests() {
|
||||
wx.navigateTo({ url: '/pages/history/index?gaokaoOnly=1' })
|
||||
}
|
||||
})
|
||||
4
miniprogram/pages/gaokao/task-center.json
Normal file
4
miniprogram/pages/gaokao/task-center.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "高考志愿任务中心",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
93
miniprogram/pages/gaokao/task-center.wxml
Normal file
93
miniprogram/pages/gaokao/task-center.wxml
Normal file
@@ -0,0 +1,93 @@
|
||||
<view class="page">
|
||||
<view class="container">
|
||||
<view class="header">
|
||||
<view class="title">高考志愿任务中心</view>
|
||||
<view class="desc">完成 MBTI、PDP、DISC、拍照面相与高考信息表单后,即可生成综合分析;若定价非 0,请在报告页解锁全文(与问卷类测评一致)。</view>
|
||||
</view>
|
||||
|
||||
<view class="task-list">
|
||||
<view class="task-card" data-code="mbti" data-status="{{tasks.mbti.status}}" data-result-id="{{tasks.mbti.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.mbti.emoji}}</text>
|
||||
<text class="name">{{tasks.mbti.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.mbti.status==='done'}}">{{tasks.mbti.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.mbti.status==='done' && tasks.mbti.testTime}}">{{tasks.mbti.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.mbti.status==='done'?'done':''}}">{{tasks.mbti.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="pdp" data-status="{{tasks.pdp.status}}" data-result-id="{{tasks.pdp.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.pdp.emoji}}</text>
|
||||
<text class="name">{{tasks.pdp.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.pdp.status==='done'}}">{{tasks.pdp.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.pdp.status==='done' && tasks.pdp.testTime}}">{{tasks.pdp.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.pdp.status==='done'?'done':''}}">{{tasks.pdp.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="disc" data-status="{{tasks.disc.status}}" data-result-id="{{tasks.disc.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.disc.emoji}}</text>
|
||||
<text class="name">{{tasks.disc.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.disc.status==='done'}}">{{tasks.disc.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去测试</view>
|
||||
<view class="task-time" wx:if="{{tasks.disc.status==='done' && tasks.disc.testTime}}">{{tasks.disc.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.disc.status==='done'?'done':''}}">{{tasks.disc.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="face" data-status="{{tasks.face.status}}" data-result-id="{{tasks.face.testResultId}}" data-record-type="{{tasks.face.recordTestType}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.face.emoji}}</text>
|
||||
<text class="name">{{tasks.face.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.face.status==='done'}}">{{tasks.face.resultText || '已完成'}}</view>
|
||||
<view class="result todo" wx:else>未完成,请去拍摄</view>
|
||||
<view class="task-time" wx:if="{{tasks.face.status==='done' && tasks.face.testTime}}">{{tasks.face.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.face.status==='done'?'done':''}}">{{tasks.face.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
|
||||
<view class="task-card" data-code="form" data-status="{{tasks.form.status}}" data-result-id="{{tasks.form.testResultId}}" bindtap="goTask">
|
||||
<view class="left">
|
||||
<view class="task-title-row">
|
||||
<text class="task-emoji">{{tasks.form.emoji}}</text>
|
||||
<text class="name">{{tasks.form.typeName}}</text>
|
||||
</view>
|
||||
<view class="result result--value" wx:if="{{tasks.form.status==='done'}}">
|
||||
<block wx:if="{{tasks.form.resultText}}">已填写:{{tasks.form.resultText}}</block>
|
||||
<block wx:else>已完成</block>
|
||||
</view>
|
||||
<view class="result todo" wx:else>未完成,请先填写</view>
|
||||
<view class="task-time" wx:if="{{tasks.form.status==='done' && tasks.form.testTime}}">{{tasks.form.testTime}}</view>
|
||||
</view>
|
||||
<view class="status {{tasks.form.status==='done'?'done':''}}">{{tasks.form.status==='done'?'查看结果':'去完成'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="history-entry" bindtap="goHistoryTests">
|
||||
<text class="history-entry__text">历史测评记录</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bottom-actions">
|
||||
<button
|
||||
class="action-btn {{canAnalyze ? 'action-btn--primary' : 'action-btn--disabled'}}"
|
||||
loading="{{analyzing}}"
|
||||
bindtap="onAnalyzeTap"
|
||||
disabled="{{analyzing}}"
|
||||
>
|
||||
{{canAnalyze ? '开始综合分析' : '综合分析(未完成)'}}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
154
miniprogram/pages/gaokao/task-center.wxss
Normal file
154
miniprogram/pages/gaokao/task-center.wxss
Normal file
@@ -0,0 +1,154 @@
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100%;
|
||||
background: #f7f8fc;
|
||||
padding: 32rpx 24rpx;
|
||||
/* 底部固定操作条占位(单主按钮 + 安全区) */
|
||||
padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.task-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.task-card {
|
||||
background: #fff;
|
||||
border-radius: 14rpx;
|
||||
padding: 22rpx 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.task-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.task-emoji {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 30rpx;
|
||||
color: #222;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.task-time {
|
||||
margin-top: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.result--value {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #4f46e5;
|
||||
}
|
||||
|
||||
.result.todo {
|
||||
color: #d04848;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 24rpx;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
.status.done {
|
||||
color: #1f9d55;
|
||||
}
|
||||
|
||||
.history-entry {
|
||||
margin: 18rpx auto 0;
|
||||
width: 100%;
|
||||
padding: 8rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.history-entry__text {
|
||||
font-size: 24rpx;
|
||||
color: #9ca3af;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 底部悬浮:全宽主操作 */
|
||||
.bottom-actions {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 200;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 16rpx 24rpx;
|
||||
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
box-shadow: 0 -8rpx 32rpx rgba(15, 23, 42, 0.08);
|
||||
border-top: 1rpx solid #eef0f4;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 100% !important;
|
||||
margin: 0;
|
||||
padding: 24rpx 32rpx;
|
||||
line-height: 1.35;
|
||||
border-radius: 16rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.action-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.action-btn--primary {
|
||||
background: #7c3aed;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.action-btn--disabled {
|
||||
background: #e5e7eb;
|
||||
color: #9ca3af;
|
||||
}
|
||||
Reference in New Issue
Block a user