修复填空复习功能2.1
This commit is contained in:
parent
af99db67cb
commit
9da98e9c82
@ -69,25 +69,45 @@ Page({
|
||||
const question_mode = questionModeMap[this.data.activeMode]
|
||||
const scope_config = {}
|
||||
this.setData({ loading: true, error: '' })
|
||||
wx.request({
|
||||
url: `${app.globalData.baseUrl}/api/v1/review/generate`,
|
||||
method: 'POST',
|
||||
header: { 'Content-Type': 'application/json', 'X-OpenID': app.globalData.openid || '' },
|
||||
data: {
|
||||
scope_type,
|
||||
scope_config,
|
||||
content_type,
|
||||
question_mode,
|
||||
review_strategy: this.data.onlyReview ? 'review_only' : 'all',
|
||||
sort_mode: this.data.reviewOrder === 'shuffle' ? 'shuffle' : 'sequential',
|
||||
total_count: this.data.questionCount,
|
||||
},
|
||||
success: (res) => {
|
||||
app.globalData.reviewSessionMeta = res.data?.data || null
|
||||
wx.navigateTo({ url: '/pages/review-session/review-session' })
|
||||
},
|
||||
fail: () => this.setData({ error: '生成复习会话失败' }),
|
||||
complete: () => this.setData({ loading: false }),
|
||||
app.ensureLogin().then((openid) => {
|
||||
if (!openid) {
|
||||
this.setData({ loading: false, error: '请先登录后再开始复习' })
|
||||
return
|
||||
}
|
||||
wx.request({
|
||||
url: `${app.globalData.baseUrl}/api/v1/review/generate`,
|
||||
method: 'POST',
|
||||
header: { 'Content-Type': 'application/json', 'X-OpenID': openid },
|
||||
data: {
|
||||
scope_type,
|
||||
scope_config,
|
||||
content_type,
|
||||
question_mode,
|
||||
review_strategy: this.data.onlyReview ? 'review_only' : 'all',
|
||||
sort_mode: this.data.reviewOrder === 'shuffle' ? 'shuffle' : 'sequential',
|
||||
total_count: this.data.questionCount,
|
||||
},
|
||||
success: (res) => {
|
||||
const session = res.data?.data || null
|
||||
if (res.statusCode < 200 || res.statusCode >= 300 || !session?.id) {
|
||||
const message = res.data?.detail || res.data?.message || '生成复习会话失败'
|
||||
this.setData({ error: message })
|
||||
wx.showToast({ title: message, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!session.record_ids?.length) {
|
||||
const message = '当前条件下没有可复习题目,请切换时间范围或关闭仅复习'
|
||||
this.setData({ error: message })
|
||||
wx.showToast({ title: message, icon: 'none' })
|
||||
return
|
||||
}
|
||||
app.globalData.reviewSessionMeta = session
|
||||
wx.setStorageSync('reviewSessionMeta', session)
|
||||
wx.navigateTo({ url: '/pages/review-session/review-session' })
|
||||
},
|
||||
fail: () => this.setData({ error: '生成复习会话失败' }),
|
||||
complete: () => this.setData({ loading: false }),
|
||||
})
|
||||
})
|
||||
},
|
||||
goHome() {
|
||||
|
||||
@ -36,6 +36,7 @@ Page({
|
||||
currentClozeQuestion: null,
|
||||
currentClozeResults: [],
|
||||
showClozeFeedback: false,
|
||||
clozeSegments: [],
|
||||
},
|
||||
submitting: false,
|
||||
judged: false,
|
||||
@ -61,17 +62,55 @@ Page({
|
||||
},
|
||||
})
|
||||
},
|
||||
buildClozeSegments(clozeQuestion) {
|
||||
if (!clozeQuestion || !Array.isArray(clozeQuestion.blanks)) return []
|
||||
const prompt = clozeQuestion.prompt_text || ''
|
||||
const segments = []
|
||||
let blankIndex = 0
|
||||
if (prompt.includes('____')) {
|
||||
prompt.split('____').forEach((text, index, parts) => {
|
||||
if (text) segments.push({ type: 'text', text, index: `text-${index}` })
|
||||
if (index < parts.length - 1) {
|
||||
segments.push({ type: 'blank', blankIndex, index: `blank-${blankIndex}` })
|
||||
blankIndex += 1
|
||||
}
|
||||
})
|
||||
return segments
|
||||
}
|
||||
|
||||
const blanks = clozeQuestion.blanks || []
|
||||
let cursor = 0
|
||||
blanks.forEach((blank, idx) => {
|
||||
const start = Math.max(0, Number(blank.start || 0))
|
||||
const end = Math.max(start, Number(blank.end || start + 1))
|
||||
if (start > cursor) {
|
||||
segments.push({ type: 'text', text: prompt.slice(cursor, start), index: `text-${idx}` })
|
||||
}
|
||||
segments.push({ type: 'blank', blankIndex: idx, index: `blank-${idx}` })
|
||||
cursor = end
|
||||
})
|
||||
if (cursor < prompt.length) {
|
||||
segments.push({ type: 'text', text: prompt.slice(cursor), index: `text-tail` })
|
||||
}
|
||||
return segments
|
||||
},
|
||||
loadQuestions() {
|
||||
const session = app.globalData.reviewSessionMeta
|
||||
if (!session) {
|
||||
const session = app.globalData.reviewSessionMeta || wx.getStorageSync('reviewSessionMeta')
|
||||
if (!session?.id) {
|
||||
this.setData({ error: '暂无复习会话' })
|
||||
return
|
||||
}
|
||||
app.globalData.reviewSessionMeta = session
|
||||
this.setData({ loading: true, error: '' })
|
||||
wx.request({
|
||||
url: `${app.globalData.baseUrl}/api/v1/review/questions?session_id=${session.id}`,
|
||||
header: { 'X-OpenID': app.globalData.openid || '' },
|
||||
success: (res) => {
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
const message = res.data?.detail || res.data?.message || '题目加载失败'
|
||||
this.setData({ error: message, questions: [] })
|
||||
return
|
||||
}
|
||||
const questions = (res.data?.data || []).map((item) => {
|
||||
if (item.question_mode === 'C') {
|
||||
return {
|
||||
@ -85,6 +124,10 @@ Page({
|
||||
entry_type: item.entry_type || 'word',
|
||||
}
|
||||
})
|
||||
if (!questions.length) {
|
||||
this.setData({ error: '当前复习会话没有题目,请返回重新选择范围', questions: [] })
|
||||
return
|
||||
}
|
||||
app.globalData.reviewSession = {
|
||||
deck: questions,
|
||||
currentIndex: 0,
|
||||
@ -115,7 +158,7 @@ Page({
|
||||
word: isCloze ? (current?.blank_prompt || clozeQuestion?.prompt_text || current?.prompt || '') : (current?.prompt || ''),
|
||||
meaning: isCloze ? (current?.answer_hint || '') : '',
|
||||
answer: session.currentAnswer || '',
|
||||
clozeAnswers: isCloze ? (session.currentAnswers || []) : [],
|
||||
clozeAnswers: isCloze ? (Array.isArray(session.currentAnswers) ? session.currentAnswers : Array.from({ length: currentClozeQuestion?.blanks?.length || 0 }, () => '')) : [],
|
||||
feedback: '',
|
||||
revealAnswer: '',
|
||||
feedbackType: '',
|
||||
@ -128,6 +171,7 @@ Page({
|
||||
currentClozeQuestion: clozeQuestion,
|
||||
currentClozeResults: session.lastClozeResults || [],
|
||||
showClozeFeedback: false,
|
||||
clozeSegments: isCloze ? this.buildClozeSegments(clozeQuestion) : [],
|
||||
})
|
||||
},
|
||||
onAnswerInput(e) {
|
||||
@ -202,6 +246,10 @@ Page({
|
||||
showClozeFeedback: clozeResults.length > 0,
|
||||
currentClozeResults: clozeResults,
|
||||
})
|
||||
if (this.data.isCloze) {
|
||||
app.globalData.reviewSession.currentAnswers = []
|
||||
this.setData({ clozeAnswers: [] })
|
||||
}
|
||||
if (this.data.settings.autoNextQuestion || advanceAfterSubmit) {
|
||||
setTimeout(() => this.nextQuestion(), shouldShowAnswer ? 1200 : 0)
|
||||
}
|
||||
@ -239,6 +287,7 @@ Page({
|
||||
}
|
||||
session.currentIndex += 1
|
||||
session.currentAnswer = ''
|
||||
session.currentAnswers = []
|
||||
this.syncSession()
|
||||
},
|
||||
markMastered() {
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
<view wx:if="{{!questions.length}}" class="empty-state">
|
||||
<text class="empty-title">暂无题目</text>
|
||||
<text class="empty-subtitle">请先生成复习会话</text>
|
||||
<text class="empty-subtitle">{{error || '请先生成复习会话'}}</text>
|
||||
</view>
|
||||
|
||||
<view wx:else class="glass-card question-card ghost-border">
|
||||
@ -23,14 +23,14 @@
|
||||
</view>
|
||||
|
||||
<view wx:if="{{isCloze}}" class="cloze-wrap">
|
||||
<text class="cloze">{{word}}</text>
|
||||
<view wx:if="{{currentClozeQuestion && currentClozeQuestion.blanks.length}}" class="cloze-input-list">
|
||||
<view wx:for="{{currentClozeQuestion.blanks}}" wx:for-item="blank" wx:for-index="blankIndex" wx:key="index" class="cloze-input-item">
|
||||
<text class="cloze-input-label">空 {{blankIndex + 1}}</text>
|
||||
<view wx:if="{{blank.hint && blank.hint.first_letter}}" class="cloze-hint">提示:首字母 {{blank.hint.first_letter}} · 长度 {{blank.hint.length}}</view>
|
||||
<input class="answer cloze-answer" data-index="{{blankIndex}}" value="{{clozeAnswers[blankIndex] || ''}}" placeholder="输入第 {{blankIndex + 1}} 个空" bindinput="onClozeAnswerInput" />
|
||||
</view>
|
||||
<view wx:if="{{currentClozeQuestion && currentClozeQuestion.blanks.length}}" class="inline-cloze">
|
||||
<block wx:for="{{clozeSegments}}" wx:for-item="segment" wx:for-index="segmentIndex" wx:key="index">
|
||||
<text wx:if="{{segment.type === 'text'}}" class="cloze-segment-text">{{segment.text}}</text>
|
||||
<input wx:else class="answer inline-cloze-answer" data-index="{{segment.blankIndex}}" value="{{clozeAnswers[segment.blankIndex] || ''}}" placeholder="空{{segment.blankIndex + 1}}" bindinput="onClozeAnswerInput" />
|
||||
</block>
|
||||
</view>
|
||||
<text wx:else class="cloze">{{word}}</text>
|
||||
|
||||
</view>
|
||||
<view wx:else class="word-wrap">
|
||||
<text class="word">{{word}}</text>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user