mirror of
https://github.com/imdap/ruoyi-plus-vben5.git
synced 2026-04-23 00:38:34 +08:00
feat: 通知模块自定义加强
This commit is contained in:
@@ -147,6 +147,34 @@ function remove(id: number | string) {
|
|||||||
function handleMakeAll() {
|
function handleMakeAll() {
|
||||||
notifications.value.forEach((item) => (item.isRead = true));
|
notifications.value.forEach((item) => (item.isRead = true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -189,6 +217,8 @@ watch(
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
@@ -147,6 +147,34 @@ function remove(id: number | string) {
|
|||||||
function handleMakeAll() {
|
function handleMakeAll() {
|
||||||
notifications.value.forEach((item) => (item.isRead = true));
|
notifications.value.forEach((item) => (item.isRead = true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -189,6 +217,8 @@ watch(
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
@@ -147,6 +147,34 @@ function remove(id: number | string) {
|
|||||||
function handleMakeAll() {
|
function handleMakeAll() {
|
||||||
notifications.value.forEach((item) => (item.isRead = true));
|
notifications.value.forEach((item) => (item.isRead = true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -189,6 +217,8 @@ watch(
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
@@ -148,6 +148,33 @@ function handleMakeAll() {
|
|||||||
notifications.value.forEach((item) => (item.isRead = true));
|
notifications.value.forEach((item) => (item.isRead = true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -190,6 +217,8 @@ watch(
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
@@ -147,6 +147,34 @@ function remove(id: number | string) {
|
|||||||
function handleMakeAll() {
|
function handleMakeAll() {
|
||||||
notifications.value.forEach((item) => (item.isRead = true));
|
notifications.value.forEach((item) => (item.isRead = true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -189,6 +217,8 @@ watch(
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export {
|
|||||||
CircleX,
|
CircleX,
|
||||||
Copy,
|
Copy,
|
||||||
CornerDownLeft,
|
CornerDownLeft,
|
||||||
|
Download,
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
Eraser,
|
Eraser,
|
||||||
Expand,
|
Expand,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export {
|
|||||||
VbenContextMenu,
|
VbenContextMenu,
|
||||||
VbenCountToAnimator,
|
VbenCountToAnimator,
|
||||||
VbenFullScreen,
|
VbenFullScreen,
|
||||||
|
VbenIconButton,
|
||||||
VbenInputPassword,
|
VbenInputPassword,
|
||||||
VbenLoading,
|
VbenLoading,
|
||||||
VbenLogo,
|
VbenLogo,
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<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';
|
||||||
|
|
||||||
@@ -15,76 +13,48 @@ import {
|
|||||||
|
|
||||||
import { useToggle } from '@vueuse/core';
|
import { useToggle } from '@vueuse/core';
|
||||||
|
|
||||||
interface Props {
|
|
||||||
/**
|
|
||||||
* 显示圆点
|
|
||||||
*/
|
|
||||||
dot?: boolean;
|
|
||||||
/**
|
|
||||||
* 消息列表
|
|
||||||
*/
|
|
||||||
notifications?: NotificationItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
defineOptions({ name: 'NotificationPopup' });
|
defineOptions({ name: 'NotificationPopup' });
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {
|
withDefaults(
|
||||||
dot: false,
|
defineProps<{
|
||||||
notifications: () => [],
|
/** 显示圆点 */
|
||||||
});
|
dot?: boolean;
|
||||||
|
/** 消息列表 */
|
||||||
|
notifications?: NotificationItem[];
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
dot: false,
|
||||||
|
notifications: () => [],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
clear: [];
|
clear: [];
|
||||||
makeAll: [];
|
makeAll: [];
|
||||||
|
onClick: [NotificationItem];
|
||||||
read: [NotificationItem];
|
read: [NotificationItem];
|
||||||
remove: [NotificationItem];
|
remove: [NotificationItem];
|
||||||
viewAll: [];
|
viewAll: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const [open, toggle] = useToggle();
|
const [open, toggle] = useToggle();
|
||||||
|
|
||||||
function close() {
|
const close = () => {
|
||||||
open.value = false;
|
open.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleViewAll() {
|
const handleViewAll = () => {
|
||||||
emit('viewAll');
|
emit('viewAll');
|
||||||
close();
|
close();
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleMakeAll() {
|
const handleMakeAll = () => {
|
||||||
emit('makeAll');
|
emit('makeAll');
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleClear() {
|
const handleClear = () => {
|
||||||
emit('clear');
|
emit('clear');
|
||||||
}
|
};
|
||||||
|
|
||||||
function handleClick(item: NotificationItem) {
|
|
||||||
// 如果通知项有链接,点击时跳转
|
|
||||||
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>
|
||||||
<VbenPopover v-model:open="open" content-class="relative right-2 w-90 p-0">
|
<VbenPopover v-model:open="open" content-class="relative right-2 w-90 p-0">
|
||||||
@@ -104,66 +74,72 @@ function navigateTo(
|
|||||||
<div class="flex items-center justify-between p-4 py-3">
|
<div class="flex items-center justify-between p-4 py-3">
|
||||||
<div class="text-foreground">{{ $t('ui.widgets.notifications') }}</div>
|
<div class="text-foreground">{{ $t('ui.widgets.notifications') }}</div>
|
||||||
<VbenIconButton
|
<VbenIconButton
|
||||||
:disabled="notifications.length <= 0"
|
:disabled="!notifications || notifications.length <= 0"
|
||||||
:tooltip="$t('ui.widgets.markAllAsRead')"
|
:tooltip="$t('ui.widgets.markAllAsRead')"
|
||||||
@click="handleMakeAll"
|
@click="handleMakeAll"
|
||||||
>
|
>
|
||||||
<MailCheck class="size-4" />
|
<MailCheck class="size-4" />
|
||||||
</VbenIconButton>
|
</VbenIconButton>
|
||||||
</div>
|
</div>
|
||||||
<VbenScrollbar v-if="notifications.length > 0">
|
<VbenScrollbar v-if="!notifications || notifications.length > 0">
|
||||||
<ul class="flex! max-h-90 w-full flex-col">
|
<ul class="flex! max-h-90 w-full flex-col">
|
||||||
<template v-for="item in notifications" :key="item.id ?? item.title">
|
<template v-for="item in notifications" :key="item.id ?? item.title">
|
||||||
<li
|
<li
|
||||||
class="relative flex w-full cursor-pointer items-start gap-5 border-t border-border p-3 hover:bg-accent"
|
class="relative flex w-full cursor-pointer items-start gap-5 border-t border-border p-3 hover:bg-accent"
|
||||||
@click="handleClick(item)"
|
@click="emit('onClick', item)"
|
||||||
>
|
>
|
||||||
<span
|
<slot name="content" :item="item">
|
||||||
v-if="!item.isRead"
|
<span
|
||||||
class="absolute top-2 right-2 size-2 rounded-sm bg-primary"
|
|
||||||
></span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
class="relative flex size-10 shrink-0 overflow-hidden rounded-full"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="item.avatar"
|
|
||||||
class="aspect-square size-full object-cover"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<div class="flex flex-col gap-1 leading-none">
|
|
||||||
<p class="font-semibold">{{ item.title }}</p>
|
|
||||||
<p class="my-1 line-clamp-2 text-xs text-muted-foreground">
|
|
||||||
{{ item.message }}
|
|
||||||
</p>
|
|
||||||
<p class="line-clamp-2 text-xs text-muted-foreground">
|
|
||||||
{{ item.date }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="absolute top-1/2 right-3 flex -translate-y-1/2 flex-col gap-2"
|
|
||||||
>
|
|
||||||
<VbenIconButton
|
|
||||||
v-if="!item.isRead"
|
v-if="!item.isRead"
|
||||||
size="xs"
|
class="absolute top-2 right-2 size-2 rounded-sm bg-primary"
|
||||||
variant="ghost"
|
></span>
|
||||||
class="h-6 px-2"
|
|
||||||
:tooltip="$t('common.confirm')"
|
<span
|
||||||
@click.stop="emit('read', item)"
|
class="relative flex size-10 shrink-0 overflow-hidden rounded-full"
|
||||||
>
|
>
|
||||||
<CircleCheckBig class="size-4" />
|
<img
|
||||||
</VbenIconButton>
|
:src="item.avatar"
|
||||||
<VbenIconButton
|
class="aspect-square size-full object-cover"
|
||||||
v-if="item.isRead"
|
/>
|
||||||
size="xs"
|
</span>
|
||||||
variant="ghost"
|
<div class="flex flex-col gap-1 leading-none">
|
||||||
class="h-6 px-2 text-destructive"
|
<p class="font-semibold">{{ item.title }}</p>
|
||||||
:tooltip="$t('common.delete')"
|
<p class="my-1 line-clamp-2 text-xs text-muted-foreground">
|
||||||
@click.stop="emit('remove', item)"
|
{{ item.message }}
|
||||||
|
</p>
|
||||||
|
<p class="line-clamp-2 text-xs text-muted-foreground">
|
||||||
|
{{ item.date }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="absolute top-1/2 right-3 flex -translate-y-1/2 flex-row gap-1"
|
||||||
>
|
>
|
||||||
<CircleX class="size-4" />
|
<slot name="action" :item="item">
|
||||||
</VbenIconButton>
|
<slot name="action-prepend" :item="item"></slot>
|
||||||
</div>
|
<VbenIconButton
|
||||||
|
v-if="!item.isRead"
|
||||||
|
size="xs"
|
||||||
|
variant="ghost"
|
||||||
|
class="h-6 px-2"
|
||||||
|
:tooltip="$t('common.confirm')"
|
||||||
|
@click.stop="emit('read', item)"
|
||||||
|
>
|
||||||
|
<CircleCheckBig class="size-4" />
|
||||||
|
</VbenIconButton>
|
||||||
|
<VbenIconButton
|
||||||
|
v-if="item.isRead"
|
||||||
|
size="xs"
|
||||||
|
variant="ghost"
|
||||||
|
class="h-6 px-2 text-destructive"
|
||||||
|
:tooltip="$t('common.delete')"
|
||||||
|
@click.stop="emit('remove', item)"
|
||||||
|
>
|
||||||
|
<CircleX class="size-4" />
|
||||||
|
</VbenIconButton>
|
||||||
|
<slot name="action-append" :item="item"></slot>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -179,7 +155,7 @@ function navigateTo(
|
|||||||
class="flex items-center justify-between border-t border-border px-4 py-3"
|
class="flex items-center justify-between border-t border-border px-4 py-3"
|
||||||
>
|
>
|
||||||
<VbenButton
|
<VbenButton
|
||||||
:disabled="notifications.length <= 0"
|
:disabled="!notifications || notifications.length <= 0"
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="handleClear"
|
@click="handleClear"
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ interface NotificationItem {
|
|||||||
link?: string;
|
link?: string;
|
||||||
query?: Record<string, any>;
|
query?: Record<string, any>;
|
||||||
state?: Record<string, any>;
|
state?: Record<string, any>;
|
||||||
|
/** 业务字段 */
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { NotificationItem };
|
export type { NotificationItem };
|
||||||
|
|||||||
@@ -163,6 +163,33 @@ function handleMakeAll() {
|
|||||||
|
|
||||||
function handleClickLogo() {}
|
function handleClickLogo() {}
|
||||||
|
|
||||||
|
const viewAll = () => {};
|
||||||
|
|
||||||
|
const handleClick = (item: NotificationItem) => {
|
||||||
|
// 如果通知项有链接,点击时跳转
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => ({
|
() => ({
|
||||||
enable: preferences.app.watermark,
|
enable: preferences.app.watermark,
|
||||||
@@ -215,6 +242,8 @@ onBeforeMount(() => {
|
|||||||
@read="(item) => item.id && markRead(item.id)"
|
@read="(item) => item.id && markRead(item.id)"
|
||||||
@remove="(item) => item.id && remove(item.id)"
|
@remove="(item) => item.id && remove(item.id)"
|
||||||
@make-all="handleMakeAll"
|
@make-all="handleMakeAll"
|
||||||
|
@on-click="handleClick"
|
||||||
|
@view-all="viewAll"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
|
|||||||
Reference in New Issue
Block a user