数据库:
- 新增迁移 username_blacklist 表加 type/reason 列
type: temp(改名30天保留)| permanent(管理员永久禁用)
reason: 禁用原因备注(最长100字符)
核心逻辑:
- UsernameBlacklist::isBlocked() 同时拦截两种类型
也包含 isReserved() 兼容旧调用
增加 scopePermanent()/scopeTemp() 查询作用域
- AuthController 注册时加 isBlocked() 拦截
禁词/保留期内均不可注册
- ShopService::useRenameCard() 已有 isReserved() 调用
因已改用 isBlocked() 别名,无需修改
后台:
- ForbiddenUsernameController:index/store/update/destroy
- 路由:/admin/forbidden-usernames(chat.site_owner 中间件)
- 视图:admin/forbidden-usernames/index.blade.php
新增表单、关键词搜索、分页、行内编辑原因、删除
- 侧边栏加「🚫 禁用用户名」入口(仅站长可见)
98 lines
3.0 KiB
PHP
98 lines
3.0 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:用户名黑名单模型
|
||
*
|
||
* 支持两种类型的禁用记录:
|
||
* temp — 用户改名后旧名称的临时保留(30天),到期后其他人可注册
|
||
* permanent — 管理员设置的永久禁用词(攻击性词汇、领导人名称等),永不可注册
|
||
*
|
||
* 凡是 isBlocked() 返回 true 的名称,无论注册还是改名均不允许使用。
|
||
*
|
||
* @author ChatRoom Laravel
|
||
*
|
||
* @version 2.0.0
|
||
*/
|
||
|
||
namespace App\Models;
|
||
|
||
use Illuminate\Database\Eloquent\Model;
|
||
|
||
class UsernameBlacklist extends Model
|
||
{
|
||
protected $table = 'username_blacklist';
|
||
|
||
/** 只有 created_at,无 updated_at */
|
||
public $timestamps = false;
|
||
|
||
protected $fillable = ['username', 'type', 'reserved_until', 'reason', 'created_at'];
|
||
|
||
protected function casts(): array
|
||
{
|
||
return [
|
||
'reserved_until' => 'datetime',
|
||
'created_at' => 'datetime',
|
||
];
|
||
}
|
||
|
||
// ──────────────────────────────────────────
|
||
// 公共查询方法
|
||
// ──────────────────────────────────────────
|
||
|
||
/**
|
||
* 判断给定名称是否被禁止使用。
|
||
*
|
||
* 满足以下任一条件时返回 true:
|
||
* 1. 存在 type=permanent 的永久禁用记录
|
||
* 2. 存在 type=temp 且 reserved_until 尚未过期的临时保留记录
|
||
*
|
||
* @param string $username 要检测的用户名
|
||
*/
|
||
public static function isBlocked(string $username): bool
|
||
{
|
||
return static::where('username', $username)
|
||
->where(function ($q) {
|
||
// 永久禁用
|
||
$q->where('type', 'permanent')
|
||
// 或:临时保留且尚未到期
|
||
->orWhere(function ($q2) {
|
||
$q2->where('type', 'temp')
|
||
->where('reserved_until', '>', now());
|
||
});
|
||
})
|
||
->exists();
|
||
}
|
||
|
||
/**
|
||
* 兼容旧调用: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');
|
||
}
|
||
}
|