@shundoo-ai/dsh-cosmic 1.0.21 → 1.0.22

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 (218) hide show
  1. package/package.json +1 -1
  2. package/skills/cosmic-build/LOCAL-PATCHES.md +43 -14
  3. package/skills/cosmic-build/SKILL.md +24 -9
  4. package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +26 -17
  5. package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +96 -2
  6. package/skills/cosmic-build/knowledge/cosmic/arch/security/security_standard.md +4 -4
  7. package/skills/cosmic-build/knowledge/cosmic/platform/allimport.md +2 -1
  8. package/skills/cosmic-build/knowledge/cosmic/platform/core/dynamic-object-collection.md +6 -4
  9. package/skills/cosmic-build/knowledge/cosmic/platform/core/model.md +9 -9
  10. package/skills/cosmic-build/knowledge/cosmic/platform/core/view.md +5 -5
  11. package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +8 -4
  12. package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +5 -3
  13. package/skills/cosmic-build/knowledge/cosmic/platform/print-plugin-guide.md +1 -0
  14. package/skills/cosmic-build/knowledge/cosmic/platform/report-plugin.md +269 -57
  15. package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +130 -23
  16. package/skills/cosmic-build/knowledge/cosmic/platform/reporttreedata-plugin.md +48 -28
  17. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/_index.md +12 -3
  18. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/attachment-name-process.md +17 -13
  19. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/dynamic-update-field.md +4 -4
  20. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/filter-grid/filter-grid-set-value.md +1 -1
  21. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-basedatafield.md +2 -3
  22. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-container-init.md +0 -1
  23. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-popup.md +0 -1
  24. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-value-parse.md +5 -6
  25. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/list-show-form.md +1 -1
  26. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/query-field-dynamic.md +0 -7
  27. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/business-data/delete-service.md +24 -29
  28. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-batch.md +4 -0
  29. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-direct-access.md +4 -0
  30. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/entity-object-access.md +8 -3
  31. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/qfilter-compose.md +6 -5
  32. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/after-bind-data-set-visible.md +5 -1
  33. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/click-return-data.md +2 -2
  34. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/closed-call-back-set-value.md +2 -2
  35. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/register-listener.md +1 -1
  36. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/set-filter-tab-org.md +3 -0
  37. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dispatch-service/microservice-dev.md +18 -11
  38. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dist-lock/dist-lock-basic.md +3 -6
  39. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/mq/mq-subscribe.md +5 -1
  40. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/async-operation.md +10 -6
  41. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/big-task-async.md +4 -2
  42. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/schedule-task.md +9 -7
  43. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-interactive.md +33 -34
  44. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-plugin-events.md +30 -22
  45. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-async-query.md +133 -0
  46. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-batch-query.md +26 -22
  47. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-chart.md +112 -0
  48. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-dataset-assembly.md +200 -0
  49. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-head-filter.md +177 -0
  50. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-hyperlink-drill.md +216 -0
  51. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-list-data-query.md +12 -12
  52. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-merge-column.md +44 -6
  53. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-print-data.md +163 -0
  54. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-row-data-toolbar.md +188 -0
  55. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-subtotal-total.md +139 -0
  56. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-data-query.md +108 -12
  57. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-list.md +181 -0
  58. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/system-service/report-plugin-interface.md +3 -0
  59. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-basedata-cascade-confirm.md +14 -11
  60. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-before-item-validate.md +1 -1
  61. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-build-filter.md +1 -1
  62. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-multi-level-filter.md +11 -11
  63. package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-refresh-node.md +22 -15
  64. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +2 -2
  65. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-entity-model.md +3 -4
  66. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-exception.md +9 -5
  67. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-orm-access.md +4 -0
  68. package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-request-context.md +7 -3
  69. package/skills/cosmic-build/knowledge/cosmic/platform/standards.md +28 -3
  70. package/skills/cosmic-build/references/compile-guide.md +36 -1
  71. package/skills/cosmic-build/references/dcs-code-rules.md +180 -0
  72. package/skills/cosmic-build/references/delivery.md +16 -2
  73. package/skills/cosmic-build/references/execution-contract.md +15 -3
  74. package/skills/cosmic-build/references/java-plugin-delivery.md +21 -11
  75. package/skills/cosmic-build/references/plugin-handoff-input.md +82 -24
  76. package/skills/cosmic-build/references/plugin-runtime-routing.md +23 -6
  77. package/skills/cosmic-build/references/report-filter-contract.md +53 -15
  78. package/skills/cosmic-build/references/sdk-inspection.md +4 -1
  79. package/skills/cosmic-build/references/type-registry.json +26 -17
  80. package/skills/cosmic-build/schemas/data-model-authoring.schema.json +1 -1
  81. package/skills/cosmic-build/scripts/_http_client.py +3 -0
  82. package/skills/cosmic-build/scripts/compile_plugin_source.py +251 -42
  83. package/skills/cosmic-build/scripts/configure_list.py +112 -0
  84. package/skills/cosmic-build/scripts/dcs-rule-catalog.json +799 -0
  85. package/skills/cosmic-build/scripts/dcs_code_gate.py +1976 -0
  86. package/skills/cosmic-build/scripts/execution_binding.py +25 -0
  87. package/skills/cosmic-build/scripts/platform_api_contract.py +352 -7
  88. package/skills/cosmic-build/scripts/plugin_source_gate.py +9 -1
  89. package/skills/cosmic-build/scripts/plugin_target_sdk.py +12 -8
  90. package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +488 -88
  91. package/skills/cosmic-build/scripts/query_plugin_handoff.py +207 -20
  92. package/skills/cosmic-build/scripts/register_plugins.py +27 -10
  93. package/skills/cosmic-build/scripts/render_output_cards.py +57 -20
  94. package/skills/cosmic-build/scripts/resolve_output_path.py +60 -26
  95. package/skills/cosmic-build/scripts/run_java_tests.py +162 -0
  96. package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +28 -0
  97. package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +1 -22
  98. package/skills/cosmic-build/scripts/test/fixtures/list_column_property_declarations.json +887 -0
  99. package/skills/cosmic-build/scripts/test/fixtures/operation-entry-field-prepare.java +78 -0
  100. package/skills/cosmic-build/scripts/test/test_add_field_required_contract.py +12 -0
  101. package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +23 -2
  102. package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +287 -4
  103. package/skills/cosmic-build/scripts/test/test_configure_list_delivery.py +132 -0
  104. package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +58 -1
  105. package/skills/cosmic-build/scripts/test/test_data_model_contract.py +19 -0
  106. package/skills/cosmic-build/scripts/test/test_dcs_code_gate.py +901 -0
  107. package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +1 -1
  108. package/skills/cosmic-build/scripts/test/test_direct_cli_architecture.py +2 -0
  109. package/skills/cosmic-build/scripts/test/test_http_client.py +6 -0
  110. package/skills/cosmic-build/scripts/test/test_java_toolchain_feedback.py +206 -0
  111. package/skills/cosmic-build/scripts/test/test_kd_api.py +21 -0
  112. package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +184 -0
  113. package/skills/cosmic-build/scripts/test/test_mcp_cli.py +139 -2
  114. package/skills/cosmic-build/scripts/test/test_menu_creation_closure.py +16 -0
  115. package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +55 -1
  116. package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +1 -1
  117. package/skills/cosmic-build/scripts/test/test_operation_field_preparation.py +84 -0
  118. package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +322 -1
  119. package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +951 -4
  120. package/skills/cosmic-build/scripts/test/test_plugin_source_gate.py +30 -2
  121. package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +21 -0
  122. package/skills/cosmic-build/scripts/test/test_property_reroute.py +165 -0
  123. package/skills/cosmic-build/scripts/test/test_property_schema_first.py +35 -0
  124. package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +221 -0
  125. package/skills/cosmic-build/scripts/test/test_register_plugins.py +76 -4
  126. package/skills/cosmic-build/scripts/test/test_render_output_cards.py +75 -3
  127. package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -5
  128. package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +103 -11
  129. package/skills/cosmic-build/scripts/test/test_report_plugin_source_gate.py +46 -16
  130. package/skills/cosmic-build/scripts/test/test_report_properties.py +74 -15
  131. package/skills/cosmic-build/scripts/test/test_report_query_data_source.py +3 -1
  132. package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +1 -2
  133. package/skills/cosmic-build/scripts/test/test_test_environment.py +76 -1
  134. package/skills/cosmic-build/scripts/test_environment.py +67 -1
  135. package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +52 -10
  136. package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +16 -3
  137. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +59 -26
  138. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +1 -1
  139. package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +75 -18
  140. package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_auto.py +39 -0
  141. package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_client.py +97 -10
  142. package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +10 -12
  143. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +3 -1
  144. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +38 -29
  145. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +400 -233
  146. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +87 -45
  147. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +42 -15
  148. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +135 -5
  149. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +1 -1
  150. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +1 -1
  151. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +17 -11
  152. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_reroute.py +15 -5
  153. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +1429 -238
  154. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/validators.py +56 -28
  155. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +380 -134
  156. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +1 -1
  157. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_export.py +12 -11
  158. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_verifier.py +42 -0
  159. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_add_field_placement_closure.py +8 -8
  160. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_configuration_readback.py +94 -0
  161. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +47 -1
  162. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_metadata_unchanged_fail_closed.py +87 -0
  163. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_dym_evidence.py +23 -23
  164. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_entity_integrity.py +279 -4
  165. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_field_guard.py +1 -1
  166. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +509 -32
  167. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +178 -1
  168. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_recreate_plan.py +125 -10
  169. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_serve_contract.py +208 -0
  170. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +259 -50
  171. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_inventory_perf.py +29 -0
  172. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +20 -0
  173. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +18 -0
  174. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +35 -0
  175. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_identity_guard.py +25 -0
  176. package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_time_range_rule.py +98 -0
  177. package/skills/cosmic-build/skills/cosmic-meta-knowledge/domain-model/report-model.md +20 -9
  178. package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/report-modeling-guide.md +55 -25
  179. package/skills/cosmic-build/skills/cosmic-meta-knowledge/property-guides/report-column-properties.md +15 -39
  180. package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +19 -17
  181. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +82 -38
  182. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-batch.md +64 -19
  183. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-plugin.md +32 -20
  184. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-tree.md +78 -31
  185. package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/report-artifact-schema.json +2 -1
  186. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-companion-fields.md +3 -0
  187. package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-list-configuration.md +2 -0
  188. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +3 -1
  189. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +27 -4
  190. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +99 -44
  191. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_examples.py +31 -4
  192. package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_validator.py +129 -29
  193. package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +6 -2
  194. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
  195. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +1 -1
  196. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +104 -25
  197. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +9 -0
  198. package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +2 -2
  199. package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +39 -12
  200. package/skills/cosmic-build/skills/mcp-server/SKILL.md +39 -24
  201. package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +20 -6
  202. package/skills/cosmic-dev-best-practices/SKILL.md +1 -1
  203. package/skills/cosmic-dev-best-practices/references/README.md +2 -2
  204. package/skills/cosmic-dev-best-practices/references/basedata-dev-convention.md +2 -2
  205. package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +4 -4
  206. package/skills/cosmic-dev-best-practices/references/design-document-convention.md +2 -2
  207. package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +4 -4
  208. package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +13 -13
  209. package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +1 -1
  210. package/skills/cosmic-dev-best-practices/references/elements/README.md +1 -1
  211. package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +1 -1
  212. package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +109 -13
  213. package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +1 -1
  214. package/skills/erp-analysis/references/delivery-contract.md +2 -1
  215. package/skills/erp-analysis/templates/AGENTS.template.md +3 -1
  216. package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +0 -169
  217. package/skills/cosmic-build/assets/platform-report-filters/platform.patch +0 -98
  218. package/skills/cosmic-build/scripts/apply_report_filter_extension.py +0 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shundoo-ai/dsh-cosmic",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "苍穹助手:金蝶云苍穹ERP的开发与数据分析,涵盖表单元数据建模、插件开发与热部署、数据可视化报告。",
