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,285 @@
1
+ # 苍穹平台 API 使用规范检查表
2
+
3
+ ## 🔴 P0 级问题
4
+
5
+ ### 1. DispatchServiceHelper 调用规范
6
+ **检查点**:
7
+ - 跨云跨应用调用是否通过 `DispatchServiceHelper.invokeService()` 调用?
8
+ - 是否直接依赖其他应用的 jar 包调用方法?
9
+ - 服务工厂路由规则是否正确?(`{isv}.{cloudId}.{appId}.ServiceFactory`)
10
+ - 调用结果是否做了异常处理?
11
+
12
+ **风险**: 直接依赖 jar 包会导致版本冲突;路由错误导致服务找不到
13
+
14
+ **修正方案**:
15
+ ```java
16
+ // ❌ 错误写法 - 直接依赖其他应用 jar 包
17
+ OtherAppService service = new OtherAppService();
18
+ service.doSomething();
19
+
20
+ // ✅ 正确写法 - 微服务调用
21
+ try {
22
+ Object result = DispatchServiceHelper.invokeService(
23
+ "isv.ti.bo", // Factory 类限定前缀
24
+ "appId", // 应用 Id
25
+ "xxxService", // 注册的服务名称
26
+ "methodName", // 调用方法
27
+ new Object[]{...} // 入参
28
+ );
29
+ } catch (Exception e) {
30
+ logger.error("微服务调用失败", e);
31
+ throw new KDBizException("服务调用失败: " + e.getMessage());
32
+ }
33
+ ```
34
+
35
+ ---
36
+
37
+ ### 2. TX 事务 API 使用规范
38
+ **检查点**:
39
+ - `TX.required()` / `TX.requiresNew()` 是否使用了 try-with-resources?
40
+ - catch 块中是否调用了 `h.markRollback()`?
41
+ - 事务内是否包含了外部 HTTP 调用或 MQ 发送?
42
+ - 事务类型选择是否合理?
43
+
44
+ **风险**: 事务未正确管理导致数据不一致
45
+
46
+ **修正方案**:
47
+ ```java
48
+ // ❌ 错误写法 - 未 markRollback
49
+ try (TXHandle h = TX.required("save")) {
50
+ try {
51
+ doSomething();
52
+ } catch (Exception e) {
53
+ logger.error("失败", e);
54
+ // 缺少 h.markRollback()!
55
+ }
56
+ }
57
+
58
+ // ✅ 正确写法
59
+ try (TXHandle h = TX.required("save")) {
60
+ try {
61
+ doSomething();
62
+ } catch (Throwable e) {
63
+ h.markRollback();
64
+ throw e;
65
+ }
66
+ }
67
+ ```
68
+
69
+ ---
70
+
71
+ ### 3. QFilter 构造安全
72
+ **检查点**:
73
+ - `QFilter` 条件参数是否来自用户输入?是否存在注入风险?
74
+ - 多值匹配是否使用了 `QCP.in` 而非 `QCP.equals`?
75
+ - 空值判断是否使用了 `QCP.is_null` 而非 `QCP.equals` null?
76
+ - 日期范围是否使用了 `QCP.large_equals` 和 `QCP.less_equals`?
77
+
78
+ **风险**: 查询逻辑错误,获取到错误数据
79
+
80
+ **修正方案**:
81
+ ```java
82
+ // ❌ 错误写法 - 操作符使用错误
83
+ new QFilter("status", QCP.equals, Arrays.asList("A", "B")); // 应用 in
84
+ new QFilter("name", QCP.equals, null); // 应用 is_null
85
+
86
+ // ✅ 正确写法
87
+ new QFilter("status", QCP.in, new String[]{"A", "B"});
88
+ new QFilter("name", QCP.is_null, null);
89
+ new QFilter("bizdate", QCP.large_equals, startDate)
90
+ .and(new QFilter("bizdate", QCP.less_equals, endDate));
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 🟠 P1 级问题
96
+
97
+ ### 4. setValue/getValue 使用规范
98
+ **检查点**:
99
+ - 分录字段 `setValue` 是否传入了 `rowIndex`?
100
+ - 分录字段 `getValue` 是否传入了 `rowIndex`?
101
+ - F7 基础资料字段赋值是否只传了 Long id?
102
+ - `setValue` 后需要刷新界面时是否调用了 `updateView`?
103
+
104
+ **风险**: 修改错误行数据、F7 赋值报错
105
+
106
+ **修正方案**:
107
+ ```java
108
+ // ❌ 错误写法 - 分录字段未传 rowIndex
109
+ getModel().setValue("entryField", value); // 不知道修改哪一行!
110
+
111
+ // ✅ 正确写法
112
+ int rowIndex = e.getChangeSet()[0].getRowIndex();
113
+ getModel().setValue("entryField", value, rowIndex);
114
+
115
+ // ❌ 错误写法 - F7 字段传 DynamicObject
116
+ getModel().setValue("org", orgDynamicObject); // 报错!
117
+
118
+ // ✅ 正确写法 - F7 字段只传 id
119
+ getModel().setValue("org", orgDynamicObject.getLong("id"));
120
+ ```
121
+
122
+ ---
123
+
124
+ ### 5. setValueFast 适用场景
125
+ **检查点**:
126
+ - 大数据包(分录 > 100 行)批量赋值是否仍使用 `model.setValue`?
127
+ - 应在大数据包场景使用 `property.setValueFast` 提升性能
128
+
129
+ **风险**: 大量 `setValue` 触发大量 `propertyChanged`,界面严重卡顿
130
+
131
+ **修正方案**:
132
+ ```java
133
+ // ❌ 错误写法 - 大数据包用 setValue
134
+ for (int i = 0; i < 500; i++) {
135
+ getModel().setValue("field1", value1, i); // 每次触发 propertyChanged
136
+ }
137
+
138
+ // ✅ 正确写法 - 使用 setValueFast
139
+ DynamicObjectCollection entries = getModel().getEntryEntity("entryEntity");
140
+ for (DynamicObject entry : entries) {
141
+ for (DynamicProperty prop : properties) {
142
+ prop.setValueFast(entry, newValue);
143
+ }
144
+ }
145
+ getView().updateView("entryEntity"); // 循环外统一刷新
146
+ ```
147
+
148
+ ---
149
+
150
+ ### 6. loadSingle vs queryOne 选择
151
+ **检查点**:
152
+ - 只读场景是否错误使用了 `loadSingle`?(应使用 `queryOne`)
153
+ - 需要保存回库的场景是否使用了 `queryOne`?(应使用 `loadSingle`)
154
+ - 判断存在是否使用了 `loadSingle`?(应使用 `exists` 或 `queryOne` 只查id)
155
+ - 高频读取基础资料是否使用了 `loadSingleFromCache`?
156
+
157
+ **数据访问方法选择速查**:
158
+ | 场景 | 推荐方法 |
159
+ |------|---------|
160
+ | 判断是否存在 | `QueryServiceHelper.exists()` |
161
+ | 读取少量字段(只读) | `QueryServiceHelper.queryOne()` |
162
+ | 读取完整数据包(需保存) | `BusinessDataServiceHelper.loadSingle()` |
163
+ | 大数据量流式处理 | `QueryServiceHelper.queryDataSet()` |
164
+ | 高频读取基础资料 | `BusinessDataServiceHelper.loadSingleFromCache()` |
165
+ | 批量加载 | `BusinessDataServiceHelper.load()` |
166
+
167
+ ---
168
+
169
+ ### 7. PageCache 使用限制
170
+ **检查点**:
171
+ - `getPageCache().put()` 的值是否为 String 类型?
172
+ - 复杂对象是否先序列化为 JSON 再存入?
173
+ - 是否在 PageCache 中存储了大量数据(超过 1MB)?
174
+
175
+ **风险**: 非 String 类型存入 PageCache 导致类型转换异常
176
+
177
+ **修正方案**:
178
+ ```java
179
+ // ❌ 错误写法
180
+ getPageCache().put("ids", idList); // 类型不对
181
+
182
+ // ✅ 正确写法
183
+ getPageCache().put("ids", SerializationUtils.toJsonString(idList));
184
+ String idsJson = getPageCache().get("ids");
185
+ List<Long> ids = SerializationUtils.fromJsonString(idsJson, List.class);
186
+ ```
187
+
188
+ ---
189
+
190
+ ### 8. FormShowParameter 参数传递
191
+ **检查点**:
192
+ - `getCustomParams().put()` 传递的值是否可序列化?
193
+ - 是否传递了 DynamicObject 等不可序列化的复杂对象?
194
+
195
+ **风险**: 序列化失败导致弹窗打开异常
196
+
197
+ **修正方案**:
198
+ ```java
199
+ // ❌ 错误写法
200
+ param.getCustomParams().put("data", dynamicObject); // 不可序列化
201
+
202
+ // ✅ 正确写法
203
+ param.getCustomParams().put("dataId", dynamicObject.getLong("id"));
204
+ param.getCustomParams().put("dataName", dynamicObject.getString("name"));
205
+ ```
206
+
207
+ ---
208
+
209
+ ### 9. 日志框架使用
210
+ **检查点**:
211
+ - 是否使用了 `kd.bos.logging.Log` 而非其他日志框架?
212
+ - 是否使用了 `System.out.println`?
213
+ - debug 日志是否用 `isDebugEnabled()` 包裹?
214
+ - 是否用 `SerializationUtils.toJsonString()` 打印大对象?(极耗 CPU)
215
+ - error 日志是否传入了异常对象?
216
+
217
+ **风险**: 日志不规范导致排查困难,性能问题
218
+
219
+ **修正方案**:
220
+ ```java
221
+ // ✅ 正确用法
222
+ private static final Log logger = LogFactory.getLog(MyClass.class);
223
+
224
+ if (logger.isDebugEnabled()) {
225
+ logger.debug("详细信息: {}", detail);
226
+ }
227
+ logger.error("操作失败", e); // 必须传入异常对象
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 🟡 P2 级问题
233
+
234
+ ### 10. queryDataSet algoKey 无意义
235
+ **检查点**:
236
+ - `QueryServiceHelper.queryDataSet()` 的第一个参数 algoKey 是否使用了有意义的标识?
237
+
238
+ **修正方案**:
239
+ ```java
240
+ // ❌ 错误写法
241
+ QueryServiceHelper.queryDataSet("q", "entity", "id", null);
242
+
243
+ // ✅ 正确写法
244
+ QueryServiceHelper.queryDataSet("scmc.ccm.queryMaterial", "bd_material", "id,name", filters);
245
+ ```
246
+
247
+ ---
248
+
249
+ ### 11. 操作自定义参数命名
250
+ **检查点**:
251
+ - `OperateOption.setVariableValue()` 的 key 是否使用了业务域前缀?
252
+
253
+ **修正方案**:
254
+ ```java
255
+ // ❌ 错误写法
256
+ option.setVariableValue("flag", "true"); // 可能冲突
257
+
258
+ // ✅ 正确写法
259
+ option.setVariableValue("scmc_ccm_skipValidation", "true");
260
+ ```
261
+
262
+ ---
263
+
264
+ ### 12. 异常类型使用规范
265
+ **检查点**:
266
+ - 是否统一使用 `KDException` / `KDBizException`?
267
+ - 有原始异常时是否作为 cause 传入?
268
+ - UI 层捕获异常后是否给出了业务语义提示?
269
+
270
+ **修正方案**:
271
+ ```java
272
+ // ❌ 错误写法 - 原始异常丢失
273
+ try {
274
+ doSomething();
275
+ } catch (Exception e) {
276
+ throw new KDException(new ErrorCode("xxx", "操作失败")); // 丢失原始异常
277
+ }
278
+
279
+ // ✅ 正确写法
280
+ try {
281
+ doSomething();
282
+ } catch (Exception e) {
283
+ throw new KDException(new ErrorCode("xxx", e.getMessage()), e);
284
+ }
285
+ ```
@@ -0,0 +1,261 @@
1
+ # 数据访问与事务检查表
2
+
3
+ ## 🔴 P0 级问题
4
+
5
+ ### 1. 事务内 DataSet 在事务外使用
6
+ **检查点**:
7
+ - 在 `TX.required` / `TX.requiresNew` 事务块内查询的 DataSet,是否在事务块外部使用?
8
+
9
+ **风险**: 事务结束后 DataSet 关联的数据库连接已释放,继续使用会抛异常或返回错误数据
10
+
11
+ **修正方案**:
12
+ ```java
13
+ // ❌ 错误写法 - 事务内查询的 DataSet 在事务外使用
14
+ DataSet ds;
15
+ try (TXHandle h = TX.required("query")) {
16
+ try {
17
+ ds = QueryServiceHelper.queryDataSet("q", "entity", "id,name", null);
18
+ } catch (Throwable e) {
19
+ h.markRollback();
20
+ throw e;
21
+ }
22
+ }
23
+ // ds 在事务外使用,连接已释放!
24
+ for (Row row : ds) { ... }
25
+
26
+ // ✅ 正确写法 - 在事务内完成数据处理
27
+ List<String> names = new ArrayList<>();
28
+ try (TXHandle h = TX.required("query")) {
29
+ try {
30
+ try (DataSet ds = QueryServiceHelper.queryDataSet("q", "entity", "id,name", null)) {
31
+ for (Row row : ds) {
32
+ names.add(row.getString("name"));
33
+ }
34
+ }
35
+ } catch (Throwable e) {
36
+ h.markRollback();
37
+ throw e;
38
+ }
39
+ }
40
+ ```
41
+
42
+ ---
43
+
44
+ ### 2. 跨库写操作
45
+ **检查点**:
46
+ - 一个事务内是否写了两个或以上的物理库?
47
+ - 是否在同一事务中操作了不同微服务节点的数据?
48
+
49
+ **风险**: 平台禁止跨库写,DB 检测到会直接抛异常;跨节点事务同样被禁止
50
+
51
+ **修正方案**:
52
+ ```java
53
+ // ❌ 错误写法 - 一个事务内写两个库
54
+ try (TXHandle h = TX.required("crossDb")) {
55
+ try {
56
+ SaveServiceHelper.save(entityA); // 库A
57
+ SaveServiceHelper.save(entityB); // 库B - 跨库写!
58
+ } catch (Throwable e) {
59
+ h.markRollback();
60
+ throw e;
61
+ }
62
+ }
63
+
64
+ // ✅ 正确写法 - 使用 MQ 异步解耦
65
+ try (TXHandle h = TX.required("saveA")) {
66
+ try {
67
+ SaveServiceHelper.save(entityA);
68
+ // 发送 MQ 消息,由消费者在另一个事务中写库B
69
+ publisher.publish(message);
70
+ } catch (Throwable e) {
71
+ h.markRollback();
72
+ throw e;
73
+ }
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ### 3. 事务中未 markRollback
80
+ **检查点**:
81
+ - `TX.required` / `TX.requiresNew` 事务块的 catch 中是否调用了 `h.markRollback()`?
82
+ - TXHandle 是否使用了 try-with-resources?
83
+
84
+ **风险**: 业务异常未标记回滚,事务可能被错误提交,导致数据不一致
85
+
86
+ **修正方案**:
87
+ ```java
88
+ // ❌ 错误写法 - 未标记回滚
89
+ try (TXHandle h = TX.required("save")) {
90
+ try {
91
+ doSomething();
92
+ } catch (Exception e) {
93
+ logger.error("失败", e);
94
+ // 缺少 h.markRollback(),事务可能被提交!
95
+ }
96
+ }
97
+
98
+ // ✅ 正确写法
99
+ try (TXHandle h = TX.required("save")) {
100
+ try {
101
+ doSomething();
102
+ } catch (Throwable e) {
103
+ h.markRollback();
104
+ throw e;
105
+ }
106
+ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## 🟠 P1 级问题
112
+
113
+ ### 4. QFilter 条件缺失导致全表扫描
114
+ **检查点**:
115
+ - `QueryServiceHelper.queryDataSet()` / `BusinessDataServiceHelper.load()` 的 filters 参数是否为 null 或空数组?
116
+ - 查询是否缺少组织、日期等基本过滤条件?
117
+
118
+ **风险**: 无过滤条件查询导致全表扫描,大数据量时严重影响性能
119
+
120
+ **修正方案**:
121
+ ```java
122
+ // ❌ 错误写法 - 无过滤条件
123
+ DynamicObject[] all = BusinessDataServiceHelper.load("entity", "id,name", null);
124
+
125
+ // ✅ 正确写法 - 添加过滤条件
126
+ QFilter orgFilter = new QFilter("org", QCP.equals, orgId);
127
+ QFilter statusFilter = new QFilter("billstatus", QCP.equals, "C");
128
+ DynamicObject[] data = BusinessDataServiceHelper.load(
129
+ "entity", "id,name",
130
+ new QFilter[]{orgFilter.and(statusFilter)});
131
+ ```
132
+
133
+ ---
134
+
135
+ ### 5. QFilter 字段层级过深
136
+ **检查点**:
137
+ - QFilter 或 selectFields 中的字段层级是否超过 4 层(如 `a.b.c.d.e`)?
138
+
139
+ **风险**: 多层级关联查询会产生笛卡尔积,数据量指数级增长,导致 OOM 或超时
140
+
141
+ **修正方案**:
142
+ ```java
143
+ // ❌ 错误写法 - 字段层级过深
144
+ QFilter filter = new QFilter("entry.material.group.parent.name", QCP.equals, "xxx");
145
+
146
+ // ✅ 正确写法 - 拆分为多次查询
147
+ // 第一步:查询物料分组
148
+ DynamicObject group = QueryServiceHelper.queryOne(
149
+ "bd_materialgroup", "id", new QFilter[]{new QFilter("parent.name", QCP.equals, "xxx")});
150
+ // 第二步:用分组ID查询
151
+ QFilter filter = new QFilter("entry.material.group", QCP.equals, group.getLong("id"));
152
+ ```
153
+
154
+ ---
155
+
156
+ ### 6. 数据访问方法选择不当
157
+ **检查点**:
158
+ - 只需判断数据是否存在时,是否使用了 `loadSingle` 或 `load`?
159
+ - 只需读取少量字段时,是否使用了 `loadSingle`(加载完整数据包)?
160
+ - 需要层级结构数据时,是否使用了 `queryOne`(返回拉平结构)?
161
+
162
+ **方法选择指南**:
163
+ | 场景 | 推荐方法 | 不推荐 |
164
+ |------|---------|--------|
165
+ | 判断是否存在 | `QueryServiceHelper.queryOne` 查 id | `loadSingle` |
166
+ | 读取少量字段 | `QueryServiceHelper.queryOne/queryDataSet` | `loadSingle` |
167
+ | 读取完整数据包(含层级) | `BusinessDataServiceHelper.loadSingle` | `queryOne` |
168
+ | 大数据量流式处理 | `QueryServiceHelper.queryDataSet` | `load` |
169
+ | 批量加载 | `BusinessDataServiceHelper.load` | 循环 `loadSingle` |
170
+ | 利用缓存 | `BusinessDataServiceHelper.loadSingleFromCache` | `loadSingle` |
171
+
172
+ ---
173
+
174
+ ### 7. 大事务风险
175
+ **检查点**:
176
+ - 事务块内是否包含了大量数据操作或耗时逻辑?
177
+ - 事务块内是否调用了外部 HTTP 接口或微服务?
178
+
179
+ **风险**: 大事务执行效率低,可能造成长时间锁等待、锁冲突,进而发生阻塞或死锁
180
+
181
+ **修正方案**:
182
+ ```java
183
+ // ❌ 错误写法 - 大事务包含外部调用
184
+ try (TXHandle h = TX.required("bigTx")) {
185
+ try {
186
+ SaveServiceHelper.save(entities);
187
+ httpClient.callExternalApi(); // 外部调用在事务内!
188
+ updateRelatedData();
189
+ } catch (Throwable e) {
190
+ h.markRollback();
191
+ throw e;
192
+ }
193
+ }
194
+
195
+ // ✅ 正确写法 - 拆分事务,外部调用放在事务外
196
+ try (TXHandle h = TX.required("saveTx")) {
197
+ try {
198
+ SaveServiceHelper.save(entities);
199
+ } catch (Throwable e) {
200
+ h.markRollback();
201
+ throw e;
202
+ }
203
+ }
204
+ // 事务外调用外部接口
205
+ httpClient.callExternalApi();
206
+ ```
207
+
208
+ ---
209
+
210
+ ### 8. QFilter 操作符使用错误
211
+ **检查点**:
212
+ - 多值匹配是否使用了 `QCP.equals` 而非 `QCP.in`?
213
+ - 模糊查询是否使用了 `QCP.equals` 而非 `QCP.like`?
214
+ - 空值判断是否使用了 `QCP.equals` null 而非 `QCP.is_null`?
215
+
216
+ **修正方案**:
217
+ ```java
218
+ // ❌ 错误写法
219
+ new QFilter("status", QCP.equals, Arrays.asList("A", "B")); // 应用 in
220
+ new QFilter("name", QCP.equals, null); // 应用 is_null
221
+
222
+ // ✅ 正确写法
223
+ new QFilter("status", QCP.in, new String[]{"A", "B"});
224
+ new QFilter("name", QCP.is_null, null);
225
+ new QFilter("name", QCP.like, "%关键字%");
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 🟡 P2 级问题
231
+
232
+ ### 9. queryDataSet 的 algoKey 无意义
233
+ **检查点**:
234
+ - `QueryServiceHelper.queryDataSet()` 的第一个参数 algoKey 是否使用了有意义的标识?
235
+
236
+ **风险**: 无意义的 algoKey 不利于后续性能分析和问题定位
237
+
238
+ **修正方案**:
239
+ ```java
240
+ // ❌ 错误写法
241
+ QueryServiceHelper.queryDataSet("q", "entity", "id", null);
242
+ QueryServiceHelper.queryDataSet("test", "entity", "id", null);
243
+
244
+ // ✅ 正确写法 - 使用有意义的标识
245
+ QueryServiceHelper.queryDataSet("scmc.ccm.queryMaterial", "bd_material", "id,name", filters);
246
+ ```
247
+
248
+ ---
249
+
250
+ ### 10. 事务传播类型选择不当
251
+ **检查点**:
252
+ - 需要独立事务的场景(如写日志)是否使用了 `TX.required`(会加入外层事务)?
253
+ - 只读查询是否使用了 `TX.required`(不必要的事务开销)?
254
+
255
+ **事务传播选择指南**:
256
+ | 场景 | 推荐类型 |
257
+ |------|---------|
258
+ | 业务数据保存 | `TX.required` |
259
+ | 独立写日志/审计 | `TX.requiresNew` |
260
+ | 只读查询 | `TX.notSupported` 或不开事务 |
261
+ | 子操作允许部分失败 | `TX.nested` |