diff --git a/frontend/src/components/Step2EnvSetup.vue b/frontend/src/components/Step2EnvSetup.vue index 0d84a6f..a27ba34 100644 --- a/frontend/src/components/Step2EnvSetup.vue +++ b/frontend/src/components/Step2EnvSetup.vue @@ -683,7 +683,7 @@ watch(currentStage, (newStage) => { phase.value = 2 // 进入配置生成阶段,开始轮询配置 if (!configTimer) { - addLog('开始生成双平台模拟配置...') + addLog(t('log.startGeneratingConfig')) startConfigPolling() } } else if (newStage === '准备模拟脚本' || newStage === 'copying_scripts') { @@ -748,10 +748,10 @@ const handleStartSimulation = () => { if (useCustomRounds.value) { // 用户自定义轮数,传递 max_rounds 参数 params.maxRounds = customMaxRounds.value - addLog(`开始模拟,自定义轮数: ${customMaxRounds.value} 轮`) + addLog(t('log.startSimCustomRounds', { rounds: customMaxRounds.value })) } else { // 用户选择保持自动生成的轮数,不传递 max_rounds 参数 - addLog(`开始模拟,使用自动配置轮数: ${autoGeneratedRounds.value} 轮`) + addLog(t('log.startSimAutoRounds', { rounds: autoGeneratedRounds.value })) } emit('next-step', params) @@ -771,15 +771,15 @@ const selectProfile = (profile) => { // 自动开始准备模拟 const startPrepareSimulation = async () => { if (!props.simulationId) { - addLog('错误:缺少 simulationId') + addLog(t('log.errorMissingSimId')) emit('update-status', 'error') return } // 标记第一步完成,开始第二步 phase.value = 1 - addLog(`模拟实例已创建: ${props.simulationId}`) - addLog('正在准备模拟环境...') + addLog(t('log.simInstanceCreated', { id: props.simulationId })) + addLog(t('log.preparingSimEnv')) emit('update-status', 'processing') try { @@ -791,35 +791,35 @@ const startPrepareSimulation = async () => { if (res.success && res.data) { if (res.data.already_prepared) { - addLog('检测到已有完成的准备工作,直接使用') + addLog(t('log.detectedExistingPrep')) await loadPreparedData() return } taskId.value = res.data.task_id - addLog(`准备任务已启动`) - addLog(` └─ Task ID: ${res.data.task_id}`) + addLog(t('log.prepareTaskStarted')) + addLog(t('log.prepareTaskId', { taskId: res.data.task_id })) // 立即设置预期Agent总数(从prepare接口返回值获取) if (res.data.expected_entities_count) { expectedTotal.value = res.data.expected_entities_count - addLog(`从Zep图谱读取到 ${res.data.expected_entities_count} 个实体`) + addLog(t('log.zepEntitiesFound', { count: res.data.expected_entities_count })) if (res.data.entity_types && res.data.entity_types.length > 0) { - addLog(` └─ 实体类型: ${res.data.entity_types.join(', ')}`) + addLog(t('log.entityTypes', { types: res.data.entity_types.join(', ') })) } } - addLog('开始轮询准备进度...') + addLog(t('log.startPollingProgress')) // 开始轮询进度 startPolling() // 开始实时获取 Profiles startProfilesPolling() } else { - addLog(`准备失败: ${res.error || '未知错误'}`) + addLog(t('log.prepareFailed', { error: res.error || t('common.unknownError') })) emit('update-status', 'error') } } catch (err) { - addLog(`准备异常: ${err.message}`) + addLog(t('log.prepareException', { error: err.message })) emit('update-status', 'error') } } @@ -893,12 +893,12 @@ const pollPrepareStatus = async () => { // 检查是否完成 if (data.status === 'completed' || data.status === 'ready' || data.already_prepared) { - addLog('✓ 准备工作已完成') + addLog(t('log.prepareComplete')) stopPolling() stopProfilesPolling() await loadPreparedData() } else if (data.status === 'failed') { - addLog(`✗ 准备失败: ${data.error || '未知错误'}`) + addLog(t('log.prepareFailedWithError', { error: data.error || t('common.unknownError') })) stopPolling() stopProfilesPolling() } @@ -937,13 +937,13 @@ const fetchProfilesRealtime = async () => { const latestProfile = profiles.value[currentCount - 1] const profileName = latestProfile?.name || latestProfile?.username || `Agent_${currentCount}` if (currentCount === 1) { - addLog(`开始生成Agent人设...`) + addLog(t('log.startGeneratingAgentProfiles')) } - addLog(`→ Agent人设 ${currentCount}/${total}: ${profileName} (${latestProfile?.profession || '未知职业'})`) - + addLog(t('log.agentProfile', { current: currentCount, total: total, name: profileName, profession: latestProfile?.profession || t('step2.unknownProfession') })) + // 如果全部生成完成 if (expectedTotal.value && currentCount >= expectedTotal.value) { - addLog(`✓ 全部 ${currentCount} 个Agent人设生成完成`) + addLog(t('log.allProfilesComplete', { count: currentCount })) } } } @@ -977,41 +977,41 @@ const fetchConfigRealtime = async () => { if (data.generation_stage && data.generation_stage !== lastLoggedConfigStage) { lastLoggedConfigStage = data.generation_stage if (data.generation_stage === 'generating_profiles') { - addLog('正在生成Agent人设配置...') + addLog(t('log.generatingAgentProfileConfig')) } else if (data.generation_stage === 'generating_config') { - addLog('正在调用LLM生成模拟配置参数...') + addLog(t('log.generatingLLMConfig')) } } // 如果配置已生成 if (data.config_generated && data.config) { simulationConfig.value = data.config - addLog('✓ 模拟配置生成完成') - + addLog(t('log.configComplete')) + // 显示详细配置摘要 if (data.summary) { - addLog(` ├─ Agent数量: ${data.summary.total_agents}个`) - addLog(` ├─ 模拟时长: ${data.summary.simulation_hours}小时`) - addLog(` ├─ 初始帖子: ${data.summary.initial_posts_count}条`) - addLog(` ├─ 热点话题: ${data.summary.hot_topics_count}个`) - addLog(` └─ 平台配置: Twitter ${data.summary.has_twitter_config ? '✓' : '✗'}, Reddit ${data.summary.has_reddit_config ? '✓' : '✗'}`) + addLog(t('log.configSummaryAgents', { count: data.summary.total_agents })) + addLog(t('log.configSummaryHours', { hours: data.summary.simulation_hours })) + addLog(t('log.configSummaryPosts', { count: data.summary.initial_posts_count })) + addLog(t('log.configSummaryTopics', { count: data.summary.hot_topics_count })) + addLog(t('log.configSummaryPlatforms', { twitter: data.summary.has_twitter_config ? '✓' : '✗', reddit: data.summary.has_reddit_config ? '✓' : '✗' })) } // 显示时间配置详情 if (data.config.time_config) { const tc = data.config.time_config - addLog(`时间配置: 每轮${tc.minutes_per_round}分钟, 共${Math.floor((tc.total_simulation_hours * 60) / tc.minutes_per_round)}轮`) + addLog(t('log.timeConfigDetail', { minutes: tc.minutes_per_round, rounds: Math.floor((tc.total_simulation_hours * 60) / tc.minutes_per_round) })) } // 显示事件配置 if (data.config.event_config?.narrative_direction) { const narrative = data.config.event_config.narrative_direction - addLog(`叙事方向: ${narrative.length > 50 ? narrative.substring(0, 50) + '...' : narrative}`) + addLog(t('log.narrativeDirection', { direction: narrative.length > 50 ? narrative.substring(0, 50) + '...' : narrative })) } stopConfigPolling() phase.value = 4 - addLog('✓ 环境搭建完成,可以开始模拟') + addLog(t('log.envSetupComplete')) emit('update-status', 'completed') } } @@ -1022,11 +1022,11 @@ const fetchConfigRealtime = async () => { const loadPreparedData = async () => { phase.value = 2 - addLog('正在加载已有配置数据...') + addLog(t('log.loadingExistingConfig')) // 最后获取一次 Profiles await fetchProfilesRealtime() - addLog(`已加载 ${profiles.value.length} 个Agent人设`) + addLog(t('log.loadedAgentProfiles', { count: profiles.value.length })) // 获取配置(使用实时接口) try { @@ -1034,26 +1034,26 @@ const loadPreparedData = async () => { if (res.success && res.data) { if (res.data.config_generated && res.data.config) { simulationConfig.value = res.data.config - addLog('✓ 模拟配置加载成功') - + addLog(t('log.configLoadSuccess')) + // 显示详细配置摘要 if (res.data.summary) { - addLog(` ├─ Agent数量: ${res.data.summary.total_agents}个`) - addLog(` ├─ 模拟时长: ${res.data.summary.simulation_hours}小时`) - addLog(` └─ 初始帖子: ${res.data.summary.initial_posts_count}条`) + addLog(t('log.configSummaryAgents', { count: res.data.summary.total_agents })) + addLog(t('log.configSummaryHours', { hours: res.data.summary.simulation_hours })) + addLog(t('log.configSummaryPostsAlt', { count: res.data.summary.initial_posts_count })) } - - addLog('✓ 环境搭建完成,可以开始模拟') + + addLog(t('log.envSetupComplete')) phase.value = 4 emit('update-status', 'completed') } else { // 配置尚未生成,开始轮询 - addLog('配置生成中,开始轮询等待...') + addLog(t('log.configGenerating')) startConfigPolling() } } } catch (err) { - addLog(`加载配置失败: ${err.message}`) + addLog(t('log.loadConfigFailed', { error: err.message })) emit('update-status', 'error') } } @@ -1071,7 +1071,7 @@ watch(() => props.systemLogs?.length, () => { onMounted(() => { // 自动开始准备流程 if (props.simulationId) { - addLog('Step2 环境搭建初始化') + addLog(t('log.step2Init')) startPrepareSimulation() } }) diff --git a/frontend/src/views/SimulationRunView.vue b/frontend/src/views/SimulationRunView.vue index 58f1b9d..c675d87 100644 --- a/frontend/src/views/SimulationRunView.vue +++ b/frontend/src/views/SimulationRunView.vue @@ -76,7 +76,9 @@ import Step3Simulation from '../components/Step3Simulation.vue' import { getProject, getGraphData } from '../api/graph' import { getSimulation, getSimulationConfig, stopSimulation, closeSimulationEnv, getEnvStatus } from '../api/simulation' import LanguageSwitcher from '../components/LanguageSwitcher.vue' +import { useI18n } from 'vue-i18n' +const { t } = useI18n() const route = useRoute() const router = useRouter() @@ -149,7 +151,7 @@ const toggleMaximize = (target) => { const handleGoBack = async () => { // 在返回 Step 2 之前,先关闭正在运行的模拟 - addLog('准备返回 Step 2,正在关闭模拟...') + addLog(t('log.preparingGoBack')) // 停止轮询 stopGraphRefresh() @@ -159,36 +161,36 @@ const handleGoBack = async () => { const envStatusRes = await getEnvStatus({ simulation_id: currentSimulationId.value }) if (envStatusRes.success && envStatusRes.data?.env_alive) { - addLog('正在关闭模拟环境...') + addLog(t('log.closingSimEnv')) try { await closeSimulationEnv({ simulation_id: currentSimulationId.value, timeout: 10 }) - addLog('✓ 模拟环境已关闭') + addLog(t('log.simEnvClosed')) } catch (closeErr) { - addLog(`关闭模拟环境失败,尝试强制停止...`) + addLog(t('log.closeSimEnvFailed')) try { await stopSimulation({ simulation_id: currentSimulationId.value }) - addLog('✓ 模拟已强制停止') + addLog(t('log.simForceStopSuccess')) } catch (stopErr) { - addLog(`强制停止失败: ${stopErr.message}`) + addLog(t('log.forceStopFailed', { error: stopErr.message })) } } } else { // 环境未运行,检查是否需要停止进程 if (isSimulating.value) { - addLog('正在停止模拟进程...') + addLog(t('log.stoppingSimProcess')) try { await stopSimulation({ simulation_id: currentSimulationId.value }) - addLog('✓ 模拟已停止') + addLog(t('log.simStopped')) } catch (err) { - addLog(`停止模拟失败: ${err.message}`) + addLog(t('log.stopSimFailed', { error: err.message })) } } } } catch (err) { - addLog(`检查模拟状态失败: ${err.message}`) + addLog(t('log.checkStatusFailed', { error: err.message })) } // 返回到 Step 2 (环境搭建) @@ -198,13 +200,13 @@ const handleGoBack = async () => { const handleNextStep = () => { // Step3Simulation 组件会直接处理报告生成和路由跳转 // 这个方法仅作为备用 - addLog('进入 Step 4: 报告生成') + addLog(t('log.enterStep4')) } // --- Data Logic --- const loadSimulationData = async () => { try { - addLog(`加载模拟数据: ${currentSimulationId.value}`) + addLog(t('log.loadingSimData', { id: currentSimulationId.value })) // 获取 simulation 信息 const simRes = await getSimulation(currentSimulationId.value) @@ -216,10 +218,10 @@ const loadSimulationData = async () => { const configRes = await getSimulationConfig(currentSimulationId.value) if (configRes.success && configRes.data?.time_config?.minutes_per_round) { minutesPerRound.value = configRes.data.time_config.minutes_per_round - addLog(`时间配置: 每轮 ${minutesPerRound.value} 分钟`) + addLog(t('log.timeConfig', { minutes: minutesPerRound.value })) } } catch (configErr) { - addLog(`获取时间配置失败,使用默认值: ${minutesPerRound.value}分钟/轮`) + addLog(t('log.timeConfigFetchFailed', { minutes: minutesPerRound.value })) } // 获取 project 信息 @@ -227,7 +229,7 @@ const loadSimulationData = async () => { const projRes = await getProject(simData.project_id) if (projRes.success && projRes.data) { projectData.value = projRes.data - addLog(`项目加载成功: ${projRes.data.project_id}`) + addLog(t('log.projectLoadSuccess', { id: projRes.data.project_id })) // 获取 graph 数据 if (projRes.data.graph_id) { @@ -236,10 +238,10 @@ const loadSimulationData = async () => { } } } else { - addLog(`加载模拟数据失败: ${simRes.error || '未知错误'}`) + addLog(t('log.loadSimDataFailed', { error: simRes.error || t('common.unknownError') })) } } catch (err) { - addLog(`加载异常: ${err.message}`) + addLog(t('log.loadException', { error: err.message })) } } @@ -255,11 +257,11 @@ const loadGraph = async (graphId) => { if (res.success) { graphData.value = res.data if (!isSimulating.value) { - addLog('图谱数据加载成功') + addLog(t('log.graphDataLoadSuccess')) } } } catch (err) { - addLog(`图谱加载失败: ${err.message}`) + addLog(t('log.graphLoadFailed', { error: err.message })) } finally { graphLoading.value = false } @@ -276,7 +278,7 @@ let graphRefreshTimer = null const startGraphRefresh = () => { if (graphRefreshTimer) return - addLog('开启图谱实时刷新 (30s)') + addLog(t('log.graphRealtimeRefreshStart')) // 立即刷新一次,然后每30秒刷新 graphRefreshTimer = setInterval(refreshGraph, 30000) } @@ -285,7 +287,7 @@ const stopGraphRefresh = () => { if (graphRefreshTimer) { clearInterval(graphRefreshTimer) graphRefreshTimer = null - addLog('停止图谱实时刷新') + addLog(t('log.graphRealtimeRefreshStop')) } } @@ -298,11 +300,11 @@ watch(isSimulating, (newValue) => { }, { immediate: true }) onMounted(() => { - addLog('SimulationRunView 初始化') + addLog(t('log.simRunViewInit')) // 记录 maxRounds 配置(值已在初始化时从 query 参数获取) if (maxRounds.value) { - addLog(`自定义模拟轮数: ${maxRounds.value}`) + addLog(t('log.customRounds', { rounds: maxRounds.value })) } loadSimulationData() diff --git a/frontend/src/views/SimulationView.vue b/frontend/src/views/SimulationView.vue index e7dcc9f..f3e1c18 100644 --- a/frontend/src/views/SimulationView.vue +++ b/frontend/src/views/SimulationView.vue @@ -73,7 +73,9 @@ import Step2EnvSetup from '../components/Step2EnvSetup.vue' import { getProject, getGraphData } from '../api/graph' import { getSimulation, stopSimulation, getEnvStatus, closeSimulationEnv } from '../api/simulation' import LanguageSwitcher from '../components/LanguageSwitcher.vue' +import { useI18n } from 'vue-i18n' +const { t } = useI18n() const route = useRoute() const router = useRouter() @@ -149,13 +151,13 @@ const handleGoBack = () => { } const handleNextStep = (params = {}) => { - addLog('进入 Step 3: 开始模拟') - + addLog(t('log.enterStep3')) + // 记录模拟轮数配置 if (params.maxRounds) { - addLog(`自定义模拟轮数: ${params.maxRounds} 轮`) + addLog(t('log.customRoundsConfig', { rounds: params.maxRounds })) } else { - addLog('使用自动配置的模拟轮数') + addLog(t('log.useAutoRounds')) } // 构建路由参数 @@ -187,7 +189,7 @@ const checkAndStopRunningSimulation = async () => { const envStatusRes = await getEnvStatus({ simulation_id: currentSimulationId.value }) if (envStatusRes.success && envStatusRes.data?.env_alive) { - addLog('检测到模拟环境正在运行,正在关闭...') + addLog(t('log.detectedSimEnvRunning')) // 尝试优雅关闭模拟环境 try { @@ -197,14 +199,14 @@ const checkAndStopRunningSimulation = async () => { }) if (closeRes.success) { - addLog('✓ 模拟环境已关闭') + addLog(t('log.simEnvClosed')) } else { - addLog(`关闭模拟环境失败: ${closeRes.error || '未知错误'}`) + addLog(t('log.closeSimEnvFailedWithError', { error: closeRes.error || t('common.unknownError') })) // 如果优雅关闭失败,尝试强制停止 await forceStopSimulation() } } catch (closeErr) { - addLog(`关闭模拟环境异常: ${closeErr.message}`) + addLog(t('log.closeSimEnvException', { error: closeErr.message })) // 如果优雅关闭异常,尝试强制停止 await forceStopSimulation() } @@ -212,7 +214,7 @@ const checkAndStopRunningSimulation = async () => { // 环境未运行,但可能进程还在,检查模拟状态 const simRes = await getSimulation(currentSimulationId.value) if (simRes.success && simRes.data?.status === 'running') { - addLog('检测到模拟状态为运行中,正在停止...') + addLog(t('log.detectedSimRunning')) await forceStopSimulation() } } @@ -229,30 +231,30 @@ const forceStopSimulation = async () => { try { const stopRes = await stopSimulation({ simulation_id: currentSimulationId.value }) if (stopRes.success) { - addLog('✓ 模拟已强制停止') + addLog(t('log.simForceStopSuccess')) } else { - addLog(`强制停止模拟失败: ${stopRes.error || '未知错误'}`) + addLog(t('log.forceStopSimFailed', { error: stopRes.error || t('common.unknownError') })) } } catch (err) { - addLog(`强制停止模拟异常: ${err.message}`) + addLog(t('log.forceStopSimException', { error: err.message })) } } const loadSimulationData = async () => { try { - addLog(`加载模拟数据: ${currentSimulationId.value}`) - + addLog(t('log.loadingSimData', { id: currentSimulationId.value })) + // 获取 simulation 信息 const simRes = await getSimulation(currentSimulationId.value) if (simRes.success && simRes.data) { const simData = simRes.data - + // 获取 project 信息 if (simData.project_id) { const projRes = await getProject(simData.project_id) if (projRes.success && projRes.data) { projectData.value = projRes.data - addLog(`项目加载成功: ${projRes.data.project_id}`) + addLog(t('log.projectLoadSuccess', { id: projRes.data.project_id })) // 获取 graph 数据 if (projRes.data.graph_id) { @@ -261,10 +263,10 @@ const loadSimulationData = async () => { } } } else { - addLog(`加载模拟数据失败: ${simRes.error || '未知错误'}`) + addLog(t('log.loadSimDataFailed', { error: simRes.error || t('common.unknownError') })) } } catch (err) { - addLog(`加载异常: ${err.message}`) + addLog(t('log.loadException', { error: err.message })) } } @@ -274,10 +276,10 @@ const loadGraph = async (graphId) => { const res = await getGraphData(graphId) if (res.success) { graphData.value = res.data - addLog('图谱数据加载成功') + addLog(t('log.graphDataLoadSuccess')) } } catch (err) { - addLog(`图谱加载失败: ${err.message}`) + addLog(t('log.graphLoadFailed', { error: err.message })) } finally { graphLoading.value = false } @@ -290,7 +292,7 @@ const refreshGraph = () => { } onMounted(async () => { - addLog('SimulationView 初始化') + addLog(t('log.simViewInit')) // 检查并关闭正在运行的模拟(用户从 Step 3 返回时) await checkAndStopRunningSimulation()