瀏覽代碼

Merge branch 'dev'

兔姬桑 4 年之前
父節點
當前提交
7f3618a2fb
共有 100 個文件被更改,包括 1823 次插入1229 次删除
  1. 2 3
      .gitignore
  2. 3 3
      app/Components/CaptchaVerify.php
  3. 6 6
      app/Components/DDNS/Aliyun.php
  4. 10 10
      app/Components/DDNS/DNSPod.php
  5. 10 10
      app/Components/DDNS/Namesilo.php
  6. 7 7
      app/Components/Helpers.php
  7. 16 16
      app/Components/IP.php
  8. 1 1
      app/Console/Commands/AutoClearLog.php
  9. 4 12
      app/Console/Commands/AutoJob.php
  10. 1 1
      app/Console/Commands/AutoStatisticsUserDailyTraffic.php
  11. 1 1
      app/Console/Commands/AutoStatisticsUserHourlyTraffic.php
  12. 17 19
      app/Console/Commands/DailyJob.php
  13. 4 4
      app/Console/Commands/ServiceTimer.php
  14. 1 1
      app/Console/Commands/UserTrafficAbnormalAutoWarning.php
  15. 1 1
      app/Console/Commands/UserTrafficAutoWarning.php
  16. 0 1
      app/Console/Kernel.php
  17. 5 8
      app/Exceptions/Handler.php
  18. 28 19
      app/Http/Controllers/Admin/ArticleController.php
  19. 1 1
      app/Http/Controllers/Admin/Config/EmailFilterController.php
  20. 0 1
      app/Http/Controllers/Admin/Config/LabelController.php
  21. 4 4
      app/Http/Controllers/Admin/Config/LevelController.php
  22. 5 3
      app/Http/Controllers/Admin/CouponController.php
  23. 2 2
      app/Http/Controllers/Admin/MarketingController.php
  24. 8 8
      app/Http/Controllers/Admin/NodeController.php
  25. 71 0
      app/Http/Controllers/Admin/PermissionController.php
  26. 78 0
      app/Http/Controllers/Admin/RoleController.php
  27. 2 2
      app/Http/Controllers/Admin/RuleController.php
  28. 4 5
      app/Http/Controllers/Admin/RuleGroupController.php
  29. 33 19
      app/Http/Controllers/Admin/ShopController.php
  30. 30 49
      app/Http/Controllers/Admin/SystemController.php
  31. 7 23
      app/Http/Controllers/Admin/TicketController.php
  32. 17 29
      app/Http/Controllers/Admin/ToolsController.php
  33. 62 70
      app/Http/Controllers/Admin/UserController.php
  34. 20 16
      app/Http/Controllers/Admin/UserGroupController.php
  35. 1 34
      app/Http/Controllers/AdminController.php
  36. 5 5
      app/Http/Controllers/Api/WebApi/BaseController.php
  37. 9 9
      app/Http/Controllers/Api/WebApi/TrojanController.php
  38. 20 20
      app/Http/Controllers/Api/WebApi/V2RayController.php
  39. 20 20
      app/Http/Controllers/Api/WebApi/VNetController.php
  40. 40 52
      app/Http/Controllers/AuthController.php
  41. 4 4
      app/Http/Controllers/Controller.php
  42. 11 11
      app/Http/Controllers/Gateway/BitpayX.php
  43. 6 6
      app/Http/Controllers/Gateway/CodePay.php
  44. 7 7
      app/Http/Controllers/Gateway/EPay.php
  45. 13 13
      app/Http/Controllers/Gateway/F2Fpay.php
  46. 4 4
      app/Http/Controllers/Gateway/PayJs.php
  47. 17 17
      app/Http/Controllers/Gateway/PayPal.php
  48. 10 10
      app/Http/Controllers/Gateway/Stripe.php
  49. 0 2
      app/Http/Controllers/PaymentController.php
  50. 0 2
      app/Http/Controllers/User/AffiliateController.php
  51. 6 6
      app/Http/Controllers/User/SubscribeController.php
  52. 30 45
      app/Http/Controllers/UserController.php
  53. 27 19
      app/Http/Kernel.php
  54. 1 1
      app/Http/Middleware/Affiliate.php
  55. 0 1
      app/Http/Middleware/Authenticate.php
  56. 2 1
      app/Http/Middleware/CheckForMaintenanceMode.php
  57. 2 1
      app/Http/Middleware/EncryptCookies.php
  58. 31 0
      app/Http/Middleware/Permission.php
  59. 2 3
      app/Http/Middleware/RedirectIfAuthenticated.php
  60. 0 28
      app/Http/Middleware/isAdmin.php
  61. 1 1
      app/Http/Middleware/isMaintenance.php
  62. 4 4
      app/Http/Requests/Admin/ArticleRequest.php
  63. 8 7
      app/Http/Requests/Admin/CouponRequest.php
  64. 31 31
      app/Http/Requests/Admin/NodeRequest.php
  65. 6 5
      app/Http/Requests/Admin/ShopStoreRequest.php
  66. 2 1
      app/Http/Requests/Admin/ShopUpdateRequest.php
  67. 1 1
      app/Http/Requests/Admin/UserStoreRequest.php
  68. 17 18
      app/Http/Requests/Admin/UserUpdateRequest.php
  69. 1 1
      app/Mail/closeTicket.php
  70. 1 1
      app/Mail/newTicket.php
  71. 1 1
      app/Mail/replyTicket.php
  72. 7 0
      app/Models/Ticket.php
  73. 85 7
      app/Models/User.php
  74. 1 1
      app/Models/UserDailyDataFlow.php
  75. 2 2
      app/Models/UserHourlyDataFlow.php
  76. 0 11
      app/Observers/NodeObserver.php
  77. 3 43
      app/Observers/UserObserver.php
  78. 5 1
      app/Providers/AuthServiceProvider.php
  79. 18 1
      app/Providers/RouteServiceProvider.php
  80. 1 1
      app/Providers/TelescopeServiceProvider.php
  81. 7 16
      app/Services/OrderService.php
  82. 0 51
      app/Services/UserService.php
  83. 10 8
      composer.json
  84. 530 131
      composer.lock
  85. 3 3
      config/HCaptcha.php
  86. 3 3
      config/NoCaptcha.php
  87. 37 37
      config/app.php
  88. 7 7
      config/auth.php
  89. 6 6
      config/broadcasting.php
  90. 16 16
      config/cache.php
  91. 31 31
      config/captcha.php
  92. 49 49
      config/database.php
  93. 11 11
      config/filesystems.php
  94. 6 6
      config/geetest.php
  95. 2 2
      config/hashing.php
  96. 7 7
      config/ide-helper.php
  97. 1 1
      config/lang-publisher.php
  98. 20 20
      config/logging.php
  99. 10 10
      config/mail.php
  100. 143 0
      config/permission.php

+ 2 - 3
.gitignore

@@ -8,7 +8,8 @@
 /storage/app/public
 /storage/*.key
 /vendor
-composer.phar
+.env
+.phpunit.result.cache
 /.idea
 /.vagrant
 /.vscode
@@ -19,8 +20,6 @@ npm-debug.log
 .DS_Store
 .phpstorm.meta.php
 yarn-error.log
-.env
-.phpunit.result.cache
 _ide_helper_models.php
 _ide_helper.php
 .php_cs.cache

+ 3 - 3
app/Components/CaptchaVerify.php

@@ -12,7 +12,7 @@ class CaptchaVerify
     {
         return [
             'sitekey' => sysConfig('hcaptcha_sitekey'),
-            'secret'  => sysConfig('hcaptcha_secret'),
+            'secret' => sysConfig('hcaptcha_secret'),
             'options' => [],
         ];
     }
@@ -21,7 +21,7 @@ class CaptchaVerify
     public static function geetestCaptchaGetConfig(): array
     {
         return [
-            'geetest_id'  => sysConfig('geetest_id'),
+            'geetest_id' => sysConfig('geetest_id'),
             'geetest_key' => sysConfig('geetest_key'),
         ];
     }
@@ -31,7 +31,7 @@ class CaptchaVerify
     {
         return [
             'sitekey' => sysConfig('google_captcha_sitekey'),
-            'secret'  => sysConfig('google_captcha_secret'),
+            'secret' => sysConfig('google_captcha_secret'),
             'options' => [],
         ];
     }

+ 6 - 6
app/Components/DDNS/Aliyun.php

@@ -57,13 +57,13 @@ class Aliyun
     private function send($action, $data = [])
     {
         $public = [
-            'Format'           => 'JSON',
-            'Version'          => '2015-01-09',
-            'AccessKeyId'      => sysConfig('ddns_key'),
-            'SignatureMethod'  => 'HMAC-SHA1',
-            'Timestamp'        => gmdate("Y-m-d\TH:i:s\Z"), //公共参数Timestamp GMT时间
+            'Format' => 'JSON',
+            'Version' => '2015-01-09',
+            'AccessKeyId' => sysConfig('ddns_key'),
+            'SignatureMethod' => 'HMAC-SHA1',
+            'Timestamp' => gmdate("Y-m-d\TH:i:s\Z"), //公共参数Timestamp GMT时间
             'SignatureVersion' => '1.0',
-            'SignatureNonce'   => str_replace('.', '', microtime(true)), //唯一数,用于防止网络重放攻击
+            'SignatureNonce' => str_replace('.', '', microtime(true)), //唯一数,用于防止网络重放攻击
         ];
         $parameters = array_merge(['Action' => $action], $data, $public);
         $parameters['Signature'] = $this->computeSignature($parameters);

+ 10 - 10
app/Components/DDNS/DNSPod.php

@@ -22,11 +22,11 @@ class DNSPod
 
         if ($domainInfo) {
             return $this->send('Record.Create', [
-                'domain_id'      => $domainInfo[2],
-                'sub_domain'     => $domainInfo[1],
-                'record_type'    => $type,
+                'domain_id' => $domainInfo[2],
+                'sub_domain' => $domainInfo[1],
+                'record_type' => $type,
                 'record_line_id' => 0,
-                'value'          => $ip,
+                'value' => $ip,
             ]);
         }
 
@@ -61,7 +61,7 @@ class DNSPod
     {
         $public = [
             'login_token' => sysConfig('ddns_key').','.sysConfig('ddns_secret'),
-            'format'      => 'json',
+            'format' => 'json',
         ];
         $parameters = array_merge($data, $public);
 
@@ -88,12 +88,12 @@ class DNSPod
         $domainInfo = $this->analysisDomain();
         if ($recordId && $domainInfo) {
             return $this->send('Record.Modify', [
-                'domain_id'      => $domainInfo[2],
-                'record_id'      => $recordId[0],
-                'sub_domain'     => $domainInfo[1],
-                'record_type'    => $type,
+                'domain_id' => $domainInfo[2],
+                'record_id' => $recordId[0],
+                'sub_domain' => $domainInfo[1],
+                'record_type' => $type,
                 'record_line_id' => 0,
-                'value'          => $ip,
+                'value' => $ip,
             ]);
         }
 

+ 10 - 10
app/Components/DDNS/Namesilo.php

@@ -20,11 +20,11 @@ class Namesilo
         $domainInfo = $this->analysisDomain();
         if ($domainInfo) {
             return $this->send('dnsAddRecord', [
-                'domain'  => $domainInfo[0],
-                'rrtype'  => $type,
-                'rrhost'  => $domainInfo[1],
+                'domain' => $domainInfo[0],
+                'rrtype' => $type,
+                'rrhost' => $domainInfo[1],
                 'rrvalue' => $ip,
-                'rrttl'   => 3600,
+                'rrttl' => 3600,
             ]);
         }
 
@@ -63,8 +63,8 @@ class Namesilo
     {
         $params = [
             'version' => 1,
-            'type'    => 'xml',
-            'key'     => sysConfig('ddns_key'),
+            'type' => 'xml',
+            'key' => sysConfig('ddns_key'),
         ];
         $query = array_merge($params, $data);
 
@@ -86,11 +86,11 @@ class Namesilo
         $domainInfo = $this->analysisDomain();
 
         return $this->send('dnsUpdateRecord', [
-            'domain'  => $domainInfo[0],
-            'rrid'    => $recordId[0],
-            'rrhost'  => $domainInfo[1],
+            'domain' => $domainInfo[0],
+            'rrid' => $recordId[0],
+            'rrhost' => $domainInfo[1],
             'rrvalue' => $ip,
-            'rrttl'   => 3600,
+            'rrttl' => 3600,
         ]);
     }
 

+ 7 - 7
app/Components/Helpers.php

@@ -193,12 +193,12 @@ class Helpers
      *
      * @param  string  $description  备注
      * @param  int  $couponId  优惠券ID
-     * @param  int  $goodsId  商品ID
-     * @param  int  $orderId  订单ID
+     * @param  int|null  $goodsId  商品ID
+     * @param  int|null  $orderId  订单ID
      *
      * @return bool
      */
