- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件 - 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow: 构建前端上传到 build/,再在服务器上 git pull 并重建容器 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.7 KiB
作品广场管理页设计
背景
作品广场当前已有学生浏览页 /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
返回所有奖项,包括未启用和空奖项。每个奖项包含:
idnamedescriptionsort_orderis_activeitem_orderingitem_count
POST /api/submission/showcase/manage/awards
创建奖项。请求字段:
namedescriptionsort_orderis_activeitem_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_idusernametask_titletask_displayscoreview_counthas_prompt_chain
提交不存在时返回 404。普通用户不能访问该接口。
奖项作品管理
GET /api/submission/showcase/manage/awards/{award_id}/items
返回该奖项下所有获奖作品。每项包含:
id:SubmissionAward.idsubmission_idusernametask_titletask_displayscoreview_countsort_orderawarded_athas_prompt_chain
排序规则沿用奖项的 item_ordering:
manual:按SubmissionAward.sort_order。awarded_at:按授奖时间倒序。score:按提交评分倒序。view_count:按浏览量倒序。
POST /api/submission/showcase/manage/awards/{award_id}/items
把提交作品加入奖项。请求字段:
submission_idsort_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 中新增管理页使用的类型:
AwardManageOutAwardManageInAwardItemManageOutAwardItemInAwardItemUpdateIn
数据流
- 进入
/dashboard/showcase后加载奖项列表。 - 自动选中第一个奖项,并加载该奖项作品。
- 保存奖项后刷新奖项列表,并保留当前选中项。
- 点击“添加作品”后打开弹窗,粘贴
submission_id并查找提交。 - 找到提交后展示提交者、任务、分数、浏览量和提示词状态。
- 确认添加后刷新当前奖项作品,同时刷新左侧作品数量。
- 修改作品手动排序值后刷新当前奖项作品。
错误处理
- 奖项名称重复时后端返回 400,前端显示错误消息。
- 奖项、作品关联或待添加提交不存在时返回 404,前端显示错误消息。
- 普通用户访问管理 API 返回 403。
- 网络或未知错误沿用现有 Axios 拦截器,同时管理页局部停止 loading 状态。
测试
后端测试覆盖:
- 普通用户不能访问作品广场管理接口。
- 管理员可以创建、编辑、启停奖项。
- 管理员可以通过
submission_id查找提交作品摘要。 - 管理员可以给提交作品授奖。
- 重复授奖不会创建重复关联。
- 移除授奖后,学生广场列表不再返回该作品。
- 奖项停用后,学生广场列表不返回该奖项。
前端验证覆盖:
- Dashboard 中管理员能看到“作品广场”菜单,普通学生看不到。
- 奖项列表、奖项编辑、作品列表能正常加载。
- 粘贴
submission_id查找作品并加入奖项后,已授奖作品列表更新。 - 删除或停用奖项后,学生
/showcase表现符合预期。
后续增强
- 拖拽排序。
- 批量授奖。
- 按班级、挑战、作者筛选广场。
- 在提交列表中提供“加入作品广场”快捷入口。