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,149 @@
|
|
|
1
|
+
# 高性能查询与计算 (QueryServiceHelper & AlgoUtils)
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
- 适用:ORM/DataSet 查询、批量聚合、内存计算和少量确需的 SQL 场景。
|
|
5
|
+
- 先抓:`QueryServiceHelper` 负责取数,`AlgoUtils` 负责 `DataSet` 过滤、聚合和转换。
|
|
6
|
+
- 跳转:只是基础资料加载优先 `BusinessDataServiceHelper.loadFromCache`;字段/元数据确认别读本页。
|
|
7
|
+
- 继续读全文:当你要写批量查询、`DataSet` 聚合或原生 SQL 兜底逻辑时。
|
|
8
|
+
|
|
9
|
+
## 概述
|
|
10
|
+
数据查询与处理是苍穹性能优化的第一大战场。`QueryServiceHelper` (位于 `kd.bos.servicehelper`) 提供 ORM 与 SQL 查询能力,极大简化了单条或批量数据的检索逻辑;`AlgoUtils` 针对苍穹特有的 `DataSet` 提供了类 Stream 的内存计算 API,是处理大数据量业务逻辑的首选。
|
|
11
|
+
|
|
12
|
+
> **适用边界**
|
|
13
|
+
> ✅ 适用:单条/批量数据查询、DataSet 内存计算与统计。
|
|
14
|
+
> ❌ 不适用:基础资料查询优先用 `BusinessDataServiceHelper.loadFromCache`;实体查询无法表达的场景才考虑裸 SQL。
|
|
15
|
+
|
|
16
|
+
## 核心类
|
|
17
|
+
- **`kd.bos.servicehelper.QueryServiceHelper`**: **查询核心**。负责从数据库(ORM 或原生 SQL)获取数据。
|
|
18
|
+
- **`kd.cd.common.util.AlgoUtils`**: **计算核心**。负责对 `DataSet` 进行过滤、聚合与转换。
|
|
19
|
+
- **`kd.bos.algo.DataSet`**: 苍穹高性能数据集对象。
|
|
20
|
+
|
|
21
|
+
## QueryServiceHelper API 方法
|
|
22
|
+
|
|
23
|
+
### 1. 单条查询
|
|
24
|
+
- `queryOne(String entityName, String selectFields, QFilter[] filters)`: 查询一条记录。
|
|
25
|
+
- `exists(String entityName, QFilter[] filters)`: 判断是否存在满足条件的记录。
|
|
26
|
+
|
|
27
|
+
### 2. 集合查询
|
|
28
|
+
- `query(String entityName, String selectFields, QFilter[] filters)`: 查询多条记录,返回 DynamicObjectCollection。
|
|
29
|
+
- `query(String entityName, String selectFields, QFilter[] filters, String orderBy)`: 带排序的查询。
|
|
30
|
+
|
|
31
|
+
### 3. 数据集查询
|
|
32
|
+
- `queryDataSet(String formId, String algoKey, String selectFields, QFilter[] filters, String orderBy)`: **最常用**。执行实体查询并返回 DataSet。
|
|
33
|
+
- `queryDataSet(String formId, String algoKey, String selectFields, QFilter[] filters, String orderBy, int top)`: 带条数限制的查询。
|
|
34
|
+
- `queryDataSet(DBRoute dbRoute, String sql)`: 原生 SQL 查询。
|
|
35
|
+
- `queryDataSet(DBRoute dbRoute, String sql, Object[] params)`: 带参数的原生 SQL 查询。
|
|
36
|
+
|
|
37
|
+
## AlgoUtils API 方法
|
|
38
|
+
|
|
39
|
+
### 1. 流处理
|
|
40
|
+
- `stream(DataSet dataSet)`: 提供对 DataSet 的 Stream 流支持。
|
|
41
|
+
|
|
42
|
+
### 2. 过滤与转换
|
|
43
|
+
- `filter(DataSet dataSet, Predicate<Row> filter)`: 对数据集执行高效过滤。
|
|
44
|
+
- `nullToZero(DataSet dataSet, String... fields)`: 将为 null 的字段值更新为 0。
|
|
45
|
+
|
|
46
|
+
### 3. 聚合计算
|
|
47
|
+
- `sumOf(DataSet dataSet, String field)`: 对数据集进行内存求和(返回 BigDecimal)。
|
|
48
|
+
- `listOf(DataSet dataSet, String field)`: 将数据集的一列提取为 List。
|
|
49
|
+
- `listOf(DataSet dataSet, Function<Row, T> function)`: 自定义函数提取为 List。
|
|
50
|
+
- `setOf(DataSet dataSet, String field)`: 将数据集的一列提取为 Set。
|
|
51
|
+
- `setOf(DataSet dataSet, Function<Row, T> function)`: 自定义函数提取为 Set。
|
|
52
|
+
|
|
53
|
+
### 4. 信息获取
|
|
54
|
+
- `fieldsOf(DataSet dataSet)`: 获取 DataSet 中字段数组。
|
|
55
|
+
- `sizeOf(DataSet dataSet)`: 获取 DataSet 大小。
|
|
56
|
+
- `dump(DataSet dataSet, String... fields)`: 转储 DataSet,按字段分组为 List。
|
|
57
|
+
|
|
58
|
+
### 5. 数据集创建
|
|
59
|
+
- `newDataSet(DynamicObjectCollection coll)`: 从 DynamicObjectCollection 创建 DataSet。
|
|
60
|
+
- `newDataSet(Map<String, DataType> metaMap, List<Object[]> seqRows)`: 根据类型映射创建。
|
|
61
|
+
- `newDataSet(String[] fields, DataType[] dataTypes, List<Object[]> seqRows)`: 根据字段定义创建。
|
|
62
|
+
- `newDataSet(RowMeta rowMeta, List<Object[]> seqRows)`: 根据 RowMeta 创建。
|
|
63
|
+
- `emptyDataSet(Map<String, DataType> metaMap, int initialSize)`: 生成空行 DataSet。
|
|
64
|
+
- `emptyDataSet(RowMeta rowMeta, int initialSize)`: 根据 RowMeta 生成空行 DataSet。
|
|
65
|
+
- `appendNullRow(DataSet dataSet, int size)`: 为 DataSet 追加空行。
|
|
66
|
+
|
|
67
|
+
### 6. 行元数据操作
|
|
68
|
+
- `rowAddField(Row row, String field, DataType dataType, Object value)`: Row 对象添加新字段并赋值。
|
|
69
|
+
- `rowMetaAddField(RowMeta rowMeta, String field, DataType dataType)`: RowMeta 添加新字段。
|
|
70
|
+
- `dumpRowMeta(RowMeta rowMeta)`: RowMeta 转换为类型映射。
|
|
71
|
+
|
|
72
|
+
### 7. 调试输出
|
|
73
|
+
- `print(DataSet dataSet)`: 等距对齐打印 DataSet。
|
|
74
|
+
- `print(DataSet dataSet, int top)`: 打印前 N 条。
|
|
75
|
+
- `print(DataSet dataSet, int top, boolean withJavaType)`: 带类型打印。
|
|
76
|
+
|
|
77
|
+
## 示例代码
|
|
78
|
+
|
|
79
|
+
### DataSet 组合查询与计算
|
|
80
|
+
```java
|
|
81
|
+
package kd.cd.common.demo;
|
|
82
|
+
|
|
83
|
+
import kd.bos.servicehelper.QueryServiceHelper;
|
|
84
|
+
import kd.cd.common.util.AlgoUtils;
|
|
85
|
+
import kd.bos.algo.DataSet;
|
|
86
|
+
import kd.bos.orm.query.QCP;
|
|
87
|
+
import kd.bos.orm.query.QFilter;
|
|
88
|
+
import java.math.BigDecimal;
|
|
89
|
+
import java.util.List;
|
|
90
|
+
import java.util.Map;
|
|
91
|
+
import java.util.Set;
|
|
92
|
+
|
|
93
|
+
public class QueryDemo {
|
|
94
|
+
public void execute() {
|
|
95
|
+
// 1. 查询已审核单据及其金额
|
|
96
|
+
QFilter filter = new QFilter("status", QCP.equals, "C");
|
|
97
|
+
try (DataSet ds = QueryServiceHelper.queryDataSet("my_bill", "my_bill", "id,totalamount", filter.toArray(), null);
|
|
98
|
+
DataSet dsForSum = ds.copy();
|
|
99
|
+
DataSet filtered = AlgoUtils.filter(ds, row ->
|
|
100
|
+
row.getBigDecimal("totalamount").compareTo(BigDecimal.valueOf(1000)) > 0)) {
|
|
101
|
+
// 2. 计算已查询数据的金额合计
|
|
102
|
+
BigDecimal sum = AlgoUtils.sumOf(dsForSum, "totalamount");
|
|
103
|
+
|
|
104
|
+
// 3. 提取高金额单据ID
|
|
105
|
+
List<Object> ids = AlgoUtils.listOf(filtered, "id");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 快速查询示例
|
|
112
|
+
```java
|
|
113
|
+
public void quickQuery() {
|
|
114
|
+
// 查一条记录
|
|
115
|
+
DynamicObject row = QueryServiceHelper.queryOne("my_bill", "id,name",
|
|
116
|
+
new QFilter[]{new QFilter("number", QCP.equals, "BILL001")});
|
|
117
|
+
|
|
118
|
+
// 判断是否存在
|
|
119
|
+
boolean exists = QueryServiceHelper.exists("my_bill",
|
|
120
|
+
new QFilter[]{new QFilter("number", QCP.equals, "BILL001")});
|
|
121
|
+
QFilter filter = new QFilter("status", QCP.equals, "C");
|
|
122
|
+
|
|
123
|
+
// 查询多条 → DynamicObjectCollection
|
|
124
|
+
DynamicObjectCollection rows = QueryServiceHelper.query("my_bill", "id,name", filter.toArray());
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 原生 SQL 查询
|
|
129
|
+
```java
|
|
130
|
+
public void sqlQuery(DBRoute dbRoute) {
|
|
131
|
+
String sql = "SELECT id, name FROM my_table WHERE status = ?";
|
|
132
|
+
try (DataSet ds = QueryServiceHelper.queryDataSet(dbRoute, sql, new Object[]{"C"})) {
|
|
133
|
+
// 处理结果
|
|
134
|
+
List<Object> ids = AlgoUtils.listOf(ds, "id");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 实践建议
|
|
140
|
+
1. **优先使用 DataSet**: 对于处理多单据关联、分录数据计算等场景,`DataSet` 性能远超 `List<DynamicObject>`。
|
|
141
|
+
2. **延迟加载**: 在 `queryDataSet` 时,仅传入必要的 `selectFields`,严禁使用 `*`。
|
|
142
|
+
3. **QFilter 优化**: 尽量在查询阶段完成数据过滤,减少传输到内存中的数据量。
|
|
143
|
+
4. **流关闭**: 使用 `try-with-resources` 确保 DataSet 被正确关闭。
|
|
144
|
+
|
|
145
|
+
## 常见坑位
|
|
146
|
+
1. **泄露隐患**: `DataSet` 必须在 `finally` 中或使用 `try-with-resources` 调用 `close()`,否则会造成内存溢出。
|
|
147
|
+
2. **空指针问题**: `AlgoUtils` 在执行计算时,如果字段值为空,应先通过 `nullToZero` 转换。
|
|
148
|
+
3. **查询频率**: 严禁在插件的生命周期内高频执行查询,应优先使用已加载到界面模型(Model)中的数据。
|
|
149
|
+
4. **SQL 注入**: 使用原生 SQL 时,务必使用参数化查询而非字符串拼接。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# 请求上下文处理 (RequestContextUtils)
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
- 适用:异步线程、后台任务、集成接口里恢复用户、租户和语言上下文。
|
|
5
|
+
- 先抓:优先 `RequestContextUtils.restore()` 或 `Guard`,不要手写 ThreadLocal 传递。
|
|
6
|
+
- 跳转:同步插件线程通常不需要本页;只看上下文字段可读 `base/sdk/sdk-request-context.md`。
|
|
7
|
+
- 继续读全文:当你要确认自动恢复模式、自定义上下文参数或反射风险时。
|
|
8
|
+
|
|
9
|
+
## 概述
|
|
10
|
+
在苍穹多线程异步开发中,`RequestContext`(包含用户、租户、多语言等)由于依赖 `ThreadLocal` 无法自动传递。`RequestContextUtils` (位于 `kd.cd.common.concurrent`) 提供了上下文的自动恢复功能,确保异步任务能正确继承主线程的身份与权限。本规范适用于后台任务、集成接口与身份模拟场景。
|
|
11
|
+
|
|
12
|
+
> **适用边界**
|
|
13
|
+
> ✅ 适用:异步线程/后台任务/集成接口中需要恢复用户上下文。
|
|
14
|
+
> ❌ 不适用:同步插件事件中上下文自动可用,无需额外处理。
|
|
15
|
+
|
|
16
|
+
## 核心类
|
|
17
|
+
- **`kd.cd.common.concurrent.RequestContextUtils`**: **核心工具类**。
|
|
18
|
+
- **`kd.cd.common.concurrent.RequestContextUtils.Guard`**: 上下文守卫接口,支持 try-with-resources。
|
|
19
|
+
- **`kd.bos.context.RequestContext`**: 苍穹核心请求上下文接口。
|
|
20
|
+
|
|
21
|
+
## 常用 API 方法
|
|
22
|
+
|
|
23
|
+
### 1. 自动恢复模式(推荐)
|
|
24
|
+
- `switchUser(long userId)`: **最常用**。切换到指定用户身份,并在 try-with-resources 结束时自动恢复。
|
|
25
|
+
- `switchContext(Map<String, Object> params)`: 根据参数切换上下文,并在 try-with-resources 结束时自动恢复。
|
|
26
|
+
|
|
27
|
+
### 2. Guard 接口
|
|
28
|
+
`Guard` 是一个函数式接口,实现了 `AutoCloseable`,配合 try-with-resources 使用,确保离开作用域时原始上下文被 100% 恢复。
|
|
29
|
+
|
|
30
|
+
## 示例代码
|
|
31
|
+
|
|
32
|
+
### 自动恢复模式(推荐)
|
|
33
|
+
```java
|
|
34
|
+
package kd.cd.common.demo;
|
|
35
|
+
|
|
36
|
+
import kd.cd.common.concurrent.RequestContextUtils;
|
|
37
|
+
import kd.bos.context.RequestContext;
|
|
38
|
+
|
|
39
|
+
public class AsyncDemo {
|
|
40
|
+
public void executeWithUser(long targetUserId) {
|
|
41
|
+
// 使用 try-with-resources 自动恢复
|
|
42
|
+
try (RequestContextUtils.Guard ignored = RequestContextUtils.switchUser(targetUserId)) {
|
|
43
|
+
// 此作用域内以 targetUser 身份执行
|
|
44
|
+
// ...执行业务逻辑...
|
|
45
|
+
}
|
|
46
|
+
// 离开作用域后自动恢复原始上下文,确保线程安全
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 自定义上下文参数
|
|
52
|
+
```java
|
|
53
|
+
public void executeWithCustomContext() {
|
|
54
|
+
Map<String, Object> params = new HashMap<>();
|
|
55
|
+
params.put("userId", "12345");
|
|
56
|
+
params.put("userName", "test");
|
|
57
|
+
|
|
58
|
+
try (RequestContextUtils.Guard ignored = RequestContextUtils.switchContext(params)) {
|
|
59
|
+
// 以切换后的上下文执行业务逻辑
|
|
60
|
+
}
|
|
61
|
+
// 自动恢复原始上下文
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 实践建议
|
|
66
|
+
1. **强制使用 Guard 模式**: 使用 `switchUser`/`switchContext` 配合 try-with-resources,杜绝忘记恢复导致的"身份污染"。
|
|
67
|
+
2. **多租户一致性**: 在多租户环境下,身份切换后所有的 `QFilter` 会自动遵循该租户的隔离逻辑。
|
|
68
|
+
3. **配合线程池**: 在高并发环境下,推荐使用此模式自动处理上下文传递。
|
|
69
|
+
|
|
70
|
+
## 重要说明
|
|
71
|
+
|
|
72
|
+
### 反射机制风险
|
|
73
|
+
该类通过反射机制直接操作 `RequestContext` 的私有字段,存在以下风险:
|
|
74
|
+
- **脆性风险**: 深度依赖金蝶 BOS 内部实现,若 BOS 版本升级修改了字段定义(一般不会发生此种情况),此类将失效。
|
|
75
|
+
|
|
76
|
+
### 支持的上下文属性
|
|
77
|
+
通过 `switchContext` 可覆盖的常用属性:
|
|
78
|
+
- `userId` - 用户 ID
|
|
79
|
+
- `userName` - 用户名
|
|
80
|
+
- `userOpenId` - 用户 OpenID
|
|
81
|
+
- `tenantId` - 租户 ID
|
|
82
|
+
- `locale` - 语言环境
|
|
83
|
+
|
|
84
|
+
## 常见坑位
|
|
85
|
+
1. **忘记恢复**: 强烈推荐使用 Guard 模式。
|
|
86
|
+
2. **空上下文报错**: 如果在静态初始化块中调用切换方法,由于主线程尚无上下文,可能会报错。
|
|
87
|
+
3. **事务关联**: 异步线程默认不继承主线程的数据库事务,如果异步操作涉及写库,需开启独立事务。
|
|
88
|
+
4. **Session 失效**: 备份中不包含 Web Session,仅包含后端业务执行所需的元数据标识。
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# 页面打开与视图管理 (ViewHandler & AutoCloseViewHandler)
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
- 适用:后台/操作插件里打开表单或列表、新页签跳转以及带参数打开界面。
|
|
5
|
+
- 先抓:默认优先 `AutoCloseViewHandler`,链式设置打开模式、组织和数据初始化。
|
|
6
|
+
- 跳转:表单插件内的简单弹窗优先直接 `getView().showForm()` 或回看 `form-utils.md`。
|
|
7
|
+
- 继续读全文:当你要确认组织参数、打开动作差异或后台视图示例时。
|
|
8
|
+
|
|
9
|
+
## 概述
|
|
10
|
+
在单据交互逻辑中,频繁涉及"点击 A 单据打开 B 单据界面"的需求。`ViewHandler` (位于 `kd.cd.common.form.handler`) 采用了链式 API 封装了复杂的 `FormShowParameter` 逻辑,支持一键实现新增、修改、查看、列表界面的弹出或新页签跳转。特别适用于后台任务中需要打开视图进行数据初始化或验证的场景。
|
|
11
|
+
|
|
12
|
+
> **适用边界**
|
|
13
|
+
> ✅ 适用:后台/操作插件中打开表单/列表界面、新页签跳转。
|
|
14
|
+
> ❌ 不适用:表单插件中的简单弹窗优先用 `getView().showForm()`,参见 `form-utils.md`。
|
|
15
|
+
|
|
16
|
+
## 核心类
|
|
17
|
+
- **`kd.cd.common.form.handler.ViewHandler`**: 视图操作核心工具接口。
|
|
18
|
+
- **`kd.cd.common.form.handler.AutoCloseViewHandler`**: **推荐使用**。自动关闭的视图处理器,实现了 `AutoCloseable`。
|
|
19
|
+
- **`kd.bos.form.FormShowParameter`**: 原生表单显示参数。
|
|
20
|
+
- **`kd.bos.bill.OperationStatus`**: 页面操作状态枚举。
|
|
21
|
+
|
|
22
|
+
## 常用 API 方法
|
|
23
|
+
|
|
24
|
+
### 1. 工厂方法
|
|
25
|
+
- `ViewHandler.of(String formId)`: 指定目标单据标识。
|
|
26
|
+
- `ViewHandler.of(String formId, Object initOrgId)`: 指定单据及初始化组织ID。
|
|
27
|
+
- `AutoCloseViewHandler.of(String formId)`: **推荐**。创建自动关闭的视图处理器。
|
|
28
|
+
- `AutoCloseViewHandler.of(String formId, Object initOrgId)`: 创建带组织的自动关闭视图处理器。
|
|
29
|
+
|
|
30
|
+
### 2. 参数设置
|
|
31
|
+
- `addCustomParam(String name, Object value)`: 向目标页面传递自定义业务参数。
|
|
32
|
+
- `setOpenOnDesignerPage()`: 设置忽略许可校验。
|
|
33
|
+
- `beforeOpen(Consumer<FormShowParameter> c)`: 注入原生参数调整代码。
|
|
34
|
+
|
|
35
|
+
### 3. 界面动作执行
|
|
36
|
+
- `openAddNewView()`: 以新增状态打开。
|
|
37
|
+
- `openAddNewViewAndInit(DynamicObject dataEntity)`: 以新增状态打开并初始化数据。
|
|
38
|
+
- `openModifyView(Object pkValue)`: 以修改状态打开指定单据。
|
|
39
|
+
- `openPeekView(Object pkValue)`: 以只读查看状态打开。
|
|
40
|
+
- `openListView()`: 打开目标单据的列表页。
|
|
41
|
+
- `openView(Object pkValue, OperationStatus operationStatus)`: 指定状态打开。
|
|
42
|
+
- `openViewByShowParameter(FormShowParameter sp)`: 自定义参数打开。
|
|
43
|
+
- `closeView()`: 关闭当前视图。
|
|
44
|
+
|
|
45
|
+
### 4. 调试方法
|
|
46
|
+
- `peek()`: 提取界面所有数据快照(调试用)。
|
|
47
|
+
- `peekUIMsg()`: 预览 UI 消息队列(调试用)。
|
|
48
|
+
- `peekUIMsgFlat()`: 获取平面化的消息列表(调试用)。
|
|
49
|
+
- `flatList(String field)`: 扁平列出字段值(调试用)。
|
|
50
|
+
|
|
51
|
+
## 示例代码
|
|
52
|
+
|
|
53
|
+
### AutoCloseViewHandler 模板(推荐)
|
|
54
|
+
```java
|
|
55
|
+
package kd.cd.common.demo;
|
|
56
|
+
|
|
57
|
+
import kd.cd.common.form.handler.AutoCloseViewHandler;
|
|
58
|
+
import kd.bos.form.IFormView;
|
|
59
|
+
|
|
60
|
+
public class ViewHandlerDemo {
|
|
61
|
+
public void backendOperation() {
|
|
62
|
+
// 使用 try-with-resources 自动关闭视图
|
|
63
|
+
try (AutoCloseViewHandler vh = AutoCloseViewHandler.of("kdcd_test")) {
|
|
64
|
+
vh.beforeOpen(sp -> sp.setAppId("fi"));
|
|
65
|
+
|
|
66
|
+
// 打开修改视图
|
|
67
|
+
IFormView view = vh.openModifyView(1462749241941L);
|
|
68
|
+
|
|
69
|
+
// 在后台视图中进行数据操作
|
|
70
|
+
// ...do something here...
|
|
71
|
+
} // 自动调用 close(),无需手动关闭
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 带组织参数的新增视图
|
|
77
|
+
```java
|
|
78
|
+
public void openWithOrg(Long orgId) {
|
|
79
|
+
try (AutoCloseViewHandler vh = AutoCloseViewHandler.of("my_bill", orgId)) {
|
|
80
|
+
vh.beforeOpen(sp -> sp.setAppId("fi"));
|
|
81
|
+
IFormView view = vh.openAddNewView();
|
|
82
|
+
|
|
83
|
+
// 操作视图数据...
|
|
84
|
+
} // 自动关闭
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 带数据初始化的新增视图
|
|
89
|
+
```java
|
|
90
|
+
public void openWithInit(DynamicObject initData) {
|
|
91
|
+
try (AutoCloseViewHandler vh = AutoCloseViewHandler.of("my_bill")) {
|
|
92
|
+
// 打开新增视图并初始化数据
|
|
93
|
+
IFormView view = vh.openAddNewViewAndInit(initData);
|
|
94
|
+
|
|
95
|
+
// 继续操作...
|
|
96
|
+
} // 自动关闭
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 批量新增数据包(推荐)
|
|
101
|
+
在后台场景下批量造单时,通过 `openAddNewView()` 触发完整的页面初始化生命周期(字段默认值、自动填充规则、插件 `afterCreateNewData` 等),提取数据包后统一批量保存,避免循环内逐条保存。
|
|
102
|
+
|
|
103
|
+
> **性能说明**:循环中多次调用 `open` 方法时,`AutoCloseViewHandler` 会复用同一个 view 实例,仅重载数据包,不会反复创建/销毁视图,因此批量场景下性能开销可控。
|
|
104
|
+
> ❗ **禁止在循环内创建 `AutoCloseViewHandler`**,否则每次迭代都会实例化新的 view 对象,丧失复用优势。正确做法是在循环外创建一次,循环内只调用 `open` 方法。
|
|
105
|
+
```java
|
|
106
|
+
public void batchCreateBills(int count) {
|
|
107
|
+
List<DynamicObject> list = new ArrayList<>(count);
|
|
108
|
+
|
|
109
|
+
try (AutoCloseViewHandler vh = AutoCloseViewHandler.of("kdcd_test")) {
|
|
110
|
+
for (int i = 0; i < count; i++) {
|
|
111
|
+
// 打开新增视图,触发完整初始化(默认值、自动填充、插件事件等)
|
|
112
|
+
IFormView view = vh.openAddNewView();
|
|
113
|
+
view.getModel().setValue("billno", i);
|
|
114
|
+
// 提取经过完整初始化的数据包
|
|
115
|
+
DynamicObject dataEntity = view.getModel().getDataEntity(true);
|
|
116
|
+
list.add(dataEntity);
|
|
117
|
+
}
|
|
118
|
+
// 统一批量保存,避免循环内逐条保存
|
|
119
|
+
OpUtils.executeOperateOrThrow("save", "kdcd_test", list.toArray(new DynamicObject[0]));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
> 对比 `DynamicObjectUtils.newDynamicObject(formId)` 构建裸数据包,此方式的优势是触发完整的页面初始化生命周期,无需手动设置默认值。详见 [DynamicObjectCrudSample.java](../../assets/snippets/data/DynamicObjectCrudSample.java)。
|
|
125
|
+
|
|
126
|
+
## ViewHandler vs AutoCloseViewHandler
|
|
127
|
+
|
|
128
|
+
| 场景 | 推荐使用 | 说明 |
|
|
129
|
+
|------|---------|------|
|
|
130
|
+
| 后台任务打开视图 | `AutoCloseViewHandler` | 配合 try-with-resources 自动关闭 |
|
|
131
|
+
| 前台界面跳转 | `ViewHandler` | 由用户手动关闭或系统管理 |
|
|
132
|
+
| 异步线程中操作 | `AutoCloseViewHandler` | 确保资源释放 |
|
|
133
|
+
|
|
134
|
+
## 重要说明
|
|
135
|
+
|
|
136
|
+
### 组织参数处理
|
|
137
|
+
- 传入的 `initOrgId` 对于单据会传入初始化组织参数。
|
|
138
|
+
- 对于基础资料会传入使用组织初始参数(仅当使用组织字段无字段名时)。
|
|
139
|
+
- 在打开新增视图并且主业务组织字段为空时,还会尝试为主业务组织字段赋值。
|
|
140
|
+
|
|
141
|
+
### 后台视图特点
|
|
142
|
+
- `openPeekView` 相关方法后台默认以查看的方式打开视图,不触发编辑操作的网络互斥。
|
|
143
|
+
- 打开的页面默认拥有权限。
|
|
144
|
+
- **必须关闭视图**:后台打开的视图必须调用 `closeView()` 或使用 `AutoCloseViewHandler`。
|
|
145
|
+
|
|
146
|
+
## 实践建议
|
|
147
|
+
1. **优先使用 AutoCloseViewHandler**: 后台场景下使用 `AutoCloseViewHandler` 配合 try-with-resources,避免忘记关闭视图导致资源泄露。
|
|
148
|
+
2. **链式调用**: 链式调用极大增强了代码可读性,相比原生 `new FormShowParameter` 可减少 50% 以上的代码量。
|
|
149
|
+
3. **参数解耦原则**: 传递大型数据对象时,建议先存储在 `PageCache` 中,仅通过 `addCustomParam` 传递其 CacheKey。
|
|
150
|
+
4. **状态回调**: 弹出界面返回后,建议在 `closedCallBack` 处理业务逻辑。
|
|
151
|
+
|
|
152
|
+
## 常见坑位
|
|
153
|
+
1. **主键类型错误**: `openModifyView` 传入的 PK 类型(Long/String)必须与物理存储一致,否则页面会报错。
|
|
154
|
+
2. **PageId 冲突**: 如果自定义 PageId,确保在并发环境下具有唯一性。
|
|
155
|
+
3. **权限校验**: 界面触发的跳转仍会受系统权限体系约束,如果当前用户无权查看目标单据,页面将弹出报错。
|
|
156
|
+
4. **忘记关闭视图**: 使用 `ViewHandler` 时忘记调用 `closeView()` 会导致内存泄露和会话资源占用,**推荐使用 `AutoCloseViewHandler`**。
|
|
157
|
+
5. **循环内创建 `AutoCloseViewHandler`**: 禁止在循环内每次迭代都 `AutoCloseViewHandler.of(...)`,否则每轮都会实例化新的 view 对象,丧失视图复用优势。正确做法是在循环外创建一次,循环内只调用 `open` 方法。
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# 单据界面插件
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
- 适用:单据界面插件的原生兜底,封装层没覆盖到的单据事件时再读本页。
|
|
5
|
+
- 先抓:`AbstractBillPlugIn`、额外监听器和单据特有事件时机。
|
|
6
|
+
- 跳转:若 `AbstractBillPlugInExt` 足够,优先回到 `adv/plugin-base.md`。
|
|
7
|
+
- 继续读全文:当你要确认工具栏、F7、操作后回调或单据关闭等具体事件时。
|
|
8
|
+
|
|
9
|
+
## 概述
|
|
10
|
+
单据界面插件继承动态表单插件能力,并增加单据特有事件,适合处理加载后初始化与单据交互控制。
|
|
11
|
+
|
|
12
|
+
> **适用边界**
|
|
13
|
+
> ✅ 本文档是原生兜底:当 `plugin-base.md`(封装层) 未覆盖你需要的单据事件时使用。
|
|
14
|
+
> ❌ 如果封装层 `AbstractBillPlugInExt` 已满足需求,优先读 `references/adv/plugin-base.md`。
|
|
15
|
+
|
|
16
|
+
- 适用场景:单据加载初始化、字段联动、操作前后 UI 协同
|
|
17
|
+
|
|
18
|
+
术语说明:文档中的 `F7` 指基础资料、引用数据等选择控件弹窗,不是键盘按键事件。
|
|
19
|
+
|
|
20
|
+
## 核心基类
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
- 基类:`kd.bos.bill.AbstractBillPlugIn`
|
|
24
|
+
- 继承关系:`AbstractBillPlugIn extends AbstractFormPlugin implements IBillPlugin`
|
|
25
|
+
|
|
26
|
+
## 额外监听器
|
|
27
|
+
|
|
28
|
+
- `BeforeF7SelectListener`:F7(基础资料/引用数据选择控件)选择前拦截
|
|
29
|
+
- `ItemClickListener`:菜单/按钮点击监听
|
|
30
|
+
- `ClickListener`:控件通用点击监听
|
|
31
|
+
- `TreeNodeClickListener`:树节点点击监听
|
|
32
|
+
|
|
33
|
+
## 核心事件
|
|
34
|
+
|
|
35
|
+
- `afterLoadData(EventObject e)`:// 单据数据加载完成后触发,适合做加载后初始化
|
|
36
|
+
- `beforeDoOperation(EventObject e)`:// 操作执行前触发,适合做前置校验/参数整理
|
|
37
|
+
- `afterDoOperation(EventObject e)`:// 操作执行后触发,适合做结果提示/刷新协同
|
|
38
|
+
- `propertyChanged(EventObject e)`:// 字段值变更后触发,适合做联动赋值
|
|
39
|
+
|
|
40
|
+
说明:单据插件同时支持动态表单全套事件(生命周期与交互事件与 `plugin-form.md` 一致)。
|
|
41
|
+
|
|
42
|
+
## 插件内上下文方法
|
|
43
|
+
|
|
44
|
+
```java
|
|
45
|
+
// 视图与模型
|
|
46
|
+
IFormView view = this.getView();
|
|
47
|
+
IDataModel model = this.getModel();
|
|
48
|
+
|
|
49
|
+
// 读取单据常用字段
|
|
50
|
+
String billNo = (String) model.getValue("billno");
|
|
51
|
+
String billStatus = (String) model.getValue("billstatus");
|
|
52
|
+
|
|
53
|
+
// 控件级操作
|
|
54
|
+
Control control = view.getControl("fieldkey");
|
|
55
|
+
BasedataEdit basedataEdit = view.getControl("basedatafield");
|
|
56
|
+
view.setEnable(false, "fieldkey");
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
说明:`view.getControl("fieldkey")` 的返回类型是 `<T extends kd.bos.form.control.Control>`,所有控件都继承自 `kd.bos.form.control.Control`,实际拿到的是具体控件对象,例如 `BasedataEdit`、`EntryGrid`、`ProgressBar` 等。
|
|
60
|
+
|
|
61
|
+
## 示例代码
|
|
62
|
+
|
|
63
|
+
示例代码统一维护在模板文件中,直接参考:
|
|
64
|
+
|
|
65
|
+
- [BillPlugInTemplate.java](../../../assets/BillPlugInTemplate.java)
|
|
66
|
+
|
|
67
|
+
## 实践建议
|
|
68
|
+
|
|
69
|
+
1. 加载后初始化优先放 `afterLoadData`。
|
|
70
|
+
2. 事务级校验放操作插件,UI 插件只做交互提示与轻校验。
|
|
71
|
+
3. 字段联动优先在 `propertyChanged`,避免分散在多个事件。
|
|
72
|
+
|
|
73
|
+
## 常见坑位
|
|
74
|
+
|
|
75
|
+
- 新增单据不触发 `afterLoadData`,初始化逻辑需兼顾 `afterCreateNewData`。
|
|
76
|
+
- 在 UI 插件中直接改状态字段替代操作流,容易与业务状态机冲突。
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# 单据转换插件
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
- 适用:BOTP 转换插件本体,处理源单取数、目标单建单、字段映射和分单合单。
|
|
5
|
+
- 先抓:`AbstractConvertPlugIn` 和转换事件顺序,先区分“业务调用”还是“转换规则扩展”。
|
|
6
|
+
- 跳转:如果只是执行下推/追踪来源,优先读 `adv/botp-convert.md` 的 `BotpUtils`。
|
|
7
|
+
- 继续读全文:当你要改转换规则、选单逻辑或目标单数据填充时。
|
|
8
|
+
|
|
9
|
+
## 概述
|
|
10
|
+
单据转换插件用于在业务流转换(下推、选单)过程中介入源单取数、目标单创建、字段映射与关联关系生成。
|
|
11
|
+
|
|
12
|
+
> **适用边界**
|
|
13
|
+
> ✅ 本文档是原生兜底:BOTP 转换/反写没有 Ext 封装,直接读本文档。
|
|
14
|
+
> ❌ 下推/选单的业务调用优先用 `BotpUtils`,参见 `references/adv/botp-convert.md`。
|
|
15
|
+
|
|
16
|
+
- 适用场景:下推规则扩展、选单逻辑增强、字段映射补充、分单合单策略调整
|
|
17
|
+
|
|
18
|
+
## 核心基类
|
|
19
|
+
- 基类:`kd.bos.entity.botp.plugin.AbstractConvertPlugIn`
|
|
20
|
+
- 继承关系:`AbstractConvertPlugIn implements IConvertPlugIn`
|
|
21
|
+
|
|
22
|
+
## 核心事件
|
|
23
|
+
|
|
24
|
+
- `initVariable`:// 初始化上下文变量(源单主实体、目标单主实体、转换规则、转换方式)
|
|
25
|
+
- `afterBuildQueryParemeter`:// 构建取数参数后,可追加字段与过滤条件
|
|
26
|
+
- `beforeBuildRowCondition`:// 编译行过滤条件前,可替换/追加规则条件
|
|
27
|
+
- `afterBuildRowCondition`:// 编译行过滤条件后,可补充诊断信息或微调最终条件
|
|
28
|
+
- `beforeGetSourceData`:// 取源单数据前,可调整语句与条件
|
|
29
|
+
- `afterGetSourceData`:// 取源单数据后,可补充第三方数据或替换源数据
|
|
30
|
+
- `beforeBuildGroupMode`:// 分单/合并策略构建前,可调整分单合并依赖字段
|
|
31
|
+
- `beforeCreateTarget`:// 创建目标单前(官方说明仅选单场景触发)
|
|
32
|
+
- `afterCreateTarget`:// 创建目标单后(官方说明主要下推场景触发)
|
|
33
|
+
- `afterFieldMapping`:// 字段映射完成后,补充目标字段赋值
|
|
34
|
+
- `afterBizRule`:// 业务规则执行后,做最终字段修正
|
|
35
|
+
- `beforeCreateLink`:// 生成关联关系前,可取消/调整关联关系
|
|
36
|
+
- `afterCreateLink`:// 生成关联关系后,补充关联携带数据
|
|
37
|
+
- `afterBuildDrawFilter`:// 选单条件生成后,追加插件过滤条件
|
|
38
|
+
- `afterConvert`:// 转换流程最后事件,做最终修正
|
|
39
|
+
|
|
40
|
+
## 插件内上下文方法
|
|
41
|
+
|
|
42
|
+
```java
|
|
43
|
+
// 上下文获取
|
|
44
|
+
BillEntityType srcMainType = this.getSrcMainType();
|
|
45
|
+
BillEntityType tgtMainType = this.getTgtMainType();
|
|
46
|
+
ConvertRuleElement rule = this.getRule();
|
|
47
|
+
ConvertOpType opType = this.getOpType(); // 下推/选单
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 示例代码
|
|
51
|
+
|
|
52
|
+
示例代码统一维护在模板文件中,直接参考:
|
|
53
|
+
|
|
54
|
+
- [ConvertPlugInTemplate.java](../../../assets/ConvertPlugInTemplate.java)
|
|
55
|
+
|
|
56
|
+
## 实践建议
|
|
57
|
+
|
|
58
|
+
1. 先在 `initVariable` 明确当前上下文(下推/选单)再分支处理。
|
|
59
|
+
2. 源单过滤尽量放 `beforeBuildRowCondition` 与 `beforeGetSourceData`,避免后置大规模删数据。
|
|
60
|
+
3. 字段补齐优先放 `afterFieldMapping`,规则执行后的兜底修正再放 `afterBizRule`。
|
|
61
|
+
4. 选单场景的额外过滤优先放 `afterBuildDrawFilter`,不要把选单过滤和普通取数过滤混写。
|
|
62
|
+
5. 关联追溯场景谨慎处理 `beforeCreateLink`,取消后会影响上下游可追踪性。
|
|
63
|
+
|
|
64
|
+
## 常见坑位
|
|
65
|
+
|
|
66
|
+
- 误把 `beforeCreateTarget` 当所有场景必触发,导致逻辑漏执行。
|
|
67
|
+
- 在 `afterConvert` 做大量数据库操作,影响转换时长。
|
|
68
|
+
- 漏掉源单关键字段准备,后续事件中字段取值为 null。
|
|
69
|
+
- 选单场景忘记区分 `afterBuildDrawFilter` 与普通取数过滤,导致过滤位置不稳定。
|
|
70
|
+
- 关联关系被取消后,后续反写/追踪功能异常。
|