Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-vue-admin
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-vue-admin
Commits
7a1e94c4
提交
7a1e94c4
authored
10月 21, 2020
作者:
chen-xt
提交者:
GitHub
10月 21, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add notice (#47)
上级
463aeabd
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
341 行增加
和
142 行删除
+341
-142
LayoutHeader.tsx
src/layouts/default/LayoutHeader.tsx
+23
-1
NoticeActionItem.tsx
src/layouts/default/actions/notice/NoticeActionItem.tsx
+0
-68
NoticeActionItem.vue
src/layouts/default/actions/notice/NoticeActionItem.vue
+64
-0
NoticeList.tsx
src/layouts/default/actions/notice/NoticeList.tsx
+0
-73
NoticeList.vue
src/layouts/default/actions/notice/NoticeList.vue
+102
-0
data.ts
src/layouts/default/actions/notice/data.ts
+148
-0
projectSetting.ts
src/settings/projectSetting.ts
+2
-0
config.d.ts
src/types/config.d.ts
+2
-0
没有找到文件。
src/layouts/default/LayoutHeader.tsx
浏览文件 @
7a1e94c4
...
...
@@ -22,6 +22,7 @@ import { useModal } from '/@/components/Modal/index';
import
{
errorStore
}
from
'/@/store/modules/error'
;
import
{
useGo
}
from
'/@/hooks/web/usePage'
;
import
{
useWindowSizeFn
}
from
'/@/hooks/event/useWindowSize'
;
import
NoticeAction
from
'./actions/notice/NoticeActionItem.vue'
;
export
default
defineComponent
({
name
:
'DefaultLayoutHeader'
,
...
...
@@ -85,7 +86,14 @@ export default defineComponent({
const
{
useErrorHandle
,
showLogo
,
headerSetting
:
{
theme
:
headerTheme
,
useLockPage
,
showRedo
,
showGithub
,
showFullScreen
},
headerSetting
:
{
theme
:
headerTheme
,
useLockPage
,
showRedo
,
showGithub
,
showFullScreen
,
showNotice
,
},
menuSetting
:
{
mode
,
type
:
menuType
,
split
:
splitMenu
,
topMenuAlign
},
showBreadCrumb
,
}
=
getProjectConfig
;
...
...
@@ -163,6 +171,20 @@ export default defineComponent({
}
}
</
Tooltip
>
)
}
{
showNotice
&&
(
<
div
>
<
Tooltip
>
{
{
title
:
()
=>
'消息中心'
,
default
:
()
=>
(
<
div
class=
{
`layout-header__action-item`
}
>
<
NoticeAction
/>
</
div
>
),
}
}
</
Tooltip
>
</
div
>
)
}
{
showRedo
&&
(
<
Tooltip
>
{
{
...
...
src/layouts/default/actions/notice/NoticeActionItem.tsx
deleted
100644 → 0
浏览文件 @
463aeabd
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
}
/>
);
};
},
});
src/layouts/default/actions/notice/NoticeActionItem.vue
0 → 100644
浏览文件 @
7a1e94c4
<
template
>
<div>
<Popover
title=
""
trigger=
"click"
>
<Badge
:count=
"count"
:numberStyle=
"numberStyle"
>
<BellOutlined
class=
"layout-header__action-icon"
/>
</Badge>
<template
#
content
>
<Tabs>
<template
v-for=
"item in tabListData"
:key=
"item.key"
>
<TabPane>
<template
#
tab
>
{{
item
.
name
}}
<span
v-if=
"item.list.length !== 0"
>
(
{{
item
.
list
.
length
}}
)
</span>
</
template
>
<NoticeList
:list=
"item.list"
/>
</TabPane>
</template>
</Tabs>
</template>
</Popover>
</div>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
;
import
{
Popover
,
Tabs
,
Badge
}
from
'ant-design-vue'
;
import
{
BellOutlined
}
from
'@ant-design/icons-vue'
;
import
{
tabListData
}
from
'./data'
;
import
NoticeList
from
'./NoticeList.vue'
;
export
default
defineComponent
({
components
:
{
Popover
,
BellOutlined
,
Tabs
,
TabPane
:
Tabs
.
TabPane
,
Badge
,
NoticeList
},
setup
()
{
let
count
=
0
;
for
(
let
i
=
0
;
i
<
tabListData
.
length
;
i
++
)
{
count
+=
tabListData
[
i
].
list
.
length
;
}
return
{
tabListData
,
count
,
numberStyle
:
{},
};
},
});
</
script
>
<
style
lang=
"less"
scoped
>
/
deep
/
.ant-tabs-tab
{
padding-top
:
8px
;
margin-right
:
12px
;
}
/
deep
/
.ant-tabs-content
{
width
:
300px
;
}
/
deep
/
.ant-badge
{
font-size
:
18px
;
.ant-badge-multiple-words
{
padding
:
0
4px
;
transform
:
translate
(
26%
,
-48%
);
}
}
</
style
>
src/layouts/default/actions/notice/NoticeList.tsx
deleted
100644 → 0
浏览文件 @
463aeabd
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
>
);
};
},
});
src/layouts/default/actions/notice/NoticeList.vue
0 → 100644
浏览文件 @
7a1e94c4
<
template
>
<List
class=
"list"
>
<template
v-for=
"item in list"
:key=
"item.id"
>
<ListItem
class=
"list__item"
>
<ListItemMeta>
<template
#
title
>
<div
class=
"title"
>
{{
item
.
title
}}
<div
class=
"extra"
v-if=
"item.extra"
>
<Tag
class=
"tag"
:color=
"item.color"
>
{{
item
.
extra
}}
</Tag>
</div>
</div>
</
template
>
<
template
#
avatar
>
<Avatar
v-if=
"item.avatar"
class=
"avatar"
:src=
"item.avatar"
/>
<span
v-else
>
{{
item
.
avatar
}}
</span>
</
template
>
<
template
#
description
>
<div>
<div
class=
"description"
>
{{
item
.
description
}}
</div>
<div
class=
"datetime"
>
{{
item
.
datetime
}}
</div>
</div>
</
template
>
</ListItemMeta>
</ListItem>
</template>
</List>
</template>
<
script
lang=
"ts"
>
import
{
defineComponent
,
PropType
}
from
'vue'
;
import
{
List
,
Avatar
,
Tag
}
from
'ant-design-vue'
;
import
{
ListItem
}
from
'./data'
;
export
default
defineComponent
({
props
:
{
list
:
{
type
:
Array
as
PropType
<
Array
<
ListItem
>>
,
default
:
()
=>
[],
},
},
components
:
{
List
,
ListItem
:
List
.
Item
,
ListItemMeta
:
List
.
Item
.
Meta
,
Avatar
,
Tag
,
},
setup
(
props
)
{
const
{
list
=
[]
}
=
props
;
return
{
list
,
};
},
});
</
script
>
<
style
lang=
"less"
scoped
>
.list
{
&::-webkit-scrollbar
{
display
:
none
;
}
&
__item
{
padding
:
6px
;
overflow
:
hidden
;
cursor
:
pointer
;
transition
:
all
0.3s
;
.title
{
margin-bottom
:
8px
;
font-weight
:
normal
;
.extra
{
float
:
right
;
margin-top
:
-1.5px
;
margin-right
:
0
;
font-weight
:
normal
;
.tag
{
margin-right
:
0
;
}
}
.avatar
{
margin-top
:
4px
;
}
.description
{
font-size
:
12px
;
line-height
:
18px
;
}
.datetime
{
margin-top
:
4px
;
font-size
:
12px
;
line-height
:
18px
;
}
}
}
}
</
style
>
src/layouts/default/actions/notice/data.ts
0 → 100644
浏览文件 @
7a1e94c4
export
interface
ListItem
{
id
:
string
;
avatar
:
string
;
title
:
string
;
datetime
:
string
;
type
:
string
;
read
?:
boolean
;
description
:
string
;
clickClose
?:
boolean
;
extra
?:
string
;
color
?:
string
;
}
export
interface
TabItem
{
key
:
string
;
name
:
string
;
list
:
ListItem
[];
unreadlist
?:
ListItem
[];
}
export
const
tabListData
:
TabItem
[]
=
[
{
key
:
'1'
,
name
:
'通知'
,
list
:
[
{
id
:
'000000001'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png'
,
title
:
'你收到了 14 份新周报'
,
description
:
''
,
datetime
:
'2017-08-09'
,
type
:
'1'
,
},
{
id
:
'000000002'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png'
,
title
:
'你推荐的 曲妮妮 已通过第三轮面试'
,
description
:
''
,
datetime
:
'2017-08-08'
,
type
:
'1'
,
},
{
id
:
'000000003'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png'
,
title
:
'这种模板可以区分多种通知类型'
,
description
:
''
,
datetime
:
'2017-08-07'
,
// read: true,
type
:
'1'
,
},
{
id
:
'000000004'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png'
,
title
:
'左侧图标用于区分不同的类型'
,
description
:
''
,
datetime
:
'2017-08-07'
,
type
:
'1'
,
},
// {
// id: '000000005',
// avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
// title: '内容不要超过两行字,超出时自动截断',
// description: '',
// datetime: '2017-08-07',
// type: '1',
// },
],
},
{
key
:
'2'
,
name
:
'消息'
,
list
:
[
{
id
:
'000000006'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg'
,
title
:
'曲丽丽 评论了你'
,
description
:
'描述信息描述信息描述信息'
,
datetime
:
'2017-08-07'
,
type
:
'2'
,
clickClose
:
true
,
},
{
id
:
'000000007'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg'
,
title
:
'朱偏右 回复了你'
,
description
:
'这种模板用于提醒谁与你发生了互动'
,
datetime
:
'2017-08-07'
,
type
:
'2'
,
clickClose
:
true
,
},
{
id
:
'000000008'
,
avatar
:
'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg'
,
title
:
'标题'
,
description
:
'这种模板用于提醒谁与你发生了互动'
,
datetime
:
'2017-08-07'
,
type
:
'2'
,
clickClose
:
true
,
},
],
},
{
key
:
'3'
,
name
:
'待办'
,
list
:
[
{
id
:
'000000009'
,
avatar
:
''
,
title
:
'任务名称'
,
description
:
'任务需要在 2017-01-12 20:00 前启动'
,
datetime
:
''
,
extra
:
'未开始'
,
color
:
''
,
type
:
'3'
,
},
{
id
:
'000000010'
,
avatar
:
''
,
title
:
'第三方紧急代码变更'
,
description
:
'冠霖 需在 2017-01-07 前完成代码变更任务'
,
datetime
:
''
,
extra
:
'马上到期'
,
color
:
'red'
,
type
:
'3'
,
},
{
id
:
'000000011'
,
avatar
:
''
,
title
:
'信息安全考试'
,
description
:
'指派竹尔于 2017-01-09 前完成更新并发布'
,
datetime
:
''
,
extra
:
'已耗时 8 天'
,
color
:
'gold'
,
type
:
'3'
,
},
{
id
:
'000000012'
,
avatar
:
''
,
title
:
'ABCD 版本发布'
,
description
:
'指派竹尔于 2017-01-09 前完成更新并发布'
,
datetime
:
''
,
extra
:
'进行中'
,
color
:
'blue'
,
type
:
'3'
,
},
],
},
];
src/settings/projectSetting.ts
浏览文件 @
7a1e94c4
...
...
@@ -39,6 +39,8 @@ const setting: ProjectConfig = {
showDoc
:
true
,
// 是否显示github
showGithub
:
true
,
// 显示消息中心按钮
showNotice
:
true
,
},
// 菜单配置
menuSetting
:
{
...
...
src/types/config.d.ts
浏览文件 @
7a1e94c4
...
...
@@ -47,6 +47,8 @@ export interface HeaderSetting {
// 显示文档按钮
showDoc
:
boolean
;
showGithub
:
boolean
;
// 显示消息中心按钮
showNotice
:
boolean
;
}
export
interface
ProjectConfig
{
// 是否显示配置按钮
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论