Browse Source

1.加入serverchan
2.批量生成账号
3.多国语言包

zhangjiangbin 8 years ago
parent
commit
1a6f494145
60 changed files with 1140 additions and 628 deletions
  1. 2 1
      .gitignore
  2. 38 38
      _ide_helper.php
  3. 38 0
      app/Components/ServerChan.php
  4. 29 5
      app/Console/Commands/AutoCheckNodeStatusJob.php
  5. 2 2
      app/Console/Commands/UserExpireWarningJob.php
  6. 2 2
      app/Console/Commands/UserTrafficWarningJob.php
  7. 1 1
      app/Console/Kernel.php
  8. 51 11
      app/Http/Controllers/AdminController.php
  9. 2 11
      app/Http/Controllers/Controller.php
  10. 5 1
      app/Http/Controllers/LoginController.php
  11. 51 0
      app/Http/Controllers/PaymentController.php
  12. 2 7
      app/Http/Controllers/RegisterController.php
  13. 18 9
      app/Http/Controllers/UserController.php
  14. 3 1
      composer.json
  15. 143 1
      composer.lock
  16. BIN
      composer.phar
  17. 5 2
      config/app.php
  18. 1 1
      config/session.php
  19. 5 0
      config/version.php
  20. 12 41
      readme.md
  21. 7 0
      resources/lang/en/404.php
  22. 10 0
      resources/lang/en/active.php
  23. 0 19
      resources/lang/en/auth.php
  24. 108 0
      resources/lang/en/home.php
  25. 13 0
      resources/lang/en/login.php
  26. 0 19
      resources/lang/en/pagination.php
  27. 0 22
      resources/lang/en/passwords.php
  28. 18 0
      resources/lang/en/register.php
  29. 0 121
      resources/lang/en/validation.php
  30. 7 0
      resources/lang/zh-CN/404.php
  31. 10 0
      resources/lang/zh-CN/active.php
  32. 107 0
      resources/lang/zh-CN/home.php
  33. 13 0
      resources/lang/zh-CN/login.php
  34. 18 0
      resources/lang/zh-CN/register.php
  35. 4 4
      resources/views/404.blade.php
  36. 1 1
      resources/views/admin/articleList.blade.php
  37. 1 1
      resources/views/admin/articleLogList.blade.php
  38. 1 1
      resources/views/admin/inviteList.blade.php
  39. 189 105
      resources/views/admin/system.blade.php
  40. 17 1
      resources/views/admin/userList.blade.php
  41. 13 13
      resources/views/login.blade.php
  42. 19 19
      resources/views/register.blade.php
  43. 3 3
      resources/views/user/active.blade.php
  44. 6 6
      resources/views/user/activeUser.blade.php
  45. 11 25
      resources/views/user/addOrder.blade.php
  46. 1 1
      resources/views/user/article.blade.php
  47. 15 15
      resources/views/user/goodsList.blade.php
  48. 13 13
      resources/views/user/index.blade.php
  49. 16 16
      resources/views/user/invite.blade.php
  50. 7 7
      resources/views/user/layouts.blade.php
  51. 25 14
      resources/views/user/orderList.blade.php
  52. 10 5
      resources/views/user/profile.blade.php
  53. 22 18
      resources/views/user/referral.blade.php
  54. 1 1
      resources/views/user/replyTicket.blade.php
  55. 10 17
      resources/views/user/subscribe.blade.php
  56. 18 21
      resources/views/user/ticketList.blade.php
  57. 6 6
      resources/views/user/trafficLog.blade.php
  58. 5 0
      routes/web.php
  59. 2 0
      sql/db.sql
  60. 3 0
      sql/update/20171210.sql

+ 2 - 1
.gitignore

@@ -4,8 +4,9 @@
 /vendor
 /.idea
 /.vagrant
-/.env
+/.env.example
 Homestead.json
 Homestead.yaml
 npm-debug.log
 .DS_Store
+.phpstorm.meta.php

+ 38 - 38
_ide_helper.php

@@ -1,7 +1,7 @@
 <?php
 /**
  * A helper file for Laravel 5, to provide autocomplete information to your IDE
- * Generated for Laravel 5.4.30 on 2017-11-08.
+ * Generated for Laravel 5.4.30 on 2017-12-08.
  *
  * @author Barry vd. Heuvel <[email protected]>
  * @see https://github.com/barryvdh/laravel-ide-helper
@@ -1898,35 +1898,35 @@ namespace Illuminate\Support\Facades {
         /**
          * Determine if the current user is authenticated.
          *
-         * @return bool 
+         * @return \App\User 
+         * @throws \Illuminate\Auth\AuthenticationException
          * @static 
          */ 
-        public static function check()
+        public static function authenticate()
         {
-            return \Illuminate\Auth\SessionGuard::check();
+            return \Illuminate\Auth\SessionGuard::authenticate();
         }
         
         /**
-         * Determine if the current user is a guest.
+         * Determine if the current user is authenticated.
          *
          * @return bool 
          * @static 
          */ 
-        public static function guest()
+        public static function check()
         {
-            return \Illuminate\Auth\SessionGuard::guest();
+            return \Illuminate\Auth\SessionGuard::check();
         }
         
         /**
-         * Determine if the current user is authenticated.
+         * Determine if the current user is a guest.
          *
-         * @return \App\User 
-         * @throws \Illuminate\Auth\AuthenticationException
+         * @return bool 
          * @static 
          */ 
-        public static function authenticate()
+        public static function guest()
         {
-            return \Illuminate\Auth\SessionGuard::authenticate();
+            return \Illuminate\Auth\SessionGuard::guest();
         }
         
         /**
@@ -11153,32 +11153,6 @@ namespace Illuminate\Support\Facades {
             return \Illuminate\View\Factory::getShared();
         }
         
-        /**
-         * Register a view composer event.
-         *
-         * @param array|string $views
-         * @param \Closure|string $callback
-         * @return array 
-         * @static 
-         */ 
-        public static function composer($views, $callback)
-        {
-            return \Illuminate\View\Factory::composer($views, $callback);
-        }
-        
-        /**
-         * Register a view creator event.
-         *
-         * @param array|string $views
-         * @param \Closure|string $callback
-         * @return array 
-         * @static 
-         */ 
-        public static function creator($views, $callback)
-        {
-            return \Illuminate\View\Factory::creator($views, $callback);
-        }
-        
         /**
          * Start a component rendering process.
          *
@@ -11227,6 +11201,19 @@ namespace Illuminate\Support\Facades {
             \Illuminate\View\Factory::endSlot();
         }
         
+        /**
+         * Register a view creator event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function creator($views, $callback)
+        {
+            return \Illuminate\View\Factory::creator($views, $callback);
+        }
+        
         /**
          * Register multiple view composers via an array.
          *
@@ -11239,6 +11226,19 @@ namespace Illuminate\Support\Facades {
             return \Illuminate\View\Factory::composers($composers);
         }
         
+        /**
+         * Register a view composer event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function composer($views, $callback)
+        {
+            return \Illuminate\View\Factory::composer($views, $callback);
+        }
+        
         /**
          * Call the composer for a given view.
          *

+ 38 - 0
app/Components/ServerChan.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Components;
+
+use GuzzleHttp\Client;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\Exception\RequestException;
+use Log;
+
+class ServerChan
+{
+    /**
+     * @param string $title 消息标题
+     * @param string $content 消息内容
+     * @param string $key ServerChan上申请的SCKEY
+     * @return string
+     */
+    public function send($title, $content, $key)
+    {
+        $client = new Client();
+
+        try {
+            $response = $client->request('GET', 'https://sc.ftqq.com/' . $key . '.send', [
+                'query' => [
+                    'text' => $title,
+                    'desp' => $content
+                ]
+            ]);
+
+            return json_decode($response->getBody());
+        } catch (RequestException $e) {
+            Log::error(Psr7\str($e->getRequest()));
+            if ($e->hasResponse()) {
+                Log::error(Psr7\str($e->getResponse()));
+            }
+        }
+    }
+}

+ 29 - 5
app/Console/Commands/AutoCheckNodeStatusJob.php

@@ -2,12 +2,14 @@
 
 namespace App\Console\Commands;
 
+use App\Components\ServerChan;
 use Illuminate\Console\Command;
 use App\Http\Models\Config;
 use App\Http\Models\SsNode;
 use App\Http\Models\SsNodeInfo;
 use App\Http\Models\EmailLog;
 use App\Mail\nodeCrashWarning;
+use Cache;
 use Mail;
 use Log;
 
@@ -15,7 +17,7 @@ class AutoCheckNodeStatusJob extends Command
 {
     protected $signature = 'command:autoCheckNodeStatusJob';
     protected $description = '自动监测节点是否宕机';
-
+    protected $cacheKey = 'node_shutdown_warning_';
     protected static $config;
 
     public function __construct()
@@ -38,8 +40,13 @@ class AutoCheckNodeStatusJob extends Command
             // 10分钟内无节点信息则认为是宕机,因为每个节点的负载信息最多保存10分钟
             $node_info = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
             if (empty($node_info) || empty($node_info->load)) {
+                // 15分钟内已发警告,则不再发
+                if (Cache::has($this->cacheKey . $node->id)) {
+                    continue;
+                }
+
                 $title = "节点宕机警告";
-                $content = "系统监测到节点【$node->name】($node->server)可能宕机了,请及时检查。";
+                $content = "系统监测到节点【{$node->name}】({$node->server})可能宕机了,请及时检查。";
 
                 // 发邮件通知管理员
                 if (self::$config['is_node_crash_warning'] && self::$config['crash_warning_email']) {
@@ -49,6 +56,23 @@ class AutoCheckNodeStatusJob extends Command
                     } catch (\Exception $e) {
                         $this->sendEmailLog(1, $title, $content, 0, $e->getMessage());
                     }
+
+                    // 写入发信缓存,防止短时间内大量发信
+                    Cache::put($this->cacheKey . $node->id, $node->name . '(' . $node->server . ')', 15);
+                }
+
+                // 通过ServerChan发微信消息提醒管理员
+                if (self::$config['is_server_chan'] && self::$config['server_chan_key']) {
+                    $serverChan = new ServerChan();
+                    $result = $serverChan->send($title, $content, self::$config['server_chan_key']);
+                    if ($result->errno > 0) {
+                        $this->sendEmailLog(1, '[ServerChan]' . $title, $content);
+                    } else {
+                        $this->sendEmailLog(1, '[ServerChan]' . $title, $content, 0, $result->errmsg);
+                    }
+
+                    // 写入发信缓存,防止短时间内大量发信
+                    Cache::put($this->cacheKey . $node->id, $node->name . '(' . $node->server . ')', 15);
                 }
             }
         }
@@ -58,9 +82,9 @@ class AutoCheckNodeStatusJob extends Command
 
     /**
      * 写入邮件发送日志
-     * @param int $user_id 用户ID
-     * @param string $title 投递类型(投递标题
-     * @param string $content 投递内容(简要概述)
+     * @param int $user_id 接收者用户ID
+     * @param string $title 标题
+     * @param string $content 内容
      * @param int $status 投递状态
      * @param string $error 投递失败时记录的异常信息
      */

+ 2 - 2
app/Console/Commands/UserExpireWarningJob.php

@@ -61,8 +61,8 @@ class UserExpireWarningJob extends Command
     /**
      * 写入邮件发送日志
      * @param int $user_id 用户ID
-     * @param string $title 投递类型(投递标题
-     * @param string $content 投递内容(简要概述)
+     * @param string $title 标题
+     * @param string $content 内容
      * @param int $status 投递状态
      * @param string $error 投递失败时记录的异常信息
      */

+ 2 - 2
app/Console/Commands/UserTrafficWarningJob.php

@@ -61,8 +61,8 @@ class UserTrafficWarningJob extends Command
     /**
      * 写入邮件发送日志
      * @param int $user_id 用户ID
-     * @param string $title 投递类型(投递标题
-     * @param string $content 投递内容(简要概述)
+     * @param string $title 标题
+     * @param string $content 内容
      * @param int $status 投递状态
      * @param string $error 投递失败时记录的异常信息
      */

+ 1 - 1
app/Console/Kernel.php

@@ -40,7 +40,7 @@ class Kernel extends ConsoleKernel
     protected function schedule(Schedule $schedule)
     {
         $schedule->command('command:autoBanUserJob')->everyTenMinutes();
-        $schedule->command('command:autoCheckNodeStatusJob')->everyThirtyMinutes();
+        $schedule->command('command:autoCheckNodeStatusJob')->everyMinute();
         $schedule->command('command:autoClearLogJob')->everyThirtyMinutes();
         $schedule->command('command:autoDecGoodsTrafficJob')->everyTenMinutes();
         $schedule->command('command:autoDisableExpireUserJob')->everyMinute();

+ 51 - 11
app/Http/Controllers/AdminController.php

@@ -213,10 +213,44 @@ class AdminController extends Controller
         }
     }
 
