lan-low-code-cli 2.5.0 → 2.6.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.
@@ -1,2653 +1,2653 @@
1
- # MKXFORM API 完整文档
2
-
3
- ## 目录
4
-
5
- - [1. 概述](#1-概述)
6
- - [2. 直接属性(initRuntime)](#2-直接属性initruntime)
7
- - [3. 内置函数(inner)](#3-内置函数inner)
8
- - [4. 常用变量(vars)](#4-常用变量vars)
9
- - [5. 通用函数(global)](#5-通用函数global)
10
- - [6. 主表函数(functions)](#6-主表函数functions)
11
- - [7. 明细表函数(details)](#7-明细表函数details)
12
- - [8. 事件(events)](#8-事件events)
13
- - [9. 流程函数(lbpms)](#9-流程函数lbpms)
14
- - [10. 集成平台(integrate)](#10-集成平台integrate)
15
- - [11. 组织架构(orgFunctions)](#11-组织架构orgfunctions)
16
- - [12. 动作流(flow)](#12-动作流flow)
17
- - [13. LanBots AI(lanbots)](#13-lanbots-ailanbots)
18
- - [14. 全局环境变量(GLOBALJS)](#14-全局环境变量globaljs)
19
- - [15. 注册顺序与生命周期](#15-注册顺序与生命周期)
20
-
21
- ---
22
-
23
- ## 1. 概述
24
-
25
- `MKXFORM` 是表单运行时的全局 API 对象,挂载在 `window.MKXFORM` 上(设计器模式通过 `initDesign`),提供了表单操作、控件交互、事件监听、流程操作等全部能力。
26
-
27
- **初始化入口:**
28
-
29
- - `MKXFORMFACTORY.initRuntime(payload)` — 创建 MKXFORM 对象并同步注册 API
30
- - `MKXFORMFACTORY.initDesign(props)` — 设计器模式,额外异步注册集成/流程/组织等 API
31
-
32
- **属性统计:**
33
-
34
- | 分类 | 数量 |
35
- | ------------------ | ------- |
36
- | 直接属性 | 15 |
37
- | 内置函数(inner) | 5 |
38
- | 常用变量(vars) | 5 |
39
- | 通用函数(global) | 13 |
40
- | 主表函数(functions) | 9 |
41
- | 明细表函数(details) | 17 |
42
- | 事件(events) | 3 |
43
- | 流程函数(fixLbpms) | 4 |
44
- | **同步合计** | **~71** |
45
- | 集成平台(integrate) | 动态 |
46
- | 流程平台(lbpms) | 动态 |
47
- | 组织架构(orgFunctions) | 动态 |
48
- | 动作流(flow) | 动态 |
49
- | LanBots(lanbots) | 动态 |
50
-
51
- ---
52
-
53
- ## 2. 直接属性(initRuntime)
54
-
55
- > 来源:`MKXFORMFACTORY.initRuntime` 中直接赋值
56
-
57
- | # | 属性名 | 类型 | 说明 |
58
- |---|--------|------|------|
59
- | 1 | `MKXFORM_DATA_CONTAINER` | `object` | 表单提交钩子容器,包含 `$$beforeSubmit`(提交前函数数组)和 `$$afterSubmit`(提交后函数数组) |
60
- | 2 | `viewStatus` | `string` | 视图状态(如 `edit`、`read` 等),后续被 vars 模块覆盖为 getter |
61
- | 3 | `docStatus` | `string` | 文档/流程状态,后续被 vars 模块覆盖为 getter |
62
- | 4 | `processInstanceId` | `string` | 当前流程实例 ID |
63
- | 5 | `platform` | `string` | 设备端(`pc` / `mobile`),后续被 vars 模块覆盖为 getter |
64
- | 6 | `dataModels` | `IDataModel[]` | 数据模型配置数组 |
65
- | 7 | `formId` | `string` | 表单 ID,后续被 vars 模块覆盖为 getter |
66
- | 8 | `formSizeType` | `string` | 表单尺寸类型(来自 viewDetail) |
67
- | 9 | `$$FORM` | `React.RefObject<IFormApi>` | 内置表单实例引用 |
68
- | 10 | `$$LBPM` | `React.MutableRefObject<any>` | 流程实例引用 |
69
- | 11 | `$$DETAILFORMS` | `React.MutableRefObject<{[key: string]: any}>` | 明细表实例引用集合 |
70
- | 12 | `$$CONTROLREF` | `React.MutableRefObject<any>` | 控件引用 |
71
- | 13 | `popupOnOk` | `() => void` | 移动端 popup 弹窗确认回调 |
72
- | 14 | `popupOnCancel` | `() => void` | 移动端 popup 弹窗取消回调 |
73
- | 15 | `businessFieldsValue` | `object` | 业务内置字段值(目前仅 EOP 合同模块场景使用) |
74
-
75
- ---
76
-
77
- ## 3. 内置函数(inner)
78
-
79
- > 模块名:`inner`,分组:`EApiGroup.inner`(对用户隐藏)
80
-
81
- ### 3.1 `callTic`
82
-
83
- **描述:** 调用集成平台接口
84
-
85
- **签名:**
86
- ```typescript
87
- callTic(config: { interfaceCode: string, param: any }, callback: (error: any, res: any) => void): Promise<void>
88
- ```
89
-
90
- **参数:**
91
-
92
- | 参数 | 类型 | 说明 |
93
- |------|------|------|
94
- | `config.interfaceCode` | `string` | 集成平台接口编码 |
95
- | `config.param` | `any` | 接口参数 |
96
- | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
97
-
98
- **实现细节:**
99
- - 调用 `api.executeForAjax(config.interfaceCode, config.param)` 发起请求
100
- - 成功时返回 `res.data`
101
- - 失败时自动调用 `Message.error('接口调用异常,请联系管 理员处理!')`,并打印错误到 console
102
- - 支持多语言(`fmtMsg`)
103
-
104
- **使用示例:**
105
- ```javascript
106
- MKXFORM.callTic({ interfaceCode: 'INTERFACE_001', param: { key: 'value' } }, function(error, res) {
107
- if (error) {
108
- console.error('调用失败', error)
109
- return
110
- }
111
- console.log('返回数据', res)
112
- })
113
- ```
114
-
115
- ---
116
-
117
- ### 3.2 `callLbpm`
118
-
119
- **描述:** 调用流程平台接口,自动注入 `processInstanceId` 和 `taskId`
120
-
121
- **签名:**
122
- ```typescript
123
- callLbpm(config: any, callback: (error: any, res: any) => void): Promise<void>
124
- ```
125
-
126
- **参数:**
127
-
128
- | 参数 | 类型 | 说明 |
129
- |------|------|------|
130
- | `config` | `any` | 流程接口配置,需包含 `functionCode` 等字段 |
131
- | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
132
-
133
- **实现细节:**
134
- - 自动注入 `processInstanceId`:优先从 `$$lbpm(MKXFORM)?.getLbpmFormValues()?.processId` 获取,降级到 `MKXFORM.processInstanceId`,最后为 `null`
135
- - 自动注入 `taskId`:从 `$$lbpm(MKXFORM)?.getLbpmFormValues()?.taskId` 获取,未获取到为 `null`
136
- - 调用 `Api.executeForAjax({ ...config, processInstanceId, taskId })`
137
- - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
138
- - 支持多语言(`fmtMsg`)
139
-
140
- **使用示例:**
141
- ```javascript
142
- MKXFORM.callLbpm({ functionCode: 'FN_APPROVE' }, function(error, res) {
143
- if (error) {
144
- console.error('调用失败', error)
145
- return
146
- }
147
- console.log('返回数据', res)
148
- })
149
- ```
150
-
151
- ---
152
-
153
- ### 3.3 `callOrg`
154
-
155
- **描述:** 调用组织架构函数接口
156
-
157
- **签名:**
158
- ```typescript
159
- callOrg(config: { id: string, param?: any }, callback: (error: any, res: any) => void): Promise<void>
160
- ```
161
-
162
- **参数:**
163
-
164
- | 参数 | 类型 | 说明 |
165
- |------|------|------|
166
- | `config.id` | `string` | 组织函数 ID,支持 `.` 分隔的路径(如 `com.example.getDept`),内部会按 `.` 分割取第二部分作为路径 |
167
- | `config.param` | `any`(可选) | 函数参数,默认 `{}` |
168
- | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
169
-
170
- **实现细节:**
171
- - 内部通过 `OrgHttp.post('/sysOrgJsFormula/{path}', param)` 发起请求
172
- - `id` 按 `.` 分割后取第二部分作为 URL 路径(如 `org.getDeptById` → `/sysOrgJsFormula/getDeptById`)
173
- - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
174
- - 支持多语言(`fmtMsg`)
175
-
176
- **使用示例:**
177
- ```javascript
178
- // 根据组织编码查找组织
179
- MKXFORM.callOrg({ id: 'sysorg.getElementByNo', param: { fdNo: 'DEPT001', orgType: 2 } }, function(error, res) {
180
- if (error) {
181
- console.error('调用失败', error)
182
- return
183
- }
184
- console.log('部门信息', res)
185
- })
186
- ```
187
-
188
- ---
189
-
190
- ### 3.4 `callFlow`
191
-
192
- **描述:** 调用动作流函数接口
193
-
194
- **签名:**
195
- ```typescript
196
- callFlow(config: { context: any, fdProcessId: string, incParams: any, fdProcessCode: string }, callback: (error: any, res: any, context: any) => void): Promise<void>
197
- ```
198
-
199
- **参数:**
200
-
201
- | 参数 | 类型 | 说明 |
202
- |------|------|------|
203
- | `config.context` | `any` | 上下文对象,内部通过 `context.fdOprId` 获取操作 ID |
204
- | `config.fdProcessId` | `string` | 流程定义 ID |
205
- | `config.incParams` | `any` | 附加参数 |
206
- | `config.fdProcessCode` | `string` | 流程编码 |
207
- | `callback` | `(error, res, context) => void` | 回调函数,第三个参数返回原始 context 对象 |
208
-
209
- **实现细节:**
210
- - 调用 `api.executeFlowForAjax({ fdOprId: context.fdOprId, fdProcessId, fdProcessCode, incParams })`
211
- - 成功时返回 `(null, res, context)`,context 原样回传
212
- - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
213
-
214
- **使用示例:**
215
- ```javascript
216
- MKXFORM.callFlow({
217
- context: { fdOprId: 'opr_001' },
218
- fdProcessId: 'process_001',
219
- incParams: {},
220
- fdProcessCode: 'FLOW_APPROVE'
221
- }, function(error, res, context) {
222
- if (error) {
223
- console.error('调用失败', error)
224
- return
225
- }
226
- console.log('流程执行结果', res)
227
- console.log('上下文', context)
228
- })
229
- ```
230
-
231
- ---
232
-
233
- ### 3.5 `callLanBots`
234
-
235
- **描述:** 调用 LanBots 快速阅读和辅助填写 AI 功能
236
-
237
- **签名:**
238
- ```typescript
239
- callLanBots(config: { fdCode: string, id: string, lanBotsType: string }, callback: (error: any, res: any) => void): void
240
- ```
241
-
242
- **参数:**
243
-
244
- | 参数 | 类型 | 说明 |
245
- |------|------|------|
246
- | `config.fdCode` | `string` | LanBots 编码 |
247
- | `config.id` | `string` | 模型 ID |
248
- | `config.lanBotsType` | `string` | 使用场景类型 |
249
- | `callback` | `(error, res) => void` | 回调函数,res 包含 `success` 和 `content` 字段 |
250
-
251
- **实现细节:**
252
- - 通过 `window['sys-xform-lanBots']` 防止重复打开(已有打开的 LanBots 时不再创建新实例)
253
- - 调用 `openLanBots(config, callback, MKXFORM, {})` 打开 AI 助手
254
- - 成功时可通过 `res.success` 和 `res.content` 获取 AI 返回内容,配合 `setValue` 回填表单
255
- - 异常时回调 `callback(error, { success: false })`
256
-
257
- **使用示例:**
258
- ```javascript
259
- MKXFORM.callLanBots({
260
- fdCode: 'CAT_001',
261
- id: 'BOT_001',
262
- lanBotsType: 'quickRead'
263
- }, function(error, res) {
264
- console.log(res)
265
- if (res && res.success) {
266
- // 将 AI 返回的内容回填到表单
267
- MKXFORM.setValue('field_id', res.content)
268
- }
269
- })
270
- ```
271
-
272
- ---
273
-
274
- ## 4. 常用变量(vars)
275
-
276
- > 模块名:`vars`,分组:`EApiGroup.all`
277
-
278
- 这些变量为只读属性,注册后会覆盖 `initRuntime` 中的同名直接属性。
279
-
280
- | # | 属性名 | 类型 | 说明 |
281
- | --- | ------------ | -------- | ------------------ |
282
- | 1 | `mkXform` | `object` | 内置表单对象(MKXFORM 自身) |
283
- | 2 | `viewStatus` | `string` | 视图状态(edit/read 等) |
284
- | 3 | `docStatus` | `string` | 文档/流程状态 |
285
- | 4 | `platform` | `string` | 设备端(pc/mobile) |
286
- | 5 | `formId` | `string` | 表单 ID |
287
-
288
- **使用示例:**
289
- ```javascript
290
- var status = MKXFORM.viewStatus // 获取当前视图状态
291
- var docStatus = MKXFORM.docStatus // 获取文档状态
292
- var platform = MKXFORM.platform // 获取设备端
293
- var fid = MKXFORM.formId // 获取表单ID
294
- ```
295
-
296
- ---
297
-
298
- ## 5. 通用函数(global)
299
-
300
- > 模块名:`global`,分组:`EApiGroup.all`
301
-
302
- ### 5.1 `ajax`
303
-
304
- **描述:** 发起异步 HTTP 请求。本质是 `axios()` 方法,可参考 http://axios-js.com/zh-cn/docs/index.html 中 axios 方法使用方式。
305
-
306
- **签名:**
307
- ```typescript
308
- ajax(config: AxiosRequestConfig, callback: (error: any, res: any) => void): Promise<any>
309
- ```
310
-
311
- **参数:**
312
-
313
- | 参数 | 类型 | 说明 |
314
- |------|------|------|
315
- | `config` | `AxiosRequestConfig` | axios 请求配置(url、method、data、headers 等),可参考 [axios 文档](http://axios-js.com/zh-cn/docs/index.html) |
316
- | `callback` | `(error, res) => void` | 回调函数。参数 `error` 为错误信息;参数 `res` 为响应数据 |
317
-
318
- **返回值:** `res` 结构为 `{ msg: string, success: boolean, data: any }`。
319
-
320
- **实现细节:**
321
- - 使用 `httpBaseUrl(url)` 解析相对 URL(兼容上下文的场景)
322
- - 错误时将 `err.response` 传递给回调函数
323
-
324
- **使用示例:**
325
- ```javascript
326
- MKXFORM.ajax({
327
- method: 'GET',
328
- url: '/api/data'
329
- }, function (error, res) {
330
- console.log(res) // {msg: 'xxx', success: true, data: xxx}
331
- })
332
- ```
333
-
334
- ---
335
-
336
- ### 5.2 `getLocale`
337
-
338
- **描述:** 获取多语言信息。可用于获取用户当前多语言标志,或返回传入键值对中匹配当前语言的值。
339
-
340
- **签名:**
341
- ```typescript
342
- getLocale(messages?: { Cn: string, Us: string, [locale: string]: string }): string
343
- ```
344
-
345
- **参数:**
346
-
347
- | 参数 | 类型 | 说明 |
348
- | -------------- | --------------------------------- | ------------------------------------- |
349
- | `messages`(可选) | `{ Cn: string, Us: string, ... }` | 多语言文本映射表。格式为 `{ Cn: '中文', Us: '英文' }` |
350
- | | | |
351
-
352
- **返回值:** 若传 `messages` 则返回当前语言对应的文本;若未传参则返回当前语言标志(如 `Cn`、`Us`)。
353
-
354
- **实现细节:**
355
- - 使用 `getDefaultLocale()` 从 runtime utils 获取当前语言标志
356
- - 若传入 `messages` 但格式不正确(缺少 `Cn` 或 `Us` 键),打印警告:`console.warn('参数不对,格式应为 {Cn: "中文", Us: "英文"}')`
357
-
358
- **使用示例:**
359
- ```javascript
360
- // 若当前用户语言为中文,未传参则直接返回 'Cn'
361
- MKXFORM.getLocale()
362
-
363
- // 若当前用户语言为中文,传了多语言键值对,则返回 '中文'
364
- MKXFORM.getLocale({ Cn: '中文', Us: '英文' })
365
- ```
366
-
367
- ---
368
-
369
- ### 5.3 `validateFields`
370
-
371
- **描述:** 强制触发表单校验,返回值为一个 Promise。
372
-
373
- **签名:**
374
- ```typescript
375
- validateFields(): Promise<{ errors: any, value: any, values: any }>
376
- ```
377
-
378
- **返回值:** Promise,resolve 时返回验证结果对象:
379
-
380
- | 字段 | 类型 | 说明 |
381
- |------|------|------|
382
- | `errors` | `object` | 错误字段数据,key 为字段 ID,value 为错误信息数组。无错误时为空 |
383
- | `value` | `any` | 表单值(同 values) |
384
- | `values` | `any` | 表单所有值 |
385
-
386
- **实现细节:**
387
- - 委托给 `$$form(MKXFORM)?.validateFields()` 执行
388
- - 内置 `withdraw()` 存根方法(TODO,待实现)
389
-
390
- **errors 格式示例:**
391
- ```json
392
- {
393
- "mk_model_xxx.fd_col_xxx": {
394
- "errors": [
395
- { "message": "单行文本1不能为空", "field": "mk_model_xxx.fd_col_xxx" }
396
- ]
397
- }
398
- }
399
- ```
400
-
401
- **使用示例:**
402
- ```javascript
403
- MKXFORM.validateFields()
404
- .then(function(result) {
405
- var errors = result.errors
406
- var values = result.values
407
- console.log('错误字段数据', errors)
408
- console.log('表单数据', values)
409
- })
410
- ```
411
-
412
- ---
413
-
414
- ### 5.4 `getFormConfigs`
415
-
416
- **描述:** 获取表单基础配置信息,如表单全部字段 ID、表 ID、表单 fdId 和字段对应控件等。
417
-
418
- **签名:**
419
- ```typescript
420
- getFormConfigs(): any
421
- ```
422
-
423
- **返回值:** 表单配置对象,包含表单所有字段的 ID、表 ID、表单 fdId、各字段对应的控件类型等信息。
424
-
425
- **实现细节:**
426
- - 委托给 `$$form(MKXFORM)?.getFormConfigs()` 执行
427
-
428
- **使用示例:**
429
- ```javascript
430
- var config = MKXFORM.getFormConfigs()
431
- ```
432
-
433
- ---
434
-
435
- ### 5.5 `getFormValues`
436
-
437
- **描述:** 获取整个表单所有值,以键值对形式返回,包含机制数据和系统字段数据。
438
-
439
- **签名:**
440
- ```typescript
441
- getFormValues(): any
442
- ```
443
-
444
- **返回值:** 表单所有字段值对象 `{ fieldId: value, ... }`,包含机制数据和系统字段数据。
445
-
446
- **实现细节:**
447
- - 委托给 `$$form(MKXFORM)?.getFieldsValue()` 执行
448
-
449
- **使用示例:**
450
- ```javascript
451
- var values = MKXFORM.getFormValues()
452
- console.log('字段A的值', values.fieldA)
453
- ```
454
-
455
- ---
456
-
457
- ### 5.6 `message`
458
-
459
- **描述:** 全局消息提示(仅支持桌面端),实际调用为 `lui` 库 `Message` 组件方法。
460
-
461
- **类型:** `@lui/core` 的 `Message` 对象
462
-
463
- **方法:**
464
-
465
- | 方法 | 签名 | 说明 |
466
- |------|------|------|
467
- | `success` | `message.success(text: string)` | 成功提示 |
468
- | `error` | `message.error(text: string)` | 错误提示 |
469
- | `warning` | `message.warning(text: string)` | 警告提示 |
470
- | `info` | `message.info(text: string)` | 信息提示 |
471
-
472
- **实现细节:**
473
- - 直接导出 `Message` 对象从 `@lui/core` 库
474
-
475
- **使用示例:**
476
- ```javascript
477
- MKXFORM.message.success('全局成功提示')
478
- MKXFORM.message.warning('全局警告提示')
479
- MKXFORM.message.error('全局错误提示')
480
- ```
481
-
482
- ---
483
-
484
- ### 5.7 `toast`
485
-
486
- **描述:** 全局消息提示(仅支持移动端),实际调用为 `mui` 库 `Toast` 组件方法。
487
-
488
- **签名:**
489
- ```typescript
490
- toast(options: { content: string, icon: 'success' | 'fail' | 'warning' }): void
491
- ```
492
-
493
- **参数:**
494
-
495
- | 参数 | 类型 | 说明 |
496
- |------|------|------|
497
- | `options.content` | `string` | 提示文本 |
498
- | `options.icon` | `'success' \| 'fail' \| 'warning'` | 图标类型 |
499
-
500
- **实现细节:**
501
- - 直接调用 `Toast.show({...options})` 从 `@mui/core` 库
502
-
503
- **使用示例:**
504
- ```javascript
505
- MKXFORM.toast({
506
- content: '全局成功提示',
507
- icon: 'success',
508
- })
509
- ```
510
-
511
- ---
512
-
513
- ### 5.8 `modal`
514
-
515
- **描述:** confirm 弹窗(仅支持桌面端),实际调用为 `lui` 库 `Modal.confirm`,具体用法可参考 `lui` 对应组件。
516
-
517
- **签名:**
518
- ```typescript
519
- modal(options: { title?: string, content: string | ReactNode, onOk?: () => void, onCancel?: () => void }): void
520
- ```
521
-
522
- **参数:**
523
-
524
- | 参数 | 类型 | 说明 |
525
- |------|------|------|
526
- | `options.title` | `string`(可选) | 弹窗标题 |
527
- | `options.content` | `string \| ReactNode` | 弹窗内容 |
528
- | `options.onOk` | `() => void`(可选) | 确认回调 |
529
- | `options.onCancel` | `() => void`(可选) | 取消回调 |
530
-
531
- **实现细节:**
532
- - 使用 `Modal.confirm` 从 `@lui/core` 库
533
- - 默认配置:`cancelText: '取消'`,`okText: '确定'`
534
-
535
- **使用示例:**
536
- ```javascript
537
- MKXFORM.modal({
538
- title: '是否关闭弹窗',
539
- content: '关闭则不再显示',
540
- onOk() {
541
- console.log('点击确认')
542
- },
543
- onCancel() {
544
- console.log('点击取消')
545
- },
546
- })
547
- ```
548
-
549
- ---
550
-
551
- ### 5.9 `mobileModal`
552
-
553
- **描述:** confirm 弹窗(仅支持移动端),实际调用为 `mui` 库 `Modal.confirm`,具体用法可参考 `mui` 对应组件。
554
-
555
- **签名:**
556
- ```typescript
557
- mobileModal(options: { title?: string, content: string, onConfirm?: () => void, onCancel?: () => void }): void
558
- ```
559
-
560
- **参数:**
561
-
562
- | 参数 | 类型 | 说明 |
563
- |------|------|------|
564
- | `options.title` | `string`(可选) | 弹窗标题 |
565
- | `options.content` | `string` | 弹窗内容 |
566
- | `options.onConfirm` | `() => void`(可选) | 确认回调 |
567
- | `options.onCancel` | `() => void`(可选) | 取消回调 |
568
-
569
- **实现细节:**
570
- - 使用 `Modal.confirm` 从 `@mui/core` 库
571
- - 默认配置:`cancelText: '取消'`,`confirmText: '确定'`(注意:移动端使用 `confirmText` 而非 `okText`)
572
-
573
- **使用示例:**
574
- ```javascript
575
- MKXFORM.mobileModal({
576
- title: '是否关闭弹窗',
577
- content: '关闭则不再显示',
578
- onConfirm() {
579
- console.log('点击确认')
580
- },
581
- onCancel() {
582
- console.log('点击取消')
583
- },
584
- })
585
- ```
586
-
587
- ---
588
-
589
- ### 5.10 `tableModal`
590
-
591
- **描述:** 表格弹窗(仅支持桌面端),弹窗内渲染一个表格。
592
-
593
- **签名:**
594
- ```typescript
595
- tableModal(options: { modal: object, table: object }): void
596
- ```
597
-
598
- **参数:**
599
-
600
- | 参数 | 类型 | 说明 |
601
- |------|------|------|
602
- | `options.modal` | `object` | 弹窗配置(title、okCancel、okButtonProps、onOk、onCancel 等),具体配置可参考 [Ant Design Modal](https://4x.ant.design/components/modal-cn) |
603
- | `options.table.columns` | `Array` | 表格列定义(title、key、dataIndex 等),具体配置可参考 [Ant Design Table](https://4x.ant.design/components/table-cn) |
604
- | `options.table.dataSource` | `Array` | 表格数据 |
605
-
606
- **实现细节:**
607
- - 校验 `typeof options !== 'object'`,类型不匹配时返回 `null`
608
- - 使用 `Modal.info` 渲染弹窗,内部通过 `createElement(Table, {...options.table})` 渲染表格
609
- - 默认配置:`width: 1152`,`maxHeight: '776px'`,`destroyOnClose: true`,隐藏 OK 按钮
610
- - 表格默认配置:`scroll: {x: true, y: true}`,`pagination: false`,`maxHeight: '500px'`
611
-
612
- **使用示例:**
613
- ```javascript
614
- MKXFORM.tableModal({
615
- modal: {
616
- title: '这是标题',
617
- okCancel: true, // 显示取消按钮
618
- okButtonProps: {style: {display: ''}}, // 显示确定按钮
619
- renderExtra: () => '扩展区域',
620
- onOk() {
621
- console.log('点击确定')
622
- },
623
- onCancel() {
624
- console.log('点击取消')
625
- },
626
- },
627
- table: {
628
- columns: [
629
- { title: 'Name', key: 'name', dataIndex: 'name' },
630
- { title: 'Age', key: 'age', dataIndex: 'age' },
631
- { title: 'Address', key: 'address', dataIndex: 'address' },
632
- { title: 'Tags', key: 'tags', dataIndex: 'tags' }
633
- ],
634
- dataSource: [
635
- {
636
- key: '1',
637
- name: 'John Brown',
638
- age: 32,
639
- address: 'New York No. 1 Lake Park',
640
- tags: 'cool',
641
- }
642
- ]
643
- }
644
- })
645
- ```
646
-
647
- ---
648
-
649
- ### 5.11 `HTMLModal`
650
-
651
- **描述:** HTML 内容弹窗(仅支持桌面端),支持渲染自定义 HTML 内容。
652
-
653
- **签名:**
654
- ```typescript
655
- HTMLModal(options: { content: string, [key: string]: any }): void
656
- ```
657
-
658
- **参数:**
659
-
660
- | 参数 | 类型 | 说明 |
661
- |------|------|------|
662
- | `options.content` | `string` | HTML 字符串内容(通过 `dangerouslySetInnerHTML` 渲染) |
663
- | 其他 | `any` | 其余 Modal 组件属性(onOk、onCancel、okButtonProps、okCancel 等),具体配置可参考 [Ant Design Modal](https://4x.ant.design/components/modal-cn) |
664
-
665
- **注意:** 默认隐藏 OK 按钮,可通过 `okButtonProps: { style: { display: '' } }` 显示。
666
-
667
- **实现细节:**
668
- - 校验 `typeof options !== 'object'`,类型不匹配时返回 `null`
669
- - 与 `tableModal` 相同的默认配置:`width: 1152`,`maxHeight: '776px'`,`destroyOnClose: true`,隐藏 OK 按钮
670
- - 使用 `createElement('div', {dangerouslySetInnerHTML: {__html: options.content}})` 渲染 HTML 内容
671
-
672
- **使用示例:**
673
- ```javascript
674
- var htmlText = '<div class="card">' +
675
- '<img src="https://picsum.photos/300/200" width="300" height="200">' +
676
- '<div style="padding:16px">' +
677
- '<h3 style="margin:0 0 8px">卡片标题</h3>' +
678
- '<p style="margin:0 0 12px;color:#666">简短描述文字</p>' +
679
- '<button style="padding:8px 16px;background:#007bff;color:#fff;border:none;border-radius:4px">按钮</button>' +
680
- '</div>' +
681
- '</div>' +
682
- '<style>' +
683
- '.card{width:300px;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.1);font-family:system-ui}' +
684
- '</style>'
685
-
686
- MKXFORM.HTMLModal({
687
- onOk() {
688
- console.log('点击确认')
689
- },
690
- onCancel() {
691
- console.log('点击取消')
692
- },
693
- // 显示确定按钮
694
- // okButtonProps: { style: { display: '' } },
695
- // 显示取消按钮
696
- // okCancel: true,
697
- content: htmlText
698
- })
699
- ```
700
-
701
- ---
702
-
703
- ### 5.12 `executeOperation`
704
-
705
- **描述:** 执行业务操作。可执行已配置好的业务操作(包括内置业务操作),此方法无返回值,部分业务操作会进行页面跳转。实际执行 `sys-modeling` 模块下 `src/desktop/operation/execute.ts` 中的 `execute` 方法。
706
-
707
- **签名:**
708
- ```typescript
709
- executeOperation(operation: OperationConfig, params: ParamsConfig): void
710
- ```
711
-
712
- **参数说明:**
713
-
714
- **operation 参数:**
715
-
716
- | 参数 | 类型 | 说明 |
717
- |------|------|------|
718
- | `code` | `string` | 操作按钮类型(add/edit/delete/import/export/print/close/instanceClone/modalDefine/other 等) |
719
- | `uniqueCode` | `string` | 操作唯一编码(不传时通过 `id` 获取操作) |
720
- | `platform` | `'pc' \| 'mobile'` | 设备类型 |
721
- | `id` | `string`(可选) | 操作 ID(不传时通过 `uniqueCode` 获取) |
722
- | `name` | `string`(可选) | 操作名称(用于弹窗标题等) |
723
- | `selected` | `boolean`(可选) | 是否需要选中数据(modalDefine/other 场景) |
724
-
725
- **params 参数:**
726
-
727
- | 参数 | 类型 | 说明 |
728
- | ----------------------- | ------------------------ | ------------------------------------------------- |
729
- | `fdType` | `number` | 表单类型:0-普通表单, 1-分类模板, 2-简单分类 |
730
- | `fdCode` | `string` | 表单编码 |
731
- | `fdXFormId` | `string` | 表单 ID(不传时通过 `fdCode` 调用接口获取) |
732
- | `baseUrl` | `string` | 路径前缀,如 `/current/sys-modeling/app/{appCode}` |
733
- | `fdTemplateId` | `string` | 分类模板 ID(分类表单时必传) |
734
- | `target` / `fdOpenMode` | `string` | 打开方式:`self`、`drawer`、`_blank` 等 |
735
- | `drawerOptions` | `object` | 抽屉配置 |
736
- | `cacheListRef` | `React.MutableRefObject` | 列表引用(用于刷新等操作) |
737
- | `$$contentviewProps` | `object` | 内容视图属性,包含 `refresh`、`history`、`query` 等 |
738
- | `setDoingOperation` | `(v: boolean) => void` | 设置操作进行中状态 |
739
- | `defaultTemplateData` | `string` | 表单默认值(JSON 序列化后会 URL 编码) |
740
- | `callback` | `Function` | 操作完成回调,同步调用业务触发时有效 |
741
- | `docId` | `string` | 文档 ID(edit/delete/print 等场景) |
742
- | `formId` | `string` | 表单 ID(部分场景使用,等价于 `fdXFormId`) |
743
- | `selectedId` | `string[]` | 选中的文档 ID 数组(deleteAll/batchPrint/modalDefine 等场景) |
744
- | `fdRightGroupId` | `string` | 权限组 ID |
745
- | `mechAuthToken` | `string` | 实体认证 Token |
746
- | `dispatch` | `Function` | Redux dispatch(export 场景) |
747
- | `refresh` | `Function` | 刷新回调 |
748
- | `viewPageId` | `string` | 视图页面 ID |
749
- | `entityName` | `string` | 实体名(分类表单场景) |
750
- | `entityId` | `string` | 文档 ID(分类表单场景) |
751
-
752
- **参数转换规则(formatParams):**
753
-
754
- 仅 `add` 和 `other` 操作(PC 端)会进行参数转换:
755
-
756
- | 传入 params 字段 | 转换后字段 | 适用操作 |
757
- |------------------|------------|----------|
758
- | `fdType` | `fdCategoryType` | add |
759
- | `fdCode` | `fdCategoryModelCode` | add, other |
760
- | `fdTemplateId` | `fdCategoryTemplateId` | add |
761
- | `fdXFormId` | `formId` | add |
762
- | `target` | `fdOpenMode` | add, other |
763
-
764
- > 其他操作(delete、edit、print 等)参数不做转换,直接透传。
765
-
766
- **各操作类型详细参数:**
767
-
768
- #### add — 新增
769
-
770
- ```javascript
771
- MKXFORM.executeOperation({
772
- code: 'add',
773
- uniqueCode: 'template_p20v4f',
774
- platform: 'pc'
775
- }, {
776
- fdType: 0,
777
- fdCode: 'template_xxx',
778
- fdXFormId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
779
- baseUrl: '/current/sys-modeling/app/jspanel',
780
- // fdTemplateId: 'template_id_xxx', // 分类表单时必传
781
- // target: 'self', // 打开方式
782
- // defaultTemplateData: '{}', // 表单默认值
783
- callback: function(res) {
784
- console.log(res)
785
- }
786
- })
787
- ```
788
-
789
- #### edit — 编辑
790
-
791
- ```javascript
792
- MKXFORM.executeOperation({
793
- code: 'edit',
794
- platform: 'pc'
795
- }, {
796
- baseUrl: '/current/sys-modeling/app/jspanel',
797
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
798
- docId: 'doc_xxx',
799
- // fdRightGroupId: 'xxx',
800
- // fdOpenMode: 'self',
801
- })
802
- ```
803
-
804
- #### delete — 删除
805
-
806
- ```javascript
807
- MKXFORM.executeOperation({
808
- code: 'delete',
809
- platform: 'pc'
810
- }, {
811
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
812
- docId: 'doc_xxx',
813
- // appId: 'xxx',
814
- // appCode: 'xxx',
815
- // mainTable: true,
816
- })
817
- ```
818
-
819
- #### deleteAll — 批量删除
820
-
821
- ```javascript
822
- MKXFORM.executeOperation({
823
- code: 'deleteAll',
824
- platform: 'pc'
825
- }, {
826
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
827
- selectedId: ['doc_id_1', 'doc_id_2'],
828
- })
829
- ```
830
-
831
- #### import — 导入
832
-
833
- ```javascript
834
- MKXFORM.executeOperation({
835
- code: 'import',
836
- platform: 'pc'
837
- }, {
838
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
839
- // isSimple: false,
840
- // listviewId: 'xxx',
841
- })
842
- ```
843
-
844
- #### export — 导出
845
-
846
- ```javascript
847
- MKXFORM.executeOperation({
848
- code: 'export',
849
- platform: 'pc'
850
- }, {
851
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
852
- dispatch: dispatch,
853
- $$contentviewProps: contentviewProps,
854
- // selectedId: [],
855
- // listviewId: 'xxx',
856
- })
857
- ```
858
-
859
- #### close — 关闭
860
-
861
- ```javascript
862
- MKXFORM.executeOperation({
863
- code: 'close',
864
- platform: 'pc'
865
- }, {
866
- $$contentviewProps: { history: history }
867
- })
868
- ```
869
-
870
- #### print — 打印
871
-
872
- ```javascript
873
- MKXFORM.executeOperation({
874
- code: 'print',
875
- platform: 'pc'
876
- }, {
877
- baseUrl: '/current/sys-modeling/app/jspanel',
878
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
879
- docId: 'doc_xxx',
880
- // listviewId: 'xxx',
881
- // viewPageId: 'xxx',
882
- })
883
- ```
884
-
885
- #### batchPrint — 批量打印
886
-
887
- ```javascript
888
- MKXFORM.executeOperation({
889
- code: 'batchPrint',
890
- platform: 'pc'
891
- }, {
892
- baseUrl: '/current/sys-modeling/app/jspanel',
893
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
894
- selectedId: ['doc_id_1', 'doc_id_2'],
895
- // selectedDocs: [{ fd_id: 'doc_id_1', fd_xform_id: 'form_id' }],
896
- })
897
- ```
898
-
899
- #### modalDefine — 对话框
900
-
901
- ```javascript
902
- MKXFORM.executeOperation({
903
- code: 'modalDefine',
904
- name: '审批',
905
- id: 'opr_xxx',
906
- selected: true,
907
- platform: 'pc'
908
- }, {
909
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
910
- selectedId: ['doc_id_1'],
911
- refresh: function() { /* 刷新列表 */ }
912
- })
913
- ```
914
-
915
- #### other — 自定义操作
916
-
917
- ```javascript
918
- MKXFORM.executeOperation({
919
- code: 'other',
920
- uniqueCode: 'my_operation',
921
- platform: 'pc'
922
- }, {
923
- fdCode: 'template_xxx',
924
- fdOpenMode: 'self',
925
- callback: function(res) { console.log(res) },
926
- // selectedId: ['doc_id_1'], // operation.selected=true 时必传
927
- // mechanisms: [], // AI 场景使用
928
- })
929
- ```
930
-
931
- #### instanceClone — 复制新建
932
-
933
- ```javascript
934
- MKXFORM.executeOperation({
935
- code: 'instanceClone',
936
- platform: 'pc'
937
- }, {
938
- baseUrl: '/current/sys-modeling/app/jspanel',
939
- formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
940
- docId: 'doc_xxx',
941
- // fdRightGroupId: 'xxx',
942
- // fdOpenMode: 'self',
943
- // defaultTemplateData: '{}',
944
- })
945
- ```
946
-
947
- ---
948
-
949
- ### 5.13 `authOperation`
950
-
951
- **描述:** 业务操作权限校验。用于在执行操作前校验用户是否有执行业务操作的权限,参数与 `executeOperation` 基本一致。
952
-
953
- **签名:**
954
- ```typescript
955
- authOperation(operation: OperationConfig, params: ParamsConfig, callback: (error: any, res: any) => void): Promise<any>
956
- ```
957
-
958
- **参数:**
959
-
960
- | 参数 | 类型 | 说明 |
961
- |------|------|------|
962
- | `operation` | `object` | 操作按钮配置(同 `executeOperation` 的 operation 参数) |
963
- | `params` | `object` | 参数配置(同 `executeOperation` 的 params 参数) |
964
- | `callback` | `(error, res) => void` | 回调函数。参数 `error` 为错误信息;参数 `res` 为请求数据 |
965
-
966
- **回调返回值:**
967
- - 有权限:`error` 为 `null`,`res` 为 `true`
968
- - 无权限:`error` 为错误信息
969
-
970
- **注意事项:**
971
- - 分类表单的 `add` 操作:如果传了 `fdCategoryModelCode`,则 `fdCategoryTemplateId` 必须有值,否则直接 reject
972
- - 如果未传 `fdXFormId`,会通过 `fdCode` 调用接口获取表单 ID
973
- - 如果未传 `operation.id`,会通过 `uniqueCode` 调用接口获取操作 ID
974
-
975
- **使用示例:**
976
- ```javascript
977
- MKXFORM.authOperation({
978
- code: 'add',
979
- uniqueCode: 'template_p20v4f',
980
- platform: 'pc'
981
- }, {
982
- fdType: 0,
983
- baseUrl: '/current/sys-modeling/app/jspanel',
984
- fdXFormId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
985
- fdCode: 'template_9vdhbck20tjaoq3ru62xg',
986
- }, function(error, res) {
987
- console.log(error, res) // 有权限返回: null true
988
- })
989
- ```
990
-
991
- ---
992
-
993
- ## 6. 主表函数(functions)
994
-
995
- > 模块名:`function`,分组:`EApiGroup.all`
996
-
997
- ### 6.1 `$`
998
-
999
- **描述:** 根据控件 ID 获取组件实例
1000
-
1001
- **签名:**
1002
- ```typescript
1003
- $(id: string): any | null
1004
- ```
1005
-
1006
- **参数:**
1007
-
1008
- | 参数 | 类型 | 说明 |
1009
- |------|------|------|
1010
- | `id` | `string` | 控件 ID |
1011
-
1012
- **返回值:** 控件对象,未找到返回 `null`。
1013
-
1014
- **实现细节:**
1015
- - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1016
- - 调用 `$$form(MKXFORM)?.$(config.key)` 获取组件实例
1017
- - 若配置未找到则返回 `null`
1018
-
1019
- **使用示例:**
1020
- ```javascript
1021
- var control = MKXFORM.$('field_id')
1022
- if (control) {
1023
- console.log('控件对象', control)
1024
- }
1025
- ```
1026
-
1027
- ---
1028
-
1029
- ### 6.2 `setValue`
1030
-
1031
- **描述:** 根据控件 ID 设置值
1032
-
1033
- **签名:**
1034
- ```typescript
1035
- setValue(id: string, value: any): void
1036
- ```
1037
-
1038
- **参数:**
1039
-
1040
- | 参数 | 类型 | 说明 |
1041
- |------|------|------|
1042
- | `id` | `string` | 控件 ID,可在数据模型中选中,格式 `[表ID.控件ID]` |
1043
- | `value` | `any` | 要设置的值。若传入 `undefined` 则自动转为 `null` |
1044
-
1045
- **实现细节:**
1046
- - 调用 `$setValue({ form, value: { [id]: v } })` 设置表单值
1047
- - **明细表/业务内置字段特殊处理**(当 `id` 包含 `.` 时,如 `tableId.fieldId`):
1048
- - 创建内部对象 `tmpVal`,包含方法:`getKeyValue()`、`getValue()`、`getFullFdName()`、`getFdName()`、`getKey()`、`getTableType()`
1049
- - 存储到 `MKXFORM.businessFieldsValue[id] = tmpVal`
1050
- - 触发事件 `mk.emit(EXFromRuntimeDataChange.ExternalFieldsChange, tmpVal)`
1051
- - 仅数据模型中存在的字段且 key 存在时才存储
1052
- - **不支持的控件类型:** 明细表、二维码、关联流程、按钮、多表头、文本说明、样例模板、多标签、自定义界面、内嵌页、审批、附件、视频、图片、附件类等
1053
-
1054
- **使用示例:**
1055
- ```javascript
1056
- // 设置普通字段
1057
- MKXFORM.setValue('field_id', '新值')
1058
-
1059
- // 设置业务内置字段(会存储到 businessFieldsValue 并触发 ExternalFieldsChange)
1060
- MKXFORM.setValue('tableId.fieldId', '表格字段值')
1061
- ```
1062
-
1063
- ---
1064
-
1065
- ### 6.3 `getValue`
1066
-
1067
- **描述:** 根据控件 ID 获取值
1068
-
1069
- **签名:**
1070
- ```typescript
1071
- getValue(id: string): any
1072
- ```
1073
-
1074
- **参数:**
1075
-
1076
- | 参数 | 类型 | 说明 |
1077
- |------|------|------|
1078
- | `id` | `string` | 控件 ID |
1079
-
1080
- **返回值:** 控件当前值。**附件类型特殊处理:** 当控件为 `@elem/xform-attach` 或 `@elem/xform-m-attach` 时,若结果为字符串则返回 `undefined`(表示空状态),否则返回数组格式。
1081
-
1082
- **不支持的控件类型:** 前端计算、图片、附件、滑块、明细表、多表头、文本描述、模板、多标签页、业务关联、自定义页面、二维码、审批、关联流程、iframe、按钮。
1083
-
1084
- **使用示例:**
1085
- ```javascript
1086
- var value = MKXFORM.getValue('field_id')
1087
- console.log('当前值', value)
1088
- ```
1089
-
1090
- ---
1091
-
1092
- ### 6.4 `setStyle`
1093
-
1094
- **描述:** 根据控件 ID 设置样式
1095
-
1096
- **签名:**
1097
- ```typescript
1098
- setStyle(id: string, style: React.CSSProperties, type: 'label' | 'content'): void
1099
- ```
1100
-
1101
- **参数:**
1102
-
1103
- | 参数 | 类型 | 说明 |
1104
- |------|------|------|
1105
- | `id` | `string` | 控件 ID |
1106
- | `style` | `React.CSSProperties` | CSS 样式对象 |
1107
- | `type` | `'label' \| 'content'` | `label` = 设置标签样式(`labelStyle` 属性);`content` = 设置内容区域样式(`controlValueStyle` 属性) |
1108
-
1109
- **实现细节:**
1110
- - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1111
- - `type='label'` 时调用 `$$form(MKXFORM).updateFormItemProps(config.key, { labelStyle: style })`
1112
- - `type='content'` 时调用 `$$form(MKXFORM).updateFormItemProps(config.key, { controlValueStyle: style })`
1113
- - `type` 无效时打印 `console.error` 错误日志
1114
-
1115
- **使用示例:**
1116
- ```javascript
1117
- // 设置标签样式(红色加粗)
1118
- MKXFORM.setStyle('field_id', { color: 'red', fontWeight: 'bold' }, 'label')
1119
-
1120
- // 设置内容区域样式
1121
- MKXFORM.setStyle('field_id', { backgroundColor: '#f0f0f0' }, 'content')
1122
- ```
1123
-
1124
- ---
1125
-
1126
- ### 6.5 `setProps`
1127
-
1128
- **描述:** 根据控件 ID 设置属性
1129
-
1130
- **签名:**
1131
- ```typescript
1132
- setProps(id: string, props: Record<string, any>): void
1133
- ```
1134
-
1135
- **参数:**
1136
-
1137
- | 参数 | 类型 | 说明 |
1138
- |------|------|------|
1139
- | `id` | `string` | 控件 ID |
1140
- | `props` | `Record<string, any>` | 要设置的属性键值对,支持以下所有属性 |
1141
-
1142
- **实现细节:**
1143
- - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1144
- - 调用 `$$form(MKXFORM)?.updateFormItemProps(config.key, props)` 更新控件属性
1145
- - 支持设置任意控件属性,底层通过 FIBRE 架构合并到 `item.props`
1146
- - 若设置 `value` 属性,会通过 `item.props.onChange(value, 'code')` 触发表单机制修改,而非直接赋值
1147
- - 若设置 `onBlur` 事件,会特殊处理以避免覆盖内部 blur 逻辑
1148
- - 若设置 `labelProps` 嵌套对象,会同步更新控件标签属性
1149
- - 修改会同步到简易配置(`flatSimpleFormConfig`)中
1150
-
1151
- **支持的属性清单:**
1152
-
1153
- #### 控件属性 (Control Props)
1154
-
1155
- | 属性名 | 类型 | 说明 |
1156
- |--------|------|------|
1157
- | `value` | `any` | 控件值(通过 onChange 机制触发更新) |
1158
- | `hidden` | `boolean` | 控件隐藏/显示 |
1159
- | `_hidden` | `boolean` | 内部隐藏标记 |
1160
- | `showStatus` | `'edit' \| 'readOnly' \| 'view' \| 'print'` | 控件状态(编辑/只读/查看/打印) |
1161
- | `disabled` | `boolean` | 禁用配置区表单项 |
1162
- | `parentHidden` | `boolean` | 父级控件隐藏状态通知子级 |
1163
- | `trace` | `any` | 追踪信息 |
1164
- | `traceData` | `any` | 追踪数据 |
1165
- | `dependenciesValue` | `object` | 依赖项的值 |
1166
- | `title` | `string` | 控件标题 |
1167
- | `controlValueStyle` | `CSSProperties` | 控件内容区域样式 |
1168
- | `updateTimer` | `string` | 触发 tab 子项重新渲染的标记 |
1169
- | `__force_update__` | `number` | 强制更新计数器 |
1170
-
1171
- #### 标签属性 (Label Props) — 嵌套在 `labelProps` 对象内
1172
-
1173
- | 属性名 | 类型 | 说明 |
1174
- |--------|------|------|
1175
- | `labelProps.hidden` | `boolean` | 标签隐藏/显示 |
1176
- | `labelProps.required` | `boolean` | 标签必填标记(红色星号) |
1177
- | `labelProps.labelStyle` | `CSSProperties` | 标签样式 |
1178
- | `labelProps.labelSuffix` | `ReactNode` | 标签后缀内容 |
1179
- | `labelProps.title` | `string` | 标签标题文本 |
1180
-
1181
- #### 明细表属性 (Detail Table Props)
1182
-
1183
- | 属性名 | 类型 | 说明 |
1184
- |--------|------|------|
1185
- | `hiddenNames` | `string[] \| undefined` | 指定隐藏的明细字段名列表 |
1186
- | `modifyNames` | `string[]` | 已修改的明细字段名列表 |
1187
- | `requireNames` | `Array<{name, required, tip}>` | 明细表字段必填规则 |
1188
- | `rowNumStyles` | `object` | 按行号设置明细控件样式 |
1189
- | `canDeleteRow` | `boolean` | 明细行是否可删除 |
1190
- | `canDeleteRowObj` | `{rowNum, canDeleteRow}` | 指定行号的可删除状态 |
1191
- | `rowValue` | `{rowNum, value}` | 明细表行数据联动更新 |
1192
- | `columns` | `array` | 明细表列定义配置 |
1193
-
1194
- #### 布局属性 (Layout Props)
1195
-
1196
- | 属性名 | 类型 | 说明 |
1197
- |--------|------|------|
1198
- | `spans` | `number[]` | 布局列宽分配数组(24 栅格) |
1199
- | `column` | `number` | 布局列数 |
1200
- | `columnSpan` | `number` | 列跨度 |
1201
- | `columns` | `array` | 列配置数组 |
1202
- | `layout` | `string` | 布局模式 |
1203
- | `desktopPaddingMode` | `'standard' \| ...` | 桌面端内边距模式 |
1204
-
1205
- #### 校验属性 (Validation Props)
1206
-
1207
- | 属性名 | 类型 | 说明 |
1208
- |--------|------|------|
1209
- | `errors` | `IError[]` | 校验错误信息列表 |
1210
- | `error` | `IError` | 单个校验错误 |
1211
- | `force` | `number` | 强制校验触发标记(通常传随机数) |
1212
-
1213
- #### 样式属性 (Style Props)
1214
-
1215
- | 属性名 | 类型 | 说明 |
1216
- |--------|------|------|
1217
- | `style` | `CSSProperties` | 控件样式对象 |
1218
- | `controlValueStyle` | `CSSProperties` | 控件值区域样式 |
1219
- | `rowNumStyles` | `object` | 明细表按行号样式 |
1220
- | `tabTitleStyle` | `CSSProperties` | Tab 标题样式 |
1221
- | `tabBarStyle` | `CSSProperties` | Tab 栏样式 |
1222
- | `controlTitleStyle` | `CSSProperties` | Steps/控件标题样式 |
1223
-
1224
- #### Tab/Steps/Collapse 专用属性
1225
-
1226
- | 属性名 | 类型 | 说明 |
1227
- |--------|------|------|
1228
- | `tabTitleStyle` | `CSSProperties` | Tab 标题样式 |
1229
- | `tabBarStyle` | `CSSProperties` | Tab 栏样式 |
1230
- | `controlTitleStyle` | `CSSProperties` | Steps 标题样式 |
1231
- | `visible` | `boolean` | Collapse 可见性 |
1232
-
1233
- **使用示例:**
1234
- ```javascript
1235
- // 设置普通属性
1236
- MKXFORM.setProps('field_id', { placeholder: '请输入', maxLength: 100, disabled: true })
1237
-
1238
- // 设置标签属性
1239
- MKXFORM.setProps('field_id', {
1240
- labelProps: {
1241
- hidden: false,
1242
- required: true,
1243
- labelStyle: { color: 'red' }
1244
- }
1245
- })
1246
-
1247
- // 设置样式
1248
- MKXFORM.setProps('field_id', {
1249
- style: { backgroundColor: '#f0f0f0' },
1250
- controlValueStyle: { fontSize: '14px' }
1251
- })
1252
-
1253
- // 设置布局
1254
- MKXFORM.setProps('field_id', { spans: [12, 12] })
1255
-
1256
- // 设置明细表属性
1257
- MKXFORM.setProps('detailTable', {
1258
- canDeleteRow: false,
1259
- hiddenNames: ['internalField1', 'internalField2']
1260
- })
1261
- ```
1262
- ---
1263
-
1264
- ### 6.6 `getFieldAttr`
1265
-
1266
- **描述:** 获取字段当前的只读/必填/隐藏等显示属性
1267
-
1268
- **签名:**
1269
- ```typescript
1270
- getFieldAttr(id: string): number
1271
- ```
1272
-
1273
- **参数:**
1274
-
1275
- | 参数 | 类型 | 说明 |
1276
- |------|------|------|
1277
- | `id` | `string` | 控件 ID |
1278
-
1279
- **返回值:**
1280
-
1281
- | 返回值 | 含义 | 判断逻辑 |
1282
- |--------|------|----------|
1283
- | `1` | 只读(readOnly) | `showStatus` 为只读 |
1284
- | `2` | 可编辑(editable) | 非只读且非必填 |
1285
- | `3` | 必填(required) | `validateRules` 存在必填规则或 `required/require` 为 true |
1286
- | `4` | 隐藏(hidden) | `showStatus` 为隐藏或 `labelProps.hidden` 为 true |
1287
-
1288
- **实现细节:**
1289
- - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1290
- - 检查优先级:隐藏 → 只读 → 必填 → 可编辑
1291
-
1292
- **使用示例:**
1293
- ```javascript
1294
- var attr = MKXFORM.getFieldAttr('field_id')
1295
- if (attr === 1) {
1296
- console.log('该字段当前为只读')
1297
- } else if (attr === 3) {
1298
- console.log('该字段当前为必填')
1299
- }
1300
- ```
1301
-
1302
- ---
1303
-
1304
- ### 6.7 `setFieldAttr`
1305
-
1306
- **描述:** 改变单个字段的显示属性(只读/必填/隐藏等)
1307
-
1308
- **签名:**
1309
- ```typescript
1310
- setFieldAttr(id: string, value: number): void
1311
- ```
1312
-
1313
- **参数:**
1314
-
1315
- | 参数 | 类型 | 说明 |
1316
- |------|------|------|
1317
- | `id` | `string` | 控件 ID |
1318
- | `value` | `number` | 属性值(见下表) |
1319
-
1320
- **value 取值:**
1321
-
1322
- | 值 | 含义 | 实现逻辑 |
1323
- | --- | ----- | -------------------------------------------------------------------- |
1324
- | `1` | 设为只读 | 设置 `showStatus` 为 readOnly。若 `extraAuth.required === false`,则覆盖校验为通过 |
1325
- | `2` | 设为可编辑 | 设置 `showStatus` 为 editable。通过 `view2edit` 辅助函数检查是否可从只读转为编辑 |
1326
- | `3` | 设为必填 | 先设为可编辑,再添加必填规则。兼容 `required` 和 `require` 两种属性名 |
1327
- | `4` | 隐藏 | 隐藏字段标签及内容 |
1328
- | `5` | 显示 | 取消隐藏,恢复字段可见性 |
1329
- | `6` | 设为非必填 | 移除 `required` 和 `require` 标记,清除必填校验规则 |
1330
- | | | |
1331
-
1332
- **实现细节:**
1333
- - 使用 `cloneDeep` 深拷贝规则对象,避免直接修改原始引用
1334
- - 所有更新通过 `$$form(MKXFORM).updateFormItemProps(config.key, { ... })` 应用
1335
- - 传入 `{ withoutValidate: true }` 标志,跳过额外校验
1336
- - `value` 不在 `[1,2,3,4,5,6]` 范围内时抛出异常
1337
- - `view2edit(showStatus, editable)` 辅助函数检查是否允许从只读转为编辑
1338
-
1339
- **使用示例:**
1340
- ```javascript
1341
- // 设为只读
1342
- MKXFORM.setFieldAttr('field_id', 1)
1343
-
1344
- // 设为必填
1345
- MKXFORM.setFieldAttr('field_id', 3)
1346
-
1347
- // 隐藏字段
1348
- MKXFORM.setFieldAttr('field_id', 4)
1349
-
1350
- // 取消隐藏
1351
- MKXFORM.setFieldAttr('field_id', 5)
1352
-
1353
- // 设为非必填
1354
- MKXFORM.setFieldAttr('field_id', 6)
1355
- ```
1356
-
1357
- ---
1358
-
1359
- ### 6.8 `getValueText`
1360
-
1361
- **描述:** 根据控件 ID 获取显示文本(而非原始值),如下拉框返回选项文本而非值
1362
-
1363
- **签名:**
1364
- ```typescript
1365
- getValueText(id: string): string
1366
- ```
1367
-
1368
- **参数:**
1369
-
1370
- | 参数 | 类型 | 说明 |
1371
- |------|------|------|
1372
- | `id` | `string` | 控件 ID |
1373
-
1374
- **返回值:** 控件的显示文本字符串。
1375
-
1376
- **实现细节:**
1377
- - 将 `id` 按 `.` 分割,取第二部分(`ids[1]`)作为控件名
1378
- - 通过 `$$controlRef(MKXFORM)?.[ids[1]]?.current?.getValueText(id)` 获取显示文本
1379
- - 若控件引用不存在则返回 `undefined`
1380
-
1381
- **使用示例:**
1382
- ```javascript
1383
- var displayText = MKXFORM.getValueText('field_id')
1384
- console.log('显示文本', displayText) // 如下拉框显示 "选项一" 而非 "value1"
1385
- ```
1386
-
1387
- ---
1388
-
1389
- ### 6.9 `getControlHtml`
1390
-
1391
- **描述:** 获取控件带样式的 HTML 字符串
1392
-
1393
- **签名:**
1394
- ```typescript
1395
- getControlHtml(id: string): string
1396
- ```
1397
-
1398
- **参数:**
1399
-
1400
- | 参数 | 类型 | 说明 |
1401
- |------|------|------|
1402
- | `id` | `string` | 控件 ID |
1403
-
1404
- **返回值:** 包含内联样式的 HTML 字符串。
1405
-
1406
- **实现细节:**
1407
- 1. 通过 `document.querySelector` 查找控件 DOM 节点(优先使用 `uuid`,降级使用 `currentId`)
1408
- 2. 深拷贝 DOM 节点(`cloneNode(true)`)
1409
- 3. 临时追加到 `document.body`
1410
- 4. 调用 `formatHmtl(id)` 格式化:
1411
- - 递归将计算样式转为内联样式(`inlineStyles`)
1412
- - 特殊处理审批控件(`@elem/xform-review`):移除展开/收起按钮、操作包裹、附件背景等
1413
- - 清理附件额外信息节点
1414
- - 将批注内容转为带对齐方式的 span 元素
1415
- 5. 提取 `innerHTML`
1416
- 6. 100ms 后移除克隆节点
1417
-
1418
- **使用示例:**
1419
- ```javascript
1420
- var html = MKXFORM.getControlHtml('field_id')
1421
- console.log('控件HTML', html)
1422
- ```
1423
-
1424
- ---
1425
-
1426
- ## 7. 明细表函数(details)
1427
-
1428
- > 模块名:`detail`,分组:`EApiGroup.all`
1429
- >
1430
- > 明细表函数中的 `id` 参数通常使用 `tableId.controlId` 格式表示明细表中的某个字段。
1431
-
1432
- ### 7.1 `getControlValue`
1433
-
1434
- **描述:** 获取明细表指定行的指定控件值
1435
-
1436
- **签名:**
1437
- ```typescript
1438
- getControlValue(id: string, rowNum: number): any
1439
- ```
1440
-
1441
- **参数:**
1442
-
1443
- | 参数 | 类型 | 说明 |
1444
- |------|------|------|
1445
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId`。按 `.` 分割,第一部分为明细表 ID |
1446
- | `rowNum` | `number` | 行号(从 0 开始) |
1447
-
1448
- **实现细节:**
1449
- - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1450
- - 调用 `$$detailForms(MKXFORM)?.[key].current?.getCurrentValues()[rowNum][id]`
1451
- - 若明细表不存在或行号越界,返回 `undefined`
1452
-
1453
- **使用示例:**
1454
- ```javascript
1455
- var value = MKXFORM.getControlValue('detailTable.amount', 0)
1456
- console.log('第一行的金额', value)
1457
- ```
1458
-
1459
- ---
1460
-
1461
- ### 7.2 `updateControl`
1462
-
1463
- **描述:** 更新明细表指定行的指定控件值
1464
-
1465
- **签名:**
1466
- ```typescript
1467
- updateControl(id: string, rowNum: number, value: any): void
1468
- ```
1469
-
1470
- **参数:**
1471
-
1472
- | 参数 | 类型 | 说明 |
1473
- |------|------|------|
1474
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1475
- | `rowNum` | `number` | 行号(从 0 开始) |
1476
- | `value` | `any` | 要设置的值 |
1477
-
1478
- **实现细节:**
1479
- - **防抖批量更新机制:** 使用 `window['MXFORM_updateControl']` 作为缓存对象,100ms `setTimeout` 延迟执行
1480
- - 多次调用会累积到同一个更新批次中
1481
- - 执行时:克隆当前行数据 → 合并新值 → 调用 `detailRef.setTinyValues()` → 调用 `detailRef.updateValues()`
1482
- - 执行完成后 300ms 清空 `tinyValues` 缓存,并重置缓存对象
1483
- - 若 ID 信息缺失,打印 `console.error` 错误日志
1484
-
1485
- **使用示例:**
1486
- ```javascript
1487
- // 以下两次调用会合并为一个批量更新
1488
- MKXFORM.updateControl('detailTable.amount', 0, 1000)
1489
- MKXFORM.updateControl('detailTable.name', 0, '张三')
1490
- ```
1491
-
1492
- ---
1493
-
1494
- ### 7.3 `updateControlStyle`
1495
-
1496
- **描述:** 更新明细表指定行的指定控件样式
1497
-
1498
- **签名:**
1499
- ```typescript
1500
- updateControlStyle(id: string, rowNum: number, style: React.CSSProperties): void
1501
- ```
1502
-
1503
- **参数:**
1504
-
1505
- | 参数 | 类型 | 说明 |
1506
- |------|------|------|
1507
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1508
- | `rowNum` | `number` | 行号(从 0 开始) |
1509
- | `style` | `React.CSSProperties` | CSS 样式对象 |
1510
-
1511
- **实现细节:**
1512
- - **防抖批量更新机制:** 使用 `window['MXFORM_updateControlStyles']` 作为缓存对象,100ms `setTimeout` 延迟执行
1513
- - 调用 `$$form(MKXFORM)?.updateFormItemProps(config.key, { rowNumStyles: tables })` 应用样式
1514
- - 仅支持 PC 端
1515
- - 仅支持只读控件:单行文本、多行文本、日期、通讯录、金额、数字、单选、复选、下拉、多选、滑块、开关
1516
-
1517
- **使用示例:**
1518
- ```javascript
1519
- MKXFORM.updateControlStyle('detailTable.amount', 0, { color: 'red', fontWeight: 'bold' })
1520
- ```
1521
-
1522
- ---
1523
-
1524
- ### 7.4 `addRow`
1525
-
1526
- **描述:** 新增明细表行
1527
-
1528
- **签名:**
1529
- ```typescript
1530
- addRow(id: string, rowValue?: Record<string, any> | Record<string, any>[]): void
1531
- ```
1532
-
1533
- **参数:**
1534
-
1535
- | 参数 | 类型 | 说明 |
1536
- |------|------|------|
1537
- | `id` | `string` | 明细表 ID |
1538
- | `rowValue`(可选) | `object \| object[]` | 行数据。对象为单行,数组为多行。不传默认添加一行空行 `[{}]` |
1539
-
1540
- **实现细节:**
1541
- - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1542
- - 获取当前值 `detailRef.getCurrentValues()`
1543
- - 若 `rowValue` 为数组,遍历 `push` 所有项
1544
- - 若 `rowValue` 为对象,`push` 单个对象
1545
- - 若未传 `rowValue`,默认添加 `[{}]`(一行空行)
1546
- - 最后调用 `detailRef.updateValues(newValues)`
1547
-
1548
- **使用示例:**
1549
- ```javascript
1550
- // 添加一行空行
1551
- MKXFORM.addRow('detailTable')
1552
-
1553
- // 添加一行带数据
1554
- MKXFORM.addRow('detailTable', { name: '张三', amount: 100 })
1555
-
1556
- // 批量添加多行
1557
- MKXFORM.addRow('detailTable', [
1558
- { name: '张三', amount: 100 },
1559
- { name: '李四', amount: 200 }
1560
- ])
1561
- ```
1562
-
1563
- ---
1564
-
1565
- ### 7.5 `updateRow`
1566
-
1567
- **描述:** 更新明细表指定行数据
1568
-
1569
- **签名:**
1570
- ```typescript
1571
- updateRow(id: string, rowNum: number, rowValue: Record<string, any> | Record<string, any>[]): void
1572
- ```
1573
-
1574
- **参数:**
1575
-
1576
- | 参数 | 类型 | 说明 |
1577
- |------|------|------|
1578
- | `id` | `string` | 明细表 ID |
1579
- | `rowNum` | `number` | 起始行号(从 0 开始) |
1580
- | `rowValue` | `object \| object[]` | 若为对象则通过 `Object.assign` 合并到指定行;若为数组则从 `rowNum` 开始逐个替换多行 |
1581
-
1582
- **实现细节:**
1583
- - `rowValue` 为数组时:从 `rowNum` 开始,用 `Object.assign` 逐个替换后续行
1584
- - `rowValue` 为对象时:用 `Object.assign(values[rowNum], rowValue)` 合并到指定行
1585
- - 最后调用 `detailRef.updateValues(values)`
1586
-
1587
- **使用示例:**
1588
- ```javascript
1589
- // 更新单行(合并属性)
1590
- MKXFORM.updateRow('detailTable', 0, { amount: 500 })
1591
-
1592
- // 替换多行(从第 0 行开始替换为以下两行)
1593
- MKXFORM.updateRow('detailTable', 0, [
1594
- { name: '王五', amount: 300 },
1595
- { name: '赵六', amount: 400 }
1596
- ])
1597
- ```
1598
-
1599
- ---
1600
-
1601
- ### 7.6 `deleteRow`
1602
-
1603
- **描述:** 删除明细表行
1604
-
1605
- **签名:**
1606
- ```typescript
1607
- deleteRow(id: string, rowNum?: number | number[] | ''): void
1608
- ```
1609
-
1610
- **参数:**
1611
-
1612
- | 参数 | 类型 | 说明 |
1613
- |------|------|------|
1614
- | `id` | `string` | 明细表 ID |
1615
- | `rowNum` | `number \| number[] \| ''`(可选) | 删除方式(见下表) |
1616
-
1617
- **rowNum 取值:**
1618
-
1619
- | 值 | 说明 | 实现逻辑 |
1620
- |----|------|----------|
1621
- | 省略 | 删除所有行 | 调用 `detailRef.deleteAll()` |
1622
- | `''` | 删除所有行 | 调用 `detailRef.deleteAll()` |
1623
- | `number` | 删除指定行号的一行 | 获取该行值,调用 `detailRef.deleteRow(values, deleteIds, deleteValues)` |
1624
- | `number[]` | 删除多个指定行号(如 `[0, 2, 4]`) | 遍历收集 `deleteIds` 和 `deleteValues`,调用 `detailRef.deleteRow()` |
1625
-
1626
- **实现细节:**
1627
- - 删除时同时收集被删除行的 ID(`deleteIds`)和值(`deleteValues`)传给底层方法
1628
-
1629
- **使用示例:**
1630
- ```javascript
1631
- // 删除第 2 行
1632
- MKXFORM.deleteRow('detailTable', 1)
1633
-
1634
- // 删除第 1、3、5 行
1635
- MKXFORM.deleteRow('detailTable', [0, 2, 4])
1636
-
1637
- // 删除所有行
1638
- MKXFORM.deleteRow('detailTable')
1639
- MKXFORM.deleteRow('detailTable', '')
1640
- ```
1641
-
1642
- ---
1643
-
1644
- ### 7.7 `getRowCount`
1645
-
1646
- **描述:** 获取明细表总行数
1647
-
1648
- **签名:**
1649
- ```typescript
1650
- getRowCount(id: string): number
1651
- ```
1652
-
1653
- **参数:**
1654
-
1655
- | 参数 | 类型 | 说明 |
1656
- |------|------|------|
1657
- | `id` | `string` | 明细表 ID |
1658
-
1659
- **返回值:** 明细表总行数。
1660
-
1661
- **注意:** 不能在表单 `onLoad` 中调用(此时明细表可能尚未初始化)。
1662
-
1663
- **实现细节:**
1664
- - 调用 `detailRef.getDataLength()`
1665
-
1666
- **使用示例:**
1667
- ```javascript
1668
- var count = MKXFORM.getRowCount('detailTable')
1669
- console.log('明细表共有 ' + count + ' 行')
1670
- ```
1671
-
1672
- ---
1673
-
1674
- ### 7.8 `getSelectedRowIndex`
1675
-
1676
- **描述:** 获取明细表选中行的下标数组
1677
-
1678
- **签名:**
1679
- ```typescript
1680
- getSelectedRowIndex(id: string): number[]
1681
- ```
1682
-
1683
- **参数:**
1684
-
1685
- | 参数 | 类型 | 说明 |
1686
- |------|------|------|
1687
- | `id` | `string` | 明细表 ID |
1688
-
1689
- **返回值:** 选中行下标数组(如 `[0, 2, 5]`)。
1690
-
1691
- **使用示例:**
1692
- ```javascript
1693
- var selectedRows = MKXFORM.getSelectedRowIndex('detailTable')
1694
- console.log('选中行', selectedRows)
1695
- ```
1696
-
1697
- ---
1698
-
1699
- ### 7.9 `checkDetailRow`
1700
-
1701
- **描述:** 选中明细表指定行
1702
-
1703
- **签名:**
1704
- ```typescript
1705
- checkDetailRow(id: string, indexArr: number[]): void
1706
- ```
1707
-
1708
- **参数:**
1709
-
1710
- | 参数 | 类型 | 说明 |
1711
- |------|------|------|
1712
- | `id` | `string` | 明细表 ID |
1713
- | `indexArr` | `number[]` | 要选中的行号数组 |
1714
-
1715
- **注意:** 不支持移动端。
1716
-
1717
- **使用示例:**
1718
- ```javascript
1719
- // 选中第 1、3 行
1720
- MKXFORM.checkDetailRow('detailTable', [0, 2])
1721
- ```
1722
-
1723
- ---
1724
-
1725
- ### 7.10 `controlDetailRowCanDelete`
1726
-
1727
- **描述:** 控制明细行是否可删除
1728
-
1729
- **签名:**
1730
- ```typescript
1731
- controlDetailRowCanDelete(id: string, canDeleteRow: boolean, rowNum?: number | number[]): void
1732
- ```
1733
-
1734
- **参数:**
1735
-
1736
- | 参数 | 类型 | 说明 |
1737
- |------|------|------|
1738
- | `id` | `string` | 明细表 ID |
1739
- | `canDeleteRow` | `boolean` | 是否允许删除 |
1740
- | `rowNum`(可选) | `number \| number[]` | 指定行号。省略则对整个明细表生效 |
1741
-
1742
- **注意:** 仅支持 PC 端。
1743
-
1744
- **使用示例:**
1745
- ```javascript
1746
- // 禁用整个明细表的删除
1747
- MKXFORM.controlDetailRowCanDelete('detailTable', false)
1748
-
1749
- // 仅禁用第 2 行的删除
1750
- MKXFORM.controlDetailRowCanDelete('detailTable', false, 1)
1751
-
1752
- // 禁用第 1、3 行的删除
1753
- MKXFORM.controlDetailRowCanDelete('detailTable', false, [0, 2])
1754
-
1755
- // 启用整个明细表的删除
1756
- MKXFORM.controlDetailRowCanDelete('detailTable', true)
1757
- ```
1758
-
1759
- ---
1760
-
1761
- ### 7.11 `cacluColumnValue`
1762
-
1763
- **描述:** 计算明细表某列的最大值、最小值和平均值
1764
-
1765
- **签名:**
1766
- ```typescript
1767
- cacluColumnValue(id: string): { max: number, min: number, average: number }
1768
- ```
1769
-
1770
- **参数:**
1771
-
1772
- | 参数 | 类型 | 说明 |
1773
- |------|------|------|
1774
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1775
-
1776
- **返回值:**
1777
-
1778
- | 字段 | 类型 | 说明 |
1779
- |------|------|------|
1780
- | `max` | `number` | 列最大值 |
1781
- | `min` | `number` | 列最小值 |
1782
- | `average` | `number` | 列平均值 |
1783
-
1784
- **实现细节:**
1785
- - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1786
- - 调用 `detailRef.getCurrentValues()` 获取所有行数据
1787
- - 提取指定列的所有值,过滤空值后计算 `Math.max`、`Math.min` 和平均值
1788
- - 无数据或列不存在时打印 `console.error` 并返回 `{ max: 0, min: 0, average: 0 }`
1789
-
1790
- **使用示例:**
1791
- ```javascript
1792
- var result = MKXFORM.cacluColumnValue('detailTable.amount')
1793
- console.log('最大值', result.max)
1794
- console.log('最小值', result.min)
1795
- console.log('平均值', result.average)
1796
- ```
1797
-
1798
- ---
1799
-
1800
- ### 7.12 `getPageControlValue`
1801
-
1802
- **描述:** 获取当前分页中指定行的指定控件值
1803
-
1804
- **签名:**
1805
- ```typescript
1806
- getPageControlValue(id: string, rowNum: number): any
1807
- ```
1808
-
1809
- **参数:**
1810
-
1811
- | 参数 | 类型 | 说明 |
1812
- | -------- | -------- | ----------------------------- |
1813
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1814
- | `rowNum` | `number` | 当前分页内的行号(从 0 开始) |
1815
-
1816
- **注意:** 仅支持 PC 端。与 `getControlValue` 的区别在于使用 `getPageCurrentValues()` 而非 `getCurrentValues()`,仅获取当前分页的数据。
1817
-
1818
- **使用示例:**
1819
- ```javascript
1820
- var value = MKXFORM.getPageControlValue('detailTable.amount', 0)
1821
- ```
1822
-
1823
- ---
1824
-
1825
- ### 7.13 `setDetailFieldAttr`
1826
-
1827
- **描述:** 改变明细表单个字段列的显示属性(只读/必填/隐藏等)
1828
-
1829
- **签名:**
1830
- ```typescript
1831
- setDetailFieldAttr(id: string, value: number): void
1832
- ```
1833
-
1834
- **参数:**
1835
-
1836
- | 参数 | 类型 | 说明 |
1837
- | ------- | -------- | ----------------------------- |
1838
- | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1839
- | `value` | `number` | 属性值(见下表) |
1840
-
1841
- **value 取值:**
1842
-
1843
- | 值 | 含义 |
1844
- | --- | ---------------------- |
1845
- | `1` | 设为只读 |
1846
- | `2` | 设为可编辑(遵循 view2edit 规则) |
1847
- | `3` | 设为必填 |
1848
- | `4` | 隐藏(标签和内容) |
1849
- | `5` | 显示(取消隐藏) |
1850
- | `6` | 设为非必填 |
1851
-
1852
- **实现细节:**
1853
- - 使用 `cloneDeep` 深拷贝明细表字段的 `columns` 配置对象,避免直接修改原始引用
1854
- - 通过 `getKeyByName(id, MKXFORM)` 解析 ID,获取明细表 key 和字段名
1855
- - 在明细表的 `columns` 数组中查找目标列
1856
- - 通过 `$$form(MKXFORM).updateFormItemProps(key, { columns: newColumns })` 应用更新
1857
- - `value` 不在 `[1,2,3,4,5,6]` 范围内时抛出异常
1858
- - ID 格式无效(不含 `.`)时打印 `console.error` 并返回
1859
- - 使用与 `setFieldAttr` 相同的 `view2edit` 辅助函数检查是否可从只读转为编辑
1860
-
1861
- **使用示例:**
1862
- ```javascript
1863
- // 将明细表金额列设为只读
1864
- MKXFORM.setDetailFieldAttr('detailTable.amount', 1)
1865
-
1866
- // 将明细表金额列设为必填
1867
- MKXFORM.setDetailFieldAttr('detailTable.amount', 3)
1868
- ```
1869
-
1870
- ---
1871
-
1872
- ### 7.14 `setDetailRowAttr`
1873
-
1874
- **描述:** 改变明细表指定行的显示属性
1875
-
1876
- **签名:**
1877
- ```typescript
1878
- setDetailRowAttr(id: string, value: number, rowNum: number, fieldId?: string): void
1879
- ```
1880
-
1881
- **参数:**
1882
-
1883
- | 参数 | 类型 | 说明 |
1884
- | ------------- | -------- | ---------------------------------------- |
1885
- | `id` | `string` | 明细表 ID |
1886
- | `value` | `number` | 属性值(1~6,同 `setFieldAttr`) |
1887
- | `rowNum` | `number` | 行号(从 0 开始) |
1888
- | `fieldId`(可选) | `string` | 指定字段 ID。省略则对整行生效,格式为 `tableId.controlId` |
1889
-
1890
- **value 取值:** 同 `setFieldAttr`(1=只读, 2=可编辑, 3=必填, 4=隐藏, 5=显示, 6=非必填)
1891
-
1892
- **实现细节:**
1893
- - 委托给 `detailRef?.setRowAttr(value, rowNum, fieldId)` 执行
1894
- - `value` 不在 1~6 范围内时抛出异常
1895
- - `rowNum` 无效时打印 `console.error` 并返回
1896
-
1897
- **使用示例:**
1898
- ```javascript
1899
- // 第 2 行整行设为只读
1900
- MKXFORM.setDetailRowAttr('detailTable', 1, 1)
1901
-
1902
- // 第 2 行的金额列设为必填
1903
- MKXFORM.setDetailRowAttr('detailTable', 3, 1, 'detailTable.amount')
1904
- ```
1905
-
1906
- ---
1907
-
1908
- ### 7.15 `setDetailFieldItemAttr`
1909
-
1910
- **描述:** 改变明细表指定行指定字段的显示属性
1911
-
1912
- **签名:**
1913
- ```typescript
1914
- setDetailFieldItemAttr(id: string, value: number, rowKey: number, fieldId?: string): void
1915
- ```
1916
-
1917
- **参数:**
1918
-
1919
- | 参数 | 类型 | 说明 |
1920
- | ------------- | -------- | -------------------------------------- |
1921
- | `id` | `string` | 明细表 ID |
1922
- | `value` | `number` | 属性值(1~6) |
1923
- | `rowKey` | `number` | 行 key |
1924
- | `fieldId`(可选) | `string` | 字段 ID。省略则对整行生效,格式为 `tableId.controlId` |
1925
-
1926
- **value 取值:** 同 `setFieldAttr`(1~6)。
1927
-
1928
- **实现细节:**
1929
- - 使用 `getKeyByName` 而非 `getConfig` 来获取明细表 key
1930
- - 委托给 `detailRef.setRowAttr(value, rowKey, fieldId)` 执行
1931
- - 与 `setDetailRowAttr` 的区别在于使用 `rowKey`(行的唯一 key)而非 `rowNum`(行号)
1932
-
1933
- **使用示例:**
1934
- ```javascript
1935
- // 第 2 行金额列设为只读
1936
- MKXFORM.setDetailFieldItemAttr('detailTable', 1, 1, 'detailTable.amount')
1937
-
1938
- // 第 2 行整行设为必填
1939
- MKXFORM.setDetailFieldItemAttr('detailTable', 3, 1)
1940
- ```
1941
-
1942
- ---
1943
-
1944
- ### 7.16 `reload`
1945
-
1946
- **描述:** 重新加载明细表数据
1947
-
1948
- **签名:**
1949
- ```typescript
1950
- reload(id: string): void
1951
- ```
1952
-
1953
- **参数:**
1954
-
1955
- | 参数 | 类型 | 说明 |
1956
- |------|------|------|
1957
- | `id` | `string` | 明细表 ID |
1958
-
1959
- **注意:** 不支持移动端。
1960
-
1961
- **实现细节:**
1962
- - 直接委托给 `detailRef?.reload()` 执行
1963
-
1964
- **使用示例:**
1965
- ```javascript
1966
- MKXFORM.reload('detailTable')
1967
- ```
1968
-
1969
- ---
1970
-
1971
- ### 7.17 `disabledOperation`
1972
-
1973
- **描述:** 禁用明细表操作按钮
1974
-
1975
- **签名:**
1976
- ```typescript
1977
- disabledOperation(id: string, limitList: Array<string> | boolean, rowNum?: number): void
1978
- ```
1979
-
1980
- **参数:**
1981
-
1982
- | 参数 | 类型 | 说明 |
1983
- |------|------|------|
1984
- | `id` | `string` | 明细表 ID |
1985
- | `limitList` | `Array<string> \| boolean` | 要禁用的操作名数组,或 `false` 禁用所有 |
1986
- | `rowNum`(可选) | `number` | 指定行号。省略则对整个明细表生效 |
1987
-
1988
- **可禁用的操作名:**
1989
-
1990
- | 操作名 | 说明 |
1991
- |--------|------|
1992
- | `'edit'` | 编辑 |
1993
- | `'insert'` | 插入行 |
1994
- | `'addNest'` | 添加子表行 |
1995
- | `'copy'` | 复制行 |
1996
- | `'delete'` | 删除行 |
1997
- | `'viewDetail'` | 查看详情 |
1998
- | `'isTrace'` | 追踪 |
1999
-
2000
- **实现细节:**
2001
- - `limitList` 可为数组 `['edit','insert','addNest','copy','delete','viewDetail','isTrace']` 指定禁用操作,或传 `false` 禁用所有操作
2002
- - 委托给 `detailRef.disabledOperation(limitList, rowNum)` 执行
2003
-
2004
- **注意:** 不支持移动端。
2005
-
2006
- **使用示例:**
2007
- ```javascript
2008
- // 禁用所有操作
2009
- MKXFORM.disabledOperation('detailTable', false)
2010
-
2011
- // 禁用新增和删除
2012
- MKXFORM.disabledOperation('detailTable', ['insert', 'delete'])
2013
-
2014
- // 仅禁用第 2 行的删除
2015
- MKXFORM.disabledOperation('detailTable', ['delete'], 1)
2016
- ```
2017
-
2018
- ---
2019
-
2020
- ## 8. 事件(events)
2021
-
2022
- > 模块名:`event`,分组:`EApiGroup.xhtml`
2023
-
2024
- ### 8.1 `onChange`
2025
-
2026
- **描述:** 根据控件 ID 监听值变化事件
2027
-
2028
- **签名:**
2029
- ```typescript
2030
- onChange(id: string, change: (value: any, extValue: any) => void): void
2031
- ```
2032
-
2033
- **参数:**
2034
-
2035
- | 参数 | 类型 | 说明 |
2036
- |------|------|------|
2037
- | `id` | `string` | 控件 ID |
2038
- | `change` | `(value, extValue) => void` | 值变化回调函数 |
2039
-
2040
- **回调参数:**
2041
-
2042
- | 参数 | 类型 | 说明 |
2043
- |------|------|------|
2044
- | `value` | `any` | 新值 |
2045
- | `extValue` | `any` | 扩展值。明细表时为 `tinyValues`(单元格变更集合) |
2046
-
2047
- **实现细节:**
2048
- - 对于明细表类型的控件,回调中会获取 `tinyValues`(单元格级别的变更数据),若 `tinyValues` 为空则跳过回调
2049
- - `extValue` 仅在明细表场景下有值,包含 `tinyValues` 对象
2050
- - 内置 `withdraw()` 存根方法,用于移除已注册的监听器
2051
-
2052
- **使用示例:**
2053
- ```javascript
2054
- // 监听字段值变化
2055
- MKXFORM.onChange('field_id', function(value, extValue) {
2056
- console.log('新值', value)
2057
- console.log('扩展值', extValue)
2058
- })
2059
-
2060
- // 监听明细表变化
2061
- MKXFORM.onChange('detailTable', function(value, extValue) {
2062
- console.log('明细表值变化', value)
2063
- console.log('单元格变更', extValue) // tinyValues 对象
2064
- })
2065
- ```
2066
-
2067
- ---
2068
-
2069
- ### 8.2 `beforeSubmit`
2070
-
2071
- **描述:** 注册表单提交前的拦截函数
2072
-
2073
- **签名:**
2074
- ```typescript
2075
- beforeSubmit(fn: Function, message?: string): void
2076
- ```
2077
-
2078
- **参数:**
2079
-
2080
- | 参数 | 类型 | 说明 |
2081
- |------|------|------|
2082
- | `fn` | `Function` | 拦截函数,返回 `true` 表示通过,返回 `false` 表示阻止提交 |
2083
- | `message`(可选) | `string` | 阻止提交时的错误提示信息 |
2084
-
2085
- **使用示例:**
2086
- ```javascript
2087
- // 提交前校验金额必须大于 0
2088
- MKXFORM.beforeSubmit(function() {
2089
- var amount = MKXFORM.getValue('amount')
2090
- if (amount <= 0) {
2091
- return false // 阻止提交
2092
- }
2093
- return true // 允许提交
2094
- }, '金额必须大于0')
2095
- ```
2096
-
2097
- **实现细节:**
2098
- - 将 `[fn, message]` 推入 `MKXFORM['MKXFORM_DATA_CONTAINER'].$$beforeSubmit` 数组
2099
- - 执行时通过 `executeIntercepts` 以 `Promise.all` 并行执行所有拦截函数
2100
- - 拦截函数返回 `undefined` 时视为 `true`(允许通过)
2101
- - 所有拦截执行完毕后有 500ms 延迟再 resolve
2102
- - 内置 `withdraw()` 方法,用于清除所有已注册的 beforeSubmit 处理器
2103
-
2104
- ---
2105
-
2106
- ### 8.3 `afterSubmit`
2107
-
2108
- **描述:** 注册表单提交成功后的回调函数
2109
-
2110
- **签名:**
2111
- ```typescript
2112
- afterSubmit(fn: Function, message?: string): void
2113
- ```
2114
-
2115
- **参数:**
2116
-
2117
- | 参数 | 类型 | 说明 |
2118
- |------|------|------|
2119
- | `fn` | `Function` | 提交成功后执行的函数 |
2120
- | `message`(可选) | `string` | 提示信息 |
2121
-
2122
- **使用示例:**
2123
- ```javascript
2124
- MKXFORM.afterSubmit(function() {
2125
- console.log('表单已成功提交')
2126
- MKXFORM.message.success('提交成功')
2127
- })
2128
- ```
2129
-
2130
- **实现细节:**
2131
- - 与 `beforeSubmit` 类似,将 `[fn, message]` 推入 `MKXFORM['MKXFORM_DATA_CONTAINER'].$$afterSubmit` 数组
2132
- - 执行时通过 `executeInterceptsAfterSubmit` 以 `Promise.all` 并行执行
2133
- - 与 `beforeSubmit` 的区别:无 500ms 延迟,立即 resolve
2134
-
2135
- ---
2136
-
2137
- ## 9. 流程函数(lbpms)
2138
-
2139
- ### 9.1 同步流程函数(fixLbpms)
2140
-
2141
- > 模块名:`lbpm`,同步注册
2142
-
2143
- #### 9.1.1 `getLbpmFormValues`
2144
-
2145
- **描述:** 获取审批提交信息
2146
-
2147
- **签名:**
2148
- ```typescript
2149
- getLbpmFormValues(): Promise<any>
2150
- ```
2151
-
2152
- **返回值:** Promise,resolve 时返回审批表单数据。
2153
-
2154
- **实现细节:**
2155
- - 注意:此方法会触发流程的校验
2156
- - 委托给 `$$lbpm(MKXFORM)?.getLbpmFormValues()` 执行
2157
-
2158
- **使用示例:**
2159
- ```javascript
2160
- MKXFORM.getLbpmFormValues().then(function(data) {
2161
- console.log('审批信息', data)
2162
- })
2163
- ```
2164
-
2165
- ---
2166
-
2167
- #### 9.1.2 `getOperationParameter`
2168
-
2169
- **描述:** 获取审批当前操作的配置信息
2170
-
2171
- **签名:**
2172
- ```typescript
2173
- getOperationParameter(): any
2174
- ```
2175
-
2176
- **返回值:** 当前审批操作的配置对象。
2177
-
2178
- **实现细节:**
2179
- - 委托给 `$$lbpm(MKXFORM)?.getOperationParameter()` 执行
2180
-
2181
- **使用示例:**
2182
- ```javascript
2183
- var param = MKXFORM.getOperationParameter()
2184
- console.log('操作配置', param)
2185
- ```
2186
-
2187
- ---
2188
-
2189
- #### 9.1.3 `getIdentity`
2190
-
2191
- **描述:** 获取当前处理人的身份信息列表
2192
-
2193
- **签名:**
2194
- ```typescript
2195
- getIdentity(): any
2196
- ```
2197
-
2198
- **返回值:** 当前处理人身份信息。
2199
-
2200
- **实现细节:**
2201
- - 委托给 `$$lbpm(MKXFORM)?.getIdentity()` 执行
2202
-
2203
- **使用示例:**
2204
- ```javascript
2205
- var identity = MKXFORM.getIdentity()
2206
- console.log('当前身份', identity)
2207
- ```
2208
-
2209
- ---
2210
-
2211
- #### 9.1.4 `getProcessInstanceId`
2212
-
2213
- **描述:** 获取当前流程实例 ID
2214
-
2215
- **签名:**
2216
- ```typescript
2217
- // 只读属性
2218
- MKXFORM.processInstanceId // 等价于 MKXFORM.getProcessInstanceId
2219
- ```
2220
-
2221
- **使用示例:**
2222
- ```javascript
2223
- var pid = MKXFORM.processInstanceId
2224
- console.log('流程实例ID', pid)
2225
- ```
2226
-
2227
- ---
2228
-
2229
- ### 9.2 异步流程函数(lbpms)
2230
-
2231
- > 仅在 `initDesign` 中异步注册,API 名称格式为 `promise_<name>`,数量取决于后端返回。
2232
-
2233
- 动态注册的流程函数通过 `callLbpm` 调用,命名格式:`promise_{functionName}`。
2234
-
2235
- **使用示例:**
2236
- ```javascript
2237
- // 具体函数名取决于后端配置
2238
- MKXFORM.promise_getNextApprover({ param: {} }, function(error, res) {
2239
- console.log(res)
2240
- })
2241
- ```
2242
-
2243
- ---
2244
-
2245
- ## 10. 集成平台(integrate)
2246
-
2247
- > 仅在 `initDesign` 中异步注册,分组名:`promise`
2248
-
2249
- 集成平台接口从后端动态获取,命名格式为 `promise_{systemName}`,每个系统下有子接口 `tic_{interfaceCode}`。
2250
-
2251
- **使用示例:**
2252
- ```javascript
2253
- // 调用指定系统的接口
2254
- MKXFORM.promise_systemName({ interfaceCode: 'CODE_001', param: {} }, function(error, res) {
2255
- console.log(res)
2256
- })
2257
- ```
2258
-
2259
- ---
2260
-
2261
- ## 11. 组织架构(orgFunctions)
2262
-
2263
- > 仅在 `initDesign` 中异步注册,分组名:`org_promise`
2264
-
2265
- 组织架构函数从后端动态获取,命名格式为 `org_{description}`。后端 API 位于 `/data/sys-org/sysOrgJsFormula/*`。
2266
-
2267
- **实现细节:**
2268
- - 调用 `api.getJsFormulaList()` 获取组织架构函数列表
2269
- - 生成 `org_{description}` 格式的 API 名称
2270
- - 通过 `callOrg` 发起请求,内部调用 `OrgHttp.post('/sysOrgJsFormula/{path}', param)` 执行
2271
-
2272
- ### 11.1 调用方式
2273
-
2274
- **签名:**
2275
- ```typescript
2276
- callOrg(config: { id: string, param?: any }, callback: (error: any, res: any) => void): Promise<void>
2277
- ```
2278
-
2279
- **参数:**
2280
-
2281
- | 参数 | 类型 | 说明 |
2282
- |------|------|------|
2283
- | `config.id` | `string` | 组织函数 ID,格式为 `sysorg.xxx`(如 `sysorg.getCurUserInfo`、`sysorg.getThisDepartment`) |
2284
- | `config.param` | `any`(可选) | 函数参数 |
2285
-
2286
- ### 11.2 常用组织架构函数
2287
-
2288
- 以下为后端提供的常用函数(通过 `jsFormulaList` 接口动态获取):
2289
-
2290
- | 函数 ID | 函数名称 | 说明 | 参数示例 |
2291
- | --------------------------------------------- | ----------- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
2292
- | `sysorg.getCurUserInfo` | 获取当前用户 | 获取当前登录用户信息 | `{}` |
2293
- | `sysorg.getElementDatas` | 查找人员和岗位 | 根据地址查找组织 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2294
- | `sysorg.getPersonByLoginName` | 根据登录名查找人员 | 通过登录名获取人员 | `{ loginName: 'zhangsan' }` |
2295
- | `sysorg.getPersonByPersonId` | 根据用户ID查找人员 | 通过人员ID获取信息 | `{ fdPersonId: 'xxx' }` |
2296
- | `sysorg.getThisDepartment` | 查找所属部门 | 获取当前人员主部门 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2297
- | `sysorg.getDepartmentAllPath` | 获取部门全路径 | 获取部门完整层级路径 | `{ addressObject: {fdId: 'xxx'} }` |
2298
- | `sysorg.getDepartmentByLevel` | 查找第X级部门 | 获取第N级部门 | `{ addressObject: {fdId: 'xxx'}, level: 2 }` |
2299
- | `sysorg.getOrganization` | 查找所属机构 | 获取上级机构 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2300
- | `sysorg.getDepartmentHead` | 查找部门领导 | 获取部门负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}] }` |
2301
- | `sysorg.getSuperiorDepartmenthead` | 查找上级部门领导 | 获取上级部门负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], condition: true }` |
2302
- | `sysorg.getDepartmentLeaderByLevel` | 获取第X级部门领导 | 获取第N级部门领导 | `{ addressObject: {fdId: 'xxx'}, level: 1 }` |
2303
- | `sysorg.getDepartmentLeadersByLevel` | 递归查找多级部门领导 | 获取多级部门领导 | `{ addressObject: {fdId: 'xxx'}, level: 3 }` |
2304
- | `sysorg.isDepartmentLeaderMyself` | 是否本部门领导 | 判断是否为本部门领导 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}] }` |
2305
- | `sysorg.isDepartmentLeaderForPerson` | 是否部门领导 | 判断指定人员是否为部门领导 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], organizations: [...] }` |
2306
- | `sysorg.getOrgHead` | 查找机构领导 | 获取机构负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 1}] }` |
2307
- | `sysorg.isRoleMember` | 岗位判断函数 | 判断是否属于某岗位 | `{ orgPost: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 4}, address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2308
- | `sysorg.getDepartmentSuperLeaderByLevel` | 查找部门上级领导 | 获取部门上级领导 | `{ organizations: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], level: 2 }` |
2309
- | `sysorg.isMember` | 成员判定函数 | 判断是否属于某组织 | `{ parent: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}, address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2310
- | `sysorg.isContainsLabel` | 组织包含标签函数 | 判断组织是否包含标签 | `{ org: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}, orgLabel: '标签名' }` |
2311
- | `sysorg.isUserContainsAnyLabel` | 当前用户包含任一标签 | 判断当前用户是否有某标签 | `{ orgLabels: ['标签1', '标签2'] }` |
2312
- | `sysorg.getOrgAttributeVal` | 查找组织属性 | 获取组织属性值 | `{ addressObject: {fdId: 'xxx'}, orgType: 2, strOrgAttribute: 'attrName' }` |
2313
- | `sysorg.checkDeptIsMain` | 主部门判断函数 | 判断是否为主部门 | `{ person: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}, dept: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2} }` |
2314
- | `sysorg.findUserAuxiliaryDept` | 查找用户辅部门 | 获取用户辅助部门列表 | `{ addressObject: {fdId: 'xxx'} }` |
2315
- | `sysorg.getElementByNo` | 根据组织编码查找组织 | 通过编码获取组织 | `{ fdNo: 'ORG001', orgType: 2 }` |
2316
- | `sysorg.getPersonAndPostByGroup` | 查找群组下的人员/岗位 | 获取群组成员 | `{ group: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 16}, isCross: false }` |
2317
- | `sysorg.isOrganizationBelongOrIncludeAnother` | 组织包含/属于判断 | 判断组织关系 | `{ firstOrgs: [...], secondOrgs: [...], relationType: 1, isCross: false }` |
2318
- | `sysorg.findUpXLevelLeader` | 向上查找X级部门领导 | 获取第N级上级领导 | `{ addressObject: {fdId: 'xxx'}, level: 2, isCross: false }` |
2319
- | `sysorg.queryDeptPersons` | 查找部门下人员 | 获取部门下所有人员 | `{ addressObject: {fdId: 'xxx'}, isIncludeChild: true }` |
2320
- | `sysorg.getPersonsByPost` | 根据岗位查找人员 | 获取岗位下所有人员 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 4}] }` |
2321
- | `sysorg.getPostOrPostPersonsByPostName` | 根据岗位名称查找 | 通过岗位名获取人员 | `{ postNameObj: {fdName: '总经理'}, orgType: 4 }` |
2322
- | `sysorg.getCurIdentityInfo` | 获取当前身份 | 获取当前用户身份信息 | `{}` |
2323
- | `sysorg.expandByGroup` | 查找群组下全部成员 | 获取群组完整成员列表 | `{ group: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 16} }` |
2324
-
2325
- ### 11.3 参数详解
2326
-
2327
- #### 11.3.1 参数对象结构
2328
-
2329
- **DefaultOrganization(组织对象):**
2330
- ```typescript
2331
- interface DefaultOrganization {
2332
- fdId: string // 组织ID
2333
- fdName: string // 组织名称
2334
- fdOrgType: number // 组织类型:1-机构, 2-部门, 4-岗位, 8-人员, 16-群组, 128-公共岗位, 256-身份
2335
- fdNo?: string // 组织编码(可选)
2336
- fdOriId?: string // 原始ID(可选)
2337
- fdIsAvailable?: boolean // 是否有效(可选)
2338
- }
2339
- ```
2340
-
2341
- #### 11.3.2 参数字段说明
2342
-
2343
- | 参数名 | 类型 | 说明 | 常用值 |
2344
- | ----------------- | ----------------------- | ---------- | ------------------------------------------------- |
2345
- | `address` | `DefaultOrganization[]` | 地址本数据,组织数组 | `[ {fdId: 'xxx', fdName: '张三', fdOrgType: 8} ]` |
2346
- | `addressObject` | `{fdId: string}` | 简化的地址对象 | `{ fdId: 'deptId_xxx' }` |
2347
- | `organizations` | `DefaultOrganization[]` | 组织数组,多个组织 | `[ {...}, {...} ]` |
2348
- | `org` | `DefaultOrganization` | 单个组织 | `{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}` |
2349
- | `parent` | `DefaultOrganization` | 父级组织 | 同上 |
2350
- | `group` | `DefaultOrganization` | 群组 | 同上 |
2351
- | `person` | `DefaultOrganization` | 人员 | 同上 |
2352
- | `dept` | `DefaultOrganization` | 部门 | 同上 |
2353
- | `orgPost` | `DefaultOrganization` | 岗位 | 同上 |
2354
- | `loginName` | `string` | 登录名 | `'zhangsan'` |
2355
- | `fdPersonId` | `string` | 人员ID | `'person_xxx'` |
2356
- | `fdNo` | `string` | 组织编码 | `'ORG001'` |
2357
- | `orgType` | `number` | 组织类型 | `1-机构, 2-部门, 4-岗位, 8-人员, 16-群组, 128-公共岗位, 256-身份` |
2358
- | `level` | `number` | 层级数字 | `0-根组织, 1-一级部门, 2-二级部门...` |
2359
- | `condition` | `boolean` | 条件开关 | `true-继续向上查找, false-不继续` |
2360
- | `isCross` | `boolean` | 是否跨组织 | `true/false` |
2361
- | `isIncludeChild` | `boolean` | 是否包含下级 | `true-包含, false-仅本级` |
2362
- | `orgLabel` | `string` | 组织标签名称 | `'标签名'` |
2363
- | `orgLabels` | `string[]` | 组织标签名称数组 | `['标签1', '标签2']` |
2364
- | `strOrgAttribute` | `string` | 组织属性名 | `'属性字段名'` |
2365
- | `postNameObj` | `{fdName: string}` | 岗位名称对象 | `{fdName: '总经理'}` |
2366
- | `relationType` | `number` | 关系类型 | `1-包含所有, 2-包含任意, 3-所有属于, 4-属于任意` |
2367
- | `strList` | `string[]` | ID字符串列表 | `['id1', 'id2']` |
2368
- | `orgList` | `DefaultOrganization[]` | 组织列表 | 同 address |
2369
-
2370
- #### 11.3.3 常用调用场景参数示例
2371
-
2372
- **场景1:根据人员获取所属部门**
2373
- ```javascript
2374
- // address 使用人员对象
2375
- MKXFORM.callOrg({
2376
- id: 'sysorg.getThisDepartment',
2377
- param: {
2378
- address: [
2379
- { fdId: 'person_123', fdName: '张三', fdOrgType: 8 }
2380
- ]
2381
- }
2382
- }, callback)
2383
- ```
2384
-
2385
- **场景2:获取部门领导**
2386
- ```javascript
2387
- // address 使用部门对象
2388
- MKXFORM.callOrg({
2389
- id: 'sysorg.getDepartmentHead',
2390
- param: {
2391
- address: [
2392
- { fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }
2393
- ]
2394
- }
2395
- }, callback)
2396
- ```
2397
-
2398
- **场景3:获取第N级部门领导**
2399
- ```javascript
2400
- // addressObject 使用简化对象
2401
- MKXFORM.callOrg({
2402
- id: 'sysorg.getDepartmentLeaderByLevel',
2403
- param: {
2404
- addressObject: { fdId: 'dept_456' },
2405
- level: 1 // 0-根组织, 1-一级部门, 2-二级部门...
2406
- }
2407
- }, callback)
2408
- ```
2409
-
2410
- **场景4:查找上级部门领导(是否继续向上)**
2411
- ```javascript
2412
- MKXFORM.callOrg({
2413
- id: 'sysorg.getSuperiorDepartmenthead',
2414
- param: {
2415
- address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }],
2416
- condition: true // true-领导为空时继续向上查找, false-不再向上
2417
- }
2418
- }, callback)
2419
- ```
2420
-
2421
- **场景5:判断是否属于某岗位**
2422
- ```javascript
2423
- MKXFORM.callOrg({
2424
- id: 'sysorg.isRoleMember',
2425
- param: {
2426
- orgPost: { fdId: 'post_789', fdName: '总经理', fdOrgType: 4 },
2427
- address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }]
2428
- }
2429
- }, callback)
2430
- ```
2431
-
2432
- **场景6:根据岗位名称查找人员**
2433
- ```javascript
2434
- MKXFORM.callOrg({
2435
- id: 'sysorg.getPostOrPostPersonsByPostName',
2436
- param: {
2437
- postNameObj: { fdName: '总经理' },
2438
- orgType: 4 // 可选,指定组织类型
2439
- }
2440
- }, callback)
2441
- ```
2442
-
2443
- **场景7:获取部门下所有人员(含下级)**
2444
- ```javascript
2445
- MKXFORM.callOrg({
2446
- id: 'sysorg.queryDeptPersons',
2447
- param: {
2448
- addressObject: { fdId: 'dept_456' },
2449
- isIncludeChild: true // true-包含子部门人员, false-仅本部门
2450
- }
2451
- }, callback)
2452
- ```
2453
-
2454
- **场景8:查找群组下全部成员**
2455
- ```javascript
2456
- MKXFORM.callOrg({
2457
- id: 'sysorg.expandByGroup',
2458
- param: {
2459
- group: { fdId: 'group_111', fdName: '项目组A', fdOrgType: 16 }
2460
- }
2461
- }, callback)
2462
- ```
2463
-
2464
- **场景9:根据组织编码查找**
2465
- ```javascript
2466
- MKXFORM.callOrg({
2467
- id: 'sysorg.getElementByNo',
2468
- param: {
2469
- fdNo: 'DEPT001', // 组织编码
2470
- orgType: 2 // 可选,1-机构 2-部门 4-岗位 8-人员 16-群组
2471
- }
2472
- }, callback)
2473
- ```
2474
-
2475
- ### 11.4 使用示例
2476
-
2477
- ```javascript
2478
- // 获取当前用户信息
2479
- MKXFORM.callOrg({ id: 'sysorg.getCurUserInfo', param: {} }, function(error, res) {
2480
- console.log('当前用户', res) // { fdId, fdName, fdOrgType, fdLoginName }
2481
- })
2482
-
2483
- // 查找所属部门(address 使用人员数组)
2484
- MKXFORM.callOrg({
2485
- id: 'sysorg.getThisDepartment',
2486
- param: {
2487
- address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }]
2488
- }
2489
- }, function(error, res) {
2490
- console.log('所属部门', res)
2491
- })
2492
-
2493
- // 查找部门领导(address 使用部门数组)
2494
- MKXFORM.callOrg({
2495
- id: 'sysorg.getDepartmentHead',
2496
- param: {
2497
- address: [{ fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }]
2498
- }
2499
- }, function(error, res) {
2500
- console.log('部门领导', res)
2501
- })
2502
-
2503
- // 获取部门全路径
2504
- MKXFORM.callOrg({ id: 'sysorg.getDepartmentAllPath', param: { addressObject: { fdId: 'dept_456' } } }, function(error, res) {
2505
- console.log('部门全路径', res)
2506
- })
2507
-
2508
- // 判断是否为本部门领导
2509
- MKXFORM.callOrg({
2510
- id: 'sysorg.isDepartmentLeaderMyself',
2511
- param: {
2512
- address: [{ fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }]
2513
- }
2514
- }, function(error, res) {
2515
- console.log('是否部门领导', res) // true/false
2516
- })
2517
-
2518
- // 获取第2级部门领导
2519
- MKXFORM.callOrg({ id: 'sysorg.getDepartmentLeaderByLevel', param: { addressObject: { fdId: 'dept_456' }, level: 2 } }, function(error, res) {
2520
- console.log('第2级部门领导', res)
2521
- })
2522
- ```
2523
-
2524
- ### 11.5 返回值结构
2525
-
2526
- 不同函数返回不同结构,常见结构示例:
2527
-
2528
- ```javascript
2529
- // 人员对象
2530
- {
2531
- fdId: '人员ID',
2532
- fdName: '人员名称',
2533
- fdOrgType: 8, // 人员类型
2534
- fdLoginName: '登录名'
2535
- }
2536
-
2537
- // 部门对象
2538
- {
2539
- fdId: '部门ID',
2540
- fdName: '部门名称',
2541
- fdHierarchyId: '层级ID',
2542
- fdParentId: '上级部门ID'
2543
- }
2544
-
2545
- // 机构对象
2546
- {
2547
- fdId: '机构ID',
2548
- fdName: '机构名称',
2549
- fdOrgType: 1 // 机构类型
2550
- }
2551
-
2552
- // 部门全路径
2553
- '集团_子公司_部门'
2554
- ```
2555
-
2556
- ---
2557
-
2558
- ## 12. 动作流(flow)
2559
-
2560
- > 仅在 `initDesign` 中异步注册,分组名:`flow`
2561
-
2562
- 动作流函数从后端动态获取,命名格式为 `flow_{fdCode}`。数量可能为 0。
2563
-
2564
- **使用示例:**
2565
- ```javascript
2566
- MKXFORM.flow_APPROVE({
2567
- context: {},
2568
- fdProcessId: 'process_001',
2569
- incParams: {},
2570
- fdProcessCode: 'FLOW_CODE'
2571
- }, function(error, res, context) {
2572
- console.log(res)
2573
- })
2574
- ```
2575
-
2576
- ---
2577
-
2578
- ## 13. LanBots AI(lanbots)
2579
-
2580
- > 仅在 `initDesign` 中异步注册,分组名:`lanbots`
2581
-
2582
- LanBots AI 函数从后端动态获取,命名格式为 `lanbotsPromises_{categoryValue}`,子接口为 `lanbots_{fdId}`。
2583
-
2584
- **使用示例:**
2585
- ```javascript
2586
- MKXFORM.callLanBots({ fdCode: 'CAT_001', id: 'BOT_001', lanBotsType: 'quickRead' }, function(error, res) {
2587
- console.log(res)
2588
- })
2589
- ```
2590
-
2591
- ---
2592
-
2593
- ## 14. 全局环境变量(GLOBALJS)
2594
-
2595
- > 仅在 `formAttr.controlAction` 存在时通过 `registerGlobalEnvToWindow` 注册
2596
-
2597
- 当表单配置了 `controlAction.$$env.data` 时,会自动注册到 `MKXFORM.GLOBALJS` 对象中。
2598
-
2599
- - **变量:** `MKXFORM.GLOBALJS[varName]` — 注册为只读变量
2600
- - **函数:** `MKXFORM.GLOBALJS[fnName](...args)` — 注册为函数,自动注入 MKXFORM 作为最后一个参数
2601
-
2602
- **使用示例:**
2603
- ```javascript
2604
- // 使用全局环境变量
2605
- var config = MKXFORM.GLOBALJS.someConfig
2606
-
2607
- // 调用全局环境函数
2608
- MKXFORM.GLOBALJS.someFunction('arg1', 'arg2')
2609
- ```
2610
-
2611
- ---
2612
-
2613
- ## 15. 注册顺序与生命周期
2614
-
2615
- ### initRuntime(同步注册)
2616
-
2617
- ```
2618
- 1. 设置直接属性(MKXFORM_DATA_CONTAINER、viewStatus、docStatus 等)
2619
- 2. inner → callTic, callLbpm, callOrg, callFlow, callLanBots
2620
- 3. vars → mkXform, viewStatus, docStatus, platform, formId
2621
- 4. global → ajax, getLocale, validateFields, getFormConfigs, getFormValues,
2622
- message, toast, modal, mobileModal, tableModal, HTMLModal,
2623
- executeOperation, authOperation
2624
- 5. function → $, setValue, getValue, setStyle, setProps,
2625
- getFieldAttr, setFieldAttr, getValueText, getControlHtml
2626
- 6. detail → getControlValue, updateControl, updateControlStyle,
2627
- addRow, updateRow, deleteRow, getRowCount,
2628
- getSelectedRowIndex, checkDetailRow, controlDetailRowCanDelete,
2629
- cacluColumnValue, getPageControlValue,
2630
- setDetailFieldAttr, setDetailRowAttr, setDetailFieldItemAttr,
2631
- reload, disabledOperation
2632
- 7. event → onChange, beforeSubmit, afterSubmit
2633
- 8. fixLbpms → getLbpmFormValues, getOperationParameter, getIdentity, getProcessInstanceId
2634
- 9. fixLbpms → (重复注册,疑似 bug)
2635
- 10. [条件] registerGlobalEnvToWindow → GLOBALJS
2636
- ```
2637
-
2638
- ### initDesign(异步注册)
2639
-
2640
- ```
2641
- window.MKXFORM = MKXFORM ← 挂载到全局
2642
- Promise.all([
2643
- integrate() → promise_{systemName} / tic_{interfaceCode}
2644
- lbpms() → promise_{name} / getIdentity / getLbpmFormValues / getOperationParameter
2645
- orgFunctions() → org_{description}
2646
- flow(props) → flow_{fdCode}
2647
- lanbots() → lanbotsPromises_{value} / lanbots_{fdId}
2648
- ])
2649
- ```
2650
-
2651
- ---
2652
-
1
+ # MKXFORM API 完整文档
2
+
3
+ ## 目录
4
+
5
+ - [1. 概述](#1-概述)
6
+ - [2. 直接属性(initRuntime)](#2-直接属性initruntime)
7
+ - [3. 内置函数(inner)](#3-内置函数inner)
8
+ - [4. 常用变量(vars)](#4-常用变量vars)
9
+ - [5. 通用函数(global)](#5-通用函数global)
10
+ - [6. 主表函数(functions)](#6-主表函数functions)
11
+ - [7. 明细表函数(details)](#7-明细表函数details)
12
+ - [8. 事件(events)](#8-事件events)
13
+ - [9. 流程函数(lbpms)](#9-流程函数lbpms)
14
+ - [10. 集成平台(integrate)](#10-集成平台integrate)
15
+ - [11. 组织架构(orgFunctions)](#11-组织架构orgfunctions)
16
+ - [12. 动作流(flow)](#12-动作流flow)
17
+ - [13. LanBots AI(lanbots)](#13-lanbots-ailanbots)
18
+ - [14. 全局环境变量(GLOBALJS)](#14-全局环境变量globaljs)
19
+ - [15. 注册顺序与生命周期](#15-注册顺序与生命周期)
20
+
21
+ ---
22
+
23
+ ## 1. 概述
24
+
25
+ `MKXFORM` 是表单运行时的全局 API 对象,挂载在 `window.MKXFORM` 上(设计器模式通过 `initDesign`),提供了表单操作、控件交互、事件监听、流程操作等全部能力。
26
+
27
+ **初始化入口:**
28
+
29
+ - `MKXFORMFACTORY.initRuntime(payload)` — 创建 MKXFORM 对象并同步注册 API
30
+ - `MKXFORMFACTORY.initDesign(props)` — 设计器模式,额外异步注册集成/流程/组织等 API
31
+
32
+ **属性统计:**
33
+
34
+ | 分类 | 数量 |
35
+ | ------------------ | ------- |
36
+ | 直接属性 | 15 |
37
+ | 内置函数(inner) | 5 |
38
+ | 常用变量(vars) | 5 |
39
+ | 通用函数(global) | 13 |
40
+ | 主表函数(functions) | 9 |
41
+ | 明细表函数(details) | 17 |
42
+ | 事件(events) | 3 |
43
+ | 流程函数(fixLbpms) | 4 |
44
+ | **同步合计** | **~71** |
45
+ | 集成平台(integrate) | 动态 |
46
+ | 流程平台(lbpms) | 动态 |
47
+ | 组织架构(orgFunctions) | 动态 |
48
+ | 动作流(flow) | 动态 |
49
+ | LanBots(lanbots) | 动态 |
50
+
51
+ ---
52
+
53
+ ## 2. 直接属性(initRuntime)
54
+
55
+ > 来源:`MKXFORMFACTORY.initRuntime` 中直接赋值
56
+
57
+ | # | 属性名 | 类型 | 说明 |
58
+ |---|--------|------|------|
59
+ | 1 | `MKXFORM_DATA_CONTAINER` | `object` | 表单提交钩子容器,包含 `$$beforeSubmit`(提交前函数数组)和 `$$afterSubmit`(提交后函数数组) |
60
+ | 2 | `viewStatus` | `string` | 视图状态(如 `edit`、`read` 等),后续被 vars 模块覆盖为 getter |
61
+ | 3 | `docStatus` | `string` | 文档/流程状态,后续被 vars 模块覆盖为 getter |
62
+ | 4 | `processInstanceId` | `string` | 当前流程实例 ID |
63
+ | 5 | `platform` | `string` | 设备端(`pc` / `mobile`),后续被 vars 模块覆盖为 getter |
64
+ | 6 | `dataModels` | `IDataModel[]` | 数据模型配置数组 |
65
+ | 7 | `formId` | `string` | 表单 ID,后续被 vars 模块覆盖为 getter |
66
+ | 8 | `formSizeType` | `string` | 表单尺寸类型(来自 viewDetail) |
67
+ | 9 | `$$FORM` | `React.RefObject<IFormApi>` | 内置表单实例引用 |
68
+ | 10 | `$$LBPM` | `React.MutableRefObject<any>` | 流程实例引用 |
69
+ | 11 | `$$DETAILFORMS` | `React.MutableRefObject<{[key: string]: any}>` | 明细表实例引用集合 |
70
+ | 12 | `$$CONTROLREF` | `React.MutableRefObject<any>` | 控件引用 |
71
+ | 13 | `popupOnOk` | `() => void` | 移动端 popup 弹窗确认回调 |
72
+ | 14 | `popupOnCancel` | `() => void` | 移动端 popup 弹窗取消回调 |
73
+ | 15 | `businessFieldsValue` | `object` | 业务内置字段值(目前仅 EOP 合同模块场景使用) |
74
+
75
+ ---
76
+
77
+ ## 3. 内置函数(inner)
78
+
79
+ > 模块名:`inner`,分组:`EApiGroup.inner`(对用户隐藏)
80
+
81
+ ### 3.1 `callTic`
82
+
83
+ **描述:** 调用集成平台接口
84
+
85
+ **签名:**
86
+ ```typescript
87
+ callTic(config: { interfaceCode: string, param: any }, callback: (error: any, res: any) => void): Promise<void>
88
+ ```
89
+
90
+ **参数:**
91
+
92
+ | 参数 | 类型 | 说明 |
93
+ |------|------|------|
94
+ | `config.interfaceCode` | `string` | 集成平台接口编码 |
95
+ | `config.param` | `any` | 接口参数 |
96
+ | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
97
+
98
+ **实现细节:**
99
+ - 调用 `api.executeForAjax(config.interfaceCode, config.param)` 发起请求
100
+ - 成功时返回 `res.data`
101
+ - 失败时自动调用 `Message.error('接口调用异常,请联系管 理员处理!')`,并打印错误到 console
102
+ - 支持多语言(`fmtMsg`)
103
+
104
+ **使用示例:**
105
+ ```javascript
106
+ MKXFORM.callTic({ interfaceCode: 'INTERFACE_001', param: { key: 'value' } }, function(error, res) {
107
+ if (error) {
108
+ console.error('调用失败', error)
109
+ return
110
+ }
111
+ console.log('返回数据', res)
112
+ })
113
+ ```
114
+
115
+ ---
116
+
117
+ ### 3.2 `callLbpm`
118
+
119
+ **描述:** 调用流程平台接口,自动注入 `processInstanceId` 和 `taskId`
120
+
121
+ **签名:**
122
+ ```typescript
123
+ callLbpm(config: any, callback: (error: any, res: any) => void): Promise<void>
124
+ ```
125
+
126
+ **参数:**
127
+
128
+ | 参数 | 类型 | 说明 |
129
+ |------|------|------|
130
+ | `config` | `any` | 流程接口配置,需包含 `functionCode` 等字段 |
131
+ | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
132
+
133
+ **实现细节:**
134
+ - 自动注入 `processInstanceId`:优先从 `$$lbpm(MKXFORM)?.getLbpmFormValues()?.processId` 获取,降级到 `MKXFORM.processInstanceId`,最后为 `null`
135
+ - 自动注入 `taskId`:从 `$$lbpm(MKXFORM)?.getLbpmFormValues()?.taskId` 获取,未获取到为 `null`
136
+ - 调用 `Api.executeForAjax({ ...config, processInstanceId, taskId })`
137
+ - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
138
+ - 支持多语言(`fmtMsg`)
139
+
140
+ **使用示例:**
141
+ ```javascript
142
+ MKXFORM.callLbpm({ functionCode: 'FN_APPROVE' }, function(error, res) {
143
+ if (error) {
144
+ console.error('调用失败', error)
145
+ return
146
+ }
147
+ console.log('返回数据', res)
148
+ })
149
+ ```
150
+
151
+ ---
152
+
153
+ ### 3.3 `callOrg`
154
+
155
+ **描述:** 调用组织架构函数接口
156
+
157
+ **签名:**
158
+ ```typescript
159
+ callOrg(config: { id: string, param?: any }, callback: (error: any, res: any) => void): Promise<void>
160
+ ```
161
+
162
+ **参数:**
163
+
164
+ | 参数 | 类型 | 说明 |
165
+ |------|------|------|
166
+ | `config.id` | `string` | 组织函数 ID,支持 `.` 分隔的路径(如 `com.example.getDept`),内部会按 `.` 分割取第二部分作为路径 |
167
+ | `config.param` | `any`(可选) | 函数参数,默认 `{}` |
168
+ | `callback` | `(error, res) => void` | 回调函数,error 为错误信息,res 为返回数据(`res.data`) |
169
+
170
+ **实现细节:**
171
+ - 内部通过 `OrgHttp.post('/sysOrgJsFormula/{path}', param)` 发起请求
172
+ - `id` 按 `.` 分割后取第二部分作为 URL 路径(如 `org.getDeptById` → `/sysOrgJsFormula/getDeptById`)
173
+ - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
174
+ - 支持多语言(`fmtMsg`)
175
+
176
+ **使用示例:**
177
+ ```javascript
178
+ // 根据组织编码查找组织
179
+ MKXFORM.callOrg({ id: 'sysorg.getElementByNo', param: { fdNo: 'DEPT001', orgType: 2 } }, function(error, res) {
180
+ if (error) {
181
+ console.error('调用失败', error)
182
+ return
183
+ }
184
+ console.log('部门信息', res)
185
+ })
186
+ ```
187
+
188
+ ---
189
+
190
+ ### 3.4 `callFlow`
191
+
192
+ **描述:** 调用动作流函数接口
193
+
194
+ **签名:**
195
+ ```typescript
196
+ callFlow(config: { context: any, fdProcessId: string, incParams: any, fdProcessCode: string }, callback: (error: any, res: any, context: any) => void): Promise<void>
197
+ ```
198
+
199
+ **参数:**
200
+
201
+ | 参数 | 类型 | 说明 |
202
+ |------|------|------|
203
+ | `config.context` | `any` | 上下文对象,内部通过 `context.fdOprId` 获取操作 ID |
204
+ | `config.fdProcessId` | `string` | 流程定义 ID |
205
+ | `config.incParams` | `any` | 附加参数 |
206
+ | `config.fdProcessCode` | `string` | 流程编码 |
207
+ | `callback` | `(error, res, context) => void` | 回调函数,第三个参数返回原始 context 对象 |
208
+
209
+ **实现细节:**
210
+ - 调用 `api.executeFlowForAjax({ fdOprId: context.fdOprId, fdProcessId, fdProcessCode, incParams })`
211
+ - 成功时返回 `(null, res, context)`,context 原样回传
212
+ - 失败时自动调用 `Message.error('接口调用异常,请联系管理员处理!')`
213
+
214
+ **使用示例:**
215
+ ```javascript
216
+ MKXFORM.callFlow({
217
+ context: { fdOprId: 'opr_001' },
218
+ fdProcessId: 'process_001',
219
+ incParams: {},
220
+ fdProcessCode: 'FLOW_APPROVE'
221
+ }, function(error, res, context) {
222
+ if (error) {
223
+ console.error('调用失败', error)
224
+ return
225
+ }
226
+ console.log('流程执行结果', res)
227
+ console.log('上下文', context)
228
+ })
229
+ ```
230
+
231
+ ---
232
+
233
+ ### 3.5 `callLanBots`
234
+
235
+ **描述:** 调用 LanBots 快速阅读和辅助填写 AI 功能
236
+
237
+ **签名:**
238
+ ```typescript
239
+ callLanBots(config: { fdCode: string, id: string, lanBotsType: string }, callback: (error: any, res: any) => void): void
240
+ ```
241
+
242
+ **参数:**
243
+
244
+ | 参数 | 类型 | 说明 |
245
+ |------|------|------|
246
+ | `config.fdCode` | `string` | LanBots 编码 |
247
+ | `config.id` | `string` | 模型 ID |
248
+ | `config.lanBotsType` | `string` | 使用场景类型 |
249
+ | `callback` | `(error, res) => void` | 回调函数,res 包含 `success` 和 `content` 字段 |
250
+
251
+ **实现细节:**
252
+ - 通过 `window['sys-xform-lanBots']` 防止重复打开(已有打开的 LanBots 时不再创建新实例)
253
+ - 调用 `openLanBots(config, callback, MKXFORM, {})` 打开 AI 助手
254
+ - 成功时可通过 `res.success` 和 `res.content` 获取 AI 返回内容,配合 `setValue` 回填表单
255
+ - 异常时回调 `callback(error, { success: false })`
256
+
257
+ **使用示例:**
258
+ ```javascript
259
+ MKXFORM.callLanBots({
260
+ fdCode: 'CAT_001',
261
+ id: 'BOT_001',
262
+ lanBotsType: 'quickRead'
263
+ }, function(error, res) {
264
+ console.log(res)
265
+ if (res && res.success) {
266
+ // 将 AI 返回的内容回填到表单
267
+ MKXFORM.setValue('field_id', res.content)
268
+ }
269
+ })
270
+ ```
271
+
272
+ ---
273
+
274
+ ## 4. 常用变量(vars)
275
+
276
+ > 模块名:`vars`,分组:`EApiGroup.all`
277
+
278
+ 这些变量为只读属性,注册后会覆盖 `initRuntime` 中的同名直接属性。
279
+
280
+ | # | 属性名 | 类型 | 说明 |
281
+ | --- | ------------ | -------- | ------------------ |
282
+ | 1 | `mkXform` | `object` | 内置表单对象(MKXFORM 自身) |
283
+ | 2 | `viewStatus` | `string` | 视图状态(edit/read 等) |
284
+ | 3 | `docStatus` | `string` | 文档/流程状态 |
285
+ | 4 | `platform` | `string` | 设备端(pc/mobile) |
286
+ | 5 | `formId` | `string` | 表单 ID |
287
+
288
+ **使用示例:**
289
+ ```javascript
290
+ var status = MKXFORM.viewStatus // 获取当前视图状态
291
+ var docStatus = MKXFORM.docStatus // 获取文档状态
292
+ var platform = MKXFORM.platform // 获取设备端
293
+ var fid = MKXFORM.formId // 获取表单ID
294
+ ```
295
+
296
+ ---
297
+
298
+ ## 5. 通用函数(global)
299
+
300
+ > 模块名:`global`,分组:`EApiGroup.all`
301
+
302
+ ### 5.1 `ajax`
303
+
304
+ **描述:** 发起异步 HTTP 请求。本质是 `axios()` 方法,可参考 http://axios-js.com/zh-cn/docs/index.html 中 axios 方法使用方式。
305
+
306
+ **签名:**
307
+ ```typescript
308
+ ajax(config: AxiosRequestConfig, callback: (error: any, res: any) => void): Promise<any>
309
+ ```
310
+
311
+ **参数:**
312
+
313
+ | 参数 | 类型 | 说明 |
314
+ |------|------|------|
315
+ | `config` | `AxiosRequestConfig` | axios 请求配置(url、method、data、headers 等),可参考 [axios 文档](http://axios-js.com/zh-cn/docs/index.html) |
316
+ | `callback` | `(error, res) => void` | 回调函数。参数 `error` 为错误信息;参数 `res` 为响应数据 |
317
+
318
+ **返回值:** `res` 结构为 `{ msg: string, success: boolean, data: any }`。
319
+
320
+ **实现细节:**
321
+ - 使用 `httpBaseUrl(url)` 解析相对 URL(兼容上下文的场景)
322
+ - 错误时将 `err.response` 传递给回调函数
323
+
324
+ **使用示例:**
325
+ ```javascript
326
+ MKXFORM.ajax({
327
+ method: 'GET',
328
+ url: '/api/data'
329
+ }, function (error, res) {
330
+ console.log(res) // {msg: 'xxx', success: true, data: xxx}
331
+ })
332
+ ```
333
+
334
+ ---
335
+
336
+ ### 5.2 `getLocale`
337
+
338
+ **描述:** 获取多语言信息。可用于获取用户当前多语言标志,或返回传入键值对中匹配当前语言的值。
339
+
340
+ **签名:**
341
+ ```typescript
342
+ getLocale(messages?: { Cn: string, Us: string, [locale: string]: string }): string
343
+ ```
344
+
345
+ **参数:**
346
+
347
+ | 参数 | 类型 | 说明 |
348
+ | -------------- | --------------------------------- | ------------------------------------- |
349
+ | `messages`(可选) | `{ Cn: string, Us: string, ... }` | 多语言文本映射表。格式为 `{ Cn: '中文', Us: '英文' }` |
350
+ | | | |
351
+
352
+ **返回值:** 若传 `messages` 则返回当前语言对应的文本;若未传参则返回当前语言标志(如 `Cn`、`Us`)。
353
+
354
+ **实现细节:**
355
+ - 使用 `getDefaultLocale()` 从 runtime utils 获取当前语言标志
356
+ - 若传入 `messages` 但格式不正确(缺少 `Cn` 或 `Us` 键),打印警告:`console.warn('参数不对,格式应为 {Cn: "中文", Us: "英文"}')`
357
+
358
+ **使用示例:**
359
+ ```javascript
360
+ // 若当前用户语言为中文,未传参则直接返回 'Cn'
361
+ MKXFORM.getLocale()
362
+
363
+ // 若当前用户语言为中文,传了多语言键值对,则返回 '中文'
364
+ MKXFORM.getLocale({ Cn: '中文', Us: '英文' })
365
+ ```
366
+
367
+ ---
368
+
369
+ ### 5.3 `validateFields`
370
+
371
+ **描述:** 强制触发表单校验,返回值为一个 Promise。
372
+
373
+ **签名:**
374
+ ```typescript
375
+ validateFields(): Promise<{ errors: any, value: any, values: any }>
376
+ ```
377
+
378
+ **返回值:** Promise,resolve 时返回验证结果对象:
379
+
380
+ | 字段 | 类型 | 说明 |
381
+ |------|------|------|
382
+ | `errors` | `object` | 错误字段数据,key 为字段 ID,value 为错误信息数组。无错误时为空 |
383
+ | `value` | `any` | 表单值(同 values) |
384
+ | `values` | `any` | 表单所有值 |
385
+
386
+ **实现细节:**
387
+ - 委托给 `$$form(MKXFORM)?.validateFields()` 执行
388
+ - 内置 `withdraw()` 存根方法(TODO,待实现)
389
+
390
+ **errors 格式示例:**
391
+ ```json
392
+ {
393
+ "mk_model_xxx.fd_col_xxx": {
394
+ "errors": [
395
+ { "message": "单行文本1不能为空", "field": "mk_model_xxx.fd_col_xxx" }
396
+ ]
397
+ }
398
+ }
399
+ ```
400
+
401
+ **使用示例:**
402
+ ```javascript
403
+ MKXFORM.validateFields()
404
+ .then(function(result) {
405
+ var errors = result.errors
406
+ var values = result.values
407
+ console.log('错误字段数据', errors)
408
+ console.log('表单数据', values)
409
+ })
410
+ ```
411
+
412
+ ---
413
+
414
+ ### 5.4 `getFormConfigs`
415
+
416
+ **描述:** 获取表单基础配置信息,如表单全部字段 ID、表 ID、表单 fdId 和字段对应控件等。
417
+
418
+ **签名:**
419
+ ```typescript
420
+ getFormConfigs(): any
421
+ ```
422
+
423
+ **返回值:** 表单配置对象,包含表单所有字段的 ID、表 ID、表单 fdId、各字段对应的控件类型等信息。
424
+
425
+ **实现细节:**
426
+ - 委托给 `$$form(MKXFORM)?.getFormConfigs()` 执行
427
+
428
+ **使用示例:**
429
+ ```javascript
430
+ var config = MKXFORM.getFormConfigs()
431
+ ```
432
+
433
+ ---
434
+
435
+ ### 5.5 `getFormValues`
436
+
437
+ **描述:** 获取整个表单所有值,以键值对形式返回,包含机制数据和系统字段数据。
438
+
439
+ **签名:**
440
+ ```typescript
441
+ getFormValues(): any
442
+ ```
443
+
444
+ **返回值:** 表单所有字段值对象 `{ fieldId: value, ... }`,包含机制数据和系统字段数据。
445
+
446
+ **实现细节:**
447
+ - 委托给 `$$form(MKXFORM)?.getFieldsValue()` 执行
448
+
449
+ **使用示例:**
450
+ ```javascript
451
+ var values = MKXFORM.getFormValues()
452
+ console.log('字段A的值', values.fieldA)
453
+ ```
454
+
455
+ ---
456
+
457
+ ### 5.6 `message`
458
+
459
+ **描述:** 全局消息提示(仅支持桌面端),实际调用为 `lui` 库 `Message` 组件方法。
460
+
461
+ **类型:** `@lui/core` 的 `Message` 对象
462
+
463
+ **方法:**
464
+
465
+ | 方法 | 签名 | 说明 |
466
+ |------|------|------|
467
+ | `success` | `message.success(text: string)` | 成功提示 |
468
+ | `error` | `message.error(text: string)` | 错误提示 |
469
+ | `warning` | `message.warning(text: string)` | 警告提示 |
470
+ | `info` | `message.info(text: string)` | 信息提示 |
471
+
472
+ **实现细节:**
473
+ - 直接导出 `Message` 对象从 `@lui/core` 库
474
+
475
+ **使用示例:**
476
+ ```javascript
477
+ MKXFORM.message.success('全局成功提示')
478
+ MKXFORM.message.warning('全局警告提示')
479
+ MKXFORM.message.error('全局错误提示')
480
+ ```
481
+
482
+ ---
483
+
484
+ ### 5.7 `toast`
485
+
486
+ **描述:** 全局消息提示(仅支持移动端),实际调用为 `mui` 库 `Toast` 组件方法。
487
+
488
+ **签名:**
489
+ ```typescript
490
+ toast(options: { content: string, icon: 'success' | 'fail' | 'warning' }): void
491
+ ```
492
+
493
+ **参数:**
494
+
495
+ | 参数 | 类型 | 说明 |
496
+ |------|------|------|
497
+ | `options.content` | `string` | 提示文本 |
498
+ | `options.icon` | `'success' \| 'fail' \| 'warning'` | 图标类型 |
499
+
500
+ **实现细节:**
501
+ - 直接调用 `Toast.show({...options})` 从 `@mui/core` 库
502
+
503
+ **使用示例:**
504
+ ```javascript
505
+ MKXFORM.toast({
506
+ content: '全局成功提示',
507
+ icon: 'success',
508
+ })
509
+ ```
510
+
511
+ ---
512
+
513
+ ### 5.8 `modal`
514
+
515
+ **描述:** confirm 弹窗(仅支持桌面端),实际调用为 `lui` 库 `Modal.confirm`,具体用法可参考 `lui` 对应组件。
516
+
517
+ **签名:**
518
+ ```typescript
519
+ modal(options: { title?: string, content: string | ReactNode, onOk?: () => void, onCancel?: () => void }): void
520
+ ```
521
+
522
+ **参数:**
523
+
524
+ | 参数 | 类型 | 说明 |
525
+ |------|------|------|
526
+ | `options.title` | `string`(可选) | 弹窗标题 |
527
+ | `options.content` | `string \| ReactNode` | 弹窗内容 |
528
+ | `options.onOk` | `() => void`(可选) | 确认回调 |
529
+ | `options.onCancel` | `() => void`(可选) | 取消回调 |
530
+
531
+ **实现细节:**
532
+ - 使用 `Modal.confirm` 从 `@lui/core` 库
533
+ - 默认配置:`cancelText: '取消'`,`okText: '确定'`
534
+
535
+ **使用示例:**
536
+ ```javascript
537
+ MKXFORM.modal({
538
+ title: '是否关闭弹窗',
539
+ content: '关闭则不再显示',
540
+ onOk() {
541
+ console.log('点击确认')
542
+ },
543
+ onCancel() {
544
+ console.log('点击取消')
545
+ },
546
+ })
547
+ ```
548
+
549
+ ---
550
+
551
+ ### 5.9 `mobileModal`
552
+
553
+ **描述:** confirm 弹窗(仅支持移动端),实际调用为 `mui` 库 `Modal.confirm`,具体用法可参考 `mui` 对应组件。
554
+
555
+ **签名:**
556
+ ```typescript
557
+ mobileModal(options: { title?: string, content: string, onConfirm?: () => void, onCancel?: () => void }): void
558
+ ```
559
+
560
+ **参数:**
561
+
562
+ | 参数 | 类型 | 说明 |
563
+ |------|------|------|
564
+ | `options.title` | `string`(可选) | 弹窗标题 |
565
+ | `options.content` | `string` | 弹窗内容 |
566
+ | `options.onConfirm` | `() => void`(可选) | 确认回调 |
567
+ | `options.onCancel` | `() => void`(可选) | 取消回调 |
568
+
569
+ **实现细节:**
570
+ - 使用 `Modal.confirm` 从 `@mui/core` 库
571
+ - 默认配置:`cancelText: '取消'`,`confirmText: '确定'`(注意:移动端使用 `confirmText` 而非 `okText`)
572
+
573
+ **使用示例:**
574
+ ```javascript
575
+ MKXFORM.mobileModal({
576
+ title: '是否关闭弹窗',
577
+ content: '关闭则不再显示',
578
+ onConfirm() {
579
+ console.log('点击确认')
580
+ },
581
+ onCancel() {
582
+ console.log('点击取消')
583
+ },
584
+ })
585
+ ```
586
+
587
+ ---
588
+
589
+ ### 5.10 `tableModal`
590
+
591
+ **描述:** 表格弹窗(仅支持桌面端),弹窗内渲染一个表格。
592
+
593
+ **签名:**
594
+ ```typescript
595
+ tableModal(options: { modal: object, table: object }): void
596
+ ```
597
+
598
+ **参数:**
599
+
600
+ | 参数 | 类型 | 说明 |
601
+ |------|------|------|
602
+ | `options.modal` | `object` | 弹窗配置(title、okCancel、okButtonProps、onOk、onCancel 等),具体配置可参考 [Ant Design Modal](https://4x.ant.design/components/modal-cn) |
603
+ | `options.table.columns` | `Array` | 表格列定义(title、key、dataIndex 等),具体配置可参考 [Ant Design Table](https://4x.ant.design/components/table-cn) |
604
+ | `options.table.dataSource` | `Array` | 表格数据 |
605
+
606
+ **实现细节:**
607
+ - 校验 `typeof options !== 'object'`,类型不匹配时返回 `null`
608
+ - 使用 `Modal.info` 渲染弹窗,内部通过 `createElement(Table, {...options.table})` 渲染表格
609
+ - 默认配置:`width: 1152`,`maxHeight: '776px'`,`destroyOnClose: true`,隐藏 OK 按钮
610
+ - 表格默认配置:`scroll: {x: true, y: true}`,`pagination: false`,`maxHeight: '500px'`
611
+
612
+ **使用示例:**
613
+ ```javascript
614
+ MKXFORM.tableModal({
615
+ modal: {
616
+ title: '这是标题',
617
+ okCancel: true, // 显示取消按钮
618
+ okButtonProps: {style: {display: ''}}, // 显示确定按钮
619
+ renderExtra: () => '扩展区域',
620
+ onOk() {
621
+ console.log('点击确定')
622
+ },
623
+ onCancel() {
624
+ console.log('点击取消')
625
+ },
626
+ },
627
+ table: {
628
+ columns: [
629
+ { title: 'Name', key: 'name', dataIndex: 'name' },
630
+ { title: 'Age', key: 'age', dataIndex: 'age' },
631
+ { title: 'Address', key: 'address', dataIndex: 'address' },
632
+ { title: 'Tags', key: 'tags', dataIndex: 'tags' }
633
+ ],
634
+ dataSource: [
635
+ {
636
+ key: '1',
637
+ name: 'John Brown',
638
+ age: 32,
639
+ address: 'New York No. 1 Lake Park',
640
+ tags: 'cool',
641
+ }
642
+ ]
643
+ }
644
+ })
645
+ ```
646
+
647
+ ---
648
+
649
+ ### 5.11 `HTMLModal`
650
+
651
+ **描述:** HTML 内容弹窗(仅支持桌面端),支持渲染自定义 HTML 内容。
652
+
653
+ **签名:**
654
+ ```typescript
655
+ HTMLModal(options: { content: string, [key: string]: any }): void
656
+ ```
657
+
658
+ **参数:**
659
+
660
+ | 参数 | 类型 | 说明 |
661
+ |------|------|------|
662
+ | `options.content` | `string` | HTML 字符串内容(通过 `dangerouslySetInnerHTML` 渲染) |
663
+ | 其他 | `any` | 其余 Modal 组件属性(onOk、onCancel、okButtonProps、okCancel 等),具体配置可参考 [Ant Design Modal](https://4x.ant.design/components/modal-cn) |
664
+
665
+ **注意:** 默认隐藏 OK 按钮,可通过 `okButtonProps: { style: { display: '' } }` 显示。
666
+
667
+ **实现细节:**
668
+ - 校验 `typeof options !== 'object'`,类型不匹配时返回 `null`
669
+ - 与 `tableModal` 相同的默认配置:`width: 1152`,`maxHeight: '776px'`,`destroyOnClose: true`,隐藏 OK 按钮
670
+ - 使用 `createElement('div', {dangerouslySetInnerHTML: {__html: options.content}})` 渲染 HTML 内容
671
+
672
+ **使用示例:**
673
+ ```javascript
674
+ var htmlText = '<div class="card">' +
675
+ '<img src="https://picsum.photos/300/200" width="300" height="200">' +
676
+ '<div style="padding:16px">' +
677
+ '<h3 style="margin:0 0 8px">卡片标题</h3>' +
678
+ '<p style="margin:0 0 12px;color:#666">简短描述文字</p>' +
679
+ '<button style="padding:8px 16px;background:#007bff;color:#fff;border:none;border-radius:4px">按钮</button>' +
680
+ '</div>' +
681
+ '</div>' +
682
+ '<style>' +
683
+ '.card{width:300px;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.1);font-family:system-ui}' +
684
+ '</style>'
685
+
686
+ MKXFORM.HTMLModal({
687
+ onOk() {
688
+ console.log('点击确认')
689
+ },
690
+ onCancel() {
691
+ console.log('点击取消')
692
+ },
693
+ // 显示确定按钮
694
+ // okButtonProps: { style: { display: '' } },
695
+ // 显示取消按钮
696
+ // okCancel: true,
697
+ content: htmlText
698
+ })
699
+ ```
700
+
701
+ ---
702
+
703
+ ### 5.12 `executeOperation`
704
+
705
+ **描述:** 执行业务操作。可执行已配置好的业务操作(包括内置业务操作),此方法无返回值,部分业务操作会进行页面跳转。实际执行 `sys-modeling` 模块下 `src/desktop/operation/execute.ts` 中的 `execute` 方法。
706
+
707
+ **签名:**
708
+ ```typescript
709
+ executeOperation(operation: OperationConfig, params: ParamsConfig): void
710
+ ```
711
+
712
+ **参数说明:**
713
+
714
+ **operation 参数:**
715
+
716
+ | 参数 | 类型 | 说明 |
717
+ |------|------|------|
718
+ | `code` | `string` | 操作按钮类型(add/edit/delete/import/export/print/close/instanceClone/modalDefine/other 等) |
719
+ | `uniqueCode` | `string` | 操作唯一编码(不传时通过 `id` 获取操作) |
720
+ | `platform` | `'pc' \| 'mobile'` | 设备类型 |
721
+ | `id` | `string`(可选) | 操作 ID(不传时通过 `uniqueCode` 获取) |
722
+ | `name` | `string`(可选) | 操作名称(用于弹窗标题等) |
723
+ | `selected` | `boolean`(可选) | 是否需要选中数据(modalDefine/other 场景) |
724
+
725
+ **params 参数:**
726
+
727
+ | 参数 | 类型 | 说明 |
728
+ | ----------------------- | ------------------------ | ------------------------------------------------- |
729
+ | `fdType` | `number` | 表单类型:0-普通表单, 1-分类模板, 2-简单分类 |
730
+ | `fdCode` | `string` | 表单编码 |
731
+ | `fdXFormId` | `string` | 表单 ID(不传时通过 `fdCode` 调用接口获取) |
732
+ | `baseUrl` | `string` | 路径前缀,如 `/current/sys-modeling/app/{appCode}` |
733
+ | `fdTemplateId` | `string` | 分类模板 ID(分类表单时必传) |
734
+ | `target` / `fdOpenMode` | `string` | 打开方式:`self`、`drawer`、`_blank` 等 |
735
+ | `drawerOptions` | `object` | 抽屉配置 |
736
+ | `cacheListRef` | `React.MutableRefObject` | 列表引用(用于刷新等操作) |
737
+ | `$$contentviewProps` | `object` | 内容视图属性,包含 `refresh`、`history`、`query` 等 |
738
+ | `setDoingOperation` | `(v: boolean) => void` | 设置操作进行中状态 |
739
+ | `defaultTemplateData` | `string` | 表单默认值(JSON 序列化后会 URL 编码) |
740
+ | `callback` | `Function` | 操作完成回调,同步调用业务触发时有效 |
741
+ | `docId` | `string` | 文档 ID(edit/delete/print 等场景) |
742
+ | `formId` | `string` | 表单 ID(部分场景使用,等价于 `fdXFormId`) |
743
+ | `selectedId` | `string[]` | 选中的文档 ID 数组(deleteAll/batchPrint/modalDefine 等场景) |
744
+ | `fdRightGroupId` | `string` | 权限组 ID |
745
+ | `mechAuthToken` | `string` | 实体认证 Token |
746
+ | `dispatch` | `Function` | Redux dispatch(export 场景) |
747
+ | `refresh` | `Function` | 刷新回调 |
748
+ | `viewPageId` | `string` | 视图页面 ID |
749
+ | `entityName` | `string` | 实体名(分类表单场景) |
750
+ | `entityId` | `string` | 文档 ID(分类表单场景) |
751
+
752
+ **参数转换规则(formatParams):**
753
+
754
+ 仅 `add` 和 `other` 操作(PC 端)会进行参数转换:
755
+
756
+ | 传入 params 字段 | 转换后字段 | 适用操作 |
757
+ |------------------|------------|----------|
758
+ | `fdType` | `fdCategoryType` | add |
759
+ | `fdCode` | `fdCategoryModelCode` | add, other |
760
+ | `fdTemplateId` | `fdCategoryTemplateId` | add |
761
+ | `fdXFormId` | `formId` | add |
762
+ | `target` | `fdOpenMode` | add, other |
763
+
764
+ > 其他操作(delete、edit、print 等)参数不做转换,直接透传。
765
+
766
+ **各操作类型详细参数:**
767
+
768
+ #### add — 新增
769
+
770
+ ```javascript
771
+ MKXFORM.executeOperation({
772
+ code: 'add',
773
+ uniqueCode: 'template_p20v4f',
774
+ platform: 'pc'
775
+ }, {
776
+ fdType: 0,
777
+ fdCode: 'template_xxx',
778
+ fdXFormId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
779
+ baseUrl: '/current/sys-modeling/app/jspanel',
780
+ // fdTemplateId: 'template_id_xxx', // 分类表单时必传
781
+ // target: 'self', // 打开方式
782
+ // defaultTemplateData: '{}', // 表单默认值
783
+ callback: function(res) {
784
+ console.log(res)
785
+ }
786
+ })
787
+ ```
788
+
789
+ #### edit — 编辑
790
+
791
+ ```javascript
792
+ MKXFORM.executeOperation({
793
+ code: 'edit',
794
+ platform: 'pc'
795
+ }, {
796
+ baseUrl: '/current/sys-modeling/app/jspanel',
797
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
798
+ docId: 'doc_xxx',
799
+ // fdRightGroupId: 'xxx',
800
+ // fdOpenMode: 'self',
801
+ })
802
+ ```
803
+
804
+ #### delete — 删除
805
+
806
+ ```javascript
807
+ MKXFORM.executeOperation({
808
+ code: 'delete',
809
+ platform: 'pc'
810
+ }, {
811
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
812
+ docId: 'doc_xxx',
813
+ // appId: 'xxx',
814
+ // appCode: 'xxx',
815
+ // mainTable: true,
816
+ })
817
+ ```
818
+
819
+ #### deleteAll — 批量删除
820
+
821
+ ```javascript
822
+ MKXFORM.executeOperation({
823
+ code: 'deleteAll',
824
+ platform: 'pc'
825
+ }, {
826
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
827
+ selectedId: ['doc_id_1', 'doc_id_2'],
828
+ })
829
+ ```
830
+
831
+ #### import — 导入
832
+
833
+ ```javascript
834
+ MKXFORM.executeOperation({
835
+ code: 'import',
836
+ platform: 'pc'
837
+ }, {
838
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
839
+ // isSimple: false,
840
+ // listviewId: 'xxx',
841
+ })
842
+ ```
843
+
844
+ #### export — 导出
845
+
846
+ ```javascript
847
+ MKXFORM.executeOperation({
848
+ code: 'export',
849
+ platform: 'pc'
850
+ }, {
851
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
852
+ dispatch: dispatch,
853
+ $$contentviewProps: contentviewProps,
854
+ // selectedId: [],
855
+ // listviewId: 'xxx',
856
+ })
857
+ ```
858
+
859
+ #### close — 关闭
860
+
861
+ ```javascript
862
+ MKXFORM.executeOperation({
863
+ code: 'close',
864
+ platform: 'pc'
865
+ }, {
866
+ $$contentviewProps: { history: history }
867
+ })
868
+ ```
869
+
870
+ #### print — 打印
871
+
872
+ ```javascript
873
+ MKXFORM.executeOperation({
874
+ code: 'print',
875
+ platform: 'pc'
876
+ }, {
877
+ baseUrl: '/current/sys-modeling/app/jspanel',
878
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
879
+ docId: 'doc_xxx',
880
+ // listviewId: 'xxx',
881
+ // viewPageId: 'xxx',
882
+ })
883
+ ```
884
+
885
+ #### batchPrint — 批量打印
886
+
887
+ ```javascript
888
+ MKXFORM.executeOperation({
889
+ code: 'batchPrint',
890
+ platform: 'pc'
891
+ }, {
892
+ baseUrl: '/current/sys-modeling/app/jspanel',
893
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
894
+ selectedId: ['doc_id_1', 'doc_id_2'],
895
+ // selectedDocs: [{ fd_id: 'doc_id_1', fd_xform_id: 'form_id' }],
896
+ })
897
+ ```
898
+
899
+ #### modalDefine — 对话框
900
+
901
+ ```javascript
902
+ MKXFORM.executeOperation({
903
+ code: 'modalDefine',
904
+ name: '审批',
905
+ id: 'opr_xxx',
906
+ selected: true,
907
+ platform: 'pc'
908
+ }, {
909
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
910
+ selectedId: ['doc_id_1'],
911
+ refresh: function() { /* 刷新列表 */ }
912
+ })
913
+ ```
914
+
915
+ #### other — 自定义操作
916
+
917
+ ```javascript
918
+ MKXFORM.executeOperation({
919
+ code: 'other',
920
+ uniqueCode: 'my_operation',
921
+ platform: 'pc'
922
+ }, {
923
+ fdCode: 'template_xxx',
924
+ fdOpenMode: 'self',
925
+ callback: function(res) { console.log(res) },
926
+ // selectedId: ['doc_id_1'], // operation.selected=true 时必传
927
+ // mechanisms: [], // AI 场景使用
928
+ })
929
+ ```
930
+
931
+ #### instanceClone — 复制新建
932
+
933
+ ```javascript
934
+ MKXFORM.executeOperation({
935
+ code: 'instanceClone',
936
+ platform: 'pc'
937
+ }, {
938
+ baseUrl: '/current/sys-modeling/app/jspanel',
939
+ formId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
940
+ docId: 'doc_xxx',
941
+ // fdRightGroupId: 'xxx',
942
+ // fdOpenMode: 'self',
943
+ // defaultTemplateData: '{}',
944
+ })
945
+ ```
946
+
947
+ ---
948
+
949
+ ### 5.13 `authOperation`
950
+
951
+ **描述:** 业务操作权限校验。用于在执行操作前校验用户是否有执行业务操作的权限,参数与 `executeOperation` 基本一致。
952
+
953
+ **签名:**
954
+ ```typescript
955
+ authOperation(operation: OperationConfig, params: ParamsConfig, callback: (error: any, res: any) => void): Promise<any>
956
+ ```
957
+
958
+ **参数:**
959
+
960
+ | 参数 | 类型 | 说明 |
961
+ |------|------|------|
962
+ | `operation` | `object` | 操作按钮配置(同 `executeOperation` 的 operation 参数) |
963
+ | `params` | `object` | 参数配置(同 `executeOperation` 的 params 参数) |
964
+ | `callback` | `(error, res) => void` | 回调函数。参数 `error` 为错误信息;参数 `res` 为请求数据 |
965
+
966
+ **回调返回值:**
967
+ - 有权限:`error` 为 `null`,`res` 为 `true`
968
+ - 无权限:`error` 为错误信息
969
+
970
+ **注意事项:**
971
+ - 分类表单的 `add` 操作:如果传了 `fdCategoryModelCode`,则 `fdCategoryTemplateId` 必须有值,否则直接 reject
972
+ - 如果未传 `fdXFormId`,会通过 `fdCode` 调用接口获取表单 ID
973
+ - 如果未传 `operation.id`,会通过 `uniqueCode` 调用接口获取操作 ID
974
+
975
+ **使用示例:**
976
+ ```javascript
977
+ MKXFORM.authOperation({
978
+ code: 'add',
979
+ uniqueCode: 'template_p20v4f',
980
+ platform: 'pc'
981
+ }, {
982
+ fdType: 0,
983
+ baseUrl: '/current/sys-modeling/app/jspanel',
984
+ fdXFormId: '1jl8h9edlwrw6v03w1rcbmkp31a3igk2b4w0',
985
+ fdCode: 'template_9vdhbck20tjaoq3ru62xg',
986
+ }, function(error, res) {
987
+ console.log(error, res) // 有权限返回: null true
988
+ })
989
+ ```
990
+
991
+ ---
992
+
993
+ ## 6. 主表函数(functions)
994
+
995
+ > 模块名:`function`,分组:`EApiGroup.all`
996
+
997
+ ### 6.1 `$`
998
+
999
+ **描述:** 根据控件 ID 获取组件实例
1000
+
1001
+ **签名:**
1002
+ ```typescript
1003
+ $(id: string): any | null
1004
+ ```
1005
+
1006
+ **参数:**
1007
+
1008
+ | 参数 | 类型 | 说明 |
1009
+ |------|------|------|
1010
+ | `id` | `string` | 控件 ID |
1011
+
1012
+ **返回值:** 控件对象,未找到返回 `null`。
1013
+
1014
+ **实现细节:**
1015
+ - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1016
+ - 调用 `$$form(MKXFORM)?.$(config.key)` 获取组件实例
1017
+ - 若配置未找到则返回 `null`
1018
+
1019
+ **使用示例:**
1020
+ ```javascript
1021
+ var control = MKXFORM.$('field_id')
1022
+ if (control) {
1023
+ console.log('控件对象', control)
1024
+ }
1025
+ ```
1026
+
1027
+ ---
1028
+
1029
+ ### 6.2 `setValue`
1030
+
1031
+ **描述:** 根据控件 ID 设置值
1032
+
1033
+ **签名:**
1034
+ ```typescript
1035
+ setValue(id: string, value: any): void
1036
+ ```
1037
+
1038
+ **参数:**
1039
+
1040
+ | 参数 | 类型 | 说明 |
1041
+ |------|------|------|
1042
+ | `id` | `string` | 控件 ID,可在数据模型中选中,格式 `[表ID.控件ID]` |
1043
+ | `value` | `any` | 要设置的值。若传入 `undefined` 则自动转为 `null` |
1044
+
1045
+ **实现细节:**
1046
+ - 调用 `$setValue({ form, value: { [id]: v } })` 设置表单值
1047
+ - **明细表/业务内置字段特殊处理**(当 `id` 包含 `.` 时,如 `tableId.fieldId`):
1048
+ - 创建内部对象 `tmpVal`,包含方法:`getKeyValue()`、`getValue()`、`getFullFdName()`、`getFdName()`、`getKey()`、`getTableType()`
1049
+ - 存储到 `MKXFORM.businessFieldsValue[id] = tmpVal`
1050
+ - 触发事件 `mk.emit(EXFromRuntimeDataChange.ExternalFieldsChange, tmpVal)`
1051
+ - 仅数据模型中存在的字段且 key 存在时才存储
1052
+ - **不支持的控件类型:** 明细表、二维码、关联流程、按钮、多表头、文本说明、样例模板、多标签、自定义界面、内嵌页、审批、附件、视频、图片、附件类等
1053
+
1054
+ **使用示例:**
1055
+ ```javascript
1056
+ // 设置普通字段
1057
+ MKXFORM.setValue('field_id', '新值')
1058
+
1059
+ // 设置业务内置字段(会存储到 businessFieldsValue 并触发 ExternalFieldsChange)
1060
+ MKXFORM.setValue('tableId.fieldId', '表格字段值')
1061
+ ```
1062
+
1063
+ ---
1064
+
1065
+ ### 6.3 `getValue`
1066
+
1067
+ **描述:** 根据控件 ID 获取值
1068
+
1069
+ **签名:**
1070
+ ```typescript
1071
+ getValue(id: string): any
1072
+ ```
1073
+
1074
+ **参数:**
1075
+
1076
+ | 参数 | 类型 | 说明 |
1077
+ |------|------|------|
1078
+ | `id` | `string` | 控件 ID |
1079
+
1080
+ **返回值:** 控件当前值。**附件类型特殊处理:** 当控件为 `@elem/xform-attach` 或 `@elem/xform-m-attach` 时,若结果为字符串则返回 `undefined`(表示空状态),否则返回数组格式。
1081
+
1082
+ **不支持的控件类型:** 前端计算、图片、附件、滑块、明细表、多表头、文本描述、模板、多标签页、业务关联、自定义页面、二维码、审批、关联流程、iframe、按钮。
1083
+
1084
+ **使用示例:**
1085
+ ```javascript
1086
+ var value = MKXFORM.getValue('field_id')
1087
+ console.log('当前值', value)
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ### 6.4 `setStyle`
1093
+
1094
+ **描述:** 根据控件 ID 设置样式
1095
+
1096
+ **签名:**
1097
+ ```typescript
1098
+ setStyle(id: string, style: React.CSSProperties, type: 'label' | 'content'): void
1099
+ ```
1100
+
1101
+ **参数:**
1102
+
1103
+ | 参数 | 类型 | 说明 |
1104
+ |------|------|------|
1105
+ | `id` | `string` | 控件 ID |
1106
+ | `style` | `React.CSSProperties` | CSS 样式对象 |
1107
+ | `type` | `'label' \| 'content'` | `label` = 设置标签样式(`labelStyle` 属性);`content` = 设置内容区域样式(`controlValueStyle` 属性) |
1108
+
1109
+ **实现细节:**
1110
+ - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1111
+ - `type='label'` 时调用 `$$form(MKXFORM).updateFormItemProps(config.key, { labelStyle: style })`
1112
+ - `type='content'` 时调用 `$$form(MKXFORM).updateFormItemProps(config.key, { controlValueStyle: style })`
1113
+ - `type` 无效时打印 `console.error` 错误日志
1114
+
1115
+ **使用示例:**
1116
+ ```javascript
1117
+ // 设置标签样式(红色加粗)
1118
+ MKXFORM.setStyle('field_id', { color: 'red', fontWeight: 'bold' }, 'label')
1119
+
1120
+ // 设置内容区域样式
1121
+ MKXFORM.setStyle('field_id', { backgroundColor: '#f0f0f0' }, 'content')
1122
+ ```
1123
+
1124
+ ---
1125
+
1126
+ ### 6.5 `setProps`
1127
+
1128
+ **描述:** 根据控件 ID 设置属性
1129
+
1130
+ **签名:**
1131
+ ```typescript
1132
+ setProps(id: string, props: Record<string, any>): void
1133
+ ```
1134
+
1135
+ **参数:**
1136
+
1137
+ | 参数 | 类型 | 说明 |
1138
+ |------|------|------|
1139
+ | `id` | `string` | 控件 ID |
1140
+ | `props` | `Record<string, any>` | 要设置的属性键值对,支持以下所有属性 |
1141
+
1142
+ **实现细节:**
1143
+ - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1144
+ - 调用 `$$form(MKXFORM)?.updateFormItemProps(config.key, props)` 更新控件属性
1145
+ - 支持设置任意控件属性,底层通过 FIBRE 架构合并到 `item.props`
1146
+ - 若设置 `value` 属性,会通过 `item.props.onChange(value, 'code')` 触发表单机制修改,而非直接赋值
1147
+ - 若设置 `onBlur` 事件,会特殊处理以避免覆盖内部 blur 逻辑
1148
+ - 若设置 `labelProps` 嵌套对象,会同步更新控件标签属性
1149
+ - 修改会同步到简易配置(`flatSimpleFormConfig`)中
1150
+
1151
+ **支持的属性清单:**
1152
+
1153
+ #### 控件属性 (Control Props)
1154
+
1155
+ | 属性名 | 类型 | 说明 |
1156
+ |--------|------|------|
1157
+ | `value` | `any` | 控件值(通过 onChange 机制触发更新) |
1158
+ | `hidden` | `boolean` | 控件隐藏/显示 |
1159
+ | `_hidden` | `boolean` | 内部隐藏标记 |
1160
+ | `showStatus` | `'edit' \| 'readOnly' \| 'view' \| 'print'` | 控件状态(编辑/只读/查看/打印) |
1161
+ | `disabled` | `boolean` | 禁用配置区表单项 |
1162
+ | `parentHidden` | `boolean` | 父级控件隐藏状态通知子级 |
1163
+ | `trace` | `any` | 追踪信息 |
1164
+ | `traceData` | `any` | 追踪数据 |
1165
+ | `dependenciesValue` | `object` | 依赖项的值 |
1166
+ | `title` | `string` | 控件标题 |
1167
+ | `controlValueStyle` | `CSSProperties` | 控件内容区域样式 |
1168
+ | `updateTimer` | `string` | 触发 tab 子项重新渲染的标记 |
1169
+ | `__force_update__` | `number` | 强制更新计数器 |
1170
+
1171
+ #### 标签属性 (Label Props) — 嵌套在 `labelProps` 对象内
1172
+
1173
+ | 属性名 | 类型 | 说明 |
1174
+ |--------|------|------|
1175
+ | `labelProps.hidden` | `boolean` | 标签隐藏/显示 |
1176
+ | `labelProps.required` | `boolean` | 标签必填标记(红色星号) |
1177
+ | `labelProps.labelStyle` | `CSSProperties` | 标签样式 |
1178
+ | `labelProps.labelSuffix` | `ReactNode` | 标签后缀内容 |
1179
+ | `labelProps.title` | `string` | 标签标题文本 |
1180
+
1181
+ #### 明细表属性 (Detail Table Props)
1182
+
1183
+ | 属性名 | 类型 | 说明 |
1184
+ |--------|------|------|
1185
+ | `hiddenNames` | `string[] \| undefined` | 指定隐藏的明细字段名列表 |
1186
+ | `modifyNames` | `string[]` | 已修改的明细字段名列表 |
1187
+ | `requireNames` | `Array<{name, required, tip}>` | 明细表字段必填规则 |
1188
+ | `rowNumStyles` | `object` | 按行号设置明细控件样式 |
1189
+ | `canDeleteRow` | `boolean` | 明细行是否可删除 |
1190
+ | `canDeleteRowObj` | `{rowNum, canDeleteRow}` | 指定行号的可删除状态 |
1191
+ | `rowValue` | `{rowNum, value}` | 明细表行数据联动更新 |
1192
+ | `columns` | `array` | 明细表列定义配置 |
1193
+
1194
+ #### 布局属性 (Layout Props)
1195
+
1196
+ | 属性名 | 类型 | 说明 |
1197
+ |--------|------|------|
1198
+ | `spans` | `number[]` | 布局列宽分配数组(24 栅格) |
1199
+ | `column` | `number` | 布局列数 |
1200
+ | `columnSpan` | `number` | 列跨度 |
1201
+ | `columns` | `array` | 列配置数组 |
1202
+ | `layout` | `string` | 布局模式 |
1203
+ | `desktopPaddingMode` | `'standard' \| ...` | 桌面端内边距模式 |
1204
+
1205
+ #### 校验属性 (Validation Props)
1206
+
1207
+ | 属性名 | 类型 | 说明 |
1208
+ |--------|------|------|
1209
+ | `errors` | `IError[]` | 校验错误信息列表 |
1210
+ | `error` | `IError` | 单个校验错误 |
1211
+ | `force` | `number` | 强制校验触发标记(通常传随机数) |
1212
+
1213
+ #### 样式属性 (Style Props)
1214
+
1215
+ | 属性名 | 类型 | 说明 |
1216
+ |--------|------|------|
1217
+ | `style` | `CSSProperties` | 控件样式对象 |
1218
+ | `controlValueStyle` | `CSSProperties` | 控件值区域样式 |
1219
+ | `rowNumStyles` | `object` | 明细表按行号样式 |
1220
+ | `tabTitleStyle` | `CSSProperties` | Tab 标题样式 |
1221
+ | `tabBarStyle` | `CSSProperties` | Tab 栏样式 |
1222
+ | `controlTitleStyle` | `CSSProperties` | Steps/控件标题样式 |
1223
+
1224
+ #### Tab/Steps/Collapse 专用属性
1225
+
1226
+ | 属性名 | 类型 | 说明 |
1227
+ |--------|------|------|
1228
+ | `tabTitleStyle` | `CSSProperties` | Tab 标题样式 |
1229
+ | `tabBarStyle` | `CSSProperties` | Tab 栏样式 |
1230
+ | `controlTitleStyle` | `CSSProperties` | Steps 标题样式 |
1231
+ | `visible` | `boolean` | Collapse 可见性 |
1232
+
1233
+ **使用示例:**
1234
+ ```javascript
1235
+ // 设置普通属性
1236
+ MKXFORM.setProps('field_id', { placeholder: '请输入', maxLength: 100, disabled: true })
1237
+
1238
+ // 设置标签属性
1239
+ MKXFORM.setProps('field_id', {
1240
+ labelProps: {
1241
+ hidden: false,
1242
+ required: true,
1243
+ labelStyle: { color: 'red' }
1244
+ }
1245
+ })
1246
+
1247
+ // 设置样式
1248
+ MKXFORM.setProps('field_id', {
1249
+ style: { backgroundColor: '#f0f0f0' },
1250
+ controlValueStyle: { fontSize: '14px' }
1251
+ })
1252
+
1253
+ // 设置布局
1254
+ MKXFORM.setProps('field_id', { spans: [12, 12] })
1255
+
1256
+ // 设置明细表属性
1257
+ MKXFORM.setProps('detailTable', {
1258
+ canDeleteRow: false,
1259
+ hiddenNames: ['internalField1', 'internalField2']
1260
+ })
1261
+ ```
1262
+ ---
1263
+
1264
+ ### 6.6 `getFieldAttr`
1265
+
1266
+ **描述:** 获取字段当前的只读/必填/隐藏等显示属性
1267
+
1268
+ **签名:**
1269
+ ```typescript
1270
+ getFieldAttr(id: string): number
1271
+ ```
1272
+
1273
+ **参数:**
1274
+
1275
+ | 参数 | 类型 | 说明 |
1276
+ |------|------|------|
1277
+ | `id` | `string` | 控件 ID |
1278
+
1279
+ **返回值:**
1280
+
1281
+ | 返回值 | 含义 | 判断逻辑 |
1282
+ |--------|------|----------|
1283
+ | `1` | 只读(readOnly) | `showStatus` 为只读 |
1284
+ | `2` | 可编辑(editable) | 非只读且非必填 |
1285
+ | `3` | 必填(required) | `validateRules` 存在必填规则或 `required/require` 为 true |
1286
+ | `4` | 隐藏(hidden) | `showStatus` 为隐藏或 `labelProps.hidden` 为 true |
1287
+
1288
+ **实现细节:**
1289
+ - 通过 `getConfig(id, MKXFORM)` 获取控件配置
1290
+ - 检查优先级:隐藏 → 只读 → 必填 → 可编辑
1291
+
1292
+ **使用示例:**
1293
+ ```javascript
1294
+ var attr = MKXFORM.getFieldAttr('field_id')
1295
+ if (attr === 1) {
1296
+ console.log('该字段当前为只读')
1297
+ } else if (attr === 3) {
1298
+ console.log('该字段当前为必填')
1299
+ }
1300
+ ```
1301
+
1302
+ ---
1303
+
1304
+ ### 6.7 `setFieldAttr`
1305
+
1306
+ **描述:** 改变单个字段的显示属性(只读/必填/隐藏等)
1307
+
1308
+ **签名:**
1309
+ ```typescript
1310
+ setFieldAttr(id: string, value: number): void
1311
+ ```
1312
+
1313
+ **参数:**
1314
+
1315
+ | 参数 | 类型 | 说明 |
1316
+ |------|------|------|
1317
+ | `id` | `string` | 控件 ID |
1318
+ | `value` | `number` | 属性值(见下表) |
1319
+
1320
+ **value 取值:**
1321
+
1322
+ | 值 | 含义 | 实现逻辑 |
1323
+ | --- | ----- | -------------------------------------------------------------------- |
1324
+ | `1` | 设为只读 | 设置 `showStatus` 为 readOnly。若 `extraAuth.required === false`,则覆盖校验为通过 |
1325
+ | `2` | 设为可编辑 | 设置 `showStatus` 为 editable。通过 `view2edit` 辅助函数检查是否可从只读转为编辑 |
1326
+ | `3` | 设为必填 | 先设为可编辑,再添加必填规则。兼容 `required` 和 `require` 两种属性名 |
1327
+ | `4` | 隐藏 | 隐藏字段标签及内容 |
1328
+ | `5` | 显示 | 取消隐藏,恢复字段可见性 |
1329
+ | `6` | 设为非必填 | 移除 `required` 和 `require` 标记,清除必填校验规则 |
1330
+ | | | |
1331
+
1332
+ **实现细节:**
1333
+ - 使用 `cloneDeep` 深拷贝规则对象,避免直接修改原始引用
1334
+ - 所有更新通过 `$$form(MKXFORM).updateFormItemProps(config.key, { ... })` 应用
1335
+ - 传入 `{ withoutValidate: true }` 标志,跳过额外校验
1336
+ - `value` 不在 `[1,2,3,4,5,6]` 范围内时抛出异常
1337
+ - `view2edit(showStatus, editable)` 辅助函数检查是否允许从只读转为编辑
1338
+
1339
+ **使用示例:**
1340
+ ```javascript
1341
+ // 设为只读
1342
+ MKXFORM.setFieldAttr('field_id', 1)
1343
+
1344
+ // 设为必填
1345
+ MKXFORM.setFieldAttr('field_id', 3)
1346
+
1347
+ // 隐藏字段
1348
+ MKXFORM.setFieldAttr('field_id', 4)
1349
+
1350
+ // 取消隐藏
1351
+ MKXFORM.setFieldAttr('field_id', 5)
1352
+
1353
+ // 设为非必填
1354
+ MKXFORM.setFieldAttr('field_id', 6)
1355
+ ```
1356
+
1357
+ ---
1358
+
1359
+ ### 6.8 `getValueText`
1360
+
1361
+ **描述:** 根据控件 ID 获取显示文本(而非原始值),如下拉框返回选项文本而非值
1362
+
1363
+ **签名:**
1364
+ ```typescript
1365
+ getValueText(id: string): string
1366
+ ```
1367
+
1368
+ **参数:**
1369
+
1370
+ | 参数 | 类型 | 说明 |
1371
+ |------|------|------|
1372
+ | `id` | `string` | 控件 ID |
1373
+
1374
+ **返回值:** 控件的显示文本字符串。
1375
+
1376
+ **实现细节:**
1377
+ - 将 `id` 按 `.` 分割,取第二部分(`ids[1]`)作为控件名
1378
+ - 通过 `$$controlRef(MKXFORM)?.[ids[1]]?.current?.getValueText(id)` 获取显示文本
1379
+ - 若控件引用不存在则返回 `undefined`
1380
+
1381
+ **使用示例:**
1382
+ ```javascript
1383
+ var displayText = MKXFORM.getValueText('field_id')
1384
+ console.log('显示文本', displayText) // 如下拉框显示 "选项一" 而非 "value1"
1385
+ ```
1386
+
1387
+ ---
1388
+
1389
+ ### 6.9 `getControlHtml`
1390
+
1391
+ **描述:** 获取控件带样式的 HTML 字符串
1392
+
1393
+ **签名:**
1394
+ ```typescript
1395
+ getControlHtml(id: string): string
1396
+ ```
1397
+
1398
+ **参数:**
1399
+
1400
+ | 参数 | 类型 | 说明 |
1401
+ |------|------|------|
1402
+ | `id` | `string` | 控件 ID |
1403
+
1404
+ **返回值:** 包含内联样式的 HTML 字符串。
1405
+
1406
+ **实现细节:**
1407
+ 1. 通过 `document.querySelector` 查找控件 DOM 节点(优先使用 `uuid`,降级使用 `currentId`)
1408
+ 2. 深拷贝 DOM 节点(`cloneNode(true)`)
1409
+ 3. 临时追加到 `document.body`
1410
+ 4. 调用 `formatHmtl(id)` 格式化:
1411
+ - 递归将计算样式转为内联样式(`inlineStyles`)
1412
+ - 特殊处理审批控件(`@elem/xform-review`):移除展开/收起按钮、操作包裹、附件背景等
1413
+ - 清理附件额外信息节点
1414
+ - 将批注内容转为带对齐方式的 span 元素
1415
+ 5. 提取 `innerHTML`
1416
+ 6. 100ms 后移除克隆节点
1417
+
1418
+ **使用示例:**
1419
+ ```javascript
1420
+ var html = MKXFORM.getControlHtml('field_id')
1421
+ console.log('控件HTML', html)
1422
+ ```
1423
+
1424
+ ---
1425
+
1426
+ ## 7. 明细表函数(details)
1427
+
1428
+ > 模块名:`detail`,分组:`EApiGroup.all`
1429
+ >
1430
+ > 明细表函数中的 `id` 参数通常使用 `tableId.controlId` 格式表示明细表中的某个字段。
1431
+
1432
+ ### 7.1 `getControlValue`
1433
+
1434
+ **描述:** 获取明细表指定行的指定控件值
1435
+
1436
+ **签名:**
1437
+ ```typescript
1438
+ getControlValue(id: string, rowNum: number): any
1439
+ ```
1440
+
1441
+ **参数:**
1442
+
1443
+ | 参数 | 类型 | 说明 |
1444
+ |------|------|------|
1445
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId`。按 `.` 分割,第一部分为明细表 ID |
1446
+ | `rowNum` | `number` | 行号(从 0 开始) |
1447
+
1448
+ **实现细节:**
1449
+ - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1450
+ - 调用 `$$detailForms(MKXFORM)?.[key].current?.getCurrentValues()[rowNum][id]`
1451
+ - 若明细表不存在或行号越界,返回 `undefined`
1452
+
1453
+ **使用示例:**
1454
+ ```javascript
1455
+ var value = MKXFORM.getControlValue('detailTable.amount', 0)
1456
+ console.log('第一行的金额', value)
1457
+ ```
1458
+
1459
+ ---
1460
+
1461
+ ### 7.2 `updateControl`
1462
+
1463
+ **描述:** 更新明细表指定行的指定控件值
1464
+
1465
+ **签名:**
1466
+ ```typescript
1467
+ updateControl(id: string, rowNum: number, value: any): void
1468
+ ```
1469
+
1470
+ **参数:**
1471
+
1472
+ | 参数 | 类型 | 说明 |
1473
+ |------|------|------|
1474
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1475
+ | `rowNum` | `number` | 行号(从 0 开始) |
1476
+ | `value` | `any` | 要设置的值 |
1477
+
1478
+ **实现细节:**
1479
+ - **防抖批量更新机制:** 使用 `window['MXFORM_updateControl']` 作为缓存对象,100ms `setTimeout` 延迟执行
1480
+ - 多次调用会累积到同一个更新批次中
1481
+ - 执行时:克隆当前行数据 → 合并新值 → 调用 `detailRef.setTinyValues()` → 调用 `detailRef.updateValues()`
1482
+ - 执行完成后 300ms 清空 `tinyValues` 缓存,并重置缓存对象
1483
+ - 若 ID 信息缺失,打印 `console.error` 错误日志
1484
+
1485
+ **使用示例:**
1486
+ ```javascript
1487
+ // 以下两次调用会合并为一个批量更新
1488
+ MKXFORM.updateControl('detailTable.amount', 0, 1000)
1489
+ MKXFORM.updateControl('detailTable.name', 0, '张三')
1490
+ ```
1491
+
1492
+ ---
1493
+
1494
+ ### 7.3 `updateControlStyle`
1495
+
1496
+ **描述:** 更新明细表指定行的指定控件样式
1497
+
1498
+ **签名:**
1499
+ ```typescript
1500
+ updateControlStyle(id: string, rowNum: number, style: React.CSSProperties): void
1501
+ ```
1502
+
1503
+ **参数:**
1504
+
1505
+ | 参数 | 类型 | 说明 |
1506
+ |------|------|------|
1507
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1508
+ | `rowNum` | `number` | 行号(从 0 开始) |
1509
+ | `style` | `React.CSSProperties` | CSS 样式对象 |
1510
+
1511
+ **实现细节:**
1512
+ - **防抖批量更新机制:** 使用 `window['MXFORM_updateControlStyles']` 作为缓存对象,100ms `setTimeout` 延迟执行
1513
+ - 调用 `$$form(MKXFORM)?.updateFormItemProps(config.key, { rowNumStyles: tables })` 应用样式
1514
+ - 仅支持 PC 端
1515
+ - 仅支持只读控件:单行文本、多行文本、日期、通讯录、金额、数字、单选、复选、下拉、多选、滑块、开关
1516
+
1517
+ **使用示例:**
1518
+ ```javascript
1519
+ MKXFORM.updateControlStyle('detailTable.amount', 0, { color: 'red', fontWeight: 'bold' })
1520
+ ```
1521
+
1522
+ ---
1523
+
1524
+ ### 7.4 `addRow`
1525
+
1526
+ **描述:** 新增明细表行
1527
+
1528
+ **签名:**
1529
+ ```typescript
1530
+ addRow(id: string, rowValue?: Record<string, any> | Record<string, any>[]): void
1531
+ ```
1532
+
1533
+ **参数:**
1534
+
1535
+ | 参数 | 类型 | 说明 |
1536
+ |------|------|------|
1537
+ | `id` | `string` | 明细表 ID |
1538
+ | `rowValue`(可选) | `object \| object[]` | 行数据。对象为单行,数组为多行。不传默认添加一行空行 `[{}]` |
1539
+
1540
+ **实现细节:**
1541
+ - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1542
+ - 获取当前值 `detailRef.getCurrentValues()`
1543
+ - 若 `rowValue` 为数组,遍历 `push` 所有项
1544
+ - 若 `rowValue` 为对象,`push` 单个对象
1545
+ - 若未传 `rowValue`,默认添加 `[{}]`(一行空行)
1546
+ - 最后调用 `detailRef.updateValues(newValues)`
1547
+
1548
+ **使用示例:**
1549
+ ```javascript
1550
+ // 添加一行空行
1551
+ MKXFORM.addRow('detailTable')
1552
+
1553
+ // 添加一行带数据
1554
+ MKXFORM.addRow('detailTable', { name: '张三', amount: 100 })
1555
+
1556
+ // 批量添加多行
1557
+ MKXFORM.addRow('detailTable', [
1558
+ { name: '张三', amount: 100 },
1559
+ { name: '李四', amount: 200 }
1560
+ ])
1561
+ ```
1562
+
1563
+ ---
1564
+
1565
+ ### 7.5 `updateRow`
1566
+
1567
+ **描述:** 更新明细表指定行数据
1568
+
1569
+ **签名:**
1570
+ ```typescript
1571
+ updateRow(id: string, rowNum: number, rowValue: Record<string, any> | Record<string, any>[]): void
1572
+ ```
1573
+
1574
+ **参数:**
1575
+
1576
+ | 参数 | 类型 | 说明 |
1577
+ |------|------|------|
1578
+ | `id` | `string` | 明细表 ID |
1579
+ | `rowNum` | `number` | 起始行号(从 0 开始) |
1580
+ | `rowValue` | `object \| object[]` | 若为对象则通过 `Object.assign` 合并到指定行;若为数组则从 `rowNum` 开始逐个替换多行 |
1581
+
1582
+ **实现细节:**
1583
+ - `rowValue` 为数组时:从 `rowNum` 开始,用 `Object.assign` 逐个替换后续行
1584
+ - `rowValue` 为对象时:用 `Object.assign(values[rowNum], rowValue)` 合并到指定行
1585
+ - 最后调用 `detailRef.updateValues(values)`
1586
+
1587
+ **使用示例:**
1588
+ ```javascript
1589
+ // 更新单行(合并属性)
1590
+ MKXFORM.updateRow('detailTable', 0, { amount: 500 })
1591
+
1592
+ // 替换多行(从第 0 行开始替换为以下两行)
1593
+ MKXFORM.updateRow('detailTable', 0, [
1594
+ { name: '王五', amount: 300 },
1595
+ { name: '赵六', amount: 400 }
1596
+ ])
1597
+ ```
1598
+
1599
+ ---
1600
+
1601
+ ### 7.6 `deleteRow`
1602
+
1603
+ **描述:** 删除明细表行
1604
+
1605
+ **签名:**
1606
+ ```typescript
1607
+ deleteRow(id: string, rowNum?: number | number[] | ''): void
1608
+ ```
1609
+
1610
+ **参数:**
1611
+
1612
+ | 参数 | 类型 | 说明 |
1613
+ |------|------|------|
1614
+ | `id` | `string` | 明细表 ID |
1615
+ | `rowNum` | `number \| number[] \| ''`(可选) | 删除方式(见下表) |
1616
+
1617
+ **rowNum 取值:**
1618
+
1619
+ | 值 | 说明 | 实现逻辑 |
1620
+ |----|------|----------|
1621
+ | 省略 | 删除所有行 | 调用 `detailRef.deleteAll()` |
1622
+ | `''` | 删除所有行 | 调用 `detailRef.deleteAll()` |
1623
+ | `number` | 删除指定行号的一行 | 获取该行值,调用 `detailRef.deleteRow(values, deleteIds, deleteValues)` |
1624
+ | `number[]` | 删除多个指定行号(如 `[0, 2, 4]`) | 遍历收集 `deleteIds` 和 `deleteValues`,调用 `detailRef.deleteRow()` |
1625
+
1626
+ **实现细节:**
1627
+ - 删除时同时收集被删除行的 ID(`deleteIds`)和值(`deleteValues`)传给底层方法
1628
+
1629
+ **使用示例:**
1630
+ ```javascript
1631
+ // 删除第 2 行
1632
+ MKXFORM.deleteRow('detailTable', 1)
1633
+
1634
+ // 删除第 1、3、5 行
1635
+ MKXFORM.deleteRow('detailTable', [0, 2, 4])
1636
+
1637
+ // 删除所有行
1638
+ MKXFORM.deleteRow('detailTable')
1639
+ MKXFORM.deleteRow('detailTable', '')
1640
+ ```
1641
+
1642
+ ---
1643
+
1644
+ ### 7.7 `getRowCount`
1645
+
1646
+ **描述:** 获取明细表总行数
1647
+
1648
+ **签名:**
1649
+ ```typescript
1650
+ getRowCount(id: string): number
1651
+ ```
1652
+
1653
+ **参数:**
1654
+
1655
+ | 参数 | 类型 | 说明 |
1656
+ |------|------|------|
1657
+ | `id` | `string` | 明细表 ID |
1658
+
1659
+ **返回值:** 明细表总行数。
1660
+
1661
+ **注意:** 不能在表单 `onLoad` 中调用(此时明细表可能尚未初始化)。
1662
+
1663
+ **实现细节:**
1664
+ - 调用 `detailRef.getDataLength()`
1665
+
1666
+ **使用示例:**
1667
+ ```javascript
1668
+ var count = MKXFORM.getRowCount('detailTable')
1669
+ console.log('明细表共有 ' + count + ' 行')
1670
+ ```
1671
+
1672
+ ---
1673
+
1674
+ ### 7.8 `getSelectedRowIndex`
1675
+
1676
+ **描述:** 获取明细表选中行的下标数组
1677
+
1678
+ **签名:**
1679
+ ```typescript
1680
+ getSelectedRowIndex(id: string): number[]
1681
+ ```
1682
+
1683
+ **参数:**
1684
+
1685
+ | 参数 | 类型 | 说明 |
1686
+ |------|------|------|
1687
+ | `id` | `string` | 明细表 ID |
1688
+
1689
+ **返回值:** 选中行下标数组(如 `[0, 2, 5]`)。
1690
+
1691
+ **使用示例:**
1692
+ ```javascript
1693
+ var selectedRows = MKXFORM.getSelectedRowIndex('detailTable')
1694
+ console.log('选中行', selectedRows)
1695
+ ```
1696
+
1697
+ ---
1698
+
1699
+ ### 7.9 `checkDetailRow`
1700
+
1701
+ **描述:** 选中明细表指定行
1702
+
1703
+ **签名:**
1704
+ ```typescript
1705
+ checkDetailRow(id: string, indexArr: number[]): void
1706
+ ```
1707
+
1708
+ **参数:**
1709
+
1710
+ | 参数 | 类型 | 说明 |
1711
+ |------|------|------|
1712
+ | `id` | `string` | 明细表 ID |
1713
+ | `indexArr` | `number[]` | 要选中的行号数组 |
1714
+
1715
+ **注意:** 不支持移动端。
1716
+
1717
+ **使用示例:**
1718
+ ```javascript
1719
+ // 选中第 1、3 行
1720
+ MKXFORM.checkDetailRow('detailTable', [0, 2])
1721
+ ```
1722
+
1723
+ ---
1724
+
1725
+ ### 7.10 `controlDetailRowCanDelete`
1726
+
1727
+ **描述:** 控制明细行是否可删除
1728
+
1729
+ **签名:**
1730
+ ```typescript
1731
+ controlDetailRowCanDelete(id: string, canDeleteRow: boolean, rowNum?: number | number[]): void
1732
+ ```
1733
+
1734
+ **参数:**
1735
+
1736
+ | 参数 | 类型 | 说明 |
1737
+ |------|------|------|
1738
+ | `id` | `string` | 明细表 ID |
1739
+ | `canDeleteRow` | `boolean` | 是否允许删除 |
1740
+ | `rowNum`(可选) | `number \| number[]` | 指定行号。省略则对整个明细表生效 |
1741
+
1742
+ **注意:** 仅支持 PC 端。
1743
+
1744
+ **使用示例:**
1745
+ ```javascript
1746
+ // 禁用整个明细表的删除
1747
+ MKXFORM.controlDetailRowCanDelete('detailTable', false)
1748
+
1749
+ // 仅禁用第 2 行的删除
1750
+ MKXFORM.controlDetailRowCanDelete('detailTable', false, 1)
1751
+
1752
+ // 禁用第 1、3 行的删除
1753
+ MKXFORM.controlDetailRowCanDelete('detailTable', false, [0, 2])
1754
+
1755
+ // 启用整个明细表的删除
1756
+ MKXFORM.controlDetailRowCanDelete('detailTable', true)
1757
+ ```
1758
+
1759
+ ---
1760
+
1761
+ ### 7.11 `cacluColumnValue`
1762
+
1763
+ **描述:** 计算明细表某列的最大值、最小值和平均值
1764
+
1765
+ **签名:**
1766
+ ```typescript
1767
+ cacluColumnValue(id: string): { max: number, min: number, average: number }
1768
+ ```
1769
+
1770
+ **参数:**
1771
+
1772
+ | 参数 | 类型 | 说明 |
1773
+ |------|------|------|
1774
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1775
+
1776
+ **返回值:**
1777
+
1778
+ | 字段 | 类型 | 说明 |
1779
+ |------|------|------|
1780
+ | `max` | `number` | 列最大值 |
1781
+ | `min` | `number` | 列最小值 |
1782
+ | `average` | `number` | 列平均值 |
1783
+
1784
+ **实现细节:**
1785
+ - 通过 `getKeyByName(id, MKXFORM)` 获取明细表 key
1786
+ - 调用 `detailRef.getCurrentValues()` 获取所有行数据
1787
+ - 提取指定列的所有值,过滤空值后计算 `Math.max`、`Math.min` 和平均值
1788
+ - 无数据或列不存在时打印 `console.error` 并返回 `{ max: 0, min: 0, average: 0 }`
1789
+
1790
+ **使用示例:**
1791
+ ```javascript
1792
+ var result = MKXFORM.cacluColumnValue('detailTable.amount')
1793
+ console.log('最大值', result.max)
1794
+ console.log('最小值', result.min)
1795
+ console.log('平均值', result.average)
1796
+ ```
1797
+
1798
+ ---
1799
+
1800
+ ### 7.12 `getPageControlValue`
1801
+
1802
+ **描述:** 获取当前分页中指定行的指定控件值
1803
+
1804
+ **签名:**
1805
+ ```typescript
1806
+ getPageControlValue(id: string, rowNum: number): any
1807
+ ```
1808
+
1809
+ **参数:**
1810
+
1811
+ | 参数 | 类型 | 说明 |
1812
+ | -------- | -------- | ----------------------------- |
1813
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1814
+ | `rowNum` | `number` | 当前分页内的行号(从 0 开始) |
1815
+
1816
+ **注意:** 仅支持 PC 端。与 `getControlValue` 的区别在于使用 `getPageCurrentValues()` 而非 `getCurrentValues()`,仅获取当前分页的数据。
1817
+
1818
+ **使用示例:**
1819
+ ```javascript
1820
+ var value = MKXFORM.getPageControlValue('detailTable.amount', 0)
1821
+ ```
1822
+
1823
+ ---
1824
+
1825
+ ### 7.13 `setDetailFieldAttr`
1826
+
1827
+ **描述:** 改变明细表单个字段列的显示属性(只读/必填/隐藏等)
1828
+
1829
+ **签名:**
1830
+ ```typescript
1831
+ setDetailFieldAttr(id: string, value: number): void
1832
+ ```
1833
+
1834
+ **参数:**
1835
+
1836
+ | 参数 | 类型 | 说明 |
1837
+ | ------- | -------- | ----------------------------- |
1838
+ | `id` | `string` | 字段 ID,格式为 `tableId.controlId` |
1839
+ | `value` | `number` | 属性值(见下表) |
1840
+
1841
+ **value 取值:**
1842
+
1843
+ | 值 | 含义 |
1844
+ | --- | ---------------------- |
1845
+ | `1` | 设为只读 |
1846
+ | `2` | 设为可编辑(遵循 view2edit 规则) |
1847
+ | `3` | 设为必填 |
1848
+ | `4` | 隐藏(标签和内容) |
1849
+ | `5` | 显示(取消隐藏) |
1850
+ | `6` | 设为非必填 |
1851
+
1852
+ **实现细节:**
1853
+ - 使用 `cloneDeep` 深拷贝明细表字段的 `columns` 配置对象,避免直接修改原始引用
1854
+ - 通过 `getKeyByName(id, MKXFORM)` 解析 ID,获取明细表 key 和字段名
1855
+ - 在明细表的 `columns` 数组中查找目标列
1856
+ - 通过 `$$form(MKXFORM).updateFormItemProps(key, { columns: newColumns })` 应用更新
1857
+ - `value` 不在 `[1,2,3,4,5,6]` 范围内时抛出异常
1858
+ - ID 格式无效(不含 `.`)时打印 `console.error` 并返回
1859
+ - 使用与 `setFieldAttr` 相同的 `view2edit` 辅助函数检查是否可从只读转为编辑
1860
+
1861
+ **使用示例:**
1862
+ ```javascript
1863
+ // 将明细表金额列设为只读
1864
+ MKXFORM.setDetailFieldAttr('detailTable.amount', 1)
1865
+
1866
+ // 将明细表金额列设为必填
1867
+ MKXFORM.setDetailFieldAttr('detailTable.amount', 3)
1868
+ ```
1869
+
1870
+ ---
1871
+
1872
+ ### 7.14 `setDetailRowAttr`
1873
+
1874
+ **描述:** 改变明细表指定行的显示属性
1875
+
1876
+ **签名:**
1877
+ ```typescript
1878
+ setDetailRowAttr(id: string, value: number, rowNum: number, fieldId?: string): void
1879
+ ```
1880
+
1881
+ **参数:**
1882
+
1883
+ | 参数 | 类型 | 说明 |
1884
+ | ------------- | -------- | ---------------------------------------- |
1885
+ | `id` | `string` | 明细表 ID |
1886
+ | `value` | `number` | 属性值(1~6,同 `setFieldAttr`) |
1887
+ | `rowNum` | `number` | 行号(从 0 开始) |
1888
+ | `fieldId`(可选) | `string` | 指定字段 ID。省略则对整行生效,格式为 `tableId.controlId` |
1889
+
1890
+ **value 取值:** 同 `setFieldAttr`(1=只读, 2=可编辑, 3=必填, 4=隐藏, 5=显示, 6=非必填)
1891
+
1892
+ **实现细节:**
1893
+ - 委托给 `detailRef?.setRowAttr(value, rowNum, fieldId)` 执行
1894
+ - `value` 不在 1~6 范围内时抛出异常
1895
+ - `rowNum` 无效时打印 `console.error` 并返回
1896
+
1897
+ **使用示例:**
1898
+ ```javascript
1899
+ // 第 2 行整行设为只读
1900
+ MKXFORM.setDetailRowAttr('detailTable', 1, 1)
1901
+
1902
+ // 第 2 行的金额列设为必填
1903
+ MKXFORM.setDetailRowAttr('detailTable', 3, 1, 'detailTable.amount')
1904
+ ```
1905
+
1906
+ ---
1907
+
1908
+ ### 7.15 `setDetailFieldItemAttr`
1909
+
1910
+ **描述:** 改变明细表指定行指定字段的显示属性
1911
+
1912
+ **签名:**
1913
+ ```typescript
1914
+ setDetailFieldItemAttr(id: string, value: number, rowKey: number, fieldId?: string): void
1915
+ ```
1916
+
1917
+ **参数:**
1918
+
1919
+ | 参数 | 类型 | 说明 |
1920
+ | ------------- | -------- | -------------------------------------- |
1921
+ | `id` | `string` | 明细表 ID |
1922
+ | `value` | `number` | 属性值(1~6) |
1923
+ | `rowKey` | `number` | 行 key |
1924
+ | `fieldId`(可选) | `string` | 字段 ID。省略则对整行生效,格式为 `tableId.controlId` |
1925
+
1926
+ **value 取值:** 同 `setFieldAttr`(1~6)。
1927
+
1928
+ **实现细节:**
1929
+ - 使用 `getKeyByName` 而非 `getConfig` 来获取明细表 key
1930
+ - 委托给 `detailRef.setRowAttr(value, rowKey, fieldId)` 执行
1931
+ - 与 `setDetailRowAttr` 的区别在于使用 `rowKey`(行的唯一 key)而非 `rowNum`(行号)
1932
+
1933
+ **使用示例:**
1934
+ ```javascript
1935
+ // 第 2 行金额列设为只读
1936
+ MKXFORM.setDetailFieldItemAttr('detailTable', 1, 1, 'detailTable.amount')
1937
+
1938
+ // 第 2 行整行设为必填
1939
+ MKXFORM.setDetailFieldItemAttr('detailTable', 3, 1)
1940
+ ```
1941
+
1942
+ ---
1943
+
1944
+ ### 7.16 `reload`
1945
+
1946
+ **描述:** 重新加载明细表数据
1947
+
1948
+ **签名:**
1949
+ ```typescript
1950
+ reload(id: string): void
1951
+ ```
1952
+
1953
+ **参数:**
1954
+
1955
+ | 参数 | 类型 | 说明 |
1956
+ |------|------|------|
1957
+ | `id` | `string` | 明细表 ID |
1958
+
1959
+ **注意:** 不支持移动端。
1960
+
1961
+ **实现细节:**
1962
+ - 直接委托给 `detailRef?.reload()` 执行
1963
+
1964
+ **使用示例:**
1965
+ ```javascript
1966
+ MKXFORM.reload('detailTable')
1967
+ ```
1968
+
1969
+ ---
1970
+
1971
+ ### 7.17 `disabledOperation`
1972
+
1973
+ **描述:** 禁用明细表操作按钮
1974
+
1975
+ **签名:**
1976
+ ```typescript
1977
+ disabledOperation(id: string, limitList: Array<string> | boolean, rowNum?: number): void
1978
+ ```
1979
+
1980
+ **参数:**
1981
+
1982
+ | 参数 | 类型 | 说明 |
1983
+ |------|------|------|
1984
+ | `id` | `string` | 明细表 ID |
1985
+ | `limitList` | `Array<string> \| boolean` | 要禁用的操作名数组,或 `false` 禁用所有 |
1986
+ | `rowNum`(可选) | `number` | 指定行号。省略则对整个明细表生效 |
1987
+
1988
+ **可禁用的操作名:**
1989
+
1990
+ | 操作名 | 说明 |
1991
+ |--------|------|
1992
+ | `'edit'` | 编辑 |
1993
+ | `'insert'` | 插入行 |
1994
+ | `'addNest'` | 添加子表行 |
1995
+ | `'copy'` | 复制行 |
1996
+ | `'delete'` | 删除行 |
1997
+ | `'viewDetail'` | 查看详情 |
1998
+ | `'isTrace'` | 追踪 |
1999
+
2000
+ **实现细节:**
2001
+ - `limitList` 可为数组 `['edit','insert','addNest','copy','delete','viewDetail','isTrace']` 指定禁用操作,或传 `false` 禁用所有操作
2002
+ - 委托给 `detailRef.disabledOperation(limitList, rowNum)` 执行
2003
+
2004
+ **注意:** 不支持移动端。
2005
+
2006
+ **使用示例:**
2007
+ ```javascript
2008
+ // 禁用所有操作
2009
+ MKXFORM.disabledOperation('detailTable', false)
2010
+
2011
+ // 禁用新增和删除
2012
+ MKXFORM.disabledOperation('detailTable', ['insert', 'delete'])
2013
+
2014
+ // 仅禁用第 2 行的删除
2015
+ MKXFORM.disabledOperation('detailTable', ['delete'], 1)
2016
+ ```
2017
+
2018
+ ---
2019
+
2020
+ ## 8. 事件(events)
2021
+
2022
+ > 模块名:`event`,分组:`EApiGroup.xhtml`
2023
+
2024
+ ### 8.1 `onChange`
2025
+
2026
+ **描述:** 根据控件 ID 监听值变化事件
2027
+
2028
+ **签名:**
2029
+ ```typescript
2030
+ onChange(id: string, change: (value: any, extValue: any) => void): void
2031
+ ```
2032
+
2033
+ **参数:**
2034
+
2035
+ | 参数 | 类型 | 说明 |
2036
+ |------|------|------|
2037
+ | `id` | `string` | 控件 ID |
2038
+ | `change` | `(value, extValue) => void` | 值变化回调函数 |
2039
+
2040
+ **回调参数:**
2041
+
2042
+ | 参数 | 类型 | 说明 |
2043
+ |------|------|------|
2044
+ | `value` | `any` | 新值 |
2045
+ | `extValue` | `any` | 扩展值。明细表时为 `tinyValues`(单元格变更集合) |
2046
+
2047
+ **实现细节:**
2048
+ - 对于明细表类型的控件,回调中会获取 `tinyValues`(单元格级别的变更数据),若 `tinyValues` 为空则跳过回调
2049
+ - `extValue` 仅在明细表场景下有值,包含 `tinyValues` 对象
2050
+ - 内置 `withdraw()` 存根方法,用于移除已注册的监听器
2051
+
2052
+ **使用示例:**
2053
+ ```javascript
2054
+ // 监听字段值变化
2055
+ MKXFORM.onChange('field_id', function(value, extValue) {
2056
+ console.log('新值', value)
2057
+ console.log('扩展值', extValue)
2058
+ })
2059
+
2060
+ // 监听明细表变化
2061
+ MKXFORM.onChange('detailTable', function(value, extValue) {
2062
+ console.log('明细表值变化', value)
2063
+ console.log('单元格变更', extValue) // tinyValues 对象
2064
+ })
2065
+ ```
2066
+
2067
+ ---
2068
+
2069
+ ### 8.2 `beforeSubmit`
2070
+
2071
+ **描述:** 注册表单提交前的拦截函数
2072
+
2073
+ **签名:**
2074
+ ```typescript
2075
+ beforeSubmit(fn: Function, message?: string): void
2076
+ ```
2077
+
2078
+ **参数:**
2079
+
2080
+ | 参数 | 类型 | 说明 |
2081
+ |------|------|------|
2082
+ | `fn` | `Function` | 拦截函数,返回 `true` 表示通过,返回 `false` 表示阻止提交 |
2083
+ | `message`(可选) | `string` | 阻止提交时的错误提示信息 |
2084
+
2085
+ **使用示例:**
2086
+ ```javascript
2087
+ // 提交前校验金额必须大于 0
2088
+ MKXFORM.beforeSubmit(function() {
2089
+ var amount = MKXFORM.getValue('amount')
2090
+ if (amount <= 0) {
2091
+ return false // 阻止提交
2092
+ }
2093
+ return true // 允许提交
2094
+ }, '金额必须大于0')
2095
+ ```
2096
+
2097
+ **实现细节:**
2098
+ - 将 `[fn, message]` 推入 `MKXFORM['MKXFORM_DATA_CONTAINER'].$$beforeSubmit` 数组
2099
+ - 执行时通过 `executeIntercepts` 以 `Promise.all` 并行执行所有拦截函数
2100
+ - 拦截函数返回 `undefined` 时视为 `true`(允许通过)
2101
+ - 所有拦截执行完毕后有 500ms 延迟再 resolve
2102
+ - 内置 `withdraw()` 方法,用于清除所有已注册的 beforeSubmit 处理器
2103
+
2104
+ ---
2105
+
2106
+ ### 8.3 `afterSubmit`
2107
+
2108
+ **描述:** 注册表单提交成功后的回调函数
2109
+
2110
+ **签名:**
2111
+ ```typescript
2112
+ afterSubmit(fn: Function, message?: string): void
2113
+ ```
2114
+
2115
+ **参数:**
2116
+
2117
+ | 参数 | 类型 | 说明 |
2118
+ |------|------|------|
2119
+ | `fn` | `Function` | 提交成功后执行的函数 |
2120
+ | `message`(可选) | `string` | 提示信息 |
2121
+
2122
+ **使用示例:**
2123
+ ```javascript
2124
+ MKXFORM.afterSubmit(function() {
2125
+ console.log('表单已成功提交')
2126
+ MKXFORM.message.success('提交成功')
2127
+ })
2128
+ ```
2129
+
2130
+ **实现细节:**
2131
+ - 与 `beforeSubmit` 类似,将 `[fn, message]` 推入 `MKXFORM['MKXFORM_DATA_CONTAINER'].$$afterSubmit` 数组
2132
+ - 执行时通过 `executeInterceptsAfterSubmit` 以 `Promise.all` 并行执行
2133
+ - 与 `beforeSubmit` 的区别:无 500ms 延迟,立即 resolve
2134
+
2135
+ ---
2136
+
2137
+ ## 9. 流程函数(lbpms)
2138
+
2139
+ ### 9.1 同步流程函数(fixLbpms)
2140
+
2141
+ > 模块名:`lbpm`,同步注册
2142
+
2143
+ #### 9.1.1 `getLbpmFormValues`
2144
+
2145
+ **描述:** 获取审批提交信息
2146
+
2147
+ **签名:**
2148
+ ```typescript
2149
+ getLbpmFormValues(): Promise<any>
2150
+ ```
2151
+
2152
+ **返回值:** Promise,resolve 时返回审批表单数据。
2153
+
2154
+ **实现细节:**
2155
+ - 注意:此方法会触发流程的校验
2156
+ - 委托给 `$$lbpm(MKXFORM)?.getLbpmFormValues()` 执行
2157
+
2158
+ **使用示例:**
2159
+ ```javascript
2160
+ MKXFORM.getLbpmFormValues().then(function(data) {
2161
+ console.log('审批信息', data)
2162
+ })
2163
+ ```
2164
+
2165
+ ---
2166
+
2167
+ #### 9.1.2 `getOperationParameter`
2168
+
2169
+ **描述:** 获取审批当前操作的配置信息
2170
+
2171
+ **签名:**
2172
+ ```typescript
2173
+ getOperationParameter(): any
2174
+ ```
2175
+
2176
+ **返回值:** 当前审批操作的配置对象。
2177
+
2178
+ **实现细节:**
2179
+ - 委托给 `$$lbpm(MKXFORM)?.getOperationParameter()` 执行
2180
+
2181
+ **使用示例:**
2182
+ ```javascript
2183
+ var param = MKXFORM.getOperationParameter()
2184
+ console.log('操作配置', param)
2185
+ ```
2186
+
2187
+ ---
2188
+
2189
+ #### 9.1.3 `getIdentity`
2190
+
2191
+ **描述:** 获取当前处理人的身份信息列表
2192
+
2193
+ **签名:**
2194
+ ```typescript
2195
+ getIdentity(): any
2196
+ ```
2197
+
2198
+ **返回值:** 当前处理人身份信息。
2199
+
2200
+ **实现细节:**
2201
+ - 委托给 `$$lbpm(MKXFORM)?.getIdentity()` 执行
2202
+
2203
+ **使用示例:**
2204
+ ```javascript
2205
+ var identity = MKXFORM.getIdentity()
2206
+ console.log('当前身份', identity)
2207
+ ```
2208
+
2209
+ ---
2210
+
2211
+ #### 9.1.4 `getProcessInstanceId`
2212
+
2213
+ **描述:** 获取当前流程实例 ID
2214
+
2215
+ **签名:**
2216
+ ```typescript
2217
+ // 只读属性
2218
+ MKXFORM.processInstanceId // 等价于 MKXFORM.getProcessInstanceId
2219
+ ```
2220
+
2221
+ **使用示例:**
2222
+ ```javascript
2223
+ var pid = MKXFORM.processInstanceId
2224
+ console.log('流程实例ID', pid)
2225
+ ```
2226
+
2227
+ ---
2228
+
2229
+ ### 9.2 异步流程函数(lbpms)
2230
+
2231
+ > 仅在 `initDesign` 中异步注册,API 名称格式为 `promise_<name>`,数量取决于后端返回。
2232
+
2233
+ 动态注册的流程函数通过 `callLbpm` 调用,命名格式:`promise_{functionName}`。
2234
+
2235
+ **使用示例:**
2236
+ ```javascript
2237
+ // 具体函数名取决于后端配置
2238
+ MKXFORM.promise_getNextApprover({ param: {} }, function(error, res) {
2239
+ console.log(res)
2240
+ })
2241
+ ```
2242
+
2243
+ ---
2244
+
2245
+ ## 10. 集成平台(integrate)
2246
+
2247
+ > 仅在 `initDesign` 中异步注册,分组名:`promise`
2248
+
2249
+ 集成平台接口从后端动态获取,命名格式为 `promise_{systemName}`,每个系统下有子接口 `tic_{interfaceCode}`。
2250
+
2251
+ **使用示例:**
2252
+ ```javascript
2253
+ // 调用指定系统的接口
2254
+ MKXFORM.promise_systemName({ interfaceCode: 'CODE_001', param: {} }, function(error, res) {
2255
+ console.log(res)
2256
+ })
2257
+ ```
2258
+
2259
+ ---
2260
+
2261
+ ## 11. 组织架构(orgFunctions)
2262
+
2263
+ > 仅在 `initDesign` 中异步注册,分组名:`org_promise`
2264
+
2265
+ 组织架构函数从后端动态获取,命名格式为 `org_{description}`。后端 API 位于 `/data/sys-org/sysOrgJsFormula/*`。
2266
+
2267
+ **实现细节:**
2268
+ - 调用 `api.getJsFormulaList()` 获取组织架构函数列表
2269
+ - 生成 `org_{description}` 格式的 API 名称
2270
+ - 通过 `callOrg` 发起请求,内部调用 `OrgHttp.post('/sysOrgJsFormula/{path}', param)` 执行
2271
+
2272
+ ### 11.1 调用方式
2273
+
2274
+ **签名:**
2275
+ ```typescript
2276
+ callOrg(config: { id: string, param?: any }, callback: (error: any, res: any) => void): Promise<void>
2277
+ ```
2278
+
2279
+ **参数:**
2280
+
2281
+ | 参数 | 类型 | 说明 |
2282
+ |------|------|------|
2283
+ | `config.id` | `string` | 组织函数 ID,格式为 `sysorg.xxx`(如 `sysorg.getCurUserInfo`、`sysorg.getThisDepartment`) |
2284
+ | `config.param` | `any`(可选) | 函数参数 |
2285
+
2286
+ ### 11.2 常用组织架构函数
2287
+
2288
+ 以下为后端提供的常用函数(通过 `jsFormulaList` 接口动态获取):
2289
+
2290
+ | 函数 ID | 函数名称 | 说明 | 参数示例 |
2291
+ | --------------------------------------------- | ----------- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
2292
+ | `sysorg.getCurUserInfo` | 获取当前用户 | 获取当前登录用户信息 | `{}` |
2293
+ | `sysorg.getElementDatas` | 查找人员和岗位 | 根据地址查找组织 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2294
+ | `sysorg.getPersonByLoginName` | 根据登录名查找人员 | 通过登录名获取人员 | `{ loginName: 'zhangsan' }` |
2295
+ | `sysorg.getPersonByPersonId` | 根据用户ID查找人员 | 通过人员ID获取信息 | `{ fdPersonId: 'xxx' }` |
2296
+ | `sysorg.getThisDepartment` | 查找所属部门 | 获取当前人员主部门 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2297
+ | `sysorg.getDepartmentAllPath` | 获取部门全路径 | 获取部门完整层级路径 | `{ addressObject: {fdId: 'xxx'} }` |
2298
+ | `sysorg.getDepartmentByLevel` | 查找第X级部门 | 获取第N级部门 | `{ addressObject: {fdId: 'xxx'}, level: 2 }` |
2299
+ | `sysorg.getOrganization` | 查找所属机构 | 获取上级机构 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2300
+ | `sysorg.getDepartmentHead` | 查找部门领导 | 获取部门负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}] }` |
2301
+ | `sysorg.getSuperiorDepartmenthead` | 查找上级部门领导 | 获取上级部门负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], condition: true }` |
2302
+ | `sysorg.getDepartmentLeaderByLevel` | 获取第X级部门领导 | 获取第N级部门领导 | `{ addressObject: {fdId: 'xxx'}, level: 1 }` |
2303
+ | `sysorg.getDepartmentLeadersByLevel` | 递归查找多级部门领导 | 获取多级部门领导 | `{ addressObject: {fdId: 'xxx'}, level: 3 }` |
2304
+ | `sysorg.isDepartmentLeaderMyself` | 是否本部门领导 | 判断是否为本部门领导 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}] }` |
2305
+ | `sysorg.isDepartmentLeaderForPerson` | 是否部门领导 | 判断指定人员是否为部门领导 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], organizations: [...] }` |
2306
+ | `sysorg.getOrgHead` | 查找机构领导 | 获取机构负责人 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 1}] }` |
2307
+ | `sysorg.isRoleMember` | 岗位判断函数 | 判断是否属于某岗位 | `{ orgPost: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 4}, address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2308
+ | `sysorg.getDepartmentSuperLeaderByLevel` | 查找部门上级领导 | 获取部门上级领导 | `{ organizations: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}], level: 2 }` |
2309
+ | `sysorg.isMember` | 成员判定函数 | 判断是否属于某组织 | `{ parent: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}, address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}] }` |
2310
+ | `sysorg.isContainsLabel` | 组织包含标签函数 | 判断组织是否包含标签 | `{ org: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}, orgLabel: '标签名' }` |
2311
+ | `sysorg.isUserContainsAnyLabel` | 当前用户包含任一标签 | 判断当前用户是否有某标签 | `{ orgLabels: ['标签1', '标签2'] }` |
2312
+ | `sysorg.getOrgAttributeVal` | 查找组织属性 | 获取组织属性值 | `{ addressObject: {fdId: 'xxx'}, orgType: 2, strOrgAttribute: 'attrName' }` |
2313
+ | `sysorg.checkDeptIsMain` | 主部门判断函数 | 判断是否为主部门 | `{ person: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 8}, dept: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 2} }` |
2314
+ | `sysorg.findUserAuxiliaryDept` | 查找用户辅部门 | 获取用户辅助部门列表 | `{ addressObject: {fdId: 'xxx'} }` |
2315
+ | `sysorg.getElementByNo` | 根据组织编码查找组织 | 通过编码获取组织 | `{ fdNo: 'ORG001', orgType: 2 }` |
2316
+ | `sysorg.getPersonAndPostByGroup` | 查找群组下的人员/岗位 | 获取群组成员 | `{ group: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 16}, isCross: false }` |
2317
+ | `sysorg.isOrganizationBelongOrIncludeAnother` | 组织包含/属于判断 | 判断组织关系 | `{ firstOrgs: [...], secondOrgs: [...], relationType: 1, isCross: false }` |
2318
+ | `sysorg.findUpXLevelLeader` | 向上查找X级部门领导 | 获取第N级上级领导 | `{ addressObject: {fdId: 'xxx'}, level: 2, isCross: false }` |
2319
+ | `sysorg.queryDeptPersons` | 查找部门下人员 | 获取部门下所有人员 | `{ addressObject: {fdId: 'xxx'}, isIncludeChild: true }` |
2320
+ | `sysorg.getPersonsByPost` | 根据岗位查找人员 | 获取岗位下所有人员 | `{ address: [{fdId: 'xxx', fdName: 'xxx', fdOrgType: 4}] }` |
2321
+ | `sysorg.getPostOrPostPersonsByPostName` | 根据岗位名称查找 | 通过岗位名获取人员 | `{ postNameObj: {fdName: '总经理'}, orgType: 4 }` |
2322
+ | `sysorg.getCurIdentityInfo` | 获取当前身份 | 获取当前用户身份信息 | `{}` |
2323
+ | `sysorg.expandByGroup` | 查找群组下全部成员 | 获取群组完整成员列表 | `{ group: {fdId: 'xxx', fdName: 'xxx', fdOrgType: 16} }` |
2324
+
2325
+ ### 11.3 参数详解
2326
+
2327
+ #### 11.3.1 参数对象结构
2328
+
2329
+ **DefaultOrganization(组织对象):**
2330
+ ```typescript
2331
+ interface DefaultOrganization {
2332
+ fdId: string // 组织ID
2333
+ fdName: string // 组织名称
2334
+ fdOrgType: number // 组织类型:1-机构, 2-部门, 4-岗位, 8-人员, 16-群组, 128-公共岗位, 256-身份
2335
+ fdNo?: string // 组织编码(可选)
2336
+ fdOriId?: string // 原始ID(可选)
2337
+ fdIsAvailable?: boolean // 是否有效(可选)
2338
+ }
2339
+ ```
2340
+
2341
+ #### 11.3.2 参数字段说明
2342
+
2343
+ | 参数名 | 类型 | 说明 | 常用值 |
2344
+ | ----------------- | ----------------------- | ---------- | ------------------------------------------------- |
2345
+ | `address` | `DefaultOrganization[]` | 地址本数据,组织数组 | `[ {fdId: 'xxx', fdName: '张三', fdOrgType: 8} ]` |
2346
+ | `addressObject` | `{fdId: string}` | 简化的地址对象 | `{ fdId: 'deptId_xxx' }` |
2347
+ | `organizations` | `DefaultOrganization[]` | 组织数组,多个组织 | `[ {...}, {...} ]` |
2348
+ | `org` | `DefaultOrganization` | 单个组织 | `{fdId: 'xxx', fdName: 'xxx', fdOrgType: 2}` |
2349
+ | `parent` | `DefaultOrganization` | 父级组织 | 同上 |
2350
+ | `group` | `DefaultOrganization` | 群组 | 同上 |
2351
+ | `person` | `DefaultOrganization` | 人员 | 同上 |
2352
+ | `dept` | `DefaultOrganization` | 部门 | 同上 |
2353
+ | `orgPost` | `DefaultOrganization` | 岗位 | 同上 |
2354
+ | `loginName` | `string` | 登录名 | `'zhangsan'` |
2355
+ | `fdPersonId` | `string` | 人员ID | `'person_xxx'` |
2356
+ | `fdNo` | `string` | 组织编码 | `'ORG001'` |
2357
+ | `orgType` | `number` | 组织类型 | `1-机构, 2-部门, 4-岗位, 8-人员, 16-群组, 128-公共岗位, 256-身份` |
2358
+ | `level` | `number` | 层级数字 | `0-根组织, 1-一级部门, 2-二级部门...` |
2359
+ | `condition` | `boolean` | 条件开关 | `true-继续向上查找, false-不继续` |
2360
+ | `isCross` | `boolean` | 是否跨组织 | `true/false` |
2361
+ | `isIncludeChild` | `boolean` | 是否包含下级 | `true-包含, false-仅本级` |
2362
+ | `orgLabel` | `string` | 组织标签名称 | `'标签名'` |
2363
+ | `orgLabels` | `string[]` | 组织标签名称数组 | `['标签1', '标签2']` |
2364
+ | `strOrgAttribute` | `string` | 组织属性名 | `'属性字段名'` |
2365
+ | `postNameObj` | `{fdName: string}` | 岗位名称对象 | `{fdName: '总经理'}` |
2366
+ | `relationType` | `number` | 关系类型 | `1-包含所有, 2-包含任意, 3-所有属于, 4-属于任意` |
2367
+ | `strList` | `string[]` | ID字符串列表 | `['id1', 'id2']` |
2368
+ | `orgList` | `DefaultOrganization[]` | 组织列表 | 同 address |
2369
+
2370
+ #### 11.3.3 常用调用场景参数示例
2371
+
2372
+ **场景1:根据人员获取所属部门**
2373
+ ```javascript
2374
+ // address 使用人员对象
2375
+ MKXFORM.callOrg({
2376
+ id: 'sysorg.getThisDepartment',
2377
+ param: {
2378
+ address: [
2379
+ { fdId: 'person_123', fdName: '张三', fdOrgType: 8 }
2380
+ ]
2381
+ }
2382
+ }, callback)
2383
+ ```
2384
+
2385
+ **场景2:获取部门领导**
2386
+ ```javascript
2387
+ // address 使用部门对象
2388
+ MKXFORM.callOrg({
2389
+ id: 'sysorg.getDepartmentHead',
2390
+ param: {
2391
+ address: [
2392
+ { fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }
2393
+ ]
2394
+ }
2395
+ }, callback)
2396
+ ```
2397
+
2398
+ **场景3:获取第N级部门领导**
2399
+ ```javascript
2400
+ // addressObject 使用简化对象
2401
+ MKXFORM.callOrg({
2402
+ id: 'sysorg.getDepartmentLeaderByLevel',
2403
+ param: {
2404
+ addressObject: { fdId: 'dept_456' },
2405
+ level: 1 // 0-根组织, 1-一级部门, 2-二级部门...
2406
+ }
2407
+ }, callback)
2408
+ ```
2409
+
2410
+ **场景4:查找上级部门领导(是否继续向上)**
2411
+ ```javascript
2412
+ MKXFORM.callOrg({
2413
+ id: 'sysorg.getSuperiorDepartmenthead',
2414
+ param: {
2415
+ address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }],
2416
+ condition: true // true-领导为空时继续向上查找, false-不再向上
2417
+ }
2418
+ }, callback)
2419
+ ```
2420
+
2421
+ **场景5:判断是否属于某岗位**
2422
+ ```javascript
2423
+ MKXFORM.callOrg({
2424
+ id: 'sysorg.isRoleMember',
2425
+ param: {
2426
+ orgPost: { fdId: 'post_789', fdName: '总经理', fdOrgType: 4 },
2427
+ address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }]
2428
+ }
2429
+ }, callback)
2430
+ ```
2431
+
2432
+ **场景6:根据岗位名称查找人员**
2433
+ ```javascript
2434
+ MKXFORM.callOrg({
2435
+ id: 'sysorg.getPostOrPostPersonsByPostName',
2436
+ param: {
2437
+ postNameObj: { fdName: '总经理' },
2438
+ orgType: 4 // 可选,指定组织类型
2439
+ }
2440
+ }, callback)
2441
+ ```
2442
+
2443
+ **场景7:获取部门下所有人员(含下级)**
2444
+ ```javascript
2445
+ MKXFORM.callOrg({
2446
+ id: 'sysorg.queryDeptPersons',
2447
+ param: {
2448
+ addressObject: { fdId: 'dept_456' },
2449
+ isIncludeChild: true // true-包含子部门人员, false-仅本部门
2450
+ }
2451
+ }, callback)
2452
+ ```
2453
+
2454
+ **场景8:查找群组下全部成员**
2455
+ ```javascript
2456
+ MKXFORM.callOrg({
2457
+ id: 'sysorg.expandByGroup',
2458
+ param: {
2459
+ group: { fdId: 'group_111', fdName: '项目组A', fdOrgType: 16 }
2460
+ }
2461
+ }, callback)
2462
+ ```
2463
+
2464
+ **场景9:根据组织编码查找**
2465
+ ```javascript
2466
+ MKXFORM.callOrg({
2467
+ id: 'sysorg.getElementByNo',
2468
+ param: {
2469
+ fdNo: 'DEPT001', // 组织编码
2470
+ orgType: 2 // 可选,1-机构 2-部门 4-岗位 8-人员 16-群组
2471
+ }
2472
+ }, callback)
2473
+ ```
2474
+
2475
+ ### 11.4 使用示例
2476
+
2477
+ ```javascript
2478
+ // 获取当前用户信息
2479
+ MKXFORM.callOrg({ id: 'sysorg.getCurUserInfo', param: {} }, function(error, res) {
2480
+ console.log('当前用户', res) // { fdId, fdName, fdOrgType, fdLoginName }
2481
+ })
2482
+
2483
+ // 查找所属部门(address 使用人员数组)
2484
+ MKXFORM.callOrg({
2485
+ id: 'sysorg.getThisDepartment',
2486
+ param: {
2487
+ address: [{ fdId: 'person_123', fdName: '张三', fdOrgType: 8 }]
2488
+ }
2489
+ }, function(error, res) {
2490
+ console.log('所属部门', res)
2491
+ })
2492
+
2493
+ // 查找部门领导(address 使用部门数组)
2494
+ MKXFORM.callOrg({
2495
+ id: 'sysorg.getDepartmentHead',
2496
+ param: {
2497
+ address: [{ fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }]
2498
+ }
2499
+ }, function(error, res) {
2500
+ console.log('部门领导', res)
2501
+ })
2502
+
2503
+ // 获取部门全路径
2504
+ MKXFORM.callOrg({ id: 'sysorg.getDepartmentAllPath', param: { addressObject: { fdId: 'dept_456' } } }, function(error, res) {
2505
+ console.log('部门全路径', res)
2506
+ })
2507
+
2508
+ // 判断是否为本部门领导
2509
+ MKXFORM.callOrg({
2510
+ id: 'sysorg.isDepartmentLeaderMyself',
2511
+ param: {
2512
+ address: [{ fdId: 'dept_456', fdName: '研发部', fdOrgType: 2 }]
2513
+ }
2514
+ }, function(error, res) {
2515
+ console.log('是否部门领导', res) // true/false
2516
+ })
2517
+
2518
+ // 获取第2级部门领导
2519
+ MKXFORM.callOrg({ id: 'sysorg.getDepartmentLeaderByLevel', param: { addressObject: { fdId: 'dept_456' }, level: 2 } }, function(error, res) {
2520
+ console.log('第2级部门领导', res)
2521
+ })
2522
+ ```
2523
+
2524
+ ### 11.5 返回值结构
2525
+
2526
+ 不同函数返回不同结构,常见结构示例:
2527
+
2528
+ ```javascript
2529
+ // 人员对象
2530
+ {
2531
+ fdId: '人员ID',
2532
+ fdName: '人员名称',
2533
+ fdOrgType: 8, // 人员类型
2534
+ fdLoginName: '登录名'
2535
+ }
2536
+
2537
+ // 部门对象
2538
+ {
2539
+ fdId: '部门ID',
2540
+ fdName: '部门名称',
2541
+ fdHierarchyId: '层级ID',
2542
+ fdParentId: '上级部门ID'
2543
+ }
2544
+
2545
+ // 机构对象
2546
+ {
2547
+ fdId: '机构ID',
2548
+ fdName: '机构名称',
2549
+ fdOrgType: 1 // 机构类型
2550
+ }
2551
+
2552
+ // 部门全路径
2553
+ '集团_子公司_部门'
2554
+ ```
2555
+
2556
+ ---
2557
+
2558
+ ## 12. 动作流(flow)
2559
+
2560
+ > 仅在 `initDesign` 中异步注册,分组名:`flow`
2561
+
2562
+ 动作流函数从后端动态获取,命名格式为 `flow_{fdCode}`。数量可能为 0。
2563
+
2564
+ **使用示例:**
2565
+ ```javascript
2566
+ MKXFORM.flow_APPROVE({
2567
+ context: {},
2568
+ fdProcessId: 'process_001',
2569
+ incParams: {},
2570
+ fdProcessCode: 'FLOW_CODE'
2571
+ }, function(error, res, context) {
2572
+ console.log(res)
2573
+ })
2574
+ ```
2575
+
2576
+ ---
2577
+
2578
+ ## 13. LanBots AI(lanbots)
2579
+
2580
+ > 仅在 `initDesign` 中异步注册,分组名:`lanbots`
2581
+
2582
+ LanBots AI 函数从后端动态获取,命名格式为 `lanbotsPromises_{categoryValue}`,子接口为 `lanbots_{fdId}`。
2583
+
2584
+ **使用示例:**
2585
+ ```javascript
2586
+ MKXFORM.callLanBots({ fdCode: 'CAT_001', id: 'BOT_001', lanBotsType: 'quickRead' }, function(error, res) {
2587
+ console.log(res)
2588
+ })
2589
+ ```
2590
+
2591
+ ---
2592
+
2593
+ ## 14. 全局环境变量(GLOBALJS)
2594
+
2595
+ > 仅在 `formAttr.controlAction` 存在时通过 `registerGlobalEnvToWindow` 注册
2596
+
2597
+ 当表单配置了 `controlAction.$$env.data` 时,会自动注册到 `MKXFORM.GLOBALJS` 对象中。
2598
+
2599
+ - **变量:** `MKXFORM.GLOBALJS[varName]` — 注册为只读变量
2600
+ - **函数:** `MKXFORM.GLOBALJS[fnName](...args)` — 注册为函数,自动注入 MKXFORM 作为最后一个参数
2601
+
2602
+ **使用示例:**
2603
+ ```javascript
2604
+ // 使用全局环境变量
2605
+ var config = MKXFORM.GLOBALJS.someConfig
2606
+
2607
+ // 调用全局环境函数
2608
+ MKXFORM.GLOBALJS.someFunction('arg1', 'arg2')
2609
+ ```
2610
+
2611
+ ---
2612
+
2613
+ ## 15. 注册顺序与生命周期
2614
+
2615
+ ### initRuntime(同步注册)
2616
+
2617
+ ```
2618
+ 1. 设置直接属性(MKXFORM_DATA_CONTAINER、viewStatus、docStatus 等)
2619
+ 2. inner → callTic, callLbpm, callOrg, callFlow, callLanBots
2620
+ 3. vars → mkXform, viewStatus, docStatus, platform, formId
2621
+ 4. global → ajax, getLocale, validateFields, getFormConfigs, getFormValues,
2622
+ message, toast, modal, mobileModal, tableModal, HTMLModal,
2623
+ executeOperation, authOperation
2624
+ 5. function → $, setValue, getValue, setStyle, setProps,
2625
+ getFieldAttr, setFieldAttr, getValueText, getControlHtml
2626
+ 6. detail → getControlValue, updateControl, updateControlStyle,
2627
+ addRow, updateRow, deleteRow, getRowCount,
2628
+ getSelectedRowIndex, checkDetailRow, controlDetailRowCanDelete,
2629
+ cacluColumnValue, getPageControlValue,
2630
+ setDetailFieldAttr, setDetailRowAttr, setDetailFieldItemAttr,
2631
+ reload, disabledOperation
2632
+ 7. event → onChange, beforeSubmit, afterSubmit
2633
+ 8. fixLbpms → getLbpmFormValues, getOperationParameter, getIdentity, getProcessInstanceId
2634
+ 9. fixLbpms → (重复注册,疑似 bug)
2635
+ 10. [条件] registerGlobalEnvToWindow → GLOBALJS
2636
+ ```
2637
+
2638
+ ### initDesign(异步注册)
2639
+
2640
+ ```
2641
+ window.MKXFORM = MKXFORM ← 挂载到全局
2642
+ Promise.all([
2643
+ integrate() → promise_{systemName} / tic_{interfaceCode}
2644
+ lbpms() → promise_{name} / getIdentity / getLbpmFormValues / getOperationParameter
2645
+ orgFunctions() → org_{description}
2646
+ flow(props) → flow_{fdCode}
2647
+ lanbots() → lanbotsPromises_{value} / lanbots_{fdId}
2648
+ ])
2649
+ ```
2650
+
2651
+ ---
2652
+
2653
2653
  文档错误纠正?联系:hexb@landray.com.cn