const WEEK = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] const toHideToast = debounce(options => { wx.showToast(options) }, 400) function platform() { let systemInfo = {} let u = '' wx.getSystemInfo({ success(res) { systemInfo = res u = systemInfo.system || '' } }) return { ...systemInfo, ios: u.indexOf('iOS') > -1, // ios终端 android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1 // android终端或uc浏览器 } } function addMultiMonth(dtstr, n) { let yy = parseInt(dtstr[0]) let mm = parseInt(dtstr[1]) let dd = parseInt(dtstr[2]) const dt = new Date(yy, mm, dd) const num = dt.getMonth() + parseInt(n) if (num / 12 > 1) { yy += Math.floor(num / 12) mm = num % 12 } else { mm += parseInt(n) } return [yy, mm, dd] } function range(n, m, polyfill = false, unit = '') { const arr = [] for (let i = n; i <= m; i++) { const value = (polyfill && i < 10 ? '0' + i : i) + unit arr.push({ text: value, value: i }) } return arr } function glDate() { const date = new Date() const YEAR = date.getFullYear() const MONTH = date.getMonth() + 1 const DAY = date.getDate() const min = [YEAR, MONTH, DAY] // 产品要求:可选时间范围未来3个月内 const max = addMultiMonth(min, 3) const data = range(min[0], max[0], false, '') data.forEach(year => { const minMonth = year.value === min[0] ? min[1] : 1 const maxMonth = year.value === max[0] ? max[1] : 12 year.children = range(minMonth, maxMonth, true, '') year.children.forEach(month => { let day = 30 if ([1, 3, 5, 7, 8, 10, 12].indexOf(month.value) > -1) { day = 31 } else { if (month.value === 2) { day = !(year.value % 400) || (!(year.value % 4) && year.value % 100) ? 29 : 28 } } const minDay = year.value === min[0] && month.value === min[1] ? min[2] : 1 const maxDay = year.value === max[0] && month.value === max[1] ? max[2] : day month.children = range(minDay, maxDay, true, '') }) }) return data } function formatGlDate() { const MINUTES = ['00', '10', '20', '30', '40', '50'] const arr = glDate() const result = [] for (let i = 0; i < arr.length; i++) { const YYYY = arr[i].text for (let j = 0; j < arr[i].children.length; j++) { const MM = arr[i].children[j].text for (let k = 0; k < arr[i].children[j].children.length; k++) { const DD = arr[i].children[j].children[k].text result.push(`${YYYY}-${MM}-${DD}`) } } } const one = result.map((item, index) => { const cur = new Date(platform().ios ? item.replace(/-/g, '/') : item).getDay() const value = item.replace('-', '年').replace('-', '月') + '日' + ' ' + WEEK[cur] return { value: (index + 11).toString(), text: value.replace(/(.*年)(.*)/, '$2'), _text: value.replace(/日.*/, '').replace(/年|月/g, '-') } }) const two = range(0, 23, true, '').map((item, index) => { return { value: '11' + (index < 10 ? '0' + index : index), text: item.text + '时', _text: item.text } }) const three = MINUTES.map((item, index) => { return { value: '1100' + (index < 10 ? '0' + index : index), text: item + '分', _text: item } }) return { one, two, three } } const formatTime = date => { const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() const hour = date.getHours() const minute = date.getMinutes() const second = date.getSeconds() return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map( formatNumber).join(':')}` } const formatArr = (arr) => { while (arr.some(item => Array.isArray(item))) { arr = [].concat(...arr) } return arr } function formatNumber(n) { n = n.toString() return n[1] ? n : `0${n}` } function cutDownTime(ts = 0, type) { if (ts < 0) { return ['0', '00', '00', '00'] } ts = parseInt(ts) var D = Math.floor(ts / 24 / 60 / 60) // 小时位 var h = Math.floor((ts - D * 24 * 60 * 60) / 3600) // 分钟位 var m = Math.floor((ts - D * 24 * 3600 - h * 3600) / 60) // 秒位 var s = ts - D * 24 * 3600 - h * 3600 - m * 60 if (['hh:mm:ss'].includes(type)) { return `${formatNumber(D * 24 + h)}:${formatNumber(m)}:${formatNumber(s)}` } if (type === 'hh:mm zh') { return (D * 24 + h) + '小时' + m + '分' } return [D, formatNumber(h), formatNumber(m), formatNumber(s)] } function formatLocation(longitude, latitude) { if (typeof longitude === 'string' && typeof latitude === 'string') { longitude = parseFloat(longitude) latitude = parseFloat(latitude) } longitude = longitude.toFixed(2) latitude = latitude.toFixed(2) return { longitude: longitude.toString().split('.'), latitude: latitude.toString().split('.') } } function formatTs(ts) { const date = new Date(ts) return { YYYY: date.getFullYear(), MM: datePolyfill(date.getMonth() + 1), DD: datePolyfill(date.getDate()), HH: datePolyfill(date.getHours()), mm: datePolyfill(date.getMinutes()), ss: datePolyfill(date.getSeconds()), week: WEEK[date.getDay()] } } function datePolyfill(val) { return (val < 10 ? '0' + val : val) + '' } /** * 检测当前的小程序 * 是否是最新版本,是否需要下载、更新 */ function checkUpdateVersion() { //判断微信版本是否 兼容小程序更新机制API的使用 if (wx.canIUse('getUpdateManager')) { const updateManager = wx.getUpdateManager() //检测版本更新 updateManager.onCheckForUpdate(function (res) { if (res.hasUpdate) { updateManager.onUpdateReady(function () { wx.showModal({ title: '温馨提示', content: '检测到新版本,是否重启小程序?', showCancel: false, success: function (res) { if (res.confirm) { // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 updateManager.applyUpdate() } } }) }) updateManager.onUpdateFailed(function () { // 新版本下载失败 wx.showModal({ title: '已有新版本', content: '请您删除小程序,重新搜索进入' }) }) } }) } else { wx.showModal({ title: '溫馨提示', content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。' }) } } /** * 函数防抖 * @param fn * @param wait * @param immediate * @returns {(function(...[*]=): void)|*} */ function debounce(fn, wait = 1000, immediate = false) { let timer = null return function (...args) { const context = this if (timer) { clearTimeout(timer) } if (immediate && !timer) { fn.apply(context, args) } timer = setTimeout(() => { fn.apply(context, args) }, wait) } } function fen2Yuan(num) { return isNaN(num) ? '' : (num * 0.01).toFixed(2) * 1 } function yuan2Fen(num) { if (isNaN(num)) { return '' } var amount = num.toString() var index = amount.indexOf('.') var arr = amount.split('.') var result = arr[0] * 100 if (index > -1) { var temp = arr[1].split('') for (var i = 0; i < temp.length; i++) { if (i === 0) { result += temp[i] * 10 } else { result += temp[i] * 1 } } } return result } /** * 开始时间与耗时之间的日期详情 * @param startTs * @param duration * @returns {[]|*[]} */ function getDayList(startTs, duration) { const isStartTs = Object.prototype.toString.call(startTs) === '[object Number]' const isDuration = Object.prototype.toString.call(duration) === '[object Number]' if (!isStartTs || !isDuration) { return [] } const result = [] const hours = [] const restTs = 3 * 3600 * 1000 const start = formatTs(startTs) const startHour = start.HH * 1 const polyfill = platform().ios ? '/' : '-' const YYYYMMDD = `${start.YYYY}${polyfill}${start.MM}${polyfill}${start.DD}` const startMax = new Date(`${YYYYMMDD} 23:59:59`).getTime() // 当天结束时间 let endTs = startTs + duration // 当天结束时间 let end = formatTs(endTs) let endHour = end.HH * 1 // 大于当天23:59:59时 if (endTs > startMax) { endTs = startMax end = formatTs(startMax) endHour = end.HH * 1 // 计算剩余日期 duration = duration - (startMax - startTs) } else { // 小于等于当天23:59:59时 duration = 0 } for (let i = startHour; i <= endHour; i++) { hours.push(i) } // 限行:高速2:00~5:00客车禁止通行 if (hours.some(item => [2, 3, 4].findIndex(hour => hour === item) > -1)) { if (duration > 0) { duration += restTs } else { if (restTs + endTs <= startMax) { endTs = restTs + endTs end = formatTs(endTs) } else { duration = restTs - (startMax - endTs) end = formatTs(startMax) endTs = startMax } } } // 相差一分钟以上 if (endTs - startTs >= 60000) { result.push({ start, end, startTs, endTs, morThen22: endHour >= 22, // 关联住宿:是否跨过当天22:00 duration }) } if (duration <= 0) { return result } return result.concat(getDayList(endTs + 1000, duration - 1000)) } module.exports = { platform, formatTime, formatArr, formatGlDate, cutDownTime, formatLocation, formatTs, checkUpdateVersion, debounce, toHideToast, fen2Yuan, yuan2Fen, getDayList }