作者 Karson

新增CRUD生成回收站视图和JS文件

新增一键生成API文档排序功能
新增表格默认导出选项
新增buttons中text和title的function支持
修复buttons中visible和disable为false时的判断Bug
修复后台添加子管理员的权限错误
正在显示 35 个修改的文件 包含 533 行增加373 行删除
@@ -15,7 +15,6 @@ use think\exception\PDOException; @@ -15,7 +15,6 @@ use think\exception\PDOException;
15 15
16 class Addon extends Command 16 class Addon extends Command
17 { 17 {
18 -  
19 protected function configure() 18 protected function configure()
20 { 19 {
21 $this 20 $this
@@ -80,7 +79,6 @@ class Addon extends Command @@ -80,7 +79,6 @@ class Addon extends Command
80 $createTableSql = $result[0]['Create Table']; 79 $createTableSql = $result[0]['Create Table'];
81 } 80 }
82 } catch (PDOException $e) { 81 } catch (PDOException $e) {
83 -  
84 } 82 }
85 83
86 $data = [ 84 $data = [
@@ -235,7 +233,8 @@ class Addon extends Command @@ -235,7 +233,8 @@ class Addon extends Command
235 $zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); 233 $zip->open($addonFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
236 234
237 $files = new \RecursiveIteratorIterator( 235 $files = new \RecursiveIteratorIterator(
238 - new \RecursiveDirectoryIterator($addonDir), \RecursiveIteratorIterator::LEAVES_ONLY 236 + new \RecursiveDirectoryIterator($addonDir),
  237 + \RecursiveIteratorIterator::LEAVES_ONLY
239 ); 238 );
240 239
241 foreach ($files as $name => $file) { 240 foreach ($files as $name => $file) {
@@ -251,7 +250,7 @@ class Addon extends Command @@ -251,7 +250,7 @@ class Addon extends Command
251 $output->info("Package Successed!"); 250 $output->info("Package Successed!");
252 break; 251 break;
253 252
254 - default : 253 + default:
255 break; 254 break;
256 } 255 }
257 } 256 }
@@ -315,5 +314,4 @@ class Addon extends Command @@ -315,5 +314,4 @@ class Addon extends Command
315 { 314 {
316 return __DIR__ . '/Addon/stubs/' . $name . '.stub'; 315 return __DIR__ . '/Addon/stubs/' . $name . '.stub';
317 } 316 }
318 -  
319 } 317 }
@@ -12,7 +12,6 @@ use think\Exception; @@ -12,7 +12,6 @@ use think\Exception;
12 12
13 class Api extends Command 13 class Api extends Command
14 { 14 {
15 -  
16 protected function configure() 15 protected function configure()
17 { 16 {
18 $site = Config::get('site'); 17 $site = Config::get('site');
@@ -84,7 +83,8 @@ class Api extends Command @@ -84,7 +83,8 @@ class Api extends Command
84 83
85 $controllerDir = $moduleDir . Config::get('url_controller_layer') . DS; 84 $controllerDir = $moduleDir . Config::get('url_controller_layer') . DS;
86 $files = new \RecursiveIteratorIterator( 85 $files = new \RecursiveIteratorIterator(
87 - new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY 86 + new \RecursiveDirectoryIterator($controllerDir),
  87 + \RecursiveIteratorIterator::LEAVES_ONLY
88 ); 88 );
89 89
90 foreach ($files as $name => $file) { 90 foreach ($files as $name => $file) {
@@ -150,7 +150,7 @@ class Api extends Command @@ -150,7 +150,7 @@ class Api extends Command
150 150
151 //Append the token's value to the name of the namespace 151 //Append the token's value to the name of the namespace
152 $namespace .= $token[1]; 152 $namespace .= $token[1];
153 - } else if ($token === ';') { 153 + } elseif ($token === ';') {
154 154
155 //If the token is the semicolon, then we're done with the namespace declaration 155 //If the token is the semicolon, then we're done with the namespace declaration
156 $getting_namespace = false; 156 $getting_namespace = false;
@@ -175,5 +175,4 @@ class Api extends Command @@ -175,5 +175,4 @@ class Api extends Command
175 //Build the fully-qualified class name and return it 175 //Build the fully-qualified class name and return it
176 return $namespace ? $namespace . '\\' . $class : $class; 176 return $namespace ? $namespace . '\\' . $class : $class;
177 } 177 }
178 -  
179 } 178 }
@@ -36,16 +36,27 @@ class Builder @@ -36,16 +36,27 @@ class Builder
36 36
37 protected function extractAnnotations() 37 protected function extractAnnotations()
38 { 38 {
39 - $st_output = [];  
40 foreach ($this->classes as $class) { 39 foreach ($this->classes as $class) {
41 $classAnnotation = Extractor::getClassAnnotations($class); 40 $classAnnotation = Extractor::getClassAnnotations($class);
42 // 如果忽略 41 // 如果忽略
43 if (isset($classAnnotation['ApiInternal'])) { 42 if (isset($classAnnotation['ApiInternal'])) {
44 continue; 43 continue;
45 } 44 }
46 - $st_output[] = Extractor::getAllClassAnnotations($class); 45 + Extractor::getClassMethodAnnotations($class);
47 } 46 }
48 - return end($st_output); 47 + $allClassAnnotation = Extractor::getAllClassAnnotations();
  48 + $allClassMethodAnnotation = Extractor::getAllClassMethodAnnotations();
  49 +
  50 +// foreach ($allClassMethodAnnotation as $className => &$methods) {
  51 +// foreach ($methods as &$method) {
  52 +// //权重判断
  53 +// if ($method && !isset($method['ApiWeigh']) && isset($allClassAnnotation[$className]['ApiWeigh'])) {
  54 +// $method['ApiWeigh'] = $allClassAnnotation[$className]['ApiWeigh'];
  55 +// }
  56 +// }
  57 +// }
  58 +// unset($methods);
  59 + return [$allClassAnnotation, $allClassMethodAnnotation];
49 } 60 }
50 61
51 protected function generateHeadersTemplate($docs) 62 protected function generateHeadersTemplate($docs)
@@ -148,12 +159,19 @@ class Builder @@ -148,12 +159,19 @@ class Builder
148 159
149 public function parse() 160 public function parse()
150 { 161 {
151 - $annotations = $this->extractAnnotations(); 162 + list($allClassAnnotations, $allClassMethodAnnotations) = $this->extractAnnotations();
152 163
  164 + $sectorArr = [];
  165 + foreach ($allClassAnnotations as $index => $allClassAnnotation) {
  166 + $sector = isset($allClassAnnotation['ApiSector']) ? $allClassAnnotation['ApiSector'][0] : $allClassAnnotation['ApiTitle'][0];
  167 + $sectorArr[$sector] = isset($allClassAnnotation['ApiWeigh']) ? $allClassAnnotation['ApiWeigh'][0] : 0;
  168 + }
  169 + arsort($sectorArr);
153 $counter = 0; 170 $counter = 0;
154 $section = null; 171 $section = null;
  172 + $weigh = 0;
155 $docslist = []; 173 $docslist = [];
156 - foreach ($annotations as $class => $methods) { 174 + foreach ($allClassMethodAnnotations as $class => $methods) {
157 foreach ($methods as $name => $docs) { 175 foreach ($methods as $name => $docs) {
158 if (isset($docs['ApiSector'][0])) { 176 if (isset($docs['ApiSector'][0])) {
159 $section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0]; 177 $section = is_array($docs['ApiSector'][0]) ? $docs['ApiSector'][0]['data'] : $docs['ApiSector'][0];
@@ -163,25 +181,36 @@ class Builder @@ -163,25 +181,36 @@ class Builder
163 if (0 === count($docs)) { 181 if (0 === count($docs)) {
164 continue; 182 continue;
165 } 183 }
166 -  
167 - $docslist[$section][] = [ 184 + $docslist[$section][$name] = [
168 'id' => $counter, 185 'id' => $counter,
169 'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0], 186 'method' => is_array($docs['ApiMethod'][0]) ? $docs['ApiMethod'][0]['data'] : $docs['ApiMethod'][0],
170 'method_label' => $this->generateBadgeForMethod($docs), 187 'method_label' => $this->generateBadgeForMethod($docs),
171 'section' => $section, 188 'section' => $section,
172 'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0], 189 'route' => is_array($docs['ApiRoute'][0]) ? $docs['ApiRoute'][0]['data'] : $docs['ApiRoute'][0],
173 - 'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0], 190 + 'title' => is_array($docs['ApiTitle'][0]) ? $docs['ApiTitle'][0]['data'] : $docs['ApiTitle'][0],
174 'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0], 191 'summary' => is_array($docs['ApiSummary'][0]) ? $docs['ApiSummary'][0]['data'] : $docs['ApiSummary'][0],
175 'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '', 192 'body' => isset($docs['ApiBody'][0]) ? is_array($docs['ApiBody'][0]) ? $docs['ApiBody'][0]['data'] : $docs['ApiBody'][0] : '',
176 'headerslist' => $this->generateHeadersTemplate($docs), 193 'headerslist' => $this->generateHeadersTemplate($docs),
177 'paramslist' => $this->generateParamsTemplate($docs), 194 'paramslist' => $this->generateParamsTemplate($docs),
178 'returnheaderslist' => $this->generateReturnHeadersTemplate($docs), 195 'returnheaderslist' => $this->generateReturnHeadersTemplate($docs),
179 'returnparamslist' => $this->generateReturnParamsTemplate($docs), 196 'returnparamslist' => $this->generateReturnParamsTemplate($docs),
  197 + 'weigh' => is_array($docs['ApiWeigh'][0]) ? $docs['ApiWeigh'][0]['data'] : $docs['ApiWeigh'][0],
180 'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '', 198 'return' => isset($docs['ApiReturn']) ? is_array($docs['ApiReturn'][0]) ? $docs['ApiReturn'][0]['data'] : $docs['ApiReturn'][0] : '',
181 ]; 199 ];
182 $counter++; 200 $counter++;
183 } 201 }
184 } 202 }
  203 +
  204 + //重建排序
  205 + foreach ($docslist as $index => &$methods) {
  206 + $methodSectorArr = [];
  207 + foreach ($methods as $name => $method) {
  208 + $methodSectorArr[$name] = isset($method['weigh']) ? $method['weigh'] : 0;
  209 + }
  210 + arsort($methodSectorArr);
  211 + $methods = array_merge(array_flip(array_keys($methodSectorArr)), $methods);
  212 + }
  213 + $docslist = array_merge(array_flip(array_keys($sectorArr)), $docslist);
185 214
186 return $docslist; 215 return $docslist;
187 } 216 }
@@ -203,5 +232,4 @@ class Builder @@ -203,5 +232,4 @@ class Builder
203 232
204 return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist])); 233 return $this->view->display(file_get_contents($template), array_merge($vars, ['docslist' => $docslist]));
205 } 234 }
206 -  
207 } 235 }
@@ -20,6 +20,10 @@ class Extractor @@ -20,6 +20,10 @@ class Extractor
20 */ 20 */
21 private static $annotationCache; 21 private static $annotationCache;
22 22
  23 + private static $classAnnotationCache;
  24 +
  25 + private static $classMethodAnnotationCache;
  26 +
23 /** 27 /**
24 * Indicates that annotations should has strict behavior, 'false' by default 28 * Indicates that annotations should has strict behavior, 'false' by default
25 * @var boolean 29 * @var boolean
@@ -63,27 +67,43 @@ class Extractor @@ -63,27 +67,43 @@ class Extractor
63 * Gets all anotations with pattern @SomeAnnotation() from a given class 67 * Gets all anotations with pattern @SomeAnnotation() from a given class
64 * 68 *
65 * @param string $className class name to get annotations 69 * @param string $className class name to get annotations
66 - * @return array self::$annotationCache all annotated elements 70 + * @return array self::$classAnnotationCache all annotated elements
67 */ 71 */
68 public static function getClassAnnotations($className) 72 public static function getClassAnnotations($className)
69 { 73 {
70 - if (!isset(self::$annotationCache[$className])) { 74 + if (!isset(self::$classAnnotationCache[$className])) {
71 $class = new \ReflectionClass($className); 75 $class = new \ReflectionClass($className);
72 - self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment()); 76 + self::$classAnnotationCache[$className] = self::parseAnnotations($class->getDocComment());
73 } 77 }
74 78
75 - return self::$annotationCache[$className]; 79 + return self::$classAnnotationCache[$className];
76 } 80 }
77 81
78 - public static function getAllClassAnnotations($className) 82 + /**
  83 + * 获取类所有方法的属性配置
  84 + * @param $className
  85 + * @return mixed
  86 + * @throws \ReflectionException
  87 + */
  88 + public static function getClassMethodAnnotations($className)
