2023-12-22 16:19:33 +08:00
|
|
|
<template>
|
2025-10-20 13:25:30 +08:00
|
|
|
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
|
2025-11-14 09:33:35 +08:00
|
|
|
<vxe-table
|
|
|
|
|
ref="tableRef"
|
|
|
|
|
height="auto"
|
|
|
|
|
:key="key"
|
|
|
|
|
:data="tableStore.table.data"
|
|
|
|
|
v-loading="tableStore.table.loading"
|
|
|
|
|
v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
|
|
|
|
@checkbox-all="selectChangeEvent"
|
|
|
|
|
@checkbox-change="selectChangeEvent"
|
|
|
|
|
:showOverflow="showOverflow"
|
|
|
|
|
:sort-config="{ remote: true }"
|
|
|
|
|
@sort-change="handleSortChange"
|
|
|
|
|
>
|
2025-11-14 15:00:10 +08:00
|
|
|
|
2024-01-04 10:38:41 +08:00
|
|
|
<!-- Column 组件内部是 el-table-column -->
|
|
|
|
|
<template v-if="isGroup">
|
2024-04-01 18:29:32 +08:00
|
|
|
<GroupColumn :column="tableStore.table.column" />
|
2024-01-04 10:38:41 +08:00
|
|
|
</template>
|
|
|
|
|
<template v-else>
|
2025-11-14 09:33:35 +08:00
|
|
|
<Column
|
|
|
|
|
:attr="item"
|
|
|
|
|
:key="key + '-column'"
|
|
|
|
|
v-for="(item, key) in tableStore.table.column"
|
|
|
|
|
:tree-node="item.treeNode"
|
|
|
|
|
>
|
2023-12-29 15:45:07 +08:00
|
|
|
<!-- tableStore 预设的列 render 方案 -->
|
2024-01-04 10:38:41 +08:00
|
|
|
<template v-if="item.render" #default="scope">
|
2025-11-14 09:33:35 +08:00
|
|
|
<FieldRender
|
|
|
|
|
:field="item"
|
|
|
|
|
:row="scope.row"
|
|
|
|
|
:column="scope.column"
|
|
|
|
|
:index="scope.rowIndex"
|
|
|
|
|
:key="
|
|
|
|
|
key +
|
|
|
|
|
'-' +
|
|
|
|
|
item.render +
|
|
|
|
|
'-' +
|
|
|
|
|
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
|
|
|
|
"
|
|
|
|
|
/>
|
2023-12-29 15:45:07 +08:00
|
|
|
</template>
|
|
|
|
|
</Column>
|
2024-01-04 10:38:41 +08:00
|
|
|
</template>
|
2024-01-15 16:14:14 +08:00
|
|
|
<slot name="columns"></slot>
|
2024-01-04 10:38:41 +08:00
|
|
|
</vxe-table>
|
|
|
|
|
</div>
|
2023-12-29 15:45:07 +08:00
|
|
|
|
2024-01-04 10:38:41 +08:00
|
|
|
<div v-if="tableStore.showPage" class="table-pagination">
|
2025-11-14 09:33:35 +08:00
|
|
|
<el-pagination
|
|
|
|
|
:currentPage="tableStore.table.params!.pageNum"
|
|
|
|
|
:page-size="tableStore.table.params!.pageSize"
|
|
|
|
|
:page-sizes="pageSizes"
|
|
|
|
|
background
|
2023-12-22 16:19:33 +08:00
|
|
|
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
2025-11-14 09:33:35 +08:00
|
|
|
:total="tableStore.table.total"
|
|
|
|
|
@size-change="onTableSizeChange"
|
|
|
|
|
@current-change="onTableCurrentChange"
|
|
|
|
|
></el-pagination>
|
2023-12-22 16:19:33 +08:00
|
|
|
</div>
|
2024-01-04 10:38:41 +08:00
|
|
|
<slot name="footer"></slot>
|
2023-12-22 16:19:33 +08:00
|
|
|
</template>
|
|
|
|
|
|
2024-01-04 10:38:41 +08:00
|
|
|
<script setup lang="ts">
|
2024-12-26 15:56:32 +08:00
|
|
|
import { ref, nextTick, inject, computed, onMounted, watch } from 'vue'
|
2024-01-18 18:19:59 +08:00
|
|
|
import type { ElTable } from 'element-plus'
|
2024-01-22 15:20:30 +08:00
|
|
|
import { VxeTableEvents, VxeTableInstance } from 'vxe-table'
|
2023-12-22 16:19:33 +08:00
|
|
|
import FieldRender from '@/components/table/fieldRender/index.vue'
|
|
|
|
|
import Column from '@/components/table/column/index.vue'
|
2024-04-01 18:29:32 +08:00
|
|
|
import GroupColumn from '@/components/table/column/groupColumn.vue'
|
2023-12-22 16:19:33 +08:00
|
|
|
import { useConfig } from '@/stores/config'
|
|
|
|
|
import type TableStoreClass from '@/utils/tableStore'
|
2024-12-26 15:56:32 +08:00
|
|
|
import { useRouter } from 'vue-router'
|
2024-01-02 14:33:55 +08:00
|
|
|
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
2023-12-22 16:19:33 +08:00
|
|
|
|
|
|
|
|
const config = useConfig()
|
2024-01-18 18:19:59 +08:00
|
|
|
const tableRef = ref<VxeTableInstance>()
|
2023-12-22 16:19:33 +08:00
|
|
|
const tableStore = inject('tableStore') as TableStoreClass
|
2024-12-26 15:56:32 +08:00
|
|
|
const router = useRouter()
|
2025-07-15 16:31:06 +08:00
|
|
|
const key = ref(0)
|
2023-12-22 16:19:33 +08:00
|
|
|
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
|
2023-12-29 15:45:07 +08:00
|
|
|
isGroup?: boolean
|
2024-12-26 15:56:32 +08:00
|
|
|
showOverflow?: boolean
|
2025-10-20 13:25:30 +08:00
|
|
|
height?: string | number
|
2023-12-22 16:19:33 +08:00
|
|
|
}
|
2023-12-29 15:45:07 +08:00
|
|
|
|
2023-12-22 16:19:33 +08:00
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
2024-12-26 15:56:32 +08:00
|
|
|
isGroup: false,
|
2025-10-20 13:25:30 +08:00
|
|
|
showOverflow: true,
|
|
|
|
|
height: undefined
|
2023-12-22 16:19:33 +08:00
|
|
|
})
|
2024-01-18 18:19:59 +08:00
|
|
|
onMounted(() => {
|
|
|
|
|
tableStore.table.ref = tableRef.value as VxeTableInstance
|
2025-11-14 15:00:10 +08:00
|
|
|
|
|
|
|
|
|
2024-01-18 18:19:59 +08:00
|
|
|
})
|
2024-04-01 18:29:32 +08:00
|
|
|
// console.log(props)
|
2023-12-22 16:19:33 +08:00
|
|
|
const onTableSizeChange = (val: number) => {
|
|
|
|
|
tableStore.onTableAction('page-size-change', { size: val })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const onTableCurrentChange = (val: number) => {
|
|
|
|
|
tableStore.onTableAction('current-page-change', { page: val })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const pageSizes = computed(() => {
|
2024-12-26 15:56:32 +08:00
|
|
|
let defaultSizes = [10, 20, 50, 100, 200]
|
2023-12-22 16:19:33 +08:00
|
|
|
if (tableStore.table.params!.pageSize) {
|
|
|
|
|
if (!defaultSizes.includes(tableStore.table.params!.pageSize)) {
|
|
|
|
|
defaultSizes.push(tableStore.table.params!.pageSize)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return defaultSizes
|
|
|
|
|
})
|
2025-07-15 16:31:06 +08:00
|
|
|
const handleSortChange = ({ field, order }: any) => {
|
|
|
|
|
// console.log('🚀 ~ handleSortChange ~ prop, order :', field, order)
|
|
|
|
|
if (field && order) {
|
|
|
|
|
// 根据当前排序条件对所有数据进行排序
|
|
|
|
|
const list = tableStore.table.copyData.sort((a, b) => {
|
|
|
|
|
if (order === 'asc') {
|
|
|
|
|
return a[field] > b[field] ? 1 : -1
|
|
|
|
|
} else {
|
|
|
|
|
return a[field] < b[field] ? 1 : -1
|
|
|
|
|
}
|
|
|
|
|
})
|
2025-10-20 13:25:30 +08:00
|
|
|
|
2025-07-15 16:31:06 +08:00
|
|
|
if (tableStore.isWebPaging) {
|
|
|
|
|
tableStore.table.data = JSON.parse(
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
window.XEUtils.chunk(list, tableStore.table.params!.pageSize)[tableStore.table.params!.pageNum - 1]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
tableStore.table.data = JSON.parse(JSON.stringify(list))
|
|
|
|
|
}
|
2023-12-22 16:19:33 +08:00
|
|
|
|
2025-07-15 16:31:06 +08:00
|
|
|
// key.value += 1
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-22 16:19:33 +08:00
|
|
|
/*
|
|
|
|
|
* 记录选择的项
|
|
|
|
|
*/
|
2024-01-22 15:20:30 +08:00
|
|
|
const selectChangeEvent: VxeTableEvents.CheckboxChange<any> = ({ checked }) => {
|
2024-04-01 18:29:32 +08:00
|
|
|
const records = (tableRef.value as VxeTableInstance).getCheckboxRecords()
|
|
|
|
|
tableStore.onTableAction('selection-change', records)
|
2023-12-22 16:19:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getRef = () => {
|
|
|
|
|
return tableRef.value
|
|
|
|
|
}
|
2024-12-26 15:56:32 +08:00
|
|
|
watch(
|
|
|
|
|
() => tableStore.table.allFlag,
|
|
|
|
|
newVal => {
|
|
|
|
|
if (tableStore.table.allFlag) {
|
2025-11-14 09:33:35 +08:00
|
|
|
console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
|
2025-10-20 13:25:30 +08:00
|
|
|
|
2024-12-26 15:56:32 +08:00
|
|
|
tableRef.value?.exportData({
|
2025-01-03 16:11:31 +08:00
|
|
|
filename: tableStore.exportName || document.querySelectorAll('.ba-nav-tab.active')[0].textContent || '', // 文件名字
|
2024-12-26 15:56:32 +08:00
|
|
|
sheetName: 'Sheet1',
|
|
|
|
|
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
|
|
|
|
useStyle: true,
|
|
|
|
|
data: tableStore.table.allData, // 数据源 // 过滤那个字段导出
|
|
|
|
|
columnFilterMethod: function (column: any) {
|
2025-07-15 16:31:06 +08:00
|
|
|
return !(
|
|
|
|
|
column.column.title === undefined ||
|
|
|
|
|
column.column.title === '序号' ||
|
|
|
|
|
column.column.title === '操作'
|
|
|
|
|
)
|
2024-12-26 15:56:32 +08:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
tableStore.table.allFlag = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
watch(
|
|
|
|
|
() => tableStore.table.data,
|
|
|
|
|
newVal => {
|
|
|
|
|
tableStore.onTableAction('selection-change', [])
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-12-22 16:19:33 +08:00
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
getRef
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
2024-01-04 10:38:41 +08:00
|
|
|
<style scoped lang="scss">
|
2023-12-22 16:19:33 +08:00
|
|
|
.ba-data-table :deep(.el-button + .el-button) {
|
|
|
|
|
margin-left: 6px;
|
|
|
|
|
}
|
2023-12-29 15:45:07 +08:00
|
|
|
|
2023-12-22 16:19:33 +08:00
|
|
|
.ba-data-table :deep(.table-header-cell) .cell {
|
|
|
|
|
color: var(--el-text-color-primary);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
2023-12-29 15:45:07 +08:00
|
|
|
|
2023-12-22 16:19:33 +08:00
|
|
|
.table-pagination {
|
2024-01-05 15:44:31 +08:00
|
|
|
height: 58px;
|
2023-12-22 16:19:33 +08:00
|
|
|
box-sizing: border-box;
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
background-color: var(--ba-bg-color-overlay);
|
|
|
|
|
padding: 13px 15px;
|
2024-01-15 10:36:24 +08:00
|
|
|
border-left: 1px solid #e4e7e9;
|
|
|
|
|
border-right: 1px solid #e4e7e9;
|
|
|
|
|
border-bottom: 1px solid #e4e7e9;
|
2023-12-22 16:19:33 +08:00
|
|
|
}
|
2024-04-01 18:29:32 +08:00
|
|
|
|
|
|
|
|
:deep(.el-pagination__sizes) {
|
|
|
|
|
.el-select {
|
|
|
|
|
min-width: 128px;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-22 16:19:33 +08:00
|
|
|
</style>
|
2024-04-01 18:29:32 +08:00
|
|
|
<!-- @/components/table/column/GroupColumn.vue@/components/table/column/GroupColumn.vue -->
|