// 全局常量
var CONSTANTS = {
    // 标示当前环境
    env: 'mobile',
    iphone: /iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase()),
    android: /android/.test(navigator.userAgent.toLowerCase()),
    versions: function () {
        var u = navigator.userAgent,
            app = navigator.appVersion;
        return { //移动终端浏览器版本信息
            trident: u.indexOf('Trident') > -1, //IE内核
            presto: u.indexOf('Presto') > -1, //opera内核
            webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
            gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
            android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
            iPhone: u.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器
            iPad: u.indexOf('iPad') > -1, //是否iPad
            webApp: u.indexOf('Safari') == -1 //是否web应该程序，没有头部与底部
        };
    }()
};
// 手机版通用工具函数
var mUtils = {
    _randomNumber: 0,
    /**
     * 本地存储
     * @param keyPrefix
     * @param type
     * @returns {_storageFactory}
     */
    _storageMapping: {},
    _popUpMapping: {},
    // 弹层cache
    _popUpCache: [],
    // 弹层基础zIndex
    _popZIndex: 10000,
    getStorageIntance: function (keyPrefix, type) {
        function _storageFactory(keyPrefix, type) {
            this.keyPrefix = keyPrefix || '';
            this.localStorageFlag = type == 'cookie' ? false : true;
        }

        _storageFactory.prototype = {
            constructor: _storageFactory,
            isSupportLocalStorage: function () {
                if (!window.localStorage) {
                    throw '错误: 当前浏览器不支持本地存储！';
                    return null;
                }
            },
            /**
             * 获取数据
             * @param  {[type]} key          [description]
             * @param  {[type]} defaultValue [无数据时 默认值]
             * @return {[type]}              [description]
             */
            getItem: function (key, defaultValue) {
                this.localStorageFlag && this.isSupportLocalStorage();
                var value;
                if (this.localStorageFlag) {
                    value = window.localStorage.getItem(this.keyPrefix + key);
                } else {
                    value = mUtils.cookie(key);
                }
                return value == null ? defaultValue : value;
            },
            /**
             * 设置值
             * @param  {[type]} key          [description]
             * @param  {[type]} value        [description]
             * @param  {[type]} cookieParams [用于cookie操作时 附加参数]
             * @return {[type]}              [description]
             */
            setItem: function (key, value, cookieParams) {
                this.localStorageFlag && this.isSupportLocalStorage();
                if (this.localStorageFlag) {
                    try {
                        window.localStorage.setItem(this.keyPrefix + key, value);
                    } catch (e) {
                        // 超出限额
                        if (e.name == 'QuotaExceededError') {
                            layer.error('存储超额，是否清除当前所有存储以释放空间？', {
                                btn: [{
                                    name: '不清除'
                                }, {
                                    name: '清除',
                                    callback: function () {
                                        window.localStorage.clear();
                                    }
                                }]
                            });
                        } else {
                            throw e;
                        }
                    }
                } else {
                    mUtils.cookie(this.keyPrefix + key, value, cookieParams);
                }
            },
            /**
             * 移除指定项
             * @param key
             * @returns {boolean}
             */
            removeItem: function (key) {
                this.localStorageFlag && this.isSupportLocalStorage();
                if (this.localStorageFlag) {
                    try {
                        window.localStorage.removeItem(this.keyPrefix + key);
                    } catch (e) {
                        return false;
                    }
                } else {
                    //mUtils.cookie(this.keyPrefix + key, "", cookieParams);
                }
            }
        };
        return this._storageMapping[keyPrefix] || (new _storageFactory(keyPrefix, type));
    },
    cookie: function (name, value, options) {
        if (typeof value != 'undefined') {
            options = options || {};
            if (value === null) {
                value = '';
                options = $.extend({},
                    options);
                options.expires = -1;
            }
            var expires = '';
            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                var date;
                if (typeof options.expires == 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString();
            }
            var path = options.path ? '; path=' + (options.path) : '';
            var domain = options.domain ? '; domain=' + (options.domain) : '';
            var secure = options.secure ? '; secure' : '';
            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
        } else {
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
    },
    /**
     * 获取表单内容数据
     * @param formSelector form表单选择器 支持jquery选择器\form对象 等
     * @param opts trim 默认trim
     * @returns {{}}
     */
    getFormData: function (formSelector, opts) {
        var $form;
        if (typeof(formSelector) == 'string') {
            $form = $('#' + formSelector);
        } else {
            $form = $(formSelector);
        }
        opts = opts || {};
        var data = $form.serializeArray();
        var result = {};
        for (var i = 0, len = data.length; i < len; i++) {
            var item = data[i];
            var name = item.name;
            var value = opts.trim === false ? item.value : $.trim(item.value);
            if (result[name] !== undefined) {
                if (result[name] instanceof Array) {
                    result[name].push(value);
                } else {
                    result[name] = [result[name]];
                    result[name].push(value);
                }
            } else {
                result[name] = value;
            }
        }
        return result;
    },
    /**
     * 获取url参数
     * @param key 字段名
     * @param urlStr 默认为window.location.search
     * @returns {{}}
     */
    getUrlParams: function (key, urlStr) {
        urlStr = urlStr || window.location.search.replace(/^\?/, "");
        var regExp = /(&|^)([^=]+)=([^&]*)(&|$)/
        var matched = urlStr.match(regExp);
        var obj = {};
        while (matched) {
            obj[matched[2]] = matched[3];
            urlStr = urlStr.replace(matched[0], "");
            matched = urlStr.match(regExp);
        }
        return key ? obj[key] : obj;
    },
    urlencode: function (text) {
        text = text || "";
        text = escape(text.toString()).replace(/\+/g, "%2B");
        var matches = text.match(/(%([0-9A-F]{2}))/gi);
        if (matches) {
            for (var matchid = 0; matchid < matches.length; matchid++) {
                var code = matches[matchid].substring(1, 3);
                if (parseInt(code, 16) >= 128) {
                    text = text.replace(matches[matchid], '%u00' + code)
                }
            }
        }
        text = text.replace('%25', '%u0025');
        return text;
    },
    printstr: function (cn_, en_) {
        var str = cn_;
        if (typeof(language) != "undefined") {
            if (language == "en") {
                str = en_;
            }
        }
        return str;
    },
    // 对Date的扩展，将 Date 转化为指定格式的String
    // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
    // 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
    // 例子：
    // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
    // (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
    formatDate: function (fmt, date) {
        date = date || new Date();
        fmt = fmt || "yyyy-MM-dd hh:mm:ss";
        var o = {
            "M+": date.getMonth() + 1, //月份
            "d+": date.getDate(), //日
            "h+": date.getHours(), //小时
            "m+": date.getMinutes(), //分
            "s+": date.getSeconds(), //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length))
        }
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
            }
        }
        return fmt;
    },
    /**
     * 临时简易事件通讯
     * @param name
     * @param callback
     * @param target
     */
    on: function (name, callback) {
        $(document).on('mUtils_' + name, callback);
    },
    off: function (name, callback) {
        $(document).off('mUtils_' + name, callback);
    },
    fire: function (name, params) {
        $(document).trigger('mUtils_' + name, params);
    },
    /**
     * 原生事件添加、删除操作
     * @param el
     * @param type
     * @param fn
     * @param capture
     */
    addEvent: function (el, type, fn, capture) {
        el.addEventListener(type, fn, !!capture);
    },

    removeEvent: function (el, type, fn, capture) {
        el.removeEventListener(type, fn, !!capture);
    },
    // px2rem
    px2rem: function (px) {
        px = (px || "0") + "";
        var value = px.match(/(\d+)/);
        if (value) {
            return (value[1] / 100) + 'rem';
        } else {
            return 0;
        }
    },
    /**
     * 设置token
     * @param opts
     */
    setToken: function (opts) {
        if (typeof(opts) == 'string') {
            opts = {
                url: opts
            }
        }
        opts = $.extend({
            url: '/services/domain/whoisinfo.asp?act=gettok',
            type: 'get',
            async: false,
            data: null,
            cache: false
        }, opts);
        $.cookie = $.cookie || mUtils.cookie;
        var isOk = true;
        $.ajax({
            async: opts.async,
            type: opts.type,
            url: opts.url,
            data: opts.data,
            cache: opts.cache,
            dataType: 'script',
            error: function (jqXHR, textStatus, errorThrown) {
                isOk = false;
                alert('获取令牌失败');
            },
            complete: function () {
                opts.callback && opts.callback(isOk);
            }
        });
        return isOk;
    },
    // 初始化页面tab切换
    initTab: function (tabDomId, opts) {
        opts = opts || {};
        var currentTab = $(tabDomId).find('li.active');
        var prevLi = currentTab[0];
        $(tabDomId).on('click', 'li', function () {
            if (opts.onClickTab && (opts.onClickTab($(this), currentTab) == false)) {
                return;
            }
            currentTab.removeClass('active');
            $("#" + currentTab.attr('data-target')).removeClass('active');
            currentTab = $(this);
            currentTab.addClass('active');
            $("#" + currentTab.attr('data-target')).addClass('active');
            if (prevLi !== this) {
                opts.onChange && opts.onChange(currentTab, $(prevLi));
            }
            prevLi = this;
        });
        opts.onChange && opts.onChange(currentTab, $(prevLi));
    },
    // 通用banner初始化
    initBanner: function (domId, opts) {
        TouchSlide($.extend({
            slideCell: domId,
            titCell: '.slide-pagination ul',
            mainCell: ".slide-wrapper ul",
            effect: "leftLoop",
            autoPage: true,
            autoPlay: false,
            interTime: 6000
        }, opts));
    },
    // 通用ajax请求
    ajax: function (opts) {
        var self = this;
        opts = $.extend({
            showMask: true,
            type: 'post',
            dataType: 'json',
            data: {}
        }, opts);
        var loadingId = null;
        if (opts.showMask) {
            loadingId = this.showLoading();
        }
        return $.ajax({
            url: opts.url,
            type: opts.type,
            data: opts.data,
            async: opts.async === false ? false : true,
            dataType: opts.dataType,
            success: function (data) {
                // alert(JSON.stringify(data))
                // 未指定dataType时 辅助转JSON
                if (opts.dataType === null) {
                    if (data.indexOf("{") >= 0) {
                        try {
                            var dataInfo = eval("(" + data + ")");
                            opts.success & opts.success.call(opts.context || null, dataInfo);
                        } catch (e) {
                            opts.success & opts.success.call(opts.context || null, data);
                        }
                    } else {
                        opts.success & opts.success.call(opts.context || null, data);
                    }
                } else {
                    opts.success & opts.success.call(opts.context || null, data);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (opts.error) {
                    opts.error.apply(opts.context || null, Array.prototype.slice.call(arguments));
                } else {
                    layer.error('网络错误，请刷新后重试！');
                }
            },
            complete: function () {
                opts.showMask && self.hideLoading(loadingId);
                opts.complete && opts.complete.apply(opts.context || null);
            }
        });
    },
    post: function (url, params, success, error, opts) {
        mUtils.ajax($.extend({
            url: url,
            data: params,
            type: 'post',
            success: success,
            error: error
        }, opts));
    },
    get: function (url, params, success, error, opts) {
        mUtils.ajax($.extend({
            url: url,
            data: params,
            type: 'get',
            success: success,
            error: error
        }, opts));
    },
    showLoading: function (opts) {
        return layer.loading(3, opts);
    },
    hideLoading: function (id) {
        layer.close(id);
    },
    // 获取当前上层 zIndex
    getTopIndex: function (gap) {
        gap = gap || 1;
        return this._popZIndex + gap;
    },
    /**
     * 显示/隐藏弹出层
     * @param target dom\id\jqObj
     * @param opts boolean（隐藏或显示） or object
     */
    togglePopup: function (target, opts) {
        if (typeof(opts) === 'boolean') {
            opts = {
                status: opts
            }
        }
        opts = $.extend({
            cache: true
        }, opts);
        // 未指定状态 默认切换即可
        target = $(target);
        // 最终状态
        var status = null;
        if (opts.status == null) {
            status = !target.hasClass('active');
        } else {
            status = !!opts.status;
        }
        var id = target.attr('id');
        var targetPop = this._popUpMapping[id];
        if (target.length == 0 || !targetPop) {
            throw '获取对应弹层失败，ID = ' + id;
            return false;
        }
        if (status) {
            targetPop.show();
        } else {
            if (opts.cache === false || (opts.cache !== true && targetPop.opts.cache === false)) {
                targetPop.destroy();
            } else {
                targetPop.hide();
            }
        }
    },
    /**
     * 基于默认弹层 构建
     * @param id
     * @param opts
     */
    createPopup: function (id, opts) {
        // 如果传了第一个参数 且不是string 说明只有一个参数
        if (id && (typeof(id) != "string")) {
            opts = id;
            id = null;
        }
        opts = opts || {};
        opts = $.extend({
            id: 'J_popUp_' + (this._randomNumber++)
        }, opts, {
            // 废除 appendCls
            appendCls: 'sub-page ' + (opts.appendCls || opts.popStyle || ""),
        });
        if (id) {
            opts.id = id.replace('#', '');
        }
        if (mUtils._popUpMapping[opts.id]) {
            var oldInstance = mUtils._popUpMapping[opts.id];
            if (oldInstance._iframeUrl && CONSTANTS.iphone && opts.iframeMode) {
                window.location.href = oldInstance._iframeUrl.replace('control_cls=sub_page', '__control_cls=sub_page');
                return false;
            }
            return oldInstance;
        }

        // 是否内容全屏
        if (opts.contentFullPage) {
            opts.appendCls += " fullpage ";
        }
        var popUpTpl = '<div class="popup-container ' + opts.appendCls + '" id="' + opts.id + '">\
                            <div class="popup-content">\
                                <div class="container ' + (opts.title ? 'popup-container-wrapper' : '') + '"></div>\
                            </div>\
                        </div>';
        var pop = $(popUpTpl).appendTo($('#globalWrapper'));
        // var pop = $(popUpTpl).appendTo($('body'));
        var instance = {
            // 缓存初始配置参数
            opts: opts,
            target: pop,
            // 默认状态
            _status: false,
            // 存储内容区
            container: pop.find('.container'),
            popContent: null,
            setContent: function (content, clear) {
                this._iframeUrl = null;
                // 用于支持dom对象、jq对象
                if ((!(content instanceof Object)) && content.match(/^url:/)) {
                    // frame情况
                    var url = content.split('url:')[1];
                    this.target.addClass('fullpage');
                    content = '<iframe frameborder="0" id="frame_' + opts.id + '" src="' + url + '" allowtransparency="true" style="width: 100%; min-height: 100%; border: 0px none;"></iframe>';
                    this._iframeUrl = url;
                }

                if (!this.popContent) {
                    this.popContent = $('<div class="popup-content-wrapper"></div>').appendTo(this.container);
                    // isUrl && this.popContent.addClass('popup-iframe-wrapper');
                }
                // 支持传递dom对象
                this.popContent[clear === true ? 'html' : 'append'](content);
                // 把底部栏位移出 :: 可能存在的问题，在弹层中只能存在一个footer-btn-container
                var footerBtnsContainer = this.popContent.find('.footer-btns-container');
                footerBtnsContainer.insertAfter(this.popContent);
                // 启用底部栏位
                if (footerBtnsContainer.length) {
                    this.popContent.addClass('footerbar-enable')
                }
                // 把标题栏移动到外层
                var back_container = this.popContent.find('.back_container');
                if (back_container.length) {
                    back_container.insertBefore(this.popContent);
                }
                // 获取iframe
                if (this._iframeUrl) {
                    this.popContentIframe = $('#frame_' + opts.id);
                }
                return this;
            },
            // 更新内容 清空原来的 然后填充
            updateContent: function (content) {
                this.setContent(content, true);
            },
            // 追加内容
            appendContent: function (content) {
                this.setContent(content, false);
            },
            _toggleStatus: function (options) {
                if (this._status == (!!options.status)) {
                    return;
                }
                if (options.status) {
                    mUtils._popUpCache.push(this);
                    // var size = mUtils.getInnerSize();
                    // this.target.css({
                    //     // height: $('body').height(),
                    //     // 始终使用最新的高度 防止地址栏缩进导致高度无法完全覆盖的问题
                    //     height: size.height,
                    //     // top: $('body').scrollTop()
                    //     // 如果body存在滚动条的情况下 且弹层2层及以上 则top值第二次则应使用上一次获取的scrollTop
                    //     top: mUtils._popUpCache.length >= 2 ? ModalHelper.getScrollTop() : $(document).scrollTop()
                    // });
                    this._adjustLayout();
                    // 调整弹层zIndex
                    this.target.css('zIndex', mUtils._popZIndex++);
                    this.target.toggleClass('active', options.status);
                    ModalHelper.afterOpen(mUtils._popUpCache.length >= 2);
                    this._adjustLayout();
                    // setTimeout(function () {
                    //     $("#globalWrapper").css('position','position');
                    //     $("#globalWrapper").css('position','relative');
                    // },0)
                    // 临时解决IOS 弹层截断问题
                    if (mUtils._popUpCache.length > 0) {
                        $("#globalWrapper").css('min-height', '3000px');
                    }
                } else {
                    mUtils._popUpCache.pop();
                    ModalHelper.beforeClose(mUtils._popUpCache.length >= 1);
                    this.target.toggleClass('active', options.status);
                    mUtils._popZIndex--;
                    // 临时解决IOS 弹层截断问题
                    if (mUtils._popUpCache.length == 0) {
                        $("#globalWrapper").css('min-height', '100%');
                    }
                }
                this._status = options.status;
            },
            // 调整弹层的定位、高度
            _adjustLayout: function (top) {
                var size = mUtils.getInnerSize();
                // 默认情况下 都使用该值
                if (top == null) {
                    // 如果body存在滚动条的情况下 且弹层2层及以上 则top值第二次则应使用上一次获取的scrollTop
                    // top = mUtils._popUpCache.length >= 2 ? ModalHelper.getScrollTop() : $(document).scrollTop();
                    top = ModalHelper.getScrollTop();
                }
                this.target.css({
                    // 始终使用最新的高度 防止地址栏缩进导致高度无法完全覆盖的问题
                    height: size.height,
                    top: top
                });
                // console.log(this.popContentIframe)
                // this.popContentIframe && this.popContentIframe.css({
                //     // 'height': size.height - 70,
                //     // 'overflow': 'auto'
                // });
            },
            show: function (options) {
                if (!this.target) {
                    throw 'Error: 当前层已销毁！';
                    return;
                }
                options = $.extend(opts, {
                    status: true
                }, options);
                this._toggleStatus(options);
                return this;
            },
            hide: function (options) {
                if (!this.target) {
                    throw 'Error: 当前层已销毁！';
                    return;
                }
                options = $.extend(opts, {
                    status: false
                }, options);
                this._toggleStatus(options);
                return this;
            },
            destroy: function () {
                this.hide();
                var self = this;
                setTimeout(function () {
                    self.target.find('iframe').attr('src', '');
                    self.target.find('iframe').remove();
                    self.container.off();
                    self.target.off().remove();
                    self.target = null;
                    self.container = null;
                    mUtils._popUpMapping[opts.id] = undefined;
                    opts = null;
                    self = null;
                }, 500);
            },
            resize: function (opts) {
                opts = opts || {};
                // 区分iphone\android
                if (CONSTANTS.iphone) {
                    var self = this;
                    if (opts.handlerKeyboard) {
                        // 当前键盘是否弹出
                        if (opts.keyboardPopup) {
                            var h = window.innerHeight;
                            self.keyboradInterval = setInterval(function () {
                                if (window.innerHeight != h) {
                                    updateHeight(window.innerHeight);
                                }
                            }, 100);
                            updateHeight(window.innerHeight);
                        } else {
                            clearInterval(self.keyboradInterval);
                            setTimeout(function () {
                                updateHeight(window.innerHeight);
                            }, 0);
                        }
                    }

                    // 浏览器高度发生变化情况
                    if (opts.windowResize) {
                        self.windowResizeHandler = setTimeout(function () {
                            clearTimeout(self.windowResizeHandler);
                            self._adjustLayout(ModalHelper.getScrollTop());
                        }, 100);
                    }

                    // 更新高度
                    function updateHeight(h) {
                        self.target.css({
                            height: h,
                            // top: 0
                        });
                    }
                }
            }
        };
        // 设置标题
        if (opts.title) {
            instance.container.html('<div class="back_container"><p class="title">' + opts.title + '</p><a class="icon-container" href="javascript:mUtils.popBack();"><i></i><span>返回</span></a></div>');
        }
        // 更新内容
        if (opts.content) {
            instance.setContent(opts.content);
        }
        // 按钮
        if (opts.btn) {
            instance.container.on('click', '.J-pop-btn', function () {
                var target = $(this);
                var fnKey = target.attr('data-fn');
                opts.btn[fnKey] && opts.btn[fnKey].call(instance, target);
            });
        }

        mUtils._popUpMapping[opts.id] = instance;
        // 针对为ifframe 且 iframeMode==true 则针对ios 直接跳页面
        if (instance._iframeUrl && CONSTANTS.iphone && opts.iframeMode) {
            window.location.href = instance._iframeUrl.replace('control_cls=sub_page', '__control_cls=sub_page');
            return false;
        }
        return instance;
    },
    /**
     * 直接显示弹层
     * @param title
     * @param content 支持字符串、dom对象、jquery对象
     * @param opts
     * @returns {*}
     */
    showPopup: function (title, content, opts) {
        opts = $.extend({title: title, content: content}, opts);
        var instance = this.createPopup(opts.id, opts);
        // 默认情况下创建完毕 就显示
        if (opts.autoShow !== false) {
            instance && instance.show();
        }
        return instance;
    },
    /**
     * 返回通用操作
     * 默认情况下 历史返回
     * @param opts
     */
    goBack: function (opts) {
        opts = opts || {};
        if (opts.url) {
            this.goUrl(opts.url, opts);
        } else {
            history.back();
        }
    },
    /*跳转到某个页面*/
    goUrl: function (url, opts) {
        window.location.href = url;
    },
    /**
     * 用于返回当前的弹层
     */
    popBack: function (opts) {
        var currentTopPop = this._popUpCache[this._popUpCache.length - 1];
        if (!currentTopPop) {
            return;
        }
        opts = $.extend({}, currentTopPop.opts, opts);
        // 默认情况下 均不cache
        if (opts.cache !== true) {
            currentTopPop.destroy();
        } else {
            currentTopPop.hide();
        }
    },
    viewHeight: window.innerHeight,
    // 获取内容区可使用高度\宽度
    getInnerSize: function (opts) {
        opts = opts || {};
        var sizeConf = {
            width: (window.innerWidth > 0) ? window.innerWidth : $(window).width(),
            height: (window.innerHeight > 0) ? window.innerHeight : $(window).height()
        };
        // 默认情况下 均不得低于原始高度
        if (opts.realSize !== true) {
            if (sizeConf.height < this.viewHeight) {
                sizeConf.height = this.viewHeight;
            }
        }
        return sizeConf;
    },
    _preventScroll: function (el, flag) {
        // abcd = el;
        // var el = document.querySelector(selector);
        var sy = 0;
        el.addEventListener('touchstart', function (e) {
            var point = e.touches ? e.touches[0] : e;
            sy = point.pageY;
        });

        el.addEventListener('touchmove', function (e) {
            // 无滚动条 直接屏蔽
            if (el.scrollHeight - el.clientHeight <= 0) {
                e.stopPropagation();
                e.preventDefault();
                return;
            }
            var point = e.touches ? e.touches[0] : e;
            // 是否上拉
            var isPullUp = (point.pageY - sy > 0);
            var str = isPullUp;
            str += ",top=" + parseInt(el.scrollTop);
            str += "," + (el.scrollTop >= el.scrollHeight - el.clientHeight);
            //滚动到顶部了
            if (isPullUp && el.scrollTop <= 0) {
                e.preventDefault();
                e.stopPropagation();
            }
            // 滚动到底部
            if (!isPullUp && el.scrollTop >= el.scrollHeight - el.clientHeight - 1) {
                e.preventDefault();
                e.stopPropagation();
            }
        });
    },
    /**
     * 注册滚动事件
     * @param target 目标容器ID\dom对象\jq对象
     * @param opts
     */
    initScroll: function (target, opts) {
        // 是否为全局滚动
        var isDoc = (target === null);

        // 无固定包裹容器版本
        target = $(target || document);
        var dom = isDoc ? document.documentElement : target[0];

        opts = $.extend({
            delay: 200 // 手机版自动在
        }, opts);

        // 延时handler
        var scrollHandler = null;
        var scrollEndHandler = null;
        var scrollTop = 0;

        // 当前是否为移动端 阻止局部区域滚动 导致整体滚动
        if (CONSTANTS.isMobile && !isDoc) {
            var sy = 0;
            dom.addEventListener('touchstart', function (e) {
                sy = e.touches[0].pageY;
                opts.onTouchStart && opts.onTouchStart(e.touches[0].pageX, e.touches[0].pageY);
            });
            dom.addEventListener('touchmove', function (e) {
                var _x = e.touches[0].pageX;
                var _y = e.touches[0].pageY;
                var down = (_y - sy > 0);
                //top 滚动到顶部 时 不再滚动  防止看到浏览器多余的内容
                if (down && scrollTop <= 0) {
                    e.preventDefault();
                }
                //bottom 滚动底部时 不再滚动  防止看到浏览器多余的内容
                if (isDoc) {
                    var scrollTop = $(document).scrollTop();
                    // 文档总长度
                    var scrollHeight = $(document).height();
                    // 页面可见高度
                    var offsetHeight = $(window).height();
                    if (!down && scrollTop > 0 && scrollTop >= scrollHeight - offsetHeight) {
                        e.preventDefault();
                    }
                } else {
                    // 普通元素 滚动距离直接元素获取
                    var scrollTop = dom.scrollTop;
                    if (!down && scrollTop > 0 && scrollTop >= dom.scrollHeight - dom.clientHeight) {
                        e.preventDefault();
                    }
                }
                // 移动中回调
                opts.onTouchMove && opts.onTouchMove(_x, _y);
            });
            dom.addEventListener('touchend', function (e) {
                // 滚动结束回调
                opts.onTouchEnd && opts.onTouchEnd(e.touches[0].pageX, e.touches[0].pageY);
            });
        }
        target.scroll(function (event) {
            clearTimeout(scrollHandler);
            clearTimeout(scrollEndHandler);
            scrollHandler = setTimeout(function () {
                clearTimeout(scrollEndHandler);
                // 当前滚动条滚动的距离
                var scrollTop = target.scrollTop();
                var isBottom = false;
                // document情况
                if (isDoc) {
                    // 文档总长度
                    var scrollHeight = $(document).height();
                    // 页面可见高度
                    var offsetHeight = $(window).height();
                    // console.log('scrollTop = ' + scrollTop);
                    // console.log('scrollHeight = ' + scrollHeight);
                    // console.log('offsetHeight = ' + offsetHeight);
                    if (scrollTop + offsetHeight >= scrollHeight) {
                        isBottom = true;
                    }
                } else {
                    // 滚动距离总长
                    var scrollHeight = dom.scrollHeight;
                    // 容器可见高度
                    var targetHeight = target.height();
                    // console.log('scrollTop = ' + scrollTop);
                    // console.log('scrollHeight = ' + scrollHeight);
                    // console.log('targetHeight = ' + targetHeight);
                    if (scrollTop + targetHeight >= scrollHeight) {
                        isBottom = true;
                    }
                }
                // 触发滚动中回调
                opts.onScroll && opts.onScroll(scrollTop, {
                    isBottom: isBottom
                });
                // 模拟触发滚动结束
                scrollEndHandler = setTimeout(function () {
                    // 屏蔽掉由弹层导致的滚动到底的问题
                    if ($('body').hasClass('popup-open') && isDoc) {
                        isBottom = false;
                    }
                    opts.onScrollEnd && opts.onScrollEnd(target.scrollTop(), {
                        isBottom: isBottom
                    });
                }, opts.delay);
            }, opts.delay);
            // event.preventDefault();
            // event.stopPropagation();
            // return false;
        });
    },
    //  首页菜单显示 用于显示闪现出菜单
    toggleMenu: function () {
        $("#J_selHeaderBox").css('height', this.getInnerSize().height);
        if ($("#J_selHeaderBox").hasClass('active')) {
            ModalHelper.beforeClose();
            $("#J_selHeaderBox").removeClass('active');
        } else {
            $("#J_selHeaderBox").addClass('active');
            ModalHelper.afterOpen();
        }

    },
    /**
     * 创建进度窗口
     * @param content
     * @param curr
     * @param total
     * @returns {*}
     */
    createProgress: function (content, curr, total) {
        var _progressTpl = '<div class="progress-container">\
                        <span class="progress-status {{resultStatus}}"></span>\
                        <div class="progress-content">{{#content || "当前处理中...."}}</div>\
                        {{if total >0 }}\
                        <div class="progress-bar"><span class="curr">{{curr}}</span>/<span class="total">{{total}}</span></div>\
                        {{/if}}\
                    </div>';
        var _progressTpl = template.compile(_progressTpl);
        var instance = layer.alert(_progressTpl({
            content: content,
            curr: curr,
            total: total
        }), "", {
            btn: false
        });
        return $.extend(instance, {
            updateProgress: function (content, curr, total) {
                this.content(_progressTpl({
                    content: content,
                    curr: curr,
                    total: total,
                    resultStatus: ""
                }))
            },
            endProgress: function (content, result, fn) {
                this.content(_progressTpl({
                    content: content,
                    result: result,
                    resultStatus: result === true ? ' process-success' : 'process-fail'
                }));
                if (typeof(fn) == 'function') {
                    this.button({
                        btn: [{
                            name: '确定',
                            // 如果不写 将调用 no
                            callback: function () {
                                return fn.call(instance);
                            }
                        }]
                    });
                }
            }
        });
    },

    // 页面ready后通用处理逻辑
    _onReady: function () {
        $(function () {
            ModalHelper.beforeClose();
            $('#layui-m-layer-gg').remove();
            // 菜单栏
            $("#J_globalMenuList").on('click', '.title', function () {
                var targetLi = $(this).parents('li');
                if ($(this).attr('href')) {
                    return;
                }
                targetLi.siblings().removeClass('active').removeClass(".active-end").children('dl').hide();
                targetLi.toggleClass('active');
                $(this).next()[targetLi.hasClass('active') ? 'slideDown' : 'slideUp'](350, function () {
                    targetLi.toggleClass('active-end');
                });
            });
            // 存在右侧栏情况
            if ($(".levitate-show").length) {
                mUtils.initScroll(null, {
                    onScroll: function (scrollTop) {
                        // 滚动中 取消实现侧栏 根据值显示active
                        if (scrollTop > 100) {
                            $('.levitate-container').removeClass('enable').addClass('active');
                        } else {
                            $('.levitate-container').removeClass('enable active');
                        }
                    },
                    onScrollEnd: function (scrollTop) {
                        // 滚动结束 是否显示active
                        if (scrollTop > 100) {
                            $('.levitate-container').addClass('active').removeClass('enable');
                        } else {
                            $('.levitate-container').removeClass('enable active');
                        }
                    }
                });
            }
            // 底部返回顶部
            $("#J_g_backTop").on('click', function () {
                $('html,body').animate({
                    scrollTop: 0
                }, 300);
            });
            // 兼容处理 弹层中输入框获取焦点问题,body内直接的输入框 则暂时不考虑
            $("body").on('focus', '.popup-container input,.popup-container textarea', function () {
                if (event.target.readOnly == true) {
                    return;
                }
                // body的高度设置 此处高度待定...
                $("body").css("height", mUtils.viewHeight);
                var pop = mUtils._popUpCache[mUtils._popUpCache.length - 1];
                var $this = this;
                pop && pop.resize({handlerKeyboard: true, keyboardPopup: true});
            }).on('blur', '.popup-container input,.popup-container textarea', function () {
                if (event.target.readOnly == true) {
                    return;
                }
                $("body").css("height", "100%");
                var pop = mUtils._popUpCache[mUtils._popUpCache.length - 1];
                pop && pop.resize({handlerKeyboard: true});
            });
            // 浏览器高度发生变化时 调整弹层高度
            var timeoutHandler = null;
            window.addEventListener('resize', function () {
                clearTimeout(timeoutHandler);
                timeoutHandler = setTimeout(function () {
                    var pop = mUtils._popUpCache[mUtils._popUpCache.length - 1];
                    pop && pop.resize({windowResize: true});
                }, 100);
            }, false);
        });
    },
    // 所有页面通用初始化
    init: function () {
        // 统一错误处理
        window.onerror = function (msg) {
            if (CONSTANTS.debugMode) {
                alert(msg);
            }
            throw msg;
        }
        template.helper('_debug', function () {
            console.log('-------debug-----');
            $.each(Array.prototype.slice.call(arguments), function (index, value) {
                console.log(value);
            });
        });
        this._onReady();
        var globalFns = ['urlencode', 'printstr'];
        for (var i = 0, len = globalFns.length; i < len; i++) {
            window[globalFns[i]] = this[globalFns[i]];
        }
        window.isnumeric = $.isNumeric;
    }
};
mUtils.init();

