fix(fe): 修复表格分页和基础功能问题
修复的主要问题: 1. **分页切换失效**(AccountsView.vue) - 修复 useTableLoader 未解构 handlePageSizeChange 函数 - 添加 @update:pageSize 事件绑定到 Pagination 组件 2. **内存泄漏修复**(多个文件) - UsersView.vue: 添加 searchTimeout 清理和 abortController.abort() - ProxiesView.vue: 添加 onUnmounted 钩子清理定时器 - RedeemView.vue: 添加 onUnmounted 钩子清理定时器 3. **分页重置问题**(UsersView.vue) - toggleBuiltInFilter: 切换筛选器时重置 pagination.page = 1 - toggleAttributeFilter: 切换属性筛选时重置 pagination.page = 1 影响范围: - frontend/src/views/admin/AccountsView.vue - frontend/src/views/admin/ProxiesView.vue - frontend/src/views/admin/RedeemView.vue - frontend/src/views/admin/UsersView.vue 测试:✓ 前端构建测试通过
This commit is contained in:
@@ -107,7 +107,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</template>
|
</template>
|
||||||
<template #pagination><Pagination v-if="pagination.total > 0" :page="pagination.page" :total="pagination.total" :page-size="pagination.page_size" @update:page="handlePageChange" /></template>
|
<template #pagination><Pagination v-if="pagination.total > 0" :page="pagination.page" :total="pagination.total" :page-size="pagination.page_size" @update:page="handlePageChange" @update:pageSize="handlePageSizeChange" /></template>
|
||||||
</TablePageLayout>
|
</TablePageLayout>
|
||||||
<CreateAccountModal :show="showCreate" :proxies="proxies" :groups="groups" @close="showCreate = false" @created="reload" />
|
<CreateAccountModal :show="showCreate" :proxies="proxies" :groups="groups" @close="showCreate = false" @created="reload" />
|
||||||
<EditAccountModal :show="showEdit" :account="edAcc" :proxies="proxies" :groups="groups" @close="showEdit = false" @updated="load" />
|
<EditAccountModal :show="showEdit" :account="edAcc" :proxies="proxies" :groups="groups" @close="showEdit = false" @updated="load" />
|
||||||
@@ -175,7 +175,7 @@ const statsAcc = ref<Account | null>(null)
|
|||||||
const togglingSchedulable = ref<number | null>(null)
|
const togglingSchedulable = ref<number | null>(null)
|
||||||
const menu = reactive<{show:boolean, acc:Account|null, pos:{top:number, left:number}|null}>({ show: false, acc: null, pos: null })
|
const menu = reactive<{show:boolean, acc:Account|null, pos:{top:number, left:number}|null}>({ show: false, acc: null, pos: null })
|
||||||
|
|
||||||
const { items: accounts, loading, params, pagination, load, reload, debouncedReload, handlePageChange } = useTableLoader<Account, any>({
|
const { items: accounts, loading, params, pagination, load, reload, debouncedReload, handlePageChange, handlePageSizeChange } = useTableLoader<Account, any>({
|
||||||
fetchFn: adminAPI.accounts.list,
|
fetchFn: adminAPI.accounts.list,
|
||||||
initialParams: { platform: '', type: '', status: '', search: '' }
|
initialParams: { platform: '', type: '', status: '', search: '' }
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -519,7 +519,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, onMounted } from 'vue'
|
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
import { adminAPI } from '@/api/admin'
|
import { adminAPI } from '@/api/admin'
|
||||||
@@ -942,4 +942,9 @@ const confirmDelete = async () => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadProxies()
|
loadProxies()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimeout(searchTimeout)
|
||||||
|
abortController?.abort()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -364,7 +364,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, onMounted } from 'vue'
|
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
import { useClipboard } from '@/composables/useClipboard'
|
import { useClipboard } from '@/composables/useClipboard'
|
||||||
@@ -693,4 +693,9 @@ onMounted(() => {
|
|||||||
loadCodes()
|
loadCodes()
|
||||||
loadSubscriptionGroups()
|
loadSubscriptionGroups()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimeout(searchTimeout)
|
||||||
|
abortController?.abort()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -943,6 +943,7 @@ const toggleBuiltInFilter = (key: string) => {
|
|||||||
visibleFilters.add(key)
|
visibleFilters.add(key)
|
||||||
}
|
}
|
||||||
saveFiltersToStorage()
|
saveFiltersToStorage()
|
||||||
|
pagination.page = 1
|
||||||
loadUsers()
|
loadUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,6 +958,7 @@ const toggleAttributeFilter = (attr: UserAttributeDefinition) => {
|
|||||||
activeAttributeFilters[attr.id] = ''
|
activeAttributeFilters[attr.id] = ''
|
||||||
}
|
}
|
||||||
saveFiltersToStorage()
|
saveFiltersToStorage()
|
||||||
|
pagination.page = 1
|
||||||
loadUsers()
|
loadUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,5 +1061,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
document.removeEventListener('click', handleClickOutside)
|
document.removeEventListener('click', handleClickOutside)
|
||||||
|
clearTimeout(searchTimeout)
|
||||||
|
abortController?.abort()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user