Files
FiDA_Front/src/utils/tools.ts
2026-02-04 10:01:50 +08:00

198 lines
5.6 KiB
TypeScript
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.
import CryptoJS from 'crypto-js'
function getUniversalZoomLevel() {
// 现代浏览器方案
if (window.visualViewport) {
return window.visualViewport.scale;
}
// 备用方案1
if (window.devicePixelRatio) {
return window.devicePixelRatio;
}
// 备用方案2不精确
return window.outerWidth / window.innerWidth;
}
const getMousePosition = (e: any, bor: any) => {
// if(e?.stopPropagation)e.stopPropagation()
// if(e?.preventDefault)e.preventDefault();
let event: any
if (bor) {
const touch = e.changedTouches[0] as any;
event = {
offsetX: touch.clientX - e.target.getBoundingClientRect().left,
offsetY: touch.clientY - e.target.getBoundingClientRect().top,
clientX: touch.clientX,
clientY: touch.clientY,
screenX: touch.screenX,
screenY: touch.screenY,
target: e.target,
}
// if(dom){
// event.offsetX = touch.clientX - dom.getBoundingClientRect().left
// event.offsetY = touch.clientY - dom.getBoundingClientRect().top
// }
} else {
event = {
offsetX: e.offsetX,
offsetY: e.offsetY,
clientX: e.clientX,
clientY: e.clientY,
screenX: e.screenX,
screenY: e.screenY,
target: e.target,
}
}
return event
}
/**
* 生成UUID v4
* @returns 返回一个标准的UUID v4字符串格式xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
*/
export function generateUUID(): string {
// 优先使用现代浏览器的crypto.randomUUID()方法
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
return crypto.randomUUID()
}
// 备用方案手动生成UUID v4
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0
const v = c === 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
export {
getUniversalZoomLevel,
getMousePosition,
}
/** 时间格式化-自定义格式
* @param value 时间对象|时间戳|时间字符串
* @param format 格式化字符串,默认值为 'yyyy-MM-dd HH:mm:ss'
* @returns 格式化后的时间字符串
*/
export function FormatDate(value: Date | number | string, format: string = 'yyyy-MM-dd HH:mm:ss') {
const date = new Date(value);
const yyyy = String(date.getFullYear());
const yy = String(date.getFullYear()).slice(-2);
const MM = String(date.getMonth() + 1).padStart(2, '0');
const M = String(date.getMonth() + 1);
const dd = String(date.getDate()).padStart(2, '0');
const d = String(date.getDate());
const HH = String(date.getHours()).padStart(2, '0');
const H = String(date.getHours());
const mm = String(date.getMinutes()).padStart(2, '0');
const m = String(date.getMinutes());
const ss = String(date.getSeconds()).padStart(2, '0');
const s = String(date.getSeconds());
const str = format.replaceAll('yyyy', yyyy)
.replaceAll('yy', yy)
.replaceAll('MM', MM)
.replaceAll('M', M)
.replaceAll('dd', dd)
.replaceAll('d', d)
.replaceAll('HH', HH)
.replaceAll('H', H)
.replaceAll('mm', mm)
.replaceAll('m', m)
.replaceAll('ss', ss)
.replaceAll('s', s);
return str;
}
/**
* 倒计时
* @param time 倒计时时间,单位秒
* @returns 倒计时字符串,格式为 mm:ss
*/
export function CountDown(time: number) {
const mm = String(Math.floor(time / 60)).padStart(2, '0');
const ss = String(time % 60).padStart(2, '0');
return `${mm}:${ss}`;
}
/**
* 下载图片
* @param list 图片列表
* @param onProgress 下载进度回调
* @param onError 下载错误回调
* @param onSuccess 下载成功回调
*/
export async function DownloadImages(list: Array<{ url: string, name?: string }>, onProgress?: (count: number, total: number, item: any) => void, onError?: (count: number, total: number, item: any) => void, onSuccess?: (successCount: number, errCount: number) => void) {
const total = list.length;
let count = 0;
let successCount = 0;
let errCount = 0;
for (let i = 0; i < list.length; i++) {
await new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", list[i].url);
xhr.responseType = "blob"
xhr.onload = function () {
count++;
if (this.status === 200) {
const blob = this.response;
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = list[i].name || list[i].url.split('/').pop().split('?').shift();
a.click();
successCount++;
typeof onProgress === "function" && onProgress(count, total, list[i]);
resolve(blob);
} else {
errCount++;
typeof onError === "function" && onError(count, total, list[i]);
resolve(true);
}
};
xhr.onerror = function () {
count++;
errCount++;
typeof onError === "function" && onError(count, total, list[i]);
resolve(true);
};
xhr.send();
})
}
typeof onSuccess === "function" && onSuccess(successCount, errCount);
}
/**
* MD5加密密码
* @param password 原始密码
* @returns MD5加密后的密码
*/
export function encryptPassword(password: string): string {
return CryptoJS.MD5(password).toString()
}
/**
* 图片分享到WhatsApp
* @param url 图片URL
* @returns 无
*/
export async function shareImageToWhatsapp (url: string){
// 把图片 URL 转为 Blob
const blob = await fetch(url).then((res) => res.blob())
// 创建文件对象
const file = new File([blob], 'image.jpg', { type: 'image/jpeg' })
// 判断浏览器是否支持文件分享
if (navigator.canShare && navigator.canShare({ files: [file] })) {
await navigator.share({
files: [file]
})
} else {
// 你可以附加一些自定义文本
const message = 'share image ' + url
// 构造WhatsApp链接
const whatsappLink = `https://api.whatsapp.com/send/?text=${encodeURIComponent(message)}`
window.open(whatsappLink, '_blank')
}
}