perf(admin): 实现切页即时导航与列表 loading 壳
非阻塞 session 刷新、侧边栏 chunk 预取、KeepAlive 对齐,以及按 tab 延迟加载重型列表页。
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onActivated } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
defineOptions({ name: 'AdminBets' });
|
||||
import { useStaleListLifecycle } from '../composables/useStaleList';
|
||||
import api from '../api';
|
||||
import { formatAmount, formatAmountFull } from '../utils/format-amount';
|
||||
import {
|
||||
@@ -34,16 +35,6 @@ const detailVisible = ref(false);
|
||||
const detail = ref<BetDetail | null>(null);
|
||||
const detailLoading = ref(false);
|
||||
|
||||
onMounted(load);
|
||||
// KeepAlive 激活时:有缓存数据则后台静默刷新,避免白屏等待
|
||||
onActivated(() => { if (bets.value.length > 0) void load(); });
|
||||
|
||||
function betContentCounts(row: BetListRow) {
|
||||
const singles = row.betType === 'SINGLE' ? 1 : 0;
|
||||
const parlays = row.betType === 'PARLAY' ? 1 : 0;
|
||||
return t('bet.content.bet_counts', { singles, parlays });
|
||||
}
|
||||
|
||||
async function load() {
|
||||
const { data } = await api.get('/admin/bets', {
|
||||
params: {
|
||||
@@ -60,15 +51,17 @@ async function load() {
|
||||
total.value = data.data.total;
|
||||
}
|
||||
|
||||
const { loading: listLoading, runLoad } = useStaleListLifecycle(() => bets.value.length > 0, load);
|
||||
|
||||
function onPageChange(p: number) {
|
||||
page.value = p;
|
||||
load();
|
||||
void runLoad(true);
|
||||
}
|
||||
|
||||
function onSizeChange(size: number) {
|
||||
pageSize.value = size;
|
||||
page.value = 1;
|
||||
load();
|
||||
void runLoad(true);
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
@@ -78,7 +71,13 @@ function resetFilters() {
|
||||
placedFrom.value = '';
|
||||
placedTo.value = '';
|
||||
page.value = 1;
|
||||
load();
|
||||
void runLoad(true);
|
||||
}
|
||||
|
||||
function betContentCounts(row: BetListRow) {
|
||||
const singles = row.betType === 'SINGLE' ? 1 : 0;
|
||||
const parlays = row.betType === 'PARLAY' ? 1 : 0;
|
||||
return t('bet.content.bet_counts', { singles, parlays });
|
||||
}
|
||||
|
||||
function parentLabel(row: BetListRow) {
|
||||
@@ -166,13 +165,13 @@ async function openDetail(row: BetListRow) {
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="load">{{ t('common.search') }}</el-button>
|
||||
<el-button type="primary" @click="runLoad(true)">{{ t('common.search') }}</el-button>
|
||||
<el-button @click="resetFilters">{{ t('common.reset') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="data-card" shadow="never">
|
||||
<el-card v-loading="listLoading" class="data-card" shadow="never">
|
||||
<div class="table-wrap">
|
||||
<el-table :data="bets" stripe class="bets-table">
|
||||
<template #empty>
|
||||
|
||||
Reference in New Issue
Block a user