From d536233bc8e5b6d447e05a0727b60f0c01490dd5 Mon Sep 17 00:00:00 2001 From: XiaoLFeng Date: Fri, 21 Jul 2023 13:51:48 +0800 Subject: [PATCH] =?UTF-8?q?AddFeature:=20=E6=B7=BB=E5=8A=A0=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8B=92=E7=BB=9D=E5=AE=A1=E6=A0=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 友链编辑页面删除,以及审核期间拒绝审核,优化Js提交体验感。 新增: - link-console-delete.blade.php - link-console-refuse-verify.blade.php 修改: - api.php - edit.blade.php - Link.php Signed-off-by: XiaoLFeng --- app/Http/Controllers/Console/Link.php | 424 +++++++++++++----- .../views/console/friends-link/edit.blade.php | 156 ++++++- .../views/mail/link-console-delete.blade.php | 55 +++ .../mail/link-console-refuse-verify.blade.php | 56 +++ routes/api.php | 7 +- 5 files changed, 571 insertions(+), 127 deletions(-) create mode 100644 resources/views/mail/link-console-delete.blade.php create mode 100644 resources/views/mail/link-console-refuse-verify.blade.php diff --git a/app/Http/Controllers/Console/Link.php b/app/Http/Controllers/Console/Link.php index abb97bf..9c89b3f 100644 --- a/app/Http/Controllers/Console/Link.php +++ b/app/Http/Controllers/Console/Link.php @@ -32,122 +32,6 @@ public function __construct() $this->data = $data->data; } - protected function viewEdit($userId): Application|Factory|View|RedirectResponse - { - $this->setDataForViewEditAndCheckAdmin($userId); - // 没有查询到执行删除 - $this->data['subDescriptionForLine'] = '友链修改'; - if ($this->data['blog'][0] == null) return Response::redirectTo(route('console.friends-link.list')); - return view('console.friends-link.edit', $this->data); - } - - protected function viewCheckAdmin($userId): View|Factory|Application|RedirectResponse - { - $this->setDataForViewEditAndCheckAdmin($userId); - // 用户期望位置替换显示 - $this->data['blog'][0]->blogLocation = $this->data['blog'][0]->blogUserLocation; - // 没有查询到执行删除 - $this->data['subDescriptionForLine'] = '友链审核'; - if ($this->data['blog'][0] == null) return Response::redirectTo(route('console.friends-link.list')); - return view('console.friends-link.edit', $this->data); - } - - protected function viewList(Request $request): Factory|View|Application|RedirectResponse - { - $this->data['request'] = $request; - $dataMarge = [ - 'blogFriendsTotal' => DB::table('blog_link') - ->whereNotIn('blog_link.blogLocation', [0]) - ->count(), - 'blogFriendsCheck' => DB::table('blog_link') - ->where('blog_link.blogLocation', 0) - ->count(), - 'blogFriendsBest' => DB::table('blog_link') - ->where('blog_link.blogLocation', 2) - ->count(), - ]; - if (empty($request->search)) { - // 获取数据库信息 - if (empty($request->page)) $request->page = 0; - $this->data['blog'] = DB::table('blog_link') - ->whereNotIn('blogLocation', [0]) - ->orderBy('id') - ->offset($request->page * 10) - ->limit(10) - ->get() - ->toArray(); - $this->data['blogCount'] = DB::table('blog_link') - ->whereNotIn('blogLocation', [0]) - ->orderBy('id') - ->count(); - $this->data['webClass'] = [ - 'active' => 'px-3 py-2 text-blue-600 border border-gray-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white', - 'unactive' => 'px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white', - ]; - $this->data['blogCount'] = ceil($this->data['blogCount'] / 10); - if ($this->data['request']->page > $this->data['blogCount'] - 1) return Response::redirectTo(route('console.friends-link.list')); - } else { - $this->data['blog'] = DB::select("SELECT * FROM xf_index.blog_link WHERE blogName LIKE '%$request->search%' OR blogUrl LIKE '%$request->search%' ORDER BY id"); - } - $this->data = array_merge($this->data, $dataMarge); - $blogColor = DB::table('blog_color') - ->orderBy('id') - ->get() - ->toArray(); - for ($i = 0; !empty($blogColor[$i]->id); $i++) { - $blogColor[$i]->colorLightType = str_replace('border-', 'ring-', $blogColor[$i]->colorLightType); - $blogColor[$i]->colorDarkType = str_replace('border-', 'ring-', $blogColor[$i]->colorDarkType); - } - $this->data['blogColor'] = $blogColor; - return view('console.friends-link.list', $this->data); - } - - protected function viewCheck(): Factory|View|Application - { - // 检查是否存在含有未在本站分配位置 - $this->data['blog'] = DB::table('blog_link') - ->whereIn('blog_link.blogLocation', [0]) - ->get() - ->toArray(); - $blogColor = DB::table('blog_color') - ->orderBy('id') - ->get() - ->toArray(); - for ($i = 0; !empty($blogColor[$i]->id); $i++) { - $blogColor[$i]->colorLightType = str_replace('border-', 'ring-', $blogColor[$i]->colorLightType); - $blogColor[$i]->colorDarkType = str_replace('border-', 'ring-', $blogColor[$i]->colorDarkType); - } - $this->data['blogColor'] = $blogColor; - return view('console.friends-link.check', $this->data); - } - - protected function viewAdd(): Factory|View|Application - { - $this->data['blogSort'] = DB::table('blog_sort') - ->orderBy('sort') - ->get() - ->toArray(); - $blogColor = DB::table('blog_color') - ->orderBy('id') - ->get() - ->toArray(); - for ($i = 0; !empty($blogColor[$i]->id); $i++) { - $blogColor[$i]->colorDarkType = str_replace('dark:', '', $blogColor[$i]->colorDarkType); - } - $this->data['blogColor'] = $blogColor; - return view('console.friends-link.add', $this->data); - } - - protected function viewSort(): Factory|View|Application - { - return view('console.friends-link.sort', $this->data); - } - - protected function viewColor(): Factory|View|Application - { - return view('console.friends-link.color', $this->data); - } - public function apiConsoleAdd(Request $request): JsonResponse { // 检查数据 @@ -419,6 +303,199 @@ public function apiConsoleCheck(Request $request): JsonResponse return Response::json($returnData, $returnData['code']); } + public function apiConsoleCheckFail(Request $request): JsonResponse + { + // 检查用户是否登录 + if (Auth::check()) { + if (Auth::user()->admin) { + // 处理获取数据 + $dataCheck = Validator::make($request->all(), [ + 'userId' => 'required|int', + 'sendMail' => 'int', + 'sendReason' => 'string', + ]); + if ($dataCheck->fails()) { + $errorType = array_keys($dataCheck->failed()); + $i = 0; + foreach ($dataCheck->failed() as $valueData) { + $errorInfo[$errorType[$i]] = array_keys($valueData); + if ($i == 0) { + $errorSingle = [ + 'info' => $errorType[$i], + 'need' => $errorInfo[$errorType[$i]], + ]; + } + $i++; + } + $returnData = [ + 'output' => 'DataFormatError', + 'code' => 403, + 'data' => [ + 'message' => '输入内容有错误', + 'errorSingle' => $errorSingle, + 'error' => $errorInfo, + ], + ]; + } else { + // 获取数据 + $this->data['blog'] = DB::table('blog_link') + ->where([['id', '=', $request->userId]]) + ->get() + ->toArray(); + $this->data['reason'] = $request->sendReason; + if (!empty($this->data['blog'][0]->id)) { + // 更新数据库 + DB::table('blog_link') + ->where([['id', '=', $this->data['blog'][0]->id]]) + ->delete(); + if (!empty($request->sendMail) && !empty($this->data['blog'][0]->blogOwnEmail)) { + Mail::send('mail.link-console-refuse-verify', $this->data, function (Message $mail) { + global $request; + $mail->from(env('MAIL_USERNAME'), env('APP_NAME')); + $mail->to($this->data['blog'][0]->blogOwnEmail); + $mail->subject(env('APP_NAME') . '-友链审核未通过通知'); + }); + } + $returnData = [ + 'output' => 'Success', + 'code' => 200, + 'data' => [ + 'message' => '删除成功', + ], + ]; + } else { + $returnData = [ + 'output' => 'NoBlog', + 'code' => 403, + 'data' => [ + 'message' => '没有对应博客序列', + ], + ]; + } + } + } else { + $returnData = [ + 'output' => 'NoPermission', + 'code' => 403, + 'data' => [ + 'message' => '没有权限', + ], + ]; + } + } else { + $returnData = [ + 'output' => 'PleaseLogin', + 'code' => 403, + 'data' => [ + 'message' => '请登录', + ], + ]; + } + return Response::json($returnData, $returnData['code']); + } + + public function apiConsoleDelete(Request $request): JsonResponse + { + // 检查用户是否登录 + if (Auth::check()) { + if (Auth::user()->admin) { + // 处理获取数据 + $dataCheck = Validator::make($request->all(), [ + 'userId' => 'required|int', + 'sendMail' => 'int', + ]); + if ($dataCheck->fails()) { + $errorType = array_keys($dataCheck->failed()); + $i = 0; + foreach ($dataCheck->failed() as $valueData) { + $errorInfo[$errorType[$i]] = array_keys($valueData); + if ($i == 0) { + $errorSingle = [ + 'info' => $errorType[$i], + 'need' => $errorInfo[$errorType[$i]], + ]; + } + $i++; + } + $returnData = [ + 'output' => 'DataFormatError', + 'code' => 403, + 'data' => [ + 'message' => '输入内容有错误', + 'errorSingle' => $errorSingle, + 'error' => $errorInfo, + ], + ]; + } else { + // 获取数据 + $this->data['blog'] = DB::table('blog_link') + ->where([['id', '=', $request->userId]]) + ->get() + ->toArray(); + if (!empty($this->data['blog'][0]->id)) { + // 更新数据库 + DB::table('blog_link') + ->where([['id', '=', $this->data['blog'][0]->id]]) + ->delete(); + if (!empty($request->sendMail) && !empty($this->data['blog'][0]->blogOwnEmail)) { + Mail::send('mail.link-console-delete', $request->all(), function (Message $mail) { + global $request; + $mail->from(env('MAIL_USERNAME'), env('APP_NAME')); + $mail->to($this->data['blog'][0]->blogOwnEmail); + $mail->subject(env('APP_NAME') . '-友链被删除'); + }); + } + $returnData = [ + 'output' => 'Success', + 'code' => 200, + 'data' => [ + 'message' => '删除成功', + ], + ]; + } else { + $returnData = [ + 'output' => 'NoBlog', + 'code' => 403, + 'data' => [ + 'message' => '没有对应博客序列', + ], + ]; + } + } + } else { + $returnData = [ + 'output' => 'NoPermission', + 'code' => 403, + 'data' => [ + 'message' => '没有权限', + ], + ]; + } + } else { + $returnData = [ + 'output' => 'PleaseLogin', + 'code' => 403, + 'data' => [ + 'message' => '请登录', + ], + ]; + } + return Response::json($returnData, $returnData['code']); + } + + protected function viewEdit($userId): Application|Factory|View|RedirectResponse + { + $this->setDataForViewEditAndCheckAdmin($userId); + if ($this->data['blog'][0] != null) { + // 没有查询到执行删除 + $this->data['subDescriptionForLine'] = '友链修改'; + if ($this->data['blog'][0] == null) return Response::redirectTo(route('console.friends-link.list')); + return view('console.friends-link.edit', $this->data); + } else { + return Response::redirectTo(route('console.friends-link.check')); + } + } + /** * @param $userId * @return void @@ -443,4 +520,119 @@ private function setDataForViewEditAndCheckAdmin($userId): void } $this->data['blogColor'] = $blogColor; } + + protected function viewCheckAdmin($userId): View|Factory|Application|RedirectResponse + { + $this->setDataForViewEditAndCheckAdmin($userId); + if ($this->data['blog'][0] != null) { + if ($this->data['blog'][0]->blogLocation == 0) { + // 用户期望位置替换显示 + $this->data['blog'][0]->blogLocation = $this->data['blog'][0]->blogUserLocation;// 没有查询到执行删除 + $this->data['subDescriptionForLine'] = '友链审核'; + if ($this->data['blog'][0] == null) return Response::redirectTo(route('console.friends-link.list')); + return view('console.friends-link.edit', $this->data); + } else { + return Response::redirectTo(route('console.friends-link.check')); + } + } else { + return Response::redirectTo(route('console.friends-link.check')); + } + } + + protected function viewList(Request $request): Factory|View|Application|RedirectResponse + { + $this->data['request'] = $request; + $dataMarge = [ + 'blogFriendsTotal' => DB::table('blog_link') + ->whereNotIn('blog_link.blogLocation', [0]) + ->count(), + 'blogFriendsCheck' => DB::table('blog_link') + ->where('blog_link.blogLocation', 0) + ->count(), + 'blogFriendsBest' => DB::table('blog_link') + ->where('blog_link.blogLocation', 2) + ->count(), + ]; + if (empty($request->search)) { + // 获取数据库信息 + if (empty($request->page)) $request->page = 0; + $this->data['blog'] = DB::table('blog_link') + ->whereNotIn('blogLocation', [0]) + ->orderBy('id') + ->offset($request->page * 10) + ->limit(10) + ->get() + ->toArray(); + $this->data['blogCount'] = DB::table('blog_link') + ->whereNotIn('blogLocation', [0]) + ->orderBy('id') + ->count(); + $this->data['webClass'] = [ + 'active' => 'px-3 py-2 text-blue-600 border border-gray-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white', + 'unactive' => 'px-3 py-2 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white', + ]; + $this->data['blogCount'] = ceil($this->data['blogCount'] / 10); + if ($this->data['request']->page > $this->data['blogCount'] - 1) return Response::redirectTo(route('console.friends-link.list')); + } else { + $this->data['blog'] = DB::select("SELECT * FROM xf_index.blog_link WHERE blogName LIKE '%$request->search%' OR blogUrl LIKE '%$request->search%' ORDER BY id"); + } + $this->data = array_merge($this->data, $dataMarge); + $blogColor = DB::table('blog_color') + ->orderBy('id') + ->get() + ->toArray(); + for ($i = 0; !empty($blogColor[$i]->id); $i++) { + $blogColor[$i]->colorLightType = str_replace('border-', 'ring-', $blogColor[$i]->colorLightType); + $blogColor[$i]->colorDarkType = str_replace('border-', 'ring-', $blogColor[$i]->colorDarkType); + } + $this->data['blogColor'] = $blogColor; + return view('console.friends-link.list', $this->data); + } + + protected function viewCheck(): Factory|View|Application + { + // 检查是否存在含有未在本站分配位置 + $this->data['blog'] = DB::table('blog_link') + ->whereIn('blog_link.blogLocation', [0]) + ->orderBy('id', 'desc') + ->get() + ->toArray(); + $blogColor = DB::table('blog_color') + ->orderBy('id') + ->get() + ->toArray(); + for ($i = 0; !empty($blogColor[$i]->id); $i++) { + $blogColor[$i]->colorLightType = str_replace('border-', 'ring-', $blogColor[$i]->colorLightType); + $blogColor[$i]->colorDarkType = str_replace('border-', 'ring-', $blogColor[$i]->colorDarkType); + } + $this->data['blogColor'] = $blogColor; + return view('console.friends-link.check', $this->data); + } + + protected function viewAdd(): Factory|View|Application + { + $this->data['blogSort'] = DB::table('blog_sort') + ->orderBy('sort') + ->get() + ->toArray(); + $blogColor = DB::table('blog_color') + ->orderBy('id') + ->get() + ->toArray(); + for ($i = 0; !empty($blogColor[$i]->id); $i++) { + $blogColor[$i]->colorDarkType = str_replace('dark:', '', $blogColor[$i]->colorDarkType); + } + $this->data['blogColor'] = $blogColor; + return view('console.friends-link.add', $this->data); + } + + protected function viewSort(): Factory|View|Application + { + return view('console.friends-link.sort', $this->data); + } + + protected function viewColor(): Factory|View|Application + { + return view('console.friends-link.color', $this->data); + } } diff --git a/resources/views/console/friends-link/edit.blade.php b/resources/views/console/friends-link/edit.blade.php index cc69754..a47ffd4 100644 --- a/resources/views/console/friends-link/edit.blade.php +++ b/resources/views/console/friends-link/edit.blade.php @@ -63,14 +63,13 @@ class="text-black dark:text-white"> 条

- +
+ class="bg-gray-100 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
@@ -267,7 +266,8 @@ class="bg-gray-100 border border-gray-300 text-gray-900 text-sm rounded-lg focus
- -
+ + + + + + @@ -422,13 +502,25 @@ function ajax() { data: $('#FormData').serialize(), url: '@if($subDescriptionForLine == '友链修改') {{ route('api.link.console.edit') }} @else {{ route('api.link.console.check') }} @endif', dataType: "json", + beforeSend: function () { + $('#SubmitSend').prop('disabled', true).removeClass('bg-green-500').addClass('bg-green-600') + .html('' + + '正在操作'); + $('#SubmitRefuse').prop('disabled', true).removeClass('bg-red-500').addClass('bg-red-600'); + }, success: function (returnData) { if (returnData.output === "Success") { + $('#SubmitSend').html('操作成功') + Toast.toggle('操作成功', ''); setTimeout(function () { location.href = '{{ route('console.friends-link.list') }}'; }, 3000); } else { + $('#SubmitSend').html('@if($subDescriptionForLine == '友链修改')提交修改@else审核通过@endif') + .prop('disabled', false).removeClass('bg-green-600').addClass('bg-green-500'); + $('#SubmitRefuse').html('@if($subDescriptionForLine == '友链修改')删除友链@else审核拒绝@endif') + .prop('disabled', false).removeClass('bg-red-600').addClass('bg-red-500'); Toast('未知错误', ''); } }, @@ -443,6 +535,58 @@ function ajax() { } else { Toast.toggle('未知错误', ''); } + $('#SubmitSend').html('@if($subDescriptionForLine == '友链修改')提交修改@else审核通过@endif') + .prop('disabled', false).removeClass('bg-green-600').addClass('bg-green-500'); + $('#SubmitRefuse').html('@if($subDescriptionForLine == '友链修改')删除友链@else审核拒绝@endif') + .prop('disabled', false).removeClass('bg-red-600').addClass('bg-red-500'); + } + }); + } + + function cancel() { + $.ajax({ + async: true, + method: "POST", + data: $('#FormDataCancel').serialize(), + url: '@if($subDescriptionForLine == '友链修改') {{ route('api.link.console.delete') }} @else {{ route('api.link.console.check-fail') }} @endif', + dataType: "json", + beforeSend: function () { + $('#SubmitSend').prop('disabled', true).removeClass('bg-green-500').addClass('bg-green-600'); + $('#SubmitRefuse').prop('disabled', true).removeClass('bg-red-500').addClass('bg-red-600') + .html('' + + '正在操作'); + }, + success: function (returnData) { + $('#SubmitRefuse').html('操作成功') + + if (returnData.output === "Success") { + Toast.toggle('操作成功', ''); + setTimeout(function () { + location.href = '{{ route('console.friends-link.list') }}'; + }, 3000); + } else { + Toast('未知错误', ''); + $('#SubmitSend').html('@if($subDescriptionForLine == '友链修改')提交修改@else审核通过@endif') + .prop('disabled', false).removeClass('bg-green-600').addClass('bg-green-500'); + $('#SubmitRefuse').html('@if($subDescriptionForLine == '友链修改')删除友链@else审核拒绝@endif') + .prop('disabled', false).removeClass('bg-red-600').addClass('bg-red-500'); + } + }, + error: function (returnData) { + Toast.set('其他错误', ''); + if (returnData.responseJSON.output === 'DataFormatError') { + for (let key in Enum) { + if (returnData.responseJSON.data.errorSingle.info === key) { + Toast.toggle(Enum[key] + '错误,注意格式', ''); + } + } + } else { + Toast.toggle('未知错误', ''); + } + $('#SubmitSend').html('@if($subDescriptionForLine == '友链修改')提交修改@else审核通过@endif') + .prop('disabled', false).removeClass('bg-green-600').addClass('bg-green-500'); + $('#SubmitRefuse').html('@if($subDescriptionForLine == '友链修改')删除友链@else审核拒绝@endif') + .prop('disabled', false).removeClass('bg-red-600').addClass('bg-red-500'); } }); } diff --git a/resources/views/mail/link-console-delete.blade.php b/resources/views/mail/link-console-delete.blade.php new file mode 100644 index 0000000..5725d51 --- /dev/null +++ b/resources/views/mail/link-console-delete.blade.php @@ -0,0 +1,55 @@ + + + + + Mail + + + + + + + + + + + + +
{{ env('APP_NAME') }}
+ + + + + + + + + + +
+ 时间: {{ date('Y-m-d H:i:s') }} +
+ Dear. {{ $userEmail }} +
+ 您好 {{ $userBlog }} + 的站长:{{ $userEmail }}
+ 您在本博客({{ env('APP_NAME') }})的友链已被删除!
+
+ 此邮件为特此提醒,若对此删除有疑问请询问管理员
+ {{ $sqlEmail }} +
+
+ + + + +
+ © 2022 - {{ date('Y') }}. {{ env('APP_NAME') }} All Rights Reserved.
+ 本邮件为自动发出,请勿直接回复 +
+
+ + + + diff --git a/resources/views/mail/link-console-refuse-verify.blade.php b/resources/views/mail/link-console-refuse-verify.blade.php new file mode 100644 index 0000000..33e9d22 --- /dev/null +++ b/resources/views/mail/link-console-refuse-verify.blade.php @@ -0,0 +1,56 @@ + + + + + Mail + + + + + + + + + + + + +
{{ env('APP_NAME') }}
+ + + + + + + + + + +
+ 时间: {{ date('Y-m-d H:i:s') }} +
+ Dear. {{ $blog[0]->blogOwnEmail }} +
+ 您好 {{ $blog[0]->blogName }} + 的站长:{{ $userEmail }}
+ 您在本博客({{ env('APP_NAME') }})申请的友链 + 审核通过!
+ @if(!empty($reason)) +
未通过原因如下:
{{ $reason }} + @endif +
+
+ + + + +
+ © 2022 - {{ date('Y') }}. {{ env('APP_NAME') }} All Rights Reserved.
+ 本邮件为自动发出,请勿直接回复 +
+
+ + + + diff --git a/routes/api.php b/routes/api.php index 85bc9c9..a207354 100644 --- a/routes/api.php +++ b/routes/api.php @@ -8,7 +8,6 @@ use App\Http\Controllers\Authme; use App\Http\Controllers\Console\Link as ConsoleLink; use App\Http\Controllers\Function\Link; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Response; use Illuminate\Support\Facades\Route; @@ -24,10 +23,6 @@ | */ -Route::middleware('auth')->get('/user', function (Request $request) { - return $request->user(); -}); - // 登陆类 Route::prefix('auth')->group(function () { Route::post('login',[Authme::class,'Login'])->name('api.auth.login'); @@ -44,6 +39,8 @@ Route::post('add', [ConsoleLink::class, 'apiConsoleAdd'])->name('api.link.console.add'); Route::post('edit', [ConsoleLink::class, 'apiConsoleEdit'])->name('api.link.console.edit'); Route::post('check', [ConsoleLink::class, 'apiConsoleCheck'])->name('api.link.console.check'); + Route::post('check-fail', [ConsoleLink::class, 'apiConsoleCheckFail'])->name('api.link.console.check-fail'); + Route::post('delete', [ConsoleLink::class, 'apiConsoleDelete'])->name('api.link.console.delete'); }); Route::prefix('custom')->group(function () { Route::post('add', [Link::class, 'apiCustomAdd'])->name('api.link.custom.add');