tchao 3 gadi atpakaļ
vecāks
revīzija
2dd0e246f1
89 mainītis faili ar 27282 papildinājumiem un 0 dzēšanām
  1. 1332 0
      web/js/angular/angular-file-upload.js
  2. 209 0
      web/js/angular/angular.min.js
  3. 690 0
      web/js/angular/baseServices.js
  4. 29 0
      web/js/angular/controller/busQueryRuleController.js
  5. 472 0
      web/js/angular/controller/sysQueryViewController.js
  6. 42 0
      web/js/angular/service/arrayToolService.js
  7. 279 0
      web/js/angular/service/baseServices.js
  8. 26 0
      web/js/angular/service/commonListService.js
  9. 115 0
      web/js/angular/service/sysQueryFieldService.js
  10. 664 0
      web/js/angular/service/sysQueryViewFilterSetting.js
  11. 1414 0
      web/js/bootstrap/bootstrap-dialog.min.js
  12. 7 0
      web/js/bootstrap/bootstrap.min.js
  13. 8 0
      web/js/bootstrap/fuelux.wizard.min.js
  14. 4 0
      web/js/bootstrap/html5shiv.min.js
  15. 366 0
      web/js/bootstrap/jquery.easypiechart.min.js
  16. 4 0
      web/js/bootstrap/jquery.min.js
  17. 2 0
      web/js/bootstrap/jquery.sparkline.min.js
  18. 4 0
      web/js/bootstrap/jquery1x.min.js
  19. 5 0
      web/js/bootstrap/respond.min.js
  20. 17 0
      web/js/bootstrap/slider-layer-slider/greensock.js
  21. 13 0
      web/js/bootstrap/slider-layer-slider/layerslider.kreaturamedia.jquery.js
  22. 13 0
      web/js/bootstrap/slider-layer-slider/layerslider.transitions.js
  23. 113 0
      web/js/calendar/My97DatePicker/WdatePicker.js
  24. 5 0
      web/js/calendar/My97DatePicker/calendar.js
  25. 28 0
      web/js/calendar/My97DatePicker/idea-WdatePicker-js.xml
  26. 14 0
      web/js/calendar/My97DatePicker/lang/en_US.js
  27. 14 0
      web/js/calendar/My97DatePicker/lang/zh_CN.js
  28. 11 0
      web/js/calendar/My97DatePicker/skin/WdatePicker.css
  29. BIN
      web/js/calendar/My97DatePicker/skin/datePicker.gif
  30. BIN
      web/js/calendar/My97DatePicker/skin/default/img.gif
  31. BIN
      web/js/calendar/My97DatePicker/skin/whyGreen/bg.jpg
  32. BIN
      web/js/calendar/My97DatePicker/skin/whyGreen/img.gif
  33. 18 0
      web/js/conf/orgUserConf.js
  34. 4 0
      web/js/dynamic.jsp
  35. 1 0
      web/js/echarts/chart/chord.js
  36. 1 0
      web/js/echarts/chart/eventRiver.js
  37. 1 0
      web/js/echarts/chart/force.js
  38. 1 0
      web/js/echarts/chart/gauge.js
  39. 1 0
      web/js/echarts/chart/line.js
  40. 10 0
      web/js/echarts/chart/map.js
  41. 1 0
      web/js/echarts/chart/scatter.js
  42. 12 0
      web/js/echarts/echarts.js
  43. 8 0
      web/js/fullcalendar/fullcalendar.min.js
  44. 184 0
      web/js/fullcalendar/gcal.js
  45. 121 0
      web/js/im/JSONResult.java
  46. 97 0
      web/js/im/controller/ImController.java
  47. 27 0
      web/js/im/encrypt/EMain.java
  48. 243 0
      web/js/im/encrypt/Encrypt.java
  49. 92 0
      web/js/im/network/HttpQueue.java
  50. 2 0
      web/js/jiejiari/jquery-1.8.3.min.js
  51. 10932 0
      web/js/jiejiari/jquery.easyui.min.js
  52. 1050 0
      web/js/jiejiari/jquery.fullcalendar.js
  53. BIN
      web/js/jqueryMedia/mediaplayer.swf
  54. 2 0
      web/js/kinggrid_h5/dialog-min.js
  55. 2 0
      web/js/kinggrid_h5/jquery-1.8.3.min.js
  56. 2752 0
      web/js/kinggrid_h5/jsQR.js
  57. 30 0
      web/js/kinggrid_h5/kinggrid.plus.min.js
  58. 8 0
      web/js/kinggrid_h5/password.min.js
  59. 34 0
      web/js/kinggrid_h5/qrcode.min.js
  60. 176 0
      web/js/kinggrid_h5/search.js
  61. 32 0
      web/js/msg.jsp
  62. 1064 0
      web/js/mySchedule/jquery.fullcalendar.js
  63. 148 0
      web/js/ntkoWebSign/NtkoAddSecSign.js
  64. 529 0
      web/js/ntkoWebSign/NtkoWebSign.js
  65. 281 0
      web/js/ntkoWebSign/WebSignPlugin.js
  66. BIN
      web/js/ntkosign/NtkoControlSetup.zip
  67. 155 0
      web/js/ntkosign/NtkoSignManage.js
  68. BIN
      web/js/ntkosign/SignToolSetup.zip
  69. BIN
      web/js/ntkosign/ntkosigntoolv3.cab
  70. 12 0
      web/js/rendor/recorder.js
  71. 175 0
      web/js/swfupload/fileprogress.js
  72. 175 0
      web/js/swfupload/handlers.form.upload.js
  73. 1132 0
      web/js/swfupload/swfupload.js
  74. 98 0
      web/js/swfupload/swfupload.queue.js
  75. BIN
      web/js/swfupload/swfupload.swf
  76. BIN
      web/js/swfupload/swfuploadbutton.swf
  77. 85 0
      web/js/util/ResizeControl.js
  78. 232 0
      web/js/util/SelectOption.js
  79. 102 0
      web/js/util/XMLDom.js
  80. 32 0
      web/js/util/bak/CustomerWindow.js
  81. 112 0
      web/js/util/bak/dialog.js
  82. 3 0
      web/js/util/demo/js2.js
  83. 26 0
      web/js/util/demo/loadjsdemo.htm
  84. 55 0
      web/js/util/easyTemplate.js
  85. 194 0
      web/js/util/form.js
  86. 482 0
      web/js/util/json2.js
  87. 94 0
      web/js/util/loadjscss.js
  88. 35 0
      web/js/util/sqlUtil.js
  89. 319 0
      web/js/util/tablednd.js

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1332 - 0
web/js/angular/angular-file-upload.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 209 - 0
web/js/angular/angular.min.js


+ 690 - 0
web/js/angular/baseServices.js

