fix: 返回列表时保留原分页页码

Co-authored-by: Cursor <cursoragent@cursor.com>
master
lion 2 months ago
parent 3fa8ae1d4b
commit 198e2400e7

@ -97,7 +97,16 @@ async function load() {
}
function goBack() {
void router.push({ name: 'manage-projects', params: { slug: competitionSlug.value } })
const query: Record<string, string> = {}
if (typeof route.query.page === 'string' && route.query.page) query.page = route.query.page
if (typeof route.query.per_page === 'string' && route.query.per_page) {
query.per_page = route.query.per_page
}
void router.push({
name: 'manage-projects',
params: { slug: competitionSlug.value },
query,
})
}
async function downloadFile(file: AdminApplicationFileRow) {

@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, inject, reactive, ref, watch, type Ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import PortalPagination from '../../components/portal/PortalPagination.vue'
import {
@ -21,6 +21,7 @@ import type {
SignupChannelRow,
} from '../../api/admin/types'
const route = useRoute()
const router = useRouter()
const competitionId = inject<Ref<number | null>>('manageCompetitionId', ref(null))
const competitionSlug = inject<Ref<string>>('manageCompetitionSlug', ref(''))
@ -28,6 +29,33 @@ const competitionSlug = inject<Ref<string>>('manageCompetitionSlug', ref(''))
const loading = ref(false)
const rows = ref<AdminApplicationRow[]>([])
const pager = reactive({ page: 1, perPage: 15, total: 0 })
function parsePositiveInt(v: unknown, fallback: number): number {
const n = typeof v === 'string' ? Number(v) : typeof v === 'number' ? v : NaN
return Number.isInteger(n) && n > 0 ? n : fallback
}
function listReturnQuery(): Record<string, string> {
const q: Record<string, string> = {}
if (pager.page > 1) q.page = String(pager.page)
if (pager.perPage !== 15) q.per_page = String(pager.perPage)
return q
}
function applyListQueryFromRoute(): void {
pager.page = parsePositiveInt(route.query.page, 1)
pager.perPage = parsePositiveInt(route.query.per_page, 15)
}
function syncListQueryToRoute(): void {
const next = listReturnQuery()
const curPage = typeof route.query.page === 'string' ? route.query.page : undefined
const curPer = typeof route.query.per_page === 'string' ? route.query.per_page : undefined
const nextPage = next.page
const nextPer = next.per_page
if (curPage === nextPage && curPer === nextPer) return
void router.replace({ query: next })
}
const tracks = ref<CompetitionTrackRow[]>([])
const signupChannels = ref<SignupChannelRow[]>([])
const publicSources = ref<PublicSourceChannelRow[]>([])
@ -205,10 +233,15 @@ async function refresh(page = pager.page) {
if (!cid) return
loading.value = true
pager.page = page
syncListQueryToRoute()
try {
const res = await listAdminApplications(cid, buildListParams(page))
rows.value = res.data
pager.total = res.meta.total
if (res.meta.current_page && res.meta.current_page !== pager.page) {
pager.page = res.meta.current_page
syncListQueryToRoute()
}
} finally {
loading.value = false
}
@ -286,13 +319,15 @@ function openDetail(row: AdminApplicationRow) {
void router.push({
name: 'manage-project-detail',
params: { slug: competitionSlug.value, id: row.id },
query: listReturnQuery(),
})
}
watch(competitionId, async (cid) => {
if (!cid) return
await loadFilters()
await refresh(1)
applyListQueryFromRoute()
await refresh(pager.page)
}, { immediate: true })
</script>

@ -325,8 +325,16 @@ onMounted(() => void loadDetail())
function goBack() {
const s = slug.value
if (s) void router.push({ name: 'reviewer-projects', params: { slug: s } })
else void router.push('/c')
if (!s) {
void router.push('/c')
return
}
const query: Record<string, string> = {}
if (typeof route.query.page === 'string' && route.query.page) query.page = route.query.page
if (typeof route.query.per_page === 'string' && route.query.per_page) {
query.per_page = route.query.per_page
}
void router.push({ name: 'reviewer-projects', params: { slug: s }, query })
}
async function downloadAttachment(f: FileItem) {

@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { computed, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
getApiBase,
readReviewerSession,
@ -25,6 +25,7 @@ export interface ReviewApplicationRow {
}
const route = useRoute()
const router = useRouter()
const slug = computed(() => String(route.params.slug ?? '').trim())
const rows = ref<ReviewApplicationRow[]>([])
@ -47,6 +48,31 @@ const meta = ref({
const page = ref(1)
const perPage = ref(15)
function parsePositiveInt(v: unknown, fallback: number): number {
const n = typeof v === 'string' ? Number(v) : typeof v === 'number' ? v : NaN
return Number.isInteger(n) && n > 0 ? n : fallback
}
function listReturnQuery(): Record<string, string> {
const q: Record<string, string> = {}
if (page.value > 1) q.page = String(page.value)
if (perPage.value !== 15) q.per_page = String(perPage.value)
return q
}
function applyListQueryFromRoute(): void {
page.value = parsePositiveInt(route.query.page, 1)
perPage.value = parsePositiveInt(route.query.per_page, 15)
}
function syncListQueryToRoute(): void {
const next = listReturnQuery()
const curPage = typeof route.query.page === 'string' ? route.query.page : undefined
const curPer = typeof route.query.per_page === 'string' ? route.query.per_page : undefined
if (curPage === next.page && curPer === next.per_page) return
void router.replace({ query: next })
}
function buildListParams(): URLSearchParams {
const qs = new URLSearchParams()
qs.set('competition_slug', slug.value)
@ -125,7 +151,6 @@ function updateResultHint() {
function refresh(p = page.value) {
page.value = p
void fetchList()
}
function resetFilters() {
@ -134,9 +159,12 @@ function resetFilters() {
refresh(1)
}
watch([slug, page, perPage], () => void fetchList())
applyListQueryFromRoute()
onMounted(() => void fetchList())
watch([slug, page, perPage], () => {
syncListQueryToRoute()
void fetchList()
}, { immediate: true })
const pageHint = computed(() => {
if (loading.value) return '加载中…'
@ -150,7 +178,6 @@ function onPageChange(p: number) {
function onPerPageChange(size: number) {
perPage.value = size
page.value = 1
void fetchList()
}
function rowIndex(i: number): number {
@ -234,7 +261,11 @@ function actionLabel(row: ReviewApplicationRow): string {
<td class="admin-actions-cell portal-sticky-right-1">
<router-link
class="btn btn-sm btn-outline-primary"
:to="{ name: 'reviewer-application-detail', params: { slug, id: String(row.id) } }"
:to="{
name: 'reviewer-application-detail',
params: { slug, id: String(row.id) },
query: listReturnQuery(),
}"
>
{{ actionLabel(row) }}
</router-link>

Loading…
Cancel
Save