fix: 虚拟机添加强制操作
Build and Deploy Vue3 / build (push) Successful in 1m26s
Build and Deploy Vue3 / deploy (push) Successful in 1m3s

This commit is contained in:
2026-03-26 17:20:00 +08:00
parent b7e806cc80
commit 71d3605f4f
+43 -16
View File
@@ -497,6 +497,26 @@
</el-tabs> </el-tabs>
</div> </div>
<!-- 电源操作确认弹窗 -->
<el-dialog v-model="powerDialogVisible" :title="`${powerLabels[powerAction] || ''}虚拟机`" width="400px" destroy-on-close>
<div style="display: flex; align-items: flex-start; gap: 12px; padding: 8px 0">
<el-icon :size="22" :style="{ color: powerAction === 'stop' ? '#F56C6C' : powerAction === 'reboot' ? '#E6A23C' : '#409EFF', flexShrink: 0, marginTop: '-1px' }">
<WarningFilled />
</el-icon>
<div>
<div style="font-size: 15px; font-weight: 500; color: #303133; margin-bottom: 12px">
确定要{{ powerLabels[powerAction] }}虚拟机「{{ detail?.name }}」吗?
</div>
<el-checkbox v-model="powerForce" style="margin-bottom: 4px">强制执行</el-checkbox>
<div style="font-size: 12px; color: #909399; padding-left: 24px">勾选后将强制{{ powerLabels[powerAction] }},可能导致数据丢失</div>
</div>
</div>
<template #footer>
<el-button @click="powerDialogVisible = false">取消</el-button>
<el-button :type="powerAction === 'stop' ? 'danger' : 'primary'" @click="submitPower">确定{{ powerLabels[powerAction] }}</el-button>
</template>
</el-dialog>
<!-- 重装弹窗 --> <!-- 重装弹窗 -->
<el-dialog v-model="rebuildDialogVisible" title="重装虚拟机" width="480px" destroy-on-close> <el-dialog v-model="rebuildDialogVisible" title="重装虚拟机" width="480px" destroy-on-close>
<el-alert title="重装会清除当前虚拟机数据并使用新镜像重新创建请谨慎操作" type="warning" :closable="false" style="margin-bottom: 16px" /> <el-alert title="重装会清除当前虚拟机数据并使用新镜像重新创建请谨慎操作" type="warning" :closable="false" style="margin-bottom: 16px" />
@@ -1122,7 +1142,7 @@
import { ref, reactive, computed, onMounted, onActivated, onDeactivated, onBeforeUnmount, nextTick, watch } from 'vue' import { ref, reactive, computed, onMounted, onActivated, onDeactivated, onBeforeUnmount, nextTick, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, Refresh, ArrowDown, Plus, Search } from '@element-plus/icons-vue' import { ArrowLeft, Refresh, ArrowDown, Plus, Search, WarningFilled } from '@element-plus/icons-vue'
import { import {
getVmDetail, getVmStatus, getVmMetrics, getVmDetail, getVmStatus, getVmMetrics,
startVm, stopVm, rebootVm, suspendVm, resumeVm, startVm, stopVm, rebootVm, suspendVm, resumeVm,
@@ -1419,24 +1439,31 @@ const clearHistory = () => {
for (const k in metricsHistory.netSeries) delete metricsHistory.netSeries[k] for (const k in metricsHistory.netSeries) delete metricsHistory.netSeries[k]
} }
const powerDialogVisible = ref(false)
const powerAction = ref('')
const powerForce = ref(false)
const powerLabels = { start: '启动', stop: '停止', reboot: '重启', suspend: '暂停', resume: '恢复' }
const handlePower = (action) => { const handlePower = (action) => {
const labels = { start: '启动', stop: '停止', reboot: '重启', suspend: '暂停', resume: '恢复' } powerAction.value = action
ElMessageBox.confirm(`确定要${labels[action]}虚拟机「${detail.value?.name}」吗?`, `${labels[action]}确认`, { powerForce.value = false
confirmButtonText: '确定', cancelButtonText: '取消', type: action === 'stop' ? 'warning' : 'info' powerDialogVisible.value = true
}).then(async () => { }
const submitPower = async () => {
const action = powerAction.value
const label = powerLabels[action]
powerDialogVisible.value = false
try { try {
const apis = { start: startVm, stop: stopVm, reboot: rebootVm, suspend: suspendVm, resume: resumeVm } const apis = { start: startVm, stop: stopVm, reboot: rebootVm, suspend: suspendVm, resume: resumeVm }
let res const fd = new FormData()
if (action === 'resume') { fd.append('service_id', serviceId.value)
const fd = new FormData(); fd.append('service_id', serviceId.value); fd.append('vm_id', vmId.value) fd.append('vm_id', vmId.value)
res = await resumeVm(fd) if (powerForce.value) fd.append('force', true)
} else { const res = await apis[action](fd)
res = await apis[action]({ service_id: serviceId.value, vm_id: vmId.value }) if (res?.data?.code === 200) { ElMessage.success(`${label}成功`); loadDetail() }
} else ElMessage.error(extractApiError(res?.data, `${label}失败`))
if (res?.data?.code === 200) { ElMessage.success(`${labels[action]}成功`); loadDetail() } } catch (e) { ElMessage.error(extractApiError(e?.response?.data, `${label}失败`)) }
else ElMessage.error(extractApiError(res?.data, `${labels[action]}失败`))
} catch (e) { ElMessage.error(extractApiError(e?.response?.data, `${labels[action]}失败`)) }
}).catch(() => {})
} }
const handleRebuild = () => { const handleRebuild = () => {