+    // 批量生成账号
+    public function batchAddUsers(Request $request)
+    {
+        \DB::beginTransaction();
+        try {
+            for ($i = 0; $i < 5; $i++) {
+                // 生成一个可用端口
+                $last_user = User::query()->orderBy('id', 'desc')->first();
+                $port = self::$config['is_rand_port'] ? $this->getRandPort() : $last_user->port + 1;
+
+                $user = new User();
+                $user->username = '批量生成-' . $this->makeRandStr(6);
+                $user->password = md5($this->makeRandStr());
+                $user->enable = 0;
+                $user->port = $port;
+                $user->passwd = $this->makeRandStr();
+                $user->transfer_enable = $this->toGB(1000);
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+365 days"));
+                $user->reg_ip = $request->getClientIp();
+                $user->status = -1;
+                $user->save();
+            }
+
+            \DB::commit();
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '批量生成账号成功']);
+        } catch (\Exception $e) {
+            \DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '批量生成账号失败:' . $e->getMessage()]);
+        }
+    }
+
     // 编辑账号
     public function editUser(Request $request)
     {
         $id = $request->get('id');
+
         if ($request->method() == 'POST') {
             $username = $request->get('username');
             $password = $request->get('password');
@@ -283,7 +317,7 @@ class AdminController extends Controller
             }
         } else {
             $user = User::query()->where('id', $id)->first();
-            if (!empty($user)) {
+            if ($user) {
                 $user->transfer_enable = $this->flowToGB($user->transfer_enable);
                 $user->balance = $user->balance / 100;
             }
@@ -304,6 +338,7 @@ class AdminController extends Controller
     public function delUser(Request $request)
     {
         $id = $request->get('id');
+
         if ($id == 1) {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '系统管理员不可删除']);
         }
@@ -406,7 +441,6 @@ class AdminController extends Controller
 
             return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
         } else {
-            // 加密方式、协议、混淆、等级、分组、国家地区
             $view['method_list'] = $this->methodList();
             $view['protocol_list'] = $this->protocolList();
             $view['obfs_list'] = $this->obfsList();
@@ -422,6 +456,7 @@ class AdminController extends Controller
     public function editNode(Request $request)
     {
         $id = $request->get('id');
+
         if ($request->method() == 'POST') {
             $name = $request->get('name');
             $group_id = $request->get('group_id');
@@ -494,8 +529,6 @@ class AdminController extends Controller
             }
         } else {
             $view['node'] = SsNode::query()->where('id', $id)->first();
-
-            // 加密方式、协议、混淆、等级、分组、国家地区
             $view['method_list'] = $this->methodList();
             $view['protocol_list'] = $this->protocolList();
             $view['obfs_list'] = $this->obfsList();
@@ -513,7 +546,7 @@ class AdminController extends Controller
         $id = $request->get('id');
 
         $node = SsNode::query()->where('id', $id)->first();
-        if (empty($node)) {
+        if (!$node) {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '节点不存在,请重试']);
         }
 
@@ -534,7 +567,7 @@ class AdminController extends Controller
         $node_id = $request->get('id');
 
         $node = SsNode::query()->where('id', $node_id)->orderBy('sort', 'desc')->first();
-        if (empty($node)) {
+        if (!$node) {
             $request->session()->flash('errorMsg', '节点不存在,请重试');
 
             return Redirect::back();
@@ -617,6 +650,7 @@ class AdminController extends Controller
     public function editArticle(Request $request)
     {
         $id = $request->get('id');
+
         if ($request->method() == 'POST') {
             $title = $request->get('title');
             $type = $request->get('type');
@@ -649,6 +683,7 @@ class AdminController extends Controller
     public function delArticle(Request $request)
     {
         $id = $request->get('id');
+
         $user = Article::query()->where('id', $id)->update(['is_del' => 1]);
         if ($user) {
             return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
@@ -661,8 +696,8 @@ class AdminController extends Controller
     public function groupList(Request $request)
     {
         $view['groupList'] = SsGroup::query()->paginate(10)->appends($request->except('page'));
-        $level_list = $this->levelList();
 
+        $level_list = $this->levelList();
         $level_dict = array();
         foreach ($level_list as $level) {
             $level_dict[$level['level']] = $level['level_name'];
@@ -696,6 +731,7 @@ class AdminController extends Controller
     public function editGroup(Request $request)
     {
         $id = $request->get('id');
+
         if ($request->method() == 'POST') {
             $name = $request->get('name');
             $level = $request->get('level');
@@ -898,7 +934,6 @@ class AdminController extends Controller
     public function import(Request $request)
     {
         if ($request->method() == 'POST') {
-
             if (!$request->hasFile('uploadFile')) {
                 $request->session()->flash('errorMsg', '请选择要上传的文件');
 
@@ -991,6 +1026,7 @@ class AdminController extends Controller
     public function export(Request $request)
     {
         $id = $request->get('id');
+
         if (empty($id)) {
             return Redirect::to('admin/userList');
         }
@@ -1055,7 +1091,6 @@ class AdminController extends Controller
         if ($request->method() == 'POST') {
             $old_password = $request->get('old_password');
             $new_password = $request->get('new_password');
-
             $old_password = md5(trim($old_password));
             $new_password = md5(trim($new_password));
 
@@ -1089,6 +1124,7 @@ class AdminController extends Controller
     public function userMonitor(Request $request)
     {
         $id = $request->get('id');
+
         if (empty($id)) {
             return Redirect::to('admin/userList');
         }
@@ -1184,6 +1220,7 @@ class AdminController extends Controller
     public function delConfig(Request $request)
     {
         $id = $request->get('id');
+
         $config = SsConfig::query()->where('id', $id)->delete();
         if ($config) {
             return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
@@ -1196,6 +1233,7 @@ class AdminController extends Controller
     public function setDefaultConfig(Request $request)
     {
         $id = $request->get('id');
+
         if (empty($id)) {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '非法请求']);
         }
@@ -1487,7 +1525,7 @@ class AdminController extends Controller
         $name = trim($request->get('name'));
         $value = trim($request->get('value'));
 
-        if ($name == '' || $value == '') {
+        if ($name == '') {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => '设置失败:请求参数异常']);
         }
 
@@ -1615,6 +1653,7 @@ class AdminController extends Controller
                 $q->where('username', 'like', '%' . $username . '%');
             });
         }
+
         if ($status) {
             $query->where('status', $status);
         }
@@ -1743,7 +1782,7 @@ class AdminController extends Controller
         }
 
         $list = $query->paginate(10);
-        if (!empty($list)) {
+        if (!$list->isEmpty()) {
             foreach ($list as &$vo) {
                 $vo->before = $vo->before / 100;
                 $vo->after = $vo->after / 100;
@@ -1760,6 +1799,7 @@ class AdminController extends Controller
     public function switchToUser(Request $request)
     {
         $id = $request->get('user_id');
+
         $user = User::query()->find($id);
         if (!$user) {
             return Response::json(['status' => 'fail', 'data' => '', 'message' => "用户不存在"]);

+ 2 - 11
app/Http/Controllers/Controller.php

@@ -206,20 +206,11 @@ class Controller extends BaseController
         return round($bytes, $precision) . ' ' . $units[$pow];
     }
 
-    // 禁止注册的邮箱后缀
-    public function forbidDomain()
-    {
-        return [
-            'gov.cn',
-            'edu.cn'
-        ];
-    }
-
     /**
      * 写入邮件发送日志
      * @param int $user_id 用户ID
-     * @param string $title 投递类型(投递标题
-     * @param string $content 投递内容(简要概述)
+     * @param string $title 标题
+     * @param string $content 内容
      * @param int $status 投递状态
      * @param string $error 投递失败时记录的异常信息
      */

+ 5 - 1
app/Http/Controllers/LoginController.php

@@ -89,8 +89,10 @@ class LoginController extends Controller
                         $obj->created_at = date('Y-m-d H:i:s');
                         $obj->save();
 
-                        $ttl = !empty(self::$config['login_add_score_range']) ? self::$config['login_add_score_range'] : 1440;
+                        // 登录多久后再登录可以获取积分
+                        $ttl = self::$config['login_add_score_range'] ? self::$config['login_add_score_range'] : 1440;
                         Cache::put('loginAddScore_' . md5($username), '1', $ttl);
+
                         $request->session()->flash('successMsg', '欢迎回来,系统自动赠送您 ' . $score . ' 积分,您可以用它兑换流量包');
                     }
                 }
@@ -112,6 +114,7 @@ class LoginController extends Controller
                 $u = User::query()->where("remember_token", $request->cookie("remember"))->first();
                 if ($u) {
                     $request->session()->put('user', $u->toArray());
+
                     if ($u->is_admin) {
                         return Redirect::to('admin');
                     }
@@ -119,6 +122,7 @@ class LoginController extends Controller
                     return Redirect::to('user');
                 }
             }
+
             $view['is_captcha'] = self::$config['is_captcha'];
             $view['is_register'] = self::$config['is_register'];
 

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

@@ -0,0 +1,51 @@
+<?php
+namespace App\Http\Controllers;
+
+use Illuminate\Http\Request;
+use PayPal\Auth\OAuthTokenCredential;
+use PayPal\Rest\ApiContext;
+use Response;
+use Redirect;
+use Captcha;
+use Cache;
+use PayPal\Api;
+use Paypal\Rest;
+use Paypal\Auth;
+
+class PaymentController extends Controller
+{
+    function __construct()
+    {
+        //
+    }
+
+    public function create(Request $request)
+    {
+        $apiContext = new ApiContext(
+            new OAuthTokenCredential(
+                'AYSq3RDGsmBLJE-otTkBtM-jBRd1TCQwFf9RGfwddNXWz0uFU9ztymylOhRS',     // ClientID
+                'EGnHDxD_qRPdaLdZz8iCr8N7_MzF-YHPTkjs6NKYQvQSBngp4PTTVWkPZRbL'      // ClientSecret
+            )
+        );
+
+        $payer = new Api\Payer();
+        $payer->setPaymentMethod('paypal');
+
+        $amount = new \PayPal\Api\Amount();
+        $amount->setTotal('1.00');
+        $amount->setCurrency('USD');
+
+        $transaction = new \PayPal\Api\Transaction();
+        $transaction->setAmount($amount);
+
+        $redirectUrls = new \PayPal\Api\RedirectUrls();
+        $redirectUrls->setReturnUrl("https://example.com/your_redirect_url.html")
+            ->setCancelUrl("https://example.com/your_cancel_url.html");
+
+        $payment = new \PayPal\Api\Payment();
+        $payment->setIntent('sale')
+            ->setPayer($payer)
+            ->setTransactions(array($transaction))
+            ->setRedirectUrls($redirectUrls);
+    }
+}

+ 2 - 7
app/Http/Controllers/RegisterController.php

@@ -21,12 +21,10 @@ use Mail;
 class RegisterController extends Controller
 {
     protected static $config;
-    protected static $forbidDomain;
 
     function __construct()
     {
         self::$config = $this->systemConfig();
-        self::$forbidDomain = $this->forbidDomain();
     }
 
     // 注册页
@@ -41,7 +39,7 @@ class RegisterController extends Controller
             $register_token = $request->get('register_token');
             $aff = intval($request->get('aff', 0));
 
-            // 防重复提交
+            // 防重复提交
             $session_register_token = $request->session()->get('register_token');
             if (empty($register_token) || $register_token != $session_register_token) {
                 $request->session()->flash('errorMsg', '请勿重复请求,刷新一下页面再试试');
@@ -72,9 +70,6 @@ class RegisterController extends Controller
 
                 return Redirect::back()->withInput();
             }
-//            else if (in_array(substr($username, strpos($username, '@') + 1), self::$forbidDomain)) {
-//                return Redirect::back()->withInput($request->except(['username']));
-//            }
 
             // 是否校验验证码
             if (self::$config['is_captcha']) {
@@ -87,7 +82,7 @@ class RegisterController extends Controller
 
             // 是否开启注册
             if (!self::$config['is_register']) {
-                $request->session()->flash('errorMsg', '系统维护暂停注册,如需账号请联系管理员');
+                $request->session()->flash('errorMsg', '系统维护暂停注册');
 
                 return Redirect::back();
             }

+ 18 - 9
app/Http/Controllers/UserController.php

@@ -12,6 +12,7 @@ use App\Http\Models\Order;
 use App\Http\Models\OrderGoods;
 use App\Http\Models\ReferralApply;
 use App\Http\Models\ReferralLog;
+use App\Http\Models\SsConfig;
 use App\Http\Models\Ticket;
 use App\Http\Models\TicketReply;
 use App\Http\Models\User;
@@ -45,6 +46,7 @@ class UserController extends Controller
     public function index(Request $request)
     {
         $user = $request->session()->get('user');
+
         $user = User::query()->where('id', $user['id'])->first();
         $user->totalTransfer = $this->flowAutoShow($user->transfer_enable);
         $user->usedTransfer = $this->flowAutoShow($user->u + $user->d);
@@ -138,14 +140,15 @@ class UserController extends Controller
         if ($request->method() == 'POST') {
             $old_password = $request->get('old_password');
             $new_password = $request->get('new_password');
-            $port = trim($request->get('port'));
+            $wechat = $request->get('wechat');
+            $qq = $request->get('qq');
             $passwd = trim($request->get('passwd'));
             $method = $request->get('method');
             $protocol = $request->get('protocol');
             $obfs = $request->get('obfs');
 
             // 修改密码
-            if (!empty($old_password) && !empty($new_password)) {
+            if ($old_password && $new_password) {
                 $old_password = md5(trim($old_password));
                 $new_password = md5(trim($new_password));
 
@@ -173,24 +176,29 @@ class UserController extends Controller
             }
 
             // 修改SS信息
-            if (empty($port)) {
-                $request->session()->flash('errorMsg', '端口不能为空');
+            if (empty($passwd)) {
+                $request->session()->flash('errorMsg', '密码不能为空');
 
-                return Redirect::to('user/profile#tab_2');
+                return Redirect::to('user/profile#tab_3');
             }
 
-            if (empty($passwd)) {
-                $request->session()->flash('errorMsg', '密码不能为空');
+            // 加密方式、协议、混淆必须存在
+            $existMethod = SsConfig::query()->where('type', 1)->where('name', $method)->first();
+            $existProtocol = SsConfig::query()->where('type', 2)->where('name', $protocol)->first();
+            $existObfs = SsConfig::query()->where('type', 3)->where('name', $obfs)->first();
+            if (!$existMethod || !$existProtocol || !$existObfs) {
+                $request->session()->flash('errorMsg', '非法请求');
 
                 return Redirect::to('user/profile#tab_2');
             }
 
             $data = [
-                //'port' => $port,
                 'passwd'   => $passwd,
                 'method'   => $method,
                 'protocol' => $protocol,
-                'obfs'     => $obfs
+                'obfs'     => $obfs,
+                'wechat'   => $wechat,
+                'qq'       => $qq
             ];
 
             $ret = User::query()->where('id', $user['id'])->update($data);
@@ -353,6 +361,7 @@ class UserController extends Controller
     public function closeTicket(Request $request)
     {
         $id = $request->get('id');
+
         $user = $request->session()->get('user');
 
         $ret = Ticket::query()->where('id', $id)->where('user_id', $user['id'])->update(['status' => 2]);

+ 3 - 1
composer.json

@@ -12,7 +12,9 @@
         "laravel/framework": "5.4.*",
         "laravel/tinker": "~1.0",
         "maatwebsite/excel": "~2.1.0",
-        "mews/captcha": "^2.1"
+        "mews/captcha": "^2.1",
+        "overtrue/laravel-lang": "~3.0",
+        "paypal/rest-api-sdk-php": "*"
     },
     "require-dev": {
         "fzaninotto/faker": "~1.4",

+ 143 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "c97b303f7da9900573b399a99d970257",
+    "content-hash": "8a222250e9934b48f8d14593fa292b50",
     "packages": [
         {
             "name": "barryvdh/laravel-ide-helper",
@@ -128,6 +128,48 @@
             ],
             "time": "2016-06-13T19:28:20+00:00"
         },
+        {
+            "name": "caouecs/laravel-lang",
+            "version": "3.0.39",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/caouecs/Laravel-lang.git",
+                "reference": "5823b5299e372791a4b63c9276fb60fd5aa02869"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://files.phpcomposer.com/files/caouecs/Laravel-lang/5823b5299e372791a4b63c9276fb60fd5aa02869.zip",
+                "reference": "5823b5299e372791a4b63c9276fb60fd5aa02869",
+                "shasum": ""
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^1.10"
+            },
+            "suggest": {
+                "ablunier/laravel-lang-installer": "Command for easily add languages to a Laravel project",
+                "arcanedev/laravel-lang": "Translations manager and checker for Laravel 5",
+                "overtrue/laravel-lang": "Command to add languages in your project"
+            },
+            "type": "library",
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "caouecs",
+                    "email": "[email protected]"
+                }
+            ],
+            "description": "Languages for Laravel",
+            "keywords": [
+                "lang",
+                "languages",
+                "laravel",
+                "lpm"
+            ],
+            "time": "2017-11-06T19:03:05+00:00"
+        },
         {
             "name": "dnoegel/php-xdg-base-dir",
             "version": "0.1",
@@ -1480,6 +1522,57 @@
             ],
             "time": "2017-06-28T20:53:48+00:00"
         },
+        {
+            "name": "overtrue/laravel-lang",
+            "version": "3.0.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/overtrue/laravel-lang.git",
+                "reference": "c49d5f86c2ab2302c06e10d7ebd66a1ac73e0bab"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://files.phpcomposer.com/files/overtrue/laravel-lang/c49d5f86c2ab2302c06e10d7ebd66a1ac73e0bab.zip",
+                "reference": "c49d5f86c2ab2302c06e10d7ebd66a1ac73e0bab",
+                "shasum": ""
+            },
+            "require": {
+                "caouecs/laravel-lang": "~3.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Overtrue\\LaravelLang\\TranslationServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Overtrue\\LaravelLang\\": "src/"
+                },
+                "files": [
+                    "src/helpers.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "overtrue",
+                    "email": "[email protected]"
+                }
+            ],
+            "description": "List of 52 languages for Laravel 5",
+            "keywords": [
+                "languages",
+                "laravel",
+                "overtrue"
+            ],
+            "time": "2017-10-28T12:10:43+00:00"
+        },
         {
             "name": "paragonie/random_compat",
             "version": "v2.0.10",
@@ -1528,6 +1621,55 @@
             ],
             "time": "2017-03-13T16:27:32+00:00"
         },
+        {
+            "name": "paypal/rest-api-sdk-php",
+            "version": "1.13.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/paypal/PayPal-PHP-SDK.git",
+                "reference": "192e217beed14c8e75624e821fdc8ec51e2a21f5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://files.phpcomposer.com/files/paypal/PayPal-PHP-SDK/192e217beed14c8e75624e821fdc8ec51e2a21f5.zip",
+                "reference": "192e217beed14c8e75624e821fdc8ec51e2a21f5",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "ext-json": "*",
+                "php": ">=5.3.0",
+                "psr/log": "^1.0.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "PayPal": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "PayPal",
+                    "homepage": "https://github.com/paypal/rest-api-sdk-php/contributors"
+                }
+            ],
+            "description": "PayPal's PHP SDK for REST APIs",
+            "homepage": "http://paypal.github.io/PayPal-PHP-SDK/",
+            "keywords": [
+                "payments",
+                "paypal",
+                "rest",
+                "sdk"
+            ],
+            "time": "2017-11-13T19:21:59+00:00"
+        },
         {
             "name": "phpoffice/phpexcel",
             "version": "1.8.1",

BIN
composer.phar


+ 5 - 2
config/app.php

@@ -77,7 +77,8 @@ return [
     |
     */
 
-    'locale' => 'zh-CN',
+    //'locale' => 'zh-CN',
+    'locale' => 'en',
 
     /*
     |--------------------------------------------------------------------------
@@ -91,6 +92,7 @@ return [
     */
 
     'fallback_locale' => 'en',
+    //'fallback_locale' => 'zh-CN',
 
     /*
     |--------------------------------------------------------------------------
@@ -161,7 +163,7 @@ return [
         Illuminate\Redis\RedisServiceProvider::class,
         Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
         Illuminate\Session\SessionServiceProvider::class,
-        Illuminate\Translation\TranslationServiceProvider::class,
+        //Illuminate\Translation\TranslationServiceProvider::class, // 弃用自带多国语言包功能
         Illuminate\Validation\ValidationServiceProvider::class,
         Illuminate\View\ViewServiceProvider::class,
 
@@ -183,6 +185,7 @@ return [
         Maatwebsite\Excel\ExcelServiceProvider::class,
         Mews\Captcha\CaptchaServiceProvider::class,
         Jenssegers\Agent\AgentServiceProvider::class,
+        Overtrue\LaravelLang\TranslationServiceProvider::class,
 
     ],
 

+ 1 - 1
config/session.php

@@ -122,7 +122,7 @@ return [
     |
     */
 
-    'cookie' => 'laravel_session',
+    'cookie' => 'ssrpanel_session',
 
     /*
     |--------------------------------------------------------------------------

+ 5 - 0
config/version.php

@@ -0,0 +1,5 @@
+<?php
+
+return [
+    'number' => 310,
+];

+ 12 - 41
readme.md

@@ -1,4 +1,4 @@
-## 演示站(已挂)
+## 演示站
 ````
 http://www.ssrpanel.com
 用户名:admin
@@ -14,7 +14,7 @@ MYSQL 5.5 (推荐5.6+)
 磁盘空间 10G+
 KVM
 
-PHP必须开启curl、gd、fileinfo组件
+PHP必须开启curl、gd、fileinfo、openssl组件
 
 小白建议使用LNMP傻瓜安装出php7.1 + mysql(5.5以上)
 手动编译请看WIKI [编译安装PHP7.1.7环境(CentOS)]
@@ -34,43 +34,7 @@ telegram群组:https://t.me/chatssrpanel
 (节点强烈不建议使用OVZ,一无法加速二容易崩溃,512M以下内存的容易经常性宕机,即便是KVM)
 ````
 
-#### 打赏作者
-````
-如果你觉得这套代码好用,微信扫一下进行打赏
-在使用过程中有发现问题就提issue,有空我会改的
-持续开发,喜欢请star一下,如果你发现什么好玩的东西,也请发到issue
-````
-![打赏作者](https://github.com/ssrpanel/ssrpanel/blob/master/public/assets/images/donate.jpeg?raw=true)
-
-#### 打赏名单
-|昵称|金额|
-|:-------|--------:| 
-|Law-杰|¥10| 
-|Err| ¥51 | 
-|緃噺開始 |¥5| 
-|【要求匿名】|¥267|
-|、无奈|¥5|
-|Sunny Woon|¥10|
-|aazzpp678|¥26|
-|风云_1688|¥15|
-|Royal|¥25|
-|bingo|¥8|
-|Eason|¥10|
-|【要求匿名】|¥270|
-|暮风|¥20|
-|huigeer|¥10|
-|真想悠哉|¥88|
-|osmond|¥10|
-|风云_1688|¥20|
-|穆飞|¥10|
-|文青|¥10|
-|Sherl|¥48|
-|小孑、|¥20|
-|曾健|¥10|
-|Lojbk|¥10|
-|Denny Wei|¥100|
-|leon|¥20|
-
+![支持作者](https://github.com/ssrpanel/ssrpanel/blob/master/public/assets/images/donate.jpeg?raw=true)
 
 这些捐赠的用途:
 - 1.30刀买了1台VPS做开发测试用(已被BAN)
@@ -78,7 +42,6 @@ telegram群组:https://t.me/chatssrpanel
 - 3.感谢`izhangxm`提交了自定义等级的分支代码
 - 4.感谢`Hao-Luo`提供的节点一键部署脚本
 
-
 #### 拉取代码
 ````
 cd /home/wwwroot/
@@ -276,6 +239,12 @@ vim user-config.json
 
 ````
 
+## 架构(私信咨询我)
+###### 单机单节点
+###### 单机多节点(数据库不分离)
+###### 单机多节点(数据库分离)
+###### 多级多节点(彻底分离)
+
 ## 校时
 ````
 如果架构是“一面板机-一数据库机-多节点机”,请务必保持各个服务器之间的时间一致,否则会影响节点在线数的准确性和单端口多用户功能的正常使用。
@@ -314,7 +283,9 @@ ntpdate cn.pool.ntp.org
 14.支持单端口多用户
 15.账号、节点24小时和近30天内的流量监控
 16.支持节点订阅功能,可一键封禁账号订阅地址
-17.美观的国家图标
+17.节点宕机提醒(邮件+ServerChan微信提醒)
+18.Paypal在线支付接口
+19.兼容SS、SSRR
 ````
 
 ## 预览

+ 7 - 0
resources/lang/en/404.php

@@ -0,0 +1,7 @@
+<?php
+
+return [
+    'title' => 'Page Not Found',
+    'back' => 'Back',
+    'tips' => 'If BUG is found, please submit it to',
+];

+ 10 - 0
resources/lang/en/active.php

@@ -0,0 +1,10 @@
+<?php
+
+return [
+    'title' => 'Activation Account',
+    'login_button' => 'Sign In',
+    'username_placeholder' => 'Please Enter E-mail',
+    'tips' => 'In system maintenance, please contact the administrator if you need an account',
+    'back' => 'Back',
+    'submit' => 'Activate',
+];

+ 0 - 19
resources/lang/en/auth.php

@@ -1,19 +0,0 @@
-<?php
-
-return [
-
-    /*
-    |--------------------------------------------------------------------------
-    | Authentication Language Lines
-    |--------------------------------------------------------------------------
-    |
-    | The following language lines are used during authentication for various
-    | messages that we need to display to the user. You are free to modify
-    | these language lines according to your application's requirements.
-    |
-    */
-
-    'failed' => 'These credentials do not match our records.',
-    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
-
-];

+ 108 - 0
resources/lang/en/home.php

@@ -0,0 +1,108 @@
+<?php
+
+return [
+    'panel' => 'Control Panel',
+    'subscribe_address' => 'My Subscribe Address',
+    'copy_subscribe_address' => 'Copy Address',
+    'subscribe_warning' => 'Warning: the subscription address is only for personal use, do not spread the address, otherwise it will lead to abnormal flow of your account.',
+
+    // 菜单
+    'home' => 'Home',
+    'services' => 'Services',
+    'traffic_log' => 'My Traffic',
+    'invite_code' => 'Invite Code',
+    'invoices' => 'Invoices',
+    'tickets' => 'Tickets',
+    'referrals' => 'Referrals',
+
+    // 首页
+    'ratio_tips' => 'Settlement Ratio: 1 means to settle 100M with 100M, 0.1 means to settle 10M with 100M, and 5 to express 500M with 100M.',
+    'subscribe_button' => 'Subscribe',
+    'account_info' => 'Account Info',
+    'account_level' => 'Level',
+    'account_balance' => 'Balance',
+    'account_score' => 'Score',
+    'account_expire' => 'Expire At',
+    'account_last_usage' => 'Last Usage',
+    'account_last_login' => 'Last Login',
+    'account_bandwidth_usage' => 'Bandwidth Usage',
+    'account_total_traffic' => 'Total',
+    'account_usage_traffic' => 'Usage',
+    'article_title' => 'Article List',
+
+    // 购买服务
+    'service_title' => 'Services',
+    'service_name' => 'Service',
+    'service_desc' => 'Description',
+    'service_price' => 'Sales Price',
+    'service_quantity' => 'Quantity',
+    'service_total_price' => 'Total Price',
+    'service_settlement_price' => 'Settlement Price',
+    'services_none' => 'None Services',
+    'service_traffic' => 'Transfer',
+    'service_days' => 'Available Days',
+    'service_buy_button' => 'Order Now',
+    'day' => 'days',
+    'coupon' => 'Coupon',
+    'redeem_coupon' => 'Redeem',
+
+
+    // 流量日志
+    'traffic_log_tips' => 'Tips: the flow statistics in 30 days will not be counted at the present day, and the flow statistics in 24 hours will not be counted at the present hour.',
+    'traffic_log_30days' => '30Days Statistics',
+    'traffic_log_24hours' => '24Hours Statistics',
+    'traffic_log_keywords' => 'Bandwidth',
+
+    // 邀请码
+    'invite_code_make' => 'Generate Invite Code',
+    'invite_code_button' => 'Create',
+    'invite_code_tips1' => 'You can generate',
+    'invite_code_tips2' => 'invite codes.',
+    'invite_code_my_codes' => 'My Invite Codes',
+    'invite_code_table_name' => 'Codes',
+    'invite_code_table_date' => 'Expire Date',
+    'invite_code_table_user' => 'Usage User',
+    'invite_code_table_status' => 'Status',
+    'invite_code_table_none_codes' => 'None Data',
+    'invite_code_table_status_un' => 'Active',
+    'invite_code_table_status_yes' => 'Already Used',
+    'invite_code_table_status_expire' => 'Expired',
+
+    // 单据
+    'invoice_title' => 'My Invoices',
+    'invoice_table_name' => 'Service',
+    'invoice_table_price' => 'Price',
+    'invoice_table_create_date' => 'Created On',
+    'invoice_table_status' => 'Status',
+    'invoice_table_none' => 'None Data',
+    'invoice_table_closed' => 'Closed',
+    'invoice_table_wait_payment' => 'Wait Payment',
+    'invoice_table_wait_confirm' => 'Wait Confirm',
+    'invoice_table_wait_active' => 'Wait Active',
+    'invoice_table_expired' => 'Expired',
+
+    // 工单
+    'ticket_title' => 'My Tickets',
+    'ticket_table_title' => 'Title',
+    'ticket_table_status' => 'Status',
+    'ticket_table_none' => 'No Data',
+    'ticket_table_status_wait' => 'No Data',
+    'ticket_table_status_reply' => 'No Data',
+    'ticket_table_status_close' => 'No Data',
+    'ticket_table_new_button' => 'Open Ticket',
+    'ticket_table_new_desc' => 'Please fill in your questions. If the picture is submitted to the work list, upload the picture at the reply.',
+    'ticket_table_new_cancel' => 'Cancel',
+    'ticket_table_new_yes' => 'Submit',
+
+    // 推广返利
+    'referral_title' => 'My Referrals',
+    'referral_button' => 'Copy Link',
+    'referral_my_link' => 'My Referral Link',
+    'referral_table_user' => 'Who',
+    'referral_table_amount' => 'Amount',
+    'referral_table_commission' => 'Commission',
+    'referral_table_status' => 'Status',
+    'referral_table_date' => 'Date',
+    'referral_table_none' => 'None Data',
+    'referral_table_apply' => 'Apply',
+];

+ 13 - 0
resources/lang/en/login.php

@@ -0,0 +1,13 @@
+<?php
+
+return [
+    'title' => 'Sign In',
+    'tips' => 'Please Enter Username and Password',
+    'username' => 'Username',
+    'password' => 'Password',
+    'captcha' => 'Captcha',
+    'remember' => 'Remember Me',
+    'forget_password' => 'Forget Password',
+    'login' => 'Sign In',
+    'register' => 'Sign Up',
+];

+ 0 - 19
resources/lang/en/pagination.php

@@ -1,19 +0,0 @@
-<?php
-
-return [
-
-    /*
-    |--------------------------------------------------------------------------
-    | Pagination Language Lines
-    |--------------------------------------------------------------------------
-    |
-    | The following language lines are used by the paginator library to build
-    | the simple pagination links. You are free to change them to anything
-    | you want to customize your views to better match your application.
-    |
-    */
-
-    'previous' => '&laquo; Previous',
-    'next' => 'Next &raquo;',
-
-];

+ 0 - 22
resources/lang/en/passwords.php

@@ -1,22 +0,0 @@
-<?php
-
-return [
-
-    /*
-    |--------------------------------------------------------------------------
-    | Password Reset Language Lines
-    |--------------------------------------------------------------------------
-    |
-    | The following language lines are the default lines which match reasons
-    | that are given by the password broker for a password update attempt
-    | has failed, such as for an invalid token or invalid new password.
-    |
-    */
-
-    'password' => 'Passwords must be at least six characters and match the confirmation.',
-    'reset' => 'Your password has been reset!',
-    'sent' => 'We have e-mailed your password reset link!',
-    'token' => 'This password reset token is invalid.',
-    'user' => "We can't find a user with that e-mail address.",
-
-];

+ 18 - 0
resources/lang/en/register.php

@@ -0,0 +1,18 @@
+<?php
+
+return [
+    'title' => 'Sign Up',
+    'username' => 'Username',
+    'username_placeholder' => 'Enter Your E-mail',
+    'password' => 'Password',
+    'retype_password' => 'Retype Password',
+    'code' => 'Invite Code',
+    'captcha' => 'Captcha',
+    'tnc_button' => 'I have read and agree to obey',
+    'tnc_link' => 'Terms of Service',
+    'register_alter' => 'In system maintenance, please contact the administrator if you need an account',
+    'back' => 'Back',
+    'submit' => 'Submit',
+    'tnc_title' => 'I have read and agree to obey',
+    'tnc_content' => 'Do just what you want to do.',
+];

+ 0 - 121
resources/lang/en/validation.php

@@ -1,121 +0,0 @@
-<?php
-
-return [
-
-    /*
-    |--------------------------------------------------------------------------
-    | Validation Language Lines
-    |--------------------------------------------------------------------------
-    |
-    | The following language lines contain the default error messages used by
-    | the validator class. Some of these rules have multiple versions such
-    | as the size rules. Feel free to tweak each of these messages here.
-    |
-    */
-
-    'accepted'             => 'The :attribute must be accepted.',
-    'active_url'           => 'The :attribute is not a valid URL.',
-    'after'                => 'The :attribute must be a date after :date.',
-    'after_or_equal'       => 'The :attribute must be a date after or equal to :date.',
-    'alpha'                => 'The :attribute may only contain letters.',
-    'alpha_dash'           => 'The :attribute may only contain letters, numbers, and dashes.',
-    'alpha_num'            => 'The :attribute may only contain letters and numbers.',
-    'array'                => 'The :attribute must be an array.',
-    'before'               => 'The :attribute must be a date before :date.',
-    'before_or_equal'      => 'The :attribute must be a date before or equal to :date.',
-    'between'              => [
-        'numeric' => 'The :attribute must be between :min and :max.',
-        'file'    => 'The :attribute must be between :min and :max kilobytes.',
-        'string'  => 'The :attribute must be between :min and :max characters.',
-        'array'   => 'The :attribute must have between :min and :max items.',
-    ],
-    'boolean'              => 'The :attribute field must be true or false.',
-    'confirmed'            => 'The :attribute confirmation does not match.',
-    'date'                 => 'The :attribute is not a valid date.',
-    'date_format'          => 'The :attribute does not match the format :format.',
-    'different'            => 'The :attribute and :other must be different.',
-    'digits'               => 'The :attribute must be :digits digits.',
-    'digits_between'       => 'The :attribute must be between :min and :max digits.',
-    'dimensions'           => 'The :attribute has invalid image dimensions.',
-    'distinct'             => 'The :attribute field has a duplicate value.',
-    'email'                => 'The :attribute must be a valid email address.',
-    'exists'               => 'The selected :attribute is invalid.',
-    'file'                 => 'The :attribute must be a file.',
-    'filled'               => 'The :attribute field must have a value.',
-    'image'                => 'The :attribute must be an image.',
-    'in'                   => 'The selected :attribute is invalid.',
-    'in_array'             => 'The :attribute field does not exist in :other.',
-    'integer'              => 'The :attribute must be an integer.',
-    'ip'                   => 'The :attribute must be a valid IP address.',
-    'ipv4'                 => 'The :attribute must be a valid IPv4 address.',
-    'ipv6'                 => 'The :attribute must be a valid IPv6 address.',
-    'json'                 => 'The :attribute must be a valid JSON string.',
-    'max'                  => [
-        'numeric' => 'The :attribute may not be greater than :max.',
-        'file'    => 'The :attribute may not be greater than :max kilobytes.',
-        'string'  => 'The :attribute may not be greater than :max characters.',
-        'array'   => 'The :attribute may not have more than :max items.',
-    ],
-    'mimes'                => 'The :attribute must be a file of type: :values.',
-    'mimetypes'            => 'The :attribute must be a file of type: :values.',
-    'min'                  => [
-        'numeric' => 'The :attribute must be at least :min.',
-        'file'    => 'The :attribute must be at least :min kilobytes.',
-        'string'  => 'The :attribute must be at least :min characters.',
-        'array'   => 'The :attribute must have at least :min items.',
-    ],
-    'not_in'               => 'The selected :attribute is invalid.',
-    'numeric'              => 'The :attribute must be a number.',
-    'present'              => 'The :attribute field must be present.',
-    'regex'                => 'The :attribute format is invalid.',
-    'required'             => 'The :attribute field is required.',
-    'required_if'          => 'The :attribute field is required when :other is :value.',
-    'required_unless'      => 'The :attribute field is required unless :other is in :values.',
-    'required_with'        => 'The :attribute field is required when :values is present.',
-    'required_with_all'    => 'The :attribute field is required when :values is present.',
-    'required_without'     => 'The :attribute field is required when :values is not present.',
-    'required_without_all' => 'The :attribute field is required when none of :values are present.',
-    'same'                 => 'The :attribute and :other must match.',
-    'size'                 => [
-        'numeric' => 'The :attribute must be :size.',
-        'file'    => 'The :attribute must be :size kilobytes.',
-        'string'  => 'The :attribute must be :size characters.',
-        'array'   => 'The :attribute must contain :size items.',
-    ],
-    'string'               => 'The :attribute must be a string.',
-    'timezone'             => 'The :attribute must be a valid zone.',
-    'unique'               => 'The :attribute has already been taken.',
-    'uploaded'             => 'The :attribute failed to upload.',
-    'url'                  => 'The :attribute format is invalid.',
-
-    /*
-    |--------------------------------------------------------------------------
-    | Custom Validation Language Lines
-    |--------------------------------------------------------------------------
-    |
-    | Here you may specify custom validation messages for attributes using the
-    | convention "attribute.rule" to name the lines. This makes it quick to
-    | specify a specific custom language line for a given attribute rule.
-    |
-    */
-
-    'custom' => [
-        'attribute-name' => [
-            'rule-name' => 'custom-message',
-        ],
-    ],
-
-    /*
-    |--------------------------------------------------------------------------
-    | Custom Validation Attributes
-    |--------------------------------------------------------------------------
-    |
-    | The following language lines are used to swap attribute place-holders
-    | with something more reader friendly such as E-Mail Address instead
-    | of "email". This simply helps us make messages a little cleaner.
-    |
-    */
-
-    'attributes' => [],
-
-];

+ 7 - 0
resources/lang/zh-CN/404.php

@@ -0,0 +1,7 @@
+<?php
+
+return [
+    'title' => '页面不存在',
+    'back' => '返 回',
+    'tips' => '如果发现BUG请提交到',
+];

+ 10 - 0
resources/lang/zh-CN/active.php

@@ -0,0 +1,10 @@
+<?php
+
+return [
+    'title' => '激活账号',
+    'login_button' => '登 录',
+    'username_placeholder' => '请输入用户名',
+    'tips' => '系统维护中,如需激活账号请联系管理员',
+    'back' => '返 回',
+    'submit' => '激 活',
+];

+ 107 - 0
resources/lang/zh-CN/home.php

@@ -0,0 +1,107 @@
+<?php
+
+return [
+    'panel' => '控制面板',
+    'subscribe_address' => '我的订阅地址',
+    'copy_subscribe_address' => '复制链接',
+    'subscribe_warning' => '警告:该订阅地址仅限个人使用,请勿传播该地址,否则会导致您的账号流量异常。',
+
+    // 菜单
+    'home' => '首页',
+    'services' => '购买服务',
+    'traffic_log' => '流量日志',
+    'invite_code' => '邀请码',
+    'invoices' => '消费记录',
+    'tickets' => '我的工单',
+    'referrals' => '推广返利',
+
+    // 首页
+    'ratio_tips' => '结算比例: 1表示用100M就结算100M,0.1表示用100M结算10M,5表示用100M结算500M。',
+    'subscribe_button' => '订阅节点',
+    'account_info' => '账号信息',
+    'account_level' => '等级',
+    'account_balance' => '余额',
+    'account_score' => '积分',
+    'account_expire' => '账号到期',
+    'account_last_usage' => '最后使用',
+    'account_last_login' => '最后登录',
+    'account_bandwidth_usage' => '已用流量',
+    'account_total_traffic' => '共计',
+    'account_usage_traffic' => '已使用',
+    'article_title' => '文章',
+
+    // 购买服务
+    'service_title' => '购买服务',
+    'service_name' => '服务',
+    'service_desc' => '描述',
+    'service_price' => '价格',
+    'service_quantity' => '数量',
+    'service_total_price' => '共计',
+    'service_settlement_price' => '结算价',
+    'services_none' => '暂无可用服务',
+    'service_traffic' => '内含流量',
+    'service_days' => '有效期',
+    'service_buy_button' => '购买',
+    'day' => '天',
+    'coupon' => '优惠券',
+    'redeem_coupon' => '使用',
+
+    // 流量日志
+    'traffic_log_tips' => '提示:30日内流量统计不会统计当天,24小时内流量统计不会统计当前小时。',
+    'traffic_log_30days' => '30日内流量消耗情况',
+    'traffic_log_24hours' => '24小时内流量消耗情况',
+    'traffic_log_keywords' => '消耗流量',
+
+    // 邀请码
+    'invite_code_make' => '生成邀请码',
+    'invite_code_button' => '生成',
+    'invite_code_tips1' => '可生成',
+    'invite_code_tips2' => '个邀请码',
+    'invite_code_my_codes' => '我的邀请码',
+    'invite_code_table_name' => '邀请码',
+    'invite_code_table_date' => '有效期',
+    'invite_code_table_user' => '使用者',
+    'invite_code_table_status' => '状态',
+    'invite_code_table_none_codes' => '暂无数据',
+    'invite_code_table_status_un' => '未使用',
+    'invite_code_table_status_yes' => '已使用',
+    'invite_code_table_status_expire' => '已过期',
+
+    // 单据
+    'invoice_title' => '消费记录',
+    'invoice_table_name' => '服务',
+    'invoice_table_price' => '价格',
+    'invoice_table_create_date' => '创建日期',
+    'invoice_table_status' => '状态',
+    'invoice_table_none' => '暂无数据',
+    'invoice_table_closed' => '关闭',
+    'invoice_table_wait_payment' => '待付款',
+    'invoice_table_wait_confirm' => '待确认',
+    'invoice_table_wait_active' => '使用中',
+    'invoice_table_expired' => '已过期',
+
+    // 工单
+    'ticket_title' => '工单列表',
+    'ticket_table_title' => '标题',
+    'ticket_table_status' => '状态',
+    'ticket_table_none' => '暂无数据',
+    'ticket_table_status_wait' => '待处理',
+    'ticket_table_status_reply' => '已回复',
+    'ticket_table_status_close' => '已关闭',
+    'ticket_table_new_button' => '发起工单',
+    'ticket_table_new_desc' => '请填写您的问题,如果图片请提交工单后在回复处上传图片',
+    'ticket_table_new_cancel' => '取消',
+    'ticket_table_new_yes' => '提交',
+
+    // 推广返利
+    'referral_title' => '推广返利',
+    'referral_button' => '复制链接',
+    'referral_my_link' => '我的推广链接',
+    'referral_table_user' => '消费者',
+    'referral_table_amount' => '消费金额',
+    'referral_table_commission' => '返利金额',
+    'referral_table_status' => '状态',
+    'referral_table_date' => '返利时间',
+    'referral_table_none' => '暂无数据',
+    'referral_table_apply' => '申请提现',
+];

+ 13 - 0
resources/lang/zh-CN/login.php

@@ -0,0 +1,13 @@
+<?php
+
+return [
+    'title' => '登录',
+    'tips' => '请输入用户名和密码',
+    'username' => '用户名',
+    'password' => '密码',
+    'captcha' => '验证码',
+    'remember' => '记住我',
+    'forget_password' => '忘记密码',
+    'login' => '登 录',
+    'register' => '注 册',
+];

+ 18 - 0
resources/lang/zh-CN/register.php

@@ -0,0 +1,18 @@
+<?php
+
+return [
+    'title' => '注册',
+    'username' => '用户名',
+    'username_placeholder' => '请输入邮箱',
+    'password' => '密码',
+    'retype_password' => '重复密码',
+    'code' => '邀请码',
+    'captcha' => '验证码',
+    'tnc_button' => '我已阅读并同意遵守',
+    'tnc_link' => '服务条款',
+    'register_alter' => '系统维护中,如需账号请联系管理员',
+    'back' => '返 回',
+    'submit' => '提 交',
+    'tnc_title' => '我已完整阅读,并承诺遵守',
+    'tnc_content' => '不得通过本站提供的服务发布、转载、传送含有下列内容之一的信息:<br>1.违反宪法确定的基本原则的;<br>2.危害国家安全,泄漏国家机密,颠覆国家政权,破坏国家统一的;<br>3.损害国家荣誉和利益的;<br>4.煽动民族仇恨、民族歧视,破坏民族团结的;<br>5.破坏国家宗教政策,宣扬邪教和封建迷信的; <br>6.散布谣言,扰乱社会秩序,破坏社会稳定的;<br>7.散布淫秽、色情、赌博、暴力、恐怖或者教唆犯罪的;<br>8.侮辱或者诽谤他人,侵害他人合法权益的;<br>9.煽动非法集会、结社、游行、示威、聚众扰乱社会秩序的;<br>10.以非法民间组织名义活动的;<br>11.含有法律、行政法规禁止的其他内容的。',
+];

+ 4 - 4
resources/views/404.blade.php

@@ -8,7 +8,7 @@
 
 <head>
     <meta charset="utf-8" />
-    <title>页面不存在</title>
+    <title>{{trans('404.title')}}</title>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta content="width=device-width, initial-scale=1" name="viewport" />
     <meta content="" name="description" />
@@ -36,11 +36,11 @@
     <div class="col-md-12 page-500">
         <div class="number font-red"> 404 </div>
         <div class="details">
-            <h3>页面不存在</h3>
-            <p> 如果发现BUG请提交到 <a href="https://github.com/ssrpanel/ssrpanel/issues" target="_blank">Issues</a>
+            <h3>{{trans('404.title')}}</h3>
+            <p> {{trans('404.tips')}} <a href="https://github.com/ssrpanel/ssrpanel/issues" target="_blank">Issues</a>
                 <br/> </p>
             <p>
-                <a href="{{url('admin')}}" class="btn red btn-outline"> 返 回 </a>
+                <a href="{{url('admin')}}" class="btn red btn-outline"> {{trans('404.back')}} </a>
                 <br> </p>
         </div>
     </div>

+ 1 - 1
resources/views/admin/articleList.blade.php

@@ -36,7 +36,7 @@
                     </div>
                     <div class="portlet-body">
                         <div class="table-scrollable">
-                            <table class="table table-striped table-bordered table-hover table-checkable order-column" id="sample_1">
+                            <table class="table table-striped table-bordered table-hover table-checkable order-column">
                                 <thead>
                                 <tr>
                                     <th> ID </th>

+ 1 - 1
resources/views/admin/articleLogList.blade.php

@@ -38,7 +38,7 @@
                     </div>
                     <div class="portlet-body">
                         <div class="table-scrollable">
-                            <table class="table table-striped table-bordered table-hover table-checkable order-column" id="sample_1">
+                            <table class="table table-striped table-bordered table-hover table-checkable order-column">
                                 <thead>
                                 <tr>
                                     <th> ID </th>

+ 1 - 1
resources/views/admin/inviteList.blade.php

@@ -17,7 +17,7 @@
         <!-- BEGIN PAGE BASE CONTENT -->
         <div class="row">
             <div class="col-md-4">
-                <div class="tab-pane active" id="tab_0">
+                <div class="tab-pane active">
                     <div class="portlet light bordered">
                         <div class="portlet-title">
                             <div class="caption">

+ 189 - 105
resources/views/admin/system.blade.php

@@ -446,20 +446,40 @@
                                                             <label for="is_node_crash_warning" class="col-md-3 control-label">节点宕机警告</label>
                                                             <div class="col-md-9">
                                                                 <input type="checkbox" class="make-switch" @if($is_node_crash_warning) checked @endif id="is_node_crash_warning" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
-                                                                <span class="help-block"> 启用如果节点宕机则会发邮件提醒管理员 </span>
+                                                                <span class="help-block"> 启用后如果节点宕机则发出提醒邮件 </span>
                                                             </div>
                                                         </div>
                                                         <div class="col-md-6">
-                                                            <label for="crash_warning_email" class="col-md-3 control-label">宕机警告收信地址</label>
+                                                            <label for="crash_warning_email" class="col-md-3 control-label">宕机收信地址</label>
                                                             <div class="col-md-9">
                                                                 <div class="input-group">
                                                                     <input class="form-control" type="text" name="crash_warning_email" value="{{$crash_warning_email}}" id="crash_warning_email" placeholder="[email protected]" />
-                                                                    <span class="input-group-addon">分钟</span>
                                                                     <span class="input-group-btn">
                                                                         <button class="btn btn-success" type="button" onclick="setCrashWarningEmail()">修改</button>
                                                                     </span>
                                                                 </div>
-                                                                <span class="help-block"> 如果启用节点宕机警告提醒,请务必配置本值 </span>
+                                                                <span class="help-block"> 启用节点宕机提醒时请务必配置本值 </span>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                    <div class="form-group">
+                                                        <div class="col-md-6">
+                                                            <label for="is_server_chan" class="col-md-3 control-label">ServerChan</label>
+                                                            <div class="col-md-9">
+                                                                <input type="checkbox" class="make-switch" @if($is_server_chan) checked @endif id="is_server_chan" data-on-color="success" data-off-color="danger" data-on-text="启用" data-off-text="关闭">
+                                                                <span class="help-block"> 启用后将使用ServerChan推送节点宕机提醒(<a href="http://sc.ftqq.com" target="_blank">绑定微信</a>) </span>
+                                                            </div>
+                                                        </div>
+                                                        <div class="col-md-6">
+                                                            <label for="server_chan_key" class="col-md-3 control-label">SCKEY</label>
+                                                            <div class="col-md-9">
+                                                                <div class="input-group">
+                                                                    <input class="form-control" type="text" name="server_chan_key" value="{{$server_chan_key}}" id="server_chan_key" placeholder="请到ServerChan申请" />
+                                                                    <span class="input-group-btn">
+                                                                        <button class="btn btn-success" type="button" onclick="setServerChanKey()">修改</button>
+                                                                    </span>
+                                                                </div>
+                                                                <span class="help-block"> 启用ServerChan,请务必填入本值(<a href="http://sc.ftqq.com" target="_blank">申请SCKEY</a>) </span>
                                                             </div>
                                                         </div>
                                                     </div>
@@ -559,7 +579,11 @@
                 var is_rand_port = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_rand_port', value:is_rand_port}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -570,7 +594,11 @@
                 var is_user_rand_port = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_user_rand_port', value:is_user_rand_port}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -581,7 +609,11 @@
                 var login_add_score = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'login_add_score', value:login_add_score}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -592,7 +624,11 @@
                 var is_register = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_register', value:is_register}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -603,7 +639,11 @@
                 var is_invite_register = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_invite_register', value:is_invite_register}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -614,11 +654,11 @@
                 var is_reset_password = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_reset_password', value:is_reset_password}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
                 });
             }
         });
@@ -629,11 +669,11 @@
                 var is_captcha = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_captcha', value:is_captcha}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
                 });
             }
         });
@@ -644,11 +684,11 @@
                 var is_active_register = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_active_register', value:is_active_register}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
                 });
             }
         });
