PHP项目Laravel通知路由按用户动态

wen PHP项目 4

本文目录导读:

PHP项目Laravel通知路由按用户动态

  1. 基础方案:通过用户模型定义路由
  2. 高级方案:基于用户状态动态路由
  3. 通过Notification类动态路由
  4. 通过自定义通知服务提供者
  5. 通过中间件获取动态路由
  6. 通过Notification Route Builder
  7. 业务场景示例
  8. 配置文件设置
  9. 最佳实践建议
  10. 生产环境注意事项

在Laravel中实现通知路由按用户动态路由,有几种常见的方案,我来详细说明:

基础方案:通过用户模型定义路由

// app/Models/User.php
class User extends Authenticatable
{
    use Notifiable;
    // 动态返回通知路由
    public function routeNotificationForSms()
    {
        return $this->phone; // 用户的手机号
    }
    public function routeNotificationForMail($notification)
    {
        return $this->email; // 用户的邮箱
    }
    public function routeNotificationForNexmo($notification)
    {
        return $this->phone;
    }
}

高级方案:基于用户状态动态路由

// app/Models/User.php
class User extends Authenticatable
{
    use Notifiable;
    public function routeNotificationForMail($notification)
    {
        // 根据用户偏好动态选择邮件地址
        if ($this->preferred_email && $this->preferred_email_enabled) {
            return $this->preferred_email;
        }
        return $this->email;
    }
    public function routeNotificationForSms($notification)
    {
        // 根据用户的国家代码动态拼接
        return $this->country_code . $this->phone;
    }
}

通过Notification类动态路由

// app/Notifications/OrderShipped.php
class OrderShipped extends Notification
{
    public function via($notifiable)
    {
        // 根据用户类型动态选择通知渠道
        $channels = ['mail'];
        if ($notifiable->sms_notifications_enabled) {
            $channels[] = 'sms';
        }
        if ($notifiable->push_notifications_enabled) {
            $channels[] = 'pusher';
        }
        return $channels;
    }
    public function toMail($notifiable)
    {
        // 动态设置邮件接收者
        return (new MailMessage)
            ->to($notifiable->notification_email)
            ->subject('订单已发货')
            ->line('您的订单已发货!');
    }
}

通过自定义通知服务提供者

// app/Notifications/NotificationServiceProvider.php
class NotificationServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Notification::delivering(function ($notification, $channel, $notifiable) {
            // 根据用户动态调整通知路由
            if ($notifiable->type == 'premium' && $channel == 'mail') {
                $notification->mail_route = $notifiable->premium_email;
            }
        });
        Notification::sent(function ($notification, $channel, $notifiable) {
            // 通知发送后的处理
            Log::info("Notification sent to user {$notifiable->id} via {$channel}");
        });
    }
}

通过中间件获取动态路由

// app/Models/User.php
class User extends Authenticatable
{
    use Notifiable;
    protected $notificationPreferences;
    public function getNotificationPreference($channel)
    {
        // 从缓存或数据库获取用户的动态通知偏好
        $this->notificationPreferences = Cache::remember('user_notifications_' . $this->id, 3600, function () {
            return $this->notificationSettings()->pluck('value', 'key')->toArray();
        });
        return $this->notificationPreferences[$channel] ?? null;
    }
    public function routeNotificationForMail($notification)
    {
        $preference = $this->getNotificationPreference('mail');
        switch ($preference) {
            case 'secondary':
                return $this->secondary_email;
            case 'custom':
                return $this->custom_mail_route;
            default:
                return $this->email;
        }
    }
}

通过Notification Route Builder

// app/Services/NotificationRouteBuilder.php
class NotificationRouteBuilder
{
    public static function buildRoute(User $user, $channel)
    {
        // 根据用户的配置动态构建路由
        switch ($channel) {
            case 'mail':
                if ($user->getSetting('mail_route') === 'custom') {
                    return $user->custom_email_address;
                }
                return $user->email;
            case 'sms':
                if ($user->getSetting('sms_route')) {
                    return $user->sms_route;
                }
                return $user->phone;
            case 'pusher':
                if ($user->getSetting('pusher_route')) {
                    return $user->pusher_route;
                }
                return null;
            default:
                return null;
        }
    }
}

业务场景示例

// 在业务逻辑中使用
class OrderService
{
    public function sendOrderNotification($order)
    {
        $user = $order->user;
        // 创建通知实例
        $notification = new OrderStatusChanged($order);
        // 根据用户类型动态发送
        if ($user->isVip()) {
            // VIP用户使用特殊路由
            Notification::route('mail', $user->vip_email)
                       ->route('sms', $user->vip_phone)
                       ->notify($notification);
        } else {
            // 普通用户使用默认路由
            $user->notify($notification);
        }
    }
}

配置文件设置

// config/notifications.php
return [
    'routes' => [
        'default' => [
            'mail' => 'email',
            'sms' => 'phone',
        ],
        'premium' => [
            'mail' => 'premium_email',
            'sms' => 'premium_phone',
        ],
        'enterprise' => [
            'mail' => 'enterprise_email',
            'sms' => 'enterprise_phone',
        ],
    ],
    'channels' => [
        'mail' => ['default', 'premium'],
        'sms' => ['default'],
    ],
];

最佳实践建议

// 建议在Notification基类中定义抽象方法
abstract class BaseNotification extends Notification
{
    public function getRouteForChannel($channel, $notifiable)
    {
        // 默认路由
        $routeMethods = [
            'mail' => 'routeNotificationForMail',
            'sms' => 'routeNotificationForSms',
            'nexmo' => 'routeNotificationForNexmo',
        ];
        if (method_exists($notifiable, $routeMethods[$channel])) {
            return $notifiable->{$routeMethods[$channel]}($this);
        }
        return null;
    }
}

生产环境注意事项

// app/Models/User.php
class User extends Authenticatable
{
    use Notifiable;
    protected function getNotificationRoutes()
    {
        // 缓存用户通知路由,减少数据库查询
        return Cache::remember("user_notification_routes_{$this->id}", 600, function () {
            return [
                'mail' => $this->notification_email ?? $this->email,
                'sms' => $this->notification_phone ?? $this->phone,
            ];
        });
    }
    public function routeNotificationForMail($notification)
    {
        $routes = $this->getNotificationRoutes();
        // 如果用户设置了特定通知,使用特定路由
        if (isset($notification->custom_routes['mail'])) {
            return $notification->custom_routes['mail'];
        }
        return $routes['mail'];
    }
}

这种动态路由机制非常适合:

  • 多语言/多地区的用户
  • VIP/普通用户不同通知渠道
  • 用户偏好设置
  • A/B测试不同通知策略
  • 特殊业务场景的通知路由

选择哪种方案取决于你的具体需求,建议从简单的开始,逐步演进。

抱歉,评论功能暂时关闭!