diff --git a/src/views/virtualization/HostDetail.vue b/src/views/virtualization/HostDetail.vue
index 959ad84..5916eae 100644
--- a/src/views/virtualization/HostDetail.vue
+++ b/src/views/virtualization/HostDetail.vue
@@ -137,10 +137,16 @@
-
-
-
{{ f.label }}
-
{{ formatDiskIoVal(detail[f.key], f) }}
+
+
+ {{ f.label }}带宽
+ {{ formatDiskIoVal(detail[f.key], true) }}
+
+
+
+
+ {{ f.label }} IOPS
+ {{ formatDiskIoVal(detail[f.key], false) }}
@@ -428,11 +434,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ formData[f.key] = Math.round((v || 0) * getIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -508,11 +527,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ tokenForm[f.key] = Math.round((v || 0) * getTokenIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -676,25 +708,42 @@ const diskIoDefaults = {
read_bytes_sec_max: 314572800, write_bytes_sec_max: 314572800,
read_iops_sec_max: 1000, write_iops_sec_max: 1000
}
-const diskIoFields = [
- { key: 'read_bytes_sec', label: '读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec', label: '写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec', label: '读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec', label: '写入 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'read_bytes_sec_max', label: '突发读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec_max', label: '突发写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec_max', label: '突发读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec_max', label: '突发写入 IOPS', unit: 'IOPS', isBandwidth: false }
+const diskIoBwFields = [
+ { key: 'read_bytes_sec', label: '读取' },
+ { key: 'write_bytes_sec', label: '写入' },
+ { key: 'read_bytes_sec_max', label: '突发读取' },
+ { key: 'write_bytes_sec_max', label: '突发写入' }
]
-const formatDiskIoVal = (val, field) => {
+const diskIoIopsFields = [
+ { key: 'read_iops_sec', label: '读取' },
+ { key: 'write_iops_sec', label: '写入' },
+ { key: 'read_iops_sec_max', label: '突发读取' },
+ { key: 'write_iops_sec_max', label: '突发写入' }
+]
+const diskIoFields = [
+ ...diskIoBwFields.map(f => ({ ...f, isBandwidth: true })),
+ ...diskIoIopsFields.map(f => ({ ...f, isBandwidth: false }))
+]
+const formatDiskIoVal = (val, isBandwidth) => {
if (!val && val !== 0) return '-'
val = Number(val)
- if (!field.isBandwidth) return val.toLocaleString() + ' ' + field.unit
+ if (!isBandwidth) return val.toLocaleString() + ' IOPS'
if (val >= 1073741824) return (val / 1073741824).toFixed(1) + ' GB/s'
if (val >= 1048576) return (val / 1048576).toFixed(0) + ' MB/s'
if (val >= 1024) return (val / 1024).toFixed(0) + ' KB/s'
return val + ' B/s'
}
+const ioBwUnitOptions = [
+ { label: 'B/s', factor: 1 },
+ { label: 'KB/s', factor: 1024 },
+ { label: 'MB/s', factor: 1048576 },
+ { label: 'GB/s', factor: 1073741824 }
+]
+const ioBwUnit = ref('MB/s')
+const tokenIoBwUnit = ref('MB/s')
+const getIoBwFactor = () => ioBwUnitOptions.find(u => u.label === ioBwUnit.value)?.factor || 1048576
+const getTokenIoBwFactor = () => ioBwUnitOptions.find(u => u.label === tokenIoBwUnit.value)?.factor || 1048576
+
const showDiskIoSection = ref(false)
const showTokenDiskIo = ref(false)
const showDetailDiskIo = ref(false)
@@ -1058,6 +1107,7 @@ const openTokenDialog = () => {
tokenMemUnit.value = 'GB'
tokenDiskUnit.value = 'GB'
showTokenDiskIo.value = false
+ tokenIoBwUnit.value = 'MB/s'
tokenDialogVisible.value = true
}
@@ -1377,5 +1427,6 @@ onBeforeUnmount(() => { isPageActive = false; disposeCharts() })
.section-hint { font-size: 12px; color: #909399; font-weight: 400; }
.tk-section-title.clickable { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 6px; }
.tk-section-title.clickable:hover { color: #409eff; }
+.io-sub-title { font-size: 13px; font-weight: 500; color: #606266; margin: 12px 0 8px; display: flex; align-items: center; }
diff --git a/src/views/virtualization/HostManage.vue b/src/views/virtualization/HostManage.vue
index f2f4c37..b2f1feb 100644
--- a/src/views/virtualization/HostManage.vue
+++ b/src/views/virtualization/HostManage.vue
@@ -165,11 +165,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ formData[f.key] = Math.round((v || 0) * getIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -290,11 +303,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ tokenForm[f.key] = Math.round((v || 0) * getTokenIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -450,25 +476,32 @@ const diskIoDefaults = {
read_bytes_sec_max: 314572800, write_bytes_sec_max: 314572800,
read_iops_sec_max: 1000, write_iops_sec_max: 1000
}
-const diskIoFields = [
- { key: 'read_bytes_sec', label: '读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec', label: '写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec', label: '读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec', label: '写入 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'read_bytes_sec_max', label: '突发读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec_max', label: '突发写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec_max', label: '突发读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec_max', label: '突发写入 IOPS', unit: 'IOPS', isBandwidth: false }
+const diskIoBwFields = [
+ { key: 'read_bytes_sec', label: '读取' },
+ { key: 'write_bytes_sec', label: '写入' },
+ { key: 'read_bytes_sec_max', label: '突发读取' },
+ { key: 'write_bytes_sec_max', label: '突发写入' }
]
-const formatDiskIoVal = (val, field) => {
- if (!val && val !== 0) return '-'
- val = Number(val)
- if (!field.isBandwidth) return val.toLocaleString() + ' ' + field.unit
- if (val >= 1073741824) return (val / 1073741824).toFixed(1) + ' GB/s'
- if (val >= 1048576) return (val / 1048576).toFixed(0) + ' MB/s'
- if (val >= 1024) return (val / 1024).toFixed(0) + ' KB/s'
- return val + ' B/s'
-}
+const diskIoIopsFields = [
+ { key: 'read_iops_sec', label: '读取' },
+ { key: 'write_iops_sec', label: '写入' },
+ { key: 'read_iops_sec_max', label: '突发读取' },
+ { key: 'write_iops_sec_max', label: '突发写入' }
+]
+const diskIoFields = [
+ ...diskIoBwFields.map(f => ({ ...f, isBandwidth: true })),
+ ...diskIoIopsFields.map(f => ({ ...f, isBandwidth: false }))
+]
+const ioBwUnitOptions = [
+ { label: 'B/s', factor: 1 },
+ { label: 'KB/s', factor: 1024 },
+ { label: 'MB/s', factor: 1048576 },
+ { label: 'GB/s', factor: 1073741824 }
+]
+const ioBwUnit = ref('MB/s')
+const tokenIoBwUnit = ref('MB/s')
+const getIoBwFactor = () => ioBwUnitOptions.find(u => u.label === ioBwUnit.value)?.factor || 1048576
+const getTokenIoBwFactor = () => ioBwUnitOptions.find(u => u.label === tokenIoBwUnit.value)?.factor || 1048576
const showDiskIoSection = ref(false)
const showTokenDiskIo = ref(false)
@@ -581,6 +614,7 @@ const resetForm = () => {
_groupName: '', ...diskIoDefaults
})
showDiskIoSection.value = false
+ ioBwUnit.value = 'MB/s'
}
const handleHostGroupSelected = (group) => {
@@ -816,6 +850,7 @@ const openTokenDialog = () => {
tokenMemUnit.value = 'GB'
tokenDiskUnit.value = 'GB'
showTokenDiskIo.value = false
+ tokenIoBwUnit.value = 'MB/s'
tokenDialogVisible.value = true
}
@@ -900,4 +935,5 @@ onMounted(() => {
.section-arrow { transition: transform 0.2s; font-size: 14px; }
.section-arrow.expanded { transform: rotate(90deg); }
.section-hint { font-size: 12px; color: #909399; font-weight: 400; }
+.io-sub-title { font-size: 13px; font-weight: 500; color: #606266; margin: 12px 0 8px; display: flex; align-items: center; }
diff --git a/src/views/virtualization/HostTreeManage.vue b/src/views/virtualization/HostTreeManage.vue
index 4b1584a..39dc89c 100644
--- a/src/views/virtualization/HostTreeManage.vue
+++ b/src/views/virtualization/HostTreeManage.vue
@@ -137,11 +137,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ tokenForm[f.key] = Math.round((v || 0) * getTokenIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -345,11 +358,24 @@
可选,不展开则使用默认值
-
-
-
- {{ f.unit }}
-
+
+
+ 带宽限制
+
+
+
+
+
+
+ hostForm[f.key] = Math.round((v || 0) * getHostIoBwFactor())" :min="0" controls-position="right" />
+
+
+
IOPS 限制
+
+
+
+
+
@@ -657,16 +683,33 @@ const diskIoDefaults = {
read_bytes_sec_max: 314572800, write_bytes_sec_max: 314572800,
read_iops_sec_max: 1000, write_iops_sec_max: 1000
}
-const diskIoFields = [
- { key: 'read_bytes_sec', label: '读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec', label: '写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec', label: '读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec', label: '写入 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'read_bytes_sec_max', label: '突发读取带宽', unit: 'B/s', isBandwidth: true },
- { key: 'write_bytes_sec_max', label: '突发写入带宽', unit: 'B/s', isBandwidth: true },
- { key: 'read_iops_sec_max', label: '突发读取 IOPS', unit: 'IOPS', isBandwidth: false },
- { key: 'write_iops_sec_max', label: '突发写入 IOPS', unit: 'IOPS', isBandwidth: false }
+const diskIoBwFields = [
+ { key: 'read_bytes_sec', label: '读取' },
+ { key: 'write_bytes_sec', label: '写入' },
+ { key: 'read_bytes_sec_max', label: '突发读取' },
+ { key: 'write_bytes_sec_max', label: '突发写入' }
]
+const diskIoIopsFields = [
+ { key: 'read_iops_sec', label: '读取' },
+ { key: 'write_iops_sec', label: '写入' },
+ { key: 'read_iops_sec_max', label: '突发读取' },
+ { key: 'write_iops_sec_max', label: '突发写入' }
+]
+const diskIoFields = [
+ ...diskIoBwFields.map(f => ({ ...f, isBandwidth: true })),
+ ...diskIoIopsFields.map(f => ({ ...f, isBandwidth: false }))
+]
+const ioBwUnitOptions = [
+ { label: 'B/s', factor: 1 },
+ { label: 'KB/s', factor: 1024 },
+ { label: 'MB/s', factor: 1048576 },
+ { label: 'GB/s', factor: 1073741824 }
+]
+const hostIoBwUnit = ref('MB/s')
+const tokenIoBwUnit = ref('MB/s')
+const getHostIoBwFactor = () => ioBwUnitOptions.find(u => u.label === hostIoBwUnit.value)?.factor || 1048576
+const getTokenIoBwFactor = () => ioBwUnitOptions.find(u => u.label === tokenIoBwUnit.value)?.factor || 1048576
+
const showHostDiskIo = ref(false)
const showTokenDiskIo = ref(false)
@@ -690,6 +733,7 @@ const handleAddHost = () => {
hostDialogType.value = 'add'
Object.assign(hostForm, { id: undefined, name: '', base_url: '', ip: '', token: '', port: 22, user: '', password: '', private_key: '', max_cpu: 0, max_memory: 0, max_disk: 0, rx_bandwidth: 0, tx_bandwidth: 0, host_group_id: 0, description: '', ...diskIoDefaults })
showHostDiskIo.value = false
+ hostIoBwUnit.value = 'MB/s'
hostDialogVisible.value = true
}
@@ -697,6 +741,7 @@ const handleAddHostToGroup = (group) => {
hostDialogType.value = 'add'
Object.assign(hostForm, { id: undefined, name: '', base_url: '', ip: '', token: '', port: 22, user: '', password: '', private_key: '', max_cpu: 0, max_memory: 0, max_disk: 0, rx_bandwidth: 0, tx_bandwidth: 0, host_group_id: group.id, description: '', ...diskIoDefaults })
showHostDiskIo.value = false
+ hostIoBwUnit.value = 'MB/s'
hostDialogVisible.value = true
}
@@ -809,6 +854,7 @@ const openTokenDialog = () => {
tokenMemUnit.value = 'GB'
tokenDiskUnit.value = 'GB'
showTokenDiskIo.value = false
+ tokenIoBwUnit.value = 'MB/s'
tokenDialogVisible.value = true
}
@@ -899,4 +945,5 @@ onMounted(() => { if (serviceId.value) loadTreeData() })
.section-arrow { transition: transform 0.2s; font-size: 14px; }
.section-arrow.expanded { transform: rotate(90deg); }
.section-hint { font-size: 12px; color: #909399; font-weight: 400; }
+.io-sub-title { font-size: 13px; font-weight: 500; color: #606266; margin: 12px 0 8px; display: flex; align-items: center; }