SOURCE

/*
  **************************************************
  version: '0.10'
  author": "46898"
  description": 全局方法
  **************************************************
 */



/**
 * @param {*} Com 组件
 * @description HOC高阶组件
 */
export const wrapper = (Com) => {
  return {
    mounted () {
    },
    props: Com.props,
    render (h) {
      // createElement
      const slots = Object.keys(this.$slots).reduce((arr, key) => arr.concat(this.$slots[key]), [])
        .map(vnode => {
          // 手动更正 context
          vnode.context = this._self
          return vnode
        })

      return h(Com, {
        props: this.$props,
        attrs: this.$attrs,
        scopedSlots: this.$scopedSlots,
        on: this.$listeners
      }, slots)
    }
  }
}

/**
 *
 * @description 异步组件
 */
export const lazyLoadView = (AsyncView) => {
  const AsyncHandler = () => ({
    component: AsyncView,
    // loading: require('./Loading.vue').default,
    // error: require('./Timeout.vue').default,
    delay: 400,
    timeout: 10000
  })

  return Promise.resolve({
    functional: true,
    render (h, { data, children }) {
      return h(AsyncHandler, data, children)
    }
  })
}


/**
 *
 * @description 深拷贝
 */
export function deepCopy (target) {
  let result
  if (typeof target === 'object') {
    if (Array.isArray(target)) {
      result = []
      for (let i of target) {
        result.push(deepCopy(i))
      }
    } else if (target === null) {
      result = null
    } else if (target.constructor === RegExp) {
      result = target
    } else {
      result = {}
      for (let i of Object.keys(target)) {
        result[i] = deepCopy(target[i])
      }
    }
  } else {
    result = target
  }
  return result
}

/**
 *
 * @description 对象合并
 */
export function merge(target) {
  for (let i = 1, j = arguments.length; i < j; i++) {
    let source = arguments[i] || {};
    for (let prop in source) {
      if (source.hasOwnProperty(prop)) {
        let value = source[prop];
        if (value !== undefined) {
          target[prop] = value;
        }
      }
    }
  }

  return target;
};


export const getImg = async (url) => {
      return new Promise((resolve, reject) => {
        let img = new Image()
        img.src = url
        img.onload = function () {
          if (this.complete === true) {
            resolve(true)
            img = null
          }
        }
        img.onerror = function () {
          resolve(false)
          img = null
        }
      })
    }


/**
 * @description 根据目录全局导入
 */
// const middleware = _utils.importAll(require.context('@/router/middleware', false, /[^pipeline]\.(js)$/))
// modules: { ..._utils.importAll(require.context('@/store/module', false, /\.(js)$/), (module) => { return { ...module, namespaced: true } }) }

// const formComp = _utils.importAll(require.context('@/components/form', false, /\.(vue)$/))
export const importAll = (requireModule, callback = (module) => module) => {
  // /([a-z_]+)\.js$/i
  const modules = {}

  requireModule.keys().forEach(fileName => {
    if (fileName === './index.js') {
      return
    }
    const moduleName = fileName.replace(/(\.\/|\.(vue|js))/g, '')
    const fileModule = requireModule(fileName).default

    modules[moduleName] = callback(fileModule)
  })
  return modules
}



/**
 * @description 根据axios返回异常全局提醒
 */
export const errorMessage = (error) => {
  const errorMessage = {
    400: '错误请求',
    401: '未授权,请重新登录',
    403: '拒绝访问',
    404: '请求错误,未找到该资源',
    405: '请求方法未允许',
    410: '请求的资源被永久删除,请联系管理员',
    500: '服务器出错,请稍后再试',
    502: '网关错误',
    503: '服务不可用,服务器暂时过载或维护',
    504: '网关超时。'
  }
  let message = '连接到服务器失败,请检查网络'
  if (error['response']) {
    const { response: { status, statusText, data: { resultInfo, resultCode } } } = error
    if (resultCode) {
      return
    }
    message = errorMessage[status] || statusText || resultInfo
    if (status === 500) {
      sessionStorage.clear()
    }
  }
  // eslint-disable-next-line
  window.$message.error(message)
}

/**
 * @description 手机终端
 */
export const isMobile = () => {
  return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent))
}


