开发中常用的工具函数,比如生成随机数、字符串填充、文件下载、页面路径参数处理等

/**
 * 获取URL中的文件后缀
 * @param {string} URL 数据源的URL
 * @returns {string} 解析后的文件后缀
 */
export function getSuffix(URL) {
  try {
    return URL.split('/')
      .pop()
      .split('?')[0]
      .split('.')
      .pop()
  } catch (e) {
    console.warn('URL is invalid')
  }
}

/**
 * 获取URL中的文件名
 * @param {string} URL 数据源的URL
 * @returns {string} 解析后的文件名
 */
export function getFileName(URL) {
  try {
    const fullName = URL.split('/')
      .pop()
      .split('?')[0]
    return fullName.substr(0, fullName.lastIndexOf('.'))
  } catch (e) {
    console.warn('URL is invalid')
    return null
  }
}

/**
 * 解析URL参数,并进行URL参数解码
 * @param {string} [url] 解析对象
 * @param {string} [key] 需要获取的参数名,不传则返回整个解析的对象
 * @returns {string|object} 返回整个解决后的对象,或者特定Key的值
 */
export function getParams(url = location.href, key) {
  const params = {}
  url = decodeURIComponent(url)
  url.replace(/[?|&](\w+)=([^&^?]*)/g, (matchStr, $1, $2) => {
    params[$1] = $2
  })
  return key ? params[key] : params
}

/**
 * URL参数串行化 / 添加参数,并进行URL参数编码
 * @param {string} [baseURL] 原URL
 * @param {object} params URL参数
 * @param {boolean} isEncode 是否解码
 * @returns {string} 解析组合好的字符串
 */
export function serialize(baseURL, params, isEncode) {
  let paramsStr = ''
  if (baseURL) {
    params = Object.assign({}, getParams(baseURL), params)
  }
  for (let key in params) {
    paramsStr += `${key}=${params[key]}&`
  }
  paramsStr = paramsStr.slice(0, -1)
  if (isEncode) {
    paramsStr = encodeURIComponent(paramsStr)
  }

  if (baseURL) {
    return `${baseURL.split('?')[0]}?${paramsStr}`
  } else {
    return paramsStr
  }
}

/**
 * 获取URL中的路径信息
 * @param {string} url 解析的URL
 * @returns {string} 路径字符串
 */
export function getPath(url) {
  url = url || location.href
  const elemList = url.split('/')
  elemList.shift() // 去除http:/
  elemList.shift() // 去除//
  elemList.shift() // 去除域名
  return elemList.join('/')
}

import axios from "axios"

/**
 * 获取随机字符串
 * @param {number} length 字符串长度
 * @param {string} [type] 随机字符串类型,letter纯字母,number纯数字,mix字母与数字混合
 * @param {string} [prefix] 字符串前缀
 * @returns {string} 生成的随机字符串
 */
export function randomString(length, type = "letter", prefix = "") {
  const numbers = "0123456789"
  const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

  let chars = ""
  let result = prefix

  if (type === "number" || type === "mix") {
    chars += numbers
  }

  if (type === "letter" || type === "mix") {
    chars += letters
  }

  for (let i = 0; i < length; i++) {
    result += chars[Math.floor(Math.random() * chars.length)]
  }
  return result
}

/**
 * 字符串填充「0」
 * @param {string} origin 原始字符串
 * @param {number} length 目标字符串长度
 * @param {boolean} isFillBack 是否从尾部跳槽
 * @returns {string} 处理后的字符串
 */
export function fillZero(origin, length, isFillBack) {
  length = origin.length > length ? origin.length : length // 若原长度比目标长度更长
  if (isFillBack) {
    return (origin.toString() + new Array(length).join("0")).substr(0, length)
  } else {
    return (new Array(length).join("0") + origin.toString()).substr(-length)
  }
}

/**
 * 比较数字大小补0
 * *compareFillZero(5) => '05'
 * *compareFillZero(25,1000) => '025'
 * @param {Number|String} num 数字
 * @param {number|String} maxNum 比较的数字
 * @param {String} fillUnit 默认0,可其他字符串*,-等
 * @returns {string} 补0后的字符串
 */
 export function compareFillZero (num, maxNum = 100, fillUnit = '0') {
  if (!num && +num !== 0) return ''
  let numString = `${num}`
  if (+num < +maxNum) {
    for (let i = 1; i < String(maxNum).length - String(num).length; i++) {
      numString = fillUnit + numString
    }
  }
  return numString
}

