@shundoo-ai/dsh-cosmic 1.0.19 → 1.0.21
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.
- package/cordis.patch.yml +5 -5
- package/package.json +1 -1
- package/skills/cosmic-build/CHANGELOG.md +4 -0
- package/skills/cosmic-build/LOCAL-PATCHES.md +91 -40
- package/skills/cosmic-build/SKILL.md +46 -13
- package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +169 -0
- package/skills/cosmic-build/assets/platform-report-filters/platform.patch +98 -0
- package/skills/cosmic-build/assets/report-algo-benchmark/ReportAlgoBenchmark.java +48 -0
- package/skills/cosmic-build/assets/report-algo-benchmark/ReportBenchmarkLogFactory.java +7 -0
- package/skills/cosmic-build/examples/java-rules/CosmicEntryQuery.java +26 -0
- package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +35 -0
- package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +77 -0
- package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapter.java +25 -0
- package/skills/cosmic-build/examples/java-rules/CosmicTimeAdapterCheck.java +26 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/api/algo/GroupbyDataSet.md +47 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterInfo.md +12 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/api/entity/report/FilterItemInfo.md +2 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +2 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/java-type-contracts.md +11 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +18 -14
- package/skills/cosmic-build/knowledge/cosmic/platform/operation-plugin.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +17 -9
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/cross-entity-aggregate-writeback.md +2 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/pre-post-operation.md +15 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +24 -68
- package/skills/cosmic-build/knowledge/cosmic/platform/workflow-plugin.md +2 -7
- package/skills/cosmic-build/references/application-context.md +35 -1
- package/skills/cosmic-build/references/common-reference.md +1 -1
- package/skills/cosmic-build/references/compile-guide.md +55 -68
- package/skills/cosmic-build/references/delivery.md +59 -7
- package/skills/cosmic-build/references/execution-contract.md +38 -0
- package/skills/cosmic-build/references/form-discovery.md +7 -1
- package/skills/cosmic-build/references/java-plugin-delivery.md +32 -162
- package/skills/cosmic-build/references/operation-dispatch.md +17 -0
- package/skills/cosmic-build/references/plugin-handoff-input.md +131 -0
- package/skills/cosmic-build/references/plugin-runtime-routing.md +1 -1
- package/skills/cosmic-build/references/report-filter-contract.md +78 -0
- package/skills/cosmic-build/references/sdk-inspection.md +23 -0
- package/skills/cosmic-build/schemas/data-model-authoring.schema.json +2 -3
- package/skills/cosmic-build/scripts/_http_client.py +55 -55
- package/skills/cosmic-build/scripts/appconfig_load.py +2 -2
- package/skills/cosmic-build/scripts/apply_report_filter_extension.py +39 -0
- package/skills/cosmic-build/scripts/bootstrap_cosmic_context.py +37 -2
- package/skills/cosmic-build/scripts/compile_plugin_source.py +279 -156
- package/skills/cosmic-build/scripts/execution_binding.py +40 -0
- package/skills/cosmic-build/scripts/inspect_platform_sdk.py +169 -0
- package/skills/cosmic-build/scripts/kd_api.py +23 -22
- package/skills/cosmic-build/scripts/kd_auth.py +1 -1
- package/skills/cosmic-build/scripts/kd_env_loader.py +19 -10
- package/skills/cosmic-build/scripts/kd_token_cache.py +2 -2
- package/skills/cosmic-build/scripts/kingscript_sdk_sync.py +350 -0
- package/skills/cosmic-build/scripts/kingscript_source_gate.py +11 -8
- package/skills/cosmic-build/scripts/platform_api_contract.py +246 -11
- package/skills/cosmic-build/scripts/plugin_corpus/build_index.py +403 -0
- package/skills/cosmic-build/scripts/plugin_corpus/jvm_classfile.py +281 -0
- package/skills/cosmic-build/scripts/plugin_corpus/measure_api_usage.py +446 -0
- package/skills/cosmic-build/scripts/plugin_source_gate.py +48 -7
- package/skills/cosmic-build/scripts/plugin_target_sdk.py +45 -0
- package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +493 -47
- package/skills/cosmic-build/scripts/preview_url.py +35 -6
- package/skills/cosmic-build/scripts/query_plugin_handoff.py +250 -0
- package/skills/cosmic-build/scripts/register_plugins.py +28 -2
- package/skills/cosmic-build/scripts/render_output_cards.py +42 -9
- package/skills/cosmic-build/scripts/report_algo_benchmark.py +46 -0
- package/skills/cosmic-build/scripts/run.py +2 -2
- package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +43 -0
- package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +64 -0
- package/skills/cosmic-build/scripts/test/fixtures/java_context_booking_native.json +541 -0
- package/skills/cosmic-build/scripts/test/test_add_rule_business_contract.py +85 -14
- package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +12 -3
- package/skills/cosmic-build/scripts/test/test_build_meta_order.py +0 -16
- package/skills/cosmic-build/scripts/test/test_cli_continuation.py +87 -0
- package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +224 -3
- package/skills/cosmic-build/scripts/test/test_control_authoring.py +123 -4
- package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +141 -0
- package/skills/cosmic-build/scripts/test/test_data_model_contract.py +30 -5
- package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +2 -10
- package/skills/cosmic-build/scripts/test/test_dym_sync_background.py +11 -0
- package/skills/cosmic-build/scripts/test/test_dynamic_form_metadata_only_contract.py +59 -1
- package/skills/cosmic-build/scripts/test/test_guide_skeleton_contract.py +87 -43
- package/skills/cosmic-build/scripts/test/test_inspect_platform_sdk.py +71 -0
- package/skills/cosmic-build/scripts/test/test_kd_api.py +67 -19
- package/skills/cosmic-build/scripts/test/test_kingscript_sdk_sync.py +221 -0
- package/skills/cosmic-build/scripts/test/test_kingscript_source_gate.py +10 -0
- package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +18 -0
- package/skills/cosmic-build/scripts/test/test_long_session_regressions.py +116 -0
- package/skills/cosmic-build/scripts/test/test_mcp_cli.py +524 -0
- package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +141 -0
- package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +36 -2
- package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +161 -1
- package/skills/cosmic-build/scripts/test/test_plugin_business_contract.py +91 -0
- package/skills/cosmic-build/scripts/test/test_plugin_corpus.py +195 -0
- package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +346 -1
- package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +70 -0
- package/skills/cosmic-build/scripts/test/test_preview_url.py +44 -1
- package/skills/cosmic-build/scripts/test/test_property_batch.py +22 -0
- package/skills/cosmic-build/scripts/test/test_property_input_discovery.py +13 -11
- package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +160 -0
- package/skills/cosmic-build/scripts/test/test_register_plugins.py +31 -1
- package/skills/cosmic-build/scripts/test/test_render_output_cards.py +50 -4
- package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -0
- package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +5 -4
- package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +36 -0
- package/skills/cosmic-build/scripts/test/test_rule_batch_evidence.py +1 -1
- package/skills/cosmic-build/scripts/test/test_rule_domain_contract.py +20 -0
- package/skills/cosmic-build/scripts/test/test_rule_function_formula.py +16 -6
- package/skills/cosmic-build/scripts/test/test_skill_entry_contract.py +1 -0
- package/skills/cosmic-build/scripts/test/test_test_environment.py +45 -0
- package/skills/cosmic-build/scripts/test/test_verify_plugin_loading.py +79 -0
- package/skills/cosmic-build/scripts/test_environment.py +49 -0
- package/skills/cosmic-build/scripts/verify_plugin_loading.py +71 -0
- package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +86 -162
- package/skills/cosmic-build/skills/cosmic-coding-script/ATTRIBUTION.md +1 -1
- package/skills/cosmic-build/skills/cosmic-coding-script/SKILL.md +45 -14
- package/skills/cosmic-build/skills/cosmic-coding-script/references/kwc-controller-authoring.md +6 -0
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/README.md +29 -19
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/docs//350/204/232/346/234/254SDK.md +3 -4
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/indexes/package-index.md +1 -1
- package/skills/cosmic-build/skills/cosmic-coding-script/references/sdk/strategy.md +27 -18
- package/skills/cosmic-build/skills/cosmic-meta-api/SKILL.md +11 -17
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/app_menu.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/meta_log.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/control-authoring.json +45 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/form-control-traits.json +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/layout-ui.json +18 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/menu-publish.json +8 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-batch.json +7 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/property-input-index.json +3 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +1 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +37 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-event-contract.json +24 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/run-build-meta.json +61 -12
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/dropdown-menu.schema.json +69 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +2 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-set.schema.json +1 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/rule-write.schema.json +14 -7
- package/skills/cosmic-build/skills/cosmic-meta-api/docs/api-summary.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/app-action/SKILL.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/develop/SKILL.md +1 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/export/SKILL.md +5 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/init/SKILL.md +13 -36
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/SKILL.md +8 -9
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/config.json.example +5 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/reset/SKILL.md +6 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/usage/SKILL.md +20 -148
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/build_receipts.py +171 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +25 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_controls.py +55 -21
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_fields.py +10 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +63 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_forms.py +59 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +8 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +36 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_plugins.py +115 -90
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +666 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +1415 -87
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/commands.py +6 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +28 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +40 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +32 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_policy_contract.py +6 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +113 -17
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/reset.py +3 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/rule_contract.py +107 -26
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/build_meta_order.py +50 -49
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +856 -150
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +47 -14
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +374 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_cli_failure_contract.py +24 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_creation_identity_boundary.py +4 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_dropdown_menu_contract.py +382 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_existing_form_ui.py +0 -25
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_field_decorator.py +50 -6
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_functional_group_resolution.py +83 -16
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_identity_template_resolution.py +103 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +28 -2
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +22 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +65 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +1041 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +65 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +17 -0
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/api-param-checklist.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/rule-modeling-guide.md +7 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +61 -13
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/app-menu/SKILL.md +8 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/SKILL.md +5 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/formtemplate/dynamic-form-artifact-schema.md +5 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +21 -9
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-entity-graphs.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-storage-constraints.md +5 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-ui-composition.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/creation-recovery.md +13 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/parse-core.md +3 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +6 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +135 -87
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/field_type_registry.py +11 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/isv_resolver.py +1 -3
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +29 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +4 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/context/SKILL.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/execute/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/SKILL.md +5 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/operation-write.md +6 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +20 -5
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/complex-apis.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/policy-grammar.md +4 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +9 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +61 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/raw-rule-authoring.md +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-actions.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/rule-reference.md +6 -6
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/state.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/unit/SKILL.md +6 -3
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +4 -4
- package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +4 -1
- package/skills/cosmic-build/skills/cosmic-meta-ui/SKILL.md +9 -1
- package/skills/cosmic-build/skills/cosmic-meta-ui/modules/button/SKILL.md +3 -0
- package/skills/cosmic-build/skills/mcp-server/SKILL.md +210 -0
- package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +431 -0
- package/skills/cosmic-build/skills/openapi-gen/SKILL.md +3 -3
- package/skills/cosmic-build/skills/openapi-gen/scripts/api/gen_runner.py +2 -2
- package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +19 -9
- package/skills/cosmic-dev-best-practices/references/cosmic-meta-api.md +14 -11
- package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +1 -1
- package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/AssistantField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/BasedataField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/BasedataPropField.md +3 -3
- package/skills/cosmic-dev-best-practices/references/elements/CreaterField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/CurrencyField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/FlexField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/MaterielField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/OrgField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +2 -2
- package/skills/cosmic-dev-best-practices/references/elements/UnitField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/UserField.md +3 -3
- package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +16 -11
- package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +5 -4
- package/skills/erp-analysis/references/delivery-contract.md +4 -2
- package/skills/erp-analysis/templates/AGENTS.template.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/.dsh/cosmic/.kd/config.json +0 -21
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import kd.bos.algo.*;
|
|
2
|
+
import java.util.*;
|
|
3
|
+
import java.util.concurrent.*;
|
|
4
|
+
|
|
5
|
+
public class ReportAlgoBenchmark {
|
|
6
|
+
static Map<String, String> read(DataSet data) {
|
|
7
|
+
Map<String, String> result=new TreeMap<>();
|
|
8
|
+
while(data.hasNext()) { Row row=data.next();result.put(row.getString("supplier"),row.getDate("first_date").getTime()+":"+row.getDate("last_date").getTime()); }
|
|
9
|
+
data.close();return result;
|
|
10
|
+
}
|
|
11
|
+
static Map<String, String> baseline(DataSet data) {
|
|
12
|
+
Map<String, String> result=new TreeMap<>();
|
|
13
|
+
for(DataSet group:data.splitByGroup(new String[]{"supplier"})) {
|
|
14
|
+
DataSet first=group.copy().topBy(1,new String[]{"bill_date asc"});
|
|
15
|
+
DataSet last=group.topBy(1,new String[]{"bill_date desc"});
|
|
16
|
+
if(!first.hasNext() || !last.hasNext()) throw new AssertionError("empty group");
|
|
17
|
+
Row firstRow=first.next();String key=firstRow.getString("supplier");long start=firstRow.getDate("bill_date").getTime();
|
|
18
|
+
long end=last.next().getDate("bill_date").getTime();result.put(key,start+":"+end);first.close();last.close();
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
static void run(int rows, int groups, int iterations) {
|
|
23
|
+
List<Object[]> input=new ArrayList<>();Map<String,String> expected=new TreeMap<>();
|
|
24
|
+
for(int i=0;i<rows;i++) input.add(new Object[]{"S"+(i%groups),new Date(i*1000L)});
|
|
25
|
+
for(int i=0;i<groups;i++) expected.put("S"+i,(i*1000L)+":"+((i+((rows-1-i)/groups)*groups)*1000L));
|
|
26
|
+
RowMeta meta=new RowMeta(new Field("supplier",DataType.StringType),new Field("bill_date",DataType.DateType));
|
|
27
|
+
Algo algo=Algo.create("report-benchmark");
|
|
28
|
+
List<Long> oldTimes=new ArrayList<>(),newTimes=new ArrayList<>();
|
|
29
|
+
for(int i=-1;i<iterations;i++) {
|
|
30
|
+
long start=System.nanoTime();Map<String,String> old=baseline(algo.createDataSet(input,meta));long oldTime=System.nanoTime()-start;
|
|
31
|
+
start=System.nanoTime();Map<String,String> optimized=read(CosmicReportAggregation.dateBounds(algo.createDataSet(input,meta)));long newTime=System.nanoTime()-start;
|
|
32
|
+
if(!expected.equals(old) || !expected.equals(optimized)) throw new AssertionError("business result differs");
|
|
33
|
+
if(i>=0) { oldTimes.add(oldTime);newTimes.add(newTime); }
|
|
34
|
+
}
|
|
35
|
+
Collections.sort(oldTimes);Collections.sort(newTimes);
|
|
36
|
+
int p95=(int)Math.ceil(iterations*.95)-1;
|
|
37
|
+
System.out.println("{\"rows\":"+rows+",\"groups\":"+groups+",\"iterations\":"+iterations+",\"resultsEqual\":true,\"baselineP50Ms\":"+oldTimes.get(iterations/2)/1e6+",\"baselineP95Ms\":"+oldTimes.get(p95)/1e6+",\"optimizedP50Ms\":"+newTimes.get(iterations/2)/1e6+",\"optimizedP95Ms\":"+newTimes.get(p95)/1e6+",\"databaseQueries\":0}");
|
|
38
|
+
}
|
|
39
|
+
public static void main(String[] args) throws Exception {
|
|
40
|
+
ExecutorService executor=kd.bos.threads.ThreadPools.newExecutorService("report-benchmark",1);
|
|
41
|
+
java.util.concurrent.atomic.AtomicBoolean completed=new java.util.concurrent.atomic.AtomicBoolean();
|
|
42
|
+
try {
|
|
43
|
+
executor.submit(()->{try(AlgoContext context=Algo.newContext()) {run(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2]));completed.set(true);}}).get(60,TimeUnit.SECONDS);
|
|
44
|
+
if(!completed.get()) throw new AssertionError("managed task did not run");
|
|
45
|
+
executor.shutdownNow();System.exit(0);
|
|
46
|
+
} catch(Exception error) { error.printStackTrace();System.exit(2); }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Isolates application logging/configuration only; computation uses the actual target SDK. */
|
|
2
|
+
public class ReportBenchmarkLogFactory extends kd.bos.logging.LogFactory {
|
|
3
|
+
protected kd.bos.logging.Log _getLog(String name) {
|
|
4
|
+
return (kd.bos.logging.Log) java.lang.reflect.Proxy.newProxyInstance(kd.bos.logging.Log.class.getClassLoader(),
|
|
5
|
+
new Class[]{kd.bos.logging.Log.class}, (proxy, method, args) -> method.getReturnType()==boolean.class ? false : null);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import java.util.Arrays;
|
|
2
|
+
import java.util.stream.Collectors;
|
|
3
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
4
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
5
|
+
import kd.bos.orm.query.QFilter;
|
|
6
|
+
import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
7
|
+
import kd.bos.servicehelper.QueryServiceHelper;
|
|
8
|
+
|
|
9
|
+
/** Compile-checked against the 8.0 SDK. Runtime identities and results need target validation. */
|
|
10
|
+
public final class CosmicEntryQuery {
|
|
11
|
+
private CosmicEntryQuery() {}
|
|
12
|
+
|
|
13
|
+
/** Query the verified form root; the result is flat and must not be saved. */
|
|
14
|
+
public static DynamicObjectCollection queryHeaderIds(String formNumber, QFilter[] filters) {
|
|
15
|
+
return QueryServiceHelper.query(formNumber, "id", filters);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Load a structured object by its queried header ID, then read its collection property. */
|
|
19
|
+
public static DynamicObjectCollection loadEntries(Object headerId, String formNumber,
|
|
20
|
+
String collectionProperty, String... entryFields) {
|
|
21
|
+
String selectFields = "id," + Arrays.stream(entryFields)
|
|
22
|
+
.map(field -> collectionProperty + "." + field).collect(Collectors.joining(","));
|
|
23
|
+
DynamicObject header = BusinessDataServiceHelper.loadSingle(headerId, formNumber, selectFields);
|
|
24
|
+
return header == null ? null : header.getDynamicObjectCollection(collectionProperty);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import kd.bos.algo.DataSet;
|
|
2
|
+
import kd.bos.orm.ORM;
|
|
3
|
+
import kd.bos.orm.query.QFilter;
|
|
4
|
+
|
|
5
|
+
/** Inputs are filtered at their owning ORM queries; headers contain exactly one row per id. */
|
|
6
|
+
public final class CosmicReportAggregation {
|
|
7
|
+
private CosmicReportAggregation() { }
|
|
8
|
+
|
|
9
|
+
/** 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,
|
|
11
|
+
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));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
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()
|
|
24
|
+
.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();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Direct aggregates avoid materializing/sorting/unioning a DataSet for each supplier. */
|
|
32
|
+
public static DataSet dateBounds(DataSet headers) {
|
|
33
|
+
return headers.groupBy(new String[]{"supplier"}).min("bill_date", "first_date").max("bill_date", "last_date").finish();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
2
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
3
|
+
import kd.bos.entity.report.FilterInfo;
|
|
4
|
+
import kd.bos.entity.report.FilterItemInfo;
|
|
5
|
+
import kd.bos.orm.query.QFilter;
|
|
6
|
+
import kd.bos.orm.query.QCP;
|
|
7
|
+
|
|
8
|
+
import java.util.ArrayList;
|
|
9
|
+
import java.util.Date;
|
|
10
|
+
import java.util.LinkedHashSet;
|
|
11
|
+
import java.util.List;
|
|
12
|
+
import java.util.Objects;
|
|
13
|
+
|
|
14
|
+
/** Target 8.0 SDK adapter. Supply verified runtime keys and organization scope. */
|
|
15
|
+
public final class CosmicReportFilters {
|
|
16
|
+
private CosmicReportFilters() { }
|
|
17
|
+
|
|
18
|
+
public static Object value(FilterInfo filter, String... keys) {
|
|
19
|
+
Object result = null;
|
|
20
|
+
if (filter == null) return null;
|
|
21
|
+
for (String key : keys) {
|
|
22
|
+
Object current = filter.getValue(key);
|
|
23
|
+
if (current == null) continue;
|
|
24
|
+
if (result != null && !Objects.equals(result, current)) {
|
|
25
|
+
throw new IllegalArgumentException("Conflicting report filter keys: " + key);
|
|
26
|
+
}
|
|
27
|
+
result = current;
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public static Date date(FilterInfo filter, String itemKey) {
|
|
33
|
+
Date result = null;
|
|
34
|
+
if (filter == null) return null;
|
|
35
|
+
for (FilterItemInfo item : filter.getFilterItems()) {
|
|
36
|
+
if (!itemKey.equals(item.getPropName()) || item.getValue() == null) continue;
|
|
37
|
+
if (!(item.getValue() instanceof Date)) {
|
|
38
|
+
throw new IllegalArgumentException("Report date filter must carry Date: " + itemKey);
|
|
39
|
+
}
|
|
40
|
+
Date current = (Date) item.getValue();
|
|
41
|
+
if (result != null && !result.equals(current)) {
|
|
42
|
+
throw new IllegalArgumentException("Conflicting report date values: " + itemKey);
|
|
43
|
+
}
|
|
44
|
+
result = current;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** For field.number comparisons only; this does not grant cross-organization access. */
|
|
50
|
+
public static List<String> numbers(Object value) {
|
|
51
|
+
LinkedHashSet<String> result = new LinkedHashSet<>();
|
|
52
|
+
if (value == null) return new ArrayList<>();
|
|
53
|
+
if (value instanceof DynamicObjectCollection) {
|
|
54
|
+
for (DynamicObject row : (DynamicObjectCollection) value) addNumber(result, row);
|
|
55
|
+
return new ArrayList<>(result);
|
|
56
|
+
}
|
|
57
|
+
if (value instanceof DynamicObject) {
|
|
58
|
+
addNumber(result, (DynamicObject) value);
|
|
59
|
+
return new ArrayList<>(result);
|
|
60
|
+
}
|
|
61
|
+
throw new IllegalArgumentException("F7 filter must carry DynamicObject or DynamicObjectCollection");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Call only after verifying code uniqueness and retaining organization/permission filters. */
|
|
65
|
+
public static QFilter numberFilter(String sourceField, Object selection) {
|
|
66
|
+
List<String> values = numbers(selection);
|
|
67
|
+
return values.isEmpty() ? null : new QFilter(sourceField + ".number", QCP.in, values.toArray(new String[0]));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private static void addNumber(LinkedHashSet<String> numbers, DynamicObject value) {
|
|
71
|
+
String number = value.getString("number");
|
|
72
|
+
if (number == null || number.trim().isEmpty()) {
|
|
73
|
+
throw new IllegalArgumentException("Selected F7 record has no number");
|
|
74
|
+
}
|
|
75
|
+
numbers.add(number);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import java.time.LocalTime;
|
|
2
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
3
|
+
|
|
4
|
+
/** Adapt an 8.0 SDK TimeProp value; do not use DynamicObject.getDate for this field type. */
|
|
5
|
+
public final class CosmicTimeAdapter {
|
|
6
|
+
private CosmicTimeAdapter() {}
|
|
7
|
+
|
|
8
|
+
public static LocalTime read(DynamicObject row, String fieldKey) {
|
|
9
|
+
if (row == null || fieldKey == null || fieldKey.isEmpty()) {
|
|
10
|
+
throw new IllegalArgumentException("A loaded TimeProp row and field key are required");
|
|
11
|
+
}
|
|
12
|
+
return fromSeconds(row.get(fieldKey));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static LocalTime fromSeconds(Object value) {
|
|
16
|
+
if (!(value instanceof Integer)) {
|
|
17
|
+
throw new IllegalArgumentException("TimeProp must be an Integer number of seconds");
|
|
18
|
+
}
|
|
19
|
+
int seconds = ((Integer) value).intValue();
|
|
20
|
+
if (seconds < 0 || seconds >= 24 * 60 * 60) {
|
|
21
|
+
throw new IllegalArgumentException("TimeProp seconds are outside one day");
|
|
22
|
+
}
|
|
23
|
+
return LocalTime.ofSecondOfDay(seconds);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import java.time.LocalTime;
|
|
2
|
+
|
|
3
|
+
public final class CosmicTimeAdapterCheck {
|
|
4
|
+
private static void expect(LocalTime actual, LocalTime expected) {
|
|
5
|
+
if (!actual.equals(expected)) throw new AssertionError(actual + " != " + expected);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
private static void reject(Object value) {
|
|
9
|
+
try {
|
|
10
|
+
CosmicTimeAdapter.fromSeconds(value);
|
|
11
|
+
throw new AssertionError("invalid TimeProp value accepted: " + value);
|
|
12
|
+
} catch (IllegalArgumentException expected) {
|
|
13
|
+
// Invalid or absent platform data must not silently omit a business validation.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public static void main(String[] args) {
|
|
18
|
+
expect(CosmicTimeAdapter.fromSeconds(Integer.valueOf(36000)), LocalTime.of(10, 0));
|
|
19
|
+
expect(CosmicTimeAdapter.fromSeconds(Integer.valueOf(46800)), LocalTime.of(13, 0));
|
|
20
|
+
reject(null);
|
|
21
|
+
reject(Integer.valueOf(-1));
|
|
22
|
+
reject(Integer.valueOf(86400));
|
|
23
|
+
reject(Long.valueOf(36000));
|
|
24
|
+
System.out.println("CosmicTimeAdapter: 6 cases passed");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
framework_version: "8.0"
|
|
3
|
+
api_class: "GroupbyDataSet"
|
|
4
|
+
api_package: "kd.bos.algo"
|
|
5
|
+
when_to_use: "按目标 SDK 对报表数据求和、计算日期边界和去重计数"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# GroupbyDataSet API
|
|
9
|
+
|
|
10
|
+
通过目标 Algo SDK 的 javap 核验,并由 CosmicReportAggregation 运行测试。
|
|
11
|
+
其他版本使用现有 SDK 查询。以下属于 Algo,不使用 AlgoX Grouper 的签名替代。
|
|
12
|
+
|
|
13
|
+
## sum
|
|
14
|
+
|
|
15
|
+
```java
|
|
16
|
+
public GroupbyDataSet sum(String expression, String alias)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## min
|
|
20
|
+
|
|
21
|
+
```java
|
|
22
|
+
public GroupbyDataSet min(String expression, String alias)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## max
|
|
26
|
+
|
|
27
|
+
```java
|
|
28
|
+
public GroupbyDataSet max(String expression, String alias)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## avg
|
|
32
|
+
|
|
33
|
+
```java
|
|
34
|
+
public GroupbyDataSet avg(String expression, String alias)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## countDistinct
|
|
38
|
+
|
|
39
|
+
```java
|
|
40
|
+
public GroupbyDataSet countDistinct(String[] fields, String alias)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## finish
|
|
44
|
+
|
|
45
|
+
```java
|
|
46
|
+
public DataSet finish()
|
|
47
|
+
```
|
|
@@ -375,11 +375,11 @@ public FilterItemInfo getFilterItem(String propName)
|
|
|
375
375
|
|
|
376
376
|
**方法签名:**
|
|
377
377
|
```java
|
|
378
|
-
public List<kd.FilterItemInfo> getFilterItems()
|
|
378
|
+
public List<kd.bos.entity.report.FilterItemInfo> getFilterItems()
|
|
379
379
|
```
|
|
380
380
|
|
|
381
381
|
**返回值:**
|
|
382
|
-
- `List<kd.FilterItemInfo>`: 返回过滤字段及其比较值集合
|
|
382
|
+
- `List<kd.bos.entity.report.FilterItemInfo>`: 返回过滤字段及其比较值集合
|
|
383
383
|
|
|
384
384
|
---
|
|
385
385
|
|
|
@@ -389,14 +389,14 @@ public List<kd.FilterItemInfo> getFilterItems()
|
|
|
389
389
|
|
|
390
390
|
**方法签名:**
|
|
391
391
|
```java
|
|
392
|
-
public List<kd.FilterItemInfo> getFilterItems(String propName)
|
|
392
|
+
public List<kd.bos.entity.report.FilterItemInfo> getFilterItems(String propName)
|
|
393
393
|
```
|
|
394
394
|
|
|
395
395
|
**参数说明:**
|
|
396
396
|
- `propName`: `String` — 字段
|
|
397
397
|
|
|
398
398
|
**返回值:**
|
|
399
|
-
- `List<kd.FilterItemInfo>`
|
|
399
|
+
- `List<kd.bos.entity.report.FilterItemInfo>`
|
|
400
400
|
|
|
401
401
|
---
|
|
402
402
|
|
|
@@ -406,11 +406,11 @@ public List<kd.FilterItemInfo> getFilterItems(String propName)
|
|
|
406
406
|
|
|
407
407
|
**方法签名:**
|
|
408
408
|
```java
|
|
409
|
-
public List<kd.FilterItemInfo> getFlexFilterItems()
|
|
409
|
+
public List<kd.bos.entity.report.FilterItemInfo> getFlexFilterItems()
|
|
410
410
|
```
|
|
411
411
|
|
|
412
412
|
**返回值:**
|
|
413
|
-
- `List<kd.FilterItemInfo>`: 返回弹性域过滤字段及其比较值集合
|
|
413
|
+
- `List<kd.bos.entity.report.FilterItemInfo>`: 返回弹性域过滤字段及其比较值集合
|
|
414
414
|
|
|
415
415
|
---
|
|
416
416
|
|
|
@@ -527,11 +527,11 @@ public String getString(String propertyName)
|
|
|
527
527
|
|
|
528
528
|
**方法签名:**
|
|
529
529
|
```java
|
|
530
|
-
public List<kd.FilterItemInfo> getTableHeadFilterItems()
|
|
530
|
+
public List<kd.bos.entity.report.FilterItemInfo> getTableHeadFilterItems()
|
|
531
531
|
```
|
|
532
532
|
|
|
533
533
|
**返回值:**
|
|
534
|
-
- `List<kd.FilterItemInfo>`
|
|
534
|
+
- `List<kd.bos.entity.report.FilterItemInfo>`
|
|
535
535
|
|
|
536
536
|
---
|
|
537
537
|
|
|
@@ -601,11 +601,11 @@ public void setFastFilter(FastFilter fastFilter)
|
|
|
601
601
|
|
|
602
602
|
**方法签名:**
|
|
603
603
|
```java
|
|
604
|
-
public void setFlexFilterItems(List<kd.FilterItemInfo> flexFilterItems)
|
|
604
|
+
public void setFlexFilterItems(List<kd.bos.entity.report.FilterItemInfo> flexFilterItems)
|
|
605
605
|
```
|
|
606
606
|
|
|
607
607
|
**参数说明:**
|
|
608
|
-
- `flexFilterItems`: `List<kd.FilterItemInfo>` — 弹性域过滤字段及其比较值集合
|
|
608
|
+
- `flexFilterItems`: `List<kd.bos.entity.report.FilterItemInfo>` — 弹性域过滤字段及其比较值集合
|
|
609
609
|
|
|
610
610
|
---
|
|
611
611
|
|
|
@@ -657,11 +657,11 @@ public void setReportFilterConfig(ReportFilterConfig reportFilterConfig)
|
|
|
657
657
|
|
|
658
658
|
**方法签名:**
|
|
659
659
|
```java
|
|
660
|
-
public void setTableHeadFilterItems(List<kd.FilterItemInfo> tableHeadFilterItems)
|
|
660
|
+
public void setTableHeadFilterItems(List<kd.bos.entity.report.FilterItemInfo> tableHeadFilterItems)
|
|
661
661
|
```
|
|
662
662
|
|
|
663
663
|
**参数说明:**
|
|
664
|
-
- `tableHeadFilterItems`: `List<kd.FilterItemInfo>` — 表头过滤条件集合
|
|
664
|
+
- `tableHeadFilterItems`: `List<kd.bos.entity.report.FilterItemInfo>` — 表头过滤条件集合
|
|
665
665
|
|
|
666
666
|
---
|
|
667
667
|
|
|
@@ -11,6 +11,8 @@ when_to_use: "当你需要使用报表单个过滤项信息时"
|
|
|
11
11
|
报表单个过滤项信息。实现 Serializable。
|
|
12
12
|
主要功能:读取属性、设置属性。
|
|
13
13
|
|
|
14
|
+
FilterItemInfo 不是 DynamicObject。目标 bos-entity-metadata-8.0.jar 的 getPropName、getValue、getDate 均为公开方法,其他 SDK 先核验签名。拆分日期使用准确起止项 key,不能用 toString 解析日期。
|
|
15
|
+
|
|
14
16
|
## Import 路径
|
|
15
17
|
```java
|
|
16
18
|
import kd.bos.entity.report.FilterItemInfo;
|
|
@@ -27,7 +27,7 @@ afterCopyData(仅复制)→ beforeBindData → afterBindData
|
|
|
27
27
|
| `getEntityType` | 创建数据包前触发 | 指定动态表单实体类型 |
|
|
28
28
|
| `createNewData` | 开始新建数据包时触发 | 自定义数据包创建 |
|
|
29
29
|
| `afterCreateNewData` | 仅新增时,数据包创建后 | 设置默认字段值 |
|
|
30
|
-
| `afterLoadData` |
|
|
30
|
+
| `afterLoadData` | 仅编辑时,数据库数据加载后。仅单据与基础资料插件(`billform` / `baseform` / `mobbill`)可用:`AbstractFormPlugin` 和 `AbstractMobFormPlugin` 没有声明 `afterLoadData` | 读取数据做额外初始化 |
|
|
31
31
|
| `afterCopyData` | 仅复制时,数据包复制后 | 清空不应复制的字段 |
|
|
32
32
|
| `beforeBindData` | 控件绑定数据之前 | 注册分录行监听 |
|
|
33
33
|
| `afterBindData` | 控件绑定数据之后 | 控制控件显隐/启用 |
|
|
@@ -207,7 +207,7 @@ import kd.bos.form.control.events.ItemClickEvent;
|
|
|
207
207
|
import kd.bos.form.events.BeforeDoOperationEventArgs;
|
|
208
208
|
import kd.bos.form.events.AfterDoOperationEventArgs;
|
|
209
209
|
import kd.bos.form.operate.FormOperate;
|
|
210
|
-
import kd.bos.form.
|
|
210
|
+
import kd.bos.form.ShowType;
|
|
211
211
|
import kd.bos.form.plugin.AbstractFormPlugin;
|
|
212
212
|
import kd.bos.logging.Log;
|
|
213
213
|
import kd.bos.logging.LogFactory;
|
|
@@ -232,8 +232,6 @@ 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 afterLoadData(EventObject e) { super.afterLoadData(e); }
|
|
236
|
-
@Override
|
|
237
235
|
public void afterBindData(EventObject e) {}
|
|
238
236
|
@Override
|
|
239
237
|
public void propertyChanged(PropertyChangedArgs e) {
|
|
@@ -126,6 +126,7 @@ QFilter filter = new QFilter("id", QCP.not_in, idSet);
|
|
|
126
126
|
| 整数 | `getLong(key)` / `getInt(key)` |
|
|
127
127
|
| 小数、金额、单价、数量 | `getBigDecimal(key)` |
|
|
128
128
|
| 日期 | `getDate(key)` |
|
|
129
|
+
| 时刻(`TimeProp` / `TimeField`) | `getInt(key)`;目标 8.0 SDK 中为距午夜的整秒数 |
|
|
129
130
|
| 是/否 | `getBoolean(key)` |
|
|
130
131
|
| 被引用的记录 | `getDynamicObject(key)` |
|
|
131
132
|
| 分录行或 `Mul*` 值 | `getDynamicObjectCollection(key)` |
|
|
@@ -133,6 +134,11 @@ QFilter filter = new QFilter("id", QCP.not_in, idSet);
|
|
|
133
134
|
|
|
134
135
|
写值用 `set(key, value)`。
|
|
135
136
|
|
|
137
|
+
`TimeProp` 不是 `DateProp`:其 SDK 属性类型为 `Integer`,实测数据库中的 10:00 为 `36000`。
|
|
138
|
+
对这个整数调用 `getDate(key)` 会经 SDK 的 `ObjectConverter` 返回 null;若代码直接跳过
|
|
139
|
+
null,时段比较会悄然失效。比较前核对原始值和字段的空值设置,同日时段使用距午夜秒数;
|
|
140
|
+
跨日与时区行为需要明确业务规则。
|
|
141
|
+
|
|
136
142
|
## 分录字段取值要带行号
|
|
137
143
|
|
|
138
144
|
`getModel().getValue(key)` 读的是单据头字段,分录字段要用 `getValue(key, rowIndex)`。视图侧
|
|
@@ -152,5 +158,8 @@ QFilter filter = new QFilter("id", QCP.not_in, idSet);
|
|
|
152
158
|
|
|
153
159
|
读该类自己的页面 `knowledge/cosmic/platform/api/**/{Class}.md`。它的方法列表只覆盖该类自身
|
|
154
160
|
声明的方法——继承来的方法记录在页面概述里 `继承自` 指向的那个类上。这些页面由 Cosmic 8.0.1
|
|
155
|
-
的 javadoc
|
|
156
|
-
|
|
161
|
+
的 javadoc 导出生成,因此不含构造器,也缺少部分公开重载:页面上没有某个方法,不能证明它不存在,
|
|
162
|
+
但同样不构成可以照写的依据。此时到绑定的目标 SDK 中查证:
|
|
163
|
+
`scripts/platform_api_contract.py --describe-class` 对未收录的类和成员会返回 `sdkLookup`,按
|
|
164
|
+
`references/sdk-inspection.md` 执行。准确的目标 SDK 仍无法确认所需签名时才返回 `L3-BLOCK`,任何
|
|
165
|
+
时候都不要凭记忆写签名。
|
|
@@ -22,17 +22,21 @@
|
|
|
22
22
|
### 列表数据格式化(packageData)
|
|
23
23
|
|
|
24
24
|
```java
|
|
25
|
-
import kd.bos.
|
|
25
|
+
import kd.bos.entity.datamodel.events.PackageDataEvent;
|
|
26
26
|
|
|
27
27
|
@Override
|
|
28
|
-
public void packageData(
|
|
28
|
+
public void packageData(PackageDataEvent e) {
|
|
29
29
|
super.packageData(e);
|
|
30
|
-
//
|
|
31
|
-
|
|
30
|
+
// 格式化某一列的显示值(原始值 → 显示文本)。
|
|
31
|
+
// getColKey() 返回列标识;需要同行其他值时用 getRowData() 取整行。
|
|
32
|
+
if (!"targetColumn".equals(e.getColKey())) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
Object rawValue = e.getFormatValue();
|
|
32
36
|
if ("C".equals(rawValue)) {
|
|
33
|
-
e.
|
|
37
|
+
e.setFormatValue("已审核");
|
|
34
38
|
} else if ("A".equals(rawValue)) {
|
|
35
|
-
e.
|
|
39
|
+
e.setFormatValue("草稿");
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
```
|
|
@@ -42,15 +46,15 @@ public void packageData(ListPackageDataEvent e) {
|
|
|
42
46
|
### 自定义列表过滤(setFilter)
|
|
43
47
|
|
|
44
48
|
```java
|
|
45
|
-
import kd.bos.
|
|
49
|
+
import kd.bos.form.events.SetFilterEvent;
|
|
46
50
|
|
|
47
51
|
@Override
|
|
48
|
-
public void setFilter(
|
|
52
|
+
public void setFilter(SetFilterEvent e) {
|
|
49
53
|
super.setFilter(e);
|
|
50
54
|
// 注入额外过滤条件(如限制仅查看本人数据)
|
|
51
55
|
long userId = RequestContext.get().getCurrUserId();
|
|
52
56
|
QFilter myFilter = new QFilter("creator", QCP.equals, userId);
|
|
53
|
-
e.
|
|
57
|
+
e.addCustomQFilter(myFilter);
|
|
54
58
|
}
|
|
55
59
|
```
|
|
56
60
|
|
|
@@ -154,7 +158,7 @@ public void billListHyperLinkClick(HyperLinkClickArgs args) {
|
|
|
154
158
|
|
|
155
159
|
```java
|
|
156
160
|
import kd.bos.form.MobileFormShowParameter;
|
|
157
|
-
import kd.bos.form.
|
|
161
|
+
import kd.bos.form.ShowType;
|
|
158
162
|
|
|
159
163
|
private void openMobileForm() {
|
|
160
164
|
MobileFormShowParameter p = new MobileFormShowParameter();
|
|
@@ -232,8 +236,8 @@ package kd.{isv}.{module}.listplugin;
|
|
|
232
236
|
|
|
233
237
|
import java.util.EventObject;
|
|
234
238
|
import kd.bos.list.plugin.AbstractListPlugin;
|
|
235
|
-
import kd.bos.
|
|
236
|
-
import kd.bos.
|
|
239
|
+
import kd.bos.entity.datamodel.events.PackageDataEvent;
|
|
240
|
+
import kd.bos.form.events.SetFilterEvent;
|
|
237
241
|
import kd.bos.list.events.ListRowClickEvent;
|
|
238
242
|
import kd.bos.form.control.events.ItemClickEvent;
|
|
239
243
|
import kd.bos.form.events.HyperLinkClickArgs;
|
|
@@ -251,9 +255,9 @@ public class Xxx{PluginSuffix} extends {BaseClass} {
|
|
|
251
255
|
addItemClickListeners("tbmain");
|
|
252
256
|
}
|
|
253
257
|
@Override
|
|
254
|
-
public void setFilter(
|
|
258
|
+
public void setFilter(SetFilterEvent e) { super.setFilter(e); }
|
|
255
259
|
@Override
|
|
256
|
-
public void packageData(
|
|
260
|
+
public void packageData(PackageDataEvent e) { super.packageData(e); }
|
|
257
261
|
@Override
|
|
258
262
|
public void itemClick(ItemClickEvent evt) {
|
|
259
263
|
super.itemClick(evt);
|
|
@@ -29,9 +29,9 @@ onPreparePropertys
|
|
|
29
29
|
## 插件内常见上下文方法
|
|
30
30
|
|
|
31
31
|
```java
|
|
32
|
-
|
|
33
|
-
OperationResult result = this.
|
|
34
|
-
|
|
32
|
+
Map<String, Object> operateMeta = this.operateMeta; // 操作信息
|
|
33
|
+
OperationResult result = this.getOperationResult(); // 操作结果
|
|
34
|
+
OperateOption options = this.getOption(); // 自定义参数
|
|
35
35
|
// OperateErrorInfo:kd.bos.entity.operate.result | ErrorLevel:kd.bos.entity.validate
|
|
36
36
|
result.addErrorInfo(new OperateErrorInfo("ERR_01", ErrorLevel.Info, 4L));
|
|
37
37
|
result.setMessage("操作成功"); // 需配 setShowMessage(true) 才会展示
|
|
@@ -48,7 +48,7 @@ result.setSuccess(false);
|
|
|
48
48
|
2. **onPreparePropertys 声明依赖字段**,否则数据包会缺失
|
|
49
49
|
3. **规则校验放 onAddValidators**,事务前事件 (`beforeExecuteOperationTransaction`) 只做兜底取消
|
|
50
50
|
4. **数据修改放 beginOperationTransaction / endOperationTransaction**(事务内,异常自动回滚)
|
|
51
|
-
5.
|
|
51
|
+
5. **级联同步和关联对象写入按原子性选择位置**:必须与本操作同成同败的写入留在事务内(第 4 条),异常要向外传播;只有明确允许在操作提交后独立执行的同步才放 afterExecuteOperationTransaction,并且要有补偿策略,见下文跨实体回写场景
|
|
52
52
|
|
|
53
53
|
## 精选场景知识
|
|
54
54
|
|
|
@@ -71,9 +71,10 @@ getColumns → [用户点击查询] → query(queryParam, null)
|
|
|
71
71
|
1. 必须定义 `private static final String ALGO_NAME` 用于可追溯性
|
|
72
72
|
2. 必须包含权限过滤:`filter.getQFilters()` — 不得跳过
|
|
73
73
|
3. selectFields CSV 必须与 `reportColumns[i].dateIndex` 精确匹配
|
|
74
|
-
4.
|
|
74
|
+
4. 过滤条件读取技能根目录的 `references/report-filter-contract.md`。选择值用实际 key 调用
|
|
75
|
+
getValue,拆分日期用强类型 FilterItemInfo;getQFilters 的权限条件不能代替用户条件取值
|
|
75
76
|
5. 构造 QFilter 前必须对过滤值做空判断
|
|
76
|
-
6. DataSet
|
|
77
|
+
6. 框架接管的返回 DataSet 不由插件关闭,自有 copy() 副本用完关闭
|
|
77
78
|
7. 使用 `private static final String ENTITY_NUMBER` 常量 — 禁止硬编码实体标识
|
|
78
79
|
8. 返回的每一列都必须携带 `handoff.reportContract` 的 `dataSetColumnTypes` 给出的 Java 类型 ——
|
|
79
80
|
用该条目的 `rowAccessor` 读它,手工构建的 `Field` 用它的 `algoDataType` 声明。类型不对是在 set
|
|
@@ -85,7 +86,7 @@ getColumns → [用户点击查询] → query(queryParam, null)
|
|
|
85
86
|
`prepare_plugin_handoff --external-schema` 已校验的 read-back,在 `verifiedFields` 里返回
|
|
86
87
|
11. `api/` 下的 API 参考页会丢掉 `throws` 子句,所以那里的签名不带它并不等于该方法没有声明。
|
|
87
88
|
`query` 与 `getColumns` 都声明了 `throws Throwable` —— 见
|
|
88
|
-
`scenes/report/report-list-data-query.md` 的 Method Signatures
|
|
89
|
+
`scenes/report/report-list-data-query.md` 的 Method Signatures 段。声明它总能编译;只有覆写不调用 `super` 时才能收窄掉,
|
|
89
90
|
不要去「修」已经声明它的示例。API 页能确定的是 `abstract`,这也是 `query` 不带 `super` 调用的原因
|
|
90
91
|
|
|
91
92
|
## 骨架模板
|
|
@@ -101,6 +102,8 @@ import kd.bos.orm.query.QFilter;
|
|
|
101
102
|
import kd.bos.servicehelper.QueryServiceHelper;
|
|
102
103
|
|
|
103
104
|
import java.util.List;
|
|
105
|
+
import java.util.ArrayList;
|
|
106
|
+
import kd.bos.orm.query.QCP;
|
|
104
107
|
|
|
105
108
|
/**
|
|
106
109
|
* 报表取数插件骨架模板(原生 AbstractReportListDataPlugin)。
|
|
@@ -119,8 +122,8 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
|
|
|
119
122
|
// this.setProgress(30);
|
|
120
123
|
}
|
|
121
124
|
|
|
122
|
-
private static final String
|
|
123
|
-
private static final String
|
|
125
|
+
private static final String ALGO_NAME = "report-query";
|
|
126
|
+
private static final String ENTITY_NUMBER = "entity_name";
|
|
124
127
|
private static final String SELECT_FIELDS = "id,billno,name";
|
|
125
128
|
private static final String ORDER_BY = "id desc";
|
|
126
129
|
private static final String FIELD_BILL_NO = "billno";
|
|
@@ -140,10 +143,15 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
|
|
|
140
143
|
//(见 api/entity/report/AbstractReportListDataPlugin.md),Java 禁止通过 super 调用
|
|
141
144
|
// 抽象方法。getColumns 是具体方法,所以那里要调 super。
|
|
142
145
|
FilterInfo filter = queryParam.getFilter();
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
List<QFilter> filters = new ArrayList<>();
|
|
147
|
+
if (filter != null) {
|
|
148
|
+
filters.addAll(filter.getQFilters());
|
|
149
|
+
// Example only: bind the actual panel key to the source field from reportContract.
|
|
150
|
+
Object billNo = filter.getValue(FIELD_BILL_NO);
|
|
151
|
+
if (billNo != null) filters.add(new QFilter(FIELD_BILL_NO, QCP.equals, billNo));
|
|
152
|
+
}
|
|
145
153
|
this.setProgress(20);
|
|
146
|
-
return QueryServiceHelper.queryDataSet(
|
|
154
|
+
return QueryServiceHelper.queryDataSet(ALGO_NAME, ENTITY_NUMBER, SELECT_FIELDS, filters.toArray(new QFilter[0]), ORDER_BY);
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
/**
|
|
@@ -152,7 +160,7 @@ public class ReportListDataPluginTemplate extends AbstractReportListDataPlugin {
|
|
|
152
160
|
* 典型用途: 动态隐藏列、修改列宽、冻结列或调整显示顺序。
|
|
153
161
|
*/
|
|
154
162
|
@Override
|
|
155
|
-
public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) {
|
|
163
|
+
public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
|
|
156
164
|
super.getColumns(columns);
|
|
157
165
|
apply(columns);
|
|
158
166
|
return columns;
|