5
5
  "keywords": [
6
6
  "dsh",
@@ -9,27 +9,25 @@
9
9
 
10
10
  | 项 | 值 |
11
11
  |---|---|
12
- | 本次对齐的上游版本 | **0.0.326**(`builtin-skills/.builtin-version`),文件日期 2026-10-19(金蝶灵基 app **1.8.0**,build 2610172146,2026-10-17 安装) |
13
- | 上一次对齐 | **0.0.299**(2026-09-29) |
12
+ | 本次对齐的上游版本 | **0.0.343**(`builtin-skills/.builtin-version`),文件日期 2026-11-06(金蝶灵基 app **1.9.1**,build 2611032038,2026-11-03 安装;技能 2026-11-06 09:54 解压) |
13
+ | 上一次对齐 | **0.0.326**(2026-10-19);其间 0.0.338 曾调研后跳过 |
14
14
  | 更早的参照基线 | `~/.lingeebuild/config/builtin-skills/app-build`(**0.0.277**,2026-08-28,已过期) |
15
15
  | 上游解压位置(已变) | **`~/.lingeebuild/profiles/v1/<hash>/config/builtin-skills/app-build`** —— 灵基 1.8.0 起 skill 按 profile 隔离解压;旧的全局 `~/.lingeebuild/config/builtin-skills` 不再更新 |
16
16
  | 上游目录布局 | `app-build/`(英文 canonical)+ `app-build/.locales/zh/`(中文覆盖层) |
17
17
  | 本 preset 布局 | 单树:`skills/cosmic-build/`(= 上游 zh 覆盖层拍平,无 `.locales/`) |
18
18
 
19
- ### 0.1 ⏸ 待同步:上游 0.0.338(**已调研完毕,暂缓执行**)
19
+ ### 0.1 ✅ 已同步:上游 **0.0.343**(2026-11-06)
20
20
 
21
- > 2026-10-30 用户决定:「过几天,等灵基更新稳定了再同步」。以下为已完成的前置调研,**下次直接照此执行,无需重新考古**。
21
+ > 2026-10-30 曾暂缓;2026-11-06 用户确认同步并当日完成。**执行记录见 §5.2**。
22
+ > 版本线:0.0.277(8/28)→ **0.0.299** ✅ → **0.0.326** ✅ → 0.0.338(跳过)→ **0.0.343** ✅(当前)
22
23
 
23
- | 项 | 结论 |
24
+ | 项 | 结论(0.0.343 带来的) |
24
25
  |---|---|
25
- | 上游版本 | **0.0.338**(金蝶灵基 app **1.8.4**,build 2610261914,2026-10-26 安装;技能 2026-10-29 解压) |
26
- | 相对 0.0.326 的改动 | **0 个新文件**;**78 个文件改动** = `.md` 33 + `.py` 45(其中 **19 个是测试**,26 个功能文件) |
27
- | 改动分布 | `scripts/` 21 · `cosmic-meta-api` 20 · `cosmic-meta-modifier` 14 · `references/` 10 · 其余零散 |
28
- | 是否含新功能 | **否** —— CHANGELOG 条目与 0.0.326 完全相同(最新仍 2026-10-13);命令数仍 **197**(+我们 7 = 204);**无新端点** |
29
- | 我们的 11 项补丁上游做了吗 | **全部未做**(`#1/#2/#3/#4/#5/#6/#7/#8/#10/#16/#17` 均仍缺;`kd_auth` 仍 `usertype/Mobile`,`kd_env_loader` 仍 `default="ierp"` 且无 password) |
30
- | 补丁重贴风险 | **高** —— 10 个补丁落点文件**全部被上游改过**(`run.py`/`_http_client.py`/`appconfig_load.py`/`kd_env_loader.py`/`kd_auth.py`/`kd_token_cache.py`/`config.py`/`cosmic_api.py`/`field_decorator.py`/`pdm_client.py`) |
31
- | token 改名 | **仍需** —— 新 zh 中 `{APP_BUILD_ROOT}` 74 处 / `{ROOT_DIR}` 61 处混用 |
32
- | 恢复时起点 | 备份基线:当前树 = 0.0.326(git 干净);旧备份 `/tmp/cosmic-build.bak-2026-10-19` 仅供参考,**同步前重新备份** |
26
+ | 相对 0.0.326 的改动 | **17 个新文件** + **211 个文件改动**(`.py` 100 其中 48 测试 / `.md` 102 / `.json` 6 / `.java` 3) |
27
+ | 新功能 | ① 新命令 **`removeReportColumn`**(197 → **198**);② **DCS 代码闸门**(`dcs_code_gate.py` + `references/dcs-code-rules.md` + `dcs-rule-catalog.json`,按 Sonar/SpotBugs/Fortify/CVE-KD 规则交付前自检 Java 插件);③ `run_java_tests.py`;④ `configure_list.py`;⑤ **报表场景知识**(`knowledge/cosmic/platform/scenes/report/` 现共 16 篇) |
28
+ | 实质修复 | 插件交付链路整条 + `cmd_apps/formactions/forms/listui/metaops/plugins/properties/rules` + `report_ops`/`validators`/`property_reroute`/`data_model_emit` |
29
+ | 新增兄弟技能 | `create-image`(技能 16 → 17,**不拷**) |
30
+ | ⚠️ **新机制** | **执行绑定闸门** `scripts/execution_binding.py` —— 同步后必须重新 bootstrap 每个 app-root,见 §5 第 5 步 |
33
31
 
34
32
  上游会把旧的 R/D/E 管线、`capabilities/`、`cosmic-{requirements,design,executor,testing,code-review}`、
35
33
  `nano-coding-impl` 整批删除——那些**不是**本 preset 的本地内容,跟随上游删除即可。
@@ -181,7 +179,7 @@ rsync -a --ignore-existing --exclude '.locales/' "$SRC/." "$DST/"
181
179
  # 4) 重贴 §2 的 17 处补丁(先 config.py,再凭据三件套)
182
180
 
183
181
  # 5) 机械适配
184
- # a. {ROOT_DIR} → {ROOT_DIR}(md 与 py 中花括号 token 形态;
182
+ # a. {APP_BUILD_ROOT} → {ROOT_DIR}(md 与 py 中花括号 token 形态;
185
183
  # 注意 py 里还有同名 Python 变量,不要一起改)
186
184
  # b. md 链接标签里的 .locales/zh/ 前缀去掉
187
185
  # c. 确认根 SKILL.md 里 {ROOT_DIR} 与 {python} 的绑定说明仍在
@@ -246,6 +244,12 @@ python3 -m compileall -q $D/scripts $D/skills && echo "compileall OK"
246
244
  # 4) 端到端只读冒烟(在工作区根执行,走工作区凭证)
247
245
  cd <工作区> && $PY $D/skills/cosmic-meta-api/scripts/cosmic_api.py --stdout queryForms --keyword "过磅"
248
246
  # 期望:退出码 0、stdout 为 JSON、stderr 出现 [auth] OK
247
+
248
+ # 5) ⚠️ 0.0.343 起:重建每个 app-root 的执行绑定(否则带 --app-root 的命令报 SKILL_REVISION_MISMATCH)
249
+ # 根因:context.json 存了技能树修订指纹(SKILL.md + scripts/skills/schemas 下全部 .py/.json 的 SHA256),
250
+ # rsync + 打补丁后指纹必变 ⇒ execution_binding.validate_execution_binding() 拒绝执行。
251
+ $PY $D/scripts/bootstrap_cosmic_context.py --project-root <app-root> --resolve-existing-app
252
+ # 期望:输出含 revision=<新指纹>、退出码 0;随后 exportKSQLByTable / getProperties 等恢复正常
249
253
  ```
250
254
 
251
255
  2026-09-29 同步后的实测结果:17/17 补丁通过、compileall 退出码 0、
@@ -256,6 +260,11 @@ markdown 断链 60 条(与上游 KD zh 完全一致,无新增)。
256
260
  命令 **204** 个(197 上游 + 7 KSQL)、compileall 退出码 0、`queryForms` 冒烟 `[auth] OK`、
257
261
  `exportKSQLByTable` 实调成功(返回 `scriptBase64`)、根 `SKILL.md` 断链 0。
258
262
 
263
+ **2026-11-06(0.0.343)同步结果**:补丁 **15/15 检查点通过**、`_API_PATH` **105** 项、
264
+ 命令 **205** 个(198 上游 + 7 KSQL,含新 `removeReportColumn`)、compileall 退出码 0、
265
+ `queryForms` / `getProperties` / `getFormSchema` / `exportKSQLByTable` 实调成功、`dataQuery` 取到真实数据、
266
+ 重新 bootstrap 后 `SKILL_REVISION_MISMATCH` 消除。
267
+
259
268
  ---
260
269
 
261
270
  ## 5.1 2026-10-19 同步记录(0.0.299 → 0.0.326)
@@ -285,6 +294,26 @@ markdown 断链 60 条(与上游 KD zh 完全一致,无新增)。
285
294
 
286
295
  ---
287
296
 
297
+ ## 5.2 2026-11-06 同步记录(0.0.326 → 0.0.343)
298
+
299
+ | 步骤 | 实际执行 |
300
+ |---|---|
301
+ | 备份 | `cp -a` → `/tmp/cosmic-build.bak-2026-11-06`(65M);补丁母本另存 `/tmp/sync343/head_*.py` |
302
+ | 步骤1 | rsync `zh` `--delete`(exclude 同 §5.1:`erpdb/`、`cosmic-vibe-coding/`、`config.json`、`tenant.json`、entity-download 3 文件、`LOCAL-PATCHES.md`、`sdk/manifests/`)→ 6621 文件 |
303
+ | 步骤2 | rsync canonical `--ignore-existing --exclude .locales/` → **7040** 文件 |
304
+ | 步骤3 | AST 重算滞后/漂移文件 **35** 个并用 canonical 覆盖 → 与 canonical **AST 差异 0** |
305
+ | 步骤4 | 重贴 17 处补丁(**15 个检查点全过**)。锚点均未变;`#2` 按"先替换 3 处 `resp.read()`、**再**插入 `_read_response`"的顺序贴,避开递归自伤 |
306
+ | 步骤5 | a) `{APP_BUILD_ROOT}` → `{ROOT_DIR}`:md **77** + py **6**(89 个 py 变量不动);b) md 的 `.locales/zh/` 清理 **16** 处;c) SKILL.md 补回 token 同义注 |
307
+ | **步骤6(0.0.343 新增,必做)** | **重新 bootstrap**:`bootstrap_cosmic_context.py --project-root <app-root> --resolve-existing-app`。否则 0.0.343 的执行绑定闸门报 `SKILL_REVISION_MISMATCH`(`context.json` 里的技能树指纹因 rsync+打补丁而失效),**所有带 `--app-root` 的命令被拦** |
308
+
309
+ **校验**:命令 **205**(198 上游 + 7 KSQL,含新 `removeReportColumn`)、`_API_PATH` **105**、compileall 0、
310
+ `queryForms` / `getProperties` / `getFormSchema` / `exportKSQLByTable` / `dataQuery` 全部实调通过。
311
+
312
+ **本次带入的上游新能力**:DCS 代码闸门(`dcs_code_gate.py` + `dcs-code-rules.md` + `dcs-rule-catalog.json`)、
313
+ `run_java_tests.py`、`configure_list.py`、报表场景知识(`scenes/report/` 共 16 篇)、插件交付链路整条修复。
314
+
315
+ ---
316
+
288
317
  ## 6. 已知遗留(不影响运行)
