# 全部活动模块优化 — 设计方案 > 所属端:超管端 > 状态:已实现(待验收) > 创建日期:2026-03-27 > 最后更新:2026-03-27 --- ## 1. 背景与问题 超管端"全部活动"模块包含列表页和详情页,均与机构端共用组件,仅通过 `isSuperAdmin` 隐藏写操作按钮。超管的核心职能是**监管**,但当前设计缺乏监管视角。 ### 列表页问题 | 问题 | 说明 | |------|------| | 无全局概览 | 没有活动总量、各状态分布等统计信息,进来就是一张裸表格 | | 缺少活动阶段筛选 | 只能筛发布状态(已发布/未发布),不能按实际阶段(报名中/征稿中/评审中/已结束)筛选 | | 缺少主办机构筛选 | 超管跨机构查看但无法按机构过滤 | | 数据列缺少阶段感知 | 看不到每个活动当前处于哪个阶段(报名中?征稿中?评审中?),只有静态的"已发布/未发布" | | 统计数字不可交互 | 报名/作品/评委列的数字是纯展示,不能点击跳转到对应的管理页面 | | 主色不一致 | 页面内写死 `#1890ff`,与全局主题色 `#6366f1` 不一致 | ### 详情页问题 | 问题 | 说明 | |------|------| | 页面为参与者视角 | 海报+报名按钮设计面向教师/学生,不适合超管监管场景 | | 缺少监管数据 | 看不到报名人数、作品提交情况、评审完成进度等关键指标 | | 缺少配置信息 | 看不到报名时间、提交时间、评审时间、评审规则等完整配置 | | 缺少快捷导航 | 无法从详情页跳转到该活动的报名数据、作品数据、评审进度等子模块 | | 文案错误 | 标题写的"竞赛详情",应为"活动详情" | --- ## 2. 现状分析 ### 2.1 列表页(contests/Index.vue) - 与机构管理端共用同一组件 - 超管通过 `isSuperAdmin` 隐藏写操作(创建/编辑/删除/发布/添加评委) - 搜索:活动名称、活动状态、活动类型、可见范围 - 表格 12 列:序号/名称/主办方/类型/状态/可见范围/公开机构/报名/作品/评委/时间/操作 - 操作列只有"查看详情" ### 2.2 详情页(contests/Detail.vue) - 与机构端、教师端完全共用 - 顶部海报区 + 3 个 Tab(活动信息/通知公告/活动结果)+ 右侧组织信息 - 报名按钮仅 teacher 角色可见,超管看不到也不需要 - 活动信息 Tab 展示富文本内容 - 活动结果 Tab 展示获奖表格(成果已发布时) ### 2.3 后端现有能力 `QueryContestDto` 已支持:contestName, contestState(published/unpublished), status(ongoing/finished), contestType, visibility 返回数据已包含:`_count { registrations, works, teams, judges }`, 时间字段齐全, `reviewedCount`, `totalWorksCount` --- ## 3. 设计方案 ### 3.1 整体思路 **列表页**:在现有基础上增加统计卡片和阶段筛选,增强数据列的信息密度和可交互性。不拆分为独立组件(超管和机构端列表差异不大),继续共用但通过 isSuperAdmin 适配。 **详情页**:超管端使用独立的详情页组件,取代当前的参与者视角页面,聚焦监管数据展示和快捷导航。 ### 3.2 列表页优化 #### 3.2.1 新增统计卡片 列表页顶部增加一行统计卡片(仅超管可见): ``` ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ 全部 12 │ │ 报名中 3 │ │ 征稿中 2 │ │ 评审中 1 │ │ 已结束 4 │ │ 未发布 2 │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ ``` 点击卡片 = 快捷筛选。需要后端新增 `GET /api/contests/stats` 接口。 活动阶段判定逻辑(基于时间字段,非数据库字段): ``` 未发布:contestState === 'unpublished' 报名中:已发布 && now 在 registerStartTime ~ registerEndTime 之间 征稿中:已发布 && now 在 submitStartTime ~ submitEndTime 之间 评审中:已发布 && now 在 reviewStartTime ~ reviewEndTime 之间 已结束:status === 'finished' 或 所有阶段时间均已过 ``` #### 3.2.2 增强筛选栏 在现有 4 项筛选基础上,超管端增加: | 新增筛选项 | 组件 | 说明 | |-----------|------|------| | 主办机构 | Select(下拉搜索) | 按 organizers 字段模糊匹配,或按创建活动的租户筛选 | | 活动阶段 | Select | 报名中 / 征稿中 / 评审中 / 已结束(前端根据时间字段过滤,或后端增加 stage 参数) | 注意:将现有的"活动状态(已发布/未发布)"和"活动阶段"合并为一个筛选项,因为阶段已隐含发布状态。 最终筛选栏(超管端): ``` 活动名称:[______] 活动阶段:[下拉] 活动类型:[下拉] 可见范围:[下拉] 主办机构:[下拉] [搜索] [重置] ``` #### 3.2.3 表格列优化 | 列 | 宽度 | 变更 | |----|------|------| | 序号 | 60 | 不变 | | 活动名称 | 200 | 不变 | | 主办机构 | 120 | **改为 tenant.name**(创建活动的租户名),替代 organizers 字段,更准确 | | 活动类型 | 90 | 不变 | | 活动阶段 | 100 | **新列,替代原"活动状态"**,根据时间字段计算当前阶段,颜色编码:蓝=报名中,绿=征稿中,橙=评审中,灰=已结束,默认=未发布 | | 可见范围 | 90 | 不变 | | 报名 | 70 | **可点击**,点击跳转到该活动的报名数据页 | | 作品 | 70 | **可点击**,点击跳转到该活动的作品数据页 | | 评审 | 80 | **改为进度展示**:`已评/总数`(如 `12/30`),利用后端已有的 reviewedCount/totalWorksCount | | 活动时间 | 160 | 不变 | | 操作 | 100 | 不变(查看详情)| 移除列: - "公开机构"列 — 信息密度低,可在详情页查看 - "评委"列 — 评委数量监管价值低,评审进度更有意义 #### 3.2.4 样式修复 - 将页面内写死的 `$primary: #1890ff` 改为 `$primary: #6366f1`,与全局主题一致 ### 3.3 详情页优化(超管专用) 超管点击"查看详情"后,跳转到**超管专用的活动详情页**,而非现有的参与者视角页面。 #### 3.3.1 页面结构 ``` ┌─ 顶部信息栏 ──────────────────────────────────────────────┐ │ ← 返回 活动名称 │ │ [个人参与] [已发布] [报名中] 主办:广东省图 创建:2026-03-01 │ └──────────────────────────────────────────────────────────┘ ┌─ 数据概览卡片 ─────────────────────────────────────────────┐ │ [报名 128人] [作品 56份] [评审进度 12/56] [评委 5人] │ │ 点击跳转 点击跳转 点击跳转 点击跳转 │ └──────────────────────────────────────────────────────────┘ ┌─ 时间轴 ──────────────────────────────────────────────────┐ │ ● 报名阶段 03-01~03-15 ● 征稿阶段 03-15~04-01 │ │ ○ 评审阶段 04-01~04-10 ○ 成果发布 未发布 │ └──────────────────────────────────────────────────────────┘ ┌─ Tab 区域 ────────────────────────────────────────────────┐ │ [活动配置] [活动内容] [通知公告] [活动结果] │ ├──────────────────────────────────────────────────────────┤ │ 活动配置 Tab: │ │ 基本信息:名称/类型/可见范围/定向条件 │ │ 报名配置:时间/是否审核/年级限制/人数限制 │ │ 作品配置:提交时间/提交规则/作品类型/作品要求 │ │ 评审配置:评审时间/评审规则名 │ │ 组织信息:主办/协办/赞助/联系方式 │ │ │ │ 活动内容 Tab: │ │ 富文本 v-html(复用现有) │ │ │ │ 通知公告 Tab: │ │ 公告列表(复用现有) │ │ │ │ 活动结果 Tab: │ │ 获奖表格(复用现有) │ └──────────────────────────────────────────────────────────┘ ``` #### 3.3.2 顶部信息栏 一行展示核心身份信息: - 返回按钮 - 活动名称(大标题) - 标签组:活动类型 + 发布状态 + 当前阶段 - 主办机构、创建时间 不使用海报/背景图,保持管理后台的简洁风格。 #### 3.3.3 数据概览卡片 4 张可点击的数据卡片: | 卡片 | 数据来源 | 点击跳转 | |------|---------|---------| | 报名人数 | `_count.registrations` | `/super/contests/registrations?contestId=xx`(报名数据页带筛选) | | 作品数量 | `_count.works` | `/super/contests/works/:id/list`(作品数据页) | | 评审进度 | `reviewedCount / totalWorksCount` | `/super/contests/reviews/:id/progress`(评审进度页) | | 评委人数 | `_count.judges` | `/super/contests/:id/judges`(评委管理页) | #### 3.3.4 时间轴 横向时间轴,展示活动的 4 个阶段及其时间范围: ``` 报名阶段 → 征稿阶段 → 评审阶段 → 成果发布 ``` - 已完成的阶段:实心圆 + 主色 - 当前阶段:实心圆 + 高亮 + 脉冲动画 - 未来阶段:空心圆 + 灰色 - 每个节点显示时间范围 #### 3.3.5 Tab 区域 | Tab | 内容 | 说明 | |-----|------|------| | 活动配置 | Descriptions 组件展示所有配置字段 | **新增**,超管最需要看到的完整配置信息 | | 活动内容 | 富文本 v-html | 复用现有逻辑 | | 通知公告 | 公告列表 | 复用现有逻辑 | | 活动结果 | 获奖表格 | 复用现有逻辑 | **活动配置 Tab 详细设计**: ``` 基本信息 ├── 活动名称 / 活动类型 / 可见范围 ├── 定向条件(城市/年龄,仅 targeted 时显示) └── 公开机构列表(仅 designated 时显示) 报名配置 ├── 报名时间:xx ~ xx ├── 是否需要审核:是/否 ├── 允许年级/班级(如有) └── 团队人数限制(团队参与时显示) 作品配置 ├── 提交时间:xx ~ xx ├── 提交规则:单次提交 / 允许重新提交 ├── 作品类型:图片/视频/文档/... └── 作品要求(文本描述) 评审配置 ├── 评审时间:xx ~ xx ├── 关联评审规则:规则名称 └── 成果状态:已发布 / 未发布 组织信息 ├── 主办单位 / 协办单位 / 赞助单位 └── 联系人 / 联系电话 ``` ### 3.4 路由设计 超管端活动详情使用独立路由,不影响现有的机构端/教师端详情页: ```typescript // 新增:超管活动详情路由 { path: "contests/:id/overview", name: "SuperContestOverview", component: () => import("@/views/contests/SuperDetail.vue"), meta: { title: "活动详情", requiresAuth: true }, } ``` 列表页"查看详情"按钮: - 超管端跳转到 `/:tenantCode/contests/:id/overview`(新页面) - 机构端保持跳转到 `/:tenantCode/contests/:id`(原页面) ### 3.5 后端改动 #### 3.5.1 新增 GET /api/contests/stats(活动统计) 仅超管可用,返回: ```json { "total": 12, "unpublished": 2, "registering": 3, "submitting": 2, "reviewing": 1, "finished": 4 } ``` 阶段判定在后端基于时间字段计算。 #### 3.5.2 扩展 GET /api/contests 查询参数 | 新增参数 | 类型 | 说明 | |---------|------|------| | `stage` | string? | 活动阶段筛选:`unpublished`/`registering`/`submitting`/`reviewing`/`finished` | | `creatorTenantId` | number? | 按创建活动的租户(主办机构)筛选 | stage 筛选逻辑在后端实现(基于时间字段比较),避免前端做应用层过滤影响分页。 #### 3.5.3 GET /api/contests/:id 返回增强 超管调用时额外返回: - `tenant: { id, name, code }`(创建活动的租户信息) - 确保 `reviewedCount` 和 `totalWorksCount` 已返回(当前已有) ### 3.6 前端改动 | 文件 | 操作 | 说明 | |------|------|------| | `frontend/src/api/contests.ts` | 修改 | QueryContestParams 增加 stage/creatorTenantId,新增 getStats 接口 | | `frontend/src/views/contests/Index.vue` | 修改 | 超管端增加统计卡片、阶段筛选、机构筛选、可点击数字、阶段列、样式修复 | | `frontend/src/views/contests/SuperDetail.vue` | **新增** | 超管专用活动详情页 | | `frontend/src/router/index.ts` | 修改 | 新增超管活动详情路由 | | `backend/src/contests/contests/contests.service.ts` | 修改 | 新增 getStats 方法,findAll 增加 stage/creatorTenantId 参数 | | `backend/src/contests/contests/contests.controller.ts` | 修改 | 新增 stats 端点,findAll 增加查询参数 | | `backend/src/contests/contests/dto/query-contest.dto.ts` | 修改 | 新增 stage/creatorTenantId 字段 | --- ## 4. 改动范围 ### 后端(3 个文件) | 文件 | 改动类型 | |------|---------| | `backend/src/contests/contests/contests.service.ts` | 修改:新增 getStats(),findAll 增加 stage/creatorTenantId 过滤 | | `backend/src/contests/contests/contests.controller.ts` | 修改:新增 GET /contests/stats,findAll 增加查询参数 | | `backend/src/contests/contests/dto/query-contest.dto.ts` | 修改:DTO 新增字段 | ### 前端(4 个文件) | 文件 | 改动类型 | |------|---------| | `frontend/src/api/contests.ts` | 修改:扩展类型和接口 | | `frontend/src/views/contests/Index.vue` | 修改:超管端增强 | | `frontend/src/views/contests/SuperDetail.vue` | **新增**:超管活动详情页 | | `frontend/src/router/index.ts` | 修改:新增路由 | --- ## 5. 实施记录 ### 2026-03-27 — 首次实现 **后端改动(3 个文件):** - `backend/src/contests/contests/dto/query-contest.dto.ts` — 新增 stage、creatorTenantId 字段 - `backend/src/contests/contests/contests.service.ts` — 新增 getContestStage() 阶段判定方法、getStats() 统计方法;findAll 增加 stage 应用层过滤和 creatorTenantId 筛选;返回数据增加 stage、creatorTenant 字段 - `backend/src/contests/contests/contests.controller.ts` — 新增 GET /api/contests/stats 端点 **前端改动(4 个文件):** - `frontend/src/api/contests.ts` — QueryContestParams 增加 stage/creatorTenantId/visibility;新增 ContestStats 类型和 getStats 接口 - `frontend/src/views/contests/Index.vue` — 重写:超管端增加统计卡片(6 个阶段)、活动阶段筛选+主办机构筛选、超管/机构分列定义、活动阶段列、报名/作品可点击跳转、评审进度列(已评/总数)、主色修复为 #6366f1 - `frontend/src/views/contests/SuperDetail.vue` — **新增**:超管活动详情页,含顶部信息栏+4 张数据概览卡片+横向时间轴+4 Tab(配置/内容/公告/结果) - `frontend/src/router/index.ts` — 新增 contests/:id/overview 超管详情路由