lan-low-code-cli 2.5.0 → 2.7.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 CHANGED
@@ -6,6 +6,7 @@
6
6
  - **创建表单**:覆盖 6 种表单类型(普通 / 审批意见 / 全局配置项 / 弹窗 / 通用 / 引用者)
7
7
  - **自动获取可用字段**:表单数据模型字段、外部映射表字段、字段库
8
8
  - **自动完善表单字段**:依据数据模型自动生成完整表单配置(`fdConfig`:字段控件 + 场景 viewModel + 权限 + 多语言 + 全局规则)并保存
9
+ - **动作流建模**:用声明式 Flow Spec 从零编译出 `fdDesign`(含符合平台编排习惯的节点布局),支持草稿/发布/启停/删除、Schema 上下文注入、golden 模板抽取与按钮脚本生成
9
10
 
10
11
  ## 一、安装与构建
11
12
 
@@ -77,6 +78,70 @@ llc form create --name <名称> [选项]
77
78
  | `--fd-run-entity-name <name>` | 表单运行时实体名称 |
78
79
  | `--table-name <name>` | 主表名(不传则调用对应接口自动生成) |
79
80
 
81
+ **表单类型**(`--type`):
82
+
83
+ | 类型 | 说明 | 表结构 |
84
+ |---|---|---|
85
+ | 缺省 / `common` | 普通表单(应用下默认走 `modeling` 族) | 主表 |
86
+ | `category` | 分类表单:分类树 + 多个模板 | 分类表 + 模板表 + 主表 |
87
+ | `simpleCategory` | 简单分类表单:分类与模板合一,强制多层级 | 聚合表 + 主表 |
88
+
89
+ ```bash
90
+ # 分类表单:自动生成三张表名,创建后立即发布
91
+ llc form create --name "采购分类表单" --app-id <appId> --type category --publish
92
+
93
+ # 简单分类表单
94
+ llc form create --name "简版分类表单" --app-id <appId> --type simpleCategory --publish
95
+
96
+ # 共享已有分类表单的分类(沿用对方的分类表与层级设置)
97
+ llc form create --name "共享分类表单" --app-id <appId> --type category --share-category purchaseCategory
98
+ ```
99
+
100
+ - 分类表单走 `categoryModel/init → add →(--publish 时 save → publish)`,与普通表单接口完全不同;
101
+ - 表名可用 `--table-name`(主表)、`--category-table-name`、`--template-table-name`(分类)、
102
+ `--polymers-table-name`(简单分类聚合表)显式指定,缺省逐个调用 `generateTableName`;
103
+ - 分类表单本身**不含业务字段**,`--add-field` / `--fields` / `--from-model` 会被拒绝——字段属于「模板」;
104
+ - 默认多层级分类,`--no-support-hierarchy` 改单层级;简单分类强制多层级、不支持共享分类;
105
+ - 模板(模板表单)用下面的 `llc template create` 创建;
106
+ - 分类表单的删除只能在平台操作(后端 `categoryModel/delete` 禁止前端直接调用),
107
+ `form get --id` 已能识别分类表单并展示 `fdType` / 三张表名。
108
+
109
+ **分类表单模板**(`llc template`):
110
+
111
+ ```bash
112
+ # 列出分类表单下的模板(运行时分类树)
113
+ llc template list --category-code <categoryCode>
114
+
115
+ # 创建模板,并把既有表单的字段 / 视图 / 权限移植进来,然后发布
116
+ llc template create --category-code <categoryCode> --name "合作模板" \
117
+ --from-form <来源表单 fdId> --publish
118
+
119
+ # 给已有模板追加字段(默认重建栅格布局让新字段可见;--keep-layout 保留原布局)
120
+ llc template add-fields --template-id <templateId> --category-code <categoryCode> \
121
+ --add-field "fd_budget:合作预算:moneytext" \
122
+ --add-field "fd_contact:对接人:address" --publish
123
+
124
+ # 删除模板(--all 清空该分类表单下的模板,需 --yes)
125
+ llc template delete --category-code <categoryCode> --all --yes
126
+ llc template delete --category-code <categoryCode> --template-id <templateId> --yes
127
+ ```
128
+
129
+ - 分类表单 `fdType=1` 走 `categoryTemplate/add`,简单分类 `fdType=2` 走 `virtualPolymers/add`;
130
+ - **跳过官方 `init`**:模板表元数据未就绪时 `init` 会空指针,改为 `add` + `mechanisms['sys-xform'].fdBuildNew=true`
131
+ 由后端建表并注册元数据,再 `sys-xform/sysXFormDesign/save` 写入设计;
132
+ - `--from-form` 会克隆来源表单的主表业务字段、视图布局(页签/栅格)与字段权限,表名替换为模板表;
133
+ **明细表节点会被剔除**(模板表结构不支持直接挂明细),可用 `--fields` 只取部分字段;
134
+ - 分类表单的模板必须挂在分类节点下:不传 `--category-node` 时自动建一个分类节点(名称默认取模板名,可用
135
+ `--category-name` 指定);
136
+ - 创建后 `template list` 能看到,平台发起页即可选择该模板填写。
137
+ - 注意区分两份设计:`template add-fields` 改的是**模板实体**的表单设计(落模板表/聚合表);
138
+ 而简单分类表单「自身的模板表单」(前台新建模板时默认使用的那份)用
139
+ `llc form autofill --id <分类表单 fdId> --add-field ... --apply --publish` 维护,两者互不影响。
140
+ - 模板编辑器打开时会拿分类表单的**发布配置**(`categoryModel/getReleaseConfig`)做字段合并,
141
+ 该配置缺 `sign` 时会报 `Cannot read properties of undefined (reading 'formula')`;
142
+ `template create` 会自动检查并用分类表单自身设计重新发布补齐
143
+ (等价于对分类表单执行 `form autofill --id <分类表单 fdId> --apply --publish`)。
144
+
80
145
  其余选项:
