重构联查功能

尝试把列表构建改成由前端渲染
This commit is contained in:
2021-03-12 07:56:51 +08:00
parent 8ad68e938e
commit d795809fb3
19 changed files with 515 additions and 196 deletions
@@ -43,6 +43,16 @@ class ArticleController extends DefaultController
'display' => $this->access['edit'],
]];
$header['buttons'] = [
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
];
$header['cols'] = $cols;
$header['tabs'] = Article::$tabs;
$header['bys'] = Article::$bys;
$header['js'] = Grid::js($header);
$search = $header['search_form'];
$query = $search['query'];
@@ -64,13 +74,14 @@ class ArticleController extends DefaultController
$model->permission('receive_id', null, false, true, false, 'created_id');
}
// 查询是否已经阅读
// 是否已经阅读
$reader = function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
};
if ($query['tab'] == 'done') {
$model->whereExists($reader);
}
@@ -81,27 +92,11 @@ class ArticleController extends DefaultController
$model->select($header['select']);
$rows = $model->paginate($query['limit'])->appends($query);
$header['cols'] = $cols;
$header['tabs'] = Article::$tabs;
$header['bys'] = Article::$bys;
$header['js'] = Grid::js($header);
$items = Grid::dataFilters($rows, $header, function($item) {
return Grid::dataFilters($rows, $header, function($item) {
return $item;
});
return $items;
}
$header['buttons'] = [
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
];
$header['cols'] = $cols;
$header['tabs'] = Article::$tabs;
$header['bys'] = Article::$bys;
$header['js'] = Grid::js($header);
return $this->display([
'header' => $header,
]);
@@ -30,7 +30,7 @@ class WidgetController extends DefaultController
};
$model->whereNotExists($reader);
$rows = $model->get(['id', 'title', 'created_at']);
$rows = $model->get(['id', 'name', 'created_at']);
$json['total'] = sizeof($rows);
$json['data'] = $rows;
+54 -47
View File
@@ -1,59 +1,66 @@
{{$header["js"]}}
<div class="panel no-border" id="{{$header['master_table']}}-controller">
@include('headers')
<div class='list-jqgrid'>
<div id="{{$header['master_table']}}-grid" style="width:100%;" class="ag-theme-balham"></div>
<div id="{{$header['master_table']}}-controller">
<div class="panel no-border">
@include('headers')
<div class='list-jqgrid'>
<div id="{{$header['master_table']}}-grid" style="width:100%;" class="ag-theme-balham"></div>
</div>
</div>
</div>
{{$header["js"]}}
<script>
(function ($) {
var table = '{{$header["master_table"]}}';
var config = gdoo.grids[table];
var action = config.action;
var search = config.search;
action.dialogType = 'layer';
(function ($) {
var header = {{json_encode($header, JSON_UNESCAPED_UNICODE)}};
// 自定义搜索方法
search.searchInit = function (e) {
var self = this;
var table = '{{$header["master_table"]}}';
var config = gdoo.grids[table];
var action = config.action;
var search = config.search;
action.dialogType = 'layer';
// 自定义搜索方法
search.searchInit = function (e) {
var self = this;
}
var options = new agGridOptions();
var gridDiv = document.querySelector("#{{$header['master_table']}}-grid");
gridDiv.style.height = getPanelHeight(48);
options.remoteDataUrl = '{{url()}}';
options.remoteParams = search.advanced.query;
options.columnDefs = config.cols;
options.onRowDoubleClicked = function (params) {
if (params.node.rowPinned) {
return;
}
var options = new agGridOptions();
var gridDiv = document.querySelector("#{{$header['master_table']}}-grid");
gridDiv.style.height = getPanelHeight(48);
if (params.data == undefined) {
return;
}
if (params.data.master_id > 0) {
action.show(params.data);
}
};
options.remoteDataUrl = '{{url()}}';
options.remoteParams = search.advanced.query;
options.columnDefs = config.cols;
options.onRowDoubleClicked = function (params) {
if (params.node.rowPinned) {
return;
}
if (params.data == undefined) {
return;
}
if (params.data.master_id > 0) {
action.show(params.data);
}
};
new agGrid.Grid(gridDiv, options);
new agGrid.Grid(gridDiv, options);
// 读取数据
options.remoteData({page: 1});
// 读取数据
options.remoteData({page: 1});
// 绑定自定义事件
var $gridDiv = $(gridDiv);
$gridDiv.on('click', '[data-toggle="event"]', function () {
var data = $(this).data();
if (data.master_id > 0) {
action[data.action](data);
}
});
config.grid = options;
})(jQuery);
// 绑定自定义事件
var $gridDiv = $(gridDiv);
$gridDiv.on('click', '[data-toggle="event"]', function () {
var data = $(this).data();
if (data.master_id > 0) {
action[data.action](data);
}
});
config.grid = options;
})(jQuery);
</script>
@include('footers')
@@ -0,0 +1,105 @@
<style>
.vue-list-page .search-inline-form .form-group {
margin-left: 4px;
}
.vue-list-page .btn-group {
margin-left: 4px;
}
</style>
<div class="vue-list-page" id="{{$header['master_table']}}-controller">
<div class="panel no-border">
@include('headers3')
<div class='list-jqgrid'>
<div id="{{$header['master_table']}}-grid" style="width:100%;" class="ag-theme-balham"></div>
</div>
</div>
</div>
{{$header["js"]}}
<script>
(function ($) {
var header = {{json_encode($header, JSON_UNESCAPED_UNICODE)}};
var table = '{{$header["master_table"]}}';
var config = gdoo.grids[table];
var action = config.action;
var search = config.search;
const vueData = {
data() {
return {
header: {},
tab_active: '',
}
},mounted() {
abc(this);
},
methods: {
url(url, query) {
var me = this;
let params = Vue.toRaw(me.header.search_form.params);
for (const key in query) {
params[key] = query[key];
}
return app.url(url, params);
}
}
}
Vue.createApp(vueData).mount("#{{$header['master_table']}}-controller");
function abc(vue) {
action.dialogType = 'layer';
// 自定义搜索方法
search.searchInit = function (e) {
var self = this;
}
var options = new agGridOptions();
var gridDiv = document.querySelector("#{{$header['master_table']}}-grid");
gridDiv.style.height = getPanelHeight(48);
options.remoteDataUrl = '{{url()}}';
options.remoteParams = search.advanced.query;
options.columnDefs = config.cols;
options.onRowDoubleClicked = function (params) {
if (params.node.rowPinned) {
return;
}
if (params.data == undefined) {
return;
}
if (params.data.master_id > 0) {
action.show(params.data);
}
};
new agGrid.Grid(gridDiv, options);
// 读取数据
options.remoteData({page: 1});
options.remoteSuccessed = function(res) {
vue.header = res.header;
vue.tab_active = vue.header.search_form.params['tab'] ? vue.header.search_form.params['tab'] : vue.header.tabs.items[0].value;
};
// 绑定自定义事件
var $gridDiv = $(gridDiv);
$gridDiv.on('click', '[data-toggle="event"]', function () {
var data = $(this).data();
if (data.master_id > 0) {
action[data.action](data);
}
});
config.grid = options;
}
})(jQuery);
</script>
@include('footers')
+13 -8
View File
@@ -53,7 +53,7 @@ class Form
$_table = $data_link.'_'.$data_type;
if ($field['type']) {
$join[$_table] = [$data_type.' as '.$_table, $_table.'.id', '=', $table.'.'.$data_link];
$join[$_table] = [$data_type.' as '.$_table, $_table.'.id', '=', $table.'.'.$data_link, $table, 1];
}
$links[$data_link][$data_link] = 'id';
@@ -76,7 +76,7 @@ class Form
$_table = $field['field'].'_'.$_t1;
}
$join[$_table] = [$_t1.' as '.$_table, $_table.'.id', '=', $data_link.'_'.$data_type.'.'.$_v2];
$join[$_table] = [$_t1.' as '.$_table, $_table.'.id', '=', $data_link.'_'.$data_type.'.'.$_v2, $data_link.'_'.$data_type, 1];
$index = $_table.'.'.$_t2;
if ($field['field'] == $data_link) {
@@ -141,6 +141,7 @@ class Form
foreach($fields as $field) {
static::fieldRelated($table, $field, $join, $select, $links);
}
$join = Grid::sortJoin($join);
$q = DB::table($table)
->where($table.'.id', (int)$options['id']);
@@ -1986,13 +1987,13 @@ class Form
return hash_equals($sessionToken, $token);
}
public static function dataFilter($table, $fields, $permissions, $master, $values)
public static function dataFilter($table, $fields, $permissions, $master, $values, &$dataFiles)
{
$permission = $permissions[$table];
foreach ($values as $key => $value) {
foreach ($fields as $field) {
$field = $fields[$key];
$key = $field['field'];
$setting = $field['setting'];
$value = $values[$key];
$row = $permission[$key];
@@ -2042,7 +2043,11 @@ class Form
}
break;
case 'checkbox':
$value = intval($value);
if (is_array($value)) {
$value = join(",", (array)$value);
} else {
$value = intval($value);
}
break;
}
$values[$key] = $value;
@@ -2103,7 +2108,7 @@ class Form
// 格式化子表数据格式
foreach ($rows as $i => $row) {
$rows[$i] = static::dataFilter($table, $fields, $permissions, $master, $row);
$rows[$i] = static::dataFilter($table, $fields, $permissions, $master, $row, $dataFiles);
}
$datas[] = [
@@ -2115,7 +2120,7 @@ class Form
];
} else {
// 处理主表的字段格式
$gets[$t] = static::dataFilter($table, $fields, $permissions, $master, $gets[$t]);
$gets[$t] = static::dataFilter($table, $fields, $permissions, $master, $gets[$t], $dataFiles);
}
}
+36 -10
View File
@@ -44,6 +44,7 @@ class Grid
}
}
}
if ($item['province_id']) {
$region_ids[$item['province_id']] = $item['province_id'];
$region_ids[$item['city_id']] = $item['city_id'];
@@ -96,6 +97,15 @@ class Grid
}
}
$_header = $header;
unset($_header['columns']);
unset($_header['dialogs']);
unset($_header['join']);
unset($_header['js']);
unset($_header['raw_select']);
unset($_header['search']);
unset($_header['select']);
$header['runs'] = $runs;
$header['dialogs'] = $dialogs;
$header['regions'] = $regions;
@@ -111,7 +121,7 @@ class Grid
} else {
$ret = collect(['data' => $rows]);
}
$ret['header'] = $header;
$ret['header'] = $_header;
return $ret;
}
@@ -290,6 +300,25 @@ class Grid
return $rows;
}
// 重新排序join
public static function sortJoin($joins)
{
foreach ($joins as $k => $join) {
static::recursiveJoin($joins, $k);
}
array_multisort(array_column($joins, 5), SORT_ASC, $joins);
return $joins;
}
public static function recursiveJoin(&$joins, $parent_id = 0) {
foreach($joins as $k => &$join) {
if ($join[4] == $parent_id) {
$join[5] = $joins[$parent_id][5] + 1;
static::recursiveJoin($joins, $k);
}
}
}
public static function fieldRelated($table, $row, &$join, &$select, &$index, &$column, &$search, $setting)
{
if ($row['data_type']) {
@@ -299,7 +328,7 @@ class Grid
$_table = $data_link.'_'.$data_type;
if ($row['type']) {
$join[$_table] = [$data_type.' as '.$_table, $_table.'.id', '=', $table.'.'.$data_link];
$join[$_table] = [$data_type.' as '.$_table, $_table.'.id', '=', $table.'.'.$data_link, $table, 1];
}
$field_count = mb_substr_count($data_field, ':');
@@ -314,8 +343,8 @@ class Grid
} else {
$_table = $row['field'].'_'.$_t1;
}
$join[$_table] = [$_t1.' as '.$_table, $_table.'.id', '=', $data_link.'_'.$data_type.'.'.$_v2];
$join[$_table] = [$_t1.' as '.$_table, $_table.'.id', '=', $data_link.'_'.$data_type.'.'.$_v2, $data_link.'_'.$data_type, 1];
$index = $_table.'.'.$_t2;
@@ -461,7 +490,7 @@ class Grid
if ($_model['parent_id'] > 0) {
$select[$_model['table'].'.id'] = [];
}
$join[] = [$_model['table'], $_model['table'].'.'.$_model['relation'], '=', $master['table'].'.id'];
$join[] = [$_model['table'], $_model['table'].'.'.$_model['relation'], '=', $master['table'].'.id', $master['table'], 0];
}
} else {
@@ -549,7 +578,7 @@ class Grid
}
static::fieldRelated($_table, $row, $join, $select, $index, $column, $_search, $setting);
if ($row['is_link']) {
if (isset($left_fields[$field])) {
continue;
}
@@ -842,11 +871,8 @@ class Grid
$res['select'] = $src_select;
$res['raw_select'] = $raw_select;
$res['join'] = static::sortJoin($join);
//print_r($join);
//print_r($select);
$res['join'] = $join;
$res['search'] = $search;
$res['search_form'] = $search_form;
+57 -43
View File
@@ -1243,7 +1243,6 @@ class FieldService
if ($field['is_print']) {
foreach ($select as $t) {
$attribute = $field['attribute'];
$n = $v = '';
list($n, $v) = explode('|', $t);
$v = is_null($v) ? trim($n) : trim($v);
@@ -1260,7 +1259,6 @@ class FieldService
$name = $attribute['name'];
foreach ($select as $i => $t) {
$n = $v = '';
list($n, $v) = explode('|', $t);
$v = is_null($v) ? trim($n) : trim($v);
@@ -1278,55 +1276,71 @@ class FieldService
public static function content_checkbox($field, $content = '', $row = [], $permission = [])
{
$field = static::content_field($field);
// 配置
$setting = $field['setting'];
$default = $setting['default'];
$content = is_null($content) ? $default : $content;
$str = [];
$checkeds = [];
$items = [];
$values = explode(",", $content);
$attribute = $field['attribute'];
$id = $attribute['id'];
$name = $attribute['name'];
$_select = explode("\n", $setting['content']);
if ($field['is_print']) {
foreach ($_select as $t) {
$n = $v = '';
list($n, $v) = explode('|', $t);
$v = is_null($v) ? trim($n) : trim($v);
if ($row[$v] == 1) {
$str[] = $n;
}
if ($v == $content) {
$str[] = $n;
}
}
return join(',', $str);
}
if ($field['type']) {
$checked = $content == 1 ? 'checked="checked"' : '';
if ($field['is_show']) {
$str[] = '<label class="i-checks i-checks-sm m-b-none" style="font-weight:normal;"><input type="checkbox" disabled="disabled" '.$checked.'><i></i>'.$field['name'].'</label>';
} else {
$str[] = '<label class="i-checks i-checks-sm m-t-xs m-b-none" style="font-weight:normal;"><input type="checkbox" id="'. $id .'" name="'. $name . '" value="1" '.$checked.'><i></i>'.$field['name'].'</label>';
}
if ($setting['type']) {
$items = DB::table($setting['type'])->where('status', 1)->orderBy('sort', 'asc')->get();
} else {
foreach ($_select as $t) {
$n = $v = '';
list($n, $v) = explode('|', $t);
$v = is_null($v) ? trim($n) : trim($v);
$checked = $row[$v] == 1 ? 'checked="checked"' : '';
if ($field['is_show']) {
$str[] = '<label class="i-checks i-checks-sm m-b-none" style="font-weight:normal;"><input type="checkbox" disabled="disabled" '.$checked.'><i></i>'.$n.'</label>';
} else {
$w = $permission[$v]['w'] == 1 ? '' : 'disabled="disabled"';
$disabled = $permission[$v]['w'] == 1 ? '' : 'i-checks-disabled';
$str[] = '<label class="i-checks '.$disabled.' i-checks-sm m-t-xs m-b-none" style="font-weight:normal;"><input type="checkbox" '.$w.' id="'. $field['table'] . '_'.$v.'" name="'. $field['table'] . '['.$v.']" value="1" '.$checked.'><i></i>'.$n.'</label>';
if (not_empty($setting['content'])) {
$selects = explode("\n", $setting['content']);
foreach ($selects as $select) {
$n = $v = '';
list($n, $v) = explode('|', $select);
$v = is_null($v) ? trim($n) : trim($v);
$items[] = ['id' => $v, 'name' => $n];
}
} else {
$items[] = ['id' => 1, 'name' => $field['name']];
}
}
return join('&nbsp;&nbsp;', $str);
// 打印模式直接返回选中的值名称
if ($field['is_print']) {
foreach ($items as $item) {
if ($field['type']) {
if (in_array($item['id'], $values)) {
$checkeds[] = $item['name'];
}
} else {
if ($row[$item['id']] == 1) {
$checkeds[] = $item['name'];
}
}
}
return join(',', $checkeds);
}
$str = [];
foreach ($items as $item) {
// 存在字段
if ($field['type']) {
$value = $v;
$checked = in_array($v, $values) ? 'checked="checked"' : '';
$name = $field['table'].'['.$field['field'].']['.$v.']';
$key = $field['field'];
} else {
$value = 1;
$checked = $row[$item['id']] == $value ? 'checked="checked"' : '';
$name = $field['table'].'['.$item['id'].']';
$key = $item['id'];
}
if ($field['is_show']) {
$str[] = '<label class="i-checks i-checks-sm m-r-xs m-b-none"><input type="checkbox" id="'. $field['table'].'_'.$item['id'].'" disabled="disabled" '.$checked.'><i></i>'.$item['name'].'</label>';
} else {
$w = $permission[$key]['w'] == 1 ? '' : 'disabled="disabled"';
$disabled = $permission[$key]['w'] == 1 ? '' : 'i-checks-disabled';
$str[] = '<label class="i-checks '.$disabled.' i-checks-sm m-t-xs m-r-xs m-b-none"><input type="checkbox" '.$w.' id="'. $field['table'].'_'.$item['id'].'" name="'.$name.'" value="'.$value.'" '.$checked.'><i></i>'.$item['name'].'</label>';
}
}
return join(' ', $str);
}
public static function content_image($field, $content = '')