功能:禁用词管理支持批量添加

- 新增 ForbiddenUsernameController::batchStore()
  支持换行、逗号、中文逗号、空格多种分隔格式
  自动去重、跳过已存在词语、忽略超长词
  返回成功数/跳过数详细提示
- 新增路由 POST /admin/forbidden-usernames/batch
- View 新增卡片加「单个/批量」两 Tab 切换
  批量 Tab 使用 textarea 多行输入
This commit is contained in:
2026-03-01 14:04:28 +08:00
parent fc495ccceb
commit 632a4240c4
3 changed files with 133 additions and 8 deletions
@@ -80,6 +80,72 @@ class ForbiddenUsernameController extends Controller
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]);
}
/**
* 更新指定禁用词的原因备注。
*