/**
 * 除去多余参数
 * @param {object} obj 需要处理的对象
 * @param {boolean} isFillEmptyStr 是否填充为空字符串
 * @returns {object} 处理完成后的对象
 */
export function deleteEmpty(obj, isFillEmptyStr = false) {
  obj = JSON.parse(JSON.stringify(obj))
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === "string") {
      obj[key] = obj[key].trim()
    }
    if (obj[key] === undefined || obj[key] === null || obj[key] === "") {
      if (isFillEmptyStr) {
        obj[key] = ""
      } else {
        delete obj[key]
      }
    }
    if (typeof obj[key] === "object" && obj[key].constructor !== Array) {
      obj[key] = deleteEmpty(obj[key])
    }
  })
  return obj
}

/**
 * 获取img标签图片的base64数据
 * @param {object} img img标签
 * @returns {string} base64数据
 */
export function getBase64Image(img) {
  const canvas = document.createElement("canvas")
  canvas.width = img.width
  canvas.height = img.height
  const ctx = canvas.getContext("2d")
  ctx.drawImage(img, 0, 0, img.width, img.height)
  return canvas.toDataURL("image/png")
}

/**
 * 将base64数据转化为file对象
 * @param {string} base64Str base64数据
 * @param {string} fileName 文件名
 * @returns {File} 文件对象
 */
export function base64ToFile(base64Str, fileName) {
  const params = base64Str.split(",")
  const mime = params[0].match(/:(.*?)/)[1]
  const fileData = atob(params[1]) // 解码Base64
  let { length } = fileData
  const uint8Array = new Uint8Array(length)
  while (length) {
    length -= 1
    uint8Array[length] = fileData.charCodeAt(length)
  }
  return new File([uint8Array], fileName, { type: mime })
}

/**
 * 将blob数据转化为buffer对象
 * @param {object} blob blob对象
 */
export function blobToBuffer(blob) {
  return new Promise(resolve => {
    let reader = new FileReader()
    reader.onload = result => {
      resolve(result)
    }
    reader.readAsArrayBuffer(blob)
  })
}

/**
 * 文件下载
 * @param {string} url 获取文件对应的URL
 * @param {object} data 文件内容
 * @param {string} fileName 文件名
 * @param {string} fileType 文件类型
 */
export function downloadFile(url, data = {}, fileName, fileType) {
  fileName = fileName || getFileName(url)
  fileType = fileType || getSuffix(url)
  data = Object.assign({}, data, { token: localStorage.getItem("token") })

  axios({
    url,
    method: "get",
    responseType: "blob",
    params: data
  }).then(res => {
    const fileBlob = new Blob([res.data]) // 创建一个Blob对象
    const a = document.createElement("a")
    a.download = `${fileName}.${fileType}`
    a.href = URL.createObjectURL(fileBlob)
    a.style.display = "none"
    document.body.appendChild(a)
    a.click()
    a.remove()
  })
}

/**
 * 根据 blob 或 url 直接下载文件
 * @param {string|Blob} url 获取文件对应的URL
 * @param {string} fileName 文件名
 * @param {string} fileType 文件类型
 */
 export function download(url, fileName = '', fileType = '') {
  const isBlob = url instanceof Blob
  if (isBlob) {
    url = URL.createObjectURL(url)
  }
  const a = document.createElement("a")
  if (fileName && fileType) {
    a.download = `${fileName}.${fileType}`
  }
  a.href = url
  a.style.display = "none"
  document.body.appendChild(a)
  a.click()
  a.remove()
  if (isBlob) {
    URL.revokeObjectURL(url)
  }
}

/**
 * 获取完整的URL绝对,解决相对路径转变为绝对路径的问题
 * @param {string} path 原路径
 * @returns {string} 解析后的路径
 */
export function getURL(path) {
  const $a = document.createElement("a")
  $a.href = path
  return $a.href
}

/**
 * 获取阿里OSS云存储的图片裁剪功能后的图片,减少图片体积,节约流量
 * @param {string} url 图片URL
 * @param {number} width 图片宽度 / 短边长度
 * @param {number} [height] 图片高度
 * @param {string} type 图片缩放方式,默认m_fill为自动裁剪,m_mfit,短边优先,长边自动扩充。详情参考https://help.aliyun.com/document_detail/44688.html?spm=a2c4g.11186623.4.1.rGBEsn
 * @returns {string} 处理后的图片链接
 */
