import { $t } from '@/locales'; /** * Transform record to option * * @example * ```ts * const record = { * key1: 'label1', * key2: 'label2' * }; * const options = transformRecordToOption(record); * // [ * // { value: 'key1', label: 'label1' }, * // { value: 'key2', label: 'label2' } * // ] * ```; * * @param record */ export function transformRecordToOption>(record: T) { return Object.entries(record).map(([value, label]) => ({ value, label })) as CommonType.Option[]; } /** * Translate options * * @param options */ export function translateOptions(options: CommonType.Option[]) { return options.map(option => ({ ...option, label: $t(option.label) })); } /** * Toggle html class * * @param className */ export function toggleHtmlClass(className: string) { function add() { document.documentElement.classList.add(className); } function remove() { document.documentElement.classList.remove(className); } return { add, remove }; } // 辅助函数:将 hex 转为 rgba export function hexToRgba(hex: string, alpha: number) { // 去掉 # 号 hex = hex.replace('#', ''); // 处理缩写形式 #RGB if (hex.length === 3) { hex = hex.split('').map(c => c + c).join(''); } const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } export const getColorWithOpacity = (color: string, opacity: number) => { // 如果 color 本身已经是 rgba 或 hsl 等,可自行扩展判断 // 这里仅处理 hex return hexToRgba(color, opacity); }; // 时间戳转换成年月日时分秒 export function formatTimestamp(timestamp: number | string | Date | null,format: string = 'yyyy-MM-dd HH:mm:ss') { if(!timestamp) { return ''; } const date = new Date(Number(timestamp)); 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'); if(format === 'yyyy-MM-dd') { return `${year}-${month}-${day}`; } if(format === 'yyyy-MM-dd HH:mm') { return `${year}-${month}-${day} ${hours}:${minutes}`; } return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } /** * 任意时间格式 → 时间戳(支持 只有小时) * @param {string|number|Date} input * @param {'ms'|'s'} unit 默认毫秒 */ export function anyToTimestamp(input: string | number | Date | null | undefined, unit = 'ms') { if (input == null || input === '') return null; const toResult = (ms: number) => Number.isNaN(ms) ? null : unit === 's' ? Math.floor(ms / 1000) : ms; // 1. 数字 if (typeof input === 'number') return toResult(input); // 2. Date if (input instanceof Date) return toResult(input.getTime()); let str = String(input).trim(); // 3. 纯数字字符串 if (/^\d+$/.test(str)) return toResult(Number(str)); // 4. 统一分隔符 str = str .replace(/[年月]/g, '-') .replace(/[日号]/g, '') .replace(/[时分]/g, ':') .replace(/秒/g, '') .replace(/[./]/g, '-') .replace(/\s+/g, ' ') .trim(); // 5. 手动解析:小时、分钟、秒、毫秒全部可选 const m = str.match( /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}))?(?::(\d{1,2}))?(?::(\d{1,2}))?(?:\.(\d{1,3}))?/ ); if (m) { const [, y, mo, d, h = '0', mi = '0', s = '0', ms = '0'] = m; const t = new Date( +y, +mo - 1, +d, +h, +mi, +s, +ms.padEnd(3, '0') ).getTime(); if (!Number.isNaN(t)) return toResult(t); } // 6. 兜底 let t = new Date(str.replace(' ', 'T')).getTime(); if (!Number.isNaN(t)) return toResult(t); t = Date.parse(str); if (!Number.isNaN(t)) return toResult(t); return null; }; // 辅助函数:Fisher-Yates 洗牌算法 function shuffle(arr:any) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } // 辅助函数:从字符串中随机获取字符 function getRandomChar(str:any) { return str[Math.floor(Math.random() * str.length)]; } // 生成至少12位,包含四类字符中的至少三种的随机密码 export function generateSecurePassword(passwordLength:number) { // 定义字符池 const charSets:any = { uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', lowercase: 'abcdefghijklmnopqrstuvwxyz', numbers: '0123456789', symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?' }; // 随机选择三种字符类型(保证至少三类) const requiredTypes = shuffle(Object.keys(charSets)).slice(0, 3); // 生成必选字符(每类至少1个) let password = requiredTypes .map((type:any) => getRandomChar(charSets[type])) .join(''); // 生成剩余字符(允许包含所有四类) const remainingLength = passwordLength - password.length; const allChars = Object.values(charSets).join(''); for (let i = 0; i < remainingLength; i++) { password += getRandomChar(allChars); } // 打乱字符顺序 return shuffle(password.split('')).join(''); } // 根据当前时间,获取指定的时间范围(返回时间戳) export function getTimeRangeStamp(timeRange: string){ const endTime = anyToTimestamp(new Date()); if(!endTime) { return null; } // 近7天 if(timeRange === 'week'){ return { from: endTime - (7 * 24 * 60 * 60 * 1000), to: endTime } } // 近一个月 if(timeRange === 'month'){ return { from: endTime - (30 * 24 * 60 * 60 * 1000), to: endTime } } // 近三个月 if(timeRange === 'quarter'){ return { from: endTime - (90 * 24 * 60 * 60 * 1000), to: endTime } } // 近半年 if(timeRange === 'half_year'){ return { from: endTime - (180 * 24 * 60 * 60 * 1000), to: endTime } } // 近一年 if(timeRange === 'year'){ return { from: endTime - (365 * 24 * 60 * 60 * 1000), to: endTime } } } // 下载文件 export function downloadFileFun(url: string, name: string) { const a = document.createElement('a'); a.href = url; a.download = name; a.style.display = 'none'; document.body.appendChild(a) a.click() document.body.removeChild(a); } // 获取 token export const getToken = () => { return localStorage.getItem('token'); }; // tag自定义样式颜色 // 文字颜色 export const tagTextColor = (color: string) => { return color || '#333'; } // 背景颜色 export const tagBgColor = (color: string) => { return getColorWithOpacity((color || '#333'), 0.08); } // 边框颜色 export const tagBorderColor = (color: string) => { return getColorWithOpacity((color || '#333'), 0.3); }