427 lines
8.2 KiB
JavaScript
427 lines
8.2 KiB
JavaScript
|
|
/**
|
|||
|
|
* 工具函数库
|
|||
|
|
* 封装常用工具函数
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { getStorageKey, validate as configValidate } from '../config/index.js'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 存储工具
|
|||
|
|
*/
|
|||
|
|
export const storage = {
|
|||
|
|
/**
|
|||
|
|
* 设置缓存
|
|||
|
|
* @param {string} key - 键名
|
|||
|
|
* @param {*} value - 值
|
|||
|
|
*/
|
|||
|
|
set(key, value) {
|
|||
|
|
const storageKey = getStorageKey(key)
|
|||
|
|
try {
|
|||
|
|
uni.setStorageSync(storageKey, value)
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('Storage set error:', e)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取缓存
|
|||
|
|
* @param {string} key - 键名
|
|||
|
|
* @returns {*}
|
|||
|
|
*/
|
|||
|
|
get(key) {
|
|||
|
|
const storageKey = getStorageKey(key)
|
|||
|
|
try {
|
|||
|
|
return uni.getStorageSync(storageKey)
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('Storage get error:', e)
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 移除缓存
|
|||
|
|
* @param {string} key - 键名
|
|||
|
|
*/
|
|||
|
|
remove(key) {
|
|||
|
|
const storageKey = getStorageKey(key)
|
|||
|
|
try {
|
|||
|
|
uni.removeStorageSync(storageKey)
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('Storage remove error:', e)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清空缓存
|
|||
|
|
*/
|
|||
|
|
clear() {
|
|||
|
|
try {
|
|||
|
|
uni.clearStorageSync()
|
|||
|
|
} catch (e) {
|
|||
|
|
console.error('Storage clear error:', e)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证工具
|
|||
|
|
*/
|
|||
|
|
export const validator = {
|
|||
|
|
/**
|
|||
|
|
* 验证手机号
|
|||
|
|
* @param {string} phone - 手机号
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
phone(phone) {
|
|||
|
|
return configValidate('phone', phone)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证邮箱
|
|||
|
|
* @param {string} email - 邮箱
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
email(email) {
|
|||
|
|
return configValidate('email', email)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证密码
|
|||
|
|
* @param {string} password - 密码
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
password(password) {
|
|||
|
|
return configValidate('password', password)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证用户名
|
|||
|
|
* @param {string} username - 用户名
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
username(username) {
|
|||
|
|
return configValidate('username', username)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证金额
|
|||
|
|
* @param {string|number} amount - 金额
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
amount(amount) {
|
|||
|
|
return configValidate('amount', String(amount))
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证是否为空
|
|||
|
|
* @param {*} value - 值
|
|||
|
|
* @returns {boolean}
|
|||
|
|
*/
|
|||
|
|
isEmpty(value) {
|
|||
|
|
if (value === null || value === undefined) return true
|
|||
|
|
if (typeof value === 'string') return value.trim() === ''
|
|||
|
|
if (Array.isArray(value)) return value.length === 0
|
|||
|
|
if (typeof value === 'object') return Object.keys(value).length === 0
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 日期工具
|
|||
|
|
*/
|
|||
|
|
export const dateUtil = {
|
|||
|
|
/**
|
|||
|
|
* 格式化日期
|
|||
|
|
* @param {Date|string|number} date - 日期
|
|||
|
|
* @param {string} format - 格式
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
format(date, format = 'YYYY-MM-DD') {
|
|||
|
|
const d = new Date(date)
|
|||
|
|
const year = d.getFullYear()
|
|||
|
|
const month = String(d.getMonth() + 1).padStart(2, '0')
|
|||
|
|
const day = String(d.getDate()).padStart(2, '0')
|
|||
|
|
const hours = String(d.getHours()).padStart(2, '0')
|
|||
|
|
const minutes = String(d.getMinutes()).padStart(2, '0')
|
|||
|
|
const seconds = String(d.getSeconds()).padStart(2, '0')
|
|||
|
|
|
|||
|
|
return format
|
|||
|
|
.replace('YYYY', year)
|
|||
|
|
.replace('MM', month)
|
|||
|
|
.replace('DD', day)
|
|||
|
|
.replace('HH', hours)
|
|||
|
|
.replace('mm', minutes)
|
|||
|
|
.replace('ss', seconds)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前日期
|
|||
|
|
* @param {string} format - 格式
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
now(format = 'YYYY-MM-DD') {
|
|||
|
|
return this.format(new Date(), format)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取月份第一天
|
|||
|
|
* @param {Date|string|number} date - 日期
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
getFirstDayOfMonth(date = new Date()) {
|
|||
|
|
const d = new Date(date)
|
|||
|
|
d.setDate(1)
|
|||
|
|
return this.format(d)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取月份最后一天
|
|||
|
|
* @param {Date|string|number} date - 日期
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
getLastDayOfMonth(date = new Date()) {
|
|||
|
|
const d = new Date(date)
|
|||
|
|
d.setMonth(d.getMonth() + 1)
|
|||
|
|
d.setDate(0)
|
|||
|
|
return this.format(d)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 金额工具
|
|||
|
|
*/
|
|||
|
|
export const moneyUtil = {
|
|||
|
|
/**
|
|||
|
|
* 格式化金额
|
|||
|
|
* @param {number} amount - 金额
|
|||
|
|
* @param {number} decimals - 小数位数
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
format(amount, decimals = 2) {
|
|||
|
|
if (amount === null || amount === undefined) return '0.00'
|
|||
|
|
const num = parseFloat(amount)
|
|||
|
|
if (isNaN(num)) return '0.00'
|
|||
|
|
return num.toFixed(decimals)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 格式化金额(带千分位)
|
|||
|
|
* @param {number} amount - 金额
|
|||
|
|
* @param {number} decimals - 小数位数
|
|||
|
|
* @returns {string}
|
|||
|
|
*/
|
|||
|
|
formatWithComma(amount, decimals = 2) {
|
|||
|
|
if (amount === null || amount === undefined) return '0.00'
|
|||
|
|
const num = parseFloat(amount)
|
|||
|
|
if (isNaN(num)) return '0.00'
|
|||
|
|
const parts = num.toFixed(decimals).split('.')
|
|||
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|||
|
|
return parts.join('.')
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 元转分
|
|||
|
|
* @param {number} yuan - 元
|
|||
|
|
* @returns {number}
|
|||
|
|
*/
|
|||
|
|
yuanToFen(yuan) {
|
|||
|
|
return Math.round(parseFloat(yuan) * 100)
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 分转元
|
|||
|
|
* @param {number} fen - 分
|
|||
|
|
* @returns {number}
|
|||
|
|
*/
|
|||
|
|
fenToYuan(fen) {
|
|||
|
|
return parseFloat((fen / 100).toFixed(2))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 页面工具
|
|||
|
|
*/
|
|||
|
|
export const pageUtil = {
|
|||
|
|
/**
|
|||
|
|
* 显示加载提示
|
|||
|
|
* @param {string} title - 提示文字
|
|||
|
|
*/
|
|||
|
|
showLoading(title = '加载中...') {
|
|||
|
|
uni.showLoading({
|
|||
|
|
title,
|
|||
|
|
mask: true
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 隐藏加载提示
|
|||
|
|
*/
|
|||
|
|
hideLoading() {
|
|||
|
|
uni.hideLoading()
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 显示成功提示
|
|||
|
|
* @param {string} title - 提示文字
|
|||
|
|
* @param {Function} callback - 回调函数
|
|||
|
|
*/
|
|||
|
|
showSuccess(title, callback) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title,
|
|||
|
|
icon: 'success',
|
|||
|
|
duration: 1500,
|
|||
|
|
success: callback
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 显示错误提示
|
|||
|
|
* @param {string} title - 提示文字
|
|||
|
|
*/
|
|||
|
|
showError(title) {
|
|||
|
|
uni.showToast({
|
|||
|
|
title,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 显示确认对话框
|
|||
|
|
* @param {string} title - 标题
|
|||
|
|
* @param {string} content - 内容
|
|||
|
|
* @returns {Promise}
|
|||
|
|
*/
|
|||
|
|
confirm(title, content = '') {
|
|||
|
|
return new Promise((resolve) => {
|
|||
|
|
uni.showModal({
|
|||
|
|
title,
|
|||
|
|
content,
|
|||
|
|
success: (res) => {
|
|||
|
|
resolve(res.confirm)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 跳转到页面
|
|||
|
|
* @param {string} url - 页面路径
|
|||
|
|
* @param {Object} params - 参数
|
|||
|
|
*/
|
|||
|
|
navigateTo(url, params = {}) {
|
|||
|
|
const queryString = Object.keys(params)
|
|||
|
|
.map(key => `${key}=${encodeURIComponent(params[key])}`)
|
|||
|
|
.join('&')
|
|||
|
|
const fullUrl = queryString ? `${url}?${queryString}` : url
|
|||
|
|
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: fullUrl
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 重定向到页面
|
|||
|
|
* @param {string} url - 页面路径
|
|||
|
|
*/
|
|||
|
|
redirectTo(url) {
|
|||
|
|
uni.redirectTo({
|
|||
|
|
url
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 切换到Tab页面
|
|||
|
|
* @param {string} url - 页面路径
|
|||
|
|
*/
|
|||
|
|
switchTab(url) {
|
|||
|
|
uni.switchTab({
|
|||
|
|
url
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 返回上一页
|
|||
|
|
* @param {number} delta - 返回层级
|
|||
|
|
*/
|
|||
|
|
navigateBack(delta = 1) {
|
|||
|
|
uni.navigateBack({
|
|||
|
|
delta
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 重新启动应用
|
|||
|
|
* @param {string} url - 启动页面
|
|||
|
|
*/
|
|||
|
|
reLaunch(url) {
|
|||
|
|
uni.reLaunch({
|
|||
|
|
url
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 防抖函数
|
|||
|
|
* @param {Function} fn - 原函数
|
|||
|
|
* @param {number} delay - 延迟时间
|
|||
|
|
* @returns {Function}
|
|||
|
|
*/
|
|||
|
|
export const debounce = (fn, delay = 300) => {
|
|||
|
|
let timer = null
|
|||
|
|
return function (...args) {
|
|||
|
|
if (timer) clearTimeout(timer)
|
|||
|
|
timer = setTimeout(() => {
|
|||
|
|
fn.apply(this, args)
|
|||
|
|
}, delay)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 节流函数
|
|||
|
|
* @param {Function} fn - 原函数
|
|||
|
|
* @param {number} interval - 间隔时间
|
|||
|
|
* @returns {Function}
|
|||
|
|
*/
|
|||
|
|
export const throttle = (fn, interval = 300) => {
|
|||
|
|
let lastTime = 0
|
|||
|
|
return function (...args) {
|
|||
|
|
const now = Date.now()
|
|||
|
|
if (now - lastTime >= interval) {
|
|||
|
|
lastTime = now
|
|||
|
|
fn.apply(this, args)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 深拷贝
|
|||
|
|
* @param {*} obj - 原对象
|
|||
|
|
* @returns {*}
|
|||
|
|
*/
|
|||
|
|
export const deepClone = (obj) => {
|
|||
|
|
if (obj === null || typeof obj !== 'object') return obj
|
|||
|
|
if (obj instanceof Date) return new Date(obj)
|
|||
|
|
if (obj instanceof Array) return obj.map(item => deepClone(item))
|
|||
|
|
if (obj instanceof Object) {
|
|||
|
|
const copy = {}
|
|||
|
|
Object.keys(obj).forEach(key => {
|
|||
|
|
copy[key] = deepClone(obj[key])
|
|||
|
|
})
|
|||
|
|
return copy
|
|||
|
|
}
|
|||
|
|
return obj
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 默认导出所有工具
|
|||
|
|
export default {
|
|||
|
|
storage,
|
|||
|
|
validator,
|
|||
|
|
dateUtil,
|
|||
|
|
moneyUtil,
|
|||
|
|
pageUtil,
|
|||
|
|
debounce,
|
|||
|
|
throttle,
|
|||
|
|
deepClone
|
|||
|
|
}
|