|
|
|
|
@ -1,192 +0,0 @@
|
|
|
|
|
# 评审评分:自定义表单与计分规则(规划)
|
|
|
|
|
|
|
|
|
|
> 在原有「每名评审对每条报名一轮打分」基础上,将 **评分界面也 Schema 化**(多维度分值、评语等可配置),并增加 **赛事级计分规则**(**未选择规则时使用系统默认**)。
|
|
|
|
|
> 与《数据结构说明》§3.7~3.8、《需求规格说明书》及《后台管理-菜单与数据库设计》配套迭代。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 一、目标
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 目标 | 说明 |
|
|
|
|
|
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **评审表单可配置** | 由后台维护 **评审 Schema**;支持 **多个维度分值**(`number`),**主分数 / 总分** 由 **多维度按权重自动计算**(非手填单一「总分」作为主逻辑;可在提交后由服务端统一算入 `total` 写入 `payload_json` 便于展示)。 |
|
|
|
|
|
| **一条提交仍是一轮** | 每名 `reviewer` × `application` **仍唯一一条评审记录**;`**payload_json`** 存各维度原始分 + 可选冗余 `total`。 |
|
|
|
|
|
| **规则可配置、按赛事** | **每个赛事** 可绑定 **独立计分规则**;若 **未选择 / 未配置**,则使用 **系统内置默认规则**(见 §4.1)。规则与 **默认** 均可版本化存在 `scoring_rules_json` 或用规则模版表。 |
|
|
|
|
|
| **平均分口径(已确认)** | **平均分 = 所有评审「总分」之和 / 已提交评审人数**;分母仅为 **已提交** 的评审记录数,**不含**未提交、未指派占位。 |
|
|
|
|
|
| **与报名锁定衔接** | 任一评审 **已提交** 有效评分记录后选手端锁定(与既有需求一致);规则变更 **不溯及** 已生成结果,除非运营触发「重算」。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 二、总体架构(两处 Schema + 一层规则)
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
赛事(competitions)
|
|
|
|
|
├── 报名 form_schema_id → 选手填报
|
|
|
|
|
├── review_form_schema_id(可选) → 评审打分表单;**未绑定时** 使用系统 **默认评审 Schema**(如内置多维度模板)
|
|
|
|
|
└── scoring_rules_json 或 scoring_rule_template_id(可选)→ 计分与聚合;**未配置时** 使用 **系统默认计分规则**(§4.1)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**规则与表单的「默认」**:均建议在代码或 `config/contest_scoring.php` 类配置中维护 **一套默认 `schema` 片段 + 默认 `scoring_rules`**,新建赛事 **一键套用**,按需再改。
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
评审提交(单行 = reviewer × application)
|
|
|
|
|
application_reviews / application_review_scores
|
|
|
|
|
├── review_schema_id(快照)
|
|
|
|
|
└── payload_json:各维度原始分 dimension_*;服务端按赛事规则计算 **line_total** 写入同一 JSON(可追溯)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 三、评审侧「自定义表单」怎么落库
|
|
|
|
|
|
|
|
|
|
### 3.1 Schema 存放(建议独立一张「评审表单定义表」或与报名表共用结构)
|
|
|
|
|
|
|
|
|
|
**方案 A(推荐)**:新建 `**review_form_schema_definitions`**,结构与 `form_schema_definitions` 类似:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 字段 | 含义 |
|
|
|
|
|
| ------------------ | --------------------------------------------------------------------------------------- |
|
|
|
|
|
| `id` | 主键 |
|
|
|
|
|
| `competition_id` | 归属赛事(或 NULL 模版) |
|
|
|
|
|
| `name` / `version` | 版本管理 |
|
|
|
|
|
| `schema_json` | 字段数组:多个 `**number` 维度**、`textarea` 评语等;**不要求**手填「总分」字段,总分由规则计算(可与 UI 只读展示 `line_total`) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**方案 B**:共用 `form_schema_definitions` 增加 `purpose` 枚举:`signup` | `review`,同一套表两种用途(筛选时注意索引与查询)。
|
|
|
|
|
|
|
|
|
|
**赛事绑定**:`competitions.review_form_schema_id` 指向当前生效的评审表单(与 `form_schema_id` 并列)。
|
|
|
|
|
|
|
|
|
|
### 3.2 评审提交记录(扩展原「单行 score」设计)
|
|
|
|
|
|
|
|
|
|
在已有 `**UNIQUE(application_id, reviewer_id)`** 前提下,将「一轮提交」存为:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 方案 | 内容 |
|
|
|
|
|
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **推荐** | `**review_schema_id`** + `**payload_json`**:键与 Schema 一致;维度分 如 `{ "dim_innovation": 30, "dim_market": 25, "comment": "…" }`;提交后由服务端按 本赛事 `scoring_rules_json` 计算 `**line_total`(本条评审总分)** 写回 `payload_json`,保证与规则版本一致、防篡改。 |
|
|
|
|
|
| 备选 | 若干固定列 + `extra_json`,仍建议保留 `**schema_id`** 以便历史还原。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**物理主键**:仍建议单表 `**application_review_scores`**(名称可改为 `**application_reviews`** 若语义 broader),**一行 = 一轮评审**。
|
|
|
|
|
|
|
|
|
|
### 3.3 评审端渲染
|
|
|
|
|
|
|
|
|
|
与报名 **同一套路**:读 `**review_form_schema_definitions.schema_json`** → 通用渲染器 → 提交写 `**payload_json`**;**禁止**评审页硬编码「分数+评语」以外的业务字段。
|
|
|
|
|
|
|
|
|
|
### 3.4 「锁定」判定(与需求对齐)
|
|
|
|
|
|
|
|
|
|
- **锁定条件**:该 `application_id` **存在至少一条**评审记录(**已提交成功**)。若草稿态存在,需约定:仅 **正式提交** 后算已打分(建议评审无草稿,直接提交)。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 四、评分规则(赛事可配置;未选则用默认)
|
|
|
|
|
|
|
|
|
|
### 4.1 系统默认规则(`competition` 未绑定自定义规则时)
|
|
|
|
|
|
|
|
|
|
适用于:**同一赛事下、所有报名共用**;多维度总分与队伍聚合如下(与产品已确认口径一致):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 概念 | 定义 |
|
|
|
|
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **单条评审总分 `line_total`** | 对单条 `payload_json` 中各 **维度分** 按 **默认权重**(或 Schema 内 `weight`)**自动求和**: linetotal = \sum_j w_j \cdot dim_j (dim_j 为评审填的各 `number` 维度,不含评语等非数值项)。 |
|
|
|
|
|
| **报名维度的「队伍总分」`team_sum`** | 对该 `application_id` 下 **所有已提交评审** 的 `line_total` **求和**: teamsum = \sum_{i \in 已提交} linetotal_i 。 |
|
|
|
|
|
| **队伍平均分 `team_avg`** | teamavg = teamsum / N_{submitted} ,其中 N_{submitted} = **已为该报名提交评审记录的人数**(**仅统计已提交**,不含未评、草稿)。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
默认权重若未在规则中写明,可由 **默认评审 Schema** 中各维度的 `weight` 或 **等额**(1/n)处理,须在 **默认 `scoring_rules_json`** 里写死一种,避免歧义。
|
|
|
|
|
|
|
|
|
|
### 4.2 赛事自定义规则(`competitions.scoring_rules_json` 非空)
|
|
|
|
|
|
|
|
|
|
- **每个赛事** 单独一份配置(或 `scoring_rule_template_id` 指向模版后拷贝成 JSON),可覆盖:
|
|
|
|
|
- **维度 → 权重**、是否某维度参与 `line_total`;
|
|
|
|
|
- **队伍聚合**:在默认「求和 + 除以已提交人数」之上,增加 **封顶、最低有效评审数、同分规则** 等(见 4.3);
|
|
|
|
|
- **展示**:列表显示 `team_sum` / `team_avg` 的小数位与列名。
|
|
|
|
|
- **未选择/空配置**:整段回退到 **§4.1 默认**(后台可表现为「使用系统默认」单选项)。
|
|
|
|
|
|
|
|
|
|
### 4.3 `scoring_rules_json` 示例(赛事级;可配置)
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"version": 1,
|
|
|
|
|
"source": "custom",
|
|
|
|
|
"dimensions": [
|
|
|
|
|
{ "key": "dim_innovation", "weight": 0.4, "min": 0, "max": 40 },
|
|
|
|
|
{ "key": "dim_market", "weight": 0.6, "min": 0, "max": 60 }
|
|
|
|
|
],
|
|
|
|
|
"line_total_formula": "weighted_sum",
|
|
|
|
|
"team_aggregate": {
|
|
|
|
|
"sum": { "on": "line_total" },
|
|
|
|
|
"average": { "on": "line_total", "denominator": "submitted_review_count" }
|
|
|
|
|
},
|
|
|
|
|
"constraints": { "min_reviewers_for_avg": 1 },
|
|
|
|
|
"tie_break": "submitted_at_asc"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- `**denominator": "submitted_review_count"**` 固定表达:**仅已提交评审**。
|
|
|
|
|
- **扩展**(二期):去极值均分、按赛道覆写规则等 —— **仍按赛事选配**,未配则用默认不启用。
|
|
|
|
|
|
|
|
|
|
### 4.4 计算时机
|
|
|
|
|
|
|
|
|
|
- **提交时**:必算 `**line_total`** 并写入 `payload_json`,便于列表直接读。
|
|
|
|
|
- **队伍层 `team_sum` / `team_avg`**:可 **按需实时聚合**;量大时再 **物化缓存** 至 `applications` 或侧表。
|
|
|
|
|
|
|
|
|
|
### 4.5 与历史单字段 `score` 的兼容
|
|
|
|
|
|
|
|
|
|
- 迁移时:若仅有一维,令 `dim_x` 一项即 `line_total`,与旧逻辑等价。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 五、后台菜单与配置入口(建议)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 菜单 | 能力 |
|
|
|
|
|
| ----------- | ---------------------------------------------------------- |
|
|
|
|
|
| 赛事中心 | **评审表单**(绑定 Schema 或选「系统默认」) |
|
|
|
|
|
| 赛事中心 | **评分规则**(选「系统默认」或 **本赛事自定义** `scoring_rules_json` / 可视化表单) |
|
|
|
|
|
| 报名管理 / 评审管理 | 列表展示 `**team_sum` / `team_avg`**(按 §4 计算) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 六、实施顺序(建议)
|
|
|
|
|
|
|
|
|
|
1. **Phase 1(与已确认口径对齐)**
|
|
|
|
|
- 评审 Schema:**多维度 `number` + 评语**;服务端按 **默认规则** 算 `**line_total`**。
|
|
|
|
|
- 评审记录表:`review_schema_id`、`payload_json`(含维度与 `**line_total`**)。
|
|
|
|
|
- `competitions.scoring_rules_json`:**可空**;空则 **§4.1**;非空则 **§4.2**。
|
|
|
|
|
- 列表/详情:展示 `**team_sum`、`team_avg`**(分母 = **已提交评审数**)。
|
|
|
|
|
2. **Phase 2**
|
|
|
|
|
- 规则编辑器 UI、模版库、约束与同分、缓存列、可选高级算法(去极值等)。
|
|
|
|
|
3. **数据迁移**
|
|
|
|
|
- 旧单列 `score` → 写入单维度或等价 `line_total`。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 七、已确认决策(本产品)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 项 | 决策 |
|
|
|
|
|
| ---------- | ----------------------------------------------------- |
|
|
|
|
|
| 主分数 / 单行总分 | **多维度按权重自动计算** 为 `**line_total`**(非手填总分为唯一依据)。 |
|
|
|
|
|
| 平均分母 | **仅已提交评审人数**。 |
|
|
|
|
|
| 可配置性 | **赛事级** 可配 Schema + 计分规则;**全部可配置**。 |
|
|
|
|
|
| 默认规则 | **未选择 / 未配置** 时使用 **系统默认**(§4.1);不同赛事可有 **不同** 自定义规则。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 仍可议(未锁定实现)
|
|
|
|
|
|
|
|
|
|
- 评审 **提交后是否允许修改本人那一轮**(影响重算与审计)。
|
|
|
|
|
- **按赛道不同规则**:是否在 `competition_tracks` 上覆盖 `scoring_rules`(当前默认同赛事级一条规则)。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 八、文档与表结构后续动作
|
|
|
|
|
|
|
|
|
|
- 将 `**review_form_schema_id`、`scoring_rules_json`(可空=默认)** 并入《后台管理-菜单与数据库设计》`competitions` 与 ER 图。
|
|
|
|
|
- 将评审提交表 `**payload_json`、`line_total`、 `review_schema_id`** 定稿进 DDL。
|
|
|
|
|
- 更新《需求规格说明书》评审 FR、《数据结构说明》§3.7。
|
|
|
|
|
|
|
|
|
|
如需下一步,可从 **默认 `scoring_rules_json` + 默认评审 Schema** 各一份落库种子数据写起。
|