(function ($) {

    $.fn.extend({
        serialize: function () {
            return jQuery.param(this.serializeArray());
        },
        serializeArray: function () {
            var rbracket = /\[\]$/,
                rCRLF = /\r?\n/g,
                rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
                rsubmittable = /^(?:input|select|textarea|keygen)/i,
                rcheckableType = (/^(?:checkbox|radio)$/i);
            return this.map(function () {
                // Can add propHook for "elements" to filter or add form elements
                var elements = jQuery.prop(this, "elements");
                return elements ? jQuery.makeArray(elements) : this;
            }).filter(function () {
                var type = this.type;
                // Use .is( ":disabled" ) so that fieldset[disabled] works
                //&& !jQuery(this).is(":disabled")
                return this.name && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&
                    (this.checked || !rcheckableType.test(type) || $(this).is(':checkbox[unvalue]'));
            }).map(function (i, elem) {
                var val = jQuery(this).val();
                if (val == null) return null;
                if ($(this).is(':checkbox[unvalue]') && !this.checked) {
                    val = $(this).attr('unvalue');
                }
                if (Array.isArray(val)) {
                    return jQuery.map(val, function (val) {
                        return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
                    });
                }
                return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
            }).get();
        },
        ajaxConf: function (data) {
            var $this = $(this);
            return {
                url: $this.attr('href') || $this.attr('url') || $this.attr('action') || $this.data('href') || $this.data('url') || $this.data('action'),
                method: ($this.attr('method') || $this.data('method') || 'get').toLowerCase(),
                data: data ? data : ($this.is('form') ? $this.serialize() : ($this.attr('args') || $this.data('args') || {})),
                beforeSend: $this.data('beforeSend') || function () {
                },
                shade: $this.data('shade') !== false,
                dataType: $this.data('type') || $this.data('dataType') || 'json',
            };
        },
        ajax: function (callback) {
            var ajaxConf = $(this).ajaxConf(), vthis = this;
            if (!ajaxConf.url || ajaxConf.beforeSend.call(this) === false) return false;
            delete ajaxConf.beforeSend;
            ajaxConf.shade && $.loading.show();
            $.ajax($.extend(ajaxConf, {
                success: function (rs) {
                    ajaxConf.shade && $.loading.hide();
                    if (callback && callback.call(vthis, rs) === false) return;
                    $.callbackSuccess.call(vthis, rs);
                }
            }));
            return true;
        },
    });

    $.extend({
        loading: (function () {
            var loadlayer = null;
            return {
                show: function (options) {
                    loadlayer = layer.open($.extend({
                        type: 3, shadeClose: false
                    }, $.isPlainObject(options) ? options : {}));
                    return loadlayer;
                },
                hide: function () {
                    loadlayer >= 0 && layer.close(loadlayer);
                }
            };
        })(),
        showMsg: function (code, msg) {
            layer.msg(msg, { icon: code ? 1 : 2 });
        },
        msg: function (msg, time, end) {
            var options = $.extend({ time: 3000 }, $.isPlainObject(msg) ? msg : {}, $.isPlainObject(time) ? time : {}), end;
            $.isFunction(end) && (options['end'] = end);
            $.isNumeric(time) && (options['time'] = time);
            $.isPlainObject(msg) && (msg = '');
            options['msg'] && (msg = options['msg']) && (delete options['msg']);
            layer.msg(msg, options);
        },
        validatorFunc: function (control) {
            var validatorTips = function (type, msg) {
                if (type) {
                    $(this).removeClass('layui-form-danger');
                    layer.close($(this).data('layer.index'));
                } else {
                    $(this).addClass('layui-form-danger').focus();
                    $(this).data('layer.index', layer.msg(msg, { icon: 5 }));
                }
            };
            return validate(control, function () {
                validatorTips.call(this, true);
            }, function (msg) {
                validatorTips.call(this, false, msg);
            });
        },
        callbackSuccess: function (rs) {
            var callback = $(this).data('callback');
            if (callback && callback.call(this, rs) === false) return;
            var time = 1000;
            if (rs && rs.msg) {
                $.showMsg(rs.code, rs.msg);
                time = 2000;
            }
            if (rs) {
                var url = rs.url || ((rs.data && rs.data.jump) ? rs.data.jump : '');
                url && setTimeout(function () {
                    url === true ? window.location.reload(true) :
                        window.location.href = url;
                }, time);
            }
        },
    });


    (function ($) {
        var $ajax = $.ajax;
        $.ajax = function (url, options) {
            options = options || {};
            if (typeof url === "object") {
                options = url;
                url = undefined;
            }
            if (url && !options.url) options.url = url;
            var fn = {
                error: options.error || function (XMLHttpRequest, textStatus, errorThrown) { },
                success: options.success || function (data, textStatus, jqXHR) { },
                beforeSend: options.beforeSend || function (XHR) { },
                complete: options.complete || function (jqXHR, textStatus) { }
            };
            $ajax($.extend(options, {
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    //错误方法增强处理
                    fn.error(XMLHttpRequest, textStatus, errorThrown);
                },
                success: function (data, textStatus, jqXHR) {
                    if (data && (data == 'no_login' || data['code'] == 'no_login')) {
                        layer.closeAll();
                        var msg = ($.isPlainObject(data) && data['msg']) ? data['msg'] : '您尚未登录，请先登录！',
                            url = ($.isPlainObject(data) && data['url']) ? data['url'] : '';
                        $.trim(msg) && layer.msg(msg);
                        setTimeout(function () {
                            url ? window.location.href = url : window.location.reload();
                        }, 1000);
                        return;
                    }
                    if (data && !$.isPlainObject(data) && data.substr(0, 5) == 'error') {
                        layer.closeAll();
                        var arry = data.split('|'), msg = arry[1] || '操作错误！';
                        $.trim(msg) && layer.msg(msg);
                        arry[2] && setTimeout(function () {
                            try {
                                window.location.href = arry[2];
                            } catch (e) {
                            }
                        }, 1000);
                        return;
                    }
                    //成功回调方法增强处理
                    fn.success(data, textStatus, jqXHR);
                },
                beforeSend: function (XHR) {
                    fn.beforeSend(XHR);
                },
                complete: function (jqXHR, textStatus) {
                    fn.complete(jqXHR, textStatus);
                }
            }));
        };
    })(window.jQuery);

})(window.jQuery)