@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
@@ -69,26 +69,31 @@ import kd.bos.entity.plugin.args.BeforeOperationArgs;
69
69
  import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
70
70
  import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
71
71
  import kd.bos.entity.plugin.args.RollbackOperationArgs;
72
+ import kd.bos.logging.Log;
73
+ import kd.bos.logging.LogFactory;
72
74
 
73
75
  /**
74
- * 演示操作插件全部事件的捕获及触发时机
76
+ * Demonstrates capturing all events of an operation plugin and their trigger timing
75
77
  *
76
78
  * @remark
77
- * 本示例代码,捕捉的事件,由前往后触发
79
+ * The events captured in this sample code are triggered from first to last
78
80
  *
79
81
  */
80
82
  public class OperationEventSample extends AbstractOperationServicePlugIn {
81
83
 
84
+ private static final Log LOG = LogFactory.getLog(OperationEventSample.class);
85
+
82
86
  /**
83
- * 操作执行,加载单据数据包之前,触发此事件;
87
+ * This event is triggered before the operation executes and before the bill data package is loaded;
84
88
  *
85
89
  * @remark
86
- * 在单据列表上执行单据操作,传入的是单据内码;
87
- * 系统需要先根据传入的单据内码,加载单据数据包,其中只包含操作要用到的字段,然后再执行操作;
88
- * 在加载单据数据包之前,操作引擎触发此事件;
90
+ * When executing bill operations on the bill list, bill internal codes are passed in;
91
+ * The system first needs to load the bill data package based on the incoming bill internal codes,
92
+ * which only contains the fields needed for the operation, before executing the operation;
93
+ * Before loading the bill data package, the operation engine triggers this event;
89
94
  *
90
- * 插件需要在此事件,添加需要用到的字段;
91
- * 否则,系统加载的单据数据包,可能没有插件要用到的字段值,从而引发中断
95
+ * The plugin must add the fields it needs in this event;
96
+ * Otherwise, the system-loaded bill data package may not contain the field values required by the plugin, causing an interruption
92
97
  */
93
98
  @Override
94
99
  public void onPreparePropertys(PreparePropertysEventArgs e) {
@@ -96,10 +101,10 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
96
101
  }
97
102
 
98
103
  /**
99
- * 构建好操作校验器之后,执行校验之前,触发此事件;
104
+ * This event is triggered after building the operation validators and before executing validation;
100
105
  *
101
106
  * @remark
102
- * 插件可以在此事件,增加自定义操作校验器,或者去掉内置的校验器
107
+ * The plugin can add custom operation validators or remove built-in validators in this event
103
108
  */
104
109
  @Override
105
110
  public void onAddValidators(AddValidatorsEventArgs e) {
@@ -107,10 +112,10 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
107
112
  }
108
113
 
109
114
  /**
110
- * 操作校验通过之后,开启事务之前,触发此事件;
115
+ * This event is triggered after operation validation passes and before the transaction begins;
111
116
  *
112
117
  * @remark
113
- * 插件可以在此事件,对通过校验的数据,进行整理
118
+ * The plugin can organize the data that passed validation in this event
114
119
  */
115
120
  @Override
116
121
  public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
@@ -118,10 +123,11 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
118
123
  }
119
124
 
120
125
  /**
121
- * 操作校验通过,开启了事务,准备把数据提交到数据库之前触发此事件;
126
+ * This event is triggered after operation validation passes, the transaction has begun,
127
+ * and before data is ready to be committed to the database;
122
128
  *
123
129
  * @remark
124
- * 可以在此事件,进行数据同步处理
130
+ * Data synchronization processing can be performed in this event
125
131
  */
126
132
  @Override
127
133
  public void beginOperationTransaction(BeginOperationTransactionArgs e) {
@@ -129,10 +135,11 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
129
135
  }
130
136
 
131
137
  /**
132
- * 单据数据已经提交到数据库之后,事务为提交之前,触发此事件;
138
+ * This event is triggered after bill data has been committed to the database
139
+ * and before the transaction is committed;
133
140
  *
134
141
  * @remark
135
- * 可以在此事件,进行数据同步处理;
142
+ * Data synchronization processing can be performed in this event;
136
143
  */
