el-plus-crud 0.0.2

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 (86) hide show
  1. package/.eslintignore +18 -0
  2. package/.eslintrc.js +78 -0
  3. package/.lintstagedrc +3 -0
  4. package/.prettierrc.js +39 -0
  5. package/CHANGELOG.md +5 -0
  6. package/LICENSE +21 -0
  7. package/README.md +15 -0
  8. package/example/App.vue +79 -0
  9. package/example/assets/vue.svg +1 -0
  10. package/example/main.js +18 -0
  11. package/example/style.css +5 -0
  12. package/index.html +13 -0
  13. package/lib/components/el-plus-form/ElPlusForm.vue +744 -0
  14. package/lib/components/el-plus-form/ElPlusFormDialog.vue +107 -0
  15. package/lib/components/el-plus-form/components/ElPlusFormAutocomplete.vue +49 -0
  16. package/lib/components/el-plus-form/components/ElPlusFormBtn.vue +96 -0
  17. package/lib/components/el-plus-form/components/ElPlusFormBtns.vue +133 -0
  18. package/lib/components/el-plus-form/components/ElPlusFormCascader.vue +38 -0
  19. package/lib/components/el-plus-form/components/ElPlusFormCascaderPanel.vue +51 -0
  20. package/lib/components/el-plus-form/components/ElPlusFormCheckbox.vue +42 -0
  21. package/lib/components/el-plus-form/components/ElPlusFormCheckboxButton.vue +42 -0
  22. package/lib/components/el-plus-form/components/ElPlusFormColor.vue +38 -0
  23. package/lib/components/el-plus-form/components/ElPlusFormDate.vue +37 -0
  24. package/lib/components/el-plus-form/components/ElPlusFormDaterange.vue +44 -0
  25. package/lib/components/el-plus-form/components/ElPlusFormDatetime.vue +38 -0
  26. package/lib/components/el-plus-form/components/ElPlusFormFile.vue +47 -0
  27. package/lib/components/el-plus-form/components/ElPlusFormImage.vue +113 -0
  28. package/lib/components/el-plus-form/components/ElPlusFormInput.vue +56 -0
  29. package/lib/components/el-plus-form/components/ElPlusFormLink.vue +271 -0
  30. package/lib/components/el-plus-form/components/ElPlusFormNbinput.vue +51 -0
  31. package/lib/components/el-plus-form/components/ElPlusFormNumber.vue +107 -0
  32. package/lib/components/el-plus-form/components/ElPlusFormPassword.vue +39 -0
  33. package/lib/components/el-plus-form/components/ElPlusFormRadio.vue +42 -0
  34. package/lib/components/el-plus-form/components/ElPlusFormRate.vue +38 -0
  35. package/lib/components/el-plus-form/components/ElPlusFormSelect.vue +149 -0
  36. package/lib/components/el-plus-form/components/ElPlusFormSlider.vue +38 -0
  37. package/lib/components/el-plus-form/components/ElPlusFormStatus.vue +67 -0
  38. package/lib/components/el-plus-form/components/ElPlusFormSwitch.vue +38 -0
  39. package/lib/components/el-plus-form/components/ElPlusFormTag.vue +78 -0
  40. package/lib/components/el-plus-form/components/ElPlusFormText.vue +115 -0
  41. package/lib/components/el-plus-form/components/ElPlusFormTextarea.vue +45 -0
  42. package/lib/components/el-plus-form/components/ElPlusFormTransfer.vue +44 -0
  43. package/lib/components/el-plus-form/components/ElPlusFormTree.vue +53 -0
  44. package/lib/components/el-plus-form/components/ElPlusFormTreeSelect.vue +36 -0
  45. package/lib/components/el-plus-form/components/components/IconSelectorList.vue +92 -0
  46. package/lib/components/el-plus-form/components/components/file-icons/FileIcons.vue +135 -0
  47. package/lib/components/el-plus-form/components/components/file-icons/data/index.ts +27 -0
  48. package/lib/components/el-plus-form/components/components/file-icons/images/doc.svg +13 -0
  49. package/lib/components/el-plus-form/components/components/file-icons/images/file.svg +19 -0
  50. package/lib/components/el-plus-form/components/components/file-icons/images/jpg.svg +14 -0
  51. package/lib/components/el-plus-form/components/components/file-icons/images/pdf.svg +13 -0
  52. package/lib/components/el-plus-form/components/components/file-icons/images/png.svg +13 -0
  53. package/lib/components/el-plus-form/components/components/file-icons/images/ppt.svg +13 -0
  54. package/lib/components/el-plus-form/components/components/file-icons/images/xls.svg +13 -0
  55. package/lib/components/el-plus-form/components/index.ts +17 -0
  56. package/lib/components/el-plus-form/data/file.ts +74 -0
  57. package/lib/components/el-plus-form/images/icon/excel.png +0 -0
  58. package/lib/components/el-plus-form/images/icon/file.png +0 -0
  59. package/lib/components/el-plus-form/images/icon/pdf.png +0 -0
  60. package/lib/components/el-plus-form/images/icon/ppt.png +0 -0
  61. package/lib/components/el-plus-form/images/icon/txt.png +0 -0
  62. package/lib/components/el-plus-form/images/icon/word.png +0 -0
  63. package/lib/components/el-plus-form/images/icon/zip.png +0 -0
  64. package/lib/components/el-plus-form/mixins/index.ts +113 -0
  65. package/lib/components/el-plus-form/util/index.ts +266 -0
  66. package/lib/components/el-plus-form/util/validate.ts +310 -0
  67. package/lib/components/el-plus-table/ElPlusTable.vue +723 -0
  68. package/lib/components/el-plus-table/components/columnItem.vue +185 -0
  69. package/lib/components/el-plus-table/components/header.vue +185 -0
  70. package/lib/components/el-plus-table/components/settingColumn.vue +168 -0
  71. package/lib/components/el-plus-table/components/statisticInfo.vue +47 -0
  72. package/lib/components/el-plus-table/util/index.ts +123 -0
  73. package/lib/config/form.ts +12 -0
  74. package/lib/config/index.ts +9 -0
  75. package/lib/index.ts +29 -0
  76. package/package.json +65 -0
  77. package/public/vite.svg +1 -0
  78. package/tsconfig.json +68 -0
  79. package/types/axios.d.ts +13 -0
  80. package/types/formList.d.ts +365 -0
  81. package/types/global.d.ts +145 -0
  82. package/types/layout.d.ts +57 -0
  83. package/types/mitt.d.ts +38 -0
  84. package/types/pinia.d.ts +149 -0
  85. package/types/views.d.ts +329 -0
  86. package/vite.config.ts +68 -0
