feat: 对接主控服务接口
Build and Deploy Vue3 / build (push) Successful in 2m29s
Build and Deploy Vue3 / deploy (push) Successful in 1m3s

This commit is contained in:
2026-03-14 15:45:07 +08:00
parent 25975c8b29
commit f4dbf17ce9
21 changed files with 6323 additions and 67 deletions
+8 -61
View File
@@ -51,11 +51,10 @@
{{ formatTime(row.CreatedAt || row.created_at) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240" fixed="right">
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
<el-button link type="primary" @click="handleViewDetail(row)">详情</el-button>
<el-button link type="primary" @click="goHostGroupMapping(row)">主机组</el-button>
<el-button link type="primary" @click="handleViewDetail(row)">详情/管理</el-button>
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
@@ -104,24 +103,6 @@
</template>
</el-dialog>
<!-- 详情弹窗 -->
<el-dialog v-model="detailDialogVisible" title="主控服务详情" width="580px" destroy-on-close>
<el-descriptions :column="2" border v-if="currentDetail" v-loading="detailLoading">
<el-descriptions-item label="ID">{{ currentDetail.Id ?? currentDetail.id }}</el-descriptions-item>
<el-descriptions-item label="服务名称">{{ currentDetail.Name }}</el-descriptions-item>
<el-descriptions-item label="服务地址">{{ currentDetail.Host }}</el-descriptions-item>
<el-descriptions-item label="服务端口">{{ currentDetail.Port }}</el-descriptions-item>
<el-descriptions-item label="认证Token" :span="2">
<el-input v-if="currentDetail.Token" :model-value="currentDetail.Token" readonly show-password style="max-width: 300px" />
<span v-else class="text-muted">未设置</span>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2">{{ currentDetail.Note || '-' }}</el-descriptions-item>
<el-descriptions-item label="创建时间" :span="2">{{ formatTime(currentDetail.CreatedAt) }}</el-descriptions-item>
</el-descriptions>
<template #footer>
<el-button @click="detailDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</div>
</template>
@@ -132,7 +113,6 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Refresh, Search } from '@element-plus/icons-vue'
import {
getKvmServiceList,
getKvmServiceDetail,
createKvmService,
updateKvmService,
deleteKvmService
@@ -143,7 +123,6 @@ const router = useRouter()
const loading = ref(false)
const submitLoading = ref(false)
const detailLoading = ref(false)
const serviceList = ref([])
const total = ref(0)
const searchKey = ref('')
@@ -159,9 +138,6 @@ const dialogVisible = ref(false)
const dialogType = ref('add')
const formRef = ref(null)
const detailDialogVisible = ref(false)
const currentDetail = ref(null)
const formData = reactive({
id: undefined,
name: '',
@@ -355,45 +331,16 @@ const handleDelete = (row) => {
}).catch(() => {})
}
// 查看详情
const handleViewDetail = async (row) => {
// 优先使用原始 Id(PascalCase),回退到规范化后的 id
const rawId = row.Id ?? row.id
console.debug('[KvmService] handleViewDetail rawId:', rawId, 'row:', row)
if (rawId === undefined || rawId === null || rawId === '') {
// 查看详情 —— 跳转到详情页面
const handleViewDetail = (row) => {
const id = Number(row.Id ?? row.id)
const name = row.Name ?? row.name
if (!id) {
ElMessage.error('无法获取服务ID,请刷新列表后重试')
return
}
detailDialogVisible.value = true
detailLoading.value = true
currentDetail.value = null
try {
const res = await getKvmServiceDetail({ id: Number(rawId) })
const body = res?.data
console.debug('[KvmService] detail response body:', JSON.stringify(body))
if (body?.code === 200 && body?.data) {
currentDetail.value = normalizeService(body.data)
} else {
// 接口返回非200,显示错误但仍展示列表行数据
ElMessage.error(body?.message || '获取详情失败')
currentDetail.value = normalizeService(row)
}
} catch (error) {
console.error('获取详情失败:', error)
const errMsg = error?.response?.data?.message || error?.message || '未知错误'
ElMessage.error('获取详情失败: ' + errMsg)
currentDetail.value = normalizeService(row)
} finally {
detailLoading.value = false
}
}
// 跳转到宿主机组映射管理
const goHostGroupMapping = (row) => {
const id = Number(row.Id ?? row.id)
const name = row.Name ?? row.name
router.push({
path: '/virtualization/host-group-mapping',
path: '/virtualization/kvm-service-detail',
query: { service_id: id, service_name: name }
})
}