export const isUserAgent = () => {
  const userAgentStr = navigator.userAgent.toLowerCase()
  const arr = ['iphone|Safari', 'huawei', 'honor', 'oppo', 'vivo', 'mi ', 'qq|QQ', 'baidu', 'sogou', 'uc|UC', '360']
  const result = arr.find(item => {
    const reg = new RegExp(item, 'g')
    return userAgentStr.match(reg)
  })
  return result || 'qt'
}

/**
 * @description try,catch捕获封装
 */
export const httpTo = (promise) => {
  return promise.then(data => {
    return [null, data]
  })
    .catch(err => {
      if (err && err.data && err.data.resultCode) {
        return [null, err.data]
      }
      return [err, null]
    })
}

/**
 * @description
 */
export const to = (fn) => {
  return async function (...args) {
    try {
      return [null, await fn.apply(this, args)]
    } catch (err) {
      return [err]
    }
  }
}

export const getAllRouteList = (arr, list = []) => {
  arr.map(item => {
    list.push(item)
    if (item.children && item.children.length) {
      list = getAllRouteList(item.children, list)
    }
  })
  return list
}

/**
 * @description 日期格式化
 */
export function   formatDate (date, fmt = 'yyyy/MM/dd hh:mm:ss') {
    let newDate = date instanceof Date ? date : new Date(date)
    let newFmt
    if ((/(y+)/).test(fmt)) {
    newFmt = fmt.replace(
        RegExp.$1,
        (`${newDate.getFullYear()}`).substr(4 - RegExp.$1.length)
    )
    }
    let o = {
    'M+': newDate.getMonth() + 1,
    'd+': newDate.getDate(),
    'h+': newDate.getHours(),
    'm+': newDate.getMinutes(),
    's+': newDate.getSeconds()
    }

    for (let k in o) {
    if (new RegExp(`(${k})`).test(newFmt)) {
        let str = `${o[k]}`

        newFmt = newFmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? str : (`00${str}`).substr(str.length)
        )
    }
    }

    return newFmt
}


/**
 * @description 文件下载
 */
export const downloadFile = (res, { fileName = '', suffix = '', success = '下载成功', failture = '下载失败' } = {}) => {
  let { header, blob } = res
  const reader = new FileReader()
  reader.readAsText(blob)
  reader.onload = function () {
       // 也可以通过 header['content-disposition'] 判断返回是否是JSON或者存在 还是文件流格式,并根据JSON 结果进行提示
    try {
      const { result } = reader
      const data = JSON.parse(result)
      window.$message.warning(data.resultInfo || failture)
      if (data['resultCode'] === '200009') {
        sessionStorage.clear()
        setTimeout(() => { location.reload() }, 1000)
      }
    } catch (error) {
      blob = new Blob([blob])
      /*
      new Blob([blob], {
        // 设置返回的文件类型
        type: type // 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为excel
    })
    */
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob)
      } else {
        let url = window.URL ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob)
        let link = document.createElement('a')
        if (fileName && suffix) {
          fileName = `${fileName}.${suffix}`
        } else {
          const disposition = header['content-disposition']
          if (disposition && disposition.split('fileName=')[1]) {
            fileName = decodeURIComponent(disposition.split('fileName=')[1])
          } else {
            failture && window.$message.warning(failture)
            return false
          }
        }
        link.style.display = 'none'
        link.href = url
        link.setAttribute('download', fileName)
        link.target = "_blank";
        link.rel = 'noopener noreferrer';
        document.body.appendChild(link)
        link.click() // link.dispatchEvent(new MouseEvent('click'))
        document.body.removeChild(link)
        window.URL.revokeObjectURL(url)
      }
      success && window.$message.success(success)
    }
  }
}

/**
 * @description 去空格
 */
export const trim = (str) => {
  return str.replace(/(^\s*)|(\s*$)/g, '')
}

/**
 * @description 域名合法性检测
 */
const checkURL = function(URL) {
  var str = URL
  // 判断URL地址的正则表达式为:http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
  // 下面的代码中应用了转义字符"\"输出一个字符"/"
  var Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/
  var objExp = new RegExp(Expression)
  if (objExp.test(str) === true) {
    return true
  } else {
    return false
  }
}

