// 公共方法工具类 /** * 日期处理相关方法 */ export const dateUtil = { /** * 格式化日期 * @param {Date|string|number} date - 日期对象或时间戳 * @param {string} format - 格式化字符串,默认为 'YYYY-MM-DD HH:mm:ss' * @returns {string} 格式化后的日期字符串 */ format(date, format = 'YYYY-MM-DD HH:mm:ss') { if (!date) return ''; if (typeof date === 'string' || typeof date === 'number') { date = new Date(date); } const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.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 HH:mm:ss') { return this.format(new Date(), format); }, /** * 获取相对时间 * @param {Date|string|number} date - 日期对象或时间戳 * @returns {string} 相对时间描述 */ relative(date) { if (!date) return ''; if (typeof date === 'string' || typeof date === 'number') { date = new Date(date); } const now = new Date(); const diff = now - date; const seconds = Math.floor(diff / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (seconds < 60) return '刚刚'; if (minutes < 60) return `${minutes}分钟前`; if (hours < 24) return `${hours}小时前`; if (days < 30) return `${days}天前`; return this.format(date, 'YYYY-MM-DD'); }, /** * 智能时间格式化 * 今天 HH:mm * 昨天 HH:mm * 其他 MM-DD HH:mm * @param {Date|string|number} date - 日期对象或时间戳 * @returns {string} 格式化后的时间字符串 */ smart(date) { if (!date) return ''; if (typeof date === 'string' || typeof date === 'number') { date = new Date(date); } const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const yesterday = new Date(today); yesterday.setDate(yesterday.getDate() - 1); const target = new Date(date.getFullYear(), date.getMonth(), date.getDate()); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const timeStr = `${hours}:${minutes}`; if (target.getTime() === today.getTime()) { return `今天 ${timeStr}`; } else if (target.getTime() === yesterday.getTime()) { return `昨天 ${timeStr}`; } else { const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${month}-${day} ${timeStr}`; } } }; /** * 数字处理相关方法 */ export const numberUtil = { /** * 格式化数字,添加千分位 * @param {number|string} num - 数字或数字字符串 * @returns {string} 格式化后的数字字符串 */ format(num) { if (num === null || num === undefined) return '0'; const number = typeof num === 'string' ? parseFloat(num) : num; if (isNaN(number)) return '0'; return number.toLocaleString(); }, /** * 格式化金额 * @param {number|string} amount - 金额 * @param {number} decimals - 小数位数,默认为2 * @returns {string} 格式化后的金额字符串 */ formatMoney(amount, decimals = 2) { if (amount === null || amount === undefined) return '0.00'; const number = typeof amount === 'string' ? parseFloat(amount) : amount; if (isNaN(number)) return '0.00'; return number.toFixed(decimals); }, /** * 格式化金额,添加千分位并保留两位小数 * @param {number|string} val - 金额 * @returns {string} 格式化后的金额字符串 */ formatMoneyWithThousand(val) { let num = Number(val); if (isNaN(num)) { return '0.00'; } let str = num.toFixed(2); let parts = str.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); return parts.join('.'); }, /** * 随机数生成 * @param {number} min - 最小值 * @param {number} max - 最大值 * @returns {number} 随机数 */ random(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, /** * 保留小数位 * @param {number} num - 数字 * @param {number} decimals - 小数位数,默认为2 * @returns {string} 保留小数位后的数字字符串 */ toFiexd(num, decimals = 2) { return Number(num).toFixed(decimals); } }; /** * 字符串处理相关方法 */ export const stringUtil = { /** * 截断字符串 * @param {string} str - 原始字符串 * @param {number} length - 截断长度 * @param {string} suffix - 后缀,默认为 '...' * @returns {string} 截断后的字符串 */ truncate(str, length, suffix = '...') { if (!str || str.length <= length) return str; return str.substring(0, length) + suffix; }, /** * 生成唯一ID * @returns {string} 唯一ID */ uuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }, /** * 手机号脱敏 * @param {string} phone - 手机号 * @returns {string} 脱敏后的手机号 */ maskPhone(phone) { if (!phone || phone.length !== 11) return phone; return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'); }, /** * 身份证号脱敏 * @param {string} idCard - 身份证号 * @returns {string} 脱敏后的身份证号 */ maskIdCard(idCard) { if (!idCard) return idCard; const length = idCard.length; if (length < 8) return idCard; return idCard.substring(0, 4) + '*'.repeat(length - 8) + idCard.substring(length - 4); } }; /** * 设备信息相关方法 */ export const deviceUtil = { /** * 获取系统信息 * @returns {Promise} 系统信息对象 */ getSystemInfo() { return new Promise((resolve, reject) => { uni.getSystemInfo({ success: resolve, fail: reject }); }); }, /** * 获取状态栏高度 * @returns {Promise} 状态栏高度 */ async getStatusBarHeight() { try { const systemInfo = await this.getSystemInfo(); return systemInfo.statusBarHeight || 0; } catch (error) { console.error('获取状态栏高度失败:', error); return 0; } }, /** * 判断是否为iOS设备 * @returns {Promise} 是否为iOS设备 */ async isIOS() { try { const systemInfo = await this.getSystemInfo(); return systemInfo.platform === 'ios'; } catch (error) { console.error('获取设备平台失败:', error); return false; } }, /** * 判断是否为Android设备 * @returns {Promise} 是否为Android设备 */ async isAndroid() { try { const systemInfo = await this.getSystemInfo(); return systemInfo.platform === 'android'; } catch (error) { console.error('获取设备平台失败:', error); return false; } }, /** * 获取窗口宽度 * @returns {Promise} 窗口宽度(px) */ async getWindowWidth() { try { const systemInfo = await this.getSystemInfo(); return systemInfo.windowWidth || 0; } catch (error) { console.error('获取窗口宽度失败:', error); return 0; } }, /** * 获取窗口高度 * @returns {Promise} 窗口高度(px) */ async getWindowHeight() { try { const systemInfo = await this.getSystemInfo(); return systemInfo.windowHeight || 0; } catch (error) { console.error('获取窗口高度失败:', error); return 0; } } }; /** * UI相关方法 */ export const uiUtil = { /** * 显示加载提示 * @param {string} title - 提示文本 * @param {boolean} mask - 是否显示遮罩 * @returns {void} */ showLoading(title = '加载中', mask = true) { uni.showLoading({ title, mask }); }, /** * 隐藏加载提示 * @returns {void} */ hideLoading() { uni.hideLoading(); }, /** * 显示错误提示 * @param {string} title - 提示文本 * @param {number} duration - 显示时长 * @returns {void} */ showError(title, duration = 1500) { uni.showToast({ title, icon: 'none', duration }); }, /** * 显示警告提示 * @param {string} title - 提示文本 * @param {string} content - 提示内容 * @param {Function} confirm - 确认回调 * @param {Function} cancel - 取消回调 * @returns {void} */ showConfirm(title, content, confirm, cancel) { uni.showModal({ title, content, success(res) { if (res.confirm) { confirm && confirm(); } else if (res.cancel) { cancel && cancel(); } } }); } }; /** * 其他工具方法 */ export const util = { /** * 设置底部状态栏颜色 * @param {string} backgroundColor - 颜色值 * @returns {void} */ setAndroidSystemBarColor(backgroundColor, frontColor = "#000000") { // 使用同步方式判断或直接通过编译宏/plus判断 const isAndroid = uni.getSystemInfoSync().platform === 'android'; if (isAndroid) { try { // #ifdef APP-PLUS if (plus.os.name === 'Android') { let color = plus.android.newObject("android.graphics.Color"); let activity = plus.android.runtimeMainActivity(); let colorInt = plus.android.invoke(color, "parseColor", backgroundColor); let window = plus.android.invoke(activity, "getWindow"); plus.android.invoke(window, "setNavigationBarColor", colorInt); uni.setNavigationBarColor({ animation: { // 动画效果 duration: 100, timingFunc: 'easeIn' } }) setTimeout(function () { uni.setNavigationBarColor({ animation: { // 动画效果 duration: 100, timingFunc: 'easeIn' } }) }, 200); } // #endif } catch (err) { console.log("状态栏修改失败", err); uni.setNavigationBarColor({ animation: { // 动画效果 duration: 100, timingFunc: 'easeIn' } }) } } }, /** * 点击标题栏按钮 * @param {*} button */ clickTitlePopupButton(button) { button.click() }, /** * 页面跳转 * @param {*} url */ goPage(url) { uni.navigateTo({ url }); }, /** * 返回 */ goBack() { uni.navigateBack(); } }; /** * 生成随机数据工具 */ export const randomUtil = { /** * 生成随机数 * @param {number} min - 最小值 * @param {number} max - 最大值 * @returns {number} 随机数 */ random(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, /** * 生成随机时间格式化时间 * @param {string|number|Date} startTime - 开始时间 * @param {string|number|Date} endTime - 结束时间 * @param {string} format - 格式化字符串 * @returns {string} 格式化后的时间 */ randomTime(startTime, endTime, format = 'YYYY-MM-DD HH:mm:ss') { let end; if (endTime) { end = new Date(endTime).getTime(); } else { end = Date.now(); } let start; if (startTime) { start = new Date(startTime).getTime(); } else { // 默认为结束时间往前推3个月 const date = new Date(end); date.setMonth(date.getMonth() - 3); start = date.getTime(); } const randomTimestamp = Math.floor(Math.random() * (end - start + 1)) + start; return dateUtil.format(randomTimestamp, format); }, /** * 生成随机金额 * @param {number} min - 最小值 * @param {number} max - 最大值 * @returns {string} 随机金额 */ randomMoney(min = 0, max = 5000) { const num = Math.random() * (max - min) + min; return num.toFixed(2); }, /** * 随机生成指定位数订单号 * @param {number} length - 订单号位数 * @returns {string} 订单号 */ randomOrderNumber(length = 16) { if (length < 13) { // 长度小于13,直接返回随机数字字符串 let result = ''; for (let i = 0; i < length; i++) { result += Math.floor(Math.random() * 10); } return result; } // 长度大于等于13,使用时间戳+随机数 const timestamp = Date.now().toString(); let result = timestamp; const padding = length - timestamp.length; if (padding > 0) { for (let i = 0; i < padding; i++) { result += Math.floor(Math.random() * 10); } } return result; } }; // 默认导出所有工具方法 export default { ...dateUtil, ...numberUtil, ...stringUtil, ...deviceUtil, ...uiUtil, ...util, ...randomUtil };