作者 Karson

CRUD新增获取器功能

如果字段是enum,set,select等类型字段会自动在Model生成获取器
新增int日期型字段的获取器和修改器
移除Traits中add/edit方法自动修改日期的功能
修复Form.api.bindevent单次绑定多个form时的BUG
修复特殊情况下刷新不显示边栏的BUG
修复特殊情况下使用addtabsit进行控制器间切换时的BUG
@@ -217,6 +217,9 @@ class Crud extends Command @@ -217,6 +217,9 @@ class Crud extends Command
217 try 217 try
218 { 218 {
219 Form::setEscapeHtml(false); 219 Form::setEscapeHtml(false);
  220 + $setAttrArr = [];
  221 + $getAttrArr = [];
  222 + $appendAttrList = [];
220 223
221 //循环所有字段,开始构造视图的HTML和JS信息 224 //循环所有字段,开始构造视图的HTML和JS信息
222 foreach ($columnList as $k => $v) 225 foreach ($columnList as $k => $v)
@@ -257,6 +260,7 @@ class Crud extends Command @@ -257,6 +260,7 @@ class Crud extends Command
257 //如果状态类型不是enum或set 260 //如果状态类型不是enum或set
258 $itemArr = !$itemArr ? ['normal', 'hidden'] : $itemArr; 261 $itemArr = !$itemArr ? ['normal', 'hidden'] : $itemArr;
259 $inputType = 'radio'; 262 $inputType = 'radio';
  263 + $this->getAttr($getAttrArr, $field);
260 } 264 }
261 if ($inputType == 'select') 265 if ($inputType == 'select')
262 { 266 {
@@ -270,6 +274,10 @@ class Crud extends Command @@ -270,6 +274,10 @@ class Crud extends Command
270 $attrStr = $this->getArrayString($attrArr); 274 $attrStr = $this->getArrayString($attrArr);
271 $itemArr = $this->getLangArray($itemArr, FALSE); 275 $itemArr = $this->getLangArray($itemArr, FALSE);
272 $itemString = $this->getArrayString($itemArr); 276 $itemString = $this->getArrayString($itemArr);
  277 +
  278 + //添加一个获取器
  279 + $this->getAttr($getAttrArr, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
  280 + $this->appendAttr($appendAttrList, $field);
273 $formAddElement = "{:build_select('{$fieldName}', [{$itemString}], '{$defaultValue}', [{$attrStr}])}"; 281 $formAddElement = "{:build_select('{$fieldName}', [{$itemString}], '{$defaultValue}', [{$attrStr}])}";
274 $formEditElement = "{:build_select('{$fieldName}', [{$itemString}], \$row.{$field}, [{$attrStr}])}"; 282 $formEditElement = "{:build_select('{$fieldName}', [{$itemString}], \$row.{$field}, [{$attrStr}])}";
275 } 283 }
@@ -302,6 +310,9 @@ class Crud extends Command @@ -302,6 +310,9 @@ class Crud extends Command
302 break; 310 break;
303 default: 311 default:
304 $fieldFunc = 'datetime'; 312 $fieldFunc = 'datetime';
  313 + $this->getAttr($getAttrArr, $field, '', $inputType);
  314 + $this->setAttr($setAttrArr, $field, '', $inputType);
  315 + $this->appendAttr($appendAttrList, $field);
305 break; 316 break;
306 } 317 }
307 $defaultDateTime = "{:date('{$phpFormat}')}"; 318 $defaultDateTime = "{:date('{$phpFormat}')}";
@@ -316,6 +327,9 @@ class Crud extends Command @@ -316,6 +327,9 @@ class Crud extends Command
316 $fieldName .= "[]"; 327 $fieldName .= "[]";
317 $itemArr = $this->getLangArray($itemArr, FALSE); 328 $itemArr = $this->getLangArray($itemArr, FALSE);
318 $itemString = $this->getArrayString($itemArr); 329 $itemString = $this->getArrayString($itemArr);
  330 + //添加一个获取器
  331 + $this->getAttr($getAttrArr, $field, $itemArr, $inputType);
  332 + $this->appendAttr($appendAttrList, $field);
