mirror of https://gitee.com/karson/fastadmin.git
新增SelectPage插件
新增CRUD生成Swith类型的Checkbox,支持tinyint和char 移除Typeahead、Tagsinput、Bootstrap-select-ajax插件 修复快捷搜索不能使用关联表字段的BUGpull/323483/MERGE
parent
438190e79f
commit
61200ff9dc
|
|
@ -17,6 +17,72 @@ class Crud extends Command
|
|||
|
||||
protected $stubList = [];
|
||||
|
||||
/**
|
||||
* Selectpage搜索字段关联
|
||||
*/
|
||||
protected $fieldSelectpageMap = [
|
||||
'nickname' => ['user_id', 'user_ids', 'admin_id', 'admin_ids']
|
||||
];
|
||||
|
||||
/**
|
||||
* Enum类型识别为单选框的结尾字符,默认会识别为单选下拉列表
|
||||
*/
|
||||
protected $enumRadioSuffix = 'data';
|
||||
|
||||
/**
|
||||
* Set类型识别为复选框的结尾字符,默认会识别为多选下拉列表
|
||||
*/
|
||||
protected $setCheckboxSuffix = 'data';
|
||||
|
||||
/**
|
||||
* Int类型识别为日期时间的结尾字符,默认会识别为数字文本框
|
||||
*/
|
||||
protected $intDateSuffix = 'time';
|
||||
|
||||
/**
|
||||
* 开头后缀
|
||||
*/
|
||||
protected $switchSuffix = 'switch';
|
||||
|
||||
/**
|
||||
* 以指定字符结尾的字段格式化函数
|
||||
*/
|
||||
protected $fieldFormatterSuffix = [
|
||||
'status' => 'status',
|
||||
'icon' => 'icon',
|
||||
'flag' => 'flag',
|
||||
'url' => 'url',
|
||||
'url' => 'url',
|
||||
'image' => 'image',
|
||||
'images' => 'images',
|
||||
'time' => ['type' => ['int', 'timestamp'], 'name' => 'datetime']
|
||||
];
|
||||
|
||||
/**
|
||||
* 识别为图片字段
|
||||
*/
|
||||
protected $imageField = ['image', 'images', 'avatar', 'avatars'];
|
||||
|
||||
/**
|
||||
* 识别为文件字段
|
||||
*/
|
||||
protected $fileField = ['file', 'files'];
|
||||
|
||||
/**
|
||||
* 保留字段
|
||||
*/
|
||||
protected $reservedField = ['createtime', 'updatetime'];
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
protected $sortField = 'weigh';
|
||||
|
||||
/**
|
||||
* 编辑器的Class
|
||||
*/
|
||||
protected $editorClass = 'summernote';
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
|
|
@ -286,7 +352,7 @@ class Crud extends Command
|
|||
}
|
||||
$inputType = '';
|
||||
//createtime和updatetime是保留字段不能修改和添加
|
||||
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, ['createtime', 'updatetime']))
|
||||
if ($v['COLUMN_KEY'] != 'PRI' && !in_array($field, $this->reservedField))
|
||||
{
|
||||
$inputType = $this->getFieldType($v);
|
||||
|
||||
|
|
@ -381,34 +447,72 @@ class Crud extends Command
|
|||
}
|
||||
else if ($inputType == 'textarea')
|
||||
{
|
||||
$cssClassArr[] = substr($field, -7) == 'content' ? 'summernote' : '';
|
||||
$cssClassArr[] = substr($field, -7) == 'content' ? $this->editorClass : '';
|
||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||
$attrArr['rows'] = 5;
|
||||
$formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
|
||||
$formEditElement = Form::textarea($fieldName, $editValue, $attrArr);
|
||||
}
|
||||
else if ($field == 'category_id' || $field == 'category_ids')
|
||||
else if ($inputType == 'switch')
|
||||
{
|
||||
$type = $table;
|
||||
if ($field == 'category_ids')
|
||||
if ($defaultValue === '1' || $defaultValue === 'Y')
|
||||
{
|
||||
$attrArr['multiple'] = '';
|
||||
}
|
||||
$attrStr = $this->getArrayString($attrArr);
|
||||
$formAddElement = "{:build_category_select('{$fieldName}', '{$type}', '{$defaultValue}', [{$attrStr}])}";
|
||||
$formEditElement = "{:build_category_select('{$fieldName}', '{$type}', \$row.{$field}, [{$attrStr}])}";
|
||||
$yes = $defaultValue;
|
||||
$no = $defaultValue === '1' ? '0' : 'N';
|
||||
}
|
||||
else
|
||||
{
|
||||
//CSS类名
|
||||
$cssClassArr[] = substr($field, -3) == '_id' ? 'typeahead' : '';
|
||||
$cssClassArr[] = substr($field, -4) == '_ids' ? 'tagsinput' : '';
|
||||
$cssClassArr = array_filter($cssClassArr);
|
||||
$no = $defaultValue;
|
||||
$yes = $defaultValue === '0' ? '1' : 'Y';
|
||||
}
|
||||
$formAddElement = $formEditElement = Form::hidden($fieldName, $no, array_merge(['checked' => ''], $attrArr));
|
||||
$attrArr['id'] = $fieldName . "-switch";
|
||||
$formAddElement .= sprintf(Form::label("{$attrArr['id']}", "%s abcdefg"), Form::checkbox($fieldName, $yes, $defaultValue === $yes, $attrArr));
|
||||
$formEditElement .= sprintf(Form::label("{$attrArr['id']}", "%s abcdefg"), Form::checkbox($fieldName, $yes, 0, $attrArr));
|
||||
$formEditElement = str_replace('type="checkbox"', 'type="checkbox" {in name="' . "\$row.{$field}" . '" value="' . $yes . '"}checked{/in}', $formEditElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
$search = $replace = '';
|
||||
//特殊字段为关联搜索
|
||||
if (substr($field, -3) == '_id' || substr($field, -4) == '_ids')
|
||||
{
|
||||
$inputType = 'text';
|
||||
$defaultValue = '';
|
||||
$attrArr['data-rule'] = 'required';
|
||||
$cssClassArr[] = 'selectpage';
|
||||
$attrArr['data-db-table'] = substr($field, 0, strripos($field, '_'));
|
||||
if ($attrArr['data-db-table'] == 'category')
|
||||
{
|
||||
$attrArr['data-params'] = '##replacetext##';
|
||||
$search = '"##replacetext##"';
|
||||
$replace = '\'{"custom[type]":"' . $table . '"}\'';
|
||||
}
|
||||
if (substr($field, -4) == '_ids')
|
||||
{
|
||||
$attrArr['data-multiple'] = 'true';
|
||||
}
|
||||
foreach ($this->fieldSelectpageMap as $m => $n)
|
||||
{
|
||||
if (in_array($field, $n))
|
||||
{
|
||||
$attrArr['data-field'] = $m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//因为有自动完成可输入其它内容
|
||||
$step = array_intersect($cssClassArr, ['typeahead', 'tagsinput']) ? 0 : $step;
|
||||
$step = array_intersect($cssClassArr, ['selectpage']) ? 0 : $step;
|
||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||
|
||||
$isUpload = in_array(substr($field, -4), ['file']) || in_array(substr($field, -5), ['files', 'image']) || in_array(substr($field, -6), ['images', 'avatar']) || in_array(substr($field, -7), ['avatars']) ? TRUE : FALSE;
|
||||
$isUpload = false;
|
||||
foreach (array_merge($this->imageField, $this->fileField) as $m => $n)
|
||||
{
|
||||
if (preg_match("/{$n}$/i", $field))
|
||||
{
|
||||
$isUpload = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//如果是步长则加上步长
|
||||
if ($step)
|
||||
{
|
||||
|
|
@ -422,7 +526,11 @@ class Crud extends Command
|
|||
|
||||
$formAddElement = Form::input($inputType, $fieldName, $defaultValue, $attrArr);
|
||||
$formEditElement = Form::input($inputType, $fieldName, $editValue, $attrArr);
|
||||
|
||||
if ($search && $replace)
|
||||
{
|
||||
$formAddElement = str_replace($search, $replace, $formAddElement);
|
||||
$formEditElement = str_replace($search, $replace, $formEditElement);
|
||||
}
|
||||
//如果是图片或文件
|
||||
if ($isUpload)
|
||||
{
|
||||
|
|
@ -450,8 +558,8 @@ class Crud extends Command
|
|||
{
|
||||
$javascriptList[] = $this->getJsColumn($field, $v['DATA_TYPE'], '_text');
|
||||
}
|
||||
//排序方式,如果有weigh则按weigh,否则按主键排序
|
||||
$order = $field == 'weigh' ? 'weigh' : $order;
|
||||
//排序方式,如果有指定排序字段,否则按主键排序
|
||||
$order = $field == $this->sortField ? $this->sortField : $order;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -579,7 +687,7 @@ class Crud extends Command
|
|||
}
|
||||
catch (\think\exception\ErrorException $e)
|
||||
{
|
||||
throw new Exception("Code: " . $e->getCode() . "\nLine: " . $e->getLine() . "\nMessage: " . $e->getMessage());
|
||||
throw new Exception("Code: " . $e->getCode() . "\nLine: " . $e->getLine() . "\nMessage: " . $e->getMessage() . "\nFile: " . $e->getFile());
|
||||
}
|
||||
$output->info("Build Successed");
|
||||
}
|
||||
|
|
@ -846,21 +954,26 @@ EOD;
|
|||
break;
|
||||
}
|
||||
$fieldsName = $v['COLUMN_NAME'];
|
||||
// 如果后缀以time结尾说明也是个时间字段
|
||||
if (substr($fieldsName, -4) == 'time')
|
||||
// 指定后缀说明也是个时间字段
|
||||
if (preg_match("/{$this->intDateSuffix}$/i", $fieldsName))
|
||||
{
|
||||
$inputType = 'datetime';
|
||||
}
|
||||
// 如果后缀以data结尾且类型为enum,说明是个单选框
|
||||
if (substr($fieldsName, -4) == 'data' && $v['DATA_TYPE'] == 'enum')
|
||||
// 指定后缀结尾且类型为enum,说明是个单选框
|
||||
if (preg_match("/{$this->enumRadioSuffix}$/i", $fieldsName) && $v['DATA_TYPE'] == 'enum')
|
||||
{
|
||||
$inputType = "radio";
|
||||
}
|
||||
// 如果后缀以data结尾且类型为set,说明是个复选框
|
||||
if (substr($fieldsName, -4) == 'data' && $v['DATA_TYPE'] == 'set')
|
||||
// 指定后缀结尾且类型为set,说明是个复选框
|
||||
if (preg_match("/{$this->setCheckboxSuffix}$/i", $fieldsName) && $v['DATA_TYPE'] == 'set')
|
||||
{
|
||||
$inputType = "checkbox";
|
||||
}
|
||||
// 指定后缀结尾且类型为char或tinyint且长度为1,说明是个Switch复选框
|
||||
if (preg_match("/{$this->switchSuffix}$/i", $fieldsName) && ($v['COLUMN_TYPE'] == 'tinyint(1)' || $v['COLUMN_TYPE'] == 'char(1)') && $v['COLUMN_DEFAULT'] !== '' && $v['COLUMN_DEFAULT'] !== null)
|
||||
{
|
||||
$inputType = "switch";
|
||||
}
|
||||
return $inputType;
|
||||
}
|
||||
|
||||
|
|
@ -891,7 +1004,15 @@ EOD;
|
|||
*/
|
||||
protected function getImageUpload($field, $content)
|
||||
{
|
||||
$filter = substr($field, -4) == 'avatar' || substr($field, -5) == 'image' || substr($field, -6) == 'images' ? ' data-mimetype="image/*"' : "";
|
||||
$filter = '';
|
||||
foreach ($this->imageField as $k => $v)
|
||||
{
|
||||
if (preg_match("/{$v}$/i", $field))
|
||||
{
|
||||
$filter = ' data-mimetype="image/*"';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$multiple = substr($field, -1) == 's' ? ' data-multiple="true"' : ' data-multiple="false"';
|
||||
$preview = $filter ? ' data-preview-id="p-' . $field . '"' : '';
|
||||
$previewcontainer = $preview ? '<ul class="row list-inline plupload-preview" id="p-' . $field . '"></ul>' : '';
|
||||
|
|
@ -914,22 +1035,26 @@ EOD;
|
|||
{
|
||||
$lang = ucfirst($field);
|
||||
$html = str_repeat(" ", 24) . "{field: '{$field}{$extend}', title: __('{$lang}')";
|
||||
$field = stripos($field, ".") !== false ? substr($field, stripos($field, '.') + 1) : $field;
|
||||
$formatter = '';
|
||||
if ($field == 'status')
|
||||
$formatter = 'status';
|
||||
else if ($field == 'icon')
|
||||
$formatter = 'icon';
|
||||
else if ($field == 'flag')
|
||||
$formatter = 'flag';
|
||||
else if (substr($field, -4) == 'time' && in_array($datatype, ['int', 'timestamp']))
|
||||
$formatter = 'datetime';
|
||||
else if (substr($field, -3) == 'url' || substr($field, -4) == 'file')
|
||||
$formatter = 'url';
|
||||
else if (substr($field, -5) == 'image')
|
||||
$formatter = 'image';
|
||||
else if (substr($field, -6) == 'images')
|
||||
$formatter = 'images';
|
||||
foreach ($this->fieldFormatterSuffix as $k => $v)
|
||||
{
|
||||
if (preg_match("/{$k}$/i", $field))
|
||||
{
|
||||
if (is_array($v))
|
||||
{
|
||||
if (in_array($datatype, $v['type']))
|
||||
{
|
||||
$formatter = $v['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$formatter = $v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($extend)
|
||||
$html .= ", operate:false";
|
||||
if ($formatter && !$extend)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,78 @@ class Ajax extends Backend
|
|||
$this->data = ['searchlist' => $searchlist];
|
||||
}
|
||||
|
||||
/**
|
||||
* SelectPage通用下拉列表搜索
|
||||
*/
|
||||
public function selectpage()
|
||||
{
|
||||
//搜索关键词,客户端输入以空格分开,这里接收为数组
|
||||
$word = $this->request->request("q_word/a");
|
||||
//当前页
|
||||
$page = $this->request->request("pageNumber");
|
||||
//分页大小
|
||||
$pagesize = $this->request->request("pageSize");
|
||||
//搜索条件
|
||||
$andor = $this->request->request("and_or");
|
||||
//排序方式
|
||||
$orderby = $this->request->request("order_by/a");
|
||||
//表名
|
||||
$table = $this->request->request("db_table");
|
||||
//显示的字段
|
||||
$field = $this->request->request("field");
|
||||
//主键
|
||||
$primarykey = $this->request->request("pkey_name");
|
||||
//主键值
|
||||
$primaryvalue = $this->request->request("pkey_value");
|
||||
//搜索字段
|
||||
$searchfield = $this->request->request("search_field/a");
|
||||
//自定义搜索条件
|
||||
$custom = $this->request->request("custom/a");
|
||||
$order = [];
|
||||
foreach ($orderby as $k => $v)
|
||||
{
|
||||
$order[$v[0]] = $v[1];
|
||||
}
|
||||
$field = $field ? $field : 'name';
|
||||
|
||||
//如果不使用ajax/selectpage这个页面提供结果,则是自己的控制器单独写搜索条件,$where按自己的需求写即可
|
||||
//这里只是能用考虑,所以搜索条件写得比较复杂
|
||||
//如果有primaryvalue,说明当前是初始化传值
|
||||
if ($primaryvalue)
|
||||
{
|
||||
$where = [$primarykey => ['in', $primaryvalue]];
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = function($query) use($word, $andor, $field, $searchfield, $custom) {
|
||||
$where = $andor == "OR" ? "whereOr" : "where";
|
||||
foreach ($word as $k => $v)
|
||||
{
|
||||
foreach ($searchfield as $m => $n)
|
||||
{
|
||||
$query->{$where}($n, "like", "%{$v}%");
|
||||
}
|
||||
}
|
||||
if ($custom && is_array($custom))
|
||||
{
|
||||
foreach ($custom as $k => $v)
|
||||
{
|
||||
$query->where($k, '=', $v);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
$list = [];
|
||||
$total = Db::name($table)->where($where)->count();
|
||||
if ($total > 0)
|
||||
{
|
||||
$list = Db::name($table)->where($where)->order($order)->page($page, $pagesize)->field("{$primarykey},{$field}")->select();
|
||||
}
|
||||
|
||||
//这里一定要返回有list这个字段,total是可选的,如果total<=list的数量,则会隐藏分页按钮
|
||||
return json(['list' => $list, 'total' => $total]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载语言包
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class Relationmodel extends Backend
|
|||
public function index()
|
||||
{
|
||||
$this->relationSearch = true;
|
||||
$this->searchFields = "admin.username,id";
|
||||
if ($this->request->isAjax())
|
||||
{
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="form-group">
|
||||
<label for="c-category_id" class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input id="c-category_id" class="form-control typeahead" name="row[category_id]" type="text" value="0" data-rule="required">
|
||||
<input id="c-category_id" class="form-control selectpage" data-db-table="category" data-params='{"custom[type]":"page"}' name="row[category_id]" type="text" value="" data-rule="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="form-group">
|
||||
<label for="c-category_id" class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input id="c-category_id" class="form-control typeahead" name="row[category_id]" type="text" value="{$row.category_id}" data-rule="required">
|
||||
<input id="c-category_id" class="form-control selectpage" data-db-table="category" data-params='{"custom[type]":"page"}' name="row[category_id]" type="text" value="{$row.category_id}" data-rule="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="form-group">
|
||||
<label for="c-user_id" class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[user_id]" value="0" id="c-user_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[user_id]" value="0" id="c-user_id" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="form-group">
|
||||
<label for="c-user_id" class="control-label col-xs-12 col-sm-2">{:__('User_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[user_id]" value="{$row.user_id}" id="c-user_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[user_id]" value="{$row.user_id}" id="c-user_id" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -2,25 +2,25 @@
|
|||
<div class="form-group">
|
||||
<label for="c-partner_id" class="control-label col-xs-12 col-sm-2">{:__('Partner_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[partner_id]" value="" id="c-partner_id" class="form-control typeahead "required />
|
||||
<input type="text" name="row[partner_id]" value="" id="c-partner_id" class="form-control "required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-role_id" class="control-label col-xs-12 col-sm-2">{:__('Role_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[role_id]" value="0" id="c-role_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[role_id]" value="0" id="c-role_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-area_id" class="control-label col-xs-12 col-sm-2">{:__('Area_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[area_id]" value="0" id="c-area_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[area_id]" value="0" id="c-area_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-editor_id" class="control-label col-xs-12 col-sm-2">{:__('Editor_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[editor_id]" value="0" id="c-editor_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[editor_id]" value="0" id="c-editor_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -3,25 +3,25 @@
|
|||
<div class="form-group">
|
||||
<label for="c-partner_id" class="control-label col-xs-12 col-sm-2">{:__('Partner_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[partner_id]" value="{$row.partner_id}" id="c-partner_id" class="form-control typeahead "required />
|
||||
<input type="text" name="row[partner_id]" value="{$row.partner_id}" id="c-partner_id" class="form-control "required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-role_id" class="control-label col-xs-12 col-sm-2">{:__('Role_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[role_id]" value="{$row.role_id}" id="c-role_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[role_id]" value="{$row.role_id}" id="c-role_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-area_id" class="control-label col-xs-12 col-sm-2">{:__('Area_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[area_id]" value="{$row.area_id}" id="c-area_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[area_id]" value="{$row.area_id}" id="c-area_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="c-editor_id" class="control-label col-xs-12 col-sm-2">{:__('Editor_id')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<input type="text" name="row[editor_id]" value="{$row.editor_id}" id="c-editor_id" class="form-control typeahead " />
|
||||
<input type="text" name="row[editor_id]" value="{$row.editor_id}" id="c-editor_id" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ class Backend extends Controller
|
|||
$searchlist = [];
|
||||
foreach ($searcharr as $k => $v)
|
||||
{
|
||||
$searchlist[] = "{$modelName}`{$v}` LIKE '%{$search}%'";
|
||||
$searchlist[] = (stripos($v, ".") !== false ? $v : "{$modelName}`{$v}`") . " LIKE '%{$search}%'";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $searchlist) . ")";
|
||||
}
|
||||
|
|
|
|||
10
bower.json
10
bower.json
|
|
@ -30,16 +30,14 @@
|
|||
"jquery-slimscroll": "slimscroll#^1.3.8",
|
||||
"jquery.cookie": "^1.4.1",
|
||||
"Sortable": "^1.5.0",
|
||||
"typeahead.js": "^0.11.1",
|
||||
"bootstrap-tagsinput": "^0.8.0",
|
||||
"nice-validator": "^1.0.10",
|
||||
"art-template": "^3.0.1",
|
||||
"ajax-bootstrap-select": "^1.3.8"
|
||||
"art-template": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dragsort": "https://github.com/karsonzhang/dragsort.git",
|
||||
"jquery-addtabs": "https://github.com/karsonzhang/jquery-addtabs.git",
|
||||
"jquery-cxselect": "https://github.com/karsonzhang/cxSelect.git#",
|
||||
"jqcron": "https://github.com/karsonzhang/jqcron.git#"
|
||||
"jquery-cxselect": "https://github.com/karsonzhang/cxSelect.git",
|
||||
"jqcron": "https://github.com/karsonzhang/jqcron.git",
|
||||
"selectpage": "https://github.com/karsonzhang/selectpage.git"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
@import url("../libs/bootstrap-table/dist/bootstrap-table.min.css");
|
||||
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
|
||||
@import url("../libs/nice-validator/dist/jquery.validator.css");
|
||||
@import url("../libs/selectpage/selectpage.css");
|
||||
body {
|
||||
background: #f1f4f6;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -6,7 +6,7 @@ require.config({
|
|||
main: 'moment'
|
||||
}],
|
||||
//在打包压缩时将会把include中的模块合并到主文件中
|
||||
include: ['css', 'layer', 'toastr', 'backend', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs'],
|
||||
include: ['css', 'layer', 'toastr', 'backend', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage'],
|
||||
paths: {
|
||||
'lang': "empty:",
|
||||
'form': 'require-form',
|
||||
|
|
@ -24,18 +24,13 @@ require.config({
|
|||
'jquery': '../libs/jquery/dist/jquery.min',
|
||||
'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
|
||||
'bootstrap-validator': '../libs/bootstrap-validator/dist/validator.min',
|
||||
'bootstrap-typeahead': '../libs/bootstrap3-typeahead/bootstrap3-typeahead.min',
|
||||
'bootstrap-tagsinput': '../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.min',
|
||||
'bootstrap-dialog': '../libs/bootstrap3-dialog/dist/js/bootstrap-dialog.min',
|
||||
'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
|
||||
'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
|
||||
'bootstrap-select-ajax': '../libs/ajax-bootstrap-select/dist/js/ajax-bootstrap-select.min',
|
||||
'bootstrap-table': '../libs/bootstrap-table/dist/bootstrap-table.min',
|
||||
'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
|
||||
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
|
||||
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
|
||||
'typeahead': '../libs/typeahead.js/dist/typeahead.jquery.min',
|
||||
'bloodhound': '../libs/typeahead.js/dist/bloodhound.min',
|
||||
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
|
||||
'dropzone': '../libs/dropzone/dist/min/dropzone-amd-module.min',
|
||||
'less': '../libs/less/dist/less.min',
|
||||
|
|
@ -54,6 +49,7 @@ require.config({
|
|||
'cookie': '../libs/jquery.cookie/jquery.cookie',
|
||||
'cxselect': '../libs/jquery-cxselect/js/jquery.cxselect',
|
||||
'template': '../libs/art-template/dist/template-native',
|
||||
'selectpage': '../libs/selectpage/selectpage',
|
||||
},
|
||||
// shim依赖配置
|
||||
shim: {
|
||||
|
|
@ -97,12 +93,6 @@ require.config({
|
|||
deps: ['bootstrap', 'slimscroll'],
|
||||
exports: '$.AdminLTE'
|
||||
},
|
||||
'typeahead': {
|
||||
deps: ['jquery'],
|
||||
init: function ($) {
|
||||
return require.s.contexts._.registry['typeahead.js'].factory($);
|
||||
}
|
||||
},
|
||||
'crontab': ['../libs/jqcron/src/jqCron', 'css!../libs/jqcron/src/jqCron.css'],
|
||||
'bootstrap-checkbox': ['jquery'],
|
||||
'bootstrap-radio': ['jquery'],
|
||||
|
|
@ -112,12 +102,6 @@ require.config({
|
|||
'moment/locale/zh-cn',
|
||||
// 'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
|
||||
],
|
||||
'bootstrap-tagsinput': [
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput-typeahead.css',
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.css',
|
||||
'jquery',
|
||||
'typeahead'
|
||||
],
|
||||
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
|
||||
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
|
||||
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
|
||||
|
|
@ -129,6 +113,7 @@ require.config({
|
|||
// 'layer': ['css!../libs/layer/build/skin/default/layer.css'],
|
||||
// 'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
|
||||
'validator-lang': ['validator-core'],
|
||||
// 'selectpage': ['css!../libs/selectpage/selectpage.css'],
|
||||
},
|
||||
baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
|
||||
map: {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -105,43 +105,16 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
|
|||
|
||||
//绑定select元素事件
|
||||
if ($(".selectpicker", form).size() > 0) {
|
||||
require(['bootstrap-select', 'bootstrap-select-ajax'], function () {
|
||||
var selectlist = $('.selectpicker', form).selectpicker();
|
||||
$.each(selectlist, function () {
|
||||
var that = this;
|
||||
if ($(this).data("live-search")) {
|
||||
$(this).ajaxSelectPicker({
|
||||
ajax: {
|
||||
url: 'ajax/selectpicker',
|
||||
beforeSend: function (xhr, setting) {
|
||||
setting.url = Backend.api.fixurl(setting.url);
|
||||
},
|
||||
data: function () {
|
||||
var params = {
|
||||
search: '{{{q}}}',
|
||||
field: $(that).attr("name")
|
||||
};
|
||||
return params;
|
||||
},
|
||||
dataType: 'json'
|
||||
},
|
||||
locale: {
|
||||
emptyTitle: 'Search...'
|
||||
},
|
||||
preprocessData: function (ret) {
|
||||
var list = [];
|
||||
if (ret.hasOwnProperty('data') && ret.data) {
|
||||
var len = ret.data.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var curr = ret.data[i];
|
||||
list.push(curr);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
},
|
||||
preserveSelected: true
|
||||
require(['bootstrap-select'], function () {
|
||||
$('.selectpicker', form).selectpicker();
|
||||
});
|
||||
}
|
||||
|
||||
//绑定selectpage元素事件
|
||||
if ($(".selectpage", form).size() > 0) {
|
||||
require(['selectpage'], function () {
|
||||
$('.selectpage', form).selectPage({
|
||||
source: 'ajax/selectpage',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -156,74 +129,6 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func
|
|||
});
|
||||
}
|
||||
|
||||
if ($(".typeahead").size() > 0 || $(".tagsinput").size() > 0) {
|
||||
require(['bloodhound'], function () {
|
||||
var remotesource = function (input) {
|
||||
var url = $(input).data("url") ? $(input).data("url") : "ajax/typeahead";
|
||||
return new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: {
|
||||
url: url + '?search=%QUERY&field=' + $(input).attr("name"),
|
||||
wildcard: '%QUERY',
|
||||
transform: function (ret) {
|
||||
return ret.data.searchlist;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//绑定typeahead事件
|
||||
if ($(".typeahead", form).size() > 0) {
|
||||
require(['typeahead'], function () {
|
||||
$(".typeahead", form).each(function () {
|
||||
$(this).typeahead({
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 0
|
||||
}, {
|
||||
name: 'typeahead',
|
||||
limit: 20,
|
||||
displayKey: 'id',
|
||||
source: remotesource(this),
|
||||
templates: {
|
||||
empty: '<li class="notfound">' + __('No matches found') + '</li>',
|
||||
suggestion: function (item) {
|
||||
return '<li>' + item.name + '</li>';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//绑定tagsinput事件
|
||||
if ($(".tagsinput", form).size() > 0) {
|
||||
require(['bootstrap-tagsinput'], function () {
|
||||
$('.tagsinput', form).each(function () {
|
||||
$(this).tagsinput({
|
||||
freeInput: false,
|
||||
itemValue: 'id',
|
||||
itemText: 'name',
|
||||
typeaheadjs: {
|
||||
name: 'tagsinput',
|
||||
limit: 20,
|
||||
displayKey: 'name',
|
||||
source: remotesource(this),
|
||||
templates: {
|
||||
empty: '<li class="notfound">' + __('No matches found') + '</li>',
|
||||
suggestion: function (item) {
|
||||
return '<li>' + item.name + '</li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//绑定日期时间元素事件
|
||||
if ($(".datetimepicker", form).size() > 0) {
|
||||
require(['bootstrap-datetimepicker'], function () {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ require.config({
|
|||
'jquery': '../libs/jquery/dist/jquery.min',
|
||||
'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
|
||||
'bootstrap-validator': '../libs/bootstrap-validator/dist/validator.min',
|
||||
'bootstrap-typeahead': '../libs/bootstrap3-typeahead/bootstrap3-typeahead.min',
|
||||
'bootstrap-tagsinput': '../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.min',
|
||||
'bootstrap-dialog': '../libs/bootstrap3-dialog/dist/js/bootstrap-dialog.min',
|
||||
'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
|
||||
'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
|
||||
|
|
@ -32,8 +30,6 @@ require.config({
|
|||
'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
|
||||
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
|
||||
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
|
||||
'typeahead': '../libs/typeahead.js/dist/typeahead.jquery.min',
|
||||
'bloodhound': '../libs/typeahead.js/dist/bloodhound.min',
|
||||
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
|
||||
'dropzone': '../libs/dropzone/dist/min/dropzone-amd-module.min',
|
||||
'less': '../libs/less/dist/less.min',
|
||||
|
|
@ -90,12 +86,6 @@ require.config({
|
|||
deps: ['bootstrap', 'slimscroll'],
|
||||
exports: '$.AdminLTE'
|
||||
},
|
||||
'typeahead': {
|
||||
deps: ['jquery'],
|
||||
init: function ($) {
|
||||
return require.s.contexts._.registry['typeahead.js'].factory($);
|
||||
}
|
||||
},
|
||||
'crontab': ['../libs/jqcron/src/jqCron', 'css!../libs/jqcron/src/jqCron.css'],
|
||||
'bootstrap-checkbox': ['jquery'],
|
||||
'bootstrap-radio': ['jquery'],
|
||||
|
|
@ -105,12 +95,6 @@ require.config({
|
|||
'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
|
||||
'moment/locale/zh-cn',
|
||||
],
|
||||
'bootstrap-tagsinput': [
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput-typeahead.css',
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.css',
|
||||
'jquery',
|
||||
'typeahead'
|
||||
],
|
||||
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
|
||||
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
|
||||
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ require.config({
|
|||
'jquery': '../libs/jquery/dist/jquery.min',
|
||||
'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
|
||||
'bootstrap-validator': '../libs/bootstrap-validator/dist/validator.min',
|
||||
'bootstrap-typeahead': '../libs/bootstrap3-typeahead/bootstrap3-typeahead.min',
|
||||
'bootstrap-tagsinput': '../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.min',
|
||||
'bootstrap-dialog': '../libs/bootstrap3-dialog/dist/js/bootstrap-dialog.min',
|
||||
'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
|
||||
'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
|
||||
|
|
@ -46,8 +44,6 @@ require.config({
|
|||
'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
|
||||
'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
|
||||
'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
|
||||
'typeahead': '../libs/typeahead.js/dist/typeahead.jquery.min',
|
||||
'bloodhound': '../libs/typeahead.js/dist/bloodhound.min',
|
||||
'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
|
||||
'dropzone': '../libs/dropzone/dist/min/dropzone-amd-module.min',
|
||||
'less': '../libs/less/dist/less.min',
|
||||
|
|
@ -104,12 +100,6 @@ require.config({
|
|||
deps: ['bootstrap', 'slimscroll'],
|
||||
exports: '$.AdminLTE'
|
||||
},
|
||||
'typeahead': {
|
||||
deps: ['jquery'],
|
||||
init: function ($) {
|
||||
return require.s.contexts._.registry['typeahead.js'].factory($);
|
||||
}
|
||||
},
|
||||
'crontab': ['../libs/jqcron/src/jqCron', 'css!../libs/jqcron/src/jqCron.css'],
|
||||
'bootstrap-checkbox': ['jquery'],
|
||||
'bootstrap-radio': ['jquery'],
|
||||
|
|
@ -119,12 +109,6 @@ require.config({
|
|||
'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
|
||||
'moment/locale/zh-cn',
|
||||
],
|
||||
'bootstrap-tagsinput': [
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput-typeahead.css',
|
||||
'css!../libs/bootstrap-tagsinput/dist/bootstrap-tagsinput.css',
|
||||
'jquery',
|
||||
'typeahead'
|
||||
],
|
||||
'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css', ],
|
||||
'summernote': ['../libs/summernote/dist/summernote.min', 'css!../libs/summernote/dist/summernote.css'],
|
||||
// 'toastr': ['css!../libs/toastr/toastr.min.css'],
|
||||
|
|
|
|||
|
|
@ -271,14 +271,16 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table',
|
|||
//渲染fontawesome图标
|
||||
return '<i class="' + value + '"></i> ' + value;
|
||||
},
|
||||
image: function (value, row, index) {
|
||||
return '<img class="img-rounded img-sm" src="' + Backend.api.cdnurl(value) + '" />';
|
||||
image: function (value, row, index, custom) {
|
||||
var classname = typeof custom !== 'undefined' ? custom : 'img-rounded img-sm';
|
||||
return '<img class="' + classname + '" src="' + Backend.api.cdnurl(value) + '" />';
|
||||
},
|
||||
images: function (value, row, index) {
|
||||
images: function (value, row, index, custom) {
|
||||
var classname = typeof custom !== 'undefined' ? custom : 'img-rounded img-sm';
|
||||
var arr = value.split(',');
|
||||
var html = [];
|
||||
$.each(arr, function (i, value) {
|
||||
html.push('<img class="img-rounded img-sm" src="' + Backend.api.cdnurl(value) + '" />');
|
||||
html.push('<img class="' + classname + '" src="' + Backend.api.cdnurl(value) + '" />');
|
||||
});
|
||||
return html.join(' ');
|
||||
},
|
||||
|
|
@ -343,7 +345,6 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table',
|
|||
var html = [];
|
||||
if (showweigh)
|
||||
html.push('<a href="javascript:;" class="btn btn-primary btn-dragsort btn-xs"><i class="fa fa-arrows"></i></a>');
|
||||
|
||||
if (showedit)
|
||||
html.push('<a href="javascript:;" class="btn btn-success btn-editone btn-xs"><i class="fa fa-pencil"></i></a>');
|
||||
if (showdel)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
@import url("../libs/bootstrap-table/dist/bootstrap-table.min.css");
|
||||
@import url("../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css");
|
||||
@import url("../libs/nice-validator/dist/jquery.validator.css");
|
||||
@import url("../libs/selectpage/selectpage.css");
|
||||
|
||||
.clearfix() {
|
||||
&:before,
|
||||
|
|
|
|||
Loading…
Reference in New Issue