cloud-web-corejs 1.0.281 → 1.1.0-dev.11

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.
Files changed (175) hide show
  1. package/package.json +6 -2
  2. package/src/components/VabUpload/image-viewer.vue +442 -442
  3. package/src/components/VabUpload/index.vue +45 -3
  4. package/src/components/VabUpload/mixins.js +126 -19
  5. package/src/components/VabUpload/view.vue +248 -209
  6. package/src/components/baseTabs/mixins.js +181 -181
  7. package/src/components/bizTab/BizBillActions.vue +129 -0
  8. package/src/components/bizTab/BizTabListPage.vue +391 -0
  9. package/src/components/bizTab/README.md +378 -0
  10. package/src/components/bizTab/billTableUtil.js +48 -0
  11. package/src/components/bizTab/billValidators.js +136 -0
  12. package/src/components/bizTab/bizBillDetailMixin.js +705 -0
  13. package/src/components/bizTab/index.js +24 -0
  14. package/src/components/excelExport/exportFieldDialog.vue +23 -12
  15. package/src/components/excelExport/exportItemConfigUtil.js +30 -0
  16. package/src/components/excelExport/mixins.js +3 -3
  17. package/src/components/excelImport/index.vue +156 -156
  18. package/src/components/jsonImport/index.vue +1 -1
  19. package/src/components/langImport/index.vue +1 -1
  20. package/src/components/mobile/statusTag/mixins.js +1 -61
  21. package/src/components/mobile/wf/addTaskUserdialog.vue +23 -3
  22. package/src/components/mobile/wf/content.vue +1705 -1556
  23. package/src/components/mobile/wf/deleteTaskUserDialog.vue +22 -3
  24. package/src/components/mobile/wf/mixins/wfModifyDialogMixin.js +8 -6
  25. package/src/components/mobile/wf/selectUserDialog.vue +118 -0
  26. package/src/components/mobile/wf/setCandidateDialog.vue +25 -4
  27. package/src/components/mobile/wf/urgingDialog.vue +26 -3
  28. package/src/components/mobile/wf/wfModifyDialog.vue +4 -0
  29. package/src/components/obsUpload/index.vue +1 -1
  30. package/src/components/table/config.js +78 -78
  31. package/src/components/table/index.js +1276 -1276
  32. package/src/components/table/plugins/cell-area/index.js +1055 -0
  33. package/src/components/table/plugins/cell-area/index.scss +77 -0
  34. package/src/components/table/plugins/cell-area/util.js +224 -0
  35. package/src/components/table/tableForm.vue +330 -330
  36. package/src/components/table/tableFormMixin.js +318 -318
  37. package/src/components/table/vxeFilter/index.js +163 -163
  38. package/src/components/table/vxeFilter/mixin.js +316 -316
  39. package/src/components/wf/content.vue +1188 -1188
  40. package/src/components/wf/wf.js +40 -20
  41. package/src/components/wf/wfActionDropdown.vue +1 -1
  42. package/src/components/wf/wfActionItems.js +1 -1
  43. package/src/components/xform/form-designer/designer.js +51 -52
  44. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +269 -269
  45. package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +18 -2
  46. package/src/components/xform/form-designer/form-widget/container-widget/detail-temp-widget.vue +132 -0
  47. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +250 -250
  48. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +23 -2
  49. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +30 -1
  50. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +319 -320
  51. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +365 -365
  52. package/src/components/xform/form-designer/form-widget/dialog/importDialog.vue +185 -185
  53. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +554 -555
  54. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +409 -409
  55. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +150 -132
  56. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +114 -114
  57. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +154 -154
  58. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +47 -1
  59. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +178 -178
  60. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +77 -77
  61. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +6 -0
  62. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +139 -139
  63. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +1 -1
  64. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +106 -106
  65. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +134 -134
  66. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +3 -2
  67. package/src/components/xform/form-designer/indexMixin.js +35 -1
  68. package/src/components/xform/form-designer/setting-panel/form-setting.vue +39 -39
  69. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +10 -10
  70. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/exportItemColumns-dialog.vue +438 -432
  71. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +2103 -2103
  72. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-temp-edito.vue +90 -0
  73. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +82 -82
  74. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +833 -846
  75. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +8 -8
  76. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +137 -137
  77. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
  78. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +43 -43
  79. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +43 -43
  80. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +96 -96
  81. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +51 -0
  82. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +42 -42
  83. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +43 -43
  84. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +158 -158
  85. package/src/components/xform/form-designer/setting-panel/property-editor/h5Span-editor.vue +51 -0
  86. package/src/components/xform/form-designer/setting-panel/property-editor/itemStyle-editor.vue +39 -0
  87. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -188
  88. package/src/components/xform/form-designer/setting-panel/property-editor/styleTempClass-editor.vue +51 -0
  89. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +347 -347
  90. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +12 -0
  91. package/src/components/xform/form-designer/toolbar-panel/index.vue +884 -874
  92. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +14 -0
  93. package/src/components/xform/form-designer/widget-panel/index.vue +11 -7
  94. package/src/components/xform/form-designer/widget-panel/indexMixin.js +30 -6
  95. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +112 -4
  96. package/src/components/xform/form-render/container-item/data-table-mixin.js +151 -93
  97. package/src/components/xform/form-render/container-item/detail-h5-item.vue +204 -34
  98. package/src/components/xform/form-render/container-item/detail-temp-item.vue +110 -0
  99. package/src/components/xform/form-render/container-item/h5-card-pane-item.vue +160 -140
  100. package/src/components/xform/form-render/container-item/list-h5-item.vue +1913 -1699
  101. package/src/components/xform/form-render/index.vue +153 -147
  102. package/src/components/xform/form-render/indexMixin.js +35 -3
  103. package/src/components/xform/lang/en-US.js +14 -0
  104. package/src/components/xform/lang/zh-CN.js +17 -0
  105. package/src/components/xform/mixins/defaultHandle.js +707 -707
  106. package/src/components/xform/styles/h5.scss +2262 -0
  107. package/src/components/xform/utils/textMaskUtil.js +182 -179
  108. package/src/components/xform/utils/treeTableUtil.js +1292 -1265
  109. package/src/components/xform/utils/util.js +56 -11
  110. package/src/directive/append-to-body/index.js +48 -0
  111. package/src/index.js +13 -4
  112. package/src/layout/components/Sidebar/default.vue +1655 -1655
  113. package/src/layout/components/extractedCode/viewDialog.vue +7 -7
  114. package/src/router/index.js +48 -27
  115. package/src/router/modules/customer.js +71 -14
  116. package/src/store/modules/permission.js +17 -18
  117. package/src/utils/assetUrl.js +19 -0
  118. package/src/utils/pdfUtil.js +429 -429
  119. package/src/utils/resolveViewComponent.js +142 -16
  120. package/src/utils/vab.js +1283 -1279
  121. package/src/views/bd/project/branch/bd_branch/edit.vue +145 -0
  122. package/src/views/bd/project/branch/bd_branch/list.vue +72 -0
  123. package/src/views/bd/project/branch/bd_branch/menuKindDialog.vue +106 -0
  124. package/src/views/bd/project/branch/bd_branch/mixins/edit.js +189 -0
  125. package/src/views/bd/project/branch/bd_branch/mixins/list.js +124 -0
  126. package/src/views/bd/project/branch/bd_branch/mixins/menuKindDialog.js +85 -0
  127. package/src/views/bd/project/branch/form_script/list.vue +31 -0
  128. package/src/views/bd/project/branch/form_template/list.vue +30 -0
  129. package/src/views/bd/project/branch/menu_kind/list.vue +31 -0
  130. package/src/views/bd/project/common/form_script/list.vue +16 -0
  131. package/src/views/bd/project/common/form_template/list.vue +15 -0
  132. package/src/views/bd/project/common/menu_kind/list.vue +15 -0
  133. package/src/views/bd/project/core/branchContext.js +100 -0
  134. package/src/views/bd/project/core/branchPage.js +78 -0
  135. package/src/views/bd/project/core/branchPageWrap.vue +225 -0
  136. package/src/views/bd/project/core/branchScope.js +44 -0
  137. package/src/views/bd/project/core/branchSearchPage.js +285 -0
  138. package/src/views/bd/project/core/branchSelect.vue +85 -0
  139. package/src/views/bd/project/core/branchTreeBar.vue +81 -0
  140. package/src/views/bd/project/core/httpBranchPatch.js +58 -0
  141. package/src/views/bd/project/datatable/menu_kind/list.vue +15 -0
  142. package/src/views/bd/project/datatable/table_model/list.vue +15 -0
  143. package/src/views/bd/setting/bd_company_env/dialog.vue +174 -174
  144. package/src/views/bd/setting/form_template/edit.vue +378 -356
  145. package/src/views/bd/setting/form_template/formDesignerDialog.vue +6 -0
  146. package/src/views/bd/setting/form_template/formTemplateType.js +43 -0
  147. package/src/views/bd/setting/form_template/list.vue +304 -303
  148. package/src/views/bd/setting/form_template/mixins/edit.js +344 -280
  149. package/src/views/bd/setting/form_template/mixins/list.js +748 -721
  150. package/src/views/bd/setting/table_model/edit.vue +1066 -1066
  151. package/src/views/bd/setting/table_model/mixins/edit.js +1455 -1455
  152. package/src/views/bd/setting/table_model/mixins/zdDialog.js +148 -148
  153. package/src/views/support/form-dialog-demo/demoPickerDialog.vue +72 -0
  154. package/src/views/support/form-dialog-demo/index.vue +537 -0
  155. package/src/views/user/file_view_ins/list.vue +970 -970
  156. package/src/views/user/form/vform/designer.vue +823 -821
  157. package/src/views/user/home/default.vue +1117 -1117
  158. package/src/views/user/home/default2.vue +1 -1
  159. package/src/views/user/home/index.vue +103 -101
  160. package/src/views/user/notify_message/dialog.vue +139 -137
  161. package/src/views/user/outLink/form_view.vue +202 -202
  162. package/src/views/user/outLink/index.vue +110 -110
  163. package/src/views/user/outLink/view.vue +3 -3
  164. package/src/views/user/role/edit.vue +632 -632
  165. package/src/views/user/role/list.vue +260 -260
  166. package/src/views/user/wf/iframe/index.vue +51 -51
  167. package/src/views/user/wf/iframe/index2.vue +64 -64
  168. package/src/views/user/wf/wf_manage/list.vue +1112 -1116
  169. package/src/views/user/wf/wf_manage/list2.vue +871 -875
  170. package/src/views/user/wf/wf_manage/wfContentDialog.vue +134 -131
  171. package/src/views/user/wf/wf_obj_config/importItemDialog.vue +1 -1
  172. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-menu-widget.vue +0 -106
  173. package/src/components/xform/form-designer/form-widget/field-widget/tableexportbuttonwidget.vue +0 -99
  174. package/src/components/xform/form-render/container-item/list-h5-item2.vue +0 -1340
  175. package/src/utils/wf.js +0 -766