319 $formAddElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], '{$defaultValue}')}"; 333 $formAddElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
320 $formEditElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], \$row.{$field})}"; 334 $formEditElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], \$row.{$field})}";
321 } 335 }
@@ -324,6 +338,9 @@ class Crud extends Command @@ -324,6 +338,9 @@ class Crud extends Command
324 $itemArr = $this->getLangArray($itemArr, FALSE); 338 $itemArr = $this->getLangArray($itemArr, FALSE);
325 $itemString = $this->getArrayString($itemArr); 339 $itemString = $this->getArrayString($itemArr);
326 $defaultValue = $defaultValue ? $defaultValue : key($itemArr); 340 $defaultValue = $defaultValue ? $defaultValue : key($itemArr);
  341 + //添加一个获取器
  342 + $this->getAttr($getAttrArr, $field, $itemArr, $inputType);
  343 + $this->appendAttr($appendAttrList, $field);
327 $formAddElement = "{:build_radios('{$fieldName}', [{$itemString}], '{$defaultValue}')}"; 344 $formAddElement = "{:build_radios('{$fieldName}', [{$itemString}], '{$defaultValue}')}";
328 $formEditElement = "{:build_radios('{$fieldName}', [{$itemString}], \$row.{$field})}"; 345 $formEditElement = "{:build_radios('{$fieldName}', [{$itemString}], \$row.{$field})}";
329 } 346 }
@@ -477,6 +494,9 @@ class Crud extends Command @@ -477,6 +494,9 @@ class Crud extends Command
477 'relationPrimaryKey' => '', 494 'relationPrimaryKey' => '',
478 'relationSearch' => $relation ? 'true' : 'false', 495 'relationSearch' => $relation ? 'true' : 'false',
479 'controllerIndex' => '', 496 'controllerIndex' => '',
  497 + 'appendAttrList' => implode(",\n", $appendAttrList),
  498 + 'getAttrList' => implode("\n\n", $getAttrArr),
  499 + 'setAttrList' => implode("\n\n", $setAttrArr),
480 'modelMethod' => '', 500 'modelMethod' => '',
481 ]; 501 ];
482 502
@@ -526,6 +546,79 @@ class Crud extends Command @@ -526,6 +546,79 @@ class Crud extends Command
526 $output->writeln("<info>Build Successed</info>"); 546 $output->writeln("<info>Build Successed</info>");
527 } 547 }
528 548
  549 + protected function getAttr(&$getAttr, $field, $itemArr = '', $inputType = '')
  550 + {
  551 + if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio']))
  552 + return;
  553 + $attrField = ucfirst($field);
  554 + if ($inputType == 'datetime')
  555 + {
  556 + $return = <<<EOD
  557 +\$value = \$data['{$field}'];
  558 + return is_numeric(\$value) ? date("Y-m-d H:i:s", \$value) : \$value;
  559 +EOD;
  560 + }
  561 + else if (in_array($inputType, ['multiple', 'checkbox']))
  562 + {
  563 + $itemString = $this->getArrayString($itemArr);
  564 + $return = <<<EOD
  565 +\$value = \$data['{$field}'];
  566 + \$valueArr = explode(',', \$value);
  567 + \$arr = [{$itemString}];
  568 + \$resultArr = [];
  569 + foreach (\$valueArr as \$k => \$v)
  570 + {
  571 + if (isset(\$arr[\$v]))
  572 + {
  573 + \$resultArr[] = \$arr[\$v];
  574 + }
  575 + }
  576 + return implode(',', \$resultArr);
  577 +EOD;
  578 + }
  579 + else
  580 + {
  581 + $itemString = $this->getArrayString($itemArr);
  582 + $return = <<<EOD
  583 +\$value = \$data['{$field}'];
  584 + \$arr = [{$itemString}];
  585 + return isset(\$arr[\$value]) ? \$arr[\$value] : '';
  586 +EOD;
  587 + }
  588 + $getAttr[] = <<<EOD
  589 + protected function get{$attrField}TextAttr(\$value, \$data)
  590 + {
  591 + $return
  592 + }
  593 +EOD;
  594 + }
  595 +
  596 + protected function setAttr(&$setAttr, $field, $itemArr = '', $inputType = '')
  597 + {
  598 + if ($inputType != 'datetime')
  599 + return;
  600 + $field = ucfirst($field);
  601 + if ($inputType == 'datetime')
  602 + {
  603 + $return = <<<EOD
  604 +return is_numeric(\$value) ? strtotime(\$value) : \$value;
  605 +EOD;
  606 + }
  607 + $setAttr[] = <<<EOD
  608 + protected function set{$field}TextAttr(\$value)
  609 + {
  610 + $return
  611 + }
  612 +EOD;
  613 + }
  614 +
  615 + protected function appendAttr(&$appendAttrList, $field)
  616 + {
  617 + $appendAttrList[] = <<<EOD
  618 + '{$field}_text'
  619 +EOD;
  620 + }
  621 +
