import {Session} from "/@/utils/storage"; const fileUrl = import.meta.env.VITE_FILE_URL const serverUrl = import.meta.env.VITE_API_URL const previewUrl = import.meta.env.VITE_PREVIEW_URL const u = { url: { file: fileUrl, server: serverUrl, preview: previewUrl }, dialog: { actions: { 'add': {title: '新增', btn: '创建'}, 'del': {title: '删除', btn: '确定'}, 'edit': {title: '修改', btn: '修改'}, 'view': {title: '详情', btn: '确定'}, }, }, /** * 16进制颜色转rgb * @param hex */ hexToRgb(hex: string) { // Remove the # character if it exists hex = hex.replace("#", ""); // Convert the hex value to RGB values 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 the RGB values as an object return {r, g, b}; }, distinctByKey(elements: Array, key: string) { let result:any[] = []; let keys:Array = []; if (!elements || elements.length === 0) { return result; } for (let i = 0; i < elements.length; i++) { if (!elements[i][key] && elements[i][key] !== 0) { continue; } let k = elements[i][key].toString(); if(!keys.includes(k)){ result.push(elements[i]); keys.push(k); } } return result; }, groupByKey(elements: Array, key: string) { let map = {}; if (!elements || elements.length === 0) { return map; } for (let i = 0; i < elements.length; i++) { if (!elements[i][key] && elements[i][key] !== 0) { continue; } let k = elements[i][key].toString(); let tmp = map[k] || []; tmp.push(elements[i]); map[k] = tmp; } return map; }, groupByKeyV2(elements: Array, key: string) { return elements.reduce((groups, item) => { const group = item[key]; if (!groups[group]) { groups[group] = []; } groups[group].push(item); return groups; }, {}); }, sortByArray(elements: Array, key: string, sortArray: Array) { if (key) { elements.sort(function (a, b) { return sortArray.indexOf(a[key]) - sortArray.indexOf(b[key]); }); } else { elements.sort(function (a, b) { return sortArray.indexOf(a) - sortArray.indexOf(b); }); } }, sort(elements: Array, key: string) { elements.sort((o1, o2) => { let value1 = o1[key]; let value2 = o2[key]; if (value2 > value1) { return -1; } else if (value2 < value1) { return 1; } else { return 0; } }) }, toMap(elements: Array, fn: Function) { let ret = {}; elements.forEach(item => { let key = fn.apply(null, [item]); ret[key] = item; }) return ret; }, /** * 浅拷贝或者一层属性的对象深拷贝 * @param obj * @returns {*} */ copyObject(obj: Object) { return Object.assign({}, obj); }, /** * 深拷贝 支持regExp、function、null、undefined * @param target * @returns {function(*=): {}} */ // eslint-disable-next-line @typescript-eslint/no-unused-vars copyDeep(target: any) { // @ts-ignore return function deepClone(target: any) { // 定义一个变量 let result; // 如果当前需要深拷贝的是一个对象的话 if (typeof target === 'object') { // 如果是一个数组的话 if (Array.isArray(target)) { result = []; // 将result赋值为一个数组,并且执行遍历 for (let i in target) { // 递归克隆数组中的每一项 result.push(deepClone(target[i])) } // 判断如果当前的值是null的话;直接赋值为null } else if (target === null) { result = null; // 判断如果当前的值是一个RegExp对象的话,直接赋值 } else if (target.constructor === RegExp) { result = target; } else { // 否则是普通对象,直接for in循环,递归赋值对象的所有值 result = {}; for (let i in target) { result[i] = deepClone(target[i]); } } // 如果不是对象的话,就是基本数据类型,那么直接赋值 } else { result = target; } // 返回最终结果 return result; } }, /** * 加强parse 支持function解析 * @param script * @returns {any} */ parseDeep(script: string) { return JSON.parse(script, function (key, value) { if (null != value && value.indexOf("function") === 0) { return eval("(function(){return " + value + "})()"); } return value; }); }, isEmptyOrNull: function (exp: any) { return !exp || typeof (exp) == "undefined" || "undefined" === exp || exp.length === 0 || exp === '' || JSON.stringify(exp) === "{}"; }, pad: function (val: any, len: number, ch: string = '0') { return val.toString().padStart(len, ch); }, mediaType: function (url: string) { let type = "other"; url = url.toLowerCase(); if (url.endsWith(".jpg") || url.endsWith(".jpeg") || url.endsWith(".png") || url.endsWith(".gif") || url.endsWith(".svg")) { type = "image"; } if (url.endsWith(".mp4") || url.endsWith(".avi") || url.endsWith(".webm") || url.endsWith(".ogg")) { type = "video"; } if (url.endsWith(".mp3") || url.endsWith(".amr") || url.endsWith(".wav")) { type = "audio"; } if ("url".endsWith(".pdf") || "url".endsWith(".doc") || "url".endsWith(".docx") || "url".endsWith(".xls") || "url".endsWith(".xlsx") || "url".endsWith(".ppt")) { type = "wps"; } return type; }, contains(array: Array, value: any, key = null) { if (!u.isEmptyOrNull(array)) { for (let i = 0; i < array.length; i++) { if (!key) { if (array[i] == value) { return true; } } else { if (value.constructor != Object && array[i][key] == value) { return true; } else if (value.constructor == Object && array[i][key] == value[key]) { return true; } } } } return false; }, removeItem(array: Array, value: any, key = null) { if (!u.isEmptyOrNull(array)) { for (let i = 0; i < array.length; i++) { if (!key) { if (array[i] == value) { array.splice(i, 1); break; } } else { if (value.constructor != Object && array[i][key] == value) { array.splice(i, 1); break; } else if (value.constructor == Object && array[i][key] == value[key]) { array.splice(i, 1); break; } } } } }, randomChars(length: number, uuid = false) { let cs = "0123456789abcdef0123456789abcdef"; let chars = ""; for (let i = 0; i < length; i++) { chars += cs[Math.floor(Math.random() * cs.length)]; if (uuid && (i === 7 || i === 11 || i === 15 || i === 19)) { chars += "-"; } } return chars.toLowerCase(); }, randomKey(length: number, uuid = false) { let cs = "0123456789abcdef012345678ABCDEFGHIJKLMNRSTZZYAL29123"; let chars = ""; for (let i = 0; i < length; i++) { chars += cs[Math.floor(Math.random() * cs.length)]; if (uuid && (i === 7 || i === 11 || i === 15 || i === 19)) { chars += "-"; } } return chars; }, getOsName() { let u = navigator.userAgent; if (!!u.match(/compatible/i) || u.match(/Windows/i)) { return 'windows'; } else if (!!u.match(/Macintosh/i) || u.match(/MacIntel/i)) { return 'macOS'; } else if (!!u.match(/iphone/i) || u.match(/Ipad/i)) { return 'ios'; } else if (u.match(/android/i)) { return 'android'; } else { return 'other'; } }, getBrowerName() { let u = navigator.userAgent; let bws = [{ name: 'sgssapp', it: /sogousearch/i.test(u) }, { name: 'wechat', it: /MicroMessenger/i.test(u) }, { name: 'weibo', it: !!u.match(/Weibo/i) }, { name: 'uc', it: !!u.match(/UCBrowser/i) || u.indexOf(' UBrowser') > -1 }, { name: 'sogou', it: u.indexOf('MetaSr') > -1 || u.indexOf('Sogou') > -1 }, { name: 'xiaomi', it: u.indexOf('MiuiBrowser') > -1 }, { name: 'baidu', it: u.indexOf('Baidu') > -1 || u.indexOf('BIDUBrowser') > -1 }, { name: '360', it: u.indexOf('360EE') > -1 || u.indexOf('360SE') > -1 }, { name: '2345', it: u.indexOf('2345Explorer') > -1 }, { name: 'edge', it: u.indexOf('Edge') > -1 }, { name: 'ie11', it: u.indexOf('Trident') > -1 && u.indexOf('rv:11.0') > -1 }, { name: 'ie', it: u.indexOf('compatible') > -1 && u.indexOf('MSIE') > -1 }, { name: 'firefox', it: u.indexOf('Firefox') > -1 }, { name: 'safari', it: u.indexOf('Safari') > -1 && u.indexOf('Chrome') === -1 }, { name: 'qqbrowser', it: u.indexOf('MQQBrowser') > -1 && u.indexOf(' QQ') === -1 }, { name: 'qq', it: u.indexOf('QQ') > -1 }, { name: 'chrome', it: u.indexOf('Chrome') > -1 || u.indexOf('CriOS') > -1 }, { name: 'opera', it: u.indexOf('Opera') > -1 || u.indexOf('OPR') > -1 }]; for (let i = 0; i < bws.length; i++) { if (bws[i].it) { return bws[i].name; } } return 'other'; }, date: { /** * @description 获取需要的时间格式 * @param {Date} time 时间、时间字符串、时间戳 * @param {String} format 时间格式,默认'YYYY-MM-DD'。如果是'星期WW',则返回(如:'星期日') * @return {String} 格式化后的时间 */ format: function (time: any, format: string) { time = time ? new Date(time) : new Date() format = format || 'YYYY-MM-DD' function tf(i: any) { return (i < 10 ? '0' : '') + i } // @ts-ignore return format.replace(/YYYY|MM|DD|hh|mm|ss|WW/g, function (a: string) { switch (a) { case 'YYYY': return tf(time.getFullYear()) case 'MM': return tf(time.getMonth() + 1) case 'DD': return tf(time.getDate()) case 'mm': return tf(time.getMinutes()) case 'hh': return tf(time.getHours()) case 'ss': return tf(time.getSeconds()) case 'WW': return ['日', '一', '二', '三', '四', '五', '六'][time.getDay()] } }) }, diff(start: Date, end: Date) { let d0 = this.begin(new Date(start)); let d1 = this.begin(new Date(end)); return (d1.getTime() - d0.getTime()) / (24 * 3600 * 1000) }, delta(time: any = null, delta = 0, type = 'day') { let t = time || new Date(); let year = t.getFullYear(), month = t.getMonth(), day = t.getDate(), hour = t.getHours(), minute = t.getMinutes(), second = t.getSeconds(); let nextMonth = 0, mod = 0; switch (type) { case "day": t = new Date(t.getTime() + (delta * 24 * 3600 * 1000)) break; case "week": t = new Date(t.getTime() + (delta * 7 * 24 * 3600 * 1000)) break; case "month": nextMonth = month + delta; mod = Math.abs(delta) % 12; if (delta < 0) { if (nextMonth < 0) { nextMonth = nextMonth + ((mod + 1) * 12); year = year - (mod + 1); } } else if (delta > 0) { nextMonth = nextMonth - ((mod + 1) * 12); year = year + (mod + 1); } t = new Date(year, nextMonth, day, hour, minute, second); break; case "quarter": nextMonth = month + (delta * 3); mod = Math.abs(delta * 3) % 12; if (delta < 0) { if (nextMonth < 0) { nextMonth = nextMonth + ((mod + 1) * 12); year = year - (mod + 1); } } else if (delta > 0) { nextMonth = nextMonth - ((mod + 1) * 12); year = year + (mod + 1); } t = new Date(year, nextMonth, day, hour, minute, second); break; case "year": t = new Date(year + delta, month, day, hour, minute, second); break; } return t; }, begin(time: any = null, type = 'day') { let t = time || new Date(); let year = t.getFullYear(), month = t.getMonth(), day = t.getDate() switch (type) { case "day": t = new Date(year, month, day); break; case "week": let date = t.getDay(); t = new Date(new Date(year, month, day).getTime() - (date * 24 * 3600 * 1000)); break; case "month": t = new Date(year, month, 1); break; case "quarter": let nextMonth = 0; if (month >= 3 && month <= 5) { nextMonth = 3; } if (month >= 6 && month <= 8) { nextMonth = 6; } if (month >= 9 && month <= 11) { nextMonth = 9; } t = new Date(year, nextMonth, 1); break; case "year": t = new Date(year, 0, 1); break; } return t; }, end(time: Date, type = 'day') { let t: Date = time || new Date(); let year = t.getFullYear(), month = t.getMonth(), day = t.getDate() switch (type) { case "day": t = new Date(year, month, day, 23, 59, 59, 999); break; case "week": let date = t.getDay(); t = new Date(new Date(year, month, day).getTime() + ((7 - date) * 24 * 3600 * 1000) - 1); break; case "month": let _d = this.delta(t, 1, 'month'); _d = this.begin(_d, 'month'); t = new Date(new Date(_d.getFullYear(), _d.getMonth(), _d.getDate()).getTime() - 1); break; case "quarter": let __d = this.delta(t, 1, 'quarter'); __d = this.begin(__d, 'quarter'); t = new Date(new Date(__d.getFullYear(), __d.getMonth(), __d.getDate()).getTime() - 1); break; case "year": t = new Date(year, 11, 13, 23, 59, 59, 999); break; } return t; } }, validator: { required: {required: true, message: "必填项", trigger: 'blur'}, requiredEnum: {type: 'number', min: 1, message: "必选项", trigger: 'blur'}, //字典类的校验规则 verifyCode: {required: true, message: "请输入验证码", trigger: 'blur'}, rangeDate: {type: 'array', length: 2, required: true, message: "必选项"}, lengthMax2: {type: 'string', max: 2, message: "最多2个字"}, lengthMax6: {type: 'string', max: 6, message: "长度最大6个字"}, lengthMax10: {type: 'string', max: 10, message: "长度最大6个字"}, lengthMax50: {type: 'string', max: 50, message: "长度最大50个字"}, length: {type: 'string', min: 4, max: 50, message: "长度为4-50个字"}, length32: {type: 'string', min: 1, max: 32, message: "不能超过32个字"}, length64: {type: 'string', min: 1, max: 64, message: "不能超过64个字"}, length128: {type: 'string', min: 1, max: 128, message: "不能超过128个字"}, length256: {type: 'string', min: 1, max: 256, message: "不能超过256个字"}, lengthShort: {min: 2, max: 20, message: "长度为4-20个字"}, lengthName: {type: 'string', min: 2, max: 10, message: "长度为2-10个字"}, positiveInt: {type: 'number', min: 1, message: "必须为正整数"}, negativeInt: {type: 'number', max: -1, message: "必须为负数"}, mobile: {type: 'string', length: 11, max: 11, pattern: '^[1][3,4,5,7,8][0-9]{9}$', message: "11位数字手机号格式错误"}, email: {type: 'email', min: 6, pattern: '^(\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$', message: "邮箱格式错误"}, password: {min: 8, message: "请输入8位密码", trigger: 'blur'}, // password: {type: 'string', min: 6, max: 12, pattern: '(\\w){6,12}', message: '格式为6-12位数字字母组合'}, idNo: {type: 'string', pattern: '(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X)$)', message: '身份证号码格式错误'}, chinese: {type: 'string', pattern: '^[\\u4e00-\\u9fa5]{0,}$', message: '请输入中文字符'}, num: {type: 'string', pattern: /^\d*$/, message: "只能输入数字"}, letter: {type: 'string', pattern: /^[A-Za-z0-9\-]$/, message: "只能输入字母和数字"}, tel: {type: 'string', pattern: /^[-\d]*$/, message: "电话只能包含数字和-"}, url: { type: 'string', pattern: /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/, message: "链接地址错误" }, }, fmt: { fmtMoney: function (money: number) { if (!money) { return "0.00"; } return (money / 100).toFixed(2); }, fmtUrl: function (v: string) { let token = Session.get('accessToken') if (!v) { return ''; } if (v.indexOf("http") === 0) { return v; } console.log(v, fileUrl) // return fileUrl + v; return `${fileUrl}${v}` }, fmtImg(v: string) { let token = Session.get('accessToken') if (u.isEmptyOrNull(v)) { return "./image/placeholder.png"; } if (v.indexOf("http") === 0) { return v; } return `${fileUrl}${v}` }, fmtPreview(v: string) { let token = Session.get('accessToken') if (u.isEmptyOrNull(v)) { return "./image/placeholder.png"; } if (v.indexOf("http") === 0) { return v; } return `${previewUrl}${v}?X-Token=${btoa(token)}` // return `${previewUrl}${v}` }, /** * byte 单位转换 * @param size */ fmtSize(size: number = 0) { if (size < 1024) { return size + 'B'; } size = size / 1024; if (size > 1024) { size = size / 1024; if (size > 1024) { size = size / 1024; return size.toFixed(2) + 'GB' } else { return size.toFixed(2) + 'MB' } } else { return size.toFixed(2) + 'KB' } }, fmtDateTime(t: any) { if (t == null) { return "-"; } let date = new Date(t); let year = date.getFullYear(); let month = date.getMonth() + 1; let day = date.getDate(); let hour = date.getHours(); let minute = date.getMinutes(); let second = date.getSeconds(); return [year, month, day].map(n => { return u.pad(n, 2) }).join('-') + ' ' + [hour, minute, second].map(n => { return u.pad(n, 2) }).join(':') }, fmtDate(t: any) { if (t == null) { return "-"; } let date = new Date(t); let year = date.getFullYear(); let month = date.getMonth() + 1; let day = date.getDate(); return [year, month, day].map(n => { return u.pad(n, 2) }).join('-'); }, fmtMonth(t: any) { if (t == null) { return "-"; } let date = new Date(t); let year = date.getFullYear(); let month = date.getMonth() + 1; return [year, month].map(n => { return u.pad(n, 2) }).join('-'); }, fmtTime(t: any) { if (t == null) { return "-"; } let date = new Date(t); let hour = date.getHours(); let minute = date.getMinutes(); return [hour, minute].map(n => { return u.pad(n, 2) }).join(':') }, fmtServerUrl(v: any) { if (!v) { return null; } if (v.indexOf("http") === 0) { return v; } return serverUrl + v.replace(/\\/g, "/"); }, fmtSensitive(v: any, start: number, length: number) { if (!v) { return ""; } let ret = []; ret.push(v.substring(0, start)); for (let i = 0; i < length; i++) { ret.push("*"); } ret.push(v.substring(start + length, v.length)); return ret.join(""); }, fmtUrlParam(key: string) { let reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)", "i"); let r = window.location.search.substr(1).match(reg); if (r != null) { return decodeURI(r[2]); } else { return null; } }, fmtDict(v: number, type: string) { if (v == null) { return ""; } const dicts = Session.get("dicts"); if (u.isEmptyOrNull(dicts)) { return '--' } let dict = (dicts).find(k => k.type == type && k.code === v); if (u.isEmptyOrNull(dict)) { return "--"; } return dict.value; }, } } export default u;