feat(i18n): replace hardcoded Chinese in frontend components with i18n calls
Replace all user-visible hardcoded Chinese strings in 7 component files with $t() / t() calls using vue-i18n: - Step1GraphBuild: ontology generation, graph build, status badges - Step2EnvSetup: simulation setup, agent personas, platform config, time config, initial activation, modal profile details - Step3Simulation: report generation button - Step4Report: section loading text, interaction button - Step5Interaction: chat interface, survey UI, tool descriptions, error messages, agent selection - GraphPanel: graph status hints, loading states, tooltips - HistoryDatabase: history cards, modal, replay buttons Added missing translation keys to both zh.json and en.json locale files. Added useI18n imports to components that need script-level translations.
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
<!-- 标题区域 -->
|
||||
<div class="section-header">
|
||||
<div class="section-line"></div>
|
||||
<span class="section-title">推演记录</span>
|
||||
<span class="section-title">{{ $t('history.title') }}</span>
|
||||
<div class="section-line"></div>
|
||||
</div>
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
<span
|
||||
class="status-icon"
|
||||
:class="{ available: project.project_id, unavailable: !project.project_id }"
|
||||
title="图谱构建"
|
||||
:title="$t('history.graphBuild')"
|
||||
>◇</span>
|
||||
<span
|
||||
class="status-icon available"
|
||||
title="环境搭建"
|
||||
:title="$t('history.envSetup')"
|
||||
>◈</span>
|
||||
<span
|
||||
class="status-icon"
|
||||
:class="{ available: project.report_id, unavailable: !project.report_id }"
|
||||
title="分析报告"
|
||||
:title="$t('history.analysisReport')"
|
||||
>◆</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,13 +67,13 @@
|
||||
</div>
|
||||
<!-- 如果有更多文件,显示提示 -->
|
||||
<div v-if="project.files.length > 3" class="files-more">
|
||||
+{{ project.files.length - 3 }} 个文件
|
||||
{{ $t('history.moreFiles', { count: project.files.length - 3 }) }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- 无文件时的占位 -->
|
||||
<div class="files-empty" v-else>
|
||||
<span class="empty-file-icon">◇</span>
|
||||
<span class="empty-file-text">暂无文件</span>
|
||||
<span class="empty-file-text">{{ $t('history.noFiles') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<!-- 加载状态 -->
|
||||
<div v-if="loading" class="loading-state">
|
||||
<span class="loading-spinner"></span>
|
||||
<span class="loading-text">加载中...</span>
|
||||
<span class="loading-text">{{ $t('history.loadingText') }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 历史回放详情弹窗 -->
|
||||
@@ -126,27 +126,27 @@
|
||||
<div class="modal-body">
|
||||
<!-- 模拟需求 -->
|
||||
<div class="modal-section">
|
||||
<div class="modal-label">模拟需求</div>
|
||||
<div class="modal-requirement">{{ selectedProject.simulation_requirement || '无' }}</div>
|
||||
<div class="modal-label">{{ $t('history.simRequirement') }}</div>
|
||||
<div class="modal-requirement">{{ selectedProject.simulation_requirement || $t('common.none') }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<div class="modal-section">
|
||||
<div class="modal-label">关联文件</div>
|
||||
<div class="modal-label">{{ $t('history.relatedFiles') }}</div>
|
||||
<div class="modal-files" v-if="selectedProject.files && selectedProject.files.length > 0">
|
||||
<div v-for="(file, index) in selectedProject.files" :key="index" class="modal-file-item">
|
||||
<span class="file-tag" :class="getFileType(file.filename)">{{ getFileTypeLabel(file.filename) }}</span>
|
||||
<span class="modal-file-name">{{ file.filename }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-empty" v-else>暂无关联文件</div>
|
||||
<div class="modal-empty" v-else>{{ $t('history.noRelatedFiles') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 推演回放分割线 -->
|
||||
<div class="modal-divider">
|
||||
<span class="divider-line"></span>
|
||||
<span class="divider-text">推演回放</span>
|
||||
<span class="divider-text">{{ $t('history.replayTitle') }}</span>
|
||||
<span class="divider-line"></span>
|
||||
</div>
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
>
|
||||
<span class="btn-step">Step1</span>
|
||||
<span class="btn-icon">◇</span>
|
||||
<span class="btn-text">图谱构建</span>
|
||||
<span class="btn-text">{{ $t('history.step1Button') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="modal-btn btn-simulation"
|
||||
@@ -167,7 +167,7 @@
|
||||
>
|
||||
<span class="btn-step">Step2</span>
|
||||
<span class="btn-icon">◈</span>
|
||||
<span class="btn-text">环境搭建</span>
|
||||
<span class="btn-text">{{ $t('history.step2Button') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="modal-btn btn-report"
|
||||
@@ -176,12 +176,12 @@
|
||||
>
|
||||
<span class="btn-step">Step4</span>
|
||||
<span class="btn-icon">◆</span>
|
||||
<span class="btn-text">分析报告</span>
|
||||
<span class="btn-text">{{ $t('history.step4Button') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 不可回放提示 -->
|
||||
<div class="modal-playback-hint">
|
||||
<span class="hint-text">Step3「开始模拟」与 Step5「深度互动」需在运行中启动,不支持历史回放</span>
|
||||
<span class="hint-text">{{ $t('history.replayHint') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -193,10 +193,12 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted, onActivated, watch, nextTick } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getSimulationHistory } from '../api/simulation'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { t } = useI18n()
|
||||
|
||||
// 状态
|
||||
const projects = ref([])
|
||||
@@ -337,7 +339,7 @@ const truncateText = (text, maxLength) => {
|
||||
|
||||
// 从模拟需求生成标题(取前20字)
|
||||
const getSimulationTitle = (requirement) => {
|
||||
if (!requirement) return '未命名模拟'
|
||||
if (!requirement) return t('history.untitledSimulation')
|
||||
const title = requirement.slice(0, 20)
|
||||
return requirement.length > 20 ? title + '...' : title
|
||||
}
|
||||
@@ -353,8 +355,8 @@ const formatSimulationId = (simulationId) => {
|
||||
const formatRounds = (simulation) => {
|
||||
const current = simulation.current_round || 0
|
||||
const total = simulation.total_rounds || 0
|
||||
if (total === 0) return '未开始'
|
||||
return `${current}/${total} 轮`
|
||||
if (total === 0) return t('history.notStarted')
|
||||
return t('history.roundsProgress', { current, total })
|
||||
}
|
||||
|
||||
// 获取文件类型(用于样式)
|
||||
@@ -382,7 +384,7 @@ const getFileTypeLabel = (filename) => {
|
||||
|
||||
// 截断文件名(保留扩展名)
|
||||
const truncateFilename = (filename, maxLength) => {
|
||||
if (!filename) return '未知文件'
|
||||
if (!filename) return t('history.unknownFile')
|
||||
if (filename.length <= maxLength) return filename
|
||||
|
||||
const ext = filename.includes('.') ? '.' + filename.split('.').pop() : ''
|
||||
|
||||
Reference in New Issue
Block a user