fix: some

This commit is contained in:
luo
2026-10-14 11:18:29 +08:00
parent 37f24882c9
commit f2344063ff
2 changed files with 103 additions and 11 deletions

View File

@@ -133,13 +133,28 @@
loading.value = true;
try {
let visibleItems;
do {
const requestedPage = page.value;
const data = await assetApi.getPackageHistory(
userStore.state.identifier,
page.value,
requestedPage,
pageSize
);
const items = Array.isArray(data.items) ? data.items : [];
visibleItems = items.filter(item => Number(item?.status) !== 4);
const responseSize = Number(data.size) > 0 ? Number(data.size) : pageSize;
const responseTotal = data.total === null || data.total === undefined
? NaN : Number(data.total);
// Pagination describes the backend's unfiltered records, not the
// visible list. Skip fully hidden pages to reach subsequent records.
noMore.value = Number.isFinite(responseTotal) && responseTotal >= 0
? requestedPage * responseSize >= responseTotal
: items.length < pageSize;
page.value = requestedPage + 1;
} while (visibleItems.length === 0 && !noMore.value);
const newData = (data.items || []).map(item => ({
const newData = visibleItems.map(item => ({
...item,
activated_at: item.activated_at ? formatDate(item.activated_at) : '',
created_at: formatDate(item.created_at),
@@ -152,11 +167,6 @@
packageList.splice(0, packageList.length, ...newData);
}
if (newData.length < pageSize) {
noMore.value = true;
} else {
page.value++;
}
} catch (e) {
console.error('加载套餐历史失败', e);
}

View File

@@ -0,0 +1,82 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import vm from 'node:vm';
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const vue = require('vue');
const source = readFileSync(new URL('../pages/asset-package-history/asset-package-history.vue', import.meta.url), 'utf8');
const plain = value => JSON.parse(JSON.stringify(value));
async function loadPage(responses) {
const requestedPages = [];
const context = vm.createContext({ console: { error() {} } });
const exports = {
vue: { ref: vue.ref, reactive: vue.reactive, onMounted() {} },
'@/api/index.js': { assetApi: { getPackageHistory: async (identifier, page, size) => {
assert.equal(identifier, 'A'); assert.equal(size, 10);
requestedPages.push(page);
return responses[page - 1] || { items: [] };
} } },
'@/store/index.js': { useUserStore: () => ({ state: { identifier: 'A' } }) }
};
const script = source.match(/<script setup>([\s\S]*?)<\/script>/)[1];
const page = new vm.SourceTextModule(script + '\nexport { loadPackageList, packageList, noMore, historyLoaded };', { context });
await page.link(specifier => {
const values = exports[specifier];
return new vm.SyntheticModule(Object.keys(values), function () {
for (const [key, value] of Object.entries(values)) this.setExport(key, value);
}, { context });
});
await page.evaluate();
return { page: page.namespace, requestedPages };
}
test('main package history hides status 4 and string 4, preserving other states and dates', async () => {
const { page } = await loadPage([{ items: [
{ status: 4 }, { status: '4' },
{ status: 0, package_name: '待生效', expires_at: '2026-10-14T12:00:00Z' },
{ status: 1 }, { status: 2 }, { status: 3 }
] }]);
await page.loadPackageList();
assert.deepEqual(plain(page.packageList).map(item => item.status), [0, 1, 2, 3]);
assert.equal(page.packageList[0].expires_at, '2026-10-14 12:00:00');
assert.equal(page.noMore.value, true);
});
test('filtering a full page must not make later records unreachable', async () => {
const { page, requestedPages } = await loadPage([
{ items: [...Array.from({ length: 9 }, () => ({ status: 4 })), { status: 1, id: 1 }] },
{ items: [{ status: 2, id: 2 }] }
]);
await page.loadPackageList();
assert.equal(page.noMore.value, false);
await page.loadPackageList(true);
assert.deepEqual(requestedPages, [1, 2]);
assert.deepEqual(plain(page.packageList).map(item => item.id), [1, 2]);
assert.equal(page.noMore.value, true);
});
test('fully invalidated first page is skipped automatically', async () => {
const { page, requestedPages } = await loadPage([
{ items: Array.from({ length: 10 }, () => ({ status: 4 })) },
{ items: [{ status: 1, id: 12 }] }
]);
await page.loadPackageList();
assert.deepEqual(requestedPages, [1, 2]);
assert.equal(page.packageList[0].id, 12);
assert.equal(page.noMore.value, true);
});
test('server total keeps pagination correct even when a filtered page is empty', async () => {
const { page, requestedPages } = await loadPage([
{ items: [{ status: '4' }], size: 10, total: 20 },
{ items: [{ status: 4 }], size: 10, total: 20 }
]);
await page.loadPackageList();
assert.deepEqual(requestedPages, [1, 2]);
assert.equal(page.packageList.length, 0);
assert.equal(page.noMore.value, true);
assert.equal(page.historyLoaded.value, true);
});