uiview-guide.md
... ...
@@ -0,0 +1,2570 @@
1
+# 视图开发手册
2
+
3
+
4
+
5
+# 第一部分:基础视图开发
6
+
7
+## 第一章:视图文件结构与配置
8
+
9
+### **1.1 核心概念**
10
+
11
+在赛意谷神平台中,**视图是 `ui_view` 模型的实例**,所有视图都通过JSON文件定义,包含以下关键特性:
12
+
13
+- **模型驱动**:每个视图必须关联一个数据模型
14
+- **JSON定义**:视图配置采用JSON格式
15
+- **文件存储**:视图文件存储在特定目录中
16
+
17
+### **1.2 项目目录结构**
18
+
19
+**resolved路径**: `resolved` 是模块的唯一包路径标识,对应物理目录。平台使用此标识定位模块资源、加载配置,机制类似Java包名。
20
+
21
+**视图路径**: 在`resolved`包下新建 **`views/`** 目录,所有视图JSON文件必须放置于此目录。
22
+
23
+**种子数据路径**: 在`resolved`包下新建 **`data/`** 目录,所有种子数据文件必须放置于此目录。
24
+
25
+```
26
+com.sie.iidp.iam/ # resolved包(如com.sie.iidp.iam)
27
+├── views/ # 视图目录(必须)
28
+│ ├── rbac_user_view.json # 用户管理视图
29
+│ ├── menu_view.json # 菜单配置视图
30
+│ ├── ui_view_seed_view.json # 后端视图
31
+│ └── ... # 其他视图文件
32
+├── data/ # 种子数据目录(必须)
33
+│ ├── rbac_user.json # 用户种子数据
34
+│ ├── rbac_role.json # 角色种子数据
35
+│ └── ... # 其他数据文件
36
+├── src/ # 源代码目录(可选)
37
+├── resources/ # 资源文件(可选)
38
+└── app.json # 应用配置文件(必须)
39
+```
40
+
41
+![image-20251229100936851](./images/ui-view-resolve-1.png)
42
+
43
+
44
+
45
+**`app.json`配置示例:**
46
+
47
+```json
48
+{
49
+ "name": "sie-iidp-iam",
50
+ "displayName": "权限",
51
+ "author": "snest",
52
+ "company": "sie",
53
+ "category": "base",
54
+ "categoryDesc": "权限模块",
55
+ "product": "base",
56
+ "productDesc": "工业互联网平台",
57
+ "description": "权限系统",
58
+ "summary": "权限系统",
59
+ "type": "SDK",
60
+ "tag": "master",
61
+ "version": "v3.0.0-RELEASE",
62
+ "resolved": "com.sie.iidp.iam",
63
+ "dependencies": [
64
+ "iidp-user-prefer",
65
+ "base-cache",
66
+ "sie-iidp-tenant"
67
+ ],
68
+ "application": true,
69
+ "icon": null,
70
+ "global": true,
71
+ "reinstall": true,
72
+ "license": "LGPL 3.0",
73
+ "sequence": 30,
74
+ "view": [
75
+ "views/menu_view.json",
76
+ "views/rbac_role_view.json",
77
+ "views/sdk_user_view.json",
78
+ "views/sdk_view_ref_model.json",
79
+ "views/ui_menu_view.json",
80
+ "views/ui_view_seed_view.json"
81
+ ],
82
+ "data": [
83
+ "data/rbac_tenant.json",
84
+ "data/rbac_user.json",
85
+ "data/rbac_token.json"
86
+ ],
87
+ "events": {
88
+ "broadcast": [
89
+ "tenant_action_scope::syncSgData",
90
+ "tenant_permission::initAuth"
91
+ ],
92
+ "startUp": [
93
+ "tenant_action_scope::syncSgData",
94
+ "init_user_session::start"
95
+ ],
96
+ "register": [],
97
+ "login": [
98
+ "rbac_user::setUserInfo"
99
+ ]
100
+ },
101
+ "globalConfig": {
102
+ "sgWhiteList": {
103
+ "value": "*.custom_view_model,*.rbac_password_policy,*.ui_menu,*.tenant_action_dimension,*.rbac_token"
104
+ },
105
+ "urlWhiteList": {
106
+ "value": "sie-iidp-iam.access_auth_model.getPermissionByTenantId"
107
+ }
108
+ },
109
+ "appConfig": {
110
+ "multiSg": {
111
+ "desc": "设置作用域切换值是否多选:true,多选;false,单选。注意:若将多选改为单选(true改为false),会清空已选的多选项。",
112
+ "value": "false"
113
+ },
114
+ "safeSg": {
115
+ "desc": "设置作用域是否支持安全值:true为支持(开启后,如果用户没有关联实例,会显示未授权),false为关闭。",
116
+ "value": "false"
117
+ }
118
+ }
119
+}
120
+```
121
+
122
+
123
+
124
+## **第二章:基础视图类型详解**
125
+
126
+### **2.1 表单视图(Form View)**
127
+
128
+用于创建或编辑单条记录。
129
+
130
+![image-20251229111105190](./images/image-20251229111105190.png)
131
+
132
+##### **1. 基础结构:**
133
+
134
+```json
135
+{
136
+ "rbac_user_form": {
137
+ "name": "用户表单",
138
+ "model": "rbac_user",
139
+ "type": "form",
140
+ "mode": "primary",
141
+ "body": {
142
+ "type": "form",
143
+ "columns": ["name", "login", "mobile", "email"],
144
+ "tabs": [...],
145
+ "tbar": [...]
146
+ }
147
+ }
148
+}
149
+```
150
+
151
+**参数说明:**
152
+
153
+| 参数 | 类型 | 必填 | 描述 | 示例值 |
154
+| -------------- | ------ | ---- | ---------------------- | ------------------- |
155
+| `name` | String | 是 | 视图显示名称 | "用户表单" |
156
+| `model` | String | 是 | 关联的模型名称 | "rbac_user" |
157
+| `type` | String | 是 | 视图类型,固定为`form` | "form" |
158
+| `mode` | String | 是 | 视图模式 | "primary"(主视图) |
159
+| `body.type` | String | 是 | 主体类型,固定为`form` | "form" |
160
+| `body.columns` | Array | 是 | 表单中显示的字段数组 | `["name", "login"]` |
161
+
162
+##### **2. 基础表单示例:**
163
+
164
+```json
165
+ {
166
+ "rbac_user_form": {
167
+ "name": "用户表单",
168
+ "model": "rbac_user",
169
+ "type": "form",
170
+ "mode": "primary",
171
+ "body": {
172
+ "type": "form",
173
+ "columns": [
174
+ {
175
+ "displayName": "姓名",
176
+ "name": "name"
177
+ },
178
+ {
179
+ "displayName": "组织",
180
+ "name": "org_id"
181
+ },
182
+ {
183
+ "displayName": "登录名",
184
+ "name": "login"
185
+ },
186
+ {
187
+ "displayName": "手机号",
188
+ "name": "mobile",
189
+ "disable_update": "edit"
190
+ },
191
+ {
192
+ "displayName": "邮箱",
193
+ "name": "email"
194
+ },
195
+ {
196
+ "displayName": "密码",
197
+ "name": "password",
198
+ "disable_update": "edit"
199
+ }
200
+ ],
201
+ "tabs": [
202
+ {
203
+ "header": "角色",
204
+ "tbar": [
205
+ {
206
+ "name": "添加",
207
+ "action": "addEr",
208
+ "auth": "update"
209
+ },
210
+ {
211
+ "name": "删除",
212
+ "action": "deleteEr",
213
+ "auth": "delete"
214
+ }
215
+ ],
216
+ "body": {
217
+ "type": "rbac_role_grid,rbac_role_form,rbac_role_search",
218
+ "field": "role_ids",
219
+ "columns": [
220
+ "name",
221
+ "is_admin"
222
+ ]
223
+ }
224
+ }
225
+ ],
226
+ "tbar": [
227
+ "@defaults"
228
+ ]
229
+ }
230
+ }
231
+ }
232
+```
233
+
234
+##### 3.表单高级示例(带ER关系):
235
+
236
+```json
237
+{
238
+ "app_user_form": {
239
+ "mode": "primary",
240
+ "name": "用户管理表单",
241
+ "model": "rbac_user",
242
+ "type": "form",
243
+ "body": {
244
+ "submitChanged": "true",
245
+ "buttons": [
246
+ "@defaults"
247
+ ],
248
+ "tabs": [
249
+ {
250
+ "header": "角色",
251
+ "tbar": [
252
+ {
253
+ "name": "设置角色",
254
+ "action": "addEr",
255
+ "auth": "update"
256
+ },
257
+ {
258
+ "name": "删除",
259
+ "action": "deleteEr",
260
+ "auth": "delete"
261
+ }
262
+ ],
263
+ "body": {
264
+ "type": "app_role_grid,app_role_search,app_role_form",
265
+ "field": "role_ids",
266
+ "columns": [
267
+ "name",
268
+ "code",
269
+ "remark"
270
+ ]
271
+ }
272
+ },
273
+ {
274
+ "header": "用户组",
275
+ "tbar": [
276
+ {
277
+ "name": "设置用户组",
278
+ "action": "addEr",
279
+ "auth": "update"
280
+ },
281
+ {
282
+ "name": "删除",
283
+ "action": "deleteEr",
284
+ "auth": "delete"
285
+ }
286
+ ],
287
+ "body": {
288
+ "type": "app_user_group_grid,app_user_group_form,app_user_group_search",
289
+ "field": "userGroupList",
290
+ "columns": [
291
+ "name",
292
+ "description"
293
+ ]
294
+ }
295
+ },
296
+ {
297
+ "header": "关联维度",
298
+ "tbar": [
299
+ {
300
+ "name": "设置维度数据",
301
+ "action": "addEr",
302
+ "auth": "update"
303
+ },
304
+ {
305
+ "name": "删除",
306
+ "action": "deleteEr",
307
+ "auth": "delete"
308
+ }
309
+ ],
310
+ "body": {
311
+ "type": "app_role_grid,app_role_search,app_role_form",
312
+ "field": "role_ids",
313
+ "checkbox": "multiple_2",
314
+ "checkType": "bgSync",
315
+ "columns": [
316
+ "name",
317
+ "code",
318
+ "remark"
319
+ ]
320
+ }
321
+ }
322
+ ],
323
+ "columns": [
324
+ "name",
325
+ {
326
+ "name": "org_id",
327
+ "custom": true,
328
+ "type": "select",
329
+ "useCustomClick": true,
330
+ "view": {
331
+ "customClick": {
332
+ "customSelect": {
333
+ "showType": "dialog",
334
+ "width": "30%",
335
+ "height": "60vh",
336
+ "useSelectTree": {
337
+ "preId": "rbac_user_app_menu_form_main_detail_top_common_items_0_items_org_id_",
338
+ "type": "single"
339
+ }
340
+ }
341
+ }
342
+ }
343
+ },
344
+ "login",
345
+ {
346
+ "name": "password",
347
+ "custom": true,
348
+ "bind_display": "${$ds.clickType==='add'}"
349
+ },
350
+ "avatar",
351
+ "gender",
352
+ "mobile",
353
+ "email",
354
+ {
355
+ "label": "状态",
356
+ "name": "status",
357
+ "defaultValue": "0"
358
+ },
359
+ "remark",
360
+ {
361
+ "label": "租户",
362
+ "name": "tenant_id",
363
+ "display": true,
364
+ "disabled": true
365
+ }
366
+ ],
367
+ "type": "form"
368
+ }
369
+ }
370
+}
371
+```
372
+
373
+
374
+
375
+### **2.2 表格视图(Grid View)**
376
+
377
+用于以表格形式展示多条记录。
378
+
379
+![image-20251229110312927](./images/image-20251229110312927.png)
380
+
381
+##### 1. 基础结构:
382
+
383
+```json
384
+{
385
+ "rbac_user_grid": {
386
+ "name": "用户表格",
387
+ "model": "rbac_user",
388
+ "type": "grid",
389
+ "mode": "primary",
390
+ "body": {
391
+ "type": "grid",
392
+ "columns": ["name", "login", "mobile", "email"],
393
+ "buttons": [...],
394
+ "tbar": [...]
395
+ }
396
+ }
397
+}
398
+```
399
+
400
+**参数说明:**
401
+
402
+| 参数 | 类型 | 必填 | 描述 |
403
+| -------------- | ------ | ---- | ---------------------- |
404
+| `name` | String | 是 | 视图显示名称 |
405
+| `model` | String | 是 | 关联的模型名称 |
406
+| `type` | String | 是 | 视图类型,固定为`grid` |
407
+| `mode` | String | 是 | 视图模式 |
408
+| `body.type` | String | 是 | 主体类型,固定为`grid` |
409
+| `body.columns` | Array | 是 | 表格列定义 |
410
+| `body.buttons` | Array | 否 | 行操作按钮 |
411
+| `body.tbar` | Array | 否 | 表格顶部工具栏 |
412
+
413
+##### 2. 基础表格示例:
414
+
415
+```json
416
+{
417
+ "rbac_user_grid": {
418
+ "name": "用户表格",
419
+ "model": "rbac_user",
420
+ "type": "grid",
421
+ "mode": "primary",
422
+ "body": {
423
+ "type": "grid",
424
+ "columns": [
425
+ {
426
+ "displayName": "姓名",
427
+ "name": "name"
428
+ },
429
+ {
430
+ "displayName": "组织",
431
+ "name": "org_id"
432
+ },
433
+ {
434
+ "displayName": "登录名",
435
+ "name": "login"
436
+ },
437
+ {
438
+ "displayName": "手机号",
439
+ "name": "mobile"
440
+ }
441
+ ],
442
+ "buttons": [
443
+ {
444
+ "name": "编辑",
445
+ "action": "edit",
446
+ "auth": "update"
447
+ },
448
+ {
449
+ "name": "重置密码",
450
+ "auth": "resetPassword",
451
+ "service": "resetPassword",
452
+ "action": "openView",
453
+ "model": "rbac_user",
454
+ "views": "custom",
455
+ "params": [
456
+ "newPassword"
457
+ ],
458
+ "actionAfter": "refreshTable"
459
+ }
460
+ ],
461
+ "tbar": [
462
+ {
463
+ "name": "新增",
464
+ "action": "create",
465
+ "auth": "create"
466
+ },
467
+ {
468
+ "name": "删除",
469
+ "action": "delete",
470
+ "auth": "delete"
471
+ }
472
+ ]
473
+ }
474
+ }
475
+}
476
+```
477
+
478
+##### 3.表格高级示例
479
+
480
+```json
481
+ {
482
+ "app_user_grid": {
483
+ "mode": "primary",
484
+ "name": "用户管理表格",
485
+ "model": "rbac_user",
486
+ "type": "grid",
487
+ "body": {
488
+ "checkbox": "multiple_2",
489
+ "buttons": [
490
+ {
491
+ "name": "编辑",
492
+ "action": "edit",
493
+ "auth": "update",
494
+ "btnType": "origin_edit"
495
+ },
496
+ {
497
+ "name": "关联维度",
498
+ "action": "edit",
499
+ "auth": "update",
500
+ "btnType": "associated_dimension"
501
+ },
502
+ {
503
+ "name": "重置密码",
504
+ "auth": "resetPassword",
505
+ "service": "resetPassword",
506
+ "action": "openView",
507
+ "model": "rbac_user",
508
+ "views": "custom",
509
+ "params": [
510
+ "newPassword"
511
+ ]
512
+ }
513
+ ],
514
+ "columns": [
515
+ "name",
516
+ {
517
+ "name": "org_id",
518
+ "hidden": true,
519
+ "custom": true
520
+ },
521
+ "orgNamePath",
522
+ "login",
523
+ "remark",
524
+ "email",
525
+ "status",
526
+ "gender",
527
+ "mobile",
528
+ "avatar"
529
+ ],
530
+ "tbar": [
531
+ {
532
+ "name": "新增",
533
+ "action": "create",
534
+ "auth": "create"
535
+ },
536
+ {
537
+ "name": "删除",
538
+ "action": "delete",
539
+ "auth": "delete"
540
+ }
541
+ ],
542
+ "type": "grid",
543
+ "searchByMainTable": {
544
+ "service": {
545
+ "search": "searchUser",
546
+ "count": "count"
547
+ },
548
+ "model": "rbac_user",
549
+ "args": {
550
+ "filter": [
551
+ [
552
+ "userType",
553
+ "=",
554
+ "0"
555
+ ]
556
+ ]
557
+ }
558
+ }
559
+ }
560
+ }
561
+
562
+```
563
+
564
+
565
+
566
+### **2.3 搜索视图(Search View)**
567
+
568
+定义列表页顶部的筛选条件。
569
+
570
+##### 1.**基础结构:**
571
+
572
+```json
573
+{
574
+ "rbac_user_search": {
575
+ "name": "用户搜索",
576
+ "model": "rbac_user",
577
+ "type": "search",
578
+ "mode": "primary",
579
+ "body": {
580
+ "type": "search",
581
+ "columns": ["name", "login", "status"]
582
+ }
583
+ }
584
+}
585
+```
586
+
587
+##### 2.**基础搜索示例:**
588
+
589
+```json
590
+{
591
+ "rbac_user_search": {
592
+ "name": "用户搜索",
593
+ "model": "rbac_user",
594
+ "type": "search",
595
+ "mode": "primary",
596
+ "body": {
597
+ "type": "search",
598
+ "columns": [
599
+ {
600
+ "displayName": "姓名",
601
+ "name": "name"
602
+ },
603
+ {
604
+ "displayName": "登录名",
605
+ "name": "login"
606
+ },
607
+ {
608
+ "displayName": "状态",
609
+ "name": "status"
610
+ }
611
+ ]
612
+ }
613
+ }
614
+}
615
+```
616
+
617
+##### 3.高级搜索示例:
618
+
619
+```json
620
+{
621
+ "app_user_search": {
622
+ "mode": "primary",
623
+ "name": "租户用户搜索",
624
+ "model": "rbac_user",
625
+ "type": "search",
626
+ "body": {
627
+ "columns": [
628
+ {
629
+ "displayName": "姓名",
630
+ "name": "name"
631
+ },
632
+ {
633
+ "name": "org_id",
634
+ "custom": true,
635
+ "type": "select",
636
+ "useCustomClick": true,
637
+ "view": {
638
+ "customClick": {
639
+ "customSelect": {
640
+ "showType": "dialog",
641
+ "width": "30%",
642
+ "height": "60vh",
643
+ "useSelectTree": {
644
+ "preId": "rbac_user_app_menu_search_org_id_",
645
+ "type": "single",
646
+ "confirm": "(vm,result)=>{sessionStorage.setItem(vm.data.id+'__values',JSON.stringify([vm.$ds.form[vm.data.name]]))}"
647
+ }
648
+ }
649
+ }
650
+ }
651
+ },
652
+ {
653
+ "displayName": "登录名",
654
+ "name": "login"
655
+ },
656
+ {
657
+ "displayName": "状态",
658
+ "name": "status"
659
+ },
660
+ {
661
+ "label": "接收时间",
662
+ "custom": true,
663
+ "display": true,
664
+ "widget": "datetimerange",
665
+ "name": "create_date"
666
+ }
667
+ ],
668
+ "type": "search",
669
+ "searchByMainTable": {
670
+ "service": {
671
+ "search": "search",
672
+ "count": "count"
673
+ },
674
+ "model": "rbac_user",
675
+ "args": {
676
+ "filter": [
677
+ [
678
+ "userType",
679
+ "=",
680
+ "0"
681
+ ]
682
+ ]
683
+ }
684
+ }
685
+ }
686
+ }
687
+}
688
+```
689
+
690
+##### 4.**支持的时间选择器类型**
691
+
692
+如果字段是日期、时间类型,可以指定 `widget`,前端使用不同的日期组件进行渲染。
693
+目前支持的 `widget` 值如下:
694
+
695
+| widget的值 | 含义 | 示例格式(返回) |
696
+| ------------- | -------- | ----------------------------------------------- |
697
+| year | 选择年份 | 2025 |
698
+| month | 选择月份 | 2025-05 |
699
+| date | 选择日期 | 2025-05-28 |
700
+| datetime | 选择时间 | 2025-05-28 14:30:00 |
701
+| monthrange | 月份范围 | \["2025-01", "2025-05"] |
702
+| daterange | 日期范围 | \["2025-05-01", "2025-05-28"] |
703
+| datetimerange | 时间范围 | \["2025-05-28 00:00:00", "2025-05-28 23:59:59"] |
704
+
705
+**配置示例**
706
+
707
+```
708
+{
709
+ "name": "create_date",
710
+ "label": "创建时间",
711
+ "display": true,
712
+ "custom": true,
713
+ "widget": "datetimerange" // 精确到秒的时间范围
714
+}
715
+```
716
+
717
+
718
+
719
+### **2.4 树视图(Tree View)**
720
+
721
+展示具有层级结构的数据。 树后端视图配置参考文档:http://iidp.chinasie.com:9999/iidpdoc/pages/4f7a25/
722
+
723
+![image-20251229114528096](./images/image-20251229114528096.png)
724
+
725
+##### 1. 基础结构:
726
+
727
+```json
728
+{
729
+ "rbac_user_tree": {
730
+ "name": "用户组织树",
731
+ "model": "rbac_user",
732
+ "type": "tree",
733
+ "mode": "primary",
734
+ "body": {
735
+ "type": "tree",
736
+ "model": "rbac_organization",
737
+ "columns": [
738
+ "name",
739
+ "parent_id",
740
+ "description"
741
+ ],
742
+ "props": {
743
+ "parent": "parent_id",
744
+ "label": "name",
745
+ "subApp": "base",
746
+ "subModel": "rbac_user",
747
+ "subViewType": "rbac_organization_grid,rbac_organization_search,rbac_organization_form",
748
+ "subViewFilter": "org_id",
749
+ "subViewFromDefault": "id",
750
+ "hasIcon": true
751
+ },
752
+ "tbar": [
753
+ "@defaults"
754
+ ],
755
+ "buttons": [
756
+ "@defaults"
757
+ ]
758
+ }
759
+ }
760
+}
761
+```
762
+
763
+**props参数说明:**
764
+
765
+| 参数 | 类型 | 描述 |
766
+| ------------------- | ------- | ---------------- |
767
+| `children` | String | 子节点字段名 |
768
+| `parent` | String | 父节点字段名 |
769
+| `label` | String | 显示标签字段 |
770
+| `expandOnClickNode` | Boolean | 点击节点是否展开 |
771
+| `hasIcon` | Boolean | 是否显示图标 |
772
+
773
+##### 2. 树高级示例:
774
+
775
+```json
776
+{
777
+ "rbac_role_tree": {
778
+ "name": "角色树",
779
+ "model": "rbac_role",
780
+ "type": "tree",
781
+ "mode": "primary",
782
+ "body": {
783
+ "type": "tree",
784
+ "model": "rbac_role",
785
+ "columns": [
786
+ "name",
787
+ "code",
788
+ "type",
789
+ "path",
790
+ "parent"
791
+ ],
792
+ "props": {
793
+ "showRoot": true,
794
+ "parent": "parent",
795
+ "label": "name",
796
+ "subApp": "sie-iidp-iam",
797
+ "subModel": "rbac_role",
798
+ "subViewType": "rbac_role_grid,rbac_role_search,rbac_role_form",
799
+ "subViewFilter": "parent",
800
+ "subViewFilterValue": "id",
801
+ "expandOnClickNode": false,
802
+ "hasIcon": false,
803
+ "showTree": true,
804
+ "customSubViewType": "rbac_role_simple_form"
805
+ },
806
+ "tbar": [
807
+ {
808
+ "action": "create",
809
+ "name": "新增"
810
+ },
811
+ {
812
+ "action": "viewAll",
813
+ "name": "全部",
814
+ "icon": "iconfont icon-tushi"
815
+ }
816
+ ],
817
+ "searchConfig": {
818
+ "model": "rbac_role",
819
+ "service": "queryRoleTree",
820
+ "args": {
821
+ "useDisplayForModel": true,
822
+ "filter": [
823
+ [
824
+ "roleType",
825
+ "=",
826
+ "0"
827
+ ]
828
+ ],
829
+ "order": "id"
830
+ }
831
+ },
832
+ "buttons": [
833
+ {
834
+ "action": "create"
835
+ },
836
+ {
837
+ "action": "edit"
838
+ },
839
+ {
840
+ "action": "delete",
841
+ "message": "删除角色,将同步删除当前角色、当前角色下的所有子级角色,请确认是否删除?"
842
+ }
843
+ ]
844
+ }
845
+ }
846
+}
847
+```
848
+
849
+
850
+
851
+### 2.5 上下表视图 "typeView": "subTable"
852
+
853
+参考文档:http://iidp.chinasie.com:9999/iidpdoc/pages/b76191/#%E4%B8%8A%E4%B8%8B%E8%A1%A8%E6%A0%BC%E6%A8%A1%E6%9D%BF
854
+
855
+#### 上下表格模板配置
856
+
857
+- typeView 控制子表的显示隐藏 在表格配置
858
+- dbClickEnterDetails 禁止双击进入详情页
859
+
860
+```
861
+{
862
+ "mbm_main_process_tech_route_grid": {
863
+ "body": {
864
+ "buttons": [
865
+ {
866
+ "action": "preview",
867
+ "auth": "read",
868
+ "name": "详情"
869
+ },
870
+ {
871
+ "action": "edit",
872
+ "auth": "update",
873
+ "name": "编辑",
874
+ "enableCondition": "(row) => {\r\n if (row[0].isEnable.value == '1') {\r\n return false\r\n } else {\r\n return true\r\n }\r\n }"
875
+ }
876
+ ],
877
+ "columns": [
878
+ {
879
+ "displayName": "编码",
880
+ "name": "code"
881
+ },
882
+ {
883
+ "label": "名称",
884
+ "name": "name"
885
+ },
886
+ {
887
+ "displayName": "状态",
888
+ "name": "isEnable"
889
+ },
890
+ {
891
+ "displayName": "制程数",
892
+ "name": "processNum"
893
+ }
894
+ ],
895
+ "tbar": [
896
+ {
897
+ "action": "create",
898
+ "auth": "create",
899
+ "name": "新增"
900
+ },
901
+ {
902
+ "action": "delete",
903
+ "auth": "delete",
904
+ "name": "删除"
905
+ },
906
+ {
907
+ "action": "enable",
908
+ "auth": "enable",
909
+ "name": "启用",
910
+ "model": "ProcessTechRouteVO",
911
+ "service": "enable",
912
+ "actionAfter": "refreshTable",
913
+ "options": {
914
+ "icon": "el-icon-open"
915
+ },
916
+ "args": {
917
+ "bind_ids": "$ds.checkedDataIds"
918
+ },
919
+ "bind_disabled": "${$ds.checkedDataList.length === 0}"
920
+ },
921
+ {
922
+ "name": "禁用",
923
+ "action": "disable",
924
+ "auth": "disable",
925
+ "model": "ProcessTechRouteVO",
926
+ "service": "disable",
927
+ "actionAfter": "refreshTable",
928
+ "options": {
929
+ "icon": "el-icon-turn-off"
930
+ },
931
+ "args": {
932
+ "bind_ids": "$ds.checkedDataIds"
933
+ },
934
+ "bind_disabled": "${$ds.checkedDataList.length === 0}"
935
+ },
936
+ {
937
+ "name": "导出",
938
+ "action": "export",
939
+ "source": "selected",
940
+ "properties": [
941
+ "code",
942
+ "name",
943
+ "isEnable",
944
+ "processNum",
945
+ "create_user",
946
+ "create_date",
947
+ "update_user",
948
+ "update_date"
949
+ ],
950
+ "model": "ProcessTechRouteVO",
951
+ "service": "excelExport"
952
+ }
953
+ ],
954
+ "checkbox": "multiple_2",
955
+ "type": "grid",
956
+ "typeView": "subTable"
957
+ },
958
+ "mode": "primary",
959
+ "model": "ProcessTechRouteVO",
960
+ "name": "制程工艺路线-表格",
961
+ "type": "grid"
962
+ }
963
+}
964
+```
965
+
966
+
967
+
968
+
969
+
970
+### 2.5 完整的视图示例:
971
+
972
+```json
973
+{
974
+ "data": {},
975
+ "views": {
976
+ "rbac_role_grid": {
977
+ "name": "角色表格",
978
+ "model": "rbac_role",
979
+ "type": "grid",
980
+ "mode": "primary",
981
+ "body": {
982
+ "type": "grid",
983
+ "columns": [
984
+ "name",
985
+ "code",
986
+ "is_admin",
987
+ "remark",
988
+ "update_user",
989
+ "update_date",
990
+ "create_user",
991
+ "create_date",
992
+ {
993
+ "name": "path",
994
+ "custom": true,
995
+ "hidden": true
996
+ }
997
+ ],
998
+ "buttons": [
999
+ {
1000
+ "name": "详情",
1001
+ "action": "preview",
1002
+ "auth": "read"
1003
+ },
1004
+ {
1005
+ "name": "编辑",
1006
+ "action": "edit",
1007
+ "auth": "update"
1008
+ },
1009
+ {
1010
+ "name": "授权",
1011
+ "model": "rbac_role",
1012
+ "auth": "authPermission",
1013
+ "service": "authPermission",
1014
+ "views": "custom"
1015
+ },
1016
+ {
1017
+ "name": "复制",
1018
+ "model": "rbac_role",
1019
+ "service": "copy",
1020
+ "auth": "copy"
1021
+ }
1022
+ ],
1023
+ "tbar": [
1024
+ {
1025
+ "name": "新增",
1026
+ "action": "create",
1027
+ "auth": "create"
1028
+ },
1029
+ {
1030
+ "name": "删除",
1031
+ "action": "delete",
1032
+ "auth": "delete"
1033
+ },
1034
+ {
1035
+ "name":"导入",
1036
+ "action": "import",
1037
+ "model": "rbac_role",
1038
+ "service": "Import",
1039
+ "fileLimit": {
1040
+ "ext": ".xls,.xlsx",
1041
+ "maxSize": "2048"
1042
+ }
1043
+ },
1044
+ {
1045
+ "name": "导出",
1046
+ "action": "export",
1047
+ "properties": ["name","code","is_admin","remark","tenant_id"],
1048
+ "model": "rbac_role",
1049
+ "service": "export"
1050
+ }
1051
+ ]
1052
+ }
1053
+ },
1054
+ "rbac_role_form": {
1055
+ "name": "角色表单",
1056
+ "model": "rbac_role",
1057
+ "type": "form",
1058
+ "mode": "primary",
1059
+ "body": {
1060
+ "type": "form",
1061
+ "columns": [
1062
+ "name",
1063
+ "is_admin",
1064
+ "code",
1065
+ "remark",
1066
+ {
1067
+ "displayName": "父角色",
1068
+ "name": "parent",
1069
+ "display": true
1070
+ }
1071
+ ],
1072
+ "tabs": [
1073
+ {
1074
+ "header": "用户",
1075
+ "rowspan": 3,
1076
+ "tbar": [
1077
+ {
1078
+ "name": "添加",
1079
+ "action": "addEr",
1080
+ "auth": "update"
1081
+ },
1082
+ {
1083
+ "name": "删除",
1084
+ "action": "deleteEr",
1085
+ "auth": "delete"
1086
+ }
1087
+ ],
1088
+ "body": {
1089
+ "type": "grid,search",
1090
+ "field": "user_ids",
1091
+ "columns": [
1092
+ "login",
1093
+ "name",
1094
+ "email",
1095
+ "mobile",
1096
+ "status"
1097
+ ]
1098
+ }
1099
+ }
1100
+ ]
1101
+ }
1102
+ },
1103
+ "rbac_role_simple_form": {
1104
+ "name": "角色表单",
1105
+ "model": "rbac_role",
1106
+ "type": "form",
1107
+ "mode": "primary",
1108
+ "body": {
1109
+ "type": "form",
1110
+ "columns": [
1111
+ "name",
1112
+ "code",
1113
+ "remark",
1114
+ {
1115
+ "displayName": "父角色",
1116
+ "custom": true,
1117
+ "name": "parent",
1118
+ "bind_disabled": "${$ds.clickType != 'add'}",
1119
+ "type": "select",
1120
+ "required": true,
1121
+ "getData": "async({config})=>{const res=await window.Tech.httpMeta({data:{params:{app:'sie-iidp-iam',model:'rbac_role',service:'lookupParentRole',args:{}}}});if(res?.data){return{items:res.data}}return[]}"
1122
+ },
1123
+ {
1124
+ "displayName": "角色类型",
1125
+ "name": "roleType",
1126
+ "hidden": true
1127
+ },
1128
+ {
1129
+ "displayName": "可删",
1130
+ "name": "roleDelete",
1131
+ "hidden": true
1132
+ }
1133
+ ],
1134
+ "tabs": []
1135
+ }
1136
+ },
1137
+ "rbac_role_search": {
1138
+ "name": "角色查询",
1139
+ "model": "rbac_role",
1140
+ "mode": "primary",
1141
+ "type": "search",
1142
+ "body": {
1143
+ "type": "search",
1144
+ "columns": [
1145
+ "name",
1146
+ "code"
1147
+ ]
1148
+ }
1149
+ },
1150
+ "rbac_role_tree": {
1151
+ "name": "角色树",
1152
+ "model": "rbac_role",
1153
+ "type": "tree",
1154
+ "mode": "primary",
1155
+ "body": {
1156
+ "type": "tree",
1157
+ "model": "rbac_role",
1158
+ "columns": [
1159
+ "name",
1160
+ "code",
1161
+ "type",
1162
+ "path",
1163
+ "parent"
1164
+ ],
1165
+ "props": {
1166
+ "showRoot": true,
1167
+ "parent": "parent",
1168
+ "label": "name",
1169
+ "subApp": "sie-iidp-iam",
1170
+ "subModel": "rbac_role",
1171
+ "subViewType": "rbac_role_grid,rbac_role_search,rbac_role_form",
1172
+ "subViewFilter": "parent",
1173
+ "subViewFilterValue": "id",
1174
+ "expandOnClickNode": false,
1175
+ "hasIcon": false,
1176
+ "showTree": true,
1177
+ "customSubViewType": "rbac_role_simple_form",
1178
+ "maxLevel": 10
1179
+ },
1180
+ "tbar": [
1181
+ {
1182
+ "action": "create",
1183
+ "name": "新增"
1184
+ },
1185
+ {
1186
+ "action": "viewAll",
1187
+ "name": "全部",
1188
+ "icon": "iconfont icon-tushi"
1189
+ }
1190
+ ],
1191
+ "searchConfig": {
1192
+ "model": "rbac_role",
1193
+ "service": "queryRoleTree",
1194
+ "args": {
1195
+ "useDisplayForModel": true,
1196
+ "filter": [
1197
+ [
1198
+ "roleType",
1199
+ "=",
1200
+ "0"
1201
+ ]
1202
+ ],
1203
+ "order": "id",
1204
+ "showRoot": false
1205
+ }
1206
+ },
1207
+ "buttons": [
1208
+ {
1209
+ "action": "create",
1210
+ "parentDisabled": true
1211
+ },
1212
+ {
1213
+ "action": "edit"
1214
+ },
1215
+ {
1216
+ "action": "delete",
1217
+ "message":"删除角色,将同步删除当前角色、当前角色下的所有子级角色,请确认是否删除?"
1218
+ }
1219
+ ]
1220
+ }
1221
+ }
1222
+ }
1223
+}
1224
+
1225
+```
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+## **第三章:基础组件配置**
1232
+
1233
+### **3.1 字段配置(Columns)**
1234
+
1235
+**3.1.1 简单字段定义**
1236
+
1237
+```json
1238
+"columns": [
1239
+ "name", // 字符串形式,使用默认配置
1240
+ "login",
1241
+ "mobile"
1242
+]
1243
+```
1244
+
1245
+**3.1.2 详细字段定义**
1246
+
1247
+```json
1248
+"columns": [
1249
+ {
1250
+ "name": "name", // 字段名称(必填)
1251
+ "displayName": "姓名", // 显示名称
1252
+ "sortable": true, // 是否可排序
1253
+ "hidden": false, // 在表格中是否隐藏
1254
+ "custom": true // 是否自定义渲染
1255
+ }
1256
+]
1257
+```
1258
+
1259
+**3.1.3 字段分组(Form中使用)**
1260
+
1261
+```json
1262
+{
1263
+ "name": "min_length",
1264
+ "displayName": "最小长度",
1265
+ "span": "6", // 宽度(总24格)
1266
+ "groupConf": {
1267
+ "name": "密码策略", // 分组名称
1268
+ "id": "group1" // 分组ID
1269
+ }
1270
+}
1271
+```
1272
+
1273
+### **3.2 工具栏(tbar)**
1274
+
1275
+**3.2.1 默认工具栏**
1276
+
1277
+```json
1278
+"tbar": ["@defaults"]
1279
+```
1280
+
1281
+- **grid视图**:默认添加"新增"、"删除"按钮
1282
+- **form视图**:默认添加"保存"按钮
1283
+
1284
+**3.2.2 自定义工具栏按钮**
1285
+
1286
+```json
1287
+"tbar": [
1288
+ {
1289
+ "name": "新增", // 按钮显示文本
1290
+ "action": "create", // 动作类型
1291
+ "auth": "create", // 权限标识
1292
+ "icon": "el-icon-plus" // 图标(可选)
1293
+ },
1294
+ {
1295
+ "name": "删除",
1296
+ "action": "delete",
1297
+ "auth": "delete"
1298
+ }
1299
+]
1300
+
1301
+// 自定义配置 - ER操作
1302
+"tbar": [
1303
+ { "name": "添加关联", "action": "addEr", "auth": "update" },
1304
+ { "name": "删除关联", "action": "deleteEr", "auth": "delete" }
1305
+]
1306
+```
1307
+
1308
+**3.2.3 常用 Action 值**
1309
+
1310
+| Action | 说明 | 适用场景 |
1311
+| :-------------- | :--------- | :--------- |
1312
+| **`create`** | 创建记录 | 通用新建 |
1313
+| **`delete`** | 删除记录 | 通用删除 |
1314
+| **`import`** | 导入数据 | 批量导入 |
1315
+| **`export`** | 导出数据 | 数据导出 |
1316
+| **`createEr`** | 创建ER关系 | 多对多关联 |
1317
+| **`addEr`** | 添加ER关系 | 添加关联 |
1318
+| **`deleteEr`** | 删除ER关系 | 移除关联 |
1319
+| **`updateEr`** | 更新ER关系 | 修改关联 |
1320
+| **`@defaults`** | 默认配置 | 快速配置 |
1321
+
1322
+
1323
+
1324
+### **3.3 行操作按钮(buttons)**
1325
+
1326
+**核心参数**
1327
+
1328
+- **`name`** - 按钮文本
1329
+- **`action`** - 动作类型
1330
+- **`auth`** - 权限标识
1331
+- **`service`** - 后端服务名
1332
+- **`enableCondition`** - 启用条件
1333
+
1334
+**3.3.1 默认按钮配置**
1335
+
1336
+```json
1337
+"buttons": ["@defaults"]
1338
+```
1339
+
1340
+自动添加“详情”、“编辑”按钮
1341
+
1342
+**3.3.2 自定义按钮配置**
1343
+
1344
+```json
1345
+"buttons": [
1346
+ {
1347
+ "name": "编辑",
1348
+ "action": "edit",
1349
+ "auth": "update"
1350
+ },
1351
+ {
1352
+ "name": "重置密码",
1353
+ "auth": "resetPassword",
1354
+ "service": "resetPassword", // 调用的后台服务
1355
+ "action": "openView" // 打开视图
1356
+ }
1357
+]
1358
+```
1359
+
1360
+**3.3.3 常用 Action 值**
1361
+
1362
+**基础操作**
1363
+
1364
+- **`preview`** - 查看详情
1365
+
1366
+- **`edit`** - 编辑记录
1367
+
1368
+- **`delete`**- 删除记录
1369
+
1370
+- **`openView`** - 打开自定义视图
1371
+
1372
+
1373
+
1374
+**核心参数**
1375
+
1376
+- **`name`** - 按钮文本
1377
+
1378
+- **`action`** - 动作类型
1379
+
1380
+- **`auth`** - 权限标识
1381
+
1382
+- **`service`** - 后端服务名
1383
+
1384
+- **`enableCondition`** - 启用条件
1385
+
1386
+
1387
+
1388
+**3.3.4 完整示例**
1389
+
1390
+```json
1391
+"buttons": [
1392
+ {
1393
+ "action": "preview",
1394
+ "auth": "read",
1395
+ "name": "详情"
1396
+ },
1397
+ {
1398
+ "action": "edit",
1399
+ "auth": "update",
1400
+ "name": "编辑"
1401
+ },
1402
+ {
1403
+ "action": "preview",
1404
+ "auth": "read",
1405
+ "name": "详情",
1406
+ "enableCondition": "(row,vm) => { return row && row[0] && row[0].type != 'TENANT_SG'; }"
1407
+ },
1408
+ {
1409
+ "action": "edit",
1410
+ "auth": "update",
1411
+ "name": "编辑",
1412
+ "enableCondition": "(row,vm) => { const hasUniqueElements = (userRoles, authRoles) => userRoles.some(item => !authRoles.includes(item.id)); return row && row[0] && row[0].type != 'TENANT_SG' && (tech.userInfo.roles.find(item => item.code == 'rbac_role_tenant_admin') != null || row[0].noAuthRoles == null || hasUniqueElements(tech.userInfo.roles, row[0].noAuthRoles)) }"
1413
+ },
1414
+ {
1415
+ "action": "edit",
1416
+ "auth": "update",
1417
+ "buttonType": "copy",
1418
+ "name": "复制",
1419
+ "enableCondition": "(row,vm) => { return row && row[0] && row[0].type != 'TENANT_SG'; }"
1420
+ },
1421
+ {
1422
+ "action": "delete",
1423
+ "auth": "delete",
1424
+ "name": "删除",
1425
+ "model": "tenant_action_scope",
1426
+ "service": "delete",
1427
+ "actionAfter": "refreshTable",
1428
+ "args": {
1429
+ "id": "$row.id"
1430
+ },
1431
+ "enableCondition": "(row,vm) => { const hasUniqueElements = (userRoles, authRoles) => userRoles.some(item => !authRoles.includes(item.id)); return row && row[0] && row[0].type != 'TENANT_SG' && (tech.userInfo.roles.find(item => item.code == 'rbac_role_tenant_admin') != null || row[0].noAuthRoles == null || hasUniqueElements(tech.userInfo.roles, row[0].noAuthRoles)) }"
1432
+ }
1433
+]
1434
+```
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+## **第四章:模型关系(ER)集成**
1441
+
1442
+### **4.1 一对多关系(OneToMany)**
1443
+
1444
+```json
1445
+{
1446
+ "name": "meta_app_category_form",
1447
+ "model": "meta_app_category",
1448
+ "body": {
1449
+ "type": "form",
1450
+ "columns": [
1451
+ "name",
1452
+ "app_ids" // 必须包含关联字段
1453
+ ],
1454
+ "tabs": [
1455
+ {
1456
+ "header": "应用",
1457
+ "body": {
1458
+ "type": "meta_app_grid",
1459
+ "field": "app_ids", // 关联字段名
1460
+ "columns": ["name", "state"]
1461
+ },
1462
+ "tbar": [
1463
+ {
1464
+ "name": "添加",
1465
+ "action": "addEr", // ER操作需带Er后缀
1466
+ "auth": "update"
1467
+ }
1468
+ ]
1469
+ }
1470
+ ]
1471
+ }
1472
+}
1473
+```
1474
+
1475
+### **4.2 多对多 模型-属性(ManyToMany)**
1476
+
1477
+```json
1478
+{
1479
+ "app_user_form": {
1480
+ "mode": "primary",
1481
+ "name": "用户管理表单",
1482
+ "model": "rbac_user",
1483
+ "type": "form",
1484
+ "body": {
1485
+ "buttons": [
1486
+ "@defaults"
1487
+ ],
1488
+ "tabs": [
1489
+ {
1490
+ "header": "角色",//ER关系tabs标题
1491
+ "tbar": [
1492
+ {
1493
+ "name": "设置角色",
1494
+ "action": "addEr",//ER关系tbar,action需要带后缀er
1495
+ "auth": "update"
1496
+ },
1497
+ {
1498
+ "name": "删除",
1499
+ "action": "deleteEr",//ER关系tbar,action需要带后缀er
1500
+ "auth": "delete"
1501
+ }
1502
+ ],
1503
+ "body": {
1504
+ "type": "app_role_grid,app_role_search,app_role_form",//ER关系模型的视图key
1505
+ "field": "role_ids",//关联的属性必填
1506
+ "columns": [//ER关系模型显示的字段
1507
+ "name",
1508
+ "code",
1509
+ "remark"
1510
+ ]
1511
+ }
1512
+ },
1513
+ {
1514
+ "header": "用户组",//ER关系tabs标题
1515
+ "tbar": [
1516
+ {
1517
+ "name": "设置用户组",
1518
+ "action": "addEr",//ER关系tbar,action需要带后缀er
1519
+ "auth": "update"
1520
+ },
1521
+ {
1522
+ "name": "删除",
1523
+ "action": "deleteEr",//ER关系tbar,action需要带后缀er
1524
+ "auth": "delete"
1525
+ }
1526
+ ],
1527
+ "body": {
1528
+ "type": "app_user_group_grid,app_user_group_form,app_user_group_search",//对方模型的视图
1529
+ "field": "userGroupList",//关联的Many2Many属性必填
1530
+ "columns": [
1531
+ "name",
1532
+ "description"
1533
+ ]
1534
+ }
1535
+ },
1536
+ {
1537
+ "header": "关联维度",
1538
+ "tbar": [
1539
+ {
1540
+ "name": "设置维度数据",
1541
+ "action": "addEr",
1542
+ "auth": "update"
1543
+ },
1544
+ {
1545
+ "name": "删除",
1546
+ "action": "deleteEr",
1547
+ "auth": "delete"
1548
+ }
1549
+ ],
1550
+ "body": {
1551
+ "type": "app_role_grid,app_role_search,app_role_form",
1552
+ "field": "role_ids",
1553
+ "checkbox": "multiple_2",
1554
+ "checkType": "bgSync",
1555
+ "columns": [
1556
+ "name",
1557
+ "code",
1558
+ "remark"
1559
+ ]
1560
+ }
1561
+ }
1562
+ ],
1563
+ "columns": [
1564
+ "name",
1565
+ {
1566
+ "name": "org_id",
1567
+ "custom": true
1568
+ },
1569
+ "login",
1570
+ {
1571
+ "name": "password",
1572
+ "custom": true,
1573
+ "bind_display": "${$ds.clickType==='add'}"
1574
+ },
1575
+ "remark",
1576
+ {
1577
+ "label": "租户",
1578
+ "name": "tenant_id",
1579
+ "display": true,
1580
+ "disabled": true
1581
+ }
1582
+ ],
1583
+ "type": "form"
1584
+ }
1585
+ }
1586
+}
1587
+```
1588
+
1589
+## **第五章:菜单配置**
1590
+
1591
+### **5.1 基础菜单定义**
1592
+
1593
+```json
1594
+{
1595
+ "menus": {
1596
+ "rbac_user_app_menu": {
1597
+ "sequence": "10", // 排序号
1598
+ "view": "rbac_user_grid,rbac_user_form", // 关联的视图
1599
+ "name": "rbac_user_app_menu", // 菜单唯一标识
1600
+ "model": "rbac_user", // 关联的模型
1601
+ "display_name": "用户管理", // 显示名称
1602
+ "parent_ids": {
1603
+ "@ref": "rbac_user_permission_menu" // 父菜单引用
1604
+ }
1605
+ }
1606
+ }
1607
+}
1608
+```
1609
+
1610
+### **5.2 菜单树配置**
1611
+
1612
+```json
1613
+{
1614
+ "menus": {
1615
+ "base_developer_center": {
1616
+ "sequence": "31",
1617
+ "name": "base_developer_center",
1618
+ "display_name": "开发者中心"
1619
+ },
1620
+ "meta_model_menu": {
1621
+ "sequence": "5",
1622
+ "name": "meta_model_menu",
1623
+ "display_name": "模型",
1624
+ "parent_ids": {
1625
+ "@ref": "base_developer_center" // 第一级子菜单
1626
+ }
1627
+ },
1628
+ "meta_sub_model_menu": {
1629
+ "sequence": "5",
1630
+ "name": "meta_sub_model_menu",
1631
+ "display_name": "子模型",
1632
+ "parent_ids": {
1633
+ "@ref": "meta_model_menu" // 第二级子菜单
1634
+ }
1635
+ }
1636
+ }
1637
+}
1638
+```
1639
+
1640
+## **第六章:种子数据(Data)**
1641
+
1642
+### **6.1 基础数据定义**
1643
+
1644
+```json
1645
+{
1646
+ "data": {
1647
+ "rbac_role_admin": {
1648
+ "model": "rbac_role", // 模型名称
1649
+ "properties": { // 字段属性
1650
+ "name": "管理员",
1651
+ "is_admin": 1
1652
+ }
1653
+ }
1654
+ }
1655
+}
1656
+```
1657
+
1658
+### **6.2 关联数据定义**
1659
+
1660
+```json
1661
+{
1662
+ "rbac_user_admin": {
1663
+ "model": "rbac_user",
1664
+ "properties": {
1665
+ "name": "管理员",
1666
+ "login": "admin",
1667
+ "role_ids": [ // 多对多关联
1668
+ {
1669
+ "@eval": "[4, @ref(rbac_role_admin), 0]" // Many2Many指令
1670
+ }
1671
+ ]
1672
+ }
1673
+ }
1674
+}
1675
+```
1676
+
1677
+**@eval指令说明**:`[4, @ref(rbac_role_admin), 0]`
1678
+
1679
+- `@ref(rbac_role_admin)`:引用已生成的`rbac_role_admin`记录ID
1680
+
1681
+
1682
+
1683
+## 第七章:基础开发流程
1684
+
1685
+### **7.1 开发步骤**
1686
+
1687
+1. **定义模型**:确保后端元模型已正确定义
1688
+2. **创建视图文件**:在`views/`目录下创建JSON文件
1689
+3. **配置基础视图**:按需创建form、grid、search、tree视图
1690
+4. **配置菜单**:在`menu_view.json`中定义导航菜单
1691
+5. **配置种子数据**:在`data/`目录下创建初始数据
1692
+6. **更新app.json**:添加视图文件路径
1693
+7. **测试验证**:部署后测试功能
1694
+
1695
+### **7.2 文件命名规范**
1696
+
1697
+- 模型相关视图:`{model_name}_view.json`
1698
+- 菜单配置:`menu_view.json`
1699
+- 种子数据:`{model_name}.json`
1700
+
1701
+### **7.3 最佳实践**
1702
+
1703
+1. **先模型后视图**:确保模型字段正确定义后再开发视图
1704
+2. **使用默认配置**:优先使用`@defaults`减少配置量
1705
+3. **保持一致性**:相同模型的视图配置保持统一风格
1706
+
1707
+---
1708
+
1709
+
1710
+
1711
+# **第二部分:高级视图开发**
1712
+
1713
+
1714
+
1715
+## **第八章:自定义交互与联动**
1716
+
1717
+### **8.1 字段联动配置**
1718
+
1719
+#### **8.1.1 值变化监听(`bind_on_changeHandler`)**
1720
+
1721
+当字段值发生变化时执行自定义逻辑:
1722
+
1723
+```json
1724
+{
1725
+ "name": "complexity",
1726
+ "bind_on_changeHandler": "(params) => {
1727
+ const {self: vm, value} = params;
1728
+ const form = vm.$ds.form;
1729
+
1730
+ let desc = '必须包含大、小写字母、数字和特殊字符的三种组合';
1731
+ let min_length = 8;
1732
+
1733
+ if(value === 'SIMPLE') {
1734
+ desc = '可以包含任意字符';
1735
+ min_length = 4;
1736
+ } else if(value === 'WEAK') {
1737
+ desc = '必须包含大、小写字母和数字的组合,不能包含特殊字符';
1738
+ min_length = 6;
1739
+ } else if(value === 'STRONG') {
1740
+ desc = '必须包含大、小写字母、数字和特殊字符的四种组合';
1741
+ min_length = 10;
1742
+ }
1743
+
1744
+ form.min_length = min_length;
1745
+ form.description = desc;
1746
+ }"
1747
+}
1748
+```
1749
+
1750
+**参数说明:**
1751
+
1752
+- `params.self`:当前字段组件实例
1753
+- `params.value`:字段变化后的值
1754
+- `vm.$ds.form`:访问表单数据对象
1755
+
1756
+#### **8.1.2 输入框失焦处理(`bind_on_handleInputBlur`)**
1757
+
1758
+```json
1759
+{
1760
+ "name": "token_expire_min",
1761
+ "bind_on_handleInputBlur": "(data) => {
1762
+ const val = data.self.$ds.form.token_expire_min.replace(/[^\d\-]/g, '');
1763
+ let newValue = val;
1764
+
1765
+ // 处理多个负号的情况
1766
+ if (val.indexOf('-') > 0) {
1767
+ newValue = val.replace(/-/g, '');
1768
+ }
1769
+ if ((val.match(/-/g) || []).length > 1) {
1770
+ newValue = '-' + val.substring(1).replace(/-/g, '');
1771
+ }
1772
+
1773
+ // 确保为正数
1774
+ if (newValue < 0) {
1775
+ newValue = Math.abs(newValue).toString();
1776
+ }
1777
+
1778
+ data.self.$ds.form.token_expire_min = newValue;
1779
+ }"
1780
+}
1781
+```
1782
+
1783
+#### **8.1.3 字段联动(`linkage`)**
1784
+
1785
+实现字段间的依赖关系:
1786
+
1787
+```json
1788
+{
1789
+ "name": "ruleType",
1790
+ "linkage": {
1791
+ "params": {}, // 传递的参数
1792
+ "children": ["parentId"] // 影响的子字段
1793
+ }
1794
+},
1795
+{
1796
+ "name": "parentId",
1797
+ "linkage": {
1798
+ "params": {
1799
+ "ruleType": "${ruleType}" // 获取ruleType字段的值
1800
+ }
1801
+ }
1802
+}
1803
+```
1804
+
1805
+### **8.2 条件渲染与显示控制**
1806
+
1807
+#### **8.2.1 表达式条件渲染(`bind_display`)**
1808
+
1809
+```json
1810
+{
1811
+ "name": "logoutAllClient",
1812
+ "bind_display": "${$ds.form.token_policy === 'MULTI_CLIENT'}"
1813
+}
1814
+```
1815
+
1816
+**支持的表达式语法:**
1817
+
1818
+- `$ds.form.fieldName`:访问表单字段值
1819
+- `$ds.mainTableRowData.fieldName`:访问表格行数据
1820
+
1821
+#### **8.2.2 函数条件渲染**
1822
+
1823
+```json
1824
+{
1825
+ "bind_display": {
1826
+ "transform": "(params) => {
1827
+ return window.tech?.userInfo?.userTenantInfo?.hasChildren ? true : false;
1828
+ }"
1829
+ }
1830
+}
1831
+```
1832
+
1833
+#### **8.2.3 禁用条件(`bind_disabled`)**
1834
+
1835
+```json
1836
+{
1837
+ "name": "type",
1838
+ "bind_disabled": "${$ds.mainTableRowData.source == 'SYSTEM_BUILT_IN'}"
1839
+}
1840
+```
1841
+
1842
+#### **8.2.4 编辑状态控制(`disable_update`)**
1843
+
1844
+```json
1845
+{
1846
+ "name": "mobile",
1847
+ "disable_update": "edit" // 编辑状态下禁用
1848
+}
1849
+```
1850
+
1851
+### **8.3 数据转换处理**
1852
+
1853
+#### **8.3.1 表单初始化转换(`transformInitValue`)**
1854
+
1855
+```json
1856
+{
1857
+ "transformInitValue": "(form) => {
1858
+ // 将数字类型转换为字符串
1859
+ if (typeof form.token_expire_min == 'number') {
1860
+ form.token_expire_min = form.token_expire_min.toString();
1861
+ }
1862
+ return form;
1863
+ }"
1864
+}
1865
+```
1866
+
1867
+#### **8.3.2 表单数据转换(`transformRes`)**
1868
+
1869
+```json
1870
+{
1871
+ "transformRes": "(form) => {
1872
+ // 将关联字段的显示值保存到新字段
1873
+ form.modelDisplayName = form.modelMetaId___values?.label;
1874
+ form.relQueryModelDisplayName = form.relQueryModelMetaId___values?.label;
1875
+ return form;
1876
+ }"
1877
+}
1878
+```
1879
+
1880
+**注意**:关联字段的值通常以`___values`后缀对象存储完整信息,如:
1881
+
1882
+- `modelMetaId`:存储ID值
1883
+- `modelMetaId___values`:存储完整的对象信息 `{value: 'id', label: '显示名'}`
1884
+
1885
+#### **8.3.3 请求参数预处理(`reqPrep`)**
1886
+
1887
+```json
1888
+{
1889
+ "name": "propertyMetaId",
1890
+ "reqPrep": "(vm, options) => {
1891
+ let commonForm = vm.$select('tenant_action_dimension__drawer_form_main_detail_top_common');
1892
+ if(commonForm.$ds.modelMetaId) {
1893
+ options.args.modelMetaId = commonForm.$ds.modelMetaId;
1894
+ }
1895
+ options.args.useDisplayForModel = true;
1896
+ return options;
1897
+ }"
1898
+}
1899
+```
1900
+
1901
+#### **8.3.4 请求响应后处理(`reqAfter`)**
1902
+
1903
+```json
1904
+{
1905
+ "reqAfter": "(vm, res) => {
1906
+ let common = vm.$select('tenant_action_dimension__drawer_form_main_detail_top_common');
1907
+ if(common.$ds.modelMetaId) {
1908
+ return res;
1909
+ }
1910
+ return [];
1911
+ }"
1912
+}
1913
+```
1914
+
1915
+### **8.4 按钮条件控制**
1916
+
1917
+#### **8.4.1 启用条件(`enableCondition`)**
1918
+
1919
+```json
1920
+{
1921
+ "name": "安装",
1922
+ "enableCondition": "function condition(row) {
1923
+ return row && row[0] && row[0].state === 'installable';
1924
+ }"
1925
+}
1926
+```
1927
+
1928
+#### **8.4.2 复杂条件判断**
1929
+
1930
+```json
1931
+{
1932
+ "name": "编辑",
1933
+ "enableCondition": "(row, vm) => {
1934
+ const hasUniqueElements = (userRoles, authRoles) =>
1935
+ userRoles.some(item => !authRoles.includes(item.id));
1936
+
1937
+ return row && row[0] && row[0].type != 'TENANT_SG' &&
1938
+ (tech.userInfo.roles.find(item => item.code == 'rbac_role_tenant_admin') != null ||
1939
+ row[0].noAuthRoles == null ||
1940
+ hasUniqueElements(tech.userInfo.roles, row[0].noAuthRoles));
1941
+ }"
1942
+}
1943
+```
1944
+
1945
+## **第九章:高级选择器与弹窗**
1946
+
1947
+### **9.1 树形选择器(`useSelectTree`)**
1948
+
1949
+#### **9.1.1 基础树选择器**
1950
+
1951
+```json
1952
+{
1953
+ "name": "parent_id",
1954
+ "type": "select",
1955
+ "useCustomClick": true,
1956
+ "view": {
1957
+ "customClick": {
1958
+ "customSelect": {
1959
+ "showType": "dialog",
1960
+ "width": "30%",
1961
+ "height": "60vh",
1962
+ "useSelectTree": {
1963
+ "preId": "organization_tree_main_wrap_right_form_items_0_items_parent_id_",
1964
+ "type": "single", // 单选模式
1965
+ "confirm": "(vm, result) => {
1966
+ // 选择确认后的回调
1967
+ sessionStorage.setItem(vm.data.id + '__values', JSON.stringify([vm.$ds.form[vm.data.name]]));
1968
+ }"
1969
+ }
1970
+ }
1971
+ }
1972
+ }
1973
+}
1974
+```
1975
+
1976
+#### **9.1.2 多选树选择器**
1977
+
1978
+```json
1979
+{
1980
+ "useSelectTree": {
1981
+ "preId": "user_group_form_user_ids_",
1982
+ "type": "multiple", // 多选模式
1983
+ "confirm": "(vm, result) => {
1984
+ // 处理多选结果
1985
+ const selectedValues = result.map(item => item.value);
1986
+ vm.$ds.form.user_ids = selectedValues;
1987
+ }"
1988
+ }
1989
+}
1990
+```
1991
+
1992
+### **9.2 弹窗视图选择器(`useOpenView`)**
1993
+
1994
+#### **9.2.1 基础弹窗选择器**
1995
+
1996
+```json
1997
+{
1998
+ "view": {
1999
+ "customClick": {
2000
+ "customSelect": {
2001
+ "showType": "dialog",
2002
+ "width": "60%",
2003
+ "useOpenView": {
2004
+ "preId": "tenant_action_dimension_menu_pre",
2005
+ "model": "tenant_action_dimension",
2006
+ "type": "grid,search", // 显示的视图类型
2007
+ "checkbox": "single", // 选择模式:single/multiple
2008
+ "valueField": "metaId", // 返回值字段
2009
+ "labelField": "name", // 显示标签字段
2010
+ "confirm": "(vm, result) => {
2011
+ // 选择确认后的处理逻辑
2012
+ let common = tech_app.page.getNode('tenant_action_dimension__drawer_form_main_detail_top_common');
2013
+ common.$ds.modelMetaId = result[0].metaId;
2014
+ }"
2015
+ }
2016
+ }
2017
+ }
2018
+ }
2019
+}
2020
+```
2021
+
2022
+#### **9.2.2 带搜索的弹窗选择器**
2023
+
2024
+```json
2025
+{
2026
+ "useOpenView": {
2027
+ "preId": "base_data_permission_form_modeName_menu_",
2028
+ "checkbox": "single",
2029
+ "model": "tenant_action_dimension",
2030
+ "app": "sie-iidp-iam", // 指定应用
2031
+ "type": "grid,search", // 同时显示表格和搜索
2032
+ "valueField": "metaId",
2033
+ "labelField": "name",
2034
+ "args": { // 传递查询参数
2035
+ "filter": [
2036
+ ["type", "=", "DIMENSION"]
2037
+ ]
2038
+ }
2039
+ }
2040
+}
2041
+```
2042
+
2043
+### **9.3 自定义弹窗配置**
2044
+
2045
+#### **9.3.1 抽屉式弹窗(Drawer)**
2046
+
2047
+```json
2048
+{
2049
+ "showType": "drawer",
2050
+ "width": "50%",
2051
+ "title": "已分配用户",
2052
+ "preId": "rbac_user_app_menu_table_tbar_allocated_",
2053
+ "model": "rbac_user_tenant",
2054
+ "type": "rbac_user_tenant_search,rbac_user_tenant_grid"
2055
+}
2056
+```
2057
+
2058
+#### **9.3.2 对话框配置**
2059
+
2060
+```json
2061
+{
2062
+ "showType": "dialog",
2063
+ "width": "30%",
2064
+ "height": "60vh", // 设置高度
2065
+ "title": "选择组织",
2066
+ "hasFooter": true, // 是否显示底部按钮
2067
+ "modal": true, // 是否模态
2068
+ "closeOnClickModal": false // 点击遮罩是否关闭
2069
+}
2070
+```
2071
+
2072
+
2073
+
2074
+## **第十章:数据查询与服务调用**
2075
+
2076
+### **10.1 自定义数据查询(`searchByMainTable`)**
2077
+
2078
+#### **10.1.1 基础查询配置**
2079
+
2080
+```json
2081
+{
2082
+ "searchByMainTable": {
2083
+ "service": {
2084
+ "search": "searchUser", // 搜索服务
2085
+ "count": "count" // 计数服务
2086
+ },
2087
+ "model": "rbac_user",
2088
+ "args": {
2089
+ "filter": [
2090
+ ["userType", "=", "0"]
2091
+ ],
2092
+ "order": "create_date desc",
2093
+ "limit": 20,
2094
+ "offset": 0
2095
+ }
2096
+ }
2097
+}
2098
+```
2099
+
2100
+#### **10.1.2 复杂查询配置**
2101
+
2102
+```json
2103
+{
2104
+ "searchByMainTable": {
2105
+ "service": {
2106
+ "search": "queryRoleTree",
2107
+ "count": "countRoleTree"
2108
+ },
2109
+ "model": "rbac_role",
2110
+ "args": {
2111
+ "useDisplayForModel": true,
2112
+ "filter": [
2113
+ ["roleType", "=", "0"],
2114
+ ["state", "=", "active"]
2115
+ ],
2116
+ "order": "id",
2117
+ "showRoot": true, // 是否显示根节点
2118
+ "includeChildren": true // 是否包含子节点
2119
+ }
2120
+ }
2121
+}
2122
+```
2123
+
2124
+### **10.2 树形数据搜索配置(`searchConfig`)**
2125
+
2126
+```json
2127
+{
2128
+ "searchConfig": {
2129
+ "model": "rbac_organization",
2130
+ "service": "searchForUser",
2131
+ "args": {
2132
+ "limit": 2147483647, // 最大限制
2133
+ "filter": [
2134
+ ["type", "=", "department"],
2135
+ ["state", "=", "active"]
2136
+ ]
2137
+ }
2138
+ }
2139
+}
2140
+```
2141
+
2142
+### **10.3 服务调用配置**
2143
+
2144
+#### **10.3.1 按钮调用服务**
2145
+
2146
+```json
2147
+{
2148
+ "name": "刷新应用",
2149
+ "model": "meta_app",
2150
+ "service": "restartApp", // 服务名称
2151
+ "auth": "restartApp",
2152
+ "showPopLoading": true // 显示加载提示
2153
+}
2154
+```
2155
+
2156
+#### **10.3.2 带参数的服务调用**
2157
+
2158
+```json
2159
+{
2160
+ "name": "删除",
2161
+ "model": "tenant_action_scope",
2162
+ "service": "delete",
2163
+ "actionAfter": "refreshTable", // 执行后的动作
2164
+ "args": {
2165
+ "id": "$row.id" // 使用行数据作为参数
2166
+ }
2167
+}
2168
+```
2169
+
2170
+### **10.4 分页配置(`pagin`)**
2171
+
2172
+```json
2173
+{
2174
+ "pagin": {
2175
+ "display": false, // 是否显示分页
2176
+ "unPaging": true, // 是否禁用分页
2177
+ "pageSize": 20, // 每页数量
2178
+ "pageSizes": [10, 20, 50, 100], // 可选页大小
2179
+ "layout": "total, sizes, prev, pager, next, jumper" // 布局
2180
+ }
2181
+}
2182
+```
2183
+
2184
+## **第十一章:权限控制与安全**
2185
+
2186
+### **11.1 按钮权限控制**
2187
+
2188
+#### **11.1.1 基础权限控制**
2189
+
2190
+```json
2191
+{
2192
+ "name": "新增",
2193
+ "action": "create",
2194
+ "auth": "create" // 权限标识,对应rbac_permission表中的auth字段
2195
+}
2196
+```
2197
+
2198
+#### **11.1.2 复合权限检查**
2199
+
2200
+```json
2201
+{
2202
+ "name": "数据权限",
2203
+ "auth": "data_auth",
2204
+ "bind_display": {
2205
+ "transform": "(params) => {
2206
+ // 检查用户角色和功能权限
2207
+ const user = window.tech?.userInfo;
2208
+ if (!user) return false;
2209
+
2210
+ // 检查是否为管理员
2211
+ const isAdmin = user.roles?.some(role => role.code === 'rbac_role_admin');
2212
+ if (isAdmin) return true;
2213
+
2214
+ // 检查具体权限
2215
+ return user.permissions?.includes('data_auth_manage');
2216
+ }"
2217
+ }
2218
+}
2219
+```
2220
+
2221
+### **11.2 字段级别权限控制**
2222
+
2223
+#### **11.2.1 基于角色的字段控制**
2224
+
2225
+```json
2226
+{
2227
+ "name": "source",
2228
+ "bind_disabled": {
2229
+ "transform": "(params) => {
2230
+ const userRoles = window.tech?.userInfo?.roles || [];
2231
+ const isSystemAdmin = userRoles.some(role => role.code === 'SYSTEM_ADMIN');
2232
+ return !isSystemAdmin; // 非系统管理员禁用
2233
+ }"
2234
+ }
2235
+}
2236
+```
2237
+
2238
+#### **11.2.2 基于数据的字段控制**
2239
+
2240
+```json
2241
+{
2242
+ "name": "ruleType",
2243
+ "bind_disabled": "$ds.clickType != 'add'", // 仅新增时可编辑
2244
+ "bind_display": "${$ds.form.source !== 'SYSTEM_BUILT_IN'}" // 非系统内置时显示
2245
+}
2246
+```
2247
+
2248
+### **11.3 数据域过滤(`domains`)**
2249
+
2250
+```json
2251
+{
2252
+ "body": {
2253
+ "type": "search",
2254
+ "columns": [...],
2255
+ "domains": [
2256
+ {
2257
+ "column": "source", // 应用字段
2258
+ "domain": [ // 过滤条件
2259
+ ["source", "=", "base"]
2260
+ ]
2261
+ },
2262
+ {
2263
+ "column": "type", // 多条件过滤
2264
+ "domain": [
2265
+ "|",
2266
+ ["type", "=", "function"],
2267
+ ["type", "=", "api"]
2268
+ ]
2269
+ }
2270
+ ]
2271
+ }
2272
+}
2273
+```
2274
+
2275
+## **第十二章:视图扩展与继承**
2276
+
2277
+### **12.1 视图扩展机制(`mode: extension`)**
2278
+
2279
+#### **12.1.1 基础扩展配置**
2280
+
2281
+```json
2282
+{
2283
+ "rbac_user_grid_ext": {
2284
+ "name": "用户表格扩展",
2285
+ "model": "rbac_user",
2286
+ "type": "grid",
2287
+ "mode": "extension", // 扩展模式
2288
+ "inherit_ids": {
2289
+ "@ref": "base.rbac_user_grid" // 继承的视图
2290
+ },
2291
+ "body": {
2292
+ "jsonpath": [...] // JSON路径操作
2293
+ }
2294
+ }
2295
+}
2296
+```
2297
+
2298
+#### **12.1.2 JSON路径操作(`jsonpath`)**
2299
+
2300
+**位置参数(`position`):**
2301
+
2302
+- `inside`:在匹配节点内部追加(默认)
2303
+- `after`:在匹配节点之后添加
2304
+- `before`:在匹配节点之前添加
2305
+- `replace`:替换匹配的节点
2306
+- `attributes`:修改节点属性
2307
+
2308
+**示例:添加字段**
2309
+
2310
+```json
2311
+{
2312
+ "jsonpath": [
2313
+ {
2314
+ "expr": "columns.email",
2315
+ "position": "after",
2316
+ "body": ["mobile"] // 在email字段后添加mobile字段
2317
+ }
2318
+ ]
2319
+}
2320
+```
2321
+
2322
+**示例:添加Tabs**
2323
+
2324
+```json
2325
+{
2326
+ "jsonpath": [
2327
+ {
2328
+ "has_not": "tabs", // 如果原视图没有tabs则创建
2329
+ "expr": "tabs",
2330
+ "position": "inside",
2331
+ "body": [
2332
+ {
2333
+ "header": "用户日志",
2334
+ "body": {
2335
+ "type": "grid",
2336
+ "field": "logs",
2337
+ "columns": ["ip", "user_agent", "url"]
2338
+ }
2339
+ }
2340
+ ]
2341
+ }
2342
+ ]
2343
+}
2344
+```
2345
+
2346
+**示例:修改字段属性**
2347
+
2348
+```json
2349
+{
2350
+ "jsonpath": [
2351
+ {
2352
+ "expr": "columns.email",
2353
+ "position": "attributes",
2354
+ "body": {
2355
+ "hidden": true, // 隐藏email字段
2356
+ "width": "150px"
2357
+ }
2358
+ }
2359
+ ]
2360
+}
2361
+```
2362
+
2363
+### **12.2 组件动态控制**
2364
+
2365
+#### **12.2.1 按钮动态显示函数(`showBtnFn`)**
2366
+
2367
+```json
2368
+{
2369
+ "showBtnFn": "(item) => {
2370
+ if (!item?.parent_id) {
2371
+ return { create: true }; // 根节点只显示创建按钮
2372
+ } else {
2373
+ return { create: true, edit: true, delete: true };
2374
+ }
2375
+ }"
2376
+}
2377
+```
2378
+
2379
+#### **12.2.2 自定义按钮过滤(`buttonsFilterMethod`)**
2380
+
2381
+```json
2382
+{
2383
+ "buttonsFilterMethod": "(btn, value, data) => {
2384
+ if (!value.parent_id && (btn?.action === 'edit' || btn?.action === 'delete')) {
2385
+ return false; // 根节点不显示编辑和删除按钮
2386
+ }
2387
+ return true;
2388
+ }"
2389
+}
2390
+```
2391
+
2392
+### **12.3 模板继承与复用**
2393
+
2394
+#### **12.3.1 创建基础模板视图**
2395
+
2396
+```json
2397
+{
2398
+ "base_form_template": {
2399
+ "name": "基础表单模板",
2400
+ "body": {
2401
+ "type": "form",
2402
+ "columns": [
2403
+ {
2404
+ "name": "name",
2405
+ "displayName": "名称",
2406
+ "required": true
2407
+ },
2408
+ {
2409
+ "name": "code",
2410
+ "displayName": "编码",
2411
+ "required": true
2412
+ },
2413
+ {
2414
+ "name": "description",
2415
+ "displayName": "描述"
2416
+ }
2417
+ ],
2418
+ "tbar": ["@defaults"]
2419
+ }
2420
+ }
2421
+}
2422
+```
2423
+
2424
+#### **12.3.2 继承并扩展模板**
2425
+
2426
+```json
2427
+{
2428
+ "specific_model_form": {
2429
+ "name": "特定模型表单",
2430
+ "model": "specific_model",
2431
+ "type": "form",
2432
+ "mode": "extension",
2433
+ "inherit_ids": {
2434
+ "@ref": "base.base_form_template"
2435
+ },
2436
+ "body": {
2437
+ "jsonpath": [
2438
+ {
2439
+ "expr": "columns",
2440
+ "position": "inside",
2441
+ "body": [
2442
+ {
2443
+ "name": "specific_field",
2444
+ "displayName": "特定字段"
2445
+ }
2446
+ ]
2447
+ }
2448
+ ]
2449
+ }
2450
+ }
2451
+}
2452
+```
2453
+
2454
+
2455
+## **第十四章:最佳实践总结**
2456
+
2457
+### **14.1 代码组织规范**
2458
+
2459
+#### **14.1.1 文件结构**
2460
+
2461
+```
2462
+views/
2463
+├── base/ # 基础视图
2464
+│ ├── rbac_user_view.json
2465
+│ ├── rbac_role_view.json
2466
+│ └── rbac_org_view.json
2467
+├── tenant/ # 租户相关视图
2468
+│ ├── tenant_user_view.json
2469
+│ └── tenant_role_view.json
2470
+├── extension/ # 扩展视图
2471
+│ ├── rbac_user_ext_view.json
2472
+│ └── rbac_role_ext_view.json
2473
+└── menu_view.json # 菜单配置
2474
+```
2475
+
2476
+#### **14.1.2 命名规范**
2477
+
2478
+- **视图名称**:`{model_name}_{view_type}`,如`rbac_user_grid`
2479
+- **扩展视图**:`{model_name}_{view_type}_ext`,如`rbac_user_grid_ext`
2480
+- **菜单名称**:`{module}_{function}_menu`,如`rbac_user_management_menu`
2481
+- **自定义字段**:使用`custom_`前缀,如`custom_display_field`
2482
+
2483
+### **14.2 配置最佳实践**
2484
+
2485
+#### **14.2.1 保持配置简洁**
2486
+
2487
+```json
2488
+{
2489
+ // 好:使用默认配置
2490
+ "tbar": ["@defaults"],
2491
+ "buttons": ["@defaults"],
2492
+
2493
+ // 好:必要的最小配置
2494
+ "tbar": [
2495
+ { "name": "新增", "action": "create", "auth": "create" },
2496
+ { "name": "删除", "action": "delete", "auth": "delete" }
2497
+ ],
2498
+
2499
+ // 避免:过度配置
2500
+ "tbar": [
2501
+ { "name": "新增", "action": "create", "auth": "create", "icon": "el-icon-plus", "type": "primary", "size": "small", "plain": false, "round": false, "circle": false }
2502
+ ]
2503
+}
2504
+```
2505
+
2506
+#### **14.2.2 使用函数封装复杂逻辑**
2507
+
2508
+```javascript
2509
+// 在单独的文件中定义工具函数
2510
+const ViewUtils = {
2511
+ // 权限检查函数
2512
+ checkPermission: (permissionCode) => {
2513
+ const user = window.tech?.userInfo;
2514
+ return user?.permissions?.includes(permissionCode) ||
2515
+ user?.roles?.some(role => role.code === 'admin');
2516
+ },
2517
+
2518
+ // 数据格式化函数
2519
+ formatDate: (timestamp) => {
2520
+ return new Date(timestamp).toLocaleString();
2521
+ }
2522
+};
2523
+
2524
+// 在视图中引用
2525
+{
2526
+ "bind_display": {
2527
+ "transform": "(params) => ViewUtils.checkPermission('data_manage')"
2528
+ }
2529
+}
2530
+```
2531
+
2532
+### **14.3 性能优化建议**
2533
+
2534
+1. **减少不必要的字段**:只显示业务需要的字段
2535
+2. **合理使用缓存**:对不常变的数据启用缓存
2536
+3. **分页加载**:大数据集使用分页,避免一次性加载
2537
+4. **懒加载**:树形数据使用懒加载
2538
+5. **虚拟滚动**:长列表使用虚拟滚动
2539
+
2540
+### **14.4 常见问题排查**
2541
+
2542
+#### **14.4.1 视图不显示**
2543
+
2544
+1. 检查`app.json`中视图路径配置是否正确
2545
+2. 检查JSON语法是否正确(可以使用JSON验证工具)
2546
+3. 检查模型名称是否与后端一致
2547
+4. 检查浏览器控制台是否有错误信息
2548
+
2549
+#### **14.4.2 按钮不生效**
2550
+
2551
+1. 检查`auth`权限标识是否正确
2552
+2. 检查`service`服务名称是否存在
2553
+3. 检查`action`动作类型是否支持
2554
+4. 检查`enableCondition`条件是否满足
2555
+
2556
+#### **14.4.3 数据不加载**
2557
+
2558
+1. 检查`searchByMainTable`配置是否正确
2559
+2. 检查网络请求是否有响应
2560
+3. 检查后端服务是否正常运行
2561
+4. 检查数据格式是否符合预期
2562
+
2563
+---
2564
+
2565
+这份完整的手册涵盖了赛意谷神平台视图开发的基础和高级特性。建议在实际开发中:
2566
+
2567
+1. 从**基础视图**开始,掌握基本结构
2568
+2. 逐步学习**高级特性**,按需使用
2569
+3. 遵循**最佳实践**,保持代码质量
2570
+4. 善用**调试工具**,快速定位问题
... ...
\ No newline at end of file