ソースを参照

feat:暂存调度配置功能的设计稿,需要暂缓实现

Jerry Liang 1 週間 前
親
コミット
0efddf7b65

+ 21 - 0
docs/despatch-config/README.md

@@ -0,0 +1,21 @@
+# 调度配置文档导航
+
+本目录整理“调度配置”模块重构的需求与设计。该模块通过 FWH 云平台接口管理 TOU 调度模版,覆盖生产服(只读、导出、对比)和测试服(完整管理),目标是替代外部“配置编辑器”。当前状态:需求梳理初稿,尚未进入设计和编码。
+
+建议阅读顺序:current-state → protocol-observations → requirements;technical-design 和 ui-design 待编辑方式讨论后补充。
+
+## 文档职责
+
+| 文档 | 内容 | 何时读取 |
+| --- | --- | --- |
+| [current-state.md](current-state.md) | 重构前的代码入口、云端接口、数据模型和问题清单 | 了解现有实现、核对重构要解决什么时 |
+| [protocol-observations.md](protocol-observations.md) | 测试服抓包得到的云端接口行为、字段规范化和待验证项 | 设计写入格式、更新语义时 |
+| [requirements.md](requirements.md) | 功能目标、环境能力划分、待确认事项、第二阶段规划 | 确定要做什么、讨论验收范围时 |
+| technical-design.md(待写) | 统一类型、环境参数化、调度模式识别、校验、对比算法、编辑分层 | 讨论如何实现时 |
+| ui-design.md(待写) | 菜单、列表、详情、编辑器、对比页面的布局和交互 | 实现或评审前端页面时 |
+
+字段的权威定义暂以 `service/dto/fwhTestTouTemplateDTO.go` 和 `deploy/kiro/skills/fwh-toolbox-workflow/references/tou-template.md` 为准;协议原文为 wiki《ScriptingForSchedulingConfiguration》。
+
+## 维护方式
+
+产品范围变化更新 `requirements.md`,并在其待确认表中关闭对应条目;设计决策确认后写入 `technical-design.md`;页面调整写入 `ui-design.md`;`current-state.md` 只描述重构前的状态,不随新代码更新,编码开始后另建 `implementation-status.md`。

+ 86 - 0
docs/despatch-config/current-state.md

