# 评审进度模块优化 — 设计方案

> 所属端：超管端
> 状态：已实现（待验收）
> 创建日期：2026-03-27
> 最后更新：2026-03-27

---

## 1. 背景与问题

超管端"评审进度"菜单是两层结构，问题模式与报名数据、作品数据一致：第一层是活动列表精简版（冗余），第二层围绕管理操作设计（开始评审/结束评审/替换评委），不符合超管只读监管定位。

### 核心问题

| 问题 | 说明 |
|------|------|
| 第一层与全部活动列表重复 | 活动列表已有评审进度列（已评/总数），两个入口功能重叠 |
| 写操作未隔离 | "开始评审""结束评审""替换评委"均为机构管理端操作 |
| 评审状态筛选无效 | 第一层评审状态下拉选了不生效（前端计算但未传后端） |
| 缺少全局统计 | 没有全平台评审总进度概览 |
| 无跨活动维度 | 不能跨活动查看所有作品的评审状态 |
| TODO 未实现 | 未提交作品列表、评委替换 API 均为空实现 |
| 样式不一致 | 主色 `#1890ff` |

---

## 2. 现状分析

### 2.1 第一层：评审进度（reviews/Progress.vue）

- 个人参与/团队参与 Tab
- 数据来源：`contestsApi.getList()` 按活动类型过滤
- 搜索：活动名称 + 评审状态（无效）
- 表格列：序号/活动名称/主办机构/评审状态/已评审÷作品数/评审时间/操作
- 操作：查看详情 → 跳转 ProgressDetail

### 2.2 第二层：评审进度详情（reviews/ProgressDetail.vue）

- 数据来源：`worksApi.getList({ contestId })`
- 搜索：作品编号/报名账号/评审进度
- 表格列：序号/作品编号/报名账号/评委评分/评审进度/操作
- 操作按钮：开始评审、结束评审、未提交作品、导出
- 评审详情 Drawer：每个评委评分 + 替换评委
- 评委替换 Drawer：选择新评委

---

## 3. 设计方案

### 3.1 整体思路

与报名/作品模块一致：**超管端两层合一为扁平作品评审列表**，展示全平台所有作品的评审状态和评分情况。隐藏所有写操作，只保留查看能力。机构端保持不变。

### 3.2 页面结构

```
┌─ 标题卡片 ──────────────────────────────────────────────┐
│  评审进度                                                │
└─────────────────────────────────────────────────────────┘

┌─ 统计卡片 ──────────────────────────────────────────────┐
│ [全部 120] [未评审 60] [评审中 40] [已完成 20]            │
└─────────────────────────────────────────────────────────┘

┌─ 筛选栏 ────────────────────────────────────────────────┐
│ 所属活动:[下拉搜索] 作品/作者:[______] 评审进度:[下拉]    │
│                                        [搜索] [重置]     │
└─────────────────────────────────────────────────────────┘

┌─ 数据表格 ──────────────────────────────────────────────┐
│ 所属活动 | 作品编号 | 提交者 | 报名账号 |                │
│ 评审进度 | 平均分 | 递交时间 | 操作                      │
└─────────────────────────────────────────────────────────┘
```

### 3.3 统计卡片

4 张卡片，可点击筛选：

| 卡片 | 数据 | 颜色 | 说明 |
|------|------|------|------|
| 全部 | 作品总数 | 主色 | validState=1 且 isLatest=true |
| 未评审 | 无评分记录的作品 | 灰色 | assignments 为空或 scores 为空 |
| 评审中 | 部分评委已评的作品 | 橙色 | 有评分但未全部评完 |
| 已完成 | 所有评委评完的作品 | 绿色 | reviewedCount >= totalJudgesCount |

复用作品 stats 接口数据即可（submitted≈未评审，reviewing≈评审中，reviewed≈已完成）。

### 3.4 筛选栏

| 筛选项 | 组件 | 说明 |
|--------|------|------|
| 所属活动 | Select（远程搜索） | 按活动名称搜索下拉 |
| 作品/作者 | Input | 搜索作品编号、提交者姓名 |
| 评审进度 | Select | 未评审 / 评审中 / 已完成 |

### 3.5 表格列

| 列 | 宽度 | 渲染方式 |
|----|------|----------|
| 所属活动 | 180 | 活动名称，可点击跳转活动详情 |
| 作品编号 | 130 | workNo，可点击查看作品详情 |
| 提交者 | 130 | 昵称 / 队伍名 |
| 报名账号 | 120 | username |
| 评审进度 | 100 | Tag：未评审（灰）/ 评审中 x/y（橙）/ 已完成（绿） |
| 平均分 | 80 | averageScore，已完成时显示分数，否则"-" |
| 递交时间 | 150 | YYYY-MM-DD HH:mm |
| 操作 | 100 | 查看详情 |

### 3.6 详情 Drawer

点击"查看详情"打开 Drawer，展示该作品的评审明细：

```
作品信息
├── 所属活动 / 作品编号
├── 提交者 / 报名账号
├── 平均分 / 评审进度（x/y）

评委评分列表（表格）
├── 评委姓名 / 所属单位 / 评分 / 评分时间
```

不提供"替换评委"操作。

### 3.7 URL 参数支持

- `/super/contests/reviews/progress` — 全部作品评审进度
- `/super/contests/reviews/progress?contestId=3` — 从活动列表跳转，筛选某活动

---

## 4. 后端改动

无新增接口。复用已有能力：
- 统计：复用 `GET /api/contests/works/stats`（已有 submitted/reviewing/reviewed）
- 列表：复用 `GET /api/contests/works`（已返回 reviewedCount/totalJudgesCount/averageScore/assignments）
- 评分详情：复用 `GET /api/contests/reviews/works/:workId/scores`（已有）

### 4.1 评审进度前端过滤

"评审进度"筛选（未评审/评审中/已完成）基于返回数据的 `reviewedCount` 和 `totalJudgesCount` 在前端过滤，或后端 works 接口增加 `reviewProgress` 参数。

简化方案：前端直接利用作品 status 字段 + scores 数据判定，不改后端。

---

## 5. 前端改动

| 文件 | 操作 | 说明 |
|------|------|------|
| `frontend/src/views/contests/reviews/Progress.vue` | 修改 | 超管端改为扁平评审进度列表（统计卡片+筛选+表格+评分Drawer），机构端保持不变 |

后端无需改动，完全复用已有的 works 接口和 stats 接口。

---

## 6. 实施记录

### 2026-03-27 — 首次实现

**后端改动：无**（完全复用 works 接口和 reviews/scores 接口）

**前端改动（1 个文件）：**
- `frontend/src/views/contests/reviews/Progress.vue` — 完全重写：超管端为扁平评审进度列表（统计卡片复用 worksApi.getStats + 筛选栏 + 全平台作品表格含评审进度/平均分 + 评分详情 Drawer 含评委评分明细），机构端保持原有两层结构；评审进度筛选为前端过滤（基于 reviewedCount/totalJudgesCount）；支持 URL 参数联动（?contestId=xx）
