UNPKG

abbott-methods

Version:

abbott,methods,method,functions,function

1,635 lines (1,535 loc) 127 kB
/** * @description 是否array类型 * @param {*} typeValue * @returns {Boolean} */ const typeArray = (typeValue) => Object.prototype.toString.call(typeValue).toLowerCase() === '[object array]'; /** * @description 相加 * @param calcArray * @returns {[]} */ const calcSum = (calcArray) => { if (typeArray(calcArray) && calcArray.length > 0) { return calcArray.reduce((total, current) => { let oneLen, twoLen; try { oneLen = total.toString().split('.')[1].length; } catch (e) { oneLen = 0; } try { twoLen = current.toString().split('.')[1].length; } catch (e) { twoLen = 0; } const number = Math.pow(10, Math.max(oneLen, twoLen)); return (total * number + current * number) / number; }); } else { return 0; } }; /** * @description 获取当前网址 * @returns {string} */ const addressBarCurrent = () => location.href; /** * @description 获取页面所在路径 * @returns {string} */ const addressBarFilePath = () => location.pathname; /** * @description 获取页面的来源 * @returns {string} */ const addressBarFrom = () => document.referrer; /** * @description 获取网址#号后的参数 * @returns {string} */ const addressBarHash = () => location.hash.slice(1); /** * @description 获取http(s) * @returns {string} */ const addressBarHttp = () => document.location.protocol === 'https:' ? 'https://' : 'http://'; /** * @description 获取域名:端口 * @returns {string} */ const addressBarHost = () => location.host; /** * @description 获取http(s)://域名:端口 * @returns {string} */ const addressBarHead = () => `${addressBarHttp()} + ${addressBarHost()}`; /** * @description 获取域名 * @returns {string} */ const addressBarName = () => location.hostname; /** * @description 获取端口 * @returns {string} */ const addressBarPort = () => location.port; /** * @description 获取参数 * @returns {string} */ const addressBarQuery = () => location.search.substr(1); /** * @description 清除键值-单层 * @param {[]|{}} ao array或object * @returns {[]} */ const aoCleanKeyOne = (ao) => { const result = []; for (const key in ao) { result.push(ao[key]); } return result; }; /** * @description 切片存储在一个新数组 * @param {[]|{}} ao array或object * @param {number} size 每个切片的大小 * @returns {[]} */ const aoChunk = (ao, size) => { const array = typeArray(ao) ? ao : aoCleanKeyOne(ao); const length = array.length; size = ~~Math.abs(+size); if (length < 1 || size < 1) { return []; } else { let index = 0; let resIndex = 0; const result = new Array(Math.ceil(length / size)); while (index < length) { result[resIndex++] = array.slice(index, (index += size)); } return result; } }; /** * @description 是否object类型 * @param {*} typeValue * @returns {Boolean} */ const typeObject = (typeValue) => Object.prototype.toString.call(typeValue).toLowerCase() === '[object object]'; /** * @desc 清除键值-全部 * @param {[]|{}} ao array或object * @returns {[]} */ const aoCleanKeyAll = (ao) => { const result = []; let count = 0; for (const key in ao) { result[count] = typeArray(ao[key]) || typeObject(ao[key]) ? aoCleanKeyAll(ao[key]) : ao[key]; count++; } return result; }; /** * @description 是否值在ao中 * @param {[]|{}} ao array或object * @param {*} aoSearch 要搜索的值 * @param {boolean} [aoMatchCase] 是否匹配大小写,true为匹配,false为不匹配,默认为不匹配 * @returns {boolean} */ const aoWhetherIn = (ao, aoSearch, aoMatchCase = false) => { const newArray = aoCleanKeyOne(ao); // 函数 some 不能循环 json 类型,统一转成数组 return newArray.some((key) => { let a = JSON.stringify(key); let b = JSON.stringify(aoSearch); if (!aoMatchCase) { a = a.toLowerCase(); b = b.toLowerCase(); } return a === b; }); }; /** * @description 删除空值以及指定的值 * @param {[]|{}} ao array或object * @param {[]|{}} aoAssign 现在仅设置为不等于空字符,其它条件可额外增加,如:[null,undefined] * @returns {[]|{}} */ const aoDeleteEmpty = (ao, aoAssign) => { const aoAssignAry = (typeArray(aoAssign) ? aoAssign : [aoAssign]); const result = typeArray(ao) ? [] : {}; for (const key in ao) { if (!(ao[key] === '' || aoWhetherIn(aoAssignAry, ao[key], false))) { typeArray(ao) ? result.push(ao[key]) : (result[key] = ao[key]); } } return result; }; /** * @description 删除键 * @param {[]|{}} ao array或object * @param {[]|string} aoKey 要删除的键,可字符或数组 * @returns {[]|{}} */ const aoDeleteKey = (ao, aoKey) => { const aoKeyAry = (typeArray(aoKey) ? aoKey : [aoKey]); const result = typeArray(ao) ? [] : {}; for (const i in ao) { if (!aoWhetherIn(aoKeyAry, i, false)) { typeArray(ao) ? result.push(ao[i]) : (result[i] = ao[i]); } } return result; }; /** * @description 删除值 * @param {[]|{}} ao array或object * @param {*} aoValue 要删除的值 * @returns {[]|{}} */ const aoDeleteValue = (ao, aoValue) => { const aoValueAry = (typeArray(aoValue) ? aoValue : [aoValue]); const result = typeArray(ao) ? [] : {}; for (const i in ao) { if (!aoWhetherIn(aoValueAry, ao[i], true)) { typeArray(ao) ? result.push(ao[i]) : (result[i] = ao[i]); } } return result; }; /** * @description 键名 * @param {[]|{}} ao array或object * @returns {[]} */ const aoKeyName = (ao) => { const result = []; for (const key in ao) { result.push(key); } return result; }; /** * @description 保留键,其它删除 * @param {[]|{}} ao array或object * @param {[]|string} aoHold 要保留的键,可字符或数组 * @returns {[]|{}} */ const aoHoldKey = (ao, aoHold) => { const aoHoldAry = (typeArray(aoHold) ? aoHold : [aoHold]); const keyArray = aoKeyName(ao); const result = typeArray(ao) ? [] : {}; for (const key in aoHoldAry) { if (aoWhetherIn(keyArray, aoHoldAry[key], false)) { typeArray(ao) ? result.push(ao[aoHoldAry[key]]) : (result[aoHoldAry[key]] = ao[aoHoldAry[key]]); } } return result; }; /** * @description 保留值,其它删除 * @param {[]|{}} ao array或object * @param {*} aoValue 要保留的值,可字符或数组 * @returns {[]|{}} */ const aoHoldValue = (ao, aoValue) => { aoValue = typeArray(aoValue) ? aoValue : [aoValue]; const result = typeArray(ao) ? [] : {}; for (const k in aoValue) { for (const e in ao) { if (JSON.stringify(aoValue[k]) === JSON.stringify(ao[e])) { typeArray(ao) ? result.push(ao[e]) : (result[e] = ao[e]); } } } return result; }; /** * @description 随机取ao中number个值 * @param {[]|{}} ao array或object * @param {number} number 取几个 * @returns {[]} */ const aoRandom = (ao, number) => { number = ~~Math.abs(number); const array = aoCleanKeyOne(ao); const result = []; for (let i = 0; i < number && array.length > 0; i++) { const r = Math.floor(Math.random() * array.length); result[i] = array[r]; array.splice(r, 1); } return result; }; /** * @description 随机生成ao中的值并排队行列 * @param {[]|{}} ao array或object * @param {number} rows 几行 * @param {number} columns 几列 * @returns {[]} */ const aoRandomRAC = (ao, rows, columns) => { const result = []; for (let i = 0; i < rows; i++) { const item = []; for (let e = 0; e < columns; e++) { const value = aoRandom([75, 80, 85], 1); item.push(value[0]); } result.push(item); } return result; }; /** * @description 重复值 * @param {[]|{}} ao array或object * @param {number} number 选项:1:不重复值的ao,2:不重复的键值,3:重复的键值 * @returns {[]|{}} */ const aoRepeat = (ao, number) => { number = ~~Math.abs(number); const a = typeArray(ao) ? [] : {}; const b = []; const c = []; for (const key in ao) { if (aoWhetherIn(a, ao[key], false)) { c.push(key); } else { b.push(key); typeArray(ao) ? a.push(ao[key]) : (a[key] = ao[key]); } } return +number === 1 ? a : +number === 2 ? b : c; }; /** * @description 反序 * @param {[]|{}} ao array或object * @returns {[]|{}} */ const aoReverse = (ao) => { const result = typeArray(ao) ? [] : {}; const keyArray = aoKeyName(ao); keyArray.reverse(); for (const key in keyArray) { typeArray(ao) ? result.push(ao[keyArray[key]]) : (result[keyArray[key]] = ao[keyArray[key]]); } return result; }; /** * @description 迪卡尔积 * @example arrayDiKaErJi([1,2,3],[1,2,3],[1,2,3]) * @returns {[]} */ const arrayDiKaErJi = (...arrayAny) => arrayAny.reduce((total, current) => { const ret = []; total.forEach((a) => { current.forEach((b) => { ret.push(a.concat([b])); }); }); return ret; }, [[]]); /** * 将多层级的数组扁平化 * @param {[]} arrayAny * @returns {[]} */ const arrayFlatten = (arrayAny) => { while (arrayAny.some((item) => Array.isArray(item))) { arrayAny = [].concat(...arrayAny); } return arrayAny; }; /** * @description 判断要查询的数组是否至少有一个元素包含在目标数组中 * @param {[]} arrayAny 需要查询的数组 * @param {[]} arrayTar 目标数组 */ const arrayHasOne = (arrayAny, arrayTar) => { return arrayTar.some((value) => arrayAny.indexOf(value) > -1); }; /** * @param {[]} arrayAny1 * @param {[]} arrayAny2 * @description 得到两个数组的交集, 两个数组的元素为数值或字符串 */ const arrayIntersection = (arrayAny1, arrayAny2) => { const len = Math.min(arrayAny1.length, arrayAny2.length); let i = -1; const res = []; while (++i < len) { const item = arrayAny2[i]; if (arrayAny1.indexOf(item) > -1) { res.push(item); } } return res; }; /** * @description 是否number类型 * @param {*} typeValue * @returns {Boolean} */ const typeNumber = (typeValue) => typeof typeValue === 'number' || (!isNaN(typeValue) && typeof typeValue === 'string'); /** * @description 排序数组 * @param {[]} arrayAny 要排序的数组 * @param {boolean} [arrayOrder] 排序方式:(true)从小到大,(false)从大到小 * @returns {[]} */ const arrayOrder = (arrayAny, arrayOrder) => { const ary = [...arrayAny]; ary.sort(function (a, b) { a = typeNumber(a) ? +a : a; b = typeNumber(b) ? +b : b; return a > b ? 1 : -1; }); return arrayOrder ? ary : ary.reverse(); }; /** * @description 根据字段进行arrayAny的排序 * @param {[]} arrayAny 必须是[[],[],...]或[{},{},...]的形式 * @param {number|string} arrayField 字段名字:如果是 arrayAny 时,请用 arrayAny 的下标 * @param {boolean} [arrayOrder] 排序顺序:(true)从小到大,(false)从大到小 * @returns {[]} * @example arrayOrderByField([[1, "a", 9], [2, "b", 8], [3, "c", 7], [4, "d", 6]], 1, false) * @example arrayOrderByField([{"a": 3}, {"a": 2}, {"a": 1}], "a") */ const arrayOrderByField = (arrayAny, arrayField, arrayOrder) => { const result = arrayAny.sort(function (a, b) { const x = a[arrayField]; const y = b[arrayField]; return x < y ? -1 : x > y ? 1 : 0; }); return arrayOrder ? result : aoReverse(result); }; /** * @description 获取arrayAny的xy等比对换 * @param {[]} arrayAny [[],[],...] * @returns {[]} * @example arrayAnyRatioReplace([[1,'a'],[2,'b'],[3,'c'],[4,'d']]) */ const arrayRatioReplace = (arrayAny) => { const result = []; let count = 0; for (let o = 0; o < length; o++) { if (count < arrayAny[o].length) { count = arrayAny[o].length; } } for (let t = 0; t < count; t++) { const ary = []; for (let i = 0; i < length; i++) { // eslint-disable-next-line no-void arrayAny[i][t] === void 0 && (arrayAny[i][t] = ''); ary.push(arrayAny[i][t]); } result.push(ary); } return result; }; /** * @description 以assign分隔arrayAny组成新的string * @param {[]} arrayAny 要分隔的数组 * @param {string} char * @returns {String} */ const arrayToStringChar = (arrayAny, char) => arrayAny.join(String(char)); /** * @description 得到两个数组的并集 * @param {[]} arrayAny1 * @param {[]} arrayAny2 */ const arrayUnion = (arrayAny1, arrayAny2) => { return Array.from(new Set([...arrayAny1, ...arrayAny2])); }; /** * @description 值是否在数组中 * @param {[]} arrayAny 用来验证的列表 * @param {*} value 要验证的值 * @return {Boolean} */ const arrayWhetherIn = (arrayAny, value) => { for (let i = 0; i < arrayAny.length; i++) { if (value === arrayAny[i]) { return true; } } return false; }; /** * @description 浏览器代理信息 * @returns {String} */ const browserUserAgent = () => navigator.userAgent.toLowerCase(); /** * @description 浏览器信息对象 * @returns {{edge: Boolean, opera: Boolean, weiXin: Boolean, safari: Boolean, chrome: Boolean, android: Boolean, firefox: Boolean, ipad: Boolean, ie: Boolean, iphone: Boolean}} */ const browserInfoObject = () => { const userAgent = browserUserAgent(); return { android: userAgent.indexOf('android'.toLowerCase()) >= 0, iphone: userAgent.indexOf('iphone'.toLowerCase()) >= 0, ipad: userAgent.indexOf('ipad'.toLowerCase()) >= 0, ie: !!window.ActiveXObject || 'ActiveXObject' in window, edge: userAgent.indexOf('edge'.toLowerCase()) >= 0, safari: userAgent.indexOf('safari'.toLowerCase()) >= 0, firefox: userAgent.indexOf('firefox'.toLowerCase()) >= 0, chrome: userAgent.indexOf('chrome'.toLowerCase()) >= 0, opera: userAgent.indexOf('opera'.toLowerCase()) >= 0, weiXin: userAgent.indexOf('MicroMessenger'.toLowerCase()) >= 0 }; }; /** * @description 浏览器是否手机浏览器 * @returns {Boolean} */ const browserIsMobile = () => { if (navigator.userAgent.match(/('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i)) { return true; } else { return false; } }; /** * @description 浏览器是否电脑浏览器 * @returns {Boolean} */ const browserIsPc = () => !browserIsMobile(); /** * @returns {String} 当前浏览器名称 */ const browserName = () => { const ua = window.navigator.userAgent; const isExplorer = (exp) => { return ua.indexOf(exp) > -1; }; if (isExplorer('MSIE')) { return 'IE'; } else if (isExplorer('Firefox')) { return 'Firefox'; } else if (isExplorer('Chrome')) { return 'Chrome'; } else if (isExplorer('Opera')) { return 'Opera'; } else if (isExplorer('Safari')) { return 'Safari'; } else { return 'Unknown'; } }; /** * @description 浏览器是否在数组中 * @param {Array} browserArray 要查询的数组 * @returns {Boolean} */ const browserWhetherInArray = (browserArray) => { return browserArray.some((value) => browserUserAgent().indexOf(value.toLowerCase()) > 0); }; /** * @description 全大写 * @param {string} string * @returns {string} */ const caseAllBig = (string) => { return String(string).toUpperCase(); }; /** * @description 全小写 * @param {string} string * @returns {string} */ const caseAllSmall = (string) => { return String(string).toLowerCase(); }; /** * @description 首字母大写,其它小写 * @param {string} string * @returns {string} */ const caseFirstBig = (string) => { return String(string).charAt(0).toUpperCase() + String(string).slice(1).toLowerCase(); }; /** * @description 单词首字母大写,其它小写 * @param {string} string * @returns {string} */ const caseWordFirstBig = (string) => { const ary = String(string).split(' '); for (let i = 0; i < ary.length; i++) { ary[i] = ary[i].slice(0, 1).toUpperCase() + ary[i].slice(1).toLowerCase(); } return ary.join(' '); }; /** * @description 是否有指定的class * @param {HTMLElement} HTMLElement * @param {string} className * @returns {Boolean} */ const classHas = (HTMLElement, className) => { return !!HTMLElement.className.match('(\\s|^)' + className + '(\\s|$)'); }; /** * @description 添加class * @param {HTMLElement} HTMLElement * @param {String} className */ const classAdd = (HTMLElement, className) => { classHas(HTMLElement, className) || (function () { const string = HTMLElement.className; const classNew = string + ' ' + className; HTMLElement.className = string.length > 0 ? classNew : className; })(); }; /** * @description 移除class * @param {HTMLElement} HTMLElement * @param {String} className */ const classRemove = (HTMLElement, className) => { classHas(HTMLElement, className) && (function () { const array = HTMLElement.className.split(' '); const result = []; Object.keys(array).forEach((key) => { array[+key] !== className && result.push(array[+key]); }); HTMLElement.className = result.join(' '); })(); }; /** * @description 切换增减class * @param {HTMLElement} HTMLElement * @param {String} className */ const classToggle = (HTMLElement, className) => { HTMLElement.className.indexOf(className) === -1 ? classAdd(HTMLElement, className) : classRemove(HTMLElement, className); }; /** * @description 控制输入:每个number个字符中间加空格 * @param controlValue * @param number * @returns {string} */ const controlInputNumberSpace = (controlValue, number) => { const theValue = String(controlValue).replace(/\s/g, ''); const array = []; const length = Math.ceil(theValue.length / number); for (let i = 0; i < length; i++) { array.push(theValue.substr(i * number, parseInt(String(number)))); } return array.join(' '); }; /** * @description 替换全部 * @param {Number|String} string * @param {Number|String} search * @param {Number|String} replace * @returns {String} */ const replaceAll = (string, search, replace) => { return String(string).split(String(search)).join(String(replace)); }; /** * @description 只替换第一个 * @param {Number|String} string * @param {Number|String} search * @param {Number|String} replace * @returns {String} */ const replaceOne = (string, search, replace) => { return String(string).replace(String(search), String(replace)); }; /** * @description 保留第一个指定的值 * @param {string} string * @param {string} char * @returns {string} */ const holdFirst = (string, char) => { const tempValue = '##@!@##@!@##'; const replaceFirstChar = replaceOne(String(string), String(char), tempValue); const otherReplaceEmpty = replaceAll(replaceFirstChar, String(char), ''); return replaceOne(otherReplaceEmpty, tempValue, String(char)); }; /** * @description 控制价格的输入 * @param {number|string} controlPrice * @param {number} [number] * @returns {string} */ const controlInputPrice = (controlPrice, number) => { let thePrice = holdFirst(holdFirst(String(controlPrice).replace(/[^\d.-]/g, ''), '-'), '.'); if (thePrice.substr(0, 1) === '.') { thePrice = '0.' + thePrice.substr(1); } if (thePrice.substr(0, 2) === '-.') { thePrice = '-0.' + thePrice.substr(2); } number = typeNumber(number) ? ~~number : 2; const ary = thePrice.split('.'); const int = ary[0]; const float = ary[1] || null; return float && float.length > number ? int + '.' + float.substr(0, number) : thePrice; }; /** * @description 是否date类型 * @param {*} typeValue * @returns {Boolean} */ const typeDate = (typeValue) => typeValue instanceof Date && !isNaN(typeValue.getTime()); /** * @description 是否string类型 * @param {*} typeValue * @returns {Boolean} */ const typeString = (typeValue) => Object.prototype.toString.call(typeValue).toLowerCase() === '[object string]' || typeNumber(typeValue); /** * @description 是否全数字格式 * @param {String} string * @returns {Boolean} */ const formatAllNumber = (string) => /^-?\d+(\.\d+)?$/.test(String(string)); /** * @description 获取时间对象 * @param {*} timeValue * @returns {Date|Null} */ const timeNewDate = (timeValue = new Date()) => { if (timeValue) { let theNewDate; if (typeDate(timeValue)) { theNewDate = timeValue; } else { let theTime = timeValue; if (typeString(theTime)) { theTime = formatAllNumber(String(theTime)) ? theTime : String(theTime).replace(/[.|-]/gm, '/'); } if (typeNumber(theTime) && String(theTime).length === 10) { theTime *= 1000; } theNewDate = typeNumber(theTime) ? new Date(+theTime) : new Date(String(theTime)); } return typeDate(theNewDate) ? theNewDate : null; } else { return new Date(); } }; const H_YM = '{y}-{m}'; const H_YM_ABBR = '{y}{m}'; const H_DATE = '{y}-{m}-{d}'; const H_DATE_ABBR = '{y}{m}{d}'; const H_MH = '{y}-{m}-01'; const H_DATETIME = '{y}-{m}-{d} {h}:{i}:{s}'; const H_DATETIME_ABBR = '{y}{m}{d}{h}{i}{s}'; const H_H_I = '{h}:{i}'; const H_M_D_H_I = '{m}-{d} {h}:{i}'; const H_Y_M_D_H_I = '{y}-{m}-{d} {h}:{i}'; const T_YM = 'YYYY-MM'; const T_YM_ABBR = 'YYYYMM'; const T_DATE = 'YYYY-MM-DD'; const T_DATE_ABBR = 'YYYYMMDD'; const T_MH = 'YYYY-MM-01'; const T_DATETIME = 'YYYY-MM-DD HH:mm:ss'; const T_DATETIME_ABBR = 'YYYYMMDDHHmmss'; const T_H_I = 'HH:mm'; const T_M_D_H_I = 'MM-DD HH:mm'; const T_Y_M_D_H_I = 'YYYY-MM-DD HH:mm'; /** * @description 获取时间对象 * @param {*} [timeValue] * @returns {{s: Number, d: Number, w: Number, h: Number, y: Number, i: Number, m: Number}|Null} */ const timeObject = (timeValue = new Date()) => { const theNewDate = timeNewDate(timeValue); return theNewDate !== null ? { y: theNewDate.getFullYear(), m: theNewDate.getMonth() + 1, d: theNewDate.getDate(), h: theNewDate.getHours(), i: theNewDate.getMinutes(), s: theNewDate.getSeconds(), w: theNewDate.getDay() } : null; }; /** * @description 时间格式化 * @param {*} [timeValue] * @param {String} [format] 格式 * @param {Boolean} [zero] 是否加零,默认加零 * @returns {Null|String} */ const timeFormat = (timeValue = new Date(), format = H_DATETIME, zero = true) => { const theObject = timeValue ? timeObject(timeValue) : timeObject(new Date()); if (theObject !== null) { return format.replace(/{([ymdhisw])+}/g, (result, key) => { const timeValue = theObject[key]; return key === 'w' ? ['日', '一', '二', '三', '四', '五', '六'][timeValue] : zero ? String(timeValue).padStart(2, '0') : String(timeValue); }); } else { return null; } }; /** * @description 计算日期number天后(前)的日期(正数为后,负数为前) * @param {*} dateValue 要计算的日期 * @param {number} number number天后(前) * @returns {String|Null} */ const dateApart = (dateValue, number) => { const theNewDate = timeNewDate(dateValue); return theNewDate ? timeFormat(~~(+theNewDate / 1000) + number * 24 * 60 * 60, H_DATE, true) : null; }; /** * @description 是否闰年 * @param {Number} year * @returns {Boolean} */ const someWhetherLeapYear = (year) => (+year % 4 === 0 && +year % 100 !== 0) || +year % 400 === 0; /** * @description 二月的天数 * @param {Number} year * @returns {Number} */ const someFebruaryDays = (year) => (someWhetherLeapYear(~~String(year)) ? 29 : 28); /** * @description 某年某月的月天数 * @param {Number} year * @param {Number} month * @returns {Number} */ const someYearMonthDays = (year, month) => { const monthDays = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][~~String(month) - 1]; return monthDays || someFebruaryDays(~~String(year)); }; /** * @description 获取number个月后(前)的日期,number可为正可为负 * @param {*} [dateValue] 时间 * @param {number} number 几个月后(前) * @returns {Null|String} */ const dateApartMonth = (dateValue = new Date(), number) => { const theObject = timeObject(dateValue); if (theObject) { const totalMonths = +theObject.y * 12 + +theObject.m + +number; let day = theObject.d; let year = Math.floor(totalMonths / 12); let month = totalMonths % 12; if (month === 0) { year = year - 1; month = 12; } const monthDays = someYearMonthDays(year, month); day = day > monthDays ? monthDays : day; const Year = String(year).padStart(4, '0'); const Month = String(month).padStart(2, '0'); const Day = String(day).padStart(2, '0'); return `${Year}-${Month}-${Day}`; } else { return null; } }; /** * @description 获取一个时间至number个月前(后)的所有年月的数据列表 * @param {number|string} number 几个月 * @param {*} [dateValue] 时间 * @returns {Array|Null} */ const dateApartMonthList = (number, dateValue = new Date()) => { const theObject = timeObject(dateValue); if (theObject) { let y = +String(theObject.y).padStart(4, '0'); let m = +String(theObject.m).padStart(2, '0'); const array = []; const big = number > 0; number = Math.abs(number); array.push(`${y}-${m}`); for (let i = 0; i < +number; i++) { if (big) { m++; if (m >= 13) { y += 1; m = 1; } } else { m--; if (m <= 0) { y -= 1; m = 12; } } const Y = `${y}`.padStart(4, '0'); const M = `${m}`.padStart(2, '0'); array.push(`${Y}-${M}`); } return array; } else { return null; } }; /** * @description 两个日期时间相差多少天 * @param {*} dateOne 日期一 * @param {*} dateTwo 日期二 * @param {beforeAll} abs 绝对值 * @returns {Number|Null} */ const dateDifference = (dateOne, dateTwo, abs) => { const oneObject = timeNewDate(dateOne); const twoObject = timeNewDate(dateTwo); if (oneObject && twoObject) { abs = abs || false; const result = ~~((oneObject.getTime() - twoObject.getTime()) / (1000 * 24 * 60 * 60)); return abs ? Math.abs(result) : result; } else { return null; } }; /** * @description 获取日期的月尾日期 * @param {*} [dateValue] * @returns {String|Null} */ const dateMonthFoot = (dateValue = new Date()) => { const theObject = timeObject(dateValue); if (theObject !== null) { const year = String(theObject.y).padStart(4, '0'); const month = String(theObject.m).padStart(2, '0'); const day = new Date(+year, +month, 0).getDate(); return `${year}-${month}-${day}`; } else { return null; } }; /** * @description 获取日期的月头日期 * @param {*} [dateValue] * @returns {String|Null} */ const dateMonthHead = (dateValue = new Date()) => { const theObject = timeNewDate(dateValue); return theObject ? timeFormat(theObject, H_MH, true) : null; }; /** * @description 时间的年份 * @param {*} [timeValue] * @returns {String|Null} */ const timeGetYear = (timeValue = new Date()) => { const theTime = timeValue || new timeValue(); const theObject = timeObject(theTime); return theObject !== null ? String(theObject.y).padStart(4, '0') : null; }; /** * @description 时间的月份 * @param {*} [timeValue] * @returns {String|Null} */ const timeGetMonth = (timeValue = new Date()) => { const theTime = timeValue || new timeValue(); const theObject = timeObject(theTime); return theObject !== null ? String(theObject.m).padStart(2, '0') : null; }; /** * @description 获取日期下月的年月 * @param {*} [dateValue] * @param {Boolean} [isResultArray] 是否返回数组形式,若false则返回字符串,默认为false * @returns {String|Array|Null} */ const dateMonthNext = (dateValue = new Date(), isResultArray) => { const theObject = timeNewDate(dateValue); if (theObject !== null) { const next = dateApart(dateMonthFoot(dateValue), 1); const year = timeGetYear(next); const month = timeGetMonth(next); isResultArray = isResultArray || false; return isResultArray ? [year, month] : `${year}-${month}`; } else { return null; } }; /** * @description 获取日期上月的年月 * @param {*} [dateValue] * @param {Boolean} [isResultArray] 是否返回数组形式,若false则返回字符串,默认为false * @returns {Array|String|Null} */ const dateMonthPrev = (dateValue = new Date(), isResultArray) => { const theObject = timeNewDate(dateValue); if (theObject) { const apart = dateApart(dateMonthHead(dateValue), -1); const year = timeGetYear(apart); const month = timeGetMonth(apart); isResultArray = isResultArray || false; return isResultArray ? [year, month] : `${year}-${month}`; } else { return null; } }; /** * @description 日期的周日日期 * @param {*} [dateValue] * @returns {String|Null} */ const dateWeekSunday = (dateValue = new Date()) => { const theNewDate = timeNewDate(dateValue); if (theNewDate !== null) { const week = theNewDate.getDay(); const ary = [0, -1, -2, -3, -4, -5, -6]; return dateApart(theNewDate, ary[week]); } else { return null; } }; /** * @description 获取日期一周的日期 * @param {*} [dateValue] * @returns {Array|Null} */ const dateOneWeek = (dateValue = new Date()) => { const theObject = timeNewDate(dateValue); if (theObject !== null) { const array = []; const sunday = dateWeekSunday(dateValue); for (let i = 0; i < 7; i++) { const apart = dateApart(sunday, i); array.push(apart); } return array; } else { return null; } }; /** * @description 获取日期一月的日期 * @param {*} [dateValue] * @returns {Array|Null} */ const dateOneMonth = (dateValue = new Date()) => { const theObject = timeNewDate(dateValue); if (theObject) { const array = []; const monthFoot = dateMonthFoot(dateValue); const oneWeek = dateOneWeek(monthFoot); array.push(oneWeek); for (let i = 0; i < 6; i++) { const apart = dateApart(oneWeek[0], -(i * 7 + 1)); if (new Date(String(apart)).getMonth() + 1 !== theObject.getMonth() + 1) { break; } const theWeek = dateOneWeek(apart); array.unshift(theWeek); } return array; } else { return null; } }; const accept = { imgAll: 'image/*', gif: 'image/gif', jpg: 'image/jpg', jpeg: 'image/jpeg,', png: 'image/png', webp: 'image/webp', bmp: 'image/bmp', svg: 'image/svg+xml', xls: 'application/vnd.ms-excel', xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', txt: 'text/plain', csv: 'text/csv', pdf: 'application/pdf', zip: 'application/zip', rar: 'application/x-rar-compressed', gz: 'application/x-gzip' }; const defineAccept = (ary) => { const n = []; for (let index = 0; index < ary.length; index++) { const element = ary[index]; if (accept[element]) { n.push(accept[element]); } else { n.push(element); } } return n.join(','); }; const acceptImage = defineAccept(['imgAll']); const acceptImgPdf = defineAccept(['imgAll', 'pdf']); const acceptPdf = defineAccept(['pdf']); const acceptExcel = defineAccept(['xls', 'xlsx']); const acceptWord = defineAccept(['doc', 'docx']); const acceptText = defineAccept(['txt', 'csv']); const acceptZip = defineAccept(['zip', 'rar', 'gz']); const defineBooleanAry = [ { value: 0, label: '否' }, { value: 1, label: '是' } ]; // noinspection NonAsciiCharacters,HttpUrlsUsage const defineFace = { '[微笑]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/5c/huanglianwx_thumb.gif', '[嘻嘻]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/0b/tootha_thumb.gif', '[哈哈]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6a/laugh.gif', '[可爱]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/14/tza_thumb.gif', '[可怜]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/af/kl_thumb.gif', '[挖鼻]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/0b/wabi_thumb.gif', '[吃惊]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/f4/cj_thumb.gif', '[害羞]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6e/shamea_thumb.gif', '[挤眼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/c3/zy_thumb.gif', '[闭嘴]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/29/bz_thumb.gif', '[鄙视]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/71/bs2_thumb.gif', '[爱你]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6d/lovea_thumb.gif', '[泪]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/9d/sada_thumb.gif', '[偷笑]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/19/heia_thumb.gif', '[亲亲]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/8f/qq_thumb.gif', '[生病]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/b6/sb_thumb.gif', '[太开心]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/mb_thumb.gif', '[白眼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d9/landeln_thumb.gif', '[右哼哼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/98/yhh_thumb.gif', '[左哼哼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6d/zhh_thumb.gif', '[嘘]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/a6/x_thumb.gif', '[衰]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/af/cry.gif', '[委屈]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/73/wq_thumb.gif', '[吐]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/9e/t_thumb.gif', '[哈欠]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/cc/haqianv2_thumb.gif', '[抱抱]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/27/bba_thumb.gif', '[怒]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/7c/angrya_thumb.gif', '[疑问]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/5c/yw_thumb.gif', '[馋嘴]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/a5/cza_thumb.gif', '[拜拜]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/70/88_thumb.gif', '[思考]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/e9/sk_thumb.gif', '[汗]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/24/sweata_thumb.gif', '[困]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/40/kunv2_thumb.gif', '[睡]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/96/huangliansj_thumb.gif', '[钱]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/90/money_thumb.gif', '[失望]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/0c/sw_thumb.gif', '[酷]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/40/cool_thumb.gif', '[色]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/20/huanglianse_thumb.gif', '[哼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/49/hatea_thumb.gif', '[鼓掌]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/36/gza_thumb.gif', '[晕]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d9/dizzya_thumb.gif', '[悲伤]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/1a/bs_thumb.gif', '[抓狂]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/62/crazya_thumb.gif', '[黑线]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/91/h_thumb.gif', '[阴险]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6d/yx_thumb.gif', '[怒骂]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/60/numav2_thumb.gif', '[互粉]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/89/hufen_thumb.gif', '[心]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/40/hearta_thumb.gif', '[伤心]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/ea/unheart.gif', '[猪头]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/pig.gif', '[熊猫]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/6e/panda_thumb.gif', '[兔子]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/81/rabbit_thumb.gif', '[ok]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d6/ok_thumb.gif', '[耶]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d9/ye_thumb.gif', '[good]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d8/good_thumb.gif', '[NO]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/ae/buyao_org.gif', '[赞]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d0/z2_thumb.gif', '[来]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/40/come_thumb.gif', '[弱]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d8/sad_thumb.gif', '[草泥马]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/7a/shenshou_thumb.gif', '[神马]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/60/horse2_thumb.gif', '[囧]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/15/j_thumb.gif', '[浮云]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/bc/fuyun_thumb.gif', '[给力]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/1e/geiliv2_thumb.gif', '[围观]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/f2/wg_thumb.gif', '[威武]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/70/vw_thumb.gif', '[奥特曼]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/bc/otm_thumb.gif', '[礼物]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/c4/liwu_thumb.gif', '[钟]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d3/clock_thumb.gif', '[话筒]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/9f/huatongv2_thumb.gif', '[蜡烛]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/d9/lazhuv2_thumb.gif', '[蛋糕]': 'http://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/3a/cakev2_thumb.gif' }; const defineIsUseAry = [ { value: '0', label: '禁用' }, { value: '1', label: '启用' } ]; /** * @description 根据字典的值获取对应的名称 * @param {Array} anyArray * @param {Number} value * @returns {String} */ const dictGetNameByValue = (anyArray, value) => { let name = ''; anyArray.forEach((item) => { if (+item.value === +value) { name = item.name; } }); return name || value; }; /** * @description 根据字典的名称获取对应的值 * @param {Array} anyArray * @param {String} name * @returns {String} */ const dictGetValueByName = (anyArray, name) => { if (typeof name === 'number') { return name; } else { let value = ''; anyArray.forEach((item) => { if (item.name === name) { value = item.value; } }); return value || name; } }; /** * @example :fetch-suggestions="(q,c) => autoQuery(q,c,a)" * @param queryString * @param queryCallback * @param queryArray */ const autoQuery = (queryString, queryCallback, queryArray) => { queryCallback(queryString ? queryArray.filter((state) => state.value.toUpperCase().match(queryString.toUpperCase())) : queryArray); }; /** * @description 获取(定义)表格的index * @param data */ const elTableIndex = (data) => { const { row, rowIndex } = data; row.index = rowIndex; }; /** * @description 关键字高亮 * @param {Object} lightObject 对象 * @param {String} lightKey 键 * @param {String} lightValue 值 * @param {String} [lightColor] 颜色 * @returns {String} */ const keyLight = (lightObject, lightKey, lightValue, lightColor = '#1980ff') => { return lightValue ? lightObject[lightKey] ? lightValue.replace(new RegExp(lightObject[lightKey], 'ig'), (val) => `<span style='color:${lightColor}'>${val}</span>`) : lightValue : '--'; }; /** * @description 日期快捷选项 * @return {[{onClick(*): void, text: string}, {onClick(*): void, text: string}, {onClick(*): void, text: string}, {onClick(*): void, text: string}, {onClick(*): void, text: string}]} */ const shortcutDate = () => { return [ { text: '一周后', onClick(picker) { const date = new Date(); date.setTime(date.getTime() + 3600 * 1000 * 24 * 7); picker.$emit('pick', date); } }, { text: '明天', onClick(picker) { const date = new Date(); date.setTime(date.getTime() + 3600 * 1000 * 24); picker.$emit('pick', date); } }, { text: '今天', onClick(picker) { picker.$emit('pick', new Date()); } }, { text: '昨天', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24); picker.$emit('pick', date); } }, { text: '一周前', onClick(picker) { const date = new Date(); date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); picker.$emit('pick', date); } } ]; }; /** * @description 范围日期快捷选项 * @return {[{onClick(*): void, text: string}, {onClick(*): void, text: string}, {onClick(*): void, text: string}]} */ const shortcutScope = () => { return [ { text: '最近一周', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); picker.$emit('pick', [start, end]); } }, { text: '最近一个月', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); picker.$emit('pick', [start, end]); } }, { text: '最近三个月', onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); picker.$emit('pick', [start, end]); } } ]; }; /** * @description 大于时间 * @param [gtTime] 大于什么时间 * @return {function(*): boolean} */ const gtTime = (GtTime) => { GtTime = GtTime ? new Date(GtTime) : new Date(); return (time) => time.getTime() < GtTime.getTime(); }; /** * @description 小于时间 * @param [ltTime] 小于什么时间 * @return {function(*): boolean} */ const ltTime = (LtTime) => { LtTime = LtTime ? new Date(LtTime) : new Date(); return (time) => time.getTime() > LtTime.getTime(); }; /** * @description 范围时间 * @param [GtTime] 大于什么时间 * @param [LtTime] 小于什么时间 * @returns {function(*): boolean} */ const scopedTime = (GtTime, LtTime) => { GtTime = GtTime ? new Date(GtTime) : new Date(); LtTime = LtTime ? new Date(LtTime) : new Date(); return (time) => time.getTime() < GtTime.getTime() || time.getTime() > LtTime.getTime(); }; /** * @description 合计方法 * @param {{}} summaryParam * @param {[]} summaryFields * @returns */ const summaryMethod = (summaryParam, summaryFields) => { const { columns, data } = summaryParam; const sums = []; columns.forEach((column, index) => { if (index === 0) { sums[index] = '合计'; return; } const values = data.map((item) => Number(item[column.property])); if (summaryFields.includes(column.property)) { sums[index] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return +(prev + curr).toFixed(2); } else { return prev; } }, 0); } }); return sums; }; /** * @desc 保证字符串尾部含有指定字符 * @param {number|string} ensureString * @param {number|string} ensureAssign * @returns {number|string} */ const ensureFootHave = (ensureString, ensureAssign) => { const theString = String(ensureString); const theAssign = String(ensureAssign); return theString.substr(-theString.length) === theAssign ? theString : theString + theAssign; }; /** * @desc 保证字符串尾部没有指定字符 * @param {number|string} ensureString * @param {number|string} ensureAssign * @returns {number|string} */ const ensureFootNone = (ensureString, ensureAssign) => { const theString = String(ensureString); const theAssign = String(ensureAssign); const strLen = theString.length; const theLen = theAssign.length; return theString.substr(-theLen) === theAssign ? ensureFootNone(theString.substr(0, strLen - theLen), theAssign) : theString; }; /** * @desc 保证字符串头部含有指定字符串 * @param {number|string} ensureString * @param {number|string} ensureAssign * @returns {number|string} */ const ensureHeadHave = (ensureString, ensureAssign) => { const theString = String(ensureString); const theAssign = String(ensureAssign); return theString.substr(0, theAssign.length) === theAssign ? theString : theAssign + theString; }; /** * @desc 保证字符串头部没有指定字符串 * @param {number|string} ensureString * @param {number|string} ensureAssign * @returns {number|string} */ const ensureHeadNone = (ensureString, ensureAssign) => { const theString = String(ensureString); const theAssign = String(ensureAssign); const length = theAssign.length; return theString.substr(0, length) === theAssign ? ensureHeadNone(theString.substr(length), theAssign) : theString; }; /** * @description 从字符串中提取文件的文件全名 * @param {String} string * @returns {String} */ const fileFullName = (string) => { const pos1 = string.lastIndexOf('/'); const pos2 = string.lastIndexOf('\\'); const pos3 = Math.max(pos1, pos2); if (pos3 < 0) { return string; } else { return string.substring(pos3 + 1); } }; /** * @description 从字符串中提取文件的文件名称 * @param {String} string * @returns {String} */ const fileBaseName = (string) => fileFullName(string).replace(/\.[^.]+$/i, ''); /** * @description 从字符串中提取文件的后缀名称 * @param {String} string * @returns {String} */ const fileSuffixName = (string) => fileFullName(string).replace(/.+[.]([^.\\/]+)$/gi, '$1'); /** * @description 从字符串中提取文件的后缀名并进行分类 * @param {String} string * @returns {String} */ const fileClassify = (string) => { const suffixName = fileSuffixName(string); const array = [ { n: 'doc', v: ['doc', 'docx', 'dot', 'docx'] }, { n: 'txt', v: ['txt'] }, { n: 'ofd', v: ['ofd'] }, { n: 'xml', v: ['xml'] }, { n: 'xls', v: ['xls', 'xlsx'] }, { n: 'ppt', v: ['ppt', 'pptx'] }, { n: 'pdf', v: ['pdf'] }, { n: 'htm', v: ['htm', 'html'] }, { n: 'pic', v: ['png', 'jpg', 'jpeg', 'bmp', 'gif'] }, { n: 'vid', v: ['avi', 'rm', 'mpg', 'mpeg', 'mpe', 'wmv', 'mp4', 'mkv', 'vob', '3gp', 'mov'] }, { n: 'aud', v: ['wav', 'mp3', 'wma', 'aif', 'cda', 'mid', 'caf', 'amr'] }, { n: 'app', v: ['exe', 'app', 'ipa', 'apk'] }, { n: 'zip', v: ['zip', 'rar'] } ]; let result = 'other'; for (let i = 0; i < array.length; i++) { if (array[i].v.includes(suffixName)) { result = array[i].n; break; } } return result; }; /** * @description 将文件流保存到本地 * @param {string} fileName 文件名 * @param {string} fileSuffix 后缀名 * @param {blob} fileType 文件类型 */ const fileSave = (fileName = 'log', fileSuffix = 'doc', fileType) => { const blob = new Blob([fileType]); const link = document.createElement('a'); const href = window.URL.createObjectURL(blob); link.href = href; link.download = `${fileName}.${fileSuffix}`; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(href); }; /** * https://www.iconfont.cn/collections/detail?spm=a313x.collections_index.i1.d9df05512.4e8d3a81H6tDBw&cid=49504 * @description 从字符串中提取文件的后缀名并进行分类 * @param {String} string * @returns {String} */ const fileType = (string) => { const suffixName = fileSuffixName(string); const array = [ { name: 'word', value: ['doc', 'docx',