137
144
  @Override
138
145
  public void endOperationTransaction(EndOperationTransactionArgs e) {
@@ -140,10 +147,11 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
140
147
  }
141
148
 
142
149
  /**
143
- * 操作事务提交失败,事务回滚之后触发此事件;
150
+ * This event is triggered after operation transaction commit fails and the transaction has rolled back;
144
151
  *
145
152
  * @remark
146
- * 该方法在事务异常后执行,插件可以在此事件,对没有事务保护的数据更新进行补偿
153
+ * This method executes after a transaction exception; the plugin can compensate
154
+ * for data updates without transaction protection in this event
147
155
  */
148
156
  @Override
149
157
  public void rollbackOperation(RollbackOperationArgs e) {
@@ -151,10 +159,10 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
151
159
  }
152
160
 
153
161
  /**
154
- * 操作执行完毕,事务提交之后,触发此事件;
162
+ * This event is triggered after the operation has completed and the transaction has been committed;
155
163
  *
156
164
  * @remark
157
- * 插件可以在此事件,处理操作后续事情,与操作事务无关
165
+ * The plugin can handle post-operation tasks in this event, unrelated to the operation transaction
158
166
  */
159
167
  @Override
160
168
  public void afterExecuteOperationTransaction(AfterOperationArgs e) {
@@ -162,8 +170,8 @@ public class OperationEventSample extends AbstractOperationServicePlugIn {
162
170
  }
163
171
 
164
172
  private void printEventInfo(String eventName, String argString){
165
- String msg = String.format("%s : %s", eventName, argString);
166
- System.out.println(msg);
173
+ // 使用平台日志,避免 DCS 禁止的 System.out(CVE-KD-0209-1)
174
+ LOG.info(String.format("%s : %s", eventName, argString));
167
175
  }
168
176
  }
