Enhance simulation file management and frontend status display
- Updated SimulationRunner to include additional files for deletion, specifically Twitter and Reddit simulation databases, and environment status files. - Refactored Step3Simulation component to streamline the status display, removing unnecessary conditions and improving the user interface for simulation phases. - Introduced a reset function to clear all simulation states before starting a new simulation, ensuring a clean environment for each run.
This commit is contained in:
parent
ec418c1def
commit
d768fd1ea2
2 changed files with 35 additions and 161 deletions
|
|
@ -1053,6 +1053,9 @@ class SimulationRunner:
|
|||
- reddit/actions.jsonl
|
||||
- simulation.log
|
||||
- stdout.log / stderr.log
|
||||
- twitter_simulation.db(模拟数据库)
|
||||
- reddit_simulation.db(模拟数据库)
|
||||
- env_status.json(环境状态)
|
||||
|
||||
注意:不会删除配置文件(simulation_config.json)和 profile 文件
|
||||
|
||||
|
|
@ -1072,12 +1075,15 @@ class SimulationRunner:
|
|||
cleaned_files = []
|
||||
errors = []
|
||||
|
||||
# 要删除的文件列表
|
||||
# 要删除的文件列表(包括数据库文件)
|
||||
files_to_delete = [
|
||||
"run_state.json",
|
||||
"simulation.log",
|
||||
"stdout.log",
|
||||
"stderr.log",
|
||||
"twitter_simulation.db", # Twitter 平台数据库
|
||||
"reddit_simulation.db", # Reddit 平台数据库
|
||||
"env_status.json", # 环境状态文件
|
||||
]
|
||||
|
||||
# 要删除的目录列表(包含动作日志)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="simulation-panel">
|
||||
<!-- Top Control Bar -->
|
||||
<div class="control-bar">
|
||||
<div class="status-group" v-if="phase >= 1">
|
||||
<div class="status-group">
|
||||
<!-- Twitter 平台进度 -->
|
||||
<div class="platform-status twitter" :class="{ active: runStatus.twitter_running, completed: runStatus.twitter_completed }">
|
||||
<div class="platform-header">
|
||||
|
|
@ -49,81 +49,23 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Phase 0 时显示简单状态 -->
|
||||
<div class="status-group" v-else>
|
||||
<div class="status-item">
|
||||
<span class="label">ROUND</span>
|
||||
<span class="value mono">0<span class="total">/{{ maxRounds || '-' }}</span></span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="label">TIME</span>
|
||||
<span class="value mono">0<span class="unit">h</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-controls">
|
||||
<button
|
||||
v-if="phase === 0"
|
||||
class="ctrl-btn start"
|
||||
:disabled="isStarting"
|
||||
@click="doStartSimulation"
|
||||
>
|
||||
<span v-if="isStarting" class="spinner-sm"></span>
|
||||
{{ isStarting ? 'INITIALIZING...' : 'START ENGINE' }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="phase === 1"
|
||||
class="ctrl-btn stop"
|
||||
:disabled="isStopping"
|
||||
@click="handleStopSimulation"
|
||||
>
|
||||
{{ isStopping ? 'STOPPING...' : 'STOP SIMULATION' }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
v-if="phase === 2"
|
||||
class="ctrl-btn next"
|
||||
:disabled="phase !== 2"
|
||||
@click="handleNextStep"
|
||||
>
|
||||
GENERATE REPORT ➝
|
||||
<span v-if="phase !== 2" class="spinner-sm running"></span>
|
||||
{{ phase === 2 ? 'GENERATE REPORT ➝' : 'SIMULATING...' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content: Dual Timeline or Start Screen -->
|
||||
<!-- Main Content: Dual Timeline -->
|
||||
<div class="main-content-area" ref="scrollContainer">
|
||||
<!-- Start Screen (Phase 0) -->
|
||||
<div v-if="phase === 0" class="start-screen">
|
||||
<div class="engine-status">
|
||||
<div class="engine-icon">⚡️</div>
|
||||
<h2>Simulation Engine Ready</h2>
|
||||
<p>Initialize the dual-platform parallel simulation environment.</p>
|
||||
</div>
|
||||
|
||||
<div class="config-grid">
|
||||
<div class="config-card">
|
||||
<span class="label">SIMULATION ID</span>
|
||||
<span class="val mono">{{ simulationId }}</span>
|
||||
</div>
|
||||
<div class="config-card">
|
||||
<span class="label">TARGET ROUNDS</span>
|
||||
<span class="val">{{ maxRounds || 'AUTO' }}</span>
|
||||
</div>
|
||||
<div class="config-card">
|
||||
<span class="label">PLATFORMS</span>
|
||||
<span class="val">Twitter + Reddit</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="startError" class="error-banner">
|
||||
{{ startError }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timeline Feed (Phase >= 1) -->
|
||||
<div v-else class="timeline-feed">
|
||||
<!-- Timeline Feed -->
|
||||
<div class="timeline-feed">
|
||||
<div class="timeline-axis"></div>
|
||||
|
||||
<TransitionGroup name="timeline-item">
|
||||
|
|
@ -238,6 +180,19 @@ const addLog = (msg) => {
|
|||
emit('add-log', msg)
|
||||
}
|
||||
|
||||
// 重置所有状态(用于重新启动模拟)
|
||||
const resetAllState = () => {
|
||||
phase.value = 0
|
||||
runStatus.value = {}
|
||||
recentActions.value = []
|
||||
prevTwitterRound.value = 0
|
||||
prevRedditRound.value = 0
|
||||
startError.value = null
|
||||
isStarting.value = false
|
||||
isStopping.value = false
|
||||
stopPolling() // 停止之前可能存在的轮询
|
||||
}
|
||||
|
||||
// 启动模拟
|
||||
const doStartSimulation = async () => {
|
||||
if (!props.simulationId) {
|
||||
|
|
@ -245,6 +200,9 @@ const doStartSimulation = async () => {
|
|||
return
|
||||
}
|
||||
|
||||
// 先重置所有状态,确保不会受到上一次模拟的影响
|
||||
resetAllState()
|
||||
|
||||
isStarting.value = true
|
||||
startError.value = null
|
||||
addLog('正在启动双平台并行模拟...')
|
||||
|
|
@ -522,30 +480,6 @@ onUnmounted(() => {
|
|||
gap: 16px;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.status-item .label {
|
||||
font-size: 10px;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.status-item .value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status-item .total, .status-item .unit {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 双平台进度卡片 */
|
||||
.platform-status {
|
||||
display: flex;
|
||||
|
|
@ -649,16 +583,6 @@ onUnmounted(() => {
|
|||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.ctrl-btn.start {
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.ctrl-btn.stop {
|
||||
background: #FFEBEE;
|
||||
color: #C62828;
|
||||
}
|
||||
|
||||
.ctrl-btn.next {
|
||||
background: #E8F5E9;
|
||||
color: #2E7D32;
|
||||
|
|
@ -682,67 +606,6 @@ onUnmounted(() => {
|
|||
background: #FAFAFA;
|
||||
}
|
||||
|
||||
/* Start Screen */
|
||||
.start-screen {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.engine-status {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.engine-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.engine-status h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.engine-status p {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.config-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.config-card {
|
||||
background: #FFF;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #EAEAEA;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.config-card .label {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: #999;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.config-card .val {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* --- Timeline Feed --- */
|
||||
.timeline-feed {
|
||||
padding: 24px;
|
||||
|
|
@ -1018,6 +881,11 @@ onUnmounted(() => {
|
|||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
.spinner-sm.running {
|
||||
border: 2px solid rgba(46, 125, 50, 0.3);
|
||||
border-top-color: #2E7D32;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue