- <template>
- <!-- <view>培训考核</view> -->
- <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}`" :index="qIdx" :data="item"
- v-model="item.value" :type="TYPE"></questionCard>
- </view>
- </view>
- </view>
- <view class="footer-btn buttom ">
- <button plain class="btn" @click="toNext" :disabled="answered < total">
- 提交
- </button>
- </view>
-
- <!-- 客服组件 -->
- <CustomerService />
- </view>
- </template>
-
- <script setup>
- import {
- ref,
- computed
- } from 'vue'
- import {
- onShow
- } from '@dcloudio/uni-app'
- import {
- getQuestionList
- } from '@/api/examination'
- 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,
- numberWords: item.numberWords,
- ...item,
- }))
-
- // 根据题目类型初始化value
- for (let i = 0; i < questions.length; i++) {
- 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
-
- // return list.value.filter(item => item.value?.length).length
- })
-
- const progress = computed(() => {
- return Math.floor(answered.value / total.value * 100)
- })
-
- const toNext = async () => {
-
- const answerBase = []
- const answerTrains = []
-
- 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: hasTrainQuestions ? 1 : 0 // 如果有培训考核题则type为1,否则为0
- }
-
- await addBaseAnswer(submitData)
-
- uni.navigateTo({
- url: "/otherPages/authentication/examination/trainCompleted/index"
- })
- }
-
- 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: 99;
-
- .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>
|