@@ -659,11 +699,11 @@
                 var expire_warning = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'expire_warning', value:expire_warning}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
                 });
             }
         });
@@ -674,11 +714,26 @@
                 var is_node_crash_warning = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_node_crash_warning', value:is_node_crash_warning}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
+                });
+            }
+        });
+
+        // 启用、禁用节点宕机发ServerChan微信消息提醒
+        $('#is_server_chan').on({
+            'switchChange.bootstrapSwitch': function(event, state) {
+                var is_server_chan = state ? 1 : 0;
+
+                $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_server_chan', value:is_server_chan}, function (ret) {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -689,11 +744,11 @@
                 var referral_status = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'referral_status', value:referral_status}, function (ret) {
-                    if (ret.status == 'fail') {
-                        layer.msg(ret.message, {time:1000}, function() {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
                             window.location.reload();
-                        });
-                    }
+                        }
+                    });
                 });
             }
         });
@@ -704,7 +759,11 @@
                 var traffic_warning = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'traffic_warning', value:traffic_warning}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -715,7 +774,11 @@
                 var is_clear_log = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_clear_log', value:is_clear_log}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -726,7 +789,11 @@
                 var reset_traffic = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'reset_traffic', value:reset_traffic}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -737,7 +804,11 @@
                 var is_traffic_ban = state ? 1 : 0;
 
                 $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'is_traffic_ban', value:is_traffic_ban}, function (ret) {
-                    console.log(ret);
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'fail') {
+                            window.location.reload();
+                        }
+                    });
                 });
             }
         });