289
318
 
290
319
  1. **35 个上游 dev 测试**里有 `.locales/zh/...` 硬路径假设,在单树布局下会失败;
@@ -6,19 +6,22 @@ description: 创建或修改金蝶云苍穹表单、字段、规则、操作、
6
6
  # App Build
7
7
 
8
8
  通过已发布的 CLI 交付用户要求的苍穹应用修改。选择下方最具体的入口,
9
- 只加载当前问题需要的内容,并保留全部明确业务要求。
9
+ 只加载当前问题需要的内容,并保留全部明确业务要求。沿当前语言入口的链接读取,
10
+ 不为确认同一契约再加载另一语言版本。
10
11
 
11
12
  表单及其当前设计保存在苍穹服务端。`appRoot` 是本地应用绑定和导出产物的目录,
12
13
  不是线上表单清单。修改已有表单时,读取下方对应领域入口,将已提供的 `appRoot`
13
14
  和用户使用的表单名称直接传给命令。本地文件或 archive 中没有记录,不证明线上表单不存在。
14
15
 
15
- `{ROOT_DIR}` 是本入口附带的技能包目录(本地补丁:上游 0.0.326 用 `APP_BUILD_ROOT` 这一同名 token,本 preset 统一为 `{ROOT_DIR}`;历史文本中的 `APP_BUILD_ROOT` 与本变量同义)。选定命令的参数尚不明确时,读取其本地契约:
16
+ `{ROOT_DIR}` 是本入口附带的技能包目录(本地补丁:上游 0.0.343 用 `APP_BUILD_ROOT` 这一同名 token,本 preset 统一为 `{ROOT_DIR}`;历史文本中的 `APP_BUILD_ROOT` 与本变量同义)。先按领域入口选命令;没有匹配的已发布命令时,用 `catalog --search <能力>` 查找,不猜命令名。选定命令的参数尚不明确时,读取其本地契约:
16
17
 