81
146
 
82
147
  | 选项 | 说明 |
@@ -196,6 +261,114 @@ llc field library [--keyword <kw>] # 字段库
196
261
  llc field gen-key --name <名称> # 生成字段编码
197
262
  ```
198
263
 
264
+ ### 表单业务操作
265
+
266
+ 在表单的列表页/查看页上增加按钮(对应平台「表单 → 业务操作」Tab)。
267
+
268
+ ```bash
269
+ llc operation list --form-id <fdId>
270
+ llc operation create --form-id <fdId> --name 打开帮助 --code openHelp \
271
+ --type link --position view --url https://example.com
272
+ llc operation create --form-id <fdId> --name 批量归档 --code archive \
273
+ --type script --script @archive.js
274
+ llc operation create --form-id <fdId> --name 转办 --code transfer \
275
+ --type dialog --dialog-id <对话框id>
276
+ llc operation get --id <operationId>
277
+ llc operation update --id <operationId> --type script \
278
+ --script @examples/operation-script-modal-table.js # 把已有按钮改成脚本模式
279
+ llc operation attach --form-id <fdId> --operation-id <operationId> # 挂到列表视图(desktop/top)
280
+ llc operation attach --form-id <fdId> --operation-id <operationId> --target view --position rightHand
281
+ llc operation detach --form-id <fdId> --operation-id <operationId> # 从视图移除
282
+ llc operation delete --id <operationId> --yes # 被页面引用时拒绝
283
+ ```
284
+
285
+ - `--type`:`link`(fdType=2 / fdViewType=4,需 `--url`)、`script`(3 / 5,需 `--script`,支持 `@文件`)、
286
+ `dialog`(3 / 1,需 `--dialog-id`)
287
+ - `--position`:`list`(默认,列表视图)/ `view`(查看视图)
288
+ - 默认不要求勾选数据;需要“先勾选数据再执行”时加 `--need-select`(链接会按接口调用,`fdUrlType=2`)
289
+ - `--dry-run` 只打印请求体;新建操作默认仅管理员可用
290
+ - `update` 基于现有操作合并:显式 `--type` 才切换类型(会重建类型相关配置,保留权限/默认值配置),
291
+ 省略时保持原类型;`--script` 支持 `@文件`,配套示例见
292
+ `examples/operation-script-modal-table.js`(弹窗 + 表格)
293
+ - `attach` / `detach` 修改视图的 `operationList`:列表视图写 `fdExtendConfig`,查看视图写 `fdConfig`;
294
+ `--view-id` 省略时自动定位该表单唯一的视图,重复挂载幂等
295
+
296
+ 脚本模式(fdType=3 / fdViewType=5)的脚本在页面中这样执行:
297
+
298
+ ```js
299
+ new Function('context', fdJavaScript)({
300
+ ...context,
301
+ fdOprId, fdIds, fdBtnCfg, destroyLoading,
302
+ })
303
+ ```
304
+
305
+ - `context.fdIds` 仅在行内按钮/标准行操作时有值(当前行 id);工具栏按钮的勾选在 `context.selectedId`(数组),
306
+ 当前行 id 另有 `context.docId`
307
+ - 弹窗能力来自宿主页面的 `window.MKXFORM`(`tableModal` / `modal` / `HTMLModal`)
308
+ - 脚本内调用 `context.destroyLoading()` 可主动关闭「执行中...」提示
309
+ - 完整上下文清单(选中数据、刷新列表、查询、跳转、事件总线、移动端差异)见
310
+ [skills/lan-low-code-cli/references/operation-script-context.md](skills/lan-low-code-cli/references/operation-script-context.md)
311
+
312
+
313
+ ### 动作流(`llc flow`)
314
+
315
+ 动作流是**应用级**对象(`--app-code` 即 `fdAppCode`),不是表单级。用声明式 JSON(Flow Spec)描述节点与连线,
316
+ CLI 负责补齐开始/结束节点、生成符合 IDE 编排习惯的坐标、按节点类型白名单裁剪字段,最后编译成
317
+ `fdDesign`(JSON 字符串)与平台 `addPublish` / `addDraft` 所需的扁平 VO。
318
+
319
+ ```bash
320
+ # 1. 纯离线:生成模板 → 校验 → 编译(不联网)
321
+ llc flow spec --app-code cli-test --name 示例流程 --code flow_demo --out flow.json
322
+ llc flow validate --spec @flow.json --json
323
+ llc flow compile --spec @flow.json --json
324
+
325
+ # 2. 只读查询
326
+ llc flow list --app-code cli-test --json
327
+ llc flow get --id <flowId> --with-design
328
+ llc flow templates --from @compile-result.json --out templates.json # 抽取 golden 骨架(剥离坐标)
329
+ llc flow schema --kind jsonSchema --entity-id <fdId>
330
+
331
+ # 3. 写入(默认预览;必须 --yes + 显式 --app-code)
332
+ llc flow apply --spec @flow.json --app-code cli-test --resolve-schema # 预览 payload
333
+ llc flow apply --spec @flow.json --app-code cli-test --resolve-schema --yes --enable --json
334
+ llc flow diff --id <flowId> --spec @flow.json --resolve-schema # 回读比对(默认忽略坐标)
335
+ llc flow script --id <flowId> --out call-flow.js # 生成 MKXFORM.flow_<code> 脚本
336
+ llc flow disable --id <flowId> --yes
337
+ llc flow delete --id <flowId> --yes
338
+ ```
339
+
340
+ **Flow Spec 关键字段**:`appCode` / `name` / `code`(`^[a-zA-Z0-9_]{1,30}$`)/ `startWay` /
341
+ `trigger`(`fdRunType`、`inParam`…)/ `nodes`(`id`、`type`、`config`、`context`、`subProcess`)/ `edges`
342
+ (`from`、`to`、`name`、`default`、`formula`)。节点 `id` 需匹配 `^[0-9a-zA-Z_]{2,32}$`。
343
+
344
+ **布局**由编译器生成,不要手写 `drawAttr.bounds`:
345
+
346
+ - `--layout ide`(默认):主链以 `--center-x`(默认 679)居中;`BranchNode` 为 56×56,其余节点 180×38;
347
+ 分支后继与分支节点同层、泳道 ±1 左右对称;汇聚下移一层;层距 = 该层最高节点 + 52。
348
+ 这与平台 mxGraph 编辑器「向下插入 / 左右插入」累积出的编排一致。
349
+ - `--layout layered`:分支后继放到下一层,可读性更强但与平台手工习惯略有差异。
350
+ - `--layout passthrough`:沿用 spec 里的 `bounds`(用于回写平台导出的流程)。
351
+ - `passthrough` 之外的模式下,`relative:false`、节点尺寸、连线 `sourceRef/targetRef` 与
352
+ `formulaConfig.branchFormulas`(引用真实连线 ID)、分支线 `exitX=0/1` 锚点均自动生成。
353
+
354
+ **Schema 注入**:`--resolve-schema` 会为引用数据模型的节点调 `getSourceJsonSchema` /
355
+ `getProcessDataOutJsonSchema` 补齐 `extraAttr.context_outputParam` / `context_bindFormId`。
356
+ 这两个端点要求 `entityId` 带 `sys-modeling#` 前缀(CLI 自动补),裸 id 会返回 500。
357
+ 失败默认只告警,`--strict-schema` 升级为错误。
358
+
359
+ **边界与已知限制**:
360
+
361
+ - `AddDataNode` / `AddOrUpdateNode` 的 `fields` 是平台真实结构
362
+ (`{field:{...},value:{format,valueJson}}`,公式引用形如 `${data.node.N1.xxx}`);
363
+ CLI **原样透传并只校验字段名,不臆造公式**。请用 `flow templates` / `flow get` 取 golden 骨架。
364
+ - 发布时后端从 `startNodeDef` 派生 `fdProcessActive`;`fdStatus=1` 即已启用。
365
+ - 运行日志端点因部署而异:源码声明 `ModelingProcessLog/findAll`,新版页面用
366
+ `sysModelingLog/findAllWithAppId`;`flow logs` 已内置候选回退,可用 `--endpoint` 指定抓包结果。
367
+ - 运行时触发端点 `executeFlowForAjax` 位于 `sys-xform` 运行时包(无文档化 REST 路径);
368
+ CLI 生成的按钮脚本走 `MKXFORM.flow_<fdCode>`,用 `operation create --type script` + `operation attach` 挂载。
369
+ - 完整命令与 Flow Spec 语法见
370
+ [skills/lan-low-code-cli/references/cli-contract.md](skills/lan-low-code-cli/references/cli-contract.md) 第 10 节。
371
+
199
372
  ### 控件类型