export function getFitURL(url, width, height, type = "m_fill") {
  height = height || width
  return url
    ? serialize(url, {
      "x-oss-process": `image/resize,${type},h_${parseInt(
        height
      )},w_${parseInt(width)}`
    })
    : ""
}

/**
 * 获取首字母大写的字符串
 * @param {string} text 待替换字符串
 * @returns {string} 转化后的字符串
 */
export function getWord(text) {
  return text[0].toUpperCase() + text.substr(1)
}

/**
 * 将横线命名转化为驼峰命名法
 * @param {string} text 待替换字符串
 * @param {string} char 单词间隔符
 * @returns {string} 转化后的字符串
 */
export function getCamelCase(text, char) {
  // const reg = new RegExp('-[a-z]+?', 'g')
  const reg = new RegExp(`${char}[a-z]+?`, "g")
  return text.replace(reg, matchStr => matchStr[1].toUpperCase())
}

/**
 * 将驼峰命名法转化为横线命名
 * @param {string} text 待替换字符串
 * @returns {string} 转化后的字符串
 */
export function getUnderScoreCase(text) {
  return text.replace(/[A-Z]+?/g, matchStr => `-${matchStr.toLowerCase()}`)
}

/**
 * 获取符合条件的所有对象
 * @param {array} list 候选数组
 * @param {object} condition 对象特征
 * @returns {array}符合的对象数组
 */
export function getMatchObjList(list, condition) {
  const matchList = []
  list.forEach((item, index) => {
    for (const key in condition) {
      if (condition[key] !== item[key]) {
        return
      }
    }
    matchList.push({
      index,
      content: item
    })
  })
  return matchList
}

/**
 * 获取符合条件的对象索引
 * @param {array} list 候选数组
 * @param {object} condition 对象特征
 * @returns {number} 符合条件的对象索引
 */
export function getObjIndex(list, condition) {
  const result = getMatchObjList(list, condition)
  return result.length > 0 ? result[0].index : -1
}

/**
 * 获取符合条件的对象
 * @param {array} list 候选数组
 * @param {object} condition 对象特征
 * @returns {object} 符合条件的对象
 */
export function getObj(list, condition) {
  return (getMatchObjList(list, condition)[0] || {}).content
}

/**
 * 解析对象字符串
 * @param {object} targetObj 目标对象
 * @param {string} str 字符串表达式
 * @param {string} splitWord 字符串表达式分隔符
 */
export function parseObjStr(targetObj, str, splitWord = '.') {
  return str.split(splitWord).reduce((obj, key) => {
    return obj[key]
  }, targetObj)
}

/**
 * 格式化大小
 * @param {number} value 文件大小(单位为Bytes)
 * @returns {string} 文件大小字符串
 */
export function formatSize(value) {
  if (value) {
    // eslint-disable-next-line no-magic-numbers
    const index = Math.floor(Math.log(value) / Math.log(1024))
    // eslint-disable-next-line no-magic-numbers
    const size = (value / 1024 ** index).toFixed(2)
    return (
      size + ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"][index]
    )
  }
  return "0 Bytes"
}

/**
 * 替换对象的key
 * @param {object} target 目标对象
 * @param {object} keyMap key值转换映射,如将a转化为b,则{a:b}
 * @returns {any} 转化后的对象
 */
export function changeObjKey(target, keyMap) {
  target = JSON.stringify(target)
  for (const key in keyMap) {
    target = target.replace(new RegExp(`"${key}":`, "g"), `"${keyMap[key]}":`)
  }
  return JSON.parse(target)
}

/**
 * 计算页码,从第几个页开始显示
 * @param {number} pageIndex 当前第几页
 * @param {number} pageNum 一共有几页
 * @param {number} pageShowNum 显示多少页码
 * @returns {number} 从第几页开始显示
 */