@@ -0,0 +1,723 @@
1
+ <template>
2
+ <div class="el-plus-table-content">
3
+ <!-- <div class="select-items" v-if="type === 'selection' && selectRowList && selectRowList.length > 0">
4
+ <span class="title">已选择({{ selectRowList.length }}个): </span>
5
+ <el-tag v-for="(item, i) in selectRowList" :key="item.id" class="select-item" size="small" closable @close="() => handelRemoveSelect(i, item)">
6
+ {{ item[tableConfig.showSelectNameKey || 'name'] }}
7
+ </el-tag>
8
+ </div> -->
9
+ <EleTabletHeader ref="tableHeaderRef" v-model="toolFormData" :tbName="props.tableConfig.tbName" :column="props.tableConfig.column" :size="size" :isShowRefresh="isShowRefresh" :loading="loading" :toolbar="tableConfig.toolbar" :isDialog="isDialog" @query="handelTopQuery" />
10
+
11
+ <!-- 中部的Tabs -->
12
+ <div class="table-tabs-panel" v-if="tableConfig.tabConf">
13
+ <el-radio-group v-model="tableTabVal" size="default" @change="handelTabChange">
14
+ <el-radio-button v-for="(item, i) in tableConfig.tabConf?.tabs" :key="i" :label="item.value" :loading="true">
15
+ {{ item.label }}
16
+ <template v-if="loadingTab">
17
+ <el-icon class="is-loading"><Loading /></el-icon>
18
+ </template>
19
+ <template v-else>
20
+ {{ getTabLabel(item) }}
21
+ </template>
22
+ </el-radio-button>
23
+ </el-radio-group>
24
+ </div>
25
+
26
+ <!-- 中间列表 -->
27
+ <div class="el-plus-table-main" v-loading="loading">
28
+ <template v-if="isDIYMain">
29
+ <slot name="main" :tableData="tableData"></slot>
30
+ </template>
31
+ <!-- 这里开始是表格内容 -->
32
+ <el-table ref="elPlusTableRef" v-else style="width: 100%" height="100%" :maxHeight="tableConfig.maxHeight || 'auto'" v-bind="tableConfig.tableAttr" :data="tableData" :row-key="rowKey" lazy :load="loadExpandData" :size="size" :row-class-name="initRowClassName" @select="handelTableSelect" @select-all="handelTableSelectAll" @expand-change="handelTableExpandChange" :treeProps="treeProps">
33
+ <!-- 下标 -->
34
+ <el-table-column v-if="isIndex" type="index" width="60" label="序号" />
35
+ <!-- 复选框 -->
36
+ <el-table-column v-if="type === 'selection'" type="selection" width="55px" :selectable="(row: any, index: number) => tableConfig?.tableAttr?.selectable(row, index) ?? true" header-align="center" align="center" />
37
+ <!-- 首列 -->
38
+ <template v-if="useSlots().firstColumn">
39
+ <slot name="firstColumn" />
40
+ </template>
41
+ <template v-for="(item, i) in headerColumns" :key="item.label + i">
42
+ <!-- 二级表头 -->
43
+ <template v-if="item.children && item.children.length > 0">
44
+ <!-- <el-table-column :prop="item.label" :label="item.label" header-align="center">
45
+ <template v-for="(item2, j) in item.children" :key="item2.label + i + j">
46
+ <el-table-column :prop="item2.prop" v-if="columnShowList[i][j]" v-bind="item2">
47
+ <template #header>
48
+ <div :class="{ 'th-required': item2.required }">
49
+ {{ item2.label }}
50
+ </div>
51
+ </template>
52
+ <template #default="scope: any">
53
+ <slot name="default"></slot>
54
+ <ColumnItem v-if="scope.$index >= 0" :field="item2.prop" :desc="item2" :scope="scope" :size="size" v-model="scope.row[item2.prop]" />
55
+ </template>
56
+ </el-table-column>
57
+ </template>
58
+ </el-table-column> -->
59
+ </template>
60
+ <!-- 单级表头 -->
61
+ <template v-else>
62
+ <el-table-column v-if="columnShowList[i]" :prop="item.prop" v-bind="item">
63
+ <template #header="{ column }: any">
64
+ <div :class="{ 'th-required': item.required }">
65
+ {{ column.label }}
66
+ </div>
67
+ </template>
68
+ <template #default="scope: any">
69
+ <ColumnItem v-if="scope.$index >= 0" :field="item.prop" :desc="item" :scope="scope" :size="size" v-model="scope.row[item.prop]" />
70
+ </template>
71
+ </el-table-column>
72
+ </template>
73
+ </template>
74
+ <template v-if="!loading && loadingStatus === 2" #empty>
75
+ <el-empty v-if="isEmptyImg" :description="nullText" />
76
+ <span v-else>{{ nullText }}</span>
77
+ </template>
78
+ <!-- 合计行 -->
79
+ <template v-if="tableConfig.summaryConf?.prop" #append>
80
+ <div class="summary-row" v-if="summaryList && summaryList.length > 0">
81
+ <div class="summary-item" v-for="(item, i) in summaryList" :key="i">
82
+ <span>{{ item.label || '合计' }}:</span>
83
+ <p>{{ item.value || 0 }}</p>
84
+ </div>
85
+ </div>
86
+ </template>
87
+ </el-table>
88
+ </div>
89
+ <div class="bottom-page-static-info" v-if="isPager || tableConfig.statistic">
90
+ <el-pagination class="page-info" small @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="+pageInfo.current" :page-sizes="[5, 10, 20, 50, 100]" :page-size="pageInfo.size" layout="total, sizes, prev, pager, next, jumper" :total="pageInfo.total" />
91
+ </div>
92
+ <slot name="bottom"></slot>
93
+ </div>
94
+ </template>
95
+ <script lang="ts" setup name="ElPlusTable">
96
+ import { ref, reactive, onMounted, computed, watch, nextTick, useSlots, inject } from 'vue'
97
+ import EleTabletHeader from './components/header.vue'
98
+ import ColumnItem from './components/columnItem.vue'
99
+ import { handelListColumn } from './util'
100
+ import { cloneDeep } from 'lodash'
101
+ import { Loading } from '@element-plus/icons-vue'
102
+
103
+ const format = inject('format') as any
104
+
105
+ const emits = defineEmits(['getUrlConsumerIds', 'selection', 'select', 'selectAll', 'update:modelValue', 'tabChange', 'expandChange'])
106
+ const props = withDefaults(
107
+ defineProps<{
108
+ tableConfig: ITableConfig
109
+ // 外部数据
110
+ modelValue?: Array<any> | null
111
+ // 列表类型 默认为index
112
+ type?: string
113
+ // 是否显示第一列的Index下标
114
+ isIndex?: boolean
115
+ // 是否分页
116
+ isPager?: boolean
117
+ // 每页显示条数
118
+ pageSize?: number
119
+ // 是否在弹框中
120
+ isDialog?: boolean
121
+ // 空占位文本
122
+ nullText?: string
123
+ // 是否显示暂无数据的图片
124
+ isEmptyImg?: boolean
125
+ // 是否显示刷新文本
126
+ isShowRefresh?: boolean
127
+ // rowKey默认为id
128
+ rowKey?: string
129
+ // 自定义table主体
130
+ isDIYMain?: boolean
131
+ // 默认选中项
132
+ selectList?: Array<any> | []
133
+ // 默认列宽
134
+ colMinWidth?: string
135
+ }>(),
136
+ {
137
+ modelValue: null,
138
+ type: 'index',
139
+ isIndex: true,
140
+ isPager: true,
141
+ pageSize: 10,
142
+ isDialog: false,
143
+ nullText: '暂无数据',
144
+ isShowRefresh: true,
145
+ rowKey: 'id',
146
+ isEmptyImg: true,
147
+ isDIYMain: false,
148
+ selectList: () => [],
149
+ colMinWidth: '170px'
150
+ }
151
+ )
152
+
153
+ const elPlusTableRef = ref()
154
+
155
+ // 顶部Tab数据
156
+ const tableTabVal = ref(props.tableConfig?.tabConf?.tabs[0].value ?? '')
157
+ const tabStatic = ref({} as any)
158
+ const getTabLabel = computed(() => (item: ITableTabItem) => {
159
+ if (item.key) {
160
+ return tabStatic.value[item.key] || 0
161
+ }
162
+ return 0
163
+ })
164
+
165
+ const tableHeaderRef = ref()
166
+
167
+ // 加载
168
+ const loading = ref(false)
169
+ const loadingTab = ref(!!props.tableConfig.tabConf?.fetch)
170
+ const listLoading = ref(false)
171
+ const size = 'small'
172
+
173
+ // 顶部查询条件数据缓存
174
+ const topQueryData = ref({} as any)
175
+
176
+ // 数据
177
+ let toolFormData = reactive(Object.assign({}) as any)
178
+ const tableData = reactive((props.modelValue || []) as any[])
179
+ const haveClassRowList = reactive([])
180
+
181
+ // 初始化表头
182
+ const headerColumns = reactive(handelListColumn(props.tableConfig.column, props.isDialog ? 'auto' : props.colMinWidth))
183
+
184
+ // 0:未加载; 1:加载中;2:加载完成
185
+ const loadingStatus = ref(0)
186
+
187
+ // 保存所有的选中行
188
+ const allSelectRowList = reactive((cloneDeep(props.selectList) || []) as any[])
189
+ // 记录树形展开的数组的下标
190
+ const treeIndexList = reactive([] as any[][])
191
+
192
+ // 分页信息
193
+ const pageInfo = reactive({
194
+ current: !props.isDialog && toolFormData.current ? parseInt(toolFormData.current as any) : 1,
195
+ total: 0,
196
+ size: !props.isDialog && toolFormData.size ? parseInt(toolFormData.size as any) : props.pageSize
197
+ })
198
+ // 数型解析
199
+ const treeProps = (props.tableConfig?.explan?.treeProps || { children: 'children', hasChildren: 'hasChildren' }) as ITreeProps
200
+
201
+ // 列的显示
202
+ const columnShowList = computed(() => {
203
+ return props.tableConfig.column.map((item) => {
204
+ if (props.tableConfig.tbName) {
205
+ return item._vif && item.scShow
206
+ } else {
207
+ // 这里初始化一下vif
208
+ if (item.vif !== undefined && item.vif !== null) {
209
+ if (typeof item.vif === 'function') {
210
+ item._vif = item.vif(item)
211
+ } else {
212
+ item._vif = !!item.vif
213
+ }
214
+ } else {
215
+ item._vif = true
216
+ }
217
+ return item._vif
218
+ }
219
+ })
220
+ })
221
+
222
+ // 合计行数据
223
+ const summaryList = computed(() => {
224
+ const tempList = [] as any[]
225
+ if (props.tableConfig.summaryConf?.prop) {
226
+ const propList = props.tableConfig.summaryConf.prop.split(',')
227
+ const labelList = props.tableConfig.summaryConf?.label?.split(',') || []
228
+ // 遍历
229
+ propList.map((prop, i: number) => {
230
+ let value = ''
231
+ if (props.tableConfig.summaryConf?.sumFn) {
232
+ value = props.tableConfig.summaryConf?.sumFn(tableData)
233
+ } else {
234
+ value = format.yuan(tableData.reduce((total: number, current) => (total += current[prop]), 0))
235
+ }
236
+ tempList.push({ label: labelList[i], value })
237
+ })
238
+ }
239
+ return tempList
240
+ })
241
+
242
+ /**
243
+ * Tab切换
244
+ * @param val
245
+ */
246
+ function handelTabChange(val: string | number | boolean) {
247
+ // 这里直接重新查询
248
+ reload(true)
249
+ // 通知父类
250
+ emits('tabChange', val)
251
+ }
252
+
253
+ /**
254
+ * 加载自身展开的数据
255
+ * @param row
256
+ * @param treeNode
257
+ * @param resolve
258
+ */
259
+ function loadExpandData(row: any, treeNode: any, resolve: any) {
260
+ const postData = getListQueryData()
261
+ postData[props.tableConfig?.explan?.idName || 'parentId'] = row.id
262
+ props.tableConfig.fetch &&
263
+ props.tableConfig.fetch(postData).then((pageInfo) => {
264
+ resolve(pageInfo?.records)
265
+ })
266
+ }
267
+
268
+ /**
269
+ * 初始化每行的颜色
270
+ * @param data
271
+ */
272
+ function initRowClassName(data: any) {
273
+ if (haveClassRowList.length > data.rowIndex) {
274
+ return haveClassRowList[data.rowIndex * 1]
275
+ }
276
+ return ''
277
+ }
278
+
279
+ /**
280
+ * 处理单个选中的情况
281
+ * @param selection
282
+ * @param row
283
+ */
284
+ function handelTableSelect(selection: any[], item: any) {
285
+ checkAndRemove(item, !selection.some((i) => i[props.rowKey] === item[props.rowKey]))
286
+ // 通知父类
287
+ emits('select', selection, item)
288
+ emits('selection', cloneDeep(allSelectRowList))
289
+ }
290
+
291
+ /**
292
+ * 处理全选
293
+ * @param selection
294
+ * @param row
295
+ */
296
+ function handelTableSelectAll(selection: any[]) {
297
+ const isRemove = !(selection && selection.length > 0)
298
+ ;(isRemove ? tableData : selection).map((item) => {
299
+ checkAndRemove(item, isRemove)
300
+ })
301
+ // 通知父类
302
+ emits('selectAll', selection, isRemove)
303
+ emits('selection', cloneDeep(allSelectRowList))
304
+ }
305
+
306
+ /**
307
+ * 处理行展开
308
+ * @param row
309
+ * @param expanded
310
+ */
311
+ function handelTableExpandChange(row: any, expanded: boolean) {
312
+ // console.log('row: ', row, expanded)
313
+ emits('expandChange', row, expanded)
314
+ }
315
+
316
+ /**
317
+ * 选中或者取消
318
+ * @param item
319
+ */
320
+ function checkAndRemove(item: any, isRemove: boolean = false) {
321
+ // 校验是否已经有了
322
+ const index = allSelectRowList.findIndex((i) => i[props.rowKey] === item[props.rowKey])
323
+ if (isRemove) {
324
+ if (index >= 0) {
325
+ allSelectRowList.splice(index, 1)
326
+ }
327
+ } else {
328
+ if (index < 0) {
329
+ allSelectRowList.push(item)
330
+ }
331
+ }
332
+ }
333
+
334
+ /**
335
+ * 外部修改选中项
336
+ * @param item
337
+ */
338
+ function changeSelect(itemList: any[], isSelect: boolean = false) {
339
+ if (itemList && itemList.length) {
340
+ itemList.map((item) => {
341
+ checkAndRemove(
342
+ allSelectRowList.find((i) => i[props.rowKey] === item[props.rowKey]),
343
+ !isSelect
344
+ )
345
+ })
346
+ }
347
+ // 这里要刷新一下tab的选中
348
+ refreshTableSelect()
349
+ }
350
+
351
+ /**
352
+ * 重置选中
353
+ */
354
+ function resetSelect() {
355
+ allSelectRowList.splice(0, allSelectRowList.length, ...props.selectList)
356
+ }
357
+
358
+ /**
359
+ * 封装分页查询条件
360
+ */
361
+ function getListQueryData() {
362
+ let queryMap = {
363
+ // 封装查询条件
364
+ // ...route.query,
365
+ // ...tableHeaderRef.value.getData(),
366
+ ...topQueryData.value,
367
+ ...props.tableConfig.queryMap,
368
+ t_: new Date().getTime()
369
+ } as any
370
+ if (props.isPager) {
371
+ // 封装分页信息
372
+ queryMap.current = pageInfo.current
373
+ queryMap.size = pageInfo.size
374
+ }
375
+ // 这里处理一下列表Tab的查询条件
376
+ if (props.tableConfig.tabConf && props.tableConfig.tabConf.prop) {
377
+ queryMap[props.tableConfig.tabConf.prop] = tableTabVal.value
378
+ }
379
+
380
+ queryMap = handelQueryData(queryMap)
381
+ if (!props.isDialog) {
382
+ }
383
+ // 这里是导出的权限判定-增加登陆信息
384
+ if (props.tableConfig?.toolbar?.export?.isAuth) {
385
+ // TODO GET Auth
386
+ }
387
+ return queryMap
388
+ }
389
+
390
+ /**
391
+ * 处理下请求参数
392
+ * @param queryMap
393
+ */
394
+ function handelQueryData(queryMap: object) {
395
+ if (!queryMap) return {}
396
+ const tempMap = {}
397
+ Object.keys(queryMap).map((key) => {
398
+ if (queryMap[key] !== undefined && queryMap[key] !== null && queryMap[key] !== '') {
399
+ tempMap[key] = queryMap[key]
400
+ }
401
+ })
402
+ return tempMap
403
+ }
404
+
405
+ /**
406
+ * 处理显示
407
+ * @param rowInfo
408
+ */
409
+ // function handelHeaderVIf(rowInfo: any) {
410
+ // let vif = false
411
+ // if (rowInfo.children && rowInfo.children.length > 0) {
412
+ // vif = rowInfo.children.some((item: any) => {
413
+ // return !(item.vif === false)
414
+ // })
415
+ // }
416
+ // return vif
417
+ // }
418
+
419
+ /**
420
+ * 处理列的显示
421
+ * @param item
422
+ */
423
+ // function handelColumnVIf(item: any) {
424
+ // if (item.vif !== undefined && item.vif !== null && item.vif !== '') {
425
+ // if (typeof item.vif === 'boolean') return item.vif
426
+ // if (typeof item.vif === 'function') return item.vif(item)
427
+ // return !!item.vif
428
+ // }
429
+ // return true
430
+ // }
431
+
432
+ /**
433
+ * 处理分页工具中pageSize变化
434
+ * @param val
435
+ */
436
+ function handleSizeChange(val: number) {
437
+ // 回到第一页
438
+ pageInfo.current = 1
439
+ pageInfo.size = val
440
+ loadData(true)
441
+ }
442
+
443
+ /**
444
+ * 处理分页工具中current变化
445
+ * @param val
446
+ */
447
+ function handleCurrentChange(val: number) {
448
+ if (pageInfo.current !== val) {
449
+ pageInfo.current = val
450
+ loadData(false)
451
+ }
452
+ }
453
+
454
+ /**
455
+ * 处理行展开
456
+ * @param list
457
+ * @param pIndexList
458
+ */
459
+ function handelTreeIndex(list: any[], pIndexList: number[]) {
460
+ let tempList = []
461
+ if (list && list.length > 0) {
462
+ list.map((item, i) => {
463
+ treeIndexList.push([...pIndexList, i])
464
+ tempList = item[treeProps.children] as any[]
465
+ if (tempList && tempList.length > 0) {
466
+ handelTreeIndex(tempList, [i])
467
+ }
468
+ })
469
+ }
470
+ }
471
+
472
+ /**
473
+ * 真正调用查询的接口
474
+ * @param isInit
475
+ */
476
+ async function loadData(isInit: Boolean) {
477
+ if (!props.tableConfig.fetch) {
478
+ loadingStatus.value = 2
479
+ // if (props.modelValue) {
480
+ // tableData.splice(0, tableData.length, ...props.modelValue)
481
+ // }
482
+ return false
483
+ }
484
+ if (loadingStatus.value === 1 || loading.value) return false
485
+ loadingStatus.value = 1
486
+ loading.value = true
487
+ tableData.splice(0, tableData.length)
488
+ if (isInit) {
489
+ pageInfo.current = 1
490
+ }
491
+ let postData = getListQueryData()
492
+ // 这里处理一下外部数据格式化
493
+ if (props.tableConfig?.toolbar?.formConfig?.beforeRequest) {
494
+ postData = props.tableConfig?.toolbar?.formConfig?.beforeRequest(JSON.parse(JSON.stringify(postData))) || postData
495
+ }
496
+ const dataPage = (await props.tableConfig.fetch(postData)) as any
497
+ try {
498
+ if (props.isPager) {
499
+ pageInfo.total = dataPage?.total * 1 || 0
500
+ pageInfo.current = dataPage?.current || 1
501
+ tableData.push(...(dataPage?.records || null))
502
+ } else {
503
+ tableData.push(...(dataPage?.records || dataPage || null))
504
+ }
505
+ if (isInit) {
506
+ // 初始化完毕后,调用一次父类更新
507
+ // emits('update:modelValue', tableData)
508
+ }
509
+ // 如果是树形结构
510
+ if (props.type === 'expand') {
511
+ treeIndexList.splice(0, treeIndexList.length)
512
+ handelTreeIndex(tableData, [])
513
+ }
514
+ listLoading.value = false
515
+ nextTick(() => {
516
+ // 遍历以及选中当前页面数据
517
+ refreshTableSelect()
518
+ })
519
+ } catch (e) {
520
+ // console.log('e: ', e)
521
+ }
522
+ loadingStatus.value = 2
523
+ loading.value = false
524
+ }
525
+
526
+ /**
527
+ * 渲染列表的选中项
528
+ */
529
+ function refreshTableSelect() {
530
+ if (tableData && tableData.length > 0 && props.type === 'selection') {
531
+ tableData.map((item: any) => {
532
+ elPlusTableRef.value!.toggleRowSelection(
533
+ item,
534
+ allSelectRowList.some((i) => i[props.rowKey] === item[props.rowKey])
535
+ )
536
+ })
537
+ }
538
+ }
539
+
540
+ /**
541
+ * 重新加载
542
+ */
543
+ async function reload(isTab: boolean = false) {
544
+ await loadData(true)
545
+ // 这里判断一下Tab
546
+ if (!isTab && props.tableConfig.tabConf && props.tableConfig.tabConf.fetch) {
547
+ tabStatic.value = await props.tableConfig.tabConf.fetch(Object.assign({}, getListQueryData(), props.tableConfig.tabConf.queryMap))
548
+ loadingTab.value = false
549
+ }
550
+ return tableData
551
+ }
552
+
553
+ /**
554
+ * 处理顶部条件表单筛选
555
+ */
556
+ function handelTopQuery() {
557
+ topQueryData.value = cloneDeep(tableHeaderRef.value.getData())
558
+ reload()
559
+ }
560
+
561
+ // 监听父类数据变更
562
+ watch(
563
+ () => props.modelValue,
564
+ (data) => {
565
+ // console.log('data: ', JSON.parse(JSON.stringify(data)))
566
+ if (!props.tableConfig.fetch) {
567
+ if (JSON.parse(JSON.stringify(data)) !== JSON.parse(JSON.stringify(tableData))) {
568
+ loadingStatus.value = 2
569
+ tableData.splice(0, tableData.length, ...(data || []))
570
+ }
571
+ }
572
+ },
573
+ { deep: true }
574
+ )
575
+
576
+ watch(
577
+ () => props.selectList,
578
+ (val: any[]) => {
579
+ allSelectRowList.splice(0, allSelectRowList.length, ...val)
580
+ // 遍历以及选中当前页面数据
581
+ refreshTableSelect()
582
+ },
583
+ {
584
+ deep: true
585
+ }
586
+ )
587
+
588
+ onMounted(() => {
589
+ reload()
590
+ })
591
+
592
+ defineExpose({ reload, tableData, changeSelect, resetSelect })
593
+ </script>
594
+ <style lang="scss">
595
+ .el-plus-table-content {
596
+ background-color: #ffffff;
597
+ border-radius: 5px;
598
+ padding: 10px;
599
+ width: 100%;
600
+ max-height: 100%;
601
+ overflow: hidden;
602
+ display: flex;
603
+ flex-direction: column;
604
+ position: relative;
605
+ .th-required {
606
+ position: relative;
607
+ &::before {
608
+ content: '*';
609
+ position: absolute;
610
+ left: -10px;
611
+ font-size: 16px;
612
+ top: 2px;
613
+ color: #ff3b30;
614
+ font-weight: bold;
615
+ }
616
+ }
617
+ .select-items {
618
+ display: flex;
619
+ flex-wrap: wrap;
620
+ align-items: center;
621
+
622
+ .title {
623
+ font-size: 18px;
624
+ font-weight: bold;
625
+ margin-right: 20px;
626
+ }
627
+
628
+ .select-item {
629
+ margin: 5px 10px 5px 0;
630
+
631
+ &:last-child {
632
+ margin-right: 0;
633
+ }
634
+ }
635
+ }
636
+
637
+ .table-tabs-panel {
638
+ margin-bottom: 16px;
639
+ }
640
+ .summary-row {
641
+ width: 100%;
642
+ background-color: var(--el-table-row-hover-bg-color);
643
+ color: var(--el-table-text-color);
644
+ padding: 16px 20px;
645
+ line-height: 24px;
646
+ height: 40px;
647
+ display: flex;
648
+ position: relative;
649
+ .summary-item {
650
+ display: flex;
651
+ align-items: center;
652
+ margin-right: 30px;
653
+ & > span {
654
+ margin-right: 20px;
655
+ }
656
+ }
657
+ }
658
+
659
+ .el-plus-table-main {
660
+ width: 100%;
661
+ flex: 1;
662
+ max-height: 100%;
663
+ display: flex;
664
+ flex-direction: column;
665
+ .el-table .cell {
666
+ display: flex;
667
+ align-items: center;
668
+ }
669
+ }
670
+
671
+ .pager-statistic {
672
+ width: 100%;
673
+ position: fixed;
674
+ height: 32px;
675
+ line-height: 32px;
676
+ bottom: 0;
677
+ text-align: right;
678
+ min-width: 900px;
679
+
680
+ .statistic-item {
681
+ display: inline-block;
682
+ }
683
+ }
684
+
685
+ .el-cascader__label {
686
+ width: 300px !important;
687
+ }
688
+
689
+ .bottom-page-static-info {
690
+ display: flex;
691
+ flex-wrap: wrap;
692
+ justify-content: center;
693
+ align-items: center;
694
+ min-height: 41px;
695
+ margin-top: 10px;
696
+
697
+ .page-info {
698
+ margin-right: 30px;
699
+ }
700
+ }
701
+
702
+ .common-list-export-excel {
703
+ background: #20a0ff;
704
+ text-decoration: none;
705
+ color: #ffffff;
706
+ font-size: 12px;
707
+ height: 29px;
708
+ line-height: 30px;
709
+ display: block;
710
+ margin-top: 5px;
711
+ border-radius: 3px;
712
+ padding: 0 10px;
713
+ }
714
+
715
+ .common-list-export-excel:hover {
716
+ background: #58b6ff;
717
+ }
718
+
719
+ .el-table__empty-block {
720
+ height: auto !important;
721
+ }
722
+ }
723
+ </style>