@@ -747,11 +818,11 @@
             var traffic_ban_value = $("#traffic_ban_value").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'traffic_ban_value', value:traffic_ban_value}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -760,11 +831,11 @@
             var traffic_ban_time = $("#traffic_ban_time").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'traffic_ban_time', value:traffic_ban_time}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -773,11 +844,24 @@
             var crash_warning_email = $("#crash_warning_email").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'crash_warning_email', value:crash_warning_email}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
+            });
+        }
+
+        // 设置ServerChan的SCKEY
+        function setServerChanKey() {
+            var server_chan_key = $("#server_chan_key").val();
+
+            $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'server_chan_key', value:server_chan_key}, function (ret) {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
+                        window.location.reload();
+                    }
+                });
             });
         }
 
@@ -855,11 +939,11 @@
             var default_days = $("#default_days").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'default_days', value:default_days}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -868,11 +952,11 @@
             var default_traffic = $("#default_traffic").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'default_traffic', value:default_traffic}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -881,11 +965,11 @@
             var invite_num = $("#invite_num").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'invite_num', value:invite_num}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -894,11 +978,11 @@
             var reset_password_times = $("#reset_password_times").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'reset_password_times', value:reset_password_times}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -907,11 +991,11 @@
             var active_times = $("#active_times").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'active_times', value:active_times}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -920,11 +1004,11 @@
             var subscribe_max = $("#subscribe_max").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'subscribe_max', value:subscribe_max}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -933,11 +1017,11 @@
             var traffic_warning_percent = $("#traffic_warning_percent").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'traffic_warning_percent', value:traffic_warning_percent}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -946,11 +1030,11 @@
             var expire_days = $("#expire_days").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'expire_days', value:expire_days}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -959,11 +1043,11 @@
             var website_name = $("#website_name").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'website_name', value:website_name}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -972,11 +1056,11 @@
             var website_url = $("#website_url").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'website_url', value:website_url}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -985,11 +1069,11 @@
             var login_add_score_range = $("#login_add_score_range").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'login_add_score_range', value:login_add_score_range}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -998,11 +1082,11 @@
             var referral_traffic = $("#referral_traffic").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'referral_traffic', value:referral_traffic}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -1011,11 +1095,11 @@
             var referral_percent = $("#referral_percent").val();
 
             $.post("{{url('admin/setReferralPercent')}}", {_token:'{{csrf_token()}}', value:referral_percent}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
 
@@ -1024,11 +1108,11 @@
             var referral_money = $("#referral_money").val();
 
             $.post("{{url('admin/setConfig')}}", {_token:'{{csrf_token()}}', name:'referral_money', value:referral_money}, function (ret) {
-                if (ret.status == 'success') {
-                    layer.msg(ret.message, {time:1000}, function() {
+                layer.msg(ret.message, {time:1000}, function() {
+                    if (ret.status == 'fail') {
                         window.location.reload();
-                    });
-                }
+                    }
+                });
             });
         }
     </script>