export function getPageStart(pageIndex, pageNum, pageShowNum) {
  let startPageIndex = 0
  pageShowNum = pageShowNum > pageNum ? pageNum : pageShowNum // 页面总数,与现显示页数总数比较
  pageShowNum = pageShowNum > 0 ? pageShowNum : 1 // 0判断
  if (pageIndex < pageNum / 2) {
    // 最左边
    startPageIndex = 0
  } else if (pageIndex > Math.floor(pageNum - pageShowNum / 2 + 1)) {
    // 最右边
    startPageIndex = pageNum - pageShowNum
  } else {
    // 中间
    startPageIndex = pageIndex - Math.floor(pageShowNum / 2) - 1
  }
  startPageIndex = startPageIndex > -1 ? startPageIndex : 0
  return startPageIndex
}

/**
 * 防抖
 * @param {function} func 回调函数
 * @param {number} waitTime 毫秒
 * @returns
 */
export function debounce(func, waitTime = 500) {
  let timeout;
  return function () {
    let _this = this,
        args = arguments;
    if (timeout) {
      clearTimeout(timeout);
    }

    timeout = setTimeout(function () {
      func.apply(_this, args)
    },  waitTime);
  }
}


/**
 * 从票号获取承兑行号
 * 从票号 1 - 13位为承兑行号,如:1abcdabcdabcd2345678,其中 abcdabcdabcd 即承兑行号
 * @param {string} draftNo 票据号
 * @returns {string} 承兑行号
 */
export const getBankCnapsFromDraftNo = (draftNo) => {
  const bankCnaps = draftNo.substring(1, 13)
  return bankCnaps
}

/**
 * 判断是否为Null(不为0,undefined的情况下)
 * *用例: isNull(null) true
 * *用例: isNull(undefined) => false
 * *用例: isNull(0) => false
 * @param {any} data 任何的数据
 * @returns {Boolean} 该数据是否为Null
 */
 export function isNull (data) {
  return !data && typeof (data) !== 'undefined' && data !== 0
}

/**
 * 获取数据类型
 * @param {*} obj
 * @returns 'String' 'Number' 'Boolean' 'Undfined' 'Null' 'Object' 'Array' 'Function'...
 */
 export const getObjectType = obj => {
  const type = Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1')
  return type
}

// 是否是 非 NaN 的数字类型
export const isNotNaNNumber = obj => getObjectType(obj) === 'Number' && !isNaN(obj)

// 是否是非空字符串的字符串类型
export const isNotEmptyString = obj => getObjectType(obj) === 'String' && obj.trim() !== ''

/**
 * 根据模版对象从另一个对象中获取与模版结构一致的对象
 * @param {Object} tempalte 模版对象 { a: null }
 * @param {Object} target  目标对象 { a: 1, b: 1}
 * @returns {Object} 返回新对象 { a: 1 }
 */
export const getObjFromTemplate = (template, target) => {
  let newObj = {}
  Object.entries(template).forEach(([key, val]) => {
    // 当 object 不存在 key 时返回 undefined,与直接判 【非真】不同
    newObj[key] = target && target[key] !== undefined ? target[key] : val
  })
  return newObj
}
// 是否是对象
export const isObject = obj => getObjectType(obj) === 'Object'

/**
 * 日期控件中,指定开始日期和结束日期的具体时刻,设置default-time属性的值
 * @param {*} start 开始时间 默认: 0:0:0
 * @param {*} end 结束时间  默认: 23:59:59
 * @returns Date[]
 */
 export const getDefaultTimeValue = (start,end) => {
  const t1 = typeof start === 'string' ? start.split(':') : start
  const t2 = typeof end === 'string' ? end.split(':') : end
  let s = t1 || [0,0,0], e = t2 || [23,59,59];

  return [
    new Date(2022, 1, 1, s[0], s[1], s[2]),
    new Date(2022, 1, 1, e[0], e[1], e[2])
  ]
}

/**
 * base64转换成Blob
 * @param { String } dataurl base64
 * @returns Blob
*/
export const dataURLtoBlob = (dataurl) => {
  const arr = dataurl.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

/**
 * 将页面转换成图片下载
 * @param { String } url 下载url
 * @param { String } name 下载名称
 *
*/
export const downloadHtml2canvas = (url, name) => {
  const a = document.createElement('a')
  a.setAttribute('href', url)
  a.setAttribute('download', name)
  a.setAttribute('target', '_blank')
  const clickEvent = document.createEvent('MouseEvents')
  clickEvent.initEvent('click', true, true)
  a.dispatchEvent(clickEvent)
}

// 获取url上的参数并转为对象
export const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => {
      (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1))
      return a
    },
    {}
  )


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值