Tree 1 kuukausi sitten
vanhempi
sitoutus
9608c0ec41

+ 92 - 0
app/Http/Controllers/Admin/GameBuyBonusConfigController.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Redis;
+
+class GameBuyBonusConfigController
+{
+    /**
+     * Bonus购买回报配置列表(可编辑)
+     */
+    public function index(Request $request)
+    {
+        $configs = DB::connection('write')
+            ->table('QPPlatformDB.dbo.GameBuyBonusConfig')
+            ->orderBy('MultiMin', 'asc')
+            ->get();
+
+        return view('admin.game_buy_bonus_config.index', compact('configs'));
+    }
+
+    /**
+     * 批量更新配置(只更新有变动的数据)
+     */
+    public function update(Request $request)
+    {
+        try {
+            $configs = $request->input('configs', []);
+
+            if (empty($configs)) {
+                return apiReturnFail('没有需要更新的数据');
+            }
+
+            DB::beginTransaction();
+
+            $updatedIds = [];
+            $updatedCount = 0;
+            
+            foreach ($configs as $configId => $data) {
+                // 构建更新数据(只包含提交的字段)
+                $updateData = [];
+                
+                if (isset($data['MultiMin'])) {
+                    $updateData['MultiMin'] = round((float)$data['MultiMin'], 2);
+                }
+                if (isset($data['MultiMax'])) {
+                    $updateData['MultiMax'] = round((float)$data['MultiMax'], 2);
+                }
+                if (isset($data['Weight'])) {
+                    $updateData['Weight'] = (int)$data['Weight'];
+                }
+                if (isset($data['WeightAdjust'])) {
+                    $updateData['WeightAdjust'] = $data['WeightAdjust'];
+                }
+
+                // 只有有数据时才更新
+                if (!empty($updateData)) {
+                    DB::connection('write')
+                        ->table('QPPlatformDB.dbo.GameBuyBonusConfig')
+                        ->where('ConfigID', $configId)
+                        ->update($updateData);
+                    
+                    $updatedIds[] = $configId;
+                    $updatedCount++;
+                }
+            }
+
+            DB::commit();
+
+            // 清除可能的缓存
+            Redis::del('game_buy_bonus_config_cache');
+
+            \Log::info('Bonus购买回报配置更新成功', [
+                'admin_id' => $request->session()->get('admin')->id ?? 0,
+                'updated_count' => $updatedCount,
+                'config_ids' => $updatedIds
+            ]);
+
+            return apiReturnSuc("配置更新成功,共更新 {$updatedCount} 条数据");
+
+        } catch (\Exception $e) {
+            DB::rollBack();
+            \Log::error('Bonus购买回报配置更新失败', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            return apiReturnFail('更新失败: ' . $e->getMessage());
+        }
+    }
+}

+ 113 - 0
app/Http/Controllers/Admin/GameSomeConfigController.php

@@ -0,0 +1,113 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Redis;
+
+class GameSomeConfigController
+{
+    /**
+     * 个控回报配置列表(可编辑)
+     */
+    public function index(Request $request)
+    {
+        // 获取游戏ID,默认为0(通用配置)
+        $gameId = $request->input('game_id', 0);
+        
+        // 可选的游戏列表
+        $games = [
+            0 => '通用配置',
+            921219001 => 'IGT-双砖'
+        ];
+        
+        // 查询指定GameID的配置
+        $configs = DB::connection('write')
+            ->table('QPPlatformDB.dbo.GameSomeConfig')
+            ->where('GameID', $gameId)
+            ->orderBy('ZMin', 'asc')
+            ->orderBy('ZMax', 'asc')
+            ->orderBy('MultiMin', 'asc')
+            ->get();
+
+        return view('admin.game_some_config.index', compact('configs', 'games', 'gameId'));
+    }
+
+    /**
+     * 批量更新配置(只更新有变动的数据)
+     */
+    public function update(Request $request)
+    {
+        try {
+            $configs = $request->input('configs', []);
+
+            if (empty($configs)) {
+                return apiReturnFail('没有需要更新的数据');
+            }
+
+            DB::beginTransaction();
+
+            $updatedIds = [];
+            $updatedCount = 0;
+            
+            foreach ($configs as $configId => $data) {
+                // 构建更新数据(只包含提交的字段)
+                $updateData = [];
+                
+                if (isset($data['ZMin'])) {
+                    $updateData['ZMin'] = (int)$data['ZMin'];
+                }
+                if (isset($data['ZMax'])) {
+                    $updateData['ZMax'] = (int)$data['ZMax'];
+                }
+                if (isset($data['MultiMin'])) {
+                    $updateData['MultiMin'] = round((float)$data['MultiMin'], 2);
+                }
+                if (isset($data['MultiMax'])) {
+                    $updateData['MultiMax'] = round((float)$data['MultiMax'], 2);
+                }
+//                if (isset($data['MultiAvg'])) {
+//                    $updateData['MultiAvg'] = round((float)$data['MultiAvg'], 2);
+//                }
+                if (isset($data['Weight'])) {
+                    $updateData['Weight'] = (int)$data['Weight'];
+                }
+                if (isset($data['WeightAdjust'])) {
+                    $updateData['WeightAdjust'] = $data['WeightAdjust'];
+                }
+                
+                // Status字段不允许修改,已移除
+
+                // 只有有数据时才更新
+                if (!empty($updateData)) {
+                    DB::connection('write')
+                        ->table('QPPlatformDB.dbo.GameSomeConfig')
+                        ->where('ConfigID', $configId)
+                        ->update($updateData);
+                    
+                    $updatedIds[] = $configId;
+                    $updatedCount++;
+                }
+            }
+
+            DB::commit();
+
+            \Log::info('个控回报配置更新成功', [
+                'admin_id' => $request->session()->get('admin')->id ?? 0,
+                'updated_count' => $updatedCount,
+                'config_ids' => $updatedIds
+            ]);
+
+            return apiReturnSuc("配置更新成功,共更新 {$updatedCount} 条数据");
+
+        } catch (\Exception $e) {
+            DB::rollBack();
+            \Log::error('个控回报配置更新失败', [
+                'error' => $e->getMessage(),
+                'trace' => $e->getTraceAsString()
+            ]);
+            return apiReturnFail('更新失败: ' . $e->getMessage());
+        }
+    }
+}

+ 92 - 18
app/Http/Controllers/Game/PayRechargeController.php

@@ -160,7 +160,7 @@ class PayRechargeController extends Controller
                         
                         if ($expireDate !== $currentDate) {
                             // 进入阶段2
-                            $nextDayStart = strtotime($expireDate . ' +1 day 00:00:00');
+                            $nextDayStart = time();
                             $newExpireTime = $nextDayStart + ($giftConfig->valid_h_2 * 3600);
                             
                             $newTimerData = [
@@ -187,7 +187,7 @@ class PayRechargeController extends Controller
                         $currentDate = date('Y-m-d', $currentTime);
                         
                         if ($expireDate !== $currentDate) {
-                            $todayStart = strtotime($currentDate . ' 00:00:00');
+                            $todayStart = time();
                             $newExpireTime = $todayStart + ($giftConfig->valid_h_2 * 3600);
                             
                             $newTimerData = [
@@ -271,27 +271,64 @@ class PayRechargeController extends Controller
         
         // 每日奖励进度
         if ($dayRewardsData) {
+            // 计算当前是购买后的第几天
+            $purchaseDate = date('Y-m-d', strtotime($giftRecord->created_at));
+            $today = date('Y-m-d');
+            $daysPassed = floor((strtotime($today) - strtotime($purchaseDate)) / 86400);
+            
+            $startDay = $dayRewardsData['start_day'] ?? 1;
+            $bonusDay = $dayRewardsData['bonus_day'] ?? 0;
+            $claimedDays = $giftRecord->day_rewards_claimed;
+            
+            // 判断每日奖励状态
+            // 0=不可领取, 1=可领取, 2=已领取, 3=过期
+            $dayRewardStatus = 0;  // 默认不可领取
+            
+            // 检查是否过期(购买后7天)
+            if ($daysPassed >= 7) {
+                $dayRewardStatus = 3;  // 过期
+            } elseif ($daysPassed >= $startDay) {
+                // 计算今天是第几个奖励日(从起始天数开始)
+                $rewardIndex = $daysPassed - $startDay;
+                
+                if ($rewardIndex < $bonusDay) {
+                    // 在奖励期内
+                    if ($claimedDays > $rewardIndex) {
+                        $dayRewardStatus = 2;  // 已领取
+                    } elseif ($claimedDays == $rewardIndex) {
+                        $dayRewardStatus = 1;  // 可领取
+                    } else {
+                        $dayRewardStatus = 0;  // 不可领取(前面的天数未领或已过期)
+                    }
+                } else {
+                    // 超过奖励天数
+                    $dayRewardStatus = 2;  // 已领取完
+                }
+            }
+            
             $giftInfo['day_rewards'] = [
                 'total_bonus' => (float)$giftRecord->day_rewards_total,
-                'bonus_day' => $dayRewardsData['bonus_day'] ?? 0,
-                'start_day' => $dayRewardsData['start_day'] ?? 1,
+                'bonus_day' => $bonusDay,
+                'start_day' => $startDay,
                 'bonus' => $dayRewardsData['bonus'] ?? [],
-                'claimed_days' => $giftRecord->day_rewards_claimed,  // 已领取天数
-                'progress' => $giftRecord->day_rewards_claimed . '/' . ($dayRewardsData['bonus_day'] ?? 0)
+                'claimed_days' => $claimedDays,
+                'progress' => $claimedDays . '/' . $bonusDay,
+                'status' => $dayRewardStatus,  // 0=不可领取, 1=可领取, 2=已领取, 3=过期
+                'status_text' => ['不可领取', '可领取', '已领取', '过期'][$dayRewardStatus] ?? '未知'
             ];
         }
         
         // 下注奖励进度
         if ($bettingBonusData) {
             $perBet = $bettingBonusData['per_bet'] ?? 100;  // 每次下注要求
-            $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2;  // 每次奖励百分比
+            $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2;  // 每次奖励金额(不是百分比
             $currentBet = $giftRecord->betting_current_bet;  // 当前累计下注
             $totalBonusLimit = $giftRecord->betting_bonus_total;  // 总奖励上限
             $claimedAmount = $giftRecord->betting_bonus_claimed;  // 已领取金额
             $remainingBonus = $totalBonusLimit - $claimedAmount;  // 剩余可领取金额
             
-            // 每次可领取的金额
-            $perReward = round($giftRecord->pay_amount * $perBetBonus / 100, 2);
+            // 每次可领取的金额(直接使用配置的值,不是百分比计算)
+            $perReward = (float)$perBetBonus;
             
             // 根据当前下注计算已达成的次数
             $completedTimes = floor($currentBet / $perBet);
@@ -304,6 +341,9 @@ class PayRechargeController extends Controller
             $maxCanClaimTimes = floor($remainingBonus / $perReward);  // 剩余总额最多可领次数
             $canClaimTimes = min($canClaimTimes, $maxCanClaimTimes);
             
+            // 当前可领取金额
+            $canClaimAmount = min($canClaimTimes * $perReward, $remainingBonus);
+            
             // 计算下次领取需要的下注金额
             $nextClaimBet = 0;
             if ($remainingBonus > 0 && $canClaimTimes == 0) {
@@ -311,17 +351,35 @@ class PayRechargeController extends Controller
                 $nextClaimBet = ($claimedTimes + 1) * $perBet - $currentBet;
             }
             
+            // 判断下注奖励状态
+            // 0=不可领取(可领取金额为0), 1=可领取, 2=已领取(所有奖励都领完), 3=过期
+            $bettingBonusStatus = 0;  // 默认不可领取
+            
+            // 检查是否过期(购买后7天)
+            if ($daysPassed >= 7) {
+                $bettingBonusStatus = 3;  // 过期
+            } elseif ($remainingBonus <= 0) {
+                $bettingBonusStatus = 2;  // 已领取完
+            } elseif ($canClaimAmount > 0) {
+                $bettingBonusStatus = 1;  // 可领取
+            } else {
+                $bettingBonusStatus = 0;  // 不可领取(下注不足)
+            }
+            
             $giftInfo['betting_bonus'] = [
                 'total_bonus' => (float)$totalBonusLimit,  // 总奖励上限
                 'per_bet' => $perBet,  // 每次下注要求
-                'per_bet_bonus' => $perBetBonus,  // 每次奖励百分比
-                'per_reward' => $perReward,  // 每次奖励金额
+                'per_bet_bonus' => $perReward,  // 每次奖励金额(实际金额)
+//                'per_reward' => $perReward,  // 每次奖励金额(保持兼容)
                 'current_bet' => (float)$currentBet,  // 当前累计下注
                 'claimed_amount' => (float)$claimedAmount,  // 已领取金额
                 'remaining_bonus' => (float)$remainingBonus,  // 剩余可领金额
+                'can_claim_amount' => (float)$canClaimAmount,  // 当前可领取金额
                 'can_claim_times' => max(0, $canClaimTimes),  // 当前可领取次数
                 'next_claim_bet' => max(0, $nextClaimBet),  // 下次领取还需下注
-                'progress' => round($currentBet, 2) . '/' . round($claimedTimes * $perBet + $perBet, 2)  // 当前进度/下次领取目标
+                'progress' => round($currentBet, 2) . '/' . round($claimedTimes * $perBet + $perBet, 2),  // 当前进度/下次领取目标
+                'status' => $bettingBonusStatus,  // 0=不可领取, 1=可领取, 2=已领取, 3=过期
+                'status_text' => ['不可领取', '可领取', '已领取', '过期'][$bettingBonusStatus] ?? '未知'
             ];
         }
         
@@ -331,15 +389,31 @@ class PayRechargeController extends Controller
             $requiredBet = $giftRecord->pay_amount * $betPayTimes;
             $currentProgress = $giftRecord->betting_current_bet;
             $taskCompleted = $currentProgress >= $requiredBet;
+            $isClaimed = $giftRecord->betting_task_claimed == 1;
+            
+            // 判断下注任务状态
+            // 0=不可领取, 1=可领取, 2=已领取, 3=过期
+            $bettingTaskStatus = 0;  // 默认不可领取
+            
+            // 检查是否过期(购买后7天)
+            if ($daysPassed >= 7) {
+                $bettingTaskStatus = 3;  // 过期
+            } elseif ($isClaimed) {
+                $bettingTaskStatus = 2;  // 已领取
+            } elseif ($taskCompleted) {
+                $bettingTaskStatus = 1;  // 可领取(任务完成且未领取)
+            } else {
+                $bettingTaskStatus = 0;  // 不可领取(任务未完成)
+            }
             
             $giftInfo['betting_task'] = [
                 'total_bonus' => (float)$giftRecord->betting_task_total,
                 'bet_pay_times' => $betPayTimes,
                 'required_bet' => $requiredBet,  // 需要下注的金额
                 'current_bet' => (float)$currentProgress,  // 当前累计下注
-                'claimed' => $giftRecord->betting_task_claimed == 1,  // 是否已领取
-                'can_claim' => $taskCompleted && $giftRecord->betting_task_claimed == 0,  // 可否领取
-                'progress' => round($currentProgress, 2) . '/' . $requiredBet
+                'progress' => round($currentProgress, 2) . '/' . $requiredBet,
+                'status' => $bettingTaskStatus,  // 0=不可领取, 1=可领取, 2=已领取, 3=过期
+                'status_text' => ['不可领取', '可领取', '已领取', '过期'][$bettingTaskStatus] ?? '未知'
             ];
         }
         
@@ -441,7 +515,7 @@ class PayRechargeController extends Controller
                 }
                 
                 $perBet = $bettingBonusData['per_bet'] ?? 100;  // 每次下注要求
-                $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2;  // 每次奖励百分比
+                $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2;  // 每次奖励金额(不是百分比
                 $currentBet = $giftRecord->betting_current_bet;  // 当前累计下注
                 $totalBonusLimit = $giftRecord->betting_bonus_total;  // 总奖励上限
                 $claimedAmount = $giftRecord->betting_bonus_claimed;  // 已领取金额
@@ -452,8 +526,8 @@ class PayRechargeController extends Controller
                     return apiReturnFail('下注奖励已全部领取');
                 }
                 
-                // 每次可领取的金额
-                $perReward = round($giftRecord->pay_amount * $perBetBonus / 100, 2);
+                // 每次可领取的金额(直接使用配置的值,不是百分比计算)
+                $perReward = (float)$perBetBonus;
                 
                 // 根据当前下注计算已达成的次数
                 $completedTimes = floor($currentBet / $perBet);

+ 258 - 0
resources/views/admin/game_buy_bonus_config/index.blade.php

@@ -0,0 +1,258 @@
+@extends('base.base')
+@section('base')
+<div class="main-panel">
+    <div class="content-wrapper">
+        <div class="row">
+            <div class="col-12 grid-margin stretch-card">
+                <div class="card">
+                    <div class="card-body">
+                        <h4 class="card-title">Bonus购买回报配置</h4>
+                        <p class="card-description">配置Bonus购买时的倍率和权重</p>
+
+<style>
+    .table-wrapper {
+        max-height: calc(100vh - 250px);
+        overflow-y: auto;
+        position: relative;
+        border: 1px solid #ddd;
+    }
+    
+    .config-table {
+        width: 100%;
+        border-collapse: collapse;
+        margin: 0;
+        background: #fff;
+    }
+    
+    .config-table th,
+    .config-table td {
+        border: 1px solid #ddd;
+        padding: 10px;
+        text-align: center;
+        font-size: 14px;
+    }
+    
+    .config-table thead {
+        position: sticky;
+        top: 0;
+        z-index: 100;
+    }
+    
+    .config-table th {
+        background-color: #4CAF50;
+        color: white;
+        font-weight: bold;
+        position: sticky;
+        top: 0;
+        box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4);
+    }
+    
+    .config-table tbody tr:nth-child(even) {
+        background-color: #f9f9f9;
+    }
+    
+    .config-table tbody tr:hover {
+        background-color: #f0f0f0;
+    }
+    
+    .config-table input[type="number"],
+    .config-table input[type="text"] {
+        width: 95%;
+        padding: 5px;
+        border: 1px solid transparent;
+        border-radius: 3px;
+        text-align: center;
+        background: transparent;
+        cursor: pointer;
+    }
+    
+    .config-table input[type="number"]:focus,
+    .config-table input[type="text"]:focus {
+        border: 1px solid #4CAF50;
+        background: #fff;
+        outline: none;
+        box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
+    }
+    
+    .config-table input[type="number"]:read-only,
+    .config-table input[type="text"]:read-only {
+        cursor: pointer;
+    }
+    
+    .editable-cell {
+        cursor: pointer;
+        position: relative;
+    }
+    
+    .editable-cell:hover::after {
+        content: '✎';
+        position: absolute;
+        right: 5px;
+        top: 50%;
+        transform: translateY(-50%);
+        color: #4CAF50;
+        font-size: 14px;
+    }
+    
+    .field-label {
+        color: #ccc;
+        font-size: 11px;
+    }
+    
+    /* 滚动条美化 */
+    .table-wrapper::-webkit-scrollbar {
+        width: 8px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-track {
+        background: #f1f1f1;
+        border-radius: 4px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-thumb {
+        background: #888;
+        border-radius: 4px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-thumb:hover {
+        background: #555;
+    }
+</style>
+
+<form id="configForm">
+    <div class="table-wrapper">
+        <table class="config-table">
+            <thead>
+                <tr>
+                    <th>ID</th>
+                    <th>倍率最小<br><span class="field-label">(MultiMin)</span></th>
+                    <th>倍率最大<br><span class="field-label">(MultiMax)</span></th>
+                    <th>权重<br><span class="field-label">(Weight)</span></th>
+                    <th>权重调节<br><span class="field-label">(WeightAdjust)</span></th>
+                </tr>
+            </thead>
+            <tbody>
+            @foreach($configs as $config)
+                <tr>
+                    <td>{{ $config->ConfigID }}</td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][MultiMin]" 
+                               value="{{ number_format($config->MultiMin, 2, '.', '') }}" 
+                               min="0" 
+                               step="0.01">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][MultiMax]" 
+                               value="{{ number_format($config->MultiMax, 2, '.', '') }}" 
+                               min="0" 
+                               step="0.01">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][Weight]" 
+                               value="{{ $config->Weight }}" 
+                               min="0" 
+                               step="1">
+                    </td>
+                    <td>
+                        <input type="text" 
+                               name="configs[{{ $config->ConfigID }}][WeightAdjust]" 
+                               value="{{ $config->WeightAdjust }}" 
+                               placeholder="如: 10Z"
+                               style="width: 120px;">
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    </div>
+
+    <div style="text-align: center; margin: 20px 0;">
+        <button type="button" class="btn btn-primary btn-lg" onclick="saveConfig()">保存配置</button>
+    </div>
+</form>
+
+<script>
+// 保存原始数据
+const originalData = {};
+
+$(document).ready(function() {
+    // 记录所有字段的原始值
+    $('input[name^="configs"]').each(function() {
+        const name = $(this).attr('name');
+        originalData[name] = $(this).val();
+        // 设置为只读,点击后才能编辑
+        $(this).attr('readonly', true);
+    });
+    
+    // 点击input时移除只读,进入编辑模式
+    $('input[type="number"], input[type="text"]').on('click', function() {
+        $(this).attr('readonly', false);
+        $(this).select();  // 选中内容,方便修改
+    });
+    
+    // 失去焦点时恢复只读
+    $('input[type="number"], input[type="text"]').on('blur', function() {
+        $(this).attr('readonly', true);
+    });
+});
+
+function saveConfig() {
+    // 收集有变动的数据
+    const changedData = {};
+    let hasChanges = false;
+    
+    $('input[name^="configs"]').each(function() {
+        const name = $(this).attr('name');
+        const currentValue = $(this).val();
+        
+        // 只添加有变动的字段
+        if (originalData[name] !== currentValue) {
+            changedData[name] = currentValue;
+            hasChanges = true;
+        }
+    });
+    
+    if (!hasChanges) {
+        layer.msg('没有数据被修改', {icon: 0});
+        return;
+    }
+    
+    // 构建只包含变动数据的表单
+    const formData = $.param(changedData);
+    
+    layer.msg('正在保存 ' + Object.keys(changedData).length + ' 个变动...', {icon: 16, time: 0, shade: 0.3});
+    
+    $.ajax({
+        url: '/admin/game-buy-bonus-config/update',
+        type: 'POST',
+        data: formData,
+        dataType: 'json',
+        success: function(res) {
+            layer.closeAll();
+            if (res.code === 200) {
+                layer.msg('配置更新成功!', {icon: 1});
+                setTimeout(function() {
+                    location.reload();
+                }, 1000);
+            } else {
+                layer.msg('更新失败: ' + (res.msg || '未知错误'), {icon: 2});
+            }
+        },
+        error: function(xhr) {
+            layer.closeAll();
+            layer.msg('请求失败: ' + xhr.statusText, {icon: 2});
+        }
+    });
+}
+</script>
+
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 364 - 0
resources/views/admin/game_some_config/index.blade.php

@@ -0,0 +1,364 @@
+@extends('base.base')
+@section('base')
+<div class="main-panel">
+    <div class="content-wrapper">
+        <div class="row">
+            <div class="col-12 grid-margin stretch-card">
+                <div class="card">
+                    <div class="card-body">
+                        <h4 class="card-title">个控回报配置</h4>
+                        <p class="card-description">配置不同个控区间和倍率的权重调节</p>
+                        
+                        <!-- 游戏选择 -->
+                        <div class="form-group" style="margin-bottom: 20px;">
+                            <label for="game_select" style="font-weight: bold; margin-right: 10px;">选择游戏:</label>
+                            <select id="game_select" class="form-control" style="width: 300px; display: inline-block;" onchange="switchGame(this.value)">
+                                @foreach($games as $id => $name)
+                                    <option value="{{ $id }}" {{ $id == $gameId ? 'selected' : '' }}>
+                                        {{ $name }} (GameID: {{ $id }})
+                                    </option>
+                                @endforeach
+                            </select>
+                            <span style="margin-left: 20px; color: #666;">
+                                当前显示:<strong>{{ $games[$gameId] ?? 'Unknown' }}</strong> 的配置
+                            </span>
+                        </div>
+
+<style>
+    .table-wrapper {
+        max-height: calc(100vh - 250px);
+        overflow-y: auto;
+        position: relative;
+        border: 1px solid #ddd;
+    }
+    
+    .config-table {
+        width: 100%;
+        border-collapse: collapse;
+        margin: 0;
+        background: #fff;
+    }
+    
+    .config-table th,
+    .config-table td {
+        border: 1px solid #ddd;
+        padding: 8px;
+        text-align: center;
+        font-size: 14px;
+    }
+    
+    .config-table thead {
+        position: sticky;
+        top: 0;
+        z-index: 100;
+    }
+    
+    .config-table th {
+        background-color: #4CAF50;
+        color: white;
+        font-weight: bold;
+        position: sticky;
+        top: 0;
+        box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4);
+    }
+    
+    .config-table tbody tr:nth-child(even) {
+        background-color: #f9f9f9;
+    }
+    
+    .config-table tbody tr:hover {
+        background-color: #f0f0f0;
+    }
+    
+    .config-table input[type="number"],
+    .config-table input[type="text"] {
+        width: 95%;
+        padding: 5px;
+        border: 1px solid transparent;
+        border-radius: 3px;
+        text-align: center;
+        background: transparent;
+        cursor: pointer;
+    }
+    
+    .config-table input[type="number"]:focus,
+    .config-table input[type="text"]:focus {
+        border: 1px solid #4CAF50;
+        background: #fff;
+        outline: none;
+        box-shadow: 0 0 5px rgba(76, 175, 80, 0.3);
+    }
+    
+    .config-table input[type="number"]:read-only,
+    .config-table input[type="text"]:read-only {
+        cursor: pointer;
+    }
+    
+    .config-table input[type="checkbox"] {
+        width: 20px;
+        height: 20px;
+        cursor: pointer;
+    }
+    
+    .editable-cell {
+        cursor: pointer;
+        position: relative;
+    }
+    
+    .editable-cell:hover::after {
+        content: '✎';
+        position: absolute;
+        right: 5px;
+        top: 50%;
+        transform: translateY(-50%);
+        color: #4CAF50;
+        font-size: 14px;
+    }
+    
+    .group-header {
+        background-color: #2196F3 !important;
+        color: white !important;
+        font-weight: bold;
+        position: sticky;
+        z-index: 50;
+    }
+    
+    .field-label {
+        color: #ccc;
+        font-size: 11px;
+    }
+    
+    /* 滚动条美化 */
+    .table-wrapper::-webkit-scrollbar {
+        width: 8px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-track {
+        background: #f1f1f1;
+        border-radius: 4px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-thumb {
+        background: #888;
+        border-radius: 4px;
+    }
+    
+    .table-wrapper::-webkit-scrollbar-thumb:hover {
+        background: #555;
+    }
+</style>
+
+<form id="configForm">
+    <div class="table-wrapper">
+        <table class="config-table">
+            <thead>
+                <tr>
+                    <th>ID</th>
+                    <th>个控最小值<br><span class="field-label">(ZMin)</span></th>
+                    <th>个控最大值<br><span class="field-label">(ZMax)</span></th>
+                    <th>倍率最小<br><span class="field-label">(MultiMin)</span></th>
+                    <th>倍率最大<br><span class="field-label">(MultiMax)</span></th>
+                    <th>权重<br><span class="field-label">(Weight)</span></th>
+                    <th>个控调节<br><span class="field-label">(WeightAdjust)</span></th>
+                </tr>
+            </thead>
+            <tbody>
+            @if(count($configs) == 0)
+                <tr>
+                    <td colspan="7" style="text-align: center; padding: 40px; color: #999;">
+                        <i class="mdi mdi-alert-circle" style="font-size: 48px;"></i>
+                        <p style="margin-top: 10px; font-size: 16px;">该游戏暂无配置数据</p>
+                    </td>
+                </tr>
+            @else
+            @php
+                $currentGroup = null;
+            @endphp
+            @foreach($configs as $config)
+                @php
+                    $groupKey = $config->ZMin . '-' . $config->ZMax;
+                    $isNewGroup = ($groupKey !== $currentGroup);
+                    $currentGroup = $groupKey;
+                @endphp
+                
+                @if($isNewGroup)
+                    <tr class="group-header">
+                        <td colspan="7">个控区间:{{ $config->ZMin }} - {{ $config->ZMax }}</td>
+                    </tr>
+                @endif
+                
+                <tr>
+                    <td>{{ $config->ConfigID }}</td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][ZMin]" 
+                               value="{{ $config->ZMin }}" 
+                               min="0" 
+                               step="1">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][ZMax]" 
+                               value="{{ $config->ZMax }}" 
+                               min="0" 
+                               step="1">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][MultiMin]" 
+                               value="{{ number_format($config->MultiMin, 2, '.', '') }}" 
+                               min="0" 
+                               step="0.01">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][MultiMax]" 
+                               value="{{ number_format($config->MultiMax, 2, '.', '') }}" 
+                               min="0" 
+                               step="0.01">
+                    </td>
+                    <td>
+                        <input type="number" 
+                               name="configs[{{ $config->ConfigID }}][Weight]" 
+                               value="{{ $config->Weight }}" 
+                               min="0" 
+                               step="1">
+                    </td>
+                    <td>
+                        <input type="text" 
+                               name="configs[{{ $config->ConfigID }}][WeightAdjust]" 
+                               value="{{ $config->WeightAdjust }}" 
+                               placeholder="如: 15000-300Z"
+                               style="width: 120px;">
+                    </td>
+                </tr>
+            @endforeach
+            @endif
+            </tbody>
+        </table>
+    </div>
+
+    @if(count($configs) > 0)
+    <div style="text-align: center; margin: 20px 0;">
+        <button type="button" class="btn btn-primary btn-lg" onclick="saveConfig()">保存配置</button>
+    </div>
+    @endif
+</form>
+
+<script>
+// 切换游戏
+function switchGame(gameId) {
+    // 检查是否有未保存的修改
+    let hasUnsavedChanges = false;
+    $('input[name^="configs"]').each(function() {
+        const name = $(this).attr('name');
+        const currentValue = $(this).val();
+        if (originalData[name] && originalData[name] !== currentValue) {
+            hasUnsavedChanges = true;
+            return false; // break
+        }
+    });
+    
+    if (hasUnsavedChanges) {
+        if (!confirm('有未保存的修改,确定要切换游戏吗?')) {
+            // 恢复选择
+            $('#game_select').val('{{ $gameId }}');
+            return;
+        }
+    }
+    
+    // 切换到选择的游戏
+    window.location.href = '/admin/game-some-config?game_id=' + gameId;
+}
+
+// 保存原始数据
+const originalData = {};
+
+$(document).ready(function() {
+    // 记录所有字段的原始值
+    $('input[name^="configs"]').each(function() {
+        const name = $(this).attr('name');
+        if ($(this).attr('type') === 'checkbox') {
+            originalData[name] = $(this).prop('checked');
+        } else {
+            originalData[name] = $(this).val();
+            // 设置为只读,点击后才能编辑
+            $(this).attr('readonly', true);
+        }
+    });
+    
+    // 点击input时移除只读,进入编辑模式
+    $('input[type="number"], input[type="text"]').on('click', function() {
+        $(this).attr('readonly', false);
+        $(this).select();  // 选中内容,方便修改
+    });
+    
+    // 失去焦点时恢复只读
+    $('input[type="number"], input[type="text"]').on('blur', function() {
+        $(this).attr('readonly', true);
+    });
+});
+
+function saveConfig() {
+    // 收集有变动的数据
+    const changedData = {};
+    let hasChanges = false;
+    
+    $('input[name^="configs"]').each(function() {
+        const name = $(this).attr('name');
+        let currentValue;
+        
+        if ($(this).attr('type') === 'checkbox') {
+            currentValue = $(this).prop('checked');
+        } else {
+            currentValue = $(this).val();
+        }
+        
+        // 只添加有变动的字段
+        if (originalData[name] !== currentValue) {
+            changedData[name] = currentValue;
+            hasChanges = true;
+        }
+    });
+    
+    if (!hasChanges) {
+        layer.msg('没有数据被修改', {icon: 0});
+        return;
+    }
+    
+    // 构建只包含变动数据的表单
+    const formData = $.param(changedData);
+    
+    layer.msg('正在保存 ' + Object.keys(changedData).length + ' 个变动...', {icon: 16, time: 0, shade: 0.3});
+    
+    $.ajax({
+        url: '/admin/game-some-config/update',
+        type: 'POST',
+        data: formData,
+        dataType: 'json',
+        success: function(res) {
+            layer.closeAll();
+            if (res.code === 200) {
+                layer.msg('配置更新成功!', {icon: 1});
+                setTimeout(function() {
+                    location.reload();
+                }, 1000);
+            } else {
+                layer.msg('更新失败: ' + (res.msg || '未知错误'), {icon: 2});
+            }
+        },
+        error: function(xhr) {
+            layer.closeAll();
+            layer.msg('请求失败: ' + xhr.statusText, {icon: 2});
+        }
+    });
+}
+</script>
+
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 8 - 0
routes/web.php