79 { 89 {
80 $class = new \ReflectionClass($className); 90 $class = new \ReflectionClass($className);
81 91
82 foreach ($class->getMethods() as $object) { 92 foreach ($class->getMethods() as $object) {
83 - self::$annotationCache['annotations'][$className][$object->name] = self::getMethodAnnotations($className, $object->name); 93 + self::$classMethodAnnotationCache[$className][$object->name] = self::getMethodAnnotations($className, $object->name);
84 } 94 }
85 95
86 - return self::$annotationCache['annotations']; 96 + return self::$classMethodAnnotationCache[$className];
  97 + }
  98 +
  99 + public static function getAllClassAnnotations()
  100 + {
  101 + return self::$classAnnotationCache;
  102 + }
  103 +
  104 + public static function getAllClassMethodAnnotations()
  105 + {
  106 + return self::$classMethodAnnotationCache;
87 } 107 }
88 108
89 /** 109 /**
@@ -181,14 +201,14 @@ class Extractor @@ -181,14 +201,14 @@ class Extractor
181 preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr); 201 preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblockMethod), $methodArr);
182 preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr); 202 preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $dockblockClass), $classArr);
183 203
184 - $methodTitle = isset($methodArr[1]) && isset($methodArr[1][0]) ? $methodArr[1][0] : '';  
185 - $classTitle = isset($classArr[1]) && isset($classArr[1][0]) ? $classArr[1][0] : '';  
186 -  
187 if (!isset($methodAnnotations['ApiMethod'])) { 204 if (!isset($methodAnnotations['ApiMethod'])) {
188 $methodAnnotations['ApiMethod'] = ['get']; 205 $methodAnnotations['ApiMethod'] = ['get'];
189 } 206 }
  207 + if (!isset($methodAnnotations['ApiWeigh'])) {
  208 + $methodAnnotations['ApiWeigh'] = [0];
  209 + }
190 if (!isset($methodAnnotations['ApiSummary'])) { 210 if (!isset($methodAnnotations['ApiSummary'])) {
191 - $methodAnnotations['ApiSummary'] = [$methodTitle]; 211 + $methodAnnotations['ApiSummary'] = $methodAnnotations['ApiTitle'];
192 } 212 }
193 213
194 if ($methodAnnotations) { 214 if ($methodAnnotations) {
@@ -210,9 +230,6 @@ class Extractor @@ -210,9 +230,6 @@ class Extractor
210 } 230 }
211 } 231 }
212 } 232 }
213 - if (!isset($methodAnnotations['ApiTitle'])) {  
214 - $methodAnnotations['ApiTitle'] = [$methodTitle];  
215 - }  
216 if (!isset($methodAnnotations['ApiRoute'])) { 233 if (!isset($methodAnnotations['ApiRoute'])) {
217 $urlArr = []; 234 $urlArr = [];
218 $className = $class->getName(); 235 $className = $class->getName();
@@ -231,7 +248,7 @@ class Extractor @@ -231,7 +248,7 @@ class Extractor
231 $methodAnnotations['ApiRoute'] = [implode('/', $urlArr)]; 248 $methodAnnotations['ApiRoute'] = [implode('/', $urlArr)];
232 } 249 }
233 if (!isset($methodAnnotations['ApiSector'])) { 250 if (!isset($methodAnnotations['ApiSector'])) {
234 - $methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : [$classTitle]; 251 + $methodAnnotations['ApiSector'] = isset($classAnnotations['ApiSector']) ? $classAnnotations['ApiSector'] : $classAnnotations['ApiTitle'];
235 } 252 }
236 if (!isset($methodAnnotations['ApiParams'])) { 253 if (!isset($methodAnnotations['ApiParams'])) {
237 $params = self::parseCustomAnnotations($docblockMethod, 'param'); 254 $params = self::parseCustomAnnotations($docblockMethod, 'param');
@@ -292,7 +309,7 @@ class Extractor @@ -292,7 +309,7 @@ class Extractor
292 $argsParts = trim($matches['args'][$i]); 309 $argsParts = trim($matches['args'][$i]);
293 if ($name == 'ApiReturn') { 310 if ($name == 'ApiReturn') {
294 $value = $argsParts; 311 $value = $argsParts;
295 - } else if ($matches['args'][$i] != '') { 312 + } elseif ($matches['args'][$i] != '') {
296 $argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts); 313 $argsParts = preg_replace("/\{(\w+)\}/", '#$1#', $argsParts);
297 $value = self::parseArgs($argsParts); 314 $value = self::parseArgs($argsParts);
298 if (is_string($value)) { 315 if (is_string($value)) {
@@ -307,6 +324,11 @@ class Extractor @@ -307,6 +324,11 @@ class Extractor
307 if (stripos($docblock, '@ApiInternal') !== false) { 324 if (stripos($docblock, '@ApiInternal') !== false) {
308 $annotations['ApiInternal'] = [true]; 325 $annotations['ApiInternal'] = [true];
309 } 326 }
  327 + if (!isset($annotations['ApiTitle'])) {
  328 + preg_match_all("/\*[\s]+(.*)(\\r\\n|\\r|\\n)/U", str_replace('/**', '', $docblock), $matchArr);
  329 + $title = isset($matchArr[1]) && isset($matchArr[1][0]) ? $matchArr[1][0] : '';
  330 + $annotations['ApiTitle'] = [$title];
  331 + }
310 332
311 return $annotations; 333 return $annotations;
312 } 334 }
@@ -354,7 +376,9 @@ class Extractor @@ -354,7 +376,9 @@ class Extractor
354 // close delimiter 376 // close delimiter
355 if ($c !== $nextDelimiter) { 377 if ($c !== $nextDelimiter) {
356 throw new Exception(sprintf( 378 throw new Exception(sprintf(
357 - "Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c 379 + "Parse Error: enclosing error -> expected: [%s], given: [%s]",
  380 + $nextDelimiter,
  381 + $c
358 )); 382 ));
359 } 383 }
360 384
@@ -362,7 +386,8 @@ class Extractor @@ -362,7 +386,8 @@ class Extractor
362 if ($i < $len) { 386 if ($i < $len) {
363 if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) { 387 if (',' !== substr($content, $i, 1) && '\\' !== $prev_c) {
364 throw new Exception(sprintf( 388 throw new Exception(sprintf(
365 - "Parse Error: missing comma separator near: ...%s<--", substr($content, ($i - 10), $i) 389 + "Parse Error: missing comma separator near: ...%s<--",
  390 + substr($content, ($i - 10), $i)
366 )); 391 ));
367 } 392 }
368 } 393 }
@@ -387,7 +412,9 @@ class Extractor @@ -387,7 +412,9 @@ class Extractor
387 // it means that the string was not enclosed, so it is parsing error. 412 // it means that the string was not enclosed, so it is parsing error.
388 if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) { 413 if ($composing === true && !empty($prevDelimiter) && !empty($nextDelimiter)) {
389 throw new Exception(sprintf( 414 throw new Exception(sprintf(
390 - "Parse Error: enclosing error -> expected: [%s], given: [%s]", $nextDelimiter, $c 415 + "Parse Error: enclosing error -> expected: [%s], given: [%s]",
  416 + $nextDelimiter,
  417 + $c
391 )); 418 ));
392 } 419 }
393 420
@@ -416,7 +443,8 @@ class Extractor @@ -416,7 +443,8 @@ class Extractor
416 // if the string is composing yet means that the structure of var. never was enclosed with '}' 443 // if the string is composing yet means that the structure of var. never was enclosed with '}'
417 if ($subComposing) { 444 if ($subComposing) {
418 throw new Exception(sprintf( 445 throw new Exception(sprintf(
419 - "Parse Error: Composite variable is not enclosed correctly. near: ...%s'", $subc 446 + "Parse Error: Composite variable is not enclosed correctly. near: ...%s'",
  447 + $subc
420 )); 448 ));
421 } 449 }
422 450
@@ -479,5 +507,4 @@ class Extractor @@ -479,5 +507,4 @@ class Extractor
479 507
480 return $val; 508 return $val;
481 } 509 }
482 -  
483 } 510 }
@@ -92,6 +92,9 @@ @@ -92,6 +92,9 @@
92 padding-left:0px; 92 padding-left:0px;
93 } 93 }
94 } 94 }
  95 + .label-primary {
  96 + background-color: #248aff;
  97 + }
95 98
96 </style> 99 </style>
97 </head> 100 </head>
@@ -547,6 +550,9 @@ @@ -547,6 +550,9 @@
547 contentType: false, 550 contentType: false,
548 processData: false, 551 processData: false,
549 headers: headers, 552 headers: headers,
  553 + xhrFields: {
  554 + withCredentials: true
  555 + },
550 success: function (data, textStatus, xhr) { 556 success: function (data, textStatus, xhr) {
551 if (typeof data === 'object') { 557 if (typeof data === 'object') {
552 var str = JSON.stringify(data, null, 2); 558 var str = JSON.stringify(data, null, 2);
@@ -15,7 +15,6 @@ use think\Loader; @@ -15,7 +15,6 @@ use think\Loader;
15 15
16 class Crud extends Command 16 class Crud extends Command
17 { 17 {
18 -  
19 protected $stubList = []; 18 protected $stubList = [];
20 19
21 /** 20 /**
@@ -93,7 +92,7 @@ class Crud extends Command @@ -93,7 +92,7 @@ class Crud extends Command
93 /** 92 /**
94 * 保留字段 93 * 保留字段
95 */ 94 */
96 - protected $reservedField = ['admin_id', 'createtime', 'updatetime']; 95 + protected $reservedField = ['admin_id'];
97 96
98 /** 97 /**
99 * 排除字段 98 * 排除字段
@@ -112,13 +111,31 @@ class Crud extends Command @@ -112,13 +111,31 @@ class Crud extends Command
112 protected $headingFilterField = 'status'; 111 protected $headingFilterField = 'status';
113 112
114 /** 113 /**
  114 + * 添加时间字段
  115 + * @var string
  116 + */
  117 + protected $createTimeField = 'createtime';
  118 +
  119 + /**
  120 + * 更新时间字段
  121 + * @var string
  122 + */
  123 + protected $updateTimeField = 'updatetime';
  124 +
  125 + /**
  126 + * 软删除时间字段
  127 + * @var string
  128 + */
  129 + protected $deleteTimeField = 'deletetime';
  130 +
  131 + /**
115 * 编辑器的Class 132 * 编辑器的Class
116 */ 133 */
117 protected $editorClass = 'editor'; 134 protected $editorClass = 'editor';
118 135
119 /** 136 /**
120 * langList的key最长字节数 137 * langList的key最长字节数
121 - */ 138 + */
122 protected $fieldMaxLen = 0; 139 protected $fieldMaxLen = 0;
123 140
124 protected function configure() 141 protected function configure()
@@ -215,32 +232,47 @@ class Crud extends Command @@ -215,32 +232,47 @@ class Crud extends Command
215 $headingfilterfield = $input->getOption('headingfilterfield'); 232 $headingfilterfield = $input->getOption('headingfilterfield');
216 //编辑器Class 233 //编辑器Class
217 $editorclass = $input->getOption('editorclass'); 234 $editorclass = $input->getOption('editorclass');
218 - if ($setcheckboxsuffix) 235 + if ($setcheckboxsuffix) {
219 $this->setCheckboxSuffix = $setcheckboxsuffix; 236 $this->setCheckboxSuffix = $setcheckboxsuffix;
220 - if ($enumradiosuffix) 237 + }
  238 + if ($enumradiosuffix) {
221 $this->enumRadioSuffix = $enumradiosuffix; 239 $this->enumRadioSuffix = $enumradiosuffix;
222 - if ($imagefield) 240 + }
  241 + if ($imagefield) {
223 $this->imageField = $imagefield; 242 $this->imageField = $imagefield;
224 - if ($filefield) 243 + }
  244 + if ($filefield) {
225 $this->fileField = $filefield; 245 $this->fileField = $filefield;
226 - if ($intdatesuffix) 246 + }
  247 + if ($intdatesuffix) {
227 $this->intDateSuffix = $intdatesuffix; 248 $this->intDateSuffix = $intdatesuffix;
228 - if ($switchsuffix) 249 + }
  250 + if ($switchsuffix) {
229 $this->switchSuffix = $switchsuffix; 251 $this->switchSuffix = $switchsuffix;
230 - if ($citysuffix) 252 + }
  253 + if ($citysuffix) {
231 $this->citySuffix = $citysuffix; 254 $this->citySuffix = $citysuffix;
232 - if ($selectpagesuffix) 255 + }
  256 + if ($selectpagesuffix) {
233 $this->selectpageSuffix = $selectpagesuffix; 257 $this->selectpageSuffix = $selectpagesuffix;
234 - if ($selectpagessuffix) 258 + }
  259 + if ($selectpagessuffix) {
235 $this->selectpagesSuffix = $selectpagessuffix; 260 $this->selectpagesSuffix = $selectpagessuffix;
236 - if ($ignoreFields) 261 + }
  262 + if ($ignoreFields) {
237 $this->ignoreFields = $ignoreFields; 263 $this->ignoreFields = $ignoreFields;
238 - if ($editorclass) 264 + }
  265 + if ($editorclass) {
239 $this->editorClass = $editorclass; 266 $this->editorClass = $editorclass;
240 - if ($sortfield) 267 + }
  268 + if ($sortfield) {
241 $this->sortField = $sortfield; 269 $this->sortField = $sortfield;
242 - if ($headingfilterfield) 270 + }
  271 + if ($headingfilterfield) {
243 $this->headingFilterField = $headingfilterfield; 272 $this->headingFilterField = $headingfilterfield;
  273 + }
  274 +
  275 + $this->reservedField = array_merge($this->reservedField, [$this->createTimeField, $this->updateTimeField, $this->deleteTimeField]);
244 276
245 $dbname = Config::get('database.database'); 277 $dbname = Config::get('database.database');
246 $prefix = Config::get('database.prefix'); 278 $prefix = Config::get('database.prefix');
@@ -254,11 +286,11 @@ class Crud extends Command @@ -254,11 +286,11 @@ class Crud extends Command
254 $modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table; 286 $modelName = $table = stripos($table, $prefix) === 0 ? substr($table, strlen($prefix)) : $table;
255 $modelTableType = 'table'; 287 $modelTableType = 'table';
256 $modelTableTypeName = $modelTableName = $modelName; 288 $modelTableTypeName = $modelTableName = $modelName;
257 - $modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], TRUE); 289 + $modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
258 if (!$modelTableInfo) { 290 if (!$modelTableInfo) {
259 $modelTableType = 'name'; 291 $modelTableType = 'name';
260 $modelTableName = $prefix . $modelName; 292 $modelTableName = $prefix . $modelName;
261 - $modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], TRUE); 293 + $modelTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$modelTableName}'", [], true);
262 if (!$modelTableInfo) { 294 if (!$modelTableInfo) {
263 throw new Exception("table not found"); 295 throw new Exception("table not found");
264 } 296 }
@@ -275,11 +307,11 @@ class Crud extends Command @@ -275,11 +307,11 @@ class Crud extends Command
275 $relationName = stripos($relationTable, $prefix) === 0 ? substr($relationTable, strlen($prefix)) : $relationTable; 307 $relationName = stripos($relationTable, $prefix) === 0 ? substr($relationTable, strlen($prefix)) : $relationTable;
276 $relationTableType = 'table'; 308 $relationTableType = 'table';
277 $relationTableTypeName = $relationTableName = $relationName; 309 $relationTableTypeName = $relationTableName = $relationName;
278 - $relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], TRUE); 310 + $relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], true);
279 if (!$relationTableInfo) { 311 if (!$relationTableInfo) {
280 $relationTableType = 'name'; 312 $relationTableType = 'name';
281 $relationTableName = $prefix . $relationName; 313 $relationTableName = $prefix . $relationName;
282 - $relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], TRUE); 314 + $relationTableInfo = Db::query("SHOW TABLE STATUS LIKE '{$relationTableName}'", [], true);
283 if (!$relationTableInfo) { 315 if (!$relationTableInfo) {
284 throw new Exception("relation table not found"); 316 throw new Exception("relation table not found");
285 } 317 }
@@ -338,6 +370,7 @@ class Crud extends Command @@ -338,6 +370,7 @@ class Crud extends Command
338 $addFile = $viewDir . 'add.html'; 370 $addFile = $viewDir . 'add.html';
339 $editFile = $viewDir . 'edit.html'; 371 $editFile = $viewDir . 'edit.html';
340 $indexFile = $viewDir . 'index.html'; 372 $indexFile = $viewDir . 'index.html';
  373 + $recyclebinFile = $viewDir . 'recyclebin.html';