529 protected function getModelName($model, $table) 622 protected function getModelName($model, $table)
530 { 623 {
531 if (!$model) 624 if (!$model)
@@ -747,7 +840,7 @@ EOD; @@ -747,7 +840,7 @@ EOD;
747 { 840 {
748 $lang = ucfirst($field); 841 $lang = ucfirst($field);
749 $html = str_repeat(" ", 24) . "{field: '{$field}', title: __('{$lang}')"; 842 $html = str_repeat(" ", 24) . "{field: '{$field}', title: __('{$lang}')";
750 - $field = substr($field, stripos($field, '.') + 1); 843 + $field = stripos($field, ".") !== false ? substr($field, stripos($field, '.') + 1) : $field;
751 $formatter = ''; 844 $formatter = '';
752 if ($field == 'status') 845 if ($field == 'status')
753 $formatter = 'status'; 846 $formatter = 'status';
@@ -16,5 +16,14 @@ class {%modelName%} extends Model @@ -16,5 +16,14 @@ class {%modelName%} extends Model
16 protected $createTime = {%createTime%}; 16 protected $createTime = {%createTime%};
17 protected $updateTime = {%updateTime%}; 17 protected $updateTime = {%updateTime%};
18 18
  19 + // 追加属性
  20 + protected $append = [
  21 +{%appendAttrList%}
  22 + ];
  23 +
  24 +{%getAttrList%}
  25 +
  26 +{%setAttrList%}
  27 +
19 {%modelMethod%} 28 {%modelMethod%}
20 } 29 }
@@ -23,6 +23,7 @@ trait Backend @@ -23,6 +23,7 @@ trait Backend
23 ->order($sort, $order) 23 ->order($sort, $order)
24 ->limit($offset, $limit) 24 ->limit($offset, $limit)
25 ->select(); 25 ->select();
  26 +
26 $result = array("total" => $total, "rows" => $list); 27 $result = array("total" => $total, "rows" => $list);
27 28
28 return json($result); 29 return json($result);
@@ -44,10 +45,27 @@ trait Backend @@ -44,10 +45,27 @@ trait Backend
44 foreach ($params as $k => &$v) 45 foreach ($params as $k => &$v)
45 { 46 {
46 $v = is_array($v) ? implode(',', $v) : $v; 47 $v = is_array($v) ? implode(',', $v) : $v;
47 - $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;  
48 } 48 }
49 - $this->model->create($params);  
50 - $this->code = 1; 49 + try
  50 + {
  51 + $result = $this->model->create($params);
  52 + if ($result !== false)
  53 + {
  54 + $this->code = 1;
  55 + }
  56 + else
  57 + {
  58 + $this->msg = $this->model->getError();
  59 + }
  60 + }
  61 + catch (think\Exception $e)
  62 + {
  63 + $this->msg = $e->getMessage();
  64 + }
  65 + }
  66 + else
  67 + {
  68 + $this->msg = __('Parameter %s can not be empty', '');
51 } 69 }
52 70
53 return; 71 return;
@@ -72,10 +90,27 @@ trait Backend @@ -72,10 +90,27 @@ trait Backend
72 foreach ($params as $k => &$v) 90 foreach ($params as $k => &$v)
73 { 91 {
74 $v = is_array($v) ? implode(',', $v) : $v; 92 $v = is_array($v) ? implode(',', $v) : $v;
75 - $v = substr($k, -4) == 'time' && !is_numeric($v) ? strtotime($v) : $v;  
76 } 93 }
77 - $row->save($params);  
78 - $this->code = 1; 94 + try
  95 + {
  96 + $result = $row->save($params);
  97 + if ($result !== false)
  98 + {
  99 + $this->code = 1;
  100 + }
  101 + else
  102 + {
  103 + $this->msg = $row->getError();
  104 + }
  105 + }
  106 + catch (think\Exception $e)
  107 + {
  108 + $this->msg = $e->getMessage();
  109 + }
  110 + }
  111 + else
  112 + {
  113 + $this->msg = __('Parameter %s can not be empty', '');
79 } 114 }
80 115
81 return; 116 return;
@@ -126,7 +161,7 @@ trait Backend @@ -126,7 +161,7 @@ trait Backend
126 } 161 }
127 else 162 else
128 { 163 {
129 - $this->code = 1; 164 + $this->msg = __('Parameter %s can not be empty', '');
130 } 165 }
131 } 166 }
132 167
@@ -92,7 +92,7 @@ class Backend extends Controller @@ -92,7 +92,7 @@ class Backend extends Controller
92 !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax()); 92 !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax());
93 93
94 // 非选项卡时重定向 94 // 非选项卡时重定向
95 - if (!IS_AJAX && !IS_ADDTABS && $controllername != 'index' && $actionname == 'index') 95 + if (!IS_AJAX && !IS_ADDTABS && !IS_DIALOG && $path !== "/{$modulename}/index/index" && $controllername != 'ajax')
96 { 96 {
97 $url = $this->request->url(); 97 $url = $this->request->url();
98 $this->redirect('index/index', [], 302, ['referer' => $url]); 98 $this->redirect('index/index', [], 302, ['referer' => $url]);
@@ -246,7 +246,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($ @@ -246,7 +246,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($
246 }); 246 });
247 }, 247 },
248 addtabs: function (url, title, icon) { 248 addtabs: function (url, title, icon) {
249 - var dom = ".sidebar-menu li a[url='{url}']" 249 + var dom = "a[url='{url}']"
250 var leftlink = top.window.$(dom.replace(/\{url\}/, url)); 250 var leftlink = top.window.$(dom.replace(/\{url\}/, url));
251 if (leftlink.size() > 0) { 251 if (leftlink.size() > 0) {
252 leftlink.trigger("click"); 252 leftlink.trigger("click");
@@ -273,7 +273,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($ @@ -273,7 +273,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang', 'moment'], function ($
273 var id = Math.floor(new Date().valueOf() * Math.random()); 273 var id = Math.floor(new Date().valueOf() * Math.random());
274 icon = typeof icon != 'undefined' ? icon : 'fa fa-circle-o'; 274 icon = typeof icon != 'undefined' ? icon : 'fa fa-circle-o';
275 title = typeof title != 'undefined' ? title : ''; 275 title = typeof title != 'undefined' ? title : '';
276 - 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"); 276 + 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");
277 } 277 }
278 } 278 }
279 } 279 }
@@ -76,9 +76,9 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func @@ -76,9 +76,9 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
76 stopOnError: true, 76 stopOnError: true,
77 valid: function (ret) { 77 valid: function (ret) {
78 //验证通过提交表单 78 //验证通过提交表单
79 - Form.api.submit(form, onBeforeSubmit, function (data) { 79 + Form.api.submit($(ret), onBeforeSubmit, function (data) {
80 if (typeof onAfterSubmit == 'function') { 80 if (typeof onAfterSubmit == 'function') {
81 - if (!onAfterSubmit.call(form, data)) { 81 + if (!onAfterSubmit.call($(ret), data)) {
82 return false; 82 return false;
83 } 83 }
84 } 84 }
@@ -239,7 +239,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func @@ -239,7 +239,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
239 $(document).on('click', ".fachoose", function () { 239 $(document).on('click', ".fachoose", function () {
240 var multiple = $(this).data("multiple") ? $(this).data("multiple") : false; 240 var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
241 var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : ''; 241 var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : '';
242 - Backend.api.open("general/attachment/select?callback=refreshchoose&element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype="+mimetype, __('Choose')); 242 + Backend.api.open("general/attachment/select?callback=refreshchoose&element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype=" + mimetype, __('Choose'));
243 return false; 243 return false;
244 }); 244 });
245 245