200
373
 
201
374
  **先查环境再选控件**:
@@ -832,6 +1005,16 @@ llc config show | set | clear
832
1005
  | 外部表字段 | `POST sys-xform/sysXFormDataModelField/loadFieldMeta` |
833
1006
  | 字段库 | `POST sys-xform/sysXFormWordsField/list` |
834
1007
  | 字段编码生成 | `POST sys-xform/sysXFormWordsField/generateFdKey` |
1008
+ | 动作流定义 CRUD / 列表 / 详情 | `POST sys-modeling/process/define/{list,get,add,update,delete,checkCodeUniqueness}` |
1009
+ | 动作流草稿与发布 | `POST sys-modeling/process/define/{addDraft,updateDraft,addPublish,updatePublish,saveDraft,publish}` |
1010
+ | 动作流启停 | `POST sys-modeling/process/define/{startup,stop}` |
1011
+ | 动作流引用关系 | `POST sys-modeling/modelingProcessDefineReferList/listByRefer` |
1012
+ | 动作流 Schema / 元数据 | `POST sys-modeling/process/define/{getSourceFields,getConditionFields,getSourceJsonSchema,getProcessDataOutJsonSchema,loadDataModel,businessNodes,nextN,…}`、`POST sys-modeling/processNode/define/*` |
1013
+ | 动作流分类 | `POST sys-modeling/sysModelingProcessCategory/{list,get,add,update,delete}` |
1014
+ | 动作流运行日志 | `POST sys-modeling/ModelingProcessLog/{findAll,get,relation}`(环境差异时可用 `--endpoint` 覆盖) |
1015
+
1016
+ > `getSourceJsonSchema` / `getProcessDataOutJsonSchema` 的 `entityId` 必须带 `sys-modeling#` 前缀;
1017
+ > `getSourceFields` / `getConditionFields` / `loadDataModel` 用裸 id。详见动作流章节。
835
1018
 
