You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel10/FilamentPHP3:点击通知内链接标记通知为已读方案

解决FilamentPHP 3中点击通知链接自动标记已读并移除的问题

问题场景

在Laravel 10 + FilamentPHP 3应用中,前端用户完成操作后会向管理员发送包含后台表单跳转链接的通知。目前点击链接可正常跳转,但通知仍停留在右上角列表中,需手动点击关闭图标才会消失,需要实现点击链接时自动将通知标记为已读并移除。

解决方案

方案一:利用Filament通知内置Action(推荐)

最贴合Filament设计规范的方式是放弃在通知body中直接嵌入HTML链接,改用Filament通知的action方法添加操作按钮,Filament会自动处理点击后的通知已读标记:

修改事件监听器中的Filament通知发送代码:

\Filament\Notifications\Notification::make()
    ->title('Quiz completed by user')
    ->body("Hi {$manager->name}, \n job seeker {$userQuizRequest->jobSeeker->name} at \"Quizzes\" site ran \"HTML category\" quiz. \n\nYou have received this notification as you are manager of \"Quizzes\" \n\nBest Regards,\nSupport of Quizzes Team")
    ->info()
    ->action('View Request', function () use ($userQuizRequest) {
        // 跳转到对应的编辑页面,替换为你的实际路由
        return redirect()->route('filament.service-owner.resources.user-quiz-requests.edit', ['record' => $userQuizRequest->id]);
    })
    ->sendToDatabase(users: [$tempUser]);

这种方式下,管理员点击「View Request」按钮时,系统会自动将该通知标记为已读并从列表中移除,无需额外编写前端代码。

方案二:自定义链接+前端JS处理(兼容现有HTML链接场景)

如果必须保留body中的HTML链接,可通过以下步骤实现需求:

1. 给链接附加通知ID

修改事件监听器代码,先保存通知获取ID,再将ID注入到链接的自定义属性中:

$tempUser = User::factory()->make([
    'id' => $manager->id,
    'name' => $manager->name,
    'email' => $manager->email,
]);

// 创建并发送通知到数据库
$filamentNotification = \Filament\Notifications\Notification::make()
    ->title('Quiz completed by user')
    ->body($content)
    ->info();

$databaseNotification = $filamentNotification->sendToDatabase(users: [$tempUser])->first();

// 给链接添加data-notification-id属性
$updatedBody = str_replace(
    '<a href="',
    '<a data-notification-id="' . $databaseNotification->id . '" href="',
    $databaseNotification->data['body']
);

// 更新通知的body内容
$databaseNotification->update([
    'data' => array_merge($databaseNotification->data, ['body' => $updatedBody])
]);

2. 添加前端点击事件处理

在Filament自定义脚本文件(如resources/js/filament.js)中添加监听逻辑:

document.addEventListener('DOMContentLoaded', () => {
    document.addEventListener('click', (e) => {
        const targetLink = e.target.closest('a[data-notification-id]');
        if (!targetLink) return;

        const notificationId = targetLink.dataset.notificationId;
        const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

        // 调用Filament标记已读接口
        fetch(`/admin/notifications/${notificationId}/mark-as-read`, {
            method: 'POST',
            headers: {
                'X-CSRF-TOKEN': csrfToken,
                'Accept': 'application/json'
            }
        }).then(() => {
            // 移除通知元素
            const notificationElement = targetLink.closest('.filament-notifications-notification');
            if (notificationElement) notificationElement.remove();
        }).catch(err => console.error('标记通知已读失败:', err));
    });
});

3. 确认路由可用性

Filament默认已注册通知标记已读的路由,若路由不存在,可手动在routes/web.php中添加:

use Filament\Http\Controllers\NotificationsController;

Route::post('/admin/notifications/{notification}/mark-as-read', [NotificationsController::class, 'markAsRead'])
    ->middleware(['auth'])
    ->name('filament.notifications.mark-as-read');

内容的提问来源于stack exchange,提问作者mstdmstd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:40:55