/** 格式化日期为 YYYY-MM-DD */ export function formatDate(date?: string | Date): string { const d = date ? new Date(date) : new Date() return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` } /** 格式化日期为 YYYY-MM */ export function formatMonth(date?: string | Date): string { const d = date ? new Date(date) : new Date() return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}` } /** 获取相对时间描述 */ export function timeAgo(dateStr: string): string { if (!dateStr) return '' const diff = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000) if (diff < 60) return '刚刚' if (diff < 3600) return `${Math.floor(diff / 60)}分钟前` if (diff < 86400) return `${Math.floor(diff / 3600)}小时前` if (diff < 2592000) return `${Math.floor(diff / 86400)}天前` return formatDate(dateStr) } /** 打卡分类 */ export const CHECKIN_CATEGORY = { study: { label: '学习成长', icon: '📚', color: '#4CC9F0' }, health: { label: '健康生活', icon: '❤️', color: '#06D6A0' }, habit: { label: '习惯自律', icon: '🔄', color: '#7209B7' }, hobby: { label: '兴趣爱好', icon: '⭐', color: '#F72585' }, goal: { label: '目标任务', icon: '🎯', color: '#FF6B35' }, } as const export type CheckinCategory = keyof typeof CHECKIN_CATEGORY export function getCategoryLabel(cat: string): string { return CHECKIN_CATEGORY[cat as CheckinCategory]?.label || cat } /** 打卡周期 */ export const CYCLE_LABEL: Record = { daily: '每日', weekly: '每周', every_other_day: '隔日', custom: '自定义', } export function getCycleLabel(cycle: string): string { return CYCLE_LABEL[cycle] || cycle } /** 隐私级别 */ export function getPrivacyLabel(level: number): string { const map: Record = { 1: '公开', 2: '仅好友可见', 3: '仅自己可见' } return map[level] || '未知' } /** 积分格式化(带 + 号) */ export function formatPoints(p: number | undefined | null): string { if (p === undefined || p === null) return '--' return p > 0 ? `+${p}` : String(p) } /** 截断字符串 */ export function truncate(str: string, len = 20): string { return str.length > len ? str.slice(0, len) + '...' : str } /** ID 缩写 */ export function shortId(id: string): string { return id.length > 8 ? id.slice(0, 8) + '...' : id }