@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
@@ -41,6 +41,19 @@ getColumns → [用户点击查询] → query(queryParam, null)
41
41
  2. 左树右表场景优先使用 `selectedObj` 限定范围。
42
42
  3. 大数据量异步查询时使用 `setProgress(int)` 反馈执行进度。
43
43
  4. 列控制集中放在 `getColumns`,不要在 `query` 混入列逻辑。
44
+ 5. 插件在多次查询之间是无状态的:每次查询都由一个新实例服务,所以成员变量只在一次 `query` 调用内有效,绝不会带到下一次。
45
+ 6. 算法名按「模块.业务.方法」命名(例如 `er.checkingpay`):性能监控里显示的就是这个名字。
46
+ 7. 用户需要处理的失败抛 `KDBizException` 并带可读文案。数据来自打开方的辅助视图(例如钻取明细弹窗)可以返回空 DataSet,而不是让整页报错。
47
+
48
+ ## 默认排序契约
49
+
50
+ Java 交付消费 `reportContract.defaultSorts` 和 `defaultSortPolicy`。规则保留有序的 `fieldKey`、
51
+ `dateIndex` 和方向,数据列名区分大小写。在 `query()` 中优先使用交互式
52
+ `ReportQueryParam.getSortInfo()` 排序,仅把已验证的列 key 映射到 DataSet 列名。
53
+ 没有交互排序时才使用默认规则;作用于关联/合并/汇总完成后的最终 DataSet,在分页/导出之前执行,
54
+ 保持权限过滤。SortInfo 和 DataSet 排序签名以目标 SDK 为准,禁止拼接未经校验的排序 key 到 SQL。
55
+ 多键默认排序与交互覆盖分别验收;源码、编译和注册不证明运行排序。
56
+ 禁止用 `InitField` 或 `setReportSorts` 实现:该 API 会污染默认显示列配置。
44
57
 
45
58
  ## 常见坑位
46
59
 
@@ -48,6 +61,10 @@ getColumns → [用户点击查询] → query(queryParam, null)
48
61
  - 忽略 `selectedObj`,导致左树右表点击节点后仍返回全量数据。
49
62
  - `query` 返回空对象而不是合法 `DataSet`。
50
63
  - 在 `query` 里逐行远程调用,导致报表超时。
64
+ - 开启了表头过滤(`ColFilter`,或 `reportform` 插件里的 `setSortAndFilter`)却没在 `query` 里应用 `getTableHeadFilterItems()`:表头过滤就不起任何作用。
65
+ - 把同一个 DataSet 遍历两次。每次遍历都会消费它,所以还要再用时,必须在第一次遍历之前先 `copy()`。
66
+ - 对列名或列顺序不同的两个 DataSet 做 `union`。
67
+ - 按 `'' as pid` 这类常量字符串列排序:它的类型未知,把该列显式声明为 `DataType.StringType` 之前 `orderBy` 会失败。
51
68
 
52
69
  ## 生成策略选择
53
70
 
@@ -61,11 +78,23 @@ getColumns → [用户点击查询] → query(queryParam, null)
61
78
  | 是 | 否 | 分批查询(覆写 `queryBatchBy`) | `scenes/report/report-batch-query.md` |
62
79
  | 否 | 左树 | 用被点击节点的 `selectedObj` 收窄数据行;树本身是另一个 `reporttreelist` 插件 | `scenes/report/report-tree-data-query.md` |
63
80
  | 是 | 左树 | 分批查询 + `selectedObj` 收窄 | `report-batch-query.md` + `report-tree-data-query.md` |
81
+ | 否 | 折叠式行 | 普通查询,数据行另带 `rowid` / `pid` / `isgroupnode`;由 `reportform` 插件开启树形 | `scenes/report/report-tree-list.md` |
82
+
83
+ 「左树」指左树右表导航,它是另一个插件(`AbstractReportTreeDataPlugin`,返回 `List<TreeNode>`),注册在
84
+ 左树上,不是本插件 DataSet 的某种形态。把同一批行折叠渲染由 `reportform` 插件开启
85
+ (`setTreeReportList` / `setTreeExpandColId`),本插件随后把数据行组织成层级:`rowid` 是每行自己的 id,
86
+ `pid` 是父行的 `rowid`,`isgroupnode` 标记分组行。不要用 `id` / `pid` 代替它们。
64
87
 
65
- 这里的「树」指左树右表导航,它是另一个插件(`AbstractReportTreeDataPlugin`,返回
66
- `List<TreeNode>`),不是本插件 DataSet 的某种形态。把同一批行折叠渲染属于 `reportform` 的职责
67
- (`setTreeReportList` / `setTreeExpandColId`),在本插件里不需要任何特殊处理。两者都没有关于
68
- `id` / `pid` DataSet 列的文档约定。
88
+ 其他需求同样对应到场景。把适用的场景作为 intent 的 `scenes` 条目传给
89
+ `prepare_plugin_handoff.py`,它会把场景的 SDK 引用展开成 import:
90
+
91
+ | 需求 | 场景 |
92
+ |---|---|
93
+ | 报表列上的表头过滤或排序 | `report/report-head-filter` |
94
+ | 小计与总计行 | `report/report-subtotal-total` |
95
+ | 链式聚合、一张报表两个来源、手工构造数据行 | `report/report-dataset-assembly` |
96
+ | 由钻取打开、通过自定义参数传值的明细报表 | `report/report-hyperlink-drill` |
97
+ | 打印报表的数据行(另一个注册在打印模板上的 `printplugin` 类) | `report/report-print-data` |
69
98
 
70
99
  **所有策略的强制规则**:
71
100
  1. 必须定义 `private static final String ALGO_NAME` 用于可追溯性
@@ -88,10 +117,88 @@ getColumns → [用户点击查询] → query(queryParam, null)
88
117
  `query` 与 `getColumns` 都声明了 `throws Throwable` —— 见
89
118
  `scenes/report/report-list-data-query.md` 的 Method Signatures 段。声明它总能编译;只有覆写不调用 `super` 时才能收窄掉,
90
119
  不要去「修」已经声明它的示例。API 页能确定的是 `abstract`,这也是 `query` 不带 `super` 调用的原因
120
+ 12. 开启了表头过滤就必须应用它:`getTableHeadFilterItems()` 返回原始条目(列 key、比较符、值),
121
+ `getHeadFilters()` 返回同样的条件转成的 `QFilter`,只有列 key 就是所查实体的字段 key 时才能直接用
122
+ 13. 每次遍历都会消费 DataSet;要读两次就在第一次遍历前 `copy()`,并关闭本插件自己持有的副本
123
+ 14. `union` 要求两边列名相同、顺序一致:缺少的列用常量补齐(`select` 里写 `"0 amount"`,
124
+ 或 `addField("0", "amount")`)
125
+
126
+ ## 把过滤条件变成查询条件
127
+
128
+ 过滤面板条件以 `FilterItemInfo` 条目从 `getFilterItems()` 传入,每条有 `getPropName()`、
129
+ `getCompareType()` 和 `getValue()`。面板 key 就是所查实体自己的字段 key 时,条目可以原样转发为
130
+ `new QFilter(item.getPropName(), item.getCompareType(), item.getValue())`。不是时 —— app-build
131
+ 的 `flt_<列>` key、`q_` 前缀、`org.id` 这样带点的基础资料路径 —— 先映射到源字段,绝不转发没有任何
132
+ 源字段拥有的 key。
133
+
134
+ 按 key 读取单个条件时用强类型访问器:多选基础资料过滤用 `getDynamicObjectCollection(key)`,其余有
135
+ `getDynamicObject(key)`、`getDate(key)`、`getBoolean(key)` 和 `getString(key)`。拆分的日期范围、F7
136
+ 身份与别名冲突以 `references/report-filter-contract.md` 为准。固定业务规则 —— 只取已审核单据、
137
+ 排除某类单据 —— 在 `query()` 里追加:插件是收口这些规则的唯一位置。
138
+
139
+ 表头过滤是另一个条件来源,在同一次查询里应用:
140
+
141
+ ```java
142
+ List<QFilter> filters = new ArrayList<>(filter.getQFilters());
143
+ List<FilterItemInfo> headItems = filter.getTableHeadFilterItems();
144
+ if (headItems != null) {
145
+ for (FilterItemInfo item : headItems) {
146
+ // HEAD_FILTER_FIELDS 把报表列 key 映射到它被选出时的源字段。
147
+ String field = HEAD_FILTER_FIELDS.get(item.getPropName());
148
+ if (field != null && item.getValue() != null) {
149
+ filters.add(new QFilter(field, item.getCompareType(), item.getValue()));
150
+ }
151
+ }
152
+ }
153
+ ```
154
+
155
+ 由 `query()` 计算出来的列没有源字段,要在计算之后再过滤。
156
+
157
+ `queryParam.getCustomParam()` 承载的是面板条件之外的值:`reportform` 插件在 `verifyQuery` 里放进去的东西,
158
+ 或钻取打开方传进来的东西。读取时做空判断,并使用稳定的 key,例如参数对象的类全名。
159
+
160
+ ## 组装 DataSet
161
+
162
+ 一次查询带回报表要用的全部字段(包括 `currency.id` 这样的关联字段),再用 DataSet 算子加工结果,
163
+ 而不是回头再查库:
164
+
165
+ - `select` 做投影、改名和计算:`"TO_CHAR(happenddate, 'yyyy.MM') as periodcol"` 把日期变成期间列;
166
+ - `groupBy(keys)` 配 `sum`、`avg`、`min`、`max` 或 `count`,再 `finish()`,完成聚合;`orderBy` 放在
167
+ `finish()` 之后,只能引用聚合后仍存在的列。比率取平均,绝不求和;
168
+ - `addField(expression, alias)` 派生新列,`filter(expression)` 剔除行,
169
+ `case when x is null then 0 else x end` 防止 null 参与运算;
170
+ - 两个来源共享同一维度时,`union` 之后要再 `groupBy` 一次,让每个维度值只有一行。
171
+
172
+ 数据来自内存而不是查询时手工构造:`Algo.create(ALGO_NAME).createDataSet(rows, new RowMeta(fields))`,
173
+ 按行内顺序每列一个 `Field`,类型取自 `dataSetColumnTypes`。常量字符串列要显式声明
174
+ `DataType.StringType`。长 id 列表按每次几百个值分批查询,而不是一个无上限的 `in`。完整写法见
175
+ `{ROOT_DIR}/knowledge/cosmic/platform/scenes/report/report-dataset-assembly.md`。
176
+
177
+ ## 小计与合计行
178
+
179
+ 列的 `Summary` 属性给列表带来它自己的合计行;数据内部的小计行,以及夹在数据行中间、带标签的合计行,
180
+ 由 `query()` 构造。每个合计层级聚合一次,每行打上 `sumlevel` 标记列(0 明细、1 小计、2 总计),
181
+ 合计行没有值的列用占位补齐,然后把各层 `union` 起来,再按分组列、`sumlevel` 的顺序 `orderBy`,
182
+ 总计行用它专属的排序键排在最后。
183
+ `reportform` 插件在 `packageData` 里给这些行打标签,并清空对它们无意义的列;只有 `sumlevel`
184
+ 是已声明的(隐藏)报表列时,它才读得到。见
185
+ `{ROOT_DIR}/knowledge/cosmic/platform/scenes/report/report-subtotal-total.md`。
186
+
187
+ ## 分批查询规则
188
+
189
+ - 分批依据列必须把数据分成均衡的批次;优先用必录过滤字段或排序字段。
190
+ - `queryBatchBy` 的结果会全部缓存在内存里,所以只返回一两列分批依据。
191
+ - 返回的分批依据要先排序,让每一批是一段连续范围。
192
+ - `setCountPerBatch(n)` 设置每批的分批依据行数,`setMaxRowCountCached(n)` 设置内存最多缓存的行数,
193
+ 默认 100,000。
194
+ - `query` 从 `byBatchInfo().getCurrentBatchRows()` 读取当前批并据此收窄;`queryBatchBy` 返回 `null`
195
+ 时执行一次普通查询。既不读当前批行也不读 `selectedObj` 的分批 `query` 会每批都返回全部行,编译边界
196
+ 会拒绝它(`PLUGIN_SOURCE_BATCH_NOT_NARROWED`)。
197
+ - 分批不是分页:一批数据可供几十到几百个列表分页。
91
198
 
