feat(需求): ①全站列表/卡片分页统一为共享 OldPagination(共N条+10/20/50/100条数可选+跳页) ②创建用户菜单权限改左右布局(后台|桌面端并排) ③修复角色筛选失效(normalizeUserPageParams 白名单丢 role 字段)

This commit is contained in:
2026-09-07 00:02:30 +08:00
parent d3f5a371e3
commit cd6beef388
18 changed files with 323 additions and 245 deletions
@@ -21,13 +21,14 @@ import {
import { validateDigitalHumanUpload } from './digitalhuman-upload-model.ts'
import { canReleaseDigitalHumanVersion, releaseDigitalHumanConfirmText } from './digitalhuman-release.ts'
import { canSetLatestDigitalHumanVersion, setLatestDigitalHumanConfirmText } from './digitalhuman-latest.ts'
import OldPagination from '@/components/OldPagination.vue'
import { digitalHumanStatusDisplay } from './digitalhuman-status-display.ts'
const loading = ref(false)
const items = ref<DigitalHumanVersion[]>([])
/** 分页(对齐 admin.js:6311 pageSize=20 + 数字页码 + 跳转;Java 列表接口不分页,前端分页呈现)。 */
const pageSize = 20
const pageSize = ref(20)
const page = ref(1)
/** 版本号搜索(客户端过滤)。 */
const versionKeyword = ref('')
@@ -37,10 +38,10 @@ const filteredItems = computed(() => {
return items.value.filter((item) => `${item.version}`.toLowerCase().includes(kw))
})
const pagedItems = computed(() => {
const start = (page.value - 1) * pageSize
return filteredItems.value.slice(start, start + pageSize)
const start = (page.value - 1) * pageSize.value
return filteredItems.value.slice(start, start + pageSize.value)
})
const totalPages = computed(() => Math.max(1, Math.ceil(filteredItems.value.length / pageSize)))
const totalPages = computed(() => Math.max(1, Math.ceil(filteredItems.value.length / pageSize.value)))
const jumpPage = ref('')
const uploadVisible = ref(false)
@@ -56,7 +57,7 @@ async function load() {
try {
items.value = (await fetchDigitalHumanVersions()).items
// 数据收缩后页码越界回钳。
const last = Math.max(Math.ceil(items.value.length / pageSize), 1)
const last = Math.max(Math.ceil(items.value.length / pageSize.value), 1)
if (page.value > last) page.value = last
} catch (error) {
ElMessage.error(error instanceof Error ? error.message : '版本列表加载失败')
@@ -70,6 +71,11 @@ function changePage(next: number): void {
page.value = next
}
function changeSize(size: number) {
pageSize.value = size
page.value = 1
}
function goJump(): void {
const n = Number.parseInt(jumpPage.value, 10)
if (Number.isNaN(n)) {
@@ -259,19 +265,7 @@ onMounted(load)
</div>
<div v-if="filteredItems.length > pageSize" class="pagination">
<button type="button" :disabled="page <= 1" @click="changePage(page - 1)">上一页</button>
<span class="page-nums">
<template v-for="n in totalPages" :key="n">
<button type="button" class="num-page" :class="{ 'is-active': n === page }" @click="changePage(n)">{{ n }}</button>
</template>
</span>
<button type="button" :disabled="page >= totalPages" @click="changePage(page + 1)">下一页</button>
<span class="page-jump">
跳至
<input v-model="jumpPage" type="text" inputmode="numeric" @keyup.enter="goJump" />
<button type="button" @click="goJump">跳转</button>
</span>
<OldPagination :total="filteredItems.length" :page="page" :page-size="pageSize" @change="changePage" @size-change="changeSize" />
</div>
</section>
@@ -15,7 +15,7 @@ const userLoading = ref(false)
const rows = ref<HistoryRecordItem[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = 15
const pageSize = ref(15)
const userOptions = ref<HistoryUserOption[]>([])
const errorText = ref('')
const filter = reactive({ userId: '', timeStart: '', timeEnd: '' })
@@ -26,7 +26,7 @@ const jumpPage = ref('')
const hasFilter = computed(() => Boolean(filter.userId || filter.timeStart || filter.timeEnd))
const emptyText = computed(() => historyEmptyText({ hasFilter: hasFilter.value, total: total.value }))
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize)))
const totalPages = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
/** datetime-local 原生值(YYYY-MM-DDTHH:mm) 转后端兼容格式。 */
function toApiTime(value: string): string | undefined {
@@ -56,7 +56,7 @@ async function load() {
try {
const result = await fetchHistoryList({
page: page.value,
pageSize,
pageSize: pageSize.value,
userId: filter.userId ? Number(filter.userId) : undefined,
timeStart: toApiTime(filter.timeStart),
timeEnd: toApiTime(filter.timeEnd),
@@ -97,6 +97,13 @@ function changePage(next: number) {
load()
}
function changeSize(size: number) {
pageSize.value = size
page.value = 1
load()
}
function goJump() {
const n = Number.parseInt(jumpPage.value, 10)
if (Number.isNaN(n)) {
@@ -192,19 +199,7 @@ onMounted(() => {
</tbody>
</table>
</div>
<div class="pagination">
<span class="page-total"> {{ total }} </span>
<button type="button" :disabled="page <= 1" @click="changePage(page - 1)">上一页</button>
<span class="page-cur"> {{ page }} / {{ totalPages }} </span>
<button type="button" :disabled="page >= totalPages" @click="changePage(page + 1)">下一页</button>
<span class="page-jump">
跳至
<input v-model="jumpPage" type="text" inputmode="numeric" @keyup.enter="goJump" />
<button type="button" @click="goJump">跳转</button>
</span>
</div>
<OldPagination :total="total" :page="page" :page-size="pageSize" @change="changePage" @size-change="changeSize" />
</section>
<div v-if="previewVisible" class="modal-mask" @click.self="previewVisible = false">