weaver-e10-builder 1.6.10 → 1.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/commands/report-admin.d.ts.map +1 -1
  2. package/dist/commands/report-admin.js +378 -2
  3. package/dist/commands/report-admin.js.map +1 -1
  4. package/dist/commands/report-validate.d.ts.map +1 -1
  5. package/dist/commands/report-validate.js +1066 -3
  6. package/dist/commands/report-validate.js.map +1 -1
  7. package/dist/commands/report.d.ts.map +1 -1
  8. package/dist/commands/report.js +341 -3
  9. package/dist/commands/report.js.map +1 -1
  10. package/dist/commands/workflow-after-submit-comment.d.ts +3 -0
  11. package/dist/commands/workflow-after-submit-comment.d.ts.map +1 -0
  12. package/dist/commands/workflow-after-submit-comment.js +56 -0
  13. package/dist/commands/workflow-after-submit-comment.js.map +1 -0
  14. package/dist/commands/workflow-setting.d.ts.map +1 -1
  15. package/dist/commands/workflow-setting.js +2 -67
  16. package/dist/commands/workflow-setting.js.map +1 -1
  17. package/dist/services/report/blueprint.d.ts +109 -0
  18. package/dist/services/report/blueprint.d.ts.map +1 -0
  19. package/dist/services/report/blueprint.js +322 -0
  20. package/dist/services/report/blueprint.js.map +1 -0
  21. package/dist/services/report/build.d.ts.map +1 -1
  22. package/dist/services/report/build.js +8 -3
  23. package/dist/services/report/build.js.map +1 -1
  24. package/dist/services/report/card.d.ts +65 -0
  25. package/dist/services/report/card.d.ts.map +1 -0
  26. package/dist/services/report/card.js +151 -0
  27. package/dist/services/report/card.js.map +1 -0
  28. package/dist/services/report/copy-health.d.ts +31 -0
  29. package/dist/services/report/copy-health.d.ts.map +1 -0
  30. package/dist/services/report/copy-health.js +87 -0
  31. package/dist/services/report/copy-health.js.map +1 -0
  32. package/dist/services/report/dataset-heal.d.ts +64 -0
  33. package/dist/services/report/dataset-heal.d.ts.map +1 -0
  34. package/dist/services/report/dataset-heal.js +89 -0
  35. package/dist/services/report/dataset-heal.js.map +1 -0
  36. package/dist/services/report/dataset-ids.d.ts +70 -0
  37. package/dist/services/report/dataset-ids.d.ts.map +1 -0
  38. package/dist/services/report/dataset-ids.js +149 -0
  39. package/dist/services/report/dataset-ids.js.map +1 -0
  40. package/dist/services/report/dataset.d.ts.map +1 -1
  41. package/dist/services/report/dataset.js +3 -1
  42. package/dist/services/report/dataset.js.map +1 -1
  43. package/dist/services/report/empty-dataset.d.ts +51 -0
  44. package/dist/services/report/empty-dataset.d.ts.map +1 -0
  45. package/dist/services/report/empty-dataset.js +213 -0
  46. package/dist/services/report/empty-dataset.js.map +1 -0
  47. package/dist/services/report/field-binding.d.ts +75 -0
  48. package/dist/services/report/field-binding.d.ts.map +1 -0
  49. package/dist/services/report/field-binding.js +160 -0
  50. package/dist/services/report/field-binding.js.map +1 -0
  51. package/dist/services/report/forms.d.ts +32 -0
  52. package/dist/services/report/forms.d.ts.map +1 -1
  53. package/dist/services/report/forms.js +90 -0
  54. package/dist/services/report/forms.js.map +1 -1
  55. package/dist/services/report/formula-parent.d.ts +25 -0
  56. package/dist/services/report/formula-parent.d.ts.map +1 -0
  57. package/dist/services/report/formula-parent.js +116 -0
  58. package/dist/services/report/formula-parent.js.map +1 -0
  59. package/dist/services/report/locate.d.ts +40 -0
  60. package/dist/services/report/locate.d.ts.map +1 -0
  61. package/dist/services/report/locate.js +122 -0
  62. package/dist/services/report/locate.js.map +1 -0
  63. package/dist/services/report/reports.d.ts +4 -0
  64. package/dist/services/report/reports.d.ts.map +1 -1
  65. package/dist/services/report/reports.js +4 -2
  66. package/dist/services/report/reports.js.map +1 -1
  67. package/dist/services/report/scene.d.ts +22 -0
  68. package/dist/services/report/scene.d.ts.map +1 -0
  69. package/dist/services/report/scene.js +145 -0
  70. package/dist/services/report/scene.js.map +1 -0
  71. package/dist/services/report/types.d.ts +28 -0
  72. package/dist/services/report/types.d.ts.map +1 -1
  73. package/dist/services/report/verify.d.ts +24 -0
  74. package/dist/services/report/verify.d.ts.map +1 -1
  75. package/dist/services/report/verify.js +115 -2
  76. package/dist/services/report/verify.js.map +1 -1
  77. package/dist/services/report/workbook.d.ts +12 -1
  78. package/dist/services/report/workbook.d.ts.map +1 -1
  79. package/dist/services/report/workbook.js +107 -8
  80. package/dist/services/report/workbook.js.map +1 -1
  81. package/dist/services/workflow-after-submit-comment.d.ts +20 -0
  82. package/dist/services/workflow-after-submit-comment.d.ts.map +1 -0
  83. package/dist/services/workflow-after-submit-comment.js +81 -0
  84. package/dist/services/workflow-after-submit-comment.js.map +1 -0
  85. package/ecodecmd/src/build.js +36 -12
  86. package/package.json +1 -1
  87. package/skill-docs/SKILL.md +4 -4
  88. package/skill-docs/_catalog.md +10 -1
  89. package/skill-docs/references/coding/guide-page-code.md +95 -0
  90. package/skill-docs/references/components/ref-component-common.md +98 -0
  91. package/skill-docs/references/report/add-dataset-registration-guide.md +44 -22
  92. package/skill-docs/references/report/advanced-crosstab-tree-guide.md +82 -0
  93. package/skill-docs/references/report/ai-report-workflow.md +100 -100
  94. package/skill-docs/references/report/api-auth-headers.md +129 -0
  95. package/skill-docs/references/report/api-report-build-fast-path.md +274 -275
  96. package/skill-docs/references/report/app-datasource-lookup-guide.md +230 -230
  97. package/skill-docs/references/report/branch-scene-guide.md +293 -0
  98. package/skill-docs/references/report/build-resilience-guide.md +99 -0
  99. package/skill-docs/references/report/card-report-guide.md +110 -0
  100. package/skill-docs/references/report/cell-config-echo-guide.md +44 -9
  101. package/skill-docs/references/report/cell-transform-guide.md +9 -9
  102. package/skill-docs/references/report/column-split-report-guide.md +96 -0
  103. package/skill-docs/references/report/condition-format-guide.md +49 -24
  104. package/skill-docs/references/report/cross-dataset-filter-guide.md +180 -69
  105. package/skill-docs/references/report/crosstab-raw-workbook-guide.md +265 -0
  106. package/skill-docs/references/report/dataset-query-filter-guide.md +231 -235
  107. package/skill-docs/references/report/dataset-sidebar-ops-guide.md +75 -34
  108. package/skill-docs/references/report/dataset-table-field-contract-guide.md +196 -46
  109. package/skill-docs/references/report/datasource-metadata-guide.md +128 -119
  110. package/skill-docs/references/report/datasource-selection-and-parent-filter-guide.md +183 -148
  111. package/skill-docs/references/report/date-range-query-reference.md +97 -102
  112. package/skill-docs/references/report/default-header-style-guide.md +8 -8
  113. package/skill-docs/references/report/designer-blank-prevention-guide.md +8 -8
  114. package/skill-docs/references/report/dossier-report-guide.md +69 -0
  115. package/skill-docs/references/report/drilldown-report-guide.md +59 -0
  116. package/skill-docs/references/report/event-hreflink-guide.md +53 -47
  117. package/skill-docs/references/report/expansion-block-parent-config-guide.md +208 -0
  118. package/skill-docs/references/report/failure-cleanup-and-nonblocking-guide.md +183 -0
  119. package/skill-docs/references/report/field-bind-exact-match-guide.md +208 -208
  120. package/skill-docs/references/report/financial-stats-report-guide.md +89 -0
  121. package/skill-docs/references/report/formula-cell-api-guide.md +325 -258
  122. package/skill-docs/references/report/golden-case-summary-sheet.md +200 -0
  123. package/skill-docs/references/report/guide-report-build.md +6 -1
  124. package/skill-docs/references/report/hidden-row-and-header-merge-guide.md +10 -10
  125. package/skill-docs/references/report/layout-showlocation-freeze-guide.md +39 -10
  126. package/skill-docs/references/report/multi-report-crosstab-casebook.md +263 -0
  127. package/skill-docs/references/report/paged-group-report-guide.md +68 -0
  128. package/skill-docs/references/report/preaggregate-auto-disable-guide.md +24 -13
  129. package/skill-docs/references/report/query-condition-api-guide.md +145 -125
  130. package/skill-docs/references/report/ref-report-commands.md +41 -3
  131. package/skill-docs/references/report/report-baseinfo-defaults-guide.md +117 -117
  132. package/skill-docs/references/report/report-building-guide.md +52 -52
  133. package/skill-docs/references/report/report-case-prompts.md +104 -0
  134. package/skill-docs/references/report/report-config-schema.md +281 -281
  135. package/skill-docs/references/report/report-create-modes-guide.md +73 -35
  136. package/skill-docs/references/report/report-data-model.md +131 -131
  137. package/skill-docs/references/report/report-delivery-contract.md +23 -3
  138. package/skill-docs/references/report/report-designer-feature-map.md +30 -35
  139. package/skill-docs/references/report/report-help-guide.md +304 -0
  140. package/skill-docs/references/report/report-internal-error-guide.md +71 -0
  141. package/skill-docs/references/report/report-knowledge-base.md +27 -27
  142. package/skill-docs/references/report/report-lifecycle-api-guide.md +126 -94
  143. package/skill-docs/references/report/report-list-page-ops-guide.md +54 -8
  144. package/skill-docs/references/report/report-permission-guide.md +99 -102
  145. package/skill-docs/references/report/report-requirement-analysis-template.md +93 -29
  146. package/skill-docs/references/report/report-self-check-guide.md +164 -164
  147. package/skill-docs/references/report/report-verification-discipline-guide.md +203 -0
  148. package/skill-docs/references/report/safe-partial-save-guide.md +151 -151
  149. package/skill-docs/references/report/shard-freeze-report-guide.md +97 -0
  150. package/skill-docs/references/report/snowflake-id-precision-guide.md +84 -84
  151. package/skill-docs/references/report/spec-build-schema.md +71 -71
  152. package/skill-docs/references/report/targeted-fix-guide.md +155 -97
  153. package/skill-docs/references/report/user-request-scope-only-guide.md +23 -4
  154. package/skill-docs/references/workflow/guide-after-submit-comment.md +58 -0
  155. package/skill-docs/references/workflow/guide-workflow.md +6 -0
