br-dionysus 1.17.7 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +73 -24
  2. package/attributes.json +1 -1
  3. package/cypress/component/MSelect.cy.ts +0 -1
  4. package/cypress/component/MSelectTable.cy.ts +538 -0
  5. package/cypress/component/MSelectV2.cy.ts +0 -1
  6. package/cypress/component/MTable.cy.ts +123 -0
  7. package/cypress/e2e/1-getting-started/todo.cy.js +143 -0
  8. package/cypress/e2e/2-advanced-examples/actions.cy.js +321 -0
  9. package/cypress/e2e/2-advanced-examples/aliasing.cy.js +39 -0
  10. package/cypress/e2e/2-advanced-examples/assertions.cy.js +176 -0
  11. package/cypress/e2e/2-advanced-examples/connectors.cy.js +98 -0
  12. package/cypress/e2e/2-advanced-examples/cookies.cy.js +118 -0
  13. package/cypress/e2e/2-advanced-examples/cypress_api.cy.js +184 -0
  14. package/cypress/e2e/2-advanced-examples/files.cy.js +85 -0
  15. package/cypress/e2e/2-advanced-examples/location.cy.js +32 -0
  16. package/cypress/e2e/2-advanced-examples/misc.cy.js +98 -0
  17. package/cypress/e2e/2-advanced-examples/navigation.cy.js +55 -0
  18. package/cypress/e2e/2-advanced-examples/network_requests.cy.js +163 -0
  19. package/cypress/e2e/2-advanced-examples/querying.cy.js +114 -0
  20. package/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js +204 -0
  21. package/cypress/e2e/2-advanced-examples/storage.cy.js +117 -0
  22. package/cypress/e2e/2-advanced-examples/traversal.cy.js +121 -0
  23. package/cypress/e2e/2-advanced-examples/utilities.cy.js +107 -0
  24. package/cypress/e2e/2-advanced-examples/viewport.cy.js +58 -0
  25. package/cypress/e2e/2-advanced-examples/waiting.cy.js +30 -0
  26. package/cypress/e2e/2-advanced-examples/window.cy.js +22 -0
  27. package/cypress/e2e/toolSlotsToData.cy.ts +127 -0
  28. package/cypress/e2e/toolUniqueByKey.cy.ts +79 -0
  29. package/cypress/support/component.ts +20 -1
  30. package/cypress.config.ts +1 -0
  31. package/dist/br-dionysus.es.js +5872 -5696
  32. package/dist/br-dionysus.umd.js +6 -5
  33. package/dist/cypress/component/MInputNumber.cy.d.ts +0 -0
  34. package/dist/cypress/component/MSelect.cy.d.ts +1 -0
  35. package/dist/cypress/component/MSelectTable.cy.d.ts +1 -0
  36. package/dist/cypress/component/MSelectV2.cy.d.ts +1 -0
  37. package/dist/cypress/component/MTable.cy.d.ts +1 -0
  38. package/dist/cypress/e2e/spec.cy.d.ts +0 -0
  39. package/dist/cypress/e2e/toolCheckType.cy.d.ts +1 -0
  40. package/dist/cypress/e2e/toolCompareStructures.cy.d.ts +1 -0
  41. package/dist/cypress/e2e/toolCreateHash.cy.d.ts +1 -0
  42. package/dist/cypress/e2e/toolMoneyFormat.cy.d.ts +1 -0
  43. package/dist/cypress/e2e/toolSlotsToData.cy.d.ts +1 -0
  44. package/dist/cypress/e2e/toolUniqueByKey.cy.d.ts +1 -0
  45. package/dist/cypress/support/commands.d.ts +0 -0
  46. package/dist/cypress/support/component.d.ts +9 -0
  47. package/dist/cypress/support/e2e.d.ts +0 -0
  48. package/dist/index.css +1 -1
  49. package/dist/packages/Hook/usePackageConfig/usePackageConfig.d.ts +2 -0
  50. package/dist/packages/MTable/src/MTable.vue.d.ts +49 -15
  51. package/dist/packages/MTable/src/token.d.ts +13 -0
  52. package/dist/packages/MTableColumn/src/MTableColumn.vue.d.ts +9 -14
  53. package/dist/packages/Tool/globalEvents/globalEvents.d.ts +26 -0
  54. package/dist/packages/index.d.ts +2 -0
  55. package/package.json +2 -2
  56. package/packages/Hook/usePackageConfig/usePackageConfig.ts +6 -4
  57. package/packages/Hook/useZIndex/useGlobalZIndex.ts +1 -1
  58. package/packages/MDialog/src/MDialog.vue +8 -8
  59. package/packages/MSelectTable/docs/README.md +1 -0
  60. package/packages/MSelectTable/src/MSelectTable.vue +6 -6
  61. package/packages/MTable/docs/DemoTest4.vue +0 -1
  62. package/packages/MTable/docs/DemoTest6.vue +122 -0
  63. package/packages/MTable/docs/DemoTest7.vue +138 -0
  64. package/packages/MTable/docs/README.md +10 -10
  65. package/packages/MTable/docs/demo.vue +10 -2
  66. package/packages/MTable/src/MBatchEdit.vue +1 -0
  67. package/packages/MTable/src/MTable.vue +254 -38
  68. package/packages/MTable/src/token.ts +14 -1
  69. package/packages/MTableColumn/docs/README.md +1 -0
  70. package/packages/MTableColumn/src/MTableColumn.vue +98 -24
  71. package/packages/Tool/globalEvents/README.md +23 -0
  72. package/packages/Tool/globalEvents/globalEvents.ts +79 -0
  73. package/packages/index.ts +2 -0
  74. package/packages/typings/global.d.ts +6 -2
  75. package/tags.json +1 -1
  76. package/tsconfig.json +3 -1
  77. package/web-types.json +1 -1
  78. package/cypress/screenshots/MSelectTable.cy.ts//344/270/213/346/213/211/350/241/250/346/240/274/351/200/211/346/213/251/345/231/250/347/273/204/344/273/266MSelectTable -- /346/265/213/350/257/225/345/215/225/351/200/211/345/212/237/350/203/275 (failed).png +0 -0
  79. package/cypress/screenshots/MSelectTable.cy.ts//344/270/213/346/213/211/350/241/250/346/240/274/351/200/211/346/213/251/345/231/250/347/273/204/344/273/266MSelectTable -- /346/265/213/350/257/225/345/237/272/347/241/200/345/212/237/350/203/275 (failed).png +0 -0
  80. package/cypress/screenshots/MSelectTable.cy.ts//344/270/213/346/213/211/350/241/250/346/240/274/351/200/211/346/213/251/345/231/250/347/273/204/344/273/266MSelectTable -- /346/265/213/350/257/225/345/244/232/351/200/211/345/212/237/350/203/275 (failed).png +0 -0
  81. package/cypress/screenshots/MSelectTable.cy.ts//344/270/213/346/213/211/350/241/250/346/240/274/351/200/211/346/213/251/345/231/250/347/273/204/344/273/266MSelectTable -- /346/265/213/350/257/225/350/277/234/347/250/213/346/220/234/347/264/242/345/212/237/350/203/275 (failed).png +0 -0
  82. package/src/global.d.ts +0 -5
