feat: user frontend i18n (zh-CN/en)
- vue-i18n@9 with locale files for zh-CN and en - Language switcher in topbar - Navigation, breadcrumb, credits page translated - Discovery page i18n keys prepared - Language persisted in localStorage - Build verified
This commit is contained in:
@@ -16,16 +16,16 @@
|
||||
:collapse-transition="false"
|
||||
@select="showMobileMenu = false"
|
||||
>
|
||||
<el-menu-item index="/discovery"><el-icon><Search /></el-icon><span>发现客户</span></el-menu-item>
|
||||
<el-menu-item index="/workspace"><el-icon><Odometer /></el-icon><span>工作台</span></el-menu-item>
|
||||
<el-menu-item index="/customers"><el-icon><User /></el-icon><span>客户管理</span></el-menu-item>
|
||||
<el-menu-item index="/products"><el-icon><Goods /></el-icon><span>产品库</span></el-menu-item>
|
||||
<el-menu-item index="/quotations"><el-icon><DocumentCopy /></el-icon><span>报价单</span></el-menu-item>
|
||||
<el-menu-item index="/translate"><el-icon><ChatLineSquare /></el-icon><span>智能翻译</span></el-menu-item>
|
||||
<el-menu-item index="/marketing"><el-icon><Promotion /></el-icon><span>营销素材</span></el-menu-item>
|
||||
<el-menu-item index="/followup"><el-icon><Message /></el-icon><span>智能跟进</span></el-menu-item>
|
||||
<el-menu-item index="/analytics"><el-icon><DataAnalysis /></el-icon><span>数据分析</span></el-menu-item>
|
||||
<el-menu-item index="/team"><el-icon><UserFilled /></el-icon><span>团队协作</span></el-menu-item>
|
||||
<el-menu-item index="/discovery"><el-icon><Search /></el-icon><span>{{ $t('nav.discovery') }}</span></el-menu-item>
|
||||
<el-menu-item index="/workspace"><el-icon><Odometer /></el-icon><span>{{ $t('nav.workspace') }}</span></el-menu-item>
|
||||
<el-menu-item index="/customers"><el-icon><User /></el-icon><span>{{ $t('nav.customers') }}</span></el-menu-item>
|
||||
<el-menu-item index="/products"><el-icon><Goods /></el-icon><span>{{ $t('nav.products') }}</span></el-menu-item>
|
||||
<el-menu-item index="/quotations"><el-icon><DocumentCopy /></el-icon><span>{{ $t('nav.quotations') }}</span></el-menu-item>
|
||||
<el-menu-item index="/translate"><el-icon><ChatLineSquare /></el-icon><span>{{ $t('nav.translate') }}</span></el-menu-item>
|
||||
<el-menu-item index="/marketing"><el-icon><Promotion /></el-icon><span>{{ $t('nav.marketing') }}</span></el-menu-item>
|
||||
<el-menu-item index="/followup"><el-icon><Message /></el-icon><span>{{ $t('nav.followup') }}</span></el-menu-item>
|
||||
<el-menu-item index="/analytics"><el-icon><DataAnalysis /></el-icon><span>{{ $t('nav.analytics') }}</span></el-menu-item>
|
||||
<el-menu-item index="/team"><el-icon><UserFilled /></el-icon><span>{{ $t('nav.team') }}</span></el-menu-item>
|
||||
</el-menu>
|
||||
</aside>
|
||||
|
||||
@@ -35,13 +35,14 @@
|
||||
<el-icon :size="20"><Expand /></el-icon>
|
||||
</el-button>
|
||||
<el-breadcrumb separator="/" class="breadcrumb">
|
||||
<el-breadcrumb-item :to="'/workspace'">工作台</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-if="route.meta?.title" :to="route.path">{{ route.meta.title }}</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="'/workspace'">{{ $t('nav.workspace') }}</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-if="route.meta?.title" :to="route.path">{{ $t('nav.' + route.name?.toLowerCase()) || route.meta.title }}</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="topbar-right">
|
||||
<el-button text style="font-size:13px;color:#999" @click="toggleLang">{{ currentLang }}</el-button>
|
||||
<el-button v-if="creditBalance !== null" text class="credit-btn" @click="$router.push('/credits')">
|
||||
<el-icon><Coin /></el-icon>
|
||||
<span class="credit-text">{{ creditBalance }} 次</span>
|
||||
<span class="credit-text">{{ creditBalance }} {{ $t('topbar.credits') }}</span>
|
||||
</el-button>
|
||||
<el-badge :value="unread" :hidden="!unread" class="notif-badge">
|
||||
<el-button text style="font-size:18px" @click="$router.push('/notifications')">
|
||||
@@ -56,9 +57,9 @@
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="$router.push('/profile')">个人中心</el-dropdown-item>
|
||||
<el-dropdown-item @click="$router.push('/notifications')">通知中心</el-dropdown-item>
|
||||
<el-dropdown-item divided @click="handleLogout">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item @click="$router.push('/profile')">{{ $t('nav.profile') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click="$router.push('/notifications')">{{ $t('nav.notifications') }}</el-dropdown-item>
|
||||
<el-dropdown-item divided @click="handleLogout">{{ $t('common.confirm') }}退出</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -89,18 +90,27 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { getUnreadCount, getCreditBalance } from '@/api'
|
||||
import AiAssistant from '@/components/AiAssistant.vue'
|
||||
import { switchLang } from '@/i18n'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { locale } = useI18n()
|
||||
const auth = useAuthStore()
|
||||
const collapsed = ref(false)
|
||||
const showMobileMenu = ref(false)
|
||||
const unread = ref(0)
|
||||
const creditBalance = ref(null)
|
||||
|
||||
const currentLang = computed(() => locale.value === 'en' ? 'English' : '中文')
|
||||
function toggleLang() {
|
||||
const next = locale.value === 'en' ? 'zh-CN' : 'en'
|
||||
switchLang(next)
|
||||
}
|
||||
|
||||
async function loadCreditBalance() {
|
||||
try {
|
||||
const res = await getCreditBalance()
|
||||
|
||||
Reference in New Issue
Block a user