836
1019
  ## 五、生成的表单配置结构(`fdConfig`,**持久化格式**)
837
1020
 
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flowApi = exports.FLOW_LIST_COLUMNS = exports.FLOW_LOG_ENDPOINTS = void 0;
4
+ exports.qualifyEntityId = qualifyEntityId;
5
+ /**
6
+ * 动作流(sysModelingActionFlow)接口
7
+ *
8
+ * 前端 `src/utils/http.ts:3` 使用 `Http.build({ modulePrefixName: 'sys-modeling' })`,
9
+ * `src/api/sysModelingActionFlow.ts:5-69` 以 `Api.build('process/define/xxx', http)` 声明端点。
10
+ * CLI 的 LcodeClient 拼接 `${baseUrl}/${relativePath}`(baseUrl 含 /data),
11
+ * 因此完整地址为 `http://<host>/data/sys-modeling/process/define/list`。
12
+ * 同构证据:`Api.build('sysModelingApplication/list', http)` 对应已验证的
13
+ * `sys-modeling/sysModelingApplication/list`。
14
+ *
15
+ * 所有接口均为 POST + JSON。
16
+ */
17
+ const DEFINE_BASE = 'sys-modeling/process/define';
18
+ const NODE_DEFINE_BASE = 'sys-modeling/processNode/define';
19
+ const CATEGORY_BASE = 'sys-modeling/sysModelingProcessCategory';
20
+ const LOG_BASE = 'sys-modeling/ModelingProcessLog';
21
+ const REFER_BASE = 'sys-modeling/modelingProcessDefineReferList';
22
+ /**
23
+ * 真实环境实测:getSourceJsonSchema / getProcessDataOutJsonSchema 要求 entityId
24
+ * 带模块前缀 `sys-modeling#`,裸 id 会返回 HTTP 500;而 getSourceFields /
25
+ * getConditionFields / loadDataModel 用裸 id 正常。与真实数据里的
26
+ * extraAttr.context_bindFormId = "sys-modeling#<fdId>" 一致。
27
+ */
28
+ function qualifyEntityId(entityId) {
29
+ return entityId.includes('#') ? entityId : `sys-modeling#${entityId}`;
30
+ }
31
+ /** 日志列表端点候选(按优先级);可用 --endpoint 覆盖 */
32
+ exports.FLOW_LOG_ENDPOINTS = [
33
+ `${LOG_BASE}/findAll`,
34
+ 'sys-modeling/sysModelingLog/findAllWithAppId',
35
+ 'sys-modeling/sysModelingLog/findAll',
36
+ ];
37
+ exports.FLOW_LIST_COLUMNS = [
38
+ 'fdId', 'fdName', 'fdDesc', 'fdCode', 'fdCreator', 'fdCreateTime',
39
+ 'fdStatus', 'fdStartWay', 'fdProcessData', 'fdProcessActive', 'fdAppCode', 'fdCategory',
40
+ ];
41
+ exports.flowApi = {
42
+ // ---- 定义 CRUD ----
43
+ list: (client, request = {}) => client.post(`${DEFINE_BASE}/list`, {
44
+ columns: exports.FLOW_LIST_COLUMNS,
45
+ pageNo: 1,
46
+ pageSize: 1000,
47
+ sorts: { fdCreateTime: 'desc' },
48
+ ...request,
49
+ }),
50
+ get: (client, fdId) => client.post(`${DEFINE_BASE}/get`, { fdId }),
51
+ add: (client, vo) => client.post(`${DEFINE_BASE}/add`, vo),
52
+ update: (client, vo) => client.post(`${DEFINE_BASE}/update`, vo),
53
+ remove: (client, fdId) => client.post(`${DEFINE_BASE}/delete`, { fdId }),
54
+ checkCodeUniqueness: (client, fdCode, fdAppCode) => client.post(`${DEFINE_BASE}/checkCodeUniqueness`, { fdCode, fdAppCode }),
55
+ // ---- 草稿 / 发布 / 状态机(UI 保存与发布走的是这四个端点) ----
56
+ addDraft: (client, vo) => client.post(`${DEFINE_BASE}/addDraft`, vo),
57
+ updateDraft: (client, vo) => client.post(`${DEFINE_BASE}/updateDraft`, vo),
58
+ addPublish: (client, vo) => client.post(`${DEFINE_BASE}/addPublish`, vo),
59
+ updatePublish: (client, vo) => client.post(`${DEFINE_BASE}/updatePublish`, vo),
60
+ saveDraft: (client, vo) => client.post(`${DEFINE_BASE}/saveDraft`, vo),
61
+ publish: (client, vo) => client.post(`${DEFINE_BASE}/publish`, vo),
62
+ startup: (client, fdId) => client.post(`${DEFINE_BASE}/startup`, { fdId }),
63
+ stop: (client, fdId) => client.post(`${DEFINE_BASE}/stop`, { fdId }),
64
+ // ---- 引用关系(删除前检查) ----
65
+ listByRefer: (client, fdId) => client.post(`${REFER_BASE}/listByRefer`, {
66
+ conditions: { fdReferId: fdId },
67
+ pageNo: 1,
68
+ pageSize: 1000,
69
+ }),
70
+ // ---- Schema / 元数据(只读,SchemaResolver 使用) ----
71
+ businessNodes: (client) => client.post(`${DEFINE_BASE}/businessNodes`, {}),
72
+ getSourceFields: (client, entityId) => client.post(`${DEFINE_BASE}/getSourceFields`, { entityId, usingTableNameAlias: true }),
73
+ getConditionFields: (client, request) => client.post(`${DEFINE_BASE}/getConditionFields`, request),
74
+ getJsonSchema: (client, entityId) => client.post(`${DEFINE_BASE}/getSourceJsonSchema`, {
75
+ entityId: qualifyEntityId(entityId), usingTableNameAlias: true,
76
+ }),
77
+ getDataOutJsonSchema: (client, entityId) => client.post(`${DEFINE_BASE}/getProcessDataOutJsonSchema`, {
78
+ entityId: qualifyEntityId(entityId), usingTableNameAlias: true,
79
+ }),
80
+ getActionFlowSchema: (client, code, appCode) => client.post(`${NODE_DEFINE_BASE}/getActiveTriggerParamSchema`, { code, appCode }),
81
+ getEventSchema: (client, code) => client.post(`${NODE_DEFINE_BASE}/getEventSchema`, { code }),
82
+ getInterfaceSchema: (client, code) => client.post(`${NODE_DEFINE_BASE}/getInterfaceSchema`, { code }),
83
+ getApiMethodSchema: (client, request) => client.post(`${NODE_DEFINE_BASE}/getApiMethodSchema`, request),
84
+ getFlowBotsSchema: (client, code) => client.post(`${NODE_DEFINE_BASE}/getFlowBotsSchema`, { code }),
85
+ getProcessEntityDetail: (client, request) => client.post(`${DEFINE_BASE}/getProcessEntityDetail`, request),
86
+ getQueryStatisticsSchema: (client, request) => client.post(`${DEFINE_BASE}/getQueryStatisticsSchema`, request),
87
+ getMetaJsonSchema: (client, request) => client.post(`${DEFINE_BASE}/getMetaJsonSchema`, request),
88
+ loadDataModel: (client, request) => client.post(`${DEFINE_BASE}/loadDataModel`, request),
89
+ getProcessDataEventInfo: (client) => client.post(`${DEFINE_BASE}/getProcessDataEventInfo`, {}),
90
+ getRecycleState: (client, entityId) => client.post('sys-modeling/sysModelingMechConfig/findByEntityId', { entityId }),
91
+ previewScheduled: (client, request) => client.post(`${DEFINE_BASE}/nextN`, request),
92
+ // ---- 分类 ----
93
+ categoryList: (client, request = {}) => client.post(`${CATEGORY_BASE}/list`, request),
94
+ categoryGet: (client, fdId) => client.post(`${CATEGORY_BASE}/get`, { fdId }),
95
+ categoryAdd: (client, vo) => client.post(`${CATEGORY_BASE}/add`, vo),
96
+ categoryUpdate: (client, vo) => client.post(`${CATEGORY_BASE}/update`, vo),
97
+ categoryDelete: (client, fdId) => client.post(`${CATEGORY_BASE}/delete`, { fdId }),
98
+ // ---- 运行日志 ----
99
+ /**
100
+ * 源码 `sysModelingActionFlowLog.ts:7` 声明 ModelingProcessLog/findAll,
101
+ * 但实测环境返回 404;日志页另有 LogQuery 的 `/sysModelingLog/findAllWithAppId`。
102
+ * 因此按候选顺序回退,并允许 --endpoint 指定抓包得到的真实路径。
103
+ */
104
+ logFindAll: async (client, request, endpoint) => {
105
+ const paths = endpoint ? [endpoint] : exports.FLOW_LOG_ENDPOINTS;
106
+ const failures = [];
107
+ for (const path of paths) {
108
+ try {
109
+ return await client.post(path, request);
110
+ }
111
+ catch (err) {
112
+ failures.push(`${path} → ${err.message.split('\n')[0]}`);
113
+ }
114
+ }
115
+ throw new Error(`动作流日志端点均不可用(环境版本可能与源码不同);可用 --endpoint 指定:\n ${failures.join('\n ')}`);
116
+ },
117
+ logGet: (client, request) => client.post(`${LOG_BASE}/get`, request),
118
+ logRelation: (client, request) => client.post(`${LOG_BASE}/relation`, request),
119
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dataSetApi = exports.modelingAppApi = exports.modelingXFormApi = exports.designApi = exports.wordsFieldApi = exports.dataModelApi = exports.formCategoryApi = exports.formDefineApi = void 0;
3
+ exports.dataSetApi = exports.modelingAppApi = exports.categoryModelApi = exports.modelingXFormApi = exports.designApi = exports.wordsFieldApi = exports.dataModelApi = exports.formCategoryApi = exports.formDefineApi = void 0;
4
4
  /**
5
5
  * 表单定义接口(后端 SysGeneralFormDefineController)
6
6
  * 基础路径:/data/sys-xform/generalFormDefine/
@@ -141,6 +141,36 @@ exports.modelingXFormApi = {
141
141
  /** 删除业务表单的运行时数据(保留表单定义) */
142
142
  removeData: (client, fdId) => client.post(`${MODELING_XFORM_BASE}/deleteData`, { fdId }),
143
143
  };
