UNPKG

ng-cw-v12

Version:

Angular UI Component Library

871 lines 122 kB
import { isPlatformBrowser } from '@angular/common'; import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { Subject } from 'rxjs'; import { debounceTime, throttleTime } from 'rxjs/operators'; import * as i0 from "@angular/core"; export class NcCommonService { constructor(platformId, rendererFactory) { this.platformId = platformId; this.rendererFactory = rendererFactory; // ---------------------经纬度--------------------- this.x_PI = 3.14159265358979324 * 3000.0 / 180.0; this.PI = 3.1415926535897932384626; this.a = 6378245.0; this.ee = 0.00669342162296594323; // ---------------------节流、防抖--------------------- this.debounceTasks = new Map(); this.throttleTasks = new Map(); // ---------------------消息提示--------------------- this.fullLoadingElement = null; this.fullLoadingKeyframesStyle = null; // ---------------------调试--------------------- /** * 美化控制台打印(log info error warning success) */ this.console = { log: (textOrTitle, content) => { const title = !content ? 'Log' : textOrTitle; const text = !content ? textOrTitle : content; this.prettyPrint(title, text, '#909399'); }, info: (textOrTitle, content) => { const title = !content ? 'Info' : textOrTitle; const text = !content ? textOrTitle : content; this.prettyPrint(title, text, '#40a9ff'); }, error: (textOrTitle, content) => { const title = !content ? 'Error' : textOrTitle; const text = !content ? textOrTitle : content; this.prettyPrint(title, text, '#F56C6C'); }, warning: (textOrTitle, content) => { const title = !content ? 'Warning' : textOrTitle; const text = !content ? textOrTitle : content; this.prettyPrint(title, text, '#E6A23C'); }, success: (textOrTitle, content) => { const title = !content ? 'Success' : textOrTitle; const text = !content ? textOrTitle : content; this.prettyPrint(title, text, '#67C23A'); } }; // 性能计时器 this.timers = {}; this.isBrowser = isPlatformBrowser(this.platformId); this.renderer = this.rendererFactory.createRenderer(null, null); } // ---------------------数字类--------------------- /** * 精确加法 * @param value1 第一个加数 * @param value2 第二个加数 * @returns 两数之和 */ mathAdd(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 找到最大的小数位数 let maxDecimals = Math.max(aDecimals, bDecimals); // 将浮点数转换为整数 let aInt = Math.round(value1 * Math.pow(10, maxDecimals)); let bInt = Math.round(value2 * Math.pow(10, maxDecimals)); // 进行整数加法 let resultInt = aInt + bInt; // 将结果转换回浮点数 return resultInt / Math.pow(10, maxDecimals); } /** * 精确减法 * @param value1 被减数 * @param value2 减数 * @returns 两数之差 */ mathSubtract(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 找到最大的小数位数 let maxDecimals = Math.max(aDecimals, bDecimals); // 将浮点数转换为整数 let aInt = Math.round(value1 * Math.pow(10, maxDecimals)); let bInt = Math.round(value2 * Math.pow(10, maxDecimals)); // 进行整数减法 let resultInt = aInt - bInt; // 将结果转换回浮点数 return resultInt / Math.pow(10, maxDecimals); } /** * 精确乘法 * @param value1 第一个乘数 * @param value2 第二个乘数 * @returns 两数之积 */ mathMultiply(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 将浮点数转换为整数 let aInt = parseInt(aStr.replace('.', '')); let bInt = parseInt(bStr.replace('.', '')); // 进行整数乘法 let resultInt = aInt * bInt; // 计算最终的小数位数 let totalDecimals = aDecimals + bDecimals; // 将结果转换回浮点数 return resultInt / Math.pow(10, totalDecimals); } /** * 精确除法 * @param value1 被除数 * @param value2 除数 * @returns 两数之商 */ mathDivide(value1, value2) { // 将浮点数转换为字符串 let aStr = value1.toString(); let bStr = value2.toString(); // 找到小数点后的位置 let aDecimals = (aStr.split('.')[1] || '').length; let bDecimals = (bStr.split('.')[1] || '').length; // 找到最大的小数位数 let maxDecimals = Math.max(aDecimals, bDecimals); // 将浮点数转换为整数 let aInt = Math.round(value1 * Math.pow(10, maxDecimals)); let bInt = Math.round(value2 * Math.pow(10, maxDecimals)); // 进行整数除法并直接返回结果 return aInt / bInt; } /** * 保留指定小数位数 * @param num 需要处理的数值 * @param len 要保留的小数位数 * @returns 处理后的数值,保留指定小数位数 */ retainDecimal(num, len) { const n = Math.pow(10, len); return Math.round(num * n) / n; } /** * 保留指定小数位数的百分比 * @param num 需要处理的数值 * @param len 要保留的小数位数 * @returns 处理后的百分比值,保留指定小数位数 */ retainPercentDecimal(num, len) { const n = Math.pow(10, len + 2); return this.mathMultiply(Math.round(num * n) / n, 100); } // ---------------------存储--------------------- /** * 设置Cookie * @param key Cookie的键 * @param value Cookie的值 * @param ttl Cookie的生存时间(毫秒) */ setCookie(key, value, ttl) { const expires = new Date(Date.now() + ttl).toUTCString(); document.cookie = `${key}=${encodeURIComponent(value)};expires=${expires};path=/`; } /** * 获取Cookie * @param key Cookie的键 * @returns Cookie的值,如果不存在则返回null */ getCookie(key) { const match = document.cookie.match(new RegExp('(^| )' + key + '=([^;]+)')); return match ? decodeURIComponent(match[2]) : null; } /** * 删除指定的Cookie * @param key 要删除的Cookie的键 */ removeCookie(key) { document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`; } /** * 清除所有Cookie */ clearCookie() { document.cookie.split(";").forEach(c => { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/"); }); } /** * 设置LocalStorage项 * @param key LocalStorage的键 * @param value LocalStorage的值 * @param ttl 可选的生存时间(毫秒) */ setLocalStorage(key, value, ttl) { const item = { value, expiry: ttl ? Date.now() + ttl : null }; localStorage.setItem(key, JSON.stringify(item)); } /** * 获取LocalStorage项 * @param key LocalStorage的键 * @returns LocalStorage的值,如果不存在或已过期则返回null */ getLocalStorage(key) { const itemStr = localStorage.getItem(key); if (!itemStr) return null; const item = JSON.parse(itemStr); if (item.expiry && Date.now() > item.expiry) { localStorage.removeItem(key); return null; } return item.value; } /** * 删除指定的LocalStorage项 * @param key 要删除的LocalStorage项的键 */ removeLocalStorage(key) { localStorage.removeItem(key); } /** * 清除所有LocalStorage项 */ clearLocalStorage() { localStorage.clear(); } /** * 设置SessionStorage项 * @param key SessionStorage的键 * @param value SessionStorage的值 */ setSessionStorage(key, value) { sessionStorage.setItem(key, JSON.stringify(value)); } /** * 获取SessionStorage项 * @param key SessionStorage的键 * @returns SessionStorage的值,如果不存在则返回null */ getSessionStorage(key) { const item = sessionStorage.getItem(key); return item ? JSON.parse(item) : null; } /** * 删除指定的SessionStorage项 * @param key 要删除的SessionStorage项的键 */ removeSessionStorage(key) { sessionStorage.removeItem(key); } /** * 清除所有SessionStorage项 */ clearSessionStorage() { sessionStorage.clear(); } // ---------------------日期类--------------------- /** * 格式化时间 * @param format 格式化模板,如 'yyyy-MM-dd HH:mm:ss',注意MM为月份、mm为分钟 * @param dateInput 可选。要格式化的日期,可以是Date对象、时间戳(number)或日期字符串,默认为当前时间 * @returns 格式化后的日期字符串 */ formatDate(format, dateInput) { if (!format) { return ''; } let date; if (!dateInput) { date = new Date(); } else if (dateInput instanceof Date) { date = dateInput; } else { date = new Date(dateInput); } // 验证日期是否有效 if (isNaN(date.getTime())) { console.warn('Invalid date input provided to formatDate'); return ''; } const year = date.getFullYear().toString(); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const day = (date.getDate()).toString().padStart(2, '0'); const hours = (date.getHours()).toString().padStart(2, '0'); const minutes = (date.getMinutes()).toString().padStart(2, '0'); const seconds = (date.getSeconds()).toString().padStart(2, '0'); return format .replace('yyyy', year) .replace('MM', month) .replace('dd', day) .replace('HH', hours) .replace('mm', minutes) .replace('ss', seconds); } /** * 获取两日期间的所有日期 * @param startDate 开始日期 * @param endDate 结束日期 * @returns 日期数组 */ getRangeDate(startDate, endDate) { let datesArray = []; let currentDate = new Date(startDate); while (currentDate <= endDate) { datesArray.push(new Date(currentDate)); currentDate.setDate(currentDate.getDate() + 1); } return datesArray; } /** * 获取两日期间的天数 * @param startDate 开始日期 * @param endDate 结束日期 * @returns 天数 */ getDaysBetween(startDate, endDate) { const oneDay = 24 * 60 * 60 * 1000; return Math.round(Math.abs((startDate.getTime() - endDate.getTime()) / oneDay)); } // ---------------------数组、对象--------------------- /** * 数组去重 * @param array 要去重的数组 * @param keyFn 可选的函数,用于从每个数组项中提取用于比较的键,例如:item => item.id * @returns T[] */ uniqueArray(array, keyFn) { if (!keyFn) { return Array.from(new Set(array)); } const seen = new Set(); return array.filter(item => { const key = keyFn(item); if (seen.has(key)) { return false; } seen.add(key); return true; }); } /** * 数组排序 * @param array 要排序的数组 * @param sort 指定排序顺序,类型:NcOrderType,'asc' 为升序,'desc' 为降序 * @param keyFn 可选。可以是对象的键名或一个函数,用于从数组项中提取排序值,例如:'age'或 item => item.name.length * @returns T[] */ sortArray(array, sort, key) { return [...array].sort((a, b) => { let valueA; let valueB; if (typeof key === 'function') { valueA = key(a); valueB = key(b); } else if (key) { valueA = a[key]; valueB = b[key]; } else { valueA = a; valueB = b; } if (valueA === valueB) return 0; if (typeof valueA === 'string' && typeof valueB === 'string') { return sort === 'asc' ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA); } return sort === 'asc' ? (valueA < valueB ? -1 : 1) : (valueB < valueA ? -1 : 1); }); } /** * 判断对象是否为空 * @param obj * @returns boolean */ isObjectEmpty(obj) { return Object.keys(obj).length === 0; } /** * 百度坐标系 (BD-09) 与火星坐标系 (GCJ-02) 的转换 * 即百度 转 谷歌、高德 * @param lng 经度 * @param lat 纬度 * @returns [lng, lat] */ bd09togcj02(lng, lat) { var x_pi = 3.14159265358979324 * 3000.0 / 180.0; var x = lng - 0.0065; var y = lat - 0.006; var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); var gg_lng = z * Math.cos(theta); var gg_lat = z * Math.sin(theta); return [gg_lng, gg_lat]; } /** * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 * 即谷歌、高德 转 百度 * @param lng 经度 * @param lat 纬度 * @returns [lng, lat] */ gcj02tobd09(lng, lat) { var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * this.x_PI); var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * this.x_PI); var bd_lng = z * Math.cos(theta) + 0.0065; var bd_lat = z * Math.sin(theta) + 0.006; return [bd_lng, bd_lat]; } /** * WGS84转火星坐标系 (GCJ-02) * 即WGS84 转 谷歌、高德 * @param lng 经度 * @param lat 纬度 * @returns [lng, lat] */ wgs84togcj02(lng, lat) { if (this.out_of_china(lng, lat)) { return [lng, lat]; } else { var dlat = this.transformlat(lng - 105.0, lat - 35.0); var dlng = this.transformlng(lng - 105.0, lat - 35.0); var radlat = lat / 180.0 * this.PI; var magic = Math.sin(radlat); magic = 1 - this.ee * magic * magic; var sqrtmagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI); dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI); var mglat = lat + dlat; var mglng = lng + dlng; return [mglng, mglat]; } } /** * 火星坐标系 (GCJ-02)转WGS84 * 即谷歌、高德 转 WGS84 * @param lng 经度 * @param lat 纬度 * @returns [lng, lat] */ gcj02towgs84(lng, lat) { if (this.out_of_china(lng, lat)) { return [lng, lat]; } else { var dlat = this.transformlat(lng - 105.0, lat - 35.0); var dlng = this.transformlng(lng - 105.0, lat - 35.0); var radlat = lat / 180.0 * this.PI; var magic = Math.sin(radlat); magic = 1 - this.ee * magic * magic; var sqrtmagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * this.PI); dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * this.PI); let mglat = lat + dlat; let mglng = lng + dlng; return [lng * 2 - mglng, lat * 2 - mglat]; } } transformlat(lng, lat) { var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lat * this.PI) + 40.0 * Math.sin(lat / 3.0 * this.PI)) * 2.0 / 3.0; ret += (160.0 * Math.sin(lat / 12.0 * this.PI) + 320 * Math.sin(lat * this.PI / 30.0)) * 2.0 / 3.0; return ret; } transformlng(lng, lat) { var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); ret += (20.0 * Math.sin(6.0 * lng * this.PI) + 20.0 * Math.sin(2.0 * lng * this.PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lng * this.PI) + 40.0 * Math.sin(lng / 3.0 * this.PI)) * 2.0 / 3.0; ret += (150.0 * Math.sin(lng / 12.0 * this.PI) + 300.0 * Math.sin(lng / 30.0 * this.PI)) * 2.0 / 3.0; return ret; } /** * 判断是否在国内,不在国内则不做偏移 */ out_of_china(lng, lat) { return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false); } /** * 小数形式经纬度转度分秒形式(秒保留3位小数) * @param digital 109.86330555555556 * @returns degrees '109°51′47.9″' */ digitalToDegrees(digital) { let digitalString = digital.toString(); let index1 = digitalString.indexOf('.'); let du = index1 < 0 ? Number(digitalString) : Number(digitalString.substring(0, index1)); //109 let fen = 0; let miao = 0; if (index1 > 0) { let strFen = Number("0" + digitalString.substring(index1)); //0.86330555555556 let strFenString = (strFen * 60).toString(); //'51.7983333333336' let index2 = strFenString.indexOf('.'); if (index2 > 0) { fen = Number(strFenString.substring(0, index2)); //51 let strMiao = Number("0" + strFenString.substring(index2)); //0.7983333333336 miao = Number((strMiao * 60).toFixed(3)); //47.900000000016 47.9 } else { fen = Number(strFenString); } } return `${du}°${fen}′${miao}″`; } /** * 度分秒形式经纬度转小数形式 * @param degrees '109°51′47.900000000016″' * @returns digital 109.86330555555556 */ degreesToDigital(degrees) { let temp1 = degrees.split('°'); let temp2 = temp1[1].split('′'); let du = temp1[0]; let fen = temp2[0]; let miao = temp2[1].substring(0, temp2[1].length - 1); return Number(du) + Number(fen) / 60 + Number(miao) / 3600; } /** * 防抖(Debounce):适用于避免短时间内多次触发的场景,只有在事件停止触发后的一段时间才会执行。例如:搜索框输入,避免频繁的API请求。 * @param key 用于标识Subject的唯一键,不同防抖任务应使用不同的key,相同key的任务会共享首次设置的delay时间 * @param delay 防抖延迟时间(毫秒) * @param fn 要防抖的函数 */ debounce(key, delay, fn) { let subject = this.debounceTasks.get(key); if (!subject) { subject = new Subject(); subject.pipe(debounceTime(delay)).subscribe(fnToExecute => { fnToExecute(); }); this.debounceTasks.set(key, subject); } subject.next(fn); } /** * 节流(Throttle):适用于限制事件在固定时间间隔内执行的场景,确保事件不会过于频繁地触发。例如:滚动页面时的事件处理,避免频繁的计算和渲染。 * @param key 用于标识Subject的唯一键,不同节流任务应使用不同的key,相同key的任务会共享首次设置的delay时间 * @param delay 节流延迟时间(毫秒) * @param fn 要节流的函数 */ throttle(key, delay, fn) { let subject = this.throttleTasks.get(key); if (!subject) { subject = new Subject(); subject.pipe(throttleTime(delay)).subscribe(fnToExecute => { fnToExecute(); }); this.throttleTasks.set(key, subject); } subject.next(fn); } /** * 显示全屏加载中(全屏蒙版) * @param content 可选。提示内容,默认:'加载中,请稍后...' */ showFullLoading(content = '加载中,请稍后...') { if (this.fullLoadingElement) { return; } this.fullLoadingElement = this.renderer.createElement('div'); this.renderer.addClass(this.fullLoadingElement, 'full-loading-container'); this.renderer.setStyle(this.fullLoadingElement, 'position', 'fixed'); this.renderer.setStyle(this.fullLoadingElement, 'top', '0'); this.renderer.setStyle(this.fullLoadingElement, 'left', '0'); this.renderer.setStyle(this.fullLoadingElement, 'width', '100%'); this.renderer.setStyle(this.fullLoadingElement, 'height', '100%'); this.renderer.setStyle(this.fullLoadingElement, 'background-color', 'rgba(0,0,0,0.5)'); this.renderer.setStyle(this.fullLoadingElement, 'display', 'flex'); this.renderer.setStyle(this.fullLoadingElement, 'flex-direction', 'column'); this.renderer.setStyle(this.fullLoadingElement, 'justify-content', 'center'); this.renderer.setStyle(this.fullLoadingElement, 'align-items', 'center'); this.renderer.setStyle(this.fullLoadingElement, 'z-index', '9999'); const spinner = this.renderer.createElement('div'); this.renderer.addClass(spinner, 'full-loading-spinner'); this.renderer.setStyle(spinner, 'border', '4px solid #f3f3f3'); this.renderer.setStyle(spinner, 'border-top', '4px solid #3498db'); this.renderer.setStyle(spinner, 'border-radius', '50%'); this.renderer.setStyle(spinner, 'width', '50px'); this.renderer.setStyle(spinner, 'height', '50px'); this.renderer.setStyle(spinner, 'animation', 'fullSpin 1s linear infinite'); const loadingText = this.renderer.createElement('div'); this.renderer.addClass(loadingText, 'full-loading-text'); this.renderer.setStyle(loadingText, 'color', 'white'); this.renderer.setStyle(loadingText, 'margin-top', '20px'); this.renderer.setStyle(loadingText, 'font-size', '18px'); this.renderer.setStyle(loadingText, 'letter-spacing', '1.5px'); this.renderer.appendChild(loadingText, this.renderer.createText(content)); const keyframes = ` @keyframes fullSpin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; this.fullLoadingKeyframesStyle = this.renderer.createElement('style'); this.renderer.appendChild(this.fullLoadingKeyframesStyle, this.renderer.createText(keyframes)); this.renderer.appendChild(document.body, this.fullLoadingKeyframesStyle); this.renderer.appendChild(this.fullLoadingElement, spinner); if (content) { this.renderer.appendChild(this.fullLoadingElement, loadingText); } this.renderer.appendChild(document.body, this.fullLoadingElement); } /** * 移除全屏加载中(全屏蒙版) */ removeFullLoading() { if (this.fullLoadingElement) { this.renderer.removeChild(document.body, this.fullLoadingElement); this.fullLoadingElement = null; } if (this.fullLoadingKeyframesStyle) { this.renderer.removeChild(document.body, this.fullLoadingKeyframesStyle); this.fullLoadingKeyframesStyle = null; } } //美化打印 prettyPrint(title, content, color) { console.log(`%c ${title} %c ${typeof content == 'object' ? '👇' : content} %c`, `background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`, `border:1px solid ${color}; border-radius: 0 2px 2px 0; color: ${color};padding: 1px;`, 'background:transparent'); if (typeof content == 'object') { console.table(content); } } ; /** * 开始性能计时器 * @param timerName 计时器名称 */ startTimer(timerName) { this.timers[timerName] = performance.now(); } /** * 结束性能计时器并返回持续时间 * @param timerName 计时器名称 * @returns 计时器持续时间(毫秒) */ endTimer(timerName) { if (!this.timers[timerName]) { console.warn(`计时器 "${timerName}" 不存在。`); return 0; } const duration = performance.now() - this.timers[timerName]; delete this.timers[timerName]; return duration; } // ---------------------其他--------------------- /** * 深克隆 * @param obj 被克隆对象 * @returns 克隆对象 */ deepClone(obj, seen = new Map()) { // Handle immutable types and functions if (obj === null || typeof obj !== 'object') { return obj; } // Handle circular references if (seen.has(obj)) { return seen.get(obj); } // Handle Date if (obj instanceof Date) { return new Date(obj.getTime()); } // Handle RegExp if (obj instanceof RegExp) { const regExpClone = new RegExp(obj.source, obj.flags); regExpClone.lastIndex = obj.lastIndex; // Preserve the lastIndex property return regExpClone; } // Handle Array if (Array.isArray(obj)) { const arrClone = []; seen.set(obj, arrClone); for (const item of obj) { arrClone.push(this.deepClone(item, seen)); } return arrClone; } // Handle Set if (obj instanceof Set) { const setClone = new Set(); seen.set(obj, setClone); for (const item of obj) { setClone.add(this.deepClone(item, seen)); } return setClone; } // Handle Map if (obj instanceof Map) { const mapClone = new Map(); seen.set(obj, mapClone); for (const [key, value] of obj) { mapClone.set(this.deepClone(key, seen), this.deepClone(value, seen)); } return mapClone; } // Handle Object const objClone = Object.create(Object.getPrototypeOf(obj)); seen.set(obj, objClone); for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { objClone[key] = this.deepClone(obj[key], seen); } } return objClone; } /** * 获取文件后缀 * @param filename string 文件名 * @returns extension */ getFileExtension(filename) { if (!filename) { return ''; } const filenameArr = filename.split('.'); if (filenameArr.length == 0) { return ''; } else { const extension = filenameArr.pop(); return extension.toLowerCase(); } } /** * jsonp封装 * @param obj \{url: '', success: ()=> {}} */ jsonpFunction(obj) { // 创建一个script标签; var script = document.createElement("script"); // 给函数起名字,定义为全局函数; var fnName = "jsonp" + new Date().getTime(); // window.aaa就是把aaa设置为全局变量! window[fnName] = obj.success; // 改变src,添加到head中 if (obj.url.includes('?')) { script.src = obj.url + "&callback=" + fnName; } else { script.src = obj.url + "?callback=" + fnName; } // 把script标签添加到head标签中,就会发送src的请求了 document.head.appendChild(script); // 代码执行完毕,把script标签删除 script.onload = function () { document.head.removeChild(script); window[fnName] = undefined; }; } /** * 生成随机颜色 * @returns HEX */ generateRandomColor() { return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0'); } /** * 生成UUID * @returns UUID */ generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } /** * 验证密码强度(必须包含大、小写字母、数字、特殊字符至少三类,长度8-16位) * @param password 待验证的密码 * @returns 密码是否符合要求 */ passwordValidate(password) { // 检查密码长度是否在8到16位之间 if (password.length < 8 || password.length > 16) { return false; } // 定义正则表达式规则 let rC = { lW: '[a-z]', uW: '[A-Z]', nW: '[0-9]', sW: '[`~!@$%\^\&\(\)\-_\+=\{\}\[\]|\\:;\"\'<>,\.\?\/_]' // 特殊字符 }; /** * 检查字符串是否匹配正则表达式 * @param str 待检查的字符串 * @param rStr 正则表达式字符串 * @returns 是否匹配 */ function Reg(str, rStr) { let reg = new RegExp(rStr); return reg.test(str); } // 检查密码是否包含各种字符类型 let tR = { l: Reg(password, rC.lW), u: Reg(password, rC.uW), n: Reg(password, rC.nW), s: Reg(password, rC.sW) // 是否包含特殊字符 }; // 密码必须包含以下四种组合之一: // 1. 小写字母 + 大写字母 + 数字 // 2. 小写字母 + 大写字母 + 特殊字符 // 3. 特殊字符 + 大写字母 + 数字 // 4. 特殊字符 + 小写字母 + 数字 return (tR.l && tR.u && tR.n) || (tR.l && tR.u && tR.s) || (tR.s && tR.u && tR.n) || (tR.s && tR.l && tR.n); } /** * 复制到剪贴板 * @param text 待复制的内容 * @returns 复制是否成功 */ copyToClipboard(text) { try { if (navigator.clipboard) { //安全模式下(https localhost 127.0.0.1) navigator.clipboard.writeText(text); return true; } else { //非安全模式 // 创建临时文本区域来复制纯文本 const textarea = document.createElement('textarea'); textarea.value = text; textarea.style.position = 'absolute'; textarea.style.left = '-9999px'; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); return true; } } catch (error) { return false; } } } NcCommonService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService, deps: [{ token: PLATFORM_ID }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable }); NcCommonService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcCommonService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i0.RendererFactory2 }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2NvbW1vbi1zZXJ2aWNlL2NvbW1vbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBK0IsTUFBTSxlQUFlLENBQUM7QUFDN0YsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQXNDNUQsTUFBTSxPQUFPLGVBQWU7SUFHeEIsWUFBeUMsVUFBa0IsRUFBVSxlQUFpQztRQUE3RCxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWtCO1FBZ1p0RyxnREFBZ0Q7UUFFeEMsU0FBSSxHQUFHLG1CQUFtQixHQUFHLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDNUMsT0FBRSxHQUFHLHdCQUF3QixDQUFDO1FBQzlCLE1BQUMsR0FBRyxTQUFTLENBQUM7UUFDZCxPQUFFLEdBQUcsc0JBQXNCLENBQUM7UUF3SnBDLGtEQUFrRDtRQUUxQyxrQkFBYSxHQUFtQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFELGtCQUFhLEdBQW1DLElBQUksR0FBRyxFQUFFLENBQUM7UUF5Q2xFLGlEQUFpRDtRQUV6Qyx1QkFBa0IsR0FBdUIsSUFBSSxDQUFDO1FBQzlDLDhCQUF5QixHQUF1QixJQUFJLENBQUM7UUEwRTdELCtDQUErQztRQUUvQzs7VUFFRTtRQUNGLFlBQU8sR0FBa0I7WUFDckIsR0FBRyxFQUFFLENBQUMsV0FBZ0IsRUFBRSxPQUFZLEVBQUUsRUFBRTtnQkFDcEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxD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