From 9f8dec18435ad29a8289650e3e925a81c74abbff Mon Sep 17 00:00:00 2001 From: vine_liutk <961510893@qq.com> Date: Tue, 20 Jun 2023 10:36:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=99=BB=E5=BD=95=E5=92=8C?= =?UTF-8?q?=E9=80=80=E5=87=BA=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Admin/Controllers/HomeController.php | 97 ++++++++++---- app/Exceptions/BizException.php | 42 ++++++ app/Exceptions/Handler.php | 141 +++++++++++++++++--- app/Filters/Admin/MonitorModeFilter.php | 2 - app/Http/Controllers/Api/AuthController.php | 40 ++++++ app/Http/Controllers/Api/UserController.php | 17 +++ config/auth.php | 4 + routes/api.php | 14 +- 8 files changed, 304 insertions(+), 53 deletions(-) create mode 100644 app/Exceptions/BizException.php create mode 100644 app/Http/Controllers/Api/AuthController.php create mode 100644 app/Http/Controllers/Api/UserController.php diff --git a/app/Admin/Controllers/HomeController.php b/app/Admin/Controllers/HomeController.php index 9c687fd..4b0a059 100644 --- a/app/Admin/Controllers/HomeController.php +++ b/app/Admin/Controllers/HomeController.php @@ -23,24 +23,65 @@ class HomeController extends AdminController { $page = $this->basePage()->css($this->css())->body([ Grid::make()->columns([ - // $this->frameworkInfo()->md(5), + $this->frameworkInfo()->md(8), Flex::make()->items([ - $this->pieChart(), - $this->cube(), - ]), - ]), - Grid::make()->columns([ - $this->lineChart()->md(8), - Flex::make()->className('h-full')->items([ $this->clock(), - // $this->giteeWidget(), + $this->hitokoto(), ])->direction('column'), ]), + // Grid::make()->columns([ + // $this->lineChart()->md(8), + // Flex::make()->className('h-full')->items([ + // $this->clock(), + // // $this->giteeWidget(), + // ])->direction('column'), + // ]), ]); return $this->response()->success($page); } + /** + * 一言 + */ + public function hitokoto() + { + return Card::make() + ->className('h-full clear-card-mb') + ->body( + Custom::make()->html(<< +
+
+ +
+
+ +
+ ——  + + + + +
+HTML + + )->onMount(<< response.json()) + .then(data => { + const hitokoto = document.querySelector('#hitokoto_text') + hitokoto.href = `https://hitokoto.cn/?uuid=\${data.uuid}` + hitokoto.innerText = data.hitokoto + document.querySelector('#hitokoto_from_who').innerText = data.from_who + document.querySelector('#hitokoto_from').innerText = data.from + }) + .catch(console.error) +JS + ) + ); + } + /** * gitee widget */ @@ -123,25 +164,25 @@ JS Image::make()->src(url(config('admin.logo'))), Wrapper::make()->className('text-3xl mt-9')->body(config('admin.name')), Flex::make()->className('w-64 mt-5')->justify('space-around')->items([ - Action::make() - ->level('link') - ->label('Gitee') - ->blank(true) - ->actionType('url') - ->blank(true) - ->link('https://gitee.com/slowlyo/owl-admin'), - Action::make() - ->level('link') - ->label('OwlAdmin 文档') - ->blank(true) - ->actionType('url') - ->link('https://slowlyo.gitee.io/owl-admin-doc/'), - Action::make() - ->level('link') - ->label('Amis 文档') - ->blank(true) - ->actionType('url') - ->link('https://aisuda.bce.baidu.com/amis/zh-CN/docs/index'), + // Action::make() + // ->level('link') + // ->label('Gitee') + // ->blank(true) + // ->actionType('url') + // ->blank(true) + // ->link('https://gitee.com/slowlyo/owl-admin'), + // Action::make() + // ->level('link') + // ->label('OwlAdmin 文档') + // ->blank(true) + // ->actionType('url') + // ->link('https://slowlyo.gitee.io/owl-admin-doc/'), + // Action::make() + // ->level('link') + // ->label('Amis 文档') + // ->blank(true) + // ->actionType('url') + // ->link('https://aisuda.bce.baidu.com/amis/zh-CN/docs/index'), ]), ]), ]) diff --git a/app/Exceptions/BizException.php b/app/Exceptions/BizException.php new file mode 100644 index 0000000..576d28b --- /dev/null +++ b/app/Exceptions/BizException.php @@ -0,0 +1,42 @@ +status = $status; + + return $this; + } + + /** + * 报告异常 + * + * @return mixed + */ + public function report() + { + } +} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 91208d0..d008bf5 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -2,34 +2,30 @@ namespace App\Exceptions; +use Illuminate\Auth\AuthenticationException; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; -use Throwable; +use Illuminate\Http\Exceptions\ThrottleRequestsException; use Illuminate\Http\Request; +use Illuminate\Validation\ValidationException; +use Symfony\Component\HttpKernel\Exception\HttpException; +use Throwable; class Handler extends ExceptionHandler { - /** - * A list of exception types with their corresponding custom log levels. - * - * @var array, \Psr\Log\LogLevel::*> - */ - protected $levels = [ - // - ]; - /** * A list of the exception types that are not reported. * - * @var array> + * @var string[] */ protected $dontReport = [ // ]; /** - * A list of the inputs that are never flashed to the session on validation exceptions. + * A list of the inputs that are never flashed for validation exceptions. * - * @var array + * @var string[] */ protected $dontFlash = [ 'current_password', @@ -37,6 +33,28 @@ class Handler extends ExceptionHandler 'password_confirmation', ]; + /** + * Get the default context variables for logging. + * + * @return array + */ + protected function context() + { + try { + return array_merge(parent::context(), [ + 'url' => request()->url(), + 'params' => request()->except($this->dontFlash), + 'accept' => request()->header('accept'), + 'client_app' => request()->header('client-app'), + 'client_version' => request()->header('client-version'), + 'client_platform' => request()->header('client-platform'), + 'client_os' => request()->header('client-os'), + ]); + } catch (Throwable $e) { + return []; + } + } + /** * Register the exception handling callbacks for the application. * @@ -44,17 +62,98 @@ class Handler extends ExceptionHandler */ public function register() { - // Laravel9.x 无法捕获 ModelNotFoundException, 在父类 prepareException 方法中被转换为 Symfony\Component\HttpKernel\Exception\NotFoundHttpException - $this->renderable(function (\Illuminate\Database\Eloquent\ModelNotFoundException $e, Request $request) { - if ($request->acceptsJson()) { - return response()->json(['status' => 404, 'msg' => '资源不存在', 'data' => null], 200); + $this->map(ModelNotFoundException::class, function ($e) { + $resource = __($key = 'models.'.$e->getModel()); + + if ($key === $resource) { + $resource = str_ireplace(['App\\Models\\Admin\\', 'App\\Models\\'], '', $e->getModel()); } + + return new HttpException(404, __(':resource not found', ['resource' => $resource]), $e); }); - $this->renderable(function (\Illuminate\Validation\ValidationException $e, Request $request) { - if ($request->acceptsJson()) { - $errors = $e->validator->errors(); - return response()->json(['status' => 422, 'msg' => $errors->first(), 'data' => null, 'errors' => $errors], 200); + + $this->renderable(function (BizException $e, $request) { + if ($this->shouldReturnJson($request, $e)) { + return response()->json($this->convertExceptionToArray($e), $e->status); } + + if (! config('app.debug')) { + $e = new HttpException($e->status, $e->getMessage(), $e); + } + + return $this->prepareResponse($request, $e); + }); + + $this->renderable(function (ThrottleRequestsException $e, Request $request) { + if ($request->acceptsJson()) { + return response()->json(['code' => 429, 'message' => $e->getMessage()]); + } + + return $this->prepareResponse($request, $e); }); } + + /** + * {@inheritdoc} + */ + protected function unauthenticated($request, AuthenticationException $exception) + { + return $this->shouldReturnJson($request, $exception) + ? response()->json([ + 'code' => 401, + 'message' => $exception->getMessage(), + ], 401) + : redirect()->guest($exception->redirectTo() ?? route('login')); + } + + /** + * {@inheritdoc} + */ + protected function invalidJson($request, ValidationException $exception) + { + return response()->json([ + 'code' => 422, + 'message' => $exception->getMessage(), + 'errors' => $exception->errors(), + ], 200); + } + + /** + * {@inheritdoc} + */ + protected function convertExceptionToArray(Throwable $e) + { + $data = [ + 'code' => 500, + 'message' => config('app.debug') ? $e->getMessage() : '服务器繁忙,请稍后再试', + ]; + if ($this->isBizException($e)) { + $data = [ + 'code' => $e->getCode(), + 'message' => $e->getMessage(), + 'data' => null, + ]; + + return $data; + } elseif ($this->isHttpException($e)) { + $data = [ + 'code' => $e->getStatusCode(), + 'message' => $e->getMessage(), + 'data' => null, + ]; + } + + return array_merge(parent::convertExceptionToArray($e), $data); + } + + /** + * 确认给定的异常是否是自定义业务异常 + * + * @param Throwable $e + * @return bool + */ + protected function isBizException(Throwable $e): bool + { + return $e instanceof BizException; + } } diff --git a/app/Filters/Admin/MonitorModeFilter.php b/app/Filters/Admin/MonitorModeFilter.php index 610b59b..bf5c91a 100644 --- a/app/Filters/Admin/MonitorModeFilter.php +++ b/app/Filters/Admin/MonitorModeFilter.php @@ -46,10 +46,8 @@ class MonitorModeFilter extends ModelFilter } return $q; }); - }else{ return $this->whereRaw("FIND_IN_SET('".$groupTags."',group_tags)"); } - } } diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php new file mode 100644 index 0000000..eedb22d --- /dev/null +++ b/app/Http/Controllers/Api/AuthController.php @@ -0,0 +1,40 @@ +validate([ + 'username' => 'required', + 'password' => 'required', + ]); + + $user = AdminUser::where(['username' => $request->input('username')])->first(); + if (! $user) { + return $this->error('用户名或密码错误'); + } + if (! Hash::check($request->input('password'), $user->password)) { + return $this->error('用户名或密码错误'); + } + + // if ($user->is_enable !== 1) { + // return $this->error('用户状态异常请联系管理员'); + // } + + return $this->attemptUser($user); + } + + protected function attemptUser(AdminUser $user, $name = 'api') + { + $token = $user->createToken($name)->plainTextToken; + + return $this->json(['token' => $token]); + } +} diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php new file mode 100644 index 0000000..025ff71 --- /dev/null +++ b/app/Http/Controllers/Api/UserController.php @@ -0,0 +1,17 @@ +user(); + // $user->tokens()->delete(); + $user->currentAccessToken()->delete(); + + return $this->success('退出成功'); + } +} diff --git a/config/auth.php b/config/auth.php index d8c6cee..4c8cdd9 100644 --- a/config/auth.php +++ b/config/auth.php @@ -40,6 +40,10 @@ return [ 'driver' => 'session', 'provider' => 'users', ], + 'api' => [ + 'driver' => 'sanctum', + 'provider' => 'users', + ], ], /* diff --git a/routes/api.php b/routes/api.php index c58e131..a6a689a 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,8 +1,7 @@ 'auth:sanctum'], function () { + + Route::prefix('users')->group(function () { + Route::delete('logout', [UserController::class, 'logout']); + }); +}); \ No newline at end of file