feat: 将页面添加分页
Build and Deploy Vue3 / build (push) Successful in 1m35s
Build and Deploy Vue3 / deploy (push) Successful in 1m5s

This commit is contained in:
2026-03-21 17:37:06 +08:00
parent 9edb59d16e
commit 25d782b050
18 changed files with 2220 additions and 154 deletions
+30 -30
View File
@@ -18,15 +18,12 @@
<el-button @click="loadList"><el-icon><Refresh /></el-icon>刷新</el-button>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<!-- 筛选栏宿主机详情下不显示 -->
<div class="filter-bar" v-if="!injectedHostId?.value">
<el-input v-model="keyword" placeholder="搜索镜像名称" clearable style="width: 220px" @keyup.enter="handleSearch" @clear="handleSearch">
<template #prefix><el-icon><Search /></el-icon></template>
</el-input>
<!-- <el-select v-if="!injectedHostId?.value" v-model="filterHostId" placeholder="选择宿主机" clearable style="width: 180px" @change="handleSearch">
<el-option v-for="h in hostOptions" :key="h.id" :label="h.name || h.ip" :value="h.id" />
</el-select> -->
<el-select v-model="filterOsType" placeholder="系统类型" clearable style="width: 130px" @change="handleSearch">
<!-- <el-select v-model="filterOsType" placeholder="系统类型" clearable style="width: 130px" @change="handleSearch">
<el-option label="Linux" value="linux" />
<el-option label="Windows" value="windows" />
</el-select>
@@ -39,7 +36,7 @@
<el-option label="下载中" value="downloading" />
<el-option label="就绪" value="ready" />
<el-option label="错误" value="error" />
</el-select>
</el-select> -->
</div>
<!-- 镜像列表 -->
@@ -56,20 +53,14 @@
<el-tag :type="row.type === 'system' ? '' : 'warning'" size="small">{{ row.type === 'system' ? '系统' : '数据' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<el-table-column label="主控状态" width="100">
<template #default="{ row }">
<el-tag :type="statusType(row.status)" size="small">{{ statusLabel(row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column v-if="injectedHostId?.value" label="同步状态" width="110">
<el-table-column label="同步状态" width="100">
<template #default="{ row }">
<el-tag :type="syncStatusType(row.sync_status)" size="small">{{ syncStatusLabel(row.sync_status) }}</el-tag>
</template>
</el-table-column>
<el-table-column v-if="injectedHostId?.value" label="宿主机状态" width="110">
<template #default="{ row }">
<el-tag v-if="row.host_status" :type="statusType(row.host_status)" size="small">{{ statusLabel(row.host_status) }}</el-tag>
<span v-else>-</span>
<el-tag :type="row.sync_status === 'synced' ? 'success' : 'warning'" size="small">{{ row.sync_status === 'synced' ? '同步' : '不同步' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="path" label="路径" min-width="200" show-overflow-tooltip />
@@ -87,10 +78,10 @@
</el-table>
<!-- 分页 -->
<div class="pagination-wrapper" v-if="total > queryParams.count">
<el-pagination v-model:current-page="queryParams.page" v-model:page-size="queryParams.count"
<div class="pagination-wrapper" v-if="total > 0">
<el-pagination v-model:current-page="queryParams.page" v-model:page-size="queryParams.page_size"
:page-sizes="[10, 20, 50]" :total="total" layout="total, sizes, prev, pager, next"
@size-change="s => { queryParams.count = s; queryParams.page = 1; loadList() }"
@size-change="s => { queryParams.page_size = s; queryParams.page = 1; loadList() }"
@current-change="p => { queryParams.page = p; loadList() }" />
</div>
@@ -253,7 +244,7 @@ const filterType = ref('')
const filterStatus = ref('')
const filterHostId = ref('')
const hostOptions = ref([])
const queryParams = reactive({ page: 1, count: 10 })
const queryParams = reactive({ page: 1, page_size: 10 })
const dialogVisible = ref(false)
const dialogType = ref('add')
@@ -329,32 +320,42 @@ const loadHostOptions = async () => {
} catch (e) { /* ignore */ }
}
const resolveHostId = async () => {
if (injectedHostId?.value) return injectedHostId.value
if (!hostOptions.value.length) await loadHostOptions()
return hostOptions.value.length ? hostOptions.value[0].id : null
}
const loadList = async () => {
if (!serviceId.value) return
loading.value = true
try {
const hostId = await resolveHostId()
let res
if (injectedHostId?.value) {
res = await getImageCompareHost({ service_id: serviceId.value, host_id: injectedHostId.value })
if (hostId) {
res = await getImageCompareHost({ service_id: serviceId.value, host_id: hostId })
} else {
const params = { service_id: serviceId.value, page: queryParams.page, count: queryParams.count }
const params = { service_id: serviceId.value, page: queryParams.page, page_size: queryParams.page_size }
if (keyword.value) params.keyword = keyword.value
if (filterOsType.value) params.os_type = filterOsType.value
if (filterType.value) params.type = filterType.value
if (filterStatus.value) params.status = filterStatus.value
if (filterHostId.value) params.host_id = filterHostId.value
res = await getImageList(params)
}
const body = res?.data
if (body?.code === 200 && body?.data) {
const inner = body.data
if (injectedHostId?.value && Array.isArray(inner.data)) {
imageList.value = inner.data.map(item => ({
if (hostId && Array.isArray(inner.data)) {
let items = inner.data.map(item => ({
...(item.image || {}),
sync_status: item.sync_status || '',
host_status: item.host_status || ''
sync_status: item.sync_status || 'not_synced',
}))
total.value = inner.total ?? imageList.value.length
if (keyword.value) {
const kw = keyword.value.toLowerCase()
items = items.filter(img => img.name?.toLowerCase().includes(kw))
}
imageList.value = items
total.value = inner.total ?? items.length
} else {
const items = Array.isArray(inner) ? inner : (inner.images || inner.data || inner.list || [])
imageList.value = items
@@ -572,7 +573,6 @@ const goBack = () => { router.push('/virtualization/kvm-service') }
onMounted(() => {
if (serviceId.value) {
loadList()
if (!injectedHostId?.value) loadHostOptions()
}
})
</script>