92
199
  ## 骨架模板
93
200
 
94
- > 适用:`reportlist`。继承 `AbstractReportListDataPlugin`(`kd.bos.entity.report.AbstractReportListDataPlugin`),**不是**表单插件,不能调用 `getView()` / `getModel()`。`query` 为抽象方法必须实现。类名后缀按 `{PluginSuffix}` 命名。注册方式:在苍穹报表模板配置中注册数据插件类全限定名。
201
+ > 适用:`reportlist`。继承 `AbstractReportListDataPlugin`(`kd.bos.entity.report.AbstractReportListDataPlugin`),**不是**表单插件,不能调用 `getView()` / `getModel()`。`query` 为抽象方法必须实现。类名后缀按 `{PluginSuffix}` 命名。注册方式:把类全限定名声明在报表 artifact 的 `reportPlugins` 里;报表流水线把它注册到报表列表的取数槽位(`ReportQueryPlugin`),`register_plugins.py` 不处理这种类型。
95
202
 
96
203
  ```java
97
204
  package kd.cd.common;
@@ -106,15 +213,15 @@ import java.util.ArrayList;
106
213
  import kd.bos.orm.query.QCP;
107
214
 
108
215
  /**
109
- * 报表取数插件骨架模板(原生 AbstractReportListDataPlugin)。
110
- * 该类仅用于示例写法,生成后请按实际业务删除无用事件并替换占位常量。
216
+ * Skeleton template for a report data plugin (native AbstractReportListDataPlugin).
217
+ * This class is for example purposes only; remove unused events and replace placeholder constants according to actual business needs after generation.
111
218
  */
112
219
  public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
113
220
 
114
221
  /**
115
- * 触发时机: 在需要了解当前插件可访问上下文能力时调用。
116
- * 参数要点: 无入参;仅展示当前插件可通过 this. 访问的方法能力。
117
- * 典型用途: 作为模板提示,指导在各事件内选择正确的上下文 API。
222
+ * Trigger timing: invoked when you need to learn what context capabilities the current plugin can access.
223
+ * Parameter notes: no input; only demonstrates methods accessible via this. in the current plugin.
224
+ * Typical use: as a template hint, guiding the selection of the correct context API in each event.
118
225
  */
119
226
  private void getContextSample() {
120
227
  // this.getQueryParam();
@@ -131,11 +238,11 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
131
238
  // ===== 核心事件 =====
132
239
 
133
240
  /**
134
- * 触发时机: 报表发起查询时。
135
- * 参数要点:
136
- * - queryParam.getFilter() 为过滤面板条件。
137
- * - selectedObj 为左侧树或左表选中对象。
138
- * 典型用途: 按查询条件与左侧选中对象组装 DataSet。
241
+ * Trigger timing: when the report initiates a query.
242
+ * Parameter notes:
243
+ * - queryParam.getFilter() is the condition from the filter panel.
244
+ * - selectedObj is the object selected in the left tree or left grid.
245
+ * Typical use: assemble the DataSet according to the query conditions and the object selected on the left.
139
246
  */
140
247
  @Override
141
248
  public DataSet query(ReportQueryParam queryParam, Object selectedObj) {
@@ -151,13 +258,13 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
151
258
  if (billNo != null) filters.add(new QFilter(FIELD_BILL_NO, QCP.equals, billNo));
152
259
  }
153
260
  this.setProgress(20);
154
- return QueryServiceHelper.queryDataSet(ALGO_NAME, ENTITY_NUMBER, SELECT_FIELDS, filters.toArray(new QFilter[0]), ORDER_BY);
261
+ return QueryServiceHelper.queryDataSet(ALGO_NAME, ENTITY_NUMBER, SELECT_FIELDS, filters.toArray(new QFilter[filters.size()]), ORDER_BY);
155
262
  }
156
263
 
157
264
  /**
158
- * 触发时机: 报表初始化列定义后。
159
- * 参数要点: columns 为系统生成的列集合,可调整显示列属性。
160
- * 典型用途: 动态隐藏列、修改列宽、冻结列或调整显示顺序。
265
+ * Trigger timing: after the report initializes column definitions.
266
+ * Parameter notes: columns is the column collection generated by the system; display column attributes can be adjusted.
267
+ * Typical use: dynamically hide columns, modify column width, freeze columns, or adjust display order.
161
268
  */
162
269
  @Override
163
270
  public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
@@ -167,10 +274,10 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
167
274
  }
168
275
 
169
276
  /**
170
- * 触发时机: getColumns 的辅助方法。
171
- * 参数要点: nodes 为列树的某一层。
172
- * 典型用途: 命中分组内的列。ReportColumnGroup 不是 ReportColumn,因此带强转的扁平循环会在
173
- * 第一个分组上抛异常,也永远到不了它 getChildren() 里的列。
277
+ * Trigger timing: helper for getColumns.
278
+ * Parameter notes: nodes is one level of the column tree.
279
+ * Typical use: reach a grouped column. A ReportColumnGroup is not a ReportColumn, so a flat
280
+ * loop with a cast throws on the first group and never reaches its getChildren() columns.
174
281
  */
175
282
  private void apply(List<AbstractReportColumn> nodes) {
176
283
  for (int i = 0; i < nodes.size(); i++) {
@@ -12,6 +12,11 @@ AbstractReportTreeDataPlugin (kd.bos.entity.report.AbstractReportTreeDataPlugin)
12
12
 
13
13
  报表树数据插件是独立的树数据构造插件,**不继承 AbstractFormPlugin**,不具备表单插件的生命周期和视图操作能力。其核心职责是构造报表左侧树形导航节点数据。当报表需要左树右表布局时,通过此插件提供树节点数据。
14
14
 
15
+ 它注册在左树自己身上:没有任何公共报表模板预置左树(`bos_grouprpttpl` 是分组报表),所以先由用户在设计器里
16
+ 给报表新增「报表树」控件(`ReportTreeAp`),再通过 `setReportProperties --target tree` 把类名写进
17
+ `ReportTreeAp.ReportPlugin`。它绝不是 `reportPlugins` 条目 —— 那个槽位是报表列表的取数插件,树插件类放在那里
18
+ 构建不出任何树。右侧的数据行仍然来自那个 `reportlist` 插件。
19
+
15
20
  ## reporttreedata 插件事件
16
21
 
17
22
  ### reporttreedata 插件事件类型
@@ -26,9 +31,30 @@ AbstractReportTreeDataPlugin (kd.bos.entity.report.AbstractReportTreeDataPlugin)
26
31
  ```