@@ -0,0 +1,86 @@
+
+# 调度配置现状梳理
+
+> 状态:2026-10-19 重构前梳理,基于 master `87182c7`。本文只记录现有代码的行为与问题,不代表新需求;新需求见 [requirements.md](requirements.md)。
+
+## 1. 功能概览
+
+现有功能是**云端 TOU 调度模版的只读浏览器**:后端代理 FWH 云平台的模版接口,前端展示列表、详情并导出 JSON。写入(新增/更新)只在 MCP 工具中提供,且仅支持测试服。
+
+| 层              | 位置                                                                                             | 现状                                                                                                      |
+| --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
+| 路由            | `src/router/record.ts`(`despatch-config`)                                                  | 菜单“调度配置”,子页“调度模版(生产)”“调度模版(测试)”                                            |
+| 生产页          | `src/views/despatch-config/touTemplatePro.vue`                                                 | 列表:模版类型/发布状态/关键字过滤、分页;右键或按钮“查看”弹窗显示详情                                  |
+| 测试页          | `src/views/despatch-config/touTemplateTest.vue`                                                | 空页面,只有 NCard                                                                                        |
+| 详情组件        | `src/views/despatch-config/component/templateTable.vue`                                        | 按季节 × 日类型分组展示时段表;由优先级反推调度类型 A~H;下载 JSON(外部配置编辑器格式);xlsx 按钮禁用 |
+| 前端 API        | `src/service/despatchConfig/`                                                                  | 仅 `list`、`info`,仅生产服                                                                           |
+| 后端路由/控制器 | `service/routes/despatchConfigRoutes.go`、`service/controllers/despatchConfigControllers.go` | `GET /despatchConfig/touTemplatePro/list`、`/info`                                                    |
+| Service         | `service/services/despatchConfigServices.go`                                                   | 生产服:list、detail;测试服:list、detail、save、cites                                                   |
+| Repo(生产)    | `service/repositories/api/fwh_pro/fwh_touTemplate.go`                                          | `selectIotTouTemplateList`、`getIotTouTemplateDetailById`,结果为 `interface{}` 透传                |
+| Repo(测试)    | `service/repositories/api/fwh_test/fwh_touTemplate.go`                                         | 另有 `updateOrSaveIotTouTemplate`、`selectCitesList`                                                  |
+| DTO             | `service/dto/fwhTestTouTemplateDTO.go`、`service/dto/touTemplateDTO.go`                      | 测试服写入 DTO 完整;`TouTemplateItemInfo` 未被使用                                                     |
+| MCP             | `service/cmd/mcp/tools/service/tou_template.go`                                                | `service_tou_template_list/detail/save/cites`;save、cites 仅测试服                                     |
+| 知识文档        | `deploy/kiro/skills/fwh-toolbox-workflow/references/tou-template.md`                           | 字段字典、日类型配对、校验规则,是目前最完整的字段说明                                                    |
+| 相关模块        | `src/views/local-utils/log-357-parser/func/parseScheduling.ts`                                 | 357 日志解析中另一套“优先级 → 调度类型”映射                                                            |
+
+## 2. 云端接口(hes-gateway)
+
+| 接口                                                | 方法      | 用途                                                                                                                    | 已接入环境 |
+| --------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------- | ---------- |
+| `/hes-gateway/manage/selectIotTouTemplateList`    | POST form | 模版列表;支持 `sourceType`、`status`、`search`、分页,另有 `countryId`、`provinceId`、更新时间范围(未使用) | 生产、测试 |
+| `/hes-gateway/manage/getIotTouTemplateDetailById` | POST form | 模版详情                                                                                                                | 生产、测试 |
+| `/hes-gateway/manage/updateOrSaveIotTouTemplate`  | POST JSON | 新增/更新,返回模版 ID;`templateId` 有值为更新                                                                       | 测试       |
+| `/hes-gateway/manage/selectCitesList`             | GET       | 国家/省/市列表;查省市需 `countryId` 且 `type=1`                                                                    | 测试       |
+
+**尚未找到**:发布、取消发布、删除模版的接口。
+
+## 3. 数据模型
+
+```
+Template(模版主体)
+  国家/省、电力公司(简称/全称)、DER 计划、资费套餐、电价类型 electricityType、
+  名称、mookRunCount、priority、env(位域)、sourceType、status
+ └─ strategyList[](策略)
+      seasonName、month("1,2,…")、日类型、可选购电/卖电电价
+      日类型配对:每天(ccociateType=1, dayType=3, ccociateSn="")
+                或 工作日(2,1) + 周末/节假日(3,2),同组共用 ccociateSn("0" 起递增)
+     └─ detailVoList[](时段,00:00→24:00 首尾衔接全覆盖)
+          waveType 峰平谷、name、briefDescribe、solarPriority/loadPriority(3 值字符串)、
+          各功率上限/固定功率(kW,单台)、SOC、offGrid/solarCutoff/heatEnable/powerOffApower/rampTime…
+```
+
+字段完整定义见 `tou-template.md` 与 `fwhTestTouTemplateDTO.go`。
+
+调度类型由 `solarPriority` + `loadPriority` 组合反推:
+
+| 光伏优先级 | 负载优先级 | 类型                                                                           |
+| ---------- | ---------- | ------------------------------------------------------------------------------ |
+| `1,2,0`  | `1,3,2`  | A 光伏余电馈网                                                                 |
+| `1,2,0`  | `1,2,0`  | B 电池待机                                                                     |
+| `1,3,2`  | `1,2,0`  | C 光伏余电充电                                                                 |
+| `1,3,2`  | `1,3,2`  | D 自发自用                                                                     |
+| `1,2,3`  | `1,2,0`  | E/G 光伏优先充电(G 为使能电网充电)                                           |
+| `1,2,0`  | `1,2,3`  | F/H 电池优先供载(H 为使能电池馈网)                                           |
+| 其他       | —         | 有 `dischargePower` 视为强制放电,有 `chargePower` 视为充电/备电,否则未知 |
+
+## 4. 问题清单
+
+### 4.1 功能缺失
+
+1. 测试服页面为空,测试服 API 未暴露给前端。
+2. 页面不能新增、编辑、复制、发布;写入只能走 MCP,且仅测试服。
+3. xlsx 导出未实现;JSON 导出为外部“配置编辑器”格式(新需求中不再支持)。
+4. 无国家/地区下拉,未使用云端已支持的国家、省、更新时间过滤。
+
+### 4.2 逻辑分散、不一致
+
+5. “优先级 → 调度类型”映射存在三份(详情展示、JSON 导出、`parseScheduling.ts`),覆盖范围不同:导出遇 A 直接抛“未实现”;`parseScheduling` 多 `noPriority`;`9,9,9` 等自定义组合都无法识别。
+6. 详情按 `seasonName` 分组而非 `ccociateSn` 配对,同季节名多组“工作日 + 周末”会互相覆盖;导出按 `seasonName + month` 分组,口径与展示不同。
+7. 数据异常直接 `throw`,详情弹窗整体渲染失败,无容错展示。
+8. 导出中 `id`/`key` 用 `Date.now()`,同一循环内重复。
+
+### 4.3 类型与结构
+
+9. 生产服接口透传 `interface{}`,前端 `interface.ts` 与测试服写入 DTO 是两套结构,存在差异。
+10. 双环境通过复制函数区分(`FwhTestXxx`),未像 `fwh_mqtt` 那样做成环境参数化的通用模块。
+11. 命名不统一:`despatch`/`dispatch` 混用;云端字段自带拼写问题(`derSchdule`、`eletic*`、`ccociate*`、`mookRunCount`),需决定是否在 DTO 层映射。

