11 changed files with 220 additions and 85 deletions
@ -1,80 +1,35 @@
|
||||
<template> |
||||
<div :class="prefixCls"> |
||||
<Popover title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`"> |
||||
<Badge :count="count" dot :numberStyle="numberStyle"> |
||||
<div> |
||||
<Tooltip :title="tips"> |
||||
<Badge :count="unreadCount" :offset="[0, 15]" size="small" @click="go({ path: PageEnum.MESSAGE_PAGE })"> |
||||
<BellOutlined /> |
||||
</Badge> |
||||
<template #content> |
||||
<Tabs> |
||||
<template v-for="item in listData" :key="item.key"> |
||||
<TabPane> |
||||
<template #tab> |
||||
{{ item.name }} |
||||
<span v-if="item.list.length !== 0">({{ item.list.length }})</span> |
||||
</template> |
||||
<!-- 绑定title-click事件的通知列表中标题是“可点击”的--> |
||||
<NoticeList :list="item.list" v-if="item.key === '1'" @title-click="onNoticeClick" /> |
||||
<NoticeList :list="item.list" v-else /> |
||||
</TabPane> |
||||
</template> |
||||
</Tabs> |
||||
</template> |
||||
</Popover> |
||||
</Tooltip> |
||||
</div> |
||||
</template> |
||||
<script lang="ts" setup> |
||||
import { computed, ref } from 'vue' |
||||
import { Popover, Tabs, Badge } from 'ant-design-vue' |
||||
import { onMounted, computed } from 'vue' |
||||
import { Badge, Tooltip } from 'ant-design-vue' |
||||
import { BellOutlined } from '@ant-design/icons-vue' |
||||
import { tabListData, ListItem } from './data' |
||||
import NoticeList from './NoticeList.vue' |
||||
import { useDesign } from '@/hooks/web/useDesign' |
||||
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
||||
const TabPane = Tabs.TabPane |
||||
const numberStyle = ref({}) |
||||
const { prefixCls } = useDesign('header-notify') |
||||
const { createMessage } = useMessage() |
||||
const listData = ref(tabListData) |
||||
|
||||
const count = computed(() => { |
||||
let count = 0 |
||||
for (let i = 0; i < tabListData.length; i++) { |
||||
count += tabListData[i].list.length |
||||
import { useGo } from '@/hooks/web/usePage' |
||||
import { PageEnum } from '@/enums/pageEnum' |
||||
import { useUserMessageStore } from '@/store/modules/userMessage' |
||||
import { storeToRefs } from 'pinia' |
||||
|
||||
const go = useGo() |
||||
|
||||
const store = useUserMessageStore() |
||||
const { unreadCount } = storeToRefs(store) |
||||
const tips = computed<string>(() => { |
||||
if (unreadCount.value === 0) { |
||||
return '查看站内信' |
||||
} |
||||
return count |
||||
return `查看站内信: 未读 ${unreadCount.value} 条` |
||||
}) |
||||
|
||||
function onNoticeClick(record: ListItem) { |
||||
createMessage.success('你点击了通知,ID=' + record.id) |
||||
// 可以直接将其标记为已读(为标题添加删除线),此处演示的代码会切换删除线状态 |
||||
record.titleDelete = !record.titleDelete |
||||
} |
||||
onMounted(async () => { |
||||
// 通过store进行更新 |
||||
store.updateUnreadCount() |
||||
}) |
||||
</script> |
||||
<style lang="less"> |
||||
@prefix-cls: ~'@{namespace}-header-notify'; |
||||
|
||||
.@{prefix-cls} { |
||||
padding-top: 2px; |
||||
|
||||
&__overlay { |
||||
max-width: 360px; |
||||
} |
||||
|
||||
.ant-tabs-content { |
||||
width: 300px; |
||||
} |
||||
|
||||
.ant-badge { |
||||
font-size: 18px; |
||||
|
||||
.ant-badge-multiple-words { |
||||
padding: 0 4px; |
||||
} |
||||
|
||||
svg { |
||||
width: 0.9em; |
||||
} |
||||
} |
||||
} |
||||
</style> |
||||
<style lang="less"></style> |
||||
|
@ -0,0 +1,24 @@
|
||||
import { defineStore } from 'pinia' |
||||
import { getUnreadNotifyMessageCount } from '@/api/system/notify/message' |
||||
|
||||
type MessageState = { |
||||
unreadCount: number // 未读消息数量
|
||||
} |
||||
|
||||
export const useUserMessageStore = defineStore('userMessage', { |
||||
state: (): MessageState => ({ |
||||
unreadCount: 0 |
||||
}), |
||||
getters: { |
||||
getUnreadCount(state) { |
||||
return state.unreadCount |
||||
} |
||||
}, |
||||
actions: { |
||||
// 更新未读消息的数量
|
||||
async updateUnreadCount() { |
||||
const count = await getUnreadNotifyMessageCount() |
||||
this.unreadCount = count |
||||
} |
||||
} |
||||
}) |
@ -1,5 +1,5 @@
|
||||
<template> |
||||
<BasicModal title="详情" @register="innerRegister"> |
||||
<BasicModal title="站内信详情" @register="innerRegister"> |
||||
<Description @register="descriptionRegister" /> |
||||
</BasicModal> |
||||
</template> |
@ -0,0 +1,97 @@
|
||||
import { useRender } from '@/components/Table' |
||||
import { DICT_TYPE } from '@/utils/dict' |
||||
import { JsonPreview } from '@/components/CodeEditor' |
||||
import { DescItem } from '@/components/Description/index' |
||||
import { h } from 'vue' |
||||
|
||||
// 站内信详情modal
|
||||
export const infoSchema: DescItem[] = [ |
||||
{ |
||||
field: 'id', |
||||
label: '编号', |
||||
labelMinWidth: 50 |
||||
}, |
||||
{ |
||||
field: 'readStatus', |
||||
label: '是否已读', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.INFRA_BOOLEAN_STRING) |
||||
} |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户类型', |
||||
render: (value) => { |
||||
console.log(value) |
||||
return useRender.renderDict(value, DICT_TYPE.USER_TYPE) |
||||
} |
||||
}, |
||||
{ |
||||
field: 'userType', |
||||
label: '用户编号' |
||||
}, |
||||
{ |
||||
field: 'templateId', |
||||
label: '模板编号' |
||||
}, |
||||
{ |
||||
field: 'templateCode', |
||||
label: '模板编码' |
||||
}, |
||||
{ |
||||
field: 'templateNickname', |
||||
label: '发送人名称' |
||||
}, |
||||
{ |
||||
field: 'templateContent', |
||||
label: '模板内容' |
||||
}, |
||||
{ |
||||
field: 'templateParams', |
||||
label: '模板参数', |
||||
render: (value) => { |
||||
return h(JsonPreview, { data: value }) |
||||
} |
||||
}, |
||||
{ |
||||
field: 'templateType', |
||||
label: '模板类型', |
||||
render: (value) => { |
||||
return useRender.renderDict(value, DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE) |
||||
} |
||||
}, |
||||
{ |
||||
field: 'readTime', |
||||
label: '阅读时间', |
||||
render: (value) => { |
||||
if (!value) { |
||||
return useRender.renderTag('未阅读') |
||||
} |
||||
return useRender.renderDate(value) |
||||
} |
||||
}, |
||||
{ |
||||
field: 'createTime', |
||||
label: '创建时间', |
||||
render: (value) => { |
||||
return useRender.renderDate(value) |
||||
} |
||||
} |
||||
] |
||||
|
||||
// 站内信详情
|
||||
export interface MessageInfo { |
||||
userId: number |
||||
userType: number |
||||
templateId: number |
||||
templateCode: string |
||||
templateNickname: string |
||||
templateContent: string |
||||
templateType: number |
||||
templateParams: { [key: string]: string } |
||||
readStatus: boolean |
||||
readTime?: any |
||||
id: number |
||||
createTime: number |
||||
key: string |
||||
} |
Reference in new issue