+ 17 - 1
resources/views/admin/userList.blade.php

@@ -27,7 +27,8 @@
                             <span class="caption-subject bold uppercase"> 账号列表 </span>
                         </div>
                         <div class="actions">
-                            <div class="btn-group">
+                            <div class="btn-group btn-group-devided">
+                                <button class="btn sbold blue" onclick="batchAddUsers()"> 批量生成 </button>
                                 <button class="btn sbold blue" onclick="addUser()"> 新增
                                     <i class="fa fa-plus"></i>
                                 </button>
@@ -175,6 +176,21 @@
     <script src="/js/layer/layer.js" type="text/javascript"></script>
 
     <script type="text/javascript">
+        // 批量生成账号
+        function batchAddUsers() {
+            layer.confirm('将自动生成5个账号,确定继续吗?', {icon: 3, title:'警告'}, function(index) {
+                $.post("{{url('admin/batchAddUsers')}}", {_token:'{{csrf_token()}}'}, function(ret) {
+                    layer.msg(ret.message, {time:1000}, function() {
+                        if (ret.status == 'success') {
+                            window.location.reload();
+                        }
+                    });
+                });
+
+                layer.close(index);
+            });
+        }
+
         // 添加账号
         function addUser() {
             window.location.href = '{{url('admin/addUser')}}';

+ 13 - 13
resources/views/login.blade.php

@@ -7,7 +7,7 @@
 
 <head>
     <meta charset="utf-8" />
-    <title>登录</title>
+    <title>{{trans('login.title')}}</title>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta content="width=device-width, initial-scale=1" name="viewport" />
     <meta content="" name="description" />
@@ -41,7 +41,7 @@
     <form class="login-form" action="{{url('login')}}" method="post">
         <div class="alert alert-danger display-hide">
             <button class="close" data-close="alert"></button>
-            <span> 请输入用户名和密码 </span>
+            <span> {{trans('login.tips')}} </span>
         </div>
         @if (Session::get('errorMsg'))
             <div class="alert alert-danger">
@@ -56,39 +56,39 @@
             </div>
         @endif
         <div class="form-group">
-            <label class="control-label visible-ie8 visible-ie9">用户名</label>
-            <input class="form-control form-control-solid placeholder-no-fix" type="text" autocomplete="off" placeholder="用户名" name="username" value="{{Request::old('username')}}" />
+            <label class="control-label visible-ie8 visible-ie9">{{trans('login.username')}}</label>
+            <input class="form-control form-control-solid placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('login.username')}}" name="username" value="{{Request::old('username')}}" />
         </div>
         <div class="form-group">
-            <label class="control-label visible-ie8 visible-ie9">密码</label>
-            <input class="form-control form-control-solid placeholder-no-fix" type="password" autocomplete="off" placeholder="密码" name="password" value="{{Request::old('password')}}" />
+            <label class="control-label visible-ie8 visible-ie9">{{trans('login.password')}}</label>
+            <input class="form-control form-control-solid placeholder-no-fix" type="password" autocomplete="off" placeholder="{{trans('login.password')}}" name="password" value="{{Request::old('password')}}" />
             <input type="hidden" name="_token" value="{{csrf_token()}}" />
         </div>
         @if($is_captcha)
             <div class="form-group" style="margin-bottom:65px;">
-                <label class="control-label visible-ie8 visible-ie9">验证码</label>
-                <input class="form-control form-control-solid placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="验证码" name="captcha" value="" />
-                <img src="{{captcha_src()}}" onclick="this.src='/captcha/default?'+Math.random()" alt="验证码" style="float:right;" />
+                <label class="control-label visible-ie8 visible-ie9">{{trans('login.captcha')}}</label>
+                <input class="form-control form-control-solid placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="{{trans('login.captcha')}}" name="captcha" value="" />
+                <img src="{{captcha_src()}}" onclick="this.src='/captcha/default?'+Math.random()" alt="{{trans('login.captcha')}}" style="float:right;" />
             </div>
         @endif
         <div class="form-actions">
             <div class="pull-left">
                 <label class="rememberme mt-checkbox mt-checkbox-outline">
-                    <input type="checkbox" name="remember" value="1"> 记住我
+                    <input type="checkbox" name="remember" value="1"> {{trans('login.remember')}}
                     <span></span>
                 </label>
             </div>
             <div class="pull-right forget-password-block">
-                <a href="{{url('resetPassword')}}" class="forget-password">忘记密码</a>
+                <a href="{{url('resetPassword')}}" class="forget-password">{{trans('login.forget_password')}}</a>
             </div>
         </div>
         <div class="form-actions">
-            <button type="submit" class="btn red btn-block uppercase">登 录</button>
+            <button type="submit" class="btn red btn-block uppercase">{{trans('login.login')}}</button>
         </div>
         @if($is_register)
             <div class="create-account">
                 <p>
-                    <a href="{{url('register')}}" class="btn-primary btn">注 册</a>
+                    <a href="{{url('register')}}" class="btn-primary btn">{{trans('login.register')}}</a>
                 </p>
             </div>
         @endif

+ 19 - 19
resources/views/register.blade.php

@@ -7,7 +7,7 @@
 
 <head>
     <meta charset="utf-8" />
-    <title>注册</title>
+    <title>{{trans('register.title')}}</title>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta content="width=device-width, initial-scale=1" name="viewport" />
     <meta content="" name="description" />
@@ -47,49 +47,49 @@
                 </div>
             @endif
             <div class="form-group">
-                <label class="control-label visible-ie8 visible-ie9">用户名</label>
-                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="请输入邮箱" name="username" value="{{Request::old('username')}}" required />
+                <label class="control-label visible-ie8 visible-ie9">{{trans('register.username')}}</label>
+                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('register.username_placeholder')}}" name="username" value="{{Request::old('username')}}" required />
                 <input type="hidden" name="register_token" value="{{Session::get('register_token')}}" />
                 <input type="hidden" name="_token" value="{{csrf_token()}}" />
                 <input type="hidden" name="aff" value="{{Request::get('aff')}}" />
             </div>
             <div class="form-group">
-                <label class="control-label visible-ie8 visible-ie9">密码</label>
-                <input class="form-control placeholder-no-fix" type="password" autocomplete="off" placeholder="密码" name="password" value="{{Request::old('password')}}" required />
+                <label class="control-label visible-ie8 visible-ie9">{{trans('register.password')}}</label>
+                <input class="form-control placeholder-no-fix" type="password" autocomplete="off" placeholder="{{trans('register.password')}}" name="password" value="{{Request::old('password')}}" required />
             </div>
             <div class="form-group">
