dataPicker.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. mbui.define(['tool','layer'], function (exports) {
  2. const tool = mbui.tool,layer = mbui.layer;
  3. let searchTimer;
  4. const dataTypes = {
  5. 'property':{
  6. title:'选择固定资产',
  7. url:'/adm/api/get_property',
  8. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  9. template:function (item,types){
  10. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  11. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  12. <div style="margin-left:8px;">\
  13. <div class="line-limit-1">' + item.title + '</div>\
  14. <div class="f12"><span class="text-gray">编号:</span>'+item.code+'<span class="text-gray" style="margin-left:12px;">分类:</span>'+item.cate+'</div>\
  15. </div>\
  16. </label>'
  17. }
  18. },
  19. 'car':{
  20. title:'选择车辆信息',
  21. url:'/adm/api/get_car',
  22. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  23. template:function (item,types){
  24. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  25. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  26. <div style="margin-left:8px;">\
  27. <div class="line-limit-1">' + item.title + '</div>\
  28. <div class="f12"><span class="text-gray">车牌号:</span>'+item.name+'<span class="text-gray" style="margin-left:12px;">座位数:</span>'+item.seats+'</div>\
  29. </div>\
  30. </label>'
  31. }
  32. },
  33. 'room':{
  34. title:'选择会议室',
  35. url:'/adm/api/get_meeting_room',
  36. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  37. template:function (item,types){
  38. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  39. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  40. <div style="margin-left:8px;">\
  41. <div class="line-limit-1">' + item.title + '</div>\
  42. <div class="f12"><span class="text-gray">设备:</span>'+item.device+'<span class="text-gray" style="margin-left:12px;">可容纳人数:</span>'+item.num+'</div>\
  43. </div>\
  44. </label>'
  45. }
  46. },
  47. 'loan':{
  48. title:'选择抵消借支',
  49. url:'/finance/api/get_loan',
  50. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  51. template:function (item,types){
  52. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  53. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  54. <div style="margin-left:8px;">\
  55. <div class="line-limit-1">' + item.title + '</div>\
  56. <div class="f12"><span class="text-gray">状态:</span>'+item.balance_name+'<span class="text-gray" style="margin-left:12px;">可抵消余额:</span>'+item.un_balance_cost+'</div>\
  57. </div>\
  58. </label>'
  59. }
  60. },
  61. 'customer':{
  62. title:'选择客户',
  63. url:'/customer/api/get_customer',
  64. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  65. template:function (item,types){
  66. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.name + '">\
  67. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  68. <div style="margin-left:8px;">\
  69. <div class="line-limit-1">' + item.name + '</div>\
  70. <div class="f12"><span class="text-gray">所属员工:</span>'+item.belong_name+'<span class="text-gray" style="margin-left:12px;">所属部门:</span>'+item.belong_department+'</div>\
  71. </div>\
  72. </label>'
  73. }
  74. },
  75. 'supplier':{
  76. title:'选择供应商',
  77. url:'/contract/api/get_supplier',
  78. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  79. template:function (item,types){
  80. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  81. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  82. <div style="margin-left:8px;">\
  83. <div class="line-limit-1">' + item.title + '</div>\
  84. <div class="f12"><span class="text-gray">联系人:</span>'+item.contact_name+'<span class="text-gray" style="margin-left:12px;">联系电话:</span>'+item.contact_mobile+'</div>\
  85. </div>\
  86. </label>'
  87. }
  88. },
  89. 'contract':{
  90. title:'选择销售合同',
  91. url:'/contract/api/get_contract',
  92. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  93. template:function (item,types){
  94. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.name + '">\
  95. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  96. <div style="margin-left:8px;">\
  97. <div class="line-limit-1">' + item.name + '</div>\
  98. <div class="f12"><span class="text-gray">合同编号:</span>'+item.code+'<span class="text-gray" style="margin-left:12px;">签订人:</span>'+item.sign_name+'</div>\
  99. </div>\
  100. </label>'
  101. }
  102. },
  103. 'product':{
  104. title:'选择产品',
  105. url:'/contract/api/get_product',
  106. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  107. template:function (item,types){
  108. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  109. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  110. <div style="margin-left:8px;">\
  111. <div class="line-limit-1">' + item.title + '</div>\
  112. <div class="f12"><span class="text-gray">编码:</span>'+item.code+'<span class="text-gray" style="margin-left:12px;">分类:</span>'+item.cate+'</div>\
  113. </div>\
  114. </label>'
  115. }
  116. },
  117. 'purchase':{
  118. title:'选择采购合同',
  119. url:'/contract/api/get_purchase',
  120. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  121. template:function (item,types){
  122. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.name + '">\
  123. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  124. <div style="margin-left:8px;">\
  125. <div class="line-limit-1">' + item.name + '</div>\
  126. <div class="f12"><span class="text-gray">合同编号:</span>'+item.code+'<span class="text-gray" style="margin-left:12px;">签订人:</span>'+item.sign_name+'</div>\
  127. </div>\
  128. </label>'
  129. }
  130. },
  131. 'purchased':{
  132. title:'选择采购物品',
  133. url:'/contract/api/get_purchased',
  134. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  135. template:function (item,types){
  136. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  137. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  138. <div style="margin-left:8px;">\
  139. <div class="line-limit-1">' + item.title + '</div>\
  140. <div class="f12"><span class="text-gray">编码:</span>'+item.code+'<span class="text-gray" style="margin-left:12px;">分类:</span>'+item.cate+'</div>\
  141. </div>\
  142. </label>'
  143. }
  144. },
  145. 'project':{
  146. title:'选择项目',
  147. url:'/project/api/get_project',
  148. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  149. template:function (item,types){
  150. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.name + '">\
  151. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  152. <div style="margin-left:8px;">\
  153. <div class="line-limit-1">' + item.name + '</div>\
  154. <div class="f12"><span class="text-gray">项目类型:</span>'+item.cate+'<span class="text-gray" style="margin-left:12px;">项目负责人:</span>'+item.director_name+'</div>\
  155. </div>\
  156. </label>'
  157. }
  158. },
  159. 'task':{
  160. title:'选择任务',
  161. url:'/project/api/get_task',
  162. searchbar:'<div class="mbui-picker-search"><input type="search" class="search-input" placeholder="输入关键字..."></div>',
  163. template:function (item,types){
  164. return '<label class="mbui-picker-item" data-id="' + item.id + '" data-title="' + item.title + '">\
  165. <input class="mbui-input-'+types+'" name="radio_picker[]" type="'+types+'" value="' + item.id + '">\
  166. <div style="margin-left:8px;">\
  167. <div class="line-limit-1">' + item.title + '</div>\
  168. <div class="f12"><span class="text-gray">负责人:</span>'+item.director_name+'<span class="text-gray" style="margin-left:12px;">任务状态:</span>'+item.status_name+'</div>\
  169. </div>\
  170. </label>'
  171. }
  172. }
  173. };
  174. //html转义,防止XSS
  175. function escapeHtml(text) {
  176. var map = {
  177. '&': '&amp;',
  178. '<': '&lt;',
  179. '>': '&gt;',
  180. '"': '&quot;',
  181. "'": '&#039;'
  182. };
  183. return text.replace(/[&<>"']/g, function(m) { return map[m]; });
  184. }
  185. var LoadData= function () {
  186. this.config = {
  187. title: "请选择内容",
  188. url: "",
  189. searchbar:"",
  190. type: "radio",
  191. where: {},
  192. limit: 20,
  193. data:[],
  194. selectData:[],
  195. template: function (data) {
  196. return JSON.parse(data);
  197. },
  198. callback: function(){}
  199. };
  200. this.index = 0;
  201. this.loaded = 0;
  202. this.page = 1;
  203. this.count = 0;
  204. this.total = 0;
  205. };
  206. // 初始化
  207. LoadData.prototype.init = function (options,types) {
  208. var that = this;
  209. let opts={};
  210. if (types != "undefined") {
  211. opts = dataTypes[types];
  212. }
  213. $.extend(true,that.config,opts,options);
  214. //console.log(that.config);
  215. that.index = new Date().getTime();
  216. var $container = $('<div class="mbui-picker-selector"><header class="mbui-bar"><a class="mbui-bar-item left" href="javascript:;"><i class="mbui-bar-arrow-left"></i>关闭</a><a class="mbui-bar-item right text-blue" href="javascript:;">确认</a><h1 class="mbui-bar-title">'+that.config.title+'</h1></header></div>');
  217. $container.append(that.config.searchbar);
  218. $container.append('<div class="load-data-container lists" id="lists_'+that.index+'"><div id="container_'+that.index+'"></div><div class="load-data-none"><i class="iconfont icon-none"></i><br>暂无数据</div><div class="load-data-loading"><span>努力加载中</span></div><div class="load-data-end"><span>—— ● ——</span></div></div>');
  219. $('body').append($container);
  220. $('#root').hide();
  221. $container.find('.left').click(function () {
  222. $container.fadeOut(function () {
  223. $container.remove();
  224. $('#root').show();
  225. });
  226. });
  227. $container.on('input','.search-input',function() {
  228. const key = $(this).val().trim();
  229. // 清除上一次的定时器
  230. clearTimeout(searchTimer);
  231. // 设置新的延迟请求
  232. searchTimer = setTimeout(() => {
  233. that.config.where['keywords']=key;
  234. that.page=1;
  235. that.ajax();
  236. }, 400);
  237. });
  238. $container.on('click','.tags-search',function() {
  239. const key = $(this).data('key');
  240. const val = $(this).data('val');
  241. $(this).addClass('active').siblings().removeClass('active');
  242. // 清除上一次的定时器
  243. clearTimeout(searchTimer);
  244. // 设置新的延迟请求
  245. searchTimer = setTimeout(() => {
  246. that.config.where[key]=val;
  247. that.page=1;
  248. that.ajax();
  249. }, 400);
  250. });
  251. $container.find('.right').click(function () {
  252. let selected = $container.find('input:checked');
  253. if (selected.length == 0) {
  254. layer.msg('请选择数据');
  255. return false;
  256. }
  257. that.config.selectData.length=0;
  258. let ids=[];
  259. for (var m = 0; m < selected.length; m++) {
  260. let selected_item = $(selected[m]).parent();
  261. let id=selected_item.data('id');
  262. ids.push(id);
  263. }
  264. that.config.selectData = that.config.data.filter(item => ids.includes(item.id));
  265. that.config.callback(that.config.selectData);
  266. $container.fadeOut(function () {
  267. $container.remove();
  268. $('#root').show();
  269. });
  270. });
  271. $('#lists_'+that.index).scroll(function(){
  272. if ($(this).scrollTop() + $('body').height() >= $('#container_'+that.index).height()-60) {
  273. console.log($(this).scrollTop());
  274. console.log('<br>');
  275. console.log($('body').height());
  276. console.log('<br>');
  277. console.log($('#container_'+that.index).height());
  278. // 滚动到页面底部时加载更多数据
  279. if (that.total < that.count && that.loaded == 0){
  280. that.ajax();
  281. }
  282. }
  283. });
  284. that.ajax();
  285. };
  286. LoadData.prototype.ajax = function () {
  287. var that = this;
  288. var elem = $('#container_'+that.index);
  289. var container = elem.parent();
  290. //console.log(container.html());
  291. // 发送请求获取数据
  292. $.ajax({
  293. url: that.config.url + '?page=' + that.page + '&limit=' + that.config.limit,
  294. type: 'GET',
  295. data: that.config.where,
  296. beforeSend: function () {
  297. // 显示加载按钮
  298. that.loaded = 1;
  299. container.find('.load-data-loading').show();
  300. container.find('.load-data-end').hide();
  301. },
  302. success: function (res) {
  303. that.count=res.count;
  304. that.total+=res.data.length;
  305. container.find('.load-data-none').attr('class','load-data-none load-data-'+that.count);
  306. if(that.page==1){
  307. that.config.data.length=0;
  308. elem.html('');
  309. }
  310. if (res.count > 0) {
  311. that.page++;
  312. that.config.data.push(...res.data);
  313. $.each(res.data, function (index, item) {
  314. // 转义JSON对象中的字符串值,防止XSS
  315. for (var key in item) {
  316. if (typeof item[key] === 'string') {
  317. item[key] = escapeHtml(item[key]);
  318. }
  319. }
  320. // 创建列表项并添加到列表中
  321. var listItem = that.config.template(item,that.config.type);
  322. elem.append(listItem);
  323. });
  324. container.find('.load-data-end').show();
  325. }
  326. else{
  327. that.config.data.length=0;
  328. that.page=1;
  329. }
  330. },
  331. complete: function () {
  332. that.loaded = 0;
  333. container.find('.load-data-loading').hide();
  334. container.find('.load-data-end').show();
  335. }
  336. });
  337. }
  338. //选择员工弹窗
  339. $('body').on('click','.picker-data',function () {
  340. let that = $(this);
  341. let types = that.data('types');
  342. let type = that.data('type');
  343. let where = that.data('where');
  344. if (typeof(type) == "undefined" || type == '') {
  345. type = 1;
  346. }
  347. type = type == 2 ? 'checkbox' : 'radio';
  348. if (typeof(types) == "undefined" || types == '') {
  349. layer.msg('请设置【picker】的类型');
  350. return false;
  351. }
  352. if (typeof(where) == "undefined" || where == '') {
  353. map = {};
  354. }
  355. else{
  356. map = JSON.parse(where);
  357. }
  358. let picker = new LoadData();
  359. picker.init({
  360. type:type,
  361. where: map,
  362. callback:function(selectData){
  363. let ids=[],titles=[];
  364. for ( var i = 0; i <selectData.length; i++){
  365. ids.push(selectData[i].id);
  366. if(!selectData[i].title){
  367. titles.push(selectData[i].name);
  368. }else{
  369. titles.push(selectData[i].title);
  370. }
  371. }
  372. that.val(titles.join(','));
  373. that.next().val(ids.join(','));
  374. }
  375. },types);
  376. });
  377. // 导出loadData模块
  378. exports('dataPicker', function (options,types) {
  379. var dataPicker = new LoadData();
  380. dataPicker.init(options,types);
  381. });
  382. });