27
32
  query(queryParam, null) ← 首次加载,返回根节点列表
28
33
  → [用户展开节点] → query(queryParam, parentNodeId) ← 返回子节点列表
29
- → [用户点击节点] → 节点ID传递给 reportlistdata 插件的 query 方法
34
+ → [用户点击节点] → 节点ID作为 selectedObj 传递给 reportlistdata 插件的 query 方法
30
35
  ```
31
36
 
37
+ ## 构建树
38
+
39
+ 两种形态都可用:
40
+
41
+ - **懒加载** —— `nodeId` 为 null 时返回根节点,为某节点 id 时返回该节点的子节点。`setLeaf(false)` 的节点
42
+ 显示展开箭头;叶子节点使用 `setLeaf(true)`。
43
+ - **一次构建** —— 返回一个合成的根节点(「全部」,`setParentid("")`、`setIsOpened(true)`),用
44
+ `setChildren(list)` 挂上全部节点。先约定根节点 id 对取数插件意味着什么 —— 不收窄,或子节点 id
45
+ 集合 —— 并把它构造成确定值,而不是把子节点 id 拼接成字符串。
46
+
47
+ 无论哪种形态:
48
+
49
+ - 每个 `setId` 的值都唯一,并在多次查询之间保持稳定;取数插件把它作为 `selectedObj` 接收,在两次查询
50
+ 之间变化的 id 会让选中态与其数据行脱节;
51
+ - 树跟随过滤面板:从 `queryParam.getFilter()` 读取与取数插件相同的条件
52
+ (`getDynamicObjectCollection(key)`、`getDate(key)`、`getString(key)`),由它们选定实体并限定节点范围;
53
+ - 基础资料经个性化处理后,同一个逻辑记录可能有多个物理 id;按 `masterid` 去重,否则同一往来方会
54
+ 出现两次,点击根节点时它的数据也会被重复计算;
55
+ - 节点要批量查询:只有节点很少时才可以接受逐行 `loadSingle`;
56
+ - 节点 DataSet 只遍历一次并关闭,就像骨架里那样。
57
+
32
58
 
33
59
 
34
60
  ### TreeNode 构建规范
@@ -40,17 +66,18 @@ node.setText(number + " " + name); // 节点显示文本
40
66
  node.setParentid(parentId); // 父节点ID(根节点设为固定值如 "0")
41
67
  node.setLeaf(false); // 非叶子节点,因此显示展开箭头
42
68
  node.setIsOpened(false); // 是否默认展开
69
+ root.setChildren(children); // 一次构建的树:根节点挂上它的子节点
43
70
  ```
