diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php
index 619d535..6945949 100644
--- a/application/admin/command/Crud.php
+++ b/application/admin/command/Crud.php
@@ -24,6 +24,11 @@ class Crud extends Command
                 ->addOption('model', 'm', Option::VALUE_OPTIONAL, 'model name', null)
                 ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', null)
                 ->addOption('local', 'l', Option::VALUE_OPTIONAL, 'local model', 1)
+                ->addOption('relation', 'r', Option::VALUE_OPTIONAL, 'relation table name without prefix', null)
+                ->addOption('relationmodel', 'e', Option::VALUE_OPTIONAL, 'relation model name', null)
+                ->addOption('relationforeignkey', 'k', Option::VALUE_OPTIONAL, 'relation foreign key', null)
+                ->addOption('relationprimarykey', 'p', Option::VALUE_OPTIONAL, 'relation primary key', null)
+                ->addOption('mode', 'o', Option::VALUE_OPTIONAL, 'relation table mode,hasone or belongsto', 'hasone')
                 ->setDescription('Build CRUD controller and model from table');
     }
 
@@ -44,8 +49,26 @@ class Crud extends Command
         {
             throw new Exception('table name can\'t empty');
         }
+        //关联表
+        $relation = $input->getOption('relation');
+        //自定义关联表模型
+        $relationModel = $input->getOption('relationmodel');
+        //模式
+        $mode = $input->getOption('mode');
+        //外键
+        $relationForeignKey = $input->getOption('relationforeignkey');
+        //主键
+        $relationPrimaryKey = $input->getOption('relationprimarykey');
+        //如果有启用关联模式
+        if ($relation && !in_array($mode, ['hasone', 'belongsto']))
+        {
+            throw new Exception("relation table only work in hasone or belongsto mode");
+        }
+
         $dbname = Config::get('database.database');
         $prefix = Config::get('database.prefix');
+
+        //检查主表
         $tableName = $prefix . $table;
         $tableInfo = Db::query("SHOW TABLE STATUS LIKE '{$tableName}'", [], TRUE);
         if (!$tableInfo)
@@ -54,6 +77,17 @@ class Crud extends Command
         }
         $tableInfo = $tableInfo[0];
 
+        //检查关联表
+        if ($relation)
+        {
+            $relationTableName = $prefix . $relation;
+            $relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], TRUE);
+            if (!$relationTableInfo)
+            {
+                throw new Exception("relation table not found");
+            }
+        }
+
         //根据表名匹配对应的Fontawesome图标
         $iconPath = ROOT_PATH . str_replace('/', DS, '/public/assets/libs/font-awesome/less/variables.less');
         $iconName = is_file($iconPath) && stripos(file_get_contents($iconPath), '@fa-var-' . $table . ':') ? $table : 'fa fa-circle-o';
@@ -72,20 +106,13 @@ class Crud extends Command
         }
 
         //模型默认以表名进行处理,以下划线进行分隔,如果需要自定义则需要传入model,不支持目录层级
-        if (!$model)
-        {
-            $modelarr = explode('_', strtolower($table));
-            foreach ($modelarr as $k => &$v)
-                $v = ucfirst($v);
-            unset($v);
-            $modelName = implode('', $modelarr);
-        }
-        else
-        {
-            $modelName = ucfirst($model);
-        }
+        $modelName = $this->getModelName($model, $table);
         $modelFile = ($local ? $adminPath : APP_PATH . 'common' . DS) . 'model' . DS . $modelName . '.php';
 
