2026-02-27 15:57:12 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 文件功能:用户名黑名单模型
|
2026-03-01 14:00:38 +08:00
|
|
|
|
*
|
|
|
|
|
|
* 支持两种类型的禁用记录:
|
|
|
|
|
|
* temp — 用户改名后旧名称的临时保留(30天),到期后其他人可注册
|
|
|
|
|
|
* permanent — 管理员设置的永久禁用词(攻击性词汇、领导人名称等),永不可注册
|
|
|
|
|
|
*
|
|
|
|
|
|
* 凡是 isBlocked() 返回 true 的名称,无论注册还是改名均不允许使用。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author ChatRoom Laravel
|
|
|
|
|
|
*
|
|
|
|
|
|
* @version 2.0.0
|
2026-02-27 15:57:12 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
|
|
|
|
|
|
|
|
class UsernameBlacklist extends Model
|
|
|
|
|
|
{
|
|
|
|
|
|
protected $table = 'username_blacklist';
|
|
|
|
|
|
|
2026-03-01 14:00:38 +08:00
|
|
|
|
/** 只有 created_at,无 updated_at */
|
|
|
|
|
|
public $timestamps = false;
|
2026-02-27 15:57:12 +08:00
|
|
|
|
|
2026-03-01 14:00:38 +08:00
|
|
|
|
protected $fillable = ['username', 'type', 'reserved_until', 'reason', 'created_at'];
|
2026-02-27 15:57:12 +08:00
|
|
|
|
|
2026-03-01 14:00:38 +08:00
|
|
|
|
protected function casts(): array
|
|
|
|
|
|
{
|
|
|
|
|
|
return [
|
|
|
|
|
|
'reserved_until' => 'datetime',
|
|
|
|
|
|
'created_at' => 'datetime',
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ──────────────────────────────────────────
|
|
|
|
|
|
// 公共查询方法
|
|
|
|
|
|
// ──────────────────────────────────────────
|
2026-02-27 15:57:12 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-02 16:38:17 +08:00
|
|
|
|
* 获取拦截该名称的具体黑名单记录(如果有)。
|
2026-03-01 14:00:38 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @param string $username 要检测的用户名
|
2026-04-02 16:38:17 +08:00
|
|
|
|
* @return static|null
|
2026-02-27 15:57:12 +08:00
|
|
|
|
*/
|
2026-04-02 16:38:17 +08:00
|
|
|
|
public static function getBlockingRecord(string $username): ?self
|
2026-02-27 15:57:12 +08:00
|
|
|
|
{
|
2026-04-02 16:35:58 +08:00
|
|
|
|
// 1. 检查是否存在精确匹配且未过期的“临时改名保留”名称
|
2026-04-02 16:38:17 +08:00
|
|
|
|
$tempRecord = static::where('type', 'temp')
|
2026-04-02 16:35:58 +08:00
|
|
|
|
->where('username', $username)
|
|
|
|
|
|
->where('reserved_until', '>', now())
|
2026-04-02 16:38:17 +08:00
|
|
|
|
->first();
|
2026-04-02 16:35:58 +08:00
|
|
|
|
|
2026-04-02 16:38:17 +08:00
|
|
|
|
if ($tempRecord) {
|
|
|
|
|
|
return $tempRecord;
|
2026-04-02 16:35:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 检查永久禁用词,改为【模糊匹配】(只要新注册的名字中包含禁用词,拦截)
|
|
|
|
|
|
// 比如数据库禁用了 "admin",那么 "admin123" 也会触发拦截
|
2026-04-02 16:38:17 +08:00
|
|
|
|
$permanentRecord = static::where('type', 'permanent')
|
2026-04-02 16:35:58 +08:00
|
|
|
|
->where('username', '!=', '')
|
|
|
|
|
|
->whereRaw('? LIKE CONCAT("%", username, "%")', [$username])
|
2026-04-02 16:38:17 +08:00
|
|
|
|
->first();
|
2026-04-02 16:35:58 +08:00
|
|
|
|
|
2026-04-02 16:38:17 +08:00
|
|
|
|
return $permanentRecord;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 判断给定名称是否被禁止使用。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $username 要检测的用户名
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function isBlocked(string $username): bool
|
|
|
|
|
|
{
|
|
|
|
|
|
return static::getBlockingRecord($username) !== null;
|
2026-02-27 15:57:12 +08:00
|
|
|
|
}
|
2026-03-01 14:00:38 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 兼容旧调用:isReserved() 等同于 isBlocked()。
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $username 要检测的用户名
|
|
|
|
|
|
*
|
|
|
|
|
|
* @deprecated 请使用 isBlocked()
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function isReserved(string $username): bool
|
|
|
|
|
|
{
|
|
|
|
|
|
return static::isBlocked($username);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ──────────────────────────────────────────
|
|
|
|
|
|
// 作用域(Scopes)
|
|
|
|
|
|
// ──────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 仅查询永久禁用词(管理员维护的列表)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function scopePermanent($query)
|
|
|
|
|
|
{
|
|
|
|
|
|
return $query->where('type', 'permanent');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 仅查询临时保留记录(改名后旧名)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function scopeTemp($query)
|
|
|
|
|
|
{
|
|
|
|
|
|
return $query->where('type', 'temp');
|
|
|
|
|
|
}
|
2026-02-27 15:57:12 +08:00
|
|
|
|
}
|