feat(views): 新增英语试题AI分析页面
This commit is contained in:
parent
1ac019b88d
commit
11a31c3745
|
|
@ -0,0 +1,187 @@
|
|||
---
|
||||
name: exam-analysis-page
|
||||
overview: 新增"英语试题AI分析"页面(ExamAnalysis.vue),支持文本输入和图片上传两种方式,通过流式调用 Gemini API 对试题进行多维度深度解析,并实时展示分析结果。
|
||||
design:
|
||||
architecture:
|
||||
framework: vue
|
||||
styleKeywords:
|
||||
- Glassmorphism
|
||||
- Dark Theme
|
||||
- Teal Accent
|
||||
- Streaming Typewriter
|
||||
- Card Layout
|
||||
- Minimalism
|
||||
fontSystem:
|
||||
fontFamily: Inter
|
||||
heading:
|
||||
size: 1.2rem
|
||||
weight: 600
|
||||
subheading:
|
||||
size: 1rem
|
||||
weight: 500
|
||||
body:
|
||||
size: 0.95rem
|
||||
weight: 400
|
||||
colorSystem:
|
||||
primary:
|
||||
- "#14b8a6"
|
||||
- "#0d9488"
|
||||
background:
|
||||
- "#0d0f17"
|
||||
- rgba(255,255,255,0.03)
|
||||
text:
|
||||
- "#ffffff"
|
||||
- "#94a3b8"
|
||||
functional:
|
||||
- "#ef4444"
|
||||
- "#fca5a5"
|
||||
- rgba(20,184,166,0.15)
|
||||
todos:
|
||||
- id: create-exam-analysis-page
|
||||
content: 创建 src/views/ExamAnalysis.vue,实现双模式输入、流式 Gemini API 调用、五维度结果卡片及完整状态管理
|
||||
status: completed
|
||||
- id: register-route-and-update-homepage
|
||||
content: 更新 src/router/index.js 注册 /exam-analysis 路由,并修改 src/views/HomePage.vue 中 card-4 的 route 为 '/exam-analysis'
|
||||
status: completed
|
||||
dependencies:
|
||||
- create-exam-analysis-page
|
||||
---
|
||||
|
||||
## 用户需求
|
||||
|
||||
开发一个英语试题 AI 分析页面,集成到现有 Vue 3 项目中,作为首页第 4 个功能卡片(英语试题AI分析)的目标页面。
|
||||
|
||||
## 产品概述
|
||||
|
||||
用户可通过文本输入或图片上传两种方式提交英语试题,系统调用 Gemini API 进行流式深度解析,分析结果实时逐字渲染展示,整体风格与现有页面保持一致(深色 Glassmorphism 风格,Teal 主题色)。
|
||||
|
||||
## 核心功能
|
||||
|
||||
- **双模式输入**:支持文本粘贴输入和图片上传(JPG/PNG,拖拽或点击),两种模式通过 Tab 切换
|
||||
- **流式 AI 分析**:通过 axios + `onDownloadProgress` 回调流式调用 Gemini API,分析结果实时逐字输出
|
||||
- **多维度解析展示**:将分析结果结构化展示为五个维度卡片:题干理解、考点识别、解题思路、正确答案、详细解析
|
||||
- **实时流式渲染**:分析过程中显示打字机效果,内容逐步呈现,用户可看到实时生成进度
|
||||
- **状态管理**:idle / analyzing / done / error 四种状态,含加载动画、错误提示、重新分析等交互
|
||||
- **路由集成**:注册 `/exam-analysis` 路由,首页 card-4 的 `route: null` 更新为 `/exam-analysis`
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **框架**:Vue 3 + `<script setup>` + Composition API(与现有项目一致)
|
||||
- **路由**:vue-router(现有,仅新增路由条目)
|
||||
- **HTTP/流式请求**:`axios` + `onDownloadProgress` 回调(Gemini SSE 流式响应,与项目现有 axios 依赖保持一致)
|
||||
- **样式**:Scoped CSS,复用现有 CSS 变量(`--bg-color`、`--card-bg`、`--card-border`、`--text-primary`、`--text-secondary`、`--accent-4`)
|
||||
|
||||
## 实现方案
|
||||
|
||||
### 流式调用策略
|
||||
|
||||
Gemini API 支持 SSE(Server-Sent Events)流式输出。使用 `axios` 发起请求,设置 `responseType: 'text'`,通过 `onDownloadProgress` 回调监听每次数据块到达,从 `event.target.responseText` 中增量提取新内容,逐步拼接到响应字符串中,触发 Vue 响应式更新实现打字机效果。与项目现有 axios 依赖保持一致,无需引入额外依赖。
|
||||
|
||||
### 结构化解析策略
|
||||
|
||||
AI 返回的 Markdown 文本通过正则表达式按标题(`##` 或特定关键词)分割为五个维度模块,每个模块独立渲染为卡片。流式过程中实时更新当前正在生成的模块内容,已完成的模块保持稳定显示。
|
||||
|
||||
### Prompt 设计
|
||||
|
||||
系统 Prompt 要求 Gemini 严格按照固定格式输出,包含五个 `##` 标题段落,便于前端解析分割。
|
||||
|
||||
## 架构设计
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[ExamAnalysis.vue] --> B[输入区域 - Tab切换]
|
||||
B --> C[文本输入 Textarea]
|
||||
B --> D[图片上传 拖拽/点击]
|
||||
A --> E[分析按钮]
|
||||
E --> F[geminiStream 流式请求]
|
||||
F --> G[axios + onDownloadProgress]
|
||||
G --> H[event.target.responseText 增量提取]
|
||||
H --> I[实时拼接 rawContent]
|
||||
I --> J[parseAnalysis 解析分割]
|
||||
J --> K[五维度卡片渲染]
|
||||
A --> L[状态机: idle/analyzing/done/error]
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── views/
|
||||
│ └── ExamAnalysis.vue # [NEW] 英语试题AI分析页面主组件
|
||||
│ # 包含:双模式输入(文本/图片Tab切换)、
|
||||
│ # 流式调用 Gemini API、实时渲染分析结果、
|
||||
│ # 五维度结构化卡片展示、完整状态管理
|
||||
├── router/
|
||||
│ └── index.js # [MODIFY] 新增 /exam-analysis 路由,
|
||||
│ # import ExamAnalysis 并添加路由条目
|
||||
└── views/
|
||||
└── HomePage.vue # [MODIFY] 第37行 card-4 的 route: null
|
||||
# 改为 route: '/exam-analysis'
|
||||
```
|
||||
|
||||
## 关键实现细节
|
||||
|
||||
### 流式请求核心逻辑
|
||||
|
||||
```js
|
||||
// Gemini API 流式调用(axios + onDownloadProgress)
|
||||
const streamAnalysis = async (prompt, imageBase64 = null) => {
|
||||
let lastLength = 0
|
||||
await axios.post(GEMINI_API_URL, buildRequestBody(prompt, imageBase64), {
|
||||
headers: { 'Content-Type': 'application/json', 'x-goog-api-key': API_KEY },
|
||||
responseType: 'text',
|
||||
onDownloadProgress: (event) => {
|
||||
const text = event.target.responseText
|
||||
const newChunk = text.slice(lastLength)
|
||||
lastLength = text.length
|
||||
// 解析 SSE data 行,提取 text delta
|
||||
rawContent.value += extractTextDelta(newChunk)
|
||||
analysisBlocks.value = parseAnalysis(rawContent.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 分析结果解析
|
||||
|
||||
将 AI 输出按 `## 题干理解 / ## 考点识别 / ## 解题思路 / ## 正确答案 / ## 详细解析` 五个标题分割,每个块独立渲染,支持基础 Markdown(加粗、换行)。
|
||||
|
||||
### 性能注意事项
|
||||
|
||||
- 流式更新频率较高,`parseAnalysis` 使用轻量正则,避免每次 chunk 触发重量级 DOM 操作
|
||||
- 图片 base64 转换在 `FileReader` 异步完成后才启用分析按钮,防止空数据提交
|
||||
- 组件卸载时调用 `axios.CancelToken` 中止未完成的流请求,防止内存泄漏
|
||||
|
||||
## 设计风格
|
||||
|
||||
延续现有项目的深色 Glassmorphism 风格,以 Teal(#14b8a6 / #0d9488)为主题色,与首页 card-4 保持一致。整体布局参考 EssayCorrection.vue 的三段式结构:顶部固定导航栏 + 中部内容区 + 底部结果区。
|
||||
|
||||
## 页面布局
|
||||
|
||||
### 1. 顶部导航栏
|
||||
|
||||
固定在顶部,毛玻璃背景,左侧返回按钮,中间标题"英语试题 AI 分析"(Teal 渐变文字),与其他页面导航栏完全一致的视觉规范。
|
||||
|
||||
### 2. 输入区域(Tab 切换)
|
||||
|
||||
两个 Tab 标签(文本输入 / 图片上传),Teal 色激活态下划线。
|
||||
|
||||
- **文本 Tab**:大尺寸 Textarea,深色背景,Teal 聚焦边框光晕,占位符提示文字
|
||||
- **图片 Tab**:虚线上传区(Teal 色边框),支持拖拽,图片预览缩略图,重新上传按钮
|
||||
|
||||
### 3. 分析按钮
|
||||
|
||||
居中大按钮,Teal 渐变背景,分析中显示旋转 Spinner + "分析中..."文字,禁用态半透明。
|
||||
|
||||
### 4. 分析结果区域
|
||||
|
||||
五个维度卡片纵向排列,每张卡片:
|
||||
|
||||
- 左侧 Teal 色竖线 + 图标 + 标题
|
||||
- 卡片内容区白色文字,支持基础 Markdown 渲染(加粗、换行)
|
||||
- 流式生成中的卡片末尾显示闪烁光标动画
|
||||
- 卡片入场动画(fadeInUp,依次延迟)
|
||||
|
||||
### 5. 错误提示
|
||||
|
||||
红色半透明 Banner,可关闭,与 EssayCorrection.vue 保持一致。
|
||||
|
|
@ -3,6 +3,7 @@ import Home from '../views/HomePage.vue'
|
|||
import Pronunciation from '../views/Pronunciation.vue'
|
||||
import Speaking from '../views/Speaking.vue'
|
||||
import EssayCorrection from '../views/EssayCorrection.vue'
|
||||
import ExamAnalysis from '../views/ExamAnalysis.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
|
|
@ -26,6 +27,11 @@ const router = createRouter({
|
|||
path: '/essay-correction',
|
||||
name: 'essay-correction',
|
||||
component: EssayCorrection
|
||||
},
|
||||
{
|
||||
path: '/exam-analysis',
|
||||
name: 'exam-analysis',
|
||||
component: ExamAnalysis
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -34,7 +34,7 @@ const features = ref([
|
|||
desc: '深度解析长难句、阅读理解及语法考点,为您提供专属错题讲解。',
|
||||
class: 'card-4',
|
||||
icon: 'analytics',
|
||||
route: null
|
||||
route: '/exam-analysis'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
|
|
|
|||
Loading…
Reference in New Issue