⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.124
Server IP:
50.28.103.30
Server:
Linux host.jcukjv-lwsites.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
Server Software:
nginx/1.28.0
PHP Version:
8.3.12
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
www
/
server
/
panel
/
BTPanel
/
static
/
vite
/
oldjs
/
View File Name :
tools.js
var bt_tools = { commandConnectionPool: {}, //ws连接池 /** * @description 表格渲染 * @param {object} config 配置对象 参考说明 * @return 当前实例对象 */ table: function (config) { var that = this, table = $(config.el), tableData = table.data('table'); if (tableData && table.find('table').length > 0) { if (config.url !== undefined) { tableData.$refresh_table_list(true); } else if (config.data !== undefined) { tableData.$reader_content(config.data); } return tableData; } function ReaderTable(config) { this.config = config; this.$load(); } ReaderTable.prototype = { style_list: [], // 样式列表 event_list: {}, // 事件列表,已绑定事件 checkbox_list: [], // 元素选中列表 batch_active: {}, event_rows_model: {}, // 事件行内元素模型,行内元素点击都会将数据临时存放 data: [], page: '', column: [], batch_thread: [], random: bt.get_random(5), init: false, // 是否初始化渲染 checked: false, // 是否激活,用来判断是否失去焦点 /** * @description 加载数据 * @return void */ $load: function () { var _that = this; if (this.config.init) this.config.init(this); $(this.config.el).addClass('bt_table'); if (this.config.minWidth) this.style_list.push({ className: this.config.el + ' table', css: 'min-width:' + this.config.minWidth, }); if (this.config.tootls) { this.$reader_tootls(this.config.tootls); } else { if ($(_that.config.el + '.divtable').length === 0) $(_that.config.el).append('<div class="divtable mtb10" style="max-height:' + (this.config.height || 'auto') + '"></div>'); } this.$reader_content(); if (_that.config.url !== undefined) { this.$refresh_table_list(_that.config.load || false); } else if (this.config.data !== undefined) { this.$reader_content(this.config.data); } else { alert('缺少data或url参数'); } if (this.config.methods) { //挂载实例方法 $.extend(this, this.config.methods); } if (this.config.height) bt_tools.$fixed_table_thead(this.config.el + ' .divtable'); }, /** * @description 刷新表格数据 * @param {boolean} load * @param {function} callback 回调函数 * @return void */ $refresh_table_list: function (load, callback) { var _that = this; this.$http(load, function (data) { if (callback) callback(data); _that.$reader_content(data.data, typeof data.total != 'undefined' ? parseInt(data.total) : data.page); }); }, /** * @description 渲染内容 * @param {object} data 渲染的数据 * @param {number} page 数据分页/总数 * @return void */ $reader_content: function (data, page) { var _that = this, thead = '', tbody = '', i = 0, column = this.config.column, event_list = {}, checkbox = $(_that.config.el + ' .checkbox_' + _that.random); data = data || []; this.data = data; if (checkbox.length) { checkbox.removeClass('active selected'); _that.checkbox_list = []; _that.$set_batch_view(); } do { var rows = data[i], completion = 0; if (data.length > 0) tbody += '<tr>'; for (var j = 0; j < column.length; j++) { var item = column[j]; if ($.isEmptyObject(item)) { completion++; continue; } if (i === 0 && !this.init) { if (!this.init) this.style_list.push(this.$dynamic_merge_style(item, j - completion)); var sortName = 'sort_' + this.random + '', checkboxName = 'checkbox_' + this.random, sortValue = item.sortValue || 'desc'; thead += '<th><span ' + (item.sort ? 'class="not-select ' + sortName + (item.sortValue ? ' sort-active' : '') + ' cursor-pointer"' : '') + ' data-index="' + j + '" ' + (item.sort ? 'data-sort="' + sortValue + '"' : '') + '>' + (item.type == 'checkbox' ? '<label><i class="cust—checkbox cursor-pointer ' + checkboxName + '" data-checkbox="all"></i><input type="checkbox" class="cust—checkbox-input"></label>' : '<span>' + item.title + '</span>') + (item.sort ? '<span class="glyphicon glyphicon-triangle-' + (sortValue == 'desc' ? 'bottom' : 'top') + ' ml5"></span>' : '') + '</span></th>'; if (i === 0) { if (!event_list[sortName] && item.sort) event_list[sortName] = { event: this.config.sortEvent, eventType: 'click', type: 'sort', }; if (!event_list[checkboxName]) event_list[checkboxName] = { event: item.checked, eventType: 'click', type: 'checkbox', }; } } if (rows !== undefined) { var template = '', className = 'event_' + item.fid + '_' + this.random; if (item.template) { template = _that.$custom_template_render(item, rows, j); } if (typeof template === 'undefined' || typeof item.template === 'undefined') { template = this.$reader_column_type(item, rows); event_list = $.extend(event_list, template[1]); template = template[0]; } var fixed = false; if (typeof item.fixed != 'undefined' && item.fixed) { if (typeof item.class != 'undefined') { if (item.class.indexOf('fixed') === -1) item.class += ' fixed'; } else { item.class = 'fixed'; } fixed = true; } tbody += '<td><span ' + (fixed ? 'style="width:' + (item.width - 16) + 'px" title="' + template + '"' : ' ') + (item['class'] ? 'class="' + item['class'] + '"' : '') + ' ' + (item.tips ? 'title="' + item.tips + '"' : '') + '>' + template + '</span></td>'; if (i === 0) { if (!event_list[className] && item.event) event_list[className] = { event: item.event, eventType: 'click', type: 'rows', }; } } } if (data.length > 0) tbody += '</tr>'; if (data.length == 0) tbody += '<tr class="no-tr"><td colspan="' + column.length + '" style="text-align:center;">' + (this.config['default'] || lan['public'].empty) + '</td></tr>'; i++; } while (i < data.length); if (!this.init) this.$style_bind(this.style_list); this.$event_bind(event_list); if (!this.init) { $(this.config.el + ' .divtable').append( '<table class="table table-hover"><thead style="position: relative;z-index: 1;">' + thead + '</thead><tbody>' + tbody + '</tbody></table></div></div>' ); } else { $(this.config.el + ' .divtable tbody').html(tbody); if (this.config.page) { $(this.config.el + ' .page').replaceWith(this.$reader_page(this.config.page, page)); } } this.init = true; if (this.config.success) this.config.success(this); }, /** * @description 自定模板渲染 * @param {object} item 当前元素模型 * @param {object} rows 当前元素数据 * @param {number} j 当前模板index * @return void */ $custom_template_render: function (item, rows, j) { var className = 'event_' + item.fid + '_' + this.random, _template = item.template(rows, j), $template = $(_template); if ($template.length > 0) { template = $template.addClass(className)[0].outerHTML; } else { if (item.type === 'text') { template = '<span class="' + className + ' ' + item['class'] + '">' + _template + '</span>'; } else { template = '<a href="javascript:;" class="btlink ' + className + '">' + _template + '</a>'; } } return template; }, /** * @description 替换table数据 * @param {string} newValue 内容数据 * @return void */ $modify_row_data: function (newValue) { this.event_rows_model.rows = $.extend(this.event_rows_model.rows, newValue); var row_model = this.event_rows_model, template = null; if (typeof row_model.model.template != 'undefined') { template = $(this.$custom_template_render(row_model.model, row_model.rows, row_model.index)); if (!template.length) template = $(this.$reader_column_type(row_model.model, row_model.rows)[0]); } else { template = $(this.$reader_column_type(row_model.model, row_model.rows)[0]); } if (row_model.model.type == 'group') { $(row_model.el).parent().empty().append(template); } else { row_model.el.replaceWith(template); } row_model.el = template; }, /** * @description 批量执行程序 * @param {object} config 配置文件 * @return void */ $batch_success_table: function (config) { var _that = this, length = $(config.html).length; bt.open({ type: 1, title: config.title, area: config.area || ['400px'], shadeClose: false, closeBtn: 2, content: config.content || '<div class="batch_title"><span class><span class="batch_icon"></span><span class="batch_text">' + config.title + ' ' + lan['public'].success + '</span></span></div><div class="' + (length > 4 ? 'fiexd_thead' : '') + ' batch_tabel divtable" style="margin: 15px 30px 15px 30px;overflow: auto;max-height: 195px; border: 1px solid #ddd;"><table style="border: none;" class="table table-hover"><thead><tr><th>' + config.th + '</th><th style="text-align:right;width:170px;">' + lan['public'].result + '</th></tr></thead><tbody>' + config.html + '</tbody></table></div>', success: function () { if (length > 4) _that.$fixed_table_thead('.fiexd_thead'); }, }); }, /** * @description 固定表头 * @param {string} el DOM选择器 * @return void */ $fixed_table_thead: function (el) { $(el).scroll(function () { var scrollTop = this.scrollTop; this.querySelector('thead').style.transform = 'translateY(' + (scrollTop - 1) + 'px)'; }); }, /** * @description 删除行内数据 */ $delete_table_row: function (index) { this.data.splice(index, 1); this.$reader_content(this.data); }, /** * @description 设置批量操作显示 * @return void 无 */ $set_batch_view: function () { if (typeof this.config.batch != 'undefined') { //判断是否存在批量操作 var bt_select_btn = $(this.config.el + ' .set_batch_option'); if (typeof this.config.batch.config != 'undefined') { // 判断批量操作是多个还是单个 if (this.checkbox_list.length > 0) { bt_select_btn .removeClass('bt-disabled btn-default') .addClass('btn-success') .text(lan['public'].please_choose + this.batch_active.title + '(' + lan['public'].selected + this.checkbox_list.length + ')'); } else { bt_select_btn .addClass('bt-disabled btn-default') .removeClass('btn-success') .text(lan['public'].please_choose + this.batch_active.title); } } else { var bt_select_val = $(this.config.el + ' .bt_table_select_group .bt_select_value'); if (this.checkbox_list.length > 0) { bt_select_btn.removeClass('bt-disabled btn-default').addClass('btn-success').prev().removeClass('bt-disabled'); bt_select_val.find('em').html('(' + lan['public'].selected + this.checkbox_list.length + ')'); } else { bt_select_btn.addClass('bt-disabled btn-default').removeClass('btn-success').prev().addClass('bt-disabled'); bt_select_val .children() .eq(0) .html(lan['public'].please_choose + '<em></em>'); bt_select_val.next().find('li').removeClass('active'); this.batch_active = {}; } } } }, /** * @description 渲染指定类型列内容 * @param {object} data 渲染的数据 * @param {object} rows 渲染的模板 * @return void */ $reader_column_type: function (item, rows) { var value = rows[item.fid], event_list = {}, className = 'click_' + item.fid + '_' + this.random, config = [], _that = this; switch (item.type) { case 'text': //普通文本 config = [value, event_list]; break; case 'checkbox': //单选内容 config = ['<label><i class="cust—checkbox cursor-pointer checkbox_' + this.random + '"></i><input type="checkbox" class="cust—checkbox-input"></label>', event_list]; break; case 'password': var _copy = '', _eye_open = '', className = 'ico_' + _that.random + '_', html = '<span class="bt-table-password mr10"><i>**********</i></span>'; if (item.eye_open) { html += '<span class="glyphicon cursor pw-ico glyphicon-eye-open mr10 ' + className + 'eye_open" title="Show"></span>'; if (!event_list[className + 'eye_open']) event_list[className + 'eye_open'] = { type: 'eye_open_password', }; } if (item.copy) { html += '<span class="ico-copy cursor btcopy mr10 ' + className + 'copy" title="Copy"></span>'; if (!event_list[className + 'copy']) event_list[className + 'copy'] = { type: 'copy_password', }; } config = [html, event_list]; break; case 'link': //超链接类型 className += '_' + item.fid; if (!event_list[className] && item.event) event_list[className] = { event: item.event, type: 'rows', }; config = [ '<a class="btlink ' + className + '" href="' + (item.href ? value : 'javascript:;') + '" ' + (item.href ? 'target="' + (item.target || '_blank') + '"' : '') + ' title="' + value + '">' + value + '</a>', event_list, ]; break; case 'input': //可编辑类型 blurName = 'blur_' + item.fid + '_' + this.random; keyupName = 'keyup_' + item.fid + '_' + this.random; if (!event_list[blurName] && item.blur) event_list[blurName] = { event: item.blur, eventType: 'blur', type: 'rows', }; if (!event_list[keyupName] && item.keyup) event_list[keyupName] = { event: item.keyup, eventType: 'keyup', type: 'rows', }; config = ['<input type="text" title="' + lan.site.click_edit + '" class="table-input ' + blurName + ' ' + keyupName + '" data-value="' + value + '" value="' + value + '" />', event_list]; break; case 'status': // 状态类型 var active = ''; $.each(item.config.list, function (index, items) { if (items[0] === value) active = items; }); if (!event_list[className] && item.event) event_list[className] = { event: item.event, type: 'rows', }; config = [ '<a class="btlink ' + className + ' ' + (active[2].indexOf('#') > -1 ? '' : active[2]) + '" style="' + (active[2].indexOf('#') > -1 ? 'color:' + active[2] + ';' : '') + '" href="javascript:;"><span>' + active[1] + '</span>' + (item.config.icon ? '<span class="glyphicon ' + active[3] + '"></span>' : '') + '</a>', event_list, ]; break; case 'switch': //开关类型 var active = '', _random = bt.get_random(5); active = new Number(value) == true ? 'checked' : ''; if (!event_list[className] && item.event) event_list[className] = { event: item.event, type: 'rows', }; config = [ '<div class="switch_group"><input class="btswitch btswitch-ios ' + className + '" id="' + _random + '" type="checkbox" ' + active + '><label class="btswitch-btn" for="' + _random + '" data-index="0" bt-event-click="set_site_server_status"></label></div>', event_list, ]; break; case 'group': var _html = ''; $.each(item.group, function (index, items) { className = (item.fid ? item.fid : 'group') + '_' + index + '_' + _that.random; var _hide = false; if (items.template) { var _template = items.template(rows, _that), $template = $(_template); if ($template.length > 0) { _html += $template.addClass(className)[0].outerHTML; } else { _html += '<a href="javascript:;" class="btlink ' + className + '" title="' + (items.title || '') + '">' + _template + '</a>'; } } else { if (typeof items.hide != 'undefined') { _hide = typeof items.hide === 'boolean' ? items.hide : items.hide(rows); if (typeof _hide != 'boolean') return false; } _html += '<a href="javascript:;" class="btlink ' + className + '" ' + (_hide ? 'style="display:none;"' : '') + ' title="' + (items.tips || items.title) + '">' + items.title + '</a>'; } //当前操作按钮长度等于当前所以值时不向后添加分割 if (!_hide) { if (items.template) { var _template = items.template(rows, _that); if (_template == '') { _html += ''; } else { _html += item.group.length == index + 1 ? '' : ' | '; } } else { _html += item.group.length == index + 1 ? '' : ' | '; } } if (!event_list[className] && items.event) event_list[className] = { event: items.event, type: 'rows', }; }); config = [_html, event_list]; break; default: config = [value, event_list]; break; } return config; }, /** * @description 批量执行程序 * @param {object} config 配置文件 * @return void */ $batch_success_table: function (config) { that.$batch_success_table(config); }, /** * @description 渲染工具条 * @param {object} data 配置参数 * @return void */ $reader_tootls: function (config) { var _that = this, event_list = {}; /** * @description 请求方法 * @param {Function} callback 回调函数 * @returns void */ function request(active, check_list) { var loadT = bt.load(active.title + lan.site.executing), batch_config = {}, list = _that.$get_data_batch_list(active.paramId, check_list); if (!active.beforeRequest) { batch_config[active.paramName] = list.join(','); } else { batch_config[active.paramName] = active.beforeRequest(check_list); } bt_tools.send( { url: active.url || _that.config.batch.url, data: $.extend(active.param || {}, batch_config), }, function (res) { loadT.close(); if (res.status === false && typeof res.success === 'undefined') { bt_tools.msg(res); return false; } if (typeof active.tips === 'undefined' || active.tips) { var html = ''; $.each(res.error, function (key, item) { html += '<tr><td><span class="text-overflow" title="' + key + '">' + key + '</span/></td><td><div style="float:right;" class="size_ellipsis"><span style="color:red">' + item + '</span></div></td></tr>'; }); $.each(res.success, function (index, item) { html += '<tr><td><span class="text-overflow" title="' + item + '">' + item + '</span></td><td><div style="float:right;" class="size_ellipsis"><span style="color:#20a53a">' + lan['public'].success + '</span></div></td></tr>'; }); _that.$batch_success_table({ title: active.title, th: active.theadName, html: html, }); if (active.refresh) _that.$refresh_table_list(true); } else { if (!active.success) { var html = ''; $.each(check_list, function (index, item) { html += '<tr><td><span class="text-overflow" title="' + item.name + '">' + item.name + '</span></td><td><div style="float:right;"><span style="color:' + (res.status ? '#20a53a' : 'red') + '">' + ((typeof active.theadValue != 'undefined' ? active.theadValue[res.status ? 0 : 1] : null) || res.msg) + '</span></div></td></tr>'; }); _that.$batch_success_table({ title: 'Batch' + active.title + 'Success', th: active.theadName, html: html, }); if (active.refresh) _that.$refresh_table_list(true); } } if (active.success) { active.success(res, check_list, _that); } } ); } /** * @description 执行批量,包含递归批量和自动化批量 * @returns void */ function execute_batch(active, check_list, success) { // if(active.recursion) 递归方式 var bacth = { loadT: 0, config: {}, check_list: check_list, bacth_status: true, start_batch: function (param, callback) { var _this = this; if (typeof param == 'undefined') param = {}; if (typeof param == 'function') (callback = param), (param = {}); if (active.load) this.loadT = layer.msg( lan['public'].executeing + active.title + ',<span class="batch_progress">' + lan['public'].schedule + ':0/' + this.check_list.length + '</span>,' + lan['public'].please_wait, { icon: 16, skin: 'batch_tips', shade: 0.3, time: 0, area: '400px', } ); this.config = { param: param, url: active.url, }; this.bacth(callback); }, /** * * @param {Number} index 递归批量程序 * @param {Function} callback 回调函数 * @return void(0) */ bacth: function (index, callback) { var _this = this, param = {}; if (typeof index === 'function' || typeof index === 'undefined') (callback = index), (index = 0); if (index < this.check_list.length) { 'function' == typeof active.url ? (this.config.url = active.url(check_list[index])) : (this.config.url = active.url); if (typeof active.param == 'function') { param = active.param(check_list[index]); } else { param = active.param; } this.config.param = $.extend(this.config.param, param); if (typeof active.paramId != 'undefined') _this.config.param[active.paramName || active.paramId] = _this.check_list[index][active.paramId]; if (typeof active.beforeBacth != 'undefined') this.config.param = $.extend(this.config.param, active.beforeBacth(_this.check_list[index])); if (this.config.param['bacth'] && index == this.check_list.length - 1) { delete this.config.param['bacth']; } if (!_this.bacth_status) return false; if (active.load) $('#layui-layer' + _this.loadT) .find('.layui-layer-content') .html( '<i class="layui-layer-ico layui-layer-ico16"></i>' + lan['public'].executeing + active.title + ',<span class="batch_progress">' + lan['public'].schedule + ':' + index + '/' + _this.check_list.length + '</span>,' + lan['public'].please_wait + (active.clear ? '<a href="javascript:;" class="btlink clear_batch" style="margin-left:20px;">cancel</a>' : '') ); bt_tools.send( { url: this.config.url, data: this.config.param, bacth: true, }, function (res) { $.extend( _this.check_list[index], { request: { status: typeof res.status === 'boolean' ? res.status : false, msg: res.msg || lan['public'].request_error, }, }, { requests: res } ); index++; _this.bacth(index, callback); } ); } else { if (success) success(); if (callback) { callback(this.check_list); } if (active.automatic) { var html = ''; for (var i = 0; i < this.check_list.length; i++) { var item = this.check_list[i]; html += '<tr><td>' + (typeof item[active.paramThead] != 'undefined' ? item[active.paramThead] : item.name) + '</td><td><div style="float:right;"><span style="color:' + (item.request.status ? '#20a53a' : 'red') + '">' + item.request.msg + '</span></div></td></tr>'; } _that.$batch_success_table({ title: 'Batch' + active.title, th: active.theadName, html: html, }); if (active.refresh) _that.$refresh_table_list(true); _that.$clear_table_checkbox(); } layer.close(this.loadT); } }, clear_bacth: function () { this.bacth_status = false; layer.close(this.loadT); }, }; if (active.callback) { active.callback(bacth); } else { if (!active.confirm || active.recursion) { if (active.confirmVerify) { bt.show_confirm('批量操作' + active.title + '已选中', '批量' + active.title + ',该操作可能会存在风险,是否继续?', function (index) { layer.close(index); if (!active.recursion) { request(active, check_list); } else { bacth.start_batch(); } }); } else { bt.confirm( { title: 'Batch ' + active.title, msg: 'Please be cautious, The selected item will be [ ' + active.title + ' ] after confirmation', shadeClose: active.shadeClose ? active.shadeClose : false, }, function (index) { layer.close(index); if (!active.recursion) { request(active, check_list); } else { bacth.start_batch(); } } ); } } else { request(active, check_list); } } } for (var i = 0; i < config.length; i++) { var template = ''; var item = config[i]; var positon = []; switch (item.type) { case 'group': positon = item.positon || ['left', 'top']; $.each(item.list, function (index, items) { var _btn = item.type + '_' + _that.random + '_' + index, html = ''; if (items.type == 'division') { template += '<span class="mlr5"></span>'; } else { if (!items.group) { template += '<button type="button" title="' + (items.tips || items.title) + '" class="btn ' + (items.active ? 'btn-success' : 'btn-default') + ' ' + _btn + ' btn-sm mr5" ' + that.$verify(_that.$reader_style(items.style), 'style') + '>' + (items.icon ? '<span class="glyphicon glyphicon-' + items.icon + ' mr5"></span>' : '') + '<span>' + items.title + '</span></button>'; } else { template += '<div class="btn-group" style="vertical-align: top;">\ <button type="button" class="btn btn-default ' + _btn + ' btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span style="margin-right:2px;">' + lan.site.category_manager + '</span><span class="caret" style="position: relative;top: -1px;"></span></button>\ <ul class="dropdown-menu"></ul>\ </div>'; if (item.list) { $.each(item.list, function (index, items) { html += '<li><a href="javascript:;" ' + +'>' + items[item.key] + '</a></li>'; }); } if (items.init) setTimeout(function () { items.init(_btn); }, 400); } } if (!event_list[_btn]) event_list[_btn] = { event: items.event, type: 'button', }; }); break; case 'search': positon = item.positon || ['right', 'top']; item.value = item.value || ''; this.config.search = item; var _input = 'search_input_' + this.random, _focus = 'search_focus_' + this.random, _btn = 'search_btn_' + this.random; template = '<div class="bt_search"><input type="text" class="search_input ' + _input + '" style="' + (item.width ? 'width:' + item.width : '') + '" placeholder="' + (item.placeholder || '') + '"/><span class="glyphicon glyphicon-search ' + _btn + '" aria-hidden="true"></span></div>'; if (!event_list[_input]) event_list[_input] = { eventType: 'keyup', type: 'search_input', }; if (!event_list[_focus]) event_list[_focus] = { type: 'search_focus', eventType: 'focus', }; if (!event_list[_btn]) event_list[_btn] = { type: 'search_btn', }; break; case 'batch': positon = item.positon || ['left', 'bottom']; item.placeholder = item.placeholder || '请选择批量操作'; item.buttonValue = item.buttonValue || '批量操作'; this.config.batch = item; var batch_list = [], _html = '', active = item.config; if (typeof item.config != 'undefined') { _that.batch_active = active; $(_that.config.el).on('click', '.set_batch_option', function (e) { var check_list = []; for (var i = 0; i < _that.checkbox_list.length; i++) { check_list.push(_that.data[_that.checkbox_list[i]]); } if ($(this).hasClass('bt-disabled')) { layer.tips(_that.config.batch.disabledTips || 'Select batch operation', $(this), { tips: [1, 'red'], time: 2000, }); return false; } switch (typeof active.confirm) { case 'function': active.confirm(active, function (param, callback) { active.param = $.extend(active.param, param); execute_batch(active, check_list, callback); }); break; case 'undefined': execute_batch(active, check_list); break; case 'object': var config = active.confirm; bt.open({ title: config.title || 'Batch execute', area: config.area || '350px', btn: config.btn || ['Confirm', 'Cancel'], content: config.content, success: function (layero, index) { config.success(layero, index, active); }, yes: function (index, layero) { config.yes(index, layero, function (param, callback) { active.param = $.extend(active.param, param); request(active, check_list); }); }, }); break; } }); } else { $.each(item.selectList, function (index, items) { if (items.group) { $.each(items.group, function (indexs, itemss) { batch_list.push($.extend({}, items, itemss)); _html += '<li class="item">' + itemss.title + '</li>'; }); delete items.group; } else { batch_list.push(items); _html += '<li class="item">' + items.title + '</li>'; } }); // 打开批量类型列表 $(_that.config.el) .unbind() .on('click', '.bt_table_select_group .bt_select_value', function (e) { var _this = this, $parent = $(this).parent(), bt_selects = $parent.find('.bt_selects'), area = $parent.offset(), _win_area = _that.$get_win_area(); if ($parent.hasClass('bt-disabled')) { layer.tips(_that.config.batch.disabledSelectValue, $parent, { tips: [1, 'red'], time: 2000, }); return false; } if ($parent.hasClass('active')) { $parent.removeClass('active'); } else { $parent.addClass('active'); } if (bt_selects.height() > _win_area[1] - area.top) { bt_selects.addClass('top'); } else { bt_selects.removeClass('top'); } $(document).one('click', function () { $(_that.config.el).find('.bt_table_select_group').removeClass('active'); return false; }); return false; }); // 选择批量的类型 $(_that.config.el).on('click', '.bt_table_select_group .item', function (e) { var _text = $(this).text(), _index = $(this).index(); $(this).addClass('active').siblings().removeClass('active'); $(_that.config.el + ' .bt_select_tips').html('Batch execute ' + _text + '<em>(' + lan.site.have_been_selected + _that.checkbox_list.length + ')</em>'); _that.batch_active = batch_list[_index]; if (!_that.checked) $('.bt_table_select_group').removeClass('active'); }); // 执行批量操作 $(_that.config.el).on('click', '.set_batch_option', function (e) { var check_list = [], active = _that.batch_active; if ($(this).hasClass('bt-disabled')) { layer.tips(_that.config.batch.disabledSelectValue, $(this), { tips: [1, 'red'], time: 2000, }); return false; } for (var i = 0; i < _that.checkbox_list.length; i++) { check_list.push(_that.data[_that.checkbox_list[i]]); } if (JSON.stringify(active) === '{}') { var bt_table_select_group = $(_that.config.el + ' .bt_table_select_group'); layer.tips(lan['public'].select_opt_type, bt_table_select_group, { tips: [1, 'red'], time: 2000, }); bt_table_select_group.css('border', '1px solid red'); setTimeout(function () { bt_table_select_group.removeAttr('style'); }, 2000); return false; } switch (typeof active.confirm) { case 'function': active.confirm(active, function (param, callback) { active.param = $.extend(active.param, param); execute_batch(active, check_list, callback); }); break; case 'undefined': execute_batch(active, check_list); break; case 'object': var config = active.confirm; bt.open({ type: 1, title: config.title || lan['public'].bulk_opt, area: config.area || '350px', btn: config.btn || [lan['public'].confirm, lan['public'].cancel], content: config.content, success: function (layero, index) { config.success(layero, index, active); }, yes: function (index, layero) { config.yes(index, layero, function (param, callback) { active.param = $.extend(active.param, param); layer.close(index); request(active, check_list); }); }, }); break; } }); } template = '<div class="bt_batch"><label><i class="cust—checkbox cursor-pointer checkbox_' + this.random + '" data-checkbox="all"></i><input type="checkbox" lass="cust—checkbox-input" /></label>' + (typeof item.config != 'undefined' ? '<button type="button" class="btn btn-default btn-sm set_batch_option bt-disabled">Batch' + item.config.title + '</button>' : '<div class="bt_table_select_group bt-disabled not-select"><span class="bt_select_value"><span class="bt_select_tips">' + lan['public'].select_opt_type + '<em></em></span><span class="glyphicon glyphicon-triangle-bottom ml5"></span></span><ul class="bt_selects ">' + _html + '</ul></div><button class="btn btn-default btn-sm set_batch_option bt-disabled" >' + item.buttonValue + '</button>') + '</div>'; break; case 'page': positon = item.positon || ['right', 'bottom']; item.page = config.page || 1; item.pageParam = item.pageParam || 'p'; item.number = item.number || 20; item.numberList = item.numberList || [10, 20, 50, 100, 200]; item.numberParam = typeof item.numberParam === 'boolean' ? item.numberParam : item.numberParam || 'limit'; this.config.page = item; // var pageNumber = bt.get_cookie('page_number') var pageNumber = this.$get_page_number(); // if (this.config.cookiePrefix && pageNumber) this.config.page.number = pageNumber if (pageNumber) this.config.page.number = pageNumber; template = this.$reader_page(this.config.page, '<div><span class="Pcurrent">1</span><span class="Pcount">Total 0</span></div>'); break; } if (template) { var tools_group = $(_that.config.el + ' .tootls_' + positon[1]); if (tools_group.length) { var tools_item = tools_group.find('.pull-' + positon[0]); tools_item.append(template); } else { var tools_group_elment = '<div class="tootls_group tootls_' + positon[1] + '"><div class="pull-left">' + (positon[0] === 'left' ? template : '') + '</div><div class="pull-right">' + (positon[0] === 'right' ? template : '') + '</div></div>'; if (positon[1] === 'top') { $(_that.config.el).append(tools_group_elment); if ($(_that.config.el + ' .divtable').length === 0) $(_that.config.el).append('<div class="divtable mtb10" style="max-height:' + _that.config.height + 'px"></div>'); } else { if ($(_that.config.el + ' .divtable').length === 0) $(_that.config.el).append('<div class="divtable mtb10" style="max-height:' + _that.config.height + 'px"></div>'); $(_that.config.el).append(tools_group_elment); } } } } if (!this.init) this.$event_bind(event_list); }, $clear_table_checkbox: function () { $(this.config.el).find('.bt_table .cust—checkbox').removeClass('selected active'); }, /** * @description 获取数据批量列表 * @param {string} 需要获取的字段 * @return {array} 当前需要批量列表 */ $get_data_batch_list: function (fid, data) { var arry = []; $.each(data || this.data, function (index, item) { arry.push(item[fid]); }); return arry; }, /** * @description 渲染分页 * @param {object} config 配置文件 * @param {object} page 分页 * @return string */ $reader_page: function (config, page) { var template = '', eventList = {}, _that = this, $page = null; if (config.number && !page) { template = (config.page !== 1 ? '<a class="Pnum page_link_' + this.random + '" data-page="1">Start</a>' : '') + (config.page !== 1 ? '<a class="Pnum page_link_' + this.random + '" data-page="' + (config.page - 1) + '">Prev</a>' : '') + (_that.data.length === config.number ? '<a class="Pnum page_link_' + this.random + '" data-page="' + (config.page + 1) + '">Next</a>' : '') + '<span class="Pcount">Page ' + config.page + '</span>'; eventList['page_link_' + this.random] = { type: 'cut_page_number' }; } else { if (typeof page === 'number') page = this.$custom_page(page); $page = $(page); $page.find('a').addClass('page_link_' + this.random); template += $page.html(); if (config.numberStatus) { var className = 'page_select_' + this.random, number = _that.$get_page_number(); template += '<select class="page_select_number ' + className + '">'; $.each(config.numberList, function (index, item) { template += '<option value="' + item + '" ' + ((number || config.number) == item ? 'selected' : '') + '>' + item + lan.site.items_page + '</option>'; }); template += '</select>'; eventList[className] = { eventType: 'change', type: 'page_select' }; } if (config.jump) { var inputName = 'page_jump_input_' + this.random; var btnName = 'page_jump_btn_' + this.random; template += '<div class="page_jump_group"><span class="page_jump_title">' + lan['public'].jump_to_page + '</span><input type="number" class="page_jump_input ' + inputName + '" value="' + config.page + '" /><span class="page_jump_title"></span><button type="button" class="page_jump_btn ' + btnName + '">' + lan['public'].confirm + '</button></div>'; eventList[inputName] = { eventType: 'keyup', type: 'page_jump_input', }; eventList[btnName] = { type: 'page_jump_btn', }; } eventList['page_link_' + this.random] = { type: 'cut_page_number', }; _that.config.page.total = $page.length === 0 ? 0 : typeof page == 'number' ? page : parseInt( $page .find('.Pcount') .html() .match(/([0-9]*)/g)[1] ); } _that.$event_bind(eventList); return '<div class="page">' + template + '</div>'; }, /** * @description 渲染样式 * @param {object|string} data 样式配置 * @return {string} 样式 */ $reader_style: function (data) { var style = ''; if (typeof data === 'string') return data; if (typeof data === 'undefined') return ''; $.each(data, function (key, item) { style += key + ':' + item + ';'; }); return style; }, /** * @description 自定义分页 * @param {} */ $custom_page: function (total) { var html = '<div class="page">', config = this.config.page, page = Math.ceil(total / config.number), tmpPageIndex = 0; if (config.page > 1 && page > 1) { html += '<a class="Pstart" href="p=1">Home</a><a class="Pstart" href="p=' + (config.page - 1) + '">Prev</a>'; } if (page <= 10) { for (var i = 1; i <= page; i++) { i == config.page ? (html += '<span class="Pcurrent">' + i + '</span>') : (html += '<a class="Pnum" href="p=' + i + '">' + i + '</a>'); } } else if (config.page < 10) { for (var i = 1; i <= 10; i++) i == config.page ? (html += '<span class="Pcurrent">' + i + '</span>') : (html += '<a class="Pnum" href="p=' + i + '">' + i + '</a>'); html += '<span>...</span>'; } else if (page - config.page < 7) { page - 7 > 1 && ((html += '<a class="Pnum" href="p=1">1</a>'), (html += '<span>...</span>')); for (var i = page - 7; i <= page; i++) i == config.page ? (html += '<span class="Pcurrent">' + i + '</span>') : (html += 1 == i ? '<span>...</span>' : '<a class="Pnum" href="p=' + i + '">' + i + '</a>'); } else { 0 == tmpPageIndex && (tmpPageIndex = config.page), (tmpPageIndex <= config.page - 5 || tmpPageIndex >= config.page + 5) && (tmpPageIndex = config.page), (html += '<a class="Pnum" href="p=1">1</a>'), (html += '<span>...</span>'); for (var i = tmpPageIndex - 3; i <= tmpPageIndex + 3; i++) i == config.page ? (html += '<span class="Pcurrent">' + i + '</span>') : (html += '<a class="Pnum" href="p=' + i + '">' + i + '</a>'); (html += '<span>...</span>'), (html += '<a class="Pnum" href="p=' + page + '">' + page + '</a>'); } return ( page > 1 && config.page < page && (html += '<a class="Pstart" href="p=' + (config.page + 1) + '">Next</a><a class="Pstart" href="p=' + page + '">Last</a>'), (html += '<span class="Pcount">Total ' + total + '</span></div>') ); }, /** * @deprecated 动态处理合并行内,css样式 * @param {object} rows 当前行数据 * @return {stinrg} className class类名 * @return void */ $dynamic_merge_style: function (column, index) { var str = ''; $.each(column, function (key, item) { switch (key) { case 'align': str += 'text-align:' + item + ';'; break; case 'width': str += 'width:' + (typeof item == 'string' ? item : item + 'px') + ';'; break; case 'style': str += item; break; case 'minWidth': str += 'min-width:' + (typeof item == 'string' ? item : item + 'px') + ';'; break; case 'maxWidth': str += 'max-width:' + (typeof item == 'string' ? item : item + 'px') + ';'; break; } }); return { index: index, css: str, }; }, /** * @description 事件绑定 * @param {array} eventList 事件列表 * @return void */ $event_bind: function (eventList) { var _that = this; $.each(eventList, function (key, item) { if (_that.event_list[key] && _that.event_list[key].eventType === item.eventType) return true; _that.event_list[key] = item; $(_that.config.el).on(item.eventType || 'click', '.' + key, function (ev) { var index = $(this).parents('tr').index(), data1 = $(this).data(), arry = [], column_data = _that.config.column[$(this).parents('td').index()]; switch (item.type) { case 'rows': _that.event_rows_model = { el: $(this), model: column_data, rows: _that.data[index], index: index, }; arry = [_that.event_rows_model.rows, _that.event_rows_model.index, ev, key, _that]; break; case 'sort': var model = _that.config.column[data1.index]; if ($(this).hasClass('sort-active')) $('.sort_' + _that.random + ' .sort-active').data({ sort: 'desc', }); $('.sort_' + _that.random) .removeClass('sort-active') .find('.glyphicon') .removeClass('glyphicon-triangle-top') .addClass('glyphicon-triangle-bottom'); $(this).addClass('sort-active'); if (data1.sort == 'asc') { $(this).data({ sort: 'desc', }); $(this).find('.glyphicon').removeClass('glyphicon-triangle-top').addClass('glyphicon-triangle-bottom'); } else { $(this).data({ sort: 'asc', }); $(this).find('.glyphicon').removeClass('glyphicon-triangle-bottom').addClass('glyphicon-triangle-top'); } _that.config.sort = _that.config.sortParam({ name: model.fid, sort: data1.sort, }); _that.$refresh_table_list(true); break; case 'checkbox': var all = $(_that.config.el + ' [data-checkbox="all"]'), checkbox_list = $(_that.config.el + ' tbody .checkbox_' + _that.random); if (data1.checkbox == undefined) { if (!$(this).hasClass('active')) { $(this).addClass('active'); _that.checkbox_list.push(index); if (_that.data.length === _that.checkbox_list.length) { all.addClass('active').removeClass('selected'); } else if (_that.checkbox_list.length > 0) { all.addClass('selected'); } } else { $(this).removeClass('active'); _that.checkbox_list.splice(_that.checkbox_list.indexOf(index), 1); if (_that.checkbox_list.length > 0) { all.addClass('selected').removeClass('active'); } else { all.removeClass('selected active'); } } } else { if (_that.checkbox_list.length === _that.data.length) { _that.checkbox_list = []; checkbox_list.removeClass('active selected').next().prop('checked', 'checked'); all.removeClass('active'); } else { checkbox_list.each(function (index, item) { if (!$(this).hasClass('active')) { $(this).addClass('active').next().prop('checked', 'checked'); _that.checkbox_list.push(index); } }); all.removeClass('selected').addClass('active'); } } _that.$set_batch_view(); break; case 'button': arry.push(ev, _that); break; case 'search_focus': var search_tips = $(_that.config.el + ' .bt_search_tips'); if ($(_that.config.el + ' .bt_search_tips').length > 0) { search_tips.remove(); } break; case 'search_input': if (ev.keyCode == 13) { $(_that.config.el + ' .search_btn_' + _that.random).click(); return false; } break; case 'search_btn': var _search = $(_that.config.el + ' .search_input'), val = $(_that.config.el + ' .search_input').val(), _filterBox = $('<div></div>').text(val), _filterText = _filterBox.html(); val = _filterText; //过滤xss val = val.replace(/(^\s*)|(\s*$)/g, ''); _search.text(val); _that.config.search.value = val; if (_that.config.page) _that.config.page.page = 1; _search.append('<div class="bt_search_tips"><span>' + val + '</span><i class="bt_search_close"></i></div>'); _that.$refresh_table_list(true); break; case 'page_select': var limit = parseInt($(this).val()); _that.$set_page_number(limit); _that.config.page.number = limit; _that.config.page.page = 1; _that.$refresh_table_list(true); return false; break; case 'page_jump_input': if (ev.keyCode === 13) { $(_that.config.el + ' .page_jump_btn_' + _that.random).click(); $(this).focus(); } return false; break; case 'page_jump_btn': var jump_page = parseInt($(_that.config.el + ' .page_jump_input_' + _that.random).val()), max_number = Math.ceil(_that.config.page.total / _that.config.page.number); if (isNaN(jump_page)) jump_page = 1; if (jump_page > max_number) jump_page = _that.config.page.page; _that.config.page.page = jump_page; _that.$refresh_table_list(true); break; case 'cut_page_number': var page = $(this).data('page') || parseInt( $(this) .attr('href') .match(/([0-9]*)$/)[0] ); _that.config.page.page = page; _that.$refresh_table_list(true); return false; break; case 'eye_open_password': if ($(this).hasClass('glyphicon-eye-open')) { $(this).addClass('glyphicon-eye-close').removeClass('glyphicon-eye-open'); $(this).prev().text(_that.data[index][column_data.fid]); } else { $(this).addClass('glyphicon-eye-open').removeClass('glyphicon-eye-close'); $(this).prev().html('<i>**********</i>'); } return false; break; case 'copy_password': bt.pub.copy_pass(_that.data[index][column_data.fid]); return false; break; } if (item.event) item.event.apply(this, arry); }); }); }, /** * @description 样式绑定 * @param {array} style_list 样式列表 * @return void */ $style_bind: function (style_list, status) { var str = '', _that = this; $.each(style_list, function (index, item) { if (item.css != '') { if (!item.className) { str += _that.config.el + ' thead th:nth-child(' + (item.index + 1) + '),' + _that.config.el + ' tbody tr td:nth-child' + (item.span ? ' span' : '') + '(' + (item.index + 1) + '){' + item.css + '}'; } else { str += item.className + '{' + item.css + '}'; } } }); if ($('#bt_table_' + _that.random).length == 0) $(_that.config.el).append('<style type="text/css" id="bt_table_' + _that.random + '">' + str + '</style>'); }, /** * @deprecated 获取WIN高度或宽度 * @return 返回当期的宽度和高度 */ $get_win_area: function () { return [window.innerWidth, window.innerHeight]; }, /** * @description 获取分页条数 * @return 返回分页条数 */ $get_page_number: function () { var name = this.config.pageName; if (name) { return bt.get_cookie(name + '_page_number'); } }, /** * @description 设置分页条数 * @param {object} limit 分页条数 * @return void */ $set_page_number: function (limit) { var name = this.config.pageName; if (name) bt.set_cookie(name + '_page_number', limit); }, /** * @description 请求数据, * @param {object} param 参数和请求路径 * @return void */ $http: function (load, success) { var page_number = this.$get_page_number(), that = this, param = {}, config = this.config, _page = config.page, _search = config.search, _sort = config.sort || {}; if (_page) { if (page_number && !_page.number) _page.number = page_number; if (_page.defaultNumber) _page.number = _page.defaultNumber; if (_page.numberParam) param[_page.numberParam] = _page.number; param[_page.pageParam] = _page.page; } if (_search) param[_search.searchParam] = _search.value; var params = $.extend(config.param, param, _sort); if (this.config.beforeRequest) { if (this.config.beforeRequest === 'model') { config.param = (function () { if (params.hasOwnProperty('data') && typeof params.data === 'string') { var oldParams = JSON.parse(params['data']); delete params['data']; return { data: JSON.stringify($.extend(oldParams, params)) }; } return { data: JSON.stringify(params) }; })(); } else { config.param = this.config.beforeRequest(params); } } else { config.param = params; } bt_tools.send( { url: config.url, data: config.param, }, function (res) { if (typeof config.dataFilter != 'undefined') { var data = config.dataFilter(res, that); if (typeof data.tootls != 'undefined') data.tootls = parseInt(data.tootls); if (success) success(data); } else { if (void 0 === res.data) { success && success({ data: res, }); } else success && success({ data: res.data, page: res.page, }); } }, { load: load ? 'Getting Data' : false, verify: typeof config.dataVerify === 'undefined' ? true : !!config.dataVerify } ); }, }; var example = new ReaderTable(config); $(config.el).data('table', example); return example; }, /** * @description 验证表单 * @param {object} el 节点 * @param {object} config 验证配置 * @param {function} callback 验证成功回调 */ verifyForm: function (el, config, callback) { var verify = false, formValue = this.getFormValue(el, []); for (var i = 0; i < config.length; i++) { var item = config[i]; verify = item.validator.apply(this, [formValue[item.name], formValue]); if (typeof verify === 'string') { this.error(verify); return false; } } callback && callback(typeof verify !== 'string', formValue); }, /** * @description 获取表单值 * @param {String} el 表单元素 * @param {Array} filter 过滤列表 * @returns {Object} 表单值 */ getFormValue: function (el, filter) { var form = $(el).serializeObject(); filter = filter && []; for (var key in form) { if (filter.indexOf(key) > -1) delete form[key]; } return form; }, /** * @description 设置layer定位 * @param {object} el 节点 */ setLayerArea: function (el) { var $el = $(el), width = $el.width(), height = $el.height(), winWidth = $(window).width(), winHeight = $(window).height(); $el.css({ left: (winWidth - width) / 2, top: (winHeight - height) / 2 }); }, /** * @description 渲染表单行内容 * @param {object} config 配置参数 */ line: function (config) { var $line = $( '<div class="line" style="' + (config.labelStyle || '') + '"><span class="tname" style="' + (config.labelWidth ? 'width:' + config.labelWidth : '') + '">' + ((typeof config.must !== 'undefined' && config.must != '' ? '<span class="color-red mr5">' + config.must + '</span>' : '') + config.label || '') + '</span><div class="info-r" style="' + (config.labelWidth ? 'margin-left:' + config.labelWidth : '') + '"></div></div>' ); var $form = this.renderLineForm(config); $form.data({ line: $line }); $line.find('.info-r').append($form); return { $line: $line, $form: $form, }; }, /** * @description 帮助提示 * @param {object} config 配置参数 */ help: function (config) { var $help = ''; for (var i = 0; i < config.list.length; i++) { var item = config.list[i]; $help += '<li>' + item + '</li>'; } return $('<ul class="help-info-text c7" style="' + (config.style || '') + '">' + $help + '</ul>'); }, /** * @description 渲染表单行内容 * @param {object} config 配置参数 * @returns {jQuery|HTMLElement|*} */ renderLineForm: function (config) { config.type = config.type || 'text'; var lineFilter = ['label', 'labelWidth', 'group', 'on', 'width', 'options', 'type']; // 排除渲染这些属性 var $form = null; var props = (function () { var attrs = {}; for (var key in config) { if (lineFilter.indexOf(key) === -1) { attrs[key] = config[key]; } } return attrs; })(); var width = config.width ? 'style="width:' + config.width + '"' : ''; switch (config.type) { case 'textarea': $form = '<textarea class="bt-input-text mr5" ' + width + '></textarea>'; break; case 'select': var options = config.options, optionsHtml = ''; for (var i = 0; i < options.length; i++) { var item = options[i], newItem = item; if (typeof item === 'string') newItem = { label: item, value: item }; optionsHtml += '<option value="' + newItem.value + '">' + newItem.label + '</option>'; } $form = '<select class="bt-input-text mr5" ' + width + '>' + optionsHtml + '</select>'; break; case 'text': $form = '<input type="text" class="bt-input-text mr5" />'; break; } $form = $($form); $form.width(config.width || '100%').attr(props); if (!config.on) config.on = {}; for (var onKey in config.on) { (function (onKey) { $form.on(onKey, function (ev) { config.on[onKey].apply(this, [ev, $(this).val()]); }); })(onKey); } return $form; }, /** * @description 渲染表单行组 * @param {object} el 配置参数 * @param {object} config 配置参数 * @param {object|undefined} formData 表单数据 */ fromGroup: function (el, config, formData) { var $el = $(el), lineList = {}; for (var i = 0; i < config.length; i++) { var item = config[i]; if (item.type === 'tips') { $el.append(this.help(item)); } else { var line = this.line(item); if (typeof formData != 'undefined') line.$form.val(formData[item.name] || ''); lineList[line.$form.attr('name')] = line; $el.append(line.$line); } } return lineList; }, /** * @description 渲染Form表单 * @param {*} config * @return 当前实例对象 */ form: function (config) { var _that = this; function ReaderForm(config) { this.config = config; this.el = config.el; this.submit = config.submit; this.data = config.data || {}; this.$load(); } ReaderForm.prototype = { element: null, style_list: [], // 样式列表 event_list: {}, // 事件列表,已绑定事件 event_type: ['click', 'event', 'focus', 'keyup', 'blur', 'change', 'input'], hide_list: [], form_element: {}, form_config: {}, random: bt.get_random(5), $load: function () { var that = this; if (this.el) { $(this.el).html(this.$reader_content()); if ($('#editCrontabForm .bt_multiple_select_updown').length > 0) { var height = $('#editCrontabForm .bt_multiple_select_updown').parent().height(); $('#editCrontabForm .line:eq(3) .tname').css({ height: height + 'px', 'line-height': height + 'px', }); } this.$event_bind(); } }, /** * @description 渲染Form内容 * @param {Function} callback 回调函数 */ $reader_content: function (callback) { var that = this, html = '', _content = ''; $.each(that.config.form, function (index, item) { if (item.separate) { html += '<div class="bt_form_separate"><span class="btn btn-sm btn-default">' + item.separate + '</span></div>'; } else { html += that.$reader_content_row(index, item); } }); that.element = $('<form class="bt-form" data-form="' + that.random + '" onsubmit="return false">' + html + '</form>'); _content = $('<div class="' + _that.$verify(that.config['class']) + '"></div>'); _content.append(that.element); if (callback) callback(); return _content[0].outerHTML; }, /** * @description 渲染行内容 * @param {object} data Form数据 * @param {number} index 下标 * @return {string} HTML结构 */ $reader_content_row: function (index, data) { try { var that = this, help = data.help || false, labelWidth = data.formLabelWidth || this.config.formLabelWidth; if (data.display === false) return ''; return ( '<div class="line' + _that.$verify(data['class']) + _that.$verify(data.hide, 'hide', true) + '"' + _that.$verify(data.id, 'id') + '>' + (typeof data.label !== 'undefined' ? '<span class="tname" ' + (labelWidth ? 'style="width:' + labelWidth + '"' : '') + '>' + (typeof data.must !== 'undefined' && data.must != '' ? '<span class="color-red mr5">' + data.must + '</span>' : '') + data.label + '</span>' : '') + '<div class="' + (data.label ? 'info-r' : '') + _that.$verify(data.line_class) + '"' + _that.$verify(that.$reader_style($.extend(data.style, labelWidth ? { 'margin-left': labelWidth } : {})), 'style') + '>' + that.$reader_form_element(data.group, index) + (help ? '<div class="c9 mt5 ' + _that.$verify(help['class'], 'class') + '" ' + _that.$verify(that.$reader_style(help.style), 'style') + '>' + help.list.join('</br>') + '</div>' : '') + '</div>' + '</div>' ); } catch (error) { console.log(error); } }, /** * @description 渲染form类型 * @param {object} data 表单数据 * @param {number} index 下标 * @return {string} HTML结构 */ $reader_form_element: function (data, index) { var that = this, html = ''; if (!Array.isArray(data)) data = [data]; $.each(data, function (key, item) { item.find_index = index; html += that.$reader_form_find(item); that.form_config[item.name] = item; }); return html; }, /** * @descripttion 渲染单个表单元素 * @param {Object} item 配置 * @return: viod */ $reader_form_find: function (item) { var that = this, html = '', style = that.$reader_style(item.style) + _that.$verify(item.width, 'width', 'style'), attribute = that.$verify_group(item, ['name', 'placeholder', 'disabled', 'readonly', 'autofocus', 'autocomplete', 'min', 'max']), event_group = that.$create_event_config(item), eventName = '', index = item.find_index; if (item.display === false) return html; html += item.label ? '<span class="mr5 inlineBlock">' + item.label + '</span>' : ''; if (typeof item['name'] !== 'undefined') { that.$check_event_bind(item.name, event_group); } html += '<div class="' + (item.dispaly || 'inlineBlock') + ' ' + _that.$verify(item.hide, 'hide', true) + ' ' + (item['class'] || '') + '">'; var _value = typeof that.data[item.name] !== 'undefined' && that.data[item.name] != '' ? that.data[item.name] : item.value || ''; switch (item.type) { case 'text': // 文本选择 case 'checkbox': // 复选框 case 'password': // 密码 case 'radio': // 单选框 case 'number': // 数字 var _event = 'event_' + item.name + '_' + that.random; switch (item.type) { case 'checkbox': // 复选框 html += '<label class="cursor-pointer form-checkbox-label" ' + _that.$verify(that.$reader_style(item.style), 'style') + '><i class="form-checkbox cust—checkbox cursor-pointer mr5 ' + _event + '_label ' + (_value ? 'active' : '') + '"></i><input type="checkbox" class="form—checkbox-input hide mr10 ' + _event + '" name="' + item.name + '" ' + (_value ? 'checked' : '') + '/><span class="vertical_middle">' + item.title + '</span></label>'; if (typeof item.disabled != 'undefined' && item.disabled) { //禁止复选框 同时可设置class:'check_disabled',使鼠标手为禁止状态 } else { that.$check_event_bind(_event + '_label', { click: { type: 'checkbox_icon', config: item }, }); that.$check_event_bind(_event, { input: { type: 'checkbox', config: item, event: item.event, }, }); } break; case 'radio': $.each(item.list, function (keys, rItem) { var radioRandom = _event + '_radio_' + keys; html += '<span class="form-radio"><input type="radio" name="' + item.name + '" ' + (_value == rItem.value ? 'checked' : '') + ' id="' + radioRandom + '" class="' + radioRandom + '" value="' + rItem.value + '"><label for="' + radioRandom + '" class="mb0">' + rItem.title + '</span>'; that.$check_event_bind(radioRandom, { input: { type: 'radio', config: item, event: item.event } }); }); break; default: html += '<input type="' + item.type + '"' + attribute + ' ' + (item.icon ? 'id="' + _event + '"' : '') + ' class="bt-input-' + (item.type !== 'select_path' && item.type !== 'number' && item.type !== 'password' ? item.type : 'text') + ' mr10 ' + (item.label ? 'vertical_middle' : '') + _that.$verify(item['class']) + '"' + _that.$verify(style, 'style') + ' value="' + _value + '"/>'; break; } if (item.btn && !item.disabled) { html += '<span class="btn ' + item.btn.type + ' ' + item.name + '_btn cursor" ' + _that.$verify(that.$reader_style(item.btn.style), 'style') + '>' + item.btn.title + '</span>'; if (typeof item.btn.event !== 'undefined') { that.$check_event_bind(item.name + '_btn', { click: { config: item, event: item.btn.event, }, }); } } if (item.icon) { html += '<span class="glyphicon ' + item.icon.type + ' ' + item.name + '_icon cursor ' + (item.disabled ? 'hide' : '') + ' mr10" ' + _that.$verify(that.$reader_style(item.icon.style), 'style') + '></span>'; if (typeof item.icon.event !== 'undefined') { that.$check_event_bind(item.name + '_icon', { click: { type: 'select_path', select: item.icon.select || '', config: item, children: '.' + item.name + '_icon', event: item.icon.event, callback: item.icon.callback, }, }); } } break; case 'textarea': html += '<textarea class="bt-input-text"' + _that.$verify(style, 'style') + attribute + ' >' + _value + '</textarea>'; $.each(['blur', 'focus', 'input'], function (index, items) { if (item.tips) { var added = null, event = {}; switch (items) { case 'blur': added = function (ev, item, element) { if ($(this).val() === '') $(this).next().show(); layer.close(item.tips.loadT); $(ev.target).data('layer', ''); }; break; case 'focus': added = function (ev, item) { $(this).next().hide(); item.tips.loadT = layer.tips(tips, $(this), { tips: [1, '#20a53a'], time: 0, area: $(this).width(), }); }; break; } } that.event_list[item.name][items] ? (that.event_list[item.name][items]['added'] = added) : (that.event_list[item.name][items] = { type: item.type, cust: false, event: item[items], added: added, }); }); if (item.tips) { var tips = ''; if (typeof item.tips.list === 'undefined') { tips = item.tips.text; } else { tips = item.tips.list.join('</br>'); } html += '<div class="placeholder c9 ' + item.name + '_tips" ' + _that.$verify(that.$reader_style(item.tips.style), 'style') + '>' + tips + '</div>'; that.$check_event_bind(item.name + '_tips', { click: { type: 'textarea_tips', config: item, }, }); } break; case 'multipleSelect': // 使用规则 【配置中必须含有value字段(无需默认值设置空数组)、需要选中的下拉项以数组逗号隔开】 html += that.$reader_multipleSelect(item, style, attribute, index); that.$check_event_bind('custom_select', { click: { type: 'custom_select', children: '.bt_select_value', }, }); that.$check_event_bind('custom_select_item', { click: { type: 'custom_select_item', children: 'li.item', }, }); that.$check_event_bind('icon_trem_close', { click: { type: 'icon_trem_close', children: '.icon-trem-close', }, }); break; case 'secondaryMenu': //下拉二级菜单 html += that.$reader_secondaryMenu(item, style, attribute, index); that.$check_event_bind('secondary_menu_parent', { 'mouseover click': { type: 'secondary_menu_parent', children: '.item-parent', }, }); that.$check_event_bind('secondary_menu_child', { click: { type: 'secondary_menu_child', children: '.item-child', }, }); break; case 'select': html += that.$reader_select(item, style, attribute, index); that.$check_event_bind('custom_select', { click: { type: 'custom_select', children: '.bt_select_value', }, }); that.$check_event_bind('custom_select_item', { click: { type: 'custom_select_item', children: 'li.item', }, }); break; case 'link': eventName = 'event_link_' + that.random + '_' + item.name; html += '<a href="' + (item.href || 'javascript:;') + '" class="btlink ' + eventName + '" ' + _that.$verify(that.$reader_style(item.style), 'style') + '>' + item.title + '</a>'; that.$check_event_bind(eventName, { click: { type: 'link_event', event: item.event, }, }); break; case 'button': html += // '<button class="btn btn-success btn-' + '<button class="btn ' + (item.hasOwnProperty('active') ? (item.active ? 'btn-success' : 'btn-default') : 'btn-success ') + ' btn-' + (item.size || 'sm ') + ' ' + eventName + ' ' + _that.$verify(item['class']) + '" ' + _that.$verify(that.$reader_style(item.style), 'style') + ' ' + attribute + '>' + item.title + '</button>'; break; case 'help': var _html = ''; $.each(item.list, function (index, items) { _html += '<li>' + items + '</li>'; }); html += '<ul class="help-info-text c7' + _that.$verify(item['class']) + '"' + _that.$verify(that.$reader_style(item.style), 'style') + ' ' + attribute + '>' + _html + '</ul>'; break; case 'other': html += item.boxcontent; } html += item.unit ? '<span class="' + (item.type === 'text-tips' ? 'text-tips' : 'unit') + '">' + item.unit + '</span>' : ''; html += item.suffix ? '<span class="text-tips ml10" ' + (item.type === 'select') + '>' + item.suffix + '</span>' : ''; html += '</div>'; return html; }, /** * @descripttion 检测检测名称 * @param {string} eventName 配置 * @param {object} config 事件配置 */ $check_event_bind: function (eventName, config) { if (!this.event_list[eventName]) { if (!this.event_list.hasOwnProperty(eventName)) { this.event_list[eventName] = config; } } }, /** * @description 创建事件配置 * @param {object} item 行内配置 * @return {object} 配置信息 */ $create_event_config: function (item) { var config = {}; if (typeof item['name'] === 'undefined') return {}; $.each(this.event_type, function (key, items) { if (item[items]) { config[items === 'event' ? 'click' : items] = { type: item.type, event: item[items], cust: ['select', 'checkbox', 'radio'].indexOf(item.type) > -1, config: item, }; } }); return config; }, /** * @description 渲染样式 * @param {object|string} data 样式配置 * @return {string} 样式 */ $reader_style: function (data) { var style = ''; if (typeof data === 'string') return data; if (typeof data === 'undefined') return ''; $.each(data, function (key, item) { style += key + ':' + item + ';'; }); return style; }, /** * @descripttion 局部刷新form表单元素 * @param {String} name 需要刷新的元素 * @param {String} name 元素新数据 * @return: viod */ $local_refresh: function (name, config) { var formFind = this.element.find('[data-name=' + name + ']'); if (this.element.find('[data-name=' + name + ']').length === 0) formFind = this.element.find('[name=' + name + ']'); formFind.parent().replaceWith(this.$reader_form_find(config)); }, /** * @description 渲染下拉,内容方法 */ $reader_select: function (item, style, attribute, index) { var that = this, list = '', option = '', active = {}; if (typeof item.list === 'function') { var event = item.list; event.call(this, this.config.form); item.list = []; } if (!Array.isArray(item.list)) { var config = item.list; bt_tools.send( { url: config.url, data: config.param || config.data || {}, }, function (res) { if (res.status !== false) { var list = item.list.dataFilter ? item.list.dataFilter(res, that) : res; if (item.list.success) item.list.success(res, that, that.config.form[index], list); item.list = list; if (!item.list.length) { item.disabled = true; layer.msg(item.placeholder || '数据获取为空', { icon: 2 }); } that.$replace_render_content(index); } else { bt.msg(res); } } ); return false; } if (typeof that.data[item.name] === 'undefined') active = item.list[0]; $.each(item.list, function (key, items) { if (items.value === item.value || items.value === that.data[item.name]) { active = items; return false; } }); $.each(item.list, function (key, items) { list += '<li class="item' + _that.$verify(items.value === active.value ? 'active' : '') + ' ' + (items.disabled ? 'disabled' : '') + '" title="' + items.title + '">' + items.title + '</li>'; option += '<option value="' + items.value + '"' + (items.disabled ? 'disabled' : '') + ' ' + _that.$verify(items.value === active.value ? 'selected' : '') + '>' + items.title + '</option>'; }); var title = !Array.isArray(item.list) ? 'Getting data...' : active ? active.title : item.placeholder; return ( '<div class="bt_select_updown mr10 ' + (item.disabled ? 'bt-disabled' : '') + ' ' + _that.$verify(item['class']) + '" ' + _that.$verify(style, 'style') + ' data-name="' + item.name + '">' + '<span class="bt_select_value"><span class="bt_select_content" title="' + (title || item.placeholder) + '">' + (title || item.placeholder) + '</span><span class="glyphicon glyphicon-triangle-bottom ml5"></span></span>' + '<ul class="bt_select_list">' + (list || '') + '</ul>' + '<select' + attribute + ' class="hide" ' + (item.disabled ? 'disabled' : '') + ' autocomplete="off">' + (option || '') + '</select>' + '</div>' ); }, /** * @description 渲染多选下拉,内容方法 */ $reader_multipleSelect: function (item, style, attribute, index) { var that = this, list = '', option = '', active = {}, mulpActive = [], str = ''; if (typeof item.list === 'function') { var event = item.list; event.call(this, this.config.form); item.list = []; } if ($.isArray(item.value)) { mulpActive = item.value; } else { if (!Array.isArray(item.list)) { var config = item.list; bt_tools.send( { url: config.url, data: config.param || config.data || {}, }, function (res) { if (res.status !== false) { var list = item.list.dataFilter ? item.list.dataFilter(res, that) : res; if (item.list.success) item.list.success(res, that, that.config.form[index], list); item.list = list; if (!item.list.length) { item.disabled = true; layer.msg(item.placeholder || '数据获取为空', { icon: 2 }); } that.$replace_render_content(index); } else { bt.msg(res); } } ); return false; } if (typeof that.data[item.name] === 'undefined') active = item.list[0]; $.each(item.list, function (key, items) { if (items.value === item.value || items.value === that.data[item.name]) { active = items; return false; } }); } $.each(item.list, function (key, items) { if ($.isArray(item.value)) { for (var i = 0; i < mulpActive.length; i++) { if (mulpActive.indexOf(items.value) > -1) { active.value = items.value; } } } list += '<li class="item item1' + _that.$verify(items.value === active.value ? 'active' : '') + ' ' + (items.disabled ? 'disabled' : '') + '" title="' + items.title + '">\ <span>' + items.title + '</span>\ <span class="icon-item-active"></span>\ </li>'; option += '<option value="' + items.value + '"' + (items.disabled ? 'disabled' : '') + ' ' + _that.$verify(items.value === active.value ? 'selected' : '') + '>' + items.title + '</option>'; }); for (var i = 0; i < item.list.length; i++) { if (mulpActive.indexOf(item.list[i].value) > -1) { str += '<span class="bt_select_content"><span>' + item.list[i].title + '</span><span class="icon-trem-close"></span></span>'; } } var title = !Array.isArray(item.list) ? '获取数据中' : active ? active.title : item.placeholder; return ( '<div class="bt_multiple_select_updown bt_select_updown mr10 ' + (item.disabled ? 'bt-disabled' : '') + ' ' + +_that.$verify(item['class']) + '" ' + _that.$verify(style, 'style') + ' data-name="' + item.name + '">' + '<span class="bt_select_value">' + (item.value.length == 0 ? '<span class="bt_select_content"><span>' + (title || item.placeholder) + '</span><span class="icon-trem-close"></span></span>' : str) + '<div class="icon-down"><svg width="12.000000" height="12.000000" viewBox="0 0 12 5" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><desc>Created with Pixso.</desc><defs></defs><path id="path" d="M0.123291 0.809418L4.71558 5.84385C4.8786 6.02302 5.16846 6.04432 5.33038 5.86389L9.87927 0.783104C10.0412 0.602676 10.04 0.311989 9.87701 0.132816C9.79626 0.0446892 9.68945 0 9.58374 0C9.47693 0 9.36938 0.0459404 9.28827 0.136574L5.02881 4.89284L0.708618 0.15662C0.627869 0.0684967 0.522217 0.0238075 0.415405 0.0238075C0.307434 0.0238075 0.20105 0.0697479 0.119873 0.160381C-0.041626 0.338303 -0.0393677 0.630241 0.123291 0.809418Z" fill-rule="nonzero" fill="#999999"></path></svg></div>\ </span>' + '<ul class="bt_select_list">' + (list || '') + '</ul>' + '<select' + attribute + ' class="hide" ' + (item.disabled ? 'disabled' : '') + ' autocomplete="off" multiple>' + (option || '') + '</select>' + '<div class="bt_select_list_arrow"></div><div class="bt_select_list_arrow_fff"></div>' + '</div>' ); }, /** * @description 渲染二级下拉 */ $reader_secondaryMenu: function (item, style, attribute, index) { // 规则限制 【通过配置中的data.xx值设置为空,可清除上次选中的内容】 // 1.不可通过请求数据来渲染 // 2.至少有一个一级内容,一级下拉不可点击 var that = this, list = '', active = {}; $.each(item.list, function (key, items) { list += '<li class="item-parent"><div class="item-menu-title" style="' + (function () { for (var i = 0; i < items.child.length; i++) { if (items.child[i].value == item.value || items.child[i].value == that.data[item.name]) { active = items.child[i]; } if (items.child[i].value === active.value) { return 'color:#20a53a;'; } } })() + '">' + items.title + '</div>' + (function () { var _con = ''; if (items.child.length > 0) { _con = '\ <svg style="margin-right: 10px;fill:#999999;" width="5.989136" height="10.000000" viewBox="0 0 5.98914 10" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\ \t<desc>\ \t\t\tCreated with Pixso.\ \t</desc>\ \t<defs/>\ \t<path id="path" d="M0.809448 9.87672L5.84387 5.28442C6.02307 5.12138 6.04431 4.83153 5.86389 4.66962L0.783081 0.120728C0.602661 -0.0411835 0.312012 -0.0400543 0.132812 0.122986C0.0446777 0.203751 0 0.310562 0 0.416229C0 0.523041 0.0458984 0.6306 0.136597 0.711746L4.89282 4.97118L0.156616 9.29137C0.0684814 9.37213 0.0238037 9.4778 0.0238037 9.58461C0.0238037 9.69255 0.0697021 9.79898 0.1604 9.88011C0.338257 10.0416 0.630249 10.0394 0.809448 9.87672Z" fill-rule="nonzero" />\ </svg><div class="item-menu-body-list">\ <ul class="">' + (function () { var str = ''; $.each(items.child, function (key, child) { str += '<li class="item-child' + _that.$verify(child.value === active.value ? 'active' : '') + '" title="' + child.title + '" data-value="' + child.value + '"><div class="item-menu-title">' + child.title + '</div></li>'; }); return str; })() + '</ul></div>'; } else { _con = '<span style="top: 0;color: #ccc;">[空]</span>'; } return _con; })() + '</li>'; }); return ( '<div class="bt_select_updown bt_seconday_menu" ' + _that.$verify(style, 'style') + ' data-name="' + item.name + '">\ <span class="bt_select_value"><span class="bt_select_content">' + (!$.isEmptyObject(active) ? active.title : item.placeholder) + '</span>\ <div class="icon-down"><svg width="12.000000" height="12.000000" viewBox="0 0 12 5" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><desc>Created with Pixso.</desc><defs></defs><path id="path" d="M0.123291 0.809418L4.71558 5.84385C4.8786 6.02302 5.16846 6.04432 5.33038 5.86389L9.87927 0.783104C10.0412 0.602676 10.04 0.311989 9.87701 0.132816C9.79626 0.0446892 9.68945 0 9.58374 0C9.47693 0 9.36938 0.0459404 9.28827 0.136574L5.02881 4.89284L0.708618 0.15662C0.627869 0.0684967 0.522217 0.0238075 0.415405 0.0238075C0.307434 0.0238075 0.20105 0.0697479 0.119873 0.160381C-0.041626 0.338303 -0.0393677 0.630241 0.123291 0.809418Z" fill-rule="nonzero" fill="#999999"></path></svg></div>\ </span>\ <ul class="bt_select_list">' + list + '</ul>\ <input ' + attribute + ' class="hide" value="' + (active.value || '') + '">\ <div class="bt_select_list_arrow"></div><div class="bt_select_list_arrow_fff"></div>\ </div>' ); }, /** * @description 替换渲染内容 */ $replace_render_content: function (index) { var that = this, config = this.config.form[index], html = that.$reader_content_row(index, config); $('[data-form=' + that.random + ']') .find('.line:eq(' + index + ')') .replaceWith(html); this.$event_bind(); }, /** * @description 重新渲染内容 * @param {object} formConfig 配置 */ $again_render_form: function (formConfig) { var formElement = $('[data-form=' + this.random + ']'), that = this; formConfig = formConfig || this.config.form; formElement.empty(); for (var i = 0; i < formConfig.length; i++) { var config = formConfig[i]; if (config.display === false) continue; formElement.append(that.$reader_content_row(i, config)); } this.config.form = formConfig; this.$event_bind(); // 处理复选框重新渲染第一次点击无效 formElement.find('.form-checkbox-label').click(); formElement.find('.form-checkbox-label').click(); }, /** * @description 事件绑定功能 * @param {Object} eventList 事件列表 * @param {Function} callback 回调函数 * @return void */ $event_bind: function (eventList, callback) { var that = this, _event = {}; that.element = $(typeof eventList === 'object' ? that.element : '[data-form=' + that.random + ']'); _event = eventList; if (typeof eventList === 'undefined') _event = that.event_list; $.each(_event, function (key, item) { if ($.isEmptyObject(item)) return true; $.each(item, function (keys, items) { if (!!item.type) return false; if (!items.hasOwnProperty('bind')) { items.bind = true; } else { return false; } var childNode = ''; if (typeof items.cust === 'boolean') { childNode = '[' + (items.cust ? 'data-' : '') + 'name=' + key + ']'; } else { childNode = '.' + key; } (function (items, key) { if (items.onEvent === false) { switch (items.type) { case 'input_checked': $(childNode).on(keys != 'event' ? keys : 'click', function (ev) { items.event.apply(this, [ev, that]); }); break; } return true; } else { if (items.type === 'select') return true; that.element.on(keys !== 'event' ? keys : 'click', items.children ? items.children : childNode, function (ev) { var form = that.$get_form_element(true), config = that.form_config[key]; switch (items.type) { case 'textarea_tips': $(this).hide().prev().focus(); break; case 'custom_select': if ($(this).parent().hasClass('bt-disabled')) return false; var select_value = $(this).next(); if (!select_value.hasClass('show')) { // var $target = $(ev.currentTarget); // var $layer = $target.parents('.layui-layer'); // var layerTop = $layer.length > 0 ? parseFloat($layer.css('top')) : 0; // var layerLeft = $layer.length > 0 ? parseFloat($layer.css('left')) : 0; // var offset = $target[0].getBoundingClientRect(); // var top = offset.top - layerTop + offset.height + 2; // var left = offset.left - layerLeft; // $('.bt_select_list').css({ // position: 'fixed', // width: offset.width + 'px', // top: top + 'px', // left: left + 'px', // }); $('.bt_select_list').removeClass('show'); select_value.addClass('show'); } else { select_value.removeClass('show'); } $(document).click(function () { that.element.find('.bt_select_list').removeClass('show'); $(this).unbind('click'); return false; }); return false; break; case 'custom_select_item': config = that.form_config[$(this).parents('.bt_select_updown').attr('data-name')]; var item_config = config.list[$(this).index()]; var item = $(this).parent().find('.item'), arry = [], _html = '', mulpVal = []; if ($(this).hasClass('disabled')) { $(this).parent().removeClass('show'); if (item_config.tips) layer.msg(item_config.tips, { icon: 2 }); return true; } if (!$(this).hasClass('active') && !$(this).hasClass('disabled')) { var value = item_config.value.toString(); $(this).parent().prev().find('.bt_select_content').text($(this).text()); $(this).parent().prev().find('.bt_select_content').prop('title', $(this).text()); if (config.type != 'multipleSelect') { $(this).addClass('active').siblings().removeClass('active'); $(this).parent().next().val(value); $(this).parent().slideUp('fast'); $(this).parent().removeClass('show'); $('.bt_select_list_arrow').fadeOut(200); $('.bt_select_list_arrow_fff').fadeOut(200); } else { $(this).addClass('active'); } } else { if (config.type == 'multipleSelect') { // if($(this).parent().find('.active').length <= 1) return layer.msg('最少选择一个!!!') $(this).removeClass('active'); } } if (config.type == 'multipleSelect') { for (var i = 0; i < item.length; i++) { if (item.eq(i).hasClass('active')) { arry.push(item.eq(i).text().trim().replace(/\s/g, '')); } } for (var i = 0; i < config.list.length; i++) { if (arry.indexOf(config.list[i].title.trim().replace(/\s/g, '')) > -1) { mulpVal.push(config.list[i].value); } } if (arry.length == 0) { _html += '<span class="bt_select_content_def">' + config.placeholder + '</span>'; } else { $(this).parent().prev().find('.bt_select_content_def').remove(); for (var i = 0; i < arry.length; i++) { _html += '<span class="bt_select_content"><span>' + arry[i] + '</span><span class="icon-trem-close"></span></span>'; } } $(this).parent().prev().find('.bt_select_content').remove(); $(this).parent().prev().find('.icon-down').before(_html); $(this).parent().next().val(mulpVal); var height = $(this).parent().parent().parent().height(); $(this) .parent() .parent() .parent() .parent() .siblings() .css({ height: height + 'px', 'line-height': height + 'px', }); $(this) .parent() .css('top', height + 12 + 'px'); $('.bt_select_list_arrow_fff').css('top', height - 3 + 'px'); $('.bt_select_list_arrow').css('top', height - 4 + 'px'); } $('.icon-trem-close').click(function () { var str = $(this).siblings().text().trim().replace(/\s/g, ''); for (var i = 0; i < item.length; i++) { if (str == item.eq(i).prop('title')) { item.eq(i).click(); } } return false; }); that.data[config.name] = config.type == 'multipleSelect' ? mulpVal : value; if (items.event) items.event = null; if (config.change) items.event = config.change; ev.stopPropagation(); break; case 'icon_trem_close': var str = $(this).siblings().text().trim().replace(/\s/g, ''), item = $(this).parent().parent().siblings('.bt_select_list').find('.item'); for (var i = 0; i < item.length; i++) { if (str == item.eq(i).prop('title')) { item.eq(i).click(); } } return false; break; case 'secondary_menu_parent': $('.item-menu-title').removeAttr('style'); $(this).addClass('down').siblings().removeClass('down').find('.item-menu-body-list').removeClass('show'); $(this).siblings().children('svg').css('fill', '#999999'); $('.down').children('svg').css('fill', '#666666'); if ($(this).find('.item-menu-body-list').length > 0) { $(this).find('.item-menu-body-list').addClass('show').parent().siblings().find('.item-menu-body-list').removeClass('show'); } ev.stopPropagation(); break; case 'secondary_menu_child': var _value = $(this).attr('data-value'); config = that.form_config[$(this).parents('.bt_select_updown').attr('data-name')]; that.data[config.name] = _value; if (items.event) items.event = null; if (config.change) items.event = config.change; ev.stopPropagation(); break; case 'select_path': bt.select_path('event_' + $(this).prev().attr('name') + '_' + that.random, items.select || '', !items.callback || items.callback.bind(that), items.defaultPath || ''); break; case 'checkbox': var checked = $(this).is(':checked'); if (checked) { $(this).prev().addClass('active'); } else { $(this).prev().removeClass('active'); } break; } if (items.event) items.event.apply(this, [that.$get_form_value(), form, that, config, ev]); // 事件 if (items.added) items.added.apply(this, [ev, config, form]); }); } })(items, key); }); }); if (callback) callback(); }, /** * @description 获取表单数据 * @return {object} 表单数据 */ $get_form_value: function () { var form = {}, ev = this.element; ev.find('input,textarea[disabled="disabled"]').each(function (index, item) { var val = $(this).val(); if ($(this).attr('type') === 'checkbox') { val = $(this).prop('checked'); } if ($(this).attr('type') === 'radio') { val = ev.find('input[name=' + $(this).attr('name') + ']:radio:checked').val(); } form[$(this).attr('name')] = val; }); return $.extend({}, ev.serializeObject(), form); }, /** * @description 设置指定数据 * */ $set_find_value: function (name, value) { var config = {}, that = this; typeof name != 'string' ? (config = name) : (config[name] = value); $.each(config, function (key, item) { that.form_element[key].val(item); }); }, /** * @description 获取Form,jquery节点 * @param {Boolean} afresh 是否强制刷新 * @return {object} */ $get_form_element: function (afresh) { var form = {}, that = this; if (afresh || $.isEmptyObject(that.form_element)) { this.element.find(':input').each(function (index) { form[$(this).attr('name')] = $(this); }); that.form_element = form; return form; } else { return that.form_element; } }, /** * @description 验证值整个列表是否存在,存在则转换成属性字符串格式 */ $verify_group: function (config, group) { var that = this, str = ''; $.each(group, function (index, item) { if (typeof config[item] === 'undefined') return true; if (['disabled', 'readonly'].indexOf(item) > -1) { str += ' ' + (config[item] ? item + '="' + item + '"' : ''); } else { str += ' ' + item + '="' + config[item] + '"'; } }); return str; }, /** * @description 验证绑定事件 * @param {String} value */ $verify_bind_event: function (eventName, row, group) { var event_list = {}; $.each(group, function (index, items) { var event_fun = row[items]; if (event_fun) { if (typeof event_list[eventName] === 'object') { if (!Array.isArray(event_list[eventName])) event_list[eventName] = [event_list[eventName]]; event_list[eventName].push({ event: event_fun, eventType: items, }); } else { event_list[eventName] = { event: event_fun, eventType: items, }; } } }); return event_list; }, /** * @description 验证值是否存在 * @param {String} value 内容/值 * @param {String|Boolean} attr 属性 * @param {String} type 属性 */ $verify: function (value, attr, type) { if (!value) return ''; if (type === true) return value ? ' ' + attr : ''; if (type === 'style') return attr ? attr + ':' + value + ';' : value; return attr ? ' ' + attr + '="' + value + '"' : ' ' + value; }, /** * @description 验证form表单 */ $verify_form: function () { var form_list = {}, form = this.config.form, form_value = this.$get_form_value(), form_element = this.$get_form_element(true), is_verify = true; for (var key = 0; key < form.length; key++) { var item = form[key]; if (!Array.isArray(item.group)) item.group = [item.group]; if (item.separate) continue; for (var i = 0; i < item.group.length; i++) { var items = item.group[i], name = items.name; if (items.type === 'help') continue; if (typeof items.verify == 'function') { var is_verify = items.verify(form_value[name], form_element[name], items, true); is_verify = typeof is_verify == 'boolean' ? false : true; } } } if (!is_verify) return is_verify; return form_value; }, /** * @description 提交内容,需要传入url * @param {Object|Function} param 附加参数或回调函数 * @param {Function} callback 回调 */ $submit: function (param, callback, tips) { var form = this.$verify_form(); if (typeof param === 'function') (tips = callback), (callback = param), (param = {}); if (!form) return false; form = $.extend(form, param); if (typeof this.config.url == 'undefined') { bt_tools.msg('Request Submission address cannot be empty!', false); return false; } bt_tools.send( { url: this.config.url, data: form, }, function (res) { if (callback) { callback(res, form); } else { bt_tools.msg(res); } }, tips || 'Submit' ); }, }; return new ReaderForm(config); }, /** * @description tab切换,支持三种模式 * @param {object} config * @return 当前实例对象 */ tab: function (config) { var _that = this; function ReaderTab(config) { this.config = config; this.theme = this.config.theme || {}; this.$load(); } ReaderTab.prototype = { type: 1, theme_list: [ { content: 'tab-body', nav: 'tab-nav', body: 'tab-con', active: 'on', }, { content: 'bt-w-body', nav: 'bt-w-menu', body: 'bt-w-con', }, ], random: bt.get_random(5), $init: function () { var that = this, active = this.config.active, config = that.config.list, _theme = {}; this.$event_bind(); if (config[that.active].success) config[that.active].success(); config[that.active]['init'] = true; }, $load: function () { var that = this; }, $reader_content: function () { var that = this, _list = that.config.list, _tab = '', _tab_con = '', _theme = that.theme, config = that.config; if (typeof that.active === 'undefined') that.active = 0; if (!$.isEmptyObject(config.theme)) { _theme = this.theme_list[that.active]; $.each(config.theme, function (key, item) { if (_theme[key]) _theme[key] += ' ' + item; }); that.theme = _theme; } if (config.type && $.isEmptyObject(config.theme)) this.theme = this.theme_list[that.active]; $.each(_list, function (index, item) { var active = that.active === index, _active = _theme['active'] || 'active'; _tab += '<span class="' + (active ? _active : '') + '">' + item.title + '</span>'; _tab_con += '<div class="tab-block ' + (active ? _active : '') + '">' + (active ? item.content : '') + '</div>'; }); that.element = $( '<div id="tab_' + that.random + '" class="' + _theme['content'] + _that.$verify(that.config['class']) + '"><div class="' + _theme['nav'] + '" >' + _tab + '</div><div class="' + _theme['body'] + '">' + _tab_con + '</div></div>' ); return that.element[0].outerHTML; }, /** * @description 事件绑定 * */ $event_bind: function () { var that = this, _theme = that.theme, active = _theme['active'] || 'active'; if (!that.el) that.element = $('#tab_' + that.random); that.element.on('click', '.' + _theme['nav'].replace(/\s+/g, '.') + ' span', function () { var index = $(this).index(), config = that.config.list[index]; $(this).addClass(active).siblings().removeClass(active); $('#tab_' + that.random + ' .' + _theme['body'] + '>div:eq(' + index + ')') .addClass(active) .siblings() .removeClass(active); that.active = index; if (!config.init) { // console.log(_theme) var contentItem = $('#tab_' + that.random + ' .' + _theme['body'] + '>div:eq(' + index + ')'); contentItem.html(config.content); if (config.success) config.success(contentItem); config.init = true; } }); }, }; return new ReaderTab(config); }, /** * @description loading过渡 * @param {*} title * @param {*} is_icon * @return void */ load: function (title) { var random = bt.get_random(5), layel = $( '<div class="layui-layer layui-layer-dialog layui-layer-msg layer-anim" id="' + random + '" type="dialog" style="z-index: 99891031;"><div class="layui-layer-content layui-layer-padding"><i class="layui-layer-ico layui-layer-ico16"></i>' + title + ',please wait...</div><span class="layui-layer-setwin"></span></div><div class="layui-layer-shade" id="layer-mask-' + random + '" times="17" style="z-index:99891000; background-color:#000; opacity:0.3; filter:alpha(opacity=30);"></div>' ), mask = '', loadT = ''; $('body').append(layel); var win = $(window), msak = $('.layer-loading-mask'), layel = $('#' + random); layel.css({ top: (win.height() - 64) / 2, left: (win.width() - 320) / 2 }); if (title === true) loadT = layer.load(); return { close: function () { if (typeof loadT == 'number') { layer.close(loadT); } else { $('body') .find('#' + random + ',#layer-mask-' + random) .remove(); } }, }; }, /** * @description 弹窗方法,有默认的参数和重构的参数 * @param {object} config 和layer参数一致 * @require 当前关闭弹窗方法 */ open: function (config) { var _config = {}, layerT = null, form = null; _config = $.extend({ type: 1, area: '640px', closeBtn: 2, btn: ['Yes', 'No'] }, config); if (typeof _config.content == 'object') { var param = _config.content; form = bt_tools.form(param); _config.success = function (layero, indexs) { form.$event_bind(); if (typeof config.success != 'undefined') config.success(layero, indexs); }; _config.yes = function (indexs, layero) { var form_val = form.$verify_form(); if (!form_val) return false; if (typeof config.yes != 'undefined') { var yes = config.yes.apply(form, [form_val, indexs, layero]); if (!yes) return false; } }; _config.content = form.$reader_content(); } layerT = layer.open(_config); return { close: function () { layer.close(layerT); }, form: form, }; }, /** * @description 封装msg方法 * @param {object|string} param1 配置参数,请求方法参数 * @param {number} param2 图标ID * @require 当前关闭弹窗方法 */ msg: function (param1, param2) { var layerT = null, msg = '', config = {}; if (typeof param1 === 'object') { if (typeof param1.status === 'boolean') { (msg = param1.msg), (config = { icon: param1.status ? 1 : 2 }); if (!param1.status) config = $.extend(config, { time: !param2 ? 0 : 3000, closeBtn: 2, shade: 0.3 }); } } if (typeof param1 === 'string') { (msg = param1), (config = { icon: typeof param2 !== 'undefined' ? param2 : 1, }); } layerT = layer.msg(msg, config); return { close: function () { layer.close(layerT); }, }; }, /** * @description 成功提示 * @param {string} msg 信息 */ success: function (msg) { this.msg({ msg: msg, status: true }); }, /** * @description 错误提示 * @param {string} msg 信息 */ error: function (msg) { this.msg({ msg: msg, status: false }); }, /** * @description 请求封装 * @param {string|object} conifg ajax配置参数/请求地址 * @param {function|object} callback 回调函数/请求参数 * @param {function} callback1 回调函数/可为空 * @returns void 无 */ send: function (param1, param2, param3, param4, param5, param6) { var params = {}, success = null, error = null, config = [], param_one = ''; $.each(arguments, function (index, items) { config.push([items, typeof items]); }); function diff_data(i) { try { success = config[i][1] == 'function' ? config[i][0] : null; error = config[i + 1][1] == 'function' ? config[i + 1][0] : null; } catch (error) {} } param_one = config[0]; switch (param_one[1]) { case 'string': $.each(config, function (index, items) { var value = items[0], type = items[1]; if (index > 1 && (type == 'boolean' || type == 'string' || type == 'object')) { var arry = param_one[0].split('/'); params['url'] = '/' + arry[0] + '?action=' + arry[1]; if (type == 'object') { params['load'] = value.load; params['verify'] = value.verify; if (value.plugin) params['url'] = '/plugin?action=a&name=' + arry[0] + '&s=' + arry[1]; } else if (type == 'string') { params['load'] = value; } return false; } else { params['url'] = param_one[0]; } }); if (config[1][1] === 'object') { params['data'] = config[1][0]; diff_data(2); } else { diff_data(1); } break; case 'object': params['url'] = param_one[0].url; params['data'] = param_one[0].data || {}; $.each(config, function (index, items) { var value = items[0], type = items[1]; if (index > 1 && (type == 'boolean' || type == 'string' || type == 'object')) { switch (type) { case 'object': params['load'] = value.load; params['verify'] = value.verify; break; case 'string': params['load'] = value; break; } return true; } }); if (config[1][1] === 'object') { params['data'] = config[1][0]; diff_data(2); } else { diff_data(1); } break; } if (params.load) params.load = this.load(params.load); $.ajax({ type: params.type || 'POST', url: params.url, data: params.data || {}, dataType: params.dataType || 'JSON', complete: function (res) { if (params.load) params.load.close(); }, success: function (res) { if (typeof params.verify == 'boolean' && !params.verify) { if (success) success(res); return false; } if (typeof res === 'string') { layer.msg(res, { icon: 2, time: 0, closeBtn: 2, }); return false; } if (params.batch) { if (success) success(res); return false; } if (res.status === false && (res.hasOwnProperty('msg') || res.hasOwnProperty('error_msg'))) { if (error) { error(res); } else { bt_tools.msg({ status: res.status, msg: !res.hasOwnProperty('msg') ? res.error_msg : res.msg }); } return false; } if (params.tips) { bt_tools.msg(res); } if (success) success(res); }, }); }, /** * @description 命令行输入 */ command_line_output: function (config) { var _that = this, uuid = bt.get_random(15); /** * @description 渲染 * @param config * @return {object} * @constructor */ function ReaderCommand(config) { var that = this; for (var key in _that.commandConnectionPool) { var item = _that.commandConnectionPool[key], element = $(item.config.el); if (config.shell === item.config.shell && element.length) { item.el = element; return item; } } if (typeof config === 'undefined') config = {}; this.config = $.extend({ route: '/sock_shell' }, config); this.xterm_config = $.extend(this.xterm_config, this.config.xterm); this.el = $(this.config.el); this.open = config.open; this.close = config.close; this.message = config.message; if (!this.config.hasOwnProperty('el')) { _that.msg({ msg: '请输入选择器element,不可为空', status: false }); return false; } if (!this.config.hasOwnProperty('shell')) { _that.msg({ msg: '请输入命令,不可为空', status: false }); return false; } if (this.config.hasOwnProperty('time')) { setTimeout(function () { that.close_connect(); }, this.config.time); } this.init(); } ReaderCommand.prototype = { socket: null, //websocket 连接保持的对象 socketToken: null, timeout: 0, // 连接到期时间,为0代表永久有效 monitor_interval: 2000, element_detection: null, uuid: uuid, fragment: [], error: 0, // 错误次数,用于监听元素内容是否还存在 retry: 0, // 重试次数 forceExit: false, // 强制断开连接 /** * @description 程序初始化 */ init: function () { var oldUUID = bt.get_cookie('commandInputViewUUID'), that = this; if (!this.el[0]) { if (this.error > 10) return false; setTimeout(function () { that.init(); this.error++; }, 2000); return false; } this.error = 0; if (this.el[0].localName !== 'pre') { this.el.append('<pre class="command_output_pre"></pre>'); this.el = this.el.find('pre'); this.config.el = this.config.el + ' pre'; } else { this.el.addClass('command_output_pre'); } if (Array.isArray(this.config.area)) { this.el.css({ width: this.config.area[0], height: this.config.area[1] }); } else { this.el.css({ width: '100%', height: '100%' }); } if (oldUUID && typeof _that.commandConnectionPool[oldUUID] != 'undefined') { _that.commandConnectionPool[oldUUID].close_connect(); delete _that.commandConnectionPool[oldUUID]; } bt.set_cookie('commandInputViewUUID', this.uuid); this.element_detection = setInterval(function () { if (!$(that.config.el).length) { clearInterval(that.element_detection); that.forceExit = true; that.close_connect(); } }, 1 * 60 * 1000); this.set_full_screen(); this.create_websocket_connect(this.config.route, this.config.shell); this.monitor_element(); }, /** * @description 创建websocket连接 * @param {string} url websocket连接地址 * @param {string} shell 需要传递的命令 */ create_websocket_connect: function (url, shell) { var that = this; this.socket = new WebSocket((location.protocol === 'http:' ? 'ws://' : 'wss://') + location.host + url); this.socket.addEventListener('open', function (ev) { if (!this.socketToken) { var _token = document.getElementById('request_token_head').getAttribute('token'); this.socketToken = { 'x-http-token': _token }; } this.send(JSON.stringify(this.socketToken)); this.send(shell); if (that.open) that.open(); that.retry = 0; }); this.socket.addEventListener('close', function (ev) { if (!that.forceExit) { if (ev.code !== 1000 && that.retry <= 10) { that.socket = that.create_websocket_connect(that.config.route, that.config.shell); that.retry++; } if (that.close) that.close(ev); } }); this.socket.addEventListener('message', function (ws_event) { var result = ws_event.data; if (!result) return; that.refresh_data(result); if (that.message) that.message(result); }); return this.socket; }, /** * @description 设置全屏视图 */ set_full_screen: function () { // 1 }, htmlEncodeByRegExp: function (str) { if (str.length == 0) return ''; return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/ /g, ' ').replace(/\'/g, ''').replace(/\"/g, '"'); }, /** * @description 刷新Pre数据 * @param {object} data 需要插入的数据 */ refresh_data: function (data) { var data = this.htmlEncodeByRegExp(data); this.fragment.push(data); if (this.fragment.length >= 300) { this.fragment.splice(0, 150); this.el.html(this.fragment.join('')); } else { this.el.append(data); } if (this.el.length > 0) { this.el.scrollTop(this.el[0].scrollHeight); } }, /** * @description 监听元素状态,判断是否移除当前的ws连接 * */ monitor_element: function () { var that = this; this.monitor_interval = setInterval(function () { if (!that.el.length) { that.close_connect(); clearInterval(that.monitor_interval); } }, that.config.monitorTime || 2000); }, /** * @description 断开命令响应和websocket连接 */ close_connect: function () { this.socket.send(''); this.socket.close(); delete _that.commandConnectionPool[this.uuid]; }, }; this.commandConnectionPool[uuid] = new ReaderCommand(config); return this.commandConnectionPool[uuid]; }, /** * @description 清理验证提示样式 * @param {object} element 元素节点 */ $clear_verify_tips: function (element) { element.removeClass('bt-border-error bt-border-sucess'); layer.close('tips'); }, /** * @description 验证提示 * @param {object} element 元素节点 * @param {string} tips 警告提示 * @return void */ $verify_tips: function (element, tips, is_error) { if (typeof is_error === 'undefined') is_error = true; element.removeClass('bt-border-error bt-border-sucess').addClass(is_error ? 'bt-border-error' : 'bt-border-sucess'); element.focus(); layer.tips('<span class="inlineBlock">' + tips + '</span>', element, { tips: [1, is_error ? 'red' : '#20a53a'], time: 3000, area: element.width(), }); }, /** * @description 验证值是否存在 * @param {String} value 内容/值 * @param {String|Boolean} attr 属性 * @param {String} type 属性 */ $verify: function (value, attr, type) { if (!value) return ''; if (type === true) return value ? ' ' + attr : ''; if (type === 'style') return attr ? attr + ':' + value + ';' : value; return attr ? ' ' + attr + '="' + value + '"' : ' ' + value; }, /** * @description 批量操作的结果 * @param {*} config */ $batch_success_table: function (config) { var _that = this, length = $(config.html).length; bt.open({ type: 1, title: config.title, area: config.area || ['400px'], shadeClose: false, closeBtn: 2, content: config.content || '<div class="batch_title"><span class><span class="batch_icon"></span><span class="batch_text">' + config.title + ' ' + lan['public'].success + '</span></span></div><div class="' + (length > 4 ? 'fiexd_thead' : '') + ' batch_tabel divtable" style="margin: 15px 30px 15px 30px;overflow: auto;max-height: 195px; border: 1px solid #ddd;"><table style="border: none;" class="table table-hover"><thead><tr><th>' + config.th + '</th><th class="text-right" style="width:206px;">' + lan['public'].result + '</th></tr></thead><tbody>' + config.html + '</tbody></table></div>', success: function () { if (length > 4) _that.$fixed_table_thead('.fiexd_thead'); }, }); }, /** * @description 固定表头 * @param {string} el DOM选择器 * @return void */ $fixed_table_thead: function (el) { $(el).scroll(function () { var scrollTop = this.scrollTop; this.querySelector('thead').style.transform = 'translateY(' + scrollTop + 'px)'; }); }, /** * @description 插件视图设置 * @param {object|string} layid dom元素或layer_id * @param {object} config 插件宽度高度或其他配置 */ $piugin_view_set: function (layid, config) { var element = $(typeof layid === 'string' ? '#layui-layer' + layid : layid).hide(), win = $(window); setTimeout(function () { var width = config.width || element.width(), height = config.height || element.height(); element .css( $.extend(config, { left: (win.width() - width) / 2, top: (win.height() - height) / 2, }) ) .addClass('custom_layer'); }, 50); setTimeout(function () { element.show(); }, 500); }, }; setTimeout(function () { $.fn.serializeObject = function () { var hasOwnProperty = Object.prototype.hasOwnProperty; return this.serializeArray().reduce(function (data, pair) { if (!hasOwnProperty.call(data, pair.name)) { data[pair.name] = pair.value; } return data; }, {}); }; }, 300); function arryCopy(arrys) { var list = arrys.concat(), arry = []; for (var i = 0; i < list.length; i++) { arry.push($.extend(true, {}, list[i])); } return arry; }