diff --git a/client/src/api/index.ts b/client/src/api/index.ts index aad6b3f..85641c5 100644 --- a/client/src/api/index.ts +++ b/client/src/api/index.ts @@ -158,6 +158,7 @@ export const aiApi = { explain: (body: BodyOf<'/api/ai/explain-question', 'post'>) => unwrap(apiClient.POST('/api/ai/explain-question', { body })) } +export type AiExplain = SuccessBody // ---- 个人档案 / 设置 ---- export const profileApi = { diff --git a/client/src/router/index.ts b/client/src/router/index.ts index e7b2486..dc0953b 100644 --- a/client/src/router/index.ts +++ b/client/src/router/index.ts @@ -5,6 +5,7 @@ import PracticeView from '../views/practice/PracticeView.vue' import AnswerView from '../views/practice/AnswerView.vue' import CustomView from '../views/practice/CustomView.vue' import WrongDetailView from '../views/practice/WrongDetailView.vue' +import AiExplainView from '../views/practice/AiExplainView.vue' import MockView from '../views/mock/MockView.vue' import MockFormView from '../views/mock/MockFormView.vue' import PlanView from '../views/plan/PlanView.vue' @@ -22,6 +23,7 @@ export const routes: RouteRecordRaw[] = [ { path: '/practice/custom', name: 'practice-custom', component: CustomView, meta: { title: '自定义组卷' } }, { path: '/practice/wrong', name: 'practice-wrong', component: PracticeView, meta: { title: '错题本' } }, { path: '/practice/wrong/:id', name: 'practice-wrong-detail', component: WrongDetailView, meta: { title: '错题详情' } }, + { path: '/practice/explain', name: 'practice-explain', component: AiExplainView, meta: { title: 'AI 讲解' } }, { path: '/practice/essay', name: 'practice-essay', component: PracticeView, meta: { title: '申论' } }, { path: '/mock', name: 'mock', component: MockView, meta: { title: '模考分析' } }, { path: '/mock/new', name: 'mock-new', component: MockFormView, meta: { title: '录入模考成绩' } }, diff --git a/client/src/views/practice/AiExplainView.vue b/client/src/views/practice/AiExplainView.vue new file mode 100644 index 0000000..3a5cab1 --- /dev/null +++ b/client/src/views/practice/AiExplainView.vue @@ -0,0 +1,257 @@ + + + + + diff --git a/client/src/views/practice/AnswerView.vue b/client/src/views/practice/AnswerView.vue index 5b67321..12f23f4 100644 --- a/client/src/views/practice/AnswerView.vue +++ b/client/src/views/practice/AnswerView.vue @@ -138,6 +138,13 @@ async function finishSession() { } } +function goAiExplain(questionId: string, userAnswer: string) { + router.push({ + name: 'practice-explain', + query: { questionId, userAnswer, requestType: 'standard' } + }) +} + function backToPractice() { router.push('/practice') } @@ -183,6 +190,14 @@ const finishAccuracy = computed(() => finishResult.value?.accuracy ?? 0) 正确答案 {{ q.correctAnswer }}

{{ q.analysis }}

+ + AI 讲解 + @@ -264,7 +279,15 @@ const finishAccuracy = computed(() => finishResult.value?.accuracy ?? 0)

{{ result.analysis }}

- 没看懂?让 AI 讲一讲 + + 没看懂?让 AI 讲一讲 +
@@ -625,6 +648,9 @@ const finishAccuracy = computed(() => finishResult.value?.accuracy ?? 0) line-height: var(--lh-body); color: var(--text-secondary); } +.wrong-list__ai { + margin-top: var(--space-2); +} .result-note { margin: var(--space-4) 0 0; font-size: var(--fs-label); diff --git a/client/src/views/practice/EssayView.vue b/client/src/views/practice/EssayView.vue new file mode 100644 index 0000000..7ff97b4 --- /dev/null +++ b/client/src/views/practice/EssayView.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/client/src/views/practice/PracticeView.vue b/client/src/views/practice/PracticeView.vue index 604c03b..510f6ba 100644 --- a/client/src/views/practice/PracticeView.vue +++ b/client/src/views/practice/PracticeView.vue @@ -13,7 +13,7 @@ import AppIcon from '../../components/base/AppIcon.vue' import AppLoading from '../../components/feedback/AppLoading.vue' import AppError from '../../components/feedback/AppError.vue' import AppEmpty from '../../components/feedback/AppEmpty.vue' -import ComingSoon from '../../components/feedback/ComingSoon.vue' +import EssayView from './EssayView.vue' import { formatPercent, formatDateShort } from '../../utils/format' import type { IconName } from '../../components/base/icons' @@ -387,7 +387,7 @@ const subtitle = computed(() => {
diff --git a/client/src/views/practice/WrongDetailView.vue b/client/src/views/practice/WrongDetailView.vue index ec2d1a6..ae877f5 100644 --- a/client/src/views/practice/WrongDetailView.vue +++ b/client/src/views/practice/WrongDetailView.vue @@ -96,6 +96,20 @@ function toggleReason(reason: string) { function backToList() { router.push('/practice/wrong') } + +/** AI 讲解:优先携带最近一次作答(历史最新一条),无历史则省略用户答案 */ +function goAiExplain() { + const questionId = detail.value?.questionId + if (!questionId) return + router.push({ + name: 'practice-explain', + query: { + questionId, + userAnswer: detail.value?.history[0]?.userAnswer ?? '', + requestType: 'standard' + } + }) +}