@@ -0,0 +1,537 @@
1
+ <template>
2
+ <div class="app-container form-dialog-demo">
3
+ <el-card shadow="never">
4
+ <div slot="header">$formDialog 表单弹框示例</div>
5
+ <div class="btns">
6
+ <el-button type="primary" @click="openBasic">1. 基础新增表单</el-button>
7
+ <el-button type="primary" @click="openEdit">2. 编辑回显</el-button>
8
+ <el-button type="primary" @click="openReadonly">3. 只读查看</el-button>
9
+ <el-button type="primary" @click="openAllTypes"
10
+ >4. 全字段类型(两列布局)</el-button
11
+ >
12
+ <el-button type="primary" @click="openBeforeConfirm"
13
+ >5. beforeConfirm 异步保存</el-button
14
+ >
15
+ <el-button type="primary" @click="openCustomRender"
16
+ >6. 自定义 render 控件</el-button
17
+ >
18
+ <el-button type="primary" @click="openNested"
19
+ >7. 叠开两层弹框</el-button
20
+ >
21
+ <el-button type="primary" @click="openDataSource"
22
+ >8. 搜索框 + 下拉数据源(静态/词汇/脚本)</el-button
23
+ >
24
+ <el-button type="primary" @click="openLinkage"
25
+ >9. 字段联动(级联/显隐/禁用/onChange)</el-button
26
+ >
27
+ <el-button type="primary" @click="openXform"
28
+ >10. xform 整表模式(formCode)</el-button
29
+ >
30
+ <el-button type="primary" @click="openXformReadonly"
31
+ >11. xform 整表只读查看</el-button
32
+ >
33
+ </div>
34
+ </el-card>
35
+
36
+ <el-card shadow="never" style="margin-top: 16px">
37
+ <div slot="header">最近一次返回结果(取消/关闭为 null)</div>
38
+ <pre class="result">{{ result }}</pre>
39
+ </el-card>
40
+ </div>
41
+ </template>
42
+
43
+ <script>
44
+ export default {
45
+ name: "formDialogDemo",
46
+ data() {
47
+ return {
48
+ result: "(还未调用)",
49
+ };
50
+ },
51
+ methods: {
52
+ show(data) {
53
+ this.result = data === null ? "null" : JSON.stringify(data, null, 2);
54
+ },
55
+
56
+ // 1. 基础新增:必填校验 + 常用控件
57
+ async openBasic() {
58
+ const data = await this.$formDialog({
59
+ title: "新增分类",
60
+ fields: [
61
+ { prop: "name", label: "名称", required: true },
62
+ {
63
+ prop: "type",
64
+ label: "类型",
65
+ type: "select",
66
+ required: true,
67
+ options: [
68
+ { label: "普通", value: 1 },
69
+ { label: "重要", value: 2 },
70
+ ],
71
+ },
72
+ { prop: "enabled", label: "启用", type: "switch" },
73
+ { prop: "remark", label: "备注", type: "textarea" },
74
+ ],
75
+ });
76
+ this.show(data);
77
+ },
78
+
79
+ // 2. 编辑回显:model 传初始值
80
+ async openEdit() {
81
+ const data = await this.$formDialog({
82
+ title: "编辑分类",
83
+ model: {
84
+ name: "季度促销",
85
+ type: 2,
86
+ enabled: true,
87
+ remark: "从列表行数据带入的初始值",
88
+ },
89
+ fields: [
90
+ { prop: "name", label: "名称", required: true },
91
+ {
92
+ prop: "type",
93
+ label: "类型",
94
+ type: "select",
95
+ options: [
96
+ { label: "普通", value: 1 },
97
+ { label: "重要", value: 2 },
98
+ ],
99
+ },
100
+ { prop: "enabled", label: "启用", type: "switch" },
101
+ { prop: "remark", label: "备注", type: "textarea" },
102
+ ],
103
+ });
104
+ this.show(data);
105
+ },
106
+
107
+ // 3. 只读查看:readonly=true,整表单禁用,底部只有关闭
108
+ async openReadonly() {
109
+ const data = await this.$formDialog({
110
+ title: "查看分类",
111
+ readonly: true,
112
+ model: { name: "季度促销", type: 2, enabled: true, remark: "只读模式" },
113
+ fields: [
114
+ { prop: "name", label: "名称" },
115
+ {
116
+ prop: "type",
117
+ label: "类型",
118
+ type: "select",
119
+ options: [
120
+ { label: "普通", value: 1 },
121
+ { label: "重要", value: 2 },
122
+ ],
123
+ },
124
+ { prop: "enabled", label: "启用", type: "switch" },
125
+ { prop: "remark", label: "备注", type: "textarea" },
126
+ ],
127
+ });
128
+ this.show(data);
129
+ },
130
+
131
+ // 4. 全字段类型 + span 两列布局 + 自定义 rules + 控件透传 props
132
+ async openAllTypes() {
133
+ const data = await this.$formDialog({
134
+ title: "全字段类型",
135
+ width: "760px",
136
+ rules: {
137
+ qty: [
138
+ {
139
+ validator: (rule, value, callback) => {
140
+ if (value != null && value % 2 !== 0) {
141
+ callback(new Error("数量必须是偶数(自定义 rules 示例)"));
142
+ } else {
143
+ callback();
144
+ }
145
+ },
146
+ trigger: "change",
147
+ },
148
+ ],
149
+ },
150
+ fields: [
151
+ { prop: "name", label: "文本", span: 12, required: true },
152
+ {
153
+ // 数字框走 baseInputNumber:scale 限小数位(0=整数),negative 允许负数
154
+ prop: "qty",
155
+ label: "数量",
156
+ type: "number",
157
+ span: 12,
158
+ scale: 0,
159
+ props: { min: 0, max: 100 },
160
+ },
161
+ {
162
+ prop: "amount",
163
+ label: "金额",
164
+ type: "number",
165
+ span: 12,
166
+ scale: 2,
167
+ negative: true,
168
+ },
169
+ { prop: "date", label: "日期", type: "date", span: 12 },
170
+ { prop: "time", label: "日期时间", type: "datetime", span: 12 },
171
+ { prop: "range", label: "日期区间", type: "daterange", span: 24 },
172
+ {
173
+ prop: "level",
174
+ label: "单选",
175
+ type: "radio",
176
+ span: 12,
177
+ options: [
178
+ { label: "低", value: "L" },
179
+ { label: "中", value: "M" },
180
+ { label: "高", value: "H" },
181
+ ],
182
+ },
183
+ {
184
+ prop: "tags",
185
+ label: "多选",
186
+ type: "checkbox",
187
+ span: 12,
188
+ options: ["标签A", "标签B", "标签C"],
189
+ },
190
+ { prop: "enabled", label: "开关", type: "switch", span: 12 },
191
+ {
192
+ prop: "locked",
193
+ label: "禁用控件",
194
+ type: "switch",
195
+ span: 12,
196
+ disabled: true,
197
+ },
198
+ ],
199
+ });
200
+ this.show(data);
201
+ },
202
+
203
+ // 5. beforeConfirm:确认前调接口,失败不关闭弹框
204
+ async openBeforeConfirm() {
205
+ const data = await this.$formDialog({
206
+ title: "异步保存(勾选“模拟失败”体验保存失败不关闭)",
207
+ fields: [
208
+ { prop: "name", label: "名称", required: true },
209
+ { prop: "mockFail", label: "模拟失败", type: "switch" },
210
+ ],
211
+ beforeConfirm: (formData) =>
212
+ new Promise((resolve, reject) => {
213
+ // 实际业务里这里通常是 this.$http({...}) 保存请求
214
+ setTimeout(() => {
215
+ if (formData.mockFail) {
216
+ this.$baseMessage({
217
+ message: "保存失败,弹框保持打开",
218
+ type: "error",
219
+ });
220
+ reject(new Error("mock fail"));
221
+ } else {
222
+ resolve();
223
+ }
224
+ }, 800);
225
+ }),
226
+ });
227
+ this.show(data);
228
+ },
229
+
230
+ // 6. render 逃生口:内置类型覆盖不了的控件自己渲染
231
+ async openCustomRender() {
232
+ const data = await this.$formDialog({
233
+ title: "自定义 render 控件",
234
+ model: { score: 3, percent: 40 },
235
+ fields: [
236
+ { prop: "name", label: "名称", required: true },
237
+ {
238
+ prop: "score",
239
+ label: "评分",
240
+ render: (h, model) =>
241
+ h("el-rate", {
242
+ props: { value: model.score },
243
+ style: "margin-top:8px",
244
+ on: {
245
+ input: (val) => {
246
+ model.score = val;
247
+ },
248
+ },
249
+ }),
250
+ },
251
+ {
252
+ prop: "percent",
253
+ label: "进度",
254
+ render: (h, model) =>
255
+ h("el-slider", {
256
+ props: { value: model.percent },
257
+ on: {
258
+ input: (val) => {
259
+ model.percent = val;
260
+ },
261
+ },
262
+ }),
263
+ },
264
+ ],
265
+ });
266
+ this.show(data);
267
+ },
268
+
269
+ // 7. 叠开两层:第一层确认后基于结果打开第二层
270
+ async openNested() {
271
+ const first = await this.$formDialog({
272
+ title: "第一层:选择类型",
273
+ fields: [
274
+ {
275
+ prop: "type",
276
+ label: "类型",
277
+ type: "select",
278
+ required: true,
279
+ options: [
280
+ { label: "普通", value: 1 },
281
+ { label: "重要", value: 2 },
282
+ ],
283
+ },
284
+ ],
285
+ });
286
+ if (first === null) {
287
+ this.show(null);
288
+ return;
289
+ }
290
+ const second = await this.$formDialog({
291
+ title: `第二层:填写${first.type === 2 ? "重要" : "普通"}事项`,
292
+ model: { type: first.type },
293
+ fields: [
294
+ { prop: "name", label: "名称", required: true },
295
+ { prop: "remark", label: "备注", type: "textarea" },
296
+ ],
297
+ });
298
+ this.show(second === null ? null : { ...first, ...second });
299
+ },
300
+
301
+ // 8. 搜索框 + 下拉数据源:静态 options / 词汇 dictCode / 脚本 scriptCode
302
+ async openDataSource() {
303
+ const customers = [
304
+ { id: 1001, name: "华南贸易有限公司" },
305
+ { id: 1002, name: "北方物流集团" },
306
+ { id: 1003, name: "东部电子科技" },
307
+ ];
308
+ const data = await this.$formDialog({
309
+ title: "搜索框与下拉数据源",
310
+ labelWidth: "120px",
311
+ fields: [
312
+ {
313
+ prop: "staticType",
314
+ label: "静态下拉",
315
+ type: "select",
316
+ options: [
317
+ { label: "普通", value: 1 },
318
+ { label: "重要", value: 2 },
319
+ ],
320
+ },
321
+ {
322
+ // 词汇下拉:显示 value、取值 sn;dictCode 替换为环境中存在的词汇编码
323
+ prop: "dictType",
324
+ label: "词汇下拉",
325
+ type: "select",
326
+ dictCode: "kehuGrade",
327
+ },
328
+ {
329
+ // 脚本下拉:"formCode/scriptCode",labelField/valueField 按脚本返回结构调整;
330
+ // 也可用 parseOptions: (res) => [{label, value}] 完全自定义解析
331
+ prop: "scriptType",
332
+ label: "脚本下拉",
333
+ type: "select",
334
+ scriptCode: "/intf/listUsers",
335
+ labelField: "nick_name",
336
+ valueField: "id",
337
+ },
338
+ {
339
+ // 搜索方式1:onSearch 完全自定义(这里用嵌套 formDialog 模拟选择)
340
+ prop: "customerName",
341
+ label: "客户(onSearch)",
342
+ type: "search",
343
+ required: true,
344
+ placeholder: "点击搜索按钮选择",
345
+ onSearch: async (model) => {
346
+ const picked = await this.$formDialog({
347
+ title: "选择客户",
348
+ width: "420px",
349
+ fields: [
350
+ {
351
+ prop: "customerId",
352
+ label: "客户",
353
+ type: "select",
354
+ required: true,
355
+ options: customers.map((item) => ({
356
+ label: item.name,
357
+ value: item.id,
358
+ })),
359
+ },
360
+ ],
361
+ });
362
+ if (picked) {
363
+ const row = customers.find(
364
+ (item) => item.id === picked.customerId
365
+ );
366
+ model.customerId = row.id;
367
+ model.customerName = row.name;
368
+ }
369
+ },
370
+ // 清除时把关联的 id 一起清掉
371
+ onClear: (model) => {
372
+ model.customerId = null;
373
+ model.customerName = null;
374
+ },
375
+ },
376
+ {
377
+ // 搜索方式2:searchComponent 打开自定义 Vue 弹框组件,
378
+ // 组件 $emit("confirm", rows) 后按 fieldMap 回写 model
379
+ prop: "supplierName",
380
+ label: "供应商(Vue弹框)",
381
+ type: "search",
382
+ placeholder: "点击搜索按钮选择",
383
+ searchComponent: {
384
+ componentPath: "views/user/user/dialog.vue",
385
+ fieldMap: { supplierId: "id", supplierName: "nickName" },
386
+ },
387
+ onClear: (model) => {
388
+ model.supplierId = null;
389
+ model.supplierName = null;
390
+ },
391
+ },
392
+ {
393
+ // 搜索方式3:searchDialog 打开 xform 搜索弹框(searchFormDialog),
394
+ // formCode 替换为环境中已配置搜索弹框的表单编码
395
+ prop: "billName",
396
+ label: "单据(xform弹框)",
397
+ type: "search",
398
+ placeholder: "点击搜索按钮选择",
399
+ searchDialog: {
400
+ formCode: "user_dialog",
401
+ multiple: false,
402
+ // queryParam: {...}, // 额外查询参数
403
+ fieldMap: { billId: "id", billName: "nick_name" },
404
+ // onConfirm: (model, rows) => {...} // 或完全自定义回写
405
+ },
406
+ onClear: (model) => {
407
+ model.billId = null;
408
+ model.billName = null;
409
+ },
410
+ },
411
+ ],
412
+ });
413
+ this.show(data);
414
+ },
415
+
416
+ // 9. 字段联动:级联下拉(dependsOn) + 显隐(visible) + 禁用(disabled) + onChange
417
+ async openLinkage() {
418
+ const cityMap = {
419
+ gd: [
420
+ { label: "广州", value: "gz" },
421
+ { label: "深圳", value: "sz" },
422
+ ],
423
+ hn: [
424
+ { label: "长沙", value: "cs" },
425
+ { label: "岳阳", value: "yy" },
426
+ ],
427
+ };
428
+ const data = await this.$formDialog({
429
+ title: "字段联动",
430
+ fields: [
431
+ {
432
+ prop: "province",
433
+ label: "省份",
434
+ type: "select",
435
+ required: true,
436
+ options: [
437
+ { label: "广东", value: "gd" },
438
+ { label: "湖南", value: "hn" },
439
+ ],
440
+ // onChange(value, model, field, dialog):dialog 上有
441
+ // setFieldOptions / reloadFieldOptions 可手动控制其他字段选项
442
+ onChange: (val, model) => {
443
+ model.provinceName = { gd: "广东", hn: "湖南" }[val] || null;
444
+ },
445
+ },
446
+ {
447
+ // 级联:province 变化时自动清空 city;选项用函数按 model 动态取。
448
+ // 若选项来自 dictCode/scriptCode,dependsOn 还会自动重新拉取
449
+ //(dictData/scriptData 支持函数形式 (model) => ({...}))
450
+ prop: "city",
451
+ label: "城市",
452
+ type: "select",
453
+ required: true,
454
+ dependsOn: ["province"],
455
+ options: (model) => cityMap[model.province] || [],
456
+ },
457
+ { prop: "needInvoice", label: "需要发票", type: "switch" },
458
+ {
459
+ // 显隐联动:开关打开才显示;隐藏时不渲染也不参与必填校验
460
+ prop: "taxNo",
461
+ label: "税号",
462
+ required: true,
463
+ visible: (model) => model.needInvoice === true,
464
+ },
465
+ {
466
+ prop: "level",
467
+ label: "等级",
468
+ type: "radio",
469
+ options: [
470
+ { label: "普通", value: 1 },
471
+ { label: "特殊", value: 2 },
472
+ ],
473
+ },
474
+ {
475
+ // 禁用联动:等级为"特殊"才允许填原因
476
+ prop: "reason",
477
+ label: "特殊原因",
478
+ type: "textarea",
479
+ disabled: (model) => model.level !== 2,
480
+ },
481
+ ],
482
+ });
483
+ this.show(data);
484
+ },
485
+
486
+ // 10. xform 整表模式:formCode 渲染设计器里配置好的表单,确认走 xform 校验
487
+ // formCode 为占位编码,按环境替换为已发布的表单模板编码
488
+ async openXform() {
489
+ const data = await this.$formDialog({
490
+ formCode: "demoForm",
491
+ // title 不传时默认取表单模板名称;width 默认 1000px
492
+ // model: { name: "初始值" }, // 初始数据(结构与 getFormData 一致)
493
+ // optionData / globalDsv 可透传给 VFormRender
494
+ // onReady: (formRef, dialog) => {}, // 表单挂载后回调,可调 setFieldValue 等
495
+ beforeConfirm: (formData) => {
496
+ // 常规用法:这里调保存接口,reject 则弹框不关闭
497
+ console.log("xform 表单数据", formData);
498
+ },
499
+ });
500
+ this.show(data);
501
+ },
502
+
503
+ // 11. xform 整表只读:readonly=true 走 setReadMode,底部只有关闭
504
+ async openXformReadonly() {
505
+ const data = await this.$formDialog({
506
+ formCode: "demoForm",
507
+ readonly: true,
508
+ model: {},
509
+ });
510
+ this.show(data);
511
+ },
512
+ },
513
+ };
514
+ </script>
515
+
516
+ <style lang="scss" scoped>
517
+ .form-dialog-demo {
518
+ padding: 16px;
519
+
520
+ .btns {
521
+ display: flex;
522
+ flex-wrap: wrap;
523
+ gap: 8px;
524
+
525
+ .el-button {
526
+ margin-left: 0;
527
+ }
528
+ }
529
+
530
+ .result {
531
+ margin: 0;
532
+ min-height: 60px;
533
+ white-space: pre-wrap;
534
+ word-break: break-all;
535
+ }
536
+ }
537
+ </style>