debug(file-management): 添加分页调试信息以排查分页问题
This commit is contained in:
parent
844525625e
commit
0631b4dd1d
@ -1,5 +1,5 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="https://s2.loli.net/2023/10/27/WzQ4JLNV5epKh6X.png" style="width:150px"/>
|
<img src="https://gaoziman.oss-cn-hangzhou.aliyuncs.com/uPic/2025-07-09-%E7%94%B0%E5%9B%AD%E7%8A%AC.svg" style="width:150px"/>
|
||||||
<h1>🚀 Coi Admin</h1>
|
<h1>🚀 Coi Admin</h1>
|
||||||
<p>A Modern Admin Dashboard Template Based on Vue3 + Vite + TypeScript + Naive UI</p>
|
<p>A Modern Admin Dashboard Template Based on Vue3 + Vite + TypeScript + Naive UI</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="https://s2.loli.net/2023/10/27/WzQ4JLNV5epKh6X.png" style="width:150px"/>
|
<img src="https://gaoziman.oss-cn-hangzhou.aliyuncs.com/uPic/2025-07-09-%E7%94%B0%E5%9B%AD%E7%8A%AC.svg" style="width:150px"/>
|
||||||
<h1>🚀 Coi Admin</h1>
|
<h1>🚀 Coi Admin</h1>
|
||||||
<p>基于 Vue3 + Vite + TypeScript + Naive UI 的现代化后台管理系统</p>
|
<p>基于 Vue3 + Vite + TypeScript + Naive UI 的现代化后台管理系统</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
472
src/components/common/CoiPagination.vue
Normal file
472
src/components/common/CoiPagination.vue
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
<template>
|
||||||
|
<div class="coi-pagination">
|
||||||
|
<div class="coi-pagination__container">
|
||||||
|
<!-- 数据统计信息 -->
|
||||||
|
<div class="coi-pagination__info">
|
||||||
|
<span class="coi-pagination__text">共 {{ itemCount }} 条</span>
|
||||||
|
<span v-if="showCurrentInfo" class="coi-pagination__text">
|
||||||
|
当前第 {{ (currentPage - 1) * pageSize + 1 }} - {{ Math.min(currentPage * pageSize, itemCount) }} 条
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页器容器 -->
|
||||||
|
<div class="coi-pagination__controls">
|
||||||
|
<!-- 每页显示数量选择器 -->
|
||||||
|
<div v-if="showSizePicker" class="coi-pagination__size-picker">
|
||||||
|
<span class="coi-pagination__size-label">每页</span>
|
||||||
|
<NSelect
|
||||||
|
v-model:value="internalPageSize"
|
||||||
|
:options="pageSizeOptions"
|
||||||
|
size="small"
|
||||||
|
class="coi-pagination__size-select"
|
||||||
|
@update:value="handlePageSizeChange"
|
||||||
|
/>
|
||||||
|
<span class="coi-pagination__size-label">条</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页控件 -->
|
||||||
|
<div class="coi-pagination__pager">
|
||||||
|
<!-- 首页按钮 -->
|
||||||
|
<button
|
||||||
|
:disabled="currentPage === 1"
|
||||||
|
class="coi-pagination__button coi-pagination__button--first"
|
||||||
|
@click="handlePageChange(1)"
|
||||||
|
>
|
||||||
|
<NIcon size="14">
|
||||||
|
<icon-park-outline:go-start />
|
||||||
|
</NIcon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 上一页按钮 -->
|
||||||
|
<button
|
||||||
|
:disabled="currentPage === 1"
|
||||||
|
class="coi-pagination__button coi-pagination__button--prev"
|
||||||
|
@click="handlePageChange(currentPage - 1)"
|
||||||
|
>
|
||||||
|
<NIcon size="14">
|
||||||
|
<icon-park-outline:left />
|
||||||
|
</NIcon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 页码按钮 -->
|
||||||
|
<div class="coi-pagination__pages">
|
||||||
|
<template v-for="pageNumber in visiblePages" :key="pageNumber">
|
||||||
|
<!-- 省略号 -->
|
||||||
|
<span v-if="pageNumber < 0" class="coi-pagination__ellipsis">
|
||||||
|
...
|
||||||
|
</span>
|
||||||
|
<!-- 正常页码按钮 -->
|
||||||
|
<button
|
||||||
|
v-else
|
||||||
|
class="coi-pagination__button coi-pagination__button--page"
|
||||||
|
:class="{ 'coi-pagination__button--active': pageNumber === currentPage }"
|
||||||
|
@click="handlePageChange(pageNumber)"
|
||||||
|
>
|
||||||
|
{{ pageNumber }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 下一页按钮 -->
|
||||||
|
<button
|
||||||
|
:disabled="currentPage === totalPages"
|
||||||
|
class="coi-pagination__button coi-pagination__button--next"
|
||||||
|
@click="handlePageChange(currentPage + 1)"
|
||||||
|
>
|
||||||
|
<NIcon size="14">
|
||||||
|
<icon-park-outline:right />
|
||||||
|
</NIcon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 尾页按钮 -->
|
||||||
|
<button
|
||||||
|
:disabled="currentPage === totalPages"
|
||||||
|
class="coi-pagination__button coi-pagination__button--last"
|
||||||
|
@click="handlePageChange(totalPages)"
|
||||||
|
>
|
||||||
|
<NIcon size="14">
|
||||||
|
<icon-park-outline:go-end />
|
||||||
|
</NIcon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 快速跳转 -->
|
||||||
|
<div v-if="showQuickJumper" class="coi-pagination__jumper">
|
||||||
|
<span class="coi-pagination__jumper-label">跳至</span>
|
||||||
|
<NInput
|
||||||
|
v-model:value="jumpValue"
|
||||||
|
size="small"
|
||||||
|
type="number"
|
||||||
|
class="coi-pagination__jumper-input"
|
||||||
|
:min="1"
|
||||||
|
:max="totalPages"
|
||||||
|
@keydown.enter="handleQuickJump"
|
||||||
|
@blur="handleQuickJump"
|
||||||
|
/>
|
||||||
|
<span class="coi-pagination__jumper-label">页</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { NIcon, NInput, NSelect } from 'naive-ui'
|
||||||
|
import { useAppStore } from '@/store'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** 当前页码 */
|
||||||
|
page?: number
|
||||||
|
/** 每页显示数量 */
|
||||||
|
pageSize?: number
|
||||||
|
/** 总条数 */
|
||||||
|
itemCount: number
|
||||||
|
/** 是否显示每页数量选择器 */
|
||||||
|
showSizePicker?: boolean
|
||||||
|
/** 每页数量选项 */
|
||||||
|
pageSizes?: number[]
|
||||||
|
/** 是否显示快速跳转 */
|
||||||
|
showQuickJumper?: boolean
|
||||||
|
/** 是否显示当前数据范围信息 */
|
||||||
|
showCurrentInfo?: boolean
|
||||||
|
/** 分页器尺寸 */
|
||||||
|
size?: 'small' | 'medium' | 'large'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(event: 'update:page', page: number): void
|
||||||
|
(event: 'update:pageSize', pageSize: number): void
|
||||||
|
(event: 'pageChange', page: number): void
|
||||||
|
(event: 'pageSizeChange', pageSize: number): void
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
showSizePicker: true,
|
||||||
|
pageSizes: () => [10, 20, 50, 100],
|
||||||
|
showQuickJumper: true,
|
||||||
|
showCurrentInfo: false,
|
||||||
|
size: 'medium',
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>()
|
||||||
|
|
||||||
|
// 获取应用store以访问主题色
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
// 获取主题色
|
||||||
|
const primaryColor = computed(() => appStore.primaryColor)
|
||||||
|
const primaryColorHover = computed(() => appStore.theme.common.primaryColorHover)
|
||||||
|
|
||||||
|
// 内部状态
|
||||||
|
const internalPage = ref(props.page)
|
||||||
|
const internalPageSize = ref(props.pageSize)
|
||||||
|
const jumpValue = ref('')
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const currentPage = computed(() => internalPage.value)
|
||||||
|
const totalPages = computed(() => Math.ceil(props.itemCount / internalPageSize.value))
|
||||||
|
|
||||||
|
// 每页数量选项
|
||||||
|
const pageSizeOptions = computed(() => {
|
||||||
|
return props.pageSizes.map(size => ({
|
||||||
|
label: `${size} 条/页`,
|
||||||
|
value: size,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
// 可见页码
|
||||||
|
const visiblePages = computed(() => {
|
||||||
|
const pages: number[] = []
|
||||||
|
const total = totalPages.value
|
||||||
|
const current = currentPage.value
|
||||||
|
|
||||||
|
if (total <= 0) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total <= 7) {
|
||||||
|
// 总页数少于等于7页,显示所有页码(包括只有1页的情况)
|
||||||
|
for (let i = 1; i <= total; i++) {
|
||||||
|
pages.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 总页数大于7页,使用省略号逻辑
|
||||||
|
if (current <= 4) {
|
||||||
|
// 当前页在前4页:1, 2, 3, 4, 5, ..., total
|
||||||
|
for (let i = 1; i <= 5; i++) {
|
||||||
|
pages.push(i)
|
||||||
|
}
|
||||||
|
if (total > 6) {
|
||||||
|
pages.push(-1) // 省略号
|
||||||
|
pages.push(total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (current >= total - 3) {
|
||||||
|
// 当前页在后4页:1, ..., total-4, total-3, total-2, total-1, total
|
||||||
|
pages.push(1)
|
||||||
|
if (total > 6) {
|
||||||
|
pages.push(-1) // 省略号
|
||||||
|
}
|
||||||
|
for (let i = Math.max(2, total - 4); i <= total; i++) {
|
||||||
|
pages.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 当前页在中间:1, ..., current-1, current, current+1, ..., total
|
||||||
|
pages.push(1)
|
||||||
|
pages.push(-1) // 省略号
|
||||||
|
for (let i = current - 1; i <= current + 1; i++) {
|
||||||
|
pages.push(i)
|
||||||
|
}
|
||||||
|
pages.push(-2) // 省略号
|
||||||
|
pages.push(total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听props变化
|
||||||
|
watch(() => props.page, (newPage) => {
|
||||||
|
internalPage.value = newPage
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => props.pageSize, (newPageSize) => {
|
||||||
|
internalPageSize.value = newPageSize
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理页码变化
|
||||||
|
function handlePageChange(page: number) {
|
||||||
|
if (page < 1 || page > totalPages.value || page === currentPage.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
internalPage.value = page
|
||||||
|
emit('update:page', page)
|
||||||
|
emit('pageChange', page)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理每页数量变化
|
||||||
|
function handlePageSizeChange(pageSize: number) {
|
||||||
|
if (pageSize === internalPageSize.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
internalPageSize.value = pageSize
|
||||||
|
|
||||||
|
// 调整当前页码,确保不超出范围
|
||||||
|
const newTotalPages = Math.ceil(props.itemCount / pageSize)
|
||||||
|
if (currentPage.value > newTotalPages) {
|
||||||
|
internalPage.value = newTotalPages
|
||||||
|
emit('update:page', newTotalPages)
|
||||||
|
emit('pageChange', newTotalPages)
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:pageSize', pageSize)
|
||||||
|
emit('pageSizeChange', pageSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理快速跳转
|
||||||
|
function handleQuickJump() {
|
||||||
|
const page = Number.parseInt(jumpValue.value)
|
||||||
|
if (Number.isNaN(page) || page < 1 || page > totalPages.value) {
|
||||||
|
jumpValue.value = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePageChange(page)
|
||||||
|
jumpValue.value = ''
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.coi-pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 0;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
color: var(--text-color-3);
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__text {
|
||||||
|
color: var(--text-color-3);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__size-picker {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__size-label {
|
||||||
|
color: var(--text-color-2);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__size-select {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__pager {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__pages {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__ellipsis {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
color: var(--text-color-3);
|
||||||
|
font-size: 14px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--card-color);
|
||||||
|
color: var(--text-color-1);
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button:hover:not(:disabled) {
|
||||||
|
border-color: v-bind(primaryColor);
|
||||||
|
color: v-bind(primaryColor);
|
||||||
|
background: v-bind(`${primaryColor}15`);
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
background: var(--card-color);
|
||||||
|
color: var(--text-color-3);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button--active {
|
||||||
|
border-color: v-bind(primaryColor) !important;
|
||||||
|
background-color: v-bind(primaryColor) !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button--active:hover {
|
||||||
|
border-color: v-bind(primaryColorHover) !important;
|
||||||
|
background-color: v-bind(primaryColorHover) !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button--first,
|
||||||
|
.coi-pagination__button--prev,
|
||||||
|
.coi-pagination__button--next,
|
||||||
|
.coi-pagination__button--last {
|
||||||
|
min-width: 32px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__jumper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__jumper-label {
|
||||||
|
color: var(--text-color-2);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__jumper-input {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 深色主题适配 */
|
||||||
|
.coi-pagination :deep(.n-select) {
|
||||||
|
--n-color: var(--card-color);
|
||||||
|
--n-color-hover: var(--card-color);
|
||||||
|
--n-border-color: var(--border-color);
|
||||||
|
--n-border-color-hover: v-bind(primaryColor);
|
||||||
|
--n-border-color-focus: v-bind(primaryColor);
|
||||||
|
--n-text-color: var(--text-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination :deep(.n-input) {
|
||||||
|
--n-color: var(--card-color);
|
||||||
|
--n-color-focus: var(--card-color);
|
||||||
|
--n-border-color: var(--border-color);
|
||||||
|
--n-border-color-hover: v-bind(primaryColor);
|
||||||
|
--n-border-color-focus: v-bind(primaryColor);
|
||||||
|
--n-text-color: var(--text-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.coi-pagination__container {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__controls {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__pager {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coi-pagination__button {
|
||||||
|
min-width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<n-pagination
|
|
||||||
v-if="count > 0"
|
|
||||||
v-model:page="page"
|
|
||||||
v-model:page-size="pageSize"
|
|
||||||
:page-sizes="[10, 20, 30, 50]"
|
|
||||||
:item-count="count"
|
|
||||||
:display-order="displayOrder"
|
|
||||||
show-size-picker
|
|
||||||
@update-page="changePage"
|
|
||||||
@update-page-size="changePage"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
interface Props {
|
|
||||||
count?: number
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
count = 0,
|
|
||||||
} = defineProps<Props>()
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
change: [page: number, pageSize: number] // 具名元组语法
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const page = ref(1)
|
|
||||||
const pageSize = ref(10)
|
|
||||||
const displayOrder: Array<'pages' | 'size-picker' | 'quick-jumper'> = ['size-picker', 'pages']
|
|
||||||
|
|
||||||
function changePage() {
|
|
||||||
emit('change', page.value, pageSize.value)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
@ -172,20 +172,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 调试信息:显示当前分页状态 -->
|
||||||
|
<div class="text-xs text-gray-500 p-2 border-t">
|
||||||
|
🔧 调试信息 - 当前分页状态: Page={{ pagination.page }}, PageSize={{ pagination.pageSize }}, ItemCount={{ pagination.itemCount }}, DataLength={{ tableData.length }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -303,6 +306,7 @@ import { h, onMounted, ref } from 'vue'
|
|||||||
import { NButton, NIcon, NImage, NP, NPopconfirm, NSpace, NTag, NText, NUpload, NUploadDragger } from 'naive-ui'
|
import { NButton, NIcon, NImage, NP, NPopconfirm, NSpace, NTag, NText, NUpload, NUploadDragger } from 'naive-ui'
|
||||||
import type { DataTableColumns, DataTableInst, FormInst, UploadFileInfo, UploadInst } from 'naive-ui'
|
import type { DataTableColumns, DataTableInst, FormInst, UploadFileInfo, UploadInst } from 'naive-ui'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import { coiMsgBox, coiMsgError, coiMsgSuccess, coiMsgWarning } from '@/utils/coi'
|
import { coiMsgBox, coiMsgError, coiMsgSuccess, coiMsgWarning } from '@/utils/coi'
|
||||||
import { usePermission } from '@/hooks/usePermission'
|
import { usePermission } from '@/hooks/usePermission'
|
||||||
import { PERMISSIONS } from '@/constants/permissions'
|
import { PERMISSIONS } from '@/constants/permissions'
|
||||||
@ -390,6 +394,13 @@ const pagination = ref({
|
|||||||
itemCount: 0,
|
itemCount: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 调试信息:输出初始分页设置
|
||||||
|
console.warn('🚀 分页初始化设置:', {
|
||||||
|
initialPage: pagination.value.page,
|
||||||
|
initialPageSize: pagination.value.pageSize,
|
||||||
|
initialItemCount: pagination.value.itemCount,
|
||||||
|
})
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns: DataTableColumns<SysFileVo> = [
|
const columns: DataTableColumns<SysFileVo> = [
|
||||||
{
|
{
|
||||||
@ -562,10 +573,25 @@ async function fetchData() {
|
|||||||
fileType: selectedCategory.value === '0' ? undefined : selectedCategory.value,
|
fileType: selectedCategory.value === '0' ? undefined : selectedCategory.value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 调试信息:输出请求参数
|
||||||
|
console.warn('🔍 fetchData 请求参数:', {
|
||||||
|
page: pagination.value.page,
|
||||||
|
pageSize: pagination.value.pageSize,
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
const { data } = await getSysFileList(params)
|
const { data } = await getSysFileList(params)
|
||||||
if (data) {
|
if (data) {
|
||||||
tableData.value = data.records
|
tableData.value = data.records
|
||||||
pagination.value.itemCount = data.total
|
pagination.value.itemCount = data.total
|
||||||
|
|
||||||
|
// 调试信息:输出返回数据
|
||||||
|
console.warn('📊 fetchData 返回数据:', {
|
||||||
|
requestedPageSize: pagination.value.pageSize,
|
||||||
|
actualDataLength: data.records.length,
|
||||||
|
totalCount: data.total,
|
||||||
|
currentPage: pagination.value.page,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
@ -606,8 +632,20 @@ function handlePageChange(page: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handlePageSizeChange(pageSize: number) {
|
function handlePageSizeChange(pageSize: number) {
|
||||||
|
console.warn('🔄 handlePageSizeChange 触发:', {
|
||||||
|
oldPageSize: pagination.value.pageSize,
|
||||||
|
newPageSize: pageSize,
|
||||||
|
currentPage: pagination.value.page,
|
||||||
|
})
|
||||||
|
|
||||||
pagination.value.pageSize = pageSize
|
pagination.value.pageSize = pageSize
|
||||||
pagination.value.page = 1
|
pagination.value.page = 1
|
||||||
|
|
||||||
|
console.warn('✅ handlePageSizeChange 更新后:', {
|
||||||
|
updatedPageSize: pagination.value.pageSize,
|
||||||
|
resetPage: pagination.value.page,
|
||||||
|
})
|
||||||
|
|
||||||
fetchData()
|
fetchData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -179,17 +179,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -204,6 +202,7 @@ import type { DataTableColumns, FormInst } from 'naive-ui'
|
|||||||
import { NButton, NIcon, NPopconfirm, NSpace, NTag } from 'naive-ui'
|
import { NButton, NIcon, NPopconfirm, NSpace, NTag } from 'naive-ui'
|
||||||
import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
|
import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import {
|
import {
|
||||||
batchDeleteLoginLog,
|
batchDeleteLoginLog,
|
||||||
deleteLoginLog,
|
deleteLoginLog,
|
||||||
|
|||||||
@ -193,17 +193,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -265,6 +263,7 @@ import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
|
|||||||
import IconParkOutlinePreviewOpen from '~icons/icon-park-outline/preview-open'
|
import IconParkOutlinePreviewOpen from '~icons/icon-park-outline/preview-open'
|
||||||
import CoiDialog from '@/components/common/CoiDialog.vue'
|
import CoiDialog from '@/components/common/CoiDialog.vue'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import {
|
import {
|
||||||
batchDeleteOperLog,
|
batchDeleteOperLog,
|
||||||
clearOperLog,
|
clearOperLog,
|
||||||
|
|||||||
@ -290,17 +290,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[12, 24, 48, 96]"
|
:page-sizes="[12, 24, 48, 96]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -409,6 +407,7 @@ import { NButton, NIcon, NImage, NP, NPopconfirm, NSpace, NSpin, NTag, NText, NT
|
|||||||
import type { DataTableColumns, DataTableInst, FormInst, UploadFileInfo, UploadInst } from 'naive-ui'
|
import type { DataTableColumns, DataTableInst, FormInst, UploadFileInfo, UploadInst } from 'naive-ui'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
import CoiDialog from '@/components/common/CoiDialog.vue'
|
import CoiDialog from '@/components/common/CoiDialog.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import { coiMsgBox, coiMsgError, coiMsgSuccess, coiMsgWarning } from '@/utils/coi'
|
import { coiMsgBox, coiMsgError, coiMsgSuccess, coiMsgWarning } from '@/utils/coi'
|
||||||
import { usePermission } from '@/hooks/usePermission'
|
import { usePermission } from '@/hooks/usePermission'
|
||||||
import { PERMISSIONS } from '@/constants/permissions'
|
import { PERMISSIONS } from '@/constants/permissions'
|
||||||
|
|||||||
@ -208,17 +208,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -428,6 +426,7 @@ import IconParkOutlineDelete from '~icons/icon-park-outline/delete'
|
|||||||
import IconParkOutlineKey from '~icons/icon-park-outline/key'
|
import IconParkOutlineKey from '~icons/icon-park-outline/key'
|
||||||
import CoiDialog from '@/components/common/CoiDialog.vue'
|
import CoiDialog from '@/components/common/CoiDialog.vue'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import {
|
import {
|
||||||
addRole,
|
addRole,
|
||||||
batchDeleteRoles,
|
batchDeleteRoles,
|
||||||
|
|||||||
@ -252,17 +252,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页器 -->
|
<!-- 分页器 -->
|
||||||
<div v-if="tableData.length > 0" class="flex items-center px-4 py-2 border-t border-gray-100">
|
<div v-if="tableData.length > 0" class="border-t border-gray-100">
|
||||||
<div class="text-sm text-gray-500 mr-4">
|
<CoiPagination
|
||||||
共 {{ pagination.itemCount }} 条
|
|
||||||
</div>
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="pagination.page"
|
v-model:page="pagination.page"
|
||||||
v-model:page-size="pagination.pageSize"
|
v-model:page-size="pagination.pageSize"
|
||||||
:item-count="pagination.itemCount"
|
:item-count="pagination.itemCount"
|
||||||
:show-size-picker="true"
|
:show-size-picker="true"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
show-quick-jumper
|
:show-quick-jumper="true"
|
||||||
|
:show-current-info="true"
|
||||||
@update:page="handlePageChange"
|
@update:page="handlePageChange"
|
||||||
@update:page-size="handlePageSizeChange"
|
@update:page-size="handlePageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -716,6 +714,7 @@ import IconParkOutlineDownloadOne from '~icons/icon-park-outline/download-one'
|
|||||||
import IconParkOutlineFileCodeOne from '~icons/icon-park-outline/file-code-one'
|
import IconParkOutlineFileCodeOne from '~icons/icon-park-outline/file-code-one'
|
||||||
import CoiDialog from '@/components/common/CoiDialog.vue'
|
import CoiDialog from '@/components/common/CoiDialog.vue'
|
||||||
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
import CoiEmpty from '@/components/common/CoiEmpty.vue'
|
||||||
|
import CoiPagination from '@/components/common/CoiPagination.vue'
|
||||||
import {
|
import {
|
||||||
addUser,
|
addUser,
|
||||||
batchDeleteUsers,
|
batchDeleteUsers,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user