作者 Karson

新增列表搜索autocomplete配置

优化关联搜索
优化附件列表缩略图显示
@@ -273,39 +273,41 @@ class Backend extends Controller @@ -273,39 +273,41 @@ class Backend extends Controller
273 $op = (array)json_decode($op, true); 273 $op = (array)json_decode($op, true);
274 $filter = $filter ? $filter : []; 274 $filter = $filter ? $filter : [];
275 $where = []; 275 $where = [];
  276 + $alias = [];
  277 + $bind = [];
276 $name = ''; 278 $name = '';
277 - $tableName = '';  
278 - if ($relationSearch) {  
279 - if (!empty($this->model)) {  
280 - $name = $this->model->getTable();  
281 - $tableName = $name . '.';  
282 - }  
283 - $sortArr = explode(',', $sort);  
284 - foreach ($sortArr as $index => & $item) {  
285 - $item = stripos($item, ".") === false ? $tableName . trim($item) : $item;  
286 - }  
287 - unset($item);  
288 - $sort = implode(',', $sortArr); 279 + $aliasName = '';
  280 + if (!empty($this->model)) {
  281 + $name = $this->model->getTable();
  282 + $alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
  283 + $aliasName = $alias[$name] . '.';
289 } 284 }
  285 + $sortArr = explode(',', $sort);
  286 + foreach ($sortArr as $index => & $item) {
  287 + $item = stripos($item, ".") === false ? $aliasName . trim($item) : $item;
  288 + }
  289 + unset($item);
  290 + $sort = implode(',', $sortArr);
290 $adminIds = $this->getDataLimitAdminIds(); 291 $adminIds = $this->getDataLimitAdminIds();
291 if (is_array($adminIds)) { 292 if (is_array($adminIds)) {
292 - $where[] = [$tableName . $this->dataLimitField, 'in', $adminIds]; 293 + $where[] = [$aliasName . $this->dataLimitField, 'in', $adminIds];
293 } 294 }
294 if ($search) { 295 if ($search) {
295 $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields); 296 $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
296 foreach ($searcharr as $k => &$v) { 297 foreach ($searcharr as $k => &$v) {
297 - $v = stripos($v, ".") === false ? $tableName . $v : $v; 298 + $v = stripos($v, ".") === false ? $aliasName . $v : $v;
298 } 299 }
299 unset($v); 300 unset($v);
300 $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"]; 301 $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
301 } 302 }
  303 + $index = 0;
302 foreach ($filter as $k => $v) { 304 foreach ($filter as $k => $v) {
303 if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) { 305 if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
304 continue; 306 continue;
305 } 307 }
306 $sym = isset($op[$k]) ? $op[$k] : '='; 308 $sym = isset($op[$k]) ? $op[$k] : '=';
307 if (stripos($k, ".") === false) { 309 if (stripos($k, ".") === false) {
308 - $k = $tableName . $k; 310 + $k = $aliasName . $k;
309 } 311 }
310 $v = !is_array($v) ? trim($v) : $v; 312 $v = !is_array($v) ? trim($v) : $v;
311 $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym); 313 $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
@@ -341,10 +343,11 @@ class Backend extends Controller @@ -341,10 +343,11 @@ class Backend extends Controller
341 case 'FINDINSET': 343 case 'FINDINSET':
342 case 'FIND_IN_SET': 344 case 'FIND_IN_SET':
343 $v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v)); 345 $v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
344 - foreach ($v as $index => $item) {  
345 - $item = str_replace([' ', ',', "'"], '', $item);  
346 - $item = addslashes(htmlentities(strip_tags($item)));  
347 - $where[] = "FIND_IN_SET('{$item}', `" . ($relationSearch ? str_replace('.', '`.`', $k) : $k) . "`)"; 346 + $findArr = array_values($v);
  347 + foreach ($findArr as $idx => $item) {
  348 + $bindName = "item_" . $index . "_" . $idx;
  349 + $bind[$bindName] = $item;
  350 + $where[] = "FIND_IN_SET(:{$bindName}, `" . str_replace('.', '`.`', $k) . "`)";
348 } 351 }
349 break; 352 break;
350 case 'IN': 353 case 'IN':
@@ -385,10 +388,10 @@ class Backend extends Controller @@ -385,10 +388,10 @@ class Backend extends Controller
385 $arr = $arr[0]; 388 $arr = $arr[0];
386 } 389 }
387 $tableArr = explode('.', $k); 390 $tableArr = explode('.', $k);
388 - if (count($tableArr) > 1 && $tableArr[0] != $name) { 391 + if (count($tableArr) > 1 && $tableArr[0] != $name && !in_array($tableArr[0], $alias)) {
389 //修复关联模型下时间无法搜索的BUG 392 //修复关联模型下时间无法搜索的BUG
390 $relation = Loader::parseName($tableArr[0], 1, false); 393 $relation = Loader::parseName($tableArr[0], 1, false);
391 - $this->model->alias([$this->model->$relation()->getTable() => $tableArr[0]]); 394 + $alias[$this->model->$relation()->getTable()] = $tableArr[0];
392 } 395 }
393 $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr]; 396 $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
394 break; 397 break;
@@ -401,8 +404,14 @@ class Backend extends Controller @@ -401,8 +404,14 @@ class Backend extends Controller
401 default: 404 default:
402 break; 405 break;
403 } 406 }
  407 + $index++;
