From e816d8538b78f2b9b0da6ea0bd2b746ce8b103af Mon Sep 17 00:00:00 2001
From: Karson <karsonzhang@163.com>
Date: Thu, 1 Jun 2017 22:13:03 +0800
Subject: [PATCH] CRUD新增获取器功能 如果字段是enum,set,select等类型字段会自动在Model生成获取器 新增int日期型字段的获取器和修改器 移除Traits中add/edit方法自动修改日期的功能 修复Form.api.bindevent单次绑定多个form时的BUG 修复特殊情况下刷新不显示边栏的BUG 修复特殊情况下使用addtabsit进行控制器间切换时的BUG

---
 application/admin/command/Crud.php              | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 application/admin/command/Crud/stubs/model.stub |  9 +++++++++
 application/admin/library/traits/Backend.php    | 49 ++++++++++++++++++++++++++++++++++++++++++-------
 application/common/controller/Backend.php       |  2 +-
 public/assets/js/backend.js                     |  4 ++--
 public/assets/js/require-form.js                |  6 +++---
 6 files changed, 151 insertions(+), 14 deletions(-)

diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php
index 6945949..d5846b6 100644
--- a/application/admin/command/Crud.php
+++ b/application/admin/command/Crud.php
@@ -217,6 +217,9 @@ class Crud extends Command
         try
         {
             Form::setEscapeHtml(false);
+            $setAttrArr = [];
+            $getAttrArr = [];
+            $appendAttrList = [];
 
             //循环所有字段,开始构造视图的HTML和JS信息
             foreach ($columnList as $k => $v)
@@ -257,6 +260,7 @@ class Crud extends Command
                         //如果状态类型不是enum或set
                         $itemArr = !$itemArr ? ['normal', 'hidden'] : $itemArr;
                         $inputType = 'radio';
+                        $this->getAttr($getAttrArr, $field);
                     }
                     if ($inputType == 'select')
                     {
@@ -270,6 +274,10 @@ class Crud extends Command
                         $attrStr = $this->getArrayString($attrArr);
                         $itemArr = $this->getLangArray($itemArr, FALSE);
                         $itemString = $this->getArrayString($itemArr);
+
+                        //添加一个获取器
+                        $this->getAttr($getAttrArr, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
+                        $this->appendAttr($appendAttrList, $field);
                         $formAddElement = "{:build_select('{$fieldName}', [{$itemString}], '{$defaultValue}', [{$attrStr}])}";
                         $formEditElement = "{:build_select('{$fieldName}', [{$itemString}], \$row.{$field}, [{$attrStr}])}";
                     }
@@ -302,6 +310,9 @@ class Crud extends Command
                                 break;
                             default:
                                 $fieldFunc = 'datetime';
+                                $this->getAttr($getAttrArr, $field, '', $inputType);
+                                $this->setAttr($setAttrArr, $field, '', $inputType);
+                                $this->appendAttr($appendAttrList, $field);
                                 break;
                         }
                         $defaultDateTime = "{:date('{$phpFormat}')}";
@@ -316,6 +327,9 @@ class Crud extends Command
                         $fieldName .= "[]";
                         $itemArr = $this->getLangArray($itemArr, FALSE);
                         $itemString = $this->getArrayString($itemArr);
+                        //添加一个获取器
+                        $this->getAttr($getAttrArr, $field, $itemArr, $inputType);
+                        $this->appendAttr($appendAttrList, $field);
                         $formAddElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
                         $formEditElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], \$row.{$field})}";
                     }
@@ -324,6 +338,9 @@ class Crud extends Command
                         $itemArr = $this->getLangArray($itemArr, FALSE);
                         $itemString = $this->getArrayString($itemArr);
                         $defaultValue = $defaultValue ? $defaultValue : key($itemArr);
+                        //添加一个获取器
+                        $this->getAttr($getAttrArr, $field, $itemArr, $inputType);
+                        $this->appendAttr($appendAttrList, $field);
                         $formAddElement = "{:build_radios('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
                         $formEditElement = "{:build_radios('{$fieldName}', [{$itemString}], \$row.{$field})}";
                     }
@@ -477,6 +494,9 @@ class Crud extends Command
                 'relationPrimaryKey'      => '',
                 'relationSearch'          => $relation ? 'true' : 'false',
                 'controllerIndex'         => '',
