feat: 表格分页支持统一配置并记忆各表格每页条数
- 后端新增聚合用户偏好 paginationPrefs(每页条数候选列表与默认每页条数),提供 GET/PUT /api/setting/pagination-prefs,默认候选 [10,20,50,100]、默认每页 20,非法值自动过滤并回退 - 后端新增 /category/page、/tag/page、/channel/page、/email-bill/configs/page、/email-bill/sender-rules/page 分页接口,原全量接口保持不变以免影响下拉、筛选、AI 与导出 - 前端新增共享 composables/usePageSizeOptions.ts 与 useTablePageSize.ts,所有表格统一取用候选列表并记住各自上次选择的每页条数,优先级为表格记忆 > 全局默认 > 20 - 各表格上次选择以聚合偏好 finance.pagination.tablePageSizes 存于本机 localStorage,收支记录页旧的 filterPrefs.pageSize 自动迁移 - 设置页外观设置新增「表格每页条数选项」分组,可增删候选值并配置默认每页条数,保存后全局即时生效 - 路由守卫在已登录时预加载分页偏好,保证表格页首次渲染即使用配置值 - 前端分类、标签、渠道、邮箱配置、发件人规则表格接入后端分页 - 补充中文、英文、日文三语文案
This commit is contained in:
@@ -17,6 +17,9 @@ import { getChannelLabel } from '../utils/channel'
|
||||
import { renderCategoryLabel } from '../utils/render'
|
||||
import { useKeywordHistory } from '../composables/useKeywordHistory'
|
||||
import { useStringPreference } from '../composables/usePreference'
|
||||
import { usePageSizeOptions } from '../composables/usePageSizeOptions'
|
||||
import { useTablePageSize } from '../composables/useTablePageSize'
|
||||
import { readTablePageSize, writeTablePageSize } from '../utils/tablePageSizePrefs'
|
||||
import { openSse } from '../utils/sse'
|
||||
import { STORAGE_KEYS } from '../utils/storageKeys'
|
||||
import { loadTransactionFilterPrefs, saveTransactionFilterPrefs } from '../utils/transactionFilterPrefs'
|
||||
@@ -94,7 +97,7 @@ interface AiRecordEditRow {
|
||||
const transactions = ref<TransactionItem[]>([]) // 交易记录列表
|
||||
const total = ref(0) // 总记录数
|
||||
const page = ref(1) // 当前页码
|
||||
const pageSize = ref(20) // 每页条数
|
||||
const pageSize = useTablePageSize('transaction') // 每页条数
|
||||
const sortValue = ref('transactionTime-desc') // 排序方式:排序字段-方向
|
||||
const sortOptions = computed(() => [
|
||||
{ label: t('transaction.sort.timeDesc'), value: 'transactionTime-desc' },
|
||||
@@ -104,7 +107,7 @@ const sortOptions = computed(() => [
|
||||
])
|
||||
const sortField = computed(() => sortValue.value.split('-')[0]) // 服务端排序字段
|
||||
const sortOrder = computed(() => sortValue.value.split('-')[1]) // 服务端排序方向:asc/desc
|
||||
const pageSizes = [10, 20, 50, 100, 200, 500] // 可选的每页条数
|
||||
const { pageSizeOptions } = usePageSizeOptions() // 所有表格共用的每页条数候选列表
|
||||
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value))) // 总页数
|
||||
// 当前页金额汇总:支出、收入与结余(含本页所有展示记录)
|
||||
const pageSummary = computed(() => {
|
||||
@@ -345,7 +348,12 @@ function loadFilterPrefs() {
|
||||
if (typeof p.filterRemark === 'string') filterRemark.value = p.filterRemark
|
||||
if (p.filterMinAmount !== undefined) filterMinAmount.value = p.filterMinAmount
|
||||
if (p.filterMaxAmount !== undefined) filterMaxAmount.value = p.filterMaxAmount
|
||||
if (typeof p.pageSize === 'number' && pageSizes.includes(p.pageSize)) pageSize.value = p.pageSize
|
||||
// 迁移旧筛选偏好中的每页条数到统一的表格分页偏好(新机制尚无值时)
|
||||
if (typeof p.pageSize === 'number' && Number.isInteger(p.pageSize) && p.pageSize > 0
|
||||
&& readTablePageSize('transaction') === null) {
|
||||
writeTablePageSize('transaction', p.pageSize)
|
||||
pageSize.value = p.pageSize
|
||||
}
|
||||
if (typeof p.sortValue === 'string' && sortOptions.value.some((o) => o.value === p.sortValue)) sortValue.value = p.sortValue
|
||||
if (p.filterTag) filterTag.value = p.filterTag
|
||||
}
|
||||
@@ -361,7 +369,6 @@ function saveFilterPrefs() {
|
||||
filterRemark: filterRemark.value,
|
||||
filterMinAmount: filterMinAmount.value,
|
||||
filterMaxAmount: filterMaxAmount.value,
|
||||
pageSize: pageSize.value,
|
||||
sortValue: sortValue.value,
|
||||
filterTag: filterTag.value,
|
||||
})
|
||||
@@ -369,7 +376,7 @@ function saveFilterPrefs() {
|
||||
|
||||
// 筛选条件变化时自动保存用户偏好
|
||||
watch(
|
||||
[filterType, filterCategory, filterChannel, filterDateRange, filterIncludeInStats, filterRemark, filterMinAmount, filterMaxAmount, pageSize, sortValue, filterTag],
|
||||
[filterType, filterCategory, filterChannel, filterDateRange, filterIncludeInStats, filterRemark, filterMinAmount, filterMaxAmount, sortValue, filterTag],
|
||||
saveFilterPrefs,
|
||||
{ deep: true },
|
||||
)
|
||||
@@ -2224,7 +2231,7 @@ onBeforeUnmount(() => {
|
||||
v-model:page="page"
|
||||
v-model:page-size="pageSize"
|
||||
:page-count="Math.ceil(total / pageSize)"
|
||||
:page-sizes="pageSizes"
|
||||
:page-sizes="pageSizeOptions"
|
||||
show-size-picker
|
||||
show-quick-jumper
|
||||
@update:page="handlePageChange"
|
||||
|
||||
Reference in New Issue
Block a user