AlexZ33 / lessions

自己练习的各种demo和课程
12 stars 2 forks source link

前端常见utils #31

Open AlexZ33 opened 5 years ago

AlexZ33 commented 5 years ago

 /**
   * @method isObject
   * @param obj
   * @returns {boolean}
   * @desc 判断当前对象是否是对象类型
   */
  _util.isObject = function (obj) {
    const type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  };
  /**
   * typeof null //"object"
   * typeof {} //"object"
   * typeof [] //"object"
   * typeof function foo(){} //"function" (特殊情况)
   *  */
  _util.isObjectSecond = function (obj) {
    return typeof obj === 'object' && obj !== null
  }

  _util.isObjectThird = function (obj) {
    return Object.prototype.toString.call(obj) === '[object Object]'
  }
AlexZ33 commented 4 years ago

时间操作

从当前时间算起,n天以前

const moment = require('moment')
moment().subtract(n, 'days').startOf('date'

console.log(moment().subtract(1, 'days').startOf('date'))
console.log(moment().subtract(2, 'days').startOf('date'))

image image

console.log(moment("2019-09-22", "YYYY-MM-DD").startOf('date').isValid())

image

AlexZ33 commented 4 years ago
const expiredDate = moment().subtract(2, 'days').startOf('date');
console.log(expiredDate)
console.log(moment("2019-09-22", "YYYY-MM-DD").startOf('date').isBefore())

image

AlexZ33 commented 4 years ago
function isObject(val) {
  return typeof val === 'function' || toString.call(val) === '[object Object]';
}

function isPrimitive(val) {
  return typeof val === 'object' ? val === null : typeof val !== 'function';
}
AlexZ33 commented 4 years ago

https://github.com/hilongjw/vue-lazyload/blob/master/src/util.js


import assign from 'assign-deep'

const inBrowser = typeof window !== 'undefined'
export const hasIntersectionObserver = checkIntersectionObserver()

function checkIntersectionObserver () {
  if (inBrowser &&
    'IntersectionObserver' in window &&
    'IntersectionObserverEntry' in window &&
    'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
  // Minimal polyfill for Edge 15's lack of `isIntersecting`
  // See: https://github.com/w3c/IntersectionObserver/issues/211
    if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) {
      Object.defineProperty(window.IntersectionObserverEntry.prototype,
        'isIntersecting', {
          get: function () {
            return this.intersectionRatio > 0
          }
        })
    }
    return true
  }
  return false
}

export const modeType = {
  event: 'event',
  observer: 'observer'
}

// CustomEvent polyfill
const CustomEvent = (function () {
  if (!inBrowser) return
  if (typeof window.CustomEvent === 'function') return window.CustomEvent
  function CustomEvent (event, params) {
    params = params || { bubbles: false, cancelable: false, detail: undefined }
    var evt = document.createEvent('CustomEvent')
    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
    return evt
  }
  CustomEvent.prototype = window.Event.prototype
  return CustomEvent
})()

function remove (arr, item) {
  if (!arr.length) return
  const index = arr.indexOf(item)
  if (index > -1) return arr.splice(index, 1)
}

function some (arr, fn) {
  let has = false
  for (let i = 0, len = arr.length; i < len; i++) {
    if (fn(arr[i])) {
      has = true
      break
    }
  }
  return has
}

function getBestSelectionFromSrcset (el, scale) {
  if (el.tagName !== 'IMG' || !el.getAttribute('data-srcset')) return

  let options = el.getAttribute('data-srcset')
  const result = []
  const container = el.parentNode
  const containerWidth = container.offsetWidth * scale

  let spaceIndex
  let tmpSrc
  let tmpWidth

  options = options.trim().split(',')

  options.map(item => {
    item = item.trim()
    spaceIndex = item.lastIndexOf(' ')
    if (spaceIndex === -1) {
      tmpSrc = item
      tmpWidth = 999998
    } else {
      tmpSrc = item.substr(0, spaceIndex)
      tmpWidth = parseInt(item.substr(spaceIndex + 1, item.length - spaceIndex - 2), 10)
    }
    result.push([tmpWidth, tmpSrc])
  })

  result.sort(function (a, b) {
    if (a[0] < b[0]) {
      return 1
    }
    if (a[0] > b[0]) {
      return -1
    }
    if (a[0] === b[0]) {
      if (b[1].indexOf('.webp', b[1].length - 5) !== -1) {
        return 1
      }
      if (a[1].indexOf('.webp', a[1].length - 5) !== -1) {
        return -1
      }
    }
    return 0
  })
  let bestSelectedSrc = ''
  let tmpOption

  for (let i = 0; i < result.length; i++) {
    tmpOption = result[i]
    bestSelectedSrc = tmpOption[1]
    const next = result[i + 1]
    if (next && next[0] < containerWidth) {
      bestSelectedSrc = tmpOption[1]
      break
    } else if (!next) {
      bestSelectedSrc = tmpOption[1]
      break
    }
  }

  return bestSelectedSrc
}

function find (arr, fn) {
  let item
  for (let i = 0, len = arr.length; i < len; i++) {
    if (fn(arr[i])) {
      item = arr[i]
      break
    }
  }
  return item
}

const getDPR = (scale = 1) => inBrowser ? (window.devicePixelRatio || scale) : scale

function supportWebp () {
  if (!inBrowser) return false

  let support = true
  const d = document

  try {
    let el = d.createElement('object')
    el.type = 'image/webp'
    el.style.visibility = 'hidden'
    el.innerHTML = '!'
    d.body.appendChild(el)
    support = !el.offsetWidth
    d.body.removeChild(el)
  } catch (err) {
    support = false
  }

  return support
}

function throttle (action, delay) {
  let timeout = null
  let lastRun = 0
  return function () {
    if (timeout) {
      return
    }
    let elapsed = Date.now() - lastRun
    let context = this
    let args = arguments
    let runCallback = function () {
      lastRun = Date.now()
      timeout = false
      action.apply(context, args)
    }
    if (elapsed >= delay) {
      runCallback()
    } else {
      timeout = setTimeout(runCallback, delay)
    }
  }
}

function testSupportsPassive () {
  if (!inBrowser) return
  let support = false
  try {
    let opts = Object.defineProperty({}, 'passive', {
      get: function () {
        support = true
      }
    })
    window.addEventListener('test', null, opts)
  } catch (e) {}
  return support
}

const supportsPassive = testSupportsPassive()

const _ = {
  on (el, type, func, capture = false) {
    if (supportsPassive) {
      el.addEventListener(type, func, {
        capture: capture,
        passive: true
      })
    } else {
      el.addEventListener(type, func, capture)
    }
  },
  off (el, type, func, capture = false) {
    el.removeEventListener(type, func, capture)
  }
}