+                'appendAttrList'          => implode(",\n", $appendAttrList),
+                'getAttrList'             => implode("\n\n", $getAttrArr),
+                'setAttrList'             => implode("\n\n", $setAttrArr),
                 'modelMethod'             => '',
             ];
 
@@ -526,6 +546,79 @@ class Crud extends Command
         $output->writeln("<info>Build Successed</info>");
     }
 
+    protected function getAttr(&$getAttr, $field, $itemArr = '', $inputType = '')
+    {
+        if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio']))
+            return;
+        $attrField = ucfirst($field);
+        if ($inputType == 'datetime')
+        {
+            $return = <<<EOD
+\$value = \$data['{$field}'];
+        return is_numeric(\$value) ? date("Y-m-d H:i:s", \$value) : \$value;
+EOD;
+        }
+        else if (in_array($inputType, ['multiple', 'checkbox']))
+        {
+            $itemString = $this->getArrayString($itemArr);
+            $return = <<<EOD
+\$value = \$data['{$field}'];
+        \$valueArr = explode(',', \$value);
+        \$arr = [{$itemString}];
+        \$resultArr = [];
+        foreach (\$valueArr as \$k => \$v)
+        {
+            if (isset(\$arr[\$v]))
+            {
+                \$resultArr[] = \$arr[\$v];
+            }
+        }
+        return implode(',', \$resultArr);
+EOD;
+        }
+        else
+        {
+            $itemString = $this->getArrayString($itemArr);
+            $return = <<<EOD
+\$value = \$data['{$field}'];
+        \$arr = [{$itemString}];
+        return isset(\$arr[\$value]) ? \$arr[\$value] : '';
+EOD;
+        }
+        $getAttr[] = <<<EOD
+    protected function get{$attrField}TextAttr(\$value, \$data)
+    {
+        $return
+    }
+EOD;
+    }
+
+    protected function setAttr(&$setAttr, $field, $itemArr = '', $inputType = '')
+    {
+        if ($inputType != 'datetime')
+            return;
+        $field = ucfirst($field);
+        if ($inputType == 'datetime')
+        {
+            $return = <<<EOD
+return is_numeric(\$value) ? strtotime(\$value) : \$value;
+EOD;
+        }
+        $setAttr[] = <<<EOD
+    protected function set{$field}TextAttr(\$value)
+    {
+        $return
+    }
+EOD;
+    }
+
+    protected function appendAttr(&$appendAttrList, $field)
+    {
+        $appendAttrList[] = <<<EOD
+        '{$field}_text'
+EOD;
+    }
+
     protected function getModelName($model, $table)
     {
         if (!$model)
@@ -747,7 +840,7 @@ EOD;
     {
         $lang = ucfirst($field);
         $html = str_repeat(" ", 24) . "{field: '{$field}', title: __('{$lang}')";
-        $field = substr($field, stripos($field, '.') + 1);
+        $field = stripos($field, ".") !== false ? substr($field, stripos($field, '.') + 1) : $field;
         $formatter = '';
         if ($field == 'status')
             $formatter = 'status';
diff --git a/application/admin/command/Crud/stubs/model.stub b/application/admin/command/Crud/stubs/model.stub
index 8e1b495..e470238 100644
--- a/application/admin/command/Crud/stubs/model.stub
+++ b/application/admin/command/Crud/stubs/model.stub
@@ -16,5 +16,14 @@ class {%modelName%} extends Model
     protected $createTime = {%createTime%};
     protected $updateTime = {%updateTime%};
     
+    // 追加属性
+    protected $append = [
+{%appendAttrList%}
+    ];
+    
+{%getAttrList%}
+
+{%setAttrList%}
+
 {%modelMethod%}
 }
diff --git a/application/admin/library/traits/Backend.php b/application/admin/library/traits/Backend.php
index 301be41..15b1027 100644
--- a/application/admin/library/traits/Backend.php
+++ b/application/admin/library/traits/Backend.php
@@ -23,6 +23,7 @@ trait Backend
                     ->order($sort, $order)
                     ->limit($offset, $limit)
                     ->select();
+          
             $result = array("total" => $total, "rows" => $list);
 
             return json($result);
@@ -44,10 +45,27 @@ trait Backend
                 foreach ($params as $k => &$v)
                 {
                     $v = is_array($v) ? implode(',', $v) : $v;
-                    $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;
                 }
-                $this->model->create($params);
-                $this->code = 1;
+                try
+                {
+                    $result = $this->model->create($params);
+                    if ($result !== false)
+                    {
+                        $this->code = 1;
+                    }
+                    else
+                    {
+                        $this->msg = $this->model->getError();
+                    }
+                }
+                catch (think\Exception $e)
+                {
+                    $this->msg = $e->getMessage();
+                }
+            }
+            else
+            {
+                $this->msg = __('Parameter %s can not be empty', '');
             }
 
             return;
