- Vite + React + TypeScript 项目初始化 - Tailwind CSS v4 + shadcn/ui 配置(button, card, input, label) - React Router v7 路由:登录页、数据看板、题库/分类/用户/设置占位页 - AdminLayout 布局:侧边栏导航 + 顶栏 - ky v2 HTTP 客户端,自动附加 Bearer token - Zustand auth store + localStorage 持久化 - 认证保护:未登录自动重定向到 /login - 数据看板骨架(4 统计卡片 + 图表占位) - 类型定义:question, user, category, api
418 lines
17 KiB
Markdown
418 lines
17 KiB
Markdown
# duoqi-admin 开发规格
|
||
|
||
> 多奇管理后台 — 工程实施指南
|
||
> 本文档为 duoqi-admin 库的自包含开发参考。产品设计细节见 [共享设计文档](../docs/specs/shared/)。
|
||
|
||
---
|
||
|
||
## 一、库职责与定位
|
||
|
||
| 维度 | 内容 |
|
||
|------|------|
|
||
| **库** | `duoqi-admin` |
|
||
| **定位** | 多奇内部管理后台,面向开发者/运营人员 |
|
||
| **产品阶段** | Phase 1 起持续迭代(题库管理从 Phase 1 即需要) |
|
||
| **核心目标** | 题库内容管理、用户管理、数据看板、系统配置 |
|
||
| **用户** | 开发者本人(Phase 1-2),后续可能扩展至运营团队 |
|
||
|
||
### 在架构中的位置
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ duoqi-harmony │ duoqi-flutter │ duoqi-web │ ← 用户端
|
||
└────────┬────────┴────────┬─────────┴────────┬────────┘
|
||
└─────────────────┼───────────────────┘
|
||
│
|
||
duoqi-api (REST API)
|
||
├── /v1/* 用户端 API
|
||
└── /admin/* 管理端 API ← 新增
|
||
│
|
||
┌─────────────────┼───────────────────┐
|
||
│ │ │
|
||
阿里云 RDS MySQL 阿里云 OSS PostHog + ClickHouse
|
||
│
|
||
duoqi-admin (CSR) ← 本库
|
||
调用 /admin/* API
|
||
```
|
||
|
||
---
|
||
|
||
## 二、技术栈
|
||
|
||
| 层面 | 选型 | 版本 | 理由 |
|
||
|------|------|------|------|
|
||
| 框架 | Vite + React | React 18 | CSR 足够,无需 SSR;比 Next.js 轻量 |
|
||
| 语言 | TypeScript | — | 与项目其他仓库统一 |
|
||
| UI 组件 | shadcn/ui | 源码级复用 | 与 duoqi-web 统一,可定制 |
|
||
| 样式 | Tailwind CSS | — | 与 shadcn/ui 集成 |
|
||
| 数据表格 | TanStack Table | v8 | 管理后台核心组件:排序、筛选、分页 |
|
||
| 表单 | React Hook Form + Zod | — | 表单校验,管理后台大量表单 |
|
||
| HTTP 客户端 | ky / fetch | — | 调用 duoqi-api admin 端点 |
|
||
| 路由 | React Router | v7 | CSR 路由,管理后台够用 |
|
||
| 状态管理 | Zustand | — | 与 duoqi-web 统一 |
|
||
| 图表 | Recharts | — | 数据看板可视化 |
|
||
| 运行方式 | `npm run dev` → `vite dev` | — | 生产构建为静态文件,部署至 CDN/OSS |
|
||
|
||
### 选型理由
|
||
|
||
- **Vite + React 而非 Next.js**:管理后台不需要 SEO、不需要 SSR、不需要 API Routes。Vite 更轻量、构建更快、开发体验更好。duoqi-web 用 Next.js 是因为它是面向用户的 Web 产品;admin 是内部工具,没必要承担 Next.js 的复杂度。
|
||
- **shadcn/ui**:与 duoqi-web 统一组件库,降低学习成本,可按需引入组件。
|
||
- **TanStack Table**:管理后台最核心的交互是数据表格(题库列表、用户列表等)。TanStack Table 是 headless table,配合 shadcn/ui 样式,灵活度最高。
|
||
- **Recharts**:轻量 React 图表库,满足数据看板需求(折线图、柱状图、饼图)。
|
||
|
||
---
|
||
|
||
## 三、项目结构
|
||
|
||
```
|
||
duoqi-admin/
|
||
├── CLAUDE.md # Agent 指引
|
||
├── dev-spec.md # 本文件
|
||
├── src/
|
||
│ ├── main.tsx # 入口
|
||
│ ├── App.tsx # 根组件(路由 + 布局)
|
||
│ ├── routes/ # 页面路由
|
||
│ │ ├── __root.tsx # 根布局(侧边栏 + 顶栏)
|
||
│ │ ├── index.tsx # 首页(数据看板)
|
||
│ │ ├── login.tsx # 管理员登录
|
||
│ │ ├── questions/ # 题库管理
|
||
│ │ │ ├── index.tsx # 题目列表
|
||
│ │ │ ├── new.tsx # 新建题目
|
||
│ │ │ └── $id.tsx # 编辑题目
|
||
│ │ ├── categories/ # 分类管理
|
||
│ │ │ ├── index.tsx # 分类列表
|
||
│ │ │ └── new.tsx # 新建/编辑分类
|
||
│ │ ├── knowledge-cards/ # 知识卡管理
|
||
│ │ │ └── index.tsx # 知识卡列表(关联题目)
|
||
│ │ ├── skill-tree/ # 技能树管理
|
||
│ │ │ └── index.tsx # 章节管理
|
||
│ │ ├── users/ # 用户管理
|
||
│ │ │ └── index.tsx # 用户列表
|
||
│ │ ├── feedback/ # 用户反馈
|
||
│ │ │ └── index.tsx # 反馈列表
|
||
│ │ └── settings/ # 系统设置
|
||
│ │ └── index.tsx # 全局配置
|
||
│ ├── components/
|
||
│ │ ├── ui/ # shadcn/ui 基础组件
|
||
│ │ ├── layout/
|
||
│ │ │ ├── Sidebar.tsx # 侧边栏导航
|
||
│ │ │ ├── Header.tsx # 顶栏(管理员信息)
|
||
│ │ │ └── AdminLayout.tsx # 管理布局容器
|
||
│ │ ├── data-table/ # 数据表格封装
|
||
│ │ │ ├── DataTable.tsx # 通用数据表格
|
||
│ │ │ ├── columns.tsx # 列定义工具
|
||
│ │ │ └── filters.tsx # 筛选器组件
|
||
│ │ ├── question-form/ # 题目编辑表单
|
||
│ │ │ ├── QuestionForm.tsx # 题目表单主组件
|
||
│ │ │ ├── StemEditor.tsx # 题干编辑(支持多媒体)
|
||
│ │ │ └── DistractorEditor.tsx # 干扰项编辑
|
||
│ │ └── charts/ # 图表组件
|
||
│ │ ├── StatsCard.tsx # 统计卡片
|
||
│ │ ├── LineChart.tsx # 折线图
|
||
│ │ └── BarChart.tsx # 柱状图
|
||
│ ├── lib/
|
||
│ │ ├── api-client.ts # duoqi-api HTTP 客户端(admin 端点)
|
||
│ │ ├── auth.ts # admin 认证(token 管理)
|
||
│ │ ├── utils.ts # 工具函数
|
||
│ │ └── constants.ts # 常量(状态枚举、难度等级等)
|
||
│ ├── hooks/
|
||
│ │ ├── use-auth.ts # 认证状态 hook
|
||
│ │ └── use-pagination.ts # 分页 hook
|
||
│ ├── stores/
|
||
│ │ └── auth-store.ts # 认证状态
|
||
│ └── types/
|
||
│ ├── question.ts # 题目相关类型
|
||
│ ├── user.ts # 用户相关类型
|
||
│ ├── category.ts # 分类相关类型
|
||
│ └── api.ts # API 响应类型
|
||
├── public/
|
||
│ └── favicon.svg
|
||
├── package.json
|
||
├── vite.config.ts
|
||
├── tailwind.config.ts
|
||
├── tsconfig.json
|
||
└── .env.example
|
||
```
|
||
|
||
---
|
||
|
||
## 四、功能范围
|
||
|
||
### 4.1 Phase 1 — 基础管理(与 duoqi-api Phase 1 并行)
|
||
|
||
| # | 功能 | 页面 | 说明 |
|
||
|---|------|------|------|
|
||
| 1 | **管理员登录** | `/login` | 环境变量 admin token 认证(Phase 1 只有你一人) |
|
||
| 2 | **题库 CRUD** | `/questions` | 新建/编辑/删除/发布题目,支持批量操作 |
|
||
| 3 | **分类管理** | `/categories` | 管理题库分类(中国历史、经典剧集、相声小品) |
|
||
| 4 | **知识卡编辑** | `/knowledge-cards` | 编辑基础版 + 深度版知识卡 |
|
||
| 5 | **技能树管理** | `/skill-tree` | 管理章节结构、排序、通过条件 |
|
||
| 6 | **数据看板** | `/` | 基础统计:用户数、答题数、正确率、留存 |
|
||
| 7 | **题目状态流转** | 题目编辑页 | 草稿 → 审核中 → 已发布 → 已下架 |
|
||
|
||
### 4.2 Phase 2 — 用户与运营
|
||
|
||
| # | 功能 | 页面 | 说明 |
|
||
|---|------|------|------|
|
||
| 8 | **用户列表** | `/users` | 查看用户、搜索、查看详情 |
|
||
| 9 | **用户反馈** | `/feedback` | 查看用户反馈(👍👎)和意见反馈 |
|
||
| 10 | **订阅管理** | `/users/$id` | 查看/调整用户订阅状态 |
|
||
| 11 | **批量导入** | `/questions` | 从 JSON/CSV 批量导入题目 |
|
||
|
||
### 4.3 Phase 3 — UGC 审核
|
||
|
||
| # | 功能 | 页面 | 说明 |
|
||
|---|------|------|------|
|
||
| 12 | **UGC 审核** | `/questions?source=ugc` | 用户投稿题目审核队列 |
|
||
| 13 | **举报处理** | `/reports` | 处理用户举报内容 |
|
||
| 14 | **运营配置** | `/settings` | 活动配置、推送文案管理 |
|
||
|
||
---
|
||
|
||
## 五、页面设计
|
||
|
||
### 5.1 布局结构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────┐
|
||
│ Header — 多奇管理后台 管理员: admin 退出 │
|
||
├──────────┬──────────────────────────────────────┤
|
||
│ │ │
|
||
│ 侧边栏 │ 主内容区 │
|
||
│ │ │
|
||
│ 数据看板 │ 页面标题 + 操作按钮 │
|
||
│ 题库管理 │ ───────────────────── │
|
||
│ 题目 │ │
|
||
│ 分类 │ 数据表格 / 表单 / 图表 │
|
||
│ 知识卡 │ │
|
||
│ 技能树 │ │
|
||
│ 用户管理 │ │
|
||
│ 用户反馈 │ │
|
||
│ 系统设置 │ │
|
||
│ │ │
|
||
└──────────┴──────────────────────────────────────┘
|
||
```
|
||
|
||
### 5.2 页面清单
|
||
|
||
#### 数据看板(首页)
|
||
|
||
| 区域 | 内容 |
|
||
|------|------|
|
||
| 统计卡片 | 总用户数、今日活跃、总答题数、平均正确率 |
|
||
| 折线图 | 近 7/30 天 DAU 趋势 |
|
||
| 柱状图 | 各分类答题量分布 |
|
||
| 排行 | 今日答题最多用户 Top 5 |
|
||
|
||
#### 题目列表
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 数据表格 | 列:ID、题干摘要、分类、难度、状态、创建时间、操作 |
|
||
| 筛选 | 按分类、难度、状态筛选 |
|
||
| 搜索 | 按题干文本搜索 |
|
||
| 批量操作 | 批量发布、批量下架、批量删除 |
|
||
| 排序 | 按创建时间、难度排序 |
|
||
|
||
#### 题目编辑
|
||
|
||
| 区域 | 内容 |
|
||
|------|------|
|
||
| 题干编辑 | 文本输入 + 多媒体上传(图片/音频/视频) |
|
||
| 正确答案 | 文本输入 |
|
||
| 干扰项 | 多行输入,至少 3 个干扰项(出题时随机抽 2 个) |
|
||
| 分类选择 | 下拉选择 |
|
||
| 难度选择 | 1-5 级 |
|
||
| 知识卡编辑 | 基础版摘要(必填)+ 深度版(可选,Pro 专属) |
|
||
| 状态操作 | 保存草稿 / 提交审核 / 发布 |
|
||
|
||
#### 分类管理
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 列表 | ID、名称、slug、题目数量、状态 |
|
||
| 编辑 | 名称、slug、父分类、排序、状态 |
|
||
| 统计 | 每个分类的题目数和答题数据 |
|
||
|
||
---
|
||
|
||
## 六、Admin API 端点(duoqi-api 新增)
|
||
|
||
duoqi-api 需要新增以下 admin 路由,所有路由需要 admin 权限中间件。
|
||
|
||
### 6.1 认证
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/admin/auth/login` | 管理员登录(token 验证) |
|
||
| GET | `/admin/auth/me` | 获取当前管理员信息 |
|
||
|
||
### 6.2 题库管理
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/questions` | 题目列表(分页、筛选、搜索) |
|
||
| GET | `/admin/questions/:id` | 题目详情(含正确答案和干扰项) |
|
||
| POST | `/admin/questions` | 创建题目 |
|
||
| PUT | `/admin/questions/:id` | 更新题目 |
|
||
| DELETE | `/admin/questions/:id` | 删除题目 |
|
||
| PATCH | `/admin/questions/:id/status` | 更新题目状态 |
|
||
| POST | `/admin/questions/batch` | 批量操作(发布/下架/删除) |
|
||
| POST | `/admin/questions/import` | 批量导入题目 |
|
||
|
||
### 6.3 分类管理
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/categories` | 分类列表 |
|
||
| POST | `/admin/categories` | 创建分类 |
|
||
| PUT | `/admin/categories/:id` | 更新分类 |
|
||
| DELETE | `/admin/categories/:id` | 删除分类 |
|
||
|
||
### 6.4 知识卡管理
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/knowledge-cards` | 知识卡列表 |
|
||
| PUT | `/admin/knowledge-cards/:id` | 更新知识卡 |
|
||
|
||
### 6.5 技能树管理
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/skill-tree` | 技能树章节列表 |
|
||
| POST | `/admin/skill-tree` | 创建章节 |
|
||
| PUT | `/admin/skill-tree/:id` | 更新章节 |
|
||
| DELETE | `/admin/skill-tree/:id` | 删除章节 |
|
||
| PATCH | `/admin/skill-tree/reorder` | 调整章节排序 |
|
||
|
||
### 6.6 用户管理
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/users` | 用户列表(分页、搜索) |
|
||
| GET | `/admin/users/:id` | 用户详情 |
|
||
| PATCH | `/admin/users/:id` | 更新用户(封禁、调整 tier) |
|
||
|
||
### 6.7 数据看板
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/stats/overview` | 总览统计(用户数、答题数、正确率) |
|
||
| GET | `/admin/stats/daily` | 每日数据趋势(DAU、答题量) |
|
||
| GET | `/admin/stats/categories` | 各分类答题分布 |
|
||
|
||
### 6.8 用户反馈
|
||
|
||
| 方法 | 路由 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/admin/feedback` | 反馈列表(分页) |
|
||
| PATCH | `/admin/feedback/:id` | 更新反馈状态(已读/已处理) |
|
||
|
||
---
|
||
|
||
## 七、认证方案
|
||
|
||
### Phase 1:静态 Token
|
||
|
||
Phase 1 只有开发者一人使用,认证方案极简:
|
||
|
||
```
|
||
登录流程:
|
||
1. 访问 /login
|
||
2. 输入 admin token(环境变量 ADMIN_TOKEN 的值)
|
||
3. 前端调用 POST /admin/auth/login { token }
|
||
4. 后端验证 token,签发 admin JWT
|
||
5. 前端存储 admin JWT,后续请求携带
|
||
|
||
中间件验证:
|
||
- Authorization: Bearer <admin_jwt>
|
||
- 后端验证 JWT 中的 role: 'admin'
|
||
```
|
||
|
||
### Phase 2+:账号密码(可选)
|
||
|
||
如需多人使用,扩展为用户名 + 密码登录。
|
||
|
||
---
|
||
|
||
## 八、环境变量
|
||
|
||
```env
|
||
# duoqi-api 地址
|
||
VITE_API_BASE_URL=http://localhost:3000
|
||
|
||
# 无需其他环境变量(admin token 通过登录页输入)
|
||
```
|
||
|
||
---
|
||
|
||
## 九、阶段路线图
|
||
|
||
### Phase 1a — 骨架搭建(与 duoqi-api Phase 1a 同步)
|
||
|
||
```
|
||
├── 项目初始化(Vite + React + TypeScript + Tailwind)
|
||
├── shadcn/ui 配置 + 基础组件引入
|
||
├── 路由配置 + 管理布局(侧边栏 + 顶栏)
|
||
├── API 客户端封装 + admin 认证
|
||
├── 登录页
|
||
└── 数据看板骨架(统计卡片 + 占位图表)
|
||
```
|
||
|
||
### Phase 1b — 题库管理核心(与 duoqi-api Phase 1b 同步)
|
||
|
||
```
|
||
├── 题目列表(DataTable + 筛选 + 搜索 + 分页)
|
||
├── 题目编辑表单(题干、正确答案、干扰项、分类、难度)
|
||
├── 知识卡编辑(基础版 + 深度版)
|
||
├── 分类管理(CRUD)
|
||
├── 题目状态流转(草稿 → 审核 → 发布 → 下架)
|
||
└── 批量导入题目(JSON)
|
||
```
|
||
|
||
### Phase 1c — 完善(与 duoqi-api Phase 1c 同步)
|
||
|
||
```
|
||
├── 技能树章节管理
|
||
├── 数据看板真实数据(对接 stats API)
|
||
├── 批量操作(发布/下架/删除)
|
||
└── 用户列表基础版(只读)
|
||
```
|
||
|
||
### Phase 2 — 用户与运营
|
||
|
||
```
|
||
├── 用户详情页(进度、订阅、答题历史)
|
||
├── 用户反馈管理
|
||
├── 订阅状态管理
|
||
└── 导出功能(CSV)
|
||
```
|
||
|
||
### Phase 3 — UGC 审核
|
||
|
||
```
|
||
├── UGC 题目审核队列
|
||
├── 举报处理
|
||
├── 运营配置(活动、推送文案)
|
||
└── 多管理员支持(账号密码登录)
|
||
```
|
||
|
||
---
|
||
|
||
## 十、设计文档索引
|
||
|
||
| 文档 | 路径 | 本库相关章节 |
|
||
|------|------|-------------|
|
||
| 题目格式设计 | [shared/question-format-design.md](../docs/specs/shared/question-format-design.md) | 全文(题目 CRUD 核心数据模型) |
|
||
| 游戏化+变现设计 | [shared/gamification-monetization-design.md](../docs/specs/shared/gamification-monetization-design.md) | §2(技能树结构) |
|
||
| 数据埋点设计 | [shared/analytics-feedback-design.md](../docs/specs/shared/analytics-feedback-design.md) | 数据看板参考 |
|
||
| 产品总纲 | [product-overview.md](../docs/product-overview.md) | 内容策略、阶段路线图 |
|
||
| 技术选型 | [tech-stack.md](../docs/tech-stack.md) | §六(代码库组织) |
|
||
| duoqi-api 开发规格 | [duoqi-api/dev-spec.md](../docs/specs/duoqi-api/dev-spec.md) | §四(数据库设计)、§五(API 设计) |
|
||
|
||
---
|
||
|
||
*创建日期:2026-04-06*
|
||
*状态:Phase 1 待启动开发(与 duoqi-api Phase 1a 同步搭建)*
|