feat(i18n): translate system title, tenant name, shorten English translation, add tooltip

This commit is contained in:
2026-06-25 16:36:18 +08:00
parent aa011c3721
commit 8d5871ca39
3 changed files with 59 additions and 27 deletions

View File

@@ -83,6 +83,9 @@ const translationDict = {
'首页': 'Home', '仪表盘': 'Dashboard', '个人中心': 'Profile', '首页': 'Home', '仪表盘': 'Dashboard', '个人中心': 'Profile',
'帮助': 'Help', '关于': 'About', '版本': 'Version', '帮助': 'Help', '关于': 'About', '版本': 'Version',
'在线': 'Online', '离线': 'Offline', '已连接': 'Connected', '未连接': 'Disconnected', '在线': 'Online', '离线': 'Offline', '已连接': 'Connected', '未连接': 'Disconnected',
'医院信息管理系统': 'Hospital HIS', '医院管理系统': 'Hospital HIS',
'信息管理系统': 'Info System', '管理系统': 'Management System',
'经创贺联': 'HealthLink', 'HIS': 'HIS',
'元': 'Yuan', '次': 'Times', '天': 'Days', '小时': 'Hours', '分钟': 'Minutes', '元': 'Yuan', '次': 'Times', '天': 'Days', '小时': 'Hours', '分钟': 'Minutes',
'条': 'Items', '个': 'Items', '项': 'Items', '次/分': 'Times/min', '条': 'Items', '个': 'Items', '项': 'Items', '次/分': 'Times/min',
// 菜单专用术语 // 菜单专用术语

View File

@@ -7,31 +7,37 @@
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground, sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
}" }"
> >
<router-link <el-tooltip
class="sidebar-logo-link" :content="title"
to="/index" placement="right"
:disabled="!collapse"
> >
<el-image <router-link
:src="logoImage" class="sidebar-logo-link"
class="sidebar-logo" to="/index"
fit="contain"
/>
<div
v-if="!collapse"
class="logo-text"
:style="{ color: textColor }"
> >
<h1 class="sidebar-title"> <el-image
{{ title }} :src="logoImage"
</h1> class="sidebar-logo"
<p fit="contain"
v-if="displayName" />
class="hospital-name" <div
v-if="!collapse"
class="logo-text"
:style="{ color: textColor }"
> >
{{ displayName }} <h1 class="sidebar-title">
</p> {{ title }}
</div> </h1>
</router-link> <p
v-if="displayName"
class="hospital-name"
>
{{ displayName }}
</p>
</div>
</router-link>
</el-tooltip>
</div> </div>
</template> </template>
@@ -41,8 +47,9 @@ import useSettingsStore from '@/store/modules/settings';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import {computed} from 'vue'; import {computed} from 'vue';
import {useI18n} from 'vue-i18n'; import {useI18n} from 'vue-i18n';
import {autoTranslate} from '@/i18n/autoTranslate';
const {t} = useI18n(); const {t, locale} = useI18n();
defineProps({ defineProps({
collapse: { collapse: {
@@ -51,11 +58,25 @@ defineProps({
}, },
}); });
const title = computed(() => import.meta.env.VITE_APP_TITLE || t('sidebar.defaultTitle'));
const settingsStore = useSettingsStore(); const settingsStore = useSettingsStore();
const userStore = useUserStore(); const userStore = useUserStore();
// 系统标题:优先用 i18n 翻译fallback 到环境变量
const title = computed(() => {
const envTitle = import.meta.env.VITE_APP_TITLE;
if (locale.value === 'zh-CN') return envTitle || t('sidebar.defaultTitle');
// 非中文时,用自动翻译
return autoTranslate(envTitle || '医院信息管理系统');
});
// 租户/医院名称:非中文时尝试自动翻译
const displayName = computed(() => {
const name = userStore.tenantName || userStore.hospitalName || userStore.orgName || '';
if (!name || locale.value === 'zh-CN') return name;
return autoTranslate(name);
});
const sideTheme = computed(() => settingsStore.sideTheme); const sideTheme = computed(() => settingsStore.sideTheme);
const displayName = computed(() => userStore.tenantName || userStore.hospitalName || userStore.orgName || '');
const textColor = computed(() => { const textColor = computed(() => {
return sideTheme.value === 'theme-dark' ? '#fff' : '#303133'; return sideTheme.value === 'theme-dark' ? '#fff' : '#303133';

View File

@@ -15,7 +15,7 @@
/> />
</div> </div>
<h1 class="brand-title"> <h1 class="brand-title">
{{ currentTenantName || settings.systemName }} {{ brandTitle }}
</h1> </h1>
<p class="brand-subtitle"> <p class="brand-subtitle">
{{ $t('login.systemSubtitle') }} {{ $t('login.systemSubtitle') }}
@@ -229,7 +229,7 @@
<span v-if="backendVersion">&nbsp;·&nbsp;{{ $t('login.backendVersion') }} v{{ formattedBackendVersion }}</span> <span v-if="backendVersion">&nbsp;·&nbsp;{{ $t('login.backendVersion') }} v{{ formattedBackendVersion }}</span>
</p> </p>
<p class="copyright"> <p class="copyright">
&copy; 2025 {{ currentTenantName || settings.systemName }}{{ $t('login.copyrightSystem') }} &copy; 2025 {{ brandTitle }}{{ $t('login.copyrightSystem') }}
</p> </p>
</div> </div>
</div> </div>
@@ -250,6 +250,7 @@ import useUserStore from '@/store/modules/user';
import {ElMessage} from 'element-plus'; import {ElMessage} from 'element-plus';
import {getSystemVersion} from '@/api/system/info'; import {getSystemVersion} from '@/api/system/info';
import logoNew from '@/assets/logo/LOGO.jpg'; import logoNew from '@/assets/logo/LOGO.jpg';
import {autoTranslate} from '@/i18n/autoTranslate';
const userStore = useUserStore(); const userStore = useUserStore();
const route = useRoute(); const route = useRoute();
@@ -304,6 +305,13 @@ const loginForm = ref({
const tenantOptions = ref([]); const tenantOptions = ref([]);
const currentTenantName = ref(''); const currentTenantName = ref('');
// 品牌标题:非中文时自动翻译
const brandTitle = computed(() => {
const name = currentTenantName.value || settings.systemName;
if (!name || locale.value === 'zh-CN') return name;
return autoTranslate(name);
});
const loginRules = computed(() => ({ const loginRules = computed(() => ({
username: [{ required: true, trigger: 'blur', message: t('login.validationUsername') }], username: [{ required: true, trigger: 'blur', message: t('login.validationUsername') }],
password: [{ required: true, trigger: 'blur', message: t('login.validationPassword') }], password: [{ required: true, trigger: 'blur', message: t('login.validationPassword') }],