Files
web/docs/superpowers/specs/2026-05-01-showcase-management-design.md
xuyueandClaude Opus 5.5 47d4679984 chore: 合并为单仓库,统一部署流程
- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件
- 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow:
  构建前端上传到 build/,再在服务器上 git pull 并重建容器

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:02:12 +08:00

230 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 作品广场管理页设计
## 背景
作品广场当前已有学生浏览页 `/showcase` 和详情页 `/showcase/:id`。奖项与获奖作品的数据模型已经存在:
- `Award`:奖项名称、简介、启用状态、奖项排序、作品排序方式。
- `SubmissionAward`:提交作品与奖项的关联、手动排序值、授奖时间。
目前日常管理只能通过 Django Admin 完成,不适合老师在前端工作流中维护作品广场。
## 目标
在现有 Dashboard 中新增“作品广场”管理页,让管理员可以完成作品广场的日常维护:
- 创建、编辑、启停、删除奖项。
- 配置奖项在广场中的顺序。
- 配置奖项内作品排序方式。
- 通过复制来的 `submission_id` 查找提交作品,并把作品加入指定奖项。
- 查看、移除、调整奖项内作品。
## 非目标
- 不做公开代码查看。学生侧仍只展示运行效果和创作过程。
- 不做拖拽排序,第一版使用数字排序值。
- 不做批量导入或批量授奖。
- 不改变现有学生广场接口返回结构,避免影响 `/showcase`。
## 权限
管理页只对 `admin` 和 `super` 可见。
后端管理 API 使用 `admin_required` 限制。普通学生访问管理 API 返回 403,未登录用户返回登录态错误。
学生浏览页保持现状:登录用户可访问 `/showcase` 和 `/showcase/:id`。
## 前端入口
在 `Dashboard.vue` 侧栏新增菜单:
- 标签:`作品广场`
- 路由:`/dashboard/showcase`
- 可见角色:`admin`、`super`
新增页面文件:
- `client/src/pages/ShowcaseManage.vue`
## 页面结构
页面采用左右分栏,延续现有 Dashboard 的工具型界面风格。
左侧为奖项列表:
- 新建奖项按钮。
- 奖项名称。
- 启用状态。
- 展示排序值。
- 作品排序方式。
- 当前作品数量。
右侧为选中奖项详情:
- 奖项编辑表单:名称、简介、排序值、是否启用、作品排序方式。
- 保存按钮。
- 删除奖项按钮。
- 已授奖作品表格:作者、任务、分数、浏览量、手动排序值、授奖时间。
- 每行支持修改手动排序值和移除作品。
- 添加作品按钮:打开添加作品弹窗,粘贴 `submission_id` 后查找对应提交,确认无误后加入当前奖项。
当没有选中奖项时,右侧显示空状态。创建第一个奖项后自动选中。
## 后端 API
新增管理接口,放在 `submission/api.py`,路径位于现有 `/submission/showcase/` 下。
### 奖项管理
`GET /api/submission/showcase/manage/awards`
返回所有奖项,包括未启用和空奖项。每个奖项包含:
- `id`
- `name`
- `description`
- `sort_order`
- `is_active`
- `item_ordering`
- `item_count`
`POST /api/submission/showcase/manage/awards`
创建奖项。请求字段:
- `name`
- `description`
- `sort_order`
- `is_active`
- `item_ordering`
`PUT /api/submission/showcase/manage/awards/{award_id}`
更新奖项。字段同创建接口。
`DELETE /api/submission/showcase/manage/awards/{award_id}`
删除奖项。级联删除该奖项下的 `SubmissionAward` 关联,不删除提交作品本身。
### 作品查找
`GET /api/submission/showcase/manage/submissions/{submission_id}`
按提交 ID 查找一条提交,用于添加作品前确认。该接口只返回管理页需要的摘要,不返回 HTML/CSS/JS 源码。返回字段:
- `submission_id`
- `username`
- `task_title`
- `task_display`
- `score`
- `view_count`
- `has_prompt_chain`
提交不存在时返回 404。普通用户不能访问该接口。
### 奖项作品管理
`GET /api/submission/showcase/manage/awards/{award_id}/items`
返回该奖项下所有获奖作品。每项包含:
- `id`:`SubmissionAward.id`
- `submission_id`
- `username`
- `task_title`
- `task_display`
- `score`
- `view_count`
- `sort_order`
- `awarded_at`
- `has_prompt_chain`
排序规则沿用奖项的 `item_ordering`:
- `manual`:按 `SubmissionAward.sort_order`。
- `awarded_at`:按授奖时间倒序。
- `score`:按提交评分倒序。
- `view_count`:按浏览量倒序。
`POST /api/submission/showcase/manage/awards/{award_id}/items`
把提交作品加入奖项。请求字段:
- `submission_id`
- `sort_order`
如果同一作品已在该奖项中,返回现有关联,不重复创建。
`PUT /api/submission/showcase/manage/items/{item_id}`
更新获奖作品关联,目前只更新 `sort_order`。
`DELETE /api/submission/showcase/manage/items/{item_id}`
移除获奖作品关联,不删除提交作品。
## 前端 API 客户端
在 `client/src/api.ts` 中扩展 `Showcase`:
- `listManageAwards()`
- `createAward(payload)`
- `updateAward(id, payload)`
- `deleteAward(id)`
- `listAwardItems(id)`
- `findSubmissionForAward(submissionId)`
- `addAwardItem(id, payload)`
- `updateAwardItem(itemId, payload)`
- `deleteAwardItem(itemId)`
在 `client/src/utils/type.ts` 中新增管理页使用的类型:
- `AwardManageOut`
- `AwardManageIn`
- `AwardItemManageOut`
- `AwardItemIn`
- `AwardItemUpdateIn`
## 数据流
1. 进入 `/dashboard/showcase` 后加载奖项列表。
2. 自动选中第一个奖项,并加载该奖项作品。
3. 保存奖项后刷新奖项列表,并保留当前选中项。
4. 点击“添加作品”后打开弹窗,粘贴 `submission_id` 并查找提交。
5. 找到提交后展示提交者、任务、分数、浏览量和提示词状态。
6. 确认添加后刷新当前奖项作品,同时刷新左侧作品数量。
7. 修改作品手动排序值后刷新当前奖项作品。
## 错误处理
- 奖项名称重复时后端返回 400,前端显示错误消息。
- 奖项、作品关联或待添加提交不存在时返回 404,前端显示错误消息。
- 普通用户访问管理 API 返回 403。
- 网络或未知错误沿用现有 Axios 拦截器,同时管理页局部停止 loading 状态。
## 测试
后端测试覆盖:
- 普通用户不能访问作品广场管理接口。
- 管理员可以创建、编辑、启停奖项。
- 管理员可以通过 `submission_id` 查找提交作品摘要。
- 管理员可以给提交作品授奖。
- 重复授奖不会创建重复关联。
- 移除授奖后,学生广场列表不再返回该作品。
- 奖项停用后,学生广场列表不返回该奖项。
前端验证覆盖:
- Dashboard 中管理员能看到“作品广场”菜单,普通学生看不到。
- 奖项列表、奖项编辑、作品列表能正常加载。
- 粘贴 `submission_id` 查找作品并加入奖项后,已授奖作品列表更新。
- 删除或停用奖项后,学生 `/showcase` 表现符合预期。
## 后续增强
- 拖拽排序。
- 批量授奖。
- 按班级、挑战、作者筛选广场。
- 在提交列表中提供“加入作品广场”快捷入口。