这个是主页面的所有内容<template> <view :class="['app-contain...
Creado el: 21 de junio de 2025
Creado el: 21 de junio de 2025
这个是主页面的所有内容<template>
<view :class="['app-container', theme]">
<view class="content">
<view class="overlay">
<!-- header -->
<view class="header" :style="{ paddingTop: height + 'px' }">
<view :style="{ height: Titleheight + 'px' }" class="header-container">
<view class="header-inner">
<view class="nav-buttons">
<view class="button-group">
<view @click="navigateBack" class="click-area">
<uni-icons type="left" color="#cccccc" size="26" />
</view>
</view>
</view>
<view class="right-placeholder" />
</view>
</view>
</template> <script> import ajax from '@/api/ajax.js' import { mapState } from 'vuex' import { getStatusBarHeight, getTitleBarHeight } from '@/utils/system.js' export default { name: 'DetailPages', data() { return { QuestionList: [], currentIndex: 0, height: 0, Titleheight: 0, letters: ['A', 'B', 'C', 'D'], // 显示用 loading: true // 添加加载状态 } }, computed: { ...mapState(['theme']), curQ() { return this.QuestionList[this.currentIndex] || { optionArray: [] } }, trueLetter() { if (!this.curQ.correctAnswerId) return '' const idx = this.curQ.optionArray.findIndex(o => o.id === this.curQ.correctAnswerId) return this.letters[idx] }, userLetter() { if (!this.curQ.userAnswerId) return '' const idx = this.curQ.optionArray.findIndex(o => o.id === this.curQ.userAnswerId) return this.letters[idx] } }, created() { this.$store.dispatch('initializeTheme') }, mounted() { this.height = getStatusBarHeight() this.Titleheight = getTitleBarHeight() this.getQuestionList() }, onLoad(option) { if (option) { this.gettypeid = option.typeid this.groupID = option.id } }, methods: { /** 接口获取题目 */ async getQuestionList() { try { this.loading = true // 显示加载状态 const option = { operateType: 'type', typeId: '0fabdb1a-cee3-470d-a8cb-73fc0eed1356' } const res = await ajax.post({ url: 'questionList', data: option, method: 'post' // 修正为 method,而不是 methon }) if (res.data.result === 'success') { // 给每道题初始化状态字段 this.QuestionList = (res.data.questionArray || []).map(q => { const correct = q.optionArray.find(o => o.isTrue)?.id return { ...q, answered: false, userAnswerId: '', correctAnswerId: correct, isCorrect: false } }) console.log(this.QuestionList,'this.QuestionListthis.QuestionListthis.QuestionListthis.QuestionList') } else { uni.showToast({ title: '获取题目列表失败,请稍后重试', icon: 'none' }) } } catch (e) { console.error(e) uni.showToast({ title: '获取题目列表失败,请检查网络或稍后重试', icon: 'none' }) } finally { this.loading = false // 隐藏加载状态 } }, /** 点击选项 */ choose(opt) { const q = this.curQ if (q.answered) return // 已作答 q.userAnswerId = opt.id q.answered = true q.isCorrect = opt.id === q.correctAnswerId // 触发视图更新 this.$set(this.QuestionList, this.currentIndex, q) }, /** 选项 row class */ itemClass(opt, idx) { const q = this.curQ if (!q.answered) return 'option-row' if (opt.id === q.correctAnswerId) return 'option-row correctback' if (opt.id === q.userAnswerId && !q.isCorrect) return 'option-row errorcolor' return 'option-row' }, /** 上一题 */ prev() { if (this.currentIndex === 0) { uni.showToast({ title: '已经是第一道题了', icon: 'none' }) } else { this.currentIndex-- } }, /** 下一题 */ next() { if (this.currentIndex >= this.QuestionList.length - 1) { uni.showToast({ title: '已经是最后一道题了', icon: 'none' }) } else { this.currentIndex++ } }, /** 返回 */ navigateBack() { uni.navigateBack() }, /** 反馈 */ problem() { uni.navigateTo({ url: '/Page-knowledgeQuiz/answerSubject/categoryHomepage/questionPage' }) } } } </script> <style lang="scss" scoped> @import '@/assets/styles/global.scss'; .content { min-height: 100vh; background: url('https://doufan.net/images/appBackImg/backimg.png') no-repeat center top / cover; position: relative; .overlay { position: absolute; inset: 0; background: url('https://doufan.net/images/appBackImg/backmc.png') no-repeat center top / cover; } .header { width: 94%; margin: 0 auto; .q-title-index, .q-title { font-size: 28rpx; color: #cccccc; } .option-row { display: flex; align-items: center; padding: 10rpx 0; border-radius: 12rpx; &.correctback { background: rgba(56, 53, 64, 0.7); } &.errorcolor { background: rgba(71, 49, 67, 0.7); } .circle { width: 48rpx; height: 48rpx; border-radius: 50%; background: #35313c; color: #d99f48; display: flex; justify-content: center; align-items: center; font-size: 24rpx; .state-icon { width: 28rpx; height: 26rpx; } } .opt-text { font-size: 28rpx; color: #cccccc; margin-left: 10rpx; } } .answer-tip { height: 76rpx; display: flex; align-items: center; margin-left: 25rpx; .answer-wrong { color: #e94351; font-size: 28rpx; } .answer-correct { color: #d99f48; font-size: 28rpx; } .answer-label { color: #cccccc; font-size: 28rpx; } .answer-true { color: #d99f48; font-size: 28rpx; margin: 0 10rpx; } .answer-false { color: #e94351; font-size: 28rpx; margin-left: 10rpx; } } .nav-btns { display: flex; justify-content: space-between; height: 74rpx; margin: 20rpx 0; .prev-btn, .next-btn { width: 328rpx; border-radius: 12rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; } .prev-btn { background: #35313c; color: #d99f48; } .next-btn { background: linear-gradient(to bottom, #d8983f, #e3d89d); } } .analysis-box { margin-top: 32rpx; padding: 20rpx; background: rgba(255, 255, 255, .1); border-radius: 12rpx; .analysis-header { display: flex; align-items: center; margin-bottom: 10rpx; .hat { width: 66rpx; height: 36rpx; } .analysis-title { font-size: 32rpx; color: #cccccc; margin-left: 10rpx; } } .analysis-content { color: #cccccc; font-size: 26rpx; line-height: 1.6; } .feedback { margin-top: 16rpx; padding: 20rpx; border-radius: 12rpx; background: rgba(255, 255, 255, .1); display: flex; align-items: center; justify-content: space-between; .feedback-text { font-size: 24rpx; color: #cccccc; margin: 0 12rpx; } } } /* 加载提示样式 */ .loading-tips { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #cccccc; font-size: 28rpx; } } } </style>提交答案的时候走一下这个接口1.answer答题text<!-- 题目主体 --> <view style="height: 88vh;width: 100%;"> <scroll-view scroll-y style="height: 100%;"> <!-- 题干 --> <view style="background:rgba(255,255,255,.1);border-radius:12rpx;padding:20rpx;"> <text class="q-title-index">{{ currentIndex + 1 }}.</text> <text class="q-title">{{ curQ.title }}</text> <!-- 选项 --> <view v-for="(opt, optIdx) in curQ.optionArray" :key="opt.id" :class="itemClass(opt, optIdx) || 0" class="option-row" @click="choose(opt)"> <!-- 圆圈 --> <view class="circle"> <!-- 未作答 --> <text v-if="!curQ.answered">{{ letters[optIdx] }}</text> <!-- 正确 --> <image v-else-if="opt.id === curQ.correctAnswerId" class="state-icon" src="https://mp-929a35ba-4f51-48bd-ae20-900476c70507.cdn.bspapp.com/img-file/Vector%20(1).png" mode="aspectFill" /> <!-- 错误 --> <image v-else-if="opt.id === curQ.userAnswerId && !curQ.isCorrect" class="state-icon" src="https://mp-929a35ba-4f51-48bd-ae20-900476c70507.cdn.bspapp.com/img-file/Vector.png" mode="aspectFill" /> <view v-else class=""> {{ letters[optIdx] }} </view> </view> <!-- 文本 --> <view class="opt-text">《{{ opt.title }}》</view> </view> </view> <!-- 答案提示 --> <view v-if="curQ.answered" class="answer-tip"> <template v-if="curQ.isCorrect"> <text class="answer-wrong">回答正确。</text> <text class="answer-label">正确答案 :</text> <text class="answer-true">{{ trueLetter }}</text> <text class="answer-label">, 你的答案</text> <text class="answer-false">{{ userLetter }}</text> </template> <template v-else> <text class="answer-wrong">回答错误。</text> <text class="answer-label">正确答案 :</text> <text class="answer-true">{{ trueLetter }}</text> <text class="answer-label">, 你的答案</text> <text class="answer-false">{{ userLetter }}</text> </template> </view> <view v-else style="height:76rpx;" /> <!-- 上/下一题按钮 --> <view class="nav-btns"> <view class="prev-btn" @click="prev">上一题</view> <view class="next-btn" @click="next">下一题</view> </view> <!-- 下面的提示词 --> <view v-if="curQ.answered" style="margin-top: 32rpx;padding: 20rpx;background-color: rgba(255, 255, 255, 0.1);border-radius: 12rpx;" class=""> <view style="width: 200rpx;height: 44rpx;display: flex;align-items: center;" class=""> <view style="width: 66rpx;height: 36rpx;" class=""> <image style="height: 100%;width: 100%;" src="https://mp-929a35ba-4f51-48bd-ae20-900476c70507.cdn.bspapp.com/img-file/帽子.png" mode="aspectFill"></image> </view> <view style="font-size: 32rpx;color: #cccccc;margin-left: 10rpx;" class=""> 答案解析 </view> </view> <view v-if="curQ.content" style="color: #cccccc;" class=""> 关注微信公众“咖值小程序”,回复“简答”,领取250个科二中小幼对应学段简答口诀,记住就可能得分! 本题考查素质教育。考试和素质并不是对立的,通过制定合适的教学计划,能够将考试和素质更好地整合起来。B选项说法错误,入选。ACD选项:应试教育与素质教育有很大不同,应试教育片面强调教育的选拔功能,只重视考试的课本内容和各种升学资料的死记硬背;而素质教育则把面向全体学生放在首位,强化普及意识。说法均正确,不选。 综上,选B。 </view> <view v-else style="color: #cccccc;" class="" > 暂无解析 </view> <view style="border-radius: 12rpx;background-color: rgba(255, 255, 255, 0.1);padding: 20rpx;margin-top: 16rpx;display: flex;justify-content: space-between;width: 100%;box-sizing: border-box;" class=""> <view @click="problem()" style="width: 60%;box-sizing: border-box;" class=""> <view style="display: flex;justify-content: center;align-items: center;" class=""> <uni-icons type="compose" color="#cccccc" size="25"></uni-icons> <view style="font-size: 24rpx;color: #cccccc;" class=""> 对这到题有疑问吗? 点击反馈 </view> </view> </view> <view style="width: 40%;box-sizing: border-box;position: relative;" class=""> <view style="position: absolute;right: 0%;" class=""> <uni-icons type="right" color="#cccccc" size="25"></uni-icons> </view> </view> </view> </view> <!-- 下面的模态框 --> <view v-if="false" style="width: 510rpx;height: 414rpx;border-radius: 12rpx;background-color: #CCCCCC;position: fixed;transform: translate(-50%,-50%);left: 50%;top: 50%;z-index: 111;" class=""> <view style="height: 40rpx;display: flex;justify-content: space-between;box-sizing: border-box;" class=""> <view style="width: 50%;box-sizing: border-box;" class=""> </view> <view style="width: 50%;box-sizing: border-box;position: relative;" class=""> <view @click.prevent="DisplayBox =false" style="position: absolute;right: 2%;height: 50rpx;width: 50rpx;background-color:#766E6E;border-radius: 50%;margin-top: 10rpx;margin-left: 10rpx;display: flex;justify-content: center;align-items: center;" class=""> <view style="color: #CCCCCC;font-size: 36rpx;" class=""> × </view> </view> </view> </view> <view style="height: 32rpx;width: 100%;display: flex;justify-content: center;align-items: center;" class=""> <view style="color: black;font-size: 32rpx;margin-top: 24rpx;" class=""> 恭喜你回答正确 </view> </view> <view style="height: 128rpx;width: 100%;display: flex;justify-content: center;align-items: center;" class=""> <view style="height: 128rpx;width: 128rpx;background: linear-gradient(to bottom,#D8983F,#E3D89D);border-radius: 50%;margin-top: 40rpx;display: flex;justify-content: center;align-items: center;" class=""> <view style="width: 70rpx;height: 70rpx;margin-left: 15rpx;" class=""> 现金 0.01¥ </view> </view> </view> <view style="width: 100%;height: 60rpx;display: flex;justify-content: center;align-items: center;margin-top: 30rpx;" class=""> <view style="height: 100%;width: 434rpx;color: #766E6E;" class=""> 立即获得0.01元的现金奖励,已经发放在您的微信里,注意查收 </view> </view> <view style="height: 40rpx;width: 100%;" class=""> </view> <view style="height: 72rpx;width: 100%;display: flex;justify-content: center;align-items: center;" class=""> <view style="display: flex;justify-content: center;align-items: center;height: 100%;border-radius: 12rpx;background: linear-gradient(to bottom,#D8983F,#E3D89D);width: 326rpx;" class=""> <view class=""> 确定 </view> </view> </view> </view> </scroll-view> </view> </view> </view> </view> </view>
入口参数
String questionId, 题目id
String[] optionIds, 选择答案
String consumerId 用户id
返回值
isTrue是否正确 不用返回一个完整的页面只需要发挥提交答案的时候 走一下这个接口 String questionId, 题目id
String[] optionIds, 选择答案
String consumerId 用户id
返回值
isTrue是否正确 就写 提交答案的方法 包括这个走接口的方法
下面只给出新增/改动的关键代码片段,直接贴进 <script>
内的 methods
区域即可,无需改动其它结构。
思路:
choose
方法里),把所选答案存下来。questionId / optionIds / consumerId
。isTrue
字段更新本地题目状态。jsmethods: { /* ① 提交答案接口 */ async submitAnswer({ questionId, optionIds, consumerId }) { try { const res = await ajax.post({ url: 'answer', // ← 后端给的接口名 method: 'post', // 保持 post data: { questionId, optionIds, consumerId } }) // 只关心 isTrue if (res.data && typeof res.data.isTrue === 'boolean') { return res.data.isTrue } // 兜底:接口异常时返回 null return null } catch (e) { console.error('submitAnswer error', e) return null } }, /* ② 点击选项 */ async choose(opt) { const q = this.curQ if (q.answered) return // 本地先记录 q.userAnswerId = opt.id q.answered = true // **调用接口**,把题目 id / 选项 id / 用户 id 传过去 const isCorrect = await this.submitAnswer({ questionId: q.id, optionIds: [opt.id], // 后端要求数组 consumerId: this.$store.state.userId // 请按实际存储位置取用户 id }) // 若接口正常返回布尔值,用它;否则回退到本地判断 if (isCorrect !== null) { q.isCorrect = isCorrect } else { q.isCorrect = opt.id === q.correctAnswerId } // 触发视图更新 this.$set(this.QuestionList, this.currentIndex, q) }, /* 其余方法保持不变 */ }
说明
consumerId
:示例里假设登录后把用户 id 存在vuex
的userId
字段;如存放位置不同,请自行替换。- 接口异常时,为了不中断流程,会退回到旧的前端逻辑(直接比对
correctAnswerId
)。如需强制以后端为准,可改为提示错误后return
。