| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- /**
- * 工具函数库
- */
- /**
- * 格式化日期时间
- * @param {String|Date} dateTime 日期时间
- * @param {String} format 格式,默认 'YYYY-MM-DD HH:mm:ss'
- * @returns {String} 格式化后的字符串
- */
- export const formatDateTime = (dateTime, format = 'YYYY-MM-DD HH:mm:ss') => {
- if (!dateTime) return ''
-
- const date = parseDate(dateTime)
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- const hour = String(date.getHours()).padStart(2, '0')
- const minute = String(date.getMinutes()).padStart(2, '0')
- const second = String(date.getSeconds()).padStart(2, '0')
-
- return format
- .replace('YYYY', year)
- .replace('MM', month)
- .replace('DD', day)
- .replace('HH', hour)
- .replace('mm', minute)
- .replace('ss', second)
- }
- /**
- * 格式化时间(月日 时:分)
- * @param {String|Date} dateTime 日期时间
- * @returns {String} 格式化后的字符串,如 "10月18日 14:00"
- */
- export const formatTime = (dateTime) => {
- if (!dateTime) return ''
-
- const date = parseDate(dateTime)
- const month = date.getMonth() + 1
- const day = date.getDate()
- const hour = date.getHours()
- const minute = date.getMinutes()
-
- return `${month}月${day}日 ${hour}:${minute < 10 ? '0' + minute : minute}`
- }
- /**
- * 计算倒计时
- * @param {String|Date} endTime 结束时间
- * @returns {Object} { days, hours, minutes, seconds, isExpired }
- */
- export const calculateCountdown = (endTime) => {
- if (!endTime) return { isExpired: true }
-
- const end = parseDate(endTime).getTime()
- const now = new Date().getTime()
- const diff = end - now
-
- if (diff <= 0) {
- return { days: 0, hours: 0, minutes: 0, seconds: 0, isExpired: true }
- }
-
- const days = Math.floor(diff / (1000 * 60 * 60 * 24))
- const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
- const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
- const seconds = Math.floor((diff % (1000 * 60)) / 1000)
-
- return { days, hours, minutes, seconds, isExpired: false }
- }
- /**
- * 格式化倒计时文本
- * @param {String|Date} endTime 结束时间
- * @returns {String} 倒计时文本,如 "2天5小时"、"5小时30分钟"、"30分钟"
- */
- export const formatCountdown = (endTime) => {
- const { days, hours, minutes, isExpired } = calculateCountdown(endTime)
-
- if (isExpired) return '已截止'
-
- if (days > 0) {
- return `${days}天${hours}小时`
- } else if (hours > 0) {
- return `${hours}小时${minutes}分钟`
- } else {
- return `${minutes}分钟`
- }
- }
- /**
- * 格式化价格
- * @param {Number} price 价格
- * @returns {String} 格式化后的价格,如 "99.00"
- */
- export const formatPrice = (price) => {
- if (price === null || price === undefined) return '0.00'
- return Number(price).toFixed(2)
- }
- /**
- * 脱敏手机号
- * @param {String} phone 手机号
- * @returns {String} 脱敏后的手机号,如 "138****8888"
- */
- export const maskPhone = (phone) => {
- if (!phone) return ''
- return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
- }
- /**
- * 脱敏姓名
- * @param {String} name 姓名
- * @returns {String} 脱敏后的姓名,如 "张*"、"欧阳**"
- */
- export const maskName = (name) => {
- if (!name) return ''
- if (name.length === 2) {
- return name[0] + '*'
- } else if (name.length > 2) {
- return name[0] + '*'.repeat(name.length - 1)
- }
- return name
- }
- /**
- * 节流函数
- * @param {Function} func 要执行的函数
- * @param {Number} delay 延迟时间(毫秒)
- * @returns {Function} 节流后的函数
- */
- export const throttle = (func, delay = 500) => {
- let timer = null
- return function(...args) {
- if (!timer) {
- timer = setTimeout(() => {
- func.apply(this, args)
- timer = null
- }, delay)
- }
- }
- }
- /**
- * 防抖函数
- * @param {Function} func 要执行的函数
- * @param {Number} delay 延迟时间(毫秒)
- * @returns {Function} 防抖后的函数
- */
- export const debounce = (func, delay = 500) => {
- let timer = null
- return function(...args) {
- if (timer) clearTimeout(timer)
- timer = setTimeout(() => {
- func.apply(this, args)
- }, delay)
- }
- }
- /**
- * 判断是否登录
- * @returns {Boolean} 是否已登录
- */
- export const isLoggedIn = () => {
- const token = uni.getStorageSync('token')
- const userInfo = uni.getStorageSync('userInfo')
- return !!(token && userInfo)
- }
- /**
- * 跳转登录页
- * @param {String} redirectUrl 登录后要跳转的页面
- */
- export const goToLogin = (redirectUrl = '') => {
- let url = '/pages/page3/page3'
- if (redirectUrl) {
- url += `?redirect=${encodeURIComponent(redirectUrl)}`
- }
- uni.navigateTo({ url })
- }
- /**
- * 检查登录状态(未登录则跳转登录页)
- * @param {String} redirectUrl 登录后要跳转的页面
- * @returns {Boolean} 是否已登录
- */
- export const checkLogin = (redirectUrl = '') => {
- if (!isLoggedIn()) {
- goToLogin(redirectUrl)
- return false
- }
- return true
- }
- /**
- * 获取年龄
- * @param {String} birthday 生日,格式 'YYYY-MM-DD'
- * @returns {Number} 年龄
- */
- export const getAge = (birthday) => {
- if (!birthday) return 0
- const birthDate = parseDate(birthday)
- const today = new Date()
- let age = today.getFullYear() - birthDate.getFullYear()
- const monthDiff = today.getMonth() - birthDate.getMonth()
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
- age--
- }
- return age
- }
- /**
- * 获取星座
- * @param {String} birthday 生日,格式 'YYYY-MM-DD'
- * @returns {String} 星座名称
- */
- export const getConstellation = (birthday) => {
- if (!birthday) return ''
- const date = parseDate(birthday)
- const month = date.getMonth() + 1
- const day = date.getDate()
-
- const constellations = [
- { name: '摩羯座', start: [12, 22], end: [1, 19] },
- { name: '水瓶座', start: [1, 20], end: [2, 18] },
- { name: '双鱼座', start: [2, 19], end: [3, 20] },
- { name: '白羊座', start: [3, 21], end: [4, 19] },
- { name: '金牛座', start: [4, 20], end: [5, 20] },
- { name: '双子座', start: [5, 21], end: [6, 21] },
- { name: '巨蟹座', start: [6, 22], end: [7, 22] },
- { name: '狮子座', start: [7, 23], end: [8, 22] },
- { name: '处女座', start: [8, 23], end: [9, 22] },
- { name: '天秤座', start: [9, 23], end: [10, 23] },
- { name: '天蝎座', start: [10, 24], end: [11, 22] },
- { name: '射手座', start: [11, 23], end: [12, 21] }
- ]
-
- for (const constellation of constellations) {
- const [startMonth, startDay] = constellation.start
- const [endMonth, endDay] = constellation.end
-
- if (startMonth === endMonth) {
- if (month === startMonth && day >= startDay && day <= endDay) {
- return constellation.name
- }
- } else {
- if ((month === startMonth && day >= startDay) || (month === endMonth && day <= endDay)) {
- return constellation.name
- }
- }
- }
-
- return ''
- }
- /**
- * 图片预览
- * @param {String|Array} urls 图片地址(单张或数组)
- * @param {Number} current 当前显示图片的索引,默认为0
- */
- export const previewImage = (urls, current = 0) => {
- const imageUrls = Array.isArray(urls) ? urls : [urls]
- uni.previewImage({
- urls: imageUrls,
- current: current
- })
- }
- /**
- * 分享功能
- * @param {Object} options 分享选项 { title, path, imageUrl }
- */
- export const share = (options = {}) => {
- return {
- title: options.title || '遇见对的人,从这里开始',
- path: options.path || '/pages/index/index',
- imageUrl: options.imageUrl || '/static/share-default.jpg'
- }
- }
- /**
- * 复制到剪贴板
- * @param {String} text 要复制的文本
- * @param {String} successMsg 成功提示文本
- */
- export const copyToClipboard = (text, successMsg = '复制成功') => {
- uni.setClipboardData({
- data: text,
- success: () => {
- uni.showToast({
- title: successMsg,
- icon: 'success'
- })
- }
- })
- }
- /**
- * 拨打电话
- * @param {String} phoneNumber 电话号码
- */
- export const makePhoneCall = (phoneNumber) => {
- uni.makePhoneCall({
- phoneNumber: phoneNumber
- })
- }
- export default {
- formatDateTime,
- formatTime,
- calculateCountdown,
- formatCountdown,
- formatPrice,
- maskPhone,
- maskName,
- throttle,
- debounce,
- isLoggedIn,
- goToLogin,
- checkLogin,
- getAge,
- getConstellation,
- previewImage,
- share,
- copyToClipboard,
- makePhoneCall
- }
- /**
- * 统一的跨端日期解析(兼容 iOS)
- * - 将 'YYYY-MM-DD HH:mm:ss' 或 'YYYY-MM-DD' 转为 'YYYY/MM/DD HH:mm:ss'
- * - 直接返回 Date 时不处理
- */
- export function parseDate(dateTime) {
- if (!dateTime) return new Date(NaN)
- if (dateTime instanceof Date) return dateTime
- let s = String(dateTime).trim()
- // 若是纯数字时间戳
- if (/^\d{10,13}$/.test(s)) {
- const ts = s.length === 10 ? Number(s) * 1000 : Number(s)
- return new Date(ts)
- }
- // iOS 兼容:横杠替换为斜杠
- s = s.replace(/-/g, '/').replace('T', ' ').replace(/\.\d{3}Z?$/, '')
- return new Date(s)
- }
|