mirror of https://gitee.com/karson/fastadmin.git
新增一键CRUD类名冲突检测
新增一键CRUD自动传递请求参数 新增一键菜单之支持ThinkPHP5标准命名规则 新增Table.api.formatter.toggle自定义URL 新增Table.api.formatter.search自定义搜索字段 修复关联模型不同命名空间之间的BUG 优化时间字段修改器的判断pull/110/MERGE
parent
f5c72393d2
commit
eccf03e43f
|
|
@ -10,6 +10,7 @@ use think\console\input\Option;
|
|||
use think\console\Output;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use think\exception\ErrorException;
|
||||
use think\Lang;
|
||||
use think\Loader;
|
||||
|
||||
|
|
@ -17,6 +18,9 @@ class Crud extends Command
|
|||
{
|
||||
protected $stubList = [];
|
||||
|
||||
protected $internalKeywords = [
|
||||
'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'
|
||||
];
|
||||
/**
|
||||
* Selectpage搜索字段关联
|
||||
*/
|
||||
|
|
@ -181,6 +185,7 @@ class Crud extends Command
|
|||
$controller = $input->getOption('controller');
|
||||
//自定义模型
|
||||
$model = $input->getOption('model');
|
||||
$model = $model ? $model : $controller;
|
||||
//验证器类
|
||||
$validate = $model;
|
||||
//自定义显示字段
|
||||
|
|
@ -324,6 +329,8 @@ class Crud extends Command
|
|||
$relations[] = [
|
||||
//关联表基础名
|
||||
'relationName' => $relationName,
|
||||
//关联表类命名空间
|
||||
'relationNamespace' => $relationNamespace,
|
||||
//关联模型名
|
||||
'relationModel' => $relationModel,
|
||||
//关联文件
|
||||
|
|
@ -369,6 +376,8 @@ class Crud extends Command
|
|||
|
||||
//视图文件
|
||||
$viewArr = $controllerArr;
|
||||
$lastValue = array_pop($viewArr);
|
||||
$viewArr[] = Loader::parseName($lastValue, 0);
|
||||
array_unshift($viewArr, 'view');
|
||||
$viewDir = $adminPath . strtolower(implode(DS, $viewArr)) . DS;
|
||||
|
||||
|
|
@ -383,7 +392,7 @@ class Crud extends Command
|
|||
//是否为删除模式
|
||||
$delete = $input->getOption('delete');
|
||||
if ($delete) {
|
||||
$readyFiles = [$controllerFile, $modelFile, $validateFile, $addFile, $editFile, $indexFile, $langFile, $javascriptFile];
|
||||
$readyFiles = [$controllerFile, $modelFile, $validateFile, $addFile, $editFile, $indexFile, $recyclebinFile, $langFile, $javascriptFile];
|
||||
foreach ($readyFiles as $k => $v) {
|
||||
$output->warning($v);
|
||||
}
|
||||
|
|
@ -409,6 +418,7 @@ class Crud extends Command
|
|||
case $addFile:
|
||||
case $editFile:
|
||||
case $indexFile:
|
||||
case $recyclebinFile:
|
||||
$this->removeEmptyBaseDir($v, $viewArr);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -522,6 +532,7 @@ class Crud extends Command
|
|||
}
|
||||
$relation['relationForeignKey'] = $relationForeignKey;
|
||||
$relation['relationPrimaryKey'] = $relationPrimaryKey;
|
||||
$relation['relationClassName'] = $modelNamespace != $relation['relationNamespace'] ? $relation['relationNamespace'] . '\\' . $relation['relationName'] : $relation['relationName'];
|
||||
}
|
||||
unset($relation);
|
||||
|
||||
|
|
@ -629,9 +640,8 @@ class Crud extends Command
|
|||
$defaultDateTime = "{:date('{$phpFormat}')}";
|
||||
$attrArr['data-date-format'] = $format;
|
||||
$attrArr['data-use-current'] = "true";
|
||||
$fieldFunc = $fieldFunc ? "|{$fieldFunc}" : "";
|
||||
$formAddElement = Form::text($fieldName, $defaultDateTime, $attrArr);
|
||||
$formEditElement = Form::text($fieldName, "{\$row.{$field}{$fieldFunc}}", $attrArr);
|
||||
$formEditElement = Form::text($fieldName, ($fieldFunc ? "{:\$row.{$field}?{$fieldFunc}(\$row.{$field}):''}" : "{\$row.{$field}{$fieldFunc}}"), $attrArr);
|
||||
} elseif ($inputType == 'checkbox' || $inputType == 'radio') {
|
||||
unset($attrArr['data-rule']);
|
||||
$fieldName = $inputType == 'checkbox' ? $fieldName .= "[]" : $fieldName;
|
||||
|
|
@ -928,7 +938,7 @@ class Crud extends Command
|
|||
if ($langList) {
|
||||
$this->writeToFile('lang', $data, $langFile);
|
||||
}
|
||||
} catch (think\exception\ErrorException $e) {
|
||||
} catch (ErrorException $e) {
|
||||
throw new Exception("Code: " . $e->getCode() . "\nLine: " . $e->getLine() . "\nMessage: " . $e->getMessage() . "\nFile: " . $e->getFile());
|
||||
}
|
||||
|
||||
|
|
@ -956,7 +966,7 @@ class Crud extends Command
|
|||
public function {$methodName}()
|
||||
{
|
||||
return [{$itemString}];
|
||||
}
|
||||
}
|
||||
EOD;
|
||||
$controllerAssignList[] = <<<EOD
|
||||
\$this->view->assign("{$fieldList}", \$this->model->{$methodName}());
|
||||
|
|
@ -980,7 +990,7 @@ EOD;
|
|||
$attrField = ucfirst($this->getCamelizeName($field));
|
||||
if ($inputType == 'datetime') {
|
||||
$return = <<<EOD
|
||||
return \$value && !is_numeric(\$value) ? strtotime(\$value) : \$value;
|
||||
return \$value === '' ? null : (\$value && !is_numeric(\$value) ? strtotime(\$value) : \$value);
|
||||
EOD;
|
||||
} elseif (in_array($inputType, ['checkbox', 'select'])) {
|
||||
$return = <<<EOD
|
||||
|
|
@ -1069,9 +1079,9 @@ EOD;
|
|||
/**
|
||||
* 获取已解析相关信息
|
||||
* @param string $module 模块名称
|
||||
* @param string $name 自定义名称
|
||||
* @param string $table 数据表名
|
||||
* @param string $type 解析类型,本例中为controller、model、validate
|
||||
* @param string $name 自定义名称
|
||||
* @param string $table 数据表名
|
||||
* @param string $type 解析类型,本例中为controller、model、validate
|
||||
* @return array
|
||||
*/
|
||||
protected function getParseNameData($module, $name, $table, $type)
|
||||
|
|
@ -1087,6 +1097,10 @@ EOD;
|
|||
$parseArr = $arr;
|
||||
array_push($parseArr, $parseName);
|
||||
}
|
||||
//类名不能为内部关键字
|
||||
if (in_array(strtolower($parseName), $this->internalKeywords)) {
|
||||
throw new Exception('Unable to use internal variable:' . $parseName);
|
||||
}
|
||||
$appNamespace = Config::get('app_namespace');
|
||||
$parseNamespace = "{$appNamespace}\\{$module}\\{$type}" . ($arr ? "\\" . implode("\\", $arr) : "");
|
||||
$moduleDir = APP_PATH . $module . DS;
|
||||
|
|
@ -1097,7 +1111,7 @@ EOD;
|
|||
/**
|
||||
* 写入到文件
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @param string $pathname
|
||||
* @return mixed
|
||||
*/
|
||||
|
|
@ -1118,7 +1132,7 @@ EOD;
|
|||
/**
|
||||
* 获取替换后的数据
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
protected function getReplacedStub($name, $data)
|
||||
|
|
@ -1183,7 +1197,7 @@ EOD;
|
|||
|
||||
/**
|
||||
* 读取数据和语言数组列表
|
||||
* @param array $arr
|
||||
* @param array $arr
|
||||
* @param boolean $withTpl
|
||||
* @return array
|
||||
*/
|
||||
|
|
@ -1303,8 +1317,8 @@ EOD;
|
|||
|
||||
/**
|
||||
* 判断是否符合指定后缀
|
||||
* @param string $field 字段名称
|
||||
* @param mixed $suffixArr 后缀
|
||||
* @param string $field 字段名称
|
||||
* @param mixed $suffixArr 后缀
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isMatchSuffix($field, $suffixArr)
|
||||
|
|
@ -1371,7 +1385,7 @@ EOD;
|
|||
* @param string $field
|
||||
* @param string $datatype
|
||||
* @param string $extend
|
||||
* @param array $itemArr
|
||||
* @param array $itemArr
|
||||
* @return string
|
||||
*/
|
||||
protected function getJsColumn($field, $datatype = '', $extend = '', $itemArr = [])
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
// 初始化表格参数配置
|
||||
Table.api.init({
|
||||
extend: {
|
||||
index_url: '{%controllerUrl%}/index',
|
||||
index_url: '{%controllerUrl%}/index' + location.search,
|
||||
add_url: '{%controllerUrl%}/add',
|
||||
edit_url: '{%controllerUrl%}/edit',
|
||||
del_url: '{%controllerUrl%}/del',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
public function {%relationMethod%}()
|
||||
{
|
||||
return $this->{%relationMode%}('{%relationName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}', [], 'LEFT')->setEagerlyType(0);
|
||||
return $this->{%relationMode%}('{%relationClassName%}', '{%relationForeignKey%}', '{%relationPrimaryKey%}', [], 'LEFT')->setEagerlyType(0);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
public function {%methodName%}($value, $data)
|
||||
{
|
||||
{
|
||||
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||
$list = $this->{%listMethodName%}();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
public function {%methodName%}($value, $data)
|
||||
{
|
||||
{
|
||||
$value = $value ? $value : (isset($data['{%field%}']) ? $data['{%field%}'] : '');
|
||||
$list = $this->{%listMethodName%}();
|
||||
return isset($list[$value]) ? $list[$value] : '';
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use think\console\Input;
|
|||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
use think\Exception;
|
||||
use think\Loader;
|
||||
|
||||
class Menu extends Command
|
||||
{
|
||||
|
|
@ -52,6 +53,18 @@ class Menu extends Command
|
|||
$ids = [];
|
||||
$list = $this->model->where(function ($query) use ($controller, $equal) {
|
||||
foreach ($controller as $index => $item) {
|
||||
if (stripos($item, '_') !== false) {
|
||||
$item = Loader::parseName($item, 1);
|
||||
}
|
||||
if (stripos($item, '/') !== false) {
|
||||
$controllerArr = explode('/', $item);
|
||||
end($controllerArr);
|
||||
$key = key($controllerArr);
|
||||
$controllerArr[$key] = Loader::parseName($controllerArr[$key]);
|
||||
} else {
|
||||
$controllerArr = [Loader::parseName($item)];
|
||||
}
|
||||
$item = str_replace('_', '\_', implode('/', $controllerArr));
|
||||
if ($equal) {
|
||||
$query->whereOr('name', 'eq', $item);
|
||||
} else {
|
||||
|
|
@ -82,10 +95,17 @@ class Menu extends Command
|
|||
|
||||
if (!in_array('all-controller', $controller)) {
|
||||
foreach ($controller as $index => $item) {
|
||||
$controllerArr = explode('/', $item);
|
||||
end($controllerArr);
|
||||
$key = key($controllerArr);
|
||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||
if (stripos($item, '_') !== false) {
|
||||
$item = Loader::parseName($item, 1);
|
||||
}
|
||||
if (stripos($item, '/') !== false) {
|
||||
$controllerArr = explode('/', $item);
|
||||
end($controllerArr);
|
||||
$key = key($controllerArr);
|
||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||
} else {
|
||||
$controllerArr = [ucfirst($item)];
|
||||
}
|
||||
$adminPath = dirname(__DIR__) . DS . 'controller' . DS . implode(DS, $controllerArr) . '.php';
|
||||
if (!is_file($adminPath)) {
|
||||
$output->error("controller not found");
|
||||
|
|
@ -159,10 +179,15 @@ class Menu extends Command
|
|||
protected function importRule($controller)
|
||||
{
|
||||
$controller = str_replace('\\', '/', $controller);
|
||||
$controllerArr = explode('/', $controller);
|
||||
end($controllerArr);
|
||||
$key = key($controllerArr);
|
||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||
if (stripos($controller, '/') !== false) {
|
||||
$controllerArr = explode('/', $controller);
|
||||
end($controllerArr);
|
||||
$key = key($controllerArr);
|
||||
$controllerArr[$key] = ucfirst($controllerArr[$key]);
|
||||
} else {
|
||||
$key = 0;
|
||||
$controllerArr = [ucfirst($controller)];
|
||||
}
|
||||
$classSuffix = Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';
|
||||
$className = "\\app\\admin\\controller\\" . implode("\\", $controllerArr) . $classSuffix;
|
||||
|
||||
|
|
|
|||
|
|
@ -479,14 +479,20 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
var color = typeof this.color !== 'undefined' ? this.color : 'success';
|
||||
var yes = typeof this.yes !== 'undefined' ? this.yes : 1;
|
||||
var no = typeof this.no !== 'undefined' ? this.no : 0;
|
||||
var url = typeof this.url !== 'undefined' ? this.url : '';
|
||||
return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Click to toggle') + "' class='btn-change' data-id='"
|
||||
+ row.id + "' data-params='" + this.field + "=" + (value == yes ? no : yes) + "'><i class='fa fa-toggle-on " + (value == yes ? 'text-' + color : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";
|
||||
+ row.id + "' " + (url ? "data-url='" + url + "'" : "") + " data-params='" + this.field + "=" + (value == yes ? no : yes) + "'><i class='fa fa-toggle-on " + (value == yes ? 'text-' + color : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";
|
||||
},
|
||||
url: function (value, row, index) {
|
||||
return '<div class="input-group input-group-sm" style="width:250px;margin:0 auto;"><input type="text" class="form-control input-sm" value="' + value + '"><span class="input-group-btn input-group-sm"><a href="' + value + '" target="_blank" class="btn btn-default btn-sm"><i class="fa fa-link"></i></a></span></div>';
|
||||
},
|
||||
search: function (value, row, index) {
|
||||
return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
|
||||
var field = this.field;
|
||||
if (typeof this.customField !== 'undefined' && typeof row[this.customField] !== 'undefined') {
|
||||
value = row[this.customField];
|
||||
field = this.customField;
|
||||
}
|
||||
return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + field + '" data-value="' + value + '">' + value + '</a>';
|
||||
},
|
||||
addtabs: function (value, row, index) {
|
||||
var url = Table.api.replaceurl(this.url, row, this.table);
|
||||
|
|
|
|||
Loading…
Reference in New Issue