import { getUrlType } from './meta'; // 加载第三方库 export const loadLib = (() => { const cache: Record> = {}; const load = ( lib: string, success: () => void, err: () => void, maxReq = 0 ) => { const el = document.createElement("script"); el.src = lib; document.body.appendChild(el); el.onload = success; el.onerror = () => { if (maxReq > 0) { load(lib, success, err, --maxReq); } else { err(); } }; }; return (lib: string) => { if (!cache[lib]) { cache[lib] = new Promise((resolve, reject) => { load(lib, resolve, reject, 3); }); } return cache[lib]; }; })(); export const getSizeStr = (size: number) => { let mb = size; if (mb < 1024) { return `${mb.toFixed(2)}BYTE`; } mb /= 1024; if (mb < 1024) { return `${mb.toFixed(2)}KB`; } mb /= 1024; if (mb < 1024) { return `${mb.toFixed(2)}MB`; } mb /= 1024; if (mb < 1024) { return `${mb.toFixed(2)}GB`; } mb /= 1024; return `${mb.toFixed(2)}TB`; }; // 日期格式化 export const formatDate = (date: Date, fmt: string = 'yyyy-MM-dd hh:mm') => { const map = { 'M+': date.getMonth() + 1, //月份 'd+': date.getDate(), //日 'h+': date.getHours(), //小时 'm+': date.getMinutes(), //分 's+': date.getSeconds(), //秒 'q+': Math.floor((date.getMonth() + 3) / 3), //季度 S: date.getMilliseconds() //毫秒 } if (/(y+)/.test(fmt)) { fmt = fmt.replace( RegExp.$1, date .getFullYear() .toString() .substr(4 - RegExp.$1.length) ) } ;(Object.keys(map) as Array).forEach(k => { if (new RegExp('(' + k + ')').test(fmt)) { const val = map[k].toString() fmt = fmt.replace( RegExp.$1, RegExp.$1.length === 1 ? val : ('00' + val).substr(val.length) ) } }) return fmt } export const togetherCallback = (cbs: (() => void)[]) => () => together(cbs) export const together = (cbs: (() => void)[]) => { cbs.forEach(cb => cb()) } export const getFileUrl = (file: LocalFile | string) => typeof file === 'string' ? file : file.url export const getFileName = (file: any): string => { return typeof file === 'string' ? file.substring(file.lastIndexOf('/') + 1) : file.blob instanceof File ? file.blob.name : getUrlType(file.url) } export const asyncTimeout = (mis: number = 0) => new Promise(resolve => setTimeout(resolve, mis)) export const jsonToForm = (data: { [key in string]: any }) => { const formData = new FormData() for (const [key, val] of Object.entries(data)) { if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { formData.append(`${key}`, val[i]) } } else { formData.append(key, val) } } return formData } // 防抖 export const debounce = any>( fn: T, delay: number = 160 ) => { let timeout: any; return function (...args: Parameters) { clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(null, args); }, delay); }; }; // 防抖 export const debounceStack = any>( fn: T, success: (data: ReturnType extends Promise ? P : ReturnType) => void, delay: number = 160 ) => { let dsToken = 0 return debounce(async (...args: Parameters) => { ++dsToken const currentToken = dsToken const result = await fn.apply(null, args); if (currentToken === dsToken) { success(result) } }, delay) }; // 四舍五入保留指定位数 export const round = (num: number, index: number = 2) => { const s = Math.pow(10, index) return Math.round(num * s) / s } export * from './store-help' export * from "./stack"; export * from "./loading"; export * from "./route"; export * from "./asyncBus"; export * from './mount' export * from './watch' export * from './diff' export * from './params' export * from './file-serve' export * from './video-cover' export * from './meta' function randomWord(randomFlag: boolean, min: number, max?: number) { let str = ""; let range = min; const arr = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", ]; // 随机产生 if (randomFlag && max) { range = Math.round(Math.random() * (max - min)) + min; } for (let i = 0; i < range; i++) { const pos = Math.round(Math.random() * (arr.length - 1)); str += arr[pos]; } return str; } import { Base64 } from "js-base64"; /** * 密码加密 * @param {String} pwd */ export function encodePwd(str: string, strv: string): string[]; export function encodePwd(str: string): string; export function encodePwd(str: string, strv = "") { str = Base64.encode(str); const NUM = 2; const front = randomWord(false, 8); const middle = randomWord(false, 8); const end = randomWord(false, 8); const str1 = str.substring(0, NUM); const str2 = str.substring(NUM); if (strv) { const strv1 = strv.substring(0, NUM); const strv2 = strv.substring(NUM); return [ front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end, ]; } return front + str2 + middle + str1 + end; } /** * 判断是否为 Firefox 且版本小于 targetVersion(如 "115.9") * @param {string} targetVersion - 目标版本字符串,例如 "115.9" * @returns {boolean} */ export function isFirefoxBelow(targetVersion = "115.9") { // 尝试使用 navigator.userAgentData (更现代) 如果可用且包含 brands // 注意:userAgentData.brand/version 可能随浏览器策略返回受限信息 const navigator = window.navigator as any if (navigator.userAgentData && Array.isArray(navigator.userAgentData.brands)) { // brands 形如 [{brand: "Chromium", version: "116"}, ...] 或可能被 UA 凭空 for (const b of navigator.userAgentData.brands) { if (typeof b.brand === "string" && /firefox/i.test(b.brand)) { const ver = b.version || ""; return compareVersionStrings(ver, targetVersion) < 0; } } } // 回退到 userAgent 字符串 const ua = navigator.userAgent || ""; // Firefox 的 UA 通常包含 "Firefox/" const m = ua.match(/Firefox\/([0-9]+(?:\.[0-9]+)*)/i); if (m && m[1]) { const ver = m[1]; return compareVersionStrings(ver, targetVersion) < 0; } // 不是 Firefox 或版本未知 return false; } /** * 比较两个版本字符串(如 "115.9.1" 与 "115.9") * 返回: * -1 如果 v1 < v2 * 0 如果 v1 == v2 * 1 如果 v1 > v2 */ function compareVersionStrings(v1: string, v2: string) { const seg1 = String(v1).split('.').map(s => parseInt(s, 10) || 0); const seg2 = String(v2).split('.').map(s => parseInt(s, 10) || 0); const len = Math.max(seg1.length, seg2.length); for (let i = 0; i < len; i++) { const a = seg1[i] || 0; const b = seg2[i] || 0; if (a < b) return -1; if (a > b) return 1; } return 0; }