# 行政区服务月报 PPT 自动更新指南

本目录用于按页更新 `ppt_templates/行政区服务月报.pptx`。当前行政区模板共 7 页，每一页由一个单文件 Python 脚本负责读取 FastAPI 数据、计算页面口径，并写回 PPTX 中对应的文本、表格、原生图表和内嵌 workbook。

行政区脚本统一使用行政区口径：

```text
scope=行政区
scope_value=<行政区名称>
```

运营商中标侧接口额外固定使用：

```text
ct=是
```

## 核心原则

- 每一页脚本都是独立文件，位于 `ppt_update/administrative_district/page_updates/P{页码}_update.py`。
- 所有数据只来自本机 FastAPI，不读取旧 `scripts/`，不使用 JSON fallback。
- 默认 FastAPI 地址为 `http://127.0.0.1:8000`。
- 每个脚本必须传入 `--district`，例如 `--district 浦东新区`。
- 脚本只更新自己负责的页面，其余页面和模板样式尽量保持不变。
- 脚本不额外处理字体、字号、文本框位置或模板版式。
- 无法完全自动分析的内容保留双花括号事实占位符，格式为 `{{数据事实；请基于数据进行概括总结分析，凸显数据特征}}` 或同义短提示。
- 可比较字段为 `/` 时，表格单元格显示 `/`；分析描述保留数据事实，并将 `/` 转为事实占位符或可比不足提示。
- 支持输入 PPTX 与输出 PPTX 为同一路径，脚本会用临时文件安全替换。

## 单页更新用法

```bash
python3 ppt_update/administrative_district/page_updates/P1_update.py \
  --pptx ppt_templates/行政区服务月报.pptx \
  --output output/浦东新区服务月报-P1更新.pptx \
  --year 2026 \
  --month 4月 \
  --district 浦东新区 \
  --api-base http://127.0.0.1:8000
```

## 整份 PPT 串行更新

```bash
python3 ppt_update/administrative_district/page_updates/P1_update.py --pptx ppt_templates/行政区服务月报.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P2_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P3_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P4_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P5_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P6_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
python3 ppt_update/administrative_district/page_updates/P7_update.py --pptx output/浦东新区服务月报-自动更新.pptx --output output/浦东新区服务月报-自动更新.pptx --year 2026 --month 4月 --district 浦东新区 --api-base http://127.0.0.1:8000
```

## 页面更新设计卡

| 页面 | 页面主题 | FastAPI 接口清单 | 模板可更新对象 | 自动生成内容 | 后置保留内容 |
| --- | --- | --- | --- | --- | --- |
| P1 | 行政区招标总览驾驶舱 | `/tender/overall`, `/tender/industry`, `/tender/major-buyers`, `/tender/class`, `/tender/time`, `/tender/customer-139` | 文本占位符、季度节奏表 | 行政区标题、累计金额/次数、同比、行业 Top、客户 Top5、政府/企业侧累计卡片、季度表、139 月度规模和次数 | 规划、行业、客群分析类文本以事实占位符保留；规划要点保留模板占位符 |
| P2 | 累计行业招标分析 | `/tender/industry` | 表格、`chart1`、`Workbook1`、行业分析占位符 | 累计行业 Top10 表、行业招标金额/次数图、行业 Top3 总览与 Top10 事实占位符 | 行业特征总结保留双花括号，供后续概括 |
| P3 | 月度招标节奏与近三月趋势 | `/tender/overall`, `/tender/industry`, `/tender/class-trend` | 月度整体表、月度行业表、`chart2`-`chart5`、`Workbook2`-`Workbook5`、趋势占位符 | 单月整体指标、月度行业 Top3、近三月政府侧/企业侧招标次数与金额图 | 月度整体、行业、趋势分析保留事实占位符 |
| P4 | 政府/企业 Top5 客户与 139 重点项目 | `/tender/major-buyers`, `/tender/customer-139`, `/tender/customer-139/key-projects` | 政府侧客户表、企业侧客户表、139 重点项目表、标题占位符、P4 备注页 | 标题周期、Top10 改 Top5、政府/企业 Top5 客户、139 月度摘要、139 重点项目 Top5、备注页写入 139 重点项目 Top10 | 139 总览与项目共性保留事实占位符 |
| P5 | 行政区运营商市场中标总览 | `/award/overall`, `/award/industry`, 当前月、去年同期、上月 `/award/overall` | 文本占位符、`chart6`-`chart11`、`Workbook6`-`Workbook11` | 累计/单月中标 KPI、同比/环比、运营商图表、行业累计金额分布图、行业累计个数分布图 | 运营商和行业判断保留短事实占位符 |
| P6 | 累计行业中标分析 | `/award/industry` | 行业份额表、`chart12`、`chart13`、`Workbook12`、`Workbook13` | 行业 Top10 竞争份额表、累计中标个数/金额图 | 行业总览与 Top3 行业竞争分析保留事实占位符 |
| P7 | 当月友商中标大单 | `/award/competitor-large-deals` | 电信大单表、联通大单表 | 电信/联通当月中标大单 Top8；空数据写“无” | 无 |

