jeeplus.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. /**
  2. * 工具组件 对原有的工具进行封装,自定义某方法统一处理
  3. *
  4. * @author lgf 2018-4-10
  5. * @Url: http://www.jeeplus.org
  6. * @version 2.0v
  7. */
  8. (function() {
  9. jp = {
  10. /**使用jp.open代替top.layer.open,参数使用完全一致,请参照layer官网, 不在直接暴露layer在,jeeplus对layer进行统一封装**/
  11. open:top.layer.open,
  12. /**通知方法,不阻塞浏览器当前窗口,四个级别 info,warning,error,success,图标不同,其余用法完全相同*/
  13. info:function(msg){
  14. return top.layer.msg(msg);
  15. },
  16. warning: function(msg){//通知
  17. return top.layer.msg(msg, {icon:0});
  18. },
  19. success:function(msg){
  20. return top.layer.msg(msg, {icon:1});
  21. },
  22. error:function(msg){
  23. return top.layer.msg(msg, {icon:2});
  24. },
  25. //layer之外的另一个选择toast风格消息提示框,直接使用jp.toastr调用
  26. toastr:(function(){
  27. top.toastr.options = {
  28. "closeButton": true,
  29. "debug": false,
  30. "progressBar": true,
  31. "positionClass": "toast-top-right",
  32. "onclick": null,
  33. "showDuration": "400",
  34. "hideDuration": "5000",
  35. "timeOut": "10000",
  36. "extendedTimeOut": "1000",
  37. "showEasing": "swing",
  38. "hideEasing": "linear",
  39. "showMethod": "fadeIn",
  40. "hideMethod": "fadeOut"
  41. }
  42. return top.toastr;
  43. })(),
  44. //页面提示声音
  45. voice:function() {
  46. var audio = document.createElement("audio");
  47. audio.src = ctxStatic+"/common/voice/default.wav";
  48. audio.play();
  49. },
  50. /**加载层,一直阻塞浏览器窗口,必须手动调用close方法关闭*/
  51. loading:function(msg){
  52. if(!msg){
  53. msg = '正在提交,请稍等...';
  54. }
  55. var index = top.layer.msg(msg, {
  56. icon: 16
  57. ,shade: 0.01,
  58. time:999999999//设置超长时间
  59. });
  60. return index;
  61. },
  62. close:function(index){
  63. if(index){
  64. top.layer.close(index);
  65. }else{
  66. top.layer.closeAll();
  67. }
  68. },
  69. /**alert弹出框,阻塞浏览器窗口*/
  70. alert:function(msg){
  71. top.layer.alert(msg, {
  72. skin: 'layui-layer-lan'
  73. ,area:['auto', 'auto']
  74. ,icon: 0
  75. ,closeBtn: 0
  76. ,anim: 4 //动画类型
  77. });
  78. },
  79. /**询问框,阻塞浏览器窗口*/
  80. confirm:function(msg, succFuc, cancelFuc){//msg:询问信息, succFuc:点‘是’调用的函数, errFuc:点‘否’调用的函数
  81. top.layer.confirm(msg,
  82. {icon: 3, title:'系统提示', btn: ['是','否'] //按钮
  83. }, function(index){
  84. if (typeof succFuc == 'function') {
  85. succFuc();
  86. }else{
  87. location = succFuc;
  88. jp.success("操作成功!", {icon:1});
  89. }
  90. top.layer.close(index);
  91. }, function(index){
  92. if(cancelFuc)
  93. cancelFuc();
  94. top.layer.close(index);
  95. });
  96. return false;
  97. },
  98. prompt:function (title, href) {
  99. var index = top.layer.prompt({title: title, formType: 2}, function(text){
  100. if (typeof href == 'function') {
  101. href(text);
  102. }else{
  103. location = href + encodeURIComponent(text);
  104. }
  105. top.layer.close(index);
  106. });
  107. },
  108. //打开一个窗体
  109. windowOpen:function(url, name, width, height){
  110. var top=parseInt((window.screen.height-height)/2,10),left=parseInt((window.screen.width-width)/2,10),
  111. options="location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,"+
  112. "resizable=yes,scrollbars=yes,"+"width="+width+",height="+height+",top="+top+",left="+left;
  113. window.open(url ,name , options);
  114. },
  115. // //打开对话框(添加修改)
  116. // openDialog: function(title,url,width,height, $table){
  117. // var auto = true;//是否使用响应式,使用百分比时,应设置为false
  118. // if(width.indexOf("%")>=0 || height.indexOf("%")>=0 ){
  119. // auto =false;
  120. // }
  121. // top.layer.open({
  122. // type: 2,
  123. // area: [width, height],
  124. // title: title,
  125. // auto:auto,
  126. // maxmin: true, //开启最大化最小化按钮
  127. // content: url ,
  128. // btn: ['确定', '关闭'],
  129. // yes: function(index, layero){
  130. // var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
  131. // if(!$table){//如果不传递table对象过来,按约定的默认id获取table对象
  132. // $table = $('#table')
  133. // }
  134. // iframeWin.contentWindow.doSubmit($table, index);
  135. // },
  136. // cancel: function(index){
  137. // }
  138. // });
  139. // },
  140. //
  141. // //打开对话框(查看)
  142. // openDialogView :function(title,url,width,height){
  143. // var auto = true;//是否使用响应式,使用百分比时,应设置为false
  144. // if(width.indexOf("%")>=0 || height.indexOf("%")>=0 ){
  145. // auto =false;
  146. // }
  147. // top.layer.open({
  148. // type: 2,
  149. // area: [width, height],
  150. // title: title,
  151. // auto:auto,
  152. // maxmin: true, //开启最大化最小化按钮
  153. // content: url ,
  154. // btn: ['关闭'],
  155. // cancel: function(index){
  156. // }
  157. // });
  158. //
  159. // },
  160. /**打开图片预览框**/
  161. showPic:function(url){
  162. var json = {
  163. "data": [ //相册包含的图片,数组格式
  164. {
  165. "src": url, //原图地址
  166. }
  167. ]
  168. };
  169. top.layer.photos({
  170. photos: json
  171. ,anim: 0 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
  172. });
  173. },
  174. /**用户选择框**/
  175. openUserSelectDialog:function(isMultiSelect, yesFuc){
  176. top.layer.open({
  177. type: 2,
  178. area: ['1150px', '560px'],
  179. title:"选择用户",
  180. auto:true,
  181. maxmin: true, //开启最大化最小化按钮
  182. content: ctx+"/sys/user/userSelect?isMultiSelect="+isMultiSelect,
  183. btn: ['确定', '关闭'],
  184. yes: function(index, layero){
  185. var ids = layero.find("iframe")[0].contentWindow.getIdSelections();
  186. var names = layero.find("iframe")[0].contentWindow.getNameSelections();
  187. var loginNames = layero.find("iframe")[0].contentWindow.getLoginNameSelections();
  188. if(ids.length ==0){
  189. jp.warning("请选择至少一个用户!");
  190. return;
  191. }
  192. // 执行保存
  193. yesFuc(ids.join(","), names.join(","), loginNames.join(","));
  194. top.layer.close(index);
  195. },
  196. cancel: function(index){
  197. //取消默认为空,如需要请自行扩展。
  198. top.layer.close(index);
  199. }
  200. });
  201. },
  202. /**
  203. * 关联用户选择对话框
  204. *
  205. * @author huang
  206. */
  207. openJoinSelectDialog:function(isParty,yesFuc){
  208. top.layer.open({
  209. type: 2,
  210. area: ['1100px', '560px'],
  211. title:isParty ? "选择党员": "选择村支书",
  212. auto:true,
  213. maxmin: true, //开启最大化最小化按钮
  214. content: ctx+"/sys/user/userJoinSelect?isParty="+isParty,
  215. btn: ['确定', '关闭'],
  216. yes: function(index, layero){
  217. var ids = layero.find("iframe")[0].contentWindow.getIdSelections();
  218. var names = layero.find("iframe")[0].contentWindow.getNameSelections();
  219. if(ids.length ==0){
  220. jp.warning("请选择至少一个用户!");
  221. return;
  222. }
  223. // 执行保存
  224. yesFuc(ids.join(","), names.join(","));
  225. top.layer.close(index);
  226. },
  227. cancel: function(index){
  228. //取消默认为空,如需要请自行扩展。
  229. top.layer.close(index);
  230. }
  231. });
  232. },
  233. /**角色选择框**/
  234. openRoleSelectDialog:function(isMultiSelect, yesFuc){
  235. var url = ctx + "/sys/role/data";
  236. var fieldLabels = "角色名|英文名";
  237. var fieldKeys = "name|enname";
  238. top.layer.open({
  239. type: 2,
  240. area: ['800px', '500px'],
  241. title:"角色选择",
  242. auto:true,
  243. name:'friend',
  244. content: ctx+"/tag/gridselect?url="+encodeURIComponent(url)+"&fieldLabels="+encodeURIComponent(fieldLabels)+"&fieldKeys="+encodeURIComponent(fieldKeys)+"&searchLabels="+encodeURIComponent(fieldLabels)+"&searchKeys="+encodeURIComponent(fieldKeys)+"&isMultiSelected="+isMultiSelect,
  245. btn: ['确定', '关闭'],
  246. yes: function(index, layero){
  247. var iframeWin = layero.find('iframe')[0].contentWindow; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
  248. var items = iframeWin.getSelections();
  249. if(items == ""){
  250. jp.warning("必须选择一条数据!");
  251. return;
  252. }
  253. var ids = [];
  254. var names = [];
  255. for(var i=0; i<items.length; i++){
  256. var item = items[i];
  257. ids.push(item.id);
  258. names.push(item.enname)
  259. }
  260. yesFuc(ids.join(","), names.join(","));
  261. top.layer.close(index);//关闭对话框。
  262. },
  263. cancel: function(index){
  264. }
  265. });
  266. },
  267. dateFormat:function (timestamp, format) {
  268. var _this = new Date(timestamp);
  269. var o = {
  270. "M+": _this.getMonth() + 1,
  271. // month
  272. "d+": _this.getDate(),
  273. // day
  274. "h+": _this.getHours(),
  275. // hour
  276. "m+": _this.getMinutes(),
  277. // minute
  278. "s+": _this.getSeconds(),
  279. // second
  280. "q+": Math.floor((_this.getMonth() + 3) / 3),
  281. // quarter
  282. "S": _this.getMilliseconds()
  283. // millisecond
  284. };
  285. if (/(y+)/.test(format) || /(Y+)/.test(format)) {
  286. format = format.replace(RegExp.$1, (_this.getFullYear() + "").substr(4 - RegExp.$1.length));
  287. }
  288. for (var k in o) {
  289. if (new RegExp("(" + k + ")").test(format)) {
  290. format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
  291. }
  292. }
  293. return format;
  294. },
  295. escapeHTML: function(a){
  296. a = "" + a;
  297. return a.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");;
  298. },
  299. /**
  300. * @function unescapeHTML 还原html脚本 < > & " '
  301. * @param a -
  302. * 字符串
  303. */
  304. unescapeHTML: function(a){
  305. a = "" + a;
  306. return a.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&apos;/g, "'");
  307. },
  308. //获取字典标签
  309. getDictLabel : function(data, value, defaultValue){
  310. for (var i=0; i<data.length; i++){
  311. var row = data[i];
  312. if (row.value == value){
  313. return row.label;
  314. }
  315. }
  316. return defaultValue;
  317. },
  318. post:function(url,data,callback){
  319. $.ajax({
  320. url:url,
  321. method:"post",
  322. data:data,
  323. error:function(xhr,textStatus){
  324. if(xhr.status == 0){
  325. jp.info("连接失败,请检查网络!")
  326. }else if(xhr.status == 404){
  327. var errDetail ="<font color='red'>404,请求地址不存在!</font>";
  328. top.layer.alert(errDetail , {
  329. icon: 2,
  330. area:['auto','auto'],
  331. title:"请求出错"
  332. })
  333. }else if(xhr.status && xhr.responseText){
  334. var errDetail ="<font color='red'>"+ xhr.responseText.replace(/[\r\n]/g,"<br>").replace(/[\r]/g,"<br>").replace(/[\n]/g,"<br>")+"</font>";
  335. top.layer.alert(errDetail , {
  336. icon: 2,
  337. area:['80%','70%'],
  338. title:xhr.status+"错误"
  339. })
  340. }else{
  341. var errDetail ="<font color='red'>未知错误!</font>";
  342. top.layer.alert(errDetail , {
  343. icon: 2,
  344. area:['auto','auto'],
  345. title:"真悲剧,后台抛出异常了"
  346. })
  347. }
  348. },
  349. success:function(data,textStatus,jqXHR){
  350. if(data.indexOf == "_login_page_"){//登录超时
  351. location.reload(true);
  352. }else{
  353. callback(data);
  354. }
  355. }
  356. });
  357. },
  358. get:function(url,callback){
  359. $.ajax({
  360. url:url,
  361. method:"get",
  362. error:function(xhr,textStatus){
  363. if(xhr.status == 0){
  364. jp.info("连接失败,请检查网络!")
  365. }else if(xhr.status == 404){
  366. var errDetail ="<font color='red'>404,请求地址不存在!</font>";
  367. top.layer.alert(errDetail , {
  368. icon: 2,
  369. area:['auto','auto'],
  370. title:"请求出错"
  371. })
  372. }else if(xhr.status && xhr.responseText){
  373. var errDetail ="<font color='red'>"+ xhr.responseText.replace(/[\r\n]/g,"<br>").replace(/[\r]/g,"<br>").replace(/[\n]/g,"<br>")+"</font>";
  374. top.layer.alert(errDetail , {
  375. icon: 2,
  376. area:['80%','70%'],
  377. title:xhr.status+"错误"
  378. })
  379. }else{
  380. var errDetail ="<font color='red'>未知错误!</font>";
  381. top.layer.alert(errDetail , {
  382. icon: 2,
  383. area:['auto','auto'],
  384. title:"真悲剧,后台抛出异常了"
  385. })
  386. }
  387. },
  388. success:function(data,textStatus,jqXHR){
  389. if(data.indexOf == "_login_page_"){//返回首页内容代表登录超时
  390. top.layer.alert("登录超时!")
  391. location.reload(true);
  392. }else{
  393. callback(data);
  394. }
  395. }
  396. });
  397. },
  398. /*
  399. * params:
  400. * id: 表单的jQuery ID 例如"#inputForm"
  401. * succFuc, 成功后执行的回调函数
  402. * beformSubmit:执行提交操作前执行的方法
  403. */
  404. ajaxForm:function(id, succFuc, beforeSubmit){
  405. $(id).ajaxForm({
  406. dataType: 'json',
  407. beforeSubmit: function (arr, form, options) {
  408. if(beforeSubmit){
  409. beforeSubmit();
  410. }
  411. var isValidate = jp.validateForm(id);//校验表单
  412. if(isValidate){
  413. form.find("button:submit").button("loading");
  414. }else{
  415. return false;
  416. }
  417. },
  418. error:function(xhr,textStatus){
  419. if(xhr.status == 0){
  420. jp.info("连接失败,请检查网络!")
  421. }else if(xhr.status == 404){
  422. var errDetail ="<font color='red'>404,请求地址不存在!</font>";
  423. top.layer.alert(errDetail , {
  424. icon: 2,
  425. area:['auto','auto'],
  426. title:"请求出错"
  427. })
  428. }else if(xhr.status && xhr.responseText){
  429. var errDetail ="<font color='red'>"+ xhr.responseText.replace(/[\r\n]/g,"<br>").replace(/[\r]/g,"<br>").replace(/[\n]/g,"<br>")+"</font>";
  430. top.layer.alert(errDetail , {
  431. icon: 2,
  432. area:['80%','70%'],
  433. title:xhr.status+"错误"
  434. })
  435. }else{
  436. var errDetail ="<font color='red'>未知错误!</font>";
  437. top.layer.alert(errDetail , {
  438. icon: 2,
  439. area:['auto','auto'],
  440. title:"真悲剧,后台抛出异常了"
  441. })
  442. }
  443. $(id).find("button:submit").button("reset");
  444. },
  445. success: function (data, statusText, xhr, form) {
  446. succFuc(data);
  447. // form.find("button:submit").button("reset");
  448. }
  449. });
  450. },
  451. //打开对话框(添加修改)
  452. openSaveDialog: function(title,url,width,height){
  453. var auto = true;//是否使用响应式,使用百分比时,应设置为false
  454. if(width.indexOf("%")>=0 || height.indexOf("%")>=0 ){
  455. auto =false;
  456. }
  457. top.layer.open({
  458. type: 2,
  459. area: [width, height],
  460. title: title,
  461. auto:auto,
  462. maxmin: true, //开启最大化最小化按钮
  463. content: url ,
  464. btn: ['确定', '关闭'],
  465. yes: function(index, layero){
  466. var iframeWin = layero.find('iframe')[0]; //得到弹出的窗口对象,执行窗口内iframe页的方法:iframeWin.method();
  467. iframeWin.contentWindow.save();//调用保存事件,在 弹出页内,需要定义save方法。处理保存事件。
  468. },
  469. cancel: function(index){
  470. }
  471. });
  472. },
  473. //打开对话框(查看)
  474. openViewDialog :function(title,url,width,height){
  475. var auto = true;//是否使用响应式,使用百分比时,应设置为false
  476. if(width.indexOf("%")>=0 || height.indexOf("%")>=0 ){
  477. auto =false;
  478. }
  479. top.layer.open({
  480. type: 2,
  481. area: [width, height],
  482. title: title,
  483. auto:auto,
  484. maxmin: true, //开启最大化最小化按钮
  485. content: url ,
  486. btn: ['关闭'],
  487. cancel: function(index){
  488. }
  489. });
  490. },
  491. //打开子对话框(仅仅用作 父子layer弹窗之间交互数据使用)
  492. openChildDialog: function(title,url,width,height, parentObj){
  493. var auto = true;//是否使用响应式,使用百分比时,应设置为false
  494. if(width.indexOf("%")>=0 || height.indexOf("%")>=0 ){
  495. auto =false;
  496. }
  497. top.layer.open({
  498. type: 2,
  499. area: [width, height],
  500. title: title,
  501. auto:auto,
  502. maxmin: true, //开启最大化最小化按钮
  503. content: url ,
  504. btn: ['确定', '关闭'],
  505. yes: function(index, layero){
  506. var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
  507. iframeWin.contentWindow.save(parentObj);//在子窗口定义save方法,负责实际业务逻辑的执行
  508. },
  509. cancel: function(index){
  510. }
  511. });
  512. },
  513. validateForm: function (id) {
  514. return $(id).validate({
  515. errorPlacement: function(error, element) {
  516. if (element.is(":checkbox")||element.is(":radio")){
  517. error.appendTo(element.parent().parent().parent().parent());
  518. }else if (element.parent().is(".form_datetime") ||element.parent().is(".input-append") || element.is(".mydatepicker")){
  519. error.appendTo(element.parent().parent());
  520. }else{
  521. error.insertAfter(element);
  522. }
  523. }
  524. }).form();
  525. },
  526. go:function(url){//在当前选项卡跳转页面
  527. window.location.href = url;
  528. },
  529. openTab:function(url,title, isNew){//isNew 为true时,打开一个新的选项卡;为false时,如果选项卡不存在,打开一个新的选项卡,如果已经存在,使已经存在的选项卡变为活跃状态。
  530. top.openTab(url,title,isNew);
  531. },
  532. /**
  533. * Ajax上传文件
  534. * @param fileObj
  535. * @param url
  536. * @param callback
  537. */
  538. uploadFile: function (fileObj, url,callback) {
  539. var data = new FormData(fileObj);
  540. // data.append("CustomField", "This is some extra data, testing");//如果要添加参数
  541. $.ajax({
  542. type: "POST",
  543. enctype: 'multipart/form-data',
  544. url: url,
  545. data: data,
  546. processData: false, //prevent jQuery from automatically transforming the data into a query string
  547. contentType: false,
  548. cache: false,
  549. timeout: 600000,
  550. success: function (result) {
  551. callback(result);
  552. },
  553. error:function(xhr, textStatus){
  554. if(xhr.status == 0){
  555. jp.info("连接失败,请检查网络!")
  556. }else if(xhr.status == 404){
  557. var errDetail ="<font color='red'>404,请求地址不存在!</font>";
  558. top.layer.alert(errDetail , {
  559. icon: 2,
  560. area:['auto','auto'],
  561. title:"请求出错"
  562. })
  563. }else if(xhr.status && xhr.responseText){
  564. var errDetail ="<font color='red'>"+ xhr.responseText.replace(/[\r\n]/g,"<br>").replace(/[\r]/g,"<br>").replace(/[\n]/g,"<br>")+"</font>";
  565. top.layer.alert(errDetail , {
  566. icon: 2,
  567. area:['80%','70%'],
  568. title:xhr.status+"错误"
  569. })
  570. }else{
  571. var errDetail =xhr.responseText=="<font color='red'>未知错误!</font>";
  572. top.layer.alert(errDetail , {
  573. icon: 2,
  574. area:['auto','auto'],
  575. title:"真悲剧,后台抛出异常了"
  576. })
  577. }
  578. }
  579. })
  580. },
  581. downloadFile: function(url, name) {
  582. var $a = $("<a></a>").attr("href", url).attr("download", name);
  583. $a[0].click();
  584. },
  585. /**
  586. * 返回当前活跃的tab页面关联的iframe的Windows对象,方便layer弹窗调用父页面的方法。
  587. */
  588. getParent: function () {
  589. return top.getActiveTab()[0].contentWindow;
  590. }
  591. }
  592. })(jQuery);