diff --git a/app/Http/Controllers/ChatController.php b/app/Http/Controllers/ChatController.php index bfed7ae..49bd074 100644 --- a/app/Http/Controllers/ChatController.php +++ b/app/Http/Controllers/ChatController.php @@ -80,14 +80,14 @@ class ChatController extends Controller // 获取当前在职职务信息(用于内容显示) $activePosition = $user->activePosition; $userData = [ - 'user_id' => $user->id, - 'level' => $user->user_level, - 'sex' => $user->sex, - 'headface' => $user->headface, - 'vip_icon' => $user->vipIcon(), - 'vip_name' => $user->vipName(), - 'vip_color' => $user->isVip() ? ($user->vipLevel?->color ?? '') : '', - 'is_admin' => $user->user_level >= $superLevel, + 'user_id' => $user->id, + 'level' => $user->user_level, + 'sex' => $user->sex, + 'headface' => $user->headface, + 'vip_icon' => $user->vipIcon(), + 'vip_name' => $user->vipName(), + 'vip_color' => $user->isVip() ? ($user->vipLevel?->color ?? '') : '', + 'is_admin' => $user->user_level >= $superLevel, 'position_icon' => $activePosition?->position?->icon ?? '', 'position_name' => $activePosition?->position?->name ?? '', ]; @@ -419,16 +419,7 @@ class ChatController extends Controller // 2. 使用 sysparam 表中可配置的等级-经验阈值计算等级 // 管理员(superlevel 及以上)不参与自动升降级,等级由后台手动设置 $superLevel = (int) Sysparam::getValue('superlevel', '100'); - $oldLevel = $user->user_level; - $leveledUp = false; - - if ($oldLevel < $superLevel) { - $newLevel = Sysparam::calculateLevel($user->exp_num); - if ($newLevel !== $oldLevel && $newLevel < $superLevel) { - $user->user_level = $newLevel; - $leveledUp = ($newLevel > $oldLevel); - } - } + $leveledUp = $this->calculateNewLevel($user, $superLevel); $user->save(); // 存点入库 @@ -506,12 +497,9 @@ class ChatController extends Controller $user->refresh(); // 重新计算等级(经验可能因事件而变化,但管理员不参与自动升降级) - if ($user->user_level < $superLevel) { - $recalcLevel = Sysparam::calculateLevel($user->exp_num); - if ($recalcLevel !== $user->user_level && $recalcLevel < $superLevel) { - $user->user_level = $recalcLevel; - $user->save(); - } + if ($this->calculateNewLevel($user, $superLevel)) { + $leveledUp = true; // 随机事件触发了升级,补充标记以便广播 + $user->save(); } // 广播随机事件消息到聊天室 @@ -576,11 +564,11 @@ class ChatController extends Controller $onlineCount = count($this->chatState->getRoomUsers($room->id)); return [ - 'id' => $room->id, - 'name' => $room->room_name, - 'online' => $onlineCount, + 'id' => $room->id, + 'name' => $room->room_name, + 'online' => $onlineCount, 'permit_level' => $room->permit_level ?? 0, - 'door_open' => (bool) $room->door_open, + 'door_open' => (bool) $room->door_open, ]; }); @@ -960,7 +948,7 @@ class ChatController extends Controller ->whereNull('logout_at') ->whereDate('login_at', today()) ->update([ - 'logout_at' => now(), + 'logout_at' => now(), 'duration_seconds' => DB::raw('GREATEST(0, TIMESTAMPDIFF(SECOND, login_at, NOW()))'), ]); @@ -970,7 +958,7 @@ class ChatController extends Controller ->whereNull('logout_at') ->whereDate('login_at', '<', today()) ->update([ - 'logout_at' => DB::raw('login_at'), // 时长 = 0 + 'logout_at' => DB::raw('login_at'), // 时长 = 0 'duration_seconds' => 0, ]); } @@ -1017,11 +1005,61 @@ class ChatController extends Controller : now(); PositionDutyLog::create([ - 'user_id' => $user->id, + 'user_id' => $user->id, 'user_position_id' => $activeUP->id, - 'login_at' => $loginAt, - 'ip_address' => request()->ip(), - 'room_id' => $roomId, + 'login_at' => $loginAt, + 'ip_address' => request()->ip(), + 'room_id' => $roomId, ]); } + + /** + * 根据经验值重新计算用户等级,申升减级均会直接修改 $user->user_level。 + * + * PHP 对象引用传递,方法内对 $user 的修改会直接反映到调用方。 + * 本方法不负责 save(),由调用方决定何时落库。 + * + * @param \App\Models\User $user 当前用户模型 + * @param int $superLevel 管理员等级阈值(达到后不参与自动升降级) + * @return bool 是否发生了升级(true = 等级提升) + */ + private function calculateNewLevel(\App\Models\User $user, int $superLevel): bool + { + // 管理员等级由后台手动维护,不参与自动升降级 + if ($user->user_level >= $superLevel) { + return false; + } + + $newLevel = Sysparam::calculateLevel($user->exp_num); + + // 等级无变化,或计算结果达到管理员阈值(异常情况),均跳过 + if ($newLevel === $user->user_level || $newLevel >= $superLevel) { + return false; + } + + $isLeveledUp = $newLevel > $user->user_level; + + // 在职职务成员:等级保护逻辑 + $activeUP = $user->activePosition; + if ($activeUP) { + $positionLevel = $activeUP->position->level ?? 0; + + // 职务要求高于当前等级 → 强制补级到职务最低要求 + if ($positionLevel > $user->user_level) { + $user->user_level = $positionLevel; + + return true; // 等级提升,调用方需保存并广播 + } + + // 降级 且 降后等级低于职务要求 → 阻止 + if (! $isLeveledUp && $newLevel < $positionLevel) { + return false; + } + } + + // PHP 对象引用传递,这里对 $user->user_level 的修改将直接反映到调用方 + $user->user_level = $newLevel; + + return $isLeveledUp; + } } diff --git a/app/Http/Controllers/RedPacketController.php b/app/Http/Controllers/RedPacketController.php index e4c7843..f39aea6 100644 --- a/app/Http/Controllers/RedPacketController.php +++ b/app/Http/Controllers/RedPacketController.php @@ -126,7 +126,10 @@ class RedPacketController extends Controller }); // 广播系统公告,含可点击「立即抢包」按钮 - $btnHtml = '