@@ -72,10 +90,27 @@ trait Backend
                 foreach ($params as $k => &$v)
                 {
                     $v = is_array($v) ? implode(',', $v) : $v;
-                    $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;
                 }
-                $row->save($params);
-                $this->code = 1;
+                try
+                {
+                    $result = $row->save($params);
+                    if ($result !== false)
+                    {
+                        $this->code = 1;
+                    }
+                    else
+                    {
+                        $this->msg = $row->getError();
+                    }
+                }
+                catch (think\Exception $e)
+                {
+                    $this->msg = $e->getMessage();
+                }
+            }
+            else
+            {
+                $this->msg = __('Parameter %s can not be empty', '');
             }
 
             return;
@@ -126,7 +161,7 @@ trait Backend
             }
             else
             {
-                $this->code = 1;
+                $this->msg = __('Parameter %s can not be empty', '');
             }
         }
 
diff --git a/application/common/controller/Backend.php b/application/common/controller/Backend.php
index 198e247..c243449 100644
--- a/application/common/controller/Backend.php
+++ b/application/common/controller/Backend.php
@@ -92,7 +92,7 @@ class Backend extends Controller
         !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax());
 
         // 非选项卡时重定向
-        if (!IS_AJAX && !IS_ADDTABS && $controllername != 'index' && $actionname == 'index')
+        if (!IS_AJAX && !IS_ADDTABS && !IS_DIALOG && $path !== "/{$modulename}/index/index" && $controllername != 'ajax')
         {
             $url = $this->request->url();
             $this->redirect('index/index', [], 302, ['referer' => $url]);
diff --git a/public/assets/js/backend.js b/public/assets/js/backend.js
index 42fc310..f934c6c 100755
--- a/public/assets/js/backend.js
+++ b/public/assets/js/backend.js
@@ -246,7 +246,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($
                 });
             },
             addtabs: function (url, title, icon) {
-                var dom = ".sidebar-menu li a[url='{url}']"
+                var dom = "a[url='{url}']"
                 var leftlink = top.window.$(dom.replace(/\{url\}/, url));
                 if (leftlink.size() > 0) {
                     leftlink.trigger("click");
@@ -273,7 +273,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($
                             var id = Math.floor(new Date().valueOf() * Math.random());
                             icon = typeof icon != 'undefined' ? icon : 'fa fa-circle-o';
                             title = typeof title != 'undefined' ? title : '';
-                            top.window.$("<a />").append('<i class="' + icon + '"></i> <span>' + title + '</span>').prop("href", url).attr({url: url, addtabs: id}).appendTo(top.window.document.body).trigger("click");
+                            top.window.$("<a />").append('<i class="' + icon + '"></i> <span>' + title + '</span>').prop("href", url).attr({url: url, addtabs: id}).addClass("hide").appendTo(top.window.document.body).trigger("click");
                         }
                     }
                 }
diff --git a/public/assets/js/require-form.js b/public/assets/js/require-form.js
index 807ecba..147ddd4 100755
--- a/public/assets/js/require-form.js
+++ b/public/assets/js/require-form.js
@@ -76,9 +76,9 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
                     stopOnError: true,
                     valid: function (ret) {
                         //验证通过提交表单
-                        Form.api.submit(form, onBeforeSubmit, function (data) {
+                        Form.api.submit($(ret), onBeforeSubmit, function (data) {
                             if (typeof onAfterSubmit == 'function') {
-                                if (!onAfterSubmit.call(form, data)) {
+                                if (!onAfterSubmit.call($(ret), data)) {
                                     return false;
                                 }
                             }
@@ -239,7 +239,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
                     $(document).on('click', ".fachoose", function () {
                         var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
                         var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
-                        Backend.api.open("general/attachment/select?callback=refreshchoose&element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype="+mimetype, __('Choose'));
+                        Backend.api.open("general/attachment/select?callback=refreshchoose&element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype, __('Choose'));
                         return false;
                     });
 
--
libgit2 0.24.0