-                <label class="control-label visible-ie8 visible-ie9">重复密码</label>
-                <input class="form-control placeholder-no-fix" type="password" autocomplete="off" placeholder="重复密码" name="repassword" value="{{Request::old('repassword')}}" required />
+                <label class="control-label visible-ie8 visible-ie9">{{trans('register.retype_password')}}</label>
+                <input class="form-control placeholder-no-fix" type="password" autocomplete="off" placeholder="{{trans('register.retype_password')}}" name="repassword" value="{{Request::old('repassword')}}" required />
             </div>
             @if($is_invite_register)
                 <div class="form-group">
-                    <label class="control-label visible-ie8 visible-ie9">邀请码</label>
-                    <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="邀请码" name="code" value="{{Request::old('code') ? Request::old('code') : Request::get('code')}}" required />
+                    <label class="control-label visible-ie8 visible-ie9">{{trans('register.code')}}</label>
+                    <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('register.code')}}" name="code" value="{{Request::old('code') ? Request::old('code') : Request::get('code')}}" required />
                 </div>
             @endif
             @if($is_captcha)
             <div class="form-group" style="margin-bottom:75px;">
-                <label class="control-label visible-ie8 visible-ie9">验证码</label>
-                <input class="form-control placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="验证码" name="captcha" value="" required />
-                <img src="{{captcha_src()}}" onclick="this.src='/captcha/default?'+Math.random()" alt="验证码" style="float:right;" />
+                <label class="control-label visible-ie8 visible-ie9">{{trans('register.captcha')}}</label>
+                <input class="form-control placeholder-no-fix" style="width:60%;float:left;" type="text" autocomplete="off" placeholder="{{trans('register.captcha')}}" name="captcha" value="" required />
+                <img src="{{captcha_src()}}" onclick="this.src='/captcha/default?'+Math.random()" alt="{{trans('register.captcha')}}" style="float:right;" />
             </div>
             @endif
             <div class="form-group margin-top-20 margin-bottom-20">
                 <label class="mt-checkbox mt-checkbox-outline">
-                    <input type="checkbox" name="tnc" checked disabled /> 我已阅读并同意遵守
-                    <a href="javascript:showTnc();"> 服务条款 </a>
+                    <input type="checkbox" name="tnc" checked disabled /> {{trans('register.tnc_button')}}
+                    <a href="javascript:showTnc();"> {{trans('register.tnc_link')}} </a>
                     <span></span>
                 </label>
             </div>
         @else
             <div class="alert alert-danger">
-                <span> 系统维护中,如需账号请联系管理员 </span>
+                <span> {{trans('register.register_alter')}} </span>
             </div>
         @endif
         <div class="form-actions">
-            <button type="button" class="btn btn-default" onclick="login()">返 回</button>
+            <button type="button" class="btn btn-default" onclick="login()">{{trans('register.back')}}</button>
             @if($is_register)
-                <button type="submit" class="btn red uppercase pull-right">提 交</button>
+                <button type="submit" class="btn red uppercase pull-right">{{trans('register.submit')}}</button>
             @endif
         </div>
     </form>
@@ -124,10 +124,10 @@
             ,shade: 0.8
             ,id: 'tnc' //设定一个id,防止重复弹出
             ,resize: false
-            ,btn: ['我已完整阅读,并承诺遵守']
+            ,btn: ['{{trans('register.tnc_title')}}']
             ,btnAlign: 'c'
             ,moveType: 1 //拖拽模式,0或者1
-            ,content: '<div style="padding: 20px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;">不得通过本站提供的服务发布、转载、传送含有下列内容之一的信息:<br>1.违反宪法确定的基本原则的;<br>2.危害国家安全,泄漏国家机密,颠覆国家政权,破坏国家统一的;<br>3.损害国家荣誉和利益的;<br>4.煽动民族仇恨、民族歧视,破坏民族团结的;<br>5.破坏国家宗教政策,宣扬邪教和封建迷信的; <br>6.散布谣言,扰乱社会秩序,破坏社会稳定的;<br>7.散布淫秽、色情、赌博、暴力、恐怖或者教唆犯罪的;<br>8.侮辱或者诽谤他人,侵害他人合法权益的;<br>9.煽动非法集会、结社、游行、示威、聚众扰乱社会秩序的;<br>10.以非法民间组织名义活动的;<br>11.含有法律、行政法规禁止的其他内容的。</div>'
+            ,content: '<div style="padding: 20px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;">{{trans('register.tnc_content')}}</div>'
             ,success: function(layero){
 //                var btn = layero.find('.layui-layer-btn');
 //                btn.find('.layui-layer-btn0').attr({

+ 3 - 3
resources/views/user/active.blade.php

@@ -7,7 +7,7 @@
 
 <head>
     <meta charset="utf-8" />
-    <title>激活账号</title>
+    <title>{{trans('active.title')}}</title>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta content="width=device-width, initial-scale=1" name="viewport" />
     <meta content="" name="description" />
@@ -29,7 +29,7 @@
     <link rel="shortcut icon" href="favicon.ico" />
 </head>
 
-<body class=" login">
+<body class="login">
 <!-- BEGIN LOGO -->
 <div class="logo">
     <a href="javascript:;"> <img src="/assets/images/home_logo.png" alt="" /> </a>
@@ -50,7 +50,7 @@
     <!-- BEGIN REGISTRATION FORM -->
     <form class="register-form" action="{{url(Request::getRequestUri())}}" method="post" style="display: block;">
         <div class="form-actions">
-            <button type="button" class="btn btn-default" onclick="login()">登 录</button>
+            <button type="button" class="btn btn-default" onclick="login()">{{trans('active.login_button')}}</button>
         </div>
     </form>
     <!-- END REGISTRATION FORM -->

+ 6 - 6
resources/views/user/activeUser.blade.php

@@ -7,7 +7,7 @@
 
 <head>
     <meta charset="utf-8" />
-    <title>激活账号</title>
+    <title>{{trans('active.title')}}</title>
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta content="width=device-width, initial-scale=1" name="viewport" />
     <meta content="" name="description" />
@@ -53,21 +53,21 @@
     <form class="forget-form" action="{{url('activeUser')}}" method="post" style="display: block;">
         @if($is_active_register)
             <div class="form-title">
-                <span class="form-title">激活账号</span>
+                <span class="form-title">{{trans('active.title')}}</span>
             </div>
             <div class="form-group">
-                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="请输入用户名" name="username" value="{{Request::get('username')}}" required />
+                <input class="form-control placeholder-no-fix" type="text" autocomplete="off" placeholder="{{trans('active.username_placeholder')}}" name="username" value="{{Request::get('username')}}" required />
                 <input type="hidden" name="_token" value="{{csrf_token()}}" />
             </div>
         @else
             <div class="alert alert-danger">
-                <span> 系统维护中,如需激活账号请联系管理员 </span>
+                <span> {{trans('active.tips')}} </span>
             </div>
         @endif
         <div class="form-actions">
-            <button type="button" class="btn btn-default" onclick="login()">返 回</button>
+            <button type="button" class="btn btn-default" onclick="login()">{{trans('active.back')}}</button>
             @if($is_active_register)
-                <button type="submit" class="btn red uppercase pull-right">激 活</button>
+                <button type="submit" class="btn red uppercase pull-right">{{trans('active.submit')}}</button>
             @endif
         </div>
     </form>

+ 11 - 25
resources/views/user/addOrder.blade.php

@@ -3,22 +3,10 @@
 @section('css')
     <link href="/assets/pages/css/invoice-2.min.css" rel="stylesheet" type="text/css" />
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
-    <div class="page-content">
-        <!-- BEGIN PAGE BREADCRUMB -->
-        <ul class="page-breadcrumb breadcrumb">
-            <li>
-                <a href="{{url('user/goodsList')}}">流量包</a>
-                <i class="fa fa-circle"></i>
-            </li>
-            <li>
-                <a href="{{url('user/addOrder')}}">购买</a>
-                <i class="fa fa-circle"></i>
-            </li>
-        </ul>
-        <!-- END PAGE BREADCRUMB -->
+    <div class="page-content" style="padding-top:0;">
         <!-- BEGIN PAGE BASE CONTENT -->
         <div class="invoice-content-2 bordered">
             <div class="row invoice-body">
@@ -26,21 +14,19 @@
                     <table class="table table-hover">
                         <thead>
                         <tr>
-                            <th class="invoice-title uppercase"> 商品信息 </th>
-                            <th class="invoice-title uppercase text-center"> 单价 </th>
-                            <th class="invoice-title uppercase text-center"> 数量 </th>
-                            <th class="invoice-title uppercase text-center"> 小计 </th>
+                            <th class="invoice-title uppercase"> {{trans('home.service_name')}} </th>
+                            <th class="invoice-title uppercase text-center"> {{trans('home.service_price')}} </th>
+                            <th class="invoice-title uppercase text-center"> {{trans('home.service_quantity')}} </th>
                         </tr>
                         </thead>
                         <tbody>
                         <tr>
                             <td style="padding: 10px;">
                                 <h2>{{$goods->name}}</h2>
-                                <p> 内含流量 {{$goods->traffic}}(有效期 {{$goods->days}}天) </p>
+                                <p> {{trans('home.service_traffic')}} {{$goods->traffic}}({{trans('home.service_days')}} {{$goods->days}}{{trans('home.day')}}) </p>
                             </td>
                             <td class="text-center"> ¥{{$goods->price}} </td>
                             <td class="text-center"> x 1 </td>
-                            <td class="text-center"> ¥{{$goods->price}} </td>
                         </tr>
                         </tbody>
                     </table>
@@ -48,22 +34,22 @@
             </div>
             <div class="row invoice-subtotal">
                 <div class="col-xs-3">
-                    <h2 class="invoice-title uppercase"> 共计 </h2>
+                    <h2 class="invoice-title uppercase"> {{trans('home.service_total_price')}} </h2>
                     <p class="invoice-desc"> ¥{{$goods->price}} </p>
                 </div>
                 <div class="col-xs-3">
-                    <h2 class="invoice-title uppercase"> 优惠 </h2>
+                    <h2 class="invoice-title uppercase"> {{trans('home.coupon')}} </h2>
                     <p class="invoice-desc">
                         <div class="input-group">
-                            <input class="form-control" type="text" name="coupon_sn" id="coupon_sn" placeholder="优惠券" />
+                            <input class="form-control" type="text" name="coupon_sn" id="coupon_sn" placeholder="{{trans('home.coupon')}}" />
                             <span class="input-group-btn">
-                                <button class="btn btn-default" type="button" onclick="redeemCoupon()"><i class="fa fa-refresh"></i> 使用 </button>
+                                <button class="btn btn-default" type="button" onclick="redeemCoupon()"><i class="fa fa-refresh"></i> {{trans('home.redeem_coupon')}} </button>
                             </span>
                         </div>
                     </p>
                 </div>
                 <div class="col-xs-6">
-                    <h2 class="invoice-title uppercase"> 实际结算 </h2>
+                    <h2 class="invoice-title uppercase"> {{trans('home.service_settlement_price')}} </h2>
                     <p class="invoice-desc grand-total"> ¥{{$goods->price}} </p>
                 </div>
             </div>

+ 1 - 1
resources/views/user/article.blade.php

@@ -1,6 +1,6 @@
 @extends('user.layouts')
 
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content">

+ 15 - 15
resources/views/user/goodsList.blade.php

@@ -10,7 +10,7 @@
         }
     </style>
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
@@ -20,40 +20,40 @@
                 <div class="portlet light bordered">
                     <div class="portlet-title">
                         <div class="caption font-dark">
-                            <span class="caption-subject bold uppercase"> 流量加油包 </span>
+                            <span class="caption-subject bold"> {{trans('home.service_title')}} </span>
                         </div>
                     </div>
                     <div class="portlet-body">
                         <div class="table-scrollable">
-                            <table class="table table-striped table-bordered table-hover table-checkable order-column">
+                            <table class="table table-striped table-bordered table-hover">
                                 <thead>
                                 <tr>
-                                    <th style="text-align: center;"> 名称 </th>
-                                    <th style="text-align: center;"> 内含流量 </th>
-                                    <th style="text-align: center;"> 有效期 </th>
-                                    <th style="text-align: center;"> 售价 </th>
-                                    <!--<th> 所需积分 </th>-->
+                                    <th> {{trans('home.service_name')}} </th>
+                                    <th style="text-align: center;"> {{trans('home.service_price')}} </th>
                                     <th> </th>
                                 </tr>
                                 </thead>
                                 <tbody>
                                 @if($goodsList->isEmpty())
                                     <tr>
-                                        <td colspan="7">暂无数据</td>
+                                        <td colspan="3">{{trans('home.services_none')}}</td>
                                     </tr>
                                 @else
                                     @foreach($goodsList as $key => $goods)
                                         <tr class="odd gradeX">
-                                            <td style="text-align: center;">
+                                            <td>
                                                 <!--@if($goods->logo) <a href="{{$goods->logo}}" class="fancybox"><img src="{{$goods->logo}}"/></a> @endif -->
-                                                {{$goods->name}}
+                                                <strong><span style="color:#dc9700">{{$goods->name}}</span></strong>
+                                                <br>
+                                                {{trans('home.service_traffic')}}:{{$goods->traffic}}
+                                                <br>
+                                                {{trans('home.service_days')}}:{{$goods->days}} {{trans('home.day')}}
+                                                <br>
+                                                Strictly Self-Managed, No Support.
                                             </td>
-                                            <td style="text-align: center;"> {{$goods->traffic}} </td>
-                                            <td style="text-align: center;"> {{$goods->days}} 天 </td>
                                             <td style="text-align: center;"> ¥{{$goods->price}} </td>
-                                            <!--<td> {{$goods->score}} </td>-->
                                             <td style="text-align: center;">
-                                                <button type="button" class="btn btn-sm red btn-outline" onclick="buy('{{$goods->id}}')">购买</button>
+                                                <button type="button" class="btn btn-sm blue" onclick="buy('{{$goods->id}}')">{{trans('home.service_buy_button')}}</button>
                                                 <!--<button type="button" class="btn btn-sm blue btn-outline" onclick="exchange('{{$goods->id}}')">兑换</button>-->
                                             </td>
                                         </tr>

+ 13 - 13
resources/views/user/index.blade.php

@@ -26,7 +26,7 @@
 
     </style>
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
@@ -47,8 +47,8 @@
         <div class="row">
             <div class="col-md-8">
                 <div class="alert alert-danger">
-                    <strong>结算比例:</strong> 1表示用100M就结算100M,0.1表示用100M结算10M,5表示用100M结算500M。
-                    <button class="btn btn-sm red" onclick="subscribe()"> 订阅节点 </button>
+                    {{trans('home.ratio_tips')}}
+                    <button class="btn btn-sm red" onclick="subscribe()"> {{trans('home.subscribe_button')}} </button>
                 </div>
                 <div class="row widget-row">
                     @if(!$nodeList->isEmpty())
@@ -82,29 +82,29 @@
             <div class="col-md-4">
                 <div class="portlet box red">
                     <div class="portlet-title">
-                        <div class="caption">账号信息</div>
+                        <div class="caption">{{trans('home.account_info')}}</div>
                         <div class="tools">
                             <a href="javascript:;" class="collapse" data-original-title="" title="折叠"> </a>
                         </div>
                     </div>
                     <div class="portlet-body">
