diff --git a/app/Http/Controllers/AdminCommandController.php b/app/Http/Controllers/AdminCommandController.php index 5f9a8bb..d2d9945 100644 --- a/app/Http/Controllers/AdminCommandController.php +++ b/app/Http/Controllers/AdminCommandController.php @@ -442,64 +442,73 @@ class AdminCommandController extends Controller return response()->json(['status' => 'error', 'message' => '不能给自己发放奖励'], 422); } - // 必须有在职职务且职务配置了 max_reward - $userPosition = $admin->activePosition; - if (! $userPosition) { - return response()->json(['status' => 'error', 'message' => '你当前没有在职职务,无权发放奖励'], 403); - } - - $position = $userPosition->position; - if (! $position?->max_reward) { - return response()->json(['status' => 'error', 'message' => '你的职务未配置奖励权限'], 403); - } - // 目标用户必须存在 $target = User::where('username', $targetUsername)->first(); if (! $target) { return response()->json(['status' => 'error', 'message' => '用户不存在'], 404); } - // ① 单次上限校验 - if ($amount > $position->max_reward) { - return response()->json([ - 'status' => 'error', - 'message' => "单次奖励上限为 {$position->max_reward} 金币,请调整金额", - ], 422); - } + // id=1 超级管理员:无需职务,无限额限制 + $isSuperAdmin = $admin->id === 1; + $userPosition = null; + $position = null; - // ② 操作人单日累计上限校验 - if ($position->daily_reward_limit) { - $todayTotal = PositionAuthorityLog::where('target_user_id', $target->id) - ->where('action_type', 'reward') - ->whereDate('created_at', today()) - ->sum('amount'); + if (! $isSuperAdmin) { + // ① 必须有在职职务 + $userPosition = $admin->activePosition; + if (! $userPosition) { + return response()->json(['status' => 'error', 'message' => '你当前没有在职职务,无权发放奖励'], 403); + } - if ($todayTotal + $amount > $position->daily_reward_limit) { - $remaining = max(0, $position->daily_reward_limit - $todayTotal); + $position = $userPosition->position; + // 职务 max_reward = 0 表示禁止,null 表示不限,正整数表示有上限 + if ($position?->max_reward === 0) { + return response()->json(['status' => 'error', 'message' => '你的职务未配置奖励权限'], 403); + } + + // ② 单次上限校验(max_reward > 0 时才限制,null = 不限) + if ($position->max_reward && $amount > $position->max_reward) { return response()->json([ 'status' => 'error', - 'message' => "今日剩余可发放额度为 {$remaining} 金币,超出单日上限({$position->daily_reward_limit})", + 'message' => "单次奖励上限为 {$position->max_reward} 金币,请调整金额", ], 422); } + + // ③ 操作人单日累计上限校验 + if ($position->daily_reward_limit) { + $todayTotal = PositionAuthorityLog::where('user_id', $admin->id) + ->where('action_type', 'reward') + ->whereDate('created_at', today()) + ->sum('amount'); + + if ($todayTotal + $amount > $position->daily_reward_limit) { + $remaining = max(0, $position->daily_reward_limit - $todayTotal); + + return response()->json([ + 'status' => 'error', + 'message' => "今日剩余可发放额度为 {$remaining} 金币,超出单日上限({$position->daily_reward_limit})", + ], 422); + } + } + + // ④ 职务级别:接收者每日次数上限 + if ($position->recipient_daily_limit) { + $recipientCount = PositionAuthorityLog::where('target_user_id', $target->id) + ->where('action_type', 'reward') + ->whereDate('created_at', today()) + ->count(); + + if ($recipientCount >= $position->recipient_daily_limit) { + return response()->json([ + 'status' => 'error', + 'message' => "{$targetUsername} 今日已由全体职务人员累计发放 {$recipientCount} 次奖励,已达每日上限({$position->recipient_daily_limit})", + ], 422); + } + } } - // ③ 同一接收者每日次数上限校验(统计今日所有职务持有者对该用户的累计发放次数) - if ($position->recipient_daily_limit) { - $recipientCount = PositionAuthorityLog::where('target_user_id', $target->id) - ->where('action_type', 'reward') - ->whereDate('created_at', today()) - ->count(); - - if ($recipientCount >= $position->recipient_daily_limit) { - return response()->json([ - 'status' => 'error', - 'message' => "{$targetUsername} 今日已由全体职务人员累计发放 {$recipientCount} 次奖励,已达每日上限({$position->recipient_daily_limit})", - ], 422); - } - } - - // ④ 全局系统级别:每位用户单日最多接收奖励次数(后台职务管理页统一配置) + // ⑤ 全局系统级别:每位用户单日最多接收奖励次数(所有操作人通用,含超管) $globalMax = (int) Sysparam::getValue('reward_recipient_daily_max', '0'); if ($globalMax > 0) { $globalCount = PositionAuthorityLog::where('target_user_id', $target->id) @@ -516,19 +525,20 @@ class AdminCommandController extends Controller } // 发放金币(通过 UserCurrencyService 原子性更新 + 写流水) + $positionName = $isSuperAdmin ? '超级管理员' : ($position->name ?? '职务'); $this->currencyService->change( $target, 'gold', $amount, CurrencySource::POSITION_REWARD, - "{$admin->username}({$position->name})职务奖励", + "{$admin->username}({$positionName})职务奖励", $roomId, ); - // 写履职记录(PositionAuthorityLog) + // 写履职记录(PositionAuthorityLog;超管无职务时 user_position_id 留 null) PositionAuthorityLog::create([ 'user_id' => $admin->id, - 'user_position_id' => $userPosition->id, + 'user_position_id' => $userPosition?->id, 'action_type' => 'reward', 'target_user_id' => $target->id, 'amount' => $amount, diff --git a/resources/views/chat/frame.blade.php b/resources/views/chat/frame.blade.php index aa9f4e6..3ebfb73 100644 --- a/resources/views/chat/frame.blade.php +++ b/resources/views/chat/frame.blade.php @@ -47,9 +47,14 @@ chatBotEnabled: {{ \App\Models\Sysparam::getValue('chatbot_enabled', '0') === '1' ? 'true' : 'false' }}, hasPosition: {{ Auth::user()->activePosition || Auth::user()->user_level >= $superLevel ? 'true' : 'false' }}, myMaxReward: @php - $pos = Auth::user()->activePosition?->position; - // -1 = 有权限但无上限(null),0 = 禁止,正整数 = 有具体上限 - echo $pos ? ($pos->max_reward === null ? -1 : (int) $pos->max_reward) : 0; + if (Auth::id() === 1) { + // 超级管理员(id=1)无需职务,直接拥有不限量奖励权 + echo -1; + } else { + $pos = Auth::user()->activePosition?->position; + // -1 = 有权限但无上限(null),0 = 禁止,正整数 = 有具体上限 + echo $pos ? ($pos->max_reward === null ? -1 : (int) $pos->max_reward) : 0; + } @endphp, appointPositionsUrl: "{{ route('chat.appoint.positions') }}", appointUrl: "{{ route('chat.appoint.appoint') }}",