+        //关联模型默认以表名进行处理,以下划线进行分隔,如果需要自定义则需要传入relationmodel,不支持目录层级
+        $relationModelName = $this->getModelName($relationModel, $relation);
+        $relationModelFile = ($local ? $adminPath : APP_PATH . 'common' . DS) . 'model' . DS . $relationModelName . '.php';
+
         //非覆盖模式时如果存在模型文件则报错
         if (is_file($modelFile) && !$force)
         {
@@ -95,12 +122,26 @@ class Crud extends Command
         require $adminPath . 'common.php';
 
         //从数据库中获取表字段信息
-        $columnList = Db::query("SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION", [$dbname, $tableName]);
+        $sql = "SELECT * FROM `information_schema`.`columns` "
+                . "WHERE TABLE_SCHEMA = ? AND table_name = ? "
+                . "ORDER BY ORDINAL_POSITION";
+        $columnList = Db::query($sql, [$dbname, $tableName]);
+        $relationColumnList = [];
+        if ($relation)
+        {
+            $relationColumnList = Db::query($sql, [$dbname, $relationTableName]);
+        }
 
-        $fields = [];
+        $fieldArr = [];
         foreach ($columnList as $k => $v)
         {
-            $fields[] = $v['COLUMN_NAME'];
+            $fieldArr[] = $v['COLUMN_NAME'];
+        }
+
+        $relationFieldArr = [];
+        foreach ($relationColumnList as $k => $v)
+        {
+            $relationFieldArr[] = $v['COLUMN_NAME'];
         }
 
         $addList = [];
@@ -110,20 +151,68 @@ class Crud extends Command
         $field = 'id';
         $order = 'id';
         $priDefined = FALSE;
-        $prikey = '';
+        $priKey = '';
+        $relationPriKey = '';
         foreach ($columnList as $k => $v)
         {
             if ($v['COLUMN_KEY'] == 'PRI')
             {
-                $prikey = $v['COLUMN_NAME'];
+                $priKey = $v['COLUMN_NAME'];
                 break;
             }
         }
-        if (!$prikey)
+        if (!$priKey)
         {
             throw new Exception('Primary key not found!');
         }
-        $order = $prikey;
+        if ($relation)
+        {
+            foreach ($relationColumnList as $k => $v)
+            {
+                if ($v['COLUMN_KEY'] == 'PRI')
+                {
+                    $relationPriKey = $v['COLUMN_NAME'];
+                    break;
+                }
+            }
+            if (!$relationPriKey)
+            {
+                throw new Exception('Relation Primary key not found!');
+            }
+        }
+        $order = $priKey;
+
+
+        //如果是关联模型
+        if ($relation)
+        {
+            if ($mode == 'hasone')
+            {
+                $relationForeignKey = $relationForeignKey ? $relationForeignKey : $table . "_id";
+                $relationPrimaryKey = $relationPrimaryKey ? $relationPrimaryKey : $priKey;
+                if (!in_array($relationForeignKey, $relationFieldArr))
+                {
+                    throw new Exception('relation table must be contain field:' . $relationForeignKey);
+                }
+                if (!in_array($relationPrimaryKey, $fieldArr))
+                {
+                    throw new Exception('table must be contain field:' . $relationPrimaryKey);
+                }
+            }
+            else
+            {
+                $relationForeignKey = $relationForeignKey ? $relationForeignKey : $relation . "_id";
+                $relationPrimaryKey = $relationPrimaryKey ? $relationPrimaryKey : $relationPriKey;
+                if (!in_array($relationForeignKey, $fieldArr))
+                {
+                    throw new Exception('table must be contain field:' . $relationForeignKey);
+                }
+                if (!in_array($relationPrimaryKey, $relationFieldArr))
+                {
+                    throw new Exception('relation table must be contain field:' . $relationPrimaryKey);
+                }
+            }
+        }
 
         try
         {
@@ -309,6 +398,30 @@ class Crud extends Command
                     $order = $field == 'weigh' ? 'weigh' : $order;
                 }
             }
+
+            $relationPriKey = 'id';
+            $relationFieldArr = [];
+            foreach ($relationColumnList as $k => $v)
+            {
+                $relationField = $v['COLUMN_NAME'];
+                $relationFieldArr[] = $field;
+
+                $relationField = strtolower($relationModelName) . "." . $relationField;
+                // 语言列表
+                if ($v['COLUMN_COMMENT'] != '')
+                {
+                    $langList[] = $this->getLangItem($relationField, $v['COLUMN_COMMENT']);
+                }
+
+                //过滤text类型字段
+                if ($v['DATA_TYPE'] != 'text')
+                {
+                    //构造JS列信息
+                    $javascriptList[] = $this->getJsColumn($relationField);
+                }
+            }
+
+
             //JS最后一列加上操作列
             $javascriptList[] = str_repeat(" ", 24) . "{field: 'operate', title: __('Operate'), events: Table.api.events.operate, formatter: Table.api.formatter.operate}";
             $addList = implode("\n", array_filter($addList));
@@ -333,6 +446,7 @@ class Crud extends Command
             $controllerNamespace = "{$appNamespace}\\{$moduleName}\\controller" . ($controllerDir ? "\\" : "") . str_replace('/', "\\", $controllerDir);
             $modelNamespace = "{$appNamespace}\\" . ($local ? $moduleName : "common") . "\\model";
 