@@ -0,0 +1,690 @@
+(function (){
+    var paths  = [
+              ];
+    for (var i=0,pi;pi = paths[i++];) {
+        document.write('<script type="text/javascript" src="'+ __ctx + pi +'"></script>');
+    }
+})();
+var baseServices = angular.module( "baseServices", ["authApp",'ComplexService'] );
+baseServices.factory("$jsonToFormData",function() {
+	function transformRequest( data, getHeaders ) {
+		var headers = getHeaders();
+		headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8";
+		return $.param(data);
+	}
+	return( transformRequest );
+})
+.directive('htCheckbox', function() {
+	return {
+        restrict: 'A',
+        link: function(scope, element, attrs) {
+            var key = attrs["htCheckbox"];
+            var getValAry = function(){
+                var val = getValByScope(element,key);
+                if(val){
+                    if(typeof val == "string"){
+                        return {type:"string",data:val.split(",")};
+                    }
+                    else{
+                        return {type:"object",data:val};
+                    }
+                }
+                return {type:"string",data:[]};
+            };
+            scope.$watch(key,function(newVal,oldVal){
+                if(!newVal)return;
+                if(newVal!==oldVal || !element.data("notFirstTime")){
+                    element.data("notFirstTime",true);
+                    if(typeof newVal == "string"){
+                        if(newVal==element.val()||newVal.split(",").indexOf(element.val())!=-1){
+                            element[0].checked = true;
+                        }
+                        else{
+                            element[0].checked = false;
+                        }
+                    }
+                    else{
+                        if(newVal.indexOf(element.val())!=-1){
+                            element[0].checked = true;
+                        }
+                        else{
+                            element[0].checked = false;
+                        }
+                    }
+                }
+            },false);
+            element.bind('change',function(){
+                var elementVal = element[0].checked,
+                    option = attrs["value"],
+                    array = getValAry();
+                if(elementVal){
+                    if(!isInArray(array.data,option)){
+                        array.data.push(option);   
+                    }
+                }
+                else{
+                    array.data.remove(option);
+                }
+                if(array.data.length > 1){
+                    array.data.remove("");
+                }
+                else if(array.data.length == 0){
+                    array.data.push("");
+                }
+                if(array.type=="string"){
+                    setValToScope(element,array.data.join(','),null,key);    
+                }
+                else{
+                    setValToScope(element,array.data,null,key);       
+                }
+            });
+        }
+    };
+})
+.provider('DemotionPermission',function(){
+	//是否需要权限降级
+	var _demotion = false;
+	this.setDemotion = function(t){
+		_demotion = !!t;
+	}
+	this.$get = function(){
+		return {
+			demotion : _demotion
+		};
+	}
+})
+/**
+ * 表单权限控制
+ */
+.directive('htPermission', ['$compile','DemotionPermission',function($compile,DemotionPermission) {
+	return {
+		priority:5,
+		link:function(scope,elm,attrs){
+			scope.handlerPermission = function(newVal,el,attr){
+				//需要权限降级时  将必填、编辑 权限降级为只读
+				if(DemotionPermission.demotion){
+					if(newVal!="y"||newVal!="r"){
+						newVal = "r";
+					}
+				}
+				var	ngModel=attr.ngModel,scopeVal = '';
+				if(el.attr("type") == "subGroupTr"){
+					scope.subFieldPermission(newVal,el);
+				}
+				else if(el.attr("type") == "subGroup"){
+	    			scope.subFieldPermission(newVal,el);
+	    		}else {
+	    			scopeVal= getValByScope(el,ngModel,scope) || '';
+	    			scope.fieldPermission(newVal,el,scopeVal);
+	    		}
+			};
+	    	scope.$watch(attrs.htPermission,function(newVal,oldVal){
+	    		if(!newVal)return;
+	    		if (newVal !== oldVal || !elm.data("notFirstTime")) {
+	    			elm.data("notFirstTime", true);
+	    			if((attrs.htSelectorDef&&parseToJson(attrs.htSelectorDef)['showCurrent'])||(elm.hasClass("selector-home")&&attrs.selectorType))
+	    				window.setTimeout(function(){ 
+	    					scope.handlerPermission(newVal,elm,attrs);
+	    				},100);
+	    			else
+	    				scope.handlerPermission(newVal,elm,attrs);
+	    		}
+	    	});
+	    	/**
+	    	 * 复合字段(子表)权限
+	    	 */
+	    	scope.subFieldPermission = function(val,elm){
+	    		switch (val) {
+					case 'b': //必填
+						var temp = attrs.htPermission.split("."),
+							ngModel = "data."+temp[temp.length-1];
+						scope.$watch(ngModel.replaceAll("\\$\\$","."),function(n,o){
+							if(n.length==0){
+								elm.addClass("field-home");
+								elm.validMe({text:"",rule:"{'required':true}"});
+							}else{
+								elm.qtipSuccess();
+							}
+						},true);
+						break;
+					case 'r': //只读
+						var inputList = elm.find("[ht-permission]");
+						inputList.each(function(){
+							var scopeVal = getValByScope($(this),"","");
+							$(this).after("<span>"+scopeVal+"</span>");
+							$(this).remove();
+						});
+						elm.children(".group-title").find("a[ng-click]").remove();
+						elm.children(".owner-div").find("a[ng-click]").remove();
+						break;
+					case 'y': //隐藏
+						elm.remove();
+						break;
+					default://编辑没修改(w)
+						break;
+				}
+	    	};
+	    	/**
+    		 * 字段权限
+    		 */
+	    	function setToReadCall(elm,scopeVal){
+	    		if(isComplexTag(elm)){
+					elm.parent().html("<span>"+scopeVal+"</span>");
+				}else if(elm.hasClass("file-div")){
+					if(scopeVal){
+						elm.next().remove();
+						elm.next().remove();
+						var temp = [];
+						for(var i =0 ;i<scopeVal.length;i++){
+							temp.push("<a onclick='downLoadFileById(\""+scopeVal[i].fileId+"\")' class='file-down' title='点击下载附件'>"+scopeVal[i].fileName+"</a>");
+						}
+						elm.after("<span>"+temp.join(",")+"</span>");
+					}else{
+						elm.closest(".s-closest").remove();
+					}
+					
+				}else{
+					elm.after("<span>"+scopeVal+"</span>");
+				}
+				elm.remove();
+	    	}
+	    	function setToRead(elem,scopeVal){
+	    		if(scopeVal){
+	    			setToReadCall(elem,scopeVal);
+	    			return;
+	    		}
+	    		var showCuEl = elem.attr("selector-def-div");
+	    		if(!showCuEl){
+	    			setToReadCall(elem,scopeVal);
+	    			return;
+	    		}
+	    		showCuEl = parseToJson(showCuEl);
+	    		if(!showCuEl.showCurrent){
+	    			setToReadCall(elem,scopeVal);
+	    			return;
+	    		}
+				window.setTimeout(function(){
+					setToRead(elem,getValByScope(elem));
+				},1000);
+	    	}
+	    	scope.fieldPermission = function(val,elm,scopeVal){
+	    		var elmParent = elm.parent();
+	    		switch (val) {
+					case 'b': //必填
+						//让字段必填 ht-field-valid="{'required':true}"
+						var tempValid = elm.attr("ht-field-valid");
+						if(tempValid){
+							tempValid = parseToJson(tempValid);
+						}else{
+							tempValid = {};
+							elm.addClass("field-home");
+						}
+						tempValid.required=true;
+						var ngModelVal = elm.attr("ng-model"); 
+						elm.removeAttr("ng-model");
+						elm.attr("ht-field-valid",JSON.stringify(tempValid));
+						$compile(elm)(elm.scope());
+						ngModelVal&&elm.attr("ng-model",ngModelVal);
+						break;
+					case 'r': //只读
+						setToRead(elm,scopeVal);
+						break;
+					case 'y': //隐藏
+						
+						if(isComplexTag(elm)||elm.attr("ht-file")){
+							elm = elm.closest(".field-home");
+							elm.prev('th').remove();
+						}else{
+							elm.parent().prev('th').remove();
+						}
+						var closestTR = elm.closest("tr") ;
+						var closestSubGroup = elm.closest("[type='subGroup']") ;
+						var tdths=closestTR.children();
+						elm.remove();
+						var isNull = true;
+						tdths.each(function(){
+							if($(this).html()){
+								isNull=false;
+								return true;
+							}
+						});
+						if(isNull) closestTR.remove();
+						//如果是子表,那么当字表中的tbody为空时 就隐藏
+						if(closestSubGroup[0]&&!closestSubGroup.find('tbody').html()) closestSubGroup.remove();
+						break;
+					default://编辑没修改(w)
+						break;
+				}
+	    	};
+	    	//在需要权限降级时,如果没有配置字段权限,默认为只读权限
+	    	if(DemotionPermission.demotion){
+				scope.handlerPermission('r',elm,attrs);
+			}
+		}
+	};
+}])
+.directive('htDate', function() {
+    return {
+        restrict: 'A',
+        link: function(scope, element, attrs) {
+        	var ngModel = attrs.ngModel;
+        	switch(attrs.htDate){
+        		case "date":
+        			$(element).on("focus",function(){
+        				var me = $(this);
+        				WdatePicker({dateFmt:'yyyy-MM-dd',alwaysUseStartDate:true});
+        				me.blur();
+    				   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+        			});
+        		break;
+         		case "datetime":
+        			$(element).on("focus",function(){
+        				var me = $(this);
+        				WdatePicker({dateFmt:'yyyy-MM-dd',alwaysUseStartDate:true});
+        				me.blur();
+    				   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+    			});
+        		break;
+        		case "wdateTime":
+        			$(element).on("focus",function(){
+        				var me = $(this), dateFmt=  (me.attr('datefmt')?me.attr('datefmt'):'yyyy-MM-dd');
+            			WdatePicker({dateFmt:dateFmt,alwaysUseStartDate:true});
+            			me.blur();
+        			   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+        			});
+        		break;
+        	}
+        }
+    };
+})
+/**
+ * 对时间进行格式化处理  控件格式如下
+ * <input type="text" 
+ * 	ng-model="data.person.born" 
+ * 	class="inputText" 
+ * 	ht-date-format="
+ * 		{'currentTime':true,'exp':'yyyy-MM-dd HH:mm:ss'}
+ * 	">
+ * currentTime:表示是否显示当前日期
+ * exp:格式化表达式
+ */
+.directive('htDateFormat', function($injector) {
+	var link = function(scope, element, attrs, $ctrl) {
+		var json = parseToJson(attrs['htDateFormat']);
+		element.addClass("dateformat");
+		if(json.currentTime){
+			var now=new Date().Format(json.exp);
+			setValToScope(element,now);
+		}
+	};
+	return {
+		restrict : 'A',
+		require : "ngModel",
+		compile : function() {
+			return link;
+		}
+	};
+})
+.directive('htDic', function(){
+	return {
+		restrict: 'EAC',
+		require : "ngModel",
+		link: function(scope, element, attrs) {
+			if(!attrs.htDic)return;
+			scope.$watch(attrs.ngModel,function(newVal,oldVal){
+				if (newVal !== oldVal || !element.data('dictionary')) {
+	    			element.data('dictionary', true);
+	    			scope.update(newVal);
+				}
+			},false);
+			
+			//ngModel的值变化 与 数据字典的初始化 是两条生命周期线,要进行赋值需要在两者都完成的时候进行
+			scope.update = function(val){
+				var dicReady = element.data("dictionaryReady"); 
+				if(typeof dicReady=='undefined'){
+					element.data("dictionaryReady",(typeof val=='undefined')?true:val);
+				}
+				else{
+					var relVal = (typeof val=='undefined')?dicReady:val;
+					element.combotree("clear");
+					//选中数据字典中key与ngModel值相同的节点
+					element.eachComboNode(function(node){
+						if(node.key&&node.key==relVal){
+							element.combotree('setValue',node.id);
+							return false;
+						}
+						return true;
+					});
+				}
+			}
+			
+			var url = __ctx +"/platform/system/dataDict/getByTypeKeyForComBo.ht?typeKey="+attrs.htDic;
+			element.combotree({
+				url:url,
+				onLoadSuccess:function(node,data){
+					scope.update();
+				},
+				onClick:function(node){
+					setValToScope(element,node.key);
+				}
+			});
+		}
+	};
+})
+.directive('htFileUpload', [function() {
+	return {
+		restrict: 'EAC',
+		scope:{
+			htFileUpload:'='
+		},
+		link: function(scope, element, attrs) {
+			scope.choose = function(){
+				UploadDialog(scope.setting);
+			}
+			
+			scope.download = function(item){
+				window.open(__ctx + "/platform/system/file/download.ht?id="+item.id);
+			}
+			
+			//移除某项
+			scope.remove = function(index){
+				scope.file.splice(index,1);
+				scope.updateValue(false);
+			}
+			
+			scope.updateValue = function(digest){
+				var v = scope.file.length==0?"":angular.toJson(scope.file);
+				//更新数据到父作用域
+				if("ng"==scope.setting.bindType){
+					var ngModel = attrs['ngModel'];
+					if(!ngModel)return;
+					eval('scope.$parent.' + ngModel + '=' + (v?v:"''"));
+					digest&&scope.$parent.$digest();
+				}
+				//更新数据到对象元素
+				else if("jq"==scope.setting.bindType){
+					if(!scope.bindObj)return;
+					scope.bindObj.val(v);
+				}
+			}
+			
+			var setting = {
+				download:true,	//true:允许下载,false:不允许下载
+				bindType:'ng'	//ng:ng-model模式,jq:jquery模式,jq模式下需要配置bind属性
+			};
+			
+			if($.extend(true,setting,scope.htFileUpload||{})){
+				scope.setting = setting;
+				
+				scope.setting.callback = function(data){
+					!angular.isArray(scope.file)&&(scope.file==[]);
+					scope.file = scope.file.concat(data);
+					scope.updateValue(true);
+				}
+				
+				if("ng"==scope.setting.bindType){
+					var ngModel = attrs['ngModel'];
+					if(!ngModel)return;
+					scope.$parent.$watch(ngModel,function(newVal,oldVal){
+			    		if (newVal !== oldVal || !element.data('file')) {
+			    			element.data('file', true);
+							scope.file = newVal || [];
+						}
+					},false);
+				}
+				else if("jq"==scope.setting.bindType){
+					var bindObj = angular.element(scope.setting.bind);
+					if(!bindObj)return;
+					scope.bindObj = bindObj;
+					scope.file = parseToJson(bindObj.val()||'');
+				}
+			}
+		},
+		template: '<span><div class="ht-input"><span class="span-user owner-span" ng-repeat="item in file">'
+				 +'<a title="下载该文件" ng-if="setting.download" ng-click="download(item)">{{item.name}}</a><span ng-if="!setting.download">{{item.name}}</span>'
+				 +'<a class="btn btn-xs fa-remove" style="margin-bottom:4px;" title="移除该项" ng-click="remove($index)"></a></span>'
+				 +'</div><a class="btn btn-sm btn-primary fa-upload" ng-click="choose()"><span>上传</span></a></span>',
+        replace: true
+	};
+}])
+/**
+ * ht-select-ajax  动态加载select的options数据  
+ *  列如: <select ng-model="form.typeId" ng-options="(m.id) as m.text for m in formTypeList"
+ *			  ht-select-ajax="{url:'${ctx}/platform/system/sysType/getByGroupKey.ht?groupKey=FORM_TYPE',field:'formTypeList'}">
+ *		 		 <option value="">请选择</option>
+ *		 </select>
+ *	传入参数 
+ *		url : 请求地址 
+ *		field : formTypeList 对应于 ng-options 中的 formTypeList (两者必须相同)
+ */
+.directive('htSelectAjax', function($injector) {
+	return {
+		restrict: 'A',
+		link: function(scope, element, attrs) {
+			var BaseService = $injector.get("BaseService");
+			var option=attrs["htSelectAjax"];
+			option=eval("("+option+")");
+			if(scope.$root.$$childHead[option.field]) return;
+			BaseService.get(option.url,function(data){
+				if(option.dataRoot){
+					data = data[option.dataRoot];
+				}
+				scope[option.field] = data;
+				scope.$root.$$childHead[option.field] = scope[option.field];
+			});
+		}
+	};
+})
+.directive('htTip', function($injector) {
+	return {
+		restrict: 'A',
+		scope:{
+			htTip:"="
+		},
+		link: function(scope, element, attrs) {
+			var defaultSetting = {
+					hide: {
+						event:'mouseleave',
+   			        	leave: false,
+   			        	fixed:true,
+   			        	delay:100
+			        },
+					style: {
+						classes: 'qtip-default  qtip qtip-bootstrap qtip-shadow'
+				    }
+				  };
+			var setting = angular.extend(scope.htTip || {},defaultSetting);
+			element.qtip(setting);
+		}
+	};
+})
+.directive('htZtree', ['BaseService',function(BaseService) {
+    return {
+        restrict: 'A',
+        scope:{
+        	htZtree:"=",
+        	htCallback:"=",
+        	htDataKey:"=",
+        	htCheck:"="
+        },
+        link: function(scope, element, attrs) {
+        	element.addClass("ztree");
+        	if(!element.prop("id")){
+        		//ztree所在ul标签必须有唯一的id属性,否则当页面有两个ztree时回调函数会出现问题
+        		element.prop("id",BaseService.guid());
+        	}
+        	scope.setting = {
+        			view:{
+        				dblClickExpand:false
+        			},
+        			data:{
+        				key:scope.htDataKey||{}
+        			},
+        			check:scope.htCheck||{},
+		        	callback: scope.htCallback||{}
+        	};
+        	
+        	scope.$watch("htZtree",function(newVal,oldVal){
+        		if(newVal!==oldVal){
+        			$.fn.zTree.init($(element),scope.setting, newVal);
+        		}
+        	},true);
+        }
+    };
+}])
+.directive('htBindHtml', function($compile) {
+	return {
+		restrict : 'A',
+		link : function(scope, elm, attrs) {
+			scope.unbindWatch = scope.$watch(attrs.htBindHtml, function(newVal, oldVal) {
+                if (newVal !== oldVal) {
+                    if(newVal){
+                        elm.data('unbindWatchTag',true);
+                        elm.html(newVal);
+                        scope.htmlFn&&scope.htmlFn.call();
+                        $compile(elm)(scope);
+                    }
+                    else{
+                        elm.html('');
+                        //避免重复添加监视
+                        elm.data('unbindWatchTag')&&scope.unbindWatch();
+                    }
+                }
+            });
+		}
+	};
+})
+.directive('htInit', function($compile) {
+	return {
+		restrict : 'A',
+		link : function(scope, elm, attrs) {
+			var json = parseToJson(attrs["htInit"]);
+			for(var i in json){
+				setValToScope(null,json[i],null,i,scope);
+			}
+		}
+	};
+})
+//显示用户的指令,使用示例:<input ht-user-tag="1" />
+.directive('htUserTag', ["BaseService",function(BaseService) {
+	return {
+		restrict : 'A',
+		scope:{
+			//userId
+			htUserTag:"=",
+		},
+		controller: function($scope,$element){
+			$scope.showDetail = function(userId){
+				new UserInfoDialog(userId).show();
+			}
+		},
+		link : function(scope, elm, attrs) {
+			if(scope.htUserTag){
+				BaseService.post(__ctx + "/platform/org/user/userInfo.ht",{id:scope.htUserTag},function(data){
+					scope.user = data;
+				});
+			}
+		},
+		template:'<span class="owner-span" ng-hide="user | isEmpty"><a href="#" ng-click="showDetail(user.id)">{{user.name}}</a></span>',
+		replace:true
+	};
+}])
+.directive('onFinishRenderFilters', function ($timeout) {
+    return {
+        restrict: 'A',
+        link: function(scope, element, attr) {
+            if (scope.$last === true) {
+                $timeout(function() {
+                    scope.$emit('ngRepeatFinished');
+                });
+            }
+        }
+    };
+})
+.service('BaseService', ['$http','$jsonToFormData', function($http,$jsonToFormData) {
+    var service = {
+    		get:function(url,callback){
+    			$http.get(url).success(function(data,status){
+            		if(callback){
+            			callback(data,status);
+            		}
+        		})
+        		.error(function(data,status){
+        			if(callback){
+            			callback(data,status);
+        			}
+        			//TODO 根据返回的错误状态(status)显示对应的全局提示
+        		});
+    		},
+    		post:function(url,param,callback){
+    			$http.post(url,param,{transformRequest:$jsonToFormData})
+				 .success(function(data,status){
+					 if(callback){
+	    				callback(data,status);
+	    			 }
+				 })
+				 .error(function(data,status){
+					 if(callback){
+	    				callback(data,status);
+	    			 }
+					 //TODO 根据返回的错误状态(status)显示对应的全局提示
+				 });
+    		},
+    		//m内容,b:true->alert输出;false:console
+    		show:function(m,b){
+    			if(b==null||b==false){
+    				console.info(m);
+    			}else{
+    				alert(m+"");
+    			}
+    		},
+    		//生成ID
+    		guid:function(){
+    			return Math.random().toString(36).substring(2, 15) +
+    	        	   Math.random().toString(36).substring(2, 15);
+    		}
+        };
+    return service;
+}])
+.filter('isEmpty', function () {
+        var bar = "";
+        return function (obj) {
+            for (bar in obj) {
+                if (obj.hasOwnProperty(bar)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+})
+.filter('htTime', function () {
+	//毫秒转换成 **天**小时**分**秒的格式
+	return function (input) {
+        var day = (input / 1000 / 60 / 60 / 24) << 0
+        	hour = (input / 1000 / 60 /60) % 24 << 0,
+        	min = (input / 1000 / 60) % 60 << 0,
+            sec = Math.round((input / 1000) % 60),
+            result = [];
+        
+        if(day){
+        	result.push(day + '天');
+        }
+        if(hour){
+        	result.push(hour+'小时');
+        }
+        if(min){
+        	result.push(min+'分');
+        }
+        if(!isNaN(sec)&&sec){
+        	result.push(sec+'秒');
+        }
+        return result.join('');
+    };
+});
+

+ 29 - 0
web/js/angular/controller/busQueryRuleController.js

@@ -0,0 +1,29 @@
+var dataRightsJsonApp = angular.module('busQueryRuleApp', [ 'baseServices','DataRightsApp' ]);
+dataRightsJsonApp.controller('busQueryRuleCtrl',['$scope','BaseService','dataRightsService','$timeout',function($scope,BaseService,dataRightsService,$timeout){
+	var service = dataRightsService;
+	$scope.service = service;
+	$timeout(function(){
+		$scope.tab =$("#tab").ligerTab({});	
+		$scope.hasInitTab = 124;
+		$scope.$digest();
+	},100)
+	service.init($scope);
+	$scope.filterUrl = __ctx + "/platform/bus/busQueryRule/filterDialog.ht?tableName=";
+	$scope.save = function(){
+		if ($scope._validForm()) {
+			service.customFormSubmit();
+		}
+	}
+	
+	$scope._validForm = function (){
+		var form=$('#dataRightsForm');
+		if(!form.valid()) return false;
+		//判断排序字段太多报错问题
+		if($scope.sortFields&&$scope.sortFields.length>3){
+			$.ligerDialog.error("排序字段不能设置超过3个,请检查!","提示信息");
+			$scope.tab.selectTabItem("sortSetting");
+			return false;
+		}
+		return true;
+	}
+}]);

+ 472 - 0
web/js/angular/controller/sysQueryViewController.js

@@ -0,0 +1,472 @@
+var sysQueryViewApp = angular.module('sysQueryViewApp', [ 'baseServices','DataRightsApp' ]);
+sysQueryViewApp.controller('sysQueryViewCtrl',['$scope','BaseService','dataRightsService',function($scope,BaseService,dataRightsService){
+	var service = dataRightsService;
+	service.noRights = true;
+	$scope.service = service;
+	$scope.type = "sysQueryView";
+	window.setTimeout(function(){
+		$scope.tab =$("#tab").ligerTab({});
+		$scope.hasInitTab = true;
+		$scope.$digest();
+		$scope.tab.selectTabItem("filterSetting");
+		var width = $('div[tabid="filterSetting"]').width()- 50;
+		var height = $("#sql").height();
+		editor = CodeMirror.fromTextArea(document.getElementById("sql"), {
+			mode: "text/x-mariadb",
+			lineWrapping:true,
+			lineNumbers: true
+		 });
+		editor.setSize(width,height);
+		$scope.tab.selectTabItem("baseSetting");
+//		//初始化日期控件
+		FormUtil.initCalendar();	
+		$("#ruleDiv").linkdiv({data:$scope.filterFields.conditions,
+							updateContent:updateContent,
+							rule2json:rule2json});
+		
+		$("#sqlTip").qtip({
+			content:{
+				text:'<div>该脚本为 groovyScript脚本 ,返回值为可执行的sql语句,' +
+					'<p>例:String sql ="select ID,field from table where 1=1";<br/>' +
+					
+					'if(params.containsKey("CATEGORY"))<br/>' +
+					'&nbsp;&nbsp;sql += " and CATEGORY like \'%"+CATEGORY+"%\'";<br/>' +
+					'return sql; </p>' +
+					'其中的params为系统所封装的一个Map对象,他封装了上下文查询条件。' +
+					'</div>'
+			}
+		});
+
+		$("#sqlTip2").qtip({
+			content:{
+				text:'<div>该脚本为sql语句 ,所填写语句会在where 1=1 后面添加,' +
+				'<p>例:AND USERID = [CUR_USER]' +
+				'</p>' +
+				'</div>'
+			}
+		});
+		
+		$scope.$digest();
+	},500);
+	service.init($scope);
+	$scope.save = function(){
+		if ($scope._validForm()) {
+			if ($scope.dataRightsJson.id) {
+				$.ligerDialog.confirm("保存会覆盖模板,如果修改了模板请手动保存模板后再进行保存业务数据模板,是否继续保存?","提示信息",function(rtn) {
+						if (rtn) service.customFormSubmit(showViewResponse);
+					});
+			} else {
+				service.customFormSubmit(showViewResponse);
+			}
+		}
+	},
+	
+	showViewResponse =function(responseText){
+		$.ligerDialog.closeWaitting();
+		var obj = new com.hotent.form.ResultMessage(responseText);
+		if (obj.isSuccess()) {
+			$.ligerDialog.confirm( obj.getMessage()+",是否继续操作","提示信息", function(rtn) {
+				if(rtn){
+					var url=location.href.getNewUrl();
+					if(url.indexOf("?id=")!=-1){
+						window.location.href =  location.href.getNewUrl();
+					}
+					else{
+						var viewId=obj.getCause();
+						window.location.href =location.href +"&id=" +viewId;
+					}
+				}else{
+					var url="list.ht?sqlId=" +sqlId;
+					window.location.href =  url.getNewUrl();
+				}
+			});
+		} else {
+			$.ligerDialog.err("提示信息","保存视图失败!",obj.getMessage());
+		}
+	},
+	
+	$scope._validForm = function (){
+		var form=$('#dataRightsForm');
+		if(!form.valid()) return false;
+		//判断排序字段太多报错问题
+		if($scope.sortFields&&$scope.sortFields.length>3){
+			$.ligerDialog.error("排序字段不能设置超过3个,请检查!","提示信息");
+			$scope.tab.selectTabItem("sortSetting");
+			return false;
+		}
+		//判断管理字段
+		if(service.manageFieldValid($scope.manageFields)){
+			$.ligerDialog.error("功能按钮出现重复的类型,请检查!","提示信息");
+			$scope.tab.selectTabItem("manageSetting");
+			return false;
+		}
+		if($scope.dataRightsJson.templateAlias=="") {
+			$scope.tab.selectTabItem("baseSetting");
+			form.valid();
+			return false;	
+		}
+		return true;
+	}
+	//预览
+	$scope.preview = function (){
+		var alias = $scope.dataRightsJson.sqlAlias;
+		var view = $scope.dataRightsJson.alias;
+		
+
+		if($.isEmpty(alias)){
+			$.ligerDialog.error("请设置完信息保存后预览!","提示信息");
+			return ;
+		}
+		var url=__ctx+ "/platform/system/sysQueryView/"+alias+"/"+view+".ht";
+		url=url.getNewUrl();
+		$.openFullWindow(url);
+	}
+	//编辑模板
+	$scope.editTemplate = function (){
+		var id = $scope.dataRightsJson.id;
+		if($.isEmpty(id)){
+			$.ligerDialog.error("请设置完信息保存后编辑模板!","提示信息");
+			return ;
+		}
+		var url=__ctx+ "/platform/system/sysQueryView/editTemplate.ht?id="+id;
+		url=url.getNewUrl();
+		$.openFullWindow(url);
+	}
+	//添加菜单
+	$scope.addToResource = function () {
+		var alias = $scope.dataRightsJson.sqlAlias;
+		var url="/platform/system/sysQueryView/"+alias+"/"+$scope.dataRightsJson.alias+".ht";
+		AddResourceDialog({addUrl:url});
+	}
+	function setGroupText(){
+		var txt = "";
+		for(var i = 0 ; i < $scope.groupingView.length ; i++){
+			txt+=" {"+(i)+"} ";
+		}
+		for(var i = 0 ; i < $scope.groupingView.length ; i++){
+			if(!$scope.groupingView[i].txtChange)
+				$scope.groupingView[i].groupText = "<b> "+ $scope.groupingView[i].groupDesc +" : {0},数量{1} </b>"
+		}
+	}
+	$scope.selectFieldToGroup = function(field){
+		$scope.groupingView = $scope.groupingView || [];
+		if(!field.gchecked){
+			for(var i = 0 ; i < $scope.groupingView.length ; i++){
+				if($scope.groupingView[i].groupField == field.name){
+					$scope.groupingView.splice(i,1);
+					setGroupText();
+					return;
+				}
+			}
+			 return;
+		}
+		
+		for(var i = 0 ; i < $scope.groupingView.length ; i++){
+			if($scope.groupingView[i].groupField == field.name){
+				 return;
+			}
+		}
+		$scope.groupingView.push({
+			groupField:field.name,
+			groupDesc:field.fieldDesc,
+			groupColumnShow : 1,
+			groupSummary:1,
+			groupOrder : "asc"
+		})
+		setGroupText();
+	}
+}])
+.controller('sysQueryViewSortListCtrl',['$scope','BaseService','dataRightsService',function($scope,BaseService,dataRightsService){
+	$scope.sysQueryViewList=sysQueryViewList;
+	$scope.moveTr = dataRightsService.moveTr;
+	$scope.save = function(){
+		var params = {},list = [];
+		for ( var i = 0; i < $scope.sysQueryViewList.length; i++) {
+			list.push({
+				id:$scope.sysQueryViewList[i].id,
+				sn:i
+			})
+		}
+		params.list = JSON.stringify(list);
+		$.post(__ctx+"/platform/system/sysQueryView/saveSortList.ht", params,function(data){
+			if(data.success){
+				frameElement.dialog.get('sucCall')(frameElement.dialog);
+			}
+			else
+				$.ligerDialog.error("保存失败!","提示信息");
+        });
+		
+	}
+	$scope.close = function(){
+		frameElement.dialog.close();
+	}
+}])
+.controller('sysQueryViewExportsCtrl',['$scope','BaseService','dataRightsService',function($scope,BaseService,dataRightsService){
+	var params = frameElement.dialog.get('conf').param;
+	$scope.colModels = $.extend(true,[],params.colModel);
+	$scope.exports = {
+		type:1
+	};
+	$scope.selectAll = function(flag){
+		for ( var i = 0; i < $scope.colModels.length; i++) {
+			switch(flag){
+				case 1:
+					$scope.colModels[i].gchecked = true;
+				break;
+				case 2:
+					$scope.colModels[i].gchecked = !$scope.colModels[i].gchecked;
+					break;
+				case 3:
+					$scope.colModels[i].gchecked = false;
+					break;
+			}
+			
+		}
+	}
+	$scope.close = function(){
+		frameElement.dialog.close();
+	}
+	$scope.toExports = function(){
+		var exportNames = [];
+		for ( var i = 0; i < $scope.colModels.length; i++) {
+			if($scope.colModels[i].gchecked&&$scope.colModels[i].label)
+				exportNames.push($scope.colModels[i].name)
+		}
+		var param = {
+				viewId : params.viewId,
+				isAll:$scope.exports.type==1?1:0,
+				exportNames:exportNames.join(","),
+				orderSeq:params.sortorder,
+				sortField:params.sortname
+		};
+		param=$.extend({},param,frameElement.dialog.get('conf').searchParams);
+		
+		switch($scope.exports.type){
+			case 2:
+			case "2":
+				param.paseSize = params.rowNum;
+				param.page = params.page;
+				break;
+		}
+
+		var form = $('#form'); 
+		form.empty();
+		for(var key in param){
+			var input = $("<input type='hidden' name='"+key+"' value='"+param[key]+"'/>");
+			form.append(input);
+	    }
+		$.ligerDialog.waitting("正在导出,请稍等!");
+		form.submit();
+		
+		
+		/*window.setTimeout(function(){
+			frameElement.dialog.close();
+		},2000);*/
+	}
+	$scope.hasChecked = function(){
+		for ( var i = 0; i < $scope.colModels.length; i++) {
+			if($scope.colModels[i].gchecked) return true;
+		}
+	}
+	$scope.selectAll(1);
+	
+}])
+//过滤条件隐藏属性<filter-hidden></filter-hidden>
+.directive('filterHidden', function() {
+	return {
+		restrict : 'E',
+		replace : true,
+		template :  '<div class="hidden">'+
+						'<!-- 数字的判断 -->'+
+						'<span  id="judgeCon-1" class="judge-condition" >'+
+							'<select  name="judgeCondition" class="ht-input" style="width:80px;  height: 30px;" onchange="judgeConditionChange.apply(this)">'+
+								'<option value="1">等于</option>'+
+								'<option value="2">不等于</option>'+
+								'<option value="3">大于</option>'+
+								'<option value="4">大于等于</option>'+
+								'<option value="5">小于</option>'+
+								'<option value="6">小于等于</option>'+
+								'<option value="7">等于变量</option>'+
+								'<option value="8">不等于变量</option>'+
+							'</select>'+
+						'</span>'+
+						'<!-- 字符串的判断 -->'+
+						'<span  id="judgeCon-2"  class="judge-condition">'+
+							'<select name="judgeCondition" class="ht-input" style="width:80px;  height: 30px;" onchange="judgeConditionChange.apply(this)">'+
+								'<option value="1">等于</option>'+
+								'<option value="3">等于(忽略大小写)</option>'+
+								'<option value="2">不等于</option>'+
+								'<option value="4">like</option>'+
+								'<option value="5">like左</option>'+
+								'<option value="6">like右</option>'+
+								'<option value="7">等于变量</option>'+
+								'<option value="8">不等于变量</option>'+
+							'</select>'+
+						'</span>'+
+						'<!-- 字典的判断 -->'+
+						'<span  id="judgeCon-4"  class="judge-condition">'+
+							'<select name="judgeCondition" class="ht-input" style="width:80px;  height: 30px;">'+
+								'<option value="1">等于</option>'+
+								'<option value="2">不等于</option>'+
+							'</select>'+
+						'</span>'+
+						'<!-- 选择器的判断 -->'+
+						'<span  id="judgeCon-5"   class="judge-condition">'+
+							'<select  name="judgeCondition" onchange="judgeConditionChange.apply(this)" class="ht-input" style="width:80px;  height: 30px;">'+
+								'<option value="1">包含</option>'+
+								'<option value="2">不包含</option>'+
+								'<option value="3">等于变量</option>'+
+								'<option value="4">不等于变量</option>'+
+							'</select>'+
+						'</span>'+
+						'<!-- 默认类型-->'+
+						'<span id="normal-input" class="judge-value"  type="1">'+
+							'<input class="short-input ht-input" name="judgeValue" type="text" style="width:100px;margin-left: 5px;"/>'+
+						'</span>'+
+						'<!-- 日期类型 -->'+
+						'<span id="date-input" class="judge-value"  type="1">'+
+							'<input id="date-input" type="text" class="Wdate ht-input" style="width:180px;"/>'+
+						'</span>'+
+					''+
+						'<!-- 用户选择器 -->'+
+						'<div id="user-div">'+
+							'<span  class="judge-value" type="1">'+
+								'<input type="hidden" value="" />'+
+								'<input type="text" readonly="readonly" class="ht-input" style="width:130px;margin-left:5px;" />'+
+								'<a href="javascript:;" class="link users">选择</a>'+
+							'</span>'+
+						'</div>'+
+					''+
+						'<!-- 角色选择器 -->'+
+						'<div id="role-div">'+
+							'<span  class="judge-value"  type="1" >'+
+								'<input type="hidden" value="" />'+
+								'<input type="text" readonly="readonly" class="ht-input" style="width:130px;margin-left:5px;" />'+
+								'<a href="javascript:;" class="link roles">选择</a>'+
+							'</span>'+
+						'</div>'+
+						'<!-- 组织选择器 -->'+
+						'<div id="org-div">'+
+							'<span  class="judge-value"  type="1">'+
+								'<input type="hidden" value="">'+
+								'<input type="text" readonly="readonly" class="ht-input" style="width:130px;margin-left:5px;" />'+
+								'<a href="javascript:;" class="link orgs">选择</a>'+
+							'</span>'+
+						'</div>'+
+						'<!-- 岗位选择器 -->'+
+						'<div id="position-div">'+
+							'<span  class="judge-value"  type="1">'+
+								'<input type="hidden" value="">'+
+								'<input type="text" readonly="readonly" class="ht-input" style="width:130px;margin-left:5px;" />'+
+								'<a href="javascript:;" class="link positions">选择</a>'+
+							'</span>'+
+						'</div>'+
+						'<!--常用变量-->'+
+						'<span id="commonVar" class="judge-value"  type="2">'+
+							'<select class="ht-input" style="width:100px;height: 30px;margin-left: 5px;">'+
+								'<option value="{{co.alias}}" ng-repeat="co in commonVars">{{co.name}}[{{co.number?"数字":"字符串"}}]</option>'+
+							'</select>'+
+						'</span>'+
+						'<select id="flowVarsSelect" class="left margin-set ht-input" name="flowVars" onchange="flowVarChange.apply(this)" style="height: 30px; ">'+
+							'<option value="">--请选择--</option>'+
+							'<option value="{{f.fieldName}}" datefmt="{{f.dateFormat}}" ctltype="{{f.controlType}}"  ftype="{{f.dataType}}" ng-repeat="f in sysQueryMetaFields">{{f.fieldDesc}}</option>'+
+						'</select>'+
+					'</div>'
+	};
+})
+//过滤条件 , 嵌入式 <filter-include-setting></filter-include-setting>
+.directive('filterIncludeSetting', function() {
+	return {
+		restrict : 'E',
+		replace : true,
+		template :  '<table style="margin: auto;width:100%;margin-top: 1px;" class="table-detail" cellpadding="0" cellspacing="0" border="0">'+
+						'<thead>'+
+							'<tr style="height: 50px;">'+
+								'<td colspan="4">'+
+									'脚本类型:'+
+									'<select ng-model="filterFields.type" class="ht-input">'+
+										'<option value="1" >条件脚本</option>'+
+										'<option value="2" >SQL</option>'+
+										'<option value="3" >追加SQL</option>'+
+									'</select>'+
+								'</td>'+
+							'</tr>'+
+						'</thead>'+
+						'<tbody>'+
+							'<tr>'+
+								'<td colspan="4" >'+
+									'<fieldset style="margin: 5px 0px 5px 0px;" id="filterSetting" ng-show="filterFields.type==1" >'+
+										'<legend>'+
+											'<span>条件设置</span>'+
+										'</legend>'+
+										'<div class="table-top">'+
+											'<div class="table-top-right">'+
+												'<div class="toolBar" style="margin:0;">'+
+													'<div class="group">'+
+														'<a class="link add" onclick="addDiv(1)">添加条件</a>'+
+													'</div>'+
+													'<div class="l-bar-separator"></div>'+
+												
+													'<div class="group">'+
+														'<a class="link switchuser" onclick="assembleDiv()">组合规则</a>'+
+													'</div>'+
+													'<div class="l-bar-separator"></div>'+
+													'<div class="group">'+
+														'<a class="link switchuser" onclick="splitDiv()">拆分规则</a>'+
+													'</div>'+
+													'<div class="l-bar-separator"></div>'+
+													'<div class="group">'+
+														'<a class="link del" onclick="removeDiv()">删除</a>'+
+													'</div>'+
+												'</div>'+
+											'</div>'+
+										'</div>'+
+										'<div id="ruleDiv" style="border:2px solid #ccc;margin:5px 0 0 0;"></div>'+
+									'</fieldset>'+
+									'<fieldset style="margin: 5px 0px 5px 0px;" id="sqlSetting" ng-show="filterFields.type==2||filterFields.type==3" >'+
+										'<legend ng-show="filterFields.type==2" >'+
+											'<span>SQL设置</span>'+
+										'</legend>'+
+										'<legend ng-show="filterFields.type==3">'+
+											'<span>追加SQL过滤</span>'+
+										'</legend>'+
+										'<table  cellpadding="0" cellspacing="0" border="0" style="width: 100%;"  class="table-detail" >'+
+											'<tr>'+
+												'<td width="5%">'+
+													'<div id="sqlTip" ng-show="filterFields.type==2">'+
+														'<a href="javascript:;" class="tipinfo"></a>'+
+													'</div>'+
+													
+													'<div id="sqlTip2" ng-show="filterFields.type==3" >'+
+														'<a href="javascript:;" class="tipinfo"></a>'+
+													'</div>'+
+													
+													'<td width="10%">常用变量:</td>'+
+													'<td>'+
+														'<select id="varFieldSelect" class="ht-input" name="varFields" onchange="varsChange.apply(this)">'+
+															'<option value="">--请选择--</option>'+
+															'<optgroup class="main-table-item" label="sql字段" ></optgroup>'+
+																'<option class="field-item"  value="{{c.name}}" ng-repeat="c in conditionFields">{{c.name}}</option>'+
+															'<optgroup class="main-table-item" label="常用变量" ></optgroup>'+
+																'<option value="{{co.alias}}" ng-repeat="co in commonVars">{{co.name}}[{{co.number?"数字":"字符串"}}]</option>'+
+														'</select>'+
+													'</td>'+
+												'</td>'+
+											'</tr>'+
+											'<tr>'+
+												'<td colspan="7">'+
+													'<textarea  id="sql" ng-model="filterFields.sql" style="height: 300px;width:1000px;display:none !important;" class="ht-input  border-none margin-none "></textarea>'+
+												'</td>'+
+											'</tr>'+
+										'</table>'+
+									'</fieldset>'+
+								'</td>'+
+							'</tr>'+
+						'</tbody>'+
+					'</table>',
+					link:function(scope){
+					
+						scope.commonVars = commonVars;
+					}
+	};
+})

+ 42 - 0
web/js/angular/service/arrayToolService.js

@@ -0,0 +1,42 @@
+angular.module('arrayToolService', [])
+.service('ArrayToolService', [function() {
+    var service = {
+    		//上移按钮
+	    	up:function(idx,list){
+	    		if(idx<1){
+	    			return;
+	    		}
+	    		var t=list[idx-1];
+	    		list[idx-1]=list[idx];
+	    		list[idx]=t;
+	    	},
+	    	//下移按钮
+	    	down:function(idx,list){
+	    		if(idx>=list.length-1){
+	    			return;
+	    		}
+	    		var t=list[idx+1];
+	    		list[idx+1]=list[idx];
+	    		list[idx]=t;
+	    	},
+	    	//删除按钮
+	    	del:function(idx,list){
+	    		list.splice(idx,1);
+	    	},
+	    	//找到指定元素的未知
+	    	indexOf:function(val,list){
+	    		for (var i = 0; i < list.length; i++) {  
+	    	        if (list[i] == val) return i;  
+	    	    }  
+	    	    return -1; 
+	    	},
+	    	//删除指定元素
+	    	remove:function(val,list){
+	    		var index = list.indexOf(val);  
+	    	    if (index > -1) {  
+	    	    	list.splice(index, 1);  
+	    	    }  
+	    	}
+    }
+    return service;
+}]);

+ 279 - 0
web/js/angular/service/baseServices.js

@@ -0,0 +1,279 @@
+var baseServices = angular.module( "baseServices", [] );
+baseServices.factory("$jsonToFormData",function() {
+	function transformRequest( data, getHeaders ) {
+		var headers = getHeaders();
+		headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8";
+		return $.param(data);
+	}
+	return( transformRequest );
+})
+.directive('htCheckbox', function() {
+    return {
+        restrict: 'A',
+        link: function(scope, element, attrs) {
+            var key = attrs["htCheckbox"];
+            var getValAry = function(){
+                var val = getValByScope(element,key);
+                if(val){
+                	return val.split(",");
+                }
+                return [];
+            };
+            scope.$watch(key,function(newVal,oldVal){
+            	var ary = getValAry();
+                if(ary&&ary.length&&ary.join(",").indexOf(attrs["value"])!=-1){
+                    element[0].checked = true;
+                }
+            });
+            element.bind('change',function(){
+                var elementVal = element[0].checked,
+                    option = attrs["value"],
+                    array = getValAry();
+                if(elementVal){
+                    array.push(option);
+                }
+                else{
+                    array.remove(option);
+                }
+                setValToScope(element,array.join(','),null,key);
+            });
+        }
+    };
+})
+.directive('htDate', function() {
+    return {
+        restrict: 'A',
+        link: function(scope, element, attrs) {
+        	var ngModel = attrs.ngModel;
+        	switch(attrs.htDate){
+        		case "date":
+        			$(element).on("focus",function(){
+        				var me = $(this);
+        				WdatePicker({dateFmt:'yyyy-MM-dd',alwaysUseStartDate:true});
+        				me.blur();
+    				   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+        			});
+        		break;
+         		case "datetime":
+        			$(element).on("focus",function(){
+        				var me = $(this);
+        				WdatePicker({dateFmt:'yyyy-MM-dd',alwaysUseStartDate:true});
+        				me.blur();
+    				   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+    			});
+        		break;
+        		case "wdateTime":
+        			$(element).on("focus",function(){
+        				var me = $(this), dateFmt=  (me.attr('datefmt')?me.attr('datefmt'):'yyyy-MM-dd');
+            			WdatePicker({dateFmt:dateFmt,alwaysUseStartDate:true});
+            			me.blur();
+        			   scope.$apply(function(){
+                           eval("(scope." + ngModel + "='" + me.val() + "')");    
+                       });
+        			});
+        		break;
+        	}
+        }
+    };
+})
+
+.service('BaseService', ['$http','$jsonToFormData', function($http,$jsonToFormData) {
+    var service = {
+    		get:function(url,callback){
+    			$http.get(url).success(function(data,status){
+            		if(callback){
+            			callback(data,status);
+            		}
+        		})
+        		.error(function(data,status){
+        			if(callback){
+            			callback(data,status);
+        			}
+        			//TODO 根据返回的错误状态(status)显示对应的全局提示
+        		});
+    		},
+    		post:function(url,param,callback){
+    			$http.post(url,param,{transformRequest:$jsonToFormData})
+				 .success(function(data,status){
+					 if(callback){
+	    				callback(data,status);
+	    			 }
+				 })
+				 .error(function(data,status){
+					 if(callback){
+	    				callback(data,status);
+	    			 }
+					 //TODO 根据返回的错误状态(status)显示对应的全局提示
+				 });
+    		},
+    		//m内容,b:true->alert输出;false:console
+    		show:function(m,b){
+    			if(b==null||b==false){
+    				// console.info(m);
+    			}else{
+    				alert(m+"");
+    			}
+    		}
+        }
+    return service;
+}])
+.directive('chooseTarget', [function() { 
+	return {
+		restrict: 'EAC',
+		scope:{
+			right:'='
+		},
+		link: function(scope, element, attrs) {
+		
+			var opList = [{k:'',v:'请选择'}
+							,{k:'none',v:'无'}
+							,{k:'everyone',v:'所有人'}
+							,{k:'user',v:'用户'}
+							,{k:'role',v:'角色'}
+							,{k:'org',v:'组织'}
+							,{k:'orgMgr',v:'组织负责人'}
+							,{k:'pos',v:'岗位'}
+							,{k:'script',v:'脚本'}],
+				opStr = "",
+				opNo = attrs.opList?parseToJson(attrs.opList).no:"";
+				opNo = opNo?opNo.split(","):"";
+				
+			scope.getOpition = function(){
+				opStr= "";
+				for(var i = 0 ; i < opList.length ; i++){
+					if($.inArray(opList[i].k,opNo)==-1)
+						opStr +='<option value="'+opList[i].k+'">'+opList[i].v+'</option>';
+				}
+				return opStr;
+			};
+			scope.v = "v";
+			if(!scope.right) scope.right = {};
+			if(!scope.right.hasOwnProperty("v"))
+				scope.v = "type";
+			scope.handClick = function(){
+				// 选择回调
+				var callback = function(ids, names) {
+					scope.right.name =names;
+					scope.right.id = ids;
+					scope.$digest();
+				};
+				switch (scope.right[scope.v]) {
+					case "user" :
+						UserDialog({callback : callback});
+						break;
+					case "role" :
+						RoleDialog({callback : callback});
+						break;
+					case "org" :
+					case "orgMgr" :
+						OrgDialog({callback : callback});
+						break;
+					case "pos" :
+						PosDialog({callback : callback});
+						break;
+					case "script" :
+						ScriptDialog({
+							callback : function(script) {
+								scope.right.script =script;
+								scope.$digest();
+							}
+						});
+						break;
+				}
+			};
+			scope.resetRight = function(){
+				var v = scope.v,
+					val = scope.right[v];
+				scope.right = {};
+				scope.right[v] = val;
+			};
+			scope.remove = function(i){
+				var ids = scope.right.id.split(",");
+				var names = scope.right.name.split(",");
+				ids.splice(i,1);
+				names.splice(i,1);
+				scope.right.id = ids.join(",");
+				scope.right.name = names.join(",");
+			};
+		},
+		template: '<select  class="ht-input w-120"   ng-model="right[v]" ht-bind-html="getOpition()" validate="{required:true}" ng-change="resetRight()">'
+					+'</select>'
+					+'<span ng-hide="right[v]==\'script\'||right[v]==\'everyone\'||right[v]==\'none\'||!right[v]||right.name==\'\'"  class="ht-input" style="width: initial;max-width: 260px;">' 
+						+'<span class="owner-span" ng-repeat="item in right.name.split(\',\')">{{item}}'
+							+'<a class="flootbutton" title="移除该项" ng-click="remove($index)">x</a>'
+						+'</span>'
+					+'</span>'
+					+'<span class="bt-select" ng-click="handClick()" ng-show="right[v]&&right[v]!=\'none\'&&right[v]!=\'everyone\'">选择</span>'
+					+'<span ng-show="right[v]==\'script\'">'
+						+'<textarea  cols="40" rows="3" ng-model="right.script" class="ht-input" validate="{required:true}" ></textarea>'
+						+'<a  href="javascript:;" class="bt-select" ng-click="handClick()">常用脚本</a>'
+					+'</span>',
+        replace: false
+	};
+}])
+ // <dialog-buttons></dialog-buttons>
+ .directive('dialogButtons', function($compile) {
+	return {
+		restrict : 'E',
+		replace : true,
+		template : '<div class="hide-panel">'+
+						'<div class="panel-top">'+
+							'<div class="panel-toolbar">'+
+								'<div class="toolBar">'+
+									'<div class="group">'+
+										'<a class="link save" href="javascript:;" ng-click="save();">'+
+											'<span></span>'+
+											'保存'+
+										'</a>'+
+									'</div>'+
+									'<div class="group">'+
+										'<a class="link del" href="javascript:;" ng-click="close()">'+
+											'<span></span>'+
+											'关闭'+
+										'</a>'+
+									'</div>'+
+								'</div>'+
+							'</div>'+
+						'</div>'+
+					'</div>'
+	};
+})
+.directive('htBindHtml', function($compile) {
+	return {
+		restrict : 'A',
+		link : function(scope, elm, attrs) {
+			scope.unbindWatch = scope.$watch(attrs.htBindHtml, function(newVal, oldVal) {
+                if (!elm.data('unbindWatchTag')) {
+                    if(newVal){
+                        elm.data('unbindWatchTag',true);
+                        elm.html(newVal);
+                        scope.htmlFn&&scope.htmlFn.call();
+                        $compile(elm)(scope);
+                    }
+                    else{
+                        //避免重复添加监视
+                        elm.data('unbindWatchTag')&&scope.unbindWatch();
+                    }
+                }
+            });
+		}
+	};
+})
+.directive('onFinishRenderFilters', function ($timeout) {
+    return {
+        restrict: 'A',
+        link: function(scope, element, attr) {
+            if (scope.$last === true) {
+                $timeout(function() {
+                    scope.$emit('ngRepeatFinished');
+                });
+            }
+        }
+    };
+})
+;
+

+ 26 - 0
web/js/angular/service/commonListService.js

@@ -0,0 +1,26 @@
+angular.module('commonListService', [])
+.service('CommonListService', [function() {
+    var service = {
+        	yesOrNoList:yesOrNoList=[
+				{
+					key:'是',
+					value:true
+				},
+				{
+					key:"否",
+					value:false
+				}
+	      	],
+	      	yesOrNoList2:yesOrNoList=[
+   				{
+   					key:'是',
+   					value:1
+   				},
+   				{
+   					key:"否",
+   					value:0
+   				}
+   	      	]
+    }
+    return service;
+}]);

+ 115 - 0
web/js/angular/service/sysQueryFieldService.js

@@ -0,0 +1,115 @@
+ var sysQuerySqlFieldServiceApp = angular.module('sysQuerySqlFieldServiceApp', []);
+ sysQuerySqlFieldServiceApp.service('sysQuerySqlFieldService', ['$http', 'dataRightsService', function($http, dataRightsService) {
+ 	var service = {
+ 		initCtrlTypeSetting:function(scope){
+ 				this.scope = scope;
+ 				scope.dialog = frameElement.dialog;
+ 				var conf =scope.dialog.get('conf');
+ 				scope.sysQueryField = conf.field;
+ 				scope.globalTypes = conf.dicList;
+ 				scope.selectList = [];
+ 				scope.sysQueryField.ctrlCon = {};
+ 				if(scope.sysQueryField.controlType == 11){
+ 					scope.selectList = parseToJson(scope.sysQueryField.controlContent);
+ 				}else if(scope.sysQueryField.controlType == 3){
+ 					scope.sysQueryField.dicType = scope.sysQueryField.controlContent;
+ 				}else if(scope.sysQueryField.controlType == 12){
+ 					scope.sysQueryField.ctrlCon = parseToJson(scope.sysQueryField.controlContent);
+ 				}
+ 				var url = __ctx + '/platform/form/bpmFormDialog/getAllDialogs.ht';
+ 				$.ajax({
+ 				    type:"get",
+ 				    async:false,
+ 				    url:url,
+ 				    success:function(data){
+ 				    	for(var i = 0 ; i < data.length ; i++){
+ 				    		data[i].resultfield = parseToJson(data[i].resultfield);
+ 				    	}
+ 				    	scope.dialogList = data;
+ 				    	scope.currentDialog=scope.getCurrentDialog();
+ 				    	if(!scope.sysQueryField.ctrlCon.dialog){
+ 	 				    	scope.sysQueryField.ctrlCon.dialog = data[0].alias;
+ 	 				    	scope.sysQueryField.ctrlCon.resultField = data[0].resultfield[0].field;
+ 				    	}
+ 				    	scope.$$phase?"":scope.$digest();
+ 				    }
+ 				});
+ 		},
+ 		initVirtual:function(scope){
+ 			this.scope = scope;
+ 			scope.dialog = frameElement.dialog;
+ 			var conf =scope.dialog.get('conf');
+ 			scope.sysQueryField = conf.field;
+ 			scope.sysQueryFields = conf.sysQueryFields;
+				scope.globalTypes = conf.dicList;
+ 			scope.selectList = [];
+ 		},
+ 		initAlarm:function(scope){
+ 			this.scope = scope;
+ 			this.util = dataRightsService;
+ 			scope.dialog = frameElement.dialog;
+ 			var conf =scope.dialog.get('conf');
+ 			scope.sysQueryField = conf.field;
+ 			scope.alarmSetting = scope.sysQueryField.alarmSetting;
+ 			if(scope.alarmSetting){
+ 				if(typeof scope.alarmSetting =="string")
+ 					scope.alarmSetting = parseToJson(scope.sysQueryField.alarmSetting)
+ 			}else{
+ 				scope.alarmSetting = [{condition:[{op:">",val:""}],color:"red"}];
+ 			}
+ 		},
+		getVirtualFromType : function(type){
+			var list = {1:"数据字典",2:"sql",3:"下拉框"};
+			return list[type];
+		},
+ 		getCtrCon:function(ctrlType){
+ 			if(ctrlType == 3)
+ 				return this.scope.sysQueryField.dicType;
+ 			else if(ctrlType == 11)
+ 				return dataRightsService.listToString(this.scope.selectList);
+ 			else if(ctrlType == 12 )
+ 				return dataRightsService.listToString(this.scope.sysQueryField.ctrlCon);
+ 		}
+ 	};
+ 	return service;
+ }])
+//<select-table></select-table>
+ .directive('selectTable', function($compile) {
+	return {
+		restrict : 'E',
+		replace : true,
+		scope:{
+			list:"="
+		},
+		template : '<table style="width:100%;">'+
+					'<thead>'+
+						'<tr>'+
+							'<td colspan="4">'+
+								'<a href="javascript:;" class="link add" ng-click="list.push({})">添加</a>'+
+							'</td>'+
+						'</tr>'+
+					'</thead>'+
+					'<tbody>'+
+						'<tr ng-repeat="sl in list">'+
+							'<td>'+
+								'<div >'+
+									'<label>'+
+										'值:'+
+										'<input ng-model="sl.optionKey" type="text" style="height:21px;width:150px" class="ht-input"/>'+
+									'</label>'+
+									'<label style="margin:0 0 0 10px;">'+
+										'选项:'+
+										'<input ng-model="sl.optionValue" style="height:21px;width:150px" class="ht-input" type="text"/>'+
+									'</label>'+
+								'</div>'+
+							'</td>'+
+							'<td>'+
+								'<div >'+
+									'<tool-buttons type="4" list="list" index="{{$index}}" ></tool-buttons>'+
+								'</div>'+
+							'</td>'+
+						'</tr>'+
+					'</tbody>'+
+				'</table>'
+	};
+})

+ 664 - 0
web/js/angular/service/sysQueryViewFilterSetting.js

@@ -0,0 +1,664 @@
+var editor=null;
+
+function changeType(type){
+	if(type == 2){
+		$('#filterSetting').hide();
+		$('#sqlSetting').show();
+		editor.setValue("");
+	}else{
+		$('#filterSetting').show();
+		$('#sqlSetting').hide();
+	}
+}
+
+function  initType(type,condition){
+	$('#type').val(type);
+	changeType(type);
+	if(type == 2){
+		editor.setValue(condition);
+		condition = "";
+	}
+	return condition
+}
+
+function varsChange(){
+		var me = $(this),
+			val = me.val();
+		if($.isEmpty(val))
+			return;
+		me.val('');
+		editor.replaceSelection(val);
+}
+
+
+
+function fieldChange(){
+		var me = $(this),
+			selected=me.find("option:selected"),
+			source = selected.attr('source'),
+			val = me.val();
+		if($.isEmpty(val))
+			return;
+		val =  (source ==1?("F_"+val):val);
+		me.val('');
+		editor.replaceSelection(val);
+}
+
+function tableChange(){
+		var me = $(this),
+		selected=me.find("option:selected"),
+		source = selected.attr('source'),
+		val = me.val();
+		if($.isEmpty(val))
+			return;
+		val =  (source ==1?("W_"+val):val);
+		me.val('');
+		editor.replaceSelection(val);
+}
+
+/**
+ * 获得初始化数据
+ * @return {String}
+ */
+function getInitData(){
+	var data = $("#filterTxt").val().trim();
+	if(data=="") return '';
+	var json = eval("("+data+")");
+	if(json.length==0)return '';
+	return json;
+};
+
+
+/**
+ * 更新内容
+ * @param {} item
+ * @param {} data
+ */
+function updateContent(item,data){
+	var nobr = $('<div class="nobr" style="float:left;margin-right:-999em;"></div>'),
+		//字段克隆
+		flowVarsSelect = $("#flowVarsSelect").clone(true).removeAttr("id"),
+		
+		paramKey = $("#paramKey").clone(true).removeAttr("id"),
+		paramCondition = $("#paramCondition").clone(true).removeAttr("id"),
+		paramValue = $("#paramValue").clone(true).removeAttr("id"),
+		ruleType;
+	if(!data){
+		ruleType= "1";
+	}else{
+		ruleType = data.ruleType;
+	}
+	
+	//普通条件
+	if(ruleType=='1'){
+		labelSpan = $('<span class="label-span left"></span>').attr("ruleType",ruleType).text('普通条件');
+		nobr.append(labelSpan)
+			.append(flowVarsSelect)
+			.append($('<div class="judge left margin-set"></div>'));
+		$("div.nobr",item).remove();
+		item.append(nobr);
+		if(data){
+			flowVarsSelect.val(data.flowvarKey).trigger("change");
+			var judgeExp = $("div.judgeExp",item),
+				judgeExp2 = $("div.judgeExp2",item);
+			if(judgeExp){
+				setJudgeValue(judgeExp,data.judgeCon1,true);
+				setJudgeValue(judgeExp,data.judgeVal1,false);
+			}
+			if(judgeExp2){
+				setJudgeValue(judgeExp2,data.judgeCon2,true);
+				setJudgeValue(judgeExp2,data.judgeVal2,false);
+			}
+		}
+	}
+	//脚本规则
+	else if(ruleType=='2'){
+		labelSpan = $('<span class="label-span left"></span>').attr("ruleType",ruleType).text('脚本条件');
+		var judge = $('<div class="judge left margin-set"></div>').append($('<a name="script" href="###" onclick="editConditionScript(this)">脚本</a>'));
+		nobr.append(labelSpan).append(judge);
+		$("div.nobr",item).remove();
+		item.append(nobr);
+		if(data.script){
+			item.data("script",data.script);
+			item.data("tables",data.tables);
+		}else if(typeof data.script==='undefined'){
+			addConditionScript(item);
+		}
+	}
+	else {//组织属性、用户属性
+		if(ruleType=='3'){
+			labelSpan = $('<span class="label-span left"></span>').attr("ruleType",ruleType).text('用户属性');
+		}
+		else {
+			labelSpan = $('<span class="label-span left"></span>').attr("ruleType",ruleType).text('组织属性');
+		}
+		nobr.append(labelSpan).append(paramKey).append(paramCondition).append(paramValue);
+		$("div.nobr",item).remove();
+		item.append(nobr);
+		if(data) {
+			paramKey.val(data.paramKey);
+			paramCondition.val(data.paramCondition);
+			paramValue.val(data.paramValue);
+		}
+	}
+};
+
+/**
+ * rule生成json
+ * @params item
+ * @returns {Object}
+ */
+function rule2json(item){
+	var jobject = {},
+		ruleType = $("span.label-span",item).attr("ruleType");
+	
+	//普通规则
+	if(ruleType=="1"){
+		var	flowvarKey = $("select[name='flowVars']",item).val(),
+			objSel=$("select[name='flowVars']",item).find("option:selected"),
+			flowvarText = objSel.text(),
+			source = objSel.attr("source"),
+			table = objSel.attr("table"),
+			mainTable = objSel.attr("maintable"),
+			relation = objSel.attr("relation"),
+			judgeExp = $("div.judgeExp",item),
+			judgeExp2 = $("div.judgeExp2",item),
+			isHidden = objSel.attr("ishidden"),
+			conDesc = [];
+		//数据来源通过前面传入
+		jobject.source= source;
+		//数据表
+		jobject.table= table;
+		//主表
+		jobject.mainTable=	mainTable;
+		//外键
+		jobject.relation=	relation;
+		//是否隐藏
+		jobject.isHidden= isHidden;
+		
+		if(!judgeExp||judgeExp.length==0)return null;
+		conDesc.push(flowvarText);
+		var optType = judgeExp.attr("optType");
+		jobject.optType = optType;
+		jobject.flowvarKey = flowvarKey;
+
+		jobject.datefmt= judgeExp.attr("datefmt");
+	
+		
+		jobject.judgeCon1 = $("select[name='judgeCondition']",judgeExp).val();
+		conDesc.push($("select[name='judgeCondition']",judgeExp).find("option:selected").text());
+		jobject.judgeVal1 = getJudgeValue(judgeExp);
+		conDesc.push(getJudgeText(judgeExp));
+		if(judgeExp2&&judgeExp2.length>0){
+			jobject.judgeCon2 = $("select[name='judgeCondition']",judgeExp2).val();
+			conDesc.push('并且');
+			conDesc.push($("select[name='judgeCondition']",judgeExp2).find("option:selected").text());
+			jobject.judgeVal2 = getJudgeValue(judgeExp2);
+			conDesc.push(getJudgeText(judgeExp2));
+		}
+		jobject.conDesc = conDesc.join(' ');
+	}
+	//脚本规则
+	else if(ruleType=='2'){
+		var script = item.data("script"),
+			tables = item.data("tables");
+		jobject.script = script;
+		jobject.tables = tables;
+		jobject.conDesc = ' 脚本 ';
+	}
+	else{//ruleType=3:用户属性  ruleType=4:组织属性
+		var conDesc = [];
+		var	paramKey = $("select[name='paramKey']",item).val(),
+			dataType = $("select[name='paramKey']",item).find("option:selected").attr("title");
+		var	paramCondition = $("select[name='paramCondition']",item).val();
+		var paramValue = $("input[name='paramValue']",item).val();
+		jobject.paramKey = paramKey;
+		jobject.paramCondition = paramCondition;
+		jobject.paramValue = paramValue;
+		conDesc.push(paramKey);
+		conDesc.push(paramCondition);
+		conDesc.push(paramValue);
+		jobject.conDesc = conDesc.join(' ');
+		
+		jobject.expression = paramKey+paramCondition+paramValue;
+		jobject.dataType = dataType;
+	}
+	
+	jobject.ruleType = ruleType;
+	var compType = $("select.computing-select",item).val();
+	if(compType){
+		//运算类型 
+		jobject.compType = compType;
+	}
+	return jobject;
+};
+
+
+
+
+/**
+ * 设置判定值
+ * @param {} p
+ * @param {} val
+ * @param {} isJudgeCon
+ */
+function setJudgeValue(p,val,isJudgeCon){
+	if(!p)return;
+	if(!isJudgeCon){
+		p.find("input").each(function(){
+			var me = $(this),
+				value = me.val(),
+				type = me.attr("type");
+			if(type=="checkbox"||type=="radio"){
+				if(val.indexOf(value)>-1){
+					me.attr("checked","checked");
+				}
+			}
+			else{
+				if(/\&\&/.test(val)){
+					var vals = val.split(/\&\&/);
+					if(me.attr("type")=="hidden")					
+						me.val(vals[0]);
+					else
+						me.val(vals[1]);
+				}
+				else
+					me.val(val);
+			}
+		});
+	}
+	var sel= p.find("select");	
+	sel.each(function(){
+		var me = $(this),
+			name = me.attr("name");
+		if((name=="judgeCondition")==isJudgeCon){
+				me.val(val);
+		}
+	});
+	//处理变量问题
+	if(isJudgeCon){
+		sel.trigger("change");
+	}
+};
+
+
+/**
+ * 字段选择事件
+ */
+function flowVarChange(el){
+	var me = el||$(this),
+		nobr = me.parents("div.nobr"),
+		option = me.find("option:selected");
+	
+	if(!option.val())return;		
+	
+	var	optType = getFlowVarType(option),
+		datefmt = option.attr("datefmt"),
+		judgeCon = null;
+	var judgeDiv = $("div.judge",nobr).empty(),
+					//获取判定条件
+		judgeExp = getJudgeExp(optType,option);
+	
+	judgeDiv.append(judgeExp);
+	//数字或日期则为多个
+	if(optType==1||optType==3){
+		var judgeExp2 = judgeExp.clone(true).removeClass("judgeExp").addClass("judgeExp2");
+		judgeDiv.append(judgeExp2);
+	}
+};
+
+/**
+ * 判断条件的改变
+ */
+function judgeConditionChange(){
+	var me = $(this),
+		judgeConditionSpan =me.parent(),
+		judgeValueSpan =judgeConditionSpan.next(".judge-value"),
+		type =judgeValueSpan.attr("type"),
+		opttype =judgeConditionSpan.parent().attr("opttype"),
+		firstVal = 1,secendVal = 2,val = me.val();
+	switch(opttype){
+		case 1:
+		case "1":
+			if($.inArray(parseInt(val), [7,8])==-1){
+				judgeValueSpan.remove();
+				judgeConditionSpan.after($("#normal-input").clone());
+				return ;
+			}
+			break;
+		case 2:
+		case "2":
+			if($.inArray(parseInt(val), [7,8])==-1){
+				judgeValueSpan.remove();
+				judgeConditionSpan.after($("#normal-input").clone());
+				return ;
+			}
+			break;
+		case 5:
+		case "5":
+			break;
+		default :
+			return;
+		break;
+	}
+	if(val == firstVal || val == secendVal){
+		if(type == firstVal)
+			return ;
+		var option =	judgeConditionSpan.parent().parent().parent().find("option:selected");
+		var	optType = getFlowVarType(option);
+		var input = getInput(optType,option);
+		judgeValueSpan.remove();
+		judgeConditionSpan.parent().append(input);
+	}else{
+		if(type == secendVal)
+			return ;
+		var commonVar =$('#commonVar').clone(true).removeAttr("id");
+		judgeValueSpan.remove();
+		judgeConditionSpan.parent().append(commonVar);
+	}	
+}
+
+
+/**
+ * 获取字段类型类型识别码
+ *	1、 数字标识
+ *	2、字符串标识
+ *	3、 日期标识
+ *	4、数据字典标识
+ *  5、选择器标识
+ *
+ */
+function getFlowVarType(opt){
+		var value = opt.val(),
+			ctltype = opt.attr("ctltype"),
+			ftype = opt.attr("ftype");
+		
+		//首先判断控件类型
+		if(ctltype){
+			switch(ctltype.toString()){
+				//用户、角色、岗位、组织选择器
+				case "4":
+				case "5":
+				case "6":
+				case "7":
+				case "8":
+				case "17":
+				case "18":
+				case "19":
+					return 5;
+				//字典
+				case "3":
+				case "11":
+				case "13":
+				case "14":
+					return 4;
+				//日期
+				case "15":
+					return 3;
+			}
+		}		
+		//发起人
+		if(value=="startUser")
+			return 5;
+		if(ftype){
+			//根据变量类型识别
+			switch(ftype.toLowerCase()){
+				case "int":
+				case "number":
+					return 1;
+				case "varchar":
+				case "string":
+					return 2;
+				case "date":
+					return 3;
+			}
+		}
+		return 2;
+};
+
+/**
+ * 获取判定值表达式
+ * @param {} optType
+ * @param {} option
+ * @return {}
+ */
+function getJudgeExp(optType,option){
+	var	expDiv = $('<div class="judgeExp left"></div>'),
+		judgeCon = $("#judgeCon-"+optType).clone(true).removeAttr("id");
+	if(!judgeCon||judgeCon.length==0){
+		judgeCon = $("#judgeCon-1").clone(true).removeAttr("id");
+	}
+		var selVal = judgeCon.find('select').val();
+	expDiv.attr("optType",optType).append(judgeCon);
+	var	input = getInput(optType,option);
+	expDiv.append(input);
+	return expDiv;
+};
+
+/**
+ * 获取判定值表达式
+ * @param {} optType
+ * @param {} option
+ * @return {}
+ */
+function getInput(optType,option){
+	var input;
+	switch(optType){
+		case 1:
+		case 2:
+		case 4:
+			input = $("#normal-input").clone(true).removeAttr("id");
+			break;
+		case 3:
+			var datefmt = option.attr("datefmt");
+			if($.isEmpty(datefmt))
+				datefmt ='yyyy-MM-dd';
+			input = $("#date-input").clone(true).removeAttr("id").attr("datefmt",datefmt);
+			break;
+//		case 4:
+//			input = getDicControl(option);
+//			break;
+		case 5:
+			input = getSelector(option).children();
+			break;
+	}
+	
+	return input;
+	
+}
+
+/**
+ * 获取字典类型的 条件值 控件
+ * @param {} option
+ * @return {}
+ */
+function getDicControl(option){
+	var value = option.val(),
+		ctltype = option.attr("ctltype"),
+		chosenopt = option.attr("chosenopt"),
+		opts = eval("("+chosenopt+")"),
+		html = '',
+		data = [],
+		type = "";
+	var tempHtml = $("#dic-radio-checkbox").val();
+	//控件13或者14都为多选
+	if(ctltype.toString()=='13'||ctltype.toString()=='14')
+		type = "checkbox";
+	else{
+		tempHtml = $("#dic-select").val();
+	}
+	
+	for(var i=0,c;c=opts[i++];){
+		data.push({type:type,name:value,option:c.key,memo:c.value});
+	}
+	
+	html = easyTemplate(tempHtml,data).toString();
+	return $(html);
+};
+
+/**
+ * 获取不同类型的选择器
+ * @param {} option
+ * @return {}
+ */
+function getSelector(option){
+	var ctltype = option.attr("ctltype"),
+		value = option.val(),
+		str = "user-div";
+	switch(ctltype.toString()){
+		case "4"://用户单选
+		case "8"://用户多选
+			str = "user-div";
+			break;
+		case "5"://角色
+		case "17"://角色
+			str = "role-div";
+			break;
+		case "6"://组织
+		case "18"://组织
+			str = "org-div";
+			break;
+		case "7"://岗位
+		case "19"://岗位
+			str = "position-div";
+			break;
+	}
+	var control = $("#"+str).clone(true,true).removeAttr("id");
+ 	$("input[type='text']",control).attr("name",value);
+ 	$("input[type='hidden']",control).attr("name",value+"ID");
+ 	$("a.link",control).attr("name",value);
+	return control;
+};
+
+
+
+/**
+ * 获取判定值
+ * @param {} p
+ * @return 
+ */
+function getJudgeValue(p){
+	if(!p)return '';
+	var val = [];
+	p.find("input").each(function(){
+		var me = $(this),
+			type = me.attr("type");
+		if(type=="checkbox"||type=="radio"){
+			if(me.attr("checked"))
+				val.push(me.val());	
+		}
+		else
+			val.push(me.val());
+	});
+	p.find("select").each(function(){
+		var me = $(this),
+			name = me.attr("name");
+		if(name=="judgeCondition")return true;
+		val.push(me.val());
+	});
+	return val.join('&&');
+};
+
+/**
+ * 获取判定text
+ * @param {} p
+ * @return {String}
+ */
+function getJudgeText(p){
+	if(!p)return '';
+	var val = [];
+	p.find("input:visible").each(function(){
+		var me = $(this),
+			type = me.attr("type");
+		if(type=="checkbox"||type=="radio"){
+			if(me.attr("checked")){
+				val.push(me.parent().text());
+			}
+		}
+		else
+			val.push(me.val());
+	});
+	p.find("select").each(function(){
+		var me = $(this),
+			name = me.attr("name");
+		if(name=="judgeCondition")return true;
+		val.push(me.find("option:selected").text());
+	});
+	return val.join('&&');
+};
+
+/**
+ * 添加条件或脚本 
+ * @param {} ruleType 1、条件;2、脚本
+ */
+function addDiv(ruleType){
+	$("#ruleDiv").linkdiv("addDiv",{ruleType:ruleType});
+};
+
+/**
+ * 删除条件
+ */
+function removeDiv(){
+	$("#ruleDiv").linkdiv("removeDiv");	
+};
+
+/**
+ * 组合条件
+ */
+function assembleDiv(){
+	$("#ruleDiv").linkdiv("assembleDiv");
+};
+
+/**
+ * 拆分条件
+ */
+function splitDiv(){
+	$("#ruleDiv").linkdiv("splitDiv");
+};
+
+/**
+ * 获得数据
+ * @return {}
+ */
+function getData(){
+	return $("#ruleDiv").linkdiv("getData");
+};
+
+
+
+/**
+ * 保存
+ */
+function save(){
+	var condition = "",
+		name = $('#name'),
+		nameV=name.val(),
+		key = $('#key'),
+		keyV=key.val(),
+		type = $('#type').val(),
+		rtn={};
+	if(nameV == "" || keyV==""){
+		alert("请输入过滤名称或key!");
+		return;
+	}
+	if(type ==2){
+		editor.save();
+		condition = $('#sql').val();
+	}else{
+		condition = getData();
+	}
+	rtn.condition=condition;
+	rtn.name=nameV;
+	rtn.key =keyV;
+	rtn.type =type;
+	//window.returnValue= rtn;
+}
+
+
+function getPingyin(inputObj){
+	var input=$(inputObj).val();
+	if($.trim(input).length<1) return;
+	var py =Share.getPingyin({input:input});
+	if($.trim($('#key').val()).length>1) return;
+	$('#key').val(py);
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1414 - 0
web/js/bootstrap/bootstrap-dialog.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 7 - 0
web/js/bootstrap/bootstrap.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 8 - 0
web/js/bootstrap/fuelux.wizard.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 0
web/js/bootstrap/html5shiv.min.js


+ 366 - 0
web/js/bootstrap/jquery.easypiechart.min.js

@@ -0,0 +1,366 @@
+/**!
+ * easyPieChart
+ * Lightweight plugin to render simple, animated and retina optimized pie charts
+ *
+ * @license 
+ * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
+ * @version 2.1.6
+ **/
+
+(function(root, factory) {
+    if(typeof exports === 'object') {
+        module.exports = factory(require('jquery'));
+    }
+    else if(typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    }
+    else {
+        factory(root.jQuery);
+    }
+}(this, function($) {
+
+/**
+ * Renderer to render the chart on a canvas object
+ * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)
+ * @param {object}     options options object of the plugin
+ */
+var CanvasRenderer = function(el, options) {
+	var cachedBackground;
+	var canvas = document.createElement('canvas');
+
+	el.appendChild(canvas);
+
+	try {
+		if (typeof(G_vmlCanvasManager) !== 'undefined' ) {
+			G_vmlCanvasManager.initElement(canvas);
+		}
+	} catch (e) {
+		// TODO: handle exception
+	}
+
+	var ctx = canvas.getContext('2d');
+
+	canvas.width = canvas.height = options.size;
+
+	// canvas on retina devices
+	var scaleBy = 1;
+	if (window.devicePixelRatio > 1) {
+		scaleBy = window.devicePixelRatio;
+		canvas.style.width = canvas.style.height = [options.size, 'px'].join('');
+		canvas.width = canvas.height = options.size * scaleBy;
+		ctx.scale(scaleBy, scaleBy);
+	}
+
+	// move 0,0 coordinates to the center
+	ctx.translate(options.size / 2, options.size / 2);
+
+	// rotate canvas -90deg
+	ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);
+
+	var radius = (options.size - options.lineWidth) / 2;
+	if (options.scaleColor && options.scaleLength) {
+		radius -= options.scaleLength + 2; // 2 is the distance between scale and bar
+	}
+
+	// IE polyfill for Date
+	Date.now = Date.now || function() {
+		return +(new Date());
+	};
+
+	/**
+	 * Draw a circle around the center of the canvas
+	 * @param {strong} color     Valid CSS color string
+	 * @param {number} lineWidth Width of the line in px
+	 * @param {number} percent   Percentage to draw (float between -1 and 1)
+	 */
+	var drawCircle = function(color, lineWidth, percent) {
+		percent = Math.min(Math.max(-1, percent || 0), 1);
+		var isNegative = percent <= 0 ? true : false;
+
+		ctx.beginPath();
+		ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);
+
+		ctx.strokeStyle = color;
+		ctx.lineWidth = lineWidth;
+
+		ctx.stroke();
+	};
+
+	/**
+	 * Draw the scale of the chart
+	 */
+	var drawScale = function() {
+		var offset;
+		var length;
+
+		ctx.lineWidth = 1;
+		ctx.fillStyle = options.scaleColor;
+
+		ctx.save();
+		for (var i = 24; i > 0; --i) {
+			if (i % 6 === 0) {
+				length = options.scaleLength;
+				offset = 0;
+			} else {
+				length = options.scaleLength * 0.6;
+				offset = options.scaleLength - length;
+			}
+			ctx.fillRect(-options.size/2 + offset, 0, length, 1);
+			ctx.rotate(Math.PI / 12);
+		}
+		ctx.restore();
+	};
+
+	/**
+	 * Request animation frame wrapper with polyfill
+	 * @return {function} Request animation frame method or timeout fallback
+	 */
+	var reqAnimationFrame = (function() {
+		return  window.requestAnimationFrame ||
+				window.webkitRequestAnimationFrame ||
+				window.mozRequestAnimationFrame ||
+				function(callback) {
+					window.setTimeout(callback, 1000 / 60);
+				};
+	}());
+
+	/**
+	 * Draw the background of the plugin including the scale and the track
+	 */
+	var drawBackground = function() {
+		if(options.scaleColor) drawScale();
+		if(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);
+	};
+
+  /**
+    * Canvas accessor
+   */
+  this.getCanvas = function() {
+    return canvas;
+  };
+
+  /**
+    * Canvas 2D context 'ctx' accessor
+   */
+  this.getCtx = function() {
+    return ctx;
+  };
+
+	/**
+	 * Clear the complete canvas
+	 */
+	this.clear = function() {
+		ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);
+	};
+
+	/**
+	 * Draw the complete chart
+	 * @param {number} percent Percent shown by the chart between -100 and 100
+	 */
+	this.draw = function(percent) {
+		// do we need to render a background
+		if (!!options.scaleColor || !!options.trackColor) {
+			// getImageData and putImageData are supported
+			if (ctx.getImageData && ctx.putImageData) {
+				if (!cachedBackground) {
+					drawBackground();
+					cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);
+				} else {
+					ctx.putImageData(cachedBackground, 0, 0);
+				}
+			} else {
+				this.clear();
+				drawBackground();
+			}
+		} else {
+			this.clear();
+		}
+
+		ctx.lineCap = options.lineCap;
+
+		// if barcolor is a function execute it and pass the percent as a value
+		var color;
+		if (typeof(options.barColor) === 'function') {
+			color = options.barColor(percent);
+		} else {
+			color = options.barColor;
+		}
+
+		// draw bar
+		drawCircle(color, options.lineWidth, percent / 100);
+	}.bind(this);
+
+	/**
+	 * Animate from some percent to some other percentage
+	 * @param {number} from Starting percentage
+	 * @param {number} to   Final percentage
+	 */
+	this.animate = function(from, to) {
+		var startTime = Date.now();
+		options.onStart(from, to);
+		var animation = function() {
+			var process = Math.min(Date.now() - startTime, options.animate.duration);
+			var currentValue = options.easing(this, process, from, to - from, options.animate.duration);
+			this.draw(currentValue);
+			options.onStep(from, to, currentValue);
+			if (process >= options.animate.duration) {
+				options.onStop(from, to);
+			} else {
+				reqAnimationFrame(animation);
+			}
+		}.bind(this);
+
+		reqAnimationFrame(animation);
+	}.bind(this);
+};
+
+var EasyPieChart = function(el, opts) {
+	var defaultOptions = {
+		barColor: '#ef1e25',
+		trackColor: '#f9f9f9',
+		scaleColor: '#dfe0e0',
+		scaleLength: 5,
+		lineCap: 'round',
+		lineWidth: 3,
+		trackWidth: undefined,
+		size: 110,
+		rotate: 0,
+		animate: {
+			duration: 1000,
+			enabled: true
+		},
+		easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/
+			t = t / (d/2);
+			if (t < 1) {
+				return c / 2 * t * t + b;
+			}
+			return -c/2 * ((--t)*(t-2) - 1) + b;
+		},
+		onStart: function(from, to) {
+			return;
+		},
+		onStep: function(from, to, currentValue) {
+			return;
+		},
+		onStop: function(from, to) {
+			return;
+		}
+	};
+
+	// detect present renderer
+	if (typeof(CanvasRenderer) !== 'undefined') {
+		defaultOptions.renderer = CanvasRenderer;
+	} else if (typeof(SVGRenderer) !== 'undefined') {
+		defaultOptions.renderer = SVGRenderer;
+	} else {
+		throw new Error('Please load either the SVG- or the CanvasRenderer');
+	}
+
+	var options = {};
+	var currentValue = 0;
+
+	/**
+	 * Initialize the plugin by creating the options object and initialize rendering
+	 */
+	var init = function() {
+		this.el = el;
+		this.options = options;
+
+		// merge user options into default options
+		for (var i in defaultOptions) {
+			if (defaultOptions.hasOwnProperty(i)) {
+				options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];
+				if (typeof(options[i]) === 'function') {
+					options[i] = options[i].bind(this);
+				}
+			}
+		}
+
+		// check for jQuery easing
+		if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {
+			options.easing = jQuery.easing[options.easing];
+		} else {
+			options.easing = defaultOptions.easing;
+		}
+
+		// process earlier animate option to avoid bc breaks
+		if (typeof(options.animate) === 'number') {
+			options.animate = {
+				duration: options.animate,
+				enabled: true
+			};
+		}
+
+		if (typeof(options.animate) === 'boolean' && !options.animate) {
+			options.animate = {
+				duration: 1000,
+				enabled: options.animate
+			};
+		}
+
+		// create renderer
+		this.renderer = new options.renderer(el, options);
+
+		// initial draw
+		this.renderer.draw(currentValue);
+
+		// initial update
+		if (el.dataset && el.dataset.percent) {
+			this.update(parseFloat(el.dataset.percent));
+		} else if (el.getAttribute && el.getAttribute('data-percent')) {
+			this.update(parseFloat(el.getAttribute('data-percent')));
+		}
+		el.style['width'] = el.style['height'] = options.size + 'px';//ht 修改
+		el.style['lineHeight'] = (options.size - 1) + 'px';//ht 修改
+	}.bind(this);
+
+	/**
+	 * Update the value of the chart
+	 * @param  {number} newValue Number between 0 and 100
+	 * @return {object}          Instance of the plugin for method chaining
+	 */
+	this.update = function(newValue) {
+		newValue = parseFloat(newValue);
+		if (options.animate.enabled) {
+			this.renderer.animate(currentValue, newValue);
+		} else {
+			this.renderer.draw(newValue);
+		}
+		currentValue = newValue;
+		return this;
+	}.bind(this);
+
+	/**
+	 * Disable animation
+	 * @return {object} Instance of the plugin for method chaining
+	 */
+	this.disableAnimation = function() {
+		options.animate.enabled = false;
+		return this;
+	};
+
+	/**
+	 * Enable animation
+	 * @return {object} Instance of the plugin for method chaining
+	 */
+	this.enableAnimation = function() {
+		options.animate.enabled = true;
+		return this;
+	};
+
+	init();
+};
+
+$.fn.easyPieChart = function(options) {
+	return this.each(function() {
+		var instanceOptions;
+
+		if (!$.data(this, 'easyPieChart')) {
+			instanceOptions = $.extend({}, options, $(this).data());
+			$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));
+		}
+	});
+};
+
+
+}));

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 0
web/js/bootstrap/jquery.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 0
web/js/bootstrap/jquery.sparkline.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 0
web/js/bootstrap/jquery1x.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
web/js/bootstrap/respond.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 17 - 0
web/js/bootstrap/slider-layer-slider/greensock.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 13 - 0
web/js/bootstrap/slider-layer-slider/layerslider.kreaturamedia.jquery.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 13 - 0
web/js/bootstrap/slider-layer-slider/layerslider.transitions.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 113 - 0
web/js/calendar/My97DatePicker/WdatePicker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
web/js/calendar/My97DatePicker/calendar.js


