feat: 虚拟机流量精细化控制接入(接口新增,待联调)
Build and Deploy Vue3 / build (push) Successful in 1m37s
Build and Deploy Vue3 / deploy (push) Successful in 1m16s

1. userVm.js/kvmService.js 新增 traffic_policy 系列 API(GET/update/add_fixed/add_temporary)
2. UserVmList.vue/VmManage.vue 创建表单新增 traffic_max、traffic_exhausted_rx/tx_mbps 三个可选字段
3. UserVmDetail.vue/VmDetail.vue 修改带宽表单新增耗尽限速字段,并各增加流量策略 Tab(展示+修改策略+增加固定/临时流量)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
shiran
2026-05-08 15:10:44 +08:00
parent 475c62aefc
commit c43d1978a8
6 changed files with 366 additions and 9 deletions
+41 -2
View File
@@ -273,6 +273,40 @@
</el-form-item>
</el-col>
</el-row>
<!-- 流量策略(可选) -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="流量上限">
<div class="unit-input-row">
<el-input-number v-model="createForm.traffic_max" :min="0" controls-position="right" style="flex:1" />
<span class="unit-text">MB</span>
</div>
<div style="font-size:12px;color:#909399;margin-top:2px">0 表示不限流量</div>
</el-form-item>
</el-col>
<el-col :span="12">
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="耗尽下行限速">
<div class="unit-input-row">
<el-input-number v-model="createForm.traffic_exhausted_rx_mbps" :min="0" :precision="2" controls-position="right" style="flex:1" />
<span class="unit-text">Mbps</span>
</div>
<div style="font-size:12px;color:#909399;margin-top:2px">流量耗尽后下行速率,0 表示不限</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="耗尽上行限速">
<div class="unit-input-row">
<el-input-number v-model="createForm.traffic_exhausted_tx_mbps" :min="0" :precision="2" controls-position="right" style="flex:1" />
<span class="unit-text">Mbps</span>
</div>
<div style="font-size:12px;color:#909399;margin-top:2px">流量耗尽后上行速率,0 表示不限</div>
</el-form-item>
</el-col>
</el-row>
<!-- 行9: 续费价格 + 基础价格 -->
<el-row :gutter="20">
<el-col :span="12">
@@ -1090,7 +1124,8 @@ const createForm = reactive({
network_ids: [], _networkNames: '',
ipv4_num: 0, ipv6_num: 0, snapshot_num: 0, backup_num: 0,
_renewPriceYuan: 0, _basePriceYuan: 0,
data_volume_size: 0, note: '', expire_time: ''
data_volume_size: 0, note: '', expire_time: '',
traffic_max: 0, traffic_exhausted_rx_mbps: 0, traffic_exhausted_tx_mbps: 0
})
const createRules = {
@@ -1116,7 +1151,8 @@ const handleCreate = (tab = 'create') => {
host_id: 0, _hostName: '', host_group_id: 0, _hostGroupName: '',
network_ids: [], _networkNames: '',
ipv4_num: 0, ipv6_num: 0, snapshot_num: 0, backup_num: 0,
_renewPriceYuan: 0, _basePriceYuan: 0, data_volume_size: 0, note: '', expire_time: ''
_renewPriceYuan: 0, _basePriceYuan: 0, data_volume_size: 0, note: '', expire_time: '',
traffic_max: 0, traffic_exhausted_rx_mbps: 0, traffic_exhausted_tx_mbps: 0
})
resetBindGoodsForm()
pendingTab = tab
@@ -1213,6 +1249,9 @@ const submitCreate = () => {
if (createForm.host_id) payload.host_id = createForm.host_id
if (createForm.host_group_id) payload.host_group_id = createForm.host_group_id
if (createForm.network_ids.length) payload.network_ids = createForm.network_ids
if (createForm.traffic_max > 0) payload.traffic_max = createForm.traffic_max
if (createForm.traffic_exhausted_rx_mbps > 0) payload.traffic_exhausted_rx_mbps = createForm.traffic_exhausted_rx_mbps
if (createForm.traffic_exhausted_tx_mbps > 0) payload.traffic_exhausted_tx_mbps = createForm.traffic_exhausted_tx_mbps
const res = await createUserVm(payload)
if (res?.data?.code === 200) { ElMessage.success('创建成功'); createVisible.value = false; loadList() }
else ElMessage.error(extractApiError(res?.data, '创建失败'))