This commit is contained in:
2026-01-14 21:06:47 +08:00
parent cdc5dff129
commit 2b00bd1a2d
2 changed files with 313 additions and 4 deletions

View File

@@ -14,7 +14,7 @@
<view class="record-section">
<view v-if="recordList.length > 0" class="record-list">
<view v-for="(record, index) in recordList" :key="index" class="record-item">
<view v-for="(record, index) in recordList" :key="index" class="record-item" @click="handleRecordClick(record)">
<view class="record-header">
<view class="record-category">{{ record.category }}</view>
<view class="record-difficulty" :class="getDifficultyClass(record.difficulty)">
@@ -45,6 +45,48 @@
<text class="no-more-text">没有更多了</text>
</view>
</view>
<view v-if="showDetail" class="detail-modal" @click="closeDetail">
<view class="detail-content" @click.stop>
<view class="detail-header">
<text class="detail-title">题目详情</text>
<text class="detail-close" @click="closeDetail"></text>
</view>
<view v-if="detailLoading" class="detail-loading">
<text class="loading-text">加载中...</text>
</view>
<view v-else-if="detailQuestion" class="detail-body">
<view class="detail-meta">
<view class="meta-tag category-tag">
<text class="meta-text">{{ detailQuestion.category }}</text>
</view>
<view class="meta-tag difficulty-tag" :class="getDifficultyClass(detailQuestion.difficulty)">
<text class="meta-text">{{ getDifficultyText(detailQuestion.difficulty) }}</text>
</view>
</view>
<view class="detail-question">
<text class="question-text">{{ detailQuestion.question }}</text>
</view>
<view v-if="detailQuestion.options" class="detail-options">
<view
v-for="(option, index) in detailQuestion.options"
:key="index"
class="detail-option"
:class="{
'correct': getOptionLabel(option) === getCorrectAnswer(),
'wrong': getOptionLabel(option) === detailQuestion.user_answer && getOptionLabel(option) !== getCorrectAnswer()
}"
>
<text class="option-text">{{ option }}</text>
</view>
</view>
<view v-if="detailQuestion.explanation" class="detail-analysis">
<text class="analysis-label">解析</text>
<text class="analysis-text">{{ detailQuestion.explanation }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</template>
@@ -59,7 +101,11 @@ export default {
pageSize: 10,
totalCount: 0,
hasMore: true,
isLoading: false
isLoading: false,
isFirstLoad: true,
showDetail: false,
detailQuestion: null,
detailLoading: false
}
},
@@ -68,10 +114,55 @@ export default {
},
onShow() {
this.loadRecord()
if (!this.isFirstLoad) {
this.loadRecord()
}
this.isFirstLoad = false
},
methods: {
async handleRecordClick(record) {
this.showDetail = true
this.detailLoading = true
this.detailQuestion = null
try {
const res = await api.getQuestionInfo(record.question_sn)
if (res.data) {
this.detailQuestion = {
...res.data,
is_correct: record.is_correct,
user_answer: record.answer,
correct_answer: record.question_answer
}
}
} catch (error) {
console.error('获取题目详情失败:', error)
uni.showToast({
title: '获取失败',
icon: 'none'
})
} finally {
this.detailLoading = false
}
},
closeDetail() {
this.showDetail = false
this.detailQuestion = null
},
getCorrectAnswer() {
if (!this.detailQuestion) return ''
return String(this.detailQuestion.correct_answer || '').toUpperCase()
},
getOptionLabel(option) {
if (!option) return ''
const match = option.match(/^([A-D])\./)
return match ? match[1] : ''
},
async loadRecord(isLoadMore = false) {
if (this.isLoading) return
if (!isLoadMore) {
@@ -86,7 +177,10 @@ export default {
try {
const res = await api.getRecord(this.currentPage, this.pageSize)
if (res.data) {
const newRecords = res.data.records || []
const newRecords = (res.data.records || []).map(record => ({
...record,
is_correct: String(record.answer || '').toUpperCase() === String(record.question_answer || '').toUpperCase()
}))
if (isLoadMore) {
this.recordList = [...this.recordList, ...newRecords]
@@ -262,6 +356,26 @@ export default {
color: #ffffff;
}
.difficulty-tag.difficulty-easy {
background: #d4edda;
color: #155724;
}
.difficulty-tag.difficulty-medium {
background: #fff3cd;
color: #856404;
}
.difficulty-tag.difficulty-hard {
background: #fd7e14;
color: #ffffff;
}
.difficulty-tag.difficulty-extreme {
background: #dc3545;
color: #ffffff;
}
.difficulty-text {
font-weight: bold;
}
@@ -355,4 +469,179 @@ export default {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.6);
}
.detail-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
}
.detail-content {
background: #ffffff;
border-radius: 20rpx;
width: 90%;
max-height: 80vh;
display: flex;
flex-direction: column;
}
.detail-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 2rpx solid #f0f0f0;
}
.detail-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.detail-close {
font-size: 48rpx;
color: #999;
line-height: 1;
}
.detail-loading {
padding: 80rpx 40rpx;
text-align: center;
}
.detail-body {
padding: 30rpx;
overflow-y: auto;
}
.detail-meta {
display: flex;
gap: 20rpx;
margin-bottom: 30rpx;
}
.meta-tag {
padding: 8rpx 20rpx;
border-radius: 16rpx;
font-size: 24rpx;
}
.category-tag {
background: #e3f2fd;
color: #0d47a1;
}
.difficulty-tag {
background: #f8f9fa;
}
.detail-question {
margin-bottom: 30rpx;
}
.question-text {
font-size: 32rpx;
color: #333;
line-height: 1.8;
}
.detail-analysis {
background: #f0f9ff;
padding: 24rpx;
border-radius: 12rpx;
margin-bottom: 30rpx;
}
.analysis-label {
font-size: 26rpx;
font-weight: bold;
color: #0d47a1;
margin-right: 10rpx;
}
.analysis-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
.detail-options {
display: flex;
flex-direction: column;
gap: 20rpx;
margin-bottom: 30rpx;
}
.detail-option {
display: flex;
align-items: center;
padding: 24rpx 30rpx;
background: #f8f9fa;
border-radius: 12rpx;
gap: 16rpx;
}
.detail-option.correct {
background: #d4edda;
border: 2rpx solid #28a745;
}
.detail-option.wrong {
background: #f8d7da;
border: 2rpx solid #dc3545;
}
.option-label {
font-size: 28rpx;
font-weight: bold;
color: #666;
min-width: 40rpx;
}
.option-text {
font-size: 28rpx;
color: #333;
flex: 1;
}
.detail-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20rpx;
border-top: 2rpx solid #f0f0f0;
}
.detail-result {
display: flex;
align-items: center;
gap: 10rpx;
font-size: 28rpx;
}
.detail-result.correct {
color: #28a745;
}
.detail-result.wrong {
color: #dc3545;
}
.detail-answer {
font-size: 28rpx;
color: #666;
}
.answer-text {
font-weight: bold;
color: #333;
}
</style>