浏览代码

Улучшена валидация и параметры запроса для получения всех персонажей, добавлена поддержка сортировки и поиска.

ilg2005 4 月之前
父节点
当前提交
08cd8e9372
共有 1 个文件被更改,包括 55 次插入44 次删除
  1. 55 44
      app/Http/Controllers/CharController.php

+ 55 - 44
app/Http/Controllers/CharController.php

@@ -15,51 +15,62 @@ class CharController extends Controller
      */
     public function GetAllCharacters(Request $request)
     {
-        // Количество элементов на странице. Можно управлять с клиента, передавая GET-параметр ?per_page=N
-        $perPage = $request->input('per_page', 15);
+        // 1. Валидация и параметры запроса
+        $validated = $request->validate([
+            'per_page' => 'sometimes|integer|min:1|max:100',
+            'search' => 'sometimes|string|nullable|max:50',
+        ]);
 
-        // Получаем пагинированные данные
-        $charactersPaginator = CharBase::paginate($perPage);
+        $perPage = $validated['per_page'] ?? 15;
+        $search = trim($validated['search'] ?? '');
 
-        // Если персонажей нет вообще
-        if ($charactersPaginator->total() === 0) {
-            return response()->json(['characters' => (object)[], 'code' => -2, 'msg' => 'Characters not found.'], 200);
+        $sortField = $request->input('sort_field', 'DBKey');
+        $sortOrder = strtolower($request->input('sort_order', 'asc')) === 'desc' ? 'desc' : 'asc';
+
+        // whitelist для полей сортировки и выборки
+        $allowedSortFields = ['DBKey', 'Name', 'Level', 'AccountName'];
+        if (!in_array($sortField, $allowedSortFields, true)) {
+            $sortField = 'DBKey';
         }
 
-        // Трансформируем коллекцию текущей страницы, чтобы вернуть только нужные поля
-        $transformedCharacters = $charactersPaginator->getCollection()->map(function ($character) {
-            return [
-                'DBKey' => $character->DBKey,
-                'Name' => $character->Name,
-                'Level' => $character->Level,
-                'AccountName' => $character->AccountName
-            ];
-        });
+        // 2. Запрос с выборкой только нужных полей
+        $query = CharBase::query()->select($allowedSortFields);
+
+        if ($search !== '') {
+            $query->where(function ($q) use ($search) {
+                $q->where('Name', 'like', "%{$search}%")
+                    ->orWhere('AccountName', 'like', "%{$search}%");
 
-        // Собираем кастомный ответ с стандартным объектом пагинации Laravel
-        $paginatedResponse = [
+                if (ctype_digit($search)) {
+                    $q->orWhere('DBKey', (int) $search);
+                }
+            });
+        }
+
+        // 3. Сортировка и пагинация
+        $charactersPaginator = $query->orderBy($sortField, $sortOrder)->paginate($perPage);
+
+        // 4. Ответ
+        // Если по запросу не найдено ни одного персонажа, возвращаем специальный ответ
+        // для сохранения обратной совместимости API.
+        if ($charactersPaginator->total() === 0) {
+            return response()->json([
+                'characters' => (object) [],
+                'code' => -2,
+                'msg' => 'Characters not found.'
+            ], 200);
+        }
+
+        // Laravel автоматически преобразует пагинатор в корректный JSON,
+        // включая только выбранные через select() поля.
+        return response()->json([
             'code' => 0,
             'msg' => 'Characters successfully received.',
-            'characters' => [
-                'current_page' => $charactersPaginator->currentPage(),
-                'data' => $transformedCharacters,
-                'first_page_url' => $charactersPaginator->url(1),
-                'from' => $charactersPaginator->firstItem(),
-                'last_page' => $charactersPaginator->lastPage(),
-                'last_page_url' => $charactersPaginator->url($charactersPaginator->lastPage()),
-                'links' => $charactersPaginator->linkCollection()->toArray(),
-                'next_page_url' => $charactersPaginator->nextPageUrl(),
-                'path' => $charactersPaginator->path(),
-                'per_page' => $charactersPaginator->perPage(),
-                'prev_page_url' => $charactersPaginator->previousPageUrl(),
-                'to' => $charactersPaginator->lastItem(),
-                'total' => $charactersPaginator->total(),
-            ]
-        ];
-
-        return response()->json($paginatedResponse, 200);
+            'characters' => $charactersPaginator,
+        ], 200);
     }
 
+    
     /**
      * Получение всех персонажей пользователя по AccountDBID.
      *
@@ -72,7 +83,7 @@ class CharController extends Controller
         $characters = CharBase::where('AccountName', $username)->get();
 
         // Проверяем, найдены ли персонажи
-         if($characters->isEmpty()){
+        if ($characters->isEmpty()) {
             return response()->json(['characters' => [], 'code' => -2, 'msg' => 'Characters not found for this user.'], 200);
         }
 
@@ -88,7 +99,7 @@ class CharController extends Controller
                 'GuildDBKey' => $character->GuildDBKey,
                 'CharPlayTime' => $character->TotalPlayTime
             ];
-        }); 
+        });
 
         return response()->json([
             'code' => 0,
@@ -98,11 +109,11 @@ class CharController extends Controller
         ], 200);
     }
 
-    public function SendItemToCharacter(Request $request) 
+    public function SendItemToCharacter(Request $request)
     {
         $character = CharBase::where('DBKey', $request->Owner)->first();
-        
-        if(!$character){
+
+        if (!$character) {
             return response()->json(['code' => -1, 'msg' => 'Character not found.'], 404);
         }
 
@@ -124,14 +135,14 @@ class CharController extends Controller
             'Comment' => ''
         ]);
 
-        if(!$validator->passes())
-            return response()->json(['code' => -1, 'msg' => $validator->errors() ], 400);
+        if (!$validator->passes())
+            return response()->json(['code' => -1, 'msg' => $validator->errors()], 400);
 
         CharCashItem_OutputBox::SENDITEMOUTPUTBOX($request);
 
         return response()->json([
             'code' => 0,
-            'msg' => 'Items successfully sent.'            
+            'msg' => 'Items successfully sent.'
         ], 200);
     }
 }