44
71
 
45
72
 
46
73
 
47
74
  ## 骨架模板
48
75
 
49
- > 适用:`reporttreelist`。继承 `AbstractReportTreeDataPlugin`(`kd.bos.entity.report.AbstractReportTreeDataPlugin`),**不是**表单插件,不能调用 `getView()` / `getModel()`。`query` 为抽象方法必须实现。类名后缀按 `{PluginSuffix}` 命名。注册方式:在苍穹报表模板配置中注册树数据插件类全限定名。
76
+ > 适用:`reporttreelist`。继承 `AbstractReportTreeDataPlugin`(`kd.bos.entity.report.AbstractReportTreeDataPlugin`),**不是**表单插件,不能调用 `getView()` / `getModel()`。`query` 为抽象方法必须实现。类名后缀按 `{PluginSuffix}` 命名。注册方式:左树自己的槽位,即用户给报表新增的报表树控件上的 `ReportTreeAp.ReportPlugin` —— 不是 `reportPlugins`。
50
77
 
51
78
  ```java
52
79
  /**
53
- * Kingdee Cosmic 报表树数据插件模板(自动生成)
80
+ * Kingdee Cosmic report tree data plugin template (auto-generated)
54
81
  * Author: [your-name] | Date: [yyyy-MM-dd]
55
82
  */
56
83
  package kd.{isv}.{module}.formplugin;
@@ -63,8 +90,9 @@ import kd.bos.algo.Row;
63
90
  import kd.bos.entity.report.AbstractReportTreeDataPlugin;
64
91
  import kd.bos.entity.report.ReportQueryParam;
65
92
  import kd.bos.entity.tree.TreeNode;
66
- import kd.bos.orm.ORM;
67
- // import kd.{isv}.{module}.business.XxxUtils;
93
+ import kd.bos.orm.query.QCP;
94
+ import kd.bos.orm.query.QFilter;
95
+ import kd.bos.servicehelper.QueryServiceHelper;
68
96
 
69
97
  /** {功能描述} */
70
98
  public class Xxx{PluginSuffix} extends AbstractReportTreeDataPlugin {
@@ -76,30 +104,22 @@ public class Xxx{PluginSuffix} extends AbstractReportTreeDataPlugin {
76
104
  @Override
77
105
  public List<TreeNode> query(ReportQueryParam queryParam, String nodeId) {
78
106
  List<TreeNode> treeNodes = new ArrayList<>();
79
-
80
- // 方式一:ORM 查询构建树节点
81
- // DataSet ds = ORM.create().queryDataSet(this.getClass().getName(),
82
- // TREE_ENTITY_ID, TREE_SELECT_FIELDS, null, "number asc");
83
- // while (ds.hasNext()) {
84
- // Row row = ds.next();
85
- // TreeNode node = new TreeNode();
86
- // node.setId(String.valueOf(row.get("id")));
87
- // node.setText(row.getString("number") + " " + row.getString("name"));
88
- // node.setParentid(row.get("parent") == null ? ROOT_NODE_ID : String.valueOf(row.get("parent")));
89
- // node.setLeaf(false);
90
- // treeNodes.add(node);
91
- // }
92
- // ds.close();
93
-
94
- // 方式二:手动构建固定树节点
95
- // TreeNode rootNode = new TreeNode();
96
- // rootNode.setId("root"); rootNode.setText("全部");
97
- // rootNode.setParentid(ROOT_NODE_ID); rootNode.setLeaf(false);
98
- // treeNodes.add(rootNode);
99
-
107
+ // DCS 禁止 ORM/DB 访问;通过 QueryServiceHelper 查询并传入有效业务过滤条件
108
+ QFilter[] filters = {new QFilter("enable", QCP.equals, "1")};
109
+ try (DataSet ds = QueryServiceHelper.queryDataSet(this.getClass().getName(),
110
+ TREE_ENTITY_ID, TREE_SELECT_FIELDS, filters, "number asc")) {
111
+ while (ds.hasNext()) {
112
+ Row row = ds.next();
113
+ Object parent = row.get("parent");
114
+ TreeNode node = new TreeNode();
115
+ node.setId(String.valueOf(row.get("id")));
116
+ node.setText(row.getString("number") + " " + row.getString("name"));
117
+ node.setParentid(parent == null ? ROOT_NODE_ID : String.valueOf(parent));
118
+ node.setLeaf(false);
119
+ treeNodes.add(node);
120
+ }
121
+ }
100
122
  return treeNodes;
101
123
  }
102
-
103
- // private void updateProgress(int progress) { this.setProgress(progress); }
104
124
  }
105
125
  ```
@@ -14,7 +14,7 @@
14
14
  | Container, 折叠, collapse, 展开, 收起 | Container 折叠控制 | `control/container/container-collapse.md` | approved | `afterBindData` | `Container` | `billform,mobform,mobbill,form,baseform` |