+ 28 - 0
web/js/calendar/My97DatePicker/idea-WdatePicker-js.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="gbk"?>
+
+<myIdeas>
+	<myIdea	
+		id
+			="001" 
+		name
+			="日期控件用不了。" >
+		修改意见:
+			可以使用可替代的日期控件,等自己有空闲时间,找到解决的原因,再替换回来。
+		优先级别:
+			为了不影响现有的计划,需要考虑可替换的功能实现。
+		备注:
+			该修改属于可以用替代方法解决的问题,属于简单性问题。
+		修改状态:
+			已经修改。但未完成。
+	</myIdea>
+	<myIdea	
+		id
+			="002" 
+		name
+			="工具条有不必要的按钮显示" >
+		修改意见:
+			可以去掉不必要的显示项目。
+		优先级别:
+			在不影响计划的情况下,可以不做修改。
+	</myIdea>
+</myIdeas>

+ 14 - 0
web/js/calendar/My97DatePicker/lang/en_US.js

@@ -0,0 +1,14 @@
+var $lang={
+errAlertMsg: "Invalid date or the date out of range,redo or not?",
+aWeekStr: ["wk", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+aLongWeekStr:["wk","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
+aMonStr: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+aLongMonStr: ["January","February","March","April","May","June","July","August","September","October","November","December"],
+clearStr: "Clear",
+todayStr: "Today",
+okStr: "OK",
+updateStr: "OK",
+timeStr: "Time",
+quickStr: "Quick Selection",
+err_1: 'MinDate Cannot be bigger than MaxDate!'
+}

+ 14 - 0
web/js/calendar/My97DatePicker/lang/zh_CN.js

@@ -0,0 +1,14 @@
+var $lang={
+errAlertMsg: "\u4E0D\u5408\u6CD5\u7684\u65E5\u671F\u683C\u5F0F\u6216\u8005\u65E5\u671F\u8D85\u51FA\u9650\u5B9A\u8303\u56F4,\u9700\u8981\u64A4\u9500\u5417?",
+aWeekStr: ["\u5468","\u65E5","\u4E00","\u4E8C","\u4E09","\u56DB","\u4E94","\u516D"],
+aLongWeekStr:["\u5468","\u661F\u671F\u65E5","\u661F\u671F\u4E00","\u661F\u671F\u4E8C","\u661F\u671F\u4E09","\u661F\u671F\u56DB","\u661F\u671F\u4E94","\u661F\u671F\u516D"],
+aMonStr: ["\u4E00\u6708","\u4E8C\u6708","\u4E09\u6708","\u56DB\u6708","\u4E94\u6708","\u516D\u6708","\u4E03\u6708","\u516B\u6708","\u4E5D\u6708","\u5341\u6708","\u5341\u4E00","\u5341\u4E8C"],
+aLongMonStr: ["\u4E00\u6708","\u4E8C\u6708","\u4E09\u6708","\u56DB\u6708","\u4E94\u6708","\u516D\u6708","\u4E03\u6708","\u516B\u6708","\u4E5D\u6708","\u5341\u6708","\u5341\u4E00\u6708","\u5341\u4E8C\u6708"],
+clearStr: "\u6E05\u7A7A",
+todayStr: "\u4ECA\u5929",
+okStr: "\u786E\u5B9A",
+updateStr: "\u786E\u5B9A",
+timeStr: "\u65F6\u95F4",
+quickStr: "\u5FEB\u901F\u9009\u62E9", 
+err_1: '\u6700\u5C0F\u65E5\u671F\u4E0D\u80FD\u5927\u4E8E\u6700\u5927\u65E5\u671F!'
+}

+ 11 - 0
web/js/calendar/My97DatePicker/skin/WdatePicker.css

@@ -0,0 +1,11 @@
+.Wdate{
+/* 	border:#999 1px solid; */
+	height:20px;
+	background:#fff url(datePicker.gif) no-repeat right;
+	padding-right: 4px;
+}
+
+.WdateFmtErr{
+	font-weight:bold;
+	color:red;
+}

BIN
web/js/calendar/My97DatePicker/skin/datePicker.gif


BIN
web/js/calendar/My97DatePicker/skin/default/img.gif


BIN
web/js/calendar/My97DatePicker/skin/whyGreen/bg.jpg


BIN
web/js/calendar/My97DatePicker/skin/whyGreen/img.gif


+ 18 - 0
web/js/conf/orgUserConf.js

@@ -0,0 +1,18 @@
+//人员,组织,岗位选择器
+var orgUserConfJson = [
+    {type:"system",value:"all",title:"全部"},
+    {type:"system",value:"self",title:"本级和下级"},
+    {type:"system",value:"department",title:"部门"},
+	{type:"system",value:"up",title:"上级"},	
+	{type:"system",value:"grade",title:"集团"},
+	{type:"system",value:"company",title:"分公司"},	
+	{type:"script",value:"",title:"脚本"}
+];
+
+//节点配置
+var orgUserFlowJson = [
+    {type:"system",value:"all",title:"全部"},
+    {type:"system",value:"department",title:"部门"},
+	{type:"system",value:"company",title:"分公司"},
+	{type:"script",value:"",title:"脚本"}
+   ];

+ 4 - 0
web/js/dynamic.jsp

@@ -0,0 +1,4 @@
+<%@page pageEncoding="UTF-8" contentType="text/javascript; charset=UTF-8"%>
+//设置ContextPath	
+var __ctx='<%=request.getContextPath()%>';
+var __jsessionId='<%=session.getId() %>';

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/chord.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/eventRiver.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/force.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/gauge.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/line.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10 - 0
web/js/echarts/chart/map.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
web/js/echarts/chart/scatter.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 12 - 0
web/js/echarts/echarts.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 8 - 0
web/js/fullcalendar/fullcalendar.min.js


+ 184 - 0
web/js/fullcalendar/gcal.js

@@ -0,0 +1,184 @@
+/*!
+ * FullCalendar v2.3.1 Google Calendar Plugin
+ * Docs & License: http://fullcalendar.io/
+ * (c) 2015 Adam Shaw
+ */
+ 
+(function(factory) {
+	if (typeof define === 'function' && define.amd) {
+		define([ 'jquery' ], factory);
+	}
+	else if (typeof exports === 'object') { // Node/CommonJS
+		module.exports = factory(require('jquery'));
+	}
+	else {
+		factory(jQuery);
+	}
+})(function($) {
+
+
+var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
+var fc = $.fullCalendar;
+var applyAll = fc.applyAll;
+
+
+fc.sourceNormalizers.push(function(sourceOptions) {
+	var googleCalendarId = sourceOptions.googleCalendarId;
+	var url = sourceOptions.url;
+	var match;
+
+	// if the Google Calendar ID hasn't been explicitly defined
+	if (!googleCalendarId && url) {
+
+		// detect if the ID was specified as a single string.
+		// will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars.
+		if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
+			googleCalendarId = url;
+		}
+		// try to scrape it out of a V1 or V3 API feed URL
+		else if (
+			(match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||
+			(match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))
+		) {
+			googleCalendarId = decodeURIComponent(match[1]);
+		}
+
+		if (googleCalendarId) {
+			sourceOptions.googleCalendarId = googleCalendarId;
+		}
+	}
+
+
+	if (googleCalendarId) { // is this a Google Calendar?
+
+		// make each Google Calendar source uneditable by default
+		if (sourceOptions.editable == null) {
+			sourceOptions.editable = false;
+		}
+
+		// We want removeEventSource to work, but it won't know about the googleCalendarId primitive.
+		// Shoehorn it into the url, which will function as the unique primitive. Won't cause side effects.
+		// This hack is obsolete since 2.2.3, but keep it so this plugin file is compatible with old versions.
+		sourceOptions.url = googleCalendarId;
+	}
+});
+
+
+fc.sourceFetchers.push(function(sourceOptions, start, end, timezone) {
+	if (sourceOptions.googleCalendarId) {
+		return transformOptions(sourceOptions, start, end, timezone, this); // `this` is the calendar
+	}
+});
+
+
+function transformOptions(sourceOptions, start, end, timezone, calendar) {
+	var url = API_BASE + '/' + encodeURIComponent(sourceOptions.googleCalendarId) + '/events?callback=?'; // jsonp
+	var apiKey = sourceOptions.googleCalendarApiKey || calendar.options.googleCalendarApiKey;
+	var success = sourceOptions.success;
+	var data;
+	var timezoneArg; // populated when a specific timezone. escaped to Google's liking
+
+	function reportError(message, apiErrorObjs) {
+		var errorObjs = apiErrorObjs || [ { message: message } ]; // to be passed into error handlers
+		var consoleObj = window.console;
+		var consoleWarnFunc = consoleObj ? (consoleObj.warn || consoleObj.log) : null;
+
+		// call error handlers
+		(sourceOptions.googleCalendarError || $.noop).apply(calendar, errorObjs);
+		(calendar.options.googleCalendarError || $.noop).apply(calendar, errorObjs);
+
+		// print error to debug console
+		if (consoleWarnFunc) {
+			consoleWarnFunc.apply(consoleObj, [ message ].concat(apiErrorObjs || []));
+		}
+	}
+
+	if (!apiKey) {
+		reportError("Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/");
+		return {}; // an empty source to use instead. won't fetch anything.
+	}
+
+	// The API expects an ISO8601 datetime with a time and timezone part.
+	// Since the calendar's timezone offset isn't always known, request the date in UTC and pad it by a day on each
+	// side, guaranteeing we will receive all events in the desired range, albeit a superset.
+	// .utc() will set a zone and give it a 00:00:00 time.
+	if (!start.hasZone()) {
+		start = start.clone().utc().add(-1, 'day');
+	}
+	if (!end.hasZone()) {
+		end = end.clone().utc().add(1, 'day');
+	}
+
+	// when sending timezone names to Google, only accepts underscores, not spaces
+	if (timezone && timezone != 'local') {
+		timezoneArg = timezone.replace(' ', '_');
+	}
+
+	data = $.extend({}, sourceOptions.data || {}, {
+		key: apiKey,
+		timeMin: start.format(),
+		timeMax: end.format(),
+		timeZone: timezoneArg,
+		singleEvents: true,
+		maxResults: 9999
+	});
+
+	return $.extend({}, sourceOptions, {
+		googleCalendarId: null, // prevents source-normalizing from happening again
+		url: url,
+		data: data,
+		startParam: false, // `false` omits this parameter. we already included it above
+		endParam: false, // same
+		timezoneParam: false, // same
+		success: function(data) {
+			var events = [];
+			var successArgs;
+			var successRes;
+
+			if (data.error) {
+				reportError('Google Calendar API: ' + data.error.message, data.error.errors);
+			}
+			else if (data.items) {
+				$.each(data.items, function(i, entry) {
+					var url = entry.htmlLink;
+
+					// make the URLs for each event show times in the correct timezone
+					if (timezoneArg) {
+						url = injectQsComponent(url, 'ctz=' + timezoneArg);
+					}
+
+					events.push({
+						id: entry.id,
+						title: entry.summary,
+						start: entry.start.dateTime || entry.start.date, // try timed. will fall back to all-day
+						end: entry.end.dateTime || entry.end.date, // same
+						url: url,
+						location: entry.location,
+						description: entry.description
+					});
+				});
+
+				// call the success handler(s) and allow it to return a new events array
+				successArgs = [ events ].concat(Array.prototype.slice.call(arguments, 1)); // forward other jq args
+				successRes = applyAll(success, this, successArgs);
+				if ($.isArray(successRes)) {
+					return successRes;
+				}
+			}
+
+			return events;
+		}
+	});
+}
+
+
+// Injects a string like "arg=value" into the querystring of a URL
+function injectQsComponent(url, component) {
+	// inject it after the querystring but before the fragment
+	return url.replace(/(\?.*?)?(#|$)/, function(whole, qs, hash) {
+		return (qs ? qs + '&' : '?') + component + hash;
+	});
+}
+
+
+});

+ 121 - 0
web/js/im/JSONResult.java

@@ -0,0 +1,121 @@
+package com.hotent.im;
+
+/**
+ * @Description: 自定义响应数据结构
+ * 				这个类是提供给门户,ios,安卓,微信商城用的
+ * 				门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
+ * 				其他自行处理
+ * 				200:表示成功
+ * 				500:表示错误,错误信息在msg字段中
+ * 				501:bean验证错误,不管多少个错误都以map形式返回
+ * 				502:拦截器拦截到用户token出错
+ * 				555:异常抛出信息
+ */
+public class JSONResult {
+
+    /**
+     * 响应业务状态
+     */
+    private Integer status;
+
+    /**
+     * 响应消息
+     */
+    private String msg;
+
+    /**
+     * 响应中的数据
+     */
+    private Object data;
+
+    /**
+     * 不使用
+     */
+
+    private String ok;
+
+    public static JSONResult build(Integer status, String msg, Object data) {
+        return new JSONResult(status, msg, data);
+    }
+
+    public static JSONResult ok(Object data) {
+        return new JSONResult(data);
+    }
+
+    public static JSONResult ok() {
+        return new JSONResult(null);
+    }
+    
+    public static JSONResult errorMsg(String msg) {
+        return new JSONResult(500, msg, null);
+    }
+    
+    public static JSONResult errorMap(Object data) {
+        return new JSONResult(501, "error", data);
+    }
+    
+    public static JSONResult errorTokenMsg(String msg) {
+        return new JSONResult(502, msg, null);
+    }
+    
+    public static JSONResult errorException(String msg) {
+        return new JSONResult(555, msg, null);
+    }
+
+    public JSONResult() {
+
+    }
+
+//    public static LeeJSONResult build(Integer status, String msg) {
+//        return new LeeJSONResult(status, msg, null);
+//    }
+
+    public JSONResult(Integer status, String msg, Object data) {
+        this.status = status;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public JSONResult(Object data) {
+        this.status = 200;
+        this.msg = "OK";
+        this.data = data;
+    }
+
+    public Boolean isOK() {
+        return this.status == 200;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+	public String getOk() {
+		return ok;
+	}
+
+	public void setOk(String ok) {
+		this.ok = ok;
+	}
+
+}

+ 97 - 0
web/js/im/controller/ImController.java

@@ -0,0 +1,97 @@
+package com.hotent.im.controller;
+
+import com.fr.report.core.A.E;
+import com.hotent.core.util.JSONUtil;
+import com.hotent.core.web.ResultMessage;
+import com.hotent.core.web.util.RequestUtil;
+import com.hotent.im.encrypt.Encrypt;
+import com.hotent.im.network.AbstractHttpPost;
+import com.hotent.im.network.Response;
+import com.hotent.mobile.controller.base.BaseMobileController;
+import com.hotent.platform.controller.system.JSONResult;
+import net.sf.json.JSONObject;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+/******************************
+ * Created by yanhongliang
+ * 2019-05-16 11:12
+ ******************************/
+
+@Controller
+@RequestMapping("/im/imController/")
+public class ImController extends BaseMobileController {
+
+    @RequestMapping("getNoreadMsgByUserName")
+    public void getNoreadMsgByUserName(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        System.out.println("-----------im_login--------1");
+
+        Map<String, Object> result = new HashMap<>();
+        try {
+            String fh_url = RequestUtil.getString(request,"fh_url");
+            String username = RequestUtil.getString(request,"username");
+
+            AbstractHttpPost post = new AbstractHttpPost() {
+                @Override
+                public void complete(Response response) {
+
+                    if (response.state != 200) {
+                        result.put("message", "网络错误!");
+                        return;
+                    }
+
+                    result.put("message", response.content);
+
+                    System.out.println("-----------im_login--------2");
+                    System.out.println(response.content);
+                }
+            };
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("USERNAME", username);
+            post.post(fh_url + "/appiminterface/getNoreadMsgByUserName", map, null);
+
+            writeResultMessage(response.getWriter(), JSONObject.fromObject(result).toString(), ResultMessage.Success);
+        }catch (Exception e) {
+            e.printStackTrace();
+            writeResultMessage(response.getWriter(),"系统错误:"+e.getMessage(), ResultMessage.Fail);
+        }
+
+    }
+
+    @RequestMapping("encrypt")
+    public void encrypt(HttpServletRequest request,HttpServletResponse response) throws IOException {
+
+        try {
+            String username = RequestUtil.getString(request,"username");
+
+            String privateKey = "privateKey";
+
+            Encrypt encrypt = new Encrypt();
+
+            String data = encrypt.encodeJSON(username, privateKey);
+
+            System.out.println("------加密------"+data);
+            System.out.println("===============================");
+            System.out.println("------解密------"+encrypt.decodeJSON(data, privateKey));
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("data", data);
+            map.put("key", privateKey);
+
+            writeResultMessage(response.getWriter(),URLEncoder.encode(JSONObject.fromObject(map).toString(), "utf8"), ResultMessage.Success);
+        }catch (Exception e) {
+            writeResultMessage(response.getWriter(),"系统错误:"+e.getMessage(), ResultMessage.Fail);
+        }
+
+    }
+
+
+}

+ 27 - 0
web/js/im/encrypt/EMain.java

@@ -0,0 +1,27 @@
+package com.hotent.im.encrypt;
+
+/******************************
+ * Created by yanhongliang
+ * 2019-06-04 11:00
+ ******************************/
+
+public class EMain {
+
+    public static void  main(String[] args) {
+
+//        String privateKey = "privateKey";
+//
+//        Encrypt encrypt = new Encrypt();
+//
+//        String str = "yhliang";
+//
+//        String encodeJSON = encrypt.encodeJSON(str, privateKey);
+//
+//        System.out.println("------加密------"+encodeJSON);
+//        System.out.println("===============================");
+//        System.out.println("------解密------"+encrypt.decodeJSON(encodeJSON, privateKey));
+
+    }
+
+
+}

+ 243 - 0
web/js/im/encrypt/Encrypt.java

@@ -0,0 +1,243 @@
+package com.hotent.im.encrypt;
+
+public class Encrypt {
+	
+	private final int _randomKeyLength;
+    private final String _publicKey;
+
+
+    /**
+     * 随机秘钥长度
+     */
+    private String _RANDOMKEYLENGTH = "16";
+
+    /**
+     * 公有秘钥
+     */
+    private String _PUBLICKEY = "112233";
+
+
+	public Encrypt()
+     {
+		 String randomKeyLength = _RANDOMKEYLENGTH;
+		 String publicKey = _PUBLICKEY;
+		 
+         _publicKey = publicKey;
+         System.out.println("_publicKey>>==--"+_publicKey);
+         
+         if("".equals(randomKeyLength)){
+        	 _randomKeyLength = 32;
+         }else{
+        	 _randomKeyLength = Integer.parseInt(randomKeyLength);
+         }
+     }
+	
+	// 加密 JSON
+	public String encodeJSON(String encodeJSON,String privateKey){
+		
+		//获取随机秘钥
+		String randomKeyChars  = getRandomKey(_randomKeyLength);
+		String publicKeyChars  = bufferWithString(_publicKey);
+		String privateKeyChars = bufferWithString(privateKey);
+		StringBuilder contentChars = new StringBuilder(bufferWithString(encodeJSON));
+
+		// 第一步先用随机密钥 从前往后 编码
+		int keyIndex = 0;
+		for(int i = 0;i<contentChars.length();i++){
+			
+			int c = contentChars.charAt(i);
+			char randomChar = randomKeyChars.charAt(keyIndex);
+			 // 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= randomKeyChars.length())
+                keyIndex = 0;
+
+            c += randomChar - 32;
+            c = c > 126 ? c - 94 : c;
+            contentChars.setCharAt(i, (char)c);
+		}
+		
+		// 第二步先用随机密钥 从后往前 编码
+		keyIndex = 0;
+	    for (int i  = contentChars.length() - 1; i >= 0; i--) {
+	    	int c = contentChars.charAt(i);
+			char randomChar = randomKeyChars.charAt(keyIndex);
+			// 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= randomKeyChars.length())
+                keyIndex = 0;
+            
+	        c += randomChar - 32;
+	        c = c > 126 ? c - 94 : c;
+            contentChars.setCharAt(i, (char)c);
+	    }
+		
+		 // 将随机密钥附加到内容顶部
+	     contentChars.insert(0, randomKeyChars);
+	    
+	     // 在顶部附加随机密钥长度
+        for (int i = 0; i < 32; i += 4) {
+            int num = (_randomKeyLength >> i) & 0xF;
+            char numChar = (char)(num + (num > 9 ? 55 : 48));
+            contentChars.insert(0, numChar);
+        }
+		
+        // 第三步再用私有密钥 从后往前 编码
+        keyIndex = 0;
+        for (int i = contentChars.length() - 1; i >=0 ; i--)
+        {
+            int c = contentChars.charAt(i);
+			char privateChar = privateKeyChars.charAt(keyIndex);
+
+            if (++keyIndex >= privateKeyChars.length())
+                keyIndex = 0;
+
+            c += privateChar - 32;
+            c = c > 126 ? c - 94 : c;
+            contentChars.setCharAt(i, (char)c);
+        }
+        
+     // 第四步最后用公有密钥 从前往后 编码
+        keyIndex = 0;
+        for (int i = 0; i < contentChars.length(); i++)
+        {
+        	
+            int c = contentChars.charAt(i);
+			char publicChar = publicKeyChars.charAt(keyIndex);
+
+            // 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= publicKeyChars.length())
+                keyIndex = 0;
+
+            c += publicChar - 32;
+            c = c > 126 ? c - 94 : c;
+            contentChars.setCharAt(i, (char)c);
+        }
+        
+		return contentChars.toString();
+	}
+	
+	 // 解密 JSON
+	public String decodeJSON(String targetJson,String privateKey){
+		
+		String publicKeyChars  = bufferWithString(_publicKey);			//共有秘钥
+		String privateKeyChars  = bufferWithString(privateKey);		//共有秘钥
+		StringBuilder contentChars = new StringBuilder(bufferWithString(targetJson));
+		
+		
+		// 解密共有密钥 从前往后 减编码
+        int keyIndex = 0;
+        for (int i = 0;i<contentChars.length();i++)
+        {
+        	
+    	    int t = contentChars.charAt(i);
+  			char publicChar = publicKeyChars.charAt(keyIndex);
+
+            if (++keyIndex >= publicKeyChars.length())
+                keyIndex = 0;
+
+            t -= publicChar - 32;
+            t = t < 32 ? t + 94 : t;
+            contentChars.setCharAt(i, (char)t);
+        }
+        // 解密私有密钥 从后往前 减编码
+        keyIndex = 0;
+        for (int i = contentChars.length()-1; i >= 0; i--) {
+        	
+    	    int t = contentChars.charAt(i);
+   			char privateChar = privateKeyChars.charAt(keyIndex);
+   			
+            // 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= privateKeyChars.length()) { 
+            		keyIndex = 0;
+            	}
+            t -= privateChar - 32;
+            t = t < 32 ? t + 94 : t;
+            contentChars.setCharAt(i, (char)(t & 0x7F));
+        }
+		
+        // 解密随机密钥
+        int length = 0;
+        for (int i = 0; i < 8; i++) {
+    		int t = contentChars.charAt(i) - 48;
+            t = t < 10 ? t : t - 7;
+            length += t << (28 - i * 4);
+        }
+        
+        System.out.println("====+++++"+contentChars);
+        System.out.println(length);
+        
+        StringBuffer randomKeyChars = new StringBuffer(contentChars.substring(8, length+8));
+        
+        contentChars.delete(0, length+8);
+        
+        // 第三步先用随机密钥 从后往前 减编码
+        keyIndex = 0;
+        for (int i  = contentChars.length() - 1; i >= 0; i--) {
+        	
+        	int c = contentChars.charAt(i);
+   			char randomChar = randomKeyChars.charAt(keyIndex);
+        	
+            
+            // 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= randomKeyChars.length()) {
+        		keyIndex = 0; 
+			}
+            c -= randomChar - 32;
+            c = c < 32 ? c + 94 : c;
+            contentChars.setCharAt(i, (char)(c & 0x7F));
+        }
+        
+     // 第四步再用随机密钥 从前往后 减编码
+        keyIndex = 0;
+        for (int i = 0; i < contentChars.length(); i++) {
+        	int c = contentChars.charAt(i);
+   			char randomChar = randomKeyChars.charAt(keyIndex);
+        	
+            
+            // 如果密钥循环一遍后 从0开始重新循环
+            if (++keyIndex >= randomKeyChars.length()) {
+        		keyIndex = 0; 
+			}
+            c -= randomChar - 32;
+            c = c < 32 ? c + 94 : c;
+            contentChars.setCharAt(i, (char)(c & 0x7F));
+        }
+		return contentChars.toString();
+	}
+	
+	//- 给中文 编码
+   public static String bufferWithString(String string){
+       
+	   StringBuffer buffer = new StringBuffer();
+	   for(int i = 0;i<string.length();i++){
+			int chr = string.codePointAt(i);
+			char chr1 = string.charAt(i);
+			
+			if (chr > 127) {
+				buffer.append("\\u");           // 代表\
+                // 2字节 16位 (1字节8位)  转16进制后为4字节字符串
+                // 0xA5F8  A5F8
+                // char >> 0   15
+                
+                for (int j = 0; j < 16; j+=4) {
+                    int k = chr >> (12 - j);
+                    int c = (k & 0xF);
+                    buffer.append(Integer.toHexString(c).toUpperCase());
+                }
+                
+			} else {
+				buffer.append(chr1);
+			}
+		}
+	   
+	   return buffer.toString();
+    }
+   
+   // 生成随机数
+	public static String getRandomKey(int length){
+		StringBuffer strb = new StringBuffer();
+		for(int i=0;i<length;i++ ) {	
+			strb.append((int)(10*(Math.random())));
+		}
+		return strb.toString();
+	}
+}

+ 92 - 0
web/js/im/network/HttpQueue.java

@@ -0,0 +1,92 @@
+package com.hotent.im.network;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by yanhongliang on 16/4/25.
+ */
+public class HttpQueue {
+
+    public interface OnComplete {
+        void onComplete(Response response);
+    }
+
+    /**
+     * 获取队列中,当前网络请求数量
+     * @return 返回当前网络请求数量
+     */
+    public static int getCount() {
+        return datas.size();
+    }
+
+    /**
+     * 清空队列
+     */
+    public static void clean() {
+        if (request != null) {
+            request.cancel();
+            datas.clear();
+            request = null;
+        }
+    }
+    private static ArrayList<Data> datas;
+    private static AbstractHttpPost request;
+    static {
+        datas = new ArrayList<>();
+    }
+
+    public static void addRequest(
+            String actionUrl,
+            Map<String, Object> params,
+            HashMap<String, MultipartFile> files,
+            OnComplete onComplete) {
+
+        datas.add(new Data(actionUrl, params,files, onComplete));
+
+        send();
+    }
+
+    private static void send() {
+        if (datas.size() == 0) {
+            return;
+        }
+        if (request != null) {
+            return;
+        }
+        final Data data = datas.remove(0);
+        request = new AbstractHttpPost() {
+            @Override
+            public void complete(Response response) {
+                data.onComplete.onComplete(response);
+                request = null;
+                send();
+            }
+        };
+
+        request.post(data.actionUrl, data.params, data.files);
+
+    }
+
+    private static class Data {
+        String actionUrl;
+        Map<String, Object> params;
+        HashMap<String, MultipartFile> files;
+        OnComplete onComplete;
+
+        Data(String url, Map<String, Object> params, HashMap<String, MultipartFile> files, OnComplete onComplete) {
+            this.actionUrl = url;
+            this.params = params;
+            this.files = files;
+            this.onComplete = onComplete;
+        }
+
+    }
+}
+
+

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 0
web/js/jiejiari/jquery-1.8.3.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10932 - 0
web/js/jiejiari/jquery.easyui.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1050 - 0
web/js/jiejiari/jquery.fullcalendar.js


BIN
web/js/jqueryMedia/mediaplayer.swf


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 0
web/js/kinggrid_h5/dialog-min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 0
web/js/kinggrid_h5/jquery-1.8.3.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2752 - 0
web/js/kinggrid_h5/jsQR.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 30 - 0
web/js/kinggrid_h5/kinggrid.plus.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 8 - 0
web/js/kinggrid_h5/password.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 34 - 0
web/js/kinggrid_h5/qrcode.min.js


+ 176 - 0
web/js/kinggrid_h5/search.js

@@ -0,0 +1,176 @@
+var ipt;
+var ser;
+var bot;
+var oul;
+var callback = null;
+
+var sealsData;
+var seals = {};
+
+/* 取li */
+var lis = document.getElementsByTagName("li");
+
+function setSeals(sealsData) {
+	this.sealsData = sealsData;
+	this.seals = sealsData.seals;
+}
+
+function deepCopy(source) {
+	var result = {};
+	for ( var key in source) {
+		result[key] = typeof source[key] === 'object' ? deepCopy(source[key])
+				: source[key];
+	}
+	return result;
+}
+
+function getSeal() {
+	var keyData = deepCopy(sealsData);
+	var seal = [];
+	if (ipt !== null && ipt.value != null) {
+		var j = 0;
+		for ( var i in seals) {
+			if (ipt.value == seals[i].signname) {
+				seal[j] = seals[i];
+				j++;
+			}
+		}
+	}
+
+	keyData.seals = seal;
+	return keyData;
+}
+
+function bindDOM(iptid, serid, botid, oulid, cb) {
+	ipt = document.getElementById(iptid);
+	ser = document.getElementById(serid);
+	bot = document.getElementById(botid);
+	oul = document.getElementById(oulid);
+	callback = cb;
+	callback(sealsData);
+
+	ipt.oninput = function() {
+		var ss = ipt.value;
+		addScript();
+		var data = [];
+		if (callback !== undefined && callback !== null  && sealsData !== undefined
+				&& sealsData !== null && sealsData.seals !== undefined && sealsData.seals !== null) {
+			var signseals = sealsData.seals;
+			for (var i = 0, j = 0; i < signseals.length; ++i) {
+				if (ss == "") {
+					data[j] = signseals[i].signname;
+					seals[signseals[i].signname] = signseals[i];
+					j++;
+				} else if (signseals[i].signname.match(ss)) {
+					data[j] = signseals[i].signname;
+					seals[signseals[i].signname] = signseals[i];
+					j++;
+				}
+			}
+		}
+		queryList(data);
+	}
+
+	ipt.onfocus = function() {
+		var ss = ipt.value;
+		addScript();
+		var data = [];
+		if (callback !== undefined && callback !== null && sealsData !== undefined
+				&& sealsData !== null && sealsData.seals !== undefined && sealsData.seals !== null) {
+			var signseals = sealsData.seals;
+			for (var i = 0, j = 0; i < signseals.length; ++i) {
+				if (ss == "") {
+					data[j] = signseals[i].signname;
+					j++;
+				} else if (signseals[i].signname.match(ss)) {
+					data[j] = signseals[i].signname;
+					j++;
+				}
+			}
+		}
+		queryList(data);
+
+	}
+}
+
+function queryList(data) {
+	ss = document.getElementsByTagName("script_search")[0];
+	document.body.removeChild(ss)
+
+	var arr = data;
+	oul.innerHTML = "";
+	if (arr.length == 0) {
+		bot.style.display = "none";
+	} else {
+		bot.style.display = "block";
+	}
+
+	for (var i = 0; i < arr.length; i++) {
+		var li = document.createElement("li");
+		li.innerHTML = arr[i];
+		li.onclick = function() {
+			ipt.value = this.innerHTML;
+			oul.innerHTML = "";
+			bot.style.display = "none";
+		}
+		oul.appendChild(li);
+	}
+}
+
+function addScript() {
+	var s = document.createElement("script_search");
+	document.body.appendChild(s);
+}
+
+/* 按键 */
+var i = 0;
+
+document.onkeydown = function(ev) {
+
+	if (bot.style.display == "block") {
+        var kcode = window.event.keyCode || ev.keyCode;
+		if (kcode == 40) {
+			for (var j = 0; j < lis.length; j++) {
+				if (lis[j].className == "sel") {
+					lis[j].className = "";
+				}
+			}
+
+			if (i < lis.length) {
+				lis[i].className = "sel";
+				i++;
+				if (i == lis.length) {
+					i = 0;
+				}
+			}
+		}
+
+		if (kcode == 38) {
+			m = 0
+			for (; m < lis.length; m++) {
+				if (lis[m].className == "sel") {
+					lis[m].className = "";
+					break;
+				}
+			}
+			i = m;
+			if (m > 0) {
+				lis[m - 1].className = "sel";
+			} else {
+				lis[lis.length - 1].className = "sel";
+			}
+		}
+
+		if (kcode == 13) {
+			for (var n = 0; n < lis.length; n++) {
+				if (lis[n].className == "sel") {
+					ipt.value = lis[n].innerHTML;
+				}
+			}
+			bot.style.display = "none";
+		}
+	} else {
+		i = 0;
+		m = 0;
+	}
+}

+ 32 - 0
web/js/msg.jsp

@@ -0,0 +1,32 @@
+<%@page language="java" pageEncoding="UTF-8"%>
+<%@page import="com.hotent.core.web.controller.BaseController"%>
+<%@page import="com.hotent.core.web.ResultMessage"%>
+
+<%
+ResultMessage _obj_=(ResultMessage)session.getAttribute(BaseController.Message);
+if(_obj_!=null){
+	session.removeAttribute(BaseController.Message);
+%>
+<script type="text/javascript">
+$(function(){
+	<%
+	  if(_obj_.getResult()==ResultMessage.Success){
+	%>
+		$.ligerDialog.success('<p><font color="green"><%=_obj_.getMessage()%></font></p>');
+	
+	<%}
+	  else{
+		if(!"".equals(_obj_.getCause())){
+	%>
+		$.ligerDialog.err('','<%=_obj_.getMessage()%>','<%=_obj_.getCause()%>');
+		<%}else{%>
+		$.ligerDialog.warn('<p><font color="red"><%=_obj_.getMessage()%></font></p>');
+	<%   }
+	   }%>
+});
+</script>
+<%
+} %>
+
+
+

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1064 - 0
web/js/mySchedule/jquery.fullcalendar.js


+ 148 - 0
web/js/ntkoWebSign/NtkoAddSecSign.js

@@ -0,0 +1,148 @@
+//注意:这是内部需要使用的函数,除
+//ocxElement.codebase = "ntkoWebSign.cab#version=4,0,2,0";
+//语句可以根据需要修改之外,其他语句不要修改
+function NtkoReserved_AddSecSignOcx(ControlID,ocxLeft,ocxTop)
+{
+	var ocxElement = null;
+	try
+	{
+		ocxElement = document.createElement('object');
+		if("string" == typeof(ControlID))
+		{
+			ocxElement.id = ControlID;
+		}
+		ocxElement.style.position = "absolute";
+		ocxElement.style.pixelLeft = ocxLeft;
+		ocxElement.style.pixelTop = ocxTop;
+		ocxElement.codebase = "ntkoWebSign.cab#version=4,0,2,0";
+		ocxElement.classid = "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA"; 
+		ocxElement.width = "10";
+		ocxElement.height = "10";
+		document.body.appendChild(ocxElement);	
+		return ocxElement;
+	}
+	catch(err)
+	{		
+		alert("印章对象装载错误!请确认您正确安装了NTKO安全电子印章系统!"+ err.number + ":" + err.description);			
+		if(ocxElement)
+		{
+			ocxElement.removeNode();
+		}
+	}
+	return null;
+}
+//注意:以下函数除提示信息之外,其他语句不要修改。
+function NtkoReserved_RunSignHelper(ocxElement,UserName,FileName,PromptSelect,
+		PrintMode,IsUseCertificate,IsLocked,IsCheckDocChange,
+		IsShowUI,SignPass,SignType,IsAddComment,AdjustToHeight,SignIndex)
+{
+	if("object" != typeof(ocxElement)) return;
+	ocxElement.SetUser(UserName);
+	switch(SignType)
+	{
+		case 0:
+			{
+				try
+				{
+					ocxElement.DoSign(FileName,PromptSelect, SignPass, PrintMode, 
+						IsUseCertificate, IsLocked,IsCheckDocChange,IsShowUI,IsAddComment);
+				}
+				catch(err)
+				{		
+				//	alert("加盖印章错误!");			
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}
+			}
+			break;
+		case 1:
+			{
+				try
+				{
+					ocxElement.DoHandSign(PrintMode,IsUseCertificate,IsLocked,IsCheckDocChange,
+						IsShowUI,SignPass,IsAddComment,AdjustToHeight);
+				}
+				catch(err)
+				{
+				//	alert("手写签名错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}		
+			}	
+			break;
+		case 2:
+			{
+				try
+				{
+					ocxElement.DoSignFromEkey(SignPass,PrintMode,IsUseCertificate,IsLocked,
+						IsCheckDocChange,IsShowUI,SignIndex,IsAddComment);
+				}
+				catch(err)
+				{
+				//	alert("加盖EKEY印章错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}		
+			}	
+			break;	
+		case 3:
+			{
+				try
+				{
+					ocxElement.DoKeyBoardComment(PrintMode,IsUseCertificate,IsLocked,IsCheckDocChange,IsShowUI,SignPass);
+				}
+				catch(err)
+				{
+				//	alert("添加安全键盘批注错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}		
+			}	
+			break;		
+		case 4:
+			{
+				try
+				{
+					ocxElement.DoHandSignFullScreen(PrintMode,IsUseCertificate,IsLocked,IsCheckDocChange,
+						IsShowUI,SignPass,IsAddComment,AdjustToHeight);
+				}
+				catch(err)
+				{
+				//	alert("全屏手写签名错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}			
+			}	
+			break;			
+		case 5:
+			{
+				try
+				{
+					ocxElement.DoHandSignInplace(PrintMode,IsUseCertificate,IsLocked,IsCheckDocChange,
+						IsShowUI,SignPass);
+				}
+				catch(err)
+				{
+				//	alert("嵌入手写签名错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}			
+			}	
+			break;					
+		default: 
+			{
+				try
+				{
+					ocxElement.DoSign(FileName,true, SignPass, PrintMode, 
+						IsUseCertificate, IsLocked,IsCheckDocChange,IsShowUI);
+				}
+				catch(err)
+				{
+				//	alert("加盖印章错误!");
+					ocxElement.Close();
+					ocxElement.removeNode();
+				}					
+			}
+			break;	
+	}
+}

+ 529 - 0
web/js/ntkoWebSign/NtkoWebSign.js

@@ -0,0 +1,529 @@
+/**
+ * WebSign控件。
+ * 使用方法:
+ * var obj=new NtkoWebSign();
+ * loadWebSign(targetId,attachmentId,espFileIdx,widthx,heightx);
+ * 	targetId: 文档容器id
+ * 	espFileIdx:附件id,如果指定那么根据该文件id加载签章。
+ *  
+ *  saveRemote:保存文档到服务器
+ *  
+ * @returns {OfficeControl}
+ */
+NtkoWebSign=function(){
+	{
+		var _self=this;
+		this.user = {id:"0",name:"开发用户",groupId:"0",groupName:"开发部"};
+		this.divId="targetId";
+		this.webSignId="ntkoocx";
+		this.webSignObj=null;
+		this.espFileId="";
+		this.height="0";    //隐藏
+		this.width="0";     //隐藏
+		this.checkForm="";
+		this.configStyle={user:{},imgStyle:'display: none;',buttonStyle:"display: none;"};
+	};
+			
+	/**
+	 * 加载NTKO Web版电子印章控件
+	 * arg targetId 加载控件存放的目标Dom元素(Div)最好是唯一的。 
+	 * arg attachmentId NTKO电子印章对象ID。如果不为空,加载对应的文件 最好是唯一的
+	 * espFileIdx 有没有对应的 NTKO电子印章文件(info文件),加载时放入!espFileIdx唯一标识
+	 */
+	this.loadWebSign = function(targetId,attachmentId,espFileIdx,conf) {
+		this.divId=targetId;
+		
+		this.width=$("#"+targetId).width();
+		this.height=$("#"+targetId).height();
+		if((attachmentId!="")&&(attachmentId!=null)&&('undefined' != typeof (attachmentId))){
+			this.webSignId=attachmentId;
+		}
+		this.espFileId=espFileIdx;
+		this.configStyle=$.extend({},this.configStyle,conf);
+		this.user = conf.user;
+		var cabPath=__ctx +"/js/ntkoWebSign/ntkoWebSign.cab#version=4,0,2,0";
+		var tags="";
+		//Web印章对象
+		tags+='<div id="webSignSeal" style="display: block;">';
+		tags+='<object id="'+this.webSignId+'" classid="clsid:DB5B521C-DA92-48e0-AE32-BDC944858D42"  codebase="'+cabPath+'"  ';
+		tags+='style="display:none">   ';
+		tags+='<param name="BackColor" value="16744576">    ';
+		tags+='<param name="ForeColor" value="16777215">    ';
+		tags+='<SPAN STYLE="color:red">不能装载NTKO WebSignHelper 控件。请在检查浏览器的选项中检查浏览器的安全设置。</SPAN>   ';
+		tags+='</object>';
+		tags+='</div> ';
+	  
+        //用于默认要需要表单验证功能标记  (如果表单设计没有需要表单验证的字段(没有页面对象中没有validate="{'isWebSign':true}")时,这标签可以防止签单报错)
+		tags+='<input type="hidden" id="isWebSignMark" name="isWebSignMark" lablename="验证功能标记" validate="{\'isWebSign\':true}" value="WebSignTrue" />';
+		
+		//用于获取鼠标的位置的对象	
+		tags+='<input type="hidden" id="mousePosX" name="mousePosX" value="50" />';
+		tags+='<input type="hidden" id="mousePosY" name="mousePosY" value="50" />';
+		
+		$('#'+this.divId).html(tags);
+		this.webSignObj = document.getElementById(this.webSignId);
+		if('undefined' == typeof (this.webSignObj.StatusCode)){
+			$.ligerDialog.warn("不能装载WEB印章控件,必须使用IE内核浏览器。可能需要在浏览器的Internet选项安全设置中修改ActiveX配置。",'提示信息',function(){
+				window.history.back();
+			});
+			return false;
+		}		
+		if((this.espFileId!="")&&(this.espFileId!=null)&&('undefined' != typeof (this.espFileId))){
+			this.loadFileInfo();
+		}
+	};
+	
+	
+	
+	/**
+	 * 获取webSignObj,代表当前的电子印章对象
+	 */
+	this.getntkoWebSignObj = function() {
+	//	this.webSignObj.IsShowRect = false;
+		return this.webSignObj;
+	};
+	
+	
+	//注意:以下四个方法是接管印章事件的内部方法。
+
+	//NtkoReservedEvent_BeforeDoSecSign如果返回true,标识可以继续盖章,如果返回false,标识取消印章。
+	//可以在这个函数中,调用Helper对象的DoWebExecute2方法查询服务器是否可以继续盖章并返回true或者false.
+	this.NtkoReservedEvent_BeforeDoSecSign = function (UserName,SignName,SignUser,SignSN)
+	{
+		return true;
+	//	alert("1NtkoReservedEvent_BeforeDoSecSign:UserName="+UserName+",SignName="+SignName+",SignUser="+SignUser+",SignSN="+SignSN);
+		try
+		{
+			var retValue = this.webSignObj.DoWebExecute2("http://192.168.0.100/testchecksign/checksign.asp",
+				"UserName="+UserName+"&SignName="+SignName+"&SignUser="+SignUser+"&SignSN="+SignSN);
+		//	alert(retValue);
+			return true;
+		}
+		catch(err)
+		{
+			alert("查询印章可用状态错误!"+ err.number + ":" + err.description);	
+			return false;
+		}	
+	};
+
+	//NtkoReservedEvent_BeforeDoSecSignFromEkey如果返回true,标识可以继续盖章,如果返回false,标识取消印章。
+	//可以在这个函数中,调用Helper对象的DoWebExecute2方法查询服务器是否可以继续盖章并返回true或者false.
+	this.NtkoReservedEvent_BeforeDoSecSignFromEkey = function (UserName,SignName,SignUser,SignSN,EkeySN)
+	{
+		return true;
+	//	alert("NtkoReservedEvent_BeforeDoSecSignFromEkey:UserName="+UserName+",SignName="+SignName+",SignUser="+SignUser+",SignSN="+SignSN+",EkeySN="+EkeySN);
+		try
+		{
+			var retValue = this.webSignObj.DoWebExecute2("http://192.168.0.100/testchecksign/checksign.asp",
+				"UserName="+UserName+"&SignName="+SignName+"&SignUser="+SignUser+"&SignSN="+SignSN+"&EkeySN="+EkeySN);
+		//	alert(retValue);
+			return true;
+		}
+		catch(err)
+		{
+			alert("查询印章可用状态错误!"+ err.number + ":" + err.description);	
+			return false;
+		}	
+	};
+
+	//该事件在印章被删除之后触发。
+	this.NtkoReservedEvent_AfterSecSignDeleted = function(UserName,SignName,SignUser,SignSN,EkeySN,UserData)
+	{
+		//alert("3NtkoReservedEvent_AfterSecSignDeleted:UserName="+UserName+",SignName="+SignName+",SignUser="+SignUser+",SignSN="+SignSN+",EkeySN="+EkeySN+",UserData="+UserData);
+	};
+
+	//NtkoReservedEvent_BeforeSecSignCheckRight事件在印章需要验证权限之前被触发。
+	/***************************************************************
+		其中的SignType:印章类型.0标识印章.1标识手写签名,2标识键盘批注
+	    返回0,1,2. 
+		0:标识用户自定义权限验证成功,且不需要系统进一步验证。
+		1:标识用户自定义权限验证失败,且不需要系统进一步验证。
+		2:标识用户自定义权限不起作用,需要系统进一步验证(用自身方法)
+	/***************************************************************/
+	this.NtkoReservedEvent_BeforeSecSignCheckRight = function(UserName,SignName,SignUser,SignSN,EkeySN,SignType,UserData)
+	{
+	//	alert("BeforeSecSignCheckRight:UserName="+UserName+",SignName="+SignName+",SignUser="+SignUser+
+	//		",SignSN="+SignSN+",EkeySN="+EkeySN+",SignType="+SignType+",UserData="+UserData);
+			
+		/***********************************************************************
+		//以下可以通过调用Helper对象的DoWebExecute2方法查询服务器
+		try
+		{
+			var retValue = ntkoobj.DoWebExecute2("http://192.168.0.100/testchecksign/checkright.asp",
+				"UserName="+UserName+"&SignName="+SignName+"&SignUser="+SignUser+"&SignSN="+SignSN+"&EkeySN="+EkeySN);
+			alert(retValue);
+			return 0; //0:标识用户自定义权限验证成功,且不需要系统进一步验证。
+		}
+		catch(err)
+		{
+			alert("查询印章权限错误!"+ err.number + ":" + err.description);	
+			return 1; //1:标识用户自定义权限验证失败,且不需要系统进一步验证。
+		}	
+		*****************************************************************/
+		
+		return 2; //2:标识用户自定义权限不起作用,需要系统进一步验证(用自身方法)
+	};
+
+	
+	/**
+	 * 增加有提示的手写WEB批注(没有自动对正大小)
+	 */
+	this.AddSecHandSign=function()
+	{
+		var secSignObj = this.webSignObj.AddSecSignOcx("SecHandSignID",20,20);
+		secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+		secSignObj.HandSignPenColor = 14402205; // 此数值计算方式为:假设需要设定颜色值RGB,则value = (blue * 65536) + (green * 256) + red
+		secSignObj.HandSignPenWidth = 5; //笔宽为5
+		secSignObj.HandSignPenStyle = 0; //笔形为1
+		//secSignObj.IsReadOnlyMode = true;
+		this.webSignObj.AddSecHandSign(secSignObj,_self.user.name,0,false,false,true,true,null,true);
+	};
+	
+	
+	/**
+	 * 增加没有提示的手写WEB批注(自动对正大小)
+	 */
+	this.AddSecHandSignNoPrompt=function()
+	{
+		var strxy = this.getXy();
+		if( strxy!="" && (strxy.split("&").length==2)){
+			var arrys = strxy.split("&");   	
+			var secSignObj = this.webSignObj.AddSecSignOcx("SecHandSignID",arrys[0],arrys[1]);
+			if(secSignObj)
+			{
+				secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+			//	secSignObj.HandSignPenColor = 0; // 此数值计算方式为:假设需要设定颜色值RGB,则value = (blue * 65536) + (green * 256) + red
+				secSignObj.HandSignPenWidth = 3; //笔宽为5
+				secSignObj.HandSignPenStyle = 0; //笔形为1
+				secSignObj.UserData = "my user data";
+				this.webSignObj.AddSecHandSign(secSignObj,_self.user.name,2,false,false,true,false,null,false,80);
+			}
+		}		
+	};
+	
+	/**
+	 * 增加有提示的手写WEB批注(自动对正大小)
+	 */
+	this.AddSecHandSignAdjust=function()
+	{
+		var secSignObj = this.webSignObj.AddSecSignOcx("SecHandSignID",20,20);
+		secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+		this.webSignObj.AddSecHandSign(secSignObj,_self.user.name,0,false,false,true,true,null,true,50);
+	};
+	
+	/**
+	 * 增加输入WEB批注(自动对正大小)
+	 */
+	this.AddSecKeyBoardComment=function()
+	{
+		var secSignObj = this.webSignObj.AddSecSignOcx("SecKeyBoardCommentID",20,20);
+		secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+		this.webSignObj.AddSecKeyBoardComment(secSignObj,_self.user.name,0,false,false,true,false);
+	};
+	
+	/**
+	 * 输入有提示的本地WEB签章批注
+	 */
+	this.AddSecSignFromLocal=function(isAddComment)
+	{
+		var secSignObj = this.webSignObj.AddSecSignOcx("SecSignFromLocalID",20,20);
+		secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+		this.webSignObj.AddSecSignFromLocal(secSignObj,_self.user.name,'',true,1,false,false,true,true,null,isAddComment);
+	};
+	
+	/**
+	 * 输入有提示的远程(URL)WEB签章批注
+	 */
+	this.AddSecSignFromURL=function()
+	{
+		var secSignObj = this.webSignObj.AddSecSignOcx("SecSignFromURLID",20,20);
+		secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+		//secSignObj.PositionTagId = "JiaFanSpan";//定义印章加盖的位置 JiaFanSpan 一般为DIV
+		this.webSignObj.AddSecSignFromURL(secSignObj,_self.user.name,
+		'http://www.ntko.com/admin/ocv14_test.nsf/vwSigns/2C0B608DD5844CA848256E46000A4C3D/$file/zhang_hetong.gif.esp?openelement',
+		2,false,false,true,false,"11111111",false);
+	};
+	
+	
+	/**
+	 * 从服务器中选印章对表单进行签章
+	 */
+	this.AddSecSignFromService=function(){
+		var strxy = this.getXy();
+		if( strxy!="" && (strxy.split("&").length==2)){
+			var arrys = strxy.split("&");   
+		//	alert("X:"+arrys[0]+"   Y:"+arrys[1]);			
+			var url = __ctx + "/platform/system/seal/dialog.ht";
+			var winArgs = "dialogWidth=800px;dialogHeight=600px;help=0;status=0;scroll=1;center=0;resizable=1;";
+			url = url.getNewUrl();
+			var that =this;
+			DialogUtil.open({
+				height:600,
+				width: 800,
+				title : '签章',
+				url: url, 
+				//自定义参数
+				sucCall:function(retVal){
+					if(typeof(retVal)==undefined){
+						return;
+					}
+					if(retVal.fileId.isEmpty()){
+						return;
+					}
+					var signUrl=__ctx + "/platform/system/sysFile/getFileById.ht?fileId=" + retVal.fileId;
+					try{
+						var secSignObj = that.webSignObj.AddSecSignOcx("SecSignFromURLID",arrys[0],arrys[1]);
+						secSignObj.WebSignInfo = that.checkPrintForm();//要Web签章验证的信息;
+						
+						/*secSignObj.PositionTagId = that.getPosDiv(); //设置印章对其到页面id为handSignPosDivID1的元素
+				        secSignObj.ReSetHTMLPosition();      */   
+						
+				        that.webSignObj.AddSecSignFromURL(secSignObj,_self.user.name,signUrl);
+					}catch(err){
+						alert("AddSecSignFromService:" +err.name + ": " + err.message);
+						return -1;
+					}
+				}
+			});
+		}		
+	};
+	
+	
+	
+	
+	
+	/**
+	 * 输入有提示的Ekey硬件WEB签章批注
+	 */
+	this.AddSecSignFromEkey=function()
+	{
+		if(this.webSignObj!=null){
+			/*if(!this.webSignObj.IsEkeyConnected)
+			{
+				alert("没有检测到EKEY.请将EKEY插入到计算机!然后点击确定继续.");
+				return false;
+			}*/
+			var secSignObj = this.webSignObj.AddSecSignOcx("SecSignFromEkeyID",20,20);
+			secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+			this.webSignObj.AddSecSignFromEkey(secSignObj,_self.user.name,2,false,false,true,true);
+		}
+	};
+	
+	/**
+	 * 输入有提示的Ekey硬件WEB签章批注
+	 */
+	this.AddSecSignFromEkeyWithSignIndex=function()
+	{
+		if(this.webSignObj!=null){
+			/*if(!this.webSignObj.IsEkeyConnected)
+			{
+				alert("没有检测到EKEY.请将EKEY插入到计算机!然后点击确定继续.");
+				return false;
+			}*/
+			var secSignObj = this.webSignObj.AddSecSignOcx("SecSignFromEkeyID",20,20);
+			secSignObj.WebSignInfo = this.checkPrintForm();          //要Web签章验证的信息;
+			this.webSignObj.AddSecSignFromEkey(secSignObj,_self.user.name,2,false,false,true,true,null,true,1/*SignIndex*/);
+		}
+	};
+
+	/**
+	 * 获取所有签章的相关信息
+	 */
+	this.ShowSignsInfo=function()
+	{
+		var objs = document.getElementsByTagName("object");
+		for(var i=0;i<objs.length;i++)
+		{
+			var obj = objs(i);
+			if(obj.classid == "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA")
+			{
+				var info = "";
+				info += "SignName="+obj.SignName;
+				info += ",Signer="+obj.Signer;
+				info += ",SignUser="+obj.SignUser;
+				info += ",SignSource="+obj.SignSource;
+				info += ",SignTime="+obj.SignTime;
+				info += ",SignSN="+obj.SignSN;
+				info += ",EkeySN="+obj.EkeySN;
+				info += ",PrintMode="+obj.PrintMode;
+				alert(info);
+			}
+		}
+	};
+	
+	/**
+	 * 清除所有印章
+	 */
+	this.ClearAllSigns=function() //清除所有印章
+	{
+		var objs = document.getElementsByTagName("object");
+		for(var i=objs.length-1;i>=0;i--)
+		{
+			var obj = objs(i);
+			if(obj.classid == "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA")
+			{
+				obj.Close();
+				obj.removeNode();
+			}
+		}
+	};
+	
+	/**
+	 * 是否支持印章对象对表单验证
+	 */
+	this.AllCheckDocChange=function(mark)
+	{
+		var objs = document.getElementsByTagName("object");
+		for(var i=0;i<objs.length;i++)
+		{
+			var obj = objs(i);
+			if(obj.classid == "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA")
+			{
+				obj.CheckDocChange(mark);   
+			}
+		}
+	};
+	
+	/**
+	 * 保存为本地图片并清除临时文件
+	 */
+	this.SavePicAsTempFile = function(imgDivid)
+	{
+		var objs = document.getElementsByTagName("object");	
+		var signscount = 0;
+		for(var i=0;i<objs.length;i++)
+		{
+			var obj = objs(i);
+			if(obj.classid == "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA") //找到一个印章
+			{
+				signscount++;
+				var tempName = obj.SavePicAsTempFile();
+				alert("第" + signscount + "个章的临时文件:" + tempName);
+				document.getElementById(imgDivid).src = "";
+				document.getElementById(imgDivid).src = tempName;
+			//	document.all("tmpimg").src = "";
+			//	document.all("tmpimg").src = tempName;
+				alert(document.getElementById(imgDivid).src);
+			//	alert("准备删除第"+signscount+"个章的临时文件");
+				document.getElementById(imgDivid).style.display='block';
+				obj.ClearTempFile();
+			}
+		}
+	};
+	
+	/**
+	 * 设定所有印章只读
+	 */
+	this.setAllsignsReadOnlyMode = function(isReadOnlyMode)
+	{
+		var objs = document.getElementsByTagName("object");
+		for(var i=0;i<objs.length;i++)
+		{
+			var obj = objs(i);
+			if(obj.classid == "clsid:AA4B3728-B61C-4bcc-AEE7-0AA47D3C0DDA")
+			{
+				obj.IsReadOnlyMode = isReadOnlyMode;
+			}
+		}
+	};
+		
+	/**
+	 * 获取要检验的表单数据
+	 */
+	this.checkPrintForm = function(){
+		var aryInput = $("input:text,input:hidden,textarea,select");
+//		var aryInput = $("input:text,input:hidden,textarea,select,input:checkbox,input:radio,span");
+		this.checkForm='';
+	    for (var i = 0, len = aryInput.length; i < len; i++) {
+			var tmp = aryInput.get(i);
+		//	var validRule = tmp.validate;  //获取自定义属性时,IE8或以下才可以用,IE8以上的都不能稳定获取!
+			var validRule = tmp.getAttribute("validate");   //获取自定义属性IE7、8、9通用
+			if ( validRule != null && validRule != '' && 'undefined' != validRule.toLowerCase() ){
+				var json = eval('(' + validRule + ')');				
+				if(json.isWebSign){
+					var name = tmp.getAttribute("lablename");   //字段说明名称
+					if( (name=="")||(name==null)||('undefined'==typeof(name)) ){
+						var arrys = (tmp.name).split(":");   //tmp.name 固定属性IE7、8、9都可以获取!
+						name = arrys[arrys.length-1];       
+					}
+					this.checkForm += name + '=' + tmp.getAttribute("name") +';'
+				}				
+			}
+		}
+		if(this.checkForm.length>0){
+			this.checkForm = this.checkForm.substr(0,this.checkForm.length-1)   //去年最后一个字符
+		}
+		return this.checkForm;
+	};
+	
+
+
+	/**
+	 * 保存签章相关信息
+	 */
+	this.SaveToServer = function(power)
+	{	
+		if(power=="w"||right=="b"){
+			var path= __ctx + "/platform/system/sysFile/saveFileInfo.ht";
+			var uploadName = this.webSignId +"_pdf"
+			var params="fileId=" + this.espFileId + "&uploadName="+ uploadName;
+			var curDate=new Date();
+			var espName=Math.random()*curDate.getMilliseconds()*10000;
+			//保存数据到服务器。
+			var retstr = this.webSignObj.SaveToURL(path,uploadName,params,espName+".info",0);  
+			if(retstr!=""&&('undefined' != typeof (retstr))&& retstr>0){
+				this.espFileId = retstr;
+				return retstr;
+			}else{
+				return "";
+			}
+		}
+    };
+    
+    /**
+	 * 加载签章相关信息
+	 */
+    this.loadFileInfo = function()
+	{	
+    	if((this.espFileId!="")&&(this.espFileId!=null)&&('undefined' != typeof (this.espFileId))){
+    		var path= __ctx + "/platform/system/sysFile/getFileById.ht?fileId=" + this.espFileId;
+    		this.webSignObj.LoadFromURL(path);
+			if (0 != this.webSignObj.StatusCode) {
+				return false;
+			}
+		}
+    };
+
+	
+    /**
+	 * 鼠标获取位置
+	 */
+	this.getXy=function()
+	{
+		var mousePosX = document.getElementById('mousePosX').value;
+		var mousePosY = document.getElementById('mousePosY').value;
+		var str = mousePosX +"&"+ mousePosY;		
+		document.getElementById('mousePosX').value = '50';
+		document.getElementById('mousePosY').value = '50';
+		if(mousePosX=='50' && mousePosY=='50'){
+			if(confirm("当前签章将保存位置:横坐标("+mousePosX+"px),纵坐标("+mousePosY+"px)!确认不需要更改吗?")){
+				return str; 
+			}else{
+				alert("请通过双击鼠标左键确定将选择的印章位置,再进行签章!");
+				return "";
+			}
+		}else{
+			return str;
+		}		
+	};
+    
+    this.getPosDiv = function(){
+    	if($("#divPos").length<1){//还没有就新建
+    		$("body").append('<div id="divPos" style="position:absolute;left:0px;top:0px;border:1px solid red;width:10px;height:10px;">测试嘿嘿嘿</div>');
+    	}
+    	return "divPos";
+    };
+};
+
+
+

+ 281 - 0
web/js/ntkoWebSign/WebSignPlugin.js

@@ -0,0 +1,281 @@
+/**
+ * WebSign插件,用于自定义表单。
+ * 
+ * 1.WebSignPlugin.init();
+ *  	加载WebSign控件。
+ * 
+ * 2.WebSignPlugin.submit();
+ * 		保存WebSign Info文档。
+ */
+WebSignPlugin = {
+		//当前登陆用户相关信息件对象
+		user:{id:"0",name:"开发用户",groupId:"0",groupName:"开发部"},
+		//WebSign控件对象
+		webSignObj:null,
+		//附件对象
+		fileObj:null,
+		//判断当前表单页面是否有WebSign控件。
+		hasWebSignField:false,
+		//初始化
+		//所做的操作如下:
+		//1.检查当前表单中是否有webSign控件。
+		//2.如果存在webSign控件
+		// 	获取文件id,将webSign控件添加到容器中。
+		init:function(){
+			this.user = getSignUserData();
+			this.fileObj=$("input[controltype='webSign']");
+			if(this.fileObj.length>0){
+				var name=this.fileObj.attr("name");
+				var fileId=this.fileObj.val();				
+				//容器的ID
+				var divId="div_" + name.replaceAll(":","_");
+				
+				var right=this.fileObj.attr("right");
+				//没有权限,删除div容器。
+				if(right=="no"){
+					$("#" + divId).remove();
+				}else{             //有读和写的权限,加载控件。
+					$.ligerDialog.waitting('正在加载印章文档,请稍候...');
+					//加载控件。
+					this.webSignObj= new NtkoWebSign();
+					//加载office控件。
+					if(right=="r"||right=="rp"){   //只读时,没有按钮操作
+						this.webSignObj.loadWebSign(divId,"ntkoocx"+divId,fileId,{user:this.user,imgStyle:'display: none;',buttonStyle:"display: none;"});
+					}else{   //可编辑 有按钮操作
+						this.webSignObj.loadWebSign(divId,"ntkoocx"+divId,fileId,{user:this.user,imgStyle:'display: none;',buttonStyle:"display: block;"});
+					}
+					$.ligerDialog.closeWaitting(); 
+					$("#" + divId).removeClass("webSign-div");   //去掉背景图片 webSign-div为Web签章的样式自定样式
+					//是否有office控件。
+					this.hasWebSignField=true;
+				}
+			}
+		},
+		//提交文件保存。
+		//如果有WebSign控件。则保存后将返回的附件id放到隐藏域。
+		submit:function(){
+			if(!this.hasWebSignField) return;
+			var right=this.fileObj.attr("right");
+			var fileId=this.fileObj.val();
+			//可写,保存office内容并上传。
+			if(right!="no"){
+				//保存到服务器。
+				if(right=="w"||right=="b"){
+					fileId=this.webSignObj.SaveToServer(right);   //返回保存对象的ID
+				}
+				//将结果放到隐藏域。
+				this.fileObj.val(fileId);
+			}else{
+	            $.ligerDialog.error("没有权限修改Web印章内容!",'提示信息');
+		    }
+		}
+};
+
+
+//获取用户
+function getSignUserData(){
+	var user = OfficePlugin.user;
+	var path = __ctx +'/platform/system/sysFile/getUserData.ht';
+    $.ajaxSetup({async:false});  //同步
+	$.post(path,{},function(data){			
+	   if(data!=""){
+		   var obj = eval('(' + data + ')');
+		   if(obj.success){
+			   user = obj.user;
+		   }
+	   }
+    });
+	$.ajaxSetup({async:true}); //异步
+	return user;
+};
+
+
+
+//获取WebSign控件对象
+function getntkoWebSignObjX(){
+	
+	if(WebSignPlugin.fileObj==null||'undefined'== typeof (WebSignPlugin.fileObj)||WebSignPlugin.fileObj.length<1){   
+		$.ligerDialog.error("请添加Web印章控件,再进行操作!(控件只支持IE内核的浏览器)",'提示信息');
+		return null;
+	}
+	var right=WebSignPlugin.fileObj.attr("right");  //权限
+	if(right=="no"){   
+		$.ligerDialog.error("没有权限修改Web印章内容!",'提示信息');
+		return null;
+	}
+	var ntkoWebSignObj = WebSignPlugin.webSignObj;
+	if((ntkoWebSignObj!="")&&(ntkoWebSignObj!=null)&&('undefined' != typeof (ntkoWebSignObj))){
+		return ntkoWebSignObj;
+	}else{
+		return null;
+	}
+}
+
+
+//增加没有提示的手写WEB批注(自动对正大小)
+function AddSecHandSignNoPromptX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecHandSignNoPrompt();
+	}
+}
+	
+//增加有提示的手写WEB批注(没有自动对正大小)
+function AddSecHandSignX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecHandSign();
+	}
+}
+
+//增加有提示的手写WEB批注(自动对正大小)
+function AddSecHandSignAdjustX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecHandSignAdjust();
+	}
+}
+
+//增加输入WEB批注(自动对正大小)
+function AddSecKeyBoardCommentX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecKeyBoardComment();
+	}
+}		
+
+//输入有提示的本地WEB签章批注
+function AddSecSignFromLocalX(mark){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecSignFromLocal(true);
+	}
+}
+
+//远程(URL)WEB签章批注
+function AddSecSignFromURLX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecSignFromURL();
+	}
+}
+
+
+//输入有提示的服务器WEB签章批注
+function AddSecSignFromServiceX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecSignFromService();
+	}
+}
+
+//输入有提示的Ekey硬件WEB签章批注
+function AddSecSignFromEkeyX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.AddSecSignFromEkey();
+	}
+}
+
+//最后一个签章保存为本地图片并清除临时文件
+function SavePicAsTempFileX(webSignImg){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.SavePicAsTempFile(webSignImg);
+	}
+}
+
+//清除所有WEB签章
+function ClearAllSignsX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.ClearAllSigns();
+	}
+}
+
+//保存签章到附件 
+function SaveToServerX(){
+	var ntkoWebSignObj = getntkoWebSignObjX();
+	if(ntkoWebSignObj!=null){
+		ntkoWebSignObj.SaveToServer(WebSignPlugin.fileObj.attr("right"));
+	}
+}
+
+
+//选择Web签章方法
+function webSignSelectEvent(selectEvent){
+    var selectValue = $("#" + selectEvent).val();
+//	alert(selectValue);
+	if(selectValue==1){
+		AddSecHandSignNoPromptX();
+	}else if(selectValue==2){
+		AddSecHandSignX();
+	}else if(selectValue==3){
+		AddSecHandSignAdjustX();
+	}else if(selectValue==4){
+		AddSecKeyBoardCommentX();
+	}else if(selectValue==5){
+		AddSecSignFromLocalX();
+	}else if(selectValue==6){
+		AddSecSignFromURLX();
+	}else if(selectValue==7){
+		AddSecSignFromEkeyX();
+	}else if(selectValue==8){
+		SaveToServerX();
+	}else if(selectValue==9){
+		ClearAllSignsX();
+	}else if(selectValue==10){
+		AddSecSignFromServiceX();
+	}else{
+		return;
+	}
+	
+	/*tags+='<div class="group"><a class="link AddSecHandSignNoPrompt" onclick="AddSecHandSignNoPromptX()" >手写批注无口令(自动)</a></div>';
+	tags+='<div class="group"><a class="link AddSecHandSign" onclick="AddSecHandSignX()" >手写批注</a></div>';
+	tags+='<div class="group"><a class="link AddSecHandSignAdjust" onclick="AddSecHandSignAdjustX()" >手写批注有口令(自动)</a></div>';
+	tags+='<div class="group"><a class="link AddSecKeyBoardComment" onclick="AddSecKeyBoardCommentX()" >输入批注</a></div>';
+	tags+='<div class="group"><a class="link AddSecSignFromLocal" onclick="AddSecSignFromLocalX(true)" >本地签章</a></div>';
+	tags+='<div class="group"><a class="link AddSecSignFromURL" onclick="AddSecSignFromURLX()" >URL签章</a></div>';
+	tags+='<div class="group"><a class="link AddSecSignFromEkey" onclick="AddSecSignFromEkeyX()" >Ekey签章</a></div>';
+	tags+='<div class="group"><a class="link SavePicAsTempFile" onclick="SavePicAsTempFileX(\'webSignImg\')" >签章保存为本地图片并清除临时文件</a></div>';	
+	tags+='<div class="group"><a class="link ClearAllSigns" onclick="ClearAllSignsX()" >清除签章</a></div>';	
+	tags+='<div class="group"><a class="link SaveToServer" onclick="SaveToServerX()" >保存签章</a></div>';		*/
+}
+
+
+/** 鼠标获取位置 **/
+//鼠标获取位置的方法
+function mousePosition(ev) {
+	if (ev.pageX || ev.pageY) {
+		return {
+			x : ev.pageX,
+			y : ev.pageY
+		};
+	}
+	return {
+		x : ev.clientX + document.body.scrollLeft - document.body.clientLeft,
+		y : ev.clientY + document.body.scrollTop - document.body.clientTop
+	};
+}
+
+//设置鼠标获取位置的对象
+function mouseOndblclick(ev) {
+	ev = ev || window.event;
+	var mousePos = mousePosition(ev);
+	var mousePosX = document.getElementById('mousePosX');
+	var mousePosY = document.getElementById('mousePosY');
+	if((mousePosX!=null)&&('undefined' != typeof (mousePosX))){
+		document.getElementById('mousePosX').value = mousePos.x;
+	}
+	if((mousePosY!=null)&&('undefined' != typeof (mousePosY))){
+		document.getElementById('mousePosY').value = mousePos.y;
+	}
+}
+
+//设置鼠标获取位置的事件(双击)
+document.ondblclick = mouseOndblclick;
+
+
+
+
+

