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 @@
-
+
| {{ ucfirst(trans('validation.attributes.name')) }} |
@@ -71,7 +71,7 @@
-
+
| {{ ucfirst(trans('validation.attributes.name')) }} |
@@ -105,7 +105,7 @@
-
+
| {{ ucfirst(trans('validation.attributes.name')) }} |
@@ -139,7 +139,7 @@
-
+
| {{ trans('model.common.level') }} |
@@ -176,7 +176,7 @@
-
+
| {{ ucfirst(trans('validation.attributes.name')) }} |
@@ -213,7 +213,7 @@
-
+
| {{ trans('model.country.icon') }} |
@@ -253,7 +253,7 @@
-
+
| {{ ucfirst(trans('validation.attributes.name')) }} |
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 @@