GameSomeConfigController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Facades\DB;
  5. class GameSomeConfigController
  6. {
  7. const CONFIG_TABLE = 'QPPlatformDB.dbo.GameSomeConfig';
  8. // 游戏卡片来源表(与 /admin/game_site/builder 游戏卡片编辑保持一致)
  9. const GAME_TABLE = 'webgame.games';
  10. /**
  11. * 品牌厂商分组:展示名 => webgame.games.brand 中对应的取值。
  12. * 取值与 webgame.games.brand 实际存储一致;如后续新增厂商在此追加即可。
  13. */
  14. private static $brandGroups = [
  15. 'PGSoft' => ['PGSoft'],
  16. 'JILI' => ['JILI'],
  17. 'PragmaticPlay' => ['PP'],
  18. 'IGT' => ['IGT'],
  19. 'Hacksaw' => ['Hacksaw'],
  20. ];
  21. /**
  22. * 个控回报配置列表(可编辑)
  23. */
  24. public function index(Request $request)
  25. {
  26. // 获取游戏ID,默认为0(通用配置)
  27. $gameId = (int)$request->input('game_id', 0);
  28. // 获取库存模式,默认为1(普通模式)
  29. $stockMode = (int)$request->input('stock_mode', 1);
  30. if (!in_array($stockMode, [1, 2])) {
  31. $stockMode = 1;
  32. }
  33. // 按品牌分组的开放游戏列表
  34. $groupedGames = $this->getOpenGamesGroupedByBrand();
  35. $games = [0 => '通用配置'];
  36. foreach ($groupedGames as $brandGames) {
  37. foreach ($brandGames as $game) {
  38. $games[$game['id']] = $game['name'];
  39. }
  40. }
  41. if (!array_key_exists($gameId, $games)) {
  42. $gameId = 0;
  43. }
  44. // 查询指定GameID和StockMode的配置
  45. $configs = DB::connection('write')
  46. ->table(self::CONFIG_TABLE)
  47. ->where('GameID', $gameId)
  48. ->where('StockMode', $stockMode)
  49. ->orderBy('ZMin', 'asc')
  50. ->orderBy('ZMax', 'asc')
  51. ->orderBy('MultiMin', 'asc')
  52. ->get();
  53. return view('admin.game_some_config.index', compact('configs', 'games', 'groupedGames', 'gameId', 'stockMode'));
  54. }
  55. /**
  56. * 批量更新配置(只更新有变动的数据)
  57. */
  58. public function update(Request $request)
  59. {
  60. $db = DB::connection('write');
  61. try {
  62. $configs = $request->input('configs', []);
  63. if (empty($configs)) {
  64. return apiReturnFail('没有需要更新的数据');
  65. }
  66. $db->beginTransaction();
  67. $updatedIds = [];
  68. $updatedCount = 0;
  69. foreach ($configs as $configId => $data) {
  70. // 构建更新数据(只包含提交的字段)
  71. $updateData = [];
  72. if (isset($data['ZMin'])) {
  73. $updateData['ZMin'] = (int)$data['ZMin'];
  74. }
  75. if (isset($data['ZMax'])) {
  76. $updateData['ZMax'] = (int)$data['ZMax'];
  77. }
  78. if (isset($data['MultiMin'])) {
  79. $updateData['MultiMin'] = round((float)$data['MultiMin'], 2);
  80. }
  81. if (isset($data['MultiMax'])) {
  82. $updateData['MultiMax'] = round((float)$data['MultiMax'], 2);
  83. }
  84. // if (isset($data['MultiAvg'])) {
  85. // $updateData['MultiAvg'] = round((float)$data['MultiAvg'], 2);
  86. // }
  87. if (isset($data['Weight'])) {
  88. $updateData['Weight'] = (int)$data['Weight'];
  89. }
  90. // 个控调节支持配置为空(使用 array_key_exists 以支持空字符串)
  91. if (array_key_exists('WeightAdjust', $data)) {
  92. $updateData['WeightAdjust'] = (string)($data['WeightAdjust'] ?? '');
  93. }
  94. // Status字段不允许修改,已移除
  95. // 只有有数据时才更新
  96. if (!empty($updateData)) {
  97. $db->table(self::CONFIG_TABLE)
  98. ->where('ConfigID', $configId)
  99. ->update($updateData);
  100. $updatedIds[] = $configId;
  101. $updatedCount++;
  102. }
  103. }
  104. $db->commit();
  105. \Log::info('个控回报配置更新成功', [
  106. 'admin_id' => $request->session()->get('admin')->id ?? 0,
  107. 'updated_count' => $updatedCount,
  108. 'config_ids' => $updatedIds
  109. ]);
  110. return apiReturnSuc("配置更新成功,共更新 {$updatedCount} 条数据");
  111. } catch (\Exception $e) {
  112. try {
  113. $db->rollBack();
  114. } catch (\Exception $rollbackException) {
  115. }
  116. \Log::error('个控回报配置更新失败', [
  117. 'error' => $e->getMessage(),
  118. 'trace' => $e->getTraceAsString()
  119. ]);
  120. return apiReturnFail('更新失败: ' . $e->getMessage());
  121. }
  122. }
  123. /**
  124. * 将通用配置复制到选中的开放游戏。
  125. */
  126. public function copyCommon(Request $request)
  127. {
  128. $db = DB::connection('write');
  129. try {
  130. $stockMode = (int)$request->input('stock_mode', 1);
  131. if (!in_array($stockMode, [1, 2])) {
  132. return apiReturnFail('库存模式参数错误');
  133. }
  134. $gameIds = $request->input('game_ids', []);
  135. if (!is_array($gameIds)) {
  136. $gameIds = explode(',', (string)$gameIds);
  137. }
  138. $openGameIds = $this->getOpenGameIds();
  139. $targetGameIds = [];
  140. foreach ($gameIds as $gameId) {
  141. $gameId = (int)$gameId;
  142. if ($gameId > 0 && in_array($gameId, $openGameIds)) {
  143. $targetGameIds[$gameId] = $gameId;
  144. }
  145. }
  146. $targetGameIds = array_values($targetGameIds);
  147. if (empty($targetGameIds)) {
  148. return apiReturnFail('请先选择要复制到的游戏');
  149. }
  150. $commonConfigs = $db->table(self::CONFIG_TABLE)
  151. ->where('GameID', 0)
  152. ->where('StockMode', $stockMode)
  153. ->orderBy('ZMin', 'asc')
  154. ->orderBy('ZMax', 'asc')
  155. ->orderBy('MultiMin', 'asc')
  156. ->get();
  157. if ($commonConfigs->isEmpty()) {
  158. return apiReturnFail('通用配置暂无数据,无法复制');
  159. }
  160. $db->beginTransaction();
  161. $insertedCount = 0;
  162. foreach ($targetGameIds as $targetGameId) {
  163. $db->table(self::CONFIG_TABLE)
  164. ->where('GameID', $targetGameId)
  165. ->where('StockMode', $stockMode)
  166. ->delete();
  167. $rows = [];
  168. foreach ($commonConfigs as $config) {
  169. $row = (array)$config;
  170. unset($row['ConfigID']);
  171. $row['GameID'] = $targetGameId;
  172. $row['StockMode'] = $stockMode;
  173. $rows[] = $row;
  174. }
  175. if (!empty($rows)) {
  176. foreach (array_chunk($rows, 100) as $chunk) {
  177. $db->table(self::CONFIG_TABLE)->insert($chunk);
  178. }
  179. $insertedCount += count($rows);
  180. }
  181. }
  182. $db->commit();
  183. \Log::info('通用个控回报配置复制成功', [
  184. 'admin_id' => $request->session()->get('admin')->id ?? 0,
  185. 'stock_mode' => $stockMode,
  186. 'target_game_ids' => $targetGameIds,
  187. 'inserted_count' => $insertedCount,
  188. ]);
  189. return apiReturnSuc([
  190. 'affected_games' => count($targetGameIds),
  191. 'inserted_count' => $insertedCount,
  192. ], '', '复制成功');
  193. } catch (\Exception $e) {
  194. try {
  195. $db->rollBack();
  196. } catch (\Exception $rollbackException) {
  197. }
  198. \Log::error('通用个控回报配置复制失败', [
  199. 'error' => $e->getMessage(),
  200. 'trace' => $e->getTraceAsString(),
  201. ]);
  202. return apiReturnFail('复制失败: ' . $e->getMessage());
  203. }
  204. }
  205. /**
  206. * 获取开放游戏并按品牌分类。
  207. *
  208. * 数据来源与 /admin/game_site/builder 游戏卡片编辑一致:直接读取 webgame.games,
  209. * 以 state>0 判定为开放游戏,按真实 brand 字段归类。
  210. * GameSomeConfig.GameID 对应 webgame.games.com_gameId(统一内部gameid),
  211. * 因此仅纳入 com_gameId>0 的游戏。
  212. */
  213. private function getOpenGamesGroupedByBrand()
  214. {
  215. // 收集目标品牌的所有 brand 取值,并建立 brand 取值 => 展示名 的映射
  216. $brandValues = [];
  217. $brandLabelMap = [];
  218. foreach (self::$brandGroups as $label => $values) {
  219. foreach ($values as $value) {
  220. $brandValues[] = $value;
  221. $brandLabelMap[strtolower($value)] = $label;
  222. }
  223. }
  224. $rows = DB::connection('mysql')
  225. ->table(self::GAME_TABLE)
  226. ->select('com_gameId', 'title', 'brand')
  227. ->where('state', '>', 0)
  228. ->where('com_gameId', '>', 0)
  229. ->whereIn('brand', $brandValues)
  230. ->orderBy('brand', 'asc')
  231. ->orderBy('title', 'asc')
  232. ->get();
  233. $groups = [];
  234. $seen = [];
  235. foreach ($rows as $row) {
  236. $gameId = (int)$row->com_gameId;
  237. if ($gameId <= 0 || isset($seen[$gameId])) {
  238. continue;
  239. }
  240. $seen[$gameId] = true;
  241. $label = $brandLabelMap[strtolower((string)$row->brand)] ?? (string)$row->brand;
  242. if (!isset($groups[$label])) {
  243. $groups[$label] = [];
  244. }
  245. $groups[$label][] = [
  246. 'id' => $gameId,
  247. 'name' => ($row->title !== null && $row->title !== '') ? $row->title : ('Game ' . $gameId),
  248. ];
  249. }
  250. // 按 $brandGroups 定义的厂商顺序输出
  251. $orderedGroups = [];
  252. foreach (array_keys(self::$brandGroups) as $label) {
  253. if (!empty($groups[$label])) {
  254. $orderedGroups[$label] = $groups[$label];
  255. unset($groups[$label]);
  256. }
  257. }
  258. foreach ($groups as $label => $games) {
  259. $orderedGroups[$label] = $games;
  260. }
  261. return $orderedGroups;
  262. }
  263. /**
  264. * 获取所有开放游戏的 GameID 列表(用于复制通用配置时校验目标游戏)。
  265. */
  266. private function getOpenGameIds()
  267. {
  268. $ids = [];
  269. foreach ($this->getOpenGamesGroupedByBrand() as $games) {
  270. foreach ($games as $game) {
  271. $gameId = (int)$game['id'];
  272. if ($gameId > 0) {
  273. $ids[$gameId] = $gameId;
  274. }
  275. }
  276. }
  277. return array_values($ids);
  278. }
  279. }