From d878aeee2ed50cb744197e1ae92b82f18e56fe10 Mon Sep 17 00:00:00 2001 From: Karson <karsonzhang@163.com> Date: Sun, 28 May 2017 23:01:09 +0800 Subject: [PATCH] 添加多图上传预览和选择 新增bootstrap-table的主键功能,可传入pk设定表的主键 修复管理员权限不刷新的BUG 修复提示未登录时,在登录后不跳转之前页面的BUG 修复在移动版部分按钮在视图的布局 修复头像不显示的BUG 修改UC默认关闭 修复plupload方法重复绑定事件的BUG 修复部分样式的显示错误 修复登录Token错误的BUG --- application/admin/command/Crud.php | 33 +++++++++++++++++++++++++++------ application/admin/command/Crud/stubs/javascript.stub | 1 + application/admin/controller/Index.php | 6 +++--- application/admin/controller/general/Attachment.php | 26 ++++++++++++++++++++++++++ application/admin/library/traits/Backend.php | 7 +++---- application/admin/view/common/header.html | 4 ++-- application/admin/view/general/attachment/select.html | 22 ++++++++++++++++++++++ application/admin/view/general/profile/index.html | 2 +- application/admin/view/page/add.html | 3 ++- application/admin/view/page/edit.html | 4 +++- application/common/controller/Backend.php | 7 +++++-- application/uc.php | 2 +- bower.json | 2 +- extend/fast/Auth.php | 8 ++++++-- public/assets/css/backend.css | 28 ++++++++++++++++++++++++++-- public/assets/js/backend/general/attachment.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public/assets/js/backend/index.js | 6 +++--- public/assets/js/require-form.js | 30 ++++++++++++++++++++++++++++++ public/assets/js/require-table.js | 23 ++++++++++++++--------- public/assets/js/require-upload.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- public/assets/less/backend.less | 31 +++++++++++++++++++++++++++++-- 21 files changed, 326 insertions(+), 49 deletions(-) create mode 100644 application/admin/view/general/attachment/select.html diff --git a/application/admin/command/Crud.php b/application/admin/command/Crud.php index 606c922..05da39f 100644 --- a/application/admin/command/Crud.php +++ b/application/admin/command/Crud.php @@ -31,7 +31,7 @@ class Crud extends Command { $adminPath = dirname(__DIR__) . DS; //表名 - $table = $input->getOption('table') ? : ''; + $table = $input->getOption('table') ?: ''; //自定义控制器 $controller = $input->getOption('controller'); //自定义模型 @@ -96,6 +96,7 @@ class Crud extends Command //从数据库中获取表字段信息 $columnList = Db::query("SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND table_name = ? ORDER BY ORDINAL_POSITION", [$dbname, $tableName]); + $fields = []; foreach ($columnList as $k => $v) { @@ -109,6 +110,20 @@ class Crud extends Command $field = 'id'; $order = 'id'; $priDefined = FALSE; + $prikey = ''; + foreach ($columnList as $k => $v) + { + if ($v['COLUMN_KEY'] == 'PRI') + { + $prikey = $v['COLUMN_NAME']; + break; + } + } + if (!$prikey) + { + throw new Exception('Primary key not found!'); + } + $order = $prikey; try { @@ -161,7 +176,7 @@ class Crud extends Command if ($v['DATA_TYPE'] == 'set') { $attrArr['multiple'] = ''; - $fieldName.="[]"; + $fieldName .= "[]"; } $attrStr = $this->getArrayString($attrArr); $itemArr = $this->getLangArray($itemArr, FALSE); @@ -209,7 +224,7 @@ class Crud extends Command } else if ($inputType == 'checkbox') { - $fieldName.="[]"; + $fieldName .= "[]"; $itemArr = $this->getLangArray($itemArr, FALSE); $itemString = $this->getArrayString($itemArr); $formAddElement = "{:build_checkboxs('{$fieldName}', [{$itemString}], '{$defaultValue}')}"; @@ -252,7 +267,7 @@ class Crud extends Command $step = array_intersect($cssClassArr, ['typeahead', 'tagsinput']) ? 0 : $step; $attrArr['class'] = implode(' ', $cssClassArr); - $isUpload = substr($field, -4) == 'file' || substr($field, -5) == 'image' || substr($field, -6) == 'avatar' ? TRUE : FALSE; + $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; //如果是步长则加上步长 if ($step) { @@ -327,6 +342,7 @@ class Crud extends Command 'modelName' => $modelName, 'tableComment' => $tableComment, 'iconName' => $iconName, + 'pk' => $prikey, 'order' => $order, 'table' => $table, 'tableName' => $tableName, @@ -531,11 +547,16 @@ EOD; */ protected function getImageUpload($field, $content) { - $filter = substr($field, -4) == 'avatar' || substr($field, -5) == 'image' ? 'data-mimetype="image/*"' : ""; + $filter = substr($field, -4) == 'avatar' || substr($field, -5) == 'image' || substr($field, -6) == 'images' ? ' data-mimetype="image/*"' : ""; + $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>' : ''; return <<<EOD <div class="form-inline"> {$content} - <span><button id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"{$filter}><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <span><button type="button" id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"{$filter}{$multiple}{$preview}><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <span><button type="button" id="fachoose-{$field}" class="btn btn-primary fachoose" data-input-id="c-{$field}"{$filter}{$multiple}><i class="fa fa-list"></i> {:__('Choose')}</button></span> + {$previewcontainer} </div> EOD; } diff --git a/application/admin/command/Crud/stubs/javascript.stub b/application/admin/command/Crud/stubs/javascript.stub index dde47a0..6b938cf 100644 --- a/application/admin/command/Crud/stubs/javascript.stub +++ b/application/admin/command/Crud/stubs/javascript.stub @@ -19,6 +19,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin // 初始化表格 table.bootstrapTable({ url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: '{%pk%}', sortName: '{%order%}', columns: [ [ diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index c009f88..6cd0a0a 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -70,18 +70,18 @@ class Index extends Backend $result = $validate->check($data); if (!$result) { - $this->error($validate->getError()); + $this->error($validate->getError(), $url, ['token' => $this->request->token()]); return; } $result = $this->auth->login($username, $password, $keeplogin ? 86400 : 0); if ($result === true) { - $this->success(__('Login successful'), $url); + $this->success(__('Login successful'), $url, ['url' => $url]); return; } else { - $this->error(__('Username or password is incorrect'), $url); + $this->error(__('Username or password is incorrect'), $url, ['token' => $this->request->token()]); } return; } diff --git a/application/admin/controller/general/Attachment.php b/application/admin/controller/general/Attachment.php index 4d99303..ec43292 100644 --- a/application/admin/controller/general/Attachment.php +++ b/application/admin/controller/general/Attachment.php @@ -46,6 +46,32 @@ class Attachment extends Backend } return $this->view->fetch(); } + + /** + * 选择附件 + */ + public function select() + { + if ($this->request->isAjax()) + { + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->where($where) + ->order($sort, $order) + ->count(); + + $list = $this->model + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch(); + } /** * 添加 diff --git a/application/admin/library/traits/Backend.php b/application/admin/library/traits/Backend.php index 51cd47c..301be41 100644 --- a/application/admin/library/traits/Backend.php +++ b/application/admin/library/traits/Backend.php @@ -2,7 +2,6 @@ namespace app\admin\library\traits; - trait Backend { @@ -61,7 +60,7 @@ trait Backend */ public function edit($ids = NULL) { - $row = $this->model->get(['id' => $ids]); + $row = $this->model->get($ids); if (!$row) $this->error(__('No Results were found')); if ($this->request->isPost()) @@ -93,7 +92,7 @@ trait Backend $this->code = -1; if ($ids) { - $count = $this->model->where('id', 'in', $ids)->delete(); + $count = $this->model->destroy($ids); if ($count) { $this->code = 1; @@ -118,7 +117,7 @@ trait Backend $values = array_intersect_key($values, array_flip(array('status'))); if ($values) { - $count = $this->model->where('id', 'in', $ids)->update($values); + $count = $this->model->where($this->model->getPk(), 'in', $ids)->update($values); if ($count) { $this->code = 1; diff --git a/application/admin/view/common/header.html b/application/admin/view/common/header.html index 369eb6a..eb3dee5 100644 --- a/application/admin/view/common/header.html +++ b/application/admin/view/common/header.html @@ -64,7 +64,7 @@ </a> </li> - <li> + <li class="hidden-xs"> <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-language"></i></a> <ul class="dropdown-menu"> <li class="{$config['language']=='zh-cn'?'active':''}"> @@ -76,7 +76,7 @@ </ul> </li> - <li> + <li class="hidden-xs"> <a href="#" data-toggle="fullscreen"><i class="fa fa-arrows-alt"></i></a> </li> diff --git a/application/admin/view/general/attachment/select.html b/application/admin/view/general/attachment/select.html new file mode 100644 index 0000000..dc967fb --- /dev/null +++ b/application/admin/view/general/attachment/select.html @@ -0,0 +1,22 @@ +<div class="panel panel-default panel-intro"> + {:build_heading()} + + <div class="panel-body"> + <div id="myTabContent" class="tab-content"> + <div class="tab-pane fade active in" id="one"> + <div class="widget-body no-padding"> + <div id="toolbar" class="toolbar"> + {:build_toolbar('refresh')} + {if request()->get('multiple') == 'true'} + <a class="btn btn-danger btn-choose-multi"><i class="fa fa-check"></i> {:__('Choose')}</a> + {/if} + </div> + <table id="table" class="table table-bordered table-hover" width="100%"> + + </table> + </div> + </div> + + </div> + </div> +</div> diff --git a/application/admin/view/general/profile/index.html b/application/admin/view/general/profile/index.html index 7ff0d7d..4a0d6a3 100644 --- a/application/admin/view/general/profile/index.html +++ b/application/admin/view/general/profile/index.html @@ -41,7 +41,7 @@ <div class="box-body box-profile"> <div class="profile-avatar-container"> - <img class="profile-user-img img-responsive img-circle plupload" src="{$admin.avatar}" alt=""> + <img class="profile-user-img img-responsive img-circle plupload" src="__CDN__{$admin.avatar}" alt=""> <div class="profile-avatar-text img-circle">{:__('Click to edit')}</div> <button id="plupload-avatar" class="plupload" data-input-id="c-avatar" data-after-upload="changeavatar"><i class="fa fa-upload"></i> {:__('Upload')}</button> </div> diff --git a/application/admin/view/page/add.html b/application/admin/view/page/add.html index 2ba52a7..cf979c6 100644 --- a/application/admin/view/page/add.html +++ b/application/admin/view/page/add.html @@ -28,7 +28,8 @@ <div class="col-xs-12 col-sm-8"> <div class="form-inline"> <input id="c-image" class="form-control" size="50" name="row[image]" type="text" value=""> - <span><button id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <span><button id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image" data-preview-id="plupload-preview-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <ul class="row list-inline plupload-preview" id="plupload-preview-image"></ul> </div> </div> </div> diff --git a/application/admin/view/page/edit.html b/application/admin/view/page/edit.html index 0bf29d6..c44deea 100644 --- a/application/admin/view/page/edit.html +++ b/application/admin/view/page/edit.html @@ -29,7 +29,9 @@ <div class="col-xs-12 col-sm-8"> <div class="form-inline"> <input id="c-image" class="form-control" size="50" name="row[image]" type="text" value="{$row.image}"> - <span><button id="plupload-image" class="btn btn-danger plupload" data-input-id="c-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <span><button type="button" id="plupload-image" class="btn btn-danger plupload" data-multiple="false" data-input-id="c-image" data-preview-id="p-image"><i class="fa fa-upload"></i> {:__('Upload')}</button></span> + <span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-multiple="false" data-input-id="c-image"><i class="fa fa-list-ul"></i> {:__('Choose')}</button></span> + <ul class="row list-inline plupload-preview" id="p-image"></ul> </div> </div> </div> diff --git a/application/common/controller/Backend.php b/application/common/controller/Backend.php index 36ac9f2..afbd2bf 100644 --- a/application/common/controller/Backend.php +++ b/application/common/controller/Backend.php @@ -93,19 +93,22 @@ class Backend extends Controller // 设置当前请求的URI $this->auth->setRequestUri($path); - // 检测是否需要验证登录 if (!$this->auth->match($this->noNeedLogin)) { //检测是否登录 if (!$this->auth->isLogin()) { - $this->error(__('Please login first'), url('index/login', ['url' => $this->request->url()])); + $url = Session::get('referer'); + $url = $url ? $url : $this->request->url(); + $this->error(__('Please login first'), url('index/login', ['url' => $url])); } // 判断是否需要验证权限 if (!$this->auth->match($this->noNeedRight)) { // 判断控制器和方法判断是否有对应权限 + $path = $this->request->path(); + $path = substr($path, 0, 1) == '/' ? $path : '/' . $path; if (!$this->auth->check($path)) { $this->error(__('You have no permission'), NULL); diff --git a/application/uc.php b/application/uc.php index e987868..17976ba 100644 --- a/application/uc.php +++ b/application/uc.php @@ -2,7 +2,7 @@ //UC配置 // Ucenter配置配置 -define('UC_STATUS', TRUE); //是否开启Ucenter同步 +define('UC_STATUS', false); //是否开启Ucenter同步 define('UC_CONNECT', 'mysql'); diff --git a/bower.json b/bower.json index 8de48d2..afe4be9 100644 --- a/bower.json +++ b/bower.json @@ -26,7 +26,7 @@ "bootstrap3-dialog": "bootstrap-dialog#^1.35.3", "require-css": "^0.1.8", "less": "^2.7.1", - "tableExport.jquery.plugin": "^1.6.4", + "tableExport.jquery.plugin": "^1.9.0", "jquery-slimscroll": "slimscroll#^1.3.8", "jquery.cookie": "^1.4.1", "Sortable": "^1.5.0", diff --git a/extend/fast/Auth.php b/extend/fast/Auth.php index 07a0d3f..86473eb 100644 --- a/extend/fast/Auth.php +++ b/extend/fast/Auth.php @@ -209,7 +209,7 @@ class Auth $_rulelist[$uid] = []; return []; } - + // 筛选条件 $where = [ 'status' => 'normal' @@ -220,9 +220,13 @@ class Auth } //读取用户组所有权限规则 $this->rules = Db::name($this->config['auth_rule'])->where($where)->field('id,pid,condition,icon,name,title,ismenu')->select(); - + //循环规则,判断结果。 $rulelist = []; // + if (in_array('*', $ids)) + { + $rulelist[] = "*"; + } foreach ($this->rules as $rule) { //超级管理员无需验证condition diff --git a/public/assets/css/backend.css b/public/assets/css/backend.css index 7133742..915fc98 100644 --- a/public/assets/css/backend.css +++ b/public/assets/css/backend.css @@ -106,8 +106,9 @@ body { font-weight: normal; } .user-panel > .image img { - width: 45px; - height: 45px; + width: 100%; + max-width: 45px; + max-height: 45px; } /*panel扩展描述样式*/ .panel-intro { @@ -329,6 +330,26 @@ body { .note-editor .note-editing-area .note-editable { display: block !important; } +.plupload-preview { + padding: 10px; + margin-bottom: 0; +} +.plupload-preview li { + margin-bottom: 10px; +} +.plupload-preview .thumbnail { + margin-bottom: 10px; +} +.plupload-preview a { + display: block; +} +.plupload-preview a:first-child { + height: 90px; +} +.plupload-preview a img { + height: 80px; + object-fit: cover; +} .pjax-loader-bar .progress { position: fixed; top: 0; @@ -526,6 +547,9 @@ body { .nav-addtabs { display: none; } + .fixed-table-toolbar .columns-right.btn-group { + display: none; + } } /*平板样式*/ /*# sourceMappingURL=backend.css.map */ \ No newline at end of file diff --git a/public/assets/js/backend/general/attachment.js b/public/assets/js/backend/general/attachment.js index 2e683f8..a68b0f6 100644 --- a/public/assets/js/backend/general/attachment.js +++ b/public/assets/js/backend/general/attachment.js @@ -42,6 +42,63 @@ define(['jquery', 'bootstrap', 'backend', 'form', 'table'], function ($, undefin Table.api.bindevent(table); }, + select: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'general/attachment/select', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + sortName: 'id', + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: __('Id')}, + {field: 'url', title: __('Preview'), formatter: Controller.api.formatter.thumb}, + {field: 'imagewidth', title: __('Imagewidth')}, + {field: 'imageheight', title: __('Imageheight')}, + {field: 'mimetype', title: __('Mimetype'), operate: 'LIKE %...%', + process: function (value, arg) { + return value.replace(/\*/g, '%'); + }}, + {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime}, + {field: 'operate', title: __('Operate'), events: { + 'click .btn-chooseone': function (e, value, row, index) { + var callback = Backend.api.query('callback'); + var id = Backend.api.query('element_id'); + var multiple = Backend.api.query('multiple'); + multiple = multiple == 'true' ? true : false; + if (id && callback) { + parent.window[callback](id, {url: row.url}, multiple); + } + }, + }, formatter: function () { + return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>'; + }} + ] + ] + }); + + // 选中多个 + $(document).on("click", ".btn-choose-multi", function () { + var callback = Backend.api.query('callback'); + var id = Backend.api.query('element_id'); + var urlArr = new Array(); + $.each(table.bootstrapTable("getAllSelections"), function (i, j) { + urlArr.push(j.url); + }); + parent.window[callback](id, {url: urlArr.join(",")}, true); + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, add: function () { Controller.api.bindevent(); }, diff --git a/public/assets/js/backend/index.js b/public/assets/js/backend/index.js index 67ffc50..b3318bf 100755 --- a/public/assets/js/backend/index.js +++ b/public/assets/js/backend/index.js @@ -141,7 +141,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { $(".tab-addtabs").addClass("ios-iframe-fix"); } - + if (Config.referer) { //刷新页面后跳到到刷新前的页面 Backend.api.addtabs(Config.referer); @@ -322,8 +322,8 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi $(window).resize(); }, login: function () { - Form.api.bindevent($("#login-form"), null, function () { - location.href = Backend.api.fixurl("index/index"); + Form.api.bindevent($("#login-form"), null, function (data) { + location.href = Backend.api.fixurl(data.url); }); } }; diff --git a/public/assets/js/require-form.js b/public/assets/js/require-form.js index 1bde208..a5b88c1 100755 --- a/public/assets/js/require-form.js +++ b/public/assets/js/require-form.js @@ -51,6 +51,9 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func } Toastr.success(msg ? msg : __('Operation completed')); } else { + if (typeof data.token !== 'undefined') { + $("input[name='__token__']").val(data.token); + } Toastr.error(msg ? msg : __('Operation failed')); } } else { @@ -230,6 +233,33 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'upload', 'validator'], func if ($(".plupload", form).size() > 0) { Upload.api.plupload(); } + + //绑定fachoose选择附件事件 + if ($(".fachoose", form).size() > 0) { + $(document).on('click', ".fachoose", function () { + var multiple = $(this).data("multiple") ? $(this).data("multiple") : false; + var mimetype = $(this).data("mimetype") ? $(this).data("mimetype") : ''; + Backend.api.open("general/attachment/select?callback=refreshchoose&element_id=" + $(this).attr("id") + "&multiple=" + multiple + "&mimetype="+mimetype, __('Choose')); + return false; + }); + + //刷新选择的元素 + window.refreshchoose = function (id, data, multiple) { + var input_id = $("#" + id).data("input-id"); + if (multiple) { + var urlArr = []; + var inputObj = $("#" + input_id); + if (inputObj.val() != "") { + urlArr.push(inputObj.val()); + } + urlArr.push(data.url); + inputObj.val(urlArr.join(",")).trigger("change"); + } else { + $("#" + input_id).val(data.url).trigger("change"); + } + layer.closeAll(); + }; + } }, custom: {} }, diff --git a/public/assets/js/require-table.js b/public/assets/js/require-table.js index cccafda..88b86ea 100644 --- a/public/assets/js/require-table.js +++ b/public/assets/js/require-table.js @@ -24,6 +24,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', locale: 'zh-CN', showToggle: true, showColumns: true, + pk: 'id', sortName: 'id', sortOrder: 'desc', paginationFirstText: __("First"), @@ -110,6 +111,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', //当内容渲染完成后 table.on('post-body.bs.table', function (e, settings, json, xhr) { $(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin"); + $(Table.config.disabledbtn, toolbar).toggleClass('disabled', true); // 挺拽选择,需要重新绑定事件 require(['drag', 'drop'], function () { @@ -187,24 +189,25 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', dragEnd: function () { var data = table.bootstrapTable('getData'); var current = data[parseInt($(this).data("index"))]; + var options = table.bootstrapTable('getOptions'); //改变的值和改变的ID集合 var ids = $.map($("tbody tr:visible", table), function (tr) { - return data[parseInt($(tr).data("index"))].id; + return data[parseInt($(tr).data("index"))][options.pk]; }); - var changeid = current.id; + var changeid = current[options.pk]; var pid = typeof current.pid != 'undefined' ? current.pid : ''; - var options = { + var params = { url: table.bootstrapTable('getOptions').extend.dragsort_url, data: { ids: ids.join(','), changeid: changeid, pid: pid, field: Table.config.dragsortfield, - orderway: table.bootstrapTable('getOptions').sortOrder, - table: table.bootstrapTable('getOptions').extend.table + orderway: options.sortOrder, + table: options.extend.table } }; - Backend.api.ajax(options, function (data) { + Backend.api.ajax(params, function (data) { Toastr.success(__('Operation completed')); table.bootstrapTable('refresh'); }); @@ -233,7 +236,7 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', operate: { 'click .btn-editone': function (e, value, row, index) { var options = $(this).closest('table').bootstrapTable('getOptions'); - Backend.api.open(options.extend.edit_url + "/ids/" + row.id, __('Edit')); + Backend.api.open(options.extend.edit_url + "/ids/" + row[options.pk], __('Edit')); }, 'click .btn-delone': function (e, value, row, index) { var that = this; @@ -250,7 +253,8 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', {icon: 3, title: __('Warning'), offset: [top, left], shadeClose: true}, function () { var table = $(that).closest('table'); - Table.api.multi("del", row.id, table, that); + var options = table.bootstrapTable('getOptions'); + Table.api.multi("del", row[options.pk], table, that); Backend.api.layer.close(index); } ); @@ -341,8 +345,9 @@ define(['jquery', 'bootstrap', 'backend', 'toastr', 'moment', 'bootstrap-table', }, // 获取选中的条目ID集合 selectedids: function (table) { + var options = table.bootstrapTable('getOptions'); return $.map(table.bootstrapTable('getSelections'), function (row) { - return row.id + return row[options.pk]; }); }, // 切换复选框状态 diff --git a/public/assets/js/require-upload.js b/public/assets/js/require-upload.js index b1ee69f..943ffac 100755 --- a/public/assets/js/require-upload.js +++ b/public/assets/js/require-upload.js @@ -1,15 +1,17 @@ -define(['jquery', 'bootstrap', 'backend', 'plupload'], function ($, undefined, Backend, Plupload) { +define(['jquery', 'bootstrap', 'backend', 'plupload', 'dragsort', 'template'], function ($, undefined, Backend, Plupload, Dragsort, Template) { var Upload = { list: {}, config: { container: document.body, - classname: '.plupload', + classname: '.plupload:not([initialized])', + previewtpl: '<li class="col-xs-3"><a href="<%=fullurl%>" data-url="<%=url%>" target="_blank" class="thumbnail"><img src="<%=fullurl%>" class="img-responsive"></a><a href="javascript:;" class="btn btn-danger btn-xs btn-trash"><i class="fa fa-trash"></i></a></li>', }, api: { //Plupload上传 plupload: function (element, onAfterUpload) { element = typeof element == 'undefined' ? Upload.config.classname : element; $(element, Upload.config.container).each(function () { + $(this).attr("initialized", true); var that = this; var id = $(this).prop("id"); var url = $(this).data("url"); @@ -20,14 +22,18 @@ define(['jquery', 'bootstrap', 'backend', 'plupload'], function ($, undefined, B //上传URL url = url ? url : Config.upload.uploadurl; url = Backend.api.fixurl(url); + //填充ID + var input_id = $(that).data("input-id") ? $(that).data("input-id") : ""; + //预览ID + var preview_id = $(that).data("preview-id") ? $(that).data("preview-id") : ""; //最大可上传 - maxsize = maxsize ? maxsize : Config.upload.maxsize; + maxsize = typeof maxsize !== "undefined" ? maxsize : Config.upload.maxsize; //文件类型 - mimetype = mimetype ? mimetype : Config.upload.mimetype; + mimetype = typeof mimetype !== "undefined" ? mimetype : Config.upload.mimetype; //请求的表单参数 - multipart = multipart ? multipart : Config.upload.multipart; + multipart = typeof multipart !== "undefined" ? multipart : Config.upload.multipart; //是否支持批量上传 - multiple = multiple ? multiple : Config.upload.multiple; + multiple = typeof multiple !== "undefined" ? multiple : Config.upload.multiple; //生成Plupload实例 Upload.list[id] = new Plupload.Uploader({ runtimes: 'html5,flash,silverlight,html4', @@ -63,6 +69,7 @@ define(['jquery', 'bootstrap', 'backend', 'plupload'], function ($, undefined, B $(that).prop("disabled", true).html("<i class='fa fa-upload'></i> 上传" + file.percent + "%"); }, FileUploaded: function (up, file, info) { + var options = this.getOption(); //还原按钮文字及状态 $(that).prop("disabled", false).html($(that).data("bakup-html")); //这里可以改成其它的表现形式 @@ -76,9 +83,14 @@ define(['jquery', 'bootstrap', 'backend', 'plupload'], function ($, undefined, B var data = ret.hasOwnProperty("data") && ret.data != "" ? ret.data : null; var msg = ret.hasOwnProperty("msg") && ret.msg != "" ? ret.msg : ""; if (ret.code === 1) { - //$("input[data-plupload-id='" + id + "-text']").val(data.url); - if ($(that).data("input-id")) { - $("input#" + $(that).data("input-id")).val(data.url); + if (input_id) { + var urlArr = []; + var inputObj = $("#" + input_id); + if (options.multi_selection && inputObj.val() != "") { + urlArr.push(inputObj.val()); + } + urlArr.push(data.url); + inputObj.val(urlArr.join(",")).trigger("change"); } var afterUpload = $("#" + id).data("after-upload"); if (afterUpload && typeof Upload.api.custom[afterUpload] == 'function') { @@ -102,6 +114,49 @@ define(['jquery', 'bootstrap', 'backend', 'plupload'], function ($, undefined, B } } }); + + //拖动排序 + if (preview_id && multiple) { + $("#" + preview_id).dragsort({ + dragSelector: "li", + dragEnd: function () { + $("#" + preview_id).trigger("fa.preview.change"); + }, + placeHolderTemplate: '<li class="col-xs-3"></li>' + }); + } + if (preview_id && input_id) { + $(document.body).on("keyup change", "#" + input_id, function () { + var inputStr = $("#" + input_id).val(); + var inputArr = inputStr.split(/\,/); + $("#" + preview_id).empty(); + $.each(inputArr, function (i, j) { + if (!j) { + return true; + } + var html = Template.render(Upload.config.previewtpl, {url: j, fullurl: Config.upload.cdnurl + j}); + $("#" + preview_id).append(html); + }); + }); + $("#" + input_id).trigger("keyup"); + } + if (preview_id) { + // 监听事件 + $(document.body).on("fa.preview.change", "#" + preview_id, function () { + var urlArr = new Array(); + $("#" + preview_id + " [data-url]").each(function (i, j) { + urlArr.push($(this).data("url")); + }); + if (input_id) { + $("#" + input_id).val(urlArr.join(",")); + } + }); + //移除按钮事件 + $(document.body).on("click", "#" + preview_id + " .btn-trash", function () { + $(this).closest("li").remove(); + $("#" + preview_id).trigger("fa.preview.change"); + }); + } Upload.list[id].init(); }); }, diff --git a/public/assets/less/backend.less b/public/assets/less/backend.less index 39ab80a..7fcb21a 100644 --- a/public/assets/less/backend.less +++ b/public/assets/less/backend.less @@ -140,8 +140,9 @@ body { } .user-panel > .image img{ - width:45px; - height:45px; + width:100%; + max-width:45px; + max-height:45px; } /*panel扩展描述样式*/ @@ -364,6 +365,27 @@ body { display: block !important; } +.plupload-preview { + padding:10px; + margin-bottom:0; + li { + margin-bottom:10px; + } + .thumbnail { + margin-bottom:10px; + } + a{ + display:block; + &:first-child{ + height:90px; + } + img{ + height:80px; + object-fit: cover; + } + } +} + .pjax-loader-bar .progress { position: fixed; top: 0; @@ -567,6 +589,11 @@ body { .nav-addtabs { display:none; } + .fixed-table-toolbar { + .columns-right.btn-group{ + display:none; + } + } } /*平板样式*/ @media (max-width: @screen-tablet) { -- libgit2 0.24.0