-    public static function addCouponLog(string $description, int $couponId, $goodsId = 0, $orderId = 0): bool
+    public static function addCouponLog($description, $couponId, $goodsId = null, $orderId = null): bool
     {
         $log = new CouponLog();
         $log->coupon_id = $couponId;
@@ -213,7 +213,7 @@ class Helpers
      * 记录余额操作日志.
      *
      * @param  int  $userId  用户ID
-     * @param  int  $orderId  订单ID
+     * @param  int|null  $orderId  订单ID
      * @param  int  $before  记录前余额
      * @param  int  $after  记录后余额
      * @param  int  $amount  发生金额
@@ -221,7 +221,7 @@ class Helpers
      *
      * @return bool
      */
-    public static function addUserCreditLog(int $userId, int $orderId, int $before, int $after, int $amount, $description = ''): bool
+    public static function addUserCreditLog($userId, $orderId, $before, $after, $amount, $description = ''): bool
     {
         $log = new UserCreditLog();
         $log->user_id = $userId;
@@ -239,14 +239,14 @@ class Helpers
      * 记录流量变动日志.
      *
      * @param  int  $userId  用户ID
-     * @param  int  $orderId  订单ID
+     * @param  int|null  $orderId  订单ID
      * @param  int  $before  记录前的值
      * @param  int  $after  记录后的值
      * @param  string  $description  描述
      *
      * @return bool
      */
-    public static function addUserTrafficModifyLog(int $userId, int $orderId, int $before, int $after, $description = ''): bool
+    public static function addUserTrafficModifyLog($userId, $orderId, $before, $after, $description = ''): bool
     {
         $log = new UserDataModifyLog();
         $log->user_id = $userId;

+ 16 - 16
app/Components/IP.php

@@ -60,11 +60,11 @@ class IP
             $location = explode('|', $ipInfo['region']);
 
             return [
-                'country'  => $location[0] ?: '',
+                'country' => $location[0] ?: '',
                 'province' => $location[2] ?: '',
-                'city'     => $location[3] ?: '',
-                'isp'      => $location[4] ?: '',
-                'area'     => $location[1] ?: '',
+                'city' => $location[3] ?: '',
+                'isp' => $location[4] ?: '',
+                'area' => $location[1] ?: '',
             ];
         }
 
@@ -80,9 +80,9 @@ class IP
                 ->lookup($ip, [Database::CITY_NAME, Database::REGION_NAME, Database::COUNTRY_NAME]);
 
             return [
-                'country'  => $location['countryName'],
+                'country' => $location['countryName'],
                 'province' => $location['regionName'],
-                'city'     => $location['cityName'],
+                'city' => $location['cityName'],
             ];
         } catch (Exception $e) {
             Log::error('【ip2Location】错误信息:'.$e->getMessage());
@@ -98,9 +98,9 @@ class IP
         $location = (new City($filePath))->findMap($ip, 'CN');
 
         return [
-            'country'  => $location['country_name'],
+            'country' => $location['country_name'],
             'province' => $location['region_name'],
-            'city'     => $location['city_name'],
+            'city' => $location['city_name'],
         ];
     }
 
@@ -114,10 +114,10 @@ class IP
             $message = $response->json();
             if ($message['code'] === 0) {
                 return [
-                    'country'  => $message['data']['country'] === 'XX' ? '' : $message['data']['country'],
+                    'country' => $message['data']['country'] === 'XX' ? '' : $message['data']['country'],
                     'province' => $message['data']['region'] === 'XX' ? '' : $message['data']['region'],
-                    'city'     => $message['data']['city'] === 'XX' ? '' : $message['data']['city'],
-                    'isp'      => $message['data']['isp'] === 'XX' ? '' : $message['data']['isp'],
+                    'city' => $message['data']['city'] === 'XX' ? '' : $message['data']['city'],
+                    'isp' => $message['data']['isp'] === 'XX' ? '' : $message['data']['isp'],
                 ];
             }
 
@@ -144,10 +144,10 @@ class IP
             $message = $response->json();
             if ($message['status'] === 0) {
                 return [
-                    'country'  => $message['content']['address_detail']['country'],
+                    'country' => $message['content']['address_detail']['country'],
                     'province' => $message['content']['address_detail']['province'],
-                    'city'     => $message['content']['address_detail']['city'],
-                    'area'     => $message['address'],
+                    'city' => $message['content']['address_detail']['city'],
+                    'area' => $message['address'],
                 ];
             }
 
@@ -167,9 +167,9 @@ class IP
             $location = (new Reader($filePath))->city($ip);
 
             return [
-                'country'  => $location->country->names['zh-CN'],
+                'country' => $location->country->names['zh-CN'],
                 'province' => '',
-                'city'     => $location->city->name ?? '',
+                'city' => $location->city->name ?? '',
             ];
         } catch (AddressNotFoundException $e) {
             Log::error('【GeoIP2】查询失败:'.$ip);

+ 1 - 1
app/Console/Commands/AutoClearLog.php

@@ -54,7 +54,7 @@ class AutoClearLog extends Command
             UserHourlyDataFlow::where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
 
             // 清除用户各节点 / 节点总计的每天流量数据日志
-            UserDailyDataFlow::where('node_id', '<>', 0)
+            UserDailyDataFlow::where('node_id', '<>', null)
                 ->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-1 month')))
                 ->orWhere('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))
                 ->delete();

+ 4 - 12
app/Console/Commands/AutoJob.php

@@ -12,7 +12,6 @@ use App\Models\NodeHeartBeat;
 use App\Models\Order;
 use App\Models\User;
 use App\Models\UserBanedLog;
-use App\Models\UserHourlyDataFlow;
 use App\Models\VerifyCode;
 use Cache;
 use Illuminate\Console\Command;
@@ -107,7 +106,7 @@ class AutoJob extends Command
                     ->count('request_ip');
                 if ($request_times >= $subscribe_ban_times) {
                     $user->subscribe->update([
-                        'status'   => 0,
+                        'status' => 0,
                         'ban_time' => strtotime('+'.sysConfig('traffic_ban_time').' minutes'),
                         'ban_desc' => '存在异常,自动封禁',
                     ]);
@@ -148,19 +147,12 @@ class AutoJob extends Command
 
         // 封禁1小时内流量异常账号
         if (sysConfig('is_traffic_ban')) {
-            $trafficBanValue = sysConfig('traffic_ban_value');
             $trafficBanTime = sysConfig('traffic_ban_time');
             foreach (User::activeUser()->whereBanTime(null)->get() as $user) {
-                // 对管理员豁免
-                if ($user->is_admin) {
-                    continue;
-                }
-
                 // 多往前取5分钟,防止数据统计任务执行时间过长导致没有数据
-                $totalTraffic = UserHourlyDataFlow::userRecentUsed($user->id)->sum('total');
-                if ($totalTraffic >= $trafficBanValue * GB) {
+                if ($user->isTrafficWarning()) {
                     $user->update([
-                        'enable'   => 0,
+                        'enable' => 0,
                         'ban_time' => strtotime('+'.$trafficBanTime.' minutes'),
                     ]);
 
@@ -177,7 +169,7 @@ class AutoJob extends Command
         // 解封被临时封禁的账号
         $userList = User::whereEnable(0)->where('status', '>=', 0)->whereNotNull('ban_time')->get();
         foreach ($userList as $user) {
-            if ($user->ban_time < time()) {
+            if ($user->getRawOriginal('ban_time') < time()) {
                 $user->update(['enable' => 1, 'ban_time' => null]);
 
                 // 写入操作日志

+ 1 - 1
app/Console/Commands/AutoStatisticsUserDailyTraffic.php

@@ -34,7 +34,7 @@ class AutoStatisticsUserDailyTraffic extends Command
         Log::info('---【'.$this->description.'】完成---,耗时'.$jobUsedTime.'秒');
     }
 
-    private function statisticsByUser($user_id, $node_id = 0): void
+    private function statisticsByUser($user_id, $node_id = null): void
     {
         $query = UserDataFlowLog::whereUserId($user_id)->whereBetween('log_time', [strtotime(date('Y-m-d')), time()]);
 

+ 1 - 1
app/Console/Commands/AutoStatisticsUserHourlyTraffic.php

@@ -34,7 +34,7 @@ class AutoStatisticsUserHourlyTraffic extends Command
         Log::info('---【'.$this->description.'】完成---,耗时'.$jobUsedTime.'秒');
     }
 
-    private function statisticsByNode($user_id, $node_id = 0): void
+    private function statisticsByNode($user_id, $node_id = null): void
     {
         $query = UserDataFlowLog::whereUserId($user_id)->whereBetween('log_time', [strtotime('-1 hour'), time()]);
 

+ 17 - 19
app/Console/Commands/DailyJob.php

@@ -47,14 +47,14 @@ class DailyJob extends Command
         foreach ($userList as $user) {
             if ($isBanStatus) {
                 $user->update([
-                    'u'               => 0,
-                    'd'               => 0,
+                    'u' => 0,
+                    'd' => 0,
                     'transfer_enable' => 0,
-                    'enable'          => 0,
-                    'level'           => 0,
-                    'reset_time'      => null,
-                    'ban_time'        => null,
-                    'status'          => -1,
+                    'enable' => 0,
+                    'level' => 0,
+                    'reset_time' => null,
+                    'ban_time' => null,
+                    'status' => -1,
                 ]);
 
                 $this->addUserBanLog($user->id, 0, '【禁止登录,清空账户】-账号已过期');
@@ -63,22 +63,22 @@ class DailyJob extends Command
                 Invite::whereInviterId($user->id)->whereStatus(0)->update(['status' => 2]);
 
                 // 写入用户流量变动记录
-                Helpers::addUserTrafficModifyLog($user->id, 0, $user->transfer_enable, 0, '[定时任务]账号已过期(禁止登录,清空账户)');
+                Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, 0, '[定时任务]账号已过期(禁止登录,清空账户)');
             } else {
                 $user->update([
-                    'u'               => 0,
-                    'd'               => 0,
+                    'u' => 0,
+                    'd' => 0,
                     'transfer_enable' => 0,
-                    'enable'          => 0,
-                    'level'           => 0,
-                    'reset_time'      => null,
-                    'ban_time'        => null,
+                    'enable' => 0,
+                    'level' => 0,
+                    'reset_time' => null,
+                    'ban_time' => null,
                 ]);
 
                 $this->addUserBanLog($user->id, 0, '【封禁代理,清空账户】-账号已过期');
 
                 // 写入用户流量变动记录
-                Helpers::addUserTrafficModifyLog($user->id, 0, $user->transfer_enable, 0, '[定时任务]账号已过期(封禁代理,清空账户)');
+                Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, 0, '[定时任务]账号已过期(封禁代理,清空账户)');
             }
         }
     }
@@ -104,10 +104,8 @@ class DailyJob extends Command
     // 关闭超过72小时未处理的工单
     private function closeTickets(): void
     {
-        $ticketList = Ticket::where('updated_at', '<=', date('Y-m-d', strtotime('-3 days')))->whereStatus(1)->get();
-        foreach ($ticketList as $ticket) {
-            $ret = Ticket::whereId($ticket->id)->update(['status' => 2]);
-            if ($ret) {
+        foreach (Ticket::where('updated_at', '<=', date('Y-m-d', strtotime('-3 days')))->whereStatus(1)->get() as $ticket) {
+            if ($ticket->close()) {
                 PushNotification::send('工单关闭提醒', '工单:ID'.$ticket->id.'超过72小时未处理,系统已自动关闭');
             }
         }

+ 4 - 4
app/Console/Commands/ServiceTimer.php

@@ -37,11 +37,11 @@ class ServiceTimer extends Command
                 continue;
             }
             $user->update([
-                'u'               => 0,
-                'd'               => 0,
+                'u' => 0,
+                'd' => 0,
                 'transfer_enable' => 0,
-                'reset_time'      => null,
-                'level'           => 0,
+                'reset_time' => null,
+                'level' => 0,
             ]);
             Helpers::addUserTrafficModifyLog($user->id, $order->id, $user->transfer_enable, 0, '[定时任务]用户所购商品到期,扣减商品对应的流量');
 

+ 1 - 1
app/Console/Commands/UserTrafficAbnormalAutoWarning.php

@@ -29,7 +29,7 @@ class UserTrafficAbnormalAutoWarning extends Command
     private function userTrafficAbnormalWarning(): void
     {
         // 1小时内流量异常用户(多往前取5分钟,防止数据统计任务执行时间过长导致没有数据)
-        $userTotalTrafficLogs = UserHourlyDataFlow::whereNodeId(0)
+        $userTotalTrafficLogs = UserHourlyDataFlow::whereNodeId(null)
             ->where('total', '>', MB * 50)
             ->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))
             ->groupBy('user_id')

+ 1 - 1
app/Console/Commands/UserTrafficAutoWarning.php

@@ -39,7 +39,7 @@ class UserTrafficAutoWarning extends Command
                 continue;
             }
 
-            $usedPercent = round(($user->d + $user->u) / $user->transfer_enable, 2) * 100; // 已使用流量百分比
+            $usedPercent = $user->used_traffic_percentage * 100; // 已使用流量百分比
             if ($usedPercent >= $trafficWarningPercent) {
                 $logId = Helpers::addNotificationLog('流量提醒', '流量已使用:'.$usedPercent.'%,请保持关注。', 1, $user->email);
                 Mail::to($user->email)->send(new userTrafficWarning($logId, $usedPercent));

+ 0 - 1
app/Console/Kernel.php

@@ -47,7 +47,6 @@ class Kernel extends ConsoleKernel
      * Define the application's command schedule.
      *
      * @param  Schedule  $schedule
-     *
      * @return void
      */
     protected function schedule(Schedule $schedule)

+ 5 - 8
app/Exceptions/Handler.php

@@ -4,7 +4,6 @@ namespace App\Exceptions;
 
 use App\Components\IP;
 use ErrorException;
-use Exception;
 use Illuminate\Auth\AuthenticationException;
 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
 use Illuminate\Http\Client\ConnectionException;
@@ -39,10 +38,9 @@ class Handler extends ExceptionHandler
      * Report or log an exception.
      *
      * @param  Throwable  $exception
-     *
      * @return void
      *
-     * @throws Exception|Throwable
+     * @throws Throwable
      */
     public function report(Throwable $exception)
     {
@@ -63,7 +61,6 @@ class Handler extends ExceptionHandler
      *
      * @param  Request  $request
      * @param  Throwable  $exception
-     *
      * @return \Symfony\Component\HttpFoundation\Response
      *
      * @throws Throwable
@@ -90,7 +87,7 @@ class Handler extends ExceptionHandler
                 case $exception instanceof TokenMismatchException: // 捕获CSRF异常
                     if ($request->ajax()) {
                         return Response::json([
-                            'status'  => 'fail',
+                            'status' => 'fail',
                             'message' => trans('error.RefreshPage').'<a href="'.route('login').'" target="_blank">'.trans('error.Refresh').'</a>',
                         ]);
                     }
@@ -109,7 +106,7 @@ class Handler extends ExceptionHandler
                 case $exception instanceof ErrorException: // 捕获系统错误异常
                     if ($request->ajax()) {
                         return Response::json([
-                            'status'  => 'fail',
+                            'status' => 'fail',
                             'message' => trans('error.SystemError').', '.trans('error.Visit').'<a href="'.route('admin.log.viewer').'" target="_blank">'.trans('error.log').'</a>',
                         ]);
                     }
@@ -122,7 +119,7 @@ class Handler extends ExceptionHandler
                 case $exception instanceof ConnectionException:
                     if ($request->ajax()) {
                         return Response::json([
-                            'status'  => 'fail',
+                            'status' => 'fail',
                             'message' => $exception->getMessage(),
                         ]);
                     }
@@ -131,7 +128,7 @@ class Handler extends ExceptionHandler
                 default:
                     if ($request->ajax()) {
                         return Response::json([
-                            'status'  => 'fail',
+                            'status' => 'fail',
                             'message' => $exception->getMessage(),
                         ]);
                     }

+ 28 - 19
app/Http/Controllers/Admin/ArticleController.php

@@ -9,10 +9,10 @@ use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
+use Illuminate\Http\UploadedFile;
 use Log;
 use Redirect;
 use Response;
-use Session;
 
 class ArticleController extends Controller
 {
@@ -36,22 +36,33 @@ class ArticleController extends Controller
         $data = $request->except('_method', '_token');
         // LOGO
         if ($request->input('type') !== '4' && $request->hasFile('logo')) {
-            $data['logo'] = 'upload/'.$request->file('logo')->store('images');
-            if (! $data['logo']) {
-                Session::flash('errorMsg', 'LOGO不合法');
-
-                return Redirect::back()->withInput();
+            $path = $this->fileUpload($request->file('logo'));
+            if (is_string($path)) {
+                $data['logo'] = $path;
+            } else {
+                return $path;
             }
         }
 
         $article = Article::create($data);
         if ($article->id) {
-            Session::flash('successMsg', '添加成功');
-        } else {
-            Session::flash('errorMsg', '添加失败');
+            return Redirect::route('admin.article.edit', $article->id)->with('successMsg', '添加成功');
+        }
+
+        return Redirect::back()->withInput()->withErrors('添加失败');
+    }
+
+    // 图片上传
+    public function fileUpload(UploadedFile $file)
+    {
+        $fileName = Str::random(8).time().'.'.$file->getClientOriginalExtension();
+        $path = $file->storeAs('public', $fileName);
+
+        if (! $path) {
+            return Redirect::back()->withInput()->withErrors('Logo存储失败');
         }
 
-        return Redirect::to(route('admin.article.edit', $article->id));
+        return 'upload/'.$fileName;
     }
 
     // 文章页面
@@ -77,21 +88,19 @@ class ArticleController extends Controller
         $data['logo'] = $data['logo'] ?? null;
         // LOGO
         if ($request->input('type') != 4 && $request->hasFile('logo')) {
-            $data['logo'] = 'upload/'.$request->file('logo')->store('images');
-            if (! $data['logo']) {
-                Session::flash('errorMsg', 'LOGO不合法');
-
-                return Redirect::back()->withInput();
+            $path = $this->fileUpload($request->file('logo'));
+            if (is_string($path)) {
+                $data['logo'] = $path;
+            } else {
+                return $path;
             }
         }
 
         if (Article::find($id)->update($data)) {
-            Session::flash('successMsg', '编辑成功');
-        } else {
-            Session::flash('errorMsg', '编辑失败');
+            return Redirect::back()->with('successMsg', '编辑成功');
         }
 
-        return Redirect::to(route('admin.article.edit', $id));
+        return Redirect::back()->withErrors('编辑失败');
     }
 
     // 删除文章

+ 1 - 1
app/Http/Controllers/Admin/Config/EmailFilterController.php

@@ -29,7 +29,7 @@ class EmailFilterController extends Controller
         ]);
 
         if ($validator->fails()) {
-            return Response::json(['status' => 'fail', 'message' => $validator->errors()->first()]);
+            return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
         }
 
         try {

+ 0 - 1
app/Http/Controllers/Admin/Config/LabelController.php

@@ -42,7 +42,6 @@ class LabelController extends Controller
     {
         try {
             Label::whereId($id)->delete();
-            NodeLabel::whereLabelId($id)->delete(); // 删除节点关联
 
             return Response::json(['status' => 'success', 'message' => '删除成功']);
         } catch (Exception $e) {

+ 4 - 4
app/Http/Controllers/Admin/Config/LevelController.php

@@ -18,12 +18,12 @@ class LevelController extends Controller
     public function store(Request $request): JsonResponse
     {
         $validator = Validator::make($request->all(), [
-            'level'      => 'required|numeric|unique:level,level',
+            'level' => 'required|numeric|unique:level,level',
             'level_name' => 'required',
         ]);
 
         if ($validator->fails()) {
-            return Response::json(['status' => 'fail', 'message' => $validator->errors()->first()]);
+            return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
         }
 
         $obj = new Level();
@@ -44,12 +44,12 @@ class LevelController extends Controller
         $level = $request->input('level');
 
         $validator = Validator::make($request->all(), [
-            'level'      => 'required|numeric',
+            'level' => 'required|numeric',
             'level_name' => 'required',
         ]);
 
         if ($validator->fails()) {
-            return Response::json(['status' => 'fail', 'message' => $validator->errors()->first()]);
+            return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
         }
         // 校验该等级下是否存在关联账号
         $levelCheck = Level::where('id', '<>', $id)->whereLevel($level)->exists();

+ 5 - 3
app/Http/Controllers/Admin/CouponController.php

@@ -60,11 +60,14 @@ class CouponController extends Controller
         // 优惠卷LOGO
         $logo = null;
         if ($request->hasFile('logo')) {
-            $logo = 'upload/'.$request->file('logo')->store('images');
+            $file = $request->file('logo');
+            $fileName = Str::random(8).time().'.'.$file->getClientOriginalExtension();
+            $path = $file->storeAs('public', $fileName);
 
-            if (! $logo) {
+            if (! $path) {
                 return Redirect::back()->withInput()->withErrors('LOGO不合法');
             }
+            $logo = 'upload/'.$fileName;
         }
         try {
             $num = (int) $request->input('num');
@@ -80,7 +83,6 @@ class CouponController extends Controller
                 $obj->rule = $request->input('rule');
                 $obj->start_time = strtotime($request->input('start_time'));
                 $obj->end_time = strtotime($request->input('end_time'));
-                $obj->status = 0;
                 $obj->save();
             }
 

+ 2 - 2
app/Http/Controllers/Admin/MarketingController.php

@@ -67,8 +67,8 @@ class MarketingController extends Controller
 
             $response = Http::timeout(15)->get('https://pushbear.ftqq.com/sub', [
                 'sendkey' => sysConfig('push_bear_send_key'),
-                'text'    => $title,
-                'desp'    => $content,
+                'text' => $title,
+                'desp' => $content,
             ]);
 
             $message = $response->json();

+ 8 - 8
app/Http/Controllers/Admin/NodeController.php

@@ -62,9 +62,9 @@ class NodeController extends Controller
     {
         return view('admin.node.info', [
             'countryList' => Country::orderBy('code')->get(),
-            'levelList'   => Level::orderBy('level')->get(),
-            'labelList'   => Label::orderByDesc('sort')->orderBy('id')->get(),
-            'dvList'      => NodeCertificate::orderBy('id')->get(),
+            'levelList' => Level::orderBy('level')->get(),
+            'labelList' => Label::orderByDesc('sort')->orderBy('id')->get(),
+            'dvList' => NodeCertificate::orderBy('id')->get(),
         ]);
     }
 
@@ -95,11 +95,11 @@ class NodeController extends Controller
     public function edit($id)
     {
         return view('admin.node.info', [
-            'node'        => Node::with('labels')->find($id),
+            'node' => Node::with('labels')->find($id),
             'countryList' => Country::orderBy('code')->get(),
-            'levelList'   => Level::orderBy('level')->get(),
-            'labelList'   => Label::orderByDesc('sort')->orderBy('id')->get(),
-            'dvList'      => NodeCertificate::orderBy('id')->get(),
+            'levelList' => Level::orderBy('level')->get(),
+            'labelList' => Label::orderByDesc('sort')->orderBy('id')->get(),
+            'dvList' => NodeCertificate::orderBy('id')->get(),
         ]);
     }
 
@@ -209,7 +209,7 @@ class NodeController extends Controller
 
         if ($result) {
             return Response::json([
-                'status'  => 'success',
+                'status' => 'success',
                 'message' => [
                     $result['telecom']['time'] ?: '无', //电信
                     $result['Unicom']['time'] ?: '无', // 联通

+ 71 - 0
app/Http/Controllers/Admin/PermissionController.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+use Illuminate\Http\Response;
+use Spatie\Permission\Models\Permission;
+
+class PermissionController extends Controller
+{
+    public function index()
+    {
+        $permissions = Permission::query()->paginate(15);
+
+        return view('admin.permission.index', compact('permissions'));
+    }
+
+    public function create()
+    {
+        return view('admin.permission.info');
+    }
+
+    public function store(Request $request)
+    {
+        $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
+
+        if ($validator->fails()) {
+            return redirect()->back()->withInput()->withErrors($validator->errors());
+        }
+
+        $permission = Permission::create($request->all());
+
+        if ($permission) {
+            return redirect()->route('admin.permission.edit', $permission)->with('successMsg', '操作成功');
+        }
+
+        return redirect()->back()->withInput()->withErrors('操作失败');
+    }
+
+    public function edit(Permission $permission)
+    {
+        return view('admin.permission.info', compact('permission'));
+    }
+
+    public function update(Request $request, Permission $permission)
+    {
+        $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
+
+        if ($validator->fails()) {
+            return redirect()->back()->withInput()->withErrors($validator->errors());
+        }
+
+        if ($permission->update($request->all())) {
+            return redirect()->back()->with('successMsg', '操作成功');
+        }
+
+        return redirect()->back()->withInput()->withErrors('操作失败');
+    }
+
+    public function destroy(Permission $permission)
+    {
+        try {
+            $permission->delete();
+        } catch (Exception $e) {
+            return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+        }
+
+        return Response::json(['status' => 'success', 'message' => '清理成功']);
+    }
+}

+ 78 - 0
app/Http/Controllers/Admin/RoleController.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+use Spatie\Permission\Models\Permission;
+use Spatie\Permission\Models\Role;
+
+class RoleController extends Controller
+{
+    public function index()
+    {
+        $roles = Role::with('permissions')->paginate(15);
+
+        return view('admin.role.index', compact('roles'));
+    }
+
+    public function create()
+    {
+        $permissions = Permission::all()->pluck('description', 'name');
+
+        return view('admin.role.info', compact('permissions'));
+    }
+
+    public function store(Request $request)
+    {
+        $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
+
+        if ($validator->fails()) {
+            return redirect()->back()->withInput()->withErrors($validator->errors());
+        }
+
+        $role = Role::create($request->except('permissions'));
+        $permissions = $request->input('permissions') ?: [];
+        if ($role->givePermissionTo($permissions)) {
+            return redirect()->route('admin.role.edit', $role)->with('successMsg', '操作成功');
+        }
+
+        return redirect()->back()->withInput()->withErrors('操作失败');
+    }
+
+    public function edit(Role $role)
+    {
+        $role->load('permissions');
+        $permissions = Permission::all()->pluck('description', 'name');
+
+        return view('admin.role.info', compact('role', 'permissions'));
+    }
+
+    public function update(Request $request, Role $role)
+    {
+        $validator = validator()->make($request->all(), ['name' => 'required', 'description' => 'required']);
+
+        if ($validator->fails()) {
+            return redirect()->back()->withInput()->withErrors($validator->errors());
+        }
+
+        $role->update($request->except('permissions'));
+        $permissions = $request->input('permissions') ?: [];
+        if ($role->syncPermissions($permissions)) {
+            return redirect()->back()->with('successMsg', '操作成功');
+        }
+
+        return redirect()->back()->withInput()->withErrors('操作失败');
+    }
+
+    public function destroy(Role $role)
+    {
+        try {
+            $role->delete();
+        } catch (Exception $e) {
+            return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
+        }
+
+        return Response::json(['status' => 'success', 'message' => '清理成功']);
+    }
+}

+ 2 - 2
app/Http/Controllers/Admin/RuleController.php

@@ -34,8 +34,8 @@ class RuleController extends Controller
     public function store(Request $request): JsonResponse
     {
         $validator = Validator::make($request->all(), [
-            'type'    => 'required|between:1,4',
-            'name'    => 'required',
+            'type' => 'required|between:1,4',
+            'name' => 'required',
             'pattern' => 'required',
         ]);
 

+ 4 - 5
app/Http/Controllers/Admin/RuleGroupController.php

@@ -37,8 +37,8 @@ class RuleGroupController extends Controller
     public function store(Request $request): RedirectResponse
     {
         $validator = Validator::make($request->all(), [
-            'name'  => 'required',
-            'type'  => 'required|boolean',
+            'name' => 'required',
+            'type' => 'required|boolean',
             'rules' => 'required',
         ]);
 
@@ -80,8 +80,8 @@ class RuleGroupController extends Controller
         }
 
         $ret = RuleGroup::find($id)->update([
-            'name'  => $request->input('name'),
-            'type'  => $request->input('type'),
+            'name' => $request->input('name'),
+            'type' => $request->input('type'),
             'rules' => $request->input('rules'),
         ]);
 
@@ -97,7 +97,6 @@ class RuleGroupController extends Controller
     {
         try {
             RuleGroup::whereId($id)->delete();
-            RuleGroupNode::whereRuleGroupId($id)->delete();
         } catch (Exception $e) {
             return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
         }

+ 33 - 19
app/Http/Controllers/Admin/ShopController.php

@@ -11,10 +11,11 @@ use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
+use Illuminate\Http\UploadedFile;
 use Log;
 use Redirect;
 use Response;
-use Session;
+use Str;
 
 /**
  * 商店控制器.
@@ -55,22 +56,21 @@ class ShopController extends Controller
     // 添加商品
     public function store(ShopStoreRequest $request): RedirectResponse
     {
-        // 商品LOGO
-        if ($request->hasFile('logo')) {
-            $logo = 'upload/'.$request->file('logo')->store('images');
-
-            if (! $logo) {
-                return Redirect::back()->withInput()->withErrors('LOGO不合法');
-            }
-        }
-
         try {
             $data = $request->except('_token', 'logo', 'traffic', 'traffic_unit');
             $data['traffic'] = $request->input('traffic') * $request->input('traffic_unit') ?? 1;
-            $data['logo'] = $logo ?? null;
             $data['is_hot'] = $request->input('is_hot') ? 1 : 0;
             $data['status'] = $request->input('status') ? 1 : 0;
 
+            // 商品LOGO
+            if ($request->hasFile('logo')) {
+                $path = $this->fileUpload($request->file('logo'));
+                if (is_string($path)) {
+                    $data['logo'] = $path;
+                } else {
+                    return $path;
+                }
+            }
             $good = Goods::create($data);
 
             if ($good) {
@@ -85,6 +85,19 @@ class ShopController extends Controller
         return Redirect::back()->withInput()->withErrors('添加商品信息失败');
     }
 
+    // 图片上传
+    public function fileUpload(UploadedFile $file)
+    {
+        $fileName = Str::random(8).time().'.'.$file->getClientOriginalExtension();
+        $path = $file->storeAs('public', $fileName);
+
+        if (! $path) {
+            return Redirect::back()->withInput()->withErrors('Logo存储失败');
+        }
+
+        return 'upload/'.$fileName;
+    }
+
     // 编辑商品页面
     public function edit($id)
     {
@@ -101,12 +114,12 @@ class ShopController extends Controller
         $data = $request->except('_token', '_method', 'logo');
         // 商品LOGO
         if ($request->hasFile('logo')) {
-            $logo = 'upload/'.$request->file('logo')->store('images');
-
-            if (! $logo) {
-                return Redirect::back()->withInput()->withErrors('LOGO不合法');
+            $path = $this->fileUpload($request->file('logo'));
+            if (is_string($path)) {
+                $data['logo'] = $path;
+            } else {
+                return $path;
             }
-            $data['logo'] = $logo;
         }
 
         try {
@@ -114,14 +127,15 @@ class ShopController extends Controller
             $data['status'] = $request->input('status') ? 1 : 0;
 
             if ($goods->update($data)) {
-                Session::flash('successMsg', '编辑成功');
+                return Redirect::back()->with('successMsg', '编辑成功');
             }
         } catch (Exception $e) {
             Log::error('编辑商品信息失败:'.$e->getMessage());
-            Session::flash('errorMsg', '编辑商品信息失败:'.$e->getMessage());
+
+            return Redirect::back()->withErrors('编辑商品信息失败:'.$e->getMessage());
         }
 
-        return Redirect::back();
+        return Redirect::back()->withInput()->withErrors('编辑失败');
     }
 
     // 删除商品

+ 30 - 49
app/Http/Controllers/Admin/SystemController.php

@@ -6,72 +6,53 @@ use App\Components\PushNotification;
 use App\Http\Controllers\Controller;
 use App\Models\Config;
 use App\Models\Label;
-use DB;
-use Exception;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
-use Redirect;
 use Response;
-use Session;
 
 class SystemController extends Controller
 {
-    // 设置系统扩展信息,例如客服、统计代码
-    public function setExtend(Request $request): ?RedirectResponse
+    // 系统设置
+    public function index()
     {
-        $websiteAnalytics = $request->input('website_analytics');
-        $websiteCustomerService = $request->input('website_customer_service');
+        $view = Config::pluck('value', 'name')->toArray();
+        $view['labelList'] = Label::orderByDesc('sort')->orderBy('id')->get();
 
-        try {
-            DB::beginTransaction();
+        return view('admin.config.system', $view);
+    }
 
-            // 首页LOGO
-            if ($request->hasFile('website_home_logo')) {
-                $ret = 'upload/'.$request->file('website_home_logo')->store('images');
-                if (! $ret) {
-                    Session::flash('errorMsg', 'LOGO不合法');
+    // 设置系统扩展信息,例如客服、统计代码
+    public function setExtend(Request $request): RedirectResponse
+    {
+        if ($request->hasFile('website_home_logo')) {
+            $validator = validator()->make($request->all(), ['website_home_logo' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048']);
 
-                    return Redirect::back();
-                }
-                Config::find('website_home_logo')->update(['value' => $ret]);
+            if ($validator->fails()) {
+                return redirect()->route('admin.system.index', '#other')->withErrors($validator->errors());
             }
-
-            // 站内LOGO
-            if ($request->hasFile('website_logo')) {
-                $ret = 'upload/'.$request->file('website_logo')->store('images');
-                if (! $ret) {
-                    Session::flash('errorMsg', 'LOGO不合法');
-
-                    return Redirect::back();
-                }
-                Config::find('website_logo')->update(['value' => $ret]);
+            $file = $request->file('website_home_logo');
+            $ret = $file->move('uploads/logo', $file->getClientOriginalName());
+            if ($ret && Config::find('website_home_logo')->update(['value' => 'uploads/logo/'.$file->getClientOriginalName()])) {
+                return redirect()->route('admin.system.index', '#other')->with('successMsg', '更新成功');
             }
+        }
 
-            Config::find('website_analytics')->update(['value' => $websiteAnalytics]);
-            Config::find('website_customer_service')->update(['value' => $websiteCustomerService]);
-
-            Session::flash('successMsg', '更新成功');
-
-            DB::commit();
-
-            return Redirect::back();
-        } catch (Exception $e) {
-            DB::rollBack();
-
-            Session::flash('errorMsg', '更新失败');
+        // 站内LOGO
+        if ($request->hasFile('website_logo')) {
+            $validator = validator()->make($request->all(), ['website_logo' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048']);
 
-            return Redirect::back();
+            if ($validator->fails()) {
+                return redirect()->route('admin.system.index', '#other')->withErrors($validator->errors());
+            }
+            $file = $request->file('website_logo');
+            $ret = $file->move('uploads/logo', $file->getClientOriginalName());
+            if ($ret && Config::find('website_logo')->update(['value' => 'uploads/logo/'.$file->getClientOriginalName()])) {
+                return redirect()->route('admin.system.index', '#other')->with('successMsg', '更新成功');
+            }
         }
-    }
 
-    // 系统设置
-    public function index()
-    {
-        $view = Config::pluck('value', 'name')->toArray();
-        $view['labelList'] = Label::orderByDesc('sort')->orderBy('id')->get();
-
-        return view('admin.config.system', $view);
+        return redirect()->route('admin.system.index', '#other')->withErrors('更新失败');
     }
 
     // 设置某个配置项

+ 7 - 23
app/Http/Controllers/Admin/TicketController.php

@@ -27,7 +27,7 @@ class TicketController extends Controller
     {
         $email = $request->input('email');
 
-        $query = Ticket::whereIn('admin_id', [0, Auth::id()]);
+        $query = Ticket::whereAdminId(Auth::id())->orwhere('admin_id', null);
 
         if (isset($email)) {
             $query->whereHas('user', static function ($q) use ($email) {
@@ -67,10 +67,8 @@ class TicketController extends Controller
         $obj->admin_id = Auth::id();
         $obj->title = $title;
         $obj->content = $content;
-        $obj->status = 0;
-        $obj->save();
 
-        if ($obj->id) {
+        if ($obj->save()) {
             return Response::json(['status' => 'success', 'message' => '工单创建成功']);
         }
 
@@ -95,9 +93,8 @@ class TicketController extends Controller
         $obj->ticket_id = $id;
         $obj->admin_id = Auth::id();
         $obj->content = $content;
-        $obj->save();
 
-        if ($obj->id) {
+        if ($obj->save()) {
             // 将工单置为已回复
             $ticket = Ticket::with('user')->find($id);
             Ticket::whereId($id)->update(['status' => 1]);
@@ -106,17 +103,8 @@ class TicketController extends Controller
             $content = '标题:'.$ticket->title.'<br>管理员回复:'.$content;
 
             // 发通知邮件
-            if (! Auth::getUser()->is_admin) {
-                if (sysConfig('webmaster_email')) {
-                    $logId = Helpers::addNotificationLog($title, $content, 1, sysConfig('webmaster_email'));
-                    Mail::to(sysConfig('webmaster_email'))->send(new replyTicket($logId, $title, $content));
-                }
-                // 推送通知管理员
-                PushNotification::send($title, $content);
-            } else {
-                $logId = Helpers::addNotificationLog($title, $content, 1, $ticket->user->email);
-                Mail::to($ticket->user->email)->send(new replyTicket($logId, $title, $content));
-            }
+            $logId = Helpers::addNotificationLog($title, $content, 1, $ticket->user->email);
+            Mail::to($ticket->user->email)->send(new replyTicket($logId, $title, $content));
 
             return Response::json(['status' => 'success', 'message' => '回复成功']);
         }
@@ -127,13 +115,9 @@ class TicketController extends Controller
     // 关闭工单
     public function destroy($id)
     {
-        $ticket = Ticket::with('user')->whereId($id)->first();
-        if (! $ticket) {
-            return Response::json(['status' => 'fail', 'message' => '关闭失败']);
-        }
+        $ticket = Ticket::with('user')->find($id);
 
-        $ret = Ticket::whereId($id)->update(['status' => 2]);
-        if (! $ret) {
+        if (! $ticket->close()) {
             return Response::json(['status' => 'fail', 'message' => '关闭失败']);
         }
 

+ 17 - 29
app/Http/Controllers/Admin/ToolsController.php

@@ -75,18 +75,18 @@ class ToolsController extends Controller
             $data = [];
             foreach ($content->port_password as $port => $passwd) {
                 $data[] = [
-                    'u'               => 0,
-                    'd'               => 0,
-                    'enable'          => 1,
-                    'method'          => $method,
-                    'obfs'            => $obfs,
-                    'obfs_param'      => empty($obfs_param) ? '' : $obfs_param,
-                    'passwd'          => $passwd,
-                    'port'            => $port,
-                    'protocol'        => $protocol,
-                    'protocol_param'  => empty($protocol_param) ? '' : $protocol_param,
+                    'u' => 0,
+                    'd' => 0,
+                    'enable' => 1,
+                    'method' => $method,
+                    'obfs' => $obfs,
+                    'obfs_param' => empty($obfs_param) ? '' : $obfs_param,
+                    'passwd' => $passwd,
+                    'port' => $port,
+                    'protocol' => $protocol,
+                    'protocol_param' => empty($protocol_param) ? '' : $protocol_param,
                     'transfer_enable' => $transfer_enable,
-                    'user'            => date('Ymd').'_IMPORT_'.$port,
+                    'user' => date('Ymd').'_IMPORT_'.$port,
                 ];
             }
 
@@ -127,24 +127,18 @@ class ToolsController extends Controller
     {
         if ($request->isMethod('POST')) {
             if (! $request->hasFile('uploadFile')) {
-                Session::flash('errorMsg', '请选择要上传的文件');
-
-                return Redirect::back();
+                return Redirect::back()->withErrors('请选择要上传的文件');
             }
 
             $file = $request->file('uploadFile');
 
             // 只能上传JSON文件
             if ($file->getClientMimeType() !== 'application/json' || $file->getClientOriginalExtension() !== 'json') {
-                Session::flash('errorMsg', '只允许上传JSON文件');
-
-                return Redirect::back();
+                return Redirect::back()->withErrors('只允许上传JSON文件');
             }
 
             if (! $file->isValid()) {
-                Session::flash('errorMsg', '产生未知错误,请重新上传');
-
-                return Redirect::back();
+                return Redirect::back()->withErrors('产生未知错误,请重新上传');
             }
 
             $save_path = realpath(storage_path('uploads'));
@@ -155,9 +149,7 @@ class ToolsController extends Controller
             $data = file_get_contents($save_path.'/'.$new_name);
             $data = json_decode($data, true);
             if (! $data) {
-                Session::flash('errorMsg', '内容格式解析异常,请上传符合SSR(R)配置规范的JSON文件');
-
-                return Redirect::back();
+                return Redirect::back()->withErrors('内容格式解析异常,请上传符合SSR(R)配置规范的JSON文件');
             }
 
             try {
@@ -185,14 +177,10 @@ class ToolsController extends Controller
             } catch (Exception $e) {
                 DB::rollBack();
 
-                Session::flash('errorMsg', '出错了,可能是导入的配置中有端口已经存在了');
-
-                return Redirect::back();
+                return Redirect::back()->withErrors('出错了,可能是导入的配置中有端口已经存在了');
             }
 
-            Session::flash('successMsg', '导入成功');
-
-            return Redirect::back();
+            return Redirect::back()->with('successMsg', '导入成功');
         }
 
         return view('admin.tools.import');

+ 62 - 70
app/Http/Controllers/Admin/UserController.php

@@ -12,7 +12,6 @@ use App\Models\Node;
 use App\Models\User;
 use App\Models\UserGroup;
 use App\Models\UserHourlyDataFlow;
-use App\Services\UserService;
 use Auth;
 use DB;
 use Exception;
@@ -22,6 +21,7 @@ use Log;
 use Redirect;
 use Response;
 use Session;
+use Spatie\Permission\Models\Role;
 use Str;
 
 class UserController extends Controller
@@ -82,7 +82,7 @@ class UserController extends Controller
 
         // 流量超过100G的
         if ($largeTraffic) {
-            $query->whereIn('status', [0, 1])->whereRaw('(u + d) >= 107374182400');
+            $query->whereIn('status', [0, 1])->whereRaw('(u + d)/transfer_enable >= 0.9');
         }
 
         // 临近过期提醒
@@ -105,40 +105,28 @@ class UserController extends Controller
             $query->whereIn('id', (new UserHourlyDataFlow)->trafficAbnormal());
         }
 
-        $userList = $query->orderByDesc('id')->paginate(15)->appends($request->except('page'));
-        foreach ($userList as $user) {
-            $user->used_flow = flowAutoShow($user->u + $user->d);
-            if ($user->expired_at < date('Y-m-d')) {
-                $user->expireWarning = -1; // 已过期
-            } elseif ($user->expired_at === date('Y-m-d')) {
-                $user->expireWarning = 0; // 今天过期
-            } elseif ($user->expired_at > date('Y-m-d') && $user->expired_at <= date('Y-m-d', strtotime('+30 days'))) {
-                $user->expireWarning = 1; // 最近一个月过期
-            } else {
-                $user->expireWarning = 2; // 大于一个月过期
-            }
-
-            // 流量异常警告
-            $totalTraffic = UserHourlyDataFlow::userRecentUsed($user->id)->sum('total');
-            $user->trafficWarning = $totalTraffic > (sysConfig('traffic_ban_value') * GB) ? 1 : 0;
-
-            // 订阅地址
-            $user->link = route('sub', $user->subscribe->code);
-        }
-
         return view('admin.user.index', [
-            'userList'   => $userList,
+            'userList' => $query->orderByDesc('id')->paginate(15)->appends($request->except('page')),
             'userGroups' => UserGroup::all()->pluck('name', 'id')->toArray(),
-            'levels'     => Level::all()->pluck('name', 'level')->toArray(),
+            'levels' => Level::all()->pluck('name', 'level')->toArray(),
         ]);
     }
 
     // 添加账号页面
     public function create()
     {
+        if (Auth::getUser()->hasRole('Super Admin')) {
+            $roles = Role::all()->pluck('description', 'name');
+        } elseif (Auth::getUser()->hasPermissionTo('give roles')) {
+            $roles = Auth::getUser()->roles();
+        } else {
+            $roles = [];
+        }
+
         return view('admin.user.info', [
-            'levelList' => Level::orderBy('level')->get(),
-            'groupList' => UserGroup::orderBy('id')->get(),
+            'levels' => Level::orderBy('level')->get(),
+            'userGroups' => UserGroup::orderBy('id')->get(),
+            'roles' => $roles,
         ]);
     }
 
@@ -146,7 +134,7 @@ class UserController extends Controller
     public function store(UserStoreRequest $request): JsonResponse
     {
         try {
-            $data = $request->except('_token', 'uuid');
+            $data = $request->except('_token', 'uuid', 'roles');
             $data['password'] = $data['password'] ?? Str::random();
             $data['port'] = $data['port'] ?? Helpers::getPort();
             $data['passwd'] = $data['passwd'] ?? Str::random();
@@ -157,9 +145,15 @@ class UserController extends Controller
             $data['reset_time'] = $data['reset_time'] > date('Y-m-d') ? $data['reset_time'] : null;
             $user = User::create($data);
 
+            $roles = $request->input('roles');
+            if ($roles && (Auth::getUser()->hasPermissionTo('give roles') || Auth::getUser()->hasRole('Super Admin'))
+                || (in_array('Super Admin', $roles, true) && Auth::getUser()->hasRole('Super Admin'))) {
+                $user->assignRole($roles);
+            }
+
             if ($user) {
                 // 写入用户流量变动记录
-                Helpers::addUserTrafficModifyLog($user->id, 0, 0, $data['transfer_enable'], '后台手动添加用户');
+                Helpers::addUserTrafficModifyLog($user->id, null, 0, $data['transfer_enable'], '后台手动添加用户');
 
                 return Response::json(['status' => 'success', 'message' => '添加成功']);
             }
@@ -173,24 +167,29 @@ class UserController extends Controller
     }
 
     // 编辑账号页面
-    public function edit($id)
+    public function edit(User $user)
     {
-        $user = User::find($id);
+        if (Auth::getUser()->hasRole('Super Admin')) {
+            $roles = Role::all()->pluck('description', 'name');
+        } elseif (Auth::getUser()->hasPermissionTo('give roles')) {
+            $roles = Auth::getUser()->roles();
+        } else {
+            $roles = [];
+        }
 
         return view('admin.user.info', [
-            'user'      => $user->load('inviter:id,email'),
-            'levelList' => Level::orderBy('level')->get(),
-            'groupList' => UserGroup::orderBy('id')->get(),
+            'user' => $user->load('inviter:id,email'),
+            'levels' => Level::orderBy('level')->get(),
+            'userGroups' => UserGroup::orderBy('id')->get(),
+            'roles' => $roles,
         ]);
     }
 
     // 编辑账号
-    public function update(UserUpdateRequest $request, $id)
+    public function update(UserUpdateRequest $request, User $user)
     {
-        $user = User::find($id);
-
         try {
-            $data = $request->except('_token', 'password', 'uuid', 'password', 'is_admin');
+            $data = $request->except('_token', 'password', 'uuid', 'password', 'roles');
             $data['passwd'] = $request->input('passwd') ?? Str::random();
             $data['vmess_id'] = $request->input('uuid') ?? Str::uuid();
             $data['transfer_enable'] *= GB;
@@ -198,6 +197,14 @@ class UserController extends Controller
             $data['expired_at'] = $data['expired_at'] ?? date('Y-m-d', strtotime('+365 days'));
             $data['remark'] = str_replace(['atob', 'eval'], '', $data['remark']);
 
+            // 只有超级管理员才能赋予超级管理员
+            $roles = $request->input('roles');
+
+            if ($roles && (Auth::getUser()->hasPermissionTo('give roles') || Auth::getUser()->hasRole('Super Admin'))
+                || (in_array('Super Admin', $roles, true) && Auth::getUser()->hasRole('Super Admin'))) {
+                $user->syncRoles($roles);
+            }
+
             // Input checking for dummy
             if ($data['enable'] === '1') {
                 if ($data['status'] === '-1' || $data['transfer_enable'] === 0 || $data['expired_at'] < date('Y-m-d')) {
@@ -205,20 +212,15 @@ class UserController extends Controller
                 }
             }
 
-            // 只有admin才有权限操作管理员属性
-            if (Auth::getUser()->is_admin === 1) {
-                $data['is_admin'] = (int) $request->input('is_admin');
-            }
-
             // 非演示环境才可以修改管理员密码
             $password = $request->input('password');
-            if (! empty($password) && ! (env('APP_DEMO') && $id === 1)) {
+            if (! empty($password) && ! (env('APP_DEMO') && $user->id === 1)) {
                 $data['password'] = $password;
             }
 
             // 写入用户流量变动记录
             if ($user->transfer_enable !== $data['transfer_enable']) {
-                Helpers::addUserTrafficModifyLog($id, 0, $user->transfer_enable, $data['transfer_enable'], '后台手动编辑用户');
+                Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, $data['transfer_enable'], '后台手动编辑用户');
             }
 
             if ($user->update($data)) {
@@ -234,26 +236,23 @@ class UserController extends Controller
     }
 
     // 删除用户
-    public function destroy($id)
+    public function destroy(User $user)
     {
-        if ($id <= 1) {
+        if ($user->id === 1) {
             return Response::json(['status' => 'fail', 'message' => '系统管理员不可删除']);
         }
 
         try {
-            DB::beginTransaction();
-
-            User::find($id)->delete();
-
-            DB::commit();
-
-            return Response::json(['status' => 'success', 'message' => '删除成功']);
+            if ($user->delete()) {
+                return Response::json(['status' => 'success', 'message' => '删除成功']);
+            }
         } catch (Exception $e) {
             Log::error('删除用户信息异常:'.$e->getMessage());
-            DB::rollBack();
 
-            return Response::json(['status' => 'fail', 'message' => '删除失败']);
+            return Response::json(['status' => 'fail', 'message' => '删除失败'.$e->getMessage()]);
         }
+
+        return Response::json(['status' => 'fail', 'message' => '删除失败']);
     }
 
     // 批量生成账号
@@ -267,7 +266,7 @@ class UserController extends Controller
 
                 if ($uid) {
                     // 写入用户流量变动记录
-                    Helpers::addUserTrafficModifyLog($uid, 0, 0, 1024 * GB, '后台批量生成用户');
+                    Helpers::addUserTrafficModifyLog($uid, null, 0, 1024 * GB, '后台批量生成用户');
                 }
             }
 
@@ -284,16 +283,14 @@ class UserController extends Controller
     // 转换成某个用户的身份
     public function switchToUser(Request $request): JsonResponse
     {
-        $id = $request->input('user_id');
-
-        $user = User::find($id);
+        $user = User::find($request->input('user_id'));
         if (! $user) {
             return Response::json(['status' => 'fail', 'message' => '用户不存在']);
         }
 
         // 存储当前管理员ID,并将当前登录信息改成要切换的用户的身份信息
         Session::put('admin', Auth::id());
-        Auth::login($user);
+        Session::put('user', $user->id);
 
         return Response::json(['status' => 'success', 'message' => '身份切换成功']);
     }
@@ -324,8 +321,8 @@ class UserController extends Controller
         $user = User::find($userId);
 
         // 加减余额
-        if ((new UserService($user))->updateCredit($amount)) {
-            Helpers::addUserCreditLog($userId, 0, $user->credit, $user->credit + $amount, $amount, '后台手动充值');  // 写入余额变动日志
+        if ($user->updateCredit($amount)) {
+            Helpers::addUserCreditLog($userId, null, $user->credit, $user->credit + $amount, $amount, '后台手动充值');  // 写入余额变动日志
 
             return Response::json(['status' => 'success', 'message' => '充值成功']);
         }
@@ -334,14 +331,9 @@ class UserController extends Controller
     }
 
     // 导出配置信息
-    public function export(Request $request, $id)
+    public function export(Request $request, User $user)
     {
-        if (empty($id)) {
-            return Redirect::back();
-        }
-
-        $user = User::find($id);
-        if (empty($user)) {
+        if ($user === null) {
             return Redirect::back();
         }
 

+ 20 - 16
app/Http/Controllers/Admin/UserGroupController.php

@@ -26,15 +26,15 @@ class UserGroupController extends Controller
     // 添加用户分组页面
     public function create()
     {
-        $view['nodeList'] = Node::whereStatus(1)->get();
+        $nodes = Node::whereStatus(1)->pluck('name', 'id');
 
-        return view('admin.user.group.info', $view);
+        return view('admin.user.group.info', compact('nodes'));
     }
 
     // 添加用户分组
     public function store(Request $request): RedirectResponse
     {
-        $validator = Validator::make($request->all(), ['name' => 'required', 'nodes' => 'required']);
+        $validator = Validator::make($request->all(), ['name' => 'required']);
 
         if ($validator->fails()) {
             return Redirect::back()->withInput()->withErrors($validator->errors());
@@ -43,28 +43,32 @@ class UserGroupController extends Controller
         $userGroup = UserGroup::create(['name' => $request->input('name'), 'nodes' => $request->input('nodes')]);
 
         if ($userGroup) {
-            return Redirect::route('admin.user.group.edit', $userGroup->id)->with('successMsg', '操作成功');
+            return Redirect::route('admin.user.group.edit', $userGroup)->with('successMsg', '操作成功');
         }
 
         return Redirect::back()->withInput()->withErrors('操作失败');
     }
 
     // 编辑用户分组页面
-    public function edit($id)
+    public function edit(UserGroup $group)
     {
-        $view['userGroup'] = UserGroup::findOrFail($id);
-        $view['nodeList'] = Node::whereStatus(1)->get();
+        $nodes = Node::whereStatus(1)->pluck('name', 'id');
 
-        return view('admin.user.group.info', $view);
+        return view('admin.user.group.info', compact('group', 'nodes'));
     }
 
     // 编辑用户分组
-    public function update(Request $request, $id)
+    public function update(Request $request, UserGroup $group)
     {
-        $userGroup = UserGroup::findOrFail($id);
-        $userGroup->name = $request->input('name');
-        $userGroup->nodes = $request->input('nodes');
-        if ($userGroup->save()) {
+        $validator = Validator::make($request->all(), ['name' => 'required']);
+
+        if ($validator->fails()) {
+            return Redirect::back()->withInput()->withErrors($validator->errors());
+        }
+
+        $group->name = $request->input('name');
+        $group->nodes = $request->input('nodes');
+        if ($group->save()) {
             return Redirect::back()->with('successMsg', '操作成功');
         }
 
@@ -72,15 +76,15 @@ class UserGroupController extends Controller
     }
 
     // 删除用户分组
-    public function destroy($id): JsonResponse
+    public function destroy(UserGroup $group): JsonResponse
     {
         // 校验该分组下是否存在关联账号
-        if (User::whereGroupId($id)->count()) {
+        if (User::whereGroupId($group->id)->count()) {
             return Response::json(['status' => 'fail', 'message' => '该分组下存在关联账号,请先取消关联!']);
         }
 
         try {
-            UserGroup::whereId($id)->delete();
+            $group->delete();
         } catch (Exception $e) {
             return Response::json(['status' => 'fail', 'message' => '删除失败,'.$e->getMessage()]);
         }

+ 1 - 34
app/Http/Controllers/AdminController.php

@@ -46,7 +46,7 @@ class AdminController extends Controller
         $view['unActiveUserCount'] = User::whereEnable(1)->whereBetween('t', [1, $past])->count(); // 不活跃用户数
         $view['onlineUserCount'] = User::where('t', '>=', strtotime('-10 minutes'))->count(); // 10分钟内在线用户数
         $view['expireWarningUserCount'] = User::whereBetween('expired_at', [date('Y-m-d'), date('Y-m-d', strtotime('+'.sysConfig('expire_days').' days'))])->count(); // 临近过期用户数
-        $view['largeTrafficUserCount'] = User::whereRaw('(u + d) >= 107374182400')->where('status', '<>', -1)->count(); // 流量超过100G的用户
+        $view['largeTrafficUserCount'] = User::whereRaw('(u + d)/transfer_enable >= 0.9')->where('status', '<>', -1)->count(); // 流量使用超过90%的用户
         $view['flowAbnormalUserCount'] = count((new UserHourlyDataFlow)->trafficAbnormal()); // 1小时内流量异常用户
         $view['nodeCount'] = Node::count();
         $view['unnormalNodeCount'] = Node::whereStatus(0)->count();
@@ -67,31 +67,6 @@ class AdminController extends Controller
         return view('admin.index', $view);
     }
 
-    // 修改个人资料
-    public function profile(Request $request)
-    {
-        if ($request->isMethod('POST')) {
-            $new_password = $request->input('new_password');
-
-            if (! Hash::check($request->input('old_password'), Auth::getUser()->password)) {
-                return Redirect::back()->withErrors('旧密码错误,请重新输入');
-            }
-
-            if (Hash::check($new_password, Auth::getUser()->password)) {
-                return Redirect::back()->withErrors('新密码不可与旧密码一样,请重新输入');
-            }
-
-            $ret = Auth::getUser()->update(['password' => $new_password]);
-            if (! $ret) {
-                return Redirect::back()->withErrors('修改失败');
-            }
-
-            return Redirect::back()->with('successMsg', '修改成功');
-        }
-
-        return view('admin.config.profile');
-    }
-
     // 邀请码列表
     public function inviteList(Request $request)
     {
@@ -109,10 +84,7 @@ class AdminController extends Controller
     {
         for ($i = 0; $i < 10; $i++) {
             $obj = new Invite();
-            $obj->inviter_id = 0;
-            $obj->invitee_id = 0;
             $obj->code = strtoupper(substr(md5(microtime().Str::random(6)), 8, 12));
-            $obj->status = 0;
             $obj->dateline = date('Y-m-d H:i:s', strtotime('+'.sysConfig('admin_invite_days').' days'));
             $obj->save();
         }
@@ -165,9 +137,4 @@ class AdminController extends Controller
 
         return view('admin.config.config', $view);
     }
-
-    public function getPort(): int
-    {
-        return Helpers::getPort();
-    }
 }

+ 5 - 5
app/Http/Controllers/Api/WebApi/BaseController.php

@@ -51,9 +51,9 @@ class BaseController
     {
         $etag = Helpers::abortIfNotModified($data);
         $data = [
-            'status'  => $status,
-            'code'    => $code,
-            'data'    => $data,
+            'status' => $status,
+            'code' => $code,
+            'data' => $data,
             'message' => $message,
         ];
 
@@ -149,8 +149,8 @@ class BaseController
                     $rule = Rule::find($ruleId);
                     if ($rule) {
                         $data[] = [
-                            'id'      => $rule->id,
-                            'type'    => $rule->type_api_label,
+                            'id' => $rule->id,
+                            'type' => $rule->type_api_label,
                             'pattern' => $rule->pattern,
                         ];
                     }

+ 9 - 9
app/Http/Controllers/Api/WebApi/TrojanController.php

@@ -13,15 +13,15 @@ class TrojanController extends BaseController
         $node = Node::find($id);
 
         return $this->returnData('获取节点信息成功', 'success', 200, [
-            'id'           => $node->id,
-            'is_udp'       => $node->is_udp ? true : false,
-            'speed_limit'  => $node->getRawOriginal('speed_limit'),
+            'id' => $node->id,
+            'is_udp' => $node->is_udp ? true : false,
+            'speed_limit' => $node->getRawOriginal('speed_limit'),
             'client_limit' => $node->client_limit,
-            'push_port'    => $node->push_port,
+            'push_port' => $node->push_port,
             'redirect_url' => sysConfig('redirect_url'),
-            'trojan_port'  => $node->port,
-            'secret'       => $node->auth->secret,
-            'license'      => sysConfig('trojan_license'),
+            'trojan_port' => $node->port,
+            'secret' => $node->auth->secret,
+            'license' => sysConfig('trojan_license'),
         ]);
     }
 
@@ -33,8 +33,8 @@ class TrojanController extends BaseController
 
         foreach ($users as $user) {
             $data[] = [
-                'uid'         => $user->id,
-                'password'    => $user->passwd,
+                'uid' => $user->id,
+                'password' => $user->passwd,
                 'speed_limit' => $user->getRawOriginal('speed_limit'),
             ];
         }

+ 20 - 20
app/Http/Controllers/Api/WebApi/V2RayController.php

@@ -20,24 +20,24 @@ class V2RayController extends BaseController
         }
 
         return $this->returnData('获取节点信息成功', 'success', 200, [
-            'id'              => $node->id,
-            'is_udp'          => $node->is_udp ? true : false,
-            'speed_limit'     => $node->getRawOriginal('speed_limit'),
-            'client_limit'    => $node->client_limit,
-            'push_port'       => $node->push_port,
-            'redirect_url'    => (string) sysConfig('redirect_url'),
-            'secret'          => $node->auth->secret,
-            'key'             => $nodeDv->key ?? '',
-            'pem'             => $nodeDv->pem ?? '',
-            'v2_license'      => (string) sysConfig('v2ray_license'),
-            'v2_alter_id'     => $node->v2_alter_id,
-            'v2_port'         => $node->v2_port,
-            'v2_method'       => $node->v2_method,
-            'v2_net'          => $node->v2_net,
-            'v2_type'         => $node->v2_type,
-            'v2_host'         => $node->v2_host,
-            'v2_path'         => $node->v2_path,
-            'v2_tls'          => $node->v2_tls ? true : false,
+            'id' => $node->id,
+            'is_udp' => $node->is_udp ? true : false,
+            'speed_limit' => $node->getRawOriginal('speed_limit'),
+            'client_limit' => $node->client_limit,
+            'push_port' => $node->push_port,
+            'redirect_url' => (string) sysConfig('redirect_url'),
+            'secret' => $node->auth->secret,
+            'key' => $nodeDv->key ?? '',
+            'pem' => $nodeDv->pem ?? '',
+            'v2_license' => (string) sysConfig('v2ray_license'),
+            'v2_alter_id' => $node->v2_alter_id,
+            'v2_port' => $node->v2_port,
+            'v2_method' => $node->v2_method,
+            'v2_net' => $node->v2_net,
+            'v2_type' => $node->v2_type,
+            'v2_host' => $node->v2_host,
+            'v2_path' => $node->v2_path,
+            'v2_tls' => $node->v2_tls ? true : false,
             'v2_tls_provider' => $tlsProvider,
         ]);
     }
@@ -50,8 +50,8 @@ class V2RayController extends BaseController
 
         foreach ($users as $user) {
             $data[] = [
-                'uid'         => $user->id,
-                'vmess_uid'   => $user->vmess_id,
+                'uid' => $user->id,
+                'vmess_uid' => $user->vmess_id,
                 'speed_limit' => $user->getRawOriginal('speed_limit'),
             ];
         }

+ 20 - 20
app/Http/Controllers/Api/WebApi/VNetController.php

@@ -13,19 +13,19 @@ class VNetController extends BaseController
         $node = Node::find($id);
 
         return $this->returnData('获取节点信息成功', 'success', 200, [
-            'id'           => $node->id,
-            'method'       => $node->method,
-            'protocol'     => $node->protocol,
-            'obfs'         => $node->obfs,
-            'obfs_param'   => $node->obfs_param ?? '',
-            'is_udp'       => $node->is_udp,
-            'speed_limit'  => $node->getRawOriginal('speed_limit'),
+            'id' => $node->id,
+            'method' => $node->method,
+            'protocol' => $node->protocol,
+            'obfs' => $node->obfs,
+            'obfs_param' => $node->obfs_param ?? '',
+            'is_udp' => $node->is_udp,
+            'speed_limit' => $node->getRawOriginal('speed_limit'),
             'client_limit' => $node->client_limit,
-            'single'       => $node->single,
-            'port'         => (string) $node->port,
-            'passwd'       => $node->passwd ?? '',
-            'push_port'    => $node->push_port,
-            'secret'       => $node->auth->secret,
+            'single' => $node->single,
+            'port' => (string) $node->port,
+            'passwd' => $node->passwd ?? '',
+            'push_port' => $node->push_port,
+            'secret' => $node->auth->secret,
             'redirect_url' => sysConfig('redirect_url'),
         ]);
     }
@@ -39,15 +39,15 @@ class VNetController extends BaseController
 
         foreach ($users as $user) {
             $data[] = [
-                'uid'         => $user->id,
-                'port'        => $user->port,
-                'passwd'      => $user->passwd,
-                'method'      => $user->method,
-                'protocol'    => $user->protocol,
-                'obfs'        => $user->obfs,
-                'obfs_param'  => $node->obfs_param,
+                'uid' => $user->id,
+                'port' => $user->port,
+                'passwd' => $user->passwd,
+                'method' => $user->method,
+                'protocol' => $user->protocol,
+                'obfs' => $user->obfs,
+                'obfs_param' => $node->obfs_param,
                 'speed_limit' => $user->getRawOriginal('speed_limit'),
-                'enable'      => $user->enable,
+                'enable' => $user->enable,
             ];
         }
 

+ 40 - 52
app/Http/Controllers/AuthController.php

@@ -13,7 +13,6 @@ use App\Models\User;
 use App\Models\UserLoginLog;
 use App\Models\Verify;
 use App\Models\VerifyCode;
-use App\Services\UserService;
 use Auth;
 use Cache;
 use Captcha;
@@ -41,10 +40,10 @@ class AuthController extends Controller
     {
         if ($request->isMethod('POST')) {
             $validator = Validator::make($request->all(), [
-                'email'    => 'required|email',
+                'email' => 'required|email',
                 'password' => 'required',
             ], [
-                'email.required'    => trans('auth.email_null'),
+                'email.required' => trans('auth.email_null'),
                 'password.required' => trans('auth.password_null'),
             ]);
 
@@ -73,18 +72,16 @@ class AuthController extends Controller
             }
 
             // 校验普通用户账号状态
-            if (! $user->is_admin) {
-                if ($user->status < 0) {
-                    Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
+            if ($user->status < 0) {
+                Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
 
-                    return Redirect::back()->withInput()->withErrors(trans('auth.login_ban', ['email' => sysConfig('webmaster_email')]));
-                }
+                return Redirect::back()->withInput()->withErrors(trans('auth.login_ban', ['email' => sysConfig('webmaster_email')]));
+            }
 
-                if ($user->status === 0 && sysConfig('is_activate_account')) {
-                    Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
+            if ($user->status === 0 && sysConfig('is_activate_account')) {
+                Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
 
-                    return Redirect::back()->withInput()->withErrors(trans('auth.active_tip').'<a href="'.route('active').'?email='.$email.'" target="_blank"><span style="color:#000">【'.trans('auth.active_account').'】</span></a>');
-                }
+                return Redirect::back()->withInput()->withErrors(trans('auth.active_tip').'<a href="'.route('active').'?email='.$email.'" target="_blank"><span style="color:#000">【'.trans('auth.active_account').'】</span></a>');
             }
 
             // 写入登录日志
@@ -94,7 +91,7 @@ class AuthController extends Controller
             Auth::getUser()->update(['last_login' => time()]);
 
             // 根据权限跳转
-            if ($user->is_admin) {
+            if ($user->hasPermissionTo('admin.index')) {
                 return Redirect::route('admin.index');
             }
 
@@ -102,7 +99,7 @@ class AuthController extends Controller
         }
 
         if (Auth::check()) {
-            if (Auth::getUser()->is_admin) {
+            if (Auth::getUser()->hasPermissionTo('admin.index')) {
                 return Redirect::route('admin.index');
             }
 
@@ -198,21 +195,21 @@ class AuthController extends Controller
 
         if ($request->isMethod('POST')) {
             $validator = Validator::make($request->all(), [
-                'username'        => 'required',
-                'email'           => 'required|email|unique:user',
-                'password'        => 'required|min:6',
+                'username' => 'required',
+                'email' => 'required|email|unique:user',
+                'password' => 'required|min:6',
                 'confirmPassword' => 'required|same:password',
-                'term'            => 'accepted',
+                'term' => 'accepted',
             ], [
-                'username.required'        => trans('auth.email_null'),
-                'email.required'           => trans('auth.email_null'),
-                'email.email'              => trans('auth.email_legitimate'),
-                'email.unique'             => trans('auth.email_exist'),
-                'password.required'        => trans('auth.password_null'),
-                'password.min'             => trans('auth.password_limit'),
+                'username.required' => trans('auth.email_null'),
+                'email.required' => trans('auth.email_null'),
+                'email.email' => trans('auth.email_legitimate'),
+                'email.unique' => trans('auth.email_exist'),
+                'password.required' => trans('auth.password_null'),
+                'password.min' => trans('auth.password_limit'),
                 'confirmPassword.required' => trans('auth.confirm_password'),
-                'confirmPassword.same'     => trans('auth.password_same'),
-                'term.accepted'            => trans('auth.unaccepted'),
+                'confirmPassword.same' => trans('auth.password_same'),
+                'term.accepted' => trans('auth.unaccepted'),
             ]);
 
             if ($validator->fails()) {
@@ -340,7 +337,7 @@ class AuthController extends Controller
                 if ($inviter_id) {
                     $referralUser = User::find($inviter_id);
                     if ($referralUser && $referralUser->expired_at >= date('Y-m-d')) {
-                        (new UserService($referralUser))->incrementData(sysConfig('referral_traffic') * MB);
+                        $referralUser->incrementData(sysConfig('referral_traffic') * MB);
                     }
                 }
 
@@ -421,11 +418,11 @@ class AuthController extends Controller
         // 没有用邀请码或者邀请码是管理员生成的,则检查cookie或者url链接
         if (! $data['inviter_id']) {
             // 检查一下cookie里有没有aff
-            $cookieAff = \Request::hasCookie('register_aff') ? \Request::cookie('register_aff') : 0;
+            $cookieAff = \Request::hasCookie('register_aff');
             if ($cookieAff) {
-                $data['inviter_id'] = User::find($cookieAff) ? $cookieAff : 0;
+                $data['inviter_id'] = User::find($cookieAff) ? $cookieAff : null;
             } elseif ($aff) { // 如果cookie里没有aff,就再检查一下请求的url里有没有aff,因为有些人的浏览器会禁用了cookie,比如chrome开了隐私模式
-                $data['inviter_id'] = User::find($aff) ? $aff : 0;
+                $data['inviter_id'] = User::find($aff) ? $aff : null;
             }
         }
 
@@ -437,10 +434,8 @@ class AuthController extends Controller
     {
         $token = md5(sysConfig('website_name').$email.microtime());
         $verify = new Verify();
-        $verify->type = 1;
         $verify->user_id = $uid;
         $verify->token = $token;
-        $verify->status = 0;
         $verify->save();
 
         return $token;
@@ -455,7 +450,7 @@ class AuthController extends Controller
                 'email' => 'required|email',
             ], [
                 'email.required' => trans('auth.email_null'),
-                'email.email'    => trans('auth.email_legitimate'),
+                'email.email' => trans('auth.email_legitimate'),
             ]);
 
             if ($validator->fails()) {
@@ -510,14 +505,14 @@ class AuthController extends Controller
 
         if ($request->isMethod('POST')) {
             $validator = Validator::make($request->all(), [
-                'password'        => 'required|min:6',
+                'password' => 'required|min:6',
                 'confirmPassword' => 'required|same:password',
             ], [
-                'password.required'        => trans('auth.password_null'),
-                'password.min'             => trans('auth.password_limit'),
+                'password.required' => trans('auth.password_null'),
+                'password.min' => trans('auth.password_limit'),
                 'confirmPassword.required' => trans('auth.password_null'),
-                'confirmPassword.min'      => trans('auth.password_limit'),
-                'confirmPassword.same'     => trans('auth.password_same'),
+                'confirmPassword.min' => trans('auth.password_limit'),
+                'confirmPassword.same' => trans('auth.password_same'),
             ]);
 
             if ($validator->fails()) {
@@ -581,8 +576,8 @@ class AuthController extends Controller
                 'email' => 'required|email|exists:user,email',
             ], [
                 'email.required' => trans('auth.email_null'),
-                'email.email'    => trans('auth.email_legitimate'),
-                'email.exists'   => trans('auth.email_notExist'),
+                'email.email' => trans('auth.email_legitimate'),
+                'email.exists' => trans('auth.email_notExist'),
             ]);
 
             if ($validator->fails()) {
@@ -645,13 +640,7 @@ class AuthController extends Controller
             return Redirect::route('login');
         }
 
-        if (empty($user)) {
-            Session::flash('errorMsg', trans('auth.overtime'));
-
-            return view('auth.active');
-        }
-
-        if ($verify->status > 0) {
+        if (empty($user) || $verify->status > 0) {
             Session::flash('errorMsg', trans('auth.overtime'));
 
             return view('auth.active');
@@ -687,7 +676,7 @@ class AuthController extends Controller
         // 账号激活后给邀请人送流量
         $inviter = $user->inviter;
         if ($inviter) {
-            (new UserService($inviter))->incrementData(sysConfig('referral_traffic') * MB);
+            $inviter->incrementData(sysConfig('referral_traffic') * MB);
         }
 
         Session::flash('successMsg', trans('auth.active_success'));
@@ -702,8 +691,8 @@ class AuthController extends Controller
             'email' => 'required|email|unique:user',
         ], [
             'email.required' => trans('auth.email_null'),
-            'email.email'    => trans('auth.email_legitimate'),
-            'email.unique'   => trans('auth.email_exist'),
+            'email.email' => trans('auth.email_legitimate'),
+            'email.unique' => trans('auth.email_exist'),
         ]);
 
         $email = $request->input('email');
@@ -744,12 +733,11 @@ class AuthController extends Controller
     }
 
     // 生成注册验证码
-    private function addVerifyCode($email, $code): void
+    private function addVerifyCode(string $email, string $code): void
     {
         $verify = new VerifyCode();
         $verify->address = $email;
         $verify->code = $code;
-        $verify->status = 0;
         $verify->save();
     }
 

+ 4 - 4
app/Http/Controllers/Controller.php

@@ -195,7 +195,7 @@ class Controller extends BaseController
     public function v2raySubUrl($name, $host, $port, $uuid, $alter_id, $net, $type, $domain, $path, $tls): string
     {
         return 'vmess://'.base64url_encode(json_encode([
-            'v'    => '2', 'ps' => $name, 'add' => $host, 'port' => $port, 'id' => $uuid, 'aid' => $alter_id, 'net' => $net,
+            'v' => '2', 'ps' => $name, 'add' => $host, 'port' => $port, 'id' => $uuid, 'aid' => $alter_id, 'net' => $net,
             'type' => $type, 'host' => $domain, 'path' => $path, 'tls' => $tls ? 'tls' : '',
         ], JSON_PRETTY_PRINT));
     }
@@ -246,10 +246,10 @@ class Controller extends BaseController
         $dailyData[date('j', strtotime(now())) - 1] = round((array_sum($hourlyFlow) + $currentFlow) / GB, 3);
 
         return [
-            'trafficDaily'  => json_encode($dailyData),
+            'trafficDaily' => json_encode($dailyData),
             'trafficHourly' => json_encode($hourlyData),
-            'monthDays'     => json_encode(range(1, date('j'), 1)), // 本月天数
-            'dayHours'      => json_encode(range(0, date('G') + 1, 1)), // 本日小时
+            'monthDays' => json_encode(range(1, date('j'), 1)), // 本月天数
+            'dayHours' => json_encode(range(0, date('G') + 1, 1)), // 本日小时
         ];
     }
 }

+ 11 - 11
app/Http/Controllers/Gateway/BitpayX.php

@@ -17,14 +17,14 @@ class BitpayX extends AbstractPayment
 
         $data = [
             'merchant_order_id' => $payment->trade_no,
-            'price_amount'      => $payment->amount,
-            'price_currency'    => 'CNY',
-            'title'             => '支付单号:'.$payment->trade_no,
-            'description'       => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'callback_url'      => route('payment.notify', ['method' => 'bitpayx']),
-            'success_url'       => route('invoice'),
-            'cancel_url'        => route('invoice'),
-            'token'             => $this->sign($payment->trade_no),
+            'price_amount' => $payment->amount,
+            'price_currency' => 'CNY',
+            'title' => '支付单号:'.$payment->trade_no,
+            'description' => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'callback_url' => route('payment.notify', ['method' => 'bitpayx']),
+            'success_url' => route('invoice'),
+            'cancel_url' => route('invoice'),
+            'token' => $this->sign($payment->trade_no),
         ];
         $result = $this->sendRequest($data);
 
@@ -44,8 +44,8 @@ class BitpayX extends AbstractPayment
     {
         $data = [
             'merchant_order_id' => $tradeNo,
-            'secret'            => sysConfig('bitpay_secret'),
-            'type'              => 'FIAT',
+            'secret' => sysConfig('bitpay_secret'),
+            'type' => 'FIAT',
         ];
 
         return $this->aliStyleSign($data, sysConfig('bitpay_secret'));
@@ -56,7 +56,7 @@ class BitpayX extends AbstractPayment
         $client = Http::baseUrl('https://api.mugglepay.com/v1/')
             ->timeout(15)
             ->withHeaders([
-                'token'        => sysConfig('bitpay_secret'),
+                'token' => sysConfig('bitpay_secret'),
                 'content-type' => 'application/json',
             ]);
 

+ 6 - 6
app/Http/Controllers/Gateway/CodePay.php

@@ -14,12 +14,12 @@ class CodePay extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $data = [
-            'id'         => sysConfig('codepay_id'),
-            'pay_id'     => $payment->trade_no,
-            'type'       => $request->input('type'),            //1支付宝支付 2QQ钱包 3微信支付
-            'price'      => $payment->amount,
-            'page'       => 1,
-            'outTime'    => 900,
+            'id' => sysConfig('codepay_id'),
+            'pay_id' => $payment->trade_no,
+            'type' => $request->input('type'),            //1支付宝支付 2QQ钱包 3微信支付
+            'price' => $payment->amount,
+            'page' => 1,
+            'outTime' => 900,
             'notify_url' => route('payment.notify', ['method' => 'codepay']),
             'return_url' => route('invoice'),
         ];

+ 7 - 7
app/Http/Controllers/Gateway/EPay.php

@@ -29,14 +29,14 @@ class EPay extends AbstractPayment
         }
 
         $data = [
-            'pid'          => sysConfig('epay_mch_id'),
-            'type'         => $type,
-            'notify_url'   => route('payment.notify', ['method' => 'epay']),
-            'return_url'   => route('invoice'),
+            'pid' => sysConfig('epay_mch_id'),
+            'type' => $type,
+            'notify_url' => route('payment.notify', ['method' => 'epay']),
+            'return_url' => route('invoice'),
             'out_trade_no' => $payment->trade_no,
-            'name'         => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'money'        => $payment->amount,
-            'sign_type'    => 'MD5',
+            'name' => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'money' => $payment->amount,
+            'sign_type' => 'MD5',
         ];
         $data['sign'] = $this->aliStyleSign($data, sysConfig('epay_key'));
 

+ 13 - 13
app/Http/Controllers/Gateway/F2Fpay.php

@@ -19,15 +19,15 @@ class F2Fpay extends AbstractPayment
     public function __construct()
     {
         self::$aliConfig = [
-            'use_sandbox'     => false,
-            'app_id'          => sysConfig('f2fpay_app_id'),
-            'sign_type'       => 'RSA2',
-            'ali_public_key'  => sysConfig('f2fpay_public_key'),
+            'use_sandbox' => false,
+            'app_id' => sysConfig('f2fpay_app_id'),
+            'sign_type' => 'RSA2',
+            'ali_public_key' => sysConfig('f2fpay_public_key'),
             'rsa_private_key' => sysConfig('f2fpay_private_key'),
-            'limit_pay'       => [],
-            'notify_url'      => route('payment.notify', ['method' => 'f2fpay']),
-            'return_url'      => route('invoice'),
-            'fee_type'        => 'CNY',
+            'limit_pay' => [],
+            'notify_url' => route('payment.notify', ['method' => 'f2fpay']),
+            'return_url' => route('invoice'),
+            'fee_type' => 'CNY',
         ];
     }
 
@@ -36,11 +36,11 @@ class F2Fpay extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $data = [
-            'body'        => '',
-            'subject'     => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'trade_no'    => $payment->trade_no,
+            'body' => '',
+            'subject' => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'trade_no' => $payment->trade_no,
             'time_expire' => time() + 900, // 必须 15分钟 内付款
-            'amount'      => $payment->amount,
+            'amount' => $payment->amount,
         ];
 
         try {
@@ -64,7 +64,7 @@ class F2Fpay extends AbstractPayment
     public function notify($request): void
     {
         $data = [
-            'trade_no'       => $request->input('out_trade_no'),
+            'trade_no' => $request->input('out_trade_no'),
             'transaction_id' => $request->input('trade_no'),
         ];
 

+ 4 - 4
app/Http/Controllers/Gateway/PayJs.php

@@ -16,7 +16,7 @@ class PayJs extends AbstractPayment
     {
         self::$config = [
             'mchid' => sysConfig('payjs_mch_id'),   // 配置商户号
-            'key'   => sysConfig('payjs_key'),   // 配置通信密钥
+            'key' => sysConfig('payjs_key'),   // 配置通信密钥
         ];
     }
 
@@ -25,10 +25,10 @@ class PayJs extends AbstractPayment
         $payment = $this->creatNewPayment(Auth::id(), $request->input('id'), $request->input('amount'));
 
         $result = (new Pay($this::$config))->cashier([
-            'body'         => sysConfig('subject_name') ?: sysConfig('website_name'),
-            'total_fee'    => $payment->amount * 100,
+            'body' => sysConfig('subject_name') ?: sysConfig('website_name'),
+            'total_fee' => $payment->amount * 100,
             'out_trade_no' => $payment->trade_no,
-            'notify_url'   => route('payment.notify', ['method' => 'payjs']),
+            'notify_url' => route('payment.notify', ['method' => 'payjs']),
         ]);
 
         // 获取收款二维码内容

+ 17 - 17
app/Http/Controllers/Gateway/PayPal.php

@@ -23,19 +23,19 @@ class PayPal extends AbstractPayment
         $config = [
             'mode' => 'live',
             'live' => [
-                'username'    => sysConfig('paypal_username'),
-                'password'    => sysConfig('paypal_password'),
-                'secret'      => sysConfig('paypal_secret'),
+                'username' => sysConfig('paypal_username'),
+                'password' => sysConfig('paypal_password'),
+                'secret' => sysConfig('paypal_secret'),
                 'certificate' => sysConfig('paypal_certificate'),
-                'app_id'      => sysConfig('paypal_app_id'),
+                'app_id' => sysConfig('paypal_app_id'),
             ],
 
             'payment_action' => 'Sale',
-            'currency'       => 'USD',
-            'billing_type'   => 'MerchantInitiatedBilling',
-            'notify_url'     => route('payment.notify', ['method' => 'paypal']),
-            'locale'         => 'zh_CN',
-            'validate_ssl'   => true,
+            'currency' => 'USD',
+            'billing_type' => 'MerchantInitiatedBilling',
+            'notify_url' => route('payment.notify', ['method' => 'paypal']),
+            'locale' => 'zh_CN',
+            'validate_ssl' => true,
         ];
         $this->provider->setApiCredentials($config);
         $response = Http::timeout(15)->get('http://api.k780.com/?app=finance.rate&scur=USD&tcur=CNY&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4');
@@ -69,19 +69,19 @@ class PayPal extends AbstractPayment
         $amount = 0.3 + ceil($amount / $this->exChange * 100) / 100;
 
         return [
-            'invoice_id'          => $trade_no,
-            'items'               => [
+            'invoice_id' => $trade_no,
+            'items' => [
                 [
-                    'name'  => sysConfig('subject_name') ?: sysConfig('website_name'),
+                    'name' => sysConfig('subject_name') ?: sysConfig('website_name'),
                     'price' => $amount,
-                    'desc'  => 'Description for'.(sysConfig('subject_name') ?: sysConfig('website_name')),
-                    'qty'   => 1,
+                    'desc' => 'Description for'.(sysConfig('subject_name') ?: sysConfig('website_name')),
+                    'qty' => 1,
                 ],
             ],
             'invoice_description' => $trade_no,
-            'return_url'          => route('paypal.checkout'),
-            'cancel_url'          => route('invoice'),
-            'total'               => $amount,
+            'return_url' => route('paypal.checkout'),
+            'cancel_url' => route('invoice'),
+            'total' => $amount,
         ];
     }
 

+ 10 - 10
app/Http/Controllers/Gateway/Stripe.php

@@ -44,22 +44,22 @@ class Stripe extends AbstractPayment
         $unitAmount = $amount * 100;
 
         return [
-            'payment_method_types' => ['card'],
-            'line_items'           => [
+            'payment_method_types' => ['card', 'alipay'],
+            'line_items' => [
                 [
                     'price_data' => [
-                        'currency'     => 'usd',
+                        'currency' => 'usd',
                         'product_data' => ['name' => sysConfig('subject_name') ?: sysConfig('website_name')],
-                        'unit_amount'  => $unitAmount,
+                        'unit_amount' => $unitAmount,
                     ],
-                    'quantity'   => 1,
+                    'quantity' => 1,
                 ],
             ],
-            'mode'                 => 'payment',
-            'success_url'          => route('invoice'),
-            'cancel_url'           => route('invoice'),
-            'client_reference_id'  => $tradeNo,
-            'customer_email'       => Auth::getUser()->email,
+            'mode' => 'payment',
+            'success_url' => route('invoice'),
+            'cancel_url' => route('invoice'),
+            'client_reference_id' => $tradeNo,
+            'customer_email' => Auth::getUser()->email,
         ];
     }
 

+ 0 - 2
app/Http/Controllers/PaymentController.php

@@ -173,10 +173,8 @@ class PaymentController extends Controller
             $order->coupon_id = $coupon->id ?? 0;
             $order->origin_amount = $credit ?: $goods->price;
             $order->amount = $amount;
-            $order->is_expire = 0;
             $order->pay_type = $pay_type;
             $order->pay_way = self::$method;
-            $order->status = 0;
             $order->save();
 
             // 使用优惠券,减少可使用次数

+ 0 - 2
app/Http/Controllers/User/AffiliateController.php

@@ -55,10 +55,8 @@ class AffiliateController extends Controller
         $ref = new ReferralApply();
         $ref->user_id = Auth::id();
         $ref->before = $commission;
-        $ref->after = 0;
         $ref->amount = $commission;
         $ref->link_logs = ReferralLog::uid()->whereStatus(0)->pluck('id')->toArray();
-        $ref->status = 0;
         if ($ref->save()) {
             return Response::json(['status' => 'success', 'message' => '申请成功,请等待管理员审核']);
         }

+ 6 - 6
app/Http/Controllers/User/SubscribeController.php

@@ -45,11 +45,11 @@ class SubscribeController extends Controller
 
         if ($user->enable !== 1) {
             if ($user->ban_time) {
-                return $this->failed('账号封禁至'.date('m-d H:i', $user->ban_time).',请解封后再更新!');
+                return $this->failed('账号封禁至'.$user->ban_time.',请解封后再更新!');
             }
 
-            $unusedTransfer = $user->transfer_enable - $user->u - $user->d;
-            if ($unusedTransfer <= 0) {
+            $unusedTraffic = $user->transfer_enable - $user->usedTraffic();
+            if ($unusedTraffic <= 0) {
                 return $this->failed('流量耗尽!请重新购买或重置流量!');
             }
 
@@ -89,7 +89,7 @@ class SubscribeController extends Controller
 
         // 展示到期时间和剩余流量
         if (sysConfig('is_custom_subscribe')) {
-            $scheme .= $this->infoGenerator('到期时间: '.$user->expired_at).$this->infoGenerator('剩余流量: '.flowAutoShow($user->transfer_enable - $user->u - $user->d));
+            $scheme .= $this->infoGenerator('到期时间: '.$user->expired_at).$this->infoGenerator('剩余流量: '.flowAutoShow($user->transfer_enable - $user->usedTraffic()));
         }
 
         // 控制客户端最多获取节点数
@@ -103,7 +103,7 @@ class SubscribeController extends Controller
         }
 
         $headers = [
-            'Content-type'  => 'application/octet-stream; charset=utf-8',
+            'Content-type' => 'application/octet-stream; charset=utf-8',
             'Cache-Control' => 'no-store, no-cache, must-revalidate',
             //'Content-Disposition' => 'attachment; filename='.$filename
         ];
@@ -128,7 +128,7 @@ class SubscribeController extends Controller
         switch ($this->subType) {
             case 2:
                 $result = 'vmess://'.base64url_encode(json_encode([
-                    'v'    => '2', 'ps' => $text, 'add' => '0.0.0.0', 'port' => 0, 'id' => 0, 'aid' => 0, 'net' => 'tcp',
+                    'v' => '2', 'ps' => $text, 'add' => '0.0.0.0', 'port' => 0, 'id' => 0, 'aid' => 0, 'net' => 'tcp',
                     'type' => 'none', 'host' => '', 'path' => '/', 'tls' => 'tls',
                 ], JSON_PRETTY_PRINT));
                 break;

+ 30 - 45
app/Http/Controllers/UserController.php

@@ -16,10 +16,8 @@ use App\Models\NodePing;
 use App\Models\Order;
 use App\Models\Ticket;
 use App\Models\TicketReply;
-use App\Models\UserHourlyDataFlow;
 use App\Models\UserLoginLog;
 use App\Models\UserSubscribe;
-use App\Services\UserService;
 use Auth;
 use Cache;
 use DB;
@@ -45,26 +43,26 @@ class UserController extends Controller
 {
     public function index()
     {
-        $user = Auth::getUser();
-        if (! $user) {
-            return redirect()->route('login');
+        if (Session::has('user')) {
+            Auth::loginUsingId(Session::get('user'));
+            Session::forget('user');
         }
+        $user = Auth::getUser();
         $totalTransfer = $user->transfer_enable;
-        $usedTransfer = $user->u + $user->d;
-        $unusedTransfer = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0;
+        $usedTransfer = $user->usedTraffic();
+        $unusedTraffic = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0;
         $expireTime = $user->expired_at;
         $view['remainDays'] = $expireTime < date('Y-m-d') ? -1 : Helpers::daysToNow($expireTime);
         $view['resetDays'] = $user->reset_time ? Helpers::daysToNow($user->reset_time) : 0;
-        $view['unusedTransfer'] = $unusedTransfer;
+        $view['unusedTraffic'] = flowAutoShow($unusedTraffic);
         $view['expireTime'] = $expireTime;
-        $view['banedTime'] = $user->ban_time ? date('Y-m-d H:i:s', $user->ban_time) : 0;
-        $view['unusedPercent'] = $totalTransfer > 0 ? round($unusedTransfer / $totalTransfer, 2) : 0;
-        $view['noticeList'] = Article::type(2)->latest()->Paginate(1); // 公告
+        $view['banedTime'] = $user->ban_time ?: 0;
+        $view['unusedPercent'] = $totalTransfer > 0 ? round($unusedTraffic / $totalTransfer, 2) * 100 : 0;
+        $view['announcements'] = Article::type(2)->take(5)->latest()->Paginate(1); // 公告
         //流量异常判断
-        $hourlyTraffic = UserHourlyDataFlow::userRecentUsed($user->id)->sum('total');
-        $view['isTrafficWarning'] = $hourlyTraffic >= (sysConfig('traffic_ban_value') * GB) ?: 0;
+        $view['isTrafficWarning'] = $user->isTrafficWarning();
         //付费用户判断
-        $view['not_paying_user'] = Order::uid()->active()->where('origin_amount', '>', 0)->doesntExist();
+        $view['paying_user'] = $user->activePayingUser();
         $view['userLoginLog'] = UserLoginLog::whereUserId($user->id)->latest()->first(); // 近期登录日志
         $view = array_merge($view, $this->dataFlowChart($user->id));
 
@@ -87,12 +85,12 @@ class UserController extends Controller
 
         $traffic = random_int((int) sysConfig('min_rand_traffic'), (int) sysConfig('max_rand_traffic')) * MB;
 
-        if (! (new UserService())->incrementData($traffic)) {
+        if (! $user->incrementData($traffic)) {
             return Response::json(['status' => 'fail', 'message' => '签到失败,系统异常']);
         }
 
         // 写入用户流量变动记录
-        Helpers::addUserTrafficModifyLog($user->id, 0, $user->transfer_enable, $user->transfer_enable + $traffic, '[签到]');
+        Helpers::addUserTrafficModifyLog($user->id, null, $user->transfer_enable, $user->transfer_enable + $traffic, '[签到]');
 
         // 多久后可以再签到
         $ttl = sysConfig('traffic_limit_time') ? sysConfig('traffic_limit_time') * Minute : Day;
@@ -242,10 +240,10 @@ class UserController extends Controller
         $user->update(['u' => 0, 'd' => 0]);
 
         // 扣余额
-        (new UserService($user))->updateCredit(-$renewCost);
+        $user->updateCredit(-$renewCost);
 
         // 记录余额操作日志
-        Helpers::addUserCreditLog($user->id, 0, $user->credit, $user->credit - $renewCost, -1 * $renewCost, '用户自行重置流量');
+        Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit - $renewCost, -1 * $renewCost, '用户自行重置流量');
 
         return Response::json(['status' => 'success', 'message' => '重置成功']);
     }
@@ -253,15 +251,15 @@ class UserController extends Controller
     // 工单
     public function ticketList(Request $request)
     {
-        $view['ticketList'] = Ticket::uid()->latest()->paginate(10)->appends($request->except('page'));
-
-        return view('user.ticketList', $view);
+        return view('user.ticketList', [
+            'tickets' => Auth::user()->tickets()->latest()->paginate(10)->appends($request->except('page')),
+        ]);
     }
 
     // 订单
     public function invoices(Request $request)
     {
-        $view['orderList'] = Order::uid()
+        $view['orderList'] = Auth::user()->orders()
             ->with(['goods', 'payment'])
             ->orderByDesc('id')
             ->paginate(10)
@@ -291,7 +289,7 @@ class UserController extends Controller
     // 订单明细
     public function invoiceDetail($sn)
     {
-        $view['order'] = Order::uid()->with(['goods', 'coupon', 'payment'])->whereOrderSn($sn)->firstOrFail();
+        $view['order'] = Order::uid()->whereOrderSn($sn)->with(['goods', 'coupon', 'payment'])->firstOrFail();
 
         return view('user.invoiceDetail', $view);
     }
@@ -312,10 +310,8 @@ class UserController extends Controller
         $obj->user_id = $user->id;
         $obj->title = $title;
         $obj->content = $content;
-        $obj->status = 0;
-        $obj->save();
 
-        if ($obj->id) {
+        if ($obj->save()) {
             $emailTitle = '新工单提醒';
             $content = '标题:【'.$title.'】<br>用户:'.$user->email.'<br>内容:'.$content;
 
@@ -357,9 +353,8 @@ class UserController extends Controller
             $obj->ticket_id = $id;
             $obj->user_id = Auth::id();
             $obj->content = $content;
-            $obj->save();
 
-            if ($obj->id) {
+            if ($obj->save()) {
                 // 重新打开工单
                 $ticket->status = 0;
                 $ticket->save();
@@ -392,8 +387,7 @@ class UserController extends Controller
     {
         $id = $request->input('id');
 
-        $ret = Ticket::uid()->whereId($id)->update(['status' => 2]);
-        if ($ret) {
+        if (Ticket::uid()->whereId($id)->close()) {
             PushNotification::send('工单关闭提醒', '工单:ID'.$id.'用户已手动关闭');
 
             return Response::json(['status' => 'success', 'message' => '关闭成功']);
@@ -431,9 +425,7 @@ class UserController extends Controller
 
         $obj = new Invite();
         $obj->inviter_id = $user->id;
-        $obj->invitee_id = 0;
         $obj->code = strtoupper(mb_substr(md5(microtime().Str::random()), 8, 12));
-        $obj->status = 0;
         $obj->dateline = date('Y-m-d H:i:s', strtotime('+'.sysConfig('user_invite_days').' days'));
         $obj->save();
         if ($obj) {
@@ -484,8 +476,8 @@ class UserController extends Controller
         }
 
         $data = [
-            'name'  => $coupon->name,
-            'type'  => $coupon->type,
+            'name' => $coupon->name,
+            'type' => $coupon->type,
             'value' => $coupon->value,
         ];
 
@@ -528,7 +520,7 @@ class UserController extends Controller
         $view['sub'] = $data;
 
         //付费用户判断
-        $view['not_paying_user'] = Order::uid()->active()->where('origin_amount', '>', 0)->doesntExist();
+        $view['paying_user'] = Auth::user()->activePayingUser();
         //客户端安装
         $view['Shadowrocket_install'] = 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Shadowrocket.plist';
         $view['Quantumult_install'] = 'itms-services://?action=download-manifest&url='.sysConfig('website_url').'/clients/Quantumult.plist';
@@ -599,7 +591,7 @@ class UserController extends Controller
         ], ['coupon_sn.required' => '券码不能为空', 'coupon_sn.exists' => '该券不可用']);
 
         if ($validator->fails()) {
-            return Response::json(['status' => 'fail', 'message' => $validator->getMessageBag()->first()]);
+            return Response::json(['status' => 'fail', 'message' => $validator->errors()->all()]);
         }
 
         $coupon = Coupon::whereSn($request->input('coupon_sn'))->firstOrFail();
@@ -608,17 +600,10 @@ class UserController extends Controller
             DB::beginTransaction();
             // 写入日志
             $user = Auth::getUser();
-            Helpers::addUserCreditLog(
-                $user->id,
-                0,
-                $user->credit,
-                $user->credit + $coupon->value,
-                $coupon->value,
-                '用户手动充值 - [充值券:'.$request->input('coupon_sn').']'
-            );
+            Helpers::addUserCreditLog($user->id, null, $user->credit, $user->credit + $coupon->value, $coupon->value, '用户手动充值 - [充值券:'.$request->input('coupon_sn').']');
 
             // 余额充值
-            (new UserService($user))->updateCredit($coupon->value);
+            $user->updateCredit($coupon->value);
 
             // 更改卡券状态
             Coupon::find($coupon->id)->update(['status' => 1]);

+ 27 - 19
app/Http/Kernel.php

@@ -6,12 +6,12 @@ use App\Http\Middleware\Affiliate;
 use App\Http\Middleware\Authenticate;
 use App\Http\Middleware\CheckForMaintenanceMode;
 use App\Http\Middleware\EncryptCookies;
-use App\Http\Middleware\isAdmin;
 use App\Http\Middleware\isAdminLogin;
 use App\Http\Middleware\isForbidden;
 use App\Http\Middleware\isLogin;
 use App\Http\Middleware\isMaintenance;
 use App\Http\Middleware\isSecurity;
+use App\Http\Middleware\Permission;
 use App\Http\Middleware\RedirectIfAuthenticated;
 use App\Http\Middleware\SetLocale;
 use App\Http\Middleware\TrimStrings;
@@ -70,6 +70,18 @@ class Kernel extends HttpKernel
             SubstituteBindings::class,
         ],
 
+        'user' => [
+            isForbidden::class,
+            isMaintenance::class,
+            isLogin::class,
+        ],
+
+        'admin' => [
+            isForbidden::class,
+            isAdminLogin::class,
+            Permission::class,
+        ],
+
         'api' => [
             'throttle:60,1',
             SubstituteBindings::class,
@@ -84,24 +96,20 @@ class Kernel extends HttpKernel
      * @var array
      */
     protected $routeMiddleware = [
-        'auth'             => Authenticate::class,
-        'auth.basic'       => AuthenticateWithBasicAuth::class,
-        'bindings'         => SubstituteBindings::class,
-        'cache.headers'    => SetCacheHeaders::class,
-        'can'              => Authorize::class,
-        'guest'            => RedirectIfAuthenticated::class,
+        'auth' => Authenticate::class,
+        'auth.basic' => AuthenticateWithBasicAuth::class,
+        'bindings' => SubstituteBindings::class,
+        'cache.headers' => SetCacheHeaders::class,
+        'can' => Authorize::class,
+        'guest' => RedirectIfAuthenticated::class,
         'password.confirm' => RequirePassword::class,
-        'signed'           => ValidateSignature::class,
-        'throttle'         => ThrottleRequests::class,
-        'verified'         => EnsureEmailIsVerified::class,
-        'webApi'           => WebApi::class,
-        'isAdmin'          => isAdmin::class,
-        'isAdminLogin'     => isAdminLogin::class,
-        'isLogin'          => isLogin::class,
-        'isMaintenance'    => isMaintenance::class,
-        'isSecurity'       => isSecurity::class,
-        'isForbidden'      => isForbidden::class,
-        'affiliate'        => Affiliate::class,
-
+        'signed' => ValidateSignature::class,
+        'throttle' => ThrottleRequests::class,
+        'verified' => EnsureEmailIsVerified::class,
+        'webApi' => WebApi::class,
+        'isMaintenance' => isMaintenance::class,
+        'isSecurity' => isSecurity::class,
+        'isForbidden' => isForbidden::class,
+        'affiliate' => Affiliate::class,
     ];
 }

+ 1 - 1
app/Http/Middleware/Affiliate.php

@@ -18,7 +18,7 @@ class Affiliate
      */
     public function handle(Request $request, Closure $next)
     {
-        $aff = $request->input('aff', 0);
+        $aff = $request->input('aff');
         if ($aff) {
             Cookie::queue('register_aff', $aff, 129600);
         }

+ 0 - 1
app/Http/Middleware/Authenticate.php

@@ -11,7 +11,6 @@ class Authenticate extends Middleware
      * Get the path the user should be redirected to when they are not authenticated.
      *
      * @param  Request  $request
-     *
      * @return string|null
      */
     protected function redirectTo($request)

+ 2 - 1
app/Http/Middleware/CheckForMaintenanceMode.php

@@ -11,6 +11,7 @@ class CheckForMaintenanceMode extends Middleware
      *
      * @var array
      */
-    protected $except = [//
+    protected $except = [
+        //
     ];
 }

+ 2 - 1
app/Http/Middleware/EncryptCookies.php

@@ -11,6 +11,7 @@ class EncryptCookies extends Middleware
      *
      * @var array
      */
-    protected $except = [//
+    protected $except = [
+        //
     ];
 }

+ 31 - 0
app/Http/Middleware/Permission.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+use Spatie\Permission\Exceptions\UnauthorizedException;
+
+class Permission
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  Request  $request
+     * @param  Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next, $guard = null)
+    {
+        if (app('auth')->guard($guard)->guest()) {
+            throw UnauthorizedException::notLoggedIn();
+        }
+
+        $route = request()->route()->getName();
+        if (app('auth')->guard($guard)->user()->can($route)) {
+            return $next($request);
+        }
+
+        throw UnauthorizedException::forPermissions((array) $route);
+    }
+}

+ 2 - 3
app/Http/Middleware/RedirectIfAuthenticated.php

@@ -3,9 +3,9 @@
 namespace App\Http\Middleware;
 
 use App\Providers\RouteServiceProvider;
-use Auth;
 use Closure;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
 
 class RedirectIfAuthenticated
 {
@@ -15,10 +15,9 @@ class RedirectIfAuthenticated
      * @param  Request  $request
      * @param  Closure  $next
      * @param  string|null  $guard
-     *
      * @return mixed
      */
-    public function handle(Request $request, Closure $next, $guard = null)
+    public function handle($request, Closure $next, $guard = null)
     {
         if (Auth::guard($guard)->check()) {
             return redirect(RouteServiceProvider::HOME);

+ 0 - 28
app/Http/Middleware/isAdmin.php

@@ -1,28 +0,0 @@
-<?php
-
-namespace App\Http\Middleware;
-
-use Auth;
-use Closure;
-use Illuminate\Http\Request;
-use Redirect;
-
-class isAdmin
-{
-    /**
-     * 校验是否为管理员身份.
-     *
-     * @param  Request  $request
-     * @param  Closure  $next
-     *
-     * @return mixed
-     */
-    public function handle(Request $request, Closure $next)
-    {
-        if (! Auth::getUser()->is_admin) {
-            return Redirect::route('home');
-        }
-
-        return $next($request);
-    }
-}

+ 1 - 1
app/Http/Middleware/isMaintenance.php

@@ -20,7 +20,7 @@ class isMaintenance
         if (sysConfig('maintenance_mode')) {
             return response()->view('auth.maintenance', [
                 'message' => sysConfig('maintenance_content'),
-                'time'    => sysConfig('maintenance_time') ?: '0',
+                'time' => sysConfig('maintenance_time') ?: '0',
             ]);
         }
 

+ 4 - 4
app/Http/Requests/Admin/ArticleRequest.php

@@ -9,12 +9,12 @@ class ArticleRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'title'   => 'required',
-            'type'    => 'required|numeric',
+            'title' => 'required',
+            'type' => 'required|numeric',
             'summary' => 'nullable',
-            'logo'    => 'nullable|exclude_if:type,4|image',
+            'logo' => 'nullable|exclude_if:type,4|image',
             'content' => 'required',
-            'sort'    => 'required_if:type,1|numeric',
+            'sort' => 'required_if:type,1|numeric',
         ];
     }
 }

+ 8 - 7
app/Http/Requests/Admin/CouponRequest.php

@@ -9,14 +9,15 @@ class CouponRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'name'         => 'required',
-            'sn'           => 'unique:coupon',
-            'type'         => 'required|integer|between:1,3',
+            'name' => 'required',
+            'sn' => 'unique:coupon',
+            'logo' => 'nullable|image',
+            'type' => 'required|integer|between:1,3',
             'usable_times' => 'integer|nullable',
-            'num'          => 'required|integer|min:1',
-            'value'        => 'required|numeric|min:0',
-            'start_time'   => 'required|date|before_or_equal:end_time',
-            'end_time'     => 'required|date|after_or_equal:start_time',
+            'num' => 'required|integer|min:1',
+            'value' => 'required|numeric|min:0',
+            'start_time' => 'required|date|before_or_equal:end_time',
+            'end_time' => 'required|date|after_or_equal:start_time',
         ];
     }
 }

+ 31 - 31
app/Http/Requests/Admin/NodeRequest.php

@@ -9,38 +9,38 @@ class NodeRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'type'           => 'required|between:1,3',
-            'name'           => 'required',
-            'country_code'   => 'required',
-            'server'         => 'required_if:is_ddns,1|nullable|ends_with:'.implode(',', config('domains')),
-            'push_port'      => 'numeric|between:0,65535',
-            'traffic_rate'   => 'required|numeric|min:0',
-            'level'          => 'required|numeric|between:0,255',
-            'speed_limit'    => 'required|numeric|min:0',
-            'client_limit'   => 'required|numeric|min:0',
-            'port'           => 'nullable|numeric|between:0,65535',
-            'ip'             => 'ipv4|required_if:is_ddns,0|nullable',
-            'ipv6'           => 'nullable|ipv6',
-            'relay_server'   => 'required_if:is_relay,1',
-            'relay_port'     => 'required_if:is_relay,1|numeric|between:0,65535',
-            'method'         => 'required_if:type,1',
-            'protocol'       => 'required_if:type,1',
-            'obfs'           => 'required_if:type,1',
-            'is_subscribe'   => 'boolean',
-            'is_ddns'        => 'boolean',
-            'is_relay'       => 'boolean',
-            'is_udp'         => 'boolean',
+            'type' => 'required|between:1,3',
+            'name' => 'required',
+            'country_code' => 'required',
+            'server' => 'required_if:is_ddns,1|nullable|ends_with:'.implode(',', config('domains')),
+            'push_port' => 'numeric|between:0,65535',
+            'traffic_rate' => 'required|numeric|min:0',
+            'level' => 'required|numeric|between:0,255',
+            'speed_limit' => 'required|numeric|min:0',
+            'client_limit' => 'required|numeric|min:0',
+            'port' => 'nullable|numeric|between:0,65535',
+            'ip' => 'ipv4|required_if:is_ddns,0|nullable',
+            'ipv6' => 'nullable|ipv6',
+            'relay_server' => 'required_if:is_relay,1',
+            'relay_port' => 'required_if:is_relay,1|numeric|between:0,65535',
+            'method' => 'required_if:type,1',
+            'protocol' => 'required_if:type,1',
+            'obfs' => 'required_if:type,1',
+            'is_subscribe' => 'boolean',
+            'is_ddns' => 'boolean',
+            'is_relay' => 'boolean',
+            'is_udp' => 'boolean',
             'detection_type' => 'between:0,3',
-            'compatible'     => 'boolean',
-            'single'         => 'boolean',
-            'sort'           => 'required|numeric|between:0,255',
-            'status'         => 'boolean',
-            'v2_alter_id'    => 'required_if:type,2|numeric|between:0,65535',
-            'v2_port'        => 'required_if:type,2|numeric|between:0,65535',
-            'v2_method'      => 'required_if:type,2',
-            'v2_net'         => 'required_if:type,2',
-            'v2_type'        => 'required_if:type,2',
-            'v2_tls'         => 'boolean',
+            'compatible' => 'boolean',
+            'single' => 'boolean',
+            'sort' => 'required|numeric|between:0,255',
+            'status' => 'boolean',
+            'v2_alter_id' => 'required_if:type,2|numeric|between:0,65535',
+            'v2_port' => 'required_if:type,2|numeric|between:0,65535',
+            'v2_method' => 'required_if:type,2',
+            'v2_net' => 'required_if:type,2',
+            'v2_type' => 'required_if:type,2',
+            'v2_tls' => 'boolean',
         ];
     }
 

+ 6 - 5
app/Http/Requests/Admin/ShopStoreRequest.php

@@ -9,12 +9,13 @@ class ShopStoreRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'name'    => 'required',
+            'name' => 'required',
             'traffic' => 'required|integer|min:1|max:10240000|nullable',
-            'price'   => 'required|numeric|min:0',
-            'type'    => 'required',
-            'renew'   => 'required_unless:type,2|min:0',
-            'days'    => 'required|integer',
+            'price' => 'required|numeric|min:0',
+            'type' => 'required',
+            'renew' => 'required_unless:type,2|min:0',
+            'days' => 'required|integer',
+            'logo' => 'nullable|image',
         ];
     }
 }

+ 2 - 1
app/Http/Requests/Admin/ShopUpdateRequest.php

@@ -9,9 +9,10 @@ class ShopUpdateRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'name'  => 'required',
+            'name' => 'required',
             'price' => 'required|numeric|min:0',
             'renew' => 'required_unless:type,2|min:0',
+            'logo' => 'nullable|image',
         ];
     }
 }

+ 1 - 1
app/Http/Requests/Admin/UserStoreRequest.php

@@ -10,7 +10,7 @@ class UserStoreRequest extends FormRequest
     {
         return [
             'username' => 'required',
-            'email'    => 'required|unique:user,email,'.$this->user,
+            'email' => 'required|unique:user,email,'.$this->user,
         ];
     }
 }

+ 17 - 18
app/Http/Requests/Admin/UserUpdateRequest.php

@@ -9,25 +9,24 @@ class UserUpdateRequest extends FormRequest
     public function rules(): array
     {
         return [
-            'username'        => 'required',
-            'email'           => 'required|unique:user,email,'.$this->user,
-            'port'            => 'required|numeric|exclude_if:port,0|gt:0|unique:user,port,'.$this->user,
-            'passwd'          => 'required|string',
-            'uuid'            => 'required|uuid',
+            'username' => 'required',
+            'email' => 'required|unique:user,email,'.$this->user->id,
+            'port' => 'required|numeric|exclude_if:port,0|gt:0|unique:user,port,'.$this->user->id,
+            'passwd' => 'required|string',
+            'uuid' => 'required|uuid',
             'transfer_enable' => 'required|numeric',
-            'enable'          => 'required|boolean',
-            'method'          => 'required|string',
-            'protocol'        => 'required|string',
-            'obfs'            => 'required|string',
-            'speed_limit'     => 'required|numeric',
-            'expired_at'      => 'required|date_format:Y-m-d',
-            'remark'          => 'nullable|string',
-            'level'           => 'required|numeric',
-            'group_id'        => 'numeric',
-            'is_admin'        => 'boolean|exclude_unless:id,1|gte:1',
-            'reset_time'      => 'nullable|date_format:Y-m-d',
-            'invite_num'      => 'numeric',
-            'status'          => 'required|integer|between:-1,1',
+            'enable' => 'required|boolean',
+            'method' => 'required|string',
+            'protocol' => 'required|string',
+            'obfs' => 'required|string',
+            'speed_limit' => 'required|numeric',
+            'expired_at' => 'required|date_format:Y-m-d',
+            'remark' => 'nullable|string',
+            'level' => 'required|numeric',
+            'group_id' => 'numeric',
+            'reset_time' => 'nullable|date_format:Y-m-d',
+            'invite_num' => 'numeric',
+            'status' => 'required|integer|between:-1,1',
         ];
     }
 }

+ 1 - 1
app/Mail/closeTicket.php

@@ -28,7 +28,7 @@ class closeTicket extends Mailable implements ShouldQueue
     public function build(): closeTicket
     {
         return $this->view('emails.closeTicket')->subject('工单关闭提醒')->with([
-            'title'   => $this->title,
+            'title' => $this->title,
             'content' => $this->content,
         ]);
     }

+ 1 - 1
app/Mail/newTicket.php

@@ -28,7 +28,7 @@ class newTicket extends Mailable implements ShouldQueue
     public function build(): newTicket
     {
         return $this->view('emails.newTicket')->subject('新工单提醒')->with([
-            'title'   => $this->title,
+            'title' => $this->title,
             'content' => $this->content,
         ]);
     }

+ 1 - 1
app/Mail/replyTicket.php

@@ -27,7 +27,7 @@ class replyTicket extends Mailable implements ShouldQueue
     public function build(): replyTicket
     {
         return $this->view('emails.replyTicket')->subject('工单回复提醒')->with([
-            'title'   => $this->title,
+            'title' => $this->title,
             'content' => $this->content,
         ]);
     }

+ 7 - 0
app/Models/Ticket.php

@@ -28,6 +28,13 @@ class Ticket extends Model
         return $this->BelongsTo(User::class);
     }
 
+    public function close(): bool
+    {
+        $this->status = 2;
+
+        return $this->save();
+    }
+
     public function getStatusLabelAttribute(): string
     {
         switch ($this->attributes['status']) {

+ 85 - 7
app/Models/User.php

@@ -9,27 +9,33 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
+use Spatie\Permission\Traits\HasRoles;
 
 /**
  * 用户信息.
  */
 class User extends Authenticatable
 {
-    use Notifiable;
+    use Notifiable, HasRoles;
 
     protected $table = 'user';
-    protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d'];
+    protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d'];
     protected $dates = ['expired_at', 'reset_time'];
     protected $guarded = ['id'];
 
-    public function onlineIpLogs(): HasMany
+    public function usedTrafficPercentage()
     {
-        return $this->hasMany(NodeOnlineUserIp::class);
+        return round(($this->usedTraffic()) / $this->transfer_enable, 2);
     }
 
-    public function orders(): HasMany
+    public function usedTraffic(): int
     {
-        return $this->hasMany(Order::class);
+        return $this->d + $this->u;
+    }
+
+    public function onlineIpLogs(): HasMany
+    {
+        return $this->hasMany(NodeOnlineUserIp::class);
     }
 
     public function payments(): HasMany
@@ -102,6 +108,11 @@ class User extends Authenticatable
         return $this->hasOne(UserSubscribe::class);
     }
 
+    public function subUrl()
+    {
+        return route('sub', $this->subscribe->code);
+    }
+
     public function subscribeLogs(): HasManyThrough
     {
         return $this->hasManyThrough(UserSubscribeLog::class, UserSubscribe::class);
@@ -199,6 +210,73 @@ class User extends Authenticatable
 
     public function scopeUserAccessNodes()
     {
-        return Node::userAllowNodes($this->attributes['group_id'], $this->attributes['level']);
+        return Node::userAllowNodes($this->attributes['group_id'] ?? 0, $this->attributes['level'] ?? 0);
+    }
+
+    public function getIsAvailableAttribute(): bool
+    {
+        return ! $this->ban_time && $this->transfer_enable && $this->expired_at > time();
+    }
+
+    public function updateCredit(float $credit): bool
+    {
+        $this->credit += $credit;
+
+        return $this->credit >= 0 && $this->save();
+    }
+
+    public function incrementData(int $data): bool
+    {// 添加用户流量
+        $this->transfer_enable += $data;
+
+        return $this->save();
+    }
+
+    public function isNotCompleteOrderByUserId(int $userId): bool
+    { // 添加用户余额
+
+        return Order::uid($userId)->whereIn('status', [0, 1])->exists();
+    }
+
+    public function trafficFetch(int $u, int $d): bool
+    {
+        $this->u += $u;
+        $this->d += $d;
+
+        return $this->save();
+    }
+
+    public function expired_status(): int
+    {
+        $expired_status = 2; // 大于一个月过期
+        if ($this->expired_at < date('Y-m-d')) {
+            $expired_status = -1; // 已过期
+        } elseif ($this->expired_at === date('Y-m-d')) {
+            $expired_status = 0; // 今天过期
+        } elseif ($this->expired_at > date('Y-m-d') && $this->expired_at <= date('Y-m-d', strtotime('+30 days'))) {
+            $expired_status = 1; // 最近一个月过期
+        }
+
+        return $expired_status;
+    }
+
+    public function isTrafficWarning(): bool
+    {// 流量异常警告
+        return $this->recentTrafficUsed() >= (sysConfig('traffic_ban_value') * GB);
+    }
+
+    public function recentTrafficUsed()
+    {
+        return UserHourlyDataFlow::userRecentUsed($this->id)->sum('total');
+    }
+
+    public function activePayingUser()
+    { //付费用户判断
+        return $this->orders()->active()->where('origin_amount', '>', 0)->exists();
+    }
+
+    public function orders(): HasMany
+    {
+        return $this->hasMany(Order::class);
     }
 }

+ 1 - 1
app/Models/UserDailyDataFlow.php

@@ -26,6 +26,6 @@ class UserDailyDataFlow extends Model
     // 用户每天使用总流量
     public function scopeUserDaily($query, $uid)
     {
-        return $query->whereUserId($uid)->whereNodeId(0);
+        return $query->whereUserId($uid)->whereNodeId(null);
     }
 }

+ 2 - 2
app/Models/UserHourlyDataFlow.php

@@ -26,7 +26,7 @@ class UserHourlyDataFlow extends Model
     // 用户每时使用总流量
     public function scopeUserHourly($query, $uid)
     {
-        return $query->whereUserId($uid)->whereNodeId(0);
+        return $query->whereUserId($uid)->whereNodeId(null);
     }
 
     public function scopeUserRecentUsed($query, $uid)
@@ -37,7 +37,7 @@ class UserHourlyDataFlow extends Model
     // 1小时内流量异常用户
     public function trafficAbnormal(): array
     {
-        $userTotalTrafficList = self::whereNodeId(0)
+        $userTotalTrafficList = self::whereNodeId(null)
             ->where('total', '>', MB * 50)
             ->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))
             ->groupBy('user_id')

+ 0 - 11
app/Observers/NodeObserver.php

@@ -83,17 +83,6 @@ class NodeObserver
 
     public function deleted(Node $node): void
     {
-        // 删除分组关联、节点标签、节点相关日志
-        $node->labels()->delete();
-        $node->heartBeats()->delete();
-        $node->onlineLogs()->delete();
-        $node->pingLogs()->delete();
-        $node->dailyDataFlows()->delete();
-        $node->hourlyDataFlows()->delete();
-        $node->rules()->delete();
-        $node->ruleGroup()->delete();
-        $node->auth()->delete();
-
         // 断开审计规则分组节点联系
         foreach (RuleGroup::all() as $ruleGroup) {
             $nodes = $ruleGroup->nodes;

+ 3 - 43
app/Observers/UserObserver.php

@@ -6,13 +6,9 @@ use App\Components\Helpers;
 use App\Jobs\VNet\addUser;
 use App\Jobs\VNet\delUser;
 use App\Jobs\VNet\editUser;
-use App\Models\Node;
 use App\Models\User;
 use App\Models\UserSubscribe;
 use Arr;
-use DB;
-use Exception;
-use Log;
 
 class UserObserver
 {
@@ -23,7 +19,7 @@ class UserObserver
         $subscribe->code = Helpers::makeSubscribeCode();
         $subscribe->save();
 
-        $allowNodes = Node::userAllowNodes($user->group_id, $user->level)->whereType(4)->pluck('id');
+        $allowNodes = $user->userAccessNodes()->whereType(4)->pluck('id');
         if ($allowNodes) {
             addUser::dispatch($user->id, $allowNodes);
         }
@@ -32,51 +28,15 @@ class UserObserver
     public function updated(User $user): void
     {
         $changes = $user->getChanges();
-        $allowNodes = Node::userAllowNodes($user->group_id, $user->level)->whereType(4)->get();
+        $allowNodes = $user->userAccessNodes()->whereType(4)->get();
         if ($allowNodes->isNotEmpty() && Arr::hasAny($changes, ['level', 'group_id', 'port', 'passwd', 'speed_limit', 'enable'])) {
             editUser::dispatch($user, $allowNodes);
         }
     }
 
-    public function deleting(User $user): void
-    {
-        try {
-            DB::beginTransaction();
-            // 邀请关系脱钩
-            $user->invites()->delete();
-            $user->invitees()->update(['inviter_id' => 0]);
-            $user->commissionSettlements()->delete();
-            $user->commissionLogs()->delete();
-
-            $user->subscribe()->delete();
-            $user->subscribeLogs()->delete();
-
-            // 清理日志
-            $user->orders()->delete();
-            $user->payments()->delete();
-            $user->onlineIpLogs()->delete();
-            $user->ruleLogs()->delete();
-            $user->tickets()->delete();
-            $user->ticketReplies()->delete();
-            $user->banedLogs()->delete();
-            $user->creditLogs()->delete();
-            $user->dailyDataFlows()->delete();
-            $user->dataFlowLogs()->delete();
-            $user->dataModifyLogs()->delete();
-            $user->hourlyDataFlows()->delete();
-            $user->loginLogs()->delete();
-            $user->verify()->delete();
-
-            DB::commit();
-        } catch (Exception $e) {
-            Log::error('删除用户相关信息错误:'.$e->getMessage());
-            DB::rollBack();
-        }
-    }
-
     public function deleted(User $user): void
     {
-        $allowNodes = Node::userAllowNodes($user->group_id, $user->level)->whereType(4)->get();
+        $allowNodes = $user->userAccessNodes()->whereType(4)->get();
         if ($allowNodes->isNotEmpty()) {
             delUser::dispatch($user->id, $allowNodes);
         }

+ 5 - 1
app/Providers/AuthServiceProvider.php

@@ -2,6 +2,7 @@
 
 namespace App\Providers;
 
+use Gate;
 use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
 
 class AuthServiceProvider extends ServiceProvider
@@ -23,6 +24,9 @@ class AuthServiceProvider extends ServiceProvider
     public function boot()
     {
         $this->registerPolicies();
-        //
+
+        Gate::before(function ($user) {
+            return $user->hasRole('Super Admin') ? true : null;
+        });
     }
 }

+ 18 - 1
app/Providers/RouteServiceProvider.php

@@ -44,7 +44,10 @@ class RouteServiceProvider extends ServiceProvider
         $this->mapApiRoutes();
 
         $this->mapWebRoutes();
-        //
+
+        $this->mapUserRoutes();
+
+        $this->mapAdminRoutes();
     }
 
     /**
@@ -75,4 +78,18 @@ class RouteServiceProvider extends ServiceProvider
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
     }
+
+    protected function mapUserRoutes()
+    {
+        Route::middleware(['web', 'user'])
+            ->namespace($this->namespace)
+            ->group(base_path('routes/user.php'));
+    }
+
+    protected function mapAdminRoutes()
+    {
+        Route::middleware(['web', 'admin'])
+            ->namespace($this->namespace)
+            ->group(base_path('routes/admin.php'));
+    }
 }

+ 1 - 1
app/Providers/TelescopeServiceProvider.php

@@ -63,7 +63,7 @@ class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
     protected function gate()
     {
         Gate::define('viewTelescope', function ($user) {
-            return $user->is_admin;
+            return $user->hasRole('Super Admin');
         });
     }
 }

+ 7 - 16
app/Services/OrderService.php

@@ -63,17 +63,10 @@ class OrderService
     private function chargeCredit(): bool
     {
         $credit = self::$user->credit;
-        $ret = (new UserService(self::$user))->updateCredit(self::$order->origin_amount);
+        $ret = self::$user->updateCredit(self::$order->origin_amount);
         // 余额变动记录日志
         if ($ret) {
-            Helpers::addUserCreditLog(
-                self::$order->user_id,
-                self::$order->id,
-                $credit,
-                self::$user->credit,
-                self::$order->amount,
-                '用户通过'.self::$order->pay_way.'充值余额'
-            );
+            Helpers::addUserCreditLog(self::$order->user_id, self::$order->id, $credit, self::$user->credit, self::$order->amount, '用户通过'.self::$order->pay_way.'充值余额');
         }
 
         return $ret;
@@ -82,8 +75,7 @@ class OrderService
     // 激活流量包
     private function activatePackage(): bool
     {
-        $ret = (new UserService(self::$user))->incrementData(self::$goods->traffic * MB);
-        if ($ret) {
+        if (self::$user->incrementData(self::$goods->traffic * MB)) {
             return Helpers::addUserTrafficModifyLog(
                 self::$order->user_id,
                 self::$order->id,
@@ -112,8 +104,8 @@ class OrderService
         $oldData = self::$user->transfer_enable;
         $updateData = [
             'invite_num' => self::$user->invite_num + (self::$goods->invite_num ?: 0),
-            'level'      => self::$goods->level,
-            'enable'     => 1,
+            'level' => self::$goods->level,
+            'enable' => 1,
         ];
 
         // 无端口用户 添加端口
@@ -157,7 +149,7 @@ class OrderService
 
         return array_merge($data, [
             'transfer_enable' => self::$goods->traffic * MB,
-            'reset_time'      => $nextResetTime,
+            'reset_time' => $nextResetTime,
         ]);
     }
 
@@ -209,7 +201,6 @@ class OrderService
         $log->order_id = $oid;
         $log->amount = $amount;
         $log->commission = $commission;
-        $log->status = 0;
 
         return $log->save();
     }
@@ -219,7 +210,7 @@ class OrderService
     {
         self::$order->update([
             'expired_at' => date('Y-m-d H:i:s', strtotime('+'.self::$goods->days.' days')),
-            'status'     => 2,
+            'status' => 2,
         ]);
 
         return $this->activatePlan();

+ 0 - 51
app/Services/UserService.php

@@ -1,51 +0,0 @@
-<?php
-
-namespace App\Services;
-
-use App\Models\Order;
-use App\Models\User;
-use Auth;
-
-class UserService
-{
-    private static $user;
-
-    public function __construct(User $user = null)
-    {
-        self::$user = $user ?: Auth::getUser();
-    }
-
-    public function isAvailable(): bool
-    {
-        return ! self::$user->ban_time && self::$user->transfer_enable && self::$user->expired_at > time();
-    }
-
-    // 添加用户余额
-    public function updateCredit(float $credit): bool
-    {
-        self::$user->credit += $credit;
-
-        return self::$user->credit >= 0 && self::$user->save();
-    }
-
-    // 添加用户流量
-    public function incrementData(int $data): bool
-    {
-        self::$user->transfer_enable += $data;
-
-        return self::$user->save();
-    }
-
-    public function isNotCompleteOrderByUserId(int $userId): bool
-    {
-        return Order::uid($userId)->whereIn('status', [0, 1])->exists();
-    }
-
-    public function trafficFetch(int $u, int $d): bool
-    {
-        self::$user->u += $u;
-        self::$user->d += $d;
-
-        return self::$user->save();
-    }
-}

+ 10 - 8
composer.json

@@ -8,26 +8,28 @@
   ],
   "license": "MIT",
   "require": {
-    "php": "^7.2.5",
+    "php": "^7.2.5|^8.0",
     "ext-json": "*",
     "ext-mbstring": "*",
     "ext-openssl": "*",
     "ext-simplexml": "*",
-    "fideloper/proxy": "^4.2",
+    "doctrine/dbal": "^2.12",
+    "fideloper/proxy": "^4.4",
     "fruitcake/laravel-cors": "^2.0",
     "geoip2/geoip2": "^2.10",
-    "guzzlehttp/guzzle": "^6.3",
+    "guzzlehttp/guzzle": "^6.3.1|^7.0.1",
     "ip2location/ip2location-laravel": "^1.2",
     "ipip/db": "^1.0",
     "jenssegers/agent": "^2.6",
-    "laravel/framework": "^7.24",
-    "laravel/tinker": "^2.0",
+    "laravel/framework": "^7.29",
+    "laravel/tinker": "^2.5",
     "mews/captcha": "^3.1",
     "mews/purifier": "^3.3",
     "overtrue/laravel-lang": "^4.0",
     "phpoffice/phpspreadsheet": "^1.14",
     "rap2hpoutre/laravel-log-viewer": "^1.6",
     "riverslei/payment": "^5.1",
+    "spatie/laravel-permission": "^3.17",
     "srmklive/paypal": "^1.7",
     "stripe/stripe-php": "^7.61",
     "xhat/payjs": "^1.4",
@@ -42,11 +44,11 @@
     "barryvdh/laravel-debugbar": "^3.4",
     "barryvdh/laravel-ide-helper": "^2.8",
     "facade/ignition": "^2.0",
-    "fzaninotto/faker": "^1.9.1",
+    "fakerphp/faker": "^1.9.1",
     "laravel/telescope": "^3.5",
     "mockery/mockery": "^1.3.1",
-    "nunomaduro/collision": "^4.1",
-    "phpunit/phpunit": "^8.5"
+    "nunomaduro/collision": "^4.3",
+    "phpunit/phpunit": "^8.5.8|^9.3.3"
   },
   "config": {
     "optimize-autoloader": true,

File diff suppressed because it is too large
+ 530 - 131
composer.lock


+ 3 - 3
config/HCaptcha.php

@@ -1,10 +1,10 @@
 <?php
 
 return [
-    'secret'            => env('HCAPTCHA_SECRET'),
-    'sitekey'           => env('HCAPTCHA_SITEKEY'),
+    'secret' => env('HCAPTCHA_SECRET'),
+    'sitekey' => env('HCAPTCHA_SITEKEY'),
     'server-get-config' => true,
-    'options'           => [
+    'options' => [
         'timeout' => 30,
     ],
 ];

+ 3 - 3
config/NoCaptcha.php

@@ -1,10 +1,10 @@
 <?php
 
 return [
-    'secret'            => env('NOCAPTCHA_SECRET'),
-    'sitekey'           => env('NOCAPTCHA_SITEKEY'),
+    'secret' => env('NOCAPTCHA_SECRET'),
+    'sitekey' => env('NOCAPTCHA_SITEKEY'),
     'server-get-config' => true,
-    'options'           => [
+    'options' => [
         'timeout' => 30,
     ],
 ];

+ 37 - 37
config/app.php

@@ -40,7 +40,7 @@ return [
     */
 
     'debug' => (bool) env('APP_DEBUG', false),
-    'demo'  => (bool) env('APP_DEMO', false),
+    'demo' => (bool) env('APP_DEMO', false),
 
     /*
     |--------------------------------------------------------------------------
@@ -191,43 +191,43 @@ return [
 
     'aliases' => [
 
-        'App'          => Illuminate\Support\Facades\App::class,
-        'Arr'          => Illuminate\Support\Arr::class,
-        'Artisan'      => Illuminate\Support\Facades\Artisan::class,
-        'Auth'         => Illuminate\Support\Facades\Auth::class,
-        'Blade'        => Illuminate\Support\Facades\Blade::class,
-        'Broadcast'    => Illuminate\Support\Facades\Broadcast::class,
-        'Bus'          => Illuminate\Support\Facades\Bus::class,
-        'Cache'        => Illuminate\Support\Facades\Cache::class,
-        'Config'       => Illuminate\Support\Facades\Config::class,
-        'Cookie'       => Illuminate\Support\Facades\Cookie::class,
-        'Crypt'        => Illuminate\Support\Facades\Crypt::class,
-        'DB'           => Illuminate\Support\Facades\DB::class,
-        'Eloquent'     => Illuminate\Database\Eloquent\Model::class,
-        'Event'        => Illuminate\Support\Facades\Event::class,
-        'File'         => Illuminate\Support\Facades\File::class,
-        'Gate'         => Illuminate\Support\Facades\Gate::class,
-        'Hash'         => Illuminate\Support\Facades\Hash::class,
-        'Http'         => Illuminate\Support\Facades\Http::class,
-        'Lang'         => Illuminate\Support\Facades\Lang::class,
-        'Log'          => Illuminate\Support\Facades\Log::class,
-        'Mail'         => Illuminate\Support\Facades\Mail::class,
+        'App' => Illuminate\Support\Facades\App::class,
+        'Arr' => Illuminate\Support\Arr::class,
+        'Artisan' => Illuminate\Support\Facades\Artisan::class,
+        'Auth' => Illuminate\Support\Facades\Auth::class,
+        'Blade' => Illuminate\Support\Facades\Blade::class,
+        'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
+        'Bus' => Illuminate\Support\Facades\Bus::class,
+        'Cache' => Illuminate\Support\Facades\Cache::class,
+        'Config' => Illuminate\Support\Facades\Config::class,
+        'Cookie' => Illuminate\Support\Facades\Cookie::class,
+        'Crypt' => Illuminate\Support\Facades\Crypt::class,
+        'DB' => Illuminate\Support\Facades\DB::class,
+        'Eloquent' => Illuminate\Database\Eloquent\Model::class,
+        'Event' => Illuminate\Support\Facades\Event::class,
+        'File' => Illuminate\Support\Facades\File::class,
+        'Gate' => Illuminate\Support\Facades\Gate::class,
+        'Hash' => Illuminate\Support\Facades\Hash::class,
+        'Http' => Illuminate\Support\Facades\Http::class,
+        'Lang' => Illuminate\Support\Facades\Lang::class,
+        'Log' => Illuminate\Support\Facades\Log::class,
+        'Mail' => Illuminate\Support\Facades\Mail::class,
         'Notification' => Illuminate\Support\Facades\Notification::class,
-        'Password'     => Illuminate\Support\Facades\Password::class,
-        'Queue'        => Illuminate\Support\Facades\Queue::class,
-        'Redirect'     => Illuminate\Support\Facades\Redirect::class,
-        'Redis'        => Illuminate\Support\Facades\Redis::class,
-        'Request'      => Illuminate\Support\Facades\Request::class,
-        'Response'     => Illuminate\Support\Facades\Response::class,
-        'Route'        => Illuminate\Support\Facades\Route::class,
-        'Schema'       => Illuminate\Support\Facades\Schema::class,
-        'Session'      => Illuminate\Support\Facades\Session::class,
-        'Storage'      => Illuminate\Support\Facades\Storage::class,
-        'Str'          => Illuminate\Support\Str::class,
-        'URL'          => Illuminate\Support\Facades\URL::class,
-        'Validator'    => Illuminate\Support\Facades\Validator::class,
-        'View'         => Illuminate\Support\Facades\View::class,
-        'Helpers'      => App\Components\Helpers::class,
+        'Password' => Illuminate\Support\Facades\Password::class,
+        'Queue' => Illuminate\Support\Facades\Queue::class,
+        'Redirect' => Illuminate\Support\Facades\Redirect::class,
+        'Redis' => Illuminate\Support\Facades\Redis::class,
+        'Request' => Illuminate\Support\Facades\Request::class,
+        'Response' => Illuminate\Support\Facades\Response::class,
+        'Route' => Illuminate\Support\Facades\Route::class,
+        'Schema' => Illuminate\Support\Facades\Schema::class,
+        'Session' => Illuminate\Support\Facades\Session::class,
+        'Storage' => Illuminate\Support\Facades\Storage::class,
+        'Str' => Illuminate\Support\Str::class,
+        'URL' => Illuminate\Support\Facades\URL::class,
+        'Validator' => Illuminate\Support\Facades\Validator::class,
+        'View' => Illuminate\Support\Facades\View::class,
+        'Helpers' => App\Components\Helpers::class,
 
     ],
 

+ 7 - 7
config/auth.php

@@ -14,7 +14,7 @@ return [
     */
 
     'defaults' => [
-        'guard'     => 'web',
+        'guard' => 'web',
         'passwords' => 'users',
     ],
 
@@ -37,14 +37,14 @@ return [
 
     'guards' => [
         'web' => [
-            'driver'   => 'session',
+            'driver' => 'session',
             'provider' => 'users',
         ],
 
         'api' => [
-            'driver'   => 'token',
+            'driver' => 'token',
             'provider' => 'users',
-            'hash'     => false,
+            'hash' => false,
         ],
     ],
 
@@ -68,7 +68,7 @@ return [
     'providers' => [
         'users' => [
             'driver' => 'eloquent',
-            'model'  => App\Models\User::class,
+            'model' => App\Models\User::class,
         ],
 
         // 'users' => [
@@ -95,8 +95,8 @@ return [
     'passwords' => [
         'users' => [
             'provider' => 'users',
-            'table'    => 'password_resets',
-            'expire'   => 60,
+            'table' => 'password_resets',
+            'expire' => 60,
             'throttle' => 60,
         ],
     ],

+ 6 - 6
config/broadcasting.php

@@ -31,18 +31,18 @@ return [
     'connections' => [
 
         'pusher' => [
-            'driver'  => 'pusher',
-            'key'     => env('PUSHER_APP_KEY'),
-            'secret'  => env('PUSHER_APP_SECRET'),
-            'app_id'  => env('PUSHER_APP_ID'),
+            'driver' => 'pusher',
+            'key' => env('PUSHER_APP_KEY'),
+            'secret' => env('PUSHER_APP_SECRET'),
+            'app_id' => env('PUSHER_APP_ID'),
             'options' => [
                 'cluster' => env('PUSHER_APP_CLUSTER'),
-                'useTLS'  => true,
+                'useTLS' => true,
             ],
         ],
 
         'redis' => [
-            'driver'     => 'redis',
+            'driver' => 'redis',
             'connection' => 'default',
         ],
 

+ 16 - 16
config/cache.php

@@ -38,51 +38,51 @@ return [
         ],
 
         'array' => [
-            'driver'    => 'array',
+            'driver' => 'array',
             'serialize' => false,
         ],
 
         'database' => [
-            'driver'     => 'database',
-            'table'      => 'cache',
+            'driver' => 'database',
+            'table' => 'cache',
             'connection' => null,
         ],
 
         'file' => [
             'driver' => 'file',
-            'path'   => storage_path('framework/cache/data'),
+            'path' => storage_path('framework/cache/data'),
         ],
 
         'memcached' => [
-            'driver'        => 'memcached',
+            'driver' => 'memcached',
             'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
-            'sasl'          => [
+            'sasl' => [
                 env('MEMCACHED_USERNAME'),
                 env('MEMCACHED_PASSWORD'),
             ],
-            'options'       => [
+            'options' => [
                 // Memcached::OPT_CONNECT_TIMEOUT => 2000,
             ],
-            'servers'       => [
+            'servers' => [
                 [
-                    'host'   => env('MEMCACHED_HOST', '127.0.0.1'),
-                    'port'   => env('MEMCACHED_PORT', 11211),
+                    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
+                    'port' => env('MEMCACHED_PORT', 11211),
                     'weight' => 100,
                 ],
             ],
         ],
 
         'redis' => [
-            'driver'     => 'redis',
+            'driver' => 'redis',
             'connection' => 'cache',
         ],
 
         'dynamodb' => [
-            'driver'   => 'dynamodb',
-            'key'      => env('AWS_ACCESS_KEY_ID'),
-            'secret'   => env('AWS_SECRET_ACCESS_KEY'),
-            'region'   => env('AWS_DEFAULT_REGION', 'us-east-1'),
-            'table'    => env('DYNAMODB_CACHE_TABLE', 'cache'),
+            'driver' => 'dynamodb',
+            'key' => env('AWS_ACCESS_KEY_ID'),
+            'secret' => env('AWS_SECRET_ACCESS_KEY'),
+            'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
+            'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
             'endpoint' => env('DYNAMODB_ENDPOINT'),
         ],
 

+ 31 - 31
config/captcha.php

@@ -6,48 +6,48 @@ return [
         'u', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'M', 'N', 'P', 'Q', 'R', 'T', 'U', 'X', 'Y',
         'Z',
     ],
-    'default'    => [
-        'length'  => 4,
-        'width'   => 120,
-        'height'  => 36,
+    'default' => [
+        'length' => 4,
+        'width' => 120,
+        'height' => 36,
         'quality' => 90,
-        'math'    => false,
-        'expire'  => 60,
+        'math' => false,
+        'expire' => 60,
     ],
-    'math'       => [
-        'length'  => 9,
-        'width'   => 120,
-        'height'  => 36,
+    'math' => [
+        'length' => 9,
+        'width' => 120,
+        'height' => 36,
         'quality' => 90,
-        'math'    => true,
+        'math' => true,
     ],
 
-    'flat'    => [
-        'length'     => 6,
-        'width'      => 160,
-        'height'     => 46,
-        'quality'    => 90,
-        'lines'      => 6,
-        'bgImage'    => false,
-        'bgColor'    => '#ecf2f4',
+    'flat' => [
+        'length' => 6,
+        'width' => 160,
+        'height' => 46,
+        'quality' => 90,
+        'lines' => 6,
+        'bgImage' => false,
+        'bgColor' => '#ecf2f4',
         'fontColors' => ['#2c3e50', '#c0392b', '#16a085', '#c0392b', '#8e44ad', '#303f9f', '#f57c00', '#795548'],
-        'contrast'   => -5,
+        'contrast' => -5,
     ],
-    'mini'    => [
+    'mini' => [
         'length' => 3,
-        'width'  => 60,
+        'width' => 60,
         'height' => 32,
     ],
     'inverse' => [
-        'length'    => 5,
-        'width'     => 120,
-        'height'    => 36,
-        'quality'   => 90,
+        'length' => 5,
+        'width' => 120,
+        'height' => 36,
+        'quality' => 90,
         'sensitive' => true,
-        'angle'     => 12,
-        'sharpen'   => 10,
-        'blur'      => 2,
-        'invert'    => true,
-        'contrast'  => -5,
+        'angle' => 12,
+        'sharpen' => 10,
+        'blur' => 2,
+        'invert' => true,
+        'contrast' => -5,
     ],
 ];

+ 49 - 49
config/database.php

@@ -36,58 +36,58 @@ return [
     'connections' => [
 
         'sqlite' => [
-            'driver'                  => 'sqlite',
-            'url'                     => env('DATABASE_URL'),
-            'database'                => env('DB_DATABASE', database_path('database.sqlite')),
-            'prefix'                  => '',
+            'driver' => 'sqlite',
+            'url' => env('DATABASE_URL'),
+            'database' => env('DB_DATABASE', database_path('database.sqlite')),
+            'prefix' => '',
             'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
         ],
 
         'mysql' => [
-            'driver'         => 'mysql',
-            'url'            => env('DATABASE_URL'),
-            'host'           => env('DB_HOST', '127.0.0.1'),
-            'port'           => env('DB_PORT', '3306'),
-            'database'       => env('DB_DATABASE', 'forge'),
-            'username'       => env('DB_USERNAME', 'forge'),
-            'password'       => env('DB_PASSWORD', ''),
-            'unix_socket'    => env('DB_SOCKET', ''),
-            'charset'        => 'utf8mb4',
-            'collation'      => 'utf8mb4_unicode_ci',
-            'prefix'         => '',
+            'driver' => 'mysql',
+            'url' => env('DATABASE_URL'),
+            'host' => env('DB_HOST', '127.0.0.1'),
+            'port' => env('DB_PORT', '3306'),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'unix_socket' => env('DB_SOCKET', ''),
+            'charset' => 'utf8mb4',
+            'collation' => 'utf8mb4_unicode_ci',
+            'prefix' => '',
             'prefix_indexes' => true,
-            'strict'         => env('DB_STRICT', true),
-            'engine'         => null,
-            'options'        => extension_loaded('pdo_mysql') ? array_filter([
+            'strict' => env('DB_STRICT', true),
+            'engine' => null,
+            'options' => extension_loaded('pdo_mysql') ? array_filter([
                 PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
             ]) : [],
         ],
 
         'pgsql' => [
-            'driver'         => 'pgsql',
-            'url'            => env('DATABASE_URL'),
-            'host'           => env('DB_HOST', '127.0.0.1'),
-            'port'           => env('DB_PORT', '5432'),
-            'database'       => env('DB_DATABASE', 'forge'),
-            'username'       => env('DB_USERNAME', 'forge'),
-            'password'       => env('DB_PASSWORD', ''),
-            'charset'        => 'utf8',
-            'prefix'         => '',
+            'driver' => 'pgsql',
+            'url' => env('DATABASE_URL'),
+            'host' => env('DB_HOST', '127.0.0.1'),
+            'port' => env('DB_PORT', '5432'),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'charset' => 'utf8',
+            'prefix' => '',
             'prefix_indexes' => true,
-            'schema'         => 'public',
-            'sslmode'        => 'prefer',
+            'schema' => 'public',
+            'sslmode' => 'prefer',
         ],
 
         'sqlsrv' => [
-            'driver'         => 'sqlsrv',
-            'url'            => env('DATABASE_URL'),
-            'host'           => env('DB_HOST', 'localhost'),
-            'port'           => env('DB_PORT', '1433'),
-            'database'       => env('DB_DATABASE', 'forge'),
-            'username'       => env('DB_USERNAME', 'forge'),
-            'password'       => env('DB_PASSWORD', ''),
-            'charset'        => 'utf8',
-            'prefix'         => '',
+            'driver' => 'sqlsrv',
+            'url' => env('DATABASE_URL'),
+            'host' => env('DB_HOST', 'localhost'),
+            'port' => env('DB_PORT', '1433'),
+            'database' => env('DB_DATABASE', 'forge'),
+            'username' => env('DB_USERNAME', 'forge'),
+            'password' => env('DB_PASSWORD', ''),
+            'charset' => 'utf8',
+            'prefix' => '',
             'prefix_indexes' => true,
         ],
 
@@ -123,31 +123,31 @@ return [
 
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),
-            'prefix'  => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
+            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
         ],
 
         'default' => [
-            'url'      => env('REDIS_URL'),
-            'host'     => env('REDIS_HOST', '127.0.0.1'),
+            'url' => env('REDIS_URL'),
+            'host' => env('REDIS_HOST', '127.0.0.1'),
             'password' => env('REDIS_PASSWORD', null),
-            'port'     => env('REDIS_PORT', '6379'),
+            'port' => env('REDIS_PORT', '6379'),
             'database' => env('REDIS_DB', '0'),
         ],
 
         'cache' => [
-            'url'      => env('REDIS_URL'),
-            'host'     => env('REDIS_HOST', '127.0.0.1'),
+            'url' => env('REDIS_URL'),
+            'host' => env('REDIS_HOST', '127.0.0.1'),
             'password' => env('REDIS_PASSWORD', null),
-            'port'     => env('REDIS_PORT', '6379'),
+            'port' => env('REDIS_PORT', '6379'),
             'database' => env('REDIS_CACHE_DB', '1'),
         ],
 
         'session' => [
-            'url'      => env('REDIS_URL'),
-            'host'     => env('REDIS_HOST', '127.0.0.1'),
+            'url' => env('REDIS_URL'),
+            'host' => env('REDIS_HOST', '127.0.0.1'),
             'password' => env('REDIS_PASSWORD', null),
-            'port'     => env('REDIS_PORT', 6379),
-            'database' => env('REDIS_SESSION_DB', 2),
+            'port' => env('REDIS_PORT', 6379),
+            'database' => env('REDIS_SESSION_DB', '2'),
         ],
 
     ],

+ 11 - 11
config/filesystems.php

@@ -13,7 +13,7 @@ return [
     |
     */
 
-    'default' => env('FILESYSTEM_DRIVER', 'public'),
+    'default' => env('FILESYSTEM_DRIVER', 'local'),
 
     /*
     |--------------------------------------------------------------------------
@@ -45,23 +45,23 @@ return [
 
         'local' => [
             'driver' => 'local',
-            'root'   => storage_path('app'),
+            'root' => storage_path('app'),
         ],
 
         'public' => [
-            'driver'     => 'local',
-            'root'       => storage_path('app/public'),
-            'url'        => env('APP_URL').'/storage',
+            'driver' => 'local',
+            'root' => storage_path('app/public'),
+            'url' => env('APP_URL').'/storage',
             'visibility' => 'public',
         ],
 
         's3' => [
-            'driver'   => 's3',
-            'key'      => env('AWS_ACCESS_KEY_ID'),
-            'secret'   => env('AWS_SECRET_ACCESS_KEY'),
-            'region'   => env('AWS_DEFAULT_REGION'),
-            'bucket'   => env('AWS_BUCKET'),
-            'url'      => env('AWS_URL'),
+            'driver' => 's3',
+            'key' => env('AWS_ACCESS_KEY_ID'),
+            'secret' => env('AWS_SECRET_ACCESS_KEY'),
+            'region' => env('AWS_DEFAULT_REGION'),
+            'bucket' => env('AWS_BUCKET'),
+            'url' => env('AWS_URL'),
             'endpoint' => env('AWS_ENDPOINT'),
         ],
 

+ 6 - 6
config/geetest.php

@@ -1,13 +1,13 @@
 <?php
 
 return [
-    'lang'              => 'zh-cn',
+    'lang' => 'zh-cn',
     'server-get-config' => true,
-    'id'                => env('GEETEST_ID'),
-    'key'               => env('GEETEST_KEY'),
-    'url'               => '/geetest',
-    'protocol'          => 'http',
-    'product'           => 'float',
+    'id' => env('GEETEST_ID'),
+    'key' => env('GEETEST_KEY'),
+    'url' => '/geetest',
+    'protocol' => 'http',
+    'product' => 'float',
     'client_fail_alert' => '请正确完成验证码操作',
     'server_fail_alert' => '验证码校验失败',
 ];

+ 2 - 2
config/hashing.php

@@ -44,9 +44,9 @@ return [
     */
 
     'argon' => [
-        'memory'  => 1024,
+        'memory' => 1024,
         'threads' => 2,
-        'time'    => 2,
+        'time' => 2,
     ],
 
 ];

+ 7 - 7
config/ide-helper.php

@@ -11,8 +11,8 @@ return [
     |
     */
 
-    'filename'      => '_ide_helper',
-    'format'        => 'php',
+    'filename' => '_ide_helper',
+    'format' => 'php',
 
     /*
     |--------------------------------------------------------------------------
@@ -146,7 +146,7 @@ return [
             'Illuminate\Database\Eloquent\Builder',
             'Illuminate\Database\Query\Builder',
         ],
-        'Session'  => ['Illuminate\Session\Store'],
+        'Session' => ['Illuminate\Session\Store'],
     ],
 
     'magic' => [],
@@ -161,7 +161,7 @@ return [
     |
     */
 
-    'interfaces'                  => [
+    'interfaces' => [
 
     ],
 
@@ -191,7 +191,7 @@ return [
     |  ),
     |
     */
-    'custom_db_types'             => [
+    'custom_db_types' => [
         'mysql' => [
             'bit' => 'boolean',
         ],
@@ -231,7 +231,7 @@ return [
     | Cast the given "real type" to the given "type".
     |
     */
-    'type_overrides'              => [
+    'type_overrides' => [
         'integer' => 'int',
         'boolean' => 'bool',
     ],
@@ -245,6 +245,6 @@ return [
     | magic methods and properties.
     |
     */
-    'include_class_docblocks'     => false,
+    'include_class_docblocks' => false,
 
 ];

+ 1 - 1
config/lang-publisher.php

@@ -59,5 +59,5 @@ return [
      *
      * By default, Caseable::NO_CASE
      */
-    'case'   => interface_exists(Caseable::class) ? Caseable::NO_CASE : 0,
+    'case' => interface_exists(Caseable::class) ? Caseable::NO_CASE : 0,
 ];

+ 20 - 20
config/logging.php

@@ -36,36 +36,36 @@ return [
 
     'channels' => [
         'stack' => [
-            'driver'            => 'stack',
-            'channels'          => ['daily'],
+            'driver' => 'stack',
+            'channels' => ['daily'],
             'ignore_exceptions' => false,
         ],
 
         'single' => [
             'driver' => 'single',
-            'path'   => storage_path('logs/laravel.log'),
-            'level'  => 'debug',
+            'path' => storage_path('logs/laravel.log'),
+            'level' => 'debug',
         ],
 
         'daily' => [
             'driver' => 'daily',
-            'path'   => storage_path('logs/laravel.log'),
-            'level'  => 'debug',
-            'days'   => 14,
+            'path' => storage_path('logs/laravel.log'),
+            'level' => 'debug',
+            'days' => 14,
         ],
 
         'slack' => [
-            'driver'   => 'slack',
-            'url'      => env('LOG_SLACK_WEBHOOK_URL'),
+            'driver' => 'slack',
+            'url' => env('LOG_SLACK_WEBHOOK_URL'),
             'username' => 'Laravel Log',
-            'emoji'    => ':boom:',
-            'level'    => 'critical',
+            'emoji' => ':boom:',
+            'level' => 'critical',
         ],
 
         'papertrail' => [
-            'driver'       => 'monolog',
-            'level'        => 'debug',
-            'handler'      => SyslogUdpHandler::class,
+            'driver' => 'monolog',
+            'level' => 'debug',
+            'handler' => SyslogUdpHandler::class,
             'handler_with' => [
                 'host' => env('PAPERTRAIL_URL'),
                 'port' => env('PAPERTRAIL_PORT'),
@@ -73,26 +73,26 @@ return [
         ],
 
         'stderr' => [
-            'driver'    => 'monolog',
-            'handler'   => StreamHandler::class,
+            'driver' => 'monolog',
+            'handler' => StreamHandler::class,
             'formatter' => env('LOG_STDERR_FORMATTER'),
-            'with'      => [
+            'with' => [
                 'stream' => 'php://stderr',
             ],
         ],
 
         'syslog' => [
             'driver' => 'syslog',
-            'level'  => 'debug',
+            'level' => 'debug',
         ],
 
         'errorlog' => [
             'driver' => 'errorlog',
-            'level'  => 'debug',
+            'level' => 'debug',
         ],
 
         'null' => [
-            'driver'  => 'monolog',
+            'driver' => 'monolog',
             'handler' => NullHandler::class,
         ],
 

+ 10 - 10
config/mail.php

@@ -35,14 +35,14 @@ return [
 
     'mailers' => [
         'smtp' => [
-            'transport'  => 'smtp',
-            'host'       => env('MAIL_HOST', 'smtp.mailgun.org'),
-            'port'       => env('MAIL_PORT', 587),
+            'transport' => 'smtp',
+            'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
+            'port' => env('MAIL_PORT', 587),
             'encryption' => env('MAIL_ENCRYPTION', 'tls'),
-            'username'   => env('MAIL_USERNAME'),
-            'password'   => env('MAIL_PASSWORD'),
-            'timeout'    => null,
-            'auth_mode'  => null,
+            'username' => env('MAIL_USERNAME'),
+            'password' => env('MAIL_PASSWORD'),
+            'timeout' => null,
+            'auth_mode' => null,
         ],
 
         'ses' => [
@@ -59,12 +59,12 @@ return [
 
         'sendmail' => [
             'transport' => 'sendmail',
-            'path'      => '/usr/sbin/sendmail -bs',
+            'path' => '/usr/sbin/sendmail -bs',
         ],
 
         'log' => [
             'transport' => 'log',
-            'channel'   => env('MAIL_LOG_CHANNEL'),
+            'channel' => env('MAIL_LOG_CHANNEL'),
         ],
 
         'array' => [
@@ -85,7 +85,7 @@ return [
 
     'from' => [
         'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
-        'name'    => env('MAIL_FROM_NAME', 'Example'),
+        'name' => env('MAIL_FROM_NAME', 'Example'),
     ],
 
     /*

+ 143 - 0
config/permission.php

@@ -0,0 +1,143 @@
+<?php
+
+return [
+
+    'models' => [
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your permissions. Of course, it
+         * is often just the "Permission" model but you may use whatever you like.
+         *
+         * The model you want to use as a Permission model needs to implement the
+         * `Spatie\Permission\Contracts\Permission` contract.
+         */
+
+        'permission' => Spatie\Permission\Models\Permission::class,
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * Eloquent model should be used to retrieve your roles. Of course, it
+         * is often just the "Role" model but you may use whatever you like.
+         *
+         * The model you want to use as a Role model needs to implement the
+         * `Spatie\Permission\Contracts\Role` contract.
+         */
+
+        'role' => Spatie\Permission\Models\Role::class,
+
+    ],
+
+    'table_names' => [
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'roles' => 'roles',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your permissions. We have chosen a basic
+         * default value but you may easily change it to any table you like.
+         */
+
+        'permissions' => 'permissions',
+
+        /*
+         * When using the "HasPermissions" trait from this package, we need to know which
+         * table should be used to retrieve your models permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_permissions' => 'model_has_permissions',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your models roles. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'model_has_roles' => 'model_has_roles',
+
+        /*
+         * When using the "HasRoles" trait from this package, we need to know which
+         * table should be used to retrieve your roles permissions. We have chosen a
+         * basic default value but you may easily change it to any table you like.
+         */
+
+        'role_has_permissions' => 'role_has_permissions',
+    ],
+
+    'column_names' => [
+
+        /*
+         * Change this if you want to name the related model primary key other than
+         * `model_id`.
+         *
+         * For example, this would be nice if your primary keys are all UUIDs. In
+         * that case, name this `model_uuid`.
+         */
+
+        'model_morph_key' => 'model_id',
+    ],
+
+    /*
+     * When set to true, the required permission names are added to the exception
+     * message. This could be considered an information leak in some contexts, so
+     * the default setting is false here for optimum safety.
+     */
+
+    'display_permission_in_exception' => false,
+
+    /*
+     * When set to true, the required role names are added to the exception
+     * message. This could be considered an information leak in some contexts, so
+     * the default setting is false here for optimum safety.
+     */
+
+    'display_role_in_exception' => false,
+
+    /*
+     * By default wildcard permission lookups are disabled.
+     */
+
+    'enable_wildcard_permission' => true,
+
+    'cache' => [
+
+        /*
+         * By default all permissions are cached for 24 hours to speed up performance.
+         * When permissions or roles are updated the cache is flushed automatically.
+         */
+
+        'expiration_time' => DateInterval::createFromDateString('24 hours'),
+
+        /*
+         * The cache key used to store all permissions.
+         */
+
+        'key' => 'spatie.permission.cache',
+
+        /*
+         * When checking for a permission against a model by passing a Permission
+         * instance to the check, this key determines what attribute on the
+         * Permissions model is used to cache against.
+         *
+         * Ideally, this should match your preferred way of checking permissions, eg:
+         * `$user->can('view-posts')` would be 'name'.
+         */
+
+        'model_key' => 'name',
+
+        /*
+         * You may optionally indicate a specific cache driver to use for permission and
+         * role caching using any of the `store` drivers listed in the cache.php config
+         * file. Using 'default' here means to use the `default` set in cache.php.
+         */
+
+        'store' => 'default',
+    ],
+];

Some files were not shown because too many files changed in this diff