## 关键字段映射

### 招标侧 P1-P4

- P1 总体 KPI：`/tender/overall.累计数据.招标预算金额（亿元）`、`招标金额同比增幅`、`招标次数`、`招标次数同比增幅`。
- P1 行业列表：`/tender/industry.累计数据`，按 `金额（亿元）` 和 `金额同比增幅` 排序。
- P1 季度表：`/tender/time.季度数据` 最近 5 个季度，写入政府/企业侧招采金额。
- P1 政府/企业卡片：`/tender/class.政府侧累计数据`、`企业侧累计数据`。
- P1/P4 139 客户：`/tender/customer-139.月度数据.招标次数`、`招标预算金额（亿元）`。
- P2 表格和图表：`/tender/industry.累计数据`，按累计金额降序取 Top10。
- P3 月度表：`/tender/overall.月度数据` 与 `/tender/industry.月度数据`，行业按月度金额降序取 Top3。
- P3 趋势图：`/tender/class-trend.月度数据` 最近 3 个月；金额接口字段为亿元，写入趋势金额图时转为万元。
- P4 客户表：`/tender/major-buyers.政府侧招标单位`、`企业侧招标单位`，过滤无意义客户名称后按金额降序取 Top5。
- P4 重点项目表：`/tender/customer-139/key-projects.重点项目`，按预算金额降序取 Top5；同一排序下的 Top10 写入第 4 页备注。

### 中标侧 P5-P7

- P5 总览：`/award/overall.累计数据` 与 `月度数据`，分别计算累计总量、单月总量、去年同期累计同比、上月单月环比。
- P5 行业图：`chart10` 使用 `/award/industry.累计数据.金额数据`，按三家运营商合计中标金额排序；`chart11` 使用 `/award/industry.累计数据.个数数据`，按三家运营商合计中标个数排序。
- P6 行业份额：`/award/industry.累计数据.个数数据` 与 `金额数据`，按累计中标金额排序取 Top10。
- P7 大单：`/award/competitor-large-deals.电信大单` 与 `联通大单`，按中标金额降序取 Top8。

## 后置占位符规则

部分内容需要后续智能体或人工基于事实进行概括总结，不在脚本里直接生成最终判断。脚本会保留双花括号，但会先填入数据事实：

```text
{{月度金额Top3行业为党政5.00亿、商客4.60亿、医卫4.20亿，合计占比100.0%；请基于数据进行概括总结分析，凸显数据特征}}
```

模板文本框空间较紧的页面会使用短提示或纯事实占位符，例如：

```text
{{移动累计：10个/1.00亿，金额份额20.0%，同比+2pp}}
{{行业Top3：党政1.80/商客1.77/医卫1.74亿，占比34.1%}}
```

这种双花括号不是未更新错误，而是给后续二次修订保留的明确标记。检查残留时应关注 `{{P1...}}` 到 `{{P7...}}` 这类模板占位符是否仍存在。

## 异常策略

所有页面均采用严格错误策略：

- FastAPI 连接失败、HTTP 非 200、返回值不是 JSON：直接报错。
- 必填数据节点缺失：直接报错。
- 必填字段为空或不是数字：直接报错。
- 排序所需数据不足：直接报错。
- 模板缺少占位符、表格、图表或 workbook：直接报错。
- 不自动补默认值，不静默跳过，不降级到旧数据。
- 同比、环比、份额变化等可比较字段为 `/` 时，展示字段原样写 `/`；描述字段保留金额、次数、份额等事实，再交给后置占位符总结。

## 测试与验证

运行行政区页面专项测试：

```bash
python3 -m unittest tests/test_administrative_district_updates.py
```

脚本编译检查：

```bash
python3 -m py_compile ppt_update/administrative_district/page_updates/P{1,2,3,4,5,6,7}_update.py
```

全量回归：

```bash
python3 -m unittest discover -s tests
```

建议每次修改模板或脚本后至少执行：

1. 对应单页测试或脚本编译检查。
2. 行政区专项测试和全量回归测试。
3. 用 FastAPI 真实生成输出 PPTX。
4. 拆包检查无 `{{P1...}}` 到 `{{P7...}}` 模板占位符和 `XXXX` 残留；事实占位符可按设计保留。
5. 使用 LibreOffice 或 PowerPoint 渲染核验重点页，确认文本未溢出、表格未扩展、图表/workbook 与表格内容同步。

## 维护建议

- 新增或调整模板占位符时，先改对应测试，再改模板与脚本。
- 页面口径变更时，优先在对应 `P{页码}_update.py` 文件顶部注释和本 README 中同步说明。
- 不要把跨页公共逻辑抽到旧 `scripts/` 中；当前设计要求每页脚本自包含，便于智能体按页理解和执行。
- 如果 FastAPI 接口字段发生变化，先更新页面测试中的样例响应，再修改脚本解析逻辑。
- 如果模板页内图表编号、workbook 编号或表格数量变化，必须同步更新对应页面测试，防止脚本写错对象。
