mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-01-24 02:00:25 +08:00
chore: fix the error-log list as the system route
This commit is contained in:
parent
1f96eaef99
commit
b335e7511b
@ -11,7 +11,7 @@
|
||||
:overlayClassName="`${prefixCls}-overlay`"
|
||||
>
|
||||
<span :class="prefixCls">
|
||||
<Icon icon="cil:language" />
|
||||
<Icon icon="ion:language" />
|
||||
<span v-if="showText" :class="`${prefixCls}__text`">{{ getLangText }}</span>
|
||||
</span>
|
||||
</Dropdown>
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppSearch',
|
||||
components: { AppSearchModal, Tooltip, SearchOutlined },
|
||||
components: { AppSearchModal, Tooltip },
|
||||
setup() {
|
||||
const showModal = ref(false);
|
||||
const { prefixCls } = useDesign('app-search');
|
||||
|
@ -6,5 +6,5 @@ export enum PageEnum {
|
||||
// error page path
|
||||
ERROR_PAGE = '/exception',
|
||||
// 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'))
|
||||
|
||||
export const Notify = createAsyncComponent(() => import('./notify/index.vue'));
|
||||
|
||||
export const LockItem = createAsyncComponent(() => import('./lock/index.vue'));
|
||||
|
||||
export const ErrorAction = createAsyncComponent(() => import('./ErrorAction.vue'));
|
||||
|
@ -1,30 +0,0 @@
|
||||
.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;
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
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>
|
||||
);
|
||||
},
|
||||
});
|
@ -1,38 +0,0 @@
|
||||
<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 @@
|
||||
<MenuItem
|
||||
key="doc"
|
||||
:text="t('layout.header.dropdownItemDoc')"
|
||||
icon="gg:loadbar-doc"
|
||||
icon="ion:document-text-outline"
|
||||
v-if="getShowDoc"
|
||||
/>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
key="lock"
|
||||
:text="t('layout.header.tooltipLock')"
|
||||
icon="ion:lock-closed-outline"
|
||||
/>
|
||||
<MenuItem
|
||||
key="loginOut"
|
||||
:text="t('layout.header.dropdownItemLoginOut')"
|
||||
icon="carbon:power"
|
||||
icon="ion:exit-outline"
|
||||
/>
|
||||
</Menu>
|
||||
</template>
|
||||
</Dropdown>
|
||||
<LockAction @register="register" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// components
|
||||
@ -31,23 +37,21 @@
|
||||
|
||||
import { defineComponent, computed } from 'vue';
|
||||
|
||||
// res
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
|
||||
import { DOC_URL } from '/@/settings/siteSetting';
|
||||
|
||||
import { openWindow } from '/@/utils';
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import headerImg from '/@/assets/images/header.jpg';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
|
||||
type MenuEvent = 'loginOut' | 'doc';
|
||||
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' | 'lock';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'UserDropdown',
|
||||
@ -56,6 +60,7 @@
|
||||
Menu,
|
||||
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
|
||||
MenuDivider: Menu.Divider,
|
||||
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
||||
},
|
||||
props: {
|
||||
theme: propTypes.oneOf(['dark', 'light']),
|
||||
@ -70,6 +75,12 @@
|
||||
return { realName, desc };
|
||||
});
|
||||
|
||||
const [register, { openModal }] = useModal();
|
||||
|
||||
function handleLock() {
|
||||
openModal(true);
|
||||
}
|
||||
|
||||
// login out
|
||||
function handleLoginOut() {
|
||||
userStore.confirmLoginOut();
|
||||
@ -88,6 +99,9 @@
|
||||
case 'doc':
|
||||
openDoc();
|
||||
break;
|
||||
case 'lock':
|
||||
handleLock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,6 +112,7 @@
|
||||
handleMenuClick,
|
||||
getShowDoc,
|
||||
headerImg,
|
||||
register,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -37,8 +37,6 @@
|
||||
|
||||
<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`" />
|
||||
|
||||
<FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" />
|
||||
@ -61,7 +59,7 @@
|
||||
|
||||
import { Layout } from 'ant-design-vue';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import LayoutMenu from '../menu';
|
||||
import LayoutMenu from '../menu/index.vue';
|
||||
import LayoutTrigger from '../trigger/index.vue';
|
||||
|
||||
import { AppSearch } from '/@/components/Application';
|
||||
@ -74,14 +72,7 @@
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { AppLocalePicker } from '/@/components/Application';
|
||||
|
||||
import {
|
||||
UserDropDown,
|
||||
LayoutBreadcrumb,
|
||||
FullScreen,
|
||||
Notify,
|
||||
LockItem,
|
||||
ErrorAction,
|
||||
} from './components';
|
||||
import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction } from './components';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
@ -97,7 +88,6 @@
|
||||
AppLocalePicker,
|
||||
FullScreen,
|
||||
Notify,
|
||||
LockItem,
|
||||
AppSearch,
|
||||
ErrorAction,
|
||||
},
|
||||
|
@ -1,22 +0,0 @@
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
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()
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
196
src/layouts/default/menu/index.vue
Normal file
196
src/layouts/default/menu/index.vue
Normal file
@ -0,0 +1,196 @@
|
||||
<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>
|
@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div @click="openDrawer" :class="prefixCls">
|
||||
<SettingOutlined />
|
||||
<Icon icon="ion:settings-outline" />
|
||||
<SettingDrawer @register="register" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { SettingOutlined } from '@ant-design/icons-vue';
|
||||
import SettingDrawer from './SettingDrawer';
|
||||
import Icon from '/@/components/Icon';
|
||||
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SettingButton',
|
||||
components: { SettingOutlined, SettingDrawer },
|
||||
components: { SettingDrawer, Icon },
|
||||
setup() {
|
||||
const [register, { openDrawer }] = useDrawer();
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
import { computed, defineComponent, ref, unref, CSSProperties } from '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 { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
|
@ -17,8 +17,9 @@
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import Sider from './LayoutSider.vue';
|
||||
import { Drawer } from 'ant-design-vue';
|
||||
import MixSider from './MixSider.vue';
|
||||
import { Drawer } from 'ant-design-vue';
|
||||
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
|
||||
<span :class="`${prefixCls}__extra-quick`" v-else @click="handleContext">
|
||||
<RightOutlined />
|
||||
<Icon icon="ion:chevron-down"></Icon>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</template>
|
||||
@ -14,6 +14,7 @@
|
||||
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { Dropdown } from '/@/components/Dropdown/index';
|
||||
import Icon from '/@/components/Icon';
|
||||
|
||||
import { TabContentProps, TabContentEnum } from '../types';
|
||||
|
||||
@ -26,7 +27,7 @@
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
export default defineComponent({
|
||||
name: 'TabContent',
|
||||
components: { Dropdown, RightOutlined },
|
||||
components: { Dropdown, RightOutlined, Icon },
|
||||
props: {
|
||||
tabItem: {
|
||||
type: Object as PropType<RouteLocationNormalized>,
|
||||
|
@ -1,3 +1,4 @@
|
||||
export default {
|
||||
login: 'Login',
|
||||
errorLogList: 'Error Log',
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
export default {
|
||||
login: '登录',
|
||||
errorLogList: '错误日志列表',
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import type { AppRouteRecordRaw } from '/@/router/types';
|
||||
import ParentLayout from '/@/layouts/page/ParentView.vue';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const EXCEPTION_COMPONENT = () => import('../views/sys/exception/Exception.vue');
|
||||
|
||||
@ -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';
|
||||
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
|
||||
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
// import { warn } from '/@/utils/log';
|
||||
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 NAME = 'permission';
|
||||
@ -121,6 +120,7 @@ class Permission extends VuexModule {
|
||||
|
||||
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
|
||||
}
|
||||
routes.push(ERROR_LOG_ROUTE);
|
||||
return routes;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div :class="`${prefixCls}__link`">
|
||||
<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="gg:loadbar-doc" color="#1890ff" /><span>文档</span></a>
|
||||
<a><Icon icon="ion:document-text-outline" color="#1890ff" /><span>文档</span></a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user