fix: resolve 10 code review issues
High priority: - Fix concurrent race condition for view_count/like_count (atomic update) - Add route request ID tracking to prevent race conditions - Filter get_joke by status=approved (no pending content leak) - Add error feedback for like button Performance: - Optimize random joke query (avoid full table sort) - Limit page_size max to 100 (DoS prevention) Medium: - Add localStorage quota error handling - Handle empty AI response gracefully - Fix generate content title extraction Low: - Add rejected_jokes to stats API - Update dashboard to show rejected count
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# 智能笑话生成器设计文档
|
||||
|
||||
**日期:** 2026-06-02
|
||||
**状态:** 已批准
|
||||
|
||||
## 功能概述
|
||||
|
||||
用户点击导航栏的「AI生成」按钮,进入生成器页面,输入关键词和/或选择场景,自动调用 AI 生成一条相关笑话。用户可查看、收藏生成的笑话。
|
||||
|
||||
## 用户交互流程
|
||||
|
||||
1. 用户点击导航栏「AI生成」图标 → 跳转 `/generate` 页面
|
||||
2. 用户选择场景(可选,支持多选)→ 用户输入关键词(可选)
|
||||
3. 点击「开始生成」→ 调用 AI → 显示生成的笑话
|
||||
4. 用户可执行以下操作:
|
||||
- 重新生成(使用相同参数)
|
||||
- 收藏到本地
|
||||
- 查看我的收藏
|
||||
- 删除收藏
|
||||
|
||||
## 页面结构
|
||||
|
||||
```
|
||||
/generate
|
||||
├── 场景选择区(chips,可多选 / 手动输入)
|
||||
├── 关键词输入框
|
||||
├── 生成按钮 [开始生成]
|
||||
├── 结果展示区(生成后显示笑话卡片)
|
||||
│ ├── 笑话内容
|
||||
│ └── 操作按钮(重新生成 / 收藏 / 再来一条)
|
||||
└── 我的收藏(localStorage 存储)
|
||||
└── 收藏列表(可删除)
|
||||
```
|
||||
|
||||
## 预设场景选项
|
||||
|
||||
- 职场
|
||||
- 校园
|
||||
- 社交
|
||||
- 家庭
|
||||
- 情感
|
||||
- 搞笑日常
|
||||
|
||||
## API 设计
|
||||
|
||||
### POST /api/generate
|
||||
|
||||
生成 AI 笑话
|
||||
|
||||
**请求体:**
|
||||
```json
|
||||
{
|
||||
"keywords": ["加班", "老板"],
|
||||
"scenario": "职场"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"title": "办公室的一天",
|
||||
"content": "老板问:为什么每天早上都迟到?\n我说:因为堵车。\n老板说:那你为什么不早点出门?\n我说:因为早出门也会堵。\n老板沉默了。",
|
||||
"created_at": "2026-06-02T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**错误响应:**
|
||||
- 401:`{ "detail": "AI 服务未配置" }`
|
||||
- 500:`{ "detail": "生成失败,请重试" }`
|
||||
|
||||
## AI Prompt
|
||||
|
||||
```
|
||||
你是一位幽默大师,专门创作轻松搞笑的短笑话。
|
||||
|
||||
场景:{场景}
|
||||
关键词:{关键词}
|
||||
|
||||
要求:
|
||||
1. 根据场景和关键词创作一条原创笑话
|
||||
2. 笑话要有反转或意外结局
|
||||
3. 语言简洁,30-150字
|
||||
4. 直接输出笑话内容,不需要解释
|
||||
|
||||
格式:
|
||||
标题:xxx
|
||||
内容:xxx
|
||||
```
|
||||
|
||||
## 数据存储
|
||||
|
||||
**收藏数据(localStorage)**
|
||||
```json
|
||||
{
|
||||
"joke_favorites": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"title": "笑话标题",
|
||||
"content": "笑话内容",
|
||||
"created_at": "2026-06-02T12:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 组件清单
|
||||
|
||||
| 组件 | 说明 |
|
||||
|------|------|
|
||||
| HeaderNav 生成按钮 | 导航栏添加 AI 生成图标入口 |
|
||||
| GeneratePage | 生成器主页面 |
|
||||
| ScenarioSelector | 场景选择 chips 组件 |
|
||||
| KeywordInput | 关键词输入框 |
|
||||
| JokeCard | 生成的笑话展示卡片(复用现有 JokeCard 样式) |
|
||||
| FavoriteList | 我的收藏列表 |
|
||||
| FavoriteItem | 收藏项(带删除按钮) |
|
||||
|
||||
## 错误处理
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
|------|----------|
|
||||
| AI 未配置 | Toast 提示「系统暂未配置 AI 服务」 |
|
||||
| 生成失败 | Toast 提示「生成失败,请重试」 |
|
||||
| 网络错误 | Toast 提示「网络错误,请检查网络连接」 |
|
||||
| 加载中 | 按钮显示 loading spinner,禁用点击 |
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 后端
|
||||
- 新增 `POST /api/generate` 接口
|
||||
- 使用现有 AiSetting 配置调用 AI
|
||||
- 返回结构化笑话数据
|
||||
|
||||
### 前端
|
||||
- 新增 `web/src/views/generate/index.vue` 页面
|
||||
- 新增 `web/src/api/generate.js` API 模块
|
||||
- 复用现有组件样式
|
||||
- localStorage 存储收藏数据
|
||||
|
||||
## 文件变更清单
|
||||
|
||||
### 新增文件
|
||||
- `api/app/routers/generate.py` - 生成器后端路由
|
||||
- `api/app/schemas/joke.py` - 添加 GenerateRequest/GenerateResponse schema
|
||||
- `web/src/views/generate/index.vue` - 生成器页面
|
||||
- `web/src/api/generate.js` - 前端 API
|
||||
|
||||
### 修改文件
|
||||
- `api/main.py` - 注册新路由
|
||||
- `web/src/router/index.js` - 添加 /generate 路由
|
||||
- `web/src/components/Header.vue` - 添加生成器入口按钮(如有)
|
||||
Reference in New Issue
Block a user