@@ -0,0 +1,293 @@
1
+ # 分支场景规则 —— 同 sheet 多报表 / 自增序号 / 单元格跳转 Sheet(SKILL A0.13)
2
+
3
+ > **优先级**:本节规则**优先级高于原有报表规则**,但**仅在识别命中时启用**。
4
+ > **不满足识别条件的普通报表需求 → 完全沿用原有全部报表逻辑**,不执行任何特殊配置。
5
+ >
6
+ > **CLI**:`e10-cli report scene rules | detect | check | apply`
7
+ > **脚本**:`e10-cli report scene` · 规则常量 `SCENE_RULES`(与 SKILL A0.13 同源)
8
+ > **声明式**:`build spec` 的 spec 支持 `columns[].cellType:"seq"|"jump"`、
9
+ > `scene.publicParent + scene.anchorCells`、`scene.jumpCells`
10
+
11
+ ---
12
+
13
+ ## 一、识别纪律(**不依赖关键词**)
14
+
15
+ > ⚠ **禁止**用「多报表」「序号」「自增」这类**业务关键词**去猜场景 —— 那正是本规则要避免的做法。
16
+ > 判定**只看内容结构**:`e10-cli report scene detect --req <需求文件>`。
17
+
18
+ 支持的输入:`.json`(spec / `cells[]` / `blocks[]`)、`.md` / `.txt` / `.csv`(文本网格)。
19
+ `.xlsx` 需先另存为 `.csv` / `.md`(本工具不直接解析二进制表格)。
20
+
21
+ 「数据源字段单元格」的结构特征(任一命中即为字段单元格):
22
+
23
+ | 形态 | 示例 |
24
+ |------|------|
25
+ | 三段式 `fieldKey` | `1324295304156717057.1162255789527552000.sort` |
26
+ | 结构化键值 | `字段:学院号` / `fieldKey: …` |
27
+ | 表格「字段」列 | 表头含 `字段` / `字段名` / `field` 列,该列有值 |
28
+
29
+ **分组规则**:连续的字段行归为一个**数据区**;空行 / 标题行 / 段落行 = **硬边界**(分隔符行 `|---|` 不断组)。
30
+
31
+ ```jsonc
32
+ // 输出(--json)
33
+ {
34
+ "scenes": ["A", "C"], // 命中场景(可同时 A+B / A+C / B+C / A+B+C)
35
+ "scene": "A+C",
36
+ "evidence": {
37
+ "dataAreas": 2, // ★ 场景 A 判据:数据区数量
38
+ "fieldRows": [7, 8, 9, 15, 16],
39
+ "seqMarked": ["【自增序号单元格】"], // ★ 场景 B 判据:标注
40
+ "jumpMarked": ["sheet2: 点击跳转sheet2"], // ★ 场景 C 判据:动作描述
41
+ "criteria": { "A": ["…"], "B": [], "C": ["识别到「点击跳转 sheetN」描述 1 处"] }
42
+ },
43
+ "action": "enable_scene_rules", // 未命中时 = "keep_default_rules"
44
+ "rules": { "A": { "mandatory": ["…"] } }
45
+ }
46
+ ```
47
+
48
+ **退出码**:detect 恒 0(识别结果本身不是错误);`check` 不合规 = **3**。
49
+
50
+ ### 1.1 识别边界说明(防过度触发 · 必须遵守)
51
+
52
+ | # | 边界 | 说明 |
53
+ |---|------|------|
54
+ | ① | **多报表只认「多组独立数据源字段」** | 仅当**同一个 sheet 内出现多组独立数据源字段(多行数据源)**才判定为多报表场景;**单报表单数据源 sheet,不新增公共父格**。 |
55
+ | ② | **公共父格只做归集,不改内部** | 公共父格**只**用于当前 sheet 内多个报表的**父格归集**,**不修改单报表内部原有单元格的左父格关系**。 |
56
+ | ③ | **`{seq}` 只认显式标注** | 只有需求里**明确标注**「自增序号单元格」才启用 `{seq}`;**普通序号 / 手工编号不触发**此规则。 |
57
+ | ④ | **跳转只认「点击跳转」描述** | 跳转 Sheet **仅当**需求描述包含「点击跳转sheetX / 点击可跳转到sheetX」这类描述才触发跳转事件;URL 参数严格遵循 `sheetIndex` **从 0 开始计数**。 |
58
+
59
+ ---
60
+
61
+ ## 二、场景 A · 同 sheet 多报表(公共父格)
62
+
63
+ ### 2.1 识别条件
64
+
65
+ **同一个 sheet 页存在多行数据源字段单元格** → 判定为「同页面上下放置多个独立报表」。
66
+
67
+ ### 2.2 强制配置(命中后必做)
68
+
69
+ > **细化指南**:`expansion-block-parent-config-guide.md`(三类单元格口径 / 泛化禁令 / 合计·总计行 / 扩展带公式格)。
70
+ > 凡同 sheet 存在「**主区 + 多个独立扩展块(统计块)**」时,按**三类单元格口径**处理:
71
+
72
+ | 类 | 单元格 | 配置 |
73
+ |---|--------|------|
74
+ | ① **公共父格** | Sheet **左上角** `Const`(自定义文本,如「统计区」) | `left=(-1,-1)` + **`isActiveParent=true`** |
75
+ | ② **入口格 + 标题/表头行整行 Const** | 每带**入口格**(数据带第一格、合计带第一格 = 纵向扩展根);每块**标题行 / 表头行整行 Const** | 左父格**统一绑定**公共父格 |
76
+ | ③ **数据格** | 入口格**右侧**的普通 Field 格 | **保持默认链**(同行前一列),**不动** |
77
+
78
+ > ⚠ **泛化禁令**:**不得**把公共父格配置**泛化**到「入口格以右的数据格」—— 数据跟随入口格扩展,
79
+ > **父格链**与**公共父格**是**两层机制**。
80
+
81
+ **合计行 / 总计行**:**合计行(按维度合计,如按学年/按部门)** 该行**整行所有格**(标签 + Field + Formula)左父格**统一 = 维度字段所在格**;
82
+ **总计行**保持**独立链**(挂自己行标签),公式**引用合计行**,不跟随维度扩展。
83
+
84
+ ### 2.3 配置形态
85
+
86
+ ```jsonc
87
+ // 公共父格(落库形态)
88
+ { "x": 0, "y": 0, "cellType": "Const", "cellText": "报表区",
89
+ "leftX": -1, "leftY": -1, "expandType": "NoExpand",
90
+ "isActiveParent": true, "displayType": "Group" }
91
+
92
+ // 各独立报表的行维入口格(=「扩展父格」)
93
+ { "x": 1, "y": 1, "cellType": "Field", "name": "zxmc", "text": "中心名称",
94
+ "expandType": "Vertical", "leftX": 0, "leftY": 0 } // ← 绑到公共父格
95
+ ```
96
+
97
+ > 公共父格若**已占用**该坐标 → **复用**它并置 `isActiveParent=true`(不新建)。
98
+
99
+ ### 2.4 判据纪律(★ 防交叉表误报)
100
+
101
+ **一个交叉表**的「列维表头」是 `Horizontal` 扩展、「行维入口」是 `Vertical` 扩展 ——
102
+ 二者同属**同一个矩阵**,**不是**两个独立报表。
103
+
104
+ | 判据 | 规则 |
105
+ |------|------|
106
+ | 只认**纵向入口** | `Vertical` 且「是根(`left=-1,-1`)**或**已绑公共父格」(`entryLikeCells()`)—— 幂等:绑过公共父格的入口格重复 check 不漏判 |
107
+ | 且必须**分布在不同行** | 行号去重后 ≥2(`looksMultiReport()`)→ 才是「上下多个独立报表」 |
108
+ | 纵向入口 ≤1 或全在同一行 | **不适用**场景 A,检查直接 PASS |
109
+
110
+ **反例(会误报的情形)**:chl测试1010 这类行列交叉表 —— 列头 `(0,3) 年级` 是 `Horizontal`、
111
+ 行头 `(1,1) 学院名称` 是 `Vertical`,粗按「扩展根≥2」会误判成多报表。**按上述判据即正确排除。**
112
+
113
+ ### 2.5 正例 / 反例
114
+
115
+ ```text
116
+ ✅ 正例:上下两个独立报表
117
+ A1「中心名称」 Vertical left=(-1,-1) ┐
118
+ A5「专业名称」 Vertical left=(-1,-1) ┘ 两个纵向根、行号不同 → 场景 A
119
+ → 修法:(0,0) 建公共父格,A1/A5 的 leftX/leftY 都改成 0,0
120
+
121
+ ❌ 反例:单块交叉表(不适用场景 A)
122
+ D1「年级」 Horizontal left=(-1,-1)
123
+ B2「学院名称」 Vertical left=(-1,-1)
124
+ → 只有 1 个纵向根 → 场景 A **不适用**,勿加公共父格
125
+ ```
126
+
127
+ ---
128
+
129
+ ## 三、场景 B · 自增序号(系统 `{seq}`)
130
+
131
+ ### 3.1 识别条件
132
+
133
+ 需求文件单元格标注 **【自增序号单元格】**(也接受 `[自增序号单元格]`)。
134
+
135
+ > ⚠ 边界③:**普通序号 / 手工编号不触发**本规则。
136
+
137
+ ### 3.2 强制配置
138
+
139
+ | # | 配置 | 说明 |
140
+ |---|------|------|
141
+ | ① | 统一使用系统标准序号字段 **`{seq}`** | `cellType='SequenceNumber'`,`cellText='{seq}'` |
142
+ | ② | **纵向扩展** | `expandType='Vertical'` |
143
+ | ③ | **禁止**用自定义公式生成序号 | 不得写 `=ROW()-2` / `=SUBTOTAL(...)` 之类 |
144
+
145
+ ### 3.3 配置形态
146
+
147
+ ```jsonc
148
+ { "cellType": "SequenceNumber", "typeName": "SequenceNumberCellType",
149
+ "cellText": "{seq}", "expandType": "Vertical", "displayType": "Group",
150
+ "leftX": 1, "leftY": 1 } // 左父格 = 所在块的入口格,随块纵向扩展
151
+ ```
152
+
153
+ > **反例**:`{"cellType":"Formula","cellText":"ROW()-2"}` —— 导出/分页后错位、跨块串号,**禁止**。
154
+
155
+ ---
156
+
157
+ ## 四、场景 C · 单元格跳转 Sheet 页
158
+
159
+ ### 4.1 识别条件
160
+
161
+ 需求描述包含「**点击跳转sheetX** / **点击可跳转到sheetX**」这类描述
162
+ (正则 `/(?:点击|单击|点按)\s*(?:可|即|能)?\s*跳转\s*(?:到|至)?\s*sheet\s*(?:页)?\s*([0-9]+)/i`)。
163
+
164
+ > ⚠ 边界④:**仅**这类「点击跳转」描述才触发;`sheetIndex` **严格从 0 开始计数**。
165
+
166
+ ### 4.2 强制配置(命中后必做)
167
+
168
+ | # | 配置 | 说明 |
169
+ |---|------|------|
170
+ | ① | 在**当前单元格**添加**点击跳转事件** | 落 `pcHreflink`(PC 端);移动端另配 `h5Hreflink`(别名 `mbhreflink`) |
171
+ | ② | 基础地址取**当前报表预览页 URL** | `/sp/edc/report/view/<reportId>` |
172
+ | ③ | URL 参数 **`sheetIndex=<N-1>`** | sheet1→`0`,sheet2→`1`,sheetN→`N-1`(**严格从 0 起**) |
173
+ | ④ | **打开方式**默认「**弹出页**」 | `openType="blank"`(与设计器右侧配置一致) |
174
+
175
+ ### 4.3 链接形态
176
+
177
+ ```text
178
+ 报表预览页:/sp/edc/report/view/1325388137101516800
179
+ 转到 sheet2 的完整链接:/sp/edc/report/view/1325388137101516800?sheetIndex=1
180
+ ```
181
+
182
+ ```jsonc
183
+ // 落库形态(fields[] + workbook style.cellType)
184
+ { "x": 2, "y": 1, "cellType": "Const", "cellText": "查看明细",
185
+ "pcHreflink": "/sp/edc/report/view/1325388137101516800?sheetIndex=1",
186
+ "h5Hreflink": "", "openType": "blank" }
187
+ ```
188
+
189
+ > **映射表(sheet 序号 → sheetIndex)**:`sheet1→0` · `sheet2→1` · `sheet3→2` … `sheetN→N-1`。
190
+ > 链接字符 `?` / `&` 必须是 **ASCII**(禁用全角 `?`),见 `event-hreflink-guide.md` §二。
191
+
192
+ ### 4.4 反例 / 常见错
193
+
194
+ | 错法 | 后果 |
195
+ |------|------|
196
+ | `sheet2 → sheetIndex=2`(off-by-one) | 跳到 sheet3,或越界无效 |
197
+ | 基础地址非 `/sp/edc/report/view/…` | 跳到无关页面 |
198
+ | `openType="popup"` / `"window"` | 非法值,平台不认(只认 `blank`/`self`/`jsscript`) |
199
+ | 链接用了全角 `?` / `&` | 预览点击**无反应** |
200
+
201
+ ---
202
+
203
+ ## 五、CLI
204
+
205
+ ```bash
206
+ # 识别(恒 exit 0)
207
+ e10-cli report scene rules
208
+ e10-cli report scene detect --req <需求文件> [--json]
209
+
210
+ # 体检(只读;exit 3 = 不合规)
211
+ e10-cli report scene check --report-id <rid> --app-id <appId> [--scene A|B|C] \
212
+ [--seq-cells "x,y;x,y"] [--jump-cells "x,y=N"] [--open-type blank] [--json]
213
+ # 离线定位:--dev-file <getReportDevInfo 的 data JSON>
214
+
215
+ # 定点修复(默认 dry-run,打印逐格差集;--apply 才落库)
216
+ e10-cli report scene apply --report-id <rid> --app-id <appId> --scene A \
217
+ [--at 0,0] [--text "报表区"] [--anchor "1,1;5,1"] [--apply]
218
+ e10-cli report scene apply --report-id <rid> --app-id <appId> --scene B \
219
+ --seq-cells "1,0" [--apply]
220
+ e10-cli report scene apply --report-id <rid> --app-id <appId> --scene C \
221
+ --jump-cells "2,1=2" [--base /sp/edc/report/view/<rid>] [--open-type blank] [--apply]
222
+ ```
223
+
224
+ **落库通道保障**:`scene apply` 一律走 `buildWorkbookFromFields`(**A0.8 定点补丁**,禁止整表重建)
225
+ + `saveReportDevInfoAuto`(**BUILD-39** 载荷自适应)+ `assertNoStaleDatasetIds`(**BUILD-42** 数据集 id 硬门禁),
226
+ `--apply` 后**自动回读校验**(场景 A:公共父格 `isActiveParent` + 锚点是否都绑上;场景 B:序号格 `SequenceNumber`+`Vertical`;
227
+ 场景 C:跳转格 `pcHreflink` 含 `/sp/edc/report/view/` 且 `sheetIndex` = N-1、`openType` 正确)。
228
+ 校验不过 → exit 2 且提示复查。
229
+
230
+ `--jump-cells` 语法:`"x,y=N"`,多个用 `;` 分隔(如 `"2,1=2;5,1=3"`);**N = 目标 sheet 序号,从 1 起**。
231
+
232
+ ---
233
+
234
+ ## 六、声明式(`build spec` 的 spec 字段)
235
+
236
+ ```jsonc
237
+ {
238
+ "appId": "…", "name": "预算执行(多报表同页)", "form": "…",
239
+ "columns": [
240
+ { "title": "序号", "cellType": "seq" }, // ★ 场景 B:系统序号 {seq}
241
+ { "title": "查看明细", "cellType": "jump", "jumpSheet": 2 }, // ★ 场景 C:跳转 sheet2
242
+ { "title": "中心名称", "field": "中心名称" }
243
+ ],
244
+ "scene": { // ★ 场景 A + C
245
+ "publicParent": { "x": 0, "y": 0, "text": "报表区" },
246
+ "anchorCells": ["1,1", "5,1"], // 各独立报表的扩展父格坐标
247
+ "jumpCells": [ { "cell": "2,1", "sheet": 2 }, "5,1=3" ], // 落库期给指定格写跳转链接
248
+ "base": "/sp/edc/report/view/<rid>", // 可选;缺省用搭建期 reportId 自动拼
249
+ "openType": "blank" // 可选;默认「弹出页」
250
+ }
251
+ }
252
+ ```
253
+
254
+ - `columns[].cellType:"seq"` → 生成 `SequenceNumber` **纵向**格;该列**不参与字段绑定匹配**(不会因无字段而 exit 4)。
255
+ - `columns[].cellType:"jump" + jumpSheet:N` → 生成 Const 文本 + 跳转链接;同样**不参与字段绑定匹配**。
256
+ - `scene.publicParent` → 落库前在指定坐标插入(或复用)公共父格并置 `isActiveParent`;
257
+ `scene.anchorCells` 列出的入口格左父格统一改到该坐标;**未列出的格一律不动**。
258
+ - `scene.jumpCells` → 落库前给每个 `{cell,sheet}`(或 `"x,y=N"`)写 `pcHreflink = <base>?sheetIndex=<N-1>` + `openType`。
259
+ - 不写 `scene` 段(或只写空对象)→ **完全不介入**(`applySceneDecl` 返回 null),原单块路径零影响。
260
+
261
+ > **多块内容**:`build spec` 当前为**单块模型**。多块(上下多个报表)内容可分别构建 /
262
+ > 在其上继续铺块后,统一用 `scene apply --scene A` 做「建公共父格 + 重绑入口格」这一步。
263
+
264
+ ---
265
+
266
+ ## 七、自检清单(交付前必过)
267
+
268
+ - [ ] 是否先跑了 `scene detect`?**不命中就不加任何特殊配置**(不要「顺手也加上」)。
269
+ - [ ] 场景 A 的公共父格是否在 **Sheet 左上角**、`isActiveParent=true`、有自定义文本?
270
+ - [ ] 场景 A 是否**只**改了「各独立报表的扩展父格」的左父格,其余格父格**未动**?(边界②)
271
+ - [ ] 是否确认这些纵向根**分布在不同行**(而非交叉表的列维/行维)?单报表单数据源**未**加公共父格?(边界①)
272
+ - [ ] 场景 B 的序号格是否 `SequenceNumber` + `Vertical` + `{seq}`,且**没有**残留公式?**普通序号未被误改**?(边界③)
273
+ - [ ] 场景 C 的跳转链接基础地址是否 `/sp/edc/report/view/<reportId>`、`sheetIndex` = **N-1(从 0 起)**、`openType=blank`?(边界④)
274
+ - [ ] 跳转链接是否用了 **ASCII** `?` / `&`(非全角)?
275
+ - [ ] `scene check` 是否 **PASS**(exit 0)?`check-ids` 是否同步合规(BUILD-42)?
276
+
277
+ ---
278
+
279
+ ## 八、相关文档
280
+
281
+ | 文档 | 关系 |
282
+ |------|------|
283
+ | `SKILL.md` A0.13 / 执行优先级 0.46 | 硬规则正文 |
284
+ | `expansion-block-parent-config-guide.md` | ★ 场景 A **细化**:三类单元格口径 / 泛化禁令 / 合计·总计行 / 扩展带公式格(BUILD-46/47/48) |
285
+ | `pitfalls BUILD-43` | 多报表未绑公共父格(各块扩展互串) |
286
+ | `pitfalls BUILD-44` | 序号用自定义公式生成(导出/分页错位) |
287
+ | `pitfalls BUILD-45` | 跳转 Sheet 的 `sheetIndex` 错位 / 基础地址非预览页 / 打开方式非法 |
288
+ | `pitfalls BUILD-48` | 公共父格泛化到数据格 / 合计行·总计行父格错配 |
289
+ | `event-hreflink-guide.md` | 超链接落库键 `pcHreflink`/`h5Hreflink`/`openType`、ASCII `?`/`&`、父格链传参 |
290
+ | `datasource-selection-and-parent-filter-guide.md` §2.0 | 既有父格链铁律(A0.7),本规则**不替代**它 |
291
+ | `formula-cell-api-guide.md` | Formula 格 API(场景 B 明令**不用**公式生号) |
292
+ | `report-requirement-analysis-template.md` §〇 | 需求分析阶段的场景识别章节 |
293
+ | `crosstab-raw-workbook-guide.md` §六 | 数据集 id 隔离(BUILD-42) |
@@ -0,0 +1,99 @@
1
+ # Agent 执行韧性(空壳清理 · 失败不卡死)(强制)
2
+
3
+ > **适用**:API/脚本搭建或改报表全程。
4
+ > **目标**:失败不留垃圾空壳;单点报错不拖死整单,先交可用结果、再提示用户、最后可后台补救。
5
+
6
+ ---
7
+
8
+ ## 一、失败 / 终止必须清理空壳报表(强制)
9
+
10
+ ### 1.1 什么叫「空壳 / 无用报表」
11
+
12
+ 满足**任一**即视为应删的空壳:
13
+
14
+ | 情形 | 说明 |
15
+ |------|------|
16
+ | 仅 `baseInfo` 建壳,**从未**成功 `saveReportDevInfo`(无 Field / 设计区空) | 临时名 `__build_*` / `__probe_*` / `__bench_*` |
17
+ | 布局保存失败 / 脚本异常退出 / 用户中止,留下未改目标名或不可用壳 | 列表里出现但点开空白或全 Const |
18
+ | 探测用临时报表(找表、压测) | 用完即删,禁止留在应用报表列表 |
19
+
20
+ **不要删**:已成功落库且已向用户交付设计器地址的正式报表(如「测试BBB报表-chl」「议题A」)。
21
+
22
+ ### 1.2 何时必须删除
23
+
24
+ - 命令 / 脚本 **抛错退出**
25
+ - Agent **中止**当前建表任务(含用户叫停)
26
+ - 同一任务内 **重建**前:旧失败 `reportId` 先 `deleteReport`
27
+ - `finally` / 收尾逻辑:扫描本会话创建的临时壳并清理
28
+
29
+ ```
30
+ POST/GET /api/bs/edc/report/deleteReport?id={reportId}
31
+ (或 multipart ids=;进回收站即可,见 report-lifecycle-api-guide.md §删除)
32
+ ```
33
+
34
+ Header 须带 `ebBusinessId`=appId。可批量:`id=id1,id2`。
35
+
36
+ ### 1.3 实现纪律
37
+
38
+ 1. 建壳成功后立刻记下 `reportId`(变量 / 日志);**禁止**只记名字。
39
+ 2. 成功改名并交付前,临时名壳仍算「进行中」;**失败路径必须 delete**。
40
+ 3. 向用户说明:「已删除失败产生的空报表 xxx」,避免列表残留。
41
+ 4. 禁止留下多个 `__build_*` 占列表。
42
+
43
+ ---
44
+
45
+ ## 二、单点失败不卡死(强制 · 失败前进)
46
+
47
+ ### 2.1 步骤分级
48
+
49
+ | 级别 | 步骤例 | 失败策略 |
50
+ |------|--------|----------|
51
+ | **阻断** | 登录、找 app/表(预算内)、建壳、绑数据集、**布局 saveReportDevInfo** | 修 1 次或删壳重建 1 次;仍失败 → **提示用户**并停止交付假链接;清理空壳 |
52
+ | **可降级** | `saveQueryItem`、`saveQueryConfig`、数据集筛选、权限、快照;**用户点名的** verify/HTML | **最多重试 1 次** → **提示用户** → **结束**(禁无限轮) |
53
+
54
+ ### 2.2 禁止卡死
55
+
56
+ - 同一 API / 同一报错 **连续尝试 > 2 次**(含重试)仍失败 → **必须停手**,向用户说明原因与需确认项。
57
+ - **禁止**为 `saveQueryItem` 500 等可降级项循环试参、开浏览器接口返回、阻塞不交布局链接。
58
+ - **禁止**在「获取查询条件失败」上耗尽会话;布局已成功则**先交付设计器地址**。
59
+
60
+ ### 2.3 对用户提示模板(可降级失败)
61
+
62
+ ```markdown
63
+ ⚠️ **查询条件未写入**(`saveQueryItem` 返回 …)
64
+ - 报表主体已保存,可先打开设计器查看布局。
65
+ - 请确认:是否仍需高级搜索条件「议题名称 / 申请人 / …」?
66
+ - 也可在设计器:页面 → 查询设置 → 手动添加。
67
+ - 我将在收尾再自动重试一次;若仍失败以你确认为准。
68
+ ```
69
+
70
+ 同类可替换:数据集筛选、权限、字段绑定抽检等。
71
+
72
+ ### 2.4 推荐执行序(建表)
73
+
74
+ ```
75
+ 找表 → 建壳 → 布局落库 → 【立刻可交设计器地址】
76
+ → 查询条件(失败则提示+跳过)
77
+ → 其它可降级项(失败则提示+跳过)
78
+ → 收尾:对失败的可降级项自动补救 1 次
79
+ → 汇总:成功项 / 需用户确认项
80
+ → finally:删除本任务产生的空壳
81
+ ```
82
+
83
+ ### 2.5 与交付合同
84
+
85
+ - 布局成功 → 遵守 `report-delivery-contract.md` §〇 **先交地址**。
86
+ - 可降级失败 → **不阻塞**首轮链接;在回复中列出「未完成项 + 请用户确认」。
87
+ - 阻断失败 → 不交假链接 + **删空壳** + 说明卡点。
88
+
89
+ ---
90
+
91
+ ## 三、相关文档
92
+
93
+ | 文档 | 关系 |
94
+ |------|------|
95
+ | `api-report-build-fast-path.md` | 建表主流程;引用本节清理与失败前进 |
96
+ | `query-condition-api-guide.md` §二点五 | 查询 500 形态;失败后按本节降级 |
97
+ | `report-delivery-contract.md` | 先交地址 |
98
+ | `report-lifecycle-api-guide.md` | deleteReport |
99
+ | `app-datasource-lookup-guide.md` §六 | 找表预算用尽则询问,不盲扫 |
@@ -0,0 +1,110 @@
1
+ # 卡片式报表 · 直构指南(e10-cli report card build)
2
+
3
+ > 场景:**每条记录 = 一张卡片**(增值税发票、设备卡、工单卡、资产卡…),纵向堆叠**同页不分页**。
4
+ > 首次打通:2026-09-15 「合同收票发票卡片-20260915」,落库 686ms / 20 格。
5
+ > 固化为命令:**`e10-cli report card build`** —— 同类需求不再写脚本。
6
+
7
+ ## 0. 三条铁律
8
+
9
+ 1. **先查 CLI 再动手**:`e10-cli report card example` 出模板 spec,改字段即可;**禁止**重写建表脚本。
10
+ 2. **字段锚点唯一**:锚点格必须是 Field 且 `expandType: Vertical` + `isActiveParent: true` + 左父格 `-1,-1`;
11
+ 卡片内**其余全部格子**(含 Const 文本)左父格一律显式指向锚点坐标 → 随记录整块复制。
12
+ 3. **字段精确预检**:`spec.cells[].field` 用**字段中文显示名**,精确命中失败 → exit 4 + 候选(禁止模糊兜底/系统字段回退)。
13
+
14
+ ## 1. 快速用法
15
+
16
+ ```bash
17
+ e10-cli report card example > card.json # 导出模板(含发票卡片示例)
18
+ e10-cli report card example paragraph > card.json # 导出「段落明细表」模板(多信息区块版式)
19
+ # 改 spec:appId / reportName / sourceId / sourceName / cells
20
+ e10-cli report card build --spec card.json # dry-run(默认)
21
+ e10-cli report card build --spec card.json --apply
22
+ ```
23
+
24
+ ## 2. spec 字段表
25
+
26
+ | 字段 | 必填 | 说明 |
27
+ |---|---|---|
28
+ | `appId` | ✅ | 目标应用 |
29
+ | `reportName` | ✅ | 报表名(建议带日期戳) |
30
+ | `reportId` | ✖ | 缺省则**自动建壳**(`baseInfo`);给了则覆盖该报表 |
31
+ | `sourceId` | ✅ | 表单 sourceId(跨应用用 `find form-global` 找) |
32
+ | `sourceName` | ✅ | 表单名 → 规范数据集名 `X(业务模块)` |
33
+ | `sourceType` | ✖ | `logic`(默认) / `form` |
34
+ | `tableName` | ✖ | 缺省 = `normalizeDatasetName(sourceName, sourceType)` |
35
+ | `anchor` | ✖ | `{x,y}` 默认 `{1,1}`(B2),必须落在 Field 格上 |
36
+ | `rowSizes` / `colSizes` | ✖ | 行高 / 列宽(隐藏列写 `0`) |
37
+ | `sheetConfig` | ✖ | 默认 `{dataPreAgg:false, simpleList:false}`(卡片式字段常含 TextArea,默认关预聚合) |
38
+ | `pageSetting` | ✖ | 默认 `{rowHeader:0,colHeader:0,gridLine:0,pagination:false}` → **不分页同页展示** |
39
+ | `showLocation` | ✖ | 默认 `1`(居左);`2` 居中。**改它会动全表显示位置**,非用户点名勿改 |
40
+ | `cells[]` | ✅ | `{x,y,text \| field, fmt, span, style}`;`x`=行(0基),`y`=列(0基),`span`=向右跨列数 |
41
+
42
+ `fmt`:`common`(默认) / `value`(0.00) / `int` / `percent` / `shortdate`
43
+ `style`:`{fore, back, bold, size, hAlign, border}`;`border:NOBORDER` 用于卡片间距行(`border:{color:'#FFFFFF',style:0}`)
44
+
45
+ ## 3. 卡片排版约定(发票类参考)
46
+
47
+ - 卡片行结构:标题行(跨列合并)→ 字段行(标签在左、值合并跨列)→ 内表头行 → 值行 → 单位行 → **间距行(空文本格,必须随块复制)**
48
+ - 标题:`fore:'#E36C09'` + `bold` + `size:16` + `hAlign:1`
49
+ - 合并用 `span`(脚本自动生成 `spans[]` + `cell.colCount`),**不要**手写 spans
50
+ - 无对应字段的格(如效果图里的「税额」)用 Const 文本占位(`--`),不要硬凑字段
51
+
52
+ ## 3.1 段落明细表(段落式卡片 · 2026-10-29 固化)
53
+
54
+ > 形态:**每条记录 = 一个规则段落块**,块内再分**多个信息区**(如「订单基本信息 / 货主信息 / 运货信息」),
55
+ > 每区一行**绿色区块标题条** + 若干**标签/值网格行**;记录间留空行;纵向堆叠随记录数复制。
56
+ > 与发票卡片**同一机制**(锚点格纵向扩展 + 全格左父格跟随),仅版式约定不同 —— 直接复用 `card build`。
57
+
58
+ **与发票卡片的版式差异**:
59
+
60
+ | 要素 | 发票卡片 | 段落明细表 |
61
+ |---|---|---|
62
+ | 块内分区 | 单一信息面 | 多个信息区,每区一条**区块标题条**(整行跨列 Const + 底色 `#C9E7D2` + bold) |
63
+ | 网格 | 标签左·值右合并 | 规则**标签/值交替网格**(6 列:标签|值|标签|值|标签|值),值一般不跨列 |
64
+ | 间距行 | 卡片间 1 行 | 段落间 1 行(空文本 + `border:NOBORDER`,必须随块复制) |
65
+ | 锚点 | 卡片首格 Field | 段落内**任一 Field 格**均可(建议第一区首行值格) |
66
+
67
+ **要点**:
68
+ - 区块标题条是 **Const**(不是数据字段),`span` 到全宽;锚点机制会让它随记录整块复制。
69
+ - 所有 Field 值格 `expandType:'Vertical'` 由脚本自动写入;**只有锚点格** `isActiveParent:true`,
70
+ 其余格(含标签 Const、区块标题条、间距行)左父格全部指向锚点 → 回读验证 `misParent=0`。
71
+ - 字段仍走**精确预检**(exit 4 + 候选);表单没有的格用 Const 占位,不硬凑。
72
+ - `pageSetting.pagination:false` 同页堆叠;要按记录分页 → 交用户在设计器选(能力边界见 §5)。
73
+
74
+ **搭建提示语句(用户可直接照此提需求 / AI 照此执行)**:
75
+
76
+ > 按段落明细表格式搭一张报表:每条记录一个段落块,块内分「XX信息 / YY信息 / ZZ信息」三个信息区,
77
+ > 每区一条整行底色标题条 + 标签/值网格;数据源表 `<sourceName>`(sourceId `<id>`,appId `<appId>`);
78
+ > 字段映射:区块1 用字段 A/B/C,区块2 用字段 D/E/F……;记录间空一行,同页堆叠不分页;
79
+ > 用 `e10-cli report card example paragraph` 导出模板改字段后 `card build`,dry-run 通过再 `--apply`,落库后回读验收(格数/锚点/全格左父格)并交设计器地址。
80
+
81
+ ## 4. 落库通道(脚本内置,勿改)
82
+
83
+ 1. `saveReportDevInfo` —— `form` 里 **`designKey` 传空串**(构建态公式/结构存活路径),workbook gzip+base64
84
+ 2. `saveReportWithCacheConfig` —— 同 workbook + `dataset` 清单 + `pageSetting`(**不分页只在这里生效**)
85
+ 3. 回读 `getReportDevInfo` 六项验证:格数 / Field 数 / 锚点 `isActiveParent` / 全格左父格→锚点 / 合并跨度 / `sheetProps.sheetConfig`
86
+ ⚠️ 环境兼容(2026-10-29 yunteams 实证):① 部分环境 fields 回读**不含 `isActiveParent` 键** → 锚点判据退化为
87
+ `expandType=Vertical + left=-1,-1`;② `sheetProps` 可能是**数组**且 `sheetConfig` 为 **JSON 字符串**
88
+ (`sheetProps[0].sheetConfig`)→ 两种形状都已兼容(e10-cli report card build 内置)。
89
+
90
+ ## 5. 能力边界(无 API 写法,交设计器并**明确告知用户**)
91
+
92
+ | 效果 | 结论 |
93
+ |---|---|
94
+ | 发票编号条形码/二维码 | 单元格不支持 → 默认文本;需设计器配条码属性 |
95
+ | 价税合计(大写/小写) | 表单无字段 → 不放该行,或设计器内加公式 |
96
+ | 一条记录按记录数**真实分页** | 与「不分页堆叠」互斥;`pageSetting.pagination` 由用户选择 |
97
+
98
+ ## 6. 验证与交付
99
+
100
+ - dry-run 会打印:格数 / 形状(x行 y列) / 字段数 / 锚点 / 预聚合开关
101
+ - `--apply` 后脚本自报 `VERIFY OK|FAIL`(FAIL → exit 2),并打印**纯文本**设计器地址
102
+ - 交付:纯文本地址,交链即停(见 `report-delivery-contract.md`)
103
+
104
+ ## 7. 历史耗时教训(14 分钟那次)
105
+
106
+ | 白烧点 | 对策 |
107
+ |---|---|
108
+ | 建壳不知有命令 → 读源码反推 6~7 次 | 规则:「确定性动作先查 CLI」(pitfalls `PERF-7`) |
109
+ | 表不在应用内 → 手工循环探测,失败 2 次 | `e10-cli report find form-global`(pitfalls `FIND-2`),验证 3.5s 命中 |
110
+ | 卡片式无固化命令 → 每轮重写脚本 | 本指南 + `card build`(pitfalls `BUILD-24`) |
@@ -28,7 +28,7 @@
28
28
  **指纹示例**:`formatterType[0] + '|' + formatter + '|' + font + '|' + backColor`