404 } 408 }
405 - $where = function ($query) use ($where) { 409 +
  410 + $this->model->alias($alias);
  411 + $model = $this->model;
  412 + $where = function ($query) use ($where, $alias, $bind, &$model) {
  413 + $model->alias($alias);
  414 + $model->bind($bind);
406 foreach ($where as $k => $v) { 415 foreach ($where as $k => $v) {
407 if (is_array($v)) { 416 if (is_array($v)) {
408 call_user_func_array([$query, 'where'], $v); 417 call_user_func_array([$query, 'where'], $v);
@@ -411,7 +420,7 @@ class Backend extends Controller @@ -411,7 +420,7 @@ class Backend extends Controller
411 } 420 }
412 } 421 }
413 }; 422 };
414 - return [$where, $sort, $order, $offset, $limit, $page]; 423 + return [$where, $sort, $order, $offset, $limit, $page, $alias, $bind];
415 } 424 }
416 425
417 /** 426 /**
@@ -15,12 +15,31 @@ class Attachment extends Model @@ -15,12 +15,31 @@ class Attachment extends Model
15 // 定义字段类型 15 // 定义字段类型
16 protected $type = [ 16 protected $type = [
17 ]; 17 ];
  18 + protected $append = [
  19 + 'thumb_style'
  20 + ];
18 21
19 public function setUploadtimeAttr($value) 22 public function setUploadtimeAttr($value)
20 { 23 {
21 return is_numeric($value) ? $value : strtotime($value); 24 return is_numeric($value) ? $value : strtotime($value);
22 } 25 }
23 26
  27 + /**
  28 + * 获取云储存的缩略图样式字符
  29 + */
  30 + public function getThumbStyleAttr($value, $data)
  31 + {
  32 + if (!isset($data['storage']) || $data['storage'] == 'local') {
  33 + return '';
  34 + } else {
  35 + $config = get_addon_config($data['storage']);
  36 + if ($config && isset($config['thumbstyle'])) {
  37 + return $config['thumbstyle'];
  38 + }
  39 + }
  40 + return '';
  41 + }
  42 +
24 public static function getMimetypeList() 43 public static function getMimetypeList()
25 { 44 {
26 $data = [ 45 $data = [
@@ -162,8 +162,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin @@ -162,8 +162,7 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin
162 formatter: { 162 formatter: {
163 thumb: function (value, row, index) { 163 thumb: function (value, row, index) {
164 if (row.mimetype.indexOf("image") > -1) { 164 if (row.mimetype.indexOf("image") > -1) {
165 - var style = row.storage === 'upyun' ? '!/fwfh/120x90' : '';  
166 - return '<a href="' + row.fullurl + '" target="_blank"><img src="' + row.fullurl + style + '" alt="" style="max-height:90px;max-width:120px"></a>'; 165 + return '<a href="' + row.fullurl + '" target="_blank"><img src="' + row.fullurl + row.thumb_style + '" alt="" style="max-height:90px;max-width:120px"></a>';
167 } else { 166 } else {
168 return '<a href="' + row.fullurl + '" target="_blank"><img src="' + Fast.api.fixurl("ajax/icon") + "?suffix=" + row.imagetype + '" alt="" style="max-height:90px;max-width:120px"></a>'; 167 return '<a href="' + row.fullurl + '" target="_blank"><img src="' + Fast.api.fixurl("ajax/icon") + "?suffix=" + row.imagetype + '" alt="" style="max-height:90px;max-width:120px"></a>';
169 } 168 }
@@ -80,6 +80,7 @@ @@ -80,6 +80,7 @@
80 var extend = typeof vObjCol.extend === 'undefined' ? '' : vObjCol.extend; 80 var extend = typeof vObjCol.extend === 'undefined' ? '' : vObjCol.extend;
81 var style = typeof vObjCol.style === 'undefined' ? '' : sprintf('style="%s"', vObjCol.style); 81 var style = typeof vObjCol.style === 'undefined' ? '' : sprintf('style="%s"', vObjCol.style);
82 extend = typeof vObjCol.data !== 'undefined' && extend == '' ? vObjCol.data : extend; 82 extend = typeof vObjCol.data !== 'undefined' && extend == '' ? vObjCol.data : extend;
  83 + extend = typeof vObjCol.autocomplete !== 'undefined' ? extend + ' autocomplete="' + (vObjCol.autocomplete === false || vObjCol.autocomplete === 'off' ? 'off' : 'on') + '"' : extend;
83 if (vObjCol.searchList) { 84 if (vObjCol.searchList) {
84 if (typeof vObjCol.searchList === 'function') { 85 if (typeof vObjCol.searchList === 'function') {
85 htmlForm.push(vObjCol.searchList.call(this, vObjCol)); 86 htmlForm.push(vObjCol.searchList.call(this, vObjCol));