@@ -2,18 +2,22 @@
2
2
  <div
3
3
  class="br-m-table-box"
4
4
  :data-is-expand="Boolean(props.expandProp)"
5
+ tabindex="0"
6
+ @keydown="onKeydown"
5
7
  >
6
8
  <el-table
7
9
  ref="tableRef"
8
- v-bind="$attrs"
10
+ v-bind="attrs"
9
11
  :size="props.size"
10
12
  :data="tableData"
11
13
  :expandRowKeys="expandRowKeys"
12
14
  :rowKey="props.rowKey"
13
15
  :cellStyle="cellStyle"
16
+ :summaryMethod="props.circleTotal ? summaryMethodFun : props.summaryMethod"
14
17
  @paste="paste"
15
18
  @cellClick="cellClick"
16
19
  @expandChange="expandChange"
20
+ @cellMouseEnter="cellMouseEnter"
17
21
  >
18
22
  <slot name="default"></slot>
19
23
  <slot name="append"></slot>
@@ -29,11 +33,12 @@
29
33
  </template>
30
34
 
31
35
  <script setup lang="ts">
32
- import { ref, onMounted, computed, useSlots, watch, provide, reactive, getCurrentInstance } from 'vue'
36
+ import { ref, onMounted, computed, useSlots, watch, provide, reactive, getCurrentInstance, onUnmounted, useAttrs } from 'vue'
33
37
  import checkType from '../../Tool/checkType/checkType'
34
38
  import { TableConfig } from './../../Hook/useTableConfig/useTableConfig'
35
39
  import { tableKey } from './token'