+ 62 - 0
docs/despatch-config/protocol-observations.md

@@ -0,0 +1,62 @@
+# 云端 TOU 模版接口实测记录
+
+> 状态:2026-10-21,基于测试服后台网页操作抓包(`TOU模版.test.franklinwh.com.har`,含登录 token,不入库)。本文只记录观察到的事实;结论被设计采纳后写入 technical-design。
+
+## 1. 抓包范围
+
+操作顺序:查询省/州 → 新建模版 → 列表 → 查看详情 → 打开编辑(未保存)→ 发布 → 删除。
+
+| # | 接口 | 方法 / 格式 | 用途 |
+| --- | --- | --- | --- |
+| 0 | `/hes-gateway/manage/selectCitesList?countryId=2&type=1&lang=ZH_CN` | GET | 查询美国的省/州 |
+| 28 | `/hes-gateway/manage/updateOrSaveIotTouTemplate` | POST JSON | 新建,返回 `result: 4576`(模版 ID) |
+| 29/34/37 | `/hes-gateway/manage/selectIotTouTemplateList` | POST form | 列表 |
+| 30/32 | `/hes-gateway/manage/getIotTouTemplateDetailById` | POST form `id=4576&lang=ZH_CN` | 详情(两次返回完全相同) |
+| 33 | `/hes-gateway/manage/setStatusIotTouTemplate` | POST form `templateId=4576&status=2&lang=ZH_CN` | **发布** |
+| 36 | `/hes-gateway/manage/setStatusIotTouTemplate` | POST form `templateId=4576&status=1&lang=ZH_CN` | **删除** |
+
+**未覆盖**:编辑后保存(更新)。
+
+## 2. 状态接口 `setStatusIotTouTemplate`
+
+- 发布和删除共用一个接口,只是 `status` 不同:`2` 发布,`1` 删除。响应 `{"code":200,"result":null}`。
+- 删除是软删除:之后列表总数从 1126 降到 1125,模版不再出现在列表中。
+- `status` 取值:`0` 未发布、`1` 已删除、`2` 已发布。没有取消发布的操作(目前只能改数据库)。
+- 发布后 `updateTime` 不变(列表中仍为 `03:02:33`)。
+
+## 3. 新建:网页提交的内容与云端存储的差异
+
+网页提交的请求体与 `fwhTestTouTemplateDTO.go` / `tou-template.md` 的约定有出入,云端会做规范化:
+
+| 字段 | 网页提交 | 详情读回 | 说明 |
+| --- | --- | --- | --- |
+| 未设置的可选数值(功率、SOC 等) | `""` | `null` | 空串可接受;我们的 DTO 用省略,两种都应可行(省略方式待验证) |
+| `solarCutoff` | `""` | `0` | 空串被存为 0 |
+| `name`(时段名) | `""` | `"mid-peak"` | 云端按 `waveType` 自动生成 |
+| `powerOffApower` | `""` | `""` | 原样 |
+| `template.mookRunCount` | `"0"`(字符串) | `0` | |
+| `template.priority` / `env` | `""` | `null` | |
+| `template.sourceType` | 未提交 | `0` | 默认系统模版 |
+| `dayName` | `All day` / `Workday` / `Holidays` | `Every day` / `Weekdays` / `Weekends,Holidays` | **云端按 `dayType` 改写**,提交什么不重要 |
+| `ccociateSn` | 数字 `2`、`4` | 字符串 `"2"`、`"4"` | 不要求从 `"0"` 连续递增,只要求同组相同 |
+| 策略顺序 | JanToJun, JulToSep×2, OctToDec×2 | JanToJun, OctToDec×2, JulToSep×2 | 读回顺序与提交不同,按 `id` 也不是提交顺序 |
+
+## 4. 详情中云端生成或只读的字段
+
+写入 DTO 没有、由云端生成的字段:
+
+- 模版:`id`、`templateId`(等于 `id`)、`gatewayId`、`templateFromType`、`eletricCompanyId`(本例 10100,按电力公司生成或匹配)、`sdcpCompanyFlag`、`status`、`countryZh/En`、`provinceZh/En`、`workMode`(本例 1)、`updateTime`、`displayFlag`、`templateType`、`ptoDate`、`nbtType`、`classification`、`remark`、`tariffName`、`templateName`、`installerTpl`、`solarChargeMin`。
+- 策略:`id`、`templateId`、`fromType`。
+- 时段:`id`、`strategyId`、`useModeFlag`(本例 0)、`dispatchId`(本例 6,优先级为 `1,3,2`/`1,3,2`,**云端似乎按优先级匹配了自己的调度模式表**)、`dispatch`、`buyRate`、`sellRate`。
+- 顶层另有 `bbDefaultVo`(本例 `null`)。
+
+## 5. 待补充验证
+
+| 编号 | 验证内容 | 影响 |
+| --- | --- | --- |
+| V-01 | 编辑后保存的请求体:网页是否回传策略/时段 `id`,是否回传第 4 节中的只读字段 | 更新语义、保持原值 |
+| V-02 | 更新后策略/时段 `id` 是否变化(整体删除重建还是按 `id` 更新) | 对比对齐、操作记录 |
+| V-03 | 对已有 `remark`、`displayFlag`、`tariffName` 等非空的模版,更新时不传这些字段,是否会被清空 | 保持原值 |
+| V-04 | `dispatchId` 的完整取值表。已知:`6`=D(`1,3,2`/`1,3,2`),`3`=E/G(`1,2,3`/`1,2,0`),`9`=Zero Import(`9,9,9`),见 `service/test/tou/main.go`;抓包中网页新建时未提交 `dispatchId`,读回为 `6`,说明云端按优先级自动匹配;完整取值表和未匹配时的取值待确认 | 调度模式定义表 |
+| V-05 | 对已发布模版执行更新后,`status` 是否保持 2 | 编辑流程 |
+| V-06 | 可选数值字段“省略”与“传空串”在云端是否等价 | 写入格式 |

