作者 Karson

优化列表导出功能

修复导出全部BUG
优化移动端列表展示
优化iOS移动端展示
@@ -262,7 +262,7 @@ class Backend extends Controller @@ -262,7 +262,7 @@ class Backend extends Controller
262 $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id'); 262 $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
263 $order = $this->request->get("order", "DESC"); 263 $order = $this->request->get("order", "DESC");
264 $offset = $this->request->get("offset/d", 0); 264 $offset = $this->request->get("offset/d", 0);
265 - $limit = $this->request->get("limit/d", 10); 265 + $limit = $this->request->get("limit/d", 999999);
266 //新增自动计算页码 266 //新增自动计算页码
267 $page = $limit ? intval($offset / $limit) + 1 : 1; 267 $page = $limit ? intval($offset / $limit) + 1 : 1;
268 if ($this->request->has("page")) { 268 if ($this->request->has("page")) {
@@ -390,7 +390,7 @@ class Backend extends Controller @@ -390,7 +390,7 @@ class Backend extends Controller
390 $relation = Loader::parseName($tableArr[0], 1, false); 390 $relation = Loader::parseName($tableArr[0], 1, false);
391 $this->model->alias([$this->model->$relation()->getTable() => $tableArr[0]]); 391 $this->model->alias([$this->model->$relation()->getTable() => $tableArr[0]]);
392 } 392 }
393 - $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' time', $arr]; 393 + $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
394 break; 394 break;
395 case 'NULL': 395 case 'NULL':
396 case 'IS NULL': 396 case 'IS NULL':
@@ -471,7 +471,7 @@ class Backend extends Controller @@ -471,7 +471,7 @@ class Backend extends Controller
471 $ishtml = $this->request->request("isHtml", 0); 471 $ishtml = $this->request->request("isHtml", 0);
472 if ($istree) { 472 if ($istree) {
473 $word = []; 473 $word = [];
474 - $pagesize = 99999; 474 + $pagesize = 999999;
475 } 475 }
476 $order = []; 476 $order = [];
477 foreach ($orderby as $k => $v) { 477 foreach ($orderby as $k => $v) {
@@ -482,7 +482,7 @@ class Backend extends Controller @@ -482,7 +482,7 @@ class Backend extends Controller
482 //如果有primaryvalue,说明当前是初始化传值 482 //如果有primaryvalue,说明当前是初始化传值
483 if ($primaryvalue !== null) { 483 if ($primaryvalue !== null) {
484 $where = [$primarykey => ['in', $primaryvalue]]; 484 $where = [$primarykey => ['in', $primaryvalue]];
485 - $pagesize = 99999; 485 + $pagesize = 999999;
486 } else { 486 } else {
487 $where = function ($query) use ($word, $andor, $field, $searchfield, $custom) { 487 $where = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
488 $logic = $andor == 'AND' ? '&' : '|'; 488 $logic = $andor == 'AND' ? '&' : '|';
@@ -244,6 +244,7 @@ class User extends Frontend @@ -244,6 +244,7 @@ class User extends Frontend
244 ]; 244 ];
245 245
246 $msg = [ 246 $msg = [
  247 + 'renewpassword.confirm' => __('Password and confirm password don\'t match')
247 ]; 248 ];
248 $data = [ 249 $data = [
249 'oldpassword' => $oldpassword, 250 'oldpassword' => $oldpassword,
@@ -54,6 +54,7 @@ return [ @@ -54,6 +54,7 @@ return [
54 'New email' => '新邮箱', 54 'New email' => '新邮箱',
55 'New mobile' => '新手机号', 55 'New mobile' => '新手机号',
56 'Change password successful' => '修改密码成功', 56 'Change password successful' => '修改密码成功',
  57 + 'Password and confirm password don\'t match' => '两次输入的密码不一致',
57 'Captcha is incorrect' => '验证码不正确', 58 'Captcha is incorrect' => '验证码不正确',
58 'Logged in successful' => '登录成功', 59 'Logged in successful' => '登录成功',
59 'Logout successful' => '退出成功', 60 'Logout successful' => '退出成功',
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 "jquery": "^2.1.4", 9 "jquery": "^2.1.4",
10 "bootstrap": "^3.3.7", 10 "bootstrap": "^3.3.7",
11 "font-awesome": "^4.6.1", 11 "font-awesome": "^4.6.1",
12 - "bootstrap-table": "fastadmin-bootstraptable#~1.11.3", 12 + "bootstrap-table": "fastadmin-bootstraptable#~1.11.5",
13 "jstree": "~3.3.2", 13 "jstree": "~3.3.2",
14 "moment": "^2.20.1", 14 "moment": "^2.20.1",
15 "toastr": "~2.1.3", 15 "toastr": "~2.1.3",
@@ -42,6 +42,13 @@ html.ios-fix body { @@ -42,6 +42,13 @@ html.ios-fix body {
42 overflow: auto; 42 overflow: auto;
43 -webkit-overflow-scrolling: touch; 43 -webkit-overflow-scrolling: touch;
44 } 44 }
  45 +html.ios-fix .wrapper,
  46 +html.ios-fix body .wrapper,
  47 +html.ios-fix .tab-pane,
  48 +html.ios-fix body .tab-pane {
  49 + overflow: auto;
  50 + -webkit-overflow-scrolling: touch;
  51 +}
45 .wrapper { 52 .wrapper {
46 height: 100%; 53 height: 100%;
47 } 54 }
@@ -973,8 +980,32 @@ table.table-nowrap thead > tr > th { @@ -973,8 +980,32 @@ table.table-nowrap thead > tr > th {
973 #firstnav .navbar-nav > .user-menu .user-image { 980 #firstnav .navbar-nav > .user-menu .user-image {
974 margin-top: -3px; 981 margin-top: -3px;
975 } 982 }
976 - .fixed-table-toolbar .columns-right.btn-group {  
977 - display: none; 983 + .fixed-table-toolbar > .bs-bars {
  984 + float: none !important;
  985 + }
  986 + .fixed-table-toolbar .toolbar a.btn-refresh,
  987 + .fixed-table-toolbar .toolbar a.btn-del,
  988 + .fixed-table-toolbar .toolbar a.btn-add,
  989 + .fixed-table-toolbar .toolbar a.btn-edit,
  990 + .fixed-table-toolbar .toolbar a.btn-import,
  991 + .fixed-table-toolbar .toolbar a.btn-more,
  992 + .fixed-table-toolbar .toolbar a.btn-recyclebin,
  993 + .fixed-table-toolbar .toolbar a.btn-mini-xs {
  994 + font-size: 0;
  995 + }
  996 + .fixed-table-toolbar .toolbar a.btn-refresh .fa,
  997 + .fixed-table-toolbar .toolbar a.btn-del .fa,
  998 + .fixed-table-toolbar .toolbar a.btn-add .fa,
  999 + .fixed-table-toolbar .toolbar a.btn-edit .fa,
  1000 + .fixed-table-toolbar .toolbar a.btn-import .fa,
  1001 + .fixed-table-toolbar .toolbar a.btn-more .fa,
  1002 + .fixed-table-toolbar .toolbar a.btn-recyclebin .fa,
  1003 + .fixed-table-toolbar .toolbar a.btn-mini-xs .fa {
  1004 + font-size: initial;
  1005 + }
  1006 + .fixed-table-toolbar .search {
  1007 + max-width: 110px;
  1008 + float: left !important;
978 } 1009 }
979 .fixed .content-wrapper, 1010 .fixed .content-wrapper,
980 .fixed .right-side { 1011 .fixed .right-side {
@@ -1085,7 +1116,7 @@ table.table-nowrap thead > tr > th { @@ -1085,7 +1116,7 @@ table.table-nowrap thead > tr > th {
1085 min-height: 41px; 1116 min-height: 41px;
1086 background-color: #fff; 1117 background-color: #fff;
1087 box-sizing: border-box; 1118 box-sizing: border-box;
1088 - z-index: 1; 1119 + z-index: 2;
1089 box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.08); 1120 box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.08);
1090 } 1121 }
1091 .fixed-columns .fixed-table-body, 1122 .fixed-columns .fixed-table-body,
@@ -14,10 +14,16 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -14,10 +14,16 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
14 titleForm: '', //为空则不显示标题,不定义默认显示:普通搜索 14 titleForm: '', //为空则不显示标题,不定义默认显示:普通搜索
15 idTable: 'commonTable', 15 idTable: 'commonTable',
16 showExport: true, 16 showExport: true,
17 - exportDataType: "all", 17 + exportDataType: "auto",
18 exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'], 18 exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
19 exportOptions: { 19 exportOptions: {
20 fileName: 'export_' + Moment().format("YYYY-MM-DD"), 20 fileName: 'export_' + Moment().format("YYYY-MM-DD"),
  21 + preventInjection: false,
  22 + mso: {
  23 + onMsoNumberFormat: function (cell, row, col) {
  24 + return !isNaN($(cell).text()) ? '\\@' : '';
  25 + },
  26 + },
21 ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列 27 ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
22 }, 28 },
23 pageSize: localStorage.getItem("pagesize") || 10, 29 pageSize: localStorage.getItem("pagesize") || 10,
@@ -39,6 +45,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -39,6 +45,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
39 paginationNextText: __("Next"), 45 paginationNextText: __("Next"),
40 paginationLastText: __("Last"), 46 paginationLastText: __("Last"),
41 cardView: false, //卡片视图 47 cardView: false, //卡片视图
  48 + iosCardView: true, //ios卡片视图
42 checkOnInit: true, //是否在初始化时判断 49 checkOnInit: true, //是否在初始化时判断
43 escape: true, //是否对内容进行转义 50 escape: true, //是否对内容进行转义
44 selectedIds: [], 51 selectedIds: [],
@@ -103,10 +110,6 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -103,10 +110,6 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
103 defaults = defaults ? defaults : {}; 110 defaults = defaults ? defaults : {};
104 columnDefaults = columnDefaults ? columnDefaults : {}; 111 columnDefaults = columnDefaults ? columnDefaults : {};
105 locales = locales ? locales : {}; 112 locales = locales ? locales : {};
106 - // 如果是iOS设备则启用卡片视图  
107 - if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {  
108 - Table.defaults.cardView = true;  
109 - }  
110 $.fn.bootstrapTable.Constructor.prototype.getSelectItem = function () { 113 $.fn.bootstrapTable.Constructor.prototype.getSelectItem = function () {
111 return this.$selectItem; 114 return this.$selectItem;
112 }; 115 };
@@ -135,6 +138,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -135,6 +138,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
135 return __('Go'); 138 return __('Go');
136 } 139 }
137 }, locales); 140 }, locales);
  141 + // 如果是iOS设备则判断是否启用卡片视图
  142 + if ($.fn.bootstrapTable.defaults.iosCardView && navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
  143 + Table.defaults.cardView = true;
  144 + $.fn.bootstrapTable.defaults.cardView = true;
  145 + }
138 if (typeof defaults.exportTypes != 'undefined') { 146 if (typeof defaults.exportTypes != 'undefined') {
139 $.fn.bootstrapTable.defaults.exportTypes = defaults.exportTypes; 147 $.fn.bootstrapTable.defaults.exportTypes = defaults.exportTypes;
140 } 148 }
@@ -227,9 +235,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -227,9 +235,14 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
227 checkboxtd.drop("start", function () { 235 checkboxtd.drop("start", function () {
228 Table.api.toggleattr(this); 236 Table.api.toggleattr(this);
229 }).drop(function () { 237 }).drop(function () {
230 - Table.api.toggleattr(this);  
231 - }).drop("end", function () {  
232 - Table.api.toggleattr(this); 238 + // Table.api.toggleattr(this);
  239 + }).drop("end", function (e) {
  240 + var that = this;
  241 + setTimeout(function () {
  242 + if (e.type === 'mousemove') {
  243 + Table.api.toggleattr(that);
  244 + }
  245 + }, 0);
233 }); 246 });
234 $.drop({ 247 $.drop({
235 multi: true 248 multi: true
@@ -237,6 +250,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -237,6 +250,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
237 }); 250 });
238 } 251 }
239 }); 252 });
  253 + var exportDataType = options.exportDataType;
