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:
bwstudio
2026-06-02 20:35:08 +08:00
parent 0b43973236
commit ceed63fcb0
144 changed files with 191660 additions and 270 deletions
@@ -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` - 添加生成器入口按钮(如有)