BIN
web/js/ntkosign/NtkoControlSetup.zip


+ 155 - 0
web/js/ntkosign/NtkoSignManage.js

@@ -0,0 +1,155 @@
+/**
+ * @author Raise
+ */
+
+NtkoSignManage = function() {
+	this.ntkoSignObj;
+	/**
+	 * 加载NTKO电子印章控件
+	 * arg targetId 加载控件存放的目标Dom元素。 
+	 * arg attachmentId NTKO电子印章文件的ID。如果不为空,加载对应的文件
+	 */
+	this.load = function(targetId,attachmentId) {
+		var cabPath=__ctx +"/media/office/ntkosigntool.cab#version=4,0,0,2";
+		var tags="";
+		tags+='<object id="ntkosignctl" classid="clsid:97D0031E-4C58-4bc7-A9BA-872D5D572896" codebase="'+cabPath+'"    ';
+		tags+='  width=450 height=100>   ';
+		tags+='<param name="BackColor" value="16744576">   ';
+		tags+='<param name="ForeColor" value="16777215">   ';
+		tags+='<param name="IsShowStatus" value="-1">   ';
+		tags+='<param name="EkeyType" value="1">   '; // HT
+		tags+='<SPAN STYLE="color:red">不能装载印章管理控件,必须使用IE内核浏览器。可能需要在浏览器的Internet选项安全设置中修改ActiveX配置。按提示加载控件。</SPAN>   ';
+		tags+='</object>   ';
+
+		$('<div style="display: none;" id="divntko"></div>').prependTo('body');
+		$('#'+targetId).append(tags);
+		this.ntkoSignObj = document.getElementById("ntkosignctl");
+		if('undefined' == typeof (this.ntkoSignObj.StatusCode)){
+			$.ligerDialog.warn("不能装载印章管理控件,必须使用IE内核浏览器。可能需要在浏览器的Internet选项安全设置中修改ActiveX配置。",'提示信息',function(){
+				window.history.back();
+			});
+			return false;
+		}
+		
+		if((attachmentId!="")||('undefined' == typeof (attachmentId))){
+			this.openFormURL(attachmentId);
+			if (0 != this.ntkoSignObj.StatusCode) {
+				window.history.back();
+			}
+		}
+		
+	};
+	
+	/**
+	 * 获取ntkoSignObj,代表当前的电子印章对象
+	 */
+	this.getntkoSignObject = function() {
+		this.ntkoSignObj.IsShowRect = false;
+		return this.ntkoSignObj;
+	};
+	
+	/**
+	 * 从指定的文件ID,打开电子印章。
+	 */
+	this.openFormURL = function(fileId) {
+		var url=__ctx + "/platform/system/sysFile/getFileById.ht?fileId=" + fileId;
+		this.ntkoSignObj.OpenFromURL(url);
+		if (0 != this.ntkoSignObj.StatusCode) {
+			alert("打开印章出错!");
+		}
+	};
+	
+	
+	/**
+	 * 从本地打开或导入电子印章。
+	 */
+	this.openFromLocal = function() {
+		this.ntkoSignObj.OpenFromLocal('',true);
+	};
+	
+	
+	/**
+	 * 从导出到本地电子印章。
+	 */
+	this.saveToLocal = function() {
+		var spassowrd = this.ntkoSignObj.Password;
+		if('undefined'==typeof (spassowrd)||spassowrd==null||spassowrd==""){
+			alert("没有印章!");
+			return false;
+		}
+		this.ntkoSignObj.SaveToLocal('',true);
+		if(0 == this.ntkoSignObj.StatusCode){
+			alert("保存印章到本地文件成功!");
+		}else{
+			alert("保存印章到本地文件失败!");
+		}
+	};
+
+	
+	/**
+	 * 创建新的电子印章
+	 */
+	this.newSign = function(callback) {
+		this.ntkoSignObj.IsShowRect = false;
+		var url=__ctx+ "/platform/system/seal/addSign.ht";
+		url=url.getNewUrl();
+		var params={
+		};
+		
+		var that =this;
+		DialogUtil.open({
+			height:400,
+			width: 600,
+			title : '电子印章',
+			url: url, 
+			isResize: true,
+			//自定义参数
+			params: params,
+			sucCall:function(rtn){
+				that.ntkoSignObj.CreateNew(rtn.signname,rtn.username,rtn.password,rtn.filename);
+				callback(rtn);
+			}
+		});
+	};
+	
+	/**
+	 * 将电子印章保存到服务器上。
+	 */
+	this.saveSign=function(){
+		var sname = this.ntkoSignObj.SignSN;
+		if('undefined'==typeof (sname)||sname==null||sname==""){
+			sname = "导入:"+this.ntkoSignObj.SignName;
+		}
+		var path= __ctx + "/platform/system/sysFile/saveFile.ht";
+		var result = this.ntkoSignObj.SaveToURL(path,"EspFileName","file_cat=sealSign&uploadName=EspFileName",sname+'.esp',0);
+		if (0 != this.ntkoSignObj.StatusCode) {
+            alert("创建印章错误.");
+            return false;
+        }
+		if(result==-1){
+			return false;
+		}
+		return result;
+	};
+	
+	
+	/**
+	 * 创建并保存电子印章。
+	 */
+	this.createSign=function(name, user, password, file){
+		var ntkoSignObj = this.getntkoSignObject();
+		ntkoSignObj.IsShowRect = false;
+		ntkoSignObj.CreateNew(name, user, password, file);
+		if (0 != ntkoSignObj.StatusCode) {
+             alert("创建印章错误.");
+             return false;
+		}
+		var path= __ctx + "/platform/system/sysFile/saveFile.ht";
+		var result = ntkoSignObj.SaveToURL(path,"EspFileName","file_cat=sealSign&uploadName=EspFileName",ntkoSignObj.SignSN+'.esp',0);
+		if (0 != ntkoSignObj.StatusCode) {
+            alert("创建印章错误.");
+            return false;
+        }
+		return result;
+	};
+};

BIN
web/js/ntkosign/SignToolSetup.zip


BIN
web/js/ntkosign/ntkosigntoolv3.cab


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 12 - 0
web/js/rendor/recorder.js


+ 175 - 0
web/js/swfupload/fileprogress.js

@@ -0,0 +1,175 @@
+/*
+	A simple class for displaying file information and progress
+	Note: This is a demonstration only and not part of SWFUpload.
+	Note: Some have had problems adapting this class in IE7. It may not be suitable for your application.
+*/
+
+// Constructor
+// file is a SWFUpload file object
+// targetID is the HTML element id attribute that the FileProgress HTML structure will be added to.
+// Instantiating a new FileProgress object with an existing file will reuse/update the existing DOM elements
+function FileProgress(file, targetID) {
+	this.fileProgressID = file.id;
+
+	this.opacity = 100;
+	this.height = 0;
+
+	this.fileProgressWrapper = document.getElementById(this.fileProgressID);
+	if (!this.fileProgressWrapper) {
+		this.fileProgressWrapper = document.createElement("div");
+		this.fileProgressWrapper.className = "progressWrapper";
+		this.fileProgressWrapper.id = this.fileProgressID;
+
+		this.fileProgressElement = document.createElement("div");
+		this.fileProgressElement.className = "progressContainer";
+
+		var progressCancel = document.createElement("a");
+		progressCancel.className = "progressCancel";
+		progressCancel.href = "#";
+		progressCancel.style.visibility = "hidden";
+		progressCancel.appendChild(document.createTextNode(" "));
+
+		var progressText = document.createElement("div");
+		progressText.className = "progressName";
+		progressText.appendChild(document.createTextNode(file.name));
+
+		var progressBar = document.createElement("div");
+		progressBar.className = "progressBarInProgress";
+
+		var progressStatus = document.createElement("div");
+		progressStatus.className = "progressBarStatus";
+		progressStatus.innerHTML = "&nbsp;";
+
+		this.fileProgressElement.appendChild(progressCancel);
+		this.fileProgressElement.appendChild(progressText);
+		this.fileProgressElement.appendChild(progressStatus);
+		this.fileProgressElement.appendChild(progressBar);
+
+		this.fileProgressWrapper.appendChild(this.fileProgressElement);
+
+		document.getElementById(targetID).appendChild(this.fileProgressWrapper);
+	} else {
+		this.fileProgressElement = this.fileProgressWrapper.firstChild;
+		this.fileProgressElement.childNodes[1].innerHTML = file.name;
+	}
+
+	this.height = this.fileProgressWrapper.offsetHeight;
+
+}
+FileProgress.prototype.setProgress = function (percentage) {
+	this.fileProgressElement.className = "progressContainer green";
+	this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
+	this.fileProgressElement.childNodes[3].style.width = percentage + "%";
+};
+FileProgress.prototype.setComplete = function () {
+	this.appear();
+	this.fileProgressElement.className = "progressContainer blue";
+	this.fileProgressElement.childNodes[3].className = "progressBarComplete";
+	this.fileProgressElement.childNodes[3].style.width = "";
+
+	var oSelf = this;
+	setTimeout(function () {
+		oSelf.disappear();
+	}, 10000);
+};
+FileProgress.prototype.setError = function () {
+	this.appear();
+	this.fileProgressElement.className = "progressContainer red";
+	this.fileProgressElement.childNodes[3].className = "progressBarError";
+	this.fileProgressElement.childNodes[3].style.width = "";
+
+	var oSelf = this;
+	setTimeout(function () {
+		oSelf.disappear();
+	}, 5000);
+};
+FileProgress.prototype.setCancelled = function () {
+	this.appear();
+	this.fileProgressElement.className = "progressContainer";
+	this.fileProgressElement.childNodes[3].className = "progressBarError";
+	this.fileProgressElement.childNodes[3].style.width = "";
+
+	var oSelf = this;
+	setTimeout(function () {
+		oSelf.disappear();
+	}, 2000);
+};
+FileProgress.prototype.setStatus = function (status) {
+	this.fileProgressElement.childNodes[2].innerHTML = status;
+};
+
+// Show/Hide the cancel button
+FileProgress.prototype.toggleCancel = function (show, swfUploadInstance) {
+	this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
+	if (swfUploadInstance) {
+		var fileID = this.fileProgressID;
+		this.fileProgressElement.childNodes[0].onclick = function () {
+			swfUploadInstance.cancelUpload(fileID);
+			return false;
+		};
+	}
+};
+
+// Makes sure the FileProgress box is visible
+FileProgress.prototype.appear = function () {
+		if (this.fileProgressWrapper.filters) {
+			try {
+				this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100;
+			} catch (e) {
+				// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
+				this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
+			}
+		} else {
+			this.fileProgressWrapper.style.opacity = 1;
+		}
+		
+		this.fileProgressWrapper.style.height = "";
+		this.height = this.fileProgressWrapper.offsetHeight;
+		this.opacity = 100;
+		this.fileProgressWrapper.style.display = "";
+
+};
+
+// Fades out and clips away the FileProgress box.
+FileProgress.prototype.disappear = function () {
+
+	var reduceOpacityBy = 15;
+	var reduceHeightBy = 4;
+	var rate = 30;	// 15 fps
+
+	if (this.opacity > 0) {
+		this.opacity -= reduceOpacityBy;
+		if (this.opacity < 0) {
+			this.opacity = 0;
+		}
+
+		if (this.fileProgressWrapper.filters) {
+			try {
+				this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity;
+			} catch (e) {
+				// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
+				this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + this.opacity + ")";
+			}
+		} else {
+			this.fileProgressWrapper.style.opacity = this.opacity / 100;
+		}
+	}
+
+	if (this.height > 0) {
+		this.height -= reduceHeightBy;
+		if (this.height < 0) {
+			this.height = 0;
+		}
+
+		this.fileProgressWrapper.style.height = this.height + "px";
+	}
+
+	if (this.height > 0 || this.opacity > 0) {
+		var oSelf = this;
+		setTimeout(function () {
+			oSelf.disappear();
+		}, rate);
+	} else {
+		this.fileProgressWrapper.style.display = "none";
+	}
+};

+ 175 - 0
web/js/swfupload/handlers.form.upload.js

@@ -0,0 +1,175 @@
+var formChecker = null;
+function preLoad() {
+	if (!this.support.loading) {
+		alert("使用SWFUpload Flash,您需要 Player 9.028或以上.");
+		return false;
+	}
+}
+function loadFailed() {
+	alert("加载 SWFUpload 失败. ");
+}
+
+// Called by the submit button to start the upload
+function doSubmit() {
+	try {
+		swfu.startUpload();
+	} catch (ex) {
+
+	}
+	return false;
+}
+
+ // Called by the queue complete handler to submit the form
+function uploadDone() {
+	try {
+		document.forms[0].submit();
+	} catch (ex) {
+		alert("表单提交失败!");
+	}
+}
+
+function fileDialogStart() {
+	var txtFileName = document.getElementById("txtFileName");
+	txtFileName.value = "";
+
+	this.cancelUpload();
+}
+
+
+
+function fileQueueError(file, errorCode, message)  {
+	try {
+		// Handle this error separately because we don't want to create a FileProgress element for it.
+		switch (errorCode) {
+		case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
+			alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
+			return;
+		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
+			alert("The file you selected is too big.");
+			this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
+			alert("The file you selected is empty.  Please select another file.");
+			this.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
+			alert("The file you choose is not an allowed file type.");
+			this.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		default:
+			alert("An error occurred in the upload. Try again later.");
+			this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		}
+	} catch (e) {
+	}
+}
+
+function fileQueued(file) {
+	try {
+		var txtFileName = document.getElementById("txtFileName");
+		txtFileName.value = file.name;
+	} catch (e) {
+	}
+
+}
+function fileDialogComplete(numFilesSelected, numFilesQueued) {
+	//validateForm();
+}
+
+function uploadProgress(file, bytesLoaded, bytesTotal) {
+
+	try {
+		var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
+
+		file.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(file, this.customSettings.progress_target);
+		progress.setProgress(percent);
+		progress.setStatus("上传中...");
+	} catch (e) {
+	}
+}
+
+function uploadSuccess(file, serverData) {
+	try {
+		file.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(file, this.customSettings.progress_target);
+		progress.setComplete();
+		progress.setStatus("完成.");
+		progress.toggleCancel(false);
+		
+		if (serverData === " ") {
+			this.customSettings.upload_successful = false;
+		} else {
+			this.customSettings.upload_successful = true;
+		}
+		
+	} catch (e) {
+	}
+}
+
+function uploadError(file, errorCode, message) {
+	try {
+		
+		if (errorCode === SWFUpload.UPLOAD_ERROR.FILE_CANCELLED) {
+			// Don't show cancelled error boxes
+			return;
+		}
+		
+		var txtFileName = document.getElementById("txtFileName");
+		txtFileName.value = "";
+		validateForm();
+		
+		// Handle this error separately because we don't want to create a FileProgress element for it.
+		switch (errorCode) {
+		case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
+			alert("There was a configuration error.  You will not be able to upload a resume at this time.");
+			this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + message);
+			return;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
+			alert("You may only upload 1 file.");
+			this.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
+			break;
+		default:
+			alert("An error occurred in the upload. Try again later.");
+			this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			return;
+		}
+
+		file.id = "singlefile";	// This makes it so FileProgress only makes a single UI element, instead of one for each file
+		var progress = new FileProgress(file, this.customSettings.progress_target);
+		progress.setError();
+		progress.toggleCancel(false);
+
+		switch (errorCode) {
+		case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
+			progress.setStatus("Upload Error");
+			this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
+			break;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
+			progress.setStatus("Upload Failed.");
+			this.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+			break;
+		case SWFUpload.UPLOAD_ERROR.IO_ERROR:
+			progress.setStatus("Server (IO) Error");
+			this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
+			break;
+		case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
+			progress.setStatus("Security Error");
+			this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
+			break;
+		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
+			progress.setStatus("Upload Cancelled");
+			this.debug("Error Code: Upload Cancelled, File name: " + file.name + ", Message: " + message);
+			break;
+		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
+			progress.setStatus("Upload Stopped");
+			this.debug("Error Code: Upload Stopped, File name: " + file.name + ", Message: " + message);
+			break;
+		}
+	} catch (ex) {
+	}
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1132 - 0
web/js/swfupload/swfupload.js


+ 98 - 0
web/js/swfupload/swfupload.queue.js

@@ -0,0 +1,98 @@
+/*
+	Queue Plug-in
+	
+	Features:
+		*Adds a cancelQueue() method for cancelling the entire queue.
+		*All queued files are uploaded when startUpload() is called.
+		*If false is returned from uploadComplete then the queue upload is stopped.
+		 If false is not returned (strict comparison) then the queue upload is continued.
+		*Adds a QueueComplete event that is fired when all the queued files have finished uploading.
+		 Set the event handler with the queue_complete_handler setting.
+		
+	*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+	SWFUpload.queue = {};
+	
+	SWFUpload.prototype.initSettings = (function (oldInitSettings) {
+		return function () {
+			if (typeof(oldInitSettings) === "function") {
+				oldInitSettings.call(this);
+			}
+			
+			this.queueSettings = {};
+			
+			this.queueSettings.queue_cancelled_flag = false;
+			this.queueSettings.queue_upload_count = 0;
+			
+			this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
+			this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
+			this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
+			this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
+			
+			this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
+		};
+	})(SWFUpload.prototype.initSettings);
+
+	SWFUpload.prototype.startUpload = function (fileID) {
+		this.queueSettings.queue_cancelled_flag = false;
+		this.callFlash("StartUpload", [fileID]);
+	};
+
+	SWFUpload.prototype.cancelQueue = function () {
+		this.queueSettings.queue_cancelled_flag = true;
+		this.stopUpload();
+		
+		var stats = this.getStats();
+		while (stats.files_queued > 0) {
+			this.cancelUpload();
+			stats = this.getStats();
+		}
+	};
+	
+	SWFUpload.queue.uploadStartHandler = function (file) {
+		var returnValue;
+		if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
+			returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
+		}
+		
+		// To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
+		returnValue = (returnValue === false) ? false : true;
+		
+		this.queueSettings.queue_cancelled_flag = !returnValue;
+
+		return returnValue;
+	};
+	
+	SWFUpload.queue.uploadCompleteHandler = function (file) {
+		var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
+		var continueUpload;
+		
+		if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
+			this.queueSettings.queue_upload_count++;
+		}
+
+		if (typeof(user_upload_complete_handler) === "function") {
+			continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
+		} else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
+			// If the file was stopped and re-queued don't restart the upload
+			continueUpload = false;
+		} else {
+			continueUpload = true;
+		}
+		
+		if (continueUpload) {
+			var stats = this.getStats();
+			if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
+				this.startUpload();
+			} else if (this.queueSettings.queue_cancelled_flag === false) {
+				this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
+				this.queueSettings.queue_upload_count = 0;
+			} else {
+				this.queueSettings.queue_cancelled_flag = false;
+				this.queueSettings.queue_upload_count = 0;
+			}
+		}
+	};
+}

BIN
web/js/swfupload/swfupload.swf


BIN
web/js/swfupload/swfuploadbutton.swf


+ 85 - 0
web/js/util/ResizeControl.js

@@ -0,0 +1,85 @@
+/**
+ * 修改表格大小
+ * 如此表格
+ * <table>
+ * <tr>
+ * <td> </td>
+ * <td id="tdId"> </td>
+ * <td> </td>
+ * </tr>
+ * </table>
+ * 指定中间那个表格的ID,就可以拖动修改表格的列宽。

+ * 调用方法:

+ * var resize=new  ResizeControl("tdId");
+ * resize.init();
+ * @param tdResizeId
+ * @return
+ */
+function ResizeControl(tdResizeId)
+{
+	var oldOffset = null;
+	var tdResize = null;
+	var isMove = false;
+	var tdLeft = null;
+	var tdRight = null;
+	var lwidth;
+	var rwidth;
+	this.tdResizeId = tdResizeId;
+	var self = this;
+	this.init = function()
+	{
+		$("body").bind("mousemove", function(event)
+		{
+			if(tdResize == null || oldOffset == null)
+				return;
+			if(isMove == false)
+				return;
+			var left = oldOffset.left;
+			var offsetX = event.clientX - left;
+			tdLeft.width(lwidth + offsetX);
+			tdRight.width(rwidth - offsetX);
+		});
+		$("#" + self.tdResizeId).bind("mousemove", function(event)
+		{
+			tdResize = $(this);
+			tdResize.css(
+			{
+				'cursor':'w-resize'
+			});
+		});
+		$("#" + self.tdResizeId).bind("mousedown", function(event)
+		{
+			tdResize = $(this);
+			if(tdResize.prevAll().length < 1 | tdResize.nextAll().length < 1)
+			{
+				return;
+			}
+			oldOffset = tdResize.offset();
+			if(event.clientX - oldOffset.left < 4 || (tdResize.width() - (event.clientX - oldOffset.left)) < 4)
+			{
+				isMove = true;
+				tdResize.css(
+				{
+					'cursor':'w-resize'
+				});
+				tdLeft = tdResize.prev();
+				tdRight = tdResize.next();
+				lwidth = tdLeft.width();
+				rwidth = tdRight.width();
+			}
+		});
+		$("body").bind("mouseup", function(event)
+		{
+			if(tdResize != null)
+			{
+				tdResize.css(
+				{
+					'cursor':'default'
+				});
+			}
+			tdResize = null;
+			oldOffset = null;
+			isMove = false;
+		});
+	};
+}

+ 232 - 0
web/js/util/SelectOption.js

@@ -0,0 +1,232 @@
+/* SelectOption对象 */
+//构造函数

+var SelectOptionHelper = function() {}
+//属性及函数
+SelectOptionHelper.prototype =
+{
+	/* private function */
+	//moveUp和moveDown方法中使用

+	swapOptionProperties:function(option1, option2)
+	{
+		var tempStr = option1.value;
+		option1.value = option2.value;
+		option2.value = tempStr;
+		tempStr = option1.text;
+		option1.text = option2.text;
+		option2.text = tempStr;
+		tempStr = option1.selected;
+		option1.selected = option2.selected;
+		option2.selected = tempStr;
+	},
+	//move和moveAll方法中使用

+	resetAutoWidth:function(obj)
+	{
+		try
+		{
+			var tempWidth = obj.style.getExpression("width");
+			if(tempWidth != null)
+			{
+				obj.style.width = "auto";
+				obj.style.setExpression("width", tempWidth);
+				obj.style.width = null;
+			}
+		}
+		catch(e)
+		{
+		}
+	},
+	/* public function */
+	//添加一个项
+	add:function(toObj, objText, objValue)
+	{
+		toObj.options[toObj.options.length] = new Option(objText, objValue);
+	},
+	//移动选中的项到目标中
+	move:function(fromObj, toObj)
+	{
+		var fromObjOptions = fromObj.options;
+		for( var i = 0;i < fromObjOptions.length;i++)
+		{
+			if(fromObjOptions[i].selected)
+			{
+				toObj.appendChild(fromObjOptions[i]);
+				i--;
+			}
+		}
+		this.resetAutoWidth(fromObj);
+		this.resetAutoWidth(toObj);
+	},
+	//移动所有的项到目标中

+	moveAll:function(fromObj, toObj)
+	{
+		var fromObjOptions = fromObj.options;
+		if(fromObjOptions.length > 1000)
+		{
+			//if(!confirm("Are you sure to move options?")) return false;
+		}
+		for( var i = 0;i < fromObjOptions.length;i++)
+		{
+			fromObjOptions[0].selected = true;
+			toObj.appendChild(fromObjOptions[i]);
+			i--;
+		}
+		this.resetAutoWidth(fromObj);
+		this.resetAutoWidth(toObj);
+	},
+	//移除相应列表的所选项目

+	removeSelectOptions:function(obj)
+	{
+		if(obj.selectedIndex == -1)
+		{
+			alert("未选择任何选项!");
+		}
+		for( var i = obj.length - 1;i >= 0;i--)
+		{
+			if(obj.options[i].selected)
+			{
+				obj.remove(obj.selectedIndex);
+				//obj.appendChild(obj.options[i]);//把当前选中的选项移到最后面
+				//obj.options.length = obj.options.length - 1;//把移到最后面的选项移去
+			}
+		}
+	},
+	//移除相应列表中的所有项目

+	removeAllOptions:function(obj)
+	{
+		obj.options.length = 0;
+	},
+	//添加左边列表中所选项目到右边列表中

+	addSelectOptions:function(objSource, objDestination)
+	{
+		if(objSource.selectedIndex == -1)
+		{
+			alert("未选择任何选项!");
+		}
+		var sourceLen = objSource.options.length;
+		for( var i = 0;i < sourceLen;i++)
+		{
+			if(objSource.options[i].selected)
+			{
+				var optionValue = objSource.options[i].value;
+				if(!this.existOptionByValue(optionValue, objDestination))
+				{
+					var optOption = new Option(objSource.options[i].text, objSource.options[i].value);
+					objDestination.options[objDestination.options.length] = optOption;
+				}
+			}
+		}
+	},
+	//添加左边列表中的全部项目到右边列表

+	addAllOptions:function(objSource, objDes)
+	{
+		if(objSource.options.length == 0)
+		{
+			alert("源列表中无选项可添加!");
+			return;
+		}
+		//清空目标列表
+		objDes.options.length = 0;
+		//添加
+		for( var i = 0;i < objSource.options.length;i++)
+		{
+			var optOption = new Option(objSource.options[i].text, objSource.options[i].value);
+			objDes.options[objDes.options.length] = optOption;
+		}
+	},
+	//判断相应的选项是否在列表中存在
+	existOptionByValue:function(optionValue, obj)
+	{
+		for( var i = 0;i < obj.options.length;i++)
+		{
+			if(optionValue == obj.options[i].value)
+				return true;
+		}
+		return false;
+	},
+	//选中相应列表中的全部项

+	selectAll:function(selectObj)
+	{
+		var theObjOptions = selectObj.options;
+		for( var i = 0;i < theObjOptions.length;i++)
+		{
+			theObjOptions[i].selected = true;
+		}
+	},
+	//取消选中相应列表中的全部项

+	unSelectAll:function(selectObj)
+	{
+		var theObjOptions = selectObj.options;
+		for( var i = 0;i < theObjOptions.length;i++)
+		{
+			theObjOptions[i].selected = false;
+		}
+	},
+	//将选中的项目向上移动若干格
+	moveUp:function(selectObj, count)
+	{
+		var theObjOptions = selectObj.options;
+		for( var c = 0;c < count;c++)
+		{
+			for( var i = 1;i < theObjOptions.length;i++)
+			{
+				if(theObjOptions[i].selected && !theObjOptions[i - 1].selected)
+				{
+					this.swapOptionProperties(theObjOptions[i], theObjOptions[i - 1]);
+				}
+			}
+		}
+	},
+	//将选中的项目向下移动若干格
+	moveDown:function(selectObj, count)
+	{
+		var theObjOptions = selectObj.options;
+		for( var c = 0;c < count;c++)
+		{
+			for( var i = theObjOptions.length - 2;i > -1;i--)
+			{
+				if(theObjOptions[i].selected && !theObjOptions[i + 1].selected)
+				{
+					this.swapOptionProperties(theObjOptions[i], theObjOptions[i + 1]);
+				}
+			}
+		}
+	},
+	//将选中的项目移至最前

+	moveTop:function(selectObj)
+	{
+		var theObjOptions = selectObj.options;
+		var oOption = null;
+		for( var i = 0;i < theObjOptions.length;i++)
+		{
+			if(theObjOptions[i].selected && oOption)
+			{
+				selectObj.insertBefore(theObjOptions[i], oOption);
+			}
+			else if(!oOption && !theObjOptions[i].selected)
+			{
+				oOption = theObjOptions[i];
+			}
+		}
+	},
+	//将选中的项目移至最后

+	moveBottom:function(selectObj)
+	{
+		var theObjOptions = selectObj.options;
+		var oOption = null;
+		for( var i = theObjOptions.length - 1;i > -1;i--)
+		{
+			if(theObjOptions[i].selected)
+			{
+				if(oOption)
+				{
+					oOption = selectObj.insertBefore(theObjOptions[i], oOption);
+				}
+				else
+				{
+					oOption = selectObj.appendChild(theObjOptions[i]);
+				}
+			}
+		}
+	}
+}
+var __SelectOption__ = new SelectOptionHelper();//默认生成一个对象


+ 102 - 0
web/js/util/XMLDom.js

@@ -0,0 +1,102 @@
+var isIe = /msie/i.test(navigator.userAgent);//是否是IE浏览器

+var XMLDom =
+{
+	// 得到xmlDom对象
+	getXMLDom:function()
+	{
+		var axo = null;
+		var MS_XML_DOM = [
+				"MSXML2.DOMDocument",
+				"Microsoft.XMLDOM",
+				"MSXML.DOMDocument",
+				"MSXML3.DOMDocument"
+		];
+		if(isIe)
+		{
+			for( var i = 0;i < 4;i++)
+			{
+				try
+				{
+					axo = new ActiveXObject(MS_XML_DOM[i]);
+					return axo;
+				}
+				catch(e)
+				{
+					return null;
+				}
+			}
+		}
+		else
+			return document.implementation.createDocument("", "doc", null);
+	},
+	// 装载一个XMLDom
+	loadXML:function(url, async, handle)
+	{
+		var xmlDom = XMLDom.getXMLDom();
+		xmlDom.preserveWhiteSpace = true;//兼容FireFox
+		xmlDom.async = (async == true) ? true : false;
+		if(async)
+		{
+			if(isIe)
+				xmlDom.onreadystatechange = function()
+				{
+					if(xmlDom.readyState == 4)
+						handle(xmlDom);
+				};
+			else
+				xmlDom.onload = function()
+				{
+					handle(xmlDom);
+				};
+		}
+		xmlDom.load(url);
+		if(!async)
+			return xmlDom;
+	},
+	// 取得XMLDom对象的xml内容
+	getXML:function(xmlDom)
+	{
+		if(isIe)
+			return xmlDom.xml;
+		else
+			return (new xmlSerializer()).serializeToString(xmlDom);
+	},
+	//得到节点的属性

+	getAttribute:function(pNode, pAttribute)
+	{
+		try
+		{
+			return pNode.attributes.getNamedItem(pAttribute).nodeValue;
+		}
+		catch(e)
+		{
+			return null;
+		}
+	},
+	//根据字符串得到Xml对象
+	loadXmlString:function(strXml)
+	{
+		var xmlDoc;
+		try
+		//Internet Explorer
+		{
+			xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+			xmlDoc.async = "false";
+			xmlDoc.loadXML(strXml);
+		}
+		catch(e)
+		{
+			try
+			//Firefox, Mozilla, Opera, etc.
+			{
+				parser = new DOMParser();
+				xmlDoc = parser.parseFromString(strXml, "text/xml");
+			}
+			catch(e)
+			{
+				alert(e.message);
+			}
+		}
+		return xmlDoc;
+	}
+};

+ 32 - 0
web/js/util/bak/CustomerWindow.js

@@ -0,0 +1,32 @@
+Namespace.register("com.hotent.ui");  
+com.hotent.ui.Window = function(title,width,height){     
+	{
+		var x=($(document.body).width()-width) /2;
+		dhxWins = new dhtmlXWindows();
+		dhxWins.setSkin("dhx_skyblue");
+		dhxWins.attachEvent("onClose", function(win){
+			 win.hide();
+		});
+		this.win = dhxWins.createWindow("win", x, 0, width, height);
+		this.win.setText(title);
+	}
+	
+    this.show=function()
+    {
+    	this.win.show();
+    },
+    this.hide=function()
+    {
+    	this.win.hide();
+    },
+    this.attachUrl=function(url)
+    {
+    	this.win.attachURL(url);
+    };
+    this.attachObject=function(url)
+    {
+    	this.win.attachObject(url);
+    };
+};
+    
+    

+ 112 - 0
web/js/util/bak/dialog.js

@@ -0,0 +1,112 @@
+Namespace.register("com.hotent.ui");  
+var _divDialog=1;
+com.hotent.ui.Dialog = function(title,width,height){     
+	{
+		this.okHandler=null;
+		this.id="div_" +_divDialog;
+		var x=($(document.body).width()-width) /2;
+		
+		this.witdh=width;
+		this.height=height;
+		this.divWidth=this.width -20;
+		this.divHeight=this.height -40;
+		
+		this.containHeight=this.divHeight-30;
+		var str="<div style='position: relative;height:"+this.divHeight+"px;width:100%;'>" +
+				"<div  id='"+this.id+"' style=' height:"+this.containHeight+"px;width:100%;'></div>"+
+				"<div class='dialogButton'>" +
+					"<a href='#' id='btnOK_"+ _divDialog +"' class='button'><span class='left'></span><span class='right'>确定</span></a>&nbsp;&nbsp;" +
+					"<a href='#' id='btnCancel_"+ _divDialog +"' class='button' style='margin-right:20px;'><span class='left'></span><span class='right'>取消</span></a>" +
+				"</div>"+
+				"</div>";
+		this.dhxWins = new dhtmlXWindows();
+		this.dhxWins.setSkin("dhx_skyblue");
+	
+		this.win = this.dhxWins.createWindow("win",x, 0, width, height);
+		this.win.setText(title);
+		this.win.denyResize();
+		this.win.allowMove();
+		
+		this.win.button("minmax1").hide();
+		this.win.attachHTMLString(str);
+		
+		var self=this;
+		
+		this.dhxWins.attachEvent("onClose", function(win){
+			 self.close();
+		});
+	
+		
+		$("#btnCancel_" + _divDialog).click(function(){
+			self.close();
+		});
+		
+		$("#btnOK_" + _divDialog).click(function(){
+			if(self.okHandler!=null){
+				self.okHandler(self );
+				self.close();
+			}
+		});
+		
+		_divDialog++;
+	}
+	//设置事件处理
+	this.setHandler=function(hanler)
+	{
+		this.okHandler=hanler;
+	},
+	//隐藏对话框
+	this.hide=function()
+	{
+		var isModal = this.win.isModal(); 
+		if(isModal)
+			this.win.setModal(false);
+		this.win.hide();
+	},	
+	//显示对话框
+    this.show=function()
+    {
+    	this.win.setModal(true);
+    	this.win.show();
+    },
+    //关闭对话框
+    this.close=function()
+    {
+    	this.win.setModal(false);
+    	//this.win.close();
+    	this.dhxWins.unload();
+    },
+    //显示一个页面的DIV
+    this.attachObject=function(objId)
+    {
+    	var obj=$("#" + objId);
+    	obj.show();
+    	$("#" + this.id).append(obj);
+    },
+    //显示一个URL页面
+    this.attachUrl=function(url)
+    {
+    	var frameId="_frame_" + _divDialog;
+    	var url=url.getNewUrl();
+    	var len=$("#" + frameId).length;
+    	if(len==0)
+    	{
+    		var str="<iframe frameborder='0' id='"+frameId+"' src='"+url+"'  width='100%' height='"+(this.divHeight-45)+"' ></iframe>";
+    		$("#" + this.id).append(str);
+    	}
+    	else{
+    		$("#" + frameId).attr("src",url);
+    	}
+    },
+    //获取IFRAME
+    //IFRAME 中有个函数getFile
+    //var iframe=winPic.getIframe();
+	//var src=iframe.getFile();
+    this.getIframe=function()
+    {
+    	var frameId="_frame_" + _divDialog;
+    	return obj=document.frames[frameId];
+    }
+};
+    
+    

+ 3 - 0
web/js/util/demo/js2.js

@@ -0,0 +1,3 @@
+function js2(msg){
+	alert(msg);
+	}

+ 26 - 0
web/js/util/demo/loadjsdemo.htm

@@ -0,0 +1,26 @@
+<html>
+	<head>
+	<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+	 <script type="text/javascript" src="../loadjscss.js"></script>
+	
+
+    <script>
+    function window.onload(){
+    	JsLoader.LoadCount=2;
+    	JsLoader.Load("demo/js1.js","javascript1");
+    	JsLoader.Load("demo/js2.js","javascript2");
+    	JsLoader.OnLoad=loadComplete;
+    }
+    
+    function loadComplete(){
+    	msgbox("js1");
+    	js2("loadComplete");
+    }
+    </script>
+</head>
+<body>
+
+</body>
+</html>

+ 55 - 0
web/js/util/easyTemplate.js

@@ -0,0 +1,55 @@
+var easyTemplate = function(s,d){
+	if(!s){return '';}
+	if(s!==easyTemplate.template){
+		easyTemplate.template = s;
+		easyTemplate.aStatement = easyTemplate.parsing(easyTemplate.separate(s));
+	}
+	var aST = easyTemplate.aStatement;
+	var process = function(d2){
+		if(d2){d = d2;}
+		return arguments.callee;
+	};
+	process.toString = function(){
+		return (new Function(aST[0],aST[1]))(d);
+	};
+	return process;
+};
+easyTemplate.separate = function(s){
+	var r = /\\'/g;
+	var sRet = s.replace(/(<(\/?)#(.*?(?:\(.*?\))*)>)|(')|([\r\n\t])|(\$\{([^\}]*?)\})/g,function(a,b,c,d,e,f,g,h){
+		if(b){return '{|}'+(c?'-':'+')+d+'{|}';}
+		if(e){return '\\\'';}
+		if(f){return '';}
+		if(g){return '\'+('+h.replace(r,'\'')+')+\'';}
+	});
+	return sRet;
+};
+easyTemplate.parsing = function(s){
+	var mName,vName,sTmp,aTmp,sFL,sEl,aList,aStm = ['var aRet = [];'];
+	aList = s.split(/\{\|\}/);
+	var r = /\s/;
+	while(aList.length){
+		sTmp = aList.shift();
+		if(!sTmp){continue;}
+		sFL = sTmp.charAt(0);
+		if(sFL!=='+'&&sFL!=='-'){
+			sTmp = '\''+sTmp+'\'';aStm.push('aRet.push('+sTmp+');');
+			continue;
+		}
+		aTmp = sTmp.split(r);
+		switch(aTmp[0]){
+			case '+macro':mName = aTmp[1];vName = aTmp[2];aStm.push('aRet.push("<!--'+mName+' start--\>");');break;
+			case '-macro':aStm.push('aRet.push("<!--'+mName+' end--\>");');break;
+			case '+if':aTmp.splice(0,1);aStm.push('if'+aTmp.join(' ')+'{');break;
+			case '+elseif':aTmp.splice(0,1);aStm.push('}else if'+aTmp.join(' ')+'{');break;
+			case '-if':aStm.push('}');break;
+			case '+else':aStm.push('}else{');break;
+			case '+list':aStm.push('if('+aTmp[1]+'&&'+aTmp[1]+'.constructor === Array){with({i:0,l:'+aTmp[1]+'.length,'+aTmp[3]+'_index:0,'+aTmp[3]+':null}){for(i=l;i--;){'+aTmp[3]+'_index=(l-i-1);'+aTmp[3]+'='+aTmp[1]+'['+aTmp[3]+'_index];');break;
+			case '-list':aStm.push('}}}');break;
+			default:break;
+		}
+	}
+	aStm.push('return aRet.join("");');
+	if(!vName){aStm.unshift('var data = arguments[0];');}
+	return [vName,aStm.join('')];
+};

+ 194 - 0
web/js/util/form.js

@@ -0,0 +1,194 @@
+Namespace.register("com.hotent.form");  
+/**
+ * 动态创建form类。
+ * 使用方法如下:
+ * var frm=new com.hotent.form.Form();
+ * frm.creatForm("表单名","提交到的页面");
+ *清除表单元素
+ * frm.clearFormEl();
+ * 添加需要提交的表单元素。
+ * frm.addFormEl("name","value");
+ * 表单提交
+ * frm.submit();
+ */
+com.hotent.form.Form=function(){
+	this.creatForm=function(formName,action)
+	{
+		var  frm=document.getElementById(formName);
+		if(frm==null || frm==undefined){
+			frm = document.createElement("FORM");  
+			document.body.appendChild(frm);  
+		}
+		//frm.action=action;
+		this.form=frm;
+		this.form.method="post";
+		this.parseAction(action);
+	};
+	
+	this.parseAction=function( _action_){
+		var idx=_action_.indexOf("?");
+		if(idx==-1){
+			this.form.action=_action_;
+		}
+		else{
+			var aryStr=_action_.split("?");
+			var action=aryStr[0];
+			this.form.action=action;
+			var queryString=aryStr[1];
+			var aryQ=queryString.split("&");
+			for(var i=0;i<aryQ.length;i++){
+				var pv=aryQ[i].split("=");
+				this.addFormEl(pv[0],pv[1]);
+			}
+		}
+		
+	}
+	
+	
+	/**
+	 * 设置方法
+	 * 值:get,post
+	 */
+	this.setMethod=function(_method){
+		this.form.method=_method;
+	};
+	
+	this.setTarget=function(_target){
+		this.form.target=_target;
+	};
+	
+	this.clearFormEl=function()
+	{
+		var childs=this.form.childNodes;
+		for(var i=childs.length-1;i>=0;i--){
+			var node=childs[i];
+			this.form.removeNode(node);
+		}
+	};
+	/**
+	 * 添加字段
+	 */
+	this.addFormEl=function(name,value){
+		 var el = document.createElement("input");  
+		 el.setAttribute("name",name);  
+		 el.setAttribute("type","hidden");  
+		 el.setAttribute("value",value);  
+		 this.form.appendChild(el);  
+	};
+	
+	this.submit=function(){
+		this.form.submit();
+	};
+};
+
+var FormSubmitUtil={
+		
+		getFormData:function(){
+			var json = {};
+			
+			$("input:text[include],input:hidden[include],textarea[include],select[include]").each(function() {
+				var name = $(this).attr('name');
+				var value=$(this).val();
+				if(json[name]){
+					json[name]+=","+value;
+				}else{
+					json[name]=value;
+				}
+			});
+			//设置radio。
+			var operatorObj = $('input[include]:radio');
+			FormSubmitUtil.setRadioData(json, operatorObj);
+			//遍历checkbox
+			operatorObj = $('input[include]:checkbox');
+			var checkedObj = $('input[include]:checkbox:checked');
+			
+			FormSubmitUtil.setCheckBoxData(json,operatorObj,checkedObj);
+			
+			return json;
+		},
+		/**
+		 * form :表单form
+		 * 把表单以ajax的方式提交上去,
+		 * callback是成功时的回调函数
+		 * handData : 在提交之前处理表单json数据。
+		 */
+		submitFormAjax : function(form,callback,handFormJson){
+			var formObj=$(form);
+			var url = $(form).attr("action");
+			var json =FormSubmitUtil. getFormData();
+			//在提交之前对数据进行处理。
+			if(handFormJson){
+				handFormJson(json);
+			}
+			
+			$.post(url,json,function(data){
+				callback(data);
+			});
+		},
+		setRadioData:function(dataObj, operatorObj){
+			$(operatorObj).each(function() {
+				var name = $(this).attr('name');
+				var value= $(this).val();
+				
+				if($(this).attr("checked")!=undefined){
+					dataObj[name]=value;
+				}
+			});
+		},
+		setCheckBoxData:function(dataObj, operatorObj, checkedObj){
+			//将所有复选框选址清空。
+			$(operatorObj).each(function() {
+				var name = $(this).attr('name');
+				dataObj[name]="";
+			});
+			//复选框取值。
+			$(checkedObj).each(function() {
+				var name = $(this).attr('name');
+				var value= $(this).val();
+				if(dataObj[name]==""){
+					dataObj[name]=value;
+				} else{
+					dataObj[name]+="," + value;
+				}
+			});
+		},
+		/**
+		 * 清除表单某个范围内的全部提交信息。
+		 * 也就是把scope内的input select textarea的name都制空
+		 */
+		clearSubmitElement:function(scope){
+			$(scope).find("input[name],select[name],textarea[name]").each(function(){
+				$(this).attr("name","");
+			});
+		}
+}
+    
+/**
+ * ResponseObject对象
+ * @param data
+ */
+com.hotent.form.ResultMessage = function(data) {
+	{
+		this.data = eval('(' + data + ')');
+	}
+
+	
+	/**
+	 * 操作是否成功
+	 * @returns {Boolean}
+	 */
+	this.isSuccess = function() {
+		return this.data['result'] == 1;
+	};
+
+	
+	/**
+	 * 获取响应信息
+	 * @returns
+	 */
+	this.getMessage = function() {
+		return this.data['message'];
+	};
+};
+
+

+ 482 - 0
web/js/util/json2.js

@@ -0,0 +1,482 @@
+/*
+    http://www.JSON.org/json2.js
+    2010-03-20
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON2.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON2.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON2.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON2.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON2.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON2.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON2.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON2.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON2) {
+    this.JSON2 = {};
+}
+
+(function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                   this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON2.stringify !== 'function') {
+        JSON2.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON2.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON2.parse !== 'function') {
+        JSON2.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON2.parse');
+        };
+    }
+}());

+ 94 - 0
web/js/util/loadjscss.js

@@ -0,0 +1,94 @@
+/**
+ * 功能:
+ * 动态加载js和css文件。
+ * 具体的使用方法见:
+ * demo/loadjsdemo.htm
+ */
+var JsLoader={
+	//预计加载个数
+	LoadCount:0,
+	//已经加载个数
+	LoaderNumber:0,
+	Load:function(js,id,callback){
+		var scriptId = document.getElementById(id);
+	    if (scriptId) {
+	        if (callback)
+	                callback();
+	        JsLoader.LoaderNumber+=1;
+	        //加载个数大于或等于预计加载个数,则触发加载完毕事件
+	        if (JsLoader.LoaderNumber >= JsLoader.LoadCount){
+	            if (JsLoader.OnLoad)
+	                JsLoader.OnLoad();
+	        }
+	    }
+	    else {
+	        var script = document.createElement("script");
+	        script.id = id;
+	        script.type = "text/javascript";
+	        
+	        script.onload = script.onreadystatechange = function(){
+	            if (script.readyState && script.readyState != 'loaded' && script.readyState != 'complete'){
+	                return;
+	            }
+	            script.onreadystatechange = script.onload = null;
+	            //当前文件加载完毕,触发回调事件
+	            if (callback)
+	                callback();
+	            JsLoader.LoaderNumber+=1;
+	            //加载个数大于或等于预计加载个数,则触发加载完毕事件
+	            if (JsLoader.LoaderNumber >= JsLoader.LoadCount)
+	                if (JsLoader.OnLoad)
+	                    JsLoader.OnLoad();
+	        };
+	        script.src = js;
+	        var head = document.getElementsByTagName('head').item(0);
+	        head.appendChild (script);
+	    }
+	}
+};
+
+
+
+/*Css 动态加载*/
+var CssLoader={
+	//预计加载个数
+	LoadCount:0,
+	LoaderNumber:0,
+	Load:function(css,id,callback){
+		 var cssId = document.getElementById(id);
+		    if (cssId) {
+		        if (callback)
+		            callback();
+		        CssLoader.LoaderNumber+=1;
+		        //加载个数大于或等于预计加载个数,则触发加载完毕事件
+		        if (CssLoader.LoaderNumber >= CssLoader.LoadCount)
+		            if (CssLoader.OnLoad)
+		                CssLoader.OnLoad();
+		    }
+		    else{
+		        var link = document.createElement("link");
+		        link.id = id;
+		        link.rel="stylesheet";
+		        link.type = "text/css";
+		        
+		        link.onload = link.onreadystatechange = function(){
+		            if (link.readyState && link.readyState != 'loaded' && link.readyState != 'complete'){
+		                return;
+		            }
+		            link.onreadystatechange = link.onload = null;
+		            //当前文件加载完毕,触发回调事件
+		            if (callback)
+		                callback();
+		            CssLoader.LoaderNumber+=1;
+		            //加载个数大于或等于预计加载个数,则触发加载完毕事件
+		            if (CssLoader.LoaderNumber >= CssLoader.LoadCount)
+		                if (CssLoader.OnLoad)
+		                    CssLoader.OnLoad();
+		        };
+		        link.src = css;
+		        var head = document.getElementsByTagName('head').item(0);
+		        head.appendChild (link);
+		    }
+	}
+};
+

+ 35 - 0
web/js/util/sqlUtil.js

@@ -0,0 +1,35 @@
+/**
+ * sql语句的工具类
+ */
+var SqlUtil = {
+	//系统引入语句:<script type="text/javascript" src="${ctx}/js/util/sqlUtil.js"></script>
+	//检查sql合法性
+	//sql:sql语句
+	//dsalias:数据源别名,默认本地数据源
+	//rollback:执行语句后是否回滚,默认true
+	//callback:返回函数----注意,当为空时,默认是一个提示函数
+	checkValidity : function(sql,dsalias,rollback,callback){
+		var params = {
+			sql : sql,
+			dsalias : dsalias,
+			rollback:rollback
+		};
+		if(!callback){
+			callback=function(data){
+				if (data) {
+					$.ligerDialog.success('<p><font color="green">验证通过!<br></font></p>');
+				}else {
+					$.ligerDialog.error('<p><font color="red">验证不通过!<br></font></p>');
+				}
+			}
+		}
+		$.ajax({
+		      url: __ctx+'/platform/system/sysQuerySqlDef/validSql.ht',
+		      type: 'POST',
+		      dataType: 'json',
+		      data:params,
+		      async:true,
+		      success: callback
+      	});
+	}
+}

+ 319 - 0
web/js/util/tablednd.js

@@ -0,0 +1,319 @@
+//功能:拖动表格进行排序。
+//使用方法:
+//包含JS:<script type="text/javascript" src="${ctx }/js/jquery/tablednd.js"></script>
+//$(document).ready(function() {
+//            $("#table").tableDnD({
+//                onDrop: sort
+//            });
+//});
+//function sort()
+//{
+//		$(":checkbox[name=id]").each(function(){
+//		var obj=$(this);
+//		str+=obj.val() +",";
+//		});
+//}
+jQuery.tableDnD = {
+    /** Keep hold of the current table being dragged */
+    currentTable : null,
+    /** Keep hold of the current drag object if any */
+    dragObject: null,
+    /** The current mouse offset */
+    mouseOffset: null,
+    /** Remember the old value of Y so that we don't do too much processing */
+    oldY: 0,
+
+    /** Actually build the structure */
+    build: function(options) {
+        // Set up the defaults if any
+
+        this.each(function() {
+            // This is bound to each matching table, set up the defaults and override with user options
+            this.tableDnDConfig = jQuery.extend({
+                onDragStyle: null,
+                onDropStyle: null,
+				// Add in the default class for whileDragging
+				onDragClass: "tDnD_whileDrag",
+                onDrop: null,
+                onDragStart: null,
+                scrollAmount: 5,
+				serializeRegexp: /[^\-]*$/, // The regular expression to use to trim row IDs
+				serializeParamName: null, // If you want to specify another parameter name instead of the table ID
+                dragHandle: null // If you give the name of a class here, then only Cells with this class will be draggable
+            }, options || {});
+            // Now make the rows draggable
+            jQuery.tableDnD.makeDraggable(this);
+        });
+
+        // Now we need to capture the mouse up and mouse move event
+        // We can use bind so that we don't interfere with other event handlers
+        jQuery(document)
+            .bind('mousemove', jQuery.tableDnD.mousemove)
+            .bind('mouseup', jQuery.tableDnD.mouseup);
+
+        // Don't break the chain
+        return this;
+    },
+
+    /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
+    makeDraggable: function(table) {
+        var config = table.tableDnDConfig;
+		if (table.tableDnDConfig.dragHandle) {
+			// We only need to add the event to the specified cells
+			var cells = jQuery("td."+table.tableDnDConfig.dragHandle, table);
+			cells.each(function() {
+				// The cell is bound to "this"
+                jQuery(this).mousedown(function(ev) {
+                    jQuery.tableDnD.dragObject = this.parentNode;
+                    jQuery.tableDnD.currentTable = table;
+                    jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
+                    if (config.onDragStart) {
+                        // Call the onDrop method if there is one
+                        config.onDragStart(table, this);
+                    }
+                    return false;
+                });
+			})
+		} else {
+			// For backwards compatibility, we add the event to the whole row
+	        var rows = jQuery("tr", table); // get all the rows as a wrapped set
+	        rows.each(function() {
+				// Iterate through each row, the row is bound to "this"
+				var row = jQuery(this);
+				if (! row.hasClass("nodrag")) {
+	                row.mousedown(function(ev) {
+	                    if (ev.target.tagName == "TD") {
+	                        jQuery.tableDnD.dragObject = this;
+	                        jQuery.tableDnD.currentTable = table;
+	                        jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev);
+	                        if (config.onDragStart) {
+	                            // Call the onDrop method if there is one
+	                            config.onDragStart(table, this);
+	                        }
+	                        return false;
+	                    }
+	                }).css("cursor", "move"); // Store the tableDnD object
+				}
+			});
+		}
+	},
+
+	updateTables: function() {
+		this.each(function() {
+			// this is now bound to each matching table
+			if (this.tableDnDConfig) {
+				jQuery.tableDnD.makeDraggable(this);
+			}
+		})
+	},
+
+    /** Get the mouse coordinates from the event (allowing for browser differences) */
+    mouseCoords: function(ev){
+        if(ev.pageX || ev.pageY){
+            return {x:ev.pageX, y:ev.pageY};
+        }
+        return {
+            x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
+            y:ev.clientY + document.body.scrollTop  - document.body.clientTop
+        };
+    },
+
+    /** Given a target element and a mouse event, get the mouse offset from that element.
+        To do this we need the element's position and the mouse position */
+    getMouseOffset: function(target, ev) {
+        ev = ev || window.event;
+
+        var docPos    = this.getPosition(target);
+        var mousePos  = this.mouseCoords(ev);
+        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
+    },
+
+    /** Get the position of an element by going up the DOM tree and adding up all the offsets */
+    getPosition: function(e){
+        var left = 0;
+        var top  = 0;
+        /** Safari fix -- thanks to Luis Chato for this! */
+        if (e.offsetHeight == 0) {
+            /** Safari 2 doesn't correctly grab the offsetTop of a table row
+            this is detailed here:
+            http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
+            the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
+            note that firefox will return a text node as a first child, so designing a more thorough
+            solution may need to take that into account, for now this seems to work in firefox, safari, ie */
+            e = e.firstChild; // a table cell
+        }
+
+        while (e.offsetParent){
+            left += e.offsetLeft;
+            top  += e.offsetTop;
+            e     = e.offsetParent;
+        }
+
+        left += e.offsetLeft;
+        top  += e.offsetTop;
+
+        return {x:left, y:top};
+    },
+
+    mousemove: function(ev) {
+        if (jQuery.tableDnD.dragObject == null) {
+            return;
+        }
+
+        var dragObj = jQuery(jQuery.tableDnD.dragObject);
+        var config = jQuery.tableDnD.currentTable.tableDnDConfig;
+        var mousePos = jQuery.tableDnD.mouseCoords(ev);
+        var y = mousePos.y - jQuery.tableDnD.mouseOffset.y;
+        //auto scroll the window
+	    var yOffset = window.pageYOffset;
+	 	if (document.all) {
+	        // Windows version
+	        //yOffset=document.body.scrollTop;
+	        if (typeof document.compatMode != 'undefined' &&
+	             document.compatMode != 'BackCompat') {
+	           yOffset = document.documentElement.scrollTop;
+	        }
+	        else if (typeof document.body != 'undefined') {
+	           yOffset=document.body.scrollTop;
+	        }
+
+	    }
+		    
+		if (mousePos.y-yOffset < config.scrollAmount) {
+	    	window.scrollBy(0, -config.scrollAmount);
+	    } else {
+            var windowHeight = window.innerHeight ? window.innerHeight
+                    : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
+            if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) {
+                window.scrollBy(0, config.scrollAmount);
+            }
+        }
+
+
+        if (y != jQuery.tableDnD.oldY) {
+            // work out if we're going up or down...
+            var movingDown = y > jQuery.tableDnD.oldY;
+            // update the old value
+            jQuery.tableDnD.oldY = y;
+            // update the style to show we're dragging
+			if (config.onDragClass) {
+				dragObj.addClass(config.onDragClass);
+			} else {
+	            dragObj.css(config.onDragStyle);
+			}
+            // If we're over a row then move the dragged row to there so that the user sees the
+            // effect dynamically
+            var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y);
+            if (currentRow) {
+                // TODO worry about what happens when there are multiple TBODIES
+                if (movingDown && jQuery.tableDnD.dragObject != currentRow) {
+                    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling);
+                } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) {
+                    jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow);
+                }
+            }
+        }
+
+        return false;
+    },
+
+    /** We're only worried about the y position really, because we can only move rows up and down */
+    findDropTargetRow: function(draggedRow, y) {
+        var rows = jQuery.tableDnD.currentTable.rows;
+        for (var i=0; i<rows.length; i++) {
+            var row = rows[i];
+            var rowY    = this.getPosition(row).y;
+            var rowHeight = parseInt(row.offsetHeight)/2;
+            if (row.offsetHeight == 0) {
+                rowY = this.getPosition(row.firstChild).y;
+                rowHeight = parseInt(row.firstChild.offsetHeight)/2;
+            }
+            // Because we always have to insert before, we need to offset the height a bit
+            if ((y > rowY - rowHeight) && (y < (rowY + rowHeight))) {
+                // that's the row we're over
+				// If it's the same as the current row, ignore it
+				if (row == draggedRow) {return null;}
+                var config = jQuery.tableDnD.currentTable.tableDnDConfig;
+                if (config.onAllowDrop) {
+                    if (config.onAllowDrop(draggedRow, row)) {
+                        return row;
+                    } else {
+                        return null;
+                    }
+                } else {
+					// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
+                    var nodrop = jQuery(row).hasClass("nodrop");
+                    if (! nodrop) {
+                        return row;
+                    } else {
+                        return null;
+                    }
+                }
+                return row;
+            }
+        }
+        return null;
+    },
+
+    mouseup: function(e) {
+        if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) {
+            var droppedRow = jQuery.tableDnD.dragObject;
+            var config = jQuery.tableDnD.currentTable.tableDnDConfig;
+            // If we have a dragObject, then we need to release it,
+            // The row will already have been moved to the right place so we just reset stuff
+			if (config.onDragClass) {
+	            jQuery(droppedRow).removeClass(config.onDragClass);
+			} else {
+	            jQuery(droppedRow).css(config.onDropStyle);
+			}
+            jQuery.tableDnD.dragObject   = null;
+            if (config.onDrop) {
+                // Call the onDrop method if there is one
+                config.onDrop(jQuery.tableDnD.currentTable, droppedRow);
+            }
+            jQuery.tableDnD.currentTable = null; // let go of the table too
+        }
+    },
+
+    serialize: function() {
+        if (jQuery.tableDnD.currentTable) {
+            return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable);
+        } else {
+            return "Error: No Table id set, you need to set an id on your table and every row";
+        }
+    },
+
+	serializeTable: function(table) {
+        var result = "";
+        var tableId = table.id;
+        var rows = table.rows;
+        for (var i=0; i<rows.length; i++) {
+            if (result.length > 0) result += "&";
+            var rowId = rows[i].id;
+            if (rowId && rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
+                rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
+            }
+
+            result += tableId + '[]=' + rowId;
+        }
+        return result;
+	},
+
+	serializeTables: function() {
+        var result = "";
+        this.each(function() {
+			// this is now bound to each matching table
+			result += jQuery.tableDnD.serializeTable(this);
+		});
+        return result;
+    }
+
+}
+
+jQuery.fn.extend(
+	{
+		tableDnD : jQuery.tableDnD.build,
+		tableDnDUpdate : jQuery.tableDnD.updateTables,
+		tableDnDSerialize: jQuery.tableDnD.serializeTables
+	}
+);