+
             $data = [
                 'controllerNamespace'     => $controllerNamespace,
                 'modelNamespace'          => $modelNamespace,
@@ -342,7 +456,7 @@ class Crud extends Command
                 'modelName'               => $modelName,
                 'tableComment'            => $tableComment,
                 'iconName'                => $iconName,
-                'pk'                      => $prikey,
+                'pk'                      => $priKey,
                 'order'                   => $order,
                 'table'                   => $table,
                 'tableName'               => $tableName,
@@ -350,15 +464,49 @@ class Crud extends Command
                 'editList'                => $editList,
                 'javascriptList'          => $javascriptList,
                 'langList'                => $langList,
-                'modelAutoWriteTimestamp' => in_array('createtime', $fields) || in_array('updatetime', $fields) ? "'int'" : 'false',
-                'createTime'              => in_array('createtime', $fields) ? "'createtime'" : 'false',
-                'updateTime'              => in_array('updatetime', $fields) ? "'updatetime'" : 'false',
+                'modelAutoWriteTimestamp' => in_array('createtime', $fieldArr) || in_array('updatetime', $fieldArr) ? "'int'" : 'false',
+                'createTime'              => in_array('createtime', $fieldArr) ? "'createtime'" : 'false',
+                'updateTime'              => in_array('updatetime', $fieldArr) ? "'updatetime'" : 'false',
+                'modelTableName'          => $table,
+                'relationModelTableName'  => $relation,
+                'relationModelName'       => $relationModelName,
+                'relationWith'            => '',
+                'relationMethod'          => '',
+                'relationModel'           => '',
+                'relationForeignKey'      => '',
+                'relationPrimaryKey'      => '',
+                'relationSearch'          => $relation ? 'true' : 'false',
+                'controllerIndex'         => '',
+                'modelMethod'             => '',
             ];
 
+            //如果使用关联模型
+            if ($relation)
+            {
+                //需要构造关联的方法
+                $data['relationMethod'] = strtolower($relationModelName);
+                //预载入的方法
+                $data['relationWith'] = "->with('{$data['relationMethod']}')";
+                //需要重写index方法
+                $data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
+                //关联的模式
+                $data['relationMode'] = $mode == 'hasone' ? 'hasOne' : 'belongsTo';
+                //关联字段
+                $data['relationForeignKey'] = $relationForeignKey;
+                $data['relationPrimaryKey'] = $relationPrimaryKey ? $relationPrimaryKey : $priKey;
+                //构造关联模型的方法
+                $data['modelMethod'] = $this->getReplacedStub('modelmethod', $data);
+            }
+
             // 生成控制器文件
             $result = $this->writeToFile('controller', $data, $controllerFile);
             // 生成模型文件
             $result = $this->writeToFile('model', $data, $modelFile);
+            if ($relation && !is_file($relationModelFile))
+            {
+                // 生成关联模型文件
+                $result = $this->writeToFile('relationmodel', $data, $relationModelFile);
+            }
             // 生成视图文件
             $result = $this->writeToFile('add', $data, $addFile);
             $result = $this->writeToFile('edit', $data, $editFile);
@@ -378,6 +526,23 @@ class Crud extends Command
         $output->writeln("<info>Build Successed</info>");
     }
 
