1 changed files with 64 additions and 0 deletions
@ -0,0 +1,64 @@ |
|||
# 设计:管理员用户列表 — 逐用户统计与公开页链接 |
|||
|
|||
**日期**:2026-04-18 |
|||
**状态**:已定稿(与产品对话一致) |
|||
|
|||
## 1. 背景与目标 |
|||
|
|||
管理员(代码中与 **`role === 'admin'`** 一致,沿用 `requireAdmin`;不引入新角色)在「用户管理」页需要: |
|||
|
|||
1. **逐用户统计**(表格列):文章数、时间线条目数、RSS 订阅源数。 |
|||
2. **跳转与复制**:当用户存在 **`publicSlug`** 时,可打开站内公开主页 `/@{publicSlug}`,并可将 **完整 URL**(`origin + '/@' + publicSlug`)复制到剪贴板。 |
|||
|
|||
**明确不包含(第一期)**:RSS 条目总数(`rss_items`)、全局汇总卡片、代用户登录、仅按可见性过滤后的计数。 |
|||
|
|||
## 2. 统计语义 |
|||
|
|||
对每位用户,三个计数均为对应表中 **`user_id` 等于该用户 id 的全表行数**,**不按** `visibility` 或其它展示规则过滤。理由:该页面向运营/审计,需反映库内真实数据量;若未来要「仅公开内容」计数,应单独开需求并改字段命名以免歧义。 |
|||
|
|||
## 3. 架构与方案选择 |
|||
|
|||
在已选方案下:**扩展现有 `GET /api/admin/users`**,在同一分页响应中为每个用户返回三个非负整数字段,避免二次请求与 id 合并问题。 |
|||
|
|||
未采用:独立 stats 接口、用户表冗余计数列。 |
|||
|
|||
## 4. API 契约 |
|||
|
|||
- **路径**:`GET /api/admin/users`(不变)。 |
|||
- **鉴权**:现有全局 auth + `requireAdmin`。 |
|||
- **分页**:沿用现有 `limit`(默认 50,最大 100)、`offset`。 |
|||
- **响应**:`users` 数组元素在现有字段(`id`, `username`, `email`, `role`, `status`, `publicSlug`, `createdAt`)基础上增加: |
|||
|
|||
| 字段 | 类型 | 说明 | |
|||
|------|------|------| |
|||
| `postCount` | 整数 ≥ 0 | `posts` 表中该 `user_id` 行数 | |
|||
| `timelineEventCount` | 整数 ≥ 0 | `timeline_events` 表中该 `user_id` 行数 | |
|||
| `rssFeedCount` | 整数 ≥ 0 | `rss_feeds` 表中该 `user_id` 行数 | |
|||
|
|||
实现细节:使用 Drizzle + SQLite 可维护的聚合方式(例如相关子查询或等价 join),以保证与分页 `ORDER BY` 一致且性能可接受;`user_id` 上应可利用现有外键/索引。 |
|||
|
|||
## 5. 前端(用户管理页) |
|||
|
|||
**文件**:`app/pages/me/admin/users/index.vue`(为主变更点)。 |
|||
|
|||
- 表格新增三列,展示上述三个计数。 |
|||
- **`publicSlug` 非空**: |
|||
- **打开**:链到路由 `/@{publicSlug}`(与站内其它公开页一致)。 |
|||
- **复制**:点击后写入剪贴板的 URL 应与浏览器打开 `/@{publicSlug}` 时一致;推荐使用 `URL(\`/@${publicSlug}\`, window.location.origin).href` 生成,避免手写拼接与编码不一致。 |
|||
- **`publicSlug` 为空**:不渲染可点击外链;复制按钮禁用或隐藏,并显示「—」等占位。 |
|||
- **复制失败**:向用户展示简短错误提示(与项目现有 toast/通知模式一致)。 |
|||
|
|||
## 6. 错误与边界 |
|||
|
|||
- 计数为 `0` 时正常显示。 |
|||
- 网络或权限错误沿用现有 `request`/`unwrap` 行为。 |
|||
|
|||
## 7. 测试 |
|||
|
|||
第一期以手动验证为主。若仓库已有 admin 列表或 Drizzle 集成测试惯例,可补充最小用例(例如种子数据下某用户的三个计数);非强制阻塞项,在实现计划中标注。 |
|||
|
|||
## 8. 非目标 |
|||
|
|||
- 不修改 `users` 表结构。 |
|||
- 不增加 `rss_items` 计数列。 |
|||
- 不实现「超级管理员」与 `admin` 的区分。 |
|||
Loading…
Reference in new issue