const loadImageAsync = (item, resolve, reject) => {
  let image = new Image()
  if (!item || !item.src) {
    const err = new Error('image src is required')
    return reject(err)
  }

  image.src = item.src

  image.onload = function () {
    resolve({
      naturalHeight: image.naturalHeight,
      naturalWidth: image.naturalWidth,
      src: image.src
    })
  }

  image.onerror = function (e) {
    reject(e)
  }
}

const style = (el, prop) => {
  return typeof getComputedStyle !== 'undefined'
    ? getComputedStyle(el, null).getPropertyValue(prop)
    : el.style[prop]
}

const overflow = (el) => {
  return style(el, 'overflow') + style(el, 'overflow-y') + style(el, 'overflow-x')
}

const scrollParent = (el) => {
  if (!inBrowser) return
  if (!(el instanceof HTMLElement)) {
    return window
  }

  let parent = el

  while (parent) {
    if (parent === document.body || parent === document.documentElement) {
      break
    }

    if (!parent.parentNode) {
      break
    }

    if (/(scroll|auto)/.test(overflow(parent))) {
      return parent
    }

    parent = parent.parentNode
  }

  return window
}

function isObject (obj) {
  return obj !== null && typeof obj === 'object'
}

function ObjectKeys (obj) {
  if (!(obj instanceof Object)) return []
  if (Object.keys) {
    return Object.keys(obj)
  } else {
    let keys = []
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        keys.push(key)
      }
    }
    return keys
  }
}

function ArrayFrom (arrLike) {
  let len = arrLike.length
  const list = []
  for (let i = 0; i < len; i++) {
    list.push(arrLike[i])
  }
  return list
}

function noop () {}

class ImageCache {
  constructor ({ max }) {
    this.options = {
      max: max || 100
    }
    this._caches = []
  }

  has (key) {
    return this._caches.indexOf(key) > -1
  }

  add (key) {
    if (this.has(key)) return
    this._caches.push(key)
    if (this._caches.length > this.options.max) {
      this.free()
    }
  }

  free () {
    this._caches.shift()
  }
}

export {
  ImageCache,
  inBrowser,
  CustomEvent,
  remove,
  some,
  find,
  assign,
  noop,
  ArrayFrom,
  _,
  isObject,
  throttle,
  supportWebp,
  getDPR,
  scrollParent,
  loadImageAsync,
  getBestSelectionFromSrcset,
  ObjectKeys
}
AlexZ33 commented 3 years ago
/**
 * cookie 相关
 * @type {{prefix: string, set: cookie.set, get: cookie.get, del: cookie.del, name: cookie.name}}
 */
var cookie = {
    prefix: "",
    set: function (name, val, timeout) {
        expires = new Date, expires.setTime(expires.getTime() + 1e3 * timeout), document.cookie = this.name(name) + "=" + escape(val) + "; expires=" + expires.toGMTString() + "; path=/"
    },
    get: function (name) {
        for (cookie_name = this.name(name) + "=", cookie_length = document.cookie.length, cookie_begin = 0; cookie_begin < cookie_length;) {
            if (value_begin = cookie_begin + cookie_name.length, document.cookie.substring(cookie_begin, value_begin) == cookie_name) {
                var valStr = document.cookie.indexOf(";", value_begin);
                return -1 == valStr && (valStr = cookie_length), unescape(document.cookie.substring(value_begin, valStr))
            }
            if (cookie_begin = document.cookie.indexOf(" ", cookie_begin) + 1, 0 == cookie_begin)break
        }
        return null
    },
    del: function (name) {
        new Date;
        document.cookie = this.name(name) + "=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/"
    },
    name: function (name) {
        return this.prefix + name
    }
};

/**
 * 微信锁,防止方法重复提交.
 */
var wx_lock = {
    open: function (fname) {
        if (wx_lock[fname + "_lock"] == "on") {
            return true;
        } else {
            wx_lock[fname + "_lock"] = "on";
            return false;
        }
    },
    close: function (fname) {
        wx_lock[fname + "_lock"] = "";
    }
};

/**
 * 通用
 * @type {{tips: util.tips}}
 */