+    protected function getModelName($model, $table)
+    {
+        if (!$model)
+        {
+            $modelarr = explode('_', strtolower($table));
+            foreach ($modelarr as $k => &$v)
+                $v = ucfirst($v);
+            unset($v);
+            $modelName = implode('', $modelarr);
+        }
+        else
+        {
+            $modelName = ucfirst($model);
+        }
+        return $modelName;
+    }
+
     /**
      * 写入到文件
      * @param string $name
@@ -387,6 +552,23 @@ class Crud extends Command
      */
     protected function writeToFile($name, $data, $pathname)
     {
+        $content = $this->getReplacedStub($name, $data);
+
+        if (!is_dir(dirname($pathname)))
+        {
+            mkdir(strtolower(dirname($pathname)), 0755, true);
+        }
+        return file_put_contents($pathname, $content);
+    }
+
+    /**
+     * 获取替换后的数据
+     * @param string $name
+     * @param array $data
+     * @return string
+     */
+    protected function getReplacedStub($name, $data)
+    {
         $search = $replace = [];
         foreach ($data as $k => $v)
         {
@@ -395,12 +577,7 @@ class Crud extends Command
         }
         $stub = file_get_contents($this->getStub($name));
         $content = str_replace($search, $replace, $stub);
-
-        if (!is_dir(dirname($pathname)))
-        {
-            mkdir(strtolower(dirname($pathname)), 0755, true);
-        }
-        return file_put_contents($pathname, $content);
+        return $content;
     }
 
     /**
@@ -570,6 +747,7 @@ EOD;
     {
         $lang = ucfirst($field);
         $html = str_repeat(" ", 24) . "{field: '{$field}', title: __('{$lang}')";
+        $field = substr($field, stripos($field, '.') + 1);
         $formatter = '';
         if ($field == 'status')
             $formatter = 'status';
diff --git a/application/admin/command/Crud/stubs/controller.stub b/application/admin/command/Crud/stubs/controller.stub
index cfb67d1..530b862 100644
--- a/application/admin/command/Crud/stubs/controller.stub
+++ b/application/admin/command/Crud/stubs/controller.stub
@@ -22,4 +22,5 @@ class {%controllerName%} extends Backend
         parent::_initialize();
         $this->model = model('{%modelName%}');
     }
+{%controllerIndex%}
 }
diff --git a/application/admin/command/Crud/stubs/controllerindex.stub b/application/admin/command/Crud/stubs/controllerindex.stub
new file mode 100644
index 0000000..d10c040
--- /dev/null
+++ b/application/admin/command/Crud/stubs/controllerindex.stub
@@ -0,0 +1,30 @@
+
+    /**
+     * 查看
+     */
+    public function index()
+    {
+        //当前是否为关联查询
+        $this->relationSearch = {%relationSearch%};
+        
+        if ($this->request->isAjax())
+        {
+            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+            $total = $this->model
+                    {%relationWith%}
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->count();
+
+            $list = $this->model
+                    {%relationWith%}
+                    ->where($where)
+                    ->order($sort, $order)
+                    ->limit($offset, $limit)
+                    ->select();
+            $result = array("total" => $total, "rows" => $list);
+
+            return json($result);
+        }
+        return $this->view->fetch();
+    }
\ No newline at end of file
diff --git a/application/admin/command/Crud/stubs/model.stub b/application/admin/command/Crud/stubs/model.stub
index 05d2e6f..8e1b495 100644
--- a/application/admin/command/Crud/stubs/model.stub
+++ b/application/admin/command/Crud/stubs/model.stub
@@ -6,11 +6,15 @@ use think\Model;
 
 class {%modelName%} extends Model
 {
-
+    // 表名,不含前缀
+    protected $name = '{%modelTableName%}';
+    
     // 自动写入时间戳字段
     protected $autoWriteTimestamp = {%modelAutoWriteTimestamp%};
 
     // 定义时间戳字段名
     protected $createTime = {%createTime%};
     protected $updateTime = {%updateTime%};
+    
+{%modelMethod%}
 }
diff --git a/application/admin/command/Crud/stubs/modelmethod.stub b/application/admin/command/Crud/stubs/modelmethod.stub
new file mode 100644
index 0000000..39b3c90
--- /dev/null
+++ b/application/admin/command/Crud/stubs/modelmethod.stub
@@ -0,0 +1,5 @@
+
+    public function {%relationMethod%}()
+    {
+        return $this->{%relationMode%}('{%relationModelName%}', '{%relationForeignKey%}', '{%pk%}')->setEagerlyType(0);
+    }
\ No newline at end of file
diff --git a/application/admin/command/Crud/stubs/relationmodel.stub b/application/admin/command/Crud/stubs/relationmodel.stub
new file mode 100644
index 0000000..e0a8c09
--- /dev/null
+++ b/application/admin/command/Crud/stubs/relationmodel.stub
@@ -0,0 +1,12 @@
+<?php
+
+namespace {%modelNamespace%};
+
+use think\Model;
+
+class {%relationModelName%} extends Model
+{
+    // 表名,不含前缀
+    protected $name = '{%relationModelTableName%}';
+    
+}
diff --git a/application/common/controller/Backend.php b/application/common/controller/Backend.php
index afbd2bf..91f658a 100644
--- a/application/common/controller/Backend.php
+++ b/application/common/controller/Backend.php
@@ -60,6 +60,16 @@ class Backend extends Controller
     protected $auth = null;
 
     /**
+     * 快速搜索时执行查找的字段
+     */
+    protected $searchFields = 'id';
+
+    /**
+     * 是否是关联查询
+     */
+    protected $relationSearch = false;
+
+    /**
      * 引入后台控制器的traits
      */
     use \app\admin\library\traits\Backend;
@@ -154,11 +164,13 @@ class Backend extends Controller
     /**
      * 生成查询所需要的条件,排序方式
      * @param mixed $searchfields 查询条件
+     * @param boolean $relationSearch 是否关联查询
      * @return array
      */