169
177
  ```
@@ -0,0 +1,133 @@
1
+ ---
2
+ version: "1.0.0"
3
+ framework_version: "8.0.1"
4
+ source_doc: "报表插件示例 示例6、示例10"
5
+ last_updated: "2026-10-19"
6
+ status: "approved"
7
+ scene_name: "报表查询开关:异步合计、全选与自定义过滤"
8
+ related_apis: ["AbstractReportFormPlugin.beforeQuery", "ReportList.setAsyncTotal", "ReportList.setSelectedAll", "ReportQueryParam.getCustomFilter", "ReportQueryParam.setCustomFilter", "FilterInfo.getQFilters", "QueryServiceHelper.queryDataSet"]
9
+ topic: "报表表单插件"
10
+ ---
11
+
12
+ # 场景:报表查询开关:异步合计、全选与自定义过滤
13
+
14
+ ## 适用情况
15
+ 大报表要尽快显示首页并保持可用:合计行不拖慢数据行,用户可以全选所有行,总行数在后台统计。这些是报表列表控件上的开关,在 `reportform` 插件的 `beforeQuery` 中为即将执行的查询设置。`beforeQuery` 也是表单插件追加自身条件的地方——它向查询参数追加,从不替换。
16
+
17
+ ## 事件/方法说明
18
+
19
+ - `beforeQuery(ReportQueryParam)`:每次查询前执行;`this.getControl("reportlistap")` 返回 `ReportList`
20
+ - `ReportList.setAsyncTotal(true)`:异步计算合计行,不拖慢数据行
21
+ - `ReportList.setSelectedAll(true)`:允许用户全选结果中的所有行(读取方式见 `report-row-data-toolbar.md`)
22
+ - `ReportList.setAsyncDataCount(true)`:异步统计总行数,首页先于总数显示。报表示例使用了它,但 8.0 SDK 没有这个方法:其 `lib/bos` 与 `lib/trd` jar 中没有任何类提到这个名字
23
+ - `ReportQueryParam.getCustomFilter()` / `setCustomFilter(List<QFilter>)`:查询参数带给取数插件的一组额外 `QFilter` 条件
24
+
25
+ 三个列表开关默认都是关闭的。
26
+
27
+ ## 方法签名
28
+ ```java
29
+ @Override
30
+ public void beforeQuery(ReportQueryParam queryParam)
31
+ ```
32
+
33
+ ## 代码示例
34
+ `extracted` `needs-verification`
35
+
36
+ 查询前打开列表选项:
37
+
38
+ ```java
39
+ package kd.bos.plugin.sample.report.bizcase;
40
+
41
+ import kd.bos.entity.report.ReportQueryParam;
42
+ import kd.bos.report.ReportList;
43
+ import kd.bos.report.plugin.AbstractReportFormPlugin;
44
+
45
+ public class AsyncQueryReportFormPlugin extends AbstractReportFormPlugin {
46
+
47
+ @Override
48
+ public void beforeQuery(ReportQueryParam queryParam) {
49
+ super.beforeQuery(queryParam);
50
+ ReportList reportList = this.getControl("reportlistap");
51
+ // 合计行异步计算,不拖慢数据行
52
+ reportList.setAsyncTotal(true);
53
+ // 用户可以全选结果中的所有行
54
+ reportList.setSelectedAll(true);
55
+ // 总行数在首页之后异步到达需要 setAsyncDataCount,8.0 SDK 没有它:
56
+ // 只在 references/sdk-inspection.md 能找到它的更新目标版本上
57
+ // 启用。
58
+ // reportList.setAsyncDataCount(true);
59
+ }
60
+ }
61
+ ```
62
+
63
+ 在表单插件中追加条件,在取数插件中应用它:
64
+
65
+ ```java
66
+ package kd.bos.plugin.sample.report.bizcase;
67
+
68
+ import java.util.ArrayList;
69
+ import java.util.List;
70
+
71
+ import kd.bos.entity.report.ReportQueryParam;
72
+ import kd.bos.orm.query.QCP;
73
+ import kd.bos.orm.query.QFilter;
74
+ import kd.bos.report.plugin.AbstractReportFormPlugin;
75
+
76
+ public class AuditedOnlyReportFormPlugin extends AbstractReportFormPlugin {
77
+
78
+ @Override
79
+ public void beforeQuery(ReportQueryParam queryParam) {
80
+ super.beforeQuery(queryParam);
81
+ // 由表单侧决定的条件,这里来自过滤面板的一个选项
82
+ if (!Boolean.TRUE.equals(this.getModel().getValue("auditedonly"))) {
83
+ return;
84
+ }
85
+ List<QFilter> customFilters = queryParam.getCustomFilter();
86
+ if (customFilters == null) {
87
+ customFilters = new ArrayList<>(1);
88
+ queryParam.setCustomFilter(customFilters);
89
+ }
90
+ // 追加:用户自己的条件仍在 queryParam.getFilter() 中
91
+ customFilters.add(new QFilter("billstatus", QCP.equals, "C"));
92
+ }
93
+ }
94
+ ```
95
+
96
+ ```java
97
+ package kd.bos.plugin.sample.report.bizcase;
98
+
99
+ import java.util.ArrayList;
100
+ import java.util.List;
101
+
102
+ import kd.bos.algo.DataSet;
103
+ import kd.bos.entity.report.AbstractReportListDataPlugin;
104
+ import kd.bos.entity.report.ReportQueryParam;
105
+ import kd.bos.orm.query.QFilter;
106
+ import kd.bos.servicehelper.QueryServiceHelper;
107
+
108
+ public class AuditedOnlyReportListDataPlugin extends AbstractReportListDataPlugin {
109
+
110
+ private static final String ALGO_NAME = "xxx.report.auditedonly";
111
+ private static final String ENTITY_NUMBER = "xxx_salesorder";
112
+
113
+ @Override
114
+ public DataSet query(ReportQueryParam queryParam, Object selectedObj) throws Throwable {
115
+ List<QFilter> filters = new ArrayList<>(queryParam.getFilter().getQFilters());
116
+ // ……过滤面板条件照常在这里追加
117
+ // 取数插件自己执行查询,所以由它自己应用自定义过滤
118
+ if (queryParam.getCustomFilter() != null) {
119
+ filters.addAll(queryParam.getCustomFilter());
120
+ }
121
+ return QueryServiceHelper.queryDataSet(ALGO_NAME, ENTITY_NUMBER, "billno, billstatus, amount",
122
+ filters.toArray(new QFilter[filters.size()]), queryParam.getSortInfo());
123
+ }
124
+ }
125
+ ```
126
+
127
+ ## 注意事项
128
+ - 这些开关属于即将执行的查询,所以在 `beforeQuery` 中设置;大报表建议打开
129
+ - `setAsyncDataCount` 来自报表示例,8.0 SDK 中不存在:在 8.0 上源码编译失败,跳过编译时则在加载时失败,编译时会给出警告(`PLUGIN_SOURCE_ABSENT_FROM_8_0_SDK`)。只在 `references/sdk-inspection.md` 能找到它的更新目标版本上使用
130
+ - `beforeQuery` 只追加,从不替换:`queryParam.setFilter(new FilterInfo())`,或在已有列表上 `setCustomFilter(new ArrayList<>())`,都会丢掉已有的全部条件
131
+ - 自定义过滤列表随查询参数到达取数插件,而取数插件自己构造查询:在 `beforeQuery` 里加的条件,要等 `query()` 把 `getCustomFilter()` 加进自己的过滤后才起作用。报表示例写的是 `queryParam.getFilter().getCustomFilter()`;8.0 SDK 把该方法声明在 `ReportQueryParam` 上,`FilterInfo` 上没有,所以调用 `queryParam.getCustomFilter()`
132
+ - 报表每次查询都需要的规则放在 `query()` 里;自定义过滤列表适合由表单侧决定的条件——来自用户的面板选项,或来自表单插件已经算出的结果(比如它有权限的组织)
133
+ - 结果非常大时,再考虑分批取数(`report-batch-query.md`)以及表头过滤 / 排序的行数上限(`report-total-type.md`)
@@ -5,7 +5,7 @@ source_doc: "bos-runtime-plugin 报表示例"
5
5
  last_updated: "2026-04-03"
6
6
  status: "approved"
7
7
  scene_name: "报表分批取数"
8
- related_apis: ["AbstractReportListDataPlugin", "queryBatchBy", "IReportBatchQueryInfo", "query", "ReportQueryParam", "ORM", "DataSet", "QFilter", "QCP"]
8
+ related_apis: ["AbstractReportListDataPlugin.queryBatchBy", "AbstractReportListDataPlugin.query", "ReportQueryParam.byBatchInfo", "ReportQueryParam.getSortInfo", "FilterInfo.getHeadFilters", "IReportBatchQueryInfo", "QueryServiceHelper.queryDataSet", "DataSet", "QFilter", "QCP"]
9
9
  topic: "报表数据查询"
10
10
  ---
11
11
 
@@ -51,14 +51,17 @@ import kd.bos.algo.Row;
51
51
  import kd.bos.entity.report.AbstractReportListDataPlugin;
52
52
  import kd.bos.entity.report.IReportBatchQueryInfo;
53
53
  import kd.bos.entity.report.ReportQueryParam;
54
- import kd.bos.orm.ORM;
55
54
  import kd.bos.orm.query.QCP;
56
55
  import kd.bos.orm.query.QFilter;
56
+ import kd.bos.servicehelper.QueryServiceHelper;
57
57
 
58
58
  public class ReportBatchQuerySample extends AbstractReportListDataPlugin {
59
59
 
60
- private static final int COUNT_PER_BATCH = 10000;
60
+ private static final int COUNT_PER_BATCH = 100;
61
61
  private static final int MAX_ROW_COUNT_CACHED = 100000;
62
+ private static final String ENTITY_NUMBER = "kdtest_report001";
63
+ private static final String BILL_NO = "billno";
64
+ private static final String SELECTED_FIELDS = "billno,kdtest_integerfield,kdtest_decimalfield,kdtest_textfield";
62
65
 
63
66
  @Override
64
67
  public DataSet queryBatchBy(ReportQueryParam queryParam) {
@@ -73,12 +76,11 @@ public class ReportBatchQuerySample extends AbstractReportListDataPlugin {
73
76
  filters.addAll(queryParam.getFilter().getHeadFilters());
74
77
  }
75
78
 
76
- // 查询分批依据字段(如单据编号)
77
- ORM orm = ORM.create();
78
- DataSet dataSet = orm.queryDataSet(getClass().getName(),
79
- "kdtest_report001", "billno",
80
- filters.toArray(new QFilter[0]),
81
- queryParam.getSortInfo(), 100000000, null);
79
+ // 查询分批依据字段(如单据编号),排好序,每批才是连续的一段
80
+ DataSet dataSet = QueryServiceHelper.queryDataSet(getClass().getName(),
81
+ ENTITY_NUMBER, BILL_NO,
82
+ filters.toArray(new QFilter[filters.size()]),
83
+ BILL_NO, 100000000);
82
84
 
83
85
  // 设置分批参数
84
86
  IReportBatchQueryInfo batchInfo = queryParam.byBatchInfo();
@@ -113,13 +115,11 @@ public class ReportBatchQuerySample extends AbstractReportListDataPlugin {
113
115
  for (Row row : currentBatchRows) {
114
116
  billNos.add(row.getString(0));
115
117
  }
116
- filters.add(new QFilter("billno", QCP.in, billNos));
118
+ filters.add(new QFilter(BILL_NO, QCP.in, billNos));
117
119
 
118
- ORM orm = ORM.create();
119
- String selectedField = "billno,kdtest_integerfield,kdtest_decimalfield,kdtest_textfield";
120
- return orm.queryDataSet(getClass().getName(),
121
- "kdtest_report001", selectedField,
122
- filters.toArray(new QFilter[0]),
120
+ return QueryServiceHelper.queryDataSet(getClass().getName(),
121
+ ENTITY_NUMBER, SELECTED_FIELDS,
122
+ filters.toArray(new QFilter[filters.size()]),
123
123
  queryParam.getSortInfo());
124
124
  }
125
125
 
@@ -129,20 +129,24 @@ public class ReportBatchQuerySample extends AbstractReportListDataPlugin {
129
129
  filters.addAll(queryParam.getFilter().getHeadFilters());
130
130
  }
131
131
 
132
- ORM orm = ORM.create();
133
- String selectedField = "billno,kdtest_integerfield,kdtest_decimalfield,kdtest_textfield";
134
- return orm.queryDataSet(getClass().getName(),
135
- "kdtest_report001", selectedField,
136
- filters.toArray(new QFilter[0]),
132
+ return QueryServiceHelper.queryDataSet(getClass().getName(),
133
+ ENTITY_NUMBER, SELECTED_FIELDS,
134
+ filters.toArray(new QFilter[filters.size()]),
137
135
  queryParam.getSortInfo());
138
136
  }
139
137
  }
140
138
  ```
