重构:提取 calculateNewLevel() 私有方法,增加在职职务等级保护逻辑
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,10 @@ class RedPacketController extends Controller
|
||||
});
|
||||
|
||||
// 广播系统公告,含可点击「立即抢包」按钮
|
||||
$btnHtml = '<button onclick="showRedPacketModal('
|
||||
// 注意这里不能死命传 self::EXPIRE_SECONDS,因为这句话会被存入数据库的历史记录。我们需要在取出来的时候能根据发包时间动态变化!
|
||||
// 啊等等!由于这条消息是直接静态写入 `chat_messages` 内容里的,这就意味着如果在这里计算,存进去的还是 300。
|
||||
// 所以我们还是传 `self::EXPIRE_SECONDS` 作为总寿命,在前端逻辑里利用 `Date.now()` 和消息的 `sent_at` 来算出真实剩余倒计时更为严谨!
|
||||
$btnHtml = '<button data-sent-at="'.time().'" onclick="showRedPacketModal('
|
||||
.$envelope->id
|
||||
.',\''.$user->username.'\','
|
||||
.self::TOTAL_AMOUNT.','
|
||||
|
||||
Reference in New Issue
Block a user