-    protected function buildparams($searchfields = NULL)
+    protected function buildparams($searchfields = null, $relationSearch = null)
     {
-        $searchfields = is_null($searchfields) ? 'id' : $searchfields;
+        $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
+        $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
         $search = $this->request->get("search", '');
         $filter = $this->request->get("filter", '');
         $op = $this->request->get("op", '');
@@ -180,25 +192,27 @@ class Backend extends Controller
             }
             $where[] = "(" . implode(' OR ', $searchlist) . ")";
         }
-        $table = '';
-        if (!empty($this->model))
+        $modelName = '';
+        if ($relationSearch)
         {
-            $class = get_class($this->model);
-            $name = basename(str_replace('\\', '/', $class));
-            $table = $this->model->db(false)->getTable($name);
-            $table = $table . ".";
-        }
-        if (stripos($sort, ".") === false)
-        {
-
-            $sort = $table . $sort;
+            if (!empty($this->model))
+            {
+                $class = get_class($this->model);
+                $name = basename(str_replace('\\', '/', $class));
+                $name = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $name));
+                $modelName = $name . ".";
+            }
+            if (stripos($sort, ".") === false)
+            {
+                $sort = $modelName . $sort;
+            }
         }
         foreach ($filter as $k => $v)
         {
             $sym = isset($op[$k]) ? $op[$k] : '=';
             if (stripos($k, ".") === false)
             {
-                $k = $table . $k;
+                $k = $modelName . $k;
             }
             $sym = isset($op[$k]) ? $op[$k] : $sym;
             switch ($sym)
diff --git a/public/assets/js/backend.js b/public/assets/js/backend.js
index fa9c086..b587b25 100755
--- a/public/assets/js/backend.js
+++ b/public/assets/js/backend.js
@@ -305,7 +305,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($
                 if (typeof Lang[string] == 'object')
                     return Lang[string];
                 string = Lang[string];
-            } else if (string.indexOf('.') !== -1) {
+            } else if (string.indexOf('.') !== -1 && false) {
                 var arr = string.split('.');
                 var current = Lang[arr[0]];
                 for (var i = 1; i < arr.length; i++) {
diff --git a/public/assets/js/require-backend.min.js b/public/assets/js/require-backend.min.js
index f28991a..48a38e5 100644
--- a/public/assets/js/require-backend.min.js
+++ b/public/assets/js/require-backend.min.js
@@ -6722,7 +6722,7 @@ define('backend',['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], f
                 if (typeof Lang[string] == 'object')
                     return Lang[string];
                 string = Lang[string];
-            } else if (string.indexOf('.') !== -1) {
+            } else if (string.indexOf('.') !== -1 && false) {
                 var arr = string.split('.');
                 var current = Lang[arr[0]];
                 for (var i = 1; i < arr.length; i++) {
@@ -7863,7 +7863,7 @@ define('table',['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap
                     }
                     value = value.toString();
                     var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                    value = value[0].toUpperCase() + value.substr(1);
+                    value = value.charAt(0).toUpperCase() + value.slice(1);
                     //渲染状态
                     var html = '<span class="text-' + color + '"><i class="fa fa-circle"></i> ' + __(value) + '</span>';
                     return html;
@@ -7891,7 +7891,7 @@ define('table',['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap
                         if (value == '')
                             return true;
                         var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                        value = value[0].toUpperCase() + value.substr(1);
+                        value = value.charAt(0).toUpperCase() + value.slice(1);
                         html.push('<span class="label label-' + color + '">' + __(value) + '</span>');
                     });
                     return html.join(' ');
diff --git a/public/assets/js/require-table.js b/public/assets/js/require-table.js
index 88b86ea..dc64e6b 100644
--- a/public/assets/js/require-table.js
+++ b/public/assets/js/require-table.js
@@ -283,7 +283,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table',
                     }
                     value = value.toString();
                     var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                    value = value[0].toUpperCase() + value.substr(1);
+                    value = value.charAt(0).toUpperCase() + value.slice(1);
                     //渲染状态
                     var html = '<span class="text-' + color + '"><i class="fa fa-circle"></i> ' + __(value) + '</span>';
                     return html;
@@ -311,7 +311,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table',
                         if (value == '')
                             return true;
                         var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
-                        value = value[0].toUpperCase() + value.substr(1);
+                        value = value.charAt(0).toUpperCase() + value.slice(1);
                         html.push('<span class="label label-' + color + '">' + __(value) + '</span>');
                     });
                     return html.join(' ');