UNPKG

calc-oa-lib

Version:

calc oa library

1,968 lines (1,789 loc) 58.9 kB
import Base from "./base"; import guid from "./guid"; import md5 from "./md5"; import constant from "../config/config.json5"; import _ from "lodash"; import jsCookie from "js-cookie"; // import { Sweetalert } from "zent"; // 按需引入 // import Sweetalert from "zent/lib/sweetalert"; import * as zent from "zent"; // import * as antd from "antd"; /** * @description 工具类 */ export default class tool extends Base { //#region 属性 /** * 返回lodash对象 * @return {object} lodash对象 */ static get _() { return _; } static #antd = globalThis.antd; static set thirdPartyLib_Antd(val) { const obj = val ?? globalThis.antd ?? antd; if (obj) { tool.#antd = obj; } } /** * 配置信息参考 https://1x.ant.design/components/message/ * @return {object} 第三方组件库_antd */ static get thirdPartyLib_Antd() { // const antd = globalThis.antd ?? antd; // if (!antd) { // console.error(`Fail to load antd!`); // return null; // } // return antd; return tool.#antd; } /** * @return {object} 第三方组件库_zent */ static get thirdPartyLib_Zent() { // const zent = globalThis.zent; // if (!zent) { // console.error(`Fail to load zent!`); // return null; // } return zent; } //#endregion //#region 构造函数 constructor() { super(); } //#endregion //#region 通用方法 /** * 判断是否函数 * @param {function} callBack 待检测的函数 * @return {boolean} 是否函数 */ static isFunction(callBack) { return ( callBack != undefined && callBack != null && (typeof callBack).toLowerCase() == "function" ); } /** * 判断是否对象 * @param {function} data 待检测的数据 * @return {boolean} 是否对象 */ static isObject(data) { return data instanceof Object && !Array.isArray(data); } /** * 判断是否数组 * @param {function} data 待检测的数据 * @return {boolean} 是否数组 */ static isArray(data) { return Array.isArray(data); } /** * 判断是否数字(匹配+-号,正负数,整数和小数) * @param {function} data 待检测的数据 * @return {boolean} 是否数字 */ static isNum(val = "") { val = (tool.isNullOrEmpty(val) ? "" : val).toString().trim(); const rule = /^[+-]?\d+$|^[+-]?\d+\.\d+$/; return rule.test(val); } /** * 将科学计数法转成常规数字 * @param {number} val 待检测的数据 * @return {boolean} 常规数字 */ static toNonExponential(val = "") { const m = val.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/); return val.toFixed( Math.max(0, (tool.isNullOrEmpty(m[1]) ? "" : m[1]).length - m[2]) ); } /** * 生成指定范围区间的随机值 * @param {number} minNum 最小值 * @param {number} maxNum 最大值 * @return {number} 随机值 */ static randomNum(minNum, maxNum) { switch (arguments.length) { case 1: return Number.parseInt(Math.random() * minNum + 1, 10); case 2: return Number.parseInt( Math.random() * (maxNum - minNum + 1) + minNum, 10 ); default: return 0; } } /** * 是否为空,包括null, undefined, 空数组, 没有任何属性的空对象 * @param {any} obj 任意对象 * @return {boolean} 如果为空对象,返回true */ static isNullOrEmpty(obj) { let isNull = false; if (obj === null || obj === undefined || obj === "") { isNull = true; return isNull; } let dataType = (typeof obj).toLowerCase(); if (dataType === "string") { obj = obj.trim(); if (obj === "") { isNull = true; return isNull; } obj = obj.toUpperCase(); if (obj === "NULL" || obj === "UNDEFINED") { isNull = true; return isNull; } } if (dataType === "array") { isNull = obj.length === 0; return isNull; } if (dataType === "object") { isNull = JSON.stringify(obj) == "{}" || JSON.stringify(obj) == "[]" ? true : false; //兼容正则表达式的情况, 如 /[^\d]/g, 也是object对象, 需要转成字符串, 判断字符串是否为空 if (isNull == true) { //判断是否正则 let regExp = new RegExp(/^\/[^\s]*\/g$/g); let isRegex = regExp.test(obj.toString()); if (isRegex) { isNull = false; } return isNull; } return isNull; } return isNull; } /** * 格式化成Object对象 * @param {*} data 待格式化的字符串/对象 * @return {object} 格式化后的对象 */ static jObject(data) { if (tool.isNullOrEmpty(data)) { return data; } let dataObj; try { let dataType = (typeof data).toLowerCase(); if (dataType == "string") { dataObj = JSON.parse(data); //再次判断转换后的内容是否为string, 若是, 再转一次 //这里不使用递归调用, 担心异常情况下会造成死循环, 导致客户端内存溢出 dataType = (typeof dataObj).toLowerCase(); if (dataType == "string") { dataObj = JSON.parse(dataObj); } } else { dataObj = data; } } catch (err) { console.error("Json format error!"); dataObj = {}; } return dataObj; } /** * 通过键(key)检索获取应用存储的值 * @param {string} keyName key name * @param {string} keyName 取出来的值是否JSON对象,默认为false * @return {object} 存储的值 */ static getSessionStorageItem(keyName, isJSON = false) { if (tool.isNullOrEmpty(keyName)) { return ""; } let val = tool.isNullOrEmpty(sessionStorage.getItem(keyName)) ? "" : sessionStorage.getItem(keyName); if (isJSON == true) { val = tool.jObject(val); } return val; } /** * 修改或添加键值(key-value)对数据到应用数据存储sessionStorage中 * @param {string} keyName key name * @param {string} value 格式化成字符串的值 * @return {boolean} 执行结果 */ static setSessionStorageItem(keyName, value = "") { if (tool.isNullOrEmpty(keyName)) { return false; } let dataType = (typeof value).toLowerCase(); if (dataType != "string") { value = JSON.stringify(value); } sessionStorage.setItem(keyName, value); return true; } /** * 通过key值删除键值对存储的数据 * @param {string} keyName key name * @return {boolean} 执行结果 */ static removeSessionStorageItem(keyName) { if (tool.isNullOrEmpty(keyName)) { return false; } sessionStorage.removeItem(keyName); return true; } /** * 清空SessionStorage的数据 * @return {boolean} 执行结果 */ static clearSessionStorageItem() { sessionStorage.clear(); return true; } /** * 通过键(key)检索获取应用存储的值 * @param {string} keyName key name * @param {string} keyName 取出来的值是否JSON对象,默认为false * @return {object} 存储的值 */ static getLocalStorageItem(keyName, isJSON = false) { if (tool.isNullOrEmpty(keyName)) { return ""; } let val = localStorage.getItem(keyName) || ""; if (isJSON == true) { val = tool.jObject(val); } return val; } /** * 修改或添加键值(key-value)对数据到应用数据存储localStorage中 * @param {string} keyName key name * @param {string} value 格式化成字符串的值 * @return {boolean} 执行结果 */ static setLocalStorageItem(keyName, value = "") { // console.log(`setLocalStorageItem`, keyName, value); if (tool.isNullOrEmpty(keyName)) { return false; } let dataType = (typeof value).toLowerCase(); if (dataType != "string") { value = JSON.stringify(value); } localStorage.setItem(keyName, value); return true; } /** * 通过key值删除键值对存储的数据 * @param {string} keyName key name * @return {boolean} 执行结果 */ static removeLocalStoragItem(keyName) { if (tool.isNullOrEmpty(keyName)) { return false; } localStorage.removeItem(keyName); return true; } /** * 清空localStorage的数据 * @return {boolean} 执行结果 */ static clearLocalStorageItem() { localStorage.clear(); return true; } /** * 获取localStorage所有的key * @return {array} localStorage所有的key */ static getLocalStorageKeys() { let keyArr = []; for (let i = 0; i < localStorage.length; i++) { keyArr.push(localStorage.key(i)); } return keyArr; } /** * 通过键(key)检索获取cookie的值 * @param {string} keyName key name * @param {string} isJSON 取出来的值是否JSON对象,默认为false * @return {object|string} 存储的值 */ static getCookie(keyName = "", isJSON = false) { let val = ""; // console.log(jsCookie); //若keyName为空,则获取全部cookie if (tool.isNullOrEmpty(keyName)) { if (isJSON) { val = jsCookie.get(); if (tool.isNullOrEmpty(val)) { val = undefined; return val; } else { // val = jsCookie.getJSON(); val = tool.jObject(val); } } else { val = jsCookie.get() ?? ""; } return val; } if (isJSON) { val = jsCookie.get(keyName); if (tool.isNullOrEmpty(val)) { val = undefined; return val; } else { // val = jsCookie.getJSON(keyName); val = tool.jObject(val); } } else { val = jsCookie.get(keyName); } return val; } /** * 设置cookie的值 * @param {string} keyName key name * @param {string|object|array} val 字符串|对象|数组 * @param {number|date} expires 定义有效期。如果传入Number,那么单位为天,也可以传入一个Date对象,表示有效期至Date指定时间。默认情况下cookie有效期截止至用户退出浏览器。 * @param {string} path 表示此cookie对哪个地址可见,默认为”/” * @param {string} secure 取出来的值是否JSON对象,默认为false * @return {boolean} 执行结果 */ static setCookie(keyName = "", val, expires = 1, path = "", secure = false) { if (tool.isNullOrEmpty(keyName)) { return false; } //将object对象转成string let dataType = (typeof val).toLowerCase(); if (dataType != "string") { val = JSON.stringify(val); } jsCookie.set(keyName, val, { expires: expires, path: path, secure: secure, }); return true; } /** * 移除指定cookie * @param {string} keyName key name * @param {string} path 表示此cookie对哪个地址可见,默认为”/” * @return {boolean} 执行结果 */ static removeCookie(keyName = "", path = "") { if (tool.isNullOrEmpty(keyName)) { return false; } if (tool.isNullOrEmpty(path)) { jsCookie.remove(keyName); return true; } jsCookie.remove(keyName, { path: path, }); return true; } /** * 移除全部cookie,只能删除不带path的cookie * @return {boolean} 执行结果 */ static clearCookie() { let cookieObj = tool.getCookie(); if (cookieObj) { Object.keys(cookieObj).forEach((key, index) => { tool.removeCookie(key); }); } } /** * 将Json对象里的Key按照名称排序 * @param {object} jObject 待排序的对象 * @return {object} 排序后的对象 */ static sortJObjectByKey(jObject) { if (tool.isNullOrEmpty(jObject)) { return {}; } //先用Object内置类的keys方法获取要排序对象的属性名, //再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组 let newkeyArray = Object.keys(jObject).sort(); //创建一个新的对象,用于存放排好序的键值; let newJObject = {}; newkeyArray.forEach((key, index) => { //遍历newkey数组,向新创建的对象中按照排好的顺序依次增加键值对 newJObject[key] = jObject[key]; }); return newJObject; } /** * 根据数据格式获取小数位个数 * @param {string} dataFormat 数据格式 * @return {number} 小数位个数 */ static getFixNum(dataFormat) { let digitalPoint = 0; if (tool.isNullOrEmpty(dataFormat)) { return digitalPoint; } let fixArray = dataFormat.split("."); if (tool.isNullOrEmpty(fixArray) || fixArray.length != 2) { return digitalPoint; } digitalPoint = fixArray[1].length; return digitalPoint; } /** * 数字格式化 * @param {string} s 待格式化的数值 * @param {number} n 小数位数,默认0位 * @param {number} isAddMillenniumDivision 是否添加千分符,默认true * @return {string} 格式化后的数值 */ static formatNum(s, n = 0, isAddMillenniumDivision = true) { let isMinus = s < 0 ? true : false; if (isMinus) { s = Math.abs(s); } let multiple = Math.pow(10, n); //round四舍五入的规则符合我们平常在数据中处理的方式 //关于js浮点数计算精度不准确问题的解决办法:https://www.cnblogs.com/xinggood/p/6639022.html // s = (Math.round((parseFloat((s + "").replace(/[^\d\.-]/g, "")) * multiple)) / multiple) + ""; let expand = tool.accMul( parseFloat((s + "").replace(/[^\d\.-]/g, "")), multiple ); s = Math.round(expand); s = tool.accDiv(s, multiple) + ""; if (isNaN(s) || (s + "").replace(/\s/g, "") == "") { return ""; } let l = s.split(".")[0].split("").reverse(); let r = s.split(".")[1]; r = tool.isNullOrEmpty(r) ? "" : r; //补0 if (r == "" || r.length < n) { // r = ""; let number = n - r.length; for (let i = 0; i < number; i++) { r += "0"; } } let t = ""; for (let i = 0; i < l.length; i++) { t += l[i] + ((i + 1) % 3 == 0 && i + 1 != l.length && isAddMillenniumDivision ? "," : ""); } if (r == "") { return (isMinus && t != 0 ? "-" : "") + t.split("").reverse().join(""); } return (isMinus ? "-" : "") + t.split("").reverse().join("") + "." + r; } /** * js中浮点数运算 两个数相乘 * @param {number} arg1 乘数 * @param {number} arg2 乘数 * @returns {number} 两个数相乘后处理精度问题的结果 */ static accMul(arg1, arg2) { arg1 = tool.isNullOrEmpty(arg1) ? 0 : arg1; arg2 = tool.isNullOrEmpty(arg2) ? 0 : arg2; let m = 0; // s1=arg1.toString(),s2=arg2.toString(); let s1, s2; if (arg1.toString().includes("e-")) { s1 = tool.toNonExponential(arg1); } else { s1 = arg1.toString(); } if (arg2.toString().includes("e-")) { s2 = tool.toNonExponential(arg2); } else { s2 = arg2.toString(); } try { m += s1.split(".")[1].length; } catch (e) {} try { m += s2.split(".")[1].length; } catch (e) {} return ( (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m) ); } /** * js中浮点数运算 两个数相除 * @param {number} arg1 除数 * @param {number} arg2 被除数 * @returns {number} 两个数相除后处理精度问题的结果 */ static accDiv(arg1, arg2) { arg1 = tool.isNullOrEmpty(arg1) ? 0 : arg1; arg2 = tool.isNullOrEmpty(arg2) ? 0 : arg2; let t1 = 0, t2 = 0, r1, r2; if (arg1.toString().includes("e-")) { r1 = tool.toNonExponential(arg1); } else { r1 = arg1.toString(); } if (arg2.toString().includes("e-")) { r2 = tool.toNonExponential(arg2); } else { r2 = arg2.toString(); } try { t1 = r1.split(".")[1].length; } catch (e) {} try { t2 = r2.split(".")[1].length; } catch (e) {} r1 = Number(r1.replace(".", "")); r2 = Number(r2.toString().replace(".", "")); return tool.accMul(r1 / r2, Math.pow(10, t2 - t1)); } /** * js中浮点数运算 两个数相加 * @param {number} arg1 加数 * @param {number} arg2 被加数 * @returns {number} 两个数相加后处理精度问题的结果 */ static accAdd(arg1, arg2) { arg1 = tool.isNullOrEmpty(arg1) ? 0 : arg1; arg2 = tool.isNullOrEmpty(arg2) ? 0 : arg2; let r1, r2, m; try { let t = arg1; if (t.toString().includes("e-")) { t = tool.toNonExponential(t); } r1 = t.toString().split(".")[1].length; } catch (e) { r1 = 0; } try { let t = arg2; if (t.toString().includes("e-")) { t = tool.toNonExponential(t); } r2 = t.toString().split(".")[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); return (tool.accMul(arg1, m) + tool.accMul(arg2, m)) / m; } /** * js中浮点数运算 两个数相减 * @param {number} arg1 减数 * @param {number} arg2 被减数 * @returns {number} 两个数相减后处理精度问题的结果 */ static subtr(arg1, arg2) { arg1 = tool.isNullOrEmpty(arg1) ? 0 : arg1; arg2 = tool.isNullOrEmpty(arg2) ? 0 : arg2; let r1, r2, m, n; try { let t = arg1; if (t.toString().includes("e-")) { t = tool.toNonExponential(t); } r1 = t.toString().split(".")[1].length; } catch (e) { r1 = 0; } try { let t = arg2; if (t.toString().includes("e-")) { t = tool.toNonExponential(t); } r2 = t.toString().split(".")[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); n = r1 >= r2 ? r1 : r2; return ((tool.accMul(arg1, m) - tool.accMul(arg2, m)) / m).toFixed(n); } /** * 使用递归的方式实现数组、对象的深拷贝 * @param {object} obj 待拷贝的对象 * @param {Array} filterProArr 需要过滤的属性集合 * @return {object} 拷贝后的对象 */ static deepClone(obj, filterProArr = []) { let objClone = null; filterProArr = tool.isNullOrEmpty(filterProArr) ? [] : filterProArr; if (tool.isObject(obj)) { objClone = {}; } else if (tool.isArray(obj)) { objClone = []; } else { objClone = obj; return objClone; } //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝 if (obj && (typeof obj).toLowerCase() === "object") { for (let key in obj) { if (filterProArr.includes(key)) { continue; } if (obj[key] && (typeof obj[key]).toLowerCase() === "object") { objClone[key] = tool.deepClone(obj[key]); } else { objClone[key] = obj[key]; } } } return objClone; } /** * 合并对象数组 * @param {array} arr1 待合并数组1 * @param {array} arr2 待合并数组2 * @param {string} uniqueKey 区分对象数组是否重复的key名称 * @return {array} 合并后的数组 */ static combineArray(arr1, arr2, uniqueKey) { let allArr = []; arr1 = tool.isNullOrEmpty(arr1) ? [] : arr1; arr2 = tool.isNullOrEmpty(arr2) ? [] : arr1; uniqueKey = tool.isNullOrEmpty(uniqueKey) ? "" : uniqueKey; //若不需要判断重复 if (tool.isNullOrEmpty(uniqueKey)) { allArr = arr1.concat(arr2); return allArr; } //获取数组1中uniqueKey对应的值 let arr1KeyValueArray = []; for (let i = 0; i < arr1.length; i++) { let uniqueKeyValue = tool.isNullOrEmpty(arr1[i][uniqueKey]) ? "" : arr1[i][uniqueKey]; if (tool.isNullOrEmpty(uniqueKeyValue)) { continue; } arr1KeyValueArray.push(uniqueKeyValue); allArr.push(arr1[i]); } for (let i = 0; i < arr2.length; i++) { let uniqueKeyValue = tool.isNullOrEmpty(arr2[i][uniqueKey]) ? "" : arr2[i][uniqueKey]; if (tool.isNullOrEmpty(uniqueKeyValue)) { continue; } //是否存在相同的值 if (!arr1KeyValueArray.includes(uniqueKeyValue)) { allArr.push(arr2[i]); } } return allArr; } /** * 合并JSON对象 * @param {object} jObject1 对象1 * @param {object} jObjct2 对象2 * @param {boolean} [isOverwrite=true] 是否重写,默认true * @return {object} 合并后的对象 */ static combineJObject(jObject1, jObjct2, isOverwrite = true) { jObject1 = tool.isNullOrEmpty(jObject1) ? {} : jObject1; jObjct2 = tool.isNullOrEmpty(jObjct2) ? {} : jObjct2; Object.keys(jObjct2).forEach((key, index) => { if (jObject1.hasOwnProperty(key) && !isOverwrite) { return true; } jObject1[key] = jObjct2[key]; }); return jObject1; } /** * 获取Url上的域名 * @param {string} url url地址,如http://197.7.50.186:8866/crm/ApiHome/ApiAction,http://crmpc.calc.com.hk/crm/ApiHome/ApiAction,https://crmpc.calc.com.hk/crm/ApiHome/ApiAction * @return {string} 域名 */ static getDomain(url) { url = tool.isNullOrEmpty(url) ? "" : url; if (tool.isNullOrEmpty(url)) { return url; } let urlArr = url.split("//"); urlArr = tool.isNullOrEmpty(urlArr) ? [] : urlArr; if (urlArr.length != 2) { return url; } let protocol = urlArr[0]; let remainUrl = urlArr[1].substring(0, urlArr[1].indexOf("/")); url = `${protocol}//${remainUrl}`; return url; } /** * url合并 * @param {string} baseUrl 基地址 * @param {string} remainUrl 待合并地址 * @return {string} 合并后的地址 */ static combineUrl(baseUrl = "", remainUrl = "") { if (tool.isNullOrEmpty(baseUrl)) { return remainUrl; } if (tool.isNullOrEmpty(remainUrl)) { return baseUrl; } //移除最后的斜杆 if (baseUrl.lastIndexOf("/") == baseUrl.length - 1) { baseUrl = baseUrl.substring(0, baseUrl.length - 1); } //移除开头的斜杆 if (remainUrl.indexOf("/") == 0) { remainUrl = remainUrl.substring(1); } //移除最后的斜杆 if (remainUrl.lastIndexOf("/") == remainUrl.length - 1) { remainUrl = remainUrl.substring(0, remainUrl.length - 1); } //合并地址 return `${baseUrl}/${remainUrl}`; } /** * 获取url上的参数 * @param {string} url 地址 * @return {object} 参数对象 */ static getUrlParam(url) { let paramObj = {}; url = url || ""; const urlArr = url.split("?") || []; if (urlArr.length == 2) { url = urlArr[1]; } else { url = urlArr[0]; } const paramArr = url.split("&") || []; if (tool.isNullOrEmpty(paramArr)) { return paramObj; } paramObj = paramArr.reduce((obj, item, index) => { const [fieldName, fieldVal = ""] = item.split("=") || []; obj[fieldName] = fieldVal; return obj; }, {}) || {}; return paramObj; } /** * 将参数对象合并到url地址上 * @param {string} url 地址 * @param {object} paramObj 参数对象 * @param {object} isEncode 是否加密合并了参数后的地址,默认false * @return {string} 合并了参数后的地址 */ static setUrlParam(url, paramObj = {}, isEncode = false) { if (tool.isNullOrEmpty(url) || tool.isNullOrEmpty(paramObj)) { return tool.isNullOrEmpty(url) ? "" : url; } //构造参数字符串 let paramStr = Object.keys(paramObj).reduce((str, key, index) => { str += `${key}=${paramObj[key] || ""}&`; return str; }, "") || ""; paramStr = tool.isNullOrEmpty(paramStr) ? "" : paramStr.substring(0, paramStr.length - 1); //参数及地址合并 url = `${url}?${paramStr}`; url = isEncode ? encodeURIComponent(url) : url; return url; } /** * 将时间转换成所有平台都支持的时间格式 yyyy/MM/dd HH:mm:ss * @param {string} dateTimeStr 时间的字符串值 * @param {string} oldFormatStr 当前时间字符串的时间格式 * @return {string} 格式化的值 */ static getRightDateTimeStr(dateTimeStr, oldFormatStr) { let yearIndex = -1; let monthIndex = -1; let dayIndex = -1; let hourIndex = -1; let minuteIndex = -1; let secondIndex = -1; //分割时间格式化-,/,空格,: let dateTimeFormatStrArray = oldFormatStr.split(/-|:|\/|\s|年|月|日/g); //获取时间格式各个部分的索引 for (let i = 0; i < dateTimeFormatStrArray.length; i++) { if ( dateTimeFormatStrArray[i] == "yyyy" || dateTimeFormatStrArray[i] == "yy" ) { yearIndex = i; } else if ( dateTimeFormatStrArray[i] == "M" || dateTimeFormatStrArray[i] == "MM" || dateTimeFormatStrArray[i] == "MMM" || dateTimeFormatStrArray[i] == "MMMM" ) { monthIndex = i; } else if ( dateTimeFormatStrArray[i] == "d" || dateTimeFormatStrArray[i] == "dd" || dateTimeFormatStrArray[i] == "ddd" || dateTimeFormatStrArray[i] == "dddd" ) { dayIndex = i; } else if ( dateTimeFormatStrArray[i] == "h" || dateTimeFormatStrArray[i] == "hh" || dateTimeFormatStrArray[i] == "H" || dateTimeFormatStrArray[i] == "HH" ) { hourIndex = i; } else if ( dateTimeFormatStrArray[i] == "m" || dateTimeFormatStrArray[i] == "mm" ) { minuteIndex = i; } else if ( dateTimeFormatStrArray[i] == "s" || dateTimeFormatStrArray[i] == "ss" ) { secondIndex = i; } else { continue; } } //拼装时间 let dateStrArray = dateTimeStr.split(/-|:|\/|\s|年|月|日/g); //若解析不到小时,则直接返回 if (hourIndex <= -1 || tool.isNullOrEmpty(dateStrArray[hourIndex])) { return `${dateStrArray[yearIndex]}/${dateStrArray[monthIndex]}/${ dateStrArray[dayIndex] <= -1 ? "01" : dateStrArray[dayIndex] }`; } //若秒为空或者解析不到秒 if (secondIndex <= -1 || tool.isNullOrEmpty(dateStrArray[secondIndex])) { return `${dateStrArray[yearIndex]}/${dateStrArray[monthIndex]}/${ dateStrArray[dayIndex] <= -1 ? "01" : dateStrArray[dayIndex] } ${dateStrArray[hourIndex]}:${dateStrArray[minuteIndex]}`; } return `${dateStrArray[yearIndex]}/${dateStrArray[monthIndex]}/${ dateStrArray[dayIndex] <= -1 ? "01" : dateStrArray[dayIndex] } ${dateStrArray[hourIndex]}:${dateStrArray[minuteIndex]}:${ dateStrArray[secondIndex] }`; } /** * 填充指定字符 * @param {string} value 待填充的字符串 * @param {string} length 总长度,默认0 * @param {string} padStr 填充用的字符 * @param {string} isPadLeft 是否左填充,默认true * @return {string} 填充后的字符串 */ static padString(value, length = 0, padStr = "0", isPadLeft = true) { if (length <= 0) { return value; } if (tool.isNullOrEmpty(value)) { value = ""; } value = new String(value); value = isPadLeft ? value.padStart(length, padStr) : value.padEnd(length, padStr); return value; } /** * 将Date对象按照给定的格式进行格式化,返回格式化后的字符串 * @param {date} date 待格式化的Date对象 * @param {string} dateTimeFormatStr 新的时间格式 * @return {string} 格式化后的字符串 */ static formatDate(date, dateTimeFormatStr) { if (tool.isNullOrEmpty(date)) { return ""; } if (typeof date != "object") { return date; } if (tool.isNullOrEmpty(dateTimeFormatStr)) { return date; } return dateTimeFormatStr.replace( /"[^"]*"|'[^']*'|\b(?:d{1,4}|M{1,4}|yy(?:yy)?|([hHmstT])\1?|[lLZ])\b/g, function ($0) { switch ($0) { case "d": return date.getDate(); case "dd": return tool.padString(date.getDate(), 2); case "ddd": return ["Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"][ date.getDay() ]; case "dddd": return [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", ][date.getDay()]; case "M": return date.getMonth() + 1; case "MM": return tool.padString(date.getMonth() + 1, 2); case "MMM": return [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ][date.getMonth()]; case "MMMM": return [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ][date.getMonth()]; case "yy": return new String(date.getFullYear()).substr(2); case "yyyy": return date.getFullYear(); case "h": return date.getHours() % 12 || 12; case "hh": return tool.padString(date.getHours() % 12 || 12, 2); case "H": return date.getHours(); case "HH": return tool.padString(date.getHours(), 2); case "m": return date.getMinutes(); case "mm": return tool.padString(date.getMinutes(), 2); case "s": return date.getSeconds(); case "ss": return tool.padString(date.getSeconds(), 2); case "l": return date.getMilliseconds(); case "ll": return tool.padString(date.getMilliseconds(), 2); case "tt": return date.getHours() < 12 ? "am" : "pm"; case "TT": return date.getHours() < 12 ? "AM" : "PM"; } } ); } /** * 将时间字符串按照新的格式进行格式化,得到格式化后的字符串 * @param {string} value 待格式化的时间字符串值 * @param {string} newFormatStr 新的时间格式 * @param {string} oldFormatStr value的时间格式,默认yyyy-MM-dd HH:mm:ss * @return {string} 格式化后的字符串 */ static changeDateTimeFormat( value, newFormatStr, oldFormatStr = "yyyy-MM-dd HH:mm:ss" ) { if ( tool.isNullOrEmpty(value) || tool.isNullOrEmpty(newFormatStr) || tool.isNullOrEmpty(oldFormatStr) ) { return ""; } //移除掉字符串中的T value = value.replace("T", " "); //移除掉字符串中的.及后面的数字 if (value.indexOf(".") >= 0) { value = value.split(".")[0]; } //1>将传入的时间转换成通用时间对象 let dateTemp = new Date(tool.getRightDateTimeStr(value, oldFormatStr)); //2>将通用时间对象转换成新的时间格式 value = tool.formatDate(dateTemp, newFormatStr); return value; } /** * 计算时间 * @param {date} handleDate 待操作的时间 * @param {number} year 需要增加的年数 * @param {number} month 需要增加的月数 * @param {number} day 需要增加的天数 * @param {boolean} isFormat 是否需要格式化。False:返回Date类型的值;True:返回格式化后的字符串 * @param {string} dateTimeFormatStr 新的时间格式 * @return {date|string} 格式化后的字符串 */ static calcDate( handleDate, year, month, day, isFormat = false, dateTimeFormatStr = "" ) { if (handleDate == null || handleDate == undefined) { return null; } if (year != null && year != undefined) { handleDate.setFullYear(handleDate.getFullYear() + year); } if (month != null && month != undefined) { handleDate.setMonth(handleDate.getMonth() + month); } if (day != null && day != undefined) { handleDate.setDate(handleDate.getDate() + day); } isFormat = isFormat == undefined || isFormat == null ? false : isFormat; if (!isFormat || tool.isNullOrEmpty(dateTimeFormatStr)) { return handleDate; } return tool.formatDate(handleDate, dateTimeFormatStr); } /** * 枚举开始日期到结束日期之间的所有日期 * @param {date} startDate 开始日期 * @param {date} endDate 结束日期 * @param {string} formatStr 格式化字符串 * @return {array<string>} 日期集合 */ static enumerateDates( startDate, endDate, formatStr = constant.format_CommonDate ) { let dateArr = []; if (!startDate || !endDate) { return dateArr; } let curDate = startDate; while (curDate <= endDate) { dateArr.push(tool.formatDate(curDate, formatStr)); curDate = tool.calcDate(curDate, 0, 0, 1, false); } return dateArr; } /** * 生成时间戳 * @param {boolean} isMillisecond 是否毫秒格式,默认为true * @return {number} 时间戳 */ static generateTimeStamp(isMillisecond = true) { return isMillisecond ? new Date().getTime() : new Date().getTime() / 1000; } /** * 生成guid * @return {string} guid */ static generateGUID() { let guidStr = ""; if (!guid) { guidStr = ""; console.error(`guid is null!`); return false; } const guidIns = new guid(); guidStr = guidIns.newGUID(); return guidStr; } /** * 将字符串进行md5签名 * @return {string} 待签名的值 */ static createMD5(val) { let md5Str = ""; if (!md5) { md5Str = ""; console.error(`md5 is null!`); return false; } md5Str = md5(val); return md5Str; } /** * 文件的字节数转化为其它合适的单位数量 * @param {number} size 文件byte大小 * @param {number} n 小数位个数 * @return {string} 格式化后的内容 */ static fileSizeFormat(size = 0, n = 2) { size = Number(size); let unit = "B"; let ks = size; if (size < 1024) { return size + unit; } ks = size / 1024; unit = "KB"; if (ks >= 1024) { ks = ks / 1024; unit = "MB"; } if (ks >= 1024) { ks = ks / 1024; unit = "GB"; } if (ks >= 1024) { ks = ks / 1024; unit = "TB"; } return ks.toFixed(n) + unit; } /** * 获取不含后缀的文件名 * @param {string} fileName 源文件名 * @return {string} 文件名 */ static getFileNameWithoutExtension(fileName) { if (tool.isNullOrEmpty(fileName)) { return fileName; } //文件名不含. if (fileName.indexOf(".") <= -1) { return fileName; } return fileName.substring(0, fileName.lastIndexOf(".")); } /** * 替换新的文件名后缀 * @param {string} fileName 源文件名 * @param {string} extension 新的文件名后缀 * @return {string} 文件名 */ static changeFileNameExtension(fileName, extension = "") { if (tool.isNullOrEmpty(fileName) || tool.isNullOrEmpty(extension)) { return fileName; } return `${tool.getFileNameWithoutExtension(fileName)}.${extension}`; } /** * 获取文件名后缀(不含.) * @param {string} fileName 文件名 * @param {boolean} isToLowerCase 是否将结果转成小写,默认为false * @return {string} 文件名后缀 */ static getFileExtension(fileName = "", isToLowerCase = false) { let fileExtension = ""; if (tool.isNullOrEmpty(fileName)) { return fileExtension; } if (fileName.lastIndexOf(".") <= -1) { return fileExtension; } fileName = fileName.trim(); fileExtension = fileName.substring( fileName.lastIndexOf(".") + 1, fileName.length ); if (isToLowerCase) { fileExtension = fileExtension.toLowerCase(); } return fileExtension; } /** * @type {array} * @description 图片文件后缀 */ static imgFileExtensionArr = ["bmp", "jpg", "jpeg", "png", "gif"]; /** * 指定的文件名是否图片文件 * @param {string} fileName 文件名 * @return {boolean} 是否图片文件 */ static isFileImage(fileName) { if (tool.isNullOrEmpty(fileName)) { return false; } //获取文件名后缀 let fileExtension = tool.getFileExtension(fileName, true); if (tool.isNullOrEmpty(fileExtension)) { return false; } return tool.imgFileExtensionArr.includes(fileExtension); } /** * @type {array} * @description 视频文件后缀 */ static videoFileExtensionArr = [ "ogg", "mpeg4", "webm", "mp4", "mov", "avi", "wmv", "3gp", "mkv", "flv", "rmvb", ]; /** * 指定的文件名是否视频文件 * @param {string} fileName 文件名 * @return {boolean} 是否视频文件 */ static isFileVideo(fileName) { if (tool.isNullOrEmpty(fileName)) { return false; } //获取文件名后缀 let fileExtension = tool.getFileExtension(fileName, true); if (tool.isNullOrEmpty(fileExtension)) { return false; } return tool.videoFileExtensionArr.includes(fileExtension); } /** * @type {array} * @description 文本文件后缀 */ static txtExtensionArr = [ "txt", "js", "sql", "cs", "jsp", "php", "class", "md", ]; /** * 指定的文件名是否文本文件 * @param {string} fileName 文件名 * @return {boolean} 是否文本文件 */ static isTxt(fileName) { if (tool.isNullOrEmpty(fileName)) { return false; } //获取文件名后缀 let fileExtension = tool.getFileExtension(fileName, true); if (tool.isNullOrEmpty(fileExtension)) { return false; } return tool.txtExtensionArr.includes(fileExtension); } /** * @type {array} * @description office文件后缀 */ static officeFileTypeArr = [ "xls", "xlsx", "doc", "docx", "ppt", "pptx", "csv", ]; /** * 指定的文件名是否office文件 * @param {string} fileName 文件名 * @return {boolean} 是否文本文件 */ static isOffice(fileName) { if (tool.isNullOrEmpty(fileName)) { return false; } //获取文件名后缀 let fileExtension = tool.getFileExtension(fileName, true); if (tool.isNullOrEmpty(fileExtension)) { return false; } return tool.officeFileTypeArr.includes(fileExtension); } /** * @type {array} * @description 可转换成pdf文件的文件后缀 */ static canChange2PdfFileExtensionArr = [ "xls", "xlsx", "doc", "docx", "ppt", "pptx", "txt", "pdf", ]; /** * 指定的文件名是否可转换成pdf文件 * @param {string} fileName 文件名 * @return {boolean} 是否可转换成pdf文件 */ static isFileCanChange2Pdf(fileName) { if (tool.isNullOrEmpty(fileName)) { return false; } //获取文件名后缀 let fileExtension = tool.getFileExtension(fileName, true); if (tool.isNullOrEmpty(fileExtension)) { return false; } return tool.canChange2PdfFileExtensionArr.includes(fileExtension); } /** * base64转Blob对象 * @param {string} base64Str 文件base64字符串 * @return {Blob} Blob对象 */ static base64ToBlob(base64Str) { if (tool.isNullOrEmpty(base64Str)) { return; } //Base64一行不能超过76字符,超过则添加回车换行符。因此需要把base64字段中的换行符,回车符给去掉,有时候因为存在需要把加号空格之类的换回来,取决于base64存取时的规则。 base64Str = base64Str.replace(/[\n\r]/g, ""); let raw = window.atob(base64Str); let rawLength = raw.length; //转换成pdf.js能直接解析的Uint8Array类型 let uInt8Array = new Uint8Array(rawLength); for (let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], { type: "application/pdf" }); //转成pdf类型 } /** * web环境下, 下载文件 * 支持下载全部类型的文件 * @return {void} */ static downloadFileEntrance() { //1>获取相关参数, 通过arguments实现函数多态 let argCount = arguments.length; let blobType = ""; let fileExtension = ""; let stream = null; let fileName = ""; let isAddTime2FileName = false; if (argCount == 4) { let exportFileType = arguments[0]; stream = arguments[1]; fileName = arguments[2]; isAddTime2FileName = arguments[3]; if (exportFileType == constant.exportFileType_Excel) { blobType = "application/vnd.ms-excel"; fileExtension = "xls"; } else if (exportFileType == constant.exportFileType_ExcelPlus) { blobType = "application/vnd.ms-excel"; fileExtension = "xlsx"; } else if (exportFileType == constant.exportFileType_PDF) { blobType = "application/pdf"; fileExtension = "pdf"; } else { throw `Not supported exportFileType:${exportFileType}!`; } } else if (argCount == 3) { stream = arguments[0]; fileName = arguments[1]; isAddTime2FileName = arguments[2]; //获取文件后缀 fileExtension = tool.getFileExtension(fileName, true); fileExtension = tool.isNullOrEmpty(fileExtension) ? "" : fileExtension; if (tool.isNullOrEmpty(fileExtension)) { throw `File (${fileName}) should have extension!`; } //获取不含后缀的文件名 fileName = tool.getFileNameWithoutExtension(fileName); } else { throw `Not supported params!`; } isAddTime2FileName = tool.isNullOrEmpty(isAddTime2FileName) ? false : isAddTime2FileName; if (tool.isNullOrEmpty(fileName)) { throw "File name is null or empty!"; } if (tool.isNullOrEmpty(fileExtension)) { throw "File extension is null or empty!"; } if (stream == null || stream == undefined) { throw "Stream is null!"; } //2>处理文件名 //需要添加时间戳 if (isAddTime2FileName) { let now = new Date(); let dateStr = `${now.getFullYear()}${(now.getMonth() + 1) .toString() .padStart(2, "0")}${now.getDate().toString().padStart(2, "0")}${now .getHours() .toString() .padStart(2, "0")}${now.getMinutes().toString().padStart(2, "0")}${now .getSeconds() .toString() .padStart(2, "0")}`; fileName = `${fileName}_${dateStr}.${fileExtension}`; } else { //不需要添加时间戳 fileName = `${fileName}.${fileExtension}`; } //3>处理文件流 let blob = null; if (tool.isNullOrEmpty(blobType)) { blob = new Blob([stream]); } else { blob = new Blob([stream], { blobType, }); } //4>导出文件 tool.downloadFile(blob, fileName); } /** * web环境下,下载文件 * @param {blob} blob blob类型的数据 * @param {blob} fileName 文件名 * @return {boolean} 执行结果 */ static downloadFile(blob, fileName) { if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveBlob(blob, fileName); } else { let link = document.createElement("a"); link.href = window.URL.createObjectURL(blob); link.download = fileName; link.style.display = "none"; // 让a标签不显示 link.click(); //释放内存, 释放一个之前已经存在的, 通过调用 URL.createObjectURL() 创建的URL对象 window.URL.revokeObjectURL(link.href); } } /** * 获取数据集合中指定属性的最大值 * @param {array} arr 数据集合 * @param {string} property 属性名称 * @return {number} 执行结果 */ static getMaxVal(arr = [], property = "") { let val = 0; if (tool.isNullOrEmpty(arr) || tool.isNullOrEmpty(property)) { return val; } arr.forEach((item, index) => { const valTemp = tool.isNullOrEmpty(item[property]) ? 0 : item[property]; if (valTemp > val) { val = valTemp; } }); return val; } /** * 数组重新排序 * @param {array} arr 待排序的数组 * @param {string} property 排序字段 * @param {string} disabledProperty 标识属性是否禁用的字段 * @return {array} 重新排序后的数组 */ static resortArr(arr = [], property = "", disabledProperty = "") { let arrNew = tool.deepClone(arr); if ( tool.isNullOrEmpty(arr) || tool.isNullOrEmpty(property) || tool.isNullOrEmpty(disabledProperty) ) { return arrNew; } arrNew = ( arrNew.filter((item, index) => { return ( (tool.isNullOrEmpty(item[disabledProperty]) ? false : item[disabledProperty]) == true ); }) || [] ).concat( arrNew.filter((item, index) => { return ( (tool.isNullOrEmpty(item[disabledProperty]) ? false : item[disabledProperty]) == false ); }) || [] ); arrNew.forEach((item, index) => { item[property] = index + 1; }); return arrNew; } /** * 浏览器上打开新的tab页 * https://www.cnblogs.com/carekee/articles/2094724.html * @param {string} url * @param {string} name * @param {object} optObj * @return {void} */ static openUrl(url, name, optObj = {}) { if (tool.isNullOrEmpty(url)) { return false; } name = name || "blank"; optObj = optObj || {}; if (tool.isNullOrEmpty(optObj)) { window.open(url, name); } else { window.open(url, name, optObj); } } static mobileRE = /(android|bb\d+|meego).+mobile|armv7l|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series[46]0|samsungbrowser.*mobile|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i; static notMobileRE = /CrOS/; static tabletRE = /android|ipad|playbook|silk/i; /** * 通过UA判断当前环境是否移动端 * @param {object} opts 参数对象 * @param {string} opts.ua UA标识, 若不传, 则使用navigator.userAgent * @param {boolean} opts.tablet * @return {void} */ static isMobile(opts) { if (!opts) opts = {}; let ua = opts.ua; if (!ua && typeof navigator !== "undefined") ua = navigator.userAgent; if (ua && ua.headers && typeof ua.headers["user-agent"] === "string") { ua = ua.headers["user-agent"]; } if (typeof ua !== "string") return false; let result = (tool.mobileRE.test(ua) && !tool.notMobileRE.test(ua)) || (!!opts.tablet && tool.tabletRE.test(ua)); if ( !result && opts.tablet && opts.featureDetect && navigator && navigator.maxTouchPoints > 1 && ua.indexOf("Macintosh") !== -1 && ua.indexOf("Safari") !== -1 ) { result = true; } return result; } //#endregion //#region 页面公共操作 /** * 获取具名插槽对象 * @param {jsx|array<jsx>} children jsx数组 * @return {object} 组件库对象 */ static getNamedSlots(children) { const slotChildren = tool.isArray(children) ? children : [children]; const slotChildrenObj = slotChildren.reduce((slotObj, item, index) => { if (!item) { return slotObj; } let { slot = "" } = item.props; // 若没有配置插槽名称, 则为默认插槽, 设置插槽名称为default if (tool.isNullOrEmpty(slot)) { slot = "default"; } slotObj[slot] = item; return slotObj; }, {}) || {}; return slotChildrenObj; } // /** // * 修改缓存的语言版本 // * @param {number|string} lv 需要设置的语言版本 // * @return {object} 组件库对象 // */ // static setCacheLV(lv = 7) { // // console.log(`setCacheLV`, lv); // lv = parseInt(lv); // const lvStr = lv.toString(); // // login - langId, string // const loginObj = // tool.getLocalStorageItem(constant.cacheKey_login, true) || {}; // loginObj["langId"] = lvStr; // tool.setLocalStorageItem(constant.cacheKey_login, loginObj); // // languageidweaver, number // tool.setLocalStorageItem(constant.cacheKey_languageidweaver, lv); // // getOsInfo - languageType, string // const getOsInfoObj = // tool.getLocalStorageItem(constant.cacheKey_getOsInfo, true) || {}; // getOsInfoObj["languageType"] = lvStr; // tool.setLocalStorageItem(constant.cacheKey_getOsInfo, getOsInfoObj); // // e9_locale - userLanguage, string // const e9_localeObj = // tool.getLocalStorageItem(constant.cacheKey_e9_locale, true) || {}; // getOsInfoObj["userLanguage"] = lvStr; // tool.setLocalStorageItem(constant.cacheKey_e9_locale, e9_localeObj); // // theme-account - userLanguage, string // const theme_accountObj = // tool.getLocalStorageItem(constant.cacheKey_theme_account, true) || {}; // getOsInfoObj["userLanguage"] = lvStr; // tool.setLocalStorageItem(constant.cacheKey_theme_account, theme_accountObj); // } // /** // * 获取缓存的当前多语言版本 // * @return {number} 当前多语言版本 // */ // static getCacheLV() { // const curLV = parseInt( // ( // tool.getLocalStorageItem(constant.cacheKey_languageidweaver, false) || 7 // ).toString() // ); // return curLV; // } // /** // * 获取对应语言版本的通用多语言对象 // * @return {number} 对应语言版本的通用多语言对象 // */ // static getLVObj() { // const lvObj = (constant.lvObj || {})[tool.getCacheLV()] || {}; // return lvObj; // } //#endregion //#region 组件封装 //#region antd /** * 显示全屏loading * @param {string} loadingText lading文本 * @param {number} duration 延迟时间, 默认0, 不消失 * @return {function} 关闭loading的回调函数 */ static showLoading(loadingText = "Executing, please wait...", duration = 0) { // console.log(`showLoading`); if (tool.isNullOrEmpty(loadingText) || !tool.thirdPartyLib_Antd) { return false; } const hideFunc = tool.thirdPartyLib_Antd.message.loading( loadingText, duration ); return hideFunc; } /** * 隐藏loading * @param {string} loadingText lading文本 * @param {number} duration 延迟时间, 默认0, 不消失 * @return {function} 关闭loading的回调函数 */ static hideLoading(hideFunc) { if (hideFunc) { hideFunc(); return; } if (!tool.thirdPartyLib_Antd) { return false; } // 全局销毁message tool.closeMessage(); } /** * 显示普通message * @param {string} msg 提示消息 * @param {number} duration 延迟时间 * @return {void} */ static showInfoMsg(msg = "", duration = 2) { if (tool.isNullOrEmpty(msg) || !tool.thirdPartyLib_Antd) { return false; } tool.thirdPartyLib_Antd.message.info(msg, duration); } /** * 显示成功message * @param {string} msg 提示消息 * @param {number} duration 延迟时间 * @return {void} */ static showSuccessMsg(msg = "", duration = 3) { if (tool.isNullOrEmpty(msg) || !tool.thirdPartyLib_Antd) { return false; } tool.thirdPartyLib_Antd.message.success(msg, duration); } /** * 显示成功message * @param {string} msg 提示消息 * @param {number} duration 延迟时间 * @return {void} */ static showWarnMsg(msg = "", duration = 3) { if (tool.isNullOrEmpty(msg) || !tool.thirdPartyLib_Antd) { return false; } tool.thirdPartyLib_Antd.message.warning(msg, duration); } /** * 显示错误message * @param {string} msg 提示消息 * @param {number} duration 延迟时间 * @return {void} */ static showErrorMsg(msg = "", duration = 3) { if (tool.isNullOrEmpty(msg) || !tool.thirdPartyLib_Antd) { return false; } tool.thirdPartyLib_Antd.message.error(msg, duration); } /** * 关闭消息 * @return {void} */ static closeMessage() { if (!tool.thirdPartyLib_Antd) { return false; } tool.thirdPartyLib_Antd.message.destroy(); } //#endre