341 $langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerBaseName . '.php'; 374 $langFile = $adminPath . 'lang' . DS . Lang::detect() . DS . $controllerBaseName . '.php';
342 375
343 //是否为删除模式 376 //是否为删除模式
@@ -355,12 +388,13 @@ class Crud extends Command @@ -355,12 +388,13 @@ class Crud extends Command
355 } 388 }
356 } 389 }
357 foreach ($readyFiles as $k => $v) { 390 foreach ($readyFiles as $k => $v) {
358 - if (file_exists($v)) 391 + if (file_exists($v)) {
359 unlink($v); 392 unlink($v);
  393 + }
360 //删除空文件夹 394 //删除空文件夹
361 if ($v == $modelFile) { 395 if ($v == $modelFile) {
362 $this->removeEmptyBaseDir($v, $modelArr); 396 $this->removeEmptyBaseDir($v, $modelArr);
363 - } else if ($v == $validateFile) { 397 + } elseif ($v == $validateFile) {
364 $this->removeEmptyBaseDir($v, $validateArr); 398 $this->removeEmptyBaseDir($v, $validateArr);
365 } else { 399 } else {
366 $this->removeEmptyBaseDir($v, $controllerArr); 400 $this->removeEmptyBaseDir($v, $controllerArr);
@@ -434,7 +468,7 @@ class Crud extends Command @@ -434,7 +468,7 @@ class Crud extends Command
434 $langList = []; 468 $langList = [];
435 $field = 'id'; 469 $field = 'id';
436 $order = 'id'; 470 $order = 'id';
437 - $priDefined = FALSE; 471 + $priDefined = false;
438 $priKey = ''; 472 $priKey = '';
439 $relationPrimaryKey = ''; 473 $relationPrimaryKey = '';
440 foreach ($columnList as $k => $v) { 474 foreach ($columnList as $k => $v) {
@@ -484,6 +518,7 @@ class Crud extends Command @@ -484,6 +518,7 @@ class Crud extends Command
484 $appendAttrList = []; 518 $appendAttrList = [];
485 $controllerAssignList = []; 519 $controllerAssignList = [];
486 $headingHtml = '{:build_heading()}'; 520 $headingHtml = '{:build_heading()}';
  521 + $recyclebinHtml = '';
487 522
488 //循环所有字段,开始构造视图的HTML和JS信息 523 //循环所有字段,开始构造视图的HTML和JS信息
489 foreach ($columnList as $k => $v) { 524 foreach ($columnList as $k => $v) {
@@ -506,7 +541,7 @@ class Crud extends Command @@ -506,7 +541,7 @@ class Crud extends Command
506 $langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']); 541 $langList[] = $this->getLangItem($field, $v['COLUMN_COMMENT']);
507 } 542 }
508 $inputType = ''; 543 $inputType = '';
509 - //createtime和updatetime是保留字段不能修改和添加 544 + //保留字段不能修改和添加
510 if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField) && !in_array($field, $this->ignoreFields)) { 545 if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField) && !in_array($field, $this->ignoreFields)) {
511 $inputType = $this->getFieldType($v); 546 $inputType = $this->getFieldType($v);
512 547
@@ -534,7 +569,7 @@ class Crud extends Command @@ -534,7 +569,7 @@ class Crud extends Command
534 569
535 $this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select'); 570 $this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
536 571
537 - $itemArr = $this->getLangArray($itemArr, FALSE); 572 + $itemArr = $this->getLangArray($itemArr, false);
538 //添加一个获取器 573 //添加一个获取器
539 $this->getAttr($getAttrArr, $field, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select'); 574 $this->getAttr($getAttrArr, $field, $v['DATA_TYPE'] == 'set' ? 'multiple' : 'select');
540 if ($v['DATA_TYPE'] == 'set') { 575 if ($v['DATA_TYPE'] == 'set') {
@@ -543,28 +578,29 @@ class Crud extends Command @@ -543,28 +578,29 @@ class Crud extends Command
543 $this->appendAttr($appendAttrList, $field); 578 $this->appendAttr($appendAttrList, $field);
544 $formAddElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]); 579 $formAddElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
545 $formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]); 580 $formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
546 - } else if ($inputType == 'datetime') { 581 + } elseif ($inputType == 'datetime') {
547 $cssClassArr[] = 'datetimepicker'; 582 $cssClassArr[] = 'datetimepicker';
548 $attrArr['class'] = implode(' ', $cssClassArr); 583 $attrArr['class'] = implode(' ', $cssClassArr);
549 $format = "YYYY-MM-DD HH:mm:ss"; 584 $format = "YYYY-MM-DD HH:mm:ss";
550 $phpFormat = "Y-m-d H:i:s"; 585 $phpFormat = "Y-m-d H:i:s";
551 $fieldFunc = ''; 586 $fieldFunc = '';
552 switch ($v['DATA_TYPE']) { 587 switch ($v['DATA_TYPE']) {
553 - case 'year'; 588 + case 'year':
554 $format = "YYYY"; 589 $format = "YYYY";
555 $phpFormat = 'Y'; 590 $phpFormat = 'Y';
556 break; 591 break;
557 - case 'date'; 592 + case 'date':
558 $format = "YYYY-MM-DD"; 593 $format = "YYYY-MM-DD";
559 $phpFormat = 'Y-m-d'; 594 $phpFormat = 'Y-m-d';
560 break; 595 break;
561 - case 'time'; 596 + case 'time':
562 $format = "HH:mm:ss"; 597 $format = "HH:mm:ss";
563 $phpFormat = 'H:i:s'; 598 $phpFormat = 'H:i:s';
564 break; 599 break;
565 - case 'timestamp'; 600 + case 'timestamp':
566 $fieldFunc = 'datetime'; 601 $fieldFunc = 'datetime';
567 - case 'datetime'; 602 + // no break
  603 + case 'datetime':
568 $format = "YYYY-MM-DD HH:mm:ss"; 604 $format = "YYYY-MM-DD HH:mm:ss";
569 $phpFormat = 'Y-m-d H:i:s'; 605 $phpFormat = 'Y-m-d H:i:s';
570 break; 606 break;
@@ -581,13 +617,13 @@ class Crud extends Command @@ -581,13 +617,13 @@ class Crud extends Command
581 $fieldFunc = $fieldFunc ? "|{$fieldFunc}" : ""; 617 $fieldFunc = $fieldFunc ? "|{$fieldFunc}" : "";
582 $formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr); 618 $formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr);
583 $formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr); 619 $formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr);
584 - } else if ($inputType == 'checkbox' || $inputType == 'radio') { 620 + } elseif ($inputType == 'checkbox' || $inputType == 'radio') {
585 unset($attrArr['data-rule']); 621 unset($attrArr['data-rule']);
586 $fieldName = $inputType == 'checkbox' ? $fieldName .= "[]" : $fieldName; 622 $fieldName = $inputType == 'checkbox' ? $fieldName .= "[]" : $fieldName;
587 $attrArr['name'] = "row[{$fieldName}]"; 623 $attrArr['name'] = "row[{$fieldName}]";
588 624
589 $this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $inputType); 625 $this->getEnum($getEnumArr, $controllerAssignList, $field, $itemArr, $inputType);
590 - $itemArr = $this->getLangArray($itemArr, FALSE); 626 + $itemArr = $this->getLangArray($itemArr, false);
591 //添加一个获取器 627 //添加一个获取器
592 $this->getAttr($getAttrArr, $field, $inputType); 628 $this->getAttr($getAttrArr, $field, $inputType);
593 if ($inputType == 'checkbox') { 629 if ($inputType == 'checkbox') {
@@ -598,13 +634,13 @@ class Crud extends Command @@ -598,13 +634,13 @@ class Crud extends Command
598 634
599 $formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]); 635 $formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => $defaultValue]);
600 $formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]); 636 $formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
601 - } else if ($inputType == 'textarea') { 637 + } elseif ($inputType == 'textarea') {
602 $cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : ''; 638 $cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : '';
603 $attrArr['class'] = implode(' ', $cssClassArr); 639 $attrArr['class'] = implode(' ', $cssClassArr);
604 $attrArr['rows'] = 5; 640 $attrArr['rows'] = 5;
605 $formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr); 641 $formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
606 $formEditElement = Form::textarea($fieldName, $editValue, $attrArr); 642 $formEditElement = Form::textarea($fieldName, $editValue, $attrArr);
607 - } else if ($inputType == 'switch') { 643 + } elseif ($inputType == 'switch') {
608 unset($attrArr['data-rule']); 644 unset($attrArr['data-rule']);
609 if ($defaultValue === '1' || $defaultValue === 'Y') { 645 if ($defaultValue === '1' || $defaultValue === 'Y') {
610 $yes = $defaultValue; 646 $yes = $defaultValue;
@@ -619,7 +655,7 @@ class Crud extends Command @@ -619,7 +655,7 @@ class Crud extends Command
619 $stateNoClass = 'fa-flip-horizontal text-gray'; 655 $stateNoClass = 'fa-flip-horizontal text-gray';
620 $formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']); 656 $formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']);
621 $formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]); 657 $formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]);
622 - } else if ($inputType == 'citypicker') { 658 + } elseif ($inputType == 'citypicker') {
623 $attrArr['class'] = implode(' ', $cssClassArr); 659 $attrArr['class'] = implode(' ', $cssClassArr);
624 $attrArr['data-toggle'] = "city-picker"; 660 $attrArr['data-toggle'] = "city-picker";
625 $formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr)); 661 $formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
@@ -692,9 +728,13 @@ class Crud extends Command @@ -692,9 +728,13 @@ class Crud extends Command
692 if ($v['DATA_TYPE'] != 'text') { 728 if ($v['DATA_TYPE'] != 'text') {
693 //主键 729 //主键
694 if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined) { 730 if ($v['COLUMN_KEY'] == 'PRI' && !$priDefined) {
695 - $priDefined = TRUE; 731 + $priDefined = true;
696 $javascriptList[] = "{checkbox: true}"; 732 $javascriptList[] = "{checkbox: true}";
697 } 733 }
  734 + if ($this->deleteTimeField == $field) {
  735 + $recyclebinHtml = $this->getReplacedStub('html/recyclebin-html', ['controllerUrl' => $controllerUrl]);
  736 + continue;
  737 + }
698 if (!$fields || in_array($field, explode(',', $fields))) { 738 if (!$fields || in_array($field, explode(',', $fields))) {
699 //构造JS列信息 739 //构造JS列信息
700 $javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], $inputType && in_array($inputType, ['select', 'checkbox', 'radio']) ? '_text' : '', $itemArr); 740 $javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], $inputType && in_array($inputType, ['select', 'checkbox', 'radio']) ? '_text' : '', $itemArr);
@@ -743,7 +783,7 @@ class Crud extends Command @@ -743,7 +783,7 @@ class Crud extends Command
743 } 783 }
744 } 784 }
745 unset($line); 785 unset($line);
746 - $langList = implode(",\n", array_filter($langList)). ","; 786 + $langList = implode(",\n", array_filter($langList)) . ",";
747 787
748 //表注释 788 //表注释
749 $tableComment = $modelTableInfo['Comment']; 789 $tableComment = $modelTableInfo['Comment'];
@@ -754,7 +794,6 @@ class Crud extends Command @@ -754,7 +794,6 @@ class Crud extends Command
754 $modelInit = $this->getReplacedStub('mixins' . DS . 'modelinit', ['order' => $order]); 794 $modelInit = $this->getReplacedStub('mixins' . DS . 'modelinit', ['order' => $order]);
755 } 795 }
756 796
757 -  
758 $data = [ 797 $data = [
759 'controllerNamespace' => $controllerNamespace, 798 'controllerNamespace' => $controllerNamespace,
760 'modelNamespace' => $modelNamespace, 799 'modelNamespace' => $modelNamespace,
@@ -777,14 +816,18 @@ class Crud extends Command @@ -777,14 +816,18 @@ class Crud extends Command
777 'editList' => $editList, 816 'editList' => $editList,
778 'javascriptList' => $javascriptList, 817 'javascriptList' => $javascriptList,
779 'langList' => $langList, 818 'langList' => $langList,
780 - 'modelAutoWriteTimestamp' => in_array('createtime', $fieldArr) || in_array('updatetime', $fieldArr) ? "'int'" : 'false',  
781 - 'createTime' => in_array('createtime', $fieldArr) ? "'createtime'" : 'false',  
782 - 'updateTime' => in_array('updatetime', $fieldArr) ? "'updatetime'" : 'false', 819 + 'sofeDeleteClassPath' => in_array($this->deleteTimeField, $fieldArr) ? "use traits\model\SoftDelete;" : '',
  820 + 'softDelete' => in_array($this->deleteTimeField, $fieldArr) ? "use SoftDelete;" : '',
  821 + 'modelAutoWriteTimestamp' => in_array($this->createTimeField, $fieldArr) || in_array($this->updateTimeField, $fieldArr) ? "'int'" : 'false',
  822 + 'createTime' => in_array($this->createTimeField, $fieldArr) ? "'{$this->createTimeField}'" : 'false',
  823 + 'updateTime' => in_array($this->updateTimeField, $fieldArr) ? "'{$this->updateTimeField}'" : 'false',
  824 + 'deleteTime' => in_array($this->deleteTimeField, $fieldArr) ? "'{$this->deleteTimeField}'" : 'false',
783 'relationSearch' => $relations ? 'true' : 'false', 825 'relationSearch' => $relations ? 'true' : 'false',
784 'relationWithList' => '', 826 'relationWithList' => '',
785 'relationMethodList' => '', 827 'relationMethodList' => '',
786 'controllerIndex' => '', 828 'controllerIndex' => '',
787 'headingHtml' => $headingHtml, 829 'headingHtml' => $headingHtml,
  830 + 'recyclebinHtml' => $recyclebinHtml,
788 'visibleFieldList' => $fields ? "\$row->visible(['" . implode("','", array_filter(explode(',', $fields))) . "']);" : '', 831 'visibleFieldList' => $fields ? "\$row->visible(['" . implode("','", array_filter(explode(',', $fields))) . "']);" : '',
789 'appendAttrList' => implode(",\n", $appendAttrList), 832 'appendAttrList' => implode(",\n", $appendAttrList),
790 'getEnumList' => implode("\n\n", $getEnumArr), 833 'getEnumList' => implode("\n\n", $getEnumArr),
@@ -832,8 +875,7 @@ class Crud extends Command @@ -832,8 +875,7 @@ class Crud extends Command
832 875
833 //需要重写index方法 876 //需要重写index方法
834 $data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data); 877 $data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
835 -  
836 - } else if ($fields) { 878 + } elseif ($fields) {
837 $data = array_merge($data, ['relationWithList' => '', 'relationMethodList' => '', 'relationVisibleFieldList' => '']); 879 $data = array_merge($data, ['relationWithList' => '', 'relationMethodList' => '', 'relationVisibleFieldList' => '']);
838 //需要重写index方法 880 //需要重写index方法
839 $data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data); 881 $data['controllerIndex'] = $this->getReplacedStub('controllerindex', $data);
@@ -852,7 +894,6 @@ class Crud extends Command @@ -852,7 +894,6 @@ class Crud extends Command
852 $result = $this->writeToFile('relationmodel', $relation, $relation['relationFile']); 894 $result = $this->writeToFile('relationmodel', $relation, $relation['relationFile']);
853 } 895 }
854 } 896 }
855 -  
856 } 897 }
857 // 生成验证文件 898 // 生成验证文件
858 $result = $this->writeToFile('validate', $data, $validateFile); 899 $result = $this->writeToFile('validate', $data, $validateFile);
@@ -860,6 +901,12 @@ class Crud extends Command @@ -860,6 +901,12 @@ class Crud extends Command
860 $result = $this->writeToFile('add', $data, $addFile); 901 $result = $this->writeToFile('add', $data, $addFile);
861 $result = $this->writeToFile('edit', $data, $editFile); 902 $result = $this->writeToFile('edit', $data, $editFile);
862 $result = $this->writeToFile('index', $data, $indexFile); 903 $result = $this->writeToFile('index', $data, $indexFile);
  904 + if ($recyclebinHtml) {
  905 + $result = $this->writeToFile('recyclebin', $data, $recyclebinFile);
  906 + $recyclebinTitle = in_array('title', $fieldArr) ? 'title' : (in_array('name', $fieldArr) ? 'name' : '');
  907 + $recyclebinTitleJs = $recyclebinTitle ? "\n {field: '{$recyclebinTitle}', title: __('" . (ucfirst($recyclebinTitle)) . "'), align: 'left'}," : '';
  908 + $data['recyclebinJs'] = $this->getReplacedStub('mixins/recyclebinjs', ['recyclebinTitleJs' => $recyclebinTitleJs, 'controllerUrl' => $controllerUrl]);
  909 + }
863 // 生成JS文件 910 // 生成JS文件
864 $result = $this->writeToFile('javascript', $data, $javascriptFile); 911 $result = $this->writeToFile('javascript', $data, $javascriptFile);
865 // 生成语言文件 912 // 生成语言文件
@@ -880,8 +927,9 @@ class Crud extends Command @@ -880,8 +927,9 @@ class Crud extends Command
880 927
881 protected function getEnum(&$getEnum, &$controllerAssignList, $field, $itemArr = '', $inputType = '') 928 protected function getEnum(&$getEnum, &$controllerAssignList, $field, $itemArr = '', $inputType = '')
882 { 929 {
883 - if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) 930 + if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) {
884 return; 931 return;
  932 + }