29
29
  相同指纹 → 直接复用已通过的 style 对象引用(或深拷贝),**不再**走 JSON 样例确认。
30
30
 
31
- ## 二、数字格式目录(工具栏回显参照)
31
+ ## 二、数字格式目录(工具栏回显金标准)
32
32
 
33
33
  > 来源:设计器静态资源 `main.js` 中格式下拉 `g()` 目录。`¥` 为全角 `U+FFE5`(JSON 中写 `\uFFE5`)。
34
34
 
@@ -55,15 +55,50 @@
55
55
  | 只改 `formatter`、不改 `formatterType` | key1 仍为 common → 常规 |
56
56
  | 半角 `¥`(U+00A5)代替全角 `¥`(U+FFE5) | 与目录 id 不全等 |
57
57
 
58
+ ### ★ 「常规」口径与短码踩雷(注意点 BUILD-47)
59
+
60
+ > **预览渲染吃 `style.formatter`,不是顶层 `formatterType`。** 构建器会把 `formatterType[0]`(短码)**透传**进 `style.formatter`。
61
+
62
+ | 目标 | ✅ 正确 | ❌ 踩雷 |
63
+ |------|--------|--------|
64
+ | **常规** | `formatterType:["common"]` + **`style.formatter:"General"`** | `style.formatter:"common"`(字面量短码) |
65
+ | 货币 | `formatterType:["huobi"]` + `style.formatter:'"¥"#,##0.00_);[Red]("¥"#,##0.00)'` | `style.formatter:"huobi"` |
66
+
67
+ - 若 `style.formatter` 落成**字面量 `common`**,SpreadJS 会把它**当数字格式串解释**(`m`=月份)→ 在 12 月预览显示成 **`co12on`**。
68
+ - 写 `0.00` / `0.##` 功能正常但设计器会归「**其他数字格式**」;用户要求「保持常规」→ 一律用 **`General` + `common`** 口径。
69
+ - **格式调整范围以用户点名的单元格区域为准**,未点名区域**不顺手改**。
70
+ - `e10-cli report validate format --map "常规"` 自动纠正并告警;`--inline '{"formatter":"common"}'` 命中断码误写。
71
+
72
+ #### 短码直通对照表(`formatterType[0]` → 必须写进 `style.formatter` 的**格式串**)
73
+
74
+ | `formatterType[0]`(短码) | `style.formatter` 必须是 |
75
+ |---------------------------|--------------------------|
76
+ | `common` | `General` |
77
+ | `percent` | `0.00%` |
78
+ | `value` | `0.00_);[Red](0.00)` |
79
+ | `huobi` | `"¥"#,##0.00_);[Red]("¥"#,##0.00)` |
80
+ | `kuaiji` | `_ "¥"* #,##0.00_ ;_ "¥"* -#,##0.00_ ;_ "¥"* "-"??_ ;_ @_ ` |
81
+ | `shortdate` | `yyyy/m/d;@__@` |
82
+ | `longdate` | `yyyy"年"m"月"d"日";@` |
83
+ | `time` | `h:mm:ss;@` |
84
+ | `fenshu` | `# ?/?` |
85
+ | `kexuejishu` | `0.00E+00` |
86
+ | `text` | `@` |
87
+
88
+ **铁律**:`formatterType` 的**字面量绝不能直通** `style.formatter`(透传 bug)。
89
+ 保存前统一归一 `style.formatter` 为合法 SpreadJS 格式串 —— 已由 落库前防御层的 **R9**
90
+ (落库前自动纠正 + action 留痕)与 构建层的 `normalizeFormulaCellShape()` 兜底。
91
+ 目录**单一事实来源**见 ``(校验器 / 保存层共用,避免漂移)。
92
+
58
93
  ### 正确写入示例(货币)