-                        <p class="text-muted"> 等级:{{$info['levelName']}} </p>
+                        <p class="text-muted"> {{trans('home.account_level')}}:{{$info['levelName']}} </p>
                         <p class="text-muted">
-                            余额:{{$info['balance']}}
+                            {{trans('home.account_balance')}}:{{$info['balance']}}
                             <span class="badge badge-danger">
                                 <a href="javascript:;" data-toggle="modal" data-target="#charge_modal" style="color:#FFF;">充值</a>
                             </span>
-                            &ensp;&ensp;积分:{{$info['score']}}
+                            &ensp;&ensp;{{trans('home.account_score')}}:{{$info['score']}}
                             <span class="badge badge-danger">
                                 <a href="javascript:;" data-toggle="modal" data-target="#excharge_modal" style="color:#FFF;">兑换</a>
                             </span>
                         </p>
-                        <p class="text-muted"> 账号到期:{{date('Y-m-d 0:0:0') > $info['expire_time'] ? '已过期' : $info['expire_time']}} </p>
-                        <p class="text-muted"> 最后使用:{{empty($info['t']) ? '从未使用' : date('Y-m-d H:i:s', $info['t'])}} </p>
-                        <p class="text-muted"> 最后登录:{{empty($info['last_login']) ? '未登录' : date('Y-m-d H:i:s', $info['last_login'])}} </p>
+                        <p class="text-muted"> {{trans('home.account_expire')}}:{{date('Y-m-d 0:0:0') > $info['expire_time'] ? '已过期' : $info['expire_time']}} </p>
+                        <p class="text-muted"> {{trans('home.account_last_usage')}}:{{empty($info['t']) ? '从未使用' : date('Y-m-d H:i:s', $info['t'])}} </p>
+                        <p class="text-muted"> {{trans('home.account_last_login')}}:{{empty($info['last_login']) ? '未登录' : date('Y-m-d H:i:s', $info['last_login'])}} </p>
                         <p class="text-muted">
-                            已用流量:{{$info['usedTransfer']}} ({{$info['totalTransfer']}})
-                            <div class="progress progress-striped active" style="margin-bottom:0;" title="共有流量{{$info['totalTransfer']}},已用{{$info['usedTransfer']}}">
+                            {{trans('home.account_bandwidth_usage')}}:{{$info['usedTransfer']}} ({{$info['totalTransfer']}})
+                            <div class="progress progress-striped active" style="margin-bottom:0;" title="{{trans('home.account_total_traffic')}} {{$info['totalTransfer']}},{{trans('home.account_usage_traffic')}} {{$info['usedTransfer']}}">
                                 <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="{{$info['usedPercent'] * 100}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$info['usedPercent'] * 100}}%">
                                     <span class="sr-only"> {{$info['usedTransfer']}} / {{$info['totalTransfer']}} </span>
                                 </div>
@@ -114,7 +114,7 @@
                 </div>
                 <div class="portlet box blue">
                     <div class="portlet-title">
-                        <div class="caption">文章</div>
+                        <div class="caption">{{trans('home.article_title')}}</div>
                         <div class="tools">
                             <a href="javascript:;" class="collapse" data-original-title="" title="折叠"> </a>
                         </div>

+ 16 - 16
resources/views/user/invite.blade.php

@@ -2,54 +2,54 @@
 
 @section('css')
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
         <!-- BEGIN PAGE BASE CONTENT -->
         <div class="row">
             <div class="col-md-4">
-                <div class="tab-pane active" id="tab_0">
+                <div class="tab-pane active">
                     <div class="portlet light bordered">
                         <div class="portlet-title">
                             <div class="caption">
-                                <span class="caption-subject font-dark bold uppercase">生成邀请码</span>
+                                <span class="caption-subject font-dark bold">{{trans('home.invite_code_make')}}</span>
                             </div>
                         </div>
                         <div class="portlet-body">
                             <div class="alert alert-info">
                                 <i class="fa fa-warning"></i>
-                                可生成 <strong> {{$num}} </strong> 个邀请码
+                                {{trans('home.invite_code_tips1')}} <strong> {{$num}} </strong> {{trans('home.invite_code_tips2')}}
                             </div>
-                            <button type="button" class="btn blue" onclick="makeInvite()" @if(!$num) disabled @endif> 生 成 </button>
+                            <button type="button" class="btn blue" onclick="makeInvite()" @if(!$num) disabled @endif> {{trans('home.invite_code_button')}} </button>
                         </div>
                     </div>
                 </div>
             </div>
             <div class="col-md-8">
-                <div class="tab-pane active" id="tab_0">
+                <div class="tab-pane active">
                     <div class="portlet light bordered">
                         <div class="portlet-title">
                             <div class="caption">
-                                <span class="caption-subject font-dark bold uppercase">我的邀请码</span>
+                                <span class="caption-subject font-dark bold">{{trans('home.invite_code_my_codes')}}</span>
                             </div>
                         </div>
                         <div class="portlet-body">
                             <div class="table-scrollable table-scrollable-borderless">
-                                <table class="table table-hover table-light">
+                                <table class="table table-hover table-light table-checkable order-column">
                                     <thead>
                                         <tr class="uppercase">
                                             <th> # </th>
-                                            <th> 邀请码 </th>
-                                            <th> 有效期 </th>
-                                            <th> 使用者 </th>
-                                            <th> 状态 </th>
+                                            <th> {{trans('home.invite_code_table_name')}} </th>
+                                            <th> {{trans('home.invite_code_table_date')}} </th>
+                                            <th> {{trans('home.invite_code_table_user')}} </th>
+                                            <th> {{trans('home.invite_code_table_status')}} </th>
                                         </tr>
                                     </thead>
                                     <tbody>
                                         @if($inviteList->isEmpty())
                                             <tr>
-                                                <td colspan="5" style="text-align: center;">暂无数据</td>
+                                                <td colspan="5" style="text-align: center;">{{trans('home.invite_code_table_none_codes')}}</td>
                                             </tr>
                                         @else
                                             @foreach($inviteList as $key => $invite)
@@ -60,11 +60,11 @@
                                                     <td> {{empty($invite->user) ? '' : $invite->user->username}} </td>
                                                     <td>
                                                         @if($invite->status == '0')
-                                                            <span class="label label-sm label-success"> 未使用 </span>
+                                                            <span class="label label-sm label-success"> {{trans('home.invite_code_table_status_un')}} </span>
                                                         @elseif($invite->status == '1')
-                                                            <span class="label label-sm label-danger"> 已使用 </span>
+                                                            <span class="label label-sm label-danger"> {{trans('home.invite_code_table_status_yes')}} </span>
                                                         @else
-                                                            <span class="label label-sm label-default"> 已过期 </span>
+                                                            <span class="label label-sm label-default"> {{trans('home.invite_code_table_status_expire')}} </span>
                                                         @endif
                                                     </td>
                                                 </tr>

+ 7 - 7
resources/views/user/layouts.blade.php

@@ -110,45 +110,45 @@
                 <li class="nav-item start {{(Request::getRequestUri() == '/' || Request::getRequestUri() == '/user' || Request::getRequestUri() == '/user/subscribe') ? 'active open' : ''}}">
                     <a href="{{url('user')}}" class="nav-link nav-toggle">
                         <i class="icon-home"></i>
-                        <span class="title">首页</span>
+                        <span class="title">{{trans('home.home')}}</span>
                         <span class="selected"></span>
                     </a>
                 </li>
                 <li class="nav-item {{in_array(Request::getRequestUri(), ['/user/goodsList', '/user/addOrder']) ? 'active open' : ''}}">
                     <a href="{{url('user/goodsList')}}" class="nav-link nav-toggle">
                         <i class="icon-basket"></i>
-                        <span class="title">购买服务</span>
+                        <span class="title">{{trans('home.services')}}</span>
                     </a>
                 </li>
                 <li class="nav-item {{Request::getRequestUri() == '/user/trafficLog' ? 'active open' : ''}}">
                     <a href="{{url('user/trafficLog')}}" class="nav-link nav-toggle">
                         <i class="icon-speedometer"></i>
-                        <span class="title">流量日志</span>
+                        <span class="title">{{trans('home.traffic_log')}}</span>
                     </a>
                 </li>
                 <li class="nav-item {{Request::getRequestUri() == '/user/invite' ? 'active open' : ''}}">
                     <a href="{{url('user/invite')}}" class="nav-link nav-toggle">
                         <i class="icon-user-follow"></i>
-                        <span class="title">邀请码</span>
+                        <span class="title">{{trans('home.invite_code')}}</span>
                     </a>
                 </li>
                 <li class="nav-item {{in_array(Request::getRequestUri(), ['/user/orderList']) ? 'active open' : ''}}">
                     <a href="{{url('user/orderList')}}" class="nav-link nav-toggle">
                         <i class="icon-wallet"></i>
-                        <span class="title">消费记录</span>
+                        <span class="title">{{trans('home.invoices')}}</span>
                     </a>
                 </li>
                 <li class="nav-item {{Request::getRequestUri() == '/user/ticketList' ? 'active open' : ''}}">
                     <a href="{{url('user/ticketList')}}" class="nav-link nav-toggle">
                         <i class="icon-question"></i>
-                        <span class="title">我的工单</span>
+                        <span class="title">{{trans('home.tickets')}}</span>
                     </a>
                 </li>
                 @if(Session::get('referral_status'))
                 <li class="nav-item {{Request::getRequestUri() == '/user/referral' ? 'active open' : ''}}">
                     <a href="{{url('user/referral')}}" class="nav-link nav-toggle">
                         <i class="icon-diamond"></i>
-                        <span class="title">推广返利</span>
+                        <span class="title">{{trans('home.referrals')}}</span>
                     </a>
                 </li>
                 @endif

+ 25 - 14
resources/views/user/orderList.blade.php

@@ -9,7 +9,7 @@
         }
     </style>
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top: 0;">
@@ -21,7 +21,7 @@
                     <div class="portlet-title">
                         <div class="caption font-dark">
                             <i class="icon-wallet font-dark"></i>
-                            <span class="caption-subject bold uppercase"> 消费记录 </span>
+                            <span class="caption-subject bold"> {{trans('home.invoice_title')}} </span>
                         </div>
                     </div>
                     <div class="portlet-body">
@@ -29,28 +29,42 @@
                             <table class="table table-striped table-bordered table-hover table-checkable order-column">
                                 <thead>
                                     <tr>
-                                        <th> ID </th>
-                                        <th> 订单编号 </th>
-                                        <th> 商品信息 </th>
-                                        <th> 创建时间 </th>
+                                        <th> # </th>
+                                        <th> {{trans('home.invoice_table_name')}} </th>
+                                        <th> {{trans('home.invoice_table_price')}} </th>
+                                        <th> {{trans('home.invoice_table_create_date')}} </th>
+                                        <th> {{trans('home.invoice_table_status')}} </th>
                                     </tr>
                                 </thead>
                                 <tbody>
                                 @if($orderList->isEmpty())
                                     <tr>
-                                        <td colspan="4">暂无数据</td>
+                                        <td colspan="4">{{trans('home.invoice_table_none')}}</td>
                                     </tr>
                                 @else
                                     @foreach($orderList as $key => $order)
                                         <tr class="odd gradeX">
                                             <td> {{$key + 1}} </td>
-                                            <td> {{$order->orderId}} </td>
                                             <td>
                                                 @foreach($order->goodsList as $goods)
-                                                    {{$goods->goods_name}}(¥{{$goods->price}})
+                                                    {{$goods->goods_name}}
                                                 @endforeach
                                             </td>
-                                            <td>{{$order->created_at}}</td>
+                                            <td>¥{{$order->totalPrice / 100}}</td>
+                                            <td>{{date('Y-m-d', strtotime($order->created_at))}}</td>
+                                            <td>
+                                                @if($order->status == -1)
+                                                    <span class="label label-default"> {{trans('home.invoice_table_closed')}} </span>
+                                                @elseif($order->status == 0)
+                                                    <span class="label label-default"> {{trans('home.invoice_table_wait_payment')}} </span>
+                                                @elseif($order->status == 1)
+                                                    <span class="label label-danger"> {{trans('home.invoice_table_wait_confirm')}} </span>
+                                                @elseif($order->status == 2)
+                                                    <span class="label label-success"> {{trans('home.invoice_table_wait_active')}} </span>
+                                                @else
+                                                    <span class="label label-default"> {{trans('home.invoice_table_expired')}} </span>
+                                                @endif
+                                            </td>
                                         </tr>
                                     @endforeach
                                 @endif
@@ -58,10 +72,7 @@
                             </table>
                         </div>
                         <div class="row">
-                            <div class="col-md-5 col-sm-5">
-                                <div class="dataTables_info" role="status" aria-live="polite">共 {{$orderList->total()}} 个记录</div>
-                            </div>
-                            <div class="col-md-7 col-sm-7">
+                            <div class="col-md-12 col-sm-12">
                                 <div class="dataTables_paginate paging_bootstrap_full_number pull-right">
                                     {{ $orderList->links() }}
                                 </div>

+ 10 - 5
resources/views/user/profile.blade.php

@@ -3,7 +3,7 @@
 @section('css')
     <link href="/assets/pages/css/profile.min.css" rel="stylesheet" type="text/css" />
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content">
@@ -41,7 +41,7 @@
                                             <a href="#tab_1" data-toggle="tab">登录密码</a>
                                         </li>
                                         <li>
-                                            <a href="#tab_2" data-toggle="tab">SS(R)信息</a>
+                                            <a href="#tab_2" data-toggle="tab">通信配置</a>
                                         </li>
                                     </ul>
                                 </div>
@@ -70,13 +70,18 @@
                                         <div class="tab-pane" id="tab_2">
                                             <form action="{{url('user/profile')}}" method="post" enctype="multipart/form-data" class="form-bordered">
                                                 <div class="form-group">
-                                                    <label class="control-label"> 端口 </label>
-                                                    <input type="text" class="form-control" name="port" value="{{$info->port}}" id="port" readonly />
-                                                    <input type="hidden" name="_token" value="{{csrf_token()}}" />
+                                                    <label class="control-label"> 微信 </label>
+                                                    <input type="text" class="form-control" name="wechat" value="{{$info->wechat}}" id="wechat" required />
+                                                </div>
+                                                <div class="form-group">
+                                                    <label class="control-label"> QQ </label>
+                                                    <input type="text" class="form-control" name="qq" value="{{$info->qq}}" id="qq" required />
                                                 </div>
+                                                <hr />
                                                 <div class="form-group">
                                                     <label class="control-label"> 连接密码 </label>
                                                     <input type="text" class="form-control" name="passwd" value="{{$info->passwd}}" id="passwd" required />
+                                                    <input type="hidden" name="_token" value="{{csrf_token()}}" />
                                                 </div>
                                                 <div class="form-group">
                                                     <label class="control-label"> 加密方式 </label>

+ 22 - 18
resources/views/user/referral.blade.php

@@ -9,28 +9,32 @@
         }
     </style>
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
         <!-- BEGIN PAGE BASE CONTENT -->
         <div class="row">
             <div class="col-md-12">