15
15
  | EntryGrid, 行绑定, beforeEntryBindRow, 行控件状态 | EntryGrid 数据绑定监听 | `control/entry-grid/entry-grid-bind-data.md` | approved | `beforeEntryBindRow` | `EntryGrid` | `billform,mobform,mobbill,form` |
16
16
  | EntryGrid, deleteEntryRow, 空行, 倒序删除 | 分录空行删除 | `control/entry-grid/entry-grid-delete-empty-row.md` | approved | — | `EntryGrid` | `billform,mobform,mobbill,form` |
17
- | FilterGrid, 过滤条件, 反序列化, 注入 | FilterGrid 动态过滤条件设置 | `control/filter-grid/filter-grid-set-value.md` | approved | — | `FilterGrid` | `listform,moblist` |
17
+ | FilterGrid, 过滤条件, 反序列化, 注入 | FilterGrid 动态过滤条件设置 | `control/filter-grid/filter-grid-set-value.md` | approved | — | `FilterGrid` | `form,billform,baseform,listform,moblist` |
18
18
  | Tab, 标签页, 切换, 懒加载, tabSelected | Tab 标签页选择监听 | `control/tab/tab-selected.md` | approved | `tabSelected` | `Tab` | `billform,mobform,mobbill,form,baseform` |
19
19
  | BillList, 列表弹窗, getSelectedRows, ListShowParameter | 列表插件打开表单 | `control/list/list-show-form.md` | approved | `itemClick` | `BillList` | `listform,moblist` |
20
20
  | BillList, 列隐藏, getShowListColumns, IListColumn | 列表列动态隐藏 | `control/list/list-column-hide.md` | approved | — | `BillList` | `listform,moblist` |
@@ -274,12 +274,21 @@
274
274
  | 关键词 | 场景名 | 文件 | 状态 | pluginType |
275
275
  |-------|-------|------|------|------------|
276
276
  | AbstractReportListDataPlugin, 报表数据查询, query, DataSet, ORM, Algo | 报表数据查询插件 | `report/report-list-data-query.md` | approved | `reportlist` |
277
- | AbstractReportTreeDataPlugin, 报表树数据, TreeNode, 树节点, 左树右表 | 报表树数据插件 | `report/report-tree-data-query.md` | approved | `reporttreelist` |
277
+ | AbstractReportTreeDataPlugin, 报表树数据, TreeNode, 树节点, 左树右表, ReportTreeAp | 报表树数据插件 | `report/report-tree-data-query.md` | approved | `reporttreelist` |
278
278
  | ReportQueryParam, 报表参数, 查询条件, 过滤 | 报表查询参数 | `report/report-verify-query.md` | approved | `reportform,reportlist,reporttreelist` |
279
279
  | ReportColumn, 报表列, 动态列, setFieldKey, setCaption, setFieldType | 报表动态列属性 | `report/report-flex-property.md` | approved | `reportform,reportlist,reporttreelist` |
280
280
  | 报表合并列, 合并列, ReportColumn, 报表 | 报表合并列 | `report/report-merge-column.md` | approved | `reportform,reportlist,reporttreelist` |
281
281
  | 报表汇总, 总计, 小计, 分组汇总, 报表 | 报表汇总类型 | `report/report-total-type.md` | approved | `reportform,reportlist,reporttreelist` |
282
- | 报表批量查询, 批量数据, 分页查询, 大数据量 | 报表批量查询 | `report/report-batch-query.md` | approved | `reportlist,reporttreelist` |
282
+ | queryBatchBy, 报表分批取数, 分批依据, IReportBatchQueryInfo, 大数据量 | 报表分批取数 | `report/report-batch-query.md` | approved | `reportlist,reporttreelist` |
283
+ | setSortAndFilter, beforeCreateFilterInfo, getTableHeadFilterItems, getHeadFilters, 表头过滤, 表头排序 | 报表表头过滤与排序 | `report/report-head-filter.md` | approved | `reportform,reportlist` |
284
+ | itemClick, 工具栏按钮, addCellClickListener, getRowData, setSelectedAll, 选中行 | 报表工具栏按钮与行数据 | `report/report-row-data-toolbar.md` | approved | `reportform` |
285
+ | hyperLinkClick, 钻取联查, BillShowParameter, ReportShowParameter, filterContainerInit, CommonFilterColumn, 过滤锁定 | 报表超链接钻取与过滤锁定 | `report/report-hyperlink-drill.md` | approved | `reportform,reportlist` |
286
+ | 小计, 合计, sumlevel, union, groupBy, packageData, 合计行标签 | 报表小计与合计行 | `report/report-subtotal-total.md` | approved | `reportlist,reportform` |
287
+ | setTreeReportList, 折叠树形行, rowid, pid, isgroupnode, expandAllNode, collapseAllNode | 折叠树形报表列表 | `report/report-tree-list.md` | approved | `reportform,reportlist` |
288
+ | beforeQuery, setAsyncTotal, setSelectedAll, setAsyncDataCount, getCustomFilter, 大报表 | 报表查询开关 | `report/report-async-query.md` | approved | `reportform,reportlist` |
289
+ | afterQuery, PieChart, PieSeries, ItemValue, 报表图表, 前 N 名 | 报表查询后联动图表 | `report/report-chart.md` | approved | `reportform` |
290
+ | select, groupBy, union, addField, copy, RowMeta, createDataSet, 双数据源, UnknownType | 报表 DataSet 组装 | `report/report-dataset-assembly.md` | approved | `reportlist` |
291
+ | AbstractPrintPlugin, afterLoadData, loadCustomData, ReportListModel, DataRowSet, 报表打印 | 报表打印数据 | `report/report-print-data.md` | approved | `printplugin` |
283
292
 