59
94
 
60
95
  ```json
61
96
  {
62
- "style": {
63
- "formatter": "\"¥\"#,##0.00_);[Red](\"¥\"#,##0.00)"
64
- },
65
- "formatterType": ["huobi"],
66
- "tag": { "formatterType": ["huobi"] }
97
+ "style": {
98
+ "formatter": "\"¥\"#,##0.00_);[Red](\"¥\"#,##0.00)"
99
+ },
100
+ "formatterType": ["huobi"],
101
+ "tag": { "formatterType": ["huobi"] }
67
102
  }
68
103
  ```
69
104
 
@@ -116,7 +151,7 @@ UI 内部拼串形态(勿原样当 formatter):`"<formatter>__@__<key1>"`
116
151
 
117
152
  1. 写入前用 CLI `validate format` / 本指南目录校验字体、字号是否在设计器支持列表内。
118
153
  2. **不支持**(例:用户要 10 号但当前租户目录无 10)→ **明确提示用户**:「报表不支持 N 号字体,已按默认字号(通常 12)展示」→ **继续用默认字号落库**,禁止中断任务。
119
- - **禁止变通**:不要手工换算 px(如 10pt→`13.3333px`)绕过目录。后端不校验会照存,但设计器无该项、工具栏回显异常,属于假装支持。
154
+ - **禁止变通**:不要手工换算 px(如 10pt→`13.3333px`)绕过目录。后端不校验会照存,但设计器无该项、工具栏回显异常,属于假装支持。
120
155
  3. 字体名优先使用设计器可选名(如 `微软雅黑`);未知字体 → 提示并回退默认字体,同样不卡住。
