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,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后端数据对象批量新建 / 批量保存 / 批量查询 / 批量复制示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:操作插件、服务层、后台任务
|
|
5
|
+
* 优先封装:DynamicObjectUtils、OpUtils
|
|
6
|
+
* 原生兜底:BusinessDataServiceHelper、SaveServiceHelper、QueryServiceHelper
|
|
7
|
+
* 相关 lint 规则:STYLE-003、STYLE-008、STYLE-015
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 在服务层或操作插件中一次性构建多张单据数据包;
|
|
11
|
+
* 2. 批量保存、批量提交、批量复制备份;
|
|
12
|
+
* 3. 按主键集合、表头条件、单据体条件批量查询数据。
|
|
13
|
+
*/
|
|
14
|
+
package kd.cd.common.snippets.data;
|
|
15
|
+
|
|
16
|
+
import kd.bos.dataentity.OperateOption;
|
|
17
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
18
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
19
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
20
|
+
import kd.bos.orm.query.QCP;
|
|
21
|
+
import kd.bos.orm.query.QFilter;
|
|
22
|
+
import kd.bos.servicehelper.BusinessDataServiceHelper;
|
|
23
|
+
import kd.bos.servicehelper.QueryServiceHelper;
|
|
24
|
+
import kd.bos.servicehelper.operation.SaveServiceHelper;
|
|
25
|
+
import kd.cd.common.operate.OpUtils;
|
|
26
|
+
import kd.cd.common.util.DynamicObjectUtils;
|
|
27
|
+
import kd.cd.core.util.CollectionUtils;
|
|
28
|
+
|
|
29
|
+
import java.util.ArrayList;
|
|
30
|
+
import java.util.Arrays;
|
|
31
|
+
import java.util.Collection;
|
|
32
|
+
import java.util.List;
|
|
33
|
+
import java.util.Map;
|
|
34
|
+
import java.util.stream.Collectors;
|
|
35
|
+
|
|
36
|
+
public class DynamicObjectCrudSample {
|
|
37
|
+
private static final String FORM_ID = "kded_simplebill";
|
|
38
|
+
private static final String ENTRY_KEY = "entryentity";
|
|
39
|
+
private static final String SUBENTRY_KEY = "subentryentity";
|
|
40
|
+
private static final String FIELD_BILL_NO = "billno";
|
|
41
|
+
private static final String FIELD_STATUS = "billstatus";
|
|
42
|
+
private static final String FIELD_REMARK = "remark";
|
|
43
|
+
private static final String FIELD_ENTRY_TEXT = "kded_dealdesc";
|
|
44
|
+
private static final String FIELD_SUB_TEXT = "kded_subdec";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 批量构建表头数据包,适合导入暂存、批量生成草稿单据。
|
|
48
|
+
*/
|
|
49
|
+
public DynamicObject[] newBills(List<String> billNos) {
|
|
50
|
+
List<DynamicObject> bills = new ArrayList<>(billNos.size());
|
|
51
|
+
int index = 1;
|
|
52
|
+
for (String billNo : billNos) {
|
|
53
|
+
DynamicObject bill = DynamicObjectUtils.newDynamicObject(FORM_ID);
|
|
54
|
+
bill.set(FIELD_BILL_NO, billNo);
|
|
55
|
+
bill.set(FIELD_STATUS, "A");
|
|
56
|
+
bill.set(FIELD_REMARK, String.format(
|
|
57
|
+
ResManager.loadKDString("批量代码创建-%s", "DynamicObjectCrudSample_0", "kd-cd-common-snippets"),
|
|
58
|
+
index
|
|
59
|
+
));
|
|
60
|
+
bills.add(bill);
|
|
61
|
+
index++;
|
|
62
|
+
}
|
|
63
|
+
return bills.toArray(new DynamicObject[0]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 批量构建含单据体 / 子单据体的数据包,适合批量造单后统一保存。
|
|
68
|
+
*/
|
|
69
|
+
public DynamicObject[] newBillsWithEntryAndSubEntry(List<String> billNos) {
|
|
70
|
+
DynamicObject[] bills = newBills(billNos);
|
|
71
|
+
for (int index = 0; index < bills.length; index++) {
|
|
72
|
+
DynamicObject bill = bills[index];
|
|
73
|
+
DynamicObjectCollection entryRows = bill.getDynamicObjectCollection(ENTRY_KEY);
|
|
74
|
+
DynamicObject entryRow = entryRows.addNew();
|
|
75
|
+
entryRow.set(FIELD_ENTRY_TEXT, String.format(
|
|
76
|
+
ResManager.loadKDString("批量代码新增单据体-%s", "DynamicObjectCrudSample_1", "kd-cd-common-snippets"),
|
|
77
|
+
index + 1
|
|
78
|
+
));
|
|
79
|
+
|
|
80
|
+
DynamicObjectCollection subRows = entryRow.getDynamicObjectCollection(SUBENTRY_KEY);
|
|
81
|
+
DynamicObject subRow = subRows.addNew();
|
|
82
|
+
subRow.set(FIELD_SUB_TEXT, String.format(
|
|
83
|
+
ResManager.loadKDString("批量代码新增子单据体-%s", "DynamicObjectCrudSample_2", "kd-cd-common-snippets"),
|
|
84
|
+
index + 1
|
|
85
|
+
));
|
|
86
|
+
}
|
|
87
|
+
return bills;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 批量保存并触发保存校验 / 保存插件。
|
|
92
|
+
*/
|
|
93
|
+
public void saveOpBatch(Collection<DynamicObject> bills) {
|
|
94
|
+
if (CollectionUtils.isNotEmpty(bills)) {
|
|
95
|
+
SaveServiceHelper.saveOperate(FORM_ID, bills.toArray(new DynamicObject[0]), OperateOption.create());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 批量直接保存,适合已完成预校验的后台修数 / 中间表同步。
|
|
101
|
+
*/
|
|
102
|
+
public void saveBatchDirectly(Collection<DynamicObject> bills) {
|
|
103
|
+
if (CollectionUtils.isNotEmpty(bills)) {
|
|
104
|
+
SaveServiceHelper.save(bills.toArray(new DynamicObject[0]));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 批量提交,失败抛出异常,适合保存后统一提交流程。
|
|
110
|
+
*/
|
|
111
|
+
public void submitBatch(Collection<DynamicObject> bills) {
|
|
112
|
+
if (CollectionUtils.isNotEmpty(bills)) {
|
|
113
|
+
OpUtils.executeOperateOrThrow("submit", FORM_ID, bills.toArray(new DynamicObject[0]));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 按主键集合批量加载实体包,适合后续统一修改后再保存。
|
|
119
|
+
*/
|
|
120
|
+
public DynamicObject[] loadByPks(Collection<?> pkValues) {
|
|
121
|
+
return BusinessDataServiceHelper.load(
|
|
122
|
+
FORM_ID,
|
|
123
|
+
"id,billno,billstatus,remark," + ENTRY_KEY + "." + FIELD_ENTRY_TEXT,
|
|
124
|
+
new QFilter("id", QCP.in, pkValues).toArray()
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 按创建人批量查询单据,适合批量重算、批量审核前的候选集准备。
|
|
130
|
+
*/
|
|
131
|
+
public DynamicObject[] queryByCreatorNames(Collection<String> creatorNames) {
|
|
132
|
+
return BusinessDataServiceHelper.load(
|
|
133
|
+
FORM_ID,
|
|
134
|
+
"id,billno,creator,creator.id,createtime",
|
|
135
|
+
new QFilter("creator.name", QCP.in, creatorNames).toArray()
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 按分录业务员批量查询扁平结果,适合做分组、校验、汇总,不适合直接回写保存。
|
|
141
|
+
*/
|
|
142
|
+
public DynamicObjectCollection queryByEntryUserNames(Collection<String> userNames) {
|
|
143
|
+
return QueryServiceHelper.query(
|
|
144
|
+
FORM_ID,
|
|
145
|
+
"id,billno,entryentity.kded_dealuser.name,entryentity.kded_dealdesc",
|
|
146
|
+
new QFilter("entryentity.kded_dealuser.name", QCP.in, userNames).toArray()
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ==================== 特殊情况:基础资料属性字段(BasedataPropField)查询取值 ====================
|
|
151
|
+
// BasedataPropField 是基础资料的派生显示字段,它的标识(如 e_materialname)是表单控件标识,
|
|
152
|
+
// 在查询的 select 字段和 QFilter 中必须使用元数据中的「引用关系」路径。
|
|
153
|
+
//
|
|
154
|
+
// 示例:元数据查询结果
|
|
155
|
+
// 标识: e_materialname | 类型: BasedataPropField | 引用关系: e_material.name
|
|
156
|
+
//
|
|
157
|
+
// ✅ 正确:使用引用关系路径
|
|
158
|
+
// select: "entryentity.e_material.name"
|
|
159
|
+
// filter: new QFilter("entryentity.e_material.name", QCP.like, "%某物料%")
|
|
160
|
+
//
|
|
161
|
+
// ❌ 错误:使用控件标识(查询时无法识别)
|
|
162
|
+
// select: "entryentity.e_materialname"
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 按分录物料名称查询,演示 BasedataPropField 在查询中的正确用法。
|
|
166
|
+
*/
|
|
167
|
+
public DynamicObjectCollection queryByMaterialName(String materialName) {
|
|
168
|
+
return QueryServiceHelper.query(
|
|
169
|
+
FORM_ID,
|
|
170
|
+
// ✅ select 中使用引用关系路径 e_material.name,而非控件标识 e_materialname
|
|
171
|
+
"id,billno," + ENTRY_KEY + ".e_material.name," + ENTRY_KEY + ".e_material.number",
|
|
172
|
+
new QFilter(ENTRY_KEY + ".e_material.name", QCP.like, "%" + materialName + "%").toArray()
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 批量复制单据作为备份包,适合修改前先批量做快照。
|
|
178
|
+
*/
|
|
179
|
+
public DynamicObject[] cloneBatchForBackup(Collection<DynamicObject> origins) {
|
|
180
|
+
List<DynamicObject> backups = new ArrayList<>(origins.size());
|
|
181
|
+
for (DynamicObject origin : origins) {
|
|
182
|
+
if (origin == null) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
DynamicObject backup = DynamicObjectUtils.clone(origin);
|
|
186
|
+
backup.set(FIELD_REMARK, String.format(
|
|
187
|
+
ResManager.loadKDString("批量备份-%s", "DynamicObjectCrudSample_3", "kd-cd-common-snippets"),
|
|
188
|
+
origin.getString(FIELD_BILL_NO)
|
|
189
|
+
));
|
|
190
|
+
backups.add(backup);
|
|
191
|
+
}
|
|
192
|
+
return backups.toArray(new DynamicObject[0]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 把批量加载结果转成主键映射,便于后续本地批量反写。
|
|
197
|
+
*/
|
|
198
|
+
public Map<Object, DynamicObject> toPkMap(Collection<?> pkValues) {
|
|
199
|
+
return Arrays.stream(loadByPks(pkValues)).collect(Collectors.toMap(
|
|
200
|
+
DynamicObject::getPkValue,
|
|
201
|
+
bill -> bill,
|
|
202
|
+
(left, right) -> left
|
|
203
|
+
));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynamicObjectUtils 常见能力示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件、操作插件、服务层
|
|
5
|
+
* 优先封装:DynamicObjectUtils
|
|
6
|
+
* 原生兜底:DynamicObject、DynamicObjectCollection 原生 API
|
|
7
|
+
* 相关 lint 规则:STYLE-006、STYLE-015
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 脱离表单模型后,直接操作 DynamicObject / DynamicObjectCollection;
|
|
11
|
+
* 2. 安全取值、批量收集字段值、对象克隆与序列化;
|
|
12
|
+
* 3. 不再重复表单层的 getModel().getValue / setValue 写法。
|
|
13
|
+
*/
|
|
14
|
+
package kd.cd.common.snippets.data;
|
|
15
|
+
|
|
16
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
17
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
18
|
+
import kd.cd.common.util.DynamicObjectUtils;
|
|
19
|
+
import kd.cd.core.util.CollectionUtils;
|
|
20
|
+
|
|
21
|
+
import java.math.BigDecimal;
|
|
22
|
+
import java.util.Collection;
|
|
23
|
+
import java.util.Collections;
|
|
24
|
+
import java.util.List;
|
|
25
|
+
import java.util.Map;
|
|
26
|
+
import java.util.Set;
|
|
27
|
+
|
|
28
|
+
public class DynamicObjectOpsSample {
|
|
29
|
+
|
|
30
|
+
// ==================== 场景1:原生取值 ====================
|
|
31
|
+
|
|
32
|
+
public static Object getValue(DynamicObject bill, String fieldKey) {
|
|
33
|
+
return DynamicObjectUtils.nullSafeGet(bill, fieldKey);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public static Object nullSafeGet(DynamicObject bill, String fieldPath) {
|
|
37
|
+
return DynamicObjectUtils.nullSafeGet(bill, fieldPath);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public static String getBaseDataNumber(DynamicObject bill, String fieldKey) {
|
|
41
|
+
Object number = DynamicObjectUtils.nullSafeGet(bill, fieldKey + ".number");
|
|
42
|
+
return number == null ? "" : String.valueOf(number);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ==================== 特殊情况:基础资料属性字段(BasedataPropField)取值 ====================
|
|
46
|
+
// BasedataPropField 是基础资料的派生显示字段,它的标识(如 e_materialname)是表单控件标识,
|
|
47
|
+
// 在 DynamicObject 上取值时必须使用元数据中的「引用关系」路径。
|
|
48
|
+
//
|
|
49
|
+
// 示例:元数据查询结果
|
|
50
|
+
// 标识: e_materialname | 类型: BasedataPropField | 引用关系: e_material.name
|
|
51
|
+
//
|
|
52
|
+
// ✅ 正确:使用引用关系路径
|
|
53
|
+
// DynamicObjectUtils.nullSafeGet(entryRow, "e_material.name");
|
|
54
|
+
//
|
|
55
|
+
// ❌ 错误:使用控件标识(DynamicObject 上不存在该属性)
|
|
56
|
+
// DynamicObjectUtils.nullSafeGet(entryRow, "e_materialname");
|
|
57
|
+
|
|
58
|
+
// ==================== 场景2:原生赋值 ====================
|
|
59
|
+
|
|
60
|
+
public static void setValue(DynamicObject bill, String fieldKey, Object value) {
|
|
61
|
+
if (bill != null) {
|
|
62
|
+
bill.set(fieldKey, value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public static void batchSetValues(DynamicObject bill, Map<String, Object> fieldValues) {
|
|
67
|
+
if (CollectionUtils.isEmpty(fieldValues)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
fieldValues.forEach(bill::set);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ==================== 场景3:分录集合操作 ====================
|
|
74
|
+
|
|
75
|
+
public static DynamicObjectCollection getEntryRows(DynamicObject bill, String entryKey) {
|
|
76
|
+
return bill.getDynamicObjectCollection(entryKey);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static BigDecimal sumEntryAmount(DynamicObject bill, String entryKey, String amountField) {
|
|
80
|
+
return DynamicObjectUtils.sumOf(getEntryRows(bill, entryKey), amountField);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public static Set<Object> collectEntryIds(Collection<DynamicObject> rows) {
|
|
84
|
+
return CollectionUtils.isEmpty(rows) ? Collections.emptySet() : DynamicObjectUtils.setOfIds(rows);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public static List<String> collectEntryNumbers(Collection<DynamicObject> rows, String numberField) {
|
|
88
|
+
return CollectionUtils.isEmpty(rows) ? Collections.emptyList() : DynamicObjectUtils.listOf(rows, numberField);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ==================== 场景4:调试/排查 ====================
|
|
92
|
+
|
|
93
|
+
public static boolean containsProperty(DynamicObject bill, String fieldKey) {
|
|
94
|
+
return DynamicObjectUtils.containsKey(bill, fieldKey);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public static Map<String, Object> dumpBill(DynamicObject bill) {
|
|
98
|
+
return DynamicObjectUtils.dump(bill);
|
|
99
|
+
}
|
|
100
|
+
}
|
package/vendor/kingdee-skills/ok-cosmic/assets/snippets/form/BeforeOperationConfirmSample.java
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* beforeDoOperation 拦截 + 弹窗确认后继续执行示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件、单据插件
|
|
5
|
+
* 优先封装:ShowParameterUtils、AbstractFormPluginExt
|
|
6
|
+
* 原生兜底:FormOperate、OperateOption、ClosedCallBackEvent
|
|
7
|
+
* 相关 lint 规则:SCENE-008、STYLE-013
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:
|
|
10
|
+
* 1. 提交前先做内存校验,命中风险则打开说明页;
|
|
11
|
+
* 2. 部分检查必须先保存拿到主键,再在 afterDoOperation 中弹结果页;
|
|
12
|
+
* 3. 用户确认后,带 continue 标记重新执行原提交操作。
|
|
13
|
+
*/
|
|
14
|
+
package kd.cd.common.snippets.form;
|
|
15
|
+
|
|
16
|
+
import kd.bos.bill.OperationStatus;
|
|
17
|
+
import kd.bos.dataentity.OperateOption;
|
|
18
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
19
|
+
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
|
20
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
21
|
+
import kd.bos.form.CloseCallBack;
|
|
22
|
+
import kd.bos.form.FormShowParameter;
|
|
23
|
+
import kd.bos.form.ShowType;
|
|
24
|
+
import kd.bos.form.events.AfterDoOperationEventArgs;
|
|
25
|
+
import kd.bos.form.events.BeforeDoOperationEventArgs;
|
|
26
|
+
import kd.bos.form.events.ClosedCallBackEvent;
|
|
27
|
+
import kd.bos.form.operate.FormOperate;
|
|
28
|
+
import kd.bos.orm.query.QCP;
|
|
29
|
+
import kd.bos.orm.query.QFilter;
|
|
30
|
+
import kd.cd.common.entity.EntityUtils;
|
|
31
|
+
import kd.cd.common.form.ShowParameterUtils;
|
|
32
|
+
import kd.cd.common.plugin.AbstractFormPluginExt;
|
|
33
|
+
import kd.cd.common.util.DynamicObjectUtils;
|
|
34
|
+
import kd.cd.core.util.BigDecimalUtils;
|
|
35
|
+
import kd.cd.core.util.CollectionUtils;
|
|
36
|
+
import kd.bos.servicehelper.QueryServiceHelper;
|
|
37
|
+
|
|
38
|
+
import java.util.ArrayList;
|
|
39
|
+
import java.util.Collections;
|
|
40
|
+
import java.util.List;
|
|
41
|
+
import java.util.Map;
|
|
42
|
+
|
|
43
|
+
public class BeforeOperationConfirmSample extends AbstractFormPluginExt {
|
|
44
|
+
private static final String OP_SAVE = "save";
|
|
45
|
+
private static final String OP_SUBMIT = "submit";
|
|
46
|
+
private static final String CHECK_WARNING_FORM_ID = "xxxx_billcheckresult";
|
|
47
|
+
private static final String CHECK_WARNING_CALLBACK_ID = "bill_check_warning";
|
|
48
|
+
private static final String CHECK_RESULT_FORM_ID = "xxxx_billcheckdetail";
|
|
49
|
+
private static final String CHECK_RESULT_CALLBACK_ID = "bill_check_detail";
|
|
50
|
+
private static final String OPTION_CONTINUE = "ContinueToSubmit";
|
|
51
|
+
private static final String OPTION_SAVE_THEN_CHECK = "SaveThenCheck";
|
|
52
|
+
private static final String ENTRY_KEY = "billentry";
|
|
53
|
+
private static final String FIELD_SUPPLIER = "supplier";
|
|
54
|
+
private static final String FIELD_QTY = "qty";
|
|
55
|
+
private static final String FIELD_TAX_AMOUNT = "taxamount";
|
|
56
|
+
private static final String RES_APP_ID = "kd-cd-common-snippets";
|
|
57
|
+
|
|
58
|
+
@Override
|
|
59
|
+
public void beforeDoOperation(BeforeDoOperationEventArgs args) {
|
|
60
|
+
super.beforeDoOperation(args);
|
|
61
|
+
if (args.isCancel()) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
FormOperate operate = (FormOperate) args.getSource();
|
|
66
|
+
if (!OP_SUBMIT.equals(operate.getOperateKey()) || isContinueSubmit(operate.getOption())) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
List<String> warnings = collectSubmitWarnings();
|
|
71
|
+
if (CollectionUtils.isNotEmpty(warnings)) {
|
|
72
|
+
openWarningConfirmForm(warnings);
|
|
73
|
+
args.setCancel(true);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Object billPk = getModel().getDataEntity().getPkValue();
|
|
78
|
+
if (EntityUtils.isEmptyPk(billPk)) {
|
|
79
|
+
OperateOption saveOption = OperateOption.create();
|
|
80
|
+
saveOption.setVariableValue(OPTION_SAVE_THEN_CHECK, "true");
|
|
81
|
+
getView().invokeOperation(OP_SAVE, saveOption);
|
|
82
|
+
args.setCancel(true);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
List<Object> resultIds = queryCheckResultIds(billPk);
|
|
87
|
+
if (CollectionUtils.isNotEmpty(resultIds)) {
|
|
88
|
+
openPersistedCheckResultForm(resultIds);
|
|
89
|
+
args.setCancel(true);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Override
|
|
94
|
+
public void afterDoOperation(AfterDoOperationEventArgs args) {
|
|
95
|
+
super.afterDoOperation(args);
|
|
96
|
+
FormOperate operate = (FormOperate) args.getSource();
|
|
97
|
+
if (OP_SAVE.equals(operate.getOperateKey())) {
|
|
98
|
+
handleSaveAfterCheck(operate, args);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (OP_SUBMIT.equals(operate.getOperateKey())
|
|
102
|
+
&& args.getOperationResult().isSuccess()
|
|
103
|
+
&& isContinueSubmit(operate.getOption())) {
|
|
104
|
+
args.getOperationResult().setMessage(ResManager.loadKDString("提交成功:已按确认结果继续执行", "BeforeOperationConfirmSample_3", RES_APP_ID));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@Override
|
|
109
|
+
public void closedCallBack(ClosedCallBackEvent e) {
|
|
110
|
+
super.closedCallBack(e);
|
|
111
|
+
// 回调数据类型和确认页的回传类型保持一致即可。
|
|
112
|
+
String actionId = e.getActionId();
|
|
113
|
+
if (!CHECK_WARNING_CALLBACK_ID.equals(actionId) && !CHECK_RESULT_CALLBACK_ID.equals(actionId)) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
@SuppressWarnings("unchecked")
|
|
117
|
+
Map<String, Object> returnData = (Map<String, Object>) e.getReturnData();
|
|
118
|
+
if (returnData != null && shouldContinueSubmit(returnData)) {
|
|
119
|
+
invokeContinueSubmit();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private void handleSaveAfterCheck(FormOperate operate, AfterDoOperationEventArgs args) {
|
|
124
|
+
if (!"true".equalsIgnoreCase(operate.getOption().getVariableValue(OPTION_SAVE_THEN_CHECK, "false"))) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (!args.getOperationResult().isSuccess()) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Object billPk = getModel().getDataEntity().getPkValue();
|
|
132
|
+
List<Object> resultIds = queryCheckResultIds(billPk);
|
|
133
|
+
if (CollectionUtils.isEmpty(resultIds)) {
|
|
134
|
+
invokeContinueSubmit();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
openPersistedCheckResultForm(resultIds);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private void openWarningConfirmForm(List<String> warnings) {
|
|
141
|
+
FormShowParameter fsp = ShowParameterUtils.getForm(
|
|
142
|
+
CHECK_WARNING_FORM_ID,
|
|
143
|
+
OperationStatus.VIEW,
|
|
144
|
+
ShowType.Modal,
|
|
145
|
+
"900px",
|
|
146
|
+
"600px"
|
|
147
|
+
);
|
|
148
|
+
fsp.setCustomParam("warnings", warnings);
|
|
149
|
+
fsp.setCloseCallBack(new CloseCallBack(this, CHECK_WARNING_CALLBACK_ID));
|
|
150
|
+
getView().showForm(fsp);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private void openPersistedCheckResultForm(List<Object> resultIds) {
|
|
154
|
+
FormShowParameter fsp = ShowParameterUtils.getForm(
|
|
155
|
+
CHECK_RESULT_FORM_ID,
|
|
156
|
+
OperationStatus.VIEW,
|
|
157
|
+
ShowType.Modal,
|
|
158
|
+
"960px",
|
|
159
|
+
"640px"
|
|
160
|
+
);
|
|
161
|
+
fsp.setCustomParam("sourceBillId", String.valueOf(getModel().getDataEntity().getPkValue()));
|
|
162
|
+
fsp.setCustomParam("resultIds", resultIds);
|
|
163
|
+
fsp.setCloseCallBack(new CloseCallBack(this, CHECK_RESULT_CALLBACK_ID));
|
|
164
|
+
getView().showForm(fsp);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private void invokeContinueSubmit() {
|
|
168
|
+
OperateOption option = OperateOption.create();
|
|
169
|
+
option.setVariableValue(OPTION_CONTINUE, "true");
|
|
170
|
+
getView().invokeOperation(OP_SUBMIT, option);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private List<Object> queryCheckResultIds(Object billPk) {
|
|
174
|
+
if (EntityUtils.isEmptyPk(billPk)) {
|
|
175
|
+
return Collections.emptyList();
|
|
176
|
+
}
|
|
177
|
+
QFilter filter = new QFilter("sourcebill.id", QCP.equals, billPk);
|
|
178
|
+
DynamicObjectCollection rows = QueryServiceHelper.query(CHECK_RESULT_FORM_ID, "id", filter.toArray());
|
|
179
|
+
return DynamicObjectUtils.listOf(rows, "id");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private boolean shouldContinueSubmit(Map<String, Object> returnData) {
|
|
183
|
+
return Boolean.TRUE.equals(returnData.get("confirmed"));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private List<String> collectSubmitWarnings() {
|
|
187
|
+
DynamicObjectCollection entryRows = getModel().getDataEntity(true).getDynamicObjectCollection(ENTRY_KEY);
|
|
188
|
+
List<String> warnings = new ArrayList<>(entryRows.size() * 3);
|
|
189
|
+
for (int i = 0; i < entryRows.size(); i++) {
|
|
190
|
+
DynamicObject row = entryRows.get(i);
|
|
191
|
+
int seq = i + 1;
|
|
192
|
+
if (row.getDynamicObject(FIELD_SUPPLIER) == null) {
|
|
193
|
+
warnings.add(String.format(
|
|
194
|
+
ResManager.loadKDString("第%s行未选择供应商", "BeforeOperationConfirmSample_0", RES_APP_ID),
|
|
195
|
+
seq
|
|
196
|
+
));
|
|
197
|
+
}
|
|
198
|
+
if (BigDecimalUtils.lessEqualsZero(row.getBigDecimal(FIELD_QTY))) {
|
|
199
|
+
warnings.add(String.format(
|
|
200
|
+
ResManager.loadKDString("第%s行数量必须大于0", "BeforeOperationConfirmSample_1", RES_APP_ID),
|
|
201
|
+
seq
|
|
202
|
+
));
|
|
203
|
+
}
|
|
204
|
+
if (row.getBigDecimal(FIELD_TAX_AMOUNT) == null) {
|
|
205
|
+
warnings.add(String.format(
|
|
206
|
+
ResManager.loadKDString("第%s行税额未计算,请先刷新金额", "BeforeOperationConfirmSample_2", RES_APP_ID),
|
|
207
|
+
seq
|
|
208
|
+
));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return warnings;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private boolean isContinueSubmit(OperateOption option) {
|
|
215
|
+
return option != null && "true".equalsIgnoreCase(option.getVariableValue(OPTION_CONTINUE, "false"));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 确认框弹窗 + 回调处理示例。
|
|
3
|
+
* <p>
|
|
4
|
+
* 适用插件:表单插件、单据插件
|
|
5
|
+
* 优先封装:AbstractFormPluginExt、PageCache
|
|
6
|
+
* 原生兜底:ConfirmCallBackListener、MessageBoxOptions、Toolbar
|
|
7
|
+
* 相关 lint 规则:SCENE-005、STYLE-013、RESOURCE-002
|
|
8
|
+
* <p>
|
|
9
|
+
* 使用场景:对分录批量标记、批量关闭、批量清理等动作做二次确认。
|
|
10
|
+
* 关键点:
|
|
11
|
+
* 1. 普通自定义按钮可在 itemClick 中直接弹确认框;
|
|
12
|
+
* 2. 标准工具栏按钮更适合在 beforeItemClick 中先拦截,再在确认后重放原动作;
|
|
13
|
+
* 3. pageCache 可用于避免确认回调后二次拦截。
|
|
14
|
+
*/
|
|
15
|
+
package kd.cd.common.snippets.form;
|
|
16
|
+
|
|
17
|
+
import kd.bos.dataentity.entity.DynamicObject;
|
|
18
|
+
import kd.bos.dataentity.resource.ResManager;
|
|
19
|
+
import kd.bos.form.ConfirmCallBackListener;
|
|
20
|
+
import kd.bos.form.MessageBoxOptions;
|
|
21
|
+
import kd.bos.form.MessageBoxResult;
|
|
22
|
+
import kd.bos.form.control.Toolbar;
|
|
23
|
+
import kd.bos.form.control.events.BeforeItemClickEvent;
|
|
24
|
+
import kd.bos.form.control.events.ItemClickEvent;
|
|
25
|
+
import kd.bos.form.events.MessageBoxClosedEvent;
|
|
26
|
+
import kd.cd.common.plugin.AbstractFormPluginExt;
|
|
27
|
+
import kd.cd.core.util.CollectionUtils;
|
|
28
|
+
|
|
29
|
+
import java.util.EventObject;
|
|
30
|
+
import java.util.List;
|
|
31
|
+
|
|
32
|
+
public class ConfirmDialogSample extends AbstractFormPluginExt {
|
|
33
|
+
private static final String ENTRY_TOOLBAR = "tbmainentry";
|
|
34
|
+
private static final String MAIN_TOOLBAR = "toolbarap";
|
|
35
|
+
private static final String ITEM_MARK_SELECTED = "xxxx_markselected";
|
|
36
|
+
private static final String CALLBACK_MARK_SELECTED = "xxxx_markselected_confirm";
|
|
37
|
+
private static final String ITEM_COPY_HISTORY = "btn_copyhis";
|
|
38
|
+
private static final String PAGE_CACHE_CONFIRM_COPY_HISTORY = "pagecache_confirm_copyhis";
|
|
39
|
+
private static final String ENTRY_KEY = "entryentity";
|
|
40
|
+
private static final String FIELD_MARKED = "xxxx_selected";
|
|
41
|
+
private static final String RES_APP_ID = "kd-cd-common-snippets";
|
|
42
|
+
|
|
43
|
+
// --- 在 registerListener 中注册工具栏按钮 ---
|
|
44
|
+
@Override
|
|
45
|
+
public void registerListener(EventObject e) {
|
|
46
|
+
super.registerListener(e);
|
|
47
|
+
addItemClickListeners(ENTRY_TOOLBAR, MAIN_TOOLBAR);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// --- 标准工具栏按钮:先拦截,再确认后重放原动作 ---
|
|
51
|
+
@Override
|
|
52
|
+
public void beforeItemClick(BeforeItemClickEvent evt) {
|
|
53
|
+
super.beforeItemClick(evt);
|
|
54
|
+
if (!ITEM_COPY_HISTORY.equals(evt.getItemKey())) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if ("true".equals(getView().getPageCache().get(PAGE_CACHE_CONFIRM_COPY_HISTORY))) {
|
|
59
|
+
getView().getPageCache().put(PAGE_CACHE_CONFIRM_COPY_HISTORY, "false");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
evt.setCancel(true);
|
|
64
|
+
getView().showConfirm(
|
|
65
|
+
ResManager.loadKDString("获取上年同期会覆盖当前取数结果,确认继续吗?", "ConfirmDialogSample_0", RES_APP_ID),
|
|
66
|
+
MessageBoxOptions.YesNo,
|
|
67
|
+
new ConfirmCallBackListener(ITEM_COPY_HISTORY, this)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// --- 按钮点击后先弹确认框 ---
|
|
72
|
+
@Override
|
|
73
|
+
public void itemClick(ItemClickEvent evt) {
|
|
74
|
+
super.itemClick(evt);
|
|
75
|
+
if (!ITEM_MARK_SELECTED.equals(evt.getItemKey())) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
List<DynamicObject> selectedRows = getEntrySelectRowsEntity(ENTRY_KEY);
|
|
80
|
+
if (CollectionUtils.isEmpty(selectedRows)) {
|
|
81
|
+
getView().showTipNotification(ResManager.loadKDString("请先选择要处理的分录行", "ConfirmDialogSample_1", RES_APP_ID));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ConfirmCallBackListener listener = new ConfirmCallBackListener(CALLBACK_MARK_SELECTED, this);
|
|
86
|
+
getView().showConfirm(ResManager.loadKDString("确定要标记所选分录吗?", "ConfirmDialogSample_2", RES_APP_ID), MessageBoxOptions.YesNo, listener);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// --- 用户确认后执行实际逻辑 ---
|
|
90
|
+
@Override
|
|
91
|
+
public void confirmCallBack(MessageBoxClosedEvent evt) {
|
|
92
|
+
super.confirmCallBack(evt);
|
|
93
|
+
String callBackId = evt.getCallBackId();
|
|
94
|
+
if (CALLBACK_MARK_SELECTED.equals(callBackId)) {
|
|
95
|
+
if (MessageBoxResult.Yes.equals(evt.getResult())) {
|
|
96
|
+
markSelectedRows();
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (ITEM_COPY_HISTORY.equals(callBackId)) {
|
|
101
|
+
tryReplayToolbarAction(evt);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private void tryReplayToolbarAction(MessageBoxClosedEvent evt) {
|
|
106
|
+
if (!MessageBoxResult.Yes.equals(evt.getResult())) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
getView().getPageCache().put(PAGE_CACHE_CONFIRM_COPY_HISTORY, "true");
|
|
110
|
+
Toolbar toolbar = getControl(MAIN_TOOLBAR);
|
|
111
|
+
toolbar.addItemClickListener(this);
|
|
112
|
+
toolbar.itemClick(ITEM_COPY_HISTORY, "");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private void markSelectedRows() {
|
|
116
|
+
List<DynamicObject> selectedRows = getEntrySelectRowsEntity(ENTRY_KEY);
|
|
117
|
+
if (CollectionUtils.isEmpty(selectedRows)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (DynamicObject row : selectedRows) {
|
|
122
|
+
row.set(FIELD_MARKED, true);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getView().updateView(ENTRY_KEY);
|
|
126
|
+
getView().showSuccessNotification(String.format(
|
|
127
|
+
ResManager.loadKDString("已标记%s行分录", "ConfirmDialogSample_3", RES_APP_ID),
|
|
128
|
+
selectedRows.size()
|
|
129
|
+
));
|
|
130
|
+
}
|
|
131
|
+
}
|