JavaScript Util工具类

class Util {
  /**
   * 删除对象数组元素
   * @param srcObjArr 原对象数组
   * @param properties 需要删除的属性
   */
  public delArrObjProperties(srcObjArr: any, property: any) {
    return srcObjArr.map((el: any) => {
      if (
        el[property].length === 0 ||
        el[property] === '' ||
        Object.keys(el[property]).length === 0 ||
        el[property]?.length === 0
      ) {
        delete el[property]
      }
      return el
    })
  }

  /**
   * @description 字符串布尔值转布尔
   * @params envName 任意类型
   */
  public convertToBoolean = (envName: any) => {
    return envName === 'true' ? true : envName === 'false' ? false : envName
  }

  /**
   * 查找父节点,传入参数:需要遍历的json,需要匹配的id
   * @param data 源数据
   * @param id 哪个节点父节点就是哪个节点的id
   * @returns
   */
  public findParentNode(data: any, id: any): any {
    //设置结果
    let result
    if (!data) {
      return //如果data传空,直接返回
    }
    for (let i = 0; i < data.children.length; i++) {
      const item = data.children[i]
      if (item.id == id) {
        result = data
        return result //这里是实际返回的值,你可以只返回当前对象,或者指定当前对象的某个字段。
      } else if (item.children && item.children.length > 0) {
        //如果有子集,则把子集作为参数重新执行本方法
        result = this.findParentNode(item, id)
        //关键,千万不要直接return本方法,不然即使没有返回值也会将返回return,导致最外层循环中断,直接返回undefined,要有返回值才return才对
        if (result) {
          return result
        }
      }
    }
    //如果执行循环中都没有return,则在此return
    return result
  }

  /**
   * 寻找孩子节点
   * @param data 数据源
   * @param id 哪个节点子节点就是哪个节点的id
   * @returns 返回找到的孩子节点
   */
  public findChildrenNode(data: any, id: any): any {
    for (let i = 0; i < data.length; i++) {
      const el = data[i]
      if (el.id === id) {
        return el?.children
      } else {
        if ('children' in data) {
          this.findChildrenNode(el?.children, id)
        }
      }
    }
  }

  /**
   * pro-table数据格式与后端数据格式之前的转化
   * @param data 数据
   * @param toTable 不是必传项,true表示后端数据转化为table数据,不传根据data是否含有data来判断是不是toData
   * @returns
   */
  public tableDataTransfer(data: any, toTable?: boolean) {
    let tableData: any = {}
    let flag = false
    if (arguments.length < 2) {
      // 没传toTable,根据data是否含有data来判断是不是toData
      if (data.data) {
        flag = true
      } else {
        flag = false
      }
    } else {
      if (toTable) {
        flag = true
      } else {
        flag = false
      }
    }
    if (flag) {
      tableData = {
        data: data.data?.content || [],
        success: data.status === 'success',
        total: data.data?.totalElements,
      }
    } else {
      const pagination = {
        size: data.pageSize || 10,
        page: (data.current || 1) - 1,
      }
      tableData = { ...data, ...pagination }
      delete tableData.pageSize
      delete tableData.current
    }

    return tableData
  }

  /**
   * 将对象作为参数添加到URL
   * @param baseUrl url
   * @param obj
   * @returns {string}
   * eg:
   *  let obj = {a: '3', b: '4'}
   *  setObjToUrlParams('www.baidu.com', obj)
   *  ==>www.baidu.com?a=3&b=4
   */
  public setObjToUrlParams(baseUrl: string, obj: any): string {
    let parameters = ''
    for (const key in obj) {
      parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
    }
    parameters = parameters.replace(/&$/, '')
    return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters
  }

  /**
   * 深度合并对象
   * @param src
   * @param target
   * @returns
   */
  public deepMerge<T = any>(src: any = {}, target: any = {}): T {
    let key: string
    for (key in target) {
      src[key] = this.isObject(src[key])
        ? this.deepMerge(src[key], target[key])
        : (src[key] = target[key])
    }
    return src
  }

  public withInstall = <T>(component: T, alias?: string) => {
    const comp = component as any
    comp.install = (app: any) => {
      app.component(comp.name || comp.displayName, component)
      if (alias) {
        app.config.globalProperties[alias] = component
      }
    }
    return component as T
  }

  /**
   * 判断对象
   * @param val
   * @returns
   */
  public isObject(val: any): val is Record<any, any> {
    return val !== null && this.is(val, 'Object')
  }
  public is(val: unknown, type: string) {
    return toString.call(val) === `[object ${type}]`
  }

