mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-09 20:57:17 +08:00
chore:优化文件管理分页
This commit is contained in:
@@ -3,11 +3,12 @@ import { useBreakpoint } from '@/hooks'
|
||||
|
||||
type Callback = () => void
|
||||
|
||||
type Options = {
|
||||
export type Options = {
|
||||
defaultPageSize: number
|
||||
defaultSizeOptions: number[]
|
||||
}
|
||||
|
||||
export function usePagination(callback: Callback, options: Options = { defaultPageSize: 10 }) {
|
||||
export function usePagination(callback: Callback, options: Options = { defaultPageSize: 10, defaultSizeOptions: [10, 20, 30, 40, 50] }) {
|
||||
const { breakpoint } = useBreakpoint()
|
||||
|
||||
const pagination = reactive({
|
||||
@@ -15,6 +16,7 @@ export function usePagination(callback: Callback, options: Options = { defaultPa
|
||||
showTotal: true,
|
||||
current: 1,
|
||||
pageSize: options.defaultPageSize,
|
||||
pageSizeOptions: options.defaultSizeOptions,
|
||||
total: 0,
|
||||
simple: false,
|
||||
onChange: (size: number) => {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import type { TableData, TableInstance } from '@arco-design/web-vue'
|
||||
import { Message, Modal } from '@arco-design/web-vue'
|
||||
import type { Options as paginationOptions } from './usePagination'
|
||||
import { usePagination } from '@/hooks'
|
||||
|
||||
interface Options<T> {
|
||||
@@ -7,6 +8,7 @@ interface Options<T> {
|
||||
onSuccess?: () => void
|
||||
immediate?: boolean
|
||||
rowKey?: keyof T
|
||||
paginationOption: paginationOptions
|
||||
}
|
||||
|
||||
type PaginationParams = { page: number, size: number }
|
||||
@@ -14,7 +16,7 @@ type Api<T> = (params: PaginationParams) => Promise<ApiRes<PageRes<T[]>>> | Prom
|
||||
|
||||
export function useTable<T>(api: Api<T>, options?: Options<T>) {
|
||||
const { formatResult, onSuccess, immediate, rowKey } = options || {}
|
||||
const { pagination, setTotal } = usePagination(() => getTableData())
|
||||
const { pagination, setTotal } = usePagination(() => getTableData(), options?.paginationOption)
|
||||
const loading = ref(false)
|
||||
const tableData = ref<T[]>([])
|
||||
|
||||
|
@@ -17,13 +17,7 @@
|
||||
</a-dropdown>
|
||||
|
||||
<a-input-group>
|
||||
<a-input
|
||||
v-model="queryForm.name"
|
||||
placeholder="请输入文件名"
|
||||
allow-clear
|
||||
style="width: 200px"
|
||||
@change="search"
|
||||
/>
|
||||
<a-input v-model="queryForm.name" placeholder="请输入文件名" allow-clear style="width: 200px" @change="search" />
|
||||
<a-button type="primary" @click="search">
|
||||
<template #icon>
|
||||
<icon-search />
|
||||
@@ -35,13 +29,8 @@
|
||||
|
||||
<!-- 右侧区域 -->
|
||||
<a-space wrap>
|
||||
<a-button
|
||||
v-if="isBatchMode"
|
||||
:disabled="!selectedFileIds.length"
|
||||
type="primary"
|
||||
status="danger"
|
||||
@click="handleMulDelete"
|
||||
>
|
||||
<a-button v-if="isBatchMode" :disabled="!selectedFileIds.length" type="primary" status="danger"
|
||||
@click="handleMulDelete">
|
||||
<template #icon>
|
||||
<icon-delete />
|
||||
</template>
|
||||
@@ -67,29 +56,20 @@
|
||||
|
||||
<!-- 文件列表-宫格模式 -->
|
||||
<a-spin id="fileMain" class="file-main__list" :loading="loading" @scroll="handleScroll">
|
||||
<FileGrid
|
||||
v-show="fileList.length && mode === 'grid'"
|
||||
:data="fileList"
|
||||
:is-batch-mode="isBatchMode"
|
||||
:selected-file-ids="selectedFileIds"
|
||||
@click="handleClickFile"
|
||||
@select="handleSelectFile"
|
||||
@right-menu-click="handleRightMenuClick"
|
||||
></FileGrid>
|
||||
<FileGrid v-show="fileList.length && mode === 'grid'" :data="fileList" :is-batch-mode="isBatchMode"
|
||||
:selected-file-ids="selectedFileIds" @click="handleClickFile" @select="handleSelectFile"
|
||||
@right-menu-click="handleRightMenuClick"></FileGrid>
|
||||
|
||||
<!-- 文件列表-列表模式 -->
|
||||
<FileList
|
||||
v-show="fileList.length && mode === 'list'"
|
||||
:data="fileList"
|
||||
:is-batch-mode="isBatchMode"
|
||||
:selected-file-ids="selectedFileIds"
|
||||
@click="handleClickFile"
|
||||
@select="handleSelectFile"
|
||||
@right-menu-click="handleRightMenuClick"
|
||||
></FileList>
|
||||
<FileList v-show="fileList.length && mode === 'list'" :data="fileList" :is-batch-mode="isBatchMode"
|
||||
:selected-file-ids="selectedFileIds" @click="handleClickFile" @select="handleSelectFile"
|
||||
@right-menu-click="handleRightMenuClick"></FileList>
|
||||
|
||||
<a-empty v-show="!fileList.length"></a-empty>
|
||||
</a-spin>
|
||||
<div class="pagination">
|
||||
<a-pagination v-bind="pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -104,6 +84,7 @@ import {
|
||||
} from '../../components/index'
|
||||
import FileGrid from './FileGrid.vue'
|
||||
import useFileManage from './useFileManage'
|
||||
import { useTable } from '@/hooks'
|
||||
import { type FileItem, type FilePageQuery, type FileQuery, deleteFile, listFile, uploadFile } from '@/apis'
|
||||
import { ImageTypes } from '@/constant/file'
|
||||
import 'viewerjs/dist/viewer.css'
|
||||
@@ -118,48 +99,17 @@ const queryForm = reactive<FileQuery>({
|
||||
type: route.query.type?.toString() || undefined,
|
||||
sort: ['updateTime,desc']
|
||||
})
|
||||
const pagination = reactive({
|
||||
page: 1,
|
||||
size: 30
|
||||
const paginationOption = reactive({
|
||||
defaultPageSize: 30,
|
||||
defaultSizeOptions: [30, 40, 50, 100, 120]
|
||||
})
|
||||
|
||||
const fileList = ref<FileItem[]>([])
|
||||
const isBatchMode = ref(false)
|
||||
const loading = ref(false)
|
||||
const timer = ref<any>()
|
||||
// 查询文件列表
|
||||
const getFileList = async (query: FilePageQuery = { ...queryForm, page: pagination.page, size: pagination.size }) => {
|
||||
try {
|
||||
loading.value = true
|
||||
isBatchMode.value = false
|
||||
query.type = query.type === '0' ? undefined : query.type
|
||||
const res = await listFile(query)
|
||||
if (res.data.list) {
|
||||
if (query.page === 1) {
|
||||
fileList.value = res.data.list
|
||||
timer.value = setTimeout(() => {
|
||||
clearTimeout(timer.value)
|
||||
timer.value = null
|
||||
}, 1000)
|
||||
} else {
|
||||
fileList.value = [...fileList.value, ...res.data.list]
|
||||
}
|
||||
} else {
|
||||
--pagination.page
|
||||
}
|
||||
} catch (error) {
|
||||
--pagination.page
|
||||
return error
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查询
|
||||
const search = () => {
|
||||
pagination.page = 1
|
||||
getFileList()
|
||||
}
|
||||
const {
|
||||
tableData: fileList,
|
||||
loading,
|
||||
pagination,
|
||||
search
|
||||
} = useTable((page) => listFile({ ...queryForm, ...page }), { immediate: false, paginationOption })
|
||||
|
||||
// 点击文件
|
||||
const handleClickFile = (item: FileItem) => {
|
||||
@@ -257,30 +207,6 @@ const handleUpload = (options: RequestOption) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleScroll = (event) => {
|
||||
const { clientHeight, scrollHeight, scrollTop } = event.target
|
||||
const scrollLinerHeight = (clientHeight / scrollHeight) * scrollHeight
|
||||
if (!timer.value) {
|
||||
timer.value = setTimeout(() => {
|
||||
if ((scrollTop + scrollLinerHeight) / scrollHeight >= 0.9 && !loading.value) {
|
||||
++pagination.page
|
||||
getFileList()
|
||||
}
|
||||
timer.value = null
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const fileMainDom = document.getElementById('fileMain')
|
||||
fileMainDom.addEventListener('scrool', handleScroll)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
// 移除事件监听
|
||||
const fileMainDom = document.getElementById('fileMain')
|
||||
fileMainDom.removeEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
onBeforeRouteUpdate((to) => {
|
||||
if (!to.query.type) return
|
||||
queryForm.type = to.query.type?.toString()
|
||||
@@ -315,5 +241,13 @@ onMounted(() => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 10px 0;
|
||||
|
||||
:deep(.arco-pagination) {
|
||||
justify-content: end;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user