240 // 处理选中筛选框后按钮的状态统一变更 254 // 处理选中筛选框后按钮的状态统一变更
241 table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table post-body.bs.table', function (e) { 255 table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table post-body.bs.table', function (e) {
242 var allIds = table.bootstrapTable("getData").map(function (item) { 256 var allIds = table.bootstrapTable("getData").map(function (item) {
@@ -262,8 +276,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table @@ -262,8 +276,11 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
262 options.selectedIds = selectedIds; 276 options.selectedIds = selectedIds;
263 options.selectedData = selectedData; 277 options.selectedData = selectedData;
264 } 278 }
  279 + //如果导出类型为auto时则自动判断
  280 + if (exportDataType === 'auto') {
  281 + options.exportDataType = selectedIds.length > 0 ? 'selected' : 'all';
  282 + }
265 $(Table.config.disabledbtn, toolbar).toggleClass('disabled', !options.selectedIds.length); 283 $(Table.config.disabledbtn, toolbar).toggleClass('disabled', !options.selectedIds.length);
266 -  
267 }); 284 });
268 // 绑定TAB事件 285 // 绑定TAB事件
269 $('.panel-heading [data-field] a[data-toggle="tab"]').on('shown.bs.tab', function (e) { 286 $('.panel-heading [data-field] a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
@@ -59,6 +59,11 @@ html.ios-fix, html.ios-fix body { @@ -59,6 +59,11 @@ html.ios-fix, html.ios-fix body {
59 height: 100%; 59 height: 100%;
60 overflow: auto; 60 overflow: auto;
61 -webkit-overflow-scrolling: touch; 61 -webkit-overflow-scrolling: touch;
  62 +
  63 + .wrapper, .tab-pane {
  64 + overflow: auto;
  65 + -webkit-overflow-scrolling: touch;
  66 + }
62 } 67 }
63 68
64 .wrapper { 69 .wrapper {
@@ -1205,8 +1210,23 @@ table.table-nowrap { @@ -1205,8 +1210,23 @@ table.table-nowrap {
1205 } 1210 }
1206 1211
1207 .fixed-table-toolbar { 1212 .fixed-table-toolbar {
1208 - .columns-right.btn-group {  
1209 - display: none; 1213 + > .bs-bars {
  1214 + float: none !important;
  1215 + }
  1216 +
  1217 + .toolbar {
  1218 + a.btn-refresh, a.btn-del, a.btn-add, a.btn-edit, a.btn-import, a.btn-more, a.btn-recyclebin, a.btn-mini-xs {
  1219 + font-size: 0;
  1220 +
  1221 + .fa {
  1222 + font-size: initial;
  1223 + }
  1224 + }
  1225 + }
  1226 +
  1227 + .search {
  1228 + max-width: 110px;
  1229 + float: left !important;
1210 } 1230 }
1211 } 1231 }
1212 1232
@@ -1349,7 +1369,7 @@ table.table-nowrap { @@ -1349,7 +1369,7 @@ table.table-nowrap {
1349 min-height: 41px; 1369 min-height: 41px;
1350 background-color: #fff; 1370 background-color: #fff;
1351 box-sizing: border-box; 1371 box-sizing: border-box;
1352 - z-index: 1; 1372 + z-index: 2;
1353 box-shadow: 0 -1px 8px rgba(0, 0, 0, .08); 1373 box-shadow: 0 -1px 8px rgba(0, 0, 0, .08);
1354 1374
1355 .fixed-table-body { 1375 .fixed-table-body {
@@ -1390,3 +1410,4 @@ table.table-nowrap { @@ -1390,3 +1410,4 @@ table.table-nowrap {
1390 -o-transform: rotate(-90deg); 1410 -o-transform: rotate(-90deg);
1391 transform: rotate(-90deg); 1411 transform: rotate(-90deg);
1392 } 1412 }
  1413 +