Skip to content

Commit dfe9950

Browse files
QTomclaude
andcommitted
feat(frontend): 分页 pageSize 持久化到 localStorage,刷新后自动恢复
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9f6ab6b commit dfe9950

15 files changed

Lines changed: 57 additions & 14 deletions

frontend/src/components/admin/announcements/AnnouncementReadStatusDialog.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import { adminAPI } from '@/api/admin'
6969
import { formatDateTime } from '@/utils/format'
7070
import type { AnnouncementUserReadStatus } from '@/types'
7171
import type { Column } from '@/components/common/types'
72+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
7273
7374
import BaseDialog from '@/components/common/BaseDialog.vue'
7475
import DataTable from '@/components/common/DataTable.vue'
@@ -92,7 +93,7 @@ const search = ref('')
9293
9394
const pagination = reactive({
9495
page: 1,
95-
page_size: 20,
96+
page_size: getPersistedPageSize(),
9697
total: 0,
9798
pages: 0
9899
})

frontend/src/components/common/Pagination.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ import { computed, ref } from 'vue'
122122
import { useI18n } from 'vue-i18n'
123123
import Icon from '@/components/icons/Icon.vue'
124124
import Select from './Select.vue'
125+
import { setPersistedPageSize } from '@/composables/usePersistedPageSize'
125126
126127
const { t } = useI18n()
127128
@@ -216,6 +217,7 @@ const goToPage = (newPage: number) => {
216217
const handlePageSizeChange = (value: string | number | boolean | null) => {
217218
if (value === null || typeof value === 'boolean') return
218219
const newPageSize = typeof value === 'string' ? parseInt(value) : value
220+
setPersistedPageSize(newPageSize)
219221
emit('update:pageSize', newPageSize)
220222
}
221223

frontend/src/components/sora/SoraLibraryPage.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
import { ref, computed, onMounted } from 'vue'
127127
import { useI18n } from 'vue-i18n'
128128
import soraAPI, { type SoraGeneration } from '@/api/sora'
129+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
129130
import SoraMediaPreview from './SoraMediaPreview.vue'
130131
131132
const emit = defineEmits<{
@@ -190,7 +191,7 @@ async function loadItems(pageNum: number) {
190191
status: 'completed',
191192
storage_type: 's3,local',
192193
page: pageNum,
193-
page_size: 20
194+
page_size: getPersistedPageSize()
194195
})
195196
const rows = Array.isArray(res.data) ? res.data : []
196197
if (pageNum === 1) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const STORAGE_KEY = 'table-page-size'
2+
const DEFAULT_PAGE_SIZE = 20
3+
4+
/**
5+
* 从 localStorage 读取/写入 pageSize
6+
* 全局共享一个 key,所有表格统一偏好
7+
*/
8+
export function getPersistedPageSize(fallback = DEFAULT_PAGE_SIZE): number {
9+
try {
10+
const stored = localStorage.getItem(STORAGE_KEY)
11+
if (stored) {
12+
const parsed = Number(stored)
13+
if (Number.isFinite(parsed) && parsed > 0) return parsed
14+
}
15+
} catch {
16+
// localStorage 不可用(隐私模式等)
17+
}
18+
return fallback
19+
}
20+
21+
export function setPersistedPageSize(size: number): void {
22+
try {
23+
localStorage.setItem(STORAGE_KEY, String(size))
24+
} catch {
25+
// 静默失败
26+
}
27+
}

frontend/src/composables/useTableLoader.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ref, reactive, onUnmounted, toRaw } from 'vue'
22
import { useDebounceFn } from '@vueuse/core'
33
import type { BasePaginationResponse, FetchOptions } from '@/types'
4+
import { getPersistedPageSize, setPersistedPageSize } from './usePersistedPageSize'
45

