table('webgame.routes') ->select('id', 'path', 'title', 'state') ->whereNull('parent_id') ->orderBy('index') ->get(); $channels = DB::connection('mysql') ->table('webgame.WebChannelConfig') ->select('ID', 'Channel', 'StateNo', 'RegionID', 'Remarks') ->orderBy('Channel') ->get(); $defaultPageId = (int)($request->input('page_id') ?: ($pages->first()->id ?? 1)); return view('admin.game_site.builder', [ 'pages' => $pages, 'channels' => $channels, 'defaultPageId' => $defaultPageId, ]); } public function data(Request $request) { $pageId = (int)$request->input('page_id', 1); $routeRows = DB::connection('mysql') ->table('webgame.routes') ->select('id', 'parent_id', 'index', 'path', 'type', 'side', 'block', 'title', 'icon', 'fill', 'style', 'component', 'query', 'login', 'lpath', 'state') ->orderBy('parent_id') ->orderBy('index') ->get(); $pageModules = DB::connection('mysql') ->table('webgame.modules') ->select('id', 'page_id', 'icon', 'pos_index', 'title', 'type', 'api', 'data_key', 'game_ids', 'tabtype', 'parent_id', 'state', 'link') ->where('page_id', $pageId) ->orderBy('pos_index') ->get(); $pageModuleIds = $pageModules->pluck('id')->all(); $links = collect(); if (!empty($pageModuleIds)) { $links = DB::connection('mysql') ->table('webgame.module_parents') ->select('module_id', 'parent_id') ->whereIn('parent_id', $pageModuleIds) ->get(); } $linkedModuleIds = $links->pluck('module_id')->all(); $allModuleIds = array_values(array_unique(array_merge($pageModuleIds, $linkedModuleIds))); $allModules = collect(); if (!empty($allModuleIds)) { $allModules = DB::connection('mysql') ->table('webgame.modules') ->select('id', 'page_id', 'icon', 'pos_index', 'title', 'type', 'api', 'data_key', 'game_ids', 'tabtype', 'parent_id', 'state', 'link') ->whereIn('id', $allModuleIds) ->orderBy('pos_index') ->get(); } $allGameIds = []; foreach ($allModules as $module) { $allGameIds = array_merge($allGameIds, $this->parseGameIds($module->game_ids)); } $allGameIds = array_values(array_unique($allGameIds)); $gamesMap = []; if (!empty($allGameIds)) { $games = DB::connection('mysql') ->table('webgame.games') ->select('id', 'title', 'img', 'brand', 'link', 'state', 'gridNum') ->whereIn('id', $allGameIds) ->get(); foreach ($games as $game) { $gamesMap[(int)$game->id] = $game; } } $moduleGames = []; foreach ($allModules as $module) { $ids = $this->parseGameIds($module->game_ids); $moduleGames[$module->id] = array_values(array_filter(array_map( fn($gid) => $gamesMap[$gid] ?? null, $ids ))); } $styles = DB::connection('mysql') ->table('webgame.styles') ->select('styleid', 'style', 'remarks') ->orderBy('styleid') ->get(); $banners = DB::connection('mysql') ->table('webgame.banners') ->select('bid', 'img', 'alt', 'link', 'state', 'b_order', 'link_module', 'theme_key') ->orderBy('b_order', 'desc') ->get(); $channels = DB::connection('mysql') ->table('webgame.WebChannelConfig') ->select('ID', 'Channel', 'StateNo', 'RegionID', 'Remarks') ->orderBy('Channel') ->get(); return response()->json([ 'code' => 200, 'msg' => 'ok', 'data' => [ 'page_id' => $pageId, 'routes' => $routeRows, 'page_modules' => $pageModules, 'modules' => $allModules, 'module_parents' => $links, 'module_games' => $moduleGames, 'styles' => $styles, 'banners' => $banners, 'channels' => $channels, ], ]); } public function updateState(Request $request) { $validator = Validator::make($request->all(), [ 'table' => 'required|in:routes,modules,games,banners', 'id' => 'required|integer', 'state' => 'required|integer|min:0', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $tableMap = [ 'routes' => ['webgame.routes', 'id'], 'modules' => ['webgame.modules', 'id'], 'games' => ['webgame.games', 'id'], 'banners' => ['webgame.banners', 'bid'], ]; $table = $request->input('table'); [$tableName, $pk] = $tableMap[$table]; DB::connection('mysql') ->table($tableName) ->where($pk, $request->input('id')) ->update(['state' => $request->input('state')]); return apiReturnSuc('state 已更新'); } public function reorderRoutes(Request $request) { $payload = $request->all(); if (array_key_exists('parent_id', $payload) && $payload['parent_id'] === '') { $payload['parent_id'] = null; } $validator = Validator::make($payload, [ 'parent_id' => 'nullable|integer', 'ordered_ids' => 'required|array|min:1', 'ordered_ids.*' => 'integer', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $parentId = $payload['parent_id'] ?? null; $orderedIds = array_values(array_unique(array_map('intval', $payload['ordered_ids'] ?? []))); DB::connection('mysql')->transaction(function () use ($parentId, $orderedIds) { foreach ($orderedIds as $i => $id) { DB::connection('mysql') ->table('webgame.routes') ->where('id', $id) ->where('parent_id', $parentId) ->update(['index' => ($i + 1) * 10]); } }); return apiReturnSuc('路由排序已保存'); } public function saveModuleLayout(Request $request) { $payload = $request->all(); if (isset($payload['items']) && is_array($payload['items'])) { foreach ($payload['items'] as $idx => $item) { if (array_key_exists('parent_id', $item) && $item['parent_id'] === '') { $payload['items'][$idx]['parent_id'] = null; } } } $validator = Validator::make($payload, [ 'page_id' => 'required|integer', 'items' => 'required|array|min:1', 'items.*.module_id' => 'required|integer', 'items.*.parent_id' => 'nullable|integer', 'items.*.pos_index' => 'required|integer|min:1', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $pageId = (int)$payload['page_id']; $items = $payload['items'] ?? []; $pageModuleIds = DB::connection('mysql') ->table('webgame.modules') ->where('page_id', $pageId) ->pluck('id') ->map(fn($v) => (int)$v) ->all(); $pageModuleIdSet = array_flip($pageModuleIds); DB::connection('mysql')->transaction(function () use ($items, $pageModuleIds, $pageModuleIdSet) { foreach ($items as $item) { $moduleId = (int)$item['module_id']; $parentId = isset($item['parent_id']) ? (int)$item['parent_id'] : null; $posIndex = (int)$item['pos_index']; if ($parentId === $moduleId) { continue; } DB::connection('mysql') ->table('webgame.modules') ->where('id', $moduleId) ->update(['pos_index' => $posIndex, 'parent_id' => $parentId]); DB::connection('mysql') ->table('webgame.module_parents') ->where('module_id', $moduleId) ->whereIn('parent_id', $pageModuleIds) ->delete(); if (!is_null($parentId) && isset($pageModuleIdSet[$parentId])) { DB::connection('mysql') ->table('webgame.module_parents') ->updateOrInsert( ['module_id' => $moduleId, 'parent_id' => $parentId], ['module_id' => $moduleId, 'parent_id' => $parentId] ); } } }); return apiReturnSuc('模块布局已保存'); } public function saveModuleGames(Request $request, int $id) { $validator = Validator::make($request->all(), [ 'game_ids' => 'present|array', 'game_ids.*' => 'integer', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $module = DB::connection('mysql')->table('webgame.modules')->where('id', $id)->first(); if (!$module) { return apiReturnFail('模块不存在'); } if (!in_array($module->type, self::GAME_MODULE_TYPES, true)) { return apiReturnFail('模块类型 [' . $module->type . '] 不支持编辑游戏列表'); } $gameIds = array_values(array_unique(array_map('intval', $request->input('game_ids', [])))); DB::connection('mysql') ->table('webgame.modules') ->where('id', $id) ->update(['game_ids' => implode(',', $gameIds)]); return apiReturnSuc('模块游戏排序已保存'); } public function searchGames(Request $request) { $q = trim((string)$request->input('q', '')); $limit = min(max((int)$request->input('limit', 50), 1), 200); $query = DB::connection('mysql') ->table('webgame.games') ->select('id', 'title', 'brand', 'img', 'link', 'state', 'gridNum') ->orderBy('id', 'desc'); if ($q !== '') { $query->where(function ($sub) use ($q) { $sub->where('title', 'like', '%' . $q . '%') ->orWhere('brand', 'like', '%' . $q . '%') ->orWhere('gid', 'like', '%' . $q . '%') ->orWhere('id', $q); }); } return response()->json([ 'code' => 200, 'msg' => 'ok', 'data' => $query->limit($limit)->get(), ]); } // ==================== GameTab CRUD ==================== public function createTab(Request $request) { $validator = Validator::make($request->all(), [ 'parent_id' => 'required|integer', 'title' => 'required|string|max:255', 'icon' => 'nullable|string|max:100', 'tabtype' => 'required|integer', 'state' => 'nullable|integer|min:0', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $parentId = (int)$request->input('parent_id'); $parent = DB::connection('mysql')->table('webgame.modules')->where('id', $parentId)->first(); if (!$parent || $parent->type !== 'ModuleGameTabs') { return apiReturnFail('父模块不存在或不是 ModuleGameTabs 类型'); } $maxPos = DB::connection('mysql') ->table('webgame.module_parents') ->where('parent_id', $parentId) ->join('webgame.modules', 'webgame.modules.id', '=', 'webgame.module_parents.module_id') ->where('webgame.modules.type', 'GameTab') ->max('webgame.modules.pos_index'); $newId = DB::connection('mysql')->table('webgame.modules')->insertGetId([ 'page_id' => $parent->page_id, 'icon' => $request->input('icon', ''), 'pos_index' => ($maxPos ?? 0) + 1, 'title' => $request->input('title'), 'type' => 'GameTab', 'api' => '', 'data' => null, 'data_key' => '', 'game_ids' => '', 'tabtype' => $request->input('tabtype'), 'parent_id' => $parent->parent_id, 'state' => $request->input('state', 16383), 'link' => '', ]); DB::connection('mysql')->table('webgame.module_parents')->insert([ 'module_id' => $newId, 'parent_id' => $parentId, ]); return apiReturnSuc(['msg' => 'Tab 已创建', 'id' => $newId]); } public function updateTab(Request $request, int $id) { $validator = Validator::make($request->all(), [ 'title' => 'nullable|string|max:255', 'icon' => 'nullable|string|max:100', 'tabtype' => 'nullable|integer', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $module = DB::connection('mysql')->table('webgame.modules')->where('id', $id)->first(); if (!$module || $module->type !== 'GameTab') { return apiReturnFail('模块不存在或不是 GameTab 类型'); } $update = []; if ($request->has('title')) $update['title'] = $request->input('title'); if ($request->has('icon')) $update['icon'] = $request->input('icon'); if ($request->has('tabtype')) $update['tabtype'] = (int)$request->input('tabtype'); if (!empty($update)) { DB::connection('mysql')->table('webgame.modules')->where('id', $id)->update($update); } return apiReturnSuc('Tab 已更新'); } public function deleteTab(Request $request, int $id) { $module = DB::connection('mysql')->table('webgame.modules')->where('id', $id)->first(); if (!$module || $module->type !== 'GameTab') { return apiReturnFail('模块不存在或不是 GameTab 类型'); } DB::connection('mysql')->transaction(function () use ($id) { DB::connection('mysql')->table('webgame.module_parents')->where('module_id', $id)->delete(); DB::connection('mysql')->table('webgame.module_parents')->where('parent_id', $id)->delete(); DB::connection('mysql')->table('webgame.modules')->where('id', $id)->delete(); }); return apiReturnSuc('Tab 已删除'); } public function reorderTabs(Request $request) { $validator = Validator::make($request->all(), [ 'parent_id' => 'required|integer', 'ordered_ids' => 'required|array|min:1', 'ordered_ids.*' => 'integer', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } $parentId = (int)$request->input('parent_id'); $orderedIds = array_values(array_unique(array_map('intval', $request->input('ordered_ids', [])))); DB::connection('mysql')->transaction(function () use ($orderedIds) { foreach ($orderedIds as $i => $id) { DB::connection('mysql') ->table('webgame.modules') ->where('id', $id) ->where('type', 'GameTab') ->update(['pos_index' => $i + 1]); } }); return apiReturnSuc('Tab 排序已保存'); } public function updateStyle(Request $request, int $id) { $validator = Validator::make($request->all(), [ 'style' => 'required|string', 'remarks' => 'nullable|string|max:200', ]); if ($validator->fails()) { return apiReturnFail($validator->errors()->first()); } DB::connection('mysql') ->table('webgame.styles') ->where('styleid', $id) ->update([ 'style' => $request->input('style'), 'remarks' => $request->input('remarks', ''), ]); return apiReturnSuc('样式已保存'); } private function parseGameIds(?string $gameIds): array { if (!$gameIds) { return []; } $parts = array_filter(array_map('trim', explode(',', $gameIds))); $ids = []; foreach ($parts as $part) { if ($part !== '' && is_numeric($part)) { $ids[] = (int)$part; } } return $ids; } }