kcode-pi 0.1.0

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 (219) hide show
  1. package/README.md +358 -0
  2. package/dist/cli/kcode.d.ts +15 -0
  3. package/dist/cli/kcode.js +153 -0
  4. package/dist/cli/main.d.ts +2 -0
  5. package/dist/cli/main.js +7 -0
  6. package/docs/KCODE_DISTRIBUTION.md +91 -0
  7. package/extensions/kingdee-harness.ts +180 -0
  8. package/extensions/kingdee-header.ts +122 -0
  9. package/extensions/kingdee-tools.ts +379 -0
  10. package/knowledge/.backup/v1.0.0/version.json +10 -0
  11. package/knowledge/cangqiong/product-notes.md +15 -0
  12. package/knowledge/common/business-flows.md +115 -0
  13. package/knowledge/common/config-guides.md +110 -0
  14. package/knowledge/common/error-patterns.md +170 -0
  15. package/knowledge/common/implementation.md +144 -0
  16. package/knowledge/cosmic/hard-constraints.md +38 -0
  17. package/knowledge/cosmic/ksql-datafix.md +34 -0
  18. package/knowledge/cosmic/platform-baseline.md +32 -0
  19. package/knowledge/cosmic/plugin-decision-matrix.md +40 -0
  20. package/knowledge/cosmic/review-checklist.md +40 -0
  21. package/knowledge/cosmic/unittest.md +35 -0
  22. package/knowledge/enterprise/api-reference.md +186 -0
  23. package/knowledge/enterprise/code-patterns.md +217 -0
  24. package/knowledge/enterprise/plugin-lifecycle.md +188 -0
  25. package/knowledge/enterprise/tables.json +159 -0
  26. package/knowledge/flagship/api-reference.md +237 -0
  27. package/knowledge/flagship/code-patterns.md +246 -0
  28. package/knowledge/flagship/cosmic-platform-note.md +15 -0
  29. package/knowledge/flagship/plugin-lifecycle.md +248 -0
  30. package/knowledge/flagship/tables.json +159 -0
  31. package/knowledge/version.json +10 -0
  32. package/knowledge/xinghan/product-notes.md +15 -0
  33. package/package.json +71 -0
  34. package/prompts/kd-discuss.md +11 -0
  35. package/prompts/kd-execute.md +12 -0
  36. package/prompts/kd-plan.md +12 -0
  37. package/prompts/kd-ship.md +12 -0
  38. package/prompts/kd-spec.md +12 -0
  39. package/prompts/kd-verify.md +12 -0
  40. package/skills/kd-check/SKILL.md +26 -0
  41. package/skills/kd-cosmic-dev/SKILL.md +82 -0
  42. package/skills/kd-cosmic-review/SKILL.md +90 -0
  43. package/skills/kd-cosmic-unittest/SKILL.md +92 -0
  44. package/skills/kd-debug/SKILL.md +30 -0
  45. package/skills/kd-discuss/SKILL.md +24 -0
  46. package/skills/kd-execute/SKILL.md +22 -0
  47. package/skills/kd-gen/SKILL.md +34 -0
  48. package/skills/kd-ksql/SKILL.md +86 -0
  49. package/skills/kd-plan/SKILL.md +24 -0
  50. package/skills/kd-ship/SKILL.md +22 -0
  51. package/skills/kd-spec/SKILL.md +24 -0
  52. package/skills/kd-verify/SKILL.md +22 -0
  53. package/themes/kcode-dark.json +81 -0
  54. package/vendor/kingdee-skills/cosmic-unittest/SKILL.md +788 -0
  55. package/vendor/kingdee-skills/cosmic-unittest/author-cache.json +5 -0
  56. package/vendor/kingdee-skills/cosmic-unittest/cosmic-unittest-skill-overview.html +746 -0
  57. package/vendor/kingdee-skills/cosmic-unittest/examples/business-test.md +205 -0
  58. package/vendor/kingdee-skills/cosmic-unittest/examples/common-test.md +257 -0
  59. package/vendor/kingdee-skills/cosmic-unittest/examples/formplugin-test.md +560 -0
  60. package/vendor/kingdee-skills/cosmic-unittest/examples/op-plugin-test.md +231 -0
  61. package/vendor/kingdee-skills/cosmic-unittest/examples/validator-test.md +232 -0
  62. package/vendor/kingdee-skills/cosmic-unittest/patterns/business-helper.md +184 -0
  63. package/vendor/kingdee-skills/cosmic-unittest/patterns/common-module.md +355 -0
  64. package/vendor/kingdee-skills/cosmic-unittest/patterns/convert-plugin.md +130 -0
  65. package/vendor/kingdee-skills/cosmic-unittest/patterns/formplugin.md +235 -0
  66. package/vendor/kingdee-skills/cosmic-unittest/patterns/op-plugin.md +226 -0
  67. package/vendor/kingdee-skills/cosmic-unittest/patterns/validator.md +206 -0
  68. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/SKILL.md +674 -0
  69. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/advanced-scenario-checklist.md +307 -0
  70. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/algox-performance-checklist.md +129 -0
  71. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/coding-standard-checklist.md +491 -0
  72. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/cosmic-api-checklist.md +285 -0
  73. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-access-checklist.md +261 -0
  74. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-transaction-checklist.md +390 -0
  75. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/domain-logic-checklist.md +295 -0
  76. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/form-plugin-checklist.md +508 -0
  77. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/infra-checklist.md +254 -0
  78. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ksql-checklist.md +305 -0
  79. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/lifecycle-checklist.md +298 -0
  80. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/operation-plugin-checklist.md +442 -0
  81. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/test-mock-checklist.md +120 -0
  82. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ui-performance-checklist.md +320 -0
  83. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/pattern-matcher.py +336 -0
  84. package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/review-score-calculator.py +121 -0
  85. package/vendor/kingdee-skills/ok-cosmic/CHANGELOG.md +295 -0
  86. package/vendor/kingdee-skills/ok-cosmic/README.md +460 -0
  87. package/vendor/kingdee-skills/ok-cosmic/SKILL.md +287 -0
  88. package/vendor/kingdee-skills/ok-cosmic/agents/openai.yaml +17 -0
  89. package/vendor/kingdee-skills/ok-cosmic/assets/BatchImportPluginTemplate.java +93 -0
  90. package/vendor/kingdee-skills/ok-cosmic/assets/BillPlugInTemplate.java +156 -0
  91. package/vendor/kingdee-skills/ok-cosmic/assets/ConvertPlugInTemplate.java +255 -0
  92. package/vendor/kingdee-skills/ok-cosmic/assets/FormPluginTemplate.java +597 -0
  93. package/vendor/kingdee-skills/ok-cosmic/assets/IWorkflowPluginTemplate.java +91 -0
  94. package/vendor/kingdee-skills/ok-cosmic/assets/ListPluginTemplate.java +194 -0
  95. package/vendor/kingdee-skills/ok-cosmic/assets/OpPluginTemplate.java +201 -0
  96. package/vendor/kingdee-skills/ok-cosmic/assets/OpenApiControllerTemplate.java +103 -0
  97. package/vendor/kingdee-skills/ok-cosmic/assets/PrintPluginTemplate.java +95 -0
  98. package/vendor/kingdee-skills/ok-cosmic/assets/ReportFormPluginTemplate.java +257 -0
  99. package/vendor/kingdee-skills/ok-cosmic/assets/ReportListDataPluginTemplate.java +70 -0
  100. package/vendor/kingdee-skills/ok-cosmic/assets/StandardTreeListPluginTemplate.java +130 -0
  101. package/vendor/kingdee-skills/ok-cosmic/assets/TaskTemplate.java +80 -0
  102. package/vendor/kingdee-skills/ok-cosmic/assets/TreeListPluginTemplate.java +152 -0
  103. package/vendor/kingdee-skills/ok-cosmic/assets/WriteBackPlugInTemplate.java +286 -0
  104. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/attachment/AttachmentUploadBindSample.java +93 -0
  105. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/BotpTracePushSample.java +168 -0
  106. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/SampleConvertPlugin.java +223 -0
  107. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/cache/SampleCacheUsage.java +218 -0
  108. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/concurrent/SampleThreadPoolBatch.java +156 -0
  109. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectCrudSample.java +205 -0
  110. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectOpsSample.java +100 -0
  111. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/BeforeOperationConfirmSample.java +217 -0
  112. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ConfirmDialogSample.java +131 -0
  113. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/EntryRowCalculateSample.java +116 -0
  114. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/F7FilterSample.java +134 -0
  115. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/GetAndSetValueSample.java +176 -0
  116. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/HyperlinkJumpSample.java +124 -0
  117. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/OpenBillModalSample.java +253 -0
  118. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ReturnParentDataSample.java +295 -0
  119. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/TreeControlSample.java +140 -0
  120. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ViewControlOpsSample.java +132 -0
  121. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPluginBasicSample.java +170 -0
  122. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPreOpenFilterSample.java +68 -0
  123. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/message/MessageNotifySample.java +95 -0
  124. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/SampleMQConsumer.java +198 -0
  125. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/sample_mq.xml +15 -0
  126. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OpAddValidatorsSample.java +137 -0
  127. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OperationOptionBridgeSample.java +228 -0
  128. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/package-info.java +19 -0
  129. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BaseDataQuerySample.java +194 -0
  130. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BatchQuerySample.java +368 -0
  131. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/DataSetQueryStatSample.java +131 -0
  132. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportFormPlugin.java +179 -0
  133. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportListDataPlugin.java +616 -0
  134. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/snippets-guide.md +64 -0
  135. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/task/ScheduleTaskSample.java +160 -0
  136. package/vendor/kingdee-skills/ok-cosmic/assets/snippets/workflow/SampleWorkflowPlugin.java +302 -0
  137. package/vendor/kingdee-skills/ok-cosmic/manifest.json +78 -0
  138. package/vendor/kingdee-skills/ok-cosmic/ok-cosmic-intro.html +903 -0
  139. package/vendor/kingdee-skills/ok-cosmic/references/adv/attachment-api.md +114 -0
  140. package/vendor/kingdee-skills/ok-cosmic/references/adv/botp-convert.md +98 -0
  141. package/vendor/kingdee-skills/ok-cosmic/references/adv/dynamic-object.md +113 -0
  142. package/vendor/kingdee-skills/ok-cosmic/references/adv/entity-metadata.md +123 -0
  143. package/vendor/kingdee-skills/ok-cosmic/references/adv/event-lifecycle.md +184 -0
  144. package/vendor/kingdee-skills/ok-cosmic/references/adv/flex-prop.md +114 -0
  145. package/vendor/kingdee-skills/ok-cosmic/references/adv/form-utils.md +133 -0
  146. package/vendor/kingdee-skills/ok-cosmic/references/adv/operate-chain.md +159 -0
  147. package/vendor/kingdee-skills/ok-cosmic/references/adv/plugin-base.md +218 -0
  148. package/vendor/kingdee-skills/ok-cosmic/references/adv/query-dataset.md +149 -0
  149. package/vendor/kingdee-skills/ok-cosmic/references/adv/request-context.md +88 -0
  150. package/vendor/kingdee-skills/ok-cosmic/references/adv/view-handler.md +157 -0
  151. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-bill.md +76 -0
  152. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-botp.md +70 -0
  153. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-form.md +165 -0
  154. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-import.md +69 -0
  155. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-list.md +227 -0
  156. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-openapi.md +112 -0
  157. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-operation.md +135 -0
  158. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-print.md +65 -0
  159. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-data.md +64 -0
  160. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-form.md +90 -0
  161. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-task.md +62 -0
  162. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-tree-list.md +71 -0
  163. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-workflow.md +82 -0
  164. package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-writeback.md +71 -0
  165. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-algo.md +67 -0
  166. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-cache.md +63 -0
  167. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-model-svc.md +82 -0
  168. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-object.md +70 -0
  169. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-entity-model.md +61 -0
  170. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-exception.md +64 -0
  171. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-file.md +63 -0
  172. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-id.md +47 -0
  173. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-lock.md +61 -0
  174. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-log.md +63 -0
  175. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-network-control.md +70 -0
  176. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-orm-access.md +78 -0
  177. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-request-context.md +62 -0
  178. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-threadpool.md +63 -0
  179. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-tx.md +64 -0
  180. package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-utils.md +67 -0
  181. package/vendor/kingdee-skills/ok-cosmic/requirements.txt +2 -0
  182. package/vendor/kingdee-skills/ok-cosmic/rules/a-layer-rules.json +24 -0
  183. package/vendor/kingdee-skills/ok-cosmic/rules/anti-patterns.md +48 -0
  184. package/vendor/kingdee-skills/ok-cosmic/rules/cheat-sheet.md +256 -0
  185. package/vendor/kingdee-skills/ok-cosmic/rules/coding-preferences.md +140 -0
  186. package/vendor/kingdee-skills/ok-cosmic/rules/constraints.md +61 -0
  187. package/vendor/kingdee-skills/ok-cosmic/rules/decision-matrix.md +222 -0
  188. package/vendor/kingdee-skills/ok-cosmic/rules/intent-routing.md +94 -0
  189. package/vendor/kingdee-skills/ok-cosmic/rules/platform-baseline.md +69 -0
  190. package/vendor/kingdee-skills/ok-cosmic/rules/post-check.md +109 -0
  191. package/vendor/kingdee-skills/ok-cosmic/scripts/config_loader.py +204 -0
  192. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-api-knowledge.py +910 -0
  193. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-basedata-query.py +359 -0
  194. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-config-check.py +181 -0
  195. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-extpoints-query.py +389 -0
  196. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-form-metadata.py +856 -0
  197. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-check.py +262 -0
  198. package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-lint.py +293 -0
  199. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/__init__.py +2 -0
  200. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/base.py +393 -0
  201. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/resource_check.py +176 -0
  202. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/scene_check.py +375 -0
  203. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/style_check.py +434 -0
  204. package/vendor/kingdee-skills/ok-cosmic/scripts/lint/verify_check.py +36 -0
  205. package/vendor/kingdee-skills/ok-cosmic/scripts/route_client.py +186 -0
  206. package/vendor/kingdee-skills/ok-cosmic/scripts/script_utils.py +40 -0
  207. package/vendor/kingdee-skills/ok-cosmic/scripts/sqlite_cache.py +142 -0
  208. package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-commons.jar +0 -0
  209. package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-features.jar +0 -0
  210. package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic-docs.db +0 -0
  211. package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic.json +13 -0
  212. package/vendor/kingdee-skills/ok-cosmic/setup/setup-mac.sh +18 -0
  213. package/vendor/kingdee-skills/ok-cosmic/setup/setup-windows.bat +53 -0
  214. package/vendor/kingdee-skills/ok-cosmic/setup/setup.jar +0 -0
  215. package/vendor/kingdee-skills/ok-ksql/SKILL.md +81 -0
  216. package/vendor/kingdee-skills/ok-ksql/agents/openai.yaml +7 -0
  217. package/vendor/kingdee-skills/ok-ksql/manifest.json +14 -0
  218. package/vendor/kingdee-skills/ok-ksql/references/ksql-datafix.md +452 -0
  219. package/vendor/kingdee-skills/ok-ksql/scripts/ksql_lint.py +363 -0