56
interface PaginationState {
67
page: number
@@ -21,14 +22,14 @@ interface TableLoaderOptions<T, P> {
2122
* 统一处理分页、筛选、搜索防抖和请求取消
2223
*/
2324
export function useTableLoader<T, P extends Record<string, any>>(options: TableLoaderOptions<T, P>) {
24-
const { fetchFn, initialParams, pageSize = 20, debounceMs = 300 } = options
25+
const { fetchFn, initialParams, pageSize, debounceMs = 300 } = options
2526

2627
const items = ref<T[]>([])
2728
const loading = ref(false)
2829
const params = reactive<P>({ ...(initialParams || {}) } as P)
2930
const pagination = reactive<PaginationState>({
3031
page: 1,
31-
page_size: pageSize,
32+
page_size: pageSize ?? getPersistedPageSize(),
3233
total: 0,
3334
pages: 0
3435
})
@@ -87,6 +88,7 @@ export function useTableLoader<T, P extends Record<string, any>>(options: TableL
8788
const handlePageSizeChange = (size: number) => {
8889
pagination.page_size = size
8990
pagination.page = 1
91+
setPersistedPageSize(size)
9092
load()
9193
}
9294

frontend/src/views/admin/AnnouncementsView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@
239239
import { computed, onMounted, reactive, ref } from 'vue'
240240
import { useI18n } from 'vue-i18n'
241241
import { useAppStore } from '@/stores/app'
242+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
242243
import { adminAPI } from '@/api/admin'
243244
import { formatDateTime, formatDateTimeLocalInput, parseDateTimeLocalInput } from '@/utils/format'
244245
import type { AdminGroup, Announcement, AnnouncementTargeting } from '@/types'
@@ -270,7 +271,7 @@ const searchQuery = ref('')
270271
271272
const pagination = reactive({
272273
page: 1,
273-
page_size: 20,
274+
page_size: getPersistedPageSize(),
274275
total: 0,
275276
pages: 0
276277
})

frontend/src/views/admin/GroupsView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,7 @@ import GroupCapacityBadge from '@/components/common/GroupCapacityBadge.vue'
18551855
import { VueDraggable } from 'vue-draggable-plus'
18561856
import { createStableObjectKeyResolver } from '@/utils/stableObjectKey'
18571857
import { useKeyedDebouncedSearch } from '@/composables/useKeyedDebouncedSearch'
1858+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
18581859
18591860
const { t } = useI18n()
18601861
const appStore = useAppStore()
@@ -2016,7 +2017,7 @@ const filters = reactive({
20162017
})
20172018
const pagination = reactive({
20182019
page: 1,
2019-
page_size: 20,
2020+
page_size: getPersistedPageSize(),
20202021
total: 0,
20212022
pages: 0
20222023
})

frontend/src/views/admin/PromoCodesView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
383383
import { useI18n } from 'vue-i18n'
384384
import { useAppStore } from '@/stores/app'
385385
import { useClipboard } from '@/composables/useClipboard'
386+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
386387
import { adminAPI } from '@/api/admin'
387388
import { formatDateTime } from '@/utils/format'
388389
import type { PromoCode, PromoCodeUsage } from '@/types'
@@ -414,7 +415,7 @@ const filters = reactive({
414415
415416
const pagination = reactive({
416417
page: 1,
417-
page_size: 20,
418+
page_size: getPersistedPageSize(),
418419
total: 0
419420
})
420421

frontend/src/views/admin/ProxiesView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,7 @@ import PlatformTypeBadge from '@/components/common/PlatformTypeBadge.vue'
884884
import { useClipboard } from '@/composables/useClipboard'
885885
import { useSwipeSelect } from '@/composables/useSwipeSelect'
886886
import { useTableSelection } from '@/composables/useTableSelection'
887+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
887888
888889
const { t } = useI18n()
889890
const appStore = useAppStore()
@@ -941,7 +942,7 @@ const filters = reactive({
941942
})
942943
const pagination = reactive({
943944
page: 1,
944-
page_size: 20,
945+
page_size: getPersistedPageSize(),
945946
total: 0,
946947
pages: 0
947948
})

frontend/src/views/admin/RedeemView.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue'
395395
import { useI18n } from 'vue-i18n'
396396
import { useAppStore } from '@/stores/app'
397397
import { useClipboard } from '@/composables/useClipboard'
398+
import { getPersistedPageSize } from '@/composables/usePersistedPageSize'
398399
import { adminAPI } from '@/api/admin'
399400
import { formatDateTime } from '@/utils/format'
400401
import type { RedeemCode, RedeemCodeType, Group, GroupPlatform, SubscriptionType } from '@/types'
@@ -532,7 +533,7 @@ const filters = reactive({
532533
})
533534
const pagination = reactive({
534535
page: 1,
535-
page_size: 20,
536+
page_size: getPersistedPageSize(),
536537
total: 0,
537538
pages: 0
538539
})

0 commit comments

Comments
 (0)