# Kylin Sensitive Word

Kylin 敏感词过滤包 — DFA 算法高效匹配、17 类风险分类、5 种抗绕过检测、三种过滤模式、词库版本管理、审计日志。

## 功能特性

- **DFA 算法**：Trie 树高效匹配，支持缓存
- **17 类风险分类**：政治/色情/暴力/赌博/诈骗/毒品/邪教/分裂/谣言/极端/广告/侮辱/低俗/标题党/歧视/隐私/网络欺凌（TC260-003 标准）
- **三级风险等级**：high/medium/low，block 模式仅拦截 high 级别
- **5 种抗绕过检测**：符号插入、谐音替换、拆字合并、全角转半角、零宽字符去除
- **三种过滤模式**：replace（替换）、block（拦截）、warn（警告）
- **词库管理**：CRUD、批量导入、增量同步、版本管理
- **分类管理**：分类 CRUD、默认分类初始化
- **审计日志**：记录敏感词检测行为，保留 180 天（满足《网络安全法》第四十七条）
- **词库统计**：按分类和风险等级统计

## 安装

```bash
composer require kylin/sensitive-word
```

## 配置发布

```bash
php artisan vendor:publish --tag=kylin-sensitive-word-config
php artisan vendor:publish --tag=kylin-sensitive-word-migrations
php artisan migrate
```

## 配置说明

```php
// config/kylin-sensitive-word.php

'replace_char' => '*',                    // 替换字符
'filter_mode'  => 'replace',              // 默认过滤模式: replace/block/warn

'categories' => [                         // 17 类风险分类
    'political'    => ['level' => 'high',   'name' => '政治敏感'],
    'pornographic' => ['level' => 'high',   'name' => '色情低俗'],
    // ... 共 17 类
],

'variant_detection' => [                  // 抗绕过检测配置
    'symbol_insert'             => true,   // 符号插入检测
    'homophone'                 => true,   // 谐音检测
    'char_split'                => true,   // 拆字检测
    'full_to_half'              => true,   // 全角转半角
    'traditional_to_simplified' => true,   // 繁体转简体
    'zero_width'                => true,   // 零宽字符去除
],

'sync_interval'    => 300,                // 词库同步间隔（秒）
'cache_ttl'        => 3600,               // 缓存 TTL（秒）
'batch_import_max' => 10000,              // 批量导入最大条数
'audit_enabled'    => true,               // 审计日志开关
'audit_retention'  => 180,                // 审计日志保留天数
```

## 使用示例

### Facade 方式

```php
use KylinSensitiveWord;

// 检测文本是否包含敏感词
$contains = KylinSensitiveWord::contains('需要检测的文本');

// 检测敏感词详情
$hits = KylinSensitiveWord::detect('需要检测的文本');
// 返回: [['word' => '敏感词', 'category' => 'political', 'risk_level' => 'high', 'position' => 5]]

// 过滤文本（默认 replace 模式）
$filtered = KylinSensitiveWord::filter('需要过滤的文本');

// block 模式（高风险敏感词抛出异常）
try {
    $filtered = KylinSensitiveWord::filter('文本', 'block');
} catch (RuntimeException $e) {
    // 高风险敏感词被拦截
}

// 添加敏感词
KylinSensitiveWord::addWord('新敏感词', 'political', 'high');

// 批量导入
$result = KylinSensitiveWord::batchImport([
    ['word' => '词1', 'category' => 'political', 'risk_level' => 'high'],
    ['word' => '词2', 'category' => 'advertising', 'risk_level' => 'low'],
]);
// 返回: ['imported' => 2, 'skipped' => 0]

// 增量同步
$result = KylinSensitiveWord::sync('1.0.0');

// 获取当前版本
$version = KylinSensitiveWord::getCurrentVersion();

// 获取分类列表
$categories = KylinSensitiveWord::getCategories();

// 初始化默认分类
KylinSensitiveWord::initDefaultCategories();

// 获取统计
$stats = KylinSensitiveWord::getStatistics();
// 返回: ['total' => 1000, 'by_category' => [...], 'by_risk_level' => [...]]

// 清除缓存
KylinSensitiveWord::clearCache();
```

### 服务注入方式

```php
use Kylin\SensitiveWord\Services\SensitiveWordService;

public function __construct(
    private readonly SensitiveWordService $sensitiveWordService
) {}

public function checkContent(string $content): string
{
    return $this->sensitiveWordService->filter($content, 'block');
}
```

### API 路由

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/kylin/sensitive-words | 敏感词列表（支持 category/risk_level/status/keyword 筛选） |
| POST | /api/kylin/sensitive-words | 添加敏感词 |
| PUT | /api/kylin/sensitive-words/{id} | 更新敏感词 |
| DELETE | /api/kylin/sensitive-words/{id} | 删除敏感词 |
| POST | /api/kylin/sensitive-words/import | 批量导入 |
| GET | /api/kylin/sensitive-words/sync | 增量同步 |
| GET | /api/kylin/sensitive-words/categories | 分类列表 |
| POST | /api/kylin/sensitive-words/categories/init | 初始化默认分类 |
| POST | /api/kylin/sensitive-words/detect | 检测文本 |
| POST | /api/kylin/sensitive-words/filter | 过滤文本 |
| GET | /api/kylin/sensitive-words/statistics | 词库统计 |

## 数据库表

| 表名 | 说明 |
|------|------|
| `ks_sensitive_words` | 敏感词表（word/category/risk_level/status/variant_of/variant_type/version/source） |
| `ks_word_categories` | 词库分类表（code/name/risk_level/status/sort） |

## 法律合规

详见 [LEGAL.md](./LEGAL.md)，涵盖：
- 《中华人民共和国网络安全法》(2017.6.1) — 第十二条、第四十七条
- 《网络信息内容生态治理规定》(2020.3.1) — 第六条、第九条
- 《互联网信息服务管理办法》(2011.1.8 修订) — 第十五条
- 《中华人民共和国未成年人保护法》(2021.6.1) — 第七十七条
- 《中华人民共和国数据安全法》(2021.9.1) — 第二十一条
- TC260-003 内容安全标准

## 依赖

- PHP ^8.5
- Laravel ^13.0

## 许可证

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