fix: 提交修改
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" @click="handleAddGroup"><el-icon><FolderAdd /></el-icon>新建宿主机组</el-button>
|
||||
<el-button type="success" @click="handleAddHost"><el-icon><Plus /></el-icon>新增宿主机</el-button>
|
||||
<el-button type="warning" @click="openTokenDialog"><el-icon><Key /></el-icon>创建注册令牌</el-button>
|
||||
<el-button @click="loadTreeData"><el-icon><Refresh /></el-icon>刷新</el-button>
|
||||
</div>
|
||||
|
||||
@@ -86,25 +87,126 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 新建/编辑宿主机组弹窗 -->
|
||||
<el-dialog v-model="groupDialogVisible" :title="groupDialogType === 'add' ? '新建宿主机组' : '编辑宿主机组'" width="480px" destroy-on-close>
|
||||
<el-form ref="groupFormRef" :model="groupForm" :rules="groupFormRules" label-width="80px">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="groupForm.name" placeholder="宿主机组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="groupForm.note" type="textarea" :rows="3" placeholder="备注(可选)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="父级组">
|
||||
<el-select v-model="groupForm.parent_id" placeholder="选择父级" style="width: 100%" clearable @clear="groupForm.parent_id = 0">
|
||||
<el-option :value="0" label="无(顶级分组)" />
|
||||
<el-option v-for="g in parentGroupOptions" :key="g.id" :value="g.id" :label="`${g.name} (ID: ${g.id})`" :disabled="g.id === groupForm.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 创建注册令牌弹窗 -->
|
||||
<el-dialog v-model="tokenDialogVisible" title="创建宿主机注册令牌" width="700px" destroy-on-close class="token-dialog">
|
||||
<el-form ref="tokenFormRef" :model="tokenForm" :rules="tokenRules" label-width="120px">
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">基本信息</div>
|
||||
<el-form-item label="宿主机名称" prop="name">
|
||||
<el-input v-model="tokenForm.name" placeholder="为该宿主机命名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属宿主机组" prop="host_group_id">
|
||||
<el-select v-model="tokenForm.host_group_id" placeholder="请选择宿主机组" filterable style="width: 100%">
|
||||
<el-option :value="0" label="请选择" disabled />
|
||||
<el-option v-for="g in allGroups" :key="g.id" :value="g.id" :label="`${g.name} (ID: ${g.id})`" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="宿主机描述">
|
||||
<el-input v-model="tokenForm.description" type="textarea" :rows="2" placeholder="宿主机描述(可选)" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">资源配额</div>
|
||||
<div class="tk-resource-grid">
|
||||
<el-form-item label="CPU" prop="max_cpu" class="tk-res-item">
|
||||
<el-input-number v-model="tokenForm.max_cpu" :min="1" controls-position="right" /><span class="tk-res-unit">核</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="内存" prop="max_memory" class="tk-res-item">
|
||||
<el-input-number v-model="tokenMemDisplay" :min="0" controls-position="right" />
|
||||
<el-select v-model="tokenMemUnit" class="tk-unit-select">
|
||||
<el-option v-for="u in memoryUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="磁盘" prop="max_disk" class="tk-res-item">
|
||||
<el-input-number v-model="tokenDiskDisplay" :min="0" controls-position="right" />
|
||||
<el-select v-model="tokenDiskUnit" class="tk-unit-select">
|
||||
<el-option v-for="u in diskUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="下行带宽" class="tk-res-item">
|
||||
<el-input-number v-model="tokenForm.rx_bandwidth" :min="0" controls-position="right" /><span class="tk-res-unit">Mbps</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="上行带宽" class="tk-res-item">
|
||||
<el-input-number v-model="tokenForm.tx_bandwidth" :min="0" controls-position="right" /><span class="tk-res-unit">Mbps</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">令牌有效期</div>
|
||||
<el-form-item label="有效期" prop="expire_hours">
|
||||
<el-input-number v-model="tokenForm.expire_hours" :min="1" :max="8760" controls-position="right" style="width: 100%" />
|
||||
<div class="form-hint">单位:小时。默认 24 小时,最大 8760 小时(365天)</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="groupDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitGroupForm">确定</el-button>
|
||||
<div class="tk-dialog-footer">
|
||||
<el-button @click="tokenDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="tokenSubmitLoading" @click="handleTokenSubmit">
|
||||
<el-icon><Key /></el-icon>创建令牌
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 令牌结果弹窗 -->
|
||||
<el-dialog v-model="tokenResultVisible" title="注册令牌已生成" width="560px" :close-on-click-modal="false" class="token-result-dialog">
|
||||
<div class="tk-result-wrapper">
|
||||
<div class="tk-result-header">
|
||||
<el-icon class="tk-result-icon"><Key /></el-icon>
|
||||
<div>
|
||||
<div class="tk-result-name">{{ tokenResultInfo.name }}</div>
|
||||
<div class="tk-result-meta">有效期 {{ tokenResultInfo.expire_hours }} 小时</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-alert type="warning" :closable="false" show-icon style="margin-bottom: 16px">
|
||||
<template #title>请立即复制并保存此令牌,关闭后将无法再次查看</template>
|
||||
</el-alert>
|
||||
<div class="tk-token-block">
|
||||
<div class="tk-token-label">后端地址</div>
|
||||
<div class="tk-token-value">{{ baseUrl }}</div>
|
||||
</div>
|
||||
<div class="tk-token-block">
|
||||
<div class="tk-token-label">service_id(主控服务ID)</div>
|
||||
<div class="tk-token-value">{{ tokenResultInfo.service_id }}</div>
|
||||
</div>
|
||||
<div class="tk-token-block">
|
||||
<div class="tk-token-label">注册令牌</div>
|
||||
<div class="tk-token-value">{{ tokenResultInfo.token }}</div>
|
||||
</div>
|
||||
<el-button type="primary" class="tk-copy-btn" @click="copyToken">
|
||||
<el-icon><CopyDocument /></el-icon>复制令牌到剪贴板
|
||||
</el-button>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="tokenResultVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新建/编辑宿主机组弹窗 -->
|
||||
<el-dialog v-model="groupDialogVisible" :title="groupDialogType === 'add' ? '新建宿主机组' : '编辑宿主机组'" width="480px" destroy-on-close class="tk-dialog">
|
||||
<el-form ref="groupFormRef" :model="groupForm" :rules="groupFormRules" label-width="80px">
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">基本信息</div>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="groupForm.name" placeholder="宿主机组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="groupForm.note" type="textarea" :rows="3" placeholder="备注(可选)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="父级组">
|
||||
<el-select v-model="groupForm.parent_id" placeholder="选择父级" style="width: 100%" clearable @clear="groupForm.parent_id = 0">
|
||||
<el-option :value="0" label="无(顶级分组)" />
|
||||
<el-option v-for="g in parentGroupOptions" :key="g.id" :value="g.id" :label="`${g.name} (ID: ${g.id})`" :disabled="g.id === groupForm.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="tk-dialog-footer">
|
||||
<el-button @click="groupDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitGroupForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
@@ -166,84 +268,82 @@
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新建/编辑宿主机弹窗 -->
|
||||
<el-dialog v-model="hostDialogVisible" :title="hostDialogType === 'add' ? '新增宿主机' : '编辑宿主机'" width="800px" destroy-on-close>
|
||||
<el-form ref="hostFormRef" :model="hostForm" :rules="hostFormRules" label-width="120px">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="hostForm.name" placeholder="宿主机名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务地址" prop="base_url">
|
||||
<el-input v-model="hostForm.base_url" placeholder="宿主机服务 URL" />
|
||||
</el-form-item>
|
||||
<el-form-item label="IP 地址" prop="ip">
|
||||
<el-input v-model="hostForm.ip" placeholder="宿主机 IP" />
|
||||
</el-form-item>
|
||||
<el-form-item label="认证Token">
|
||||
<el-input v-model="hostForm.token" placeholder="可选" show-password />
|
||||
</el-form-item>
|
||||
<el-divider content-position="left">SSH 配置</el-divider>
|
||||
<el-form-item label="SSH 端口">
|
||||
<el-input-number v-model="hostForm.port" :min="0" :max="65535" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SSH 用户名">
|
||||
<el-input v-model="hostForm.user" placeholder="默认 tunneluser" />
|
||||
</el-form-item>
|
||||
<el-form-item label="SSH 密码">
|
||||
<el-input v-model="hostForm.password" placeholder="可选" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="SSH 私钥">
|
||||
<el-input v-model="hostForm.private_key" type="textarea" :rows="4" placeholder="SSH 私钥内容(可选)" />
|
||||
</el-form-item>
|
||||
<el-divider content-position="left">资源限制</el-divider>
|
||||
<el-form-item label="最大CPU(核)">
|
||||
<el-input-number v-model="hostForm.max_cpu" :min="0" controls-position="right" style="width: 240px" />
|
||||
</el-form-item>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="最大内存">
|
||||
<div class="unit-input-row">
|
||||
<el-select v-model="memoryUnit" style="width: 70px; flex-shrink: 0;" size="default">
|
||||
<el-option v-for="u in memoryUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
<el-input-number v-model="memoryDisplay" :min="0" controls-position="right" class="wide-number" />
|
||||
</div>
|
||||
<el-dialog v-model="hostDialogVisible" :title="hostDialogType === 'add' ? '新增宿主机' : '编辑宿主机'" width="800px" destroy-on-close class="tk-dialog">
|
||||
<el-form ref="hostFormRef" :model="hostForm" :rules="hostFormRules" label-width="100px">
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">基本信息</div>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="hostForm.name" placeholder="宿主机名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="服务地址" prop="base_url">
|
||||
<el-input v-model="hostForm.base_url" placeholder="宿主机服务 URL" />
|
||||
</el-form-item>
|
||||
<el-form-item label="IP 地址" prop="ip">
|
||||
<el-input v-model="hostForm.ip" placeholder="宿主机 IP" />
|
||||
</el-form-item>
|
||||
<el-form-item label="认证Token">
|
||||
<el-input v-model="hostForm.token" placeholder="可选" show-password />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">SSH 配置</div>
|
||||
<el-form-item label="端口">
|
||||
<el-input-number v-model="hostForm.port" :min="0" :max="65535" controls-position="right" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="hostForm.user" placeholder="默认 tunneluser" />
|
||||
</el-form-item>
|
||||
<el-form-item label="密码">
|
||||
<el-input v-model="hostForm.password" placeholder="可选" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="私钥">
|
||||
<el-input v-model="hostForm.private_key" type="textarea" :rows="4" placeholder="SSH 私钥内容(可选)" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">资源限制</div>
|
||||
<div class="tk-resource-grid">
|
||||
<el-form-item label="CPU">
|
||||
<el-input-number v-model="hostForm.max_cpu" :min="0" controls-position="right" /><span class="tk-res-unit">核</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="最大磁盘">
|
||||
<div class="unit-input-row">
|
||||
<el-select v-model="diskUnit" style="width: 70px; flex-shrink: 0;" size="default">
|
||||
<el-option v-for="u in diskUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
<el-input-number v-model="diskDisplay" :min="0" controls-position="right" class="wide-number" />
|
||||
</div>
|
||||
<el-form-item label="内存">
|
||||
<el-input-number v-model="memoryDisplay" :min="0" controls-position="right" />
|
||||
<el-select v-model="memoryUnit" class="tk-unit-select">
|
||||
<el-option v-for="u in memoryUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="下行带宽(Mbps)">
|
||||
<el-input-number v-model="hostForm.rx_bandwidth" :min="0" controls-position="right" style="width: 100%" />
|
||||
<el-form-item label="磁盘">
|
||||
<el-input-number v-model="diskDisplay" :min="0" controls-position="right" />
|
||||
<el-select v-model="diskUnit" class="tk-unit-select">
|
||||
<el-option v-for="u in diskUnitOptions" :key="u.label" :label="u.label" :value="u.label" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上行带宽(Mbps)">
|
||||
<el-input-number v-model="hostForm.tx_bandwidth" :min="0" controls-position="right" style="width: 100%" />
|
||||
<el-form-item label="下行带宽">
|
||||
<el-input-number v-model="hostForm.rx_bandwidth" :min="0" controls-position="right" /><span class="tk-res-unit">Mbps</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="宿主机组">
|
||||
<el-select v-model="hostForm.host_group_id" placeholder="选择宿主机组" clearable filterable style="width: 100%">
|
||||
<el-option :value="0" label="不选择" />
|
||||
<el-option v-for="g in allGroups" :key="g.id" :value="g.id" :label="`${g.name} (ID: ${g.id})`" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="介绍">
|
||||
<el-input v-model="hostForm.description" type="textarea" :rows="2" placeholder="可选" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上行带宽">
|
||||
<el-input-number v-model="hostForm.tx_bandwidth" :min="0" controls-position="right" /><span class="tk-res-unit">Mbps</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tk-section">
|
||||
<div class="tk-section-title">其他配置</div>
|
||||
<el-form-item label="宿主机组">
|
||||
<el-select v-model="hostForm.host_group_id" placeholder="选择宿主机组" clearable filterable style="width: 100%">
|
||||
<el-option :value="0" label="不选择" />
|
||||
<el-option v-for="g in allGroups" :key="g.id" :value="g.id" :label="`${g.name} (ID: ${g.id})`" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="介绍">
|
||||
<el-input v-model="hostForm.description" type="textarea" :rows="2" placeholder="可选" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="hostDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitHostForm">确定</el-button>
|
||||
<div class="tk-dialog-footer">
|
||||
<el-button @click="hostDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitHostForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -253,15 +353,17 @@
|
||||
import { ref, reactive, computed, inject, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, Refresh, ArrowLeft, ArrowRight, Loading, FolderAdd } from '@element-plus/icons-vue'
|
||||
import { Plus, Refresh, ArrowLeft, ArrowRight, Loading, FolderAdd, Key, CopyDocument } from '@element-plus/icons-vue'
|
||||
import {
|
||||
getRemoteHostGroupList, getRemoteHostGroupTree, getRemoteHostGroupDetail,
|
||||
createRemoteHostGroup, updateRemoteHostGroup, deleteRemoteHostGroup,
|
||||
getOptimalHostInfo,
|
||||
getRemoteHostList, getRemoteHostDetail,
|
||||
addRemoteHost, updateRemoteHost, deleteRemoteHost
|
||||
addRemoteHost, updateRemoteHost, deleteRemoteHost,
|
||||
createHostToken
|
||||
} from '@/api/admin/kvmService'
|
||||
import { extractApiError } from '@/utils/kvmErrorUtil'
|
||||
import { baseUrl } from '@/config/env'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -609,6 +711,106 @@ const handleDeleteHost = (row) => {
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
// ========== 创建注册令牌 ==========
|
||||
const tokenDialogVisible = ref(false)
|
||||
const tokenSubmitLoading = ref(false)
|
||||
const tokenResultVisible = ref(false)
|
||||
const tokenFormRef = ref(null)
|
||||
const tokenMemUnit = ref('GB')
|
||||
const tokenDiskUnit = ref('GB')
|
||||
|
||||
const tokenForm = reactive({
|
||||
name: '', host_group_id: 0, max_cpu: 4,
|
||||
max_memory: 4194304, max_disk: 100,
|
||||
rx_bandwidth: 100, tx_bandwidth: 100,
|
||||
description: '', expire_hours: 24
|
||||
})
|
||||
const tokenResultInfo = reactive({ name: '', expire_hours: 24, token: '', service_id: 0 })
|
||||
const tokenRules = {
|
||||
name: [{ required: true, message: '请输入宿主机名称', trigger: 'blur' }],
|
||||
host_group_id: [{ required: true, type: 'number', min: 1, message: '请选择宿主机组', trigger: 'change' }],
|
||||
max_cpu: [{ required: true, type: 'number', min: 1, message: '请设置最大CPU核数', trigger: 'change' }],
|
||||
max_memory: [{ required: true, type: 'number', min: 1, message: '请设置最大内存', trigger: 'change' }],
|
||||
max_disk: [{ required: true, type: 'number', min: 1, message: '请设置最大磁盘', trigger: 'change' }],
|
||||
expire_hours: [{ required: true, type: 'number', min: 1, message: '请设置有效期', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const getTokenMemFactor = () => memoryUnitOptions.find(u => u.label === tokenMemUnit.value)?.factor || 1048576
|
||||
const getTokenDiskFactor = () => diskUnitOptions.find(u => u.label === tokenDiskUnit.value)?.factor || 1
|
||||
const tokenMemDisplay = computed({
|
||||
get: () => tokenForm.max_memory ? +(tokenForm.max_memory / getTokenMemFactor()).toFixed(2) : 0,
|
||||
set: (v) => { tokenForm.max_memory = Math.round((v || 0) * getTokenMemFactor()) }
|
||||
})
|
||||
const tokenDiskDisplay = computed({
|
||||
get: () => tokenForm.max_disk ? +(tokenForm.max_disk / getTokenDiskFactor()).toFixed(2) : 0,
|
||||
set: (v) => { tokenForm.max_disk = Math.round((v || 0) * getTokenDiskFactor()) }
|
||||
})
|
||||
|
||||
const openTokenDialog = () => {
|
||||
Object.assign(tokenForm, {
|
||||
name: '', host_group_id: 0, max_cpu: 4,
|
||||
max_memory: 4194304, max_disk: 100,
|
||||
rx_bandwidth: 100, tx_bandwidth: 100,
|
||||
description: '', expire_hours: 24
|
||||
})
|
||||
tokenMemUnit.value = 'GB'
|
||||
tokenDiskUnit.value = 'GB'
|
||||
tokenDialogVisible.value = true
|
||||
}
|
||||
|
||||
const handleTokenSubmit = () => {
|
||||
tokenFormRef.value?.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
tokenSubmitLoading.value = true
|
||||
try {
|
||||
const fd = new FormData()
|
||||
fd.append('service_id', serviceId.value)
|
||||
fd.append('name', tokenForm.name)
|
||||
fd.append('host_group_id', tokenForm.host_group_id)
|
||||
fd.append('max_cpu', tokenForm.max_cpu)
|
||||
fd.append('max_memory', tokenForm.max_memory)
|
||||
fd.append('max_disk', tokenForm.max_disk)
|
||||
fd.append('rx_bandwidth', tokenForm.rx_bandwidth)
|
||||
fd.append('tx_bandwidth', tokenForm.tx_bandwidth)
|
||||
fd.append('description', tokenForm.description || '')
|
||||
fd.append('expire_hours', tokenForm.expire_hours)
|
||||
const res = await createHostToken(fd)
|
||||
const body = res?.data
|
||||
if (body?.code === 200 && body?.data) {
|
||||
tokenResultInfo.name = tokenForm.name
|
||||
tokenResultInfo.expire_hours = tokenForm.expire_hours
|
||||
tokenResultInfo.token = body.data.token || body.data.Token || JSON.stringify(body.data)
|
||||
tokenResultInfo.service_id = serviceId.value
|
||||
tokenDialogVisible.value = false
|
||||
tokenResultVisible.value = true
|
||||
ElMessage.success('注册令牌创建成功')
|
||||
} else {
|
||||
ElMessage.error(extractApiError(body, '创建令牌失败'))
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error(extractApiError(e?.response?.data, '创建令牌失败'))
|
||||
} finally {
|
||||
tokenSubmitLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const copyToken = async () => {
|
||||
const text = `后端地址:${baseUrl}\nservice_id:${tokenResultInfo.service_id}\n注册令牌:${tokenResultInfo.token}`
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
ElMessage.success('令牌信息已复制到剪贴板')
|
||||
} catch {
|
||||
const ta = document.createElement('textarea')
|
||||
ta.value = text
|
||||
document.body.appendChild(ta)
|
||||
ta.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(ta)
|
||||
ElMessage.success('令牌信息已复制到剪贴板')
|
||||
}
|
||||
}
|
||||
|
||||
const goBack = () => { router.push('/virtualization/kvm-service') }
|
||||
|
||||
onMounted(() => { if (serviceId.value) loadTreeData() })
|
||||
@@ -616,11 +818,6 @@ onMounted(() => { if (serviceId.value) loadTreeData() })
|
||||
|
||||
<style scoped>
|
||||
.host-tree-container { padding: 0; }
|
||||
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
|
||||
.header-left { display: flex; align-items: center; gap: 16px; }
|
||||
.header-info h3 { margin: 0; font-size: 18px; color: #303133; }
|
||||
.sub-info { font-size: 13px; color: #909399; }
|
||||
.toolbar { display: flex; gap: 8px; margin-bottom: 16px; }
|
||||
|
||||
.tree-name-cell {
|
||||
display: flex;
|
||||
@@ -640,10 +837,6 @@ onMounted(() => { if (serviceId.value) loadTreeData() })
|
||||
.expand-placeholder { width: 20px; display: inline-block; }
|
||||
.row-name { font-weight: 500; color: #303133; }
|
||||
|
||||
.unit-input-row { display: flex; gap: 6px; width: 100%; }
|
||||
.wide-number { flex: 1; min-width: 140px; }
|
||||
.host-addr { color: #409eff; font-size: 13px; }
|
||||
.host-url { color: #909399; font-size: 12px; }
|
||||
.resource-info { display: flex; gap: 4px; flex-wrap: wrap; }
|
||||
.text-muted { color: #c0c4cc; font-size: 12px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user