141
139
 
142
140
  ## 注意事项
141
+ - 按报表示例给出的原则选择分批依据:
142
+ 1. 用来分批的字段,每批对应的报表数据要较为均衡,避免一批耗尽内存
143
+ 2. 尽量采用必录条件或排序字段作为分批依据
144
+ 3. 分批依据字段可以是一个或多个,但 `queryBatchBy` 返回的 DataSet 会全部缓存在内存中:只返回分批依据列,并控制数据量
145
+ 4. 返回的分批依据集要先排序,交给 `query` 的每一批才是连续的一段
146
+ - 分批不等于分页:分批是数据分批加载,分页是列表翻页,通常一批数据可供几十到几百个分页
143
147
  - `queryBatchBy` 返回 null 表示不启用分批取数,框架将直接调用 `query` 获取全量数据
144
148
  - `queryBatchBy` 返回的 DataSet 每行代表一个批次标识,框架按 `countPerBatch` 分批后逐批调用 `query`,每批数据作为 `query` 的 `selectedObj` 参数传入
145
- - 分批模式下 `query` 方法可通过 `selectedObj` 参数获取当前批次数据,也可通过 `queryParam.byBatchInfo().getCurrentBatchRows()` 获取当前批次的行数据
146
- - `setCountPerBatch` 控制每批数据条数,建议根据数据量和内存情况设置(如 10000)
149
+ - 分批模式下 `query` 方法可通过 `selectedObj` 参数获取当前批次数据,也可通过 `queryParam.byBatchInfo().getCurrentBatchRows()` 获取当前批次的行数据——报表示例用的是 `getCurrentBatchRows()`。两者都不读的分批 `query` 每批都返回完整结果,报表会把每行重复显示批次数那么多遍;编译边界会拒绝它(`PLUGIN_SOURCE_BATCH_NOT_NARROWED`)
150
+ - `setCountPerBatch` 设置多少行分批依据组成一批,一批中的每行分批依据都会成为 `query` 里 `in` 条件的一个值:按每个依据值带出的行数来定,并让 `in` 列表保持较短(报表示例每批 100 个物料)
147
151
  - `setMaxRowCountCached` 控制最大缓存行数,默认 10 万行
