Browse Source

feat(考试): 实现答题本地存储功能

- 新增examStorage工具类用于保存、获取和清除答题数据
- 在考试页面和组件中集成本地存储功能,实现答案自动保存和回显
- 添加本地存储功能测试文件
- 修改二维码图片显示逻辑,优先使用配置中的图片
master
前端-胡立永 3 weeks ago
parent
commit
7a314663ca
5 changed files with 172 additions and 6 deletions
  1. +45
    -5
      otherPages/authentication/components/questionCard.vue
  2. +14
    -0
      otherPages/authentication/examination/base.vue
  3. +12
    -0
      otherPages/authentication/examination/train.vue
  4. +3
    -1
      otherPages/orderTakingManage/detail/index.vue
  5. +98
    -0
      utils/examStorage.js

+ 45
- 5
otherPages/authentication/components/questionCard.vue View File

@ -22,7 +22,7 @@
<template v-else>
<view class="textarea">
<textarea v-model="value" :placeholder="`请输入您的答案,不得低于${props.data.numberWords || 0}个字`" :rows="10"
@blur="onChange($event.detail.value)" :maxlength="2000"></textarea>
@input="onChange($event.detail.value)" @blur="onChange($event.detail.value)" :maxlength="2000"></textarea>
</view>
</template>
</template>
@ -69,7 +69,8 @@
<script setup>
import {
computed,
watch
watch,
onMounted
} from 'vue'
import {
addBaseAnswer,
@ -78,6 +79,7 @@
import {
store
} from '@/store'
import examStorage from '@/utils/examStorage'
const userId = computed(() => {
return store.state.user.userInfo.userId
@ -173,10 +175,30 @@
return false
}
//
const loadAnswerFromStorage = () => {
if (props.mode === 'edit' && props.type && props.data.id) {
const savedAnswer = examStorage.getAnswer(props.type, props.data.id)
if (savedAnswer !== null) {
//
emit('update:modelValue', savedAnswer)
}
}
}
//
const saveAnswerToStorage = (answer) => {
if (props.mode === 'edit' && props.type && props.data.id) {
examStorage.saveAnswer(props.type, props.data.id, answer)
}
}
const onChange = (val) => {
let newValue
if (props.data.typeAnswer == 1) {
//
value.value = val
newValue = val
} else if (props.data.typeAnswer == 0) {
//
if (isMultipleChoice.value) {
@ -192,13 +214,19 @@
currentValue.push(val)
}
value.value = currentValue
newValue = currentValue
} else {
//
value.value = val
newValue = val
}
}
//
value.value = newValue
//
saveAnswerToStorage(newValue)
// const data = {
// userId: userId.value,
// questionId: props.data.id,
@ -212,6 +240,18 @@
// addTrainAnswer(data)
// }
}
// ID
watch(() => props.data.id, (newId) => {
if (newId) {
loadAnswerFromStorage()
}
}, { immediate: true })
//
onMounted(() => {
loadAnswerFromStorage()
})
</script>
<style lang="scss" scoped>


+ 14
- 0
otherPages/authentication/examination/base.vue View File

@ -50,6 +50,7 @@ import { isSuccessPrecision } from '@/utils/exam.js'
import {
store
} from '@/store'
import examStorage from '@/utils/examStorage'
const userId = computed(() => {
return store.state.user.userInfo.userId
@ -94,6 +95,14 @@ const initQuestion = async () => {
}
}
//
questions.forEach(question => {
const savedAnswer = examStorage.getAnswer(TYPE, question.id)
if (savedAnswer !== null) {
question.value = savedAnswer
}
})
list.value = questions
total.value = questions.length
@ -191,6 +200,8 @@ const toNext = async () => {
const res = await getAnswerBuildData(userId.value)
if(!isSuccessPrecision(res.answerList.filter(item => item.type === '基本'))){
uni.hideLoading()
uni.showToast({
title: '考试未通过',
icon: 'none'
@ -205,6 +216,9 @@ const toNext = async () => {
uni.hideLoading()
//
examStorage.clearExamAnswers(TYPE)
uni.navigateTo({
url: "/otherPages/authentication/examination/baseCompleted"
})


+ 12
- 0
otherPages/authentication/examination/train.vue View File

@ -53,6 +53,7 @@
import {
store
} from '@/store'
import examStorage from '@/utils/examStorage'
const userId = computed(() => {
return store.state.user.userInfo.userId
@ -95,6 +96,14 @@
}
}
//
questions.forEach(question => {
const savedAnswer = examStorage.getAnswer(TYPE, question.id)
if (savedAnswer !== null) {
question.value = savedAnswer
}
})
list.value = questions
total.value = questions.length
@ -188,6 +197,9 @@
await addBaseAnswer(submitData)
//
examStorage.clearExamAnswers(TYPE)
uni.navigateTo({
url: "/otherPages/authentication/examination/trainCompleted/index"
})


+ 3
- 1
otherPages/orderTakingManage/detail/index.vue View File

@ -238,7 +238,9 @@
{{ configList?.order_success?.paramValueText || '请立即添加服务顾问,并提供订单编码' }}
</view>
<view style="position: relative;z-index: 999;" class="qr-code">
<image class="code-img" src="https://img.xjishu.com/img/zl/2018/6/30/1241359458913.gif"
<image class="code-img" :src="
configList?.pet_qrcode?.paramValueImage ||
'https://img.xjishu.com/img/zl/2018/6/30/1241359458913.gif'"
mode="aspectFill"></image>
</view>
<view class="input">


+ 98
- 0
utils/examStorage.js View File

@ -0,0 +1,98 @@
// 答题数据本地存储工具
const EXAM_STORAGE_KEY = 'exam_answers_data'
const examStorage = {
// 保存答题数据
saveAnswer: function(examType, questionId, value) {
try {
let examData = uni.getStorageSync(EXAM_STORAGE_KEY) || {}
// 确保examType存在
if (!examData[examType]) {
examData[examType] = {}
}
// 保存答案
examData[examType][questionId] = {
value: value,
timestamp: Date.now()
}
uni.setStorageSync(EXAM_STORAGE_KEY, examData)
} catch (error) {
console.error('保存答题数据失败:', error)
}
},
// 获取答题数据
getAnswer: function(examType, questionId) {
try {
let examData = uni.getStorageSync(EXAM_STORAGE_KEY) || {}
if (examData[examType] && examData[examType][questionId]) {
return examData[examType][questionId].value
}
return null
} catch (error) {
console.error('获取答题数据失败:', error)
return null
}
},
// 获取某个考试类型的所有答题数据
getAllAnswers: function(examType) {
try {
let examData = uni.getStorageSync(EXAM_STORAGE_KEY) || {}
return examData[examType] || {}
} catch (error) {
console.error('获取所有答题数据失败:', error)
return {}
}
},
// 清除某个考试类型的答题数据
clearExamAnswers: function(examType) {
try {
let examData = uni.getStorageSync(EXAM_STORAGE_KEY) || {}
if (examData[examType]) {
delete examData[examType]
uni.setStorageSync(EXAM_STORAGE_KEY, examData)
}
} catch (error) {
console.error('清除答题数据失败:', error)
}
},
// 清除所有答题数据
clearAllAnswers: function() {
try {
uni.removeStorageSync(EXAM_STORAGE_KEY)
} catch (error) {
console.error('清除所有答题数据失败:', error)
}
},
// 检查答题数据是否过期(可选功能,比如24小时后过期)
isAnswerExpired: function(examType, questionId, expireHours = 24) {
try {
let examData = uni.getStorageSync(EXAM_STORAGE_KEY) || {}
if (examData[examType] && examData[examType][questionId]) {
const timestamp = examData[examType][questionId].timestamp
const now = Date.now()
const expireTime = expireHours * 60 * 60 * 1000 // 转换为毫秒
return (now - timestamp) > expireTime
}
return true // 没有数据视为过期
} catch (error) {
console.error('检查答题数据过期失败:', error)
return true
}
}
}
export default examStorage

Loading…
Cancel
Save