fix: 首次访问获取客户端默认语言/静态路由title

This commit is contained in:
TsMask
2023-11-20 18:12:29 +08:00
parent 9fdd322757
commit e9054e320f
13 changed files with 142 additions and 35 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> </title> <title>laoding...</title>
<link rel="preload" href="/loading.js" as="script"> <link rel="preload" href="/loading.js" as="script">
<script async src="/loading.js"></script> <script async src="/loading.js"></script>
<link rel="preload" href="/config.js" as="script"> <link rel="preload" href="/config.js" as="script">

View File

@@ -155,22 +155,30 @@
} }
</style>`; </style>`;
// 根据浏览器选择语言
const lang = localStorage.getItem('cache:local:i18n');
if (!lang) {
let preferredLanguage = navigator.language;
if (preferredLanguage.indexOf('-')) {
preferredLanguage = preferredLanguage.replace('-', '_');
}
localStorage.setItem('cache:local:i18n', preferredLanguage);
}
let loadInfo = { let loadInfo = {
title: '正在加载资源', title: '正在加载资源',
titleSub: '初次加载资源可能需要较多时间', titleSub: '初次加载资源可能需要较多时间',
msg: '请耐心等待', msg: '请耐心等待',
}; };
document.title = "AGrandEMS"; // document.title = "AGrandEMS";
// 判断选择语言
const lang = localStorage.getItem('cache:local:i18n') || 'zh_CN';
if (lang === 'en_US') { if (lang === 'en_US') {
loadInfo = { loadInfo = {
title: 'Loading Resources', title: 'Loading Resources',
titleSub: 'Loading resources for the first time may take a lot of time', titleSub: 'Loading resources for the first time may take a lot of time',
msg: 'Please be patient', msg: 'Please be patient',
}; };
document.title = "AGrandEMS"; // document.title = "AGrandEMS";
} }
const divStr = ` const divStr = `

View File

@@ -2,25 +2,46 @@
export const RESULT_CODE_SUCCESS = 1; export const RESULT_CODE_SUCCESS = 1;
/**响应-msg正常成功 */ /**响应-msg正常成功 */
export const RESULT_MSG_SUCCESS = 'success'; export const RESULT_MSG_SUCCESS: Record<string, string> = {
zh_CN: '成功!',
en_US: 'Success!',
};
/**响应-code错误失败 */ /**响应-code错误失败 */
export const RESULT_CODE_ERROR = 0; export const RESULT_CODE_ERROR = 0;
/**响应-msg错误失败 */ /**响应-msg错误失败 */
export const RESULT_MSG_ERROR = 'error'; export const RESULT_MSG_ERROR: Record<string, string> = {
zh_CN: '错误!',
en_US: 'Error!',
};
/**响应-网络连接超时 */ /**响应-网络连接超时 */
export const RESULT_MSG_TIMEOUT = 'Network connection timeout!'; export const RESULT_MSG_TIMEOUT: Record<string, string> = {
zh_CN: '网络连接超时!',
en_US: 'Network Connection Timeout!',
};
/**响应-未知响应数据类型 */ /**响应-未知响应数据类型 */
export const RESULT_MSG_NOT_TYPE = 'Unknown response data type!'; export const RESULT_MSG_NOT_TYPE: Record<string, string> = {
zh_CN: '未知响应数据类型!',
en_US: 'Unknown Response Data Type!',
};
/**响应-服务器连接出错 */ /**响应-服务器连接出错 */
export const RESULT_MSG_SERVER_ERROR = 'Server connection error!'; export const RESULT_MSG_SERVER_ERROR: Record<string, string> = {
zh_CN: '服务器连接出错!',
en_US: 'Server Connection Error!',
};
/**响应-请求地址未找到 */ /**响应-请求地址未找到 */
export const RESULT_MSG_URL_NOTFOUND = 'Request address not found!'; export const RESULT_MSG_URL_NOTFOUND: Record<string, string> = {
zh_CN: '请求地址未找到!',
en_US: 'Request Address Not Found!',
};
/**响应-数据正在处理,请勿重复提交 */ /**响应-数据正在处理,请勿重复提交 */
export const RESULT_MSG_URL_RESUBMIT = 'Data is being processed, please do not resubmit!'; export const RESULT_MSG_URL_RESUBMIT: Record<string, string> = {
zh_CN: '数据正在处理,请勿重复提交!',
en_US: 'Data are being processed, please do not resubmit',
};

View File

