# Kylin Notification

Kylin 多渠道通知推送系统 — 站内信/短信/邮件/微信/APP推送，含用户授权同意、注销清理、敏感内容过滤。

## 功能特性

- **站内信**：系统内消息通知，已读/未读状态管理
- **短信**：阿里云短信、腾讯云短信（双通道容灾）
- **邮件**：SMTP / 阿里云邮件推送
- **微信**：模板消息、订阅消息、客服消息
- **APP 推送**：极光推送、个推、友盟推送、FCM
- **Apple 推送**：APNs HTTP/2 Provider API（Token/Certificate 认证）
- **适配器模式**：统一 `ChannelInterface` 接口，易于扩展新渠道
- **发送日志**：记录每次推送的状态和响应（`NotificationLog`）
- **模板管理**：通知模板定义与变量替换
- **用户授权同意**：用户可对各渠道独立授权/撤销（`NotificationPreference`）
- **用户注销清理**：注销时清理通知记录和授权同意记录（`purgeForUser()`）
- **敏感内容过滤**：自动过滤身份证号、手机号、银行卡号等敏感信息

## 安装

```bash
composer require kylin/notification
```

## 配置发布

```bash
php artisan vendor:publish --tag=kylin-notification-config
```

## 使用示例

### Facade

```php
use Kylin\Notification\Facades\KylinNotification;

// 发送站内信（默认允许，无需授权）
KylinNotification::send('order_shipped', '订单已发货', '您的订单已发出', ['database'], [
    'notifiable_type' => 'App\\Models\\User',
    'notifiable_id' => $user->id,
]);

// 发送短信（需用户已授权）
KylinNotification::send('verification_code', '验证码', '您的验证码是 123456', ['aliyun_sms'], [
    'notifiable_type' => 'App\\Models\\User',
    'notifiable_id' => $user->id,
    'channel_params' => [
        'aliyun_sms' => ['phone' => '13800138000', 'template_code' => 'SMS_123', 'template_params' => ['code' => '123456']],
    ],
]);

// 多渠道同时发送
KylinNotification::send('new_message', '新消息', '您收到一条新消息', ['database', 'mail', 'jpush'], [
    'notifiable_type' => 'App\\Models\\User',
    'notifiable_id' => $user->id,
]);

// 系统级通知（跳过授权校验，如账号安全告警）
KylinNotification::send('security_alert', '安全告警', '您的账号在异地登录', ['aliyun_sms'], [
    'notifiable_type' => 'App\\Models\\User',
    'notifiable_id' => $user->id,
    'skip_consent_check' => true,
    'channel_params' => [
        'aliyun_sms' => ['phone' => '13800138000', 'template_code' => 'SMS_456'],
    ],
]);
```

### 用户授权同意管理

```php
use Kylin\Notification\Facades\KylinNotification;

// 用户授权同意某渠道（PIPL 第 44 条）
KylinNotification::grantConsent('App\\Models\\User', $user->id, 'aliyun_sms');

// 用户撤销某渠道授权
KylinNotification::revokeConsent('App\\Models\\User', $user->id, 'aliyun_sms');
```

### 用户注销清理

```php
use Kylin\Notification\Facades\KylinNotification;

// 用户注销时清理通知数据（PIPL 第 47 条）
$result = KylinNotification::purgeForUser('App\\Models\\User', $user->id);
// 返回 ['notifications' => 15, 'preferences' => 3]
```

### 通知渠道配置

```php
// config/kylin-notification.php
'channels' => [
    'aliyun_sms' => [
        'access_key' => env('ALIYUN_SMS_ACCESS_KEY'),
        'access_secret' => env('ALIYUN_SMS_ACCESS_SECRET'),
        'sign_name' => env('ALIYUN_SMS_SIGN_NAME'),
    ],
    'jpush' => [
        'app_key' => env('JPUSH_APP_KEY'),
        'master_secret' => env('JPUSH_MASTER_SECRET'),
    ],
    'apns' => [
        'environment' => env('APNS_ENVIRONMENT', 'sandbox'),
        'key_id' => env('APNS_KEY_ID'),
        'team_id' => env('APNS_TEAM_ID'),
    ],
],
```

## SDK 目录结构

```
src/
├── Channels/
│   ├── DatabaseChannel.php         # 站内信
│   ├── AliyunSmsChannel.php        # 阿里云短信
│   ├── TencentSmsChannel.php       # 腾讯云短信
│   ├── MailChannel.php             # 邮件
│   ├── WechatTemplateChannel.php   # 微信模板消息
│   ├── JPushChannel.php            # 极光推送
│   ├── GeTuiChannel.php            # 个推
│   ├── UMengChannel.php            # 友盟推送
│   ├── FcmChannel.php              # FCM
│   └── ApnsChannel.php             # Apple APNs
├── Contracts/ChannelInterface.php
├── Events/NotificationSent.php
├── Models/
│   ├── Notification.php
│   ├── NotificationLog.php
│   └── NotificationPreference.php  # 用户授权同意
├── Services/NotificationService.php
└── Http/Controllers/NotificationController.php
```

## 合规要点

| 合规项 | 实现方式 | 法律依据 |
|------|------|------|
| 用户授权同意 | `NotificationPreference` + `checkConsent()` | 《个人信息保护法》第四十四条 |
| 用户注销清理 | `purgeForUser()` | 《个人信息保护法》第四十七条 |
| 敏感内容过滤 | `sanitizeContent()` 过滤身份证/手机号/银行卡号 | 《网络安全法》第四十二条 |
| 通知日志 | `NotificationLog` 全量记录 | 《网络安全法》第二十一条 |
| 短信发送授权 | 默认拒绝，需用户主动授权 | 《通信短信息服务管理规定》第十八条 |
| 审计日志 | 所有关键操作写入 `kylin/audit-log` | 《网络安全法》第二十一条 |

## 审计事件

| 事件 | 说明 |
|------|------|
| `notification_sent` | 通知发送 |
| `notification_consent_granted` | 用户授权同意 |
| `notification_consent_revoked` | 用户撤销授权 |
| `notification_user_purged` | 用户注销清理 |

## API 路由

所有路由需通过 `auth:sanctum` 鉴权。

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/kylin/notifications | 通知列表 |
| GET | /api/kylin/notifications/unread-count | 未读数量 |
| POST | /api/kylin/notifications/{id}/read | 标记已读 |
| POST | /api/kylin/notifications/read-all | 全部标记已读 |

## 数据库表

| 表名 | 说明 |
|------|------|
| `kylin_notifications` | 通知记录表 |
| `kylin_notification_logs` | 通知发送日志表 |
| `kylin_notification_preferences` | 用户授权同意表 |

## 法律合规

详见 [LEGAL.md](./LEGAL.md)，涵盖：
- 《中华人民共和国个人信息保护法》(2021.11.1) — 授权同意、注销清理
- 《中华人民共和国网络安全法》(2017.6.1) — 日志留存、敏感信息过滤
- 《通信短信息服务管理规定》(2015.6.30) — 短信授权、日志记录
- 《互联网信息服务管理办法》(2000.9.25) — 内容合规
- 《中华人民共和国数据安全法》(2021.9.1) — 数据安全管理

## 依赖

- PHP ^8.5
- Laravel ^13.0
- kylin/core
- guzzlehttp/guzzle ^7.0
- 建议：kylin/audit-log（审计日志）、kylin/word-filter（敏感词过滤）

## 许可证

私有软件，未经授权禁止使用。
