Files
oa_app/utils/format.js
T
2026-09-24 16:07:02 +08:00

182 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export function asList(raw) {
if (Array.isArray(raw)) return raw.filter((x) => x && typeof x === 'object')
if (raw && typeof raw === 'object') {
const nested = raw.records || raw.list || raw.items || raw.messages || raw.projects || raw.data
if (Array.isArray(nested)) return nested.filter((x) => x && typeof x === 'object')
return [raw]
}
return []
}
export function firstText(row, keys, fallback = '') {
for (const k of keys) {
const v = row && row[k]
if (v != null && String(v).trim() && String(v) !== 'null') return String(v).trim()
}
return fallback
}
export function initial(name) {
const s = String(name || '').trim()
return s ? s.slice(0, 1) : '?'
}
export function maskPhone(phone) {
const s = String(phone || '')
if (s.length < 7) return s
return s.slice(0, 3) + '****' + s.slice(-4)
}
function asDate(t) {
if (t == null || t === '') return null
let d
const n = Number(t)
if (!Number.isNaN(n) && String(t).length >= 10) {
d = new Date(n < 1e12 ? n * 1000 : n)
} else {
d = new Date(t)
}
if (Number.isNaN(d.getTime())) return null
return d
}
function dayStart(d) {
return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
}
function period(d) {
const h = d.getHours()
if (h < 6) return '凌晨'
if (h < 12) return '上午'
if (h < 13) return '中午'
if (h < 18) return '下午'
return '晚上'
}
function hm12(d) {
const h = d.getHours() % 12 || 12
const m = String(d.getMinutes()).padStart(2, '0')
return `${h}:${m}`
}
export function fmtTime(t) {
const d = asDate(t)
if (!d) return t == null ? '' : String(t)
const label = period(d) + hm12(d)
const now = new Date()
const diff = (dayStart(now) - dayStart(d)) / 86400000
if (diff === 0) return label
if (diff === 1) return '昨天 ' + label
if (diff < 7) {
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
return week[d.getDay()] + ' ' + label
}
return `${d.getMonth() + 1}月${d.getDate()}日 ${label}`
}
export function fmtListTime(t) {
const d = asDate(t)
if (!d) return t == null ? '' : String(t)
const now = new Date()
const diff = (dayStart(now) - dayStart(d)) / 86400000
if (diff === 0) return period(d) + hm12(d)
if (diff === 1) return '昨天'
if (diff < 7) {
const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
return week[d.getDay()]
}
return `${d.getMonth() + 1}月${d.getDate()}日`
}
export function pad2(n) {
return String(n).padStart(2, '0')
}
/** 弹性:9:00–9:30 上班,18:00–18:30 下班。早于 9:00、晚于 18:30 的分钟计入调休。 */
export function flexCreditMinutes(inTime, outTime) {
const inn = hmMinutes(inTime)
const out = hmMinutes(outTime)
let extra = 0
if (inn != null && inn < 9 * 60) extra += 9 * 60 - inn
if (out != null && out > 18 * 60 + 30) extra += out - (18 * 60 + 30)
return extra
}
export function flexCreditText(minutes) {
const n = Math.max(0, Math.round(Number(minutes) || 0))
if (!n) return '0 分钟'
const h = Math.floor(n / 60)
const m = n % 60
if (h && m) return h + ' 小时 ' + m + ' 分钟'
if (h) return h + ' 小时'
return m + ' 分钟'
}
function hmMinutes(value) {
const m = String(value || '').match(/(\d{1,2}):(\d{2})/)
if (!m) return null
const h = Number(m[1])
const min = Number(m[2])
if (h > 23 || min > 59) return null
return h * 60 + min
}
export function clockText(date) {
const d = date || new Date()
return `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`
}
export function yuan(v) {
const n = Number(v)
if (Number.isNaN(n)) return ''
return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}
export function dmId(a, b) {
const pair = [String(a), String(b)].sort()
return `dm:${pair[0]}:${pair[1]}`
}
export function convType(s) {
const t = String((s && s.type) || '')
if (t === 'dm') return 'direct'
if (t === 'group' || t === 'work' || t === 'files' || t === 'direct') return t
const id = String((s && s.id) || '')
if (id.startsWith('g:')) return 'group'
if (id.startsWith('work:')) return 'work'
if (id.startsWith('files:')) return 'files'
return 'direct'
}
const FLOW_STATUS = {
pending: '待审批',
waiting: '待处理',
processing: '审批中',
reviewing: '审阅中',
review: '待审阅',
approved: '已通过',
passed: '已通过',
rejected: '已驳回',
refused: '已拒绝',
denied: '已拒绝',
cancelled: '已撤销',
canceled: '已撤销',
withdrawn: '已撤回',
draft: '草稿',
done: '已完成',
completed: '已完成',
handled: '已处理',
reviewed: '已审阅',
running: '进行中'
}
export function flowStatus(status) {
const raw = String(status || '').trim()
if (!raw) return '待处理'
return FLOW_STATUS[raw.toLowerCase()] || raw
}
export function toast(title, icon = 'none') {
uni.showToast({ title: String(title || ''), icon, duration: 2200 })
}