xiang 6 سال پیش
والد
کامیت
92725075a0
100فایلهای تغییر یافته به همراه8239 افزوده شده و 4818 حذف شده
  1. 129 0
      README.md
  2. 4 20
      application/admin/config.php
  3. 53 0
      application/admin/controller/Common.php
  4. 340 97
      application/admin/controller/Index.php
  5. 44 0
      application/admin/controller/Lang.php
  6. 51 77
      application/admin/controller/Login.php
  7. 9 0
      application/admin/lang/en-us.php
  8. 39 0
      application/admin/lang/zh-cn.php
  9. 169 0
      application/admin/model/Admin.php
  10. 150 0
      application/admin/model/Message.php
  11. 276 0
      application/admin/model/Platform.php
  12. 64 0
      application/admin/model/Upload.php
  13. 140 0
      application/admin/model/User.php
  14. 109 0
      application/admin/model/UserPlatform.php
  15. 43 0
      application/admin/validate/Admin.php
  16. 39 0
      application/admin/validate/Common.php
  17. 38 0
      application/admin/validate/Platform.php
  18. 32 0
      application/admin/validate/User.php
  19. 35 0
      application/admin/validate/UserPlatform.php
  20. 262 0
      application/admin/view/index/addplatform.html
  21. 142 520
      application/admin/view/index/index.html
  22. 98 0
      application/admin/view/index/messageInfo.html
  23. 233 0
      application/admin/view/index/messagelist.html
  24. 290 0
      application/admin/view/index/platformlist.html
  25. 189 0
      application/admin/view/index/platformuser.html
  26. 280 0
      application/admin/view/index/updateplatform.html
  27. 274 0
      application/admin/view/index/userlist.html
  28. 14 0
      application/admin/view/layout/footer.html
  29. 83 0
      application/admin/view/layout/header.html
  30. 94 0
      application/admin/view/layout/navigation.html
  31. 86 0
      application/admin/view/login/login.html
  32. 177 133
      application/common.php
  33. 239 21
      application/config.php
  34. 10 6
      application/database.php
  35. 14 0
      application/extra/queue.php
  36. 5 3
      application/index/config.php
  37. 21 16
      application/index/controller/Common.php
  38. 354 98
      application/index/controller/Index.php
  39. 44 0
      application/index/controller/Lang.php
  40. 107 59
      application/index/controller/Login.php
  41. 9 0
      application/index/lang/en-us.php
  42. 52 0
      application/index/lang/zh-cn.php
  43. 45 0
      application/index/model/Code.php
  44. 245 0
      application/index/model/Message.php
  45. 14 0
      application/index/model/MessageUser.php
  46. 55 0
      application/index/model/MessageVerify.php
  47. 264 0
      application/index/model/Platform.php
  48. 56 0
      application/index/model/PlatformUser.php
  49. 360 0
      application/index/model/User.php
  50. 102 0
      application/index/model/UserPlatform.php
  51. 28 0
      application/index/validate/Message.php
  52. 30 0
      application/index/validate/Platform.php
  53. 43 0
      application/index/validate/User.php
  54. 4 4
      build.php
  55. 40 38
      composer.json
  56. 5 6
      public/.htaccess
  57. BIN
      public/favicon.ico
  58. 5 13
      public/index.php
  59. 0 3
      public/router.php
  60. 2 0
      public/static/.gitignore
  61. BIN
      public/uploads/20190923/1077da179d335f32c78eec9b68a920fc.jpeg
  62. BIN
      public/uploads/20190923/a4fd59e8776a1d171ac8d4336e2da680.jpeg
  63. 20 0
      tests/ExampleTest.php
  64. 16 0
      tests/TestCase.php
  65. 1 1
      think
  66. 2 2
      thinkphp/CONTRIBUTING.md
  67. 1 1
      thinkphp/LICENSE.txt
  68. 3 4
      thinkphp/README.md
  69. 2 4
      thinkphp/base.php
  70. 1 1
      thinkphp/console.php
  71. 9 19
      thinkphp/convention.php
  72. 12 16
      thinkphp/helper.php
  73. 51 120
      thinkphp/lang/zh-cn.php
  74. 221 331
      thinkphp/library/think/App.php
  75. 67 98
      thinkphp/library/think/Build.php
  76. 69 85
      thinkphp/library/think/Cache.php
  77. 118 212
      thinkphp/library/think/Collection.php
  78. 58 102
      thinkphp/library/think/Config.php
  79. 122 266
      thinkphp/library/think/Console.php
  80. 45 62
      thinkphp/library/think/Controller.php
  81. 66 123
      thinkphp/library/think/Cookie.php
  82. 28 57
      thinkphp/library/think/Db.php
  83. 46 86
      thinkphp/library/think/Debug.php
  84. 5 13
      thinkphp/library/think/Env.php
  85. 28 47
      thinkphp/library/think/Error.php
  86. 10 11
      thinkphp/library/think/Exception.php
  87. 88 155
      thinkphp/library/think/File.php
  88. 25 37
      thinkphp/library/think/Hook.php
  89. 47 95
      thinkphp/library/think/Lang.php
  90. 193 305
      thinkphp/library/think/Loader.php
  91. 77 106
      thinkphp/library/think/Log.php
  92. 169 558
      thinkphp/library/think/Model.php
  93. 16 56
      thinkphp/library/think/Paginator.php
  94. 132 220
      thinkphp/library/think/Request.php
  95. 10 14
      thinkphp/library/think/Response.php
  96. 162 217
      thinkphp/library/think/Route.php
  97. 3 4
      thinkphp/library/think/Session.php
  98. 38 26
      thinkphp/library/think/Template.php
  99. 18 32
      thinkphp/library/think/Url.php
  100. 121 218
      thinkphp/library/think/Validate.php

+ 129 - 0
README.md

@@ -0,0 +1,129 @@
+ThinkPHP 5.0
+===============
+
+[![Total Downloads](https://poser.pugx.org/topthink/think/downloads)](https://packagist.org/packages/topthink/think)
+[![Latest Stable Version](https://poser.pugx.org/topthink/think/v/stable)](https://packagist.org/packages/topthink/think)
+[![Latest Unstable Version](https://poser.pugx.org/topthink/think/v/unstable)](https://packagist.org/packages/topthink/think)
+[![License](https://poser.pugx.org/topthink/think/license)](https://packagist.org/packages/topthink/think)
+
+ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,对已有的CBD模式做了更深的强化,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括:
+
+ + 基于命名空间和众多PHP新特性
+ + 核心功能组件化
+ + 强化路由功能
+ + 更灵活的控制器
+ + 重构的模型和数据库类
+ + 配置文件可分离
+ + 重写的自动验证和完成
+ + 简化扩展机制
+ + API支持完善
+ + 改进的Log类
+ + 命令行访问支持
+ + REST支持
+ + 引导文件支持
+ + 方便的自动生成定义
+ + 真正惰性加载
+ + 分布式环境支持
+ + 更多的社交类库
+
+> ThinkPHP5的运行环境要求PHP5.4以上。
+
+详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5)
+
+## 目录结构
+
+初始的目录结构如下:
+
+~~~
+www  WEB部署目录(或者子目录)
+├─application           应用目录
+│  ├─common             公共模块目录(可以更改)
+│  ├─module_name        模块目录
+│  │  ├─config.php      模块配置文件
+│  │  ├─common.php      模块函数文件
+│  │  ├─controller      控制器目录
+│  │  ├─model           模型目录
+│  │  ├─view            视图目录
+│  │  └─ ...            更多类库目录
+│  │
+│  ├─command.php        命令行工具配置文件
+│  ├─common.php         公共函数文件
+│  ├─config.php         公共配置文件
+│  ├─route.php          路由配置文件
+│  ├─tags.php           应用行为扩展定义文件
+│  └─database.php       数据库配置文件
+│
+├─public                WEB目录(对外访问目录)
+│  ├─index.php          入口文件
+│  ├─router.php         快速测试文件
+│  └─.htaccess          用于apache的重写
+│
+├─thinkphp              框架系统目录
+│  ├─lang               语言文件目录
+│  ├─library            框架类库目录
+│  │  ├─think           Think类库包目录
+│  │  └─traits          系统Trait目录
+│  │
+│  ├─tpl                系统模板目录
+│  ├─base.php           基础定义文件
+│  ├─console.php        控制台入口文件
+│  ├─convention.php     框架惯例配置文件
+│  ├─helper.php         助手函数文件
+│  ├─phpunit.xml        phpunit配置文件
+│  └─start.php          框架入口文件
+│
+├─extend                扩展类库目录
+├─runtime               应用的运行时目录(可写,可定制)
+├─vendor                第三方类库目录(Composer依赖库)
+├─build.php             自动生成定义文件(参考)
+├─composer.json         composer 定义文件
+├─LICENSE.txt           授权说明文件
+├─README.md             README 文件
+├─think                 命令行入口文件
+~~~
+
+> router.php用于php自带webserver支持,可用于快速测试
+> 切换到public目录后,启动命令:php -S localhost:8888  router.php
+> 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。
+
+## 命名规范
+
+`ThinkPHP5`遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范:
+
+### 目录和文件
+
+*   目录不强制规范,驼峰和小写+下划线模式均支持;
+*   类库、函数文件统一以`.php`为后缀;
+*   类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;
+*   类名和类文件名保持一致,统一采用驼峰法命名(首字母大写);
+
+### 函数和类、属性命名
+*   类的命名采用驼峰法,并且首字母大写,例如 `User`、`UserType`,默认不需要添加后缀,例如`UserController`应该直接命名为`User`;
+*   函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 `get_client_ip`;
+*   方法的命名使用驼峰法,并且首字母小写,例如 `getUserName`;
+*   属性的命名使用驼峰法,并且首字母小写,例如 `tableName`、`instance`;
+*   以双下划线“__”打头的函数或方法作为魔法方法,例如 `__call` 和 `__autoload`;
+
+### 常量和配置
+*   常量以大写字母和下划线命名,例如 `APP_PATH`和 `THINK_PATH`;
+*   配置参数以小写字母和下划线命名,例如 `url_route_on` 和`url_convert`;
+
+### 数据表和字段
+*   数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例如 `think_user` 表和 `user_name`字段,不建议使用驼峰和中文作为数据表字段命名。
+
+## 参与开发
+请参阅 [ThinkPHP5 核心框架包](https://github.com/top-think/framework)。
+
+## 版权信息
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+
+本项目包含的第三方源码和二进制文件之版权信息另行标注。
+
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
+
+All rights reserved。
+
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+更多细节参阅 [LICENSE.txt](LICENSE.txt)

+ 4 - 20
application/admin/config.php

@@ -5,27 +5,11 @@ return [
     // 模板参数替换
     'view_replace_str' => [
         '__CSS__' => '/static/admin/css',
+        '__DATA__' => '/static/admin/data',
+        '__FONTS__' => '/static/admin/fonts',
         '__JS__'  => '/static/admin/js',
-        '__IMG__' => '/static/admin/images',
-        '__EDIT__' => '/static/kindeditor',
-        '__ENTRANCE__' => '/static/entranceJs',
+        '__IMG__' => '/static/admin/img',
+        '__VENDOR__' => '/static/admin/vendor',
     ],
 
-    // 客服状态
-    'kf_status' => [
-        1 => '启用',
-        2 => '禁用'
-    ],
-
-    // 客服状态
-    'host' => [
-        1 => '是',
-        2 => '否'
-    ],
-
-    // 是否在线
-    'online' => [
-        1 => '在线',
-        2 => '离线'
-    ]
 ];

+ 53 - 0
application/admin/controller/Common.php

@@ -0,0 +1,53 @@
+<?php
+namespace app\admin\controller;
+
+use think\Controller;
+use think\Exception;
+use think\Request;
+use think\Session;
+use think\Log;
+use think\cache\driver\Redis;
+
+class Common extends Controller
+{
+
+
+    /**
+     * 构造函数.
+     *
+     * @access public
+     * @return string
+     */
+    public function _initialize()
+    {
+        // 验证是否登陆.
+        if (!Session::has('admin')) {
+            return $this->redirect('Admin/Login/login');
+        }
+
+    }//end _initialize()
+
+
+    /**
+     * 获取当前模块.
+     */
+    protected function getModular()
+    {
+        $request    = Request::instance();
+        $controller = $request->controller();
+        $module     = $request->module();
+        $action     = $request->action();
+        $path       = $request->path();
+        $data       = [
+            'controller' => $controller,
+            'module'     => $module,
+            'action'     => $action,
+            'path'       => $path,
+        ];
+
+        return $data;
+
+    }//end getModular()
+
+
+}

+ 340 - 97
application/admin/controller/Index.php

@@ -1,152 +1,395 @@
 <?php
 namespace app\admin\controller;
 
-class Index extends Base
+use think\Controller;
+use think\Exception;
+use think\Session;
+use think\Request;
+use think\Log;
+use think\cache\driver\Redis;
+
+class Index extends Common
 {
-    // 后台总体框架
+
+
+    /**
+     * 主页显示
+     *
+     * @access public
+     * @return string
+     */
     public function index()
     {
-        return $this->fetch('/index');
-    }
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+
+        // 传递参数.
+        $this->assign([
+            'adminInfo' => $adminInfo,
+            'getPath'   => $getModular['path'],
+            'getAction' => $getModular['action'],
+        ]);
+
+        return $this->fetch();
+
+    }//end index()
+
 
-    // 后台默认首页
-    public function indexPage()
+    /**
+     * 用户列表
+     *
+     * @access public
+     * @return string
+     */
+    public function userList()
     {
-        $groups = model('Groups')->selectGroups();
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取用户列表.
+        $userList = model('User')->userList();
+
+        // 传递参数.
         $this->assign([
-            'socket' => config('socket'),
-            'token' => session('token'),
-            'groups' => $groups,
+            'adminInfo'   => $adminInfo,
+            'getPath'     => $getModular['path'],
+            'getAction'   => $getModular['action'],
+            'userList'    => $userList['data']['userList'],
+            'page'        => $userList['data']['page'],
+            'currentPage' => $userList['data']['currentPage'],
         ]);
 
+        return $this->fetch('userlist');
 
+    }//end userList()
 
-        $data = db('now_data')->where('id', 1)->find();
 
-        // 生成从 8点 到 22点的时间数组
-        $dateLine = array_map(function($vo){
-            if($vo < 10){
-                return '0' . $vo;
-            }else{
-                return $vo;
-            }
-        }, range(8, 22));
-
-        // 初始化数据
-        $line = [];
-        foreach($dateLine as $key=>$vo){
-            $line[$vo] = [
-                'is_talking' => 0,
-                'in_queue' => 0,
-                'success_in' => 0,
-                'total_in' => 0
-            ];
+    /**
+     * 修改用户
+     *
+     * @access public
+     * @return string
+     */
+    public function updateUser()
+    {
+
+        try {
+            model('User')->updateUser();
+        } catch (\Exception $e) {
+            Log::write($e->getMessage(), 'error');
+            return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
         }
 
+        return json(['code' => 1, 'data' => '', 'msg' => lang('MC01004')]);
 
-        //$dbData = db('service_data')->where('add_date',date('Y-m-d'))->group('add_hour')->select();
-        $dbData = db('service_data')->where('add_date',date('Y-m-d'))->select();
+    }//end updateUser()
 
-        foreach($line as $key=>$vo){
-            foreach($dbData as $k=>$v){
-                if($v['add_hour'] == $key){
-                    $line[$key]['is_talking'] = $v['is_talking'];
-                    $line[$key]['in_queue'] = $v['in_queue'];
-                    $line[$key]['success_in'] = $v['success_in'];
-                    $line[$key]['total_in'] = $v['total_in'];
 
-                    unset($dbData[$k]);
-                    continue;
-                }
-            }
-        }
+    /**
+     * 平台列表
+     *
+     * @access public
+     * @return string
+     */
+    public function platformList()
+    {
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取平台列表.
+        $platformList = model('Platform')->platformList();
+
+        // 传递参数.
+        $this->assign([
+            'adminInfo'    => $adminInfo,
+            'getPath'      => $getModular['path'],
+            'getAction'    => $getModular['action'],
+            'platformList' => $platformList['data']['platformList'],
+            'page'         => $platformList['data']['page'],
+            'currentPage'  => $platformList['data']['currentPage'],
+        ]);
 
+        return $this->fetch('platformlist');
 
-        $showData = [];
-        foreach($line as $key=>$vo){
-            $showData['is_talking'][] = $vo['is_talking'];
-            $showData['in_queue'][] = $vo['in_queue'];
-            $showData['success_in'][] = $vo['success_in'];
-            $showData['total_in'][] = $vo['total_in'];
+    }//end platformList()
+
+
+    /**
+     * 修改平台
+     *
+     * @access public
+     * @return string
+     */
+    public function updatePlatform()
+    {
+        if(request()->isAjax()) {
+            try {
+                $back = model('Platform')->updatePlatform();
+            } catch (\Exception $e) {
+                Log::write($e->getMessage(), 'error');
+                return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
+            }
+
+            return json($back);
         }
 
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取平台数据.
+        $platform = model('Platform')->platform();
+
+        // 传递参数.
         $this->assign([
-            'data' => $data,
-            'show_data' => json_encode($showData)
+            'adminInfo' => $adminInfo,
+            'getPath'   => $getModular['path'],
+            'getAction' => $getModular['action'],
+            'platform'  => $platform['data']['platform'],
         ]);
+        return $this->fetch('updateplatform');
+
+    }//end updatePlatform()
+
+
+    /**
+     * 删除所选平台
+     *
+     * @access public
+     * @return string
+     */
+    public function delPlatform()
+    {
+        $ids = $_GET['ids'];
+
+        try {
+            $back = model('Platform')->delPlatform($ids);
+        } catch (\Exception $e) {
+            Log::write($e->getMessage(), 'error');
+            return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
+        }
+
+        return json(['code' => 1, 'data' => $ids, 'msg' => lang('MC01003')]);
 
-        return $this->fetch('index');
     }
 
-    // 清除缓存
-    public function clear()
+    /**
+     * 删除所选用户
+     *
+     * @access public
+     * @return string
+     */
+    public function delUser()
     {
-        if (false === removeDir(RUNTIME_PATH)) {
-            return json(['code' => -1, 'data' => '', 'msg' => '清除缓存失败']);
+        $ids = $_GET['ids'];
+
+        try {
+            $back = model('User')->delUser($ids);
+        } catch (\Exception $e) {
+            Log::write($e->delUser(), 'error');
+            return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
         }
-        return json(['code' => 1, 'data' => '', 'msg' => '清除缓存成功']);
+
+        return json(['code' => 1, 'data' => $ids, 'msg' => lang('MC01003')]);
+
     }
 
-    // 修改管理员密码
-    public function changePassword()
+    /**
+     * 删除所选消息
+     *
+     * @access public
+     * @return string
+     */
+    public function delMessage()
     {
-//        $token = session('token');
-//        $res = model('Admins')->checktoken($token);
-//        if($res == -1){
-//            return $res;
-//        }
-//        $user_id = $res;
+        $ids = $_GET['ids'];
+
+        try {
+            $back = model('Message')->delMessage($ids);
+        } catch (\Exception $e) {
+            Log::write($e->getMessage(), 'error');
+            return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
+        }
 
-        $user_id = session('user_id');
+        return json(['code' => 1, 'data' => $ids, 'msg' => lang('MC01003')]);
 
-        if(request()->isPost()){
+    }
 
-            $param = input('post.');
 
-            if(empty($param['old_pwd'])){
-                return json(['code' => -2, 'data' => '', 'msg' => '请输入旧密码']);
+    /**
+     * 新增平台
+     *
+     * @access public
+     * @return string
+     */
+    public function addPlatform()
+    {
+        if(request()->isAjax()) {
+            try {
+                $back = model('Platform')->addPlatform();
+            } catch (\Exception $e) {
+                Log::write($e->getMessage(), 'error');
+                return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
             }
 
-            if(empty($param['password'])){
-                return json(['code' => -3, 'data' => '', 'msg' => '请输入新密码']);
-            }
+            return json($back);
+        }
 
-            $userPwd = db('admins')->where('id', $user_id)->find();
-            if(empty($userPwd)){
-                return json(['code' => -4, 'data' => '', 'msg' => '管理员不存在']);
-            }
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
 
-            if(md5($param['old_pwd'] . config('salt')) != $userPwd['password']){
-                return json(['code' => -1, 'data' => '', 'msg' => '旧密码错误']);
-            }
+        // 传递参数.
+        $this->assign([
+            'adminInfo' => $adminInfo,
+            'getPath'   => $getModular['path'],
+            'getAction' => $getModular['action'],
+        ]);
+        return $this->fetch('addplatform');
 
-            $info['password'] = md5($param['password'] . config('salt'));
+    }//end addPlatform()
 
-            db('admins')->where('id', $user_id)->setField('password', $info['password']);
 
-            return json(['code' => 1, 'data' => '', 'msg' => '修改密码成功']);
+    /**
+     * 平台用户列表
+     *
+     * @access public
+     * @return string
+     */
+    public function platformUser()
+    {
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取平台用户列表.
+        $userList = model('UserPlatform')->userList();
+
+        // 传递参数.
+        $this->assign([
+            'adminInfo'   => $adminInfo,
+            'getPath'     => $getModular['path'],
+            'getAction'   => $getModular['action'],
+            'userList'    => $userList['data']['userList'],
+            'page'        => $userList['data']['page'],
+            'currentPage' => $userList['data']['currentPage'],
+        ]);
+        return $this->fetch('platformuser');
+
+    }//end platformUser()
+
+
+    /**
+     * 删除平台用户
+     *
+     * @access public
+     * @return string
+     */
+    public function delPlatUser()
+    {
+        try {
+            model('UserPlatform')->deleteUser();
+        } catch (\Exception $e) {
+            Log::write($e->getMessage(), 'error');
+            return json(['code' => -2, 'data' => '', 'msg' => lang('EC01002')]);
         }
-    }
 
-    // 管理员信息
-    public function adminInfo(){
-        $user_id = session('user_id');
+        return json(['code' => 1, 'data' => '', 'msg' => lang('MC01004')]);
 
-        //管理员信息
-        $admin = db('admins')->where('id', $user_id)->find();
+    }//end delPlatUser()
 
-        //菜单
-        $menu = db('menu')->select();
 
-        $date['admin'] = $admin;
-        $date['menu'] = $menu;
-        return $date;
+    /**
+     * 修改用户密码
+     *
+     * @access public
+     * @return string
+     */
+    public function updatePassword()
+    {
+        $code = -2;
+        $msg  = lang('EC01002');
+        $data = [];
+        try {
+            // 修改密码.
+            $backData = model('Admin')->updatePassword();
+            if ($backData['code'] === 1) {
+                $code = 1;
+                $msg  = $backData['msg'];
+                $data = $backData['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $backData['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end updatePassword()
 
+
+    /**
+     * 消息列表
+     *
+     * @access public
+     * @return string
+     */
+    public function messageList()
+    {
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取消息列表.
+        $messageList = model('message')->messageList();
+        // 传递参数.
         $this->assign([
-            'data' => $date
+            'adminInfo'   => $adminInfo,
+            'getPath'     => $getModular['path'],
+            'getAction'   => $getModular['action'],
+            'messageList' => $messageList['data']['messageList'],
+            'page'        => $messageList['data']['page'],
+            'currentPage' => $messageList['data']['currentPage'],
         ]);
 
+        return $this->fetch('messagelist');
+
+    }//end messageList()
+
+
+    /**
+     * 消息详情
+     *
+     * @access public
+     * @return string
+     */
+    public function messageInfo()
+    {
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        // 获取当前模块地址.
+        $getModular = $this->getModular();
+        // 获取消息详情.
+        $messageList = model('message')->messageInfo();
+
+        // 传递参数.
+        $this->assign([
+            'adminInfo'   => $adminInfo,
+            'getPath'     => $getModular['path'],
+            'getAction'   => $getModular['action'],
+            'messageInfo' => $messageList['data']['messageInfo'],
+        ]);
+
+        return $this->fetch('messageinfo');
+
+    }//end messageInfo()
+
 
-        return $this->fetch('/menu');
-    }
 }

+ 44 - 0
application/admin/controller/Lang.php

@@ -0,0 +1,44 @@
+<?php
+namespace app\index\controller;
+
+use think\Controller;
+use think\Exception;
+use think\Log;
+
+class Lang extends Controller
+{
+
+
+    /**
+     * 国际化
+     *
+     * @access public
+     * @return string
+     */
+    public function lang()
+    {
+        $code = -2;
+        $data = [];
+        $msg  = lang('EC01002');
+        try {
+            // 获取头部信息.
+            $header = headerInfo();
+            // 成功则返回成功.
+            if (in_array($header['lang'], LANG)) {
+                $code = 1;
+                $msg  = lang('MC01001');
+                cookie('think_var', $header['lang']);
+                // 失败则返回错误信息.
+            } else {
+                $msg = lang('EC01001');
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }//end try
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end lang()
+
+
+}

+ 51 - 77
application/admin/controller/Login.php

@@ -1,99 +1,73 @@
 <?php
-/**
- * User: nickbai
- * Date: 2017/10/24 10:46
- * Email: 1902822973@qq.com
- */
 namespace app\admin\controller;
 
 use think\Controller;
+use think\Exception;
+use think\Session;
+use think\Log;
+use think\cache\driver\Redis;
 
 class Login extends Controller
 {
-    // 稳定性测试
-    /*public function aaaa()
-    {
-        $accounts = db('accounts')->select();
-        $this->assign([
-            'accounts' => json_encode($accounts),
-            'socket' => config('socket'),
-        ]);
-        return $this->fetch();
-    }*/
-    // 登录首页
-    public function index()
-    {
-        $this->assign([
-            'version' => config('version')
-        ]);
 
-        return $this->fetch();
-    }
 
-    // 处理登录
-    public function doLogin()
+    /**
+     * 管理员登录
+     *
+     * @access public
+     * @return string
+     */
+    public function login()
     {
-        if(request()->isPost()){
-
-            $userName = input("param.user_name/s");
-            $password = input("param.password/s");
-
-            if(empty($userName)){
-                return json(['code' => -1, 'data' => '', 'msg' => '用户名不能为空']);
+        $msg = '';
+        
+        if (input('post.')) {
+            $msg = lang('EC01002');
+            try {
+                // 获取管理员信息.
+                $userInfo = model('Admin')->login();
+                print_r($userInfo);
+                // 成功则跳转.
+                if ($userInfo['code'] === 1) {
+                    return $this->redirect('Admin/Index/index');
+                    // 失败则返回错误信息.
+                } else {
+                    $msg = $userInfo['msg'];
+                }
+            } catch (Exception $e) {
+                Log::write($e->getMessage(), 'error');
             }
+        }
 
-            if(empty($password)){
-                return json(['code' => -2, 'data' => '', 'msg' => '密码不能为空']);
-            }
+        $this->assign([
+            'errorMsg' => $msg,
+        ]);
 
-            $userInfo = db('admins')->where('user_name', $userName)->find();
-            if(empty($userInfo)){
-                return json(['code' => -3, 'data' => '', 'msg' => '管理员不存在']);
-            }
+        return $this->fetch();
 
-            if(md5($password . config('salt')) != $userInfo['password']){
-                return json(['code' => -4, 'data' => '', 'msg' => '密码错误']);
-            }
+    }//end login()
 
-            if(1 != $userInfo['status']){
-                return json(['code' => -5, 'data' => '', 'msg' => '您已被禁用']);
-            }
 
-            $group = db('admingroup')->where('group_id', $userInfo['group_id'])->find();
-            if(1 != $group['status']){
-                return json(['code' => -6, 'data' => '', 'msg' => '您的权限角色已被禁用']);
+    /**
+     * 退出登陆
+     *
+     * @access public
+     * @return string
+     */
+    public function logout()
+    {
+        try {
+            // 退出登陆.
+            $userInfo = model('Admin')->logout();
+            // 成功.
+            if ($userInfo['code'] === 1) {
+                return $this->redirect('Admin/Login/login');
             }
-
-            session('user_name',$userName);
-            session('user_id',$userInfo['id']);
-
-            // 登陆成功 生成token
-            $module = mt_rand(100000,999999);
-            $token = base64_encode($module.'#$@%!^*/'.time().'/'.$userInfo['id']);
-            // 更新管理员状态
-            $param = [
-                'last_login_ip' => request()->ip(),
-                'token' => $token,
-                'expire_time' => time(),
-                'last_login_time' => time()
-            ];
-            db('admins')->where('id', $userInfo['id'])->update($param);
-
-            session('token', $token);
-            $this->assign([
-                'token' => $token,
-                'user_name' => $userName
-            ]);
-
-            return json(['code' => 1, 'data' => url('index/index'), 'msg' => '登录成功']);
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
         }
-    }
 
-    public function loginOut()
-    {
-        session(null);
+    }//end logout()
 
-        $this->redirect(url('login/index'));
-    }
 
 }

+ 9 - 0
application/admin/lang/en-us.php

@@ -0,0 +1,9 @@
+<?php
+return[
+    // 公共
+    'MC01001' => 'Successful language setup',
+    'EC01001' => 'Language settings failed',
+    //用户-登录
+    'MA01001' => 'Login Successfully',
+    'EA01001' => 'Your username or password is incorrect',
+];

+ 39 - 0
application/admin/lang/zh-cn.php

@@ -0,0 +1,39 @@
+<?php
+return[
+    // 公共.
+    'MC01001' => '语言设置成功',
+    'MC01002' => '添加成功',
+    'MC01003' => '删除成功',
+    'MC01004' => '修改成功',
+    'MC01005' => '获取成功',
+    'MC01006' => '发布成功',
+    'EC01001' => '语言设置失败',
+    'EC01002' => '未知错误',
+    'EC01003' => '邮箱格式错误',
+    'EC01004' => '发布失败',
+    'EC01005' => '文件超过100 KB',
+    'EC01006' => '只能上传jpg|png|gif|jpeg的文件',
+    'EC01007' => '图片上传失败',
+
+    // 用户.
+    'MA01001' => '登录成功',
+    'MA01002' => '注册成功',
+    'MA01003' => '退出成功',
+    'EA01001' => '密码错误',
+    'EA01002' => '用户名错误',
+    'EA01003' => '错误邮箱',
+    'EA01004' => 'token错误',
+    'EA01005' => 'token超时',
+    'EA01006' => '旧密码错误',
+    'EA01007' => '新密码格式错误',
+    'EA01008' => '手机格式错误',
+    'EA01009' => '用户名已存在',
+
+    // 平台列表.
+    'MP01001' => '列表获取成功',
+    'MP01002' => '验证成功',
+    'EP01001' => '参数错误',
+    'EP01002' => '验证超时, 请重新绑定',
+    'EP01003' => '验证失败',
+    'EP01004' => '该账户已经被绑定',
+];

+ 169 - 0
application/admin/model/Admin.php

@@ -0,0 +1,169 @@
+<?php
+namespace app\admin\model;
+
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class Admin extends Model
+{
+
+
+    /**
+     * 管理员登陆
+     */
+    public function login()
+    {
+        $code  = -2;
+        // $redis = new Redis;
+        // 获取的用户信息.
+        $param = input('post.');
+        $name     = $param['name'];
+        $password = $param['password'];
+
+        // 验证传参.
+        $data     = [
+            'name'     => $name,
+            'password' => $password,
+        ];
+        $validate = Loader::validate('Admin');
+        if (!$validate->scene('login')->check($data)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 获取用户信息.
+        $adminInfoWhere['admin_name'] = $name;
+        $adminInfoWhere['admin_status'] = 1;
+        $getAdminInfo = $this
+            ->field('admin_name, admin_identity, admin_phone, admin_nickname, admin_salt, admin_password')
+            ->where($adminInfoWhere)
+            ->find();
+        $adminSalt = $getAdminInfo['admin_salt'];
+        // print_r(md5(md5($adminSalt.$password)));exit;
+        // 验证密码.
+        if (md5(md5($adminSalt.$password)) !== $getAdminInfo['admin_password']) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01001'),
+                'data' => [],
+            ];
+        }
+
+        // 存储用户信息.
+        $adminInfo = [
+            'adminName'     => $getAdminInfo['admin_name'],
+            'adminId'       => $getAdminInfo['admin_identity'],
+            'adminNick'     => $getAdminInfo['admin_nickname'],
+            'lastOperation' => time(),
+        ];
+        session('admin', $adminInfo);
+
+        // 修改最后操作信息.
+        $upData  = [
+            'admin_last_time' => time(),
+            'admin_last_ip'   => $_SERVER['REMOTE_ADDR'],
+        ];
+        $upAdmin = $this
+            ->where($adminInfoWhere)
+            ->update($upData);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MA01001'),
+            'data' => [],
+        ];
+
+    }//end login()
+
+
+    /**
+     * 退出登陆
+     */
+    public function logout()
+    {
+        Session::delete('admin');
+        return [
+            'code' => 1,
+            'msg'  => lang('MA01003'),
+            'data' => [],
+        ];
+
+    }//end logout()
+
+
+    /**
+     * 修改用户密码
+     */
+    public function updatePassword()
+    {
+        $code = -2;
+        // 验证传参.
+        $param       = input('get.');
+        $oldPassword = $param['oldPassword'];
+        $newPassword = $param['newPassword'];
+        $data        = [
+            'oldPassword' => $oldPassword,
+            'newPassword' => $newPassword,
+        ];
+        $validate    = Loader::validate('Admin');
+        if (!$validate->scene('updatePassword')->check($data)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 获取管理员信息.
+        $adminInfo = session('admin');
+        $conditions_admin['admin_identity'] = $adminInfo['adminId'];
+        // 查询用户.
+        $adminInfo = $this
+            ->field('admin_salt, admin_password')
+            ->where($conditions_admin)
+            ->find();
+        // 验证旧密码.
+        $adminSalt = $adminInfo['admin_salt'];
+        if (md5(md5($adminSalt.$oldPassword)) !== $adminInfo['admin_password']) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01006'),
+                'data' => [],
+            ];
+        }
+
+        // 修改密码.
+        $newPasswordData = GenPassword($newPassword);
+        $updateData      = [
+            'admin_password' => $newPasswordData['password'],
+            'admin_salt'     => $newPasswordData['encryption'],
+        ];
+
+        $getAdminInfo = $this
+            ->where($conditions_admin)
+            ->update($updateData);
+        if (empty($getAdminInfo) === true) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01002'),
+                'data' => [],
+            ];
+        } else {
+            $code = 1;
+            return [
+                'code' => $code,
+                'msg'  => lang('MC01004'),
+                'data' => [],
+            ];
+        }
+
+    }//end updatePassword()
+
+
+}

+ 150 - 0
application/admin/model/Message.php

@@ -0,0 +1,150 @@
+<?php
+namespace app\admin\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+use think\DB;
+
+class Message extends Model
+{
+
+
+    /**
+     * 消息列表
+     */
+    public function messageList()
+    {
+        $code         = -2;
+        $limit        = (input('pageSize') ?? 10);
+        $currentPage  = (input('currentPage') ?? 1);
+        $platformName = input('platformName');
+        $getData      = [
+            'pageSize'    => $limit,
+            'currentPage' => $currentPage,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Common');
+        if (!$validate->scene('messageList')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [
+                    'messageList'  => [],
+                    'messageCount' => 0,
+                    'currentPage'  => 1,
+                    'page'         => [],
+                ],
+            ];
+        }
+
+        $offset = (($currentPage - 1) * $limit);
+        $where  = [];
+        if (strlen($platformName)) {
+            $where['platform_name'] = [
+                'like',
+                "%$platformName%"
+            ];
+        }
+
+        $messageList = $this
+            ->field('message_title, message_time, message_ip, platform_name, message_id')
+            ->alias('a')
+            ->join('platform b', 'a.platform_identity = b.platform_identity');
+
+        if ($where) {
+            $messageList = $messageList->where($where);
+        }
+
+        $messageList = $messageList->order('message_time', 'desc')
+            ->limit($offset, $limit)
+            ->select();
+        // 查询总数.
+        $messageCount = $this
+            ->alias('a')
+            ->join('platform b', 'a.platform_identity = b.platform_identity');
+
+        if ($where) {
+            $messageCount = $messageCount->where($where);
+        }
+
+        $messageCount = $messageCount->count();
+        // 分页.
+        $page = getPage($messageCount, $limit, $currentPage);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'messageList'  => $messageList,
+                'messageCount' => $messageCount,
+                'currentPage'  => $currentPage,
+                'page'         => $page,
+            ],
+        ];
+
+    }//end messageList()
+
+
+    /**
+     * 消息详情
+     */
+    public function messageInfo()
+    {
+
+        $code      = -2;
+        $messageId = input('id');
+        $getData   = ['message_id' => $messageId];
+
+        // 验证传参.
+        $validate = Loader::validate('Common');
+        if (!$validate->scene('messageInfo')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => ['messageInfo' => []],
+            ];
+        }
+
+        $messageInfo = $this
+            ->field('message_title, message_time, message_content, platform_name')
+            ->alias('a')
+            ->join('platform b', 'a.platform_identity = b.platform_identity')
+            ->where($getData)
+            ->find();
+
+        if (empty($messageInfo) === false) {
+            return [
+                'code' => 1,
+                'msg'  => lang('MC01005'),
+                'data' => ['messageInfo' => $messageInfo],
+            ];
+        } else {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01002'),
+                'data' => ['messageInfo' => []],
+            ];
+        }
+
+    }//end messageInfo()
+
+    /**
+     * 删除所选消息
+     */
+    public function delMessage($ids)
+    {
+        $this->wherein('message_id',$ids)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01003'),
+            'data' => [],
+        ];
+
+    }//end delMessage()
+
+
+}

+ 276 - 0
application/admin/model/Platform.php

@@ -0,0 +1,276 @@
+<?php
+namespace app\admin\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class Platform extends Model
+{
+
+
+    /**
+     * 获取平台列表
+     */
+    public function platformList()
+    {
+        $code         = -2;
+        $limit        = (input('pageSize') ?? 10);
+        $currentPage  = (input('currentPage') ?? 1);
+        $platformName = input('platformName');
+        $getData      = [
+            'pageSize'    => $limit,
+            'currentPage' => $currentPage,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Common');
+        if (!$validate->scene('platformList')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [
+                    'userList'    => [],
+                    'userCount'   => 0,
+                    'currentPage' => 1,
+                    'page'        => [],
+                ],
+            ];
+        }
+
+        $offset = (($currentPage - 1) * $limit);
+        $where  = [];
+        if (strlen($platformName)) {
+            $where['platform_name'] = [
+                'like',
+                "%$platformName%"
+            ];
+        }
+
+        // 获取列表.
+        $platformList = $this;
+        if ($where) {
+            $platformList = $platformList->where($where);
+        }
+
+        $platformList = $platformList
+            ->limit($offset, $limit)
+            ->select();
+        // 查询总数.
+        $platformCount = $this;
+        if ($where) {
+            $platformCount = $platformCount->where($where);
+        }
+
+        $platformCount = $platformCount->count();
+
+        // 分页.
+        $page = getPage($platformCount, $limit, $currentPage);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'platformList'  => $platformList,
+                'platformCount' => $platformCount,
+                'currentPage'   => $currentPage,
+                'page'          => $page,
+            ],
+        ];
+
+    }//end platformList()
+
+
+    /**
+     * 获取平台数据
+     */
+    public function platform()
+    {
+        $code       = -2;
+        $platformId = input('id');
+        $getData    = ['platformId' => $platformId];
+
+        // 验证传参.
+        $validate = Loader::validate('Platform');
+        if (!$validate->scene('platform')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [
+                    'userList'    => [],
+                    'userCount'   => 0,
+                    'currentPage' => 1,
+                    'page'        => [],
+                ],
+            ];
+        }
+
+        $where['platform_id'] = $platformId;
+        $platform = $this->where($where)->find();
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'platform'  => $platform,
+            ],
+        ];
+
+    }//end platform()
+
+
+    /**
+     * 修改平台
+     */
+    public function updatePlatform()
+    {
+        $code           = -2;
+        $platformId     = input('platform_id');
+        $platformName   = input('platform_name');
+        $platformEmail  = input('platform_email');
+        $platformPhone  = input('platform_phone');
+        $platformStatus = input('platform_status');
+        $platformRemark = input('platform_remark');
+        $platformUrl    = input('platform_url');
+        $getData        = [
+            'platformId'      => $platformId,
+            'platform_name'   => $platformName,
+            'platform_email'  => $platformEmail,
+            'platform_phone'  => $platformPhone,
+            'platform_status' => $platformStatus,
+            'platform_remark' => $platformRemark,
+            'platform_url'    => $platformUrl,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Platform');
+        if (!$validate->scene('updatePlatform')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 图片上传.
+        $file = request()->file('file');
+        if (empty($file) === false) {
+            $upData = model('Upload')->uploadImg();
+            if ($upData['code'] === 1) {
+                $imgSrc = $upData['data'];
+            } else {
+                return $upData;
+            }
+        }
+
+        // 修改平台.
+        $data = [
+            'platform_name'   => $platformName,
+            'platform_email'  => $platformEmail,
+            'platform_phone'  => $platformPhone,
+            'platform_status' => $platformStatus,
+            'platform_remark' => $platformRemark,
+            'platform_url'    => $platformUrl,
+        ];
+        if (isset($imgSrc) === true) {
+            $data['platform_img'] = $imgSrc;
+        }
+
+        $where['platform_id'] = $platformId;
+        $this->where($where)->update($data);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01004'),
+            'data' => [],
+        ];
+
+    }//end updatePlatform()
+
+
+    /**
+     * 新增平台
+     */
+    public function addPlatform()
+    {
+        $code           = -2;
+        $platformName   = input('platform_name');
+        $platformEmail  = input('platform_email');
+        $platformPhone  = input('platform_phone');
+        $platformStatus = input('platform_status');
+        $platformRemark = input('platform_remark');
+        $platformUrl    = input('platform_url');
+        $getData        = [
+            'platform_name'   => $platformName,
+            'platform_email'  => $platformEmail,
+            'platform_phone'  => $platformPhone,
+            'platform_status' => $platformStatus,
+            'platform_remark' => $platformRemark,
+            'platform_url'    => $platformUrl,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Platform');
+        if (!$validate->scene('addPlatform')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 图片上传.
+        $file = request()->file('file');
+        if (empty($file) === false) {
+            $upData = model('Upload')->uploadImg();
+            if ($upData['code'] === 1) {
+                $imgSrc = $upData['data'];
+            } else {
+                return $upData;
+            }
+        } else {
+            $imgSrc = '/static/admin/img/map-marker-violet.png';
+        }
+
+        // 新增平台.
+        $data = [
+            'platform_name'          => $platformName,
+            'platform_email'         => $platformEmail,
+            'platform_phone'         => $platformPhone,
+            'platform_status'        => $platformStatus,
+            'platform_remark'        => $platformRemark,
+            'platform_url'           => $platformUrl,
+            'platform_code'          => randomPassword(),
+            'platform_identity'      => UUID(),
+            'platform_register_time' => time(),
+            'platform_img'           => $imgSrc,
+            'platform_register_ip'   => $_SERVER['REMOTE_ADDR'],
+        ];
+        $this->insert($data);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01002'),
+            'data' => [],
+        ];
+
+    }//end addPlatform()
+
+
+    /**
+     * 删除所选平台
+     */
+    public function delPlatform($ids)
+    {
+        $this->wherein('platform_id',$ids)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01003'),
+            'data' => [],
+        ];
+
+    }//end addPlatform()
+
+
+}

+ 64 - 0
application/admin/model/Upload.php

@@ -0,0 +1,64 @@
+<?php
+namespace app\admin\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class Upload extends Model
+{
+
+
+    /**
+     * 图片上传.
+     */
+    public function uploadImg()
+    {
+        $code = -2;
+        $file = request()->file('file');
+
+        $fileInfo = $file->getInfo();
+        if ($fileInfo['size'] > 1024 * 100 * 2) {
+            // 上传失败获取错误信息.
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01005'),
+                'data' => [],
+            ];
+        }
+
+        // 检测图片格式.
+        $ext    = explode('/', $fileInfo['type']);
+        $ext    = array_pop($ext);
+        $extArr = explode('|', 'jpg|png|gif|jpeg');
+        if (in_array($ext, $extArr) === false) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01006'),
+                'data' => [],
+            ];
+        }
+
+        // 移动到框架应用根目录/public/uploads/ 目录下.
+        $info = $file->move(ROOT_PATH.'public'.DS.'uploads');
+        if (empty($info) === false) {
+            $src = '/uploads/'.date('Ymd').'/'.$info->getFilename();
+            return [
+                'code' => 1,
+                'msg'  => '',
+                'data' => $src,
+            ];
+        } else {
+            // 上传失败获取错误信息.
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01007'),
+                'data' => [],
+            ];
+        }
+
+    }//end uploadImg()
+
+
+}

+ 140 - 0
application/admin/model/User.php

@@ -0,0 +1,140 @@
+<?php
+namespace app\admin\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class User extends Model
+{
+
+
+    /**
+     * 用户列表
+     */
+    public function userList()
+    {
+        $code        = -2;
+        $limit       = (input('pageSize') ?? 10);
+        $currentPage = (input('currentPage') ?? 1);
+        $userName    = input('userName');
+        $getData     = [
+            'pageSize'    => $limit,
+            'currentPage' => $currentPage,
+            'userName'    => $userName,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Common');
+        if (!$validate->scene('userList')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [
+                    'userList'    => [],
+                    'userCount'   => 0,
+                    'currentPage' => 1,
+                    'page'        => [],
+                ],
+            ];
+        }
+
+        $offset = (($currentPage - 1) * $limit);
+        $where  = [];
+        if (strlen($userName)) {
+            $where['user_name'] = [
+                'like',
+                "%$userName%"
+            ];
+        }
+
+        // 获取用户列表.
+        $userList = $this;
+        if ($where) {
+            $userList = $userList->where($where);
+        }
+
+        $userList = $userList
+            ->limit($offset, $limit)
+            ->select();
+        // 查询总数.
+        $userCount = $this;
+        if ($where) {
+            $userCount = $userCount->where($where);
+        }
+
+        $userCount = $userCount->count();
+
+        // 分页.
+        $page = getPage($userCount, $limit, $currentPage);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'userList'    => $userList,
+                'userCount'   => $userCount,
+                'currentPage' => $currentPage,
+                'page'        => $page,
+            ],
+        ];
+
+    }//end userList()
+
+
+    /**
+     * 修改用户
+     */
+    public function updateUser()
+    {
+        $code       = -2;
+        $userId     = input('id');
+        $userStatus = input('status');
+        $getData    = [
+            'user_id'     => $userId,
+            'user_status' => $userStatus,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Common');
+        if (!$validate->scene('userList')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 修改用户.
+        $where['user_id']    = $userId;
+        $data['user_status'] = $userStatus;
+        $updateUser          = $this
+            ->where($where)
+            ->update($data);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01004'),
+            'data' => [],
+        ];
+
+    }//end updateUser()
+
+    /**
+     * 删除所选用户
+     */
+    public function delUser($ids)
+    {
+        $this->wherein('user_id',$ids)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01003'),
+            'data' => [],
+        ];
+
+    }//end delUser()
+
+
+}

+ 109 - 0
application/admin/model/UserPlatform.php

@@ -0,0 +1,109 @@
+<?php
+namespace app\admin\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class UserPlatform extends Model
+{
+
+
+    /**
+     * 平台用户
+     */
+    public function userList()
+    {
+        $code        = -2;
+        $limit       = (input('pageSize') ?? 10);
+        $currentPage = (input('currentPage') ?? 1);
+        $platformId  = input('id');
+        $getData     = [
+            'platform_id' => $platformId,
+            'pageSize'    => $limit,
+            'currentPage' => $currentPage,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('UserPlatform');
+        if (!$validate->scene('userList')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 查询平台用户.
+        $offset = (($currentPage - 1) * $limit);
+        $where   = [
+            'platform_id' => $platformId,
+            'user_status' => 1,
+        ];
+        $file = ['platform_user', 'user_name', 'user_platform_rtime', 'user_platform_rip', 'user_platform_id', 'user_nickname', 'user_full_name', 'user_email', 'user_phone'];
+        $userList = $this
+            ->field($file)
+            ->alias('a')
+            ->join('user b', 'a.user_identity = b.user_identity')
+            ->where($where)
+            ->limit($offset, $limit)
+            ->select();
+
+        // 查询总数.
+        $userCount = $this
+            ->alias('a')
+            ->join('user b', 'a.user_identity = b.user_identity')
+            ->where($where)
+            ->count();
+
+        // 分页.
+        $page = getPage($userCount, $limit, $currentPage);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'userList'    => $userList,
+                'userCount'   => $userCount,
+                'currentPage' => $currentPage,
+                'page'        => $page,
+            ],
+        ];
+
+    }//end userList()
+
+
+    /**
+     * 删除用户平台关联
+     */
+    public function deleteUser()
+    {
+        $code           = -2;
+        $userPlatformId = input('id');
+        $getData        = ['user_platform_id' => $userPlatformId];
+
+        // 验证传参.
+        $validate = Loader::validate('UserPlatform');
+        if (!$validate->scene('deleteUser')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 查询平台用户.
+        $where = ['user_platform_id' => $userPlatformId];
+        $this->where($where)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [],
+        ];
+
+    }//end deleteUser()
+
+
+}

+ 43 - 0
application/admin/validate/Admin.php

@@ -0,0 +1,43 @@
+<?php
+namespace app\admin\validate;
+
+use think\Validate;
+use think\Lang;
+
+class Admin extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'name'    =>  'require|alphaNum|length:5,20',
+        'password'      =>  'require|length:6,20',
+        'oldPassword'      =>  'require|length:6,20',
+        'newPassword'      =>  'require|length:6,20',
+        'email' =>  'email',
+        'phone' =>  'length:11',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'login'   =>  ['name', 'password'],
+        'registered'   =>  ['name', 'password', 'phone'],
+        'logout'   =>  ['name'],
+        'updatePassword'   =>  ['newPassword', 'oldPassword'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'name'  =>  lang('EA01002'),
+            'password'  =>  lang('EA01001'),
+            'email' =>  lang('EA01003'),
+            'oldPassword' =>  lang('EA01006'),
+            'newPassword' =>  lang('EA01007'),
+            'phone' =>  lang('EA01008'),
+        ];
+    }
+}
+

+ 39 - 0
application/admin/validate/Common.php

@@ -0,0 +1,39 @@
+<?php
+namespace app\admin\validate;
+
+use think\Validate;
+use think\Lang;
+
+class Common extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'pageSize'    =>  'number',
+        'currentPage'    =>  'number',
+        'userName'    =>  'alphaNum',
+        'platformName'    =>  'alphaNum',
+        'message_id'    =>  'require|number',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'userList'   =>  ['pageSize', 'currentPage', 'userName'],
+        'platformList'   =>  ['pageSize', 'currentPage'],
+        'messageList'   =>  ['pageSize', 'currentPage'],
+        'messageInfo'   =>  ['message_id'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'pageSize'  =>  lang('EC01002'),
+            'currentPage'  =>  lang('EC01002'),
+            'userName'  =>  lang('EA01002'),
+        ];
+    }
+}
+

+ 38 - 0
application/admin/validate/Platform.php

@@ -0,0 +1,38 @@
+<?php
+namespace app\admin\validate;
+
+use think\Validate;
+use think\Lang;
+
+class Platform extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'platformId'    =>  'require|number|length:1,20',
+        'platform_email'    =>  'email',
+        'platform_phone'    =>  'length:11',
+        'platform_status'    =>  'require|number|length:1',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'platform'   =>  ['platformId'],
+        'updatePlatform'   =>  ['platformId', 'platform_email', 'platform_phone', 'platform_status'],
+        'addPlatform'   =>  ['platform_email', 'platform_phone', 'platform_status'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'platformId'  =>  lang('EP01001'),
+            'platform_email'  =>  lang('EC01003'),
+            'platform_phone'  =>  lang('EA01008'),
+            'platform_status'  =>  lang('EC01002'),
+        ];
+    }
+}
+

+ 32 - 0
application/admin/validate/User.php

@@ -0,0 +1,32 @@
+<?php
+namespace app\admin\validate;
+
+use think\Validate;
+use think\Lang;
+
+class User extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'user_id'    =>  'require|number',
+        'user_status'    =>  'require|number',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'updateUser'   =>  ['user_id', 'user_status'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'user_id'  =>  lang('EC01002'),
+            'user_status'  =>  lang('EC01002'),
+        ];
+    }
+}
+

+ 35 - 0
application/admin/validate/UserPlatform.php

@@ -0,0 +1,35 @@
+<?php
+namespace app\admin\validate;
+
+use think\Validate;
+use think\Lang;
+
+class UserPlatform extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'pageSize'    =>  'number',
+        'currentPage'    =>  'number',
+        'platform_id'    =>  'require|number|length:1,20',
+        'user_platform_id'    =>  'require|number|length:1,20',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'userList'   =>  ['platform_id', 'pageSize', 'currentPage'],
+        'deleteUser'   =>  ['user_platform_id'],
+    ];
+
+    public function __construct() {
+        $this->message = [
+            'platform_id'  =>  lang('EP01001'),
+            'user_platform_id'  =>  lang('EP01001'),
+            'pageSize'  =>  lang('EC01002'),
+            'currentPage'  =>  lang('EC01002'),
+        ];
+    }
+}
+

+ 262 - 0
application/admin/view/index/addplatform.html

@@ -0,0 +1,262 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">新增平台</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">平台管理</li>
+              <li class="breadcrumb-item">平台列表</li>
+              <li class="breadcrumb-item active">新增平台</li>
+            </ul>
+          </div>
+          <!-- Forms Section-->
+          <section class="forms">
+            <div class="container-fluid">
+              <div class="row">
+                <!-- Form Elements -->
+                <div class="col-lg-12">
+                  <div class="card">
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">新增平台</h3>
+                    </div>
+                    <div class="card-body">
+                      <form class="form-horizontal">
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台名称:</label>
+                          <div class="col-sm-9">
+                            <input type="text" id="platform_name" class="form-control">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台邮箱:</label>
+                          <div class="col-sm-9">
+                            <input type="text" id="platform_email" class="form-control">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台电话:</label>
+                          <div class="col-sm-9">
+                            <input type="text" id="platform_phone" class="form-control">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台图标:</label>
+                          <div class="layui-input-block" style="display: flex;">
+                            <input id="file" style="border-style: hidden;border-left: 1px solid #ededed;width: 150px;" type="file" class="layui-input field-name" name="file"/>
+                            <div style="display: flex;margin-left: 20px;">
+                              所选图标:
+                              <img id="onFile" src="__IMG__/map-marker-violet.png" style="width: 30px;height: 30px">
+                            </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">状&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;态:<br></label>
+                          <div class="col-sm-9" style="display: flex; line-height: 2.5;">
+                            <div>
+                              <input id="optionsRadios1" type="radio" checked value="1" name="platform_status">
+                              <label for="optionsRadios1">启用</label>
+                            </div>
+                            <div style="margin-left: 30px;">
+                              <input id="optionsRadios2" type="radio" value="2" name="platform_status">
+                              <label for="optionsRadios2">禁用</label>
+                            </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">验证网址:</label>
+                          <div class="col-sm-9">
+                            <div class="input-group">
+                              <input id="newPlatformUrl" type="text" class="form-control">
+                              <div class="input-group-append">
+                                <button onclick="addPlatformUrl()" type="button" class="btn btn-primary">添加</button>
+                              </div>
+                            </div>
+                          </div>
+                          <div class="col-sm-9" style="margin-left: 110px">
+                              <div class="card-body no-padding" id="platformUrl">
+
+                              </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">备&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注:</label>
+                          <div class="col-sm-9">
+                            <textarea id="platform_remark" class="form-control"></textarea>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <div class="col-sm-4" style="margin-left: 110px;">
+                            <a class="btn btn-primary" onclick="onSubmit()" style="color: #fff">提交</a>
+                            <a class="btn btn-secondary" onclick="goBack()" style="color: #fff">返回</a>
+                          </div>
+                        </div>
+                      </form>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+  <script>
+    let platformUrl = [];
+    function deleteUrl($k) {
+      platformUrl.splice($k, 1);
+      let newPlatformUrl = '';
+      for(let key in platformUrl) {
+        newPlatformUrl += '<div class="item d-flex">' +
+            '<label style="width: 90%; word-break: break-all;">'+platformUrl[key]+'</label>' +
+            '<div style="display: flex; align-items: center;">' +
+            '<i onclick="deleteUrl('+key+')" class="icon iconfont icon-delete" style="margin-left: 20px; color: red; font-size: 20px; cursor:pointer"></i>' +
+            '</div>' +
+            '</div>';
+      }
+      $("#platformUrl").html(newPlatformUrl);
+    }
+    function addPlatformUrl() {
+      let newPlatformUrl = $("#newPlatformUrl").val();
+      platformUrl.push(newPlatformUrl);
+      let nowPlatformUrl = '';
+      for(let key in platformUrl) {
+        nowPlatformUrl += '<div class="item d-flex">' +
+            '<label style="width: 90%; word-break: break-all;">'+platformUrl[key]+'</label>' +
+            '<div style="display: flex; align-items: center;">' +
+            '<i onclick="deleteUrl('+key+')" class="icon iconfont icon-delete" style="margin-left: 20px; color: red; font-size: 20px; cursor:pointer"></i>' +
+            '</div>' +
+            '</div>';
+      }
+      $("#platformUrl").html(nowPlatformUrl);
+    }
+    function onSubmit() {
+      let formData = new FormData();
+      if ($("#file")[0].files[0]) {
+        formData.append("file",$("#file")[0].files[0]);
+      }
+      formData.append("platform_name",$("#platform_name").val());
+      formData.append("platform_email",$("#platform_email").val());
+      formData.append("platform_phone",$("#platform_phone").val());
+      formData.append("platform_status",$("input[name='platform_status']:checked").val());
+      formData.append("platform_remark",$("#platform_remark").val());
+      formData.append("platform_url",JSON.stringify(platformUrl));
+      $.ajax({
+        url: "{:url('admin/index/addPlatform')}", /*接口域名地址*/
+        type:'post',
+        data: formData,
+        contentType: false,
+        processData: false,
+        success:function(res){
+          if(res.code == 1){
+            layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+              let urlParam = "{:url('admin/index/platformList')}";
+              window.location.href = urlParam;
+            });
+          } else {
+            layer.alert(res.msg, {title: '友情提示', icon: 2});
+          }
+        }
+      });
+      /*$.getJSON("{:url('admin/index/addPlatform')}", param, function(res){
+        if(1 == res.code){
+          layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+            let urlParam = "{:url('admin/index/platformList')}";
+            window.location.href = urlParam;
+          });
+        }else{
+          layer.alert(res.msg, {title: '友情提示', icon: 2});
+        }
+      });*/
+    }
+    function goBack() {
+      let urlParam = "{:url('admin/index/platformList')}";
+      window.location.href = urlParam;
+    }
+    // 图片预览.
+    $(function() {
+      $("#file").change(function(e) {
+        var imgBox = e.target;
+        uploadImg(imgBox)
+      });
+
+      function uploadImg(tag) {
+        var file = tag.files[0];
+        var imgSrc;
+        if (!/image\/\w+/.test(file.type)) {
+          layer.alert("您选择的图片格式错误", {title: '友情提示', icon: 2});
+          let fileIput = $("#file").val("");
+          //fileIput.after(fileIput.clone().val(""));
+          $("#onFile").attr("src", '__IMG__//map-marker-violet.png');
+          //fileIput.remove();
+          return false;
+        }
+        var reader = new FileReader();
+        reader.readAsDataURL(file);
+        reader.onload = function() {
+          imgSrc = this.result;
+          $("#onFile").attr("src", imgSrc);
+        };
+      }
+    })
+  </script>
+  </body>
+</html>

+ 142 - 520
application/admin/view/index/index.html

@@ -1,534 +1,156 @@
 <!DOCTYPE html>
 <html>
-<head>
+  <head>
     <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>后台首页</title>
-    <link rel="shortcut icon" href="favicon.ico">
-    <link href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
-    <link href="https://cdn.staticfile.org/font-awesome/4.4.0/css/font-awesome.css?v=4.4.0" rel="stylesheet">
-    <link href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
-    <link href="__CSS__/bootstrap.min.css?v=3.3.6" rel="stylesheet">
-    <link href="__CSS__/font-awesome.min.css?v=4.4.0" rel="stylesheet">
-    <link href="__CSS__/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
-    <link href="__CSS__/animate.min.css" rel="stylesheet">
-    <link href="__CSS__/style.min.css?v=4.1.0" rel="stylesheet">
-    <link href="__JS__/layui/css/myLayui.css" rel="stylesheet">
-</head>
-<style>
-    dl dd{
-        height: 30px;
-    }
-    input.layui-input.layui-unselect {
-        height: 30px;
-    }
-</style>
-<body class="gray-bg">
-<div class="wrapper wrapper-content">
-    <div class="row">
-        <div class="col-sm-2">
-            <div class="ibox float-e-margins">
-                <div class="ibox-title" style="display: flex; justify-content: center;">
-                    <!--<span class="label label-primary pull-right">今天</span>-->
-                    <h3>敏感词报警</h3>
-                </div>
-                <div class="ibox-content" style="text-align: center">
-                    <h1 class="no-margins"><span id="allSensitive">0</span><span style="font-size: 14px; margin-left: 10px">次</span></h1>
-                    <small></small>
-                </div>
-                <div class="ibox-content" style="font-size: 12px; padding: 5px 20px 5px; height: 45px;">
-                    <div style="justify-content: center; display: flex">
-                        <div style="text-align: right;">访客次数</div>
-                        <div style="margin-left: 20px; width: 30px" id="userSensitive">0</div>
-                    </div>
-                    <div style="justify-content: center; display: flex">
-                        <div style="text-align: right;">客服次数</div>
-                        <div style="margin-left: 20px; width: 30px" id="serverSensitive">0</div>
-                    </div>
-                </div>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Home</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">系统中心</h2>
             </div>
-        </div>
-        <div class="col-sm-2">
-            <div class="ibox float-e-margins">
-                <div class="ibox-title" style="display: flex; justify-content: center;">
-                    <!--<span class="label label-primary pull-right">今天</span>-->
-                    <h3>平均响应超时</h3>
-                </div>
-                <div class="ibox-content" style="text-align: center">
-                    <h1 class="no-margins"><span id="csdTime">0</span><span style="font-size: 14px; margin-left: 10px">秒</span></h1>
-                    <small></small>
-                </div>
-                <div class="ibox-content" style="font-size: 12px; padding: 5px 20px 5px; height: 45px; line-height: 3;">
-                    <div style="justify-content: center; display: flex">
-                        <div style="text-align: right;">响应超时次数</div>
-                        <div style="margin-left: 20px; text-align: right;" id="csdNumber">0</div>
+          </header>
+          <!-- Dashboard Counts Section-->
+          <section class="dashboard-counts no-padding-bottom">
+            <div class="container-fluid">
+              <div class="row bg-white has-shadow">
+                <!-- Item -->
+                <div class="col-xl-3 col-sm-6">
+                  <div class="item d-flex align-items-center">
+                    <div class="icon bg-violet"><span class="icon iconfont icon-user" style="font-size: 25px; line-height: 1;"></span></div>
+                    <div class="title"><span>New<br>Clients</span>
+                      <div class="progress">
+                        <div role="progressbar" style="width: 25%; height: 4px;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" class="progress-bar bg-violet"></div>
+                      </div>
                     </div>
-                </div>
-            </div>
-        </div>
-        <div class="col-sm-2">
-            <div class="ibox float-e-margins">
-                <div class="ibox-title" style="display: flex; justify-content: center;">
-                    <!--<span class="label label-primary pull-right">今天</span>-->
-                    <h3>平均会话超时</h3>
-                </div>
-                <div class="ibox-content" style="text-align: center">
-                    <h1 class="no-margins"><span id="overtimeTime">0</span><span style="font-size: 14px; margin-left: 10px">秒</span></h1>
-                    <small></small>
-                </div>
-                <div class="ibox-content" style="font-size: 12px; padding: 5px 20px 5px; height: 45px; line-height: 3;">
-                    <div style="justify-content: center; display: flex">
-                        <div style="text-align: right;">会话超时次数</div>
-                        <div style="margin-left: 20px; text-align: right;" id="overtimeNumber">0</div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="col-sm-2">
-            <div class="ibox float-e-margins">
-                <div class="ibox-title" style="display: flex; justify-content: center;">
-                    <!--<span class="label label-primary pull-right">今天</span>-->
-                    <h3>满意度报警</h3>
-                </div>
-                <div class="ibox-content" style="text-align: center">
-                    <h1 class="no-margins"><span id="evaluateCount1">0</span><span style="font-size: 14px; margin-left: 10px">次</span></h1>
-                    <small></small>
-                </div>
-                <div class="ibox-content" style="font-size: 12px; padding: 5px 20px 5px; height: 45px; line-height: 3;">
-                    <div style="justify-content: center; display: flex">
-                        <div style="text-align: right;">不满意次数</div>
-                        <div style="margin-left: 20px; text-align: right;" id="evaluateCount2">0</div>
+                    <div class="number"><strong>25</strong></div>
+                  </div>
+                </div>
+                <!-- Item -->
+                <div class="col-xl-3 col-sm-6">
+                  <div class="item d-flex align-items-center">
+                    <div class="icon bg-red"><span class="icon iconfont icon-snippets" style="font-size: 25px; line-height: 1;"></span></div>
+                    <div class="title"><span>Work<br>Orders</span>
+                      <div class="progress">
+                        <div role="progressbar" style="width: 70%; height: 4px;" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" class="progress-bar bg-red"></div>
+                      </div>
                     </div>
-                </div>
-            </div>
-        </div>
-    </div>
-
-    <div class="ibox float-e-margins">
-        <input style="display:none;" type="text" value="1" id="type">
-        <div style="display: flex;">
-            <div class="ibox-title" style="width: 100px; cursor:pointer;" id="current1" onclick="current(1)">
-                <h5>当前会话</h5>
-            </div>
-            <div class="ibox-title" id="current2" style="width: 100px; cursor:pointer; background: #eee" onclick="current(2)">
-                <h5>登陆客服</h5>
-            </div>
-            <div class="ibox-title" style="width: calc(100% - 200px); background: #eee;">
-            </div>
-        </div>
-        <div class="ibox-content">
-            <!--搜索框开始-->
-            <form id="realTimeForm"  role="form" method="post" class="form-inline">
-                <div class="content clearfix m-b">
-                    <div class="form-group" style="margin-top: 5px;">
-                        <label>分组名称:</label>
-                        <div class="input-group col-sm-4 layui-form" style="width: 120px;">
-                            <input type="hidden" id="group_id"/>
-                            <select lay-verify="required" lay-filter="group">
-                                <option value="">全部客服组</option>
-                                {if !empty($groups)}
-                                {foreach name="groups" item="vo"}
-                                <option value="{$vo['id']}">{$vo['name']}</option>
-                                {/foreach}
-                                {/if}
-                            </select>
-                        </div>
+                    <div class="number"><strong>70</strong></div>
+                  </div>
+                </div>
+                <!-- Item -->
+                <div class="col-xl-3 col-sm-6">
+                  <div class="item d-flex align-items-center">
+                    <div class="icon bg-green"><span class="icon iconfont icon-audit" style="font-size: 25px; line-height: 1;"></span></div>
+                    <div class="title"><span>New<br>Invoices</span>
+                      <div class="progress">
+                        <div role="progressbar" style="width: 40%; height: 4px;" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" class="progress-bar bg-green"></div>
+                      </div>
                     </div>
-                    <div class="form-group" style="margin-left: 40px;margin-top: 5px;">
-                        <label>报警状态:</label>
-                        <div class="input-group col-sm-4 layui-form" style="width: 120px;">
-                            <input type="hidden" id="alarm_id"/>
-                            <select lay-verify="required" lay-filter="alarm">
-                                <option value="">所有会话</option>
-                                <option value="1">正常会话</option>
-                                <option value="2">报警会话</option>
-                            </select>
-                        </div>
+                    <div class="number"><strong>40</strong></div>
+                  </div>
+                </div>
+                <!-- Item -->
+                <div class="col-xl-3 col-sm-6">
+                  <div class="item d-flex align-items-center">
+                    <div class="icon bg-orange"><span class="icon iconfont icon-medicinebox-fill" style="font-size: 25px; line-height: 1;"></span></div>
+                    <div class="title"><span>Open<br>Cases</span>
+                      <div class="progress">
+                        <div role="progressbar" style="width: 50%; height: 4px;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" class="progress-bar bg-orange"></div>
+                      </div>
                     </div>
+                    <div class="number"><strong>50</strong></div>
+                  </div>
                 </div>
-            </form>
-            <!--搜索框结束-->
-            <div id="realTimeTable" class="example-wrap">
-                <div class="example">
-                    <table class="table table-hover table-striped">
-                        <thead>
-                        <tr>
-                            <th>会话ID</th>
-                            <th>访客进线时间</th>
-                            <th>接待客服</th>
-                            <th>访客名</th>
-                            <th>会话开始时间</th>
-                            <th>报警次数</th>
-                            <th>操作</th>
-                        </tr>
-                        </thead>
-                        <tbody id="table">
-                        <tr>
-                            <td colspan="999" style="text-align: center">暂无数据</td>
-                        </tr>
-                        </tbody>
-                    </table>
-                </div>
+              </div>
             </div>
-            <!-- End Example Pagination -->
-
-
-            <!--搜索框开始-->
-            <form id='commentForm' style="display: none" role="form" method="get" class="form-inline">
-                <div class="content clearfix m-b">
-                    <div class="form-group">
-                        <label>分组名称:</label>
-                        <div class="input-group col-sm-4 layui-form" style="width: 120px;">
-                            <select lay-verify="required" lay-filter="group" name="type1" id="type1">
-                                <option value="">全部客服组</option>
-                                {if !empty($groups)}
-                                {foreach name="groups" item="vo"}
-                                <option value="{$vo['id']}">{$vo['name']}</option>
-                                {/foreach}
-                                {/if}
-                            </select>
-                        </div>
-                    </div>
-                    <div class="form-group" style="margin-left: 40px">
-                        <label>登陆状态:</label>
-                        <div class="input-group col-sm-4 layui-form" style="width: 120px;">
-                            <select lay-verify="required" lay-filter="alarm"  name="type2" id="type2">
-                                <option value="">所有状态</option>
-                                <option value="1">在线状态</option>
-                                <option value="3">休息状态</option>
-                                <option value="2">隐身状态</option>
-                            </select>
-                        </div>
-                    </div>
-
-                    <div class="form-group" style="display: none">
-                        <lable>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</lable>
-                        <select name="type3" id="type3" class="form-control">
-                            <option value="0">所有会话</option>
-                            <option value="1">正常会话</option>
-                            <option value="2">报警回话</option>
-                        </select>
-                    </div>
-
-
-                    <div class="form-group">
-                        <lable>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</lable>
-                        <button class="btn btn-primary btn-sm" type="button" style="margin-top:5px" id="search">搜索
-                        </button>
-                    </div>
-                </div>
-            </form>
-            <!--搜索框结束-->
-            <div id="commentTable" style="display: none" class="example-wrap">
-                <div class="example">
-                    <table id="cusTable">
-                        <thead>
-                        <th data-field="uidname">客服</th>
-                        <th data-field="ip">IP</th>
-                        <th data-field="status">状态</th>
-                        <th data-field="hhl">当前会话量</th>
-                        <th data-field="jdl">今日接待量</th>
-                        <th data-field="pjhysc">今日平均会话时长</th>
-                        <th data-field="cpl">今日参评率</th>
-                        <th data-field="mydl">今日满意度</th>
-                        <th data-field="pjxysc">今日平均响应时长</th>
-                        <th data-field="jrxxsc">今日休息时长</th>
-                        <th data-field="fxx">发消息</th>
-                        </thead>
-                    </table>
-                </div>
+          </section>
+          <!-- Dashboard Header Section    -->
+          <section class="dashboard-header">
+            <div class="container-fluid">
+              <div class="row">
+                <!-- Statistics -->
+                <div class="statistics col-lg-3 col-12">
+                  <div class="statistic d-flex align-items-center bg-white has-shadow">
+                    <div class="icon bg-red"><i class="fa fa-tasks"></i></div>
+                    <div class="text"><strong>234</strong><br><small>Applications</small></div>
+                  </div>
+                  <div class="statistic d-flex align-items-center bg-white has-shadow">
+                    <div class="icon bg-green"><i class="fa fa-calendar-o"></i></div>
+                    <div class="text"><strong>152</strong><br><small>Interviews</small></div>
+                  </div>
+                  <div class="statistic d-flex align-items-center bg-white has-shadow">
+                    <div class="icon bg-orange"><i class="fa fa-paper-plane-o"></i></div>
+                    <div class="text"><strong>147</strong><br><small>Forwards</small></div>
+                  </div>
+                </div>
+                <!-- Line Chart            -->
+                <div class="chart col-lg-6 col-12">
+                  <div class="line-chart bg-white d-flex align-items-center justify-content-center has-shadow">
+                    <canvas id="lineCahrt"></canvas>
+                  </div>
+                </div>
+                <div class="chart col-lg-3 col-12">
+                  <!-- Bar Chart   -->
+                  <div class="bar-chart has-shadow bg-white">
+                    <div class="title"><strong class="text-violet">95%</strong><br><small>Current Server Uptime</small></div>
+                    <canvas id="barChartHome"></canvas>
+                  </div>
+                  <!-- Numbers-->
+                  <div class="statistic d-flex align-items-center bg-white has-shadow">
+                    <div class="icon bg-green"><i class="fa fa-line-chart"></i></div>
+                    <div class="text"><strong>99.9%</strong><br><small>Success Rate</small></div>
+                  </div>
+                </div>
+              </div>
             </div>
-            <!-- End Example Pagination -->
-
-
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
         </div>
+      </div>
     </div>
-</div>
-<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
-<script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
-<script src="/static/admin/js/plugins/echarts/echarts.min.js"></script>
-<script src="/static/customer/js/md5.js"></script>
-<script src="__JS__/jquery.min.js?v=2.1.4"></script>
-<script src="__JS__/bootstrap.min.js?v=3.3.6"></script>
-<script src="__JS__/content.min.js?v=1.0.0"></script>
-<script src="__JS__/plugins/bootstrap-table/bootstrap-table.min.js"></script>
-<script src="__JS__/plugins/bootstrap-table/bootstrap-table-mobile.min.js"></script>
-<script src="__JS__/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
-<script src="__JS__/plugins/layer/layer.min.js"></script>
-<script src="__JS__/plugins/validate/jquery.validate.min.js"></script>
-<script src="__JS__/plugins/validate/messages_zh.min.js"></script>
-<script src="__JS__/layui/layui.js"></script>
-<script src="__JS__/jquery.form.js"></script>
-<script type="text/javascript">
-  function current(id) {
-    $("#type").val(id);
-    if (id == 1) {
-      $("#current1").css("background","#fff");
-      $("#current2").css("background","#eee");
-      $("#realTimeForm").css("display","block");
-      $("#realTimeTable").css("display","block");
-      $("#commentForm").css("display","none");
-      $("#commentTable").css("display","none");
-    } else if (id == 2) {
-      $("#current2").css({"background":"#fff"});
-      $("#current1").css({"background":"#eee"});
-      $("#realTimeForm").css({"display":"none"});
-      $("#realTimeTable").css({"display":"none"});
-      $("#commentForm").css({"display":"block"});
-      $("#commentTable").css({"display":"block"});
-      initTable()
-    }
-  }
-  layui.use(['form', 'upload'], function(){
-    var form = layui.form;
-
-    form.on('select(group)', function(value){
-      $("#group_id").val(value.value);
-      onSearch()
-    });
-
-    form.on('select(alarm)', function(value){
-      $("#alarm_id").val(value.value);
-      onSearch()
-    });
-  });
-  function initTable() {
-    //先销毁表格
-    $('#cusTable').bootstrapTable('destroy');
-    //初始化表格,动态从服务器加载数据
-    $("#cusTable").bootstrapTable({
-      method: "get",  //使用get请求到服务器获取数据
-      url: "{:url('kfonitoring/kfjiankong')}", //获取数据的地址
-      striped: true,  //表格显示条纹
-      pagination: true, //启动分页
-      pageSize: 50,  //每页显示的记录数
-      pageNumber: 1, //当前第几页
-      pageList: [20, 50],  //记录数可选列表
-      sidePagination: "server", //表示服务端请求
-      paginationFirstText: "首页",
-      paginationPreText: "上一页",
-      paginationNextText: "下一页",
-      paginationLastText: "尾页",
-      queryParamsType: "undefined",
-      queryParams: function queryParams(params) {   //设置查询参数
-        var param = {
-          pageNumber: params.pageNumber,
-          pageSize: params.pageSize,
-          searchText: $('#type1').val() + ',' + $('#type2').val() + ',' + $('#type3').val()
-        };
-        return param;
-      },
-      onLoadSuccess: function (res) {  //加载成功时执行
-        if (111 == res.code) {
-          window.location.reload();
-        }
-        layer.msg("加载成功", {time: 1000});
-      },
-      onLoadError: function () {  //加载失败时执行
-        layer.msg("加载数据失败");
-      }
-    });
-  }
-  $(document).ready(function () {
-    //调用函数,初始化表格
-    initTable();
-
-    //当点击查询按钮的时候执行
-    $("#search").bind("click", initTable);
-  });
-</script>
-<!--webSocket-->
-<script>
-  let config = {
-    socket: '{$socket}',
-    token: '{$token}',
-  };
-  let myData = [];
-  let date = new Date(new Date().setHours(0, 0, 0, 0)) / 1000;
-  let getLocation = window.location.href;
-  let host = getLocation.split('/admin')[0];
-  //let apiToken = hex_md5('customer-service'+date+host);
-  let apiToken = hex_md5('customer-service'+host);
-  let socket = new WebSocket('ws://' + config.socket+'?apiToken=' + apiToken);
-  socket.onopen = function(res) {
-    console.log('握手成功');
-    // 登录
-    let login_data = JSON.stringify({
-      type: 'adminInit',
-      token:  config.token
-    });
-    socket.send(login_data);
-  };
-
-  // 心跳检测.
-  setInterval(function(){
-    socket.send(JSON.stringify({
-      type: 'ping',
-    }));
-  }, 5000);
-
-
-  socket.onmessage = function(res) {
-    var data = eval("("+res.data+")");
-    switch(data['message_type']){
-        // 服务端ping客户端
-      case 'monitor':
-        myData = data.data.cvtList;
-        putMonitor(data.data);
-        break;
-    }
-  };
-
-  socket.onclose = function(res) {
-    layer.alert('实时监控连接失败', {
-      title: '错误提示',  icon: 2, closeBtn: 0
-    }, '');
-  };
-
-  /**
-   * 时间戳转化为年 月 日 时 分 秒
-   * time: 传入时间戳
-   * format:返回格式,支持自定义,但参数必须与formateArr里保持一致
-   */
-  function customFormatDateTime(timeStamp,custom,isDtae) {
-    var date = new Date();
-    date.setTime(timeStamp * 1000);
-    var y = date.getFullYear();
-    var m = date.getMonth() + 1;
-    m = m < 10 ? ('0' + m) : m;
-    var d = date.getDate();
-    d = d < 10 ? ('0' + d) : d;
-    var h = date.getHours();
-    h = h < 10 ? ('0' + h) : h;
-    var minute = date.getMinutes();
-    var second = date.getSeconds();
-    minute = minute < 10 ? ('0' + minute) : minute;
-    second = second < 10 ? ('0' + second) : second;
-    if (isDtae == 0){
-      return y + custom + m //+'student';
-    }else if (isDtae ==1){
-      return y + custom + m + custom + d;
-    } else if (isDtae ==2) {
-      return h + ':' + minute;
-    } else {
-      return y + '-' + m + '-' + d + '-' + h + ':' + minute + ':' + second;
-    }
-  };
-  function onSearch() {
-    let table = "";
-    let cvtList = searchData();
-    for(key in cvtList){
-      let start_time = cvtList[key].start_time;
-      let intime = cvtList[key].intime
-      if (key != "length") {
-        table += "<tr>" +
-            "<td>"+cvtList[key].servicelog_id+"</td>" +
-            "<td>"+customFormatDateTime(intime,'',2)+"</td>" +
-            "<td>"+cvtList[key].server_name+"</td>" +
-            "<td>"+cvtList[key].user_name+"</td>" +
-            "<td>"+customFormatDateTime(start_time,'',2)+"</td>" +
-            "<td>"+cvtList[key].allCount+"</td>" +
-            "<td>" +
-            "<a href='/admin/system/detail/id/"+cvtList[key].servicelog_id+"/type/onLine.html'>" +
-            "<button type='button' class='btn btn-primary btn-sm'>" +
-            " 详情" +
-            "</button>" +
-            "</a>" +
-            "</td>" +
-            "</tr>"
-      }
-    }
-    if (table) {
-      $("#table").html(table);
-    } else {
-      $("#table").html("<tr>" +
-          "<td colspan='6' style='text-align: center'>暂无数据</td>" +
-          "</tr>");
-    }
-  }
-  function searchData() {
-    let group_id = $("#group_id").val();
-    let alarm_id = $("#alarm_id").val();
-    let newData = [];
-    if (group_id && alarm_id) {
-      if (alarm_id == 1) {
-        for (keys in myData) {
-          if (group_id == myData[keys].group_id && !myData[keys].allCount) {
-            newData.push(myData[keys])
-          }
-        }
-      } else if (alarm_id == 2) {
-        for (keys in myData) {
-          if (group_id == myData[keys].group_id && myData[keys].allCount) {
-            newData.push(myData[keys])
-          }
-        }
-      }
-    } else if(group_id) {
-      for (keys in myData) {
-        if (group_id == myData[keys].group_id) {
-          newData.push(myData[keys])
-        }
-      }
-    } else if(alarm_id) {
-      if (alarm_id == 1) {
-        for (keys in myData) {
-          if (!myData[keys].allCount) {
-            newData.push(myData[keys])
-          }
-        }
-      } else if (alarm_id == 2) {
-        for (keys in myData) {
-          if (myData[keys].allCount) {
-            newData.push(myData[keys])
-          }
-        }
-      }
-    } else {
-      newData = myData
-    }
-    return newData;
-  }
-
-  function msg(id) {
-    layui.use('layer', function () {
-          layer.open({
-            type: 2,
-            title: '请输入消息内容',
-            area: ['500px', '600px'], //自定义文本域宽高
-            content:'/admin/kfnotice/add.html?uid='+id
-          });
-        }
-    )
-  }
-
-  // 渲染
-  function putMonitor(data) {
-    $("#allSensitive").html(data.userSensitive + data.serverSensitive);
-    $("#userSensitive").html(data.userSensitive);
-    $("#serverSensitive").html(data.serverSensitive);
-    $("#csdNumber").html(data.csdNumber);
-    $("#overtimeNumber").html(data.overtimeNumber);
-    $("#evaluateCount1").html(data.evaluateCount);
-    $("#evaluateCount2").html(data.evaluateCount);
-    // 响应超时.
-    let n = data.csdTime.length;
-    let csdTime = 0;
-    for(keys in data.csdTime){
-      csdTime += data.csdTime[keys]
-    }
-    csdTime = csdTime ? Math.ceil(csdTime/n) : 0;
-    $("#csdTime").html(csdTime);
-    // 会话超时.
-    let m = data.overtimeTime.length;
-    let overtimeTime = 0;
-    for(keys in data.overtimeTime){
-      overtimeTime += data.overtimeTime[keys]
-    }
-    overtimeTime = overtimeTime ? Math.ceil(overtimeTime/m) : 0;
-    $("#overtimeTime").html(overtimeTime);
-    onSearch();
-  }
-</script>
-</body>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/charts-home.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+  </body>
 </html>

+ 98 - 0
application/admin/view/index/messageInfo.html

@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <title></title>
+  <meta name="description" content="">
+  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+  <meta name="robots" content="all,follow">
+  <!-- Bootstrap CSS-->
+  <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+  <!-- Font Awesome CSS-->
+  <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+  <!-- Fontastic Custom icon font-->
+  <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+  <link rel="stylesheet" href="__CSS__/iconfont.css">
+  <!-- Google fonts - Poppins -->
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+  <!-- theme stylesheet-->
+  <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+  <!-- Custom stylesheet - for your changes-->
+  <link rel="stylesheet" href="__CSS__/custom.css">
+  <!-- Favicon-->
+  <link rel="shortcut icon" href="__IMG__/favicon.ico">
+  <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+  <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+  <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+</head>
+<body>
+<div class="page">
+  <!-- Main Navbar-->
+  {include file="layout/header" /}
+  <div class="page-content d-flex align-items-stretch">
+    <!-- Side Navbar -->
+    {include file="layout/navigation" /}
+    <div class="content-inner">
+      <!-- Page Header-->
+      <header class="page-header">
+        <div class="container-fluid">
+          <h2 class="no-margin-bottom">消息详情</h2>
+        </div>
+      </header>
+      <!-- Breadcrumb-->
+      <div class="breadcrumb-holder container-fluid">
+        <ul class="breadcrumb">
+          <li class="breadcrumb-item">消息管理</li>
+          <li class="breadcrumb-item active">消息列表</li>
+          <li class="breadcrumb-item active">消息详情</li>
+        </ul>
+      </div>
+      <section class="tables">
+        <div class="container-fluid">
+          <div class="row">
+            <div class="col-lg-12">
+              <div class="recent-activities card">
+                <div class="card-header">
+                  <h3 class="h4">消息详情</h3>
+                </div>
+                <div class="card-body no-padding">
+                  <div class="item">
+                    <div class="row">
+                      <div class="col-3 date-holder text-right">
+                        <span style="margin: 10px 10px 0 0; color: #454545;">{$messageInfo['platform_name']}</span>
+                        <div class="date"> <span><?php echo date('Y-m-d H:i',$messageInfo['message_time']); ?></span><br><!--<span class="text-info">6 hours ago</span>--></div>
+                      </div>
+                      <div class="col-9 content" style="height: calc(100vh - 430px);">
+                        <h3 style="text-align: center;">{$messageInfo['message_title']}</h3>
+                        <p style="font-size: 1em; color: #666; margin-top: 30px;" id="messageContent"><?php echo htmlspecialchars_decode($messageInfo['message_content']); ?></p>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <!-- Page Footer-->
+      {include file="layout/footer" /}
+    </div>
+  </div>
+</div>
+<!-- JavaScript files-->
+<script src="__VENDOR__/jquery/jquery.min.js"></script>
+<script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+<script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+<script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+<script src="__VENDOR__/chart.js/Chart.min.js"></script>
+<script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+<script src="__JS__/jquery.form.js"></script>
+<script src="__JS__/plugins/layer/layer.min.js"></script>
+<!-- Main File-->
+<script src="__JS__/front.js"></script>
+<script>
+
+</script>
+</body>
+</html>

+ 233 - 0
application/admin/view/index/messagelist.html

@@ -0,0 +1,233 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">消息列表</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">消息管理</li>
+              <li class="breadcrumb-item active">消息列表</li>
+            </ul>
+          </div>
+          <section class="tables">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="col-lg-12">
+                  <div class="card">
+                    <!--<div class="card-close">
+                      <div class="dropdown">
+                        <button type="button" id="closeCard1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-ellipsis-v"></i></button>
+                        <div aria-labelledby="closeCard1" class="dropdown-menu dropdown-menu-right has-shadow"><a href="#" class="dropdown-item remove"> <i class="fa fa-times"></i>Close</a><a href="#" class="dropdown-item edit"> <i class="fa fa-gear"></i>Edit</a></div>
+                      </div>
+                    </div>-->
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">消息列表</h3>
+                    </div>
+                    <div class="card-body">
+                      <div class="form-group col-lg-6" style="float: right;">
+                        <div class="input-group">
+                          <span style="line-height: 2; font-size: 18px; margin-right: 5px;">平台名</span>
+                          <input type="text" id="platformName" class="form-control">
+                          <div class="input-group-append">
+                            <button type="button" onclick="onSearch()" class="btn btn-primary">查询</button>
+                          </div>
+                          <div class="input-group-append" style="margin-left: 20px;">
+                            <button type="button" onclick="ondelete()" class="btn btn-primary">删除</button>
+                          </div>
+                        </div>
+                      </div>
+                      <div class="table-responsive">
+                        <table class="table table-striped">
+                          <thead>
+                            <tr>
+                              <th><input type="checkbox" lay-filter="checkeds" lay-skin="primary" class="checkall" onclick="oncheck()"></th>
+                              <th>序号</th>
+                              <th>平台名</th>
+                              <th>标题</th>
+                              <th>消息时间</th>
+                              <th>发送者IP</th>
+                              <th>操作</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            <?php foreach ($messageList as $k => $v): ?>
+                              <tr>
+                                <td class="check-mail">
+                                  <input type="checkbox" class="checkone" value="{$k+1}" name="ids" lay-skin="primary">
+                                </td>
+                                <th scope="row">{$k+1}</th>
+                                <td>{$v['platform_name']}</td>
+                                <td>{$v['message_title']}</td>
+                                <td><?php echo date('Y-m-d H:i',$v['message_time']); ?></td>
+                                <td>{$v['message_ip']}</td>
+
+                                <td>
+                                  <span onclick="getInfo({$v['message_id']})" style="color: #1428ce; cursor:pointer" class="icon iconfont icon-info-circle-fill" title="详情"></span>
+                                </td>
+                              </tr>
+                            <?php endforeach; ?>
+                          </tbody>
+                        </table>
+                        <ul class="list-unstyled" style="display: flex; justify-content: end;">
+
+                          <?php if (count($page) > 1): ?>
+                          <?php foreach ($page as $k => $v): ?>
+                          <li>
+                            <a onclick="changePage({$v})" style="{$currentPage == $v ? 'pointer-events:none;' : ''}" class="btn btn-xs {$currentPage == $v ? 'btn-secondary' : ''}">{$v}</a>
+                          </li>
+                          <?php endforeach; ?>
+                          <?php endif; ?>
+
+                        </ul>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+    <script>
+      function onSearch() {
+        let platformName = $("#platformName").val();
+        let urlParam = '';
+        if (platformName) {
+          urlParam = "{:url('admin/index/messagelist')}"+"?platformName="+platformName;
+        } else {
+          urlParam = "{:url('admin/index/messagelist')}";
+        }
+        window.location.href = urlParam;
+      }
+      function getInfo(id) {
+        let urlParam = "{:url('admin/index/messageInfo')}"+"?id="+id;
+        window.location.href = urlParam;
+      }
+      function changePage(page) {
+        let param = getQueryString();
+        param.currentPage = page;
+        let urlParam = "{:url('admin/index/messageList')}"+"?"+putUrlParam(param);
+        window.location.href = urlParam;
+      }
+      // 获取URL参数.
+      function getQueryString() {
+        var qs = location.search.substr(1), // 获取url中"?"符后的字串
+            args = {}, // 保存参数数据的对象
+            items = qs.length ? qs.split("&") : [], // 取得每一个参数项
+            item = null,
+            len = items.length;
+        for(var i = 0; i < len; i++) {
+          item = items[i].split("=");
+          var name = decodeURIComponent(item[0]),
+              value = decodeURIComponent(item[1]);
+          if(name) {
+            args[name] = value;
+          }
+        }
+        return args;
+      }
+      // 对象转URL参数
+      function putUrlParam(param) {
+        let urlParam = '';
+        let n = 1;
+        for(let key  in param){
+          if (n === 1) {
+            urlParam = key+'='+param[key];
+          } else {
+            urlParam += '&'+key+'='+param[key];
+          }
+          n++;
+        }
+        return urlParam;
+      }
+
+      function oncheck() {
+        if($('.checkall').is(':checked')==true){
+          $('.checkone').prop('checked',true);
+        }else{
+          $('.checkone').prop('checked',false);
+        }
+      }
+
+      function ondelete() {
+        let msg = '确认删除所选消息';
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          var ids = [];
+          $("input[name='ids']:checked").each(function(i){
+            ids.push($(this).val())
+          })
+          if(ids==''){
+            layer.msg('未选中任何消息'); return false;
+          }
+          //console.log(ids);
+          $.getJSON("{:url('admin/index/delMessage')}", {'ids' : ids}, function(res){
+            //console.log(res);
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+
+          layer.close(index);
+        })
+      }
+    </script>
+  </body>
+</html>

+ 290 - 0
application/admin/view/index/platformlist.html

@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">平台列表</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">平台管理</li>
+              <li class="breadcrumb-item active">平台列表</li>
+            </ul>
+          </div>
+          <section class="tables">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="col-lg-12">
+                  <div class="card">
+                    <!--<div class="card-close">
+                      <div class="dropdown">
+                        <button type="button" id="closeCard1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-ellipsis-v"></i></button>
+                        <div aria-labelledby="closeCard1" class="dropdown-menu dropdown-menu-right has-shadow"><a href="#" class="dropdown-item remove"> <i class="fa fa-times"></i>Close</a><a href="#" class="dropdown-item edit"> <i class="fa fa-gear"></i>Edit</a></div>
+                      </div>
+                    </div>-->
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">平台列表</h3>
+                    </div>
+                    <div class="card-body">
+                      <div class="form-group col-lg-4" style="float: left;">
+                        <div class="input-group">
+                          <a class="btn btn-primary" href="{:url('admin/index/addPlatform')}" style="background-color: #169bd5; border-color: #169bd5; color: #fff">新增</a>
+                        </div>
+                      </div>
+                      <div class="form-group col-lg-6" style="float: right;">
+                        <div class="input-group">
+                          <span style="line-height: 2; font-size: 18px; margin-right: 5px;">平台名</span>
+                          <input type="text" id="platformName" class="form-control">
+                          <div class="input-group-append">
+                            <button type="button" onclick="onSearch()" class="btn btn-primary">查询</button>
+                          </div>
+                          <div class="input-group-append" style="margin-left: 20px;">
+                            <button type="button" onclick="ondelete()" class="btn btn-primary">删除</button>
+                          </div>
+                        </div>
+                      </div>
+                      <div class="table-responsive">
+                        <table class="table table-striped">
+                          <thead>
+                            <tr>
+                              <th><input type="checkbox" lay-filter="checkeds" lay-skin="primary" class="checkall" onclick="oncheck()"></th>
+                              <th>序号</th>
+                              <th>图标</th>
+                              <th>平台名</th>
+                              <!--<th>CODE</th>-->
+                              <th>注册时间</th>
+                              <th>注册IP</th>
+                              <!-- <th>验证网址</th>-->
+                              <th>邮箱</th>
+                              <th>电话</th>
+                               <!-- <th>备注</th> -->
+                              <th>状态</th>
+                              <th>操作</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            <?php foreach ($platformList as $k => $v): ?>
+                              <tr>
+                                <td class="check-mail">
+                                  <input type="checkbox" class="checkone" value="{$k+1}" name="ids" lay-skin="primary">
+                                </td>
+                                <th scope="row">{$k+1}</th>
+                                <td><img src="{$v['platform_img']}" style="width: 30px;height: 30px"></td>
+                                <td>{$v['platform_name']}</td>
+                                <!--<td>{$v['platform_code']}</td>-->
+                                <td><?php echo date('Y-m-d H:i',$v['platform_register_time']); ?></td>
+                                <td>{$v['platform_register_ip']}</td>
+                                <!-- <td>
+                                  <?php
+                                  $platformUrl = json_decode($v['platform_url']);
+                                  foreach ($platformUrl as $va):
+                                  ?>
+                                    <p style="margin-bottom: 0px; width: 230px">
+                                      <?php
+                                    if (strlen($va) <= 30) {echo $va;}
+                                    else {echo mb_strcut($va, 0, 30, 'utf-8').'...';}
+                                   ?>
+                                    </p>
+                                  <?php endforeach; ?>
+                                </td> -->
+                                <td>{$v['platform_email']}</td>
+                                <td>{$v['platform_phone']}</td>
+                                <!-- <td>
+                                  <?php
+                                  if (strlen($v['platform_remark']) <= 40) {echo $v['platform_remark'];}
+                                  else {echo mb_strcut($v['platform_remark'], 0, 40, 'utf-8').'...';}
+                               ?>
+                                </td> -->
+                                <td>
+                                  <?php if ($v['platform_status'] == 1): ?>
+                                  <span style="color: #26ce16;">启用</span>
+                                  <?php else: ?>
+                                  <span style="color: red;">禁用</span>
+                                  <?php endif; ?></td>
+                                <td>
+                                  <a href="{:url('admin/index/updatePlatform',['id'=>$v['platform_id']])}" class="icon iconfont icon-edit-square" title="编辑" style="text-decoration: none; color: #666; cursor:pointer"></a>
+                                  <span onclick="platformUser({$v['platform_id']})" class="icon iconfont icon-user" title="查看" style="text-decoration: none; color: #666; cursor:pointer"></span>
+                                </td>
+                              </tr>
+                            <?php endforeach; ?>
+                          </tbody>
+                        </table>
+                        <ul class="list-unstyled" style="display: flex; justify-content: end;">
+
+                          <?php if (count($page) > 1): ?>
+                          <?php foreach ($page as $k => $v): ?>
+                          <li>
+                            <a onclick="changePage({$v})" style="{$currentPage == $v ? 'pointer-events:none;' : ''}" class="btn btn-xs {$currentPage == $v ? 'btn-secondary' : ''}">{$v}</a>
+                          </li>
+                          <?php endforeach; ?>
+                          <?php endif; ?>
+
+                        </ul>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+    <script>
+      function platformUser(id) {
+        let urlParam = "{:url('admin/index/platformUser')}"+"?id="+id;
+        window.location.href = urlParam;
+      }
+      function onSearch() {
+        let platformName = $("#platformName").val();
+        let urlParam = "{:url('admin/index/platformlist')}"+"?platformName="+platformName;
+        window.location.href = urlParam;
+      }
+
+      function oncheck() {
+        if($('.checkall').is(':checked')==true){
+          $('.checkone').prop('checked',true);
+        }else{
+          $('.checkone').prop('checked',false);
+        }
+      }
+
+      function ondelete() {
+        let msg = '确认删除所选平台';
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          var ids = [];
+          $("input[name='ids']:checked").each(function(i){
+            ids.push($(this).val())
+          })
+          if(ids==''){
+            layer.msg('未选中任何平台'); return false;
+          }
+          //console.log(ids);
+          $.getJSON("{:url('admin/index/delPlatform')}", {'ids' : ids}, function(res){
+            //console.log(res);
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+
+          layer.close(index);
+        })
+      }
+
+      function checkStatus(id, getStatus) {
+        let msg = '确认禁用此用户';
+        if (getStatus != 1) {
+          msg = '确认启用此用户';
+        }
+        let status = getStatus == 1 ? 2 : 1;
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          $.getJSON("{:url('admin/index/updatePlatform')}", {'id' : id, status: status}, function(res){
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+
+          layer.close(index);
+        })
+      }
+      function changePage(page) {
+        let param = getQueryString();
+        param.currentPage = page;
+        let urlParam = "{:url('admin/index/platformList')}"+"?"+putUrlParam(param);
+        window.location.href = urlParam;
+      }
+      // 获取URL参数.
+      function getQueryString() {
+        var qs = location.search.substr(1), // 获取url中"?"符后的字串
+            args = {}, // 保存参数数据的对象
+            items = qs.length ? qs.split("&") : [], // 取得每一个参数项
+            item = null,
+            len = items.length;
+        for(var i = 0; i < len; i++) {
+          item = items[i].split("=");
+          var name = decodeURIComponent(item[0]),
+              value = decodeURIComponent(item[1]);
+          if(name) {
+            args[name] = value;
+          }
+        }
+        return args;
+      }
+      // 对象转URL参数
+      function putUrlParam(param) {
+        let urlParam = '';
+        let n = 1;
+        for(let key  in param){
+          if (n === 1) {
+            urlParam = key+'='+param[key];
+          } else {
+            urlParam += '&'+key+'='+param[key];
+          }
+          n++;
+        }
+        return urlParam;
+      }
+    </script>
+  </body>
+</html>

+ 189 - 0
application/admin/view/index/platformuser.html

@@ -0,0 +1,189 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">用户列表</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">用户管理</li>
+              <li class="breadcrumb-item active">用户列表</li>
+            </ul>
+          </div>
+          <section class="tables">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="col-lg-12">
+                  <div class="card">
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">平台用户</h3>
+                    </div>
+                    <div class="card-body">
+                      <div class="table-responsive">
+                        <table class="table table-striped">
+                          <thead>
+                            <tr>
+                              <th>序号</th>
+                              <th>平台用户名</th>
+                              <th>用户名</th>
+                              <th>注册时间</th>
+                              <th>注册IP</th>
+                              <th>手机号</th>
+                              <th>操作</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            <?php foreach ($userList as $k => $v): ?>
+                              <tr>
+                                <th scope="row">{$k+1}</th>
+                                <td>{$v['platform_user']}</td>
+                                <td>{$v['user_name']}</td>
+                                <td><?php echo date('Y-m-d H:i',$v['user_platform_rtime']); ?></td>
+                                <td>{$v['user_platform_rip']}</td>
+                                <td>{$v['user_phone']}</td>
+                                <td>
+                                  <span onclick="deleteUser({$v['user_platform_id']})" style="color: #ce2714; cursor:pointer" class="icon iconfont icon-delete" title="删除"></span>
+                                </td>
+                              </tr>
+                            <?php endforeach; ?>
+                          </tbody>
+                        </table>
+                        <ul class="list-unstyled" style="display: flex; justify-content: end;">
+
+                          <?php if (count($page) > 1): ?>
+                          <?php foreach ($page as $k => $v): ?>
+                          <li>
+                            <a onclick="changePage({$v})" style="{$currentPage == $v ? 'pointer-events:none;' : ''}" class="btn btn-xs {$currentPage == $v ? 'btn-secondary' : ''}">{$v}</a>
+                          </li>
+                          <?php endforeach; ?>
+                          <?php endif; ?>
+
+                        </ul>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+    <script>
+      function onSearch() {
+        let userName = $("#userName").val();
+        let urlParam = '';
+        if (userName) {
+          urlParam = "{:url('admin/index/userlist')}"+"?userName="+userName;
+        } else {
+          urlParam = "{:url('admin/index/userlist')}";
+        }
+        window.location.href = urlParam;
+      }
+      function deleteUser(id) {
+        let msg = '确认删除该关联关系';
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          $.getJSON("{:url('admin/index/delPlatUser')}", {'id' : id}, function(res){
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+          layer.close(index);
+        })
+      }
+      function changePage(page) {
+        let param = getQueryString();
+        param.currentPage = page;
+        let urlParam = "{:url('admin/index/platformUser')}"+"?"+putUrlParam(param);
+        window.location.href = urlParam;
+      }
+      // 获取URL参数.
+      function getQueryString() {
+        var qs = location.search.substr(1), // 获取url中"?"符后的字串
+            args = {}, // 保存参数数据的对象
+            items = qs.length ? qs.split("&") : [], // 取得每一个参数项
+            item = null,
+            len = items.length;
+        for(var i = 0; i < len; i++) {
+          item = items[i].split("=");
+          var name = decodeURIComponent(item[0]),
+              value = decodeURIComponent(item[1]);
+          if(name) {
+            args[name] = value;
+          }
+        }
+        return args;
+      }
+      // 对象转URL参数
+      function putUrlParam(param) {
+        let urlParam = '';
+        let n = 1;
+        for(let key  in param){
+          if (n === 1) {
+            urlParam = key+'='+param[key];
+          } else {
+            urlParam += '&'+key+'='+param[key];
+          }
+          n++;
+        }
+        return urlParam;
+      }
+    </script>
+  </body>
+</html>

+ 280 - 0
application/admin/view/index/updateplatform.html

@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">平台编辑</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">平台管理</li>
+              <li class="breadcrumb-item">平台列表</li>
+              <li class="breadcrumb-item active">平台编辑</li>
+            </ul>
+          </div>
+          <!-- Forms Section-->
+          <section class="forms">
+            <div class="container-fluid">
+              <div class="row">
+                <!-- Form Elements -->
+                <div class="col-lg-12">
+                  <div class="card">
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">平台编辑</h3>
+                    </div>
+                    <div class="card-body">
+                      <form class="form-horizontal">
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台名称:</label>
+                          <div class="col-sm-9">
+                            <input type="text" id="platform_name" value="{$platform['platform_name']}" class="form-control">
+                            <input type="text" id="platform_id" value="{$platform['platform_id']}" style="display: none">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台邮箱:</label>
+                          <div class="col-sm-9">
+                            <input type="text" value="{$platform['platform_email']}" id="platform_email" class="form-control">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台电话:</label>
+                          <div class="col-sm-9">
+                            <input type="text" id="platform_phone" value="{$platform['platform_phone']}" class="form-control">
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">平台图标:</label>
+                          <div class="layui-input-block" style="display: flex;">
+                            <input id="file" style="border-style: hidden;border-left: 1px solid #ededed;width: 150px;" type="file" class="layui-input field-name" name="file"/>
+                            <div style="display: flex;margin-left: 20px;">
+                              所选图标:
+                              <img id="onFile" src="__IMG__/map-marker-violet.png" style="width: 30px;height: 30px">
+                            </div>
+                            <div style="display: flex;margin-left: 20px;">
+                              原图标:
+                              <img src="{$platform['platform_img']}" style="width: 30px;height: 30px">
+                            </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">状&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;态:<br></label>
+                          <div class="col-sm-9" style="display: flex; line-height: 2.5;">
+                            <div>
+                              <input id="optionsRadios1" type="radio" {$platform['platform_status'] == 1 ? 'checked' : ''} value="1" name="platform_status">
+                              <label for="optionsRadios1">启用</label>
+                            </div>
+                            <div style="margin-left: 30px;">
+                              <input id="optionsRadios2" type="radio" value="2" {$platform['platform_status'] == 2 ? 'checked' : ''} name="platform_status">
+                              <label for="optionsRadios2">禁用</label>
+                            </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">验证网址:</label>
+                          <div class="col-sm-9">
+                            <div class="input-group">
+                              <input id="newPlatformUrl" type="text" class="form-control">
+                              <div class="input-group-append">
+                                <button onclick="addPlatformUrl()" type="button" class="btn btn-primary">添加</button>
+                              </div>
+                            </div>
+                          </div>
+                          <div class="col-sm-9" style="margin-left: 110px">
+                              <div class="card-body no-padding" id="platformUrl">
+
+                                <?php
+                                $platformUrl = json_decode($platform['platform_url']);
+                                foreach ($platformUrl as $k=>$va):
+                              ?>
+                                  <div class="item d-flex">
+                                    <label style="width: 90%; word-break: break-all;">{$va}</label>
+                                    <div style="display: flex; align-items: center;">
+                                      <i onclick="deleteUrl({$k})" class="icon iconfont icon-delete" style="margin-left: 20px; color: red; font-size: 20px; cursor:pointer"></i>
+                                    </div>
+                                  </div>
+                                <?php endforeach; ?>
+
+                              </div>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <label style="margin: 8px 0px 0px 30px; width: 80px;" class="form-control-label">备&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注:</label>
+                          <div class="col-sm-9">
+                            <textarea id="platform_remark" class="form-control">{$platform['platform_remark']}</textarea>
+                          </div>
+                        </div>
+                        <div class="line"></div>
+                        <div class="form-group row">
+                          <div class="col-sm-4" style="margin-left: 110px;">
+                            <a class="btn btn-primary" onclick="onSubmit()" style="color: #fff">提交</a>
+                            <a class="btn btn-secondary" onclick="goBack()" style="color: #fff">返回</a>
+                          </div>
+                        </div>
+                      </form>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+  <script>
+    let platformUrl = {$platform['platform_url']};
+    function deleteUrl($k) {
+      platformUrl.splice($k, 1);
+      let newPlatformUrl = '';
+      for(let key in platformUrl) {
+        newPlatformUrl += '<div class="item d-flex">' +
+            '<label style="width: 90%; word-break: break-all;">'+platformUrl[key]+'</label>' +
+            '<div style="display: flex; align-items: center;">' +
+            '<i onclick="deleteUrl('+key+')" class="icon iconfont icon-delete" style="margin-left: 20px; color: red; font-size: 20px; cursor:pointer"></i>' +
+            '</div>' +
+            '</div>';
+      }
+      $("#platformUrl").html(newPlatformUrl);
+    }
+    function addPlatformUrl() {
+      let newPlatformUrl = $("#newPlatformUrl").val();
+      platformUrl.push(newPlatformUrl);
+      let nowPlatformUrl = '';
+      for(let key in platformUrl) {
+        nowPlatformUrl += '<div class="item d-flex">' +
+            '<label style="width: 90%; word-break: break-all;">'+platformUrl[key]+'</label>' +
+            '<div style="display: flex; align-items: center;">' +
+            '<span onclick="deleteUrl('+key+')" class="icon iconfont icon-delete" style="margin-left: 20px; color: red; font-size: 20px; cursor:pointer"></span>' +
+            '</div>' +
+            '</div>';
+      }
+      $("#platformUrl").html(nowPlatformUrl);
+    }
+    function onSubmit() {
+      let formData = new FormData();
+      if ($("#file")[0].files[0]) {
+        formData.append("file",$("#file")[0].files[0]);
+      }
+      formData.append("platform_id",$("#platform_id").val());
+      formData.append("platform_name",$("#platform_name").val());
+      formData.append("platform_email",$("#platform_email").val());
+      formData.append("platform_phone",$("#platform_phone").val());
+      formData.append("platform_status",$("input[name='platform_status']:checked").val());
+      formData.append("platform_remark",$("#platform_remark").val());
+      formData.append("platform_url",JSON.stringify(platformUrl));
+      $.ajax({
+        url: "{:url('admin/index/updatePlatform')}", /*接口域名地址*/
+        type:'post',
+        data: formData,
+        contentType: false,
+        processData: false,
+        success:function(res){
+          if(res.code == 1){
+            layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+              let urlParam = "{:url('admin/index/platformList')}";
+              window.location.href = urlParam;
+            });
+          } else {
+            layer.alert(res.msg, {title: '友情提示', icon: 2});
+          }
+        }
+      });
+      /*$.getJSON("{:url('admin/index/updatePlatform')}", param, function(res){
+        if(1 == res.code){
+          layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+            let urlParam = "{:url('admin/index/platformList')}";
+            window.location.href = urlParam;
+          });
+        }else{
+          layer.alert(res.msg, {title: '友情提示', icon: 2});
+        }
+      });*/
+    }
+    function goBack() {
+      let urlParam = "{:url('admin/index/platformList')}";
+      window.location.href = urlParam;
+    }
+    // 图片预览.
+    $(function() {
+      $("#file").change(function(e) {
+        var imgBox = e.target;
+        uploadImg(imgBox)
+      });
+
+      function uploadImg(tag) {
+        var file = tag.files[0];
+        var imgSrc;
+        if (!/image\/\w+/.test(file.type)) {
+          layer.alert("您选择的图片格式错误", {title: '友情提示', icon: 2});
+          let fileIput = $("#file").val("");
+          //fileIput.after(fileIput.clone().val(""));
+          $("#onFile").attr("src", '__IMG__//map-marker-violet.png');
+          //fileIput.remove();
+          return false;
+        }
+        var reader = new FileReader();
+        reader.readAsDataURL(file);
+        reader.onload = function() {
+          imgSrc = this.result;
+          $("#onFile").attr("src", imgSrc);
+        };
+      }
+    })
+  </script>
+  </body>
+</html>

+ 274 - 0
application/admin/view/index/userlist.html

@@ -0,0 +1,274 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <!--<link rel="stylesheet" href="__CSS__/fontastic.css">-->
+    <link rel="stylesheet" href="__CSS__/iconfont.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page">
+      <!-- Main Navbar-->
+      {include file="layout/header" /}
+      <div class="page-content d-flex align-items-stretch">
+        <!-- Side Navbar -->
+        {include file="layout/navigation" /}
+        <div class="content-inner">
+          <!-- Page Header-->
+          <header class="page-header">
+            <div class="container-fluid">
+              <h2 class="no-margin-bottom">用户列表</h2>
+            </div>
+          </header>
+          <!-- Breadcrumb-->
+          <div class="breadcrumb-holder container-fluid">
+            <ul class="breadcrumb">
+              <li class="breadcrumb-item">用户管理</li>
+              <li class="breadcrumb-item active">用户列表</li>
+            </ul>
+          </div>
+          <section class="tables">
+            <div class="container-fluid">
+              <div class="row">
+                <div class="col-lg-12">
+                  <div class="card">
+                    <!--<div class="card-close">
+                      <div class="dropdown">
+                        <button type="button" id="closeCard1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle"><i class="fa fa-ellipsis-v"></i></button>
+                        <div aria-labelledby="closeCard1" class="dropdown-menu dropdown-menu-right has-shadow"><a href="#" class="dropdown-item remove"> <i class="fa fa-times"></i>Close</a><a href="#" class="dropdown-item edit"> <i class="fa fa-gear"></i>Edit</a></div>
+                      </div>
+                    </div>-->
+                    <div class="card-header d-flex align-items-center">
+                      <h3 class="h4">用户列表</h3>
+                    </div>
+                    <div class="card-body">
+                      <div class="form-group col-lg-6" style="float: right;">
+                        <div class="input-group">
+                          <span style="line-height: 2; font-size: 18px; margin-right: 5px;">用户名</span>
+                          <input type="text" id="userName" class="form-control">
+                          <div class="input-group-append">
+                            <button type="button" onclick="onSearch()" class="btn btn-primary">查询</button>
+                          </div>
+                          <div class="input-group-append" style="margin-left: 20px;">
+                            <button type="button" onclick="ondelete()" class="btn btn-primary">删除</button>
+                          </div>
+                        </div>
+                      </div>
+                      <div class="table-responsive">
+                        <table class="table table-striped">
+                          <thead>
+                            <tr>
+                              <th><input type="checkbox" lay-filter="checkeds" lay-skin="primary" class="checkall" onclick="oncheck()"></th>
+                              <th>序号</th>
+                              <th>用户名</th>
+                              <th>注册IP</th>
+                              <th>注册时间</th>
+                              <th>最后登录时间</th>
+                              <th>最后登录IP</th>
+                              <th>手机号</th>
+                              <th>备注</th>
+                              <th>状态</th>
+                              <th>操作</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            <?php foreach ($userList as $k => $v): ?>
+                              <tr>
+                                <td class="check-mail">
+                                  <input type="checkbox" class="checkone" value="{$k+1}" name="ids" lay-skin="primary">
+                                </td>
+                                <th scope="row">{$k+1}</th>
+                                <td>{$v['user_name']}</td>
+                                <td>{$v['user_register_ip']}</td>
+                                <td><?php echo date('Y-m-d H:i',$v['user_register_time']); ?></td>
+                                <td><?php echo date('Y-m-d H:i',$v['user_last_time']); ?></td>
+                                <td>{$v['user_last_ip']}</td>
+                                <td>{$v['user_phone']}</td>
+                                <td>
+                                  <?php
+                                  if (strlen($v['user_remark']) <= 40) {echo $v['user_remark'];}
+                                  else {echo mb_strcut($v['user_remark'], 0, 60, 'utf-8').'...';}
+                               ?>
+                                </td>
+                                <td>
+                                  <?php if ($v['user_status'] == 1): ?>
+                                  <span style="color: #26ce16;">启用</span>
+                                  <?php else: ?>
+                                  <span style="color: red;">禁用</span>
+                                  <?php endif; ?>
+                                </td>
+                                <td>
+                                  <?php if ($v['user_status'] == 1): ?>
+                                  <span onclick="checkStatus({$v['user_id']}, {$v['user_status']})" style="color: #ce2714; cursor:pointer" class="icon iconfont icon-lock-fill" title="禁用"></span>
+                                  <?php else: ?>
+                                  <span onclick="checkStatus({$v['user_id']}, {$v['user_status']})" style="color: #12a604; cursor:pointer" class="icon iconfont icon-unlock-fill" title="启用"></span>
+                                  <?php endif; ?>
+                                </td>
+                              </tr>
+                            <?php endforeach; ?>
+                          </tbody>
+                        </table>
+                        <ul class="list-unstyled" style="display: flex; justify-content: end;">
+
+                          <?php if (count($page) > 1): ?>
+                          <?php foreach ($page as $k => $v): ?>
+                          <li>
+                            <a onclick="changePage({$v})" style="{$currentPage == $v ? 'pointer-events:none;' : ''}" class="btn btn-xs {$currentPage == $v ? 'btn-secondary' : ''}">{$v}</a>
+                          </li>
+                          <?php endforeach; ?>
+                          <?php endif; ?>
+
+                        </ul>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+          <!-- Page Footer-->
+          {include file="layout/footer" /}
+        </div>
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <script src="__JS__/jquery.form.js"></script>
+    <script src="__JS__/plugins/layer/layer.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+    <script>
+      function onSearch() {
+        let userName = $("#userName").val();
+        let urlParam = '';
+        if (userName) {
+          urlParam = "{:url('admin/index/userlist')}"+"?userName="+userName;
+        } else {
+          urlParam = "{:url('admin/index/userlist')}";
+        }
+        window.location.href = urlParam;
+      }
+
+      function oncheck() {
+        if($('.checkall').is(':checked')==true){
+          $('.checkone').prop('checked',true);
+        }else{
+          $('.checkone').prop('checked',false);
+        }
+      }
+
+      function ondelete() {
+        let msg = '确认删除所选用户';
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          var ids = [];
+          $("input[name='ids']:checked").each(function(i){
+            ids.push($(this).val())
+          })
+          if(ids==''){
+            layer.msg('未选中任何用户'); return false;
+          }
+          //console.log(ids);
+          $.getJSON("{:url('admin/index/delUser')}", {'ids' : ids}, function(res){
+            //console.log(res);
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+
+          layer.close(index);
+        })
+      }
+
+      function checkStatus(id, getStatus) {
+        let msg = '确认禁用此用户';
+        if (getStatus != 1) {
+          msg = '确认启用此用户';
+        }
+        let status = getStatus == 1 ? 2 : 1;
+        layer.confirm(msg, {icon: 3, title:'提示'}, function(index){
+          $.getJSON("{:url('admin/index/updateUser')}", {'id' : id, status: status}, function(res){
+            if(1 == res.code){
+              layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+                location.reload();
+              });
+            }else if(111 == res.code){
+              window.location.reload();
+            }else{
+              layer.alert(res.msg, {title: '友情提示', icon: 2});
+            }
+          });
+
+          layer.close(index);
+        })
+      }
+      function changePage(page) {
+        let param = getQueryString();
+        param.currentPage = page;
+        let urlParam = "{:url('admin/index/userList')}"+"?"+putUrlParam(param);
+        window.location.href = urlParam;
+      }
+      // 获取URL参数.
+      function getQueryString() {
+        var qs = location.search.substr(1), // 获取url中"?"符后的字串
+            args = {}, // 保存参数数据的对象
+            items = qs.length ? qs.split("&") : [], // 取得每一个参数项
+            item = null,
+            len = items.length;
+        for(var i = 0; i < len; i++) {
+          item = items[i].split("=");
+          var name = decodeURIComponent(item[0]),
+              value = decodeURIComponent(item[1]);
+          if(name) {
+            args[name] = value;
+          }
+        }
+        return args;
+      }
+      // 对象转URL参数
+      function putUrlParam(param) {
+        let urlParam = '';
+        let n = 1;
+        for(let key  in param){
+          if (n === 1) {
+            urlParam = key+'='+param[key];
+          } else {
+            urlParam += '&'+key+'='+param[key];
+          }
+          n++;
+        }
+        return urlParam;
+      }
+    </script>
+  </body>
+</html>

+ 14 - 0
application/admin/view/layout/footer.html

@@ -0,0 +1,14 @@
+<footer class="main-footer">
+    <div class="container-fluid">
+        <div class="row">
+            <p style="margin: 0 auto;">保护伞后台管理</p>
+            <!--<div class="col-sm-6">
+                &lt;!&ndash;<p>Copyright &copy; 2019.Company name All rights reserved.More Templates <a href="http://www.cssmoban.com/" target="_blank" title="模板之家">模板之家</a> - Collect from <a href="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></p>&ndash;&gt;
+            </div>
+            <div class="col-sm-6 text-right">
+                <p></p>
+                &lt;!&ndash; Please do not remove the backlink to us unless you support further theme's development at https://bootstrapious.com/donate. It is part of the license conditions. Thank you for understanding :)&ndash;&gt;
+            </div>-->
+        </div>
+    </div>
+</footer>

+ 83 - 0
application/admin/view/layout/header.html

@@ -0,0 +1,83 @@
+<header class="header">
+    <nav class="navbar">
+        <!-- Search Box-->
+        <div class="search-box">
+            <button class="dismiss"><i class="icon-close"></i></button>
+            <form id="searchForm" action="#" role="search">
+                <input type="search" placeholder="What are you looking for..." class="form-control">
+            </form>
+        </div>
+        <div class="container-fluid">
+            <div class="navbar-holder d-flex align-items-center justify-content-between">
+                <!-- Navbar Header-->
+                <div class="navbar-header">
+                    <!-- Navbar Brand --><a href="index.html" class="navbar-brand d-none d-sm-inline-block">
+                    <div class="brand-text d-none d-lg-inline-block"><strong>后台管理系统</strong></div>
+                    <div class="brand-text d-none d-sm-inline-block d-lg-none"><strong>BD</strong></div></a>
+                    <!-- Toggle Button--><a id="toggle-btn" href="#" class="menu-btn active"><span></span><span></span><span></span></a>
+                </div>
+                <!-- Navbar Menu -->
+                <ul class="nav-menu list-unstyled d-flex flex-md-row align-items-md-center">
+                    <!-- Search-->
+                    <!--<li class="nav-item d-flex align-items-center"><a id="search" href="#"><i class="icon-search"></i></a></li>
+                    &lt;!&ndash; Notifications&ndash;&gt;
+                    <li class="nav-item dropdown"> <a id="notifications" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link"><i class="fa fa-bell-o"></i><span class="badge bg-red badge-corner">12</span></a>
+                      <ul aria-labelledby="notifications" class="dropdown-menu">
+                        <li><a rel="nofollow" href="#" class="dropdown-item">
+                            <div class="notification">
+                              <div class="notification-content"><i class="fa fa-envelope bg-green"></i>You have 6 new messages </div>
+                              <div class="notification-time"><small>4 minutes ago</small></div>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item">
+                            <div class="notification">
+                              <div class="notification-content"><i class="fa fa-twitter bg-blue"></i>You have 2 followers</div>
+                              <div class="notification-time"><small>4 minutes ago</small></div>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item">
+                            <div class="notification">
+                              <div class="notification-content"><i class="fa fa-upload bg-orange"></i>Server Rebooted</div>
+                              <div class="notification-time"><small>4 minutes ago</small></div>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item">
+                            <div class="notification">
+                              <div class="notification-content"><i class="fa fa-twitter bg-blue"></i>You have 2 followers</div>
+                              <div class="notification-time"><small>10 minutes ago</small></div>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item all-notifications text-center"> <strong>view all notifications                                            </strong></a></li>
+                      </ul>
+                    </li>
+                    &lt;!&ndash; Messages                        &ndash;&gt;
+                    <li class="nav-item dropdown"> <a id="messages" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link"><i class="fa fa-envelope-o"></i><span class="badge bg-orange badge-corner">10</span></a>
+                      <ul aria-labelledby="notifications" class="dropdown-menu">
+                        <li><a rel="nofollow" href="#" class="dropdown-item d-flex">
+                            <div class="msg-profile"> <img src="img/avatar-1.jpg" alt="..." class="img-fluid rounded-circle"></div>
+                            <div class="msg-body">
+                              <h3 class="h5">Jason Doe</h3><span>Sent You Message</span>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item d-flex">
+                            <div class="msg-profile"> <img src="img/avatar-2.jpg" alt="..." class="img-fluid rounded-circle"></div>
+                            <div class="msg-body">
+                              <h3 class="h5">Frank Williams</h3><span>Sent You Message</span>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item d-flex">
+                            <div class="msg-profile"> <img src="img/avatar-3.jpg" alt="..." class="img-fluid rounded-circle"></div>
+                            <div class="msg-body">
+                              <h3 class="h5">Ashley Wood</h3><span>Sent You Message</span>
+                            </div></a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item all-notifications text-center"> <strong>Read all messages   </strong></a></li>
+                      </ul>
+                    </li>
+                    &lt;!&ndash; Languages dropdown    &ndash;&gt;
+                    <li class="nav-item dropdown"><a id="languages" rel="nofollow" data-target="#" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link language dropdown-toggle"><img src="img/flags/16/GB.png" alt="English"><span class="d-none d-sm-inline-block">English</span></a>
+                      <ul aria-labelledby="languages" class="dropdown-menu">
+                        <li><a rel="nofollow" href="#" class="dropdown-item"> <img src="img/flags/16/DE.png" alt="English" class="mr-2">German</a></li>
+                        <li><a rel="nofollow" href="#" class="dropdown-item"> <img src="img/flags/16/FR.png" alt="English" class="mr-2">French                                         </a></li>
+                      </ul>
+                    </li>-->
+                    <!-- Logout    -->
+                    <li class="nav-item"><a href="{:url('admin/login/logout')}" class="nav-link logout"> <span class="d-none d-sm-inline">退出</span><i class="fa fa-sign-out"></i></a></li>
+                </ul>
+            </div>
+        </div>
+    </nav>
+</header>

+ 94 - 0
application/admin/view/layout/navigation.html

@@ -0,0 +1,94 @@
+<nav class="side-navbar">
+    <!-- Sidebar Header-->
+    <div style="cursor:pointer" data-toggle="modal" data-target="#myModal" class="sidebar-header d-flex align-items-center">
+        <div class="avatar"><img src="__IMG__/avatar-1.jpg" alt="..." class="img-fluid rounded-circle"></div>
+        <div class="title">
+            <h1 class="h4">{$adminInfo['adminName']}</h1>
+            <p>欢迎您</p>
+        </div>
+    </div>
+    <!-- Sidebar Navidation Menus--><!--<span class="heading">Main</span>-->
+    <ul class="list-unstyled">
+        <li class="{$getPath == 'admin/index/index'? 'active' : '';}"><a href="{:url('admin/index/index')}"><span class="icon iconfont icon-home" style="font-size: 25px; line-height: 1;"></span> &nbsp;系统中心</a></li>
+        <li>
+            <a href="#user" aria-expanded="<?php if (in_array($getAction, ['userlist'])){ echo ('true');} ?>" data-toggle="collapse">
+                <span class="icon iconfont icon-user" style="font-size: 25px; line-height: 1;"></span> &nbsp;
+                用户管理
+            </a>
+            <ul id="user" class="collapse list-unstyled <?php if (in_array($getAction, ['userlist'])){ echo ('show');} ?>">
+                <li  class="{$getPath == 'admin/index/userlist'? 'active' : '';}"><a href="{:url('admin/index/userList')}">用户列表</a></li>
+            </ul>
+        </li>
+        <li>
+            <a href="#platform" aria-expanded="<?php if (in_array($getAction, ['platformlist'])){ echo ('true');} ?>" data-toggle="collapse">
+                <span class="icon iconfont icon-unorderedlist" style="font-size: 25px; line-height: 1;"></span> &nbsp;
+                平台管理
+            </a>
+            <ul id="platform" class="collapse list-unstyled <?php if (in_array($getAction, ['platformlist'])){ echo ('show');} ?>">
+                <li  class="{$getPath == 'admin/index/platformlist'? 'active' : '';}"><a href="{:url('admin/index/platformList')}">平台列表</a></li>
+            </ul>
+        </li>
+        <li>
+            <a href="#message" aria-expanded="<?php if (in_array($getAction, ['messagelist'])){ echo ('true');} ?>" data-toggle="collapse">
+                <span class="icon iconfont icon-message" style="font-size: 25px; line-height: 1;"></span> &nbsp;
+                消息管理
+            </a>
+            <ul id="message" class="collapse list-unstyled <?php if (in_array($getAction, ['messagelist'])){ echo ('show');} ?>">
+                <li  class="{$getPath == 'admin/index/messagelist'? 'active' : '';}"><a href="{:url('admin/index/messageList')}">消息列表</a></li>
+            </ul>
+        </li>
+    </ul>
+</nav>
+<div id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" class="modal fade text-left">
+    <div role="document" class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 id="exampleModalLabel" class="modal-title">修改密码</h4>
+                <button type="button" data-dismiss="modal" aria-label="Close" class="close"><span aria-hidden="true">×</span></button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label>旧密码</label>
+                        <input type="password" id="oldPassword" placeholder="旧密码" class="form-control">
+                    </div>
+                    <div class="form-group">
+                        <label>新密码</label>
+                        <input type="password" id="newPassword" placeholder="新密码" class="form-control">
+                    </div>
+                    <div class="form-group">
+                        <label>确认新密码</label>
+                        <input type="password" id="reNewPassword" placeholder="确认新密码" class="form-control">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" data-dismiss="modal" class="btn btn-secondary">关闭</button>
+                <button type="button" onclick="updatePassword()" class="btn btn-primary">确认</button>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    function updatePassword() {
+      const oldPassword = $("#oldPassword").val();
+      const newPassword = $("#newPassword").val();
+      const reNewPassword = $("#reNewPassword").val();
+      if (!newPassword) {
+        layer.alert("请输入新密码", {title: '友情提示', icon: 2});
+      } else if (newPassword != reNewPassword) {
+        layer.alert("两次输入密码不一致", {title: '友情提示', icon: 2});
+      } else {
+        $.getJSON("{:url('admin/index/updatePassword')}", {oldPassword : oldPassword, newPassword: newPassword}, function(res){
+          if(1 == res.code){
+            layer.alert(res.msg, {title: '友情提示', icon: 1, closeBtn: 0}, function(){
+              location.reload();
+            });
+          }else{
+            layer.alert(res.msg, {title: '友情提示', icon: 2});
+          }
+        });
+      }
+    }
+</script>
+

+ 86 - 0
application/admin/view/login/login.html

@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title></title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="robots" content="all,follow">
+    <!-- Bootstrap CSS-->
+    <link rel="stylesheet" href="__VENDOR__/bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome CSS-->
+    <link rel="stylesheet" href="__VENDOR__/font-awesome/css/font-awesome.min.css">
+    <!-- Fontastic Custom icon font-->
+    <link rel="stylesheet" href="__CSS__/fontastic.css">
+    <!-- Google fonts - Poppins -->
+    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,700">
+    <!-- theme stylesheet-->
+    <link rel="stylesheet" href="__CSS__/style.default.css" id="theme-stylesheet">
+    <!-- Custom stylesheet - for your changes-->
+    <link rel="stylesheet" href="__CSS__/custom.css">
+    <!-- Favicon-->
+    <link rel="shortcut icon" href="__IMG__/favicon.ico">
+    <!-- Tweaks for older IEs--><!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
+  </head>
+  <body>
+    <div class="page login-page">
+      <div class="container d-flex align-items-center">
+        <div class="form-holder has-shadow">
+          <div class="row">
+            <!-- Logo & Information Panel-->
+            <div class="col-lg-6">
+              <div class="info d-flex align-items-center">
+                <div class="content">
+                  <div class="logo">
+                    <h1>后台管理系统</h1>
+                  </div>
+                  <!--<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>-->
+                </div>
+              </div>
+            </div>
+            <!-- Form Panel    -->
+            <div class="col-lg-6 bg-white">
+              <div class="form d-flex align-items-center">
+                <div class="content">
+                  <form method="post" class="form-validate" >
+                    <div class="form-group">
+                      <input id="login-username" type="text" name="name" required data-msg="请输入您的用户名" class="input-material">
+                      <label for="login-username" class="label-material">用户名</label>
+                    </div>
+                    <div class="form-group">
+                      <input id="login-password" type="password" name="password" required data-msg="请输入您的密码" class="input-material">
+                      <label for="login-password" class="label-material">密码</label>
+                    </div>
+                    <div>
+                      <small style="color: #f20000" id="errorMsg">{$errorMsg}</small>
+                    </div>
+                    <input style="margin-top: 30px;" type="submit" class="btn btn-primary" value="登陆"/>
+                    <!-- This should be submit button but I replaced it with <a> for demo purposes-->
+                  </form>
+                  <!--<a href="#" class="forgot-pass">Forgot Password?</a><br><small>Do not have an account? </small><a href="register.html" class="signup">Signup</a>-->
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="copyrights text-center">
+        <!--<p>Design by <a href="#" class="external">Bootstrapious</a>
+          &lt;!&ndash; Please do not remove the backlink to us unless you support further theme's development at https://bootstrapious.com/donate. It is part of the license conditions. Thank you for understanding :)&ndash;&gt;
+        </p>-->
+      </div>
+    </div>
+    <!-- JavaScript files-->
+    <script src="__VENDOR__/jquery/jquery.min.js"></script>
+    <script src="__VENDOR__/popper.js/umd/popper.min.js"> </script>
+    <script src="__VENDOR__/bootstrap/js/bootstrap.min.js"></script>
+    <script src="__VENDOR__/jquery.cookie/jquery.cookie.js"> </script>
+    <script src="__VENDOR__/chart.js/Chart.min.js"></script>
+    <script src="__VENDOR__/jquery-validation/jquery.validate.min.js"></script>
+    <!-- Main File-->
+    <script src="__JS__/front.js"></script>
+  </body>
+</html>

+ 177 - 133
application/common.php

@@ -9,116 +9,116 @@
 // | Author: 流年 <liu21st@gmail.com>
 // +----------------------------------------------------------------------
 
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
-use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
-use PhpOffice\PhpSpreadsheet\Reader\Xls;
-use PhpOffice\PhpSpreadsheet\IOFactory;
-use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
-use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
-use PhpOffice\PhpSpreadsheet\Cell\DataType;
-use PhpOffice\PhpSpreadsheet\Style\Fill;
-use PhpOffice\PhpSpreadsheet\Style\Color;
-use PhpOffice\PhpSpreadsheet\Style\Alignment;
-use PhpOffice\PhpSpreadsheet\Style\Border;
-use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
-
-
-// 应用公共文件
 /**
- * 删除目录以及其下的文件
- * @param $directory
- * @return bool
+ * 定义常量
  */
-function removeDir($directory)
-{
-    if (false == is_dir($directory)) {
-        return false;
-    }
+$server_name = $_SERVER['SERVER_NAME'];
+$server_name_html = "www" . substr($server_name, strpos($server_name, '.'));
+define("URL", $server_name_html);
+//国际化
+define("LANG", ['zh-cn', 'en-us']);
 
-    $handle = opendir($directory);
-    while (false !== ($file = readdir($handle))) {
-        if ('.' != $file && '..' != $file) {
-            is_dir("$directory/$file") ? removeDir("$directory/$file") : @unlink("$directory/$file");
-        }
-    }
 
-    if (readdir($handle) == false) {
-        closedir($handle);
-        rmdir($directory);
-    }
-
-    return true;
-}
 
 
-function Kfid($uid)
-{
-    return trim($uid, 'KF');
+/**
+ * 获取request
+ */
+function requestInfo() {
+    $requestInfo = \think\Request::instance();
+    return $requestInfo;
 }
 
-function kfUid($id)
-{
-    return 'KF' . $id;
+/**
+ * 获取header
+ */
+function headerInfo() {
+    $requestInfo = requestInfo ();
+    $headerInfo = $requestInfo->header();
+    return $headerInfo;
 }
 
-//数组转为健的数组
-function kftoKey($uidArray, $type = 0)
-{
-    $return = [];
-    foreach ($uidArray as $val) {
-        if ($type == 0) {
-            $return[$val] = 0;
-        } elseif ($type == 1) {
-            $return[$val] = [];
-        } else {
-            $return[$val] = $val;
-        }
+/**
+ * 随机盐值
+ */
+function GenEncryption() {
+    // 生成随机数.
+    srand((double) microtime() * 1000000);
+    $ychar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
+    $list = explode(",", $ychar);
+    $authnum = "";
+    for ($i = 0; $i < 6; $i++) {
+        $randnum = rand(0, 61); // 10+26;
+        $authnum .= $list[$randnum];
     }
-    return $return;
+    return $authnum;
 }
 
+/**
+ * 密码加密
+ */
+function GenPassword($password) {
+    $Enc = GenEncryption();
+    $Pwd = md5(md5($Enc . $password));
+    return array("encryption" => $Enc, "password" => $Pwd);
+}
 
-//保留小数位数
-function floatPointDigit($data, $long = 2)
-{
-    $long = intval($long);
-    $for1 = "%." . $long . "f";
-    $for2 = "%." . ($long + 1) . "f";
-    return sprintf($for1, substr(sprintf($for2, $data), 0, -1));
+/**
+ * 生成token
+ *
+ * @return string
+ */
+function getToken() {
+    $enc = GenEncryption();
+    $time = time();
+    $token = substr(uniqid($enc . $time), 0, 35);
+    return $token;
 }
 
-//秒格式化为 小时分秒
-function secendToHourMinit($sec)
-{
-    $array = ['h' => 0, 'm' => 0, 's' => 0];
-    $sec = intval($sec);
-    $array['h'] = floor($sec / 3600);
-    $array['m'] = floor(($sec - 3600 * $array['h']) / 60);
-    $array['s'] = $sec - 3600 * $array['h'] - 60 * $array['m'];
-
-    $return = '';
-    if ($array['h']) {
-        $return .= $array['h'] . '小时';
-    }
+/**
+ * UUID 生成
+ */
+function UUID() {
+    $prefix = '';
+    $str = md5(uniqid(mt_rand(), true));
+    $uuid = substr($str, 0, 8) . '-';
+    $uuid .= substr($str, 8, 4) . '-';
+    $uuid .= substr($str, 12, 4) . '-';
+    $uuid .= substr($str, 16, 4) . '-';
+    $uuid .= substr($str, 20, 12);
+    return $prefix . $uuid;
+}
 
-    if ($array['m']) {
-        $return .= $array['m'] . '分';
-    }
+/**
+ * 订单 生成
+ */
+function OrderID($prefix = '') {
+    $num = mt_rand(100, 999);
+    list($s, $m) = explode(' ', microtime());
+    $order = date("YmdHis") . ($s * 1000000) . $num;
+    return $prefix . $order;
+}
+
+/**
+ * 获取客户端真实IP
+ */
+function GETIP() {
+    global $ip;
 
-    if ($array['s']) {
-        $return .= $array['s'] . '秒';
+    if (getenv("HTTP_CLIENT_IP")) {
+        $ip = getenv("HTTP_CLIENT_IP");
+    } else if (getenv("HTTP_X_FORWARDED_FOR")) {
+        $ip = getenv("HTTP_X_FORWARDED_FOR");
+    } else if (getenv("REMOTE_ADDR")) {
+        $ip = getenv("REMOTE_ADDR");
+    } else {
+        $ip = "Unknow";
     }
 
-    return $return;
+    return $ip;
 
 }
 
-//小数转百分比显示
-function perDisplay($dit, $xiaos = 2)
-{
-    return floatPointDigit(floor(100 * $dit), $xiaos) . '%';
-}
-
 /**
  * 数据加密
  */
@@ -167,57 +167,101 @@ function unlock_url($txt, $key)
     return base64_decode($tmp);
 }
 
-
 /**
- * 接口调用
- *
- * @access public
- * @param mixed $url 接口地址
- * @param mixed $where $params参数
- * @param mixed $timeout 请求时效
- * @return String
+ * 分页
  */
-function make_request($url, $params, $timeout=30)
+function getPage($count, $pageSize, $currentPage)
 {
-    set_time_limit(0);
-    if (function_exists('curl_init') === true) {
-        $ch = curl_init();
-        $header = array(
-            'Accept-Language: zh-cn',
-            'Connection: Keep-Alive',
-            'Cache-Control: no-cache'
-        );
-        curl_setopt($ch, CURLOPT_POST, 1);
-        curl_setopt($ch, CURLOPT_URL, $url);
-        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
-        if ($timeout > 0) curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
-        $result = curl_exec($ch);
-        $errno = curl_errno($ch);
-        curl_close($ch);
-        return $result;
-    } else {
-        $context = array(
-            'http' => array(
-                'method' => 'POST',
-                'header' => 'Content-type: application/x-www-form-urlencoded' . "\r\n" .
-                    'Content-length: ' . strlen($params),
-                'content' => $params));
-        if ($timeout > 0) $context['http']['timeout'] = $timeout;
-        $contextid = stream_context_create($context);
-        $sock = @fopen($url, 'r', false, $contextid);
-        if ($sock) {
-            $result = '';
-            while (!feof($sock)) {
-                $result .= fgets($sock, 8192);
-            }
-            fclose($sock);
+    // 总页数.
+    $allPage = ceil($count/$pageSize);
+    $page = [];
+    if ($allPage > 5) {
+        // 判断开始页码.
+        if ($currentPage <= 3) {
+            $n = 1;
+        } else if ($currentPage >= ($allPage - 2)) {
+            $n = ($allPage - 4);
         } else {
-            return 'TimeOut';
+            $n = ($currentPage - 2);
+        }
+
+        for ($i = 0; $i <= 4; $i++) {
+            $page[$i] = $n;
+            $n++;
+        }
+    } else {
+        for ($i = 0; $i <= ($allPage - 1); $i++) {
+            $page[$i] = $i + 1;
+        }
+    }
+
+    return $page;
+}
+
+/**
+ * CODE生成
+ */
+function getCode() {
+    $format = 8;
+    $dics = array(
+        0=>'0',    1=>'1', 2=>'2', 3=>'3', 4=>'4', 5=>'5', 6=>'6', 7=>'7', 8=>'8',
+        9=>'9', 10=>'A',  11=>'B', 12=>'C', 13=>'D', 14=>'E', 15=>'F',  16=>'G',  17=>'H',
+        18=>'I',19=>'J',  20=>'K', 21=>'L',  22=>'M',  23=>'N', 24=>'O', 25=>'P', 26=>'Q',
+        27=>'R',28=>'S',  29=>'T',  30=>'U', 31=>'V',  32=>'W',  33=>'X', 34=>'Y', 35=>'Z'
+    );
+    list($msec, $sec) = explode(' ', microtime());
+    $msectime =  (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
+    $int = substr($msectime,0,13);
+    $dnum = 36; //进制数
+    $arr = array ();
+    $loop = true;
+    while ($loop) {
+        $arr[] = $dics[bcmod($int, $dnum)];
+        $int = bcdiv($int, $dnum, 0);
+        if ($int == '0') {
+            $loop = false;
         }
     }
-    return $result;
+    if (count($arr) < $format)
+        $arr = array_pad($arr, $format, $dics[0]);
+
+    return implode('', array_reverse($arr));
+}
+
+/**
+ * 生成随机密码
+ */
+function randomPassword($len = 32, $keyword = '') {
+
+    if (strlen($keyword) > $len) {//关键字不能比总长度长
+
+        return false;
+
+    }
+
+    $str = '';
+
+    $chars = 'abcdefghijkmnpqrstuvwxyz23456789ABCDEFGHIJKMNPQRSTUVWXYZ'; //去掉1跟字母l防混淆
+
+    if ($len > strlen($chars)) {//位数过长重复字符串一定次数
+
+        $chars = str_repeat($chars, ceil($len / strlen($chars)));
+
+    }
+
+    $chars = str_shuffle($chars); //打乱字符串
+
+    $str = substr($chars, 0, $len);
+
+    if (!empty($keyword)) {
+
+        $start = $len - strlen($keyword);
+
+        $str = substr_replace($str, $keyword, mt_rand(0, $start), strlen($keyword)); //从随机位置插入关键字
+
+    }
 
-}//end make_request()
+    return $str;
+
+}
 

+ 239 - 21
application/config.php

@@ -14,31 +14,144 @@ return [
     // | 应用设置
     // +----------------------------------------------------------------------
 
-    // 当前系统版本
-    'version' => 'v1.0.1',
+    // 应用命名空间
+    'app_namespace'          => 'app',
+    // 应用调试模式
+    'app_debug'              => true,
+    // 应用Trace
+    'app_trace'              => true,
+    // 应用模式状态
+    'app_status'             => '',
+    // 是否支持多模块
+    'app_multi_module'       => true,
+    // 入口自动绑定模块
+    'auto_bind_module'       => false,
+    // 注册的根命名空间
+    'root_namespace'         => [],
+    // 扩展函数文件
+    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],
+    // 默认输出类型
+    'default_return_type'    => 'html',
+    // 默认AJAX 数据返回格式,可选json xml ...
+    'default_ajax_return'    => 'json',
+    // 默认JSONP格式返回的处理方法
+    'default_jsonp_handler'  => 'jsonpReturn',
+    // 默认JSONP处理方法
+    'var_jsonp_handler'      => 'callback',
+    // 默认时区
+    'default_timezone'       => 'PRC',
+    // 是否开启多语言
+    'lang_switch_on'         => true,
+    'lang_list'              => ['zh-cn','en-us'],
+    // 默认全局过滤方法 用逗号分隔多个
+    'default_filter'         => '',
+    // 默认语言
+    'default_lang'           => 'zh-cn',
+    // 应用类库后缀
+    'class_suffix'           => false,
+    // 控制器类后缀
+    'controller_suffix'      => false,
 
-    // 加密盐
-    'salt' => '~NickBai!@#',
+    // +----------------------------------------------------------------------
+    // | 模块设置
+    // +----------------------------------------------------------------------
 
-    // socket server
-    'socket' => 'ky.281570.com:9101',
+    // 默认模块名
+    'default_module'         => 'index',
+    // 禁止访问模块
+    'deny_module_list'       => ['common'],
+    // 默认控制器名
+    'default_controller'     => 'Index',
+    // 默认操作名
+    'default_action'         => 'index',
+    // 默认验证器
+    'default_validate'       => '',
+    // 默认的空控制器名
+    'empty_controller'       => 'Error',
+    // 操作方法后缀
+    'action_suffix'          => '',
+    // 自动搜索控制器
+    'controller_auto_search' => false,
 
-    // 管理员登录时间
-    'save_time' => 86400,
+    // +----------------------------------------------------------------------
+    // | URL设置
+    // +----------------------------------------------------------------------
 
+    // PATHINFO变量名 用于兼容模式
+    'var_pathinfo'           => 's',
+    // 兼容PATH_INFO获取
+    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
+    // pathinfo分隔符
+    'pathinfo_depr'          => '/',
+    // URL伪静态后缀
+    'url_html_suffix'        => 'html',
+    // URL普通方式参数 用于自动生成
+    'url_common_param'       => false,
+    // URL参数方式 0 按名称成对解析 1 按顺序解析
+    'url_param_type'         => 0,
+    // 是否开启路由
+    'url_route_on'           => true,
+    // 路由使用完整匹配
+    'route_complete_match'   => false,
+    // 路由配置文件(支持配置多个)
+    'route_config_file'      => ['route'],
+    // 是否强制使用路由
+    'url_route_must'         => false,
+    // 域名部署
+    'url_domain_deploy'      => false,
+    // 域名根,如thinkphp.cn
+    'url_domain_root'        => '',
+    // 是否自动转换URL中的控制器和操作名
+    'url_convert'            => true,
+    // 默认的访问控制器层
+    'url_controller_layer'   => 'controller',
+    // 表单请求类型伪装变量
+    'var_method'             => '_method',
+    // 表单ajax伪装变量
+    'var_ajax'               => '_ajax',
+    // 表单pjax伪装变量
+    'var_pjax'               => '_pjax',
+    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+    'request_cache'          => false,
+    // 请求缓存有效期
+    'request_cache_expire'   => null,
 
-    'cache' => [
-        'type' => 'File',
-        'path' => CACHE_PATH,
-        'prefix' => '',
-        'expire' => 0,
+    // +----------------------------------------------------------------------
+    // | 模板设置
+    // +----------------------------------------------------------------------
+
+    'template'               => [
+        // 模板引擎类型 支持 php think 支持扩展
+        'type'         => 'Think',
+        // 模板路径
+        'view_path'    => '',
+        // 模板后缀
+        'view_suffix'  => 'html',
+        // 模板文件名分隔符
+        'view_depr'    => DS,
+        // 模板引擎普通标签开始标记
+        'tpl_begin'    => '{',
+        // 模板引擎普通标签结束标记
+        'tpl_end'      => '}',
+        // 标签库标签开始标记
+        'taglib_begin' => '{',
+        // 标签库标签结束标记
+        'taglib_end'   => '}',
     ],
 
+    // 视图输出字符串内容替换
+    'view_replace_str'       => [],
+    // 默认跳转页面对应的模板文件
+    'dispatch_success_tmpl'  => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
+    'dispatch_error_tmpl'    => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
 
-    // 应用命名空间
-    'app_namespace' => 'app',
+    // +----------------------------------------------------------------------
+    // | 异常及错误设置
+    // +----------------------------------------------------------------------
 
-    'exception_tmpl' => '',
+    // 异常页面的模板文件
+    //'exception_tmpl'         => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
+    'exception_tmpl'         => '',
     'http_exception_template' => [
         // 定义404错误的重定向页面地址
         '404' => APP_PATH.'404.html',
@@ -47,9 +160,114 @@ return [
         '403' => APP_PATH.'404.html',
     ],
 
-    // 应用调试模式
-    'app_debug' => true,
-    // 应用Trace
-    'app_trace' => true
-];
+    // 错误显示信息,非调试模式有效
+    'error_message'          => '页面错误!请稍后再试~',
+    // 显示错误信息
+    'show_error_msg'         => true,
+    // 异常处理handle类 留空使用 \think\exception\Handle
+    'exception_handle'       => '',
+
+    // +----------------------------------------------------------------------
+    // | 日志设置
+    // +----------------------------------------------------------------------
+
+    'log'                    => [
+        // 日志记录方式,内置 file socket 支持扩展
+        'type'  => 'File',
+        // 日志保存目录
+        'path'  => LOG_PATH,
+        // 日志记录级别
+        'level' => ['error', 'sql', 'redis'],
+    ],
 
+    // +----------------------------------------------------------------------
+    // | Trace设置 开启 app_trace 后 有效
+    // +----------------------------------------------------------------------
+    'trace'                  => [
+        // 内置Html Console 支持扩展
+        'type' => 'Html',
+    ],
+
+    // +----------------------------------------------------------------------
+    // | 缓存设置
+    // +----------------------------------------------------------------------
+
+   'cache'                  => [
+       // 驱动方式
+       'type'   => 'File',
+       // 缓存保存目录
+       'path'   => CACHE_PATH,
+       // 缓存前缀
+       'prefix' => '',
+       // 缓存有效期 0表示永久缓存
+       'expire' => 0,
+   ],
+    // 'cache'                  => [
+    //     'type'   => 'redis',
+    //     'host'       => '192.168.33.10',
+    //     'port'       => 6379,
+    //     'password'   => 'aqm1728',
+    //     'select' => 0,
+    // ],
+
+    // +----------------------------------------------------------------------
+    // | 会话设置
+    // +----------------------------------------------------------------------
+
+    /*'session'                => [
+        'id'             => '',
+        // SESSION_ID的提交变量,解决flash上传跨域
+        'var_session_id' => '',
+        // SESSION 前缀
+        'prefix'         => 'think',
+        // 驱动方式 支持redis memcache memcached
+        'type'           => '',
+        // 是否自动开启 SESSION
+        'auto_start'     => true,
+    ],*/
+    'session'                => [
+        'id'             => '',
+        // SESSION_ID的提交变量,解决flash上传跨域
+        'var_session_id' => '',
+        // SESSION 前缀
+        'prefix'         => 'module',
+        // 驱动方式 支持redis memcache memcached
+        'type'           => '',
+        // 'host'       => '192.168.33.10',
+        // 'port'       => 6379,
+        // 'password'   => 'aqm1728',
+        // 是否自动开启 SESSION
+        'auto_start'     => true,
+        'select'     => 8,
+
+        
+    ],
+
+    // +----------------------------------------------------------------------
+    // | Cookie设置
+    // +----------------------------------------------------------------------
+    'cookie'                 => [
+        // cookie 名称前缀
+        'prefix'    => '',
+        // cookie 保存时间
+        'expire'    => 0,
+        // cookie 保存路径
+        'path'      => '/',
+        // cookie 有效域名
+        'domain'    => '',
+        //  cookie 启用安全传输
+        'secure'    => false,
+        // httponly设置
+        'httponly'  => '',
+        // 是否使用 setcookie
+        'setcookie' => true,
+    ],
+
+    //分页配置
+    'paginate'               => [
+        'type'      => 'bootstrap',
+        'var_page'  => 'page',
+        'list_rows' => 1,
+    ],
+
+];

+ 10 - 6
application/database.php

@@ -15,11 +15,11 @@ return [
     // 服务器地址
     'hostname'        => '127.0.0.1',
     // 数据库名
-    'database'        => 'customer_service',
+    'database'        => 'verification',
     // 用户名
     'username'        => 'root',
     // 密码
-    'password'        => 'root1234',
+    'password'        => 'root',
     // 端口
     'hostport'        => '3306',
     // 连接dsn
@@ -27,11 +27,11 @@ return [
     // 数据库连接参数
     'params'          => [],
     // 数据库编码默认采用utf8
-    'charset'         => 'utf8mb4',
+    'charset'         => 'utf8',
     // 数据库表前缀
-    'prefix'          => 'ws_',
+    'prefix'          => 'verify_',
     // 数据库调试模式
-    'debug'           => false,
+    'debug'           => true,
     // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
     'deploy'          => 0,
     // 数据库读写是否分离 主从式有效
@@ -41,7 +41,7 @@ return [
     // 指定从服务器序号
     'slave_no'        => '',
     // 是否严格检查字段是否存在
-    'fields_strict'   => false,
+    'fields_strict'   => true,
     // 数据集返回类型
     'resultset_type'  => 'array',
     // 自动写入时间戳字段
@@ -50,4 +50,8 @@ return [
     'datetime_format' => 'Y-m-d H:i:s',
     // 是否需要进行SQL性能分析
     'sql_explain'     => false,
+    // Builder类
+    'builder'         => '',
+    // Query类
+    'query'           => '\\think\\db\\Query',
 ];

+ 14 - 0
application/extra/queue.php

@@ -0,0 +1,14 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: yunwuxin <448901948@qq.com>
+// +----------------------------------------------------------------------
+
+return [
+    'connector' => 'Sync'
+];

+ 5 - 3
application/index/config.php

@@ -1,5 +1,7 @@
 <?php
 //配置文件
-return [
-
-];
+/*return [
+    'paginate' => [
+        'type'
+    ],
+];*/

+ 21 - 16
application/index/controller/Common.php

@@ -2,10 +2,11 @@
 namespace app\index\controller;
 
 use think\Controller;
+use think\Exception;
+use think\Session;
+use think\Log;
+use think\cache\driver\Redis;
 
-/**
- * 公共类
- */
 class Common extends Controller
 {
 
@@ -16,22 +17,26 @@ class Common extends Controller
      * @access public
      * @return string
      */
-    protected function verifyApiToken()
+    protected function verifyToken()
     {
-        $request     = \think\Request::instance();
-        $getApiToken = input('server.HTTP_apiToken');
-        $action      = $request->action();
-        $controller  = $request->controller();
-        $module      = $request->module();
-        $apiToken    = md5(strtolower($action.'Customer-Service'.$controller.$module));
-        //print_r([strtolower($action.'Customer-Service'.$controller.$module),$apiToken, $getApiToken]);die;
-        if ($getApiToken === $apiToken) {
-            return true;
-        } else {
-            return false;
+        $userToken = input('get.userToken');
+        // 获取用户信息.
+        $getUserInfo = model('User')->currentUser($userToken);
+        $getUserInfo = $getUserInfo['data'];
+        if($getUserInfo){
+            $nowTime  = strtotime(date('Y-m-d H:i:s').'-1 week');
+            if ($getUserInfo['user_lastOperation'] < $nowTime) {
+                return lang('EA01005');
+            }
+            $userInfo['user_lastOperation'] = time();
+            model('User')->updateLastOperation($userToken,$userInfo['user_lastOperation']);
+            return 1;
+        }
+         else {
+            return lang('EA01004');
         }
 
-    }//end verifyApiToken()
+    }//end verifyToken()
 
 
 }

+ 354 - 98
application/index/controller/Index.php

@@ -1,128 +1,384 @@
 <?php
-
 namespace app\index\controller;
 
 use think\Controller;
+use think\Exception;
+use think\Session;
+
 
 class Index extends Common
 {
 
+    /**
+     * 修改用户密码
+     *
+     * @access public
+     * @return string
+     */
+    public function updatePassword()
+    {
+        // 验证token.
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
+        }
+
+        try {
+            $getData = array_keys(input('post.'));
+            $getData = json_decode($getData[0], 256);
+            if(empty($getData['oldPassword'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01013')]);
+            }
+            if(empty($getData['newPassword'])) {
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01014')]);
+            }
+
+            // 修改密码.
+            $updatePassword = model('User')->updatePassword($getData);
+            if ($updatePassword['code'] === 1) {
+                $code = 1;
+                $msg  = $updatePassword['msg'];
+                $data = $updatePassword['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $updatePassword['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end updatePassword()
+
 
     /**
-     * 获取敏感词
+     * 获取平台列表
      *
      * @access public
-     * @return array JsonString
+     * @return string
      */
-    public function sensitiveWords()
+    public function platformList()
     {
         // 验证token.
-        $tokenStatus = $this->verifyApiToken();
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
+        }
+
+        try {
+            // 获取平台列表.
+            $platformList = model('Platform')->platformList();
+            if ($platformList['code'] === 1) {
+                $code = 1;
+                $msg  = $platformList['msg'];
+                $data = $platformList['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $platformList['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end platformList()
+
+
+    /**
+     * 安全验证
+     *
+     * @access public
+     * @return string
+     */
+    public function securityVerify()
+    {
         $code = -2;
-        $msg = '错误';
-        if ($tokenStatus === false) {
-            $msg = 'token错误';
-            return json(['code' => $code, 'data' => [], 'msg' => $msg]);
+        $msg  = lang('EC01002');
+        $data = [];
+        try {
+            // 安全验证.
+            $securityVerify = model('Platform')->securityVerify();
+            if ($securityVerify['code'] === 1) {
+                $code = 1;
+                $msg  = $securityVerify['msg'];
+                $data = $securityVerify['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $securityVerify['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end securityVerify()
+
+
+    /**
+     * 获取已注册平台列表
+     *
+     * @access public
+     * @return string
+     */
+    public function myPlatform()
+    {
+        // 验证token.
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
         }
 
         try {
-            // 获取敏感词.
-            $wordsField = ['*'];
-            $sysWordsWhere['sensitivewords_status'] = 1;
-            $sysWordsWhere['sensitivewords_for'] = 1;
-            // 查询客服敏感词.
-            $userSensitive = model('sensitivewords')->selectWords($wordsField, $sysWordsWhere);
-            // 获取敏感词.
-            $wordsField = ['*'];
-            $sysWordsWhere['sensitivewords_status'] = 1;
-            $sysWordsWhere['sensitivewords_for'] = 2;
-            // 查询用户敏感词.
-            $serverSensitive = model('sensitivewords')->selectWords($wordsField, $sysWordsWhere);
-            $data = [
-                'userSensitive' => $userSensitive,
-                'serverSensitive' => $serverSensitive,
-            ];
-
-            return json(['code' => 1, 'data' => $data, 'msg' => '成功']);
-        } catch (\Exception $e) {
-            return json(['code' => $code, 'data' => [], 'msg' => $msg]);
-        }//end try
-
-    }//end sensitiveWords()
-
-
-    public function index()
+            // 获取平台列表.
+            $myPlatform = model('Platform')->myPlatform();
+            if ($myPlatform['code'] === 1) {
+                $code = 1;
+                $msg  = $myPlatform['msg'];
+                $data = $myPlatform['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $myPlatform['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end myPlatform()
+
+
+    /**
+     * 获取平台验证码
+     *
+     * @access public
+     * @return string
+     */
+    public function platformToken()
     {
-        return $this->fetch();
-    }
+        // 验证token.
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
+        }
 
-    // pc客户端
-    public function chat()
+        try {
+            $getData = array_keys(input('post.'));
+            $getData = json_decode($getData[0], 256);
+            if(empty($getData['platformId'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EP01005')]);
+            }
+            // 获取平台验证码.
+            $platformToken = model('Platform')->platformToken($getData);
+            if ($platformToken['code'] === 1) {
+                $code = 1;
+                $msg  = $platformToken['msg'];
+                $data = $platformToken['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $platformToken['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end platformToken()
+
+
+    /**
+     * 验证返回信息
+     *
+     * @access public
+     * @return string
+     */
+    public function verifyPlatform()
     {
-        // 跳转到移动端
-        if (request()->isMobile()) {
-            $param = http_build_query([
-                'id' => input('param.id'),
-                'name' => input('param.name'),
-                'group' => input('param.group'),
-                'avatar' => input('param.avatar')
-            ]);
-            $this->redirect('/index/index/mobile?' . $param);
-        }
-
-        $this->assign([
-            'socket' => config('socket'),
-            'id' => input('param.id'),
-            'name' => input('param.name'),
-            'group' => input('param.group'),
-            'avatar' => input('param.avatar'),
-        ]);
-
-        return $this->fetch();
-    }
-
-    // 移动客户端
-    public function mobile()
+        // 验证token.
+        $code = -2;
+        $msg  = lang('EC01002');
+        $data = [];
+        try {
+            // 获取平台验证码.
+            $platformToken = model('Platform')->verifyPlatform();
+            //return json(['code' => 11, 'data' => 22, 'msg' => 11]);
+            if ($platformToken['code'] === 1) {
+                $code = 1;
+                $msg  = $platformToken['msg'];
+                $data = $platformToken['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $platformToken['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end verifyPlatform()
+
+
+    /**
+     * 获取消息发送验证
+     *
+     * @access public
+     * @return string
+     */
+    public function sendMsgVerify()
     {
-        $this->assign([
-            'socket' => config('socket'),
-            'id' => input('param.id'),
-            'name' => input('param.name'),
-            'group' => input('param.group'),
-            'avatar' => input('param.avatar'),
-        ]);
-
-        return $this->fetch();
-    }
-
-    public function systime()
+        // 验证token.
+        $code = -2;
+        $msg  = lang('EC01002');
+        $data = [];
+
+        try {
+            // 消息发送.
+            $sendMessage = model('Message')->sendMsgVerify();
+            if ($sendMessage['code'] === 1) {
+                $code = 1;
+                $msg  = $sendMessage['msg'];
+                $data = $sendMessage['data'];
+
+                // 失败则返回错误信息.
+            } else {
+                $msg = $sendMessage['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end sendMsgVerify()
+
+
+    /**
+     * 消息接收
+     *
+     * @access public
+     * @return string
+     */
+    public function platformMessage()
     {
-        $now = time();
-        $time = date('Y-m-d H:i', $now);
-        $settings = db('settings')->where('id', 1)->find();
-        return json(['code' => 1, 'data' => ['time' => $time, 'logo' => $settings['logo'], 'enterprise_name' => $settings['enterprise_name']], 'msg' => '成功']);
-    }
+        // 验证token.
+        $code = -2;
+        $msg  = lang('EC01002');
+        $data = [];
+        try {
+            // 消息接收.
+            $platformMessage = model('Message')->getMessage();
+            if ($platformMessage['code'] === 1) {
+                $code = 1;
+                $msg  = $platformMessage['msg'];
+                $data = $platformMessage['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $platformMessage['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end platformMessage()
 
 
-    //得到公共配置信息
-    public function getConfigs()
+    /**
+     * 消息发送
+     *
+     * @access public
+     * @return string
+     */
+    public function sendMessage()
     {
-        $now = time();
-        $time = date('Y-m-d H:i', $now);
-
-        $checkcode = db('platform')->where('platform_code', 'Customer-Service')->find();
-        $chkcode = $checkcode ? $checkcode['platform_status'] : 1;
-
-        $settings = db('settings')->where('id', 1)->find();
-
-        $ret = [
-            'time' => $time,
-            'checkcodeflag' => $chkcode,
-            'logo' => $settings['logo'],
-            'enterprise_name' => $settings['enterprise_name'],
-        ];
-        return json(['code' => 1, 'data' => $ret, 'msg' => 'success']);
-    }
+        // 验证token.
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
+        }
+
+        try {
+            // 消息发送.
+            $sendMessage = model('Message')->sendMessage();
+            if ($sendMessage['code'] === 1) {
+                $code = 1;
+                $msg  = $sendMessage['msg'];
+                $data = $sendMessage['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $sendMessage['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end sendMessage()
+
+    /**
+     * 解除绑定
+     *
+     * @access public
+     * @return string
+     */
+    public function unBind()
+    {
+        // 验证token.
+        $code        = -2;
+        $msg         = lang('EC01002');
+        $data        = [];
+        $tokenStatus = $this->verifyToken();
+        if ($tokenStatus !== 1) {
+            return json(['code' => $code, 'data' => $data, 'msg' => $tokenStatus]);
+        }
+
+        try {
+            $getData = array_keys(input('post.'));
+            $getData = json_decode($getData[0], 256);
+
+            //验证密码
+            $checkPwd = model('User')->checkPwd($getData);
+            if ($checkPwd['code'] !== 1) {
+                return json(['code' => $checkPwd['code'], 'data' => '', 'msg' => $checkPwd['msg']]);
+            }
+            // 解除绑定.
+            $unBind = model('UserPlatform')->unBind($getData);
+            if ($unBind['code'] === 1) {
+                $code = 1;
+                $msg  = $unBind['msg'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $unBind['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
+
+        return json(['code' => $code, 'data' => '', 'msg' => $msg]);
+
+    }//end unbind()
 
 
 }

+ 44 - 0
application/index/controller/Lang.php

@@ -0,0 +1,44 @@
+<?php
+namespace app\index\controller;
+
+use think\Controller;
+use think\Exception;
+use think\Log;
+
+class Lang extends Controller
+{
+
+
+    /**
+     * 国际化
+     *
+     * @access public
+     * @return string
+     */
+    public function lang()
+    {
+        $code = -2;
+        $data = [];
+        $msg  = lang('EC01002');
+        try {
+            // 获取头部信息.
+            $header = headerInfo();
+            // 成功则返回成功.
+            if (in_array($header['lang'], LANG)) {
+                $code = 1;
+                $msg  = lang('MC01001');
+                cookie('think_var', $header['lang']);
+                // 失败则返回错误信息.
+            } else {
+                $msg = lang('EC01001');
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }//end try
+
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end lang()
+
+
+}

+ 107 - 59
application/index/controller/Login.php

@@ -1,81 +1,129 @@
 <?php
-/**
- * User: nickbai
- * Date: 2017/10/24 10:46
- * Email: 1902822973@qq.com
- */
 namespace app\index\controller;
 
 use think\Controller;
+use think\Exception;
+use think\Session;
+use think\Log;
+use think\cache\driver\Redis;
 
 class Login extends Controller
 {
-    // 登录首页
-    public function index()
-    {
-        $this->assign([
-            'version' => config('version')
-        ]);
-
-        return $this->fetch();
 
-    }
 
-    // 处理登录
-    public function doLogin()
+    /**
+     * 用户登录
+     *
+     * @access public
+     * @return string
+     */
+    public function login()
     {
-        if(request()->isPost()){
+        $code = -2;
+        $data = [];
+        $msg  = lang('EC01002');
+        try {
+            $getData = array_keys(input('post.'));
+            $getData = json_decode($getData[0], 256);
+            if(empty($getData['name'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01010')]);
+            }
+            if(empty($getData['password'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01011')]);
+            }
+            // 获取用户信息.
+            $userInfo = model('User')->login($getData);
+            // 成功则返回用户信息.
+            if ($userInfo['code'] === 1) {
+                $code = 1;
+                $msg  = $userInfo['msg'];
+                $data = $userInfo['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $userInfo['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
 
-            $userName = input("param.user_name/s");
-            $password = input("param.password/s");
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end login()
 
-            if(empty($userName)){
-                return json(['code' => -1, 'data' => '', 'msg' => '用户名或邮箱不能为空']);
-            }
 
-            if(empty($password)){
-                return json(['code' => -2, 'data' => '', 'msg' => '密码不能为空']);
+    /**
+     * 用户注册
+     *
+     * @access public
+     * @return string
+     */
+    public function registered()
+    {
+        $code = -2;
+        $data = [];
+        $msg  = lang('EC01002');
+        try {
+            $getData = array_keys(input('post.'));
+            $getData = json_decode($getData[0], 256);
+            if(empty($getData['name'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01010')]);
+            }
+            if(empty($getData['password'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01011')]);
             }
+            if(empty($getData['phone'])){
+                return json(['code' => $code, 'data' => $data, 'msg' => lang('EA01012')]);
+            }
+            // 用户注册.
+            $userInfo = model('User')->registered($getData);
+            // 成功则返回用户信息.
+            if ($userInfo['code'] === 1) {
+                $code = 1;
+                $msg  = $userInfo['msg'];
+                $data = $userInfo['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $userInfo['msg'];
+            }
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
+        }
 
-            $user_name = db('accounts')->where('account_name', $userName)->find();
-            $user_email = db('accounts')->where('account_email', $userName)->find();
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
 
-            if(empty($user_name) && empty($user_email)){
-                return json(['code' => -3, 'data' => '', 'msg' => '用户名或邮箱不存在']);
-            }
-            if(!empty($user_name)){$userInfo = $user_name;}
-            if(!empty($user_email)){$userInfo = $user_email;}
+    }//end registered()
 
-            if(md5($password . config('salt')) != $userInfo['password']){
-                return json(['code' => -4, 'data' => '', 'msg' => '密码错误']);
-            }
 
-            if(1 != $userInfo['status']){
-                return json(['code' => -5, 'data' => '', 'msg' => '您已被禁用']);
+    /**
+     * 退出登陆
+     *
+     * @access public
+     * @return string
+     */
+    public function logout()
+    {
+        $code = -2;
+        $data = [];
+        $msg  = lang('EC01002');
+        try {
+            // 退出登陆.
+            $userInfo = model('User')->logout();
+            // 成功.
+            if ($userInfo['code'] === 1) {
+                $code = 1;
+                $msg  = $userInfo['msg'];
+                $data = $userInfo['data'];
+                // 失败则返回错误信息.
+            } else {
+                $msg = $userInfo['msg'];
             }
-
-            // 登陆成功 生成token
-            $module = mt_rand(100000,999999);
-            $token = base64_encode($module.'#$@%!^*/'.time().'/'.$userInfo['id']);
-            // 更新用户状态
-            $param = [
-                'token' => $token,
-                'expire_time' => time(),
-                'last_login_time' => time()
-            ];
-            db('accounts')->where('id', $userInfo['id'])->update($param);
-
-            $this->assign([
-                'token' => $token
-            ]);
-
-            return json(['code' => 1, 'data' => url('user/index'), 'msg' => '登陆成功']);
+        } catch (Exception $e) {
+            Log::write($e->getMessage(), 'error');
         }
-    }
 
-    public function loginOut()
-    {
-        $this->redirect(url('login/index'));
-    }
+        return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
+
+    }//end logout()
+
 
-}
+}

+ 9 - 0
application/index/lang/en-us.php

@@ -0,0 +1,9 @@
+<?php
+return[
+    // 公共
+    'MC01001' => 'Successful language setup',
+    'EC01001' => 'Language settings failed',
+    //用户-登录
+    'MA01001' => 'Login Successfully',
+    'EA01001' => 'Your username or password is incorrect',
+];

+ 52 - 0
application/index/lang/zh-cn.php

@@ -0,0 +1,52 @@
+<?php
+return[
+    // 公共.
+    'MC01001' => '语言设置成功',
+    'MC01002' => '添加成功',
+    'MC01003' => '删除成功',
+    'MC01004' => '修改成功',
+    'MC01005' => '获取成功',
+    'MC01006' => '发布成功',
+    'EC01001' => '语言设置失败',
+    'EC01002' => '未知错误',
+    'EC01003' => '邮箱格式错误',
+    'EC01004' => '发布失败',
+
+    // 用户.
+    'MA01001' => '登录成功',
+    'MA01002' => '注册成功',
+    'MA01003' => '退出成功',
+    'EA01001' => '密码错误',
+    'EA01002' => '用户名错误',
+    'EA01003' => '错误邮箱',
+    'EA01004' => 'token错误',
+    'EA01005' => 'token超时',
+    'EA01006' => '旧密码错误',
+    'EA01007' => '新密码格式错误',
+    'EA01008' => '手机格式错误',
+    'EA01009' => '用户名已存在',
+    'EA01010' => '用户名不能为空',
+    'EA01011' => '密码不能为空',
+    'EA01012' => '手机不能为空',
+    'EA01013' => '旧密码不能为空',
+    'EA01014' => '新密码不能为空',
+
+    // 平台列表.
+    'MP01001' => '列表获取成功',
+    'MP01002' => '验证成功',
+    'EP01001' => '参数错误',
+    'EP01002' => '验证超时, 请重新绑定',
+    'EP01003' => '验证失败',
+    'EP01004' => '该账户已经被绑定',
+    'EP01005' => '平台ID不能为空',
+    'EP01006' => '平台不存在',
+    'EP01007' => '验证码不能为空',
+    'EP01008' => '平台验证码不能为空',
+    'EP01009' => '平台用户名不能为空',
+    'EP01010' => '标题不能为空',
+    'EP01011' => '内容不能为空',
+    'EP01012' => '消息验证码不能为空',
+    'EP01013' => '平台id码不能为空',
+    'EP01014' => '平台用户不能为空',
+    'EP01015' => '解绑成功',
+];

+ 45 - 0
application/index/model/Code.php

@@ -0,0 +1,45 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class Code extends Model
+{
+
+    /**
+     * 添加验证码
+     */
+    public function addCode($data)
+    {
+//        // 添加验证码
+
+        $addCode = $this->insert($data);
+
+    }//end addCode()
+
+
+    /**
+     * 查询验证码
+     */
+    public function selectCode($safetyCodeKey)
+    {
+//        // 查询验证码
+        $codeWhere['code_key'] = $safetyCodeKey;
+        $code = $this
+            ->field('code_key, code_time')
+            ->where($codeWhere)
+            ->find();
+
+        return [
+            'code' => 1,
+            'msg'  => '',
+            'data' => $code,
+        ];
+
+    }//end addCode()
+
+
+}

+ 245 - 0
application/index/model/Message.php

@@ -0,0 +1,245 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+use think\DB;
+
+class Message extends Model
+{
+
+
+    /**
+     * 消息接收
+     */
+    public function getMessage()
+    {
+        $code  = -2;
+        // 接收参数.
+        $systemKey     = input('post.systemKey');
+        $title         = input('post.title');
+        $content       = htmlspecialchars(input('post.content'));
+        $messageVerify = input('post.messageVerify');
+        if(empty($systemKey)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01008'),
+                'data' => [],
+            ];
+        }
+        if(empty($title)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01010'),
+                'data' => [],
+            ];
+        }
+        if(empty($content)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01011'),
+                'data' => [],
+            ];
+        }
+        if(empty($messageVerify)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01012'),
+                'data' => [],
+            ];
+        }
+        $getData       = [
+            'platform_code' => $systemKey,
+            'messageVerify' => $messageVerify,
+        ];
+
+        // 验证传参.
+        $validate = Loader::validate('Message');
+        if (!$validate->scene('getMessage')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 验证token.
+
+        $MessageVerifyWhere['message_verify'] = $messageVerify;
+        $messageVerify = model('MessageVerify')->selectMessageVerify($MessageVerifyWhere);
+        $messageVerify = $messageVerify['data'];
+        $nowTime    = strtotime(date('Y-m-d H:i:s').'-10 min');
+        if (!$messageVerify || $messageVerify['message_verify_time'] < $nowTime) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01003'),
+                'data' => [],
+            ];
+        }
+
+        // 删除该验证缓存.
+        model('MessageVerify')->delMessageVerify($MessageVerifyWhere);
+
+        // 查询平台信息.
+        $platformWhere = [
+            'platform_code'   => $systemKey,
+            'platform_status' => 1,
+        ];
+        $platform      = model('Platform')
+            ->field(['platform_id', 'platform_identity'])
+            ->where($platformWhere)
+            ->find();
+
+        // 查询平台订阅用户.
+        $userPlatformWhere = [
+            'platform_id' => $platform['platform_id'],
+            'user_status' => 1,
+        ];
+        $userPlatform      = model('UserPlatform')
+            ->field(['a.user_identity'])
+            ->alias('a')
+            ->join('user b', 'a.user_identity = b.user_identity')
+            ->where($userPlatformWhere)
+            ->select();
+        $userPlatform = array_unique($userPlatform, SORT_REGULAR);
+
+        DB::startTrans();
+        // 消息入库.
+        $messageIdentity = UUID();
+        $addMessageData  = [
+            'message_title'     => $title,
+            'message_content'   => $content,
+            'message_identity'  => $messageIdentity,
+            'message_time'      => time(),
+            'message_ip'        => $_SERVER['REMOTE_ADDR'],
+            'platform_identity' => $platform['platform_identity'],
+        ];
+        $addMessage      = $this->insert($addMessageData);
+        // 消息订阅入库.
+        $addError = false;
+        foreach ($userPlatform as $v) {
+            $addUsrMsgData  = [
+                'message_identity' => $messageIdentity,
+                'user_identity'    => $v['user_identity'],
+            ];
+            $addUserMessage = model('MessageUser')->insert($addUsrMsgData);
+            if (empty($addUserMessage) === true) {
+                $addError = true;
+            }
+        }
+
+        if ($addError === false && empty($addMessage) === false) {
+            DB::commit();
+            return [
+                'code' => 1,
+                'msg'  => lang('MC01006'),
+                'data' => [],
+            ];
+        } else {
+            DB::rollback();
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01004'),
+                'data' => [],
+            ];
+        }
+
+    }//end getMessage()
+
+
+    /**
+     * 消息发送
+     */
+    public function sendMessage()
+    {
+        $userToken = input('get.userToken');
+        // 获取用户信息.
+        $getUserInfo = model('user')->currentUser($userToken);
+        $getUserInfo =  $getUserInfo['data'];
+
+        // 消息取出.
+        $where['user_identity'] = $getUserInfo['userId'];
+        $getMessage             = model('MessageUser')
+            ->field(['b.message_id', 'message_title', 'message_content', 'message_time'])
+            ->alias('a')
+            ->join('message b', 'a.message_identity = b.message_identity')
+            ->join('platform c', 'b.platform_identity = c.platform_identity', 'left')
+            ->where($where)
+            ->select();
+
+        // 消息删除.
+        //model('MessageUser')->where($where)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => $getMessage,
+        ];
+
+    }//end sendMessage()
+
+
+    /**
+     * 获取消息发送验证
+     */
+    public function sendMsgVerify()
+    {
+        $code  = -2;
+        // 接收参数.
+        $platformCode = input('get.platformCode');
+        if(empty($platformCode)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01008'),
+                'data' => [],
+            ];
+        }
+        $getData      = ['platform_code' => $platformCode];
+
+        // 验证传参.
+        $validate = Loader::validate('Message');
+        if (!$validate->scene('getMessage')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 查询平台信息.
+        $platformWhere = [
+            'platform_code'   => $platformCode,
+            'platform_status' => 1,
+        ];
+        $platform      = model('Platform')
+            ->field(['platform_id'])
+            ->where($platformWhere)
+            ->find();
+        if (empty($platform) === true) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01002'),
+                'data' => [],
+            ];
+        }
+
+        // 生成验证.
+        $messageVerify = randomPassword();
+        $verifyData    = [
+            'message_verify_time'  => time(),
+            'message_verify' => $messageVerify,
+        ];
+        $addMessageVerify = model('MessageVerify')->addMessageVerify($verifyData);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => ['messageVerify' => $messageVerify],
+        ];
+
+    }//end sendMsgVerify()
+
+
+}

+ 14 - 0
application/index/model/MessageUser.php

@@ -0,0 +1,14 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+use think\DB;
+
+class MessageUser extends Model
+{
+
+
+}

+ 55 - 0
application/index/model/MessageVerify.php

@@ -0,0 +1,55 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class MessageVerify extends Model
+{
+
+    /**
+     * 添加消息验证
+     */
+    public function addMessageVerify($verifyData)
+    {
+        // 添加验证码
+        $addMessageVerify = $this->insert($verifyData);
+
+    }//end addMessageVerify()
+
+
+    /**
+     * 查询消息验证
+     */
+    public function selectMessageVerify($MessageVerifyWhere)
+    {
+        // 查询消息验证
+        $MessageVerify = $this
+            ->field('message_verify, message_verify_time')
+            ->where($MessageVerifyWhere)
+            ->find();
+
+        return [
+            'code' => 1,
+            'msg'  => '',
+            'data' => $MessageVerify,
+        ];
+
+    }//end selectMessageVerify()
+
+    /**
+     * 删除消息验证
+     */
+    public function delMessageVerify($MessageVerifyWhere)
+    {
+        // 删除消息验证
+        $MessageVerify = $this
+            ->where($MessageVerifyWhere)
+            ->delete();
+
+    }//end delMessageVerify()
+
+
+}

+ 264 - 0
application/index/model/Platform.php

@@ -0,0 +1,264 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class Platform extends Model
+{
+    /**
+     * 获取平台列表
+     */
+    public function platformList()
+    {
+        // 获取平台列表.
+        $platformWhere['platform_status'] = 1;
+        $getPlatform = $this
+            ->field('platform_name, platform_code, platform_id, platform_remark, platform_url, platform_img')
+            ->where($platformWhere)
+            ->select();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MP01001'),
+            'data' => ['list' => $getPlatform],
+        ];
+
+    }//end platformList()
+
+
+    /**
+     * 获取已注册平台列表
+     */
+    public function myPlatform()
+    {
+        $userToken = input('get.userToken');
+        // 获取用户信息.
+        $getUserInfo = model('user')->currentUser($userToken);
+        $getUserInfo =  $getUserInfo['data'];
+
+        // 获取平台列表.
+        $platformWhere['platform_status'] = 1;
+        $platformWhere['user_identity']   = $getUserInfo['user_identity'];
+        $getPlatform = $this
+            ->field('platform_user, platform_code, a.platform_id, platform_remark, platform_name, platform_img')
+            ->alias('a')
+            ->join('user_platform b', 'a.platform_id = b.platform_id')
+            ->where($platformWhere)
+            ->select();
+
+        // 循环添加验证码.
+        foreach ($getPlatform as $k => $v) {
+            $newCode  = rand(100000, 999999);
+            $codeData = [
+                'code' => $newCode,
+                'time' => time(),
+            ];
+            $codeKey  = $v['platform_user'].'-'.$v['platform_code'];
+            $data = [
+                'code_key' => $codeKey,
+                'code_time' => $codeData['time'],
+            ];
+            $addCode = model('Code')->addCode($data);
+
+            $getPlatform[$k]['safetyCode'] = $newCode;
+        }
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MP01001'),
+            'data' => ['list' => $getPlatform],
+        ];
+
+    }//end myPlatform()
+
+
+    /**
+     * 安全验证
+     */
+    public function securityVerify()
+    {
+        $code         = -2;
+        $verifyCode   = input('get.verifyCode');
+        $platformCode = input('get.platformCode');
+        $platformUser = input('get.userName');
+        if(empty($verifyCode)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01007'),
+                'data' => [],
+            ];
+        }
+        if(empty($platformCode)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01008'),
+                'data' => [],
+            ];
+        }
+        if(empty($platformUser)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01009'),
+                'data' => [],
+            ];
+        }
+        $safetyCodeKey  = $platformUser.'-'.$platformCode;
+
+        $safetyCodeKey = model('Code')->selectCode($safetyCodeKey);
+        $safetyCodeKey = $safetyCodeKey['data'];
+        // 验证.
+        $nowTime = strtotime(date('Y-m-d H:i:s').'-1 min');
+        if (!$safetyCodeKey || $safetyCodeKey['code_time'] < $nowTime) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01003'),
+                'data' => [],
+            ];
+        }
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MP01002'),
+            'data' => [],
+        ];
+
+    }//end securityVerify()
+
+
+    /**
+     * 获取平台验证码
+     */
+    public function platformToken($getData)
+    {
+        $code       = -2;
+        $userToken  = input('get.userToken');
+        $userInfoWhere['user_token'] = $userToken;
+        // 获取用户信息.
+        $getUserInfo = model('user')->currentUser($userToken);
+        $getUserInfo =  $getUserInfo['data'];
+
+        $platformId = $getData['platformId'];
+        // 验证传参.
+        $data     = ['platformId' => $platformId];
+        $validate = Loader::validate('Platform');
+        if (!$validate->scene('platformToken')->check($data)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 获取平台信息.
+        $platformWhere['platform_status'] = 1;
+        $platformWhere['platform_id']     = $platformId;
+        $getPlatform = $this
+            ->field('platform_code')
+            ->where($platformWhere)
+            ->find();
+        // 加密.
+        if(empty($getPlatform)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01006'),
+                'data' => [],
+            ];
+        }
+        $token = randomPassword();
+
+        $data = [
+            'user_identity' => $getUserInfo['user_identity'],
+            'platform_id' => $platformId,
+            'platform_code' => $getPlatform['platform_code'],
+            'platform_code_time' => time(),
+        ];
+        $addCode = model('PlatformUser')->addPlatformUser($data);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MC01005'),
+            'data' => [
+                'verifySystem'   => $token,
+                'verifySystemId' => $platformId,
+            ],
+        ];
+
+    }//end platformToken()
+
+
+    /**
+     * 验证
+     */
+    public function verifyPlatform()
+    {
+        $code         = -2;
+        $backSystem   = input('get.backSystem');
+        $platformCode = input('get.platformCode');
+        $platformUser = input('get.userName');
+        if(empty($backSystem)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01007'),
+                'data' => [],
+            ];
+        }
+        if(empty($platformCode)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01008'),
+                'data' => [],
+            ];
+        }
+        if(empty($platformUser)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01009'),
+                'data' => [],
+            ];
+        }
+
+        // 验证.
+        $platformWhere['platform_code'] = $platformCode;
+        $platformCode = model('PlatformUser')->selectPlatformUser($platformWhere);
+        $platformCode = $platformCode['data'];
+        $nowTime    = strtotime(date('Y-m-d H:i:s').'-5 min');
+
+        if (!$platformCode || $platformCode['platform_code_time'] < $nowTime) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01002'),
+                'data' => [],
+            ];
+        }
+
+        // 获取平台信息.
+        $platformWhere['platform_status'] = 1;
+        $platformWhere['platform_code']   = $platformCode;
+        $getPlatform = $this
+            ->field('platform_id')
+            ->where($platformWhere)
+            ->find();
+
+        if (empty($getPlatform) === true) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01003'),
+                'data' => [],
+            ];
+        }
+
+        // 删除验证token.
+        model('PlatformUser')->delPlatformUser($platformWhere);
+
+        // 验证成功则加入数据.
+        $addUserPlatform = model('UserPlatform')->addUserPlatform($platformCode['user_identity'], $getPlatform['platform_id'], $platformUser);
+
+        return $addUserPlatform;
+
+    }//end verifyPlatform()
+
+
+}

+ 56 - 0
application/index/model/PlatformUser.php

@@ -0,0 +1,56 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class PlatformUser extends Model
+{
+
+    /**
+     * 添加平台验证码
+     */
+    public function addPlatformUser($data)
+    {
+        // 添加平台验证码
+
+        $addPlatformUser = $this->insert($data);
+
+    }//end addPlatformUser()
+
+
+    /**
+     * 查询验证码
+     */
+    public function selectPlatformUser($platformWhere)
+    {
+        // 添加验证码
+        $platform = $this
+            ->field('code_key, code_time')
+            ->where($platformWhere)
+            ->find();
+
+        return [
+            'code' => 1,
+            'msg'  => '',
+            'data' => $platform,
+        ];
+
+    }//end addCode()
+
+    /**
+     * 删除验证码
+     */
+    public function delPlatformUser($platformWhere)
+    {
+        // 删除验证码
+        $platform = $this
+            ->where($platformWhere)
+            ->delect();
+
+    }//end delPlatformUser()
+
+
+}

+ 360 - 0
application/index/model/User.php

@@ -0,0 +1,360 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class User extends Model
+{
+
+
+    /**
+     * 用户登陆
+     */
+    public function login($getData)
+    {
+        $code  = -2;
+        // 获取的用户信息.
+        $name     = $getData['name'];
+        $password = $getData['password'];
+
+        // 验证传参.
+        $data     = [
+            'name'     => $name,
+            'password' => $password,
+        ];
+        $validate = Loader::validate('User');
+        if (!$validate->scene('login')->check($data)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 获取用户信息.
+        $userInfoWhere['user_name'] = $name;
+        $userInfoWhere['user_status'] = 1;
+        $getUserInfo = $this
+            ->field('user_name, user_identity, user_phone, user_nickname, user_salt, user_password')
+            ->where($userInfoWhere)
+            ->find();
+        if(empty($getUserInfo)){
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01002'),
+                'data' => [],
+            ];
+        }
+        $userSalt = $getUserInfo['user_salt'];
+        // 验证密码.
+        if (md5(md5($userSalt.$password)) !== $getUserInfo['user_password']) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01001'),
+                'data' => [],
+            ];
+        }
+
+        // 存储token及用户信息.
+        $userInfo  = [
+            'userName'      => $getUserInfo['user_name'],
+            'userId'        => $getUserInfo['user_identity'],
+            'userNick'      => $getUserInfo['user_nickname'],
+            'phone'      => $getUserInfo['user_phone'],
+            'lastOperation' => time(),
+        ];
+        $userToken = getToken();
+
+        // 修改最后操作信息.
+        $upData = [
+            'user_last_time' => time(),
+            'user_last_ip'   => $_SERVER['REMOTE_ADDR'],
+            'user_token'   => $userToken,
+            'user_lastOperation'   => $userInfo['lastOperation'],
+        ];
+        $upUser = $this
+            ->where($userInfoWhere)
+            ->update($upData);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MA01001'),
+            'data' => [
+                'userToken' => $userToken,
+                'userInfo'  => [
+                    'phone' => $getUserInfo['user_phone'],
+                    'userId'  => $getUserInfo['user_identity'],
+                    'name'  => $name,
+                    'lastOperation'  => $userInfo['lastOperation'],
+                ],
+            ],
+        ];
+
+    }//end login()
+
+
+    /**
+     * 用户注册
+     */
+    public function registered($getData)
+    {
+        $code  = -2;
+        // 获取的用户信息.
+        $name     = $getData['name'];
+        $password = $getData['password'];
+        $phone    = $getData['phone'];
+
+        // 验证传参.
+        $data     = [
+            'name'     => $name,
+            'password' => $password,
+            'phone'    => $phone,
+        ];
+        $validate = Loader::validate('User');
+        if (!$validate->scene('registered')->check($data)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        // 查询用户是否存在.
+        $haveUser = $this
+            ->field('user_id')
+            ->where('user_name', $name)
+            ->find();
+        if (empty($haveUser) === false) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01009'),
+                'data' => [],
+            ];
+        }
+
+        $userToken = getToken();
+        // 新增数据.
+        $genPassword                    = GenPassword($password);
+        $userData['user_name']          = $name;
+        $userData['user_phone']         = $phone;
+        $userData['user_identity']      = UUID();
+        $userData['user_password']      = $genPassword['password'];
+        $userData['user_salt']          = $genPassword['encryption'];
+        $userData['user_register_time'] = time();
+        $userData['user_register_ip']   = $_SERVER['REMOTE_ADDR'];
+        $userData['user_last_time']     = time();
+        $userData['user_last_ip']       = $_SERVER['REMOTE_ADDR'];
+        $userData['user_token']         = $userToken;
+        $userData['user_lastOperation'] = time();
+        // 新增用户.
+        $addUser = $this->insert($userData);
+        if (empty($addUser) === false) {
+            // 存储token及用户信息.
+            $userInfo  = [
+                'userName'      => $name,
+                'userId'        => $userData['user_identity'],
+                'phone'        => $userData['user_phone'],
+                'lastOperation' => time(),
+            ];
+
+            return [
+                'code' => 1,
+                'msg'  => lang('MA01002'),
+                'data' => [
+                    'userToken' => $userToken,
+                    'userInfo'  => [
+                        'phone' => $userInfo['phone'],
+                        'name'  => $userInfo['userName'],
+                        'userId'  => $userInfo['userId'],
+                        'lastOperation'  => $userInfo['lastOperation'],
+                    ],
+                ],
+            ];
+        } else {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01002'),
+                'data' => [],
+            ];
+        }//end if
+
+    }//end registered()
+
+
+    /**
+     * 退出登陆
+     */
+    public function logout()
+    {
+//        // 获取的传参信息.
+        $userToken = input('get.userToken');
+
+        $userInfoWhere['user_token'] = $userToken;
+        $upData = [
+            'user_token'   => '',
+            'user_lastOperation'   => '',
+        ];
+
+        $upUser = $this
+            ->where($userInfoWhere)
+            ->update($upData);
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MA01003'),
+            'data' => [],
+        ];
+
+    }//end logout()
+
+
+    /**
+     * 当前用户信息
+     */
+    public function currentUser($userToken)
+    {
+//        $userToken = input('get.userToken');
+        // 获取用户信息.
+        $userInfoWhere['user_token'] = $userToken;
+        $getUserInfo = $this
+            ->field('user_name, user_identity, user_phone, user_nickname, user_salt, user_password,user_token,user_lastOperation')
+            ->where($userInfoWhere)
+            ->find()
+            ->toArray();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('MA01003'),
+            'data' => $getUserInfo,
+        ];
+
+    }//end currentUser()
+
+    /**
+     * 更新用户操作时间
+     */
+    public function updateLastOperation($userToken,$time)
+    {
+        $userInfoWhere['user_token'] = $userToken;
+        $upData = [
+            'user_lastOperation'   => $time,
+        ];
+
+        $upUser = $this
+            ->where($userInfoWhere)
+            ->update($upData);
+
+    }//end updateLastOperation()
+
+
+    /**
+     * 修改用户密码
+     */
+    public function updatePassword($getData)
+    {
+        $code    = -2;
+
+        // 验证传参.
+        $validate = Loader::validate('User');
+        if (!$validate->scene('updatePassword')->check($getData)) {
+            return [
+                'code' => $code,
+                'msg'  => $validate->getError(),
+                'data' => [],
+            ];
+        }
+
+        $userToken = input('get.userToken');
+        $conditions_user['user_token'] = $userToken;
+
+        $userInfo = $this
+            ->field('user_salt, user_password')
+            ->where($conditions_user)
+            ->find();
+
+        // 验证旧密码.
+        $userSalt = $userInfo['user_salt'];
+        if (md5(md5($userSalt.$getData['oldPassword'])) !== $userInfo['user_password']) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EA01006'),
+                'data' => [],
+            ];
+        }
+
+        // 修改密码.
+        $newPassword = GenPassword($getData['newPassword']);
+        $updateData  = [
+            'user_password' => $newPassword['password'],
+            'user_salt'     => $newPassword['encryption'],
+        ];
+
+        $getUserInfo = $this
+            ->where($conditions_user)
+            ->update($updateData);
+        if (empty($getUserInfo) === true) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EC01002'),
+                'data' => [],
+            ];
+        } else {
+            $code = 1;
+            return [
+                'code' => $code,
+                'msg'  => lang('MC01004'),
+                'data' => [],
+            ];
+        }
+
+    }//end updatePassword()
+
+    /**
+     * 验证用户密码
+     */
+    public function checkPwd($getData)
+    {
+        $userToken = input('get.userToken');
+        $conditions_user['user_token'] = $userToken;
+        // 获取用户信息.
+        $userInfo = $this
+            ->field('user_salt, user_password')
+            ->where($conditions_user)
+            ->find();
+
+        if(empty($getData['password'])){
+            return [
+                'code' => -2,
+                'msg'  => lang('EA01011'),
+                'data' => [],
+            ];
+        }
+
+        if(empty($userInfo)){
+            return [
+                'code' => -2,
+                'msg'  => lang('EA01012'),
+                'data' => [],
+            ];
+        }
+
+        if($userInfo['user_password'] != md5(md5($userInfo['user_salt'].$getData['password']))){
+            return [
+                'code' => -2,
+                'msg'  => lang('EA01001'),
+                'data' => [],
+            ];
+        }
+        return [
+            'code' => 1,
+            'msg'  => '',
+            'data' => $userInfo,
+        ];
+
+    }//end checkPwd()
+
+
+}

+ 102 - 0
application/index/model/UserPlatform.php

@@ -0,0 +1,102 @@
+<?php
+namespace app\index\model;
+use\think\Model;
+use think\Session;
+use think\cache\driver\Redis;
+use think\Loader;
+use think\Cache;
+
+class UserPlatform extends Model
+{
+
+
+    /**
+     * 新增用户平台关联
+     */
+    public function addUserPlatform($userIdentity, $platformId, $platformUser)
+    {
+        $code = -2;
+        // 查询是否已经有记录.
+        $getHaveWhere = [
+            'platform_user' => $platformUser,
+            'platform_id'   => $platformId,
+        ];
+        $getHave      = $this
+            ->field('user_platform_id')
+            ->where($getHaveWhere)
+            ->find();
+
+        if (empty($getHave) === false) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01004'),
+                'data' => [],
+            ];
+        }
+
+        // 新增用户平台关联.
+        $data    = [
+            'user_identity'       => $userIdentity,
+            'platform_id'         => $platformId,
+            'platform_user'       => $platformUser,
+            'user_platform_rtime' => time(),
+            'user_platform_rip'   => $_SERVER['REMOTE_ADDR'],
+        ];
+        $addData = $this->insert($data);
+
+        if (empty($addData) === true) {
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01003'),
+                'data' => [],
+            ];
+        } else {
+            return [
+                'code' => 1,
+                'msg'  => lang('MP01002'),
+                'data' => [],
+            ];
+        }
+
+    }//end addUserPlatform()
+
+    /**
+     * 根据绑定用户删除用户平台关联
+     */
+    public function unBind($getData)
+    {
+        $code    = -2;
+        $userToken = input('get.userToken');
+        // 获取用户信息.
+        $getUserInfo = model('user')->currentUser($userToken);
+        $getUserInfo =  $getUserInfo['data'];
+
+        if(empty($getData['platform_id'])){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01013'),
+                'data' => [],
+            ];
+        }
+        if(empty($getData['platform_user'])){
+            return [
+                'code' => $code,
+                'msg'  => lang('EP01014'),
+                'data' => [],
+            ];
+        }
+        $where['user_identity'] = $getUserInfo['user_identity'];
+        $where['platform_id'] = $getData['platform_id'];
+        $where['platform_user'] = $getData['platform_user'];
+        $this->where($where)->delete();
+
+        return [
+            'code' => 1,
+            'msg'  => lang('EP01015'),
+            'data' => [],
+        ];
+
+    }//end unBind()
+
+
+}

+ 28 - 0
application/index/validate/Message.php

@@ -0,0 +1,28 @@
+<?php
+namespace app\index\validate;
+
+use think\Validate;
+use think\Lang;
+
+class Message extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'platform_code'    =>  'alphaNum|length:32',
+        'messageVerify'    =>  'alphaNum|length:32',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'getMessage'   =>  ['platform_code', 'messageVerify'],
+    ];
+    public function __construct() {
+        $this->message = [
+            'platform_code'  =>  lang('EC01004'),
+        ];
+    }
+}
+

+ 30 - 0
application/index/validate/Platform.php

@@ -0,0 +1,30 @@
+<?php
+namespace app\index\validate;
+
+use think\Validate;
+use think\Lang;
+
+class Platform extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'platformId'    =>  'require|number|length:1,20',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'platformToken'   =>  ['platformId'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'platformId'  =>  lang('EP01001'),
+        ];
+    }
+}
+

+ 43 - 0
application/index/validate/User.php

@@ -0,0 +1,43 @@
+<?php
+namespace app\index\validate;
+
+use think\Validate;
+use think\Lang;
+
+class User extends Validate
+{
+    // 验证规则.
+    protected $rule = [
+        'name'    =>  'require|alphaNum|length:6,20',
+        'password'      =>  'require|length:6,20',
+        'oldPassword'      =>  'require|length:6,20',
+        'newPassword'      =>  'require|length:6,20',
+        'email' =>  'email',
+        'phone' =>  'length:11',
+    ];
+
+    // 触犯规则提示语.
+    protected $message = '';
+
+    // 验证层.
+    protected $scene = [
+        'login'   =>  ['name', 'password'],
+        'registered'   =>  ['name', 'password', 'phone'],
+        'logout'   =>  ['name'],
+        'updatePassword'   =>  ['newPassword', 'oldPassword'],
+    ];
+    public function __construct() {
+        $this->message = [
+            //'user.require'  =>  '用户名必须',
+            //'user.alphaNum'  =>  '用户名必须由字母和数组组成',
+            //'user.length'  =>  '用户名为6~20位',
+            'name'  =>  lang('EA01002'),
+            'password'  =>  lang('EA01001'),
+            'email' =>  lang('EA01003'),
+            'oldPassword' =>  lang('EA01006'),
+            'newPassword' =>  lang('EA01007'),
+            'phone' =>  lang('EA01008'),
+        ];
+    }
+}
+

+ 4 - 4
build.php

@@ -13,12 +13,12 @@ return [
     // 生成应用公共文件
     '__file__' => ['common.php', 'config.php', 'database.php'],
 
-    // 定义index模块的自动生成 (按照实际定义的文件名生成)
-    'index'     => [
+    // 定义demo模块的自动生成 (按照实际定义的文件名生成)
+    'demo'     => [
         '__file__'   => ['common.php'],
         '__dir__'    => ['behavior', 'controller', 'model', 'view'],
-        'controller' => ['Index'],
-        'model'      => [],
+        'controller' => ['Index', 'Test', 'UserType'],
+        'model'      => ['User', 'UserType'],
         'view'       => ['index/index'],
     ],
     // 其他更多的模块定义

+ 40 - 38
composer.json

@@ -1,41 +1,43 @@
 {
-  "name": "topthink/think",
-  "description": "the new thinkphp framework",
-  "type": "project",
-  "keywords": [
-    "framework",
-    "thinkphp",
-    "ORM"
-  ],
-  "homepage": "http://thinkphp.cn/",
-  "license": "Apache-2.0",
-  "authors": [
-    {
-      "name": "liu21st",
-      "email": "liu21st@gmail.com"
+    "name": "topthink/think",
+    "description": "the new thinkphp framework",
+    "type": "project",
+    "keywords": [
+        "framework",
+        "thinkphp",
+        "ORM"
+    ],
+    "homepage": "http://thinkphp.cn/",
+    "license": "Apache-2.0",
+    "authors": [
+        {
+            "name": "liu21st",
+            "email": "liu21st@gmail.com"
+        }
+    ],
+     "repositories": {
+    	"packagist": {
+        	"type": "composer",
+        	"url": "https://packagist.phpcomposer.com"
+    	}
+	},
+    "require": {
+        "php": ">=5.4.0",
+        "topthink/framework": "^5.0",
+        "topthink/think-image": "^1.0",
+        "topthink/think-captcha": "^1.0",
+        "topthink/think-mongo": "^1.0",
+        "topthink/think-migration": "^1.0",
+        "topthink/think-angular": "^1.0",
+        "topthink/think-sae": "^1.0",
+        "topthink/think-worker": "^1.0",
+        "topthink/think-queue": "^1.0",
+        "topthink/think-testing": "^1.0"
+    },
+    "extra": {
+        "think-path": "thinkphp"
+    },
+    "config": {
+        "preferred-install": "dist"
     }
-  ],
-  "require": {
-    "php": ">=5.4.0",
-    "topthink/framework": "~5.0.0",
-    "zoujingli/ip2region": "^1.0",
-    "phpoffice/phpspreadsheet": "1.8.2"
-  },
-  "autoload": {
-    "psr-4": {
-      "app\\": "application/"
-    }
-  },
-  "extra": {
-    "think-path": "thinkphp"
-  },
-  "config": {
-    "preferred-install": "dist"
-  },
-  "repositories": {
-    "packagist": {
-      "type": "composer",
-      "url": "https://packagist.phpcomposer.com"
-    }
-  }
 }

+ 5 - 6
public/.htaccess

@@ -1,8 +1,7 @@
 <IfModule mod_rewrite.c>
-  Options +FollowSymlinks -Multiviews
-  RewriteEngine On
-
-  RewriteCond %{REQUEST_FILENAME} !-d
-  RewriteCond %{REQUEST_FILENAME} !-f
-  RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
+Options +FollowSymlinks -Multiviews
+RewriteEngine on
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
 </IfModule>

BIN
public/favicon.ico


+ 5 - 13
public/index.php

@@ -9,25 +9,17 @@
 // | Author: liu21st <liu21st@gmail.com>
 // +----------------------------------------------------------------------
 
-date_default_timezone_set('PRC');
-
-// [ 应用入口文件 ]
 //编码
 header('content-type:text/html;charset=utf-8');
-// 处理预请求报错(将请求的头部数据全部允许,然后直接返回).
-if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
-    header("Access-Control-Allow-Origin: *");
-    header("Access-Control-Allow-Credentials", "true");
-    header("Access-Control-Max-Age", "3600");
-    header("Access-Control-Allow-Headers: Origin, X-Requested-With, X-Custom-Header, Content-Type, Accept, Authorization, userToken, apiToken");
-    header('Access-Control-Allow-Methods: GET, POST, PUT,DELETE,OPTIONS,PATCH');
-    header('Access-Control-Expose-Headers', "userToken, apiToken");
-    exit;
-}
 //跨域
 header('Access-Control-Allow-Origin:*');
 header('Access-Control-Allow-Methods:OPTIONS, GET, POST'); // 允许option,get,post请求
 header('Access-Control-Allow-Headers:x-requested-with'); // 允许x-requested-with请求头
+//北京时间转换
+date_default_timezone_set('PRC');
+
+// [ 应用入口文件 ]
+
 // 定义应用目录
 define('APP_PATH', __DIR__ . '/../application/');
 // 加载框架引导文件

+ 0 - 3
public/router.php

@@ -13,8 +13,5 @@
 if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["REQUEST_URI"])) {
     return false;
 } else {
-    if (!isset($_SERVER['PATH_INFO'])) {
-        $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
-    }
     require __DIR__ . "/index.php";
 }

+ 2 - 0
public/static/.gitignore

@@ -0,0 +1,2 @@
+*
+!.gitignore

BIN
public/uploads/20190923/1077da179d335f32c78eec9b68a920fc.jpeg


BIN
public/uploads/20190923/a4fd59e8776a1d171ac8d4336e2da680.jpeg


+ 20 - 0
tests/ExampleTest.php

@@ -0,0 +1,20 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: yunwuxin <448901948@qq.com>
+// +----------------------------------------------------------------------
+namespace tests;
+
+class ExampleTest extends TestCase
+{
+
+    public function testBasicExample()
+    {
+        $this->visit('/')->see('ThinkPHP');
+    }
+}

+ 16 - 0
tests/TestCase.php

@@ -0,0 +1,16 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: yunwuxin <448901948@qq.com>
+// +----------------------------------------------------------------------
+namespace tests;
+
+class TestCase extends \think\testing\TestCase
+{
+    protected $baseUrl = 'http://localhost';
+}

+ 1 - 1
think

@@ -14,4 +14,4 @@
 define('APP_PATH', __DIR__ . '/application/');
 
 // 加载框架引导文件
-require __DIR__.'/thinkphp/console.php';
+require './thinkphp/console.php';

+ 2 - 2
thinkphp/CONTRIBUTING.md

@@ -7,7 +7,7 @@
 
 ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。
 
-参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。
+参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。
 
 我们希望你贡献的代码符合:
 
@@ -60,7 +60,7 @@ GitHub 提供了 Issue 功能,该功能可以用于:
 6. 变基(衍合 `rebase`)你的分支到上游 master 分支;
 7. `push` 你的本地仓库到 GitHub;
 8. 提交 `pull request`;
-9. 等待 CI 验证(若不通过则重复 5~7,不需要重新提交 `pull request`,GitHub 会自动更新你的 `pull request`);
+9. 等待 CI 验证(若不通过则重复 5~7,GitHub 会自动更新你的 `pull request`);
 10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。
 
 *若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`*

+ 1 - 1
thinkphp/LICENSE.txt

@@ -1,6 +1,6 @@
 
 ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
-版权所有Copyright © 2006-2017 by ThinkPHP (http://thinkphp.cn)
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
 All rights reserved。
 ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
 

+ 3 - 4
thinkphp/README.md

@@ -28,11 +28,10 @@ ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PH
  + 真正惰性加载
  + 分布式环境支持
  + 支持Composer
- + 支持MongoDb
 
 > ThinkPHP5的运行环境要求PHP5.4以上。
 
-详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart)
+详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5)
 
 ## 目录结构
 
@@ -92,7 +91,7 @@ www  WEB部署目录(或者子目录)
 
 ## 命名规范
 
-ThinkPHP5的命名规范遵循`PSR-2`规范以及`PSR-4`自动加载规范。
+ThinkPHP5的命名规范遵循PSR-2规范以及PSR-4自动加载规范。
 
 ## 参与开发
 注册并登录 Github 帐号, fork 本项目并进行改动。
@@ -105,7 +104,7 @@ ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
 
 本项目包含的第三方源码和二进制文件之版权信息另行标注。
 
-版权所有Copyright © 2006-2018 by ThinkPHP (http://thinkphp.cn)
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
 
 All rights reserved。
 

+ 2 - 4
thinkphp/base.php

@@ -2,14 +2,14 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
 // | Author: liu21st <liu21st@gmail.com>
 // +----------------------------------------------------------------------
 
-define('THINK_VERSION', '5.0.24');
+define('THINK_VERSION', '5.0.5');
 define('THINK_START_TIME', microtime(true));
 define('THINK_START_MEM', memory_get_usage());
 define('EXT', '.php');
@@ -40,10 +40,8 @@ require CORE_PATH . 'Loader.php';
 // 加载环境变量配置文件
 if (is_file(ROOT_PATH . '.env')) {
     $env = parse_ini_file(ROOT_PATH . '.env', true);
-
     foreach ($env as $key => $val) {
         $name = ENV_PREFIX . strtoupper($key);
-
         if (is_array($val)) {
             foreach ($val as $k => $v) {
                 $item = $name . '_' . strtoupper($k);

+ 1 - 1
thinkphp/console.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006-2017 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------

+ 9 - 19
thinkphp/convention.php

@@ -4,10 +4,11 @@ return [
     // +----------------------------------------------------------------------
     // | 应用设置
     // +----------------------------------------------------------------------
-    // 默认Host地址
-    'app_host'               => '',
+
+    // 应用命名空间
+    'app_namespace'          => 'app',
     // 应用调试模式
-    'app_debug'              => false,
+    'app_debug'              => true,
     // 应用Trace
     'app_trace'              => false,
     // 应用模式状态
@@ -74,8 +75,6 @@ return [
     'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
     // pathinfo分隔符
     'pathinfo_depr'          => '/',
-    // HTTPS代理标识
-    'https_agent_name'       => '',
     // URL伪静态后缀
     'url_html_suffix'        => 'html',
     // URL普通方式参数 用于自动生成
@@ -108,16 +107,12 @@ return [
     'request_cache'          => false,
     // 请求缓存有效期
     'request_cache_expire'   => null,
-    // 全局请求缓存排除规则
-    'request_cache_except'   => [],
 
     // +----------------------------------------------------------------------
     // | 模板设置
     // +----------------------------------------------------------------------
 
     'template'               => [
-        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
-        'auto_rule'    => 1,
         // 模板引擎类型 支持 php think 支持扩展
         'type'         => 'Think',
         // 视图基础目录,配置目录为所有模块的视图起始目录
@@ -157,8 +152,6 @@ return [
     'show_error_msg'         => false,
     // 异常处理handle类 留空使用 \think\exception\Handle
     'exception_handle'       => '',
-    // 是否记录trace信息到日志
-    'record_trace'           => false,
 
     // +----------------------------------------------------------------------
     // | 日志设置
@@ -211,7 +204,7 @@ return [
         // 是否自动开启 SESSION
         'auto_start'     => true,
         'httponly'       => true,
-        'secure'         => false,
+        'secure'         => true,
     ],
 
     // +----------------------------------------------------------------------
@@ -279,6 +272,10 @@ return [
         'datetime_format' => 'Y-m-d H:i:s',
         // 是否需要进行SQL性能分析
         'sql_explain'     => false,
+        // Builder类
+        'builder'         => '',
+        // Query类
+        'query'           => '\\think\\db\\Query',
     ],
 
     //分页配置
@@ -288,11 +285,4 @@ return [
         'list_rows' => 15,
     ],
 
-    //控制台配置
-    'console'                => [
-        'name'    => 'Think Console',
-        'version' => '0.1',
-        'user'    => null,
-    ],
-
 ];

+ 12 - 16
thinkphp/helper.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -127,7 +127,7 @@ if (!function_exists('input')) {
         if ($pos = strpos($key, '.')) {
             // 指定参数来源
             list($method, $key) = explode('.', $key, 2);
-            if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
+            if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
                 $key    = $method . '.' . $key;
                 $method = 'param';
             }
@@ -192,7 +192,7 @@ if (!function_exists('db')) {
      * @param bool          $force 是否强制重新连接
      * @return \think\db\Query
      */
-    function db($name = '', $config = [], $force = false)
+    function db($name = '', $config = [], $force = true)
     {
         return Db::connect($config, $force)->name($name);
     }
@@ -354,25 +354,22 @@ if (!function_exists('cache')) {
     {
         if (is_array($options)) {
             // 缓存操作的同时初始化
-            $cache = Cache::connect($options);
+            Cache::connect($options);
         } elseif (is_array($name)) {
             // 缓存初始化
             return Cache::connect($name);
-        } else {
-            $cache = Cache::init();
         }
-
         if (is_null($name)) {
-            return $cache->clear($value);
+            return Cache::clear($value);
         } elseif ('' === $value) {
             // 获取缓存
-            return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name);
+            return 0 === strpos($name, '?') ? Cache::has(substr($name, 1)) : Cache::get($name);
         } elseif (is_null($value)) {
             // 删除缓存
-            return $cache->rm($name);
+            return Cache::rm($name);
         } elseif (0 === strpos($name, '?') && '' !== $value) {
             $expire = is_numeric($options) ? $options : null;
-            return $cache->remember(substr($name, 1), $value, $expire);
+            return Cache::remember(substr($name, 1), $value, $expire);
         } else {
             // 缓存数据
             if (is_array($options)) {
@@ -381,9 +378,9 @@ if (!function_exists('cache')) {
                 $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间
             }
             if (is_null($tag)) {
-                return $cache->set($name, $value, $expire);
+                return Cache::set($name, $value, $expire);
             } else {
-                return $cache->tag($tag)->set($name, $value, $expire);
+                return Cache::tag($tag)->set($name, $value, $expire);
             }
         }
     }
@@ -498,16 +495,15 @@ if (!function_exists('redirect')) {
      * @param mixed         $url 重定向地址 支持Url::build方法的地址
      * @param array|integer $params 额外参数
      * @param integer       $code 状态码
-     * @param array         $with 隐式传参
      * @return \think\response\Redirect
      */
-    function redirect($url = [], $params = [], $code = 302, $with = [])
+    function redirect($url = [], $params = [], $code = 302)
     {
         if (is_integer($params)) {
             $code   = $params;
             $params = [];
         }
-        return Response::create($url, 'redirect', $code)->params($params)->with($with);
+        return Response::create($url, 'redirect', $code)->params($params);
     }
 }
 

+ 51 - 120
thinkphp/lang/zh-cn.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -12,125 +12,56 @@
 // 核心中文语言包
 return [
     // 系统错误提示
-    'Undefined variable'                                        => '未定义变量',
-    'Undefined index'                                           => '未定义数组索引',
-    'Undefined offset'                                          => '未定义数组下标',
-    'Parse error'                                               => '语法解析错误',
-    'Type error'                                                => '类型错误',
-    'Fatal error'                                               => '致命错误',
-    'syntax error'                                              => '语法错误',
+    'Undefined variable'        => '未定义变量',
+    'Undefined index'           => '未定义数组索引',
+    'Undefined offset'          => '未定义数组下标',
+    'Parse error'               => '语法解析错误',
+    'Type error'                => '类型错误',
+    'Fatal error'               => '致命错误',
+    'syntax error'              => '语法错误',
 
     // 框架核心错误提示
-    'dispatch type not support'                                 => '不支持的调度类型',
-    'method param miss'                                         => '方法参数错误',
-    'method not exists'                                         => '方法不存在',
-    'module not exists'                                         => '模块不存在',
-    'controller not exists'                                     => '控制器不存在',
-    'class not exists'                                          => '类不存在',
-    'property not exists'                                       => '类的属性不存在',
-    'template not exists'                                       => '模板文件不存在',
-    'illegal controller name'                                   => '非法的控制器名称',
-    'illegal action name'                                       => '非法的操作名称',
-    'url suffix deny'                                           => '禁止的URL后缀访问',
-    'Route Not Found'                                           => '当前访问路由未定义',
-    'Undefined db type'                                         => '未定义数据库类型',
-    'variable type error'                                       => '变量类型错误',
-    'PSR-4 error'                                               => 'PSR-4 规范错误',
-    'not support total'                                         => '简洁模式下不能获取数据总数',
-    'not support last'                                          => '简洁模式下不能获取最后一页',
-    'error session handler'                                     => '错误的SESSION处理器类',
-    'not allow php tag'                                         => '模板不允许使用PHP语法',
-    'not support'                                               => '不支持',
-    'redisd master'                                             => 'Redisd 主服务器错误',
-    'redisd slave'                                              => 'Redisd 从服务器错误',
-    'must run at sae'                                           => '必须在SAE运行',
-    'memcache init error'                                       => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务',
-    'KVDB init error'                                           => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务',
-    'fields not exists'                                         => '数据表字段不存在',
-    'where express error'                                       => '查询表达式错误',
-    'not support data'                                          => '不支持的数据表达式',
-    'no data to update'                                         => '没有任何数据需要更新',
-    'miss data to insert'                                       => '缺少需要写入的数据',
-    'miss complex primary data'                                 => '缺少复合主键数据',
-    'miss update condition'                                     => '缺少更新条件',
-    'model data Not Found'                                      => '模型数据不存在',
-    'table data not Found'                                      => '表数据不存在',
-    'delete without condition'                                  => '没有条件不会执行删除操作',
-    'miss relation data'                                        => '缺少关联表数据',
-    'tag attr must'                                             => '模板标签属性必须',
-    'tag error'                                                 => '模板标签错误',
-    'cache write error'                                         => '缓存写入失败',
-    'sae mc write error'                                        => 'SAE mc 写入错误',
-    'route name not exists'                                     => '路由标识不存在(或参数不够)',
-    'invalid request'                                           => '非法请求',
-    'bind attr has exists'                                      => '模型的属性已经存在',
-    'relation data not exists'                                  => '关联数据不存在',
-    'relation not support'                                      => '关联不支持',
-    'chunk not support order'                                   => 'Chunk不支持调用order方法',
-    'closure not support cache(true)'                           => '使用闭包查询不支持cache(true),请指定缓存Key',
-
-    // 上传错误信息
-    'unknown upload error'                                      => '未知上传错误!',
-    'file write error'                                          => '文件写入失败!',
-    'upload temp dir not found'                                 => '找不到临时文件夹!',
-    'no file to uploaded'                                       => '没有文件被上传!',
-    'only the portion of file is uploaded'                      => '文件只有部分被上传!',
-    'upload File size exceeds the maximum value'                => '上传文件大小超过了最大值!',
-    'upload write error'                                        => '文件上传保存错误!',
-    'has the same filename: {:filename}'                        => '存在同名文件:{:filename}',
-    'upload illegal files'                                      => '非法上传文件',
-    'illegal image files'                                       => '非法图片文件',
-    'extensions to upload is not allowed'                       => '上传文件后缀不允许',
-    'mimetype to upload is not allowed'                         => '上传文件MIME类型不允许!',
-    'filesize not match'                                        => '上传文件大小不符!',
-    'directory {:path} creation failed'                         => '目录 {:path} 创建失败!',
-
-    // Validate Error Message
-    ':attribute require'                                        => ':attribute不能为空',
-    ':attribute must be numeric'                                => ':attribute必须是数字',
-    ':attribute must be integer'                                => ':attribute必须是整数',
-    ':attribute must be float'                                  => ':attribute必须是浮点数',
-    ':attribute must be bool'                                   => ':attribute必须是布尔值',
-    ':attribute not a valid email address'                      => ':attribute格式不符',
-    ':attribute not a valid mobile'                             => ':attribute格式不符',
-    ':attribute must be a array'                                => ':attribute必须是数组',
-    ':attribute must be yes,on or 1'                            => ':attribute必须是yes、on或者1',
-    ':attribute not a valid datetime'                           => ':attribute不是一个有效的日期或时间格式',
-    ':attribute not a valid file'                               => ':attribute不是有效的上传文件',
-    ':attribute not a valid image'                              => ':attribute不是有效的图像文件',
-    ':attribute must be alpha'                                  => ':attribute只能是字母',
-    ':attribute must be alpha-numeric'                          => ':attribute只能是字母和数字',
-    ':attribute must be alpha-numeric, dash, underscore'        => ':attribute只能是字母、数字和下划线_及破折号-',
-    ':attribute not a valid domain or ip'                       => ':attribute不是有效的域名或者IP',
-    ':attribute must be chinese'                                => ':attribute只能是汉字',
-    ':attribute must be chinese or alpha'                       => ':attribute只能是汉字、字母',
-    ':attribute must be chinese,alpha-numeric'                  => ':attribute只能是汉字、字母和数字',
-    ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-',
-    ':attribute not a valid url'                                => ':attribute不是有效的URL地址',
-    ':attribute not a valid ip'                                 => ':attribute不是有效的IP地址',
-    ':attribute must be dateFormat of :rule'                    => ':attribute必须使用日期格式 :rule',
-    ':attribute must be in :rule'                               => ':attribute必须在 :rule 范围内',
-    ':attribute be notin :rule'                                 => ':attribute不能在 :rule 范围内',
-    ':attribute must between :1 - :2'                           => ':attribute只能在 :1 - :2 之间',
-    ':attribute not between :1 - :2'                            => ':attribute不能在 :1 - :2 之间',
-    'size of :attribute must be :rule'                          => ':attribute长度不符合要求 :rule',
-    'max size of :attribute must be :rule'                      => ':attribute长度不能超过 :rule',
-    'min size of :attribute must be :rule'                      => ':attribute长度不能小于 :rule',
-    ':attribute cannot be less than :rule'                      => ':attribute日期不能小于 :rule',
-    ':attribute cannot exceed :rule'                            => ':attribute日期不能超过 :rule',
-    ':attribute not within :rule'                               => '不在有效期内 :rule',
-    'access IP is not allowed'                                  => '不允许的IP访问',
-    'access IP denied'                                          => '禁止的IP访问',
-    ':attribute out of accord with :2'                          => ':attribute和确认字段:2不一致',
-    ':attribute cannot be same with :2'                         => ':attribute和比较字段:2不能相同',
-    ':attribute must greater than or equal :rule'               => ':attribute必须大于等于 :rule',
-    ':attribute must greater than :rule'                        => ':attribute必须大于 :rule',
-    ':attribute must less than or equal :rule'                  => ':attribute必须小于等于 :rule',
-    ':attribute must less than :rule'                           => ':attribute必须小于 :rule',
-    ':attribute must equal :rule'                               => ':attribute必须等于 :rule',
-    ':attribute has exists'                                     => ':attribute已存在',
-    ':attribute not conform to the rules'                       => ':attribute不符合指定规则',
-    'invalid Request method'                                    => '无效的请求类型',
-    'invalid token'                                             => '令牌数据无效',
-    'not conform to the rules'                                  => '规则错误',
+    'dispatch type not support' => '不支持的调度类型',
+    'method param miss'         => '方法参数错误',
+    'method not exists'         => '方法不存在',
+    'module not exists'         => '模块不存在',
+    'controller not exists'     => '控制器不存在',
+    'class not exists'          => '类不存在',
+    'property not exists'       => '类的属性不存在',
+    'template not exists'       => '模板文件不存在',
+    'illegal controller name'   => '非法的控制器名称',
+    'illegal action name'       => '非法的操作名称',
+    'url suffix deny'           => '禁止的URL后缀访问',
+    'Route Not Found'           => '当前访问路由未定义',
+    'Underfined db type'        => '未定义数据库类型',
+    'variable type error'       => '变量类型错误',
+    'PSR-4 error'               => 'PSR-4 规范错误',
+    'not support total'         => '简洁模式下不能获取数据总数',
+    'not support last'          => '简洁模式下不能获取最后一页',
+    'error session handler'     => '错误的SESSION处理器类',
+    'not allow php tag'         => '模板不允许使用PHP语法',
+    'not support'               => '不支持',
+    'redisd master'             => 'Redisd 主服务器错误',
+    'redisd slave'              => 'Redisd 从服务器错误',
+    'must run at sae'           => '必须在SAE运行',
+    'memcache init error'       => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务',
+    'KVDB init error'           => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务',
+    'fields not exists'         => '数据表字段不存在',
+    'where express error'       => '查询表达式错误',
+    'no data to update'         => '没有任何数据需要更新',
+    'miss data to insert'       => '缺少需要写入的数据',
+    'miss complex primary data' => '缺少复合主键数据',
+    'miss update condition'     => '缺少更新条件',
+    'model data Not Found'      => '模型数据不存在',
+    'table data not Found'      => '表数据不存在',
+    'delete without condition'  => '没有条件不会执行删除操作',
+    'miss relation data'        => '缺少关联表数据',
+    'tag attr must'             => '模板标签属性必须',
+    'tag error'                 => '模板标签错误',
+    'cache write error'         => '缓存写入失败',
+    'sae mc write error'        => 'SAE mc 写入错误',
+    'route name not exists'     => '路由标识不存在(或参数不够)',
+    'invalid request'           => '非法请求',
+    'bind attr has exists'      => '模型的属性已经存在',
+    'relation data not exists'  => '关联数据不存在',
 ];

+ 221 - 331
thinkphp/library/think/App.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -11,14 +11,13 @@
 
 namespace think;
 
-use think\exception\ClassNotFoundException;
 use think\exception\HttpException;
 use think\exception\HttpResponseException;
 use think\exception\RouteNotFoundException;
 
 /**
  * App 应用管理
- * @author liu21st <liu21st@gmail.com>
+ * @author  liu21st <liu21st@gmail.com>
  */
 class App
 {
@@ -57,32 +56,24 @@ class App
      */
     protected static $routeMust;
 
-    /**
-     * @var array 请求调度分发
-     */
     protected static $dispatch;
-
-    /**
-     * @var array 额外加载文件
-     */
     protected static $file = [];
 
     /**
      * 执行应用程序
      * @access public
-     * @param  Request $request 请求对象
+     * @param Request $request Request对象
      * @return Response
      * @throws Exception
      */
     public static function run(Request $request = null)
     {
-        $request = is_null($request) ? Request::instance() : $request;
+        is_null($request) && $request = Request::instance();
 
         try {
             $config = self::initCommon();
-
-            // 模块/控制器绑定
             if (defined('BIND_MODULE')) {
+                // 模块/控制器绑定
                 BIND_MODULE && Route::bind(BIND_MODULE);
             } elseif ($config['auto_bind_module']) {
                 // 入口自动绑定
@@ -94,28 +85,26 @@ class App
 
             $request->filter($config['default_filter']);
 
-            // 默认语言
-            Lang::range($config['default_lang']);
-            // 开启多语言机制 检测当前语言
-            $config['lang_switch_on'] && Lang::detect();
+            if ($config['lang_switch_on']) {
+                // 开启多语言机制 检测当前语言
+                Lang::detect();
+            } else {
+                // 读取默认语言
+                Lang::range($config['default_lang']);
+            }
             $request->langset(Lang::range());
-
             // 加载系统语言包
             Lang::load([
                 THINK_PATH . 'lang' . DS . $request->langset() . EXT,
                 APP_PATH . 'lang' . DS . $request->langset() . EXT,
             ]);
 
-            // 监听 app_dispatch
-            Hook::listen('app_dispatch', self::$dispatch);
             // 获取应用调度信息
             $dispatch = self::$dispatch;
-
-            // 未设置调度信息则进行 URL 路由检测
             if (empty($dispatch)) {
+                // 进行URL路由检测
                 $dispatch = self::routeCheck($request, $config);
             }
-
             // 记录当前调度信息
             $request->dispatch($dispatch);
 
@@ -126,17 +115,40 @@ class App
                 Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');
             }
 
-            // 监听 app_begin
+            // 监听app_begin
             Hook::listen('app_begin', $dispatch);
-
             // 请求缓存检查
-            $request->cache(
-                $config['request_cache'],
-                $config['request_cache_expire'],
-                $config['request_cache_except']
-            );
-
-            $data = self::exec($dispatch, $config);
+            $request->cache($config['request_cache'], $config['request_cache_expire']);
+
+            switch ($dispatch['type']) {
+                case 'redirect':
+                    // 执行重定向跳转
+                    $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);
+                    break;
+                case 'module':
+                    // 模块/控制器/操作
+                    $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);
+                    break;
+                case 'controller':
+                    // 执行控制器操作
+                    $vars = array_merge(Request::instance()->param(), $dispatch['var']);
+                    $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);
+                    break;
+                case 'method':
+                    // 执行回调方法
+                    $vars = array_merge(Request::instance()->param(), $dispatch['var']);
+                    $data = self::invokeMethod($dispatch['method'], $vars);
+                    break;
+                case 'function':
+                    // 执行闭包
+                    $data = self::invokeFunction($dispatch['function']);
+                    break;
+                case 'response':
+                    $data = $dispatch['response'];
+                    break;
+                default:
+                    throw new \InvalidArgumentException('dispatch type not support');
+            }
         } catch (HttpResponseException $exception) {
             $data = $exception->getResponse();
         }
@@ -149,151 +161,24 @@ class App
             $response = $data;
         } elseif (!is_null($data)) {
             // 默认自动识别响应输出类型
-            $type = $request->isAjax() ?
-            Config::get('default_ajax_return') :
-            Config::get('default_return_type');
-
+            $isAjax   = $request->isAjax();
+            $type     = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');
             $response = Response::create($data, $type);
         } else {
             $response = Response::create();
         }
 
-        // 监听 app_end
+        // 监听app_end
         Hook::listen('app_end', $response);
 
         return $response;
     }
 
-    /**
-     * 初始化应用,并返回配置信息
-     * @access public
-     * @return array
-     */
-    public static function initCommon()
-    {
-        if (empty(self::$init)) {
-            if (defined('APP_NAMESPACE')) {
-                self::$namespace = APP_NAMESPACE;
-            }
-
-            Loader::addNamespace(self::$namespace, APP_PATH);
-
-            // 初始化应用
-            $config       = self::init();
-            self::$suffix = $config['class_suffix'];
-
-            // 应用调试模式
-            self::$debug = Env::get('app_debug', Config::get('app_debug'));
-
-            if (!self::$debug) {
-                ini_set('display_errors', 'Off');
-            } elseif (!IS_CLI) {
-                // 重新申请一块比较大的 buffer
-                if (ob_get_level() > 0) {
-                    $output = ob_get_clean();
-                }
-
-                ob_start();
-
-                if (!empty($output)) {
-                    echo $output;
-                }
-
-            }
-
-            if (!empty($config['root_namespace'])) {
-                Loader::addNamespace($config['root_namespace']);
-            }
-
-            // 加载额外文件
-            if (!empty($config['extra_file_list'])) {
-                foreach ($config['extra_file_list'] as $file) {
-                    $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT;
-                    if (is_file($file) && !isset(self::$file[$file])) {
-                        include $file;
-                        self::$file[$file] = true;
-                    }
-                }
-            }
-
-            // 设置系统时区
-            date_default_timezone_set($config['default_timezone']);
-
-            // 监听 app_init
-            Hook::listen('app_init');
-
-            self::$init = true;
-        }
-
-        return Config::get();
-    }
-
-    /**
-     * 初始化应用或模块
-     * @access public
-     * @param string $module 模块名
-     * @return array
-     */
-    private static function init($module = '')
-    {
-        // 定位模块目录
-        $module = $module ? $module . DS : '';
-
-        // 加载初始化文件
-        if (is_file(APP_PATH . $module . 'init' . EXT)) {
-            include APP_PATH . $module . 'init' . EXT;
-        } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) {
-            include RUNTIME_PATH . $module . 'init' . EXT;
-        } else {
-            // 加载模块配置
-            $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT);
-
-            // 读取数据库配置文件
-            $filename = CONF_PATH . $module . 'database' . CONF_EXT;
-            Config::load($filename, 'database');
-
-            // 读取扩展配置文件
-            if (is_dir(CONF_PATH . $module . 'extra')) {
-                $dir   = CONF_PATH . $module . 'extra';
-                $files = scandir($dir);
-                foreach ($files as $file) {
-                    if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) {
-                        $filename = $dir . DS . $file;
-                        Config::load($filename, pathinfo($file, PATHINFO_FILENAME));
-                    }
-                }
-            }
-
-            // 加载应用状态配置
-            if ($config['app_status']) {
-                Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);
-            }
-
-            // 加载行为扩展文件
-            if (is_file(CONF_PATH . $module . 'tags' . EXT)) {
-                Hook::import(include CONF_PATH . $module . 'tags' . EXT);
-            }
-
-            // 加载公共文件
-            $path = APP_PATH . $module;
-            if (is_file($path . 'common' . EXT)) {
-                include $path . 'common' . EXT;
-            }
-
-            // 加载当前模块语言包
-            if ($module) {
-                Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);
-            }
-        }
-
-        return Config::get();
-    }
-
     /**
      * 设置当前请求的调度信息
      * @access public
      * @param array|string  $dispatch 调度信息
-     * @param string        $type     调度类型
+     * @param string        $type 调度类型
      * @return void
      */
     public static function dispatch($dispatch, $type = 'module')
@@ -312,10 +197,8 @@ class App
     {
         $reflect = new \ReflectionFunction($function);
         $args    = self::bindParams($reflect, $vars);
-
         // 记录执行信息
         self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
-
         return $reflect->invokeArgs($args);
     }
 
@@ -335,180 +218,108 @@ class App
             // 静态方法
             $reflect = new \ReflectionMethod($method);
         }
-
         $args = self::bindParams($reflect, $vars);
 
         self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');
-
         return $reflect->invokeArgs(isset($class) ? $class : null, $args);
     }
 
     /**
      * 调用反射执行类的实例化 支持依赖注入
      * @access public
-     * @param string $class 类名
-     * @param array  $vars  变量
+     * @param string    $class 类名
+     * @param array     $vars  变量
      * @return mixed
      */
     public static function invokeClass($class, $vars = [])
     {
         $reflect     = new \ReflectionClass($class);
         $constructor = $reflect->getConstructor();
-        $args        = $constructor ? self::bindParams($constructor, $vars) : [];
-
+        if ($constructor) {
+            $args = self::bindParams($constructor, $vars);
+        } else {
+            $args = [];
+        }
         return $reflect->newInstanceArgs($args);
     }
 
     /**
      * 绑定参数
-     * @access private
+     * @access public
      * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类
      * @param array                                 $vars    变量
      * @return array
      */
     private static function bindParams($reflect, $vars = [])
     {
-        // 自动获取请求变量
         if (empty($vars)) {
-            $vars = Config::get('url_param_type') ?
-            Request::instance()->route() :
-            Request::instance()->param();
+            // 自动获取请求变量
+            if (Config::get('url_param_type')) {
+                $vars = Request::instance()->route();
+            } else {
+                $vars = Request::instance()->param();
+            }
         }
-
         $args = [];
+        // 判断数组类型 数字数组时按顺序绑定参数
+        reset($vars);
+        $type = key($vars) === 0 ? 1 : 0;
         if ($reflect->getNumberOfParameters() > 0) {
-            // 判断数组类型 数字数组时按顺序绑定参数
-            reset($vars);
-            $type = key($vars) === 0 ? 1 : 0;
-
-            foreach ($reflect->getParameters() as $param) {
-                $args[] = self::getParamValue($param, $vars, $type);
-            }
-        }
-
-        return $args;
-    }
-
-    /**
-     * 获取参数值
-     * @access private
-     * @param \ReflectionParameter  $param 参数
-     * @param array                 $vars  变量
-     * @param string                $type  类别
-     * @return array
-     */
-    private static function getParamValue($param, &$vars, $type)
-    {
-        $name  = $param->getName();
-        $class = $param->getClass();
-
-        if ($class) {
-            $className = $class->getName();
-            $bind      = Request::instance()->$name;
-
-            if ($bind instanceof $className) {
-                $result = $bind;
-            } else {
-                if (method_exists($className, 'invoke')) {
-                    $method = new \ReflectionMethod($className, 'invoke');
-
-                    if ($method->isPublic() && $method->isStatic()) {
-                        return $className::invoke(Request::instance());
+            $params = $reflect->getParameters();
+            foreach ($params as $param) {
+                $name  = $param->getName();
+                $class = $param->getClass();
+                if ($class) {
+                    $className = $class->getName();
+                    $bind      = Request::instance()->$name;
+                    if ($bind instanceof $className) {
+                        $args[] = $bind;
+                    } else {
+                        if (method_exists($className, 'invoke')) {
+                            $method = new \ReflectionMethod($className, 'invoke');
+                            if ($method->isPublic() && $method->isStatic()) {
+                                $args[] = $className::invoke(Request::instance());
+                                continue;
+                            }
+                        }
+                        $args[] = method_exists($className, 'instance') ? $className::instance() : new $className;
                     }
+                } elseif (1 == $type && !empty($vars)) {
+                    $args[] = array_shift($vars);
+                } elseif (0 == $type && isset($vars[$name])) {
+                    $args[] = $vars[$name];
+                } elseif ($param->isDefaultValueAvailable()) {
+                    $args[] = $param->getDefaultValue();
+                } else {
+                    throw new \InvalidArgumentException('method param miss:' . $name);
                 }
-
-                $result = method_exists($className, 'instance') ?
-                $className::instance() :
-                new $className;
             }
-        } elseif (1 == $type && !empty($vars)) {
-            $result = array_shift($vars);
-        } elseif (0 == $type && isset($vars[$name])) {
-            $result = $vars[$name];
-        } elseif ($param->isDefaultValueAvailable()) {
-            $result = $param->getDefaultValue();
-        } else {
-            throw new \InvalidArgumentException('method param miss:' . $name);
         }
-
-        return $result;
-    }
-
-    /**
-     * 执行调用分发
-     * @access protected
-     * @param array $dispatch 调用信息
-     * @param array $config   配置信息
-     * @return Response|mixed
-     * @throws \InvalidArgumentException
-     */
-    protected static function exec($dispatch, $config)
-    {
-        switch ($dispatch['type']) {
-            case 'redirect': // 重定向跳转
-                $data = Response::create($dispatch['url'], 'redirect')
-                    ->code($dispatch['status']);
-                break;
-            case 'module': // 模块/控制器/操作
-                $data = self::module(
-                    $dispatch['module'],
-                    $config,
-                    isset($dispatch['convert']) ? $dispatch['convert'] : null
-                );
-                break;
-            case 'controller': // 执行控制器操作
-                $vars = array_merge(Request::instance()->param(), $dispatch['var']);
-                $data = Loader::action(
-                    $dispatch['controller'],
-                    $vars,
-                    $config['url_controller_layer'],
-                    $config['controller_suffix']
-                );
-                break;
-            case 'method': // 回调方法
-                $vars = array_merge(Request::instance()->param(), $dispatch['var']);
-                $data = self::invokeMethod($dispatch['method'], $vars);
-                break;
-            case 'function': // 闭包
-                $data = self::invokeFunction($dispatch['function']);
-                break;
-            case 'response': // Response 实例
-                $data = $dispatch['response'];
-                break;
-            default:
-                throw new \InvalidArgumentException('dispatch type not support');
-        }
-
-        return $data;
+        return $args;
     }
 
     /**
      * 执行模块
      * @access public
-     * @param array $result  模块/控制器/操作
-     * @param array $config  配置参数
+     * @param array $result 模块/控制器/操作
+     * @param array $config 配置参数
      * @param bool  $convert 是否自动转换控制器和操作名
      * @return mixed
-     * @throws HttpException
      */
     public static function module($result, $config, $convert = null)
     {
         if (is_string($result)) {
             $result = explode('/', $result);
         }
-
         $request = Request::instance();
-
         if ($config['app_multi_module']) {
             // 多模块部署
             $module    = strip_tags(strtolower($result[0] ?: $config['default_module']));
             $bind      = Route::getBind('module');
             $available = false;
-
             if ($bind) {
                 // 绑定模块
                 list($bindModule) = explode('/', $bind);
-
                 if (empty($result[0])) {
                     $module    = $bindModule;
                     $available = true;
@@ -524,13 +335,8 @@ class App
                 // 初始化模块
                 $request->module($module);
                 $config = self::init($module);
-
                 // 模块请求缓存检查
-                $request->cache(
-                    $config['request_cache'],
-                    $config['request_cache_expire'],
-                    $config['request_cache_except']
-                );
+                $request->cache($config['request_cache'], $config['request_cache_expire']);
             } else {
                 throw new HttpException(404, 'module not exists:' . $module);
             }
@@ -539,32 +345,18 @@ class App
             $module = '';
             $request->module($module);
         }
-
-        // 设置默认过滤机制
-        $request->filter($config['default_filter']);
-
         // 当前模块路径
         App::$modulePath = APP_PATH . ($module ? $module . DS : '');
 
         // 是否自动转换控制器和操作名
         $convert = is_bool($convert) ? $convert : $config['url_convert'];
-
         // 获取控制器名
         $controller = strip_tags($result[1] ?: $config['default_controller']);
-
-        if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
-            throw new HttpException(404, 'controller not exists:' . $controller);
-        }
-
         $controller = $convert ? strtolower($controller) : $controller;
 
         // 获取操作名
         $actionName = strip_tags($result[2] ?: $config['default_action']);
-        if (!empty($config['action_convert'])) {
-            $actionName = Loader::parseName($actionName, 1);
-        } else {
-            $actionName = $convert ? strtolower($actionName) : $actionName;
-        }
+        $actionName = $convert ? strtolower($actionName) : $actionName;
 
         // 设置当前请求的控制器、操作
         $request->controller(Loader::parseName($controller, 1))->action($actionName);
@@ -572,17 +364,10 @@ class App
         // 监听module_init
         Hook::listen('module_init', $request);
 
-        try {
-            $instance = Loader::controller(
-                $controller,
-                $config['url_controller_layer'],
-                $config['controller_suffix'],
-                $config['empty_controller']
-            );
-        } catch (ClassNotFoundException $e) {
-            throw new HttpException(404, 'controller not exists:' . $e->getClass());
+        $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);
+        if (is_null($instance)) {
+            throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1));
         }
-
         // 获取当前操作名
         $action = $actionName . $config['action_suffix'];
 
@@ -590,13 +375,6 @@ class App
         if (is_callable([$instance, $action])) {
             // 执行操作方法
             $call = [$instance, $action];
-            // 严格获取当前操作方法名
-            $reflect    = new \ReflectionMethod($instance, $action);
-            $methodName = $reflect->getName();
-            $suffix     = $config['action_suffix'];
-            $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;
-            $request->action($actionName);
-
         } elseif (is_callable([$instance, '_empty'])) {
             // 空操作
             $call = [$instance, '_empty'];
@@ -611,11 +389,123 @@ class App
         return self::invokeMethod($call, $vars);
     }
 
+    /**
+     * 初始化应用
+     */
+    public static function initCommon()
+    {
+        if (empty(self::$init)) {
+            // 初始化应用
+            $config       = self::init();
+            self::$suffix = $config['class_suffix'];
+
+            // 应用调试模式
+            self::$debug = Env::get('app_debug', Config::get('app_debug'));
+            if (!self::$debug) {
+                ini_set('display_errors', 'Off');
+            } elseif (!IS_CLI) {
+                //重新申请一块比较大的buffer
+                if (ob_get_level() > 0) {
+                    $output = ob_get_clean();
+                }
+                ob_start();
+                if (!empty($output)) {
+                    echo $output;
+                }
+            }
+
+            // 注册应用命名空间
+            self::$namespace = $config['app_namespace'];
+            Loader::addNamespace($config['app_namespace'], APP_PATH);
+            if (!empty($config['root_namespace'])) {
+                Loader::addNamespace($config['root_namespace']);
+            }
+
+            // 加载额外文件
+            if (!empty($config['extra_file_list'])) {
+                foreach ($config['extra_file_list'] as $file) {
+                    $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT;
+                    if (is_file($file) && !isset(self::$file[$file])) {
+                        include $file;
+                        self::$file[$file] = true;
+                    }
+                }
+            }
+
+            // 设置系统时区
+            date_default_timezone_set($config['default_timezone']);
+
+            // 监听app_init
+            Hook::listen('app_init');
+
+            self::$init = true;
+        }
+        return Config::get();
+    }
+
+    /**
+     * 初始化应用或模块
+     * @access public
+     * @param string $module 模块名
+     * @return array
+     */
+    private static function init($module = '')
+    {
+        // 定位模块目录
+        $module = $module ? $module . DS : '';
+
+        // 加载初始化文件
+        if (is_file(APP_PATH . $module . 'init' . EXT)) {
+            include APP_PATH . $module . 'init' . EXT;
+        } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) {
+            include RUNTIME_PATH . $module . 'init' . EXT;
+        } else {
+            $path = APP_PATH . $module;
+            // 加载模块配置
+            $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT);
+            // 读取数据库配置文件
+            $filename = CONF_PATH . $module . 'database' . CONF_EXT;
+            Config::load($filename, 'database');
+            // 读取扩展配置文件
+            if (is_dir(CONF_PATH . $module . 'extra')) {
+                $dir   = CONF_PATH . $module . 'extra';
+                $files = scandir($dir);
+                foreach ($files as $file) {
+                    if (strpos($file, CONF_EXT)) {
+                        $filename = $dir . DS . $file;
+                        Config::load($filename, pathinfo($file, PATHINFO_FILENAME));
+                    }
+                }
+            }
+
+            // 加载应用状态配置
+            if ($config['app_status']) {
+                $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);
+            }
+
+            // 加载行为扩展文件
+            if (is_file(CONF_PATH . $module . 'tags' . EXT)) {
+                Hook::import(include CONF_PATH . $module . 'tags' . EXT);
+            }
+
+            // 加载公共文件
+            if (is_file($path . 'common' . EXT)) {
+                include $path . 'common' . EXT;
+            }
+
+            // 加载当前模块语言包
+            if ($module) {
+                Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);
+            }
+        }
+        return Config::get();
+    }
+
     /**
      * URL路由检测(根据PATH_INFO)
      * @access public
-     * @param  \think\Request $request 请求实例
-     * @param  array          $config  配置信息
+     * @param  \think\Request $request
+     * @param  array          $config
      * @return array
      * @throws \think\Exception
      */
@@ -624,7 +514,6 @@ class App
         $path   = $request->path();
         $depr   = $config['pathinfo_depr'];
         $result = false;
-
         // 路由检测
         $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
         if ($check) {
@@ -632,14 +521,18 @@ class App
             if (is_file(RUNTIME_PATH . 'route.php')) {
                 // 读取路由缓存
                 $rules = include RUNTIME_PATH . 'route.php';
-                is_array($rules) && Route::rules($rules);
+                if (is_array($rules)) {
+                    Route::rules($rules);
+                }
             } else {
                 $files = $config['route_config_file'];
                 foreach ($files as $file) {
                     if (is_file(CONF_PATH . $file . CONF_EXT)) {
                         // 导入路由配置
                         $rules = include CONF_PATH . $file . CONF_EXT;
-                        is_array($rules) && Route::import($rules);
+                        if (is_array($rules)) {
+                            Route::import($rules);
+                        }
                     }
                 }
             }
@@ -647,18 +540,15 @@ class App
             // 路由检测(根据路由定义返回不同的URL调度)
             $result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
             $must   = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];
-
             if ($must && false === $result) {
                 // 路由无效
                 throw new RouteNotFoundException();
             }
         }
-
-        // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
         if (false === $result) {
+            // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
             $result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
         }
-
         return $result;
     }
 

+ 67 - 98
thinkphp/library/think/Build.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -14,44 +14,36 @@ namespace think;
 class Build
 {
     /**
-     * 根据传入的 build 资料创建目录和文件
-     * @access public
-     * @param  array  $build     build 列表
+     * 根据传入的build资料创建目录和文件
+     * @access protected
+     * @param  array  $build build列表
      * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix    类库后缀
+     * @param  bool   $suffix 类库后缀
      * @return void
-     * @throws Exception
      */
     public static function run(array $build = [], $namespace = 'app', $suffix = false)
     {
         // 锁定
-        $lock = APP_PATH . 'build.lock';
-
-        // 如果锁定文件不可写(不存在)则进行处理,否则表示已经有程序在处理了
-        if (!is_writable($lock)) {
-            if (!touch($lock)) {
-                throw new Exception(
-                    '应用目录[' . APP_PATH . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~',
-                    10006
-                );
-            }
-
-            foreach ($build as $module => $list) {
-                if ('__dir__' == $module) {
-                    // 创建目录列表
-                    self::buildDir($list);
-                } elseif ('__file__' == $module) {
-                    // 创建文件列表
-                    self::buildFile($list);
-                } else {
-                    // 创建模块
-                    self::module($module, $list, $namespace, $suffix);
-                }
+        $lockfile = APP_PATH . 'build.lock';
+        if (is_writable($lockfile)) {
+            return;
+        } elseif (!touch($lockfile)) {
+            throw new Exception('应用目录[' . APP_PATH . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~', 10006);
+        }
+        foreach ($build as $module => $list) {
+            if ('__dir__' == $module) {
+                // 创建目录列表
+                self::buildDir($list);
+            } elseif ('__file__' == $module) {
+                // 创建文件列表
+                self::buildFile($list);
+            } else {
+                // 创建模块
+                self::module($module, $list, $namespace, $suffix);
             }
-
-            // 解除锁定
-            unlink($lock);
         }
+        // 解除锁定
+        unlink($lockfile);
     }
 
     /**
@@ -63,8 +55,10 @@ class Build
     protected static function buildDir($list)
     {
         foreach ($list as $dir) {
-            // 目录不存在则创建目录
-            !is_dir(APP_PATH . $dir) && mkdir(APP_PATH . $dir, 0755, true);
+            if (!is_dir(APP_PATH . $dir)) {
+                // 创建目录
+                mkdir(APP_PATH . $dir, 0755, true);
+            }
         }
     }
 
@@ -77,17 +71,12 @@ class Build
     protected static function buildFile($list)
     {
         foreach ($list as $file) {
-            // 先创建目录
             if (!is_dir(APP_PATH . dirname($file))) {
+                // 创建目录
                 mkdir(APP_PATH . dirname($file), 0755, true);
             }
-
-            // 再创建文件
             if (!is_file(APP_PATH . $file)) {
-                file_put_contents(
-                    APP_PATH . $file,
-                    'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : ''
-                );
+                file_put_contents(APP_PATH . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : '');
             }
         }
     }
@@ -95,60 +84,57 @@ class Build
     /**
      * 创建模块
      * @access public
-     * @param  string $module    模块名
-     * @param  array  $list      build 列表
+     * @param  string $module 模块名
+     * @param  array  $list build列表
      * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix    类库后缀
+     * @param  bool   $suffix 类库后缀
      * @return void
      */
     public static function module($module = '', $list = [], $namespace = 'app', $suffix = false)
     {
-        $module = $module ?: '';
-
-        // 创建模块目录
-        !is_dir(APP_PATH . $module) && mkdir(APP_PATH . $module);
-
-        // 如果不是 runtime 目录则需要创建配置文件和公共文件、创建模块的默认页面
+        $module = $module ? $module : '';
+        if (!is_dir(APP_PATH . $module)) {
+            // 创建模块目录
+            mkdir(APP_PATH . $module);
+        }
         if (basename(RUNTIME_PATH) != $module) {
+            // 创建配置文件和公共文件
             self::buildCommon($module);
+            // 创建模块的默认页面
             self::buildHello($module, $namespace, $suffix);
         }
-
-        // 未指定文件和目录,则创建默认的模块目录和文件
         if (empty($list)) {
+            // 创建默认的模块目录和文件
             $list = [
                 '__file__' => ['config.php', 'common.php'],
                 '__dir__'  => ['controller', 'model', 'view'],
             ];
         }
-
         // 创建子目录和文件
         foreach ($list as $path => $file) {
             $modulePath = APP_PATH . $module . DS;
-
             if ('__dir__' == $path) {
                 // 生成子目录
                 foreach ($file as $dir) {
-                    self::checkDirBuild($modulePath . $dir);
+                    if (!is_dir($modulePath . $dir)) {
+                        // 创建目录
+                        mkdir($modulePath . $dir, 0755, true);
+                    }
                 }
             } elseif ('__file__' == $path) {
                 // 生成(空白)文件
                 foreach ($file as $name) {
                     if (!is_file($modulePath . $name)) {
-                        file_put_contents(
-                            $modulePath . $name,
-                            'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : ''
-                        );
+                        file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : '');
                     }
                 }
             } else {
-                // 生成相关 MVC 文件
+                // 生成相关MVC文件
                 foreach ($file as $val) {
                     $val      = trim($val);
                     $filename = $modulePath . $path . DS . $val . ($suffix ? ucfirst($path) : '') . EXT;
                     $space    = $namespace . '\\' . ($module ? $module . '\\' : '') . $path;
                     $class    = $val . ($suffix ? ucfirst($path) : '');
-
                     switch ($path) {
                         case 'controller': // 控制器
                             $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}";
@@ -158,7 +144,10 @@ class Build
                             break;
                         case 'view': // 视图
                             $filename = $modulePath . $path . DS . $val . '.html';
-                            self::checkDirBuild(dirname($filename));
+                            if (!is_dir(dirname($filename))) {
+                                // 创建目录
+                                mkdir(dirname($filename), 0755, true);
+                            }
                             $content = '';
                             break;
                         default:
@@ -176,60 +165,40 @@ class Build
 
     /**
      * 创建模块的欢迎页面
-     * @access protected
-     * @param  string $module    模块名
+     * @access public
+     * @param  string $module 模块名
      * @param  string $namespace 应用类库命名空间
-     * @param  bool   $suffix    类库后缀
+     * @param  bool   $suffix 类库后缀
      * @return void
      */
     protected static function buildHello($module, $namespace, $suffix = false)
     {
-        $filename = APP_PATH . ($module ? $module . DS : '') .
-            'controller' . DS . 'Index' .
-            ($suffix ? 'Controller' : '') . EXT;
-
+        $filename = APP_PATH . ($module ? $module . DS : '') . 'controller' . DS . 'Index' . ($suffix ? 'Controller' : '') . EXT;
         if (!is_file($filename)) {
-            $module = $module ? $module . '\\' : '';
-            $suffix = $suffix ? 'Controller' : '';
-            $content = str_replace(
-                ['{$app}', '{$module}', '{layer}', '{$suffix}'],
-                [$namespace, $module, 'controller', $suffix],
-                file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl')
-            );
-
-            self::checkDirBuild(dirname($filename));
+            $content = file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl');
+            $content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [$namespace, $module ? $module . '\\' : '', 'controller', $suffix ? 'Controller' : ''], $content);
+            if (!is_dir(dirname($filename))) {
+                mkdir(dirname($filename), 0755, true);
+            }
             file_put_contents($filename, $content);
         }
     }
 
     /**
      * 创建模块的公共文件
-     * @access protected
+     * @access public
      * @param  string $module 模块名
      * @return void
      */
     protected static function buildCommon($module)
     {
-        $config = CONF_PATH . ($module ? $module . DS : '') . 'config.php';
-
-        self::checkDirBuild(dirname($config));
-
-        if (!is_file($config)) {
-            file_put_contents($config, "<?php\n//配置文件\nreturn [\n\n];");
+        $filename = CONF_PATH . ($module ? $module . DS : '') . 'config.php';
+        if (!is_file($filename)) {
+            file_put_contents($filename, "<?php\n//配置文件\nreturn [\n\n];");
+        }
+        $filename = APP_PATH . ($module ? $module . DS : '') . 'common.php';
+        if (!is_file($filename)) {
+            file_put_contents($filename, "<?php\n");
         }
-
-        $common = APP_PATH . ($module ? $module . DS : '') . 'common.php';
-        if (!is_file($common)) file_put_contents($common, "<?php\n");
-    }
-
-    /**
-     * 创建目录
-     * @access protected
-     * @param  string $dirname 目录名称
-     * @return void
-     */
-    protected static function checkDirBuild($dirname)
-    {
-        !is_dir($dirname) && mkdir($dirname, 0755, true);
     }
 }

+ 69 - 85
thinkphp/library/think/Cache.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -15,233 +15,217 @@ use think\cache\Driver;
 
 class Cache
 {
-    /**
-     * @var array 缓存的实例
-     */
-    public static $instance = [];
-
-    /**
-     * @var int 缓存读取次数
-     */
-    public static $readTimes = 0;
-
-    /**
-     * @var int 缓存写入次数
-     */
-    public static $writeTimes = 0;
+    protected static $instance = [];
+    public static $readTimes   = 0;
+    public static $writeTimes  = 0;
 
     /**
-     * @var object 操作句柄
+     * 操作句柄
+     * @var object
+     * @access protected
      */
-    public static $handler;
+    protected static $handler;
 
     /**
-     * 连接缓存驱动
+     * 连接缓存
      * @access public
-     * @param  array       $options 配置数组
-     * @param  bool|string $name    缓存连接标识 true 强制重新连接
+     * @param array         $options  配置数组
+     * @param bool|string   $name 缓存连接标识 true 强制重新连接
      * @return Driver
      */
     public static function connect(array $options = [], $name = false)
     {
         $type = !empty($options['type']) ? $options['type'] : 'File';
-
         if (false === $name) {
             $name = md5(serialize($options));
         }
 
         if (true === $name || !isset(self::$instance[$name])) {
-            $class = false === strpos($type, '\\') ?
-            '\\think\\cache\\driver\\' . ucwords($type) :
-            $type;
+            $class = false !== strpos($type, '\\') ? $type : '\\think\\cache\\driver\\' . ucwords($type);
 
             // 记录初始化信息
             App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info');
-
             if (true === $name) {
                 return new $class($options);
+            } else {
+                self::$instance[$name] = new $class($options);
             }
-
-            self::$instance[$name] = new $class($options);
         }
-
-        return self::$instance[$name];
+        self::$handler = self::$instance[$name];
+        return self::$handler;
     }
 
     /**
      * 自动初始化缓存
      * @access public
-     * @param  array $options 配置数组
-     * @return Driver
+     * @param array         $options  配置数组
+     * @return void
      */
     public static function init(array $options = [])
     {
         if (is_null(self::$handler)) {
-            if (empty($options) && 'complex' == Config::get('cache.type')) {
-                $default = Config::get('cache.default');
-                // 获取默认缓存配置,并连接
-                $options = Config::get('cache.' . $default['type']) ?: $default;
-            } elseif (empty($options)) {
-                $options = Config::get('cache');
+            // 自动初始化缓存
+            if (!empty($options)) {
+                self::connect($options);
+            } elseif ('complex' == Config::get('cache.type')) {
+                self::connect(Config::get('cache.default'));
+            } else {
+                self::connect(Config::get('cache'));
             }
-
-            self::$handler = self::connect($options);
         }
-
-        return self::$handler;
     }
 
     /**
      * 切换缓存类型 需要配置 cache.type 为 complex
      * @access public
-     * @param  string $name 缓存标识
+     * @param string $name 缓存标识
      * @return Driver
      */
-    public static function store($name = '')
+    public static function store($name)
     {
-        if ('' !== $name && 'complex' == Config::get('cache.type')) {
-            return self::connect(Config::get('cache.' . $name), strtolower($name));
+        if ('complex' == Config::get('cache.type')) {
+            self::connect(Config::get('cache.' . $name), strtolower($name));
         }
-
-        return self::init();
+        return self::$handler;
     }
 
     /**
      * 判断缓存是否存在
      * @access public
-     * @param  string $name 缓存变量名
+     * @param string $name 缓存变量名
      * @return bool
      */
     public static function has($name)
     {
+        self::init();
         self::$readTimes++;
-
-        return self::init()->has($name);
+        return self::$handler->has($name);
     }
 
     /**
      * 读取缓存
      * @access public
-     * @param  string $name    缓存标识
-     * @param  mixed  $default 默认值
+     * @param string $name 缓存标识
+     * @param mixed  $default 默认值
      * @return mixed
      */
     public static function get($name, $default = false)
     {
+        self::init();
         self::$readTimes++;
-
-        return self::init()->get($name, $default);
+        return self::$handler->get($name, $default);
     }
 
     /**
      * 写入缓存
      * @access public
-     * @param  string   $name   缓存标识
-     * @param  mixed    $value  存储数据
-     * @param  int|null $expire 有效时间 0为永久
+     * @param string        $name 缓存标识
+     * @param mixed         $value  存储数据
+     * @param int|null      $expire  有效时间 0为永久
      * @return boolean
      */
     public static function set($name, $value, $expire = null)
     {
+        self::init();
         self::$writeTimes++;
-
-        return self::init()->set($name, $value, $expire);
+        return self::$handler->set($name, $value, $expire);
     }
 
     /**
      * 自增缓存(针对数值缓存)
      * @access public
-     * @param  string $name 缓存变量名
-     * @param  int    $step 步长
+     * @param string    $name 缓存变量名
+     * @param int       $step 步长
      * @return false|int
      */
     public static function inc($name, $step = 1)
     {
+        self::init();
         self::$writeTimes++;
-
-        return self::init()->inc($name, $step);
+        return self::$handler->inc($name, $step);
     }
 
     /**
      * 自减缓存(针对数值缓存)
      * @access public
-     * @param  string $name 缓存变量名
-     * @param  int    $step 步长
+     * @param string    $name 缓存变量名
+     * @param int       $step 步长
      * @return false|int
      */
     public static function dec($name, $step = 1)
     {
+        self::init();
         self::$writeTimes++;
-
-        return self::init()->dec($name, $step);
+        return self::$handler->dec($name, $step);
     }
 
     /**
      * 删除缓存
      * @access public
-     * @param  string $name 缓存标识
+     * @param string    $name 缓存标识
      * @return boolean
      */
     public static function rm($name)
     {
+        self::init();
         self::$writeTimes++;
-
-        return self::init()->rm($name);
+        return self::$handler->rm($name);
     }
 
     /**
      * 清除缓存
      * @access public
-     * @param  string $tag 标签名
+     * @param string $tag 标签名
      * @return boolean
      */
     public static function clear($tag = null)
     {
+        self::init();
         self::$writeTimes++;
-
-        return self::init()->clear($tag);
+        return self::$handler->clear($tag);
     }
 
     /**
      * 读取缓存并删除
      * @access public
-     * @param  string $name 缓存变量名
+     * @param string $name 缓存变量名
      * @return mixed
      */
     public static function pull($name)
     {
+        self::init();
         self::$readTimes++;
         self::$writeTimes++;
-
-        return self::init()->pull($name);
+        return self::$handler->pull($name);
     }
 
     /**
      * 如果不存在则写入缓存
      * @access public
-     * @param  string $name   缓存变量名
-     * @param  mixed  $value  存储数据
-     * @param  int    $expire 有效时间 0为永久
+     * @param string    $name 缓存变量名
+     * @param mixed     $value  存储数据
+     * @param int       $expire  有效时间 0为永久
      * @return mixed
      */
     public static function remember($name, $value, $expire = null)
     {
+        self::init();
         self::$readTimes++;
-
-        return self::init()->remember($name, $value, $expire);
+        return self::$handler->remember($name, $value, $expire);
     }
 
     /**
      * 缓存标签
      * @access public
-     * @param  string       $name    标签名
-     * @param  string|array $keys    缓存标识
-     * @param  bool         $overlay 是否覆盖
+     * @param string        $name 标签名
+     * @param string|array  $keys 缓存标识
+     * @param bool          $overlay 是否覆盖
      * @return Driver
      */
     public static function tag($name, $keys = null, $overlay = false)
     {
-        return self::init()->tag($name, $keys, $overlay);
+        self::init();
+        return self::$handler->tag($name, $keys, $overlay);
     }
 
 }

+ 118 - 212
thinkphp/library/think/Collection.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -19,35 +19,20 @@ use JsonSerializable;
 
 class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable
 {
-    /**
-     * @var array 数据
-     */
     protected $items = [];
 
-    /**
-     * Collection constructor.
-     * @access public
-     * @param  array $items 数据
-     */
     public function __construct($items = [])
     {
         $this->items = $this->convertToArray($items);
     }
 
-    /**
-     * 创建 Collection 实例
-     * @access public
-     * @param  array $items 数据
-     * @return static
-     */
     public static function make($items = [])
     {
         return new static($items);
     }
 
     /**
-     * 判断数据是否为空
-     * @access public
+     * 是否为空
      * @return bool
      */
     public function isEmpty()
@@ -55,96 +40,74 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         return empty($this->items);
     }
 
-    /**
-     * 将数据转成数组
-     * @access public
-     * @return array
-     */
     public function toArray()
     {
         return array_map(function ($value) {
-            return ($value instanceof Model || $value instanceof self) ?
-                $value->toArray() :
-                $value;
+            return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value;
         }, $this->items);
     }
 
-    /**
-     * 获取全部的数据
-     * @access public
-     * @return array
-     */
     public function all()
     {
         return $this->items;
     }
 
     /**
-     * 交换数组中的键和值
-     * @access public
-     * @return static
-     */
-    public function flip()
-    {
-        return new static(array_flip($this->items));
-    }
-
-    /**
-     * 返回数组中所有的键名组成的新 Collection 实例
-     * @access public
+     * 合并数组
+     *
+     * @param  mixed $items
      * @return static
      */
-    public function keys()
+    public function merge($items)
     {
-        return new static(array_keys($this->items));
+        return new static(array_merge($this->items, $this->convertToArray($items)));
     }
 
     /**
-     * 返回数组中所有的值组成的新 Collection 实例
-     * @access public
+     * 比较数组,返回差集
+     *
+     * @param  mixed $items
      * @return static
      */
-    public function values()
+    public function diff($items)
     {
-        return new static(array_values($this->items));
+        return new static(array_diff($this->items, $this->convertToArray($items)));
     }
 
     /**
-     * 合并数组并返回一个新的 Collection 实例
-     * @access public
-     * @param  mixed $items 新的数据
+     * 交换数组中的键和值
+     *
      * @return static
      */
-    public function merge($items)
+    public function flip()
     {
-        return new static(array_merge($this->items, $this->convertToArray($items)));
+        return new static(array_flip($this->items));
     }
 
     /**
-     * 比较数组,返回差集生成的新 Collection 实例
-     * @access public
-     * @param  mixed $items 做比较的数据
+     * 比较数组,返回交集
+     *
+     * @param  mixed $items
      * @return static
      */
-    public function diff($items)
+    public function intersect($items)
     {
-        return new static(array_diff($this->items, $this->convertToArray($items)));
+        return new static(array_intersect($this->items, $this->convertToArray($items)));
     }
 
     /**
-     * 比较数组,返回交集组成的 Collection 新实例
-     * @access public
-     * @param  mixed $items 比较数据
+     * 返回数组中所有的键名
+     *
      * @return static
      */
-    public function intersect($items)
+    public function keys()
     {
-        return new static(array_intersect($this->items, $this->convertToArray($items)));
+        return new static(array_keys($this->items));
     }
 
     /**
-     * 返回并删除数据中的的最后一个元素(出栈)
-     * @access public
+     * 删除数组的最后一个元素(出栈)
+     *
      * @return mixed
      */
     public function pop()
@@ -152,53 +115,11 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         return array_pop($this->items);
     }
 
-    /**
-     * 返回并删除数据中首个元素
-     * @access public
-     * @return mixed
-     */
-    public function shift()
-    {
-        return array_shift($this->items);
-    }
-
-    /**
-     * 在数组开头插入一个元素
-     * @access public
-     * @param mixed $value 值
-     * @param mixed $key   键名
-     * @return void
-     */
-    public function unshift($value, $key = null)
-    {
-        if (is_null($key)) {
-            array_unshift($this->items, $value);
-        } else {
-            $this->items = [$key => $value] + $this->items;
-        }
-    }
-
-    /**
-     * 在数组结尾插入一个元素
-     * @access public
-     * @param  mixed $value 值
-     * @param  mixed $key   键名
-     * @return void
-     */
-    public function push($value, $key = null)
-    {
-        if (is_null($key)) {
-            $this->items[] = $value;
-        } else {
-            $this->items[$key] = $value;
-        }
-    }
-
     /**
      * 通过使用用户自定义函数,以字符串返回数组
-     * @access public
-     * @param  callable $callback 回调函数
-     * @param  mixed    $initial  初始值
+     *
+     * @param  callable $callback
+     * @param  mixed    $initial
      * @return mixed
      */
     public function reduce(callable $callback, $initial = null)
@@ -207,8 +128,8 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
     }
 
     /**
-     * 以相反的顺序创建一个新的 Collection 实例
-     * @access public
+     * 以相反的顺序返回数组。
+     *
      * @return static
      */
     public function reverse()
@@ -217,10 +138,20 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
     }
 
     /**
-     * 把数据分割为新的数组块
-     * @access public
-     * @param  int  $size         分隔长度
-     * @param  bool $preserveKeys 是否保持原数据索引
+     * 删除数组中首个元素,并返回被删除元素的值
+     *
+     * @return mixed
+     */
+    public function shift()
+    {
+        return array_shift($this->items);
+    }
+
+    /**
+     * 把一个数组分割为新的数组块.
+     *
+     * @param  int  $size
+     * @param  bool $preserveKeys
      * @return static
      */
     public function chunk($size, $preserveKeys = false)
@@ -235,70 +166,78 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
     }
 
     /**
-     * 给数据中的每个元素执行回调
-     * @access public
-     * @param  callable $callback 回调函数
+     * 在数组开头插入一个元素
+     * @param mixed $value
+     * @param null  $key
+     * @return int
+     */
+    public function unshift($value, $key = null)
+    {
+        if (is_null($key)) {
+            array_unshift($this->items, $value);
+        } else {
+            $this->items = [$key => $value] + $this->items;
+        }
+    }
+
+    /**
+     * 给每个元素执行个回调
+     *
+     * @param  callable $callback
      * @return $this
      */
     public function each(callable $callback)
     {
         foreach ($this->items as $key => $item) {
-            $result = $callback($item, $key);
-
-            if (false === $result) {
+            if ($callback($item, $key) === false) {
                 break;
             }
-
-            if (!is_object($item)) {
-                $this->items[$key] = $result;
-            }
         }
 
         return $this;
     }
 
     /**
-     * 用回调函数过滤数据中的元素
-     * @access public
-     * @param callable|null $callback 回调函数
+     * 用回调函数过滤数组中的元素
+     * @param callable|null $callback
      * @return static
      */
     public function filter(callable $callback = null)
     {
-        return new static(array_filter($this->items, $callback ?: null));
+        if ($callback) {
+            return new static(array_filter($this->items, $callback));
+        }
+
+        return new static(array_filter($this->items));
     }
 
     /**
-     * 返回数据中指定的一列
-     * @access public
-     * @param mixed $columnKey 键名
-     * @param null  $indexKey  作为索引值的列
+     * 返回数组中指定的一列
+     * @param      $column_key
+     * @param null $index_key
      * @return array
      */
-    public function column($columnKey, $indexKey = null)
+    public function column($column_key, $index_key = null)
     {
         if (function_exists('array_column')) {
-            return array_column($this->items, $columnKey, $indexKey);
+            return array_column($this->items, $column_key, $index_key);
         }
 
         $result = [];
         foreach ($this->items as $row) {
-            $key    = $value = null;
+            $key    = $value    = null;
             $keySet = $valueSet = false;
-
-            if (null !== $indexKey && array_key_exists($indexKey, $row)) {
-                $key    = (string) $row[$indexKey];
+            if (null !== $index_key && array_key_exists($index_key, $row)) {
                 $keySet = true;
+                $key    = (string) $row[$index_key];
             }
-
-            if (null === $columnKey) {
+            if (null === $column_key) {
                 $valueSet = true;
                 $value    = $row;
-            } elseif (is_array($row) && array_key_exists($columnKey, $row)) {
+            } elseif (is_array($row) && array_key_exists($column_key, $row)) {
                 $valueSet = true;
-                $value    = $row[$columnKey];
+                $value    = $row[$column_key];
             }
-
             if ($valueSet) {
                 if ($keySet) {
                     $result[$key] = $value;
@@ -307,30 +246,34 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
                 }
             }
         }
-
         return $result;
     }
 
     /**
-     * 对数据排序,并返回排序后的数据组成的新 Collection 实例
-     * @access public
-     * @param  callable|null $callback 回调函数
+     * 对数组排序
+     *
+     * @param  callable|null $callback
      * @return static
      */
     public function sort(callable $callback = null)
     {
-        $items    = $this->items;
-        $callback = $callback ?: function ($a, $b) {
-            return $a == $b ? 0 : (($a < $b) ? -1 : 1);
-        };
+        $items = $this->items;
+
+        $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) {
+
+            if ($a == $b) {
+                return 0;
+            }
+
+            return ($a < $b) ? -1 : 1;
+        });
 
-        uasort($items, $callback);
         return new static($items);
     }
 
     /**
-     * 将数据打乱后组成新的 Collection 实例
-     * @access public
+     * 将数组打乱
+     *
      * @return static
      */
     public function shuffle()
@@ -338,15 +281,16 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         $items = $this->items;
 
         shuffle($items);
+
         return new static($items);
     }
 
     /**
-     * 截取数据并返回新的 Collection 实例
-     * @access public
-     * @param  int  $offset       起始位置
-     * @param  int  $length       截取长度
-     * @param  bool $preserveKeys 是否保持原先的键名
+     * 截取数
+     *
+     * @param  int  $offset
+     * @param  int  $length
+     * @param  bool $preserveKeys
      * @return static
      */
     public function slice($offset, $length = null, $preserveKeys = false)
@@ -354,35 +298,17 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         return new static(array_slice($this->items, $offset, $length, $preserveKeys));
     }
 
-    /**
-     * 指定的键是否存在
-     * @access public
-     * @param  mixed $offset 键名
-     * @return bool
-     */
+    // ArrayAccess
     public function offsetExists($offset)
     {
         return array_key_exists($offset, $this->items);
     }
 
-    /**
-     * 获取指定键对应的值
-     * @access public
-     * @param  mixed $offset 键名
-     * @return mixed
-     */
     public function offsetGet($offset)
     {
         return $this->items[$offset];
     }
 
-    /**
-     * 设置键值
-     * @access public
-     * @param  mixed $offset 键名
-     * @param  mixed $value  值
-     * @return void
-     */
     public function offsetSet($offset, $value)
     {
         if (is_null($offset)) {
@@ -392,51 +318,33 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         }
     }
 
-    /**
-     * 删除指定键值
-     * @access public
-     * @param  mixed $offset 键名
-     * @return void
-     */
     public function offsetUnset($offset)
     {
         unset($this->items[$offset]);
     }
 
-    /**
-     * 统计数据的个数
-     * @access public
-     * @return int
-     */
+    //Countable
     public function count()
     {
         return count($this->items);
     }
 
-    /**
-     * 获取数据的迭代器
-     * @access public
-     * @return ArrayIterator
-     */
+    //IteratorAggregate
     public function getIterator()
     {
         return new ArrayIterator($this->items);
     }
 
-    /**
-     * 将数据反序列化成数组
-     * @access public
-     * @return array
-     */
+    //JsonSerializable
     public function jsonSerialize()
     {
         return $this->toArray();
     }
 
     /**
-     * 转换当前数据集为 JSON 字符串
+     * 转换当前数据集为JSON字符串
      * @access public
-     * @param  integer $options json 参数
+     * @param integer $options json参数
      * @return string
      */
     public function toJson($options = JSON_UNESCAPED_UNICODE)
@@ -444,24 +352,22 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
         return json_encode($this->toArray(), $options);
     }
 
-    /**
-     * 将数据转换成字符串
-     * @access public
-     * @return string
-     */
     public function __toString()
     {
         return $this->toJson();
     }
 
     /**
-     * 将数据转换成数组
-     * @access protected
-     * @param  mixed $items 数据
+     * 转换成数组
+     *
+     * @param  mixed $items
      * @return array
      */
     protected function convertToArray($items)
     {
-        return $items instanceof self ? $items->all() : (array) $items;
+        if ($items instanceof self) {
+            return $items->all();
+        }
+        return (array) $items;
     }
 }

+ 58 - 102
thinkphp/library/think/Config.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -13,88 +13,70 @@ namespace think;
 
 class Config
 {
-    /**
-     * @var array 配置参数
-     */
+    // 配置参数
     private static $config = [];
-
-    /**
-     * @var string 参数作用域
-     */
+    // 参数作用域
     private static $range = '_sys_';
 
-    /**
-     * 设定配置参数的作用域
-     * @access public
-     * @param  string $range 作用域
-     * @return void
-     */
+    // 设定配置参数的作用域
     public static function range($range)
     {
         self::$range = $range;
-
-        if (!isset(self::$config[$range])) self::$config[$range] = [];
+        if (!isset(self::$config[$range])) {
+            self::$config[$range] = [];
+        }
     }
 
     /**
      * 解析配置文件或内容
-     * @access public
-     * @param  string $config 配置文件路径或内容
-     * @param  string $type   配置解析类型
-     * @param  string $name   配置名(如设置即表示二级配置)
-     * @param  string $range  作用域
+     * @param string    $config 配置文件路径或内容
+     * @param string    $type 配置解析类型
+     * @param string    $name 配置名(如设置即表示二级配置)
+     * @param string    $range  作用域
      * @return mixed
      */
     public static function parse($config, $type = '', $name = '', $range = '')
     {
         $range = $range ?: self::$range;
-
-        if (empty($type)) $type = pathinfo($config, PATHINFO_EXTENSION);
-
-        $class = false !== strpos($type, '\\') ?
-            $type :
-            '\\think\\config\\driver\\' . ucwords($type);
-
+        if (empty($type)) {
+            $type = pathinfo($config, PATHINFO_EXTENSION);
+        }
+        $class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type);
         return self::set((new $class())->parse($config), $name, $range);
     }
 
     /**
      * 加载配置文件(PHP格式)
-     * @access public
-     * @param  string $file  配置文件名
-     * @param  string $name  配置名(如设置即表示二级配置)
-     * @param  string $range 作用域
+     * @param string    $file 配置文件名
+     * @param string    $name 配置名(如设置即表示二级配置)
+     * @param string    $range  作用域
      * @return mixed
      */
     public static function load($file, $name = '', $range = '')
     {
         $range = $range ?: self::$range;
-
-        if (!isset(self::$config[$range])) self::$config[$range] = [];
-
+        if (!isset(self::$config[$range])) {
+            self::$config[$range] = [];
+        }
         if (is_file($file)) {
             $name = strtolower($name);
             $type = pathinfo($file, PATHINFO_EXTENSION);
-
             if ('php' == $type) {
                 return self::set(include $file, $name, $range);
-            }
-
-            if ('yaml' == $type && function_exists('yaml_parse_file')) {
+            } elseif ('yaml' == $type && function_exists('yaml_parse_file')) {
                 return self::set(yaml_parse_file($file), $name, $range);
+            } else {
+                return self::parse($file, $type, $name, $range);
             }
-
-            return self::parse($file, $type, $name, $range);
+        } else {
+            return self::$config[$range];
         }
-
-        return self::$config[$range];
     }
 
     /**
      * 检测配置是否存在
-     * @access public
-     * @param  string $name 配置参数名(支持二级配置 . 号分割)
-     * @param  string $range  作用域
+     * @param string    $name 配置参数名(支持二级配置 .号分割)
+     * @param string    $range  作用域
      * @return bool
      */
     public static function has($name, $range = '')
@@ -103,108 +85,82 @@ class Config
 
         if (!strpos($name, '.')) {
             return isset(self::$config[$range][strtolower($name)]);
+        } else {
+            // 二维数组设置和获取支持
+            $name = explode('.', $name);
+            return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
         }
-
-        // 二维数组设置和获取支持
-        $name = explode('.', $name, 2);
-        return isset(self::$config[$range][strtolower($name[0])][$name[1]]);
     }
 
     /**
      * 获取配置参数 为空则获取所有配置
-     * @access public
-     * @param  string $name 配置参数名(支持二级配置 . 号分割)
-     * @param  string $range  作用域
+     * @param string    $name 配置参数名(支持二级配置 .号分割)
+     * @param string    $range  作用域
      * @return mixed
      */
     public static function get($name = null, $range = '')
     {
         $range = $range ?: self::$range;
-
         // 无参数时获取所有
         if (empty($name) && isset(self::$config[$range])) {
             return self::$config[$range];
         }
 
-        // 非二级配置时直接返回
         if (!strpos($name, '.')) {
             $name = strtolower($name);
             return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;
+        } else {
+            // 二维数组设置和获取支持
+            $name    = explode('.', $name);
+            $name[0] = strtolower($name[0]);
+            return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null;
         }
-
-        // 二维数组设置和获取支持
-        $name    = explode('.', $name, 2);
-        $name[0] = strtolower($name[0]);
-
-        if (!isset(self::$config[$range][$name[0]])) {
-            // 动态载入额外配置
-            $module = Request::instance()->module();
-            $file   = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT;
-
-            is_file($file) && self::load($file, $name[0]);
-        }
-
-        return isset(self::$config[$range][$name[0]][$name[1]]) ?
-            self::$config[$range][$name[0]][$name[1]] :
-            null;
     }
 
     /**
-     * 设置配置参数 name 为数组则为批量设置
-     * @access public
-     * @param  string|array $name  配置参数名(支持二级配置 . 号分割)
-     * @param  mixed        $value 配置值
-     * @param  string       $range 作用域
+     * 设置配置参数 name为数组则为批量设置
+     * @param string|array  $name 配置参数名(支持二级配置 .号分割)
+     * @param mixed         $value 配置值
+     * @param string        $range  作用域
      * @return mixed
      */
     public static function set($name, $value = null, $range = '')
     {
         $range = $range ?: self::$range;
-
-        if (!isset(self::$config[$range])) self::$config[$range] = [];
-
-        // 字符串则表示单个配置设置
+        if (!isset(self::$config[$range])) {
+            self::$config[$range] = [];
+        }
         if (is_string($name)) {
             if (!strpos($name, '.')) {
                 self::$config[$range][strtolower($name)] = $value;
             } else {
-                // 二维数组
-                $name = explode('.', $name, 2);
+                // 二维数组设置和获取支持
+                $name                                                 = explode('.', $name);
                 self::$config[$range][strtolower($name[0])][$name[1]] = $value;
             }
-
-            return $value;
-        }
-
-        // 数组则表示批量设置
-        if (is_array($name)) {
+            return;
+        } elseif (is_array($name)) {
+            // 批量设置
             if (!empty($value)) {
                 self::$config[$range][$value] = isset(self::$config[$range][$value]) ?
-                    array_merge(self::$config[$range][$value], $name) :
-                    $name;
-
+                array_merge(self::$config[$range][$value], $name) :
+                self::$config[$range][$value] = $name;
                 return self::$config[$range][$value];
+            } else {
+                return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name));
             }
-
-            return self::$config[$range] = array_merge(
-                self::$config[$range], array_change_key_case($name)
-            );
+        } else {
+            // 为空直接返回 已有配置
+            return self::$config[$range];
         }
-
-        // 为空直接返回已有配置
-        return self::$config[$range];
     }
 
     /**
      * 重置配置参数
-     * @access public
-     * @param  string $range 作用域
-     * @return void
      */
     public static function reset($range = '')
     {
         $range = $range ?: self::$range;
-
         if (true === $range) {
             self::$config = [];
         } else {

+ 122 - 266
thinkphp/library/think/Console.php

@@ -20,49 +20,20 @@ use think\console\output\driver\Buffer;
 
 class Console
 {
-    /**
-     * @var string 命令名称
-     */
-    private $name;
 
-    /**
-     * @var string 命令版本
-     */
+    private $name;
     private $version;
 
-    /**
-     * @var Command[] 命令
-     */
+    /** @var Command[] */
     private $commands = [];
 
-    /**
-     * @var bool 是否需要帮助信息
-     */
     private $wantHelps = false;
 
-    /**
-     * @var bool 是否捕获异常
-     */
     private $catchExceptions = true;
-
-    /**
-     * @var bool 是否自动退出执行
-     */
-    private $autoExit = true;
-
-    /**
-     * @var InputDefinition 输入定义
-     */
+    private $autoExit        = true;
     private $definition;
-
-    /**
-     * @var string 默认执行的命令
-     */
     private $defaultCommand;
 
-    /**
-     * @var array 默认提供的命令
-     */
     private static $defaultCommands = [
         "think\\console\\command\\Help",
         "think\\console\\command\\Lists",
@@ -76,22 +47,11 @@ class Console
         "think\\console\\command\\optimize\\Schema",
     ];
 
-    /**
-     * Console constructor.
-     * @access public
-     * @param  string     $name    名称
-     * @param  string     $version 版本
-     * @param null|string $user    执行用户
-     */
-    public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN', $user = null)
+    public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
     {
         $this->name    = $name;
         $this->version = $version;
 
-        if ($user) {
-            $this->setUser($user);
-        }
-
         $this->defaultCommand = 'list';
         $this->definition     = $this->getDefaultInputDefinition();
 
@@ -100,58 +60,38 @@ class Console
         }
     }
 
-    /**
-     * 设置执行用户
-     * @param $user
-     */
-    public function setUser($user)
-    {
-        $user = posix_getpwnam($user);
-        if ($user) {
-            posix_setuid($user['uid']);
-            posix_setgid($user['gid']);
-        }
-    }
-
-    /**
-     * 初始化 Console
-     * @access public
-     * @param  bool $run 是否运行 Console
-     * @return int|Console
-     */
     public static function init($run = true)
     {
         static $console;
-
         if (!$console) {
-            $config = Config::get('console');
-            // 实例化 console
-            $console = new self($config['name'], $config['version'], $config['user']);
-
+            // 实例化console
+            $console = new self('Think Console', '0.1');
             // 读取指令集
             if (is_file(CONF_PATH . 'command' . EXT)) {
                 $commands = include CONF_PATH . 'command' . EXT;
-
                 if (is_array($commands)) {
                     foreach ($commands as $command) {
-                        class_exists($command) &&
-                        is_subclass_of($command, "\\think\\console\\Command") &&
-                        $console->add(new $command());  // 注册指令
+                        if (class_exists($command) && is_subclass_of($command, "\\think\\console\\Command")) {
+                            // 注册指令
+                            $console->add(new $command());
+                        }
                     }
                 }
             }
         }
-
-        return $run ? $console->run() : $console;
+        if ($run) {
+            // 运行
+            return $console->run();
+        } else {
+            return $console;
+        }
     }
 
     /**
-     * 调用命令
-     * @access public
-     * @param  string $command
-     * @param  array  $parameters
-     * @param  string $driver
-     * @return Output
+     * @param        $command
+     * @param array  $parameters
+     * @param string $driver
+     * @return Output|Buffer
      */
     public static function call($command, array $parameters = [], $driver = 'buffer')
     {
@@ -170,9 +110,9 @@ class Console
 
     /**
      * 执行当前的指令
-     * @access public
      * @return int
      * @throws \Exception
+     * @api
      */
     public function run()
     {
@@ -184,21 +124,27 @@ class Console
         try {
             $exitCode = $this->doRun($input, $output);
         } catch (\Exception $e) {
-            if (!$this->catchExceptions) throw $e;
+            if (!$this->catchExceptions) {
+                throw $e;
+            }
 
             $output->renderException($e);
 
             $exitCode = $e->getCode();
-
             if (is_numeric($exitCode)) {
-                $exitCode = ((int) $exitCode) ?: 1;
+                $exitCode = (int) $exitCode;
+                if (0 === $exitCode) {
+                    $exitCode = 1;
+                }
             } else {
                 $exitCode = 1;
             }
         }
 
         if ($this->autoExit) {
-            if ($exitCode > 255) $exitCode = 255;
+            if ($exitCode > 255) {
+                $exitCode = 255;
+            }
 
             exit($exitCode);
         }
@@ -208,14 +154,12 @@ class Console
 
     /**
      * 执行指令
-     * @access public
-     * @param  Input  $input  输入
-     * @param  Output $output 输出
+     * @param Input  $input
+     * @param Output $output
      * @return int
      */
     public function doRun(Input $input, Output $output)
     {
-        // 获取版本信息
         if (true === $input->hasParameterOption(['--version', '-V'])) {
             $output->writeln($this->getLongVersion());
 
@@ -224,7 +168,6 @@ class Console
 
         $name = $this->getCommandName($input);
 
-        // 获取帮助信息
         if (true === $input->hasParameterOption(['--help', '-h'])) {
             if (!$name) {
                 $name  = 'help';
@@ -239,26 +182,25 @@ class Console
             $input = new Input([$this->defaultCommand]);
         }
 
-        return $this->doRunCommand($this->find($name), $input, $output);
+        $command = $this->find($name);
+
+        $exitCode = $this->doRunCommand($command, $input, $output);
+
+        return $exitCode;
     }
 
     /**
      * 设置输入参数定义
-     * @access public
-     * @param  InputDefinition $definition 输入定义
-     * @return $this;
+     * @param InputDefinition $definition
      */
     public function setDefinition(InputDefinition $definition)
     {
         $this->definition = $definition;
-
-        return $this;
     }
 
     /**
      * 获取输入参数定义
-     * @access public
-     * @return InputDefinition
+     * @return InputDefinition The InputDefinition instance
      */
     public function getDefinition()
     {
@@ -266,9 +208,8 @@ class Console
     }
 
     /**
-     * 获取帮助信息
-     * @access public
-     * @return string
+     * Gets the help message.
+     * @return string A help message.
      */
     public function getHelp()
     {
@@ -276,34 +217,27 @@ class Console
     }
 
     /**
-     * 设置是否捕获异常
-     * @access public
-     * @param bool $boolean 是否捕获
-     * @return $this
+     * 是否捕获异常
+     * @param bool $boolean
+     * @api
      */
     public function setCatchExceptions($boolean)
     {
         $this->catchExceptions = (bool) $boolean;
-
-        return $this;
     }
 
     /**
-     * 设置是否自动退出
-     * @access public
-     * @param bool $boolean 是否自动退出
-     * @return $this
+     * 是否自动退出
+     * @param bool $boolean
+     * @api
      */
     public function setAutoExit($boolean)
     {
         $this->autoExit = (bool) $boolean;
-
-        return $this;
     }
 
     /**
      * 获取名称
-     * @access public
      * @return string
      */
     public function getName()
@@ -313,21 +247,17 @@ class Console
 
     /**
      * 设置名称
-     * @access public
-     * @param  string $name 名称
-     * @return $this
+     * @param string $name
      */
     public function setName($name)
     {
         $this->name = $name;
-
-        return $this;
     }
 
     /**
      * 获取版本
-     * @access public
      * @return string
+     * @api
      */
     public function getVersion()
     {
@@ -336,30 +266,21 @@ class Console
 
     /**
      * 设置版本
-     * @access public
-     * @param  string $version 版本信息
-     * @return $this
+     * @param string $version
      */
     public function setVersion($version)
     {
         $this->version = $version;
-
-        return $this;
     }
 
     /**
      * 获取完整的版本号
-     * @access public
      * @return string
      */
     public function getLongVersion()
     {
         if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
-            return sprintf(
-                '<info>%s</info> version <comment>%s</comment>',
-                $this->getName(),
-                $this->getVersion()
-            );
+            return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
         }
 
         return '<info>Console Tool</info>';
@@ -367,8 +288,7 @@ class Console
 
     /**
      * 注册一个指令
-     * @access public
-     * @param string $name 指令名称
+     * @param string $name
      * @return Command
      */
     public function register($name)
@@ -377,37 +297,32 @@ class Console
     }
 
     /**
-     * 批量添加指令
-     * @access public
-     * @param  Command[] $commands 指令实例
-     * @return $this
+     * 添加指令
+     * @param Command[] $commands
      */
     public function addCommands(array $commands)
     {
-        foreach ($commands as $command) $this->add($command);
-
-        return $this;
+        foreach ($commands as $command) {
+            $this->add($command);
+        }
     }
 
     /**
      * 添加一个指令
-     * @access public
-     * @param  Command $command 命令实例
-     * @return Command|bool
+     * @param Command $command
+     * @return Command
      */
     public function add(Command $command)
     {
+        $command->setConsole($this);
+
         if (!$command->isEnabled()) {
             $command->setConsole(null);
-            return false;
+            return;
         }
 
-        $command->setConsole($this);
-
         if (null === $command->getDefinition()) {
-            throw new \LogicException(
-                sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))
-            );
+            throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
         }
 
         $this->commands[$command->getName()] = $command;
@@ -421,17 +336,14 @@ class Console
 
     /**
      * 获取指令
-     * @access public
-     * @param  string $name 指令名称
+     * @param string $name 指令名称
      * @return Command
      * @throws \InvalidArgumentException
      */
     public function get($name)
     {
         if (!isset($this->commands[$name])) {
-            throw new \InvalidArgumentException(
-                sprintf('The command "%s" does not exist.', $name)
-            );
+            throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
         }
 
         $command = $this->commands[$name];
@@ -451,8 +363,7 @@ class Console
 
     /**
      * 某个指令是否存在
-     * @access public
-     * @param  string $name 指令名称
+     * @param string $name 指令名称
      * @return bool
      */
     public function has($name)
@@ -462,22 +373,16 @@ class Console
 
     /**
      * 获取所有的命名空间
-     * @access public
      * @return array
      */
     public function getNamespaces()
     {
         $namespaces = [];
-
         foreach ($this->commands as $command) {
-            $namespaces = array_merge(
-                $namespaces, $this->extractAllNamespaces($command->getName())
-            );
+            $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
 
             foreach ($command->getAliases() as $alias) {
-                $namespaces = array_merge(
-                    $namespaces, $this->extractAllNamespaces($alias)
-                );
+                $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
             }
         }
 
@@ -485,25 +390,21 @@ class Console
     }
 
     /**
-     * 查找注册命名空间中的名称或缩写
-     * @access public
+     * 查找注册命名空间中的名称或缩写。
      * @param string $namespace
      * @return string
      * @throws \InvalidArgumentException
      */
     public function findNamespace($namespace)
     {
-        $expr = preg_replace_callback('{([^:]+|)}', function ($matches) {
+        $allNamespaces = $this->getNamespaces();
+        $expr          = preg_replace_callback('{([^:]+|)}', function ($matches) {
             return preg_quote($matches[1]) . '[^:]*';
         }, $namespace);
-
-        $allNamespaces = $this->getNamespaces();
-        $namespaces    = preg_grep('{^' . $expr . '}', $allNamespaces);
+        $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);
 
         if (empty($namespaces)) {
-            $message = sprintf(
-                'There are no commands defined in the "%s" namespace.', $namespace
-            );
+            $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
 
             if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
                 if (1 == count($alternatives)) {
@@ -519,14 +420,8 @@ class Console
         }
 
         $exact = in_array($namespace, $namespaces, true);
-
         if (count($namespaces) > 1 && !$exact) {
-            throw new \InvalidArgumentException(
-                sprintf(
-                    'The namespace "%s" is ambiguous (%s).',
-                    $namespace,
-                    $this->getAbbreviationSuggestions(array_values($namespaces)))
-            );
+            throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))));
         }
 
         return $exact ? $namespace : reset($namespaces);
@@ -534,22 +429,20 @@ class Console
 
     /**
      * 查找指令
-     * @access public
-     * @param  string $name 名称或者别名
+     * @param string $name 名称或者别名
      * @return Command
      * @throws \InvalidArgumentException
      */
     public function find($name)
     {
-        $expr = preg_replace_callback('{([^:]+|)}', function ($matches) {
+        $allCommands = array_keys($this->commands);
+        $expr        = preg_replace_callback('{([^:]+|)}', function ($matches) {
             return preg_quote($matches[1]) . '[^:]*';
         }, $name);
-
-        $allCommands = array_keys($this->commands);
-        $commands    = preg_grep('{^' . $expr . '}', $allCommands);
+        $commands = preg_grep('{^' . $expr . '}', $allCommands);
 
         if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) {
-            if (false !== ($pos = strrpos($name, ':'))) {
+            if (false !== $pos = strrpos($name, ':')) {
                 $this->findNamespace(substr($name, 0, $pos));
             }
 
@@ -580,9 +473,7 @@ class Console
         if (count($commands) > 1 && !$exact) {
             $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
 
-            throw new \InvalidArgumentException(
-                sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)
-            );
+            throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
         }
 
         return $this->get($exact ? $name : reset($commands));
@@ -590,20 +481,21 @@ class Console
 
     /**
      * 获取所有的指令
-     * @access public
-     * @param  string $namespace 命名空间
+     * @param string $namespace 命名空间
      * @return Command[]
+     * @api
      */
     public function all($namespace = null)
     {
-        if (null === $namespace) return $this->commands;
+        if (null === $namespace) {
+            return $this->commands;
+        }
 
         $commands = [];
-
         foreach ($this->commands as $name => $command) {
-            $ext = $this->extractNamespace($name, substr_count($namespace, ':') + 1);
-
-            if ($ext === $namespace) $commands[$name] = $command;
+            if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) {
+                $commands[$name] = $command;
+            }
         }
 
         return $commands;
@@ -611,8 +503,7 @@ class Console
 
     /**
      * 获取可能的指令名
-     * @access public
-     * @param  array $names 指令名
+     * @param array $names
      * @return array
      */
     public static function getAbbreviations($names)
@@ -629,11 +520,9 @@ class Console
     }
 
     /**
-     * 配置基于用户的参数和选项的输入和输出实例
-     * @access protected
-     * @param  Input  $input  输入实例
-     * @param  Output $output 输出实例
-     * @return void
+     * 配置基于用户的参数和选项的输入和输出实例。
+     * @param Input  $input  输入实例
+     * @param Output $output 输出实例
      */
     protected function configureIO(Input $input, Output $output)
     {
@@ -662,10 +551,9 @@ class Console
 
     /**
      * 执行指令
-     * @access protected
-     * @param  Command $command 指令实例
-     * @param  Input   $input   输入实例
-     * @param  Output  $output  输出实例
+     * @param Command $command 指令实例
+     * @param Input   $input   输入实例
+     * @param Output  $output  输出实例
      * @return int
      * @throws \Exception
      */
@@ -675,9 +563,8 @@ class Console
     }
 
     /**
-     * 获取指令的名称
-     * @access protected
-     * @param  Input $input 输入实例
+     * 获取指令的基础名称
+     * @param Input $input
      * @return string
      */
     protected function getCommandName(Input $input)
@@ -687,7 +574,6 @@ class Console
 
     /**
      * 获取默认输入定义
-     * @access protected
      * @return InputDefinition
      */
     protected function getDefaultInputDefinition()
@@ -705,55 +591,41 @@ class Console
     }
 
     /**
-     * 获取默认命令
-     * @access protected
-     * @return Command[]
+     * 设置默认命令
+     * @return Command[] An array of default Command instances
      */
     protected function getDefaultCommands()
     {
         $defaultCommands = [];
 
-        foreach (self::$defaultCommands as $class) {
-            if (class_exists($class) && is_subclass_of($class, "think\\console\\Command")) {
-                $defaultCommands[] = new $class();
+        foreach (self::$defaultCommands as $classname) {
+            if (class_exists($classname) && is_subclass_of($classname, "think\\console\\Command")) {
+                $defaultCommands[] = new $classname();
             }
         }
 
         return $defaultCommands;
     }
 
-    /**
-     * 添加默认指令
-     * @access public
-     * @param  array $classes 指令
-     * @return void
-     */
-    public static function addDefaultCommands(array $classes)
+    public static function addDefaultCommands(array $classnames)
     {
-        self::$defaultCommands = array_merge(self::$defaultCommands, $classes);
+        self::$defaultCommands = array_merge(self::$defaultCommands, $classnames);
     }
 
     /**
      * 获取可能的建议
-     * @access private
-     * @param  array $abbrevs
+     * @param array $abbrevs
      * @return string
      */
     private function getAbbreviationSuggestions($abbrevs)
     {
-        return sprintf(
-            '%s, %s%s',
-            $abbrevs[0],
-            $abbrevs[1],
-            count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''
-        );
+        return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
     }
 
     /**
-     * 返回指令的命名空间部分
-     * @access public
-     * @param  string $name  指令名称
-     * @param  string $limit 部分的命名空间的最大数量
+     * 返回命名空间部分
+     * @param string $name  指令
+     * @param string $limit 部分的命名空间的最大数量
      * @return string
      */
     public function extractNamespace($name, $limit = null)
@@ -766,17 +638,16 @@ class Console
 
     /**
      * 查找可替代的建议
-     * @access private
-     * @param string             $name       指令名称
-     * @param array|\Traversable $collection 建议集合
+     * @param string             $name
+     * @param array|\Traversable $collection
      * @return array
      */
     private function findAlternatives($name, $collection)
     {
-        $threshold       = 1e3;
-        $alternatives    = [];
-        $collectionParts = [];
+        $threshold    = 1e3;
+        $alternatives = [];
 
+        $collectionParts = [];
         foreach ($collection as $item) {
             $collectionParts[$item] = explode(':', $item);
         }
@@ -784,7 +655,6 @@ class Console
         foreach (explode(':', $name) as $i => $subname) {
             foreach ($collectionParts as $collectionName => $parts) {
                 $exists = isset($alternatives[$collectionName]);
-
                 if (!isset($parts[$i]) && $exists) {
                     $alternatives[$collectionName] += $threshold;
                     continue;
@@ -793,14 +663,8 @@ class Console
                 }
 
                 $lev = levenshtein($subname, $parts[$i]);
-
-                if ($lev <= strlen($subname) / 3 ||
-                    '' !== $subname &&
-                    false !== strpos($parts[$i], $subname)
-                ) {
-                    $alternatives[$collectionName] = $exists ?
-                        $alternatives[$collectionName] + $lev :
-                        $lev;
+                if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
+                    $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
                 } elseif ($exists) {
                     $alternatives[$collectionName] += $threshold;
                 }
@@ -809,18 +673,14 @@ class Console
 
         foreach ($collection as $item) {
             $lev = levenshtein($name, $item);
-
             if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
-                $alternatives[$item] = isset($alternatives[$item]) ?
-                    $alternatives[$item] - $lev :
-                    $lev;
+                $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
             }
         }
 
         $alternatives = array_filter($alternatives, function ($lev) use ($threshold) {
             return $lev < 2 * $threshold;
         });
-
         asort($alternatives);
 
         return array_keys($alternatives);
@@ -828,28 +688,24 @@ class Console
 
     /**
      * 设置默认的指令
-     * @access public
-     * @param string $commandName 指令名称
-     * @return $this
+     * @param string $commandName The Command name
      */
     public function setDefaultCommand($commandName)
     {
         $this->defaultCommand = $commandName;
-
-        return $this;
     }
 
     /**
      * 返回所有的命名空间
-     * @access private
-     * @param  string $name 指令名称
+     * @param string $name
      * @return array
      */
     private function extractAllNamespaces($name)
     {
+        $parts      = explode(':', $name, -1);
         $namespaces = [];
 
-        foreach (explode(':', $name, -1) as $part) {
+        foreach ($parts as $part) {
             if (count($namespaces)) {
                 $namespaces[] = end($namespaces) . ':' . $part;
             } else {

+ 45 - 62
thinkphp/library/think/Controller.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -11,49 +11,46 @@
 
 namespace think;
 
-use think\exception\ValidateException;
-use traits\controller\Jump;
+\think\Loader::import('controller/Jump', TRAIT_PATH, EXT);
 
-Loader::import('controller/Jump', TRAIT_PATH, EXT);
+use think\exception\ValidateException;
 
 class Controller
 {
-    use Jump;
+    use \traits\controller\Jump;
 
     /**
      * @var \think\View 视图类实例
      */
     protected $view;
-
     /**
-     * @var \think\Request Request 实例
+     * @var \think\Request Request实例
      */
     protected $request;
-
-    /**
-     * @var bool 验证失败是否抛出异常
-     */
+    // 验证失败是否抛出异常
     protected $failException = false;
-
-    /**
-     * @var bool 是否批量验证
-     */
+    // 是否批量验证
     protected $batchValidate = false;
 
     /**
-     * @var array 前置操作方法列表
+     * 前置操作方法列表
+     * @var array $beforeActionList
+     * @access protected
      */
     protected $beforeActionList = [];
 
     /**
-     * 构造方法
+     * 架构函数
+     * @param Request $request Request对象
      * @access public
-     * @param Request $request Request 对象
      */
     public function __construct(Request $request = null)
     {
+        if (is_null($request)) {
+            $request = Request::instance();
+        }
         $this->view    = View::instance(Config::get('template'), Config::get('view_replace_str'));
-        $this->request = is_null($request) ? Request::instance() : $request;
+        $this->request = $request;
 
         // 控制器初始化
         $this->_initialize();
@@ -68,10 +65,7 @@ class Controller
         }
     }
 
-    /**
-     * 初始化操作
-     * @access protected
-     */
+    // 初始化
     protected function _initialize()
     {
     }
@@ -79,9 +73,8 @@ class Controller
     /**
      * 前置操作
      * @access protected
-     * @param  string $method  前置操作方法名
-     * @param  array  $options 调用参数 ['only'=>[...]] 或者 ['except'=>[...]]
-     * @return void
+     * @param string $method  前置操作方法名
+     * @param array  $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
      */
     protected function beforeAction($method, $options = [])
     {
@@ -89,7 +82,6 @@ class Controller
             if (is_string($options['only'])) {
                 $options['only'] = explode(',', $options['only']);
             }
-
             if (!in_array($this->request->action(), $options['only'])) {
                 return;
             }
@@ -97,7 +89,6 @@ class Controller
             if (is_string($options['except'])) {
                 $options['except'] = explode(',', $options['except']);
             }
-
             if (in_array($this->request->action(), $options['except'])) {
                 return;
             }
@@ -109,10 +100,10 @@ class Controller
     /**
      * 加载模板输出
      * @access protected
-     * @param  string $template 模板文件名
-     * @param  array  $vars     模板输出变量
-     * @param  array  $replace  模板替换
-     * @param  array  $config   模板参数
+     * @param string $template 模板文件名
+     * @param array  $vars     模板输出变量
+     * @param array  $replace  模板替换
+     * @param array  $config   模板参数
      * @return mixed
      */
     protected function fetch($template = '', $vars = [], $replace = [], $config = [])
@@ -123,10 +114,10 @@ class Controller
     /**
      * 渲染内容输出
      * @access protected
-     * @param  string $content 模板内容
-     * @param  array  $vars    模板输出变量
-     * @param  array  $replace 替换内容
-     * @param  array  $config  模板参数
+     * @param string $content 模板内容
+     * @param array  $vars    模板输出变量
+     * @param array  $replace 替换内容
+     * @param array  $config  模板参数
      * @return mixed
      */
     protected function display($content = '', $vars = [], $replace = [], $config = [])
@@ -137,28 +128,24 @@ class Controller
     /**
      * 模板变量赋值
      * @access protected
-     * @param  mixed $name  要显示的模板变量
-     * @param  mixed $value 变量的值
-     * @return $this
+     * @param mixed $name  要显示的模板变量
+     * @param mixed $value 变量的值
+     * @return void
      */
     protected function assign($name, $value = '')
     {
         $this->view->assign($name, $value);
-
-        return $this;
     }
 
     /**
      * 初始化模板引擎
      * @access protected
      * @param array|string $engine 引擎参数
-     * @return $this
+     * @return void
      */
     protected function engine($engine)
     {
         $this->view->engine($engine);
-
-        return $this;
     }
 
     /**
@@ -170,18 +157,17 @@ class Controller
     protected function validateFailException($fail = true)
     {
         $this->failException = $fail;
-
         return $this;
     }
 
     /**
      * 验证数据
      * @access protected
-     * @param  array        $data     数据
-     * @param  string|array $validate 验证器名或者验证规则数组
-     * @param  array        $message  提示信息
-     * @param  bool         $batch    是否批量验证
-     * @param  mixed        $callback 回调方法(闭包)
+     * @param array        $data     数据
+     * @param string|array $validate 验证器名或者验证规则数组
+     * @param array        $message  提示信息
+     * @param bool         $batch    是否批量验证
+     * @param mixed        $callback 回调方法(闭包)
      * @return array|string|true
      * @throws ValidateException
      */
@@ -191,27 +177,24 @@ class Controller
             $v = Loader::validate();
             $v->rule($validate);
         } else {
-            // 支持场景
             if (strpos($validate, '.')) {
+                // 支持场景
                 list($validate, $scene) = explode('.', $validate);
             }
-
             $v = Loader::validate($validate);
-
-            !empty($scene) && $v->scene($scene);
+            if (!empty($scene)) {
+                $v->scene($scene);
+            }
         }
-
-        // 批量验证
+        // 是否批量验证
         if ($batch || $this->batchValidate) {
             $v->batch(true);
         }
 
-        // 设置错误信息
         if (is_array($message)) {
             $v->message($message);
         }
 
-        // 使用回调验证
         if ($callback && is_callable($callback)) {
             call_user_func_array($callback, [$v, &$data]);
         }
@@ -219,11 +202,11 @@ class Controller
         if (!$v->check($data)) {
             if ($this->failException) {
                 throw new ValidateException($v->getError());
+            } else {
+                return $v->getError();
             }
-
-            return $v->getError();
+        } else {
+            return true;
         }
-
-        return true;
     }
 }

+ 66 - 123
thinkphp/library/think/Cookie.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -13,28 +13,28 @@ namespace think;
 
 class Cookie
 {
-    /**
-     * @var array cookie 设置参数
-     */
     protected static $config = [
-        'prefix'    => '', // cookie 名称前缀
-        'expire'    => 0, // cookie 保存时间
-        'path'      => '/', // cookie 保存路径
-        'domain'    => '', // cookie 有效域名
-        'secure'    => false, //  cookie 启用安全传输
-        'httponly'  => false, // httponly 设置
-        'setcookie' => true, // 是否使用 setcookie
+        // cookie 名称前缀
+        'prefix'    => '',
+        // cookie 保存时间
+        'expire'    => 0,
+        // cookie 保存路径
+        'path'      => '/',
+        // cookie 有效域名
+        'domain'    => '',
+        //  cookie 启用安全传输
+        'secure'    => false,
+        // httponly设置
+        'httponly'  => '',
+        // 是否使用 setcookie
+        'setcookie' => true,
     ];
 
-    /**
-     * @var bool 是否完成初始化了
-     */
     protected static $init;
 
     /**
      * Cookie初始化
-     * @access public
-     * @param  array $config 配置参数
+     * @param array $config
      * @return void
      */
     public static function init(array $config = [])
@@ -42,43 +42,39 @@ class Cookie
         if (empty($config)) {
             $config = Config::get('cookie');
         }
-
         self::$config = array_merge(self::$config, array_change_key_case($config));
-
         if (!empty(self::$config['httponly'])) {
             ini_set('session.cookie_httponly', 1);
         }
-
         self::$init = true;
     }
 
     /**
-     * 设置或者获取 cookie 作用域(前缀)
-     * @access public
-     * @param  string $prefix 前缀
-     * @return string|
+     * 设置或者获取cookie作用域(前缀)
+     * @param string $prefix
+     * @return string|void
      */
     public static function prefix($prefix = '')
     {
         if (empty($prefix)) {
             return self::$config['prefix'];
         }
-
-        return self::$config['prefix'] = $prefix;
+        self::$config['prefix'] = $prefix;
     }
 
     /**
      * Cookie 设置、获取、删除
-     * @access public
-     * @param  string $name   cookie 名称
-     * @param  mixed  $value  cookie 值
-     * @param  mixed  $option 可选参数 可能会是 null|integer|string
-     * @return void
+     *
+     * @param string $name  cookie名称
+     * @param mixed  $value cookie值
+     * @param mixed  $option 可选参数 可能会是 null|integer|string
+     *
+     * @return mixed
+     * @internal param mixed $options cookie参数
      */
     public static function set($name, $value = '', $option = null)
     {
         !isset(self::$init) && self::init();
-
         // 参数设置(会覆盖黙认设置)
         if (!is_null($option)) {
             if (is_numeric($option)) {
@@ -86,40 +82,28 @@ class Cookie
             } elseif (is_string($option)) {
                 parse_str($option, $option);
             }
-
             $config = array_merge(self::$config, array_change_key_case($option));
         } else {
             $config = self::$config;
         }
-
         $name = $config['prefix'] . $name;
-
-        // 设置 cookie
+        // 设置cookie
         if (is_array($value)) {
             array_walk_recursive($value, 'self::jsonFormatProtect', 'encode');
             $value = 'think:' . json_encode($value);
         }
-
-        $expire = !empty($config['expire']) ?
-        $_SERVER['REQUEST_TIME'] + intval($config['expire']) :
-        0;
-
+        $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;
         if ($config['setcookie']) {
-            setcookie(
-                $name, $value, $expire, $config['path'], $config['domain'],
-                $config['secure'], $config['httponly']
-            );
+            setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
         }
-
         $_COOKIE[$name] = $value;
     }
 
     /**
-     * 永久保存 Cookie 数据
-     * @access public
-     * @param  string $name   cookie 名称
-     * @param  mixed  $value  cookie 值
-     * @param  mixed  $option 可选参数 可能会是 null|integer|string
+     * 永久保存Cookie数据
+     * @param string $name  cookie名称
+     * @param mixed  $value cookie值
+     * @param mixed  $option 可选参数 可能会是 null|integer|string
      * @return void
      */
     public static function forever($name, $value = '', $option = null)
@@ -127,142 +111,101 @@ class Cookie
         if (is_null($option) || is_numeric($option)) {
             $option = [];
         }
-
         $option['expire'] = 315360000;
-
         self::set($name, $value, $option);
     }
 
     /**
-     * 判断是否有 Cookie 数据
-     * @access public
-     * @param  string      $name   cookie 名称
-     * @param  string|null $prefix cookie 前缀
+     * 判断Cookie数据
+     * @param string        $name cookie名称
+     * @param string|null   $prefix cookie前缀
      * @return bool
      */
     public static function has($name, $prefix = null)
     {
         !isset(self::$init) && self::init();
-
         $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];
-
-        return isset($_COOKIE[$prefix . $name]);
+        $name   = $prefix . $name;
+        return isset($_COOKIE[$name]);
     }
 
     /**
-     * 获取 Cookie 的值
-     * @access public
-     * @param string      $name   cookie 名称
-     * @param string|null $prefix cookie 前缀
+     * Cookie获取
+     * @param string        $name cookie名称
+     * @param string|null   $prefix cookie前缀
      * @return mixed
      */
-    public static function get($name = '', $prefix = null)
+    public static function get($name, $prefix = null)
     {
         !isset(self::$init) && self::init();
-
         $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];
-        $key    = $prefix . $name;
-
-        if ('' == $name) {
-            // 获取全部
-            if ($prefix) {
-                $value = [];
-
-                foreach ($_COOKIE as $k => $val) {
-                    if (0 === strpos($k, $prefix)) {
-                        $value[$k] = $val;
-                    }
-
-                }
-            } else {
-                $value = $_COOKIE;
-            }
-        } elseif (isset($_COOKIE[$key])) {
-            $value = $_COOKIE[$key];
-
+        $name   = $prefix . $name;
+        if (isset($_COOKIE[$name])) {
+            $value = $_COOKIE[$name];
             if (0 === strpos($value, 'think:')) {
-                $value = json_decode(substr($value, 6), true);
+                $value = substr($value, 6);
+                $value = json_decode($value, true);
                 array_walk_recursive($value, 'self::jsonFormatProtect', 'decode');
             }
+            return $value;
         } else {
-            $value = null;
+            return;
         }
-
-        return $value;
     }
 
     /**
-     * 删除 Cookie
-     * @access public
-     * @param  string      $name   cookie 名称
-     * @param  string|null $prefix cookie 前缀
-     * @return void
+     * Cookie删除
+     * @param string        $name cookie名称
+     * @param string|null   $prefix cookie前缀
+     * @return mixed
      */
     public static function delete($name, $prefix = null)
     {
         !isset(self::$init) && self::init();
-
         $config = self::$config;
         $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
         $name   = $prefix . $name;
-
         if ($config['setcookie']) {
-            setcookie(
-                $name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'],
-                $config['domain'], $config['secure'], $config['httponly']
-            );
+            setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
         }
-
-        // 删除指定 cookie
+        // 删除指定cookie
         unset($_COOKIE[$name]);
     }
 
     /**
-     * 清除指定前缀的所有 cookie
-     * @access public
-     * @param  string|null $prefix cookie 前缀
-     * @return void
+     * Cookie清空
+     * @param string|null $prefix cookie前缀
+     * @return mixed
      */
     public static function clear($prefix = null)
     {
+        // 清除指定前缀的所有cookie
         if (empty($_COOKIE)) {
             return;
         }
-
         !isset(self::$init) && self::init();
-
-        // 要删除的 cookie 前缀,不指定则删除 config 设置的指定前缀
+        // 要删除的cookie前缀,不指定则删除config设置的指定前缀
         $config = self::$config;
         $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
-
         if ($prefix) {
+            // 如果前缀为空字符串将不作处理直接返回
             foreach ($_COOKIE as $key => $val) {
                 if (0 === strpos($key, $prefix)) {
                     if ($config['setcookie']) {
-                        setcookie(
-                            $key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'],
-                            $config['domain'], $config['secure'], $config['httponly']
-                        );
+                        setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);
                     }
-
                     unset($_COOKIE[$key]);
                 }
             }
         }
+        return;
     }
 
-    /**
-     * json 转换时的格式保护
-     * @access protected
-     * @param  mixed  $val  要转换的值
-     * @param  string $key  键名
-     * @param  string $type 转换类别
-     * @return void
-     */
-    protected static function jsonFormatProtect(&$val, $key, $type = 'encode')
+    private static function jsonFormatProtect(&$val, $key, $type = 'encode')
     {
         if (!empty($val) && true !== $val) {
             $val = 'decode' == $type ? urldecode($val) : urlencode($val);
         }
     }
+
 }

+ 28 - 57
thinkphp/library/think/Db.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -36,7 +36,7 @@ use think\db\Query;
  * @method integer update(array $data) static 更新记录
  * @method integer delete(mixed $data = null) static 删除记录
  * @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据
- * @method mixed query(string $sql, array $bind = [], boolean $master = false, bool $pdo = false) static SQL查询
+ * @method mixed query(string $sql, array $bind = [], boolean $fetch = false, boolean $master = false, mixed $class = null) static SQL查询
  * @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行
  * @method Paginator paginate(integer $listRows = 15, mixed $simple = null, array $config = []) static 分页查询
  * @method mixed transaction(callable $callback) static 执行数据库事务
@@ -44,31 +44,22 @@ use think\db\Query;
  * @method void commit() static 用于非自动提交状态下面的查询提交
  * @method void rollback() static 事务回滚
  * @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句
- * @method string quote(string $str) static SQL指令安全过滤
- * @method string getLastInsID($sequence = null) static 获取最近插入的ID
  */
 class Db
 {
-    /**
-     * @var Connection[] 数据库连接实例
-     */
+    //  数据库连接实例
     private static $instance = [];
-
-    /**
-     * @var int 查询次数
-     */
+    // 查询次数
     public static $queryTimes = 0;
-
-    /**
-     * @var int 执行次数
-     */
+    // 执行次数
     public static $executeTimes = 0;
 
     /**
-     * 数据库初始化,并取得数据库类实例
+     * 数据库初始化 并取得数据库类实例
+     * @static
      * @access public
-     * @param  mixed       $config 连接配置
-     * @param  bool|string $name   连接标识 true 强制重新连接
+     * @param mixed         $config 连接配置
+     * @param bool|string   $name 连接标识 true 强制重新连接
      * @return Connection
      * @throws Exception
      */
@@ -77,48 +68,31 @@ class Db
         if (false === $name) {
             $name = md5(serialize($config));
         }
-
         if (true === $name || !isset(self::$instance[$name])) {
             // 解析连接参数 支持数组和字符串
             $options = self::parseConfig($config);
-
             if (empty($options['type'])) {
-                throw new \InvalidArgumentException('Undefined db type');
+                throw new \InvalidArgumentException('Underfined db type');
             }
-
-            $class = false !== strpos($options['type'], '\\') ?
-            $options['type'] :
-            '\\think\\db\\connector\\' . ucwords($options['type']);
-
+            $class = false !== strpos($options['type'], '\\') ? $options['type'] : '\\think\\db\\connector\\' . ucwords($options['type']);
             // 记录初始化信息
             if (App::$debug) {
                 Log::record('[ DB ] INIT ' . $options['type'], 'info');
             }
-
             if (true === $name) {
-                $name = md5(serialize($config));
+                return new $class($options);
+            } else {
+                self::$instance[$name] = new $class($options);
             }
-
-            self::$instance[$name] = new $class($options);
         }
-
         return self::$instance[$name];
     }
 
-    /**
-     * 清除连接实例
-     * @access public
-     * @return void
-     */
-    public static function clear()
-    {
-        self::$instance = [];
-    }
-
     /**
      * 数据库连接参数解析
+     * @static
      * @access private
-     * @param  mixed $config 连接参数
+     * @param mixed $config
      * @return array
      */
     private static function parseConfig($config)
@@ -126,27 +100,30 @@ class Db
         if (empty($config)) {
             $config = Config::get('database');
         } elseif (is_string($config) && false === strpos($config, '/')) {
-            $config = Config::get($config); // 支持读取配置参数
+            // 支持读取配置参数
+            $config = Config::get($config);
+        }
+        if (is_string($config)) {
+            return self::parseDsn($config);
+        } else {
+            return $config;
         }
-
-        return is_string($config) ? self::parseDsn($config) : $config;
     }
 
     /**
-     * DSN 解析
+     * DSN解析
      * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8
+     * @static
      * @access private
-     * @param  string $dsnStr 数据库 DSN 字符串解析
+     * @param string $dsnStr
      * @return array
      */
     private static function parseDsn($dsnStr)
     {
         $info = parse_url($dsnStr);
-
         if (!$info) {
             return [];
         }
-
         $dsn = [
             'type'     => $info['scheme'],
             'username' => isset($info['user']) ? $info['user'] : '',
@@ -162,19 +139,13 @@ class Db
         } else {
             $dsn['params'] = [];
         }
-
         return $dsn;
     }
 
-    /**
-     * 调用驱动类的方法
-     * @access public
-     * @param  string $method 方法名
-     * @param  array  $params 参数
-     * @return mixed
-     */
+    // 调用驱动类的方法
     public static function __callStatic($method, $params)
     {
+        // 自动初始化数据库
         return call_user_func_array([self::connect(), $method], $params);
     }
 }

+ 46 - 86
thinkphp/library/think/Debug.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -16,27 +16,21 @@ use think\response\Redirect;
 
 class Debug
 {
-    /**
-     * @var array 区间时间信息
-     */
+    // 区间时间信息
     protected static $info = [];
-
-    /**
-     * @var array 区间内存信息
-     */
+    // 区间内存信息
     protected static $mem = [];
 
     /**
      * 记录时间(微秒)和内存使用情况
-     * @access public
-     * @param  string $name  标记位置
-     * @param  mixed  $value 标记值(留空则取当前 time 表示仅记录时间 否则同时记录时间和内存)
-     * @return void
+     * @param string    $name 标记位置
+     * @param mixed     $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存
+     * @return mixed
      */
     public static function remark($name, $value = '')
     {
+        // 记录时间和内存使用
         self::$info[$name] = is_float($value) ? $value : microtime(true);
-
         if ('time' != $value) {
             self::$mem['mem'][$name]  = is_float($value) ? $value : memory_get_usage();
             self::$mem['peak'][$name] = memory_get_peak_usage();
@@ -44,27 +38,24 @@ class Debug
     }
 
     /**
-     * 统计某个区间的时间(微秒)使用情况 返回值以秒为单位
-     * @access public
-     * @param  string  $start 开始标签
-     * @param  string  $end   结束标签
-     * @param  integer $dec   小数位
-     * @return string
+     * 统计某个区间的时间(微秒)使用情况
+     * @param string            $start 开始标签
+     * @param string            $end 结束标签
+     * @param integer|string    $dec 小数位
+     * @return integer
      */
     public static function getRangeTime($start, $end, $dec = 6)
     {
         if (!isset(self::$info[$end])) {
             self::$info[$end] = microtime(true);
         }
-
         return number_format((self::$info[$end] - self::$info[$start]), $dec);
     }
 
     /**
-     * 统计从开始到统计时的时间(微秒)使用情况 返回值以秒为单位
-     * @access public
-     * @param  integer $dec 小数位
-     * @return string
+     * 统计从开始到统计时的时间(微秒)使用情况
+     * @param integer|string $dec 小数位
+     * @return integer
      */
     public static function getUseTime($dec = 6)
     {
@@ -73,7 +64,6 @@ class Debug
 
     /**
      * 获取当前访问的吞吐率情况
-     * @access public
      * @return string
      */
     public static function getThroughputRate()
@@ -83,10 +73,9 @@ class Debug
 
     /**
      * 记录区间的内存使用情况
-     * @access public
-     * @param  string  $start 开始标签
-     * @param  string  $end   结束标签
-     * @param  integer $dec   小数位
+     * @param string            $start 开始标签
+     * @param string            $end 结束标签
+     * @param integer|string    $dec 小数位
      * @return string
      */
     public static function getRangeMem($start, $end, $dec = 2)
@@ -94,23 +83,19 @@ class Debug
         if (!isset(self::$mem['mem'][$end])) {
             self::$mem['mem'][$end] = memory_get_usage();
         }
-
         $size = self::$mem['mem'][$end] - self::$mem['mem'][$start];
         $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
         $pos  = 0;
-
         while ($size >= 1024) {
             $size /= 1024;
             $pos++;
         }
-
         return round($size, $dec) . " " . $a[$pos];
     }
 
     /**
      * 统计从开始到统计时的内存使用情况
-     * @access public
-     * @param  integer $dec 小数位
+     * @param integer|string $dec 小数位
      * @return string
      */
     public static function getUseMem($dec = 2)
@@ -118,128 +103,103 @@ class Debug
         $size = memory_get_usage() - THINK_START_MEM;
         $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
         $pos  = 0;
-
         while ($size >= 1024) {
             $size /= 1024;
             $pos++;
         }
-
         return round($size, $dec) . " " . $a[$pos];
     }
 
     /**
      * 统计区间的内存峰值情况
-     * @access public
-     * @param  string  $start 开始标签
-     * @param  string  $end   结束标签
-     * @param  integer $dec   小数位
-     * @return string
+     * @param string            $start 开始标签
+     * @param string            $end 结束标签
+     * @param integer|string    $dec 小数位
+     * @return mixed
      */
     public static function getMemPeak($start, $end, $dec = 2)
     {
         if (!isset(self::$mem['peak'][$end])) {
             self::$mem['peak'][$end] = memory_get_peak_usage();
         }
-
         $size = self::$mem['peak'][$end] - self::$mem['peak'][$start];
         $a    = ['B', 'KB', 'MB', 'GB', 'TB'];
         $pos  = 0;
-
         while ($size >= 1024) {
             $size /= 1024;
             $pos++;
         }
-
         return round($size, $dec) . " " . $a[$pos];
     }
 
     /**
      * 获取文件加载信息
-     * @access public
-     * @param  bool $detail 是否显示详细
+     * @param bool  $detail 是否显示详细
      * @return integer|array
      */
     public static function getFile($detail = false)
     {
-        $files = get_included_files();
-
         if ($detail) {
-            $info = [];
-
-            foreach ($files as $file) {
+            $files = get_included_files();
+            $info  = [];
+            foreach ($files as $key => $file) {
                 $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )';
             }
-
             return $info;
         }
-
-        return count($files);
+        return count(get_included_files());
     }
 
     /**
      * 浏览器友好的变量输出
-     * @access public
-     * @param  mixed       $var   变量
-     * @param  boolean     $echo  是否输出(默认为 true,为 false 则返回输出字符串)
-     * @param  string|null $label 标签(默认为空)
-     * @param  integer     $flags htmlspecialchars 的标志
-     * @return null|string
+     * @param mixed         $var 变量
+     * @param boolean       $echo 是否输出 默认为true 如果为false 则返回输出字符串
+     * @param string        $label 标签 默认为空
+     * @param integer       $flags htmlspecialchars flags
+     * @return void|string
      */
     public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE)
     {
         $label = (null === $label) ? '' : rtrim($label) . ':';
-
         ob_start();
         var_dump($var);
-        $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', ob_get_clean());
-
+        $output = ob_get_clean();
+        $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
         if (IS_CLI) {
             $output = PHP_EOL . $label . $output . PHP_EOL;
         } else {
             if (!extension_loaded('xdebug')) {
                 $output = htmlspecialchars($output, $flags);
             }
-
             $output = '<pre>' . $label . $output . '</pre>';
         }
-
         if ($echo) {
             echo($output);
             return;
+        } else {
+            return $output;
         }
-
-        return $output;
     }
 
-    /**
-     * 调试信息注入到响应中
-     * @access public
-     * @param  Response $response 响应实例
-     * @param  string   $content  返回的字符串
-     * @return void
-     */
     public static function inject(Response $response, &$content)
     {
-        $config = Config::get('trace');
-        $type   = isset($config['type']) ? $config['type'] : 'Html';
-        $class  = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type);
-
+        $config  = Config::get('trace');
+        $type    = isset($config['type']) ? $config['type'] : 'Html';
+        $request = Request::instance();
+        $class   = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type);
         unset($config['type']);
-
-        if (!class_exists($class)) {
+        if (class_exists($class)) {
+            $trace = new $class($config);
+        } else {
             throw new ClassNotFoundException('class not exists:' . $class, $class);
         }
 
-        /** @var \think\debug\Console|\think\debug\Html $trace */
-        $trace = new $class($config);
-
         if ($response instanceof Redirect) {
-            // TODO 记录
+            //TODO 记录
         } else {
             $output = $trace->output($response, Log::getLog());
-
             if (is_string($output)) {
-                // trace 调试信息注入
+                // trace调试信息注入
                 $pos = strripos($content, '</body>');
                 if (false !== $pos) {
                     $content = substr($content, 0, $pos) . $output . substr($content, $pos);

+ 5 - 13
thinkphp/library/think/Env.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -15,25 +15,17 @@ class Env
 {
     /**
      * 获取环境变量值
-     * @access public
-     * @param  string $name    环境变量名(支持二级 . 号分割)
-     * @param  string $default 默认值
+     * @param string    $name 环境变量名(支持二级 .号分割)
+     * @param string    $default  默认值
      * @return mixed
      */
     public static function get($name, $default = null)
     {
         $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name)));
-
         if (false !== $result) {
-            if ('false' === $result) {
-                $result = false;
-            } elseif ('true' === $result) {
-                $result = true;
-            }
-
             return $result;
+        } else {
+            return $default;
         }
-
-        return $default;
     }
 }

+ 28 - 47
thinkphp/library/think/Error.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -20,7 +20,6 @@ class Error
 {
     /**
      * 注册异常处理
-     * @access public
      * @return void
      */
     public static function register()
@@ -32,10 +31,8 @@ class Error
     }
 
     /**
-     * 异常处理
-     * @access public
-     * @param  \Exception|\Throwable $e 异常
-     * @return void
+     * Exception Handler
+     * @param  \Exception|\Throwable $e
      */
     public static function appException($e)
     {
@@ -43,50 +40,44 @@ class Error
             $e = new ThrowableError($e);
         }
 
-        $handler = self::getExceptionHandler();
-        $handler->report($e);
-
+        self::getExceptionHandler()->report($e);
         if (IS_CLI) {
-            $handler->renderForConsole(new ConsoleOutput, $e);
+            self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
         } else {
-            $handler->render($e)->send();
+            self::getExceptionHandler()->render($e)->send();
         }
     }
 
     /**
-     * 错误处理
-     * @access public
-     * @param  integer $errno      错误编号
-     * @param  integer $errstr     详细错误信息
-     * @param  string  $errfile    出错的文件
-     * @param  integer $errline    出错行号
-     * @return void
+     * Error Handler
+     * @param  integer $errno   错误编号
+     * @param  integer $errstr  详细错误信息
+     * @param  string  $errfile 出错的文件
+     * @param  integer $errline 出错行号
+     * @param array    $errcontext
      * @throws ErrorException
      */
-    public static function appError($errno, $errstr, $errfile = '', $errline = 0)
+    public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])
     {
-        $exception = new ErrorException($errno, $errstr, $errfile, $errline);
-
-        // 符合异常处理的则将错误信息托管至 think\exception\ErrorException
+        $exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext);
         if (error_reporting() & $errno) {
+            // 将错误信息托管至 think\exception\ErrorException
             throw $exception;
+        } else {
+            self::getExceptionHandler()->report($exception);
         }
-
-        self::getExceptionHandler()->report($exception);
     }
 
     /**
-     * 异常中止处理
-     * @access public
-     * @return void
+     * Shutdown Handler
      */
     public static function appShutdown()
     {
-        // 将错误信息托管至 think\ErrorException
         if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
-            self::appException(new ErrorException(
-                $error['type'], $error['message'], $error['file'], $error['line']
-            ));
+            // 将错误信息托管至think\ErrorException
+            $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']);
+
+            self::appException($exception);
         }
 
         // 写入日志
@@ -95,8 +86,8 @@ class Error
 
     /**
      * 确定错误类型是否致命
-     * @access protected
-     * @param  int $type 错误类型
+     *
+     * @param  int $type
      * @return bool
      */
     protected static function isFatal($type)
@@ -105,32 +96,22 @@ class Error
     }
 
     /**
-     * 获取异常处理的实例
-     * @access public
+     * Get an instance of the exception handler.
+     *
      * @return Handle
      */
     public static function getExceptionHandler()
     {
         static $handle;
-
         if (!$handle) {
-            // 异常处理 handle
+            // 异常处理handle
             $class = Config::get('exception_handle');
-
-            if ($class && is_string($class) && class_exists($class) &&
-                is_subclass_of($class, "\\think\\exception\\Handle")
-            ) {
+            if ($class && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) {
                 $handle = new $class;
             } else {
                 $handle = new Handle;
-
-                if ($class instanceof \Closure) {
-                    $handle->setRender($class);
-                }
-
             }
         }
-
         return $handle;
     }
 }

+ 10 - 11
thinkphp/library/think/Exception.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -13,13 +13,15 @@ namespace think;
 
 class Exception extends \Exception
 {
+
     /**
-     * @var array 保存异常页面显示的额外 Debug 数据
+     * 保存异常页面显示的额外Debug数据
+     * @var array
      */
     protected $data = [];
 
     /**
-     * 设置异常额外的 Debug 数据
+     * 设置异常额外的Debug数据
      * 数据将会显示为下面的格式
      *
      * Exception Data
@@ -31,10 +33,8 @@ class Exception extends \Exception
      *   key1      value1
      *   key2      value2
      *
-     * @access protected
-     * @param  string $label 数据分类,用于异常页面显示
-     * @param  array  $data  需要显示的数据,必须为关联数组
-     * @return void
+     * @param string $label 数据分类,用于异常页面显示
+     * @param array  $data  需要显示的数据,必须为关联数组
      */
     final protected function setData($label, array $data)
     {
@@ -42,14 +42,13 @@ class Exception extends \Exception
     }
 
     /**
-     * 获取异常额外 Debug 数据
+     * 获取异常额外Debug数据
      * 主要用于输出到异常页面便于调试
-     * @access public
-     * @return array
+     * @return array 由setData设置的Debug数据
      */
     final public function getData()
     {
         return $this->data;
     }
-
+    
 }

+ 88 - 155
thinkphp/library/think/File.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -11,56 +11,31 @@
 
 namespace think;
 
+use SplFileInfo;
 use SplFileObject;
 
 class File extends SplFileObject
 {
     /**
-     * @var string 错误信息
+     * 错误信息
+     * @var string
      */
     private $error = '';
-
-    /**
-     * @var string 当前完整文件名
-     */
+    // 当前完整文件名
     protected $filename;
-
-    /**
-     * @var string 上传文件名
-     */
+    // 上传文件名
     protected $saveName;
-
-    /**
-     * @var string 文件上传命名规则
-     */
+    // 文件上传命名规则
     protected $rule = 'date';
-
-    /**
-     * @var array 文件上传验证规则
-     */
+    // 文件上传验证规则
     protected $validate = [];
-
-    /**
-     * @var bool 单元测试
-     */
+    // 单元测试
     protected $isTest;
-
-    /**
-     * @var array 上传文件信息
-     */
+    // 上传文件信息
     protected $info;
-
-    /**
-     * @var array 文件 hash 信息
-     */
+    // 文件hash信息
     protected $hash = [];
 
-    /**
-     * File constructor.
-     * @access public
-     * @param  string $filename 文件名称
-     * @param  string $mode     访问模式
-     */
     public function __construct($filename, $mode = 'r')
     {
         parent::__construct($filename, $mode);
@@ -68,35 +43,30 @@ class File extends SplFileObject
     }
 
     /**
-     * 设置是否是单元测试
-     * @access public
-     * @param  bool $test 是否是测试
+     * 是否测试
+     * @param  bool   $test 是否测试
      * @return $this
      */
     public function isTest($test = false)
     {
         $this->isTest = $test;
-
         return $this;
     }
 
     /**
      * 设置上传信息
-     * @access public
-     * @param  array $info 上传文件信息
+     * @param  array   $info 上传文件信息
      * @return $this
      */
     public function setUploadInfo($info)
     {
         $this->info = $info;
-
         return $this;
     }
 
     /**
      * 获取上传文件的信息
-     * @access public
-     * @param  string $name 信息名称
+     * @param  string   $name
      * @return array|string
      */
     public function getInfo($name = '')
@@ -106,7 +76,6 @@ class File extends SplFileObject
 
     /**
      * 获取上传文件的文件名
-     * @access public
      * @return string
      */
     public function getSaveName()
@@ -116,101 +85,93 @@ class File extends SplFileObject
 
     /**
      * 设置上传文件的保存文件名
-     * @access public
-     * @param  string $saveName 保存名称
+     * @param  string   $saveName
      * @return $this
      */
     public function setSaveName($saveName)
     {
         $this->saveName = $saveName;
-
         return $this;
     }
 
     /**
      * 获取文件的哈希散列值
-     * @access public
-     * @param  string $type 类型
-     * @return string
+     * @return $string
      */
     public function hash($type = 'sha1')
     {
         if (!isset($this->hash[$type])) {
             $this->hash[$type] = hash_file($type, $this->filename);
         }
-
         return $this->hash[$type];
     }
 
     /**
      * 检查目录是否可写
-     * @access protected
-     * @param  string $path 目录
+     * @param  string   $path    目录
      * @return boolean
      */
     protected function checkPath($path)
     {
-        if (is_dir($path) || mkdir($path, 0755, true)) {
+        if (is_dir($path)) {
             return true;
         }
 
-        $this->error = ['directory {:path} creation failed', ['path' => $path]];
-
-        return false;
+        if (mkdir($path, 0755, true)) {
+            return true;
+        } else {
+            $this->error = "目录 {$path} 创建失败!";
+            return false;
+        }
     }
 
     /**
      * 获取文件类型信息
-     * @access public
      * @return string
      */
     public function getMime()
     {
         $finfo = finfo_open(FILEINFO_MIME_TYPE);
-
         return finfo_file($finfo, $this->filename);
     }
 
     /**
      * 设置文件的命名规则
-     * @access public
-     * @param  string $rule 文件命名规则
+     * @param  string   $rule    文件命名规则
      * @return $this
      */
     public function rule($rule)
     {
         $this->rule = $rule;
-
         return $this;
     }
 
     /**
      * 设置上传文件的验证规则
-     * @access public
-     * @param  array $rule 验证规则
+     * @param  array   $rule    验证规则
      * @return $this
      */
-    public function validate(array $rule = [])
+    public function validate($rule = [])
     {
         $this->validate = $rule;
-
         return $this;
     }
 
     /**
      * 检测是否合法的上传文件
-     * @access public
      * @return bool
      */
     public function isValid()
     {
-        return $this->isTest ? is_file($this->filename) : is_uploaded_file($this->filename);
+        if ($this->isTest) {
+            return is_file($this->filename);
+        }
+        return is_uploaded_file($this->filename);
     }
 
     /**
      * 检测上传文件
-     * @access public
-     * @param  array $rule 验证规则
+     * @param  array   $rule    验证规则
      * @return bool
      */
     public function check($rule = [])
@@ -219,25 +180,25 @@ class File extends SplFileObject
 
         /* 检查文件大小 */
         if (isset($rule['size']) && !$this->checkSize($rule['size'])) {
-            $this->error = 'filesize not match';
+            $this->error = '上传文件大小不符!';
             return false;
         }
 
-        /* 检查文件 Mime 类型 */
+        /* 检查文件Mime类型 */
         if (isset($rule['type']) && !$this->checkMime($rule['type'])) {
-            $this->error = 'mimetype to upload is not allowed';
+            $this->error = '上传文件MIME类型不允许!';
             return false;
         }
 
         /* 检查文件后缀 */
         if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) {
-            $this->error = 'extensions to upload is not allowed';
+            $this->error = '上传文件后缀不允许';
             return false;
         }
 
         /* 检查图像文件 */
         if (!$this->checkImg()) {
-            $this->error = 'illegal image files';
+            $this->error = '非法图像文件!';
             return false;
         }
 
@@ -246,8 +207,7 @@ class File extends SplFileObject
 
     /**
      * 检测上传文件后缀
-     * @access public
-     * @param  array|string $ext 允许后缀
+     * @param  array|string   $ext    允许后缀
      * @return bool
      */
     public function checkExt($ext)
@@ -255,76 +215,73 @@ class File extends SplFileObject
         if (is_string($ext)) {
             $ext = explode(',', $ext);
         }
-
         $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
-
-        return in_array($extension, $ext);
+        if (!in_array($extension, $ext)) {
+            return false;
+        }
+        return true;
     }
 
     /**
      * 检测图像文件
-     * @access public
      * @return bool
      */
     public function checkImg()
     {
         $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));
-
-        // 如果上传的不是图片,或者是图片而且后缀确实符合图片类型则返回 true
-        return !in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) || in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13]);
+        /* 对图像文件进行严格检测 */
+        if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6])) {
+            return false;
+        }
+        return true;
     }
 
-    /**
-     * 判断图像类型
-     * @access protected
-     * @param  string $image 图片名称
-     * @return bool|int
-     */
+    // 判断图像类型
     protected function getImageType($image)
     {
         if (function_exists('exif_imagetype')) {
             return exif_imagetype($image);
-        }
-
-        try {
+        } else {
             $info = getimagesize($image);
-            return $info ? $info[2] : false;
-        } catch (\Exception $e) {
-            return false;
+            return $info[2];
         }
     }
 
     /**
      * 检测上传文件大小
-     * @access public
-     * @param  integer $size 最大大小
+     * @param  integer   $size    最大大小
      * @return bool
      */
     public function checkSize($size)
     {
-        return $this->getSize() <= $size;
+        if ($this->getSize() > $size) {
+            return false;
+        }
+        return true;
     }
 
     /**
      * 检测上传文件类型
-     * @access public
-     * @param  array|string $mime 允许类型
+     * @param  array|string   $mime    允许类型
      * @return bool
      */
     public function checkMime($mime)
     {
-        $mime = is_string($mime) ? explode(',', $mime) : $mime;
-
-        return in_array(strtolower($this->getMime()), $mime);
+        if (is_string($mime)) {
+            $mime = explode(',', $mime);
+        }
+        if (!in_array(strtolower($this->getMime()), $mime)) {
+            return false;
+        }
+        return true;
     }
 
     /**
      * 移动文件
-     * @access public
-     * @param  string      $path     保存路径
-     * @param  string|bool $savename 保存的文件名 默认自动生成
-     * @param  boolean     $replace  同名文件是否覆盖
-     * @return false|File
+     * @param  string           $path    保存路径
+     * @param  string|bool      $savename    保存的文件名 默认自动生成
+     * @param  boolean          $replace 同名文件是否覆盖
+     * @return false|SplFileInfo false-失败 否则返回SplFileInfo实例
      */
     public function move($path, $savename = true, $replace = true)
     {
@@ -336,7 +293,7 @@ class File extends SplFileObject
 
         // 检测合法性
         if (!$this->isValid()) {
-            $this->error = 'upload illegal files';
+            $this->error = '非法上传文件';
             return false;
         }
 
@@ -344,7 +301,6 @@ class File extends SplFileObject
         if (!$this->check()) {
             return false;
         }
-
         $path = rtrim($path, DS) . DS;
         // 文件保存命名规则
         $saveName = $this->buildSaveName($savename);
@@ -355,9 +311,9 @@ class File extends SplFileObject
             return false;
         }
 
-        // 不覆盖同名文件
+        /* 不覆盖同名文件 */
         if (!$replace && is_file($filename)) {
-            $this->error = ['has the same filename: {:filename}', ['filename' => $filename]];
+            $this->error = '存在同名文件' . $filename;
             return false;
         }
 
@@ -365,27 +321,25 @@ class File extends SplFileObject
         if ($this->isTest) {
             rename($this->filename, $filename);
         } elseif (!move_uploaded_file($this->filename, $filename)) {
-            $this->error = 'upload write error';
+            $this->error = '文件上传保存错误!';
             return false;
         }
-
-        // 返回 File 对象实例
+        // 返回 File对象实例
         $file = new self($filename);
-        $file->setSaveName($saveName)->setUploadInfo($this->info);
-
+        $file->setSaveName($saveName);
+        $file->setUploadInfo($this->info);
         return $file;
     }
 
     /**
      * 获取保存文件名
-     * @access protected
-     * @param  string|bool $savename 保存的文件名 默认自动生成
+     * @param  string|bool   $savename    保存的文件名 默认自动生成
      * @return string
      */
     protected function buildSaveName($savename)
     {
-        // 自动生成文件名
         if (true === $savename) {
+            // 自动生成文件名
             if ($this->rule instanceof \Closure) {
                 $savename = call_user_func_array($this->rule, [$this]);
             } else {
@@ -404,73 +358,52 @@ class File extends SplFileObject
                         }
                 }
             }
-        } elseif ('' === $savename || false === $savename) {
+        } elseif ('' === $savename) {
             $savename = $this->getInfo('name');
         }
-
         if (!strpos($savename, '.')) {
             $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);
         }
-
         return $savename;
     }
 
     /**
      * 获取错误代码信息
-     * @access private
-     * @param  int $errorNo 错误号
-     * @return $this
+     * @param int $errorNo  错误号
      */
     private function error($errorNo)
     {
         switch ($errorNo) {
             case 1:
             case 2:
-                $this->error = 'upload File size exceeds the maximum value';
+                $this->error = '上传文件大小超过了最大值!';
                 break;
             case 3:
-                $this->error = 'only the portion of file is uploaded';
+                $this->error = '文件只有部分被上传!';
                 break;
             case 4:
-                $this->error = 'no file to uploaded';
+                $this->error = '没有文件被上传!';
                 break;
             case 6:
-                $this->error = 'upload temp dir not found';
+                $this->error = '找不到临时文件夹!';
                 break;
             case 7:
-                $this->error = 'file write error';
+                $this->error = '文件写入失败!';
                 break;
             default:
-                $this->error = 'unknown upload error';
+                $this->error = '未知上传错误!';
         }
-
-        return $this;
     }
 
     /**
-     * 获取错误信息(支持多语言)
-     * @access public
-     * @return string
+     * 获取错误信息
+     * @return mixed
      */
     public function getError()
     {
-        if (is_array($this->error)) {
-            list($msg, $vars) = $this->error;
-        } else {
-            $msg  = $this->error;
-            $vars = [];
-        }
-
-        return Lang::has($msg) ? Lang::get($msg, $vars) : $msg;
+        return $this->error;
     }
 
-    /**
-     * 魔法方法,获取文件的 hash 值
-     * @access public
-     * @param  string $method 方法名
-     * @param  mixed  $args   调用参数
-     * @return string
-     */
     public function __call($method, $args)
     {
         return $this->hash($method);

+ 25 - 37
thinkphp/library/think/Hook.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -13,23 +13,19 @@ namespace think;
 
 class Hook
 {
-    /**
-     * @var array 标签
-     */
+
     private static $tags = [];
 
     /**
      * 动态添加行为扩展到某个标签
-     * @access public
-     * @param  string $tag      标签名称
-     * @param  mixed  $behavior 行为名称
-     * @param  bool   $first    是否放到开头执行
+     * @param string    $tag 标签名称
+     * @param mixed     $behavior 行为名称
+     * @param bool      $first 是否放到开头执行
      * @return void
      */
     public static function add($tag, $behavior, $first = false)
     {
         isset(self::$tags[$tag]) || self::$tags[$tag] = [];
-
         if (is_array($behavior) && !is_callable($behavior)) {
             if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) {
                 unset($behavior['_overlay']);
@@ -47,10 +43,8 @@ class Hook
 
     /**
      * 批量导入插件
-     * @access public
-     * @param  array   $tags      插件信息
-     * @param  boolean $recursive 是否递归合并
-     * @return void
+     * @param array        $tags 插件信息
+     * @param boolean     $recursive 是否递归合并
      */
     public static function import(array $tags, $recursive = true)
     {
@@ -65,59 +59,55 @@ class Hook
 
     /**
      * 获取插件信息
-     * @access public
-     * @param  string $tag 插件位置(留空获取全部)
+     * @param string $tag 插件位置 留空获取全部
      * @return array
      */
     public static function get($tag = '')
     {
         if (empty($tag)) {
+            //获取全部的插件信息
             return self::$tags;
+        } else {
+            return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
         }
-
-        return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];
     }
 
     /**
      * 监听标签的行为
-     * @access public
-     * @param  string $tag    标签名称
-     * @param  mixed  $params 传入参数
-     * @param  mixed  $extra  额外参数
-     * @param  bool   $once   只获取一个有效返回值
+     * @param string $tag    标签名称
+     * @param mixed  $params 传入参数
+     * @param mixed  $extra  额外参数
+     * @param bool   $once   只获取一个有效返回值
      * @return mixed
      */
     public static function listen($tag, &$params = null, $extra = null, $once = false)
     {
         $results = [];
-
-        foreach (static::get($tag) as $key => $name) {
+        $tags    = static::get($tag);
+        foreach ($tags as $key => $name) {
             $results[$key] = self::exec($name, $tag, $params, $extra);
-
-            // 如果返回 false,或者仅获取一个有效返回则中断行为执行
-            if (false === $results[$key] || (!is_null($results[$key]) && $once)) {
+            if (false === $results[$key]) {
+                // 如果返回false 则中断行为执行
+                break;
+            } elseif (!is_null($results[$key]) && $once) {
                 break;
             }
         }
-
         return $once ? end($results) : $results;
     }
 
     /**
      * 执行某个行为
-     * @access public
-     * @param  mixed  $class  要执行的行为
-     * @param  string $tag    方法名(标签名)
-     * @param  mixed  $params 传人的参数
-     * @param  mixed  $extra  额外参数
+     * @param mixed     $class 要执行的行为
+     * @param string    $tag 方法名(标签名)
+     * @param Mixed     $params 传人的参数
+     * @param mixed     $extra 额外参数
      * @return mixed
      */
     public static function exec($class, $tag = '', &$params = null, $extra = null)
     {
         App::$debug && Debug::remark('behavior_start', 'time');
-
         $method = Loader::parseName($tag, 1, false);
-
         if ($class instanceof \Closure) {
             $result = call_user_func_array($class, [ & $params, $extra]);
             $class  = 'Closure';
@@ -136,12 +126,10 @@ class Hook
             $method = ($tag && is_callable([$obj, $method])) ? $method : 'run';
             $result = $obj->$method($params, $extra);
         }
-
         if (App::$debug) {
             Debug::remark('behavior_end', 'time');
             Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
         }
-
         return $result;
     }
 

+ 47 - 95
thinkphp/library/think/Lang.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -13,148 +13,110 @@ namespace think;
 
 class Lang
 {
-    /**
-     * @var array 语言数据
-     */
+    // 语言数据
     private static $lang = [];
-
-    /**
-     * @var string 语言作用域
-     */
+    // 语言作用域
     private static $range = 'zh-cn';
-
-    /**
-     * @var string 语言自动侦测的变量
-     */
+    // 语言自动侦测的变量
     protected static $langDetectVar = 'lang';
-
-    /**
-     * @var string 语言 Cookie 变量
-     */
+    // 语言Cookie变量
     protected static $langCookieVar = 'think_var';
-
-    /**
-     * @var int 语言 Cookie 的过期时间
-     */
+    // 语言Cookie的过期时间
     protected static $langCookieExpire = 3600;
-
-    /**
-     * @var array 允许语言列表
-     */
+    // 允许语言列表
     protected static $allowLangList = [];
 
-    /**
-     * @var array Accept-Language 转义为对应语言包名称 系统默认配置
-     */
-    protected static $acceptLanguage = ['zh-hans-cn' => 'zh-cn'];
-
-    /**
-     * 设定当前的语言
-     * @access public
-     * @param  string $range 语言作用域
-     * @return string
-     */
+    // 设定当前的语言
     public static function range($range = '')
     {
-        if ($range) {
+        if ('' == $range) {
+            return self::$range;
+        } else {
             self::$range = $range;
         }
-
-        return self::$range;
     }
 
     /**
      * 设置语言定义(不区分大小写)
-     * @access public
-     * @param  string|array  $name  语言变量
-     * @param  string        $value 语言值
-     * @param  string        $range 语言作用域
+     * @param string|array  $name 语言变量
+     * @param string        $value 语言值
+     * @param string        $range 语言作用域
      * @return mixed
      */
     public static function set($name, $value = null, $range = '')
     {
         $range = $range ?: self::$range;
-
+        // 批量定义
         if (!isset(self::$lang[$range])) {
             self::$lang[$range] = [];
         }
-
         if (is_array($name)) {
             return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range];
+        } else {
+            return self::$lang[$range][strtolower($name)] = $value;
         }
-
-        return self::$lang[$range][strtolower($name)] = $value;
     }
 
     /**
      * 加载语言定义(不区分大小写)
-     * @access public
-     * @param  array|string $file 语言文件
-     * @param  string $range      语言作用域
+     * @param string $file 语言文件
+     * @param string $range 语言作用域
      * @return mixed
      */
     public static function load($file, $range = '')
     {
         $range = $range ?: self::$range;
-        $file  = is_string($file) ? [$file] : $file;
-
         if (!isset(self::$lang[$range])) {
             self::$lang[$range] = [];
         }
-
+        // 批量定义
+        if (is_string($file)) {
+            $file = [$file];
+        }
         $lang = [];
-
         foreach ($file as $_file) {
             if (is_file($_file)) {
                 // 记录加载信息
                 App::$debug && Log::record('[ LANG ] ' . $_file, 'info');
-
                 $_lang = include $_file;
-
                 if (is_array($_lang)) {
                     $lang = array_change_key_case($_lang) + $lang;
                 }
             }
         }
-
         if (!empty($lang)) {
             self::$lang[$range] = $lang + self::$lang[$range];
         }
-
         return self::$lang[$range];
     }
 
     /**
      * 获取语言定义(不区分大小写)
-     * @access public
-     * @param  string|null $name  语言变量
-     * @param  string      $range 语言作用域
+     * @param string|null   $name 语言变量
+     * @param array         $vars 变量替换
+     * @param string        $range 语言作用域
      * @return mixed
      */
     public static function has($name, $range = '')
     {
         $range = $range ?: self::$range;
-
         return isset(self::$lang[$range][strtolower($name)]);
     }
 
     /**
      * 获取语言定义(不区分大小写)
-     * @access public
-     * @param  string|null $name  语言变量
-     * @param  array       $vars  变量替换
-     * @param  string      $range 语言作用域
+     * @param string|null   $name 语言变量
+     * @param array         $vars 变量替换
+     * @param string        $range 语言作用域
      * @return mixed
      */
     public static function get($name = null, $vars = [], $range = '')
     {
         $range = $range ?: self::$range;
-
         // 空参数返回所有定义
         if (empty($name)) {
             return self::$lang[$range];
         }
-
         $key   = strtolower($name);
         $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name;
 
@@ -179,50 +141,43 @@ class Lang
             }
 
         }
-
         return $value;
     }
 
     /**
      * 自动侦测设置获取语言选择
-     * @access public
      * @return string
      */
     public static function detect()
     {
+        // 自动侦测设置获取语言选择
         $langSet = '';
-
         if (isset($_GET[self::$langDetectVar])) {
-            // url 中设置了语言变量
+            // url中设置了语言变量
             $langSet = strtolower($_GET[self::$langDetectVar]);
-        } elseif (isset($_COOKIE[self::$langCookieVar])) {
-            // Cookie 中设置了语言变量
-            $langSet = strtolower($_COOKIE[self::$langCookieVar]);
+            Cookie::set(self::$langCookieVar, $langSet, self::$langCookieExpire);
+        } elseif (Cookie::get(self::$langCookieVar)) {
+            // 获取上次用户的选择
+            $langSet = strtolower(Cookie::get(self::$langCookieVar));
         } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
             // 自动侦测浏览器语言
             preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
-            $langSet     = strtolower($matches[1]);
-            $acceptLangs = Config::get('header_accept_lang');
-
-            if (isset($acceptLangs[$langSet])) {
-                $langSet = $acceptLangs[$langSet];
-            } elseif (isset(self::$acceptLanguage[$langSet])) {
-                $langSet = self::$acceptLanguage[$langSet];
-            }
+            $langSet = strtolower($matches[1]);
+            Cookie::set(self::$langCookieVar, $langSet, self::$langCookieExpire);
         }
-
-        // 合法的语言
         if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) {
+            // 合法的语言
             self::$range = $langSet ?: self::$range;
         }
-
+        if ('zh-hans-cn' == self::$range) {
+            self::$range = 'zh-cn';
+        }
         return self::$range;
     }
 
     /**
      * 设置语言自动侦测的变量
-     * @access public
-     * @param  string $var 变量名称
+     * @param string $var 变量名称
      * @return void
      */
     public static function setLangDetectVar($var)
@@ -231,9 +186,8 @@ class Lang
     }
 
     /**
-     * 设置语言的 cookie 保存变量
-     * @access public
-     * @param  string $var 变量名称
+     * 设置语言的cookie保存变量
+     * @param string $var 变量名称
      * @return void
      */
     public static function setLangCookieVar($var)
@@ -242,9 +196,8 @@ class Lang
     }
 
     /**
-     * 设置语言的 cookie 的过期时间
-     * @access public
-     * @param  string $expire 过期时间
+     * 设置语言的cookie的过期时间
+     * @param string $expire 过期时间
      * @return void
      */
     public static function setLangCookieExpire($expire)
@@ -254,8 +207,7 @@ class Lang
 
     /**
      * 设置允许的语言列表
-     * @access public
-     * @param  array $list 语言列表
+     * @param array $list 语言列表
      * @return void
      */
     public static function setAllowLangList($list)

+ 193 - 305
thinkphp/library/think/Loader.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -15,57 +15,26 @@ use think\exception\ClassNotFoundException;
 
 class Loader
 {
-    /**
-     * @var array 实例数组
-     */
     protected static $instance = [];
+    // 类名映射
+    protected static $map = [];
 
-    /**
-     * @var array 类名映射
-     */
-    protected static $classMap = [];
-
-    /**
-     * @var array 命名空间别名
-     */
+    // 命名空间别名
     protected static $namespaceAlias = [];
 
-    /**
-     * @var array PSR-4 命名空间前缀长度映射
-     */
+    // PSR-4
     private static $prefixLengthsPsr4 = [];
+    private static $prefixDirsPsr4    = [];
+    private static $fallbackDirsPsr4  = [];
 
-    /**
-     * @var array PSR-4 的加载目录
-     */
-    private static $prefixDirsPsr4 = [];
-
-    /**
-     * @var array PSR-4 加载失败的回退目录
-     */
-    private static $fallbackDirsPsr4 = [];
-
-    /**
-     * @var array PSR-0 命名空间前缀映射
-     */
-    private static $prefixesPsr0 = [];
-
-    /**
-     * @var array PSR-0 加载失败的回退目录
-     */
+    // PSR-0
+    private static $prefixesPsr0     = [];
     private static $fallbackDirsPsr0 = [];
 
-    /**
-     * @var array 需要加载的文件
-     */
-    private static $files = [];
+    // 自动加载的文件
+    private static $autoloadFiles = [];
 
-    /**
-     * 自动加载
-     * @access public
-     * @param  string $class 类名
-     * @return bool
-     */
+    // 自动加载
     public static function autoload($class)
     {
         // 检测命名空间别名
@@ -80,33 +49,33 @@ class Loader
         }
 
         if ($file = self::findFile($class)) {
-            // 非 Win 环境不严格区分大小写
-            if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) {
-                __include_file($file);
-                return true;
+
+            // Win环境严格区分大小写
+            if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
+                return false;
             }
-        }
 
-        return false;
+            __include_file($file);
+            return true;
+        }
     }
 
     /**
      * 查找文件
-     * @access private
-     * @param  string $class 类名
-     * @return bool|string
+     * @param $class
+     * @return bool
      */
     private static function findFile($class)
     {
-        // 类库映射
-        if (!empty(self::$classMap[$class])) {
-            return self::$classMap[$class];
+        if (!empty(self::$map[$class])) {
+            // 类库映射
+            return self::$map[$class];
         }
 
         // 查找 PSR-4
         $logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
-        $first           = $class[0];
 
+        $first = $class[0];
         if (isset(self::$prefixLengthsPsr4[$first])) {
             foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
                 if (0 === strpos($class, $prefix)) {
@@ -128,7 +97,7 @@ class Loader
 
         // 查找 PSR-0
         if (false !== $pos = strrpos($class, '\\')) {
-            // namespace class name
+            // namespaced class name
             $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
             . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
         } else {
@@ -155,33 +124,20 @@ class Loader
             }
         }
 
-        // 找不到则设置映射为 false 并返回
-        return self::$classMap[$class] = false;
+        return self::$map[$class] = false;
     }
 
-    /**
-     * 注册 classmap
-     * @access public
-     * @param  string|array $class 类名
-     * @param  string       $map   映射
-     * @return void
-     */
+    // 注册classmap
     public static function addClassMap($class, $map = '')
     {
         if (is_array($class)) {
-            self::$classMap = array_merge(self::$classMap, $class);
+            self::$map = array_merge(self::$map, $class);
         } else {
-            self::$classMap[$class] = $map;
+            self::$map[$class] = $map;
         }
     }
 
-    /**
-     * 注册命名空间
-     * @access public
-     * @param  string|array $namespace 命名空间
-     * @param  string       $path      路径
-     * @return void
-     */
+    // 注册命名空间
     public static function addNamespace($namespace, $path = '')
     {
         if (is_array($namespace)) {
@@ -193,77 +149,84 @@ class Loader
         }
     }
 
-    /**
-     * 添加 PSR-0 命名空间
-     * @access private
-     * @param  array|string $prefix  空间前缀
-     * @param  array        $paths   路径
-     * @param  bool         $prepend 预先设置的优先级更高
-     * @return void
-     */
+    // 添加Ps0空间
     private static function addPsr0($prefix, $paths, $prepend = false)
     {
         if (!$prefix) {
-            self::$fallbackDirsPsr0 = $prepend ?
-            array_merge((array) $paths, self::$fallbackDirsPsr0) :
-            array_merge(self::$fallbackDirsPsr0, (array) $paths);
-        } else {
-            $first = $prefix[0];
-
-            if (!isset(self::$prefixesPsr0[$first][$prefix])) {
-                self::$prefixesPsr0[$first][$prefix] = (array) $paths;
+            if ($prepend) {
+                self::$fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    self::$fallbackDirsPsr0
+                );
             } else {
-                self::$prefixesPsr0[$first][$prefix] = $prepend ?
-                array_merge((array) $paths, self::$prefixesPsr0[$first][$prefix]) :
-                array_merge(self::$prefixesPsr0[$first][$prefix], (array) $paths);
+                self::$fallbackDirsPsr0 = array_merge(
+                    self::$fallbackDirsPsr0,
+                    (array) $paths
+                );
             }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset(self::$prefixesPsr0[$first][$prefix])) {
+            self::$prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            self::$prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                self::$prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            self::$prefixesPsr0[$first][$prefix] = array_merge(
+                self::$prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
         }
     }
 
-    /**
-     * 添加 PSR-4 空间
-     * @access private
-     * @param  array|string $prefix  空间前缀
-     * @param  string       $paths   路径
-     * @param  bool         $prepend 预先设置的优先级更高
-     * @return void
-     */
+    // 添加Psr4空间
     private static function addPsr4($prefix, $paths, $prepend = false)
     {
         if (!$prefix) {
             // Register directories for the root namespace.
-            self::$fallbackDirsPsr4 = $prepend ?
-            array_merge((array) $paths, self::$fallbackDirsPsr4) :
-            array_merge(self::$fallbackDirsPsr4, (array) $paths);
-
+            if ($prepend) {
+                self::$fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    self::$fallbackDirsPsr4
+                );
+            } else {
+                self::$fallbackDirsPsr4 = array_merge(
+                    self::$fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
         } elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
             // Register directories for a new namespace.
             $length = strlen($prefix);
             if ('\\' !== $prefix[$length - 1]) {
-                throw new \InvalidArgumentException(
-                    "A non-empty PSR-4 prefix must end with a namespace separator."
-                );
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
             }
-
             self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
             self::$prefixDirsPsr4[$prefix]                = (array) $paths;
-
-        } else {
-            self::$prefixDirsPsr4[$prefix] = $prepend ?
+        } elseif ($prepend) {
             // Prepend directories for an already registered namespace.
-            array_merge((array) $paths, self::$prefixDirsPsr4[$prefix]) :
+            self::$prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                self::$prefixDirsPsr4[$prefix]
+            );
+        } else {
             // Append directories for an already registered namespace.
-            array_merge(self::$prefixDirsPsr4[$prefix], (array) $paths);
+            self::$prefixDirsPsr4[$prefix] = array_merge(
+                self::$prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
         }
     }
 
-    /**
-     * 注册命名空间别名
-     * @access public
-     * @param  array|string $namespace 命名空间
-     * @param  string       $original  源文件
-     * @return void
-     */
+    // 注册命名空间别名
     public static function addNamespaceAlias($namespace, $original = '')
     {
         if (is_array($namespace)) {
@@ -273,58 +236,32 @@ class Loader
         }
     }
 
-    /**
-     * 注册自动加载机制
-     * @access public
-     * @param  callable $autoload 自动加载处理方法
-     * @return void
-     */
-    public static function register($autoload = null)
+    // 注册自动加载机制
+    public static function register($autoload = '')
     {
         // 注册系统自动加载
         spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
-
-        // Composer 自动加载支持
-        if (is_dir(VENDOR_PATH . 'composer')) {
-            if (PHP_VERSION_ID >= 50600 && is_file(VENDOR_PATH . 'composer' . DS . 'autoload_static.php')) {
-                require VENDOR_PATH . 'composer' . DS . 'autoload_static.php';
-
-                $declaredClass = get_declared_classes();
-                $composerClass = array_pop($declaredClass);
-
-                foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) {
-                    if (property_exists($composerClass, $attr)) {
-                        self::${$attr} = $composerClass::${$attr};
-                    }
-                }
-            } else {
-                self::registerComposerLoader();
-            }
-        }
-
         // 注册命名空间定义
         self::addNamespace([
             'think'    => LIB_PATH . 'think' . DS,
             'behavior' => LIB_PATH . 'behavior' . DS,
             'traits'   => LIB_PATH . 'traits' . DS,
         ]);
-
         // 加载类库映射文件
         if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {
             self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));
         }
 
-        self::loadComposerAutoloadFiles();
+        // Composer自动加载支持
+        if (is_dir(VENDOR_PATH . 'composer')) {
+            self::registerComposerLoader();
+        }
 
-        // 自动加载 extend 目录
+        // 自动加载extend目录
         self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);
     }
 
-    /**
-     * 注册 composer 自动加载
-     * @access private
-     * @return void
-     */
+    // 注册composer自动加载
     private static function registerComposerLoader()
     {
         if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {
@@ -349,36 +286,28 @@ class Loader
         }
 
         if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {
-            self::$files = require VENDOR_PATH . 'composer/autoload_files.php';
-        }
-    }
-
-    // 加载composer autofile文件
-    public static function loadComposerAutoloadFiles()
-    {
-        foreach (self::$files as $fileIdentifier => $file) {
-            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
-                __require_file($file);
-
-                $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+            $includeFiles = require VENDOR_PATH . 'composer/autoload_files.php';
+            foreach ($includeFiles as $fileIdentifier => $file) {
+                if (empty(self::$autoloadFiles[$fileIdentifier])) {
+                    __require_file($file);
+                    self::$autoloadFiles[$fileIdentifier] = true;
+                }
             }
         }
     }
 
     /**
-     * 导入所需的类库 同 Java 的 Import 本函数有缓存功能
-     * @access public
-     * @param  string $class   类库命名空间字符串
-     * @param  string $baseUrl 起始路径
-     * @param  string $ext     导入的文件扩展名
-     * @return bool
+     * 导入所需的类库 同java的Import 本函数有缓存功能
+     * @param string $class   类库命名空间字符串
+     * @param string $baseUrl 起始路径
+     * @param string $ext     导入的文件扩展名
+     * @return boolean
      */
     public static function import($class, $baseUrl = '', $ext = EXT)
     {
         static $_file = [];
         $key          = $class . $baseUrl;
         $class        = str_replace(['.', '#'], [DS, '.'], $class);
-
         if (isset($_file[$key])) {
             return true;
         }
@@ -390,7 +319,7 @@ class Loader
                 // 注册的命名空间
                 $baseUrl = self::$prefixDirsPsr4[$name . '\\'];
             } elseif ('@' == $name) {
-                // 加载当前模块应用类库
+                //加载当前模块应用类库
                 $baseUrl = App::$modulePath;
             } elseif (is_dir(EXTEND_PATH . $name)) {
                 $baseUrl = EXTEND_PATH . $name . DS;
@@ -401,11 +330,11 @@ class Loader
         } elseif (substr($baseUrl, -1) != DS) {
             $baseUrl .= DS;
         }
-
-        // 如果类存在则导入类库文件
+        // 如果类存在 则导入类库文件
         if (is_array($baseUrl)) {
             foreach ($baseUrl as $path) {
-                if (is_file($filename = $path . DS . $class . $ext)) {
+                $filename = $path . DS . $class . $ext;
+                if (is_file($filename)) {
                     break;
                 }
             }
@@ -413,154 +342,132 @@ class Loader
             $filename = $baseUrl . $class . $ext;
         }
 
-        if (!empty($filename) &&
-            is_file($filename) &&
-            (!IS_WIN || pathinfo($filename, PATHINFO_FILENAME) == pathinfo(realpath($filename), PATHINFO_FILENAME))
-        ) {
+        if (!empty($filename) && is_file($filename)) {
+            // 开启调试模式Win环境严格区分大小写
+            if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) {
+                return false;
+            }
             __include_file($filename);
             $_file[$key] = true;
-
             return true;
         }
-
         return false;
     }
 
     /**
      * 实例化(分层)模型
-     * @access public
-     * @param  string $name         Model名称
-     * @param  string $layer        业务层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $common       公共模块名
-     * @return object
+     * @param string $name         Model名称
+     * @param string $layer        业务层名称
+     * @param bool   $appendSuffix 是否添加类名后缀
+     * @param string $common       公共模块名
+     * @return Object
      * @throws ClassNotFoundException
      */
     public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')
     {
-        $uid = $name . $layer;
-
-        if (isset(self::$instance[$uid])) {
-            return self::$instance[$uid];
+        $guid = $name . $layer;
+        if (isset(self::$instance[$guid])) {
+            return self::$instance[$guid];
+        }
+        if (strpos($name, '\\')) {
+            $class = $name;
+        } else {
+            if (strpos($name, '/')) {
+                list($module, $name) = explode('/', $name, 2);
+            } else {
+                $module = Request::instance()->module();
+            }
+            $class = self::parseClass($module, $layer, $name, $appendSuffix);
         }
-
-        list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
-
         if (class_exists($class)) {
             $model = new $class();
         } else {
             $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
-
             if (class_exists($class)) {
                 $model = new $class();
             } else {
                 throw new ClassNotFoundException('class not exists:' . $class, $class);
             }
         }
-
-        return self::$instance[$uid] = $model;
+        self::$instance[$guid] = $model;
+        return $model;
     }
 
     /**
      * 实例化(分层)控制器 格式:[模块名/]控制器名
-     * @access public
-     * @param  string $name         资源地址
-     * @param  string $layer        控制层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $empty        空控制器名称
-     * @return object
+     * @param string $name         资源地址
+     * @param string $layer        控制层名称
+     * @param bool   $appendSuffix 是否添加类名后缀
+     * @param string $empty        空控制器名称
+     * @return Object|false
      * @throws ClassNotFoundException
      */
     public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')
     {
-        list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
-
+        if (strpos($name, '\\')) {
+            $class = $name;
+        } else {
+            if (strpos($name, '/')) {
+                list($module, $name) = explode('/', $name);
+            } else {
+                $module = Request::instance()->module();
+            }
+            $class = self::parseClass($module, $layer, $name, $appendSuffix);
+        }
         if (class_exists($class)) {
             return App::invokeClass($class);
+        } elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {
+            return new $emptyClass(Request::instance());
         }
-
-        if ($empty) {
-            $emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix);
-
-            if (class_exists($emptyClass)) {
-                return new $emptyClass(Request::instance());
-            }
-        }
-
-        throw new ClassNotFoundException('class not exists:' . $class, $class);
     }
 
     /**
      * 实例化验证类 格式:[模块名/]验证器名
-     * @access public
-     * @param  string $name         资源地址
-     * @param  string $layer        验证层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @param  string $common       公共模块名
-     * @return object|false
+     * @param string $name         资源地址
+     * @param string $layer        验证层名称
+     * @param bool   $appendSuffix 是否添加类名后缀
+     * @param string $common       公共模块名
+     * @return Object|false
      * @throws ClassNotFoundException
      */
     public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')
     {
         $name = $name ?: Config::get('default_validate');
-
         if (empty($name)) {
             return new Validate;
         }
-
-        $uid = $name . $layer;
-        if (isset(self::$instance[$uid])) {
-            return self::$instance[$uid];
+        $guid = $name . $layer;
+        if (isset(self::$instance[$guid])) {
+            return self::$instance[$guid];
+        }
+        if (strpos($name, '\\')) {
+            $class = $name;
+        } else {
+            if (strpos($name, '/')) {
+                list($module, $name) = explode('/', $name);
+            } else {
+                $module = Request::instance()->module();
+            }
+            $class = self::parseClass($module, $layer, $name, $appendSuffix);
         }
-
-        list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);
-
         if (class_exists($class)) {
             $validate = new $class;
         } else {
             $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class);
-
             if (class_exists($class)) {
                 $validate = new $class;
             } else {
                 throw new ClassNotFoundException('class not exists:' . $class, $class);
             }
         }
-
-        return self::$instance[$uid] = $validate;
-    }
-
-    /**
-     * 解析模块和类名
-     * @access protected
-     * @param  string $name         资源地址
-     * @param  string $layer        验证层名称
-     * @param  bool   $appendSuffix 是否添加类名后缀
-     * @return array
-     */
-    protected static function getModuleAndClass($name, $layer, $appendSuffix)
-    {
-        if (false !== strpos($name, '\\')) {
-            $module = Request::instance()->module();
-            $class  = $name;
-        } else {
-            if (strpos($name, '/')) {
-                list($module, $name) = explode('/', $name, 2);
-            } else {
-                $module = Request::instance()->module();
-            }
-
-            $class = self::parseClass($module, $layer, $name, $appendSuffix);
-        }
-
-        return [$module, $class];
+        self::$instance[$guid] = $validate;
+        return $validate;
     }
 
     /**
      * 数据库初始化 并取得数据库类实例
-     * @access public
-     * @param  mixed       $config 数据库配置
-     * @param  bool|string $name   连接标识 true 强制重新连接
+     * @param mixed         $config 数据库配置
+     * @param bool|string   $name 连接标识 true 强制重新连接
      * @return \think\db\Connection
      */
     public static function db($config = [], $name = false)
@@ -570,11 +477,10 @@ class Loader
 
     /**
      * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作
-     * @access public
-     * @param  string       $url          调用地址
-     * @param  string|array $vars         调用参数 支持字符串和数组
-     * @param  string       $layer        要调用的控制层名称
-     * @param  bool         $appendSuffix 是否添加类名后缀
+     * @param string       $url          调用地址
+     * @param string|array $vars         调用参数 支持字符串和数组
+     * @param string       $layer        要调用的控制层名称
+     * @param bool         $appendSuffix 是否添加类名后缀
      * @return mixed
      */
     public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
@@ -583,7 +489,6 @@ class Loader
         $action = $info['basename'];
         $module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();
         $class  = self::controller($module, $layer, $appendSuffix);
-
         if ($class) {
             if (is_scalar($vars)) {
                 if (strpos($vars, '=')) {
@@ -592,20 +497,16 @@ class Loader
                     $vars = [$vars];
                 }
             }
-
             return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);
         }
-
-        return false;
     }
 
     /**
      * 字符串命名风格转换
-     * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格
-     * @access public
-     * @param  string  $name    字符串
-     * @param  integer $type    转换类型
-     * @param  bool    $ucfirst 首字母是否大写(驼峰规则)
+     * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
+     * @param string  $name 字符串
+     * @param integer $type 转换类型
+     * @param bool    $ucfirst 首字母是否大写(驼峰规则)
      * @return string
      */
     public static function parseName($name, $type = 0, $ucfirst = true)
@@ -614,38 +515,31 @@ class Loader
             $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                 return strtoupper($match[1]);
             }, $name);
-
             return $ucfirst ? ucfirst($name) : lcfirst($name);
+        } else {
+            return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
         }
-
-        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
     }
 
     /**
      * 解析应用类的类名
-     * @access public
-     * @param  string $module       模块名
-     * @param  string $layer        层名 controller model ...
-     * @param  string $name         类名
-     * @param  bool   $appendSuffix 是否添加类名后缀
+     * @param string $module 模块名
+     * @param string $layer  层名 controller model ...
+     * @param string $name   类名
+     * @param bool   $appendSuffix
      * @return string
      */
     public static function parseClass($module, $layer, $name, $appendSuffix = false)
     {
-
-        $array = explode('\\', str_replace(['/', '.'], '\\', $name));
-        $class = self::parseName(array_pop($array), 1);
-        $class = $class . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');
+        $name  = str_replace(['/', '.'], '\\', $name);
+        $array = explode('\\', $name);
+        $class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');
         $path  = $array ? implode('\\', $array) . '\\' : '';
-
-        return App::$namespace . '\\' .
-            ($module ? $module . '\\' : '') .
-            $layer . '\\' . $path . $class;
+        return App::$namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class;
     }
 
     /**
      * 初始化类的实例
-     * @access public
      * @return void
      */
     public static function clearInstance()
@@ -654,11 +548,10 @@ class Loader
     }
 }
 
-// 作用范围隔离
-
 /**
- * include
- * @param  string $file 文件路径
+ * 作用范围隔离
+ *
+ * @param $file
  * @return mixed
  */
 function __include_file($file)
@@ -666,11 +559,6 @@ function __include_file($file)
     return include $file;
 }
 
-/**
- * require
- * @param  string $file 文件路径
- * @return mixed
- */
 function __require_file($file)
 {
     return require $file;

+ 77 - 106
thinkphp/library/think/Log.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -17,12 +17,12 @@ use think\exception\ClassNotFoundException;
  * Class Log
  * @package think
  *
- * @method void log($msg) static 记录一般日志
- * @method void error($msg) static 记录错误日志
- * @method void info($msg) static 记录一般信息日志
- * @method void sql($msg) static 记录 SQL 查询日志
- * @method void notice($msg) static 记录提示日志
- * @method void alert($msg) static 记录报警日志
+ * @method void log($msg) static
+ * @method void error($msg) static
+ * @method void info($msg) static
+ * @method void sql($msg) static
+ * @method void notice($msg) static
+ * @method void alert($msg) static
  */
 class Log
 {
@@ -34,60 +34,41 @@ class Log
     const ALERT  = 'alert';
     const DEBUG  = 'debug';
 
-    /**
-     * @var array 日志信息
-     */
+    // 日志信息
     protected static $log = [];
-
-    /**
-     * @var array 配置参数
-     */
+    // 配置参数
     protected static $config = [];
-
-    /**
-     * @var array 日志类型
-     */
+    // 日志类型
     protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug'];
-
-    /**
-     * @var log\driver\File|log\driver\Test|log\driver\Socket 日志写入驱动
-     */
+    // 日志写入驱动
     protected static $driver;
 
-    /**
-     * @var string 当前日志授权 key
-     */
+    // 当前日志授权key
     protected static $key;
 
     /**
      * 日志初始化
-     * @access public
-     * @param  array $config 配置参数
-     * @return void
+     * @param array $config
      */
     public static function init($config = [])
     {
-        $type  = isset($config['type']) ? $config['type'] : 'File';
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type);
-
+        $type         = isset($config['type']) ? $config['type'] : 'File';
+        $class        = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type);
         self::$config = $config;
         unset($config['type']);
-
         if (class_exists($class)) {
             self::$driver = new $class($config);
         } else {
             throw new ClassNotFoundException('class not exists:' . $class, $class);
         }
-
         // 记录初始化信息
         App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info');
     }
 
     /**
      * 获取日志信息
-     * @access public
-     * @param  string $type 信息类型
-     * @return array|string
+     * @param string $type 信息类型
+     * @return array
      */
     public static function getLog($type = '')
     {
@@ -96,22 +77,21 @@ class Log
 
     /**
      * 记录调试信息
-     * @access public
-     * @param  mixed  $msg  调试信息
-     * @param  string $type 信息类型
+     * @param mixed  $msg  调试信息
+     * @param string $type 信息类型
      * @return void
      */
     public static function record($msg, $type = 'log')
     {
         self::$log[$type][] = $msg;
-
-        // 命令行下面日志写入改进
-        IS_CLI && self::save();
+        if (IS_CLI && count(self::$log[$type]) > 100) {
+            // 命令行下面日志写入改进
+            self::save();
+        }
     }
 
     /**
      * 清空日志信息
-     * @access public
      * @return void
      */
     public static function clear()
@@ -120,9 +100,8 @@ class Log
     }
 
     /**
-     * 设置当前日志记录的授权 key
-     * @access public
-     * @param  string $key 授权 key
+     * 当前日志记录的授权key
+     * @param string  $key  授权key
      * @return void
      */
     public static function key($key)
@@ -132,105 +111,97 @@ class Log
 
     /**
      * 检查日志写入权限
-     * @access public
-     * @param  array $config 当前日志配置参数
+     * @param array  $config  当前日志配置参数
      * @return bool
      */
     public static function check($config)
     {
-        return !self::$key || empty($config['allow_key']) || in_array(self::$key, $config['allow_key']);
+        if (self::$key && !empty($config['allow_key']) && !in_array(self::$key, $config['allow_key'])) {
+            return false;
+        }
+        return true;
     }
 
     /**
      * 保存调试信息
-     * @access public
      * @return bool
      */
     public static function save()
     {
-        // 没有需要保存的记录则直接返回
-        if (empty(self::$log)) {
-            return true;
-        }
-
-        is_null(self::$driver) && self::init(Config::get('log'));
-
-        // 检测日志写入权限
-        if (!self::check(self::$config)) {
-            return false;
-        }
+        if (!empty(self::$log)) {
+            if (is_null(self::$driver)) {
+                self::init(Config::get('log'));
+            }
 
-        if (empty(self::$config['level'])) {
-            // 获取全部日志
-            $log = self::$log;
-            if (!App::$debug && isset($log['debug'])) {
-                unset($log['debug']);
+            if (!self::check(self::$config)) {
+                // 检测日志写入权限
+                return false;
             }
-        } else {
-            // 记录允许级别
-            $log = [];
-            foreach (self::$config['level'] as $level) {
-                if (isset(self::$log[$level])) {
-                    $log[$level] = self::$log[$level];
+
+            if (empty(self::$config['level'])) {
+                // 获取全部日志
+                $log = self::$log;
+                if (!App::$debug && isset($log['debug'])) {
+                    unset($log['debug']);
+                }
+            } else {
+                // 记录允许级别
+                $log = [];
+                foreach (self::$config['level'] as $level) {
+                    if (isset(self::$log[$level])) {
+                        $log[$level] = self::$log[$level];
+                    }
                 }
             }
-        }
-
-        if ($result = self::$driver->save($log, true)) {
-            self::$log = [];
-        }
 
-        Hook::listen('log_write_done', $log);
+            $result = self::$driver->save($log);
+            if ($result) {
+                self::$log = [];
+            }
 
-        return $result;
+            return $result;
+        }
+        return true;
     }
 
     /**
      * 实时写入日志信息 并支持行为
-     * @access public
-     * @param  mixed  $msg   调试信息
-     * @param  string $type  信息类型
-     * @param  bool   $force 是否强制写入
+     * @param mixed  $msg  调试信息
+     * @param string $type 信息类型
+     * @param bool   $force 是否强制写入
      * @return bool
      */
     public static function write($msg, $type = 'log', $force = false)
     {
-        $log = self::$log;
-
-        // 如果不是强制写入,而且信息类型不在可记录的类别中则直接返回 false 不做记录
-        if (true !== $force && !empty(self::$config['level']) && !in_array($type, self::$config['level'])) {
+        // 封装日志信息
+        if (true === $force || empty(self::$config['level'])) {
+            $log[$type][] = $msg;
+        } elseif (in_array($type, self::$config['level'])) {
+            $log[$type][] = $msg;
+        } else {
             return false;
         }
 
-        // 封装日志信息
-        $log[$type][] = $msg;
-
-        // 监听 log_write
+        // 监听log_write
         Hook::listen('log_write', $log);
-
-        is_null(self::$driver) && self::init(Config::get('log'));
-
-        // 写入日志
-        if ($result = self::$driver->save($log, false)) {
-            self::$log = [];
+        if (is_null(self::$driver)) {
+            self::init(Config::get('log'));
         }
-
-        return $result;
+        // 写入日志
+        return self::$driver->save($log, false);
     }
 
     /**
-     * 静态方法调用
-     * @access public
-     * @param  string $method 调用方法
-     * @param  mixed  $args   参数
-     * @return void
+     * 静态调用
+     * @param $method
+     * @param $args
+     * @return mixed
      */
     public static function __callStatic($method, $args)
     {
         if (in_array($method, self::$type)) {
             array_push($args, $method);
-
-            call_user_func_array('\\think\\Log::record', $args);
+            return call_user_func_array('\\think\\Log::record', $args);
         }
     }
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 169 - 558
thinkphp/library/think/Model.php


+ 16 - 56
thinkphp/library/think/Paginator.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -49,9 +49,6 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
         'fragment' => '',
     ];
 
-    /** @var mixed simple模式下的下个元素 */
-    protected $nextItem;
-
     public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])
     {
         $this->options = array_merge($this->options, $options);
@@ -68,10 +65,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
         if ($simple) {
             $this->currentPage = $this->setCurrentPage($currentPage);
             $this->hasMore     = count($items) > ($this->listRows);
-            if ($this->hasMore) {
-                $this->nextItem = $items->slice($this->listRows, 1);
-            }
-            $items = $items->slice(0, $this->listRows);
+            $items             = $items->slice(0, $this->listRows);
         } else {
             $this->total       = $total;
             $this->lastPage    = (int) ceil($total / $listRows);
@@ -128,7 +122,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
         }
         $url = $path;
         if (!empty($parameters)) {
-            $url .= '?' . http_build_query($parameters, null, '&');
+            $url .= '?' . urldecode(http_build_query($parameters, null, '&'));
         }
         return $url . $this->buildFragment();
     }
@@ -141,9 +135,9 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      */
     public static function getCurrentPage($varPage = 'page', $default = 1)
     {
-        $page = (int) Request::instance()->param($varPage);
+        $page = Request::instance()->request($varPage);
 
-        if (filter_var($page, FILTER_VALIDATE_INT) !== false && $page >= 1) {
+        if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {
             return $page;
         }
 
@@ -279,26 +273,6 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
         return $this->items->isEmpty();
     }
 
-    /**
-     * 给每个元素执行个回调
-     *
-     * @param  callable $callback
-     * @return $this
-     */
-    public function each(callable $callback)
-    {
-        foreach ($this->items as $key => $item) {
-            $result = $callback($item, $key);
-            if (false === $result) {
-                break;
-            } elseif (!is_object($item)) {
-                $this->items[$key] = $result;
-            }
-        }
-
-        return $this;
-    }
-
     /**
      * Retrieve an external iterator
      * @return Traversable An instance of an object implementing <b>Iterator</b> or
@@ -365,24 +339,18 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
 
     public function toArray()
     {
-        if ($this->simple) {
-            return [
-                'per_page'     => $this->listRows,
-                'current_page' => $this->currentPage,
-                'has_more'     => $this->hasMore,
-                'next_item'    => $this->nextItem,
-                'data'         => $this->items->toArray(),
-            ];
-        } else {
-            return [
-                'total'        => $this->total,
-                'per_page'     => $this->listRows,
-                'current_page' => $this->currentPage,
-                'last_page'    => $this->lastPage,
-                'data'         => $this->items->toArray(),
-            ];
+        try {
+            $total = $this->total();
+        } catch (Exception $e) {
+            $total = null;
         }
 
+        return [
+            'total'        => $total,
+            'per_page'     => $this->listRows(),
+            'current_page' => $this->currentPage(),
+            'data'         => $this->items->toArray()
+        ];
     }
 
     /**
@@ -395,15 +363,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
 
     public function __call($name, $arguments)
     {
-        $collection = $this->getCollection();
-
-        $result = call_user_func_array([$collection, $name], $arguments);
-
-        if ($result === $collection) {
-            return $this;
-        }
-
-        return $result;
+        return call_user_func_array([$this->getCollection(), $name], $arguments);
     }
 
 }

+ 132 - 220
thinkphp/library/think/Request.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -59,11 +59,6 @@ class Request
      */
     protected $routeInfo = [];
 
-    /**
-     * @var array 环境变量
-     */
-    protected $env;
-
     /**
      * @var array 当前调度信息
      */
@@ -93,18 +88,20 @@ class Request
      * @var array 资源类型
      */
     protected $mimeType = [
-        'xml'   => 'application/xml,text/xml,application/x-xml',
-        'json'  => 'application/json,text/x-json,application/jsonrequest,text/json',
-        'js'    => 'text/javascript,application/javascript,application/x-javascript',
-        'css'   => 'text/css',
-        'rss'   => 'application/rss+xml',
-        'yaml'  => 'application/x-yaml,text/yaml',
-        'atom'  => 'application/atom+xml',
-        'pdf'   => 'application/pdf',
-        'text'  => 'text/plain',
-        'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*',
-        'csv'   => 'text/csv',
-        'html'  => 'text/html,application/xhtml+xml,*/*',
+        'xml'  => 'application/xml,text/xml,application/x-xml',
+        'json' => 'application/json,text/x-json,application/jsonrequest,text/json',
+        'js'   => 'text/javascript,application/javascript,application/x-javascript',
+        'css'  => 'text/css',
+        'rss'  => 'application/rss+xml',
+        'yaml' => 'application/x-yaml,text/yaml',
+        'atom' => 'application/atom+xml',
+        'pdf'  => 'application/pdf',
+        'text' => 'text/plain',
+        'png'  => 'image/png',
+        'jpg'  => 'image/jpg,image/jpeg,image/pjpeg',
+        'gif'  => 'image/gif',
+        'csv'  => 'text/csv',
+        'html' => 'text/html,application/xhtml+xml,*/*',
     ];
 
     protected $content;
@@ -121,14 +118,9 @@ class Request
     protected $cache;
     // 缓存是否检查
     protected $isCheckCache;
-    /**
-     * 是否合并Param
-     * @var bool
-     */
-    protected $mergeParam = false;
 
     /**
-     * 构函数
+     * 架构函数
      * @access protected
      * @param array $options 参数
      */
@@ -142,7 +134,6 @@ class Request
         if (is_null($this->filter)) {
             $this->filter = Config::get('default_filter');
         }
-
         // 保存 php://input
         $this->input = file_get_contents('php://input');
     }
@@ -160,8 +151,8 @@ class Request
     /**
      * Hook 方法注入
      * @access public
-     * @param string|array $method   方法名
-     * @param mixed        $callback callable
+     * @param string|array  $method 方法名
+     * @param mixed         $callback callable
      * @return void
      */
     public static function hook($method, $callback = null)
@@ -187,28 +178,16 @@ class Request
         return self::$instance;
     }
 
-    /**
-     * 销毁当前请求对象
-     * @access public
-     * @return void
-     */
-    public static function destroy()
-    {
-        if (!is_null(self::$instance)) {
-            self::$instance = null;
-        }
-    }
-
     /**
      * 创建一个URL请求
      * @access public
-     * @param string $uri    URL地址
-     * @param string $method 请求类型
-     * @param array  $params 请求参数
-     * @param array  $cookie
-     * @param array  $files
-     * @param array  $server
-     * @param string $content
+     * @param string    $uri URL地址
+     * @param string    $method 请求类型
+     * @param array     $params 请求参数
+     * @param array     $cookie
+     * @param array     $files
+     * @param array     $server
+     * @param string    $content
      * @return \think\Request
      */
     public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null)
@@ -249,7 +228,7 @@ class Request
             parse_str(html_entity_decode($info['query']), $query);
             if (!empty($params)) {
                 $params      = array_replace($query, $params);
-                $queryString = http_build_query($params, '', '&');
+                $queryString = http_build_query($query, '', '&');
             } else {
                 $params      = $query;
                 $queryString = $info['query'];
@@ -496,8 +475,8 @@ class Request
     /**
      * 设置资源类型
      * @access public
-     * @param string|array $type 资源类型名
-     * @param string       $val  资源类型
+     * @param string|array  $type 资源类型名
+     * @param string        $val 资源类型
      * @return void
      */
     public function mimeType($type, $val = '')
@@ -512,28 +491,22 @@ class Request
     /**
      * 当前的请求类型
      * @access public
-     * @param bool $method true 获取原始请求类型
+     * @param bool $method  true 获取原始请求类型
      * @return string
      */
     public function method($method = false)
     {
         if (true === $method) {
             // 获取原始请求类型
-            return $this->server('REQUEST_METHOD') ?: 'GET';
+            return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
         } elseif (!$this->method) {
             if (isset($_POST[Config::get('var_method')])) {
-                $method = strtoupper($_POST[Config::get('var_method')]);
-                if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) {
-                    $this->method = $method;
-                    $this->{$this->method}($_POST);
-                } else {
-                    $this->method = 'POST';
-                }
-                unset($_POST[Config::get('var_method')]);
+                $this->method = strtoupper($_POST[Config::get('var_method')]);
+                $this->{$this->method}($_POST);
             } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
                 $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
             } else {
-                $this->method = $this->server('REQUEST_METHOD') ?: 'GET';
+                $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);
             }
         }
         return $this->method;
@@ -630,16 +603,16 @@ class Request
     }
 
     /**
-     * 获取当前请求的参数
+     * 获取获取当前请求的参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 变量名
+     * @param mixed         $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function param($name = '', $default = null, $filter = '')
     {
-        if (empty($this->mergeParam)) {
+        if (empty($this->param)) {
             $method = $this->method(true);
             // 自动获取请求变量
             switch ($method) {
@@ -655,42 +628,40 @@ class Request
                     $vars = [];
             }
             // 当前请求参数和URL地址中的参数合并
-            $this->param      = array_merge($this->param, $this->get(false), $vars, $this->route(false));
-            $this->mergeParam = true;
+            $this->param = array_merge($this->get(false), $vars, $this->route(false));
         }
         if (true === $name) {
             // 获取包含文件上传信息的数组
             $file = $this->file();
-            $data = is_array($file) ? array_merge($this->param, $file) : $this->param;
+            $data = array_merge($this->param, $file);
             return $this->input($data, '', $default, $filter);
         }
         return $this->input($this->param, $name, $default, $filter);
     }
 
     /**
-     * 设置获取路由参数
+     * 设置获取获取路由参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 变量名
+     * @param mixed         $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function route($name = '', $default = null, $filter = '')
     {
         if (is_array($name)) {
             $this->param        = [];
-            $this->mergeParam   = false;
             return $this->route = array_merge($this->route, $name);
         }
         return $this->input($this->route, $name, $default, $filter);
     }
 
     /**
-     * 设置获取GET参数
+     * 设置获取获取GET参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 变量名
+     * @param mixed         $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function get($name = '', $default = null, $filter = '')
@@ -700,25 +671,24 @@ class Request
         }
         if (is_array($name)) {
             $this->param      = [];
-            $this->mergeParam = false;
             return $this->get = array_merge($this->get, $name);
         }
         return $this->input($this->get, $name, $default, $filter);
     }
 
     /**
-     * 设置获取POST参数
+     * 设置获取获取POST参数
      * @access public
-     * @param string       $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string        $name 变量名
+     * @param mixed         $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function post($name = '', $default = null, $filter = '')
     {
         if (empty($this->post)) {
             $content = $this->input;
-            if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) {
+            if (empty($_POST) && 'application/json' == $this->contentType()) {
                 $this->post = (array) json_decode($content, true);
             } else {
                 $this->post = $_POST;
@@ -726,25 +696,24 @@ class Request
         }
         if (is_array($name)) {
             $this->param       = [];
-            $this->mergeParam  = false;
             return $this->post = array_merge($this->post, $name);
         }
         return $this->input($this->post, $name, $default, $filter);
     }
 
     /**
-     * 设置获取PUT参数
+     * 设置获取获取PUT参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array      $name 变量名
+     * @param mixed             $default 默认值
+     * @param string|array      $filter 过滤方法
      * @return mixed
      */
     public function put($name = '', $default = null, $filter = '')
     {
         if (is_null($this->put)) {
             $content = $this->input;
-            if (false !== strpos($this->contentType(), 'application/json')) {
+            if ('application/json' == $this->contentType()) {
                 $this->put = (array) json_decode($content, true);
             } else {
                 parse_str($content, $this->put);
@@ -752,7 +721,6 @@ class Request
         }
         if (is_array($name)) {
             $this->param      = [];
-            $this->mergeParam = false;
             return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name);
         }
 
@@ -760,11 +728,11 @@ class Request
     }
 
     /**
-     * 设置获取DELETE参数
+     * 设置获取获取DELETE参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array      $name 变量名
+     * @param mixed             $default 默认值
+     * @param string|array      $filter 过滤方法
      * @return mixed
      */
     public function delete($name = '', $default = null, $filter = '')
@@ -773,11 +741,11 @@ class Request
     }
 
     /**
-     * 设置获取PATCH参数
+     * 设置获取获取PATCH参数
      * @access public
-     * @param string|array $name    变量名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array      $name 变量名
+     * @param mixed             $default 默认值
+     * @param string|array      $filter 过滤方法
      * @return mixed
      */
     public function patch($name = '', $default = null, $filter = '')
@@ -787,9 +755,9 @@ class Request
 
     /**
      * 获取request变量
-     * @param string       $name    数据名称
-     * @param string       $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string        $name 数据名称
+     * @param string        $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function request($name = '', $default = null, $filter = '')
@@ -799,7 +767,6 @@ class Request
         }
         if (is_array($name)) {
             $this->param          = [];
-            $this->mergeParam     = false;
             return $this->request = array_merge($this->request, $name);
         }
         return $this->input($this->request, $name, $default, $filter);
@@ -808,9 +775,9 @@ class Request
     /**
      * 获取session数据
      * @access public
-     * @param string|array $name    数据名称
-     * @param string       $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 数据名称
+     * @param string        $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function session($name = '', $default = null, $filter = '')
@@ -827,42 +794,28 @@ class Request
     /**
      * 获取cookie参数
      * @access public
-     * @param string|array $name    数据名称
-     * @param string       $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 数据名称
+     * @param string        $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function cookie($name = '', $default = null, $filter = '')
     {
         if (empty($this->cookie)) {
-            $this->cookie = Cookie::get();
+            $this->cookie = $_COOKIE;
         }
         if (is_array($name)) {
             return $this->cookie = array_merge($this->cookie, $name);
-        } elseif (!empty($name)) {
-            $data = Cookie::has($name) ? Cookie::get($name) : $default;
-        } else {
-            $data = $this->cookie;
-        }
-
-        // 解析过滤器
-        $filter = $this->getFilter($filter, $default);
-
-        if (is_array($data)) {
-            array_walk_recursive($data, [$this, 'filterValue'], $filter);
-            reset($data);
-        } else {
-            $this->filterValue($data, $name, $filter);
         }
-        return $data;
+        return $this->input($this->cookie, $name, $default, $filter);
     }
 
     /**
      * 获取server参数
      * @access public
-     * @param string|array $name    数据名称
-     * @param string       $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 数据名称
+     * @param string        $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function server($name = '', $default = null, $filter = '')
@@ -938,9 +891,9 @@ class Request
 
     /**
      * 获取环境变量
-     * @param string|array $name    数据名称
-     * @param string       $default 默认值
-     * @param string|array $filter  过滤方法
+     * @param string|array  $name 数据名称
+     * @param string        $default 默认值
+     * @param string|array  $filter 过滤方法
      * @return mixed
      */
     public function env($name = '', $default = null, $filter = '')
@@ -957,8 +910,8 @@ class Request
     /**
      * 设置或者获取当前的Header
      * @access public
-     * @param string|array $name    header名称
-     * @param string       $default 默认值
+     * @param string|array  $name header名称
+     * @param string        $default 默认值
      * @return string
      */
     public function header($name = '', $default = null)
@@ -996,10 +949,10 @@ class Request
 
     /**
      * 获取变量 支持过滤和默认值
-     * @param array        $data    数据源
-     * @param string|false $name    字段名
-     * @param mixed        $default 默认值
-     * @param string|array $filter  过滤函数
+     * @param array         $data 数据源
+     * @param string|false  $name 字段名
+     * @param mixed         $default 默认值
+     * @param string|array  $filter 过滤函数
      * @return mixed
      */
     public function input($data = [], $name = '', $default = null, $filter = '')
@@ -1031,8 +984,18 @@ class Request
         }
 
         // 解析过滤器
-        $filter = $this->getFilter($filter, $default);
+        if (is_null($filter)) {
+            $filter = [];
+        } else {
+            $filter = $filter ?: $this->filter;
+            if (is_string($filter)) {
+                $filter = explode(',', $filter);
+            } else {
+                $filter = (array) $filter;
+            }
+        }
 
+        $filter[] = $default;
         if (is_array($data)) {
             array_walk_recursive($data, [$this, 'filterValue'], $filter);
             reset($data);
@@ -1061,28 +1024,11 @@ class Request
         }
     }
 
-    protected function getFilter($filter, $default)
-    {
-        if (is_null($filter)) {
-            $filter = [];
-        } else {
-            $filter = $filter ?: $this->filter;
-            if (is_string($filter) && false === strpos($filter, '/')) {
-                $filter = explode(',', $filter);
-            } else {
-                $filter = (array) $filter;
-            }
-        }
-
-        $filter[] = $default;
-        return $filter;
-    }
-
     /**
      * 递归过滤给定的值
-     * @param mixed $value   键值
-     * @param mixed $key     键名
-     * @param array $filters 过滤方法+默认值
+     * @param mixed     $value 键值
+     * @param mixed     $key 键名
+     * @param array     $filters 过滤方法+默认值
      * @return mixed
      */
     private function filterValue(&$value, $key, $filters)
@@ -1093,7 +1039,7 @@ class Request
                 // 调用函数或者方法过滤
                 $value = call_user_func($filter, $value);
             } elseif (is_scalar($value)) {
-                if (false !== strpos($filter, '/')) {
+                if (strpos($filter, '/')) {
                     // 正则过滤
                     if (!preg_match($filter, $value)) {
                         // 匹配不成功返回默认值
@@ -1122,7 +1068,7 @@ class Request
     public function filterExp(&$value)
     {
         // 过滤查询特殊字符
-        if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOT EXISTS|NOTEXISTS|EXISTS|NOT NULL|NOTNULL|NULL|BETWEEN TIME|NOT BETWEEN TIME|NOTBETWEEN TIME|NOTIN|NOT IN|IN)$/i', $value)) {
+        if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {
             $value .= ' ';
         }
         // TODO 其他安全过滤
@@ -1167,9 +1113,9 @@ class Request
     /**
      * 是否存在某个请求参数
      * @access public
-     * @param string $name       变量名
-     * @param string $type       变量类型
-     * @param bool   $checkEmpty 是否检测空值
+     * @param string    $name 变量名
+     * @param string    $type 变量类型
+     * @param bool      $checkEmpty 是否检测空值
      * @return mixed
      */
     public function has($name, $type = 'param', $checkEmpty = false)
@@ -1193,8 +1139,8 @@ class Request
     /**
      * 获取指定的参数
      * @access public
-     * @param string|array $name 变量名
-     * @param string       $type 变量类型
+     * @param string|array  $name 变量名
+     * @param string        $type 变量类型
      * @return mixed
      */
     public function only($name, $type = 'param')
@@ -1215,8 +1161,8 @@ class Request
     /**
      * 排除指定参数获取
      * @access public
-     * @param string|array $name 变量名
-     * @param string       $type 变量类型
+     * @param string|array  $name 变量名
+     * @param string        $type 变量类型
      * @return mixed
      */
     public function except($name, $type = 'param')
@@ -1249,8 +1195,6 @@ class Request
             return true;
         } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) {
             return true;
-        } elseif (Config::get('https_agent_name') && isset($server[Config::get('https_agent_name')])) {
-            return true;
         }
         return false;
     }
@@ -1258,7 +1202,7 @@ class Request
     /**
      * 当前是否Ajax请求
      * @access public
-     * @param bool $ajax true 获取原始ajax请求
+     * @param bool $ajax  true 获取原始ajax请求
      * @return bool
      */
     public function isAjax($ajax = false)
@@ -1268,16 +1212,14 @@ class Request
         if (true === $ajax) {
             return $result;
         } else {
-            $result           = $this->param(Config::get('var_ajax')) ? true : $result;
-            $this->mergeParam = false;
-            return $result;
+            return $this->param(Config::get('var_ajax')) ? true : $result;
         }
     }
 
     /**
      * 当前是否Pjax请求
      * @access public
-     * @param bool $pjax true 获取原始pjax请求
+     * @param bool $pjax  true 获取原始pjax请求
      * @return bool
      */
     public function isPjax($pjax = false)
@@ -1286,19 +1228,17 @@ class Request
         if (true === $pjax) {
             return $result;
         } else {
-            $result           = $this->param(Config::get('var_pjax')) ? true : $result;
-            $this->mergeParam = false;
-            return $result;
+            return $this->param(Config::get('var_pjax')) ? true : $result;
         }
     }
 
     /**
      * 获取客户端IP地址
-     * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
-     * @param boolean $adv  是否进行高级模式获取(有可能被伪装)
+     * @param integer   $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
+     * @param boolean   $adv 是否进行高级模式获取(有可能被伪装)
      * @return mixed
      */
-    public function ip($type = 0, $adv = true)
+    public function ip($type = 0, $adv = false)
     {
         $type      = $type ? 1 : 0;
         static $ip = null;
@@ -1306,11 +1246,7 @@ class Request
             return $ip[$type];
         }
 
-        $httpAgentIp = Config::get('http_agent_ip');
-
-        if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) {
-            $ip = $_SERVER[$httpAgentIp];
-        } elseif ($adv) {
+        if ($adv) {
             if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                 $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                 $pos = array_search('unknown', $arr);
@@ -1375,18 +1311,11 @@ class Request
     /**
      * 当前请求的host
      * @access public
-     * @param bool $strict true 仅仅获取HOST
      * @return string
      */
-    public function host($strict = false)
+    public function host()
     {
-        if (isset($_SERVER['HTTP_X_REAL_HOST'])) {
-            $host = $_SERVER['HTTP_X_REAL_HOST'];
-        } else {
-            $host = $this->server('HTTP_HOST');
-        }
-
-        return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host;
+        return $this->server('HTTP_HOST');
     }
 
     /**
@@ -1428,11 +1357,7 @@ class Request
     {
         $contentType = $this->server('CONTENT_TYPE');
         if ($contentType) {
-            if (strpos($contentType, ';')) {
-                list($type) = explode(';', $contentType);
-            } else {
-                $type = $contentType;
-            }
+            list($type) = explode(';', $contentType);
             return trim($type);
         }
         return '';
@@ -1456,7 +1381,7 @@ class Request
     /**
      * 设置或者获取当前请求的调度信息
      * @access public
-     * @param array $dispatch 调度信息
+     * @param array  $dispatch 调度信息
      * @return array
      */
     public function dispatch($dispatch = null)
@@ -1507,12 +1432,11 @@ class Request
      */
     public function action($action = null)
     {
-        if (!is_null($action) && !is_bool($action)) {
+        if (!is_null($action)) {
             $this->action = $action;
             return $this;
         } else {
-            $name = $this->action ?: '';
-            return true === $action ? $name : strtolower($name);
+            return $this->action ?: '';
         }
     }
 
@@ -1576,19 +1500,12 @@ class Request
     /**
      * 设置当前地址的请求缓存
      * @access public
-     * @param string $key    缓存标识,支持变量规则 ,例如 item/:name/:id
+     * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id
      * @param mixed  $expire 缓存有效期
-     * @param array  $except 缓存排除
-     * @param string $tag    缓存标签
      * @return void
      */
-    public function cache($key, $expire = null, $except = [], $tag = null)
+    public function cache($key, $expire = null)
     {
-        if (!is_array($except)) {
-            $tag    = $except;
-            $except = [];
-        }
-
         if (false !== $key && $this->isGet() && !$this->isCheckCache) {
             // 标记请求缓存检查
             $this->isCheckCache = true;
@@ -1599,11 +1516,6 @@ class Request
             if ($key instanceof \Closure) {
                 $key = call_user_func_array($key, [$this]);
             } elseif (true === $key) {
-                foreach ($except as $rule) {
-                    if (0 === stripos($this->url(), $rule)) {
-                        return;
-                    }
-                }
                 // 自动缓存功能
                 $key = '__URL__';
             } elseif (strpos($key, '|')) {
@@ -1611,7 +1523,7 @@ class Request
             }
             // 特殊规则替换
             if (false !== strpos($key, '__')) {
-                $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url(true))], $key);
+                $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__'], [$this->module, $this->controller, $this->action, md5($this->url())], $key);
             }
 
             if (false !== strpos($key, ':')) {
@@ -1642,7 +1554,7 @@ class Request
                 $response               = Response::create($content)->header($header);
                 throw new \think\exception\HttpResponseException($response);
             } else {
-                $this->cache = [$key, $expire, $tag];
+                $this->cache = [$key, $expire];
             }
         }
     }
@@ -1660,8 +1572,8 @@ class Request
     /**
      * 设置当前请求绑定的对象实例
      * @access public
-     * @param string|array $name 绑定的对象标识
-     * @param mixed        $obj  绑定的对象实例
+     * @param string $name 绑定的对象标识
+     * @param mixed  $obj 绑定的对象实例
      * @return mixed
      */
     public function bind($name, $obj = null)

+ 10 - 14
thinkphp/library/think/Response.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -19,6 +19,7 @@ use think\response\Xml as XmlResponse;
 
 class Response
 {
+
     // 原始数据
     protected $data;
 
@@ -39,7 +40,7 @@ class Response
     protected $content = null;
 
     /**
-     * 构函数
+     * 构函数
      * @access   public
      * @param mixed $data    输出数据
      * @param int   $code
@@ -49,12 +50,12 @@ class Response
     public function __construct($data = '', $code = 200, array $header = [], $options = [])
     {
         $this->data($data);
+        $this->header = $header;
+        $this->code   = $code;
         if (!empty($options)) {
             $this->options = array_merge($this->options, $options);
         }
         $this->contentType($this->contentType, $this->charset);
-        $this->header = array_merge($this->header, $header);
-        $this->code   = $code;
     }
 
     /**
@@ -69,7 +70,9 @@ class Response
      */
     public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])
     {
-        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type));
+        $type = empty($type) ? 'null' : strtolower($type);
+
+        $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type);
         if (class_exists($class)) {
             $response = new $class($data, $code, $header, $options);
         } else {
@@ -87,9 +90,6 @@ class Response
      */
     public function send()
     {
-        // 监听response_send
-        Hook::listen('response_send', $this);
-
         // 处理输出数据
         $data = $this->getContent();
 
@@ -104,7 +104,7 @@ class Response
                 $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';
                 $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
                 $this->header['Expires']       = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';
-                Cache::tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]);
+                Cache::set($cache[0], [$data, $this->header], $cache[1]);
             }
         }
 
@@ -113,11 +113,7 @@ class Response
             http_response_code($this->code);
             // 发送头部信息
             foreach ($this->header as $name => $val) {
-                if (is_null($val)) {
-                    header($name);
-                } else {
-                    header($name . ':' . $val);
-                }
+                header($name . ':' . $val);
             }
         }
 

+ 162 - 217
thinkphp/library/think/Route.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -68,8 +68,8 @@ class Route
     /**
      * 注册变量规则
      * @access public
-     * @param string|array $name 变量名
-     * @param string       $rule 变量规则
+     * @param string|array  $name 变量名
+     * @param string        $rule 变量规则
      * @return void
      */
     public static function pattern($name = null, $rule = '')
@@ -84,10 +84,10 @@ class Route
     /**
      * 注册子域名部署规则
      * @access public
-     * @param string|array $domain  子域名
-     * @param mixed        $rule    路由规则
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string|array  $domain 子域名
+     * @param mixed         $rule 路由规则
+     * @param array         $option 路由参数
+     * @param array         $pattern 变量规则
      * @return void
      */
     public static function domain($domain, $rule = '', $option = [], $pattern = [])
@@ -121,8 +121,8 @@ class Route
     /**
      * 设置路由绑定
      * @access public
-     * @param mixed  $bind 绑定信息
-     * @param string $type 绑定类型 默认为module 支持 namespace class controller
+     * @param mixed     $bind 绑定信息
+     * @param string    $type 绑定类型 默认为module 支持 namespace class controller
      * @return mixed
      */
     public static function bind($bind, $type = 'module')
@@ -133,8 +133,8 @@ class Route
     /**
      * 设置或者获取路由标识
      * @access public
-     * @param string|array $name  路由命名标识 数组表示批量设置
-     * @param array        $value 路由地址及变量信息
+     * @param string|array     $name 路由命名标识 数组表示批量设置
+     * @param array            $value 路由地址及变量信息
      * @return array
      */
     public static function name($name = '', $value = null)
@@ -154,7 +154,7 @@ class Route
     /**
      * 读取路由绑定
      * @access public
-     * @param string $type 绑定类型
+     * @param string    $type 绑定类型
      * @return mixed
      */
     public static function getBind($type)
@@ -165,8 +165,8 @@ class Route
     /**
      * 导入配置文件的路由规则
      * @access public
-     * @param array  $rule 路由规则
-     * @param string $type 请求类型
+     * @param array     $rule 路由规则
+     * @param string    $type 请求类型
      * @return void
      */
     public static function import(array $rule, $type = '*')
@@ -222,17 +222,16 @@ class Route
     /**
      * 注册路由规则
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param string       $type    请求类型
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param string    $type 请求类型
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [])
     {
         $group = self::getGroup('name');
-
         if (!is_null($group)) {
             // 路由分组
             $option  = array_merge(self::getGroup('option'), $option);
@@ -255,11 +254,9 @@ class Route
                     $option1  = array_merge($option, $val[1]);
                     $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []);
                 } else {
-                    $option1  = null;
-                    $pattern1 = null;
-                    $route    = $val;
+                    $route = $val;
                 }
-                self::setRule($key, $route, $type, !is_null($option1) ? $option1 : $option, !is_null($pattern1) ? $pattern1 : $pattern, $group);
+                self::setRule($key, $route, $type, isset($option1) ? $option1 : $option, isset($pattern1) ? $pattern1 : $pattern, $group);
             }
         } else {
             self::setRule($rule, $route, $type, $option, $pattern, $group);
@@ -270,12 +267,12 @@ class Route
     /**
      * 设置路由规则
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param string       $type    请求类型
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
-     * @param string       $group   所属分组
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param string    $type 请求类型
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
+     * @param string    $group 所属分组
      * @return void
      */
     protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '')
@@ -307,12 +304,8 @@ class Route
         }
         $vars = self::parseVar($rule);
         if (isset($name)) {
-            $key    = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
-            $suffix = isset($option['ext']) ? $option['ext'] : null;
-            self::name($name, [$key, $vars, self::$domain, $suffix]);
-        }
-        if (isset($option['modular'])) {
-            $route = $option['modular'] . '/' . $route;
+            $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule;
+            self::name($name, [$key, $vars, self::$domain]);
         }
         if ($group) {
             if ('*' != $type) {
@@ -335,9 +328,9 @@ class Route
             if ('*' == $type) {
                 // 注册路由快捷方式
                 foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {
-                    if (self::$domain && !isset(self::$rules['domain'][self::$domain][$method][$rule])) {
+                    if (self::$domain) {
                         self::$rules['domain'][self::$domain][$method][$rule] = true;
-                    } elseif (!self::$domain && !isset(self::$rules[$method][$rule])) {
+                    } else {
                         self::$rules[$method][$rule] = true;
                     }
                 }
@@ -348,7 +341,7 @@ class Route
     /**
      * 设置当前执行的参数信息
      * @access public
-     * @param array $options 参数信息
+     * @param array    $options 参数信息
      * @return mixed
      */
     protected static function setOption($options = [])
@@ -369,7 +362,7 @@ class Route
     /**
      * 获取当前的分组信息
      * @access public
-     * @param string $type 分组信息名称 name option pattern
+     * @param string    $type 分组信息名称 name option pattern
      * @return mixed
      */
     public static function getGroup($type)
@@ -384,9 +377,9 @@ class Route
     /**
      * 设置当前的路由分组
      * @access public
-     * @param string $name    分组名称
-     * @param array  $option  分组路由参数
-     * @param array  $pattern 分组变量规则
+     * @param string    $name 分组名称
+     * @param array     $option 分组路由参数
+     * @param array     $pattern 分组变量规则
      * @return void
      */
     public static function setGroup($name, $option = [], $pattern = [])
@@ -399,10 +392,10 @@ class Route
     /**
      * 注册路由分组
      * @access public
-     * @param string|array   $name    分组名称或者参数
-     * @param array|\Closure $routes  路由地址
-     * @param array          $option  路由参数
-     * @param array          $pattern 变量规则
+     * @param string|array      $name 分组名称或者参数
+     * @param array|\Closure    $routes 路由地址
+     * @param array             $option 路由参数
+     * @param array             $pattern 变量规则
      * @return void
      */
     public static function group($name, $routes, $option = [], $pattern = [])
@@ -430,8 +423,7 @@ class Route
                     self::$rules['*'][$name]['pattern'] = $pattern;
                 }
             } else {
-                $item          = [];
-                $completeMatch = Config::get('route_complete_match');
+                $item = [];
                 foreach ($routes as $key => $val) {
                     if (is_numeric($key)) {
                         $key = array_shift($val);
@@ -450,15 +442,12 @@ class Route
                         // 是否完整匹配
                         $options['complete_match'] = true;
                         $key                       = substr($key, 0, -1);
-                    } elseif ($completeMatch) {
-                        $options['complete_match'] = true;
                     }
                     $key    = trim($key, '/');
                     $vars   = self::parseVar($key);
                     $item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns];
                     // 设置路由标识
-                    $suffix = isset($options['ext']) ? $options['ext'] : null;
-                    self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain, $suffix]);
+                    self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain]);
                 }
                 self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];
             }
@@ -487,10 +476,10 @@ class Route
     /**
      * 注册路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function any($rule, $route = '', $option = [], $pattern = [])
@@ -501,10 +490,10 @@ class Route
     /**
      * 注册GET路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function get($rule, $route = '', $option = [], $pattern = [])
@@ -515,10 +504,10 @@ class Route
     /**
      * 注册POST路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function post($rule, $route = '', $option = [], $pattern = [])
@@ -529,10 +518,10 @@ class Route
     /**
      * 注册PUT路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function put($rule, $route = '', $option = [], $pattern = [])
@@ -543,10 +532,10 @@ class Route
     /**
      * 注册DELETE路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function delete($rule, $route = '', $option = [], $pattern = [])
@@ -557,10 +546,10 @@ class Route
     /**
      * 注册PATCH路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function patch($rule, $route = '', $option = [], $pattern = [])
@@ -571,10 +560,10 @@ class Route
     /**
      * 注册资源路由
      * @access public
-     * @param string|array $rule    路由规则
-     * @param string       $route   路由地址
-     * @param array        $option  路由参数
-     * @param array        $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function resource($rule, $route = '', $option = [], $pattern = [])
@@ -618,10 +607,10 @@ class Route
     /**
      * 注册控制器路由 操作方法对应不同的请求后缀
      * @access public
-     * @param string $rule    路由规则
-     * @param string $route   路由地址
-     * @param array  $option  路由参数
-     * @param array  $pattern 变量规则
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param array     $option 路由参数
+     * @param array     $pattern 变量规则
      * @return void
      */
     public static function controller($rule, $route = '', $option = [], $pattern = [])
@@ -634,9 +623,9 @@ class Route
     /**
      * 注册别名路由
      * @access public
-     * @param string|array $rule   路由别名
-     * @param string       $route  路由地址
-     * @param array        $option 路由参数
+     * @param string|array  $rule 路由别名
+     * @param string        $route 路由地址
+     * @param array         $option 路由参数
      * @return void
      */
     public static function alias($rule = null, $route = '', $option = [])
@@ -651,8 +640,8 @@ class Route
     /**
      * 设置不同请求类型下面的方法前缀
      * @access public
-     * @param string $method 请求类型
-     * @param string $prefix 类型前缀
+     * @param string    $method 请求类型
+     * @param string    $prefix 类型前缀
      * @return void
      */
     public static function setMethodPrefix($method, $prefix = '')
@@ -667,8 +656,8 @@ class Route
     /**
      * rest方法定义和修改
      * @access public
-     * @param string|array $name     方法名称
-     * @param array|bool   $resource 资源
+     * @param string        $name 方法名称
+     * @param array|bool    $resource 资源
      * @return void
      */
     public static function rest($name, $resource = [])
@@ -683,9 +672,9 @@ class Route
     /**
      * 注册未匹配路由规则后的处理
      * @access public
-     * @param string $route  路由地址
-     * @param string $method 请求类型
-     * @param array  $option 路由参数
+     * @param string    $route 路由地址
+     * @param string    $method 请求类型
+     * @param array     $option 路由参数
      * @return void
      */
     public static function miss($route, $method = '*', $option = [])
@@ -696,7 +685,7 @@ class Route
     /**
      * 注册一个自动解析的URL路由
      * @access public
-     * @param string $route 路由地址
+     * @param string    $route 路由地址
      * @return void
      */
     public static function auto($route)
@@ -726,9 +715,9 @@ class Route
     /**
      * 检测子域名部署
      * @access public
-     * @param Request $request      Request请求对象
-     * @param array   $currentRules 当前路由规则
-     * @param string  $method       请求类型
+     * @param Request   $request Request请求对象
+     * @param array     $currentRules 当前路由规则
+     * @param string    $method 请求类型
      * @return void
      */
     public static function checkDomain($request, &$currentRules, $method = 'get')
@@ -737,7 +726,7 @@ class Route
         $rules = self::$rules['domain'];
         // 开启子域名部署 支持二级和三级域名
         if (!empty($rules)) {
-            $host = $request->host(true);
+            $host = $request->host();
             if (isset($rules[$host])) {
                 // 完整域名或者IP配置
                 $item = $rules[$host];
@@ -827,27 +816,18 @@ class Route
     /**
      * 检测URL路由
      * @access public
-     * @param Request $request     Request请求对象
-     * @param string  $url         URL地址
-     * @param string  $depr        URL分隔符
-     * @param bool    $checkDomain 是否检测域名规则
+     * @param Request   $request Request请求对象
+     * @param string    $url URL地址
+     * @param string    $depr URL分隔符
+     * @param bool      $checkDomain 是否检测域名规则
      * @return false|array
      */
     public static function check($request, $url, $depr = '/', $checkDomain = false)
     {
-        //检查解析缓存
-        if (!App::$debug && Config::get('route_check_cache')) {
-            $key = self::getCheckCacheKey($request);
-            if (Cache::has($key)) {
-                list($rule, $route, $pathinfo, $option, $matches) = Cache::get($key);
-                return self::parseRule($rule, $route, $pathinfo, $option, $matches, true);
-            }
-        }
-
         // 分隔符替换 确保路由定义使用统一的分隔符
         $url = str_replace($depr, '|', $url);
 
-        if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) {
+        if (strpos($url, '|') && isset(self::$rules['alias'][strstr($url, '|', true)])) {
             // 检测路由别名
             $result = self::checkRouteAlias($request, $url, $depr);
             if (false !== $result) {
@@ -856,7 +836,7 @@ class Route
         }
         $method = strtolower($request->method());
         // 获取当前请求类型的路由规则
-        $rules = isset(self::$rules[$method]) ? self::$rules[$method] : [];
+        $rules = self::$rules[$method];
         // 检测域名部署
         if ($checkDomain) {
             self::checkDomain($request, $rules, $method);
@@ -897,12 +877,12 @@ class Route
     /**
      * 检测路由规则
      * @access private
-     * @param Request $request
-     * @param array   $rules   路由规则
-     * @param string  $url     URL地址
-     * @param string  $depr    URL分割符
-     * @param string  $group   路由分组名
-     * @param array   $options 路由参数(分组)
+     * @param Request   $request
+     * @param array     $rules 路由规则
+     * @param string    $url URL地址
+     * @param string    $depr URL分割符
+     * @param string    $group 路由分组名
+     * @param array     $options 路由参数(分组)
      * @return mixed
      */
     private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = [])
@@ -938,7 +918,7 @@ class Route
                 } else {
                     $str = $key;
                 }
-                if (is_string($str) && $str && 0 !== stripos(str_replace('|', '/', $url), $str)) {
+                if (is_string($str) && $str && 0 !== strpos(str_replace('|', '/', $url), $str)) {
                     continue;
                 }
                 self::setOption($option);
@@ -980,9 +960,9 @@ class Route
     /**
      * 检测路由别名
      * @access private
-     * @param Request $request
-     * @param string  $url  URL地址
-     * @param string  $depr URL分隔符
+     * @param Request   $request
+     * @param string    $url URL地址
+     * @param string    $depr URL分隔符
      * @return mixed
      */
     private static function checkRouteAlias($request, $url, $depr)
@@ -1027,9 +1007,9 @@ class Route
     /**
      * 检测URL绑定
      * @access private
-     * @param string $url   URL地址
-     * @param array  $rules 路由规则
-     * @param string $depr  URL分隔符
+     * @param string    $url URL地址
+     * @param array     $rules 路由规则
+     * @param string    $depr URL分隔符
      * @return mixed
      */
     private static function checkUrlBind(&$url, &$rules, $depr = '/')
@@ -1058,9 +1038,9 @@ class Route
     /**
      * 绑定到类
      * @access public
-     * @param string $url   URL地址
-     * @param string $class 类名(带命名空间)
-     * @param string $depr  URL分隔符
+     * @param string    $url URL地址
+     * @param string    $class 类名(带命名空间)
+     * @param string    $depr URL分隔符
      * @return array
      */
     public static function bindToClass($url, $class, $depr = '/')
@@ -1071,15 +1051,15 @@ class Route
         if (!empty($array[1])) {
             self::parseUrlParams($array[1]);
         }
-        return ['type' => 'method', 'method' => [$class, $action], 'var' => []];
+        return ['type' => 'method', 'method' => [$class, $action]];
     }
 
     /**
      * 绑定到命名空间
      * @access public
-     * @param string $url       URL地址
-     * @param string $namespace 命名空间
-     * @param string $depr      URL分隔符
+     * @param string    $url URL地址
+     * @param string    $namespace 命名空间
+     * @param string    $depr URL分隔符
      * @return array
      */
     public static function bindToNamespace($url, $namespace, $depr = '/')
@@ -1091,15 +1071,15 @@ class Route
         if (!empty($array[2])) {
             self::parseUrlParams($array[2]);
         }
-        return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method], 'var' => []];
+        return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method]];
     }
 
     /**
      * 绑定到控制器类
      * @access public
-     * @param string $url        URL地址
-     * @param string $controller 控制器名 (支持带模块名 index/user )
-     * @param string $depr       URL分隔符
+     * @param string    $url URL地址
+     * @param string    $controller 控制器名 (支持带模块名 index/user )
+     * @param string    $depr URL分隔符
      * @return array
      */
     public static function bindToController($url, $controller, $depr = '/')
@@ -1110,15 +1090,15 @@ class Route
         if (!empty($array[1])) {
             self::parseUrlParams($array[1]);
         }
-        return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'var' => []];
+        return ['type' => 'controller', 'controller' => $controller . '/' . $action];
     }
 
     /**
      * 绑定到模块/控制器
      * @access public
-     * @param string $url        URL地址
-     * @param string $controller 控制器类名(带命名空间)
-     * @param string $depr       URL分隔符
+     * @param string    $url URL地址
+     * @param string    $controller 控制器类名(带命名空间)
+     * @param string    $depr URL分隔符
      * @return array
      */
     public static function bindToModule($url, $controller, $depr = '/')
@@ -1135,8 +1115,8 @@ class Route
     /**
      * 路由参数有效性检查
      * @access private
-     * @param array   $option  路由参数
-     * @param Request $request Request对象
+     * @param array     $option 路由参数
+     * @param Request   $request Request对象
      * @return bool
      */
     private static function checkOption($option, $request)
@@ -1146,8 +1126,8 @@ class Route
              || (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测
              || (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测
              || (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测
-             || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) // 伪静态后缀检测
-             || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|'))
+             || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', $request->ext() ? '|' . $request->ext() . '|' : '')) // 伪静态后缀检测
+             || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', $request->ext() ? '|' . $request->ext() . '|' : ''))
             || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测
              || (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测
              || (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测
@@ -1162,18 +1142,18 @@ class Route
     /**
      * 检测路由规则
      * @access private
-     * @param string $rule    路由规则
-     * @param string $route   路由地址
-     * @param string $url     URL地址
-     * @param array  $pattern 变量规则
-     * @param array  $option  路由参数
-     * @param string $depr    URL分隔符(全局)
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param string    $url URL地址
+     * @param array     $pattern 变量规则
+     * @param array     $option 路由参数
+     * @param string    $depr URL分隔符(全局)
      * @return array|false
      */
     private static function checkRule($rule, $route, $url, $pattern, $option, $depr)
     {
         // 检查完整规则定义
-        if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) {
+        if (isset($pattern['__url__']) && !preg_match('/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) {
             return false;
         }
         // 检查路由的参数分隔符
@@ -1184,7 +1164,7 @@ class Route
         $len1 = substr_count($url, '|');
         $len2 = substr_count($rule, '/');
         // 多余参数是否合并
-        $merge = !empty($option['merge_extra_vars']);
+        $merge = !empty($option['merge_extra_vars']) ? true : false;
         if ($merge && $len1 > $len2) {
             $url = str_replace('|', $depr, $url);
             $url = implode('|', explode($depr, $url, $len2 + 1));
@@ -1198,9 +1178,9 @@ class Route
                 }
             }
             $pattern = array_merge(self::$rules['pattern'], $pattern);
-            if (false !== $match = self::match($url, $rule, $pattern)) {
+            if (false !== $match = self::match($url, $rule, $pattern, $merge)) {
                 // 匹配到路由规则
-                return self::parseRule($rule, $route, $url, $option, $match);
+                return self::parseRule($rule, $route, $url, $option, $match, $merge);
             }
         }
         return false;
@@ -1209,9 +1189,9 @@ class Route
     /**
      * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2...
      * @access public
-     * @param string $url        URL地址
-     * @param string $depr       URL分隔符
-     * @param bool   $autoSearch 是否自动深度搜索控制器
+     * @param string    $url URL地址
+     * @param string    $depr URL分隔符
+     * @param bool      $autoSearch 是否自动深度搜索控制器
      * @return array
      */
     public static function parseUrl($url, $depr = '/', $autoSearch = false)
@@ -1278,7 +1258,7 @@ class Route
     /**
      * 解析URL的pathinfo参数和变量
      * @access private
-     * @param string $url URL地址
+     * @param string    $url URL地址
      * @return array
      */
     private static function parseUrlPath($url)
@@ -1295,6 +1275,9 @@ class Route
         } elseif (strpos($url, '/')) {
             // [模块/控制器/操作]
             $path = explode('/', $url);
+        } elseif (false !== strpos($url, '=')) {
+            // 参数1=值1&参数2=值2...
+            parse_str($url, $var);
         } else {
             $path = [$url];
         }
@@ -1304,9 +1287,9 @@ class Route
     /**
      * 检测URL和规则路由是否匹配
      * @access private
-     * @param string $url     URL地址
-     * @param string $rule    路由规则
-     * @param array  $pattern 变量规则
+     * @param string    $url URL地址
+     * @param string    $rule 路由规则
+     * @param array     $pattern 变量规则
      * @return array|false
      */
     private static function match($url, $rule, $pattern)
@@ -1363,7 +1346,7 @@ class Route
                         if (false === $result) {
                             return false;
                         }
-                    } elseif (!preg_match(0 === strpos($pattern[$name], '/') ? $pattern[$name] : '/^' . $pattern[$name] . '$/', $m1[$key])) {
+                    } elseif (!preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) {
                         return false;
                     }
                 }
@@ -1379,28 +1362,16 @@ class Route
     /**
      * 解析规则路由
      * @access private
-     * @param string $rule      路由规则
-     * @param string $route     路由地址
-     * @param string $pathinfo  URL地址
-     * @param array  $option    路由参数
-     * @param array  $matches   匹配的变量
-     * @param bool   $fromCache 通过缓存解析
+     * @param string    $rule 路由规则
+     * @param string    $route 路由地址
+     * @param string    $pathinfo URL地址
+     * @param array     $option 路由参数
+     * @param array     $matches 匹配的变量
      * @return array
      */
-    private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [], $fromCache = false)
+    private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [])
     {
         $request = Request::instance();
-
-        //保存解析缓存
-        if (Config::get('route_check_cache') && !$fromCache) {
-            try {
-                $key = self::getCheckCacheKey($request);
-                Cache::tag('route_check')->set($key, [$rule, $route, $pathinfo, $option, $matches]);
-            } catch (\Exception $e) {
-
-            }
-        }
-
         // 解析路由规则
         if ($rule) {
             $rule = explode('/', $rule);
@@ -1475,10 +1446,6 @@ class Route
             $request->bind($bind);
         }
 
-        if (!empty($option['response'])) {
-            Hook::add('response_send', $option['response']);
-        }
-
         // 解析额外参数
         self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches);
         // 记录匹配的路由信息
@@ -1527,19 +1494,18 @@ class Route
             App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : '');
         } else {
             // 路由到模块/控制器/操作
-            $result = self::parseModule($route, isset($option['convert']) ? $option['convert'] : false);
+            $result = self::parseModule($route);
         }
         // 开启请求缓存
         if ($request->isGet() && isset($option['cache'])) {
             $cache = $option['cache'];
             if (is_array($cache)) {
-                list($key, $expire, $tag) = array_pad($cache, 3, null);
+                list($key, $expire) = $cache;
             } else {
                 $key    = str_replace('|', '/', $pathinfo);
                 $expire = $cache;
-                $tag    = null;
             }
-            $request->cache($key, $expire, $tag);
+            $request->cache($key, $expire);
         }
         return $result;
     }
@@ -1547,11 +1513,10 @@ class Route
     /**
      * 解析URL地址为 模块/控制器/操作
      * @access private
-     * @param string $url     URL地址
-     * @param bool   $convert 是否自动转换URL地址
+     * @param string    $url URL地址
      * @return array
      */
-    private static function parseModule($url, $convert = false)
+    private static function parseModule($url)
     {
         list($path, $var) = self::parseUrlPath($url);
         $action           = array_pop($path);
@@ -1565,14 +1530,14 @@ class Route
         // 设置当前请求的路由变量
         Request::instance()->route($var);
         // 路由到模块/控制器/操作
-        return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => $convert];
+        return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];
     }
 
     /**
      * 解析URL地址中的参数Request对象
      * @access private
-     * @param string $url 路由规则
-     * @param array  $var 变量
+     * @param string    $rule 路由规则
+     * @param array     $var 变量
      * @return void
      */
     private static function parseUrlParams($url, &$var = [])
@@ -1622,24 +1587,4 @@ class Route
         }
         return $var;
     }
-
-    /**
-     * 获取路由解析缓存的key
-     * @param Request $request
-     * @return string
-     */
-    private static function getCheckCacheKey(Request $request)
-    {
-        static $key;
-
-        if (empty($key)) {
-            if ($callback = Config::get('route_check_cache_key')) {
-                $key = call_user_func($callback, $request);
-            } else {
-                $key = "{$request->host(true)}|{$request->method()}|{$request->path()}";
-            }
-        }
-
-        return $key;
-    }
 }

+ 3 - 4
thinkphp/library/think/Session.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -25,7 +25,6 @@ class Session
      */
     public static function prefix($prefix = '')
     {
-        empty(self::$init) && self::boot();
         if (empty($prefix) && null !== $prefix) {
             return self::$prefix;
         } else {
@@ -57,7 +56,7 @@ class Session
             $isDoStart = true;
         }
 
-        if (isset($config['prefix']) && ('' === self::$prefix || null === self::$prefix)) {
+        if (isset($config['prefix'])) {
             self::$prefix = $config['prefix'];
         }
         if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) {
@@ -348,7 +347,7 @@ class Session
      * @param bool $delete 是否删除关联会话文件
      * @return void
      */
-    public static function regenerate($delete = false)
+    private static function regenerate($delete = false)
     {
         session_regenerate_id($delete);
     }

+ 38 - 26
thinkphp/library/think/Template.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -12,7 +12,6 @@
 namespace think;
 
 use think\exception\TemplateNotFoundException;
-use think\template\TagLib;
 
 /**
  * ThinkPHP分离出来的模板引擎
@@ -58,22 +57,17 @@ class Template
     protected $storage;
 
     /**
-     * 构函数
+     * 构函数
      * @access public
-     * @param array $config
      */
     public function __construct(array $config = [])
     {
-        $this->config['cache_path'] = TEMP_PATH;
-        $this->config               = array_merge($this->config, $config);
-
-        $this->config['taglib_begin_origin'] = $this->config['taglib_begin'];
-        $this->config['taglib_end_origin']   = $this->config['taglib_end'];
-
-        $this->config['taglib_begin'] = preg_quote($this->config['taglib_begin'], '/');
-        $this->config['taglib_end']   = preg_quote($this->config['taglib_end'], '/');
-        $this->config['tpl_begin']    = preg_quote($this->config['tpl_begin'], '/');
-        $this->config['tpl_end']      = preg_quote($this->config['tpl_end'], '/');
+        $this->config['cache_path']   = TEMP_PATH;
+        $this->config                 = array_merge($this->config, $config);
+        $this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']);
+        $this->config['taglib_end']   = $this->stripPreg($this->config['taglib_end']);
+        $this->config['tpl_begin']    = $this->stripPreg($this->config['tpl_begin']);
+        $this->config['tpl_end']      = $this->stripPreg($this->config['tpl_end']);
 
         // 初始化模板编译存储器
         $type          = $this->config['compile_type'] ? $this->config['compile_type'] : 'File';
@@ -81,6 +75,20 @@ class Template
         $this->storage = new $class();
     }
 
+    /**
+     * 字符串替换 避免正则混淆
+     * @access private
+     * @param string $str
+     * @return string
+     */
+    private function stripPreg($str)
+    {
+        return str_replace(
+            ['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'],
+            ['\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'],
+            $str);
+    }
+
     /**
      * 模板变量赋值
      * @access public
@@ -112,7 +120,7 @@ class Template
      * 模板引擎配置项
      * @access public
      * @param array|string $config
-     * @return string|void|array
+     * @return void|array
      */
     public function config($config)
     {
@@ -175,7 +183,7 @@ class Template
         }
         $template = $this->parseTemplateFile($template);
         if ($template) {
-            $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($this->config['layout_name'] . $template) . '.' . ltrim($this->config['cache_suffix'], '.');
+            $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . '.' . ltrim($this->config['cache_suffix'], '.');
             if (!$this->checkCache($cacheFile)) {
                 // 缓存无效 重新模板编译
                 $content = file_get_contents($template);
@@ -226,7 +234,7 @@ class Template
      * @access public
      * @param mixed     $name 布局模板名称 false 则关闭布局
      * @param string    $replace 布局模板内容替换标识
-     * @return Template
+     * @return object
      */
     public function layout($name, $replace = '')
     {
@@ -680,7 +688,6 @@ class Template
         } else {
             $className = '\\think\\template\\taglib\\' . ucwords($tagLib);
         }
-        /** @var Taglib $tLib */
         $tLib = new $className($this);
         $tLib->parseTag($content, $hide ? '' : $tagLib);
         return;
@@ -756,26 +763,31 @@ class Template
                             } else {
                                 if (isset($array[1])) {
                                     $this->parseVar($array[2]);
-                                    $express = $name . $array[1] . $array[2];
+                                    $_name = ' && ' . $name . $array[1] . $array[2];
                                 } else {
-                                    $express = false;
+                                    $_name = '';
                                 }
                                 // $name为数组
                                 switch ($first) {
                                     case '?':
                                         // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx
-                                        $str = '<?php echo ' . ($express ?: 'isset(' . $name . ')') . '?' . $name . ':' . substr($str, 1) . '; ?>';
+                                        $str = '<?php echo isset(' . $name . ')' . $_name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';
                                         break;
                                     case '=':
                                         // {$varname?='xxx'} $varname为真时才输出xxx
-                                        $str = '<?php if(' . ($express ?: '!empty(' . $name . ')') . ') echo ' . substr($str, 1) . '; ?>';
+                                        $str = '<?php if(!empty(' . $name . ')' . $_name . ') echo ' . substr($str, 1) . '; ?>';
                                         break;
                                     case ':':
                                         // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx
-                                        $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . '?' . $name . $str . '; ?>';
+                                        $str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $name . $str . '; ?>';
                                         break;
                                     default:
-                                        $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . '?' . $str . '; ?>';
+                                        if (strpos($str, ':')) {
+                                            // {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b
+                                            $str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $str . '; ?>';
+                                        } else {
+                                            $str = '<?php echo ' . $_name . '?' . $str . '; ?>';
+                                        }
                                 }
                             }
                         } else {
@@ -915,7 +927,7 @@ class Template
                         if (false === strpos($name, '(')) {
                             $name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')';
                         } else {
-                            $name = '(' . $name . ' ?: ' . $args[1] . ')';
+                            $name = '(' . $name . ' !== \'\'?' . $name . ':' . $args[1] . ')';
                         }
                         break;
                     default: // 通用模板函数
@@ -1063,7 +1075,7 @@ class Template
             } else {
                 $path = isset($module) ? APP_PATH . $module . DS . basename($this->config['view_path']) . DS : $this->config['view_path'];
             }
-            $template = realpath($path . $template . '.' . ltrim($this->config['view_suffix'], '.'));
+            $template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.');
         }
 
         if (is_file($template)) {

+ 18 - 32
thinkphp/library/think/Url.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -80,9 +80,6 @@ class Url
             if (!empty($match[1])) {
                 $domain = $match[1];
             }
-            if (!is_null($match[2])) {
-                $suffix = $match[2];
-            }
         } elseif (!empty($rule) && isset($name)) {
             throw new \InvalidArgumentException('route name not exists:' . $name);
         } else {
@@ -118,7 +115,7 @@ class Url
             $type = Route::getBind('type');
             if ($type) {
                 $bind = Route::getBind($type);
-                if ($bind && 0 === strpos($url, $bind)) {
+                if (0 === strpos($url, $bind)) {
                     $url = substr($url, strlen($bind) + 1);
                 }
             }
@@ -135,7 +132,7 @@ class Url
         if (!empty($vars)) {
             // 添加参数
             if (Config::get('url_common_param')) {
-                $vars = http_build_query($vars);
+                $vars = urldecode(http_build_query($vars));
                 $url .= $suffix . '?' . $vars . $anchor;
             } else {
                 $paramType = Config::get('url_param_type');
@@ -156,8 +153,7 @@ class Url
         // 检测域名
         $domain = self::parseDomain($url, $domain);
         // URL组装
-        $url = $domain . rtrim(self::$root ?: Request::instance()->root(), '/') . '/' . ltrim($url, '/');
-
+        $url             = $domain . (self::$root ?: Request::instance()->root()) . '/' . ltrim($url, '/');
         self::$bindCheck = false;
         return $url;
     }
@@ -210,21 +206,17 @@ class Url
             }
             $module = $module ? $module . '/' : '';
 
-            $controller = $request->controller();
+            $controller = Loader::parseName($request->controller());
             if ('' == $url) {
                 // 空字符串输出当前的 模块/控制器/操作
-                $action = $request->action();
+                $url = $module . $controller . '/' . $request->action();
             } else {
                 $path       = explode('/', $url);
-                $action     = array_pop($path);
-                $controller = empty($path) ? $controller : array_pop($path);
+                $action     = Config::get('url_convert') ? strtolower(array_pop($path)) : array_pop($path);
+                $controller = empty($path) ? $controller : (Config::get('url_convert') ? Loader::parseName(array_pop($path)) : array_pop($path));
                 $module     = empty($path) ? $module : array_pop($path) . '/';
+                $url        = $module . $controller . '/' . $action;
             }
-            if (Config::get('url_convert')) {
-                $action     = strtolower($action);
-                $controller = Loader::parseName($controller);
-            }
-            $url = $module . $controller . '/' . $action;
         }
         return $url;
     }
@@ -239,7 +231,7 @@ class Url
         $rootDomain = Config::get('url_domain_root');
         if (true === $domain) {
             // 自动判断域名
-            $domain = Config::get('app_host') ?: $request->host();
+            $domain = $request->host();
 
             $domains = Route::rules('domain');
             if ($domains) {
@@ -269,19 +261,14 @@ class Url
 
         } else {
             if (empty($rootDomain)) {
-                $host       = Config::get('app_host') ?: $request->host();
+                $host       = $request->host();
                 $rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host;
             }
-            if (substr_count($domain, '.') < 2 && !strpos($domain, $rootDomain)) {
+            if (!strpos($domain, $rootDomain)) {
                 $domain .= '.' . $rootDomain;
             }
         }
-        if (false !== strpos($domain, '://')) {
-            $scheme = '';
-        } else {
-            $scheme = $request->isSsl() || Config::get('is_https') ? 'https://' : 'http://';
-        }
-        return $scheme . $domain;
+        return ($request->isSsl() ? 'https://' : 'http://') . $domain;
     }
 
     // 解析URL后缀
@@ -300,19 +287,18 @@ class Url
     public static function getRuleUrl($rule, &$vars = [])
     {
         foreach ($rule as $item) {
-            list($url, $pattern, $domain, $suffix) = $item;
+            list($url, $pattern, $domain) = $item;
             if (empty($pattern)) {
-                return [rtrim($url, '$'), $domain, $suffix];
+                return [$url, $domain];
             }
-            $type = Config::get('url_common_param');
             foreach ($pattern as $key => $val) {
                 if (isset($vars[$key])) {
-                    $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url);
+                    $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url);
                     unset($vars[$key]);
-                    $result = [$url, $domain, $suffix];
+                    $result = [$url, $domain];
                 } elseif (2 == $val) {
                     $url    = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);
-                    $result = [$url, $domain, $suffix];
+                    $result = [$url, $domain];
                 } else {
                     break;
                 }

+ 121 - 218
thinkphp/library/think/Validate.php

@@ -2,7 +2,7 @@
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
 // +----------------------------------------------------------------------
-// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.
 // +----------------------------------------------------------------------
 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 // +----------------------------------------------------------------------
@@ -36,56 +36,54 @@ class Validate
 
     // 验证规则默认提示信息
     protected static $typeMsg = [
-        'require'     => ':attribute require',
-        'number'      => ':attribute must be numeric',
-        'integer'     => ':attribute must be integer',
-        'float'       => ':attribute must be float',
-        'boolean'     => ':attribute must be bool',
-        'email'       => ':attribute not a valid email address',
-        'array'       => ':attribute must be a array',
-        'accepted'    => ':attribute must be yes,on or 1',
-        'date'        => ':attribute not a valid datetime',
-        'file'        => ':attribute not a valid file',
-        'image'       => ':attribute not a valid image',
-        'alpha'       => ':attribute must be alpha',
-        'alphaNum'    => ':attribute must be alpha-numeric',
-        'alphaDash'   => ':attribute must be alpha-numeric, dash, underscore',
-        'activeUrl'   => ':attribute not a valid domain or ip',
-        'chs'         => ':attribute must be chinese',
-        'chsAlpha'    => ':attribute must be chinese or alpha',
-        'chsAlphaNum' => ':attribute must be chinese,alpha-numeric',
-        'chsDash'     => ':attribute must be chinese,alpha-numeric,underscore, dash',
-        'url'         => ':attribute not a valid url',
-        'ip'          => ':attribute not a valid ip',
-        'dateFormat'  => ':attribute must be dateFormat of :rule',
-        'in'          => ':attribute must be in :rule',
-        'notIn'       => ':attribute be notin :rule',
-        'between'     => ':attribute must between :1 - :2',
-        'notBetween'  => ':attribute not between :1 - :2',
-        'length'      => 'size of :attribute must be :rule',
-        'max'         => 'max size of :attribute must be :rule',
-        'min'         => 'min size of :attribute must be :rule',
-        'after'       => ':attribute cannot be less than :rule',
-        'before'      => ':attribute cannot exceed :rule',
-        'afterWith'   => ':attribute cannot be less than :rule',
-        'beforeWith'  => ':attribute cannot exceed :rule',
-        'expire'      => ':attribute not within :rule',
-        'allowIp'     => 'access IP is not allowed',
-        'denyIp'      => 'access IP denied',
-        'confirm'     => ':attribute out of accord with :2',
-        'different'   => ':attribute cannot be same with :2',
-        'egt'         => ':attribute must greater than or equal :rule',
-        'gt'          => ':attribute must greater than :rule',
-        'elt'         => ':attribute must less than or equal :rule',
-        'lt'          => ':attribute must less than :rule',
-        'eq'          => ':attribute must equal :rule',
-        'unique'      => ':attribute has exists',
-        'regex'       => ':attribute not conform to the rules',
-        'method'      => 'invalid Request method',
-        'token'       => 'invalid token',
-        'fileSize'    => 'filesize not match',
-        'fileExt'     => 'extensions to upload is not allowed',
-        'fileMime'    => 'mimetype to upload is not allowed',
+        'require'     => ':attribute不能为空',
+        'number'      => ':attribute必须是数字',
+        'float'       => ':attribute必须是浮点数',
+        'boolean'     => ':attribute必须是布尔值',
+        'email'       => ':attribute格式不符',
+        'array'       => ':attribute必须是数组',
+        'accepted'    => ':attribute必须是yes、on或者1',
+        'date'        => ':attribute格式不符合',
+        'file'        => ':attribute不是有效的上传文件',
+        'image'       => ':attribute不是有效的图像文件',
+        'alpha'       => ':attribute只能是字母',
+        'alphaNum'    => ':attribute只能是字母和数字',
+        'alphaDash'   => ':attribute只能是字母、数字和下划线_及破折号-',
+        'activeUrl'   => ':attribute不是有效的域名或者IP',
+        'chs'         => ':attribute只能是汉字',
+        'chsAlpha'    => ':attribute只能是汉字、字母',
+        'chsAlphaNum' => ':attribute只能是汉字、字母和数字',
+        'chsDash'     => ':attribute只能是汉字、字母、数字和下划线_及破折号-',
+        'url'         => ':attribute不是有效的URL地址',
+        'ip'          => ':attribute不是有效的IP地址',
+        'dateFormat'  => ':attribute必须使用日期格式 :rule',
+        'in'          => ':attribute必须在 :rule 范围内',
+        'notIn'       => ':attribute不能在 :rule 范围内',
+        'between'     => ':attribute只能在 :1 - :2 之间',
+        'notBetween'  => ':attribute不能在 :1 - :2 之间',
+        'length'      => ':attribute长度不符合要求 :rule',
+        'max'         => ':attribute长度不能超过 :rule',
+        'min'         => ':attribute长度不能小于 :rule',
+        'after'       => ':attribute日期不能小于 :rule',
+        'before'      => ':attribute日期不能超过 :rule',
+        'expire'      => '不在有效期内 :rule',
+        'allowIp'     => '不允许的IP访问',
+        'denyIp'      => '禁止的IP访问',
+        'confirm'     => ':attribute和确认字段:2不一致',
+        'different'   => ':attribute和比较字段:2不能相同',
+        'egt'         => ':attribute必须大于等于 :rule',
+        'gt'          => ':attribute必须大于 :rule',
+        'elt'         => ':attribute必须小于等于 :rule',
+        'lt'          => ':attribute必须小于 :rule',
+        'eq'          => ':attribute必须等于 :rule',
+        'unique'      => ':attribute已存在',
+        'regex'       => ':attribute不符合指定规则',
+        'method'      => '无效的请求类型',
+        'token'       => '令牌数据无效',
+        'fileSize'    => '上传文件大小不符',
+        'fileExt'     => '上传文件后缀不符',
+        'fileMime'    => '上传文件类型不符',
+
     ];
 
     // 当前验证场景
@@ -104,7 +102,7 @@ class Validate
     protected $batch = false;
 
     /**
-     * 构函数
+     * 构函数
      * @access public
      * @param array $rules 验证规则
      * @param array $message 验证提示信息
@@ -167,7 +165,7 @@ class Validate
     }
 
     /**
-     * 设置验证规则的默认提示信息
+     * 获取验证规则的默认提示信息
      * @access protected
      * @param string|array  $type  验证规则类型名称或者数组
      * @param string        $msg  验证提示信息
@@ -341,41 +339,6 @@ class Validate
         return !empty($this->error) ? false : true;
     }
 
-    /**
-     * 根据验证规则验证数据
-     * @access protected
-     * @param  mixed     $value 字段值
-     * @param  mixed     $rules 验证规则
-     * @return bool
-     */
-    protected function checkRule($value, $rules)
-    {
-        if ($rules instanceof \Closure) {
-            return call_user_func_array($rules, [$value]);
-        } elseif (is_string($rules)) {
-            $rules = explode('|', $rules);
-        }
-
-        foreach ($rules as $key => $rule) {
-            if ($rule instanceof \Closure) {
-                $result = call_user_func_array($rule, [$value]);
-            } else {
-                // 判断验证类型
-                list($type, $rule) = $this->getValidateType($key, $rule);
-
-                $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];
-
-                $result = call_user_func_array($callback, [$value, $rule]);
-            }
-
-            if (true !== $result) {
-                return $result;
-            }
-        }
-
-        return true;
-    }
-
     /**
      * 验证单个字段规则
      * @access protected
@@ -400,7 +363,25 @@ class Validate
                 $info   = is_numeric($key) ? '' : $key;
             } else {
                 // 判断验证类型
-                list($type, $rule, $info) = $this->getValidateType($key, $rule);
+                if (is_numeric($key)) {
+                    if (strpos($rule, ':')) {
+                        list($type, $rule) = explode(':', $rule, 2);
+                        if (isset($this->alias[$type])) {
+                            // 判断别名
+                            $type = $this->alias[$type];
+                        }
+                        $info = $type;
+                    } elseif (method_exists($this, $rule)) {
+                        $type = $rule;
+                        $info = $rule;
+                        $rule = '';
+                    } else {
+                        $type = 'is';
+                        $info = $rule;
+                    }
+                } else {
+                    $info = $type = $key;
+                }
 
                 // 如果不是require 有数据才会行验证
                 if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) {
@@ -436,39 +417,6 @@ class Validate
         return $result;
     }
 
-    /**
-     * 获取当前验证类型及规则
-     * @access public
-     * @param  mixed     $key
-     * @param  mixed     $rule
-     * @return array
-     */
-    protected function getValidateType($key, $rule)
-    {
-        // 判断验证类型
-        if (!is_numeric($key)) {
-            return [$key, $rule, $key];
-        }
-
-        if (strpos($rule, ':')) {
-            list($type, $rule) = explode(':', $rule, 2);
-            if (isset($this->alias[$type])) {
-                // 判断别名
-                $type = $this->alias[$type];
-            }
-            $info = $type;
-        } elseif (method_exists($this, $rule)) {
-            $type = $rule;
-            $info = $rule;
-            $rule = '';
-        } else {
-            $type = 'is';
-            $info = $rule;
-        }
-
-        return [$type, $rule, $info];
-    }
-
     /**
      * 验证是否和某个字段的值一致
      * @access protected
@@ -508,13 +456,11 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function egt($value, $rule, $data)
+    protected function egt($value, $rule)
     {
-        $val = $this->getDataValue($data, $rule);
-        return !is_null($val) && $value >= $val;
+        return $value >= $rule;
     }
 
     /**
@@ -522,13 +468,11 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function gt($value, $rule, $data)
+    protected function gt($value, $rule)
     {
-        $val = $this->getDataValue($data, $rule);
-        return !is_null($val) && $value > $val;
+        return $value > $rule;
     }
 
     /**
@@ -536,13 +480,11 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function elt($value, $rule, $data)
+    protected function elt($value, $rule)
     {
-        $val = $this->getDataValue($data, $rule);
-        return !is_null($val) && $value <= $val;
+        return $value <= $rule;
     }
 
     /**
@@ -550,13 +492,11 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function lt($value, $rule, $data)
+    protected function lt($value, $rule)
     {
-        $val = $this->getDataValue($data, $rule);
-        return !is_null($val) && $value < $val;
+        return $value < $rule;
     }
 
     /**
@@ -628,7 +568,7 @@ class Validate
                 break;
             case 'ip':
                 // 是否为IP地址
-                $result = $this->filter($value, [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6]);
+                $result = $this->filter($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6);
                 break;
             case 'url':
                 // 是否为一个URL地址
@@ -684,12 +624,8 @@ class Validate
         if (function_exists('exif_imagetype')) {
             return exif_imagetype($image);
         } else {
-            try {
-                $info = getimagesize($image);
-                return $info ? $info[2] : false;
-            } catch (\Exception $e) {
-                return false;
-            }
+            $info = getimagesize($image);
+            return $info[2];
         }
     }
 
@@ -720,7 +656,7 @@ class Validate
         if (!in_array($rule, ['ipv4', 'ipv6'])) {
             $rule = 'ipv4';
         }
-        return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]);
+        return $this->filter($value, FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4);
     }
 
     /**
@@ -732,17 +668,21 @@ class Validate
      */
     protected function fileExt($file, $rule)
     {
+        if (!($file instanceof File)) {
+            return false;
+        }
+        if (is_string($rule)) {
+            $rule = explode(',', $rule);
+        }
         if (is_array($file)) {
             foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkExt($rule)) {
+                if (!$item->checkExt($rule)) {
                     return false;
                 }
             }
             return true;
-        } elseif ($file instanceof File) {
-            return $file->checkExt($rule);
         } else {
-            return false;
+            return $file->checkExt($rule);
         }
     }
 
@@ -755,17 +695,21 @@ class Validate
      */
     protected function fileMime($file, $rule)
     {
+        if (!($file instanceof File)) {
+            return false;
+        }
+        if (is_string($rule)) {
+            $rule = explode(',', $rule);
+        }
         if (is_array($file)) {
             foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkMime($rule)) {
+                if (!$item->checkMime($rule)) {
                     return false;
                 }
             }
             return true;
-        } elseif ($file instanceof File) {
-            return $file->checkMime($rule);
         } else {
-            return false;
+            return $file->checkMime($rule);
         }
     }
 
@@ -778,17 +722,18 @@ class Validate
      */
     protected function fileSize($file, $rule)
     {
+        if (!($file instanceof File)) {
+            return false;
+        }
         if (is_array($file)) {
             foreach ($file as $item) {
-                if (!($item instanceof File) || !$item->checkSize($rule)) {
+                if (!$item->checkSize($rule)) {
                     return false;
                 }
             }
             return true;
-        } elseif ($file instanceof File) {
-            return $file->checkSize($rule);
         } else {
-            return false;
+            return $file->checkSize($rule);
         }
     }
 
@@ -880,26 +825,21 @@ class Validate
             // 支持多个字段验证
             $fields = explode('^', $key);
             foreach ($fields as $key) {
-                if (isset($data[$key])) {
-                    $map[$key] = $data[$key];
-                }
+                $map[$key] = $data[$key];
             }
         } elseif (strpos($key, '=')) {
             parse_str($key, $map);
-        } elseif (isset($data[$field])) {
-            $map[$key] = $data[$field];
         } else {
-            $map = [];
+            $map[$key] = $data[$field];
         }
 
-        $pk = isset($rule[3]) ? $rule[3] : $db->getPk();
-        if (is_string($pk)) {
-            if (isset($rule[2])) {
-                $map[$pk] = ['neq', $rule[2]];
-            } elseif (isset($data[$pk])) {
-                $map[$pk] = ['neq', $data[$pk]];
-            }
+        $pk = strval(isset($rule[3]) ? $rule[3] : $db->getPk());
+        if (isset($rule[2])) {
+            $map[$pk] = ['neq', $rule[2]];
+        } elseif (isset($data[$pk])) {
+            $map[$pk] = ['neq', $data[$pk]];
         }
+
         if ($db->where($map)->field($pk)->find()) {
             return false;
         }
@@ -932,7 +872,6 @@ class Validate
             list($rule, $param) = explode(',', $rule);
         } elseif (is_array($rule)) {
             $param = isset($rule[1]) ? $rule[1] : null;
-            $rule  = $rule[0];
         } else {
             $param = null;
         }
@@ -951,7 +890,7 @@ class Validate
     {
         list($field, $val) = explode(',', $rule);
         if ($this->getDataValue($data, $field) == $val) {
-            return !empty($value) || '0' == $value;
+            return !empty($value);
         } else {
             return true;
         }
@@ -969,7 +908,7 @@ class Validate
     {
         $result = call_user_func_array($rule, [$value, $data]);
         if ($result) {
-            return !empty($value) || '0' == $value;
+            return !empty($value);
         } else {
             return true;
         }
@@ -987,7 +926,7 @@ class Validate
     {
         $val = $this->getDataValue($data, $rule);
         if (!empty($val)) {
-            return !empty($value) || '0' == $value;
+            return !empty($value);
         } else {
             return true;
         }
@@ -1119,10 +1058,9 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function after($value, $rule, $data)
+    protected function after($value, $rule)
     {
         return strtotime($value) >= strtotime($rule);
     }
@@ -1132,42 +1070,13 @@ class Validate
      * @access protected
      * @param mixed     $value  字段值
      * @param mixed     $rule  验证规则
-     * @param array     $data  数据
      * @return bool
      */
-    protected function before($value, $rule, $data)
+    protected function before($value, $rule)
     {
         return strtotime($value) <= strtotime($rule);
     }
 
-    /**
-     * 验证日期字段
-     * @access protected
-     * @param mixed     $value  字段值
-     * @param mixed     $rule  验证规则
-     * @param array     $data  数据
-     * @return bool
-     */
-    protected function afterWith($value, $rule, $data)
-    {
-        $rule = $this->getDataValue($data, $rule);
-        return !is_null($rule) && strtotime($value) >= strtotime($rule);
-    }
-
-    /**
-     * 验证日期字段
-     * @access protected
-     * @param mixed     $value  字段值
-     * @param mixed     $rule  验证规则
-     * @param array     $data  数据
-     * @return bool
-     */
-    protected function beforeWith($value, $rule, $data)
-    {
-        $rule = $this->getDataValue($data, $rule);
-        return !is_null($rule) && strtotime($value) <= strtotime($rule);
-    }
-
     /**
      * 验证有效期
      * @access protected
@@ -1231,7 +1140,7 @@ class Validate
             // 不是正则表达式则两端补上/
             $rule = '/^' . $rule . '$/';
         }
-        return is_scalar($value) && 1 === preg_match($rule, (string) $value);
+        return 1 === preg_match($rule, (string) $value);
     }
 
     /**
@@ -1270,15 +1179,13 @@ class Validate
     /**
      * 获取数据值
      * @access protected
-     * @param array $data 数据
-     * @param string $key 数据标识 支持二维
+     * @param array     $data  数据
+     * @param string    $key  数据标识 支持二维
      * @return mixed
      */
     protected function getDataValue($data, $key)
     {
-        if (is_numeric($key)) {
-            $value = $key;
-        } elseif (strpos($key, '.')) {
+        if (strpos($key, '.')) {
             // 支持二维数组验证
             list($name1, $name2) = explode('.', $key);
             $value               = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null;
@@ -1307,16 +1214,12 @@ class Validate
             $msg = $this->message[$attribute];
         } elseif (isset(self::$typeMsg[$type])) {
             $msg = self::$typeMsg[$type];
-        } elseif (0 === strpos($type, 'require')) {
-            $msg = self::$typeMsg['require'];
         } else {
-            $msg = $title . Lang::get('not conform to the rules');
+            $msg = $title . '规则错误';
         }
 
         if (is_string($msg) && 0 === strpos($msg, '{%')) {
             $msg = Lang::get(substr($msg, 2, -1));
-        } elseif (Lang::has($msg)) {
-            $msg = Lang::get($msg);
         }
 
         if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) {

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است