Files
chatroom/app/Http/Controllers/Admin/ForbiddenUsernameController.php
lkddi 632a4240c4 功能:禁用词管理支持批量添加
- 新增 ForbiddenUsernameController::batchStore()
  支持换行、逗号、中文逗号、空格多种分隔格式
  自动去重、跳过已存在词语、忽略超长词
  返回成功数/跳过数详细提示
- 新增路由 POST /admin/forbidden-usernames/batch
- View 新增卡片加「单个/批量」两 Tab 切换
  批量 Tab 使用 textarea 多行输入
2026-03-01 14:04:28 +08:00

182 lines
5.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 文件功能:禁用用户名管理控制器(站长专用)
*
* 管理 username_blacklist 表中 type=permanent 的永久禁用词列表。
* 包含:国家领导人名称、攻击性词汇、违禁词等不允许注册或改名的词语。
*
* 用户在注册AuthController和改名ShopService::useRenameCard时均会经过该表检测。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\UsernameBlacklist;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
class ForbiddenUsernameController extends Controller
{
/**
* 分页列出所有永久禁用词。
* 支持关键词模糊搜索GET ?q=xxx
*/
public function index(Request $request): \Illuminate\View\View
{
$q = $request->query('q', '');
$items = UsernameBlacklist::permanent()
->when($q, fn ($query) => $query->where('username', 'like', "%{$q}%"))
->orderByDesc('created_at')
->paginate(20)
->withQueryString();
return view('admin.forbidden-usernames.index', [
'items' => $items,
'q' => $q,
]);
}
/**
* 新增一条永久禁用词。
*
* @param Request $request 请求体username必填reason选填
*/
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'username' => ['required', 'string', 'max:50'],
'reason' => ['nullable', 'string', 'max:100'],
], [
'username.required' => '禁用词不能为空。',
'username.max' => '禁用词最长50字符。',
]);
$username = trim($validated['username']);
// 已存在同名的永久记录则不重复插入
$exists = UsernameBlacklist::permanent()
->where('username', $username)
->exists();
if ($exists) {
return response()->json(['status' => 'error', 'message' => '该词语已在永久禁用列表中。'], 422);
}
UsernameBlacklist::create([
'username' => $username,
'type' => 'permanent',
'reserved_until' => null,
'reason' => $validated['reason'] ?? null,
'created_at' => Carbon::now(),
]);
return response()->json(['status' => 'success', 'message' => "{$username}」已加入永久禁用列表。"]);
}
/**
* 批量添加永久禁用词。
*
* 接受多行文本或逗号分隔的词语列表,自动去重并过滤已存在者。
* 返回成功添加数量和跳过数量。
*
* @param Request $request 请求体words换行/逗号分隔reason选填共用
*/
public function batchStore(Request $request): JsonResponse
{
$validated = $request->validate([
'words' => ['required', 'string'],
'reason' => ['nullable', 'string', 'max:100'],
], [
'words.required' => '请输入至少一个词语。',
]);
// 支持换行、逗号、中文逗号、空格分隔
$rawWords = preg_split('/[\r\n,\s]+/', $validated['words']);
$reason = trim($validated['reason'] ?? '');
// 过滤空串、截断过长、去重
$words = collect($rawWords)
->map(fn ($w) => trim($w))
->filter(fn ($w) => $w !== '' && mb_strlen($w) <= 50)
->unique()
->values();
if ($words->isEmpty()) {
return response()->json(['status' => 'error', 'message' => '没有有效的词语,请检查输入。'], 422);
}
// 查询已存在的(批量一次查询)
$existing = UsernameBlacklist::permanent()
->whereIn('username', $words->all())
->pluck('username')
->flip(); // 转为键名方便 has() 查询
$now = Carbon::now();
$added = 0;
$rows = [];
foreach ($words as $word) {
if ($existing->has($word)) {
continue; // 跳过已存在
}
$rows[] = [
'username' => $word,
'type' => 'permanent',
'reserved_until' => null,
'reason' => $reason ?: null,
'created_at' => $now,
];
$added++;
}
if (! empty($rows)) {
UsernameBlacklist::insert($rows);
}
$skipped = $words->count() - $added;
$msg = "成功添加 {$added} 个词语".($skipped > 0 ? ",跳过 {$skipped} 个(已存在)" : '').'。';
return response()->json(['status' => 'success', 'message' => $msg, 'added' => $added]);
}
/**
* 更新指定禁用词的原因备注。
*
* @param int $id 记录 ID
* @param Request $request 请求体reason
*/
public function update(Request $request, int $id): JsonResponse
{
$item = UsernameBlacklist::permanent()->findOrFail($id);
$validated = $request->validate([
'reason' => ['nullable', 'string', 'max:100'],
]);
$item->update(['reason' => $validated['reason']]);
return response()->json(['status' => 'success', 'message' => '备注已更新。']);
}
/**
* 删除指定永久禁用词。
*
* @param int $id 记录 ID
*/
public function destroy(int $id): JsonResponse
{
$item = UsernameBlacklist::permanent()->findOrFail($id);
$name = $item->username;
$item->delete();
return response()->json(['status' => 'success', 'message' => "{$name}」已从永久禁用列表移除。"]);
}
}