/** * sunui-extends.js for sunui * * author:1940694428@qq.com * * 2020.05.12 * * **/ // const regeneratorRuntime = require("regenerator-runtime"); module.exports = { version: "last update:2020.05.12 , veriosn:1.0.0", /** * 计算两个日期时间相差的年数、月数、天数、小时数、分钟数、秒数 * DIFFTIME(开始时间,结束时间,[单位]),单位可以是 "y" 、"M"、"d"、"h"、"m"、"s"' * console.log(DIFFTIME('2019-6-30 13:20:00', '2020-10-01 11:20:32', 's')) */ getDay(day) { var today = new Date(); var targetday_milliseconds = today.getTime() + 1000 * 60 * 60 * 24 * day; today.setTime(targetday_milliseconds); //注意,这行是关键代码 var tYear = today.getFullYear(); var tMonth = today.getMonth(); var tDate = today.getDate(); tMonth = this.doHandleMonth(tMonth + 1); tDate = this.doHandleMonth(tDate); return tYear + "-" + tMonth + "-" + tDate; }, doHandleMonth(month) { var m = month; if (month.toString().length == 1) { m = "0" + month; } return m; }, tab(time,date1) { var sDate = new Date(time); var oDate1 = new Date(date1); // var oDate2 = new Date(date2); console.log('1111111', time,date1); if (sDate.getTime() < oDate1.getTime()) { console.log('第一个大', sDate.getTime(), oDate1.getTime()); return true; } else { console.log('第二个大', sDate.getTime(), oDate1.getTime()); return false; } }, DIFFTIME(startTime, endTime, unit) { if (!startTime || !endTime) { return ''; } // 判断当前月天数 function getDays(mouth, year) { let days = 30; if (mouth === 2) { days = year % 4 === 0 ? 29 : 28; } else if ( mouth === 1 || mouth === 3 || mouth === 5 || mouth === 7 || mouth === 8 || mouth === 10 || mouth === 12 ) { // 月份为:1,3,5,7,8,10,12 时,为大月.则天数为31; days = 31; } return days; } const start = new Date(startTime); const end = new Date(endTime); // 计算时间戳的差 const diffValue = end - start; // 获取年 const startYear = start.getFullYear(); const endYear = end.getFullYear(); // 获取月 const startMouth = start.getMonth() + 1; const endMouth = end.getMonth() + 1; // 获取日 const startDay = start.getDate(); const endDay = end.getDate(); // 获取小时 const startHours = start.getHours(); const endHours = end.getHours(); // 获取分 const startMinutes = start.getMinutes(); const endMinutes = end.getMinutes(); // 获取秒 const startSeconds = start.getSeconds(); const endSeconds = end.getSeconds(); // 下方注释两行为调试用 // console.log('start:', startYear, startMouth, startDay, startHours, startMinutes, startSeconds) // console.log('end:', endYear, endMouth, endDay, endHours, endMinutes, endSeconds) if (unit === 'y' || unit === 'M') { // 相差年份月份 const diffYear = endYear - startYear; // 获取当前月天数 const startDays = getDays(startMouth, startYear); const endDays = getDays(endMouth, endYear); const diffStartMouth = (startDays - (startDay + (startHours * 60 + startMinutes + startSeconds / 60) / 60 / 24 - 1)) / startDays; const diffEndMouth = (endDay + (endHours * 60 + endMinutes + endSeconds / 60) / 60 / 24 - 1) / endDays; const diffMouth = diffStartMouth + diffEndMouth + (12 - startMouth - 1) + endMouth + (diffYear - 1) * 12; if (unit === 'y') { return Math.floor((diffMouth / 12) * 100) / 100; } else { return diffMouth; } } else if (unit === 'd') { const d = parseInt(diffValue / 1000 / 60 / 60 / 24); return d; } else if (unit === 'h') { const h = parseInt(diffValue / 1000 / 60 / 60); return h; } else if (unit === 'm') { const m = parseInt(diffValue / 1000 / 60); return m; } else if (unit === 's') { const s = parseInt(diffValue / 1000); return s; } else { console.log('请输入正确的单位'); } }, // 传入2021-09-14 13:20:40 返回['2021-09-14','13:20:40'] yearAndDate(date) { return date.trim().split(' '); }, /*判断一个元素是否在数组中*/ contains(arr, val) { return arr.indexOf(val) != -1 ? true : false; }, // 查找数组最小值 arrayMin(arr) { return Math.min(...arr); }, // 从数组中移除 falsey 值 arrayCompact(arr) { return arr.filter(Boolean); }, // 数组中重复的值计数 arrCount(arr, value) { return arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); }, // 返回两个数组差异 arrayDiff(a, b) { const s = new Set(b); return a.filter(x => !s.has(x)); }, // 判断数组元素是否重复 isArrRepeat(arr) { let _arr = arr.sort(); console.log(_arr); for (let i = 0; i < _arr.length; i++) { if (_arr[i] === _arr[i + 1]) { return true; } } return false; }, /** * @param {arr} 数组 * @param {fn} 回调函数 * @return {undefined} */ each(arr, fn) { fn = fn || Function; let a = []; let args = Array.prototype.slice.call(arguments, 1); for (let i = 0; i < arr.length; i++) { let res = fn.apply(arr, [arr[i], i].concat(args)); if (res != null) a.push(res); } }, /** * @param {arr} 数组 * @param {fn} 回调函数 * @param {thisObj} this指向 * @return {Array} */ map(arr, fn, thisObj) { let scope = thisObj || window; let a = []; for (let i = 0, j = arr.length; i < j; ++i) { let res = fn.call(scope, arr[i], i, this); if (res != null) a.push(res); } return a; }, /** * @param {arr} 数组 * @param {type} 1:从小到大 2:从大到小 3:随机 * @return {Array} */ sort(arr, type = 1) { return arr.sort((a, b) => { switch (type) { case 1: return a - b; case 2: return b - a; case 3: return Math.random() - 0.5; default: return arr; } }) }, /*去重*/ arrayUnique(arr) { if (Array.hasOwnProperty('from')) { return Array.from(new Set(arr)); } else { let n = {}, r = []; for (let i = 0; i < arr.length; i++) { if (!n[arr[i]]) { n[arr[i]] = true; r.push(arr[i]); } } return r; } // 注:上面 else 里面的排重并不能区分 2 和 '2',但能减少用indexOf带来的性能 /* 正确排重 if ( Array.hasOwnProperty('from') ) { return Array.from(new Set(arr)) }else{ let r = [], NaNBol = true for(let i=0; i < arr.length; i++) { if (arr[i] !== arr[i]) { if (NaNBol && r.indexOf(arr[i]) === -1) { r.push(arr[i]) NaNBol = false } }else{ if(r.indexOf(arr[i]) === -1) r.push(arr[i]) } } return r } */ }, /*求两个集合的并集*/ union(a, b) { let newArr = a.concat(b); return this.arrayUnique(newArr); }, /*求两个集合的交集*/ intersect(a, b) { let _this = this; a = this.arrayUnique(a); return this.map(a, function(o) { return _this.contains(b, o) ? o : null; }); }, /*删除其中一个元素*/ arrayRemove(arr, ele) { let index = arr.indexOf(ele); if (index > -1) { arr.splice(index, 1); } return arr; }, /*删除某一项数组*/ arraySplice(arr, index) { arr.splice(Number(index), 1); return arr; }, /*将类数组转换为数组的方法*/ formArray(ary) { let arr = []; if (Array.isArray(ary)) { arr = ary; } else { arr = Array.prototype.slice.call(ary); }; return arr; }, /*最大值*/ max(arr) { return Math.max.apply(null, arr); }, /*最小值*/ min(arr) { return Math.min.apply(null, arr); }, /*求和*/ sum(arr) { return arr.reduce((pre, cur) => { return pre + cur }); }, /*平均值*/ average(arr) { return this.sum(arr) / arr.length; }, /** * 设置和获取同步缓存 * @param {String} key 设置key * @param {Any} value 缓存任意值 * @return {Any} 返回版本信息 */ setCache(key, value) { wx.setStorageSync(key, JSON.stringify(value)); }, getCache(key) { try { return JSON.parse(wx.getStorageSync(key)); } catch (e) { //TODO handle the exception return wx.getStorageSync(key); } }, removeCache(key) { wx.removeStorageSync(key); }, clearCache() { wx.clearStorageSync(); }, // 获取是否闰年 dateLeapYear() { let year = new Date().getFullYear(); return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) }, // 获取当前时间戳 - 13位转为10位,然后*1000再parseInt dateStamp(digits = 10) { digits = Number(digits); switch (digits) { case 10: return Math.round(new Date().getTime() / 1000).toString(); case 13: return new Date().getTime().toString(); } }, /** * 类型判断 * @param {String,Number} number 传入的数值 * @return {String} 返回字符串 */ toDigit(any) { return any.toString().replace(/^(\d)$/, `0$1`); }, /** *秒转成分钟: 如 100 => 01:40 * * @param {*} sec * @returns */ dateStoM(sec) { const MINUTE = 60; const minute = Math.floor(sec / MINUTE); const surplusSec = sec % MINUTE; return `${this.toDigit(minute)}:${this.toDigit(surplusSec)}`; }, /** * 传入13位时间戳获取距离当前时间 * @param {*} sec * @return {String} 3天前 返回距离时间具体描述 */ dateDistance(timestamp) { let publishTime = Number(timestamp) / 1000, date = new Date(publishTime * 1000), Y = this.toDigit(date.getFullYear()), M = this.toDigit(date.getMonth() + 1), D = this.toDigit(date.getDate()), H = this.toDigit(date.getHours()), m = this.toDigit(date.getMinutes()), s = this.toDigit(date.getSeconds()); let nowTime = new Date().getTime() / 1000, diffValue = nowTime - publishTime, diff_days = parseInt(diffValue / 86400), diff_hours = parseInt(diffValue / 3600), diff_minutes = parseInt(diffValue / 60), diff_secodes = parseInt(diffValue); if (diff_days > 0 && diff_days < 3) { return diff_days + "天前"; } else if (diff_days <= 0 && diff_hours > 0) { return diff_hours + "小时前"; } else if (diff_hours <= 0 && diff_minutes > 0) { return diff_minutes + "分钟前"; } else if (diff_secodes < 60) { if (diff_secodes <= 0) { return "刚刚"; } else { return diff_secodes + "秒前"; } } else if (diff_days >= 3 && diff_days < 30) { return M + '-' + D + ' ' + H + ':' + m; } else if (diff_days >= 30) { return Y + '-' + M + '-' + D + ' ' + H + ':' + m; } }, /** * 获取当天周几 * @param {} * @return {String} "星期x" 返回周几 */ dateWeek() { let day = new Date().getDay(); let week = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五"); return week[day]; }, /** * 获取当天是否周六周日 * @param {} * @return {Boolean} true/false 返回是否周六周日 */ dateWeekend() { let _date = new Date(); let _nowTime = _date.getTime(); let _week = _date.getDay(); let _yearMonthDay = `${_date.getFullYear()}-${_date.getMonth()+1>=10?_date.getMonth()+1:'0'+_date.getMonth()+1}-${_date.getDate()>=10?_date.getDate():'0'+_date.getDate()}`; let _dayLongTime = 24 * 60 * 60 * 1000; let _furtureSundayTimes = _nowTime + (7 - _week) * _dayLongTime; let _furtureSaturdayTimes = _nowTime + (6 - _week) * _dayLongTime; let _mealSunDay; let _mealSaturDay; _furtureSundayTimes = new Date(_furtureSundayTimes); _furtureSaturdayTimes = new Date(_furtureSaturdayTimes); let _satYear = _furtureSaturdayTimes.getFullYear(); let _satMonth = _furtureSaturdayTimes.getMonth() + 1; let _satDay = _furtureSaturdayTimes.getDate(); let _sunYear = _furtureSundayTimes.getFullYear(); let _sunMonth = _furtureSundayTimes.getMonth() + 1; let _sunDay = _furtureSundayTimes.getDate(); _satMonth = _satMonth >= 10 ? _satMonth : '0' + _satMonth; _satDay = _satDay >= 10 ? _satDay : '0' + _satDay; _sunMonth = _sunMonth >= 10 ? _sunMonth : '0' + _sunMonth; _sunDay = _sunDay >= 10 ? _sunDay : '0' + _sunDay; _mealSunDay = _satYear + '-' + _satMonth + '-' + _satDay; _mealSaturDay = _sunYear + '-' + _sunMonth + '-' + _sunDay; let _weekendDay = [_mealSunDay, _mealSaturDay]; let _isWeekend = _weekendDay.indexOf(_yearMonthDay) != -1; // 最近的周六/周日 _weekendDay. _isWeekend:true | false return _isWeekend; }, /** * 传入13位时间戳 * @param {String,Number} timestamp "1589257080657" * @param {String} format "Y-M-D Y-M-D-h-m-s" * @return {String} "2020*01*05 10:00" */ dateFormat(timestamp, format) { format = format || `Y-M-D`; const cur = Number(timestamp) ? new Date(Number(timestamp)) : new Date(); const year = cur.getFullYear(); const month = this.toDigit(cur.getMonth() + 1); const day = this.toDigit(cur.getDate()); const hour = this.toDigit(cur.getHours()); const minute = this.toDigit(cur.getMinutes()); const second = this.toDigit(cur.getSeconds()); return format.replace(/Y|M|D|h|m|s/g, function(matches) { return ({ Y: year, M: month, D: day, h: hour, m: minute, s: second })[matches]; }); }, /** * 格式化时间 * * @param {time} 时间 * @param {cFormat} 格式 * @return {String} 字符串 * * @example formatTime('2018-1-29', '{y}/{m}/{d} {h}:{i}:{s}') // -> 2018/01/29 00:00:00 */ formatTime(time, cFormat) { if (arguments.length === 0) return null if ((time + '').length === 10) { time = +time * 1000 } let format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}', date if (typeof time === 'object') { date = time } else { date = new Date(time) } let formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() } let time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key] if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1] if (result.length > 0 && value < 10) { value = '0' + value } return value || 0 }) return time_str }, /** * 返回指定长度的月份集合 * * @param {time} 时间 * @param {len} 长度 * @param {direction} 方向: 1: 前几个月; 2: 后几个月; 3:前后几个月 默认 3 * @return {Array} 数组 * * @example dateMonths('2018-1-29', 6, 1) // -> ["2018-1", "2017-12", "2017-11", "2017-10", "2017-9", "2017-8", "2017-7"] */ dateMonths(time, len, direction) { direction = isNaN(direction) ? 3 : direction; let mm = new Date(time).getMonth() + 1, yy = new Date(time).getFullYear(), index = mm; let cutMonth = function(index) { let arr if (direction === 1) { arr = formatPre(index).reverse() } else if (direction === 2) { arr = formatNext(index) } else { arr = formatPre(index).reverse().slice(len / 2).concat(formatNext(index).slice(1, len / 2 + 1)) } return arr.sort(function(t1, t2) { return new Date(t1).getTime() - new Date(t2).getTime() }) } let formatPre = function(index) { let currNum = index, preNum = 0, currArr = [], preArr = [] if (index - len < 0) { preNum = len - currNum } for (let i = 0; i < currNum; i++) { currArr.push([yy + '-' + (currNum - i)]) } for (let i = 1; i <= preNum; i++) { preArr.push([(yy - Math.ceil(i / 12)) + '-' + (12 - (i - 1) % 12)]) } return currArr.concat(preArr) } let formatNext = function(index) { let currNum = 12 - index, nextNum = 0, currArr = [], nextArr = [] if (len - currNum > 0) { nextNum = len - currNum } for (let i = 0; i <= currNum; i++) { currArr.push([yy + '-' + (index + i)]) } for (let i = 1; i < nextNum; i++) { nextArr.push([(yy + Math.ceil(i / 12)) + '-' + (i % 13 === 0 ? 1 : i % 13)]) } return currArr.concat(nextArr) } return cutMonth(index) }, /** * 返回指定长度的天数集合 * * @param {time} 时间 * @param {len} 长度 * @param {direction} 方向: 1: 前几天; 2: 后几天; 3:前后几天 默认 3 * @return {Array} 数组 * * @example dateDays('2018-1-29', 6) // -> ["2018-1-26", "2018-1-27", "2018-1-28", "2018-1-29", "2018-1-30", "2018-1-31", "2018-2-1"] */ dateDays(time, len, diretion) { let tt = new Date(time) let getDay = function(day) { let t = new Date(time) t.setDate(t.getDate() + day) let m = t.getMonth() + 1 return t.getFullYear() + '-' + m + '-' + t.getDate() } let arr = [] if (diretion === 1) { for (let i = 1; i <= len; i++) { arr.unshift(getDay(-i)) } } else if (diretion === 2) { for (let i = 1; i <= len; i++) { arr.push(getDay(i)) } } else { for (let i = 1; i <= len; i++) { arr.unshift(getDay(-i)) } arr.push(tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()) for (let i = 1; i <= len; i++) { arr.push(getDay(i)) } } return diretion === 1 ? arr.concat([tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt .getDate()]) : diretion === 2 ? [tt.getFullYear() + '-' + (tt.getMonth() + 1) + '-' + tt.getDate()].concat(arr) : arr }, /** * @param {s} 秒数 * @return {String} 字符串 * * @example formatHMS(3610) // -> 1h0m10s */ dateStoH(s) { let str = '' if (s > 3600) { str = Math.floor(s / 3600) + 'h' + Math.floor(s % 3600 / 60) + 'm' + s % 60 + 's' } else if (s > 60) { str = Math.floor(s / 60) + 'm' + s % 60 + 's' } else { str = s % 60 + 's' } return str }, /*获取某月有多少天*/ dateMonthOfDay(timestamp) { let date = new Date(Number(timestamp)) let year = date.getFullYear() let mouth = date.getMonth() + 1 let days //当月份为二月时,根据闰年还是非闰年判断天数 if (mouth == 2) { days = (year % 4 == 0 && year % 100 == 0 && year % 400 == 0) || (year % 4 == 0 && year % 100 != 0) ? 28 : 29 } else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12) { //月份为:1,3,5,7,8,10,12 时,为大月.则天数为31; days = 31 } else { //其他月份,天数为:30. days = 30 } return days }, /*获取某年有多少天*/ dateYearOfDay(time) { let firstDayYear = this.dateFirstDayOfYear(time); let lastDayYear = this.dateLastDayOfYear(time); let numSecond = (new Date(lastDayYear).getTime() - new Date(firstDayYear).getTime()) / 1000; return Math.ceil(numSecond / (24 * 3600)); }, /*获取某年的第一天*/ dateFirstDayOfYear(time) { let year = new Date(time).getFullYear(); return year + "-01-01 00:00:00"; }, /*获取某年最后一天*/ dateLastDayOfYear(time) { let year = new Date(time).getFullYear(); let dateString = year + "-12-01 00:00:00"; let endDay = this.getMonthOfDay(dateString); return year + "-12-" + endDay + " 23:59:59"; }, /*获取某个日期是当年中的第几天*/ dateDayOfYear(time) { let firstDayYear = this.dateFirstDayOfYear(time); let numSecond = (new Date(time).getTime() - new Date(firstDayYear).getTime()) / 1000; return Math.ceil(numSecond / (24 * 3600)); }, /*获取某个日期在这一年的第几周*/ dateDayOfYearWeek(time) { let numdays = this.dateDayOfYear(time); return Math.ceil(numdays / 7); }, /** * 是否对象 * @param {Object} obj 传入对象 * @return {Boolean} 返回true或false */ isObject(obj) { return obj !== null && typeof obj === 'object'; }, /** * 是否正则表达式 * @param {RegExp} v 传入正则表达式 * @return {Boolean} 返回true或false */ isRegExp(v) { return Object.prototype.toString.call(v) === '[object RegExp]'; }, /** * 是否未定义 * @param {String} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isUndef(v) { return v === undefined || v === null; }, /** * 是否已定义 * @param {String} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isDef(v) { return v !== undefined && v !== null; }, /** * 是否已定义 * @param {String} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isString(v) { return v.constructor == String; }, /** * 是否已定义 * @param {Number} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isNumber(v) { return v.constructor == Number; }, /** * 是否已定义 * @param {Boolean} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isBoolean(v) { return v.constructor == true; }, /** * 是否已定义 * @param {Function} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isFunc(v) { return v.constructor == Function; }, /** * 是否Array * @param {Array} v 传入需要校验的值 * @return {Boolean} 返回true或false */ isArray(v) { return Array.isArray(v); }, // 是否为false - https://www.cnblogs.com/cisum/p/12072873.html isTrue(any) { let match = ['undefined', 'null', 'NaN', 'false', false, 0, undefined, NaN, '']; return match.indexOf(any) > -1 ? false : true; }, /** * 是否存在空格 * @param {Object} obj 传入需要校验的值 * @return {Boolean} 返回true或false */ isSpaceObject(obj) { return Object.keys(obj).length > 0 ? true : false; }, /** * 是否存在空格 * @param {String} str 传入需要校验的值 * @return {Boolean} 返回true或false */ isSpace(str) { return /\s/.test(str); }, /** * 是否为符号 * @param {Symbol} symbol 传入需要校验的值 * @return {Boolean} 返回true或false */ isSymbol(v) { return typeof v === 'symbol'; }, /** * [获取当前经纬度] * const map = await this.$map.latlng(); * @return {Object}=>{lat:xx,lng:xx} */ latlng: () => { return new Promise((resolve, reject) => { wx.getLocation({ type: 'gcj02', success: res => { resolve({ lat: res.latitude, lng: res.longitude }); }, fail: err => { reject(err); } }); }); }, /** * [传入腾讯地图密钥以获取当前地理位置信息] * const map = await this.$map.location({lat:'xx',lng:'xx',key:'xxxx-xxxx'}); * * * gcj02不支持国外腾讯地图 * * @return {Object} */ location: ({ lat, lng, key }) => { return new Promise((resolve, reject) => { wx.request({ url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${key}`, method: 'GET', success: res => { res.data.status == 0 ? resolve(res.data.result) : reject(res.data .message); } }); }); }, /** * [传入腾讯地图密钥以获取当前地理位置信息以及当地天气] * const weather = await this.$map.weather({key:xxxx-xxxx}); * @return {Object} */ weather: ({ key }) => { return new Promise((resolve, reject) => { wx.getLocation({ type: 'gcj02', success: res => { wx.request({ url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${res.latitude},${res.longitude}&key=${key}`, method: 'GET', success: res => { if (res.data.message == 'query ok') { let address = res.data.result.address_component; wx.request({ url: `https://wis.qq.com/weather/common`, method: 'GET', data: { source: 'xw', weather_type: 'observe|alarm|air|forecast_1h|forecast_24h|index|limit|tips|rise', province: `${address.province}`, city: `${address.city}`, county: `${address.district}` }, success: res => { resolve(res.data.data); }, fail: () => { reject(res.data.message); }, complete: () => {} }); } } }); }, fail: err => { reject(err); } }); }); }, /** * [选择地图上的地址信息] * const map = await this.$map.chooseLocation({lat,lng}); * @return {Object} */ chooseLocation: ({ lat, lng }) => { return new Promise((resolve, reject) => { wx.chooseLocation({ latitude: lat, longitude: lng, success: res => { resolve(res); }, fail: err => { reject(err); } }); }); }, /** * [传入经纬度以及腾讯地图密钥获取对应地址信息] * const map = await this.$map.openLocation({lat:xx,lng:xx,key:'xx-xx'}); * @return {Null} */ openLocation: ({ lat, lng, key }) => { return new Promise((resolve, reject) => { wx.request({ url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${key}`, method: 'GET', success: res => { try { wx.openLocation({ latitude: res.data.result.location.lat, longitude: res.data.result.location.lng, name: res.data.result.ad_info.district, address: res.data.result.address, scale: 18 }); } catch (e) { //TODO handle the exception reject(res.data.message); } }, fail: err => { reject(err); } }); }); }, /*随机数范围*/ random(min, max) { if (arguments.length === 2) { return Math.floor(min + Math.random() * ((max + 1) - min)) } else { return null; } }, moneyFormat(number, decimals, dec_point, thousands_sep) { /* * 参数说明: * number:要格式化的数字 * decimals:保留几位小数 * dec_point:小数点符号 * thousands_sep:千分位符号 * */ number = (number + '').replace(/[^0-9+-Ee.]/g, ''); var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, s = '', toFixedFix = function(n, prec) { var k = Math.pow(10, prec); return '' + Math.floor(n * k) / k; }; s = (prec ? toFixedFix(n, prec) : '' + Math.floor(n)).split('.'); var re = /(-?\d+)(\d{3})/; // console.log(s) while (re.test(s[0])) { s[0] = s[0].replace(re, "$1" + sep + "$2"); } if ((s[1] || '').length < prec) { s[1] = s[1] || ''; s[1] += new Array(prec - s[1].length + 1).join('0'); } return s.join(dec); }, /** * 数值转字符串 * @param {Number} * @return {String} */ numStr(v) { return v.toString(); }, /** * 数值转字符串 * @param {Number} num 当前数字 * @param {Number} total 当前总数 * @return {String} 返回百分比 */ numPer(num, total) { num = parseFloat(num); total = parseFloat(total); if (isNaN(num) || isNaN(total)) { return "-"; } return total <= 0 ? "0%" : (Math.round(num / total * 10000) / 100.00) + "%"; }, /** * 取小数位 * @param {String,Number} * @return {String} */ numDigit(digit, num = 2) { return Number(digit).toFixed(num); }, /** * 取最小数 * @param {String,Number} * @return {String} */ numMin(v1, v2) { return Math.min(Number(v1), Number(v2)); }, /** * 取最大数 * @param {String,Number} * @return {String} */ numMax(v1, v2) { return Math.max(Number(v1), Number(v2)); }, /** * 返回数的绝对值 * @param {String,Number} * @return {String} */ numAbs(v) { return Math.abs(Number(v)); }, /** * 向上取整 * @param {String,Number} * @return {String} */ numUp(v) { return Math.ceil(Number(v)); }, /** * 向下取整 * @param {String,Number} * @return {String} */ numDown(v) { return Math.floor(Number(v)); }, /** * 去除小数部分 * @param {String,Number} * @return {String} */ numTrunc(v) { return Math.trunc(Number(v)); }, /** * 判断是否为正数/负数/零 * @param {String,Number} * @return {String} */ isSign(v) { return Math.sign(Number(v)); }, /** * 判断是否为整数 * @param {String,Number} * @return {String} */ isInt(v) { return Number.isInteger(Number(v)); }, // 设置页面标题 title(title) { wx.setNavigationBarTitle({ title }); }, /** * [URL参数拼接] * @param [url,obj] * @return {String} */ createURL({ url, obj }) { return new Promise((resolve, reject) => { let props = ""; for (let p in obj) { if (obj[p]) props += "&" + p + "=" + obj[p]; } resolve(`${url}?${props.substr(1)}`); }); }, /** * 保留当前页面,跳转到应用内的某个页面 * @param {String} url 页面路径 * @param {Object} params 页面参数 */ navGo(url, params) { this._openInterceptor('navigateTo', url, params); }, /** * 关闭当前页面,跳转到应用内的某个页面 * @param {String} url 页面路径 * @param {Object} params 页面参数 */ navTo(url, params) { this._openInterceptor('redirectTo', url, params); }, /** * 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 * @param {String} url 页面路径 * @param {Object} params 页面参数 */ navSwitch(url, params) { this._openInterceptor('switchTab', url, params); }, /** * 关闭所有页面,打开到应用内的某个页面 * @param {String} url 页面路径 * @param {Object} params 页面参数 */ navRe(url, params) { this._openInterceptor('reLaunch', url, params); }, /** * 返回页面 * @param {Number} delta 返回层级 * @param {None} params 无 */ navBack(delta = 1) { wx.navigateBack({ delta }); }, /** * 页面跳转封装 * @param {String} method 微信JS方法 * @param {String} url 页面路径 * @param {Object} params 页面参数 */ _openInterceptor(method, url, params) { if (this.IsPageNavigating) return; this.IsPageNavigating = true; params = this.param(params); wx[method]({ url: url + params, complete: () => { this.IsPageNavigating = false; } }); }, // 授权数据解析 authParam(obj) { if (obj) { if (Object.keys(obj).length) { return JSON.parse(obj); } } else { return {}; } }, /** * 将对象解析成url字符串 * @param {Object} obj 参数对象 * @param {Boolean} unEncodeURI 不使用编码 * @return {String} 转换之后的url参数 */ param(obj = {}, unEncodeURI) { let result = []; for (let name of Object.keys(obj)) { let value = obj[name]; result.push(name + '=' + (unEncodeURI ? value : encodeURIComponent(value))); } if (result.length) { return '?' + result.join('&'); } else { return ''; } }, /** * 将url字符串解析成对象 * @param {String} str 带url参数的地址 * @param {Boolean} unDecodeURI 不使用解码 * @return {Object} 转换之后的url参数 */ unparam(str = '', unDecodeURI) { let result = {}, query = str.split('?')[1]; if (!query) return result; let arr = query.split('&'); arr.forEach((item, idx) => { let param = item.split('='), name = param[0], value = param[1] || ''; if (name) { result[name] = unDecodeURI ? value : decodeURIComponent(value); } }); return result; }, // 获取上级页面 getCurrentPageUrl() { let pages = getCurrentPages(); let currentPage = pages[pages.length - 1]; let url = currentPage.route; return url; }, /** * [微信小程序拦截] * @param [url:地址,param:参数] * @return {Null} */ weChatAuth(url, param) { let parse = JSON.stringify(encodeURIComponent(param)); if (!wx.getStorageSync('userInfo')) { wx.navigateTo({ url: `/pages/auth/auth?url=${url}&parse=${parse}` }); } else { wx.navigateTo({ url: `${url}?${param}` }); } }, /** * 获取当前页面路径 * @param {} * @return {Object} */ getCurrentPath() { return this.getCurrentPage().__route__; }, /** * @param {Object} pay 支付参数 * @return {Callback} 无 * */ wePay(args, success, fail) { wx.requestPayment({ "provider": args.provider || 'wxpay', "timeStamp": args.timeStamp, "nonceStr": args.nonceStr, "package": args.package, "signType": args.signType, "paySign": args.paySign, "success": (res) => { success(JSON.stringify(res)); }, "fail": (err) => { fail(JSON.stringify(err)); } }); }, /** * 校验手机号 * @param mobile * @returns {boolean} */ checkPhone(mobile) { return /^[1][0-9]{10}$/.test(mobile) }, /** * 校验纯数字 * @param num * @returns {boolean} */ checkNum(num) { return /^[0-9]+$/.test(num) }, /** * 校验用户名:1-20位字符,首字符为字母 * @param str * @returns {RegExp} */ checkUserName(str) { return /^[a-zA-Z]{1,20}$/.test(str) }, /** * 校验密码:6-20位,数字、字母、下划线 * @param str * @returns {boolean} */ checkPwd(str) { return /^(\\w){6,20}$/.test(str) }, /** * 校验正整数 + 0 * @param num * @returns {boolean} */ checkPositiveInteger(num) { return /^[0-9]*[1-9][0-9]*$/.test(num) }, /** * 校验字符串是否为数字 * @param str * @returns {boolean} */ checkNumber(str) { let regPos = /^\d+(\.\d+)?$/; //非负浮点数 let regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数 if (regPos.test(str) || regNeg.test(str)) { return true; } else { return false; } }, /** * 校验字符串是否为电子邮箱 * @param str * @returns {boolean} */ checkEmail(str) { return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ .test(str); }, /** * 小于10补零 * @param {String,Number} number 传入的数值 * @return {String} 返回字符串 */ toDigit(any) { return any.toString().replace(/^(\d)$/, `0$1`); }, /** * 类型判断 * @param {Any} value 任意需要判断的参数 * @return {String} 返回的类型 */ type(v) { return Object.prototype.toString.call(v).split(' ')[1].substr(0, Object.prototype.toString.call(v) .split(' ')[1].length - 1); }, /** * 消息 * @param {String} key 设置key * @return {NONE} 打印消息 */ toast(title = "提示", icon = "none", duration = "2") { wx.showToast({ title, icon, duration: Number(duration) * 1e3 }); }, /** * 取小数位 * @param {String,Number} * @return {String} */ digit(digit, num = 2) { return Number(digit).toFixed(num); }, /** * 获取点击元素携带值 * @param {Object} e 点击对象 * @param {String} elename 点击所获取的具体值 * @return {Object,String} getElement 返回对象或者字符串 */ ele(e, elename) { return elename ? e.currentTarget.dataset[elename] : e.currentTarget.dataset; }, // 获取任意区间随机数 random(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); }, /** * [匹配item是否在数组] * @param [m:延迟时间] * @return [none] */ delay(m = 3, success) { setTimeout(() => { success() }, m * 1e3); }, /** * [去除所有空格] * @param [str:字符串] * @return str */ spaceRemove(str) { return str.replace(/\s+/g, ''); }, /** * [拨打号码] * @param [phoneNumber:手机号] * @return {Null} */ phone(phoneNumber) { wx.makePhoneCall({ phoneNumber: phoneNumber + '' }); }, /** * [底部适配(iphone XR\iphone X\ iphone Xs Max)] * @return {Boolean} */ isIphoneX() { return new Promise((resolve, reject) => { wx.getSystemInfo({ success(res) { resolve(res.model.search('iPhone X') != -1); }, fail(err) { reject(err); } }); }); }, /** * [sleep睡眠时间] * @return {Boolean} */ sleep(numberMillis) { let now = new Date(); let exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } }, /** * @param {} * @return {String} uuid 返回uuid */ uuid() { return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); }, /** * @param {Function} * @return {String} time 返回程序所用时间 */ timeConsum(callback) { console.time('timeTaken'); const r = callback(); console.timeEnd('timeTaken'); return r; }, // 身份证号脱敏 desensitizationIdNumber(idNumber) { return idNumber.replace(/^(.{6})(?:\d+)(.{4})$/, "\$1********\$2") }, // 数据脱敏 desensitization(string = '', start, end) { let star = '' function makeStar(number) { if (number > 0) { star += '*'; return makeStar(--number) } else { return star } }; return string.substring(0, start) + makeStar(end - start) + string.substring(end) }, // 手机号脱敏 desensitizationPhone(phone) { return phone.substring(0, 3) + "****" + phone.substring(7) } }