table('QPAccountsDB.dbo.SystemStatusInfo') ->whereIn('StatusName', ['StockMode2BetLevels', 'StockMode2RevenueRatio', 'StockMode2SwitchRecharge']) ->get() ->keyBy('StatusName'); // 解析 StockMode2BetLevels $betLevelsString = $systemConfig['StockMode2BetLevels']->StatusString ?? '0|2|10|10000,0|0|100|1000'; $betLevelsParts = explode(',', $betLevelsString); $betMaxLimits = explode('|', $betLevelsParts[0] ?? '0|2|10|10000'); $rechargeMinLimits = explode('|', $betLevelsParts[1] ?? '0|0|100|1000'); // 获取 RoomStockStatic2 数据 $roomStocks = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->where('GameID', 0) ->orderBy('SortID') ->get(); return view('admin.stock_mode.index', compact( 'systemConfig', 'betMaxLimits', 'rechargeMinLimits', 'roomStocks' )); } /** * 更新系统配置参数 */ public function updateSystemConfig(Request $request) { try { $betMaxLimits = $request->input('bet_max_limits', []); $rechargeMinLimits = $request->input('recharge_min_limits', []); $revenueRatio = $request->input('revenue_ratio', 50); $switchRecharge = $request->input('switch_recharge', 100); // 构建 StockMode2BetLevels 的 StatusString $betMaxString = implode('|', $betMaxLimits); $rechargeMinString = implode('|', $rechargeMinLimits); $betLevelsString = $betMaxString . ',' . $rechargeMinString; // 更新 StockMode2BetLevels DB::connection('write') ->table('QPAccountsDB.dbo.SystemStatusInfo') ->where('StatusName', 'StockMode2BetLevels') ->update([ 'StatusString' => $betLevelsString, 'StatusValue' => 0 ]); // 更新 StockMode2RevenueRatio DB::connection('write') ->table('QPAccountsDB.dbo.SystemStatusInfo') ->where('StatusName', 'StockMode2RevenueRatio') ->update([ 'StatusValue' => $revenueRatio ]); // 更新 StockMode2SwitchRecharge DB::connection('write') ->table('QPAccountsDB.dbo.SystemStatusInfo') ->where('StatusName', 'StockMode2SwitchRecharge') ->update([ 'StatusValue' => $switchRecharge ]); \Log::info('库存模式系统配置更新成功', [ 'bet_levels' => $betLevelsString, 'revenue_ratio' => $revenueRatio, 'switch_recharge' => $switchRecharge ]); return response()->json(['status' => 'success', 'message' => '系统配置更新成功']); } catch (\Exception $e) { \Log::error('库存模式系统配置更新失败', ['error' => $e->getMessage()]); return response()->json(['status' => 'error', 'message' => '更新失败: ' . $e->getMessage()]); } } /** * 更新房间库存配置 */ public function updateRoomStock(Request $request) { try { $sortId = $request->input('sort_id'); $levelBase = $request->input('level_base'); if (!$sortId || !is_numeric($levelBase)) { return response()->json(['status' => 'error', 'message' => '参数错误']); } // 更新 RoomStockStatic2 $affected = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->where('GameID', 0) ->where('SortID', $sortId) ->update([ 'LevelBase' => $levelBase ]); if ($affected === 0) { // 如果没有记录,则插入新记录 DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->insert([ 'GameID' => 0, 'SortID' => $sortId, 'Stock' => 0, 'LevelBase' => $levelBase, 'Revenue' => 0, 'RevenueD' => 0 ]); } \Log::info('房间库存配置更新成功', [ 'sort_id' => $sortId, 'level_base' => $levelBase ]); return response()->json(['status' => 'success', 'message' => '房间库存配置更新成功']); } catch (\Exception $e) { \Log::error('房间库存配置更新失败', ['error' => $e->getMessage()]); return response()->json(['status' => 'error', 'message' => '更新失败: ' . $e->getMessage()]); } } /** * 更新库存(增减) */ public function updateStock(Request $request) { try { $sortId = $request->input('sort_id'); $adjustValue = $request->input('adjust_value'); // 已经是数据库值(前端已乘以100) if (!$sortId || !is_numeric($adjustValue)) { return response()->json(['status' => 'error', 'message' => '参数错误']); } // 使用 increment/decrement 方法更新库存 $query = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->where('GameID', 0) ->where('SortID', $sortId); if ($adjustValue > 0) { $query->increment('Stock', $adjustValue); } elseif ($adjustValue < 0) { $query->decrement('Stock', abs($adjustValue)); } // 获取更新后的库存值 $roomStock = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->where('GameID', 0) ->where('SortID', $sortId) ->first(); if (!$roomStock) { return response()->json(['status' => 'error', 'message' => '房间数据不存在']); } \Log::info('库存更新成功', [ 'sort_id' => $sortId, 'adjust_value' => $adjustValue, 'new_stock' => $roomStock->Stock ]); return response()->json([ 'status' => 'success', 'message' => '库存更新成功', 'new_stock' => $roomStock->Stock ]); } catch (\Exception $e) { \Log::error('库存更新失败', ['error' => $e->getMessage()]); return response()->json(['status' => 'error', 'message' => '更新失败: ' . $e->getMessage()]); } } /** * 获取房间库存统计信息 */ public function getRoomStockStats() { try { $roomStocks = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockStatic2') ->where('GameID', 0) ->orderBy('SortID') ->get(); return response()->json(['status' => 'success', 'data' => $roomStocks]); } catch (\Exception $e) { \Log::error('获取房间库存统计失败', ['error' => $e->getMessage()]); return response()->json(['status' => 'error', 'message' => '获取失败: ' . $e->getMessage()]); } } /** * 获取库存快照历史数据 */ public function getSnapshotHistory(Request $request) { try { $sortId = $request->input('sort_id', 1); $minutes = $request->input('minutes', 60); // 默认1小时 // 计算开始时间 $startTime = date('Y-m-d H:i:s', strtotime("-{$minutes} minutes")); // 查询起始时间之前的最后一条数据(用于填充前置空白) $previousSnapshot = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockSnapshot2') ->where('GameID', 0) ->where('SortID', $sortId) ->where('CreateTime', '<', $startTime) ->orderBy('CreateTime', 'desc') ->first(); // 查询时间范围内的快照数据 $snapshots = DB::connection('write') ->table('QPPlatformDB.dbo.RoomStockSnapshot2') ->where('GameID', 0) ->where('SortID', $sortId) ->where('CreateTime', '>=', $startTime) ->orderBy('CreateTime', 'asc') ->get(); // 处理数据 $data = []; // 添加前置数据(如果存在) if ($previousSnapshot) { $stock = $previousSnapshot->Stock; $levelBase = $previousSnapshot->LevelBase; $stockRatio = $levelBase > 0 ? round($stock / $levelBase, 2) : 0; $zValue = $this->calculateZValue($stock, $levelBase); $data[] = [ 'id' => $previousSnapshot->ID, 'stock' => round($stock / 100, 2), 'levelBase' => round($levelBase / 100, 2), 'revenue' => round($previousSnapshot->Revenue / 100, 2), 'revenueD' => round($previousSnapshot->RevenueD / 100, 2), 'stockChange' => round($previousSnapshot->StockChange / 100, 2), 'revenueChange' => round($previousSnapshot->RevenueChange / 100, 2), 'stockRatio' => $stockRatio, 'zValue' => $zValue, 'createTime' => $previousSnapshot->CreateTime, 'timestamp' => strtotime($previousSnapshot->CreateTime) * 1000, 'isPrevious' => true // 标记为前置数据 ]; } // 添加时间范围内的数据 foreach ($snapshots as $snapshot) { $stock = $snapshot->Stock; $levelBase = $snapshot->LevelBase; $stockRatio = $levelBase > 0 ? round($stock / $levelBase, 2) : 0; $zValue = $this->calculateZValue($stock, $levelBase); $data[] = [ 'id' => $snapshot->ID, 'stock' => round($stock / 100, 2), 'levelBase' => round($levelBase / 100, 2), 'revenue' => round($snapshot->Revenue / 100, 2), 'revenueD' => round($snapshot->RevenueD / 100, 2), 'stockChange' => round($snapshot->StockChange / 100, 2), 'revenueChange' => round($snapshot->RevenueChange / 100, 2), 'stockRatio' => $stockRatio, 'zValue' => $zValue, 'createTime' => $snapshot->CreateTime, 'timestamp' => strtotime($snapshot->CreateTime) * 1000, 'isPrevious' => false ]; } return response()->json(['status' => 'success', 'data' => $data]); } catch (\Exception $e) { \Log::error('获取快照历史失败', ['error' => $e->getMessage()]); return response()->json(['status' => 'error', 'message' => '获取失败: ' . $e->getMessage()]); } } /** * 计算 Z 值(个控) */ private function calculateZValue($stock, $levelBase) { if ($levelBase == 0) { return 0; } if ($stock < $levelBase * 2) { return 0; } elseif ($stock >= $levelBase * 2 && $stock < $levelBase * 4) { // 2x ~ 4x 区间:Z = FLOOR((stock - 2*base) / (2*base / 5)) + 1 $stockDiff = $stock - ($levelBase * 2); $baseStep = $levelBase * 2 / 5; $zValue = floor($stockDiff / $baseStep) + 1; return min(max($zValue, 1), 5); } elseif ($stock >= $levelBase * 4 && $stock < $levelBase * 6) { // 4x ~ 6x 区间 $stockDiff = $stock - ($levelBase * 4); $baseStep = $levelBase * 2 / 5; $zValue = floor($stockDiff / $baseStep) + 6; return min(max($zValue, 6), 10); } elseif ($stock >= $levelBase * 6 && $stock < $levelBase * 8) { // 6x ~ 8x 区间 $stockDiff = $stock - ($levelBase * 6); $baseStep = $levelBase * 2 / 5; $zValue = floor($stockDiff / $baseStep) + 11; return min(max($zValue, 11), 15); } else { // 8x+ 区间 $stockDiff = $stock - ($levelBase * 8); $baseStep = $levelBase * 4 / 5; $zValue = floor($stockDiff / $baseStep) + 16; return min(max($zValue, 16), 20); } } }