mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-02-12 11:30:07 +08:00
feat: 增加繁体中文适配 (#1497)
This commit is contained in:
parent
4662f4703c
commit
597c9ea4c0
@ -60,7 +60,7 @@ func GinI18nLocalize() gin.HandlerFunc {
|
|||||||
return ginI18n.Localize(
|
return ginI18n.Localize(
|
||||||
ginI18n.WithBundle(&ginI18n.BundleCfg{
|
ginI18n.WithBundle(&ginI18n.BundleCfg{
|
||||||
RootPath: "./lang",
|
RootPath: "./lang",
|
||||||
AcceptLanguage: []language.Tag{language.Chinese, language.English},
|
AcceptLanguage: []language.Tag{language.Chinese, language.English, language.TraditionalChinese},
|
||||||
DefaultLanguage: language.Chinese,
|
DefaultLanguage: language.Chinese,
|
||||||
FormatBundleFile: "yaml",
|
FormatBundleFile: "yaml",
|
||||||
UnmarshalFunc: yaml.Unmarshal,
|
UnmarshalFunc: yaml.Unmarshal,
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
ErrInvalidParams: "請求參數錯誤: {{ .detail }}"
|
ErrInvalidParams: "請求參數錯誤: {{ .detail }}"
|
||||||
ErrToken: "Token 訊息錯誤: {{ .detail }}"
|
|
||||||
ErrTokenParse: "Token 產生錯誤: {{ .detail }}"
|
ErrTokenParse: "Token 產生錯誤: {{ .detail }}"
|
||||||
ErrTokenTimeOut: "登入資料已過期: {{ .detail }}"
|
|
||||||
ErrInitialPassword: "原密碼錯誤"
|
ErrInitialPassword: "原密碼錯誤"
|
||||||
ErrInternalServer: "伺服器內部錯誤: {{ .detail }}"
|
ErrInternalServer: "伺服器內部錯誤: {{ .detail }}"
|
||||||
ErrRecordExist: "紀錄已存在"
|
ErrRecordExist: "記錄已存在"
|
||||||
ErrRecordNotFound: "紀錄未找到"
|
ErrRecordNotFound: "記錄未找到"
|
||||||
ErrStructTransform: "類型轉換失敗: {{ .detail }}"
|
ErrStructTransform: "類型轉換失敗: {{ .detail }}"
|
||||||
ErrNotLogin: "用戶未登入: {{ .detail }}"
|
ErrNotLogin: "用戶未登入: {{ .detail }}"
|
||||||
ErrNotSafety: "當前用戶登入狀態不安全: {{ .detail }}"
|
|
||||||
ErrPasswordExpired: "當前密碼已過期: {{ .detail }}"
|
ErrPasswordExpired: "當前密碼已過期: {{ .detail }}"
|
||||||
ErrNotSupportType: "系統暫不支持當前類型: {{ .detail }}"
|
ErrNotSupportType: "系統暫不支持當前類型: {{ .detail }}"
|
||||||
ErrRepoNotValid: "遠程倉庫驗證失敗!"
|
|
||||||
|
|
||||||
#common
|
#common
|
||||||
ErrNameIsExist: "名稱已存在"
|
ErrNameIsExist: "名稱已存在"
|
@ -18,11 +18,13 @@ class RequestHttp {
|
|||||||
service: AxiosInstance;
|
service: AxiosInstance;
|
||||||
public constructor(config: AxiosRequestConfig) {
|
public constructor(config: AxiosRequestConfig) {
|
||||||
this.service = axios.create(config);
|
this.service = axios.create(config);
|
||||||
|
let language = globalStore.language === 'tw' ? 'zh-Hant' : globalStore.language;
|
||||||
this.service.interceptors.request.use(
|
this.service.interceptors.request.use(
|
||||||
(config: AxiosRequestConfig) => {
|
(config: AxiosRequestConfig) => {
|
||||||
if (config.method != 'get') {
|
if (config.method != 'get') {
|
||||||
config.headers = {
|
config.headers = {
|
||||||
'X-CSRF-TOKEN': globalStore.csrfToken,
|
'X-CSRF-TOKEN': globalStore.csrfToken,
|
||||||
|
'Accept-Language': language,
|
||||||
...config.headers,
|
...config.headers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
import zh from './modules/zh';
|
import zh from './modules/zh';
|
||||||
|
import tw from './modules/tw';
|
||||||
import en from './modules/en';
|
import en from './modules/en';
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
@ -8,6 +9,7 @@ const i18n = createI18n({
|
|||||||
globalInjection: true,
|
globalInjection: true,
|
||||||
messages: {
|
messages: {
|
||||||
zh,
|
zh,
|
||||||
|
tw,
|
||||||
en,
|
en,
|
||||||
},
|
},
|
||||||
warnHtmlMessage: false,
|
warnHtmlMessage: false,
|
||||||
|
@ -135,6 +135,7 @@ const message = {
|
|||||||
licenseHelper:
|
licenseHelper:
|
||||||
'Agree « <a href="https://www.fit2cloud.com/legal/licenses.html" target="_blank">Community License Agreement</a> »',
|
'Agree « <a href="https://www.fit2cloud.com/legal/licenses.html" target="_blank">Community License Agreement</a> »',
|
||||||
errorAgree: 'Please click to agree to the Community Software License Agreement',
|
errorAgree: 'Please click to agree to the Community Software License Agreement',
|
||||||
|
logout: 'Logout',
|
||||||
},
|
},
|
||||||
rule: {
|
rule: {
|
||||||
username: 'Please enter a username',
|
username: 'Please enter a username',
|
||||||
@ -182,18 +183,6 @@ const message = {
|
|||||||
notFound: 'The resource does not exist',
|
notFound: 'The resource does not exist',
|
||||||
commonError: 'The request failed',
|
commonError: 'The request failed',
|
||||||
},
|
},
|
||||||
header: {
|
|
||||||
language: 'Internationalization',
|
|
||||||
zh: '简体中文',
|
|
||||||
en: 'English',
|
|
||||||
theme: 'Layout Settings',
|
|
||||||
globalTheme: 'Global',
|
|
||||||
themeColor: 'Theme Color',
|
|
||||||
darkTheme: 'Dark Theme',
|
|
||||||
personalData: 'Personal Data',
|
|
||||||
changePassword: 'Change Password',
|
|
||||||
logout: 'Logout',
|
|
||||||
},
|
|
||||||
service: {
|
service: {
|
||||||
serviceNotStarted: 'The {0} service is not currently started',
|
serviceNotStarted: 'The {0} service is not currently started',
|
||||||
},
|
},
|
||||||
|
1503
frontend/src/lang/modules/tw.ts
Normal file
1503
frontend/src/lang/modules/tw.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -136,6 +136,7 @@ const message = {
|
|||||||
licenseHelper:
|
licenseHelper:
|
||||||
'同意 « <a href="https://www.fit2cloud.com/legal/licenses.html" target="_blank"> 飞致云社区软件许可协议</a> »',
|
'同意 « <a href="https://www.fit2cloud.com/legal/licenses.html" target="_blank"> 飞致云社区软件许可协议</a> »',
|
||||||
errorAgree: '请点击同意社区软件许可协议',
|
errorAgree: '请点击同意社区软件许可协议',
|
||||||
|
logout: '退出登录',
|
||||||
},
|
},
|
||||||
rule: {
|
rule: {
|
||||||
username: '请输入用户名',
|
username: '请输入用户名',
|
||||||
@ -181,18 +182,6 @@ const message = {
|
|||||||
notFound: '资源不存在',
|
notFound: '资源不存在',
|
||||||
commonError: '请求失败',
|
commonError: '请求失败',
|
||||||
},
|
},
|
||||||
header: {
|
|
||||||
language: '国际化',
|
|
||||||
zh: '简体中文',
|
|
||||||
en: 'English',
|
|
||||||
theme: '布局设置',
|
|
||||||
globalTheme: '全局主题',
|
|
||||||
themeColor: '主题颜色',
|
|
||||||
darkTheme: '暗黑主题',
|
|
||||||
personalData: '个人资料',
|
|
||||||
changePassword: '修改密码',
|
|
||||||
logout: '退出登录',
|
|
||||||
},
|
|
||||||
service: {
|
service: {
|
||||||
serviceNotStarted: '当前未启动 {0} 服务',
|
serviceNotStarted: '当前未启动 {0} 服务',
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<SvgIcon :iconName="'p-logout'" :className="'svg-icon'"></SvgIcon>
|
<SvgIcon :iconName="'p-logout'" :className="'svg-icon'"></SvgIcon>
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span @click="logout">{{ $t('commons.header.logout') }}</span>
|
<span @click="logout">{{ $t('commons.login.logout') }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
|
@ -13,7 +13,7 @@ export interface GlobalState {
|
|||||||
isLogin: boolean;
|
isLogin: boolean;
|
||||||
entrance: string;
|
entrance: string;
|
||||||
csrfToken: string;
|
csrfToken: string;
|
||||||
language: string; // zh | en
|
language: string; // zh | en | tw
|
||||||
// assemblySize: string; // small | default | large
|
// assemblySize: string; // small | default | large
|
||||||
themeConfig: ThemeConfigProp;
|
themeConfig: ThemeConfigProp;
|
||||||
isFullScreen: boolean;
|
isFullScreen: boolean;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
:type="activeTag === item.key ? 'primary' : ''"
|
:type="activeTag === item.key ? 'primary' : ''"
|
||||||
:plain="activeTag !== item.key"
|
:plain="activeTag !== item.key"
|
||||||
>
|
>
|
||||||
{{ language == 'zh' ? item.name : item.key }}
|
{{ language == 'zh' || language == 'tw' ? item.name : item.key }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@ -79,13 +79,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="app-desc">
|
<div class="app-desc">
|
||||||
<span class="desc">
|
<span class="desc">
|
||||||
{{ language == 'zh' ? app.shortDescZh : app.shortDescEn }}
|
{{
|
||||||
|
language == 'zh' || language == 'tw'
|
||||||
|
? app.shortDescZh
|
||||||
|
: app.shortDescEn
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-tag">
|
<div class="app-tag">
|
||||||
<el-tag v-for="(tag, ind) in app.tags" :key="ind" style="margin-right: 5px">
|
<el-tag v-for="(tag, ind) in app.tags" :key="ind" style="margin-right: 5px">
|
||||||
<span :style="{ color: getColor(ind) }">
|
<span :style="{ color: getColor(ind) }">
|
||||||
{{ language == 'zh' ? tag.name : tag.key }}
|
{{ language == 'zh' || language == 'tw' ? tag.name : tag.key }}
|
||||||
</span>
|
</span>
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="app.status === 'TakeDown'" style="margin-right: 5px">
|
<el-tag v-if="app.status === 'TakeDown'" style="margin-right: 5px">
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<span>
|
<span>
|
||||||
{{ language == 'zh' ? app.shortDescZh : app.shortDescEn }}
|
{{ language == 'zh' || language == 'tw' ? app.shortDescZh : app.shortDescEn }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="version">
|
<div class="version">
|
||||||
|
@ -237,7 +237,7 @@ const changeService = (value: string, services: App.AppService[]) => {
|
|||||||
|
|
||||||
const getLabel = (row: ParamObj): string => {
|
const getLabel = (row: ParamObj): string => {
|
||||||
const language = useI18n().locale.value;
|
const language = useI18n().locale.value;
|
||||||
if (language == 'zh') {
|
if (language == 'zh' || language == 'tw') {
|
||||||
return row.labelZh;
|
return row.labelZh;
|
||||||
} else {
|
} else {
|
||||||
return row.labelEn;
|
return row.labelEn;
|
||||||
|
@ -223,7 +223,7 @@ const get = async () => {
|
|||||||
|
|
||||||
const getLabel = (row: EditForm): string => {
|
const getLabel = (row: EditForm): string => {
|
||||||
const language = useI18n().locale.value;
|
const language = useI18n().locale.value;
|
||||||
if (language == 'zh') {
|
if (language == 'zh' || language == 'tw') {
|
||||||
return row.labelZh;
|
return row.labelZh;
|
||||||
} else {
|
} else {
|
||||||
return row.labelEn;
|
return row.labelEn;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="h-app-desc">
|
<div class="h-app-desc">
|
||||||
<span>
|
<span>
|
||||||
{{ language == 'zh' ? app.shortDescZh : app.shortDescEn }}
|
{{ language == 'zh' || language == 'tw' ? app.shortDescZh : app.shortDescEn }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,7 +65,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('logs.operate')" min-width="150px" prop="detailZH">
|
<el-table-column :label="$t('logs.operate')" min-width="150px" prop="detailZH">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="globalStore.language === 'zh'">{{ row.detailZH }}</span>
|
<span v-if="globalStore.language === 'zh' || globalStore.language === 'tw'">
|
||||||
|
{{ row.detailZH }}
|
||||||
|
</span>
|
||||||
<span v-if="globalStore.language === 'en'">{{ row.detailEN }}</span>
|
<span v-if="globalStore.language === 'en'">{{ row.detailEN }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -143,7 +145,7 @@ const search = async () => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
data.value = res.data.items || [];
|
data.value = res.data.items || [];
|
||||||
if (globalStore.language === 'zh') {
|
if (globalStore.language === 'zh' || globalStore.language === 'tw') {
|
||||||
for (const item of data.value) {
|
for (const item of data.value) {
|
||||||
item.detailZH = loadDetail(item.detailZH);
|
item.detailZH = loadDetail(item.detailZH);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@
|
|||||||
@change="onSave('Language', form.language)"
|
@change="onSave('Language', form.language)"
|
||||||
v-model="form.language"
|
v-model="form.language"
|
||||||
>
|
>
|
||||||
<el-radio label="zh">中文</el-radio>
|
<el-radio label="zh">中文(简体)</el-radio>
|
||||||
|
<el-radio label="tw">中文(繁體)</el-radio>
|
||||||
<el-radio label="en">English</el-radio>
|
<el-radio label="en">English</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -98,7 +98,7 @@ const handleParams = () => {
|
|||||||
|
|
||||||
const getLabel = (row: ParamObj): string => {
|
const getLabel = (row: ParamObj): string => {
|
||||||
const language = useI18n().locale.value;
|
const language = useI18n().locale.value;
|
||||||
if (language == 'zh') {
|
if (language == 'zh' || language == 'tw') {
|
||||||
return row.labelZh;
|
return row.labelZh;
|
||||||
} else {
|
} else {
|
||||||
return row.labelEn;
|
return row.labelEn;
|
||||||
|
@ -93,7 +93,7 @@ const handleParams = () => {
|
|||||||
|
|
||||||
const getLabel = (row: ParamObj): string => {
|
const getLabel = (row: ParamObj): string => {
|
||||||
const language = useI18n().locale.value;
|
const language = useI18n().locale.value;
|
||||||
if (language == 'zh') {
|
if (language == 'zh' || language == 'tw') {
|
||||||
return row.labelZh;
|
return row.labelZh;
|
||||||
} else {
|
} else {
|
||||||
return row.labelEn;
|
return row.labelEn;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user