fix: 修改内存的基础单位为kb
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
<div class="vm-config">
|
||||
<el-tag size="small" type="info" v-if="row.vcpu">{{ row.vcpu }}核</el-tag>
|
||||
<el-tag size="small" type="info" v-if="row.memory">{{ formatMemory(row.memory) }}</el-tag>
|
||||
<el-tag size="small" type="info" v-if="row.system_size">{{ row.system_size }}MB盘</el-tag>
|
||||
<el-tag size="small" type="info" v-if="row.system_size">{{ row.system_size }}GB盘</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -58,10 +58,26 @@
|
||||
<template #default="{ row }">{{ getHostLabel(row.host_id) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="user_id" label="用户" width="80" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<el-table-column label="操作" width="280" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleGoDetail(row)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button link type="primary" size="small" @click="handleGoDetail(row)">详情</el-button>
|
||||
<el-button link type="success" size="small" @click="handlePower(row, 'start')" :disabled="row.status === 'running'">启动</el-button>
|
||||
<el-button link type="warning" size="small" @click="handlePower(row, 'stop')" :disabled="row.status === 'stopped' || row.status === 'stop'">关机</el-button>
|
||||
<el-dropdown trigger="click" @command="cmd => handleMoreAction(row, cmd)" style="margin-left: 4px">
|
||||
<el-button link type="info" size="small">更多<el-icon class="el-icon--right"><ArrowDown /></el-icon></el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="reboot">重启</el-dropdown-item>
|
||||
<el-dropdown-item command="suspend">暂停</el-dropdown-item>
|
||||
<el-dropdown-item command="resume" v-if="row.status === 'paused'">恢复</el-dropdown-item>
|
||||
<el-dropdown-item command="rebuild" divided>重建</el-dropdown-item>
|
||||
<el-dropdown-item command="rescue">救援模式</el-dropdown-item>
|
||||
<el-dropdown-item command="exit_rescue">退出救援</el-dropdown-item>
|
||||
<el-dropdown-item command="detail" divided>查看详情</el-dropdown-item>
|
||||
<el-dropdown-item command="delete" divided style="color: #f56c6c">删除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -108,7 +124,7 @@
|
||||
<div class="bind-selector-row">
|
||||
<el-input :model-value="createForm.host_group_id ? `${createForm._groupName || ''} (ID: ${createForm.host_group_id})` : '未选择'" disabled style="flex: 1" />
|
||||
<el-button type="primary" @click="showHostGroupSelector = true" style="margin-left: 8px">选择</el-button>
|
||||
<el-button v-if="createForm.host_group_id" @click="createForm.host_group_id = 0; createForm._groupName = ''" style="margin-left: 4px">清除</el-button>
|
||||
<el-button v-if="createForm.host_group_id" @click="createForm.host_group_id = null; createForm._groupName = ''" style="margin-left: 4px">清除</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
@@ -119,20 +135,20 @@
|
||||
<el-select v-model="memoryUnit" class="resource-unit-select">
|
||||
<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="1" controls-position="right" class="resource-input" />
|
||||
<el-input-number v-model="memoryDisplay" :min="0" controls-position="right" class="resource-input" />
|
||||
</div>
|
||||
<div class="resource-item">
|
||||
<span class="resource-label">* 系统盘</span>
|
||||
<el-select v-model="diskUnit" class="resource-unit-select">
|
||||
<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="1" controls-position="right" class="resource-input" />
|
||||
<el-input-number v-model="diskDisplay" :min="0" controls-position="right" class="resource-input" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-row">
|
||||
<div class="resource-item">
|
||||
<span class="resource-label">* CPU(核)</span>
|
||||
<el-input-number v-model="createForm.vcpu" :min="1" controls-position="right" class="resource-input" />
|
||||
<el-input-number v-model="createForm.vcpu" :min="0" controls-position="right" class="resource-input" />
|
||||
</div>
|
||||
<div class="resource-item">
|
||||
<span class="resource-label">下行带宽(Mbps)</span>
|
||||
@@ -155,10 +171,10 @@
|
||||
<el-input-number v-model="createForm.ip_num" :min="1" controls-position="right" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="网络IP列表" v-if="ipMode === 'ids'">
|
||||
<el-select v-model="createForm.network_ids" multiple filterable placeholder="选择网络IP" style="width: 100%">
|
||||
<el-option v-for="n in networkOptions" :key="n.id" :label="`${n.name || ''} - ${n.address || n.ip || ''} (ID: ${n.id})`" :value="n.id" />
|
||||
<el-select v-model="createForm.network_ids" multiple filterable placeholder="选择可用网络IP" style="width: 100%">
|
||||
<el-option v-for="n in networkOptions" :key="n.id" :label="`${n.name || ''} - ${n.address || n.ip || ''}`" :value="n.id" />
|
||||
</el-select>
|
||||
<div class="form-tip" v-if="!networkOptions.length">请先选择宿主机以加载可用网络</div>
|
||||
<div class="form-tip" v-if="!networkOptions.length">请先选择宿主机以加载可用网络(仅显示未使用的网络)</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -193,7 +209,7 @@
|
||||
<el-descriptions-item label="名称">{{ currentDetail.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="CPU">{{ currentDetail.vcpu }} 核</el-descriptions-item>
|
||||
<el-descriptions-item label="内存">{{ formatMemory(currentDetail.memory) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="系统盘">{{ currentDetail.system_size }} MB</el-descriptions-item>
|
||||
<el-descriptions-item label="系统盘">{{ currentDetail.system_size }} GB</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="vmStatusType(currentDetail.status)" size="small">{{ vmStatusLabel(currentDetail.status) }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
@@ -304,8 +320,9 @@ const router = useRouter()
|
||||
const embedded = inject('embedded', false)
|
||||
const injectedServiceId = inject('serviceId', null)
|
||||
const injectedServiceName = inject('serviceName', null)
|
||||
const injectedHostId = inject('hostId', null)
|
||||
const serviceId = computed(() => injectedServiceId?.value || parseInt(route.query.service_id) || 0)
|
||||
const hostId = computed(() => parseInt(route.query.host_id) || 0)
|
||||
const hostId = computed(() => injectedHostId?.value || parseInt(route.query.host_id) || 0)
|
||||
const serviceName = computed(() => injectedServiceName?.value || route.query.service_name || '')
|
||||
|
||||
const loading = ref(false)
|
||||
@@ -329,35 +346,37 @@ const hostMode = ref('host')
|
||||
const ipMode = ref('num')
|
||||
const networkOptions = ref([])
|
||||
|
||||
// 内存单位: API传输单位为 KB
|
||||
// 内存单位: API传输单位为 bytes
|
||||
const memoryUnitOptions = [
|
||||
{ label: 'KB', factor: 1 },
|
||||
{ label: 'MB', factor: 1024 },
|
||||
{ label: 'GB', factor: 1048576 }
|
||||
]
|
||||
const memoryUnit = ref('KB')
|
||||
const memoryUnit = ref('GB')
|
||||
const getMemFactor = () => memoryUnitOptions.find(u => u.label === memoryUnit.value)?.factor || 1
|
||||
const memoryDisplay = computed({
|
||||
get: () => Math.round(createForm.memory / getMemFactor()),
|
||||
set: (v) => { createForm.memory = Math.round(v * getMemFactor()) }
|
||||
})
|
||||
|
||||
// 系统盘单位: API传输单位为 MB
|
||||
// 系统盘: API传输单位为 GB
|
||||
const diskUnitOptions = [
|
||||
{ label: 'MB', factor: 1 },
|
||||
{ label: 'GB', factor: 1024 }
|
||||
{ label: 'GB', factor: 1 },
|
||||
{ label: 'TB', factor: 1024 }
|
||||
]
|
||||
const diskUnit = ref('GB')
|
||||
const getDiskFactor = () => diskUnitOptions.find(u => u.label === diskUnit.value)?.factor || 1
|
||||
const diskDisplay = computed({
|
||||
get: () => Math.round(createForm.system_size / getDiskFactor()),
|
||||
get: () => {
|
||||
const f = getDiskFactor()
|
||||
return f === 1 ? createForm.system_size : +(createForm.system_size / f).toFixed(2)
|
||||
},
|
||||
set: (v) => { createForm.system_size = Math.round(v * getDiskFactor()) }
|
||||
})
|
||||
|
||||
const loadNetworkOptions = async (hostId) => {
|
||||
if (!hostId) return
|
||||
try {
|
||||
const res = await getNetworkList({ service_id: serviceId.value, host_id: hostId, page: 1, page_size: 200 })
|
||||
const res = await getNetworkList({ service_id: serviceId.value, host_id: hostId, used: false, page: 1, page_size: 200 })
|
||||
const body = res?.data
|
||||
if (body?.code === 200 && body?.data) {
|
||||
const inner = body.data
|
||||
@@ -377,7 +396,7 @@ const loadHostOptions = async () => {
|
||||
const body = res?.data
|
||||
if (body?.code === 200 && body?.data) {
|
||||
const inner = body.data
|
||||
hostOptions.value = inner.hosts || inner.data || (Array.isArray(inner) ? inner : [])
|
||||
hostOptions.value = Array.isArray(inner) ? inner : (inner.hosts || inner.list || inner.data || [])
|
||||
}
|
||||
} catch (e) { console.error('加载宿主机列表失败:', e) }
|
||||
}
|
||||
@@ -402,16 +421,16 @@ const rebuildImageName = ref('')
|
||||
const vmMetricsData = ref(null)
|
||||
|
||||
const createForm = reactive({
|
||||
name: '', host_id: 0, image_id: 0, vcpu: 1, memory: 1048576,
|
||||
system_size: 10240, rx_bandwidth: 0, tx_bandwidth: 0,
|
||||
host_group_id: 0, user_id: 0, ip_num: 0, network_ids: [],
|
||||
name: '', host_id: null, image_id: 0, vcpu: 0, memory: 0,
|
||||
system_size: 0, rx_bandwidth: 0, tx_bandwidth: 0,
|
||||
host_group_id: null, user_id: 0, ip_num: 0, network_ids: [],
|
||||
_imageName: '', _groupName: '', _userName: ''
|
||||
})
|
||||
|
||||
const createRules = {
|
||||
image_id: [{ required: true, message: '请选择镜像', trigger: 'blur', type: 'number', min: 1 }],
|
||||
vcpu: [{ required: true, message: '请输入CPU核数', trigger: 'blur' }],
|
||||
memory: [{ required: true, message: '请输入内存(KB)', trigger: 'blur' }],
|
||||
memory: [{ required: true, message: '请输入内存', trigger: 'blur' }],
|
||||
system_size: [{ required: true, message: '请输入系统盘大小', trigger: 'blur' }],
|
||||
user_id: [{ required: true, message: '请选择用户', trigger: 'change', type: 'number', min: 1 }]
|
||||
}
|
||||
@@ -430,6 +449,8 @@ const vmStatusLabel = (s) => ({
|
||||
|
||||
const formatMemory = (kb) => {
|
||||
if (!kb) return '-'
|
||||
kb = Number(kb)
|
||||
if (kb >= 1073741824) return (kb / 1073741824).toFixed(1) + ' TB'
|
||||
if (kb >= 1048576) return (kb / 1048576).toFixed(1) + ' GB'
|
||||
if (kb >= 1024) return (kb / 1024).toFixed(0) + ' MB'
|
||||
return kb + ' KB'
|
||||
@@ -484,14 +505,16 @@ const handleSearch = () => { queryParams.page = 1; loadList() }
|
||||
|
||||
const handleAdd = () => {
|
||||
Object.assign(createForm, {
|
||||
name: '', host_id: hostId.value || 0, image_id: 0,
|
||||
vcpu: 1, memory: 1048576, system_size: 10240,
|
||||
rx_bandwidth: 0, tx_bandwidth: 0, host_group_id: 0, user_id: 0, ip_num: 0, network_ids: [],
|
||||
name: '', host_id: null, image_id: 0,
|
||||
vcpu: 0, memory: 0, system_size: 0,
|
||||
rx_bandwidth: 0, tx_bandwidth: 0, host_group_id: null, user_id: 0, ip_num: 0, network_ids: [],
|
||||
_imageName: '', _groupName: '', _userName: ''
|
||||
})
|
||||
memoryUnit.value = 'GB'
|
||||
diskUnit.value = 'GB'
|
||||
hostMode.value = 'host'
|
||||
ipMode.value = 'num'
|
||||
if (createForm.host_id) loadNetworkOptions(createForm.host_id)
|
||||
networkOptions.value = []
|
||||
createDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -552,9 +575,13 @@ const handlePower = (row, action) => {
|
||||
}
|
||||
|
||||
const handleMoreAction = (row, command) => {
|
||||
const powerActions = ['reboot', 'suspend', 'resume']
|
||||
if (powerActions.includes(command)) { handlePower(row, command); return }
|
||||
if (command === 'rebuild') handleRebuild(row)
|
||||
else if (command === 'rescue') handleRescue(row)
|
||||
else if (command === 'exit_rescue') handleExitRescue(row)
|
||||
else if (command === 'detail') handleViewDetail(row)
|
||||
else if (command === 'delete') handleDelete(row)
|
||||
}
|
||||
|
||||
const handleRebuild = (row) => {
|
||||
@@ -639,7 +666,7 @@ const fetchVmMetrics = async (vm) => {
|
||||
}
|
||||
|
||||
const handleGoDetail = (row) => {
|
||||
router.push({ path: '/virtualization/vm-detail', query: { service_id: serviceId.value, service_name: serviceName.value, id: row.id } })
|
||||
router.push({ path: '/virtualization/vm-detail', query: { service_id: serviceId.value, service_name: serviceName.value, vm_id: row.id } })
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
|
||||
Reference in New Issue
Block a user