feat(assessment): 连接个人信息页与答题页数据流
- 新增 PendingRecordDto 模型,支持查询进行中的测评记录 - 后端新增 GetPendingRecord 接口,支持断点续答 - 邀请码路径改为调用 createOrder 创建订单和测评记录 - info 页面加载时检测未完成测评,支持继续上次或重新开始 - questions 页面改用 recordId 提交答案,匹配后端接口 - usePayment 返回 assessmentRecordId 供页面传递
This commit is contained in:
parent
e73527f2ae
commit
7a54c91154
|
|
@ -406,4 +406,44 @@ public class AssessmentController : ControllerBase
|
|||
return ApiResponse<List<ScoreOptionDto>>.Fail("获取评分标准失败");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户进行中的测评记录
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// GET /api/assessment/getPendingRecord?typeId=1
|
||||
///
|
||||
/// 查询当前用户状态为待测评或测评中的最新测评记录,用于断点续答。
|
||||
/// 需要用户登录认证。
|
||||
/// </remarks>
|
||||
/// <param name="typeId">测评类型ID</param>
|
||||
/// <returns>进行中的测评记录,如果没有则返回null</returns>
|
||||
[HttpGet("getPendingRecord")]
|
||||
[Authorize]
|
||||
[ProducesResponseType(typeof(ApiResponse<PendingRecordDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ApiResponse<PendingRecordDto>), StatusCodes.Status401Unauthorized)]
|
||||
public async Task<ApiResponse<PendingRecordDto>> GetPendingRecord([FromQuery] long typeId)
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (userId == null)
|
||||
{
|
||||
return ApiResponse<PendingRecordDto>.Unauthorized();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (typeId <= 0)
|
||||
{
|
||||
return ApiResponse<PendingRecordDto>.Fail("测评类型ID无效");
|
||||
}
|
||||
|
||||
var record = await _assessmentService.GetPendingRecordAsync(userId.Value, typeId);
|
||||
return ApiResponse<PendingRecordDto>.Success(record!);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to get pending record, userId: {UserId}, typeId: {TypeId}", userId, typeId);
|
||||
return ApiResponse<PendingRecordDto>.Fail("查询进行中的测评记录失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,4 +112,15 @@ public interface IAssessmentService
|
|||
/// <param name="typeId">测评类型ID</param>
|
||||
/// <returns>评分标准选项列表</returns>
|
||||
Task<List<ScoreOptionDto>> GetScoreOptionsAsync(long typeId);
|
||||
/// <summary>
|
||||
/// 获取用户进行中的测评记录
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 查询当前用户状态为待测评(1)或测评中(2)的最新测评记录。
|
||||
/// 用于页面加载时检测是否有未完成的测评,支持断点续答。
|
||||
/// </remarks>
|
||||
/// <param name="userId">当前用户ID</param>
|
||||
/// <param name="typeId">测评类型ID</param>
|
||||
/// <returns>进行中的测评记录,如果没有则返回null</returns>
|
||||
Task<PendingRecordDto?> GetPendingRecordAsync(long userId, long typeId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -614,4 +614,43 @@ public class AssessmentService : IAssessmentService
|
|||
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<PendingRecordDto?> GetPendingRecordAsync(long userId, long typeId)
|
||||
{
|
||||
_logger.LogDebug("查询进行中的测评记录,userId: {UserId}, typeId: {TypeId}", userId, typeId);
|
||||
|
||||
var record = await _dbContext.AssessmentRecords
|
||||
.AsNoTracking()
|
||||
.Where(r => r.UserId == userId
|
||||
&& r.AssessmentTypeId == typeId
|
||||
&& (r.Status == 1 || r.Status == 2)
|
||||
&& !r.IsDeleted)
|
||||
.OrderByDescending(r => r.CreateTime)
|
||||
.Select(r => new PendingRecordDto
|
||||
{
|
||||
RecordId = r.Id,
|
||||
OrderId = r.OrderId,
|
||||
AssessmentTypeId = r.AssessmentTypeId,
|
||||
Name = r.Name,
|
||||
Phone = r.Phone,
|
||||
Gender = r.Gender,
|
||||
Age = r.Age,
|
||||
EducationStage = r.EducationStage,
|
||||
Province = r.Province,
|
||||
City = r.City,
|
||||
District = r.District,
|
||||
Status = r.Status,
|
||||
CreateTime = r.CreateTime
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (record != null)
|
||||
{
|
||||
_logger.LogInformation("找到进行中的测评记录,userId: {UserId}, recordId: {RecordId}, status: {Status}",
|
||||
userId, record.RecordId, record.Status);
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
namespace MiAssessment.Model.Models.Assessment;
|
||||
|
||||
/// <summary>
|
||||
/// 进行中的测评记录DTO
|
||||
/// </summary>
|
||||
public class PendingRecordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 测评记录ID
|
||||
/// </summary>
|
||||
public long RecordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单ID
|
||||
/// </summary>
|
||||
public long OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 测评类型ID
|
||||
/// </summary>
|
||||
public long AssessmentTypeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 测评人姓名
|
||||
/// </summary>
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phone { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 性别:1男 2女
|
||||
/// </summary>
|
||||
public int Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 年龄
|
||||
/// </summary>
|
||||
public int Age { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 学业阶段
|
||||
/// </summary>
|
||||
public int EducationStage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public string Province { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 城市
|
||||
/// </summary>
|
||||
public string City { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 区县
|
||||
/// </summary>
|
||||
public string District { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 记录状态:1待测评 2测评中
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
|
|
@ -25,8 +25,7 @@ export function getQuestionList(typeId) {
|
|||
/**
|
||||
* 提交答案
|
||||
* @param {Object} data - 提交数据
|
||||
* @param {number} data.typeId - 测评类型ID
|
||||
* @param {Object} data.userInfo - 用户信息
|
||||
* @param {number} data.recordId - 测评记录ID
|
||||
* @param {Array} data.answers - 答案列表
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
|
|
@ -81,6 +80,15 @@ export function getScoreOptions(typeId) {
|
|||
return get('/assessment/getScoreOptions', { typeId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户进行中的测评记录
|
||||
* @param {number} typeId - 测评类型ID
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export function getPendingRecord(typeId) {
|
||||
return get('/assessment/getPendingRecord', { typeId })
|
||||
}
|
||||
|
||||
export default {
|
||||
getIntro,
|
||||
getQuestionList,
|
||||
|
|
@ -89,5 +97,6 @@ export default {
|
|||
getResult,
|
||||
verifyInviteCode,
|
||||
getHistoryList,
|
||||
getScoreOptions
|
||||
getScoreOptions,
|
||||
getPendingRecord
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ export function usePayment() {
|
|||
// 3. 查询支付结果
|
||||
const result = await checkPayResult(order.orderId)
|
||||
if (result && result.paid) {
|
||||
return { success: true, orderId: order.orderId }
|
||||
return { success: true, orderId: order.orderId, assessmentRecordId: order.assessmentRecordId }
|
||||
}
|
||||
|
||||
return { success: false, orderId: order.orderId, error: '支付结果确认失败' }
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* - 表单填写:姓名、手机号、性别、年龄、学业阶段、省市区
|
||||
* - 支付测评和邀请码免费测评两个入口
|
||||
* - 邀请码验证弹窗
|
||||
* - 进行中测评记录恢复(断点续答)
|
||||
*/
|
||||
|
||||
import { ref, computed, watch } from 'vue'
|
||||
|
|
@ -14,7 +15,8 @@ import { onLoad, onUnload } 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'
|
||||
|
||||
|
|
@ -62,6 +64,21 @@ function getEducationStageValue(label) {
|
|||
return map[label] || 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 数值转学业阶段文本
|
||||
*/
|
||||
function getEducationStageLabel(value) {
|
||||
const map = { 1: '小学及以下', 2: '初中', 3: '高中', 4: '大专' }
|
||||
return map[value] || ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 数值转性别文本
|
||||
*/
|
||||
function getGenderLabel(value) {
|
||||
return value === 1 ? '男' : value === 2 ? '女' : ''
|
||||
}
|
||||
|
||||
// 选择器索引
|
||||
const genderIndex = ref(-1)
|
||||
const ageIndex = ref(-1)
|
||||
|
|
@ -78,6 +95,10 @@ const inviteLoading = ref(false)
|
|||
// 页面加载状态
|
||||
const pageLoading = ref(true)
|
||||
|
||||
// 进行中的测评记录
|
||||
const pendingRecord = ref(null)
|
||||
const showPendingPopup = ref(false)
|
||||
|
||||
// 本地缓存 key
|
||||
const STORAGE_KEY = 'assessment_info_form'
|
||||
|
||||
|
|
@ -156,6 +177,19 @@ const isFormComplete = computed(() => {
|
|||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 是否处于继续上次测评模式
|
||||
*/
|
||||
const isContinueMode = computed(() => pendingRecord.value !== null)
|
||||
|
||||
/**
|
||||
* 底部按钮文案
|
||||
*/
|
||||
const payBtnText = computed(() => {
|
||||
if (isContinueMode.value) return '开始答题'
|
||||
return `支付¥${introData.value.price || 20}元开始测评`
|
||||
})
|
||||
|
||||
/**
|
||||
* 加载测评介绍
|
||||
*/
|
||||
|
|
@ -178,6 +212,56 @@ async function loadIntro() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有进行中的测评记录
|
||||
*/
|
||||
async function checkPendingRecord() {
|
||||
if (!userStore.isLoggedIn) return
|
||||
|
||||
try {
|
||||
const res = await getPendingRecord(typeId.value)
|
||||
if (res && res.code === 0 && res.data) {
|
||||
pendingRecord.value = res.data
|
||||
showPendingPopup.value = true
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询进行中测评记录失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户选择继续上次测评
|
||||
*/
|
||||
function handleContinuePending() {
|
||||
showPendingPopup.value = false
|
||||
const record = pendingRecord.value
|
||||
|
||||
// 回填个人信息到表单
|
||||
formData.value.name = record.name || ''
|
||||
formData.value.phone = record.phone || ''
|
||||
formData.value.gender = getGenderLabel(record.gender)
|
||||
formData.value.age = record.age ? `${record.age}岁` : ''
|
||||
formData.value.educationStage = getEducationStageLabel(record.educationStage)
|
||||
formData.value.province = record.province || ''
|
||||
formData.value.city = record.city || ''
|
||||
formData.value.district = record.district || ''
|
||||
|
||||
// 同步选择器索引
|
||||
genderIndex.value = record.gender === 1 ? 0 : record.gender === 2 ? 1 : -1
|
||||
ageIndex.value = record.age ? record.age - 10 : -1
|
||||
const eduIdx = educationOptions.indexOf(getEducationStageLabel(record.educationStage))
|
||||
educationIndex.value = eduIdx >= 0 ? eduIdx : -1
|
||||
regionValue.value = [record.province || '', record.city || '', record.district || '']
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户选择不继续上次测评
|
||||
*/
|
||||
function handleDismissPending() {
|
||||
showPendingPopup.value = false
|
||||
pendingRecord.value = null
|
||||
}
|
||||
|
||||
/** 性别选择 */
|
||||
function onGenderChange(e) {
|
||||
genderIndex.value = e.detail.value
|
||||
|
|
@ -234,9 +318,35 @@ function validateForm() {
|
|||
return true
|
||||
}
|
||||
|
||||
/** 支付测评 */
|
||||
/**
|
||||
* 构建测评信息对象
|
||||
*/
|
||||
function buildAssessmentInfo() {
|
||||
return {
|
||||
name: formData.value.name,
|
||||
phone: formData.value.phone,
|
||||
gender: formData.value.gender === '男' ? 1 : 2,
|
||||
age: parseInt(formData.value.age) || 0,
|
||||
educationStage: getEducationStageValue(formData.value.educationStage),
|
||||
province: formData.value.province,
|
||||
city: formData.value.city,
|
||||
district: formData.value.district
|
||||
}
|
||||
}
|
||||
|
||||
/** 支付测评 / 继续上次测评 */
|
||||
async function handlePayAssessment() {
|
||||
if (!checkLogin()) return
|
||||
|
||||
// 继续上次测评模式:直接跳转答题页
|
||||
if (isContinueMode.value) {
|
||||
clearFormStorage()
|
||||
uni.redirectTo({
|
||||
url: `/pages/assessment/questions/index?typeId=${typeId.value}&recordId=${pendingRecord.value.recordId}`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!validateForm()) return
|
||||
|
||||
try {
|
||||
|
|
@ -244,23 +354,16 @@ async function handlePayAssessment() {
|
|||
const result = await processPayment({
|
||||
orderType: 1,
|
||||
productId: typeId.value,
|
||||
assessmentInfo: {
|
||||
name: formData.value.name,
|
||||
phone: formData.value.phone,
|
||||
gender: formData.value.gender === '男' ? 1 : 2,
|
||||
age: parseInt(formData.value.age) || 0,
|
||||
educationStage: getEducationStageValue(formData.value.educationStage),
|
||||
province: formData.value.province,
|
||||
city: formData.value.city,
|
||||
district: formData.value.district
|
||||
}
|
||||
assessmentInfo: buildAssessmentInfo()
|
||||
})
|
||||
uni.hideLoading()
|
||||
|
||||
if (result.success) {
|
||||
clearFormStorage()
|
||||
// 从 createOrder 返回中获取 assessmentRecordId
|
||||
const recordId = result.assessmentRecordId || ''
|
||||
uni.redirectTo({
|
||||
url: `/pages/assessment/questions/index?typeId=${typeId.value}&orderId=${result.orderId}`
|
||||
url: `/pages/assessment/questions/index?typeId=${typeId.value}&recordId=${recordId}`
|
||||
})
|
||||
} else if (result.error) {
|
||||
uni.showToast({ title: result.error, icon: 'none' })
|
||||
|
|
@ -300,22 +403,42 @@ async function submitInviteCode() {
|
|||
|
||||
inviteLoading.value = true
|
||||
try {
|
||||
// 1. 验证邀请码
|
||||
const res = await verifyInviteCode(inviteCode.value.trim())
|
||||
if (res && res.code === 0 && res.data && res.data.isValid) {
|
||||
closeInvitePopup()
|
||||
clearFormStorage()
|
||||
uni.redirectTo({
|
||||
url: `/pages/assessment/questions/index?typeId=${typeId.value}&inviteCode=${inviteCode.value}`
|
||||
})
|
||||
} else {
|
||||
if (!res || res.code !== 0 || !res.data || !res.data.isValid) {
|
||||
uni.showToast({
|
||||
title: res?.data?.errorMessage || res?.message || '邀请码有误,请重新输入',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 邀请码有效,创建免费订单(带 inviteCodeId)
|
||||
const inviteCodeId = res.data.inviteCodeId
|
||||
uni.showLoading({ title: '创建订单中...' })
|
||||
|
||||
const orderRes = await createOrder({
|
||||
orderType: 1,
|
||||
productId: typeId.value,
|
||||
assessmentInfo: buildAssessmentInfo(),
|
||||
inviteCodeId: inviteCodeId
|
||||
})
|
||||
uni.hideLoading()
|
||||
|
||||
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}`
|
||||
})
|
||||
} else {
|
||||
uni.showToast({ title: orderRes?.message || '创建订单失败', icon: 'none' })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('验证邀请码失败:', error)
|
||||
uni.showToast({ title: '验证失败,请重试', icon: 'none' })
|
||||
uni.hideLoading()
|
||||
console.error('邀请码提交失败:', error)
|
||||
uni.showToast({ title: '提交失败,请重试', icon: 'none' })
|
||||
} finally {
|
||||
inviteLoading.value = false
|
||||
}
|
||||
|
|
@ -336,6 +459,8 @@ onLoad((options) => {
|
|||
}
|
||||
|
||||
loadIntro()
|
||||
// 检查是否有进行中的测评
|
||||
checkPendingRecord()
|
||||
})
|
||||
|
||||
/** 页面卸载时保存 */
|
||||
|
|
@ -364,7 +489,9 @@ onUnload(() => {
|
|||
|
||||
<!-- 表单卡片 -->
|
||||
<view class="form-card">
|
||||
<view class="form-tip">正式测评前,请先填写您的基本信息</view>
|
||||
<view class="form-tip">
|
||||
{{ isContinueMode ? '您有一次未完成的测评,信息已自动填充' : '正式测评前,请先填写您的基本信息' }}
|
||||
</view>
|
||||
|
||||
<!-- 姓名 -->
|
||||
<view class="form-item">
|
||||
|
|
@ -376,6 +503,7 @@ onUnload(() => {
|
|||
placeholder-class="input-placeholder"
|
||||
v-model="formData.name"
|
||||
maxlength="20"
|
||||
:disabled="isContinueMode"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -390,14 +518,15 @@ onUnload(() => {
|
|||
placeholder-class="input-placeholder"
|
||||
v-model="formData.phone"
|
||||
maxlength="11"
|
||||
:disabled="isContinueMode"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 性别 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label"><text class="required">*</text>姓别</view>
|
||||
<picker mode="selector" :range="genderOptions" @change="onGenderChange">
|
||||
<view class="form-label"><text class="required">*</text>性别</view>
|
||||
<picker mode="selector" :range="genderOptions" @change="onGenderChange" :disabled="isContinueMode">
|
||||
<view class="form-select-box">
|
||||
<text :class="formData.gender ? 'select-value' : 'select-placeholder'">
|
||||
{{ formData.gender || '请选择' }}
|
||||
|
|
@ -410,7 +539,7 @@ onUnload(() => {
|
|||
<!-- 年龄 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label"><text class="required">*</text>年龄</view>
|
||||
<picker mode="selector" :range="ageOptions" @change="onAgeChange">
|
||||
<picker mode="selector" :range="ageOptions" @change="onAgeChange" :disabled="isContinueMode">
|
||||
<view class="form-select-box">
|
||||
<text :class="formData.age ? 'select-value' : 'select-placeholder'">
|
||||
{{ formData.age || '请选择' }}
|
||||
|
|
@ -423,7 +552,7 @@ onUnload(() => {
|
|||
<!-- 学业阶段 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label"><text class="required">*</text>学业阶段</view>
|
||||
<picker mode="selector" :range="educationOptions" @change="onEducationChange">
|
||||
<picker mode="selector" :range="educationOptions" @change="onEducationChange" :disabled="isContinueMode">
|
||||
<view class="form-select-box">
|
||||
<text :class="formData.educationStage ? 'select-value' : 'select-placeholder'">
|
||||
{{ formData.educationStage || '请选择' }}
|
||||
|
|
@ -436,7 +565,7 @@ onUnload(() => {
|
|||
<!-- 所在城市 -->
|
||||
<view class="form-item form-item-last">
|
||||
<view class="form-label"><text class="required">*</text>所在城市</view>
|
||||
<picker mode="region" @change="onRegionChange">
|
||||
<picker mode="region" @change="onRegionChange" :disabled="isContinueMode">
|
||||
<view class="form-region-row">
|
||||
<view class="region-box">
|
||||
<text :class="formData.province ? 'select-value' : 'select-placeholder'">
|
||||
|
|
@ -463,11 +592,38 @@ onUnload(() => {
|
|||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="btn-group">
|
||||
<view class="btn-invite" @click="openInvitePopup">
|
||||
<view v-if="!isContinueMode" class="btn-invite" @click="openInvitePopup">
|
||||
<text>邀请码免费测评</text>
|
||||
</view>
|
||||
<view class="btn-pay" @click="handlePayAssessment">
|
||||
<text>支付¥{{ introData.price || 20 }}元开始测评</text>
|
||||
<view class="btn-pay" :class="{ 'btn-full': isContinueMode }" @click="handlePayAssessment">
|
||||
<text>{{ payBtnText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 进行中测评弹窗 -->
|
||||
<view v-if="showPendingPopup" class="popup-mask" @click="handleDismissPending">
|
||||
<view class="popup-container" @click.stop>
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">提示</text>
|
||||
<view class="popup-close" @click="handleDismissPending">
|
||||
<text>×</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="popup-body">
|
||||
<view class="pending-msg">您有一次未完成的测评,是否继续上次的测评?</view>
|
||||
<view class="pending-info">
|
||||
<text>姓名:{{ pendingRecord?.name }}</text>
|
||||
<text>手机号:{{ pendingRecord?.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="popup-footer pending-footer">
|
||||
<view class="popup-btn-outline" @click="handleDismissPending">
|
||||
<text>重新开始</text>
|
||||
</view>
|
||||
<view class="popup-btn" @click="handleContinuePending">
|
||||
<text>继续测评</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
|
@ -615,7 +771,6 @@ onUnload(() => {
|
|||
font-size: $font-size-md;
|
||||
color: $text-placeholder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// CSS 下拉箭头
|
||||
|
|
@ -711,9 +866,13 @@ onUnload(() => {
|
|||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.btn-full {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 邀请码弹窗 ==========
|
||||
// ========== 弹窗通用 ==========
|
||||
.popup-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
|
@ -768,18 +927,6 @@ onUnload(() => {
|
|||
padding: $spacing-xl $spacing-lg;
|
||||
}
|
||||
|
||||
.invite-input {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background-color: $bg-gray;
|
||||
border-radius: $border-radius-md;
|
||||
padding: 0 $spacing-lg;
|
||||
font-size: $font-size-lg;
|
||||
color: $text-color;
|
||||
text-align: center;
|
||||
letter-spacing: 8rpx;
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
padding: 0 $spacing-lg $spacing-xl;
|
||||
}
|
||||
|
|
@ -807,4 +954,69 @@ onUnload(() => {
|
|||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-btn-outline {
|
||||
height: 88rpx;
|
||||
background-color: $bg-white;
|
||||
border: 2rpx solid $border-color;
|
||||
border-radius: 44rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
text {
|
||||
font-size: $font-size-lg;
|
||||
font-weight: $font-weight-medium;
|
||||
color: $text-secondary;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 进行中测评弹窗 ==========
|
||||
.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;
|
||||
padding: $spacing-md $spacing-lg;
|
||||
background-color: $bg-gray;
|
||||
border-radius: $border-radius-md;
|
||||
|
||||
text {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.pending-footer {
|
||||
display: flex;
|
||||
gap: $spacing-md;
|
||||
|
||||
.popup-btn-outline,
|
||||
.popup-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 邀请码输入 ==========
|
||||
.invite-input {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background-color: $bg-gray;
|
||||
border-radius: $border-radius-md;
|
||||
padding: 0 $spacing-lg;
|
||||
font-size: $font-size-lg;
|
||||
color: $text-color;
|
||||
text-align: center;
|
||||
letter-spacing: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ const userStore = useUserStore()
|
|||
|
||||
// 页面参数
|
||||
const typeId = ref(0)
|
||||
const orderId = ref('')
|
||||
const inviteCode = ref('')
|
||||
const recordId = ref(0)
|
||||
|
||||
// 题目数据
|
||||
const questions = ref([])
|
||||
|
|
@ -141,19 +140,17 @@ async function handleSubmit() {
|
|||
const answerList = questions.value.map((q, index) => {
|
||||
const qId = q.id || index + 1
|
||||
const scoreIndex = answers.value[qId]
|
||||
return { questionId: qId, score: scoreOptions.value[scoreIndex].score }
|
||||
return { questionId: qId, answerValue: scoreOptions.value[scoreIndex].score }
|
||||
})
|
||||
|
||||
const res = await submitAnswers({
|
||||
typeId: typeId.value,
|
||||
orderId: orderId.value,
|
||||
inviteCode: inviteCode.value,
|
||||
recordId: recordId.value,
|
||||
answers: answerList
|
||||
})
|
||||
|
||||
if (res && res.code === 0) {
|
||||
const recordId = res.data?.recordId || res.data?.id || ''
|
||||
uni.redirectTo({ url: `/pages/assessment/loading/index?recordId=${recordId}` })
|
||||
const resRecordId = res.data?.recordId || res.data?.id || recordId.value
|
||||
uni.redirectTo({ url: `/pages/assessment/loading/index?recordId=${resRecordId}` })
|
||||
} else {
|
||||
uni.showToast({ title: res?.message || '提交失败,请重试', icon: 'none' })
|
||||
}
|
||||
|
|
@ -183,8 +180,7 @@ function scrollToQuestion(questionNo) {
|
|||
/** 页面加载 */
|
||||
onLoad((options) => {
|
||||
typeId.value = Number(options.typeId) || 1
|
||||
orderId.value = options.orderId || ''
|
||||
inviteCode.value = options.inviteCode || ''
|
||||
recordId.value = Number(options.recordId) || 0
|
||||
userStore.restoreFromStorage()
|
||||
loadQuestions()
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user