/* * @Author: fxs bjnsfxs@163.com * @Date: 2024-08-26 15:46:42 * @LastEditors: fxs bjnsfxs@163.com * @LastEditTime: 2024-11-27 * @Description: * */ import { ElMessage } from 'element-plus' /** * 包装防抖函数 * * @param {array} func 函数 * @param {number} delay 时间 */ export function debounceFunc any>( func: T, delay: number ): (...args: Parameters) => void { let timer: ReturnType | null return (...args: Parameters) => { if (timer) clearTimeout(timer) timer = setTimeout(() => { func(...args) }, delay) } } /** * 节流函数 * * @param func 函数 * @param delay 延迟 */ export function throttleFunc any>( func: T, delay: number ): (...args: Parameters) => void { let lastCall = 0 return function (...args: Parameters) { const now = Date.now() if (now - lastCall >= delay) { lastCall = now func(...args) } } } /** * 将小数转换为百分比字符串 * * @param decimal 小数 * @param decimalPlaces 保留几位小数 */ export function decimalToPercentage(decimal: number, decimalPlaces: number = 0): string { // Convert the decimal to a percentage by multiplying by 100 const percentage = decimal * 100 // Format the percentage to a fixed number of decimal places const formattedPercentage = percentage.toFixed(decimalPlaces) // Append the '%' symbol and return the result return `${formattedPercentage}%` } /** * 格式化时间,如20240816=>2024-8-16 * * @param dateString */ export function formatDate(dateString: string) { // 从字符串中提取年份、月份和日期 const year = dateString.slice(0, 4) const month = dateString.slice(4, 6) const day = dateString.slice(6, 8) // 将月份和日期转换为整数以去除前导零 const formattedMonth = parseInt(month, 10) const formattedDay = parseInt(day, 10) if (year === '' || isNaN(formattedMonth) || isNaN(formattedDay)) { return '无' } // 生成新的日期字符串 return `${year}-${formattedMonth}-${formattedDay}` } /** * 将时间转为year-month-day的格式 * * @param dateTime Date对象 */ export function resetTimeToMidnight(dateTime: Date): string { // 创建一个 Date 对象来解析输入的日期时间字符串 // 将时间部分设置为 00:00:00 dateTime.setHours(0, 0, 0, 0) // 格式化日期为 'YYYY-MM-DD' 格式 const year = dateTime.getFullYear() const month = String(dateTime.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要加1 const day = String(dateTime.getDate()).padStart(2, '0') // 返回格式化的字符串 return `${year}-${month}-${day}` } /** * 创建一个日期范围 * * @param {*} day 天数 */ export const createDateRange = (day: number): [Date, Date] => { const end = new Date() const start = new Date() start.setTime(start.getTime() - 3600 * 1000 * 24 * day) return [start, end] } /** * 将时间戳转为日期字符串yyyy-MM-dd HH:mm:ss * * 根据isMilliseconds参数判断是否为毫秒,默认为秒级时间戳 * * @param timestamp 时间戳 * @param isMilliseconds 是否为毫秒级时间戳 */ export const formatTimestamp = (timestamp: number, isMilliseconds: boolean = false): string => { if (timestamp === 0) return '无' // 将秒级时间戳转换为毫秒级时间戳 const adjustedTimestamp = isMilliseconds ? timestamp : timestamp * 1000 const date = new Date(adjustedTimestamp) // 格式化为 yyyy-MM-dd HH:mm:ss const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从 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') return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` } /** * 获取时间戳范围,时间戳从0:00开始,到23:59结束 * @param dateRange 日期范围 */ export function getRangeTimestamps(dateRange: Date[]): [number, number] { const [startDate, endDate] = dateRange // 确保日期有效 if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { throw new Error('Invalid date') } // 设置开始日期为当天 UTC 00:00:00 const rangeStart = new Date(startDate) rangeStart.setHours(0, 0, 0, 0) // 设置结束日期为当天 UTC 23:59:59.999 const rangeEnd = new Date(endDate) rangeEnd.setHours(23, 59, 59, 999) // 返回时间戳 return [rangeStart.getTime(), rangeEnd.getTime()] } /** * 复制文字到剪贴板 * * @param {string} text */ export const copyText = (text: string) => { return new Promise((resolve, reject) => { navigator.clipboard .writeText(text) .then(() => { ElMessage({ type: 'success', message: '复制成功' }) resolve(true) }) .catch((err) => { ElMessage({ type: 'error', message: '复制失败' }) reject(err) throw new Error(err) }) }) } /** * 用于保存watch切换之前的数据 * * @param {any} data 需要保存的数据 * @param {any} store 需要保存到的对象 */ export const saveWatchData = (data: any, store: any) => { if (Array.isArray(data)) { // 这里需要深拷贝,否则会导致引用问题 store.splice(0, store.length, ...JSON.parse(JSON.stringify(data))) } else { Object.assign(store, JSON.parse(JSON.stringify(data))) } } /** * 用于比较watch切换之前的数据 * * @param {any} data 需要比较的数据 * @param {any} store 需要比较到的对象 */ export const compareWatchData = (data: any, store: any): boolean => { return JSON.stringify(data) === JSON.stringify(store) } /** * 模糊查询 * @param {string} pattern 需要匹配的模式,即正则表达式 * @param {string} text 需要被搜索的目标字符串 * @param {boolean} matchCase 是否区分大小写,默认为true,即不区分大小写 */ export const fuzzySearch = (pattern: string, text: string, matchCase: boolean = true): boolean => { const regex = new RegExp(pattern, matchCase ? 'i' : '') // 'i' 标志表示忽略大小写 return regex.test(text) } /** * 生成一个随机文件名,以当前时间为种子,生成16位随机字符串 */ export const generateRandomFileName = () => { const timestamp = Date.now().toString(36) // 将时间戳转换为36进制字符串 const randomString = Math.random().toString(36).substring(2, 8) // 生成8位随机字符串 return timestamp + randomString } /** * 生成随机颜色 * @param count 生成颜色的数量 */ export function generateUniqueColors(count: number) { const colors = [] // 基础参数:控制颜色柔和度 const baseSaturation = 90 // 饱和度范围 65-75%(避免过艳) const baseLightness = 70 // 亮度范围 65-75%(避免过深或过亮) for (let i = 0; i < count; i++) { // 1. 色相均匀分布(核心区分度) const hue = ((i * 360) / count) % 360 // 2. 饱和度和亮度微调(增加次区分度) const saturation = baseSaturation + ((i % 3) - 1) * 5 // 波动 ±5% const lightness = baseLightness + ((i % 2) - 0.5) * 10 // 奇数项稍暗,偶数项稍亮 // 3. 约束范围(确保不过深/过亮) const clampedSaturation = Math.min(75, Math.max(65, saturation)) const clampedLightness = Math.min(75, Math.max(65, lightness)) colors.push(`hsl(${hue}, ${clampedSaturation}%, ${clampedLightness}%)`) } return colors } export const getFileIconBySuffix = (filename: string, fileType: 'folder' | 'file'): string => { const iconBasePath = '/img/fileIcon/' if (fileType === 'folder') return iconBasePath + 'folder.png' const suffix = filename.split('.').pop()?.toLowerCase() || '' switch (suffix) { case 'json': return iconBasePath + 'json-file.png' case 'png': case 'jpg': case 'jpeg': case 'gif': return iconBasePath + 'img-file.png' case 'txt': return iconBasePath + 'txt-file.png' case 'mp3': case 'wav': return iconBasePath + 'mp3-file.png' default: return iconBasePath + 'unknow-file.png' } } // 快速选择日期 export const shortcutsDate = [ { text: '上一周', value: () => createDateRange(7) }, { text: '上个月', value: () => createDateRange(30) }, { text: '近三个月', value: () => createDateRange(90) } ]