36
40
  import slotsToData, { SlotsToDataReturnItem } from './../../Tool/slotsToData/slotsToData'
41
+ import globalEvents from '../../Tool/globalEvents/globalEvents'
37
42
 
38
43
  interface FilterValue {
39
44
  [key: string]: Array<string | number>;
@@ -55,10 +60,14 @@ const props = withDefaults(defineProps<{
55
60
  rowKey?: Function | string;
56
61
  /** 表格配置key */
57
62
  tableConfigKey?: string;
58
- /** 显示单元格选中状态 */
59
- showSelectionCellStatus?: boolean;
60
- /** 选中列(必须showSelection为true) */
61
- selectionCell?: string;
63
+ /** 选中列 */
64
+ selectionCell?: string | number | symbol;
65
+ // /** 是否在表尾显示合计行 */
66
+ // showSummary?: boolean;
67
+ /** 自定义的合计计算方法 */
68
+ summaryMethod?:((data: { columns: any[], data: any[] }) => string[]) | null;
69
+ /** 是否圈选合计 */
70
+ circleTotal?: boolean;
62
71
  }>(), {
63
72
  size: '',
64
73
  sole: 'key',
@@ -69,16 +78,76 @@ const props = withDefaults(defineProps<{
69
78
  expandRowKeys: () => [],
70
79
  rowKey: '',
71
80
  tableConfigKey: '',
72
- showSelectionCellStatus: false,
73
- selectionCell: ''
81
+ selectionCell: '',
82
+ // showSummary: false,
83
+ summaryMethod: null,
84
+ circleTotal: true
74
85
  })
75
86
 
76
87
  const slots = useSlots()
77
88
 
89
+ const attrs = useAttrs()
90
+
91
+ const summaryMethodFun = (param: { columns: any[], data: Record<any, any>[] }): string[] => {
92
+ const value: string[] = []
93
+ const tableTitle: TableTitle[] = getTableTitle()
94
+ const tableTitleMap: Record<string, TableTitle> = {}
95
+ tableTitle.forEach(item => {
96
+ tableTitleMap[item.prop as string] = item
97
+ })
98
+
99
+ // 是否存在圈选
100
+ const isExistRange = selectionArea.startX !== null && selectionArea.startY !== null && selectionArea.endX !== null && selectionArea.endY !== null
101
+ if (!isExistRange) {
102
+ param.columns.forEach(column => {
103
+ let qty: number | string = ''
104
+ const isSummary = tableTitleMap[column.property]?.isSummary ?? true
105
+
106
+ param.data.forEach(item => {
107
+ const isNumber = checkType(item[column.property]).isNumber()
108
+ if (isNumber && isSummary) qty = (qty || 0) + item[column.property]
109
+ })
110
+
111
+ if (!column.property) value.push((attrs as any)?.sumText ?? '合')
112
+ else if (column.property === 'sn') value.push('')
113
+ else value.push(qty)
114
+ })
115
+ return value
116
+ }
117
+
118
+ const startX: number = (selectionArea.startX || 0) > (selectionArea.endX || 0) ? (selectionArea.endX || 0) : (selectionArea.startX || 0)
119
+ const startY: number = (selectionArea.startY || 0) > (selectionArea.endY || 0) ? (selectionArea.endY || 0) : (selectionArea.startY || 0)
120
+ const endX: number = (selectionArea.startX || 0) > (selectionArea.endX || 0) ? (selectionArea.startX || 0) : (selectionArea.endX || 0)
121
+ const endY: number = (selectionArea.startY || 0) > (selectionArea.endY || 0) ? (selectionArea.startY || 0) : (selectionArea.endY || 0)
122
+
123
+ param.columns.forEach((column, x) => {
124
+ let qty: number | string = ''
125
+ const isSummary = tableTitleMap[column.property]?.isSummary ?? true
126
+
127
+ // 是否为圈选行
128
+ const isRangeCol = x >= startX && x <= endX
129
+
130
+ param.data.forEach((item, y) => {
131
+ const isNumber = checkType(item[column.property]).isNumber()
132
+ // 是否在圈选范围
133
+ const isRange = x >= startX && x <= endX && y >= startY && y <= endY
134
+ if (isNumber && !isRangeCol && isSummary) qty = (qty || 0) + item[column.property]
135
+ if (isNumber && isRangeCol && isRange && isSummary) qty = (qty || 0) + item[column.property]
136
+ })
137
+
138
+ if (!column.property) value.push((attrs as any)?.sumText ?? '合')
139
+ else if (column.property === 'sn') value.push('')
140
+ else value.push(qty)
141
+ })
142
+ return value
143
+ }
144
+
78
145
  /**
79
- * 获取表格头信息
146
+ * @description 获取表格头信息
147
+ * @param {boolean} isComplete 是否包含完整信息(既多选列等)
148
+ * @return {TableTitle[]} 表格头信息
80
149
  * */
81
- const getTableTitle = (): TableTitle[] => {
150
+ const getTableTitle = (isComplete: boolean = false): TableTitle[] => {
82
151
  const slotDefaultData = slotsToData(slots, {
83
152
  name: 'default',
84
153
  isJumpFgt: false,
@@ -92,7 +161,7 @@ const getTableTitle = (): TableTitle[] => {
92
161
  mTableColumnItemList.push(item)
93
162
  }
94
163
  })
95
- const tableTitle: TableTitle[] = mTableColumnItemList.map(item => {
164
+ let tableTitle: TableTitle[] = mTableColumnItemList.map(item => {
96
165
  return {
97
166
  label: item.props?.label ?? '',
98
167
  prop: item.props?.prop ?? '',
@@ -102,9 +171,11 @@ const getTableTitle = (): TableTitle[] => {
102
171
  fixed: item.props?.fixed ?? false,
103
172
  isBatchEdit: item.props?.isBatchEdit === '' || item.props?.isBatchEdit === true,
104
173
  show: item.props?.show ?? true,
105
- sort: item.props?.sort ?? 0
174
+ sort: item.props?.sort ?? 0,
175
+ isSummary: item.props?.isSummary ?? true
106
176
  }
107
- }).filter(item => item.prop)
177
+ })
178
+ if (!isComplete) tableTitle = tableTitle.filter(item => item.prop)
108
179
  return tableTitle
109
180
  }
110
181
 
@@ -175,30 +246,124 @@ const emit = defineEmits<{
175
246
  /** expandProp模式下 当用户对某一行展开或者关闭的时候会触发该事件 */
176
247
  privateExpandChange: [row: any, expandedRows: any[]];
177
248
  /** 选中单元格更新 */
178
- 'update:selectionCell': [string];
249
+ 'update:selectionCell': [ string | number | symbol ];
250
+ /** 复制事件 */
251
+ copyData: [ data: { text: string, selection: { startX: number, startY: number, endX: number, endY: number } } ];
179
252
  }>()
180
253
 
181
- interface SelectionCellInfoType {
182
- /** 列索引 */
183
- columnIndex: number | null;
184
- /** 行索引 */
185
- rowIndex: number | null;
186
- /** 列key */
187
- prop: string;
254
+ interface SelectionAreaType {
255
+ /** 开始x */
256
+ startX: number | null;
257
+ /** 开始Y */
258
+ startY: number | null;
259
+ /** 结束x */
260
+ endX: number | null;
261
+ /** 结束Y */
262
+ endY: number | null;
263
+ /** 圈选中 */
264
+ isInProgress: boolean;
188
265
  }
189
- const selectionCellInfo: SelectionCellInfoType = reactive<SelectionCellInfoType>({
190
- columnIndex: null,
191
- rowIndex: null,
192
- prop: ''
266
+ /** 选中区域 */
267
+ const selectionArea: SelectionAreaType = reactive<SelectionAreaType>({
268
+ /** 开始x */
269
+ startX: null,
270
+ /** 开始Y */
271
+ startY: null,
272
+ /** 结束x */
273
+ endX: null,
274
+ /** 结束Y */
275
+ endY: null,
276
+ /** 圈选中 */
277
+ isInProgress: false
193
278
  })
194
279
  const cellStyle = (data: { row: any, column: any, rowIndex: number, columnIndex: number }): Record<string, any> => {
195
- if (!props.selectionCell) return {}
196
- if (!props.showSelectionCellStatus) return {}
197
- if (data.columnIndex !== selectionCellInfo.columnIndex || data.rowIndex !== selectionCellInfo.rowIndex) return {}
280
+ if (selectionArea.startX === null || selectionArea.startY === null || selectionArea.endX === null || selectionArea.endY === null) return {}
281
+ const startX = selectionArea.startX > selectionArea.endX ? selectionArea.endX : selectionArea.startX
282
+ const startY = selectionArea.startY > selectionArea.endY ? selectionArea.endY : selectionArea.startY
283
+ const endX = selectionArea.startX > selectionArea.endX ? selectionArea.startX : selectionArea.endX
284
+ const endY = selectionArea.startY > selectionArea.endY ? selectionArea.startY : selectionArea.endY
285
+ if (data.columnIndex < startX || data.columnIndex > endX) return {}
286
+ if (data.rowIndex < startY || data.rowIndex > endY) return {}
198
287
  return {
199
288
  backgroundColor: 'var(--el-color-primary-light-9)'
200
289
  }
201
290
  }
291
+ const cellMouseEnter = (row: any, column: any, cell: HTMLTableCellElement) => {
292
+ if (!selectionArea.isInProgress) return
293
+
294
+ const tr = cell.parentElement
295
+ if (!tr) return
296
+ const parent = tr.parentNode
297
+ if (!parent) return
298
+ const rowIndex = Array.from(parent.children).indexOf(tr)
299
+
300
+ selectionArea.endX = cell.cellIndex
301
+ selectionArea.endY = rowIndex
302
+ }
303
+
304
+ const taskUpKey = 'MTable-onmouseup-' + createHash()
305
+ globalEvents().register({
306
+ id: taskUpKey,
307
+ eventName: 'onmouseup',
308
+ callback: () => {
309
+ selectionArea.isInProgress = false
310
+ }
311
+ })
312
+ onUnmounted(() => {
313
+ globalEvents().unregister(taskUpKey)
314
+ })
315
+ const taskDownKey = 'MTable-onmousedown-' + createHash()
316
+ globalEvents().register({
317
+ id: taskDownKey,
318
+ eventName: 'onmousedown',
319
+ callback: () => {
320
+ selectionArea.isInProgress = false
321
+ selectionArea.startX = null
322
+ selectionArea.startY = null
323
+ selectionArea.endX = null
324
+ selectionArea.endY = null
325
+ }
326
+ })
327
+ onUnmounted(() => {
328
+ globalEvents().unregister(taskDownKey)
329
+ })
330
+
331
+ watch(
332
+ () => [selectionArea.startX, selectionArea.endX],
333
+ () => {
334
+ let prop: string | number | symbol = ''
335
+ if (selectionArea.startX === selectionArea.endX && selectionArea.startX !== null && selectionArea.endX !== null) {
336
+ const tableTitle = getTableTitle(true)
337
+ prop = (tableTitle[selectionArea.startX] ?? {})?.prop ?? ''
338
+ }
339
+ selectionCell.value = prop
340
+ emit('update:selectionCell', prop)
341
+ }
342
+ )
343
+
344
+ /** 复制内容到粘贴板 */
345
+ const copyTextToClipboard = async (text: string) => {
346
+ const textarea = document.createElement('textarea')
347
+ textarea.value = text
348
+
349
+ textarea.style.position = 'fixed'
350
+ textarea.style.opacity = '0'
351
+ textarea.style.pointerEvents = 'none'
352
+
353
+ document.body.appendChild(textarea)
354
+ textarea.select()
355
+ textarea.setSelectionRange(0, textarea.value.length)
356
+
357
+ let success = false
358
+ try {
359
+ success = document.execCommand('copy')
360
+ } catch (err) {
361
+ console.error('复制失败:', err)
362
+ }
363
+
364
+ document.body.removeChild(textarea)
365
+ return success
366
+ }
202
367
 
203
368
  const privateExpandChange = (index: number) => {
204
369
  const row = tableData.value[index]
@@ -257,15 +422,16 @@ const cellClick = (row: any, column: { property: string; }, cell: any) => {
257
422
  elDom.value?.addEventListener('paste', disablePasteEvent)
258
423
  }
259
424
 
260
- const tr = cell.parentElement
261
- if (!tr) return
262
- const parent = tr.parentNode
263
- const rowIndex = Array.from(parent.children).indexOf(tr)
264
- const isRepeatClick = selectionCellInfo.columnIndex === cell.cellIndex && selectionCellInfo.rowIndex === rowIndex
265
- selectionCellInfo.columnIndex = cell.cellIndex
266
- selectionCellInfo.rowIndex = rowIndex
267
- selectionCellInfo.prop = column.property
268
- emit('update:selectionCell', isRepeatClick ? '' : column.property)
425
+ if (!selectionArea.isInProgress) {
426
+ const tr = cell.parentElement
427
+ if (!tr) return
428
+ const parent = tr.parentNode
429
+ const rowIndex = Array.from(parent.children).indexOf(tr)
430
+ selectionArea.startX = cell.cellIndex
431
+ selectionArea.startY = rowIndex
432
+ selectionArea.endX = cell.cellIndex
433
+ selectionArea.endY = rowIndex
434
+ }
269
435
  }
270
436
  const instance = getCurrentInstance()
271
437
  const disablePasteEvent = (e: { preventDefault: () => void; }) => {
@@ -353,7 +519,9 @@ provide(tableKey, {
353
519
  rowKey: props.rowKey,
354
520
  tableConfigKey: props.tableConfigKey,
355
521
  privateExpandChange,
356
- showFilter: Boolean(props.filtersValue)
522
+ showFilter: Boolean(props.filtersValue),
523
+ /** 选中区域 */
524
+ selectionArea
357
525
  })
358
526
 
359
527
  defineExpose({
@@ -372,6 +540,54 @@ defineExpose({
372
540
  setScrollLeft: (left: number) => tableRef.value?.setScrollLeft(left),
373
541
  getTableTitle
374
542
  })
543
+
544
+ /** 选中的单元格 */
545
+ const selectionCell = ref<string | number | symbol>(props.selectionCell)
546
+ watch(
547
+ () => props.selectionCell,
548
+ () => {
549
+ selectionCell.value = props.selectionCell
550
+ }
551
+ )
552
+
553
+ /** 表格单元格复制 */
554
+ const buildCopyText = (): string => {
555
+ if (selectionArea.startX === null || selectionArea.startY === null || selectionArea.endX === null || selectionArea.endY === null) return ''
556
+ const startX = selectionArea.startX < selectionArea.endX ? selectionArea.startX : selectionArea.endX
557
+ const startY = selectionArea.startY < selectionArea.endY ? selectionArea.startY : selectionArea.endY
558
+ const endX = selectionArea.startX > selectionArea.endX ? selectionArea.startX : selectionArea.endX
559
+ const endY = selectionArea.startY > selectionArea.endY ? selectionArea.startY : selectionArea.endY
560
+ const tableTitle = getTableTitle(true)
561
+ const copyColKey: (string | number | symbol)[] = []
562
+ for (let i = startX; i < endX + 1; i++) {
563
+ copyColKey.push(tableTitle[i].prop)
564
+ }
565
+ const text: any[] = []
566
+ for (let i = startY; i < endY; i++) {
567
+ const row: any[] = []
568
+ copyColKey.forEach(key => {
569
+ row.push(props.data[i][key as string])
570
+ })
571
+ text.push(row.join('\t'))
572
+ }
573
+
574
+ return text.join('\n')
575
+ }
576
+ const onKeydown = async (e: KeyboardEvent) => {
577
+ if (!((e.ctrlKey || e.metaKey) && String(e.key).toLowerCase() === 'c')) return
578
+ const text = buildCopyText()
579
+ if (!text) return
580
+ await copyTextToClipboard(text)
581
+ emit('copyData', {
582
+ text,
583
+ selection: {
584
+ startX: selectionArea.startX as number,
585
+ startY: selectionArea.startY as number,
586
+ endX: selectionArea.endX as number,
587
+ endY: selectionArea.endY as number
588
+ }
589
+ })
590
+ }
375
591
  </script>
376
592
 
377
593
  <style scoped lang="scss">
@@ -20,5 +20,18 @@ export const tableKey: InjectionKey<{
20
20
  /** expandProp模式下 当用户对某一行展开或者关闭的时候会触发 */
21
21
  privateExpandChange: Function,
22
22
  /** 是否显示筛选图标 */
23
- showFilter: boolean
23
+ showFilter: boolean,
24
+ /** 选中区域 */
25
+ selectionArea: {
26
+ /** 开始x */
27
+ startX: number | null;
28
+ /** 开始Y */
29
+ startY: number | null;
30
+ /** 结束x */
31
+ endX: number | null;
32
+ /** 结束Y */
33
+ endY: number | null;
34
+ /** 圈选中 */
35
+ isInProgress: boolean;
36
+ }
24
37
  }> = Symbol('tableKey')
@@ -19,4 +19,5 @@ import demo from './demo.vue'
19
19
  | filters | 表格筛选数据 | string[],number[] | - | any[] |
20
20
  | filterMethod | 筛选方法 | Function | - | () => void |
21
21
  | children | 多级表头 时使用传递对应数据进行循环 | Table-column API[] | - | [] |
22
+ | isBatchEdit | 是否允许批改 | boolean | - | false |
22
23
  | 其余参数 | 参考el官网的table | any | - | https://element-plus.org/zh-CN/component/table.html |
@@ -9,12 +9,30 @@
9
9
  >
10
10
  <slot
11
11
  name="default"
12
- :row="scope.row"
13
- :column="scope.column"
14
- :index="scope.$index"
15
- :$index="scope.$index"
12
+ v-bind="{
13
+ index: scope.$index,
14
+ ...scope
15
+ }"
16
16
  ></slot>
17
17
  </template>
18
+ <template
19
+ #default="scope"
20
+ v-if="!slots.default"
21
+ >
22
+ <div
23
+ class="u-my-table-column-text"
24
+ @mousedown="mousedown($event, scope.cellIndex, scope.$index)"
25
+ >
26
+ {{ columnData[scope.$index] }}
27
+ <slot
28
+ name="default"
29
+ v-bind="{
30
+ index: scope.$index,
31
+ ...scope
32
+ }"
33
+ ></slot>
34
+ </div>
35
+ </template>
18
36
 
19
37
  <!--展开行开始-->
20
38
  <template
@@ -32,10 +50,10 @@
32
50
  </el-icon>
33
51
  <slot
34
52
  name="default"
35
- :row="scope.row"
36
- :column="scope.column"
37
- :index="scope.$index"
38
- :$index="scope.$index"
53
+ v-bind="{
54
+ index: scope.$index,
55
+ ...scope
56
+ }"
39
57
  ></slot>
40
58
  </div>
41
59
  </template>
@@ -57,8 +75,9 @@
57
75
  </template>
58
76
  <!--展开行结束-->
59
77
 
78
+ <!--子行开始-->
60
79
  <template v-if="props.children && props.children.length">
61
- <m-table-column
80
+ <MTableColumn
62
81
  v-for="child in props.children"
63
82
  :key="child.prop"
64
83
  :prop="child.prop"
@@ -66,16 +85,20 @@
66
85
  :minWidth="child.minWidth"
67
86
  showOverflowTooltip
68
87
  :children="child.children || []"
69
- ></m-table-column>
88
+ :isBatchEdit="child.isBatchEdit"
89
+ ></MTableColumn>
70
90
  </template>
91
+ <!--子行结束-->
92
+
93
+ <!--表格配置开始-->
71
94
  <template #header="scope">
72
95
  <span>
73
96
  <slot
74
97
  name="header"
75
- :row="scope.row"
76
- :column="scope.column"
77
- :index="scope.$index"
78
- :$index="scope.$index"
98
+ v-bind="{
99
+ index: scope.$index,
100
+ ...scope
101
+ }"
79
102
  ></slot>
80
103
  <span>
81
104
  <span v-if="!slots.header">{{ scope.column.label }}</span>
@@ -134,15 +157,16 @@
134
157
  <el-checkbox
135
158
  v-for="item in getCheckboxOptions(props.filters)"
136
159
  :key="item.value"
137
- :label="item.value"
160
+ :value="item.value"
138
161
  >
139
162
  <template v-if="slots.default">
140
163
  <slot
141
164
  name="default"
142
- :row="{ [scope.column.property]: item.text }"
143
- :column="scope.column"
144
- :index="scope.$index"
145
- :$index="scope.$index"
165
+ v-bind="{
166
+ index: scope.$index,
167
+ ...scope,
168
+ row: { [scope.column.property]: item.text }
169
+ }"
146
170
  ></slot>
147
171
  </template>
148
172
  <template v-if="!slots.default">{{ item.text }}</template>
@@ -177,6 +201,7 @@
177
201
  </span>
178
202
  </span>
179
203
  </template>
204
+ <!--表格配置开始-->
180
205
  </el-table-column>
181
206
  </template>
182
207
 
@@ -185,6 +210,8 @@ import { ref, useSlots, useAttrs, inject, computed } from 'vue'
185
210
  import checkType from '../../Tool/checkType/checkType'
186
211
  import { tableKey } from './../../MTable/src/token'
187
212
  import { useZIndex } from 'element-plus'
213
+ import { MTableColumn } from 'packages/MTableColumn'
214
+ import { ArrowRight } from '@element-plus/icons-vue'
188
215
 
189
216
  interface FilterValue {
190
217
  [key: string]: Array<string | number>
@@ -197,17 +224,20 @@ interface PropChildren {
197
224
 
198
225
  const props = withDefaults(defineProps<{
199
226
  /** 列筛选过滤条件(当为null时,不显示筛选图标) */
200
- filtersValue?: FilterValue | null,
227
+ filtersValue?: FilterValue | null;
201
228
  /** 过滤选项 */
202
- filters?: Array<{ text: string | number, value: string | number }>,
229
+ filters?: Array<{ text: string | number, value: string | number }>;
203
230
  /** 过滤方法 */
204
- filterMethod?: Function | null,
205
- children?: Array<PropChildren>,
231
+ filterMethod?: Function | null;
232
+ children?: Array<PropChildren>;
233
+ /** 是否允许批改 */
234
+ isBatchEdit?: boolean;
206
235
  }>(), {
207
236
  filtersValue: null,
208
237
  filters: () => [],
209
238
  filterMethod: null,
210
- children: () => []
239
+ children: () => [],
240
+ isBatchEdit: false
211
241
  })
212
242
 
213
243
  const slots = useSlots()
@@ -350,6 +380,17 @@ const boxStyle = ref<BoxStyle>({
350
380
  right: 'unset',
351
381
  zIndex: thisZIndex
352
382
  })
383
+
384
+ // 选中区域
385
+ const selectionArea = tableKeyData?.selectionArea ?? { startX: null, startY: null, endX: null, endY: null, isInProgress: false }
386
+ const mousedown = (event: Event, x: number, y: number) => {
387
+ selectionArea.isInProgress = true
388
+ selectionArea.startX = x
389
+ selectionArea.startY = y
390
+ selectionArea.endX = null
391
+ selectionArea.endY = null
392
+ event.stopPropagation()
393
+ }
353
394
  </script>
354
395
 
355
396
  <style scoped lang="scss">
@@ -388,6 +429,15 @@ const boxStyle = ref<BoxStyle>({
388
429
  transform: rotate(90deg);
389
430
  }
390
431
  }
432
+
433
+ .u-my-table-column-text {
434
+ overflow: hidden;
435
+ display: block;
436
+ overflow-wrap: break-word;
437
+ text-overflow: ellipsis;
438
+ white-space: nowrap;
439
+ user-select: none;
440
+ }
391
441
  </style>
392
442
 
393
443
  <style lang="scss">
@@ -471,4 +521,28 @@ const boxStyle = ref<BoxStyle>({
471
521
  .filter-i {
472
522
  background-color: var(--el-color-primary);
473
523
  }
524
+
525
+ .br-m-table-box {
526
+ .el-table__body-wrapper {
527
+ .el-table .el-table__cell {
528
+ padding-top: 0;
529
+ padding-bottom: 0;
530
+
531
+ .u-my-table-column-text {
532
+ padding-top: 8px;
533
+ padding-bottom: 8px;
534
+ }
535
+ }
536
+
537
+ .el-table .cell {
538
+ padding-left: 0;
539
+ padding-right: 0;
540
+
541
+ .u-my-table-column-text {
542
+ padding-left: 12px;
543
+ padding-right: 12px;
544
+ }
545
+ }
546
+ }
547
+ }
474
548
  </style>
@@ -0,0 +1,23 @@
1
+ ## 全局事件代理 globalEvents
2
+
3
+ ### 1) 参数
4
+
5
+ | 参数 | 描述 | 类型 | 默认值 |
6
+ |-------|--------------------------|--------|--------|
7
+ | point | 锚点(绑定事件的dom节点的class,id等) | string | 'body' |
8
+
9
+ ### 2) 返参
10
+
11
+ | 参数 | 描述 | 类型 | 默认值 |
12
+ |------------|----------------------------|--------------------------------------|-----|
13
+ | register | 注册行为 | (options: EventRegistration) => void | - |
14
+ | unregister | 注销行为(id存在即注销对应行为,不存在即注销所有) | (id?: string \| number) => void | - |
15
+
16
+ #### 2.1) EventRegistration
17
+
18
+ | 参数 | 描述 | 类型 | 默认值 |
19
+ |-----------|------------------|--------------------|-----|
20
+ | eventName | 事件类型 | GlobalEventName | - |
21
+ | id | 唯一标识符 | string \| number | - |
22
+ | callback | 事件回调 | (event: T) => void | - |
23
+ | priority | 事件优先级(数字越小优先级越高) | number | - |