猫妈狗爸伴宠师小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

251 lines
5.5 KiB

<template>
<view class="page">
<view class="header">
<view class="flex-rowl color-fff size-28 title">
{{ `答题进度 ${answered}/${total}` }}
</view>
<up-line-progress class="progress" :percentage="progress" activeColor="#FFBF60" inactiveColor="#D9D9D9" height="16rpx" :showText="false"></up-line-progress>
</view>
<view class="box">
<view class="content bg-fff">
<view>
<view class="label size-22">
混合题型
</view>
</view>
<view>
<questionCard
v-for="(item, qIdx) in list"
:key="`question-${qIdx}`"
v-model="item.value"
:index="qIdx"
:data="item"
:type="TYPE"
></questionCard>
</view>
</view>
</view>
<view class="footer-btn">
<button plain class="btn" @click="toNext" :disabled="answered < total">
提交
</button>
</view>
</view>
<!-- 客服组件 -->
<CustomerService />
</template>
<script setup>
import { ref, computed } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { getQuestionList, getQuestionOptions, getAnswerBuildData } from '@/api/examination'
import { isSuccessPrecision } from '@/utils/exam.js'
import {
addBaseAnswer,
addTrainAnswer
} from '@/api/examination'
import {
store
} from '@/store'
const userId = computed(() => {
return store.state.user.userInfo.userId
})
import questionCard from '../components/questionCard.vue';
const TYPE = '基本'
const list = ref([])
const total = ref(0)
const initQuestion = async () => {
try {
let questions = (await getQuestionList({ type: TYPE })).map(item => ({
id: item.id,
title: item.title,
value: null,
answerList : item.answerList,
...item,
}))
// todo: 替换成批量查询接口
for (let i = 0; i < questions.length; i++) {
// const options = (await getQuestionOptions({ questionId: questions[i].id })).map(item => ({ id: item.id, title: item.title}))
// questions[i].options = options
if (questions[i].typeAnswer == 0) {
// 选择题
questions[i].options = questions[i].answerList
// 判断是否是多选题,初始化对应的 value 类型
const correctAnswers = questions[i].answerList.filter(option => option.isTrue === 1 || option.isTrue === true)
const isMultipleChoice = correctAnswers.length > 1
// 多选题初始化为空数组,单选题初始化为 null
questions[i].value = isMultipleChoice ? [] : null
} else if (questions[i].typeAnswer == 1) {
// 填空题
questions[i].value = null
}
}
list.value = questions
total.value = questions.length
} catch (err) {
}
}
const answered = computed(() => {
return list.value.filter(item => {
if(item.value == null){
return false
}
if (item.typeAnswer == 0) {
// 选择题逻辑
// 检查多选题是否至少选择了一个选项
if(Array.isArray(item.value)){
return item.value.length > 0
}
// 单选题检查是否有值
return item.value !== null && item.value !== undefined
} else if (item.typeAnswer == 1) {
// 填空题逻辑
if(typeof item.value == 'string'){
return item.value.length >= (item.numberWords || 0)
}
return false
}
return false
}).length
})
const progress = computed(() => {
return Math.floor(answered.value / total.value * 100)
})
const toNext = async () => {
const answerBase = []
const answerTrains = []
uni.showLoading({
title: '提交中...'
})
list.value.forEach(n => {
if (n.typeAnswer == 0) {
// 选择题 - 基本考核
if (Array.isArray(n.value)) {
// 多选题:为每个选中的选项创建一个答案记录
n.value.forEach(answerId => {
answerBase.push({
userId: userId.value,
questionId: n.id,
answerId: answerId,
})
})
} else {
// 单选题:直接使用原有格式
answerBase.push({
userId: userId.value,
questionId: n.id,
answerId: n.value,
})
}
} else if (n.typeAnswer == 1) {
// 填空题 - 培训考核
answerTrains.push({
userId: userId.value,
questionId: n.id,
answer: n.value,
})
}
})
// 根据题目类型判断提交数据的type字段
const hasBaseQuestions = list.value.some(item => item.typeAnswer == 0)
const hasTrainQuestions = list.value.some(item => item.typeAnswer == 1)
// 提交数据
const submitData = {
answerBase: answerBase,
answerTrains: answerTrains,
type: hasBaseQuestions ? 0 : 1 // 如果有基本考试题则type为0,否则为1
}
await addBaseAnswer(submitData)
const res = await getAnswerBuildData(userId.value)
if(!isSuccessPrecision(res.answerList.filter(item => item.type === '基本'))){
uni.showToast({
title: '考试未通过',
icon: 'none'
})
uni.navigateTo({
url: "/otherPages/authentication/examination/errorDetail"
})
return
}
uni.hideLoading()
uni.navigateTo({
url: "/otherPages/authentication/examination/baseCompleted"
})
}
onShow(() => {
initQuestion()
})
</script>
<style lang="scss" scoped>
.page {
padding-bottom: 144rpx;
}
.header {
padding: 0 36rpx;
position: sticky;
top: 0;
background-image: linear-gradient(180deg, #FFBF60 0, #ffbf60 2%, #ffbf60 8%, #f2f2f2 90%);
z-index: 999;
.progress {
margin-top: 19rpx;
}
}
.box {
margin-top: 31rpx;
padding: 16rpx;
.content {
border-radius: 20rpx;
padding: 15rpx 20rpx;
.label {
display: inline-block;
padding: 5rpx 15rpx;
color: #fff;
background-color: #FFBF60;
}
}
}
</style>