文件
fenleixinxi/uniapp/common/utils/format.js

102 行
3.0 KiB
JavaScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

/**
* 格式化工具集
*/
import config from '../config/index.js'
/** 金额分转元 */
export function fen2yuan(fen) {
return (Number(fen || 0) / 100).toFixed(2)
}
/** 金额元转分 */
export function yuan2fen(yuan) {
return Math.round(Number(yuan || 0) * 100)
}
/** 统一解析时间入参,避免 ISO / '-' / '/' 混用导致 Invalid Date */
function toDate(input) {
if (input instanceof Date) return input
const s = String(input)
let d = new Date(s)
if (isNaN(d.getTime())) d = new Date(s.replace(/-/g, '/'))
return d
}
/** 时间戳/日期串 -> YYYY-MM-DD HH:mm */
export function formatTime(input) {
if (!input) return ''
const d = toDate(input)
if (isNaN(d.getTime())) return String(input)
const p = (n) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
}
/** 相对时间:刚刚 / N分钟前 / N小时前 / N天前 */
export function fromNow(input) {
if (!input) return ''
const d = toDate(input)
if (isNaN(d.getTime())) return String(input)
const diff = Math.floor((Date.now() - d.getTime()) / 1000)
if (diff < 60) return '刚刚'
if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`
if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`
if (diff < 86400 * 30) return `${Math.floor(diff / 86400)}天前`
return formatTime(input)
}
/** 手机号脱敏 */
export function maskPhone(phone) {
const s = String(phone || '')
return s.length === 11 ? s.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : s
}
/** 距离格式化(米) */
export function formatDistance(meters) {
const m = Number(meters || 0)
if (m < 1000) return `${Math.round(m)}m`
return `${(m / 1000).toFixed(1)}km`
}
/**
* 距离格式化(千米,一位小数)
* 契约 §2.1:feed / 详情下发的 distance 单位为 km(一位小数),无坐标时为 null。
*/
export function formatKm(km) {
if (km === null || km === undefined || km === '') return ''
const n = Number(km)
if (isNaN(n)) return ''
return `${n.toFixed(1)}km`
}
/**
* 资源地址:后端统一返回**相对路径**(/uploads/YYYYMMDD/xxx.jpg,与用户头像口径一致),
* 小程序 `<image src="/uploads/...">` 会被当成包内路径而裂图,因此展示前必须拼上后端域名。
* 已是 http(s)/data/blob 的地址原样返回。
* @param {string} url
* @returns {string}
*/
export function assetUrl(url) {
const s = String(url == null ? '' : url)
if (!s) return ''
if (/^(https?:)?\/\//i.test(s) || /^(data|blob):/i.test(s)) return s
// config.baseURL 形如 https://host/api,这里只取域名部分(uploads 挂在站点根目录)
const origin = String(config.baseURL || '').replace(/^(https?:\/\/[^/]+).*$/i, '$1')
return origin + (s.charAt(0) === '/' ? s : '/' + s)
}
export const formatRelativeTime = fromNow
export default {
formatRelativeTime,
fen2yuan,
yuan2fen,
formatTime,
fromNow,
maskPhone,
formatDistance,
formatKm,
assetUrl,
}