mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 19:29:04 +08:00
wip: multi-language support
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
<template>
|
||||
<BasicModal :width="800" title="错误详情" v-bind="$attrs">
|
||||
<BasicModal :width="800" :title="t('sys.errorLog.tableActionDesc')" v-bind="$attrs">
|
||||
<Description :data="info" @register="register" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { BasicModal } from '/@/components/Modal/index';
|
||||
import { ErrorInfo } from '/@/store/modules/error';
|
||||
import { Description, useDescription } from '/@/components/Description/index';
|
||||
|
||||
import { getDescSchema } from './data';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -20,12 +23,15 @@
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const [register] = useDescription({
|
||||
column: 2,
|
||||
schema: getDescSchema(),
|
||||
});
|
||||
return {
|
||||
register,
|
||||
useI18n,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -2,11 +2,15 @@ import { Tag } from 'ant-design-vue';
|
||||
import { BasicColumn } from '/@/components/Table/index';
|
||||
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
|
||||
|
||||
import { useExternalI18n } from '/@/hooks/web/useLocale';
|
||||
|
||||
const { t } = useExternalI18n();
|
||||
|
||||
export function getColumns(): BasicColumn[] {
|
||||
return [
|
||||
{
|
||||
dataIndex: 'type',
|
||||
title: '类型',
|
||||
title: t('sys.errorLog.tableColumnType'),
|
||||
width: 80,
|
||||
customRender: ({ text }) => {
|
||||
const color =
|
||||
@@ -24,17 +28,17 @@ export function getColumns(): BasicColumn[] {
|
||||
},
|
||||
{
|
||||
dataIndex: 'url',
|
||||
title: '地址',
|
||||
title: 'URL',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
dataIndex: 'time',
|
||||
title: '时间',
|
||||
title: t('sys.errorLog.tableColumnDate'),
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
dataIndex: 'file',
|
||||
title: '文件',
|
||||
title: t('sys.errorLog.tableColumnFile'),
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
@@ -44,12 +48,12 @@ export function getColumns(): BasicColumn[] {
|
||||
},
|
||||
{
|
||||
dataIndex: 'message',
|
||||
title: '错误信息',
|
||||
title: t('sys.errorLog.tableColumnMsg'),
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
dataIndex: 'stack',
|
||||
title: 'stack信息',
|
||||
title: t('sys.errorLog.tableColumnStackMsg'),
|
||||
width: 300,
|
||||
},
|
||||
];
|
||||
|
@@ -6,12 +6,22 @@
|
||||
<DetailModal :info="rowInfoRef" @register="registerModal" />
|
||||
<BasicTable @register="register" class="error-handle-table">
|
||||
<template #toolbar>
|
||||
<a-button @click="fireVueError" type="primary"> 点击触发vue错误 </a-button>
|
||||
<a-button @click="fireResourceError" type="primary"> 点击触发resource错误 </a-button>
|
||||
<a-button @click="fireAjaxError" type="primary"> 点击触发ajax错误 </a-button>
|
||||
<a-button @click="fireVueError" type="primary">
|
||||
{{ t('sys.errorLog.fireVueError') }}
|
||||
</a-button>
|
||||
<a-button @click="fireResourceError" type="primary">
|
||||
{{ t('sys.errorLog.fireResourceError') }}
|
||||
</a-button>
|
||||
<a-button @click="fireAjaxError" type="primary">
|
||||
{{ t('sys.errorLog.fireAjaxError') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction :actions="[{ label: '详情', onClick: handleDetail.bind(null, record) }]" />
|
||||
<TableAction
|
||||
:actions="[
|
||||
{ label: t('sys.errorLog.tableActionDesc'), onClick: handleDetail.bind(null, record) },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
@@ -21,10 +31,11 @@
|
||||
import { defineComponent, watch, ref, nextTick } from 'vue';
|
||||
|
||||
import DetailModal from './DetailModal.vue';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table/index';
|
||||
|
||||
import { useModal } from '/@/components/Modal/index';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table/index';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { errorStore, ErrorInfo } from '/@/store/modules/error';
|
||||
|
||||
@@ -42,12 +53,14 @@
|
||||
const rowInfoRef = ref<ErrorInfo>();
|
||||
const imgListRef = ref<string[]>([]);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const [register, { setTableData }] = useTable({
|
||||
title: '错误日志列表',
|
||||
title: t('sys.errorLog.tableTitle'),
|
||||
columns: getColumns(),
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: '操作',
|
||||
title: 'Action',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
@@ -67,7 +80,7 @@
|
||||
);
|
||||
const { createMessage } = useMessage();
|
||||
if (isDevMode()) {
|
||||
createMessage.info('只在`/src/settings/projectSetting.ts` 内的useErrorHandle=true时生效!');
|
||||
createMessage.info(t('sys.errorLog.enableMessage'));
|
||||
}
|
||||
// 查看详情
|
||||
function handleDetail(row: ErrorInfo) {
|
||||
@@ -96,6 +109,7 @@
|
||||
fireAjaxError,
|
||||
imgListRef,
|
||||
rowInfoRef,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -12,6 +12,7 @@ import { useRoute } from 'vue-router';
|
||||
|
||||
import { useGo, useRedo } from '/@/hooks/web/usePage';
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import './exception.less';
|
||||
interface MapValue {
|
||||
@@ -47,9 +48,12 @@ export default defineComponent({
|
||||
},
|
||||
setup(props) {
|
||||
const statusMapRef = ref(new Map<string | number, MapValue>());
|
||||
|
||||
const { query } = useRoute();
|
||||
const go = useGo();
|
||||
const redo = useRedo();
|
||||
const { t } = useI18n();
|
||||
|
||||
const getStatus = computed(() => {
|
||||
const { status: routeStatus } = query;
|
||||
const { status } = props;
|
||||
@@ -62,41 +66,44 @@ export default defineComponent({
|
||||
}
|
||||
);
|
||||
|
||||
const backLoginI18n = t('sys.exception.backLogin');
|
||||
const backHomeI18n = t('sys.exception.backHome');
|
||||
|
||||
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
|
||||
title: '403',
|
||||
status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
|
||||
subTitle: `Sorry, you don't have access to this page.!`,
|
||||
btnText: props.full ? 'Back Login' : 'Back Home',
|
||||
subTitle: t('sys.exception.subTitle403'),
|
||||
btnText: props.full ? backLoginI18n : backHomeI18n,
|
||||
handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
|
||||
});
|
||||
|
||||
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
|
||||
title: '404',
|
||||
status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
|
||||
subTitle: `Sorry, the page you visited does not exist.`,
|
||||
btnText: props.full ? 'Back Login' : 'Back Home',
|
||||
subTitle: t('sys.exception.subTitle404'),
|
||||
btnText: props.full ? backLoginI18n : backHomeI18n,
|
||||
handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
|
||||
});
|
||||
|
||||
unref(statusMapRef).set(ExceptionEnum.ERROR, {
|
||||
title: '500',
|
||||
status: `${ExceptionEnum.ERROR}`,
|
||||
subTitle: `Sorry, the server is reporting an error.`,
|
||||
btnText: 'Back Home',
|
||||
subTitle: t('sys.exception.subTitle500'),
|
||||
btnText: backHomeI18n,
|
||||
handler: () => go(),
|
||||
});
|
||||
|
||||
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
|
||||
title: 'No data on the current page',
|
||||
title: t('sys.exception.noDataTitle'),
|
||||
subTitle: '',
|
||||
btnText: 'Refresh',
|
||||
btnText: t('sys.exception.redo'),
|
||||
handler: () => redo(),
|
||||
icon: notDataImg,
|
||||
});
|
||||
|
||||
unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
|
||||
title: 'Network Error',
|
||||
subTitle: 'Sorry,Your network connection has been disconnected, please check your network!',
|
||||
title: t('sys.exception.networkErrorTitle'),
|
||||
subTitle: t('sys.exception.networkErrorSubTitle'),
|
||||
btnText: 'Refresh',
|
||||
handler: () => redo(),
|
||||
icon: netWorkImg,
|
||||
|
@@ -6,36 +6,38 @@
|
||||
<p class="lock-page__header-name">{{ realName }}</p>
|
||||
</div>
|
||||
<BasicForm @register="register" v-if="!getIsNotPwd" />
|
||||
<Alert v-if="errMsgRef" type="error" message="锁屏密码错误" banner />
|
||||
<Alert v-if="errMsgRef" type="error" :message="t('sys.lock.alert')" banner />
|
||||
<div class="lock-page__footer">
|
||||
<a-button type="default" class="mt-2 mr-2" @click="goLogin" v-if="!getIsNotPwd">
|
||||
返回登录
|
||||
{{ t('sys.lock.backToLogin') }}
|
||||
</a-button>
|
||||
<a-button type="primary" class="mt-2" @click="unLock(!getIsNotPwd)" :loading="loadingRef">
|
||||
进入系统
|
||||
{{ t('sys.lock.entry') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// 组件相关
|
||||
import { defineComponent, ref, computed } from 'vue';
|
||||
import { Alert } from 'ant-design-vue';
|
||||
// hook
|
||||
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LockPage',
|
||||
components: { Alert, BasicForm },
|
||||
|
||||
setup() {
|
||||
// 获取配置文件
|
||||
// 样式前缀
|
||||
const loadingRef = ref(false);
|
||||
const errMsgRef = ref(false);
|
||||
|
||||
const { t } = useI18n();
|
||||
const [register, { validateFields }] = useForm({
|
||||
showActionButtonGroup: false,
|
||||
schemas: [
|
||||
@@ -45,7 +47,7 @@
|
||||
component: 'InputPassword',
|
||||
componentProps: {
|
||||
style: { width: '100%' },
|
||||
placeholder: '请输入锁屏密码或者用户密码',
|
||||
placeholder: t('sys.lock.placeholder'),
|
||||
},
|
||||
rules: [{ required: true }],
|
||||
},
|
||||
@@ -55,6 +57,14 @@
|
||||
const { realName } = userStore.getUserInfoState || {};
|
||||
return realName;
|
||||
});
|
||||
|
||||
const getIsNotPwd = computed(() => {
|
||||
if (!appStore.getLockInfo) {
|
||||
return true;
|
||||
}
|
||||
return appStore.getLockInfo.pwd === undefined;
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: unLock
|
||||
*/
|
||||
@@ -76,17 +86,12 @@
|
||||
loadingRef.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function goLogin() {
|
||||
userStore.loginOut(true);
|
||||
appStore.resetLockInfo();
|
||||
}
|
||||
const getIsNotPwd = computed(() => {
|
||||
if (!appStore.getLockInfo) {
|
||||
return true;
|
||||
}
|
||||
return appStore.getLockInfo.pwd === undefined;
|
||||
});
|
||||
// 账号密码登录
|
||||
|
||||
return {
|
||||
register,
|
||||
getIsNotPwd,
|
||||
@@ -95,6 +100,7 @@
|
||||
unLock,
|
||||
errMsgRef,
|
||||
loadingRef,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -4,6 +4,7 @@
|
||||
<div class="login-form-wrap">
|
||||
<div class="login-form mx-6">
|
||||
<div class="login-form__content px-2 py-10">
|
||||
<AppLocalPicker class="login-form__locale" />
|
||||
<header>
|
||||
<img :src="logo" class="mr-4" />
|
||||
<h1>{{ title }}</h1>
|
||||
@@ -29,13 +30,15 @@
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-checkbox v-model:checked="autoLogin" size="small">自动登录</a-checkbox>
|
||||
<a-checkbox v-model:checked="autoLogin" size="small">{{
|
||||
t('sys.login.autoLogin')
|
||||
}}</a-checkbox>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item :style="{ 'text-align': 'right' }">
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-button type="link" size="small">忘记密码</a-button>
|
||||
<a-button type="link" size="small">{{ t('sys.login.forgetPassword') }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -47,7 +50,7 @@
|
||||
:block="true"
|
||||
@click="login"
|
||||
:loading="formState.loading"
|
||||
>{{ t('system.login.button') }}</a-button
|
||||
>{{ t('sys.login.loginButton') }}</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -61,6 +64,7 @@
|
||||
import { Checkbox } from 'ant-design-vue';
|
||||
|
||||
import Button from '/@/components/Button/index.vue';
|
||||
import { AppLocalPicker } from '/@/components/Application';
|
||||
// import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index';
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
@@ -68,7 +72,7 @@
|
||||
|
||||
// import { appStore } from '/@/store/modules/app';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useSetting } from '/@/hooks/core/useSetting';
|
||||
import { useGlobSetting } from '/@/settings/use';
|
||||
import logo from '/@/assets/images/logo.png';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -76,14 +80,16 @@
|
||||
// BasicDragVerify,
|
||||
AButton: Button,
|
||||
ACheckbox: Checkbox,
|
||||
AppLocalPicker,
|
||||
},
|
||||
setup() {
|
||||
const formRef = ref<any>(null);
|
||||
const autoLoginRef = ref(false);
|
||||
// const verifyRef = ref<RefInstanceType<DragVerifyActionType>>(null);
|
||||
|
||||
const { globSetting } = useSetting();
|
||||
const globSetting = useGlobSetting();
|
||||
const { notification } = useMessage();
|
||||
const { t } = useI18n();
|
||||
|
||||
// const openLoginVerifyRef = computed(() => appStore.getProjectConfig.openLoginVerify);
|
||||
|
||||
@@ -97,8 +103,10 @@
|
||||
});
|
||||
|
||||
const formRules = reactive({
|
||||
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
account: [{ required: true, message: t('sys.login.accountPlaceholder'), trigger: 'blur' }],
|
||||
password: [
|
||||
{ required: true, message: t('sys.login.passwordPlaceholder'), trigger: 'blur' },
|
||||
],
|
||||
// verify: unref(openLoginVerifyRef) ? [{ required: true, message: '请通过验证码校验' }] : [],
|
||||
});
|
||||
|
||||
@@ -123,8 +131,8 @@
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: '登录成功',
|
||||
description: `欢迎回来: ${userInfo.realName}`,
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
@@ -134,7 +142,6 @@
|
||||
formState.loading = false;
|
||||
}
|
||||
}
|
||||
const { t } = useI18n();
|
||||
return {
|
||||
formRef,
|
||||
// verifyRef,
|
||||
@@ -195,7 +202,14 @@
|
||||
.respond-to(xlarge, { width: 540px; right:0});
|
||||
}
|
||||
|
||||
&__locale {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #999;
|
||||
|
Reference in New Issue
Block a user