util.js 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. import {
  2. base64_encode,
  3. base64_decode
  4. } from './base64.js';
  5. import md5 from './md5.js';
  6. import App from '../../App'
  7. var util = {};
  8. util.base64Encode = function(str) {
  9. return base64_encode(str)
  10. };
  11. util.base64Decode = function(str) {
  12. return base64_decode(str)
  13. };
  14. util.md5 = function(str) {
  15. return md5(str)
  16. };
  17. /**
  18. 构造微擎地址,
  19. @params action 微擎系统中的controller, action, do,格式为 'wxapp/home/navs'
  20. @params querystring 格式为 {参数名1 : 值1, 参数名2 : 值2}
  21. */
  22. util.url = function(action, querystring) {
  23. // console.log('这是util下',App)
  24. var app = App;
  25. var formvar = 'wxapp';
  26. var url = '';
  27. //#ifdef H5
  28. var ua = navigator.userAgent.toLowerCase();
  29. var isWeixin = ua.indexOf('micromessenger') != -1;
  30. if (isWeixin) {
  31. formvar = 'mp';
  32. } else {
  33. formvar = 'h5';
  34. }
  35. //#endif
  36. //#ifdef APP-PLUS
  37. formvar = 'app';
  38. //#endif
  39. url = app.siteInfo.siteroot + '?i=' + app.siteInfo.uniacid + '&t=' + app.siteInfo.multiid + '&v=' + app
  40. .siteInfo.version + '&from=' + formvar + '&';
  41. //#ifdef H5
  42. let urlquery = getQuery(window.location.href);
  43. if (urlquery.length > 0) {
  44. var urli = '';
  45. for (let i = 0; i < urlquery.length; i++) {
  46. if (urlquery[i] && urlquery[i].name && urlquery[i].value) {
  47. if (urlquery[i].name == "i") {
  48. urli = urlquery[i].name + '=' + urlquery[i].value;
  49. }
  50. }
  51. }
  52. if (urli) {
  53. url = window.location.protocol + '//' + window.location.host + '/app/index.php?t=' + app.siteInfo
  54. .multiid + '&v=' + app
  55. .siteInfo
  56. .version + '&from=' + formvar + '&' + urli + '&';
  57. }
  58. }
  59. //#endif
  60. if (action) {
  61. action = action.split('/');
  62. if (action[0]) {
  63. url += 'c=' + action[0] + '&';
  64. }
  65. if (action[1]) {
  66. url += 'a=' + action[1] + '&';
  67. }
  68. if (action[2]) {
  69. url += 'do=' + action[2] + '&';
  70. }
  71. }
  72. if (querystring && typeof querystring === 'object') {
  73. for (let param in querystring) {
  74. if (param && querystring.hasOwnProperty(param) && querystring[param]) {
  75. url += param + '=' + querystring[param] + '&';
  76. }
  77. }
  78. }
  79. //console.log(url);
  80. return url;
  81. }
  82. function getQuery(url) {
  83. var theRequest = [];
  84. if (url.indexOf("?") != -1) {
  85. var str = url.split('?')[1];
  86. if (str.indexOf("#") != -1) {
  87. str = str.split('#')[0]
  88. }
  89. var strs = str.split("&");
  90. for (var i = 0; i < strs.length; i++) {
  91. if (strs[i].split("=")[0] && unescape(strs[i].split("=")[1])) {
  92. theRequest[i] = {
  93. 'name': strs[i].split("=")[0],
  94. 'value': unescape(strs[i].split("=")[1])
  95. }
  96. }
  97. }
  98. }
  99. return theRequest;
  100. }
  101. /*
  102. * 获取链接某个参数
  103. * url 链接地址
  104. * name 参数名称
  105. */
  106. function getUrlParam(url, name) {
  107. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
  108. var r = url.split('?')[1].match(reg); //匹配目标参数
  109. if (r != null) return unescape(r[2]);
  110. return null; //返回参数值
  111. }
  112. /**
  113. * 获取签名 将链接地址的所有参数按字母排序后拼接加上token进行md5
  114. * url 链接地址
  115. * date 参数{参数名1 : 值1, 参数名2 : 值2} *
  116. * token 签名token 非必须
  117. */
  118. function getSign(url, data, token) {
  119. var _ = require('./underscore.js');
  120. var md5 = require('./md5.js');
  121. var querystring = '';
  122. var sign = getUrlParam(url, 'sign');
  123. if (sign || (data && data.sign)) {
  124. return false;
  125. } else {
  126. if (url) {
  127. querystring = getQuery(url);
  128. }
  129. if (data) {
  130. var theRequest = [];
  131. for (let param in data) {
  132. if (param && data[param]) {
  133. theRequest = theRequest.concat({
  134. 'name': param,
  135. 'value': data[param]
  136. })
  137. }
  138. }
  139. querystring = querystring.concat(theRequest);
  140. }
  141. //排序
  142. querystring = _.sortBy(querystring, 'name');
  143. //去重
  144. querystring = _.uniq(querystring, true, 'name');
  145. var urlData = '';
  146. for (let i = 0; i < querystring.length; i++) {
  147. if (querystring[i] && querystring[i].name && querystring[i].value) {
  148. urlData += querystring[i].name + '=' + querystring[i].value;
  149. if (i < (querystring.length - 1)) {
  150. urlData += '&';
  151. }
  152. }
  153. }
  154. token = token ? token : App.siteInfo.token;
  155. sign = md5(urlData + token);
  156. return sign;
  157. }
  158. }
  159. util.getSign = function(url, data, token) {
  160. return getSign(url, data, token);
  161. };
  162. /**
  163. 二次封装微信wx.request函数、增加交互体全、配置缓存、以及配合微擎格式化返回数据
  164. */
  165. util.request = function(option) {
  166. var _ = require('./underscore.js');
  167. var md5 = require('./md5.js');
  168. var app = App;
  169. var option = option ? option : {};
  170. option.cachetime = option.cachetime ? option.cachetime : 0;
  171. //console.log(option.showLoading);
  172. //option.showLoading = typeof option.showLoading != 'undefined' ? option.showLoading : true;
  173. if (typeof option.showLoading == 'undefined') {
  174. option.showLoading = false;
  175. }
  176. //console.log(option.showLoading);
  177. var sessionid = uni.getStorageSync('userInfo').sessionid;
  178. var url = option.url;
  179. if (url.indexOf('http://') == -1 && url.indexOf('https://') == -1) {
  180. url = util.url(url);
  181. }
  182. var state = getUrlParam(url, 'state');
  183. if (!state && !(option.data && option.data.state) && sessionid) {
  184. url = url + '&state=we7sid-' + sessionid
  185. }
  186. if (!option.data || !option.data.m) {
  187. if (App.module) {
  188. url = url + '&m=' + App.module;
  189. } else {
  190. var nowPage = getCurrentPages();
  191. if (nowPage.length) {
  192. nowPage = nowPage[getCurrentPages().length - 1];
  193. if (nowPage && nowPage.__route__) {
  194. url = url + '&m=' + nowPage.__route__.split('/')[0];
  195. }
  196. }
  197. }
  198. }
  199. var sign = getSign(url, option.data);
  200. if (sign) {
  201. url = url + "&sign=" + sign;
  202. }
  203. if (!url) {
  204. return false;
  205. }
  206. if (option.showLoading) {
  207. //uni.showNavigationBarLoading();
  208. util.showLoading();
  209. }
  210. if (option.cachetime) {
  211. var cachekey = md5(url);
  212. var cachedata = uni.getStorageSync(cachekey);
  213. var timestamp = (new Date()).valueOf();
  214. if (cachedata && cachedata.data) {
  215. if (cachedata.expire > timestamp) {
  216. if (option.complete && typeof option.complete == 'function') {
  217. option.complete(cachedata);
  218. }
  219. if (option.success && typeof option.success == 'function') {
  220. option.success(cachedata);
  221. }
  222. //console.log('cache:' + url);
  223. uni.hideLoading();
  224. uni.hideNavigationBarLoading();
  225. return true;
  226. } else {
  227. uni.removeStorageSync(cachekey)
  228. }
  229. }
  230. }
  231. console.log(url);
  232. uni.request({
  233. 'url': url,
  234. 'data': option.data ? option.data : {},
  235. 'header': option.header ? option.header : {},
  236. 'method': option.method ? option.method : 'GET',
  237. 'header': {
  238. 'content-type': 'application/x-www-form-urlencoded'
  239. },
  240. 'success': function(response) {
  241. uni.hideNavigationBarLoading();
  242. uni.hideLoading();
  243. if (response.data.errno) {
  244. if (response.data.errno == '41009') {
  245. uni.setStorageSync('userInfo', '');
  246. util.getUserInfo(function() {
  247. util.request(option)
  248. });
  249. return;
  250. } else {
  251. if (option.fail && typeof option.fail == 'function') {
  252. option.fail(response);
  253. } else {
  254. if (!response.data.message) {
  255. response.data.message = response.data.msg;
  256. }
  257. if (response.data.message) {
  258. if (response.data.data != null && response.data.data.redirect) {
  259. var redirect = response.data.data.redirect;
  260. } else {
  261. var redirect = '';
  262. }
  263. app.util.message(response.data.message, redirect, 'error');
  264. }
  265. }
  266. return;
  267. }
  268. } else {
  269. if (option.success && typeof option.success == 'function') {
  270. option.success(response);
  271. }
  272. //写入缓存,减少HTTP请求,并且如果网络异常可以读取缓存数据
  273. if (option.cachetime) {
  274. var cachedata = {
  275. 'data': response.data,
  276. 'expire': timestamp + option.cachetime * 1000
  277. };
  278. var iscache = 1;
  279. if (option.data) {
  280. if (option.data.samkey) {
  281. iscache = 0;
  282. }
  283. }
  284. if (iscache==1) {
  285. uni.setStorageSync(cachekey, cachedata);
  286. }
  287. }
  288. }
  289. },
  290. 'fail': function(response) {
  291. uni.hideNavigationBarLoading();
  292. uni.hideLoading();
  293. //如果请求失败,尝试从缓存中读取数据
  294. var md5 = require('./md5.js');
  295. var cachekey = md5(url);
  296. var cachedata = uni.getStorageSync(cachekey);
  297. if (cachedata && cachedata.data) {
  298. if (option.success && typeof option.success == 'function') {
  299. option.success(cachedata);
  300. }
  301. console.log('failreadcache:' + url);
  302. return true;
  303. } else {
  304. if (option.fail && typeof option.fail == 'function') {
  305. option.fail(response);
  306. }
  307. }
  308. },
  309. 'complete': function(response) {
  310. // uni.hideNavigationBarLoading();
  311. // uni.hideLoading();
  312. if (option.complete && typeof option.complete == 'function') {
  313. option.complete(response);
  314. }
  315. }
  316. });
  317. }
  318. util.getWe7User = function(cb, code) {
  319. var userInfo = uni.getStorageSync('userInfo') || {};
  320. util.request({
  321. url: 'auth/session/openid',
  322. data: {
  323. code: code ? code : ''
  324. },
  325. cachetime: 0,
  326. showLoading: false,
  327. success: function(session) {
  328. if (!session.data.errno) {
  329. userInfo.sessionid = session.data.data.sessionid
  330. userInfo.memberInfo = session.data.data.userinfo
  331. uni.setStorageSync('userInfo', userInfo)
  332. }
  333. typeof cb == "function" && cb(userInfo);
  334. }
  335. });
  336. }
  337. util.upadteUser = function(wxInfo, cb) {
  338. var userInfo = uni.getStorageSync('userInfo');
  339. if (!wxInfo) {
  340. return typeof cb == "function" && cb(userInfo);;
  341. }
  342. userInfo.wxInfo = wxInfo.userInfo
  343. util.request({
  344. url: 'auth/session/userinfo',
  345. data: {
  346. signature: wxInfo.signature,
  347. rawData: wxInfo.rawData,
  348. iv: wxInfo.iv,
  349. encryptedData: wxInfo.encryptedData
  350. },
  351. method: 'POST',
  352. header: {
  353. 'content-type': 'application/x-www-form-urlencoded'
  354. },
  355. cachetime: 0,
  356. success: function(res) {
  357. if (!res.data.errno) {
  358. userInfo.memberInfo = res.data.data;
  359. uni.setStorageSync('userInfo', userInfo);
  360. }
  361. typeof cb == "function" && cb(userInfo);
  362. }
  363. });
  364. }
  365. util.checkSession = function(option) {
  366. util.request({
  367. url: 'auth/session/check',
  368. method: 'POST',
  369. cachetime: 0,
  370. showLoading: false,
  371. success: function(res) {
  372. if (!res.data.errno) {
  373. typeof option.success == "function" && option.success();
  374. } else {
  375. typeof option.fail == "function" && option.fail();
  376. }
  377. },
  378. fail: function() {
  379. typeof option.fail == "function" && option.fail();
  380. }
  381. })
  382. }
  383. /*
  384. * 获取用户信息
  385. */
  386. util.getUserInfo = function(cb, wxInfo) {
  387. // #ifdef MP-WEIXIN
  388. var login = function() {
  389. var userInfo = {
  390. 'sessionid': '',
  391. 'wxInfo': '',
  392. 'memberInfo': '',
  393. };
  394. uni.login({
  395. success: function(res) {
  396. util.getWe7User(function(userInfo) {
  397. if (wxInfo) {
  398. util.upadteUser(wxInfo, function(userInfo) {
  399. typeof cb == "function" && cb(userInfo);
  400. })
  401. } else {
  402. if (uni.canIUse('getUserInfo')) {
  403. // 如果可用
  404. uni.getUserInfo({
  405. withCredentials: true,
  406. success: function(wxInfo) {
  407. //console.log(wxInfo);
  408. util.upadteUser(wxInfo, function(userInfo) {
  409. typeof cb == "function" && cb(
  410. userInfo);
  411. })
  412. },
  413. fail: function() {
  414. typeof cb == "function" && cb(userInfo);
  415. }
  416. })
  417. } else {
  418. typeof cb == "function" && cb(userInfo);
  419. }
  420. }
  421. }, res.code)
  422. },
  423. fail: function(res) {
  424. console.log(res);
  425. }
  426. });
  427. };
  428. var userInfo = uni.getStorageSync('userInfo') || {};
  429. if (userInfo.sessionid) {
  430. util.checkSession({
  431. success: function() {
  432. if (wxInfo) {
  433. util.upadteUser(wxInfo, function(userInfo) {
  434. typeof cb == "function" && cb(userInfo);
  435. })
  436. } else {
  437. typeof cb == "function" && cb(userInfo);
  438. }
  439. },
  440. fail: function() {
  441. userInfo.sessionid = '';
  442. console.log('relogin');
  443. uni.removeStorageSync('userInfo');
  444. login();
  445. }
  446. })
  447. } else {
  448. //调用登录接口
  449. login();
  450. }
  451. // #endif
  452. // #ifndef MP-WEIXIN
  453. var mplogin = function() {
  454. var userInfo = {
  455. 'sessionid': '',
  456. 'wxInfo': '',
  457. 'memberInfo': '',
  458. };
  459. util.getWe7User(function(userInfo) {
  460. if (navigator) {
  461. var ua = navigator.userAgent.toLowerCase();
  462. var isWeixin = ua.indexOf('micromessenger') != -1;
  463. }
  464. if (isWeixin) {
  465. let urlquery = getQuery(window.location.href);
  466. if (urlquery.length > 0) {
  467. var urli = '';
  468. for (let i = 0; i < urlquery.length; i++) {
  469. if (urlquery[i] && urlquery[i].name && urlquery[i].value) {
  470. if (urlquery[i].name == "i") {
  471. urli = urlquery[i].name + '=' + urlquery[i].value;
  472. }
  473. }
  474. }
  475. }
  476. window.location.href =
  477. '/public/index.php?s=/index/wechatmp/wechat&xmtoken=' +
  478. userInfo.sessionid +
  479. '&' + urli + '&backurl=' + encodeURIComponent(location.href)
  480. }
  481. typeof cb == "function" && cb(userInfo);
  482. }, '')
  483. };
  484. var userInfo = uni.getStorageSync('userInfo') || {};
  485. if (userInfo.sessionid) {
  486. util.checkSession({
  487. success: function() {
  488. typeof cb == "function" && cb(userInfo);
  489. },
  490. fail: function() {
  491. userInfo.sessionid = '';
  492. console.log('relogin');
  493. uni.removeStorageSync('userInfo');
  494. mplogin();
  495. }
  496. })
  497. } else {
  498. //调用登录接口
  499. mplogin();
  500. }
  501. // #endif
  502. }
  503. util.getmpuserinfo = function() {
  504. util.getUserInfo(function(userInfo) {
  505. var ua = navigator.userAgent.toLowerCase();
  506. var isWeixin = ua.indexOf('micromessenger') != -1;
  507. if (isWeixin) {
  508. let urlquery = getQuery(window.location.href);
  509. if (urlquery.length > 0) {
  510. var urli = '';
  511. for (let i = 0; i < urlquery.length; i++) {
  512. if (urlquery[i] && urlquery[i].name && urlquery[i].value) {
  513. if (urlquery[i].name == "i") {
  514. urli = urlquery[i].name + '=' + urlquery[i].value;
  515. }
  516. }
  517. }
  518. }
  519. window.location.href =
  520. '/public/index.php?s=/index/wechatmp/wechatuserinfo&xmtoken=' +
  521. userInfo.sessionid +
  522. '&' + urli + '&backurl=' + encodeURIComponent(location.href)
  523. }
  524. })
  525. };
  526. util.navigateBack = function(obj) {
  527. let delta = obj.delta ? obj.delta : 1;
  528. if (obj.data) {
  529. let pages = getCurrentPages()
  530. let curPage = pages[pages.length - (delta + 1)];
  531. if (curPage.pageForResult) {
  532. curPage.pageForResult(obj.data);
  533. } else {
  534. curPage.setData(obj.data);
  535. }
  536. }
  537. uni.navigateBack({
  538. delta: delta, // 回退前 delta(默认为1) 页面
  539. success: function(res) {
  540. // success
  541. typeof obj.success == "function" && obj.success(res);
  542. },
  543. fail: function(err) {
  544. // fail
  545. typeof obj.fail == "function" && obj.fail(err);
  546. },
  547. complete: function() {
  548. // complete
  549. typeof obj.complete == "function" && obj.complete();
  550. }
  551. })
  552. };
  553. util.footer = function($this) {
  554. let app = App;
  555. let that = $this;
  556. let tabBar = app.tabBar;
  557. for (let i in tabBar['list']) {
  558. tabBar['list'][i]['pageUrl'] = tabBar['list'][i]['pagePath'].replace(/(\?|#)[^"]*/g, '')
  559. }
  560. that.tabBar = tabBar;
  561. // #ifdef MP-WEIXIN
  562. that.tabBar.thisurl = that.__route__;
  563. // #endif
  564. //#ifdef H5
  565. that.tabBar.thisurl = that.$route.path;
  566. //#endif
  567. };
  568. /*
  569. * 提示信息
  570. * type 为 success, error 当为 success, 时,为toast方式,否则为模态框的方式
  571. * redirect 为提示后的跳转地址, 跳转的时候可以加上 协议名称
  572. * navigate:/we7/pages/detail/detail 以 navigateTo 的方法跳转,
  573. * redirect:/we7/pages/detail/detail 以 redirectTo 的方式跳转,默认为 redirect
  574. */
  575. util.message = function(title, redirect, type) {
  576. if (!title) {
  577. return true;
  578. }
  579. if (typeof title == 'object') {
  580. redirect = title.redirect;
  581. type = title.type;
  582. title = title.title;
  583. }
  584. if (redirect) {
  585. var redirectType = redirect.substring(0, 9),
  586. url = '',
  587. redirectFunction = '';
  588. if (redirectType == 'navigate:') {
  589. redirectFunction = 'navigateTo';
  590. url = redirect.substring(9);
  591. } else if (redirectType == 'redirect:') {
  592. redirectFunction = 'redirectTo';
  593. url = redirect.substring(9);
  594. } else {
  595. url = redirect;
  596. redirectFunction = 'redirectTo';
  597. }
  598. }
  599. //console.log(url)
  600. if (!type) {
  601. type = 'success';
  602. }
  603. if (type == 'success') {
  604. uni.showToast({
  605. title: title,
  606. icon: 'success',
  607. duration: 2000,
  608. mask: url ? true : false,
  609. complete: function() {
  610. if (url) {
  611. setTimeout(function() {
  612. wx[redirectFunction]({
  613. url: url,
  614. });
  615. }, 1800);
  616. }
  617. }
  618. });
  619. } else if (type == 'error') {
  620. uni.showModal({
  621. title: '系统信息',
  622. content: title,
  623. showCancel: false,
  624. complete: function() {
  625. if (url) {
  626. wx[redirectFunction]({
  627. url: url,
  628. });
  629. }
  630. }
  631. });
  632. }
  633. }
  634. //util.user = util.getUserInfo;
  635. //封装微信等待提示,防止ajax过多时,show多次
  636. util.showLoading = function() {
  637. var isShowLoading = uni.getStorageSync('isShowLoading');
  638. if (isShowLoading) {
  639. uni.hideLoading();
  640. uni.setStorageSync('isShowLoading', false);
  641. }
  642. uni.showLoading({
  643. title: '加载中',
  644. complete: function() {
  645. uni.setStorageSync('isShowLoading', true);
  646. },
  647. fail: function() {
  648. uni.setStorageSync('isShowLoading', false);
  649. }
  650. });
  651. }
  652. util.showImage = function(event) {
  653. var url = event ? event.currentTarget.dataset.preview : '';
  654. if (!url) {
  655. return false;
  656. }
  657. uni.previewImage({
  658. urls: [url]
  659. });
  660. }
  661. /**
  662. * 转换内容中的emoji表情为 unicode 码点,在Php中使用utf8_bytes来转换输出
  663. */
  664. util.parseContent = function(string) {
  665. if (!string) {
  666. return string;
  667. }
  668. var ranges = [
  669. '\ud83c[\udf00-\udfff]', // U+1F300 to U+1F3FF
  670. '\ud83d[\udc00-\ude4f]', // U+1F400 to U+1F64F
  671. '\ud83d[\ude80-\udeff]' // U+1F680 to U+1F6FF
  672. ];
  673. var emoji = string.match(
  674. new RegExp(ranges.join('|'), 'g'));
  675. if (emoji) {
  676. for (var i in emoji) {
  677. string = string.replace(emoji[i], '[U+' + emoji[i].codePointAt(0).toString(16).toUpperCase() + ']');
  678. }
  679. }
  680. return string;
  681. }
  682. util.date = function() {
  683. /**
  684. * 判断闰年
  685. * @param date Date日期对象
  686. * @return boolean true 或false
  687. */
  688. this.isLeapYear = function(date) {
  689. return (0 == date.getYear() % 4 && ((date.getYear() % 100 != 0) || (date.getYear() % 400 == 0)));
  690. }
  691. /**
  692. * 日期对象转换为指定格式的字符串
  693. * @param f 日期格式,格式定义如下 yyyy-MM-dd HH:mm:ss
  694. * @param date Date日期对象, 如果缺省,则为当前时间
  695. *
  696. * YYYY/yyyy/YY/yy 表示年份
  697. * MM/M 月份
  698. * W/w 星期
  699. * dd/DD/d/D 日期
  700. * hh/HH/h/H 时间
  701. * mm/m 分钟
  702. * ss/SS/s/S 秒
  703. * @return string 指定格式的时间字符串
  704. */
  705. this.dateToStr = function(formatStr, date) {
  706. formatStr = arguments[0] || "yyyy-MM-dd HH:mm:ss";
  707. date = arguments[1] || new Date();
  708. var str = formatStr;
  709. var Week = ['日', '一', '二', '三', '四', '五', '六'];
  710. str = str.replace(/yyyy|YYYY/, date.getFullYear());
  711. str = str.replace(/yy|YY/, (date.getYear() % 100) > 9 ? (date.getYear() % 100).toString() : '0' + (date
  712. .getYear() % 100));
  713. str = str.replace(/MM/, date.getMonth() > 9 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1));
  714. str = str.replace(/M/g, date.getMonth());
  715. str = str.replace(/w|W/g, Week[date.getDay()]);
  716. str = str.replace(/dd|DD/, date.getDate() > 9 ? date.getDate().toString() : '0' + date.getDate());
  717. str = str.replace(/d|D/g, date.getDate());
  718. str = str.replace(/hh|HH/, date.getHours() > 9 ? date.getHours().toString() : '0' + date.getHours());
  719. str = str.replace(/h|H/g, date.getHours());
  720. str = str.replace(/mm/, date.getMinutes() > 9 ? date.getMinutes().toString() : '0' + date.getMinutes());
  721. str = str.replace(/m/g, date.getMinutes());
  722. str = str.replace(/ss|SS/, date.getSeconds() > 9 ? date.getSeconds().toString() : '0' + date
  723. .getSeconds());
  724. str = str.replace(/s|S/g, date.getSeconds());
  725. return str;
  726. }
  727. /**
  728. * 日期计算
  729. * @param strInterval string 可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
  730. * @param num int
  731. * @param date Date 日期对象
  732. * @return Date 返回日期对象
  733. */
  734. this.dateAdd = function(strInterval, num, date) {
  735. date = arguments[2] || new Date();
  736. switch (strInterval) {
  737. case 's':
  738. return new Date(date.getTime() + (1000 * num));
  739. case 'n':
  740. return new Date(date.getTime() + (60000 * num));
  741. case 'h':
  742. return new Date(date.getTime() + (3600000 * num));
  743. case 'd':
  744. return new Date(date.getTime() + (86400000 * num));
  745. case 'w':
  746. return new Date(date.getTime() + ((86400000 * 7) * num));
  747. case 'm':
  748. return new Date(date.getFullYear(), (date.getMonth()) + num, date.getDate(), date.getHours(),
  749. date.getMinutes(), date.getSeconds());
  750. case 'y':
  751. return new Date((date.getFullYear() + num), date.getMonth(), date.getDate(), date.getHours(),
  752. date.getMinutes(), date.getSeconds());
  753. }
  754. }
  755. /**
  756. * 比较日期差 dtEnd 格式为日期型或者有效日期格式字符串
  757. * @param strInterval string 可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
  758. * @param dtStart Date 可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
  759. * @param dtEnd Date 可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
  760. */
  761. this.dateDiff = function(strInterval, dtStart, dtEnd) {
  762. switch (strInterval) {
  763. case 's':
  764. return parseInt((dtEnd - dtStart) / 1000);
  765. case 'n':
  766. return parseInt((dtEnd - dtStart) / 60000);
  767. case 'h':
  768. return parseInt((dtEnd - dtStart) / 3600000);
  769. case 'd':
  770. return parseInt((dtEnd - dtStart) / 86400000);
  771. case 'w':
  772. return parseInt((dtEnd - dtStart) / (86400000 * 7));
  773. case 'm':
  774. return (dtEnd.getMonth() + 1) + ((dtEnd.getFullYear() - dtStart.getFullYear()) * 12) - (dtStart
  775. .getMonth() + 1);
  776. case 'y':
  777. return dtEnd.getFullYear() - dtStart.getFullYear();
  778. }
  779. }
  780. /**
  781. * 字符串转换为日期对象 // eval 不可用
  782. * @param date Date 格式为yyyy-MM-dd HH:mm:ss,必须按年月日时分秒的顺序,中间分隔符不限制
  783. */
  784. this.strToDate = function(dateStr) {
  785. var data = dateStr;
  786. var reCat = /(\d{1,4})/gm;
  787. var t = data.match(reCat);
  788. t[1] = t[1] - 1;
  789. eval('var d = new Date(' + t.join(',') + ');');
  790. return d;
  791. }
  792. /**
  793. * 把指定格式的字符串转换为日期对象yyyy-MM-dd HH:mm:ss
  794. *
  795. */
  796. this.strFormatToDate = function(formatStr, dateStr) {
  797. var year = 0;
  798. var start = -1;
  799. var len = dateStr.length;
  800. if ((start = formatStr.indexOf('yyyy')) > -1 && start < len) {
  801. year = dateStr.substr(start, 4);
  802. }
  803. var month = 0;
  804. if ((start = formatStr.indexOf('MM')) > -1 && start < len) {
  805. month = parseInt(dateStr.substr(start, 2)) - 1;
  806. }
  807. var day = 0;
  808. if ((start = formatStr.indexOf('dd')) > -1 && start < len) {
  809. day = parseInt(dateStr.substr(start, 2));
  810. }
  811. var hour = 0;
  812. if (((start = formatStr.indexOf('HH')) > -1 || (start = formatStr.indexOf('hh')) > 1) && start < len) {
  813. hour = parseInt(dateStr.substr(start, 2));
  814. }
  815. var minute = 0;
  816. if ((start = formatStr.indexOf('mm')) > -1 && start < len) {
  817. minute = dateStr.substr(start, 2);
  818. }
  819. var second = 0;
  820. if ((start = formatStr.indexOf('ss')) > -1 && start < len) {
  821. second = dateStr.substr(start, 2);
  822. }
  823. return new Date(year, month, day, hour, minute, second);
  824. }
  825. /**
  826. * 日期对象转换为毫秒数
  827. */
  828. this.dateToLong = function(date) {
  829. return date.getTime();
  830. }
  831. /**
  832. * 毫秒转换为日期对象
  833. * @param dateVal number 日期的毫秒数
  834. */
  835. this.longToDate = function(dateVal) {
  836. return new Date(dateVal);
  837. }
  838. /**
  839. * 判断字符串是否为日期格式
  840. * @param str string 字符串
  841. * @param formatStr string 日期格式, 如下 yyyy-MM-dd
  842. */
  843. this.isDate = function(str, formatStr) {
  844. if (formatStr == null) {
  845. formatStr = "yyyyMMdd";
  846. }
  847. var yIndex = formatStr.indexOf("yyyy");
  848. if (yIndex == -1) {
  849. return false;
  850. }
  851. var year = str.substring(yIndex, yIndex + 4);
  852. var mIndex = formatStr.indexOf("MM");
  853. if (mIndex == -1) {
  854. return false;
  855. }
  856. var month = str.substring(mIndex, mIndex + 2);
  857. var dIndex = formatStr.indexOf("dd");
  858. if (dIndex == -1) {
  859. return false;
  860. }
  861. var day = str.substring(dIndex, dIndex + 2);
  862. if (!isNumber(year) || year > "2100" || year < "1900") {
  863. return false;
  864. }
  865. if (!isNumber(month) || month > "12" || month < "01") {
  866. return false;
  867. }
  868. if (day > getMaxDay(year, month) || day < "01") {
  869. return false;
  870. }
  871. return true;
  872. }
  873. this.getMaxDay = function(year, month) {
  874. if (month == 4 || month == 6 || month == 9 || month == 11)
  875. return "30";
  876. if (month == 2)
  877. if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
  878. return "29";
  879. else
  880. return "28";
  881. return "31";
  882. }
  883. /**
  884. * 变量是否为数字
  885. */
  886. this.isNumber = function(str) {
  887. var regExp = /^\d+$/g;
  888. return regExp.test(str);
  889. }
  890. /**
  891. * 把日期分割成数组 [年、月、日、时、分、秒]
  892. */
  893. this.toArray = function(myDate) {
  894. myDate = arguments[0] || new Date();
  895. var myArray = Array();
  896. myArray[0] = myDate.getFullYear();
  897. myArray[1] = myDate.getMonth();
  898. myArray[2] = myDate.getDate();
  899. myArray[3] = myDate.getHours();
  900. myArray[4] = myDate.getMinutes();
  901. myArray[5] = myDate.getSeconds();
  902. return myArray;
  903. }
  904. /**
  905. * 取得日期数据信息
  906. * 参数 interval 表示数据类型
  907. * y 年 M月 d日 w星期 ww周 h时 n分 s秒
  908. */
  909. this.datePart = function(interval, myDate) {
  910. myDate = arguments[1] || new Date();
  911. var partStr = '';
  912. var Week = ['日', '一', '二', '三', '四', '五', '六'];
  913. switch (interval) {
  914. case 'y':
  915. partStr = myDate.getFullYear();
  916. break;
  917. case 'M':
  918. partStr = myDate.getMonth() + 1;
  919. break;
  920. case 'd':
  921. partStr = myDate.getDate();
  922. break;
  923. case 'w':
  924. partStr = Week[myDate.getDay()];
  925. break;
  926. case 'ww':
  927. partStr = myDate.WeekNumOfYear();
  928. break;
  929. case 'h':
  930. partStr = myDate.getHours();
  931. break;
  932. case 'm':
  933. partStr = myDate.getMinutes();
  934. break;
  935. case 's':
  936. partStr = myDate.getSeconds();
  937. break;
  938. }
  939. return partStr;
  940. }
  941. /**
  942. * 取得当前日期所在月的最大天数
  943. */
  944. this.maxDayOfDate = function(date) {
  945. date = arguments[0] || new Date();
  946. date.setDate(1);
  947. date.setMonth(date.getMonth() + 1);
  948. var time = date.getTime() - 24 * 60 * 60 * 1000;
  949. var newDate = new Date(time);
  950. return newDate.getDate();
  951. }
  952. };
  953. module.exports = util;