sa.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. // =========================== sa对象封装一系列工具方法 ===========================
  2. var sa = {
  3. version: '2.2',
  4. update_time: '2020-4-17',
  5. info: '增加了sa_admin字段,方便调用'
  6. };
  7. // =========================== 当前环境配置 =======================================
  8. (function(){
  9. // 公司开发环境
  10. var cfg_dev = {
  11. api_url: 'http://127.0.0.1:8989', // 所有ajax请求接口父地址
  12. }
  13. sa.cfg = cfg_dev; // 最终环境 , 上线前请选择正确的环境
  14. })();
  15. // =========================== ajax的封装 =======================================
  16. (function(){
  17. sa.ajax = function(url, type, header, data, isCookie, successFn, errorFn){
  18. // // 默认配置
  19. // var defaultCfg = {
  20. // msg: '努力加载中...', // 提示语
  21. // baseUrl: (url.indexOf('http') === 0 ? '' : sa.cfg.api_url),// 父url,拼接在url前面
  22. // // sleep: 0, // 休眠n毫秒处理回调函数
  23. // type: 'post', // 默认请求类型
  24. // success200: success200, // code=200, 代表成功
  25. // success500: function(res){ // code=500, 代表失败
  26. // return layer.alert('失败:' + res.msg);
  27. // },
  28. // success403: function(res){ // code=403, 代表权限不足
  29. // return layer.alert("权限不足," + res.msg, {icon: 5});
  30. // },
  31. // success401: function(res){ // code=401, 代表未登录
  32. // return layer.confirm("您当前暂未登录,是否立即登录?", {}, function(){
  33. // layer.closeAll();
  34. // return sa.$page.openLogin(cfg.login_url);
  35. // });
  36. // },
  37. // errorfn: function(xhr, type, errorThrown){ // ajax发生异常时的默认处理函数
  38. // if(xhr.status == 0){
  39. // return layer.alert('无法连接到服务器,请检查网络');
  40. // }
  41. // return layer.alert("异常:" + JSON.stringify(xhr));
  42. // },
  43. // complete: function(xhr, ts) { // 成功失败都会执行
  44. // }
  45. // }
  46. // 将调用者的配置和默认配置合并
  47. // cfg = sa.extendJson(cfg, defaultCfg);
  48. // 打印请求地址和参数, 以便调试
  49. console.log("请求地址:" + url);
  50. console.log("请求参数:" + JSON.stringify(data));
  51. // 开始显示loading图标
  52. sa.loading('努力加载中...');
  53. // 开始请求ajax
  54. return $.ajax({
  55. url: url,
  56. type: type,
  57. data: data,
  58. dataType: 'json',
  59. headers: header,
  60. // 跨域处理
  61. xhrFields: {
  62. withCredentials: isCookie // 携带跨域cookie
  63. },
  64. crossDomain: true,
  65. beforeSend: function(xhr) {
  66. xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
  67. },
  68. success: function(res){
  69. console.log('返回数据:', res);
  70. sa.hideLoading();
  71. successFn(res);
  72. // 如果相应的处理函数存在
  73. // if(cfg['success' + res.code] != undefined) {
  74. // return cfg['success' + res.code](res);
  75. // }
  76. // layer.alert('未知状态码:' + JSON.stringify(res));
  77. },
  78. error: function(xhr, type, errorThrown){
  79. sa.hideLoading();
  80. errorFn(xhr, type, errorThrown)
  81. // console.log(JSON.stringify(xhr));
  82. // console.log(xhr, type, errorThrown);
  83. },
  84. // complete: cfg.complete
  85. });
  86. };
  87. // 模拟一个ajax
  88. // 请注意: 本模板中所有ajax请求调用的均为此模拟函数
  89. sa.ajax2 = function(url, data, success200, cfg){
  90. // 如果是简写模式(省略了data参数)
  91. if(typeof data === 'function'){
  92. cfg = success200;
  93. success200 = data;
  94. data = {};
  95. }
  96. // 几个默认配置
  97. cfg = cfg || {};
  98. cfg.baseUrl = (url.indexOf('http') === 0 ? '' : sa.cfg.api_url); // 父url,拼接在url前面
  99. // 设定一个默认的提示文字
  100. if(cfg.msg == undefined || cfg.msg == null || cfg.msg == '') {
  101. cfg.msg = '正在努力加载...';
  102. }
  103. // 默认延时函数
  104. if(cfg.sleep == undefined || cfg.sleep == null || cfg.sleep == '' || cfg.sleep == 0) {
  105. cfg.sleep = 600;
  106. }
  107. // 默认的模拟数据
  108. cfg.res = cfg.res || {
  109. code: 200,
  110. msg: 'ok',
  111. data: []
  112. }
  113. // 开始loding
  114. sa.loading(cfg.msg);
  115. // 打印请求地址和参数, 以便调试
  116. console.log("======= 模拟ajax =======");
  117. console.log("请求地址:" + cfg.baseUrl + url);
  118. console.log("请求参数:" + JSON.stringify(data));
  119. // 模拟ajax的延时
  120. setTimeout(function() {
  121. sa.hideLoading(); // 隐藏掉转圈圈
  122. console.log('返回数据:', cfg.res);
  123. success200(cfg.res);
  124. }, cfg.sleep)
  125. };
  126. })();
  127. // =========================== 封装弹窗相关函数 =======================================
  128. (function() {
  129. var me = sa;
  130. if(window.layer) {
  131. layer.ready(function(){});
  132. }
  133. // tips提示文字
  134. me.msg = function(msg, cfg) {
  135. msg = msg || '操作成功';
  136. layer.msg(msg, cfg);
  137. };
  138. // 操作成功的提示
  139. me.ok = function(msg) {
  140. msg = msg || '操作成功';
  141. layer.msg(msg, {anim: 0, icon: 1 });
  142. }
  143. me.ok2 = function(msg) {
  144. msg = msg || '操作成功';
  145. layer.msg(msg, {anim: 0, icon: 6 });
  146. }
  147. // 操作失败的提示
  148. me.error = function(msg) {
  149. msg = msg || '操作失败';
  150. layer.msg(msg, {anim: 6, icon: 2 });
  151. }
  152. me.error2 = function(msg) {
  153. msg = msg || '操作失败';
  154. layer.msg(msg, {anim: 6, icon: 5 });
  155. }
  156. // alert弹窗 [text=提示文字, cfg=配置(可省略), okFn=点击确定之后的回调函数]
  157. me.alert = function(text, okFn) {
  158. // 开始弹窗
  159. layer.alert(text, function(index) {
  160. layer.close(index);
  161. if(okFn) {
  162. okFn();
  163. }
  164. });
  165. };
  166. // 询问框 [text=提示文字, okFn=点击确定之后的回调函数]
  167. me.confirm = function(text, okFn) {
  168. layer.confirm(text, {}, function(index) {
  169. layer.close(index);
  170. if(okFn) {
  171. okFn();
  172. }
  173. }.bind(this));
  174. };
  175. // 输入框 [title=提示文字, okFn=点击确定后的回调函数, formType=输入框类型(0=文本,1=密码,2=多行文本域) 可省略, value=默认值 可省略 ]
  176. me.prompt = function(title, okFn, formType, value) {
  177. layer.prompt({
  178. title: title,
  179. formType: formType,
  180. value: value
  181. }, function(pass, index){
  182. layer.close(index);
  183. if(okFn) {
  184. okFn(pass);
  185. }
  186. });
  187. }
  188. // 打开loading
  189. me.loading = function(msg) {
  190. layer.closeAll(); // 开始前先把所有弹窗关了
  191. return layer.msg(msg, {icon: 16, shade: 0.3, time: 1000 * 20, skin: 'ajax-layer-load' });
  192. };
  193. // 隐藏loading
  194. me.hideLoading = function() {
  195. layer.closeAll();
  196. };
  197. // ============== 一些常用弹窗 =====================
  198. // 大窗显示一个图片
  199. // 参数: src=地址、w=宽度(默认80%)、h=高度(默认80%)
  200. me.showImage = function(src, w, h) {
  201. w = w || '80%';
  202. h = h || '80%';
  203. var content = '<div style="height: 100%; overflow: hidden !important;">' +
  204. '<img src="' + src + ' " style="width: 100%; height: 100%;" />' +
  205. '</div>';
  206. layer.open({
  207. type: 1,
  208. title: false,
  209. shadeClose: true,
  210. closeBtn: 0,
  211. area: [w, h], //宽高
  212. content: content
  213. });
  214. }
  215. // 预览一组图片
  216. // srcList=图片路径数组, index=打开立即显示哪张(可填下标, 也可填写src路径)
  217. me.showImageList = function(srcList, index) {
  218. // 如果填的是个string
  219. if(typeof srcList === 'string') {
  220. try{
  221. srcList = JSON.parse(srcList);
  222. }catch(e){
  223. srcList = [];
  224. }
  225. }
  226. // 如果填的是路径
  227. index = index || 0;
  228. if(typeof index === 'string') {
  229. index = srcList.indexOf(index);
  230. index = (index == -1 ? 0 : index);
  231. }
  232. // 开始展示
  233. var arr_list = [];
  234. srcList.forEach(function(item) {
  235. arr_list.push({
  236. alt: '左右键切换',
  237. pid: 1,
  238. src: item,
  239. thumb: item
  240. })
  241. })
  242. layer.photos({
  243. photos: {
  244. title: '',
  245. id: new Date().getTime(),
  246. start: index,
  247. data: arr_list
  248. }
  249. ,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
  250. });
  251. }
  252. // 显示一个iframe
  253. // 参数: 标题,地址,宽,高 , 点击遮罩是否关闭, 默认false
  254. me.showIframe = function(title, url, w, h, shadeClose) {
  255. // 参数修正
  256. w = w || '95%';
  257. h = h || '95%';
  258. shadeClose = (shadeClose === undefined ? false : shadeClose);
  259. // 弹出面板
  260. var index = layer.open({
  261. type: 2,
  262. title: title, // 标题
  263. shadeClose: shadeClose, // 是否点击遮罩关闭
  264. maxmin: true, // 显示最大化按钮
  265. shade: 0.8, // 遮罩透明度
  266. scrollbar: false, // 屏蔽掉外层的滚动条
  267. moveOut: true, // 是否可拖动到外面
  268. area: [w, h], // 大小
  269. content: url, // 传值
  270. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  271. resizing: function(layero) {
  272. solveLayerBug(index);
  273. }
  274. });
  275. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  276. $('#layui-layer' + index + ' .layui-layer-max').click(function() {
  277. setTimeout(function() {
  278. solveLayerBug(index);
  279. }, 200)
  280. })
  281. }
  282. me.showView = me.showIframe;
  283. // 显示一个iframe, 底部按钮方式
  284. // 参数: 标题,地址,点击确定按钮执行的代码(在子窗口执行),宽,高
  285. me.showIframe2 = function(title, url, evalStr, w, h) {
  286. // 参数修正
  287. w = w || '95%';
  288. h = h || '95%';
  289. // 弹出面板
  290. var index = layer.open({
  291. type: 2,
  292. title: title, // 标题
  293. closeBtn: (title ? 1 : 0), // 是否显示关闭按钮
  294. btn: ['确定', '取消'],
  295. shadeClose: false, // 是否点击遮罩关闭
  296. maxmin: true, // 显示最大化按钮
  297. shade: 0.8, // 遮罩透明度
  298. scrollbar: false, // 屏蔽掉外层的滚动条
  299. moveOut: true, // 是否可拖动到外面
  300. area: [w, h], // 大小
  301. content: url, // 传值
  302. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  303. resizing: function(layero) {
  304. },
  305. yes: function(index, layero) {
  306. var iframe = document.getElementById('layui-layer-iframe' + index);
  307. var iframeWindow = iframe.contentWindow;
  308. iframeWindow.eval(evalStr);
  309. }
  310. });
  311. }
  312. // 显示一个iframe
  313. // 参数: 标题,地址,宽,高 , 点击遮罩是否关闭, 默认false
  314. me.showIframe3 = function(title, url, w, h, shadeClose) {
  315. // 参数修正
  316. w = w || '95%';
  317. h = h || '95%';
  318. shadeClose = (shadeClose === undefined ? false : shadeClose);
  319. // 弹出面板
  320. var index = layer.open({
  321. type: 2,
  322. title: title, // 标题
  323. shadeClose: false, // 是否点击遮罩关闭
  324. maxmin: true, // 显示最大化按钮
  325. shade: 0, // 遮罩透明度
  326. scrollbar: true, // 屏蔽掉外层的滚动条
  327. moveOut: true, // 是否可拖动到外面
  328. zIndex: layer.zIndex,
  329. area: [w, h], // 大小
  330. content: url, // 传值
  331. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  332. resizing: function(layero) {
  333. solveLayerBug(index);
  334. },
  335. // 操作这个layer的时候置顶它
  336. success: function(layero){
  337. layer.setTop(layero);
  338. }
  339. });
  340. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  341. $('#layui-layer' + index + ' .layui-layer-max').click(function() {
  342. setTimeout(function() {
  343. solveLayerBug(index);
  344. }, 200)
  345. })
  346. }
  347. // 当前iframe关闭自身 (在iframe中调用)
  348. me.closeCurrIframe = function() {
  349. try{
  350. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  351. parent.layer.close(index); //再执行关闭
  352. }catch(e){
  353. //TODO handle the exception
  354. }
  355. }
  356. me.closeCurrView = me.closeCurrIframe;
  357. //执行一个函数, 解决layer拉伸或者最大化的时候,iframe高度不能自适应的问题
  358. function solveLayerBug(index) {
  359. var selected = '#layui-layer' + index;
  360. var height = $(selected).height();
  361. var title_height = $(selected).find('.layui-layer-title').height();
  362. $(selected).find('iframe').css('height', (height - title_height) + 'px');
  363. }
  364. })();
  365. // =========================== 常用util函数封装 =======================================
  366. (function () {
  367. // 超级对象
  368. var me = sa;
  369. // =========================== 常用util函数封装 =======================================
  370. if(true) {
  371. // 从url中查询到指定参数值
  372. me.p = function(name, defaultValue){
  373. var query = window.location.search.substring(1);
  374. var vars = query.split("&");
  375. for (var i=0;i<vars.length;i++) {
  376. var pair = vars[i].split("=");
  377. if(pair[0] == name){return pair[1];}
  378. }
  379. return(defaultValue == undefined ? null : defaultValue);
  380. }
  381. // 判断一个变量是否为null
  382. // 返回true或false,如果return_obj有值,则在true的情况下返回return_obj
  383. me.isNull = function(obj, return_obj){
  384. var flag = [null, undefined, '', 'null', 'undefined'].indexOf(obj) != -1;
  385. if(return_obj === undefined){
  386. return flag;
  387. } else {
  388. if(flag){
  389. return return_obj;
  390. } else {
  391. return obj;
  392. }
  393. }
  394. }
  395. // 将时间戳转化为指定时间
  396. // way:方式(1=年月日,2=年月日时分秒)默认1, 也可以指定格式:yyyy-MM-dd HH:mm:ss
  397. me.forDate = function(inputTime, way) {
  398. if(me.isNull(inputTime) == true){
  399. return "";
  400. }
  401. var date = new Date(inputTime);
  402. var y = date.getFullYear();
  403. var m = date.getMonth() + 1;
  404. m = m < 10 ? ('0' + m) : m;
  405. var d = date.getDate();
  406. d = d < 10 ? ('0' + d) : d;
  407. var h = date.getHours();
  408. h = h < 10 ? ('0' + h) : h;
  409. var minute = date.getMinutes();
  410. var second = date.getSeconds();
  411. minute = minute < 10 ? ('0' + minute) : minute;
  412. second = second < 10 ? ('0' + second) : second;
  413. var ms = date.getMilliseconds();
  414. way = way || 1;
  415. // way == 1 年月日
  416. if(way === 1) {
  417. return y + '-' + m + '-' + d;
  418. }
  419. // way == 1 年月日时分秒
  420. if(way === 2){
  421. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  422. }
  423. // way == 具体格式 标准格式: yyyy-MM-dd HH:mm:ss
  424. if(typeof way == 'string') {
  425. return way.replace("yyyy", y).replace("MM", m).replace("dd", d).replace("HH", h).replace("mm", minute).replace("ss", second).replace("ms", ms);
  426. }
  427. return y + '-' + m + '-' + d;
  428. };
  429. // 将时间转化为 个性化 如:3小时前,
  430. // d1 之于 d2 ,d2不填则默认取当前时间
  431. me.forDate2 = function(d, d2){
  432. var hou = "前";
  433. if(d == null || d == '') {
  434. return '';
  435. }
  436. if(d2 == null || d2 == '') {
  437. d2 = new Date();
  438. }
  439. d2 = new Date(d2).getTime();
  440. var timestamp = new Date(d).getTime() - 1000;
  441. var mistiming = Math.round((d2 - timestamp) / 1000);
  442. if(mistiming < 0) {
  443. mistiming = 0 - mistiming;
  444. hou = '后'
  445. }
  446. var arrr = ['年', '月', '周', '天', '小时', '分钟', '秒'];
  447. var arrn = [31536000, 2592000, 604800, 86400, 3600, 60, 1];
  448. for (var i = 0; i < arrn.length; i++) {
  449. var inm = Math.floor(mistiming / arrn[i]);
  450. if (inm != 0) {
  451. return inm + arrr[i] + hou;
  452. }
  453. }
  454. }
  455. // 综合以上两种方式,进行格式化
  456. // 小于24小时的走forDate2,否则forDat
  457. me.forDate3 = function(d, way) {
  458. if(d == null || d == '' ) {
  459. return '';
  460. }
  461. var cha = new Date().getTime() - new Date(d).getTime();
  462. cha = (cha > 0 ? cha : 0 - cha);
  463. if(cha < (86400 * 1000)) {
  464. return me.forDate2(d);
  465. }
  466. return me.forDate(d, way);
  467. }
  468. // 返回时间差, 此格式数组:[x, x, x, 天, 时, 分, 秒]
  469. me.getSJC = function (small_time, big_time) {
  470. var date1 = new Date(small_time); //开始时间
  471. var date2 = new Date(big_time); //结束时间
  472. var date3 = date2.getTime() - date1.getTime(); //时间差秒
  473. //计算出相差天数
  474. var days = Math.floor(date3 / (24 * 3600 * 1000));
  475. //计算出小时数
  476. var leave1 = date3 % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
  477. var hours = Math.floor(leave1 / (3600 * 1000));
  478. //计算相差分钟数
  479. var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
  480. var minutes = Math.floor(leave2 / (60 * 1000));
  481. //计算相差秒数
  482. var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
  483. var seconds = Math.round(leave3 / 1000);
  484. // 返回数组
  485. return [0, 0, 0, days, hours, minutes, seconds];
  486. }
  487. // 将日期,加上指定天数
  488. me.dateAdd = function(d, n) {
  489. var s = new Date(d).getTime();
  490. s += 86400000 * n;
  491. return new Date(s);
  492. }
  493. // 转化json,出错返回默认值
  494. me.JSONParse = function(obj, default_obj){
  495. try{
  496. return JSON.parse(obj) || default_obj;
  497. }catch(e){
  498. return default_obj || {};
  499. }
  500. }
  501. // 截取指定长度字符,默认50
  502. me.maxLength = function (str, length) {
  503. length = length || 50;
  504. if(!str){
  505. return "";
  506. }
  507. return (str.length > length) ? str.substr(0, length) + ' ...' : str;
  508. },
  509. // 过滤掉标签
  510. me.text = function(str){
  511. if(!str){
  512. return "";
  513. }
  514. return str.replace(/<[^>]+>/g,"");
  515. }
  516. // 为指定集合的每一项元素添加上is_update属性
  517. me.listAU = function(list){
  518. list.forEach(function(ts){
  519. ts.is_update = false;
  520. })
  521. return list;
  522. }
  523. // 获得一段文字中所有图片的路径
  524. me.getSrcList = function(str){
  525. try{
  526. var imgReg = /<img.*?(?:>|\/>)/gi; //匹配图片(g表示匹配所有结果i表示区分大小写)
  527. var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; //匹配src属性
  528. var arr = str.match(imgReg); // 图片数组
  529. var srcList = [];
  530. for (var i = 0; i < arr.length; i++) {
  531. var src = arr[i].match(srcReg);
  532. srcList.push(src[1]);
  533. }
  534. return srcList;
  535. } catch (e){
  536. return [];
  537. }
  538. }
  539. // 无精度损失的乘法
  540. me.accMul = function(arg1, arg2) {
  541. var m = 0,
  542. s1 = arg1.toString(),
  543. s2 = arg2.toString(),
  544. t;
  545. t = s1.split(".");
  546. // 判断有没有小数位,避免出错
  547. if (t[1]) {
  548. m += t[1].length
  549. }
  550. t = s2.split(".");
  551. if (t[1]) {
  552. m += t[1].length
  553. }
  554. return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
  555. }
  556. // 正则验证是否为手机号
  557. me.isPhone = function(str) {
  558. str = str + '';
  559. if((/^1[34578]\d{9}$/.test(str))){
  560. return true;
  561. }
  562. return false;
  563. }
  564. // 产生随机字符串
  565. me.randomString = function(len) {
  566.   len = len || 32;
  567.   var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
  568.   var maxPos = $chars.length;
  569.   var str = '';
  570.   for (i = 0; i < len; i++) {
  571.     str += $chars.charAt(Math.floor(Math.random() * maxPos));
  572.   }
  573.   return str;
  574. }
  575. // == if 结束
  576. }
  577. // =========================== 数组操作 =======================================
  578. if (true) {
  579. // 从数组里获取数据,根据指定数据
  580. me.arrayGet = function(arr, prop, value){
  581. for (var i = 0; i < arr.length; i++) {
  582. if(arr[i][prop] == value){
  583. return arr[i];
  584. }
  585. }
  586. return null;
  587. }
  588. // 从数组删除指定记录
  589. me.arrayDelete = function(arr, item){
  590. var index = arr.indexOf(item);
  591. if (index > -1) {
  592. arr.splice(index, 1);
  593. }
  594. }
  595. // 从数组删除指定id的记录
  596. me.arrayDeleteById = function(arr, id){
  597. var item = me.arrayGet(arr, 'id', id);
  598. me.arrayDelete(arr, item);
  599. }
  600. // 将数组B添加到数组A的开头
  601. me.unshiftArray = function(arrA, arrB){
  602. if(arrB){
  603. arrB.reverse().forEach(function(ts){
  604. arrA.unshift(ts);
  605. })
  606. }
  607. return arrA;
  608. }
  609. // 将数组B添加到数组A的末尾
  610. me.pushArray = function(arrA, arrB){
  611. if(arrB){
  612. arrB.forEach(function(ts){
  613. arrA.push(ts);
  614. })
  615. }
  616. return arrA;
  617. }
  618. // == if 结束
  619. }
  620. // =========================== 浏览器相关 =======================================
  621. if (true) {
  622. // set cookie 值
  623. me.setCookie = function setCookie(cname, cvalue, exdays) {
  624. exdays = exdays || 30;
  625. var d = new Date();
  626. d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  627. var expires = "expires=" + d.toGMTString();
  628. document.cookie = cname + "=" + escape(cvalue) + "; " + expires + "; path=/";
  629. }
  630. // get cookie 值
  631. me.getCookie = function(objName){
  632. var arrStr = document.cookie.split("; ");
  633. for (var i = 0; i < arrStr.length; i++) {
  634. var temp = arrStr[i].split("=");
  635. if (temp[0] == objName){
  636. return unescape(temp[1])
  637. };
  638. }
  639. return "";
  640. }
  641. // 复制指定文本
  642. me.copyText = function(str){
  643. var oInput = document.createElement('textarea');
  644. oInput.value = str;
  645. document.body.appendChild(oInput);
  646. oInput.select(); // 选择对象
  647. document.execCommand("Copy"); // 执行浏览器复制命令
  648. oInput.className = 'oInput';
  649. oInput.style.display='none';
  650. }
  651. // jquery序列化表单增强版: 排除空值
  652. me.serializeNotNull = function(selected){
  653. var serStr = $(selected).serialize();
  654. return serStr.split("&").filter(function(str){return !str.endsWith("=")}).join("&");
  655. }
  656. // 将cookie序列化为k=v形式
  657. me.strCookie = function(){
  658. return document.cookie.replace(/; /g,"&");
  659. }
  660. // 回到顶部
  661. me.goTop = function() {
  662. function smoothscroll(){
  663. var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
  664. if (currentScroll > 0) {
  665. window.requestAnimationFrame(smoothscroll);
  666. window.scrollTo (0,currentScroll - (currentScroll/5));
  667. }
  668. };
  669. smoothscroll();
  670. }
  671. // == if 结束
  672. }
  673. // =========================== javascript对象操作 =======================================
  674. if (true) {
  675. // 去除json对象中的空值
  676. me.removeNull = function(obj){
  677. var newObj = {};
  678. if(obj != undefined && obj != null) {
  679. for(var key in obj) {
  680. if(obj[key] === undefined || obj[key] === null || obj[key] == '') {
  681. //
  682. } else {
  683. newObj[key] = obj[key];
  684. }
  685. }
  686. }
  687. return newObj;
  688. }
  689. // JSON 浅拷贝, 返回拷贝后的obj
  690. me.copyJSON = function(obj){
  691. if(obj === null || obj === undefined) {
  692. return obj;
  693. };
  694. var new_obj = {};
  695. for(var key in obj) {
  696. new_obj[key] = obj [key];
  697. }
  698. return new_obj;
  699. }
  700. // json合并, 将 defaulet配置项 转移到 user配置项里 并返回 user配置项
  701. me.extendJson = function(userOption, defaultOption) {
  702. if(!userOption) {
  703. return defaultOption;
  704. };
  705. for(var key in defaultOption) {
  706. if(userOption[key] === undefined) {
  707. userOption[key] = defaultOption[key];
  708. } else if(userOption[key] == null){
  709. } else if(typeof userOption[key] == "object") {
  710. me.extendJson(userOption[key], defaultOption[key]); //深度匹配
  711. }
  712. }
  713. return userOption;
  714. }
  715. // == if 结束
  716. }
  717. // =========================== 本地集合存储 =======================================
  718. if (true) {
  719. // 获取指定key的list
  720. me.keyListGet = function(key){
  721. try{
  722. var str = localStorage.getItem('LIST_' + key);
  723. if(str == undefined || str == null || str =='' || str == 'undefined' || typeof(JSON.parse(str)) == 'string'){
  724. //alert('key' + str);
  725. str = '[]';
  726. }
  727. return JSON.parse(str);
  728. }catch(e){
  729. return [];
  730. }
  731. },
  732. me.keyListSet = function(key, list){
  733. localStorage.setItem('LIST_' + key, JSON.stringify(list));
  734. },
  735. me.keyListHas = function(key, item){
  736. var arr2 = me.keyListGet(key);
  737. return arr2.indexOf(item) != -1;
  738. },
  739. me.keyListAdd = function(key, item){
  740. var arr = me.keyListGet(key);
  741. arr.push(item);
  742. me.keyListSet(key,arr);
  743. },
  744. me.keyListRemove = function(key, item){
  745. var arr = me.keyListGet(key);
  746. var index = arr.indexOf(item);
  747. if (index > -1) {
  748. arr.splice(index, 1);
  749. }
  750. me.keyListSet(key,arr);
  751. }
  752. // == if 结束
  753. }
  754. })();
  755. // =========================== $sys 有关当前系统的方法 一般不能复制到别的项目中用 =======================================
  756. (function(){
  757. // 超级对象
  758. var me = {};
  759. sa.$sys = me;
  760. // 定义key
  761. var pcode_key = 'permission_code';
  762. // 写入当前会话的权限码集合
  763. sa.setAuth = function(codeList) {
  764. sa.keyListSet(pcode_key, codeList);
  765. }
  766. // 清除当前会话的权限码集合
  767. sa.clearAuth = function() {
  768. sa.keyListSet(pcode_key, []);
  769. }
  770. // 检查当前会话是否拥有一个权限码, 返回true和false
  771. sa.isAuth = function(pcode) {
  772. return sa.keyListHas(pcode_key, pcode);
  773. }
  774. // 检查当前会话是否拥有一个权限码, 如果没有, 则跳转到无权限页面
  775. // 注意: 非二级目录页面请注意调整路径问题
  776. sa.checkAuth = function(pcode, not_pcode_url) {
  777. var is_have = sa.keyListHas(pcode_key, pcode);
  778. if(is_have == false) {
  779. location.href= not_pcode_url || '../../sa-html/error-page/403.html';
  780. throw '暂无权限: ' + pcode;
  781. }
  782. }
  783. // 同上, 只不过是以弹窗的形式显示出来无权限来
  784. sa.checkAuthTs = function(pcode, not_pcode_url) {
  785. var is_have = sa.keyListHas(pcode_key, pcode);
  786. if(is_have == false) {
  787. var url = not_pcode_url || '../../sa-html/error-page/403.html';
  788. layer.open({
  789. type: 2,
  790. title: false, // 标题
  791. shadeClose: true, // 是否点击遮罩关闭
  792. shade: 0.8, // 遮罩透明度
  793. scrollbar: false, // 屏蔽掉外层的滚动条
  794. closeBtn: false,
  795. area: ['700px', '600px'], // 大小
  796. content: url // 传值
  797. });
  798. throw '暂无权限: ' + pcode;
  799. }
  800. }
  801. // ======================= 登录相关 ============================
  802. // 写入当前已登陆用户信息
  803. me.setCurrUser = function(currUser){
  804. localStorage.setItem('currUser', JSON.stringify(currUser));
  805. }
  806. // 获得当前已登陆用户信息
  807. me.getCurrUser = function(){
  808. var user = localStorage.getItem("currUser");
  809. if(user == undefined || user == null || user == 'null' || user == '' || user == '{}' || user.length < 10){
  810. user = {
  811. id: '0',
  812. username: '未登录'
  813. }
  814. }else{
  815. user = JSON.parse(user);
  816. }
  817. return user;
  818. }
  819. // ======================= 配置相关 ============================
  820. // 写入配置信息
  821. me.setAppCfg = function(cfg) {
  822. if(typeof cfg != 'string') {
  823. cfg = JSON.stringify(cfg);
  824. }
  825. localStorage.setItem('app_cfg', cfg);
  826. }
  827. // 获取配置信息
  828. me.getAppCfg = function() {
  829. var app_cfg = sa.JSONParse(localStorage.getItem('app_cfg'), {}) || {};
  830. return app_cfg;
  831. }
  832. })();
  833. // =========================== $page 跳页面相关 避免一次变动,到处乱改 =======================================
  834. (function(){
  835. // 超级对象
  836. var me={};
  837. sa.$page = me;
  838. // 打开登录页面
  839. me.openLogin = function(login_url) {
  840. layer.open({
  841. type: 2,
  842. title: '登录',
  843. shadeClose: true,
  844. shade: 0.8,
  845. area: ['90%', '90%'],
  846. content: login_url || '../../login.html'
  847. });
  848. }
  849. // 打开admin信息界面
  850. me.openAdminInfo = function(id, username) {
  851. var title = username + ' - 账号详情';
  852. if(username === undefined) {
  853. title = '账号详情';
  854. }
  855. sa.showIframe(title, '../sf-admin/admin-info.html?id=' + id, '700px', '600px');
  856. }
  857. })();
  858. // 如果当前是Vue环境, 则挂在到Vue示例
  859. if(window.Vue) {
  860. Vue.prototype.sa = sa;
  861. }
  862. // 如果是sa_admin环境
  863. window.sa_admin = window.sa_admin || parent.sa_admin || top.sa_admin;
  864. // 对外开放, 在模块化时解开此注释
  865. // export default sa;