Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
771baa66
Commit
771baa66
authored
Jan 18, 2026
by
yangjianbo
Browse files
feat(界面): 优化分页跳转与页大小显示
分页组件支持隐藏每页条数选择器并新增跳转页输入 清理任务列表启用跳转页并固定每页 5 条 补充中英文分页文案
parent
bd18f4b8
Changes
4
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/admin/usage/UsageCleanupDialog.vue
View file @
771baa66
...
@@ -66,6 +66,19 @@
...
@@ -66,6 +66,19 @@
</div>
</div>
</div>
</div>
</div>
</div>
<Pagination
v-if=
"tasksTotal > tasksPageSize"
class=
"mt-4"
:total=
"tasksTotal"
:page=
"tasksPage"
:page-size=
"tasksPageSize"
:page-size-options=
"[5]"
:show-page-size-selector=
"false"
:show-jump=
"true"
@
update:page=
"handleTaskPageChange"
@
update:pageSize=
"handleTaskPageSizeChange"
/>
</div>
</div>
</div>
</div>
...
@@ -108,6 +121,7 @@ import { useI18n } from 'vue-i18n'
...
@@ -108,6 +121,7 @@ import { useI18n } from 'vue-i18n'
import
{
useAppStore
}
from
'
@/stores/app
'
import
{
useAppStore
}
from
'
@/stores/app
'
import
BaseDialog
from
'
@/components/common/BaseDialog.vue
'
import
BaseDialog
from
'
@/components/common/BaseDialog.vue
'
import
ConfirmDialog
from
'
@/components/common/ConfirmDialog.vue
'
import
ConfirmDialog
from
'
@/components/common/ConfirmDialog.vue
'
import
Pagination
from
'
@/components/common/Pagination.vue
'
import
UsageFilters
from
'
@/components/admin/usage/UsageFilters.vue
'
import
UsageFilters
from
'
@/components/admin/usage/UsageFilters.vue
'
import
{
adminUsageAPI
}
from
'
@/api/admin/usage
'
import
{
adminUsageAPI
}
from
'
@/api/admin/usage
'
import
type
{
AdminUsageQueryParams
,
UsageCleanupTask
,
CreateUsageCleanupTaskRequest
}
from
'
@/api/admin/usage
'
import
type
{
AdminUsageQueryParams
,
UsageCleanupTask
,
CreateUsageCleanupTaskRequest
}
from
'
@/api/admin/usage
'
...
@@ -131,6 +145,9 @@ const localEndDate = ref('')
...
@@ -131,6 +145,9 @@ const localEndDate = ref('')
const
tasks
=
ref
<
UsageCleanupTask
[]
>
([])
const
tasks
=
ref
<
UsageCleanupTask
[]
>
([])
const
tasksLoading
=
ref
(
false
)
const
tasksLoading
=
ref
(
false
)
const
tasksPage
=
ref
(
1
)
const
tasksPageSize
=
ref
(
5
)
const
tasksTotal
=
ref
(
0
)
const
submitting
=
ref
(
false
)
const
submitting
=
ref
(
false
)
const
confirmVisible
=
ref
(
false
)
const
confirmVisible
=
ref
(
false
)
const
cancelConfirmVisible
=
ref
(
false
)
const
cancelConfirmVisible
=
ref
(
false
)
...
@@ -146,6 +163,8 @@ const resetFilters = () => {
...
@@ -146,6 +163,8 @@ const resetFilters = () => {
localEndDate
.
value
=
props
.
endDate
localEndDate
.
value
=
props
.
endDate
localFilters
.
value
.
start_date
=
localStartDate
.
value
localFilters
.
value
.
start_date
=
localStartDate
.
value
localFilters
.
value
.
end_date
=
localEndDate
.
value
localFilters
.
value
.
end_date
=
localEndDate
.
value
tasksPage
.
value
=
1
tasksTotal
.
value
=
0
}
}
const
startPolling
=
()
=>
{
const
startPolling
=
()
=>
{
...
@@ -219,8 +238,18 @@ const loadTasks = async () => {
...
@@ -219,8 +238,18 @@ const loadTasks = async () => {
if
(
!
props
.
show
)
return
if
(
!
props
.
show
)
return
tasksLoading
.
value
=
true
tasksLoading
.
value
=
true
try
{
try
{
const
res
=
await
adminUsageAPI
.
listCleanupTasks
({
page
:
1
,
page_size
:
5
})
const
res
=
await
adminUsageAPI
.
listCleanupTasks
({
page
:
tasksPage
.
value
,
page_size
:
tasksPageSize
.
value
})
tasks
.
value
=
res
.
items
||
[]
tasks
.
value
=
res
.
items
||
[]
tasksTotal
.
value
=
res
.
total
||
0
if
(
res
.
page
)
{
tasksPage
.
value
=
res
.
page
}
if
(
res
.
page_size
)
{
tasksPageSize
.
value
=
res
.
page_size
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'
Failed to load cleanup tasks:
'
,
error
)
console
.
error
(
'
Failed to load cleanup tasks:
'
,
error
)
appStore
.
showError
(
t
(
'
admin.usage.cleanup.loadFailed
'
))
appStore
.
showError
(
t
(
'
admin.usage.cleanup.loadFailed
'
))
...
@@ -229,6 +258,18 @@ const loadTasks = async () => {
...
@@ -229,6 +258,18 @@ const loadTasks = async () => {
}
}
}
}
const
handleTaskPageChange
=
(
page
:
number
)
=>
{
tasksPage
.
value
=
page
loadTasks
()
}
const
handleTaskPageSizeChange
=
(
size
:
number
)
=>
{
if
(
!
Number
.
isFinite
(
size
)
||
size
<=
0
)
return
tasksPageSize
.
value
=
size
tasksPage
.
value
=
1
loadTasks
()
}
const
openConfirm
=
()
=>
{
const
openConfirm
=
()
=>
{
confirmVisible
.
value
=
true
confirmVisible
.
value
=
true
}
}
...
...
frontend/src/components/common/Pagination.vue
View file @
771baa66
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
<
/p
>
<
/p
>
<!--
Page
size
selector
-->
<!--
Page
size
selector
-->
<
div
class
=
"
flex items-center space-x-2
"
>
<
div
v
-
if
=
"
showPageSizeSelector
"
class
=
"
flex items-center space-x-2
"
>
<
span
class
=
"
text-sm text-gray-700 dark:text-gray-300
"
<
span
class
=
"
text-sm text-gray-700 dark:text-gray-300
"
>
{{
t
(
'
pagination.perPage
'
)
}}
:
<
/spa
n
>
{{
t
(
'
pagination.perPage
'
)
}}
:
<
/spa
n
>
>
...
@@ -49,6 +49,22 @@
...
@@ -49,6 +49,22 @@
/>
/>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
v
-
if
=
"
showJump
"
class
=
"
flex items-center space-x-2
"
>
<
span
class
=
"
text-sm text-gray-700 dark:text-gray-300
"
>
{{
t
(
'
pagination.jumpTo
'
)
}}
<
/span
>
<
input
v
-
model
=
"
jumpPage
"
type
=
"
number
"
min
=
"
1
"
:
max
=
"
totalPages
"
class
=
"
input w-20 text-sm
"
:
placeholder
=
"
t('pagination.jumpPlaceholder')
"
@
keyup
.
enter
=
"
submitJump
"
/>
<
button
type
=
"
button
"
class
=
"
btn btn-ghost btn-sm
"
@
click
=
"
submitJump
"
>
{{
t
(
'
pagination.jumpAction
'
)
}}
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<!--
Desktop
pagination
buttons
-->
<!--
Desktop
pagination
buttons
-->
...
@@ -102,7 +118,7 @@
...
@@ -102,7 +118,7 @@
<
/template
>
<
/template
>
<
script
setup
lang
=
"
ts
"
>
<
script
setup
lang
=
"
ts
"
>
import
{
computed
}
from
'
vue
'
import
{
computed
,
ref
}
from
'
vue
'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useI18n
}
from
'
vue-i18n
'
import
Icon
from
'
@/components/icons/Icon.vue
'
import
Icon
from
'
@/components/icons/Icon.vue
'
import
Select
from
'
./Select.vue
'
import
Select
from
'
./Select.vue
'
...
@@ -114,6 +130,8 @@ interface Props {
...
@@ -114,6 +130,8 @@ interface Props {
page
:
number
page
:
number
pageSize
:
number
pageSize
:
number
pageSizeOptions
?:
number
[]
pageSizeOptions
?:
number
[]
showPageSizeSelector
?:
boolean
showJump
?:
boolean
}
}
interface
Emits
{
interface
Emits
{
...
@@ -122,7 +140,9 @@ interface Emits {
...
@@ -122,7 +140,9 @@ interface Emits {
}
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
pageSizeOptions
:
()
=>
[
10
,
20
,
50
,
100
]
pageSizeOptions
:
()
=>
[
10
,
20
,
50
,
100
],
showPageSizeSelector
:
true
,
showJump
:
false
}
)
}
)
const
emit
=
defineEmits
<
Emits
>
()
const
emit
=
defineEmits
<
Emits
>
()
...
@@ -146,6 +166,8 @@ const pageSizeSelectOptions = computed(() => {
...
@@ -146,6 +166,8 @@ const pageSizeSelectOptions = computed(() => {
}
))
}
))
}
)
}
)
const
jumpPage
=
ref
(
''
)
const
visiblePages
=
computed
(()
=>
{
const
visiblePages
=
computed
(()
=>
{
const
pages
:
(
number
|
string
)[]
=
[]
const
pages
:
(
number
|
string
)[]
=
[]
const
maxVisible
=
7
const
maxVisible
=
7
...
@@ -196,6 +218,16 @@ const handlePageSizeChange = (value: string | number | boolean | null) => {
...
@@ -196,6 +218,16 @@ const handlePageSizeChange = (value: string | number | boolean | null) => {
const
newPageSize
=
typeof
value
===
'
string
'
?
parseInt
(
value
)
:
value
const
newPageSize
=
typeof
value
===
'
string
'
?
parseInt
(
value
)
:
value
emit
(
'
update:pageSize
'
,
newPageSize
)
emit
(
'
update:pageSize
'
,
newPageSize
)
}
}
const
submitJump
=
()
=>
{
const
value
=
jumpPage
.
value
.
trim
()
if
(
!
value
)
return
const
pageNum
=
Number
.
parseInt
(
value
,
10
)
if
(
Number
.
isNaN
(
pageNum
))
return
const
nextPage
=
Math
.
min
(
Math
.
max
(
pageNum
,
1
),
totalPages
.
value
)
jumpPage
.
value
=
''
goToPage
(
nextPage
)
}
<
/script
>
<
/script
>
<
style
scoped
>
<
style
scoped
>
...
...
frontend/src/i18n/locales/en.ts
View file @
771baa66
...
@@ -571,7 +571,10 @@ export default {
...
@@ -571,7 +571,10 @@ export default {
previous
:
'
Previous
'
,
previous
:
'
Previous
'
,
next
:
'
Next
'
,
next
:
'
Next
'
,
perPage
:
'
Per page
'
,
perPage
:
'
Per page
'
,
goToPage
:
'
Go to page {page}
'
goToPage
:
'
Go to page {page}
'
,
jumpTo
:
'
Jump to
'
,
jumpPlaceholder
:
'
Page
'
,
jumpAction
:
'
Go
'
},
},
// Errors
// Errors
...
...
frontend/src/i18n/locales/zh.ts
View file @
771baa66
...
@@ -567,7 +567,10 @@ export default {
...
@@ -567,7 +567,10 @@ export default {
previous
:
'
上一页
'
,
previous
:
'
上一页
'
,
next
:
'
下一页
'
,
next
:
'
下一页
'
,
perPage
:
'
每页
'
,
perPage
:
'
每页
'
,
goToPage
:
'
跳转到第 {page} 页
'
goToPage
:
'
跳转到第 {page} 页
'
,
jumpTo
:
'
跳转页
'
,
jumpPlaceholder
:
'
页码
'
,
jumpAction
:
'
跳转
'
},
},
// Errors
// Errors
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment