﻿//excavator（挖掘机）：是基于jquery、ui函数库封装的JS框架，它的主要功能：
//1，console：开发时调试日志
//2，AjaxRequest：ajax请求
//3，ExceptionHandle: 服务端返回异常信息误处理
//4，Authentication：网站前台鉴权反转控制
//5，OperaResultHandle：业务操作结果反转控制

var Excavator = {
    version : "1.0.0", // 版本号
    devMode : false,// 是否开发模式，生产环境需要作出修改
    webRoot : "/portal"// 应用上下文，当WebRoot为Root时，该值为空

};// end Excavator
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
var Console = {
    info : function(msg) {// 消息
		if (this.ablePrint()) console.info(msg);
    },
    debug : function(msg) {// 调试信息
    	if (this.ablePrint()) console.debug(msg);
    },
    error : function(msg) {// 错误信息
    	if (this.ablePrint()) console.error(msg);
    },
    // 能否打印
    ablePrint : function() {
    	return Excavator.devMode && window.console;
    }
};// end Console
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
//进度条对象
var ProgressBar = {
	//进度条属性
	options: {isLock: false, isCenter: true, drag: true, closeTimeOut: 5000},
	
	//打开进度条
	open: function(opt){
		loadFn(opt);
	},
	
	//关闭进度条
	close: function(){
		loadFn({isHide:true});
	}
}
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// 该对象封装了请求URL的前缀和后缀
var URLHandler = {
    DEFAULT_INIT_PAGE_AFTER_LOGIN : "/products",// 登录后默认跳转页面
    REQ_PREFIX : Excavator.webRoot, // 请求前缀
    REQ_SUFFIX : ".jsps", // 请求后缀

    // 包装Form的URL
    warpURL : function(fid) {
		var form = $("#" + fid);
		var url = this.REQ_PREFIX + form.attr("action") + this.REQ_SUFFIX;
		return url;
    },

    // 直接包装传入的URL
    defaultWarpURL : function(url) {
	return (/^.*jsp$/).test(url) || (/^.*websitesearch$/).test(url)
		|| (/^.*action=Logout$/).test(url) ? url : (this.REQ_PREFIX
		+ url + this.REQ_SUFFIX);
    }
};// end URLHandler
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// 默认请求
var OrdinaryRequest = {
    // 默认的Form表单提交
    submitForm : function(fid) {
		var url = URLHandler.warpURL(fid);
		var form = $("#" + fid);
		form.attr("action", url);
		form.submit();
    }
};// OrdinaryRequest
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////

