fix(pl): 保留统计分页总数并避免刷新取消权限初始化。

This commit is contained in:
wuzilong committed 2026-11-01 22:20:24 +08:00
1 parent 013ca2f164
commit f9c489531d
2 files changed
+89 -4

No files matched your search

+82 -1
View File
@@ -126,7 +126,7 @@ function harness(fixed?: string) {
const state = scope.run(() =>
new Function(
...Object.keys(env),
`${code}; return { rows, fixedDetail, details, load, loadDetail, allowed, canEdit, keyword, setFilterState }`
`${code}; return { rows, fixedDetail, details, load, loadDetail, allowed, canEdit, keyword, setFilterState, page, total }`
)(...Object.values(env))
)
return {
@@ -490,3 +490,84 @@ test('closing dialog invalidates pending searches including their finally state'
assert.equal(s.searching.value, false)
h.stop()
})
// Mount the real Element Plus pager. Its page-count watcher must remain active.
import ElPagination from 'element-plus/es/components/pagination/src/pagination.mjs'
test('real pagination keeps page two while loading and preserves count after request failure', async () => {
const h = harness(),
s = h.state
h.permissions[0].resolve({ all: true })
await flush()
h.calls[0].resolve({ list: [{ id: 'first' }], total: 45 })
await flush()
const renderer = vue.createRenderer<any, any>({
createElement: () => ({}),
createText: () => ({}),
createComment: () => ({}),
setText: () => {},
setElementText: () => {},
parentNode: () => null,
nextSibling: () => null,
insert: () => {},
remove: () => {},
patchProp: () => {}
})
const app = renderer.createApp({
render: () =>
vue.h(ElPagination, {
currentPage: s.page.value,
total: s.total.value,
pageSize: 20,
layout: '',
'onUpdate:current-page': (value: number) => {
s.page.value = value
},
onCurrentChange: () => {
void s.load()
}
})
})
app.mount({})
s.page.value = 2
const pending = s.load()
await vue.nextTick()
await flush()
assert.equal(s.page.value, 2)
assert.equal(h.calls.length, 2)
assert.equal(h.calls[1].args[0].page, 2)
h.calls[1].resolve({ list: [{ id: 'second' }], total: 45 })
await pending
await vue.nextTick()
assert.equal(s.page.value, 2)
assert.equal(s.rows.value[0].id, 'second')
const failed = s.load()
h.calls[2].reject(Error('failed'))
await failed
await vue.nextTick()
assert.equal(s.page.value, 2)
assert.equal(s.total.value, 45)
assert.deepEqual(s.rows.value, [])
h.user.getUserInfo.tenantNo = 'next'
await vue.nextTick()
assert.equal(s.page.value, 1)
assert.equal(s.total.value, 0)
app.unmount()
h.stop()
})
test('refresh and search while permission request is pending do not cancel initialization', async () => {
const h = harness(),
s = h.state
await s.load()
s.keyword.value = '目标'
s.setFilterState('contractNo', { text: 'HT' })
assert.equal(h.calls.length, 0)
h.permissions[0].resolve({ menuCodes: ['pl:quota-cert:list'] })
await flush()
assert.equal(h.calls.length, 1)
assert.deepEqual(h.calls[0].args[0], { page: 1, pageSize: 20, keyword: '目标', contractNo: 'HT' })
h.calls[0].resolve({ list: [{ id: 'loaded' }], total: 1 })
await flush()
assert.equal(s.rows.value[0].id, 'loaded')
h.stop()
})
@@ -229,19 +229,23 @@
{ onChange: search }
)
watchVisibleColumns(visibleColumns)
function clear() {
function clearResults() {
loader.invalidate()
epoch++
rows.value = []
fixedDetail.value = undefined
total.value = 0
loading.value = false
error.value = ''
Object.keys(details).forEach((k) => delete details[k])
}
function clear() {
clearResults()
total.value = 0
page.value = 1
}
async function load() {
clear()
if (!allowed.value || !props.active) return
clearResults()
const current = epoch
loading.value = true
try {