feat: sport notification link

This commit is contained in:
shixi 2025-11-12 00:55:24 +08:00
parent dbc5ea32ae
commit 0bbb20fee0
6 changed files with 121 additions and 1 deletions

View File

@ -54,6 +54,24 @@ const notifications = ref<NotificationItem[]>([
message: '描述信息描述信息描述信息', message: '描述信息描述信息描述信息',
title: '代办提醒', title: '代办提醒',
}, },
{
id: 5,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转Workspace示例',
link: '/workspace',
},
{
id: 6,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转外部链接示例',
link: 'https://doc.vben.pro',
},
]); ]);
const userStore = useUserStore(); const userStore = useUserStore();

View File

@ -54,6 +54,24 @@ const notifications = ref<NotificationItem[]>([
message: '描述信息描述信息描述信息', message: '描述信息描述信息描述信息',
title: '代办提醒', title: '代办提醒',
}, },
{
id: 5,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转Workspace示例',
link: '/workspace',
},
{
id: 6,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转外部链接示例',
link: 'https://doc.vben.pro',
},
]); ]);
const userStore = useUserStore(); const userStore = useUserStore();

View File

@ -54,6 +54,24 @@ const notifications = ref<NotificationItem[]>([
message: '描述信息描述信息描述信息', message: '描述信息描述信息描述信息',
title: '代办提醒', title: '代办提醒',
}, },
{
id: 5,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转Workspace示例',
link: '/workspace',
},
{
id: 6,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转外部链接示例',
link: 'https://doc.vben.pro',
},
]); ]);
const userStore = useUserStore(); const userStore = useUserStore();

View File

@ -1,6 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { NotificationItem } from './types'; import type { NotificationItem } from './types';
import { useRouter } from 'vue-router';
import { Bell, CircleCheckBig, CircleX, MailCheck } from '@vben/icons'; import { Bell, CircleCheckBig, CircleX, MailCheck } from '@vben/icons';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
@ -39,6 +41,7 @@ const emit = defineEmits<{
viewAll: []; viewAll: [];
}>(); }>();
const router = useRouter();
const [open, toggle] = useToggle(); const [open, toggle] = useToggle();
function close() { function close() {
@ -59,7 +62,28 @@ function handleClear() {
} }
function handleClick(item: NotificationItem) { function handleClick(item: NotificationItem) {
emit('read', item); //
if (item.link) {
navigateTo(item.link, item.query, item.state);
}
}
function navigateTo(
link: string,
query?: Record<string, any>,
state?: Record<string, any>,
) {
if (link.startsWith('http://') || link.startsWith('https://')) {
//
window.open(link, '_blank');
} else {
// query state
router.push({
path: link,
query: query || {},
state,
});
}
} }
</script> </script>
<template> <template>

View File

@ -5,6 +5,13 @@ interface NotificationItem {
isRead?: boolean; isRead?: boolean;
message: string; message: string;
title: string; title: string;
/**
* URL
* @example '/dashboard' 'https://example.com'
*/
link?: string;
query?: Record<string, any>;
state?: Record<string, any>;
} }
export type { NotificationItem }; export type { NotificationItem };

View File

@ -36,6 +36,7 @@ setMenuList([
const notifications = ref<NotificationItem[]>([ const notifications = ref<NotificationItem[]>([
{ {
id: 1,
avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB', avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB',
date: '3小时前', date: '3小时前',
isRead: true, isRead: true,
@ -43,6 +44,7 @@ const notifications = ref<NotificationItem[]>([
title: '收到了 14 份新周报', title: '收到了 14 份新周报',
}, },
{ {
id: 2,
avatar: 'https://avatar.vercel.sh/1', avatar: 'https://avatar.vercel.sh/1',
date: '刚刚', date: '刚刚',
isRead: false, isRead: false,
@ -50,6 +52,7 @@ const notifications = ref<NotificationItem[]>([
title: '朱偏右 回复了你', title: '朱偏右 回复了你',
}, },
{ {
id: 3,
avatar: 'https://avatar.vercel.sh/1', avatar: 'https://avatar.vercel.sh/1',
date: '2024-01-01', date: '2024-01-01',
isRead: false, isRead: false,
@ -57,12 +60,31 @@ const notifications = ref<NotificationItem[]>([
title: '曲丽丽 评论了你', title: '曲丽丽 评论了你',
}, },
{ {
id: 4,
avatar: 'https://avatar.vercel.sh/satori', avatar: 'https://avatar.vercel.sh/satori',
date: '1天前', date: '1天前',
isRead: false, isRead: false,
message: '描述信息描述信息描述信息', message: '描述信息描述信息描述信息',
title: '代办提醒', title: '代办提醒',
}, },
{
id: 5,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转Workspace示例',
link: '/workspace',
},
{
id: 6,
avatar: 'https://avatar.vercel.sh/satori',
date: '1天前',
isRead: false,
message: '描述信息描述信息描述信息',
title: '跳转外部链接示例',
link: 'https://doc.vben.pro',
},
]); ]);
const userStore = useUserStore(); const userStore = useUserStore();
@ -115,6 +137,17 @@ function handleNoticeClear() {
notifications.value = []; notifications.value = [];
} }
function markRead(id: number | string) {
const item = notifications.value.find((item) => item.id === id);
if (item) {
item.isRead = true;
}
}
function remove(id: number | string) {
notifications.value = notifications.value.filter((item) => item.id !== id);
}
function handleMakeAll() { function handleMakeAll() {
notifications.value.forEach((item) => (item.isRead = true)); notifications.value.forEach((item) => (item.isRead = true));
} }
@ -170,6 +203,8 @@ onBeforeMount(() => {
:dot="showDot" :dot="showDot"
:notifications="notifications" :notifications="notifications"
@clear="handleNoticeClear" @clear="handleNoticeClear"
@read="(item) => item.id && markRead(item.id)"
@remove="(item) => item.id && remove(item.id)"
@make-all="handleMakeAll" @make-all="handleMakeAll"
/> />
</template> </template>