@epxing/designer 5.3.0-beta.2 → 5.3.0-beta.3

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 (33) hide show
  1. package/API.md +1 -1
  2. package/README.md +46 -46
  3. package/dist/src/page-designer/PageDesigner.js +11 -0
  4. package/dist/src/page-designer/designer.js +21 -0
  5. package/dist/src/page-designer/previews/add-form/Preview.js +1 -1
  6. package/dist/src/page-designer/previews/add-form/Preview.vue.js +19 -8
  7. package/dist/src/page-designer/setting-panel/Setting.js +46 -10
  8. package/dist/src/visual/config-page/ComponentLibraryDialog.js +8 -2
  9. package/dist/src/visual/config-page/DashboardMobile.js +1 -1
  10. package/dist/style.css +116 -112
  11. package/package.json +8 -8
  12. package/src/index.js +27 -27
  13. package/src/page-designer/PageDesigner.vue +11 -0
  14. package/src/page-designer/designer.js +1322 -1299
  15. package/src/page-designer/previews/add-form/Preview.vue +43 -44
  16. package/src/page-designer/setting-panel/Setting.vue +24 -2
  17. package/src/page-designer/widget-preview/Mixin.js +285 -285
  18. package/src/page-designer/widget-preview/Preview.vue +322 -322
  19. package/src/page-designer/widget-preview/WidgetWrapper.vue +197 -197
  20. package/src/page-designer/widget-preview/directive.js +258 -258
  21. package/src/visual/CategoryList.vue +563 -563
  22. package/src/visual/ComponentList.vue +280 -280
  23. package/src/visual/CreatePage.vue +389 -389
  24. package/src/visual/EntityCardList.vue +449 -449
  25. package/src/visual/EntityList.vue +838 -838
  26. package/src/visual/config-page/ComponentLibraryDialog.vue +7 -1
  27. package/src/visual/config-page/DashboardMobile.vue +934 -934
  28. package/src/visual/widgets/ProcessFormItemVisual.vue +58 -58
  29. package/types/index.d.ts +22 -22
  30. package/types/page-designer.d.ts +3 -3
  31. package/types/visual-component.d.ts +1 -1
  32. package/types/visual-entity-list.d.ts +1 -1
  33. package/types/visual-entity-sub-list.d.ts +1 -1
