fix: 虚拟机网络管理改为解绑逻辑,不再删除底层网络
Build and Deploy Vue3 / build (push) Successful in 1m33s
Build and Deploy Vue3 / deploy (push) Successful in 44s

将 user-vm/UserVmDetail 和 virtualization/VmDetail 中的网络删除操作改为通过 updateVm 接口解绑,与绑定网络逻辑对称,避免误删底层物理网络。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
shiran
2026-06-30 10:26:01 +08:00
parent cae5551107
commit 0155715278
3 changed files with 48 additions and 19 deletions
+20 -6
View File
@@ -302,7 +302,7 @@
<el-button link type="primary" size="small" @click="handleNetDetail(row)">详情</el-button>
<el-button link type="primary" size="small" @click="handleNetEdit(row)">编辑</el-button>
<el-button v-if="!row.is_primary" link type="warning" size="small" @click="handleSetPrimary(row)">设为主IP</el-button>
<el-button link type="danger" size="small" @click="handleNetDelete(row)">删除</el-button>
<el-button link type="danger" size="small" @click="handleNetDelete(row)">解绑</el-button>
</template>
</el-table-column>
</el-table>
@@ -2962,13 +2962,27 @@ const submitNetForm = () => {
}
const handleNetDetail = (row) => { netDetailData.value = row; netDetailVisible.value = true }
const handleNetDelete = (row) => {
ElMessageBox.confirm(`确定要删除网络「${row.name}」(ID: ${row.id}) 吗?`, '删除网络', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
ElMessageBox.confirm(`确定从该虚拟机解绑网络「${row.name}」(ID: ${row.id}) 吗?`, '解绑网络', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
.then(async () => {
actionLoading.value = true
try {
const res = await deleteNetwork({ service_id: serviceId.value, network_id: row.id, host_id: row.host_id })
if (res?.data?.code === 200) { ElMessage.success('删除成功'); loadDetail() }
else ElMessage.error(extractApiError(res?.data, '删除失败'))
} catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
const fd = new FormData()
fd.append('service_id', serviceId.value)
fd.append('vm_id', vmId.value)
const remainingNetworks = vmNetworks.value.filter(n => n.id !== row.id)
const bridgeIds = remainingNetworks.filter(n => n.type === 'bridge').map(n => n.id)
const natNet = remainingNetworks.find(n => n.type === 'nat')
bridgeIds.forEach(id => fd.append('network_ids', id))
if (natNet) fd.append('internet_network_id', natNet.id)
if (detail.value?.rx_bandwidth) fd.append('rx_bandwidth', detail.value.rx_bandwidth)
if (detail.value?.tx_bandwidth) fd.append('tx_bandwidth', detail.value.tx_bandwidth)
if (detail.value?.ssh_port) fd.append('ssh_port', detail.value.ssh_port)
if (vmPortGroup.value?.id) fd.append('port_group_id', vmPortGroup.value.id)
const res = await updateVm(fd)
if (res?.data?.code === 200) { ElMessage.success('解绑网络成功'); loadDetail() }
else ElMessage.error(extractApiError(res?.data, '解绑网络失败'))
} catch (e) { ElMessage.error(extractApiError(e?.response?.data, '解绑网络失败')) }
finally { actionLoading.value = false }
}).catch(() => {})
}