azon_seeker/src/components/ResultTable.vue
2025-06-20 17:26:24 +08:00

97 lines
2.3 KiB
Vue

<script setup lang="ts">
const page = reactive({ current: 1, size: 10 });
export type TableColumn =
| {
title: string;
key: string;
minWidth?: number;
hidden?: boolean;
render?: (row: any) => VNode;
}
| {
type: 'expand';
hidden?: boolean;
expandable: (row: any) => boolean;
renderExpand: (row: any) => VNode;
};
const props = defineProps<{
records: Record<string, unknown>[];
columns: TableColumn[];
}>();
const itemView = computed(() => {
const { current, size } = page;
const data = props.records;
const pageCount = ~~(data.length / size) + (data.length % size > 0 ? 1 : 0);
const offset = (current - 1) * size;
if (data.length > 0 && offset >= data.length) {
page.current = 1;
}
const records = data.slice(offset, offset + size);
return { records, pageCount, origin: data };
});
function generateUUID() {
return crypto.randomUUID();
}
</script>
<template>
<div class="result-table">
<n-card class="result-content-container">
<template #header><slot name="header" /></template>
<template #header-extra><slot name="header-extra" /></template>
<n-empty v-if="itemView.records.length === 0" size="huge">
<template #icon>
<n-icon size="60">
<solar-cat-linear />
</n-icon>
</template>
<template #default>
<h3>还没有数据哦</h3>
</template>
</n-empty>
<n-space vertical v-else>
<n-data-table
:row-key="() => `${generateUUID()}`"
:columns="columns.filter((col) => col.hidden !== true)"
:data="itemView.records"
/>
<div class="data-pagination">
<n-pagination
v-model:page="page.current"
v-model:page-size="page.size"
:page-count="itemView.pageCount"
:page-sizes="[5, 10, 15, 20, 25]"
show-size-picker
/>
</div>
</n-space>
</n-card>
</div>
</template>
<style scoped lang="scss">
.result-table {
width: 100%;
height: 100%;
}
.result-content-container {
min-height: 100%;
:deep(.n-card__content:has(.n-empty)) {
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
}
}
.data-pagination {
display: flex;
flex-direction: row-reverse;
}
</style>