144
+ /**
145
+ * 分类表单 / 简单分类表单(后端 SysModelingCategoryModelController)
146
+ *
147
+ * 基础路径:/data/sys-modeling/categoryModel/
148
+ * 流程:init(预生成 fdId 与机制)→ add(建档并建主表)→ save/publish(发布态)
149
+ *
150
+ * fdType:1=分类表单(分类表 + 模板表 + 主表)、2=简单分类表单(聚合表 + 主表)
151
+ */
152
+ const CATEGORY_MODEL_BASE = 'sys-modeling/categoryModel';
153
+ exports.categoryModelApi = {
154
+ /** 初始化:返回预生成 fdId 与机制(sys-xform 等) */
155
+ init: (client) => client.post(`${CATEGORY_MODEL_BASE}/init`, {}),
156
+ /** 新建分类表单,返回 { fdId } */
157
+ add: (client, payload) => client.post(`${CATEGORY_MODEL_BASE}/add`, payload),
158
+ /** 详情(含 mechanisms) */
159
+ get: (client, fdId) => client.post(`${CATEGORY_MODEL_BASE}/get`, {
160
+ fdId,
161
+ mechanisms: { load: '*' },
162
+ }),
163
+ /** 保存(草稿) */
164
+ save: (client, payload) => client.post(`${CATEGORY_MODEL_BASE}/save`, payload),
165
+ /** 发布 */
166
+ publish: (client, payload) => client.post(`${CATEGORY_MODEL_BASE}/publish`, payload),
167
+ /** 列表(按编码/名称等条件查询) */
168
+ list: (client, request = {}) => client.post(`${CATEGORY_MODEL_BASE}/list`, {
169
+ pageNo: 1,
170
+ pageSize: 20,
171
+ ...request,
172
+ }),
173
+ };
144
174
  /** 业务建模应用接口 */
