Skip to content

other 其他

ts
/**
 * 获取浏览器标识(PC)
 */
export function getPcBrowserType() {
  const agent = navigator.userAgent.toLowerCase() // 取得浏览器的userAgent字符串
  const isOpera = agent.indexOf('opera') > -1 // 判断是否Opera浏览器
  const isIE = agent.indexOf('compatible') > -1 && agent.indexOf('msie') > -1 && !isOpera // 判断是否IE浏览器
  const isEdge = agent.indexOf('edge') > -1 // 判断是否IE的Edge浏览器
  const isFirefox = agent.indexOf('firefox') > -1 // 判断是否Firefox浏览器
  const isSafari = agent.indexOf('safari') > -1 && agent.indexOf('chrome') === -1 // 判断是否Safari浏览器
  const isChrome = agent.indexOf('chrome') > -1 && agent.indexOf('safari') > -1 // 判断Chrome浏览器
  const isIE11 = agent.indexOf('trident') > -1 && agent.indexOf('rv:11.0') > -1
  return {
    agent,
    isOpera,
    isEdge,
    isFirefox,
    isSafari,
    isChrome,
    isIE11,
    isIE: (isIE && agent.replace(/.*msie (\d+)\.\d+;.*/g, '$1')) || 0
  }
}
/**
 * 客户端检测(移动端)
 */
export function getAppBrowserType() {
  const json = {
    userAgent: navigator.userAgent.toLowerCase(),
    isAndroid: Boolean(navigator.userAgent.match(/android/gi)),
    isIos: Boolean(navigator.userAgent.match(/iphone|ipod|ipad/gi)),
    isWeChat: Boolean(navigator.userAgent.match(/MicroMessenger/gi)),
    isQQ: Boolean(navigator.userAgent.match(/ QQ/gi)),
    isQQBrowser: Boolean(navigator.userAgent.match(/MQQBrowser/gi)),
    isUCBrowser: Boolean(navigator.userAgent.match(/UCBrowser/gi)),
    isSafari: Boolean(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)),
    iosVersion: ''
  }
  let iosVersion: any = json.userAgent.match(/os\s*(\d+)/)
  iosVersion = iosVersion ? iosVersion[1] || 0 : 0
  json.iosVersion = iosVersion
  return json
}

/**
 * 字符串形式的ip转整数形式
 * @param ipString
 */
export function ipStringToInteger(ipString: string) {
  if (!ipString) {
    throw new Error('ipString 找不到')
  }
  if (
    !/^(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(?:\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])){3}$/.test(
      ipString
    )
  ) {
    throw new Error('ipString 不是正确的ip')
  }
  const binaryString = ipString
    .split('.')
    .map(s => parseInt(s, 10).toString(2).padStart(8, '0'))
    .join('')
  return parseInt(binaryString, 2)
}
/**
 * 根据cidr获取ip范围段,数字形式
 * @param ipWithSubnet 192.168.0.1/24
 */
export function getIpRange(ipWithSubnet: string) {
  const [ipStr, subnetStr] = ipWithSubnet.split('/')
  const ip = ipStringToInteger(ipStr)
  const subnet = parseInt(subnetStr, 10)
  // eslint-disable-next-line no-bitwise
  const mask = 0xffffffff << (32 - subnet)

  // eslint-disable-next-line no-bitwise
  const networkAddress = ip & mask
  // eslint-disable-next-line no-bitwise
  const broadcastAddress = networkAddress + (1 << (32 - subnet)) - 1

  // eslint-disable-next-line no-bitwise
  const minIp = (networkAddress + 1) >>> 0 // 无符号右移位
  // eslint-disable-next-line no-bitwise
  const maxIp = (broadcastAddress - 1) >>> 0 // 无符号右移位

  return [minIp, maxIp]
}

/**
 * 基于promise和async/await封装的延迟执行
 * @param ms 延迟执行的毫秒数
 */
export function sleep(ms: number): Promise<void> {
  return new Promise<void>(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

/**
 * 对比两个对象的差异,并返回增加的和减少的属性
 * @param oldObj
 * @param newObj
 */
export function diffObject(oldObj: object, newObj: object) {
  const hasKey = (obj: object, k: string) => Object.prototype.hasOwnProperty.call(obj, k)
  /** 增加 */
  const increase = {}
  /** 减少 */
  const decrease = {}
  /** 对于newObj已经判断过的key */
  const usedKeys: string[] = []
  // 过滤old
  for (const key in oldObj) {
    if (hasKey(oldObj, key)) {
      const k = key as keyof typeof oldObj
      if (hasKey(newObj, k)) {
        usedKeys.push(k)
        if (oldObj[k] != newObj[k]) {
          // 如果值不相等,新增和减少都要有
          increase[k] = newObj[k]
          decrease[k] = oldObj[k]
        }
      } else {
        decrease[k] = oldObj[k]
      }
    }
  }
  // 过滤没比对过的new
  for (const key in newObj) {
    if (usedKeys.includes(key)) continue
    if (hasKey(newObj, key)) {
      const k = key as keyof typeof newObj
      increase[k] = newObj[k]
    }
  }
  return {
    /** 增加 */
    increase,
    /** 减少 */
    decrease
  }
}