From 26cd36c76185357b7701718ae11caa81492820ca Mon Sep 17 00:00:00 2001 From: jiannei Date: Wed, 11 Oct 2023 17:36:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=20paginate/simplePaginate/cursorPaginate=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Support/Format.php | 41 +++++-- src/Support/Traits/JsonResponseTrait.php | 6 +- tests/SuccessTest.php | 135 ++++++++++++++++++++--- 3 files changed, 154 insertions(+), 28 deletions(-) diff --git a/src/Support/Format.php b/src/Support/Format.php index ebf5ea9..334fe0a 100644 --- a/src/Support/Format.php +++ b/src/Support/Format.php @@ -88,9 +88,9 @@ public function data($data, ?string $message, int $code, $errors = null): array */ public function paginator(AbstractPaginator|AbstractCursorPaginator $resource, $transformer = null, $resourceName = null): array { - $fractal = fractal()->collection($resource, $transformer ?: function ($item) { - return $item->toArray(); - }, $resourceName)->serializeWith(DataArraySerializer::class); + $fractal = fractal() + ->collection($resource, $transformer ?: fn($item) => $item->toArray(), $resourceName) + ->serializeWith(DataArraySerializer::class); return tap($fractal, $this->formatCollection($resource))->toArray(); } @@ -105,9 +105,9 @@ public function paginator(AbstractPaginator|AbstractCursorPaginator $resource, $ */ public function resourceCollection(ResourceCollection $collection, $transformer = null, $resourceName = null): array { - $fractal = fractal()->collection($collection->resource, $transformer ?: function (JsonResource $resource) { - return array_merge_recursive($resource->resolve(request()), $resource->with(request()), $resource->additional); - }, $resourceName)->serializeWith(DataArraySerializer::class); + $fractal = fractal() + ->collection($collection->resource, $transformer ?: $this->formatJsonResource(), $resourceName) + ->serializeWith(DataArraySerializer::class); return tap($fractal, $this->formatCollection($collection->resource))->toArray(); } @@ -122,9 +122,12 @@ public function resourceCollection(ResourceCollection $collection, $transformer */ public function jsonResource(JsonResource $resource, $transformer = null, $resourceName = null): array { - $data = array_merge_recursive($resource->resolve(request()), $resource->with(request()), $resource->additional); + $data = value($this->formatJsonResource(),$resource); - return fractal()->item($data, $transformer ?: fn () => $data, $resourceName)->serializeWith(ArraySerializer::class)->toArray(); + return fractal() + ->item($data, $transformer ?: fn () => $data, $resourceName) + ->serializeWith(ArraySerializer::class) + ->toArray(); } /** @@ -172,6 +175,24 @@ protected function formatStatusCode($code, string $from = 'success'): int return (int) substr($from === 'fail' ? (Config::get('response.error_code') ?: $code) : $code, 0, 3); } + /** + * Get JsonResource resource data. + * + * @return \Closure + */ + protected function formatJsonResource(): \Closure + { + return function (JsonResource $resource) { + return array_merge_recursive($resource->resolve(request()), $resource->with(request()), $resource->additional); + }; + } + + /** + * Format paginator data. + * + * @param $collection + * @return \Closure + */ protected function formatCollection($collection): \Closure { return function (Fractal $item) use ($collection) { @@ -189,8 +210,8 @@ protected function formatCollection($collection): \Closure 'per_page' => $collection->perPage(), 'current_page' => $collection->currentPage(), 'links' => array_filter([ - 'previous' => $paginated['prev_page_url'] ?? '', - 'next' => $paginated['next_page_url'] ?? '', + 'previous' => $collection->previousPageUrl(), + 'next' => $collection->nextPageUrl(), ]), ], ]), diff --git a/src/Support/Traits/JsonResponseTrait.php b/src/Support/Traits/JsonResponseTrait.php index 82611e3..7665d94 100644 --- a/src/Support/Traits/JsonResponseTrait.php +++ b/src/Support/Traits/JsonResponseTrait.php @@ -72,7 +72,7 @@ public function noContent(string $message = ''): JsonResponse * @param int $option * @return JsonResponse */ - public function ok(string $message = '', int $code = 200, array $headers = [], int $option = 0) + public function ok(string $message = '', int $code = 200, array $headers = [], int $option = 0): JsonResponse { return $this->success([], $message, $code, $headers, $option); } @@ -86,7 +86,7 @@ public function ok(string $message = '', int $code = 200, array $headers = [], i * @param int $option * @return JsonResponse */ - public function localize(int $code = 200, array $headers = [], int $option = 0) + public function localize(int $code = 200, array $headers = [], int $option = 0): JsonResponse { return $this->ok('', $code, $headers, $option); } @@ -94,7 +94,7 @@ public function localize(int $code = 200, array $headers = [], int $option = 0) /** * Return a 400 bad request error. * - * @param string|null $message + * @param string $message */ public function errorBadRequest(string $message = ''): void { diff --git a/tests/SuccessTest.php b/tests/SuccessTest.php index 3ac2880..6b6b2f6 100644 --- a/tests/SuccessTest.php +++ b/tests/SuccessTest.php @@ -12,6 +12,7 @@ namespace Jiannei\Response\Laravel\Tests; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Arr; use Jiannei\Response\Laravel\Support\Facades\Response; use Jiannei\Response\Laravel\Tests\Repositories\Enums\ResponseCodeEnum; use Jiannei\Response\Laravel\Tests\Repositories\Models\User; @@ -161,32 +162,29 @@ public function testSuccessWithPaginatedData() { // 方式八:返回分页的 Api collection User::factory()->count(20)->create(); - $users = User::paginate(); + $users = User::query()->paginate(); $response = Response::success(new UserCollection($users)); $this->assertEquals(200, $response->status()); - $paginated = $users->toArray(); - $formatData = $users->map(function ($item) { - return [ - 'nickname' => $item->name, - 'email' => $item->email, - ]; - })->all(); + $formatData = Arr::map($users->items(),fn($item) => [ + 'nickname' => $item->name, + 'email' => $item->email, + ]); $data = [ 'data' => $formatData, 'meta' => [ 'pagination' => [ - 'count' => $paginated['to'] ?? 0, - 'per_page' => $paginated['per_page'] ?? 0, - 'current_page' => $paginated['current_page'] ?? 0, - 'total' => $paginated['total'] ?? 0, - 'total_pages' => $paginated['last_page'] ?? 0, + 'count' => $users->lastItem(), + 'per_page' => $users->perPage(), + 'current_page' => $users->currentPage(), + 'total' => $users->total(), + 'total_pages' => $users->lastPage(), 'links' => array_filter([ - 'previous' => $paginated['prev_page_url'] ?? '', - 'next' => $paginated['next_page_url'] ?? '', + 'previous' => $users->previousPageUrl(), + 'next' => $users->nextPageUrl(), ]), ], ], @@ -233,4 +231,111 @@ public function testSuccessWithCustomMessageAndCode() $this->assertJsonStringEqualsJsonString($expectedJson, $response->getContent()); } + + public function testLengthAwarePaginator() + { + User::factory()->count(20)->create(); + $users = User::query()->paginate(); + + $response = Response::success($users); + + $this->assertEquals(200, $response->status()); + + $formatData = Arr::map($users->items(),fn($item) => $item->toArray()); + + $data = [ + 'data' => $formatData, + 'meta' => [ + 'pagination' => [ + 'count' => $users->lastItem(), + 'per_page' => $users->perPage(), + 'current_page' => $users->currentPage(), + 'total' => $users->total(), + 'total_pages' => $users->lastPage(), + 'links' => array_filter([ + 'previous' => $users->previousPageUrl(), + 'next' => $users->nextPageUrl(), + ]), + ], + ], + ]; + $expectedJson = json_encode([ + 'status' => 'success', + 'code' => 200, + 'message' => ResponseCodeEnum::fromValue(200)->description, + 'data' => $data, + 'error' => (object) [], + ]); + + $this->assertJsonStringEqualsJsonString($expectedJson, $response->getContent()); + } + + public function testSimplePaginator() + { + User::factory()->count(20)->create(); + $users = User::query()->simplePaginate(); + + $response = Response::success($users); + + $this->assertEquals(200, $response->status()); + + $formatData = Arr::map($users->items(),fn($item) => $item->toArray()); + + $data = [ + 'data' => $formatData, + 'meta' => [ + 'pagination' => [ + 'count' => $users->lastItem(), + 'per_page' => $users->perPage(), + 'current_page' => $users->currentPage(), + 'links' => array_filter([ + 'previous' => $users->previousPageUrl(), + 'next' => $users->nextPageUrl(), + ]), + ], + ], + ]; + $expectedJson = json_encode([ + 'status' => 'success', + 'code' => 200, + 'message' => ResponseCodeEnum::fromValue(200)->description, + 'data' => $data, + 'error' => (object) [], + ]); + + $this->assertJsonStringEqualsJsonString($expectedJson, $response->getContent()); + } + + public function testCursorPaginator() + { + User::factory()->count(20)->create(); + $users = User::query()->cursorPaginate(); + + $response = Response::success($users); + + $this->assertEquals(200, $response->status()); + + $formatData = Arr::map($users->items(),fn($item) => $item->toArray()); + + $data = [ + 'data' => $formatData, + 'meta' => [ + 'cursor' => [ + 'current' => $users->cursor()?->encode(), + 'prev' => $users->previousCursor()?->encode(), + 'next' => $users->nextCursor()?->encode(), + 'count' => count($users->items()) + ], + ], + ]; + $expectedJson = json_encode([ + 'status' => 'success', + 'code' => 200, + 'message' => ResponseCodeEnum::fromValue(200)->description, + 'data' => $data, + 'error' => (object) [], + ]); + + $this->assertJsonStringEqualsJsonString($expectedJson, $response->getContent()); + } }