Implement simulation environment management features in frontend

- Added new API functions for closing the simulation environment and retrieving its status.
- Enhanced the SimulationRunView and SimulationView components to gracefully handle simulation termination when navigating between steps.
- Introduced logging for better user feedback during the simulation closure process, including attempts to force stop if graceful closure fails.
This commit is contained in:
666ghj 2025-12-12 16:25:28 +08:00
parent 0577ecdae8
commit ec418c1def
3 changed files with 132 additions and 4 deletions

View file

@ -152,3 +152,19 @@ export const getSimulationActions = (simulationId, params = {}) => {
return service.get(`/api/simulation/${simulationId}/actions`, { params })
}
/**
* 关闭模拟环境优雅退出
* @param {Object} data - { simulation_id, timeout? }
*/
export const closeSimulationEnv = (data) => {
return service.post('/api/simulation/close-env', data)
}
/**
* 获取模拟环境状态
* @param {Object} data - { simulation_id }
*/
export const getEnvStatus = (data) => {
return service.post('/api/simulation/env-status', data)
}

View file

@ -71,7 +71,7 @@ import { useRoute, useRouter } from 'vue-router'
import GraphPanel from '../components/GraphPanel.vue'
import Step3Simulation from '../components/Step3Simulation.vue'
import { getProject, getGraphData } from '../api/graph'
import { getSimulation } from '../api/simulation'
import { getSimulation, stopSimulation, closeSimulationEnv, getEnvStatus } from '../api/simulation'
const route = useRoute()
const router = useRouter()
@ -142,7 +142,50 @@ const toggleMaximize = (target) => {
}
}
const handleGoBack = () => {
const handleGoBack = async () => {
// Step 2
addLog('准备返回 Step 2正在关闭模拟...')
//
stopGraphRefresh()
try {
//
const envStatusRes = await getEnvStatus({ simulation_id: currentSimulationId.value })
if (envStatusRes.success && envStatusRes.data?.env_alive) {
addLog('正在关闭模拟环境...')
try {
await closeSimulationEnv({
simulation_id: currentSimulationId.value,
timeout: 10
})
addLog('✓ 模拟环境已关闭')
} catch (closeErr) {
addLog(`关闭模拟环境失败,尝试强制停止...`)
try {
await stopSimulation({ simulation_id: currentSimulationId.value })
addLog('✓ 模拟已强制停止')
} catch (stopErr) {
addLog(`强制停止失败: ${stopErr.message}`)
}
}
} else {
//
if (isSimulating.value) {
addLog('正在停止模拟进程...')
try {
await stopSimulation({ simulation_id: currentSimulationId.value })
addLog('✓ 模拟已停止')
} catch (err) {
addLog(`停止模拟失败: ${err.message}`)
}
}
}
} catch (err) {
addLog(`检查模拟状态失败: ${err.message}`)
}
// Step 2 ()
router.push({ name: 'Simulation', params: { simulationId: currentSimulationId.value } })
}

View file

@ -69,7 +69,7 @@ import { useRoute, useRouter } from 'vue-router'
import GraphPanel from '../components/GraphPanel.vue'
import Step2EnvSetup from '../components/Step2EnvSetup.vue'
import { getProject, getGraphData } from '../api/graph'
import { getSimulation } from '../api/simulation'
import { getSimulation, stopSimulation, getEnvStatus, closeSimulationEnv } from '../api/simulation'
const route = useRoute()
const router = useRouter()
@ -171,6 +171,70 @@ const handleNextStep = (params = {}) => {
}
// --- Data Logic ---
/**
* 检查并关闭正在运行的模拟
* 当用户从 Step 3 返回到 Step 2 默认用户要退出模拟
*/
const checkAndStopRunningSimulation = async () => {
if (!currentSimulationId.value) return
try {
//
const envStatusRes = await getEnvStatus({ simulation_id: currentSimulationId.value })
if (envStatusRes.success && envStatusRes.data?.env_alive) {
addLog('检测到模拟环境正在运行,正在关闭...')
//
try {
const closeRes = await closeSimulationEnv({
simulation_id: currentSimulationId.value,
timeout: 10 // 10
})
if (closeRes.success) {
addLog('✓ 模拟环境已关闭')
} else {
addLog(`关闭模拟环境失败: ${closeRes.error || '未知错误'}`)
//
await forceStopSimulation()
}
} catch (closeErr) {
addLog(`关闭模拟环境异常: ${closeErr.message}`)
//
await forceStopSimulation()
}
} else {
//
const simRes = await getSimulation(currentSimulationId.value)
if (simRes.success && simRes.data?.status === 'running') {
addLog('检测到模拟状态为运行中,正在停止...')
await forceStopSimulation()
}
}
} catch (err) {
//
console.warn('检查模拟状态失败:', err)
}
}
/**
* 强制停止模拟
*/
const forceStopSimulation = async () => {
try {
const stopRes = await stopSimulation({ simulation_id: currentSimulationId.value })
if (stopRes.success) {
addLog('✓ 模拟已强制停止')
} else {
addLog(`强制停止模拟失败: ${stopRes.error || '未知错误'}`)
}
} catch (err) {
addLog(`强制停止模拟异常: ${err.message}`)
}
}
const loadSimulationData = async () => {
try {
addLog(`加载模拟数据: ${currentSimulationId.value}`)
@ -222,8 +286,13 @@ const refreshGraph = () => {
}
}
onMounted(() => {
onMounted(async () => {
addLog('SimulationView 初始化')
// Step 3
await checkAndStopRunningSimulation()
//
loadSimulationData()
})
</script>