diff --git a/src/components/Paginator.vue b/src/components/Paginator.vue new file mode 100644 index 0000000..de8aaf7 --- /dev/null +++ b/src/components/Paginator.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/src/i18n/en/common.ts b/src/i18n/en/common.ts index d517b39..c53d03e 100644 --- a/src/i18n/en/common.ts +++ b/src/i18n/en/common.ts @@ -14,5 +14,12 @@ export default { close: 'Close', loading: 'Loading…', unknownError: 'Unknown error', + // Pagination UI (F-260621-02 P3 baseline; off by default, opt-in per-page) + pagination: { + prev: 'Prev', + next: 'Next', + perPage: 'Per page', + total: '{n} total', + }, }, } diff --git a/src/i18n/zh-CN/common.ts b/src/i18n/zh-CN/common.ts index 8abb61d..f91d864 100644 --- a/src/i18n/zh-CN/common.ts +++ b/src/i18n/zh-CN/common.ts @@ -14,5 +14,12 @@ export default { close: '关闭', loading: '加载中…', unknownError: '未知错误', + // 分页 UI(F-260621-02 P3 基建,默认不分页,用户选每页 N 条才触发) + pagination: { + prev: '上一页', + next: '下一页', + perPage: '每页', + total: '共 {n} 条', + }, }, } diff --git a/src/views/Ideas.vue b/src/views/Ideas.vue index 9d0905c..a4522d5 100644 --- a/src/views/Ideas.vue +++ b/src/views/Ideas.vue @@ -52,7 +52,7 @@
{{ $t('ideas.listEmpty') }}
+ + @@ -132,6 +138,7 @@ import { stripMd } from '../utils/markdown' import ConfirmDialog from '../components/ConfirmDialog.vue' import IdeaDetail from '../components/ideas/IdeaDetail.vue' import { useConfirm } from '../composables/useConfirm' +import Paginator from '../components/Paginator.vue' const { t } = useI18n() const router = useRouter() @@ -149,6 +156,10 @@ const searchQuery = ref('') // 列表排序:score 高分在前 / time 新在前(默认 score,避免高分灵感被淹没) const sortMode = ref<'score' | 'time'>('score') +// 分页(F-260621-02 P3):pageSize=0 → 全量(向后兼容,等价改造前);用户选 N → 客户端切片 +const page = ref(1) +const pageSize = ref(0) + // ── 新建灵感模态框 ── const showCaptureModal = ref(false) const newIdeaTitle = ref('') @@ -218,9 +229,9 @@ async function reloadIdeas(immediate = false) { } // 筛选/排序变化即时重载;keyword 输入防抖重载 -watch(activeFilter, () => void reloadIdeas(true)) -watch(sortMode, () => void reloadIdeas(true)) -watch(searchQuery, () => void reloadIdeas(false)) +watch(activeFilter, () => { page.value = 1; void reloadIdeas(true) }) +watch(sortMode, () => { page.value = 1; void reloadIdeas(true) }) +watch(searchQuery, () => { page.value = 1; void reloadIdeas(false) }) const filteredIdeas = computed(() => { let ideas = store.ideas @@ -237,6 +248,13 @@ const filteredIdeas = computed(() => { return ideas }) +// 分页视图(F-260621-02 P3):pageSize=0 → 全量(等价改造前);否则取当前页窗口。 +const pagedIdeas = computed(() => { + if (pageSize.value <= 0) return filteredIdeas.value + const start = (page.value - 1) * pageSize.value + return filteredIdeas.value.slice(start, start + pageSize.value) +}) + const currentIdea = computed(() => { if (!selectedId.value) return null return store.ideas.find(i => i.id === selectedId.value) ?? null diff --git a/src/views/Projects.vue b/src/views/Projects.vue index f748885..92fab5e 100644 --- a/src/views/Projects.vue +++ b/src/views/Projects.vue @@ -140,9 +140,16 @@
- +
+ + +
{{ $t('projects.empty') }} @@ -165,6 +172,7 @@ import { projectApi } from '@/api' import { formatDate } from '@/utils/time' import ConfirmDialog from '@/components/ConfirmDialog.vue' import ProjectCard from '@/components/project/ProjectCard.vue' +import Paginator from '@/components/Paginator.vue' import { useConfirm } from '@/composables/useConfirm' import type { ProjectRecord } from '@/api/types' import type { ScannedProjectItem } from '@/api/project' @@ -172,6 +180,17 @@ import type { ScannedProjectItem } from '@/api/project' const store = useProjectStore() const { t } = useI18n() +// 分页(F-260621-02 P3):pageSize=0 → 全量(向后兼容,等价改造前);用户选 N → 客户端切片 +const page = ref(1) +const pageSize = ref(0) + +// 分页视图:pageSize=0 → 全量;否则取当前页窗口 +const pagedProjects = computed(() => { + if (pageSize.value <= 0) return store.projects + const start = (page.value - 1) * pageSize.value + return store.projects.slice(start, start + pageSize.value) +}) + // 状态映射统一走 ../constants/project(与 ProjectDetail/Tasks/Dashboard 一致) // formatDate 由 ../utils/time 提供(统一毫秒字符串解析,根治 Invalid Date) diff --git a/src/views/Tasks.vue b/src/views/Tasks.vue index 0925f69..a798703 100644 --- a/src/views/Tasks.vue +++ b/src/views/Tasks.vue @@ -77,6 +77,13 @@
+ + +