17
18
  ```text
18
19
  {python} {ROOT_DIR}/skills/cosmic-meta-api/scripts/cosmic_api.py --stdout describeCommand <已选命令>
19
20
  ```
20
21
 
21
- 返回的 schema 说明命令输入;目标查询由领域命令完成,不通过搜索应用目录完成。
22
+ `describeCommand` 返回 `status: "found"` 时,命令和参数在 `action.command`、`action.arguments`,执行前缀在 `action.execution.argvPrefix`,不是顶层字段。同时遵循 `action.argumentGroups` 的必选/互斥组合、`action.argumentConstraints` 的条件约束和命令可用性;不把一个命令的参数移用到另一个命令。`not_found` 仅表示命令名未发布,不能证明平台不支持该能力。
23
+
24
+ 完整契约读取一次,不用 `head`、`tail` 截断。工具显示截断时用 `--output` 保存,从文件补读缺失内容,保留参数组、条件约束和输入 Schema。stdout/stderr 与失败处理遵循[执行契约](references/execution-contract.md)。目标查询由领域命令完成,不通过搜索应用目录完成。
22
25
 
23
26
  创建入口负责契约支持的初始状态,未覆盖属性或布局交给对应入口。写命令自行解析准确表单目标;
24
27
  只有用户要求发现,或没有表单目标时才进入发现入口。
@@ -28,22 +31,30 @@ description: 创建或修改金蝶云苍穹表单、字段、规则、操作、
28
31
  | 当前请求 | 入口 |
29
32
  |---|---|
30
33
  | 修改下拉菜单项,包括显示名称、说明及顺序 | [skills/cosmic-meta-ui/SKILL.md](skills/cosmic-meta-ui/SKILL.md):`configureDropdownMenu` 根据菜单项或明确按钮定位菜单,保留绑定的操作定义 |
34
+ | 查询指定模板预置字段 | [skills/cosmic-meta-modeling/SKILL.md](skills/cosmic-meta-modeling/SKILL.md):只读模板查询分支 |
31
35
  | 查找表单或确认所属应用 | [references/form-discovery.md](references/form-discovery.md) |
32
36
  | 查询或新建功能分组(BizUnit),包括新建表单明确要求的分组;功能分组不是应用菜单 | [skills/cosmic-meta-modifier/modules/unit/SKILL.md](skills/cosmic-meta-modifier/modules/unit/SKILL.md) |
33
37
  | 将表单移动到其他功能分组(不是应用菜单) | [skills/cosmic-meta-modifier/SKILL.md](skills/cosmic-meta-modifier/SKILL.md) |
34
38
  | 创建表单、实体、基础资料或应用菜单(不是功能分组) | [skills/cosmic-meta-modeling/SKILL.md](skills/cosmic-meta-modeling/SKILL.md) |
35
39
  | 新增/删除字段或分录;继承、复制、扩展或移动已有表单 | [skills/cosmic-meta-modifier/SKILL.md](skills/cosmic-meta-modifier/SKILL.md) |
36
- | 修改字段/控件/分录标识或属性、必填、默认值、拆分表或页签操作 | [skills/cosmic-meta-modifier/modules/property/SKILL.md](skills/cosmic-meta-modifier/modules/property/SKILL.md) |
37
- | 配置计算或条件字段行为 | [skills/cosmic-meta-modifier/modules/rule/SKILL.md](skills/cosmic-meta-modifier/modules/rule/SKILL.md) |
40
+ | 修改字段/控件/分录标识或属性、必填/条件必填、默认值、拆分表或页签操作 | [skills/cosmic-meta-modifier/modules/property/SKILL.md](skills/cosmic-meta-modifier/modules/property/SKILL.md) |
41
+ | 配置计算、联动或表单规则(条件必填走上方属性入口) | [skills/cosmic-meta-modifier/modules/rule/SKILL.md](skills/cosmic-meta-modifier/modules/rule/SKILL.md) |
38
42
  | 配置保存、提交或其他操作校验 | [skills/cosmic-meta-modifier/modules/operation/SKILL.md](skills/cosmic-meta-modifier/modules/operation/SKILL.md) |
39
43
  | 新增可见控件或面板;修改布局、位置或容器外观 | [skills/cosmic-meta-ui/SKILL.md](skills/cosmic-meta-ui/SKILL.md);明确交互的操作先使用操作入口 |
40
- | 配置列表视图的列、搜索字段、过滤条件或排序 | [skills/cosmic-meta-modifier/references/list-filter-modification.md](skills/cosmic-meta-modifier/references/list-filter-modification.md) |
44
+ | 配置列表列、汇总/零值显示、格式、搜索、过滤或排序 | [skills/cosmic-meta-modifier/references/list-filter-modification.md](skills/cosmic-meta-modifier/references/list-filter-modification.md) |
41
45
  | 修改报表元数据、插件注册、元数据脚本或其他已有元数据 | [skills/cosmic-meta-modifier/SKILL.md](skills/cosmic-meta-modifier/SKILL.md) |
