提交 b335e751 编写于 作者: V vben

chore: fix the error-log list as the system route

上级 1f96eaef
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
:overlayClassName="`${prefixCls}-overlay`" :overlayClassName="`${prefixCls}-overlay`"
> >
<span :class="prefixCls"> <span :class="prefixCls">
<Icon icon="cil:language" /> <Icon icon="ion:language" />
<span v-if="showText" :class="`${prefixCls}__text`">{{ getLangText }}</span> <span v-if="showText" :class="`${prefixCls}__text`">{{ getLangText }}</span>
</span> </span>
</Dropdown> </Dropdown>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
export default defineComponent({ export default defineComponent({
name: 'AppSearch', name: 'AppSearch',
components: { AppSearchModal, Tooltip, SearchOutlined }, components: { AppSearchModal, Tooltip },
setup() { setup() {
const showModal = ref(false); const showModal = ref(false);
const { prefixCls } = useDesign('app-search'); const { prefixCls } = useDesign('app-search');
......
...@@ -6,5 +6,5 @@ export enum PageEnum { ...@@ -6,5 +6,5 @@ export enum PageEnum {
// error page path // error page path
ERROR_PAGE = '/exception', ERROR_PAGE = '/exception',
// error log page path // error log page path
ERROR_LOG_PAGE = '/feat/error-log', ERROR_LOG_PAGE = '/error-log/list',
} }
...@@ -10,6 +10,4 @@ export const FullScreen = createAsyncComponent(() => import('./FullScreen.vue')) ...@@ -10,6 +10,4 @@ export const FullScreen = createAsyncComponent(() => import('./FullScreen.vue'))
export const Notify = createAsyncComponent(() => import('./notify/index.vue')); export const Notify = createAsyncComponent(() => import('./notify/index.vue'));
export const LockItem = createAsyncComponent(() => import('./lock/index.vue'));
export const ErrorAction = createAsyncComponent(() => import('./ErrorAction.vue')); export const ErrorAction = createAsyncComponent(() => import('./ErrorAction.vue'));
.lock-modal {
&__entry {
position: relative;
height: 240px;
padding: 130px 30px 60px 30px;
background: #fff;
border-radius: 10px;
}
&__header {
position: absolute;
top: 0;
left: calc(50% - 45px);
width: auto;
text-align: center;
&-img {
width: 70px;
border-radius: 50%;
}
&-name {
margin-top: 5px;
}
}
&__footer {
text-align: center;
}
}
import './LockAction.less';
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal/index';
import { Button } from '/@/components/Button';
import { BasicForm, useForm } from '/@/components/Form/index';
import headerImg from '/@/assets/images/header.jpg';
import { userStore } from '/@/store/modules/user';
import { useI18n } from '/@/hooks/web/useI18n';
import { lockStore } from '/@/store/modules/lock';
const prefixCls = 'lock-modal';
export default defineComponent({
name: 'LockModal',
setup(_, { attrs }) {
const { t } = useI18n();
const [register, { closeModal }] = useModalInner();
const [registerForm, { validateFields, resetFields }] = useForm({
showActionButtonGroup: false,
schemas: [
{
field: 'password',
label: t('layout.header.lockScreenPassword'),
component: 'InputPassword',
required: true,
},
],
});
async function lock() {
const values = (await validateFields()) as any;
const password: string | undefined = values.password;
closeModal();
lockStore.commitLockInfoState({
isLock: true,
pwd: password,
});
await resetFields();
}
return () => (
<BasicModal
footer={null}
title={t('layout.header.lockScreen')}
{...attrs}
class={prefixCls}
onRegister={register}
>
{() => (
<div class={`${prefixCls}__entry`}>
<div class={`${prefixCls}__header`}>
<img src={headerImg} class={`${prefixCls}__header-img`} />
<p class={`${prefixCls}__header-name`}>{userStore.getUserInfoState.realName}</p>
</div>
<BasicForm onRegister={registerForm} />
<div class={`${prefixCls}__footer`}>
<Button type="primary" block class="mt-2" onClick={lock}>
{() => t('layout.header.lockScreenBtn')}
</Button>
</div>
</div>
)}
</BasicModal>
);
},
});
<template>
<span @click="handleLock">
<Tooltip :title="t('layout.header.tooltipLock')" placement="bottom" :mouseEnterDelay="0.5">
<LockOutlined />
</Tooltip>
<LockAction @register="register" />
</span>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Tooltip } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { LockOutlined } from '@ant-design/icons-vue';
import { useModal } from '/@/components/Modal';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
export default defineComponent({
name: 'FullScreen',
components: {
LockOutlined,
Tooltip,
LockAction: createAsyncComponent(() => import('./LockModal.vue')),
},
setup() {
const { t } = useI18n();
const [register, { openModal }] = useModal();
function handleLock() {
openModal(true);
}
return {
t,
register,
handleLock,
};
},
});
</script>
...@@ -12,18 +12,24 @@ ...@@ -12,18 +12,24 @@
<MenuItem <MenuItem
key="doc" key="doc"
:text="t('layout.header.dropdownItemDoc')" :text="t('layout.header.dropdownItemDoc')"
icon="gg:loadbar-doc" icon="ion:document-text-outline"
v-if="getShowDoc" v-if="getShowDoc"
/> />
<MenuDivider /> <MenuDivider />
<MenuItem
key="lock"
:text="t('layout.header.tooltipLock')"
icon="ion:lock-closed-outline"
/>
<MenuItem <MenuItem
key="loginOut" key="loginOut"
:text="t('layout.header.dropdownItemLoginOut')" :text="t('layout.header.dropdownItemLoginOut')"
icon="carbon:power" icon="ion:exit-outline"
/> />
</Menu> </Menu>
</template> </template>
</Dropdown> </Dropdown>
<LockAction @register="register" />
</template> </template>
<script lang="ts"> <script lang="ts">
// components // components
...@@ -31,23 +37,21 @@ ...@@ -31,23 +37,21 @@
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
// res
import { userStore } from '/@/store/modules/user';
import { DOC_URL } from '/@/settings/siteSetting'; import { DOC_URL } from '/@/settings/siteSetting';
import { openWindow } from '/@/utils'; import { userStore } from '/@/store/modules/user';
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; import { useModal } from '/@/components/Modal';
import { propTypes } from '/@/utils/propTypes';
import headerImg from '/@/assets/images/header.jpg'; import headerImg from '/@/assets/images/header.jpg';
import { propTypes } from '/@/utils/propTypes';
import { openWindow } from '/@/utils';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
type MenuEvent = 'loginOut' | 'doc'; type MenuEvent = 'loginOut' | 'doc' | 'lock';
export default defineComponent({ export default defineComponent({
name: 'UserDropdown', name: 'UserDropdown',
...@@ -56,6 +60,7 @@ ...@@ -56,6 +60,7 @@
Menu, Menu,
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')), MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
MenuDivider: Menu.Divider, MenuDivider: Menu.Divider,
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
}, },
props: { props: {
theme: propTypes.oneOf(['dark', 'light']), theme: propTypes.oneOf(['dark', 'light']),
...@@ -70,6 +75,12 @@ ...@@ -70,6 +75,12 @@
return { realName, desc }; return { realName, desc };
}); });
const [register, { openModal }] = useModal();
function handleLock() {
openModal(true);
}
// login out // login out
function handleLoginOut() { function handleLoginOut() {
userStore.confirmLoginOut(); userStore.confirmLoginOut();
...@@ -88,6 +99,9 @@ ...@@ -88,6 +99,9 @@
case 'doc': case 'doc':
openDoc(); openDoc();
break; break;
case 'lock':
handleLock();
break;
} }
} }
...@@ -98,6 +112,7 @@ ...@@ -98,6 +112,7 @@
handleMenuClick, handleMenuClick,
getShowDoc, getShowDoc,
headerImg, headerImg,
register,
}; };
}, },
}); });
......
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
<ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" /> <ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
<LockItem v-if="getUseLockPage" :class="`${prefixCls}-action__item lock-item`" />
<Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" /> <Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
<FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" /> <FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" />
...@@ -61,7 +59,7 @@ ...@@ -61,7 +59,7 @@
import { Layout } from 'ant-design-vue'; import { Layout } from 'ant-design-vue';
import { AppLogo } from '/@/components/Application'; import { AppLogo } from '/@/components/Application';
import LayoutMenu from '../menu'; import LayoutMenu from '../menu/index.vue';
import LayoutTrigger from '../trigger/index.vue'; import LayoutTrigger from '../trigger/index.vue';
import { AppSearch } from '/@/components/Application'; import { AppSearch } from '/@/components/Application';
...@@ -74,14 +72,7 @@ ...@@ -74,14 +72,7 @@
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { AppLocalePicker } from '/@/components/Application'; import { AppLocalePicker } from '/@/components/Application';
import { import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction } from './components';
UserDropDown,
LayoutBreadcrumb,
FullScreen,
Notify,
LockItem,
ErrorAction,
} from './components';
import { useAppInject } from '/@/hooks/web/useAppInject'; import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
...@@ -97,7 +88,6 @@ ...@@ -97,7 +88,6 @@
AppLocalePicker, AppLocalePicker,
FullScreen, FullScreen,
Notify, Notify,
LockItem,
AppSearch, AppSearch,
ErrorAction, ErrorAction,
}, },
......
@prefix-cls: ~'@{namespace}-layout-menu';
@logo-prefix-cls: ~'@{namespace}-app-logo';
.@{prefix-cls} {
&-logo {
height: @header-height;
padding: 10px 4px 10px 10px;
img {
width: @logo-width;
height: @logo-width;
}
}
&--mobile {
.@{logo-prefix-cls} {
&__title {
opacity: 1;
}
}
}
}
import './index.less';
import type { PropType, CSSProperties } from 'vue';
import { computed, defineComponent, unref, toRef } from 'vue';
import { BasicMenu } from '/@/components/Menu';
import { SimpleMenu } from '/@/components/SimpleMenu';
import { AppLogo } from '/@/components/Application';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { ScrollContainer } from '/@/components/Container';
import { useGo } from '/@/hooks/web/usePage';
import { useSplitMenu } from './useLayoutMenu';
import { openWindow } from '/@/utils';
import { propTypes } from '/@/utils/propTypes';
import { isUrl } from '/@/utils/is';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '/@/hooks/web/useDesign';
export default defineComponent({
name: 'LayoutMenu',
props: {
theme: propTypes.oneOf(['light', 'dark']),
splitType: {
type: Number as PropType<MenuSplitTyeEnum>,
default: MenuSplitTyeEnum.NONE,
},
isHorizontal: propTypes.bool,
// menu Mode
menuMode: {
type: [String] as PropType<Nullable<MenuModeEnum>>,
default: '',
},
},
setup(props) {
const go = useGo();
const {
getMenuMode,
getMenuType,
getMenuTheme,
getCollapsed,
getCollapsedShowTitle,
getAccordion,
getIsHorizontal,
getIsSidebarType,
} = useMenuSetting();
const { getShowLogo } = useRootSetting();
const { prefixCls } = useDesign('layout-menu');
const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
const { getIsMobile } = useAppInject();
const getComputedMenuMode = computed(() =>
unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)
);
const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
const getUseScroll = computed(() => {
return (
!unref(getIsHorizontal) &&
(unref(getIsSidebarType) ||
props.splitType === MenuSplitTyeEnum.LEFT ||
props.splitType === MenuSplitTyeEnum.NONE)
);
});
const getWrapperStyle = computed(
(): CSSProperties => {
return {
height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
};
}
);
const getLogoClass = computed(() => {
return [
`${prefixCls}-logo`,
unref(getComputedMenuTheme),
{
[`${prefixCls}--mobile`]: unref(getIsMobile),
},
];
});
/**
* click menu
* @param menu
*/
function handleMenuClick(path: string) {
go(path);
}
/**
* before click menu
* @param menu
*/
async function beforeMenuClickFn(path: string) {
if (!isUrl(path)) {
return true;
}
openWindow(path);
return false;
}
function renderHeader() {
if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
return (
<AppLogo
showTitle={!unref(getCollapsed)}
class={unref(getLogoClass)}
theme={unref(getComputedMenuTheme)}
/>
);
}
function renderMenu() {
const menus = unref(menusRef);
// console.log(menus);
if (!menus || !menus.length) return null;
return !props.isHorizontal ? (
<SimpleMenu
beforeClickFn={beforeMenuClickFn}
items={menus}
theme={unref(getComputedMenuTheme)}
accordion={unref(getAccordion)}
collapse={unref(getCollapsed)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
onMenuClick={handleMenuClick}
/>
) : (
<BasicMenu
beforeClickFn={beforeMenuClickFn}
isHorizontal={props.isHorizontal}
type={unref(getMenuType)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
showLogo={unref(getIsShowLogo)}
mode={unref(getComputedMenuMode)}
theme={unref(getComputedMenuTheme)}
items={menus}
accordion={unref(getAccordion)}
onMenuClick={handleMenuClick}
/>
);
}
return () => {
return (
<>
{renderHeader()}
{unref(getUseScroll) ? (
<ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer>
) : (
renderMenu()
)}
</>
);
};
},
});
<script lang="tsx">
import type { PropType, CSSProperties } from 'vue';
import { computed, defineComponent, unref, toRef } from 'vue';
import { BasicMenu } from '/@/components/Menu';
import { SimpleMenu } from '/@/components/SimpleMenu';
import { AppLogo } from '/@/components/Application';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { ScrollContainer } from '/@/components/Container';
import { useGo } from '/@/hooks/web/usePage';
import { useSplitMenu } from './useLayoutMenu';
import { openWindow } from '/@/utils';
import { propTypes } from '/@/utils/propTypes';
import { isUrl } from '/@/utils/is';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useAppInject } from '/@/hooks/web/useAppInject';
import { useDesign } from '/@/hooks/web/useDesign';
export default defineComponent({
name: 'LayoutMenu',
props: {
theme: propTypes.oneOf(['light', 'dark']),
splitType: {
type: Number as PropType<MenuSplitTyeEnum>,
default: MenuSplitTyeEnum.NONE,
},
isHorizontal: propTypes.bool,
// menu Mode
menuMode: {
type: [String] as PropType<Nullable<MenuModeEnum>>,
default: '',
},
},
setup(props) {
const go = useGo();
const {
getMenuMode,
getMenuType,
getMenuTheme,
getCollapsed,
getCollapsedShowTitle,
getAccordion,
getIsHorizontal,
getIsSidebarType,
} = useMenuSetting();
const { getShowLogo } = useRootSetting();
const { prefixCls } = useDesign('layout-menu');
const { menusRef } = useSplitMenu(toRef(props, 'splitType'));
const { getIsMobile } = useAppInject();
const getComputedMenuMode = computed(() =>
unref(getIsMobile) ? MenuModeEnum.INLINE : props.menuMode || unref(getMenuMode)
);
const getComputedMenuTheme = computed(() => props.theme || unref(getMenuTheme));
const getIsShowLogo = computed(() => unref(getShowLogo) && unref(getIsSidebarType));
const getUseScroll = computed(() => {
return (
!unref(getIsHorizontal) &&
(unref(getIsSidebarType) ||
props.splitType === MenuSplitTyeEnum.LEFT ||
props.splitType === MenuSplitTyeEnum.NONE)
);
});
const getWrapperStyle = computed(
(): CSSProperties => {
return {
height: `calc(100% - ${unref(getIsShowLogo) ? '48px' : '0px'})`,
};
}
);
const getLogoClass = computed(() => {
return [
`${prefixCls}-logo`,
unref(getComputedMenuTheme),
{
[`${prefixCls}--mobile`]: unref(getIsMobile),
},
];
});
/**
* click menu
* @param menu
*/
function handleMenuClick(path: string) {
go(path);
}
/**
* before click menu
* @param menu
*/
async function beforeMenuClickFn(path: string) {
if (!isUrl(path)) {
return true;
}
openWindow(path);
return false;
}
function renderHeader() {
if (!unref(getIsShowLogo) && !unref(getIsMobile)) return null;
return (
<AppLogo
showTitle={!unref(getCollapsed)}
class={unref(getLogoClass)}
theme={unref(getComputedMenuTheme)}
/>
);
}
function renderMenu() {
const menus = unref(menusRef);
// console.log(menus);
if (!menus || !menus.length) return null;
return !props.isHorizontal ? (
<SimpleMenu
beforeClickFn={beforeMenuClickFn}
items={menus}
theme={unref(getComputedMenuTheme)}
accordion={unref(getAccordion)}
collapse={unref(getCollapsed)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
onMenuClick={handleMenuClick}
/>
) : (
<BasicMenu
beforeClickFn={beforeMenuClickFn}
isHorizontal={props.isHorizontal}
type={unref(getMenuType)}
collapsedShowTitle={unref(getCollapsedShowTitle)}
showLogo={unref(getIsShowLogo)}
mode={unref(getComputedMenuMode)}
theme={unref(getComputedMenuTheme)}
items={menus}
accordion={unref(getAccordion)}
onMenuClick={handleMenuClick}
/>
);
}
return () => {
return (
<>
{renderHeader()}
{unref(getUseScroll) ? (
<ScrollContainer style={unref(getWrapperStyle)}>{() => renderMenu()}</ScrollContainer>
) : (
renderMenu()
)}
</>
);
};
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-layout-menu';
@logo-prefix-cls: ~'@{namespace}-app-logo';
.@{prefix-cls} {
&-logo {
height: @header-height;
padding: 10px 4px 10px 10px;
img {
width: @logo-width;
height: @logo-width;
}
}
&--mobile {
.@{logo-prefix-cls} {
&__title {
opacity: 1;
}
}
}
}
</style>
<template> <template>
<div @click="openDrawer" :class="prefixCls"> <div @click="openDrawer" :class="prefixCls">
<SettingOutlined /> <Icon icon="ion:settings-outline" />
<SettingDrawer @register="register" /> <SettingDrawer @register="register" />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { SettingOutlined } from '@ant-design/icons-vue';
import SettingDrawer from './SettingDrawer'; import SettingDrawer from './SettingDrawer';
import Icon from '/@/components/Icon';
import { useDrawer } from '/@/components/Drawer'; import { useDrawer } from '/@/components/Drawer';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
export default defineComponent({ export default defineComponent({
name: 'SettingButton', name: 'SettingButton',
components: { SettingOutlined, SettingDrawer }, components: { SettingDrawer, Icon },
setup() { setup() {
const [register, { openDrawer }] = useDrawer(); const [register, { openDrawer }] = useDrawer();
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
import { computed, defineComponent, ref, unref, CSSProperties } from 'vue'; import { computed, defineComponent, ref, unref, CSSProperties } from 'vue';
import { Layout } from 'ant-design-vue'; import { Layout } from 'ant-design-vue';
import LayoutMenu from '../menu'; import LayoutMenu from '../menu/index.vue';
import LayoutTrigger from '/@/layouts/default/trigger/index.vue'; import LayoutTrigger from '/@/layouts/default/trigger/index.vue';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum'; import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
......
...@@ -17,8 +17,9 @@ ...@@ -17,8 +17,9 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import Sider from './LayoutSider.vue'; import Sider from './LayoutSider.vue';
import { Drawer } from 'ant-design-vue';
import MixSider from './MixSider.vue'; import MixSider from './MixSider.vue';
import { Drawer } from 'ant-design-vue';
import { useAppInject } from '/@/hooks/web/useAppInject'; import { useAppInject } from '/@/hooks/web/useAppInject';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useDesign } from '/@/hooks/web/useDesign'; import { useDesign } from '/@/hooks/web/useDesign';
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</div> </div>
<span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext"> <span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext">
<RightOutlined /> <Icon icon="ion:chevron-down"></Icon>
</span> </span>
</Dropdown> </Dropdown>
</template> </template>
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
import { defineComponent, computed } from 'vue'; import { defineComponent, computed } from 'vue';
import { Dropdown } from '/@/components/Dropdown/index'; import { Dropdown } from '/@/components/Dropdown/index';
import Icon from '/@/components/Icon';
import { TabContentProps, TabContentEnum } from '../types'; import { TabContentProps, TabContentEnum } from '../types';
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
import { RouteLocationNormalized } from 'vue-router'; import { RouteLocationNormalized } from 'vue-router';
export default defineComponent({ export default defineComponent({
name: 'TabContent', name: 'TabContent',
components: { Dropdown, RightOutlined }, components: { Dropdown, RightOutlined, Icon },
props: { props: {
tabItem: { tabItem: {
type: Object as PropType<RouteLocationNormalized>, type: Object as PropType<RouteLocationNormalized>,
......
export default { export default {
login: 'Login', login: 'Login',
errorLogList: 'Error Log',
}; };
export default { export default {
login: '登录', login: '登录',
errorLogList: '错误日志列表',
}; };
import type { AppRouteRecordRaw } from '/@/router/types'; import type { AppRouteRecordRaw } from '/@/router/types';
import ParentLayout from '/@/layouts/page/ParentView.vue'; import ParentLayout from '/@/layouts/page/ParentView.vue';
import { t } from '/@/hooks/web/useI18n';
const EXCEPTION_COMPONENT = () => import('../views/sys/exception/Exception.vue'); const EXCEPTION_COMPONENT = () => import('../views/sys/exception/Exception.vue');
...@@ -65,3 +66,24 @@ export const REDIRECT_ROUTE: AppRouteRecordRaw = { ...@@ -65,3 +66,24 @@ export const REDIRECT_ROUTE: AppRouteRecordRaw = {
}, },
], ],
}; };
export const ERROR_LOG_ROUTE: AppRouteRecordRaw = {
path: '/error-log',
name: 'errorLog',
component: LAYOUT,
meta: {
title: 'ErrorLog',
hideBreadcrumb: true,
},
children: [
{
path: 'list',
name: 'errorLogList',
component: () => import('/@/views/sys/error-log/index.vue'),
meta: {
title: t('routes.basic.errorLogList'),
hideBreadcrumb: true,
},
},
],
};
...@@ -18,9 +18,8 @@ import { transformObjToRoute } from '/@/router/helper/routeHelper'; ...@@ -18,9 +18,8 @@ import { transformObjToRoute } from '/@/router/helper/routeHelper';
import { transformRouteToMenu } from '/@/router/helper/menuHelper'; import { transformRouteToMenu } from '/@/router/helper/menuHelper';
import { useMessage } from '/@/hooks/web/useMessage'; import { useMessage } from '/@/hooks/web/useMessage';
// import { warn } from '/@/utils/log';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/constant'; import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/constant';
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const NAME = 'permission'; const NAME = 'permission';
...@@ -121,6 +120,7 @@ class Permission extends VuexModule { ...@@ -121,6 +120,7 @@ class Permission extends VuexModule {
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
} }
routes.push(ERROR_LOG_ROUTE);
return routes; return routes;
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div :class="`${prefixCls}__link`"> <div :class="`${prefixCls}__link`">
<a><Icon icon="bx:bx-paper-plane" color="#1890ff" /><span>开始</span></a> <a><Icon icon="bx:bx-paper-plane" color="#1890ff" /><span>开始</span></a>
<a><Icon icon="carbon:warning" color="#1890ff" /><span>简介</span></a> <a><Icon icon="carbon:warning" color="#1890ff" /><span>简介</span></a>
<a><Icon icon="gg:loadbar-doc" color="#1890ff" /><span>文档</span></a> <a><Icon icon="ion:document-text-outline" color="#1890ff" /><span>文档</span></a>
</div> </div>
</template> </template>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册