Files
chatroom/app/Http/Controllers/UserController.php
lkddi 50fc804402 feat: 实现挂机修仙、排行榜、大厅重构与全站留言板系统
- (Phase 8) 后台各维度管理与配置
- (Phase 9) 全自动静默挂机修仙升级
- (Phase 9) 四大维度风云排行榜页面
- (Phase 10) 全站留言板与悄悄话私信功能
- 运行 Pint 代码格式化
2026-02-26 13:35:38 +08:00

150 lines
5.2 KiB
PHP

<?php
/**
* 文件功能:用户中心与管理控制器
* 接管原版 USERinfo.ASP, USERSET.ASP, chpasswd.asp, KILLUSER.ASP
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Http\Controllers;
use App\Events\UserKicked;
use App\Events\UserMuted;
use App\Http\Requests\ChangePasswordRequest;
use App\Http\Requests\UpdateProfileRequest;
use App\Models\Room;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
/**
* 查看其他用户资料片 (对应 USERinfo.ASP)
*/
public function show(string $username): JsonResponse
{
$user = User::where('username', $username)->firstOrFail();
// 隐藏关键信息,只返回公开资料
return response()->json([
'username' => $user->username,
'sex' => $user->sex,
'headface' => $user->headface,
'user_level' => $user->user_level,
'sign' => $user->sign ?? '这个人很懒,什么都没留下。',
'created_at' => $user->created_at->format('Y-m-d'),
]);
}
/**
* 修改个人资料 (对应 USERSET.ASP)
*/
public function updateProfile(UpdateProfileRequest $request): JsonResponse
{
$user = Auth::user();
$user->update($request->validated());
return response()->json(['status' => 'success', 'message' => '资料更新成功。']);
}
/**
* 修改密码 (对应 chpasswd.asp)
*/
public function changePassword(ChangePasswordRequest $request): JsonResponse
{
$user = Auth::user();
$oldPasswordInput = $request->input('old_password');
// 双模式密码校验逻辑(沿用 AuthController 中策略)
$isOldPasswordCorrect = false;
// 优先验证 Bcrypt
if (Hash::check($oldPasswordInput, $user->password)) {
$isOldPasswordCorrect = true;
}
// 降级验证旧版 MD5
elseif (md5($oldPasswordInput) === $user->password) {
$isOldPasswordCorrect = true;
}
if (! $isOldPasswordCorrect) {
return response()->json(['status' => 'error', 'message' => '当前密码输入不正确。'], 422);
}
// 验证通过,覆盖为新的 Bcrypt 加密串
$user->password = Hash::make($request->input('new_password'));
$user->save();
return response()->json(['status' => 'success', 'message' => '密码已成功修改。下次请使用新密码登录。']);
}
/**
* 管理员/房主操作:踢出房间 (对应 KILLUSER.ASP)
*/
public function kick(Request $request, string $username): JsonResponse
{
$operator = Auth::user();
$roomId = $request->input('room_id');
if (! $roomId) {
return response()->json(['status' => 'error', 'message' => '缺少房间参数。'], 422);
}
$room = Room::findOrFail($roomId);
// 鉴权:操作者要是房间房主或者系统超管
if ($room->master !== $operator->username && $operator->user_level < 15) {
return response()->json(['status' => 'error', 'message' => '权限不足,无法执行踢出操作。'], 403);
}
$targetUser = User::where('username', $username)->first();
if (! $targetUser) {
return response()->json(['status' => 'error', 'message' => '目标用户不存在。'], 404);
}
// 防误伤高管
if ($targetUser->user_level >= 15 && $operator->user_level < 15) {
return response()->json(['status' => 'error', 'message' => '权限不足,无法踢出同级或高级管理人员。'], 403);
}
// 核心动作:向频道内所有人发送包含“某某踢出某某”的事件
broadcast(new UserKicked($roomId, $targetUser->username, "管理员 [{$operator->username}] 将 [{$targetUser->username}] 踢出了聊天室。"));
return response()->json(['status' => 'success', 'message' => "已成功将 {$targetUser->username} 踢出房间。"]);
}
/**
* 管理员/具有道具者操作:禁言 (对应新加的限制功能)
*/
public function mute(Request $request, string $username): JsonResponse
{
$operator = Auth::user();
$roomId = $request->input('room_id');
$duration = $request->input('duration', 5); // 默认封停分钟数
if (! $roomId) {
return response()->json(['status' => 'error', 'message' => '缺少房间参数。'], 422);
}
$room = Room::findOrFail($roomId);
// 此处只做简单鉴权演示,和踢人一致
if ($room->master !== $operator->username && $operator->user_level < 15) {
return response()->json(['status' => 'error', 'message' => '权限不足,无法执行禁言操作。'], 403);
}
// 后续可以在 Redis 中写入一个 `mute:{$username}` 并附带 `TTL` 以在后台拦截
// 立刻向房间发送 Muted 事件
broadcast(new UserMuted($roomId, $username, $duration));
return response()->json(['status' => 'success', 'message' => "已对 {$username} 实施封口 {$duration} 分钟。"]);
}
}