46
+ | 根据在线实体生成或同步物理模型、表结构、KSQL 建表或索引脚本 | [skills/cosmic-meta-api/modules/pdm/SKILL.md](skills/cosmic-meta-api/modules/pdm/SKILL.md):使用平台生成结果;实体不可用时说明原因,不推测字段 |
42
47
  | 查看、比较或还原元数据版本 | [skills/cosmic-meta-api/apis/meta_log.md](skills/cosmic-meta-api/apis/meta_log.md) |
43
48
  | 编写或修改 Java 插件源码,包括元数据无法表达的后端行为 | [references/java-plugin-delivery.md](references/java-plugin-delivery.md) |
44
49
  | 将已有操作发布为 OpenAPI | [skills/openapi-gen/SKILL.md](skills/openapi-gen/SKILL.md) |
45
50
  | 注册、查询或管理 MCP 服务(open_mcp_ext) | [skills/mcp-server/SKILL.md](skills/mcp-server/SKILL.md) |
46
51
 
52
+ 用户明确要求 Java 插件或已有源码修改时,可独立进入该入口;只读取行为需要的页面、实体或操作事实。
53
+
54
+ 本地 `.dym` 文件不等于在线实体:PDM 命令不能直接转换此文件。不得推测生成 DDL、
55
+ 索引、隐含字段或类型。需要可访问且版本匹配的平台实体或平台生成的权威物理模型;
56
+ 比较之前先说明版本差异。
57
+
47
58
  自定义苍穹前端页面使用 kd-frontend-development;非苍穹应用使用对应的
48
59
  standalone 或 site 技能。
49
60
 
@@ -62,7 +73,7 @@ standalone 或 site 技能。
62
73
  [references/application-context.md](references/application-context.md)。
63
74
  - CLI 回执、写入验证、未知状态、删除和本地运行状态遵循
64
75
  [references/execution-contract.md](references/execution-contract.md)。
65
- - 只有所选元数据入口无法表达剩余行为时才进入 Java。
76
+ - 用户明确要求 Java,或所选元数据入口无法表达剩余行为时,进入 Java。
66
77
  - 用户要求运行态验证,或诊断/修复运行报错时调用外部运行工具;优先使用可用的 `agent_browser`。
67
78
  - 只询问会实质改变业务结果的决定。
68
79
 
@@ -70,9 +81,11 @@ standalone 或 site 技能。
70
81
 
71
82
  先按选定入口实施。prepare 给出的完成输入路径是实施后要创建的文件,开始时不存在是正常状态。`TEST_ENVIRONMENT_HANDOFF` 由写入后的原生收口器生成,不在实施前到其他任务或工作树中寻找。
72
83
 
73
- 消费已绑定的需求/前阶段产物一次,按“结构、静态属性、规则、操作校验、无法用元数据表达的行为”整理尚未完成的效果。选择每个效果的最小已发布 writer,输入完整时直接执行;仅加载命中的专题,独立读取可并行。同一表单的规则用已发布批量命令,属性批量保持其原生契约,避免逐项重新发现身份。
84
+ 消费已绑定的需求/前阶段产物一次,保留每项未完成要求。新建时先加载建模及结构专题,结构验证后再加载剩余属性、规则和操作细节。只有后续要求会决定初始结构、引用关系、初始必填或创建参数时,才提前处理;延后加载不等于延后必要业务决定或遗漏要求。
74
85
 
75
- 复用 writer 返回的准确身份和验证回执;成功写入后不再查询无关候选、不重读同一说明、不为交付重做验证。参数错误按返回的准确形状修复;类型/能力边界错误直接切换该行为所属路线,避免在多个命令间摇摆。回执只证明它实际检查的内容:逐行必填不等于最少行数,设计态规则保存不等于浏览器运行通过。有运行验证请求时使用可用的 `agent_browser`;一次打开表单与检查默认值属于该行为的冒烟验证,不能冒充范围外测试阶段。
86
+ 为剩余事项选择最小已发布 writer。输入与契约已知的操作可在同一模型回合安排,独立读取可并行;同一表单优先使用原生属性/规则批量命令。共享表单的写入保持串行,并逐条检查回执;依赖前序身份或结果的命令等待其验证完成。失败边界遵循执行契约。
87
+
88
+ 复用 writer 返回的准确身份和验证回执;成功写入后不再查询无关候选、不重读同一说明、不为交付重做验证。参数错误按返回的准确形状修复。确定性的准备失败先解决共同原因,再继续该批次;不为通过校验改写已选应用绑定。类型/能力边界错误直接切换该行为所属路线,避免在多个命令间摇摆。回执只证明它实际检查的内容:逐行必填不等于最少行数,设计态规则保存不等于浏览器运行通过。有运行验证请求时使用可用的 `agent_browser`;一次打开表单与检查默认值属于该行为的冒烟验证,不能冒充范围外测试阶段。
76
89
 
77
90
  ## 完成条件
78
91
 
@@ -94,3 +107,5 @@ standalone 或 site 技能。
94
107
  所有明确要求都有验证证据或明确未完成边界,且不存在写后未知状态时任务完成。
95
108
  已验证无变化时可以直接说明现状,不重复写入。仍可执行的实现工作不属于“未完成边界”;
96
109
  必须继续完成,只有缺少具体业务决定或能力确实不支持时才能停下。
110
+
111
+ 具名 Python 辅助脚本使用对应专题中已提供的命令;参数不明确时查看该脚本的 `--help`。辅助脚本不是 `cosmic_api.py` 的子命令。
@@ -1,35 +1,44 @@
1
1
  import kd.bos.algo.DataSet;
2
- import kd.bos.orm.ORM;
3
2
  import kd.bos.orm.query.QFilter;
3
+ import kd.bos.servicehelper.QueryServiceHelper;
4
4
 
