一、超管端设计优化 - 文档管理SOP体系建立,docs目录重组 - 统一用户管理:跨租户全局视角,合并用户管理+公众用户 - 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作) - 菜单精简:移除评委管理/评审规则/通知管理 - Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一 二、UGC绘本创作社区P0 - 数据库:10张新表(user_works/user_work_pages/work_tags等) - 子女账号独立化:Child升级为独立User,家长切换+独立登录 - 用户作品库:CRUD+发布审核,8个API - AI创作流程:提交→生成→保存到作品库,4个API - 作品广场:首页改造为推荐流,标签+搜索+排序 - 内容审核(超管端):作品审核+作品管理+标签管理 - 活动联动:WorkSelector作品选择器 - 布局改造:底部5Tab(发现/创作/活动/作品库/我的) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
24 KiB
24 KiB
赛事管理模块产品方案与实现计划
📋 目录
产品交互方案
1. 赛事创建
1.1 功能概述
管理员创建赛事,填写赛事基本信息、时间安排、参赛范围等。
1.2 交互流程
管理员进入"赛事管理" → 点击"创建赛事" → 填写表单 → 保存草稿/提交审核
1.3 表单字段(基于 t_contest 表)
-
基本信息
- 赛事名称(必填,唯一性校验)
- 赛事类型(字典:individual/team)
- 赛事状态(默认:unpublished)
- 封面图(上传)
- 海报图(上传)
- 赛事详情(富文本编辑器)
-
时间安排
- 赛事开始时间
- 赛事结束时间
- 报名开始时间
- 报名结束时间
- 作品提交开始时间
- 作品提交结束时间
- 评审开始时间
- 评审结束时间
- 结果发布时间(可选)
-
参赛范围
- 授权租户(多选,支持租户列表选择)
- 提交规则(once/resubmit)
-
联系信息
- 联系人姓名
- 联系电话
- 联系人二维码(上传)
-
组织信息
- 主办单位(数组)
- 协办单位(数组)
- 赞助单位(数组)
-
线下信息
- 线下地址(可选)
-
评审规则
- 评审规则ID(关联评审规则配置)
1.4 业务规则
- 时间顺序校验:报名开始 < 报名结束 < 提交开始 < 提交结束 < 评审开始 < 评审结束 < 结果发布
- 赛事名称在系统内唯一
- 创建后状态为
unpublished,需要发布后才能被租户看到 - 支持保存草稿(可多次编辑)
2. 赛事发布
2.1 功能概述
管理员将已创建的赛事发布,使其对授权租户可见。
2.2 交互流程
赛事列表 → 选择赛事 → 点击"发布" → 确认发布 → 更新状态为 published
2.3 业务规则
- 只有状态为
unpublished的赛事可以发布 - 发布前校验必填字段完整性
- 发布后,授权租户可以看到该赛事
- 已发布的赛事可以撤回(状态改回
unpublished),但需要检查是否有报名记录
3. 赛事公告
3.1 功能概述
管理员发布赛事相关公告,通知参赛者重要信息。
3.2 交互流程
赛事详情页 → "公告管理" → 创建公告 → 编辑内容 → 发布公告
3.3 功能设计
注意:当前 SQL 中没有公告表,需要新增:
t_contest_notice表- id, contest_id, title, content, notice_type, priority, publish_time, creator, create_time, modify_time, valid_state
3.4 公告类型
- 系统公告(系统自动生成)
- 人工公告(管理员发布)
- 紧急通知(高优先级)
4. 赛事报名
4.1 功能概述
授权租户的用户(学生/老师)报名参加赛事,支持个人赛和团队赛。
4.2 交互流程
个人赛报名:
租户用户登录 → 浏览已发布赛事 → 选择赛事 → 点击"立即报名" → 填写信息 → 提交报名
团队赛报名:
队长创建团队 → 邀请成员 → 成员确认加入 → 队长提交团队报名 → 等待审核
4.3 报名流程详细设计
4.3.1 个人赛报名
- 用户选择赛事
- 检查报名时间是否在有效期内
- 检查用户是否已报名(防止重复报名)
- 填写报名信息(账号信息自动填充)
- 提交报名(状态:pending)
- 管理员审核(可选,根据赛事配置)
- 审核通过(状态:passed)或拒绝(状态:rejected)
4.3.2 团队赛报名
- 队长创建团队
- 填写团队名称(租户内唯一)
- 设置最大成员数
- 邀请成员(通过账号搜索)
- 成员确认加入
- 收到邀请通知
- 确认/拒绝加入
- 队长提交团队报名
- 检查团队成员数量是否符合要求
- 提交报名(所有成员状态:pending)
- 管理员审核团队报名
- 审核通过:所有成员状态改为 passed
- 审核拒绝:所有成员状态改为 rejected
4.4 数据表关系
t_contest_registration:报名记录表- 个人赛:registration_type = 'individual',team_id = null
- 团队赛:registration_type = 'team',team_id 关联 t_contest_team
t_contest_team:团队表t_contest_team_member:团队成员表
4.5 业务规则
- 报名时间限制:必须在
register_start_time和register_end_time之间 - 报名状态流转:pending → passed/rejected/withdrawn
- 已通过的报名可以撤回(withdrawn),但需要检查是否已提交作品
- 团队名称在同一赛事、同一租户内唯一
- 团队成员角色:leader(队长)、member(队员)、mentor(指导教师)
5. 赛事作品提交
5.1 功能概述
已报名的用户提交参赛作品,支持单次提交和多次提交(根据赛事配置)。
5.2 交互流程
已报名用户 → 进入"我的赛事" → 选择赛事 → 点击"提交作品" → 上传作品文件 → 填写作品信息 → 提交
5.3 作品提交表单
- 作品标题(必填)
- 作品说明(可选)
- 作品文件(支持多文件上传)
- 图片、视频、3D模型等
- 文件类型和大小限制
- 作品预览URL(可选,用于3D/视频预览)
- AI建模元数据(可选,JSON格式)
5.4 提交规则
单次提交(submit_rule = 'once'):
- 只能提交一次作品
- 提交后状态为
submitted,不可修改
多次提交(submit_rule = 'resubmit'):
- 可以多次提交作品
- 每次提交创建新版本(version 递增)
- 旧版本
is_latest = 0,新版本is_latest = 1 - 只有最新版本参与评审
5.5 数据表关系
t_contest_work:作品主表- entry_id 关联 t_contest_registration.id
- files 字段存储简易文件列表(JSON)
t_contest_work_attachment:作品附件表(详细文件信息)
5.6 业务规则
- 提交时间限制:必须在
submit_start_time和submit_end_time之间 - 必须已通过报名审核(registration_state = 'passed')
- 作品编号(work_no)自动生成,格式:CONTEST-{contest_id}-{序号}
- 作品状态流转:
- submitted(已提交)
- locked(已锁定,不可修改)
- reviewing(评审中)
- rejected(已拒绝)
- accepted(已接受)
6. 赛事作品评审
6.1 功能概述
评委对提交的作品进行评分,支持多维度评分和评语。
6.2 交互流程
评委登录 → 进入"评审管理" → 选择赛事 → 查看分配的作品列表 → 点击作品 → 查看作品详情 → 评分 → 提交评分
6.3 评审流程设计
6.3.1 作品分配
- 需要新增表:
t_contest_work_judge_assignment(作品分配表)- id, contest_id, work_id, judge_id, assignment_time, status
- 管理员或系统自动分配作品给评委
- 支持手动分配和自动分配(轮询、随机等)
6.3.2 评分界面
- 显示作品信息(标题、说明、文件、预览等)
- 显示评审规则(review_rule_id 关联的评审规则)
- 多维度评分表单
- 根据评审规则动态生成评分维度
- 每个维度设置分数范围
- 总分自动计算(根据评审规则配置的权重)
- 评语输入框
- 提交评分按钮
6.3.3 评分数据
t_contest_work_score:评分表- dimension_scores:JSON格式,存储各维度分数
- total_score:总分(根据规则计算)
- comments:评语
6.4 评审规则设计
需要新增表:t_contest_review_rule(评审规则表)
- id, contest_id, rule_name, dimensions(JSON,存储评分维度配置)
- 示例维度配置:
{ "dimension1": { "name": "创意性", "weight": 0.3, "maxScore": 100 }, "dimension2": { "name": "技术性", "weight": 0.4, "maxScore": 100 }, "dimension3": { "name": "完成度", "weight": 0.3, "maxScore": 100 } }
6.5 业务规则
- 评审时间限制:必须在
review_start_time和review_end_time之间 - 作品状态更新:评审开始时,作品状态改为
reviewing - 每个作品可以被多个评委评审
- 最终得分计算:取所有评委的平均分,或根据评审规则计算
- 评审完成后,作品状态改为
accepted或rejected
7. 赛事结果公布
7.1 功能概述
管理员公布赛事评审结果,包括获奖名单、排名等。
7.2 交互流程
管理员 → 进入"赛事管理" → 选择赛事 → 点击"公布结果" → 确认公布 → 结果发布
7.3 结果公布内容
- 获奖名单(按奖项分类)
- 作品排名(按总分排序)
- 各维度平均分统计
- 评审统计信息(参与评审人数、作品数量等)
7.4 业务规则
- 只有评审已完成的赛事可以公布结果
- 公布后,
result_publish_time设置为当前时间 - 结果公布后,所有用户可以看到排名和获奖信息
- 支持导出结果(Excel/PDF)
数据库设计分析
现有表结构
1. t_contest(赛事表)
✅ 优点:
- 字段设计完整,覆盖赛事全生命周期
- 支持多租户(contest_tenant 字段)
- 时间字段齐全
⚠️ 注意事项:
contest_tenant使用 text 类型存储租户列表,建议考虑 JSON 类型或关联表organizers、co_organizers、sponsors使用 text 存储数组,建议使用 JSON
2. t_contest_attachment(赛事附件表)
✅ 设计合理,支持多种文件类型
3. t_contest_work(作品表)
✅ 优点:
- 支持版本控制(version、is_latest)
- 支持多种提交来源(teacher/student/team_leader)
- 支持 AI 建模元数据
⚠️ 问题:
- 索引
idx_submit_filter引用了不存在的字段review_status,应删除或修正
4. t_contest_work_attachment(作品附件表)
⚠️ 问题:
- 第102行末尾有多余的逗号,需要删除
5. t_contest_work_score(评分表)
⚠️ 问题:
- 表定义重复(104-123行和125-144行),需要删除重复定义
6. t_contest_registration(报名表)
✅ 设计合理,支持个人和团队报名
7. t_contest_team(团队表)
⚠️ 问题:
- 唯一索引
uk_team_name引用了不存在的字段name,应改为team_name
8. t_contest_team_member(团队成员表)
✅ 设计合理
缺失的表结构
1. t_contest_notice(赛事公告表)
CREATE TABLE `t_contest_notice` (
`id` varchar(63) NOT NULL COMMENT '主键id',
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
`title` varchar(255) NOT NULL COMMENT '公告标题',
`content` text NOT NULL COMMENT '公告内容',
`notice_type` varchar(31) NOT NULL DEFAULT 'manual' COMMENT '公告类型:system/manual/urgent',
`priority` int DEFAULT 0 COMMENT '优先级(数字越大优先级越高)',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`valid_state` varchar(1) NOT NULL DEFAULT '1' COMMENT '有效状态(1-有效,2-失效)',
PRIMARY KEY (`id`),
KEY `idx_contest` (`contest_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='赛事公告表';
2. t_contest_review_rule(评审规则表)
CREATE TABLE `t_contest_review_rule` (
`id` varchar(63) NOT NULL COMMENT '主键id',
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
`rule_name` varchar(127) NOT NULL COMMENT '规则名称',
`dimensions` json NOT NULL COMMENT '评分维度配置JSON',
`calculation_rule` varchar(31) DEFAULT 'average' COMMENT '计算规则:average/max/min/weighted',
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`valid_state` varchar(1) NOT NULL DEFAULT '1' COMMENT '有效状态(1-有效,2-失效)',
PRIMARY KEY (`id`),
KEY `idx_contest` (`contest_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评审规则表';
3. t_contest_work_judge_assignment(作品分配表)
CREATE TABLE `t_contest_work_judge_assignment` (
`id` varchar(63) NOT NULL COMMENT '主键id',
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
`work_id` varchar(63) NOT NULL COMMENT '作品id',
`judge_id` varchar(63) NOT NULL COMMENT '评委用户id',
`assignment_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '分配时间',
`status` varchar(31) NOT NULL DEFAULT 'assigned' COMMENT '分配状态:assigned/reviewing/completed',
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_work_judge` (`work_id`, `judge_id`),
KEY `idx_contest_judge` (`contest_id`, `judge_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作品分配表';
功能模块划分
后端模块结构
backend/src/contests/
├── contests.module.ts # 赛事主模块
├── contests.controller.ts # 赛事控制器
├── contests.service.ts # 赛事服务
├── dto/
│ ├── create-contest.dto.ts
│ ├── update-contest.dto.ts
│ ├── query-contest.dto.ts
│ └── publish-contest.dto.ts
├── works/
│ ├── works.module.ts
│ ├── works.controller.ts
│ ├── works.service.ts
│ └── dto/
│ ├── create-work.dto.ts
│ ├── update-work.dto.ts
│ └── submit-work.dto.ts
├── registrations/
│ ├── registrations.module.ts
│ ├── registrations.controller.ts
│ ├── registrations.service.ts
│ └── dto/
│ ├── create-registration.dto.ts
│ ├── review-registration.dto.ts
│ └── create-team.dto.ts
├── teams/
│ ├── teams.module.ts
│ ├── teams.controller.ts
│ ├── teams.service.ts
│ └── dto/
│ ├── create-team.dto.ts
│ └── invite-member.dto.ts
├── reviews/
│ ├── reviews.module.ts
│ ├── reviews.controller.ts
│ ├── reviews.service.ts
│ └── dto/
│ ├── create-score.dto.ts
│ ├── assign-work.dto.ts
│ └── create-review-rule.dto.ts
└── notices/
├── notices.module.ts
├── notices.controller.ts
├── notices.service.ts
└── dto/
├── create-notice.dto.ts
└── update-notice.dto.ts
前端模块结构
frontend/src/views/contests/
├── Index.vue # 赛事列表页
├── Create.vue # 创建赛事页
├── Detail.vue # 赛事详情页
├── Edit.vue # 编辑赛事页
├── works/
│ ├── Index.vue # 作品列表页
│ ├── Submit.vue # 提交作品页
│ └── Detail.vue # 作品详情页
├── registrations/
│ ├── Index.vue # 报名列表页
│ ├── Register.vue # 报名页
│ └── Review.vue # 审核报名页
├── teams/
│ ├── Index.vue # 团队列表页
│ ├── Create.vue # 创建团队页
│ └── Detail.vue # 团队详情页
├── reviews/
│ ├── Index.vue # 评审列表页
│ ├── Score.vue # 评分页
│ └── Results.vue # 结果公布页
└── notices/
├── Index.vue # 公告列表页
└── Create.vue # 创建公告页
实现计划
阶段一:基础功能(2-3周)
1.1 数据库迁移
- 修复 SQL 文件中的错误
- 删除
t_contest_work_score重复定义 - 修复
t_contest_work_attachment的逗号错误 - 修复
t_contest_team索引字段名错误 - 修复
t_contest_work索引字段错误
- 删除
- 创建缺失的表(公告表、评审规则表、作品分配表)
- 更新 Prisma schema
- 执行数据库迁移
1.2 后端基础模块
- 创建 contests 模块(Controller、Service、DTO)
- 实现赛事 CRUD 接口
- 实现赛事发布/撤回接口
- 实现租户权限控制
- 编写单元测试
1.3 前端基础页面
- 创建赛事列表页
- 创建赛事创建/编辑页
- 创建赛事详情页
- 集成权限控制
- 实现路由配置
阶段二:报名功能(2周)
2.1 后端实现
- 创建 registrations 模块
- 实现个人报名接口
- 实现团队报名接口
- 实现报名审核接口
- 实现报名状态流转逻辑
2.2 前端实现
- 创建报名页面
- 创建团队管理页面
- 创建报名审核页面
- 实现报名状态展示
阶段三:作品提交功能(2周)
3.1 后端实现
- 创建 works 模块
- 实现作品提交接口
- 实现文件上传功能
- 实现作品版本控制逻辑
- 实现作品状态管理
3.2 前端实现
- 创建作品提交页面
- 实现文件上传组件
- 创建作品列表页
- 创建作品详情页
阶段四:评审功能(2-3周)
4.1 后端实现
- 创建 reviews 模块
- 实现评审规则管理接口
- 实现作品分配接口
- 实现评分接口
- 实现评分计算逻辑
4.2 前端实现
- 创建评审规则配置页
- 创建作品分配页
- 创建评分页面
- 实现多维度评分表单
阶段五:结果公布与公告(1周)
5.1 后端实现
- 创建 notices 模块
- 实现公告 CRUD 接口
- 实现结果公布接口
- 实现结果统计接口
5.2 前端实现
- 创建公告管理页面
- 创建结果公布页面
- 实现结果展示页面
阶段六:优化与测试(1-2周)
6.1 功能优化
- 性能优化(数据库查询优化、缓存)
- 用户体验优化
- 错误处理完善
6.2 测试
- 单元测试
- 集成测试
- 端到端测试
- 压力测试
技术实现要点
1. 权限设计
1.1 权限编码规划
contest:create # 创建赛事
contest:read # 查看赛事
contest:update # 更新赛事
contest:delete # 删除赛事
contest:publish # 发布赛事
contest:register # 报名赛事
work:submit # 提交作品
work:read # 查看作品
work:update # 更新作品
review:assign # 分配作品
review:score # 评分
review:read # 查看评审
result:publish # 公布结果
notice:create # 创建公告
notice:read # 查看公告
1.2 角色规划
- 超级管理员:所有权限
- 赛事管理员:contest:、notice:、result:publish
- 评委:review:assign、review:score、review:read、work:read
- 参赛者:contest:read、contest:register、work:submit、work:read
2. 租户隔离
2.1 数据隔离策略
- 赛事创建:超级租户创建,通过
contest_tenant字段控制可见范围 - 报名数据:通过
tenant_key字段隔离 - 作品数据:通过
tenant_key字段隔离 - 评审数据:通过
tenant_key字段隔离
2.2 接口权限控制
- 使用
@TenantId()装饰器获取租户信息 - Service 层自动过滤租户数据
- Controller 层验证租户权限
3. 时间状态管理
3.1 赛事状态机
unpublished → published → (可撤回) → unpublished
3.2 报名状态机
pending → passed/rejected/withdrawn
3.3 作品状态机
submitted → locked → reviewing → accepted/rejected
3.4 定时任务
- 自动更新报名状态(根据时间)
- 自动更新作品提交状态
- 自动更新评审状态
- 自动发送通知(可选)
4. 文件上传
4.1 文件存储
- 使用对象存储(OSS/S3)或本地存储
- 文件类型限制:图片、视频、3D模型、文档等
- 文件大小限制:根据文件类型设置
4.2 文件管理
- 文件上传接口
- 文件删除接口
- 文件预览接口
- 文件下载接口
5. 通知系统
5.1 通知类型
- 报名成功通知
- 报名审核结果通知
- 作品提交成功通知
- 评审结果通知
- 结果公布通知
5.2 通知方式(可选)
- 站内消息
- 邮件通知
- 短信通知(可选)
6. 数据统计
6.1 赛事统计
- 报名人数统计
- 作品提交数量统计
- 评审进度统计
- 结果统计
6.2 报表导出
- 报名名单导出(Excel)
- 作品列表导出(Excel)
- 评审结果导出(Excel)
- 结果报告导出(PDF)
注意事项
1. SQL 文件问题修复
在开始开发前,必须先修复 SQL 文件中的错误:
- 删除重复的
t_contest_work_score表定义 - 修复
t_contest_work_attachment表的语法错误 - 修复
t_contest_team表的索引错误 - 修复
t_contest_work表的索引错误
2. 数据一致性
- 报名和作品的关系:一个报名可以对应多个作品版本
- 团队和报名的关系:一个团队对应多个报名记录(每个成员一条)
- 作品和评分的关系:一个作品可以有多条评分记录(多个评委)
3. 性能考虑
- 赛事列表查询需要分页
- 作品列表查询需要分页和筛选
- 评分计算需要缓存
- 文件上传需要异步处理
4. 安全性
- 文件上传需要验证文件类型和大小
- 接口需要权限验证
- 敏感操作需要日志记录
- 防止 SQL 注入和 XSS 攻击
总结
本方案基于现有的多租户 RBAC 系统架构,设计了完整的赛事管理功能模块。主要特点:
- 完整的生命周期管理:从赛事创建到结果公布的全流程
- 灵活的参赛方式:支持个人赛和团队赛
- 强大的评审系统:支持多维度评分和自定义评审规则
- 良好的扩展性:模块化设计,易于扩展新功能
建议按照阶段逐步实现,每个阶段完成后进行测试和优化,确保系统稳定可靠。