var slider = {
 //判断设备是否支持touch事件
    touch:('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,

 //事件
 events:{
  slider:document,
  handleEvent:function(event){
   if(event.type == 'touchstart'){
    this.start(event);
   }else if(event.type == 'touchmove'){
    this.move(event);
   }else if(event.type == 'touchend'){
    this.end(event);
   }
  },

  //滑动开始
  start:function(event){
   //touches数组对象获得屏幕上所有的touch,取第一个touch
   var touch = event.targetTouches[0];
   //取第一个touch的坐标值
   startPos = {x:touch.pageX,y:touch.pageY,time:+new Date};
   //这个参数判断是垂直滚动还是水平滚动
   isScrolling = 0;
   this.slider.addEventListener('touchmove',this,false);
   this.slider.addEventListener('touchend',this,false);
  },

  //移动
  move:function(event){
   //当屏幕有多个touch或者页面被缩放过,就不执行move操作
   if(event.targetTouches.length > 1 || event.scale && event.scale !== 1) return;
   var touch = event.targetTouches[0];
   endPos = {x:touch.pageX - startPos.x,y:touch.pageY - startPos.y};
   //isScrolling为1时,表示纵向滑动,0为横向滑动
   isScrolling = Math.abs(endPos.x) < Math.abs(endPos.y) ? 1:0;
   if(isScrolling === 1){
    //阻止触摸事件的默认行为,即阻止滚屏
    event.preventDefault();
   }
  },

  //滑动释放
  end:function(event){
   //滑动的持续时间
   var duration = +new Date - startPos.time;
   var i = 0;
   if(Number(duration) > 10){
    if(isScrolling === 1){
     //判断是上移还是下移,当偏移量大于10时执行
     if(endPos.y < -10){
      i = 1;
     }else if(endPos.y > 10){
      i = 3;
     }
    }else if(isScrolling === 0){
     //判断是左移还是右移,当偏移量大于10时执行
     if(endPos.x > 10){
      i = 2;
     }else if(endPos.x < -10){
      i = 4;
     }
    }
    this.callback(i);
    startPos = endPos = null;
    return false;
   }

   //解绑事件
   this.slider.removeEventListener('touchmove',this,false);
   this.slider.removeEventListener('touchend',this,false);
  },

  //要执行函数
  callback:function(direction){
   //上右下左1234
   switch(direction){
    case 1:

     break;
    case 2:

     break;
    case 3:

     break;
    case 4:

     break;
    default:
     break;
   };
  },
    },

 //初始化
    init:function(){
        if(!!this.touch) this.events.slider.addEventListener('touchstart',this.events,false);
    }
};

var util = {
    //提示
    tips: function (content, timeout) {
        $(".indexct_tips").remove();
        var msgHtml = '<div class="indexct_tips">' +
            '<p>' + content + '</p>' +
            '<div class="indexct_tips_overlay"></div>' +
            '</div>';
        $(msgHtml).appendTo("body").fadeOut(timeout || 300000);
    },
    //提示
    successTips: function (content, timeout) {
        $(".successTips").remove();
        var msgHtml = '<div class="successTips">' +
            '<p>' + content + '</p>' +
            '<div class="successTips_overlay"></div>' +
            '</div>';
        $(msgHtml).appendTo("body").fadeOut(timeout || 1000);
//      util.tips("ssss")

    },
    //提示
    prize1:function(getPrizeTxt){
        $(".prize-layer").remove();
        var prizeStr = '<div class="prize-layer">'+
            '<div class="prize-wrap">'+
                '<div class="prize-txt">'+
                    '<h1>恭喜你!</h1>'+
                    '<p>'+'获得'+getPrizeTxt+'</p>'+
                '</div>'+
                '<div class="information">'+
                '<input type="text" name="" id="name" value="" placeholder="请填写姓名"/>'+
                    '<input type="text" name="" id="" value="" placeholder="请填写手机号码获取"/><label for=""></label>'+
                    '<section class="express-area">'+
                        '<a id="expressArea" href="javascript:void(0)">'+
                            '<dl>'+
                                '<dd>省   市   区/县</dd>'+
                            '</dl>'+
                       '</a>'+
                    '</section>'+
                    '<input type="text" name="" id="" value="" placeholder="请输入地址"/><label for=""></label>'+
                '</div>'+
                '<div class="prize-confirm">'+
                    '<img class="tell" src="../cap-img/getPrize.png"/>'+
                '</div>'+
            '</div>'+
        '</div>';
        $(prizeStr).appendTo("body");
    },
    prize2:function(getPrizeTxt){
        $(".prize-layer").remove();
        var prizeStr = '<div class="prize-layer">'+
            '<div class="prize-wrap">'+
                '<div class="prize-txt">'+
                    '<h1>'+'获得'+'恭喜你!</h1>'+
                    '<p>'+getPrizeTxt+'</p>'+
                '</div>'+
                '<div class="information">'+
                    '<input type="text" name="" id="" value="" placeholder="请填写手机号码获取"/><label for=""></label>'+
                '</div>'+
                '<div class="prize-confirm">'+
                    '<img class="tell" src="../cap-img/getPrize.png"/>'+
                '</div>'+
            '</div>'+
        '</div>';
        $(prizeStr).appendTo("body");

    },
    prize3:function(){
        $(".prize-layer").remove();
        var prizeStr = '<div class="prize-layer">'+
            '<div class="prize-wrap">'+
                '<div class="prize-txt">'+
                    '<h1>非常遗憾!</h1>'+
                    '<p>再来一次,再来一次吧</p>'+
                '</div>'+
                '<div class="prize-confirm">'+
                    '<img class="onceAgain" src="../cap-img/losePrize.png"/>'+
                '</div>'+
            '</div>'+
        '</div>';
        $(prizeStr).appendTo("body");
    },
    confirm: function (content, callback) {
        $(".weui_dialog_confirm").remove();
        var msgHtml = '<div class="weui_dialog_confirm"><div class="weui_mask"></div><div class="weui_dialog">' +
            '<div class="weui_dialog_hd"><strong class="weui_dialog_title">确认</strong></div>' +
            '<div class="weui_dialog_bd">' + content + '</div>' +
            '<div class="weui_dialog_ft"><a href="javascript:;" class="weui_btn_dialog primary">确定</a>' +
            '<a href="javascript:;" class="weui_btn_dialog default" onclick="$(\'.weui_dialog_confirm\').remove();">取消</a></div></div>' +
            '</div>';
        $(msgHtml).appendTo("body");
        $(".weui_btn_dialog.primary").one("click", function () {
            $.isFunction(callback) && callback();
            $('.weui_dialog_confirm').remove();
        })
    },
    //是否微信
    isWeixn: function () {
        var ua = navigator.userAgent.toLowerCase();
        if (ua.match(/MicroMessenger/i) == "micromessenger") {
            return true;
        } else {
            return false;
        }
    },
    //验证手机号
    isMobel: function (value) {
        if (/^(1)\d{10}$/g.test(value)) {
            return true;
        } else {
            return false;
        }
    },
    //截取字符串 str:字符串  ,len 需要截取的长度
    cutString: function (str, len) {
        if (str.length > len) {
            str = str.substring(0, len);
            return str;
        } else {
            return str;
        }
    },
    //截取掉最后一个字符
    cutLastOne:function(str){
        str = str.substring(0,str.length-1);
        return str;
    },
    //获取url参数
    getQueryString: function (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;
    },
    //判断是否有特殊字符
    matchSpecial: function (str) {
        var containSpecial = RegExp(/[(\~)(\!)(\@)(\#)(\$)(\%)(\s)(\^)(\&)(\*)(\()(\))(\-)(\_)(\+)(\=)(\[)(\])(\{)(\})(\|)(\\)(\;)(\:)(\,)(\')(\")(\.)(\/)(\<)(\>)(\?)(\【)(\】)(\()(\))]/gi);
        return ( str.match(containSpecial) );
    },
    //判断是否有特殊字符
    containSpecial: function (s) {
        var containSpecial = RegExp(/[(\~)(\!)(\@)(\#)(\$)(\%)(\^)(\&)(\*)(\()(\))(\-)(\_)(\+)(\=)(\[)(\])(\{)(\})(\|)(\\)(\;)(\:)(\,)(\')(\")(\.)(\/)(\<)(\>)(\?)(\【)(\】)(\()(\))]+/);
        return ( containSpecial.test(s) );
    }
};
$(function(){
    window.sysinfo && window.sysinfo.cookie && window.sysinfo.cookie.pre && (cookie.prefix = window.sysinfo.cookie.pre);
})
AlexZ33 commented 3 years ago

define('utils/util', [
    'libs/jquery',
    'libs/aes/aes',
    'share/libs/lodash',
    'libs/Class',
    'router/router',
    'utils/getPageId',
    'libs/jquery.placeholder'
], ($, CryptoJS, { default: _ }, Class, { default: router }, { isReleaseMode }) => {
    const CATALOG_TYPE = {
        DIR: '1',
        PC: '2',
        PHONE: '3',
        PAD: '4',
        POPUP: '5'
    };

    function isTrue(value) {
        return (value === true || value === 'true');
    }

    function isFalse(value) {
        return (value === false || value === 'false');
    }

    function getBoolean(value, def) {
        return (isTrue(value) || isFalse(value)) ? isTrue(value) : def;
    }

    function isEmptyString(str) {
        return (str !== undefined && (`${str}`).replace(/ /g, '').length === 0);
    }

    /**
     * 设置输入框的placeholder, 包括不支持placeholder属性的IE9
     * @param {DOM/jQuery DOM} element 输入框元素
     * @param {String} value placeholder的内容
     */
    function setPlaceholder(element, value) {
        if (typeof value === 'string') {
            const $element = $(element);
            $element.attr('placeholder', value);
            if (!('placeholder' in document.createElement('input'))) {
                $element.placeholder({ customClass: 'tiny-placeholder' });
            }
        }
    }

    /**
     * 检测浏览器的类型及版本
     * @return {Object} [属性version表示浏览器的版本,是字符串类型;小写的浏览器名称属性,是布尔型]
     */
    const browserDetect = (function () {
        const browser = {};
        const userAgent = navigator.userAgent.toLowerCase(); let
            aAgentInfo;

        /* eslint-disable */
        (aAgentInfo = userAgent.match(/rv:([\d.]+)\) like gecko/)) ? browser.msie = true
            : (aAgentInfo = userAgent.match(/msie ([\d.]+)/)) ? browser.msie = true
                : (aAgentInfo = userAgent.match(/firefox\/([\d.]+)/)) ? browser.firefox = true
                    : (aAgentInfo = userAgent.match(/chrome\/([\d.]+)/)) ? browser.chrome = true
                        : (aAgentInfo = userAgent.match(/opera.([\d.]+)/)) ? browser.opera = true
                            : (aAgentInfo = userAgent.match(/version\/([\d.]+).*safari/)) ? browser.safari = true : 0;
        /* eslint-enable */

        if (!aAgentInfo) {
            aAgentInfo = [undefined, '47.0'];
        }
        browser.version = aAgentInfo[1]; // eslint-disable-line

        return browser;
    }());

    function showLoading(param) {
        // 扩展showLoading方法,可以在指定的dom中转圈, hide的时候也要传dom
        let loadingDom;

        if (param.dom) {
            const domPosn = param.dom.css('position');
            if (!domPosn || domPosn === 'static') {
                param.dom.css('position', 'relative');
            }
            loadingDom = param.dom.find('.loadingMask');
            if (!loadingDom || !loadingDom.length) {
                // eslint-disable-next-line
                loadingDom = $(`<div class="loadingMask"><div class="loadingBox"><div id="loading" class="loading"><span class="_loading"></span><span class="loading-text" id="mask-loading-text">${param.info || ''}</span></div></div></div>`);
                param.dom.append(loadingDom);
            }

            loadingDom.removeAttr('style');
            param.style && loadingDom.css(param.style); // eslint-disable-line

            return;
        }

        loadingDom = $('#loadingMask');
        if (loadingDom.length) {
            loadingDom.removeAttr('style');
            param.style && loadingDom.css(param.style); // eslint-disable-line
            loadingDom.show().find('#loading').text(param.info || 'Loading...');
            return;
        }

        // eslint-disable-next-line
        loadingDom = $(`<div id="loadingMask" class="loadingMask"><div class="loadingBox"><div id="loading" class="loading"><span class="_loading"></span><span>${param.info || 'Loading'}</span></div></div></div>`);

        param.style && loadingDom.css(param.style); // eslint-disable-line

        $('body').append(loadingDom);
    }

    function hideLoading(param) {
        if (param && param.dom) {
            param.dom.find('.loadingMask').hide();
        } else {
            $('#loadingMask').hide();
        }
    }

    // 获取URL传参
    // ?a=1&b=2
    function queryString(name) {
        const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
        const param = window.location.href.split('?')[1];
        if (!param) {
            return null;
        }
        const r = param.match(reg);
        return !r ? null : unescape(r[2]);
    }

    // 生成guid
    function guid() {
        function S4() {
            return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        }
        return (`${S4() + S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`);
    }

    /* function tzmoment(timestamp){
     var _zone = window.timezone || 'Asia/Shanghai';
     var tzMoment = moment(timestamp).tz(_zone);
     //夏令时
     if(tzMoment.isDST()){
     tzMoment.add(1, 'h');
     }
     return tzMoment;
     } */

    function tzmoment(timestamp) {
        if (!window.timezone) {
            return new Date(timestamp).getTime();
        }
        const tzOffset = window.timezone.offset;
        const lr = tzOffset > 0 ? '+' : '-';
        const h = tzOffset / (60 * 60 * 1000);
        const tzOffsetConvert = `${lr + (h > 10 ? h : `0${h}`)}:00`;
        const tzMoment = moment(+timestamp).zone(tzOffsetConvert);
        // 夏令时
        if (tzMoment.isDST()) {
            tzMoment.add(1, 'h');
        }
        return tzMoment;
    }

    function getTimestampFromTZC(timestamp) {
        return tzmoment(timestamp).valueOf();
    }

    function timeZoneConversion(timestamp, format) {
        const _format = format || 'MM/DD/YYYY HH:mm:ss';
        return tzmoment(timestamp).format(_format);
    }

    function decodeHtml(str) {
        const arrEntities = {
            lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"', '#x28': '(', '#x29': ')', '#39': "'"
        };
        if (str && _.isString(str)) {
            return str.replace(/&(lt|gt|nbsp|amp|quot|#x28|#x29|#39);/ig, (all, t) => arrEntities[t]);
        }
        return str;
    }
    /**
     * 对字符串进行转义
     *           HTML实体编码 转换
     *             & 为 &amp;
     *             转换 < 为 &lt;
     *             转换 > 为 &gt;
     *             转换"为&quot;
     *             转换 '为16进制 &#x27; 或者10进制&#39;
     *             转换 /为16进制&#x2F;或者10进制&#47;
     *             转换 ( 为10进制&#40; 或者16进制&#x28;
     *             转换 ) 为10进制&#41; 或者 16进制&#x29;
     * @param res
     * @param {array} exs [{old:"要替换的字符串",new:"替换的目标字符串"}]
     * @returns {*}
     */
    function encode(res, exs) {
        res = res // eslint-disable-line
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot')
            .replace(/'/g, '&#39;')
            .replace(/\//g, '&#47;')
            .replace(/\(/g, '&#40;')
            .replace(/\)/g, '&#41;');

        if (exs && exs.length) {
            exs.forEach((item) => {
                res = res.replace(item.old, item.new); // eslint-disable-line
            });
        }

        return res;
    }
    /**
     * 设置颜色透明
     */
    function modifyAlpha(color, alpha) {
        return _echarts4 ? _echarts4.color.modifyAlpha(color, alpha || 0.6) : color;
    }

    // 颜色变深或变浅
    function Color() {
        let transparent = 1; const
            reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
        /* rgb转十六进制 */
        this.colorHex = function (color) {
            const that = color;
            if (/^(rgba|RGBA|rgb|RGB)/.test(that)) {
                const aColor = that.replace(/(?:\(|\)|rgba|RGBA|rgb|RGB)*/g, '').split(',');
                let strHex = '';
                const _len = (color.indexOf('rgba') > -1) ? aColor.length - 1 : aColor.length;
                for (let i = 0; i < _len; i++) {
                    let hex = Number(aColor[i]).toString(16);
                    if (hex.length === 1) {
                        hex += hex;
                    }
                    strHex += hex;
                }
                transparent = (color.indexOf('rgba') > -1) ? aColor[aColor.length - 1] : 1;
                if (strHex.length !== 6) {
                    strHex = that;
                }
                return strHex;
            } if (reg.test(that)) {
                const aNum = that.replace(/#/, '').split('');
                if (aNum.length === 6) {
                    return that;
                } if (aNum.length === 3) {
                    let numHex = '#';
                    for (let i = 0; i < aNum.length; i += 1) {
                        numHex += (aNum + aNum);
                    }
                    return numHex;
                }
            } else {
                return that;
            }

            return '';
        };
        /* 16进制转为RGB格式 */
        this.colorRgb = function (color) {
            let sColor = color.toLowerCase();
            if (sColor && reg.test(sColor)) {
                if (sColor.length === 4) {
                    let sColorNew = '#';
                    for (let i = 1; i < 4; i += 1) {
                        sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
                    }
                    sColor = sColorNew;
                }
                // 处理六位的颜色值
                const sColorChange = [];
                for (let i = 1; i < 7; i += 2) {
                    sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)); // eslint-disable-line
                }
                sColorChange.push(transparent);
                return `rgba(${sColorChange.join(',')})`;
            }
            return sColor;
        };
        function stringify(arrColor, type) {
            if (!arrColor || !arrColor.length) {
                return;
            }
            let colorStr = `${arrColor[0]},${arrColor[1]},${arrColor[2]}`;
            if (type === 'rgba') {
                colorStr += `,${arrColor[3]}`;
            }
            return `${type}(${colorStr})`; // eslint-disable-line
        }
        function clampCssByte(i) {
            i = Math.round(i); // eslint-disable-line
            return i < 0 ? 0 : i > 255 ? 255 : i; // eslint-disable-line
        }
        function parseCssInt(str) {
            if (str.length && str.charAt(str.length - 1) === '%') {
                return clampCssByte(parseFloat(str) / 100 * 255); // eslint-disable-line
            }
            return clampCssByte(parseInt(str, 10));
        }
        function setRgba(out, r, g, b, a) {
            out[0] = r; out[1] = g; out[2] = b; out[3] = a; // eslint-disable-line
            return out;
        }
        // 将颜色值str转化成rgb或rgba数组
        function HexToRgb(str, rgbaArr) {
            // replace替换查找的到的字符串
            str = str.replace(/ /g, '').toLowerCase(); // eslint-disable-line
            rgbaArr = rgbaArr || []; // eslint-disable-line
            // 十六进制颜色值
            if (str.charAt(0) === '#') {
                const iv = parseInt(str.substr(1), 16);
                const hexColor = str.length === 4 ? 0xfff : 0xffffff;
                if (iv >= 0 && iv <= hexColor) {
                    setRgba(rgbaArr,
                        (iv & 0xff0000) >> 16,
                        (iv & 0xff00) >> 8,
                        iv & 0xff,
                        1);
                    return rgbaArr;
                }
            }
            // rgb rgba 颜色值
            const op = str.indexOf('(');
            const ep = str.indexOf(')');
            let alpha;
            if (op !== -1 && ep + 1 === str.length) {
                const fname = str.substr(0, op);
                const params = str.substr(op + 1, ep - (op + 1)).split(',');
                alpha = params[3] === undefined ? 1 : parseFloat(params[3]);
                const len = fname === 'rgba' ? 4 : 3;
                if (params.length === len) {
                    setRgba(rgbaArr,
                        parseCssInt(params[0]),
                        parseCssInt(params[1]),
                        parseCssInt(params[2]),
                        alpha);
                    return rgbaArr;
                }
            }
            return setRgba(rgbaArr, 0, 0, 0, alpha);
        }
        // 将rgb颜色值为a,b,c转化成hex颜色值
        function RgbToHex(a, b, c) {
            const hexs = [a.toString(16), b.toString(16), c.toString(16)];
            for (let i = 0; i < 3; i++) if (hexs[i].length === 1) hexs[i] = `0${hexs[i]}`;
            return `#${hexs.join('')}`;
        }
        // 得到hex颜色值为color的加深颜色值,level为加深的程度,限0-1之间
        this.getDarkColor = function (color, level) {
            const rgbc = HexToRgb(color);
            for (let i = 0; i < 3; i++) rgbc[i] = Math.floor(rgbc[i] * (1 - level));
            return RgbToHex(rgbc[0], rgbc[1], rgbc[2]);
        };
        // 得到hex颜色值为color的减淡颜色值,level为减淡的程度,限0-1之间
        this.getLightColor = function (color, level) {
            const rgbc = HexToRgb(color);
            for (let i = 0; i < 3; i++) {
                rgbc[i] = rgbc[i] * (1 - level) | 0;
            }
            return stringify(rgbc, rgbc.length === 4 ? 'rgba' : 'rgb');
        };
    }
    // 获取改变后的颜色值
    function getChangeBgColor(bgcolor, type, opacity) {
        let _bgColor = bgcolor;
        const _color = new Color();
        let hoverColor;

        if (type) {
            const transparent = 1;
            if (/^(rgba|RGBA|rgb|RGB)/.test(_bgColor)) {
                _bgColor = _color.colorHex(_bgColor);
            }
            hoverColor = _color.getDarkColor(_bgColor.replace(/#/, ''), 0.2);
            if (transparent < 1) {
                hoverColor = _color.colorRgb(hoverColor);
            }
            if (opacity !== undefined) {
                hoverColor = d3v4.color(hoverColor);
                hoverColor.opacity = 0.7;
                hoverColor = hoverColor.toString();
            }
        } else {
            const opa = opacity !== undefined ? opacity : -0.2;// 高亮透明度系数
            hoverColor = _color.getLightColor(_bgColor, opa);
        }
        return hoverColor;
    }
    // 开启下钻后,首次需要查询的维度和度量id
    function getDrillField(columns) {
        let _childId; const
            _fields = [];
        $.each(columns, (i, v) => {
            if (_childId !== v.id || !v.children) {
                _fields.push(v.id);
            }
            if (v.children && v.children.length > 0) {
                _childId = v.children[0]; // eslint-disable-line
            }
        });
        return _fields;
    }
    function isIn(target) {
        /* eslint-disable */
        for (let i = 1, len = arguments.length; i < len; i++) {
            if (typeof (arguments[i]) === 'object' && arguments[i].length && arguments[i].length >= 1) {
                for (let i2 = 0, len2 = arguments[i].length; i2 < len2; i2++) {
                    if (arguments[i][i2] == target) {
                        return true;
                    }
                }
            } else if (arguments[i] == target) {
                return true;
            }
        }
        /* eslint-enable */

        return false;
    }
    function getShowMenuItem(id, menuId) { // nts
        const data = {};
        data.id = id;
        data.menuId = menuId;
        const widgetThis = $(`#${id}`).widget();
        let newData = '';
        $.each(widgetThis.menuList, (k, v) => {
            if (v.id === menuId) {
                newData = v.name;
            }
        });
        return newData;
    }
    // 解决firefox低版本的title显示不完的BUG
    String.prototype.cutForTitle = function () { // eslint-disable-line
        const val = this;
        if (val.length <= 20) return val.toString();
        const len = Math.ceil(val.length / 20);
        let i = 0;
        let count = 0;
        const array = [];
        for (; i < len; i++) {
            array.push(val.substring(count, count + 20));
            count += 20;
        }
        return array.join('&#10');
    };

    // 查询容器/组件 通用 lova
    function pluginUpdate(widget, query) {
        if (!widget) {
            return;
        }
        const { directiveName } = widget;
        if (directiveName === 'tinyEtable') {
            if (
                widget
                && widget.columnSortsIns
                && widget.columnSortsIns.s
                && widget.columnSortsIns.s.fields
            ) {
                query.fields = widget.columnSortsIns.s.fields; // eslint-disable-line
            }
        } else if (directiveName === 'tinyEchartpie' || directiveName === 'tinyEchartprovinceMap') {
            query.fields = widget.cacheUpdateParam.fields; // eslint-disable-line
        }

        widget.update(query);
    }
    // 删除查询数据id重复的参数
    function delRepeatParams(widget, currFilter, otherKey1, otherKey2, otherKey3) {
        const otherFilter1 = angular.copy(widget[otherKey1]);
        const otherFilter2 = angular.copy(widget[otherKey2]);
        const otherFilter3 = otherKey3 && angular.copy(widget[otherKey3]);
        $.each(currFilter, (k, v) => {
            if (otherFilter1 && otherFilter1.length) {
                $.each(otherFilter1, (k1, v1) => {
                    if (v.id === v1.id) {
                        widget[otherKey1].splice(k1, 1);
                    }
                });
            }
            if (otherFilter2 && otherFilter2.length) {
                $.each(otherFilter2, (k1, v1) => {
                    if (v.id === v1.id) {
                        widget[otherKey2].splice(k1, 1);
                    }
                });
            }
            if (otherFilter3 && otherFilter3.length) {
                $.each(otherFilter3, (k1, v1) => {
                    if (v.id === v1.id) {
                        widget[otherKey3].splice(k1, 1);
                    }
                });
            }
        });
    }
    // 火狐 IE浏览器兼容 lova;
    function newDate(str) {
        if (str) {
            if (typeof str === 'string') {
                return new Date(str.replace(/\.|\-/ig, '/')); // eslint-disable-line
            }
            return new Date(str);
        }
        return new Date();
    }

    function getPhyicUnitSize(prop) {
        return prop.indexOf('rem') != -1 ? prop : (prop.indexOf('px') != -1 ? prop : `${prop}px`); // eslint-disable-line
    }

    // 获取对象信息
    function getObjInfo(model, arr) {
        try {
            return new Function('model', `return model.${arr}`)(model); // eslint-disable-line
        } catch (e) {
            return null;
        }
    }
    // 获取对象信息
    function getInfo(obj, arr) {
        try {
            arr = arr.split('.'); // eslint-disable-line
            _.each(arr, (a) => {
                if (!obj[a]) { obj[a] = {}; } // eslint-disable-line
                obj = obj[a]; // eslint-disable-line
            });
            return obj;
        } catch (e) {
            return undefined;
        }
    }

    /**
     * //获取组件绑定模型,分字段返回绑定情况(包含动态模型绑定的字段)
     * @param id
     * @returns {*}
     */
    function dynamicColumn(id) {
        let model; let
            modelFiedls;
        if (id) {
            model = $(`#${id}`).widget().model.getModelSetting();
        } else {
            return;
        }
        if (!model) { return; }
        /**
         * svg地图获取模型
         */
        if (model.multiModel && model.multiModel.length > 0) {
            modelFiedls = {};
            _.each(model.multiModel, (a) => {
                if (model[a] instanceof Array) {
                    modelFiedls[a] = [];
                    _.each(model[a], (a2, b2) => {
                        modelFiedls[a][b2] = undefined;
                        _.each(a2, (a3) => {
                            modelFiedls[a][b2] = (getmodelArr(a3)); // eslint-disable-line
                        });
                    });
                } else {
                    modelFiedls[a] = undefined;
                    _.each(model[a], (a2) => {
                        modelFiedls[a] = getmodelArr(a2); // eslint-disable-line
                    });
                }
            });
            return modelFiedls; // eslint-disable-line
        }
        if (model.cubeType !== undefined && model.cubeId !== undefined) {
            return getmodelArr(model); // eslint-disable-line
        }
        function getmodelArr(model) { // eslint-disable-line
            const arr = [];
            const dyecharValue = getObjInfo(model, 'dynamicColumn.echarValue.value');
            const echarValue = getObjInfo(model, 'echarValue.value');

            const echarValueKey = _.union((_.keys(dyecharValue)), (_.keys(echarValue)));
            if (echarValueKey) {
                _.each(echarValueKey, (a) => {
                    const dymic = getObjInfo(dyecharValue, a) || [];
                    const colmun = getObjInfo(echarValue, a) || [];
                    const d = [].concat(dymic, colmun);
                    if (d.length > 0) {
                        arr.push({
                            type: a,
                            value: $.extend(true, [], d)
                        });
                    }
                });
            }
            const index = getObjInfo(model, 'index') || [];
            const dymicIndex = getObjInfo(model, 'dynamicColumn.value.index') || [];
            const dimesion = getObjInfo(model, 'dimension') || [];
            const dymicDimesion = getObjInfo(model, 'dynamicColumn.value.dimension') || [];
            const allIndex = [].concat(index, dymicIndex);
            const allDimesion = [].concat(dimesion, dymicDimesion);
            if (allIndex.length > 0) {
                arr.push({
                    type: 'index',
                    value: $.extend(true, [], allIndex)
                });
            }
            if (allDimesion.length > 0) {
                arr.push({
                    type: 'dimension',
                    value: $.extend(true, [], allDimesion)
                });
            }
            return arr;
        }
    }

    /**
     * 获取绑定模型,返回当前绑定的字段对象(包含动态模型绑定的字段)
     * @param id
     */
    function getModeldynamicField(id) {
        let model;
        if (id) {
            model = $(`#${id}`).widget().model.getModelSetting();
        } else {
            return;
        }
        if (!model) { return; }
        const fieldsArr = window.tinyWidget.util.dynamicColumn(id);
        let fields = {};
        if (fieldsArr) {
            fields = {};
            if (model.multiModel && model.multiModel.length > 0) {
                _.each(model.multiModel, (a) => {
                    if (model[a] instanceof Array) {
                        fields[a] = [];
                        _.each(fieldsArr[a], (a2, b2) => {
                            fields[a][b2] = {};
                            getField(a2, fields[a][b2]); // eslint-disable-line
                        });
                    } else {
                        fields[a] = {};
                        getField(fieldsArr[a], fields[a]); // eslint-disable-line
                    }
                });
            } else {
                fields = {};
                getField(fieldsArr, fields); // eslint-disable-line
            }
        }

        function getField(info, pObj) {
            _.each(info, (a) => {
                _.each(a.value, (a2) => {
                    pObj[a2.id] = a2; // eslint-disable-line
                });
            });
        }

        return fields; // eslint-disable-line
    }
    if (!window.tinyWidget) {
        window.tinyWidget = {};
    }
    /**
     * 对已转义的自定义字符进行反转义
     * @param res
     * @returns {*}
     */
    function decodeDefChar(res) {
        res = res // eslint-disable-line
            .replace(/&#39;/g, "'")
            .replace(/&#47;/g, '\\')
            .replace(/&#40;/g, '(')
            .replace(/&#41;/g, ')');

        return res;
    }
    /** *
     * 获取csrf token信息
     * @returns {*}
     */
    function get_srf_token() { // eslint-disable-line
        const $csrfToken = $('#_csrf_token');
        const obj = {};
        if ($csrfToken.length) {
            obj.name = $csrfToken.attr('name');
            obj.val = $csrfToken.val();
            return obj;
        }
        return null;
    }

    /**
     * 通过打开新窗口下载功能的函数封装  给window.open,加入token参数
     * @param url
     * @returns {Window}
     */
    function openDownLoad(url) {
        if (!url) {
            return window.open();
        }
        const csrfToken = window.tinyWidget.util.get_srf_token();
        const params = {};
        params[csrfToken.name] = csrfToken.val;
        let link = '';
        if ((/\?/g).test(url)) {
            link = [url, $.param(params)].join('&');
        } else {
            link = [url, $.param(params)].join('?');
        }
        return window.open(link);
    }

    function getWidgetById(id) {
        return $(`#${id}`).widget();
    }

    /* 判断是否是变异 */
    function isChangeVariation(str) {
        const nextStr = str.split(this.variationStr);
        return nextStr[1] && nextStr[1].length || false; // eslint-disable-line
    }
    /* 还原id */
    function restoreVariation(id) {
        const _u = this.variationStr;
        return id.split(_u)[0];
    }
    /* 合成id */
    function generateVariation(id, key) {
        const _u = this.variationStr;
        return id.split(_u)[0] + _u + key;
    }

    /* 对比字符串,包含关系 */
    function equalByInclude(str1, str2) {
        if (str1.indexOf(str2) !== -1 || str2.indexOf(str1) !== -1) {
            return true;
        }
        return false;
    }

    function openWindow(option) {
        if (!window.tinyWidget.Window) {
            return;
        }
        let win;
        if (option.controllerName) {
            option['content-type'] = 'url'; // eslint-disable-line
            option.completeFn = function () { // eslint-disable-line
                // 动态关联controller
                // eslint-disable-next-line
                const ctrlDom = win.wBaseDiv.find('.overview').attr('ng-controller', option.controllerName);
            };
        }
        win = new window.tinyWidget.Window(option);
        win.show();
        return win; // eslint-disable-line
    }
    // 时间转换 'yyyy-MM-dd  hh:mm:ss'
    function dateFormat(date, format) {
        const o = {
            'M+': date.getMonth() + 1, // month
            'd+': date.getDate(), // day
            'h+': date.getHours(), // hour
            'm+': date.getMinutes(), // minute
            's+': date.getSeconds(), // second
            'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
            S: date.getMilliseconds() // millisecond
        };

        if (/(y+)/.test(format)) {
            // eslint-disable-next-line
            format = format.replace(RegExp.$1, (`${date.getFullYear()}`).substr(4 - RegExp.$1.length));
        }

        // eslint-disable-next-line
        for (const k in o) {
            if (new RegExp(`(${k})`).test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : (`00${o[k]}`).substr((`${o[k]}`).length)); // eslint-disable-line
            }
        }
        return format;
    }

    // 获取缩放比例
    // - 没有开启自适应,则不缩放,返回 1
    // - 开启自适应返回:实际画布宽度 / 用户设置画布宽度
    function getScale() {
        const pageCfg = ven.app.getCurrentPage();
        const page = pageCfg.page || {};

        // eslint-disable-next-line
        if (isNaN(page.width) || page.resolution === 'off') {
            return 1;
        }

        // eslint-disable-next-line
        return getCanvasWidth() / page.width;
    }

    // const mobileDetect = new MobileDetect(window.navigator.userAgent);
    // 不同模式下,画布宽度
    function getCanvasWidth() {
        // 发布模式下,全屏
        if (isReleaseMode()) {
            return document.body.clientWidth;
        }

        // 动静态预览
        const pageCfg = ven.app.getCurrentPage();
        if (!pageCfg || !pageCfg.page || !pageCfg.page.width) {
            return document.body.clientWidth;
        }

        // auto 的话不开启自适应
        if (pageCfg.page.width === 'auto') {
            return document.body.clientWidth;
        }

        // 移动设备
        // if (mobileDetect.tablet() || mobileDetect.mobile()) {
        //     return document.body.clientWidth;
        // }

        // PC
        const routeConfig = router.getCurrentPageStateCfg() || {};
        switch (routeConfig.catalogType) {
        case CATALOG_TYPE.PHONE:
        case CATALOG_TYPE.PAD:
            if (pageCfg.page.width === 'auto') {
                return document.body.clientWidth;
            }

            return pageCfg.page.width;
        case CATALOG_TYPE.PC:
        default:
            return document.body.clientWidth;
        }
    }

    // 获取当前设备下,rem 的基准字体大小
    function getRootFontSize() {
        return getCanvasWidth() / 320 * 10; // eslint-disable-line
    }

    // 获取用户在设计器中,设置的 rem 基准字体大小
    function getOriginRootFontSize() {
        const pageCfg = ven.app.getCurrentPage();

        let clientWidth;
        if (pageCfg && pageCfg.page && pageCfg.page.width) {
            clientWidth = pageCfg.page.width;
        } else {
            clientWidth = document.body.clientWidth;
        }

        if (typeof clientWidth === 'string') {
            clientWidth = parseInt(clientWidth, 10) || document.body.clientWidth;
        }

        return clientWidth / 320 * 10; // eslint-disable-line
    }

    function isEmptyString2(str) {
        return (str === undefined || (`${str}`).length === 0) || str === null;
    }

    function isEmptyNumber(num) {
        return ((num === undefined || (`${num}`).length === 0) || num === null || String(num) === 'NaN');
    }
    // 浏览器识别
    const getBrowserAgent = (function () {
        if (navigator.userAgent.indexOf('Chrome') > 0) {
            return 'Chrome'; // Chrome浏览器
        }
        if (navigator.userAgent.indexOf('MSIE') > 0) {
            return 'MSIE'; // ie浏览器
        }
        if (navigator.userAgent.indexOf('Firefox') > 0) {
            return 'Firefox'; // Firefox浏览器
        }

        return '';
    }());

    function getUuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8); // eslint-disable-line
            return v.toString(16);
        });
    }

    /**
     * <script>标签需要转义,防止XSS
     * @param {*} value
     */
    function filterScriptTags(value) {
        function stringEncode(str) {
            const div = document.createElement('div');
            if (div.innerText) {
                div.innerText = str;
            } else {
                div.textContent = str;
            }
            return div.innerHTML;
        }
        value = value.replace(/<script>/gi, stringEncode('<script>')); // eslint-disable-line
        value = value.replace(new RegExp('</script>', 'gi'), stringEncode('</script>')); // eslint-disable-line
        return value;
    }

    /**
     * query数据由数组转换为key
     * @param result
     */
    function queryArrayToObj(result) {
        if (!result) {
            return false;
        }
        const { data } = result;
        const { columns } = result;
        let resultData = [];
        if (data && data[0] && data[0] instanceof Array) {
            data.forEach((a) => {
                const obj = {};
                a.forEach((a2, b2) => {
                    if (columns[b2] && columns[b2].id) {
                        obj[columns[b2].id] = a2;
                    }
                });
                resultData.push(obj);
            });
        } else {
            resultData = result.data;
        }
        return resultData;
    }

    window.startTimeStamp = +new Date(); // 系统初始时间戳
    /**
     * 获取系统时间
     */
    function getServerSystemTime() {
        let cdate;
        if (window.SF_DATA.serverSystemTime !== undefined) {
            cdate = Number(window.SF_DATA.serverSystemTime) + (+new Date()) - window.startTimeStamp;
        } else {
            cdate = +new Date();
        }
        return {
            currentTime: cdate
        };
    }

    /**
     *  单实例工具方法,单例直接绑定在
     * @param instanceKey
     * @param Factory
     */
    function getSingleInstance(instanceKey, Factory) {
        if (Factory[instanceKey]) {
            return Factory[instanceKey];
        }
        Factory[instanceKey] = new Factory(); // eslint-disable-line
        return Factory[instanceKey];
    }

    /**
     * 获取菜单扁平结构
     * @returns {Array}
     */
    function getFlatMenuStruct() {
        let result = [];

        if (window.SF_DATA && window.SF_DATA.menuConfig) {
            result = getChildrenMenu(window.SF_DATA.menuConfig); // eslint-disable-line
        }
        function getChildrenMenu(menus) {
            let res = [];
            for (let step = 0; step < menus.length; step++) {
                if (menus[step].children) {
                    res = res.concat(getChildrenMenu(menus[step].children));
                } else {
                    res.push(menus[step]);
                }
            }
            return res;
        }

        return result;
    }

    /**
     * 颜色短代码转换为长代码
     * @date 2020-3-06
     * @param {any} shortHex 颜色短码
     * @returns {any} 颜色长码
     */
    function extendHex(shortHex) {
        return `#${
            shortHex
                .slice(shortHex.startsWith('#') ? 1 : 0)
                .split('')
                .map((x) => x + x)
                .join('')}`;
    }

    /**
     * 四方通过秘钥加密
     * @param word
     * @returns {string|*}
     */
    function encrypt(word) {
        // return word;
        if (word === '') { return word; }
        const key = CryptoJS.enc.Latin1.parse('sefonsoft1qa2ws3ed!@#$%^');
        const iv = CryptoJS.enc.Latin1.parse('sefonsoft@#$%^18');
        const encrypted = CryptoJS.AES.encrypt(word, key, {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        return encrypted.toString();
    }

    window.tinyWidget.util = {

        variationStr: '-_-',
        getFlatMenuStruct,
        getSingleInstance,
        getUuid,
        openWindow,
        dateFormat,
        isEmptyNumber,
        getScale,
        isEmptyString2,
        getBrowserAgent,
        isChangeVariation,
        restoreVariation,
        generateVariation,
        equalByInclude,

        isTrue,
        isFalse,
        decodeDefChar,
        get_srf_token,
        openDownLoad,
        getWidgetById,
        getBoolean,
        isEmptyString,
        setPlaceholder,
        browser: browserDetect,

        showLoading,
        hideLoading,
        queryString,
        guid,
        timeZoneConversion,
        getTimestampFromTZC,
        decodeHtml,
        encode,
        modifyAlpha,
        getChangeBgColor,
        getDrillField,
        isIn,
        newDate,
        getMenuIds: getShowMenuItem, // nts
        pluginUpdate,
        delRepeatParams,
        getPhyicUnitSize,
        getObjInfo,
        getInfo,
        dynamicColumn,
        getModeldynamicField,
        filterScriptTags,
        queryArrayToObj,
        getSystemTime: getServerSystemTime,
        CATALOG_TYPE,
        getRootFontSize,
        getOriginRootFontSize,
        getCanvasWidth,
        extendHex,
        encrypt
    };

    const strag = [
        { target: 'val', handler: window.tinyWidget.util.decodeHtml },
        { target: 'text', handler: window.tinyWidget.util.decodeHtml }
    ];
    let i;
    // eslint-disable-next-line
    for (i in strag) {
        (function () { // eslint-disable-line
            const { target } = strag[i];
            const { handler } = strag[i];
            const jqOriginalFn = $.fn[target];
            $.fn[target] = function (str) { // eslint-disable-line
                str = handler(str); // eslint-disable-line
                if (str !== undefined) {
                    return jqOriginalFn.call(this, str);
                }
                return jqOriginalFn.call(this);
            };
        }());
    }

    return window.tinyWidget.util;
});