148
152
  - 此插件不继承 AbstractFormPlugin,不能调用 `getView()` 等表单方法
@@ -0,0 +1,112 @@
1
+ ---
2
+ version: "1.0.0"
3
+ framework_version: "8.0.1"
4
+ source_doc: "标品报表案例 06"
5
+ last_updated: "2026-10-19"
6
+ status: "approved"
7
+ scene_name: "报表查询后联动图表"
8
+ related_apis: ["AbstractReportFormPlugin.afterQuery", "PieChart.clearData", "PieChart.createPieSeries", "PieChart.setTitlePropValue", "PieChart.setLegendPropValue", "PieChart.refresh", "PieSeries.setData", "PieSeries.setPropValue", "PieSeries.setRadius", "DataSet.copy", "DataSet.filter", "DataSet.groupBy", "DataSet.orderBy", "GroupbyDataSet.sum", "GroupbyDataSet.finish", "QueryServiceHelper.queryDataSet"]
9
+ topic: "报表表单插件"
10
+ ---
11
+
12
+ # 场景:报表查询后联动图表
13
+
14
+ ## 适用情况
15
+ 报表表单在列表旁边放了一个图表——逾期金额前五的客户、各账龄分组的占比——图表必须与列表使用同样的条件。`reportform` 插件在 `afterQuery` 中绘制它,此时查询已经执行:取出报表表单上布局好的图表控件,聚合数值,填充系列,刷新控件。
16
+
17
+ ## 事件/方法说明
18
+
19
+ - `afterQuery(ReportQueryParam)`:在取数插件的查询之后执行;参数里是列表查询所用的同样条件
20
+ - `this.getControl(key)`:报表表单上布局的图表控件,例如 `PieChart`
21
+ - `PieChart.clearData()` → `createPieSeries(title)` → `PieSeries.setData(ItemValue[])` → `refresh()`:一次完整的绘制;`new ItemValue(name, value)` 是一块扇区
22
+ - `setTitlePropValue(prop, value)`、`setLegendPropValue(prop, value)`、`PieSeries.setPropValue(prop, value)`、`PieSeries.setRadius(inside, outside)`:样式
23
+ - `DataSet.groupBy(keys).sum(field).finish()` 与 `orderBy(new String[]{"field desc"})`:图表自己的聚合,因为列表的行通常比图表要细
24
+
25
+ ## 方法签名
26
+ ```java
27
+ @Override
28
+ public void afterQuery(ReportQueryParam queryParam)
29
+ ```
30
+
31
+ ## 代码示例
32
+ `extracted` `needs-verification`
33
+
34
+ 逾期金额前五的客户加"其他",取自列表的条件:
35
+
36
+ ```java
37
+ package kd.bos.plugin.sample.report.bizcase;
38
+
39
+ import java.math.BigDecimal;
40
+ import java.util.ArrayList;
41
+ import java.util.List;
42
+
43
+ import kd.bos.algo.DataSet;
44
+ import kd.bos.algo.Row;
45
+ import kd.bos.dataentity.resource.ResManager;
46
+ import kd.bos.entity.report.ReportQueryParam;
47
+ import kd.bos.form.chart.ItemValue;
48
+ import kd.bos.form.chart.PieChart;
49
+ import kd.bos.form.chart.PieSeries;
50
+ import kd.bos.orm.query.QFilter;
51
+ import kd.bos.report.plugin.AbstractReportFormPlugin;
52
+ import kd.bos.servicehelper.QueryServiceHelper;
53
+
54
+ public class OverdueChartReportFormPlugin extends AbstractReportFormPlugin {
55
+
56
+ private static final String ALGO_NAME = "xxx.report.overduechart";
57
+ private static final String ENTITY_NUMBER = "xxx_arbill";
58
+ private static final int TOP = 5;
59
+
60
+ @Override
61
+ public void afterQuery(ReportQueryParam queryParam) {
62
+ super.afterQuery(queryParam);
63
+ List<QFilter> filters = new ArrayList<>(queryParam.getFilter().getQFilters());
64
+ // ……与取数插件相同的过滤面板条件,图表才与列表一致
65
+
66
+ // 每个客户一行:图表自己的聚合
67
+ DataSet amounts = QueryServiceHelper.queryDataSet(ALGO_NAME, ENTITY_NUMBER,
68
+ "customer.name as customer, overdueamt", filters.toArray(new QFilter[filters.size()]), null)
69
+ .groupBy(new String[]{"customer"}).sum("overdueamt").finish()
70
+ .orderBy(new String[]{"overdueamt desc"});
71
+ List<ItemValue> items = new ArrayList<>(TOP + 1);
72
+ BigDecimal others = BigDecimal.ZERO;
73
+ int index = 0;
74
+ try {
75
+ while (amounts.hasNext()) {
76
+ Row row = amounts.next();
77
+ BigDecimal amount = row.getBigDecimal("overdueamt") == null ? BigDecimal.ZERO : row.getBigDecimal("overdueamt");
78
+ // The first five are slices of their own; the rest add up to "其他"
79
+ if (index++ < TOP) {
80
+ items.add(new ItemValue(row.getString("customer"), amount));
81
+ } else {
82
+ others = others.add(amount);
83
+ }
84
+ }
85
+ } finally {
86
+ amounts.close();
87
+ }
88
+ if (others.signum() != 0) {
89
+ items.add(new ItemValue(ResManager.loadKDString("其他", "OverdueChartReportFormPlugin_0", "xxx-report"), others));
90
+ }
91
+ if (items.isEmpty()) {
92
+ // 空图表也需要一块占位
93
+ items.add(new ItemValue(ResManager.loadKDString("无数据", "OverdueChartReportFormPlugin_1", "xxx-report"), 1));
94
+ }
95
+ PieChart chart = this.getControl("overduechart");
96
+ chart.clearData();
97
+ PieSeries series = chart.createPieSeries(ResManager.loadKDString("逾期金额", "OverdueChartReportFormPlugin_2", "xxx-report"));
98
+ series.setData(items.toArray(new ItemValue[items.size()]));
99
+ chart.refresh();
100
+ }
101
+ }
102
+ ```
103
+
104
+ ## 注意事项
105
+ - 图表控件是元数据:在报表表单上布局,用它的标识调用 `getControl`;填充前 `clearData()` 清掉上一次查询的扇区,填充后 `refresh()` 绘制新的
106
+ - 数值要么来自基于 `queryParam` 条件的单独查询(如上),要么来自取数插件共享的 DataSet。标品通过静态 `ThreadLocal` 持有者共享,豁免了平台 PMD 规则 `KdThreadLocalNotAllowedRule`,而且之所以安全,只是因为查询与 `afterQuery` 在同一个请求的同一个线程上执行;如果你也这样共享,读完就移除,否则池化的线程会把它带给下一个请求
107
+ - 每次遍历都会消费 DataSet。两个图表读同一个 DataSet 时,在第一次遍历之前 `copy()`——`DataSet second = first.copy();`——并关闭插件自己持有的副本
108
+ - 标记为合计的行(`sumlevel` 为 1 和 2,见 `report-subtotal-total.md`)会被重复计算;先用 `filter("sumlevel=0")` 去掉它们
109
+ - 聚合之前可用 `DataSet.addField("balance-notdueamt", "overdueamt")` 以表达式派生一列
110
+ - 扇区名称里的百分比:用 `NumberFormat.getPercentInstance()` 格式化占比,拼到名称后面,例如"客户 A(12.34%)"
111
+ - 样式通过属性 map 设置:`setTitlePropValue("textStyle", map)`,`series.setPropValue("label", map)` 配合 `{"normal": {"show": false}}` 隐藏标签,`setLegendPropValue("right", 10)`,`series.setRadius("40%", "80%")` 画成环形
112
+ - 其他图表类型套路相同:`getControl`、一个系列、数据、`refresh()`