284
293
  ## ①① KWC 控制器场景(kwc/)
285
294
 
@@ -42,45 +42,49 @@ import kd.bos.entity.datamodel.events.PropertyChangedArgs;
42
42
  import java.util.stream.Collectors;
43
43
 
44
44
  public class AllContractFileBillPlugin extends AbstractBillPlugIn {
45
+ private static final String ATTACHMENT = "attachment";
46
+
45
47
  @Override
46
48
  public void propertyChanged(PropertyChangedArgs e) {
47
49
  super.propertyChanged(e);
48
50
  String formId = this.getView().getEntityId();
49
51
  String fileEntry = "cngc_entryentity";
50
- String fileFiled = "attachment";
52
+ String fileField = ATTACHMENT;
51
53
  String fileName = "attachname";
52
54
 
53
55
  // 根据表单ID映射不同的字段名
54
56
  switch (formId) {
55
57
  case "mscon_contract":
56
58
  fileEntry = "attentry";
57
- fileFiled = "attachment";
58
- fileName = "attachment";
59
+ fileField = ATTACHMENT;
60
+ fileName = ATTACHMENT;
59
61
  break;
60
62
  case "mscon_reviewtask":
61
63
  fileEntry = "attentry";
62
- fileFiled = "attachment";
64
+ fileField = ATTACHMENT;
63
65
  fileName = "attachmentname";
64
66
  break;
65
67
  case "cngc_signoff_cancel":
66
68
  fileEntry = "entryentity";
67
- fileFiled = "cngc_fj";
69
+ fileField = "cngc_fj";
68
70
  fileName = "cngc_attachmentname";
69
71
  break;
70
- // 其他表单类型映射...
72
+ default:
73
+ // 未列出的表单沿用默认字段映射。
74
+ break;
71
75
  }
72
76
 
73
- if (fileFiled.equalsIgnoreCase(e.getProperty().getName())) {
74
- setFileName(fileEntry, fileFiled, fileName);
77
+ if (fileField.equalsIgnoreCase(e.getProperty().getName())) {
78
+ setFileName(fileEntry, fileField, fileName);
75
79
  }
76
80
  }
77
81
 
78
- private void setFileName(String fileEntry, String fileFiled, String fileName) {
79
- DynamicObject this_model = this.getModel().getDataEntity(true);
80
- DynamicObjectCollection this_model_col = this_model.getDynamicObjectCollection(fileEntry);
81
- this_model_col.stream().forEach(item -> {
82
+ private void setFileName(String fileEntry, String fileField, String fileName) {
83
+ DynamicObject dataEntity = this.getModel().getDataEntity(true);
84
+ DynamicObjectCollection entries = dataEntity.getDynamicObjectCollection(fileEntry);
85
+ entries.stream().forEach(item -> {
82
86
  MulBasedataDynamicObjectCollection attachment =
83
- (MulBasedataDynamicObjectCollection) item.get(fileFiled);
87
+ (MulBasedataDynamicObjectCollection) item.get(fileField);
84
88
  String fileNames = attachment.stream()
85
89
  .map(i -> ((DynamicObject) i.get("fbasedataid")).get("name").toString())
86
90
  .collect(Collectors.joining(";"));
@@ -44,9 +44,9 @@ import kd.bos.url.UrlService;
44
44
  import java.util.Arrays;
45
45
 
46
46
  public class WhPictureSaveSubmitAuditFormPlugin extends AbstractBillPlugIn {
47
- private static final String save = "bar_save";
48
- private static final String submit = "bar_submit";
49
- private static final String audit = "bar_audit";
47
+ private static final String SAVE = "bar_save";
48
+ private static final String SUBMIT = "bar_submit";
49
+ private static final String AUDIT = "bar_audit";
50
50
  private static final String PICTURE = "cngc_picture";
51
51
 
52
52
  @Override
@@ -55,7 +55,7 @@ public class WhPictureSaveSubmitAuditFormPlugin extends AbstractBillPlugIn {
55
55
  String itemKey = evt.getItemKey();
56
56
  DynamicObject dataEntity = this.getView().getModel().getDataEntity();
57
57
 
58
- if (Arrays.asList(save, submit, audit).contains(itemKey)) {
58
+ if (Arrays.asList(SAVE, SUBMIT, AUDIT).contains(itemKey)) {
59
59
  // 从基础资料查询图片
60
60
  DynamicObject[] picturesIds = BusinessDataServiceHelper.load(
61
61
  "ide_pictureresediter", "id,fnumber,fname",
@@ -21,7 +21,7 @@ related_apis: ["FilterGrid.SetValue", "FilterCondition", "SerializationUtils.fro
21
21
  ## 涉及的核心对象(必读)
22
22
  | 对象 | 用途 | 文档路径 |
23
23
  |------|------|---------|
24
- | FilterGrid | 通用过滤控件,接收 FilterCondition 对象 | output/platform/form/core/view.md |
24
+ | FilterGrid | 通用过滤控件,接收 FilterCondition 对象 | knowledge/cosmic/platform/core/view.md |
25
25
  | FilterCondition | 过滤条件数据对象 | — |
26
26
  | SerializationUtils | JSON 反序列化工具 | — |
27
27
 
@@ -42,13 +42,12 @@ import kd.bos.orm.query.QFilter;
42
42
 
43
43
  @Override
44
44
  public void filterColumnSetFilter(SetFilterEvent args) {
45
- System.err.println("filterColumnSetFilter");
46
45
  if ("basedatafield2.name".equals(args.getFieldName()))
47
46
  {
48
- sargs.addCustomQFilter(new QFilter("name", QFilter.equals, "test123"));
47
+ args.addCustomQFilter(new QFilter("name", QFilter.equals, "test123"));
49
48
  }
50
49
 
51
- // 基础资料依赖于上面的选择字段orgfield1,将orgfield1的已选中值添加到basedatafield2
50
+ // 基础资料依赖于上面的选择字段orgfield1,将orgfield1的已选中值添加到basedatafield2
52
51
  if ("basedatafield2.name".equals(args.getFieldName())) {
53
52
  FilterColumnSetFilterEvent args2 = (FilterColumnSetFilterEvent) args;
54
53
  args.addCustomQFilter(new QFilter("name", QFilter.equals, args2.getCommonFilterValue("orgfield1.number")));
@@ -43,7 +43,6 @@ import kd.bos.form.events.FilterContainerInitArgs;
43
43
 
44
44
  @Override
45
45
  public void filterContainerInit(FilterContainerInitArgs args) {
46
- System.err.println("filterContainerInit");
47
46
  FilterColumn filterColumn = args.getFilterColumn("datefield");
48
47
  filterColumn.setDefaultValues("2019-1-30", "2019-1-31");
49
48
  FilterColumn filterColumn2 = new FilterColumn("textfield");
@@ -41,7 +41,6 @@ import kd.bos.orm.query.QFilter;
41
41
 
42
42
  @Override
43
43
  public void filterContainerBeforeF7Select(BeforeFilterF7SelectEvent args) {
44
- System.err.println("filterContainerBeforeF7Select");
45
44
  if ("basedatafield2.name".equals(args.getFieldName()))
46
45
  args.addCustomQFilter(new QFilter("name", QFilter.equals, "test123"));
47
46
 
@@ -53,12 +53,11 @@ import kd.bos.form.events.FilterContainerSearchClickArgs;
53
53
 
54
54
  @Override
55
55
  public void filterContainerSearchClick(FilterContainerSearchClickArgs args) {
56
- System.err.println("filterContainerSearchClick");
57
- System.err.println(args.getFilterValue("datefield"));
58
- System.err.println(args.getFastFilterValues());
59
- System.err.println(args.getQFilter("datefield"));
60
- System.err.println(args.getSelectMainOrgIds());
61
- args.addConstFilter("datefield", CompareTypeEnum.TODAY);
56
+ // 通过 getFilterValue / getFastFilterValues / getQFilter / getSelectMainOrgIds 读取值;
57
+ // 不通过 System.out/err 打印,DCS 不允许这种写法(CVE-KD-0209-1)
58
+ if (args.getFilterValue("datefield") == null) {
59
+ args.addConstFilter("datefield", CompareTypeEnum.TODAY);
60
+ }
62
61
  args.addFastFilter("textfield", "test");
63
62
  args.addFilter("textfield", CompareTypeEnum.EQUAL, "123");
64
63
  super.filterContainerSearchClick(args);
@@ -46,7 +46,7 @@ public class OpenBillFromListPlugin extends AbstractListPlugin {
46
46
  super.itemClick(evt);
47
47
  if ("btn_open".equals(evt.getItemKey())) {
48
48
  ListSelectedRowCollection selectedRows = this.getSelectedRows();
49
- if (selectedRows.size() == 0) {
49
+ if (selectedRows.isEmpty()) {
50
50
  this.getView().showMessage("请选择数据");
51
51
  return;
52
52
  }
@@ -44,7 +44,6 @@ beforecreatelistcolumnsargs.getDynamicTextListColumns()
44
44
  ```java
45
45
  import kd.bos.form.events.BeforeCreateListColumnsArgs;
46
46
  import kd.bos.list.ComboListColumn;
47
- import kd.bos.list.IListColumn;
48
47
  import kd.bos.list.MergeListColumn;
49
48
 
50
49
  @Override
@@ -55,12 +54,6 @@ public void beforeCreateListColumns(BeforeCreateListColumnsArgs beforecreatelist
55
54
  mergeListColumn.setKey("mergelistcolumn");
56
55
  mergeListColumn.getItems().add(comboListColumn);
57
56
  beforecreatelistcolumnsargs.addListColumn(mergeListColumn);
58
- IListColumn listColumn = beforecreatelistcolumnsargs.getListColumn("textfield");
59
- System.err.println("beforeCreateListColumns");
60
- System.err.println(listColumn);
61
- System.err.println(beforecreatelistcolumnsargs.getDynamicTextListColumns());
62
- System.err.println(beforecreatelistcolumnsargs.getMergeListColumns());
63
- System.err.println(beforecreatelistcolumnsargs.getListGroupColumns());
64
57
  super.beforeCreateListColumns(beforecreatelistcolumnsargs);
65
58
  }
66
59
  ```