sa.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388
  1. // =========================== sa对象封装一系列工具方法 ===========================
  2. var sa = {
  3. version: '2.4.3',
  4. update_time: '2020-10-2',
  5. info: '新增双击layer标题处全屏'
  6. };
  7. // =========================== 当前环境配置 =======================================
  8. (function(){
  9. // 公司开发环境
  10. var cfg_dev = {
  11. api_url: 'http://192.168.3.217:8099/pro', // 所有ajax请求接口父地址
  12. web_url: 'http://www.baidu.com' // 此项目前台地址 (此配置项非必须)
  13. }
  14. // 服务器测试环境
  15. var cfg_test = {
  16. api_url: 'http://47.101.143.145/pro',
  17. web_url: 'http://www.baidu.com'
  18. }
  19. // 正式生产环境
  20. var cfg_prod = {
  21. api_url: 'http://116.252.74.16:8099/pro',
  22. web_url: 'http://www.baidu.com'
  23. }
  24. sa.cfg = cfg_prod; // 最终环境 , 上线前请选择正确的环境
  25. })();
  26. // =========================== ajax的封装 =======================================
  27. (function(){
  28. sa.ajaxNoLoading = function(url, data, success200, cfg){
  29. // 如果是简写模式(省略了data参数)
  30. if(typeof data === 'function'){
  31. cfg = success200;
  32. success200 = data;
  33. data = {};
  34. }
  35. // 默认配置
  36. var defaultCfg = {
  37. baseUrl: (url.indexOf('http') === 0 ? '' : sa.cfg.api_url),// 父url,拼接在url前面
  38. sleep: 0, // 休眠n毫秒处理回调函数
  39. type: 'post', // 默认请求类型
  40. success200: success200, // code=200, 代表成功
  41. success500: function(res){ // code=500, 代表失败
  42. return layer.alert('失败:' + res.msg);
  43. },
  44. success403: function(res){ // code=403, 代表权限不足
  45. return layer.alert("权限不足," + res.msg, {icon: 5});
  46. },
  47. success401: function(res){ // code=401, 代表未登录
  48. return layer.confirm("您当前暂未登录,是否立即登录?", {}, function(){
  49. layer.closeAll();
  50. return sa.$page.openLogin(cfg.login_url);
  51. });
  52. },
  53. errorfn: function(xhr, type, errorThrown){ // ajax发生异常时的默认处理函数
  54. if(xhr.status == 0){
  55. return layer.alert('无法连接到服务器,请检查网络');
  56. }
  57. return layer.alert("异常:" + JSON.stringify(xhr));
  58. },
  59. complete: function(xhr, ts) { // 成功失败都会执行
  60. }
  61. }
  62. // 将调用者的配置和默认配置合并
  63. cfg = sa.extendJson(cfg, defaultCfg);
  64. // 开始显示loading图标
  65. if(cfg.msg != null){
  66. sa.loading(cfg.msg);
  67. }
  68. // 开始请求ajax
  69. return $.ajax({
  70. url: cfg.baseUrl + url,
  71. type: cfg.type,
  72. data: data,
  73. dataType: 'json',
  74. // xhrFields: {
  75. // withCredentials: true // 携带跨域cookie
  76. // },
  77. // crossDomain: true,
  78. beforeSend: function(xhr) {
  79. xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
  80. // 追加token
  81. if(localStorage.tokenName) {
  82. xhr.setRequestHeader(localStorage.tokenName, localStorage.tokenValue);
  83. }
  84. },
  85. success: function(res){
  86. setTimeout(function() {
  87. sa.hideLoading();
  88. // 如果相应的处理函数存在
  89. if(cfg['success' + res.code] != undefined) {
  90. return cfg['success' + res.code](res);
  91. }
  92. layer.alert('未知状态码:' + JSON.stringify(res));
  93. }, cfg.sleep);
  94. },
  95. error: function(xhr, type, errorThrown){
  96. setTimeout(function() {
  97. sa.hideLoading();
  98. return cfg.errorfn(xhr, type, errorThrown);
  99. }, cfg.sleep);
  100. },
  101. complete: cfg.complete
  102. });
  103. };
  104. /** 对ajax的再封装, 这个ajax假设你的接口会返回以下格式的内容
  105. {
  106. "code": 200,
  107. "msg": "ok",
  108. "data": []
  109. }
  110. 如果返回的不是这个格式, 你可能需要改动一下源码, 要么改动服务端适应此ajax, 要么改动这个ajax适应你的服务端
  111. * @param {Object} url 请求地址
  112. * @param {Object} data 请求参数
  113. * @param {Object} success200 当返回的code码==200时的回调函数
  114. * @param {Object} 其它配置,可配置项有:
  115. {
  116. msg: '', // 默认的提示文字 填null为不提示
  117. type: 'get', // 设定请求类型 默认post
  118. baseUrl: '', // ajax请求拼接的父路径 默认取 sa.cfg.api_url
  119. sleep: 0, // ajax模拟的延时毫秒数, 默认0
  120. success500: fn, // code码等于500时的回调函数 (一般代表服务器错误)
  121. success403: fn, // code码等于403时的回调函数 (一般代表无权限)
  122. success401: fn, // code码等于401时的回调函数 (一般代表未登录)
  123. errorfn: fn, // ajax发生错误时的回调函数 (一般是ajax请求本身发生了错误)
  124. complete: fn, // ajax无论成功还是失败都会执行的回调函数
  125. }
  126. */
  127. sa.ajax = function(url, data, success200, cfg){
  128. // 如果是简写模式(省略了data参数)
  129. if(typeof data === 'function'){
  130. cfg = success200;
  131. success200 = data;
  132. data = {};
  133. }
  134. // 默认配置
  135. var defaultCfg = {
  136. msg: '努力加载中...', // 提示语
  137. baseUrl: (url.indexOf('http') === 0 ? '' : sa.cfg.api_url),// 父url,拼接在url前面
  138. sleep: 0, // 休眠n毫秒处理回调函数
  139. type: 'post', // 默认请求类型
  140. success200: success200, // code=200, 代表成功
  141. success500: function(res){ // code=500, 代表失败
  142. return layer.alert('失败:' + res.msg);
  143. },
  144. success403: function(res){ // code=403, 代表权限不足
  145. return layer.alert("权限不足," + res.msg, {icon: 5});
  146. },
  147. success401: function(res){ // code=401, 代表未登录
  148. return layer.confirm("您当前暂未登录,是否立即登录?", {}, function(){
  149. layer.closeAll();
  150. return sa.$page.openLogin(cfg.login_url);
  151. });
  152. },
  153. errorfn: function(xhr, type, errorThrown){ // ajax发生异常时的默认处理函数
  154. if(xhr.status == 0){
  155. return layer.alert('无法连接到服务器,请检查网络');
  156. }
  157. return layer.alert("异常:" + JSON.stringify(xhr));
  158. },
  159. complete: function(xhr, ts) { // 成功失败都会执行
  160. }
  161. }
  162. // 将调用者的配置和默认配置合并
  163. cfg = sa.extendJson(cfg, defaultCfg);
  164. // 开始显示loading图标
  165. if(cfg.msg != null){
  166. sa.loading(cfg.msg);
  167. }
  168. // 开始请求ajax
  169. return $.ajax({
  170. url: cfg.baseUrl + url,
  171. type: cfg.type,
  172. data: data,
  173. dataType: 'json',
  174. // xhrFields: {
  175. // withCredentials: true // 携带跨域cookie
  176. // },
  177. // crossDomain: true,
  178. beforeSend: function(xhr) {
  179. xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
  180. // 追加token
  181. if(localStorage.tokenName) {
  182. xhr.setRequestHeader(localStorage.tokenName, localStorage.tokenValue);
  183. }
  184. },
  185. success: function(res){
  186. console.log('返回数据:', res);
  187. setTimeout(function() {
  188. sa.hideLoading();
  189. // 如果相应的处理函数存在
  190. if(cfg['success' + res.code] != undefined) {
  191. return cfg['success' + res.code](res);
  192. }
  193. layer.alert('未知状态码:' + JSON.stringify(res));
  194. }, cfg.sleep);
  195. },
  196. error: function(xhr, type, errorThrown){
  197. setTimeout(function() {
  198. sa.hideLoading();
  199. return cfg.errorfn(xhr, type, errorThrown);
  200. }, cfg.sleep);
  201. },
  202. complete: cfg.complete
  203. });
  204. };
  205. // 模拟一个ajax
  206. // 请注意: 本模板中所有ajax请求调用的均为此模拟函数
  207. sa.ajax2 = function(url, data, success200, cfg){
  208. // 如果是简写模式(省略了data参数)
  209. if(typeof data === 'function'){
  210. cfg = success200;
  211. success200 = data;
  212. data = {};
  213. }
  214. // 几个默认配置
  215. cfg = cfg || {};
  216. cfg.baseUrl = (url.indexOf('http') === 0 ? '' : sa.cfg.api_url); // 父url,拼接在url前面
  217. // 设定一个默认的提示文字
  218. if(cfg.msg == undefined || cfg.msg == null || cfg.msg == '') {
  219. cfg.msg = '正在努力加载...';
  220. }
  221. // 默认延时函数
  222. if(cfg.sleep == undefined || cfg.sleep == null || cfg.sleep == '' || cfg.sleep == 0) {
  223. cfg.sleep = 600;
  224. }
  225. // 默认的模拟数据
  226. cfg.res = cfg.res || {
  227. code: 200,
  228. msg: 'ok',
  229. data: []
  230. }
  231. // 开始loding
  232. sa.loading(cfg.msg);
  233. // 打印请求地址和参数, 以便调试
  234. console.log("======= 模拟ajax =======");
  235. console.log("请求地址:" + cfg.baseUrl + url);
  236. console.log("请求参数:" + JSON.stringify(data));
  237. // 模拟ajax的延时
  238. setTimeout(function() {
  239. sa.hideLoading(); // 隐藏掉转圈圈
  240. console.log('返回数据:', cfg.res);
  241. success200(cfg.res);
  242. }, cfg.sleep)
  243. };
  244. })();
  245. // =========================== 封装弹窗相关函数 =======================================
  246. (function() {
  247. var me = sa;
  248. if(window.layer) {
  249. layer.ready(function(){});
  250. }
  251. // tips提示文字
  252. me.msg = function(msg, cfg) {
  253. msg = msg || '操作成功';
  254. layer.msg(msg, cfg);
  255. };
  256. // 操作成功的提示
  257. me.ok = function(msg) {
  258. msg = msg || '操作成功';
  259. layer.msg(msg, {anim: 0, icon: 1 });
  260. }
  261. me.ok2 = function(msg) {
  262. msg = msg || '操作成功';
  263. layer.msg(msg, {anim: 0, icon: 6 });
  264. }
  265. // 操作失败的提示
  266. me.error = function(msg) {
  267. msg = msg || '操作失败';
  268. layer.msg(msg, {anim: 6, icon: 2 });
  269. }
  270. me.error2 = function(msg) {
  271. msg = msg || '操作失败';
  272. layer.msg(msg, {anim: 6, icon: 5 });
  273. }
  274. // alert弹窗 [text=提示文字, okFn=点击确定之后的回调函数]
  275. me.alert = function(text, okFn) {
  276. // 开始弹窗
  277. layer.alert(text, function(index) {
  278. layer.close(index);
  279. if(okFn) {
  280. okFn();
  281. }
  282. });
  283. };
  284. // 询问框 [text=提示文字, okFn=点击确定之后的回调函数]
  285. me.confirm = function(text, okFn) {
  286. layer.confirm(text, {}, function(index) {
  287. layer.close(index);
  288. if(okFn) {
  289. okFn();
  290. }
  291. }.bind(this));
  292. };
  293. // 输入框 [title=提示文字, okFn=点击确定后的回调函数, formType=输入框类型(0=文本,1=密码,2=多行文本域) 可省略, value=默认值 可省略 ]
  294. me.prompt = function(title, okFn, formType, value) {
  295. layer.prompt({
  296. title: title,
  297. formType: formType,
  298. value: value
  299. }, function(pass, index){
  300. layer.close(index);
  301. if(okFn) {
  302. okFn(pass);
  303. }
  304. });
  305. }
  306. // 打开loading
  307. me.loading = function(msg) {
  308. layer.closeAll(); // 开始前先把所有弹窗关了
  309. return layer.msg(msg, {icon: 16, shade: 0.3, time: 1000 * 20, skin: 'ajax-layer-load' });
  310. };
  311. // 隐藏loading
  312. me.hideLoading = function() {
  313. layer.closeAll();
  314. };
  315. // ============== 一些常用弹窗 =====================
  316. // 大窗显示一个图片
  317. // 参数: src=地址、w=宽度(默认80%)、h=高度(默认80%)
  318. me.showImage = function(src, w, h) {
  319. w = w || '80%';
  320. h = h || '80%';
  321. var content = '<div style="height: 100%; overflow: hidden !important;">' +
  322. '<img src="' + src + ' " style="width: 100%; height: 100%;" />' +
  323. '</div>';
  324. layer.open({
  325. type: 1,
  326. title: false,
  327. shadeClose: true,
  328. closeBtn: 0,
  329. area: [w, h], //宽高
  330. content: content
  331. });
  332. }
  333. // 预览一组图片
  334. // srcList=图片路径数组(可以是json样,也可以是逗号切割式), index=打开立即显示哪张(可填下标, 也可填写src路径)
  335. me.showImageList = function(srcList, index) {
  336. // 如果填的是个string
  337. srcList = srcList || [];
  338. if(typeof srcList === 'string') {
  339. try{
  340. srcList = JSON.parse(srcList);
  341. }catch(e){
  342. try{
  343. srcList = srcList.split(','); // 尝试字符串切割
  344. }catch(e){
  345. srcList = [];
  346. }
  347. }
  348. }
  349. // 如果填的是路径
  350. index = index || 0;
  351. if(typeof index === 'string') {
  352. index = srcList.indexOf(index);
  353. index = (index == -1 ? 0 : index);
  354. }
  355. // 开始展示
  356. var arr_list = [];
  357. srcList.forEach(function(item) {
  358. arr_list.push({
  359. alt: '左右键切换',
  360. pid: 1,
  361. src: item,
  362. thumb: item
  363. })
  364. })
  365. layer.photos({
  366. photos: {
  367. title: '',
  368. id: new Date().getTime(),
  369. start: index,
  370. data: arr_list
  371. }
  372. ,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
  373. });
  374. }
  375. // 显示一个iframe
  376. // 参数: 标题,地址,宽,高 , 点击遮罩是否关闭, 默认false
  377. me.showIframe = function(title, url, w, h, shadeClose) {
  378. // 参数修正
  379. w = w || '95%';
  380. h = h || '95%';
  381. shadeClose = (shadeClose === undefined ? false : shadeClose);
  382. // 弹出面板
  383. var index = layer.open({
  384. type: 2,
  385. title: title, // 标题
  386. shadeClose: shadeClose, // 是否点击遮罩关闭
  387. maxmin: true, // 显示最大化按钮
  388. shade: 0.8, // 遮罩透明度
  389. scrollbar: false, // 屏蔽掉外层的滚动条
  390. moveOut: true, // 是否可拖动到外面
  391. area: [w, h], // 大小
  392. content: url, // 传值
  393. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  394. resizing: function(layero) {
  395. solveLayerBug(index);
  396. }
  397. });
  398. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  399. $('#layui-layer' + index + ' .layui-layer-max').click(function() {
  400. setTimeout(function() {
  401. solveLayerBug(index);
  402. }, 200)
  403. })
  404. }
  405. me.showView = me.showIframe;
  406. // 显示一个iframe, 底部按钮方式
  407. // 参数: 标题,地址,点击确定按钮执行的代码(在子窗口执行),宽,高
  408. me.showIframe2 = function(title, url, evalStr, w, h) {
  409. // 参数修正
  410. w = w || '95%';
  411. h = h || '95%';
  412. // 弹出面板
  413. var index = layer.open({
  414. type: 2,
  415. title: title, // 标题
  416. closeBtn: (title ? 1 : 0), // 是否显示关闭按钮
  417. btn: ['确定', '取消'],
  418. shadeClose: false, // 是否点击遮罩关闭
  419. maxmin: true, // 显示最大化按钮
  420. shade: 0.8, // 遮罩透明度
  421. scrollbar: false, // 屏蔽掉外层的滚动条
  422. moveOut: true, // 是否可拖动到外面
  423. area: [w, h], // 大小
  424. content: url, // 传值
  425. // 解决拉伸或者最大化的时候,iframe高度不能自适应的问题
  426. resizing: function(layero) {
  427. },
  428. yes: function(index, layero) {
  429. var iframe = document.getElementById('layui-layer-iframe' + index);
  430. var iframeWindow = iframe.contentWindow;
  431. iframeWindow.eval(evalStr);
  432. }
  433. });
  434. }
  435. // 当前iframe关闭自身 (在iframe中调用)
  436. me.closeCurrIframe = function() {
  437. try{
  438. var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
  439. parent.layer.close(index); //再执行关闭
  440. }catch(e){
  441. //TODO handle the exception
  442. }
  443. }
  444. me.closeCurrView = me.closeCurrIframe;
  445. //执行一个函数, 解决layer拉伸或者最大化的时候,iframe高度不能自适应的问题
  446. function solveLayerBug(index) {
  447. var selected = '#layui-layer' + index;
  448. var height = $(selected).height();
  449. var title_height = $(selected).find('.layui-layer-title').height();
  450. $(selected).find('iframe').css('height', (height - title_height) + 'px');
  451. }
  452. // 监听回车事件,达到回车关闭弹窗的效果
  453. if(window.$) {
  454. $(document).on('keydown', function() {
  455. if(event.keyCode === 13 && $(".layui-layer-btn0").length == 1 && !window.is_not_watch_enter && $(this).find('.layui-layer-input').length == 0){
  456. $(".layui-layer-btn0").click();
  457. return false;
  458. }
  459. });
  460. }
  461. })();
  462. // =========================== 常用util函数封装 =======================================
  463. (function () {
  464. // 超级对象
  465. var me = sa;
  466. // =========================== 常用util函数封装 =======================================
  467. if(true) {
  468. // 从url中查询到指定参数值
  469. me.p = function(name, defaultValue){
  470. var query = window.location.search.substring(1);
  471. var vars = query.split("&");
  472. for (var i=0;i<vars.length;i++) {
  473. var pair = vars[i].split("=");
  474. if(pair[0] == name){return pair[1];}
  475. }
  476. return(defaultValue == undefined ? null : defaultValue);
  477. }
  478. me.q = function(name, defaultValue){
  479. var query = window.location.search.substring(1);
  480. var vars = query.split("&");
  481. for (var i=0;i<vars.length;i++) {
  482. var pair = vars[i].split("=");
  483. if(pair[0] == name){return pair[1];}
  484. }
  485. return(defaultValue == undefined ? null : defaultValue);
  486. }
  487. // 判断一个变量是否为null
  488. // 返回true或false,如果return_obj有值,则在true的情况下返回return_obj
  489. me.isNull = function(obj, return_obj){
  490. var flag = [null, undefined, '', 'null', 'undefined'].indexOf(obj) != -1;
  491. if(return_obj === undefined){
  492. return flag;
  493. } else {
  494. if(flag){
  495. return return_obj;
  496. } else {
  497. return obj;
  498. }
  499. }
  500. }
  501. // 将时间戳转化为指定时间
  502. // way:方式(1=年月日,2=年月日时分秒)默认1, 也可以指定格式:yyyy-MM-dd HH:mm:ss
  503. me.forDate = function(inputTime, way) {
  504. if(me.isNull(inputTime) == true){
  505. return "";
  506. }
  507. var date = new Date(inputTime);
  508. var y = date.getFullYear();
  509. var m = date.getMonth() + 1;
  510. m = m < 10 ? ('0' + m) : m;
  511. var d = date.getDate();
  512. d = d < 10 ? ('0' + d) : d;
  513. var h = date.getHours();
  514. h = h < 10 ? ('0' + h) : h;
  515. var minute = date.getMinutes();
  516. var second = date.getSeconds();
  517. minute = minute < 10 ? ('0' + minute) : minute;
  518. second = second < 10 ? ('0' + second) : second;
  519. var ms = date.getMilliseconds();
  520. way = way || 1;
  521. // way == 1 年月日
  522. if(way === 1) {
  523. return y + '-' + m + '-' + d;
  524. }
  525. // way == 1 年月日时分秒
  526. if(way === 2){
  527. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  528. }
  529. // way == 具体格式 标准格式: yyyy-MM-dd HH:mm:ss
  530. if(typeof way == 'string') {
  531. return way.replace("yyyy", y).replace("MM", m).replace("dd", d).replace("HH", h).replace("mm", minute).replace("ss", second).replace("ms", ms);
  532. }
  533. return y + '-' + m + '-' + d;
  534. };
  535. // 时间日期
  536. me.forDatetime = function(inputTime) {
  537. return me.forDate(inputTime, 2);
  538. }
  539. // 将时间转化为 个性化 如:3小时前,
  540. // d1 之于 d2 ,d2不填则默认取当前时间
  541. me.forDate2 = function(d, d2){
  542. var hou = "前";
  543. if(d == null || d == '') {
  544. return '';
  545. }
  546. if(d2 == null || d2 == '') {
  547. d2 = new Date();
  548. }
  549. d2 = new Date(d2).getTime();
  550. var timestamp = new Date(d).getTime() - 1000;
  551. var mistiming = Math.round((d2 - timestamp) / 1000);
  552. if(mistiming < 0) {
  553. mistiming = 0 - mistiming;
  554. hou = '后'
  555. }
  556. var arrr = ['年', '月', '周', '天', '小时', '分钟', '秒'];
  557. var arrn = [31536000, 2592000, 604800, 86400, 3600, 60, 1];
  558. for (var i = 0; i < arrn.length; i++) {
  559. var inm = Math.floor(mistiming / arrn[i]);
  560. if (inm != 0) {
  561. return inm + arrr[i] + hou;
  562. }
  563. }
  564. }
  565. // 综合以上两种方式,进行格式化
  566. // 小于24小时的走forDate2,否则forDat
  567. me.forDate3 = function(d, way) {
  568. if(d == null || d == '' ) {
  569. return '';
  570. }
  571. var cha = new Date().getTime() - new Date(d).getTime();
  572. cha = (cha > 0 ? cha : 0 - cha);
  573. if(cha < (86400 * 1000)) {
  574. return me.forDate2(d);
  575. }
  576. return me.forDate(d, way);
  577. }
  578. // 返回时间差, 此格式数组:[x, x, x, 天, 时, 分, 秒]
  579. me.getSJC = function (small_time, big_time) {
  580. var date1 = new Date(small_time); //开始时间
  581. var date2 = new Date(big_time); //结束时间
  582. var date3 = date2.getTime() - date1.getTime(); //时间差秒
  583. //计算出相差天数
  584. var days = Math.floor(date3 / (24 * 3600 * 1000));
  585. //计算出小时数
  586. var leave1 = date3 % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
  587. var hours = Math.floor(leave1 / (3600 * 1000));
  588. //计算相差分钟数
  589. var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
  590. var minutes = Math.floor(leave2 / (60 * 1000));
  591. //计算相差秒数
  592. var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
  593. var seconds = Math.round(leave3 / 1000);
  594. // 返回数组
  595. return [0, 0, 0, days, hours, minutes, seconds];
  596. }
  597. // 将日期,加上指定天数
  598. me.dateAdd = function(d, n) {
  599. var s = new Date(d).getTime();
  600. s += 86400000 * n;
  601. return new Date(s);
  602. }
  603. // 转化json,出错返回默认值
  604. me.JSONParse = function(obj, default_obj){
  605. try{
  606. return JSON.parse(obj) || default_obj;
  607. }catch(e){
  608. return default_obj || {};
  609. }
  610. }
  611. // 截取指定长度字符,默认50
  612. me.maxLength = function (str, length) {
  613. length = length || 50;
  614. if(!str){
  615. return "";
  616. }
  617. return (str.length > length) ? str.substr(0, length) + ' ...' : str;
  618. },
  619. // 过滤掉标签
  620. me.text = function(str){
  621. if(!str){
  622. return "";
  623. }
  624. return str.replace(/<[^>]+>/g,"");
  625. }
  626. // 为指定集合的每一项元素添加上is_update属性
  627. me.listAU = function(list){
  628. list.forEach(function(ts){
  629. ts.is_update = false;
  630. })
  631. return list;
  632. }
  633. // 获得一段文字中所有图片的路径
  634. me.getSrcList = function(str){
  635. try{
  636. var imgReg = /<img.*?(?:>|\/>)/gi; //匹配图片(g表示匹配所有结果i表示区分大小写)
  637. var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; //匹配src属性
  638. var arr = str.match(imgReg); // 图片数组
  639. var srcList = [];
  640. for (var i = 0; i < arr.length; i++) {
  641. var src = arr[i].match(srcReg);
  642. srcList.push(src[1]);
  643. }
  644. return srcList;
  645. } catch (e){
  646. return [];
  647. }
  648. }
  649. // 无精度损失的乘法
  650. me.accMul = function(arg1, arg2) {
  651. var m = 0,
  652. s1 = arg1.toString(),
  653. s2 = arg2.toString(),
  654. t;
  655. t = s1.split(".");
  656. // 判断有没有小数位,避免出错
  657. if (t[1]) {
  658. m += t[1].length
  659. }
  660. t = s2.split(".");
  661. if (t[1]) {
  662. m += t[1].length
  663. }
  664. return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
  665. }
  666. // 正则验证是否为手机号
  667. me.isPhone = function(str) {
  668. str = str + '';
  669. if((/^1[34578]\d{9}$/.test(str))){
  670. return true;
  671. }
  672. return false;
  673. }
  674. me.isNum = function(str) {
  675. str = str + '';
  676. if((/^[0-9]*$/.test(str))||(/^[0-9]+(.[0-9]{1})?$/.test(str))){
  677. return true;
  678. }
  679. return false;
  680. }
  681. // 产生随机字符串
  682. me.randomString = function(len) {
  683.   len = len || 32;
  684.   var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
  685.   var maxPos = $chars.length;
  686.   var str = '';
  687.   for (i = 0; i < len; i++) {
  688.     str += $chars.charAt(Math.floor(Math.random() * maxPos));
  689.   }
  690.   return str;
  691. }
  692. // 刷新页面
  693. me.f5 = function() {
  694. location.reload();
  695. }
  696. // 动态加载js
  697. me.loadJS = function(src, onload) {
  698. var script = document.createElement("script");
  699. script.setAttribute("type", "text/javascript");
  700. script.src = src;
  701. script.onload = onload;
  702. document.body.appendChild(script);
  703. }
  704. // 产生随机数字
  705. me.randomNum = function(min, max) {
  706. return parseInt(Math.random() * (max - min + 1) + min, 10);
  707. }
  708. // 打开页面
  709. me.open = function(url) {
  710. window.open(url);
  711. }
  712. // == if 结束
  713. }
  714. // =========================== 数组操作 =======================================
  715. if (true) {
  716. // 从数组里获取数据,根据指定数据
  717. me.getArrayField = function(arr, prop){
  718. var propArr = [];
  719. for (var i = 0; i < arr.length; i++) {
  720. propArr.push(arr[i][prop]);
  721. }
  722. return propArr;
  723. }
  724. // 从数组里获取数据,根据指定数据
  725. me.arrayGet = function(arr, prop, value){
  726. for (var i = 0; i < arr.length; i++) {
  727. if(arr[i][prop] == value){
  728. return arr[i];
  729. }
  730. }
  731. return null;
  732. }
  733. // 正则验证是否为手机号
  734. me.isPhone = function(str) {
  735. str = str + '';
  736. if ((/^1[3456789]\d{9}$/.test(str))) {
  737. return true;
  738. }
  739. return false;
  740. }
  741. // 从数组删除指定记录
  742. me.arrayDelete = function(arr, item){
  743. if(item instanceof Array) {
  744. for (let i = 0; i < item.length; i++) {
  745. let ite = item[i];
  746. let index = arr.indexOf(ite);
  747. if (index > -1) {
  748. arr.splice(index, 1);
  749. }
  750. }
  751. } else {
  752. var index = arr.indexOf(item);
  753. if (index > -1) {
  754. arr.splice(index, 1);
  755. }
  756. }
  757. }
  758. // 从数组删除指定id的记录
  759. me.arrayDeleteById = function(arr, id){
  760. var item = me.arrayGet(arr, 'id', id);
  761. me.arrayDelete(arr, item);
  762. }
  763. // 将数组B添加到数组A的开头
  764. me.unshiftArray = function(arrA, arrB){
  765. if(arrB){
  766. arrB.reverse().forEach(function(ts){
  767. arrA.unshift(ts);
  768. })
  769. }
  770. return arrA;
  771. }
  772. // 将数组B添加到数组A的末尾
  773. me.pushArray = function(arrA, arrB){
  774. if(arrB){
  775. arrB.forEach(function(ts){
  776. arrA.push(ts);
  777. })
  778. }
  779. return arrA;
  780. }
  781. // == if 结束
  782. }
  783. // =========================== 浏览器相关 =======================================
  784. if (true) {
  785. // set cookie 值
  786. me.setCookie = function setCookie(cname, cvalue, exdays) {
  787. exdays = exdays || 30;
  788. var d = new Date();
  789. d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
  790. var expires = "expires=" + d.toGMTString();
  791. document.cookie = cname + "=" + escape(cvalue) + "; " + expires + "; path=/";
  792. }
  793. // get cookie 值
  794. me.getCookie = function(objName){
  795. var arrStr = document.cookie.split("; ");
  796. for (var i = 0; i < arrStr.length; i++) {
  797. var temp = arrStr[i].split("=");
  798. if (temp[0] == objName){
  799. return unescape(temp[1])
  800. };
  801. }
  802. return "";
  803. }
  804. // 复制指定文本
  805. me.copyText = function(str){
  806. var oInput = document.createElement('input');
  807. oInput.value = str;
  808. document.body.appendChild(oInput);
  809. oInput.select(); // 选择对象
  810. document.execCommand("Copy"); // 执行浏览器复制命令
  811. oInput.className = 'oInput';
  812. oInput.style.display='none';
  813. }
  814. // jquery序列化表单增强版: 排除空值
  815. me.serializeNotNull = function(selected){
  816. var serStr = $(selected).serialize();
  817. return serStr.split("&").filter(function(str){return !str.endsWith("=")}).join("&");
  818. }
  819. // 将cookie序列化为k=v形式
  820. me.strCookie = function(){
  821. return document.cookie.replace(/; /g,"&");
  822. }
  823. // 回到顶部
  824. me.goTop = function() {
  825. function smoothscroll(){
  826. var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
  827. if (currentScroll > 0) {
  828. window.requestAnimationFrame(smoothscroll);
  829. window.scrollTo (0,currentScroll - (currentScroll/5));
  830. }
  831. };
  832. smoothscroll();
  833. }
  834. // == if 结束
  835. }
  836. // =========================== javascript对象操作 =======================================
  837. if (true) {
  838. // 去除json对象中的空值
  839. me.removeNull = function(obj){
  840. var newObj = {};
  841. if(obj != undefined && obj != null) {
  842. for(var key in obj) {
  843. if(obj[key] === undefined || obj[key] === null || obj[key] === '') {
  844. //
  845. } else {
  846. newObj[key] = obj[key];
  847. }
  848. }
  849. }
  850. return newObj;
  851. }
  852. // JSON 浅拷贝, 返回拷贝后的obj
  853. me.copyJSON = function(obj){
  854. if(obj === null || obj === undefined) {
  855. return obj;
  856. };
  857. var new_obj = {};
  858. for(var key in obj) {
  859. new_obj[key] = obj [key];
  860. }
  861. return new_obj;
  862. }
  863. // json合并, 将 defaulet配置项 转移到 user配置项里 并返回 user配置项
  864. me.extendJson = function(userOption, defaultOption) {
  865. if(!userOption) {
  866. return defaultOption;
  867. };
  868. for(var key in defaultOption) {
  869. if(userOption[key] === undefined) {
  870. userOption[key] = defaultOption[key];
  871. } else if(userOption[key] == null){
  872. } else if(typeof userOption[key] == "object") {
  873. me.extendJson(userOption[key], defaultOption[key]); //深度匹配
  874. }
  875. }
  876. return userOption;
  877. }
  878. // == if 结束
  879. }
  880. // =========================== 本地集合存储 =======================================
  881. if (true) {
  882. // 获取指定key的list
  883. me.keyListGet = function(key){
  884. try{
  885. var str = localStorage.getItem('LIST_' + key);
  886. if(str == undefined || str == null || str =='' || str == 'undefined' || typeof(JSON.parse(str)) == 'string'){
  887. //alert('key' + str);
  888. str = '[]';
  889. }
  890. return JSON.parse(str);
  891. }catch(e){
  892. return [];
  893. }
  894. },
  895. me.keyListSet = function(key, list){
  896. localStorage.setItem('LIST_' + key, JSON.stringify(list));
  897. },
  898. me.keyListHas = function(key, item){
  899. var arr2 = me.keyListGet(key);
  900. return arr2.indexOf(item) != -1;
  901. },
  902. me.keyListAdd = function(key, item){
  903. var arr = me.keyListGet(key);
  904. arr.push(item);
  905. me.keyListSet(key,arr);
  906. },
  907. me.keyListRemove = function(key, item){
  908. var arr = me.keyListGet(key);
  909. var index = arr.indexOf(item);
  910. if (index > -1) {
  911. arr.splice(index, 1);
  912. }
  913. me.keyListSet(key,arr);
  914. }
  915. // == if 结束
  916. }
  917. // =========================== 对sa-admin的优化 =======================================
  918. if (true) {
  919. // 封装element-ui的导出表格
  920. // 参数:选择器(默认.data-count),fileName=导出的文件名称
  921. me.exportExcel = function(select, fileName) {
  922. // 声明函数
  923. let exportExcel_fn = function(select, fileName) {
  924. // 赋默认值
  925. select = select || '.data-table';
  926. fileName = fileName || 'table.xlsx';
  927. // 开始导出
  928. let wb = XLSX.utils.table_to_book(document.querySelector(select)); // 这里就是表格
  929. let sheet = wb.Sheets.Sheet1; // 单元表
  930. try{
  931. // 强改宽度
  932. sheet['!cols'] = sheet['!cols'] || [];
  933. let thList = document.querySelector(select).querySelectorAll('.el-table__header-wrapper tr th');
  934. for (var i = 0; i < thList.length; i++) {
  935. // 如果是多选框
  936. if(thList[i].querySelector('.el-checkbox')) {
  937. sheet['!cols'].push({ wch: 5 }); // 强改宽度
  938. continue;
  939. }
  940. sheet['!cols'].push({ wch: 15 }); // 强改宽度
  941. }
  942. // 强改高度
  943. sheet['!rows'] = sheet['!rows'] || [];
  944. let trList = document.querySelector(select).querySelectorAll('.el-table__body-wrapper tbody tr');
  945. for (var i = 0; i < trList.length + 1; i++) {
  946. sheet['!rows'].push({ hpx: 20 }); // 强改高度
  947. }
  948. } catch(e) {
  949. console.err(e);
  950. }
  951. // 开始制作并输出
  952. let wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' });
  953. // 点击
  954. let blob = new Blob([wbout], { type: 'application/octet-stream'});
  955. const a= document.createElement("a")
  956. a.href = URL.createObjectURL(blob)
  957. a.download = fileName // 这里填保存成的文件名
  958. a.click()
  959. URL.revokeObjectURL(a.href)
  960. a.remove();
  961. sa.hideLoading();
  962. }
  963. sa.loading('正在导出...');
  964. // 判断是否首次加载
  965. if(window.XLSX) {
  966. return exportExcel_fn(select, fileName);
  967. } else {
  968. me.loadJS('https://unpkg.com/xlsx@0.16.6/dist/xlsx.core.min.js', function() {
  969. return exportExcel_fn(select, fileName);
  970. });
  971. }
  972. }
  973. // 刷新表格高度, 请务必在所有表格高度发生变化的地方调用此方法
  974. me.f5TableHeight = function() {
  975. Vue.nextTick(function() {
  976. if($('.el-table.data-table .el-table__body-wrapper table').length == 0) {
  977. return;
  978. }
  979. var _f5Height = function() {
  980. var height = $('.el-table .el-table__body-wrapper table').height();
  981. height = height == 0 ? 60 : height;
  982. // 判断是否有滚动条
  983. var tw = $('.el-table .el-table__body-wrapper').get(0);
  984. if(tw.scrollWidth > tw.clientWidth) {
  985. height = height + 16;
  986. }
  987. if($('.el-table .el-table__body-wrapper table td').width() == 0) {
  988. return;
  989. }
  990. // 设置高度
  991. $('.el-table .el-table__body-wrapper').css('min-height', height);
  992. $('.el-table .el-table__body-wrapper').css('max-height', height);
  993. };
  994. setTimeout(_f5Height, 0)
  995. setTimeout(_f5Height, 200)
  996. })
  997. }
  998. // 在表格查询的页面,监听input回车事件,提交查询
  999. me.onInputEnter = function(app) {
  1000. Vue.nextTick(function() {
  1001. app = app || window.app;
  1002. // document.querySelectorAll('.el-form input').forEach(function(item) {
  1003. // item.onkeydown = function(e) {
  1004. // var theEvent = e || window.event;
  1005. // var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
  1006. // if (code == 13) {
  1007. // app.p.pageNo = 1;
  1008. // app.f5();
  1009. // }
  1010. // }
  1011. // })
  1012. document.querySelectorAll('.el-form').forEach(function(item) {
  1013. item.onkeydown = function(e) {
  1014. var theEvent = e || window.event;
  1015. var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
  1016. if (code == 13) {
  1017. var target = e.target||e.srcElement;
  1018. if(target.tagName.toLowerCase()=="input") {
  1019. app.p.pageNo = 1;
  1020. app.f5();
  1021. }
  1022. }
  1023. }
  1024. })
  1025. })
  1026. }
  1027. // 如果value为true,则抛出异常
  1028. me.check = function(value, errorMsg) {
  1029. if(value === true) {
  1030. throw {type: 'sa-error', msg: errorMsg};
  1031. }
  1032. }
  1033. // 如果value为null,则抛出异常
  1034. me.checkNull = function(value, errorMsg) {
  1035. if(me.isNull(value)) {
  1036. throw {type: 'sa-error', msg: errorMsg};
  1037. }
  1038. }
  1039. // 监听窗口变动
  1040. if(!window.onresize) {
  1041. window.onresize = function() {
  1042. try{
  1043. me.f5TableHeight();
  1044. }catch(e){
  1045. // console.log(e);
  1046. }
  1047. }
  1048. }
  1049. // 双击layer标题处全屏
  1050. if(window.$) {
  1051. $(document).on('mousedown', '.layui-layer-title', function(e) {
  1052. // console.log('单击中');
  1053. if(window.layer_title_last_click_time) {
  1054. var cz = new Date().getTime() - window.layer_title_last_click_time;
  1055. if(cz < 250) {
  1056. console.log('双击');
  1057. $(this).parent().find('.layui-layer-max').click();
  1058. }
  1059. }
  1060. window.layer_title_last_click_time = new Date().getTime();
  1061. })
  1062. }
  1063. // == if 结束
  1064. }
  1065. })();
  1066. // =========================== $sys 有关当前系统的方法 一般不能复制到别的项目中用 =======================================
  1067. (function(){
  1068. // 超级对象
  1069. var me = {};
  1070. sa.$sys = me;
  1071. // ======================= 登录相关 ============================
  1072. // 写入当前已登陆用户信息
  1073. me.setCurrUser = function(currUser){
  1074. localStorage.setItem('currUser', JSON.stringify(currUser));
  1075. }
  1076. // 获得当前已登陆用户信息
  1077. me.getCurrUser = function(){
  1078. var user = localStorage.getItem("currUser");
  1079. if(user == undefined || user == null || user == 'null' || user == '' || user == '{}' || user.length < 10){
  1080. user = {
  1081. id: '0',
  1082. username: '未登录'
  1083. }
  1084. }else{
  1085. user = JSON.parse(user);
  1086. }
  1087. return user;
  1088. }
  1089. // 如果未登录,则强制跳转到登录
  1090. me.checkLogin = function(not_login_url){
  1091. console.log(me.getCurrUser());
  1092. if(me.getCurrUser().id == 0) {
  1093. location.href= not_login_url || '../../login.html';
  1094. throw '未登录,请先登录';
  1095. }
  1096. }
  1097. // 同上, 只不过是以弹窗的形式显示未登录
  1098. me.checkLoginTs = function(not_login_url){
  1099. if(me.getCurrUser().id == 0) {
  1100. sa.$page.openLogin(not_login_url || '../../login.html');
  1101. throw '未登录,请先登录';
  1102. }
  1103. }
  1104. // ========================= 权限验证 =========================
  1105. // 定义key
  1106. var pcode_key = 'permission_code';
  1107. // 写入当前会话的权限码集合
  1108. sa.setAuth = function(codeList) {
  1109. sa.keyListSet(pcode_key, codeList);
  1110. }
  1111. // 清除当前会话的权限码集合
  1112. sa.clearAuth = function() {
  1113. sa.keyListSet(pcode_key, []);
  1114. }
  1115. // 检查当前会话是否拥有一个权限码, 返回true和false
  1116. sa.isAuth = function(pcode) {
  1117. return sa.keyListHas(pcode_key, pcode);
  1118. }
  1119. // 检查当前会话是否拥有一个权限码, 如果没有, 则跳转到无权限页面
  1120. // 注意: 非二级目录页面请注意调整路径问题
  1121. sa.checkAuth = function(pcode, not_pcode_url) {
  1122. var is_have = sa.keyListHas(pcode_key, pcode);
  1123. if(is_have == false) {
  1124. location.href= not_pcode_url || '../../sa-view/error-page/403.html';
  1125. throw '暂无权限: ' + pcode;
  1126. }
  1127. }
  1128. // 同上, 只不过是以弹窗的形式显示出来无权限来
  1129. sa.checkAuthTs = function(pcode, not_pcode_url) {
  1130. var is_have = sa.keyListHas(pcode_key, pcode);
  1131. if(is_have == false) {
  1132. var url = not_pcode_url || '../../sa-view/error-page/403.html';
  1133. layer.open({
  1134. type: 2,
  1135. title: false, // 标题
  1136. shadeClose: true, // 是否点击遮罩关闭
  1137. shade: 0.8, // 遮罩透明度
  1138. scrollbar: false, // 屏蔽掉外层的滚动条
  1139. closeBtn: false,
  1140. area: ['700px', '600px'], // 大小
  1141. content: url // 传值
  1142. });
  1143. throw '暂无权限: ' + pcode;
  1144. }
  1145. }
  1146. // ======================= 配置相关 ============================
  1147. // 写入配置信息
  1148. me.setAppCfg = function(cfg) {
  1149. if(typeof cfg != 'string') {
  1150. cfg = JSON.stringify(cfg);
  1151. }
  1152. localStorage.setItem('app_cfg', cfg);
  1153. }
  1154. // 获取配置信息
  1155. me.getAppCfg = function() {
  1156. var app_cfg = sa.JSONParse(localStorage.getItem('app_cfg'), {}) || {};
  1157. return app_cfg;
  1158. }
  1159. })();
  1160. // =========================== $page 跳页面相关 避免一次变动,到处乱改 =======================================
  1161. (function(){
  1162. // 超级对象
  1163. var me={};
  1164. sa.$page = me;
  1165. // 打开登录页面
  1166. me.openLogin = function(login_url) {
  1167. layer.open({
  1168. type: 2,
  1169. // title: '登录',
  1170. title: false,
  1171. closeBtn: false,
  1172. shadeClose: true,
  1173. shade: 0.8,
  1174. // area: ['90%', '100%'],
  1175. area: ['70%', '80%'],
  1176. // area: ['450px', '360px'],
  1177. resize: false,
  1178. content: login_url || '../../login.html'
  1179. });
  1180. }
  1181. // 打开admin信息界面
  1182. me.openAdminInfo = function(id, username) {
  1183. var title = username + ' - 账号详情';
  1184. if(username === undefined) {
  1185. title = '账号详情';
  1186. }
  1187. sa.showIframe(title, '../sp-admin/admin-info.html?id=' + id, '700px', '600px');
  1188. }
  1189. })();
  1190. // 如果是sa_admin环境
  1191. window.sa_admin = window.sa_admin || parent.sa_admin || top.sa_admin;
  1192. window.saAdmin = window.sa_admin;
  1193. // 如果当前是Vue环境, 则挂在到 Vue 示例
  1194. if(window.Vue) {
  1195. // 全局的 sa 对象
  1196. Vue.prototype.sa = window.sa;
  1197. Vue.prototype.sa_admin = window.sa_admin;
  1198. Vue.prototype.saAdmin = window.saAdmin;
  1199. // 表单校验异常捕获
  1200. Vue.config.errorHandler = function(err, vm) {
  1201. if(err.type == 'sa-error') {
  1202. return sa.error(err.msg);
  1203. }
  1204. throw err;
  1205. }
  1206. // Element-UI 全局组件样式
  1207. Vue.prototype.$ELEMENT = { size: 'mini', zIndex: 3000 };
  1208. // 加载全局组件 (注意路径问题)
  1209. // if(window.httpVueLoader && window.loadComponent !== false) {
  1210. // Vue.component("sa-item", httpVueLoader('../../sa-frame/com/sa-item.vue'));
  1211. // Vue.component("sa-td", httpVueLoader('../../sa-frame/com/sa-td.vue'));
  1212. // }
  1213. }
  1214. // 对外开放, 在模块化时解开此注释
  1215. // export default sa;