885 $fieldList = $this->getFieldListName($field); 933 $fieldList = $this->getFieldListName($field);
886 $methodName = 'get' . ucfirst($fieldList); 934 $methodName = 'get' . ucfirst($fieldList);
887 foreach ($itemArr as $k => &$v) { 935 foreach ($itemArr as $k => &$v) {
@@ -902,22 +950,24 @@ EOD; @@ -902,22 +950,24 @@ EOD;
902 950
903 protected function getAttr(&$getAttr, $field, $inputType = '') 951 protected function getAttr(&$getAttr, $field, $inputType = '')
904 { 952 {
905 - if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) 953 + if (!in_array($inputType, ['datetime', 'select', 'multiple', 'checkbox', 'radio'])) {
906 return; 954 return;
  955 + }
907 $attrField = ucfirst($this->getCamelizeName($field)); 956 $attrField = ucfirst($this->getCamelizeName($field));
908 $getAttr[] = $this->getReplacedStub("mixins" . DS . $inputType, ['field' => $field, 'methodName' => "get{$attrField}TextAttr", 'listMethodName' => "get{$attrField}List"]); 957 $getAttr[] = $this->getReplacedStub("mixins" . DS . $inputType, ['field' => $field, 'methodName' => "get{$attrField}TextAttr", 'listMethodName' => "get{$attrField}List"]);
909 } 958 }
910 959
911 protected function setAttr(&$setAttr, $field, $inputType = '') 960 protected function setAttr(&$setAttr, $field, $inputType = '')
912 { 961 {
913 - if (!in_array($inputType, ['datetime', 'checkbox', 'select'])) 962 + if (!in_array($inputType, ['datetime', 'checkbox', 'select'])) {
914 return; 963 return;
  964 + }
915 $attrField = ucfirst($this->getCamelizeName($field)); 965 $attrField = ucfirst($this->getCamelizeName($field));
916 if ($inputType == 'datetime') { 966 if ($inputType == 'datetime') {
917 $return = <<<EOD 967 $return = <<<EOD
918 return \$value && !is_numeric(\$value) ? strtotime(\$value) : \$value; 968 return \$value && !is_numeric(\$value) ? strtotime(\$value) : \$value;
919 EOD; 969 EOD;
920 - } else if (in_array($inputType, ['checkbox', 'select'])) { 970 + } elseif (in_array($inputType, ['checkbox', 'select'])) {
921 $return = <<<EOD 971 $return = <<<EOD
922 return is_array(\$value) ? implode(',', \$value) : \$value; 972 return is_array(\$value) ? implode(',', \$value) : \$value;
923 EOD; 973 EOD;
@@ -1118,7 +1168,7 @@ EOD; @@ -1118,7 +1168,7 @@ EOD;
1118 * @param boolean $withTpl 1168 * @param boolean $withTpl
1119 * @return array 1169 * @return array
1120 */ 1170 */
1121 - protected function getLangArray($arr, $withTpl = TRUE) 1171 + protected function getLangArray($arr, $withTpl = true)
1122 { 1172 {
1123 $langArr = []; 1173 $langArr = [];
1124 foreach ($arr as $k => $v) { 1174 foreach ($arr as $k => $v) {
@@ -1134,8 +1184,9 @@ EOD; @@ -1134,8 +1184,9 @@ EOD;
1134 */ 1184 */
1135 protected function getArrayString($arr) 1185 protected function getArrayString($arr)
1136 { 1186 {
1137 - if (!is_array($arr)) 1187 + if (!is_array($arr)) {
1138 return $arr; 1188 return $arr;
  1189 + }
1139 $stringArr = []; 1190 $stringArr = [];
1140 foreach ($arr as $k => $v) { 1191 foreach ($arr as $k => $v) {
1141 $is_var = in_array(substr($v, 0, 1), ['$', '_']); 1192 $is_var = in_array(substr($v, 0, 1), ['$', '_']);
@@ -1197,11 +1248,11 @@ EOD; @@ -1197,11 +1248,11 @@ EOD;
1197 case 'tinytext': 1248 case 'tinytext':
1198 $inputType = 'textarea'; 1249 $inputType = 'textarea';
1199 break; 1250 break;
1200 - case 'year';  
1201 - case 'date';  
1202 - case 'time';  
1203 - case 'datetime';  
1204 - case 'timestamp'; 1251 + case 'year':
  1252 + case 'date':
  1253 + case 'time':
  1254 + case 'datetime':
  1255 + case 'timestamp':
1205 $inputType = 'datetime'; 1256 $inputType = 'datetime';
1206 break; 1257 break;
1207 default: 1258 default:
@@ -1327,8 +1378,9 @@ EOD; @@ -1327,8 +1378,9 @@ EOD;
1327 $formatter = 'label'; 1378 $formatter = 'label';
1328 } 1379 }
1329 foreach ($itemArr as $k => &$v) { 1380 foreach ($itemArr as $k => &$v) {
1330 - if (substr($v, 0, 3) !== '__(') 1381 + if (substr($v, 0, 3) !== '__(') {
1331 $v = "__('" . mb_ucfirst($v) . "')"; 1382 $v = "__('" . mb_ucfirst($v) . "')";
  1383 + }
1332 } 1384 }
1333 unset($v); 1385 unset($v);
1334 $searchList = json_encode($itemArr, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE); 1386 $searchList = json_encode($itemArr, JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE);
@@ -1338,22 +1390,23 @@ EOD; @@ -1338,22 +1390,23 @@ EOD;
1338 } 1390 }
1339 if (in_array($datatype, ['date', 'datetime']) || $formatter === 'datetime') { 1391 if (in_array($datatype, ['date', 'datetime']) || $formatter === 'datetime') {
1340 $html .= ", operate:'RANGE', addclass:'datetimerange'"; 1392 $html .= ", operate:'RANGE', addclass:'datetimerange'";
1341 - } else if (in_array($datatype, ['float', 'double', 'decimal'])) { 1393 + } elseif (in_array($datatype, ['float', 'double', 'decimal'])) {
1342 $html .= ", operate:'BETWEEN'"; 1394 $html .= ", operate:'BETWEEN'";
1343 } 1395 }
1344 if (in_array($datatype, ['set'])) { 1396 if (in_array($datatype, ['set'])) {
1345 $html .= ", operate:'FIND_IN_SET'"; 1397 $html .= ", operate:'FIND_IN_SET'";
1346 } 1398 }
1347 - if (in_array($formatter, ['image','images'])) { 1399 + if (in_array($formatter, ['image', 'images'])) {
1348 $html .= ", events: Table.api.events.image"; 1400 $html .= ", events: Table.api.events.image";
1349 } 1401 }
1350 if ($itemArr && !$formatter) { 1402 if ($itemArr && !$formatter) {
1351 $formatter = 'normal'; 1403 $formatter = 'normal';
1352 } 1404 }
1353 - if ($formatter) 1405 + if ($formatter) {
1354 $html .= ", formatter: Table.api.formatter." . $formatter . "}"; 1406 $html .= ", formatter: Table.api.formatter." . $formatter . "}";
1355 - else 1407 + } else {
1356 $html .= "}"; 1408 $html .= "}";
  1409 + }
1357 return $html; 1410 return $html;
1358 } 1411 }
1359 1412
@@ -1367,5 +1420,4 @@ EOD; @@ -1367,5 +1420,4 @@ EOD;
1367 { 1420 {
1368 return $this->getCamelizeName($field) . 'List'; 1421 return $this->getCamelizeName($field) . 'List';
1369 } 1422 }
1370 -  
1371 } 1423 }
  1 +<a class="btn btn-success btn-recyclebin btn-dialog" href="{%controllerUrl%}/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
@@ -19,6 +19,8 @@ @@ -19,6 +19,8 @@
19 <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li> 19 <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
20 </ul> 20 </ul>
21 </div> 21 </div>
  22 +
  23 + {%recyclebinHtml%}
22 </div> 24 </div>
23 <table id="table" class="table table-striped table-bordered table-hover table-nowrap" 25 <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
24 data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}" 26 data-operate-edit="{:$auth->check('{%controllerUrl%}/edit')}"
@@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin @@ -30,7 +30,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
30 30
31 // 为表格绑定事件 31 // 为表格绑定事件
32 Table.api.bindevent(table); 32 Table.api.bindevent(table);
33 - }, 33 + },{%recyclebinJs%}
34 add: function () { 34 add: function () {
35 Controller.api.bindevent(); 35 Controller.api.bindevent();
36 }, 36 },
  1 +
  2 + recyclebin: function () {
  3 + // 初始化表格参数配置
  4 + Table.api.init({
  5 + extend: {
  6 + 'dragsort_url': ''
  7 + }
  8 + });
  9 +
  10 + var table = $("#table");
  11 +
  12 + // 初始化表格
  13 + table.bootstrapTable({
  14 + url: '{%controllerUrl%}/recyclebin',
  15 + pk: 'id',
  16 + sortName: 'id',
  17 + columns: [
  18 + [
  19 + {checkbox: true},
  20 + {field: 'id', title: __('Id')},{%recyclebinTitleJs%}
  21 + {
  22 + field: 'deletetime',
  23 + title: __('Deletetime'),
  24 + operate: 'RANGE',
  25 + addclass: 'datetimerange',
  26 + formatter: Table.api.formatter.datetime
  27 + },
  28 + {
  29 + field: 'operate',
  30 + width: '130px',
  31 + title: __('Operate'),
  32 + table: table,
  33 + events: Table.api.events.operate,
  34 + buttons: [
  35 + {
  36 + name: 'Restore',
  37 + text: __('Restore'),
  38 + classname: 'btn btn-xs btn-info btn-restoreit',
  39 + icon: 'fa fa-rotate-left',
  40 + url: '{%controllerUrl%}/restore'
  41 + },
  42 + {
  43 + name: 'Destroy',
  44 + text: __('Destroy'),
  45 + classname: 'btn btn-xs btn-danger btn-destroyit',
  46 + icon: 'fa fa-times',
  47 + url: '{%controllerUrl%}/destroy'
  48 + }
  49 + ],
  50 + formatter: Table.api.formatter.operate
  51 + }
  52 + ]
  53 + ]
  54 + });
  55 +
  56 + // 为表格绑定事件
  57 + Table.api.bindevent(table);
  58 + },
@@ -3,9 +3,13 @@ @@ -3,9 +3,13 @@
3 namespace {%modelNamespace%}; 3 namespace {%modelNamespace%};
4 4
5 use think\Model; 5 use think\Model;
  6 +{%sofeDeleteClassPath%}
6 7
7 class {%modelName%} extends Model 8 class {%modelName%} extends Model
8 { 9 {
  10 +
  11 + {%softDelete%}
  12 +
9 // 表名 13 // 表名
10 protected ${%modelTableType%} = '{%modelTableTypeName%}'; 14 protected ${%modelTableType%} = '{%modelTableTypeName%}';
11 15
@@ -15,7 +19,8 @@ class {%modelName%} extends Model @@ -15,7 +19,8 @@ class {%modelName%} extends Model
15 // 定义时间戳字段名 19 // 定义时间戳字段名
16 protected $createTime = {%createTime%}; 20 protected $createTime = {%createTime%};
17 protected $updateTime = {%updateTime%}; 21 protected $updateTime = {%updateTime%};
18 - 22 + protected $deleteTime = {%deleteTime%};
  23 +
19 // 追加属性 24 // 追加属性
20 protected $append = [ 25 protected $append = [
21 {%appendAttrList%} 26 {%appendAttrList%}
  1 +<div class="panel panel-default panel-intro">
  2 + {:build_heading()}
  3 +
  4 + <div class="panel-body">
  5 + <div id="myTabContent" class="tab-content">
  6 + <div class="tab-pane fade active in" id="one">
  7 + <div class="widget-body no-padding">
  8 + <div id="toolbar" class="toolbar">
  9 + {:build_toolbar('refresh')}
  10 + <a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
  11 + <a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
  12 + <a class="btn btn-success btn-restoreall {:$auth->check('{%controllerUrl%}/restore')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
  13 + <a class="btn btn-danger btn-destroyall {:$auth->check('{%controllerUrl%}/destroy')?'':'hide'}" href="javascript:;" data-url="{%controllerUrl%}/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
  14 + </div>
  15 + <table id="table" class="table table-striped table-bordered table-hover"
  16 + data-operate-restore="{:$auth->check('{%controllerUrl%}/restore')}"
  17 + data-operate-destroy="{:$auth->check('{%controllerUrl%}/destroy')}"
  18 + width="100%">
  19 + </table>
  20 + </div>
  21 + </div>
  22 +
  23 + </div>
  24 + </div>
  25 +</div>
@@ -13,7 +13,6 @@ use think\Exception; @@ -13,7 +13,6 @@ use think\Exception;
13 13
14 class Install extends Command 14 class Install extends Command
15 { 15 {
16 -  
17 protected $model = null; 16 protected $model = null;
18 17
19 protected function configure() 18 protected function configure()
@@ -27,7 +26,7 @@ class Install extends Command @@ -27,7 +26,7 @@ class Install extends Command
27 ->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix']) 26 ->addOption('prefix', 'r', Option::VALUE_OPTIONAL, 'table prefix', $config['prefix'])
28 ->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username']) 27 ->addOption('username', 'u', Option::VALUE_OPTIONAL, 'mysql username', $config['username'])
29 ->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password']) 28 ->addOption('password', 'p', Option::VALUE_OPTIONAL, 'mysql password', $config['password'])
30 - ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', FALSE) 29 + ->addOption('force', 'f', Option::VALUE_OPTIONAL, 'force override', false)
31 ->setDescription('New installation of FastAdmin'); 30 ->setDescription('New installation of FastAdmin');
32 } 31 }
33 32
@@ -93,5 +92,4 @@ class Install extends Command @@ -93,5 +92,4 @@ class Install extends Command
93 92
94 $output->info("Install Successed!"); 93 $output->info("Install Successed!");
95 } 94 }
96 -  
97 } 95 }
@@ -15,7 +15,6 @@ use think\Exception; @@ -15,7 +15,6 @@ use think\Exception;
15 15
16 class Menu extends Command 16 class Menu extends Command
17 { 17 {
18 -  
19 protected $model = null; 18 protected $model = null;
20 19
21 protected function configure() 20 protected function configure()
@@ -32,7 +31,6 @@ class Menu extends Command @@ -32,7 +31,6 @@ class Menu extends Command
32 31
33 protected function execute(Input $input, Output $output) 32 protected function execute(Input $input, Output $output)
34 { 33 {
35 -  
36 $this->model = new AuthRule(); 34 $this->model = new AuthRule();
37 $adminPath = dirname(__DIR__) . DS; 35 $adminPath = dirname(__DIR__) . DS;
38 //控制器名 36 //控制器名
@@ -54,10 +52,11 @@ class Menu extends Command @@ -54,10 +52,11 @@ class Menu extends Command
54 $ids = []; 52 $ids = [];
55 $list = $this->model->where(function ($query) use ($controller, $equal) { 53 $list = $this->model->where(function ($query) use ($controller, $equal) {
56 foreach ($controller as $index => $item) { 54 foreach ($controller as $index => $item) {
57 - if ($equal) 55 + if ($equal) {
58 $query->whereOr('name', 'eq', $item); 56 $query->whereOr('name', 'eq', $item);
59 - else 57 + } else {
60 $query->whereOr('name', 'like', strtolower($item) . "%"); 58 $query->whereOr('name', 'like', strtolower($item) . "%");
  59 + }
61 } 60 }
62 })->select(); 61 })->select();
63 foreach ($list as $k => $v) { 62 foreach ($list as $k => $v) {
@@ -94,8 +93,11 @@ class Menu extends Command @@ -94,8 +93,11 @@ class Menu extends Command
94 } 93 }
95 $this->importRule($item); 94 $this->importRule($item);
96 } 95 }
97 -  
98 } else { 96 } else {
  97 + $authRuleList = AuthRule::select();
  98 + //生成权限规则备份文件
  99 + file_put_contents(RUNTIME_PATH . 'authrule.json', json_encode(collection($authRuleList)->toArray()));
  100 +
99 $this->model->where('id', '>', 0)->delete(); 101 $this->model->where('id', '>', 0)->delete();
100 $controllerDir = $adminPath . 'controller' . DS; 102 $controllerDir = $adminPath . 'controller' . DS;
101 // 扫描新的节点信息并导入 103 // 扫描新的节点信息并导入
@@ -199,7 +201,7 @@ class Menu extends Command @@ -199,7 +201,7 @@ class Menu extends Command
199 } 201 }
200 } 202 }
201 //忽略的类 203 //忽略的类
202 - if (stripos($classComment, "@internal") !== FALSE) { 204 + if (stripos($classComment, "@internal") !== false) {
203 return; 205 return;
204 } 206 }
205 preg_match_all('#(@.*?)\n#s', $classComment, $annotations); 207 preg_match_all('#(@.*?)\n#s', $classComment, $annotations);
@@ -208,10 +210,10 @@ class Menu extends Command @@ -208,10 +210,10 @@ class Menu extends Command
208 //判断注释中是否设置了icon值 210 //判断注释中是否设置了icon值
209 if (isset($annotations[1])) { 211 if (isset($annotations[1])) {
210 foreach ($annotations[1] as $tag) { 212 foreach ($annotations[1] as $tag) {
211 - if (stripos($tag, '@icon') !== FALSE) { 213 + if (stripos($tag, '@icon') !== false) {
212 $controllerIcon = substr($tag, stripos($tag, ' ') + 1); 214 $controllerIcon = substr($tag, stripos($tag, ' ') + 1);
213 } 215 }
214 - if (stripos($tag, '@remark') !== FALSE) { 216 + if (stripos($tag, '@remark') !== false) {
215 $controllerRemark = substr($tag, stripos($tag, ' ') + 1); 217 $controllerRemark = substr($tag, stripos($tag, ' ') + 1);
216 } 218 }
217 } 219 }
@@ -226,7 +228,13 @@ class Menu extends Command @@ -226,7 +228,13 @@ class Menu extends Command
226 $pid = 0; 228 $pid = 0;
227 foreach ($controllerArr as $k => $v) { 229 foreach ($controllerArr as $k => $v) {
228 $key = $k + 1; 230 $key = $k + 1;
229 - $name = strtolower(implode('/', array_slice($controllerArr, 0, $key))); 231 + //驼峰转下划线
  232 + $controllerNameArr = array_slice($controllerArr, 0, $key);
  233 + foreach ($controllerNameArr as &$val) {
  234 + $val = strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $val), "_"));
  235 + }
  236 + unset($val);
  237 + $name = implode('/', $controllerNameArr);
230 $title = (!isset($controllerArr[$key]) ? $controllerTitle : ''); 238 $title = (!isset($controllerArr[$key]) ? $controllerTitle : '');
231 $icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list'); 239 $icon = (!isset($controllerArr[$key]) ? $controllerIcon : 'fa fa-list');
232 $remark = (!isset($controllerArr[$key]) ? $controllerRemark : ''); 240 $remark = (!isset($controllerArr[$key]) ? $controllerRemark : '');
@@ -259,7 +267,7 @@ class Menu extends Command @@ -259,7 +267,7 @@ class Menu extends Command
259 } 267 }
260 $comment = $reflector->getMethod($n->name)->getDocComment(); 268 $comment = $reflector->getMethod($n->name)->getDocComment();
261 //忽略的方法 269 //忽略的方法
262 - if (stripos($comment, "@internal") !== FALSE) { 270 + if (stripos($comment, "@internal") !== false) {
263 continue; 271 continue;
264 } 272 }
265 //过滤掉其它字符 273 //过滤掉其它字符
@@ -285,5 +293,4 @@ class Menu extends Command @@ -285,5 +293,4 @@ class Menu extends Command
285 return $id ? $id : null; 293 return $id ? $id : null;
286 } 294 }
287 } 295 }
288 -  
289 } 296 }
@@ -37,12 +37,10 @@ class Min extends Command @@ -37,12 +37,10 @@ class Min extends Command
37 $resource = $input->getOption('resource') ?: ''; 37 $resource = $input->getOption('resource') ?: '';
38 $optimize = $input->getOption('optimize') ?: 'none'; 38 $optimize = $input->getOption('optimize') ?: 'none';
39 39
40 - if (!$module || !in_array($module, ['frontend', 'backend', 'all']))  
41 - { 40 + if (!$module || !in_array($module, ['frontend', 'backend', 'all'])) {
42 throw new Exception('Please input correct module name'); 41 throw new Exception('Please input correct module name');
43 } 42 }
44 - if (!$resource || !in_array($resource, ['js', 'css', 'all']))  
45 - { 43 + if (!$resource || !in_array($resource, ['js', 'css', 'all'])) {
46 throw new Exception('Please input correct resource name'); 44 throw new Exception('Please input correct resource name');
47 } 45 }
48 46
@@ -55,41 +53,31 @@ class Min extends Command @@ -55,41 +53,31 @@ class Min extends Command
55 53
56 $nodeExec = ''; 54 $nodeExec = '';
57 55
58 - if (!$nodeExec)  
59 - {  
60 - if (IS_WIN)  
61 - { 56 + if (!$nodeExec) {
  57 + if (IS_WIN) {
62 // Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更 58 // Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
63 $nodeExec = 'C:\Program Files\nodejs\node.exe'; 59 $nodeExec = 'C:\Program Files\nodejs\node.exe';
64 - if (file_exists($nodeExec)){ 60 + if (file_exists($nodeExec)) {
65 $nodeExec = '"' . $nodeExec . '"'; 61 $nodeExec = '"' . $nodeExec . '"';
66 - }else{ 62 + } else {
67 // 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更 63 // 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更
68 // 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率 64 // 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
69 $nodeExec = '"node.exe"'; 65 $nodeExec = '"node.exe"';
70 } 66 }
71 - }  
72 - else  
73 - {  
74 - try  
75 - { 67 + } else {
  68 + try {
76 $nodeExec = exec("which node"); 69 $nodeExec = exec("which node");
77 - if (!$nodeExec)  
78 - { 70 + if (!$nodeExec) {
79 throw new Exception("node environment not found!please install node first!"); 71 throw new Exception("node environment not found!please install node first!");
80 } 72 }
81 - }  
82 - catch (Exception $e)  
83 - { 73 + } catch (Exception $e) {
84 throw new Exception($e->getMessage()); 74 throw new Exception($e->getMessage());
85 } 75 }
86 } 76 }
87 } 77 }
88 78
89 - foreach ($moduleArr as $mod)  
90 - {  
91 - foreach ($resourceArr as $res)  
92 - { 79 + foreach ($moduleArr as $mod) {
  80 + foreach ($resourceArr as $res) {
93 $data = [ 81 $data = [
94 'publicPath' => $publicPath, 82 'publicPath' => $publicPath,
95 'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']), 83 'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
@@ -104,17 +92,14 @@ class Min extends Command @@ -104,17 +92,14 @@ class Min extends Command
104 92
105 //源文件 93 //源文件
106 $from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res; 94 $from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
107 - if (!is_file($from))  
108 - { 95 + if (!is_file($from)) {
109 $output->error("{$res} source file not found!file:{$from}"); 96 $output->error("{$res} source file not found!file:{$from}");
110 continue; 97 continue;
111 } 98 }
112 - if ($res == "js")  
113 - { 99 + if ($res == "js") {
114 $content = file_get_contents($from); 100 $content = file_get_contents($from);
115 preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches); 101 preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
116 - if (!isset($matches[1]))  
117 - { 102 + if (!isset($matches[1])) {
118 $output->error("js config not found!"); 103 $output->error("js config not found!");
119 continue; 104 continue;
120 } 105 }
@@ -128,16 +113,14 @@ class Min extends Command @@ -128,16 +113,14 @@ class Min extends Command
128 113
129 // 执行压缩 114 // 执行压缩
130 $command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\""; 115 $command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
131 - if ($output->isDebug())  
132 - { 116 + if ($output->isDebug()) {
133 $output->warning($command); 117 $output->warning($command);
134 } 118 }
135 echo exec($command); 119 echo exec($command);
136 } 120 }
137 } 121 }
138 122
139 - if (!$output->isDebug())  
140 - { 123 + if (!$output->isDebug()) {
141 @unlink($tempFile); 124 @unlink($tempFile);
142 } 125 }
143 126
@@ -154,16 +137,14 @@ class Min extends Command @@ -154,16 +137,14 @@ class Min extends Command
154 protected function writeToFile($name, $data, $pathname) 137 protected function writeToFile($name, $data, $pathname)
155 { 138 {
156 $search = $replace = []; 139 $search = $replace = [];
157 - foreach ($data as $k => $v)  
158 - { 140 + foreach ($data as $k => $v) {
159 $search[] = "{%{$k}%}"; 141 $search[] = "{%{$k}%}";
160 $replace[] = $v; 142 $replace[] = $v;
161 } 143 }
162 $stub = file_get_contents($this->getStub($name)); 144 $stub = file_get_contents($this->getStub($name));
163 $content = str_replace($search, $replace, $stub); 145 $content = str_replace($search, $replace, $stub);
164 146
165 - if (!is_dir(dirname($pathname)))  
166 - { 147 + if (!is_dir(dirname($pathname))) {
167 mkdir(strtolower(dirname($pathname)), 0755, true); 148 mkdir(strtolower(dirname($pathname)), 0755, true);
168 } 149 }
169 return file_put_contents($pathname, $content); 150 return file_put_contents($pathname, $content);
@@ -178,5 +159,4 @@ class Min extends Command @@ -178,5 +159,4 @@ class Min extends Command
178 { 159 {
179 return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub'; 160 return __DIR__ . DS . 'Min' . DS . 'stubs' . DS . $name . '.stub';
180 } 161 }
181 -  
182 } 162 }
@@ -74,6 +74,7 @@ if (!function_exists('build_category_select')) { @@ -74,6 +74,7 @@ if (!function_exists('build_category_select')) {
74 * @param string $type 74 * @param string $type
75 * @param mixed $selected 75 * @param mixed $selected
76 * @param array $attr 76 * @param array $attr
  77 + * @param array $header
77 * @return string 78 * @return string
78 */ 79 */
79 function build_category_select($name, $type, $selected = null, $attr = [], $header = []) 80 function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
@@ -98,14 +99,14 @@ if (!function_exists('build_toolbar')) { @@ -98,14 +99,14 @@ if (!function_exists('build_toolbar')) {
98 * @param array $attr 按钮属性值 99 * @param array $attr 按钮属性值
99 * @return string 100 * @return string
100 */ 101 */
101 - function build_toolbar($btns = NULL, $attr = []) 102 + function build_toolbar($btns = null, $attr = [])
102 { 103 {
103 $auth = \app\admin\library\Auth::instance(); 104 $auth = \app\admin\library\Auth::instance();
104 $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller())); 105 $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
105 $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import']; 106 $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
106 $btns = is_array($btns) ? $btns : explode(',', $btns); 107 $btns = is_array($btns) ? $btns : explode(',', $btns);
107 $index = array_search('delete', $btns); 108 $index = array_search('delete', $btns);
108 - if ($index !== FALSE) { 109 + if ($index !== false) {
109 $btns[$index] = 'del'; 110 $btns[$index] = 'del';
110 } 111 }
111 $btnAttr = [ 112 $btnAttr = [
@@ -140,7 +141,7 @@ if (!function_exists('build_toolbar')) { @@ -140,7 +141,7 @@ if (!function_exists('build_toolbar')) {
140 } 141 }
141 $download .= empty($download) ? '' : "\n "; 142 $download .= empty($download) ? '' : "\n ";
142 if (!empty($download)) { 143 if (!empty($download)) {
143 - $html[] = <<<EOT 144 + $html[] = <<<EOT
144 <div class="btn-group"> 145 <div class="btn-group">
145 <button type="button" href="{$href}" class="btn btn-info btn-import" title="{$title}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="{$icon}"></i> {$text}</button> 146 <button type="button" href="{$href}" class="btn btn-info btn-import" title="{$title}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="{$icon}"></i> {$text}</button>
146 <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版"> 147 <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版">
@@ -169,7 +170,7 @@ if (!function_exists('build_heading')) { @@ -169,7 +170,7 @@ if (!function_exists('build_heading')) {
169 * @param string $path 指定的path 170 * @param string $path 指定的path
170 * @return string 171 * @return string
171 */ 172 */
172 - function build_heading($path = NULL, $container = TRUE) 173 + function build_heading($path = null, $container = true)
173 { 174 {
174 $title = $content = ''; 175 $title = $content = '';
175 if (is_null($path)) { 176 if (is_null($path)) {
@@ -183,8 +184,9 @@ if (!function_exists('build_heading')) { @@ -183,8 +184,9 @@ if (!function_exists('build_heading')) {
183 $title = __($data['title']); 184 $title = __($data['title']);
184 $content = __($data['remark']); 185 $content = __($data['remark']);
185 } 186 }
186 - if (!$content) 187 + if (!$content) {
187 return ''; 188 return '';
  189 + }
188 $result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>'; 190 $result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
189 if ($container) { 191 if ($container) {
190 $result = '<div class="panel-heading">' . $result . '</div>'; 192 $result = '<div class="panel-heading">' . $result . '</div>';
@@ -37,21 +37,16 @@ class Group extends Backend @@ -37,21 +37,16 @@ class Group extends Backend
37 37
38 Tree::instance()->init($groupList); 38 Tree::instance()->init($groupList);
39 $result = []; 39 $result = [];
40 - if ($this->auth->isSuperAdmin())  
41 - { 40 + if ($this->auth->isSuperAdmin()) {
42 $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0)); 41 $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
43 - }  
44 - else  
45 - { 42 + } else {
46 $groups = $this->auth->getGroups(); 43 $groups = $this->auth->getGroups();
47 - foreach ($groups as $m => $n)  
48 - { 44 + foreach ($groups as $m => $n) {
49 $result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid']))); 45 $result = array_merge($result, Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['pid'])));
50 } 46 }
51 } 47 }
52 $groupName = []; 48 $groupName = [];
53 - foreach ($result as $k => $v)  
54 - { 49 + foreach ($result as $k => $v) {
55 $groupName[$v['id']] = $v['name']; 50 $groupName[$v['id']] = $v['name'];
56 } 51 }
57 52
@@ -66,20 +61,16 @@ class Group extends Backend @@ -66,20 +61,16 @@ class Group extends Backend
66 */ 61 */
67 public function index() 62 public function index()
68 { 63 {
69 - if ($this->request->isAjax())  
70 - { 64 + if ($this->request->isAjax()) {
71 $list = AuthGroup::all(array_keys($this->groupdata)); 65 $list = AuthGroup::all(array_keys($this->groupdata));
72 $list = collection($list)->toArray(); 66 $list = collection($list)->toArray();
73 $groupList = []; 67 $groupList = [];
74 - foreach ($list as $k => $v)  
75 - { 68 + foreach ($list as $k => $v) {
76 $groupList[$v['id']] = $v; 69 $groupList[$v['id']] = $v;
77 } 70 }
78 $list = []; 71 $list = [];
79 - foreach ($this->groupdata as $k => $v)  
80 - {  
81 - if (isset($groupList[$k]))  
82 - { 72 + foreach ($this->groupdata as $k => $v) {
  73 + if (isset($groupList[$k])) {
83 $groupList[$k]['name'] = $v; 74 $groupList[$k]['name'] = $v;
84 $list[] = $groupList[$k]; 75 $list[] = $groupList[$k];
85 } 76 }
@@ -97,17 +88,14 @@ class Group extends Backend @@ -97,17 +88,14 @@ class Group extends Backend
97 */ 88 */
98 public function add() 89 public function add()
99 { 90 {
100 - if ($this->request->isPost())  
101 - { 91 + if ($this->request->isPost()) {
102 $params = $this->request->post("row/a", [], 'strip_tags'); 92 $params = $this->request->post("row/a", [], 'strip_tags');
103 $params['rules'] = explode(',', $params['rules']); 93 $params['rules'] = explode(',', $params['rules']);
104 - if (!in_array($params['pid'], $this->childrenGroupIds))  
105 - { 94 + if (!in_array($params['pid'], $this->childrenGroupIds)) {
106 $this->error(__('The parent group can not be its own child')); 95 $this->error(__('The parent group can not be its own child'));
107 } 96 }
108 $parentmodel = model("AuthGroup")->get($params['pid']); 97 $parentmodel = model("AuthGroup")->get($params['pid']);
109 - if (!$parentmodel)  
110 - { 98 + if (!$parentmodel) {
111 $this->error(__('The parent group can not found')); 99 $this->error(__('The parent group can not found'));
112 } 100 }
113 // 父级别的规则节点 101 // 父级别的规则节点
@@ -120,8 +108,7 @@ class Group extends Backend @@ -120,8 +108,7 @@ class Group extends Backend
120 // 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限 108 // 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
121 $rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules); 109 $rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
122 $params['rules'] = implode(',', $rules); 110 $params['rules'] = implode(',', $rules);
123 - if ($params)  
124 - { 111 + if ($params) {
125 $this->model->create($params); 112 $this->model->create($params);
126 $this->success(); 113 $this->success();
127 } 114 }
@@ -133,24 +120,22 @@ class Group extends Backend @@ -133,24 +120,22 @@ class Group extends Backend
133 /** 120 /**
134 * 编辑 121 * 编辑
135 */ 122 */
136 - public function edit($ids = NULL) 123 + public function edit($ids = null)
137 { 124 {
138 $row = $this->model->get(['id' => $ids]); 125 $row = $this->model->get(['id' => $ids]);
139 - if (!$row) 126 + if (!$row) {
140 $this->error(__('No Results were found')); 127 $this->error(__('No Results were found'));
141 - if ($this->request->isPost())  
142 - { 128 + }
  129 + if ($this->request->isPost()) {
143 $params = $this->request->post("row/a", [], 'strip_tags'); 130 $params = $this->request->post("row/a", [], 'strip_tags');
144 // 父节点不能是它自身的子节点 131 // 父节点不能是它自身的子节点
145 - if (!in_array($params['pid'], $this->childrenGroupIds))  
146 - { 132 + if (!in_array($params['pid'], $this->childrenGroupIds)) {
147 $this->error(__('The parent group can not be its own child')); 133 $this->error(__('The parent group can not be its own child'));
148 } 134 }
149 $params['rules'] = explode(',', $params['rules']); 135 $params['rules'] = explode(',', $params['rules']);
150 136
151 $parentmodel = model("AuthGroup")->get($params['pid']); 137 $parentmodel = model("AuthGroup")->get($params['pid']);
152 - if (!$parentmodel)  
153 - { 138 + if (!$parentmodel) {
154 $this->error(__('The parent group can not found')); 139 $this->error(__('The parent group can not found'));
155 } 140 }
156 // 父级别的规则节点 141 // 父级别的规则节点
@@ -163,8 +148,7 @@ class Group extends Backend @@ -163,8 +148,7 @@ class Group extends Backend
163 // 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限 148 // 如果当前组别不是超级管理员则需要过滤规则节点,不能超当前组别的权限
164 $rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules); 149 $rules = in_array('*', $currentrules) ? $rules : array_intersect($currentrules, $rules);
165 $params['rules'] = implode(',', $rules); 150 $params['rules'] = implode(',', $rules);
166 - if ($params)  
167 - { 151 + if ($params) {
168 $row->save($params); 152 $row->save($params);
169 $this->success(); 153 $this->success();
170 } 154 }
@@ -180,11 +164,10 @@ class Group extends Backend @@ -180,11 +164,10 @@ class Group extends Backend
180 */ 164 */
181 public function del($ids = "") 165 public function del($ids = "")
182 { 166 {
183 - if ($ids)  
184 - { 167 + if ($ids) {
185 $ids = explode(',', $ids); 168 $ids = explode(',', $ids);
186 $grouplist = $this->auth->getGroups(); 169 $grouplist = $this->auth->getGroups();
187 - $group_ids = array_map(function($group) { 170 + $group_ids = array_map(function ($group) {
188 return $group['id']; 171 return $group['id'];
189 }, $grouplist); 172 }, $grouplist);
190 // 移除掉当前管理员所在组别 173 // 移除掉当前管理员所在组别
@@ -193,30 +176,25 @@ class Group extends Backend @@ -193,30 +176,25 @@ class Group extends Backend
193 // 循环判断每一个组别是否可删除 176 // 循环判断每一个组别是否可删除
194 $grouplist = $this->model->where('id', 'in', $ids)->select(); 177 $grouplist = $this->model->where('id', 'in', $ids)->select();
195 $groupaccessmodel = model('AuthGroupAccess'); 178 $groupaccessmodel = model('AuthGroupAccess');
196 - foreach ($grouplist as $k => $v)  
197 - { 179 + foreach ($grouplist as $k => $v) {
198 // 当前组别下有管理员 180 // 当前组别下有管理员
199 $groupone = $groupaccessmodel->get(['group_id' => $v['id']]); 181 $groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
200 - if ($groupone)  
201 - { 182 + if ($groupone) {
202 $ids = array_diff($ids, [$v['id']]); 183 $ids = array_diff($ids, [$v['id']]);
203 continue; 184 continue;
204 } 185 }
205 // 当前组别下有子组别 186 // 当前组别下有子组别
206 $groupone = $this->model->get(['pid' => $v['id']]); 187 $groupone = $this->model->get(['pid' => $v['id']]);
207 - if ($groupone)  
208 - { 188 + if ($groupone) {
209 $ids = array_diff($ids, [$v['id']]); 189 $ids = array_diff($ids, [$v['id']]);
210 continue; 190 continue;
211 } 191 }
212 } 192 }
213 - if (!$ids)  
214 - { 193 + if (!$ids) {
215 $this->error(__('You can not delete group that contain child group and administrators')); 194 $this->error(__('You can not delete group that contain child group and administrators'));
216 } 195 }
217 $count = $this->model->where('id', 'in', $ids)->delete(); 196 $count = $this->model->where('id', 'in', $ids)->delete();
218 - if ($count)  
219 - { 197 + if ($count) {
220 $this->success(); 198 $this->success();
221 } 199 }
222 } 200 }
@@ -235,7 +213,7 @@ class Group extends Backend @@ -235,7 +213,7 @@ class Group extends Backend
235 213
236 /** 214 /**
237 * 读取角色权限树 215 * 读取角色权限树
238 - * 216 + *
239 * @internal 217 * @internal
240 */ 218 */
241 public function roletree() 219 public function roletree()
@@ -246,35 +224,32 @@ class Group extends Backend @@ -246,35 +224,32 @@ class Group extends Backend
246 $id = $this->request->post("id"); 224 $id = $this->request->post("id");
247 $pid = $this->request->post("pid"); 225 $pid = $this->request->post("pid");
248 $parentGroupModel = $model->get($pid); 226 $parentGroupModel = $model->get($pid);
249 - $currentGroupModel = NULL;  
250 - if ($id)  
251 - { 227 + $currentGroupModel = null;
  228 + if ($id) {
252 $currentGroupModel = $model->get($id); 229 $currentGroupModel = $model->get($id);
253 } 230 }
254 - if (($pid || $parentGroupModel) && (!$id || $currentGroupModel))  
255 - {  
256 - $id = $id ? $id : NULL; 231 + if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
  232 + $id = $id ? $id : null;
257 $ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray(); 233 $ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
258 //读取父类角色所有节点列表 234 //读取父类角色所有节点列表
259 $parentRuleList = []; 235 $parentRuleList = [];
260 - if (in_array('*', explode(',', $parentGroupModel->rules)))  
261 - { 236 + if (in_array('*', explode(',', $parentGroupModel->rules))) {
262 $parentRuleList = $ruleList; 237 $parentRuleList = $ruleList;
263 - }  
264 - else  
265 - { 238 + } else {
266 $parentRuleIds = explode(',', $parentGroupModel->rules); 239 $parentRuleIds = explode(',', $parentGroupModel->rules);
267 - foreach ($ruleList as $k => $v)  
268 - {  
269 - if (in_array($v['id'], $parentRuleIds))  
270 - { 240 + foreach ($ruleList as $k => $v) {
  241 + if (in_array($v['id'], $parentRuleIds)) {
271 $parentRuleList[] = $v; 242 $parentRuleList[] = $v;
272 } 243 }
273 } 244 }
274 } 245 }
275 246
  247 + $ruleTree = new Tree();
  248 + $groupTree = new Tree();
276 //当前所有正常规则列表 249 //当前所有正常规则列表
277 - Tree::instance()->init($parentRuleList); 250 + $ruleTree->init($parentRuleList);
  251 + //角色组列表
  252 + $groupTree->init(collection(model('AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
278 253
279 //读取当前角色下规则ID集合 254 //读取当前角色下规则ID集合
280 $adminRuleIds = $this->auth->getRuleIds(); 255 $adminRuleIds = $this->auth->getRuleIds();
@@ -283,39 +258,34 @@ class Group extends Backend @@ -283,39 +258,34 @@ class Group extends Backend
283 //当前拥有的规则ID集合 258 //当前拥有的规则ID集合
284 $currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : []; 259 $currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
285 260
286 - if (!$id || !in_array($pid, Tree::instance()->getChildrenIds($id, TRUE)))  
287 - {  
288 - $parentRuleList = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'name'); 261 + if (!$id || !in_array($pid, $this->childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
  262 + $parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
289 $hasChildrens = []; 263 $hasChildrens = [];
290 - foreach ($parentRuleList as $k => $v)  
291 - {  
292 - if ($v['haschild']) 264 + foreach ($parentRuleList as $k => $v) {
  265 + if ($v['haschild']) {
293 $hasChildrens[] = $v['id']; 266 $hasChildrens[] = $v['id'];
  267 + }
294 } 268 }
295 - $parentRuleIds = array_map(function($item) { 269 + $parentRuleIds = array_map(function ($item) {
296 return $item['id']; 270 return $item['id'];
297 }, $parentRuleList); 271 }, $parentRuleList);
298 $nodeList = []; 272 $nodeList = [];
299 - foreach ($parentRuleList as $k => $v)  
300 - {  
301 - if (!$superadmin && !in_array($v['id'], $adminRuleIds)) 273 + foreach ($parentRuleList as $k => $v) {
  274 + if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
302 continue; 275 continue;
303 - if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) 276 + }
  277 + if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
304 continue; 278 continue;
  279 + }
305 $state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens)); 280 $state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
306 $nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state); 281 $nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
307 } 282 }
308 $this->success('', null, $nodeList); 283 $this->success('', null, $nodeList);
309 - }  
310 - else  
311 - { 284 + } else {
312 $this->error(__('Can not change the parent to child')); 285 $this->error(__('Can not change the parent to child'));
313 } 286 }
314 - }  
315 - else  
316 - { 287 + } else {
317 $this->error(__('Group not found')); 288 $this->error(__('Group not found'));
318 } 289 }
319 } 290 }
320 -  
321 } 291 }
@@ -113,6 +113,12 @@ return [ @@ -113,6 +113,12 @@ return [
113 '%d year%s ago' => '%d年前', 113 '%d year%s ago' => '%d年前',
114 'Set to normal' => '设为正常', 114 'Set to normal' => '设为正常',
115 'Set to hidden' => '设为隐藏', 115 'Set to hidden' => '设为隐藏',
  116 + 'Recycle bin' => '回收站',
  117 + 'Restore' => '还原',
  118 + 'Restore all' => '还原全部',
  119 + 'Destroy' => '销毁',
  120 + 'Destroy all' => '清空回收站',
  121 + 'Nothing need restore' => '没有需要还原的数据',
116 //提示 122 //提示
117 'Go back' => '返回首页', 123 'Go back' => '返回首页',
118 'Jump now' => '立即跳转', 124 'Jump now' => '立即跳转',
@@ -130,6 +136,7 @@ return [ @@ -130,6 +136,7 @@ return [
130 'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?', 136 'Are you sure you want to delete the %s selected item?' => '确定删除选中的 %s 项?',
131 'Are you sure you want to delete this item?' => '确定删除此项?', 137 'Are you sure you want to delete this item?' => '确定删除此项?',
132 'Are you sure you want to delete or turncate?' => '确定删除或清空?', 138 'Are you sure you want to delete or turncate?' => '确定删除或清空?',
  139 + 'Are you sure you want to truncate?' => '确定清空?',
133 'You have no permission' => '你没有权限访问', 140 'You have no permission' => '你没有权限访问',
134 'Please enter your username' => '请输入你的用户名', 141 'Please enter your username' => '请输入你的用户名',
135 'Please enter your password' => '请输入你的密码', 142 'Please enter your password' => '请输入你的密码',
@@ -7,6 +7,8 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate; @@ -7,6 +7,8 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
7 use PhpOffice\PhpSpreadsheet\Reader\Xlsx; 7 use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
8 use PhpOffice\PhpSpreadsheet\Reader\Xls; 8 use PhpOffice\PhpSpreadsheet\Reader\Xls;
9 use PhpOffice\PhpSpreadsheet\Reader\Csv; 9 use PhpOffice\PhpSpreadsheet\Reader\Csv;
  10 +use think\Exception;
  11 +
10 trait Backend 12 trait Backend
11 { 13 {
12 14
@@ -19,15 +21,12 @@ trait Backend @@ -19,15 +21,12 @@ trait Backend
19 { 21 {
20 if (is_array($this->excludeFields)) { 22 if (is_array($this->excludeFields)) {
21 foreach ($this->excludeFields as $field) { 23 foreach ($this->excludeFields as $field) {
22 - if (key_exists($field,$params))  
23 - { 24 + if (key_exists($field, $params)) {
24 unset($params[$field]); 25 unset($params[$field]);
25 } 26 }
26 } 27 }
27 } else { 28 } else {
28 -  
29 - if (key_exists($this->excludeFields,$params))  
30 - { 29 + if (key_exists($this->excludeFields, $params)) {
31 unset($params[$this->excludeFields]); 30 unset($params[$this->excludeFields]);
32 } 31 }
33 } 32 }
@@ -104,7 +103,6 @@ trait Backend @@ -104,7 +103,6 @@ trait Backend
104 if ($this->request->isPost()) { 103 if ($this->request->isPost()) {
105 $params = $this->request->post("row/a"); 104 $params = $this->request->post("row/a");
106 if ($params) { 105 if ($params) {
107 -  
108 $params = $this->preExcludeFields($params); 106 $params = $this->preExcludeFields($params);
109 107
110 if ($this->dataLimit && $this->dataLimitFieldAutoFill) { 108 if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
@@ -137,11 +135,12 @@ trait Backend @@ -137,11 +135,12 @@ trait Backend
137 /** 135 /**
138 * 编辑 136 * 编辑
139 */ 137 */
140 - public function edit($ids = NULL) 138 + public function edit($ids = null)
141 { 139 {
142 $row = $this->model->get($ids); 140 $row = $this->model->get($ids);
143 - if (!$row) 141 + if (!$row) {
144 $this->error(__('No Results were found')); 142 $this->error(__('No Results were found'));
  143 + }
145 $adminIds = $this->getDataLimitAdminIds(); 144 $adminIds = $this->getDataLimitAdminIds();
146 if (is_array($adminIds)) { 145 if (is_array($adminIds)) {
147 if (!in_array($row[$this->dataLimitField], $adminIds)) { 146 if (!in_array($row[$this->dataLimitField], $adminIds)) {
@@ -151,7 +150,6 @@ trait Backend @@ -151,7 +150,6 @@ trait Backend
151 if ($this->request->isPost()) { 150 if ($this->request->isPost()) {
152 $params = $this->request->post("row/a"); 151 $params = $this->request->post("row/a");
153 if ($params) { 152 if ($params) {
154 -  
155 $params = $this->preExcludeFields($params); 153 $params = $this->preExcludeFields($params);
156 154
157 try { 155 try {
@@ -419,5 +417,4 @@ trait Backend @@ -419,5 +417,4 @@ trait Backend
419 417
420 $this->success(); 418 $this->success();
421 } 419 }
422 -  
423 } 420 }
@@ -100,6 +100,7 @@ @@ -100,6 +100,7 @@
100 <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}"> 100 <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
101 <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> 101 <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}" data-preview-id="p-{$item.name}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
102 <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span> 102 <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-mimetype="image/*" data-multiple="{$item.type=='image'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
  103 + <span class="msg-box n-right" for="c-{$item.name}"></span>
103 <ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul> 104 <ul class="row list-inline plupload-preview" id="p-{$item.name}"></ul>
104 </div> 105 </div>
105 {/case} 106 {/case}
@@ -109,6 +110,7 @@ @@ -109,6 +110,7 @@
109 <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}"> 110 <input id="c-{$item.name}" class="form-control" size="50" name="row[{$item.name}]" type="text" value="{$item.value}" data-tip="{$item.tip}">
110 <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> 111 <span><button type="button" id="plupload-{$item.name}" class="btn btn-danger plupload" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
111 <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span> 112 <span><button type="button" id="fachoose-{$item.name}" class="btn btn-primary fachoose" data-input-id="c-{$item.name}" data-multiple="{$item.type=='file'?'false':'true'}"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
  113 + <span class="msg-box n-right" for="c-{$item.name}"></span>
112 </div> 114 </div>
113 {/case} 115 {/case}
114 {case switch} 116 {case switch}
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 </div> 7 </div>
8 </div> 8 </div>
9 <div class="form-group"> 9 <div class="form-group">
10 - <label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label> 10 + <label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
11 <div class="col-xs-12 col-sm-8"> 11 <div class="col-xs-12 col-sm-8">
12 <span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span> 12 <span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
13 <span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span> 13 <span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 </div> 16 </div>
17 </div> 17 </div>
18 <div class="form-group"> 18 <div class="form-group">
19 - <label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> 19 + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
20 <div class="col-xs-12 col-sm-8"> 20 <div class="col-xs-12 col-sm-8">
21 21
22 <div class="radio"> 22 <div class="radio">
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 </div> 7 </div>
8 </div> 8 </div>
9 <div class="form-group"> 9 <div class="form-group">
10 - <label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label> 10 + <label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
11 <div class="col-xs-12 col-sm-8"> 11 <div class="col-xs-12 col-sm-8">
12 <span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span> 12 <span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
13 <span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span> 13 <span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 </div> 16 </div>
17 </div> 17 </div>
18 <div class="form-group"> 18 <div class="form-group">
19 - <label for="c-status" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> 19 + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
20 <div class="col-xs-12 col-sm-8"> 20 <div class="col-xs-12 col-sm-8">
21 21
22 <div class="radio"> 22 <div class="radio">
1 <form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action=""> 1 <form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
2 <div class="form-group"> 2 <div class="form-group">
3 - <label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label> 3 + <label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
4 <div class="col-xs-12 col-sm-8"> 4 <div class="col-xs-12 col-sm-8">
5 {:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')])} 5 {:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')])}
6 </div> 6 </div>
7 </div> 7 </div>
8 8
9 <div class="form-group"> 9 <div class="form-group">
10 - <label for="c-pid" class="control-label col-xs-12 col-sm-2">{:__('Pid')}:</label> 10 + <label class="control-label col-xs-12 col-sm-2">{:__('Pid')}:</label>
11 <div class="col-xs-12 col-sm-8"> 11 <div class="col-xs-12 col-sm-8">
12 {:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])} 12 {:build_select('row[pid]', $ruledata, null, ['class'=>'form-control', 'required'=>''])}
13 </div> 13 </div>
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 </div> 37 </div>
38 </div> 38 </div>
39 <div class="form-group"> 39 <div class="form-group">
40 - <label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> 40 + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
41 <div class="col-xs-12 col-sm-8"> 41 <div class="col-xs-12 col-sm-8">
42 {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])} 42 {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')])}
43 </div> 43 </div>
1 <form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action=""> 1 <form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
2 2
3 <div class="form-group"> 3 <div class="form-group">
4 - <label for="content" class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label> 4 + <label class="control-label col-xs-12 col-sm-2">{:__('Ismenu')}:</label>
5 <div class="col-xs-12 col-sm-8"> 5 <div class="col-xs-12 col-sm-8">
6 {:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')], $row['ismenu'])} 6 {:build_radios('row[ismenu]', ['1'=>__('Yes'), '0'=>__('No')], $row['ismenu'])}
7 </div> 7 </div>
8 </div> 8 </div>
9 <div class="form-group"> 9 <div class="form-group">
10 - <label for="pid" class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label> 10 + <label class="control-label col-xs-12 col-sm-2">{:__('Parent')}:</label>
11 <div class="col-xs-12 col-sm-8"> 11 <div class="col-xs-12 col-sm-8">
12 {:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])} 12 {:build_select('row[pid]', $ruledata, $row['pid'], ['class'=>'form-control', 'required'=>''])}
13 </div> 13 </div>
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 </div> 37 </div>
38 </div> 38 </div>
39 <div class="form-group"> 39 <div class="form-group">
40 - <label for="content" class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label> 40 + <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
41 <div class="col-xs-12 col-sm-8"> 41 <div class="col-xs-12 col-sm-8">
42 {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])} 42 {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
43 </div> 43 </div>
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 <div class="form-group"> 21 <div class="form-group">
22 <label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label> 22 <label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label>
23 <div class="col-xs-12 col-sm-4"> 23 <div class="col-xs-12 col-sm-4">
24 - <input id="c-password" data-rule="" class="form-control" name="row[password]" type="text" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" /> 24 + <input id="c-password" data-rule="password" class="form-control" name="row[password]" type="text" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" />
25 </div> 25 </div>
26 </div> 26 </div>
27 <div class="form-group"> 27 <div class="form-group">
@@ -32,7 +32,7 @@ class User extends Api @@ -32,7 +32,7 @@ class User extends Api
32 32
33 /** 33 /**
34 * 会员登录 34 * 会员登录
35 - * 35 + *
36 * @param string $account 账号 36 * @param string $account 账号
37 * @param string $password 密码 37 * @param string $password 密码
38 */ 38 */
@@ -40,25 +40,21 @@ class User extends Api @@ -40,25 +40,21 @@ class User extends Api
40 { 40 {
41 $account = $this->request->request('account'); 41 $account = $this->request->request('account');
42 $password = $this->request->request('password'); 42 $password = $this->request->request('password');
43 - if (!$account || !$password)  
44 - { 43 + if (!$account || !$password) {
45 $this->error(__('Invalid parameters')); 44 $this->error(__('Invalid parameters'));
46 } 45 }
47 $ret = $this->auth->login($account, $password); 46 $ret = $this->auth->login($account, $password);
48 - if ($ret)  
49 - { 47 + if ($ret) {
50 $data = ['userinfo' => $this->auth->getUserinfo()]; 48 $data = ['userinfo' => $this->auth->getUserinfo()];
51 $this->success(__('Logged in successful'), $data); 49 $this->success(__('Logged in successful'), $data);
52 - }  
53 - else  
54 - { 50 + } else {
55 $this->error($this->auth->getError()); 51 $this->error($this->auth->getError());
56 } 52 }
57 } 53 }
58 54
59 /** 55 /**
60 * 手机验证码登录 56 * 手机验证码登录
61 - * 57 + *
62 * @param string $mobile 手机号 58 * @param string $mobile 手机号
63 * @param string $captcha 验证码 59 * @param string $captcha 验证码
64 */ 60 */
@@ -66,43 +62,34 @@ class User extends Api @@ -66,43 +62,34 @@ class User extends Api
66 { 62 {
67 $mobile = $this->request->request('mobile'); 63 $mobile = $this->request->request('mobile');
68 $captcha = $this->request->request('captcha'); 64 $captcha = $this->request->request('captcha');
69 - if (!$mobile || !$captcha)  
70 - { 65 + if (!$mobile || !$captcha) {
71 $this->error(__('Invalid parameters')); 66 $this->error(__('Invalid parameters'));
72 } 67 }
73 - if (!Validate::regex($mobile, "^1\d{10}$"))  
74 - { 68 + if (!Validate::regex($mobile, "^1\d{10}$")) {
75 $this->error(__('Mobile is incorrect')); 69 $this->error(__('Mobile is incorrect'));
76 } 70 }
77 - if (!Sms::check($mobile, $captcha, 'mobilelogin'))  
78 - { 71 + if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
79 $this->error(__('Captcha is incorrect')); 72 $this->error(__('Captcha is incorrect'));
80 } 73 }
81 $user = \app\common\model\User::getByMobile($mobile); 74 $user = \app\common\model\User::getByMobile($mobile);
82 - if ($user)  
83 - { 75 + if ($user) {
84 //如果已经有账号则直接登录 76 //如果已经有账号则直接登录
85 $ret = $this->auth->direct($user->id); 77 $ret = $this->auth->direct($user->id);
86 - }  
87 - else  
88 - { 78 + } else {
89 $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []); 79 $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
90 } 80 }
91 - if ($ret)  
92 - { 81 + if ($ret) {
93 Sms::flush($mobile, 'mobilelogin'); 82 Sms::flush($mobile, 'mobilelogin');
94 $data = ['userinfo' => $this->auth->getUserinfo()]; 83 $data = ['userinfo' => $this->auth->getUserinfo()];
95 $this->success(__('Logged in successful'), $data); 84 $this->success(__('Logged in successful'), $data);
96 - }  
97 - else  
98 - { 85 + } else {
99 $this->error($this->auth->getError()); 86 $this->error($this->auth->getError());
100 } 87 }
101 } 88 }
102 89
103 /** 90 /**
104 * 注册会员 91 * 注册会员
105 - * 92 + *
106 * @param string $username 用户名 93 * @param string $username 用户名
107 * @param string $password 密码 94 * @param string $password 密码
108 * @param string $email 邮箱 95 * @param string $email 邮箱
@@ -114,26 +101,20 @@ class User extends Api @@ -114,26 +101,20 @@ class User extends Api
114 $password = $this->request->request('password'); 101 $password = $this->request->request('password');
115 $email = $this->request->request('email'); 102 $email = $this->request->request('email');
116 $mobile = $this->request->request('mobile'); 103 $mobile = $this->request->request('mobile');
117 - if (!$username || !$password)  
118 - { 104 + if (!$username || !$password) {
119 $this->error(__('Invalid parameters')); 105 $this->error(__('Invalid parameters'));
120 } 106 }
121 - if ($email && !Validate::is($email, "email"))  
122 - { 107 + if ($email && !Validate::is($email, "email")) {
123 $this->error(__('Email is incorrect')); 108 $this->error(__('Email is incorrect'));
124 } 109 }
125 - if ($mobile && !Validate::regex($mobile, "^1\d{10}$"))  
126 - { 110 + if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
127 $this->error(__('Mobile is incorrect')); 111 $this->error(__('Mobile is incorrect'));
128 } 112 }
129 $ret = $this->auth->register($username, $password, $email, $mobile, []); 113 $ret = $this->auth->register($username, $password, $email, $mobile, []);
130 - if ($ret)  
131 - { 114 + if ($ret) {
132 $data = ['userinfo' => $this->auth->getUserinfo()]; 115 $data = ['userinfo' => $this->auth->getUserinfo()];
133 $this->success(__('Sign up successful'), $data); 116 $this->success(__('Sign up successful'), $data);
134 - }  
135 - else  
136 - { 117 + } else {
137 $this->error($this->auth->getError()); 118 $this->error($this->auth->getError());
138 } 119 }
139 } 120 }
@@ -149,7 +130,7 @@ class User extends Api @@ -149,7 +130,7 @@ class User extends Api
149 130
150 /** 131 /**
151 * 修改会员个人信息 132 * 修改会员个人信息
152 - * 133 + *
153 * @param string $avatar 头像地址 134 * @param string $avatar 头像地址
154 * @param string $username 用户名 135 * @param string $username 用户名
155 * @param string $nickname 昵称 136 * @param string $nickname 昵称
@@ -162,12 +143,13 @@ class User extends Api @@ -162,12 +143,13 @@ class User extends Api
162 $nickname = $this->request->request('nickname'); 143 $nickname = $this->request->request('nickname');
163 $bio = $this->request->request('bio'); 144 $bio = $this->request->request('bio');
164 $avatar = $this->request->request('avatar'); 145 $avatar = $this->request->request('avatar');
165 - $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();  
166 - if ($exists)  
167 - {  
168 - $this->error(__('Username already exists')); 146 + if ($username) {
  147 + $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
  148 + if ($exists) {
  149 + $this->error(__('Username already exists'));
  150 + }
  151 + $user->username = $username;
169 } 152 }
170 - $user->username = $username;  
171 $user->nickname = $nickname; 153 $user->nickname = $nickname;
172 $user->bio = $bio; 154 $user->bio = $bio;
173 $user->avatar = $avatar; 155 $user->avatar = $avatar;
@@ -177,7 +159,7 @@ class User extends Api @@ -177,7 +159,7 @@ class User extends Api
177 159
178 /** 160 /**
179 * 修改邮箱 161 * 修改邮箱
180 - * 162 + *
181 * @param string $email 邮箱 163 * @param string $email 邮箱
182 * @param string $captcha 验证码 164 * @param string $captcha 验证码
183 */ 165 */
@@ -186,21 +168,17 @@ class User extends Api @@ -186,21 +168,17 @@ class User extends Api
186 $user = $this->auth->getUser(); 168 $user = $this->auth->getUser();
187 $email = $this->request->post('email'); 169 $email = $this->request->post('email');
188 $captcha = $this->request->request('captcha'); 170 $captcha = $this->request->request('captcha');
189 - if (!$email || !$captcha)  
190 - { 171 + if (!$email || !$captcha) {
191 $this->error(__('Invalid parameters')); 172 $this->error(__('Invalid parameters'));
192 } 173 }
193 - if (!Validate::is($email, "email"))  
194 - { 174 + if (!Validate::is($email, "email")) {
195 $this->error(__('Email is incorrect')); 175 $this->error(__('Email is incorrect'));
196 } 176 }
197 - if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find())  
198 - { 177 + if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) {
199 $this->error(__('Email already exists')); 178 $this->error(__('Email already exists'));
200 } 179 }
201 $result = Ems::check($email, $captcha, 'changeemail'); 180 $result = Ems::check($email, $captcha, 'changeemail');
202 - if (!$result)  
203 - { 181 + if (!$result) {
204 $this->error(__('Captcha is incorrect')); 182 $this->error(__('Captcha is incorrect'));
205 } 183 }
206 $verification = $user->verification; 184 $verification = $user->verification;
@@ -215,7 +193,7 @@ class User extends Api @@ -215,7 +193,7 @@ class User extends Api
215 193
216 /** 194 /**
217 * 修改手机号 195 * 修改手机号
218 - * 196 + *
219 * @param string $email 手机号 197 * @param string $email 手机号
220 * @param string $captcha 验证码 198 * @param string $captcha 验证码
221 */ 199 */
@@ -224,21 +202,17 @@ class User extends Api @@ -224,21 +202,17 @@ class User extends Api
224 $user = $this->auth->getUser(); 202 $user = $this->auth->getUser();
225 $mobile = $this->request->request('mobile'); 203 $mobile = $this->request->request('mobile');
226 $captcha = $this->request->request('captcha'); 204 $captcha = $this->request->request('captcha');
227 - if (!$mobile || !$captcha)  
228 - { 205 + if (!$mobile || !$captcha) {
229 $this->error(__('Invalid parameters')); 206 $this->error(__('Invalid parameters'));
230 } 207 }
231 - if (!Validate::regex($mobile, "^1\d{10}$"))  
232 - { 208 + if (!Validate::regex($mobile, "^1\d{10}$")) {
233 $this->error(__('Mobile is incorrect')); 209 $this->error(__('Mobile is incorrect'));
234 } 210 }
235 - if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find())  
236 - { 211 + if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
237 $this->error(__('Mobile already exists')); 212 $this->error(__('Mobile already exists'));
238 } 213 }
239 $result = Sms::check($mobile, $captcha, 'changemobile'); 214 $result = Sms::check($mobile, $captcha, 'changemobile');
240 - if (!$result)  
241 - { 215 + if (!$result) {
242 $this->error(__('Captcha is incorrect')); 216 $this->error(__('Captcha is incorrect'));
243 } 217 }
244 $verification = $user->verification; 218 $verification = $user->verification;
@@ -253,7 +227,7 @@ class User extends Api @@ -253,7 +227,7 @@ class User extends Api
253 227
254 /** 228 /**
255 * 第三方登录 229 * 第三方登录
256 - * 230 + *
257 * @param string $platform 平台名称 231 * @param string $platform 平台名称
258 * @param string $code Code码 232 * @param string $code Code码
259 */ 233 */
@@ -263,18 +237,15 @@ class User extends Api @@ -263,18 +237,15 @@ class User extends Api
263 $platform = $this->request->request("platform"); 237 $platform = $this->request->request("platform");
264 $code = $this->request->request("code"); 238 $code = $this->request->request("code");
265 $config = get_addon_config('third'); 239 $config = get_addon_config('third');
266 - if (!$config || !isset($config[$platform]))  
267 - { 240 + if (!$config || !isset($config[$platform])) {
268 $this->error(__('Invalid parameters')); 241 $this->error(__('Invalid parameters'));
269 } 242 }
270 $app = new \addons\third\library\Application($config); 243 $app = new \addons\third\library\Application($config);
271 //通过code换access_token和绑定会员 244 //通过code换access_token和绑定会员
272 $result = $app->{$platform}->getUserInfo(['code' => $code]); 245 $result = $app->{$platform}->getUserInfo(['code' => $code]);
273 - if ($result)  
274 - { 246 + if ($result) {
275 $loginret = \addons\third\library\Service::connect($platform, $result); 247 $loginret = \addons\third\library\Service::connect($platform, $result);
276 - if ($loginret)  
277 - { 248 + if ($loginret) {
278 $data = [ 249 $data = [
279 'userinfo' => $this->auth->getUserinfo(), 250 'userinfo' => $this->auth->getUserinfo(),
280 'thirdinfo' => $result 251 'thirdinfo' => $result
@@ -287,7 +258,7 @@ class User extends Api @@ -287,7 +258,7 @@ class User extends Api
287 258
288 /** 259 /**
289 * 重置密码 260 * 重置密码
290 - * 261 + *
291 * @param string $mobile 手机号 262 * @param string $mobile 手机号
292 * @param string $newpassword 新密码 263 * @param string $newpassword 新密码
293 * @param string $captcha 验证码 264 * @param string $captcha 验证码
@@ -299,42 +270,32 @@ class User extends Api @@ -299,42 +270,32 @@ class User extends Api
299 $email = $this->request->request("email"); 270 $email = $this->request->request("email");
300 $newpassword = $this->request->request("newpassword"); 271 $newpassword = $this->request->request("newpassword");
301 $captcha = $this->request->request("captcha"); 272 $captcha = $this->request->request("captcha");
302 - if (!$newpassword || !$captcha)  
303 - { 273 + if (!$newpassword || !$captcha) {
304 $this->error(__('Invalid parameters')); 274 $this->error(__('Invalid parameters'));
305 } 275 }
306 - if ($type == 'mobile')  
307 - {  
308 - if (!Validate::regex($mobile, "^1\d{10}$"))  
309 - { 276 + if ($type == 'mobile') {
  277 + if (!Validate::regex($mobile, "^1\d{10}$")) {
310 $this->error(__('Mobile is incorrect')); 278 $this->error(__('Mobile is incorrect'));
311 } 279 }
312 $user = \app\common\model\User::getByMobile($mobile); 280 $user = \app\common\model\User::getByMobile($mobile);
313 - if (!$user)  
314 - { 281 + if (!$user) {
315 $this->error(__('User not found')); 282 $this->error(__('User not found'));
316 } 283 }
317 $ret = Sms::check($mobile, $captcha, 'resetpwd'); 284 $ret = Sms::check($mobile, $captcha, 'resetpwd');
318 - if (!$ret)  
319 - { 285 + if (!$ret) {
320 $this->error(__('Captcha is incorrect')); 286 $this->error(__('Captcha is incorrect'));
321 } 287 }
322 Sms::flush($mobile, 'resetpwd'); 288 Sms::flush($mobile, 'resetpwd');
323 - }  
324 - else  
325 - {  
326 - if (!Validate::is($email, "email"))  
327 - { 289 + } else {
  290 + if (!Validate::is($email, "email")) {
328 $this->error(__('Email is incorrect')); 291 $this->error(__('Email is incorrect'));
329 } 292 }
330 $user = \app\common\model\User::getByEmail($email); 293 $user = \app\common\model\User::getByEmail($email);
331 - if (!$user)  
332 - { 294 + if (!$user) {
333 $this->error(__('User not found')); 295 $this->error(__('User not found'));
334 } 296 }
335 $ret = Ems::check($email, $captcha, 'resetpwd'); 297 $ret = Ems::check($email, $captcha, 'resetpwd');
336 - if (!$ret)  
337 - { 298 + if (!$ret) {
338 $this->error(__('Captcha is incorrect')); 299 $this->error(__('Captcha is incorrect'));
339 } 300 }
340 Ems::flush($email, 'resetpwd'); 301 Ems::flush($email, 'resetpwd');
@@ -342,12 +303,9 @@ class User extends Api @@ -342,12 +303,9 @@ class User extends Api
342 //模拟一次登录 303 //模拟一次登录
343 $this->auth->direct($user->id); 304 $this->auth->direct($user->id);
344 $ret = $this->auth->changepwd($newpassword, '', true); 305 $ret = $this->auth->changepwd($newpassword, '', true);
345 - if ($ret)  
346 - { 306 + if ($ret) {
347 $this->success(__('Reset password successful')); 307 $this->success(__('Reset password successful'));
348 - }  
349 - else  
350 - { 308 + } else {
351 $this->error($this->auth->getError()); 309 $this->error($this->auth->getError());
352 } 310 }
353 } 311 }
@@ -64,7 +64,7 @@ class Frontend extends Controller @@ -64,7 +64,7 @@ class Frontend extends Controller
64 $this->auth->init($token); 64 $this->auth->init($token);
65 //检测是否登录 65 //检测是否登录
66 if (!$this->auth->isLogin()) { 66 if (!$this->auth->isLogin()) {
67 - $this->error(__('Please login first'), 'user/login'); 67 + $this->error(__('Please login first'), 'index/user/login');
68 } 68 }
69 // 判断是否需要验证权限 69 // 判断是否需要验证权限
70 if (!$this->auth->match($this->noNeedRight)) { 70 if (!$this->auth->match($this->noNeedRight)) {
@@ -92,6 +92,9 @@ @@ -92,6 +92,9 @@
92 padding-left:0px; 92 padding-left:0px;
93 } 93 }
94 } 94 }
  95 + .label-primary {
  96 + background-color: #248aff;
  97 + }
95 98
96 </style> 99 </style>
97 </head> 100 </head>
@@ -3727,7 +3730,7 @@ @@ -3727,7 +3730,7 @@
3727 3730
3728 <div class="row mt0 footer"> 3731 <div class="row mt0 footer">
3729 <div class="col-md-6" align="left"> 3732 <div class="col-md-6" align="left">
3730 - Generated on 2018-10-19 17:00:36 </div> 3733 + Generated on 2019-02-26 17:13:43 </div>
3731 <div class="col-md-6" align="right"> 3734 <div class="col-md-6" align="right">
3732 <a href="https://www.fastadmin.net" target="_blank">FastAdmin</a> 3735 <a href="https://www.fastadmin.net" target="_blank">FastAdmin</a>
3733 </div> 3736 </div>
@@ -3929,6 +3932,9 @@ @@ -3929,6 +3932,9 @@
3929 contentType: false, 3932 contentType: false,
3930 processData: false, 3933 processData: false,
3931 headers: headers, 3934 headers: headers,
  3935 + xhrFields: {
  3936 + withCredentials: true
  3937 + },
3932 success: function (data, textStatus, xhr) { 3938 success: function (data, textStatus, xhr) {
3933 if (typeof data === 'object') { 3939 if (typeof data === 'object') {
3934 var str = JSON.stringify(data, null, 2); 3940 var str = JSON.stringify(data, null, 2);
@@ -92,7 +92,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin @@ -92,7 +92,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
92 'click .btn-chooseone': function (e, value, row, index) { 92 'click .btn-chooseone': function (e, value, row, index) {
93 var multiple = Backend.api.query('multiple'); 93 var multiple = Backend.api.query('multiple');
94 multiple = multiple == 'true' ? true : false; 94 multiple = multiple == 'true' ? true : false;
95 - Fast.api.close({url: row.url, multiple: false}); 95 + Fast.api.close({url: row.url, multiple: multiple});
96 }, 96 },
97 }, formatter: function () { 97 }, formatter: function () {
98 return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>'; 98 return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
@@ -110,7 +110,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin @@ -110,7 +110,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
110 }); 110 });
111 var multiple = Backend.api.query('multiple'); 111 var multiple = Backend.api.query('multiple');
112 multiple = multiple == 'true' ? true : false; 112 multiple = multiple == 'true' ? true : false;
113 - Fast.api.close({url: urlArr.join(","), multiple: true}); 113 + Fast.api.close({url: urlArr.join(","), multiple: multiple});
114 }); 114 });
115 115
116 // 为表格绑定事件 116 // 为表格绑定事件
@@ -350,7 +350,7 @@ @@ -350,7 +350,7 @@
350 var searchQuery = getSearchQuery(this); 350 var searchQuery = getSearchQuery(this);
351 this.trigger('common-search', this, searchQuery); 351 this.trigger('common-search', this, searchQuery);
352 this.options.pageNumber = 1; 352 this.options.pageNumber = 1;
353 - this.options.pageSize = $.fn.bootstrapTable.defaults.pageSize; 353 + //this.options.pageSize = $.fn.bootstrapTable.defaults.pageSize;
354 this.refresh({}); 354 this.refresh({});
355 }; 355 };
356 356
@@ -114,7 +114,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine @@ -114,7 +114,7 @@ define(['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefine
114 }, 114 },
115 //打开一个弹出窗口 115 //打开一个弹出窗口
116 open: function (url, title, options) { 116 open: function (url, title, options) {
117 - title = title ? title : ""; 117 + title = options && options.title ? options.title : (title ? title : "");
118 url = Fast.api.fixurl(url); 118 url = Fast.api.fixurl(url);
119 url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1"; 119 url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
120 var area = [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%']; 120 var area = [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
@@ -16,6 +16,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -16,6 +16,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
16 showExport: true, 16 showExport: true,
17 exportDataType: "all", 17 exportDataType: "all",
18 exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'], 18 exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
  19 + exportOptions: {
  20 + fileName: 'export_' + Moment().format("YYYY-MM-DD"),
  21 + ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
  22 + },
19 pageSize: 10, 23 pageSize: 10,
20 pageList: [10, 25, 50, 'All'], 24 pageList: [10, 25, 50, 'All'],
21 pagination: true, 25 pagination: true,
@@ -62,6 +66,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -62,6 +66,10 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
62 multibtn: '.btn-multi', 66 multibtn: '.btn-multi',
63 disabledbtn: '.btn-disabled', 67 disabledbtn: '.btn-disabled',
64 editonebtn: '.btn-editone', 68 editonebtn: '.btn-editone',
  69 + restoreonebtn: '.btn-restoreone',
  70 + destroyonebtn: '.btn-destroyone',
  71 + restoreallbtn: '.btn-restoreall',
  72 + destroyallbtn: '.btn-destroyall',
65 dragsortfield: 'weigh', 73 dragsortfield: 'weigh',
66 }, 74 },
67 api: { 75 api: {
@@ -203,6 +211,29 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -203,6 +211,29 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
203 Fast.api.open(url, __('Edit'), $(that).data() || {}); 211 Fast.api.open(url, __('Edit'), $(that).data() || {});
204 }); 212 });
205 }); 213 });
  214 + //清空回收站
  215 + $(document).on('click', Table.config.destroyallbtn, function () {
  216 + var that = this;
  217 + Layer.confirm(__('Are you sure you want to truncate?'), function () {
  218 + var url = $(that).data("url") ? $(that).data("url") : $(that).attr("href");
  219 + Fast.api.ajax(url, function () {
  220 + Layer.closeAll();
  221 + table.bootstrapTable('refresh');
  222 + }, function () {
  223 + Layer.closeAll();
  224 + });
  225 + });
  226 + return false;
  227 + });
  228 + //还原或删除
  229 + $(document).on('click', Table.config.restoreallbtn + ',' + Table.config.restoreonebtn + ',' + Table.config.destroyonebtn, function () {
  230 + var that = this;
  231 + var url = $(that).data("url") ? $(that).data("url") : $(that).attr("href");
  232 + Fast.api.ajax(url, function () {
  233 + table.bootstrapTable('refresh');
  234 + });
  235 + return false;
  236 + });
206 // 批量操作按钮事件 237 // 批量操作按钮事件
207 $(toolbar).on('click', Table.config.multibtn, function () { 238 $(toolbar).on('click', Table.config.multibtn, function () {
208 var ids = Table.api.selectedids(table); 239 var ids = Table.api.selectedids(table);
@@ -369,14 +400,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -369,14 +400,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
369 },//单元格图片预览 400 },//单元格图片预览
370 image: { 401 image: {
371 'click .img-center': function (e, value, row, index) { 402 'click .img-center': function (e, value, row, index) {
372 - data = [];  
373 - value= value.split(","); 403 + var data = [];
  404 + value = value.split(",");
374 $.each(value, function (index, value) { 405 $.each(value, function (index, value) {
375 data.push({ 406 data.push({
376 src: Fast.api.cdnurl(value), 407 src: Fast.api.cdnurl(value),
377 }); 408 });
378 }); 409 });
379 - layer.photos({ 410 + Layer.photos({
380 photos: { 411 photos: {
381 "data": data 412 "data": data
382 }, 413 },
@@ -558,7 +589,8 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -558,7 +589,8 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
558 type = typeof type === 'undefined' ? 'buttons' : type; 589 type = typeof type === 'undefined' ? 'buttons' : type;
559 var options = table ? table.bootstrapTable('getOptions') : {}; 590 var options = table ? table.bootstrapTable('getOptions') : {};
560 var html = []; 591 var html = [];
561 - var hidden, visible, disable, url, classname, icon, text, title, refresh, confirm, extend, click, dropdown, link; 592 + var hidden, visible, disable, url, classname, icon, text, title, refresh, confirm, extend,
  593 + dropdown, link;
562 var fieldIndex = column.fieldIndex; 594 var fieldIndex = column.fieldIndex;
563 var dropdowns = {}; 595 var dropdowns = {};
564 596
@@ -573,11 +605,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -573,11 +605,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
573 } 605 }
574 var attr = table.data(type + "-" + j.name); 606 var attr = table.data(type + "-" + j.name);
575 if (typeof attr === 'undefined' || attr) { 607 if (typeof attr === 'undefined' || attr) {
576 - hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (j.hidden ? j.hidden : false); 608 + hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (typeof j.hidden !== 'undefined' ? j.hidden : false);
577 if (hidden) { 609 if (hidden) {
578 return true; 610 return true;
579 } 611 }
580 - visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (j.visible ? j.visible : true); 612 + visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (typeof j.visible !== 'undefined' ? j.visible : true);
581 if (!visible) { 613 if (!visible) {
582 return true; 614 return true;
583 } 615 }
@@ -586,12 +618,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -586,12 +618,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
586 url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;'); 618 url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;');
587 classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one'; 619 classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
588 icon = j.icon ? j.icon : ''; 620 icon = j.icon ? j.icon : '';
589 - text = j.text ? j.text : '';  
590 - title = j.title ? j.title : text; 621 + text = typeof j.text === 'function' ? j.text.call(table, row, j) : j.text ? j.text : '';
  622 + title = typeof j.title === 'function' ? j.title.call(table, row, j) : j.title ? j.title : text;
591 refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : ''; 623 refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : '';
592 confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : ''; 624 confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : '';
593 extend = j.extend ? j.extend : ''; 625 extend = j.extend ? j.extend : '';
594 - disable = typeof j.disable === 'function' ? j.disable.call(table, row, j) : (j.disable ? j.disable : false); 626 + disable = typeof j.disable === 'function' ? j.disable.call(table, row, j) : (typeof j.disable !== 'undefined' ? j.disable : false);
595 if (disable) { 627 if (disable) {
596 classname = classname + ' disabled'; 628 classname = classname + ' disabled';
597 } 629 }