diff --git a/uniapp/pages/assessment/info/index.vue b/uniapp/pages/assessment/info/index.vue index ccf1532..8630cd3 100644 --- a/uniapp/pages/assessment/info/index.vue +++ b/uniapp/pages/assessment/info/index.vue @@ -10,12 +10,12 @@ * - 进行中测评记录恢复(断点续答) */ -import { ref, computed, watch } from 'vue' -import { onLoad, onUnload } from '@dcloudio/uni-app' +import { ref, computed } from 'vue' +import { onLoad } from '@dcloudio/uni-app' import { useUserStore } from '@/store/user.js' import { useAuth } from '@/composables/useAuth.js' import { usePayment } from '@/composables/usePayment.js' -import { getIntro, verifyInviteCode } from '@/api/assessment.js' +import { getIntro, verifyInviteCode, getPendingRecord } from '@/api/assessment.js' import { createOrder } from '@/api/order.js' import { isPhone } from '@/utils/validate.js' import Navbar from '@/components/Navbar/index.vue' @@ -80,68 +80,79 @@ const inviteLoading = ref(false) // 页面加载状态 const pageLoading = ref(true) -// 本地缓存 key -const STORAGE_KEY = 'assessment_info_form' +// 进行中测评记录 +const pendingRecord = ref(null) +const showPendingPopup = ref(false) /** - * 保存表单数据到本地 + * 是否为继续测评模式 */ -function saveFormToStorage() { - const data = { - ...formData.value, - genderIndex: genderIndex.value, - ageIndex: ageIndex.value, - educationIndex: educationIndex.value, - regionValue: regionValue.value - } +const isContinueMode = computed(() => !!pendingRecord.value) + +/** + * 性别数值转文本 + */ +function getGenderLabel(val) { + return val === 1 ? '男' : val === 2 ? '女' : '' +} + +/** + * 学业阶段数值转文本 + */ +function getEducationStageLabel(val) { + const map = { 1: '小学及以下', 2: '初中', 3: '高中', 4: '大专' } + return map[val] || '' +} + +/** + * 检查是否有进行中的测评记录 + */ +async function checkPendingRecord() { try { - uni.setStorageSync(STORAGE_KEY, JSON.stringify(data)) + const res = await getPendingRecord(typeId.value) + if (res && res.code === 0 && res.data) { + pendingRecord.value = res.data + showPendingPopup.value = true + } } catch (e) { - console.error('保存表单数据失败:', e) + console.error('检查进行中测评失败:', e) } } /** - * 从本地还原表单数据 + * 继续进行中的测评 */ -function restoreFormFromStorage() { - try { - const raw = uni.getStorageSync(STORAGE_KEY) - if (!raw) return - const data = JSON.parse(raw) - formData.value.name = data.name || '' - formData.value.phone = data.phone || '' - formData.value.gender = data.gender || '' - formData.value.age = data.age || '' - formData.value.educationStage = data.educationStage || '' - formData.value.province = data.province || '' - formData.value.city = data.city || '' - formData.value.district = data.district || '' - genderIndex.value = data.genderIndex ?? -1 - ageIndex.value = data.ageIndex ?? -1 - educationIndex.value = data.educationIndex ?? -1 - regionValue.value = data.regionValue || [] - } catch (e) { - console.error('还原表单数据失败:', e) - } +function handleContinuePending() { + if (!pendingRecord.value) return + const r = pendingRecord.value + + // 填充表单 + formData.value.name = r.name || '' + formData.value.phone = r.phone || '' + formData.value.gender = getGenderLabel(r.gender) + formData.value.age = r.age ? `${r.age}岁` : '' + formData.value.educationStage = getEducationStageLabel(r.educationStage) + formData.value.province = r.province || '' + formData.value.city = r.city || '' + formData.value.district = r.district || '' + + // 同步选择器索引 + genderIndex.value = r.gender === 1 ? 0 : r.gender === 2 ? 1 : -1 + ageIndex.value = r.age ? r.age - 10 : -1 + educationIndex.value = educationOptions.indexOf(getEducationStageLabel(r.educationStage)) + regionValue.value = [r.province || '', r.city || '', r.district || ''] + + showPendingPopup.value = false } /** - * 提交成功后清除缓存 + * 放弃进行中的测评,重新开始 */ -function clearFormStorage() { - try { - uni.removeStorageSync(STORAGE_KEY) - } catch (e) { - // ignore - } +function handleDismissPending() { + pendingRecord.value = null + showPendingPopup.value = false } -// 监听表单变化,自动保存 -watch(formData, () => { - saveFormToStorage() -}, { deep: true }) - /** * 表单是否填写完整 */ @@ -162,6 +173,7 @@ const isFormComplete = computed(() => { * 底部按钮文案 */ const payBtnText = computed(() => { + if (isContinueMode.value) return '继续测评' return `支付¥${introData.value.price || 20}元开始测评` }) @@ -262,6 +274,15 @@ function buildAssessmentInfo() { /** 支付测评 */ async function handlePayAssessment() { if (!checkLogin()) return + + // 继续测评模式:直接跳转到答题页 + if (isContinueMode.value && pendingRecord.value) { + uni.redirectTo({ + url: `/pages/assessment/questions/index?typeId=${typeId.value}&recordId=${pendingRecord.value.recordId}` + }) + return + } + if (!validateForm()) return try { @@ -274,7 +295,6 @@ async function handlePayAssessment() { uni.hideLoading() if (result.success) { - clearFormStorage() // 从 createOrder 返回中获取 assessmentRecordId const recordId = result.assessmentRecordId || '' uni.redirectTo({ @@ -342,7 +362,6 @@ async function submitInviteCode() { if (orderRes && orderRes.code === 0 && orderRes.data) { closeInvitePopup() - clearFormStorage() const recordId = orderRes.data.assessmentRecordId || '' uni.redirectTo({ url: `/pages/assessment/questions/index?typeId=${typeId.value}&recordId=${recordId}` @@ -365,20 +384,17 @@ onLoad((options) => { typeName.value = decodeURIComponent(options.typeName || '') userStore.restoreFromStorage() - // 还原本地缓存的表单数据 - restoreFormFromStorage() - // 如果已登录且手机号为空,预填手机号 if (userStore.isLoggedIn && userStore.phone && !formData.value.phone) { formData.value.phone = userStore.phone } loadIntro() -}) -/** 页面卸载时保存 */ -onUnload(() => { - saveFormToStorage() + // 检查是否有进行中的测评记录 + if (userStore.isLoggedIn) { + checkPendingRecord() + } }) @@ -403,7 +419,7 @@ onUnload(() => { - 正式测评前,请先填写您的基本信息 + {{ isContinueMode ? '您有一份进行中的测评,信息已自动填充' : '正式测评前,请先填写您的基本信息' }} @@ -416,6 +432,7 @@ onUnload(() => { placeholder-class="input-placeholder" v-model="formData.name" maxlength="20" + :disabled="isContinueMode" /> @@ -430,6 +447,7 @@ onUnload(() => { placeholder-class="input-placeholder" v-model="formData.phone" maxlength="11" + :disabled="isContinueMode" /> @@ -437,7 +455,7 @@ onUnload(() => { *性别 - + {{ formData.gender || '请选择' }} @@ -450,7 +468,7 @@ onUnload(() => { *年龄 - + {{ formData.age || '请选择' }} @@ -463,7 +481,7 @@ onUnload(() => { *学业阶段 - + {{ formData.educationStage || '请选择' }} @@ -476,7 +494,7 @@ onUnload(() => { *所在城市 - + @@ -503,10 +521,10 @@ onUnload(() => { - + 邀请码免费测评 - + {{ payBtnText }} @@ -537,6 +555,31 @@ onUnload(() => { + + + + + 发现进行中的测评 + + + + 您有一份未完成的测评记录,是否继续? + + + 姓名:{{ pendingRecord?.name }} + 手机号:{{ pendingRecord?.phone }} + + + + + 重新开始 + + + 继续测评 + + + + @@ -750,6 +793,10 @@ onUnload(() => { &:active { opacity: 0.8; } + + &.btn-full { + flex: 1; + } } // ========== 弹窗通用 ========== @@ -855,6 +902,41 @@ onUnload(() => { } } +// ========== 进行中测评弹窗 ========== +.pending-popup { + .pending-msg { + font-size: $font-size-md; + color: $text-color; + text-align: center; + margin-bottom: $spacing-lg; + } + + .pending-info { + display: flex; + flex-direction: column; + gap: $spacing-sm; + background-color: $bg-gray; + border-radius: $border-radius-md; + padding: $spacing-lg; + + text { + font-size: $font-size-sm; + color: $text-secondary; + } + } +} + +.pending-footer { + display: flex; + gap: $spacing-md; + padding: 0 $spacing-lg $spacing-xl; + + .popup-btn-outline, + .popup-btn { + flex: 1; + } +} + // ========== 邀请码输入 ========== .invite-input { width: 100%;