121
156
 
122
157
  ---
@@ -141,7 +176,7 @@ e10-cli report validate format --map "货币"
141
176
  e10-cli report validate transform --map "人员"
142
177
  e10-cli report validate transform --map "部门全路径"
143
178
  e10-cli report validate transform --list
144
- ```
179
+
145
180
  e10-cli report validate format --map "货币"
146
181
  e10-cli report validate format --map "年份"
147
182
  e10-cli report validate format --file cell.json
@@ -150,7 +185,7 @@ e10-cli report validate format --file cell.json
150
185
  e10-cli report verify format <reportId> [appId]
151
186
  ```
152
187
 
153
- 脚本:`e10-cli report verify format`。
188
+ 脚本:`e10-cli report validate format`。
154
189
 
155
190
  ---
156
191
 
@@ -37,7 +37,7 @@
37
37
  | 颜色选择框 | `colorSelect` | `transSelectOptions`(`selectName` 常为颜色值) |
38
38
  | 分值图标 | `scoreIcon` | `transSelectOptions:[{id:"scoreIconId",selectValue:"1",selectName:"<最大分>"}]` |
39
39
  | 斜线文字 | `slashWord` | `transSelectOptions:[{id:"slashWordId",selectValue:"slashWord",selectName:"TopLeftDownRight"|"DownLeftTopRight"}]`;文案最多 3 段,半角 `;` 分隔 |
