diff --git a/thinkphp/convention.php b/thinkphp/convention.php
index 4cae2c34c..3e2d31ffb 100644
--- a/thinkphp/convention.php
+++ b/thinkphp/convention.php
@@ -138,6 +138,8 @@ return [
     // +----------------------------------------------------------------------
 
     'template' => [
+        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
+        'auto_rule'    => 1,
         // 模板引擎类型 支持 php think 支持扩展
         'type'         => 'Think',
         // 视图基础目录,配置目录为所有模块的视图起始目录
diff --git a/thinkphp/helper.php b/thinkphp/helper.php
index 18ade67df..30670f9f1 100644
--- a/thinkphp/helper.php
+++ b/thinkphp/helper.php
@@ -29,7 +29,6 @@ use think\facade\Request;
 use think\facade\Route;
 use think\facade\Session;
 use think\facade\Url;
-use think\Loader;
 use think\Response;
 use think\route\RuleItem;
 
@@ -659,10 +658,6 @@ if (!function_exists('view')) {
      */
     function view($template = '', $vars = [], $code = 200, $filter = null)
     {
-        if ('' === $template) {
-            $template = Loader::parseName(request()->action(true));
-        }
-
         return Response::create($template, 'view', $code)->assign($vars)->filter($filter);
     }
 }
diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php
index fb59cfd8c..6da1888b5 100644
--- a/thinkphp/library/think/App.php
+++ b/thinkphp/library/think/App.php
@@ -20,7 +20,7 @@ use think\route\Dispatch;
  */
 class App implements \ArrayAccess
 {
-    const VERSION = '5.1.7';
+    const VERSION = '5.1.8';
 
     /**
      * 当前模块路径
@@ -269,12 +269,13 @@ class App implements \ArrayAccess
             if ('' == $module) {
                 // 加载系统助手函数
                 include $this->thinkPath . 'helper.php';
-                // 加载全局中间件
-                if (is_file($path . 'middleware.php')) {
-                    $middleware = include $path . 'middleware.php';
-                    if (is_array($middleware)) {
-                        $this->middleware->import($middleware);
-                    }
+            }
+
+            // 加载中间件
+            if (is_file($path . 'middleware.php')) {
+                $middleware = include $path . 'middleware.php';
+                if (is_array($middleware)) {
+                    $this->middleware->import($middleware);
                 }
             }
 
@@ -492,6 +493,10 @@ class App implements \ArrayAccess
             }
         }
 
+        if (is_file($this->runtimePath . 'rule_regex.php')) {
+            $this->route->setRuleRegexs(include $this->runtimePath . 'rule_regex.php');
+        }
+
         // 是否强制路由模式
         $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');
 
diff --git a/thinkphp/library/think/Container.php b/thinkphp/library/think/Container.php
index b138e6003..08c48a076 100644
--- a/thinkphp/library/think/Container.php
+++ b/thinkphp/library/think/Container.php
@@ -165,7 +165,7 @@ class Container
      * 创建类的实例
      * @access public
      * @param  string        $abstract       类名或者标识
-     * @param  array|true    $args           变量
+     * @param  array|true    $vars           变量
      * @param  bool          $newInstance    是否每次创建新的实例
      * @return object
      */
diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php
index 28909c89f..ffa381866 100644
--- a/thinkphp/library/think/Controller.php
+++ b/thinkphp/library/think/Controller.php
@@ -118,10 +118,6 @@ class Controller
      */
     protected function fetch($template = '', $vars = [], $config = [])
     {
-        if ('' === $template) {
-            $template = Loader::parseName($this->request->action(true));
-        }
-
         return $this->view->fetch($template, $vars, $config);
     }
 
diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php
index d8065f23c..6354f9e47 100644
--- a/thinkphp/library/think/Loader.php
+++ b/thinkphp/library/think/Loader.php
@@ -58,7 +58,9 @@ class Loader
         // 注册系统自动加载
         spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
 
-        $path = realpath(dirname($_SERVER['SCRIPT_FILENAME']));
+        $scriptName = 'cli' == PHP_SAPI ? getcwd() . DIRECTORY_SEPARATOR . $_SERVER['argv'][0] : $_SERVER['SCRIPT_FILENAME'];
+
+        $path = realpath(dirname($scriptName));
 
         if ('cli-server' == PHP_SAPI || !is_file('./think')) {
             $rootPath = dirname($path) . DIRECTORY_SEPARATOR;
diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php
index 0e8248dfd..b584ee78f 100644
--- a/thinkphp/library/think/Log.php
+++ b/thinkphp/library/think/Log.php
@@ -80,6 +80,9 @@ class Log implements LoggerInterface
         $this->config = $config;
 
         unset($config['type']);
+        if (!empty($config['close'])) {
+            $this->allowWrite = false;
+        }
 
         if (class_exists($class)) {
             $this->driver = new $class($config);
diff --git a/thinkphp/library/think/Middleware.php b/thinkphp/library/think/Middleware.php
index 296de275b..6c2d22116 100644
--- a/thinkphp/library/think/Middleware.php
+++ b/thinkphp/library/think/Middleware.php
@@ -11,6 +11,10 @@
 
 namespace think;
 
+use InvalidArgumentException;
+use LogicException;
+use think\exception\HttpResponseException;
+
 class Middleware
 {
     protected $queue = [];
@@ -33,7 +37,9 @@ class Middleware
 
         $middleware = $this->buildMiddleware($middleware);
 
-        $this->queue[] = $middleware;
+        if ($middleware) {
+            $this->queue[] = $middleware;
+        }
     }
 
     /**
@@ -47,7 +53,9 @@ class Middleware
 
         $middleware = $this->buildMiddleware($middleware);
 
-        array_unshift($this->queue, $middleware);
+        if ($middleware) {
+            array_unshift($this->queue, $middleware);
+        }
     }
 
     /**
@@ -73,25 +81,27 @@ class Middleware
         }
 
         if ($middleware instanceof \Closure) {
-            return [$middleware, null];
+            return [$middleware, isset($param) ? $param : null];
         }
 
         if (!is_string($middleware)) {
-            throw new \InvalidArgumentException('The middleware is invalid');
+            throw new InvalidArgumentException('The middleware is invalid');
         }
 
         if (false === strpos($middleware, '\\')) {
-            $value = Container::get('config')->get('middleware.' . $middleware);
-            $class = $value ?: Container::get('app')->getNamespace() . '\\http\\middleware\\' . $middleware;
-        } else {
-            $class = $middleware;
+            $value      = Container::get('config')->get('middleware.' . $middleware);
+            $middleware = $value ?: Container::get('app')->getNamespace() . '\\http\\middleware\\' . $middleware;
         }
 
-        if (strpos($class, ':')) {
-            list($class, $param) = explode(':', $class, 2);
+        if (is_array($middleware)) {
+            return $this->import($middleware);
         }
 
-        return [[Container::get($class), 'handle'], isset($param) ? $param : null];
+        if (strpos($middleware, ':')) {
+            list($middleware, $param) = explode(':', $middleware, 2);
+        }
+
+        return [[Container::get($middleware), 'handle'], isset($param) ? $param : null];
     }
 
     protected function resolve()
@@ -99,19 +109,23 @@ class Middleware
         return function (Request $request) {
             $middleware = array_shift($this->queue);
 
-            if (null !== $middleware) {
-                list($call, $param) = $middleware;
-
-                $response = call_user_func_array($call, [$request, $this->resolve(), $param]);
-
-                if (!$response instanceof Response) {
-                    throw new \LogicException('The middleware must return Response instance');
-                }
-
-                return $response;
-            } else {
-                throw new \InvalidArgumentException('The queue was exhausted, with no response returned');
+            if (null === $middleware) {
+                throw new InvalidArgumentException('The queue was exhausted, with no response returned');
             }
+
+            list($call, $param) = $middleware;
+
+            try {
+                $response = call_user_func_array($call, [$request, $this->resolve(), $param]);
+            } catch (HttpResponseException $exception) {
+                $response = $exception->getResponse();
+            }
+
+            if (!$response instanceof Response) {
+                throw new LogicException('The middleware must return Response instance');
+            }
+
+            return $response;
         };
     }
 
diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php
index 66b88ce9c..16db947bb 100644
--- a/thinkphp/library/think/Request.php
+++ b/thinkphp/library/think/Request.php
@@ -323,10 +323,12 @@ class Request
         $server['PATH_INFO']      = '';
         $server['REQUEST_METHOD'] = strtoupper($method);
         $info                     = parse_url($uri);
+
         if (isset($info['host'])) {
             $server['SERVER_NAME'] = $info['host'];
             $server['HTTP_HOST']   = $info['host'];
         }
+
         if (isset($info['scheme'])) {
             if ('https' === $info['scheme']) {
                 $server['HTTPS']       = 'on';
@@ -336,27 +338,34 @@ class Request
                 $server['SERVER_PORT'] = 80;
             }
         }
+
         if (isset($info['port'])) {
             $server['SERVER_PORT'] = $info['port'];
             $server['HTTP_HOST']   = $server['HTTP_HOST'] . ':' . $info['port'];
         }
+
         if (isset($info['user'])) {
             $server['PHP_AUTH_USER'] = $info['user'];
         }
+
         if (isset($info['pass'])) {
             $server['PHP_AUTH_PW'] = $info['pass'];
         }
+
         if (!isset($info['path'])) {
             $info['path'] = '/';
         }
-        $options                      = [];
+
+        $options     = [];
+        $queryString = '';
+
         $options[strtolower($method)] = $params;
-        $queryString                  = '';
+
         if (isset($info['query'])) {
             parse_str(html_entity_decode($info['query']), $query);
             if (!empty($params)) {
                 $params      = array_replace($query, $params);
-                $queryString = http_build_query($query, '', '&');
+                $queryString = http_build_query($params, '', '&');
             } else {
                 $params      = $query;
                 $queryString = $info['query'];
@@ -364,6 +373,7 @@ class Request
         } elseif (!empty($params)) {
             $queryString = http_build_query($params, '', '&');
         }
+
         if ($queryString) {
             parse_str($queryString, $get);
             $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;
@@ -1557,7 +1567,11 @@ class Request
             return $ip[$type];
         }
 
-        if ($adv) {
+        $httpAgentIp = $this->config->get('http_agent_ip');
+
+        if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) {
+            $ip = $_SERVER[$httpAgentIp];
+        } elseif ($adv) {
             if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                 $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                 $pos = array_search('unknown', $arr);
diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php
index 81f914b9f..645fb9e1d 100644
--- a/thinkphp/library/think/Route.php
+++ b/thinkphp/library/think/Route.php
@@ -313,6 +313,8 @@ class Route
     {
         if (is_null($domain)) {
             $domain = $this->domain;
+        } elseif (!strpos($domain, '.')) {
+            $domain .= '.' . $this->request->rootDomain();
         }
 
         $subDomain = $this->request->subDomain();
@@ -596,8 +598,7 @@ class Route
         $group = new RuleGroup($this, $this->group, $rule, null, $option, $pattern);
 
         foreach ($this->methodPrefix as $type => $val) {
-            $item = $this->$type(':action', $val . ':action');
-            $group->addRuleItem($item, $type);
+            $group->addRule('<action>', $val . '<action>', $type);
         }
 
         return $group->prefix($route . '/');
diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php
index a7281df46..1e4dfd7d2 100644
--- a/thinkphp/library/think/Url.php
+++ b/thinkphp/library/think/Url.php
@@ -124,7 +124,7 @@ class Url
             if ($alias) {
                 // 别名路由解析
                 foreach ($alias as $key => $item) {
-                    $val = $item->gerRoute();
+                    $val = $item->getRoute();
 
                     if (0 === strpos($url, $val)) {
                         $url        = $key . substr($url, strlen($val));
@@ -148,7 +148,7 @@ class Url
 
         // 检测URL绑定
         if (!$this->bindCheck) {
-            $bind = $this->app['route']->getBind();
+            $bind = $this->app['route']->getBind($domain ?: null);
 
             if ($bind && 0 === strpos($url, $bind)) {
                 $url = substr($url, strlen($bind) + 1);
@@ -252,11 +252,11 @@ class Url
             return '';
         }
 
+        $rootDomain = $this->app['request']->rootDomain();
         if (true === $domain) {
 
             // 自动判断域名
-            $domain     = $this->app['config']->get('app_host') ?: $this->app['request']->host();
-            $rootDomain = $this->app['config']->get('url_domain_root');
+            $domain = $this->app['config']->get('app_host') ?: $this->app['request']->host();
 
             $domains = $this->app['route']->getDomains();
 
@@ -286,6 +286,8 @@ class Url
                     }
                 }
             }
+        } elseif (!strpos($domain, '.')) {
+            $domain .= '.' . $rootDomain;
         }
 
         if (false !== strpos($domain, '://')) {
diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php
index 4abfc6b25..930f7d0fa 100644
--- a/thinkphp/library/think/Validate.php
+++ b/thinkphp/library/think/Validate.php
@@ -749,7 +749,7 @@ class Validate
                 $result = in_array($value, [true, false, 0, 1, '0', '1'], true);
                 break;
             case 'number':
-                $result = is_numeric($value);
+                $result = ctype_digit($value);
                 break;
             case 'array':
                 // 是否为数组
diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php
index 3ff1a0128..5f10200bf 100644
--- a/thinkphp/library/think/cache/driver/File.php
+++ b/thinkphp/library/think/cache/driver/File.php
@@ -59,10 +59,11 @@ class File extends Driver
     private function init()
     {
         // 创建项目缓存目录
-        if (!is_dir($this->options['path'])) {
-            if (mkdir($this->options['path'], 0755, true)) {
+        try {
+            if (!is_dir($this->options['path']) && mkdir($this->options['path'], 0755, true)) {
                 return true;
             }
+        } catch (\Exception $e) {
         }
 
         return false;
@@ -92,7 +93,10 @@ class File extends Driver
         $dir      = dirname($filename);
 
         if ($auto && !is_dir($dir)) {
-            mkdir($dir, 0755, true);
+            try {
+                mkdir($dir, 0755, true);
+            } catch (\Exception $e) {
+            }
         }
 
         return $filename;
diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php
index 2f019608c..77958c334 100644
--- a/thinkphp/library/think/cache/driver/Redis.php
+++ b/thinkphp/library/think/cache/driver/Redis.php
@@ -203,39 +203,4 @@ class Redis extends Driver
         return $this->handler->flushDB();
     }
 
-    /**
-     * 如果不存在则写入缓存
-     * @access public
-     * @param string $name 缓存变量名
-     * @param mixed $value 存储数据
-     * @param int $expire  有效时间 0为永久
-     * @return mixed
-     */
-    public function remember($name, $value, $expire = null)
-    {
-        if (is_null($expire)) {
-            $expire = $this->options['expire'];
-        }
-
-        // 没有过期参数时,使用setnx
-        if (!$expire) {
-            $key = $this->getCacheKey($name);
-            $val = $this->serialize($value);
-            $res = $this->handler->setnx($key, $val);
-            if ($res) {
-                $this->writeTimes++;
-                return $value;
-            } else {
-                return $this->get($name);
-            }
-        }
-
-        if ($this->has($name)) {
-            return $this->get($name);
-        } else {
-            $this->set($name, $value, $expire);
-        }
-
-        return $value;
-    }
 }
diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php
index d6a5df4e7..78ea0f4a9 100644
--- a/thinkphp/library/think/db/Builder.php
+++ b/thinkphp/library/think/db/Builder.php
@@ -143,11 +143,6 @@ abstract class Builder
                     case 'DEC':
                         $result[$item] = $item . ' - ' . floatval($val[1]);
                         break;
-                    default:
-                        $value = $this->parseArrayData($query, $val);
-                        if ($value) {
-                            $result[$item] = $value;
-                        }
                 }
             } elseif (is_scalar($val)) {
                 // 过滤非标量数据
@@ -158,18 +153,6 @@ abstract class Builder
         return $result;
     }
 
-    /**
-     * 数组数据解析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  array     $data
-     * @return mixed
-     */
-    protected function parseArrayData(Query $query, $data)
-    {
-        return false;
-    }
-
     /**
      * 数据绑定处理
      * @access protected
@@ -492,13 +475,13 @@ abstract class Builder
     /**
      * 表达式查询
      * @access protected
-     * @param  Query     $query        查询对象
-     * @param  string    $key
-     * @param  string    $exp
-     * @param  mixed     $value
-     * @param  string    $field
-     * @param  string    $bindName
-     * @param  integer   $bindType
+     * @param  Query        $query        查询对象
+     * @param  string       $key
+     * @param  string       $exp
+     * @param  Expression   $value
+     * @param  string       $field
+     * @param  string       $bindName
+     * @param  integer      $bindType
      * @return string
      */
     protected function parseExp(Query $query, $key, $exp, Expression $value, $field, $bindName, $bindType)
diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php
index f5cd5f400..a73fa293d 100644
--- a/thinkphp/library/think/db/builder/Mysql.php
+++ b/thinkphp/library/think/db/builder/Mysql.php
@@ -173,33 +173,6 @@ class Mysql extends Builder
         return $fieldsStr;
     }
 
-    /**
-     * 数组数据解析
-     * @access protected
-     * @param  Query     $query     查询对象
-     * @param  array     $data
-     * @return mixed
-     */
-    protected function parseArrayData(Query $query, $data)
-    {
-        list($type, $value) = $data;
-
-        switch (strtolower($type)) {
-            case 'point':
-                $fun   = isset($data[2]) ? $data[2] : 'GeomFromText';
-                $point = isset($data[3]) ? $data[3] : 'POINT';
-                if (is_array($value)) {
-                    $value = implode(' ', $value);
-                }
-                $result = $fun . '(\'' . $point . '(' . $value . ')\')';
-                break;
-            default:
-                $result = false;
-        }
-
-        return $result;
-    }
-
     /**
      * 随机排序
      * @access protected
diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php
index f71509222..1db14925b 100644
--- a/thinkphp/library/think/log/driver/File.php
+++ b/thinkphp/library/think/log/driver/File.php
@@ -61,8 +61,11 @@ class File
                 $filename = date('Ymd') . $cli . '.log';
                 $files    = glob($this->config['path'] . '*.log');
 
-                if (count($files) > $this->config['max_files']) {
-                    unlink($files[0]);
+                try {
+                    if (count($files) > $this->config['max_files']) {
+                        unlink($files[0]);
+                    }
+                } catch (\Exception $e) {
                 }
             } else {
                 $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . $cli . '.log';
diff --git a/thinkphp/library/think/route/Dispatch.php b/thinkphp/library/think/route/Dispatch.php
index ca6b5d63d..ec7e15497 100644
--- a/thinkphp/library/think/route/Dispatch.php
+++ b/thinkphp/library/think/route/Dispatch.php
@@ -32,8 +32,12 @@ abstract class Dispatch
         $this->dispatch = $dispatch;
         $this->param    = $param;
         $this->code     = $code;
+        $this->init();
     }
 
+    protected function init()
+    {}
+
     public function convert($convert)
     {
         $this->convert = $convert;
diff --git a/thinkphp/library/think/route/Domain.php b/thinkphp/library/think/route/Domain.php
index 08581908e..9043017c4 100644
--- a/thinkphp/library/think/route/Domain.php
+++ b/thinkphp/library/think/route/Domain.php
@@ -20,6 +20,8 @@ use think\route\dispatch\Module as ModuleDispatch;
 
 class Domain extends RuleGroup
 {
+    protected $bind;
+
     /**
      * 架构函数
      * @access public
@@ -68,6 +70,12 @@ class Domain extends RuleGroup
             return $result;
         }
 
+        // 添加域名中间件
+        if (!empty($this->option['middleware'])) {
+            Container::get('middleware')->import($this->option['middleware']);
+            unset($this->option['middleware']);
+        }
+
         return parent::check($request, $url, $depr, $completeMatch);
     }
 
@@ -79,6 +87,7 @@ class Domain extends RuleGroup
      */
     public function bind($bind)
     {
+        $this->bind = $bind;
         $this->router->bind($bind, $this->domain);
 
         return $this;
@@ -110,10 +119,8 @@ class Domain extends RuleGroup
      */
     private function checkUrlBind($url, $depr = '/')
     {
-        $bind = $this->router->getBind($this->domain);
-
-        if (!empty($bind)) {
-
+        if (!empty($this->bind)) {
+            $bind = $this->bind;
             $this->parseBindAppendParam($bind);
 
             // 记录绑定信息
diff --git a/thinkphp/library/think/route/Rule.php b/thinkphp/library/think/route/Rule.php
index 92f1ce9de..8d53c4377 100644
--- a/thinkphp/library/think/route/Rule.php
+++ b/thinkphp/library/think/route/Rule.php
@@ -97,6 +97,16 @@ abstract class Rule
         return $this->name;
     }
 
+    /**
+     * 获取Parent对象
+     * @access public
+     * @return $this|null
+     */
+    public function getParent()
+    {
+        return $this->parent;
+    }
+
     /**
      * 获取变量规则定义
      * @access public
@@ -635,9 +645,7 @@ abstract class Rule
     {
         // 添加中间件
         if (!empty($option['middleware'])) {
-            foreach ($option['middleware'] as $middleware) {
-                Container::get('middleware')->add($middleware);
-            }
+            Container::get('middleware')->import($option['middleware']);
         }
 
         // 绑定模型数据
diff --git a/thinkphp/library/think/route/RuleGroup.php b/thinkphp/library/think/route/RuleGroup.php
index 4f2f7d147..bf8c65897 100644
--- a/thinkphp/library/think/route/RuleGroup.php
+++ b/thinkphp/library/think/route/RuleGroup.php
@@ -232,7 +232,7 @@ class RuleGroup extends Rule
      */
     public function lazy($lazy = true)
     {
-        if (!$lazy && !is_object($this->rule)) {
+        if (!$lazy) {
             $this->parseGroupRule($this->rule);
             $this->rule = null;
         }
diff --git a/thinkphp/library/think/route/RuleItem.php b/thinkphp/library/think/route/RuleItem.php
index b7873b0cf..27e5e7548 100644
--- a/thinkphp/library/think/route/RuleItem.php
+++ b/thinkphp/library/think/route/RuleItem.php
@@ -139,6 +139,20 @@ class RuleItem extends Rule
         return $this;
     }
 
+    /**
+     * 设置别名
+     * @access public
+     * @param  string     $name
+     * @return $this
+     */
+    public function name($name)
+    {
+        $this->name = $name;
+        $this->setRuleName(true);
+
+        return $this;
+    }
+
     /**
      * 设置路由标识 用于URL反解生成
      * @access protected
diff --git a/thinkphp/library/think/route/RuleName.php b/thinkphp/library/think/route/RuleName.php
index 460ccab39..408a7c93e 100644
--- a/thinkphp/library/think/route/RuleName.php
+++ b/thinkphp/library/think/route/RuleName.php
@@ -25,7 +25,7 @@ class RuleName
      */
     public function set($name, $value, $first = false)
     {
-        if ($first) {
+        if ($first && isset($this->item[$name])) {
             array_unshift($this->item[$name], $value);
         } else {
             $this->item[$name][] = $value;
diff --git a/thinkphp/library/think/route/dispatch/Module.php b/thinkphp/library/think/route/dispatch/Module.php
index ed8e21ec0..26c92e94d 100644
--- a/thinkphp/library/think/route/dispatch/Module.php
+++ b/thinkphp/library/think/route/dispatch/Module.php
@@ -20,7 +20,10 @@ use think\route\Dispatch;
 
 class Module extends Dispatch
 {
-    public function run()
+    protected $controller;
+    protected $actionName;
+
+    protected function init()
     {
         $result = $this->dispatch;
 
@@ -78,21 +81,25 @@ class Module extends Dispatch
         // 是否自动转换控制器和操作名
         $convert = is_bool($this->convert) ? $this->convert : $this->app->config('app.url_convert');
         // 获取控制器名
-        $controller = strip_tags($result[1] ?: $this->app->config('app.default_controller'));
-        $controller = $convert ? strtolower($controller) : $controller;
+        $controller       = strip_tags($result[1] ?: $this->app->config('app.default_controller'));
+        $this->controller = $convert ? strtolower($controller) : $controller;
 
         // 获取操作名
-        $actionName = strip_tags($result[2] ?: $this->app->config('app.default_action'));
+        $this->actionName = strip_tags($result[2] ?: $this->app->config('app.default_action'));
 
         // 设置当前请求的控制器、操作
-        $this->app['request']->controller(Loader::parseName($controller, 1))->action($actionName);
+        $this->app['request']->controller(Loader::parseName($this->controller, 1))->action($this->actionName);
 
         // 监听module_init
         $this->app['hook']->listen('module_init');
 
+    }
+
+    public function run()
+    {
         // 实例化控制器
         try {
-            $instance = $this->app->controller($controller,
+            $instance = $this->app->controller($this->controller,
                 $this->app->config('app.url_controller_layer'),
                 $this->app->config('app.controller_suffix'),
                 $this->app->config('app.empty_controller'));
@@ -101,7 +108,7 @@ class Module extends Dispatch
         }
 
         // 获取当前操作名
-        $action = $actionName . $this->app->config('app.action_suffix');
+        $action = $this->actionName . $this->app->config('app.action_suffix');
 
         if (is_callable([$instance, $action])) {
             // 执行操作方法
@@ -121,7 +128,7 @@ class Module extends Dispatch
         } elseif (is_callable([$instance, '_empty'])) {
             // 空操作
             $call    = [$instance, '_empty'];
-            $vars    = [$actionName];
+            $vars    = [$this->actionName];
             $reflect = new ReflectionMethod($instance, '_empty');
         } else {
             // 操作不存在
@@ -129,7 +136,6 @@ class Module extends Dispatch
         }
 
         $this->app['hook']->listen('action_begin', $call);
-
         return Container::getInstance()->invokeReflectMethod($instance, $reflect, $vars);
     }
 }
diff --git a/thinkphp/library/think/route/dispatch/Url.php b/thinkphp/library/think/route/dispatch/Url.php
index 1d5b9d01a..f26197aae 100644
--- a/thinkphp/library/think/route/dispatch/Url.php
+++ b/thinkphp/library/think/route/dispatch/Url.php
@@ -17,13 +17,18 @@ use think\route\Dispatch;
 
 class Url extends Dispatch
 {
-    public function run()
+    protected function init()
     {
         // 解析默认的URL规则
         $url    = str_replace($this->param['depr'], '|', $this->dispatch);
         $result = $this->parseUrl($url);
 
-        return (new Module($result))->run();
+        $this->dispatch = new Module($result);
+    }
+
+    public function run()
+    {
+        return $this->dispatch->run();
     }
 
     /**
diff --git a/thinkphp/library/think/view/driver/Php.php b/thinkphp/library/think/view/driver/Php.php
index e2091aada..6e5db3bd7 100644
--- a/thinkphp/library/think/view/driver/Php.php
+++ b/thinkphp/library/think/view/driver/Php.php
@@ -19,6 +19,8 @@ class Php
 {
     // 模板引擎参数
     protected $config = [
+        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
+        'auto_rule'   => 1,
         // 视图基础目录(集中式)
         'view_base'   => '',
         // 模板起始路径
@@ -139,7 +141,7 @@ class Php
             if ($controller) {
                 if ('' == $template) {
                     // 如果模板文件名为空 按照默认规则定位
-                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $request->action();
+                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action());
                 } elseif (false === strpos($template, $depr)) {
                     $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
                 }
diff --git a/thinkphp/library/think/view/driver/Think.php b/thinkphp/library/think/view/driver/Think.php
index 83daa1c57..137acf859 100644
--- a/thinkphp/library/think/view/driver/Think.php
+++ b/thinkphp/library/think/view/driver/Think.php
@@ -22,6 +22,8 @@ class Think
     private $template;
     // 模板引擎参数
     protected $config = [
+        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写
+        'auto_rule'   => 1,
         // 视图基础目录(集中式)
         'view_base'   => '',
         // 模板起始路径
@@ -133,7 +135,7 @@ class Think
             if ($controller) {
                 if ('' == $template) {
                     // 如果模板文件名为空 按照默认规则定位
-                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $request->action();
+                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . (1 == $this->config['auto_rule'] ? Loader::parseName($request->action(true)) : $request->action());
                 } elseif (false === strpos($template, $depr)) {
                     $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
                 }
diff --git a/vendor/autoload.php b/vendor/autoload.php
index b72f4a932..370320b1c 100644
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer/autoload_real.php';
 
-return ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af::getLoader();
+return ComposerAutoloaderInit89214cd95eb7c7c04f32b98e8012aa49::getLoader();
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index c18d97a36..a750b2486 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -163,6 +163,7 @@ return array(
     'app\\wechat\\controller\\News' => $baseDir . '/application/wechat/controller/News.php',
     'app\\wechat\\controller\\Review' => $baseDir . '/application/wechat/controller/Review.php',
     'app\\wechat\\controller\\Tags' => $baseDir . '/application/wechat/controller/Tags.php',
+    'app\\wechat\\controller\\api\\Js' => $baseDir . '/application/wechat/controller/api/Js.php',
     'app\\wechat\\controller\\api\\Push' => $baseDir . '/application/wechat/controller/api/Push.php',
     'app\\wechat\\controller\\api\\Tools' => $baseDir . '/application/wechat/controller/api/Tools.php',
     'app\\wechat\\service\\FansService' => $baseDir . '/application/wechat/service/FansService.php',
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index 8d2b66e79..6797dae11 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af
+class ComposerAutoloaderInit89214cd95eb7c7c04f32b98e8012aa49
 {
     private static $loader;
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit89214cd95eb7c7c04f32b98e8012aa49', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit89214cd95eb7c7c04f32b98e8012aa49', 'loadClassLoader'));
 
         $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
         if ($useStaticLoader) {
             require_once __DIR__ . '/autoload_static.php';
 
-            call_user_func(\Composer\Autoload\ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af::getInitializer($loader));
+            call_user_func(\Composer\Autoload\ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49::getInitializer($loader));
         } else {
             $map = require __DIR__ . '/autoload_namespaces.php';
             foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit95af81df6ac420fb6c658e7c9ee159af
         $loader->register(true);
 
         if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af::$files;
+            $includeFiles = Composer\Autoload\ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49::$files;
         } else {
             $includeFiles = require __DIR__ . '/autoload_files.php';
         }
         foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequire95af81df6ac420fb6c658e7c9ee159af($fileIdentifier, $file);
+            composerRequire89214cd95eb7c7c04f32b98e8012aa49($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
 
-function composerRequire95af81df6ac420fb6c658e7c9ee159af($fileIdentifier, $file)
+function composerRequire89214cd95eb7c7c04f32b98e8012aa49($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
         require $file;
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index d77aefaf3..6c4c81d93 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
 
 namespace Composer\Autoload;
 
-class ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af
+class ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49
 {
     public static $files = array (
         '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
@@ -241,6 +241,7 @@ class ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af
         'app\\wechat\\controller\\News' => __DIR__ . '/../..' . '/application/wechat/controller/News.php',
         'app\\wechat\\controller\\Review' => __DIR__ . '/../..' . '/application/wechat/controller/Review.php',
         'app\\wechat\\controller\\Tags' => __DIR__ . '/../..' . '/application/wechat/controller/Tags.php',
+        'app\\wechat\\controller\\api\\Js' => __DIR__ . '/../..' . '/application/wechat/controller/api/Js.php',
         'app\\wechat\\controller\\api\\Push' => __DIR__ . '/../..' . '/application/wechat/controller/api/Push.php',
         'app\\wechat\\controller\\api\\Tools' => __DIR__ . '/../..' . '/application/wechat/controller/api/Tools.php',
         'app\\wechat\\service\\FansService' => __DIR__ . '/../..' . '/application/wechat/service/FansService.php',
@@ -257,9 +258,9 @@ class ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af
     public static function getInitializer(ClassLoader $loader)
     {
         return \Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af::$prefixDirsPsr4;
-            $loader->classMap = ComposerStaticInit95af81df6ac420fb6c658e7c9ee159af::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticInit89214cd95eb7c7c04f32b98e8012aa49::$classMap;
 
         }, null, ClassLoader::class);
     }
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 277d7f926..e47427012 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -175,17 +175,17 @@
     },
     {
         "name": "topthink/framework",
-        "version": "v5.1.7",
-        "version_normalized": "5.1.7.0",
+        "version": "v5.1.8",
+        "version_normalized": "5.1.8.0",
         "source": {
             "type": "git",
             "url": "https://github.com/top-think/framework.git",
-            "reference": "81a93819dbbd66774405daf9c27a9219232dba9a"
+            "reference": "8f6c84abd9e2f9db5a071168c0153724b54b083c"
         },
         "dist": {
             "type": "zip",
-            "url": "https://files.phpcomposer.com/files/top-think/framework/81a93819dbbd66774405daf9c27a9219232dba9a.zip",
-            "reference": "81a93819dbbd66774405daf9c27a9219232dba9a",
+            "url": "https://files.phpcomposer.com/files/top-think/framework/8f6c84abd9e2f9db5a071168c0153724b54b083c.zip",
+            "reference": "8f6c84abd9e2f9db5a071168c0153724b54b083c",
             "shasum": ""
         },
         "require": {
@@ -201,7 +201,7 @@
             "sebastian/phpcpd": "2.*",
             "squizlabs/php_codesniffer": "2.*"
         },
-        "time": "2018-03-29T04:16:43+00:00",
+        "time": "2018-04-06T05:28:49+00:00",
         "type": "think-framework",
         "installation-source": "dist",
         "notification-url": "https://packagist.org/downloads/",
@@ -269,8 +269,8 @@
     },
     {
         "name": "symfony/options-resolver",
-        "version": "v3.4.6",
-        "version_normalized": "3.4.6.0",
+        "version": "v3.4.8",
+        "version_normalized": "3.4.8.0",
         "source": {
             "type": "git",
             "url": "https://github.com/symfony/options-resolver.git",