var AjaxRequest = {
    TIMEOUT : 30000, // 超时时间（毫秒）
    REQ_METHOD : "POST", // 请求方法

    // 参数过滤，将调用者传入的选项和默认值结合实现预定大于配置的原则
    optionFilter : function(options) {
		if (ObjectUtils.isUndefined(options) || options == null)
		    return AjaxOptions;
		return $.extend(true, AjaxOptions, options);
    },
    
    // AJAX提交一个form表单
    submitForm : function(fid, options) {
		var url = URLHandler.warpURL(fid);
		var data = $("#" + fid).serialize();
		this.request(url, data, fid, this.optionFilter(options));
    },
    
    // 默认的AJAX提交
    // options.data对象表示提交的数据，可以是一般对象，可以是json对象
    submitDefault : function(url, options) {
		url = URLHandler.defaultWarpURL(url);
		var fid = null;
		var data = (options == undefined || options == null
			|| options.data == undefined || options.data == null) ? ""
			: ObjectUtils.param(options.data);
		this.request(url, data, fid, this.optionFilter(options));
    },
    
    // AJAX 请求
    request : function(url, data, fid, options) {
		Console.info("========================Ajax Request========================");
		Console.debug("URL[" + url + "] Data[" + data + "]");
		ProgressBar.open(options.proBar)//打开进度条
		
		//延迟时间，单位毫秒。在开发模式下模拟网络延迟
		var delay = Excavator.devMode ? 2000 : 0;
		window.setTimeout(
				function(){
					$.ajax({
					    url : url,
					    cache : options.cache,
					    data : data,
					    async : options.async != null ? options.async : true,
					    type : this.REQ_METHOD,
					    timeout : this.TIMEOUT,
					    success : function(result, textStatus, jqXHR) { AjaxRequest.defaultSuccess(result, textStatus, jqXHR, fid, options); }
					});// end ajax
				},delay);
		
    },

    // 默认成功处理
    defaultSuccess : function(result, textStatus, jqXHR, fid, options) {
    	Console .info("========================Ajax Response========================");
    	ProgressBar.close();//关闭进度条
    	var status = jqXHR.status;
    	Console.debug("TextStatus[" + textStatus + "] Status[" + status + "] StatusText[" + jqXHR.statusText + "]");
		if (textStatus === "success" && status === 200) {// Ajax请求成功
		    if (ObjectUtils.isJson(result)) {
			var writeType = result.writeType;// 服务端返回JSON类型
			Console.debug("Response json type: " + writeType);
			// 服务端表单验证错误
			if (writeType == FieldValidate.FLAGE)
			    FieldValidate.invok(result.writeJson, fid, options.event);
			// 服务端业务操作结果
			else if (writeType == OperaResult.FLAGE)
			    OperaResult.invok(result.writeJson, options.event);
			// 服务端异常
			else if (ArrayUtils.containts(ExceptionHandler.FLAGE, writeType))
			    ExceptionHandler.invok(result.writeJson, writeType);
			// 未知类型
			else {
				//Console.error("Unkown json type: " + writeType);
			    //alert("未知JSON类型: " + writeType);
			    options.callBack(result);
			}
		    }// end is json
		    else {
		    	options.callBack(result);
		    }
		} 
		else AjaxRequest.defaultError(textStatus, jqXHR);
    },

    // 默认AJAX请求失败
    defaultError : function(textStatus, jqXHR) {
    	alert("Ajax Request Error: " + textStatus);
    },

    // 默认回调函数
    defaultCallBack : function(result) {
    	Console.info("Execute default call back");
    	winPop({ html : result, isMsg : 'success'});
    }
    
};// end AjaxRequest
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
var OperaResult = {
    FLAGE : "Result", // 服务端业务操作结果标识
    FAIL : "Fail", // 业务操作失败类型
    SUCCESS : "Success", // 业务操作成功类型
    AUTHEN : "Authen", // 鉴权失败类型
    INTERCEPTOR : "Interceptor",// 拦截器类型

    // 业务操作结果处理入口
    invok : function(result, event) {
		Console.info("==================Business Operation Result Handle==================");
		var resultType = result.resultType;
		Console.debug("Handle result type: " + resultType);

		if (resultType === this.AUTHEN)
			event.onAuthen(result);
		else if (resultType == this.FAIL)
			event.onFail(result);
		else if (resultType === this.SUCCESS)
			event.onSuccess(result);
		else if (resultType === this.INTERCEPTOR)
			event.onInterceptor(result);
		else
			OperaResultUtils.defaultHandle(result, "dialog");
    },
    // 业务权限结果处理
    authenHandle : function(result) {
    	Console.debug("==================Authen result handle==================");
		if (result.errorID.indexOf("bad.role") != -1) {
		    Authentication.openWindow();
		    return;
		}
		if (result.errorID.indexOf("bad.loginType.SP") != -1) {
		    Authentication.openLoginTypeModifyWindow("SP");
		    return;
		}
		if (result.errorID.indexOf("bad.loginType.RSP") != -1) {
		    Authentication.openLoginTypeModifyWindow("RSP");
		    return;
		}
		OperaResultUtils.defaultHandle(result, "error");
    },

    failHandle : function(result) {
		Console.debug("Fail result handle...");
		OperaResultUtils.defaultHandle(result, "error");
    },

    successHandle : function(result) {
		Console.debug("Success result handle...");
		OperaResultUtils.defaultHandle(result, "success");
    },

    interceptorHandle : function(result) {
		Console.debug("Interceptor result handle...");
		OperaResultUtils.defaultHandle(result, "error");
    }
};// end OperaResult
var OperaResultUtils = {
    defaultHandle : function(result, type) {
		Console.debug("Business result default handle by type: " + type);
		var msg = "<h2>" + result.message + "</h2><br/>";
		if (Excavator.devMode) {
		    msg += "<hr><p><h2>详细内容（调试模式已打开）</h2>";
		    $.each(result, function(key, value) {
		    	msg += "<li>" + key + ": " + value + "</li>";
		    })// end each
		    msg += "</p>";
		}// end if
		winPop({ html : msg, isMsg : type, width : 'mid', isLock : false });
		return msg;
    }
};// end OperaResult
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
var FieldValidate = {
    FLAGE : "FeildError", // 服务端表单验证失败标识

    // 服务端表单验证错误处理入口
    invok : function(errors, fid, event) {
		Console.info("==================Field Errors Handle==================");
		event.onFieldError(errors, fid);
    },
    handleForm : function(errors, fid) {
		Console.debug("Handle Field errors with form[" + fid + "]");
		var html = "";
		for ( var i = 0; i < errors.length; i++) {
		    var error = errors[i];
		    var f = jQuery('#' + error.fieldName);
		    html += "属性名称【" + error.fieldName + "】 错误信息【" + error.message + "】<br/>";
		}//end for
		winPop({ html : html, isMsg : 'error', width : 'max', isLock : false });
    }
};// end FieldValidate
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// 默认Ajax选项设置，该对象必须在AjaxRequest、OperaResult和FieldValidate之后定义
var AjaxOptions = {
	cache : false,//是否缓存，默认不进行缓存，浏览器将不缓存此页面。
    proBar : ProgressBar.options, //进度条属性
    callBack : AjaxRequest.defaultCallBack,// 默认回调函数
    event : {// 默认的事件有：
		onFieldError : FieldValidate.handleForm,// 表单验证错误事件
		onFail : OperaResult.failHandle,
		onSuccess : OperaResult.successHandle,
		onAuthen : OperaResult.authenHandle,
		onInterceptor : OperaResult.interceptorHandle
    }
};// end AjaxOptions
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
var ExceptionHandler = {
    FLAGE : [ "Exception", "JAFException" ], // 服务端异常标识

    // 异常处理入口
    invok : function(ex, type) {
		Console.info("==================Server Exception Handle==================");
		Console.debug("Handle exception type: " + type);
		var msg = "";
		if (type == this.FLAGE[1])
		    msg = this.jafErrorHandler(ex);
		else
		    msg = this.defaultHandler(ex);
	
		msg += this.getMssage(ex);
		winPop({ html : msg, isMsg : 'error', width : 'max', isLock : false});
    },
    
    // 默认异常处理
    defaultHandler : function(ex) {
    	return ex.defaultMsg;
    },
    
    // JAFError处理
    jafErrorHandler : function(ex) {
    	return ex.defaultMsg;
    },
    getMssage : function(ex) {
		var msg = "";
		if (Excavator.devMode) {
		    msg += "<hr><P><h2>详细内容：（调试模式已打开）</h2>";
		    msg += "<li>异常类型：" + ex.className + "</li>";
		    msg += "<li>异常信息：" + ex.message + "</li>";
		    // JAFError独有属性
		    msg += "<li>ErrorId: " + ex.errorId + "</li>";
		    msg += "<li>ErrorMsg: " + ex.errorMsg + "</li>";
		    /*
		     * 禁止堆栈信息的输出 msg += "</P>"; msg += "<P><h2>堆栈信息：</h2>"; msg += "<textarea
		     * rows='50' cols='100'>" var s = ex.stackTrace; for ( var i = 0; i <
		     * s.length; i++) { msg += s[i].className + "." + s[i].methodName +
		     * "(" + s[i].fileName + ":" + s[i].lineNumber + ")\n"; }// end for
		     * msg += "</textarea>"; msg += "</P>";
		     * 
		     */
		}
		return msg;
    }
};// end ExceptionHandler
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////