@@ -726,6 +726,14 @@ Route::group([
         $route->any('/common-config/update', 'Admin\CommonConfigController@update')->name('admin.common-config.update');
         $route->any('/pg-game-config/update', 'Admin\PGGameConfigController@update')->name('admin.pg-game-config.update');
         $route->post('/pg-game-config/copy_all', 'Admin\PGGameConfigController@copyAll')->name('admin.pg-game-config.copy_all');
+        
+        // 个控回报配置
+        $route->any('/game-some-config', 'Admin\GameSomeConfigController@index')->name('admin.game-some-config');
+        $route->post('/game-some-config/update', 'Admin\GameSomeConfigController@update')->name('admin.game-some-config.update');
+        
+        // Bonus购买回报配置
+        $route->any('/game-buy-bonus-config', 'Admin\GameBuyBonusConfigController@index')->name('admin.game-buy-bonus-config');
+        $route->post('/game-buy-bonus-config/update', 'Admin\GameBuyBonusConfigController@update')->name('admin.game-buy-bonus-config.update');
         // PG游戏参数配置
         $route->any('/jl-game-config', 'Admin\JLGameConfigController@index')->name('admin.jl-game-config');
         $route->any('/jl-game-config/update', 'Admin\JLGameConfigController@update')->name('admin.jl-game-config.update');