util.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. import Config from './config.js'
  2. import store from '@/store/index.js'
  3. import JSEncrypt from 'jsencrypt'
  4. import Http from './http.js'
  5. export default {
  6. data() {
  7. return {
  8. regExp: {
  9. number: /^\d{0,10}$/,
  10. digit: /^\d{0,10}(.?\d{0,2})$/
  11. }
  12. }
  13. },
  14. /**
  15. * 页面跳转
  16. * @param {string} to 跳转链接 /pages/index/index
  17. * @param {Object} param 参数 {key : value, ...}
  18. * @param {string} mode 模式
  19. */
  20. redirectTo(to, param, mode) {
  21. let url = to;
  22. let tabbarList = ['/pages/index/index', '/pages/goods/list', '/pages/order/list', '/pages/my/index',
  23. '/pages/member/list'
  24. ]
  25. for (let i = 0; i < tabbarList.length; i++) {
  26. if (to.indexOf(tabbarList[i]) != -1) {
  27. uni.switchTab({
  28. url: url
  29. })
  30. return;
  31. }
  32. }
  33. if (param != undefined) {
  34. Object.keys(param).forEach(function(key) {
  35. if (url.indexOf('?') != -1) {
  36. url += "&" + key + "=" + param[key];
  37. } else {
  38. url += "?" + key + "=" + param[key];
  39. }
  40. });
  41. }
  42. switch (mode) {
  43. case 'tabbar':
  44. // 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
  45. uni.switchTab({
  46. url: url
  47. })
  48. break;
  49. case 'redirectTo':
  50. // 关闭当前页面,跳转到应用内的某个页面。
  51. uni.redirectTo({
  52. url: url
  53. });
  54. break;
  55. case 'reLaunch':
  56. // 关闭所有页面,打开到应用内的某个页面。
  57. uni.reLaunch({
  58. url: url
  59. });
  60. break;
  61. default:
  62. // 保留当前页面,跳转到应用内的某个页面
  63. uni.navigateTo({
  64. url: url
  65. });
  66. }
  67. },
  68. /**
  69. * 图片路径转换
  70. * @param {String} img_path 图片地址
  71. * @param {Object} params 参数,针对商品、相册里面的图片区分大中小,size: big、mid、small
  72. */
  73. img(img_path, params) {
  74. var path = "";
  75. if (img_path && img_path != undefined && img_path != "") {
  76. if (params && img_path != this.getDefaultImage().default_goods_img) {
  77. // 过滤默认图
  78. let arr = img_path.split(".");
  79. let suffix = arr[arr.length - 1];
  80. arr.pop();
  81. arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase();
  82. arr.push(suffix);
  83. img_path = arr.join(".");
  84. }
  85. if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) {
  86. path = Config.imgDomain + "/" + img_path;
  87. } else {
  88. path = img_path;
  89. }
  90. }
  91. return path;
  92. },
  93. /**
  94. * 时间戳转日期格式
  95. * @param {Object} timeStamp
  96. */
  97. timeStampTurnTime(timeStamp, type = "") {
  98. if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) {
  99. var date = new Date();
  100. date.setTime(timeStamp * 1000);
  101. var y = date.getFullYear();
  102. var m = date.getMonth() + 1;
  103. m = m < 10 ? ('0' + m) : m;
  104. var d = date.getDate();
  105. d = d < 10 ? ('0' + d) : d;
  106. var h = date.getHours();
  107. h = h < 10 ? ('0' + h) : h;
  108. var minute = date.getMinutes();
  109. var second = date.getSeconds();
  110. minute = minute < 10 ? ('0' + minute) : minute;
  111. second = second < 10 ? ('0' + second) : second;
  112. if (type) {
  113. return y + '-' + m + '-' + d;
  114. } else {
  115. return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
  116. }
  117. } else {
  118. return "";
  119. }
  120. },
  121. /**
  122. * 日期格式转时间戳
  123. * @param {Object} timeStamp
  124. */
  125. timeTurnTimeStamp(string) {
  126. var f = string.split(' ', 2);
  127. var d = (f[0] ? f[0] : '').split('-', 3);
  128. var t = (f[1] ? f[1] : '').split(':', 3);
  129. return (new Date(
  130. parseInt(d[0], 10) || null,
  131. (parseInt(d[1], 10) || 1) - 1,
  132. parseInt(d[2], 10) || null,
  133. parseInt(t[0], 10) || null,
  134. parseInt(t[1], 10) || null,
  135. parseInt(t[2], 10) || null
  136. )).getTime() / 1000;
  137. },
  138. /**
  139. * 倒计时
  140. * @param {Object} seconds 秒
  141. */
  142. countDown(seconds) {
  143. let [day, hour, minute, second] = [0, 0, 0, 0]
  144. if (seconds > 0) {
  145. day = Math.floor(seconds / (60 * 60 * 24))
  146. hour = Math.floor(seconds / (60 * 60)) - (day * 24)
  147. minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
  148. second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
  149. }
  150. if (day < 10) {
  151. day = '0' + day
  152. }
  153. if (hour < 10) {
  154. hour = '0' + hour
  155. }
  156. if (minute < 10) {
  157. minute = '0' + minute
  158. }
  159. if (second < 10) {
  160. second = '0' + second
  161. }
  162. return {
  163. d: day,
  164. h: hour,
  165. i: minute,
  166. s: second
  167. };
  168. },
  169. /**
  170. * 数值去重
  171. * @param {Array} arr 数组
  172. * @param {string} field 字段
  173. */
  174. unique(arr, field) {
  175. const res = new Map();
  176. return arr.filter((a) => !res.has(a[field]) && res.set(a[field], 1));
  177. },
  178. /**
  179. * 判断值是否在数组中
  180. * @param {Object} elem
  181. * @param {Object} arr
  182. * @param {Object} i
  183. */
  184. inArray: function(elem, arr) {
  185. return arr == null ? -1 : arr.indexOf(elem);
  186. },
  187. /**
  188. * 获取某天日期
  189. * @param {Object} day
  190. */
  191. getDay: function(day) {
  192. var today = new Date();
  193. var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day;
  194. today.setTime(targetday_milliseconds);
  195. const doHandleMonth = function(month) {
  196. var m = month;
  197. if (month.toString().length == 1) {
  198. m = "0" + month;
  199. }
  200. return m
  201. }
  202. var tYear = today.getFullYear();
  203. var tMonth = today.getMonth();
  204. var tDate = today.getDate();
  205. var tWeek = today.getDay();
  206. var time = parseInt(today.getTime() / 1000);
  207. tMonth = doHandleMonth(tMonth + 1);
  208. tDate = doHandleMonth(tDate);
  209. const week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  210. return {
  211. 't': time,
  212. 'y': tYear,
  213. 'm': tMonth,
  214. 'd': tDate,
  215. 'w': week[tWeek]
  216. };
  217. },
  218. /**
  219. * 图片选择加上传
  220. * @param {Object} params {"number":1,"sourceType":["album","camera"],"path":"image","url":""}
  221. * @param {Object} callback
  222. * @param string url
  223. * return array
  224. */
  225. upload: function(params, callback) {
  226. // #ifdef H5
  227. var app_type = this.isWeiXin() ? 'wechat' : 'h5';
  228. var app_type_name = this.isWeiXin() ? '微信公众号' : 'H5';
  229. // #endif
  230. // #ifdef MP-WEIXIN
  231. var app_type = 'weapp';
  232. var app_type_name = '微信小程序';
  233. // #endif
  234. // #ifdef MP-ALIPAY
  235. var app_type = 'aliapp';
  236. var app_type_name = '支付宝小程序';
  237. // #endif
  238. // #ifdef MP-BAIDU
  239. var app_type = 'baiduapp';
  240. var app_type_name = '百度小程序';
  241. // #endif
  242. // #ifdef MP-TOUTIAO
  243. var app_type = 'MP-TOUTIAO';
  244. var app_type_name = '头条小程序';
  245. // #endif
  246. // #ifdef MP-QQ
  247. var app_type = 'MP-QQ';
  248. var app_type_name = 'QQ小程序';
  249. // #endif
  250. var data = {
  251. token: uni.getStorageSync('token'),
  252. app_type: app_type,
  253. app_type_name: app_type_name
  254. }
  255. data = Object.assign(data, params);
  256. var _self = this;
  257. params.sourceType = params.sourceType || ['album', 'camera'];
  258. uni.chooseImage({
  259. count: params.number,
  260. sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
  261. sourceType: params.sourceType, //从相册或者拍照
  262. success: async function(res) {
  263. const tempFilePaths = res.tempFilePaths;
  264. var _data = data;
  265. var imgs = [];
  266. for (var i = 0; i < tempFilePaths.length; i++) {
  267. var path = await _self.upload_file_server(tempFilePaths[i], _data, params.path, params.url);
  268. imgs.push(path);
  269. }
  270. typeof callback == 'function' && callback(imgs);
  271. }
  272. });
  273. },
  274. //上传
  275. upload_file_server(tempFilePath, data, path, url = "") {
  276. if (url) {
  277. var uploadUrl = Config.baseUrl + url
  278. } else {
  279. var uploadUrl = Config.baseUrl + '/shopapi/upload/' + path
  280. }
  281. uni.showLoading({
  282. title: '上传中...',
  283. mask: true
  284. });
  285. return new Promise((resolve, reject) => {
  286. uni.uploadFile({
  287. url: uploadUrl,
  288. filePath: tempFilePath,
  289. name: 'file',
  290. formData: data,
  291. success: function(res) {
  292. var path_str = JSON.parse(res.data);
  293. if (path_str.code >= 0) {
  294. resolve(path_str.data.pic_path);
  295. } else {
  296. reject("error");
  297. }
  298. uni.hideLoading();
  299. }
  300. });
  301. });
  302. },
  303. /**
  304. * 复制
  305. * @param {Object} message
  306. * @param {Object} callback
  307. */
  308. copy(value, callback) {
  309. // #ifdef H5
  310. var oInput = document.createElement('input'); //创建一个隐藏input(重要!)
  311. oInput.value = value; //赋值
  312. document.body.appendChild(oInput);
  313. oInput.select(); // 选择对象
  314. document.execCommand("Copy"); // 执行浏览器复制命令
  315. oInput.className = 'oInput';
  316. oInput.style.display = 'none';
  317. uni.hideKeyboard();
  318. this.showToast({
  319. title: '复制成功'
  320. });
  321. typeof callback == 'function' && callback();
  322. // #endif
  323. // #ifdef MP || APP-PLUS
  324. uni.setClipboardData({
  325. data: value,
  326. success: () => {
  327. typeof callback == 'function' && callback();
  328. }
  329. });
  330. // #endif
  331. },
  332. /**
  333. * 是否是微信浏览器
  334. */
  335. isWeiXin() {
  336. // #ifndef H5
  337. return false;
  338. // #endif
  339. var ua = navigator.userAgent.toLowerCase();
  340. if (ua.match(/MicroMessenger/i) == "micromessenger") {
  341. return true;
  342. } else {
  343. return false;
  344. }
  345. },
  346. /**
  347. * 显示消息提示框
  348. * @param {Object} params 参数
  349. */
  350. showToast(params = {}) {
  351. params.title = params.title || "";
  352. params.icon = params.icon || "none";
  353. params.position = params.position || 'bottom';
  354. params.duration = 1500;
  355. uni.showToast(params);
  356. },
  357. /**
  358. * 检测苹果X以上的手机
  359. */
  360. isIPhoneX() {
  361. let res = uni.getSystemInfoSync();
  362. if (res.model.search('iPhone X') != -1) {
  363. return true;
  364. }
  365. return false;
  366. },
  367. //判断安卓还是iOS
  368. isAndroid() {
  369. let platform = uni.getSystemInfoSync().platform
  370. if (platform == 'ios') {
  371. return false;
  372. } else if (platform == 'android') {
  373. return true;
  374. }
  375. },
  376. /**
  377. * 深度拷贝对象
  378. * @param {Object} obj
  379. */
  380. deepClone(obj) {
  381. const isObject = function(obj) {
  382. return typeof obj == 'object';
  383. }
  384. if (!isObject(obj)) {
  385. throw new Error('obj 不是一个对象!')
  386. }
  387. //判断传进来的是对象还是数组
  388. let isArray = Array.isArray(obj)
  389. let cloneObj = isArray ? [] : {}
  390. //通过for...in来拷贝
  391. for (let key in obj) {
  392. cloneObj[key] = isObject(obj[key]) ? this.deepClone(obj[key]) : obj[key]
  393. }
  394. return cloneObj
  395. },
  396. /**
  397. * 获取默认图
  398. * @param {Object} link
  399. */
  400. getDefaultImage() {
  401. let defaultImg = uni.getStorageSync('default_img');
  402. if (defaultImg) {
  403. defaultImg = JSON.parse(defaultImg);
  404. defaultImg.default_goods_img = this.img(defaultImg.default_goods_img);
  405. defaultImg.default_headimg = this.img(defaultImg.default_headimg);
  406. defaultImg.default_shop_img = this.img(defaultImg.default_shop_img);
  407. defaultImg.default_category_img = this.img(defaultImg.default_category_img);
  408. defaultImg.default_city_img = this.img(defaultImg.default_city_img);
  409. defaultImg.default_supply_img = this.img(defaultImg.default_supply_img);
  410. defaultImg.default_store_img = this.img(defaultImg.default_store_img);
  411. defaultImg.default_brand_img = this.img(defaultImg.default_brand_img);
  412. return defaultImg;
  413. } else {
  414. return {
  415. default_goods_img: '',
  416. default_headimg: '',
  417. default_shop_img: '',
  418. default_category_img: '',
  419. default_city_img: '',
  420. default_supply_img: '',
  421. default_store_img: '',
  422. default_brand_img: ''
  423. };
  424. }
  425. },
  426. /**
  427. * 判断手机是否为iphoneX系列
  428. */
  429. uniappIsIPhoneX() {
  430. let isIphoneX = false;
  431. let systemInfo = uni.getSystemInfoSync();
  432. // #ifdef MP
  433. if (systemInfo.model.search('iPhone X') != -1 || systemInfo.model.search('iPhone 11') != -1 || systemInfo.model.search(
  434. 'iPhone12') != -1) {
  435. isIphoneX = true;
  436. }
  437. // #endif
  438. // #ifdef H5
  439. var u = navigator.userAgent;
  440. var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  441. if (isIOS) {
  442. if (systemInfo.screenWidth == 375 && systemInfo.screenHeight == 812 && systemInfo.pixelRatio == 3) {
  443. isIphoneX = true;
  444. } else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 3) {
  445. isIphoneX = true;
  446. } else if (systemInfo.screenWidth == 414 && systemInfo.screenHeight == 896 && systemInfo.pixelRatio == 2) {
  447. isIphoneX = true;
  448. }
  449. }
  450. // #endif
  451. return isIphoneX;
  452. },
  453. /**
  454. * 判断手机是否为iphone11系列
  455. */
  456. uniappIsIPhone11() {
  457. let isIphone11 = false;
  458. let systemInfo = uni.getSystemInfoSync();
  459. // #ifdef MP
  460. if (systemInfo.model.search('iPhone 11') != -1) {
  461. isIphone11 = true;
  462. }
  463. // #endif
  464. return isIphone11;
  465. },
  466. /**
  467. * 判断当前页面栈是否存在,如果存在,则返回该页面栈,否则跳转到该页面
  468. * @param {Object} url
  469. */
  470. jumpPage(url) {
  471. let jump = true;
  472. let arr = getCurrentPages().reverse();
  473. for (let i = 0; i < arr.length; i++) {
  474. if (url.indexOf(arr[i].route) != -1) {
  475. jump = false;
  476. uni.navigateBack({
  477. delta: i
  478. });
  479. break;
  480. }
  481. }
  482. if (jump) {
  483. this.$util.diyRedirectTo(url);
  484. }
  485. },
  486. /**
  487. * 计算两个经纬度之间的距离
  488. * @param {Object} lat1
  489. * @param {Object} lng1
  490. * @param {Object} lat2
  491. * @param {Object} lng2
  492. */
  493. getDistance(lat1, lng1, lat2, lng2) {
  494. var radLat1 = lat1 * Math.PI / 180.0;
  495. var radLat2 = lat2 * Math.PI / 180.0;
  496. var a = radLat1 - radLat2;
  497. var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
  498. var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
  499. Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
  500. s = s * 6378.137; // EARTH_RADIUS;
  501. s = Math.round(s * 10000) / 10000;
  502. return s;
  503. },
  504. // #ifdef H5
  505. /**
  506. * 判断该浏览器是否为safaria浏览器
  507. */
  508. isSafari() {
  509. let res = uni.getSystemInfoSync();
  510. var ua = navigator.userAgent.toLowerCase();
  511. if (ua.indexOf('applewebkit') > -1 && ua.indexOf('mobile') > -1 && ua.indexOf('safari') > -1 &&
  512. ua.indexOf('linux') === -1 && ua.indexOf('android') === -1 && ua.indexOf('chrome') === -1 &&
  513. ua.indexOf('ios') === -1 && ua.indexOf('browser') === -1) {
  514. return true;
  515. } else {
  516. return false;
  517. }
  518. },
  519. // #endif
  520. goBack(backUrl = '/pages/index/index') {
  521. if (getCurrentPages().length == 1) {
  522. this.redirectTo(backUrl);
  523. } else {
  524. uni.navigateBack();
  525. }
  526. },
  527. /**
  528. * 转换数字,保留f位
  529. * @param {Object} e
  530. * @param {Object} f
  531. */
  532. numberFixed(e, f) {
  533. if (!f) {
  534. f = 0;
  535. }
  536. return Number(e).toFixed(f);
  537. },
  538. /**
  539. * 获取url参数
  540. * @param {Object} callback
  541. */
  542. getUrlCode(callback) {
  543. var url = location.search;
  544. var theRequest = new Object();
  545. if (url.indexOf('?') != -1) {
  546. var str = url.substr(1);
  547. var strs = str.split('&');
  548. for (var i = 0; i < strs.length; i++) {
  549. theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1];
  550. }
  551. }
  552. typeof callback == 'function' && callback(theRequest);
  553. },
  554. /**
  555. * 检测是否登录
  556. * @param {Object} back 返回的页面
  557. */
  558. checkToken(back) {
  559. if (!uni.getStorageSync('token')) {
  560. this.redirectTo('/pages/login/login', {
  561. back
  562. }, 'redirectTo');
  563. return false;
  564. }
  565. if (!uni.getStorageSync('site_id')) {
  566. this.redirectTo('/pages/login/login', {}, 'redirectTo');
  567. return false;
  568. }
  569. return true;
  570. }
  571. }