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

Filament控制台发送通知(存储至数据库)及学生订阅到期通知实现咨询

学生订阅到期通知实现方案

一、定时触发到期通知(Laravel 任务调度+通知系统)

Laravel原生的任务调度与Notification系统完全可以实现「保存通知+到期触发」的需求,无需依赖Filament额外功能:

  1. 创建订阅到期通知类
    生成支持邮件+数据库存储的通知类:
php artisan make:notification SubscriptionExpiringNotification

编辑生成的类,同时启用Mail和Database通道:

use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\DatabaseMessage;

class SubscriptionExpiringNotification extends Notification
{
    public function via($notifiable)
    {
        return ['mail', 'database']; // 同时保存到数据库并发送邮件
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject('你的订阅即将到期')
            ->line('你的订阅将在3天后到期,请及时续费。')
            ->action('立即续费', route('subscription.renew'));
    }

    public function toDatabase($notifiable)
    {
        return [
            'title' => '订阅即将到期',
            'body' => '你的订阅将在3天后到期,请及时续费。',
            'action_url' => route('subscription.renew'),
            'expires_at' => now()->addDays(3)
        ];
    }
}
  1. 编写定时检查任务
    生成用于查询即将到期订阅的命令类:
php artisan make:command CheckSubscriptionExpirations

在handle方法中实现查询与通知逻辑:

use App\Models\Student;
use App\Notifications\SubscriptionExpiringNotification;
use Illuminate\Console\Command;

class CheckSubscriptionExpirations extends Command
{
    protected $signature = 'subscriptions:check-expirations';
    protected $description = '检查即将到期的学生订阅并发送通知';

    public function handle()
    {
        // 查询3天后到期、未过期的学生
        $students = Student::where('subscription_expires_at', '<=', now()->addDays(3))
            ->where('subscription_expires_at', '>', now())
            ->get();

        foreach ($students as $student) {
            // 避免重复发送,判断是否已发送过该类型通知
            if (!$student->notifications()->where('type', SubscriptionExpiringNotification::class)->exists()) {
                $student->notify(new SubscriptionExpiringNotification());
            }
        }

        $this->info('订阅到期通知检查完成');
    }
}
  1. 注册定时任务
    在app/Console/Kernel.php的schedule方法中添加任务调度规则:
protected function schedule(Schedule $schedule)
{
    $schedule->command('subscriptions:check-expirations')->daily(); // 每天执行一次
}

二、Filament面板内自动弹出通知

通过Filament的组件挂载逻辑或全局中间件,可实现学生进入面板时自动弹窗:

方式1:在学生Dashboard挂载时触发

编辑学生面板的Dashboard组件(如app/Filament/Student/Widgets/StudentDashboard.php):

use App\Models\Notification;
use Filament\Notifications\Notification as FilamentNotification;
use Filament\Widgets\DashboardWidget;

class StudentDashboard extends DashboardWidget
{
    protected static string $view = 'filament.student.widgets.student-dashboard';

    public function mount()
    {
        parent::mount();

        // 获取当前学生未读的订阅到期通知
        $expirationNotifications = auth()->user()->notifications()
            ->where('type', \App\Notifications\SubscriptionExpiringNotification::class)
            ->whereNull('read_at')
            ->get();

        foreach ($expirationNotifications as $notification) {
            FilamentNotification::make()
                ->title($notification->data['title'])
                ->body($notification->data['body'])
                ->action('立即续费', $notification->data['action_url'])
                ->danger() // 用危险样式突出提醒
                ->send();

            // 标记为已读,避免重复弹窗
            $notification->markAsRead();
        }
    }
}

方式2:全局中间件触发(全面板页面生效)

生成自定义中间件:

php artisan make:middleware CheckStudentExpirationNotifications

编写中间件逻辑:

use Closure;
use Filament\Notifications\Notification as FilamentNotification;
use Illuminate\Http\Request;

class CheckStudentExpirationNotifications
{
    public function handle(Request $request, Closure $next)
    {
        if (auth()->check() && auth()->user()->isStudent()) { // 根据你的用户角色判断逻辑调整
            $expirationNotifications = auth()->user()->notifications()
                ->where('type', \App\Notifications\SubscriptionExpiringNotification::class)
                ->whereNull('read_at')
                ->get();

            foreach ($expirationNotifications as $notification) {
                FilamentNotification::make()
                    ->title($notification->data['title'])
                    ->body($notification->data['body'])
                    ->action('立即续费', $notification->data['action_url'])
                    ->danger()
                    ->send();

                $notification->markAsRead();
            }
        }

        return $next($request);
    }
}

在app/Http/Kernel.php的filament中间件组中注册该中间件:

protected $middlewareGroups = [
    // ...其他中间件组
    'filament' => [
        // 已有Filament中间件
        \App\Http\Middleware\CheckStudentExpirationNotifications::class,
    ],
];

补充提示

  • 数据库通知依赖Laravel自带的notifications表,若未生成可执行php artisan notifications:table并迁移
  • 可调整任务调度频率,例如改为每天上午9点执行:->dailyAt('09:00')
  • Filament通知支持success/warning/danger等样式,可根据需求替换

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:57:38