// 获取登陆框主体内容
var AuthenticationLogin = {
    // 初始化登陆框
    init : function() {
	var url = "/authen/normal/index";
	var options = {
	    async : false,
	    callBack : function(result) {
		$("#_login_div_content").html(result);
	    }
	};
	AjaxRequest.submitDefault(url, options);
    },
    // 头部登录信息查询
    headInit : function() {
	var url = "/authen/normal/headInit";
	var options = {
	    async : true,
	    callBack : function(result) {
		$("#_login_head_div_content").html(result);
	    }
	};
	AjaxRequest.submitDefault(url, options);
    }
};
// 动态密码获取
var DynamicPassword = {
    get : function(mobileNumber) {
	if (!checkRex('mobile', 11, 11).test(mobileNumber)) {
	    alert("请正确输入广东移动手机号码！");
	    return;
	}
	var url = "/components/code/dynamicPassword/send";
	var options = {
	    async : true,
	    data : {
		"mobileNumber" : mobileNumber
	    },
	    callBack : function(result) {
		alert(result);
	    }
	};
	AjaxRequest.submitDefault(url, options);
    }
};
// 鉴权
var Authentication = {
    // 登入
    login : function(fid) {
	// from提交
	// OrdinaryRequest.submitForm(fid);
	// ajax提交
	var personLoginOptions = {
	    event : {

		onSuccess : function(result) {
		    // 设置用户手机号码到cookie 有效期一年
		    setCookie('personLoginMobileNumber', $('#mobileNumber')
			    .val(), 365 * 24, '/');
		    // OperaResult.successHandle(result);
		    var backUrl = $("#_init_page").val();
		    if (typeof backUrl == 'undefined' || backUrl == "") {
			backUrl = URLHandler.DEFAULT_INIT_PAGE_AFTER_LOGIN;
		    }
		    top.location.href = backUrl;
		},

		onInterceptor : function(result) {
		    $('#ImageArea').click();
		    Authentication.imageVrifyRequired();
		    $('#personalAction').sendErr({
			tipsText : result.message
		    });
		},

		onFail : function(result) {
		    $('#ImageArea').click();
		    // 地市公告，用弹出层方式展示
		    if (/^LIMIT_ATTRIBUTE.*$/.test(result.failID)) {
			winPop({
			    "html" : result.message
			});

		    } else {
			Authentication.imageVrifyRequired();
			$('#personalAction').sendErr({
			    tipsText : result.message
			});
		    }
		},

		onFieldError : function(errors) {
		    $('#ImageArea').click();
		    for ( var i = 0; i < errors.length; i++) {
			var error = errors[i];
			$('#personalAction').sendErr({
			    tipsText : error.message
			});
		    }
		}
	    }
	};
	AjaxRequest.submitForm(fid, personLoginOptions);
    },
    // 转换登录方式
    switchLoginType : function(name, value) {
	$('#' + name).attr('value', value);
    },
    // 弹出登录框
    openWindow : function(options) {
	var closeCallBack; // closeCallBack:(fn) 窗口关闭的回调方法
	if (options != undefined) {
	    closeCallBack = options.closeCallBack;
	}
	winPop({
	    closeCallBack : closeCallBack,
	    title : '登录',
	    width : 'mid',
	    html : '<div id="loginPop" class="loginPop"></div>',
	    callBack : function() {
		$('#loginPop').load(
			URLHandler.REQ_PREFIX + '/authen/normal/index'
				+ URLHandler.REQ_SUFFIX, function() {
			    $('#loginPop').css({
				'background' : 'none'
			    });
			});
	    }
	});
    },
    /**
     * 弹出二次登录登录框 loginTypeCode登录模式编码，服务密码为SP;动态密码为RSP
     */
    openLoginTypeModifyWindow : function(name) {

	var name = name;// 登录模式编码
	var title = name == "SP" ? "服务密码登录验证" : "动态密码登录验证";
	var url = URLHandler.REQ_PREFIX + '/authen/loginTypeModify/index'
		+ URLHandler.REQ_SUFFIX + "?loginTypeName=" + name;// 默认请求地址
	winPop({
	    title : title,
	    width : 'mid',
	    html : '<div id="loginTypeModifyPop" class="loginTypeModifyPop"></div>',
	    callBack : function() {
		$('#loginTypeModifyPop').load(url, function() {
		    $('#loginTypeModifyPop').css({
			'background' : 'none'
		    });
		});
	    }
	});
    },
    // 登录模式修改
    loginTypeModify : function(fid) {
	var options = {
	    event : {
		onSuccess : function(result) {
		    top.location.reload();
		},
		onFail : function(result) {
		    $('#personalAction').sendErr({
			tipsText : result.message
		    });
		},
		onFieldError : function(errors) {
		    for ( var i = 0; i < errors.length; i++) {
			var error = errors[i];
			$('#personalAction').sendErr({
			    tipsText : error.message
			});
		    }
		}
	    }
	};
	AjaxRequest.submitForm(fid, options);
    },
    // 弹出签订协议登录框
    openBizAgreementWindow : function(options) {
	winPop({
	    isMsg : 'optionTips',
	    optionTitle : '办理该业务前请先接受业务办理协议。 ',
	    html : '<input id="s_biz_agreement"  onclick="Authentication.bizAgreementCheck();" type="checkbox"/>已<a href="/service/agreement.shtml" class="color_1" target="_blank">阅读</a>并接受 业务办理协议',
	    button : '<span class="btn_150x30"><button disabled="disabled" id="s_biz_agreement_button" onclick="javascript:Authentication.bizAgreement();">确 认</button></span>'
		    + '&nbsp;&nbsp;<span class="btn_150x30"><button onclick="location.href=\'/common/redirect.jsp\'">返回网厅首页</button></span>'
	});
    },
    //
    bizAgreementCheck : function() {
	$("#s_biz_agreement_button").attr("disabled",
		!$("#s_biz_agreement").attr("checked"));

    },
    // 签订协议
    bizAgreement : function() {
	var url = "/authen/normal/bizAgreement";
	var options = {
	    callBack : function(result) {
		top.location.reload();
	    }
	};
	AjaxRequest.submitDefault(url, options);
    },
    // 判断是否需要验证码
    imageVrifyRequired : function() {
	// 手机号码格式不满足 则不执行
	if (!checkRex('mobile', 11, 11).test($('#mobileNumber').val())) {
	    return;
	}
	var options = {
	    async : true,
	    data : {
		"mobileNumber" : $("#mobileNumber").val()
	    },
	    event : {
		onSuccess : function(result) {
		    if ("IMAGEVRIFY_REQUIRED" == result.successID) {
			$("#imageCode").attr("parameter", "{type:'checkCode'}")
			$("#imageCodePersonalTr").show();
		    } else {
			$("#imageCode").removeAttr("parameter");
			$("#imageCodePersonalTr").hide();
		    }
		}
	    }
	};
	AjaxRequest.submitDefault("/authen/normal/imageVrifyRequired", options);
    },
    // 登出
    logout : function() {
	var options = {
	    async : true,
	    event : {
		onSuccess : function(result) {
		    top.location.href = "/";
		},
		onFail : function(result) {
		    $('#personalAction').sendErr({
			tipsText : result.message
		    });
		}
	    }
	};
	AjaxRequest.submitDefault("/authen/normal/logout", options);
    },
    // 监控用户登入
    monitorLogin : function(fid) {
	// ajax提交
	var personLoginOptions = {
	    event : {
		onSuccess : function(result) {
		    // 设置用户手机号码到cookie 有效期一年
		    setCookie('personLoginMobileNumber', $('#mobileNumber')
			    .val(), 365 * 24, '/');
		    var backUrl = $("#_init_page").val();
		    if (typeof backUrl == 'undefined' || backUrl == "") {
			backUrl = URLHandler.DEFAULT_INIT_PAGE_AFTER_LOGIN;
		    }
		    top.location.href = backUrl;
		},

		onInterceptor : function(result) {
		    $('#personalAction').sendErr({
			tipsText : result.message
		    });
		},

		onFail : function(result) {
		    // 地市公告，用弹出层方式展示
		    if (/^LIMIT_ATTRIBUTE.*$/.test(result.failID)) {
			winPop({
			    "html" : result.message
			});

		    } else {
			$('#personalAction').sendErr({
			    tipsText : result.message
			});
		    }
		},

		onFieldError : function(errors) {
		    for ( var i = 0; i < errors.length; i++) {
			var error = errors[i];
			$('#personalAction').sendErr({
			    tipsText : error.message
			});
		    }
		}
	    }
	};
	AjaxRequest.submitForm(fid, personLoginOptions);
    }
};// end Authentication
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////////////////
var ObjectUtils = {
    OBJ_TYPE : "object", // 对象类型
    STR_TYPE : "string", // 字符串类型
    UNDEFINED_TYPE : "undefined",// 未定义类型

    // 判断某个对象是否是JSON对象
    // 判断某个字符串是否是JSON格式
    // true表示是JSON对象或JSON格式
    isJson : function(obj) {
		try {
		    if (typeof (obj) == this.OBJ_TYPE) {
			return Object.prototype.toString.call(obj).toLowerCase() == "[object object]"
				&& !obj.length;
		    } else if (typeof (obj) == this.STR_TYPE) {
			return !(jQuery.parseJSON(obj) == null);
		    } else {
			return false;
		    }
		} catch (e) {
		    Console.error("ObjectUtils.isJson catch a exception: " + e);
		    return false;
		}
		return true;
    },
    // 判断某个对象是否是数组类型
    // true表示该对象是数组
    isArray : function(obj) {
    	return $.isArray(obj);
    },
    // 创建一个序列化的数组或对象，适用于一个URL 地址查询字符串或Ajax请求。
    param : function(obj) {
    	return $.param(obj, true);
    },
    // 判断某个对象是否未定义
    // true表示未定义
    isUndefined : function(obj) {
    	return jQuery.type(obj) == this.UNDEFINED_TYPE;
    }
};// end ObjectUtils
var ArrayUtils = {
    // 判断某个对象是否在给定的数组中
    containts : function(array, obj) {
		if (!ObjectUtils.isArray(array))
		    return false;
		if (ObjectUtils.isUndefined(obj))
		    return false;
		return jQuery.inArray(obj, array) > -1;
    }
};// end ArrayUtils