-                <div class="alert alert-danger">
-                    通过您的推广链接注册的账号可以获得 <code>{{$referral_traffic}}流量</code> 奖励。您可以获得他们每笔消费的<code>{{$referral_percent * 100}}%现金</code>返利。累计满 <code>{{$referral_money}}元</code>,就可以申请提现至微信或者支付宝。
+                <div class="note note-info">
+                    <p> 通过您的推广链接注册的用户可获得 {{$referral_traffic}} 流量奖励。您可以获得他们每笔消费金额的 {{$referral_percent * 100}}% 作为现金返利。 </p>
                 </div>
+            </div>
+        </div>
+        <div class="row">
+            <div class="col-md-12">
                 <div class="portlet light form-fit bordered">
                     <div class="portlet-title">
                         <div class="caption">
                             <i class="icon-link font-blue"></i>
-                            <span class="caption-subject font-blue bold uppercase">我的推广链接</span>
+                            <span class="caption-subject font-blue bold">{{trans('home.referral_my_link')}}</span>
                         </div>
                     </div>
                     <div class="portlet-body form">
                         <div class="mt-clipboard-container">
                             <input type="text" id="mt-target-1" class="form-control" value="{{$link}}" />
                             <a href="javascript:;" class="btn blue mt-clipboard" data-clipboard-action="copy" data-clipboard-target="#mt-target-1">
-                                <i class="icon-note"></i> 复制链接
+                                <i class="icon-note"></i> {{trans('home.referral_button')}}
                             </a>
                         </div>
                     </div>
@@ -40,37 +44,37 @@
                     <div class="portlet-title">
                         <div class="caption font-dark">
                             <i class="icon-diamond font-dark"></i>
-                            <span class="caption-subject bold uppercase"> 推广返利 </span>
+                            <span class="caption-subject bold"> {{trans('home.referral_title')}} </span>
                         </div>
                         <div class="actions">
-                            <button type="submit" class="btn red" onclick="extractMoney()"><i class="fa fa-money"></i> 申请提现</button>
+                            <button type="submit" class="btn red" onclick="extractMoney()"><i class="fa fa-money"></i> {{trans('home.referral_table_apply')}} </button>
                         </div>
                     </div>
                     <div class="portlet-body">
                         <div class="table-scrollable">
-                            <table class="table table-striped table-bordered table-hover table-checkable order-column" id="sample_1">
+                            <table class="table table-striped table-bordered table-hover table-checkable order-column">
                                 <thead>
                                 <tr>
-                                    <th> ID </th>
-                                    <th> 消费者 </th>
-                                    <th> 消费金额 </th>
-                                    <th> 返利金额 </th>
-                                    <th> 状态 </th>
-                                    <th> 返利时间 </th>
+                                    <th> # </th>
+                                    <th> {{trans('home.referral_table_user')}} </th>
+                                    <th> {{trans('home.referral_table_amount')}} </th>
+                                    <th> {{trans('home.referral_table_commission')}} </th>
+                                    <th> {{trans('home.referral_table_status')}} </th>
+                                    <th> {{trans('home.referral_table_date')}} </th>
                                 </tr>
                                 </thead>
                                 <tbody>
                                 @if($referralLogList->isEmpty())
                                     <tr>
-                                        <td colspan="6">暂无数据</td>
+                                        <td colspan="5"> {{trans('home.referral_table_none')}} </td>
                                     </tr>
                                 @else
                                     @foreach($referralLogList as $key => $referralLog)
                                         <tr class="odd gradeX">
                                             <td> {{$key + 1}} </td>
                                             <td> {{$referralLog->user->username}} </td>
-                                            <td> {{$referralLog->amount}} </td>
-                                            <td> {{$referralLog->ref_amount}} </td>
+                                            <td> {{$referralLog->amount}} </td>
+                                            <td> {{$referralLog->ref_amount}} </td>
                                             <td>
                                                 @if ($referralLog->status == 1)
                                                     <span class="label label-sm label-danger">申请中</span>
@@ -88,7 +92,7 @@
                         </div>
                         <div class="row">
                             <div class="col-md-4 col-sm-4">
-                                <div class="dataTables_info" role="status" aria-live="polite">共 {{$referralLogList->total()}} 条记录,合计返利<code>{{$canAmount}}元</code></div>
+                                <div class="dataTables_info" role="status" aria-live="polite">共 {{$referralLogList->total()}} 条记录,合计返利<code>{{$canAmount}}</code>,满 <code>{{$referral_money}}</code> 元可申请提现。</div>
                             </div>
                             <div class="col-md-8 col-sm-8">
                                 <div class="dataTables_paginate paging_bootstrap_full_number pull-right">

+ 1 - 1
resources/views/user/replyTicket.blade.php

@@ -4,7 +4,7 @@
     <link href="/assets/global/plugins/datatables/datatables.min.css" rel="stylesheet" type="text/css" />
     <link href="/assets/global/plugins/datatables/plugins/bootstrap/datatables.bootstrap.css" rel="stylesheet" type="text/css" />
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content">

+ 10 - 17
resources/views/user/subscribe.blade.php

@@ -9,39 +9,32 @@
         }
     </style>
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
-    <div class="page-content">
-        <!-- BEGIN PAGE BREADCRUMB -->
-        <ul class="page-breadcrumb breadcrumb">
-            <li>
-                <a href="{{url('user/nodeList')}}">节点列表</a>
-                <i class="fa fa-circle"></i>
-            </li>
-            <li>
-                <a href="{{url('user/subscribe')}}">订阅</a>
-            </li>
-        </ul>
-        <!-- END PAGE BREADCRUMB -->
+    <div class="page-content" style="padding-top:0;">
         <!-- BEGIN PAGE BASE CONTENT -->
         <div class="row">
             <div class="col-md-12">
-                <div class="alert alert-danger">
-                    <strong>警告:</strong>该订阅地址仅限个人使用,请勿传播该地址,否则会导致您的账号流量异常。
+                <div class="note note-danger">
+                    <p> {{trans('home.subscribe_warning')}} </p>
                 </div>
+            </div>
+        </div>
+        <div class="row">
+            <div class="col-md-12">
                 <div class="portlet light form-fit bordered">
                     <div class="portlet-title">
                         <div class="caption">
                             <i class="icon-link font-blue"></i>
-                            <span class="caption-subject font-blue bold uppercase">订阅地址</span>
+                            <span class="caption-subject font-blue bold">{{trans('home.subscribe_address')}}</span>
                         </div>
                     </div>
                     <div class="portlet-body form">
                         <div class="mt-clipboard-container">
                             <input type="text" id="mt-target-1" class="form-control" value="{{$link}}" />
                             <a href="javascript:;" class="btn blue mt-clipboard" data-clipboard-action="copy" data-clipboard-target="#mt-target-1">
-                                <i class="icon-note"></i> 复制链接
+                                <i class="icon-note"></i> {{trans('home.copy_subscribe_address')}}
                             </a>
                         </div>
                     </div>

+ 18 - 21
resources/views/user/ticketList.blade.php

@@ -4,7 +4,7 @@
     <link href="/assets/global/plugins/datatables/datatables.min.css" rel="stylesheet" type="text/css" />
     <link href="/assets/global/plugins/datatables/plugins/bootstrap/datatables.bootstrap.css" rel="stylesheet" type="text/css" />
 @endsection
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
@@ -16,11 +16,11 @@
                     <div class="portlet-title">
                         <div class="caption font-dark">
                             <i class="icon-question font-dark"></i>
-                            <span class="caption-subject bold uppercase"> 工单列表 </span>
+                            <span class="caption-subject bold"> {{trans('home.ticket_title')}} </span>
                         </div>
                         <div class="actions">
                             <div class="btn-group">
-                                <button class="btn sbold blue" data-toggle="modal" data-target="#charge_modal"> 发起工单 </button>
+                                <button class="btn sbold blue" data-toggle="modal" data-target="#charge_modal"> {{trans('home.ticket_table_new_button')}} </button>
                             </div>
                         </div>
                     </div>
@@ -28,16 +28,16 @@
                         <div class="table-scrollable">
                             <table class="table table-striped table-bordered table-hover table-checkable order-column">
                                 <thead>
-                                <tr>
-                                    <th> ID </th>
-                                    <th> 标题 </th>
-                                    <th> 状态 </th>
-                                </tr>
+                                    <tr>
+                                        <th> # </th>
+                                        <th> {{trans('home.ticket_table_title')}} </th>
+                                        <th> {{trans('home.ticket_table_status')}} </th>
+                                    </tr>
                                 </thead>
                                 <tbody>
                                 @if($ticketList->isEmpty())
                                     <tr>
-                                        <td colspan="4">暂无数据</td>
+                                        <td colspan="4"> {{trans('home.ticket_table_none')}} </td>
                                     </tr>
                                 @else
                                     @foreach($ticketList as $key => $ticket)
@@ -46,11 +46,11 @@
                                             <td> <a href="{{url('user/replyTicket?id=') . $ticket->id}}" target="_blank">{{$ticket->title}}</a> </td>
                                             <td>
                                                 @if ($ticket->status == 0)
-                                                    <span class="label label-info"> 待处理 </span>
+                                                    <span class="label label-info"> {{trans('home.ticket_table_status_wait')}} </span>
                                                 @elseif ($ticket->status == 1)
-                                                    <span class="label label-danger"> 已回复 </span>
+                                                    <span class="label label-danger"> {{trans('home.ticket_table_status_reply')}} </span>
                                                 @else
-                                                    <span class="label label-default"> 已关闭 </span>
+                                                    <span class="label label-default"> {{trans('home.ticket_table_status_close')}} </span>
                                                 @endif
                                             </td>
                                         </tr>
@@ -60,10 +60,7 @@
                             </table>
                         </div>
                         <div class="row">
-                            <div class="col-md-4 col-sm-4">
-                                <div class="dataTables_info" role="status" aria-live="polite">共 {{$ticketList->total()}} 个工单</div>
-                            </div>
-                            <div class="col-md-8 col-sm-8">
+                            <div class="col-md-12 col-sm-12">
                                 <div class="dataTables_paginate paging_bootstrap_full_number pull-right">
                                     {{ $ticketList->links() }}
                                 </div>
@@ -79,15 +76,15 @@
                 <div class="modal-content">
                     <div class="modal-header">
                         <button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
-                        <h4 class="modal-title"> 发起工单 </h4>
+                        <h4 class="modal-title"> {{trans('home.ticket_table_new_button')}} </h4>
                     </div>
                     <div class="modal-body">
-                        <input type="text" name="title" id="title" placeholder="工单标题" class="form-control margin-bottom-20">
-                        <textarea name="content" id="content" placeholder="请填写您的问题,如果图片请提交工单后在回复处上传图片" class="form-control margin-bottom-20" rows="4"></textarea>
+                        <input type="text" name="title" id="title" placeholder="{{trans('home.ticket_table_title')}}" class="form-control margin-bottom-20">
+                        <textarea name="content" id="content" placeholder="{{trans('home.ticket_table_new_desc')}}" class="form-control margin-bottom-20" rows="4"></textarea>
                     </div>
                     <div class="modal-footer">
-                        <button type="button" data-dismiss="modal" class="btn red btn-outline">关闭</button>
-                        <button type="button" data-dismiss="modal" class="btn green btn-outline" onclick="addTicket()">提交</button>
+                        <button type="button" data-dismiss="modal" class="btn dark btn-outline"> {{trans('home.ticket_table_new_cancel')}} </button>
+                        <button type="button" data-dismiss="modal" class="btn green btn-outline" onclick="addTicket()"> {{trans('home.ticket_table_new_yes')}} </button>
                     </div>
                 </div>
             </div>

+ 6 - 6
resources/views/user/trafficLog.blade.php

@@ -3,7 +3,7 @@
 @section('css')
 @endsection
 
-@section('title', '控制面板')
+@section('title', trans('home.panel'))
 @section('content')
     <!-- BEGIN CONTENT BODY -->
     <div class="page-content" style="padding-top:0;">
@@ -11,7 +11,7 @@
         <div class="row">
             <div class="col-md-12">
                 <div class="note note-info">
-                    <p> 提示:30日内流量统计不会统计当天,24小时内流量统计不会统计当前小时;如果无统计数据,请检查定时任务是否正常。 </p>
+                    <p> {{trans('home.traffic_log_tips')}} </p>
                 </div>
             </div>
         </div>
@@ -45,7 +45,7 @@
 
         option = {
             title: {
-                text: '30日内流量消耗情况',
+                text: '{{trans('home.traffic_log_30days')}}',
                 subtext: '单位M'
             },
             tooltip: {
@@ -71,7 +71,7 @@
             series: [
                 @if(!empty($trafficDaily))
                 {
-                    name:'消耗流量',
+                    name:'{{trans('home.traffic_log_keywords')}}',
                     type:'line',
                     data:[{!! $trafficDaily !!}],
                     markPoint: {
@@ -91,7 +91,7 @@
 
         option = {
             title: {
-                text: '24小时内流量消耗情况',
+                text: '{{trans('home.traffic_log_24hours')}}',
                 subtext: '单位M'
             },
             tooltip: {
@@ -117,7 +117,7 @@
             series: [
                 @if(!empty($trafficHourly))
                 {
-                    name:'消耗流量',
+                    name:'{{trans('home.traffic_log_keywords')}}',
                     type:'line',
                     data:[{!! $trafficHourly !!}],
                     markPoint: {

+ 5 - 0
routes/web.php

@@ -15,6 +15,7 @@ Route::group(['middleware' => ['user', 'admin']], function() {
     Route::get('admin', 'AdminController@index'); // 后台首页
     Route::get('admin/userList', 'AdminController@userList'); // 账号列表
     Route::any('admin/addUser', 'AdminController@addUser'); // 添加账号
+    Route::post('admin/batchAddUsers', 'AdminController@batchAddUsers'); // 批量生成账号
     Route::any('admin/editUser', 'AdminController@editUser'); // 编辑账号
     Route::post('admin/delUser', 'AdminController@delUser'); // 删除账号
     Route::get('admin/nodeList', 'AdminController@nodeList'); // 节点列表
@@ -102,3 +103,7 @@ Route::group(['middleware' => ['user']], function() {
     Route::post('user/extractMoney', 'UserController@extractMoney'); // 申请提现
     Route::post("user/switchToAdmin","UserController@switchToAdmin"); // 转换成管理员的身份
 });
+
+//Route::group(['middleware' => ['user']], function() {
+    Route::any('payment/create', 'PaymentController@create');
+//});

+ 2 - 0
sql/db.sql

@@ -288,6 +288,8 @@ INSERT INTO `config` VALUES ('35', 'traffic_ban_time', 60);
 INSERT INTO `config` VALUES ('36', 'is_clear_log', 1);
 INSERT INTO `config` VALUES ('37', 'is_node_crash_warning', 0);
 INSERT INTO `config` VALUES ('38', 'crash_warning_email', '');
+INSERT INTO `config` VALUES ('39', 'is_server_chan', 0);
+INSERT INTO `config` VALUES ('40', 'server_chan_key', '');
 
 
 -- ----------------------------

+ 3 - 0
sql/update/20171210.sql

@@ -0,0 +1,3 @@
+-- ServerChan微信推送节点宕机消息
+INSERT INTO `config` VALUES ('39', 'is_server_chan', 0);
+INSERT INTO `config` VALUES ('40', 'server_chan_key', '');