/**
 * @description 遍历参数url中?后面的 比如{a:111,b:222,c:333}变为a=111&b=222&c=333
 */
export const formatParam = (obj) => {
  let str = ''
  for (let i in obj) {
    str += `${i}=${obj[i]}&`
  }
  return str.slice(0, -1)
}

/**
 * @description  url参数处理(获取参数)方式一
 */
export const getQueryString = (name) => {
  var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
  var r = window.location.search.substr(1).match(reg)
  if (r != null) {
    return unescape(r[2])
  }
  return null
}

/**
 * @description url参数处理(获取参数)方式二
 */
export const setUrlParams = (key, value, url) => {
  const reg = new RegExp('(' + key + ')=([^&]*)', 'ig')
  let _url = url || location.href
  const result = reg.exec(_url)
  if (result) {
    return _url.replace(result[0], key + '=' + value)
  } else {
    const reg = /\?(.*)#?(.*)/gi
    const search = reg.exec(_url)
    if (search !== null) {
      return _url.replace(search[1], search[1] + '&' + key + '=' + value)
    } else {
      return ''
    }
  }
}

/**
 * @description url参数获取
 */
export const getUrlParams = (key, url) => {
  const reg = new RegExp('(' + key + ')=([^&]*)', 'ig')
  let _url = url || location.href
  const result = reg.exec(_url)
  if (result) {
    return result[2]
  } else {
    return ''
  }
}



export const RGBToHex = (color) => {
  const values = color
    .replace(/rgba?\(/, '')
    .replace(/\)/, '')
    .replace(/[\s+]/g, '')
    .split(',')
  const a = parseFloat(values[3] || 1)
  const r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255)
  const g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255)
  const b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255)
  return '#' +
    ('0' + r.toString(16)).slice(-2) +
    ('0' + g.toString(16)).slice(-2) +
    ('0' + b.toString(16)).slice(-2)
}


/**
 * @description 获取DPI
 */
export const getDPI = () => {
  let arrDPI = []
  let tmpNode = document.createElement('div')
  tmpNode.style.cssText = 'width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden'
  document.body.appendChild(tmpNode)
  arrDPI[0] = parseInt(tmpNode.offsetWidth)
  arrDPI[1] = parseInt(tmpNode.offsetHeight)
  tmpNode.parentNode.removeChild(tmpNode)
  return arrDPI
}

/**
 * @description 颜色是否深色
 */
export const isLight = (rgb) => {
  return (0.213 * rgb[0] + 0.715 * rgb[1] + 0.072 * rgb[2] > (255 / 2))
}

/**
 * @description 动态载入远程JS
 */
export const getJSLoad = (id, url) => {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = `${url}${url.includes('?') ? '&' : '?'}timestamp=${new Date().getTime()}`
    if (!document.body.querySelector(`#${id}`)) {
      script.setAttribute('id', id)
      document.body.appendChild(script)
    }
    script.onload = () => {
      resolve(script)
    }
    script.onerror = (e) => {
      reject(e)
    }
  })
}


/**
 * @value {*} mm数值
 * @description mm转换px
 */
export const mmConversionPx = (value) => {
  const inch = value * 10 / 254
  const c_value = inch * getDPI[0]
  return Math.floor(c_value * 100) / 100
}



/**
 * @description 获取el相对浏览器左上角left值
 */
export const getEleLeft = function (_el) {
  let offset = _el.offsetLeft
  if (_el.offsetParent != null) {
    offset += getEleLeft(_el.offsetParent)
  }
  return offset
}

/**
 * @description 获取el相对浏览器左上角top值
 */
export const getEleTop = function (_el) {
  let offset = _el.offsetTop
  if (_el.offsetParent != null) {
    offset += getEleTop(_el.offsetParent)
  }
  return offset
}

/**
 * @description 获取el父级所有scrollTop总和, 所有scrollLeft总和
 */
export const getEleScroll = function () {
  let arr = {
    scrollTop: 0,
    scrollLeft: 0
  }
  const init = function (_el, type = 'scrollTop') {
    let _parentNode
    _parentNode = _el.parentNode
    if (_parentNode[type]) {
      arr[type] = _parentNode[type] + arr[type]
    }
    if (_parentNode !== document.documentElement) {
      init(_parentNode, type)
    }
    return arr[type]
  }
  const reset = function () {
    arr = {
      scrollTop: 0,
      scrollLeft: 0
    }
  }
  return { init: init, reset: reset }
}()