@@ -0,0 +1,256 @@
1
+ # 高频 API 速查表
2
+
3
+ 以下 API 签名已确认准确,AI 可直接使用无需脚本验证。
4
+
5
+ ## QFilter 构造与组合 `[查询]`
6
+
7
+ ```java
8
+ import kd.bos.orm.query.QCP;
9
+ import kd.bos.orm.query.QFilter;
10
+
11
+ // 基本构造
12
+ new QFilter("field", QCP.equals, value)
13
+ new QFilter("field", QCP.not_equals, value)
14
+ new QFilter("field", QCP.large_than, value)
15
+ new QFilter("field", QCP.less_than, value)
16
+ new QFilter("field", QCP.large_equals, value)
17
+ new QFilter("field", QCP.less_equals, value)
18
+ new QFilter("field", QCP.in, new Object[]{v1, v2, v3})
19
+ new QFilter("field", QCP.not_in, new Object[]{v1, v2, v3})
20
+ new QFilter("field", QCP.like, "%keyword%")
21
+ new QFilter("field", QCP.is_null, null)
22
+ new QFilter("field", QCP.is_not_null, null)
23
+
24
+ // 组合
25
+ filter1.and(filter2)
26
+ filter1.or(filter2)
27
+ ```
28
+
29
+ ## Model 读写 `[表单] [单据]`
30
+
31
+ ```java
32
+ import kd.bos.dataentity.entity.DynamicObject;
33
+ import kd.bos.dataentity.entity.DynamicObjectCollection;
34
+
35
+ // 读取字段值
36
+ Object val = getModel().getValue("fieldKey"); // 表头字段
37
+ Object val = getModel().getValue("fieldKey", rowIndex); // 分录字段
38
+ Object val = getModel().getValue("fieldKey", rowIndex, parentRowIndex);// 子分录字段
39
+
40
+ // 设置字段值(自动触发 propertyChanged)
41
+ getModel().setValue("fieldKey", value); // 表头
42
+ getModel().setValue("fieldKey", value, rowIndex); // 分录
43
+
44
+ // 按 ID 设置基础资料字段(自动加载引用对象,比 setValue + loadSingle 更简洁)
45
+ getModel().setItemValueByID("basedataFieldKey", pkId); // 表头基础资料
46
+ getModel().setItemValueByID("basedataFieldKey", pkId, rowIndex); // 分录基础资料
47
+
48
+ // 按编码设置基础资料字段(已知编码不知 ID 时使用)
49
+ getModel().setItemValueByNumber("basedataFieldKey", number); // 表头基础资料
50
+ getModel().setItemValueByNumber("basedataFieldKey", number, rowIndex); // 分录基础资料
51
+
52
+ // 分录操作
53
+ int rowCount = getModel().getEntryRowCount("entryKey"); // 分录行数
54
+ int newRow = getModel().createNewEntryRow("entryKey", rowIndex); // 新增分录行
55
+ getModel().deleteEntryRow("entryKey", rowIndex); // 删除分录行
56
+ DynamicObject rowEntity = getModel().getEntryRowEntity("entryKey", rowIndex); // 获取分录行数据包
57
+ DynamicObject dataEntity = getModel().getDataEntity(); // 获取完整数据包
58
+ DynamicObjectCollection entry = dataEntity.getDynamicObjectCollection("entryKey"); // 分录集合
59
+ ```
60
+
61
+ ## View 控制 `[表单] [单据] [列表]`
62
+
63
+ ```java
64
+ import kd.bos.form.FormShowParameter;
65
+ import kd.bos.form.control.Control;
66
+ import kd.bos.list.ListShowParameter;
67
+
68
+ // 字段锁定/解锁
69
+ getView().setEnable(boolean, "key1", "key2"...); // 支持多 key
70
+
71
+ // 字段锁定/解锁(分录按行处理)
72
+ getView().setEnable(boolean, index , "key1", "key2"...); // 支持多 key
73
+
74
+ // 字段显示/隐藏
75
+ getView().setVisible(boolean, "key1", "key2"...); // 支持多 key
76
+
77
+ // 通知
78
+ getView().showSuccessNotification(String msg);
79
+ getView().showErrorNotification(String msg);
80
+ getView().showTipNotification(String msg);
81
+
82
+ // 操作
83
+ getView().invokeOperation(String opKey); // 调用操作
84
+ getView().updateView(String key); // 刷新控件
85
+ getView().updateView(); // 刷新整个视图
86
+ getView().showForm(FormShowParameter/ListShowParameter); // 打开页面
87
+
88
+ // PageCache(跨事件传值)
89
+ getView().getPageCache().put(String key, String value);
90
+ String val = getView().getPageCache().get(String key);
91
+
92
+ // 获取控件
93
+ Control ctrl = getView().getControl("controlKey");
94
+ ```
95
+
96
+ ## 封装工具类速查 `[通用]`
97
+
98
+ ```java
99
+ import kd.cd.core.util.CharSequenceUtils;
100
+ import kd.cd.core.util.CollectionUtils;
101
+ // fallback
102
+ // import org.apache.commons.lang3.StringUtils;
103
+ // import org.apache.commons.collections4.CollectionUtils;
104
+ import kd.cd.common.util.DynamicObjectUtils;
105
+ import kd.cd.common.operate.OpUtils;
106
+ import kd.bos.orm.query.QFilter;
107
+
108
+ // 字符串判空
109
+ CharSequenceUtils.isBlank(str)
110
+ CharSequenceUtils.isNotBlank(str)
111
+ CharSequenceUtils.equals(a, b)
112
+
113
+ // 集合判空
114
+ CollectionUtils.isEmpty(collection)
115
+ CollectionUtils.isNotEmpty(collection)
116
+
117
+ // DynamicObject 取值
118
+ DynamicObjectUtils.nullSafeGet(dynamicObject, "field") // 安全取值(空安全)
119
+ DynamicObjectUtils.setOf(dynamicObjects, "field")
120
+ DynamicObjectUtils.listOf(dynamicObjects, "field")
121
+
122
+ // 查询(标准 API)
123
+ QueryServiceHelper.queryOne(entityId, field, filters) // 查一条
124
+ QueryServiceHelper.query(entityId, selectFields, filters) // 查多条 → DynamicObjectCollection
125
+ QueryServiceHelper.query(entityId, selectFields, filters, orderBy) // 查多条 + 排序
126
+ QueryServiceHelper.queryDataSet(formId, algoKey, selectFields, filters, orderBy) // 查 DataSet
127
+
128
+ // 操作(失败即抛异常,适合大多数场景)
129
+ OpUtils.executeOperateOrThrow(opKey, entityId, new Object[]{pk})
130
+ OpUtils.executeOperateOrThrow(opKey, entityId, dataEntities)
131
+ OpUtils.throwIfFail(operationResult)
132
+ OpUtils.addErrorMessage(plugin, dataEntity, message)
133
+
134
+ // 操作(需要自行解析结果,适合 MQ 消费、后台任务等"失败不抛异常"场景)
135
+ OperationResult result = OperationServiceHelper.executeOperate(opKey, entityId, pks, option)
136
+ if (!result.isSuccess()) { String errMsg = OpUtils.getCompleteFailMsg(result); /* 自行处理 */ }
137
+ ```
138
+
139
+ ## 弹窗与回调 `[表单] [单据]`
140
+
141
+ ```java
142
+ import kd.bos.bill.OperationStatus;
143
+ import kd.bos.form.CloseCallBack;
144
+ import kd.bos.form.ConfirmCallBackListener;
145
+ import kd.bos.form.FormShowParameter;
146
+ import kd.bos.form.MessageBoxOptions;
147
+ import kd.bos.form.ShowType;
148
+ import kd.bos.list.ListShowParameter;
149
+ import kd.cd.common.form.ShowParameterUtils;
150
+
151
+ // 打开 F7 列表弹窗
152
+ ListShowParameter lsp = ShowParameterUtils.getF7List(formId, multiSelect);
153
+ getView().showForm(lsp);
154
+
155
+ // 打开普通表单弹窗
156
+ FormShowParameter fsp = ShowParameterUtils.getForm(formId, OperationStatus.ADDNEW, ShowType.Modal, "500px", "300px");
157
+ fsp.setCustomParam("key", value);
158
+ fsp.setCloseCallBack(new CloseCallBack(this, "actionId"));
159
+ getView().showForm(fsp);
160
+
161
+ // 确认框
162
+ ConfirmCallBackListener listener = new ConfirmCallBackListener("callbackId", this);
163
+ getView().showConfirm("确认信息?", MessageBoxOptions.YesNo, listener);
164
+ ```
165
+
166
+ ## 操作链 `[操作]`
167
+
168
+ ```java
169
+ import kd.cd.common.operate.chain.OperateChain;
170
+
171
+ // 链式操作
172
+ OperateChain.of(dataEntity).save().submit().audit().failThenThrow();
173
+ OperateChain.of(entityId, pkValue).save().submit().failThenDeleteAndThrow();
174
+ ```
175
+
176
+ ## BOTP 下推与选单 `[转换]`
177
+
178
+ ```java
179
+ import kd.cd.common.util.BotpUtils;
180
+ import kd.cd.common.util.BotpUtils.PushResult;
181
+
182
+ // 后台下推并保存(最常用,4 参数:源单标识, 目标单标识, 源单主键, 转换规则ID)
183
+ PushResult result = BotpUtils.pushAndSave(sourceFormId, targetFormId, sourcePk, null);
184
+ result.failThenThrow();
185
+ result.isSuccess();
186
+ result.getErrMsg();
187
+ Object[] targetPks = result.getPks();
188
+
189
+ // 下推不保存(只生成内存对象)
190
+ PushResult result = BotpUtils.pushNoSave(sourceFormId, targetFormId, sourcePk, null);
191
+
192
+ // 获取默认转换规则
193
+ String ruleId = BotpUtils.getDefaultRuleId(sourceFormId, targetFormId);
194
+
195
+ // 正向链路追踪:查所有下游目的单
196
+ Map<Long, Map<String, Set<Long>>> targets = BotpUtils.findAllTargetBills(targetEntityId, entityId, pkValues);
197
+
198
+ // 反向链路追踪:查直接上游源单
199
+ Map<Long, Set<Long>> sources = BotpUtils.findDirectSourceBills(sourceEntityId, entityId, pkValues);
200
+ ```
201
+
202
+ ## 元数据常用操作 `[通用]`
203
+
204
+ ```java
205
+ import kd.bos.entity.MainEntityType;
206
+ import kd.bos.entity.property.EntryType;
207
+ import kd.bos.dataentity.metadata.IDataEntityProperty;
208
+ import kd.cd.common.entity.EntityUtils;
209
+
210
+ // 获取主实体类型
211
+ MainEntityType mainType = EntityUtils.getMainEntityType(formId);
212
+
213
+ // 获取字段属性(单据头 & 单据体均适用)
214
+ IDataEntityProperty prop = EntityUtils.getProperty(formId, "fieldKey");
215
+
216
+ // 获取分录实体类型
217
+ EntryType entryType = EntityUtils.getEntryType(formId, "entryKey");
218
+
219
+ ```
220
+
221
+ ## 异常与日志 `[通用]`
222
+
223
+ ```java
224
+ import kd.bos.exception.ErrorCode;
225
+ import kd.bos.exception.KDBizException;
226
+ import kd.bos.logging.Log;
227
+ import kd.bos.logging.LogFactory;
228
+
229
+ // 业务异常(统一使用 KDBizException)
230
+ throw new KDBizException(new ErrorCode("myModule", "errCode001"), "业务描述");
231
+
232
+ // 包装异常(保留原始 cause)
233
+ throw new KDBizException(new ErrorCode("myModule", "errCode002"), e);
234
+
235
+ // 日志记录(插件内直接使用内置 log)
236
+ log.info("操作完成: billNo={}", billNo);
237
+ log.error("操作失败", e); // 异常用 error 级别
238
+
239
+ // 非插件类获取日志
240
+ private static final Log log = LogFactory.getLog(MyService.class);
241
+ ```
242
+
243
+ ## 多语言 `[通用]`
244
+
245
+ ```java
246
+ import kd.bos.dataentity.resource.ResManager;
247
+
248
+ // 标准写法:完整句模板 + 占位符
249
+ String msg = String.format(
250
+ ResManager.loadKDString("单据 %1$s 的金额 %2$s 超出限额", "MyPlugin_0", "kd-cd-myapp"),
251
+ billNo, amount
252
+ );
253
+
254
+ // 错误写法(禁止拼接)
255
+ // String msg = "单据" + billNo + "的金额" + amount + "超出限额";
256
+ ```
@@ -0,0 +1,140 @@
1
+ # 编码偏好、默认写法与治理方向
2
+
3
+ > 本文件为 `style_check.py`(STYLE-\*)、`resource_check.py`(RESOURCE-\*)、`verify_check.py`(VERIFY-\*)的**规则来源**。
4
+ > 幻觉禁忌和场景错配见 [anti-patterns.md](anti-patterns.md);当前自动 lint 规则前缀为 SCENE-\*。
5
+
6
+ 本文件承载 `ok-cosmic` 的 **B 层** 和 **C 层** 规则:
7
+
8
+ - **B 层:推荐项 / 新代码默认写法**
9
+ - 新生成代码默认尽量遵守。
10
+ - 历史存量代码若暂未满足,不因此直接判为错误。
11
+ - **"新代码"与"历史修补"的判断标准**:如果当前任务是**新增文件或新增方法**,按新代码标准遵守 B 层;如果是**在已有方法内追加几行逻辑**,优先保持与周围代码风格一致,B 层不强制。不确定时问用户。
12
+ - **C 层:目标态治理 / 渐进优化**
13
+ - 适合模板升级、专项治理、批量重构。
14
+ - 默认不作为一次性交付阻断项。
15
+
16
+ 真正的硬红线请看 [constraints.md](constraints.md)。
17
+
18
+ ## B1. 新代码默认写法
19
+
20
+ ### 插件基类与封装优先级
21
+
22
+ - **[B1.1]** **插件基类(封装层)**:新代码优先选择 `kd.cd.common.plugin` 包下的扩展基类:
23
+ `AbstractBillPlugInExt`、`AbstractFormPluginExt`、`AbstractListPluginExt`、`AbstractOperationServicePlugInExt`、`AbstractValidatorExt`
24
+ - **[B1.2]** **原生插件基类**:BOTP 转换(`AbstractConvertPlugIn`)和反写(`AbstractWriteBackPlugIn`)没有 `*Ext` 封装版本,直接使用 `kd.bos.entity.botp.plugin` 包下的原生基类。
25
+ - **[B1.3]** 如果必须给出原生写法:
26
+ 先说明为什么仓库封装不适用,再给最小可行实现,不要把原生样板扩散成默认风格。
27
+ - **[B1.4]** 历史项目中大量原生基类写法是可预期的;评估现有代码时,不要因为“不是 Ext 基类”就直接判错。
28
+
29
+ ### 工具类与实现风格
30
+
31
+ - **[B1.5]** 需要错误汇总时,优先使用 `OpUtils.addErrorMessage(...)`、`OpUtils.getCompleteFailMsg(...)`、`PushResult.failThenThrow()`
32
+ - **[B1.6]** 字符串判空优先使用 `CharSequenceUtils`;当其 API 未覆盖时(如 `trimToEmpty`、`substringBefore` 等),fallback 为 `org.apache.commons.lang3.StringUtils`;不要在**新示例代码**里混用 `ObjectUtils` 做字符串空白判断。
33
+ - **[B1.7]** 集合判空优先使用 `CollectionUtils`(`kd.cd.core.util`);当其 API 未覆盖时(如 `partition`、`union` 等),fallback 为 `org.apache.commons.collections4.CollectionUtils`;不要在**新示例代码**里手写 `!= null && !isEmpty()`。
34
+ - **[B1.8]** 对异常优先使用日志框架记录;`*Ext` 基类里直接使用内置的 `public final Log log`,非插件类可直接使用 `kd.bos.logging.LogFactory`。
35
+ - **[B1.9]** 未经用户明确要求,不要偏离 `assets/FormPluginTemplate.java` 的代码风格;确需偏离时,在答案里说明原因。
36
+ - **[B1.10]** 若必须新增模板之外的 `import`,需仅新增最小集合,并说明新增原因。
37
+
38
+ ### 业务封装优先级
39
+
40
+ - **[B1.11]** 对单据状态流转,失败即抛异常的场景优先使用 `OpUtils.executeOperateOrThrow`;需要自行解析操作结果的场景(如 MQ 消费、后台任务、失败后回填错误信息)可直接使用 `OperationServiceHelper.executeOperate` 并检查 `OperationResult`。
41
+ - **[B1.12]** 只有在需要连续调用多个操作时,才优先使用 `OperateChain`;单次 `save`、`submit`、`audit` 优先使用 `OpUtils`。
42
+ - **[B1.13]** 对单据转换,优先使用 `BotpUtils`;不要在**新代码**里手拼 `PushArgs`/`DrawArgs` 等重复样板。
43
+ - **[B1.14]** 处理基础资料(BaseData)相关业务动作时,先查 `BaseDataServiceHelper` 是否已有现成方法。
44
+ - **[B1.15]** 在操作插件里,除非需要准备的字段非常多,否则不要使用 `allFields()`;优先按实际场景显式准备字段。
45
+ - **[B1.16]** 对查询,优先使用 `QueryServiceHelper` + `AlgoUtils`;不要先写裸 SQL 或循环查库。
46
+ - **[B1.17]** `QueryServiceHelper.query(...)` 查出来的是扁平结果集,默认只用于读取、分组、聚合;不要直接 `set(...)` 后 `SaveServiceHelper.update/save(...)`。
47
+ - **[B1.18]** 查询基础资料时,优先使用 `BusinessDataServiceHelper.loadFromCache(...)`;不要对基础资料反复用普通查询接口查库。
48
+ - **[B1.19]** 对动态对象取值,优先使用 `DynamicObjectUtils`;不要直接深链式 `get("a.b.c")`。
49
+ - **[B1.20]** 对附件处理,优先使用 `AttachmentUtils` 和 uploader;不要直接散落调用 `AttachmentServiceHelper`。
50
+ - **[B1.21]** `references/base/*` 只用于补齐原生知识、事件签名和缺失能力;不要因为能写原生 API 就绕开现有封装。
51
+
52
+ ### 查询、资源与提示语
53
+
54
+ - **[B1.22]** 判断"是否存在"时,**新代码优先**使用 `QueryServiceHelper.exists(...)`,不要使用 `queryOne(...) != null` 这种写法。
55
+ - **[B1.23]** 查询时只取实际需要的字段;除加载完整单据/基础资料外,不要默认 `allFields()` 或无选择地查整包数据。
56
+ - **[B1.24]** `DataSet` 使用后要在最靠近创建/转换的位置关闭;优先用清晰的生命周期包裹,避免跨方法悬挂。
57
+ - **[B1.25]** 需要参数化查询时,优先使用平台查询构造或 KSQL 参数,不要手拼 where 条件字符串。
58
+ - **[B1.26]** 面向用户的提示语要体现业务语义和下一步动作,不要只抛底层异常文本。
59
+ - **[B1.27]** 报表或大结果集处理时,优先复用已查询数据,并用 `algo` 做分组、去重、统计;不要把大聚合逻辑堆进 Java 循环。
60
+ - **[B1.28]** 大数据量查询(如批量同步、报表取数、后台任务处理)时,优先使用分页迭代(`setLimit` + 循环偏移)或流式 `DataSet` 处理;不要一次性全量加载到内存。
61
+
62
+ ## B2. 元数据与脚本配合细则
63
+
64
+ - **[B2.1]** **元数据查询约束**:调用 `cosmic-form-metadata.py` 时,脚本会无条件展示所有字段;如果概览模式未显示所需字段,请主动在 `--fuzzy` 中增加搜索词进行精准匹配。
65
+ - **[B2.2]** 如果脚本未查到字段或表单元数据,必须提醒用户确认其提供的表单名称/标识是否正确,再继续处理。
66
+ - **[B2.3]** **字段元数据强制验证**:只要要生成/修改代码,且已知目标单据/表单,凡涉及字段(无论用户给中文名还是英文标识),都必须通过 `cosmic-form-metadata.py` 确认字段存在、字段类型、所属实体和特殊取值规则后再写入代码。
67
+ - **[B2.4]** **批量合并**:需要确认多个字段时,必须合并为一次 `--fuzzy` 调用(如 `--fuzzy qty price amount material org`),严禁逐个字段发起多次查询。
68
+ - **[B2.5]** **自动详情**:当 `--fuzzy` 传入 ≥3 个关键词时,脚本自动升级为详情模式(含枚举/refType),无需手动追加 `--show-detail`。
69
+ - **[B2.6]** **常规字段对齐**:仅确认 1-2 个字段标识时,不带 `--show-detail` 和 `--sql`。
70
+ - **[B2.7]** **深度实现(含枚举值)**:当需要编写枚举判断、手动赋值或基础资料关联查询前,带上 `--show-detail`。**枚举/下拉选项值的具体取值属于 A 层硬约束 [A1.8],必须查 Ext 列确认后才能写入代码,详见 [constraints.md](constraints.md)。**
71
+ - **[B2.8]** **生成 SQL**:除非用户强依赖编写原生 JDBC/SQL 查询,否则默认不要使用 `--sql`。
72
+
73
+ ## C1. 目标态治理项
74
+
75
+ 以下内容仍然推荐,但默认作为长期治理方向,而不是当前一次性交付阻断项:
76
+
77
+ - **[C1.1]** **验证来源注释**:建议在关键 `@Override` 方法或 BOS SDK 关键调用附近补充“验证来源”注释,作为事实留痕。
78
+ - **[C1.2]** **异常体系统一**:建议逐步把历史项目中的 `RuntimeException`、`IllegalArgumentException` 等,收敛到更明确的业务异常或带 `cause` 的统一异常体系。
79
+ - **[C1.3]** **日志治理**:建议逐步清理历史代码中的 `printStackTrace()`,统一为 `logger.error("问题描述", e)`。
80
+ - **[C1.4]** **存在性判断治理**:建议在后续重构中逐步把 `queryOne(...) != null` 迁移为更明确的存在性判断或领域查询封装。
81
+ - **[C1.5]** **原生基类迁移**:对稳定运行的历史插件,不要求为了“改成 Ext 基类”而进行无收益重构;只有在功能演进、模板升级、公共封装复用收益明确时再迁移。
82
+
83
+ ## C2. 评估历史代码时的默认口径
84
+
85
+ - **[C2.1]** 发现历史代码使用原生基类、`StringUtils`、`queryOne(...)`、`OperationServiceHelper.executeOperate(...)` 等写法时,先判断其是否触犯 [constraints.md](constraints.md) 中的硬红线。
86
+ - **[C2.2]** 若没有触犯 A 层红线,则应描述为:
87
+ - “当前可运行的历史写法”
88
+ - “建议新代码采用的替代写法”
89
+ - “是否值得在本次需求中顺手收敛”
90
+ - **[C2.3]** 不要把所有历史写法一律描述成"错误";要区分 **硬错误**、**推荐替换**、**后续治理** 三种层级。
91
+
92
+ ## 自动检测规则速查(STYLE / RESOURCE)
93
+
94
+ > 以下规则由 `style_check.py` 和 `resource_check.py` 自动扫描。
95
+ > A 层规则 ID 定义在 [a-layer-rules.json](a-layer-rules.json)(单一可信源),报 ERROR 必须修复;B 层报 WARNING,新代码优先修复。
96
+
97
+ ### STYLE-\*: 编码风格
98
+
99
+ | 规则 ID | 检测模式 | 正确做法 | 层级 |
100
+ |---|---|---|---|
101
+ | STYLE-001 | `StringUtils.isBlank/isEmpty/equals` 等判空方法 | `CharSequenceUtils`(仅 `isBlank/isNotBlank/isEmpty/isNotEmpty/equals`;`trimToEmpty` 等未覆盖方法 fallback `org.apache.commons.lang3.StringUtils`) | B |
102
+ | STYLE-002 | `!= null && !collection.isEmpty()` | `CollectionUtils.isNotEmpty(...)`;`partition` 等未覆盖方法 fallback `org.apache.commons.collections4.CollectionUtils` | B |
103
+ | STYLE-003 | 散落调用 `OperationServiceHelper.save/submit/audit` | `OpUtils` 或 `OperateChain` | B |
104
+ | STYLE-004 | `new PushArgs(...)` | `BotpUtils` | B |
105
+ | STYLE-005 | `new DrawArgs(...)` | `BotpUtils` | B |
106
+ | STYLE-006 | `dynamicObject.get("a.b.c")` 深链取值 | `DynamicObjectUtils` 安全取值 | B |
107
+ | STYLE-007 | 直接调用 `AttachmentServiceHelper` | `AttachmentUtils` + uploader | B |
108
+ | STYLE-008 | `queryOne(...) != null` 判存在 | `QueryServiceHelper.exists(...)` | B |
109
+ | STYLE-009 | `printStackTrace()` | `logger.error("描述", e)` | **A** |
110
+ | STYLE-010 | 操作插件使用 `allFields()` | 显式按场景准备字段 | B |
111
+ | STYLE-011 | SQL/KSQL 字符串拼接 | 参数化查询 | **A** |
112
+ | STYLE-012 | 数据库方言 SQL(`limit`/`rownum`/`nvl`/`isnull`) | KSQL 或平台查询接口 | **A** |
113
+ | STYLE-013 | 中文词条拼接(`"关于" + name + ...`) | 完整句模板 + `String.format(ResManager.loadKDString(...))` | B |
114
+ | STYLE-014 | 循环中 `view.updateView(...)` | 循环结束后统一局部刷新 | **A** |
115
+ | STYLE-015 | 循环中访问数据库(N+1 查询/写入),包括 `for`/`while` 及 `stream().forEach`/`map` 等 lambda 迭代;覆盖 `BusinessDataServiceHelper`/`QueryServiceHelper`/`SaveServiceHelper` | 分组 key → 批量加载 → 本地映射 | **A** |
116
+ | STYLE-016 | 循环中访问 Redis | 批量读取或本地缓存 | **A** |
117
+ | STYLE-017 | `query(...)` 结果直接 `set(...)` / `save` | 先 `query` 出 id,再 `load` 实体包后更新 | B |
118
+ | STYLE-018 | `throw new RuntimeException(...)` 等 | `KDBizException`,保留原始 `cause` | **A** |
119
+ | STYLE-019 | `new Thread(...)` | `kd.bos.threads.ThreadPools` | B |
120
+ | STYLE-020 | `Executors.*` | `ThreadPools.new*` / `ThreadPools.executeOnce*` | B |
121
+ | STYLE-021 | `SerializationUtils.toJsonString(args)` 打印大对象 | 只按需提取关键字段打印 | B |
122
+ | STYLE-022 | 循环中 `ORM.create(...)` | 批量组织数据,按批次处理 | **A** |
123
+ | STYLE-023 | 循环中 `DispatchServiceHelper.invoke*` | 合并/批量调用或先聚合参数 | **A** |
124
+ | STYLE-024 | `new QFilter(field, "=", value)` 第二个参数用字符串 | `new QFilter(field, QCP.equals, value)`,使用 QCP 枚举 | **A** |
125
+ | STYLE-025 | `BusinessDataServiceHelper.load(...)` 未指定查询字段(配合 `EntityUtils.getMainEntityType` / `BusinessDataServiceHelper.newDynamicObject` / `EntityMetadataCache.getDataEntityType` 全量加载) | 使用 `BusinessDataServiceHelper.load(entityName, selectFields, filters)` 指定所需字段 | B |
126
+ | STYLE-026 | 主键/id 用 `== null` / `!= null` / `== 0L` / `<= 0` 判空 | `EntityUtils.isEmptyPk(pk)` / `isNotEmptyPk(pk)`(兼容 null 和 0L) | B |
127
+ | STYLE-027 | BigDecimal 原生加减乘除与比较(`.add()` / `.subtract()` / `.multiply()` / `.divide()` / `.compareTo()`) | `BigDecimalUtils.add()` / `subtract()` / `multiply()` / `divide()` / `equals()` / `largeThan()` | B |
128
+
129
+ ### RESOURCE-\*: 资源管理
130
+
131
+ | 规则 ID | 检测模式 | 正确做法 | 层级 |
132
+ |---|---|---|---|
133
+ | RESOURCE-001 | 插件成员变量持有 `DataSet`/`InputStream` 等 | 方法内短持有,用完关闭 | B |
134
+ | RESOURCE-002 | 非 `final` 的 `static` 状态变量 | `PageCache` 或实例变量 | B |
135
+ | RESOURCE-003 | `ResManager.loadKDString(...)` 固化为 `static final` | 改为方法内实时获取 | B |
136
+ | RESOURCE-004 | `DataSet` 声明但未 `close()` | try-with-resources 或就近关闭 | **A** |
137
+
138
+ RESOURCE-004 例外(不报错):
139
+ - **报表插件等场景中 `return ds;`** — DataSet 作为方法返回值,由调用方/框架负责关闭。
140
+ - **DataSet 参与计算或合并** — `DataSet result = ds1.union(ds2)` 中 `ds1`、`ds2` 被消费,只需 close 最终结果 `result`。
@@ -0,0 +1,61 @@
1
+ # 硬约束与交付红线
2
+
3
+ > 本文件为**流程与原则守卫**(guidance-only),不直接对应 lint 脚本。
4
+ > 可自动检测的规则见:[anti-patterns.md](anti-patterns.md)(SCENE)、[coding-preferences.md](coding-preferences.md)(STYLE/RESOURCE/VERIFY)。
5
+
6
+ 本文件只承载 `ok-cosmic` 的 **A 层规则**:会直接影响事实准确性、插件上下文、事件阶段和交付正确性的硬约束。
7
+
8
+ - 命中本文件中的问题,默认按 **阻断交付** 处理。
9
+ - 不属于本文件的"推荐写法"与"目标态治理",请分别查看:
10
+ - [coding-preferences.md](coding-preferences.md)
11
+ - [post-check.md](post-check.md)
12
+
13
+ ## A1. 事实校验与模板约束
14
+
15
+ - **[A1.1] 拒绝幻觉**:严禁凭记忆或猜测生成任何 API 签名、事件方法名或单据字段标识。
16
+ - **[A1.2] 模板强制先行**:AI 在生成任何苍穹插件代码前,必须先读取对应的 `assets/*.java` 模板文件,并严格遵守模板中的方法签名。
17
+ - **[A1.3] 签名强制校验**:在编写任何 `@Override` 方法或调用 BOS SDK 关键方法前,应通过 `cosmic-api-knowledge.py` 的 `detail` 子命令验证该方法确实存在且签名准确(已在 `rules/cheat-sheet.md` 中列出的 API 可直接使用,无需脚本验证)。`API-*` 事后 lint 规则已废弃,若事前校验被跳过,只能依赖编译、脚本查询或人工确认补救。
18
+ - **[A1.4] 入口对齐协议**:
19
+ - **UI 控制 (只读/隐藏/弹窗)**:必须通过 `IFormView`(由 `this.getView()` 获取)。
20
+ - **数据操作 (取值/赋值/结构)**:必须通过 `IDataModel`(由 `this.getModel()` 获取)。
21
+ - **[A1.5] 验证优先级**:在使用原生 SDK 前,必须先查本地 `.md`,再通过脚本验证。
22
+ - **[A1.6] 继承溯源**:利用脚本返回的继承树确认方法是否在基类中。
23
+ - **[A1.7] 代码风格基线**:新生成代码必须以对应模板为主,不得脱离模板随意改写方法签名、生命周期方法或基础骨架。
24
+ - **[A1.8] 枚举/下拉选项值禁猜**:凡是需要使用 `ComboField`、下拉列表等字段的**具体选项值**(无论用于条件判断、状态赋值、QFilter 构造、数据反写还是任何其他场景),**严禁凭空编造或凭经验猜测**。必须先通过 `cosmic-form-metadata.py` 查询该字段,读取返回结果中「附加信息 (Ext)」列的真实枚举映射(如 `A:已审核, B:暂存`),确认后才能将对应的值写入代码。
25
+ - **[A1.9] 字段生成代码强制验证**:只要要生成或修改代码,且已知目标单据/表单(`formId` 或 `billName`),凡涉及字段(无论用户给的是中文名还是英文标识),都必须先通过 `cosmic-form-metadata.py` 验证字段是否存在、字段类型、所属实体(表头/表体/子表体/容器)和特殊取值规则(如 `BasedataPropField` 的 `refType`、`LargeTextField` 的 `{fieldKey}_tag`、Combo/下拉字段 Ext 映射)。未验证前不得直接把用户给出的字段写入代码。
26
+
27
+ ## A2. 平台开发红线
28
+
29
+ > 以下条目的平台背景详见 [platform-baseline.md](platform-baseline.md),对应的自动化 lint 规则主要见 [anti-patterns.md](anti-patterns.md)。
30
+
31
+ - **[A2.1] 绑定阶段禁改数据**:禁止在 `beforeBindData`、`afterBindData` 中修改数据对象。(→ `SCENE-008`)
32
+ - **[A2.2] initialize 边界**:禁止在 `initialize()` 中注册控件事件或做 UI 逻辑。(→ `SCENE-006`, `SCENE-007`)
33
+ - **[A2.3] 元数据访问边界**:业务代码禁止直接访问平台元数据表 `t_meta_xxx`。(→ `SCENE-009`)
34
+ - **[A2.4] 标准产品保护**:禁止继承标准产品表单/单据插件;禁止禁用原厂插件。
35
+ - **[A2.5] 引用对象类型一致**:创建引用对象时必须使用属性复杂类型或当前实体正确类型。(→ `SCENE-010`)
36
+ - **[A2.6] 元数据单例保护**:从缓存获取到的实体元数据必须先 `clone` 再修改。
37
+ - **[A2.7] 设计器/PDM 一致性**:业务对象、字段、默认值、可空性等定义以 PDM 和设计器为准。
38
+
39
+ ## A3. 运行时与运维红线
40
+
41
+ - **[A3.1] 数据访问红线**:查询必须参数化;`DataSet` 使用完必须关闭;禁止把 SQL/KSQL 条件当字符串随意拼接。(→ `STYLE-011`, `STYLE-012`, `RESOURCE-004`)
42
+ - **[A3.2] 性能红线**:禁止在循环中访问数据库、Redis、`view.updateView()`、`ORM.create()`、`DispatchServiceHelper.invoke*()`。(→ `STYLE-014`, `STYLE-015`, `STYLE-016`, `STYLE-022`, `STYLE-023`)
43
+ - **[A3.3] 日志红线**:统一使用 `kd.bos.logging.Log`;禁止 `printStackTrace()`。(→ `STYLE-009`)
44
+ - **[A3.4] 异常红线**:业务流程中的业务异常不得直接用 `RuntimeException` 伪装。(→ `STYLE-018`)
45
+
46
+ ## A4. 与 B/C 层的边界
47
+
48
+ - **不属于 A 层**:
49
+ - "优先使用 `Ext` 基类而不是原生基类"
50
+ - "优先使用 `OpUtils` / `BotpUtils`"
51
+ - "优先使用 `QueryServiceHelper.exists(...)` 替代 `queryOne(...)`"
52
+ - "给每个 `@Override` 都补验证来源注释"
53
+ - 上述内容仍然是有价值的,但默认分别归入:
54
+ - **B 层推荐项**:新代码默认遵守
55
+ - **C 层治理项**:适合逐步清理历史项目,不作为当前一次性交付的硬阻断
56
+
57
+ ## A5. 当前默认交付判断
58
+
59
+ - 命中 `SCENE-*` 中的硬错误,默认必须修复。
60
+ - 命中本文件列出的平台红线或运行时红线,默认必须修复。
61
+ - 若用户明确要求"按历史代码风格补丁式修改",可保留 **B/C 层** 历史写法,但仍不得突破 **A 层** 红线。