caixiangyi 9 vuotta sitten
commit
629d58add0
100 muutettua tiedostoa jossa 14123 lisäystä ja 0 poistoa
  1. 32 0
      x_attendance_assemble_control/.classpath
  2. 17 0
      x_attendance_assemble_control/.project
  3. 12 0
      x_attendance_assemble_control/.settings/org.eclipse.jdt.core.prefs
  4. 191 0
      x_attendance_assemble_control/jest/ajaxfileupload.js
  5. 26 0
      x_attendance_assemble_control/jest/common.js
  6. 105 0
      x_attendance_assemble_control/jest/data.js
  7. 44 0
      x_attendance_assemble_control/jest/do_statistic.html
  8. 17 0
      x_attendance_assemble_control/jest/do_statistic.js
  9. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceAdmin.html
  10. 56 0
      x_attendance_assemble_control/jest/entity_AttendanceAdmin.js
  11. 77 0
      x_attendance_assemble_control/jest/entity_AttendanceAppeal.html
  12. 82 0
      x_attendance_assemble_control/jest/entity_AttendanceAppeal.js
  13. 90 0
      x_attendance_assemble_control/jest/entity_AttendanceDetail.html
  14. 124 0
      x_attendance_assemble_control/jest/entity_AttendanceDetail.js
  15. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceDetailFileImport.html
  16. 61 0
      x_attendance_assemble_control/jest/entity_AttendanceDetailFileImport.js
  17. 70 0
      x_attendance_assemble_control/jest/entity_AttendanceImportFileInfo.html
  18. 71 0
      x_attendance_assemble_control/jest/entity_AttendanceImportFileInfo.js
  19. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceScheduleSetting.html
  20. 56 0
      x_attendance_assemble_control/jest/entity_AttendanceScheduleSetting.js
  21. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceSelfHoliday.html
  22. 56 0
      x_attendance_assemble_control/jest/entity_AttendanceSelfHoliday.js
  23. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceSetting.html
  24. 56 0
      x_attendance_assemble_control/jest/entity_AttendanceSetting.js
  25. 58 0
      x_attendance_assemble_control/jest/entity_AttendanceWorkDayConfig.html
  26. 56 0
      x_attendance_assemble_control/jest/entity_AttendanceWorkDayConfig.js
  27. 88 0
      x_attendance_assemble_control/jest/index.html
  28. 1 0
      x_attendance_assemble_control/jest/jquery.js
  29. 94 0
      x_attendance_assemble_control/jest/showStatistic.html
  30. 62 0
      x_attendance_assemble_control/jest/showStatistic.js
  31. 48 0
      x_attendance_assemble_control/jest/test.html
  32. 71 0
      x_attendance_assemble_control/jest/test.js
  33. 45 0
      x_attendance_assemble_control/jest/uuid.html
  34. 833 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java
  35. 278 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/Excel2003Reader.java
  36. 211 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/Excel2007Reader.java
  37. 31 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/ExcelReaderUtil.java
  38. 13 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/IRowReader.java
  39. 213 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/UserModelEventListener.java
  40. 225 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/AbstractExcel2007Writer.java
  41. 62 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/Excel2003Writer.java
  42. 49 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/Excel2007WriterImpl.java
  43. 48 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/XMLEncoder.java
  44. 24 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/AbstractFactory.java
  45. 11 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ApplicationGobal.java
  46. 18 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ApplicationServletContextListener.java
  47. 199 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/Business.java
  48. 17 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/CacheUtil.java
  49. 7 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/MimeTypeDefinition.java
  50. 38 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java
  51. 54 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceAdminFactory.java
  52. 518 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceAppealInfoFactory.java
  53. 881 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailFactory.java
  54. 126 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailMobileFactory.java
  55. 927 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailStatisticFactory.java
  56. 73 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceEmployeeConfigFactory.java
  57. 59 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceImportFileInfoFactory.java
  58. 92 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceScheduleSettingFactory.java
  59. 265 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSelfHolidayFactory.java
  60. 91 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSettingFactory.java
  61. 131 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceStatisticRequireLogFactory.java
  62. 79 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceStatisticalCycleFactory.java
  63. 234 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceWorkDayConfigFactory.java
  64. 293 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticCompanyForDayFactory.java
  65. 274 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticCompanyForMonthFactory.java
  66. 353 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticDepartmentForDayFactory.java
  67. 878 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticDepartmentForMonthFactory.java
  68. 663 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticPersonForMonthFactory.java
  69. 50 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/ActionApplication.java
  70. 33 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/AttendanceJaxrsFilter.java
  71. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/AttendanceSimpleJaxrsFilter.java
  72. 39 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/DateRecord.java
  73. 40 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/WrapOutMessage.java
  74. 210 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/AttendanceAdminAction.java
  75. 24 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapInAttendanceAdmin.java
  76. 33 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapInFilter.java
  77. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapOutAttendanceAdmin.java
  78. 558 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/AttendanceAppealInfoAction.java
  79. 24 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInAttendanceAppealInfo.java
  80. 43 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInFilter.java
  81. 123 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInFilterAppeal.java
  82. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapOutAttendanceAppealInfo.java
  83. 18 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceCycles.java
  84. 1164 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceDetailAction.java
  85. 382 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceDetailMobileAction.java
  86. 17 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetail.java
  87. 120 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailMobile.java
  88. 65 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailMobileQuery.java
  89. 55 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailRecive.java
  90. 182 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInFilter.java
  91. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapOutAttendanceDetail.java
  92. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapOutAttendanceDetailMobile.java
  93. 218 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/AttendanceEmployeeConfigAction.java
  94. 24 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapInAttendanceEmployeeConfig.java
  95. 33 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapInFilter.java
  96. 16 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapOutAttendanceEmployeeConfig.java
  97. 171 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/AttendanceImportFileInfoAction.java
  98. 24 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapInAttendanceImportFileInfo.java
  99. 33 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapInFilter.java
  100. 20 0
      x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapOutAttendanceImportFileInfo.java

+ 32 - 0
x_attendance_assemble_control/.classpath

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/test/java"/>
+	<classpathentry kind="src" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/collections4/commons-collections4-4.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/lang3/commons-lang3-3.4.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/google/gson/gson-2.7.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/javax/javaee-api-7.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/net/commons-net-3.3.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/fileupload/commons-fileupload-1.3.1.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/io/commons-io-2.4.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/imgscalr/imgscalr-lib-4.2.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/codec/commons-codec-1.8.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/xmlbeans-2.6.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/store/jars/x_collaboration_core_entity-4.0.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/store/jars/x_collaboration_core_message-4.0.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/store/jars/x_attendance_core_entity-4.0.0.jar" sourcepath="/x_attendance_core_entity"/>
+	<classpathentry kind="lib" path="D:/x/lib/slf4j/slf4j-api-1.7.21.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/openjpa/openjpa-2.4.2-SNAPSHOT.jar"/>
+	<classpathentry kind="lib" path="D:/x/store/jars/x_base_core_project-4.0.0.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/curvesapi-1.04.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/poi-3.15-beta2.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/poi-excelant-3.15-beta2.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/poi-ooxml-3.15-beta2.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/poi/poi-ooxml-schemas-3.15-beta2.jar"/>
+	<classpathentry kind="lib" path="D:/x/lib/apache/commons/beanutils/commons-beanutils-1.8.3.jar"/>
+	<classpathentry kind="lib" path="D:/x/store/jars/x_organization_core_express-4.0.0.jar" sourcepath="/x_organization_core_express"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>

+ 17 - 0
x_attendance_assemble_control/.project

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>x_attendance_assemble_control</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

+ 12 - 0
x_attendance_assemble_control/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8

+ 191 - 0
x_attendance_assemble_control/jest/ajaxfileupload.js

@@ -0,0 +1,191 @@
+
+jQuery.extend({
+	
+
+    createUploadIframe: function(id, uri)
+	{
+			//create frame
+            var frameId = 'jUploadFrame' + id;
+            var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
+			if(window.ActiveXObject)
+			{
+                if(typeof uri== 'boolean'){
+					iframeHtml += ' src="' + 'javascript:false' + '"';
+
+                }
+                else if(typeof uri== 'string'){
+					iframeHtml += ' src="' + uri + '"';
+
+                }	
+			}
+			iframeHtml += ' />';
+			jQuery(iframeHtml).appendTo(document.body);
+
+            return jQuery('#' + frameId).get(0);			
+    },
+    createUploadForm: function(id, fileElementId)
+	{
+		//create form	
+		var formId = 'jUploadForm' + id;
+		var fileId = 'jUploadFile' + id;
+		var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');	
+		var oldElement = jQuery('#' + fileElementId);
+		var newElement = jQuery(oldElement).clone();
+		jQuery(oldElement).attr('id', fileId);
+		jQuery(oldElement).before(newElement);
+		jQuery(oldElement).appendTo(form);
+		//set attributes
+		jQuery(form).css('position', 'absolute');
+		jQuery(form).css('top', '-1200px');
+		jQuery(form).css('left', '-1200px');
+		jQuery(form).appendTo('body');		
+		return form;
+    },
+
+    ajaxFileUpload: function(s) {
+        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout		
+        s = jQuery.extend({}, jQuery.ajaxSettings, s);
+        var id = new Date().getTime()        
+		var form = jQuery.createUploadForm(id, s.fileElementId);
+		var io = jQuery.createUploadIframe(id, s.secureuri);
+		var frameId = 'jUploadFrame' + id;
+		var formId = 'jUploadForm' + id;		
+        // Watch for a new set of requests
+        if ( s.global && ! jQuery.active++ )
+		{
+			jQuery.event.trigger( "ajaxStart" );
+		}            
+        var requestDone = false;
+        // Create the request object
+        var xml = {}   
+        if ( s.global )
+            jQuery.event.trigger("ajaxSend", [xml, s]);
+        // Wait for a response to come back
+        var uploadCallback = function(isTimeout)
+		{			
+			var io = document.getElementById(frameId);
+            try 
+			{				
+				if(io.contentWindow)
+				{
+					 xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
+                	 xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
+					 
+				}else if(io.contentDocument)
+				{
+					 xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
+                	xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
+				}						
+            }catch(e)
+			{
+				jQuery.handleError(s, xml, null, e);
+			}
+            if ( xml || isTimeout == "timeout") 
+			{				
+                requestDone = true;
+                var status;
+                try {
+                    status = isTimeout != "timeout" ? "success" : "error";
+                    // Make sure that the request was successful or notmodified
+                    if ( status != "error" )
+					{
+                        // process the data (runs the xml through httpData regardless of callback)
+                        var data = jQuery.uploadHttpData( xml, s.dataType );    
+                        // If a local callback was specified, fire it and pass it the data
+                        if ( s.success )
+                            s.success( data, status );
+    
+                        // Fire the global callback
+                        if( s.global )
+                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+                    } else
+                        jQuery.handleError(s, xml, status);
+                } catch(e) 
+				{
+                    status = "error";
+                    jQuery.handleError(s, xml, status, e);
+                }
+
+                // The request was completed
+                if( s.global )
+                    jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+                // Handle the global AJAX counter
+                if ( s.global && ! --jQuery.active )
+                    jQuery.event.trigger( "ajaxStop" );
+
+                // Process result
+                if ( s.complete )
+                    s.complete(xml, status);
+
+                jQuery(io).unbind()
+
+                setTimeout(function()
+									{	try 
+										{
+											jQuery(io).remove();
+											jQuery(form).remove();	
+											
+										} catch(e) 
+										{
+											jQuery.handleError(s, xml, null, e);
+										}									
+
+									}, 100)
+
+                xml = null
+
+            }
+        }
+        // Timeout checker
+        if ( s.timeout > 0 ) 
+		{
+            setTimeout(function(){
+                // Check to see if the request is still happening
+                if( !requestDone ) uploadCallback( "timeout" );
+            }, s.timeout);
+        }
+        try 
+		{
+
+			var form = jQuery('#' + formId);
+			jQuery(form).attr('action', s.url);
+			jQuery(form).attr('method', 'POST');
+			jQuery(form).attr('target', frameId);
+            if(form.encoding)
+			{
+				jQuery(form).attr('encoding', 'multipart/form-data');      			
+            }
+            else
+			{	
+				jQuery(form).attr('enctype', 'multipart/form-data');			
+            }			
+            jQuery(form).submit();
+
+        } catch(e) 
+		{			
+            jQuery.handleError(s, xml, null, e);
+        }
+		
+		jQuery('#' + frameId).load(uploadCallback	);
+        return {abort: function () {}};	
+
+    },
+
+    uploadHttpData: function( r, type ) {
+        var data = !type;
+        data = type == "xml" || data ? r.responseXML : r.responseText;
+        // If the type is "script", eval it in global context
+        if ( type == "script" )
+            jQuery.globalEval( data );
+        // Get the JavaScript object, if JSON is used.
+        if ( type == "json" )
+            eval( "data = " + data );
+        // evaluate scripts within html
+        if ( type == "html" )
+            jQuery("<div>").html(data).evalScripts();
+
+        return data;
+    }
+})
+

+ 26 - 0
x_attendance_assemble_control/jest/common.js

@@ -0,0 +1,26 @@
+function failure(data) {
+	console.log(data);
+	alert(data.message);
+}
+
+function splitValue(str) {
+	if (str) {
+		if (str.length > 0) {
+			return str.split(',');
+		}
+	}
+	return [];
+}
+
+function joinValue(o, split) {
+	var s = ',';
+	if (split) {
+		s = '' + split;
+	}
+	if (o) {
+		if (toString.apply(o) === '[object Array]') {
+			return o.join(s);
+		}
+	}
+	return o;
+}

+ 105 - 0
x_attendance_assemble_control/jest/data.js

@@ -0,0 +1,105 @@
+function data_query() {
+    str = '<table border="1" width="100%">';
+    str += '<tr><td>id:</td><td><input type="text" id="id" style="width:95%"/></td></tr>';
+    str += '<tr><td>type:</td><td>';
+    str += '<select id="type">';
+    str += '<option value="appInfo">appInfo</option>';
+    str += '<option value="catagoryInfo">catagoryInfo</option>';
+    str += '<option value="fileInfo">fileInfo</option>';
+    str += '<option value="appCatagoryPermission">appCatagoryPermission</option>';
+    str += '<option value="appCatagoryAdmin">appCatagoryAdmin</option>';
+    str += '<option value="log">log</option>';
+    str += '</select>';
+    str += '</td></tr>';
+    str += '<tr><td colspan="2"><button id="get">get</button>&nbsp;<button id="put">put</button>&nbsp;<button id="post">post</button>&nbsp;<button id="uuid">UUID</button></td></tr>';
+    str += '<tr><td colspan="2"><textarea id="data" style="width:95%;height:500px"/></td></tr>';
+    str += '</table>';
+    $('#content').html(str);
+    $('#result').html('');
+    $('#get', '#content').click(function() {
+    	data_get($('#id').val(), $('#type').val());
+    });
+    $('#put', '#content').click(function() {
+    	data_put($('#id').val(), $('#type').val());
+    });
+    $('#post', '#content').click(function() {
+    	data_post($('#id').val(), $('#type').val());
+    });
+    $('#uuid', '#content').click(function() {
+    	get_uuid();
+    });
+}
+
+function get_uuid( ) {
+	$('#data', '#content').val('');
+	$.ajax({
+		type : 'get',
+		dataType : 'json',
+		url : '../jaxrs/uuid/random',
+		xhrFields : {
+			'withCredentials' : true
+		},
+		crossDomain : true
+	}).done(function(data) {
+		if (data.type == 'success') {
+			$('#content').html(JSON.stringify(json.data));
+		} else {
+			failure(data);
+		}
+	});
+}
+
+function data_get(id, type) {
+    $('#data', '#content').val('');
+    $.ajax({
+	type : 'get',
+	dataType : 'json',
+	contentType : 'application/json; charset=utf-8',
+	url : '../jaxrs/' + type + '/' + id,
+	xhrFields : {
+	    'withCredentials' : true
+	},
+	crossDomain : true
+    }).done(function(json) {
+		$('#result').html(JSON.stringify(data, null, 4));
+		if (json.type == 'success') {
+		    $('#data', '#content').val(JSON.stringify(json.data, null, 4));
+		} else {
+		    failure(data);
+		}
+    }).fail(function(data) {
+    	failure(data);
+    });
+}
+
+function data_put( id, type ) {
+    $.ajax({
+		type : 'put',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/' + type + '/' + id,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#data', '#content').val())),
+		crossDomain : true
+    }).done(function(data) {
+    	$('#result').html(JSON.stringify(data.data, null, 4));
+    });
+}
+
+function data_post( id, type ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/' + type ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#data', '#content').val())),
+		crossDomain : true
+    }).done(function(data) {
+    	$('#result').html(JSON.stringify(data.data, null, 4));
+    });
+}

+ 44 - 0
x_attendance_assemble_control/jest/do_statistic.html

@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./do_statistic.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#dostatistic').click(function() {
+    		do_statistic();
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			Do_Statistic
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="dostatistic">do_statistic</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+</body>
+</html>

+ 17 - 0
x_attendance_assemble_control/jest/do_statistic.js

@@ -0,0 +1,17 @@
+function do_statistic() {
+	var query_url = '../jaxrs/statistic/do';
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceAdmin.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceAdmin.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendanceadmin($('#id').val());
+        });
+        $('#post').click(function() {
+        	data_post_attendanceadmin();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendanceadmin( $('#id').val() );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceAdmin
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 56 - 0
x_attendance_assemble_control/jest/entity_AttendanceAdmin.js

@@ -0,0 +1,56 @@
+function data_get_attendanceadmin( id ) {
+	var query_url = '../jaxrs/attendanceadmin/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendanceadmin/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_post_attendanceadmin( id ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceadmin' ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendanceadmin( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceadmin/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 77 - 0
x_attendance_assemble_control/jest/entity_AttendanceAppeal.html

@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceAppeal.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendanceappeal();
+        });
+    	$('#put').click(function() {
+    		data_put_attendanceappeal();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendanceappeal( $('#id').val() );
+        });        
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:<input type="text" id="id" style="width:95%"/></td>
+			</tr>
+			<tr>
+				<td width="50px">last_id:<input type="text" id="last_id" style="width:95%" value="(0)"/></td>
+				<td width="50px">count:<input type="text" id="count" style="width:95%" value="10"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceAppeal
+	    		</td>
+			</tr>
+			<tr>
+	    		<td width="50px">GET:/jaxrs/attendanceappealInfo/
+	    			<select id="service_url">
+	    				<option value="{id}">{id}</option>
+	    			</select>
+	    		</td>
+			</tr>
+			<tr>
+	    		<td width="50px">PUT:/jaxrs/attendanceappealInfo/
+	    			<select id="put_url">
+	    				<option value="appeal/{id}">appeal/{id}</option>
+	    				<option value="process/{id}">process/{id}</option>
+	    				<option value="process2/{id}">process2/{id}</option>
+	    				<option value="filter/list/{id}/next/{count}">filter/list/{id}/next/{count}</option>
+	    				<option value="filter/list/{id}/prev/{count}">filter/list/{id}/prev/{count}</option>
+	    			</select>
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="put">PUT</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+</body>
+</html>

+ 82 - 0
x_attendance_assemble_control/jest/entity_AttendanceAppeal.js

@@ -0,0 +1,82 @@
+var service_base_path = '../jaxrs/attendanceappealInfo';
+function data_get_attendanceappeal( ) {
+	var service_url = $("#service_url").val();
+	var query_url =  service_base_path + "/" + service_url;
+	
+	//获取用户所填写的参数
+	var id = $("#id").val();
+	
+	//根据参数组织URL
+	query_url = query_url.replace( "{id}",id );
+
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_put_attendanceappeal( ) {
+	var service_url = $("#put_url").val();
+	var query_url =  service_base_path + "/" + service_url;
+	
+	//获取用户所填写的参数
+	var id = $("#id").val();
+	var last_id = $("#last_id").val();
+	var count = $("#count").val();
+	
+	//根据参数组织URL	
+	if( "filter/list/{id}/next/{count}" == service_url ){
+		query_url = query_url.replace( "{id}",last_id );
+		query_url = query_url.replace( "{count}",count );
+	}else if( "filter/list/{id}/prev/{count}" == service_url ){
+		query_url = query_url.replace( "{id}",last_id );
+		query_url = query_url.replace( "{count}",count );
+	}else{
+		query_url = query_url.replace( "{id}",id );
+		query_url = query_url.replace( "{count}",count );
+	}
+	
+	alert("PUT:"+query_url);
+	$.ajax({
+		type : 'put',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendanceappeal( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendancedetail/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 90 - 0
x_attendance_assemble_control/jest/entity_AttendanceDetail.html

@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceDetail.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendancedetail();
+        });
+    	$('#put').click(function() {
+    		data_put_attendancedetail();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendancedetail( $('#id').val() );
+        });
+        $('#analyse').click(function() {
+        	data_Analyse( $('#anlyseStartDate').val(), $('#anlyseEndDate').val() );
+        });
+        
+        
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:<input type="text" id="id" style="width:95%"/></td>
+				<td>file_id:<input type="text" id="file_id" style="width:95%"/></td>
+			</tr>
+			<tr>
+				<td width="50px">last_id:<input type="text" id="last_id" style="width:95%" value="(0)"/></td>
+				<td width="50px">count:<input type="text" id="count" style="width:95%" value="10"/></td>
+			</tr>
+			<tr>
+				<td>anlyseStartDate:<input type="text" id="anlyseStartDate" style="width:95%" value="(0)"/></td>
+				<td>anlyseEndDate:<input type="text" id="anlyseEndDate" style="width:95%" value="(0)"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceDetail
+	    		</td>
+			</tr>
+			<tr>
+	    		<td width="50px">GET:/jaxrs/attendancedetail/
+	    			<select id="service_url">
+	    				<option value="list/{file_id}">list/{file_id}</option>
+	    				<option value="{id}">{id}</option>
+	    			</select>
+	    		</td>
+			</tr>
+			<tr>
+	    		<td width="50px">PUT:/jaxrs/attendancedetail/
+	    			<select id="put_url">
+	    				<option value="filter/list">filter/list</option>
+	    				<option value="filter/list/user">filter/list/user</option>
+	    				<option value="filter/list/department">filter/list/department</option>
+	    				<option value="filter/list/company">filter/list/company</option>
+	    				<option value="filter/list/{id}/next/{count}">filter/list/{id}/next/{count}</option>
+	    				<option value="filter/list/{id}/prev/{count}">filter/list/{id}/prev/{count}</option>
+	    			</select>
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="put">PUT</button>
+					<button id="delete">DELETE</button>
+					<button id="analyse">Analyse</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+</body>
+</html>

+ 124 - 0
x_attendance_assemble_control/jest/entity_AttendanceDetail.js

@@ -0,0 +1,124 @@
+var service_base_path = '../jaxrs/attendancedetail';
+function data_get_attendancedetail( ) {
+	var service_url = $("#service_url").val();
+	var query_url =  service_base_path + "/" + service_url;
+	
+	//获取用户所填写的参数
+	var id = $("#id").val();
+	var file_id = $("#file_id").val();
+	var last_id = $("#last_id").val();
+	var count = $("#count").val();
+	
+	//根据参数组织URL
+	if( "{id}" == service_url ){
+		query_url = query_url.replace( "{id}",id );
+		if( id == null || id == "" || id == undefined){
+			alert("请填写ID");return false;
+		}
+	}else if( "list/{file_id}" == service_url ){
+		if( file_id == null || file_id == "" || file_id == undefined){
+			alert("请填写file_id");return false;
+		}
+		query_url = query_url.replace( "{file_id}",file_id );
+	}
+
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_put_attendancedetail( ) {
+	var service_url = $("#put_url").val();
+	var query_url =  service_base_path + "/" + service_url;
+	
+	//获取用户所填写的参数
+	var last_id = $("#last_id").val();
+	var count = $("#count").val();
+	
+	//根据参数组织URL
+	if( "filter/list/{id}/next/{count}" == service_url ){
+		query_url = query_url.replace( "{id}",last_id );
+		query_url = query_url.replace( "{count}",count );
+		if( last_id == null || last_id == "" || last_id == undefined){
+			alert("请填写last_id");return false;
+		}
+		if( count == null || count == "" || count == undefined){
+			alert("请填写count");return false;
+		}
+	}else if( "filter/list/{id}/prev/{count}" == service_url ){
+		query_url = query_url.replace( "{id}",last_id );
+		query_url = query_url.replace( "{count}",count );
+		if( last_id == null || last_id == "" || last_id == undefined){
+			alert("请填写last_id");return false;
+		}
+		if( count == null || count == "" || count == undefined){
+			alert("请填写count");return false;
+		}
+	}
+	alert("PUT:"+query_url);
+	alert(JSON.stringify($.parseJSON($('#content').val())));
+	$.ajax({
+		type : 'put',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_Analyse( anlyseStartDate, anlyseEndDate ) {
+	var query_url = '../jaxrs/attendancedetail/analyse/{startDate}/{endDate}';
+	//如果未输入ID,那么就查询所有的应用信息
+	query_url = query_url.replace( "{startDate}",anlyseStartDate );
+	query_url = query_url.replace( "{endDate}",anlyseEndDate );
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_delete_attendancedetail( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendancedetail/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceDetailFileImport.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceDetailFileImport.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#checkData').click(function() {
+    		checkData( $('#file_id').val() );
+        });
+        $('#importData').click(function() {
+        	importData( $('#file_id').val() );
+        });
+        $('#testImport').click(function() {
+        	testImport();
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>file_id:</td>
+				<td><input type="text" id="file_id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceDetailFileImport
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="checkData">CheckDataFile</button>
+					<button id="importData">ImportDataFile</button>
+					<button id="testImport">testImportData</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 61 - 0
x_attendance_assemble_control/jest/entity_AttendanceDetailFileImport.js

@@ -0,0 +1,61 @@
+function checkData( file_id ) {
+	if( file_id == null || file_id == undefined || file_id == "" ){
+		alert("请输入file_id");
+		return false;
+	}
+	var query_url = '../jaxrs/fileimport/check/' + file_id;	
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function importData( file_id ) {
+	if( file_id == null || file_id == undefined || file_id == "" ){
+		alert("请输入file_id");
+		return false;
+	}
+	var query_url = '../jaxrs/fileimport/import/' + file_id;	
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function testImport( ) {
+	var query_url = '../jaxrs/fileimport/import/test';	
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}

+ 70 - 0
x_attendance_assemble_control/jest/entity_AttendanceImportFileInfo.html

@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./ajaxfileupload.js"></script>
+<script src="./entity_AttendanceImportFileInfo.js"></script>
+<script>
+    $(document).ready(function() {
+    	 $('#upload').click(function() {
+         	upload_attendanceimportfileinfo();
+         });
+    	 
+    	 $('#download').click(function() {
+         	download_attendanceimportfileinfo($('#id').val());
+         });    	
+    	
+    	 $('#get').click(function() {
+    		data_get_attendanceimportfileinfo($('#id').val());
+         });
+       
+         $('#delete').click(function() {
+        	data_delete_attendanceimportfileinfo( $('#id').val() );
+         });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+			<tr>
+				<td>file:</td>
+				<td><input type="file" id="file" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceSetting
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="upload">Upload</button>
+					<button id="download">Download</button>
+					<button id="get">GET</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 71 - 0
x_attendance_assemble_control/jest/entity_AttendanceImportFileInfo.js

@@ -0,0 +1,71 @@
+function upload_attendanceimportfileinfo() {
+	//开始上传具体的文件
+	$.ajaxFileUpload({				
+		//处理文件上传操作的服务器端地址(可以传参数,已亲测可用)
+	    url: '../servlet/upload/',
+ 		data:{},
+		secureuri:false,            //是否启用安全提交,默认为false 
+		fileElementId:'file',         //文件选择框的id属性
+		dataType:'text',            //服务器返回的格式,可以是json或xml等
+		success:function( data, status){        //服务器响应成功时的处理函数
+			$('#result').html("数据导入成功!");
+		},
+		error:function(data, status, e){ //服务器响应失败时的处理函数
+			console.log(e);
+			console.log(data);
+			$('#result').html('上传失败,请重试!!');
+		}
+	});
+}
+
+function download_attendanceimportfileinfo( id ) {
+	
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+	
+    window.open( '../servlet/download/'+id+'/stream' );
+}
+
+function data_get_attendanceimportfileinfo( id ) {
+	var query_url = '../jaxrs/attendanceimportfileinfo/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendanceimportfileinfo/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+
+function data_delete_attendanceimportfileinfo( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceimportfileinfo/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceScheduleSetting.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceScheduleSetting.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendanceschedulesetting($('#id').val());
+        });
+        $('#post').click(function() {
+        	data_post_attendanceschedulesetting();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendanceschedulesetting( $('#id').val() );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceScheduleSetting
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 56 - 0
x_attendance_assemble_control/jest/entity_AttendanceScheduleSetting.js

@@ -0,0 +1,56 @@
+function data_get_attendanceschedulesetting( id ) {
+	var query_url = '../jaxrs/attendanceschedulesetting/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendanceschedulesetting/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_post_attendanceschedulesetting( id ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceschedulesetting' ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendanceschedulesetting( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceschedulesetting/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceSelfHoliday.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceSelfHoliday.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendanceselfholiday($('#id').val());
+        });
+        $('#post').click(function() {
+        	data_post_attendanceselfholiday();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendanceselfholiday( $('#id').val() );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceAdmin
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 56 - 0
x_attendance_assemble_control/jest/entity_AttendanceSelfHoliday.js

@@ -0,0 +1,56 @@
+function data_get_attendanceselfholiday( id ) {
+	var query_url = '../jaxrs/attendanceselfholiday/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendanceselfholiday/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_post_attendanceselfholiday( id ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceselfholiday' ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendanceselfholiday( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceselfholiday/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceSetting.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceSetting.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendancesetting($('#id').val());
+        });
+        $('#post').click(function() {
+        	data_post_attendancesetting();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendancesetting( $('#id').val() );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceSetting
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 56 - 0
x_attendance_assemble_control/jest/entity_AttendanceSetting.js

@@ -0,0 +1,56 @@
+function data_get_attendancesetting( id ) {
+	var query_url = '../jaxrs/attendancesetting/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendancesetting/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_post_attendancesetting( id ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendancesetting' ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendancesetting( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendancesetting/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 58 - 0
x_attendance_assemble_control/jest/entity_AttendanceWorkDayConfig.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./entity_AttendanceWorkDayConfig.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		data_get_attendanceworkdayconfig($('#id').val());
+        });
+        $('#post').click(function() {
+        	data_post_attendanceworkdayconfig();
+        });
+        $('#delete').click(function() {
+        	data_delete_attendanceworkdayconfig( $('#id').val() );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>id:</td>
+				<td><input type="text" id="id" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td>type:</td>
+				<td>
+	    			AttendanceWorkDayConfig
+	    		</td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 56 - 0
x_attendance_assemble_control/jest/entity_AttendanceWorkDayConfig.js

@@ -0,0 +1,56 @@
+function data_get_attendanceworkdayconfig( id ) {
+	var query_url = '../jaxrs/attendanceworkdayconfig/' + id;
+	//如果未输入ID,那么就查询所有的应用信息
+	if( id == null || id == undefined || id == "" ){
+		query_url = '../jaxrs/attendanceworkdayconfig/list/all';
+	}
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function data_post_attendanceworkdayconfig( id ) {
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceworkdayconfig' ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function data_delete_attendanceworkdayconfig( id ) {
+	if( id == null || id == undefined || id == "" ){
+		alert("请输入ID");
+		return false;
+	}
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : '../jaxrs/attendanceworkdayconfig/' + id ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 88 - 0
x_attendance_assemble_control/jest/index.html

@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>x_attendance_assemble_control</title>
+<script src="./common.js"></script>
+<script src="./jquery.js"></script>
+<script>
+    $(document).ready(function() {
+    	
+		$("#main_content").load("uuid.html");
+		
+		$("#uuid").click(function(){ $("#main_content").load("uuid.html"); });
+		
+		$("#entity_AttendanceAdmin").click(function(){ $("#main_content").load("entity_AttendanceAdmin.html"); });		
+		$("#entity_AttendanceDetail").click(function(){ $("#main_content").load("entity_AttendanceDetail.html"); });
+		$("#entity_AttendanceAppeal").click(function(){ $("#main_content").load("entity_AttendanceAppeal.html"); });
+		$("#entity_AttendanceImportFileInfo").click(function(){ $("#main_content").load("entity_AttendanceImportFileInfo.html"); });
+		$("#entity_AttendanceScheduleSetting").click(function(){ $("#main_content").load("entity_AttendanceScheduleSetting.html"); });
+		$("#entity_AttendanceSetting").click(function(){ $("#main_content").load("entity_AttendanceSetting.html"); });
+		$("#entity_AttendanceWorkDayConfig").click(function(){ $("#main_content").load("entity_AttendanceWorkDayConfig.html"); });
+		$("#entity_AttendanceSelfHoliday").click(function(){ $("#main_content").load("entity_AttendanceSelfHoliday.html"); });
+		
+		$("#entity_AttendanceDetailFileImport").click(function(){ $("#main_content").load("entity_AttendanceDetailFileImport.html"); });
+		
+		$("#do_statistic").click(function(){ $("#main_content").load("do_statistic.html"); });
+		$("#showStatistic").click(function(){ $("#main_content").load("showStatistic.html"); });
+		
+		
+		$("#test").click(function(){ $("#main_content").load("test.html"); });
+		
+    });
+</script>
+</head>
+<body style="margin: 0; font-size: 1.0em; font-family: Microsoft Yahei">
+	<div id="container" style="width: 1000px; margin: 0 auto;">
+		<div id="header" style="background-color: #4682B4; clear: both; text-align: center;">
+			x_attendance_assemble_control_jest for x_attendance_assemble_control
+		</div>
+		<div id="menu" style="background-color: #B0E0E6; height: 950px; width: 280px; float: left;">
+			<ul>
+				<li>UUID
+					<ul>
+						<li><a id="uuid" href="javascript:void(0)">RandomUUID</a></li>
+					</ul>
+				</li>
+				<li>通用测试页
+					<ul>
+						<li><a id="test" href="javascript:void(0)">Test</a></li>
+					</ul>
+				</li>
+				<li>Entity
+					<ul>
+						<li><a id="entity_AttendanceAdmin" href="javascript:void(0)">Admin</a></li>
+						<li><a id="entity_AttendanceDetail" href="javascript:void(0)">Detail</a></li>
+						<li><a id="entity_AttendanceAppeal" href="javascript:void(0)">Appeal</a></li>
+						<li><a id="entity_AttendanceScheduleSetting" href="javascript:void(0)">ScheduleSetting</a></li>
+						<li><a id="entity_AttendanceSetting" href="javascript:void(0)">Setting</a></li>
+						<li><a id="entity_AttendanceWorkDayConfig" href="javascript:void(0)">WorkDayConfig</a></li>
+						<li><a id="entity_AttendanceSelfHoliday" href="javascript:void(0)">SelfHoliday</a></li>
+					</ul>
+				</li>
+				<li>Import
+					<ul>
+						<li><a id="entity_AttendanceImportFileInfo" href="javascript:void(0)">FileUpload</a></li>
+						<li><a id="entity_AttendanceDetailFileImport" href="javascript:void(0)">DetailImport</a></li>					
+					</ul>
+				</li>
+				<li>Statistic
+					<ul>
+						<li><a id="do_statistic" href="javascript:void(0)">doStatistic</a></li>	
+						<li><a id="showStatistic" href="javascript:void(0)">ShowStatistic</a></li>	
+					</ul>
+				</li>
+				<li>ShowStatistic
+					<ul>
+						<li><a id="statistic_Person" href="javascript:void(0)">Person</a></li>
+						<li><a id="statistic_Department" href="javascript:void(0)">Department</a></li>
+						<li><a id="statistic_Company" href="javascript:void(0)">Company</a></li>			
+					</ul>
+				</li>
+			</ul>
+		</div>
+		<div id="main_content" style="float: left; width: 720px;"></div>
+		<div id="footer" style="background-color: #4682B4; clear: both; text-align: center; display: none"> Copyright © x</div>
+	</div>
+</body>
+</html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
x_attendance_assemble_control/jest/jquery.js


+ 94 - 0
x_attendance_assemble_control/jest/showStatistic.html

@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./showStatistic.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		var _name = $("#name").val();
+    		var _year = $("#year").val();
+    		var _month = $("#month").val();
+    		var _date = $("#date").val();
+    		getStatistic( _name, _year, _month, _date );
+        });
+    	$('#put').click(function() {
+    		var _id = $("#last_id").val();
+    		var _count = $("#count").val();
+    		getFilterListForStatistic( _id, _count );
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>name:<input type="text" id="name" value="蔡艳红"/></td>
+				<td>date:<input type="text" id="date" value=""/></td>
+			</tr>
+	    	<tr>
+				<td>year:<input type="text" id="year" value="2016"/></td>
+				<td>month:<input type="text" id="month" value="03"/></td>
+			</tr>
+			<tr>
+				<td>last_id:<input type="text" id="last_id" value="(0)"/></td>
+				<td>count:<input type="text" id="count" value="10"/></td>
+			</tr>
+	    	<tr>
+				<td>type:SHOW_Statistic</td>
+			</tr>
+	    	<tr>
+	    		<td>
+					<select id="queryUrl">
+						<option value="person/{name}/{year}/{month}">person/{name}/{year}/{month}</option>
+						<option value="persons/department/{name}/{year}/{month}">persons/department/{name}/{year}/{month}</option>
+						<option value="department/{name}/{year}/{month}">department/{name}/{year}/{month}</option>
+						<option value="department/sum/{name}/{year}/{month}">department/sum/{name}/{year}/{month}</option>
+						<option value="department/{name}/{date}">department/{name}/{date}</option>
+						<option value="department/day/{name}/{year}/{month}">department/day/{name}/{year}/{month}</option>
+						<option value="department/day/{name}/{date}">department/day/{name}/{date}</option>
+						<option value="company/{name}/{year}/{month}">company/{name}/{year}/{month}</option>
+						<option value="company/day/{name}/{year}/{month}">company/day/{name}/{year}/{month}</option>
+					</select>
+				</td>
+				<td>
+					<button id="get">GET</button>
+				</td>
+			</tr>
+			<tr>
+	    		<td>
+					<select id="putUrl">
+						<option value="filter/personMonth/list/{id}/next/{count}">filter/personMonth/list/{id}/next/{count}</option>
+						<option value="filter/personMonth/list/{id}/prev/{count}">filter/personMonth/list/{id}/prev/{count}</option>
+						<option value="filter/departmentMonth/list/{id}/next/{count}">filter/departmentMonth/list/{id}/next/{count}</option>
+						<option value="filter/departmentMonth/list/{id}/prev/{count}">filter/departmentMonth/list/{id}/prev/{count}</option>
+						<option value="filter/companyMonth/list/{id}/next/{count}">filter/companyMonth/list/{id}/next/{count}</option>
+						<option value="filter/companyMonth/list/{id}/prev/{count}">filter/companyMonth/list/{id}/prev/{count}</option>
+						<option value="filter/departmentDay/list/{id}/next/{count}">filter/departmentDay/list/{id}/next/{count}</option>
+						<option value="filter/departmentDay/list/{id}/prev/{count}">filter/departmentDay/list/{id}/prev/{count}</option>
+						<option value="filter/companyDay/list/{id}/next/{count}">filter/companyDay/list/{id}/next/{count}</option>
+						<option value="filter/companyDay/list/{id}/prev/{count}">filter/companyDay/list/{id}/prev/{count}</option>
+					</select>
+				</td>
+				<td>
+					<button id="put">PUT</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="content" style="width:97%;height:300px"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:400px"></textarea>
+				</td>
+			</tr>
+	    </table>
+	</div>
+</div>
+</body>
+</html>

+ 62 - 0
x_attendance_assemble_control/jest/showStatistic.js

@@ -0,0 +1,62 @@
+var service_base_path = '../jaxrs/statisticshow/';
+function getStatistic( name, year, month, date ) {
+	var query_url = service_base_path + $("#queryUrl").val();
+	if( name != null && name != undefined && name != "(0)"){
+		query_url = query_url.replace( "{name}", encodeURIComponent(name) );
+	}
+	if( date != null && date != undefined && date != "(0)"){
+		query_url = query_url.replace( "{date}", encodeURIComponent(date) );
+	}
+	if( year != null && year != undefined && year != "(0)"){
+		query_url = query_url.replace( "{year}", year );
+	}
+	if( month != null && month != undefined && month != "(0)"){
+		query_url = query_url.replace( "{month}", month );
+	}
+	alert(query_url);
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function getFilterListForStatistic( last_id, _count ){
+	var service_url = $("#putUrl").val();
+	var query_url =  service_base_path + "/" + service_url;
+	
+	if( last_id == null || last_id == undefined ){
+		last_id="(0)";
+	}
+	if( _count == null || _count == undefined ){
+		_count=20;
+	}
+	
+	//根据参数组织URL
+	query_url = query_url.replace( "{id}",last_id );
+	query_url = query_url.replace( "{count}",_count );
+	
+	alert( "PUT:"+query_url );
+	$.ajax({
+		type : 'put',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : query_url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 48 - 0
x_attendance_assemble_control/jest/test.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script src="./test.js"></script>
+<script>
+    $(document).ready(function() {
+    	$('#get').click(function() {
+    		doget();
+        });
+    	$('#put').click(function() {
+    		doput();
+        });
+        $('#post').click(function() {
+        	dopost();
+        });
+        $('#delete').click(function() {
+        	dodelete();
+        });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" style="width:100%">
+	    	<tr>
+				<td>URL:</td>
+				<td>/jaxrs/<input type="text" id="url" style="width:95%"/></td>
+			</tr>
+	    	<tr>
+				<td colspan="2">
+					<button id="get">GET</button>
+					<button id="post">POST</button>
+					<button id="put">PUT</button>
+					<button id="delete">DELETE</button>
+				</td>
+			</tr>
+			<tr><td colspan="2"><textarea id="content" style="width:97%;height:300px">{}</textarea></td></tr>
+			<tr><td colspan="2"><textarea id="result" style="width:97%;height:400px"></textarea></td></tr>
+	    </table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 71 - 0
x_attendance_assemble_control/jest/test.js

@@ -0,0 +1,71 @@
+function doget() {
+	var url = '../jaxrs/'+$("#url").val();
+	alert(url);
+    $.ajax({
+		type : 'get',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html( JSON.stringify( json, null, 4) );
+    }).fail(function(json) {
+    	failure(json);
+    });
+}
+
+function dopost() {
+	var url = '../jaxrs/'+$("#url").val();
+	alert(url);
+    $.ajax({
+		type : 'post',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : url ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function doput() {
+	var url = '../jaxrs/'+$("#url").val();
+	alert(url);
+	$.ajax({
+		type : 'put',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : url ,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		data : JSON.stringify($.parseJSON($('#content').val())),
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}
+
+function dodelete() {
+	var url = '../jaxrs/'+$("#url").val();
+	alert(url);
+    $.ajax({
+		type : 'delete',
+		dataType : 'json',
+		contentType : 'application/json; charset=utf-8',
+		url : url,
+		xhrFields : {
+		    'withCredentials' : true
+		},
+		crossDomain : true
+    }).done(function(json) {
+    	$('#result').html(JSON.stringify(json.data, null, 4));
+    });
+}

+ 45 - 0
x_attendance_assemble_control/jest/uuid.html

@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>main_entiity</title>
+<script>
+    $(document).ready(function() {
+		$('#get_uuid').click(function() {
+			$('#data', '#result').val('');
+			$.ajax({
+				type : 'get',
+				dataType : 'json',
+				url : '../jaxrs/uuid/random',
+				xhrFields : {
+					'withCredentials' : true
+				},
+				crossDomain : true
+			}).done(function(json) {
+				$('#result').html(JSON.stringify( json, null, 4));
+			});
+	    });
+    });
+</script>
+</head>
+<body>
+<div style="float: left; width: 720px;">
+	<div style="width: 100%;">
+		<table border="1" width="100%">
+	    	<tr>
+				<td colspan="2">
+					<button id="get_uuid">GET UUID</button>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<textarea id="result" style="width:97%;height:600px"/>
+				</td>
+			</tr>
+    	</table>
+	</div>
+</div>
+		
+		
+</body>
+</html>

+ 833 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java

@@ -0,0 +1,833 @@
+package com.x.attendance.assemble.common.date;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @项目名 :SuperviseEfficientSystem
+ * @包  名 :com.land.util.date
+ * @文件名 :DateUtil.java
+ * @作  者 :李  义
+ * @单  位 :浙江兰德纵横网络技术有限公司
+ * @日  期 :2013-06-07
+ */
+public class DateOperation {
+	
+	private Logger logger = LoggerFactory.getLogger( DateOperation.class );
+	/**
+	 * 根据样式得到格式化对象SimpleDateFormat
+	 * @param date
+	 * @param style
+	 * @return
+	 */
+	public String getDate(Date date, String style) {
+		SimpleDateFormat format = new SimpleDateFormat(style);
+		return format.format(date);
+	}
+
+	/**
+	 * 得到某日期的日期部分
+	 * 
+	 * @param date
+	 * @return yyyy-MM-dd
+	 */
+	public String getDate(Date date) {
+		return format1.format(date);
+	}
+
+	/**
+	 * 得到某日期的时间部分
+	 * 
+	 * @param date
+	 * @return HH:mm:ss
+	 */
+	public  String getTime(Date date) {
+		return format2.format(date);
+	}
+
+	public  Date getDateFromString(String dateString, String style) throws Exception{
+		Date date = null;
+		if(style==null||"".equals(style.trim())){
+			date = format1.parse(dateString);
+		}else if("yyyy-MM-dd HH:mm:ss".equalsIgnoreCase(style.trim())){
+			date = format3.parse(dateString);
+		}else if("yyyy-MM-dd HH:mm".equalsIgnoreCase(style.trim())){
+			date = format3_2.parse(dateString);
+		}else if("yyyy/MM/dd HH:mm:ss".equalsIgnoreCase(style.trim())){
+			date = format3_1.parse(dateString);
+		}else if("yyyy/MM/dd".equalsIgnoreCase(style.trim())){
+			date = format4.parse(dateString);
+		}else if("yyyy-MM-dd".equalsIgnoreCase(style.trim())){
+			date = format1.parse(dateString);
+		}else if("yyyyMMdd".equalsIgnoreCase(style.trim())){
+			date = format5.parse(dateString);
+		}else if("yyyyMMddHHmmss".equalsIgnoreCase(style.trim())){
+			date = format7.parse(dateString);
+		}else if("HH:mm:ss".equalsIgnoreCase(style.trim())){
+			date = format2.parse(dateString);
+		}else if("HH:mm".equalsIgnoreCase(style.trim())){
+			date = format2_1.parse(dateString);
+		}else{
+			throw new Exception("对不起,您输入的日期style系统无法识别,请检查您的参数输入!");
+		}
+		return date;
+	}
+	
+	/**
+	 * 将字符串转换为日期格式
+	 * 会尝试多种格式转换,转换成功后返回结果
+	 * @param dateString
+	 * @return
+	 * @throws Exception
+	 */
+	public  Date getDateFromString( String dateString ) throws Exception{
+		Date date = null;
+		try{
+			date = getDateFromString( dateString, "yyyy-MM-dd HH:mm:ss" );
+			return date;
+		}catch(Exception e){}
+
+		try{
+			date = getDateFromString( dateString, "yyyy-MM-dd HH:mm" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "yyyy/MM/dd HH:mm:ss" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "yyyy-MM-dd" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "yyyy/MM/dd" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "yyyyMMdd" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "yyyyMMddHHmmss" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "HH:mm:ss" );
+			return date;
+		}catch(Exception e){}
+		
+		try{
+			date = getDateFromString( dateString, "HH:mm" );
+			return date;
+		}catch(Exception e){}
+		
+		return date;
+	}
+	
+	
+	public  String getDateStringFromDate(Date date, String style) throws Exception{
+		String dateString = null;
+		if(style==null||"".equals(style.trim())){
+			dateString = format1.format(date);
+		}else if("yyyy-MM-dd HH:mm:ss".equalsIgnoreCase(style.trim())){
+			dateString = format3.format(date);
+		}else if("yyyy/MM/dd HH:mm:ss".equalsIgnoreCase(style.trim())){
+			dateString = format3_1.format(date);
+		}else if("yyyy/MM/dd".equalsIgnoreCase(style.trim())){
+			dateString = format4.format(date);
+		}else if("yyyy-MM-dd".equalsIgnoreCase(style.trim())){
+			dateString = format1.format(date);
+		}else if("yyyyMMdd".equalsIgnoreCase(style.trim())){
+			dateString = format5.format(date);
+		}else if("yyyyMMddHHmmss".equalsIgnoreCase(style.trim())){
+			dateString = format7.format(date);
+		}else if("HH:mm:ss".equalsIgnoreCase(style.trim())){
+			dateString = format2.format(date);
+		}else{
+			throw new Exception("对不起,您输入的日期style系统无法识别,请检查您的参数输入!style=" + style);
+		}
+		return dateString;
+	}
+	
+	/**
+	 * 得到某日期加上或减去天数后的日期,day为负数时减去
+	 * 
+	 * @param date
+	 * @param month
+	 * @return "yyyy-MM-dd"
+	 * @throws Exception 
+	 */
+	public  String getDayAdd(String dateString, int day, String style) throws Exception {
+		Date date = getDateFromString(dateString, style);
+		return getDayAdd(date, day);
+	}
+	
+	/**
+	 * 得到某日期加上或减去天数后的日期,day为负数时减去
+	 * 
+	 * @param date
+	 * @param month
+	 * @return "yyyy-MM-dd"
+	 */
+	public  String getDayAdd(Date date, int day) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.add(Calendar.DATE, day);
+		return format1.format(calendar.getTime());
+	}
+
+	/**
+	 * 得到某日期加上或减去月份后的日期,month为负数时减去
+	 * 
+	 * @param date
+	 * @param month
+	 * @return "yyyy-MM-dd"
+	 */
+	public  String getMonthAdd(Date date, int month) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.add(Calendar.MONTH, month);
+		return format1.format(calendar.getTime());
+	}
+	
+	/**
+	 * 得到某日期加上或减去分钟后的日期,min为负数时减去
+	 * 
+	 * @param date
+	 * @param month
+	 * @return "yyyy-MM-dd HH:mi:ss"
+	 */
+	public  String getMinutesAdd(Date date, int min) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.add(Calendar.MINUTE, min);
+		return format3.format(calendar.getTime());
+	}
+	/**
+	 * 得到某日期的日
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getDay(Date date) {
+		try{
+			return format10.format(date);
+		}catch(Exception e){
+			return "0";
+		}
+	}
+	public int getDayNumber(Date date) {
+		String result = null;
+		try{
+			result = format10.format(date);
+		}catch(Exception e){
+			result = "0";
+		}
+		return Integer.parseInt(result);
+	}
+	/**
+	 * 得到某日期的月份
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getMonth(Date date) {
+		try{
+			return format9.format(date);
+		}catch(Exception e){
+			return "0";
+		}
+	}
+	public int getMonthNumber(Date date) {
+		String result = null;
+		try{
+			result = format9.format(date);
+		}catch(Exception e){
+			result = "0";
+		}
+		return Integer.parseInt(result);
+	}
+
+	/**
+	 * 得到某日期的年份
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getYear(Date date) {
+		try{
+			return format8.format(date);
+		}catch(Exception e){
+			return "0";
+		}
+	}
+	public int getYearNumber(Date date) {
+		String result = null;
+		try{
+			result = format8.format(date);
+		}catch(Exception e){
+			result = "0";
+		}
+		return Integer.parseInt(result);
+	}
+	/**
+	 * 得到某日期的小时
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getHour(Date date) {
+		try{
+			return format11.format(date);
+		}catch(Exception e){
+			return "0";
+		}
+	}
+	/**
+	 * 得到某日期的分钟
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getMinites(Date date) {
+		return format12.format(date);
+	}
+	/**
+	 * 得到某日期的秒
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 */
+	public  String getSeconds(Date date) {
+		return format13.format(date);
+	}
+	/**
+	 * 得到某年有多少天
+	 * 
+	 * @param String
+	 *            date "yyyy-MM-dd"
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	public  int getDaysForYear(String date) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(format1.parse(date));
+		return calendar.get(calendar.DAY_OF_YEAR);
+	}
+
+	/**
+	 * 得到某年有多少天
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	public  int getDaysForYear(Date date) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return calendar.get(calendar.DAY_OF_YEAR);
+	}
+
+	/**
+	 * 得到某年有多少天
+	 * 
+	 * @param String
+	 *            year "yyyy"
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	public  int getDaysForYear_YYYY(String year) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(format8.parse(year));
+		return calendar.get(calendar.DAY_OF_YEAR);
+	}
+
+	/**
+	 * 得到某月有多少天
+	 * 
+	 * @param String
+	 *            date "yyyy-MM-dd"
+	 * @return
+	 * @throws ParseException
+	 */
+	public  int getDaysForMonth(String date) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(format1.parse(date));
+		return calendar.getActualMaximum( Calendar.DAY_OF_MONTH);
+	}
+
+	/**
+	 * 得到某月有多少天
+	 * 
+	 * @param String
+	 *            date "yyyy-MM"
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	public  int getDaysForMonth_MM(String date) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(format14.parse(date));
+		return calendar.get(calendar.DAY_OF_MONTH);
+	}
+
+	/**
+	 * 得到某月有多少天
+	 * 
+	 * @param Date
+	 *            date
+	 * @return
+	 * @throws ParseException
+	 */
+	public  int getDaysForMonth(Date date) throws ParseException {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return calendar.get(Calendar.DAY_OF_MONTH);
+	}
+
+	/**
+	 * 得到当前的日期
+	 * 
+	 * @return
+	 */
+	public  String getNowDate() {
+		return format1.format(new Date());
+	}
+
+	/**
+	 * 得到当前的时间
+	 * 
+	 * @return
+	 */
+	public  String getNowTime() {
+		return format2.format(new Date());
+	}
+	/**
+	 * 得到当前的时间
+	 * yyyyMMddHHmmss
+	 * @return
+	 */
+	public  String getNowTimeChar() {
+		return format7.format(new Date());
+	}
+	/**
+	 * 得到当前的时间
+	 * yyyy-MM-dd HH:mm:ss
+	 * @return
+	 */
+	public  String getNowDateTime() {
+		return format3.format(new Date());
+	}
+	/**
+	 * 得到两个时间之前的分差
+	 * @param date1 yyyy-MM-dd HH:mm:ss
+	 * @param date2 yyyy-MM-dd HH:mm:ss
+	 * @return
+	 */
+	public  long getDeff(String date1,String date2) {
+		long dayNumber = 0;
+		// 1小时=60分钟=3600秒=3600000
+		long mins = 60L * 1000L;
+		// long day= 24L * 60L * 60L * 1000L;计算天数之差
+		SimpleDateFormat df = null;
+		if(date1.length() == 19){
+			df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		}else if(date1.length() == 10){
+			df = new SimpleDateFormat("yyyy-MM-dd");
+		}else if(date1.length() == 8){
+			df = new SimpleDateFormat("HH:mm:ss");
+		}else{
+			df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		}
+		try {
+			java.util.Date d1 = df.parse(date1);
+			java.util.Date d2 = df.parse(date2);
+			dayNumber = (d2.getTime() - d1.getTime()) / mins;
+		} catch (Exception e) {
+			logger.error( "系统获取得到两个时间之前的分差发生异常",  e);
+		}
+		return dayNumber;
+	}
+	/**
+	 * 得到两个时间之前的分差
+	 * @param date1 yyyy-MM-dd HH:mm:ss
+	 * @param date2 yyyy-MM-dd HH:mm:ss
+	 * @return
+	 */
+	public long getDeff(Date date1,Date date2) {
+		long dayNumber = 0;
+		// 1小时=60分钟=3600秒=3600000
+		long mins = 60L * 1000L;
+		// long day= 24L * 60L * 60L * 1000L;计算天数之差
+		try {
+			dayNumber = (date2.getTime() - date1.getTime()) / mins;
+		} catch (Exception e) {
+			logger.error( "系统获取得到两个时间之前的分差发生异常",  e);
+		}
+		return dayNumber;
+	}
+	/**
+	 * 
+	 * 日期格式转换
+	 * 从YYYY-MM-DD转换到YYYYMMDD
+	 * @param date
+	 * @throws ParseException 
+	 */
+	public  String changeDateFormat(String dateString){
+		Date date;
+		String reslut = null;
+		try {
+			if("".equals(dateString)){
+				dateString="0000-00-00";
+			}
+			date = format1.parse(dateString);
+			reslut = format5.format(date);
+		} catch (ParseException e) {
+			try {
+				date = format1.parse("0000-00-00");
+			} catch (ParseException e1) {
+				logger.error( "系统日期格式转换发生异常",  e1);
+			}
+			logger.error( "系统日期格式转换发生异常",  e);
+		}
+		
+		return reslut;
+	}
+	
+	/** 格式 yyyy-MM-dd */
+	public  final SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
+	/** 格式 HH:mm:ss */
+	public  final SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
+	public  final SimpleDateFormat format2_1 = new SimpleDateFormat("HH:mm");
+	/** 格式 yyyy-MM-dd HH:mm:ss */
+	public  final SimpleDateFormat format3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+	public  final SimpleDateFormat format3_2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+	public  final SimpleDateFormat format3_1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+	/** 格式 yyyy/MM/dd */
+	public  final SimpleDateFormat format4 = new SimpleDateFormat("yyyy/MM/dd");
+	/** 格式 yyyyMMdd */
+	public  final SimpleDateFormat format5 = new SimpleDateFormat("yyyyMMdd");
+	/** 格式 HHmmss */
+	public  final SimpleDateFormat format6 = new SimpleDateFormat("HHmmss");
+	/** 格式 yyyyMMddHHmmss */
+	public  final SimpleDateFormat format7 = new SimpleDateFormat("yyyyMMddHHmmss");
+	/** 格式 yyyy */
+	public  final SimpleDateFormat format8 = new SimpleDateFormat("yyyy");
+	/** 格式 MM */
+	public  final SimpleDateFormat format9 = new SimpleDateFormat("MM");
+	/** 格式 dd */
+	public  final SimpleDateFormat format10 = new SimpleDateFormat("dd");
+	/** 格式 HH */
+	public  final SimpleDateFormat format11 = new SimpleDateFormat("HH");
+	/** 格式 mm */
+	public  final SimpleDateFormat format12 = new SimpleDateFormat("mm");
+	/** 格式 ss */
+	public  final SimpleDateFormat format13 = new SimpleDateFormat("ss");
+	/** 格式 ss */
+	public  final SimpleDateFormat format14 = new SimpleDateFormat("yyyy-MM");
+	
+	
+	public  String getStartOfWeek(String dateString){
+		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+		try {
+			Date date = format.parse(dateString);
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(date);
+			cal.setFirstDayOfWeek(Calendar.MONDAY);
+			int tmp = cal.get(Calendar.DAY_OF_WEEK) - 1;
+			if (0 == tmp) {
+				tmp = 7;
+			}
+			cal.add(Calendar.DATE, -(tmp-1));
+			return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 00:00:00";
+		} catch (ParseException e) {
+			logger.error( "系统getStartOfWeek日期格式转换发生异常",  e);
+		} catch (Exception e) {
+			logger.error( "系统getStartOfWeek发生异常",  e);
+		}
+		return null;
+	}
+	
+	public  String getEndOfWeek(String dateString){
+		try {
+			Date date = getDateFromString(getStartOfWeek(dateString), "yyyy-MM-dd HH:mm:ss");
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(date);
+			cal.setFirstDayOfWeek(Calendar.MONDAY);
+			cal.add(Calendar.DATE, 6);
+			return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 23:59:59";
+		} catch (ParseException e) {
+			logger.error( "系统getEndOfWeek日期格式转换发生异常",  e);
+		} catch (Exception e) {
+			logger.error( "系统getEndOfWeek发生异常",  e);
+		}
+		return null;
+	}
+	
+	
+	
+	/**
+	 * 将时间格式转换为 **月**日**时**分的格式
+	 * @param dateString
+	 * @param style
+	 * @return
+	 * @throws Exception
+	 */
+	public String getDateCNString( String dateString, String style ) throws Exception{
+		StringBuffer ch_date_string = new StringBuffer();
+		Date _date = null;
+		try{
+			_date = getDateFromString( dateString, style );
+		}catch(Exception e){
+			logger.error( "系统getDateCNString日期格式转换发生异常",  e);
+		}
+		if(_date == null ){
+			_date = new Date();
+		}
+		String year = getYear( _date );
+		String month = getMonth( _date );
+		String day = getDay( _date );
+		String hour = getHour( _date );
+		String min = getMinites( _date );
+		ch_date_string.append( year );
+		ch_date_string.append( "年" );
+		ch_date_string.append( month );
+		ch_date_string.append( "月" );
+		ch_date_string.append( day );
+		ch_date_string.append( "日" );
+		ch_date_string.append( hour );
+		ch_date_string.append( "时" );
+		ch_date_string.append( min );
+		ch_date_string.append( "分" );		
+		return ch_date_string.toString();
+	}
+	
+	/**
+	 * 将时间格式转换为 **月**日**时**分**秒 的格式
+	 * @param dateString
+	 * @param style
+	 * @return
+	 * @throws Exception
+	 */
+	public String getDateCNString2( String dateString, String style ) throws Exception{
+		StringBuffer ch_date_string = new StringBuffer();
+		Date _date = null;
+		try{
+			_date = getDateFromString( dateString, style );
+		}catch(Exception e){
+			logger.error( "系统getDateCNString2日期格式转换发生异常",  e);
+		}
+		if(_date == null ){
+			_date = new Date();
+		}
+		String year = getYear( _date );
+		String month = getMonth( _date );
+		String day = getDay( _date );
+		String hour = getHour( _date );
+		String min = getMinites( _date );
+		String sec = getSeconds( _date );
+		ch_date_string.append( year );
+		ch_date_string.append( "年" );
+		ch_date_string.append( month );
+		ch_date_string.append( "月" );
+		ch_date_string.append( day );
+		ch_date_string.append( "日" );
+		ch_date_string.append( hour );
+		ch_date_string.append( "时" );
+		ch_date_string.append( min );
+		ch_date_string.append( "分" );
+		ch_date_string.append( sec );
+		ch_date_string.append( "秒" );
+		return ch_date_string.toString();
+	}
+	
+	/**
+	 * 获取日期在一年中的周数
+	 * 结果从1开始
+	 * @param dateString yyyy-mm-dd
+	 * @return
+	 */
+	public  int getWeekNumOfYear( String dateString ){
+		try {
+			Date date = getDateFromString( dateString , "yyyy-MM-dd");
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(date);
+			cal.setFirstDayOfWeek(2);//设置每周的第一天是星期一
+	        //月份有问题(这里的月份开始计数为0)
+	        //本年的第几天,在计算时间间隔的时候有用
+	        //System.out.println("一年中的天数:" + cal.get(Calendar.DAY_OF_YEAR));
+	        //System.out.println("一年中的周数:" + cal.get(Calendar.WEEK_OF_YEAR));
+	        //即本月的第几周
+	        //System.out.println("一月中的周数:" + cal.get(Calendar.WEEK_OF_MONTH));
+	        //即一周中的第几天(这里是以周日为第一天的)
+	        //System.out.println("一周中的天数:" + cal.get(Calendar.DAY_OF_WEEK));
+			return cal.get(Calendar.WEEK_OF_YEAR);
+		} catch (ParseException e) {
+			logger.error( "系统getWeekNumOfYear日期格式转换发生异常",  e);
+		} catch (Exception e) {
+			logger.error( "系统getWeekNumOfYear发生异常",  e);
+		}
+		return -1;
+	}
+	
+	/**
+	 * 判断是否周末
+	 * @param recordDate
+	 * @return
+	 */
+	public boolean isWeekend( Date recordDate ) {
+		Calendar cal = Calendar.getInstance();
+	    cal.setTime( recordDate );
+	    if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
+	       return true;
+	    }
+		return false;
+	}
+	
+	public long getMinutes( Date date1, Date data2){
+		 long l=data2.getTime()-date1.getTime();
+		 long min=((l/(60*1000)));
+		 return min;
+	}
+
+	/**
+	 * 根据提供的年份月份,获取当月所有的日期字符串:yyyy-mm-dd
+	 * @param s_year
+	 * @param _month
+	 * @return
+	 */
+	public List<String> getDateStringFormMonth(String s_year, String _month) {
+		List<String> result = new ArrayList<String>();
+		Calendar cal = Calendar.getInstance();
+		int year = 0;
+		int month = 0;
+		int days = 0;
+		try{
+			year = Integer.parseInt( s_year );
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+		try{
+			month = Integer.parseInt( _month );
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+		cal.set(year, month-1, 1);
+		days = cal.getActualMaximum(Calendar.DATE);
+		for( int i =1; i<= days ; i++){
+			result.add( s_year + "-" + (month<10?"0"+month:month) + "-" + (i<10?"0"+i:i));
+		}
+		return result;
+	}
+	
+	/**
+	 * 根据提供的两个时间之间所有的日期字符串:yyyy-mm-dd
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 * @throws Exception 
+	 */
+	public List<String> listDateStringBetweenDate( Date startDate, Date endDate ) throws Exception {		
+		List<String> result = new ArrayList<String>();
+		Calendar cal = Calendar.getInstance();
+		startDate = getDateFromString( getDateStringFromDate( startDate, "yyyy-MM-dd") );
+		endDate = getDateFromString( getDateStringFromDate( endDate, "yyyy-MM-dd") + " 23:59:59");	
+		cal.setTime( startDate );
+		while( cal.getTime().before(endDate)){
+			//logger.debug( getDateStringFromDate( cal.getTime(), "yyyy-MM-dd") );
+			result.add( getDateStringFromDate( cal.getTime(), "yyyy-MM-dd"));
+			cal.add(Calendar.DATE, 1);
+		}
+		return result;
+	}
+	
+	/**
+	 * 获取日期所在月份的第一天
+	 * @param recordDate
+	 * @return
+	 * @throws Exception 
+	 */
+	public Date getFirstDateInMonth(Date recordDate) throws Exception {
+		String year = format8.format(recordDate);
+		String month = format9.format(recordDate);
+		return getDateFromString( year + "-" + month + "-01" );
+	}
+	
+	/**
+	 * 获取日期所在月份的第一天
+	 * @param recordDate yyyy-MM-dd
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getFirstDateStringInMonth(Date recordDate) throws Exception {
+		String year = format8.format(recordDate);
+		String month = format9.format(recordDate);
+		return year + "-" + month + "-01";
+	}
+	
+	/**
+	 * 获取当月的最后一日
+	 * @param date
+	 * @return
+	 */
+	public static Date getLastDayOfMonth(Date date) {  
+        Calendar calendar = convert(date);  
+        calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));  
+        return calendar.getTime();  
+    }  
+	/** 
+     * 将日期转换为日历 
+     * @param date 日期 
+     * @return 日历 
+     */  
+    private static Calendar convert(Date date) {  
+        Calendar calendar = Calendar.getInstance();  
+        calendar.setTime(date);  
+        return calendar;  
+    }  
+	/**
+	 * 获取日期所在月份的第一天
+	 * @param recordDate
+	 * @return
+	 * @throws Exception 
+	 */
+	public Date getLastDateInMonth(Date recordDate) throws Exception {
+		Date lastDate = getLastDayOfMonth(recordDate);
+		return getDateFromString( getDateStringFromDate( lastDate, "yyyy-MM-dd") );
+	}
+	
+	/**
+	 * 获取日期所在月份的第一天
+	 * @param recordDate yyyy-MM-dd
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getLastDateStringInMonth(Date recordDate) throws Exception {
+		Date lastDate = getLastDayOfMonth(recordDate);
+		return getDateStringFromDate( lastDate, "yyyy-MM-dd");
+	}
+}

+ 278 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/Excel2003Reader.java

@@ -0,0 +1,278 @@
+package com.x.attendance.assemble.common.excel.reader;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
+import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
+import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
+import org.apache.poi.hssf.eventusermodel.HSSFListener;
+import org.apache.poi.hssf.eventusermodel.HSSFRequest;
+import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
+import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
+import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
+import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.BoolErrRecord;
+import org.apache.poi.hssf.record.BoundSheetRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.LabelRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SSTRecord;
+import org.apache.poi.hssf.record.StringRecord;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+/**
+ * 抽象Excel2003读取器,通过实现HSSFListener监听器,采用事件驱动模式解析excel2003
+ * 中的内容,遇到特定事件才会触发,大大减少了内存的使用。
+ *
+ */
+public  class Excel2003Reader implements HSSFListener{
+	private int minColumns = -1;
+	private POIFSFileSystem fs;
+	private int lastRowNumber;
+	private int lastColumnNumber;
+
+	/** Should we output the formula, or the value it has? */
+	private boolean outputFormulaValues = true;
+
+	/** For parsing Formulas */
+	private SheetRecordCollectingListener workbookBuildingListener;
+	//excel2003工作薄
+	private HSSFWorkbook stubWorkbook;
+
+	// Records we pick up as we process
+	private SSTRecord sstRecord;
+	private FormatTrackingHSSFListener formatListener;
+
+	//表索引
+	private int sheetIndex = -1;
+	private BoundSheetRecord[] orderedBSRs;
+	@SuppressWarnings("rawtypes")
+	private ArrayList boundSheetRecords = new ArrayList();
+
+	// For handling formulas with string results
+	private int nextRow;
+	private int nextColumn;
+	private boolean outputNextStringRecord;
+	//当前行
+	private int curRow = 0;
+	//存储行记录的容器
+	private List<String> rowlist = new ArrayList<String>();;
+	@SuppressWarnings( "unused")
+	private String sheetName;
+	
+	private String fileKey;
+	private int startRow;
+	private IRowReader rowReader;
+
+	
+	public void setRowReader(IRowReader rowReader, String fileKey, int startRow ){
+		this.rowReader = rowReader;
+		this.fileKey = fileKey;
+		this.startRow = startRow;
+	}
+	
+	/**
+	 * 遍历excel下所有的sheet
+	 * @param fileKey 
+	 * @throws IOException
+	 */
+	public void process(String fileName ) throws IOException {
+		
+		this.fs = new POIFSFileSystem(new FileInputStream(fileName));
+		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener( this);
+		formatListener = new FormatTrackingHSSFListener(listener);
+		HSSFEventFactory factory = new HSSFEventFactory();
+		HSSFRequest request = new HSSFRequest();
+		if ( outputFormulaValues ) {
+			request.addListenerForAllRecords( formatListener );
+		} else {
+			workbookBuildingListener = new SheetRecordCollectingListener( formatListener);
+			request.addListenerForAllRecords(workbookBuildingListener);
+		}
+		factory.processWorkbookEvents(request, fs);
+		//数据读取完成
+		
+	}
+	
+	/**
+	 * 遍历excel下所有的sheet
+	 * @param fileKey 
+	 * @throws IOException
+	 */
+	public void process( InputStream is ) throws IOException {
+		this.fs = new POIFSFileSystem( is );
+		MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener( this);
+		formatListener = new FormatTrackingHSSFListener(listener);
+		HSSFEventFactory factory = new HSSFEventFactory();
+		HSSFRequest request = new HSSFRequest();
+		if ( outputFormulaValues ) {
+			request.addListenerForAllRecords( formatListener );
+		} else {
+			workbookBuildingListener = new SheetRecordCollectingListener( formatListener);
+			request.addListenerForAllRecords(workbookBuildingListener);
+		}
+		factory.processWorkbookEvents(request, fs);
+		//数据读取完成
+		
+	}
+	
+	/**
+	 * HSSFListener 监听方法,处理 Record
+	 */
+	@SuppressWarnings("unchecked")
+	public void processRecord(Record record) {
+		int thisRow = -1;
+		int thisColumn = -1;
+		String thisStr = null;
+		String value = null;
+		switch (record.getSid()) {
+			case BoundSheetRecord.sid:
+				boundSheetRecords.add(record);
+				break;
+			case BOFRecord.sid:
+				BOFRecord br = (BOFRecord) record;
+				if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
+					// 如果有需要,则建立子工作薄
+					if (workbookBuildingListener != null && stubWorkbook == null) {
+						stubWorkbook = workbookBuildingListener
+								.getStubHSSFWorkbook();
+					}
+					
+					sheetIndex++;
+					if (orderedBSRs == null) {
+						orderedBSRs = BoundSheetRecord
+								.orderByBofPosition(boundSheetRecords);
+					}
+					sheetName = orderedBSRs[sheetIndex].getSheetname();
+				}
+				break;
+	
+			case SSTRecord.sid:
+				sstRecord = (SSTRecord) record;
+				break;
+	
+			case BlankRecord.sid:
+				BlankRecord brec = (BlankRecord) record;
+				thisRow = brec.getRow();
+				thisColumn = brec.getColumn();
+				thisStr = "";
+				rowlist.add(thisColumn, thisStr);
+				break;
+			case BoolErrRecord.sid: //单元格为布尔类型
+				BoolErrRecord berec = (BoolErrRecord) record;
+				thisRow = berec.getRow();
+				thisColumn = berec.getColumn();
+				thisStr = berec.getBooleanValue()+"";
+				rowlist.add(thisColumn, thisStr);
+				break;
+	
+			case FormulaRecord.sid: //单元格为公式类型
+				FormulaRecord frec = (FormulaRecord) record;
+				thisRow = frec.getRow();
+				thisColumn = frec.getColumn();
+				if (outputFormulaValues) {
+					if (Double.isNaN(frec.getValue())) {
+						// Formula result is a string
+						// This is stored in the next record
+						outputNextStringRecord = true;
+						nextRow = frec.getRow();
+						nextColumn = frec.getColumn();
+					} else {
+						thisStr = formatListener.formatNumberDateCell(frec);
+					}
+				} else {
+					thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';
+				}
+				rowlist.add(thisColumn,thisStr);
+				break;
+			case StringRecord.sid://单元格中公式的字符串
+				if (outputNextStringRecord) {
+					// String for formula
+					StringRecord srec = (StringRecord) record;
+					thisStr = srec.getString();
+					thisRow = nextRow;
+					thisColumn = nextColumn;
+					outputNextStringRecord = false;
+				}
+				break;
+			case LabelRecord.sid:
+				LabelRecord lrec = (LabelRecord) record;
+				curRow = thisRow = lrec.getRow();
+				thisColumn = lrec.getColumn();
+				value = lrec.getValue().trim();
+				value = value.equals("")?" ":value;
+				this.rowlist.add(thisColumn, value);
+				break;
+			case LabelSSTRecord.sid:  //单元格为字符串类型
+				LabelSSTRecord lsrec = (LabelSSTRecord) record;
+				curRow = thisRow = lsrec.getRow();
+				thisColumn = lsrec.getColumn();
+				if (sstRecord == null) {
+					rowlist.add(thisColumn, " ");
+				} else {
+					value =  sstRecord
+					.getString(lsrec.getSSTIndex()).toString().trim();
+					value = value.equals("")?" ":value;
+					rowlist.add(thisColumn,value);
+				}
+				break;
+			case NumberRecord.sid:  //单元格为数字类型
+				NumberRecord numrec = (NumberRecord) record;
+				curRow = thisRow = numrec.getRow();
+				thisColumn = numrec.getColumn();
+				value = formatListener.formatNumberDateCell(numrec).trim();
+				value = value.equals("")?" ":value;
+				// 向容器加入列值
+				rowlist.add(thisColumn, value);
+				break;
+			default:
+				break;
+		}
+
+		// 遇到新行的操作
+		if (thisRow != -1 && thisRow != lastRowNumber) {
+			lastColumnNumber = -1;
+		}
+
+		// 空值的操作
+		if (record instanceof MissingCellDummyRecord) {
+			MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
+			curRow = thisRow = mc.getRow();
+			thisColumn = mc.getColumn();
+			rowlist.add(thisColumn," ");
+		}
+
+		// 更新行和列的值
+		if (thisRow > -1)
+			lastRowNumber = thisRow;
+		if (thisColumn > -1)
+			lastColumnNumber = thisColumn;
+
+		// 行结束时的操作
+		if (record instanceof LastCellOfRowDummyRecord) {
+			if (minColumns > 0) {
+				// 列值重新置空
+				if (lastColumnNumber == -1) {
+					lastColumnNumber = 0;
+				}
+			}
+			lastColumnNumber = -1;
+			// 每行结束时, 调用getRows() 方法
+			
+			rowReader.getRows(sheetIndex,curRow, rowlist, this.fileKey, this.startRow );
+			
+			// 清空容器
+			rowlist.clear();
+		}
+	}
+	
+}

+ 211 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/Excel2007Reader.java

@@ -0,0 +1,211 @@
+package com.x.attendance.assemble.common.excel.reader;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.xssf.eventusermodel.XSSFReader;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * 抽象Excel2007读取器,excel2007的底层数据结构是xml文件,采用SAX的事件驱动的方法解析
+ * xml,需要继承DefaultHandler,在遇到文件内容时,事件会触发,这种做法可以大大降低
+ * 内存的耗费,特别使用于大数据量的文件。
+ *
+ */
+public class Excel2007Reader extends DefaultHandler {
+	//共享字符串表
+	private SharedStringsTable sst;
+	//上一次的内容
+	private String lastContents;
+	
+	private boolean nextIsString;
+
+	private int sheetIndex = -1;
+	
+	private List<String> rowlist = new ArrayList<String>();
+	//当前行
+	private int curRow = 0;
+	//当前列
+	private int curCol = 0;
+	//日期标志
+	private boolean dateFlag;
+	//数字标志
+	private boolean numberFlag;
+	
+	private boolean isTElement;
+	
+	private String fileKey;
+	private int startRow;
+	private IRowReader rowReader;
+	
+	public void setRowReader(IRowReader rowReader, String fileKey, int startRow){
+		this.rowReader = rowReader;
+		this.fileKey = fileKey;
+		this.startRow = startRow;
+	}
+	
+	/**只遍历一个电子表格,其中sheetId为要遍历的sheet索引,从1开始,1-3
+	 * @param filename
+	 * @param sheetId
+	 * @throws Exception
+	 */
+	public void processOneSheet(String filename,int sheetId) throws Exception {
+		OPCPackage pkg = OPCPackage.open(filename);
+		XSSFReader r = new XSSFReader(pkg);
+		SharedStringsTable sst = r.getSharedStringsTable();
+		XMLReader parser = fetchSheetParser(sst);
+		
+		// 根据 rId# 或 rSheet# 查找sheet
+		InputStream sheet2 = r.getSheet("rId"+sheetId);
+		sheetIndex++;
+		InputSource sheetSource = new InputSource(sheet2);
+		parser.parse(sheetSource);
+		sheet2.close();
+	}
+
+	/**
+	 * 遍历工作簿中所有的电子表格
+	 * @param filename
+	 * @param fileKey 
+	 * @throws Exception
+	 */
+	public void process( String filename ) throws Exception {
+		OPCPackage pkg = OPCPackage.open(filename);
+		XSSFReader r = new XSSFReader(pkg);
+		SharedStringsTable sst = r.getSharedStringsTable();
+		XMLReader parser = fetchSheetParser(sst);
+		Iterator<InputStream> sheets = r.getSheetsData();
+		while (sheets.hasNext()) {
+			curRow = 0;
+			sheetIndex++;
+			InputStream sheet = sheets.next();
+			InputSource sheetSource = new InputSource(sheet);
+			parser.parse( sheetSource );
+			sheet.close();
+		}
+		//数据读取完成
+	}
+
+	public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
+		XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+		this.sst = sst;
+		parser.setContentHandler(this);
+		return parser;
+	}
+
+	public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
+		
+		// c => 单元格
+		if ("c".equals(name)) {
+			// 如果下一个元素是 SST 的索引,则将nextIsString标记为true
+			String cellType = attributes.getValue("t");
+			if ("s".equals(cellType)) {
+				nextIsString = true;
+			} else {
+				nextIsString = false;
+			}
+			//日期格式
+			String cellDateType = attributes.getValue("s");
+			if ("1".equals(cellDateType)){
+				dateFlag = true;
+			} else {
+				dateFlag = false;
+			}
+			String cellNumberType = attributes.getValue("s");
+			if("2".equals(cellNumberType)){
+				numberFlag = true;
+			} else {
+				numberFlag = false;
+			}
+			
+		}
+		//当元素为t时
+		if("t".equals(name)){
+			isTElement = true;
+		} else {
+			isTElement = false;
+		}
+		
+		// 置空
+		lastContents = "";
+	}
+
+	public void endElement(String uri, String localName, String name)
+			throws SAXException {
+		
+		// 根据SST的索引值的到单元格的真正要存储的字符串
+		// 这时characters()方法可能会被调用多次
+		if (nextIsString) {
+			try {
+				int idx = Integer.parseInt(lastContents);
+				lastContents = new XSSFRichTextString(sst.getEntryAt(idx))
+						.toString();
+			} catch (Exception e) {
+
+			}
+		} 
+		//t元素也包含字符串
+		if(isTElement){
+			String value = lastContents.trim();
+			rowlist.add(curCol, value);
+			curCol++;
+			isTElement = false;
+			// v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
+			// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
+		} else if ("v".equals(name)) {
+			String value = lastContents.trim();
+			value = value.equals("")?" ":value;
+			//日期格式处理
+			if(dateFlag){
+				try{
+					Date date = HSSFDateUtil.getJavaDate(Double.valueOf(value));
+					SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
+					value = dateFormat.format(date);
+				}catch(Exception e){
+					
+				}
+			} 
+			//数字类型处理
+			if(numberFlag){
+				try{
+					BigDecimal bd = new BigDecimal(value);
+					value = bd.setScale(3,BigDecimal.ROUND_UP).toString();
+				}catch(Exception e){
+					
+				}
+			}
+			rowlist.add(curCol, value);
+			curCol++;
+		}else {
+			//如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
+			if (name.equals("row")) {
+				
+				rowReader.getRows(sheetIndex,curRow,rowlist, this.fileKey, this.startRow );
+				rowlist.clear();
+				curRow++;
+				curCol = 0;
+			}
+		}
+		
+	}
+
+	public void characters(char[] ch, int start, int length)
+			throws SAXException {
+		//得到单元格内容的值
+		lastContents += new String(ch, start, length);
+	}
+}

+ 31 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/ExcelReaderUtil.java

@@ -0,0 +1,31 @@
+package com.x.attendance.assemble.common.excel.reader;
+public class ExcelReaderUtil {
+	
+	//excel2003扩展名
+	public static final String EXCEL03_EXTENSION = ".xls";
+	//excel2007扩展名
+	public static final String EXCEL07_EXTENSION = ".xlsx";
+	
+	/**
+	 * 读取Excel文件,可能是03也可能是07版本
+	 * @param excel03
+	 * @param excel07
+	 * @param fileName
+	 * @throws Exception 
+	 */
+	public static void readExcel(IRowReader reader, String fileName, String fileKey, int startRow ) throws Exception{
+		// 处理excel2003文件
+		if (fileName.endsWith(EXCEL03_EXTENSION)){
+			Excel2003Reader excel03 = new Excel2003Reader();
+			excel03.setRowReader(reader, fileKey, startRow);
+			excel03.process(fileName);
+		// 处理excel2007文件
+		} else if (fileName.endsWith(EXCEL07_EXTENSION)){
+			Excel2007Reader excel07 = new Excel2007Reader();
+			excel07.setRowReader(reader, fileKey, startRow);
+			excel07.process(fileName);
+		} else {
+			throw new  Exception("文件格式错误,fileName的扩展名只能是xls或xlsx。");
+		}
+	}
+}

+ 13 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/IRowReader.java

@@ -0,0 +1,13 @@
+package com.x.attendance.assemble.common.excel.reader;
+
+import java.util.List;
+
+public interface IRowReader {
+	
+	/**业务逻辑实现方法
+	 * @param sheetIndex
+	 * @param curRow
+	 * @param rowlist
+	 */
+	public  void getRows(int sheetIndex,int curRow, List<String> rowlist, String fileKey, int startRow);
+}

+ 213 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/reader/UserModelEventListener.java

@@ -0,0 +1,213 @@
+package com.x.attendance.assemble.common.excel.reader;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
+import org.apache.poi.hssf.eventusermodel.HSSFListener;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.BoolErrRecord;
+import org.apache.poi.hssf.record.BoundSheetRecord;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.LabelSSTRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.SSTRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * 基于POI HSSF的eventmodel 模型的时间解析方式
+ *   优点:解析数据相当快。
+ *   缺点:1.仅仅支持97~2003版本的excel,不支持2007版本的excel。
+ *         2.只能读Excel中一个Sheet页面。
+ * 
+ * @Title: 
+ * @Description: 实现TODO
+ * @Copyright:Copyright (c) 2011
+ * @Company:易程科技股份有限公司
+ * @Date:2012-6-14
+ * @author  longgangbai
+ * @version 1.0
+ */
+public class UserModelEventListener implements HSSFListener {
+	private static Logger logger=LoggerFactory.getLogger(UserModelEventListener.class);
+	private SSTRecord sstrec;
+	/** Should we output the formula, or the value it has? */
+	private boolean outputFormulaValues = true;
+	/** For parsing Formulas */
+	private SheetRecordCollectingListener workbookBuildingListener;
+
+    //当前Sheet的内容
+    private List<Map<String,Object>> currentSheetDataMap=new ArrayList<Map<String,Object>>();
+    //列对应的字段
+	private static String[] trianListheadTitle=new String[]{"trainCode","firstStation","lastStation","startStation","arriveStation","startTime","arriveTime","fistLevelPrice","secondLevelPrice","km","useDate"};
+
+    //一行记录
+    private Map<String,Object> currentSheetRowDataMap=new HashMap<String,Object>();
+    private int curRowNum=0;
+    private int ignoreRowNum=1;
+    private int sheetNo=0;
+    
+	@Override
+	public void processRecord(org.apache.poi.hssf.record.Record record) {
+		switch (record.getSid()) {
+		
+		case BOFRecord.sid:
+			BOFRecord bof = (BOFRecord) record;
+			//顺序进入新的Workbook  
+			if (bof.getType() == bof.TYPE_WORKBOOK) {
+				logger.debug("开始解析excel 文档.....");
+			//顺序进入新的Worksheet,因为Event API不会把Excel文件里的所有数据结构都关联起来,
+			//所以这儿一定要记录现在进入第几个sheet了。
+			} else if (bof.getType() == bof.TYPE_WORKSHEET) {
+				//读取新的一个Sheet页
+				logger.debug("开始解析sheet页面内容...");
+				System.out.println("sheetNo="+sheetNo);
+				sheetNo++;
+				currentSheetDataMap=new ArrayList<Map<String,Object>>();
+			}
+			break;
+	    //开始解析Sheet的信息,记录sheet,这儿会把所有的sheet都顺序打印出来,如果有多个sheet的话,可以顺序记入到一个List里   
+		case BoundSheetRecord.sid:
+			BoundSheetRecord bsr = (BoundSheetRecord) record;
+			System.out.println("sheetName="+bsr.getSheetname());
+			logger.debug("New sheet named: " + bsr.getSheetname());
+			break;
+		//执行行记录事件
+		case RowRecord.sid:
+			RowRecord rowrec = (RowRecord) record;
+			logger.debug("记录开始, first column at "
+					+ rowrec.getFirstCol() + " last column at "
+					+ rowrec.getLastCol());
+			break;
+		// SSTRecords store a array of unique strings used in Excel.
+		case SSTRecord.sid:
+			sstrec = (SSTRecord) record;
+			for (int k = 0; k < sstrec.getNumUniqueStrings(); k++) {
+				logger.debug("String table value " + k + " = "
+						+ sstrec.getString(k));
+			}
+			break;
+			
+		//发现数字类型的cell,因为数字和日期都是用这个格式,所以下面一定要判断是不是日期格式,另外默认的数字也会被视为日期格式,所以如果是数字的话,一定要明确指定格式!!!!!!!   
+		case NumberRecord.sid:
+				NumberRecord nr = (NumberRecord) record;
+				//HSSFDateUtil.isInternalDateFormat(nr.getXFIndex())  判断是否为时间列
+				int column=nr.getColumn();
+				if(column==5||column==6){
+					addDataAndrChangeRow(nr.getRow(),nr.getColumn(),getTime(nr.getValue()));
+				}else{
+					addDataAndrChangeRow(nr.getRow(),nr.getColumn(),(int)nr.getValue());
+				}
+				break;
+		//发现字符串类型,这儿要取字符串的值的话,跟据其index去字符串表里读取   
+		case LabelSSTRecord.sid:
+			LabelSSTRecord lsr = (LabelSSTRecord)record; 
+			addDataAndrChangeRow(lsr.getRow(),lsr.getColumn(), sstrec.getString(lsr.getSSTIndex()));
+			logger.debug("文字列:"+sstrec.getString(lsr.getSSTIndex())+", 行:"+lsr.getRow()+", 列:"+lsr.getColumn());   
+			break;
+	    case BoolErrRecord.sid: //解析boolean错误信息
+            BoolErrRecord ber = (BoolErrRecord)record;   
+            if(ber.isBoolean()){   
+            	addDataAndrChangeRow(ber.getRow(),ber.getColumn(), ber.getBooleanValue());
+            	logger.debug("Boolean:"+ber.getBooleanValue()+", 行:"+ber.getRow()+", 列:"+ber.getColumn());   
+            }   
+            if(ber.isError()){   
+            	logger.debug("Error:"+ber.getErrorValue()+", 行:"+ber.getRow()+", 列:"+ber.getColumn());   
+            }   
+            break;   
+         //空白记录的信息
+        case BlankRecord.sid: 
+            BlankRecord br = (BlankRecord)record;   
+            addDataAndrChangeRow(br.getRow(),br.getColumn(), "");
+            logger.debug("空。 行:"+br.getRow()+", 列:"+br.getColumn());   
+            break;   
+        case FormulaRecord.sid: //数式   
+            FormulaRecord fr = (FormulaRecord)record;  
+            addDataAndrChangeRow(fr.getRow(),fr.getColumn(), fr.getValue());
+            logger.debug("数字 。 行:"+fr.getRow()+", 列:"+fr.getColumn());  
+            break;  
+		}
+	}
+	/** 
+     * HH:MM格式时间的数字转换方法</li> 
+     * @param sNum 
+     * @return 
+     */ 
+    private static String getTime(double daynum) 
+    { 
+        double totalSeconds=daynum*86400.0D;
+        //总的分钟数
+        int seconds =(int)totalSeconds/60;
+        //实际小时数
+        int hours =seconds/60;
+        int minutes = seconds-hours*60;
+        //剩余的实际分钟数
+        StringBuffer sb=new StringBuffer();
+        if(String.valueOf(hours).length()==1){
+        	sb.append("0"+hours);
+        }else{
+        	sb.append(hours);
+        }
+        sb.append(":");
+        if(String.valueOf(minutes).length()==1){
+        	sb.append("0"+minutes);
+        }else{
+        	sb.append(minutes);
+        }
+        return sb.toString();
+    } 
+	/**
+	 *  添加数据记录并检查是否换行
+	 * @param row 实际当前行号
+	 * @param col 实际记录当前列
+	 * @param value  当前cell的值
+	 */
+	public void addDataAndrChangeRow(int row,int col,Object value){
+		//当前行如果大于实际行表示改行忽略,不记录
+		if(curRowNum!=row){
+			if(CollectionUtils.isEmpty(currentSheetDataMap)){
+				 currentSheetDataMap=new ArrayList<Map<String,Object>>();
+			}
+			currentSheetDataMap.add(currentSheetRowDataMap);
+			logger.debug("行号:"+curRowNum +" 行内容:"+currentSheetRowDataMap.toString());
+			logger.debug("\n");
+			currentSheetRowDataMap=new HashMap<String,Object>();
+			currentSheetRowDataMap.put(trianListheadTitle[col], value);
+			logger.debug(row+":"+col+"  "+value+"\r");
+			curRowNum=row;
+		}else{
+			currentSheetRowDataMap.put(trianListheadTitle[col], value);
+			logger.debug(row+":"+col+"  "+value+"\r");
+		}
+	}
+	public List<Map<String, Object>> getCurrentSheetDataMap() {
+		return currentSheetDataMap;
+	}
+	public void setCurrentSheetDataMap(List<Map<String, Object>> currentSheetDataMap) {
+		this.currentSheetDataMap = currentSheetDataMap;
+	}
+	public Map<String, Object> getCurrentSheetRowDataMap() {
+		return currentSheetRowDataMap;
+	}
+	public void setCurrentSheetRowDataMap(Map<String, Object> currentSheetRowDataMap) {
+		this.currentSheetRowDataMap = currentSheetRowDataMap;
+	}
+	public int getCurRowNum() {
+		return curRowNum;
+	}
+	public void setCurRowNum(int curRowNum) {
+		this.curRowNum = curRowNum;
+	}
+	public int getIgnoreRowNum() {
+		return ignoreRowNum;
+	}
+	public void setIgnoreRowNum(int ignoreRowNum) {
+		this.ignoreRowNum = ignoreRowNum;
+	}
+
+}

+ 225 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/AbstractExcel2007Writer.java

@@ -0,0 +1,225 @@
+package com.x.attendance.assemble.common.excel.writer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+/**
+ * 抽象excel2007读入器,先构建.xlsx一张模板,改写模板中的sheet.xml,使用这种方法
+ * 写入.xlsx文件,不需要太大的内存
+ *
+ */
+public abstract class AbstractExcel2007Writer {
+	
+	private SpreadsheetWriter sw;
+
+	/**
+	 * 写入电子表格的主要流程
+	 * @param fileName
+	 * @throws Exception
+	 */
+	public void process(String fileName) throws Exception{
+		// 建立工作簿和电子表格对象
+		XSSFWorkbook wb = new XSSFWorkbook();
+		XSSFSheet sheet = wb.createSheet("sheet1");
+		// 持有电子表格数据的xml文件名 例如 /xl/worksheets/sheet1.xml
+		String sheetRef = sheet.getPackagePart().getPartName().getName();
+
+		// 保存模板
+		FileOutputStream os = new FileOutputStream("template.xlsx");
+		wb.write(os);
+		os.close();
+		
+		// 生成xml文件
+		File tmp = File.createTempFile("sheet", ".xml");
+		Writer fw = new FileWriter(tmp);
+		sw = new SpreadsheetWriter(fw);
+		generate();
+		fw.close();
+		
+		// 使用产生的数据替换模板
+		File templateFile = new File("template.xlsx");
+		FileOutputStream out = new FileOutputStream(fileName);
+		substitute(templateFile, tmp, sheetRef.substring(1), out);
+		out.close();
+		//删除文件之前调用一下垃圾回收器,否则无法删除模板文件
+		System.gc();
+		// 删除临时模板文件
+		if (templateFile.isFile()&&templateFile.exists()){
+			templateFile.delete();
+		}
+	}
+
+	/**
+	 * 类使用者应该使用此方法进行写操作
+	 * @throws Exception
+	 */
+	public abstract void generate() throws Exception;
+
+	public void beginSheet() throws IOException {
+		sw.beginSheet();
+	}
+
+	public void insertRow(int rowNum) throws IOException {
+		sw.insertRow(rowNum);
+	}
+
+	public void createCell(int columnIndex, String value) throws IOException {
+		sw.createCell(columnIndex, value, -1);
+	}
+
+	public void createCell(int columnIndex, double value) throws IOException {
+		sw.createCell(columnIndex, value, -1);
+	}
+
+	public void endRow() throws IOException {
+		sw.endRow();
+	}
+
+	public void endSheet() throws IOException {
+		sw.endSheet();
+	}
+
+	/**
+	 *
+	 * @param zipfile the template file
+	 * @param tmpfile the XML file with the sheet data
+	 * @param entry the name of the sheet entry to substitute, e.g. xl/worksheets/sheet1.xml
+	 * @param out the stream to write the result to
+	 */
+	private static void substitute(File zipfile, File tmpfile, String entry,
+			OutputStream out) throws IOException {
+		ZipFile zip = new ZipFile(zipfile);
+		ZipOutputStream zos = new ZipOutputStream(out);
+
+		@SuppressWarnings("unchecked")
+		Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) zip.entries();
+		while (en.hasMoreElements()) {
+			ZipEntry ze = en.nextElement();
+			if (!ze.getName().equals(entry)) {
+				zos.putNextEntry(new ZipEntry(ze.getName()));
+				InputStream is = zip.getInputStream(ze);
+				copyStream(is, zos);
+				is.close();
+			}
+		}
+		zos.putNextEntry(new ZipEntry(entry));
+		InputStream is = new FileInputStream(tmpfile);
+		copyStream(is, zos);
+		is.close();
+		zos.close();
+	}
+
+	private static void copyStream(InputStream in, OutputStream out)
+			throws IOException {
+		byte[] chunk = new byte[1024];
+		int count;
+		while ((count = in.read(chunk)) >= 0) {
+			out.write(chunk, 0, count);
+		}
+	}
+
+	/**
+	 * 在写入器中写入电子表格
+	 * 
+	 */
+	public static class SpreadsheetWriter {
+		private final Writer _out;
+		private int _rownum;
+		private static String LINE_SEPARATOR = System.getProperty("line.separator");
+
+		public SpreadsheetWriter(Writer out) {
+			_out = out;
+		}
+
+		public void beginSheet() throws IOException {
+			_out.write("<?xml version=\"1.0\" encoding=\"GB2312\"?>"
+							+ "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">");
+			_out.write("<sheetData>"+LINE_SEPARATOR);
+		}
+
+		public void endSheet() throws IOException {
+			_out.write("</sheetData>");
+			_out.write("</worksheet>");
+		}
+
+		/**
+		 * 插入新行
+		 *
+		 * @param rownum 以0开始
+		 */
+		public void insertRow(int rownum) throws IOException {
+			_out.write("<row r=\"" + (rownum + 1) + "\">"+LINE_SEPARATOR);
+			this._rownum = rownum;
+		}
+
+		/**
+		 * 插入行结束标志
+		 */
+		public void endRow() throws IOException {
+			_out.write("</row>"+LINE_SEPARATOR);
+		}
+
+		/**
+		 * 插入新列
+		 * @param columnIndex
+		 * @param value
+		 * @param styleIndex
+		 * @throws IOException
+		 */
+		public void createCell(int columnIndex, String value, int styleIndex)
+				throws IOException {
+			String ref = new CellReference(_rownum, columnIndex)
+					.formatAsString();
+			_out.write("<c r=\"" + ref + "\" t=\"inlineStr\"");
+			if (styleIndex != -1)
+				_out.write(" s=\"" + styleIndex + "\"");
+			_out.write(">");
+			_out.write("<is><t>"+XMLEncoder.encode(value)+"</t></is>");
+			_out.write("</c>");
+		}
+
+		public void createCell(int columnIndex, String value)
+				throws IOException {
+			createCell(columnIndex, value, -1);
+		}
+
+		public void createCell(int columnIndex, double value, int styleIndex)
+				throws IOException {
+			String ref = new CellReference(_rownum, columnIndex)
+					.formatAsString();
+			_out.write("<c r=\"" + ref + "\" t=\"n\"");
+			if (styleIndex != -1)
+				_out.write(" s=\"" + styleIndex + "\"");
+			_out.write(">");
+			_out.write("<v>" + value + "</v>");
+			_out.write("</c>");
+		}
+
+		public void createCell(int columnIndex, double value)
+				throws IOException {
+			createCell(columnIndex, value, -1);
+		}
+
+		public void createCell(int columnIndex, Calendar value, int styleIndex)
+				throws IOException {
+			createCell(columnIndex, DateUtil.getExcelDate(value, false),
+					styleIndex);
+		}
+	}
+}

+ 62 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/Excel2003Writer.java

@@ -0,0 +1,62 @@
+package com.x.attendance.assemble.common.excel.writer;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+
+public class Excel2003Writer {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		try{	
+			System.out.println("开始写入excel2003....");
+			writeExcel("tes2003.xls");
+			System.out.println("写完xcel2003");
+		} catch (IOException e) {
+		
+		}
+	}
+	
+	
+	/**
+	 * 写入excel并填充内容,一个sheet只能写65536行以下,超出会报异常,写入时建议使用AbstractExcel2007Writer
+	 * @param fileName
+	 * @throws IOException
+	 */
+	public static void writeExcel(String fileName) throws IOException{
+			
+			// 创建excel2003对象
+			Workbook wb = new HSSFWorkbook();
+			
+			// 设置文件放置路径和文件名
+		    FileOutputStream fileOut = new FileOutputStream(fileName);
+		    // 创建新的表单
+		    Sheet sheet = wb.createSheet("newsheet");
+		    // 创建新行
+		    for(int i=0;i<20000;i++){
+			    Row row = sheet.createRow(i);
+			    // 创建单元格
+			    Cell cell = row.createCell(0);
+			    // 设置单元格值
+			    cell.setCellValue(1);
+			    row.createCell(1).setCellValue(1+i);
+			    row.createCell(2).setCellValue(true);
+			    row.createCell(3).setCellValue(0.43d);
+			    row.createCell(4).setCellValue('d');
+			    row.createCell(5).setCellValue("");
+			    row.createCell(6).setCellValue("第七列"+i);
+			    row.createCell(7).setCellValue("第八列"+i);
+		    }
+		    wb.write(fileOut);
+		    fileOut.close();
+	}
+
+
+}

+ 49 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/Excel2007WriterImpl.java

@@ -0,0 +1,49 @@
+package com.x.attendance.assemble.common.excel.writer;
+public class Excel2007WriterImpl extends AbstractExcel2007Writer{
+
+	
+	/**
+	 * @param args
+	 * @throws Exception
+	 */
+	public static void main(String[] args) throws Exception {
+		// TODO Auto-generated method stub
+		System.out.println("............................");
+		long start = System.currentTimeMillis();
+		//构建excel2007写入器
+		AbstractExcel2007Writer excel07Writer = new Excel2007WriterImpl();
+		//调用处理方法
+		excel07Writer.process("F://test07.xlsx");
+		long end = System.currentTimeMillis();
+		System.out.println("....................."+(end-start)/1000);
+	}
+
+	
+	/* 
+	 * 可根据需求重写此方法,对于单元格的小数或者日期格式,会出现精度问题或者日期格式转化问题,建议使用字符串插入方法
+	 * @see com.excel.ver2.AbstractExcel2007Writer#generate()
+	 */
+	@Override
+	public void generate()throws Exception {
+        //电子表格开始
+        beginSheet();
+        for (int rownum = 0; rownum < 100; rownum++) {
+        	//插入新行
+            insertRow(rownum);
+            //建立新单元格,索引值从0开始,表示第一列
+            createCell(0, "中国<" + rownum + "!");
+            createCell(1, 34343.123456789);
+            createCell(2, "23.67%");
+            createCell(3, "12:12:23");
+            createCell(4, "2010-10-11 12:12:23");
+            createCell(5, "true");
+            createCell(6, "false");
+          
+            //结束行
+            endRow();
+        }
+        //电子表格结束
+        endSheet();
+	}
+
+}

+ 48 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/excel/writer/XMLEncoder.java

@@ -0,0 +1,48 @@
+package com.x.attendance.assemble.common.excel.writer;
+
+public class XMLEncoder {
+
+    private static final String[] xmlCode = new String[256];
+
+    static {
+        // Special characters
+        xmlCode['\''] = "'";
+        xmlCode['\"'] = "\""; // double quote
+        xmlCode['&'] = "&"; // ampersand
+        xmlCode['<'] = "<"; // lower than
+        xmlCode['>'] = ">"; // greater than
+    }
+
+    /**
+     * <p>
+     * Encode the given text into xml.
+     * </p>
+     * 
+     * @param string the text to encode
+     * @return the encoded string
+     */
+    public static String encode(String string) {
+        if (string == null) return "";
+        int n = string.length();
+        char character;
+        String xmlchar;
+        StringBuffer buffer = new StringBuffer();
+        // loop over all the characters of the String.
+        for (int i = 0; i < n; i++) {
+            character = string.charAt(i);
+            // the xmlcode of these characters are added to a StringBuffer one by one
+            try {
+                xmlchar = xmlCode[character];
+                if (xmlchar == null) {
+                    buffer.append(character);
+                } else {
+                    buffer.append(xmlCode[character]);
+                }
+            } catch (ArrayIndexOutOfBoundsException aioobe) {
+                buffer.append(character);
+            }
+        }
+        return buffer.toString();
+    }
+
+}

+ 24 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/AbstractFactory.java

@@ -0,0 +1,24 @@
+package com.x.attendance.assemble.control;
+
+import com.x.base.core.container.EntityManagerContainer;
+
+public abstract class AbstractFactory {
+
+	private Business business;
+
+	public AbstractFactory( Business business ) throws Exception {
+		try {
+			if ( null == business ) {
+				throw new Exception("business can not be null.");
+			}
+			this.business = business;
+		} catch ( Exception e ) {
+			throw new Exception("can not instantiating factory.");
+		}
+	}
+
+	public EntityManagerContainer entityManagerContainer() throws Exception {
+		return this.business.entityManagerContainer();
+	}
+
+}

+ 11 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ApplicationGobal.java

@@ -0,0 +1,11 @@
+package com.x.attendance.assemble.control;
+
+import java.util.Map;
+
+import com.x.attendance.assemble.control.jaxrs.fileimport.CacheImportFileStatus;
+
+public class ApplicationGobal {
+	
+	public static Map<String, CacheImportFileStatus> importFileCheckResultMap = null;	
+	
+}

+ 18 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ApplicationServletContextListener.java

@@ -0,0 +1,18 @@
+package com.x.attendance.assemble.control;
+
+import javax.servlet.annotation.WebListener;
+
+import com.x.base.core.project.AbstractApplicationServletContextListener;
+import com.x.base.core.project.ThisApplicationClass;
+import com.x.base.core.project.x_attendance_assemble_control;
+
+@WebListener
+@ThisApplicationClass(ThisApplication.class)
+public class ApplicationServletContextListener extends AbstractApplicationServletContextListener {
+
+	@Override
+	public Class<?> getThis() {
+		return x_attendance_assemble_control.class;
+	}
+
+}

+ 199 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/Business.java

@@ -0,0 +1,199 @@
+package com.x.attendance.assemble.control;
+
+import com.x.attendance.assemble.control.factory.AttendanceAdminFactory;
+import com.x.attendance.assemble.control.factory.AttendanceAppealInfoFactory;
+import com.x.attendance.assemble.control.factory.AttendanceDetailFactory;
+import com.x.attendance.assemble.control.factory.AttendanceDetailMobileFactory;
+import com.x.attendance.assemble.control.factory.AttendanceDetailStatisticFactory;
+import com.x.attendance.assemble.control.factory.AttendanceEmployeeConfigFactory;
+import com.x.attendance.assemble.control.factory.AttendanceImportFileInfoFactory;
+import com.x.attendance.assemble.control.factory.AttendanceScheduleSettingFactory;
+import com.x.attendance.assemble.control.factory.AttendanceSelfHolidayFactory;
+import com.x.attendance.assemble.control.factory.AttendanceSettingFactory;
+import com.x.attendance.assemble.control.factory.AttendanceStatisticRequireLogFactory;
+import com.x.attendance.assemble.control.factory.AttendanceStatisticalCycleFactory;
+import com.x.attendance.assemble.control.factory.AttendanceWorkDayConfigFactory;
+import com.x.attendance.assemble.control.factory.StatisticCompanyForDayFactory;
+import com.x.attendance.assemble.control.factory.StatisticCompanyForMonthFactory;
+import com.x.attendance.assemble.control.factory.StatisticDepartmentForDayFactory;
+import com.x.attendance.assemble.control.factory.StatisticDepartmentForMonthFactory;
+import com.x.attendance.assemble.control.factory.StatisticPersonForMonthFactory;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.organization.core.express.Organization;
+
+public class Business {
+
+	private EntityManagerContainer emc;
+	
+	public Business(EntityManagerContainer emc) throws Exception {
+		this.emc = emc;
+	}
+	public EntityManagerContainer entityManagerContainer() {
+		return this.emc;
+	}
+	
+	//人员组织业务处理类
+	private Organization organization;
+	//系统配置业务处理类
+	private AttendanceSettingFactory attendanceSettingFactory;
+	//节假日工作日配置业务处理类
+	private AttendanceWorkDayConfigFactory attendanceWorkDayConfigFactory;
+	//人员考勤数据导入文件操作业务处理类
+	private AttendanceImportFileInfoFactory attendanceImportFileInfoFactory;
+	//人员考勤数据业务处理类
+	private AttendanceDetailFactory attendanceDetailFactory;
+	private AttendanceDetailMobileFactory attendanceDetailMobileFactory;
+	//考勤管理员业务处理类
+	private AttendanceAdminFactory attendanceAdminFactory;
+	//排班管理业务处理类
+	private AttendanceScheduleSettingFactory attendanceScheduleSettingFactory;
+	//休假申请数据业务处理类
+	private AttendanceSelfHolidayFactory attendanceSelfHolidayFactory;
+	
+	private StatisticCompanyForDayFactory statisticCompanyForDayFactory;
+	
+	private StatisticCompanyForMonthFactory statisticCompanyForMonthFactory;
+	
+	private StatisticDepartmentForDayFactory statisticDepartmentForDayFactory;
+	
+	private StatisticDepartmentForMonthFactory statisticDepartmentForMonthFactory;
+	
+	private StatisticPersonForMonthFactory statisticPersonForMonthFactory;
+	
+	private AttendanceAppealInfoFactory attendanceAppealInfoFactory;
+	
+	private AttendanceStatisticalCycleFactory attendanceStatisticalCycleFactory;
+	
+	private AttendanceEmployeeConfigFactory attendanceEmployeeConfigFactory;
+	
+	private AttendanceStatisticRequireLogFactory attendanceStatisticRequireLogFactory;
+	
+	private AttendanceDetailStatisticFactory attendanceDetailStatisticFactory;
+	
+	public AttendanceDetailMobileFactory getAttendanceDetailMobileFactory() throws Exception {
+		if (null == this.attendanceDetailMobileFactory) {
+			this.attendanceDetailMobileFactory = new AttendanceDetailMobileFactory( this );
+		}
+		return attendanceDetailMobileFactory;
+	}
+	
+	public AttendanceDetailStatisticFactory getAttendanceDetailStatisticFactory() throws Exception {
+		if (null == this.attendanceDetailStatisticFactory) {
+			this.attendanceDetailStatisticFactory = new AttendanceDetailStatisticFactory( this );
+		}
+		return attendanceDetailStatisticFactory;
+	}
+	
+	public AttendanceEmployeeConfigFactory getAttendanceEmployeeConfigFactory() throws Exception {
+		if (null == this.attendanceEmployeeConfigFactory) {
+			this.attendanceEmployeeConfigFactory = new AttendanceEmployeeConfigFactory( this );
+		}
+		return attendanceEmployeeConfigFactory;
+	}
+	
+	public AttendanceStatisticRequireLogFactory getAttendanceStatisticRequireLogFactory() throws Exception {
+		if (null == this.attendanceStatisticRequireLogFactory) {
+			this.attendanceStatisticRequireLogFactory = new AttendanceStatisticRequireLogFactory( this );
+		}
+		return attendanceStatisticRequireLogFactory;
+	}
+	
+	public AttendanceStatisticalCycleFactory getAttendanceStatisticalCycleFactory() throws Exception {
+		if (null == this.attendanceStatisticalCycleFactory) {
+			this.attendanceStatisticalCycleFactory = new AttendanceStatisticalCycleFactory( this );
+		}
+		return attendanceStatisticalCycleFactory;
+	}
+	
+	public AttendanceAppealInfoFactory getAttendanceAppealInfoFactory() throws Exception {
+		if (null == this.attendanceAppealInfoFactory) {
+			this.attendanceAppealInfoFactory = new AttendanceAppealInfoFactory( this );
+		}
+		return attendanceAppealInfoFactory;
+	}
+	
+	public StatisticCompanyForDayFactory getStatisticCompanyForDayFactory() throws Exception {
+		if (null == this.statisticCompanyForDayFactory) {
+			this.statisticCompanyForDayFactory = new StatisticCompanyForDayFactory( this );
+		}
+		return statisticCompanyForDayFactory;
+	}
+	public StatisticCompanyForMonthFactory getStatisticCompanyForMonthFactory() throws Exception {
+		if (null == this.statisticCompanyForMonthFactory) {
+			this.statisticCompanyForMonthFactory = new StatisticCompanyForMonthFactory( this );
+		}
+		return statisticCompanyForMonthFactory;
+	}
+	public StatisticDepartmentForDayFactory getStatisticDepartmentForDayFactory() throws Exception {
+		if (null == this.statisticDepartmentForDayFactory) {
+			this.statisticDepartmentForDayFactory = new StatisticDepartmentForDayFactory( this );
+		}
+		return statisticDepartmentForDayFactory;
+	}
+	public StatisticDepartmentForMonthFactory getStatisticDepartmentForMonthFactory() throws Exception {
+		if (null == this.statisticDepartmentForMonthFactory) {
+			this.statisticDepartmentForMonthFactory = new StatisticDepartmentForMonthFactory( this );
+		}
+		return statisticDepartmentForMonthFactory;
+	}
+	public StatisticPersonForMonthFactory getStatisticPersonForMonthFactory() throws Exception {
+		if (null == this.statisticPersonForMonthFactory) {
+			this.statisticPersonForMonthFactory = new StatisticPersonForMonthFactory( this );
+		}
+		return statisticPersonForMonthFactory;
+	}
+	public Organization organization() throws Exception {
+		if (null == this.organization) {
+			this.organization = new Organization();
+		}
+		return organization;
+	}
+	
+	public AttendanceSettingFactory getAttendanceSettingFactory() throws Exception {
+		if (null == this.attendanceSettingFactory) {
+			this.attendanceSettingFactory = new AttendanceSettingFactory( this );
+		}
+		return attendanceSettingFactory;
+	}
+	
+	public AttendanceWorkDayConfigFactory getAttendanceWorkDayConfigFactory() throws Exception {
+		if (null == this.attendanceWorkDayConfigFactory) {
+			this.attendanceWorkDayConfigFactory = new AttendanceWorkDayConfigFactory( this );
+		}
+		return attendanceWorkDayConfigFactory;
+	}
+	
+	public AttendanceImportFileInfoFactory getAttendanceImportFileInfoFactory() throws Exception {
+		if (null == this.attendanceImportFileInfoFactory) {
+			this.attendanceImportFileInfoFactory = new AttendanceImportFileInfoFactory( this );
+		}
+		return attendanceImportFileInfoFactory;
+	}
+	
+	public AttendanceDetailFactory getAttendanceDetailFactory() throws Exception {
+		if (null == this.attendanceDetailFactory) {
+			this.attendanceDetailFactory = new AttendanceDetailFactory( this );
+		}
+		return attendanceDetailFactory;
+	}
+	public AttendanceAdminFactory getAttendanceAdminFactory() throws Exception {
+		if (null == this.attendanceAdminFactory) {
+			this.attendanceAdminFactory = new AttendanceAdminFactory( this );
+		}
+		return attendanceAdminFactory;
+	}
+	
+	public AttendanceScheduleSettingFactory getAttendanceScheduleSettingFactory() throws Exception {
+		if (null == this.attendanceScheduleSettingFactory) {
+			this.attendanceScheduleSettingFactory = new AttendanceScheduleSettingFactory( this );
+		}
+		return attendanceScheduleSettingFactory;
+	}
+	
+	public AttendanceSelfHolidayFactory getAttendanceSelfHolidayFactory() throws Exception {
+		if (null == this.attendanceSelfHolidayFactory) {
+			this.attendanceSelfHolidayFactory = new AttendanceSelfHolidayFactory( this );
+		}
+		return attendanceSelfHolidayFactory;
+	}
+}

+ 17 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/CacheUtil.java

@@ -0,0 +1,17 @@
+package com.x.attendance.assemble.control;
+
+import com.x.base.core.cache.ApplicationCache;
+import com.x.base.core.entity.JpaObject;
+
+/**
+ * 缓存管理帮助类
+ * @author liyi
+ *
+ */
+public class CacheUtil {
+	
+	public static <T extends JpaObject> void notify( Class<T> clz ) throws Exception {
+		ApplicationCache.notify( clz );
+	}
+	
+}

+ 7 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/MimeTypeDefinition.java

@@ -0,0 +1,7 @@
+package com.x.attendance.assemble.control;
+
+import javax.activation.MimetypesFileTypeMap;
+
+public class MimeTypeDefinition {
+	public static MimetypesFileTypeMap instance;
+}

+ 38 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java

@@ -0,0 +1,38 @@
+package com.x.attendance.assemble.control;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.jaxrs.attendanceappealinfo.AttendanceAppealInfoAction;
+import com.x.attendance.assemble.control.service.AttendanceSettingService;
+import com.x.attendance.assemble.control.task.AttendanceStatisticTask;
+import com.x.base.core.application.task.ReportTask;
+import com.x.base.core.project.AbstractThisApplication;
+import com.x.base.core.project.server.Config;
+import com.x.collaboration.core.message.Collaboration;
+
+public class ThisApplication extends AbstractThisApplication {
+	
+	public static void init() throws Exception {
+		/* 启动报告任务 */
+		scheduleWithFixedDelay(new ReportTask(), 1, 20);
+		initDatasFromCenters();
+		initStoragesFromCenters();
+		Config.workTimeConfig().initWorkTime();
+		scheduleWithFixedDelay(new AttendanceStatisticTask(), 60 * 5, 60 * 10);
+		Collaboration.start();
+		initAllSystemConfig();
+	}
+
+	public static void destroy() throws Exception {
+		Collaboration.stop();
+	}
+	
+	private static void initAllSystemConfig() {
+		try {
+			new AttendanceSettingService().initAllSystemConfig();
+		} catch (Exception e) {
+			LoggerFactory.getLogger( ThisApplication.class ).error( "attendance system check all system config got an exception.", e );
+		}
+	}
+}

+ 54 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceAdminFactory.java

@@ -0,0 +1,54 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceAdmin;
+import com.x.attendance.entity.AttendanceAdmin_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceAdminFactory extends AbstractFactory {
+	
+	public AttendanceAdminFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceAdmin应用信息对象")
+	public AttendanceAdmin get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceAdmin.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceAdmin应用信息列表")
+	public List<AttendanceAdmin> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceAdmin.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceAdmin> cq = cb.createQuery(AttendanceAdmin.class);
+		Root<AttendanceAdmin> root = cq.from( AttendanceAdmin.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceAdmin应用信息列表")
+	public List<AttendanceAdmin> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceAdmin>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceAdmin.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceAdmin> cq = cb.createQuery(AttendanceAdmin.class);
+		Root<AttendanceAdmin> root = cq.from(AttendanceAdmin.class);
+		Predicate p = root.get(AttendanceAdmin_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}	
+}

+ 518 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceAppealInfoFactory.java

@@ -0,0 +1,518 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendanceappealinfo.WrapInFilterAppeal;
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.attendance.entity.AttendanceAppealInfo_;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceAppealInfoFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceAppealInfoFactory.class );
+	
+	public AttendanceAppealInfoFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceAppealInfo信息对象")
+	public AttendanceAppealInfo get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceAppealInfo.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceAppealInfo信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select(root.get(AttendanceAppealInfo_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示全部的AttendanceAppealInfo信息列表")
+	public String getMaxRecordDate() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceAppealInfo> cq = cb.createQuery(AttendanceAppealInfo.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.orderBy( cb.desc( root.get( AttendanceAppealInfo_.recordDateString) ) );	
+		List<AttendanceAppealInfo> resultList = em.createQuery(cq).setMaxResults(1).getResultList();
+		if( resultList == null || resultList.size() == 0 ){
+			return null;
+		}else{
+			return resultList.get(0).getRecordDateString();
+		}
+	}
+	
+	@MethodDescribe("根据员工姓名和打卡日期列示AttendanceAppealInfo信息列表")
+	public List<String> listByEmployeeNameAndAppealDate( String employeeName, String appealDateString ) throws Exception {
+		
+		if( employeeName == null || appealDateString == null ){
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select(root.get(AttendanceAppealInfo_.id));
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.empName),  employeeName );
+		p = cb.and( p, cb.equal( root.get(AttendanceAppealInfo_.appealDateString ),  appealDateString ) );
+		return em.createQuery(cq.where( p )).getResultList();
+	}
+	
+	@MethodDescribe("根据部门和打卡日期列示AttendanceAppealInfo信息列表")
+	public List<String> listByDepartmentNameAndAppealDate( String departmentName, String appealDateString ) throws Exception {
+		
+		if( departmentName == null || appealDateString == null ){
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select(root.get(AttendanceAppealInfo_.id));
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.departmentName),  departmentName );
+		p = cb.and( p, cb.equal( root.get(AttendanceAppealInfo_.appealDateString ),  appealDateString ) );
+		return em.createQuery(cq.where( p )).getResultList();
+	}
+	
+	@MethodDescribe("根据公司和打卡日期列示AttendanceAppealInfo信息列表")
+	public List<String> listByCompanyNameAndAppealDate( String companyName, String appealDateString ) throws Exception {
+		
+		if( companyName == null || appealDateString == null ){
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select(root.get(AttendanceAppealInfo_.id));
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.companyName),  companyName );
+		p = cb.and( p, cb.equal( root.get(AttendanceAppealInfo_.appealDateString ),  appealDateString ) );
+		return em.createQuery(cq.where( p )).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceAppealInfo信息列表")
+	public List<AttendanceAppealInfo> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceAppealInfo>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceAppealInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceAppealInfo> cq = cb.createQuery(AttendanceAppealInfo.class);
+		Root<AttendanceAppealInfo> root = cq.from(AttendanceAppealInfo.class);
+		Predicate p = root.get(AttendanceAppealInfo_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	@MethodDescribe("按年份月份查询某用户的申诉记录列表")
+	public List<String> listUserAttendanceAppealInfoByYearAndMonth(String user, String year, String month)  throws Exception {
+		if( user == null || user.isEmpty() ||year == null || month == null || year.isEmpty() || month.isEmpty()  ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select( root.get(AttendanceAppealInfo_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.empName), user );
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.monthString), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("按年份月份查询某部门的申诉记录列表")
+	public List<String> listDepartmentAttendanceAppealInfoByYearAndMonth(String departmentName, String year, String month)  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select( root.get(AttendanceAppealInfo_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.departmentName), departmentName );
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.monthString), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("按年份月份查询某公司的申诉记录列表")
+	public List<String> listCompanyAttendanceAppealInfoByYearAndMonth(String companyName, String year, String month)  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select( root.get(AttendanceAppealInfo_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceAppealInfo_.companyName), companyName );
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceAppealInfo_.monthString), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("查询未归档的申诉记录列表,最大2000条")
+	public List<String> listNonArchiveAppealInfoIds()  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceAppealInfo> root = cq.from( AttendanceAppealInfo.class);
+		cq.select( root.get(AttendanceAppealInfo_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.isNotNull( root.get(AttendanceAppealInfo_.archiveTime) );
+		return em.createQuery(cq.where(p)).setMaxResults(2000).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<AttendanceAppealInfo> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterAppeal wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceAppealInfo.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getDetailId()) && (!wrapIn.getDetailId().isEmpty())) {
+			sql_stringBuffer.append(" and o.detailId = ?" + (index));
+			vs.add( wrapIn.getDetailId() );
+			index++;
+		}
+		if ((null != wrapIn.getEmpName()) && (!wrapIn.getEmpName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getEmpName() );
+			index++;
+		}
+		if ((null != wrapIn.getDepartmentName()) && (!wrapIn.getDepartmentName().isEmpty())) {
+			sql_stringBuffer.append(" and o.departmentName = ?" + (index));
+			vs.add( wrapIn.getDepartmentName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && (!wrapIn.getCompanyName().isEmpty())) {
+			sql_stringBuffer.append(" and o.companyName = ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getYearString() ) && (!wrapIn.getYearString().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getYearString() );
+			index++;
+		}
+		if ((null != wrapIn.getMonthString()) && (!wrapIn.getMonthString().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getMonthString() );
+			index++;
+		}
+		if (wrapIn.getStatus()!=999) {
+			sql_stringBuffer.append(" and o.status = ?" + (index));
+			vs.add( wrapIn.getStatus() );
+			index++;
+		}
+		if ((null != wrapIn.getAppealReason()) && (!wrapIn.getAppealReason().isEmpty())) {
+			sql_stringBuffer.append(" and o.appealReason = ?" + (index));
+			vs.add( wrapIn.getAppealReason() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson1()) && (!wrapIn.getProcessPerson1().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson1 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson1() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson2()) && (!wrapIn.getProcessPerson2().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson2 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson2() );
+			index++;
+		}
+		
+		//添加OR条件
+		if (wrapIn.getOrAtrribute() != null && wrapIn.getOrAtrribute().size() > 0) {
+			sql_stringBuffer.append(" and (");
+			NameValueCountPair nameValueCountPair = null;
+			for (int p = 0; p < wrapIn.getOrAtrribute().size(); p++) {
+				nameValueCountPair = wrapIn.getOrAtrribute().get(p);
+				if (p == 0) {
+					sql_stringBuffer.append(" o." + nameValueCountPair.getName() + " = ?" + (index));
+
+				} else {
+					sql_stringBuffer.append(" or o." + nameValueCountPair.getName() + " = ?" + (index));
+				}
+				vs.add(nameValueCountPair.getValue());
+				index++;
+			}
+			sql_stringBuffer.append(" )");
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+	
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceAppealInfo.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AttendanceAppealInfo> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterAppeal wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceAppealInfo.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getDetailId()) && (!wrapIn.getDetailId().isEmpty())) {
+			sql_stringBuffer.append(" and o.detailId = ?" + (index));
+			vs.add( wrapIn.getDetailId() );
+			index++;
+		}
+		if ((null != wrapIn.getEmpName()) && (!wrapIn.getEmpName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getEmpName() );
+			index++;
+		}
+		if ((null != wrapIn.getDepartmentName()) && (!wrapIn.getDepartmentName().isEmpty())) {
+			sql_stringBuffer.append(" and o.departmentName = ?" + (index));
+			vs.add( wrapIn.getDepartmentName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && (!wrapIn.getCompanyName().isEmpty())) {
+			sql_stringBuffer.append(" and o.companyName = ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getYearString() ) && (!wrapIn.getYearString().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getYearString() );
+			index++;
+		}
+		if ((null != wrapIn.getMonthString()) && (!wrapIn.getMonthString().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getMonthString() );
+			index++;
+		}
+		if (wrapIn.getStatus()!=999) {
+			sql_stringBuffer.append(" and o.status = ?" + (index));
+			vs.add( wrapIn.getStatus() );
+			index++;
+		}
+		if ((null != wrapIn.getAppealReason()) && (!wrapIn.getAppealReason().isEmpty())) {
+			sql_stringBuffer.append(" and o.appealReason = ?" + (index));
+			vs.add( wrapIn.getAppealReason() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson1()) && (!wrapIn.getProcessPerson1().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson1 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson1() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson2()) && (!wrapIn.getProcessPerson2().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson2 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson2() );
+			index++;
+		}
+		//添加OR
+		if( wrapIn.getOrAtrribute() != null && wrapIn.getOrAtrribute().size() > 0){
+			sql_stringBuffer.append(" and (" );
+			NameValueCountPair nameValueCountPair = null;
+			for( int p = 0 ; p< wrapIn.getOrAtrribute().size(); p++ ){
+				nameValueCountPair = wrapIn.getOrAtrribute().get(p);
+				if( p == 0 ){
+					sql_stringBuffer.append(" o."+nameValueCountPair.getName()+" = ?" + (index));
+					
+				}else{
+					sql_stringBuffer.append(" or o."+nameValueCountPair.getName()+" = ?" + (index));					
+				}
+				vs.add( nameValueCountPair.getValue() );
+				index++;
+			}
+			sql_stringBuffer.append(" )" );
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceAppealInfo.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterAppeal wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceAppealInfo.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+AttendanceAppealInfo.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getDetailId()) && (!wrapIn.getDetailId().isEmpty())) {
+			sql_stringBuffer.append(" and o.detailId = ?" + (index));
+			vs.add( wrapIn.getDetailId() );
+			index++;
+		}
+		if ((null != wrapIn.getEmpName()) && (!wrapIn.getEmpName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getEmpName() );
+			index++;
+		}
+		if ((null != wrapIn.getDepartmentName()) && (!wrapIn.getDepartmentName().isEmpty())) {
+			sql_stringBuffer.append(" and o.departmentName = ?" + (index));
+			vs.add( wrapIn.getDepartmentName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && (!wrapIn.getCompanyName().isEmpty())) {
+			sql_stringBuffer.append(" and o.companyName = ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getYearString() ) && (!wrapIn.getYearString().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getYearString() );
+			index++;
+		}
+		if ((null != wrapIn.getMonthString()) && (!wrapIn.getMonthString().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getMonthString() );
+			index++;
+		}
+		if (wrapIn.getStatus()!=999) {
+			sql_stringBuffer.append(" and o.status = ?" + (index));
+			vs.add( wrapIn.getStatus() );
+			index++;
+		}
+		if ((null != wrapIn.getAppealReason()) && (!wrapIn.getAppealReason().isEmpty())) {
+			sql_stringBuffer.append(" and o.appealReason = ?" + (index));
+			vs.add( wrapIn.getAppealReason() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson1()) && (!wrapIn.getProcessPerson1().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson1 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson1() );
+			index++;
+		}
+		if ((null != wrapIn.getProcessPerson2()) && (!wrapIn.getProcessPerson2().isEmpty())) {
+			sql_stringBuffer.append(" and o.processPerson2 = ?" + (index));
+			vs.add( wrapIn.getProcessPerson2() );
+			index++;
+		}
+		//添加OR
+		if (wrapIn.getOrAtrribute() != null && wrapIn.getOrAtrribute().size() > 0) {
+			sql_stringBuffer.append(" and (");
+			NameValueCountPair nameValueCountPair = null;
+			for (int p = 0; p < wrapIn.getOrAtrribute().size(); p++) {
+				nameValueCountPair = wrapIn.getOrAtrribute().get(p);
+				if (p == 0) {
+					sql_stringBuffer.append(" o." + nameValueCountPair.getName() + " = ?" + (index));
+
+				} else {
+					sql_stringBuffer.append(" or o." + nameValueCountPair.getName() + " = ?" + (index));
+				}
+				vs.add(nameValueCountPair.getValue());
+				index++;
+			}
+			sql_stringBuffer.append(" )");
+		}
+
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceAppealInfo.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+}

+ 881 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailFactory.java

@@ -0,0 +1,881 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Selection;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.AttendanceCycles;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.WrapInFilter;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetail_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceDetailFactory extends AbstractFactory {
+	
+	public AttendanceDetailFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceDetail信息对象")
+	public AttendanceDetail get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceDetail.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceDetail信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select(root.get(AttendanceDetail_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示全部的AttendanceDetail信息列表")
+	public String getMaxRecordDate() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();		
+		CriteriaQuery<AttendanceDetail> cq = cb.createQuery( AttendanceDetail.class );
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);		
+		cq.orderBy( cb.desc( root.get( AttendanceDetail_.recordDateString) ) );	
+		List<AttendanceDetail> resultList = em.createQuery(cq).setMaxResults(1).getResultList();
+		if( resultList == null || resultList.size() == 0 ){
+			return null;
+		}else{
+			return resultList.get(0).getRecordDateString();
+		}
+	}
+	
+	@MethodDescribe("根据员工姓名和打卡日期列示AttendanceDetail信息列表")
+	public List<String> listByEmployeeNameAndDate( String employeeName, String recordDateString ) throws Exception {
+		
+		if( employeeName == null || recordDateString == null ){
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select(root.get(AttendanceDetail_.id));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.empName),  employeeName );
+		p = cb.and( p, cb.equal( root.get(AttendanceDetail_.recordDateString ),  recordDateString ) );
+		return em.createQuery(cq.where( p )).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceDetail信息列表")
+	public List<AttendanceDetail> list(List<String> ids) throws Exception {
+		List<AttendanceDetail> resultList = null;
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceDetail>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetail> cq = cb.createQuery(AttendanceDetail.class);
+		Root<AttendanceDetail> root = cq.from(AttendanceDetail.class);
+		Predicate p = root.get(AttendanceDetail_.id).in(ids);
+		resultList = em.createQuery( cq.where(p) ).getResultList();
+		if( resultList == null ){
+			resultList = new ArrayList<AttendanceDetail>();
+		}
+		return resultList;
+	}
+
+	/**
+	 * 分析时间范围内的所有打卡记录
+	 * 1、如果未传入时间,或者时间有错,那么分析所有未分析过的打卡记录
+	 * 2、只分析未归档的,已经归档的将不再分析了
+	 * @param startDateString
+	 * @param endDateString
+	 * @return
+	 * @throws Exception
+	 */
+	@MethodDescribe("按指定的开始时间,结束时间列示未被分析的AttendanceDetail信息列表")
+	public List<String> getAllAnalysenessDetails(String startDateString, String endDateString) throws Exception {
+		DateOperation dateOperation = new DateOperation();
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select(root.get(AttendanceDetail_.id));
+		//一般始终为true, id is not null
+		Predicate p = root.get( AttendanceDetail_.id ).isNotNull();
+		p = cb.and( p, root.get( AttendanceDetail_.archiveTime ).isNull()); //要未归档的,才再次进行分析
+		Date startDate = null;
+		Date endDate = null;
+		try{
+			startDate = dateOperation.getDateFromString( startDateString );
+		}catch(Exception e){
+			startDate = null;
+		}
+		try{
+			endDate = dateOperation.getDateFromString( endDateString );
+		}catch(Exception e){
+			endDate = null;
+		}
+		//如果开始时间和结束时间有值,那么分析一个时间区间内的所有打卡记录,已经分析过了的,也需要重新分析一次
+		if( startDate != null  && endDate != null ){
+			p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), startDate, endDate));
+		}else{
+			if( startDate != null ){
+				p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), startDate, new Date()));
+			}
+			if( endDate != null ){
+				p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), new Date(), endDate));
+			}
+			if( startDate == null && endDate == null ){
+				//startDateString和endDateString都为空,只分析所有未分析过的
+				List<Integer> statusArray = new ArrayList<Integer>();
+				statusArray.add( 0 ); //未分析的
+				statusArray.add( -1 ); //有错误的
+				p = cb.and( p, root.get( AttendanceDetail_.recordStatus).in( statusArray ));
+			}
+		}
+		return em.createQuery(cq.where(p)).setMaxResults(10000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的开始时间,结束时间列示未被分析的AttendanceDetail信息列表")
+	public List<String> getUserAnalysenessDetails(String empName, String startDateString, String endDateString) throws Exception {
+		DateOperation dateOperation = new DateOperation();
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select(root.get(AttendanceDetail_.id));
+
+		Predicate p = cb.equal( root.get(AttendanceDetail_.empName),  empName );
+		
+		Date startDate = null;
+		Date endDate = null;
+		try{
+			startDate = dateOperation.getDateFromString( startDateString );
+		}catch(Exception e){
+			startDate = null;
+		}
+		try{
+			endDate = dateOperation.getDateFromString( endDateString );
+		}catch(Exception e){
+			endDate = null;
+		}
+		//如果开始时间和结束时间有值,那么分析一个时间区间内的所有打卡记录,已经分析过了的,也需要重新分析一次
+		if( startDate != null  && endDate != null ){
+			p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), startDate, endDate));
+		}else{
+			if( startDate != null ){
+				p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), startDate, new Date()));
+			}
+			if( endDate != null ){
+				p = cb.and( p, cb.between( root.get( AttendanceDetail_.recordDate), new Date(), endDate));
+			}
+			if( startDate == null && endDate == null ){
+				//startDateString和endDateString都为空,只分析所有未分析过的
+				List<Integer> statusArray = new ArrayList<Integer>();
+				statusArray.add( 0 ); //未分析的
+				statusArray.add( -1 ); //有错误的
+				p = cb.and( p, root.get( AttendanceDetail_.recordStatus).in( statusArray ));
+			}
+		}
+		return em.createQuery(cq.where(p)).setMaxResults(10000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的年份,月份列示AttendanceDetail信息列表")
+	public List<AttendanceDetail> getDetailsByYearAndMonth(String year, String month) throws Exception {
+		if( year == null || month == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetail> cq = cb.createQuery(AttendanceDetail.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		return em.createQuery(cq.where(p)).setMaxResults(20000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息列表")
+	public List<AttendanceDetail> getDetailsByCycleYearAndMonth(String cycleYear, String cycleMonth) throws Exception {
+		if( cycleYear == null || cycleMonth == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetail> cq = cb.createQuery(AttendanceDetail.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		return em.createQuery(cq.where(p)).setMaxResults(20000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的年份,月份列示已分析的AttendanceDetail信息中涉及的部门列表")
+	public List<String> getDetailsDepartmentsByYearAndMonth(String year, String month) throws Exception {
+		if( year == null || month == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.departmentName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	/**
+	 * 迟到、缺勤、早退、工时不足、异常打卡,但未申诉通过的
+	 * @param year
+	 * @param month
+	 * @return
+	 * @throws Exception
+	 */
+	@MethodDescribe("获取所有需要导出所有异常数据(未申诉的、申诉未通过的)")
+	public List<String> getDetailsWithAllAbnormalCase( String year, String month ) throws Exception {
+		if( year == null || month == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		
+		Predicate p = cb.lessThan( root.get(AttendanceDetail_.appealStatus), 9); //如果等于9就是申诉通过
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), year ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), month ));
+		
+		Predicate orCase = cb.isTrue(root.get(AttendanceDetail_.isLate)); //迟到
+		orCase = cb.or( orCase, cb.isTrue( root.get(AttendanceDetail_.isLeaveEarlier)) ); //或者早退
+		orCase = cb.or( orCase, cb.isTrue( root.get(AttendanceDetail_.isAbnormalDuty) )); //或者异常打卡
+		orCase = cb.or( orCase, cb.isTrue( root.get(AttendanceDetail_.isAbsent) )); //或者缺勤
+		orCase = cb.or( orCase, cb.isTrue( root.get(AttendanceDetail_.isLackOfTime) )); //或者工时不足
+		
+		Predicate where = cb.and( p, orCase );
+		
+		return em.createQuery(cq.where(where)).setMaxResults(20000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的部门列表")
+	public List<String> getDetailsDepartmentsByCycleYearAndMonth(String cycleYear, String cycleMonth) throws Exception {
+		if( cycleYear == null || cycleMonth == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.departmentName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的公司名称列表")
+	public List<String> distinctDetailsCompanyNamesByYearAndMonth(String year, String month) throws Exception {
+		if( year == null || month == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.companyName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的员工姓名列表")
+	public List<String> distinctDetailsEmployeeNamesByCycleYearAndMonth(String cycleYear, String cycleMonth) throws Exception {
+		if( cycleYear == null || cycleMonth == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.empName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的公司名称列表")
+	public List<String> distinctDetailsCompanyNamesByCycleYearAndMonth(String cycleYear, String cycleMonth) throws Exception {
+		if( cycleYear == null || cycleMonth == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.companyName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的部门名称列表")
+	public List<String> distinctDetailsDepartmentNamesByCycleYearAndMonth( String cycleYear, String cycleMonth ) throws Exception {
+		if( cycleYear == null || cycleMonth == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.departmentName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+	
+	@MethodDescribe("按指定的统计周期年份,月份列示AttendanceDetail信息中涉及的部门名称列表")
+	public List<String> distinctDetailsDepartmentNamesByCycleYearAndMonth( String cycleYear, String cycleMonth, String employeeName ) throws Exception {
+		if( cycleYear == null || cycleMonth == null || employeeName == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.departmentName ));
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.empName), employeeName ));
+		return em.createQuery(cq.where(p)).setMaxResults(1000).getResultList();
+	}
+
+
+	@MethodDescribe("按batchName查询一次导入的所有数据记录列表")
+	public List<String> listByBatchName( String file_id ) throws Exception{
+		if( file_id == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.distinct(true).select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.batchName), file_id );
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	@MethodDescribe("按年份月份查询某用户的打卡数据记录列表")
+	public List<String> listUserAttendanceDetailByYearAndMonth(String user, String year, String month)  throws Exception {
+		if( user == null || user.isEmpty() ||year == null || month == null || year.isEmpty() || month.isEmpty()  ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		if( user != null && !user.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.empName), user ));
+		}
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("按周期年份月份查询某用户的打卡数据记录列表")
+	public List<String> listUserAttendanceDetailByCycleYearAndMonth(String user, String year, String month)  throws Exception {
+		if( user == null || user.isEmpty() ||year == null || month == null || year.isEmpty() || month.isEmpty()  ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		if( user != null && !user.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.empName), user ));
+		}
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleYear), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.cycleMonth), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("按年份月份查询某部门的打卡数据记录列表")
+	public List<String> listDepartmentAttendanceDetailByYearAndMonth( List<String> departmentNames, String year, String month)  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		if( departmentNames != null && departmentNames.size() > 0 ){
+			p = cb.and(p, root.get(AttendanceDetail_.departmentName).in(departmentNames));
+		}
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		}
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("按年份月份查询某公司的打卡数据记录列表")
+	public List<String> listCompanyAttendanceDetailByYearAndMonth(List<String> companyNames, String year, String month)  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.equal( root.get(AttendanceDetail_.recordStatus), 1 );
+		if( companyNames != null && companyNames.size() > 0 ){
+			p = cb.and(p, root.get(AttendanceDetail_.companyName).in( companyNames ));
+		}
+		if( year != null && !year.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.yearString), year ));
+		}
+		if( month != null && !month.isEmpty() ){
+			p = cb.and(p, cb.equal( root.get(AttendanceDetail_.monthString), month ));
+		}
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<AttendanceDetail> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceDetail.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.departmentName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleYear() ) && (!wrapIn.getCycleYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleYear = ?" + (index));
+			vs.add( wrapIn.getCycleYear() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleMonth()) && (!wrapIn.getCycleMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleMonth = ?" + (index));
+			vs.add( wrapIn.getCycleMonth() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_year() ) && (!wrapIn.getQ_year().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getQ_year() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_month()) && (!wrapIn.getQ_month().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getQ_month() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_date()) && (!wrapIn.getQ_date().isEmpty())) {
+			sql_stringBuffer.append(" and o.recordDateString = ?" + (index));
+			vs.add( wrapIn.getQ_date() );
+			index++;
+		}
+		
+		if ( wrapIn.getRecordStatus() != 999 ) {
+			sql_stringBuffer.append(" and o.recordStatus = ?" + (index));
+			vs.add( wrapIn.getRecordStatus() );
+			index++;
+		}
+		
+		if (wrapIn.getIsAbsent() != null ) {
+			sql_stringBuffer.append(" and o.isAbsent = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLate() != null ) {
+			sql_stringBuffer.append(" and o.isLate = ?" + (index));
+			vs.add( wrapIn.getIsLate() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLackOfTime() != null ) {
+			sql_stringBuffer.append(" and o.isLackOfTime = ?" + (index));
+			vs.add( wrapIn.getIsLackOfTime() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLeaveEarlier() != null ) {
+			sql_stringBuffer.append(" and o.isLeaveEarlier = ?" + (index));
+			vs.add( wrapIn.getIsLeaveEarlier() );
+			index++;
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceDetail.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AttendanceDetail> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceDetail.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.departmentName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleYear() ) && (!wrapIn.getCycleYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleYear = ?" + (index));
+			vs.add( wrapIn.getCycleYear() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleMonth()) && (!wrapIn.getCycleMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleMonth = ?" + (index));
+			vs.add( wrapIn.getCycleMonth() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_year() ) && (!wrapIn.getQ_year().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getQ_year() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_month()) && (!wrapIn.getQ_month().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getQ_month() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_date()) && (!wrapIn.getQ_date().isEmpty())) {
+			sql_stringBuffer.append(" and o.recordDateString = ?" + (index));
+			vs.add( wrapIn.getQ_date() );
+			index++;
+		}
+		
+		if ( wrapIn.getRecordStatus() != 999 ) {
+			sql_stringBuffer.append(" and o.recordStatus = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+		
+		if (wrapIn.getIsAbsent() != null ) {
+			sql_stringBuffer.append(" and o.isAbsent = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLate() != null ) {
+			sql_stringBuffer.append(" and o.isLate = ?" + (index));
+			vs.add( wrapIn.getIsLate() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLackOfTime() != null ) {
+			sql_stringBuffer.append(" and o.isLackOfTime = ?" + (index));
+			vs.add( wrapIn.getIsLackOfTime() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLeaveEarlier() != null ) {
+			sql_stringBuffer.append(" and o.isLeaveEarlier = ?" + (index));
+			vs.add( wrapIn.getIsLeaveEarlier() );
+			index++;
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceDetail.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(count).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		DateOperation dateOperation = new DateOperation();
+		Date startDate = null, endDate = null;
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+AttendanceDetail.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.empName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.departmentName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleYear() ) && (!wrapIn.getCycleYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleYear = ?" + (index));
+			vs.add( wrapIn.getCycleYear() );
+			index++;
+		}
+		if ((null != wrapIn.getCycleMonth()) && (!wrapIn.getCycleMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.cycleMonth = ?" + (index));
+			vs.add( wrapIn.getCycleMonth() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_year() ) && (!wrapIn.getQ_year().isEmpty())) {
+			sql_stringBuffer.append(" and o.yearString = ?" + (index));
+			vs.add( wrapIn.getQ_year() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_month()) && (!wrapIn.getQ_month().isEmpty())) {
+			sql_stringBuffer.append(" and o.monthString = ?" + (index));
+			vs.add( wrapIn.getQ_month() );
+			index++;
+		}
+		if ((null != wrapIn.getQ_date()) && (!wrapIn.getQ_date().isEmpty())) {
+			sql_stringBuffer.append(" and o.recordDateString = ?" + (index));
+			vs.add( wrapIn.getQ_date() );
+			index++;
+		}
+		if ( wrapIn.getRecordStatus() != 999 ) {
+			sql_stringBuffer.append(" and o.recordStatus = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+		
+		if (wrapIn.getIsAbsent() != null ) {
+			sql_stringBuffer.append(" and o.isAbsent = ?" + (index));
+			vs.add( wrapIn.getIsAbsent() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLate() != null ) {
+			sql_stringBuffer.append(" and o.isLate = ?" + (index));
+			vs.add( wrapIn.getIsLate() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLackOfTime() != null ) {
+			sql_stringBuffer.append(" and o.isLackOfTime = ?" + (index));
+			vs.add( wrapIn.getIsLackOfTime() );
+			index++;
+		}
+		
+		if (wrapIn.getIsLeaveEarlier() != null ) {
+			sql_stringBuffer.append(" and o.isLeaveEarlier = ?" + (index));
+			vs.add( wrapIn.getIsLeaveEarlier() );
+			index++;
+		}
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceDetail.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+
+	public List<String> getByUserAndRecordDate(String employeeName, String recordDateStringFormated)  throws Exception{		
+		//logger.debug( "[getByUserAndRecordDate]employeeName=" + employeeName + " && recordDateStringFormated=" + recordDateStringFormated );
+		if( employeeName == null || employeeName.isEmpty() || recordDateStringFormated == null || recordDateStringFormated.isEmpty() ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.equal( root.get(AttendanceDetail_.empName), employeeName );
+		p = cb.and(p, cb.equal( root.get(AttendanceDetail_.recordDateString), recordDateStringFormated ));	
+		cq.select( root.get(AttendanceDetail_.id ));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	
+	public List<AttendanceCycles> getCyclesFromDetailWithDateSplit( Date startDate, Date endDate )  throws Exception{
+		if( startDate == null || startDate == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceCycles> cq = cb.createQuery(AttendanceCycles.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.between( root.get(AttendanceDetail_.recordDate), startDate, endDate);
+		
+		List<Selection<?>> selectionList = new ArrayList<Selection<?>>();
+		selectionList.add(root.get(AttendanceDetail_.cycleYear ));
+		selectionList.add(root.get(AttendanceDetail_.cycleMonth ));
+		cq.distinct(true).multiselect(selectionList);
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	public List<AttendanceCycles> getCyclesFromDetailWithDateSplit( String empName, Date startDate, Date endDate )  throws Exception{
+		if( startDate == null || startDate == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceCycles> cq = cb.createQuery(AttendanceCycles.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.between( root.get(AttendanceDetail_.recordDate), startDate, endDate);
+		p = cb.and( p, cb.equal( root.get(AttendanceDetail_.empName), empName));
+		List<Selection<?>> selectionList = new ArrayList<Selection<?>>();
+		selectionList.add(root.get(AttendanceDetail_.cycleYear ));
+		selectionList.add(root.get(AttendanceDetail_.cycleMonth ));
+		cq.distinct(true).multiselect(selectionList);
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("查询未归档的条卡记录列表,最大2000条")
+	public List<String> listNonArchiveDetailInfoIds()  throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		cq.select( root.get(AttendanceDetail_.id ));
+		//一般始终为true, id is not null
+		Predicate p = cb.isNotNull( root.get(AttendanceDetail_.archiveTime) );
+		return em.createQuery(cq.where(p)).setMaxResults(2000).getResultList();
+	}
+}

+ 126 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailMobileFactory.java

@@ -0,0 +1,126 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.attendance.entity.AttendanceDetailMobile_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceDetailMobileFactory extends AbstractFactory {
+	
+	public AttendanceDetailMobileFactory( Business business ) throws Exception {
+		super(business);
+	}
+
+	public List<String> listByEmployeeNameDateAndTime( String empName, String recordDateString, String signTime ) throws Exception {
+		if( empName == null || empName.isEmpty() ){
+			throw new Exception("empName is null!");
+		}
+		if( recordDateString == null || recordDateString.isEmpty() ){
+			throw new Exception("recordDateString is null!");
+		}
+		if( signTime == null || signTime.isEmpty() ){
+			throw new Exception("signTime is null!");
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceDetailMobile> root = cq.from( AttendanceDetailMobile.class);
+		cq.select(root.get(AttendanceDetailMobile_.id));
+		Predicate p = cb.equal( root.get(AttendanceDetailMobile_.empName),  empName );
+		p = cb.and( p, cb.equal( root.get(AttendanceDetailMobile_.recordDateString ),  recordDateString ) );
+		p = cb.and( p, cb.equal( root.get(AttendanceDetailMobile_.signTime ),  signTime ) );
+		return em.createQuery(cq.where( p )).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceDetailMobile信息列表")
+	public List<AttendanceDetailMobile> list(List<String> ids) throws Exception {
+		List<AttendanceDetailMobile> resultList = null;
+		if( ids == null || ids.size() == 0 ){
+			throw new Exception("ids is null!");
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetailMobile> cq = cb.createQuery(AttendanceDetailMobile.class);
+		Root<AttendanceDetailMobile> root = cq.from(AttendanceDetailMobile.class);
+		Predicate p = root.get( AttendanceDetailMobile_.id).in( ids );
+		resultList = em.createQuery( cq.where(p) ).getResultList();
+		return resultList;
+	}
+
+	public Long countAttendanceDetailMobileForPage( String empNo, String empName, String signDescription,
+			String startDate, String endDate) throws Exception {
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetailMobile.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetailMobile> root = cq.from(AttendanceDetailMobile.class);
+		Predicate p = cb.isNotNull( root.get( AttendanceDetailMobile_.id ) );
+		if( empNo != null && !empNo.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.empNo ), empNo ) );
+		}
+		if( empName != null && !empName.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.empName ), empName ) );
+		}
+		if( signDescription != null && !signDescription.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.signDescription ), signDescription ) );
+		}
+		if( startDate != null && !startDate.isEmpty() ){
+			if( endDate != null && !endDate.isEmpty() && !endDate.equals( startDate ) ){//查询日期区间
+				p = cb.between( root.get( AttendanceDetailMobile_.recordDateString ), startDate, endDate );
+			}else{
+				//查询startDate当天
+				p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.recordDateString ), startDate ) );
+			}
+		}
+		cq.select( cb.count( root ) );		
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	public List<AttendanceDetailMobile> listAttendanceDetailMobileForPage( String empNo, String empName, String signDescription,
+			String startDate, String endDate, Integer selectTotal ) throws Exception {
+		if( selectTotal == null ){
+			selectTotal = 100;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetailMobile.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetailMobile> cq = cb.createQuery(AttendanceDetailMobile.class);
+		Root<AttendanceDetailMobile> root = cq.from(AttendanceDetailMobile.class);
+		Predicate p = cb.isNotNull( root.get( AttendanceDetailMobile_.id ) );
+		if( empNo != null && !empNo.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.empNo ), empNo ) );
+		}
+		if( empName != null && !empName.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.empName ), empName ) );
+		}
+		if( signDescription != null && !signDescription.isEmpty() ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.signDescription ), signDescription ) );
+		}
+		if( startDate != null && !startDate.isEmpty() ){
+			if( endDate != null && !endDate.isEmpty() && !endDate.equals( startDate ) ){//查询日期区间
+				p = cb.between( root.get( AttendanceDetailMobile_.recordDateString ), startDate, endDate );
+			}else{
+				//查询startDate当天
+				p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.recordDateString ), startDate ) );
+			}
+		}
+		return em.createQuery(cq.where(p)).setMaxResults( selectTotal ).getResultList();
+	}
+
+	public AttendanceDetailMobile get(String id) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceDetailMobile.class );
+	}
+
+}

+ 927 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailStatisticFactory.java

@@ -0,0 +1,927 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetail_;
+
+/**
+ * 打卡信息统计服务类,以打卡信息表为基础进行统计
+ * @author liyi
+ */
+public class AttendanceDetailStatisticFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceDetailStatisticFactory.class );
+	
+	public AttendanceDetailStatisticFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	/**
+	 * 根据员工,年月,统计异常打卡次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countAbNormalDutyByEmployeeCycleYearAndMonth(List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.empName).in( employeeNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isAbnormalDuty) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计工时不足次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLackOfTimeByEmployeeCycleYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.empName).in( employeeNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLackOfTime) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计早退次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLeaveEarlierByEmployeeCycleYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.empName).in( employeeNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLeaveEarlier ) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计迟到次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLateByEmployeeCycleYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.empName).in( employeeNames );
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLate ) ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计签退次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOffDutyByEmployeeCycleYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.offDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.offDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.empName).in( employeeNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计签退次数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOnDutyByEmployeeCycleYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.onDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.onDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.empName).in( employeeNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,年月,统计请假天数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayDaysByEmployeeYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		// 不是周末,或者是周末但是调工作日了
+		Predicate p1 = cb.isFalse(root.get( AttendanceDetail_.isWeekend ));
+		p1 = cb.or( p1, cb.and(cb.isTrue(root.get( AttendanceDetail_.isWeekend )), cb.isTrue(root.get( AttendanceDetail_.isWorkday )) ));
+								
+		Predicate p = root.get( AttendanceDetail_.empName).in( employeeNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isFalse(root.get( AttendanceDetail_.isHoliday ))); //不是节假日
+		p = cb.and( p, p1 ); //不是周末并且未调休工作晶
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear ));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth ));
+		}
+		
+		//查询总数
+		cq.select( cb.sum( root.get( AttendanceDetail_.getSelfHolidayDays ) ) );	
+				
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	
+	
+	/**
+	 * 根据员工,年月,统计缺勤天数
+	 * @param employeeNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDaysByEmployeeYearAndMonth( List<String> employeeNames, String cycleYear, String cycleMonth) throws Exception{
+		if( employeeNames == null || employeeNames.size() == 0 ){
+			logger.error("employeeNames is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);	
+		Predicate p = root.get(AttendanceDetail_.empName).in( employeeNames );		
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(AttendanceDetail_.cycleYear), cycleYear));
+		}
+		
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.sum( root.get(AttendanceDetail_.absence ) ) );	
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,年月,统计异常打卡次数
+	 * @param departmentNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countAbNormalDutyByDempartmentCycleYearAndMonth(List<String> departmentNames, String cycleYear, String cycleMonth) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isAbnormalDuty) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,年月,统计工时不足次数
+	 * @param departmentNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLackOfTimeByDempartmentCycleYearAndMonth( List<String> departmentNames, String cycleYear, String cycleMonth) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLackOfTime) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,年月,统计早退次数
+	 * @param departmentNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLeaveEarlierByDempartmentCycleYearAndMonth( List<String> departmentNames, String cycleYear, String cycleMonth) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLeaveEarlier ) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,年月,统计迟到次数
+	 * @param departmentNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLateByDempartmentCycleYearAndMonth( List<String> departmentNames, String cycleYear, String cycleMonth) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLate ) ));
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.cycleMonth), cycleMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计异常打卡次数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countAbNormalDutyByDempartmentAndDate(List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isAbnormalDuty) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计工时不足次数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLackOfTimeByDempartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLackOfTime) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计早退次数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLeaveEarlierByDempartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLeaveEarlier ) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计迟到次数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLateByDempartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLate ) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,打卡日期,统计缺勤天数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDaysByDepartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);	
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.sum( root.get(AttendanceDetail_.absence ) ) );	
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据员工,打卡日期月,统计请假天数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayDaysByDepartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);			
+		Predicate p = root.get( AttendanceDetail_.departmentName ).in( departmentNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}		
+		//查询总数
+		cq.select( cb.sum( root.get( AttendanceDetail_.getSelfHolidayDays ) ) );	
+				
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计签退人数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOffDutyByDepartmentAndDate( List<String> departmentNames, String recordDate ) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.offDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.offDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.departmentName).in( departmentNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.departmentName), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,打卡日期,统计签到人数
+	 * @param departmentNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOnDutyByDepartmentAndDate( List<String> departmentNames, String recordDate) throws Exception{
+		if( departmentNames == null || departmentNames.size() == 0 ){
+			logger.error("departmentNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.onDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.onDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.departmentName ).in( departmentNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.departmentName), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计异常打卡次数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countAbNormalDutyByCompanyAndDate(List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isAbnormalDuty) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计工时不足次数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLackOfTimeByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLackOfTime) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计早退次数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLeaveEarlierByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLeaveEarlier ) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计迟到次数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countLateByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		p = cb.and( p, cb.isTrue( root.get( AttendanceDetail_.isLate ) ));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计缺勤天数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDaysByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);	
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}
+		//查询总数
+		cq.select( cb.sum( root.get(AttendanceDetail_.absence ) ) );	
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期月,统计请假天数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayDaysByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);			
+		Predicate p = root.get( AttendanceDetail_.companyName ).in( companyNames );
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString ), recordDate));
+		}		
+		//查询总数
+		cq.select( cb.sum( root.get( AttendanceDetail_.getSelfHolidayDays ) ) );	
+				
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计签到人数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOffDutyByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.offDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.offDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.companyName ).in( companyNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司,打卡日期,统计签到人数
+	 * @param companyNames
+	 * @param recordDate
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countOnDutyByCompanyAndDate( List<String> companyNames, String recordDate ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetail.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<AttendanceDetail> root = cq.from( AttendanceDetail.class);
+		Predicate p = cb.isNotNull(root.get( AttendanceDetail_.onDutyTime ));
+		p = cb.and( p, cb.notEqual( root.get( AttendanceDetail_.onDutyTime), ""));
+		p = cb.and( p, root.get( AttendanceDetail_.companyName).in( companyNames ));
+		p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordStatus ), 1));
+		if( recordDate == null || recordDate.isEmpty() ){
+			logger.error("recordDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( AttendanceDetail_.recordDateString), recordDate));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+}

+ 73 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceEmployeeConfigFactory.java

@@ -0,0 +1,73 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.attendance.entity.AttendanceEmployeeConfig_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 员工考勤需求配置服务器
+ * @author liyi
+ */
+public class AttendanceEmployeeConfigFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceEmployeeConfigFactory.class );
+	
+	public AttendanceEmployeeConfigFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceEmployeeConfig信息对象")
+	public AttendanceEmployeeConfig get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceEmployeeConfig.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceEmployeeConfig信息列表")
+	public List<AttendanceEmployeeConfig> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceEmployeeConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceEmployeeConfig> cq = cb.createQuery(AttendanceEmployeeConfig.class);
+		Root<AttendanceEmployeeConfig> root = cq.from( AttendanceEmployeeConfig.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceEmployeeConfig信息列表")
+	public List<AttendanceEmployeeConfig> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceEmployeeConfig>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceEmployeeConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceEmployeeConfig> cq = cb.createQuery(AttendanceEmployeeConfig.class);
+		Root<AttendanceEmployeeConfig> root = cq.from(AttendanceEmployeeConfig.class);
+		Predicate p = root.get(AttendanceEmployeeConfig_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据配置类别列示AttendanceEmployeeConfig信息列表")
+	public List<String> listByConfigType( String configType ) throws Exception {
+		if( configType == null || configType.isEmpty()){
+			return new ArrayList<String>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceEmployeeConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceEmployeeConfig> root = cq.from(AttendanceEmployeeConfig.class);
+		Predicate p = cb.equal(root.get(AttendanceEmployeeConfig_.configType), configType);	
+		cq.select(root.get(AttendanceEmployeeConfig_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}	
+}

+ 59 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceImportFileInfoFactory.java

@@ -0,0 +1,59 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceImportFileInfo;
+import com.x.attendance.entity.AttendanceImportFileInfo_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceImportFileInfoFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceImportFileInfoFactory.class );
+	
+	public AttendanceImportFileInfoFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceImportFileInfo应用信息对象")
+	public AttendanceImportFileInfo get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceImportFileInfo.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceImportFileInfo应用信息列表")
+	public List<AttendanceImportFileInfo> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceImportFileInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceImportFileInfo> cq = cb.createQuery(AttendanceImportFileInfo.class);
+		Root<AttendanceImportFileInfo> root = cq.from( AttendanceImportFileInfo.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceImportFileInfo应用信息列表")
+	public List<AttendanceImportFileInfo> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceImportFileInfo>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceImportFileInfo.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceImportFileInfo> cq = cb.createQuery(AttendanceImportFileInfo.class);
+		Root<AttendanceImportFileInfo> root = cq.from(AttendanceImportFileInfo.class);
+		Predicate p = root.get(AttendanceImportFileInfo_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}	
+}

+ 92 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceScheduleSettingFactory.java

@@ -0,0 +1,92 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+import com.x.attendance.entity.AttendanceScheduleSetting_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceScheduleSettingFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceScheduleSettingFactory.class );
+	
+	public AttendanceScheduleSettingFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceScheduleSetting应用信息对象")
+	public AttendanceScheduleSetting get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceScheduleSetting.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceScheduleSetting应用信息列表")
+	public List<AttendanceScheduleSetting> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceScheduleSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceScheduleSetting> cq = cb.createQuery(AttendanceScheduleSetting.class);
+		Root<AttendanceScheduleSetting> root = cq.from( AttendanceScheduleSetting.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceScheduleSetting应用信息列表")
+	public List<AttendanceScheduleSetting> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceScheduleSetting>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceScheduleSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceScheduleSetting> cq = cb.createQuery(AttendanceScheduleSetting.class);
+		Root<AttendanceScheduleSetting> root = cq.from(AttendanceScheduleSetting.class);
+		Predicate p = root.get(AttendanceScheduleSetting_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据部门名称,查询部门排班信息对象")
+	public List<String> listByDepartmentName( String departmentName ) throws Exception{		
+		EntityManager em = this.entityManagerContainer().get(AttendanceScheduleSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceScheduleSetting> root = cq.from(AttendanceScheduleSetting.class);
+		Predicate p = cb.equal(root.get(AttendanceScheduleSetting_.organizationName), departmentName );
+		cq.select(root.get(AttendanceScheduleSetting_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据部门名称,查询部门排班信息对象")
+	public List<String> listByDepartmentNames( List<String> departmentNameList ) throws Exception{		
+		EntityManager em = this.entityManagerContainer().get(AttendanceScheduleSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceScheduleSetting> root = cq.from(AttendanceScheduleSetting.class);
+		Predicate p = root.get(AttendanceScheduleSetting_.organizationName).in(departmentNameList);
+		cq.select(root.get(AttendanceScheduleSetting_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据公司名称,查询公司排班信息对象")
+	public List<String> listByCompanyName( String companyName ) throws Exception{		
+		EntityManager em = this.entityManagerContainer().get(AttendanceScheduleSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceScheduleSetting> root = cq.from(AttendanceScheduleSetting.class);
+		Predicate p = cb.equal(root.get(AttendanceScheduleSetting_.companyName), companyName );
+		cq.select(root.get(AttendanceScheduleSetting_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+}

+ 265 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSelfHolidayFactory.java

@@ -0,0 +1,265 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.selfholiday.WrapInFilter;
+import com.x.attendance.entity.AttendanceSelfHoliday;
+import com.x.attendance.entity.AttendanceSelfHoliday_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceSelfHolidayFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceSelfHolidayFactory.class );
+	
+	public AttendanceSelfHolidayFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceSelfHoliday信息对象")
+	public AttendanceSelfHoliday get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceSelfHoliday.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceSelfHoliday信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceSelfHoliday.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceSelfHoliday> root = cq.from( AttendanceSelfHoliday.class);
+		cq.select(root.get(AttendanceSelfHoliday_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceSelfHoliday信息列表")
+	public List<AttendanceSelfHoliday> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceSelfHoliday>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceSelfHoliday.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceSelfHoliday> cq = cb.createQuery(AttendanceSelfHoliday.class);
+		Root<AttendanceSelfHoliday> root = cq.from(AttendanceSelfHoliday.class);
+		Predicate p = root.get(AttendanceSelfHoliday_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	@MethodDescribe("列示单个员工的AttendanceSelfHoliday信息列表")
+	public List<String> getByEmployeeName(String empName) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceSelfHoliday.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceSelfHoliday> root = cq.from( AttendanceSelfHoliday.class);
+		Predicate p = root.get(AttendanceSelfHoliday_.employeeName).in( empName );
+		cq.select(root.get(AttendanceSelfHoliday_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据流程的文档ID列示员工的AttendanceSelfHoliday信息列表")
+	public List<String> getByWorkFlowDocId(String docId) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceSelfHoliday.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceSelfHoliday> root = cq.from( AttendanceSelfHoliday.class);
+		Predicate p = cb.equal(root.get(AttendanceSelfHoliday_.docId), docId);
+		cq.select(root.get(AttendanceSelfHoliday_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listByStartDateAndEndDate(Date startDate, Date endDate) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceSelfHoliday.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceSelfHoliday> root = cq.from( AttendanceSelfHoliday.class);
+		Predicate p = cb.between(root.get(AttendanceSelfHoliday_.startTime), startDate, endDate);
+		p = cb.and( p, cb.between(root.get(AttendanceSelfHoliday_.endTime), startDate, endDate));
+		cq.select(root.get(AttendanceSelfHoliday_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<AttendanceSelfHoliday> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceSelfHoliday.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceSelfHoliday.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.employeeName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.organizationName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceSelfHoliday.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<AttendanceSelfHoliday> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceSelfHoliday.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+AttendanceSelfHoliday.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.employeeName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.organizationName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		
+		if( wrapIn.getKey() != null && !wrapIn.getKey().isEmpty()){
+			sql_stringBuffer.append(" order by o."+wrapIn.getKey()+" " + order );
+		}else{
+			sql_stringBuffer.append(" order by o.sequence " + order );
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceSelfHoliday.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilter wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( AttendanceSelfHoliday.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+AttendanceSelfHoliday.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getQ_empName()) && (!wrapIn.getQ_empName().isEmpty())) {
+			sql_stringBuffer.append(" and o.employeeName = ?" + (index));
+			vs.add( wrapIn.getQ_empName() );
+			index++;
+		}
+		if (null != wrapIn.getDepartmentNames() && wrapIn.getDepartmentNames().size()>0) {
+			sql_stringBuffer.append(" and o.organizationName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getDepartmentNames() );
+			index++;
+		}
+		if (null != wrapIn.getCompanyNames() && wrapIn.getCompanyNames().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ( ?" + (index) + ")");
+			vs.add( wrapIn.getCompanyNames() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), AttendanceSelfHoliday.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+}

+ 91 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceSettingFactory.java

@@ -0,0 +1,91 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceSetting;
+import com.x.attendance.entity.AttendanceSetting_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceSettingFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceSettingFactory.class );
+	
+	public AttendanceSettingFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceSetting应用信息对象")
+	public AttendanceSetting get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceSetting.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceSetting应用信息列表")
+	public List<AttendanceSetting> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceSetting> cq = cb.createQuery(AttendanceSetting.class);
+		Root<AttendanceSetting> root = cq.from( AttendanceSetting.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceSetting应用信息列表")
+	public List<AttendanceSetting> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceSetting>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceSetting> cq = cb.createQuery(AttendanceSetting.class);
+		Root<AttendanceSetting> root = cq.from(AttendanceSetting.class);
+		Predicate p = root.get(AttendanceSetting_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据CODE列示指定Id的AttendanceSetting应用信息列表")
+	public List<String> listIdsByCode(String code) throws Exception {
+		if( code == null || code.isEmpty() ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceSetting> root = cq.from(AttendanceSetting.class);
+		Predicate p = cb.equal(root.get(AttendanceSetting_.configCode),  code);
+		cq.select(root.get(AttendanceSetting_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public AttendanceSetting getWithConfigCode(String configCode) throws Exception {
+		if( configCode == null || configCode.isEmpty() ){
+			return null;
+		}
+		AttendanceSetting attendanceSetting = null;
+		List<AttendanceSetting> settingList = null;
+		EntityManager em = this.entityManagerContainer().get(AttendanceSetting.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceSetting> cq = cb.createQuery(AttendanceSetting.class);
+		Root<AttendanceSetting> root = cq.from(AttendanceSetting.class);
+		Predicate p = cb.equal(root.get( AttendanceSetting_.configCode ),  configCode );
+		settingList = em.createQuery(cq.where(p)).getResultList();
+		if( settingList != null && settingList.size() > 0 ){
+			attendanceSetting = settingList.get(0);
+		}
+		return attendanceSetting;
+	}
+}

+ 131 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceStatisticRequireLogFactory.java

@@ -0,0 +1,131 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceStatisticRequireLog;
+import com.x.attendance.entity.AttendanceStatisticRequireLog_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 员工考勤需求配置服务器
+ * @author liyi
+ */
+public class AttendanceStatisticRequireLogFactory extends AbstractFactory {
+	
+	public AttendanceStatisticRequireLogFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceStatisticRequireLog信息对象")
+	public AttendanceStatisticRequireLog get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceStatisticRequireLog.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceStatisticRequireLog信息列表")
+	public List<AttendanceStatisticRequireLog> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticRequireLog.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticRequireLog> cq = cb.createQuery(AttendanceStatisticRequireLog.class);
+		Root<AttendanceStatisticRequireLog> root = cq.from( AttendanceStatisticRequireLog.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceStatisticRequireLog信息列表")
+	public List<AttendanceStatisticRequireLog> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceStatisticRequireLog>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticRequireLog.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticRequireLog> cq = cb.createQuery(AttendanceStatisticRequireLog.class);
+		Root<AttendanceStatisticRequireLog> root = cq.from(AttendanceStatisticRequireLog.class);
+		Predicate p = root.get(AttendanceStatisticRequireLog_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据统计名称,统计Key,处理状态,列示AttendanceStatisticRequireLog信息列表")
+	public List<AttendanceStatisticRequireLog> getByNameKeyAndStatus( String name, String key, String stauts ) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticRequireLog.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticRequireLog> cq = cb.createQuery(AttendanceStatisticRequireLog.class);
+		Root<AttendanceStatisticRequireLog> root = cq.from(AttendanceStatisticRequireLog.class);
+		Predicate p = root.get(AttendanceStatisticRequireLog_.id).isNotNull();
+		if( name != null && !name.isEmpty() ){
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticName), name));
+		}
+		if( key != null && !key.isEmpty() ){
+			p = cb.and(p,  cb.equal(root.get(AttendanceStatisticRequireLog_.statisticKey), key));
+		}
+		if( stauts != null && !stauts.isEmpty() ){
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.processStatus), stauts));
+		}
+		return em.createQuery( cq.where(p) ).getResultList();
+	}
+
+	public List<AttendanceStatisticRequireLog> getByNameKeyAndStatus(String statisticType, String key, String statisticYear, String statisticMonth, String statisticDate, String status) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticRequireLog.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticRequireLog> cq = cb.createQuery(AttendanceStatisticRequireLog.class);
+		Root<AttendanceStatisticRequireLog> root = cq.from(AttendanceStatisticRequireLog.class);
+		Predicate p = root.get(AttendanceStatisticRequireLog_.id).isNotNull();
+		if( statisticType != null && !statisticType.isEmpty() ){
+			//logger.debug( "statisticType=" + statisticType );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticType), statisticType));
+		}
+		if( key != null && !key.isEmpty() ){
+			//logger.debug( "statisticKey=" + key );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticKey), key));
+		}
+		if( statisticYear != null && !statisticYear.isEmpty() ){
+			//logger.debug( "statisticYear=" + statisticYear );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticYear), statisticYear));
+		}
+		if( statisticMonth != null && !statisticMonth.isEmpty() ){
+			//logger.debug( "statisticMonth=" + statisticMonth );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticMonth), statisticMonth));
+		}
+		if( statisticDate != null && !statisticDate.isEmpty() ){
+			//logger.debug( "statisticDay=" + statisticDate );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticDay), statisticDate));
+		}
+		if( status != null && !status.isEmpty() ){
+			//logger.debug( "processStatus=" + status );
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.processStatus), status));
+		}
+		//logger.debug(em.createQuery( cq.where(p) ).toString());
+		return em.createQuery( cq.where(p) ).getResultList();
+	}
+
+	/**
+	 * 根据统计的类型以及处理状态获取所有符合条件的统计需求对象列表
+	 * 
+	 * @param statisticType:PERSON_PER_MONTH|DEPARTMENT_PER_MONTH|COMPANY_PER_MONTH|DEPARTMENT_PER_DAY|COMPANY_PER_DAY
+	 * @param processStatus:WAITING|PROCESSING|COMPLETE|ERROR
+	 * @return
+	 * @throws Exception
+	 */
+	public List<AttendanceStatisticRequireLog> listByStatisticTypeAndStatus( String statisticType, String processStatus) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticRequireLog.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticRequireLog> cq = cb.createQuery(AttendanceStatisticRequireLog.class);
+		Root<AttendanceStatisticRequireLog> root = cq.from(AttendanceStatisticRequireLog.class);
+		Predicate p = root.get(AttendanceStatisticRequireLog_.id).isNotNull();
+		if( statisticType != null && !statisticType.isEmpty() ){
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.statisticType), statisticType));
+		}
+		if( processStatus != null && !processStatus.isEmpty() ){
+			p = cb.and(p, cb.equal(root.get(AttendanceStatisticRequireLog_.processStatus), processStatus));
+		}
+		//logger.debug( em.createQuery(cq.where(p)).toString() );
+		return em.createQuery( cq.where(p) ).getResultList();
+	}
+}

+ 79 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceStatisticalCycleFactory.java

@@ -0,0 +1,79 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceStatisticalCycle;
+import com.x.attendance.entity.AttendanceStatisticalCycle_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceStatisticalCycleFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleFactory.class );
+	
+	public AttendanceStatisticalCycleFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceStatisticalCycle信息对象")
+	public AttendanceStatisticalCycle get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceStatisticalCycle.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceStatisticalCycle信息列表")
+	public List<AttendanceStatisticalCycle> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticalCycle.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticalCycle> cq = cb.createQuery( AttendanceStatisticalCycle.class );
+		Root<AttendanceStatisticalCycle> root = cq.from( AttendanceStatisticalCycle.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceStatisticalCycle信息列表")
+	public List<AttendanceStatisticalCycle> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceStatisticalCycle>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticalCycle.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceStatisticalCycle> cq = cb.createQuery(AttendanceStatisticalCycle.class);
+		Root<AttendanceStatisticalCycle> root = cq.from(AttendanceStatisticalCycle.class);
+		Predicate p = root.get(AttendanceStatisticalCycle_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据参数列示AttendanceStatisticalCycle信息列表")
+	public List<String> listByParameter( String companyName, String organizatinName, String cycleYear, String cycleMonth ) throws Exception{
+		EntityManager em = this.entityManagerContainer().get(AttendanceStatisticalCycle.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceStatisticalCycle> root = cq.from(AttendanceStatisticalCycle.class);
+		Predicate p = cb.equal( root.get( AttendanceStatisticalCycle_.cycleYear), cycleYear);		
+		if( companyName != null ){ 
+			 p = cb.and( p, cb.equal( root.get( AttendanceStatisticalCycle_.companyName), companyName));
+		}
+		if( organizatinName != null ){ 
+			 p = cb.and( p, cb.equal( root.get( AttendanceStatisticalCycle_.departmentName), organizatinName));
+		}
+		if( cycleMonth != null ){ 
+			 p = cb.and( p, cb.equal( root.get( AttendanceStatisticalCycle_.cycleMonth), cycleMonth));
+		}
+		cq.select(root.get(AttendanceStatisticalCycle_.id));
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+}

+ 234 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceWorkDayConfigFactory.java

@@ -0,0 +1,234 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.entity.AttendanceWorkDayConfig;
+import com.x.attendance.entity.AttendanceWorkDayConfig_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+/**
+ * 系统配置信息表基础功能服务类
+ * @author liyi
+ */
+public class AttendanceWorkDayConfigFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceWorkDayConfigFactory.class );
+	private DateOperation dateOperation = new DateOperation();
+	
+	public AttendanceWorkDayConfigFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的AttendanceWorkDayConfig信息对象")
+	public AttendanceWorkDayConfig get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, AttendanceWorkDayConfig.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的AttendanceWorkDayConfig信息列表")
+	public List<AttendanceWorkDayConfig> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceWorkDayConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceWorkDayConfig> cq = cb.createQuery(AttendanceWorkDayConfig.class);
+		Root<AttendanceWorkDayConfig> root = cq.from( AttendanceWorkDayConfig.class);
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的AttendanceWorkDayConfig信息列表")
+	public List<AttendanceWorkDayConfig> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<AttendanceWorkDayConfig>();
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceWorkDayConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceWorkDayConfig> cq = cb.createQuery(AttendanceWorkDayConfig.class);
+		Root<AttendanceWorkDayConfig> root = cq.from(AttendanceWorkDayConfig.class);
+		Predicate p = root.get(AttendanceWorkDayConfig_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据年份月份列示全部的AttendanceWorkDayConfig信息列表")
+	public List<String> listByYearAndMonth( String year, String month ) throws Exception {
+		if( year == null ){
+			return null;
+		}
+		if( "0".equals(month) || "00".equals(month) || "(0)".equals(month)){
+			month = null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get(AttendanceWorkDayConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceWorkDayConfig> root = cq.from( AttendanceWorkDayConfig.class);
+		cq.select(root.get(AttendanceWorkDayConfig_.id));
+		
+		Predicate p = cb.equal( root.get(AttendanceWorkDayConfig_.configYear), year);
+		if( month != null ){
+			p = cb.and( p, cb.equal( root.get(AttendanceWorkDayConfig_.configMonth), month));
+		}
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据年份和节假日名称列示全部的AttendanceWorkDayConfig信息列表")
+	public List<String> listByYearAndName( String year, String configName ) throws Exception {
+		if( year == null ){
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get(AttendanceWorkDayConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceWorkDayConfig> root = cq.from( AttendanceWorkDayConfig.class);
+		cq.select(root.get(AttendanceWorkDayConfig_.id));
+		
+		Predicate p = cb.equal( root.get(AttendanceWorkDayConfig_.configYear), year);
+		if( configName != null ){
+			p = cb.and( p, cb.equal( root.get(AttendanceWorkDayConfig_.configName), configName));
+		}
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+	
+	@MethodDescribe("根据节假日名称列示全部的AttendanceWorkDayConfig信息列表")
+	public List<String> listByName( String configName ) throws Exception {
+		EntityManager em = this.entityManagerContainer().get(AttendanceWorkDayConfig.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<AttendanceWorkDayConfig> root = cq.from( AttendanceWorkDayConfig.class);
+		cq.select(root.get(AttendanceWorkDayConfig_.id));
+		
+		Predicate p = cb.equal( root.get(AttendanceWorkDayConfig_.configName), configName);
+		
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	@MethodDescribe("根据节假日配置计算一个月的应出勤天数")
+	public int getWorkDaysCountForMonth( String s_year, String _month, List<AttendanceWorkDayConfig> workDayConfigList ) throws Exception {
+		/**
+		 * 1、计算当月的总天数
+		 * 2、遍历每天的日期
+		 *    1)判断是否周末
+		 *    2)判断是否调工作日
+		 *    3)判断是否节日
+		 */
+		int workDaysCountForMonth = 0;
+		//1、计算当月的总天数
+		int daysCountForMonth = dateOperation.getDaysForMonth( s_year + "-" + _month + "-01" );
+		//logger.debug(s_year + "-" + _month + ", 总天数:" + daysCountForMonth );
+		workDaysCountForMonth = daysCountForMonth; //先假设每天都是工作日
+		//2、遍历每天的日期
+		String dateString = null;
+		boolean isHoliday = true;
+		for( int i = 1; i<= daysCountForMonth ; i++ ){
+			isHoliday = true;
+			dateString = s_year + "-" + _month + "-" + (i<10?"0"+i:i);
+			//判断当天是否周末
+			if( !dateOperation.isWeekend( dateOperation.getDateFromString( dateString )) ){
+				//logger.debug( dateString + ", 不是周末。" );
+				//如果不是周末
+				if( workDayConfigList != null && workDayConfigList.size() > 0 ){
+					//遍历所有的节假日配置进行判断,是否法定节假日
+					for( AttendanceWorkDayConfig workDayConfig : workDayConfigList ){
+						if( workDayConfig.getConfigDate().trim().equals( dateString ) && "Holiday".equalsIgnoreCase( workDayConfig.getConfigType() )
+						){
+							workDaysCountForMonth--;//当天不是工作日,当月出勤日减一天。
+							//logger.debug( dateString + ", 节假日减1天。" );
+							break;
+						}
+					}
+				}
+			}else{
+				//如果是周末
+				//logger.debug( dateString + ", 是周末。" );
+				if( workDayConfigList != null && workDayConfigList.size() > 0 ){
+					//遍历所有的节假日配置进行判断,是否调休工作日
+					for( AttendanceWorkDayConfig workDayConfig : workDayConfigList ){
+						if( workDayConfig.getConfigDate().trim().equals( dateString ) && "Workday".equalsIgnoreCase( workDayConfig.getConfigType() )
+						){
+							isHoliday = false; //是配置的调休工作日
+							logger.debug( dateString + ", 判断应该是工作日。" );
+							break;
+						}
+					}
+				}
+				if( isHoliday ){
+					//如果不是配置的调休工作日,则当天不是工作日,当月出勤日减一天。
+					//logger.debug( dateString + ", 是周末未调休,减一天。" );
+					workDaysCountForMonth--;
+					//logger.debug( dateString + ", 是工作日,加一天。" );
+				}else{
+					//logger.debug( dateString + ", 是周末但是调休。" );
+				}
+			}
+		}
+		//logger.debug( "返回结果,工作日总天数:" + workDaysCountForMonth );
+		return workDaysCountForMonth;
+	}
+	
+	@MethodDescribe("根据节假日配置计算一个周期内的应出勤天数")
+	public Integer getWorkDaysCountForMonth( Date startDate, Date endDate, List<AttendanceWorkDayConfig> workDayConfigList ) throws Exception {
+		/**
+		 * 1、计算当月的总天数
+		 * 2、遍历每天的日期
+		 *    1)判断是否周末
+		 *    2)判断是否调工作日
+		 *    3)判断是否节日
+		 */
+		boolean isHoliday = true;
+		int workDaysCountForMonth = 0;
+		if( endDate.getTime() > new Date().getTime()){
+			endDate = new Date();
+		}
+		List<String> dateStringList = dateOperation.listDateStringBetweenDate(startDate, endDate);
+		if( dateStringList != null && dateStringList.size() > 0 ){
+			workDaysCountForMonth = dateStringList.size();
+			for( String dateString : dateStringList){
+				//判断当天是否周末
+				if( !dateOperation.isWeekend( dateOperation.getDateFromString( dateString )) ){
+					//logger.debug( dateString + ", 不是周末。" );
+					//如果不是周末
+					if( workDayConfigList != null && workDayConfigList.size() > 0 ){
+						//遍历所有的节假日配置进行判断,是否法定节假日
+						for( AttendanceWorkDayConfig workDayConfig : workDayConfigList ){
+							if( workDayConfig.getConfigDate().trim().equals( dateString ) && "Holiday".equalsIgnoreCase( workDayConfig.getConfigType() )
+							){
+								workDaysCountForMonth--;//当天不是工作日,当月出勤日减一天。
+								break;
+							}
+						}
+					}
+				}else{
+					//如果是周末
+					if( workDayConfigList != null && workDayConfigList.size() > 0 ){
+						//遍历所有的节假日配置进行判断,是否调休工作日
+						for( AttendanceWorkDayConfig workDayConfig : workDayConfigList ){
+							if( workDayConfig.getConfigDate().trim().equals( dateString ) && "Workday".equalsIgnoreCase( workDayConfig.getConfigType() )
+							){
+								isHoliday = false; //是配置的调休工作日
+								logger.debug( dateString + ", 判断应该是工作日。" );
+								break;
+							}
+						}
+					}
+					if( isHoliday ){
+						//如果不是配置的调休工作日,则当天不是工作日,当月出勤日减一天。
+						workDaysCountForMonth--;
+					}
+				}
+			}
+		}
+		return workDaysCountForMonth;
+	}
+}

+ 293 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticCompanyForDayFactory.java

@@ -0,0 +1,293 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.WrapInFilterStatisticCompanyForDay;
+import com.x.attendance.entity.StatisticCompanyForDay;
+import com.x.attendance.entity.StatisticCompanyForDay_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+public class StatisticCompanyForDayFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( StatisticCompanyForDayFactory.class );
+	
+	public StatisticCompanyForDayFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的StatisticCompanyForDay应用信息对象")
+	public StatisticCompanyForDay get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, StatisticCompanyForDay.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的StatisticCompanyForDay应用信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(StatisticCompanyForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticCompanyForDay> root = cq.from( StatisticCompanyForDay.class);
+		cq.select(root.get(StatisticCompanyForDay_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的StatisticCompanyForDay应用信息列表")
+	public List<StatisticCompanyForDay> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<StatisticCompanyForDay>();
+		}
+		EntityManager em = this.entityManagerContainer().get(StatisticCompanyForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticCompanyForDay> cq = cb.createQuery(StatisticCompanyForDay.class);
+		Root<StatisticCompanyForDay> root = cq.from(StatisticCompanyForDay.class);
+		Predicate p = root.get(StatisticCompanyForDay_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listByCompanyRecordDateString(String companyName, String sDate) throws Exception{
+		if( companyName == null || companyName.isEmpty() ){
+			logger.error("companyName is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticCompanyForDay> root = cq.from( StatisticCompanyForDay.class);
+		Predicate p = cb.equal( root.get( StatisticCompanyForDay_.companyName), companyName);
+		if( sDate == null || sDate.isEmpty() ){
+			logger.error("sDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticCompanyForDay_.statisticDate), sDate));
+		}
+		cq.select(root.get( StatisticCompanyForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+
+	public List<String> listByNameYearAndMonth(String name, String year, String month) throws Exception {
+		if( name == null || name.isEmpty() ){
+			logger.error("name is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticCompanyForDay> root = cq.from( StatisticCompanyForDay.class);
+		Predicate p = cb.equal( root.get( StatisticCompanyForDay_.companyName), name);
+		if( year == null || year.isEmpty() ){
+			logger.error("year is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticCompanyForDay_.statisticYear), year));
+		}
+		if( month == null || month.isEmpty() ){
+			logger.error("month is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticCompanyForDay_.statisticMonth), month));
+		}
+		cq.select(root.get( StatisticCompanyForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<StatisticCompanyForDay> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticCompanyForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForDay.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticCompanyForDay.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+				
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<StatisticCompanyForDay> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticCompanyForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForDay.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticCompanyForDay.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterStatisticCompanyForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForDay.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+StatisticCompanyForDay.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+}

+ 274 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticCompanyForMonthFactory.java

@@ -0,0 +1,274 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.WrapInFilterStatisticCompanyForMonth;
+import com.x.attendance.entity.StatisticCompanyForMonth;
+import com.x.attendance.entity.StatisticCompanyForMonth_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+public class StatisticCompanyForMonthFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( StatisticCompanyForMonthFactory.class );
+	
+	public StatisticCompanyForMonthFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的StatisticCompanyForMonth信息对象")
+	public StatisticCompanyForMonth get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, StatisticCompanyForMonth.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的StatisticCompanyForMonth信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(StatisticCompanyForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticCompanyForMonth> root = cq.from( StatisticCompanyForMonth.class);
+		cq.select(root.get(StatisticCompanyForMonth_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的StatisticCompanyForMonth信息列表")
+	public List<StatisticCompanyForMonth> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<StatisticCompanyForMonth>();
+		}
+		EntityManager em = this.entityManagerContainer().get(StatisticCompanyForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticCompanyForMonth> cq = cb.createQuery(StatisticCompanyForMonth.class);
+		Root<StatisticCompanyForMonth> root = cq.from(StatisticCompanyForMonth.class);
+		Predicate p = root.get(StatisticCompanyForMonth_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listByCompanyYearAndMonth(String companyName, String sYear, String sMonth) throws Exception {
+		if( companyName == null || companyName.isEmpty() ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticCompanyForMonth> root = cq.from( StatisticCompanyForMonth.class);
+		Predicate p = cb.equal( root.get(StatisticCompanyForMonth_.companyName), companyName);
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticCompanyForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticCompanyForMonth_.statisticMonth), sMonth));
+		}
+		cq.select(root.get(StatisticCompanyForMonth_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(60).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<StatisticCompanyForMonth> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticCompanyForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticCompanyForMonth.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+				
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<StatisticCompanyForMonth> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticCompanyForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticCompanyForMonth.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterStatisticCompanyForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticCompanyForMonth.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+StatisticCompanyForMonth.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticCompanyForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+
+}

+ 353 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticDepartmentForDayFactory.java

@@ -0,0 +1,353 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.WrapInFilterStatisticDepartmentForDay;
+import com.x.attendance.entity.StatisticDepartmentForDay;
+import com.x.attendance.entity.StatisticDepartmentForDay_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+public class StatisticDepartmentForDayFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( StatisticDepartmentForDayFactory.class );
+	
+	public StatisticDepartmentForDayFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的StatisticDepartmentForDay信息对象")
+	public StatisticDepartmentForDay get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, StatisticDepartmentForDay.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的StatisticDepartmentForDay信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		cq.select(root.get(StatisticDepartmentForDay_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的StatisticDepartmentForDay信息列表")
+	public List<StatisticDepartmentForDay> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<StatisticDepartmentForDay>();
+		}
+		EntityManager em = this.entityManagerContainer().get(StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticDepartmentForDay> cq = cb.createQuery(StatisticDepartmentForDay.class);
+		Root<StatisticDepartmentForDay> root = cq.from(StatisticDepartmentForDay.class);
+		Predicate p = root.get(StatisticDepartmentForDay_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listByDepartmentRecordDateString( List<String> organizationName, String sDate) throws Exception {
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		Predicate p = root.get( StatisticDepartmentForDay_.organizationName).in(organizationName);
+		if( sDate == null || sDate.isEmpty() ){
+			logger.error("sDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticDate), sDate));
+		}
+		cq.select(root.get( StatisticDepartmentForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+	
+	public List<String> listByDepartmentRecordDateString( String organizationName, String sDate) throws Exception {
+		if( organizationName == null || organizationName.isEmpty() ){
+			logger.error("organizationName is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		Predicate p = cb.equal( root.get( StatisticDepartmentForDay_.organizationName), organizationName);
+		if( sDate == null || sDate.isEmpty() ){
+			logger.error("sDate is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticDate), sDate));
+		}
+		cq.select(root.get( StatisticDepartmentForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+
+	public List<String> listByDepartmentDayYearAndMonth(List<String> name, String year, String month) throws Exception {
+		if( name == null || name.size() == 0 ){
+			logger.error("name is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		Predicate p = root.get( StatisticDepartmentForDay_.organizationName).in(name);
+		if( year == null || year.isEmpty() ){
+			logger.error("year is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticYear), year));
+		}
+		if( month == null || month.isEmpty() ){
+			logger.error("month is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticMonth), month));
+		}
+		cq.select(root.get( StatisticDepartmentForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+
+	public List<String> listByDepartmentDayDate(List<String> name, String date) throws Exception{
+		if( name == null || name.size() == 0 ){
+			logger.error("name is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		Predicate p = root.get( StatisticDepartmentForDay_.organizationName).in( name );
+		if( date == null || date.isEmpty() ){
+			logger.error("year is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticDate), date));
+		}
+		cq.select(root.get( StatisticDepartmentForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+	
+	public List<String> listByDepartmentDayDate( String name, String date) throws Exception{
+		if( name == null || name.isEmpty() ){
+			logger.error("name is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root< StatisticDepartmentForDay> root = cq.from( StatisticDepartmentForDay.class);
+		Predicate p = cb.equal(root.get( StatisticDepartmentForDay_.organizationName), name);
+		if( date == null || date.isEmpty() ){
+			logger.error("year is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticDepartmentForDay_.statisticDate), date));
+		}
+		cq.select(root.get( StatisticDepartmentForDay_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(62).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<StatisticDepartmentForDay> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticDepartmentForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticDepartmentForDay.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+				
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<StatisticDepartmentForDay> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticDepartmentForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticDepartmentForDay.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterStatisticDepartmentForDay wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForDay.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+StatisticDepartmentForDay.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForDay.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+}

+ 878 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticDepartmentForMonthFactory.java

@@ -0,0 +1,878 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.WrapInFilterStatisticDepartmentForMonth;
+import com.x.attendance.entity.StatisticDepartmentForMonth;
+import com.x.attendance.entity.StatisticDepartmentForMonth_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+public class StatisticDepartmentForMonthFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( StatisticDepartmentForMonthFactory.class );
+	
+	public StatisticDepartmentForMonthFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的StatisticDepartmentForMonth信息对象")
+	public StatisticDepartmentForMonth get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, StatisticDepartmentForMonth.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的StatisticDepartmentForMonth信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);
+		cq.select(root.get(StatisticDepartmentForMonth_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的StatisticDepartmentForMonth信息列表")
+	public List<StatisticDepartmentForMonth> list(List<String> ids) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<StatisticDepartmentForMonth>();
+		}
+		EntityManager em = this.entityManagerContainer().get(StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticDepartmentForMonth> cq = cb.createQuery(StatisticDepartmentForMonth.class);
+		Root<StatisticDepartmentForMonth> root = cq.from(StatisticDepartmentForMonth.class);
+		Predicate p = root.get(StatisticDepartmentForMonth_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	
+	
+	
+	public List<String> listByDepartmentYearAndMonth( String organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.isEmpty() ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);
+		Predicate p = cb.equal( root.get(StatisticDepartmentForMonth_.organizationName), organizationName);
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		cq.select(root.get(StatisticDepartmentForMonth_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(60).getResultList();
+	}
+	
+	public List<String> listByDepartmentYearAndMonth( List<String> organizationNames, String sYear, String sMonth) throws Exception{
+		if( organizationNames == null || organizationNames.size() == 0  ){
+			logger.error("organizationNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in(organizationNames);
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		cq.select(root.get(StatisticDepartmentForMonth_.id));
+		return em.createQuery(cq.where(p)).setMaxResults(60).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<StatisticDepartmentForMonth> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticDepartmentForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticDepartmentForMonth.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+				
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<StatisticDepartmentForMonth> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticDepartmentForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticDepartmentForMonth.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterStatisticDepartmentForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+StatisticDepartmentForMonth.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticDepartmentForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员迟到次数总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLateCountByDepartmentYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.lateCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员异常打卡次数总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumAbNormalDutyCountByDepartmentYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.abNormalDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员工时不足人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLackOfTimeCountByDepartmentYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.lackOfTimeCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员早退人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLeaveEarlyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.leaveEarlyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员签退人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOffDutyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.offDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员签到人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOnDutyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员出勤人天总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAttendanceDayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onDutyEmployeeCount ) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员请假人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onSelfHolidayCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门名称,统计年月,统计公司所有人员缺勤人次总和
+	 * @param organizationName
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.absenceDayCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );		
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员数量
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLateCountByCompanyNamesYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.lateCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员出勤人天数总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAttendanceDayCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onDutyEmployeeCount ) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员异常打卡次数总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumAbNormalDutyCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.abNormalDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员工时不足次数总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLackOfTimeCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}	
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.lackOfTimeCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员早退人次总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLeaveEarlyCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}	
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.leaveEarlyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员签退人次总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOffDutyCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}	
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.offDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员签到人次总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOnDutyCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}	
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onDutyCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员请假人次总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}	
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.onSelfHolidayCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	/**
+	 * 根据公司名称,统计年月,统计公司所有人员缺勤人天总和
+	 * @param companyNames
+	 * @param cycleYear
+	 * @param cycleMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDayCountByCompanyNamesYearAndMonth( List<String> companyNames, String cycleYear, String cycleMonth ) throws Exception{
+		if( companyNames == null || companyNames.size() == 0 ){
+			logger.error("companyNames is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticDepartmentForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticDepartmentForMonth> root = cq.from( StatisticDepartmentForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticDepartmentForMonth_.absenceDayCount) ) );		
+		Predicate p = root.get(StatisticDepartmentForMonth_.companyName).in( companyNames );
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticYear), cycleYear));
+		}
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticDepartmentForMonth_.statisticMonth), cycleMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+}

+ 663 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/StatisticPersonForMonthFactory.java

@@ -0,0 +1,663 @@
+package com.x.attendance.assemble.control.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.AbstractFactory;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.WrapInFilterStatisticPersonForMonth;
+import com.x.attendance.entity.StatisticPersonForMonth;
+import com.x.attendance.entity.StatisticPersonForMonth_;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.utils.annotation.MethodDescribe;
+
+public class StatisticPersonForMonthFactory extends AbstractFactory {
+
+	private Logger logger = LoggerFactory.getLogger( StatisticPersonForMonthFactory.class );
+	
+	public StatisticPersonForMonthFactory(Business business) throws Exception {
+		super(business);
+	}
+
+	@MethodDescribe("获取指定Id的StatisticPersonForMonth信息对象")
+	public StatisticPersonForMonth get( String id ) throws Exception {
+		return this.entityManagerContainer().find(id, StatisticPersonForMonth.class, ExceptionWhen.none);
+	}
+	
+	@MethodDescribe("列示全部的StatisticPersonForMonth信息列表")
+	public List<String> listAll() throws Exception {
+		EntityManager em = this.entityManagerContainer().get(StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);
+		cq.select(root.get(StatisticPersonForMonth_.id));
+		return em.createQuery(cq).getResultList();
+	}
+	
+	@MethodDescribe("列示指定Id的StatisticPersonForMonth信息列表")
+	public List<StatisticPersonForMonth> list( List<String> ids ) throws Exception {
+		if( ids == null || ids.size() == 0 ){
+			return new ArrayList<StatisticPersonForMonth>();
+		}
+		EntityManager em = this.entityManagerContainer().get(StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticPersonForMonth> cq = cb.createQuery(StatisticPersonForMonth.class);
+		Root<StatisticPersonForMonth> root = cq.from(StatisticPersonForMonth.class);
+		Predicate p = root.get(StatisticPersonForMonth_.id).in(ids);
+		return em.createQuery(cq.where(p)).getResultList();
+	}
+
+	public List<String> listByUserYearAndMonth( String employeeName, String sYear, String sMonth ) throws Exception {
+		if( employeeName == null || employeeName.isEmpty() ){
+			logger.error("employeeName is null!");
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery( String.class );
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class );
+		Predicate p = cb.equal( root.get( StatisticPersonForMonth_.employeeName ), employeeName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error( "sYear is null!" );
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticYear ), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticMonth ), sMonth));
+		}
+		cq.select(root.get( StatisticPersonForMonth_.id ) );
+		return em.createQuery( cq.where( p ) ).setMaxResults( 60 ).getResultList();
+	}
+
+	public List<String> listByDepartmentYearAndMonth( List<String> departmentNameList, String year, String month ) throws Exception{
+		
+		if( departmentNameList == null || departmentNameList.size() == 0 ){
+			logger.error( "name is null!" );
+			return null;
+		}
+		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<String> cq = cb.createQuery(String.class );
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class );
+		Predicate p = root.get( StatisticPersonForMonth_.organizationName ).in(departmentNameList);
+		if( year == null || year.isEmpty() ){
+			logger.error("year is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticYear ), year ) );
+		}
+		if( month == null || month.isEmpty() ){
+			logger.error("month is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticMonth ), month ));
+		}
+		cq.select(root.get( StatisticPersonForMonth_.id ));
+		return em.createQuery( cq.where( p ) ).setMaxResults( 60 ).getResultList();
+	}
+	
+	/**
+	 * 查询下一页的信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public List<StatisticPersonForMonth> listIdsNextWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticPersonForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		Integer index = 1;
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticPersonForMonth.class.getCanonicalName()+" o where 1=1" );
+
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? "<" : ">") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+				
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsNextWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticPersonForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		return query.setMaxResults(count).getResultList();
+	}	
+	
+	/**
+	 * 查询上一页的文档信息数据
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public List<StatisticPersonForMonth> listIdsPrevWithFilter( String id, Integer count, Object sequence, WrapInFilterStatisticPersonForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class );
+		String order = wrapIn.getOrder();//排序方式
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		if( order == null || order.isEmpty() ){
+			order = "DESC";
+		}
+		
+		sql_stringBuffer.append( "SELECT o FROM "+StatisticPersonForMonth.class.getCanonicalName()+" o where 1=1" );
+		if ((null != sequence) ) {
+			sql_stringBuffer.append(" and o.sequence " + (StringUtils.equalsIgnoreCase(order, "DESC") ? ">" : "<") + (" ?" + (index)));
+			vs.add(sequence);
+			index++;
+		}
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		sql_stringBuffer.append(" order by o.sequence " + order );
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticPersonForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}
+		
+		return query.setMaxResults(20).getResultList();
+	}
+	
+	/**
+	 * 查询符合的文档信息总数
+	 * @param id
+	 * @param count
+	 * @param sequence
+	 * @param wrapIn
+	 * @return
+	 * @throws Exception
+	 */
+	public long getCountWithFilter( WrapInFilterStatisticPersonForMonth wrapIn ) throws Exception {
+		//先获取上一页最后一条的sequence值,如果有值的话,以此sequence值作为依据取后续的count条数据
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class );
+		List<Object> vs = new ArrayList<>();
+		StringBuffer sql_stringBuffer = new StringBuffer();
+		Integer index = 1;
+		
+		sql_stringBuffer.append( "SELECT count(o.id) FROM "+StatisticPersonForMonth.class.getCanonicalName()+" o where 1=1" );
+		
+		if ((null != wrapIn.getEmployeeName()) && wrapIn.getEmployeeName().size() > 0) {
+			sql_stringBuffer.append(" and o.employeeName in ?" + (index));
+			vs.add( wrapIn.getEmployeeName() );
+			index++;
+		}
+		if ((null != wrapIn.getOrganizationName()) && wrapIn.getOrganizationName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.organizationName in ?" + (index));
+			vs.add( wrapIn.getOrganizationName() );
+			index++;
+		}
+		if ((null != wrapIn.getCompanyName()) && wrapIn.getCompanyName().size() > 0 ) {
+			sql_stringBuffer.append(" and o.companyName in ?" + (index));
+			vs.add( wrapIn.getCompanyName() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticYear() ) && (!wrapIn.getStatisticYear().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticYear = ?" + (index));
+			vs.add( wrapIn.getStatisticYear() );
+			index++;
+		}
+		if ((null != wrapIn.getStatisticMonth()) && (!wrapIn.getStatisticMonth().isEmpty())) {
+			sql_stringBuffer.append(" and o.statisticMonth = ?" + (index));
+			vs.add( wrapIn.getStatisticMonth() );
+			index++;
+		}
+		
+		//logger.debug("listIdsPrevWithFilter:["+sql_stringBuffer.toString()+"]");
+		//logger.debug( vs );
+		
+		Query query = em.createQuery( sql_stringBuffer.toString(), StatisticPersonForMonth.class );
+		//为查询设置所有的参数值
+		for (int i = 0; i < vs.size(); i++) {
+			query.setParameter(i + 1, vs.get(i));
+		}		
+		return (Long) query.getSingleResult();
+	}
+	
+	public StatisticPersonForMonth get(String employeeName, String cycleYear, String cycleMonth) throws Exception {
+		if( employeeName == null ){
+			logger.error("employeeName is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<StatisticPersonForMonth> cq = cb.createQuery(StatisticPersonForMonth.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);	
+		Predicate p = cb.equal( root.get( StatisticPersonForMonth_.employeeName ), employeeName);		
+		if( cycleYear == null || cycleYear.isEmpty() ){
+			logger.error("cycleYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticYear), cycleYear));
+		}
+		
+		if( cycleMonth == null || cycleMonth.isEmpty() ){
+			logger.error("cycleMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get( StatisticPersonForMonth_.statisticMonth), cycleMonth));
+		}
+		try{
+			return em.createQuery(cq.where(p)).getSingleResult();
+		}catch(NoResultException e){
+			return null;
+		}
+	}
+	
+	/**
+	 * 根据部门名称,年份月份,统计员工数量
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long countEmployeeCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		//查询总数
+		cq.select( cb.count( root ) );	
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门,统计年月,计算部门内所有员工迟到数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLateCountByDepartmentYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.lateTimes ) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工出勤天数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAttendanceDayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.onDutyDayCount) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工异常打卡数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumAbNormalDutyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.abNormalDutyCount) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工工时不足次数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLackOfTimeCountByDepartmentYearAndMonth(List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.lackOfTimeCount) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工早退次数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumLeaveEarlyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.leaveEarlyTimes ) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工签退次数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOffDutyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.offDutyTimes ) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工签到退次数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Long sumOnDutyCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.onDutyTimes ) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工请假天数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumOnSelfHolidayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}		
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.onSelfHolidayCount) ) );		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+	
+	/**
+	 * 根据部门列表,统计年月,计算部门内所有员工缺勤天数总和
+	 * @param organizationName
+	 * @param sYear
+	 * @param sMonth
+	 * @return
+	 * @throws Exception
+	 */
+	public Double sumAbsenceDayCountByDepartmentYearAndMonth( List<String> organizationName, String sYear, String sMonth) throws Exception{
+		if( organizationName == null || organizationName.size() == 0 ){
+			logger.error("organizationName is null!");
+			return null;
+		}
+		EntityManager em = this.entityManagerContainer().get( StatisticPersonForMonth.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Double> cq = cb.createQuery(Double.class);
+		Root<StatisticPersonForMonth> root = cq.from( StatisticPersonForMonth.class);		
+		//查询总数
+		cq.select( cb.sum( root.get(StatisticPersonForMonth_.absenceDayCount) ) );	
+		
+		Predicate p = root.get(StatisticPersonForMonth_.organizationName).in( organizationName );
+		
+		if( sYear == null || sYear.isEmpty() ){
+			logger.error("sYear is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticYear), sYear));
+		}
+		
+		if( sMonth == null || sMonth.isEmpty() ){
+			logger.error("sMonth is null!");
+		}else{
+			p = cb.and( p, cb.equal( root.get(StatisticPersonForMonth_.statisticMonth), sMonth));
+		}
+		return em.createQuery(cq.where(p)).getSingleResult();
+	}
+}

+ 50 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/ActionApplication.java

@@ -0,0 +1,50 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import java.util.Set;
+
+import javax.ws.rs.ApplicationPath;
+
+import com.x.attendance.assemble.control.jaxrs.attendanceadmin.AttendanceAdminAction;
+import com.x.attendance.assemble.control.jaxrs.attendanceappealinfo.AttendanceAppealInfoAction;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.AttendanceDetailAction;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.AttendanceDetailMobileAction;
+import com.x.attendance.assemble.control.jaxrs.attendanceemployeeconfig.AttendanceEmployeeConfigAction;
+import com.x.attendance.assemble.control.jaxrs.attendanceimportfileinfo.AttendanceImportFileInfoAction;
+import com.x.attendance.assemble.control.jaxrs.attendanceschedulesetting.AttendanceScheduleSettingAction;
+import com.x.attendance.assemble.control.jaxrs.attendancesetting.AttendanceSettingAction;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.AttendanceStatisticAction;
+import com.x.attendance.assemble.control.jaxrs.attendancestatistic.AttendanceStatisticShowAction;
+import com.x.attendance.assemble.control.jaxrs.attendancestatisticalcycle.AttendanceStatisticalCycleAction;
+import com.x.attendance.assemble.control.jaxrs.attendancestatisticrequirelog.AttendanceStatisticRequireLogAction;
+import com.x.attendance.assemble.control.jaxrs.attendanceworkdayconfig.AttendanceWorkDayConfigAction;
+import com.x.attendance.assemble.control.jaxrs.fileimport.AttendanceDetailFileImportAction;
+import com.x.attendance.assemble.control.jaxrs.selfholiday.AttendanceSelfHolidayAction;
+import com.x.attendance.assemble.control.jaxrs.selfholiday.AttendanceSelfHolidaySimpleAction;
+import com.x.attendance.assemble.control.jaxrs.uuid.UUIDAction;
+import com.x.base.core.application.jaxrs.AbstractActionApplication;
+
+@ApplicationPath("jaxrs")
+public class ActionApplication extends AbstractActionApplication {
+
+	public Set<Class<?>> getClasses() {
+		this.classes.add(UUIDAction.class);
+		this.classes.add(AttendanceDetailAction.class);
+		this.classes.add(AttendanceDetailMobileAction.class);
+		this.classes.add(AttendanceImportFileInfoAction.class);
+		this.classes.add(AttendanceSettingAction.class);
+		this.classes.add(AttendanceWorkDayConfigAction.class);
+		this.classes.add(AttendanceAdminAction.class);
+		this.classes.add(AttendanceScheduleSettingAction.class);
+		this.classes.add(AttendanceSelfHolidayAction.class);
+		this.classes.add(AttendanceSelfHolidaySimpleAction.class);
+		this.classes.add(AttendanceDetailFileImportAction.class);
+		this.classes.add(AttendanceAppealInfoAction.class);
+		this.classes.add(AttendanceStatisticAction.class);
+		this.classes.add(AttendanceStatisticShowAction.class);
+		this.classes.add(AttendanceStatisticalCycleAction.class);
+		this.classes.add(AttendanceEmployeeConfigAction.class);
+		this.classes.add(AttendanceStatisticRequireLogAction.class);
+		return this.classes;
+	}
+
+}

+ 33 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/AttendanceJaxrsFilter.java

@@ -0,0 +1,33 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import javax.servlet.annotation.WebFilter;
+
+import com.x.base.core.application.jaxrs.ManagerUserJaxrsFilter;
+
+/**
+ * web服务过滤器,将指定的URL定义为需要用户认证的服务,如果用户未登录,则无法访问该服务
+ * @author liyi *
+ */
+@WebFilter(urlPatterns = { 
+		"/jaxrs/attendanceadmin/*",
+		"/jaxrs/attendancedetail/*",
+		"/jaxrs/attendancedetail/mobile/*",
+		"/jaxrs/attendancedetailbakup/*",
+		"/jaxrs/attendanceappealInfo/*",
+		"/jaxrs/attendanceimportfileinfo/*",
+		"/jaxrs/attendanceschedulesetting/*",
+		"/jaxrs/attendancesetting/*",
+		"/jaxrs/attendanceworkdayconfig/*",
+		"/jaxrs/attendanceselfholiday/*",
+		"/jaxrs/fileimport/*",
+		"/jaxrs/statistic/*",
+		"/jaxrs/statisticshow/*",
+		"/jaxrs/attendancestatisticalcycle/*",
+		"/jaxrs/attendancestatisticrequirelog/*",
+		"/jaxrs/attendanceemployeeconfig/*",
+		"/jaxrs/uuid/*",
+		"/servlet/*"
+})
+public class AttendanceJaxrsFilter extends ManagerUserJaxrsFilter {
+	
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/AttendanceSimpleJaxrsFilter.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import javax.servlet.annotation.WebFilter;
+
+import com.x.base.core.application.jaxrs.AnonymousCipherManagerUserJaxrsFilter;
+
+/**
+ * web服务过滤器,将指定的URL定义为需要用户认证的服务,如果用户未登录,则无法访问该服务
+ * @author liyi *
+ */
+@WebFilter(urlPatterns = { 
+		"/jaxrs/selfholidaysimple/*"
+})
+public class AttendanceSimpleJaxrsFilter extends AnonymousCipherManagerUserJaxrsFilter {
+	
+}

+ 39 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/DateRecord.java

@@ -0,0 +1,39 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import java.io.Serializable;
+
+import com.x.base.core.gson.GsonPropertyObject;
+
+public class DateRecord extends GsonPropertyObject implements Serializable{
+	private static final long serialVersionUID = 1L;
+	private String year;
+	private String month;
+	private String date;
+	public DateRecord() {
+		
+	}
+	public DateRecord(String recordYearString, String recordMonthString) {
+		this.year = recordYearString;
+		this.month = recordMonthString;
+	}
+	public String getYear() {
+		return year;
+	}
+	public void setYear(String year) {
+		this.year = year;
+	}
+	public String getMonth() {
+		return month;
+	}
+	public void setMonth(String month) {
+		this.month = month;
+	}
+	public String getDate() {
+		return date;
+	}
+	public void setDate(String date) {
+		this.date = date;
+	}
+	
+	
+}

+ 40 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/WrapOutMessage.java

@@ -0,0 +1,40 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.x.base.core.gson.GsonPropertyObject;
+
+public class WrapOutMessage extends GsonPropertyObject implements Serializable{
+	private static final long serialVersionUID = 1L;
+	
+	private String message;
+	private String status;
+	private String exceptionMessage;
+	private List<DateRecord> dateRecordList;
+	
+	public String getMessage() {
+		return message;
+	}
+	public void setMessage(String message) {
+		this.message = message;
+	}
+	public String getStatus() {
+		return status;
+	}
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	public String getExceptionMessage() {
+		return exceptionMessage;
+	}
+	public void setExceptionMessage(String exceptionMessage) {
+		this.exceptionMessage = exceptionMessage;
+	}
+	public List<DateRecord> getDateRecordList() {
+		return dateRecordList;
+	}
+	public void setDateRecordList(List<DateRecord> dateRecordList) {
+		this.dateRecordList = dateRecordList;
+	}	
+}

+ 210 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/AttendanceAdminAction.java

@@ -0,0 +1,210 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceadmin;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceAdminServiceAdv;
+import com.x.attendance.assemble.control.service.UserManagerService;
+import com.x.attendance.entity.AttendanceAdmin;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.EffectivePerson;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+
+
+@Path("attendanceadmin")
+public class AttendanceAdminAction extends StandardJaxrsAction{
+	
+	private Logger logger = LoggerFactory.getLogger( AttendanceAdminAction.class );
+	private BeanCopyTools<WrapInAttendanceAdmin, AttendanceAdmin> wrapin_copier = BeanCopyToolsBuilder.create( WrapInAttendanceAdmin.class, AttendanceAdmin.class, null, WrapInAttendanceAdmin.Excludes );
+	private BeanCopyTools<AttendanceAdmin, WrapOutAttendanceAdmin> wrapout_copier = BeanCopyToolsBuilder.create( AttendanceAdmin.class, WrapOutAttendanceAdmin.class, null, WrapOutAttendanceAdmin.Excludes);
+	private AttendanceAdminServiceAdv attendanceAdminServiceAdv = new AttendanceAdminServiceAdv();
+	private UserManagerService userManagerService = new UserManagerService();
+	
+	@HttpMethodDescribe(value = "获取所有AttendanceAdmin列表", response = WrapOutAttendanceAdmin.class)
+	@GET
+	@Path("list/all")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listAllAttendanceAdmin( @Context HttpServletRequest request ) {
+		ActionResult<List<WrapOutAttendanceAdmin>> result = new ActionResult<>();
+		List<WrapOutAttendanceAdmin> wraps = null;
+		List<AttendanceAdmin> attendanceAdminList = null;
+		Boolean check = true;
+		if( check ){
+			try {
+				attendanceAdminList = attendanceAdminServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage("系统在获取所有管理员信息时发生异常!");
+				logger.error( "system list all attendance admin info got an exception.", e );
+			}
+		}
+		if( check ){
+			if( attendanceAdminList != null && !attendanceAdminList.isEmpty() ){
+				try {
+					wraps = wrapout_copier.copy( attendanceAdminList );
+					result.setData(wraps);
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage("系统在转换所有管理员信息为输出对象时发生异常!");
+					logger.error( "system copy all attendance admin info to wrap out got an exception.", e );
+				}
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID获取指定的AttendanceAdmin对象.", response = WrapOutAttendanceAdmin.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get( @Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult<WrapOutAttendanceAdmin> result = new ActionResult<>();
+		WrapOutAttendanceAdmin wrap = null;
+		AttendanceAdmin attendanceAdmin = null;
+		Boolean check = true;
+		if( check ){
+			try {
+				attendanceAdmin = attendanceAdminServiceAdv.get( id );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage("系统在根据ID获取管理员信息时发生异常!");
+				logger.error( "system get attendance admin info by id got an exception.", e );
+			}
+		}
+		if( check ){
+			if (attendanceAdmin != null) {
+				try {
+					wrap = wrapout_copier.copy( attendanceAdmin );
+					result.setData(wrap);
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage("系统在转换管理员信息为输出对象时发生异常!");
+					logger.error( "system copy attendance admin info to wrap out got an exception.", e );
+				}
+				
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "新建或者更新AttendanceAdmin对象.", request = WrapInAttendanceAdmin.class, response = WrapOutMessage.class)
+	@POST
+	@Produces( HttpMediaType.APPLICATION_JSON_UTF_8 )
+	@Consumes( MediaType.APPLICATION_JSON )
+	public Response post(@Context HttpServletRequest request, WrapInAttendanceAdmin wrapIn) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		WrapOutMessage wrapOutMessage = new WrapOutMessage();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		AttendanceAdmin attendanceAdmin = null;
+		String companyName = null;
+		Boolean check = true;
+		
+		if( wrapIn == null){
+			check = false;
+			result.error( new Exception("系统未获取到传入的参数,无法继续保存信息!") );
+			result.setUserMessage("系统未获取到传入的参数,无法继续保存信息!");
+			logger.error( "wrapIn object is null." );
+		}		
+		if( check ){
+			if( wrapIn.getOrganizationName() == null  || wrapIn.getOrganizationName().isEmpty() ){
+				try {
+					companyName = userManagerService.getCompanyNameByEmployeeName( currentPerson.getName() );
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage("系统获取登录用户所属公司时发生异常!");
+					logger.error( "system get company name by user name got an exception{'name':'"+ currentPerson.getName() +"'}." );
+				}
+				wrapIn.setOrganizationName( companyName );
+			}
+		}
+		if( check ){
+			try {
+				attendanceAdmin = new AttendanceAdmin();
+				wrapin_copier.copy( wrapIn, attendanceAdmin );
+				if(  wrapIn.getId() != null && !wrapIn.getId().isEmpty() ){
+					attendanceAdmin.setId( wrapIn.getId() );
+				}
+			} catch (Exception e) {
+				check = false;
+				wrapOutMessage.setStatus( "ERROR");
+				wrapOutMessage.setMessage( "系统在COPY传入信息到考勤员对象时发生异常." );
+				wrapOutMessage.setExceptionMessage( e.getMessage() );
+				logger.error( "system copy wrap in to attendance admin object got an exception.", e );
+			}
+		}
+		if( check ){
+			try {
+				attendanceAdmin = attendanceAdminServiceAdv.save( attendanceAdmin );
+				wrapOutMessage.setStatus( "SUCCESS");
+				wrapOutMessage.setMessage( attendanceAdmin.getId() );
+			} catch (Exception e) {
+				check = false;
+				wrapOutMessage.setStatus( "ERROR");
+				wrapOutMessage.setMessage( "保存AttendanceAdmin过程中发生异常." );
+				wrapOutMessage.setExceptionMessage( e.getMessage() );
+				logger.error( "system save attendance admin info got an exception.", e );
+			}
+		}
+		result.setData( wrapOutMessage );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID删除AttendanceAdminAttendanceAdmin对象.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces( HttpMediaType.APPLICATION_JSON_UTF_8 )
+	@Consumes( MediaType.APPLICATION_JSON )
+	public Response delete( @Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		WrapOutMessage wrapOutMessage = new WrapOutMessage();
+		Boolean check = true;
+		
+        if( check ){
+        	if( id == null || id.isEmpty() || "(0)".equals( id )){
+        		check = false;
+        		result.error( new Exception("传入的id为空,或者不合法,无法查询数据。") );
+        	}
+        }
+        if( check ){
+        	try {
+        		attendanceAdminServiceAdv.delete( id );
+    			wrapOutMessage.setStatus("SUCCESS");
+    			wrapOutMessage.setMessage( "成功删除AttendanceAdmin信息。id=" + id );
+    		} catch (Exception e) {
+    			wrapOutMessage.setStatus("ERROR");
+    			wrapOutMessage.setMessage( "删除AttendanceAdmin过程中发生异常。" );
+    			wrapOutMessage.setExceptionMessage( e.getMessage() );
+    			logger.error( "system delete attendance admin info got an exception.", e );
+    		}
+        }
+        result.setData( wrapOutMessage );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 24 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapInAttendanceAdmin.java

@@ -0,0 +1,24 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceadmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAdmin;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAdmin.class)
+public class WrapInAttendanceAdmin extends AttendanceAdmin {
+	private static final long serialVersionUID = -5076990764713538973L;
+	public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodifies);
+
+	private String identity = null;
+
+	public String getIdentity() {
+		return identity;
+	}
+
+	public void setIdentity(String identity) {
+		this.identity = identity;
+	}
+}

+ 33 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapInFilter.java

@@ -0,0 +1,33 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceadmin;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceSetting;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceSetting.class)
+public class WrapInFilter extends GsonPropertyObject {
+
+	private List<NameValueCountPair> appIdList;
+
+	private String key;	
+
+	public List<NameValueCountPair> getAppIdList() {
+		return appIdList;
+	}
+
+	public void setAppIdList(List<NameValueCountPair> appIdList) {
+		this.appIdList = appIdList;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceadmin/WrapOutAttendanceAdmin.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceadmin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAdmin;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAdmin.class )
+public class WrapOutAttendanceAdmin extends AttendanceAdmin  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+}

+ 558 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/AttendanceAppealInfoAction.java

@@ -0,0 +1,558 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceAppealInfoServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceDetailServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceNoticeService;
+import com.x.attendance.assemble.control.service.UserManagerService;
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.EffectivePerson;
+import com.x.base.core.http.HttpAttribute;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+import com.x.organization.core.express.wrap.WrapDepartment;
+import com.x.organization.core.express.wrap.WrapPerson;
+
+@Path("attendanceappealInfo")
+public class AttendanceAppealInfoAction extends StandardJaxrsAction {
+
+	private Logger logger = LoggerFactory.getLogger( AttendanceAppealInfoAction.class );
+	private BeanCopyTools<AttendanceAppealInfo, WrapOutAttendanceAppealInfo> wrapout_copier = BeanCopyToolsBuilder.create(AttendanceAppealInfo.class, WrapOutAttendanceAppealInfo.class, null, WrapOutAttendanceAppealInfo.Excludes);
+	private AttendanceAppealInfoServiceAdv attendanceAppealInfoServiceAdv = new AttendanceAppealInfoServiceAdv();
+	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
+	private UserManagerService userManagerService = new UserManagerService();
+	private AttendanceNoticeService attendanceNoticeService = new AttendanceNoticeService();
+	
+	@HttpMethodDescribe(value = "根据ID获取AttendanceAppealInfo对象.", response = WrapOutAttendanceAppealInfo.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutAttendanceAppealInfo> result = new ActionResult<>();
+		WrapOutAttendanceAppealInfo wrap = null;
+		AttendanceAppealInfo attendanceAppealInfo = null;
+        Boolean check = true;	
+        if( check ){
+        	if( id == null || id.isEmpty() || "(0)".equals( id )){
+        		check = false;
+        		result.error( new Exception("传入的id为空,或者不合法,无法查询数据。") );
+        	}
+        }
+        if( check ){
+        	try {
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get( id );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在根据Id查询申诉信息时发生异常!" );
+				logger.error( "system get appeal info by id got an exception.", e );
+			}
+        }
+        if( check ){
+        	if( attendanceAppealInfo != null ){
+        		try {
+					wrap = wrapout_copier.copy( attendanceAppealInfo );
+					result.setData(wrap);
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage( "系统转换申诉对象为输出格式时发生异常!" );
+					logger.error( "system copy appeal info to wrap out got an exception.", e );
+				}
+        	}
+        }
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "根据ID删除AttendanceAppealInfo申诉信息对象.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response delete(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		Boolean check = true;
+		
+        if( check ){
+        	if( id == null || id.isEmpty() || "(0)".equals( id )){
+        		check = false;
+        		result.error( new Exception("传入的id为空,或者不合法,无法查询数据。") );
+        	}
+        }		
+		if( check ){
+			try {
+				attendanceAppealInfoServiceAdv.delete( id );
+				result.setUserMessage( "成功删除申诉信息信息。id=" + id );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "删除申诉信息过程中发生异常!" );
+				logger.error( "system delete appeal info by id got an exception.", e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	/**
+	 * 对某条打卡记录进行申诉
+	 * 
+	 * @param request
+	 * @param id
+	 * @param wrapIn
+	 * @return
+	 */
+	@HttpMethodDescribe(value = "对某条打卡记录进行申诉", request = WrapInAttendanceAppealInfo.class, response = WrapOutMessage.class)
+	@PUT
+	@Path("appeal/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response appealAttendanceDetail(@Context HttpServletRequest request, @PathParam("id") String id, WrapInAttendanceAppealInfo wrapIn) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		WrapOutMessage wrapOutMessage = new WrapOutMessage();
+		DateOperation dateOperation = new DateOperation();
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		AttendanceDetail attendanceDetail = null;
+		WrapDepartment department = null;
+		WrapPerson person = null;
+		Boolean check = true;
+		
+		if( check ){
+			try {
+				attendanceDetail = attendanceDetailServiceAdv.get( id );
+			} catch (Exception e) {
+				check = false;
+				logger.error("system get attendance detail with id got an exception.", e );
+				result.error( e );
+				result.setUserMessage( "系统根据ID查询打卡明细时发生异常。" );
+			}
+		}		
+		if( check ){
+			if (attendanceDetail != null) {
+				//利用打卡记录中的信息,创建一个申诉信息记录
+				//申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过!
+				attendanceAppealInfo = new AttendanceAppealInfo();
+				attendanceAppealInfo.setId(id);
+				attendanceAppealInfo.setDetailId(id);
+				attendanceAppealInfo.setRecordDate( attendanceDetail.getRecordDate() );
+				attendanceAppealInfo.setRecordDateString( attendanceDetail.getRecordDateString() );
+				attendanceAppealInfo.setYearString( attendanceDetail.getCycleYear() );
+				attendanceAppealInfo.setMonthString( attendanceDetail.getCycleMonth() );
+				attendanceAppealInfo.setEmpName( attendanceDetail.getEmpName() );
+				attendanceAppealInfo.setDepartmentName( attendanceDetail.getDepartmentName() );
+				attendanceAppealInfo.setCompanyName( attendanceDetail.getCompanyName() );
+				attendanceAppealInfo.setAppealDescription( wrapIn.getAppealDescription() );
+				attendanceAppealInfo.setAppealReason( wrapIn.getAppealReason() );
+				attendanceAppealInfo.setReason( wrapIn.getReason() );
+				attendanceAppealInfo.setAddress( wrapIn.getAddress() );
+				attendanceAppealInfo.setSelfHolidayType( wrapIn.getSelfHolidayType() );
+				attendanceAppealInfo.setAppealDateString( dateOperation.getNowDateTime() );
+				attendanceAppealInfo.setProcessPerson1( wrapIn.getProcessPerson1() );
+				attendanceAppealInfo.setProcessPerson2( wrapIn.getProcessPerson2() );
+				attendanceAppealInfo.setStartTime( wrapIn.getStartTime() );
+				attendanceAppealInfo.setEndTime( wrapIn.getEndTime() );	
+				// 将第一个处理人设置为当前处理人
+				attendanceAppealInfo.setCurrentProcessor( attendanceAppealInfo.getProcessPerson1() );
+			}else{// 打卡记录不存在
+				check = false;
+				result.error( new Exception("打卡信息不存在,无法继续进行申诉") );
+				result.setUserMessage( "打卡信息不存在,无法继续进行申诉!" );
+				logger.error( "attendanceDetailInfo{'id':'" + id + "'} not exists, system can not appeal attendance detail." );
+			}
+		}
+		if( check ){
+			if( attendanceAppealInfo != null ){
+				//wrapIn.getProcessPerson1() 有可能是姓名,有可能是身份,如果是身份,那么直接根据身份来确定部门
+				//如果是人员姓名,那么需要取根据姓名查询到的第一个部门的信息
+				if (wrapIn.getProcessPerson1() != null && !wrapIn.getProcessPerson1().isEmpty()) {
+					//先根据人员姓名获取一次,如果传入的是身份,则无法获取到部门信息,也可能发生异常
+					try {
+						department = userManagerService.getDepartmentByEmployeeName( wrapIn.getProcessPerson1() );
+						if( department != null ){
+							attendanceAppealInfo.setProcessPersonDepartment1( department.getName() );
+							attendanceAppealInfo.setProcessPersonCompany1( department.getCompany() );
+						}
+					} catch (Exception e) {
+						department = null;
+					}
+					if( department == null ){//再根据人员身份获取一次
+						try {
+							department = userManagerService.getDepartmentByIdentity( wrapIn.getProcessPerson1() );
+							if( department != null ){
+								person = userManagerService.getPersonByIdentity( wrapIn.getProcessPerson1() );
+								if( person != null ){
+									attendanceAppealInfo.setProcessPerson1( person.getName() );
+									attendanceAppealInfo.setProcessPersonDepartment1( department.getName() );
+									attendanceAppealInfo.setProcessPersonCompany1( department.getCompany() );
+								}else{
+									check = false;
+									result.error( new Exception("系统无法根据员工身份查询到审核人信息!身份:" + wrapIn.getProcessPerson1() ) );
+									result.setUserMessage( "系统无法根据员工身份查询到审核人信息!" );
+									logger.error("system can not find any person by employee identity for processor1:" + wrapIn.getProcessPerson1() );
+								}
+							}else{
+								check = false;
+								result.error( new Exception("系统无法根据员工姓名以及身份查询到部门信息,请检查该审核人的部门信息!KEY:"+ wrapIn.getProcessPerson1() ) );
+								result.setUserMessage( "系统无法根据员工姓名以及身份查询到部门信息,请检查该审核人的部门信息!" );
+								logger.error("system can not find any department by employee name for processor1:" + wrapIn.getProcessPerson1() );
+							}
+						} catch (Exception e) {
+							check = false;
+							result.error( e );
+							result.setUserMessage( "系统根据员工姓名查询部门信息时发生异常!" );
+							logger.error("system query department by employee name got an exception", e );
+						}
+					}
+				}
+			}
+		}
+		if( check ){
+			if( attendanceAppealInfo != null ){
+				//wrapIn.getProcessPerson2() 有可能是姓名,有可能是身份,如果是身份,那么直接根据身份来确定部门
+				//如果是人员姓名,那么需要取根据姓名查询到的第一个部门的信息
+				if ( wrapIn.getProcessPerson2() != null && !wrapIn.getProcessPerson2().isEmpty() ) {
+					//先根据人员姓名获取一次,如果传入的是身份,则无法获取到部门信息,也可能发生异常
+					try {
+						department = userManagerService.getDepartmentByEmployeeName( wrapIn.getProcessPerson2() );
+						if( department != null ){
+							attendanceAppealInfo.setProcessPersonDepartment2( department.getName() );
+							attendanceAppealInfo.setProcessPersonCompany2( department.getCompany() );
+						}
+					} catch (Exception e) {
+						department = null;
+					}
+					if( department == null ){//再根据人员身份获取一次
+						try {
+							department = userManagerService.getDepartmentByIdentity( wrapIn.getProcessPerson2() );
+							if( department != null ){
+								person = userManagerService.getPersonByIdentity( wrapIn.getProcessPerson2() );
+								if( person != null ){
+									attendanceAppealInfo.setProcessPerson2( person.getName() );
+									attendanceAppealInfo.setProcessPersonDepartment2( department.getName() );
+									attendanceAppealInfo.setProcessPersonCompany2( department.getCompany() );
+								}else{
+									check = false;
+									result.error( new Exception("系统无法根据员工身份查询到人员信息!" ) );
+									result.setUserMessage( "系统无法根据员工身份查询到人员信息!" );
+									logger.error("system can not find any department by employee identity for processor2:" + wrapIn.getProcessPerson2() );
+								}
+							}else{
+								check = false;
+								result.error( new Exception("系统无法根据员工姓名查询到部门信息,请检查该员工的部门信息!" ) );
+								result.setUserMessage( "系统无法根据员工姓名查询到部门信息,请检查该员工的部门信息!" );
+								logger.error("system can not find any department by employee name for processor2:" + wrapIn.getProcessPerson2() );
+							}
+						} catch (Exception e) {
+							check = false;
+							result.error( e );
+							result.setUserMessage( "系统根据员工姓名查询部门信息时发生异常!" );
+							logger.error("system query department by employee name got an exception", e );
+						}
+					}
+				}	
+			}
+		}
+		if( check ){
+			try {
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.saveNewAppeal( attendanceAppealInfo );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在保存申诉信息时发生异常!" );
+				logger.error("system save appeal info got an exception", e );
+			}
+		}
+		if( check ){
+			//填充申诉信息内容 - 申诉信息成功生成.尝试向当前处理人[" + wrapIn.getProcessPerson1() + "]发送消息通知......
+			try {
+				attendanceNoticeService.notifyAttendanceAppealProcessness1Message( attendanceAppealInfo);
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "申诉信息提交成功,向申诉当前处理人发送通知消息发生异常!" );
+				logger.error("system send notice to current processor got an exception.name:" + wrapIn.getProcessPerson1(), e );
+			}
+		}
+		result.setData( wrapOutMessage );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "审核人处理申诉记录", request = WrapInAttendanceAppealInfo.class, response = WrapOutMessage.class)
+	@PUT
+	@Path("process/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response firstProcessAttendanceAppeal( @Context HttpServletRequest request, @PathParam("id") String id,
+			WrapInAttendanceAppealInfo wrapIn ) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		EffectivePerson currentPerson = this.effectivePerson( request );
+		WrapDepartment department = null;
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		String departmentName = null, companyName = null;
+		Boolean check = true;
+		
+		if( check ){
+			try{
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get( id );
+				if( attendanceAppealInfo == null ){
+					check = false;
+					result.error( new Exception( "申诉信息不存在,申诉处理不成功!" ) );
+					result.setUserMessage( "申诉信息不存在,申诉处理不成功!" );
+					logger.error("attendanceAppealInfo{'id':'" + id + "'} not exists, system can not process appeal info." );
+				}
+			} catch ( Exception e ) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在根据ID查询申诉信息对象时发生异常!" );
+				logger.error("system get appeal info with id got an exception.id:" + id, e );
+			}
+		}
+		if( check ){
+			try{
+				department = userManagerService.getDepartmentByEmployeeName( currentPerson.getName() );
+				if (department != null) {
+					departmentName = department.getName();
+					companyName = department.getCompany();
+				}else{
+					check = false;
+					result.error( new Exception( "抱歉,未能在系统中查询到您所在的部门信息,申诉信息暂时无法处理,请联系管理员。") );
+					result.setUserMessage( "抱歉,未能在系统中查询到您所在的部门信息,申诉信息暂时无法处理,请联系管理员。" );
+				}
+			}catch( Exception e ){
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在根据登录用户姓名查询用户所在的部门时发生异常!" );
+				logger.error("system get department with user name got an exception.id:" + id, e );
+			}
+		}
+		if( check ){
+			try{
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.firstProcessAttendanceAppeal(
+						id, departmentName, companyName, currentPerson.getName(), //processorName
+						new Date(), //processTime
+						wrapIn.getOpinion1(),  //opinion
+						wrapIn.getStatus() //status审批状态:0-待处理,1-审批通过,-1-审批不能过,2-需要下一次审批
+				);
+				result.setUserMessage( "申诉信息审核处理成功!" );
+			} catch ( Exception e ) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在更新申诉处理信息对象时发生异常!" );
+				logger.error("system update appeal first process info got an exception.id:" + id, e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "复核人处理申诉记录", request = WrapInAttendanceAppealInfo.class, response = WrapOutMessage.class)
+	@PUT
+	@Path("process2/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response secondProcessAttendanceAppeal( @Context HttpServletRequest request, @PathParam("id") String id,
+			WrapInAttendanceAppealInfo wrapIn) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		WrapDepartment department = null;
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		String departmentName = null, companyName = null;
+		Boolean check = true;
+		
+		if( check ){
+			try{
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get( id );
+				if( attendanceAppealInfo == null ){
+					check = false;
+					result.error( new Exception( "申诉信息不存在,申诉处理不成功!" ) );
+					result.setUserMessage( "申诉信息不存在,申诉处理不成功!" );
+					logger.error("attendanceAppealInfo{'id':'" + id + "'} not exists, system can not process appeal info." );
+				}
+			} catch ( Exception e ) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在根据ID查询申诉信息对象时发生异常!" );
+				logger.error("system get appeal info with id got an exception.id:" + id, e );
+			}
+		}
+		if( check ){
+			try{
+				department = userManagerService.getDepartmentByEmployeeName( currentPerson.getName() );
+				if (department != null) {
+					departmentName = department.getName();
+					companyName = department.getCompany();
+				}else{
+					check = false;
+					result.error( new Exception( "抱歉,未能在系统中查询到您所在的部门信息,申诉信息暂时无法处理,请联系管理员。") );
+					result.setUserMessage( "抱歉,未能在系统中查询到您所在的部门信息,申诉信息暂时无法处理,请联系管理员。" );
+				}
+			}catch( Exception e ){
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在根据登录用户姓名查询用户所在的部门时发生异常!" );
+				logger.error("system get department with user name got an exception.id:" + id, e );
+			}
+		}
+		if( check ){
+			try{
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.secondProcessAttendanceAppeal(
+						id, departmentName, companyName, currentPerson.getName(), //processorName
+						new Date(), //processTime
+						wrapIn.getOpinion2(),  //opinion
+						wrapIn.getStatus() //status
+				);
+				result.setUserMessage( "申诉信息复核处理成功!" );
+			} catch ( Exception e ) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在更新申诉处理信息对象时发生异常!" );
+				logger.error("system update appeal first process info got an exception.id:" + id, e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "列示根据过滤条件的AttendanceAppealInfo,下一页.", response = WrapOutAttendanceAppealInfo.class, request = WrapInFilterAppeal.class)
+	@PUT
+	@Path("filter/list/{id}/next/{count}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listNextWithFilter(@Context HttpServletRequest request, @PathParam("id") String id,
+			@PathParam("count") Integer count, WrapInFilterAppeal wrapIn) {
+		ActionResult<List<WrapOutAttendanceAppealInfo>> result = new ActionResult<>();
+		List<WrapOutAttendanceAppealInfo> wraps = null;
+		Long total = 0L;
+		List<AttendanceAppealInfo> detailList = null;
+		
+		try {
+			EntityManagerContainer emc = EntityManagerContainerFactory.instance().create();
+			Business business = new Business(emc);
+
+			// 查询出ID对应的记录的sequence
+			Object sequence = null;
+			if (id == null || "(0)".equals(id) || id.isEmpty()) {
+				logger.debug("第一页查询,没有id传入");
+			} else {
+				if (!StringUtils.equalsIgnoreCase(id, HttpAttribute.x_empty_symbol)) {
+					sequence = PropertyUtils.getProperty( emc.find(id, AttendanceAppealInfo.class, ExceptionWhen.not_found), "sequence");
+				}
+			}
+			// 从数据库中查询符合条件的一页数据对象
+			detailList = business.getAttendanceAppealInfoFactory().listIdsNextWithFilter(id, count, sequence, wrapIn);
+			// 从数据库中查询符合条件的对象总数
+			total = business.getAttendanceAppealInfoFactory().getCountWithFilter(wrapIn);
+			// 将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象
+			wraps = wrapout_copier.copy(detailList);
+
+			// 对查询的列表进行排序
+			result.setCount(total);
+			result.setData(wraps);
+
+		} catch (Throwable th) {
+			th.printStackTrace();
+			result.error(th);
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "列示根据过滤条件的AttendanceAppealInfo,上一页.", response = WrapOutAttendanceAppealInfo.class, request = WrapInFilterAppeal.class)
+	@PUT
+	@Path("filter/list/{id}/prev/{count}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listPrevWithFilter(@Context HttpServletRequest request, @PathParam("id") String id,
+			@PathParam("count") Integer count, WrapInFilterAppeal wrapIn) {
+		ActionResult<List<WrapOutAttendanceAppealInfo>> result = new ActionResult<>();
+		List<WrapOutAttendanceAppealInfo> wraps = null;
+		Long total = 0L;
+		List<AttendanceAppealInfo> detailList = null;
+		try {
+			EntityManagerContainer emc = EntityManagerContainerFactory.instance().create();
+			Business business = new Business(emc);
+
+			// 查询出ID对应的记录的sequence
+			Object sequence = null;
+			logger.debug("传入的ID=" + id);
+			if (id == null || "(0)".equals(id) || id.isEmpty()) {
+				logger.debug("第一页查询,没有id传入");
+			} else {
+				if (!StringUtils.equalsIgnoreCase(id, HttpAttribute.x_empty_symbol)) {
+					sequence = PropertyUtils
+							.getProperty(emc.find(id, AttendanceAppealInfo.class, ExceptionWhen.not_found), "sequence");
+				}
+			}
+			// 从数据库中查询符合条件的一页数据对象
+			detailList = business.getAttendanceAppealInfoFactory().listIdsPrevWithFilter(id, count, sequence, wrapIn);
+			// 从数据库中查询符合条件的对象总数
+			total = business.getAttendanceAppealInfoFactory().getCountWithFilter(wrapIn);
+			// 将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象
+			wraps = wrapout_copier.copy(detailList);
+			result.setCount(total);
+			result.setData(wraps);
+		} catch (Throwable th) {
+			th.printStackTrace();
+			result.error(th);
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "将指定的申诉信息记录归档", response = WrapOutMessage.class)
+	@GET
+	@Path("archive/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response archiveAttendanceAppeal(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		
+		if ( id != null && !id.isEmpty() ) { //归档指定的考勤申诉记录
+			try{
+				attendanceAppealInfoServiceAdv.archive( id );
+				result.setUserMessage( "对指定申诉信息进行归档操作成功完成!" );
+			}catch( Exception e ){
+				result.error( e );
+				result.setUserMessage( "系统在根据ID对申诉信息进行归档操作时发生异常!" );
+				logger.error("system archive appeal info with id{'"+ id +"'} got an exception.id:" + id, e );
+			}
+		}else{ //归档所有的考勤申诉记录
+			try{
+				attendanceAppealInfoServiceAdv.archiveAll();
+				result.setUserMessage( "对所有申诉信息进行归档操作成功完成!" );
+			}catch( Exception e ){
+				result.error( e );
+				result.setUserMessage( "系统在对所有申诉信息进行归档操作时发生异常!" );
+				logger.error("system archive all appeal info got an exception.id:" + id, e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 24 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInAttendanceAppealInfo.java

@@ -0,0 +1,24 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAppealInfo.class)
+public class WrapInAttendanceAppealInfo extends AttendanceAppealInfo {
+	private static final long serialVersionUID = -5076990764713538973L;
+	public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodifies);
+
+	private String identity = null;
+
+	public String getIdentity() {
+		return identity;
+	}
+
+	public void setIdentity(String identity) {
+		this.identity = identity;
+	}
+}

+ 43 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInFilter.java

@@ -0,0 +1,43 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAppealInfo.class)
+public class WrapInFilter extends GsonPropertyObject {
+
+	private List<NameValueCountPair> appIdList;
+	
+	private List<NameValueCountPair> orAtrribute;
+
+	private String key;	
+
+	public List<NameValueCountPair> getAppIdList() {
+		return appIdList;
+	}
+
+	public void setAppIdList(List<NameValueCountPair> appIdList) {
+		this.appIdList = appIdList;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public List<NameValueCountPair> getOrAtrribute() {
+		return orAtrribute;
+	}
+
+	public void setOrAtrribute(List<NameValueCountPair> orAtrribute) {
+		this.orAtrribute = orAtrribute;
+	}
+	
+}

+ 123 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapInFilterAppeal.java

@@ -0,0 +1,123 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAppealInfo.class)
+public class WrapInFilterAppeal extends GsonPropertyObject {
+
+	private String detailId;
+	private String empName;	
+	private String companyName;	
+	private String departmentName;
+	private String yearString;
+	private String monthString;
+	private String appealDateString;
+	private String recordDateString;
+	//审批状态:0-待处理,1-审批通过,-1-审批不能过,2-需要下一次审批
+	private int status = 999;
+	private String appealReason;
+	private String processPerson1;
+	private String processPerson2;	
+	private String order = "DESC";
+	private String key;
+	
+	private List<NameValueCountPair> orAtrribute;
+	
+	public String getDetailId() {
+		return detailId;
+	}
+	public void setDetailId(String detailId) {
+		this.detailId = detailId;
+	}
+	public String getEmpName() {
+		return empName;
+	}
+	public void setEmpName(String empName) {
+		this.empName = empName;
+	}
+	public String getCompanyName() {
+		return companyName;
+	}
+	public void setCompanyName(String companyName) {
+		this.companyName = companyName;
+	}
+	public String getDepartmentName() {
+		return departmentName;
+	}
+	public void setDepartmentName(String departmentName) {
+		this.departmentName = departmentName;
+	}
+	public String getYearString() {
+		return yearString;
+	}
+	public void setYearString(String yearString) {
+		this.yearString = yearString;
+	}
+	public String getMonthString() {
+		return monthString;
+	}
+	public void setMonthString(String monthString) {
+		this.monthString = monthString;
+	}
+	public String getAppealDateString() {
+		return appealDateString;
+	}
+	public void setAppealDateString(String appealDateString) {
+		this.appealDateString = appealDateString;
+	}
+	public String getRecordDateString() {
+		return recordDateString;
+	}
+	public void setRecordDateString(String recordDateString) {
+		this.recordDateString = recordDateString;
+	}
+	public int getStatus() {
+		return status;
+	}
+	public void setStatus(int status) {
+		this.status = status;
+	}
+	public String getAppealReason() {
+		return appealReason;
+	}
+	public void setAppealReason(String appealReason) {
+		this.appealReason = appealReason;
+	}
+	public String getProcessPerson1() {
+		return processPerson1;
+	}
+	public void setProcessPerson1(String processPerson1) {
+		this.processPerson1 = processPerson1;
+	}
+	public String getProcessPerson2() {
+		return processPerson2;
+	}
+	public void setProcessPerson2(String processPerson2) {
+		this.processPerson2 = processPerson2;
+	}
+	public String getOrder() {
+		return order;
+	}
+	public void setOrder(String order) {
+		this.order = order;
+	}
+	public String getKey() {
+		return key;
+	}
+	public void setKey(String key) {
+		this.key = key;
+	}
+	public List<NameValueCountPair> getOrAtrribute() {
+		return orAtrribute;
+	}
+	public void setOrAtrribute(List<NameValueCountPair> orAtrribute) {
+		this.orAtrribute = orAtrribute;
+	}
+
+	
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/WrapOutAttendanceAppealInfo.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceAppealInfo.class )
+public class WrapOutAttendanceAppealInfo extends AttendanceAppealInfo  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+}

+ 18 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceCycles.java

@@ -0,0 +1,18 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+public class AttendanceCycles {
+	private String cycleYear;
+	private String cycleMonth;
+	public String getCycleYear() {
+		return cycleYear;
+	}
+	public void setCycleYear(String cycleYear) {
+		this.cycleYear = cycleYear;
+	}
+	public String getCycleMonth() {
+		return cycleMonth;
+	}
+	public void setCycleMonth(String cycleMonth) {
+		this.cycleMonth = cycleMonth;
+	}
+}

+ 1164 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceDetailAction.java

@@ -0,0 +1,1164 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceDetailAnalyseServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceDetailServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceEmployeeConfigServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceStatisticalCycleServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceWorkDayConfigServiceAdv;
+import com.x.attendance.assemble.control.service.UserManagerService;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.attendance.entity.AttendanceStatisticalCycle;
+import com.x.attendance.entity.AttendanceWorkDayConfig;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.exception.ExceptionWhen;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.EffectivePerson;
+import com.x.base.core.http.HttpAttribute;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.WrapOutId;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+import com.x.organization.core.express.wrap.WrapCompany;
+import com.x.organization.core.express.wrap.WrapDepartment;
+
+
+@Path("attendancedetail")
+public class AttendanceDetailAction extends StandardJaxrsAction{
+	
+	private Logger logger = LoggerFactory.getLogger( AttendanceDetailAction.class );
+	private UserManagerService userManagerService = new UserManagerService();
+	private AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
+	private AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+	private AttendanceStatisticalCycleServiceAdv attendanceStatisticCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
+	private AttendanceEmployeeConfigServiceAdv attendanceEmployeeConfigServiceAdv = new AttendanceEmployeeConfigServiceAdv();
+	private BeanCopyTools<AttendanceDetail, WrapOutAttendanceDetail> wrapout_copier = BeanCopyToolsBuilder.create( AttendanceDetail.class, WrapOutAttendanceDetail.class, null, WrapOutAttendanceDetail.Excludes);
+
+	@HttpMethodDescribe(value = "根据ID获取AttendanceDetail对象.", response = WrapOutAttendanceDetail.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get(@Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult<WrapOutAttendanceDetail> result = new ActionResult<>();
+		WrapOutAttendanceDetail wrap = null;
+		AttendanceDetail attendanceDetail = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null ){
+				check = false;
+				result.error( new Exception("需要查询的打卡详细记录ID为空,无法进行数据查询。") );
+				result.setUserMessage( "需要查询的打卡详细记录ID为空,无法进行数据查询。" );
+			}
+		}		
+		if( check ){
+			try {
+				attendanceDetail = attendanceDetailServiceAdv.get( id );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在根据用户传入的ID查询打卡详细信息记录时发生异常。") );
+				result.setUserMessage( "系统在根据用户传入的ID查询打卡详细信息记录时发生异常。" );
+				logger.error( "system get attendance detail info with id:"+ id +" got an exception.", e );
+			}
+		}		
+		if( check ){
+			if( attendanceDetail == null ){
+				check = false;
+				result.error( new Exception("系统在根据用户传入的ID未能查询到任何打卡详细信息记录常。" ) );
+				result.setUserMessage( "系统在根据用户传入的ID未能查询到任何打卡详细信息记录常。" );
+			}
+		}		
+		if( check ){
+			try {
+				wrap = wrapout_copier.copy( attendanceDetail );
+				result.setData(wrap);
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在转换数据库对象attendanceDetail为输出对象时发生异常。") );
+				result.setUserMessage( "系统在转换数据库对象为输出对象时发生异常。" );
+				logger.error( "system copy attendanceDetail to wrap got an exception.", e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "获取数据库中指定导入文件名称的数据列表", response = WrapOutAttendanceDetail.class )
+	@GET
+	@Path("list/{file_id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listAttendanceDetailByBatchName( @Context HttpServletRequest request, @PathParam("file_id") String file_id ) {
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		List<String> ids = null;
+		List<AttendanceDetail> attendanceDetailList = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( file_id == null ){
+				check = false;
+				result.error( new Exception("需要查询的打卡导入文件ID为空,无法进行详细数据查询。") );
+				result.setUserMessage( "需要查询的打卡导入文件ID为空,无法进行详细数据查询。" );
+			}
+		}
+		if( check ){
+			try {
+				ids = attendanceDetailServiceAdv.listByBatchName( file_id );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统根据批次号/导入文件ID查询打卡详细信息ID列表时发生异常。") );
+				result.setUserMessage( "系统根据批次号/导入文件ID查询打卡详细信息ID列表时发生异常。" );
+				logger.error( "system list detail with batch id/import file id{'id':'"+ file_id +"'} got an exception.", e );
+			}
+		}
+		
+		if( check ){
+			if( ids != null && !ids.isEmpty() ){
+				try {
+					attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception("系统根据ID列表查询打卡详细信息列表时发生异常。") );
+					result.setUserMessage( "系统根据ID列表查询打卡详细信息列表时发生异常。" );
+					logger.error( "system list detail with {'ids':'"+ ids +"'} got an exception.", e );
+				}
+			}
+		}
+		if( check ){
+			if( attendanceDetailList != null && !attendanceDetailList.isEmpty() ){
+				try {
+					wraps = wrapout_copier.copy( attendanceDetailList );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception("系统在转换数据库对象attendanceDetailList为输出对象时发生异常。") );
+					result.setUserMessage( "系统在转换数据库对象为输出对象时发生异常。" );
+					logger.error( "system copy attendanceDetailList to wrap got an exception.", e );
+				}
+			}
+		}
+		result.setData( wraps );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "获取指定年月的打卡数据列表", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listAttendanceDetail( @Context HttpServletRequest request, WrapInFilter wrapIn ) {		
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;		
+		String q_empName = null;
+		String q_year = null;
+		String q_month = null;
+		List<String> ids = null;
+		List<AttendanceDetail> attendanceDetailList = null;
+		Date maxRecordDate = null;
+		String maxRecordDateString = null;
+		DateOperation dateOperation = new DateOperation();
+		Boolean check = true;
+		
+		if( check ){
+			if( wrapIn == null ){
+				wrapIn = new WrapInFilter();
+			}
+			q_empName = wrapIn.getQ_empName();
+			q_year = wrapIn.getQ_year();
+			q_month = wrapIn.getQ_month();
+		}
+		if( check ){
+			try {
+				maxRecordDateString = attendanceDetailServiceAdv.getMaxRecordDate();
+				maxRecordDate = dateOperation.getDateFromString( maxRecordDateString );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询打卡信息记录最大日期时发生异常!" ) );
+				result.setUserMessage( "系统在查询打卡信息记录最大日期时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}
+		}
+		if( check ){
+			if( q_year == null || q_year.isEmpty() ){
+				q_year = dateOperation.getYear(maxRecordDate);
+			}
+			if( q_month == null || q_month.isEmpty() ){
+				q_month = dateOperation.getMonth(maxRecordDate);
+			}
+		}
+		if( check ){
+			try {
+				ids = attendanceDetailServiceAdv.listUserAttendanceDetailByYearAndMonth( q_empName, q_year, q_month );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据员工姓名,年份月份查询打卡详细信息ID列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据员工姓名,年份月份查询打卡详细信息ID列表时发生异常!" );
+				logger.error( "system query attendance detail ids with empName, year and month got an exception.", e );
+			}
+		}
+		if( check ){
+			if( ids != null && !ids.isEmpty() ){
+				try {
+					attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在根据ID列表查询打卡详细信息列表时发生异常!" ) );
+					result.setUserMessage( "系统在根据ID列表查询打卡详细信息ID列表时发生异常!" );
+					logger.error( "system query attendance detail ids with ids got an exception.", e );
+				}
+			}
+		}
+		if( check ){
+			if( attendanceDetailList != null ){
+				try {
+					wraps = wrapout_copier.copy( attendanceDetailList );
+					result.setData( wraps );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统转换数据库对象列表为输出列表时发生异常!" ) );
+					result.setUserMessage( "系统转换数据库对象列表为输出列表时发生异常!" );
+					logger.error( "system copy attendance detail list to wrap got an exception.", e );
+				}
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "获取用户指定年月的打卡数据列表", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list/user")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listUserAttendanceDetail(@Context HttpServletRequest request, WrapInFilter wrapIn ) {		
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		String q_empName = null;
+		String q_year = null;
+		String q_month = null;
+		String cycleYear = null;
+		String cycleMonth = null;
+		List<String> ids = null;
+		List<AttendanceDetail> attendanceDetailList = null;
+		Date maxRecordDate = null;
+		String maxRecordDateString = null;
+		DateOperation dateOperation = new DateOperation();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		Boolean check = true;
+		
+		if( check ){
+			if( wrapIn == null ){
+				wrapIn = new WrapInFilter();
+			}
+			q_empName = wrapIn.getQ_empName();
+			q_year = wrapIn.getQ_year();
+			q_month = wrapIn.getQ_month();
+			cycleYear = wrapIn.getCycleYear();
+			cycleMonth = wrapIn.getCycleMonth();
+			if( q_empName == null || q_empName.isEmpty() ){
+				q_empName = currentPerson.getName();
+			}
+		}
+		if( check ){
+			try {
+				maxRecordDateString = attendanceDetailServiceAdv.getMaxRecordDate();
+				maxRecordDate = dateOperation.getDateFromString( maxRecordDateString );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询打卡信息记录最大日期时发生异常!" ) );
+				result.setUserMessage( "系统在查询打卡信息记录最大日期时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}
+			//logger.info( ">>>>>>>>>>>>>getmaxrecordDate:" + ( new Date().getTime() -_start.getTime() ) );
+		}
+		if( check ){
+			if( q_year == null || q_year.isEmpty() ){
+				q_year = dateOperation.getYear(maxRecordDate);
+			}
+			if( q_month == null || q_month.isEmpty() ){
+				q_month = dateOperation.getMonth(maxRecordDate);
+			}
+		}
+		if( check ){
+			if( cycleYear != null && cycleMonth != null&& !cycleYear.isEmpty() && !cycleMonth.isEmpty() ){
+				try {
+					ids = attendanceDetailServiceAdv.listUserAttendanceDetailByCycleYearAndMonth( q_empName, cycleYear, cycleMonth );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在根据员工姓名,考勤周期查询员工考勤信息ID列表时发生异常!" ) );
+					result.setUserMessage( "系统在根据员工姓名,考勤周期查询员工考勤信息ID列表时发生异常!" );
+					logger.error( "system query attendance detail with empName, cycleYear and cycleMonth got an exception.", e );
+				}
+				//logger.info( ">>>>>>>>>>>>>listAttendanceDetailIds with cycle:" + ( new Date().getTime() -_start.getTime() ) );
+			}else if( q_year != null && q_month != null && !q_year.isEmpty() && !q_month.isEmpty()){
+				try {
+					ids = attendanceDetailServiceAdv.listUserAttendanceDetailByYearAndMonth( q_empName, q_year, q_month );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在根据员工姓名,考勤周期查询员工考勤信息ID列表时发生异常!" ) );
+					result.setUserMessage( "系统在根据员工姓名,考勤周期查询员工考勤信息ID列表时发生异常!" );
+					logger.error( "system query attendance detail with empName, cycleYear and cycleMonth got an exception.", e );
+				}
+				//logger.info( ">>>>>>>>>>>>>listAttendanceDetailIds:" + ( new Date().getTime() -_start.getTime() ) );
+			}
+		}
+		if( check ){
+			if( ids != null && !ids.isEmpty() ){
+				try {
+					attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在根据ID列表查询员工考勤信息列表时发生异常!" ) );
+					result.setUserMessage( "系统在根据ID列表查询员工考勤信息列表时发生异常!" );
+					logger.error( "system query attendance detail with ids got an exception.", e );
+				}
+			}
+			//logger.info( ">>>>>>>>>>>>>listAttendanceDetail:" + ( new Date().getTime() -_start.getTime() ) );
+		}
+		if( check ){
+			if( attendanceDetailList != null ){
+				try {
+					wraps = wrapout_copier.copy( attendanceDetailList );
+					result.setData( wraps );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统转换数据库对象列表为输出列表时发生异常!" ) );
+					result.setUserMessage( "系统转换数据库对象列表为输出列表时发生异常!" );
+					logger.error( "system copy attendance detail list to wrap got an exception.", e );
+				}	
+			}
+			//logger.info( ">>>>>>>>>>>>>wrapout_copier:" + ( new Date().getTime() -_start.getTime() ) );
+		}
+		//logger.info( ">>>>>>>>>>>>>total time:" + ( new Date().getTime() - start.getTime() ) );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "获取公司指定年月的打卡数据列表", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list/company")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listCompanyAttendanceDetail(@Context HttpServletRequest request, WrapInFilter wrapIn ) {		
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		String q_companyName = null;
+		String q_year = null;
+		String q_month = null;
+		List<String> ids = null;
+		List<String> companyNames = new ArrayList<String>();
+		List<AttendanceDetail> attendanceDetailList = null;
+		Date maxRecordDate = null;
+		String maxRecordDateString = null;
+		DateOperation dateOperation = new DateOperation();
+		Boolean check = true;
+
+		if( check ){
+			if( wrapIn == null ){
+				wrapIn = new WrapInFilter();
+			}
+			q_companyName = wrapIn.getQ_companyName();
+			q_year = wrapIn.getQ_year();
+			q_month = wrapIn.getQ_month();
+		}
+		if( check ){
+			try {
+				maxRecordDateString = attendanceDetailServiceAdv.getMaxRecordDate();
+				maxRecordDate = dateOperation.getDateFromString( maxRecordDateString );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询打卡信息记录最大日期时发生异常!" ) );
+				result.setUserMessage( "系统在查询打卡信息记录最大日期时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}
+		}
+		if( check ){
+			if( q_year == null || q_year.isEmpty() ){
+				q_year = dateOperation.getYear( maxRecordDate );
+			}
+			if( q_month == null || q_month.isEmpty() ){
+				q_month = dateOperation.getMonth( maxRecordDate );
+			}
+		}
+		if( check ){
+			if( q_companyName != null && !q_companyName.isEmpty()){
+				try{
+					companyNames = userManagerService.listSubCompanyNameList( q_companyName );
+				}catch(Exception e){
+					logger.error("系统在根据公司名称获取下级公司的时候发生异常", e);
+				}
+				if( !companyNames.contains( q_companyName )){
+					companyNames.add( q_companyName );
+				}
+			}
+		}
+		if( check ){
+			try {
+				ids = attendanceDetailServiceAdv.listCompanyAttendanceDetailByYearAndMonth( companyNames, q_year, q_month );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据公司名称,打卡年份和打卡月份查询公司员工打卡信息ID列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据公司名称,打卡年份和打卡月份查询公司员工打卡信息ID列表时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}	
+		}
+		if( check ){
+			try {
+				attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据ID列表查询员工考勤信息列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据ID列表查询员工考勤信息列表时发生异常!" );
+				logger.error( "system query attendance detail with ids got an exception.", e );
+			}
+		}
+		if( check ){
+			if( attendanceDetailList != null ){
+				try {
+					wraps = wrapout_copier.copy( attendanceDetailList );
+					result.setData( wraps );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统转换数据库对象列表为输出列表时发生异常!" ) );
+					result.setUserMessage( "系统转换数据库对象列表为输出列表时发生异常!" );
+					logger.error( "system copy attendance detail list to wrap got an exception.", e );
+				}	
+			}
+		}		
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "获取部门指定年月的打卡数据列表", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list/department")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listDepartmentAttendanceDetail(@Context HttpServletRequest request, WrapInFilter wrapIn ) {		
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		String q_departmentName = null;
+		String q_year = null;
+		String q_month = null;
+		List<String> ids = null;
+		List<String> departmentNames = new ArrayList<String>();
+		List<AttendanceDetail> attendanceDetailList = null;
+		Date maxRecordDate = null;
+		String maxRecordDateString = null;
+		DateOperation dateOperation = new DateOperation();
+		Boolean check = true;
+		
+		if( check ){
+			if( wrapIn == null ){
+				wrapIn = new WrapInFilter();
+			}
+			q_departmentName = wrapIn.getQ_companyName();
+			q_year = wrapIn.getQ_year();
+			q_month = wrapIn.getQ_month();
+		}
+		if( check ){
+			try {
+				maxRecordDateString = attendanceDetailServiceAdv.getMaxRecordDate();
+				maxRecordDate = dateOperation.getDateFromString( maxRecordDateString );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询打卡信息记录最大日期时发生异常!" ) );
+				result.setUserMessage( "系统在查询打卡信息记录最大日期时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}
+		}
+		if( check ){
+			if( q_year == null || q_year.isEmpty() ){
+				q_year = dateOperation.getYear( maxRecordDate );
+			}
+			if( q_month == null || q_month.isEmpty() ){
+				q_month = dateOperation.getMonth( maxRecordDate );
+			}
+		}
+		if( check ){
+			if( q_departmentName != null && !q_departmentName.isEmpty()){
+				try{
+					departmentNames = userManagerService.listSubOrganizationNameList( q_departmentName );
+				}catch(Exception e){
+					logger.error("系统在根据公司名称获取下级公司的时候发生异常", e);
+				}
+				if( !departmentNames.contains( q_departmentName )){
+					departmentNames.add( q_departmentName );
+				}
+			}
+		}
+		if( check ){
+			try {
+				ids = attendanceDetailServiceAdv.listDepartmentAttendanceDetailByYearAndMonth( departmentNames, q_year, q_month );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据公司名称,打卡年份和打卡月份查询公司员工打卡信息ID列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据公司名称,打卡年份和打卡月份查询公司员工打卡信息ID列表时发生异常!" );
+				logger.error( "system query attendance detail max record date got an exception.", e );
+			}	
+		}
+		if( check ){
+			try {
+				attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据ID列表查询员工考勤信息列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据ID列表查询员工考勤信息列表时发生异常!" );
+				logger.error( "system query attendance detail with ids got an exception.", e );
+			}
+		}
+		if( check ){
+			if( attendanceDetailList != null ){
+				try {
+					wraps = wrapout_copier.copy( attendanceDetailList );
+					result.setData( wraps );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统转换数据库对象列表为输出列表时发生异常!" ) );
+					result.setUserMessage( "系统转换数据库对象列表为输出列表时发生异常!" );
+					logger.error( "system copy attendance detail list to wrap got an exception.", e );
+				}	
+			}
+		}		
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}	
+	
+	@HttpMethodDescribe(value = "根据周期的年份月份,以及需要考勤人员的名单,检查人员在周期内每天的考核数据是否存在,如果不存在,则进行补齐", response = WrapOutMessage.class )
+	@GET
+	@Path("checkDetailWithPersonByCycle/{cycleYear}/{cycleMonth}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response checkDetailWithPersonByCycle(@Context HttpServletRequest request, @PathParam("cycleYear") String cycleYear , @PathParam("cycleMonth") String cycleMonth ) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		AttendanceStatisticalCycle attendanceStatisticalCycle  = null;		
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> companyAttendanceStatisticalCycleMap = null;
+		List<String> ids = null;
+		List<AttendanceEmployeeConfig> attendanceEmployeeConfigList = null;
+		Boolean check = true;
+		if( check ){
+			if( cycleYear == null || cycleYear.isEmpty() ){
+				check = false;
+				result.error( new Exception( "参数统计周期年份为空,无法继续进行操作!" ) );
+				result.setUserMessage( "参数统计周期年份为空,无法继续进行操作!" );
+			}
+		}
+		if( check ){
+			if( cycleMonth == null || cycleMonth.isEmpty() ){
+				check = false;
+				result.error( new Exception( "参数统计周期月份为空,无法继续进行操作!" ) );
+				result.setUserMessage( "参数统计周期月份为空,无法继续进行操作!" );
+			}
+		}
+		if( check ){
+			try {
+				ids = attendanceEmployeeConfigServiceAdv.listByConfigType( "REQUIRED" );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询需要考勤的人员配置列表时发生异常!" ) );
+				result.setUserMessage( "系统在查询需要考勤的人员配置列表时发生异常!" );
+				logger.error( "system list employee config ids with employee config require type got an exception!", e );
+			}
+		}
+		if( check ){
+			if( ids != null && !ids.isEmpty() ){
+				try {
+					attendanceEmployeeConfigList = attendanceEmployeeConfigServiceAdv.list( ids );
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在查询需要考勤的人员配置列表时发生异常!" ) );
+					result.setUserMessage( "系统在查询需要考勤的人员配置列表时发生异常!" );
+					logger.error( "system list employee config with ids got an exception.", e );
+				}
+			}
+		}
+		if( check && attendanceEmployeeConfigList != null && attendanceEmployeeConfigList.size() > 0){
+			if( check ){
+				try {//查询所有的周期配置,组织成Map
+					companyAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles();
+				} catch (Exception e) {
+					check = false;
+					result.error( new Exception( "系统在查询并且组织所有的统计周期时发生异常!" ) );
+					result.setUserMessage( "系统在查询并且组织所有的统计周期时发生异常!" );
+					logger.error( "system query and compose statistic cycle to map got an exception.", e );
+				}
+			}
+			if( check ){
+				Boolean globalCheck = true;
+				Boolean subCheck = true;
+				for( AttendanceEmployeeConfig attendanceEmployeeConfig : attendanceEmployeeConfigList ){
+					subCheck = true;
+					try {
+						attendanceEmployeeConfig = attendanceEmployeeConfigServiceAdv.checkAttendanceEmployeeConfig( attendanceEmployeeConfig );
+					} catch (Exception e ) {
+						globalCheck = subCheck = false;
+						result.error( new Exception( "系统检查需要考勤员工配置信息时发生异常!" ) );
+						result.setUserMessage( "系统检查需要考勤员工配置信息时发生异常!" );
+						logger.error( "system check attendance employee config info got an exception.", e );
+					}
+					if( subCheck ){
+						try {//根据公司部门,年月获取到一个适合的统计周期,如果没有则新建一个新的配置
+							attendanceStatisticalCycle = attendanceStatisticCycleServiceAdv.getAttendanceDetailStatisticCycle( attendanceEmployeeConfig.getCompanyName(), attendanceEmployeeConfig.getOrganizationName(), cycleYear, cycleMonth, companyAttendanceStatisticalCycleMap );
+						} catch (Exception e) {
+							globalCheck = subCheck = false;
+							result.error( new Exception( "系统在根据员工的公司和部门查询指定的统计周期时发生异常!" ) );
+							result.setUserMessage( "系统在根据员工的公司和部门查询指定的统计周期时发生异常!" );
+							logger.error( "system query statistic cycle with department, company and year, month got an exception.", e );
+						}
+					}
+					if( subCheck ){
+						if( attendanceStatisticalCycle != null ){
+							try {
+								attendanceDetailServiceAdv.checkAndReplenish( attendanceStatisticalCycle.getCycleStartDate(), attendanceStatisticalCycle.getCycleEndDate(), attendanceEmployeeConfig );
+							} catch (Exception e) {
+								globalCheck = subCheck = false;
+								result.error( new Exception( "系统根据时间列表核对和补充员工打卡信息时发生异常!" ) );
+								result.setUserMessage( "系统根据时间列表核对和补充员工打卡信息时发生异常!" );
+								logger.error( "system check and replenish attendance detail info got an exception.", e );
+							}
+						}
+					}
+				}
+				if( globalCheck ){
+					result.setUserMessage( "系统根据时间列表核对和补充员工打卡信息成功完成!" );
+				}else{
+					result.warn( "系统根据时间列表核对和补充员工打卡信息成完成,但部分数据未补充录成功。" );
+					result.setUserMessage( "系统根据时间列表核对和补充员工打卡信息成完成,但部分数据未补充录成功!" );
+				}
+			}
+		}
+		logger.info( "系统对统计周期["+cycleYear+"-"+cycleMonth+"]的打卡数据核对完成!");
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "分析打卡数据", response = WrapOutMessage.class)
+	@GET
+	@Path("analyse/{startDate}/{endDate}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response analyseAttendanceDetails(@Context HttpServletRequest request, @PathParam("startDate") String startDate, @PathParam("endDate") String endDate ) {
+		ActionResult< WrapOutMessage > result = new ActionResult<>();
+		List<String> ids = null;
+		List<AttendanceDetail> attendanceDetailList = null;
+		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> companyAttendanceStatisticalCycleMap = null;
+		Boolean check = true;
+		
+		if( check ){
+			try {
+				ids = attendanceDetailServiceAdv.getAllAnalysenessDetails( startDate, endDate );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统根据开始时间和结束时间查询需要分析的员工打卡信息ID列表时发生异常!" ) );
+				result.setUserMessage( "系统根据开始时间和结束时间查询需要分析的员工打卡信息ID列表时发生异常!" );
+				logger.error( "system query all analyseness detail info with start and end date{'startDate':'"+ startDate +"','endDate':'"+ endDate +"'} got an exception.", e );
+			}
+		}
+		if( check && ids != null && !ids.isEmpty()  ){
+			try {
+				attendanceDetailList = attendanceDetailServiceAdv.list( ids );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据ID列表查询员工考勤信息列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据ID列表查询员工考勤信息列表时发生异常!" );
+				logger.error( "system query attendance detail with ids got an exception.", e );
+			}	
+		}
+		if( check && attendanceDetailList != null && !attendanceDetailList.isEmpty() ){
+			try {
+				attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在根据ID列表查询工作节假日配置信息列表时发生异常!" ) );
+				result.setUserMessage( "系统在根据ID列表查询工作节假日配置信息列表时发生异常!" );
+				logger.error( "system query attendance work day config info with ids got an exception.", e );
+			}	
+		}
+		if( check && attendanceDetailList != null && !attendanceDetailList.isEmpty() ){
+			try {//查询所有的周期配置,组织成Map
+				companyAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles();
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception( "系统在查询并且组织所有的统计周期时发生异常!" ) );
+				result.setUserMessage( "系统在查询并且组织所有的统计周期时发生异常!" );
+				logger.error( "system query and compose statistic cycle to map got an exception.", e );
+			}
+		}
+		if( check ){
+			if( attendanceDetailList != null && !attendanceDetailList.isEmpty() ){
+				int i = 0;
+				int count = attendanceDetailList.size();
+				for( AttendanceDetail detail : attendanceDetailList ){
+					i++;
+					if( i % 100 == 0){
+						logger.debug("已经分析["+i+"/"+count+"]条数据,请继续等待分析过程完成......");
+					}
+					try{
+						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceWorkDayConfigList, companyAttendanceStatisticalCycleMap );	
+					}catch(Exception e){
+						check = false;
+						result.error( new Exception( "系统分析员工打卡信息时发生异常!" ) );
+						result.setUserMessage( "系统分析员工打卡信息时发生异常!" );
+						logger.error( "system analyse employee attendance detail info got an exception.", e );
+					}
+				}
+			}else{
+				result.setUserMessage( "没有需要分析的员工打卡信息!" );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "分析打卡数据", response = WrapOutMessage.class)
+	@GET
+	@Path("analyse/id/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response analyseAttendanceDetails(@Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult< WrapOutMessage > result = new ActionResult<>();
+		AttendanceDetail detail = null;
+		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> companyAttendanceStatisticalCycleMap = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null || id.isEmpty() ){
+				check = false;
+				result.error( new Exception( "用户传入的需要分析的打卡记录ID为空,无法进行数据分析!" ) );
+				result.setUserMessage( "用户传入的需要分析的打卡记录ID为空,无法进行数据分析!" );
+			}
+		}
+		if( check ){
+			try {
+				detail = attendanceDetailServiceAdv.get( id );
+				if( detail == null ){
+					check = false;
+					result.error( new Exception( "打卡记录不存在,无法进行数据分析操作!" ) );
+					result.setUserMessage( "打卡记录不存在,无法进行数据分析操作!" );
+					logger.error( "system attendance detail{'id':'"+id+"'} is not exists." );
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统根据ID查询打卡信息对象时发生异常!" );
+				logger.error( "system get attendance detail with id got an exception.id:" + id, e );
+			}
+		}
+		if( check ){
+			try {
+				attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统查询所有的工作节假日配置信息列表时发生异常!" );
+				logger.error( "system query all work day config list got an exception", e );
+			}
+		}
+		if( check ){
+			try {
+				companyAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles();
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在查询并且组织所有的统计周期时发生异常!" );
+				logger.error( "system query and compose statistic cycle to map got an exception.", e );
+			}
+		}
+		if( check ){
+			try{
+				attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceWorkDayConfigList, companyAttendanceStatisticalCycleMap);
+				result.setUserMessage( "打卡信息分析完成。" );
+			}catch(Exception e){
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统分析指定打卡信息对象时发生异常!" );
+				logger.error( "system analyse attendance detail got an exception.", e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "将指定的打卡记录归档", response = WrapOutMessage.class )
+	@GET
+	@Path("archive/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response archiveAttendanceDetail( @Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		Boolean check = true;
+		
+		if( check ){
+			if( id != null && !id.isEmpty() ){
+				try{
+					attendanceDetailServiceAdv.archive( id );
+					result.setUserMessage( "指定打卡信息归档完成。" );
+				}catch(Exception e){
+					check = false;
+					result.error( e );
+					result.setUserMessage( "系统归档指定打卡信息对象时发生异常!" );
+					logger.error( "system archive attendance detail got an exception.id:" + id, e );
+				}
+			}else{
+				try{
+					attendanceDetailServiceAdv.archiveAll();
+					result.setUserMessage( "所有打卡信息归档完成。" );
+				}catch(Exception e){
+					check = false;
+					result.error( e );
+					result.setUserMessage( "系统归档所有定打卡信息对象时发生异常!" );
+					logger.error( "system archive all attendance detail got an exception.", e );
+				}
+			}
+		}		
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "列示根据过滤条件的AttendanceDetail,下一页.", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list/{id}/next/{count}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listNextWithFilter(@Context HttpServletRequest request, @PathParam("id") String id, @PathParam("count") Integer count, WrapInFilter wrapIn) {
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		long total = 0;
+		List<AttendanceDetail> detailList = null;
+		List<String> companyNames = new ArrayList<String>();
+		List<String> departmentNames = new ArrayList<String>();
+		List<WrapCompany> companyList = null;
+		List<WrapDepartment> departments = null;
+		logger.debug("user[" + currentPerson.getName() + "] try to list attendanceDetail for nextpage, last id=" + id );
+		try {		
+			EntityManagerContainer emc = EntityManagerContainerFactory.instance().create();
+			Business business = new Business(emc);
+			
+			//查询出ID对应的记录的sequence
+			Object sequence = null;
+			if( id == null || "(0)".equals(id) || id.isEmpty() ){
+				//logger.debug( "第一页查询,没有id传入" );
+			}else{
+				if (!StringUtils.equalsIgnoreCase(id, HttpAttribute.x_empty_symbol)) {
+					sequence = PropertyUtils.getProperty(emc.find( id, AttendanceDetail.class, ExceptionWhen.not_found), "sequence");
+				}
+			}
+			
+			//处理一下公司,查询下级公司
+			if( wrapIn.getQ_companyName() != null && !wrapIn.getQ_companyName().isEmpty() ){
+				companyNames.add( wrapIn.getQ_companyName() );
+				try{
+					companyList = business.organization().company().listSubNested( wrapIn.getQ_companyName() );
+				}catch(Exception e){
+					logger.error("系统在根据公司名称获取下级公司的时候发生异常", e);
+				}
+				if( companyList != null && companyList.size() > 0 ){
+					for( WrapCompany company : companyList){
+						companyNames.add(company.getName());
+					}
+				}
+				wrapIn.setCompanyNames(companyNames);
+			}
+			
+			//处理一下部门,查询下级部门
+			if( wrapIn.getQ_departmentName() != null && !wrapIn.getQ_departmentName().isEmpty() ){
+				departmentNames.add(wrapIn.getQ_departmentName());
+				try{
+					departments = business.organization().department().listSubNested( wrapIn.getQ_departmentName() );
+				}catch(Exception e){
+					logger.error("系统在根据部门名称查询下级部门的时候发生异常", e);
+				}
+				if( departments != null && departments.size() > 0 ){
+					for( WrapDepartment department : departments){
+						departmentNames.add( department.getName() );
+					}
+				}
+				wrapIn.setDepartmentNames(departmentNames);
+			}
+			
+			//从数据库中查询符合条件的一页数据对象
+			detailList = business.getAttendanceDetailFactory().listIdsNextWithFilter( id, count, sequence, wrapIn );
+			//从数据库中查询符合条件的对象总数
+			total = business.getAttendanceDetailFactory().getCountWithFilter( wrapIn );
+			//将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象
+			wraps = wrapout_copier.copy( detailList );	
+			//对查询的列表进行排序
+			result.setCount( total );
+			result.setData(wraps);
+
+		} catch (Throwable th) {
+			th.printStackTrace();
+			result.error(th);
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+
+	@HttpMethodDescribe(value = "列示根据过滤条件的AttendanceDetail,上一页.", response = WrapOutAttendanceDetail.class, request = WrapInFilter.class)
+	@PUT
+	@Path("filter/list/{id}/prev/{count}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listPrevWithFilter(@Context HttpServletRequest request, @PathParam("id") String id, @PathParam("count") Integer count, WrapInFilter wrapIn) {
+		ActionResult<List<WrapOutAttendanceDetail>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetail> wraps = null;
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		long total = 0;
+		List<AttendanceDetail> detailList = null;
+		List<String> companyNames = new ArrayList<String>();
+		List<String> departmentNames = new ArrayList<String>();
+		List<WrapCompany> companyList = null;
+		List<WrapDepartment> departments = null;
+		logger.debug("user[" + currentPerson.getName() + "] try to list attendanceDetail for nextpage, last id=" + id );
+		try {		
+			EntityManagerContainer emc = EntityManagerContainerFactory.instance().create();
+			Business business = new Business(emc);
+			
+			//查询出ID对应的记录的sequence
+			Object sequence = null;
+			//logger.debug( "传入的ID=" + id );
+			if( id == null || "(0)".equals(id) || id.isEmpty() ){
+				//logger.debug( "第一页查询,没有id传入" );
+			}else{
+				if (!StringUtils.equalsIgnoreCase(id, HttpAttribute.x_empty_symbol)) {
+					sequence = PropertyUtils.getProperty(emc.find(id, AttendanceDetail.class, ExceptionWhen.not_found), "sequence");
+				}
+			}		
+			
+			//处理一下公司,查询下级公司
+			if( wrapIn.getQ_companyName() != null && !wrapIn.getQ_companyName().isEmpty() ){
+				companyNames.add( wrapIn.getQ_companyName() );
+				try{
+					companyList = business.organization().company().listSubNested( wrapIn.getQ_companyName() );
+				}catch(Exception e){
+					logger.error("系统在根据公司名称获取下级公司的时候发生异常", e);
+				}
+				if( companyList != null && companyList.size() > 0 ){
+					for( WrapCompany company : companyList){
+						companyNames.add(company.getName());
+					}
+				}
+				wrapIn.setCompanyNames(companyNames);
+			}
+			
+			//处理一下部门,查询下级部门
+			if( wrapIn.getQ_departmentName() != null && !wrapIn.getQ_departmentName().isEmpty() ){
+				departmentNames.add(wrapIn.getQ_departmentName());
+				try{
+					departments = business.organization().department().listSubNested( wrapIn.getQ_departmentName() );
+				}catch(Exception e){
+					logger.error("系统在根据部门名称查询下级部门的时候发生异常", e);
+				}
+				if( departments != null && departments.size() > 0 ){
+					for( WrapDepartment department : departments){
+						departmentNames.add( department.getName() );
+					}
+				}
+				wrapIn.setDepartmentNames(departmentNames);
+			}
+			
+			//从数据库中查询符合条件的一页数据对象
+			detailList = business.getAttendanceDetailFactory().listIdsPrevWithFilter( id, count, sequence, wrapIn );
+			//从数据库中查询符合条件的对象总数
+			total = business.getAttendanceDetailFactory().getCountWithFilter( wrapIn );
+			//将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象
+			wraps = wrapout_copier.copy( detailList );
+			result.setCount( total );
+			result.setData(wraps);
+
+		} catch (Throwable th) {
+			th.printStackTrace();
+			result.error(th);
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	/**
+	 * 打卡信息接入
+	 * 1-员工姓名 EmployeeName	
+	   2-员工号   EmployeeNo
+	   3-日期	RecordDateString
+	   4-签到时间  OnDutyTime
+	   5-签退时间  OffDutyTime
+	 * @author liyi_
+	 */
+	@HttpMethodDescribe(value = "接入完成的上下班打卡信息记录,接入完成后直接分析.", request = WrapInAttendanceDetailRecive.class, response = WrapOutMessage.class)
+	@Path("recive")
+	@POST
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response recive(@Context HttpServletRequest request, WrapInAttendanceDetailRecive wrapIn ) {
+		ActionResult<WrapOutId> result = new ActionResult<>();
+		WrapOutId wrapOutId = null;
+		Date datetime = null;
+		DateOperation dateOperation = new DateOperation();
+		AttendanceDetail attendanceDetail = new AttendanceDetail();
+		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> companyAttendanceStatisticalCycleMap = null;
+		Boolean check = true;
+		
+		if( wrapIn == null ){
+			check = false;
+			result.error( new Exception("系统未获取到需要保存的数据!") );
+			result.setUserMessage( "系统未获取到需要保存的数据!" );
+		}
+		if( check ){
+			if( wrapIn.getRecordDateString() == null || wrapIn.getRecordDateString().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡日期不能为空,格式: yyyy-mm-dd!") );
+				result.setUserMessage( "打卡信息中打卡日期不能为空,格式: yyyy-mm-dd!" );
+			}
+		}
+		if( check ){
+			if( wrapIn.getEmpName() == null || wrapIn.getEmpName().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡员工姓名不能为空!") );
+				result.setUserMessage( "打卡信息中打卡员工姓名不能为空!" );
+			}
+		}
+		if( check ){
+			try{
+				datetime = dateOperation.getDateFromString( wrapIn.getRecordDateString() );
+				attendanceDetail.setRecordDate( datetime );
+				attendanceDetail.setRecordDateString( dateOperation.getDateStringFromDate( datetime, "YYYY-MM-DD") );
+				attendanceDetail.setYearString( dateOperation.getYear( datetime ) );
+				attendanceDetail.setMonthString( dateOperation.getMonth(datetime) );
+			}catch( Exception e ){
+				check = false;
+				result.error( new Exception("打卡日期格式异常,时间:" + wrapIn.getRecordDateString() ) );
+				result.setUserMessage( "打卡日期格式异常,时间:" + wrapIn.getRecordDateString() );
+				logger.error("record date string error:" + wrapIn.getRecordDateString(), e);
+			}
+		}
+		if( check ){
+			if( wrapIn.getOnDutyTime() != null && wrapIn.getOnDutyTime().trim().length() > 0 ){
+				try{
+					datetime = dateOperation.getDateFromString( wrapIn.getOnDutyTime() );
+					attendanceDetail.setOnDutyTime( dateOperation.getDateStringFromDate( datetime, "HH:mm:ss") ); //上班打卡时间
+				}catch( Exception e ){
+					check = false;
+					result.error( new Exception("上班打卡时间格式异常,时间:" + wrapIn.getOnDutyTime() ) );
+					result.setUserMessage( "上班打卡时间格式异常,时间:" + wrapIn.getOnDutyTime() );
+					logger.error("on duty time string error:" + wrapIn.getOnDutyTime(), e);
+				}
+			}
+		}
+		if( check ){
+			if( wrapIn.getOffDutyTime() != null && wrapIn.getOffDutyTime().trim().length() > 0 ){
+				try{
+					datetime = dateOperation.getDateFromString( wrapIn.getOffDutyTime() );
+					attendanceDetail.setOffDutyTime( dateOperation.getDateStringFromDate( datetime, "HH:mm:ss") ); //上班打卡时间
+				}catch( Exception e ){
+					check = false;
+					result.error( new Exception("下班打卡时间格式异常,时间:" + wrapIn.getOffDutyTime() ) );
+					result.setUserMessage( "下班打卡时间格式异常,时间:" + wrapIn.getOffDutyTime() );
+					logger.error("off duty time string error:" + wrapIn.getOffDutyTime(), e);
+				}
+			}
+		}
+		if( check ){
+			try {
+				attendanceDetail = attendanceDetailServiceAdv.save( attendanceDetail );
+				wrapOutId = new WrapOutId( attendanceDetail.getId() );
+				result.setData( wrapOutId );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在保存打卡数据信息时发生异常。" ) );
+				result.setUserMessage( "系统在保存打卡数据信息时发生异常。" );
+				logger.error("system save attendanceDetail got an exception.", e);
+			}
+		}
+		if( check ){
+			try {
+				attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统查询所有的工作节假日配置信息列表时发生异常!" );
+				logger.error( "system query all work day config list got an exception", e );
+			}
+		}
+		if( check ){
+			try {
+				companyAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles();
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统在查询并且组织所有的统计周期时发生异常!" );
+				logger.error( "system query and compose statistic cycle to map got an exception.", e );
+			}
+		}
+		if( check ){
+			try{
+				attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( attendanceDetail, attendanceWorkDayConfigList, companyAttendanceStatisticalCycleMap);
+				result.setUserMessage( "打卡信息保存并且分析完成。" );
+			}catch(Exception e){
+				check = false;
+				result.error( e );
+				result.setUserMessage( "系统分析指定打卡信息对象时发生异常!" );
+				logger.error( "system analyse attendance detail got an exception.", e );
+			}
+		}
+		
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID删除AttendanceDetail数据对象.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response delete(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		WrapOutMessage wrapOutMessage = new WrapOutMessage();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		logger.debug("user " + currentPerson.getName() + "try to delete attendanceDetail......" );
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			//先判断需要操作的应用信息是否存在,根据ID进行一次查询,如果不存在不允许继续操作
+			AttendanceDetail attendanceDetail = emc.find(id, AttendanceDetail.class);
+			if (null == attendanceDetail) {
+				wrapOutMessage.setStatus("ERROR");
+				wrapOutMessage.setMessage( "需要删除的打卡数据信息不存在。id=" + id );
+			}else{
+				//进行数据库持久化操作				
+				emc.beginTransaction( AttendanceDetail.class );
+				emc.remove( attendanceDetail, CheckRemoveType.all );
+				emc.commit();			
+				wrapOutMessage.setStatus("SUCCESS");
+				wrapOutMessage.setMessage( "成功删除打卡数据信息。id=" + id );
+			}			
+		} catch ( Exception e ) {
+			e.printStackTrace();
+			wrapOutMessage.setStatus("ERROR");
+			wrapOutMessage.setMessage( "删除打卡数据过程中发生异常。" );
+			wrapOutMessage.setExceptionMessage( e.getMessage() );
+		}
+		result.setData( wrapOutMessage );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 382 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceDetailMobileAction.java

@@ -0,0 +1,382 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceDetailServiceAdv;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.WrapOutId;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+import com.x.base.core.utils.SortTools;
+
+
+@Path("attendancedetail/mobile")
+public class AttendanceDetailMobileAction extends StandardJaxrsAction{
+	
+	private Logger logger = LoggerFactory.getLogger( AttendanceDetailMobileAction.class );
+	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
+	private BeanCopyTools<AttendanceDetailMobile, WrapOutAttendanceDetailMobile> wrapout_copier = BeanCopyToolsBuilder.create( AttendanceDetailMobile.class, WrapOutAttendanceDetailMobile.class, null, WrapOutAttendanceDetailMobile.Excludes);
+
+	@HttpMethodDescribe(value = "根据ID获取AttendanceDetail对象.", response = WrapOutAttendanceDetailMobile.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get(@Context HttpServletRequest request, @PathParam("id") String id ) {
+		ActionResult<WrapOutAttendanceDetailMobile> result = new ActionResult<>();
+		WrapOutAttendanceDetailMobile wrap = null;
+		AttendanceDetailMobile attendanceDetailMobile = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null ){
+				check = false;
+				result.error( new Exception("需要查询的打卡详细记录ID为空,无法进行数据查询。") );
+				result.setUserMessage( "需要查询的打卡详细记录ID为空,无法进行数据查询。" );
+			}
+		}		
+		if( check ){
+			try {
+				attendanceDetailMobile = attendanceDetailServiceAdv.getMobile( id );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在根据用户传入的ID查询打卡详细信息记录时发生异常。") );
+				result.setUserMessage( "系统在根据用户传入的ID查询打卡详细信息记录时发生异常。" );
+				logger.error( "system get attendance detail Mobile info with id:"+ id +" got an exception.", e );
+			}
+		}		
+		if( check ){
+			if( attendanceDetailMobile == null ){
+				check = false;
+				result.error( new Exception("系统在根据用户传入的ID未能查询到任何打卡详细信息记录常。" ) );
+				result.setUserMessage( "系统在根据用户传入的ID未能查询到任何打卡详细信息记录常。" );
+			}
+		}		
+		if( check ){
+			try {
+				wrap = wrapout_copier.copy( attendanceDetailMobile );
+				result.setData(wrap);
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在转换数据库对象attendanceDetailMobile为输出对象时发生异常。") );
+				result.setUserMessage( "系统在转换数据库对象为输出对象时发生异常。" );
+				logger.error( "system copy attendanceDetailMobile to wrap got an exception.", e );
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "手机打卡信息明细查询.", request = WrapInAttendanceDetailMobileQuery.class, response = AttendanceDetailMobile.class)
+	@Path("filter/list/page/{page}/count/{count}")
+	@PUT
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listDataForMobile(@Context HttpServletRequest request, @PathParam("page") Integer page, @PathParam("count") Integer count, WrapInAttendanceDetailMobileQuery wrapIn ) {
+		ActionResult<List<WrapOutAttendanceDetailMobile>> result = new ActionResult<>();
+		List<WrapOutAttendanceDetailMobile> wraps = new ArrayList<>();
+		List<WrapOutAttendanceDetailMobile> allResultWrap = null;
+		List<AttendanceDetailMobile> attendanceDetailMobileList = null;
+		Date datetime = null;
+		DateOperation dateOperation = new DateOperation();
+		Long total = 0L;
+		Integer selectTotal = 0;
+		Boolean check = true;
+		Boolean queryConditionIsNull = true;
+		
+		if( wrapIn == null ){
+			check = false;
+			result.error( new Exception("系统未获取到需要保存的数据!") );
+			result.setUserMessage( "系统未获取到需要保存的数据!" );
+		}
+		if( check ){
+			if( page == null ){
+				page = 1;
+			}
+		}
+		if( check ){
+			if( count == null ){
+				count = 20;
+			}
+		}
+		if( page <= 0 ){
+			page = 1;
+		}
+		if( count <= 0 ){
+			count = 20;
+		}
+		if( check ){
+			if( wrapIn.getEmpNo() != null && !wrapIn.getEmpNo().isEmpty() ){
+				queryConditionIsNull = false;
+			}
+			if( wrapIn.getEmpName() != null && !wrapIn.getEmpName().isEmpty() ){
+				queryConditionIsNull = false;
+			}
+			if( wrapIn.getStartDate() != null && !wrapIn.getStartDate().isEmpty() ){
+				queryConditionIsNull = false;
+				if( wrapIn.getEndDate() == null || wrapIn.getEndDate().isEmpty() ){
+					wrapIn.setEndDate( wrapIn.getStartDate() );
+				}
+			}
+			if( queryConditionIsNull ){
+				check = false;
+				result.error( new Exception("员工号,员工姓名和查询日期不能全部为空!") );
+				result.setUserMessage( "员工号,员工姓名和查询日期不能全部为空!" );
+			}
+		}
+		if( check ){
+			if( wrapIn.getEndDate() != null && !wrapIn.getEndDate().isEmpty() ){
+				try{
+					datetime = dateOperation.getDateFromString( wrapIn.getEndDate() );
+					wrapIn.setEndDate( dateOperation.getDateStringFromDate( datetime, "YYYY-MM-DD") ); //结束日期
+				}catch( Exception e ){
+					check = false;
+					result.error( new Exception("结束日期格式异常,日期:" + wrapIn.getEndDate() ) );
+					result.setUserMessage( "结束日期格式异常,日期:" + wrapIn.getEndDate() );
+					logger.error("end date string error:" + wrapIn.getEndDate(), e);
+				}
+				if( wrapIn.getEndDate() == null || wrapIn.getEndDate().isEmpty() ){
+					wrapIn.setEndDate( wrapIn.getStartDate() );
+				}
+			}
+			if( wrapIn.getStartDate() != null && !wrapIn.getStartDate().isEmpty() ){
+				try{
+					datetime = dateOperation.getDateFromString( wrapIn.getStartDate() );
+					wrapIn.setStartDate( dateOperation.getDateStringFromDate( datetime, "YYYY-MM-DD") ); //开始日期
+				}catch( Exception e ){
+					check = false;
+					result.error( new Exception("开始日期格式异常,日期:" + wrapIn.getStartDate() ) );
+					result.setUserMessage( "开始日期格式异常,日期:" + wrapIn.getStartDate() );
+					logger.error("start date string error:" + wrapIn.getStartDate(), e);
+				}
+			}
+		}
+		//查询的最大条目数
+		selectTotal = page * count;
+		if( check ){
+			if( selectTotal > 0 ){
+				try{
+					total = attendanceDetailServiceAdv.countAttendanceDetailMobileForPage( wrapIn.getEmpNo(), wrapIn.getEmpName(), wrapIn.getSignDescription(), wrapIn.getStartDate(), wrapIn.getEndDate() );
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage( "根据ID信息查询版块信息时发生异常!" );
+					logger.error( "system query all top subject info with section info got an exceptin.", e );
+				}
+			}
+		}
+		if( check ){
+			if( selectTotal > 0 && total > 0 ){
+				try{
+					attendanceDetailMobileList = attendanceDetailServiceAdv.listAttendanceDetailMobileForPage( wrapIn.getEmpNo(), wrapIn.getEmpName(), wrapIn.getSignDescription(), wrapIn.getStartDate(), wrapIn.getEndDate(), selectTotal );
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage( "根据ID信息查询版块信息时发生异常!" );
+					logger.error( "system query all top subject info with section info got an exceptin.", e );
+				}
+			}
+		}
+		if( check ){
+			if( attendanceDetailMobileList != null && !attendanceDetailMobileList.isEmpty() ){
+				try {
+					allResultWrap = wrapout_copier.copy( attendanceDetailMobileList );
+				} catch (Exception e) {
+					check = false;
+					result.error( e );
+					result.setUserMessage( "系统将列表转换为输出格式时发生异常!" );
+					logger.error( "system copy list to wraps got an exceptin.", e );
+				}
+			}
+		}
+		if( check ){
+			int startIndex = ( page - 1 ) * count;
+			int endIndex = page * count;
+			for( int i=0; allResultWrap != null && i< allResultWrap.size(); i++ ){
+				if( i >= startIndex && i < endIndex ){
+					wraps.add( allResultWrap.get( i ) );
+				}
+			}
+		}
+		result.setCount( total );
+		result.setData( wraps );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	/**
+	 * 打卡信息接入,移动端特点,会多次接入,部分接入,一次接入的信息不完整
+	 * 接入后只保存 ,由定时代理定期进行数据整合,入库并且 分析
+	 * 1-员工姓名 EmployeeName	
+	   2-员工号   EmployeeNo
+	   3-日期	RecordDateString
+	   4-打卡时间 SignTime
+	   6-打卡位置 
+	   7-打卡坐标
+	 * @author liyi_
+	 */
+	@HttpMethodDescribe(value = "打卡信息接入,移动端特点,会多次接入,部分接入,一次接入的信息不完整,接入完成后不直接进行分析.", request = WrapInAttendanceDetailMobile.class, response = WrapOutId.class)
+	@Path("recive")
+	@POST
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response reciveForMobile(@Context HttpServletRequest request, WrapInAttendanceDetailMobile wrapIn ) {
+		ActionResult<WrapOutId> result = new ActionResult<>();
+		WrapOutId wrapOutId = null;
+		Date datetime = null;
+		DateOperation dateOperation = new DateOperation();
+		AttendanceDetailMobile attendanceDetailMobile = new AttendanceDetailMobile();
+		Boolean check = true;
+		
+		if( wrapIn == null ){
+			check = false;
+			result.error( new Exception("系统未获取到需要保存的数据!") );
+			result.setUserMessage( "系统未获取到需要保存的数据!" );
+		}
+		if( check ){
+			if( wrapIn.getRecordAddress() == null || wrapIn.getRecordAddress().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡地址描述 不能为空!") );
+				result.setUserMessage( "打卡信息中打卡地址描述 不能为空!" );
+			}else{
+				attendanceDetailMobile.setRecordAddress( wrapIn.getRecordAddress() );
+			}
+		}
+		if( check ){
+			if( wrapIn.getLatitude() == null || wrapIn.getLatitude().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡地址纬度信息不能为空!") );
+				result.setUserMessage( "打卡信息中打卡地址纬度信息不能为空!" );
+			}else{
+				attendanceDetailMobile.setLatitude( wrapIn.getLatitude() );
+			}
+		}
+		if( check ){
+			if( wrapIn.getLongitude() == null || wrapIn.getLongitude().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡地址经度信息不能为空!") );
+				result.setUserMessage( "打卡信息中打卡地址经度信息不能为空!" );
+			}else{
+				attendanceDetailMobile.setLongitude( wrapIn.getLongitude() );
+			}
+		}
+		if( check ){
+			if( wrapIn.getRecordDateString() == null || wrapIn.getRecordDateString().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡日期不能为空,格式: yyyy-mm-dd!") );
+				result.setUserMessage( "打卡信息中打卡日期不能为空,格式: yyyy-mm-dd!" );
+			}else{
+				attendanceDetailMobile.setRecordDateString( wrapIn.getRecordDateString() );
+			}
+		}
+		if( check ){
+			if( wrapIn.getEmpName() == null || wrapIn.getEmpName().isEmpty() ){
+				check = false;
+				result.error( new Exception("打卡信息中打卡员工姓名不能为空!") );
+				result.setUserMessage( "打卡信息中打卡员工姓名不能为空!" );
+			}else{
+				attendanceDetailMobile.setEmpName( wrapIn.getEmpName() );
+			}
+		}
+		if( check ){
+			try{
+				datetime = dateOperation.getDateFromString( wrapIn.getRecordDateString() );
+				attendanceDetailMobile.setRecordDate( datetime );
+				attendanceDetailMobile.setRecordDateString( dateOperation.getDateStringFromDate( datetime, "YYYY-MM-DD") );
+			}catch( Exception e ){
+				check = false;
+				result.error( new Exception("打卡日期格式异常,时间:" + wrapIn.getRecordDateString() ) );
+				result.setUserMessage( "打卡日期格式异常,时间:" + wrapIn.getRecordDateString() );
+				logger.error("record date string error:" + wrapIn.getRecordDateString(), e);
+			}
+		}
+		if( check ){
+			if( wrapIn.getSignTime() != null && wrapIn.getSignTime().trim().length() > 0 ){
+				try{
+					datetime = dateOperation.getDateFromString( wrapIn.getSignTime() );
+					attendanceDetailMobile.setSignTime( dateOperation.getDateStringFromDate( datetime, "HH:mm:ss") ); //打卡时间
+				}catch( Exception e ){
+					check = false;
+					result.error( new Exception("打卡时间格式异常,时间:" + wrapIn.getSignTime() ) );
+					result.setUserMessage( "打卡时间格式异常,时间:" + wrapIn.getSignTime() );
+					logger.error("sign time string error:" + wrapIn.getSignTime(), e);
+				}
+			}
+		}
+		if( check ){
+			if( wrapIn.getId() != null && !wrapIn.getId().isEmpty()){
+				attendanceDetailMobile.setId( wrapIn.getId() );
+			}
+			attendanceDetailMobile.setSignDescription( wrapIn.getSignDescription() );
+			try {
+				attendanceDetailMobile = attendanceDetailServiceAdv.save( attendanceDetailMobile );
+				wrapOutId = new WrapOutId( attendanceDetailMobile.getId() );
+				result.setData( wrapOutId );
+			} catch (Exception e) {
+				check = false;
+				result.error( new Exception("系统在保存打卡数据信息时发生异常。" ) );
+				result.setUserMessage( "系统在保存打卡数据信息时发生异常。" );
+				logger.error("system save attendanceDetailMobile got an exception.", e);
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID删除AttendanceDetailMobile数据对象.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response delete(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutMessage> result = new ActionResult<>();
+		WrapOutMessage wrapOutMessage = new WrapOutMessage();
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			//先判断需要操作的应用信息是否存在,根据ID进行一次查询,如果不存在不允许继续操作
+			AttendanceDetailMobile attendanceDetailMobile = emc.find(id, AttendanceDetailMobile.class);
+			if (null == attendanceDetailMobile) {
+				wrapOutMessage.setStatus("ERROR");
+				wrapOutMessage.setMessage( "需要删除的打卡数据信息不存在。id=" + id );
+			}else{
+				//进行数据库持久化操作				
+				emc.beginTransaction( AttendanceDetailMobile.class );
+				emc.remove( attendanceDetailMobile, CheckRemoveType.all );
+				emc.commit();			
+				wrapOutMessage.setStatus("SUCCESS");
+				wrapOutMessage.setMessage( "成功删除打卡数据信息。id=" + id );
+			}			
+		} catch ( Exception e ) {
+			e.printStackTrace();
+			wrapOutMessage.setStatus("ERROR");
+			wrapOutMessage.setMessage( "删除打卡数据过程中发生异常。" );
+			wrapOutMessage.setExceptionMessage( e.getMessage() );
+		}
+		result.setData( wrapOutMessage );
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 17 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetail.java

@@ -0,0 +1,17 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetail.class)
+public class WrapInAttendanceDetail extends AttendanceDetail {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodifies);
+
+}

+ 120 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailMobile.java

@@ -0,0 +1,120 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.base.core.entity.annotation.EntityFieldDescribe;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetailMobile.class)
+public class WrapInAttendanceDetailMobile {
+	
+	@EntityFieldDescribe( "Id, 可以为空." )
+	private String id;
+	
+	@EntityFieldDescribe( "员工号, 可以为空." )
+	private String empNo;
+
+	@EntityFieldDescribe( "员工姓名, 必须填写." )
+	private String empName;
+
+	@EntityFieldDescribe( "打卡记录日期字符串:yyyy-mm-dd, 必须填写." )
+	private String recordDateString;	
+
+	@EntityFieldDescribe( "打卡时间: hh24:mi:ss, 必须填写." )
+	private String signTime;
+
+	@EntityFieldDescribe( "打卡说明:上班打卡,下班打卡, 可以为空." )
+	private String signDescription;
+
+	@EntityFieldDescribe( "其他说明备注, 可以为空." )
+	private String description;
+
+	@EntityFieldDescribe( "打卡地点描述, 可以为空." )
+	private String recordAddress = "未知";
+	
+	@EntityFieldDescribe( "经度, 可以为空." )
+	private String longitude;
+
+	@EntityFieldDescribe( "纬度, 可以为空." )
+	private String latitude;
+
+	@EntityFieldDescribe( "操作设备类别:手机品牌|PAD|PC|其他, 可以为空." )
+	private String optMachineType = "其他";
+
+	@EntityFieldDescribe( "操作设备类别:Mac|Windows|IOS|Android|其他, 可以为空." )
+	private String optSystemName = "其他";
+
+	public String getRecordDateString() {
+		return recordDateString;
+	}
+	public void setRecordDateString(String recordDateString) {
+		this.recordDateString = recordDateString;
+	}
+	public String getSignDescription() {
+		return signDescription;
+	}
+	public void setSignDescription(String signDescription) {
+		this.signDescription = signDescription;
+	}
+	public String getDescription() {
+		return description;
+	}
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	public String getRecordAddress() {
+		return recordAddress;
+	}
+	public void setRecordAddress(String recordAddress) {
+		this.recordAddress = recordAddress;
+	}
+	public String getLongitude() {
+		return longitude;
+	}
+	public void setLongitude(String longitude) {
+		this.longitude = longitude;
+	}
+	public String getLatitude() {
+		return latitude;
+	}
+	public void setLatitude(String latitude) {
+		this.latitude = latitude;
+	}
+	public String getOptMachineType() {
+		return optMachineType;
+	}
+	public void setOptMachineType(String optMachineType) {
+		this.optMachineType = optMachineType;
+	}
+	public String getOptSystemName() {
+		return optSystemName;
+	}
+	public void setOptSystemName(String optSystemName) {
+		this.optSystemName = optSystemName;
+	}
+	
+	public String getEmpNo() {
+		return empNo;
+	}
+	public void setEmpNo(String empNo) {
+		this.empNo = empNo;
+	}
+	public String getEmpName() {
+		return empName;
+	}
+	public void setEmpName(String empName) {
+		this.empName = empName;
+	}
+	public String getSignTime() {
+		return signTime;
+	}
+	public void setSignTime(String signTime) {
+		this.signTime = signTime;
+	}
+	public String getId() {
+		return id;
+	}
+	public void setId(String id) {
+		this.id = id;
+	}
+	
+}

+ 65 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailMobileQuery.java

@@ -0,0 +1,65 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.base.core.entity.annotation.EntityFieldDescribe;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetailMobile.class)
+public class WrapInAttendanceDetailMobileQuery {
+
+	@EntityFieldDescribe( "员工号,根据员工号查询记录" )
+	private String empNo;
+
+	@EntityFieldDescribe( "员工姓名,根据员工姓名查询记录." )
+	private String empName;
+
+	@EntityFieldDescribe( "开始日期:yyyy-mm-dd." )
+	private String startDate;
+	
+	@EntityFieldDescribe( "结束日期:yyyy-mm-dd,如果开始日期填写,结束日期不填写就是只查询开始日期那一天" )
+	private String endDate;
+
+	@EntityFieldDescribe( "打卡说明:上班打卡,下班打卡." )
+	private String signDescription;
+
+	public String getEmpNo() {
+		return empNo;
+	}
+
+	public void setEmpNo(String empNo) {
+		this.empNo = empNo;
+	}
+
+	public String getEmpName() {
+		return empName;
+	}
+
+	public void setEmpName(String empName) {
+		this.empName = empName;
+	}
+
+	public String getStartDate() {
+		return startDate;
+	}
+
+	public void setStartDate(String startDate) {
+		this.startDate = startDate;
+	}
+
+	public String getEndDate() {
+		return endDate;
+	}
+
+	public void setEndDate(String endDate) {
+		this.endDate = endDate;
+	}
+
+	public String getSignDescription() {
+		return signDescription;
+	}
+
+	public void setSignDescription(String signDescription) {
+		this.signDescription = signDescription;
+	}
+
+}

+ 55 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInAttendanceDetailRecive.java

@@ -0,0 +1,55 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.http.annotation.Wrap;
+
+/**
+ * 1-员工姓名 EmployeeName	
+   2-员工号   EmployeeNo
+   3-日期	RecordDateString
+   4-签到时间  OnDutyTime
+   5-签退时间  OffDutyTime
+ * @author liyi_
+ *
+ */
+@Wrap( AttendanceDetail.class)
+public class WrapInAttendanceDetailRecive {
+
+	private String empName = null;
+	private String empNo = null;
+	private String recordDateString = null;
+	private String onDutyTime = null;
+	private String offDutyTime = null;
+	
+	
+	public String getEmpName() {
+		return empName;
+	}
+	public void setEmpName(String empName) {
+		this.empName = empName;
+	}
+	public String getEmpNo() {
+		return empNo;
+	}
+	public void setEmpNo(String empNo) {
+		this.empNo = empNo;
+	}
+	public String getRecordDateString() {
+		return recordDateString;
+	}
+	public void setRecordDateString(String recordDateString) {
+		this.recordDateString = recordDateString;
+	}
+	public String getOnDutyTime() {
+		return onDutyTime;
+	}
+	public void setOnDutyTime(String onDutyTime) {
+		this.onDutyTime = onDutyTime;
+	}
+	public String getOffDutyTime() {
+		return offDutyTime;
+	}
+	public void setOffDutyTime(String offDutyTime) {
+		this.offDutyTime = offDutyTime;
+	}
+}

+ 182 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapInFilter.java

@@ -0,0 +1,182 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetail.class)
+public class WrapInFilter extends GsonPropertyObject {
+
+	private String q_empName;
+	
+	private List<String> companyNames;
+	
+	private String q_companyName;
+	
+	private List<String> departmentNames;
+	
+	private String q_departmentName;
+
+	private String q_year;
+	
+	private String q_month;
+	
+	private String cycleYear;
+	
+	private String cycleMonth;
+	
+	private String q_date;
+	
+	private int recordStatus = 999;
+	
+	private Boolean isAbsent = null;
+	
+	private Boolean isLate = null;
+	
+	private Boolean isLeaveEarlier = null;
+	
+	private Boolean isLackOfTime = null;
+	
+	private String order = "DESC";
+
+	private String key;
+
+	public String getQ_empName() {
+		return q_empName;
+	}
+
+	public String getCycleYear() {
+		return cycleYear;
+	}
+
+	public void setCycleYear(String cycleYear) {
+		this.cycleYear = cycleYear;
+	}
+
+	public String getCycleMonth() {
+		return cycleMonth;
+	}
+
+	public void setCycleMonth(String cycleMonth) {
+		this.cycleMonth = cycleMonth;
+	}
+
+	public void setQ_empName(String q_empName) {
+		this.q_empName = q_empName;
+	}
+
+	public String getQ_year() {
+		return q_year;
+	}
+
+	public void setQ_year(String q_year) {
+		this.q_year = q_year;
+	}
+
+	public String getQ_month() {
+		return q_month;
+	}
+
+	public void setQ_month(String q_month) {
+		this.q_month = q_month;
+	}
+
+	public List<String> getCompanyNames() {
+		return companyNames;
+	}
+
+	public void setCompanyNames(List<String> companyNames) {
+		this.companyNames = companyNames;
+	}
+
+	public List<String> getDepartmentNames() {
+		return departmentNames;
+	}
+
+	public void setDepartmentNames(List<String> departmentNames) {
+		this.departmentNames = departmentNames;
+	}
+
+	public String getOrder() {
+		return order;
+	}
+
+	public void setOrder(String order) {
+		this.order = order;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public String getQ_date() {
+		return q_date;
+	}
+
+	public void setQ_date(String q_date) {
+		this.q_date = q_date;
+	}
+	
+	public Boolean getIsAbsent() {
+		return isAbsent;
+	}
+
+	public void setIsAbsent(Boolean isAbsent) {
+		this.isAbsent = isAbsent;
+	}
+
+	public Boolean getIsLate() {
+		return isLate;
+	}
+
+	public void setIsLate(Boolean isLate) {
+		this.isLate = isLate;
+	}
+
+	public Boolean getIsLeaveEarlier() {
+		return isLeaveEarlier;
+	}
+
+	public void setIsLeaveEarlier(Boolean isLeaveEarlier) {
+		this.isLeaveEarlier = isLeaveEarlier;
+	}
+
+	public Boolean getIsLackOfTime() {
+		return isLackOfTime;
+	}
+
+	public void setIsLackOfTime(Boolean isLackOfTime) {
+		this.isLackOfTime = isLackOfTime;
+	}
+
+	public int getRecordStatus() {
+		return recordStatus;
+	}
+
+	public void setRecordStatus(int recordStatus) {
+		this.recordStatus = recordStatus;
+	}
+
+	public String getQ_companyName() {
+		return q_companyName;
+	}
+
+	public void setQ_companyName(String q_companyName) {
+		this.q_companyName = q_companyName;
+	}
+
+	public String getQ_departmentName() {
+		return q_departmentName;
+	}
+
+	public void setQ_departmentName(String q_departmentName) {
+		this.q_departmentName = q_departmentName;
+	}
+	
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapOutAttendanceDetail.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetail.class )
+public class WrapOutAttendanceDetail extends AttendanceDetail  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/WrapOutAttendanceDetailMobile.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceDetailMobile.class )
+public class WrapOutAttendanceDetailMobile extends AttendanceDetailMobile  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+}

+ 218 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/AttendanceEmployeeConfigAction.java

@@ -0,0 +1,218 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceemployeeconfig;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceEmployeeConfigServiceAdv;
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.WrapOutId;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+
+
+@Path("attendanceemployeeconfig")
+public class AttendanceEmployeeConfigAction extends StandardJaxrsAction{
+	
+	private Logger logger = LoggerFactory.getLogger( AttendanceEmployeeConfigAction.class );
+	private AttendanceEmployeeConfigServiceAdv attendanceEmployeeConfigServiceAdv = new AttendanceEmployeeConfigServiceAdv();
+	private BeanCopyTools<WrapInAttendanceEmployeeConfig, AttendanceEmployeeConfig> wrapin_copier = BeanCopyToolsBuilder.create( WrapInAttendanceEmployeeConfig.class, AttendanceEmployeeConfig.class, null, WrapInAttendanceEmployeeConfig.Excludes );
+	private BeanCopyTools<AttendanceEmployeeConfig, WrapOutAttendanceEmployeeConfig> wrapout_copier = BeanCopyToolsBuilder.create( AttendanceEmployeeConfig.class, WrapOutAttendanceEmployeeConfig.class, null, WrapOutAttendanceEmployeeConfig.Excludes);
+	
+	@HttpMethodDescribe(value = "获取所有AttendanceEmployeeConfig列表", response = WrapOutAttendanceEmployeeConfig.class)
+	@GET
+	@Path("list/all")
+	@Produces( HttpMediaType.APPLICATION_JSON_UTF_8 )
+	@Consumes( MediaType.APPLICATION_JSON )
+	public Response listAllAttendanceEmployeeConfig( @Context HttpServletRequest request ) {
+		ActionResult<List<WrapOutAttendanceEmployeeConfig>> result = new ActionResult<>();
+		List<WrapOutAttendanceEmployeeConfig> wraps = null;
+		List<AttendanceEmployeeConfig> attendanceEmployeeConfigList = null;
+		Boolean check = true;
+		if( check ){
+			try {
+				attendanceEmployeeConfigList = attendanceEmployeeConfigServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统查询所有人员考勤配置时发生异常。");
+				logger.error( "system query all employee config list got an exception.", e);
+			}
+		}
+		if( check && attendanceEmployeeConfigList != null ){
+			//将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象
+			try {
+				wraps = wrapout_copier.copy( attendanceEmployeeConfigList );
+				result.setData(wraps);
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象时发生异常。");
+				logger.error( "system copy employee config list to wrap got an exception.", e);
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID获取AttendanceEmployeeConfig对象.", response = WrapOutAttendanceEmployeeConfig.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutAttendanceEmployeeConfig> result = new ActionResult<>();
+		WrapOutAttendanceEmployeeConfig wrap = null;
+		AttendanceEmployeeConfig attendanceEmployeeConfig = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null || id.isEmpty() ){
+				check = false;
+				result.error( new Exception("查询操作传入的参数ID为空,无法进行查询操作。") );
+				result.setUserMessage("查询操作传入的参数ID为空,无法进行查询操作。。");
+			}
+		}		
+		if( check ){
+			try {
+				attendanceEmployeeConfig = attendanceEmployeeConfigServiceAdv.get( id );
+				if( attendanceEmployeeConfig == null ){
+					check = false;
+					result.error(new Exception("指定的人员考勤数据不存在!"));
+					result.setUserMessage("指定的人员考勤数据不存在!");
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统根据ID查询指定的人员考勤配置信息时发生异常。");
+				logger.error( "system query employee config with id got an exception.id:" + id, e);
+			}
+		}
+		if( check ){
+			try {
+				wrap = wrapout_copier.copy(attendanceEmployeeConfig);
+				result.setData(wrap);
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象时发生异常。");
+				logger.error( "system copy employee config to wrap got an exception.", e);
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "新建或者更新AttendanceEmployeeConfig对象.", request = WrapInAttendanceEmployeeConfig.class, response = WrapOutMessage.class)
+	@POST
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response post(@Context HttpServletRequest request, WrapInAttendanceEmployeeConfig wrapIn ) {
+		ActionResult<WrapOutId> result = new ActionResult<>();
+		WrapOutId wrapOutId = null;
+		AttendanceEmployeeConfig attendanceEmployeeConfig = new AttendanceEmployeeConfig();
+		Boolean check = true;
+		
+		if( check ){
+			if( wrapIn == null ){
+				check = false;
+				result.error(new Exception("请求传入的参数为空,无法继续保存人员考勤数据!"));
+				result.setUserMessage("请求传入的参数为空,无法继续保存人员考勤数据!");
+			}
+		}
+		if( check ){
+			try {
+				wrapin_copier.copy( wrapIn, attendanceEmployeeConfig );
+				if( wrapIn.getId() != null && !wrapIn.getId().isEmpty() ){
+					attendanceEmployeeConfig.setId( wrapIn.getId() );
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage("系统将传入的参数COPY到对象里时发生异常!");
+				logger.error( "system copy wrap in to attendanceEmployeeConfig object got an exception.", e );
+			}
+		}
+		if( check ){
+			try {
+				attendanceEmployeeConfig = attendanceEmployeeConfigServiceAdv.save( attendanceEmployeeConfig );
+				wrapOutId = new WrapOutId( attendanceEmployeeConfig.getId() );
+				result.setData( wrapOutId );
+				result.setUserMessage( "人员考勤配置数据保存成功!" );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage("系统将传入的参数COPY到对象里时发生异常!");
+				logger.error( "system copy wrap in to attendanceEmployeeConfig object got an exception.", e );
+			}
+		}		
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID删除AttendanceEmployeeConfigAttendanceEmployeeConfig对象.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response delete(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutId> result = new ActionResult<>();
+		WrapOutId wrapOutId = null;
+		AttendanceEmployeeConfig attendanceEmployeeConfig = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null || id.isEmpty() ){
+				check = false;
+				result.error( new Exception("传入的参数ID为空,无法进行删除操作。") );
+				result.setUserMessage("传入的参数ID为空,无法进行删除操作。。");
+			}
+		}		
+		if( check ){
+			try {
+				attendanceEmployeeConfig = attendanceEmployeeConfigServiceAdv.get( id );
+				if( attendanceEmployeeConfig == null ){
+					check = false;
+					result.error(new Exception("需要删除的人员考勤数据不存在!"));
+					result.setUserMessage("需要删除的人员考勤数据不存在!");
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统根据ID查询指定的人员考勤配置信息时发生异常。");
+				logger.error( "system query employee config with id got an exception.id:" + id, e);
+			}
+		}
+		if( check ){
+			try {
+				attendanceEmployeeConfigServiceAdv.delete( id );
+				result.setUserMessage( "人员考勤配置数据保存成功!" );
+				wrapOutId = new WrapOutId( id );
+				result.setData( wrapOutId );
+			} catch (Exception e) {
+				check = false;
+				result.error( e );
+				result.setUserMessage("系统根据ID删除指定的人员考勤配置信息时发生异常。");
+				logger.error( "system delete employee config with id got an exception.id:" + id, e);
+			}
+			
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 24 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapInAttendanceEmployeeConfig.java

@@ -0,0 +1,24 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceemployeeconfig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceEmployeeConfig.class)
+public class WrapInAttendanceEmployeeConfig extends AttendanceEmployeeConfig {
+	private static final long serialVersionUID = -5076990764713538973L;
+	public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodifies);
+
+	private String identity = null;
+
+	public String getIdentity() {
+		return identity;
+	}
+
+	public void setIdentity(String identity) {
+		this.identity = identity;
+	}
+}

+ 33 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapInFilter.java

@@ -0,0 +1,33 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceemployeeconfig;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceEmployeeConfig.class)
+public class WrapInFilter extends GsonPropertyObject {
+
+	private List<NameValueCountPair> appIdList;
+
+	private String key;	
+
+	public List<NameValueCountPair> getAppIdList() {
+		return appIdList;
+	}
+
+	public void setAppIdList(List<NameValueCountPair> appIdList) {
+		this.appIdList = appIdList;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+}

+ 16 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceemployeeconfig/WrapOutAttendanceEmployeeConfig.java

@@ -0,0 +1,16 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceemployeeconfig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceEmployeeConfig;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceEmployeeConfig.class )
+public class WrapOutAttendanceEmployeeConfig extends AttendanceEmployeeConfig  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+}

+ 171 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/AttendanceImportFileInfoAction.java

@@ -0,0 +1,171 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceimportfileinfo;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.x.attendance.assemble.control.jaxrs.WrapOutMessage;
+import com.x.attendance.assemble.control.service.AttendanceImportFileInfoServiceAdv;
+import com.x.attendance.entity.AttendanceImportFileInfo;
+import com.x.base.core.application.jaxrs.StandardJaxrsAction;
+import com.x.base.core.bean.BeanCopyTools;
+import com.x.base.core.bean.BeanCopyToolsBuilder;
+import com.x.base.core.http.ActionResult;
+import com.x.base.core.http.HttpMediaType;
+import com.x.base.core.http.ResponseFactory;
+import com.x.base.core.http.WrapOutId;
+import com.x.base.core.http.annotation.HttpMethodDescribe;
+
+
+@Path("attendanceimportfileinfo")
+public class AttendanceImportFileInfoAction extends StandardJaxrsAction{
+	
+	private Logger logger = LoggerFactory.getLogger( AttendanceImportFileInfoAction.class );
+	private BeanCopyTools<AttendanceImportFileInfo, WrapOutAttendanceImportFileInfo> wrapout_copier = BeanCopyToolsBuilder.create( AttendanceImportFileInfo.class, WrapOutAttendanceImportFileInfo.class, null, WrapOutAttendanceImportFileInfo.Excludes);
+	private AttendanceImportFileInfoServiceAdv attendanceImportFileInfoServiceAdv = new AttendanceImportFileInfoServiceAdv();
+	
+	@HttpMethodDescribe(value = "获取所有已经上传成功的文件列表", response = WrapOutAttendanceImportFileInfo.class)
+	@GET
+	@Path("list/all")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response listAllAttendanceImportFileInfo(@Context HttpServletRequest request ) {
+		ActionResult<List<WrapOutAttendanceImportFileInfo>> result = new ActionResult<>();
+		List<WrapOutAttendanceImportFileInfo> wraps = null;
+		List<AttendanceImportFileInfo> attendanceSettingList = null;
+		Boolean check = true;
+		
+		if( check ){
+			try {
+				attendanceSettingList = attendanceImportFileInfoServiceAdv.listAll();
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统查询所有导入文件信息列表时发生异常。");
+				logger.error( "system query all import file info list got an exception.", e);
+			}
+		}
+		if( check && attendanceSettingList != null ){
+			try {
+				wraps = wrapout_copier.copy( attendanceSettingList );
+				result.setData(wraps);
+				result.setUserMessage( "查询成功!" );
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象时发生异常。");
+				logger.error( "system copy import file info list to wrap got an exception.", e);
+			}
+			
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID获取AttendanceImportFileInfo对象.", response = WrapOutAttendanceImportFileInfo.class)
+	@GET
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response get(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutAttendanceImportFileInfo> result = new ActionResult<>();
+		WrapOutAttendanceImportFileInfo wrap = null;
+		AttendanceImportFileInfo attendanceImportFileInfo = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null || id.isEmpty() ){
+				check = false;
+				result.error( new Exception("系统传入的ID为空。") );
+				result.setUserMessage("系统传入的ID为空。");
+			}
+		}
+		if( check ){
+			try {
+				attendanceImportFileInfo = attendanceImportFileInfoServiceAdv.get(id);
+				if( attendanceImportFileInfo == null ){
+					check = false;
+					result.error( new Exception("指定的文件导入信息不存在。") );
+					result.setUserMessage("指定的文件导入信息不存在。");
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统根据ID查询导入文件信息列表时发生异常。");
+				logger.error( "system query import file info with id got an exception.id:" + id, e);
+			}
+		}
+		if( check && attendanceImportFileInfo != null ){
+			try {
+				wrap = wrapout_copier.copy(attendanceImportFileInfo);
+				result.setData(wrap);
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("将所有查询出来的有状态的对象转换为可以输出的过滤过属性的对象时发生异常。");
+				logger.error( "system copy import file info to wrap got an exception.", e);
+			}	
+		}	
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+	
+	@HttpMethodDescribe(value = "根据ID删除已经上传成功的文件以及文件信息.", response = WrapOutMessage.class)
+	@DELETE
+	@Path("{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public Response delete(@Context HttpServletRequest request, @PathParam("id") String id) {
+		ActionResult<WrapOutId> result = new ActionResult<>();
+		WrapOutId wrapOutId = null;
+		AttendanceImportFileInfo attendanceImportFileInfo = null;
+		Boolean check = true;
+		
+		if( check ){
+			if( id == null || id.isEmpty() ){
+				check = false;
+				result.error( new Exception("系统传入的ID为空。") );
+				result.setUserMessage("系统传入的ID为空。");
+			}
+		}
+		if( check ){
+			try {
+				attendanceImportFileInfo = attendanceImportFileInfoServiceAdv.get(id);
+				if( attendanceImportFileInfo == null ){
+					check = false;
+					result.error( new Exception("指定的文件导入信息不存在。") );
+					result.setUserMessage("指定的文件导入信息不存在。");
+				}
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统根据ID查询导入文件信息列表时发生异常。");
+				logger.error( "system query import file info with id got an exception.id:" + id, e);
+			}
+		}
+		if( check ){
+			try {
+				attendanceImportFileInfoServiceAdv.delete(id);
+				wrapOutId = new WrapOutId( id );
+				result.setData( wrapOutId );
+				result.setUserMessage( "数据删除成功!" );
+			} catch (Exception e) {
+				check = false;
+				result.error(e);
+				result.setUserMessage("系统根据ID删除导入文件信息列表时发生异常。");
+				logger.error( "system delete import file info with id got an exception.id:" + id, e);
+			}
+		}
+		return ResponseFactory.getDefaultActionResultResponse(result);
+	}
+}

+ 24 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapInAttendanceImportFileInfo.java

@@ -0,0 +1,24 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceimportfileinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceImportFileInfo;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceImportFileInfo.class)
+public class WrapInAttendanceImportFileInfo extends AttendanceImportFileInfo {
+	private static final long serialVersionUID = -5076990764713538973L;
+	public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodifies);
+
+	private String identity = null;
+
+	public String getIdentity() {
+		return identity;
+	}
+
+	public void setIdentity(String identity) {
+		this.identity = identity;
+	}
+}

+ 33 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapInFilter.java

@@ -0,0 +1,33 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceimportfileinfo;
+
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceImportFileInfo;
+import com.x.base.core.bean.NameValueCountPair;
+import com.x.base.core.gson.GsonPropertyObject;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceImportFileInfo.class)
+public class WrapInFilter extends GsonPropertyObject {
+
+	private List<NameValueCountPair> appIdList;
+
+	private String key;	
+
+	public List<NameValueCountPair> getAppIdList() {
+		return appIdList;
+	}
+
+	public void setAppIdList(List<NameValueCountPair> appIdList) {
+		this.appIdList = appIdList;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+}

+ 20 - 0
x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceimportfileinfo/WrapOutAttendanceImportFileInfo.java

@@ -0,0 +1,20 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceimportfileinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.x.attendance.entity.AttendanceImportFileInfo;
+import com.x.base.core.http.annotation.Wrap;
+
+@Wrap( AttendanceImportFileInfo.class )
+public class WrapOutAttendanceImportFileInfo extends AttendanceImportFileInfo  {
+	
+	private static final long serialVersionUID = -5076990764713538973L;
+	
+	public static List<String> Excludes = new ArrayList<String>();
+	
+	static {
+		Excludes.add("fileBody");
+		Excludes.add("dataContent");
+	}
+}

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä