kcode-pi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +358 -0
- package/dist/cli/kcode.d.ts +15 -0
- package/dist/cli/kcode.js +153 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +7 -0
- package/docs/KCODE_DISTRIBUTION.md +91 -0
- package/extensions/kingdee-harness.ts +180 -0
- package/extensions/kingdee-header.ts +122 -0
- package/extensions/kingdee-tools.ts +379 -0
- package/knowledge/.backup/v1.0.0/version.json +10 -0
- package/knowledge/cangqiong/product-notes.md +15 -0
- package/knowledge/common/business-flows.md +115 -0
- package/knowledge/common/config-guides.md +110 -0
- package/knowledge/common/error-patterns.md +170 -0
- package/knowledge/common/implementation.md +144 -0
- package/knowledge/cosmic/hard-constraints.md +38 -0
- package/knowledge/cosmic/ksql-datafix.md +34 -0
- package/knowledge/cosmic/platform-baseline.md +32 -0
- package/knowledge/cosmic/plugin-decision-matrix.md +40 -0
- package/knowledge/cosmic/review-checklist.md +40 -0
- package/knowledge/cosmic/unittest.md +35 -0
- package/knowledge/enterprise/api-reference.md +186 -0
- package/knowledge/enterprise/code-patterns.md +217 -0
- package/knowledge/enterprise/plugin-lifecycle.md +188 -0
- package/knowledge/enterprise/tables.json +159 -0
- package/knowledge/flagship/api-reference.md +237 -0
- package/knowledge/flagship/code-patterns.md +246 -0
- package/knowledge/flagship/cosmic-platform-note.md +15 -0
- package/knowledge/flagship/plugin-lifecycle.md +248 -0
- package/knowledge/flagship/tables.json +159 -0
- package/knowledge/version.json +10 -0
- package/knowledge/xinghan/product-notes.md +15 -0
- package/package.json +71 -0
- package/prompts/kd-discuss.md +11 -0
- package/prompts/kd-execute.md +12 -0
- package/prompts/kd-plan.md +12 -0
- package/prompts/kd-ship.md +12 -0
- package/prompts/kd-spec.md +12 -0
- package/prompts/kd-verify.md +12 -0
- package/skills/kd-check/SKILL.md +26 -0
- package/skills/kd-cosmic-dev/SKILL.md +82 -0
- package/skills/kd-cosmic-review/SKILL.md +90 -0
- package/skills/kd-cosmic-unittest/SKILL.md +92 -0
- package/skills/kd-debug/SKILL.md +30 -0
- package/skills/kd-discuss/SKILL.md +24 -0
- package/skills/kd-execute/SKILL.md +22 -0
- package/skills/kd-gen/SKILL.md +34 -0
- package/skills/kd-ksql/SKILL.md +86 -0
- package/skills/kd-plan/SKILL.md +24 -0
- package/skills/kd-ship/SKILL.md +22 -0
- package/skills/kd-spec/SKILL.md +24 -0
- package/skills/kd-verify/SKILL.md +22 -0
- package/themes/kcode-dark.json +81 -0
- package/vendor/kingdee-skills/cosmic-unittest/SKILL.md +788 -0
- package/vendor/kingdee-skills/cosmic-unittest/author-cache.json +5 -0
- package/vendor/kingdee-skills/cosmic-unittest/cosmic-unittest-skill-overview.html +746 -0
- package/vendor/kingdee-skills/cosmic-unittest/examples/business-test.md +205 -0
- package/vendor/kingdee-skills/cosmic-unittest/examples/common-test.md +257 -0
- package/vendor/kingdee-skills/cosmic-unittest/examples/formplugin-test.md +560 -0
- package/vendor/kingdee-skills/cosmic-unittest/examples/op-plugin-test.md +231 -0
- package/vendor/kingdee-skills/cosmic-unittest/examples/validator-test.md +232 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/business-helper.md +184 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/common-module.md +355 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/convert-plugin.md +130 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/formplugin.md +235 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/op-plugin.md +226 -0
- package/vendor/kingdee-skills/cosmic-unittest/patterns/validator.md +206 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/SKILL.md +674 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/advanced-scenario-checklist.md +307 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/algox-performance-checklist.md +129 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/coding-standard-checklist.md +491 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/cosmic-api-checklist.md +285 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-access-checklist.md +261 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/data-transaction-checklist.md +390 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/domain-logic-checklist.md +295 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/form-plugin-checklist.md +508 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/infra-checklist.md +254 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ksql-checklist.md +305 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/lifecycle-checklist.md +298 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/operation-plugin-checklist.md +442 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/test-mock-checklist.md +120 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/references/ui-performance-checklist.md +320 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/pattern-matcher.py +336 -0
- package/vendor/kingdee-skills/kingdee-cosmic-reviewer/scripts/review-score-calculator.py +121 -0
- package/vendor/kingdee-skills/ok-cosmic/CHANGELOG.md +295 -0
- package/vendor/kingdee-skills/ok-cosmic/README.md +460 -0
- package/vendor/kingdee-skills/ok-cosmic/SKILL.md +287 -0
- package/vendor/kingdee-skills/ok-cosmic/agents/openai.yaml +17 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/BatchImportPluginTemplate.java +93 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/BillPlugInTemplate.java +156 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/ConvertPlugInTemplate.java +255 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/FormPluginTemplate.java +597 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/IWorkflowPluginTemplate.java +91 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/ListPluginTemplate.java +194 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/OpPluginTemplate.java +201 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/OpenApiControllerTemplate.java +103 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/PrintPluginTemplate.java +95 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/ReportFormPluginTemplate.java +257 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/ReportListDataPluginTemplate.java +70 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/StandardTreeListPluginTemplate.java +130 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/TaskTemplate.java +80 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/TreeListPluginTemplate.java +152 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/WriteBackPlugInTemplate.java +286 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/attachment/AttachmentUploadBindSample.java +93 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/BotpTracePushSample.java +168 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/botp/SampleConvertPlugin.java +223 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/cache/SampleCacheUsage.java +218 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/concurrent/SampleThreadPoolBatch.java +156 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectCrudSample.java +205 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/data/DynamicObjectOpsSample.java +100 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/BeforeOperationConfirmSample.java +217 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ConfirmDialogSample.java +131 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/EntryRowCalculateSample.java +116 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/F7FilterSample.java +134 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/GetAndSetValueSample.java +176 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/HyperlinkJumpSample.java +124 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/OpenBillModalSample.java +253 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ReturnParentDataSample.java +295 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/TreeControlSample.java +140 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/ViewControlOpsSample.java +132 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPluginBasicSample.java +170 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/list/ListPreOpenFilterSample.java +68 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/message/MessageNotifySample.java +95 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/SampleMQConsumer.java +198 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/mq/sample_mq.xml +15 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OpAddValidatorsSample.java +137 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/operation/OperationOptionBridgeSample.java +228 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/package-info.java +19 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BaseDataQuerySample.java +194 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/BatchQuerySample.java +368 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/query/DataSetQueryStatSample.java +131 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportFormPlugin.java +179 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/report/SampleReportListDataPlugin.java +616 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/snippets-guide.md +64 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/task/ScheduleTaskSample.java +160 -0
- package/vendor/kingdee-skills/ok-cosmic/assets/snippets/workflow/SampleWorkflowPlugin.java +302 -0
- package/vendor/kingdee-skills/ok-cosmic/manifest.json +78 -0
- package/vendor/kingdee-skills/ok-cosmic/ok-cosmic-intro.html +903 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/attachment-api.md +114 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/botp-convert.md +98 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/dynamic-object.md +113 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/entity-metadata.md +123 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/event-lifecycle.md +184 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/flex-prop.md +114 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/form-utils.md +133 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/operate-chain.md +159 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/plugin-base.md +218 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/query-dataset.md +149 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/request-context.md +88 -0
- package/vendor/kingdee-skills/ok-cosmic/references/adv/view-handler.md +157 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-bill.md +76 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-botp.md +70 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-form.md +165 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-import.md +69 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-list.md +227 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-openapi.md +112 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-operation.md +135 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-print.md +65 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-data.md +64 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-report-form.md +90 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-task.md +62 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-tree-list.md +71 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-workflow.md +82 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/plugin/plugin-writeback.md +71 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-algo.md +67 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-cache.md +63 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-model-svc.md +82 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-dynamic-object.md +70 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-entity-model.md +61 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-exception.md +64 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-file.md +63 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-id.md +47 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-lock.md +61 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-log.md +63 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-network-control.md +70 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-orm-access.md +78 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-request-context.md +62 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-threadpool.md +63 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-tx.md +64 -0
- package/vendor/kingdee-skills/ok-cosmic/references/base/sdk/sdk-utils.md +67 -0
- package/vendor/kingdee-skills/ok-cosmic/requirements.txt +2 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/a-layer-rules.json +24 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/anti-patterns.md +48 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/cheat-sheet.md +256 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/coding-preferences.md +140 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/constraints.md +61 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/decision-matrix.md +222 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/intent-routing.md +94 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/platform-baseline.md +69 -0
- package/vendor/kingdee-skills/ok-cosmic/rules/post-check.md +109 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/config_loader.py +204 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-api-knowledge.py +910 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-basedata-query.py +359 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-config-check.py +181 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-extpoints-query.py +389 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-form-metadata.py +856 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-check.py +262 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/cosmic-post-lint.py +293 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/__init__.py +2 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/base.py +393 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/resource_check.py +176 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/scene_check.py +375 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/style_check.py +434 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/lint/verify_check.py +36 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/route_client.py +186 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/script_utils.py +40 -0
- package/vendor/kingdee-skills/ok-cosmic/scripts/sqlite_cache.py +142 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-commons.jar +0 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/cuslib/kd-cd-cosmic-features.jar +0 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic-docs.db +0 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/ok-cosmic.json +13 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/setup-mac.sh +18 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/setup-windows.bat +53 -0
- package/vendor/kingdee-skills/ok-cosmic/setup/setup.jar +0 -0
- package/vendor/kingdee-skills/ok-ksql/SKILL.md +81 -0
- package/vendor/kingdee-skills/ok-ksql/agents/openai.yaml +7 -0
- package/vendor/kingdee-skills/ok-ksql/manifest.json +14 -0
- package/vendor/kingdee-skills/ok-ksql/references/ksql-datafix.md +452 -0
- package/vendor/kingdee-skills/ok-ksql/scripts/ksql_lint.py +363 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 打开单据/动态表单弹窗并处理关闭回调示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件、单据插件
|
|
5
|
+
* 优先封装:ShowParameterUtils、DynamicObjectUtils
|
|
6
|
+
* 原生兜底:CloseCallBack、ClosedCallBackEvent、FormShowParameter / ListShowParameter
|
|
7
|
+
* 相关 lint 规则:当前无专门规则,可参考 STYLE-013、SCENE-005
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 打开 F7 列表让用户多选基础资料;
|
|
11
|
+
* 2. 打开自定义动态表单并按当前分录回填结果;
|
|
12
|
+
* 3. 打开特殊成员 F7,并按动态 actionId 回填多选基础资料。
|
|
13
|
+
*/
|
|
14
|
+
package kd.cd.common.snippets.form;
|
|
15
|
+
|
|
16
|
+
import kd.bos.bill.OperationStatus;
|
|
17
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
18
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
19
|
+
import kd.bos.dataentity.entity.MulBasedataDynamicObjectCollection;
|
|
20
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
21
|
+
import kd.bos.entity.datamodel.ListSelectedRow;
|
|
22
|
+
import kd.bos.entity.datamodel.ListSelectedRowCollection;
|
|
23
|
+
import kd.bos.form.CloseCallBack;
|
|
24
|
+
import kd.bos.form.FormShowParameter;
|
|
25
|
+
import kd.bos.form.ShowType;
|
|
26
|
+
import kd.bos.form.events.ClosedCallBackEvent;
|
|
27
|
+
import kd.bos.form.IPageCache;
|
|
28
|
+
import kd.bos.list.ListFilterParameter;
|
|
29
|
+
import kd.bos.list.ListShowParameter;
|
|
30
|
+
import kd.bos.orm.query.QCP;
|
|
31
|
+
import kd.bos.orm.query.QFilter;
|
|
32
|
+
import kd.cd.common.entity.EntityUtils;
|
|
33
|
+
import kd.cd.common.form.ShowParameterUtils;
|
|
34
|
+
import kd.cd.common.plugin.AbstractFormPluginExt;
|
|
35
|
+
import kd.cd.common.util.DynamicObjectUtils;
|
|
36
|
+
import kd.cd.core.util.CharSequenceUtils;
|
|
37
|
+
import kd.cd.core.util.CollectionUtils;
|
|
38
|
+
|
|
39
|
+
import java.util.LinkedHashSet;
|
|
40
|
+
import java.util.Set;
|
|
41
|
+
|
|
42
|
+
public class OpenBillModalSample extends AbstractFormPluginExt {
|
|
43
|
+
private static final String CALLBACK_SELECT_SUPPLIER = "select_supplier";
|
|
44
|
+
private static final String CALLBACK_SELECT_BUDGET = "select_budget";
|
|
45
|
+
private static final String CALLBACK_SELECT_DIM_MEMBER_PREFIX = "select_dim_member:";
|
|
46
|
+
private static final String SUPPLIER_ENTRY = "entrysupplier";
|
|
47
|
+
private static final String SUPPLIER_FIELD = "supplier";
|
|
48
|
+
private static final String BILL_ENTRY = "billentry";
|
|
49
|
+
private static final String SPECIAL_MEMBER_F7_FORM_ID = "bcm_mulmemberf7base_tem";
|
|
50
|
+
private static final String PAGE_CACHE_BUDGET_ROW = "budget_callback_row";
|
|
51
|
+
private static final String FIELD_BUDGET_ORG_NUMBER = "xxxx_orgnumber";
|
|
52
|
+
private static final String FIELD_BUDGET_YEAR = "xxxx_budgetyear";
|
|
53
|
+
private static final String FIELD_COST_CENTER = "xxxx_costcenter";
|
|
54
|
+
private static final String FIELD_WORKTASK = "xxxx_worktask";
|
|
55
|
+
private static final String FIELD_WORKTASK_NO = "xxxx_worktaskno";
|
|
56
|
+
private static final String FIELD_FEE_ACCOUNT = "xxxx_feeaccount";
|
|
57
|
+
private static final String FIELD_FEE_ACCOUNT_NO = "xxxx_feeaccountno";
|
|
58
|
+
private static final String FIELD_BUDGET_OFFICER = "xxxx_budgetofficer";
|
|
59
|
+
private static final String RES_APP_ID = "kd-cd-common-snippets";
|
|
60
|
+
|
|
61
|
+
public void openSupplierSelector(Object orgId, Object materialId) {
|
|
62
|
+
ListShowParameter showParameter = ShowParameterUtils.getF7List("bd_supplier", true);
|
|
63
|
+
showParameter.setCloseCallBack(new CloseCallBack(this, CALLBACK_SELECT_SUPPLIER));
|
|
64
|
+
|
|
65
|
+
ListFilterParameter listFilter = showParameter.getListFilterParameter();
|
|
66
|
+
listFilter.getQFilters().add(new QFilter("enable", QCP.equals, true));
|
|
67
|
+
listFilter.getQFilters().add(new QFilter("createorg.id", QCP.equals, orgId));
|
|
68
|
+
listFilter.getQFilters().add(new QFilter("suppliermaterial.material.masterid.id", QCP.equals, materialId));
|
|
69
|
+
getView().showForm(showParameter);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public void openBudgetSelectorForCurrentRow() {
|
|
73
|
+
int rowIndex = getModel().getEntryCurrentRowIndex(BILL_ENTRY);
|
|
74
|
+
if (!isValidEntryRow(rowIndex)) {
|
|
75
|
+
getView().showTipNotification(ResManager.loadKDString("请先定位到需要回填的分录行", "OpenBillModalSample_0", RES_APP_ID));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
String orgNumber = toText(getModel().getValue(FIELD_BUDGET_ORG_NUMBER, rowIndex));
|
|
80
|
+
String budgetYear = toText(getModel().getValue(FIELD_BUDGET_YEAR, rowIndex));
|
|
81
|
+
String costCenter = toText(getModel().getValue(FIELD_COST_CENTER, rowIndex));
|
|
82
|
+
if (CharSequenceUtils.isBlank(orgNumber)
|
|
83
|
+
|| CharSequenceUtils.isBlank(budgetYear)
|
|
84
|
+
|| CharSequenceUtils.isBlank(costCenter)) {
|
|
85
|
+
getView().showTipNotification(ResManager.loadKDString("请先补全预算组织、预算年度和成本中心", "OpenBillModalSample_1", RES_APP_ID));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getPageCache().put(PAGE_CACHE_BUDGET_ROW, String.valueOf(rowIndex));
|
|
90
|
+
openBudgetSelector(orgNumber, budgetYear, costCenter);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public void openBudgetSelector(String orgNumber, String budgetYear, String costCenter) {
|
|
94
|
+
FormShowParameter fsp = ShowParameterUtils.getForm(
|
|
95
|
+
"xxxx_budgetlist",
|
|
96
|
+
OperationStatus.ADDNEW,
|
|
97
|
+
ShowType.Modal,
|
|
98
|
+
"900px",
|
|
99
|
+
"600px"
|
|
100
|
+
);
|
|
101
|
+
fsp.setCustomParam("OrgNumber", orgNumber);
|
|
102
|
+
fsp.setCustomParam("BudgetYear", budgetYear);
|
|
103
|
+
fsp.setCustomParam("CostCenter", costCenter);
|
|
104
|
+
fsp.setCloseCallBack(new CloseCallBack(this, CALLBACK_SELECT_BUDGET));
|
|
105
|
+
getView().showForm(fsp);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public void openMemberSelector(Object modelId, String fieldKey, String memberModel, Object dimensionId) {
|
|
109
|
+
ListShowParameter showParameter = ShowParameterUtils.getF7List(SPECIAL_MEMBER_F7_FORM_ID, true);
|
|
110
|
+
showParameter.setCustomParam("KEY_MODEL_ID", String.valueOf(modelId));
|
|
111
|
+
showParameter.setCustomParam("dimensionid", String.valueOf(dimensionId));
|
|
112
|
+
showParameter.setCustomParam("mutilentity", "[]");
|
|
113
|
+
showParameter.setCustomParam("sign", fieldKey);
|
|
114
|
+
showParameter.setCloseCallBack(new CloseCallBack(this, buildMemberCallbackId(fieldKey, memberModel)));
|
|
115
|
+
getView().showForm(showParameter);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@Override
|
|
119
|
+
public void closedCallBack(ClosedCallBackEvent e) {
|
|
120
|
+
super.closedCallBack(e);
|
|
121
|
+
// 回调数据类型和对应选择页的回传类型保持一致即可。
|
|
122
|
+
String actionId = e.getActionId();
|
|
123
|
+
Object returnData = e.getReturnData();
|
|
124
|
+
if (returnData == null) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (actionId != null && actionId.startsWith(CALLBACK_SELECT_DIM_MEMBER_PREFIX)) {
|
|
128
|
+
handleDimMemberSelected(actionId, (DynamicObjectCollection) returnData);
|
|
129
|
+
} else if (CALLBACK_SELECT_SUPPLIER.equals(actionId)) {
|
|
130
|
+
handleSupplierSelected((ListSelectedRowCollection) returnData);
|
|
131
|
+
} else if (CALLBACK_SELECT_BUDGET.equals(actionId)) {
|
|
132
|
+
@SuppressWarnings("unchecked")
|
|
133
|
+
java.util.Map<String, String> selectedBudget = (java.util.Map<String, String>) returnData;
|
|
134
|
+
handleBudgetSelected(selectedBudget);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private void handleSupplierSelected(ListSelectedRowCollection selectedRows) {
|
|
139
|
+
if (CollectionUtils.isEmpty(selectedRows)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Set<Object> existingSupplierIds = new LinkedHashSet<>();
|
|
144
|
+
for (DynamicObject row : getModel().getEntryEntity(SUPPLIER_ENTRY)) {
|
|
145
|
+
DynamicObject supplier = row.getDynamicObject(SUPPLIER_FIELD);
|
|
146
|
+
Object supplierId = DynamicObjectUtils.nullSafeGet(supplier, "id");
|
|
147
|
+
if (EntityUtils.isNotEmptyPk(supplierId)) {
|
|
148
|
+
existingSupplierIds.add(supplierId);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
int addedCount = 0;
|
|
153
|
+
for (ListSelectedRow selectedRow : selectedRows) {
|
|
154
|
+
Object supplierId = selectedRow.getPrimaryKeyValue();
|
|
155
|
+
if (EntityUtils.isEmptyPk(supplierId) || !existingSupplierIds.add(supplierId)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
int rowIndex = getModel().createNewEntryRow(SUPPLIER_ENTRY);
|
|
159
|
+
getModel().setItemValueByID(SUPPLIER_FIELD, supplierId, rowIndex);
|
|
160
|
+
addedCount++;
|
|
161
|
+
}
|
|
162
|
+
if (addedCount == 0) {
|
|
163
|
+
getView().showTipNotification(ResManager.loadKDString("所选供应商已全部存在,无需重复回填", "OpenBillModalSample_2", RES_APP_ID));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
getView().updateView(SUPPLIER_ENTRY);
|
|
167
|
+
getView().showSuccessNotification(String.format(
|
|
168
|
+
ResManager.loadKDString("已新增%s行供应商", "OpenBillModalSample_3", RES_APP_ID),
|
|
169
|
+
addedCount
|
|
170
|
+
));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private void handleBudgetSelected(java.util.Map<String, String> selectedBudget) {
|
|
174
|
+
int rowIndex = resolveBudgetRowIndex();
|
|
175
|
+
if (!isValidEntryRow(rowIndex)) {
|
|
176
|
+
getView().showTipNotification(ResManager.loadKDString("目标分录行已不存在,请重新选择预算", "OpenBillModalSample_4", RES_APP_ID));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
getModel().setEntryCurrentRowIndex(BILL_ENTRY, rowIndex);
|
|
181
|
+
getModel().setValue(FIELD_WORKTASK, selectedBudget.get("workTask"), rowIndex);
|
|
182
|
+
getModel().setValue(FIELD_WORKTASK_NO, selectedBudget.get("workTaskNo"), rowIndex);
|
|
183
|
+
getModel().setValue(FIELD_FEE_ACCOUNT, selectedBudget.get("feeAccount"), rowIndex);
|
|
184
|
+
getModel().setValue(FIELD_FEE_ACCOUNT_NO, selectedBudget.get("feeAccountNo"), rowIndex);
|
|
185
|
+
getModel().setValue(FIELD_BUDGET_OFFICER, selectedBudget.get("budgetOfficer"), rowIndex);
|
|
186
|
+
getView().updateView(BILL_ENTRY);
|
|
187
|
+
getView().showSuccessNotification(String.format(
|
|
188
|
+
ResManager.loadKDString("已回填第%s行预算信息", "OpenBillModalSample_5", RES_APP_ID),
|
|
189
|
+
rowIndex + 1
|
|
190
|
+
));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private String buildMemberCallbackId(String fieldKey, String memberModel) {
|
|
194
|
+
return CALLBACK_SELECT_DIM_MEMBER_PREFIX + fieldKey + "|" + memberModel;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private void handleDimMemberSelected(String actionId, DynamicObjectCollection selectedRows) {
|
|
198
|
+
String[] parts = actionId.substring(CALLBACK_SELECT_DIM_MEMBER_PREFIX.length()).split("\\|", 2);
|
|
199
|
+
if (parts.length != 2) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
String fieldKey = parts[0];
|
|
204
|
+
String memberModel = parts[1];
|
|
205
|
+
MulBasedataDynamicObjectCollection coll = (MulBasedataDynamicObjectCollection) getModel().getValue(fieldKey);
|
|
206
|
+
|
|
207
|
+
Set<Object> existingMemberIds = new LinkedHashSet<>();
|
|
208
|
+
for (DynamicObject row : coll) {
|
|
209
|
+
DynamicObject member = row.getDynamicObject("fbasedataid");
|
|
210
|
+
Object memberId = DynamicObjectUtils.nullSafeGet(member, "id");
|
|
211
|
+
if (EntityUtils.isNotEmptyPk(memberId)) {
|
|
212
|
+
existingMemberIds.add(memberId);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
int addedCount = 0;
|
|
217
|
+
for (DynamicObject selectedRow : selectedRows) {
|
|
218
|
+
Object memberId = selectedRow.get("mid1");
|
|
219
|
+
if (EntityUtils.isEmptyPk(memberId) || !existingMemberIds.add(memberId)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
DynamicObject row = coll.addNew();
|
|
223
|
+
DynamicObject member = DynamicObjectUtils.newDynamicObject(memberModel);
|
|
224
|
+
member.set("id", memberId);
|
|
225
|
+
row.set("fbasedataid", member);
|
|
226
|
+
addedCount++;
|
|
227
|
+
}
|
|
228
|
+
if (addedCount == 0) {
|
|
229
|
+
getView().showTipNotification(ResManager.loadKDString("所选成员已全部存在,无需重复回填", "OpenBillModalSample_6", RES_APP_ID));
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
getModel().setValue(fieldKey, coll);
|
|
233
|
+
getView().updateView(fieldKey);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private int resolveBudgetRowIndex() {
|
|
237
|
+
IPageCache pageCache = getPageCache();
|
|
238
|
+
String rowText = pageCache.get(PAGE_CACHE_BUDGET_ROW);
|
|
239
|
+
pageCache.remove(PAGE_CACHE_BUDGET_ROW);
|
|
240
|
+
if (rowText == null) {
|
|
241
|
+
return getModel().getEntryCurrentRowIndex(BILL_ENTRY);
|
|
242
|
+
}
|
|
243
|
+
return Integer.parseInt(rowText);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private boolean isValidEntryRow(int rowIndex) {
|
|
247
|
+
return rowIndex >= 0 && rowIndex < getModel().getEntryEntity(BILL_ENTRY).size();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private String toText(Object value) {
|
|
251
|
+
return value == null ? "" : String.valueOf(value).trim();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 子页面选中数据后 returnDataToParent(...) 示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件、单据插件
|
|
5
|
+
* 优先封装:AbstractFormPluginExt
|
|
6
|
+
* 原生兜底:returnDataToParent(...)、sendFormAction(...)、IFormView
|
|
7
|
+
* 相关 lint 规则:当前无专门规则,可参考 SCENE-005、STYLE-013、RESOURCE-002
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 单行 Map 回传,父页面按目标行覆盖;
|
|
11
|
+
* 2. List<Map> 回传,父页面批量追加并去重;
|
|
12
|
+
* 3. 子页面直接修改父页面模型后 sendFormAction。
|
|
13
|
+
*/
|
|
14
|
+
package kd.cd.common.snippets.form;
|
|
15
|
+
|
|
16
|
+
import kd.bos.bill.OperationStatus;
|
|
17
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
18
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
19
|
+
import kd.bos.entity.datamodel.IDataModel;
|
|
20
|
+
import kd.bos.form.CloseCallBack;
|
|
21
|
+
import kd.bos.form.FormShowParameter;
|
|
22
|
+
import kd.bos.form.IFormView;
|
|
23
|
+
import kd.bos.form.ShowType;
|
|
24
|
+
import kd.bos.form.control.Control;
|
|
25
|
+
import kd.bos.form.control.events.RowClickEvent;
|
|
26
|
+
import kd.bos.form.control.events.RowClickEventListener;
|
|
27
|
+
import kd.bos.form.events.ClosedCallBackEvent;
|
|
28
|
+
import kd.cd.common.entity.EntityUtils;
|
|
29
|
+
import kd.cd.common.form.ShowParameterUtils;
|
|
30
|
+
import kd.cd.common.plugin.AbstractFormPluginExt;
|
|
31
|
+
import kd.cd.core.util.CharSequenceUtils;
|
|
32
|
+
import kd.cd.core.util.CollectionUtils;
|
|
33
|
+
|
|
34
|
+
import java.util.ArrayList;
|
|
35
|
+
import java.util.Collections;
|
|
36
|
+
import java.util.EventObject;
|
|
37
|
+
import java.util.HashMap;
|
|
38
|
+
import java.util.HashSet;
|
|
39
|
+
import java.util.List;
|
|
40
|
+
import java.util.Map;
|
|
41
|
+
import java.util.Set;
|
|
42
|
+
|
|
43
|
+
public class ReturnParentDataSample extends AbstractFormPluginExt implements RowClickEventListener {
|
|
44
|
+
private static final String ENTRY_KEY = "entryentity";
|
|
45
|
+
private static final String BTN_OK = "btnok";
|
|
46
|
+
private static final String FIELD_NUMBER = "number";
|
|
47
|
+
private static final String FIELD_NAME = "name";
|
|
48
|
+
private static final String FIELD_OWNER = "owner";
|
|
49
|
+
private static final String PARENT_REMARK = "remark";
|
|
50
|
+
private static final String CALLBACK_CHILD_SELECT = "select_from_child";
|
|
51
|
+
private static final String CHILD_FORM_ID = "xxxx_child_selector";
|
|
52
|
+
private static final String CUSTOM_PARAM_TARGET_ROW_INDEX = "targetRowIndex";
|
|
53
|
+
private static final String RES_APP_ID = "kd-cd-common-snippets";
|
|
54
|
+
|
|
55
|
+
@Override
|
|
56
|
+
public void registerListener(EventObject e) {
|
|
57
|
+
super.registerListener(e);
|
|
58
|
+
addClickListeners(BTN_OK);
|
|
59
|
+
addEntryRowClickListeners(ENTRY_KEY);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Override
|
|
63
|
+
public void click(EventObject evt) {
|
|
64
|
+
super.click(evt);
|
|
65
|
+
Control control = (Control) evt.getSource();
|
|
66
|
+
if (BTN_OK.equalsIgnoreCase(control.getKey())) {
|
|
67
|
+
returnSelectedData();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Override
|
|
72
|
+
public void entryRowDoubleClick(RowClickEvent evt) {
|
|
73
|
+
DynamicObject row = resolveRowByIndex(evt.getRow());
|
|
74
|
+
if (row != null) {
|
|
75
|
+
returnSingleRow(row);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private void returnSelectedData() {
|
|
80
|
+
List<DynamicObject> selectedRows = getEntrySelectRowsEntity(ENTRY_KEY);
|
|
81
|
+
if (CollectionUtils.isNotEmpty(selectedRows)) {
|
|
82
|
+
if (selectedRows.size() == 1) {
|
|
83
|
+
returnSingleRow(selectedRows.get(0));
|
|
84
|
+
} else {
|
|
85
|
+
returnMultiRows(selectedRows);
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
DynamicObject currentRow = resolveRowByIndex(getModel().getEntryCurrentRowIndex(ENTRY_KEY));
|
|
91
|
+
if (currentRow == null) {
|
|
92
|
+
getView().showTipNotification(ResManager.loadKDString("请先选择一行数据", "ReturnParentDataSample_0", RES_APP_ID));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
returnSingleRow(currentRow);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private void returnSingleRow(DynamicObject row) {
|
|
99
|
+
Map<String, String> result = buildRowResult(row);
|
|
100
|
+
if (CollectionUtils.isEmpty(result)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
getView().returnDataToParent(result);
|
|
104
|
+
getView().close();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private void returnMultiRows(List<DynamicObject> selectedRows) {
|
|
108
|
+
List<Map<String, String>> resultList = new ArrayList<>(selectedRows.size());
|
|
109
|
+
for (DynamicObject row : selectedRows) {
|
|
110
|
+
Map<String, String> result = buildRowResult(row);
|
|
111
|
+
if (!result.isEmpty()) {
|
|
112
|
+
resultList.add(result);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (CollectionUtils.isEmpty(resultList)) {
|
|
116
|
+
getView().showTipNotification(ResManager.loadKDString("所选数据无可回传内容", "ReturnParentDataSample_1", RES_APP_ID));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
getView().returnDataToParent(resultList);
|
|
120
|
+
getView().close();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private Map<String, String> buildRowResult(DynamicObject row) {
|
|
124
|
+
Object ownerId = row.get(FIELD_OWNER + "_id");
|
|
125
|
+
if (EntityUtils.isEmptyPk(ownerId)) {
|
|
126
|
+
getView().showErrorNotification(ResManager.loadKDString("所选行未设置负责人,不能回传", "ReturnParentDataSample_2", RES_APP_ID));
|
|
127
|
+
return Collections.emptyMap();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
String number = row.getString(FIELD_NUMBER);
|
|
131
|
+
if (CharSequenceUtils.isBlank(number)) {
|
|
132
|
+
getView().showErrorNotification(ResManager.loadKDString("所选行编码为空,不能回传", "ReturnParentDataSample_3", RES_APP_ID));
|
|
133
|
+
return Collections.emptyMap();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Map<String, String> result = new HashMap<>(4);
|
|
137
|
+
result.put(FIELD_NUMBER, number);
|
|
138
|
+
result.put(FIELD_NAME, row.getString(FIELD_NAME));
|
|
139
|
+
result.put("ownerId", String.valueOf(ownerId));
|
|
140
|
+
|
|
141
|
+
int targetRowIndex = resolveRowIndex(getView().getFormShowParameter().getCustomParam(CUSTOM_PARAM_TARGET_ROW_INDEX));
|
|
142
|
+
if (targetRowIndex >= 0) {
|
|
143
|
+
result.put(CUSTOM_PARAM_TARGET_ROW_INDEX, String.valueOf(targetRowIndex));
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public void writeBackToParentDirectly() {
|
|
149
|
+
DynamicObject currentRow = resolveRowByIndex(getModel().getEntryCurrentRowIndex(ENTRY_KEY));
|
|
150
|
+
IFormView parentView = getView().getParentView();
|
|
151
|
+
if (currentRow == null || parentView == null) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
IDataModel parentModel = parentView.getModel();
|
|
156
|
+
int targetRowIndex = resolveRowIndex(
|
|
157
|
+
getView().getFormShowParameter().getCustomParam(CUSTOM_PARAM_TARGET_ROW_INDEX)
|
|
158
|
+
);
|
|
159
|
+
if (isValidParentRow(parentModel, targetRowIndex)) {
|
|
160
|
+
parentModel.setValue(FIELD_NUMBER, currentRow.get(FIELD_NUMBER), targetRowIndex);
|
|
161
|
+
parentModel.setValue(FIELD_NAME, currentRow.get(FIELD_NAME), targetRowIndex);
|
|
162
|
+
parentModel.setValue(FIELD_OWNER, currentRow.get(FIELD_OWNER), targetRowIndex);
|
|
163
|
+
parentView.updateView(ENTRY_KEY);
|
|
164
|
+
} else {
|
|
165
|
+
parentModel.setValue(PARENT_REMARK, currentRow.get(FIELD_NAME));
|
|
166
|
+
parentView.updateView(PARENT_REMARK);
|
|
167
|
+
}
|
|
168
|
+
getView().sendFormAction(parentView);
|
|
169
|
+
getView().close();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private DynamicObject resolveRowByIndex(int rowIndex) {
|
|
173
|
+
List<DynamicObject> rows = getModel().getEntryEntity(ENTRY_KEY);
|
|
174
|
+
if (rowIndex < 0 || rowIndex >= rows.size()) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
return rows.get(rowIndex);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private boolean isValidParentRow(IDataModel parentModel, int rowIndex) {
|
|
181
|
+
int rowCount = parentModel.getDataEntity(true).getDynamicObjectCollection(ENTRY_KEY).size();
|
|
182
|
+
return rowIndex >= 0 && rowIndex < rowCount;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 父页面侧:打开子页面,并在 closedCallBack 中消费回传数据。
|
|
187
|
+
*/
|
|
188
|
+
public static class ParentReceiveSide extends AbstractFormPluginExt {
|
|
189
|
+
public void openChildSelector() {
|
|
190
|
+
FormShowParameter fsp = ShowParameterUtils.getForm(
|
|
191
|
+
CHILD_FORM_ID,
|
|
192
|
+
OperationStatus.ADDNEW,
|
|
193
|
+
ShowType.Modal,
|
|
194
|
+
"800px",
|
|
195
|
+
"600px"
|
|
196
|
+
);
|
|
197
|
+
int rowIndex = getModel().getEntryCurrentRowIndex(ENTRY_KEY);
|
|
198
|
+
if (rowIndex >= 0) {
|
|
199
|
+
fsp.setCustomParam(CUSTOM_PARAM_TARGET_ROW_INDEX, rowIndex);
|
|
200
|
+
}
|
|
201
|
+
fsp.setCloseCallBack(new CloseCallBack(this, CALLBACK_CHILD_SELECT));
|
|
202
|
+
getView().showForm(fsp);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@Override
|
|
206
|
+
public void closedCallBack(ClosedCallBackEvent e) {
|
|
207
|
+
super.closedCallBack(e);
|
|
208
|
+
// 回调数据类型和子页面 returnDataToParent(...) 的回传类型保持一致即可。
|
|
209
|
+
if (!CALLBACK_CHILD_SELECT.equals(e.getActionId())) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
Object returnData = e.getReturnData();
|
|
213
|
+
if (returnData == null) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (returnData instanceof List<?>) {
|
|
217
|
+
@SuppressWarnings("unchecked")
|
|
218
|
+
List<Map<?, ?>> returnDataList = (List<Map<?, ?>>) returnData;
|
|
219
|
+
applyReturnedList(returnDataList);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
applyReturnedMap((Map<?, ?>) returnData);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private void applyReturnedMap(Map<?, ?> returnData) {
|
|
226
|
+
int rowIndex = resolveRowIndex(returnData.get(CUSTOM_PARAM_TARGET_ROW_INDEX));
|
|
227
|
+
if (!isValidEntryRow(rowIndex)) {
|
|
228
|
+
rowIndex = getModel().getEntryCurrentRowIndex(ENTRY_KEY);
|
|
229
|
+
}
|
|
230
|
+
if (!isValidEntryRow(rowIndex)) {
|
|
231
|
+
rowIndex = getModel().createNewEntryRow(ENTRY_KEY);
|
|
232
|
+
}
|
|
233
|
+
fillParentRow(rowIndex, returnData);
|
|
234
|
+
getModel().setEntryCurrentRowIndex(ENTRY_KEY, rowIndex);
|
|
235
|
+
getView().updateView(ENTRY_KEY);
|
|
236
|
+
getView().showSuccessNotification(ResManager.loadKDString("已回填当前行数据", "ReturnParentDataSample_4", RES_APP_ID));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private void applyReturnedList(List<Map<?, ?>> returnDataList) {
|
|
240
|
+
Set<String> existingNumbers = collectExistingNumbers();
|
|
241
|
+
int addedCount = 0;
|
|
242
|
+
int lastRowIndex = -1;
|
|
243
|
+
for (Map<?, ?> rowData : returnDataList) {
|
|
244
|
+
String number = String.valueOf(rowData.get(FIELD_NUMBER));
|
|
245
|
+
if (CharSequenceUtils.isBlank(number) || !existingNumbers.add(number)) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
lastRowIndex = getModel().createNewEntryRow(ENTRY_KEY);
|
|
249
|
+
fillParentRow(lastRowIndex, rowData);
|
|
250
|
+
addedCount++;
|
|
251
|
+
}
|
|
252
|
+
if (addedCount == 0) {
|
|
253
|
+
getView().showTipNotification(ResManager.loadKDString("回传数据已全部存在,无需重复追加", "ReturnParentDataSample_5", RES_APP_ID));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (lastRowIndex >= 0) {
|
|
257
|
+
getModel().setEntryCurrentRowIndex(ENTRY_KEY, lastRowIndex);
|
|
258
|
+
}
|
|
259
|
+
getView().updateView(ENTRY_KEY);
|
|
260
|
+
getView().showSuccessNotification(String.format(
|
|
261
|
+
ResManager.loadKDString("已追加%s行数据", "ReturnParentDataSample_6", RES_APP_ID),
|
|
262
|
+
addedCount
|
|
263
|
+
));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private void fillParentRow(int rowIndex, Map<?, ?> returnData) {
|
|
267
|
+
getModel().setValue(FIELD_NUMBER, returnData.get(FIELD_NUMBER), rowIndex);
|
|
268
|
+
getModel().setValue(FIELD_NAME, returnData.get(FIELD_NAME), rowIndex);
|
|
269
|
+
getModel().setItemValueByID(FIELD_OWNER, returnData.get("ownerId"), rowIndex);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private Set<String> collectExistingNumbers() {
|
|
273
|
+
List<DynamicObject> rows = getModel().getEntryEntity(ENTRY_KEY);
|
|
274
|
+
Set<String> numbers = new HashSet<>(rows.size());
|
|
275
|
+
for (DynamicObject row : rows) {
|
|
276
|
+
String number = row.getString(FIELD_NUMBER);
|
|
277
|
+
if (CharSequenceUtils.isNotBlank(number)) {
|
|
278
|
+
numbers.add(number);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return numbers;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private boolean isValidEntryRow(int rowIndex) {
|
|
285
|
+
return rowIndex >= 0 && rowIndex < getModel().getEntryEntity(ENTRY_KEY).size();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private static int resolveRowIndex(Object rowValue) {
|
|
290
|
+
if (rowValue == null) {
|
|
291
|
+
return -1;
|
|
292
|
+
}
|
|
293
|
+
return Integer.parseInt(String.valueOf(rowValue).trim());
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 树形控件(TreeView)交互示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件
|
|
5
|
+
* 优先封装:AbstractFormPluginExt、PageCache
|
|
6
|
+
* 原生兜底:TreeView、TreeNode、SerializationUtils
|
|
7
|
+
* 相关 lint 规则:当前无专门规则,可参考 SCENE-005、RESOURCE-002
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 动态构建实体树形结构;
|
|
11
|
+
* 2. 树节点点击/双击事件处理;
|
|
12
|
+
* 3. 树节点搜索定位;
|
|
13
|
+
* 4. 多选/单选节点回传。
|
|
14
|
+
*/
|
|
15
|
+
package kd.cd.common.snippets.form;
|
|
16
|
+
|
|
17
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
18
|
+
import kd.bos.dataentity.serialization.SerializationUtils;
|
|
19
|
+
import kd.bos.entity.tree.TreeNode;
|
|
20
|
+
import kd.bos.form.control.Search;
|
|
21
|
+
import kd.bos.form.control.TreeView;
|
|
22
|
+
import kd.bos.form.control.events.ItemClickEvent;
|
|
23
|
+
import kd.bos.form.control.events.SearchEnterEvent;
|
|
24
|
+
import kd.bos.form.control.events.SearchEnterListener;
|
|
25
|
+
import kd.bos.form.control.events.TreeNodeClickListener;
|
|
26
|
+
import kd.bos.form.control.events.TreeNodeEvent;
|
|
27
|
+
import kd.cd.common.plugin.AbstractFormPluginExt;
|
|
28
|
+
import kd.cd.core.util.CharSequenceUtils;
|
|
29
|
+
import kd.cd.core.util.CollectionUtils;
|
|
30
|
+
|
|
31
|
+
import java.util.ArrayList;
|
|
32
|
+
import java.util.EventObject;
|
|
33
|
+
import java.util.List;
|
|
34
|
+
|
|
35
|
+
public class TreeControlSample extends AbstractFormPluginExt implements TreeNodeClickListener, SearchEnterListener {
|
|
36
|
+
private static final String TREE_CONTROL_KEY = "kdcd_treeviewap";
|
|
37
|
+
private static final String ROOT_NODE_CACHE = "rootjson";
|
|
38
|
+
private static final String BTN_OK = "kdcd_ok";
|
|
39
|
+
private static final String MULTI_SELECT_PARAM = "mutiSelect";
|
|
40
|
+
private static final String RES_APP_ID = "kd-cd-common-snippets";
|
|
41
|
+
|
|
42
|
+
// --- 注册树控件和搜索框监听 ---
|
|
43
|
+
@Override
|
|
44
|
+
public void registerListener(EventObject e) {
|
|
45
|
+
super.registerListener(e);
|
|
46
|
+
TreeView tree = getTreeView();
|
|
47
|
+
tree.addTreeNodeClickListener(this);
|
|
48
|
+
Search search = getControl("kdcd_searchap");
|
|
49
|
+
search.addEnterListener(this);
|
|
50
|
+
addItemClickListeners("kdcd_toolbarap");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// --- 初始化树结构 ---
|
|
54
|
+
private void buildTree(String entityId, String entryKey, boolean multiSelect) {
|
|
55
|
+
TreeView tree = getTreeView();
|
|
56
|
+
String rootId = CharSequenceUtils.isBlank(entryKey) ? entityId : entryKey;
|
|
57
|
+
TreeNode root = recoverRootNode();
|
|
58
|
+
tree.addNode(root);
|
|
59
|
+
tree.setRootVisible(true);
|
|
60
|
+
tree.expand(rootId);
|
|
61
|
+
tree.setMulti(multiSelect);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// --- 构建根节点(从自定义参数或缓存恢复) ---
|
|
65
|
+
private TreeNode recoverRootNode() {
|
|
66
|
+
String rootJsonString = getPageCache().get(ROOT_NODE_CACHE);
|
|
67
|
+
return SerializationUtils.fromJsonString(rootJsonString, TreeNode.class);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// --- 树节点双击事件:选中并返回 ---
|
|
71
|
+
@Override
|
|
72
|
+
public void treeNodeDoubleClick(TreeNodeEvent evt) {
|
|
73
|
+
closeAndReturnData();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// --- 搜索框回车事件:定位匹配节点 ---
|
|
77
|
+
@Override
|
|
78
|
+
public void search(SearchEnterEvent evt) {
|
|
79
|
+
String searchText = evt.getText();
|
|
80
|
+
if (CharSequenceUtils.isBlank(searchText)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
TreeNode root = recoverRootNode();
|
|
85
|
+
List<String> ids = loadSearchIds(root, searchText);
|
|
86
|
+
|
|
87
|
+
if (CollectionUtils.isEmpty(ids)) {
|
|
88
|
+
getPageCache().put(searchText, null);
|
|
89
|
+
getView().showSuccessNotification(ResManager.loadKDString("已是最后一个", "TreeControlSample_0", RES_APP_ID));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 定位到第一个匹配节点
|
|
94
|
+
String currId = ids.get(0);
|
|
95
|
+
ids.remove(0);
|
|
96
|
+
getPageCache().put(searchText, SerializationUtils.toJsonString(ids));
|
|
97
|
+
|
|
98
|
+
TreeNode currNode = root.getTreeNode(currId);
|
|
99
|
+
getTreeView().focusNode(currNode);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --- 确定按钮点击:返回选中数据 ---
|
|
103
|
+
@Override
|
|
104
|
+
public void itemClick(ItemClickEvent evt) {
|
|
105
|
+
super.itemClick(evt);
|
|
106
|
+
if (BTN_OK.equals(evt.getItemKey())) {
|
|
107
|
+
closeAndReturnData();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// --- 关闭页面并返回选中数据 ---
|
|
112
|
+
private void closeAndReturnData() {
|
|
113
|
+
TreeView tree = getTreeView();
|
|
114
|
+
Object returnData = Boolean.TRUE.equals(getCustomParam(MULTI_SELECT_PARAM))
|
|
115
|
+
? tree.getTreeState().getSelectedNodes()
|
|
116
|
+
: tree.getTreeState().getFocusNode();
|
|
117
|
+
getView().returnDataToParent(returnData);
|
|
118
|
+
getView().close();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@SuppressWarnings("unchecked")
|
|
122
|
+
private List<String> loadSearchIds(TreeNode root, String searchText) {
|
|
123
|
+
String cachedIds = getPageCache().get(searchText);
|
|
124
|
+
if (cachedIds != null) {
|
|
125
|
+
return SerializationUtils.fromJsonString(cachedIds, List.class);
|
|
126
|
+
}
|
|
127
|
+
List<TreeNode> matchedNodes = root.getTreeNodeListByText(new ArrayList<>(0), searchText, 10000);
|
|
128
|
+
List<String> ids = new ArrayList<>(matchedNodes.size());
|
|
129
|
+
for (TreeNode matchedNode : matchedNodes) {
|
|
130
|
+
ids.add(matchedNode.getId());
|
|
131
|
+
}
|
|
132
|
+
getPageCache().put(searchText, SerializationUtils.toJsonString(ids));
|
|
133
|
+
return ids;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// --- 获取树控件实例 ---
|
|
137
|
+
private TreeView getTreeView() {
|
|
138
|
+
return getControl(TREE_CONTROL_KEY);
|
|
139
|
+
}
|
|
140
|
+
}
|