feat: add error handle

This commit is contained in:
vben
2020-10-18 21:55:21 +08:00
parent c0692b0f43
commit 7101587b96
32 changed files with 674 additions and 116 deletions

View File

@@ -1,5 +1,5 @@
import { defineComponent, unref, computed } from 'vue';
import { Layout, Tooltip } from 'ant-design-vue';
import { Layout, Tooltip, Badge } from 'ant-design-vue';
import Logo from '/@/layouts/Logo.vue';
import UserDropdown from './UserDropdown';
import LayoutMenu from './LayoutMenu';
@@ -12,12 +12,15 @@ import {
FullscreenOutlined,
GithubFilled,
LockOutlined,
BugOutlined,
} from '@ant-design/icons-vue';
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
import { GITHUB_URL } from '/@/settings/siteSetting';
import LockAction from './actions/LockActionItem';
import { useModal } from '/@/components/Modal/index';
import { errorStore } from '/@/store/modules/error';
import { useGo } from '/@/hooks/web/usePage';
export default defineComponent({
name: 'DefaultLayoutHeader',
@@ -25,6 +28,7 @@ export default defineComponent({
const { refreshPage } = useTabs();
const [register, { openModal }] = useModal();
const { toggleFullscreen, isFullscreenRef } = useFullscreen();
const go = useGo();
const getProjectConfigRef = computed(() => {
return appStore.getProjectConfig;
});
@@ -37,6 +41,12 @@ export default defineComponent({
const theme = unref(getProjectConfigRef).headerSetting.theme;
return theme ? `layout-header__header--${theme}` : '';
});
function handleToErrorList() {
errorStore.commitErrorListCountState(0);
go('/exception/error-log');
}
/**
* @description: 锁定屏幕
*/
@@ -46,9 +56,9 @@ export default defineComponent({
return () => {
const getProjectConfig = unref(getProjectConfigRef);
const {
// useErrorHandle,
useErrorHandle,
showLogo,
headerSetting: { theme: headerTheme, showRedo, showGithub, showFullScreen },
headerSetting: { theme: headerTheme, useLockPage, showRedo, showGithub, showFullScreen },
menuSetting: { mode, type: menuType, split: splitMenu, topMenuAlign },
showBreadCrumb,
} = getProjectConfig;
@@ -77,8 +87,28 @@ export default defineComponent({
</div>
<div class={`layout-header__action`}>
{useErrorHandle && (
<Tooltip>
{{
title: () => '错误日志',
default: () => (
<Badge
count={errorStore.getErrorListCountState}
offset={[0, 10]}
overflowCount={99}
>
{() => (
<div class={`layout-header__action-item`} onClick={handleToErrorList}>
<BugOutlined class={`layout-header__action-icon`} />
</div>
)}
</Badge>
),
}}
</Tooltip>
)}
{showGithub && (
// @ts-ignore
<Tooltip>
{{
title: () => 'github',
@@ -90,8 +120,7 @@ export default defineComponent({
}}
</Tooltip>
)}
{showGithub && (
// @ts-ignore
{useLockPage && (
<Tooltip>
{{
title: () => '锁定屏幕',
@@ -104,7 +133,6 @@ export default defineComponent({
</Tooltip>
)}
{showRedo && (
// @ts-ignore
<Tooltip>
{{
title: () => '刷新',
@@ -117,7 +145,6 @@ export default defineComponent({
</Tooltip>
)}
{showFullScreen && (
// @ts-ignore
<Tooltip>
{{
title: () => (unref(isFullscreenRef) ? '退出全屏' : '全屏'),

View File

@@ -40,10 +40,11 @@ export default defineComponent({
let password: string | undefined = '';
try {
const values = (await validateFields()) as any;
password = values.password;
if (!valid) {
password = undefined;
} else {
const values = (await validateFields()) as any;
password = values.password;
}
setModalProps({
visible: false,

View File

@@ -0,0 +1,68 @@
import { defineComponent } from 'vue';
import { Popover, Tabs } from 'ant-design-vue';
import NoticeList from './NoticeList';
import { NoticeTabItem, NoticeListItem, noticeTabListData, noticeListData } from './data';
import './index.less';
const prefixCls = 'notice-popover';
export default defineComponent({
name: 'NoticePopover',
props: {
visible: {
type: Boolean,
default: false,
},
},
setup(props, { attrs }) {
// 渲染卡片内容
function renderContent() {
return (
<Tabs class={`${prefixCls}__tabs`}>
{() => {
return noticeTabListData.map((item: NoticeTabItem) => {
const { key, name } = item;
return (
<Tabs.TabPane key={key} tab={renderTab(key, name)}>
{() => <NoticeList list={getListData(key)} />}
</Tabs.TabPane>
);
});
}}
</Tabs>
);
}
// tab标题渲染
function renderTab(key: string, name: string) {
const list = getListData(key);
const unreadlist = list.filter((item: NoticeListItem) => !item.read);
return (
<div>
{name}
{unreadlist.length > 0 && <span>{unreadlist.length}</span>}
</div>
);
}
// 获取数据
function getListData(type: string) {
return noticeListData.filter((item: NoticeListItem) => item.type === type);
}
return () => {
const { visible } = props;
return (
<Popover
title=""
{...{
...attrs,
visible,
}}
content={renderContent}
class={prefixCls}
/>
);
};
},
});

View File

@@ -0,0 +1,73 @@
import { defineComponent } from 'vue';
import { List, Avatar, Tag } from 'ant-design-vue';
import { NoticeListItem } from './data';
import './index.less';
const prefixCls = 'notice-popover';
export default defineComponent({
name: 'NoticeList',
props: {
list: {
type: Array,
default: () => [],
},
},
setup(props) {
// 头像渲染
function renderAvatar(avatar: string) {
return avatar ? <Avatar class="avatar" src={avatar} /> : <span>{avatar}</span>;
}
// 描述渲染
function renderDescription(description: string, datetime: string) {
return (
<div>
<div class="description">{description}</div>
<div class="datetime">{datetime}</div>
</div>
);
}
// 标题渲染
function renderTitle(title: string, extra?: string, color?: string) {
return (
<div class="title">
{title}
{extra && (
<div class="extra">
<Tag class="tag" color={color}>
{() => extra}
</Tag>
</div>
)}
</div>
);
}
return () => {
const { list } = props;
return (
<List dataSource={list} class={`${prefixCls}__list`}>
{() => {
return list.map((item: NoticeListItem) => {
const { id, avatar, title, description, datetime, extra, read, color } = item;
return (
<List.Item key={id} class={`${prefixCls}__list-item ${read ? 'read' : ''}`}>
{() => (
<List.Item.Meta
class="meta"
avatar={renderAvatar(avatar)}
title={renderTitle(title, extra, color)}
description={renderDescription(description, datetime)}
/>
)}
</List.Item>
);
});
}}
</List>
);
};
},
});

View File

@@ -102,12 +102,12 @@
.setting-button {
top: 45%;
right: 0;
padding: 14px;
padding: 8px;
border-radius: 6px 0 0 6px;
svg {
width: 1.2em;
height: 1.2em;
width: 1em;
height: 1em;
}
}

View File

@@ -30,7 +30,7 @@
position: absolute;
z-index: 10;
display: flex;
padding: 10px;
// padding: 10px;
color: @white;
cursor: pointer;
background: @primary-color;

View File

@@ -54,6 +54,7 @@ export default defineComponent({
{...on}
name={name || route.meta.transitionName || routerTransition}
mode="out-in"
appear={true}
>
{() => Content}
</Transition>