@@ -1,838 +1,838 @@
1
- <script>
2
- // @jsx-vue3(T30 JSX 批:Vue3 JSX 语法,@vue/babel-plugin-jsx 编译)
3
-
4
- import ComponentVue from './Component.vue'
5
- import Background from './config/Background.vue'
6
- export default {
7
- name: 'epx-visual-entity-list',
8
- extends: ComponentVue,
9
- components: {
10
- [Background.name]: Background
11
- },
12
- data () {
13
- return {
14
- FunctionOption: [],
15
- operateConfigs: {},
16
- unfold: false,
17
- backgroundCondition: null,
18
- backgroundStyleDialog: false,
19
- operateOptions: {}
20
- }
21
- },
22
- computed: {
23
- metaView () {
24
- if (this.currentMeta && this.currentMeta.metaView) {
25
- return this.currentMeta.metaView[this.currentMetaViewId]
26
- }
27
- return null
28
- }
29
- },
30
- watch: {
31
- allConfigs: {
32
- handler (v) {
33
- this.componentMetaId = v.metaId
34
- },
35
- immediate: true
36
- },
37
- 'allConfigs.categoryField': {
38
- handler (v) {
39
- // 根据字段获取对象
40
- if (v) {
41
- const fieldConfigs = this.currentMeta.getAllFieldConfigs().find(item => item.attriName === v[0])
42
- if (fieldConfigs) {
43
- this.treeMetaId = fieldConfigs.codeKey
44
- this.treeFieldIsObject = fieldConfigs.dataType === 'object' || fieldConfigs.dataType === 'dept' || fieldConfigs.dataType === 'user'
45
- // this.initConfigOptions()
46
- }
47
- }
48
- },
49
- immediate: true
50
- },
51
- async currentMetaViewId (v) {
52
- if (!v) return
53
- await this.getAllFields()
54
- // 仅用户切换视图且字段树加载成功时,按新视图过滤已配置字段(配置回显不过滤,避免误删)
55
- if (!this.canFilterFieldsByView(v)) return
56
- const { listFields, orderFields, rowFields } = this.config
57
- if (listFields) {
58
- const filtered = listFields.filter(item => this.getField(item.attriName || item))
59
- if (filtered.length !== listFields.length) this.changeConfigItem('listFields', filtered)
60
- }
61
- if (orderFields) {
62
- const filtered = orderFields.filter(item => this.getField(item.attriName || item))
63
- if (filtered.length !== orderFields.length) this.changeConfigItem('orderFields', filtered)
64
- }
65
- if (rowFields) {
66
- const filtered = rowFields.map(row => row.filter(item => this.getField(item.attriName || item)))
67
- if (!this.$_.isEqual(filtered, rowFields)) this.changeConfigItem('rowFields', filtered)
68
- }
69
- }
70
- },
71
- methods: {
72
- getOperateOptions () {
73
- this.getHandlerList()
74
- this.getCommonOperates()
75
- this.operateConfigs = [
76
- {
77
- key: 'base',
78
- title: '基本',
79
- options: ['text', 'ui', 'styles', 'icon', 'showName', 'preview']
80
- },
81
- {
82
- key: 'event',
83
- title: '事件',
84
- options: ['handler', 'metaId', 'action', 'rule', 'moveType', 'exportFileImmediately', 'exportFileFields', 'exportFileNameFields', 'openMode', 'page', 'menuId', 'serviceId', 'pageType', 'printWay', 'printCode', 'cptName', 'printOperates', 'showDownloadReportDialog', 'showDownloadReportFormat', 'downloadReportFormat', 'downloadReportNameFields', 'downloadReportNameSplit', 'downloadReportWay', 'destActivityId', 'processNode', 'processCode', 'processNodes', 'endOtherNode', 'showCheckFields', 'checkRequireFields', 'checkOpinionValue', 'function', 'importPromptCode', 'sendMessageType', 'defaultMessageTemplate', 'messageTemplateScope', 'receiveMessagePhone', 'receiveMessageEmail', 'sendMessageEmail', 'editableFields', 'params', 'beforeTrigger', 'afterTrigger', 'afterTriggerPage', 'afterTriggerPageOpenMode', 'afterTriggerParams']
85
- },
86
- {
87
- key: 'advance',
88
- title: '高级',
89
- options: ['terminal', 'num', 'limitFlag', 'limitCondition', 'limitTip', 'showConditionType', 'showCondition', 'showConditionEl', 'confirm', 'confirmMsg', 'confirmButtonText', 'cancelButtonText', 'successMsg', 'failMsg', 'mask']
90
- }
91
- ]
92
- this.operateOptions = {
93
- showCheckFields: {
94
- key: 'showCheckFields',
95
- label: '显示字段',
96
- type: 'checkbox',
97
- options: [{ label: '审核意见', value: 'opinion' }, { label: '审核签名', value: 'sign' }],
98
- showFlag: { handler: ['batchCheck'] }
99
- },
100
- checkRequireFields: {
101
- key: 'checkRequireFields',
102
- label: '必填字段',
103
- type: 'checkbox',
104
- options: [{ label: '审核意见', value: 'opinion' }, { label: '审核签名', value: 'sign' }],
105
- showFlag: { handler: ['batchCheck'] }
106
- },
107
- checkOpinionValue: {
108
- key: 'checkOpinionValue',
109
- label: '审核意见默认值',
110
- type: 'text',
111
- showFlag: { handler: ['batchCheck'], showCheckFields: ['opinion'] }
112
- },
113
- importPromptCode: {
114
- key: 'importPromptCode',
115
- label: '导入大模型提示词',
116
- type: 'object',
117
- object: 'FM_AI_PROMPT',
118
- dataKey: 'CODE',
119
- showFlag: { handler: ['entityImport'] }
120
- },
121
- sendMessageType: {
122
- key: 'sendMessageType',
123
- label: '发送方式',
124
- type: 'checkbox',
125
- defaultValue: ['template', 'custom'],
126
- options: [{ label: '模版发送', value: 'template' }, { label: '自定义', value: 'custom' }],
127
- showFlag: { handler: ['sendMessage'] }
128
- },
129
- defaultMessageTemplate: {
130
- key: 'defaultMessageTemplate',
131
- label: '默认模版',
132
- type: 'object',
133
- object: 'FM_MESSAGE_TEMPLATE',
134
- scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
135
- showFlag: { handler: ['sendMessage'] }
136
- },
137
- messageTemplateScope: {
138
- key: 'messageTemplateScope',
139
- label: '模版范围',
140
- type: 'object',
141
- object: 'FM_MESSAGE_TEMPLATE',
142
- fieldConfigs: { isMultiple: '1' },
143
- scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
144
- showFlag: { handler: ['sendMessage'] }
145
- },
146
- receiveMessagePhone: {
147
- key: 'receiveMessagePhone',
148
- label: '接收人手机号',
149
- type: 'field',
150
- showSubField: false,
151
- showSubFlag: false,
152
- showFlag: { handler: ['sendMessage'] }
153
- },
154
- receiveMessageEmail: {
155
- key: 'receiveMessageEmail',
156
- label: '接收人邮箱',
157
- type: 'field',
158
- showSubField: false,
159
- showSubFlag: false,
160
- showFlag: { handler: ['sendMessage'] }
161
- },
162
- sendMessageEmail: {
163
- key: 'sendMessageEmail',
164
- label: '默认发送邮箱',
165
- type: 'object',
166
- object: 'FM_MAIL_CONFIG',
167
- scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
168
- showFlag: { handler: ['sendMessage'] }
169
- },
170
- exportFileImmediately: {
171
- key: 'exportFileImmediately',
172
- label: '是否直接导出',
173
- type: 'switch',
174
- options: [{ label: '是', value: true }, { label: '否', value: false }],
175
- defaultValue: false,
176
- showFlag: { handler: ['exportFile'] }
177
- },
178
- exportFileFields: {
179
- key: 'exportFileFields',
180
- label: '导出附件',
181
- type: 'field',
182
- limit: { dataType: ['blob', 'photo'] },
183
- showFlag: { handler: ['exportFile'], exportFileImmediately: true }
184
- },
185
- exportFileNameFields: {
186
- key: 'exportFileNameFields',
187
- label: '导出附件命名',
188
- type: 'field',
189
- showFlag: { handler: ['exportFile'], exportFileImmediately: true }
190
- },
191
- page: {
192
- key: 'page',
193
- label: '打开页面',
194
- type: 'page',
195
- showFlag: { handler: ['goPage', 'addEntity', 'editEntity', 'entityImport', 'exportFile'] }
196
- },
197
- editableFields: {
198
- key: 'editableFields',
199
- label: '可编辑字段',
200
- type: 'field',
201
- showSubField: false,
202
- showSubFlag: false,
203
- showFlag: { handler: ['editMultiEntity'] }
204
- },
205
- processCode: {
206
- key: 'processCode',
207
- label: '选择流程',
208
- type: 'object',
209
- object: 'ACT_RE_MODEL',
210
- dataKey: 'KEY',
211
- fieldConfigs: {
212
- scopeParams: [{ field: 'ENTITY', values: this.currentMetaId }, { field: 'CATEGORY', values: '1' }]
213
- },
214
- showFlag: { handler: ['skipProcessNode', 'resetCheckPerson', 'rejectionProcess'] }
215
- },
216
- processNodes: {
217
- key: 'processNodes',
218
- label: '选择可跳转结束节点',
219
- type: 'select',
220
- multiple: true,
221
- showFlag: { handler: ['skipProcessNode'] }
222
- },
223
- endOtherNode: {
224
- key: 'endOtherNode',
225
- label: '结束其他节点',
226
- type: 'switch',
227
- options: [{ label: '是', value: true }, { label: '否', value: false }],
228
- defaultValue: true,
229
- showFlag: { handler: ['skipProcessNode'] }
230
- }
231
- }
232
- let oldMetaId = this.currentMetaId
233
- let oldProcessCode = null
234
- this.changeOperate = (key, operate) => {
235
- if (operate.metaId !== oldMetaId) {
236
- const processCode = this.operateOptions.processCode
237
- oldMetaId = operate.metaId
238
- delete this.operateOptions.processCode
239
- this.$nextTick(() => {
240
- this.operateOptions.processCode = {
241
- ...processCode,
242
- fieldConfigs: {
243
- scopeParams: [{ field: 'ENTITY', values: operate.metaId || this.currentMetaId }, { field: 'CATEGORY', values: '1' }]
244
- }
245
- }
246
- })
247
- }
248
- if (operate?.processCode && operate.processCode !== oldProcessCode) {
249
- oldProcessCode = operate.processCode
250
- this.$http.get({
251
- action: 'processNodeList',
252
- entityId: 'ACT_RE_MODEL',
253
- processCode: operate.processCode
254
- })
255
- .then(data => {
256
- const optionList = data.map(item => {
257
- return {
258
- label: item.name,
259
- value: item.id
260
- }
261
- })
262
- const processNodes = this.operateOptions.processNodes
263
- delete this.operateOptions.processNodes
264
- this.$nextTick(() => {
265
- this.operateOptions.processNodes = { ...processNodes, options: optionList }
266
- })
267
- })
268
- }
269
- }
270
- },
271
- initDefaultConfigs () {
272
- let defaultListFields = []
273
- if (this.currentMeta) {
274
- if (this.metaView) {
275
- const { listFields, fields } = this.metaView
276
- if (listFields) {
277
- defaultListFields = JSON.parse(listFields)
278
- } else {
279
- defaultListFields = JSON.parse(fields)
280
- }
281
- } else {
282
- defaultListFields = this.currentMeta.getAllFields()
283
- }
284
- }
285
- // const { addPage = 'entity-add-page', editPage = 'entity-edit-page', openMode = '3', addPageFlag = 'v_add' } = this.allConfigs
286
- const { addPage = 'entity-add-page', editPage = 'entity-edit-page', openMode = '3' } = this.allConfigs
287
- let keywords = []
288
- let metaKey = 'ID'
289
- if (this.currentMeta) {
290
- const { label, keyNames = [] } = this.currentMeta
291
- metaKey = this.currentMeta.getKey()
292
- keywords = [...keyNames]
293
- if (label) {
294
- keywords.push(label)
295
- }
296
- }
297
- this.defaultConfigs = {
298
- flex: true,
299
- componentName: this.componentInfo.title,
300
- type: 'table',
301
- addPageFlag: 'v_add',
302
- editPageFlag: 'v_add',
303
- detailPageFlag: 'v_add',
304
- detailFlag: true,
305
- componentType: '',
306
- metaId: this.pageMetaId,
307
- action: 'list',
308
- searchFlag: true,
309
- searchMode: 'keyword',
310
- showSearchLabel: false,
311
- isChangeListType: false,
312
- border: false,
313
- keywords,
314
- searchFields: [],
315
- listFields: defaultListFields,
316
- pageFlag: true,
317
- pageSize: 20,
318
-
319
- operateEllipsis: 2,
320
- serialColumnFlag: true, // 是否显示序号列
321
- operateColumnFlag: true, // 是否显示操作列
322
- operateColumnWidth: 100,
323
- operateColumnEllipsis: 2,
324
- operateColumnPosition: 'start',
325
- categoryExpandLevel: 'none',
326
- operateTreeListFlag: true,
327
- dragSort: false,
328
- fixedTable: true,
329
- span: 24,
330
- metaKeyField: [metaKey],
331
- operates: [
332
- {
333
- text: '新增',
334
- handler: 'addEntity',
335
- action: 'save',
336
- ui: 'primary',
337
- num: 0,
338
- openMode,
339
- component: addPage,
340
- params: {}
341
- },
342
- {
343
- text: '删除',
344
- handler: 'commonAction',
345
- action: 'removeMulti',
346
- num: 'n',
347
- confirm: true,
348
- confirmMsg: this.$t('Confirm the deletion') + '?',
349
- successMsg: '删除成功',
350
- params: {
351
- ids: `#[${metaKey}]`
352
- }
353
- },
354
- {
355
- text: '导入',
356
- handler: 'entityImport',
357
- action: 'entityImport',
358
- component: 'import-page',
359
- params: {}
360
- },
361
- {
362
- text: '导出',
363
- handler: 'goPage',
364
- action: 'entityExport',
365
- component: 'export-page',
366
- params: {
367
- selects: `#[${metaKey}]`,
368
- total: '$[total]',
369
- params: '$[params]',
370
- fields: '$[exportFields]',
371
- scopeParams: '$[scopeParams]'
372
- }
373
- }
374
- ],
375
- columnOperates: [
376
- // {
377
- // text: '多选',
378
- // handler: 'multiSelect',
379
- // terminal: 'mobile'
380
- // },
381
- {
382
- text: '编辑',
383
- handler: 'editEntity',
384
- action: 'update',
385
- num: 1,
386
- openMode,
387
- component: editPage,
388
- pageType: 'EDIT'
389
- }
390
- // {
391
- // text: '删除',
392
- // handler: 'commonAction',
393
- // action: 'removeMulti',
394
- // num: 'n',
395
- // confirmMsg: this.$t('Confirm the deletion') + '?',
396
- // successMsg: '删除成功',
397
- // params: {
398
- // ids: `#[${this.$metaKey}]`
399
- // }
400
- // }
401
- ],
402
- treeListOperates: [{
403
- text: '上移',
404
- handler: 'operateTree',
405
- action: 'operateTree',
406
- moveType: 'pre'
407
- },
408
- {
409
- text: '下移',
410
- handler: 'operateTree',
411
- action: 'operateTree',
412
- moveType: 'next'
413
- },
414
- {
415
- text: '移到最前',
416
- handler: 'operateTree',
417
- action: 'operateTree',
418
- moveType: 'first'
419
- },
420
- {
421
- text: '移到最后',
422
- handler: 'operateTree',
423
- action: 'operateTree',
424
- moveType: 'last'
425
- },
426
- {
427
- text: '移到外层',
428
- handler: 'operateTree',
429
- action: 'operateTree',
430
- moveType: 'upper'
431
- },
432
- {
433
- text: '移到指定位置',
434
- action: 'dragTree',
435
- handler: 'dragTree'
436
- }],
437
-
438
- // 列表内容
439
- treeExpandLevel: 'first',
440
- treeExpandMore: false
441
- }
442
- },
443
- initConfig () {
444
- const config = this.$_.cloneDeep(this.compConfig)
445
- if (this.componentInfo.span) {
446
- config.span = this.componentInfo.span
447
- }
448
- this.config = config
449
- },
450
- getFieldOptions () {
451
- this.getFunctionOption()
452
- this.fieldOptions = [
453
- { key: 'attriName', label: '字段', readonly: true },
454
- { key: 'configWay', label: '配置方式', type: 'radio', options: [{ label: '默认配置', value: 'default' }, { label: '自定义', value: 'custom' }], defaultValue: 'default' },
455
- { key: 'attriLabel', label: '名称', type: 'text' },
456
- { key: 'width', label: '宽度', type: 'text', defaultValue: '120' },
457
- { key: 'color', label: '字体颜色', type: 'color', defaultValue: '#333' },
458
- { key: 'icon', label: '图标', type: 'object', object: 'FM_FONT_ICON', tip: '图标只在卡片模式展示' },
459
- { key: 'iconColor', label: '图标颜色', type: 'color' },
460
- { key: 'newLine', label: '是否换行', type: 'switch', defaultValue: false },
461
- {
462
- key: 'lineNum',
463
- label: '显示行数',
464
- type: 'num',
465
- showFlag: {
466
- newLine: true
467
- }
468
- },
469
- {
470
- key: 'showTooltip',
471
- label: '鼠标悬浮展示',
472
- type: 'switch',
473
- defaultValue: true,
474
- showFlag: {
475
- newLine: [false, null, undefined]
476
- }
477
- },
478
- { key: 'locked', label: '是否锁定', type: 'switch', defaultValue: false },
479
- { key: 'editable', label: '可编辑', type: 'switch', defaultValue: false },
480
- { key: 'rule', label: '逻辑编排', type: 'select', options: this.ruleList, showFlag: { editable: true } },
481
- { key: 'addible', label: '可新增', type: 'switch', defaultValue: true },
482
- { key: 'state', label: '字段状态', type: 'radio', options: [{ label: '显示', value: 'DETAIL' }, { label: '隐藏', value: 'HIDDEN' }], defaultValue: 'DETAIL' },
483
- { key: 'align', label: '对齐方式', type: 'radio', options: [{ label: '左对齐', value: 'left' }, { label: '居中对齐', value: 'center' }, { label: '右对齐', value: 'right' }], defaultValue: 'left' },
484
- { key: 'isLabel', label: '外部标签', type: 'radio', options: [{ label: '是', value: true }, { label: '否', value: false }] },
485
- { key: 'sortable', label: '可排序', type: 'radio', options: [{ label: '是', value: true }, { label: '否', value: false }] },
486
- {
487
- key: 'findPageId',
488
- label: '对象查找页面',
489
- type: 'object',
490
- object: 'FM_PAGE_CONFIG',
491
- scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
492
- showFlag: {
493
- editable: true,
494
- dataType: ['multiobject', 'object', 'user', 'dept', 'list', 'treeList']
495
- }
496
- },
497
- {
498
- key: 'objectScope',
499
- label: '对象查询范围',
500
- type: 'object-scope',
501
- showFlag: {
502
- editable: true,
503
- dataType: ['multiobject', 'object', 'user', 'dept']
504
- }
505
- },
506
- {
507
- key: 'fieldExMethod',
508
- label: '字段扩展方式',
509
- type: 'radio',
510
- code: 'FIELD_EX_METHOD',
511
- defaultValue: 'suffix',
512
- showFlag: {
513
- dataType: ['text', 'num']
514
- }
515
- },
516
- {
517
- key: 'suffix',
518
- label: '前/后缀内容',
519
- type: 'text',
520
- showFlag: {
521
- dataType: ['text', 'num']
522
- }
523
- },
524
- {
525
- key: 'numericalUnits',
526
- label: '数值单位',
527
- type: 'radio',
528
- code: 'Numerical units',
529
- showFlag: {
530
- dataType: ['num']
531
- }
532
- },
533
- { key: 'link', label: '链接', type: 'switch' },
534
- { key: 'linkType', label: '链接类型', type: 'radio', code: 'LINK_TYPE', showFlag: { link: [true] } },
535
- { key: 'linkPageId', label: '页面', type: 'object', object: 'FM_PAGE_CONFIG', scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }], showFlag: { link: [true], linkType: 'page' } },
536
- { key: 'linkAddress', label: '链接地址', showFlag: { link: [true], linkType: 'url' } },
537
- { key: 'linkOpenType', label: '链接打开方式', type: 'radio', code: 'OPEN_PAGE_MODE', showFlag: { link: [true], linkType: ['page', 'detail'] } },
538
- { key: 'linkParams', label: '链接参数设置', type: 'params', showFlag: { link: [true], linkType: ['page', 'detail'] } },
539
- { key: 'showSummary', label: '显示合计项', type: 'switch', defaultValue: false, showFlag: { dataType: ['num', 'int'] } },
540
- { key: 'showOptionStyle', label: '显示选项样式', type: 'switch', defaultValue: false, showFlag: { dataType: ['list'] } },
541
- { key: 'imageFit', label: '图片显示方式', type: 'radio', options: [{ label: '剪切', value: 'cover' }, { label: '填充', value: 'fill' }, { label: '缩放', value: 'contain' }, { label: '不做处理', value: 'none' }], defaultValue: 'cover', showFlag: { dataType: ['photo'] } },
542
- { key: 'imgaePosition', label: '图片显示位置', type: 'radio', options: [{ label: '顶部', value: 'top' }, { label: '居中', value: 'center' }, { label: '底部', value: 'bottom' }], defaultValue: 'center', showFlag: { dataType: ['photo'] } },
543
- { key: 'previewDialogSize', label: '预览弹窗大小', type: 'radio', options: [{ label: '50%', value: '50%' }, { label: '75%', value: '75%' }, { label: '80%', value: '80%' }, { label: '90%', value: '90%' }, { label: '全屏', value: 'fullscreen' }], defaultValue: '75%', showFlag: { dataType: ['blob'] } },
544
- // {
545
- // key: 'showWay',
546
- // label: '显示内容',
547
- // type: 'radio',
548
- // options: [{ label: '字段值', value: 'value' }, { label: '记录数', value: 'record' }, { label: '字段统计', value: 'statistics' }],
549
- // defaultValue: 'value',
550
- // showCondition: {
551
- // el: '#{field.relationSort===\'1\'&&field.type!==\'meta\'}'
552
- // }
553
-
554
- // },
555
- {
556
- key: 'showWay',
557
- label: '显示内容',
558
- type: 'radio',
559
- options: [{ label: '字段值', value: 'value' }, { label: '记录数', value: 'record' }, { label: '自定义', value: 'el' }],
560
- defaultValue: 'value',
561
- showFlag: {
562
- type: 'meta'
563
- }
564
- },
565
- {
566
- key: 'statisticsType',
567
- label: '统计方式',
568
- type: 'radio',
569
- code: 'FIELD_STATISTIC_TYPE',
570
- defaultValue: 'SUM',
571
- showFlag: {
572
- showWay: 'statistics',
573
- type: 'meta'
574
- }
575
- },
576
- {
577
- key: 'showWay',
578
- label: '显示内容',
579
- type: 'radio',
580
- options: [{ label: '字段值', value: 'value' }, { label: '统计值', value: 'statistics' }],
581
- defaultValue: 'value',
582
- showFlag: {
583
- relationSort: '1',
584
- dataType: ['num']
585
- }
586
- },
587
- {
588
- key: 'statisticsType',
589
- label: '统计方式',
590
- type: 'radio',
591
- code: 'FIELD_STATISTIC_TYPE',
592
- defaultValue: 'SUM',
593
- showFlag: {
594
- showWay: 'statistics',
595
- relationSort: '1',
596
- dataType: ['num']
597
- }
598
- },
599
- {
600
- key: 'fields',
601
- label: '展示字段',
602
- type: 'field',
603
- showFlag: {
604
- // relationSort: '1',
605
- type: 'meta',
606
- showWay: ['value', undefined, null]
607
- }
608
- },
609
-
610
- {
611
- key: 'showEl',
612
- label: '自定义内容',
613
- type: 'rule',
614
- showFlag: {
615
- showWay: 'el',
616
- type: 'meta'
617
- }
618
- },
619
- {
620
- key: 'separator',
621
- label: '字段分隔符',
622
- type: 'radio-input',
623
- options: [{ label: '、', value: '、' }, { label: '/', value: '/' }, { label: ',', value: ',' }],
624
- defaultValue: '、',
625
- showFlag: {
626
- // relationSort: '1'
627
- type: 'meta'
628
- }
629
- },
630
- {
631
- key: 'showFieldName',
632
- label: '是否展示字段名',
633
- type: 'radio',
634
- options: [{ label: '是', value: '1' }, { label: '否', value: '0' }],
635
- defaultValue: '0',
636
- showFlag: {
637
- // relationSort: '1'
638
- type: 'meta'
639
- }
640
- },
641
- {
642
- key: 'orderFields',
643
- label: '数据排序',
644
- type: 'order-field',
645
- showFlag: {
646
- relationSort: '1'
647
- }
648
- },
649
- {
650
- key: 'scopeParams',
651
- label: '查询范围',
652
- type: 'scope',
653
- showFlag: {
654
- relationSort: '1'
655
- }
656
- },
657
- {
658
- key: 'recordSeparator',
659
- label: '记录分隔符',
660
- type: 'radio-input',
661
- options: [{ label: '换行', value: '\n' }, { label: '/', value: '/' }, { label: ',', value: ',' }],
662
- defaultValue: '\n',
663
- showFlag: {
664
- relationSort: '1'
665
- }
666
- }
667
- ]
668
- this.rowFieldOptions = [...this.fieldOptions]
669
- this.rowFieldOptions.splice(4, 0,
670
- { key: 'showLabel', label: '显示标题', type: 'radio', options: [{ label: '显示', value: true }, { label: '不显示', value: false }], defaultValue: false },
671
- { key: 'split', label: '分隔符', type: 'radio', options: [{ label: '竖号', value: ' | ' }, { label: '斜杠', value: ' / ' }, { label: '空格', value: ' ' }], defaultValue: ' | ' },
672
- { key: 'fontWeight', label: this.$t('whether the bold'), type: 'radio', options: [{ label: this.$t('yes'), value: 'bold' }, { label: this.$t('no'), value: 'normal' }] },
673
- { key: 'fontSize', label: this.$t('font size'), type: 'num', defaultValue: 14 })
674
- },
675
- addCondition (v) {
676
- const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
677
- backgroundConditionSet.push({ condition: v, style: null })
678
- this.config.backgroundConditionSet = backgroundConditionSet
679
- },
680
- setConditionBackgroundStyle (item, index) {
681
- this.backgroundStyleDialog = true
682
- this.conditionBackgroundStyle = item.style || {}
683
- this.editConditionIndex = index
684
- },
685
- deleteConditionBackgroundStyle (index) {
686
- const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
687
- backgroundConditionSet.splice(index, 1)
688
- this.config.backgroundConditionSet = backgroundConditionSet
689
- },
690
- saveConditionBackgroundStyle () {
691
- const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
692
- backgroundConditionSet.splice(this.editConditionIndex, 1, { ...backgroundConditionSet[this.editConditionIndex], style: this.conditionBackgroundStyle })
693
- this.config.backgroundConditionSet = backgroundConditionSet
694
- this.conditionBackgroundStyle = {}
695
- this.backgroundStyleDialog = false
696
- this.editConditionIndex = null
697
- },
698
- renderCardBackground () {
699
- const { backgroundConditionSet = [] } = this.config
700
- return (
701
- <div class={['epx-page-designer-setting-style__item', 'epx-visual-entity-list__card-background', { 'epx-page-designer-setting-style__item--unfold': this.unfold }]}>
702
- <div class="epx-page-designer-setting-style__header">
703
- <span>
704
- <i class="epx-page-designer-setting-style__fold-icon el-icon-caret-right" onClick={() => { this.unfold = !this.unfold }}></i>
705
- <label class="epx-page-designer-setting-style__label" for="">{this.$t('background')}</label>
706
- </span>
707
- </div>
708
- <div class="epx-page-designer-setting-style__content">
709
- <epx-visual-config-background v-model={this.config.backgroundStyle} class="epx-visual-entity-list__background-style" defaultValue={{
710
- backgroundSize: 'cover',
711
- backgroundRepeat: 'no-repeat',
712
- backgroundPosition: 'center'
713
- }}></epx-visual-config-background>
714
- <div class="epx-visual-entity-list__background-conditions">
715
- {
716
- backgroundConditionSet.map((item, index) => (
717
- <div key={index} class="epx-visual-entity-list__background-condition-item">
718
- <div class="epx-visual-entity-list__background-condition-content">
719
- <epx-visual-config-scope
720
- designer={this.designer}
721
- value={item.condition}
722
- pageParams={this.pageParams}
723
- treeFieldStore={this.treeFieldStore}
724
- componentMetaId={this.componentMetaId || this.pageMetaId}
725
- scopeConfigs={this.scopeConfigs}
726
- state='DETAIL'
727
- />
728
- <el-button type="primary" link class="epx-visual-entity-list__background-condition-set" onClick={this.setConditionBackgroundStyle.bind(this, item, index)}>
729
- <i class="el-icon-setting"></i>
730
- 背景设置
731
- </el-button>
732
- </div>
733
- <i class="epx-visual-entity-list__background-condition-remove el-icon-close" onClick={this.deleteConditionBackgroundStyle.bind(this, index)}></i>
734
- </div>
735
- ))
736
- }
737
- <epx-visual-config-scope
738
- designer={this.designer}
739
- value={this.backgroundCondition}
740
- pageParams={this.pageParams}
741
- treeFieldStore={this.treeFieldStore}
742
- componentMetaId={this.componentMetaId || this.pageMetaId}
743
- scopeConfigs={this.scopeConfigs}
744
- operateName="+ 添加动态背景条件"
745
- onChangeConfigs={v => this.addCondition(v)}
746
- >
747
- </epx-visual-config-scope>
748
- </div>
749
-
750
- <el-dialog
751
- title="背景设置"
752
- modelValue={this.backgroundStyleDialog}
753
- width="420px"
754
- show-close={false}
755
- append-to-body
756
- destroy-on-close
757
- center v-slots={{
758
- footer: () => (<span class="dialog-footer">
759
- <el-button onClick={() => { this.backgroundStyleDialog = false }}>取 消</el-button>
760
- <el-button type="primary"onClick={this.saveConditionBackgroundStyle}>确 定</el-button>
761
- </span>)
762
- }}>
763
- {
764
- this.backgroundStyleDialog &&
765
- <epx-visual-config-background
766
- v-model={this.conditionBackgroundStyle}
767
- defaultValue={{
768
- backgroundSize: 'cover',
769
- backgroundRepeat: 'no-repeat'
770
- }}></epx-visual-config-background>
771
- }
772
- </el-dialog>
773
- </div>
774
- </div>
775
- )
776
- }
777
- }
778
- }
779
- </script>
780
- <style lang="scss">
781
- // 2026-09-09:整块从 <style scoped> 搬来。
782
- // Vue3 的 extends **不继承** __scopeId,本组件有 4 个纯 script 继承者(ClientList /
783
- // ComponentList / DblogList / MetaList,都没有自己的 <template>、也没转写 __scopeId)
784
- // ⇒ 它们渲染出的 DOM 上一个 data-v-* 都没有,这一簇规则整块静默失效:卡片背景配置项的
785
- // 负边距丢失、条件列表没有分隔线与 flex 布局。
786
- //
787
- // ⚠️ 三个搬迁要点,别改回去:
788
- // 1) 类名必须带 BEM 前缀——`.background-style` / `.background-condition__*` 都是通用名,
789
- // 裸着放进无 scoped 块就是全局污染。
790
- // 2) 原文的 `:deep(...)` 全部去掉了:`:deep()` 是 scoped 专用的穿透语法,只有 scoped 块
791
- // 才会被编译器改写;留在无 scoped 块里会原样输出成浏览器不认识的伪类 ⇒ 规则照样失效。
792
- // 无 scoped 下嵌在块内本身就是后代选择器,语义等价。
793
- // 3) 这簇 DOM 挂在 `epx-page-designer-setting-style__item` 上,**不在** .epx-visual-entity-list
794
- // 的后代里。能这么写是因为本仓 e() 在不含 modifier / .is- / 伪类时走 @at-root,生成的是
795
- // 独立类名 `.epx-x__y` 而不是后代选择器(见 theme/utils/mixins.scss)。
796
- //
797
- // 原 `.background-condititon`(三个 t)是笔误,与 `.background-condition__*` 并非同名;
798
- // 类名反正要整体重命名,就没把笔误固化进 BEM 名,统一成 conditions,JSX 同步改。
799
- @include b(visual-entity-list) {
800
- @include e(card-background) {
801
- margin: 0 -10px;
802
-
803
- .epx-page-designer-setting-style__subitem {
804
- margin: 20px 0;
805
- }
806
- .epx-page-designer-setting-style__content {
807
- background: none;
808
- padding: 0;
809
- }
810
- }
811
- @include e(background-style) {
812
- padding: 10px 10px 10px 28px;
813
- background: #F5F7FA;
814
- }
815
- @include e(background-conditions) {
816
- padding: 10px;
817
- }
818
- @include e(background-condition-item) {
819
- display: flex;
820
- padding: 10px 0;
821
- border-bottom: 1px solid #DCDCDC;
822
- }
823
- @include e(background-condition-content) {
824
- flex: 1;
825
- }
826
- @include e(background-condition-set) {
827
- margin: 0;
828
- i {
829
- margin-right: 4px;
830
- }
831
- }
832
- @include e(background-condition-remove) {
833
- font-size: var(--epx-font-size-l);
834
- cursor: pointer;
835
- margin-top: 4px;
836
- }
837
- }
838
- </style>
1
+ <script>
2
+ // @jsx-vue3(T30 JSX 批:Vue3 JSX 语法,@vue/babel-plugin-jsx 编译)
3
+
4
+ import ComponentVue from './Component.vue'
5
+ import Background from './config/Background.vue'
6
+ export default {
7
+ name: 'epx-visual-entity-list',
8
+ extends: ComponentVue,
9
+ components: {
10
+ [Background.name]: Background
11
+ },
12
+ data () {
13
+ return {
14
+ FunctionOption: [],
15
+ operateConfigs: {},
16
+ unfold: false,
17
+ backgroundCondition: null,
18
+ backgroundStyleDialog: false,
19
+ operateOptions: {}
20
+ }
21
+ },
22
+ computed: {
23
+ metaView () {
24
+ if (this.currentMeta && this.currentMeta.metaView) {
25
+ return this.currentMeta.metaView[this.currentMetaViewId]
26
+ }
27
+ return null
28
+ }
29
+ },
30
+ watch: {
31
+ allConfigs: {
32
+ handler (v) {
33
+ this.componentMetaId = v.metaId
34
+ },
35
+ immediate: true
36
+ },
37
+ 'allConfigs.categoryField': {
38
+ handler (v) {
39
+ // 根据字段获取对象
40
+ if (v) {
41
+ const fieldConfigs = this.currentMeta.getAllFieldConfigs().find(item => item.attriName === v[0])
42
+ if (fieldConfigs) {
43
+ this.treeMetaId = fieldConfigs.codeKey
44
+ this.treeFieldIsObject = fieldConfigs.dataType === 'object' || fieldConfigs.dataType === 'dept' || fieldConfigs.dataType === 'user'
45
+ // this.initConfigOptions()
46
+ }
47
+ }
48
+ },
49
+ immediate: true
50
+ },
51
+ async currentMetaViewId (v) {
52
+ if (!v) return
53
+ await this.getAllFields()
54
+ // 仅用户切换视图且字段树加载成功时,按新视图过滤已配置字段(配置回显不过滤,避免误删)
55
+ if (!this.canFilterFieldsByView(v)) return
56
+ const { listFields, orderFields, rowFields } = this.config
57
+ if (listFields) {
58
+ const filtered = listFields.filter(item => this.getField(item.attriName || item))
59
+ if (filtered.length !== listFields.length) this.changeConfigItem('listFields', filtered)
60
+ }
61
+ if (orderFields) {
62
+ const filtered = orderFields.filter(item => this.getField(item.attriName || item))
63
+ if (filtered.length !== orderFields.length) this.changeConfigItem('orderFields', filtered)
64
+ }
65
+ if (rowFields) {
66
+ const filtered = rowFields.map(row => row.filter(item => this.getField(item.attriName || item)))
67
+ if (!this.$_.isEqual(filtered, rowFields)) this.changeConfigItem('rowFields', filtered)
68
+ }
69
+ }
70
+ },
71
+ methods: {
72
+ getOperateOptions () {
73
+ this.getHandlerList()
74
+ this.getCommonOperates()
75
+ this.operateConfigs = [
76
+ {
77
+ key: 'base',
78
+ title: '基本',
79
+ options: ['text', 'ui', 'styles', 'icon', 'showName', 'preview']
80
+ },
81
+ {
82
+ key: 'event',
83
+ title: '事件',
84
+ options: ['handler', 'metaId', 'action', 'rule', 'moveType', 'exportFileImmediately', 'exportFileFields', 'exportFileNameFields', 'openMode', 'page', 'menuId', 'serviceId', 'pageType', 'printWay', 'printCode', 'cptName', 'printOperates', 'showDownloadReportDialog', 'showDownloadReportFormat', 'downloadReportFormat', 'downloadReportNameFields', 'downloadReportNameSplit', 'downloadReportWay', 'destActivityId', 'processNode', 'processCode', 'processNodes', 'endOtherNode', 'showCheckFields', 'checkRequireFields', 'checkOpinionValue', 'function', 'importPromptCode', 'sendMessageType', 'defaultMessageTemplate', 'messageTemplateScope', 'receiveMessagePhone', 'receiveMessageEmail', 'sendMessageEmail', 'editableFields', 'params', 'beforeTrigger', 'afterTrigger', 'afterTriggerPage', 'afterTriggerPageOpenMode', 'afterTriggerParams']
85
+ },
86
+ {
87
+ key: 'advance',
88
+ title: '高级',
89
+ options: ['terminal', 'num', 'limitFlag', 'limitCondition', 'limitTip', 'showConditionType', 'showCondition', 'showConditionEl', 'confirm', 'confirmMsg', 'confirmButtonText', 'cancelButtonText', 'successMsg', 'failMsg', 'mask']
90
+ }
91
+ ]
92
+ this.operateOptions = {
93
+ showCheckFields: {
94
+ key: 'showCheckFields',
95
+ label: '显示字段',
96
+ type: 'checkbox',
97
+ options: [{ label: '审核意见', value: 'opinion' }, { label: '审核签名', value: 'sign' }],
98
+ showFlag: { handler: ['batchCheck'] }
99
+ },
100
+ checkRequireFields: {
101
+ key: 'checkRequireFields',
102
+ label: '必填字段',
103
+ type: 'checkbox',
104
+ options: [{ label: '审核意见', value: 'opinion' }, { label: '审核签名', value: 'sign' }],
105
+ showFlag: { handler: ['batchCheck'] }
106
+ },
107
+ checkOpinionValue: {
108
+ key: 'checkOpinionValue',
109
+ label: '审核意见默认值',
110
+ type: 'text',
111
+ showFlag: { handler: ['batchCheck'], showCheckFields: ['opinion'] }
112
+ },
113
+ importPromptCode: {
114
+ key: 'importPromptCode',
115
+ label: '导入大模型提示词',
116
+ type: 'object',
117
+ object: 'FM_AI_PROMPT',
118
+ dataKey: 'CODE',
119
+ showFlag: { handler: ['entityImport'] }
120
+ },
121
+ sendMessageType: {
122
+ key: 'sendMessageType',
123
+ label: '发送方式',
124
+ type: 'checkbox',
125
+ defaultValue: ['template', 'custom'],
126
+ options: [{ label: '模版发送', value: 'template' }, { label: '自定义', value: 'custom' }],
127
+ showFlag: { handler: ['sendMessage'] }
128
+ },
129
+ defaultMessageTemplate: {
130
+ key: 'defaultMessageTemplate',
131
+ label: '默认模版',
132
+ type: 'object',
133
+ object: 'FM_MESSAGE_TEMPLATE',
134
+ scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
135
+ showFlag: { handler: ['sendMessage'] }
136
+ },
137
+ messageTemplateScope: {
138
+ key: 'messageTemplateScope',
139
+ label: '模版范围',
140
+ type: 'object',
141
+ object: 'FM_MESSAGE_TEMPLATE',
142
+ fieldConfigs: { isMultiple: '1' },
143
+ scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
144
+ showFlag: { handler: ['sendMessage'] }
145
+ },
146
+ receiveMessagePhone: {
147
+ key: 'receiveMessagePhone',
148
+ label: '接收人手机号',
149
+ type: 'field',
150
+ showSubField: false,
151
+ showSubFlag: false,
152
+ showFlag: { handler: ['sendMessage'] }
153
+ },
154
+ receiveMessageEmail: {
155
+ key: 'receiveMessageEmail',
156
+ label: '接收人邮箱',
157
+ type: 'field',
158
+ showSubField: false,
159
+ showSubFlag: false,
160
+ showFlag: { handler: ['sendMessage'] }
161
+ },
162
+ sendMessageEmail: {
163
+ key: 'sendMessageEmail',
164
+ label: '默认发送邮箱',
165
+ type: 'object',
166
+ object: 'FM_MAIL_CONFIG',
167
+ scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
168
+ showFlag: { handler: ['sendMessage'] }
169
+ },
170
+ exportFileImmediately: {
171
+ key: 'exportFileImmediately',
172
+ label: '是否直接导出',
173
+ type: 'switch',
174
+ options: [{ label: '是', value: true }, { label: '否', value: false }],
175
+ defaultValue: false,
176
+ showFlag: { handler: ['exportFile'] }
177
+ },
178
+ exportFileFields: {
179
+ key: 'exportFileFields',
180
+ label: '导出附件',
181
+ type: 'field',
182
+ limit: { dataType: ['blob', 'photo'] },
183
+ showFlag: { handler: ['exportFile'], exportFileImmediately: true }
184
+ },
185
+ exportFileNameFields: {
186
+ key: 'exportFileNameFields',
187
+ label: '导出附件命名',
188
+ type: 'field',
189
+ showFlag: { handler: ['exportFile'], exportFileImmediately: true }
190
+ },
191
+ page: {
192
+ key: 'page',
193
+ label: '打开页面',
194
+ type: 'page',
195
+ showFlag: { handler: ['goPage', 'addEntity', 'editEntity', 'entityImport', 'exportFile'] }
196
+ },
197
+ editableFields: {
198
+ key: 'editableFields',
199
+ label: '可编辑字段',
200
+ type: 'field',
201
+ showSubField: false,
202
+ showSubFlag: false,
203
+ showFlag: { handler: ['editMultiEntity'] }
204
+ },
205
+ processCode: {
206
+ key: 'processCode',
207
+ label: '选择流程',
208
+ type: 'object',
209
+ object: 'ACT_RE_MODEL',
210
+ dataKey: 'KEY',
211
+ fieldConfigs: {
212
+ scopeParams: [{ field: 'ENTITY', values: this.currentMetaId }, { field: 'CATEGORY', values: '1' }]
213
+ },
214
+ showFlag: { handler: ['skipProcessNode', 'resetCheckPerson', 'rejectionProcess'] }
215
+ },
216
+ processNodes: {
217
+ key: 'processNodes',
218
+ label: '选择可跳转结束节点',
219
+ type: 'select',
220
+ multiple: true,
221
+ showFlag: { handler: ['skipProcessNode'] }
222
+ },
223
+ endOtherNode: {
224
+ key: 'endOtherNode',
225
+ label: '结束其他节点',
226
+ type: 'switch',
227
+ options: [{ label: '是', value: true }, { label: '否', value: false }],
228
+ defaultValue: true,
229
+ showFlag: { handler: ['skipProcessNode'] }
230
+ }
231
+ }
232
+ let oldMetaId = this.currentMetaId
233
+ let oldProcessCode = null
234
+ this.changeOperate = (key, operate) => {
235
+ if (operate.metaId !== oldMetaId) {
236
+ const processCode = this.operateOptions.processCode
237
+ oldMetaId = operate.metaId
238
+ delete this.operateOptions.processCode
239
+ this.$nextTick(() => {
240
+ this.operateOptions.processCode = {
241
+ ...processCode,
242
+ fieldConfigs: {
243
+ scopeParams: [{ field: 'ENTITY', values: operate.metaId || this.currentMetaId }, { field: 'CATEGORY', values: '1' }]
244
+ }
245
+ }
246
+ })
247
+ }
248
+ if (operate?.processCode && operate.processCode !== oldProcessCode) {
249
+ oldProcessCode = operate.processCode
250
+ this.$http.get({
251
+ action: 'processNodeList',
252
+ entityId: 'ACT_RE_MODEL',
253
+ processCode: operate.processCode
254
+ })
255
+ .then(data => {
256
+ const optionList = data.map(item => {
257
+ return {
258
+ label: item.name,
259
+ value: item.id
260
+ }
261
+ })
262
+ const processNodes = this.operateOptions.processNodes
263
+ delete this.operateOptions.processNodes
264
+ this.$nextTick(() => {
265
+ this.operateOptions.processNodes = { ...processNodes, options: optionList }
266
+ })
267
+ })
268
+ }
269
+ }
270
+ },
271
+ initDefaultConfigs () {
272
+ let defaultListFields = []
273
+ if (this.currentMeta) {
274
+ if (this.metaView) {
275
+ const { listFields, fields } = this.metaView
276
+ if (listFields) {
277
+ defaultListFields = JSON.parse(listFields)
278
+ } else {
279
+ defaultListFields = JSON.parse(fields)
280
+ }
281
+ } else {
282
+ defaultListFields = this.currentMeta.getAllFields()
283
+ }
284
+ }
285
+ // const { addPage = 'entity-add-page', editPage = 'entity-edit-page', openMode = '3', addPageFlag = 'v_add' } = this.allConfigs
286
+ const { addPage = 'entity-add-page', editPage = 'entity-edit-page', openMode = '3' } = this.allConfigs
287
+ let keywords = []
288
+ let metaKey = 'ID'
289
+ if (this.currentMeta) {
290
+ const { label, keyNames = [] } = this.currentMeta
291
+ metaKey = this.currentMeta.getKey()
292
+ keywords = [...keyNames]
293
+ if (label) {
294
+ keywords.push(label)
295
+ }
296
+ }
297
+ this.defaultConfigs = {
298
+ flex: true,
299
+ componentName: this.componentInfo.title,
300
+ type: 'table',
301
+ addPageFlag: 'v_add',
302
+ editPageFlag: 'v_add',
303
+ detailPageFlag: 'v_add',
304
+ detailFlag: true,
305
+ componentType: '',
306
+ metaId: this.pageMetaId,
307
+ action: 'list',
308
+ searchFlag: true,
309
+ searchMode: 'keyword',
310
+ showSearchLabel: false,
311
+ isChangeListType: false,
312
+ border: false,
313
+ keywords,
314
+ searchFields: [],
315
+ listFields: defaultListFields,
316
+ pageFlag: true,
317
+ pageSize: 20,
318
+
319
+ operateEllipsis: 2,
320
+ serialColumnFlag: true, // 是否显示序号列
321
+ operateColumnFlag: true, // 是否显示操作列
322
+ operateColumnWidth: 100,
323
+ operateColumnEllipsis: 2,
324
+ operateColumnPosition: 'start',
325
+ categoryExpandLevel: 'none',
326
+ operateTreeListFlag: true,
327
+ dragSort: false,
328
+ fixedTable: true,
329
+ span: 24,
330
+ metaKeyField: [metaKey],
331
+ operates: [
332
+ {
333
+ text: '新增',
334
+ handler: 'addEntity',
335
+ action: 'save',
336
+ ui: 'primary',
337
+ num: 0,
338
+ openMode,
339
+ component: addPage,
340
+ params: {}
341
+ },
342
+ {
343
+ text: '删除',
344
+ handler: 'commonAction',
345
+ action: 'removeMulti',
346
+ num: 'n',
347
+ confirm: true,
348
+ confirmMsg: this.$t('Confirm the deletion') + '?',
349
+ successMsg: '删除成功',
350
+ params: {
351
+ ids: `#[${metaKey}]`
352
+ }
353
+ },
354
+ {
355
+ text: '导入',
356
+ handler: 'entityImport',
357
+ action: 'entityImport',
358
+ component: 'import-page',
359
+ params: {}
360
+ },
361
+ {
362
+ text: '导出',
363
+ handler: 'goPage',
364
+ action: 'entityExport',
365
+ component: 'export-page',
366
+ params: {
367
+ selects: `#[${metaKey}]`,
368
+ total: '$[total]',
369
+ params: '$[params]',
370
+ fields: '$[exportFields]',
371
+ scopeParams: '$[scopeParams]'
372
+ }
373
+ }
374
+ ],
375
+ columnOperates: [
376
+ // {
377
+ // text: '多选',
378
+ // handler: 'multiSelect',
379
+ // terminal: 'mobile'
380
+ // },
381
+ {
382
+ text: '编辑',
383
+ handler: 'editEntity',
384
+ action: 'update',
385
+ num: 1,
386
+ openMode,
387
+ component: editPage,
388
+ pageType: 'EDIT'
389
+ }
390
+ // {
391
+ // text: '删除',
392
+ // handler: 'commonAction',
393
+ // action: 'removeMulti',
394
+ // num: 'n',
395
+ // confirmMsg: this.$t('Confirm the deletion') + '?',
396
+ // successMsg: '删除成功',
397
+ // params: {
398
+ // ids: `#[${this.$metaKey}]`
399
+ // }
400
+ // }
401
+ ],
402
+ treeListOperates: [{
403
+ text: '上移',
404
+ handler: 'operateTree',
405
+ action: 'operateTree',
406
+ moveType: 'pre'
407
+ },
408
+ {
409
+ text: '下移',
410
+ handler: 'operateTree',
411
+ action: 'operateTree',
412
+ moveType: 'next'
413
+ },
414
+ {
415
+ text: '移到最前',
416
+ handler: 'operateTree',
417
+ action: 'operateTree',
418
+ moveType: 'first'
419
+ },
420
+ {
421
+ text: '移到最后',
422
+ handler: 'operateTree',
423
+ action: 'operateTree',
424
+ moveType: 'last'
425
+ },
426
+ {
427
+ text: '移到外层',
428
+ handler: 'operateTree',
429
+ action: 'operateTree',
430
+ moveType: 'upper'
431
+ },
432
+ {
433
+ text: '移到指定位置',
434
+ action: 'dragTree',
435
+ handler: 'dragTree'
436
+ }],
437
+
438
+ // 列表内容
439
+ treeExpandLevel: 'first',
440
+ treeExpandMore: false
441
+ }
442
+ },
443
+ initConfig () {
444
+ const config = this.$_.cloneDeep(this.compConfig)
445
+ if (this.componentInfo.span) {
446
+ config.span = this.componentInfo.span
447
+ }
448
+ this.config = config
449
+ },
450
+ getFieldOptions () {
451
+ this.getFunctionOption()
452
+ this.fieldOptions = [
453
+ { key: 'attriName', label: '字段', readonly: true },
454
+ { key: 'configWay', label: '配置方式', type: 'radio', options: [{ label: '默认配置', value: 'default' }, { label: '自定义', value: 'custom' }], defaultValue: 'default' },
455
+ { key: 'attriLabel', label: '名称', type: 'text' },
456
+ { key: 'width', label: '宽度', type: 'text', defaultValue: '120' },
457
+ { key: 'color', label: '字体颜色', type: 'color', defaultValue: '#333' },
458
+ { key: 'icon', label: '图标', type: 'object', object: 'FM_FONT_ICON', tip: '图标只在卡片模式展示' },
459
+ { key: 'iconColor', label: '图标颜色', type: 'color' },
460
+ { key: 'newLine', label: '是否换行', type: 'switch', defaultValue: false },
461
+ {
462
+ key: 'lineNum',
463
+ label: '显示行数',
464
+ type: 'num',
465
+ showFlag: {
466
+ newLine: true
467
+ }
468
+ },
469
+ {
470
+ key: 'showTooltip',
471
+ label: '鼠标悬浮展示',
472
+ type: 'switch',
473
+ defaultValue: true,
474
+ showFlag: {
475
+ newLine: [false, null, undefined]
476
+ }
477
+ },
478
+ { key: 'locked', label: '是否锁定', type: 'switch', defaultValue: false },
479
+ { key: 'editable', label: '可编辑', type: 'switch', defaultValue: false },
480
+ { key: 'rule', label: '逻辑编排', type: 'select', options: this.ruleList, showFlag: { editable: true } },
481
+ { key: 'addible', label: '可新增', type: 'switch', defaultValue: true },
482
+ { key: 'state', label: '字段状态', type: 'radio', options: [{ label: '显示', value: 'DETAIL' }, { label: '隐藏', value: 'HIDDEN' }], defaultValue: 'DETAIL' },
483
+ { key: 'align', label: '对齐方式', type: 'radio', options: [{ label: '左对齐', value: 'left' }, { label: '居中对齐', value: 'center' }, { label: '右对齐', value: 'right' }], defaultValue: 'left' },
484
+ { key: 'isLabel', label: '外部标签', type: 'radio', options: [{ label: '是', value: true }, { label: '否', value: false }] },
485
+ { key: 'sortable', label: '可排序', type: 'radio', options: [{ label: '是', value: true }, { label: '否', value: false }] },
486
+ {
487
+ key: 'findPageId',
488
+ label: '对象查找页面',
489
+ type: 'object',
490
+ object: 'FM_PAGE_CONFIG',
491
+ scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }],
492
+ showFlag: {
493
+ editable: true,
494
+ dataType: ['multiobject', 'object', 'user', 'dept', 'list', 'treeList']
495
+ }
496
+ },
497
+ {
498
+ key: 'objectScope',
499
+ label: '对象查询范围',
500
+ type: 'object-scope',
501
+ showFlag: {
502
+ editable: true,
503
+ dataType: ['multiobject', 'object', 'user', 'dept']
504
+ }
505
+ },
506
+ {
507
+ key: 'fieldExMethod',
508
+ label: '字段扩展方式',
509
+ type: 'radio',
510
+ code: 'FIELD_EX_METHOD',
511
+ defaultValue: 'suffix',
512
+ showFlag: {
513
+ dataType: ['text', 'num']
514
+ }
515
+ },
516
+ {
517
+ key: 'suffix',
518
+ label: '前/后缀内容',
519
+ type: 'text',
520
+ showFlag: {
521
+ dataType: ['text', 'num']
522
+ }
523
+ },
524
+ {
525
+ key: 'numericalUnits',
526
+ label: '数值单位',
527
+ type: 'radio',
528
+ code: 'Numerical units',
529
+ showFlag: {
530
+ dataType: ['num']
531
+ }
532
+ },
533
+ { key: 'link', label: '链接', type: 'switch' },
534
+ { key: 'linkType', label: '链接类型', type: 'radio', code: 'LINK_TYPE', showFlag: { link: [true] } },
535
+ { key: 'linkPageId', label: '页面', type: 'object', object: 'FM_PAGE_CONFIG', scopeParams: [{ field: 'SYSTEM', values: this.SYSTEM }], showFlag: { link: [true], linkType: 'page' } },
536
+ { key: 'linkAddress', label: '链接地址', showFlag: { link: [true], linkType: 'url' } },
537
+ { key: 'linkOpenType', label: '链接打开方式', type: 'radio', code: 'OPEN_PAGE_MODE', showFlag: { link: [true], linkType: ['page', 'detail'] } },
538
+ { key: 'linkParams', label: '链接参数设置', type: 'params', showFlag: { link: [true], linkType: ['page', 'detail'] } },
539
+ { key: 'showSummary', label: '显示合计项', type: 'switch', defaultValue: false, showFlag: { dataType: ['num', 'int'] } },
540
+ { key: 'showOptionStyle', label: '显示选项样式', type: 'switch', defaultValue: false, showFlag: { dataType: ['list'] } },
541
+ { key: 'imageFit', label: '图片显示方式', type: 'radio', options: [{ label: '剪切', value: 'cover' }, { label: '填充', value: 'fill' }, { label: '缩放', value: 'contain' }, { label: '不做处理', value: 'none' }], defaultValue: 'cover', showFlag: { dataType: ['photo'] } },
542
+ { key: 'imgaePosition', label: '图片显示位置', type: 'radio', options: [{ label: '顶部', value: 'top' }, { label: '居中', value: 'center' }, { label: '底部', value: 'bottom' }], defaultValue: 'center', showFlag: { dataType: ['photo'] } },
543
+ { key: 'previewDialogSize', label: '预览弹窗大小', type: 'radio', options: [{ label: '50%', value: '50%' }, { label: '75%', value: '75%' }, { label: '80%', value: '80%' }, { label: '90%', value: '90%' }, { label: '全屏', value: 'fullscreen' }], defaultValue: '75%', showFlag: { dataType: ['blob'] } },
544
+ // {
545
+ // key: 'showWay',
546
+ // label: '显示内容',
547
+ // type: 'radio',
548
+ // options: [{ label: '字段值', value: 'value' }, { label: '记录数', value: 'record' }, { label: '字段统计', value: 'statistics' }],
549
+ // defaultValue: 'value',
550
+ // showCondition: {
551
+ // el: '#{field.relationSort===\'1\'&&field.type!==\'meta\'}'
552
+ // }
553
+
554
+ // },
555
+ {
556
+ key: 'showWay',
557
+ label: '显示内容',
558
+ type: 'radio',
559
+ options: [{ label: '字段值', value: 'value' }, { label: '记录数', value: 'record' }, { label: '自定义', value: 'el' }],
560
+ defaultValue: 'value',
561
+ showFlag: {
562
+ type: 'meta'
563
+ }
564
+ },
565
+ {
566
+ key: 'statisticsType',
567
+ label: '统计方式',
568
+ type: 'radio',
569
+ code: 'FIELD_STATISTIC_TYPE',
570
+ defaultValue: 'SUM',
571
+ showFlag: {
572
+ showWay: 'statistics',
573
+ type: 'meta'
574
+ }
575
+ },
576
+ {
577
+ key: 'showWay',
578
+ label: '显示内容',
579
+ type: 'radio',
580
+ options: [{ label: '字段值', value: 'value' }, { label: '统计值', value: 'statistics' }],
581
+ defaultValue: 'value',
582
+ showFlag: {
583
+ relationSort: '1',
584
+ dataType: ['num']
585
+ }
586
+ },
587
+ {
588
+ key: 'statisticsType',
589
+ label: '统计方式',
590
+ type: 'radio',
591
+ code: 'FIELD_STATISTIC_TYPE',
592
+ defaultValue: 'SUM',
593
+ showFlag: {
594
+ showWay: 'statistics',
595
+ relationSort: '1',
596
+ dataType: ['num']
597
+ }
598
+ },
599
+ {
600
+ key: 'fields',
601
+ label: '展示字段',
602
+ type: 'field',
603
+ showFlag: {
604
+ // relationSort: '1',
605
+ type: 'meta',
606
+ showWay: ['value', undefined, null]
607
+ }
608
+ },
609
+
610
+ {
611
+ key: 'showEl',
612
+ label: '自定义内容',
613
+ type: 'rule',
614
+ showFlag: {
615
+ showWay: 'el',
616
+ type: 'meta'
617
+ }
618
+ },
619
+ {
620
+ key: 'separator',
621
+ label: '字段分隔符',
622
+ type: 'radio-input',
623
+ options: [{ label: '、', value: '、' }, { label: '/', value: '/' }, { label: ',', value: ',' }],
624
+ defaultValue: '、',
625
+ showFlag: {
626
+ // relationSort: '1'
627
+ type: 'meta'
628
+ }
629
+ },
630
+ {
631
+ key: 'showFieldName',
632
+ label: '是否展示字段名',
633
+ type: 'radio',
634
+ options: [{ label: '是', value: '1' }, { label: '否', value: '0' }],
635
+ defaultValue: '0',
636
+ showFlag: {
637
+ // relationSort: '1'
638
+ type: 'meta'
639
+ }
640
+ },
641
+ {
642
+ key: 'orderFields',
643
+ label: '数据排序',
644
+ type: 'order-field',
645
+ showFlag: {
646
+ relationSort: '1'
647
+ }
648
+ },
649
+ {
650
+ key: 'scopeParams',
651
+ label: '查询范围',
652
+ type: 'scope',
653
+ showFlag: {
654
+ relationSort: '1'
655
+ }
656
+ },
657
+ {
658
+ key: 'recordSeparator',
659
+ label: '记录分隔符',
660
+ type: 'radio-input',
661
+ options: [{ label: '换行', value: '\n' }, { label: '/', value: '/' }, { label: ',', value: ',' }],
662
+ defaultValue: '\n',
663
+ showFlag: {
664
+ relationSort: '1'
665
+ }
666
+ }
667
+ ]
668
+ this.rowFieldOptions = [...this.fieldOptions]
669
+ this.rowFieldOptions.splice(4, 0,
670
+ { key: 'showLabel', label: '显示标题', type: 'radio', options: [{ label: '显示', value: true }, { label: '不显示', value: false }], defaultValue: false },
671
+ { key: 'split', label: '分隔符', type: 'radio', options: [{ label: '竖号', value: ' | ' }, { label: '斜杠', value: ' / ' }, { label: '空格', value: ' ' }], defaultValue: ' | ' },
672
+ { key: 'fontWeight', label: this.$t('whether the bold'), type: 'radio', options: [{ label: this.$t('yes'), value: 'bold' }, { label: this.$t('no'), value: 'normal' }] },
673
+ { key: 'fontSize', label: this.$t('font size'), type: 'num', defaultValue: 14 })
674
+ },
675
+ addCondition (v) {
676
+ const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
677
+ backgroundConditionSet.push({ condition: v, style: null })
678
+ this.config.backgroundConditionSet = backgroundConditionSet
679
+ },
680
+ setConditionBackgroundStyle (item, index) {
681
+ this.backgroundStyleDialog = true
682
+ this.conditionBackgroundStyle = item.style || {}
683
+ this.editConditionIndex = index
684
+ },
685
+ deleteConditionBackgroundStyle (index) {
686
+ const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
687
+ backgroundConditionSet.splice(index, 1)
688
+ this.config.backgroundConditionSet = backgroundConditionSet
689
+ },
690
+ saveConditionBackgroundStyle () {
691
+ const backgroundConditionSet = this.config.backgroundConditionSet ? [...this.config.backgroundConditionSet] : []
692
+ backgroundConditionSet.splice(this.editConditionIndex, 1, { ...backgroundConditionSet[this.editConditionIndex], style: this.conditionBackgroundStyle })
693
+ this.config.backgroundConditionSet = backgroundConditionSet
694
+ this.conditionBackgroundStyle = {}
695
+ this.backgroundStyleDialog = false
696
+ this.editConditionIndex = null
697
+ },
698
+ renderCardBackground () {
699
+ const { backgroundConditionSet = [] } = this.config
700
+ return (
701
+ <div class={['epx-page-designer-setting-style__item', 'epx-visual-entity-list__card-background', { 'epx-page-designer-setting-style__item--unfold': this.unfold }]}>
702
+ <div class="epx-page-designer-setting-style__header">
703
+ <span>
704
+ <i class="epx-page-designer-setting-style__fold-icon el-icon-caret-right" onClick={() => { this.unfold = !this.unfold }}></i>
705
+ <label class="epx-page-designer-setting-style__label" for="">{this.$t('background')}</label>
706
+ </span>
707
+ </div>
708
+ <div class="epx-page-designer-setting-style__content">
709
+ <epx-visual-config-background v-model={this.config.backgroundStyle} class="epx-visual-entity-list__background-style" defaultValue={{
710
+ backgroundSize: 'cover',
711
+ backgroundRepeat: 'no-repeat',
712
+ backgroundPosition: 'center'
713
+ }}></epx-visual-config-background>
714
+ <div class="epx-visual-entity-list__background-conditions">
715
+ {
716
+ backgroundConditionSet.map((item, index) => (
717
+ <div key={index} class="epx-visual-entity-list__background-condition-item">
718
+ <div class="epx-visual-entity-list__background-condition-content">
719
+ <epx-visual-config-scope
720
+ designer={this.designer}
721
+ value={item.condition}
722
+ pageParams={this.pageParams}
723
+ treeFieldStore={this.treeFieldStore}
724
+ componentMetaId={this.componentMetaId || this.pageMetaId}
725
+ scopeConfigs={this.scopeConfigs}
726
+ state='DETAIL'
727
+ />
728
+ <el-button type="primary" link class="epx-visual-entity-list__background-condition-set" onClick={this.setConditionBackgroundStyle.bind(this, item, index)}>
729
+ <i class="el-icon-setting"></i>
730
+ 背景设置
731
+ </el-button>
732
+ </div>
733
+ <i class="epx-visual-entity-list__background-condition-remove el-icon-close" onClick={this.deleteConditionBackgroundStyle.bind(this, index)}></i>
734
+ </div>
735
+ ))
736
+ }
737
+ <epx-visual-config-scope
738
+ designer={this.designer}
739
+ value={this.backgroundCondition}
740
+ pageParams={this.pageParams}
741
+ treeFieldStore={this.treeFieldStore}
742
+ componentMetaId={this.componentMetaId || this.pageMetaId}
743
+ scopeConfigs={this.scopeConfigs}
744
+ operateName="+ 添加动态背景条件"
745
+ onChangeConfigs={v => this.addCondition(v)}
746
+ >
747
+ </epx-visual-config-scope>
748
+ </div>
749
+
750
+ <el-dialog
751
+ title="背景设置"
752
+ modelValue={this.backgroundStyleDialog}
753
+ width="420px"
754
+ show-close={false}
755
+ append-to-body
756
+ destroy-on-close
757
+ center v-slots={{
758
+ footer: () => (<span class="dialog-footer">
759
+ <el-button onClick={() => { this.backgroundStyleDialog = false }}>取 消</el-button>
760
+ <el-button type="primary"onClick={this.saveConditionBackgroundStyle}>确 定</el-button>
761
+ </span>)
762
+ }}>
763
+ {
764
+ this.backgroundStyleDialog &&
765
+ <epx-visual-config-background
766
+ v-model={this.conditionBackgroundStyle}
767
+ defaultValue={{
768
+ backgroundSize: 'cover',
769
+ backgroundRepeat: 'no-repeat'
770
+ }}></epx-visual-config-background>
771
+ }
772
+ </el-dialog>
773
+ </div>
774
+ </div>
775
+ )
776
+ }
777
+ }
778
+ }
779
+ </script>
780
+ <style lang="scss">
781
+ // 2026-09-09:整块从 <style scoped> 搬来。
782
+ // Vue3 的 extends **不继承** __scopeId,本组件有 4 个纯 script 继承者(ClientList /
783
+ // ComponentList / DblogList / MetaList,都没有自己的 <template>、也没转写 __scopeId)
784
+ // ⇒ 它们渲染出的 DOM 上一个 data-v-* 都没有,这一簇规则整块静默失效:卡片背景配置项的
785
+ // 负边距丢失、条件列表没有分隔线与 flex 布局。
786
+ //
787
+ // ⚠️ 三个搬迁要点,别改回去:
788
+ // 1) 类名必须带 BEM 前缀——`.background-style` / `.background-condition__*` 都是通用名,
789
+ // 裸着放进无 scoped 块就是全局污染。
790
+ // 2) 原文的 `:deep(...)` 全部去掉了:`:deep()` 是 scoped 专用的穿透语法,只有 scoped 块
791
+ // 才会被编译器改写;留在无 scoped 块里会原样输出成浏览器不认识的伪类 ⇒ 规则照样失效。
792
+ // 无 scoped 下嵌在块内本身就是后代选择器,语义等价。
793
+ // 3) 这簇 DOM 挂在 `epx-page-designer-setting-style__item` 上,**不在** .epx-visual-entity-list
794
+ // 的后代里。能这么写是因为本仓 e() 在不含 modifier / .is- / 伪类时走 @at-root,生成的是
795
+ // 独立类名 `.epx-x__y` 而不是后代选择器(见 theme/utils/mixins.scss)。
796
+ //
797
+ // 原 `.background-condititon`(三个 t)是笔误,与 `.background-condition__*` 并非同名;
798
+ // 类名反正要整体重命名,就没把笔误固化进 BEM 名,统一成 conditions,JSX 同步改。
799
+ @include b(visual-entity-list) {
800
+ @include e(card-background) {
801
+ margin: 0 -10px;
802
+
803
+ .epx-page-designer-setting-style__subitem {
804
+ margin: 20px 0;
805
+ }
806
+ .epx-page-designer-setting-style__content {
807
+ background: none;
808
+ padding: 0;
809
+ }
810
+ }
811
+ @include e(background-style) {
812
+ padding: 10px 10px 10px 28px;
813
+ background: #F5F7FA;
814
+ }
815
+ @include e(background-conditions) {
816
+ padding: 10px;
817
+ }
818
+ @include e(background-condition-item) {
819
+ display: flex;
820
+ padding: 10px 0;
821
+ border-bottom: 1px solid #DCDCDC;
822
+ }
823
+ @include e(background-condition-content) {
824
+ flex: 1;
825
+ }
826
+ @include e(background-condition-set) {
827
+ margin: 0;
828
+ i {
829
+ margin-right: 4px;
830
+ }
831
+ }
832
+ @include e(background-condition-remove) {
833
+ font-size: var(--epx-font-size-l);
834
+ cursor: pointer;
835
+ margin-top: 4px;
836
+ }
837
+ }
838
+ </style>