sohelp-eleplus 1.1.18 → 1.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,28 @@
1
1
  export default {
2
- id: 'sohelp-grid',
2
+ showFooter: false,
3
+ round: true,
4
+ border: true,
5
+ stripe: true,
6
+ loading: false,
7
+ minHeight: 300,
8
+ maxHeight: '100%',
9
+ size: 'mini',
10
+ params: {},
11
+ columnConfig: {
12
+ resizable: true,
13
+ drag: false
14
+ },
3
15
  customConfig: {
16
+ //默认不会将列设置保存到本地存储中
17
+ storage: false,
4
18
  placement: 'top-right' // 自定义列工具栏位置
5
19
  },
6
20
  rowConfig: {
21
+ keyField: 'id',
7
22
  useKey: true, //sortable 排序
8
- sHover: true,
23
+ isHover: true,
9
24
  isCurrent: true,
10
- resizable: true,
25
+ resizable: false,
11
26
  drag: true
12
27
  },
13
28
  rowDragConfig: {
@@ -49,6 +64,13 @@ export default {
49
64
  range: true,
50
65
  reserve: true
51
66
  },
67
+ radioConfig: {
68
+ strict: false,
69
+ checkRowKey: 'id',
70
+ highlight: true,
71
+ reserve: true,
72
+ trigger: 'cell' // 关键配置:点击行触发选中
73
+ },
52
74
  scrollX: {
53
75
  gt: 0,
54
76
  //自动启用纵向虚拟滚动
@@ -59,15 +81,6 @@ export default {
59
81
  //自动启用纵向虚拟滚动
60
82
  enabled: true
61
83
  },
62
- showFooter: false,
63
- round: true,
64
- border: true,
65
- stripe: false,
66
- loading: false,
67
- minHeight: 300,
68
- maxHeight: '100%',
69
- size: 'mini',
70
- params: {},
71
84
  pagerConfig: {
72
85
  enabled: true,
73
86
  total: 0,
@@ -77,18 +90,18 @@ export default {
77
90
  },
78
91
  customConfig: {
79
92
  immediate: false,
93
+ isCurrent: true,
94
+ resizable: true,
80
95
  storage: {
81
96
  visible: true, // 保存列显示/隐藏状态
82
97
  resizable: true, // 保存列宽调整
83
98
  sort: true, // 保存列排序
84
99
  fixed: true
100
+ },
101
+ slots: {
102
+ header: 'setting'
85
103
  }
86
104
  },
87
- columnConfig: {
88
- isCurrent: true,
89
- resizable: true
90
- },
91
-
92
105
  sortConfig: {
93
106
  remote: true
94
107
  },
@@ -2,18 +2,18 @@ export default {
2
2
  /**网格列表配置ID*/
3
3
  refid: {
4
4
  type: String,
5
- defaultValue: '',
5
+ default: '',
6
6
  required: true
7
7
  },
8
8
  /**自动加载数据*/
9
9
  autoLoad: {
10
10
  type: Boolean,
11
- defaultValue: true
11
+ default: true
12
12
  },
13
13
  /**数据源URL**/
14
14
  url: {
15
15
  type: String,
16
- defaultValue: ''
16
+ default: ''
17
17
  },
18
18
  /**允许行拖动*/
19
19
  rowDrag: Boolean,
@@ -1,9 +1,9 @@
1
- import { reactive, ref } from "vue";
2
- import _DefaultGridOptions from "../js/DefaultGridOptions";
3
- import { moduleCache } from "../../cache/ModuleCache";
4
- import { usePermission } from "@/utils/use-permission";
5
- import { useMobile } from "@/utils/use-mobile";
6
- import { useI18n } from "vue-i18n";
1
+ import { reactive, ref } from 'vue';
2
+ import _DefaultGridOptions from '../js/DefaultGridOptions';
3
+ import { moduleCache } from '../../cache/ModuleCache';
4
+ import { usePermission } from '@/utils/use-permission';
5
+ import { useMobile } from '@/utils/use-mobile';
6
+ import { useI18n } from 'vue-i18n';
7
7
 
8
8
  /**
9
9
  * 深拷贝
@@ -19,27 +19,27 @@ function createDynamicStyle(styleConfigs = [], isCell = true) {
19
19
  // 预编译条件表达式为函数
20
20
  const compiledConfigs = styleConfigs.map((config) => ({
21
21
  ...config,
22
- conditionFn: new Function("row", `return ${config.condition}`)
22
+ conditionFn: new Function('row', `return ${config.condition}`)
23
23
  }));
24
24
 
25
- return function({ row, column }) {
25
+ return function ({ row, column }) {
26
26
  const _config = isCell ? compiledConfigs.filter((c) => c.name === column.field) : compiledConfigs;
27
27
  if (!_config || !_config.length) return null;
28
28
  try {
29
29
  for (const config of _config) {
30
- const conditionFn = new Function("row", `return ${config.condition}`);
30
+ const conditionFn = new Function('row', `return ${config.condition}`);
31
31
  if (conditionFn(row)) {
32
32
  return {
33
33
  color: config.fontColor,
34
34
  backgroundColor: config.bgColor,
35
- fontWeight: config?.bold ? "bold" : "",
36
- fontStyle: config.italic ? "italic" : "",
37
- textDecoration: config.strikethrough ? "line-through" : config.underline ? "underline" : ""
35
+ fontWeight: config?.bold ? 'bold' : '',
36
+ fontStyle: config.italic ? 'italic' : '',
37
+ textDecoration: config.strikethrough ? 'line-through' : config.underline ? 'underline' : ''
38
38
  };
39
39
  }
40
40
  }
41
41
  } catch (e) {
42
- console.error("条件解析错误:", e);
42
+ console.error('条件解析错误:', e);
43
43
  }
44
44
  return null;
45
45
  };
@@ -64,8 +64,8 @@ const switchVxeProperty = (property, sortList, f, formulaMap) => {
64
64
  query: property.query,
65
65
  width: property.width || 120,
66
66
  type: property.editor || property.type,
67
- align: property.align || "left",
68
- titleSuffix: property.tooltip ? { content: property.tooltip, placement: "top" } : "",
67
+ align: property.align || 'left',
68
+ titleSuffix: property.tooltip ? { content: property.tooltip, placement: 'top' } : '',
69
69
 
70
70
  showOverflow: true,
71
71
  editRender: {
@@ -75,13 +75,13 @@ const switchVxeProperty = (property, sortList, f, formulaMap) => {
75
75
  },
76
76
  fixed: !property.lock ? false : property.lockAlign,
77
77
  slots: {
78
- default: "default_" + property.name,
79
- header: "header_" + property.name
78
+ default: 'default_' + property.name,
79
+ header: 'header_' + property.name
80
80
  },
81
81
  contentRender: {
82
82
  name: property.render,
83
83
  props: property.renderParam || {},
84
- event: "event"
84
+ event: 'event'
85
85
  }
86
86
  };
87
87
 
@@ -90,16 +90,22 @@ const switchVxeProperty = (property, sortList, f, formulaMap) => {
90
90
  }
91
91
 
92
92
  if (property.dict) {
93
- editor.editRender["code"] = property.dict;
93
+ editor.editRender['code'] = property.dict;
94
94
  }
95
95
 
96
- // 编辑
96
+ // 取默认显示值
97
+ if (property.type === 'RELATION' && editor.labelField === '') {
98
+ const fields = property.relationList?.split(',');
99
+ editor.labelField = fields.includes('id') && fields.length > 1 ? fields[1] : fields[0];
100
+ }
101
+
102
+ // 自定义编辑插槽
97
103
  if (property.edit) {
98
- editor.slots.edit = "edit_" + property.name;
104
+ editor.slots.edit = 'edit_' + property.name;
99
105
  }
100
106
 
101
107
  if (
102
- ["SohelpImageUpload", "SohelpFileUpload", "SohelpRate", "SohelpSwitch", "SohelpProcess"].includes(property.editor)
108
+ ['SohelpImageUpload', 'SohelpFileUpload', 'SohelpRate', 'SohelpSwitch', 'SohelpProcess'].includes(property.editor)
103
109
  ) {
104
110
  delete editor.slots.edit; //不渲染编辑
105
111
  editor.editRender.enabled = false;
@@ -114,16 +120,16 @@ const switchVxeProperty = (property, sortList, f, formulaMap) => {
114
120
  const isSummary = f.find((item) => item.field === property.name);
115
121
 
116
122
  if (isSummary) {
117
- editor.slots["footer"] = "footer_" + property.name;
123
+ editor.slots['footer'] = 'footer_' + property.name;
118
124
  }
119
125
 
120
126
  // 排序
121
127
  if (sortList?.includes(property.name)) {
122
- editor["sortable"] = true;
128
+ editor['sortable'] = true;
123
129
  }
124
130
 
125
- if (property.name === "id") {
126
- editor["width"] = 150;
131
+ if (property.name === 'id') {
132
+ editor['width'] = 150;
127
133
  }
128
134
 
129
135
  return editor;
@@ -133,11 +139,11 @@ const switchVxeProperty = (property, sortList, f, formulaMap) => {
133
139
  * 筛选配置
134
140
  */
135
141
  const switchFilterConfig = (editor) => {
136
- editor.filters = [{ data: "", checked: false }];
142
+ editor.filters = [{ data: '', checked: false }];
137
143
  editor.filterRender = {};
138
144
  editor.slots = {
139
145
  ...editor.slots,
140
- filter: "filter_" + editor.field
146
+ filter: 'filter_' + editor.field
141
147
  };
142
148
  };
143
149
 
@@ -162,7 +168,7 @@ const filterFieldsByProperties = (_data) => {
162
168
  });
163
169
 
164
170
  data.filter.keywords = filterArray(data.filter.keywords);
165
- data.filter.field = filterArray(data.filter.field, "name");
171
+ data.filter.field = filterArray(data.filter.field, 'name');
166
172
 
167
173
  //过滤掉不在列表中的sort属性
168
174
  data.filter.sort = filterArray(data.filter.sort.filter((item) => data.filter.field.some((f) => f.name === item)));
@@ -174,14 +180,14 @@ const filterFieldsByProperties = (_data) => {
174
180
  * 工具栏默认图标
175
181
  */
176
182
  const defaultIcons = {
177
- "crud.edit": "vxe-icon-edit",
178
- "crud.delete": "vxe-icon-delete",
179
- "crud.create": "vxe-icon-add",
180
- "crud.save": "vxe-icon-save",
181
- "crud.view": "vxe-icon-eye-fill",
182
- "workflow.submit": "vxe-icon-success-circle",
183
- "workflow.view": "vxe-icon-file-txt",
184
- "report.print": "vxe-icon-print"
183
+ 'crud.edit': 'vxe-icon-edit',
184
+ 'crud.delete': 'vxe-icon-delete',
185
+ 'crud.create': 'vxe-icon-add',
186
+ 'crud.save': 'vxe-icon-save',
187
+ 'crud.view': 'vxe-icon-eye-fill',
188
+ 'workflow.submit': 'vxe-icon-success-circle',
189
+ 'workflow.view': 'vxe-icon-file-txt',
190
+ 'report.print': 'vxe-icon-print'
185
191
  };
186
192
 
187
193
  /**
@@ -203,11 +209,11 @@ const getToolbarsButtons = (data) => {
203
209
  const formatterButton = (arr, type) => {
204
210
  return arr.map((item) => {
205
211
  let params = {};
206
- if (item.params && typeof item.params === "string") {
212
+ if (item.params && typeof item.params === 'string') {
207
213
  try {
208
214
  params = JSON.parse(item.params);
209
215
  } catch (e) {
210
- console.error("FormatterButton Error:", e);
216
+ console.error('FormatterButton Error:', e);
211
217
  params = {};
212
218
  }
213
219
  }
@@ -231,16 +237,16 @@ const getToolbarsButtons = (data) => {
231
237
  let arr = [...formatterButton(common)];
232
238
  if (more.length > 0) {
233
239
  arr.push({
234
- code: "more",
235
- name: "更多操作",
240
+ code: 'more',
241
+ name: '更多操作',
236
242
  dropdowns: formatterButton(more)
237
243
  });
238
244
  }
239
245
  if (batch.length > 0) {
240
246
  arr.push({
241
- code: "batchMore",
242
- name: "批量操作",
243
- dropdowns: formatterButton(batch, "batch"),
247
+ code: 'batchMore',
248
+ name: '批量操作',
249
+ dropdowns: formatterButton(batch, 'batch'),
244
250
  disabled: true
245
251
  });
246
252
  }
@@ -282,9 +288,9 @@ export function useSohelpGridConfig() {
282
288
  * 初始化商邦网格列表配置
283
289
  */
284
290
  const initial = async (isGridConfig, refid) => {
285
- if (!refid) throw new Error("配置列表请配置地址!");
291
+ if (!refid) throw new Error('配置列表请配置地址!');
286
292
  let _refid = refid;
287
- if (_refid.indexOf("!") === -1) _refid = refid + "!default";
293
+ if (_refid.indexOf('!') === -1) _refid = refid + '!default';
288
294
 
289
295
  isConfigInitialized.value = false;
290
296
  const permission = usePermission();
@@ -296,7 +302,7 @@ export function useSohelpGridConfig() {
296
302
  const config = isGridConfig ? await moduleCache.getGrid(_refid) : await moduleCache.getEntityGrid(_refid);
297
303
 
298
304
  if (!config) {
299
- throw new Error(_refid + " : 没有发现网格列表配置!");
305
+ throw new Error(_refid + ' : 没有发现网格列表配置!');
300
306
  }
301
307
 
302
308
  try {
@@ -305,11 +311,11 @@ export function useSohelpGridConfig() {
305
311
  propertiesMap,
306
312
  (SohelpConfig?.properties || []).reduce((acc, cur) => {
307
313
  let param = {};
308
- if (cur?.editorParam && typeof cur.editorParam === "string") {
314
+ if (cur?.editorParam && typeof cur.editorParam === 'string') {
309
315
  try {
310
316
  param = JSON.parse(cur.editorParam);
311
317
  } catch (e) {
312
- console.error("解析editorParam失败:", e);
318
+ console.error('解析editorParam失败:', e);
313
319
  }
314
320
  }
315
321
  acc[cur.name] = { ...cur, editorParam: param };
@@ -337,14 +343,14 @@ export function useSohelpGridConfig() {
337
343
  DefaultGridOptions.toolbarConfig.buttons = buttons;
338
344
  // 更多下拉菜单索引
339
345
  batchButtonsIndex = buttons.reduce((acc, curr, index) => {
340
- if (curr.code === "batchMore") acc.push(index);
346
+ if (curr.code === 'batchMore') acc.push(index);
341
347
  return acc;
342
348
  }, []);
343
349
 
344
350
  //把标题转成国际化
345
351
  buttons.forEach((item) => {
346
- const code = item.code.replace(".", "-");
347
- const i18nKey = item.i18n === "" || code !== "custom" ? "grid.toolbar." + code : item.i18n;
352
+ const code = item.code.replace('.', '-');
353
+ const i18nKey = item.i18n === '' || code !== 'custom' ? 'grid.toolbar.' + code : item.i18n;
348
354
  if (i18nKey) {
349
355
  const i18n = t(i18nKey);
350
356
  item.name = i18n ? i18n : item.name;
@@ -353,38 +359,60 @@ export function useSohelpGridConfig() {
353
359
  }
354
360
 
355
361
  //初始化属性列表配置
356
- let columns = [
357
- {
358
- field: "_checkbox",
359
- title: "",
360
- fixed: mobile.value ? false : "left",
361
- type: "checkbox",
362
- align: "center",
362
+ let columns = [];
363
+
364
+ //是否支持选择
365
+ if (config?.selectionType === 'checkbox') {
366
+ columns.push({
367
+ field: '_checkbox',
368
+ title: '',
369
+ fixed: mobile.value ? false : 'left',
370
+ type: 'checkbox',
371
+ align: 'center',
363
372
  width: 40
364
- },
365
- {
366
- field: "_seq",
367
- type: "seq",
368
- title: "#",
369
- fixed: mobile.value ? false : "left",
370
- align: "center",
373
+ });
374
+ }
375
+
376
+ if (config?.selectionType === 'radio') {
377
+ columns.push({
378
+ field: '_radio',
379
+ title: '',
380
+ fixed: mobile.value ? false : 'left',
381
+ type: 'radio',
382
+ align: 'center',
371
383
  width: 40
372
- }
373
- ];
384
+ });
385
+ }
386
+
387
+ //是否显示行号
388
+ if (config?.rowNumber) {
389
+ columns.push({
390
+ field: '_seq',
391
+ type: 'seq',
392
+ title: '#',
393
+ fixed: mobile.value ? false : 'left',
394
+ align: 'center',
395
+ width: 40
396
+ });
397
+ }
374
398
 
375
- const isRowDrag = config.rowDrag;
376
399
  //是否支持拖动
377
- if (isRowDrag) {
400
+ if (config?.rowDrag) {
378
401
  columns.unshift({
379
- title: "",
380
- fixed: mobile.value ? false : "left",
402
+ title: '',
403
+ fixed: mobile.value ? false : 'left',
381
404
  width: 40,
382
- align: "center",
405
+ align: 'center',
383
406
  dragSort: true,
384
- field: "_drag"
407
+ field: '_drag'
385
408
  });
386
409
  }
387
410
 
411
+ //列拖动
412
+ if (config?.columnDrag) {
413
+ DefaultGridOptions.columnConfig.drag = true;
414
+ }
415
+
388
416
  const requireData = {};
389
417
  //商邦列转换成Vxe列
390
418
  if (SohelpConfig.properties?.length > 0) {
@@ -396,10 +424,10 @@ export function useSohelpGridConfig() {
396
424
  row.visible = SohelpConfig.list.includes(item.name);
397
425
  row.fixed = mobile.value ? false : row.fixed;
398
426
  // 添加操作栏插槽
399
- if (item.name === "_operation") {
427
+ if (item.name === '_operation') {
400
428
  row.visible = true;
401
429
  row.slots = {
402
- default: "_operation"
430
+ default: '_operation'
403
431
  };
404
432
  }
405
433
 
@@ -410,22 +438,22 @@ export function useSohelpGridConfig() {
410
438
  requireData[item.name] = [
411
439
  {
412
440
  required: true,
413
- message: row.title + "不能为空"
441
+ message: row.title + '不能为空'
414
442
  }
415
443
  ];
416
444
  }
417
445
  });
418
446
 
419
447
  //没有工具栏则不显示操作拦
420
- if (config?.operationToolbars?.length == 0) {
421
- columns = columns.filter((item) => item.field != "_operation");
448
+ if (config?.operations?.length == 0) {
449
+ columns = columns.filter((item) => item.field != '_operation');
422
450
  }
423
451
 
424
452
  //将columns按照fields排序
425
453
  const sortColumns = columns
426
454
  .sort((a, b) => {
427
- if (a.field === "_operation") return 1;
428
- if (b.field === "_operation") return -1;
455
+ if (a.field === '_operation') return 1;
456
+ if (b.field === '_operation') return -1;
429
457
  return config.list.indexOf(a.field) - config.list.indexOf(b.field);
430
458
  })
431
459
  .sort((a, b) => {
@@ -434,8 +462,8 @@ export function useSohelpGridConfig() {
434
462
 
435
463
  //_operation列安排最后一列
436
464
  DefaultGridOptions.columns = [
437
- ...sortColumns.filter((col) => col.field !== "_operation"),
438
- ...sortColumns.filter((col) => col.field === "_operation")
465
+ ...sortColumns.filter((col) => col.field !== '_operation'),
466
+ ...sortColumns.filter((col) => col.field === '_operation')
439
467
  ];
440
468
  DefaultGridOptions.editRules = { ...requireData };
441
469
  }
@@ -458,7 +486,7 @@ export function useSohelpGridConfig() {
458
486
 
459
487
  // 拦截编辑
460
488
  DefaultGridOptions.editConfig.beforeEditMethod = ({ row, column }) => {
461
- if (column.type === "SohelpTextarea") {
489
+ if (column.type === 'SohelpTextarea') {
462
490
  return false;
463
491
  }
464
492
  return true;
@@ -470,8 +498,8 @@ export function useSohelpGridConfig() {
470
498
 
471
499
  // 行列样式
472
500
  if (config.colors && config.colors.length > 0) {
473
- const rowData = config.colors.filter((item) => item.type !== "c");
474
- const cellData = config.colors.filter((item) => item.type === "c");
501
+ const rowData = config.colors.filter((item) => item.type !== 'c');
502
+ const cellData = config.colors.filter((item) => item.type === 'c');
475
503
  if (rowData.length > 0) {
476
504
  DefaultGridOptions.rowStyle = createDynamicRowStyle(rowData);
477
505
  } else {
@@ -482,21 +510,69 @@ export function useSohelpGridConfig() {
482
510
  }
483
511
  }
484
512
  isConfigInitialized.value = true;
513
+
514
+ //序号列配置
515
+ DefaultGridOptions.seqConfig = {
516
+ seqMethod: ({ rowIndex }) => {
517
+ const { pageSize, currentPage } = DefaultGridOptions.pagerConfig;
518
+ return (currentPage - 1) * pageSize + rowIndex + 1;
519
+ }
520
+ };
521
+
485
522
  //转化初始化其他参数...
486
523
  } catch (error) {
487
524
  throw error; //重新抛出错误,以便调用者可以处理它
488
525
  }
489
526
 
527
+ const operationsButtons = getOperationToolbars();
490
528
  return {
491
529
  gridOptions: DefaultGridOptions,
492
530
  sohelpConfig: SohelpConfig,
493
531
  propertiesMap: propertiesMap,
494
532
  batchButtonsIndex: batchButtonsIndex,
495
533
  footerData: footerData,
496
- formulaMap: formulaMap
534
+ formulaMap: formulaMap,
535
+ operationsButtons: operationsButtons
497
536
  };
498
537
  };
499
538
 
539
+ // 操作栏按钮分类
540
+ const getOperationToolbars = () => {
541
+ const buttonsMap = {};
542
+ const permission = usePermission();
543
+ SohelpConfig.operations
544
+ ?.filter((f) => !f.authority || permission.hasPermission(f.authority))
545
+ .map((button) => {
546
+ const type = button.buttonType || 'common';
547
+ const code = button.type === 'custom' ? button.id : button.type;
548
+ if (!buttonsMap[type]) {
549
+ buttonsMap[type] = [];
550
+ }
551
+ const title = button.type === 'custom' ? button.title : t('grid.toolbar.' + button.type?.replaceAll('.', '-'));
552
+ let params = button.params || {};
553
+ if (button.params && typeof button.params === 'string') {
554
+ try {
555
+ params = JSON.parse(button.params);
556
+ } catch (e) {
557
+ params = {};
558
+ EleMessage.error('button.params配置JSON参数格式错误');
559
+ }
560
+ }
561
+ buttonsMap[type].push({
562
+ title: title || button.title,
563
+ id: button.id,
564
+ code: code,
565
+ handler: button.handler,
566
+ icon: button.iconCls,
567
+ params: params,
568
+ refid: button.refid,
569
+ openType: button.openType,
570
+ render: button.render
571
+ });
572
+ });
573
+ return buttonsMap;
574
+ };
575
+
500
576
  /**
501
577
  * 配置是否加载完成
502
578
  */
@@ -15,7 +15,7 @@
15
15
  </template>
16
16
 
17
17
  <el-option style="height: auto; padding: 0; height: 262px; overflow: hidden; align-items: flex-start">
18
- <sohelp-vxe-grid
18
+ <sohelp-grid-view
19
19
  :refid="refid"
20
20
  ref="tableRef"
21
21
  class="vxe-grid-main"
@@ -25,7 +25,7 @@
25
25
  v-model:data="selectedData"
26
26
  :url="url"
27
27
  >
28
- </sohelp-vxe-grid>
28
+ </sohelp-grid-view>
29
29
  </el-option>
30
30
 
31
31
  <template #footer>