40
- | 关联类型 | `browser` | 弹窗写入 `browserType`(如 `{module,type}` / ComInfo id,**以实际请求为准**) |
40
+ | 关联类型 | `browser` | 弹窗写入 `browserType`(如 `{module,type}` / ComInfo id,**以接口返回为准**) |
41
41
  | 图片 | `picture` | — |
42
42
 
43
43
  > Java 仍兼容遗留 `hrm` / `dept` / `subcom` / `fill`,**新写禁止**用遗留值;人员/部门一律走 `browser`+ComInfo。
@@ -46,13 +46,13 @@
46
46
 
47
47
  ```json
48
48
  {
49
- "transType": "browser",
50
- "browserType": [{ "id": "HrmEmployeeComInfo" }],
51
- "isHtml": "0",
52
- "qrcodeType": "no",
53
- "prefixAndSuffix": ["", ""],
54
- "hiddenContext": "0",
55
- "textDirection": "FromLeftToRight"
49
+ "transType": "browser",
50
+ "browserType": [{ "id": "HrmEmployeeComInfo" }],
51
+ "isHtml": "0",
52
+ "qrcodeType": "no",
53
+ "prefixAndSuffix": ["", ""],
54
+ "hiddenContext": "0",
55
+ "textDirection": "FromLeftToRight"
56
56
  }
57
57
  ```
58
58
 
@@ -144,4 +144,4 @@ e10-cli report validate transform --list
144
144
  - `cell-config-echo-guide.md` — 数字格式 / 日期分组 / 字体
145
145
  - `report-designer-feature-map.md` — 右侧面板总览
146
146
  - `report-data-model.md` §八 — 已废弃错误表,以本文为准
147
- - `safe_report_save.js` — `fieldToCell` 透传
147
+ - `` — `fieldToCell` 透传