687 lines
23 KiB
JavaScript
Raw Normal View History

2025-05-20 16:33:23 +08:00
define(['jquery', 'table'], function ($, Table) {
/**
* 事件顺序
pre-body.bs.table
post-header.bs.table
reset-view.bs.table
post-body.bs.table
editable-init.bs.table
load-success.bs.table
*/
var filesource = window.location.href;
var defaultconfig = {
//lineheight:'35px',//默认的行高度,为解决fixcolumn插件高度问题会造成错位的问题 v2.1.8 修复配置fixcolumns时出现左边固定栏的高度与原表格不一致的问题@commented by chensm
stickyHeaderleft: "30px", //表头固定的居左位置,为解决fixheader插件表头错位的问题
sortableHeaderFixedwidth: 50, //排序的表头箭头宽度,为解决sortable插件的排序箭头遮挡表头的问题,
remoteselectpagesize: 10, //下拉框选择默认条数
};
var globaldata = null; //control返回的data数据 {total: 10011,totalviews: 1530,rows[]} load-success.bs.table写入
var fielddatas = []; //需要转ID转name的Field字段 {admin_id=>["ID#1"=>"xxxxxxxx"]} load-success.bs.table写入
var post_body_json = null; //post-body.bs.table 写入,计算合计用
Table.api.bindevent_orignal = Table.api.bindevent;
Table.api.init_orignal = Table.api.init;
Table.api.init = function (defaults, columnDefaults, locales) {
this.init_orignal(defaults, columnDefaults, locales);
}
function htmlEscape(str) {
str = str + "";
return str.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
Table.api.bindevent = function (table) {
var that = this;
this.bindevent_orignal(table);
var options = table.bootstrapTable('getOptions');
//异步下载
if (true) {
if (options.asyndownload != null && options.asyndownload === true) {
//添加下载button
//$(table).parent().parent().before('\
$("#toolbar").append('\
<button type="button" class="btn btn-primary csmtable-generateexcel">导出Excel表格</button>\
<button type="button" class="btn csmtable-readydownload" style="display:none">生成Excel表格中</button>\
<button type="button" class="btn csmtable-downloadexcel" style="display:none">&nbsp;</button>\
<button type="button" class="btn csmtable-downloadexcelfile" style="display:none">&nbsp;</button>\
');
//显示下载按钮当前状态
var si = null;
var sifunc = function (time) {
setTimeout(function () {
//console.log('sifunc setTimeout='+time);
Fast.api.ajax({
//url: window.Config.__CDN__+"/addons/csminvite/indexajax/getInviteInfo",
url: Fast.api.fixurl("csmtable/csmxlstable/queryGenerageStatus"),
type: "post",
data: {
filesource: filesource
},
loading: false
}, function (data, ret) {
//console.log(data.row);
if (data != null && data.row != null) {
if (data.row.progress >= 100) {
$(".csmtable-readydownload").css("display", "none");
$(".csmtable-downloadexcel").css("display", "none");
$(".csmtable-downloadexcelfile").css("display", "inline");
$(".csmtable-downloadexcelfile").text("Excel表格生成完成点击下载文件。Excel表格生成时间" + data.row.createtime + "");
$(".csmtable-downloadexcelfile").attr("data-fileid", data.row.id);
$(".csmtable-generateexcel").text("重新导出");
return false;
} else {
$(".csmtable-readydownload").css("display", "none");
$(".csmtable-downloadexcel").css("display", "inline");
$(".csmtable-downloadexcelfile").css("display", "none");
if (data.row.iserror != null && data.row.iserror == 'Y') {
$(".csmtable-downloadexcel").text("下载报错,原因:" + data.row.errormsg);
} else {
$(".csmtable-downloadexcel").text("正在下载中,下载进度:" + data.row.progress + "%");
sifunc(4000);
return false;
}
}
} else {
//sifunc(4000);
}
return false;
});
}, time);
}
sifunc(1000);
$(".csmtable-downloadexcelfile").click(function () {
var fileid = $(".csmtable-downloadexcelfile").attr("data-fileid");
window.open(Fast.api.fixurl("csmtable/csmxlstable/download") + "?id=" + fileid);
});
//绑定下载按钮
$(".csmtable-generateexcel").click(function () {
$(".csmtable-readydownload").css("display", "inline");
$(".csmtable-downloadexcel").css("display", "none");
$(".csmtable-downloadexcelfile").css("display", "none");
var columns = table.bootstrapTable('getOptions').columns[0];
//chensm@20200606 检查table的数据
//如果column的field有重复,则报错,不允许下载
if (true) {
var cc = [];
for (var i in columns) {
var ff = columns[i]['field'];
//console.log("===>"+ff+"="+cc[ff]);
if (cc[ff] != null && cc[ff] != '') {
alert('table中:' + ff + '重复,无法下载,先修改JS再下载!');
return;
}
cc[ff] = columns[i]['field'];
}
}
sifunc(1000);
columnjson = [];
for (var i in columns) {
var column = columns[i];
if (column.checkbox != null && column.checkbox == true) {
continue;
}
if (column.visible != null && column.visible == false) {
continue;
}
if (column.field == 'operate') {
continue;
}
var formatter = column['formatter'];
if (formatter == Table.api.formatter.datetime) {
formatter = "Table.api.formatter.datetime";
} else {
formatter = "";
}
columnjson.push({
"field": column['field'],
"title": column['title'],
"datasource": column['datasource'],
"datafield": column['datafield'],
"datasourcealias": column['datasourcealias'],
"formatter": formatter,
"searchList": (column['datasource'] != null && column['datasource'] != '') ? "" : column['searchList'],
'operate': column['operate'],
});
}
//console.log(columnjson);
var opt = {
silent: true,
query: {
csmtable_method: 'download_excel',
csmtable_columns: JSON.stringify(columnjson),
csmtable_filesource: filesource,
}
};
$("#table").bootstrapTable('refresh', opt);
// v2.2.5
// Fast.api.ajax({
// url: Fast.api.fixurl("csmtable/csmgenerate/generate"),
// type: "post",
// data: {
// csmtable_columns: JSON.stringify(columnjson),
// csmtable_filesource: filesource,
// csmtable_indexurl:table.bootstrapTable.defaults.extend.index_url,
// },
// loading:false,
// }, function (data, ret) {
// return false;
// }, function () {
// return false;
// });
});
}
} //end if
//var options = table.bootstrapTable('getOptions');
var columns = options.columns[0];
var columnwithdatasources = {};
// table.on('all.bs.table', function (args,name) {
// console.log('----->',name,args);
// });
//在表格内容渲染完成后回调的事件,显示合计 & 修复高度
table.on('post-body.bs.table', function (settings, json, xhr) {
post_body_json = json;
//var options = table.bootstrapTable('getOptions');
//v2.1.8 修复配置fixcolumns时出现左边固定栏的高度与原表格不一致的问题@commented by chensm
//修复高度:fixcolumn高度问题会造成错位的问题
// if(false){
// let vv = options.lineheight;
// vv = (vv==null||vv=='')?defaultconfig['lineheight']:vv;
// $(table).find('td').css('height',vv);
// $(table).find('th').css('height',vv);
// $(table).find('th').css('background-color','white');
// }
//修复fixheader表头错位的问题
if (true) {
let vv = options.stickyHeaderleft;
vv = (vv == null || vv == '') ? defaultconfig['stickyHeaderleft'] : vv;
$("#table-sticky-header-sticky-header-container").css('left', vv);
//2.1.6 修复在fa_1.2.0.20201008版本中固定列出现滚动条的问题
//$("#table-sticky-header tr").css('height','49px');
// var l=document.querySelector('.fixed-table-body');
// var r=document.querySelector('.fixed-table-container');
// l.addEventListener('scroll',function(){
// console.log('-----1');
// r.scrollTop = l.scrollTop;
// });
}
//修复sortable排序箭头遮挡标题文字的问题
if (true) {
for (var i = 0, j = columns.length; i < j; i++) {
var column = columns[i];
//如果未定义width,则修复sortable排序箭头遮挡标题文字的问题
if (column.width == null || column == '') {
if (column.sortable != null && column.sortable == true) {
// 2.2.7 修复column在sortable开启时a.b格式字段出现JS的报错问题
var obj = $("th[data-field='" + column.field + "']");
if (obj == null || obj.css("width") == null) {
continue;
}
var width = (obj.css("width")).replace('px', '');
width = parseInt(width) + defaultconfig.sortableHeaderFixedwidth;
width = (width == null || width == '' || width == 0) ? '200px' : width;
obj.css('width', width + 'px');
obj.css('min-width', width + 'px');
column.width = width + 'px';
}
}
}
}
//处理treegrid,避免自己添加onPostBody方法
if (true) {
let treeGrid = options.treeGrid;
if (treeGrid != null && treeGrid == true) {
var treeColumn = -1;;
for (var i = 0, j = columns.length; i < j; i++) {
if (columns[i].field == options.treeShowField) {
treeColumn = i;
}
}
table.treegrid({
treeColumn: treeColumn,
onChange: function () {
table.bootstrapTable('resetWidth');
}
});
}
}
//editable增强
if (true) {
for (var i = 0, j = columns.length; i < j; i++) {
if (columns[i].editable != null && columns[i].editabletype != null) {
let datafield = columns[i].datafield;
datafield = (datafield == null || datafield == '') ? 'name' : datafield;
switch (columns[i].editabletype) {
case 'dict_select':
let editablesource = []; //[{value: 'male', text: __('Genderdata male')}]
for (let key in columns[i].searchList) {
let value = columns[i].searchList[key];
editablesource.push({
value: key,
text: value
});
}
columns[i].formatter = null;
columns[i].editable = {
type: 'select',
source: editablesource,
title: '请选择',
onblur: 'ignore',
};
break;
case 'remote_select':
columns[i].editable = {
type: 'select2',
title: '请选择',
onblur: 'ignore',
pk: columns[i]['field'],
display: function (value, sourceData) {
//修复select2选择后,回写是id,而不是name
//由于select2 editable修改后返回的是id,所以需要修正为名称
//只有当前editable修改返回,才需要执行此逻辑:通过当前dom节点和修改过来的节点不一样,来判断
if (true) {
let fieldname = $(this).attr("data-name");
let fieldvalue = $(this).attr("data-value");
let that = this;
//chensm@20200603 修复了id为空造成js报错
if (fieldvalue != null && value != null && fieldvalue != value) {
//console.log(fieldvalue,value,datasourceobj);
var datasourceobj = columnwithdatasources[fieldname];
$.ajax({
dataType: 'json',
type: 'get',
url: Fast.api.fixurl(datasourceobj.datasource),
data: {
filter: '{"id":"' + value + '"}',
op: '{"id":"="}'
},
success: function (json) {
//console.log(json);
for (var index in json.rows) {
$(that).html(htmlEscape(json.rows[index][datasourceobj.datafield]));
}
},
});
}
}
$(this).html(htmlEscape(value));
},
select2: {
ajax: {
url: Fast.api.fixurl(columns[i].datasource),
allowClear: true,
multiple: false,
minimumInputLength: 1,
data: function (params) {
var query = {
filter: '{"' + datafield + '":"' + (params.term == null ? '' : params.term) + '"}',
op: '{"' + datafield + '":"like"}',
offset: params.offset + 1 || 0,
limit: defaultconfig.remoteselectpagesize,
};
params.offset = query.offset;
params.limit = query.limit;
return query;
},
processResults: function (data, params) {
var results = [];
var pagination = null;
if (data != null) {
//console.log("processResults",data.rows);
for (var ii = 0, jj = data.rows.length; ii < jj; ii++) {
results.push({
id: data.rows[ii].id,
text: data.rows[ii][datafield]
});
}
var total = data.total;
var offset = params.offset || 0;
if (total > (offset + 1) * params.limit) {
pagination = {
"more": true
};
}
}
//console.log(results);
return {
results: results,
pagination: pagination
};
},
},
},
};
break;
default:
columns[i].editable = {
type: 'select',
source: editablesource,
title: '请选择',
onblur: 'ignore',
display: function (value, sourceData) {
$(that).html(htmlEscape(value));
},
};
break;
} //swith
}
//}
}
} //end true
var countFieldCount = 0;
//显示合计
if (true) {
var tds = "";
var tiphtml = "";
let isfoundshowsum = false;
for (var i = 0, j = columns.length; i < j; i++) {
var column = columns[i];
// v2.1.5_20200921@修复showcolumns:true的情况下,用户自己隐藏字段,会造成合计错位的问题
if (column.visible === false) {
continue;
}
if (column.showsum != null && column.showsum == true) {
isfoundshowsum = true;
var sum = 0;
var tiphtmlpend = "";
if (column.sumfield != null && column.sumfield != '') {
if (globaldata != null) {
sum = globaldata[column.sumfield];
}
} else {
for (var ii = 0, jj = post_body_json.length; ii < jj; ii++) {
var vv = post_body_json[ii][column.field];
sum = utils.floatAdd(sum, parseFloat((vv == null || vv == '') ? '0' : vv));
}
tiphtmlpend = "";//"(当前页面合计)2";
}
tiphtml += "<span class='csmtable-tipslabel'>" + column.title + ":</span>" + sum + "<span class='csmtable-tipspend'>" + tiphtmlpend + "</span><BR>";
tds += "<td class='csmtable-tdsum'>" + sum + "</td>";
countFieldCount++;
} else {
tds += "<td></td>";
}
}
if (isfoundshowsum === true) {
//v2.1.8 修复了开启showsum的时候排序后页面无法刷新的问题
//$(table).find("tr").last().after("<tr class='csmtable-trsum'>"+tds+"</tr>");
$(table).find("tr").last().after("<tr data-index='0' class='csmtable-trsum'>" + tds + "</tr>");
}
// v2.2.8 修复多个合计的情况下前端popover高度问题
var fixedPopupHeight = "<BR>".repeat(((countFieldCount - 2) > 0) ? (countFieldCount - 2) : 0);
// https://getbootstrap.net/docs/components/popovers/
//鼠标移动显示合计tips
$('.csmtable-tdsum').popover({
html: true,
title: '合计统计:',
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div>' + fixedPopupHeight + '</div>',
content: function () {
return tiphtml;
}
}).on("mouseenter", function () {
var _this = this;
$(this).popover("show");
$(this).siblings(".popover").on("mouseleave", function () {
$(_this).popover('hide');
});
}).on("mouseleave", function () {
var _this = this;
setTimeout(function () {
if (!$(".popover:hover").length) {
$(_this).popover("hide")
}
}, 100);
});
} //end true
}); //table.on('post-body.bs.table')
// 当表格数据加载完成时,处理datasource和datafield
table.on('load-success.bs.table', function (e, data) {
globaldata = data;
//v2.1.2 关联字段支持datasource
//console.log('----',data.rows);
for (let i = 0, j = data.rows ? data.rows.length : 0; i < j; i++) {
let irow = data.rows[i];
for (let ii in irow) {
let iirow = irow[ii];
if (utils.isJSON(iirow)) {
for (let iii in iirow) {
data.rows[i][ii + "." + iii] = iirow[iii];
}
}
}
}
//处理datasource和datafield
if (true) {
var ajaxs = [];
for (var i = 0, j = columns.length; i < j; i++) {
if (columns[i].datasource != null && columns[i].datasource != '') {
// 如果datafield没有定义在默认为title
let column = columns[i];
let datasource = column.datasource;
let datafield = column.datafield;
datafield = (datafield == null || datafield == '') ? 'name' : datafield;
columnwithdatasources[columns[i].field] = ({
datasource: datasource,
datafield: datafield
});
// 收集需要转换的id一次性调用后台获取name
let ids = "";
for (let ii = 0, jj = data.rows ? data.rows.length : 0; ii < jj; ii++) {
ids += data.rows[ii][column["field"]] + ",";
}
//增加了datasourcealias,用于id换名称有alias
let alias = '';
if (column.datasourcealias != null && column.datasourcealias != '') {
alias = column.datasourcealias + '.';
}
//v2.2.5 修复admin账号的安全漏洞
let datasource_callremote = column.datasource;
if (datasource_callremote == "auth/admin") {
datasource_callremote = "csmtable/datasource/admin";
}
let fielddata = [];
let a = $.ajax({
dataType: 'json',
type: 'get',
url: Fast.api.fixurl(datasource_callremote),
data: {
filter: '{"' + alias + 'id":"' + ids + '"}',
op: '{"' + alias + 'id":"in"}',
sort: '' + alias + 'id',
order: 'desc'
},
success: function (json) {
//console.log('===2>',datasource_callremote,json);
for (var index in json.rows) {
let item = json.rows[index];
fielddata['ID#' + item['id']] = item[datafield];
}
},
});
ajaxs.push(a);
fielddatas[columns[i].field] = fielddata;
//console.log(columns[i].field+"/"+fielddata);//todo csm mutil-selectid
}
}
//当ajax请求都完成后,再将fielddatas写入到data中
if (ajaxs.length > 0) {
$.when.apply(this, ajaxs).done(function () {
for (var field in fielddatas) {
var fielddata = fielddatas[field];
for (var i = 0, j = data.rows.length; i < j; i++) {
//data.rows[i][field] = fielddata['ID#'+data.rows[i][field]];
//chensm@20200626:支持一对多关联,用逗号分隔
//v2.1.2 row中对应field字段为空,则不会tostring报错
var tt = (data.rows[i][field] == null) ? "" : data.rows[i][field].toString();
if (tt.indexOf(",") < 0) {
data.rows[i][field] = fielddata['ID#' + tt];
} else {
var iids = tt.split(',');
var ivalues = [];
for (var ii = 0; ii < iids.length; ii++) {
ivalues[ii] = fielddata['ID#' + iids[ii]];
}
data.rows[i][field] = ivalues.join(',');
}
}
}
globaldata = data;
table.bootstrapTable("load", data); //2.2.2 修复remote_select类型在查询列表中显示ID没有显示对应datafield的问题
//console.log(data);
}).fail(function () {
alert("Datasource render fail");
});
}
} //end true
//table.bootstrapTable("load",data);
if (true) {
if (options.fixedColumns == true) {
//修复固定列后,全选checkbox无法选中新生成的checkbox
$("input[name=btSelectAll]").click(function () {
var checked = $(this).prop('checked');
$("input[name=btSelectItem]").prop('checked', checked);
});
//v2.1.7 修复了在fa_1.2.0.20201008版本下,fixcolumn开启下无法点击checkbox的问题 @chensm add 20201213
$(".fixed-columns input[name=btSelectItem]").unbind("click");
$(".fixed-columns tr td").unbind("click");
//console.log($._data($(".fixed-columns input[name=btSelectItem]").get(0)).events);
$(".fixed-columns input[name=btSelectItem]").on('click', function () {
//console.log('cccc22020/12/13'+$(this).checked);
var checked = $(this).prop('checked');
var value = $(this).data('index');
$("input[name=btSelectItem][data-index=" + value + "]").each(function () {
$(this).prop('checked', checked);
$(this).trigger('click');
$(this).trigger('click');
//$(this).trigger('change');
});
});
//v2.1.8 修复配置fixcolumns时出现左边固定栏的高度与原表格不一致的问题
$('.bootstrap-table th,.bootstrap-table td').css('height', '50px');
//alert($(".fixed-table-body #table").css('height'));
$('.fixed-table-body-columns').css('height', $(".fixed-table-body table tbody").css('height')); //用于修正1.2.0.20201008_beta之前fixed column的table高度
$('.fixed-columns').css('height', $(".fixed-table-body table").css('height')); //用于修正1.2.0.20201008_beta之后fixed column的table高度
$('.fixed-table-body').css('overflow-y', 'hidden');
$('.fixed-table-body').css('width', '');
$('.fixed-table-body').css('height', '');
}
}
}); //table.on('load-success.bs.table')
};
var utils = {
floatAdd: function (arg1, arg2) {
if (isNaN(arg1)) {
arg1 = 0;
}
if (isNaN(arg2)) {
arg2 = 0;
}
arg1 = Number(arg1);
arg2 = Number(arg2);
var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
},
isJSON: function (obj) {
var isjson = typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
return isjson;
}
};
return Table;
});