+ 164 - 0
docs/despatch-config/requirements.md

@@ -0,0 +1,164 @@
+# 调度配置功能需求
+
+> 状态:需求梳理初稿,2026-10-19;2026-10-21 根据测试服抓包补充发布/删除接口,关闭 Q-03、Q-09、Q-11;确定调度模式定义表与高级修改范围,关闭 Q-01、Q-12、Q-13、Q-14。本文记录重构后的目标能力和待确认的产品口径;实现方式写入 technical-design 和 ui-design。现状与问题见 [current-state.md](current-state.md)。
+
+## 1. 目标与范围
+
+重构“调度配置”模块,使其成为**云端 TOU 调度模版的完整管理工具**,并替代外部“配置编辑器”:
+
+1. 查看模版列表与详情(生产服、测试服);
+2. 在测试服新增、编辑模版(发布、删除放到后续迭代);
+3. 导出模版(生产服、测试服);
+4. 生产服模版与指定测试服模版对比,显示差异。
+
+**范围内**:仅通过 FWH 云平台(hes-gateway)接口管理模版。
+
+**范围外**:
+
+- 不直接通过 MQTT 向设备下发或读取调度(355/357 协议),后续也不考虑绕过 FWH Server;wiki《ScriptingForSchedulingConfiguration》是 FWH Server 与设备之间的协议,仅作设计参考,字段格式不照搬;
+- 不再兼容外部“配置编辑器”的 JSON 格式;
+- 生产服不提供任何写操作;
+- AI/MCP 对接放到第二阶段(见第 5 节)。
+
+## 2. 功能需求
+
+### FR-01 菜单与环境
+
+- 主菜单“调度配置”,生产服与测试服使用**独立子菜单**。
+- 每个页面只操作所属环境,页面上明确标出环境;一个环境不可用(未配置、登录失败)时不影响另一个环境。
+
+| 能力 | 生产服 | 测试服 |
+| --- | :---: | :---: |
+| 列表 / 详情 | ✓ | ✓ |
+| 导出 | ✓ | ✓ |
+| 新增 / 编辑 | — | ✓ |
+| 发布 / 删除(后续迭代) | — | ✓ |
+| 对比(生产 ↔ 测试) | ✓ | 待定(见 Q-06) |
+
+### FR-02 模版列表
+
+- 分页列表,支持按模版类型、发布状态、关键字过滤。
+- 增加国家、地区过滤(云端接口已支持 `countryId`、`provinceId`),选项来自 `selectCitesList`。
+- 列表至少显示:ID、类型、国家、地区、DER 计划、电力公司、资费套餐、电价类型、发布状态、更新时间。
+
+### FR-03 模版详情
+
+- 展示模版主体信息和全部策略。策略按**季节 × 日类型**组织,工作日与周末/节假日按 `ccociateSn` 配对,不按季节名合并。
+- 每个时段显示:时间段、峰平谷、调度类型(由优先级按第 3 节“解析规则”识别)、设置了的扩展参数;可查看该时段的原始字段。
+- 策略级电价(购电/卖电)按峰平谷显示。
+- 提供 24 小时时间轴等直观视图(具体形式在 ui-design 中确定)。
+- **容错**:数据不符合规则(时段未覆盖整天、配对缺失、未知 `dayType`、无法识别的优先级组合等)时仍应展示,并标出具体问题,不能让整个详情渲染失败。
+
+### FR-04 新增与编辑(仅测试服)
+
+- 支持新建空白模版、编辑已有模版;“基于已有模版复制新建”的范围见 Q-02。
+- **不提供原始字段的直接编辑**。编辑以“选择”为主:
+  - 模版主体:国家/地区下拉、电价类型等枚举选项;
+  - 策略:选择月份、日类型(每天 / 工作日 + 周末节假日),系统自动生成 `ccociateType`、`ccociateSn`、`dayType`、`dayName`;
+  - 时段:编辑时间段与峰平谷,选择调度模式(A~H、强制充电、强制放电等),系统按调度模式定义表写入对应的**标准** `solarPriority`/`loadPriority` 及参数(见第 3 节“写入规则”)。
+- 在模式选择之外提供**高级修改**:除优先级外,时段的其他参数(功率上限/固定功率、SOC、`gcaoMax`、`heatEnable`、`rampTime`、`offGrid`、`solarCutoff`、`powerOffApower` 等)都可以修改,也可以清空为“未设置”。
+- **优先级不开放自定义输入**,只能通过选择调度模式确定,或设置为空(不下发优先级)。设为空时 `solarPriority` 和 `loadPriority` 同时写为空字符串 `""`,不允许只有一个为空。
+- **模式参数约束**:部分模式对参数有约束(见第 3 节扩展模式参数表),分两种:
+  - **固定**:值由模式决定,界面只读,不能修改也不能清空(如 Zero Import 的 `gridFeedMax`);
+  - **必填**:选择模式时填入默认值,用户可以改数值,但不能清空;必填参数为空时禁止保存。
+  - 优先级对所有模式都相当于“固定”。高级修改中,除优先级和当前模式的固定参数外,其他参数都可以修改或清空。
+- **切换模式**:切换调度模式时,替换优先级,清除原模式的固定/必填参数(新模式也需要的除外)并填入新模式的固定值和默认值;其他高级参数保留。切换前提示将被清除的参数。
+- **保持原值**:编辑已有模版时,用户没有改动的内容保存时必须原样写回,包括非标准的优先级数值(如 `9,9,9`)和其他字段,不做规范化。优先级只在用户对该时段重新选择调度模式(或设为空)时才被替换。保存前的确认弹窗只列出用户实际改动的内容。
+- 保存前校验,校验不通过时禁止保存并定位到具体问题:
+  - 每个策略的时段 00:00→24:00 首尾衔接,无空档、无重叠,格式 `HH:mm`;
+  - 工作日与周末/节假日必须成对,`ccociateSn` 正确;
+  - 月份在各策略间不重叠且覆盖全年(是否强制覆盖全年见 Q-04);
+  - 数值在合法范围内(功率 kW 精度 0.1,SOC 0~100,`rampTime` 0~300 等);
+  - 写入时 `sourceType` 只能为 0(系统模版)。
+- 保存前显示确认弹窗,列出本次写入的内容或与原版本的差异;保存后重新读取详情,确认云端结果与提交内容一致。
+
+### FR-05 发布与删除(仅测试服,后续迭代)
+
+- 本期不实现,后续迭代再加。
+- 云端接口已确认:`setStatusIotTouTemplate`,`status=2` 发布、`status=1` 删除(软删除,从列表消失),见 [protocol-observations.md](protocol-observations.md) 第 2 节。
+- 云端没有取消发布的功能(目前只能改数据库),本工具也不提供。
+- 实现时:操作前显示确认弹窗,删除需二次确认。
+
+### FR-06 导出(生产服、测试服)
+
+- 导出单个模版。格式不再沿用外部配置编辑器,具体格式见 Q-05。
+- 文件名包含电力公司简称、DER 计划、模版名称、环境和时间戳。
+
+### FR-07 对比(生产服 ↔ 测试服)
+
+- 在生产服模版上选择一个测试服模版(按 ID 或通过列表搜索)进行对比。
+- 对比覆盖三层:模版主体字段、策略(季节、月份、日类型、电价)、时段(时间段、峰平谷、调度类型、全部参数)。
+- 差异分为:新增、删除、修改;修改项同时显示两边的值。可只看差异,也可显示全部。
+- 策略和时段的对齐规则(按季节名 + 日类型,或按月份 + 日类型;时间段切分不同时如何对比)在技术设计中确定。
+- 两边都只读取,不修改任何一方。
+
+## 3. 共同需求
+
+- **调度模式定义表**:统一定义基础工作模式 A~H(以及强制充电、强制放电等),每个模式包含名称、语义说明、`solarPriority`/`loadPriority` 写入值和必需参数。定义表需可扩展,新增模式只修改这一处;也可以加入使用非标准数值的特殊模式(如 `9,9,9` 的 Zero Import),加入后即可在编辑时选择。详情、编辑、对比、导出共用此表;与 357 日志解析(`parseScheduling.ts`)的关系在技术设计中确定。
+- **解析规则(只用于展示、对比、导出等读取场景)**:优先级每位取值 0~9,`0` 表示不涉及;非 0 值只看相对大小(越大优先级越高,相同表示按比例/功率分配),不要求是 1/2/3。因此 `9,9,9`、`2,5,1` 等任意数值都应显示出正确的调度逻辑。归不到已定义模式的组合显示为“自定义”并给出语义说明,不报错。优先级为空时显示为“未设置优先级”。
+- 解析时先把每组优先级做**稠密排名归一化**:`0` 保持为 `0`,非 0 值按从小到大依次映射为 1、2、3,相同值映射为同一个数。例如 `9,9,9` → `1,1,1`,`2,5,1` → `2,3,1`,`0,5,9` → `0,1,2`。然后用归一化后的结果去匹配 A~H。**特殊模式(如 Zero Import)不参与归一化**,按原始数值精确匹配;例如 `5,5,5` 归一化后是 `1,1,1`,不会被识别为 Zero Import,而是“自定义”。
+
+**调度模式定义表(初版,2026-10-21 确认)**
+
+优先级顺序:光伏 `[市电, 负载, aPower]`,负载 `[市电, 光伏, aPower]`。
+
+| 模式 | 名称 | 光伏优先级 | 负载优先级 | 语义 |
+| --- | --- | --- | --- | --- |
+| A | Excess solar export to grid(光伏余电馈网) | `1,2,0` | `1,3,2` | 光伏优先供载,剩余馈网;不足由 aPower 补,再不足由市电补;aPower 不充电 |
+| B | aPower standby(电池待机) | `1,2,0` | `1,2,0` | 光伏优先供载,剩余馈网;不足由市电补;aPower 不充不放 |
+| C | Excess solar charge aPower(光伏余电充电) | `1,3,2` | `1,2,0` | 光伏优先供载,剩余给 aPower 充电,再剩余馈网;不足由市电补;aPower 不放电 |
+| D | Self-consumption(自发自用) | `1,3,2` | `1,3,2` | 光伏优先供载,剩余充电,再剩余馈网;不足由 aPower 补,再不足由市电补 |
+| E/G | aPower charge from solar / grid(优先充电) | `1,2,3` | `1,2,0` | 光伏优先给 aPower 充电,剩余供载,再剩余馈网;不足由市电补;aPower 不放电。用户在 PCS 设置中使能电网充电时表现为 G |
+| F/H | aPower supply home / export to grid(优先供载) | `1,2,0` | `1,2,3` | aPower 优先供载,光伏馈网;不足由光伏补,再不足由市电补;aPower 不充电。用户在 PCS 设置中使能电池馈网时表现为 H |
+| — | 未设置优先级 | `""` | `""` | 两个优先级同时为空字符串 |
+| 强制充电 | aPower charge from grid / Backup only(强制充电 / 仅备电) | `""` | `""` | 电网不限充电,aPower 以固定功率充电并保持满电 |
+| 强制放电 | aPower forced discharge(强制放电) | `""` | `""` | 不限 aPower 馈网,aPower 以固定功率放电至预留 SOC |
+| Zero Import | Zero Import(零取电,特殊模式) | `9,9,9` | `9,9,9` | 时段内尽量不从电网取电,由 aPower 放电供载,馈网限制在极小值;按原始值精确匹配,不归一化 |
+
+写入时使用表中的数值。语义说明参考 wiki《ScriptingForSchedulingConfiguration》的常用优先级组合,界面文案在 ui-design 中确定。E/G、F/H 在模版中各是一个模式,不拆分:E 变成 G、F 变成 H 取决于模版之外用户的 PCS 设置(电网充电使能、电池馈网使能),模版无法也不需要区分,界面统一显示为 E/G、F/H;扩展模式(强制充电/仅备电、强制放电、Zero Import)已确认加入,参数见下方扩展模式参数表。
+
+> **补充信息(仅用于理解 Zero Import,不作为需求)**:Zero Import 来自澳洲 GloBird 的 ZEROHERO 套餐(参考模版 4477)。套餐条款:晚高峰(当地时间 18:00–21:00,每天)每小时从电网取电少于 0.03 kWh 即视为“Zero”;另有 ZEROCHARGE 功能,按 28 天账单周期每天限 50 kWh(属于套餐规则,由普通时段参数实现,不是调度模式)。
+
+**扩展模式的参数(2026-10-21 确认)**
+
+选择模式时填入下表的值:“固定”参数只读;“必填”参数可以修改但不能清空;“初始值”参数可以在高级修改中调整或清空。
+
+| 模式 | 参数(单位 kW,按单台 aPower) | 来源 |
+| --- | --- | --- |
+| 强制充电 | 固定:优先级 `""`/`""`;必填:`chargePower=8`(单台最大充电功率)、`gridChargeMax=-1`(默认不限) | wiki《常规调度配置·仅备电》(原文 8000 W)、`tou-template.md` |
+| 强制放电 | 固定:优先级 `""`/`""`;必填:`dischargePower=10`(单台最大放电功率)、`gridDischargeMax=-1`(默认不限) | wiki《常规调度配置·强制aPower放电》(原文 10000 W) |
+| Zero Import | 固定:优先级 `9,9,9`/`9,9,9`、`gridDischargeMax=0.1`、`gridFeedMax=0.1`;必填:`dischargePower=10`;初始值:`gridMax=0`、`gcaoMax=0`、`heatEnable=1` | `service/test/tou/main.go` 测试数据(云端 `dispatchId=9`) |
+
+识别顺序(解析时):
+
+1. 按原始值精确匹配特殊模式(Zero Import:`9,9,9`/`9,9,9`);
+2. 两个优先级都为空时:只设置了 `chargePower` → 强制充电;只设置了 `dischargePower` → 强制放电;两者都没设置 → 未设置优先级;两者都设置了 → 自定义并标出异常;
+3. 归一化后匹配 A~H;
+4. 都不匹配 → 自定义(只有一个优先级为空也归为自定义并标出异常)。
+
+“设置了”指字段有值且不为 `-1`(未设置的哨兵值)。Zero Import 只按优先级识别;如果已有数据的固定参数与定义不一致(如 `gridFeedMax` 不是 0.1),仍识别为 Zero Import,但标出不一致,且在用户未改动该时段时原样保留。识别结果只看优先级和上述字段,A~H 时段上额外设置的功率参数作为高级参数显示,不改变模式。
+
+- **写入规则**:用户新设置的优先级只能取自调度模式定义表,或者为空;不允许手工输入其他数值,避免下层应用无法识别。已有的非标准数值在用户没有改动时原样保留(见 FR-04“保持原值”)。
+- 前后端使用统一的模版类型定义,生产服与测试服共用同一套结构和代码,通过环境参数区分。
+- 云端字段拼写问题(`derSchdule`、`eletic*`、`ccociate*`、`mookRunCount`)在界面上显示规范名称;是否在 DTO 层映射由技术设计决定。
+- 模版主体中的 `priority`、`env`、`mookRunCount` 目前很少使用,不做语义解释:编辑时原样保留,允许按原始值填写,不做枚举或位域拆解。
+- 写操作记录操作人、环境、模版 ID 和提交内容,便于追溯(存储方式见 Q-07)。
+
+## 4. 待确认事项
+
+已关闭:Q-03(发布/删除接口已确认,功能放到后续迭代,见 FR-05)、Q-09(`priority`/`env`/`mookRunCount` 原样保留,见第 3 节)、Q-11(优先级为空时两者都写空字符串,见 FR-04)、Q-12(E/G、F/H 不拆分,由用户 PCS 设置决定,见调度模式定义表)、Q-01(高级修改:除优先级外全部参数可改,见 FR-04)、Q-13(扩展模式的优先级和参数,见模式参数表)、Q-14(强制充放电的 `gridChargeMax`/`gridDischargeMax` 为必填,预设 -1,可修改)。
+
+| 编号 | 问题 | 影响 |
+| --- | --- | --- |
+| Q-02 | 是否支持“复制已有模版新建”,是否允许以生产服模版为蓝本在测试服新建 | FR-04、FR-07 |
+| Q-04 | 月份是否必须覆盖全年;一个模版最多几组策略 | FR-04 校验 |
+| Q-05 | 导出格式:云端原始 JSON、规范化 JSON、xlsx,还是多选 | FR-06 |
+| Q-06 | 测试服页面是否也提供对比入口(反向对比) | FR-01、FR-07 |
+| Q-07 | 写操作记录是否入库,是否需要在工具内保留历史版本 | 共同需求 |
+| Q-08 | API 模版(1)和用户推荐(2)是否保留在列表中供查看和过滤(写入已限定为系统模版 0) | FR-02、FR-04 |
+| Q-10 | 权限:编辑和发布是否全部开放,是否需要区分角色 | FR-04、FR-05 |
+
+## 5. 第二阶段(暂不实现)
+
+- 模块接入 MCP,让 AI 完成模版编辑,复用本阶段的统一类型、校验规则和调度模式识别。
+- 现有 MCP 工具 `service_tou_template_*` 在第二阶段改为调用重构后的服务层。