5
- /** Inputs are filtered at their owning ORM queries; headers contain exactly one row per id. */
5
+ /** Inputs are filtered at their owning queries; headers contain exactly one row per id. */
6
6
  public final class CosmicReportAggregation {
7
+ private static final String MAIN_ID = "main_id";
8
+ private static final String ID = "id";
9
+ private static final String AMOUNT = "amount";
10
+ private static final String ADD_AMOUNT = "add_amount";
11
+ private static final String DEDUCT_AMOUNT = "deduct_amount";
12
+ private static final String BASE_AMOUNT = "base_amount";
13
+ private static final String SUPPLIER = "supplier";
14
+ private static final String BILL_DATE = "bill_date";
15
+
7
16
  private CosmicReportAggregation() { }
8
17
 
9
18
  /** Three form-root queries, with identical permission/business/user scope pushed into each. */
10
- public static DataSet query(ORM orm, String algo, String entity, String headerSelect,
19
+ public static DataSet query(String algo, String entity, String headerSelect,
11
20
  String additionSelect, String deductionSelect, QFilter[] filters) {
12
- return aggregate(orm.queryDataSet(algo, entity, headerSelect, filters, null),
13
- orm.queryDataSet(algo, entity, additionSelect, filters, null),
14
- orm.queryDataSet(algo, entity, deductionSelect, filters, null));
21
+ return aggregate(QueryServiceHelper.queryDataSet(algo, entity, headerSelect, filters, null),
22
+ QueryServiceHelper.queryDataSet(algo, entity, additionSelect, filters, null),
23
+ QueryServiceHelper.queryDataSet(algo, entity, deductionSelect, filters, null));
15
24
  }
16
25
 
17
26
  public static DataSet aggregate(DataSet headers, DataSet additions, DataSet deductions) {
18
- DataSet added = additions.groupBy(new String[]{"main_id"}).sum("amount", "add_amount").finish();
19
- DataSet deducted = deductions.groupBy(new String[]{"main_id"}).sum("amount", "deduct_amount").finish();
20
- DataSet joined = headers.leftJoin(added).on("id", "main_id")
21
- .select(new String[]{"id", "supplier", "bill_date", "base_amount"}, new String[]{"add_amount"}).finish()
22
- .leftJoin(deducted).on("id", "main_id")
23
- .select(new String[]{"id", "supplier", "bill_date", "base_amount", "add_amount"}, new String[]{"deduct_amount"}).finish()
27
+ DataSet added = additions.groupBy(new String[]{MAIN_ID}).sum(AMOUNT, ADD_AMOUNT).finish();
28
+ DataSet deducted = deductions.groupBy(new String[]{MAIN_ID}).sum(AMOUNT, DEDUCT_AMOUNT).finish();
29
+ DataSet joined = headers.leftJoin(added).on(ID, MAIN_ID)
30
+ .select(new String[]{ID, SUPPLIER, BILL_DATE, BASE_AMOUNT}, new String[]{ADD_AMOUNT}).finish()
31
+ .leftJoin(deducted).on(ID, MAIN_ID)
32
+ .select(new String[]{ID, SUPPLIER, BILL_DATE, BASE_AMOUNT, ADD_AMOUNT}, new String[]{DEDUCT_AMOUNT}).finish()
24
33
  .select("id,supplier,bill_date,base_amount,case when add_amount is null then 0 else add_amount end as add_amount,case when deduct_amount is null then 0 else deduct_amount end as deduct_amount");
25
- return joined.groupBy(new String[]{"supplier"})
26
- .sum("base_amount", "base_amount").sum("add_amount", "add_amount").sum("deduct_amount", "deduct_amount")
27
- .min("bill_date", "first_date").max("bill_date", "last_date")
28
- .countDistinct(new String[]{"id"}, "bill_count").finish();
34
+ return joined.groupBy(new String[]{SUPPLIER})
35
+ .sum(BASE_AMOUNT, BASE_AMOUNT).sum(ADD_AMOUNT, ADD_AMOUNT).sum(DEDUCT_AMOUNT, DEDUCT_AMOUNT)
36
+ .min(BILL_DATE, "first_date").max(BILL_DATE, "last_date")
37
+ .countDistinct(new String[]{ID}, "bill_count").finish();
29
38
  }
30
39
 
31
40
  /** Direct aggregates avoid materializing/sorting/unioning a DataSet for each supplier. */
32
41
  public static DataSet dateBounds(DataSet headers) {
33
- return headers.groupBy(new String[]{"supplier"}).min("bill_date", "first_date").max("bill_date", "last_date").finish();
42
+ return headers.groupBy(new String[]{SUPPLIER}).min(BILL_DATE, "first_date").max(BILL_DATE, "last_date").finish();
34
43
  }
35
44
  }
@@ -1,11 +1,13 @@
1
1
  import kd.bos.dataentity.entity.DynamicObject;
2
2
  import kd.bos.dataentity.entity.DynamicObjectCollection;
3
+ import kd.bos.entity.property.MulBasedataProp;
3
4
  import kd.bos.entity.report.FilterInfo;
4
5
  import kd.bos.entity.report.FilterItemInfo;
5
6
  import kd.bos.orm.query.QFilter;
6
7
  import kd.bos.orm.query.QCP;
7
8
 
8
9
  import java.util.ArrayList;
10
+ import java.util.Collection;
9
11
  import java.util.Date;
10
12
  import java.util.LinkedHashSet;
11
13
  import java.util.List;
@@ -64,11 +66,103 @@ public final class CosmicReportFilters {
64
66
  /** Call only after verifying code uniqueness and retaining organization/permission filters. */
65
67
  public static QFilter numberFilter(String sourceField, Object selection) {
66
68
  List<String> values = numbers(selection);
67
- return values.isEmpty() ? null : new QFilter(sourceField + ".number", QCP.in, values.toArray(new String[0]));
69
+ return values.isEmpty() ? null : new QFilter(sourceField + ".number", QCP.in, values.toArray(new String[values.size()]));
70
+ }
71
+
72
+ // MulBasedataProp 的集合元素是关联表行,fbasedataid 才是业务记录;绝不回退到包装行主键。
73
+ private static DynamicObject record(DynamicObject value) {
74
+ if (value == null) throw new IllegalArgumentException("F7 选择项不能为空");
75
+ boolean hasReference = value.getDynamicObjectType().getProperty(MulBasedataProp.KEY_BASEDATAID) != null;
76
+ boolean hasShadow = value.getDynamicObjectType().getProperty(MulBasedataProp.KEY_BASEDATAID_ID) != null;
77
+ if (!hasReference && !hasShadow) return value;
78
+ Object reference = hasReference ? value.get(MulBasedataProp.KEY_BASEDATAID) : null;
79
+ if (!(reference instanceof DynamicObject)) {
80
+ throw new IllegalArgumentException("多选基础资料引用未加载,不能使用关联表行主键");
81
+ }
82
+ return (DynamicObject) reference;
83
+ }
84
+
85
+ public static List<Long> ids(Object selection) {
86
+ LinkedHashSet<Long> result = new LinkedHashSet<>();
87
+ if (selection == null) return new ArrayList<>();
88
+ if (selection instanceof DynamicObjectCollection) {
89
+ for (DynamicObject row : (DynamicObjectCollection) selection) addId(result, row);
90
+ return new ArrayList<>(result);
91
+ }
92
+ if (selection instanceof DynamicObject) {
93
+ addId(result, (DynamicObject) selection);
94
+ return new ArrayList<>(result);
95
+ }
96
+ throw new IllegalArgumentException("F7 过滤值必须是基础资料对象或对象集合");
97
+ }
98
+
99
+ private static void addId(LinkedHashSet<Long> ids, DynamicObject row) {
100
+ if (row == null) throw new IllegalArgumentException("F7 选择项不能为空");
101
+ boolean hasShadow = row.getDynamicObjectType().getProperty(MulBasedataProp.KEY_BASEDATAID_ID) != null;
102
+ Object shadow = hasShadow ? row.get(MulBasedataProp.KEY_BASEDATAID_ID) : null;
103
+ Object id = shadow != null ? shadow : record(row).getPkValue();
104
+ if (shadow != null && row.getDynamicObjectType().getProperty(MulBasedataProp.KEY_BASEDATAID) != null) {
105
+ Object reference = row.get(MulBasedataProp.KEY_BASEDATAID);
106
+ if (reference != null && (!(reference instanceof DynamicObject)
107
+ || !Objects.equals(id, ((DynamicObject) reference).getPkValue()))) {
108
+ throw new IllegalArgumentException("多选基础资料引用主键与影子主键冲突");
109
+ }
110
+ }
111
+ if (!(id instanceof Long) || ((Long) id) <= 0L) {
112
+ throw new IllegalArgumentException("基础资料必须携带有效 Long 业务主键");
113
+ }
114
+ ids.add((Long) id);
115
+ }
116
+
117
+ public static QFilter idFilter(String sourceField, Object selection) {
118
+ List<Long> values = ids(selection);
119
+ return values.isEmpty() ? null : new QFilter(sourceField, QCP.in, values.toArray(new Long[values.size()]));
120
+ }
121
+
122
+ public static boolean missing(Object value) {
123
+ return value == null || (value instanceof String && ((String) value).trim().isEmpty())
124
+ || (value instanceof Collection && ((Collection<?>) value).isEmpty())
125
+ || (value instanceof Object[] && ((Object[]) value).length == 0);
126
+ }
127
+
128
+ // verifyQuery 与 query 开头共用;0、false、带前导零的编码都不是空值。
129
+ public static void require(Object value, String label) {
130
+ if (missing(value)) throw new IllegalArgumentException("必录过滤条件不能为空:" + label);
131
+ }
132
+
133
+ public static QFilter comparison(String sourceField, String compare, Object value) {
134
+ if (!"=".equals(compare) && !"in".equals(compare)) {
135
+ throw new IllegalArgumentException("仅支持 =、in;日期 between 使用 rangeFilters");
136
+ }
137
+ if (missing(value)) return null;
138
+ if ("=".equals(compare)) {
139
+ scalar(value);
140
+ return new QFilter(sourceField, QCP.equals, value);
141
+ }
142
+ if (!(value instanceof Collection)) throw new IllegalArgumentException("in 必须携带标量集合");
143
+ for (Object item : (Collection<?>) value) scalar(item);
144
+ return new QFilter(sourceField, QCP.in, ((Collection<?>) value).toArray());
145
+ }
146
+
147
+ private static void scalar(Object value) {
148
+ if (missing(value) || !(value instanceof String || value instanceof Number
149
+ || value instanceof Boolean || value instanceof Date)) {
150
+ throw new IllegalArgumentException("查询条件必须携带非空标量;F7 先提取业务主键或编码");
151
+ }
152
+ }
153
+
154
+ public static List<QFilter> rangeFilters(String sourceField, Date start, Date end, boolean inclusiveEnd) {
155
+ if (start != null && end != null && (start.after(end) || (!inclusiveEnd && start.equals(end)))) {
156
+ throw new IllegalArgumentException("日期范围起点必须早于终点");
157
+ }
158
+ List<QFilter> result = new ArrayList<>();
159
+ if (start != null) result.add(new QFilter(sourceField, QCP.large_equals, start));
160
+ if (end != null) result.add(new QFilter(sourceField, inclusiveEnd ? QCP.less_equals : QCP.less_than, end));
161
+ return result;
68
162
  }
69
163
 
70
164
  private static void addNumber(LinkedHashSet<String> numbers, DynamicObject value) {
71
- String number = value.getString("number");
165
+ String number = record(value).getString("number");
72
166
  if (number == null || number.trim().isEmpty()) {
73
167
  throw new IllegalArgumentException("Selected F7 record has no number");
74
168
  }
@@ -377,16 +377,16 @@ ArrayList<String> arrayList = (ArrayList<String>) subList; // 抛出异常
377
377
  List<String> subList = list.subList(0, 1);
378
378
  ```
379
379
 
380
- **【🔴 强制】使用集合转数组必须使用 toArray(T[] array),传入长度为 0 的空数组**
380
+ **【🔴 强制】使用集合转数组必须使用 toArray(T[] array),数组类型与集合元素一致、长度等于集合大小(DCS 禁止 new T[0]:ITA_INEFFICIENT_TO_ARRAY)**
381
381
 
382
382
  ```java
383
383
  // ❌ 错误:直接使用无参方法
384
384
  List<String> list = new ArrayList<>();
385
385
  String[] array = list.toArray(); // 返回 Object[],强转会出错
386
386
 
387
- // ✅ 正确:传入类型为完全一致、长度为 0 的空数组
387
+ // ✅ 正确:数组元素类型完全一致,长度等于集合大小
388
388
  List<String> list = new ArrayList<>();
389
- String[] array = list.toArray(new String[0]);
389
+ String[] array = list.toArray(new String[list.size()]);
390
390
  ```
391
391
 
392
392
  ### 3.4 OOP 安全规约
@@ -1862,7 +1862,7 @@ if (maxAmt == null) {
1862
1862
  5. **long 赋值时使用大写 L**
1863
1863
  6. **不要在 foreach 循环里进行元素的 remove/add 操作**
1864
1864
  7. **ArrayList 的 subList 结果不可强转**
1865
- 8. **使用集合转数组必须传入类型为完全一致、长度为 0 的空数组**
1865
+ 8. **集合转数组传入类型完全一致、长度等于集合大小的数组(DCS 禁止 new T[0])**
1866
1866
  9. **所有的覆写方法必须加@Override 注解**
1867
1867
  10. **所有整型包装类对象之间值的比较全部使用 equals 方法**
1868
1868
 
@@ -6,7 +6,7 @@
6
6
  无法机器校验,只能凭实测来源信任。用 `python3 scripts/gen_api_index.py` 重新生成;不要手工
7
7
  编辑 java 代码块——需要新增 import 时请补充场景,让该 import 获得证据。
8
8
 
9
- ## Registered API classes(已注册 API 类,1527 个)
9
+ ## Registered API classes(已注册 API 类,1528 个)
10
10
 
11
11
  ```java
12
12
  import kd.bos.algo.Algo;
@@ -23,6 +23,7 @@ import kd.bos.algo.DataSetBuilder;
23
23
  import kd.bos.algo.DataType;
24
24
  import kd.bos.algo.Field;
25
25
  import kd.bos.algo.FilterFunction;
26
+ import kd.bos.algo.GroupbyDataSet;
26
27
  import kd.bos.algo.HashTable;
27
28
  import kd.bos.algo.Input;
28
29
  import kd.bos.algo.JoinHint;
@@ -124,12 +124,12 @@ if (entries == null || entries.isEmpty()) {
124
124
 
125
125
  // 获取分录行数
126
126
  int rowCount = entries.size();
127
- if (entries.size() == 0) {
127
+ if (entries.isEmpty()) {
128
128
  // 处理空分录
129
129
  }
130
130
 
131
131
  // 判断分录行数是否满足条件
132
- if (entries.size() > 0) {
132
+ if (!entries.isEmpty()) {
133
133
  // 处理非空分录
134
134
  }
135
135
  ```
@@ -171,7 +171,7 @@ for (DynamicObject parentRow : parentEntries) {
171
171
  ```java
172
172
  // 转换为 DynamicObject 数组(用于批量加载或操作)
173
173
  DynamicObjectCollection entries = getModel().getEntryEntity("entry");
174
- DynamicObject[] entryArray = entries.toArray(new DynamicObject[0]);
174
+ DynamicObject[] entryArray = entries.toArray(new DynamicObject[entries.size()]);
175
175
 
176
176
  // 用于 BusinessDataServiceHelper.load()
177
177
  QFilter filter = new QFilter("id", QCP.in, idList);
@@ -296,5 +296,7 @@ if (parentRow != null) {
296
296
  if (entries.size() > 0) { } // entries 可能为 null
297
297
 
298
298
  // ✅ 使用 isEmpty()
299
- if (entries != null && !entries.isEmpty()) { }
299
+ if (entries != null && !entries.isEmpty()) {
300
+ // 在这里处理非空分录;不要保留空块。
301
+ }
300
302
  ```
@@ -80,11 +80,11 @@ related_scenes:
80
80
 
81
81
  Model 对象常用于以下技术模式(详细代码结构和变体请参考对应文档):
82
82
 
83
- - [字段联动](../scenes/patterns/field-linkage.md) - 字段值变化时自动更新其他字段
84
- - [批量更新](../scenes/patterns/batch-update.md) - 一次性更新多个字段,避免重复触发事件
85
- - [数据初始化](../scenes/patterns/data-init.md) - 表单打开时设置默认值
86
- - [分录批量操作](../scenes/patterns/entry-batch-operation.md) - 循环处理分录数据
87
- - [分录行管理](../scenes/patterns/entry-row-management.md) - 新增、删除、清空分录行
83
+ - [字段联动](../scenes/event/property-changed-set-value.md) - 字段值变化时自动更新其他字段
84
+ - [批量更新](../scenes/common/model-begin-end-init.md) - 一次性更新多个字段,避免重复触发事件
85
+ - [数据初始化](../scenes/event/after-bind-data-set-value.md) - 表单打开时设置默认值
86
+ - [分录批量操作](../scenes/event/property-changed-entry-batch.md) - 循环处理分录数据
87
+ - [分录行管理](../scenes/_index.md) - 新增、删除、清空分录行
88
88
 
89
89
  > 技术模式文档包含:模式定义、涉及的核心对象、典型代码结构、常见变体、业务场景示例
90
90
 
@@ -514,7 +514,7 @@ getView().updateView("entry");
514
514
  ## 相关文档
515
515
 
516
516
  - [View 核心对象](view.md) - 界面控制和刷新
517
- - [Control 核心对象](control.md) - 控件操作
518
- - [字段联动场景](../scenes/patterns/field-linkage.md) - propertyChanged 中的 Model 用法
519
- - [分录批量操作场景](../scenes/patterns/entry-batch-operation.md) - getEntryEntity 的典型用法
520
- - [数据初始化场景](../scenes/patterns/data-init.md) - afterBindData 中的 Model 用法
517
+ - [Control 核心对象](view.md) - 控件操作
518
+ - [字段联动场景](../scenes/event/property-changed-set-value.md) - propertyChanged 中的 Model 用法
519
+ - [分录批量操作场景](../scenes/event/property-changed-entry-batch.md) - getEntryEntity 的典型用法
520
+ - [数据初始化场景](../scenes/event/after-bind-data-set-value.md) - afterBindData 中的 Model 用法
@@ -81,11 +81,11 @@ related_scenes:
81
81
 
82
82
  View 对象常用于以下技术模式(详细代码结构和变体请参考对应文档):
83
83
 
84
- - [消息通知](../scenes/patterns/notification.md) - 向用户显示提示、警告、错误、成功消息
85
- - [动态控件控制](../scenes/patterns/dynamic-control.md) - 根据业务逻辑动态控制控件显示和启用状态
86
- - [页面跳转](../scenes/patterns/page-navigation.md) - 打开新表单、关闭页面、返回数据
87
- - [确认对话框](../scenes/patterns/confirm-dialog.md) - 在执行危险操作前请求用户确认
88
- - [父子页面交互](../scenes/patterns/parent-child-interaction.md) - 子页面与父页面的数据传递和操作触发
84
+ - [消息通知](../api/form/IFormView.md) - 向用户显示提示、警告、错误、成功消息
85
+ - [动态控件控制](../scenes/event/after-bind-data-set-visible.md) - 根据业务逻辑动态控制控件显示和启用状态
86
+ - [页面跳转](../scenes/event/item-click-show-form.md) - 打开新表单、关闭页面、返回数据
87
+ - [确认对话框](../scenes/event/item-click-show-confirm.md) - 在执行危险操作前请求用户确认
88
+ - [父子页面交互](../scenes/event/closed-call-back-set-value.md) - 子页面与父页面的数据传递和操作触发
89
89
 
90
90
  > 技术模式文档包含:模式定义、涉及的核心对象、典型代码结构、常见变体、业务场景示例
91
91
 
@@ -189,7 +189,7 @@ public void registerListener(EventObject e) {
189
189
 
190
190
  ```java
191
191
  /**
192
- * Kingdee Cosmic 插件模板(自动生成)
192
+ * Kingdee Cosmic plugin template (auto-generated)
193
193
  * Author: [your-name] | Date: [yyyy-MM-dd]
194
194
  */
195
195
  package kd.{isv}.{module}.formplugin;
@@ -232,18 +232,22 @@ public class Xxx{PluginSuffix} extends {BaseClass} {
232
232
  @Override
233
233
  public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); }
234
234
  @Override
235
- public void afterBindData(EventObject e) {}
235
+ public void afterBindData(EventObject e) { super.afterBindData(e); }
236
236
  @Override
237
237
  public void propertyChanged(PropertyChangedArgs e) {
238
238
  super.propertyChanged(e);
239
239
  String key = e.getProperty().getName();
240
- if (FIELD_XXX.equals(key)) {}
240
+ if (FIELD_XXX.equals(key)) {
241
+ // 在此处理字段变化;DCS 不允许空代码块(S108)
242
+ }
241
243
  }
242
244
  @Override
243
245
  public void itemClick(ItemClickEvent evt) {
244
246
  super.itemClick(evt);
245
247
  String itemKey = evt.getItemKey();
246
- if (BTN_XXX.equals(itemKey)) {}
248
+ if (BTN_XXX.equals(itemKey)) {
249
+ // 在此处理按钮点击;DCS 不允许空代码块(S108)
250
+ }
247
251
  }
248
252
  @Override
249
253
  public void closedCallBack(ClosedCallBackEvent e) {
@@ -229,7 +229,7 @@ ListSelectedRow row = billList.getCurrentSelectedRowInfo();
229
229
 
230
230
  ```java
231
231
  /**
232
- * Kingdee Cosmic 列表插件模板(自动生成)
232
+ * Kingdee Cosmic list plugin template (auto-generated)
233
233
  * Author: [your-name] | Date: [yyyy-MM-dd]
234
234
  */
235
235
  package kd.{isv}.{module}.listplugin;
@@ -261,12 +261,14 @@ public class Xxx{PluginSuffix} extends {BaseClass} {
261
261
  @Override
262
262
  public void itemClick(ItemClickEvent evt) {
263
263
  super.itemClick(evt);
264
- if (BTN_XXX.equals(evt.getItemKey())) {}
264
+ if (BTN_XXX.equals(evt.getItemKey())) {
265
+ // 在此处理按钮点击;DCS 不允许空代码块(S108)
266
+ }
265
267
  }
266
268
  @Override
267
269
  public void listRowClick(ListRowClickEvent evt) { super.listRowClick(evt); }
268
270
  @Override
269
- public void billListHyperLinkClick(HyperLinkClickArgs args) {}
271
+ public void billListHyperLinkClick(HyperLinkClickArgs args) { super.billListHyperLinkClick(args); }
270
272
  }
271
273
  ```
272
274
 
@@ -623,6 +623,7 @@ public class PurchaseOrderPrintPlugin extends AbstractPrintPlugin {
623
623
  7. 使用 `beforeExpFile` 自定义文件名时,需保证文件名唯一性。
624
624
  8. `AbstractPrintSeniorPlugin` 仅在需要控制数据访问器参数时使用,一般场景使用 `AbstractPrintPlugin` 即可。
625
625
  9. 表格操作中插入/删除行列后如果之前有合并设置,建议使用带 `isReMerge=true` 参数的方法重新处理合并。
626
+ 10. 报表没有可供引擎加载的实体行:报表的打印插件在 `afterLoadData` 和 `loadCustomData` 中读取报表页面的列表模型(`MainDataSource.getPageId()` → `ReportView` → `ReportListModel.getRowData(startIndex, length)`)。见 `{ROOT_DIR}/knowledge/cosmic/platform/scenes/report/report-print-data.md`。
626
627
 
627
628
  ## 骨架模板
628
629