// cookie 清理
(function () {
    try{
        var cookies = document.cookie.match(/\b(ASPSESSIONID[A-Z]+)(?==)/g);
        if(cookies&&cookies.length>20){
            for(var i=0,len=cookies.length;i<len;i++){
                mUtils.cookie(cookies[i],"",{
                    expires:-1
                });
            }
        }
    }catch(e){}
})();

var menuUtils = {
    //首页点击更多按钮显示或隐藏悬浮框
    setlevitate: function () {
        $('.levitate-container').removeClass('active').addClass('enable');
    },
    showPhoneBox: function (selector) {
        $(".levitate-mask").toggleClass('active');
        $(selector).toggleClass('active');
    }
}
// menuUtils.init();
//键盘事件
var h1 = parseInt(window.innerHeight);
//键盘事件安卓苹果兼容js
function getonfocus() {
    var ua = navigator.userAgent.toLowerCase();
    if (/iphone|ipad|ipod/.test(ua)) {
        return false
    } else if (/android/.test(ua)) {
        var h2 = h1 - parseInt(window.innerHeight);
        var st = parseInt(document.body.scrollTop);
        document.body.scrollTop == st + h2;
        h1 = parseInt(window.innerHeight);
        return false;
    }
}
function getonblue() {
    var ua = navigator.userAgent.toLowerCase();
    if (/iphone|ipad|ipod/.test(ua)) {
        return false
    } else if (/android/.test(ua)) {
        var h2 = parseInt(window.innerHeight) - h1;
        var st = parseInt(document.body.scrollTop);
        document.body.scrollTop == st - h2;
        h1 = parseInt(window.innerHeight);
        return false
    }
}
window.getonblur = getonblue;
// 部分jquery扩展代码
$.escape_b64 = function (Keyword) {
    return escape(Keyword).replace(/\+/ig, "%2B").replace(/\//ig, "%2F");
}
$.isjson = function (obj) {
    return typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
}