From 60a55dcfd1055144914a753f74b7c249d2ae1bb1 Mon Sep 17 00:00:00 2001 From: BrettonYe Date: Wed, 1 Jan 2025 11:19:26 +0800 Subject: [PATCH] Split User Routes and Adjust Admin Routes --- app/Console/Commands/TaskDaily.php | 2 +- .../Controllers/Admin/InviteController.php | 63 +++ .../Controllers/Admin/SystemController.php | 18 + .../Controllers/Admin/TicketController.php | 6 +- app/Http/Controllers/AdminController.php | 75 ---- app/Http/Controllers/OAuthController.php | 8 +- .../Controllers/User/AffiliateController.php | 10 +- .../Controllers/User/ArticleController.php | 46 ++ .../Controllers/User/InviteController.php | 46 ++ .../Controllers/User/InvoiceController.php | 50 +++ app/Http/Controllers/User/NodeController.php | 40 ++ app/Http/Controllers/User/ShopController.php | 125 ++++++ .../Controllers/User/TicketController.php | 86 ++++ app/Http/Controllers/UserController.php | 423 ++---------------- app/Notifications/PaymentReceived.php | 2 +- app/Utils/Payments/CodePay.php | 2 +- app/Utils/Payments/EPay.php | 2 +- app/Utils/Payments/PayBeaver.php | 2 +- app/Utils/Payments/PayPal.php | 4 +- app/Utils/Payments/Stripe.php | 6 +- database/seeders/LabelSeeder.php | 4 +- resources/views/admin/article/show.blade.php | 2 +- resources/views/admin/config/common.blade.php | 14 +- resources/views/admin/logs/order.blade.php | 2 +- resources/views/admin/user/export.blade.php | 29 +- resources/views/admin/user/index.blade.php | 8 +- resources/views/admin/user/info.blade.php | 8 +- resources/views/user/buy.blade.php | 4 +- .../notifications/paymentReceived.blade.php | 2 +- .../user/components/payment/default.blade.php | 4 +- .../user/components/payment/manual.blade.php | 2 +- resources/views/user/index.blade.php | 8 +- resources/views/user/invite.blade.php | 2 +- resources/views/user/invoices.blade.php | 4 +- resources/views/user/knowledge.blade.php | 2 +- resources/views/user/layouts.blade.php | 34 +- resources/views/user/nodeList.blade.php | 3 +- resources/views/user/profile.blade.php | 7 +- resources/views/user/referral.blade.php | 2 +- resources/views/user/replyTicket.blade.php | 51 ++- resources/views/user/services.blade.php | 6 +- ...ticketList.blade.php => tickets.blade.php} | 5 +- routes/admin.php | 21 +- routes/user.php | 80 ++-- 44 files changed, 716 insertions(+), 604 deletions(-) create mode 100644 app/Http/Controllers/Admin/InviteController.php create mode 100644 app/Http/Controllers/User/ArticleController.php create mode 100644 app/Http/Controllers/User/InviteController.php create mode 100644 app/Http/Controllers/User/InvoiceController.php create mode 100644 app/Http/Controllers/User/NodeController.php create mode 100644 app/Http/Controllers/User/ShopController.php create mode 100644 app/Http/Controllers/User/TicketController.php rename resources/views/user/{ticketList.blade.php => tickets.blade.php} (97%) diff --git a/app/Console/Commands/TaskDaily.php b/app/Console/Commands/TaskDaily.php index 7b25e80e..c5868bb8 100644 --- a/app/Console/Commands/TaskDaily.php +++ b/app/Console/Commands/TaskDaily.php @@ -78,7 +78,7 @@ class TaskDaily extends Command })->where('updated_at', '<=', now()->subHours($closeTicketsHours))->chunk(config('tasks.chunk'), function ($tickets) use ($closeTicketsHours) { $tickets->each(function ($ticket) use ($closeTicketsHours) { if ($ticket->close()) { - $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('replyTicket', ['id' => $ticket->id]), + $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('ticket.edit', $ticket), __('You have not responded this ticket in :num hours, System has closed your ticket.', ['num' => $closeTicketsHours]))); } }); diff --git a/app/Http/Controllers/Admin/InviteController.php b/app/Http/Controllers/Admin/InviteController.php new file mode 100644 index 00000000..6e53d66b --- /dev/null +++ b/app/Http/Controllers/Admin/InviteController.php @@ -0,0 +1,63 @@ + Invite::with(['invitee:id,username', 'inviter:id,username'])->orderBy('status')->orderByDesc('id')->paginate(15)->appends(request('page')), + ]); + } + + public function create(): JsonResponse + { // 生成邀请码 + for ($i = 0; $i < 10; $i++) { + $obj = new Invite; + $obj->code = strtoupper(substr(md5(microtime().Str::random(6)), 8, 12)); + $obj->dateline = date('Y-m-d H:i:s', strtotime(sysConfig('admin_invite_days').' days')); + $obj->save(); + } + + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.generate')])]); + } + + public function export(): void + { // 导出邀请码 + $inviteList = Invite::whereStatus(0)->orderBy('id')->get(); + $filename = trans('user.invite.attribute').'_'.date('Ymd').'.xlsx'; + + $spreadsheet = new Spreadsheet; + $spreadsheet->getProperties()->setCreator('ProxyPanel')->setLastModifiedBy('ProxyPanel')->setTitle(trans('user.invite.attribute'))->setSubject(trans('user.invite.attribute')); + $spreadsheet->setActiveSheetIndex(0); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setTitle(trans('user.invite.attribute')); + $sheet->fromArray([trans('user.invite.attribute'), trans('common.available_date')]); + + foreach ($inviteList as $k => $vo) { + $sheet->fromArray([$vo->code, $vo->dateline], null, 'A'.($k + 2)); + } + + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // 输出07Excel文件 + //header('Content-Type:application/vnd.ms-excel'); // 输出Excel03版本文件 + header('Content-Disposition: attachment;filename="'.$filename.'"'); + header('Cache-Control: max-age=0'); + try { + $writer = new Xlsx($spreadsheet); + $writer->save('php://output'); + } catch (Exception $e) { + Log::error(trans('common.error_action_item', ['action' => trans('common.export'), 'attribute' => trans('user.invite.attribute')]).': '.$e->getMessage()); + } + } +} diff --git a/app/Http/Controllers/Admin/SystemController.php b/app/Http/Controllers/Admin/SystemController.php index ab453470..afa0f0d5 100644 --- a/app/Http/Controllers/Admin/SystemController.php +++ b/app/Http/Controllers/Admin/SystemController.php @@ -13,6 +13,11 @@ use App\Channels\WeChatChannel; use App\Http\Controllers\Controller; use App\Http\Requests\Admin\SystemRequest; use App\Models\Config; +use App\Models\Country; +use App\Models\GoodsCategory; +use App\Models\Label; +use App\Models\Level; +use App\Models\SsConfig; use App\Notifications\Custom; use App\Services\TelegramService; use App\Utils\DDNS; @@ -246,4 +251,17 @@ class SystemController extends Controller return Response::json(['status' => 'success', 'message' => trans('admin.system.notification.test.success')]); } + + public function common(): View + { + return view('admin.config.common', [ + 'methods' => SsConfig::type(1)->get(), + 'protocols' => SsConfig::type(2)->get(), + 'categories' => GoodsCategory::all(), + 'obfsList' => SsConfig::type(3)->get(), + 'countries' => Country::all(), + 'levels' => Level::all(), + 'labels' => Label::with('nodes')->get(), + ]); + } } diff --git a/app/Http/Controllers/Admin/TicketController.php b/app/Http/Controllers/Admin/TicketController.php index cfbaa2b5..33d259e2 100644 --- a/app/Http/Controllers/Admin/TicketController.php +++ b/app/Http/Controllers/Admin/TicketController.php @@ -43,7 +43,7 @@ class TicketController extends Controller } if ($ticket = Ticket::create(['user_id' => $user->id, 'admin_id' => auth()->id(), 'title' => $data['title'], 'content' => clean($data['content'])])) { - $user->notify(new TicketCreated($ticket, route('replyTicket', ['id' => $ticket->id]))); + $user->notify(new TicketCreated($ticket, route('ticket.edit', $ticket))); return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.create')])]); } @@ -75,7 +75,7 @@ class TicketController extends Controller // 通知用户 if (sysConfig('ticket_replied_notification')) { - $ticket->user->notify(new TicketReplied($reply, route('replyTicket', ['id' => $ticket->id]), true)); + $ticket->user->notify(new TicketReplied($reply, route('ticket.edit', $ticket), true)); } return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.ticket.reply')])]); @@ -92,7 +92,7 @@ class TicketController extends Controller } // 通知用户 if (sysConfig('ticket_closed_notification')) { - $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('replyTicket', ['id' => $ticket->id]), \request('reason'), true)); + $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('ticket.edit', $ticket), \request('reason'), true)); } return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.close')])]); diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index fc498056..4755e4b6 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -2,29 +2,17 @@ namespace App\Http\Controllers; -use App\Models\Country; -use App\Models\GoodsCategory; -use App\Models\Invite; -use App\Models\Label; -use App\Models\Level; use App\Models\Node; use App\Models\NodeDailyDataFlow; use App\Models\NodeHourlyDataFlow; use App\Models\Order; use App\Models\ReferralApply; use App\Models\ReferralLog; -use App\Models\SsConfig; use App\Models\User; use App\Models\UserHourlyDataFlow; use Cache; use DB; -use Illuminate\Http\JsonResponse; -use Log; -use PhpOffice\PhpSpreadsheet\Exception; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use Response; -use Str; class AdminController extends Controller { @@ -77,67 +65,4 @@ class AdminController extends Controller 'todaySuccessOrder' => Order::whereIn('status', [2, 3])->whereDate('created_at', $today)->count(), ]); } - - // 邀请码列表 - public function inviteList() - { - return view('admin.aff.invite', [ - 'inviteList' => Invite::with(['invitee:id,username', 'inviter:id,username'])->orderBy('status')->orderByDesc('id')->paginate(15)->appends(request('page')), - ]); - } - - // 生成邀请码 - public function makeInvite(): JsonResponse - { - for ($i = 0; $i < 10; $i++) { - $obj = new Invite; - $obj->code = strtoupper(substr(md5(microtime().Str::random(6)), 8, 12)); - $obj->dateline = date('Y-m-d H:i:s', strtotime(sysConfig('admin_invite_days').' days')); - $obj->save(); - } - - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.generate')])]); - } - - // 导出邀请码 - public function exportInvite(): void - { - $inviteList = Invite::whereStatus(0)->orderBy('id')->get(); - $filename = trans('user.invite.attribute').'_'.date('Ymd').'.xlsx'; - - $spreadsheet = new Spreadsheet; - $spreadsheet->getProperties()->setCreator('ProxyPanel')->setLastModifiedBy('ProxyPanel')->setTitle(trans('user.invite.attribute'))->setSubject(trans('user.invite.attribute')); - $spreadsheet->setActiveSheetIndex(0); - $sheet = $spreadsheet->getActiveSheet(); - $sheet->setTitle(trans('user.invite.attribute')); - $sheet->fromArray([trans('user.invite.attribute'), trans('common.available_date')]); - - foreach ($inviteList as $k => $vo) { - $sheet->fromArray([$vo->code, $vo->dateline], null, 'A'.($k + 2)); - } - - header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // 输出07Excel文件 - //header('Content-Type:application/vnd.ms-excel'); // 输出Excel03版本文件 - header('Content-Disposition: attachment;filename="'.$filename.'"'); - header('Cache-Control: max-age=0'); - try { - $writer = new Xlsx($spreadsheet); - $writer->save('php://output'); - } catch (Exception $e) { - Log::error(trans('common.error_action_item', ['action' => trans('common.export'), 'attribute' => trans('user.invite.attribute')]).': '.$e->getMessage()); - } - } - - public function config() - { - return view('admin.config.common', [ - 'methods' => SsConfig::type(1)->get(), - 'protocols' => SsConfig::type(2)->get(), - 'categories' => GoodsCategory::all(), - 'obfsList' => SsConfig::type(3)->get(), - 'countries' => Country::all(), - 'levels' => Level::all(), - 'labels' => Label::with('nodes')->get(), - ]); - } } diff --git a/app/Http/Controllers/OAuthController.php b/app/Http/Controllers/OAuthController.php index 8bf70477..ae8b243e 100644 --- a/app/Http/Controllers/OAuthController.php +++ b/app/Http/Controllers/OAuthController.php @@ -18,10 +18,10 @@ class OAuthController extends Controller $user = Auth::user(); if ($user && $user->userAuths()->whereType($provider)->delete()) { - return redirect()->route('profile')->with('successMsg', trans('common.success_item', ['attribute' => trans('user.oauth.unbind')])); + return redirect()->back()->with('successMsg', trans('common.success_item', ['attribute' => trans('user.oauth.unbind')])); } - return redirect()->route('profile')->withErrors(trans('common.failed_item', ['attribute' => trans('user.oauth.unbind')])); + return redirect()->back()->withErrors(trans('common.failed_item', ['attribute' => trans('user.oauth.unbind')])); } public function bind(string $provider): RedirectResponse @@ -36,7 +36,7 @@ class OAuthController extends Controller $user = Auth::user(); if (! $user) { - return redirect()->route('profile')->withErrors(trans('common.failed_item', ['attribute' => trans('user.oauth.bind')])); + return redirect()->back()->withErrors(trans('common.failed_item', ['attribute' => trans('user.oauth.bind')])); } return $this->bindLogic($provider, $user, $authInfo); @@ -60,7 +60,7 @@ class OAuthController extends Controller $message = trans('common.success_item', ['attribute' => trans('user.oauth.bind')]); } - return redirect()->route('profile')->with('successMsg', $message); + return redirect()->back()->with('successMsg', $message); } public function register(string $provider): RedirectResponse diff --git a/app/Http/Controllers/User/AffiliateController.php b/app/Http/Controllers/User/AffiliateController.php index f357fb18..1b77a571 100644 --- a/app/Http/Controllers/User/AffiliateController.php +++ b/app/Http/Controllers/User/AffiliateController.php @@ -15,7 +15,7 @@ use Response; class AffiliateController extends Controller { // 推广返利 - public function referral() + public function index() { if (ReferralLog::uid()->doesntExist() && Order::uid()->whereStatus(2)->doesntExist()) { return Response::view('auth.error', ['message' => trans('user.purchase.required').''.trans('common.back').''], 402); @@ -35,7 +35,7 @@ class AffiliateController extends Controller } // 申请提现 - public function extractMoney(): JsonResponse + public function withdraw(): JsonResponse { // 判断账户是否过期 if (Auth::getUser()->expiration_date < date('Y-m-d')) { @@ -48,8 +48,8 @@ class AffiliateController extends Controller } // 校验可以提现金额是否超过系统设置的阀值 - $commission = ReferralLog::uid()->whereStatus(0)->sum('commission'); - $commission /= 100; + $referrals = ReferralLog::uid()->whereStatus(0)->get(); + $commission = $referrals->sum('commission'); if ($commission < sysConfig('referral_money')) { return Response::json([ 'status' => 'fail', 'title' => trans('common.failed_item', ['attribute' => trans('common.request')]), 'message' => trans('user.referral.msg.unfulfilled', ['amount' => Helpers::getPriceTag(sysConfig('referral_money'))]), @@ -60,7 +60,7 @@ class AffiliateController extends Controller $ref->user_id = Auth::id(); $ref->before = $commission; $ref->amount = $commission; - $ref->link_logs = ReferralLog::uid()->whereStatus(0)->pluck('id')->toArray(); + $ref->link_logs = $referrals->pluck('id')->toArray(); if ($ref->save()) { return Response::json(['status' => 'success', 'title' => trans('common.success_item', ['attribute' => trans('common.request')]), 'message' => trans('user.referral.msg.wait')]); } diff --git a/app/Http/Controllers/User/ArticleController.php b/app/Http/Controllers/User/ArticleController.php new file mode 100644 index 00000000..a67cc1c6 --- /dev/null +++ b/app/Http/Controllers/User/ArticleController.php @@ -0,0 +1,46 @@ +whereStatus(1)->exists()) { + $data[] = 'ss'; + } + if (Node::whereIn('type', [1, 4])->whereStatus(1)->exists()) { + $data[] = 'ssr'; + } + if (Node::whereType(2)->whereStatus(1)->exists()) { + $data[] = 'v2'; + } + if (Node::whereType(3)->whereStatus(1)->exists()) { + $data[] = 'trojan'; + } + + $subscribe = auth()->user()->subscribe; + + return view('user.knowledge', [ + 'subType' => $data, + 'subUrl' => route('sub', $subscribe->code), + 'subStatus' => $subscribe->status, + 'subMsg' => $subscribe->ban_desc, + 'knowledges' => Article::type(1)->lang()->orderByDesc('sort')->latest()->get()->groupBy('category'), + ]); + } + + public function show(Article $article): JsonResponse + { // 公告详情 + $articleService = new ArticleService($article); + + return response()->json(['title' => $article->title, 'content' => $articleService->getContent()]); + } +} diff --git a/app/Http/Controllers/User/InviteController.php b/app/Http/Controllers/User/InviteController.php new file mode 100644 index 00000000..d50f587a --- /dev/null +++ b/app/Http/Controllers/User/InviteController.php @@ -0,0 +1,46 @@ +active()->where('origin_amount', '>', 0)->doesntExist()) { + return Response::view('auth.error', ['message' => trans('user.purchase.required').' '.trans('common.back').''], 402); + } + + return Response::view('user.invite', [ + 'num' => auth()->user()->invite_num, // 还可以生成的邀请码数量 + 'inviteList' => Invite::uid()->with('invitee')->paginate(10), // 邀请码列表 + 'referral_traffic' => formatBytes(sysConfig('referral_traffic'), 'MiB'), + 'referral_percent' => sysConfig('referral_percent'), + ]); + } + + public function store(): JsonResponse + { // 生成邀请码 + $user = auth()->user(); + if ($user->invite_num <= 0) { + return Response::json(['status' => 'fail', 'message' => trans('user.invite.generate_failed')]); + } + $invite = $user->invites()->create([ + 'code' => strtoupper(mb_substr(md5(microtime().Str::random()), 8, 12)), + 'dateline' => date('Y-m-d H:i:s', strtotime(sysConfig('user_invite_days').' days')), + ]); + if ($invite) { + $user->decrement('invite_num'); + + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.generate')])]); + } + + return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.generate')])]); + } +} diff --git a/app/Http/Controllers/User/InvoiceController.php b/app/Http/Controllers/User/InvoiceController.php new file mode 100644 index 00000000..6aaaca17 --- /dev/null +++ b/app/Http/Controllers/User/InvoiceController.php @@ -0,0 +1,50 @@ + auth()->user()->orders()->with(['goods', 'payment'])->orderByDesc('id')->paginate(10)->appends($request->except('page')), + 'prepaidPlan' => Order::userPrepay()->exists(), + ]); + } + + public function show(string $sn): \Illuminate\Http\Response + { // 订单明细 + return Response::view('user.invoiceDetail', ['order' => Order::uid()->whereSn($sn)->with(['goods', 'coupon'])->firstOrFail()]); + } + + public function activate(): JsonResponse + { // 激活套餐 + $activePlan = Order::userActivePlan()->first(); + if ($activePlan) { + if ($activePlan->expired()) { // 关闭先前套餐后,新套餐自动运行 + if (Order::userActivePlan()->exists()) { + return Response::json(['status' => 'success', 'message' => trans('common.active_item', ['attribute' => trans('common.success')])]); + } + + return Response::json(['status' => 'success', 'message' => trans('common.close')]); + } + } else { + $prepaidPlan = Order::userPrepay()->first(); + if ($prepaidPlan) { // 关闭先前套餐后,新套餐自动运行 + if ($prepaidPlan->complete()) { + return Response::json(['status' => 'success', 'message' => trans('common.active_item', ['attribute' => trans('common.success')])]); + } + + return Response::json(['status' => 'success', 'message' => trans('common.close')]); + } + } + + return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.close')])]); + } +} diff --git a/app/Http/Controllers/User/NodeController.php b/app/Http/Controllers/User/NodeController.php new file mode 100644 index 00000000..99438e17 --- /dev/null +++ b/app/Http/Controllers/User/NodeController.php @@ -0,0 +1,40 @@ +user(); + + // 获取当前用户可用节点 + $nodeList = $user->nodes()->whereIn('is_display', [1, 3])->with(['labels', 'level_table'])->get(); + $onlineNode = NodeHeartbeat::recently()->distinct()->pluck('node_id')->toArray(); + foreach ($nodeList as $node) { + // 节点在线状态 + $node->offline = ! in_array($node->id, $onlineNode, true); + } + + return Response::view('user.nodeList', [ + 'nodesGeo' => $nodeList->pluck('name', 'geo')->toArray(), + 'nodeList' => $nodeList, + ]); + } + + public function show(Request $request, Node $node): JsonResponse + { // 节点详细 + $proxyServer = new ProxyService; + $server = $proxyServer->getProxyConfig($node); + + return Response::json(['status' => 'success', 'data' => $proxyServer->getUserProxyConfig($server, $request->input('type') !== 'text'), 'title' => $server['type']]); + } +} diff --git a/app/Http/Controllers/User/ShopController.php b/app/Http/Controllers/User/ShopController.php new file mode 100644 index 00000000..1777176d --- /dev/null +++ b/app/Http/Controllers/User/ShopController.php @@ -0,0 +1,125 @@ +user(); + // 余额充值商品,只取10个 + $renewOrder = Order::userActivePlan($user->id)->first(); + $renewPrice = $renewOrder->goods->renew ?? 0; + // 有重置日时按照重置日为标准,否则就以过期日为标准 + $dataPlusDays = $user->reset_time ?? $user->expired_at; + + $goodsList = Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->get(); + + if ($user && $nodes = $user->userGroup) { + $nodes = $nodes->nodes(); + } else { + $nodes = Node::all(); + } + foreach ($goodsList as $goods) { + $goods->node_count = $nodes->where('level', '<=', $goods->level)->count(); + $goods->node_countries = $nodes->where('level', '<=', $goods->level)->pluck('country_code')->unique(); + } + + return Response::view('user.services', [ + 'chargeGoodsList' => Goods::type(3)->orderBy('price')->get(), + 'goodsList' => $goodsList, + 'renewTraffic' => $renewPrice ? Helpers::getPriceTag($renewPrice) : 0, + 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? $dataPlusDays->diffInDays() : 0, + ]); + } + + public function resetTraffic(): JsonResponse + { // 重置流量 + $user = auth()->user(); + $order = Order::userActivePlan()->firstOrFail(); + $renewCost = $order->goods->renew; + if ($user->credit < $renewCost) { + return Response::json(['status' => 'fail', 'message' => trans('user.payment.insufficient_balance')]); + } + + $user->update(['u' => 0, 'd' => 0]); + + // 记录余额操作日志 + Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit - $renewCost, -1 * $renewCost, 'The user manually reset the data.'); + + // 扣余额 + $user->updateCredit(-$renewCost); + + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.reset')])]); + } + + public function checkBonus(Request $request, Goods $good): JsonResponse + { // 兑换优惠券码 + $coupon_sn = $request->input('coupon_sn'); + + if (empty($coupon_sn)) { + return Response::json(['status' => 'fail', 'title' => trans('common.failed'), 'message' => trans('user.coupon.error.unknown')]); + } + + $coupon = (new CouponService($coupon_sn))->search($good); // 检查券合规性 + + if (! $coupon instanceof Coupon) { + return $coupon; + } + + $data = [ + 'name' => $coupon->name, + 'type' => $coupon->type, + 'value' => $coupon->type === 2 ? $coupon->value : Helpers::getPriceTag($coupon->value), + ]; + + return Response::json(['status' => 'success', 'data' => $data, 'message' => trans('common.applied', ['attribute' => trans('model.coupon.attribute')])]); + } + + public function show(Goods $good): \Illuminate\Http\Response + { // 显示服务详细 + $user = auth()->user(); + // 有重置日时按照重置日为标准,否则就以过期日为标准 + $dataPlusDays = $user->reset_time ?? $user->expired_at; + + return Response::view('user.buy', [ + 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? $dataPlusDays->diffInDays() : 0, + 'activePlan' => Order::userActivePlan()->exists(), + 'goods' => $good, + ]); + } + + public function charge(Request $request): JsonResponse + { + $validator = Validator::make($request->all(), [ + 'coupon_sn' => [ + 'required', Rule::exists('coupon', 'sn')->where(static function ($query) { + $query->whereType(3)->whereStatus(0); + }), + ], + ]); + + if ($validator->fails()) { + return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]); + } + + if ((new CouponService($request->input('coupon_sn')))->charge()) { + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.recharge')])]); + } + + return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('user.recharge')])]); + } +} diff --git a/app/Http/Controllers/User/TicketController.php b/app/Http/Controllers/User/TicketController.php new file mode 100644 index 00000000..a96e14bf --- /dev/null +++ b/app/Http/Controllers/User/TicketController.php @@ -0,0 +1,86 @@ + auth()->user()->tickets()->latest()->paginate(10)->appends($request->except('page')), + ]); + } + + public function store(Request $request): ?JsonResponse + { // 添加工单 + $user = auth()->user(); + $title = $request->input('title'); + $content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300); + + if (empty($title) || empty($content)) { + return Response::json([ + 'status' => 'fail', 'message' => trans('validation.required', ['attribute' => ucfirst(trans('validation.attributes.title')).'&'.ucfirst(trans('validation.attributes.content'))]), + ]); + } + + if ($ticket = $user->tickets()->create(compact('title', 'content'))) { + // 通知相关管理员 + Notification::send(User::find(1), new TicketCreated($ticket, route('admin.ticket.edit', $ticket))); + } + + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.submit')])]); + } + + public function edit(Ticket $ticket) + { // 回复工单 + return view('user.replyTicket', [ + 'ticket' => $ticket, + 'replyList' => $ticket->reply()->with('ticket:id,status', 'admin:id,username,qq', 'user:id,username,qq')->oldest()->get(), + ]); + } + + public function reply(Request $request, Ticket $ticket) + { + $content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300); + + if (empty($content)) { + return Response::json([ + 'status' => 'fail', 'message' => trans('validation.required', ['attribute' => ucfirst(trans('validation.attributes.title')).'&'.ucfirst(trans('validation.attributes.content'))]), + ]); + } + + $reply = $ticket->reply()->create(['user_id' => auth()->id(), 'content' => $content]); + if ($reply) { + // 重新打开工单 + if (in_array($ticket->status, [1, 2], true)) { + $ticket->update(['status' => 0]); + } + + // 通知相关管理员 + Notification::send(User::find(1), new TicketReplied($reply, route('admin.ticket.edit', $ticket))); + + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.ticket.reply')])]); + } + + return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('user.ticket.reply')])]); + } + + public function close(Ticket $ticket): JsonResponse + { // 关闭工单 + if ($ticket->close()) { + return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.close')])]); + } + + return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.close')])]); + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index c630ca80..556e8c41 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -4,19 +4,6 @@ namespace App\Http\Controllers; use App\Helpers\DataChart; use App\Models\Article; -use App\Models\Coupon; -use App\Models\Goods; -use App\Models\Invite; -use App\Models\Node; -use App\Models\NodeHeartbeat; -use App\Models\Order; -use App\Models\Ticket; -use App\Models\User; -use App\Notifications\TicketCreated; -use App\Notifications\TicketReplied; -use App\Services\ArticleService; -use App\Services\CouponService; -use App\Services\ProxyService; use App\Services\UserService; use App\Utils\Helpers; use Cache; @@ -26,14 +13,11 @@ use Hash; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Validation\Rule; use Log; -use Notification; use Redirect; use Response; use Session; use Str; -use Validator; class UserController extends Controller { @@ -108,365 +92,65 @@ class UserController extends Controller return Response::json(['status' => 'success', 'message' => trans('user.home.attendance.success', ['data' => formatBytes($traffic)])]); } - // 节点列表 - public function nodeList(Request $request) - { - $user = auth()->user(); - if ($request->isMethod('POST')) { - $proxyServer = new ProxyService; - $server = $proxyServer->getProxyConfig(Node::findOrFail($request->input('id'))); - - return Response::json(['status' => 'success', 'data' => $proxyServer->getUserProxyConfig($server, $request->input('type') !== 'text'), 'title' => $server['type']]); - } - - // 获取当前用户可用节点 - $nodeList = $user->nodes()->whereIn('is_display', [1, 3])->with(['labels', 'level_table'])->get(); - $onlineNode = NodeHeartbeat::recently()->distinct()->pluck('node_id')->toArray(); - foreach ($nodeList as $node) { - // 节点在线状态 - $node->offline = ! in_array($node->id, $onlineNode, true); - } - - return view('user.nodeList', [ - 'nodesGeo' => $nodeList->pluck('name', 'geo')->toArray(), - 'nodeList' => $nodeList, - ]); - } - - public function article(Article $article): JsonResponse - { // 公告详情 - $articleService = new ArticleService($article); - - return response()->json(['title' => $article->title, 'content' => $articleService->getContent()]); - } - // 修改个人资料 - public function profile(Request $request) + public function profile() { $user = auth()->user(); - if ($request->isMethod('POST')) { - // 修改密码 - if ($request->has(['password', 'new_password'])) { - $data = $request->only(['password', 'new_password']); - - if (! Hash::check($data['password'], $user->password)) { - return Redirect::back()->withErrors(trans('auth.password.reset.error.wrong')); - } - - if (Hash::check($data['new_password'], $user->password)) { - return Redirect::back()->withErrors(trans('auth.password.reset.error.same')); - } - - // 演示环境禁止改管理员密码 - if ($user->id === 1 && config('app.env') === 'demo') { - return Redirect::back()->withErrors(trans('auth.password.reset.error.demo')); - } - - if (! $user->update(['password' => $data['new_password']])) { - return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); - } - - return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); - // 修改代理密码 - } - - if ($request->has('passwd')) { - $passwd = $request->input('passwd'); - if (! $user->update(['passwd' => $passwd])) { - return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); - } - - return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); - } - - // 修改联系方式 - if ($request->has(['nickname', 'wechat', 'qq'])) { - $data = $request->only(['nickname', 'wechat', 'qq']); - if (empty($data['nickname'])) { - return Redirect::back()->withErrors(trans('validation.required', ['attribute' => trans('model.user.nickname')])); - } - - if (! $user->update($data)) { - return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); - } - } - - return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); - } $auth = $user->userAuths()->pluck('type')->toArray(); return view('user.profile', compact('auth')); } - // 商品列表 - public function services() + public function updateProfile(Request $request): RedirectResponse { $user = auth()->user(); - // 余额充值商品,只取10个 - $renewOrder = Order::userActivePlan($user->id)->first(); - $renewPrice = $renewOrder->goods->renew ?? 0; - // 有重置日时按照重置日为标准,否则就以过期日为标准 - $dataPlusDays = $user->reset_time ?? $user->expired_at; + // 修改密码 + if ($request->has(['password', 'new_password'])) { + $data = $request->only(['password', 'new_password']); - $goodsList = Goods::whereStatus(1)->where('type', '<=', '2')->orderByDesc('type')->orderByDesc('sort')->get(); - - if ($user && $nodes = $user->userGroup) { - $nodes = $nodes->nodes(); - } else { - $nodes = Node::all(); - } - foreach ($goodsList as $goods) { - $goods->node_count = $nodes->where('level', '<=', $goods->level)->where('status', 1)->count(); - $goods->node_countries = $nodes->where('level', '<=', $goods->level)->where('status', 1)->pluck('country_code')->unique(); - } - - return view('user.services', [ - 'chargeGoodsList' => Goods::type(3)->orderBy('price')->get(), - 'goodsList' => $goodsList, - 'renewTraffic' => $renewPrice ? Helpers::getPriceTag($renewPrice) : 0, - 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? $dataPlusDays->diffInDays() : 0, - ]); - } - - //重置流量 - public function resetUserTraffic(): ?JsonResponse - { - $user = auth()->user(); - $order = Order::userActivePlan()->firstOrFail(); - $renewCost = $order->goods->renew; - if ($user->credit < $renewCost) { - return Response::json(['status' => 'fail', 'message' => trans('user.payment.insufficient_balance')]); - } - - $user->update(['u' => 0, 'd' => 0]); - - // 记录余额操作日志 - Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit - $renewCost, -1 * $renewCost, 'The user manually reset the data.'); - - // 扣余额 - $user->updateCredit(-$renewCost); - - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.reset')])]); - } - - // 工单 - public function ticketList(Request $request) - { - return view('user.ticketList', [ - 'tickets' => auth()->user()->tickets()->latest()->paginate(10)->appends($request->except('page')), - ]); - } - - // 订单 - public function invoices(Request $request) - { - return view('user.invoices', [ - 'orderList' => auth()->user()->orders()->with(['goods', 'payment'])->orderByDesc('id')->paginate(10)->appends($request->except('page')), - 'prepaidPlan' => Order::userPrepay()->exists(), - ]); - } - - public function closePlan(): JsonResponse - { - $activePlan = Order::userActivePlan()->first(); - if ($activePlan) { - if ($activePlan->expired()) { // 关闭先前套餐后,新套餐自动运行 - if (Order::userActivePlan()->exists()) { - return Response::json(['status' => 'success', 'message' => trans('common.active_item', ['attribute' => trans('common.success')])]); - } - - return Response::json(['status' => 'success', 'message' => trans('common.close')]); + if (! Hash::check($data['password'], $user->password)) { + return Redirect::back()->withErrors(trans('auth.password.reset.error.wrong')); } - } else { - $prepaidPlan = Order::userPrepay()->first(); - if ($prepaidPlan) { // 关闭先前套餐后,新套餐自动运行 - if ($prepaidPlan->complete()) { - return Response::json(['status' => 'success', 'message' => trans('common.active_item', ['attribute' => trans('common.success')])]); - } - return Response::json(['status' => 'success', 'message' => trans('common.close')]); + if (Hash::check($data['new_password'], $user->password)) { + return Redirect::back()->withErrors(trans('auth.password.reset.error.same')); + } + + // 演示环境禁止改管理员密码 + if ($user->id === 1 && config('app.env') === 'demo') { + return Redirect::back()->withErrors(trans('auth.password.reset.error.demo')); + } + + if (! $user->update(['password' => $data['new_password']])) { + return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); + } + + return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); + // 修改代理密码 + } + + if ($request->has('passwd')) { + $passwd = $request->input('passwd'); + if (! $user->update(['passwd' => $passwd])) { + return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); + } + + return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); + } + + // 修改联系方式 + if ($request->has(['nickname', 'wechat', 'qq'])) { + $data = $request->only(['nickname', 'wechat', 'qq']); + if (empty($data['nickname'])) { + return Redirect::back()->withErrors(trans('validation.required', ['attribute' => trans('model.user.nickname')])); + } + + if (! $user->update($data)) { + return Redirect::back()->withErrors(trans('common.failed_item', ['attribute' => trans('common.update')])); } } - return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.close')])]); - } - - // 订单明细 - public function invoiceDetail($sn) - { - return view('user.invoiceDetail', ['order' => Order::uid()->whereSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail()]); - } - - // 添加工单 - public function createTicket(Request $request): ?JsonResponse - { - $user = auth()->user(); - $title = $request->input('title'); - $content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300); - - if (empty($title) || empty($content)) { - return Response::json([ - 'status' => 'fail', 'message' => trans('validation.required', ['attribute' => ucfirst(trans('validation.attributes.title')).'&'.ucfirst(trans('validation.attributes.content'))]), - ]); - } - - if ($ticket = $user->tickets()->create(compact('title', 'content'))) { - // 通知相关管理员 - Notification::send(User::find(1), new TicketCreated($ticket, route('admin.ticket.edit', $ticket))); - } - - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.submit')])]); - } - - // 回复工单 - public function replyTicket(Request $request) - { - $id = $request->input('id'); - - $ticket = Ticket::uid()->with('user')->whereId($id)->firstOrFail(); - - if ($request->isMethod('POST')) { - $content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300); - - if (empty($content)) { - return Response::json([ - 'status' => 'fail', 'message' => trans('validation.required', ['attribute' => ucfirst(trans('validation.attributes.title')).'&'.ucfirst(trans('validation.attributes.content'))]), - ]); - } - - $reply = $ticket->reply()->create(['user_id' => auth()->id(), 'content' => $content]); - if ($reply) { - // 重新打开工单 - if ($ticket->status === 2) { - $ticket->update(['status' => 0]); - } - - // 通知相关管理员 - Notification::send(User::find(1), new TicketReplied($reply, route('admin.ticket.edit', $ticket))); - - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.ticket.reply')])]); - } - - return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('user.ticket.reply')])]); - } - - return view('user.replyTicket', [ - 'ticket' => $ticket, - 'replyList' => $ticket->reply()->with('ticket:id,status', 'admin:id,username,qq', 'user:id,username,qq')->oldest()->get(), - ]); - } - - // 关闭工单 - public function closeTicket(Request $request): ?JsonResponse - { - $id = $request->input('id'); - - if (Ticket::uid()->whereId($id)->firstOrFail()->close()) { - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.close')])]); - } - - return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.close')])]); - } - - // 邀请码 - public function invite() - { - if (Order::uid()->active()->where('origin_amount', '>', 0)->doesntExist()) { - return Response::view('auth.error', ['message' => trans('user.purchase.required').' '.trans('common.back').''], 402); - } - - return view('user.invite', [ - 'num' => auth()->user()->invite_num, // 还可以生成的邀请码数量 - 'inviteList' => Invite::uid()->with(['invitee', 'inviter'])->paginate(10), // 邀请码列表 - 'referral_traffic' => formatBytes(sysConfig('referral_traffic'), 'MiB'), - 'referral_percent' => sysConfig('referral_percent'), - ]); - } - - // 生成邀请码 - public function makeInvite(): JsonResponse - { - $user = auth()->user(); - if ($user->invite_num <= 0) { - return Response::json(['status' => 'fail', 'message' => trans('user.invite.generate_failed')]); - } - $invite = $user->invites()->create([ - 'code' => strtoupper(mb_substr(md5(microtime().Str::random()), 8, 12)), - 'dateline' => date('Y-m-d H:i:s', strtotime(sysConfig('user_invite_days').' days')), - ]); - if ($invite) { - $user->decrement('invite_num'); - - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.generate')])]); - } - - return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.generate')])]); - } - - // 使用优惠券 - public function redeemCoupon(Request $request, Goods $good): JsonResponse - { - $coupon_sn = $request->input('coupon_sn'); - - if (empty($coupon_sn)) { - return Response::json(['status' => 'fail', 'title' => trans('common.failed'), 'message' => trans('user.coupon.error.unknown')]); - } - - $coupon = (new CouponService($coupon_sn))->search($good); // 检查券合规性 - - if (! $coupon instanceof Coupon) { - return $coupon; - } - - $data = [ - 'name' => $coupon->name, - 'type' => $coupon->type, - 'value' => $coupon->type === 2 ? $coupon->value : Helpers::getPriceTag($coupon->value), - ]; - - return Response::json(['status' => 'success', 'data' => $data, 'message' => trans('common.applied', ['attribute' => trans('model.coupon.attribute')])]); - } - - // 购买服务 - public function buy(Goods $good) - { - $user = auth()->user(); - // 有重置日时按照重置日为标准,否则就以过期日为标准 - $dataPlusDays = $user->reset_time ?? $user->expired_at; - - return view('user.buy', [ - 'dataPlusDays' => $dataPlusDays > date('Y-m-d') ? $dataPlusDays->diffInDays() : 0, - 'activePlan' => Order::userActivePlan()->exists(), - 'goods' => $good, - ]); - } - - // 帮助中心 - public function knowledge() - { - $data = []; - if (Node::whereType(0)->whereStatus(1)->exists()) { - $data[] = 'ss'; - } - if (Node::whereIn('type', [1, 4])->whereStatus(1)->exists()) { - $data[] = 'ssr'; - } - if (Node::whereType(2)->whereStatus(1)->exists()) { - $data[] = 'v2'; - } - if (Node::whereType(3)->whereStatus(1)->exists()) { - $data[] = 'trojan'; - } - - $subscribe = auth()->user()->subscribe; - - return view('user.knowledge', [ - 'subType' => $data, - 'subUrl' => route('sub', $subscribe->code), - 'subStatus' => $subscribe->status, - 'subMsg' => $subscribe->ban_desc, - 'knowledges' => Article::type(1)->lang()->orderByDesc('sort')->latest()->get()->groupBy('category'), - ]); + return Redirect::back()->with('successMsg', trans('common.success_item', ['attribute' => trans('common.update')])); } public function exchangeSubscribe(): ?JsonResponse @@ -508,27 +192,6 @@ class UserController extends Controller return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.toggle')])]); } - public function charge(Request $request): ?JsonResponse - { - $validator = Validator::make($request->all(), [ - 'coupon_sn' => [ - 'required', Rule::exists('coupon', 'sn')->where(static function ($query) { - $query->whereType(3)->whereStatus(0); - }), - ], - ]); - - if ($validator->fails()) { - return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]); - } - - if ((new CouponService($request->input('coupon_sn')))->charge()) { - return Response::json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.recharge')])]); - } - - return Response::json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('user.recharge')])]); - } - public function switchCurrency(string $code): RedirectResponse { // 切换语言 Session::put('currency', $code); diff --git a/app/Notifications/PaymentReceived.php b/app/Notifications/PaymentReceived.php index 188141fb..6b2ca338 100644 --- a/app/Notifications/PaymentReceived.php +++ b/app/Notifications/PaymentReceived.php @@ -24,7 +24,7 @@ class PaymentReceived extends Notification implements ShouldQueue public function toMail($notifiable): MailMessage { return (new MailMessage)->subject(__('Payment Received'))->line(__('Payment for #:sn has been received! Total amount: :amount.', ['sn' => $this->sn, 'amount' => $this->amountWithSign]))->action(__('Invoice Detail'), - route('invoiceInfo', $this->sn)); + route('invoice.show', $this->sn)); } public function toDataBase($notifiable): array diff --git a/app/Utils/Payments/CodePay.php b/app/Utils/Payments/CodePay.php index 925c25ff..c939ac3c 100644 --- a/app/Utils/Payments/CodePay.php +++ b/app/Utils/Payments/CodePay.php @@ -25,7 +25,7 @@ class CodePay extends PaymentService implements Gateway 'page' => 1, 'outTime' => 900, 'notify_url' => route('payment.notify', ['method' => 'codepay']), - 'return_url' => route('invoice'), + 'return_url' => route('invoice.index'), ]; $data['sign'] = PaymentHelper::aliStyleSign($data, sysConfig('codepay_key')); diff --git a/app/Utils/Payments/EPay.php b/app/Utils/Payments/EPay.php index b370c23c..2a330c93 100644 --- a/app/Utils/Payments/EPay.php +++ b/app/Utils/Payments/EPay.php @@ -22,7 +22,7 @@ class EPay extends PaymentService implements Gateway 'pid' => sysConfig('epay_mch_id'), 'type' => [1 => 'alipay', 2 => 'qqpay', 3 => 'wxpay'][$request->input('type')] ?? 'alipay', 'notify_url' => route('payment.notify', ['method' => 'epay']), - 'return_url' => route('invoice'), + 'return_url' => route('invoice.index'), 'out_trade_no' => $payment->trade_no, 'name' => sysConfig('subject_name') ?: sysConfig('website_name'), 'money' => $payment->amount, diff --git a/app/Utils/Payments/PayBeaver.php b/app/Utils/Payments/PayBeaver.php index a282a81e..36f55c4e 100644 --- a/app/Utils/Payments/PayBeaver.php +++ b/app/Utils/Payments/PayBeaver.php @@ -39,7 +39,7 @@ class PayBeaver extends PaymentService implements Gateway 'merchant_order_id' => $payment->trade_no, 'price_amount' => $payment->amount * 110, 'notify_url' => route('payment.notify', ['method' => 'paybeaver']), - 'return_url' => route('invoice'), + 'return_url' => route('invoice.index'), ]); if (! isset($result['message']) && isset($result['data']['pay_url'])) { diff --git a/app/Utils/Payments/PayPal.php b/app/Utils/Payments/PayPal.php index 9c141670..4978f959 100644 --- a/app/Utils/Payments/PayPal.php +++ b/app/Utils/Payments/PayPal.php @@ -48,7 +48,7 @@ class PayPal extends PaymentService implements Gateway 'intent' => 'CAPTURE', 'application_context' => [ 'return_url' => route('payment.notify', ['method' => 'paypal']), - 'cancel_url' => route('invoice'), + 'cancel_url' => route('invoice.index'), ], 'purchase_units' => [ 0 => [ @@ -98,7 +98,7 @@ class PayPal extends PaymentService implements Gateway ], 'invoice_description' => $trade_no, 'return_url' => route('payment.notify', ['method' => 'paypal']), - 'cancel_url' => route('invoice'), + 'cancel_url' => route('invoice.index'), 'total' => $amount, ]; } diff --git a/app/Utils/Payments/Stripe.php b/app/Utils/Payments/Stripe.php index 1d034287..7dbdbb1e 100644 --- a/app/Utils/Payments/Stripe.php +++ b/app/Utils/Payments/Stripe.php @@ -41,7 +41,7 @@ class Stripe extends PaymentService implements Gateway 'identifier' => '', ], 'redirect' => [ - 'return_url' => route('invoice'), + 'return_url' => route('invoice.index'), ], ]); if ($type === 3) { @@ -99,8 +99,8 @@ class Stripe extends PaymentService implements Gateway ], ], 'mode' => 'payment', - 'success_url' => route('invoice'), - 'cancel_url' => route('invoice'), + 'success_url' => route('invoice.index'), + 'cancel_url' => route('invoice.index'), 'client_reference_id' => $tradeNo, 'customer_email' => Auth::getUser()->email, ]; diff --git a/database/seeders/LabelSeeder.php b/database/seeders/LabelSeeder.php index 376bc81e..2b658b16 100644 --- a/database/seeders/LabelSeeder.php +++ b/database/seeders/LabelSeeder.php @@ -19,12 +19,12 @@ class LabelSeeder extends Seeder 'Happyon', 'AbemeTV', 'DMM', - 'NicoNico', + 'Niconico', 'Pixiv', 'TVer', 'TVB', 'HBO Go', - 'BiliBili港澳台', + 'Bilibili 港澳台', '動畫瘋', '四季線上影視', 'LINE TV', diff --git a/resources/views/admin/article/show.blade.php b/resources/views/admin/article/show.blade.php index e1fefd63..bfc22b9a 100644 --- a/resources/views/admin/article/show.blade.php +++ b/resources/views/admin/article/show.blade.php @@ -41,7 +41,7 @@ if (!document.getElementById("article_B" + id).innerHTML) { $.ajax({ method: "GET", - url: '{{ route('article', '') }}/' + id, + url: '{{ route('admin.article.show', '') }}/' + id, beforeSend: function() { $("#loading_article").show(); }, diff --git a/resources/views/admin/config/common.blade.php b/resources/views/admin/config/common.blade.php index 5e12269e..c4d6a988 100644 --- a/resources/views/admin/config/common.blade.php +++ b/resources/views/admin/config/common.blade.php @@ -37,7 +37,7 @@ - +
@@ -71,7 +71,7 @@ -
{{ ucfirst(trans('validation.attributes.name')) }}
+
@@ -105,7 +105,7 @@ -
{{ ucfirst(trans('validation.attributes.name')) }}
+
@@ -139,7 +139,7 @@ -
{{ ucfirst(trans('validation.attributes.name')) }}
+
@@ -176,7 +176,7 @@ -
{{ trans('model.common.level') }}
+
@@ -213,7 +213,7 @@ -
{{ ucfirst(trans('validation.attributes.name')) }}
+
@@ -253,7 +253,7 @@ -
{{ trans('model.country.icon') }}
+
diff --git a/resources/views/admin/logs/order.blade.php b/resources/views/admin/logs/order.blade.php index 2d98428b..564f9394 100644 --- a/resources/views/admin/logs/order.blade.php +++ b/resources/views/admin/logs/order.blade.php @@ -61,7 +61,7 @@
{{ ucfirst(trans('validation.attributes.name')) }} @can('admin.user.exportProxy')
- - -
@endcan @@ -86,12 +86,19 @@ @can('admin.user.exportProxy')