  /**
   * @description 日期格式化
   * @param dateTime 日期
   * @param pattern 日期格式
   * @returns 格式化日期
   */
  public formatDate(dateTime?: any, format?: string = "YY-MM-DD hh:mm:ss" ) {
      let time = dateTime ? dateTime : new Date();
      let date;
      if (typeof time === "object") {
        date = time;
      } else {
        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
          time = parseInt(time);
        } else if (typeof time === "string") {
          time = time
            .replace(new RegExp(/-/gm), "/")
            .replace("T", " ")
            .replace(new RegExp(/\.[\d]{3}/gm), "");
        }
        if (typeof time === "number" && time.toString().length === 10) {
          time = time * 1000;
        }
        date = new Date(time);
      }
      const formatObj = {
        YYYY: date.getFullYear(),
        MM: date.getMonth() + 1,
        DD: date.getDate(),
        HH: date.getHours(),
        mm: date.getMinutes(),
        ss: date.getSeconds(),
        W: date.getDay(),
      };
      const time_str = format.replace(/YYYY|MM|DD|hh|mm|ss|W/g, (key, result) => {
        let value = formatObj[key];
        if (key === "W") {
          return "星期" + ["日", "一", "二", "三", "四", "五", "六"][value];
        }
        if (result.length > 0 && value < 10) {
          value = "0" + value;
        }
        return value || 0;
      });
      return time_str;
  }

  /**
   * @description 判断两个数组是否有交集
   * @param arr1 待查询数组
   * @param arr2 参考数组
   * @returns 有交集返回true,否则返回false
   */
  public findIntersection(arr1: any, arr2: any) {
    const intersect: any = new Set([...arr1].filter((x) => arr2.includes(x)))
    if (intersect.size > 0) return true
    return false
  }

  /**
   * @description 处理description无数据状态数据显示问题
   * @param sourceData 待格式化数据
   * @param defaultData 待格式化自定义
   */
  public setDefaultValue(sourceData: any, defaultVal?: any, tofix?: number) {
    let data = defaultVal
    if (tofix && sourceData) {
      data =
        sourceData || sourceData === 0
          ? sourceData.toFixed(tofix)
          : arguments.length > 1
          ? defaultVal
          : '--'
    } else {
      data = sourceData || sourceData === 0 ? sourceData : arguments.length > 1 ? defaultVal : '--'
    }
    return data
  }

  /**
   * 空数据或者无效数据转换为默认显示模式
   * @param sourceData 源数据
   * @param defaultVal 格式化默认值
   * @returns
   */
  public transformEmptyData(sourceData: any, defaultVal?: any) {
    if (sourceData) {
      Object.keys(sourceData).map((key) => {
        if (
          sourceData[key] === null ||
          sourceData[key] === '' ||
          sourceData[key] === undefined ||
          sourceData[key] === NaN
        ) {
          sourceData[key] = defaultVal || '--'
        }
      })
    }
    return sourceData
  }

  /**
   * 最终版防抖(支持立即执行,设置延迟,取消防抖)
   * @param fn 回调函数
   * @param delay 延迟
   * @param immediate 是否立即执行
   * @returns debounced
   */
  public finalDebounce(fn: any, delay: number, immediate: boolean) {
    let timer: any = null
    const debounced: any = () => {
      if (timer) clearTimeout(timer)
      // 立即执行
      if (immediate) {
        const callNow = !timer
        timer = setTimeout(() => {
          timer = null
        }, delay || 500)
        if (callNow) fn.call()
      } else {
        timer = setTimeout(() => {
          fn.call()
        }, delay || 500)
      }
    }
    debounced.cancel = () => {
      // 取消防抖
      clearTimeout(timer)
      timer = null
    }
    return debounced
  }

  /**
   * 根据download参数判断预览还是下载
   * @param url  附件地址
   * @param download  附件可以预览或者下载
   */
  public fileDownload(url: any, download = true) {
    function getFileName(_url: string) {
      const name = _url.split('/')
      return name.pop()
    }

    const filename: any = getFileName(url)

    fetch(url, {
      method: 'GET',
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/octet-stream',
      },
      mode: 'no-cors',
    })
      .then((response) => {
        return response.blob()
      })
      .then((blob) => {
        const blobUrl = window.URL.createObjectURL(blob)
        const tempLink = document.createElement('a')
        tempLink.style.display = 'none'
        tempLink.href = blobUrl
        if (download) {
          //下载
          tempLink.setAttribute('download', filename)
        } else {
          //预览
          tempLink.setAttribute('target', '_blank')
        }
        document.body.appendChild(tempLink)
        tempLink.click()
        setTimeout(() => {
          URL.revokeObjectURL(blobUrl)
          document.body.removeChild(tempLink)
        })
      })
      .catch()
  }
}
export default new Util()
posted @   沐雨辰沨  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2021-09-09 hbuilder检测不到夜神模拟器
2020-09-09 JavaScript——for循环
2020-09-09 迭代器
2020-09-09 DOM外联样式相关操作
点击右上角即可分享
微信分享提示