145
175
  const MODELING_APP_BASE = 'sys-modeling/sysModelingApplication';
146
176
  exports.modelingAppApi = {
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.operationApi = void 0;
4
+ /**
5
+ * 表单业务操作接口(后端 SysModelingOperationController)
6
+ * 基础路径:/data/sys-modeling/sysModelingOperation/
7
+ * 所有接口均为 POST + JSON
8
+ */
9
+ const BASE = 'sys-modeling/sysModelingOperation';
10
+ exports.operationApi = {
11
+ /** 业务操作列表(按表单:conditions.fdXForm) */
12
+ list: (client, request = {}) => client.post(`${BASE}/list`, request),
13
+ /** 业务操作详情 */
14
+ get: (client, fdId) => client.post(`${BASE}/get`, { fdId }),
15
+ /** 新建业务操作,返回 { fdId } */
16
+ add: (client, vo) => client.post(`${BASE}/add`, vo),
17
+ /** 修改业务操作(请求体为完整 VO,未提交的字段会被保留) */
18
+ update: (client, vo) => client.post(`${BASE}/update`, vo),
19
+ /** 删除业务操作 */
20
+ remove: (client, fdId) => client.post(`${BASE}/delete`, { fdId }),
21
+ /** 查询业务操作被引用的情况(删除前校验) */
22
+ listByRefer: (client, fdId) => client.post(`${BASE}/listByRefer`, {
23
+ conditions: { fdReferId: fdId },
24
+ offset: 0,
25
+ pageSize: 1000,
26
+ }),
27
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templateApi = void 0;
4
+ /**
5
+ * 分类表单模板(发起页模板)接口。
6
+ *
7
+ * 模板不是普通表单:分类表单下挂的是「虚拟模板」
8
+ * - 分类表单(fdType=1):`/data/sys-modeling/categoryTemplate/*`
9
+ * - 简单分类表单(fdType=2):`/data/sys-modeling/virtualPolymers/*`
10
+ * 两者都可通过 `virtualCommonTemplate/*` 统一 get / save / publish。
11
+ *
12
+ * 注意:官方 `init` 接口在模板表元数据未就绪时会空指针(FormTemplateVirtualMetaEntityListener),
13
+ * 因此这里直接 `add`(带 `mechanisms['sys-xform'].fdBuildNew=true`),由后端建表并生成元数据,
14
+ * 再用 `sys-xform/sysXFormDesign/save` 写入字段与视图。
15
+ */
16
+ const CATEGORY_MODEL_BASE = 'sys-modeling/categoryModel';
17
+ const CATEGORY_TEMPLATE_BASE = 'sys-modeling/categoryTemplate';
18
+ const POLYMERS_BASE = 'sys-modeling/virtualPolymers';
19
+ const VIRTUAL_COMMON_BASE = 'sys-modeling/virtualCommonTemplate';
20
+ const VIRTUAL_CATEGORY_BASE = 'sys-modeling/virtualCategory';
21
+ exports.templateApi = {
22
+ /** 按编码查分类表单(分类表单与简单分类表单都在 categoryModel 表) */
23
+ findCategoryByCode: (client, code) => client.post(`${CATEGORY_MODEL_BASE}/list`, {
24
+ conditions: { fdCode: code },
25
+ pageNo: 1,
26
+ pageSize: 1,
27
+ count: true,
28
+ }),
29
+ /** 创建模板:简单分类走 virtualPolymers,普通分类走 categoryTemplate */
30
+ create: (client, kind, payload) => client.post(kind === 'simple' ? `${POLYMERS_BASE}/add` : `${CATEGORY_TEMPLATE_BASE}/add`, payload),
31
+ /** 读取模板(统一入口,按分类表单类型分流) */
32
+ get: (client, fdId, categoryCode) => client.post(`${VIRTUAL_COMMON_BASE}/get`, {
33
+ fdId,
34
+ fdCategoryModelCode: categoryCode,
35
+ mechanisms: { load: '*' },
36
+ }),
37
+ /** 保存模板 */
38
+ save: (client, payload) => client.post(`${VIRTUAL_COMMON_BASE}/save`, payload),
39
+ /** 发布模板 */
40
+ publish: (client, payload) => client.post(`${VIRTUAL_COMMON_BASE}/publish`, payload),
41
+ /** 更新模板(用于挂分类节点等) */
42
+ update: (client, payload) => client.post(`${VIRTUAL_COMMON_BASE}/update`, payload),
43
+ /** 模板列表(运行时分类树,含模板卡片) */
44
+ tree: (client, categoryCode) => client.post(`${VIRTUAL_CATEGORY_BASE}/tree`, { fdCategoryModelCode: categoryCode, mechanisms: { load: '*' } }),
45
+ /** 新建分类节点(分类表单的模板必须挂在分类节点下才会出现在发起页) */
46
+ addCategoryNode: (client, payload) => client.post(`${VIRTUAL_CATEGORY_BASE}/add`, {
47
+ hasChild: false,
48
+ ...payload,
49
+ }),
50
+ /** 列出分类表单下的模板:简单分类走运行时树,分类表单走 listAll */
51
+ listByCategory: (client, kind, categoryCode) => kind === 'simple'
52
+ ? client.post(`${VIRTUAL_CATEGORY_BASE}/tree`, { fdCategoryModelCode: categoryCode, mechanisms: { load: '*' } })
53
+ : client.post(`${CATEGORY_TEMPLATE_BASE}/listAll`, {
54
+ fdCategoryModelCode: categoryCode,
55
+ mechanisms: { load: '*' },
56
+ }),
57
+ /** 批量删除模板 */
58
+ deleteTemplates: (client, kind, categoryCode, fdIds) => kind === 'simple'
59
+ ? client.post(`${POLYMERS_BASE}/batchDelete`, {
60
+ fdIds,
61
+ fdCategoryModelCode: categoryCode,
62
+ })
63
+ : client.post(`${CATEGORY_TEMPLATE_BASE}/batchDelete`, {
64
+ fdIds,
65
+ fdCategoryModelCode: categoryCode,
66
+ }),
67
+ /** 删除分类节点 */
68
+ deleteCategoryNode: (client, categoryCode, fdId) => client.post(`${VIRTUAL_CATEGORY_BASE}/delete`, {
69
+ fdId,
70
+ fdCategoryModelCode: categoryCode,
71
+ }),
72
+ /** 读取模板的表单设计(xform 设计器接口) */
73
+ loadDesign: (client, fdId) => client.post(`sys-xform/sysXFormDesign/load`, { fdId }),
74
+ /** 保存模板的表单设计 */
75
+ saveDesign: (client, payload) => client.post(`sys-xform/sysXFormDesign/save`, payload),
76
+ };
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formViewApi = exports.listViewApi = void 0;
4
+ /** 列表视图:按钮配置在 fdExtendConfig[platform].operationList */
5
+ const LIST_VIEW_BASE = 'sys-modeling/sysModelingListView';
6
+ /** 查看/新建视图:按钮配置在 fdConfig[platform].operationList */
7
+ const VIEW_BASE = 'sys-modeling/sysModelingView';
8
+ exports.listViewApi = {
9
+ list: (client, request = {}) => client.post(`${LIST_VIEW_BASE}/list`, request),
10
+ get: (client, fdId) => client.post(`${LIST_VIEW_BASE}/get`, {
11
+ fdId,
12
+ mechanisms: { load: '*' },
13
+ }),
14
+ update: (client, vo) => client.post(`${LIST_VIEW_BASE}/update`, vo),
15
+ };
16
+ exports.formViewApi = {
17
+ list: (client, request = {}) => client.post(`${VIEW_BASE}/list`, request),
18
+ get: (client, fdId) => client.post(`${VIEW_BASE}/get`, {
19
+ fdId,
20
+ mechanisms: { load: '*' },
21
+ }),
22
+ update: (client, vo) => client.post(`${VIEW_BASE}/update`, vo),
23
+ };