@@ -6,7 +6,7 @@ import enUS from './locales/en-US';
const i18n = createI18n({ const i18n = createI18n({
legacy: false, // 使用 Composition API 的方式创建 i18n 实例 legacy: false, // 使用 Composition API 的方式创建 i18n 实例
locale: localGet(CACHE_LOCAL_I18N) || 'zh_CN', // 默认显示语言 locale: localGet(CACHE_LOCAL_I18N) || 'en_US', // 默认显示语言
messages: { messages: {
zh_CN: zhCN, zh_CN: zhCN,
en_US: enUS, en_US: enUS,

View File

@@ -124,6 +124,10 @@ export default {
// 静态路由 // 静态路由
router: { router: {
index: "Home", index: "Home",
login: "Sign In",
register: 'Registrations',
page403: 'No Access',
page404: 'Match Page Not Found',
account: { account: {
index: "Personal Center", index: "Personal Center",
profile: "Personal Info", profile: "Personal Info",

View File

@@ -124,6 +124,10 @@ export default {
// 静态路由 // 静态路由
router: { router: {
index: "主页", index: "主页",
login: "登录",
register: '注册',
page403: '没有访问权限',
page404: '找不到匹配页面',
account: { account: {
index: "个人中心", index: "个人中心",
profile: "个人信息", profile: "个人信息",

View File

@@ -82,6 +82,9 @@ type OptionsType = {
signal?: AbortSignal; signal?: AbortSignal;
}; };
// 多语言处理
const language = localGet(CACHE_LOCAL_I18N) || 'en_US';
// 兼容旧前端可改配置文件 // 兼容旧前端可改配置文件
const baseUrl = import.meta.env.PROD const baseUrl = import.meta.env.PROD
? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL ? sessionGet('baseUrl') || import.meta.env.VITE_API_BASE_URL
@@ -121,11 +124,7 @@ function beforeRequest(options: OptionsType): OptionsType | Promise<any> {
} }
// 客户端接受语言 // 客户端接受语言
Reflect.set( Reflect.set(options.headers, 'Accept-Language', `${language};q=0.9`);
options.headers,
'Accept-Language',
`${localGet(CACHE_LOCAL_I18N) || 'en_US'};q=0.9`
);
// 是否需要设置 token // 是否需要设置 token
const token = getToken(); const token = getToken();
@@ -153,7 +152,7 @@ function beforeRequest(options: OptionsType): OptionsType | Promise<any> {
requestObj.data === data && requestObj.data === data &&
requestObj.time - time < interval requestObj.time - time < interval
) { ) {
const message = RESULT_MSG_URL_RESUBMIT; const message = RESULT_MSG_URL_RESUBMIT[language];
return Promise.resolve({ return Promise.resolve({
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: message, msg: message,
@@ -204,14 +203,14 @@ function interceptorResponse(res: ResultType): ResultType | Promise<any> {
if (!Reflect.has(res, 'code')) { if (!Reflect.has(res, 'code')) {
return Promise.resolve({ return Promise.resolve({
code: RESULT_CODE_SUCCESS, code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS, msg: RESULT_MSG_SUCCESS[language],
data: res, data: res,
}); });
} }
if (Reflect.has(res, 'error')) { if (Reflect.has(res, 'error')) {
return Promise.resolve({ return Promise.resolve({
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: RESULT_MSG_ERROR, msg: RESULT_MSG_ERROR[language],
data: res.error, data: res.error,
}); });
} }
@@ -291,7 +290,7 @@ export async function request(options: OptionsType): Promise<ResultType> {
: await res.arrayBuffer(); : await res.arrayBuffer();
return { return {
code: RESULT_CODE_SUCCESS, code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS, msg: RESULT_MSG_SUCCESS[language],
data: data, data: data,
status: res.status, status: res.status,
headers: res.headers, headers: res.headers,
@@ -299,7 +298,7 @@ export async function request(options: OptionsType): Promise<ResultType> {
default: default:
return { return {
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: RESULT_MSG_NOT_TYPE, msg: RESULT_MSG_NOT_TYPE[language],
}; };
} }
} catch (error: any) { } catch (error: any) {
@@ -307,7 +306,7 @@ export async function request(options: OptionsType): Promise<ResultType> {
if (error.name === 'AbortError') { if (error.name === 'AbortError') {
return { return {
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: RESULT_MSG_TIMEOUT, msg: RESULT_MSG_TIMEOUT[language],
}; };
} }
throw error; throw error;
@@ -326,21 +325,21 @@ function stateCode(res: Response) {
if (res.status === 500) { if (res.status === 500) {
return { return {
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: RESULT_MSG_SERVER_ERROR, msg: RESULT_MSG_SERVER_ERROR[language],
}; };
} }
// 上传文件成功无内容返回 // 上传文件成功无内容返回
if (res.status === 204 && res.statusText === 'No Content') { if (res.status === 204 && res.statusText === 'No Content') {
return { return {
code: RESULT_CODE_SUCCESS, code: RESULT_CODE_SUCCESS,
msg: RESULT_MSG_SUCCESS, msg: RESULT_MSG_SUCCESS[language],
}; };
} }
// 地址找不到 // 地址找不到
if (res.status === 404 || res.status === 405) { if (res.status === 404 || res.status === 405) {
return { return {
code: RESULT_CODE_ERROR, code: RESULT_CODE_ERROR,
msg: RESULT_MSG_URL_NOTFOUND, msg: RESULT_MSG_URL_NOTFOUND[language],
}; };
} }
// 身份授权 // 身份授权

View File

@@ -66,16 +66,19 @@ const constantRoutes: RouteRecordRaw[] = [
{ {
path: '/login', path: '/login',
name: 'Login', name: 'Login',
meta: { title: 'router.login' },
component: () => import('@/views/login.vue'), component: () => import('@/views/login.vue'),
}, },
{ {
path: '/register', path: '/register',
name: 'Register', name: 'Register',
meta: { title: 'router.register' },
component: () => import('@/views/register.vue'), component: () => import('@/views/register.vue'),
}, },
{ {
path: '/403', path: '/403',
name: 'NotPermission', name: 'NotPermission',
meta: { title: 'router.page403' },
component: () => import('@/views/error/403.vue'), component: () => import('@/views/error/403.vue'),
}, },
{ {
@@ -91,6 +94,7 @@ const constantRoutes: RouteRecordRaw[] = [
}, },
{ {
path: '/:pathMatch(.*)*', path: '/:pathMatch(.*)*',
meta: { title: 'router.page404' },
component: () => import('@/views/error/404.vue'), component: () => import('@/views/error/404.vue'),
}, },
]; ];

View File

@@ -47,7 +47,7 @@ const useAppStore = defineStore('app', {
*/ */
getLOGOIcon(state) { getLOGOIcon(state) {
const path = state.filePathIcon; const path = state.filePathIcon;
if (!path) { if (!path || path === '#') {
return defaultLOGOIcon; return defaultLOGOIcon;
} }
if (validHttp(path)) { if (validHttp(path)) {
@@ -66,7 +66,7 @@ const useAppStore = defineStore('app', {
*/ */
getLOGOBrand(state) { getLOGOBrand(state) {
const path = state.filePathBrand; const path = state.filePathBrand;
if (!path) { if (!path || path === '#') {
return defaultLOGOBrand; return defaultLOGOBrand;
} }
if (validHttp(path)) { if (validHttp(path)) {

View File

@@ -1,8 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRouter } from 'vue-router'; import { onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
const router = useRouter(); const router = useRouter();
const route = useRoute();
const appStore = useAppStore();
const { t } = useI18n(); const { t } = useI18n();
/**
* 国际化翻译转换
*/
function fnLocale() {
let title = route.meta.title as string;
if (title.indexOf('router.') !== -1) {
title = t(title);
}
appStore.setTitle(title);
}
onMounted(() => {
fnLocale();
});
</script> </script>
<template> <template>

View File

@@ -1,6 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
const route = useRoute();
const appStore = useAppStore();
const { t } = useI18n(); const { t } = useI18n();
/**
* 国际化翻译转换
*/
function fnLocale() {
let title = route.meta.title as string;
if (title.indexOf('router.') !== -1) {
title = t(title);
}
appStore.setTitle(title);
}
onMounted(() => {
fnLocale();
});
</script> </script>
<template> <template>

View File

@@ -21,9 +21,9 @@ let state = reactive({
/**表单属性 */ /**表单属性 */
from: { from: {
/**账号 */ /**账号 */
username: '', username: 'supervisor',
/**密码 */ /**密码 */
password: '', password: 'rootaa',
/**验证码 */ /**验证码 */
code: '', code: '',
/**验证码uuid */ /**验证码uuid */
@@ -96,10 +96,22 @@ const calcBG = computed(() => {
backgroundSize: 'cover', backgroundSize: 'cover',
}; };
} }
return undefined return undefined;
}); });
/**
* 国际化翻译转换
*/
function fnLocale() {
let title = route.meta.title as string;
if (title.indexOf('router.') !== -1) {
title = t(title);
}
appStore.setTitle(title);
}
onMounted(() => { onMounted(() => {
fnLocale()
fnGetCaptcha(); fnGetCaptcha();
}); });

View File

@@ -1,15 +1,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import { GlobalFooter } from '@ant-design-vue/pro-layout'; import { GlobalFooter } from '@ant-design-vue/pro-layout';
import { Modal, message } from 'ant-design-vue/lib'; import { Modal, message } from 'ant-design-vue/lib';
import { reactive, toRaw } from 'vue'; import { onMounted, reactive, toRaw } from 'vue';
import { register } from '@/api/login'; import { register } from '@/api/login';
import { regExpPasswd, regExpUserName } from '@/utils/regular-utils'; import { regExpPasswd, regExpUserName } from '@/utils/regular-utils';
import { useRouter } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
const { t } = useI18n(); const { t } = useI18n();
const router = useRouter(); const router = useRouter();
const route = useRoute();
const appStore = useAppStore(); const appStore = useAppStore();
let state = reactive({ let state = reactive({
@@ -68,6 +69,21 @@ function fnFinish() {
state.formClick = false; state.formClick = false;
}); });
} }
/**
* 国际化翻译转换
*/
function fnLocale() {
let title = route.meta.title as string;
if (title.indexOf('router.') !== -1) {
title = t(title);
}
appStore.setTitle(title);
}
onMounted(() => {
fnLocale();
});
</script> </script>
<template> <template>