# 三个脚本的配置字段说明

三个脚本各吃一个 JSON。写在产出目录的 `02-过程\` 下，方便出问题时回看。

---

## 1. fill_forms.py 的配置

模板查找顺序（命中即停）：`<技能目录>\templates\`（专用，优先） → `Z_Skills\template\03-培训\`（通用，兜底）。
同名多版本取版本号最高的。运行时会打印用的是 `[专用]` 还是 `[通用]`。

```json
{
  "培训主题":     "有限空间作业安全",
  "文件日期":     "20260810",
  "通知单编号":   "安培2026-08-10",
  "通知日期":     "2026年8月8日",
  "培训名称":     "有限空间作业专项安全教育培训",
  "培训时间":     "2026年8月10日 15:00",
  "培训地点":     "项目部会议室",
  "培训主持":     "项目部安全环保部",
  "授课人员":     "项目部安全环保部",
  "培训议题":     "1. 有限空间的定义与辨识\n2. 三大危害……",
  "培训目的":     "通过本次培训……（≥200字）",
  "培训内容":     "有限空间作业安全（与通知单口径一致）",
  "培训主要内容": "1. ……\n2. ……（比培训内容详细）",
  "应培训人数":   "",
  "实培训人数":   ""
}
```

要点：

- `培训议题`、`培训目的`、`培训主要内容` 用 `\n` 分行，脚本会在单元格里正确换行
- `应培训人数`、`实培训人数` 用户没给就留空字符串，**不要编数字**
- 签到表脚本内部会强制把 `培训时间` 置空，不用单独配

字段对应哪份表单：

| 字段 | 通知单 | 记录表 | 评估表 | 签到表 |
|---|---|---|---|---|
| 通知单编号 | ✓ | | | |
| 培训名称 | ✓ | | ✓ | |
| 培训时间 | ✓ | ✓ | ✓ | 强制留空 |
| 培训地点 | ✓ | ✓ | | ✓ |
| 培训主持 | ✓ | | | |
| 培训议题 | ✓ | | | |
| 培训目的 | ✓ | | | |
| 通知日期 | ✓ | | | |
| 培训内容 | | ✓ | | ✓ |
| 培训主要内容 | | ✓ | | |
| 授课人员 | | ✓ | ✓ | |
| 应培训/实培训人数 | | ✓ | | |

---

## 2. build_pptx.py 的配置

```json
{
  "培训主题": "有限空间作业安全",
  "副标题":   "专项安全教育培训",
  "单位":     "××工程局  ××光伏项目部",
  "培训时间": "2026年8月10日",
  "章节": [
    {
      "标题": "什么是有限空间",
      "要点页": [
        {
          "标题": "有限空间的定义与判定",
          "要点": [
            {"标题": "三个判定条件", "说明": "封闭或部分封闭、进出口受限、不是为长时间工作设计的空间。三条同时满足才算。"},
            {"标题": "本项目的典型场所", "说明": "电缆沟、集水井、箱变基础坑、未通风的设备舱室。"}
          ]
        }
      ]
    }
  ],
  "核心要点": ["先通风、再检测、后作业", "……"],
  "结束语":   "安全无小事  责任重于山"
}
```

页数怎么算：

```
总页数 = 1(封面) + 1(目录) + 章节数 + 所有要点页数 + 1(回顾) + 1(结束)
```

要凑够 10 页：4 个章节、每章 2 个要点页 → 1+1+4+8+1+1 = **16 页**。

排版硬约束（脚本已实现，配置里别超）：

- 每个要点页最多 **4 个要点块**，超出的会被丢弃
- 每个要点的 `说明` 控制在 **60 字以内**，超了会溢出版面
- 宁可多分一页，也不要往一页里塞

---

## 3. build_exam.py 的配置

```json
{
  "培训主题": "有限空间作业安全",
  "单选": [
    {"题号": 1, "题干": "进入有限空间前，正确的作业顺序是（ ）。",
     "选项": {"A": "先检测后通风", "B": "先通风后检测", "C": "边通风边作业", "D": "直接进入"},
     "答案": "B"}
  ],
  "多选": [
    {"题号": 1, "题干": "有限空间的主要危害包括（ ）。",
     "选项": {"A": "…", "B": "…", "C": "…", "D": "…", "E": "…"},
     "答案": "ABD"}
  ],
  "判断": [
    {"题号": 1, "题干": "发现有人在有限空间内昏迷，应立即下去救人。", "答案": "×"}
  ]
}
```

固定不变：单选 6 题、多选 4 题、判断 5 题；单选 4 选项、多选 5 选项。

### 答案分布规则（脚本会强制校验）

`check_answer_spread()` 不通过就不出卷：

1. **单选**：A/B/C/D 每个字母最多出现 2 次；不允许只用到 2 个以下的字母
2. **判断**：√ 和 × 的数量差 ≤ 1（即 3:2 或 2:3）
3. **多选**：4 题的正确项组合不能重复

先单独跑校验，通过了再出卷：

```bash
python scripts/build_exam.py --config exam.json --check-only
```

不通过时的正确做法是**调换选项顺序**（把正确答案挪到别的字母上），不是改题目。