export const debounce2 = function (fn, wait) {
  let timeout = null
  return function () {
    if (timeout !== null) {
      clearTimeout(timeout)
    }
    timeout = setTimeout(fn, wait)
  }
}

/**
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 * @description 函数防抖
 */
export const debounce = (func, wait, immediate) => {
  let timeout
  return function () {
    let that = this
    let args = arguments

    if (timeout) {
      clearTimeout(timeout)
    }
    if (immediate) {
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) {
        func.apply(that, args)
      }
    } else {
      timeout = setTimeout(() => {
        func.apply(that, args)
      }, wait)
    }
  }
}





 export function debounce2(func, wait, immediate) {
   let timeout, args, context, timestamp, result;

   const later = function() {
    // 据上一次触发时间间隔
     const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
     if (last < wait && last > 0) {
       timeout = setTimeout(later, wait - last);
     } else {
       timeout = null;
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
       if (!immediate) {
         result = func.apply(context, args);
         if (!timeout) context = args = null;
       }
     }
   };

   return function(...args) {
     context = this;
     timestamp = +new Date();
     const callNow = immediate && !timeout;
    // 如果延时不存在,重新设定延时
     if (!timeout) timeout = setTimeout(later, wait);
     if (callNow) {
       result = func.apply(context, args);
       context = args = null;
     }

     return result;
   };
 }

/**
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 * @description 函数节流
 */
export const throttle = (func, wait, type) => {
  if (type === 1) {
    var previous = 0
  } else if (type === 2) {
    var timeout
  }
  return function () {
    let context = this
    let args = arguments
    if (type === 1) {
      let now = Date.now()

      if (now - previous > wait) {
        func.apply(context, args)
        previous = now
      }
    } else if (type === 2) {
      if (!timeout) {
        timeout = setTimeout(() => {
          timeout = null
          func.apply(context, args)
        }, wait)
      }
    }
  }
}

/**
 * @description 设置cookie
 */
export const setCookie = (name, value, expiredays = 1) => {
  const exdate = new Date()
  exdate.setDate(exdate.getDate() + expiredays)
  document.cookie = name + '=' + escape(value) + ((expiredays === null) ? '' : ';expires=' + exdate.toGMTString()) + ';path=/;'
  console.error(name, value, escape(value), document.cookie)
}

/**
 * @description 获取cookie
 */
export const getCookie = (name) => {
  if (document.cookie.length > 0) {
    let sIndex = document.cookie.indexOf(name + '=')
    if (sIndex !== -1) {
      sIndex = sIndex + name.length + 1
      let eIndex = document.cookie.indexOf(';', sIndex)
      if (eIndex === -1) {
        eIndex = document.cookie.length
      }
      return unescape(document.cookie.substring(sIndex, eIndex))
    }
  }
  return ''
}

/**
 * @description 清空cookie
 */
export const clearCookie = () => {
  const exdate = new Date()
  exdate.setDate(exdate.getDate() - 1 * 60 * 60 * 1000)
  const cookies = document.cookie.match(/[^ =;]+(?=\\=)/g)
  if (cookies) {
    for (let i = 0; i < cookies.length; i++) {
      document.cookie = cookies[i] + '=0; expires=' + exdate.toGMTString() + ';path=/;'
    }
  }
}

/* eslint-disable */
(function buildConsole (arr) {
  const getStyle = (style) => {
    style = Object.assign({}, {
      'padding': '1px',
      'color': '#fff'
    }, style)
    return function (_style) {
      for (let [key, value] of Object.entries(style)) {
        _style = _style + `${key}:${value};`
      }
      return _style
    }()
  }
  for (let [key, value] of Object.entries(arr)) {
    console.log(`%c ${key} %c ${value} `, getStyle({ 'border-radius': '3px 0 0 3px', background: '#606060' }), getStyle({ 'border-radius': '0 3px 3px 0', background: '#42c02e' }))
  }
}({ 'Environment': VUE_APP_ENV, 'Build Date ': VUE_APP_VERSION }))
/* eslint-disable */
console 命令行工具 X clear

                    
>
console