Преглед изворни кода

Merge branch 'feature/Attendance.duty.proxy.for.three.times' into 'develop'

Merge for feature/Attendance.duty.proxy.for.three.times[考勤管理]优化考勤代码,整理考勤统计的方式,启用消息队列

See merge request o2oa/o2oa!597
李义 пре 5 година
родитељ
комит
27cad1041e
41 измењених фајлова са 2026 додато и 1461 уклоњено
  1. 4 4
      o2server/x_attendance_assemble_control/pom.xml
  2. 119 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/AttendanceDetailStatisticQueue.java
  3. 64 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/PersonAttendanceDetailAnalyseQueue.java
  4. 12 4
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java
  5. 74 60
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionReciveAttendance.java
  6. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionDelete.java
  7. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionSave.java
  8. 5 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/BaseAction.java
  9. 6 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionDelete.java
  10. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionSave.java
  11. 3 11
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDelete.java
  12. 3 13
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDeleteByWfDocId.java
  13. 12 20
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionSave.java
  14. 2 27
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/processor/thread/OperatorDataAnalyse.java
  15. 532 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseCoreService.java
  16. 401 767
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseService.java
  17. 116 12
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseServiceAdv.java
  18. 1 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseService.java
  19. 4 7
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseServiceAdv.java
  20. 22 14
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailServiceAdv.java
  21. 1 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceSettingService.java
  22. 91 62
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticServiceAdv.java
  23. 27 3
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleService.java
  24. 8 7
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleServiceAdv.java
  25. 21 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceWorkDayConfigService.java
  26. 109 252
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetail.java
  27. 40 12
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceScheduleSetting.java
  28. 12 6
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkDayConfig.java
  29. 14 7
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkPlace.java
  30. 14 9
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/DingdingQywxSyncRecord.java
  31. 26 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingPersonForMonth.java
  32. 26 16
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForDay.java
  33. 24 13
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForMonth.java
  34. 30 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticPersonForMonth.java
  35. 26 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxPersonForMonth.java
  36. 29 18
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForDay.java
  37. 24 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForMonth.java
  38. 28 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForDay.java
  39. 26 13
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForMonth.java
  40. 30 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForDay.java
  41. 28 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForMonth.java

+ 4 - 4
o2server/x_attendance_assemble_control/pom.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <project
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-	xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+		xmlns="http://maven.apache.org/POM/4.0.0"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>o2oa</groupId>
@@ -122,4 +122,4 @@
 			</plugin>
 		</plugins>
 	</build>
-</project>
+</project>

+ 119 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/AttendanceDetailStatisticQueue.java

@@ -0,0 +1,119 @@
+package com.x.attendance.assemble.control;
+
+import com.alibaba.druid.util.StringUtils;
+import com.x.attendance.assemble.control.service.*;
+import com.x.attendance.entity.AttendanceStatisticRequireLog;
+import com.x.attendance.entity.AttendanceStatisticalCycle;
+import com.x.attendance.entity.AttendanceWorkDayConfig;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.queue.AbstractQueue;
+import net.sf.ehcache.Ehcache;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 对单个员工的打卡信息进行分析的队列
+ */
+public class AttendanceDetailStatisticQueue extends AbstractQueue<String> {
+
+    protected Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+    private AttendanceStatisticRequireLogServiceAdv statisticRequireLogServiceAdv = new AttendanceStatisticRequireLogServiceAdv();
+    private AttendanceWorkDayConfigService workDayConfigService = new AttendanceWorkDayConfigService();
+    private AttendanceStatisticRequireLogService statisticRequireLogService = new AttendanceStatisticRequireLogService();
+    private AttendanceStatisticService statisticService = new AttendanceStatisticService();
+    private AttendanceStatisticalCycleService statisticalCycleService = new AttendanceStatisticalCycleService();
+    private static final Logger logger = LoggerFactory.getLogger(AttendanceDetailStatisticQueue.class);
+
+    @Override
+    protected void execute( String logId ) throws Exception {
+        AttendanceStatisticRequireLog log = statisticRequireLogServiceAdv.get(logId);
+        if( log != null ){
+            logger.debug("system try to statistic attendance detail, logId:" + logId );
+            AttendanceStatisticalCycle attendanceStatisticalCycle  = null;
+            List<AttendanceWorkDayConfig> workDayConfigList = null;
+            List<AttendanceStatisticRequireLog> attendanceStatisticRequireLogList = null;
+            Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = null;
+
+            try {//先查询所有的法定节假日和工作日配置列表
+                workDayConfigList = workDayConfigService.getAllWorkDayConfigWithCache(false );
+            } catch ( Exception e ) {
+                logger.warn("【统计】系统在查询当月有打卡记录的员工姓名列表时发生异常!" );
+                logger.error(e);
+            }
+
+            try{//查询所有的考勤统计周期信息,并且组织成MAP
+                statisticalCycleMap = statisticalCycleService.getAllStatisticalCycleMapWithCache(false);
+            }catch(Exception e){
+                logger.warn( "【统计】系统在查询并且组织所有的考勤统计周期信息时发生异常。" );
+                logger.error(e);
+            }
+
+            //先处理所有的统计错误
+            try {
+                logger.debug( false, "准备处理恢复的统计错误信息, 所有错误统计将会重新计算......" );
+                statisticRequireLogService.resetStatisticError();
+            } catch (Exception e) {
+                logger.warn("【统计】系统在重置统计错误信息时发生异常!" );
+                logger.error(e);
+            }
+            //统计类型:PERSON_PER_MONTH|UNIT_PER_MONTH|TOPUNIT_PER_MONTH|UNIT_PER_DAY|TOPUNIT_PER_DAY
+            //统计处理状态:WAITING|PROCESSING|COMPLETE|ERROR
+            if( StringUtils.equals( "PERSON_PER_MONTH", log.getStatisticType() )){
+                logger.debug( false, "系统准备统计[员工每月统计], 员工:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+                try {
+                    attendanceStatisticalCycle = statisticalCycleService.getStatisticCycleByEmployee( log, statisticalCycleMap, false );
+                } catch (Exception e) {
+                    logger.warn("【统计】系统在根据统计需求记录信息查询统计周期信息时发生异常!" );
+                    logger.error(e);
+                }
+                if( attendanceStatisticalCycle != null ){
+                    try{
+                        statisticService.statisticEmployeeAttendanceForMonth( log, attendanceStatisticalCycle, workDayConfigList, statisticalCycleMap);
+                    }catch(Exception e){
+                        logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+                        logger.error(e);
+                    }
+                }
+            } else if ( StringUtils.equals( "UNIT_PER_MONTH", log.getStatisticType() )){
+                logger.debug( false, "系统准备统计[组织每月统计], 组织:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+                try{
+                    statisticService.statisticUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap );
+                }catch(Exception e){
+                    logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+                    logger.error(e);
+                }
+            } else if ( StringUtils.equals( "TOPUNIT_PER_MONTH", log.getStatisticType() )){
+                logger.debug( false, "系统准备统计[顶层组织每月统计], 顶层组织:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+                try{
+                    statisticService.statisticTopUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap);
+                }catch(Exception e){
+                    logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+                    logger.error(e);
+                }
+            } else if ( StringUtils.equals( "UNIT_PER_DAY", log.getStatisticType() )){
+                logger.debug( false, "系统准备统计[组织每月统计], 组织:" + log.getStatisticKey() + ", 统计日期:" + log.getStatisticDay() );
+                try{
+                    statisticService.statisticUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap, false );
+                }catch(Exception e){
+                    logger.warn( "【统计】系统在根据需求进行组织每日打卡记录分析结果统计时发生异常。" );
+                    logger.error(e);
+                }
+            } else if ( StringUtils.equals( "TOPUNIT_PER_DAY", log.getStatisticType() )){
+                logger.debug( false, "系统准备统计[顶层组织每月统计], 顶层组织:" + log.getStatisticKey() + ", 统计日期:" + log.getStatisticDay() );
+                try{
+                    statisticService.statisticTopUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap );
+                }catch(Exception e){
+                    logger.warn( "【统计】系统在根据需求进行顶层组织每日打卡记录分析结果统计时发生异常。" );
+                    logger.error(e);
+                }
+            }else{
+                logger.warn( "statistic require log can not execute, type:" + log.getStatisticType() );
+            }
+            logger.debug("["+logId+"] attendance detail record statistic task execute completed。" );
+        }else{
+            logger.warn("attandence statistic require logId not exists, id:" + logId );
+        }
+    }
+}

+ 64 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/PersonAttendanceDetailAnalyseQueue.java

@@ -0,0 +1,64 @@
+package com.x.attendance.assemble.control;
+
+import com.x.attendance.assemble.control.service.AttendanceDetailAnalyseServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceDetailServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceStatisticalCycleServiceAdv;
+import com.x.attendance.assemble.control.service.AttendanceWorkDayConfigServiceAdv;
+import com.x.attendance.entity.*;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.queue.AbstractQueue;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import java.util.*;
+
+/**
+ * 对单个员工的打卡信息进行分析的队列
+ */
+public class PersonAttendanceDetailAnalyseQueue extends AbstractQueue<String> {
+
+    protected Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+
+    private AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+    private AttendanceStatisticalCycleServiceAdv statisticalCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+    private AttendanceDetailAnalyseServiceAdv detailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
+    private AttendanceDetailServiceAdv detailServiceAdv = new AttendanceDetailServiceAdv();
+    private static final Logger logger = LoggerFactory.getLogger(PersonAttendanceDetailAnalyseQueue.class);
+
+    @Override
+    protected void execute( String detailId ) throws Exception {
+        AttendanceDetail record = detailServiceAdv.get( detailId );
+        if( record != null ){
+            logger.debug("system try to analyse attendance detail for person, Id:" + record.getId() );
+
+
+            String cacheKey = ApplicationCache.concreteCacheKey( "map#all" );
+            Element element = cache.get(cacheKey);
+            try {
+
+                Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = null;
+                if ((null != element) && (null != element.getObjectValue())) {
+                    statisticalCycleMap = (Map<String, Map<String, List<AttendanceStatisticalCycle>>>) element.getObjectValue();
+                }else{
+                    statisticalCycleMap = statisticalCycleServiceAdv.getCycleMapFormAllCycles( false );
+                }
+
+                List<AttendanceWorkDayConfig> workDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+
+                detailAnalyseServiceAdv.analyseAttendanceDetail( record, workDayConfigList, statisticalCycleMap, false );
+                logger.debug( "attendance detail analyse completed.person:" + record.getEmpName() + ", date:" + record.getRecordDateString());
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            logger.debug("["+record.getEmpName()+"]["+ record.getRecordDateString() +"] attendance detail record analyse task execute completed。" );
+        }else{
+            logger.warn("attandence detail not exists, id:" + detailId );
+        }
+
+    }
+
+
+}

+ 12 - 4
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java

@@ -20,21 +20,25 @@ public class ThisApplication {
 	public static QywxAttendanceSyncQueue qywxQueue = new QywxAttendanceSyncQueue();
 	public static QywxUnitStatisticQueue unitQywxStatisticQueue = new QywxUnitStatisticQueue();
 	public static QywxPersonStatisticQueue personQywxStatisticQueue = new QywxPersonStatisticQueue();
-
 	public static DingdingPersonStatisticQueue personStatisticQueue = new DingdingPersonStatisticQueue();
 	public static DingdingUnitStatisticQueue unitStatisticQueue = new DingdingUnitStatisticQueue();
 
+	public static PersonAttendanceDetailAnalyseQueue detailAnalyseQueue = new PersonAttendanceDetailAnalyseQueue();
+	public static AttendanceDetailStatisticQueue detailStatisticQueue = new AttendanceDetailStatisticQueue();
+
 
 	public static void init() throws Exception {
 		try {
+
 			new AttendanceSettingService().initAllSystemConfig();
-			context.schedule(AttendanceStatisticTask.class, "0 0 0/4 * * ?");
-			context.schedule(MobileRecordAnalyseTask.class, "0 0/10 * * * ?");
+
+			detailAnalyseQueue.start();
+			detailStatisticQueue.start();
 			if (BooleanUtils.isTrue(Config.dingding().getAttendanceSyncEnable())) {
 				dingdingQueue.start();
 				personStatisticQueue.start();
 				unitStatisticQueue.start();
-				context.schedule(DingdingAttendanceSyncScheduleTask.class, "0 0 1 * * ?");
+				context.schedule( DingdingAttendanceSyncScheduleTask.class, "0 0 1 * * ?" );
 				//已经将任务 放到了同步结束后执行 暂时不需要开定时任务了
 //				context.schedule(DingdingAttendanceStatisticScheduleTask.class, "0 0 3 * * ?");
 //				context.schedule(DingdingAttendanceStatisticPersonScheduleTask.class, "0 0 3 * * ?");
@@ -45,6 +49,10 @@ public class ThisApplication {
 				personQywxStatisticQueue.start();
 				context.schedule(QywxAttendanceSyncScheduleTask.class, "0 0 1 * * ?");
 			}
+
+			context.schedule(AttendanceStatisticTask.class, "0 0 0/4 * * ?");
+			context.schedule(MobileRecordAnalyseTask.class, "0 0/10 * * * ?");
+
 		} catch (Exception e) {
 			e.printStackTrace();
 		}

+ 74 - 60
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionReciveAttendance.java

@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletRequest;
 import com.google.gson.JsonElement;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceDetail;
 import com.x.attendance.entity.AttendanceScheduleSetting;
 import com.x.attendance.entity.AttendanceSelfHoliday;
@@ -26,17 +27,16 @@ public class ActionReciveAttendance extends BaseAction {
 	
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
-		Wi wrapIn = null;
-		Date datetime = null;
-		List<String> ids_temp = null;
 		DateOperation dateOperation = new DateOperation();
 		AttendanceDetail attendanceDetail = new AttendanceDetail();
-		AttendanceScheduleSetting attendanceScheduleSetting = null;
-		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
-		List<AttendanceSelfHoliday> selfHolidays = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
+//		List<String> ids_temp = null;
+//		AttendanceScheduleSetting attendanceScheduleSetting = null;
+//		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
+//		List<AttendanceSelfHoliday> selfHolidays = null;
+//		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		Boolean check = true;
 
+		Wi wrapIn = null;
 		try {
 			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
 		} catch (Exception e) {
@@ -59,6 +59,9 @@ public class ActionReciveAttendance extends BaseAction {
 				result.error(exception);
 			}
 		}
+
+		Date datetime = null;
+
 		if (check) {
 			try {
 				datetime = dateOperation.getDateFromString(wrapIn.getRecordDateString());
@@ -86,6 +89,7 @@ public class ActionReciveAttendance extends BaseAction {
 				}
 			}
 		}
+
 		if (check) {
 			if (wrapIn.getOffDutyTime() != null && wrapIn.getOffDutyTime().trim().length() > 0) {
 				try {
@@ -110,63 +114,73 @@ public class ActionReciveAttendance extends BaseAction {
 				logger.error(e, effectivePerson, request, null);
 			}
 		}
+
 		if (check) {
+			//分析保存好的考勤数据
 			try {
-				attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceDetailProcess( e, "系统在根据ID列表查询工作节假日配置信息列表时发生异常!" );
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			try {
-				topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( effectivePerson.getDebugger() );
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceDetailProcess( e, "系统在查询并且组织所有的统计周期时发生异常." );
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		
-		if (check) {
-			try{
-				ids_temp = attendanceSelfHolidayServiceAdv.getByPersonName( attendanceDetail.getEmpName() );
-				if( ids_temp != null && !ids_temp.isEmpty() ) {
-					selfHolidays = attendanceSelfHolidayServiceAdv.list( ids_temp );
-				}
-			}catch( Exception e ){
-				check = false;
-				Exception exception = new ExceptionAttendanceDetailProcess( e, "system list attendance self holiday info ids with employee name got an exception.empname:" + attendanceDetail.getEmpName() );
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		
-		if (check) {
-			try{
-				attendanceScheduleSetting = attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithPerson( attendanceDetail.getEmpName(), effectivePerson.getDebugger() );
-			}catch( Exception e ){
-				check = false;
-				Exception exception = new ExceptionAttendanceDetailProcess( e, "system get unit schedule setting for employee with unit names got an exception." + attendanceDetail.getEmpName() );
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		
-		if (check) {
-			try {
-				attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( attendanceDetail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger());
-				logger.info("打卡信息保存并且分析完成。");
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceDetailProcess(e, "系统分析员工打卡信息时发生异常!ID:" + attendanceDetail.getId());
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
+				ThisApplication.detailAnalyseQueue.send( attendanceDetail.getId() );
+			} catch ( Exception e1 ) {
+				e1.printStackTrace();
 			}
 		}
+
+//		if (check) {
+//			try {
+//				attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+//			} catch (Exception e) {
+//				check = false;
+//				Exception exception = new ExceptionAttendanceDetailProcess( e, "系统在根据ID列表查询工作节假日配置信息列表时发生异常!" );
+//				result.error(exception);
+//				logger.error(e, effectivePerson, request, null);
+//			}
+//		}
+//		if (check) {
+//			try {
+//				topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( effectivePerson.getDebugger() );
+//			} catch (Exception e) {
+//				check = false;
+//				Exception exception = new ExceptionAttendanceDetailProcess( e, "系统在查询并且组织所有的统计周期时发生异常." );
+//				result.error(exception);
+//				logger.error(e, effectivePerson, request, null);
+//			}
+//		}
+//
+//		if (check) {
+//			try{
+//				ids_temp = attendanceSelfHolidayServiceAdv.getByPersonName( attendanceDetail.getEmpName() );
+//				if( ids_temp != null && !ids_temp.isEmpty() ) {
+//					selfHolidays = attendanceSelfHolidayServiceAdv.list( ids_temp );
+//				}
+//			}catch( Exception e ){
+//				check = false;
+//				Exception exception = new ExceptionAttendanceDetailProcess( e, "system list attendance self holiday info ids with employee name got an exception.empname:" + attendanceDetail.getEmpName() );
+//				result.error(exception);
+//				logger.error(e, effectivePerson, request, null);
+//			}
+//		}
+//
+//		if (check) {
+//			try{
+//				attendanceScheduleSetting = attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithPerson( attendanceDetail.getEmpName(), effectivePerson.getDebugger() );
+//			}catch( Exception e ){
+//				check = false;
+//				Exception exception = new ExceptionAttendanceDetailProcess( e, "system get unit schedule setting for employee with unit names got an exception." + attendanceDetail.getEmpName() );
+//				result.error(exception);
+//				logger.error(e, effectivePerson, request, null);
+//			}
+//		}
+//
+//		if (check) {
+//			try {
+//				attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( attendanceDetail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger());
+//				logger.info("打卡信息保存并且分析完成。");
+//			} catch (Exception e) {
+//				check = false;
+//				Exception exception = new ExceptionAttendanceDetailProcess(e, "系统分析员工打卡信息时发生异常!ID:" + attendanceDetail.getId());
+//				result.error(exception);
+//				logger.error(e, effectivePerson, request, null);
+//			}
+//		}
 		return result;
 	}
 	

+ 4 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionDelete.java

@@ -5,6 +5,7 @@ import com.x.attendance.entity.AttendanceStatisticalCycle;
 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.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -28,6 +29,9 @@ public class ActionDelete extends BaseAction {
 				emc.beginTransaction(AttendanceStatisticalCycle.class);
 				emc.remove(attendanceStatisticalCycle, CheckRemoveType.all);
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceStatisticalCycle.class );
+
 				result.setData(new Wo(id));
 			}
 		} catch (Exception e) {

+ 4 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionSave.java

@@ -14,6 +14,7 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -80,6 +81,9 @@ public class ActionSave extends BaseAction {
 					emc.persist(attendanceStatisticalCycle, CheckPersistType.all);
 				}
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceStatisticalCycle.class );
+
 				result.setData(new Wo(attendanceStatisticalCycle.getId()));
 			} catch (Exception e) {
 				e.printStackTrace();

+ 5 - 1
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/BaseAction.java

@@ -2,10 +2,14 @@ package com.x.attendance.assemble.control.jaxrs.attendancestatisticalcycle;
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.service.UserManagerService;
+import com.x.attendance.entity.AttendanceStatisticalCycle;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import net.sf.ehcache.Ehcache;
 
 public class BaseAction extends StandardJaxrsAction{
-	
+
+	protected Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
 	protected UserManagerService userManagerService = new UserManagerService();
 	protected DateOperation dateOperation = new DateOperation();
 

+ 6 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionDelete.java

@@ -1,10 +1,13 @@
 package com.x.attendance.assemble.control.jaxrs.attendanceworkdayconfig;
 
 import javax.servlet.http.HttpServletRequest;
+
+import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
 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.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -29,6 +32,9 @@ public class ActionDelete extends BaseAction {
 				emc.beginTransaction(AttendanceWorkDayConfig.class);
 				emc.remove(attendanceWorkDayConfig, CheckRemoveType.all);
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceWorkDayConfig.class );
+
 				result.setData(new Wo(id));
 			}
 		} catch (Exception e) {

+ 4 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionSave.java

@@ -14,6 +14,7 @@ import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
@@ -95,6 +96,9 @@ public class ActionSave extends BaseAction {
 							attendanceWorkDayConfig.setConfigMonth(dateOperation.getMonth(date));
 							emc.persist(attendanceWorkDayConfig, CheckPersistType.all);
 							emc.commit();
+
+							ApplicationCache.notify( AttendanceWorkDayConfig.class );
+
 							result.setData(new Wo(attendanceWorkDayConfig.getId()));
 						} catch (Exception e) {
 							Exception exception = new ExceptionWorkDayConfigProcess(e,

+ 3 - 11
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDelete.java

@@ -22,7 +22,6 @@ public class ActionDelete extends BaseAction {
 	
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		EffectivePerson currentPerson = this.effectivePerson(request);
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			//先判断需要操作的应用信息是否存在,根据ID进行一次查询,如果不存在不允许继续操作
@@ -30,23 +29,16 @@ public class ActionDelete extends BaseAction {
 			if (null == attendanceSelfHoliday) {
 				Exception exception = new ExceptionSelfHolidayNotExists( id );
 				result.error( exception );
-				//logger.error( e, currentPerson, request, null);
 			}else{
 				emc.beginTransaction( AttendanceSelfHoliday.class );
 				emc.remove( attendanceSelfHoliday, CheckRemoveType.all );
 				emc.commit();
 				result.setData( new Wo(id) );
+
 				//根据员工休假数据来记录与这条数据相关的统计需求记录
-				List<String> ids = attendanceDetailAnalyseServiceAdv.getAnalyseAttendanceDetailIds( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime() );
+				List<String> ids = attendanceDetailAnalyseServiceAdv.listAnalyseAttendanceDetailIds( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
 				if( ListTools.isNotEmpty( ids ) ){
-					try {//查询所有的周期配置,组织成Map
-						topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( effectivePerson.getDebugger() );
-					} catch (Exception e) {
-						Exception exception = new ExceptionSelfHolidayProcess( e, "系统在查询并且组织所有的统计周期时发生异常." );
-						result.error( exception );
-						logger.error( e, currentPerson, request, null);
-					}
-					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger()  );
+					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger()  );
 				}
 			}			
 		} catch ( Exception e ) {

+ 3 - 13
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDeleteByWfDocId.java

@@ -1,13 +1,11 @@
 package com.x.attendance.assemble.control.jaxrs.selfholiday;
 
 import java.util.List;
-import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.entity.AttendanceSelfHoliday;
-import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckRemoveType;
@@ -26,7 +24,6 @@ public class ActionDeleteByWfDocId extends BaseAction {
 		logger.debug( effectivePerson, ">>>>>>>>>>method delete has been called, try to delete attendanceSelfHoliday{'wfDocId':'" + wfDocId + "'}......");
 		ActionResult<Wo> result = new ActionResult<>();
 		EffectivePerson currentPerson = this.effectivePerson(request);
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		
 		logger.debug( effectivePerson, ">>>>>>>>>>user " + currentPerson.getDistinguishedName() + "try to delete AttendanceSelfHoliday......");
 		List<String> ids = null;
@@ -48,18 +45,11 @@ public class ActionDeleteByWfDocId extends BaseAction {
 						logger.debug( effectivePerson, ">>>>>>>>>>System delete attendanceSelfHoliday success......");
 
 						// 应该只需要重新分析该用户在请假期间已经存在的打卡数据即可
-						ids = attendanceDetailAnalyseServiceAdv.getAnalyseAttendanceDetailIds(
+						ids = attendanceDetailAnalyseServiceAdv.listAnalyseAttendanceDetailIds(
 								attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(),
-								attendanceSelfHoliday.getEndTime());
+								attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
 						if ( ListTools.isNotEmpty( ids ) ) {
-							try {// 查询所有的周期配置,组织成Map
-								topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( effectivePerson.getDebugger() );
-							} catch (Exception e) {
-								Exception exception = new ExceptionSelfHolidayProcess( e, "系统在查询并且组织所有的统计周期时发生异常." );
-								result.error(exception);
-								logger.error(e, currentPerson, request, null);
-							}
-							attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger() );
+							attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
 						}
 					}
 				}

+ 12 - 20
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionSave.java

@@ -16,6 +16,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import org.apache.commons.lang3.StringUtils;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -29,7 +30,6 @@ public class ActionSave extends BaseAction {
 		ActionResult<Wo> result = new ActionResult<>();
 		Wi wrapIn = null;
 		List<AttendanceSelfHoliday> holidayList = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 
 		//获取到当前用户信息
 		EffectivePerson currentPerson = this.effectivePerson(request);
@@ -47,7 +47,6 @@ public class ActionSave extends BaseAction {
 		if( check ){
 			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 				AttendanceSelfHoliday attendanceSelfHoliday = null;
-//				AttendanceSelfHoliday attendanceSelfHoliday = new AttendanceSelfHoliday();
 
 				if( wrapIn != null && StringUtils.isNoneEmpty( wrapIn.getEmployeeName() )
 						&& StringUtils.isNoneEmpty( wrapIn.getEmployeeNumber() )
@@ -60,11 +59,11 @@ public class ActionSave extends BaseAction {
 					if(StringUtils.isNotEmpty( wrapIn.getBatchFlag() ) ){
 						holidayList = attendanceSelfHolidayServiceAdv.listWithBatchFlag( wrapIn.getBatchFlag() );
 						if(ListTools.isNotEmpty( holidayList )){
-							logger.info("++++++++先根据batchFlag删除原来的数据,然后再进行新数据的保存+++++++++" );
+							logger.info("先根据batchFlag删除原来的数据,然后再进行新数据的保存" );
 							for( AttendanceSelfHoliday holiday : holidayList ){
 								emc.remove( emc.find(holiday.getId(), AttendanceSelfHoliday.class ), CheckRemoveType.all );
 							}
-							logger.info("++++++++删除" + holidayList.size() + "条旧请假信息数据。" );
+							logger.info("删除" + holidayList.size() + "条旧请假信息数据。" );
 						}
 					}
 
@@ -75,7 +74,7 @@ public class ActionSave extends BaseAction {
 							//更新已经存在的信息
 							wrapIn.copyTo( attendanceSelfHoliday );
 							attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
-							logger.info("++++++++更新:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
+							logger.info("更新:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
 							emc.check( attendanceSelfHoliday, CheckPersistType.all);
 						}else{
 							attendanceSelfHoliday = new AttendanceSelfHoliday();
@@ -83,7 +82,7 @@ public class ActionSave extends BaseAction {
 							//使用参数传入的ID作为记录的ID
 							attendanceSelfHoliday.setId( wrapIn.getId() );
 							attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
-							logger.info("++++++++新增:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
+							logger.info("新增:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
 							emc.persist( attendanceSelfHoliday, CheckPersistType.all);
 						}
 					}else{
@@ -92,7 +91,7 @@ public class ActionSave extends BaseAction {
 
 						wrapIn.copyTo( attendanceSelfHoliday );
 						attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
-						logger.info("++++++++新增,无ID:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
+						logger.debug("新增,无ID:gson.toJson( attendanceSelfHoliday ) = " + gson.toJson( attendanceSelfHoliday ) );
 						emc.persist( attendanceSelfHoliday, CheckPersistType.all);
 						result.setData( new Wo( attendanceSelfHoliday.getId() ) );
 					}
@@ -101,26 +100,20 @@ public class ActionSave extends BaseAction {
 					
 					//根据员工休假数据来记录与这条数据相关的统计需求记录
 					//new AttendanceDetailAnalyseService().recordStatisticRequireLog( attendanceSelfHoliday );
-					logger.info("++++++++休假数据有变动,对该员工的该请假时间内的所有打卡记录进行分析......" );
+					logger.debug("休假数据有变动,对该员工的该请假时间内的所有打卡记录进行分析......" );
+
 					//休假数据有更新,对该员工的该请假时间内的所有打卡记录进行分析
-					List<String> ids = attendanceDetailAnalyseServiceAdv.getAnalyseAttendanceDetailIds( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime() );
+					List<String> ids = attendanceDetailAnalyseServiceAdv.listAnalyseAttendanceDetailIds(attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
 					if( ListTools.isNotEmpty( ids ) ){
-						try {//查询所有的周期配置,组织成Map
-							topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( effectivePerson.getDebugger() );
-						} catch (Exception e) {
-							Exception exception = new ExceptionSelfHolidayProcess( e, "系统在查询并且组织所有的统计周期时发生异常." );
-							result.error( exception );
-							logger.error( e, currentPerson, request, null);
-						}
-						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger()  );
+						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetailWithIds(ids, effectivePerson.getDebugger() );
 					}
 				}else{
 					if( jsonElement == null ){
-						logger.info("++++++++传入的员工请假信息JSON数据为空......" );
+						logger.debug("传入的员工请假信息JSON数据为空......" );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的员工请假信息JSON数据为空,无法保存数据信息,请检查数据内容!" );
 						result.error( exception );
 					}else {
-						logger.info("++++++++传入的数据不符合请假数据接口要求......" );
+						logger.debug("传入的数据不符合请假数据接口要求......" );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的数据不符合请假数据接口要求,请检查数据内容:" + jsonElement.getAsString() );
 						result.error( exception );
 					}
@@ -132,7 +125,6 @@ public class ActionSave extends BaseAction {
 				logger.error( e, currentPerson, request, null);
 			}
 		}
-		logger.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" );
 		return result;
 	}
 	

+ 2 - 27
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/processor/thread/OperatorDataAnalyse.java

@@ -20,9 +20,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 public class OperatorDataAnalyse implements Runnable{
 
 	private static  Logger logger = LoggerFactory.getLogger( OperatorDataAnalyse.class );
-	private AttendanceSelfHolidayServiceAdv attendanceSelfHolidayServiceAdv = null;
 	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = null;
-	private AttendanceScheduleSettingServiceAdv attendanceScheduleSettingServiceAdv = null;
 	private AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = null;
 	private StatusSystemImportOpt statusSystemImportOpt = null;
 	private EntityAnalyseData entityAnalyseData = null;
@@ -30,8 +28,6 @@ public class OperatorDataAnalyse implements Runnable{
 	private Boolean debugger = false;
 	
 	public OperatorDataAnalyse( EntityAnalyseData entityAnalyseData, Boolean debugger ) {
-		attendanceScheduleSettingServiceAdv = new AttendanceScheduleSettingServiceAdv();
-		attendanceSelfHolidayServiceAdv = new AttendanceSelfHolidayServiceAdv();
 		attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
 		statusSystemImportOpt = StatusSystemImportOpt.getInstance();
 		attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
@@ -45,40 +41,19 @@ public class OperatorDataAnalyse implements Runnable{
 	}
 	
 	private void execute( EntityAnalyseData entityAnalyseData ) {
-		List<String> ids_temp = null;
 		List<String> detail_ids = entityAnalyseData.getDetailIds();
-		List<AttendanceSelfHoliday> selfHolidays = null;
-		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = entityAnalyseData.getAttendanceWorkDayConfigList();
-		AttendanceScheduleSetting attendanceScheduleSetting = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = entityAnalyseData.getTopUnitAttendanceStatisticalCycleMap();
 		AttendanceDetail detail = null;
 		
 		statusSystemImportOpt.setProcessing( true );
 		statusSystemImportOpt.setProcessing_analysis( true );
 		
 		if ( detail_ids != null && !detail_ids.isEmpty() ) {
-			try{
-				ids_temp = attendanceSelfHolidayServiceAdv.getByPersonName( entityAnalyseData.getPersonName() );
-				if( ids_temp != null && !ids_temp.isEmpty() ) {
-					selfHolidays = attendanceSelfHolidayServiceAdv.list( ids_temp );
-				}
-			}catch( Exception e ){
-				logger.warn( "system list attendance self holiday info ids with employee name got an exception.empname:" + entityAnalyseData.getPersonName() );
-				logger.error(e);
-			}
-			
-			try{
-				attendanceScheduleSetting =  attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithPerson( entityAnalyseData.getPersonName(), debugger );
-			}catch( Exception e ){
-				logger.warn( "system get unit schedule setting for employee with unit names got an exception." + entityAnalyseData.getPersonName() );
-				logger.error(e);
-			}
-			
+
 			for ( String id: detail_ids ) {
 				try {
 					detail = attendanceDetailServiceAdv.get( id );
 					if ( detail != null ) {
-						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
+						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, debugger );
 						statusSystemImportOpt.increaseProcess_analysis_count(1);
 					} else {
 						statusSystemImportOpt.increaseProcess_analysis_error(1);

+ 532 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseCoreService.java

@@ -0,0 +1,532 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.factory.AttendanceStatisticRequireLogFactory;
+import com.x.attendance.assemble.control.jaxrs.attendancedetail.AttendanceCycles;
+import com.x.attendance.entity.*;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+
+/**
+ * 考勤打卡记录分析服务类
+ * @author LIYI
+ *
+ */
+class AttendanceDetailAnalyseCoreService {
+	
+	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseCoreService.class );
+	private AttendanceSelfHolidayService attendanceSelfHolidayService = new AttendanceSelfHolidayService();
+	private AttendanceScheduleSettingService attendanceScheduleSettingService = new AttendanceScheduleSettingService();
+	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
+	private DateOperation dateOperation = new DateOperation();
+	private UserManagerService userManagerService = new UserManagerService();
+
+
+	/**
+	 * 打卡记录分析核心方法,分析一条打卡记录信息<br/>
+		<b>迟到</b>:晚于最迟“迟到起算时间”,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
+		<b>早退</b>:下班打卡时间早于“迟到起算时间”,并且工作当日时间不满9个小时,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
+		<b>异常</b>:缺少签到退中的1条打卡数据 或者 上下班打卡时间都在最迟起算时间内,不满9个小时,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
+		<b>缺勤</b>:当天没有打卡数据,并且当天是工作日(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)
+	 * @param detail
+	 * @param attendanceScheduleSetting
+	 * @param dateOperation
+	 * @throws Exception 
+	 */
+	AttendanceDetail analyseCore( AttendanceDetail detail, AttendanceScheduleSetting attendanceScheduleSetting, DateOperation dateOperation, Boolean debugger ) throws Exception {
+		if( dateOperation == null ){
+			dateOperation = new DateOperation();
+		}
+		if( detail == null ){
+			throw new Exception("detail is null!" );
+		}
+		//排班规则 早上9:00 - 晚上18:00
+		/**
+		 * 新规则
+		 * 早上9:00 - 中午12:00
+		 * 中午13:00 - 晚上18:00
+		 */
+		if( attendanceScheduleSetting == null ){
+			throw new Exception("attendanceScheduleSetting is null, empName:" + detail.getEmpName() );
+		}
+
+		Date onDutyTime = null, offDutyTime = null, middleDutyTime = null;
+		//上班签到时间
+		Date onWorkTime = null, offWorkTime = null, middleWorkStartTime = null, middleWorkEndTime = null;
+		Date lateStartTime = null, leaveEarlyStartTime = null, absenceStartTime = null;
+		Date morningEndTime = null;
+
+		//考勤异常时段
+//		StringBuffer abnormalDutyDayTime = new StringBuffer();
+		
+		//先初始化当前打卡信息中的上下班时间要求,该要求是是根据员工所在组织排班信息获取到的
+		//中午打卡时间要求 13:30
+		try {
+			logger.debug( debugger, ">>>>>>>>>>格式化[上班签到时间]onWorkTime=" +  detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+			onWorkTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+			onWorkTime = null;
+			logger.debug( debugger, ">>>>>>>>>>系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime());
+			logger.error(e);
+		}
+
+		try {
+			logger.debug(debugger, ">>>>>>>>>>格式化[中午开始时间]middleStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getMiddayRestStartTime());
+			middleWorkStartTime = dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestStartTime());
+			logger.debug(debugger, ">>>>>>>>>>格式化[中午结束时间]middleEndTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getMiddayRestEndTime());
+			middleWorkEndTime = dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestEndTime());
+		} catch (Exception e) {
+			detail.setDescription(detail.getDescription() + "; 系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getMiddayRestStartTime() + " - " + attendanceScheduleSetting.getMiddayRestEndTime());
+			onWorkTime = null;
+			logger.debug(debugger, ">>>>>>>>>>系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getMiddayRestStartTime() + " - " + attendanceScheduleSetting.getMiddayRestEndTime());
+			logger.error(e);
+		}
+
+		try {
+			logger.debug( debugger, ">>>>>>>>>>格式化[下班签退时间]offWorkTime=" +  detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			offWorkTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			offWorkTime = null;
+			logger.debug( debugger, ">>>>>>>>>>系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			logger.error(e);
+		}
+		
+		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getLateStartTime() ) ){
+			try {
+				lateStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime() );
+				lateStartTime = null;
+				logger.warn( "系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime());
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>迟到时间设置为空!系统将不判断迟到情况");
+		}
+		
+		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getLeaveEarlyStartTime() ) ){
+			try {
+				logger.debug( debugger, ">>>>>>>>>>格式化[早退起算时间]leaveEarlyStartTime=" +  detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
+				leaveEarlyStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
+				leaveEarlyStartTime = null;
+				logger.warn( "系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>早退时间设置为空!系统将不判断早退情况");
+		}
+		
+		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getAbsenceStartTime() ) ){
+			try {
+				logger.debug( debugger, ">>>>>>>>>>格式化[缺勤起算时间]absenceStartTime=" +  detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
+				absenceStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
+				absenceStartTime = null;
+				logger.warn( "系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>上午缺勤时间设置为空!系统将不判上午缺勤情况");
+		}
+		
+		try {
+			//上午工作结束时间取中午打卡开始时间
+
+			logger.debug(debugger, ">>>>>>>>>>格式化[上午工作结束时间]morningEndTime=" + attendanceScheduleSetting.getMiddayRestStartTime());
+			morningEndTime = dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestStartTime());
+		} catch (Exception e) {
+			detail.setDescription(detail.getDescription() + "; 系统进行时间转换时发生异常,morningEndTime=" + detail.getRecordDateString() + attendanceScheduleSetting.getMiddayRestStartTime());
+			morningEndTime = null;
+			logger.warn("系统进行时间转换时发生异常,morningEndTime=" + detail.getRecordDateString() + attendanceScheduleSetting.getMiddayRestStartTime());
+			logger.error(e);
+		}
+
+		//规则:上午打卡时间、下班打卡时间、中午开始时间、中午结束时间
+		if (onWorkTime != null && offWorkTime != null && middleWorkStartTime != null && middleWorkEndTime != null) {
+			logger.debug( debugger, ">>>>>>>>>>上下班排班信息获取正常:onWorkTime=" +  onWorkTime + ", offWorkTime="+offWorkTime );
+			//获取员工签到时间(签到规则,上午9:00)
+			try {
+				if( detail.getOnDutyTime() == null || detail.getOnDutyTime().isEmpty() ){
+					logger.debug( debugger, ">>>>>>>>>>onDutyTime 为空 " );
+					onDutyTime = null;
+				}else{
+					logger.debug( debugger, ">>>>>>>>>>格式化onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+					onDutyTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+				}
+			} catch (Exception e) {
+				onDutyTime = null;
+				logger.warn( "系统进行时间转换时发生异常,onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+				logger.error(e);
+			}
+
+			//获取员工中午签到时间---------------------------------------------
+			try {
+				if ( StringUtils.isEmpty(detail.getMiddayRestStartTime())) {
+					logger.debug(debugger, "middayRestStartTime 为空 ");
+					middleDutyTime = null;
+				} else {
+					logger.debug(debugger, "middayRestStartTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime());
+					middleDutyTime = dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestStartTime());
+				}
+			} catch (Exception e) {
+				middleDutyTime = null;
+				logger.warn("系统进行时间转换时发生异常,middayRestStartTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime());
+				logger.error(e);
+			}
+
+			//获取员工签退时间(签退规则,下午18:00)
+			try {
+				if( detail.getOffDutyTime() == null || detail.getOffDutyTime().isEmpty() ){
+					logger.debug( debugger, ">>>>>>>>>>offDutyTime 为空" );
+					offDutyTime = null;
+				}else{
+					logger.debug( debugger, ">>>>>>>>>>格式化offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+					offDutyTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+				}
+			} catch (Exception e) {
+				offDutyTime = null;
+				logger.warn( "系统进行时间转换时发生异常,offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+				logger.error(e);
+			}
+
+			
+			//=========================================================================================================
+			//=====如果员工没有签到并且没有签退,一条打卡时间都没有,那么是算缺勤的========================================
+			//=========================================================================================================
+			if (onDutyTime == null && offDutyTime == null && middleDutyTime == null) {
+				//if( detail.getIsGetSelfHolidays()  && "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ) ){
+				if( detail.getIsGetSelfHolidays()  ){
+					logger.debug( debugger, ">>>>>>>>>>请幸运,全天请假不计缺勤。" );
+					detail.setAttendance( 0.0 );
+					detail.setIsAbsent( false );
+					detail.setAbsence( 0.0 );
+					detail.setAbsentDayTime("无");
+					detail.setWorkTimeDuration( 0L );
+				}else{
+					if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
+						|| detail.getIsHoliday() //或者是节假日
+					){
+						logger.debug( debugger, ">>>>>>>>>>未请假,不是工作日,不计缺勤。" );
+						detail.setAttendance( 0.0 );
+						detail.setIsAbsent( false );
+						detail.setAbsence( 0.0 );
+						detail.setAbsentDayTime("无");
+						detail.setWorkTimeDuration( 0L );
+					}else{
+						logger.debug( debugger, ">>>>>>>>>>未请假,工作日,计缺勤1天。" );
+						detail.setAttendance( 0.0 );
+						detail.setIsAbsent( true );
+						detail.setAbsence( 1.0 );
+						detail.setAbsentDayTime("全天");
+						detail.setWorkTimeDuration( 0L );
+					}
+				}
+			}else{
+				//=========================================================================================================
+				//=====上午  如果员工已经签到================================================================================
+				//=========================================================================================================
+				if( onDutyTime != null ){
+					logger.debug( debugger, ">>>>>>>>>>上午打过卡,时间:onDutyTime=" + onDutyTime + ", 上午工作结束时间:morningEndTime=" + morningEndTime );					
+					//absenceStartTimes可以不配置,如果不配置,则为null
+					//上午签到过了,如果排班设置里已经配置过了旷工起算时间,那么判断员工是否已经缺勤,如果未休假,则视为缺勤半天
+					if( absenceStartTime != null && onDutyTime.after( absenceStartTime )){
+						logger.debug( debugger, ">>>>>>>>>>上午打卡时间晚于缺勤计时时间......" );
+						if( detail.getIsGetSelfHolidays()  && ("上午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
+							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,出勤只算半天,但请过假了不算缺勤" );
+							detail.setIsAbsent( false );
+							detail.setAbsence(0.0);
+						}else{
+							if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
+									|| detail.getIsHoliday() //或者是节假日
+								){
+								logger.debug( debugger, ">>>>>>>>>>休息天,不算缺勤,出勤最多只能算半天" );
+								detail.setIsAbsent( false );
+								detail.setAbsence(0.0);
+							}else{
+								logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,缺勤半天,出勤最多只能算半天" );
+								detail.setIsAbsent( true );
+								composeAbsenceStatusForAttendanceDetail(detail);
+								detail.setAbsentDayTime("上午");
+							}
+						}
+						//缺勤直接扣半天出勤, 请假不算出勤,所以也只有半天
+						composeAttendanceStatusForAttendanceDetail(detail);
+					}else if( lateStartTime != null && onDutyTime.after( lateStartTime )){ 
+						//上午签到过了,如果排班设置里已经配置过了迟到起算时间,那么判断员工是否已经迟到,如果未休假
+						detail.setAttendance( 1.0 );//迟到没关系,出勤时间不用扣半天
+						logger.debug( debugger, ">>>>>>>>>>上午打卡时间晚于迟到计时时间......" );
+						if( detail.getIsGetSelfHolidays()  && ("上午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))
+						){
+							logger.debug( debugger, ">>>>>>>>>>请幸运,请过假了不算迟到" );
+							detail.setLateTimeDuration( 0L ); //请假了不算迟到
+							detail.setIsLate(false );//请假了不算迟到
+						}else{
+							if( ( detail.getIsWeekend()  && !detail.getIsWorkday()) //周末,并且未调休为工作日
+									|| detail.getIsHoliday() //或者是节假日
+								){
+								detail.setLateTimeDuration( 0L );
+								detail.setIsLate( false );
+								logger.debug( debugger, ">>>>>>>>>>休息天,不算迟到" );
+							}else{
+								if( onDutyTime == null || offDutyTime == null ){
+									detail.setIsAbnormalDuty( true );
+								}else{
+									long minutes = dateOperation.getMinutes( onWorkTime, onDutyTime ); //迟到计算从上班时间开始计算,不是迟到起算时间
+									detail.setLateTimeDuration( minutes );//没请假算迟到时长 
+									detail.setIsLate( true );//没请假算迟到
+									logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,计迟到一次,迟到时长:minutes=" + minutes );
+								}
+							}
+						}
+						long minutes = dateOperation.getMinutes( onDutyTime, morningEndTime );
+						logger.debug( debugger, ">>>>>>>>>>上午工作时长, 从"+onDutyTime+"到"+morningEndTime+" :minutes=" + minutes + "分钟。" );
+						detail.setWorkTimeDuration( minutes );//记录上午的工作时长
+					}else{//上午正常打卡
+						long minutes = dateOperation.getMinutes( onWorkTime, morningEndTime );
+						logger.debug( debugger, ">>>>>>>>>>上午工作时长, 从"+onDutyTime+"到"+morningEndTime+" :minutes=" + minutes + "分钟。" );
+						detail.setWorkTimeDuration( minutes );//记录上午的工作时长
+					}
+
+				}else{
+					logger.debug( debugger, ">>>>>>>>>>员工上午未打卡,异常状态......" );
+					if( detail.getIsGetSelfHolidays() && ("上午".equalsIgnoreCase( detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))
+					){
+						logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,不需要打卡,不算异常" );
+						detail.setIsAbsent( false );
+					}else{
+						if( ( detail.getIsWeekend()&& !detail.getIsWorkday() ) //周末,并且未调休为工作日
+								|| detail.getIsHoliday() //或者是节假日
+							){
+							logger.debug( debugger, ">>>>>>>>>>休息天,不算打卡异常,本来就不需要打卡" );
+							detail.setAbnormalDutyDayTime("无");
+							detail.setIsAbnormalDuty( false );
+						}else{
+							logger.debug(debugger, ">>>>>>>>>>呵呵,没请假,算缺勤。");
+							//========================== 是否异常 =================================
+//							abnormalDutyDayTime.append("上午");
+//							detail.setAbnormalDutyDayTime(abnormalDutyDayTime.toString());
+//							detail.setIsAbnormalDuty(true);
+							//===================== 记录缺勤 =========================
+							detail.setIsAbsent(true);
+							composeAbsenceStatusForAttendanceDetail(detail);
+							detail.setAbsentDayTime("上午");
+							//===================== 记录出勤 =========================
+							composeAttendanceStatusForAttendanceDetail(detail);
+							//detail.setAttendance( 0.5 ); //上午打卡异常,不知道算不算出勤时间
+						}
+					}
+					logger.debug( debugger, ">>>>>>>>>>上午工作时长, 未打卡:minutes= 0 分钟。" );
+					detail.setWorkTimeDuration( 0L );//记录上午的工作时长
+				}
+
+
+				//=========================================================================================================
+				//=====中午  如果员工已经签到================================================================================
+				//=========================================================================================================
+				if(middleDutyTime == null || !middleWorkStartTime.before(middleDutyTime) || !middleWorkEndTime.after(middleDutyTime)){
+//					===============  异常  ===============
+					/*if(abnormalDutyDayTime.length() > 0){
+						detail.setAbnormalDutyDayTime("|中午");
+					}else {
+						detail.setAbnormalDutyDayTime("中午");
+					}
+
+					detail.setIsAbnormalDuty(true);*/
+					if (detail.getIsGetSelfHolidays() && ("上午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase(detail.getSelfHolidayDayTime()))) {
+						logger.debug(debugger, ">>>>>>>>>>很幸运,请假不计考勤,出勤只算半天,但请过假了不算缺勤");
+						detail.setIsAbsent(false);
+						detail.setAbsence(0.0);
+					} else {
+						if ((detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
+								|| detail.getIsHoliday() //或者是节假日
+						) {
+							logger.debug(debugger, ">>>>>>>>>>休息天,不算缺勤,出勤最多只能算半天");
+							detail.setIsAbsent(false);
+							detail.setAbsence(0.0);
+						} else {
+							logger.debug(debugger, ">>>>>>>>>>呵呵,没请假,缺勤半天,出勤最多只能算半天");
+							//===================== 记录缺勤 =========================
+							detail.setIsAbsent(true);
+							composeAbsenceStatusForAttendanceDetail(detail);
+							detail.setAbsentDayTime("中午");
+							//===================== 记录出勤 =========================
+							composeAttendanceStatusForAttendanceDetail(detail);
+							detail.setAbnormalDutyDayTime("中午");
+							detail.setIsAbnormalDuty(true);
+
+						}
+					}
+
+				}
+
+				//=========================================================================================================
+				//=====下午  如果员工已经签退================================================================================
+				//=========================================================================================================
+				if( offDutyTime != null ){
+					logger.debug( debugger, ">>>>>>>>>>早退计时时间:leaveEarlyStartTime=" + leaveEarlyStartTime );
+					long minutes = dateOperation.getMinutes( morningEndTime, offDutyTime);
+					logger.debug( debugger, ">>>>>>>>>>下午工作时长, 从"+morningEndTime+"到"+offDutyTime+" :minutes=" + minutes + "分钟。" );
+					detail.setWorkTimeDuration( detail.getWorkTimeDuration() + minutes );//记录上午的工作时长 + 下午工作时长
+					logger.debug( debugger, ">>>>>>>>>>全天工作时长, :minutes=" + detail.getWorkTimeDuration() + "分钟。" );
+					if( leaveEarlyStartTime != null && offDutyTime.before( leaveEarlyStartTime )){
+						logger.debug( debugger, ">>>>>>>>>>下午打卡时间早于早退计时时间......" );
+						if( detail.getIsGetSelfHolidays() && ("下午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
+							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,出勤只算半天,但请过假了不算早退" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+							//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤时间
+						}else{
+							if( ( detail.getIsWeekend() && !detail.getIsWorkday() ) //周末,并且未调休为工作日
+									|| detail.getIsHoliday() //或者是节假日
+							){
+								logger.debug( debugger, ">>>>>>>>>>休息天,不算早退" );
+								detail.setLeaveEarlierTimeDuration( 0L );
+								detail.setIsLeaveEarlier( false );
+								//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤
+							}else{
+//								minutes = dateOperation.getMinutes( offDutyTime, leaveEarlyStartTime );
+								minutes = dateOperation.getMinutes( offDutyTime, offWorkTime );
+								detail.setLeaveEarlierTimeDuration(minutes); //早退时间
+//								detail.setIsLeaveEarlier( true );
+								//===================== 记录缺勤 =========================
+								detail.setIsAbsent(true);
+								composeAbsenceStatusForAttendanceDetail(detail);
+								detail.setAbsentDayTime("下午");
+								//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤
+								//=========================== 记录出勤 =========================
+								composeAttendanceStatusForAttendanceDetail(detail);
+							}
+						}
+						//在早退起算之后,并在下班时间之前
+					} else if ((leaveEarlyStartTime != null && offDutyTime.after(leaveEarlyStartTime)) && offDutyTime.before(offWorkTime)) {
+						logger.debug(debugger, ">>>>>>>>>>下午打卡时间晚于早退计时时间早于下班时间......");
+						if (detail.getIsGetSelfHolidays() && ("下午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase(detail.getSelfHolidayDayTime()))) {
+							logger.debug(debugger, ">>>>>>>>>>请幸运,请假不计考勤,出勤只算半天,但请过假了不算早退");
+							detail.setLeaveEarlierTimeDuration(0L);
+							detail.setIsLeaveEarlier(false);
+							//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤时间
+						} else {
+							if ((detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
+									|| detail.getIsHoliday() //或者是节假日
+							) {
+								logger.debug(debugger, ">>>>>>>>>>休息天,不算早退");
+								detail.setLeaveEarlierTimeDuration(0L);
+								detail.setIsLeaveEarlier(false);
+								//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤
+							} else {
+//								minutes = dateOperation.getMinutes(offDutyTime, leaveEarlyStartTime);
+								minutes = dateOperation.getMinutes(offDutyTime, offWorkTime);
+								detail.setLeaveEarlierTimeDuration(minutes); //早退时间
+								detail.setIsLeaveEarlier(true);
+
+							}
+						}
+					}
+				}else{
+					//如果打卡是今天,但是还没有到下班打卡时间
+					if(  detail.getRecordDateString().equals( dateOperation.getNowDate() )  && dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffWorkTime()).after( new Date() ) ) {
+						detail.setAbnormalDutyDayTime("无");
+						detail.setIsAbnormalDuty(false);
+						logger.debug( debugger, ">>>>>>>>>>还没有到下班打卡时间,先不分析结果。" );
+					}else {
+						logger.debug( debugger, ">>>>>>>>>>员工下午未打卡,属于异常状态......" );
+						//员工未签退,算缺勤了半天,出勤率: - 0.5
+						if( detail.getIsGetSelfHolidays()  && ("下午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
+							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,不需要打卡,不算异常状态" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+							composeAttendanceStatusForAttendanceDetail(detail);
+							//detail.setAttendance( detail.getAttendance() - 0.5 );
+						}else{
+							if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
+									|| detail.getIsHoliday() //或者是节假日
+								){
+								logger.debug( debugger, ">>>>>>>>>>休息天,不算异常" );
+								detail.setAbnormalDutyDayTime("无");
+								detail.setIsAbnormalDuty(false);
+							}else{
+//								if(abnormalDutyDayTime.length() > 0){
+//									detail.setAbnormalDutyDayTime("|下午");
+//								}else {
+//									detail.setAbnormalDutyDayTime("下午");
+//								}
+								//===================== 记录缺勤 =========================
+								detail.setIsAbsent(true);
+								composeAbsenceStatusForAttendanceDetail(detail);
+								detail.setAbsentDayTime("下午");
+								//=========================== 记录出勤 =========================
+								composeAttendanceStatusForAttendanceDetail(detail);
+								detail.setIsAbnormalDuty(true);
+								logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,未打卡,算异常状态。" );
+							}
+						}						
+					}
+					logger.debug( debugger, ">>>>>>>>>>全天工作时长,[下午未打卡,只算上午的工作时长] :minutes=" + detail.getWorkTimeDuration() + "分钟。" );
+				}
+			}
+			
+			
+			//=========================================================================================================
+			//=====如果上下班都打卡了,但是工作时间没有9小时,那么属于工时不足(如果迟到了,就算迟到,不算工时不足)========================================
+			//=========================================================================================================
+			if( onDutyTime != null && offDutyTime != null){
+				if( ( detail.getIsWeekend() && !detail.getIsWorkday() ) //周末,并且未调休为工作日
+						|| detail.getIsHoliday() //或者是节假日
+					){
+					//没事
+				}else{
+					if( !detail.getIsGetSelfHolidays() ){ // 没请假
+						//计算工时
+						long minutes = dateOperation.getMinutes( onDutyTime, offDutyTime);
+						if( minutes < (60*9)){
+							logger.debug( debugger, ">>>>>>>>>>签到时间["+onDutyTime+"],签退时间["+offDutyTime+"],工作时间:"+minutes+"分钟!工时不足!" );
+							if( !detail.getIsLate() ){
+								detail.setIsLackOfTime(true);//工时不足
+							}
+						}
+					}
+				}
+			}
+			
+			detail.setRecordStatus( 1 );
+		}
+		return detail;
+	}
+
+	/**
+	 * 分析打卡信息,为打卡数据计算缺勤天数信息
+	 * @param detail
+	 */
+	private void composeAbsenceStatusForAttendanceDetail(AttendanceDetail detail) {
+		Double absence = detail.getAbsence();
+		if (absence < 1.0) {
+			detail.setAbsence(absence + 0.5);
+		}
+	}
+
+	//
+
+	/**
+	 * 分析打卡信息,为打卡数据计算出勤天数信息
+	 * @param detail
+	 */
+	private void composeAttendanceStatusForAttendanceDetail(AttendanceDetail detail) {
+		Double attendance = detail.getAttendance();
+		if (attendance > 0.0) {
+			detail.setAttendance(attendance - 0.5);
+		}
+	}
+
+}

+ 401 - 767
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseService.java

@@ -6,6 +6,11 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.tools.ListTools;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
 import org.apache.commons.lang3.StringUtils;
 
 import com.x.attendance.assemble.common.date.DateOperation;
@@ -30,23 +35,26 @@ import com.x.base.core.project.logger.LoggerFactory;
  *
  */
 public class AttendanceDetailAnalyseService {
-	
+
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseService.class );
 	private AttendanceSelfHolidayService attendanceSelfHolidayService = new AttendanceSelfHolidayService();
 	private AttendanceScheduleSettingService attendanceScheduleSettingService = new AttendanceScheduleSettingService();
-	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
+	private AttendanceStatisticalCycleService statisticalCycleService = new AttendanceStatisticalCycleService();
+	private AttendanceWorkDayConfigService workDayConfigService = new AttendanceWorkDayConfigService();
+	private AttendanceDetailAnalyseCoreService attendanceDetailAnalyseCoreService = new AttendanceDetailAnalyseCoreService();
 	private DateOperation dateOperation = new DateOperation();
 	private UserManagerService userManagerService = new UserManagerService();
-	
+
 	/**
-	 * 根据员工姓名,开始日期和结束日期获取日期范围内所有的打卡记录信息ID列表,从开始日期0点,到结束日期23点59分
+	 * 根据员工姓名\开始日期\结束日期查询日期范围内所有的打卡记录信息ID列表<br/>
+	 * 时间从开始日期0点,到结束日期23点59分
 	 * @param empName
 	 * @param startDate
 	 * @param endDate
 	 * @return
 	 * @throws Exception
 	 */
-	public List<String> getAnalyseAttendanceDetailIds( EntityManagerContainer emc, String empName, Date startDate, Date endDate )throws Exception{		
+	public List<String> listAnalyseAttendanceDetailIds( EntityManagerContainer emc, String empName, Date startDate, Date endDate )throws Exception{
 		Business business = null;
 		List<String> ids = null;
 		String startDateString = null, endDateString = null;
@@ -56,113 +64,154 @@ public class AttendanceDetailAnalyseService {
 		ids = business.getAttendanceDetailFactory().getUserAnalysenessDetails( empName, startDateString, endDateString);
 		return ids;
 	}
-	
+
 	/**
-     * 根据员工姓名,开始日期和结束日期重新分析所有的打卡记录
-     * 一般在用户补了休假记录的时候使用,补充了休假记录,需要将休假日期范围内的所有打卡记录重新分析,并且触发相关月份的统计
-     * @param empName
-     * @param startDate
-     * @param endDate
-     * @return
-     * @throws Exception
-     */
-	public Boolean analyseAttendanceDetails( EntityManagerContainer emc, String empName, Date startDate, Date endDate, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
-		Business business = null;
-		List<String> ids = null;
-		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
-		List<AttendanceDetail> attendanceDetailList = null;
-		
-		business = new Business(emc);
-		ids = getAnalyseAttendanceDetailIds( emc, empName, startDate, endDate );
-		if( ids == null || ids.isEmpty() ){
-			logger.debug( debugger, ">>>>>>>>>>attendance detail info ids not exists for emp{'empName':'"+empName+"','startDate':'"+startDate+"','endDate':'"+endDate+"'}");
+	 * 对一组的打卡信息数据进行分析
+	 * @param emc
+	 * @param detailIds
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetailWithIds(EntityManagerContainer emc, List<String> detailIds, Boolean debugger ) throws Exception{
+		if( ListTools.isEmpty( detailIds ) ){
 			return true;
 		}
-		attendanceDetailList = business.getAttendanceDetailFactory().list( ids );
-		if( attendanceDetailList == null || attendanceDetailList.isEmpty() ){
-			logger.debug( debugger, ">>>>>>>>>>attendance detail info not exists for emp{'empName':'"+empName+"','startDate':'"+startDate+"','endDate':'"+endDate+"'}");
+		analyseAttendanceDetails( emc, emc.list( AttendanceDetail.class, detailIds ), debugger );
+		logger.debug( "employee attendance detail analyse over!" );
+		return true;
+	}
+
+	/**
+	 * 对一组的打卡信息数据进行分析
+	 * @param emc
+	 * @param detailList
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetails( EntityManagerContainer emc, List<AttendanceDetail> detailList, Boolean debugger ) throws Exception{
+		if( ListTools.isEmpty( detailList ) ){
 			return true;
 		}
-		attendanceWorkDayConfigList = business.getAttendanceWorkDayConfigFactory().listAll();
-		for( AttendanceDetail detail : attendanceDetailList ){
+		List<AttendanceWorkDayConfig> workDayConfigList = workDayConfigService.getAllWorkDayConfigWithCache(debugger);
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = statisticalCycleService.getAllStatisticalCycleMapWithCache(debugger);
+
+		for( AttendanceDetail detail : detailList ){
 			try{
-				analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+				analyseAttendanceDetail( emc, detail, workDayConfigList, statisticalCycleMap, debugger );
 			}catch(Exception e){
-				logger.info( "employee attenance detail analyse got an exception:["+detail.getEmpName()+"]["+detail.getRecordDateString()+"]");
+				logger.debug( "employee attendance detail analyse got an exception:["+detail.getEmpName()+"]["+detail.getRecordDateString()+"]" );
 				logger.error(e);
 			}
 		}
-		logger.info( "employee attendance details by empname, startdate and end date analyse over!" );;
+
+		logger.debug( "employee attendance detail analyse over!" );
 		return true;
 	}
-	
+
 	/**
 	 * 对一组的打卡信息数据进行分析
+	 * @param emc
 	 * @param detailList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @throws Exception
 	 */
-	public boolean analyseAttendanceDetails( EntityManagerContainer emc, List<AttendanceDetail> detailList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
+	public boolean analyseAttendanceDetails( EntityManagerContainer emc, List<AttendanceDetail> detailList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap, Boolean debugger ) throws Exception{
 		if( detailList == null || detailList.isEmpty() ){
 			return true;
 		}
+		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = workDayConfigService.getAllWorkDayConfigWithCache(debugger);
+
+		for( AttendanceDetail detail : detailList ){
+			try{
+				analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, statisticalCycleMap, debugger );
+			}catch(Exception e){
+				logger.debug( "employee attendance detail analyse got an exception:["+detail.getEmpName()+"]["+detail.getRecordDateString()+"]" );
+				logger.error(e);
+			}
+		}
+
+		logger.debug( "employee attendance detail analyse over!" );
+		return true;
+	}
+
+	/**
+	 * 根据员工姓名,开始日期和结束日期重新分析所有的打卡记录,一般在用户补了休假记录的时候使用,补充了休假记录,需要将休假日期范围内的所有打卡记录重新分析,并且触发相关月份的统计
+	 * @param emc
+	 * @param empName
+	 * @param startDate
+	 * @param endDate
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public Boolean analyseAttendanceDetails( EntityManagerContainer emc, String empName, Date startDate, Date endDate, Boolean debugger ) throws Exception{
 		Business business = null;
-		List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
-		
-		business = new Business(emc);
-		attendanceWorkDayConfigList = business.getAttendanceWorkDayConfigFactory().listAll();
-		for( AttendanceDetail detail : detailList ){			
+		List<String> ids = null;
+		List<AttendanceWorkDayConfig> workDayConfigList = workDayConfigService.getAllWorkDayConfigWithCache(debugger);
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = statisticalCycleService.getAllStatisticalCycleMapWithCache(debugger);
+		List<AttendanceDetail> attendanceDetailList = null;
+
+		ids = listAnalyseAttendanceDetailIds( emc, empName, startDate, endDate );
+		if(ListTools.isEmpty( ids )){
+			logger.debug( debugger, "attendance detail info ids not exists for emp{'empName':'"+empName+"','startDate':'"+startDate+"','endDate':'"+endDate+"'}");
+			return true;
+		}
+		attendanceDetailList = business.getAttendanceDetailFactory().list( ids );
+		if( ListTools.isEmpty( attendanceDetailList ) ){
+			logger.debug( debugger, "attendance detail info not exists for emp{'empName':'"+empName+"','startDate':'"+startDate+"','endDate':'"+endDate+"'}");
+			return true;
+		}
+
+		for( AttendanceDetail detail : attendanceDetailList ){
 			try{
-				analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
+				analyseAttendanceDetail( emc, detail, workDayConfigList, statisticalCycleMap, debugger );
 			}catch(Exception e){
-				logger.info( "employee attendance detail analyse got an exception:["+detail.getEmpName()+"]["+detail.getRecordDateString()+"]" );
+				logger.info( "employee attenance detail analyse got an exception:["+detail.getEmpName()+"]["+detail.getRecordDateString()+"]");
 				logger.error(e);
 			}
 		}
-		logger.info( "employee attendance detail analyse over!" );
+		logger.info( "employee attendance details by empname, startdate and end date analyse over!" );;
 		return true;
 	}
 
 	/**
-	 * 对单条的打卡数据分析统计周期
-	 * 包装成List使用另一个方法进行操作:analyseAttendanceDetails
-	 * 
-	 * @param detail
+	 * 对单条的打卡数据进行分析
+	 * @param emc
+	 * @param detailId
+	 * @param debugger
 	 * @return
 	 * @throws Exception
 	 */
-	public AttendanceDetail analyseAttendanceDetailStatisticCycle( AttendanceDetail detail, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
-		AttendanceStatisticalCycle attendanceStatisticalCycle = null;
-		//根据打卡信息所属个人的组织获取一个合适的统计周期对象		
-		attendanceStatisticalCycle = attendanceStatisticalCycleService.getStatisticCycleWithStartAndEnd(
-				detail.getTopUnitName(), 
-				detail.getUnitName(), 
-				detail.getRecordDate(), 
-				topUnitAttendanceStatisticalCycleMap,
-				debugger
-		);
-		if( attendanceStatisticalCycle != null ) {
-			logger.debug( debugger, ">>>>>>>>>>日期" + detail.getRecordDateString() + ", 周期" + attendanceStatisticalCycle.getCycleStartDateString() + "-" + attendanceStatisticalCycle.getCycleEndDateString() );
-			detail.setCycleYear( attendanceStatisticalCycle.getCycleYear() );
-			detail.setCycleMonth( attendanceStatisticalCycle.getCycleMonth() );
+	public boolean analyseAttendanceDetail( EntityManagerContainer emc, String detailId, Boolean debugger ) throws Exception{
+		if( StringUtils.isNotEmpty( detailId )){
+			return analyseAttendanceDetail( emc, emc.find( detailId, AttendanceDetail.class ),
+					workDayConfigService.getAllWorkDayConfigWithCache(debugger),
+					statisticalCycleService.getAllStatisticalCycleMapWithCache(debugger),
+					debugger );
+		}else{
+			logger.info( "detailId为空,无法继续进行分析。" );
 		}
-		return detail;
+		return false;
 	}
-	
+
 	/**
 	 * 对单条的打卡数据进行分析
-	 * 包装成List使用另一个方法进行操作:analyseAttendanceDetails
 	 * @param emc
 	 * @param detail
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @throws Exception
 	 */
-	public boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
+	public boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail, Boolean debugger ) throws Exception{
 		if( detail != null ){
-			List<AttendanceDetail> detailList = new ArrayList<AttendanceDetail>();
-			detailList.add( detail );
-			return analyseAttendanceDetails( emc, detailList, topUnitAttendanceStatisticalCycleMap, debugger );
+			return analyseAttendanceDetail( emc, detail,
+					workDayConfigService.getAllWorkDayConfigWithCache(debugger),
+					statisticalCycleService.getAllStatisticalCycleMapWithCache(debugger),
+					debugger );
 		}else{
 			logger.info( "detail为空,无法继续进行分析。" );
 		}
@@ -173,106 +222,120 @@ public class AttendanceDetailAnalyseService {
 	 * 对单条的打卡数据进行详细分析
 	 * @param emc
 	 * @param detail
-	 * @param attendanceWorkDayConfigList
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param workDayConfigList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @throws Exception
 	 */
-	public Boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail,
-			List<AttendanceWorkDayConfig> attendanceWorkDayConfigList, Map<String, Map<String, 
-			List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
+	public Boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap, Boolean debugger ) throws Exception{
 		List<String> ids_temp = null;
-		AttendanceScheduleSetting attendanceScheduleSetting = null;
-		List<AttendanceSelfHoliday> attendanceSelfHolidayList = null;
+		AttendanceScheduleSetting scheduleSetting = null;
+		List<AttendanceSelfHoliday> selfHolidayList = null;
 		if( detail != null ){
 			try{
+				//查询员工休假记录
 				ids_temp = attendanceSelfHolidayService.getByPersonName( emc, detail.getEmpName() );
 				if( ids_temp != null && !ids_temp.isEmpty() ) {
-					attendanceSelfHolidayList = attendanceSelfHolidayService.list( emc, ids_temp );
+					selfHolidayList = attendanceSelfHolidayService.list( emc, ids_temp );
 				}
 			}catch( Exception e ){
 				logger.warn( "system list attendance self holiday info ids with employee name got an exception.empname:" + detail.getEmpName() );
 				logger.error(e);
 			}
+
+			//查询用户匹配的排班配置
+			scheduleSetting = attendanceScheduleSettingService.getAttendanceScheduleSettingWithPerson( detail.getEmpName(), debugger );
 			
-			attendanceScheduleSetting = attendanceScheduleSettingService.getAttendanceScheduleSettingWithPerson( detail.getEmpName(), debugger );
-			
-			return analyseAttendanceDetail( emc, detail, attendanceScheduleSetting, attendanceSelfHolidayList, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
+			return analyseAttendanceDetail( emc, detail, scheduleSetting, selfHolidayList, workDayConfigList, statisticalCycleMap, debugger );
 
 		}else{
 			logger.warn( "attendance detail is null, system can not analyse." );
 		}
 		return false;
 	}
-	
+
 	/**
 	 * 对单条的打卡数据进行详细分析
 	 * @param emc
 	 * @param detail
-	 * @param attendanceScheduleSetting
-	 * @param attendanceSelfHolidayList
-	 * @param attendanceWorkDayConfigList
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param scheduleSetting
+	 * @param selfHolidayList
+	 * @param workDayConfigList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @throws Exception
 	 */
-	public Boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail, 
-			AttendanceScheduleSetting attendanceScheduleSetting, List<AttendanceSelfHoliday> attendanceSelfHolidayList, 
-			List<AttendanceWorkDayConfig> attendanceWorkDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap,
+	private Boolean analyseAttendanceDetail( EntityManagerContainer emc, AttendanceDetail detail,
+											AttendanceScheduleSetting scheduleSetting,
+											List<AttendanceSelfHoliday> selfHolidayList,
+											List<AttendanceWorkDayConfig> workDayConfigList,
+											Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap,
 			Boolean debugger ) throws Exception{
+
 		if( detail != null ){
-			DateOperation dateOperation = new DateOperation();
-			logger.debug( debugger, "attendance detail analysing, employee name:["+detail.getEmpName()+"]-["+detail.getRecordDateString()+"]......" );		
+			logger.debug( debugger, "attendance detail analysing, employee name:["+detail.getEmpName()+"]-["+detail.getRecordDateString()+"]......" );
 			Boolean check = true;
-			Date recordDate = null;
-			
-			if( attendanceScheduleSetting == null ){
+
+
+			if( scheduleSetting == null ){
 				check = false;
 				saveAnalyseResultAndStatus( emc, detail.getId(), -1, "未查询到员工[" + detail.getEmpName() + "]所在组织的排班信息" );
 			}
-			
+
+			//初始化考勤打卡记录
 			if( check ){
-				if( detail.getRecordDateString() != null && detail.getRecordDateString().length() > 0 ){
+				//要重新查询,才可能在这个emc里进行事务管理
+				detail = emc.find( detail.getId(), AttendanceDetail.class );
+				if( detail != null ){
+					//将打卡数据里分析过的状态全部清空,还原成未分析的数据
+					detail.refresh();
+				}else{
+					check = false;
+					logger.warn( "system can not find detail, record may be deleted." );
+				}
+			}
+
+			Date recordDate = null;
+			if( check ){
+				if( StringUtils.isNotEmpty(detail.getRecordDateString()) ){
 					try{
+						//把日期字符串转换为日期对象,便于比较计算
 						recordDate = dateOperation.getDateFromString( detail.getRecordDateString());
 					}catch(Exception e){
 						saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性recordDate,日期recordDateString:" + detail.getRecordDateString() );
 						check = false;
 					}
+					if( recordDate != null ){ detail.setRecordDate( recordDate ); }
 				}else{
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性为空" );
 					check = false;
 				}
 			}
-			
-			if( check ){
-				detail = emc.find( detail.getId(), AttendanceDetail.class );//要重新查询一次,才可能在这个emc里进行管理
-				if( detail != null ){
-					detail.refresh(); //将打卡数据里分析过的状态全部清空,还原成未分析的数据
-				}else{
-					check = false;
-					logger.warn( "system can not find detail, record may be deleted." );
-				}
-			}
-			
+
 			if( check ){
-				if( attendanceScheduleSetting != null ){
-					detail.setTopUnitName( attendanceScheduleSetting.getTopUnitName() );
-					if( StringUtils.isNotEmpty( attendanceScheduleSetting.getUnitName() ) && !"*".equals( attendanceScheduleSetting.getUnitName() )) {
-						detail.setUnitName( attendanceScheduleSetting.getUnitName() );
+				if( scheduleSetting != null ){
+					detail.setTopUnitName( scheduleSetting.getTopUnitName() );
+					if( StringUtils.isNotEmpty( scheduleSetting.getUnitName() ) && !"*".equals( scheduleSetting.getUnitName() )) {
+						detail.setUnitName( scheduleSetting.getUnitName() );
 					}else {
 						detail.setUnitName( userManagerService.getUnitNameWithPersonName( detail.getEmpName() ) );
 					}
-					detail.setOnWorkTime( attendanceScheduleSetting.getOnDutyTime() );
-					detail.setOffWorkTime( attendanceScheduleSetting.getOffDutyTime() );
-				}
-				if( recordDate != null ){
-					detail.setRecordDate( recordDate );
+					detail.setOnWorkTime( scheduleSetting.getOnDutyTime() );
+					detail.setMiddayRestStartTime( scheduleSetting.getMiddayRestStartTime() );
+					detail.setMiddayRestEndTime( scheduleSetting.getMiddayRestEndTime() );
+					detail.setOffWorkTime( scheduleSetting.getOffDutyTime() );
+				}else{
+					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "考勤排班信息为空,无法执行考勤记录分析。" );
+					check = false;
+					logger.warn( "system can not find scheduleSetting for detail. UNIT:" + detail.getUnitName() );
 				}
 			}
+
 			if( check ){
 				try{
-					setSelfHolidays( detail, attendanceSelfHolidayList, dateOperation, debugger );
+					composeSelfHolidaysForAttendanceDetail( detail, selfHolidayList, dateOperation, debugger );
 				}catch( Exception e ){
 					check = false;
 					logger.warn( "system analyse employee self holiday for detail got an exception." + detail.getEmpName() );
@@ -280,6 +343,7 @@ public class AttendanceDetailAnalyseService {
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在根据打卡信息,请假信息分析员工请假情况时发生异常" );
 				}
 			}
+
 			if( check ){
 				try{
 					detail.setIsWeekend( dateOperation.isWeekend( detail.getRecordDate() ));
@@ -290,9 +354,10 @@ public class AttendanceDetailAnalyseService {
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是周末时发生异常, recordDate:" + detail.getRecordDateString() );
 				}
 			}
+
 			if( check ){
 				try{
-					detail.setIsHoliday( isHoliday( detail, attendanceWorkDayConfigList, dateOperation ) );
+					detail.setIsHoliday( isHoliday( detail, workDayConfigList, dateOperation ) );
 				}catch( Exception e ){
 					check = false;
 					logger.warn( "system analyse record date may be holiday got an exception." + detail.getRecordDateString() );
@@ -300,19 +365,21 @@ public class AttendanceDetailAnalyseService {
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是节假日时发生异常, recordDate:"+ detail.getRecordDateString() );
 				}
 			}
+
 			if( check ){
 				try{
-					detail.setIsWorkday( isWorkday( detail, attendanceWorkDayConfigList, dateOperation ) );
+					detail.setIsWorkday( isWorkday( detail, workDayConfigList, dateOperation ) );
 				}catch( Exception e ){
 					check = false;
 					logger.warn( "system analyse record date may be workday got an exception." + detail.getRecordDateString() );
 					logger.error(e);
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是工作日时发生异常" );
 				}
-			}	
+			}
+
 			if( check ){
 				try{
-					analyseAttendanceDetailStatisticCycle( detail, topUnitAttendanceStatisticalCycleMap, debugger );
+					composeStatisticCycleForAttendanceDetail( detail, statisticalCycleMap, debugger );
 				}catch( Exception e ){
 					check = false;
 					logger.warn( "system analyse detail statistic cycle got an exception." + detail.getEmpName() );
@@ -322,7 +389,8 @@ public class AttendanceDetailAnalyseService {
 			}
 			if( check ){
 				try{
-					analyseAttendanceDetail( detail, attendanceScheduleSetting, dateOperation, debugger );
+					//使用分析核心算法进行考勤状态分析
+					detail = attendanceDetailAnalyseCoreService.analyseCore( detail, scheduleSetting, dateOperation, debugger );
 				}catch( Exception e ){
 					check = false;
 					logger.warn( "system analyse detail by on and off work time for advance analyse got an exception." + detail.getEmpName() );
@@ -331,12 +399,14 @@ public class AttendanceDetailAnalyseService {
 				}
 			}
 			if( check ){
+				//保存打卡数据分析结果
 				emc.beginTransaction( AttendanceDetail.class );
 				detail.setRecordStatus( 1 );
 				detail.setDescription("员工打卡记录分析完成!" );
 				emc.check( detail, CheckPersistType.all );
 				emc.commit();
 			}
+
 			if( check ){
 				//分析成功根据打卡数据来记录与这条数据相关的统计需求记录
 				recordStatisticRequireLog( detail, debugger );
@@ -347,268 +417,95 @@ public class AttendanceDetailAnalyseService {
 		}
 		return false;
 	}
+
 	/**
-	 * 根据打卡数据来记录与这条数据相关的统计需求记录
+	 * 分析打卡信息,为打卡数据计算考勤周期信息
+	 *
 	 * @param detail
-	 * @throws Exception 
+	 * @return
+	 * @throws Exception
 	 */
-	public void recordStatisticRequireLog( AttendanceDetail detail, Boolean debugger ) throws Exception{
-		//数据分析完成,那么需要记录一下需要统计的信息数据
-		AttendanceStatisticRequireLog attendanceStatisticRequireLog = null;
-		AttendanceStatisticRequireLogFactory attendanceStatisticRequireLogFactory = null;
-		Business business = null;
-		List<AttendanceStatisticRequireLog> logList = null;
-		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-			business = new Business(emc);
-			attendanceStatisticRequireLogFactory = business.getAttendanceStatisticRequireLogFactory();
-			//个人统计每月统计
-			logList = null;
-			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("PERSON_PER_MONTH", detail.getEmpName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
-			if( logList == null || logList.size() == 0 ){
-				logger.debug( debugger, ">>>>>>>>>>统计数据不存在:PERSON_PER_MONTH,"+ detail.getEmpName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-				attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-				attendanceStatisticRequireLog.setStatisticName("员工每月统计");
-				attendanceStatisticRequireLog.setStatisticType("PERSON_PER_MONTH");
-				attendanceStatisticRequireLog.setStatisticKey( detail.getEmpName() );
-				attendanceStatisticRequireLog.setStatisticYear( detail.getCycleYear() );
-				attendanceStatisticRequireLog.setStatisticMonth( detail.getCycleMonth() );
-				emc.beginTransaction( AttendanceStatisticRequireLog.class );
-				emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-				emc.commit();
-			}else{
-				logger.debug( debugger, ">>>>>>>>>>统计数据已存在:PERSON_PER_MONTH,"+ detail.getEmpName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-			}
-			//组织按月统计
-			logList = null;
-			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_MONTH", detail.getUnitName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
-			if( logList == null || logList.size() == 0 ){
-				logger.debug( debugger, ">>>>>>>>>>统计数据不存在:UNIT_PER_MONTH,"+ detail.getUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-				attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-				attendanceStatisticRequireLog.setStatisticName("组织每月统计");
-				attendanceStatisticRequireLog.setStatisticType("UNIT_PER_MONTH");
-				attendanceStatisticRequireLog.setStatisticKey( detail.getUnitName() );
-				attendanceStatisticRequireLog.setStatisticYear( detail.getCycleYear() );
-				attendanceStatisticRequireLog.setStatisticMonth( detail.getCycleMonth() );
-				emc.beginTransaction( AttendanceStatisticRequireLog.class );
-				emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-				emc.commit();
-			}else{
-				logger.debug( debugger, ">>>>>>>>>>统计数据已存在:UNIT_PER_MONTH,"+ detail.getUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-			}
-			//顶层组织按月统计
-			logList = null;
-			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_MONTH", detail.getTopUnitName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
-			if( logList == null || logList.size() == 0 ){
-				logger.debug( debugger, ">>>>>>>>>>统计数据不存在:TOPUNIT_PER_MONTH,"+ detail.getTopUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-				attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-				attendanceStatisticRequireLog.setStatisticName("顶层组织每月统计");
-				attendanceStatisticRequireLog.setStatisticType("TOPUNIT_PER_MONTH");
-				attendanceStatisticRequireLog.setStatisticKey( detail.getTopUnitName() );
-				attendanceStatisticRequireLog.setStatisticYear( detail.getCycleYear() );
-				attendanceStatisticRequireLog.setStatisticMonth( detail.getCycleMonth() );
-				emc.beginTransaction( AttendanceStatisticRequireLog.class );
-				emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-				emc.commit();
-			}else{
-				logger.debug( debugger, ">>>>>>>>>>统计数据已存在:TOPUNIT_PER_MONTH,"+ detail.getTopUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
-			}
-			//组织每日统计
-			logList = null;
-			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_DAY", detail.getUnitName(), null, null, detail.getRecordDateString(), "WAITING");
-			if( logList == null || logList.size() == 0 ){
-				logger.debug( debugger, ">>>>>>>>>>统计数据不存在:UNIT_PER_DAY,"+ detail.getUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
-				attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-				attendanceStatisticRequireLog.setStatisticName("组织每日统计");
-				attendanceStatisticRequireLog.setStatisticType("UNIT_PER_DAY");
-				attendanceStatisticRequireLog.setStatisticKey( detail.getUnitName() );
-				attendanceStatisticRequireLog.setStatisticYear( detail.getCycleYear() );
-				attendanceStatisticRequireLog.setStatisticMonth( detail.getCycleMonth() );
-				attendanceStatisticRequireLog.setStatisticDay( detail.getRecordDateString() );
-				emc.beginTransaction( AttendanceStatisticRequireLog.class );
-				emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-				emc.commit();
-			}else{
-				logger.debug( debugger, ">>>>>>>>>>统计数据已存在:UNIT_PER_DAY,"+ detail.getUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
-			}
-			//顶层组织每日统计
-			logList = null;
-			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_DAY", detail.getTopUnitName(), null, null, detail.getRecordDateString(), "WAITING");
-			if( logList == null || logList.size() == 0 ){
-				logger.debug( debugger, ">>>>>>>>>>统计数据不存在:TOPUNIT_PER_DAY,"+ detail.getTopUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
-				attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-				attendanceStatisticRequireLog.setStatisticName("顶层组织每日统计");
-				attendanceStatisticRequireLog.setStatisticType("TOPUNIT_PER_DAY");
-				attendanceStatisticRequireLog.setStatisticKey( detail.getTopUnitName() );
-				attendanceStatisticRequireLog.setStatisticYear( detail.getCycleYear() );
-				attendanceStatisticRequireLog.setStatisticMonth( detail.getCycleMonth() );
-				attendanceStatisticRequireLog.setStatisticDay( detail.getRecordDateString() );
-				emc.beginTransaction( AttendanceStatisticRequireLog.class );
-				emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-				emc.commit();
-			}else{
-				logger.debug( debugger, ">>>>>>>>>>统计数据已存在:TOPUNIT_PER_DAY,"+ detail.getTopUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
-			}
-		}catch(Exception e){
-			logger.warn("系统在向数据库新增统计需求时发生异常" );
-			logger.error(e);
+	private AttendanceDetail composeStatisticCycleForAttendanceDetail( AttendanceDetail detail, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
+		AttendanceStatisticalCycle attendanceStatisticalCycle = null;
+		//根据打卡信息所属个人的组织获取一个合适的统计周期对象
+		attendanceStatisticalCycle = statisticalCycleService.getStatisticCycleWithStartAndEnd(
+				detail.getTopUnitName(),
+				detail.getUnitName(),
+				detail.getRecordDate(),
+				topUnitAttendanceStatisticalCycleMap,
+				debugger
+		);
+		if( attendanceStatisticalCycle != null ) {
+			logger.debug( debugger, "日期" + detail.getRecordDateString() + ", 周期" + attendanceStatisticalCycle.getCycleStartDateString() + "-" + attendanceStatisticalCycle.getCycleEndDateString() );
+			detail.setCycleYear( attendanceStatisticalCycle.getCycleYear() );
+			detail.setCycleMonth( attendanceStatisticalCycle.getCycleMonth() );
 		}
+		return detail;
 	}
-	
+
 	/**
-	 * 根据员工休假数据来记录与这条数据相关的统计需求记录
-	 * @param detail
-	 * @throws Exception 
+	 * 分析打卡信息,判断员工是否正在休假以及休假的时段
+	 * @param attendanceSelfHolidayList
+	 * @return
+	 * @throws Exception
 	 */
-	public void recordStatisticRequireLog( AttendanceSelfHoliday holiday, Boolean debugger ) throws Exception{
-		//数据分析完成,那么需要记录一下需要统计的信息数据
-		AttendanceStatisticRequireLog attendanceStatisticRequireLog = null;
-		AttendanceStatisticRequireLogFactory attendanceStatisticRequireLogFactory = null;
-		Business business = null;
-		List<AttendanceStatisticRequireLog> logList = null;
-		List<AttendanceCycles> cycleList = null;
-		
-		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-			business = new Business(emc);
-			//查询员工请假期间有几个统计周期
-			cycleList = business.getAttendanceDetailFactory().getCyclesFromDetailWithDateSplit( holiday.getEmployeeName(), holiday.getStartTime(), holiday.getEndTime());
-		}catch(Exception e){
-			logger.warn("系统在查询员工请假期间有几个统计周期时发生异常" );
-			logger.error(e);
-		}
-		
-		if( cycleList != null && cycleList.size() > 0 ){
-			for( AttendanceCycles attendanceCycles : cycleList){
-				try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-					business = new Business(emc);
-					attendanceStatisticRequireLogFactory = business.getAttendanceStatisticRequireLogFactory();
-					//个人统计每月统计
-					logList = null;
-					logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("PERSON_PER_MONTH", holiday.getEmployeeName(), attendanceCycles.getCycleYear(), attendanceCycles.getCycleMonth(), null, "WAITING");
-					if( logList == null || logList.size() == 0 ){
-						logger.debug( debugger, ">>>>>>>>>>统计数据不存在:PERSON_PER_MONTH,"+ holiday.getEmployeeName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-						attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-						attendanceStatisticRequireLog.setStatisticName("员工每月统计");
-						attendanceStatisticRequireLog.setStatisticType("PERSON_PER_MONTH");
-						attendanceStatisticRequireLog.setStatisticKey( holiday.getEmployeeName() );
-						attendanceStatisticRequireLog.setStatisticYear( attendanceCycles.getCycleYear() );
-						attendanceStatisticRequireLog.setStatisticMonth( attendanceCycles.getCycleMonth() );
-						emc.beginTransaction( AttendanceStatisticRequireLog.class );
-						emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-						emc.commit();
-					}else{
-						logger.debug( debugger, ">>>>>>>>>>统计数据已存在:PERSON_PER_MONTH,"+ holiday.getEmployeeName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-					}
-					//组织按月统计
-					logList = null;
-					logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_MONTH", holiday.getUnitName(), attendanceCycles.getCycleYear(), attendanceCycles.getCycleMonth(), null, "WAITING");
-					if( logList == null || logList.size() == 0 ){
-						logger.debug( debugger, ">>>>>>>>>>统计数据不存在:UNIT_PER_MONTH,"+ holiday.getUnitName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-						attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-						attendanceStatisticRequireLog.setStatisticName("组织每月统计");
-						attendanceStatisticRequireLog.setStatisticType("UNIT_PER_MONTH");
-						attendanceStatisticRequireLog.setStatisticKey( holiday.getUnitName() );
-						attendanceStatisticRequireLog.setStatisticYear( attendanceCycles.getCycleYear() );
-						attendanceStatisticRequireLog.setStatisticMonth( attendanceCycles.getCycleMonth() );
-						emc.beginTransaction( AttendanceStatisticRequireLog.class );
-						emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-						emc.commit();
-					}else{
-						logger.debug( debugger, ">>>>>>>>>>统计数据已存在:UNIT_PER_MONTH,"+ holiday.getUnitName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-					}
-					//顶层组织按月统计
-					logList = null;
-					logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_MONTH", holiday.getTopUnitName(), attendanceCycles.getCycleYear(), attendanceCycles.getCycleMonth(), null, "WAITING");
-					if( logList == null || logList.size() == 0 ){
-						logger.debug( debugger, ">>>>>>>>>>统计数据不存在:TOPUNIT_PER_MONTH,"+ holiday.getTopUnitName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-						attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-						attendanceStatisticRequireLog.setStatisticName("顶层组织每月统计");
-						attendanceStatisticRequireLog.setStatisticType("TOPUNIT_PER_MONTH");
-						attendanceStatisticRequireLog.setStatisticKey( holiday.getTopUnitName() );
-						attendanceStatisticRequireLog.setStatisticYear( attendanceCycles.getCycleYear() );
-						attendanceStatisticRequireLog.setStatisticMonth( attendanceCycles.getCycleMonth() );
-						emc.beginTransaction( AttendanceStatisticRequireLog.class );
-						emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-						emc.commit();
-					}else{
-						logger.debug( debugger, ">>>>>>>>>>统计数据已存在:TOPUNIT_PER_MONTH,"+ holiday.getTopUnitName() + ", " + attendanceCycles.getCycleYear() + ", " + attendanceCycles.getCycleMonth() + ", null, WAITING" );
-					}
-				}catch(Exception e){
-					logger.warn("系统在向数据库新增每月统计需求时发生异常" );
-					logger.error(e);
-				}
+	private AttendanceDetail composeSelfHolidaysForAttendanceDetail( AttendanceDetail detail, List<AttendanceSelfHoliday> attendanceSelfHolidayList, DateOperation dateOperation, Boolean debugger ) throws Exception {
+		//查询当前打卡用户所有的请假申请中,打卡时间是否处于休假时间段中
+		Date dayWorkStart = null, dayWorkEnd = null, dayMiddle = null ;
+		if( attendanceSelfHolidayList != null ){
+			//如果打卡日期全天 在 休假时间的中间,那么是全天请假
+			try {
+				dayWorkStart = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " " + detail.getOnWorkTime());
+			} catch (Exception e) {
+				logger.warn( "获取打卡日期的一天的工作开始时间发生异常。" );
+				logger.error(e);
+				return detail;
 			}
-		}
-		List<String> dateList = null;
-		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-			business = new Business(emc);
-			//查询员工请假期间有几多少天
-			DateOperation dateOperation = new DateOperation();
-			dateList = dateOperation.listDateStringBetweenDate( holiday.getStartTime(), holiday.getEndTime() );
-		}catch(Exception e){
-			logger.warn("系统在查询员工请假期间有几多少天时发生异常" );
-			logger.error(e);
-		}
-		DateOperation dateOperation = new DateOperation();
-		if( dateList != null ){
-			for( String date : dateList ){
-				
-				try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-					business = new Business(emc);
-					//查询员工请假期间有几个统计周期
-					cycleList = business.getAttendanceDetailFactory().getCyclesFromDetailWithDateSplit( holiday.getEmployeeName(), dateOperation.getDateFromString(date + " 00:00:00"), dateOperation.getDateFromString(date+ " 23:59:59"));
-				}catch(Exception e){
-					logger.warn("系统在查询员工请假期间有几个统计周期时发生异常" );
-					logger.error(e);
-				}
-				
-				if( cycleList !=  null && cycleList.size() > 0 ){
-					for( AttendanceCycles attendanceCycles : cycleList ){
-						try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
-							business = new Business(emc);
-							//组织每日统计
-							logList = null;
-							logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_DAY", holiday.getUnitName(), null, null, date, "WAITING");
-							if( logList == null || logList.size() == 0 ){
-								logger.debug( debugger, ">>>>>>>>>>统计数据不存在:UNIT_PER_DAY,"+ holiday.getUnitName() + ", null, null , "+ date +", WAITING" );
-								attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-								attendanceStatisticRequireLog.setStatisticName("组织每日统计");
-								attendanceStatisticRequireLog.setStatisticType("UNIT_PER_DAY");
-								attendanceStatisticRequireLog.setStatisticKey( holiday.getUnitName() );
-								attendanceStatisticRequireLog.setStatisticYear( attendanceCycles.getCycleYear() );
-								attendanceStatisticRequireLog.setStatisticMonth( attendanceCycles.getCycleMonth() );
-								attendanceStatisticRequireLog.setStatisticDay( date );
-								emc.beginTransaction( AttendanceStatisticRequireLog.class );
-								emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-								emc.commit();
-							}else{
-								logger.debug( debugger, ">>>>>>>>>>统计数据已存在:UNIT_PER_DAY,"+ holiday.getUnitName() + ", null, null , "+ date +", WAITING" );
-							}
-							//顶层组织每日统计
-							logList = null;
-							logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_DAY", holiday.getTopUnitName(), null, null, date, "WAITING");
-							if( logList == null || logList.size() == 0 ){
-								logger.debug( debugger, ">>>>>>>>>>统计数据不存在:TOPUNIT_PER_DAY,"+ holiday.getTopUnitName() + ", null, null , "+ date +", WAITING" );
-								attendanceStatisticRequireLog = new AttendanceStatisticRequireLog();
-								attendanceStatisticRequireLog.setStatisticName("顶层组织每日统计");
-								attendanceStatisticRequireLog.setStatisticType("TOPUNIT_PER_DAY");
-								attendanceStatisticRequireLog.setStatisticKey( holiday.getTopUnitName() );
-								attendanceStatisticRequireLog.setStatisticYear( attendanceCycles.getCycleYear() );
-								attendanceStatisticRequireLog.setStatisticMonth( attendanceCycles.getCycleMonth() );
-								attendanceStatisticRequireLog.setStatisticDay( date );
-								emc.beginTransaction( AttendanceStatisticRequireLog.class );
-								emc.persist( attendanceStatisticRequireLog, CheckPersistType.all);	
-								emc.commit();
-							}else{
-								logger.debug( debugger, ">>>>>>>>>>统计数据已存在:TOPUNIT_PER_DAY,"+ holiday.getTopUnitName() + ", null, null , "+ date +", WAITING" );
-							}
-						}catch(Exception e){
-							logger.warn("系统在向数据库新增每日统计需求时发生异常" );
-							logger.error(e);
+			try {
+				dayWorkEnd = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " " + detail.getOffWorkTime() );
+			} catch (Exception e) {
+				logger.warn( "获取打卡日期的一天的工作结束时间发生异常。" );
+				logger.error(e);
+				return detail;
+			}
+			try {
+				dayMiddle = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " 12:00:00" );
+			} catch (Exception e) {
+				logger.warn( "获取打卡日期的一天的工作午休时间发生异常。" );
+				logger.error(e);
+				return detail;
+			}
+			//循环比对,看看是否全天请假
+			for( AttendanceSelfHoliday selfHoliday : attendanceSelfHolidayList ){
+				if( selfHoliday.getEndTime().getTime() > dayWorkStart.getTime() && selfHoliday.getStartTime().getTime() < dayWorkEnd.getTime() ){
+					//对比员工姓名,员工姓名是唯一键
+					if( detail.getEmpName().equals( selfHoliday.getEmployeeName() ) ){
+						if( selfHoliday.getStartTime().getTime() <= dayWorkStart.getTime() && selfHoliday.getEndTime().getTime() >= ( dayMiddle.getTime() + 2*60*60*1000 )){
+							logger.debug( debugger, detail.getEmpName()+"全天请假了");
+							//全天休假
+							detail.setIsGetSelfHolidays(true);
+							detail.setSelfHolidayDayTime("全天");
+							detail.setGetSelfHolidayDays(1.0);
+						}else if( selfHoliday.getEndTime().getTime() <= dayMiddle.getTime() && selfHoliday.getEndTime().getTime() > dayWorkStart.getTime()
+						){
+							//上午休假
+							logger.debug( debugger, detail.getEmpName()+"上午休假了");
+							detail.setIsGetSelfHolidays(true);
+							detail.setSelfHolidayDayTime("上午");
+							detail.setGetSelfHolidayDays(0.5);
+						}else if( selfHoliday.getStartTime().getTime() >= dayMiddle.getTime() && selfHoliday.getStartTime().getTime() <= dayWorkEnd.getTime()
+						){
+							//上午休假
+							logger.debug( debugger, detail.getEmpName()+"下午休假了");
+							detail.setIsGetSelfHolidays( true );
+							detail.setSelfHolidayDayTime("下午");
+							detail.setGetSelfHolidayDays(0.5);
 						}
 					}
 				}
 			}
 		}
+		return detail;
 	}
 	
 	/**
@@ -676,421 +573,158 @@ public class AttendanceDetailAnalyseService {
 		}	
 		return false;
 	}
-	
+
 	/**
-	 * 判断员工是否正在休假以及休假的时段
-	 * @param recordDate
-	 * @param attendanceSelfHolidayList 
-	 * @return
-	 * @throws Exception 
+	 * 修改打卡记录的分析状态,0-未分析,1-已分析
+	 * @param emc
+	 * @param id
+	 * @param status
+	 * @param description
+	 * @throws Exception
 	 */
-	private void setSelfHolidays( AttendanceDetail detail, List<AttendanceSelfHoliday> attendanceSelfHolidayList, DateOperation dateOperation, Boolean debugger ) throws Exception {
-		//查询当前打卡用户所有的请假申请中,打卡时间是否处于休假时间段中
-		Date dayWorkStart = null, dayWorkEnd = null, dayMiddle = null ;
-		if( attendanceSelfHolidayList != null ){
-			//如果打卡日期全天 在 休假时间的中间,那么是全天请假
-			try {
-				dayWorkStart = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " " + detail.getOnWorkTime());
-			} catch (Exception e) {
-				logger.warn( "setSelfHolidays获取打卡日期的一天的工作开始时间发生异常。" );
-				logger.error(e);
-				return;
-			}
-			try {
-				dayWorkEnd = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " " + detail.getOffWorkTime() );
-			} catch (Exception e) {
-				logger.warn( "setSelfHolidays获取打卡日期的一天的工作结束时间发生异常。" );
-				logger.error(e);
-				return;
-			}
-			try {
-				dayMiddle = dateOperation.getDateFromString( dateOperation.getDateStringFromDate(detail.getRecordDate(), "yyyy-MM-dd") + " 12:00:00" );
-			} catch (Exception e) {
-				logger.warn( "setSelfHolidays获取打卡日期的一天的工作午休时间发生异常。" );
-				logger.error(e);
-				return;
-			}
-			//循环比对,看看是否全天请假
-			for( AttendanceSelfHoliday selfHoliday : attendanceSelfHolidayList ){
-				if( selfHoliday.getEndTime().getTime() > dayWorkStart.getTime() && selfHoliday.getStartTime().getTime() < dayWorkEnd.getTime() ){
-					//对比员工姓名,员工姓名是唯一键
-					if( detail.getEmpName().equals( selfHoliday.getEmployeeName() ) ){
-						if( selfHoliday.getStartTime().getTime() <= dayWorkStart.getTime() && selfHoliday.getEndTime().getTime() >= ( dayMiddle.getTime() + 2*60*60*1000 )){
-							logger.debug( debugger, ">>>>>>>>>>"+detail.getEmpName()+"全天请假了");
-							//全天休假
-							detail.setIsGetSelfHolidays(true);
-							detail.setSelfHolidayDayTime("全天");
-							detail.setGetSelfHolidayDays(1.0);
-						}else if( selfHoliday.getEndTime().getTime() <= dayMiddle.getTime() && selfHoliday.getEndTime().getTime() > dayWorkStart.getTime()
-						){
-							//上午休假
-							logger.debug( debugger, ">>>>>>>>>>"+detail.getEmpName()+"上午休假了");
-							detail.setIsGetSelfHolidays(true);
-							detail.setSelfHolidayDayTime("上午");
-							detail.setGetSelfHolidayDays(0.5);
-						}else if( selfHoliday.getStartTime().getTime() >= dayMiddle.getTime() && selfHoliday.getStartTime().getTime() <= dayWorkEnd.getTime()
-						){
-							//上午休假
-							logger.debug( debugger, ">>>>>>>>>>"+detail.getEmpName()+"下午休假了");
-							detail.setIsGetSelfHolidays( true );
-							detail.setSelfHolidayDayTime("下午");
-							detail.setGetSelfHolidayDays(0.5);
-						}
-					}
-				}
-			}
+	private void saveAnalyseResultAndStatus( EntityManagerContainer emc, String id, int status, String description) throws Exception {
+		AttendanceDetail detail = emc.find( id, AttendanceDetail.class );
+		emc.beginTransaction( AttendanceDetail.class );
+		detail.setRecordStatus( status );
+		detail.setDescription( description );
+		if( detail != null && detail.getEmpName() != null ){
+			detail.setEmpName( detail.getEmpName().trim() );
 		}
+		emc.check( detail, CheckPersistType.all );
+		emc.commit();
 	}
-	
+
 	/**
-	 * 分析一条打卡记录信息<br/>
-		<b>迟到</b>:晚于最迟“迟到起算时间”,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
-		<b>早退</b>:下班打卡时间早于“迟到起算时间”,并且工作当日时间不满9个小时,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
-		<b>异常</b>:缺少签到退中的1条打卡数据 或者 上下班打卡时间都在最迟起算时间内,不满9个小时,(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)<br/>
-		<b>缺勤</b>:当天没有打卡数据,并且当天是工作日(当天为非周末非节假日正常上班日,并且未请假,或者当天是调休的工作日)
+	 * 根据打卡数据来记录与这条数据相关的统计需求记录
 	 * @param detail
-	 * @param attendanceScheduleSetting
-	 * @param dateOperation
-	 * @throws Exception 
+	 * @param debugger
+	 * @throws Exception
 	 */
-	private void analyseAttendanceDetail( AttendanceDetail detail, AttendanceScheduleSetting attendanceScheduleSetting, DateOperation dateOperation, Boolean debugger ) throws Exception {
-		if( dateOperation == null ){
-			dateOperation = new DateOperation();
-		}
-		if( detail == null ){
-			throw new Exception("detail is null!" );
-		}
-		if( attendanceScheduleSetting == null ){
-			throw new Exception("attendanceScheduleSetting is null, empName:" + detail.getEmpName() );
-		}
-		
-		Date onDutyTime = null, offDutyTime = null;
-		Date onWorkTime = null, offWorkTime = null;
-		Date lateStartTime = null, leaveEarlyStartTime = null, absenceStartTime = null;
-		Date morningEndTime = null;
-		
-		//先初始化当前打卡信息中的上下班时间要求,该要求是是根据员工所在组织排班信息获取到的
-		try {
-			logger.debug( debugger, ">>>>>>>>>>格式化[上班签到时间]onWorkTime=" +  detail.getRecordDateString() + " " + detail.getOnWorkTime() );
-			onWorkTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnWorkTime() );
-		} catch (Exception e) {
-			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime() );
-			onWorkTime = null;
-			logger.debug( debugger, ">>>>>>>>>>系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime());
-			logger.error(e);
-		}
-		
-		try {
-			logger.debug( debugger, ">>>>>>>>>>格式化[下班签退时间]offWorkTime=" +  detail.getRecordDateString() + " " + detail.getOffWorkTime() );
-			offWorkTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffWorkTime() );
-		} catch (Exception e) {
-			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
-			offWorkTime = null;
-			logger.debug( debugger, ">>>>>>>>>>系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
-			logger.error(e);
-		}
-		
-		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getLateStartTime() ) ){
-			try {
-				lateStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime() );
-			} catch (Exception e) {
-				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime() );
-				lateStartTime = null;
-				logger.warn( "系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLateStartTime());
-				logger.error(e);
-			}
-		}else{
-			logger.debug( debugger, ">>>>>>>>>>迟到时间设置为空!系统将不判断迟到情况");
-		}
-		
-		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getLeaveEarlyStartTime() ) ){
-			try {
-				logger.debug( debugger, ">>>>>>>>>>格式化[早退起算时间]leaveEarlyStartTime=" +  detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
-				leaveEarlyStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
-			} catch (Exception e) {
-				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
-				leaveEarlyStartTime = null;
-				logger.warn( "系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getLeaveEarlyStartTime() );
-				logger.error(e);
-			}
-		}else{
-			logger.debug( debugger, ">>>>>>>>>>早退时间设置为空!系统将不判断早退情况");
-		}
-		
-		if( StringUtils.isNotEmpty( attendanceScheduleSetting.getAbsenceStartTime() ) ){
-			try {
-				logger.debug( debugger, ">>>>>>>>>>格式化[缺勤起算时间]absenceStartTime=" +  detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
-				absenceStartTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
-			} catch (Exception e) {
-				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
-				absenceStartTime = null;
-				logger.warn( "系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + attendanceScheduleSetting.getAbsenceStartTime() );
-				logger.error(e);
-			}
-		}else{
-			logger.debug( debugger, ">>>>>>>>>>上午缺勤时间设置为空!系统将不判上午缺勤情况");
-		}
-		
-		try {
-			logger.debug( debugger, ">>>>>>>>>>格式化[上午工作结束时间]morningEndTime=" +  detail.getRecordDateString() + " 12:00:00" );
-			morningEndTime = dateOperation.getDateFromString( detail.getRecordDateString() + " 12:00:00"  );
-		} catch (Exception e) {
-			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,morningEndTime=" + detail.getRecordDateString() + " 12:00:00" );
-			morningEndTime = null;
-			logger.warn( "系统进行时间转换时发生异常,morningEndTime=" + detail.getRecordDateString() + " 12:00:00" );
-			logger.error(e);
-		}
-		
-		
-		if( onWorkTime != null && offWorkTime != null ){
-			logger.debug( debugger, ">>>>>>>>>>上下班排班信息获取正常:onWorkTime=" +  onWorkTime + ", offWorkTime="+offWorkTime );
-			//获取员工签到时间
-			try {
-				if( detail.getOnDutyTime() == null || detail.getOnDutyTime().isEmpty() ){
-					logger.debug( debugger, ">>>>>>>>>>onDutyTime 为空 " );
-					onDutyTime = null;
-				}else{
-					logger.debug( debugger, ">>>>>>>>>>格式化onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
-					onDutyTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+	private void recordStatisticRequireLog( AttendanceDetail detail, Boolean debugger ) throws Exception{
+		//数据分析完成,那么需要记录一下需要统计的信息数据
+		AttendanceStatisticRequireLog log = null;
+		AttendanceStatisticRequireLogFactory attendanceStatisticRequireLogFactory = null;
+		Business business = null;
+		List<AttendanceStatisticRequireLog> logList = null;
+		try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create() ) {
+			business = new Business(emc);
+			attendanceStatisticRequireLogFactory = business.getAttendanceStatisticRequireLogFactory();
+			//个人统计每月统计
+			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("PERSON_PER_MONTH", detail.getEmpName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
+			if( ListTools.isEmpty(logList) ){
+				logger.debug( debugger, "统计数据不存在:PERSON_PER_MONTH,"+ detail.getEmpName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
+				log = new AttendanceStatisticRequireLog();
+				log.setStatisticName("员工每月统计");
+				log.setStatisticType("PERSON_PER_MONTH");
+				log.setStatisticKey( detail.getEmpName() );
+				log.setStatisticYear( detail.getCycleYear() );
+				log.setStatisticMonth( detail.getCycleMonth() );
+				emc.beginTransaction( AttendanceStatisticRequireLog.class );
+				emc.persist( log, CheckPersistType.all);
+				emc.commit();
+
+				//统计考勤数据
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
-			} catch (Exception e) {
-				onDutyTime = null;
-				logger.warn( "系统进行时间转换时发生异常,onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
-				logger.error(e);
+			}else{
+				logger.debug( debugger, "统计数据已存在:PERSON_PER_MONTH,"+ detail.getEmpName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
 			}
-			//获取员工签退时间
-			try {
-				if( detail.getOffDutyTime() == null || detail.getOffDutyTime().isEmpty() ){
-					logger.debug( debugger, ">>>>>>>>>>offDutyTime 为空" );
-					offDutyTime = null;
-				}else{
-					logger.debug( debugger, ">>>>>>>>>>格式化offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
-					offDutyTime = dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+			//组织按月统计
+			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_MONTH", detail.getUnitName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
+			if( ListTools.isEmpty(logList) ){
+				logger.debug( debugger, "统计数据不存在:UNIT_PER_MONTH,"+ detail.getUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
+				log = new AttendanceStatisticRequireLog();
+				log.setStatisticName("组织每月统计");
+				log.setStatisticType("UNIT_PER_MONTH");
+				log.setStatisticKey( detail.getUnitName() );
+				log.setStatisticYear( detail.getCycleYear() );
+				log.setStatisticMonth( detail.getCycleMonth() );
+				emc.beginTransaction( AttendanceStatisticRequireLog.class );
+				emc.persist( log, CheckPersistType.all);
+				emc.commit();
+				//统计考勤数据
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
-			} catch (Exception e) {
-				offDutyTime = null;
-				logger.warn( "系统进行时间转换时发生异常,offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
-				logger.error(e);
+			}else{
+				logger.debug( debugger, "统计数据已存在:UNIT_PER_MONTH,"+ detail.getUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
 			}
-			
-			//=========================================================================================================
-			//=====如果员工没有签到并且没有签退,一条打卡时间都没有,那么是算缺勤的========================================
-			//=========================================================================================================
-			if( onDutyTime == null && offDutyTime == null ){
-				//if( detail.getIsGetSelfHolidays()  && "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ) ){
-				if( detail.getIsGetSelfHolidays()  ){
-					logger.debug( debugger, ">>>>>>>>>>请幸运,全天请假不计缺勤。" );
-					detail.setAttendance( 0.0 );
-					detail.setIsAbsent( false );
-					detail.setAbsence( 0.0 );
-					detail.setAbsentDayTime("无");
-					detail.setWorkTimeDuration( 0L );
-				}else{
-					if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
-						|| detail.getIsHoliday() //或者是节假日
-					){
-						logger.debug( debugger, ">>>>>>>>>>未请假,不是工作日,不计缺勤。" );
-						detail.setAttendance( 0.0 );
-						detail.setIsAbsent( false );
-						detail.setAbsence( 0.0 );
-						detail.setAbsentDayTime("无");
-						detail.setWorkTimeDuration( 0L );
-					}else{
-						logger.debug( debugger, ">>>>>>>>>>未请假,工作日,计缺勤1天。" );
-						detail.setAttendance( 0.0 );
-						detail.setIsAbsent( true );
-						detail.setAbsence( 1.0 );
-						detail.setAbsentDayTime("全天");
-						detail.setWorkTimeDuration( 0L );
-					}
+			//顶层组织按月统计
+			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_MONTH", detail.getTopUnitName(), detail.getCycleYear(), detail.getCycleMonth(), null, "WAITING");
+			if( ListTools.isEmpty(logList) ){
+				logger.debug( debugger, "统计数据不存在:TOPUNIT_PER_MONTH,"+ detail.getTopUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
+				log = new AttendanceStatisticRequireLog();
+				log.setStatisticName("顶层组织每月统计");
+				log.setStatisticType("TOPUNIT_PER_MONTH");
+				log.setStatisticKey( detail.getTopUnitName() );
+				log.setStatisticYear( detail.getCycleYear() );
+				log.setStatisticMonth( detail.getCycleMonth() );
+				emc.beginTransaction( AttendanceStatisticRequireLog.class );
+				emc.persist( log, CheckPersistType.all);
+				emc.commit();
+				//统计考勤数据
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
 			}else{
-				//=========================================================================================================
-				//=====上午  如果员工已经签到================================================================================
-				//=========================================================================================================
-				if( onDutyTime != null ){
-					logger.debug( debugger, ">>>>>>>>>>上午打过卡,时间:onDutyTime=" + onDutyTime + ", 上午工作结束时间:morningEndTime=" + morningEndTime );					
-					//absenceStartTimes可以不配置,如果不配置,则为null
-					//上午签到过了,如果排班设置里已经配置过了缺勤起算时间,那么判断员工是否已经缺勤,如果未休假,则视为缺勤半天			
-					if( absenceStartTime != null && onDutyTime.after( absenceStartTime )){
-						logger.debug( debugger, ">>>>>>>>>>上午打卡时间晚于缺勤计时时间......" );
-						if( detail.getIsGetSelfHolidays()  && ("上午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
-							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,出勤只算半天,但请过假了不算缺勤" );
-							detail.setIsAbsent( false );
-							detail.setAbsence(0.0);
-						}else{
-							if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
-									|| detail.getIsHoliday() //或者是节假日
-								){
-								logger.debug( debugger, ">>>>>>>>>>休息天,不算缺勤,出勤最多只能算半天" );
-								detail.setIsAbsent( false );
-								detail.setAbsence(0.0);
-							}else{
-								logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,缺勤半天,出勤最多只能算半天" );
-								detail.setIsAbsent( true );
-								detail.setAbsence(0.5);
-								detail.setAbsentDayTime("上午");
-							}
-						}
-						//缺勤直接扣半天出勤, 请假不算出勤,所以也只有半天
-						detail.setAttendance( 0.5 );
-					}else if( lateStartTime != null && onDutyTime.after( lateStartTime )){ 
-						//上午签到过了,如果排班设置里已经配置过了迟到起算时间,那么判断员工是否已经迟到,如果未休假
-						detail.setAttendance( 1.0 );//迟到没关系,出勤时间不用扣半天
-						logger.debug( debugger, ">>>>>>>>>>上午打卡时间晚于迟到计时时间......" );
-						if( detail.getIsGetSelfHolidays()  && ("上午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))
-						){
-							logger.debug( debugger, ">>>>>>>>>>请幸运,请过假了不算迟到" );
-							detail.setLateTimeDuration( 0L ); //请假了不算迟到
-							detail.setIsLate(false );//请假了不算迟到
-						}else{
-							if( ( detail.getIsWeekend()  && !detail.getIsWorkday()) //周末,并且未调休为工作日
-									|| detail.getIsHoliday() //或者是节假日
-								){
-								detail.setLateTimeDuration( 0L );
-								detail.setIsLate( false );
-								logger.debug( debugger, ">>>>>>>>>>休息天,不算迟到" );
-							}else{
-								if( onDutyTime == null || offDutyTime == null ){
-									detail.setIsAbnormalDuty( true );
-								}else{
-									long minutes = dateOperation.getMinutes( onWorkTime, onDutyTime ); //迟到计算从上班时间开始计算,不是迟到起算时间
-									detail.setLateTimeDuration( minutes );//没请假算迟到时长 
-									detail.setIsLate( true );//没请假算迟到
-									logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,计迟到一次,迟到时长:minutes=" + minutes );
-								}
-							}
-						}
-					}
-					long minutes = dateOperation.getMinutes( onDutyTime, morningEndTime );
-					logger.debug( debugger, ">>>>>>>>>>上午工作时长, 从"+onDutyTime+"到"+morningEndTime+" :minutes=" + minutes + "分钟。" );
-					detail.setWorkTimeDuration( minutes );//记录上午的工作时长
-				}else{
-					logger.debug( debugger, ">>>>>>>>>>员工上午未打卡,异常状态......" );
-					if( detail.getIsGetSelfHolidays() && ("上午".equalsIgnoreCase( detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))
-					){
-						logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,不需要打卡,不算异常" );
-						detail.setIsAbsent( false );
-						//detail.setAttendance( 0.5 );
-					}else{
-						if( ( detail.getIsWeekend()&& !detail.getIsWorkday() ) //周末,并且未调休为工作日
-								|| detail.getIsHoliday() //或者是节假日
-							){
-							logger.debug( debugger, ">>>>>>>>>>休息天,不算打卡异常,本来就不需要打卡" );
-							detail.setAbnormalDutyDayTime("无");
-							detail.setIsAbnormalDuty( false );
-							//detail.setAttendance( 0 )
-						}else{
-							logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,打卡异常。" );
-							detail.setAbnormalDutyDayTime("上午");
-							detail.setIsAbnormalDuty(true);
-							//detail.setAttendance( 0.5 ); //上午打卡异常,不知道算不算出勤时间
-						}
-					}
-					logger.debug( debugger, ">>>>>>>>>>上午工作时长, 未打卡:minutes= 0 分钟。" );
-					detail.setWorkTimeDuration( 0L );//记录上午的工作时长
-				}
-				//=========================================================================================================
-				//=====下午  如果员工已经签退================================================================================
-				//=========================================================================================================
-				if( offDutyTime != null ){
-					logger.debug( debugger, ">>>>>>>>>>早退计时时间:leaveEarlyStartTime=" + leaveEarlyStartTime );
-					long minutes = dateOperation.getMinutes( morningEndTime, offDutyTime);
-					logger.debug( debugger, ">>>>>>>>>>下午工作时长, 从"+morningEndTime+"到"+offDutyTime+" :minutes=" + minutes + "分钟。" );
-					detail.setWorkTimeDuration( detail.getWorkTimeDuration() + minutes );//记录上午的工作时长 + 下午工作时长
-					logger.debug( debugger, ">>>>>>>>>>全天工作时长, :minutes=" + detail.getWorkTimeDuration() + "分钟。" );					
-					if( leaveEarlyStartTime != null && offDutyTime.before( leaveEarlyStartTime )){
-						logger.debug( debugger, ">>>>>>>>>>下午打卡时间早于早退计时时间......" );
-						if( detail.getIsGetSelfHolidays() && ("下午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
-							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,出勤只算半天,但请过假了不算早退" );
-							detail.setLeaveEarlierTimeDuration( 0L );
-							detail.setIsLeaveEarlier( false );
-							//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤时间
-						}else{
-							if( ( detail.getIsWeekend() && !detail.getIsWorkday() ) //周末,并且未调休为工作日
-									|| detail.getIsHoliday() //或者是节假日
-								){
-								logger.debug( debugger, ">>>>>>>>>>休息天,不算早退" );
-								detail.setLeaveEarlierTimeDuration( 0L );
-								detail.setIsLeaveEarlier( false );
-								//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤
-							}else{
-								minutes = dateOperation.getMinutes( offDutyTime, leaveEarlyStartTime );
-								detail.setLeaveEarlierTimeDuration(minutes); //早退时间
-								detail.setIsLeaveEarlier( true );
-								//detail.setAttendance( detail.getAttendance() - 0.5 );//早退了,不知道算不算出勤
-								logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,早退计一次,全天工作时长:"+detail.getWorkTimeDuration()+"分钟,早退时长:minutes=" + minutes );
-							}
-						}
-					}
-				}else{
-					//如果打卡是今天,但是还没有到下班打卡时间
-					if(  detail.getRecordDateString().equals( dateOperation.getNowDate() )  && dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffWorkTime()).after( new Date() ) ) {
-						detail.setAbnormalDutyDayTime("无");
-						detail.setIsAbnormalDuty(false);
-						logger.debug( debugger, ">>>>>>>>>>还没有到下班打卡时间,先不分析结果。" );
-					}else {
-						logger.debug( debugger, ">>>>>>>>>>员工下午未打卡,属于异常状态......" );
-						//员工未签退,算缺勤了半天,出勤率: - 0.5
-						if( detail.getIsGetSelfHolidays()  && ("下午".equalsIgnoreCase(detail.getSelfHolidayDayTime()) || "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() ))){
-							logger.debug( debugger, ">>>>>>>>>>请幸运,请假不计考勤,不需要打卡,不算异常状态" );
-							detail.setLeaveEarlierTimeDuration( 0L );
-							detail.setIsLeaveEarlier( false );
-							//detail.setAttendance( detail.getAttendance() - 0.5 );
-						}else{
-							if( ( detail.getIsWeekend() && !detail.getIsWorkday()) //周末,并且未调休为工作日
-									|| detail.getIsHoliday() //或者是节假日
-								){
-								logger.debug( debugger, ">>>>>>>>>>休息天,不算异常" );
-								detail.setAbnormalDutyDayTime("无");
-								detail.setIsAbnormalDuty(false);
-							}else{
-								detail.setAbnormalDutyDayTime("下午");
-								detail.setIsAbnormalDuty(true);
-								logger.debug( debugger, ">>>>>>>>>>呵呵,没请假,未打卡,算异常状态。" );
-							}
-						}						
-					}
-					logger.debug( debugger, ">>>>>>>>>>全天工作时长,[下午未打卡,只算上午的工作时长] :minutes=" + detail.getWorkTimeDuration() + "分钟。" );
+				logger.debug( debugger, "统计数据已存在:TOPUNIT_PER_MONTH,"+ detail.getTopUnitName() + ", " + detail.getCycleYear() + ", " + detail.getCycleMonth() + ", null, WAITING" );
+			}
+			//组织每日统计
+			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("UNIT_PER_DAY", detail.getUnitName(), null, null, detail.getRecordDateString(), "WAITING");
+			if( ListTools.isEmpty(logList) ){
+				logger.debug( debugger, "统计数据不存在:UNIT_PER_DAY,"+ detail.getUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
+				log = new AttendanceStatisticRequireLog();
+				log.setStatisticName("组织每日统计");
+				log.setStatisticType("UNIT_PER_DAY");
+				log.setStatisticKey( detail.getUnitName() );
+				log.setStatisticYear( detail.getCycleYear() );
+				log.setStatisticMonth( detail.getCycleMonth() );
+				log.setStatisticDay( detail.getRecordDateString() );
+				emc.beginTransaction( AttendanceStatisticRequireLog.class );
+				emc.persist( log, CheckPersistType.all);
+				emc.commit();
+				//统计考勤数据
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+			}else{
+				logger.debug( debugger, "统计数据已存在:UNIT_PER_DAY,"+ detail.getUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
 			}
-			
-			
-			//=========================================================================================================
-			//=====如果上下班都打卡了,但是工作时间没有9小时,那么属于工时不足(如果迟到了,就算迟到,不算工时不足)========================================
-			//=========================================================================================================
-			if( onDutyTime != null && offDutyTime != null){
-				if( ( detail.getIsWeekend() && !detail.getIsWorkday() ) //周末,并且未调休为工作日
-						|| detail.getIsHoliday() //或者是节假日
-					){
-					//没事
-				}else{
-					if( !detail.getIsGetSelfHolidays() ){ // 没请假
-						//计算工时
-						long minutes = dateOperation.getMinutes( onDutyTime, offDutyTime);
-						if( minutes < (60*9)){
-							logger.debug( debugger, ">>>>>>>>>>签到时间["+onDutyTime+"],签退时间["+offDutyTime+"],工作时间:"+minutes+"分钟!工时不足!" );
-							if( !detail.getIsLate() ){
-								detail.setIsLackOfTime(true);//工时不足
-							}
-						}
-					}
+			//顶层组织每日统计
+			logList = attendanceStatisticRequireLogFactory.getByNameKeyAndStatus("TOPUNIT_PER_DAY", detail.getTopUnitName(), null, null, detail.getRecordDateString(), "WAITING");
+			if( ListTools.isEmpty(logList) ){
+				logger.debug( debugger, "统计数据不存在:TOPUNIT_PER_DAY,"+ detail.getTopUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
+				log = new AttendanceStatisticRequireLog();
+				log.setStatisticName("顶层组织每日统计");
+				log.setStatisticType("TOPUNIT_PER_DAY");
+				log.setStatisticKey( detail.getTopUnitName() );
+				log.setStatisticYear( detail.getCycleYear() );
+				log.setStatisticMonth( detail.getCycleMonth() );
+				log.setStatisticDay( detail.getRecordDateString() );
+				emc.beginTransaction( AttendanceStatisticRequireLog.class );
+				emc.persist( log, CheckPersistType.all);
+				emc.commit();
+				//统计考勤数据
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+			}else{
+				logger.debug( debugger, "统计数据已存在:TOPUNIT_PER_DAY,"+ detail.getTopUnitName() + ", null, null , "+ detail.getRecordDateString() +", WAITING" );
 			}
-			
-			detail.setRecordStatus( 1 );
-		}
-	}
-	
-	private void saveAnalyseResultAndStatus( EntityManagerContainer emc, String id, int status, String description) throws Exception {
-		AttendanceDetail detail = emc.find( id, AttendanceDetail.class );
-		emc.beginTransaction( AttendanceDetail.class );
-		detail.setRecordStatus( status );
-		detail.setDescription( description );
-		if( detail != null && detail.getEmpName() != null ){
-			detail.setEmpName( detail.getEmpName().trim() );
+		}catch(Exception e){
+			logger.warn("系统在向数据库新增统计需求时发生异常" );
+			logger.error(e);
 		}
-		emc.check( detail, CheckPersistType.all );
-		emc.commit();
 	}
 }

+ 116 - 12
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseServiceAdv.java

@@ -1,9 +1,18 @@
 package com.x.attendance.assemble.control.service;
 
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.factory.AttendanceStatisticRequireLogFactory;
 import com.x.attendance.entity.*;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.tools.ListTools;
+import net.sf.ehcache.Ehcache;
+import org.apache.commons.lang3.StringUtils;
 
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -14,38 +23,133 @@ import java.util.Map;
  *
  */
 public class AttendanceDetailAnalyseServiceAdv {
-	
-	private AttendanceDetailAnalyseService attendanceDetailAnalyseService = new AttendanceDetailAnalyseService();
-	
-	public Boolean analyseAttendanceDetail( AttendanceDetail detail, AttendanceScheduleSetting attendanceScheduleSetting, List<AttendanceSelfHoliday> selfHolidays, List<AttendanceWorkDayConfig> attendanceWorkDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger) throws Exception {
+	private AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+	private AttendanceStatisticalCycleServiceAdv statisticalCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+	private AttendanceDetailServiceAdv detailServiceAdv = new AttendanceDetailServiceAdv();
+	private AttendanceDetailAnalyseService detailAnalyseService = new AttendanceDetailAnalyseService();
+
+	/**
+	 * 根据员工姓名\开始日期\结束日期查询日期范围内所有的打卡记录信息ID列表<br/>
+	 * 时间从开始日期0点,到结束日期23点59分
+	 * @param empName
+	 * @param startDate
+	 * @param endDate
+	 * @return
+	 * @throws Exception
+	 */
+	public List<String> listAnalyseAttendanceDetailIds( String empName, Date startDate, Date endDate, Boolean debugger )throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return detailAnalyseService.listAnalyseAttendanceDetailIds( emc, empName, startDate, endDate );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 对一组的打卡信息数据进行分析
+	 * @param detailIds
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetailWithIds( List<String> detailIds, Boolean debugger ) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return detailAnalyseService.analyseAttendanceDetailWithIds( emc, detailIds, debugger );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 对一组的打卡信息数据进行分析
+	 * @param detailList
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetails( List<AttendanceDetail> detailList, Boolean debugger ) throws Exception{
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.analyseAttendanceDetail( emc, detail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+			return detailAnalyseService.analyseAttendanceDetails( emc, detailList, debugger );
 		} catch ( Exception e ) {
 			throw e;
 		}
 	}
-	
-	public Boolean analyseAttendanceDetail( AttendanceDetail detail, List<AttendanceWorkDayConfig> attendanceWorkDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger) throws Exception {
+
+	/**
+	 * 对一组的打卡信息数据进行分析
+	 * @param detailList
+	 * @param statisticalCycleMap
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetails( List<AttendanceDetail> detailList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap, Boolean debugger ) throws Exception{
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+			return detailAnalyseService.analyseAttendanceDetails( emc, detailList, statisticalCycleMap, debugger );
 		} catch ( Exception e ) {
 			throw e;
 		}
 	}
 
+	/**
+	 * 根据员工姓名,开始日期和结束日期重新分析所有的打卡记录,一般在用户补了休假记录的时候使用,补充了休假记录,需要将休假日期范围内的所有打卡记录重新分析,并且触发相关月份的统计
+	 * @param empName
+	 * @param startDate
+	 * @param endDate
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public Boolean analyseAttendanceDetails( String empName, Date startDate, Date endDate, Boolean debugger ) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return detailAnalyseService.analyseAttendanceDetails( emc, empName, startDate, endDate, debugger );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
 
-	public List<String> getAnalyseAttendanceDetailIds( String employeeName, Date startTime, Date endTime ) throws Exception {
+	/**
+	 * 对单条的打卡数据进行分析
+	 * @param detailId
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetail( String detailId, Boolean debugger ) throws Exception{
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.getAnalyseAttendanceDetailIds( emc, employeeName, startTime, endTime );	
+			return detailAnalyseService.analyseAttendanceDetail( emc, detailId, debugger );
 		} catch ( Exception e ) {
 			throw e;
 		}
 	}
 
+	/**
+	 * 对单条的打卡数据进行分析
+	 * @param detail
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetail( AttendanceDetail detail, Boolean debugger ) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return detailAnalyseService.analyseAttendanceDetail( emc, detail, debugger );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
 
-	public Boolean analyseAttendanceDetails(String employeeName, Date startTime, Date endTime, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception {
+	/**
+	 * 对单条的打卡数据进行详细分析
+	 * @param detail
+	 * @param workDayConfigList
+	 * @param statisticalCycleMap
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public Boolean analyseAttendanceDetail( AttendanceDetail detail, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap, Boolean debugger ) throws Exception{
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.analyseAttendanceDetails( emc, employeeName, startTime, endTime, topUnitAttendanceStatisticalCycleMap, debugger );	
+			return detailAnalyseService.analyseAttendanceDetail( emc, detail, workDayConfigList, statisticalCycleMap, debugger );
 		} catch ( Exception e ) {
 			throw e;
 		}

+ 1 - 1
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseService.java

@@ -54,7 +54,7 @@ public class AttendanceDetailMobileAnalyseService {
 					attendanceDetail = emc.find( detailId, AttendanceDetail.class );
 					if( attendanceDetail != null ){
 						emc.beginTransaction( AttendanceDetail.class );
-						attendanceDetail.setRecordStatus( 0 );
+						attendanceDetail.setRecordStatus( 0 );//设置未分析
 						if( "上班打卡".equals( attendanceDetailMobile.getSignDescription() )){
 							if( attendanceDetail.getOnDutyTime() == null ){
 								onDutyTime = dateOperation.getDateFromString( attendanceDetailMobile.getSignTime() );

+ 4 - 7
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseServiceAdv.java

@@ -20,7 +20,7 @@ import com.x.base.core.entity.annotation.CheckPersistType;
  */
 public class AttendanceDetailMobileAnalyseServiceAdv {
 	private AttendanceDetailAnalyseService attendanceDetailAnalyseService = new AttendanceDetailAnalyseService();
-	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
+	private AttendanceStatisticalCycleService statisticalCycleService = new AttendanceStatisticalCycleService();
 	private AttendanceDetailMobileAnalyseService attendanceDetailMobileAnalyseService = new AttendanceDetailMobileAnalyseService();
 	
 	/**
@@ -28,8 +28,7 @@ public class AttendanceDetailMobileAnalyseServiceAdv {
 	 * 2、如果当前的打卡记录是上班打卡,则只进行记录不进行分析
 	 * 3、如果当前的打卡记录是下班打卡,则更新考勤信息后,对考勤记录进行分析
 	 * 4、查询该用户是否仍有未分析的考勤数据,如果日期不是今天,那么,全部进行分析
-	 * 
-	 * @param emc
+	 *
 	 * @param id
 	 * @return
 	 */
@@ -38,17 +37,15 @@ public class AttendanceDetailMobileAnalyseServiceAdv {
 		AttendanceDetail attendanceDetail = null;
 		AttendanceDetailMobile attendanceDetailMobile = null;
 		List<String> ids = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		EntityManagerContainer emc = EntityManagerContainerFactory.instance().create();
 		try{
 			business = new Business(emc);
 			attendanceDetailMobile = emc.find( id, AttendanceDetailMobile.class );
-			topUnitAttendanceStatisticalCycleMap = attendanceStatisticalCycleService.getCycleMapFormAllCycles( debugger );
 			if( attendanceDetailMobile != null ){
 				attendanceDetail = attendanceDetailMobileAnalyseService.composeAttendanceDetailMobile( emc, id );
 				if( attendanceDetail != null ){
 					if( StringUtils.isNotEmpty( attendanceDetail.getOffDutyTime() ) ){
-						attendanceDetailAnalyseService.analyseAttendanceDetail(emc, attendanceDetail, topUnitAttendanceStatisticalCycleMap, debugger );
+						attendanceDetailAnalyseService.analyseAttendanceDetail(emc, attendanceDetail, debugger );
 					}
 				}
 				
@@ -59,7 +56,7 @@ public class AttendanceDetailMobileAnalyseServiceAdv {
 						if( attendanceDetail != null ){
 							//只要不是和手机打卡记录同一天的都需要进行分析
 							if( !attendanceDetail.getRecordDateString().equals( attendanceDetailMobile.getRecordDateString() )){
-								attendanceDetailAnalyseService.analyseAttendanceDetail( emc, attendanceDetail, topUnitAttendanceStatisticalCycleMap, debugger );
+								attendanceDetailAnalyseService.analyseAttendanceDetail( emc, attendanceDetail, debugger );
 							}
 						}
 					}

+ 22 - 14
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailServiceAdv.java

@@ -4,6 +4,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import com.x.attendance.assemble.control.ThisApplication;
 import org.apache.commons.lang3.StringUtils;
 
 import com.x.attendance.assemble.common.date.DateOperation;
@@ -25,9 +26,9 @@ public class AttendanceDetailServiceAdv {
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailServiceAdv.class );
 	private AttendanceDetailService attendanceDetailService = new AttendanceDetailService();
 	private AttendanceDetailMobileService attendanceDetailMobileService = new AttendanceDetailMobileService();
-	protected AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
-	protected AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
-	protected AttendanceStatisticalCycleServiceAdv attendanceStatisticCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+//	protected AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
+//	protected AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+//	protected AttendanceStatisticalCycleServiceAdv attendanceStatisticCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
 	
 	public AttendanceDetail get( String id ) throws Exception {
 		if( id == null || id.isEmpty() ){
@@ -274,19 +275,26 @@ public class AttendanceDetailServiceAdv {
 					emc.check( detailMobile , CheckPersistType.all );
 				}
 				emc.commit();
-				
-				List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
-				Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
+
+				//分析保存好的考勤数据
 				try {
-					attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
-					topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( false );
-					
-					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, false );
-					logger.info( ">>>>>>>>>>attendance detail analyse completed.person:" + detail.getEmpName() + ", date:" + detail.getRecordDateString());
-					
-				} catch (Exception e) {
-					e.printStackTrace();
+					ThisApplication.detailAnalyseQueue.send( detail.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+
+//				List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
+//				Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
+//				try {
+//					attendanceWorkDayConfigList = attendanceWorkDayConfigServiceAdv.listAll();
+//					topUnitAttendanceStatisticalCycleMap = attendanceStatisticCycleServiceAdv.getCycleMapFormAllCycles( false );
+//
+//					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, false );
+//					logger.info( ">>>>>>>>>>attendance detail analyse completed.person:" + detail.getEmpName() + ", date:" + detail.getRecordDateString());
+//
+//				} catch (Exception e) {
+//					e.printStackTrace();
+//				}
 			}
 		} catch ( Exception e ) {
 			throw e;

+ 1 - 1
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceSettingService.java

@@ -138,7 +138,7 @@ public class AttendanceSettingService {
 			logger.error(e);
 		}
 
-		value = "";
+		value = "";
 		type = "text";
 		selectContent = null;
 		isMultiple = false;

+ 91 - 62
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticServiceAdv.java

@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceStatisticRequireLog;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
@@ -20,36 +21,34 @@ import com.x.base.core.project.logger.LoggerFactory;
 public class AttendanceStatisticServiceAdv {
 	
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticServiceAdv.class );
-	private AttendanceWorkDayConfigService attendanceWorkDayConfigService = new AttendanceWorkDayConfigService();
+//	private AttendanceWorkDayConfigService attendanceWorkDayConfigService = new AttendanceWorkDayConfigService();
 	private AttendanceStatisticRequireLogService attendanceStatisticRequireLogService = new AttendanceStatisticRequireLogService();
 	private AttendanceStatisticService attendanceStatisticService = new AttendanceStatisticService();
-	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
+//	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
 
 	/**
 	 * 根据统计年份月份列表来对每个月的数据进行统计
 	 */
 	public void doStatistic( Boolean debugger ) {
 		logger.debug( debugger, ">>>>>>>>>>>系统正准备开始进行数据统计......" );
-		AttendanceStatisticalCycle attendanceStatisticalCycle  = null;
-		List<AttendanceWorkDayConfig> workDayConfigList = null;
+//		AttendanceStatisticalCycle attendanceStatisticalCycle  = null;
+//		List<AttendanceWorkDayConfig> workDayConfigList = null;
 		List<AttendanceStatisticRequireLog> attendanceStatisticRequireLogList = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
+//		Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = null;
 		
-		try {//先查询所有的法定节假日和工作日配置列表
-			logger.debug( debugger, ">>>>>>>>>>>准备所有的法定节假日和工作日配置列表......" );
-			workDayConfigList = attendanceWorkDayConfigService.listAll();
-		} catch ( Exception e ) {
-			logger.warn("【统计】系统在查询当月有打卡记录的员工姓名列表时发生异常!" );
-			logger.error(e);
-		}
-		
-		try{//查询所有的考勤统计周期信息,并且组织成MAP
-			logger.debug( debugger, ">>>>>>>>>>>准备所有的考勤统计周期信息......" );
-			topUnitAttendanceStatisticalCycleMap = attendanceStatisticalCycleService.getCycleMapFormAllCycles(debugger);
-		}catch(Exception e){
-			logger.warn( "【统计】系统在查询并且组织所有的考勤统计周期信息时发生异常。" );
-			logger.error(e);
-		}
+//		try {//先查询所有的法定节假日和工作日配置列表
+//			workDayConfigList = attendanceWorkDayConfigService.getAllWorkDayConfigWithCache(debugger);
+//		} catch ( Exception e ) {
+//			logger.warn("【统计】系统在查询当月有打卡记录的员工姓名列表时发生异常!" );
+//			logger.error(e);
+//		}
+//
+//		try{//查询所有的考勤统计周期信息,并且组织成MAP
+//			statisticalCycleMap = attendanceStatisticalCycleService.getAllStatisticalCycleMapWithCache(debugger);
+//		}catch(Exception e){
+//			logger.warn( "【统计】系统在查询并且组织所有的考勤统计周期信息时发生异常。" );
+//			logger.error(e);
+//		}
 		
 		//先处理所有的统计错误
 		try {
@@ -78,22 +77,28 @@ public class AttendanceStatisticServiceAdv {
 		}		
 		
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[员工每月统计], 员工:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计月份:" + attendanceStatisticRequireLog.getStatisticYear() + "-" +attendanceStatisticRequireLog.getStatisticMonth() );
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
 				try {
-					attendanceStatisticalCycle = attendanceStatisticalCycleService.getStatisticCycleByEmployee( attendanceStatisticRequireLog, topUnitAttendanceStatisticalCycleMap, debugger );
-				} catch (Exception e) {
-					logger.warn("【统计】系统在根据统计需求记录信息查询统计周期信息时发生异常!" );
-					logger.error(e);
-				}
-				if( attendanceStatisticalCycle != null ){
-					try{
-						attendanceStatisticService.statisticEmployeeAttendanceForMonth( attendanceStatisticRequireLog, attendanceStatisticalCycle, workDayConfigList, topUnitAttendanceStatisticalCycleMap);
-					}catch(Exception e){
-						logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
-						logger.error(e);
-					}
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+//				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[员工每月统计], 员工:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+//				try {
+//					attendanceStatisticalCycle = attendanceStatisticalCycleService.getStatisticCycleByEmployee( log, statisticalCycleMap, debugger );
+//				} catch (Exception e) {
+//					logger.warn("【统计】系统在根据统计需求记录信息查询统计周期信息时发生异常!" );
+//					logger.error(e);
+//				}
+//				if( attendanceStatisticalCycle != null ){
+//					try{
+//						attendanceStatisticService.statisticEmployeeAttendanceForMonth( log, attendanceStatisticalCycle, workDayConfigList, statisticalCycleMap);
+//					}catch(Exception e){
+//						logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+//						logger.error(e);
+//					}
+//				}
 			}
 		}
 		
@@ -108,14 +113,20 @@ public class AttendanceStatisticServiceAdv {
 			logger.error(e);
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[组织每月统计], 组织:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计月份:" + attendanceStatisticRequireLog.getStatisticYear() + "-" +attendanceStatisticRequireLog.getStatisticMonth() );
-				try{
-					attendanceStatisticService.statisticUnitAttendanceForMonth( attendanceStatisticRequireLog, workDayConfigList, topUnitAttendanceStatisticalCycleMap );
-				}catch(Exception e){
-					logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
-					logger.error(e);
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+//				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[组织每月统计], 组织:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+//				try{
+//					attendanceStatisticService.statisticUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap );
+//				}catch(Exception e){
+//					logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+//					logger.error(e);
+//				}
 			}
 		}		
 		
@@ -129,14 +140,20 @@ public class AttendanceStatisticServiceAdv {
 			logger.error(e);
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[顶层组织每月统计], 顶层组织:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计月份:" + attendanceStatisticRequireLog.getStatisticYear() + "-" +attendanceStatisticRequireLog.getStatisticMonth() );
-				try{
-					attendanceStatisticService.statisticTopUnitAttendanceForMonth( attendanceStatisticRequireLog, workDayConfigList, topUnitAttendanceStatisticalCycleMap);
-				}catch(Exception e){
-					logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
-					logger.error(e);
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+//				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[顶层组织每月统计], 顶层组织:" + log.getStatisticKey() + ", 统计月份:" + log.getStatisticYear() + "-" +log.getStatisticMonth() );
+//				try{
+//					attendanceStatisticService.statisticTopUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap);
+//				}catch(Exception e){
+//					logger.warn( "【统计】系统在根据需求进行员工月度打卡记录分析结果统计时发生异常。" );
+//					logger.error(e);
+//				}
 			}
 		}		
 		
@@ -150,14 +167,20 @@ public class AttendanceStatisticServiceAdv {
 			logger.error(e);
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[组织每月统计], 组织:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计日期:" + attendanceStatisticRequireLog.getStatisticDay() );
-				try{
-					attendanceStatisticService.statisticUnitAttendanceForDay( attendanceStatisticRequireLog, workDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
-				}catch(Exception e){
-					logger.warn( "【统计】系统在根据需求进行组织每日打卡记录分析结果统计时发生异常。" );
-					logger.error(e);
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+//				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[组织每月统计], 组织:" + log.getStatisticKey() + ", 统计日期:" + log.getStatisticDay() );
+//				try{
+//					attendanceStatisticService.statisticUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap, debugger );
+//				}catch(Exception e){
+//					logger.warn( "【统计】系统在根据需求进行组织每日打卡记录分析结果统计时发生异常。" );
+//					logger.error(e);
+//				}
 			}
 		}
 		
@@ -171,14 +194,20 @@ public class AttendanceStatisticServiceAdv {
 			logger.error(e);
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[顶层组织每月统计], 顶层组织:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计日期:" + attendanceStatisticRequireLog.getStatisticDay() );
-				try{
-					attendanceStatisticService.statisticTopUnitAttendanceForDay( attendanceStatisticRequireLog, workDayConfigList, topUnitAttendanceStatisticalCycleMap );
-				}catch(Exception e){
-					logger.warn( "【统计】系统在根据需求进行顶层组织每日打卡记录分析结果统计时发生异常。" );
-					logger.error(e);
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
+				try {
+					ThisApplication.detailStatisticQueue.send( log.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
+//				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[顶层组织每月统计], 顶层组织:" + log.getStatisticKey() + ", 统计日期:" + log.getStatisticDay() );
+//				try{
+//					attendanceStatisticService.statisticTopUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap );
+//				}catch(Exception e){
+//					logger.warn( "【统计】系统在根据需求进行顶层组织每日打卡记录分析结果统计时发生异常。" );
+//					logger.error(e);
+//				}
 			}
 		}
 		logger.debug( debugger, ">>>>>>>>>>>系统数据统计运行完成." );

+ 27 - 3
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleService.java

@@ -15,15 +15,37 @@ import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckRemoveType;
+import com.x.base.core.project.cache.ApplicationCache;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
 
 public class AttendanceStatisticalCycleService {
-	
+
+	private Ehcache cache_AttendanceStatisticalCycle = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleService.class );
 	private UserManagerService userManagerService = new UserManagerService();
 	private DateOperation dateOperation = new DateOperation();
-	
+
+	/**
+	 * 从缓存中获取所有的考勤周期配置
+	 * @return
+	 * @throws Exception
+	 */
+	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getAllStatisticalCycleMapWithCache(Boolean debugger) throws Exception {
+		String cacheKey = ApplicationCache.concreteCacheKey( "map#all" );
+		Element element = cache_AttendanceStatisticalCycle.get(cacheKey);
+		Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap = null;
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			return (Map<String, Map<String, List<AttendanceStatisticalCycle>>>) element.getObjectValue();
+		}else{
+			return getCycleMapFormAllCycles( false );
+		}
+	}
+
 	public List<AttendanceStatisticalCycle> listAll(EntityManagerContainer emc) throws Exception {
 		Business business =  new Business( emc );
 		return business.getAttendanceStatisticalCycleFactory().listAll();
@@ -41,7 +63,9 @@ public class AttendanceStatisticalCycleService {
 			throw e;
 		}
 	}
-	
+
+
+
 	/**
 	 * TODO 将所有的统计周期配置信息组织成一个大的Map
 	 * @param emc

+ 8 - 7
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleServiceAdv.java

@@ -16,7 +16,7 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 
 public class AttendanceStatisticalCycleServiceAdv {
-	
+
 	private AttendanceStatisticalCycleService attendanceStatisticCycleService = new AttendanceStatisticalCycleService();
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleServiceAdv.class );
 	private UserManagerService userManagerService = new UserManagerService();
@@ -28,12 +28,12 @@ public class AttendanceStatisticalCycleServiceAdv {
 			throw e;
 		}
 	}
-	
+
 	/**
 	 * 将所有的周期配置组织成一个Map便于查询操作
-	 * @param cycles
+	 * @param debugger
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getCycleMapFormAllCycles( Boolean debugger ) throws Exception{
 		List<AttendanceStatisticalCycle> cycles = null;
@@ -417,11 +417,12 @@ public class AttendanceStatisticalCycleServiceAdv {
 		}
 		return null;
 	}
-	
+
 	/**
 	 * 将单个对象放到一个List里,并且去重复
 	 * @param cycle
-	 * @param topUnitCycles
+	 * @param unitCycles
+	 * @param debugger
 	 * @return
 	 */
 	public List<AttendanceStatisticalCycle> putDistinctCycleInList( AttendanceStatisticalCycle cycle, List<AttendanceStatisticalCycle> unitCycles, Boolean debugger ) {
@@ -446,6 +447,6 @@ public class AttendanceStatisticalCycleServiceAdv {
 		//如果循环完了,证明不存在,要添加一个对象
 		unitCycles.add( cycle );
 		return unitCycles;
-	}	
+	}
 }
 

+ 21 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceWorkDayConfigService.java

@@ -6,10 +6,31 @@ import com.x.attendance.assemble.control.Business;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.cache.ApplicationCache;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
 
 
 public class AttendanceWorkDayConfigService {
 
+	private Ehcache cache_AttendanceWorkDayConfig = ApplicationCache.instance().getCache( AttendanceWorkDayConfig.class);
+	/**
+	 * 从缓存中获取所有的工作日配置
+	 * @return
+	 * @throws Exception
+	 */
+	public List<AttendanceWorkDayConfig> getAllWorkDayConfigWithCache(Boolean debugger) throws Exception {
+		String cacheKey = ApplicationCache.concreteCacheKey( "list#all" );
+		Element element = cache_AttendanceWorkDayConfig.get(cacheKey);
+		List<AttendanceWorkDayConfig> workDayConfigList = null;
+
+		if ((null != element) && (null != element.getObjectValue())) {
+			return (List<AttendanceWorkDayConfig>) element.getObjectValue();
+		}else{
+			return listAll();
+		}
+	}
+
 	public AttendanceWorkDayConfig get( EntityManagerContainer emc, String id ) throws Exception {
 		if( id == null || id.isEmpty() ){
 			return null;

+ 109 - 252
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetail.java

@@ -170,6 +170,18 @@ public class AttendanceDetail extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	private String onDutyTime;
 
+	public static final String middayRestStartTime_FIELDNAME = "middayRestStartTime";
+	@FieldDescribe("午休开始时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + onDutyTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestStartTime;
+
+	public static final String middayRestEndTime_FIELDNAME = "middayRestEndTime";
+	@FieldDescribe("午休结束时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestEndTime;
+
 	public static final String offDutyTime_FIELDNAME = "offDutyTime";
 	@FieldDescribe("下班打卡时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
@@ -249,12 +261,6 @@ public class AttendanceDetail extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	private String appealDescription;
 
-	public static final String archiveTime_FIELDNAME = "archiveTime";
-	@FieldDescribe("归档时间")
-	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + archiveTime_FIELDNAME )
-	@CheckPersist(allowEmpty = true)
-	private String archiveTime;
-
 	public static final String isHoliday_FIELDNAME = "isHoliday";
 	@FieldDescribe("是否法定节假日")
 	@Column( name = ColumnNamePrefix + isHoliday_FIELDNAME )
@@ -309,41 +315,39 @@ public class AttendanceDetail extends SliceJpaObject {
 	@CheckPersist(allowEmpty = false)
 	private Boolean isWeekend = false;
 
+	public static final String archiveTime_FIELDNAME = "archiveTime";
+	@FieldDescribe("记录归档时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + archiveTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String archiveTime;
+
 	/**
 	 * 获取是否工时不足
 	 * 
 	 * @return
 	 */
-	public Boolean getIsLackOfTime() {
-		return isLackOfTime;
-	}
+	public Boolean getIsLackOfTime() { return isLackOfTime; }
 
 	/**
 	 * 设置是否工时不足
 	 * 
 	 * @param isLackOfTime
 	 */
-	public void setIsLackOfTime(Boolean isLackOfTime) {
-		this.isLackOfTime = isLackOfTime;
-	}
+	public void setIsLackOfTime(Boolean isLackOfTime) { this.isLackOfTime = isLackOfTime; }
 
 	/**
 	 * 获取员工号(String)
 	 * 
 	 * @return
 	 */
-	public String getEmpNo() {
-		return empNo;
-	}
+	public String getEmpNo() { return empNo; }
 
 	/**
 	 * 设置员工号(String)
 	 * 
 	 * @param empNo
 	 */
-	public void setEmpNo(String empNo) {
-		this.empNo = empNo;
-	}
+	public void setEmpNo(String empNo) { this.empNo = empNo; }
 
 	/**
 	 * 获取员工姓名(String)
@@ -374,662 +378,515 @@ public class AttendanceDetail extends SliceJpaObject {
 	 * 
 	 * @return
 	 */
-	public Boolean getIsLate() {
-		return isLate;
-	}
+	public Boolean getIsLate() { return isLate; }
 
 	/**
 	 * 设置员工是否已经迟到(Integer)
 	 * 
 	 * @param isLate
 	 */
-	public void setIsLate(Boolean isLate) {
-		this.isLate = isLate;
-	}
+	public void setIsLate(Boolean isLate) { this.isLate = isLate; }
 
 	/**
 	 * 获取员工是否早退(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsLeaveEarlier() {
-		return isLeaveEarlier;
-	}
+	public Boolean getIsLeaveEarlier() { return isLeaveEarlier; }
 
 	/**
 	 * 设置员工是否早退(Integer)
 	 * 
 	 * @param isLeaveEarlier
 	 */
-	public void setIsLeaveEarlier(Boolean isLeaveEarlier) {
-		this.isLeaveEarlier = isLeaveEarlier;
-	}
+	public void setIsLeaveEarlier(Boolean isLeaveEarlier) { this.isLeaveEarlier = isLeaveEarlier; }
 
 	/**
 	 * 获取员工员工打卡记录日期(String)
 	 * 
 	 * @return
 	 */
-	public String getRecordDateString() {
-		return recordDateString;
-	}
+	public String getRecordDateString() { return recordDateString; }
 
 	/**
 	 * 设置员工员工打卡记录日期(String)
 	 * 
 	 * @param recordDateString
 	 */
-	public void setRecordDateString(String recordDateString) {
-		this.recordDateString = recordDateString;
-	}
+	public void setRecordDateString(String recordDateString) { this.recordDateString = recordDateString; }
 
 	/**
 	 * 获取员工员工打卡记录日期(Date)
 	 * 
 	 * @return
 	 */
-	public Date getRecordDate() {
-		return recordDate;
-	}
+	public Date getRecordDate() { return recordDate; }
 
 	/**
 	 * 设置员工员工打卡记录日期(Date)
 	 * 
 	 * @param recordDate
 	 */
-	public void setRecordDate(Date recordDate) {
-		this.recordDate = recordDate;
-	}
+	public void setRecordDate(Date recordDate) { this.recordDate = recordDate; }
 
 	/**
 	 * 获取员工打卡记录导入批次号-导入文件ID(String)
 	 * 
 	 * @return
 	 */
-	public String getBatchName() {
-		return batchName;
-	}
+	public String getBatchName() { return batchName; }
 
 	/**
 	 * 设置员工打卡记录导入批次号-导入文件ID(String)
 	 * 
 	 * @param batchName
 	 */
-	public void setBatchName(String batchName) {
-		this.batchName = batchName;
-	}
+	public void setBatchName(String batchName) { this.batchName = batchName; }
 
 	/**
 	 * 获取员工标准上班时间(String)
 	 * 
 	 * @return
 	 */
-	public String getOnWorkTime() {
-		return onWorkTime;
-	}
+	public String getOnWorkTime() { return onWorkTime; }
 
 	/**
 	 * 设置员工标准上班时间(String)
 	 * 
 	 * @param onWorkTime
 	 */
-	public void setOnWorkTime(String onWorkTime) {
-		this.onWorkTime = onWorkTime;
-	}
+	public void setOnWorkTime(String onWorkTime) { this.onWorkTime = onWorkTime; }
 
 	/**
 	 * 获取员工标准下班时间(String)
 	 * 
 	 * @return
 	 */
-	public String getOffWorkTime() {
-		return offWorkTime;
-	}
+	public String getOffWorkTime() { return offWorkTime; }
 
 	/**
 	 * 设置员工标准下班时间(String)
 	 * 
 	 * @param offWorkTime
 	 */
-	public void setOffWorkTime(String offWorkTime) {
-		this.offWorkTime = offWorkTime;
-	}
+	public void setOffWorkTime(String offWorkTime) { this.offWorkTime = offWorkTime; }
 
 	/**
 	 * 获取员工迟到时长(Long)
 	 * 
 	 * @return
 	 */
-	public Long getLateTimeDuration() {
-		return lateTimeDuration;
-	}
+	public Long getLateTimeDuration() { return lateTimeDuration; }
 
 	/**
 	 * 设置员工迟到时长(Long)
 	 * 
 	 * @param lateTimeDuration
 	 */
-	public void setLateTimeDuration(Long lateTimeDuration) {
-		this.lateTimeDuration = lateTimeDuration;
-	}
+	public void setLateTimeDuration(Long lateTimeDuration) { this.lateTimeDuration = lateTimeDuration; }
 
 	/**
 	 * 获取员工早退时长(Long)
 	 * 
 	 * @return
 	 */
-	public Long getLeaveEarlierTimeDuration() {
-		return leaveEarlierTimeDuration;
-	}
+	public Long getLeaveEarlierTimeDuration() { return leaveEarlierTimeDuration; }
 
 	/**
 	 * 设置员工早退时长(Long)
 	 * 
 	 * @param leaveEarlierTimeDuration
 	 */
-	public void setLeaveEarlierTimeDuration(Long leaveEarlierTimeDuration) {
-		this.leaveEarlierTimeDuration = leaveEarlierTimeDuration;
-	}
+	public void setLeaveEarlierTimeDuration(Long leaveEarlierTimeDuration) { this.leaveEarlierTimeDuration = leaveEarlierTimeDuration; }
 
 	/**
 	 * 获取员工是否缺勤(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsAbsent() {
-		return isAbsent;
-	}
+	public Boolean getIsAbsent() { return isAbsent; }
 
 	/**
 	 * 设置员工是否缺勤(Integer)
 	 * 
 	 * @param isAbsent
 	 */
-	public void setIsAbsent(Boolean isAbsent) {
-		this.isAbsent = isAbsent;
-	}
+	public void setIsAbsent(Boolean isAbsent) { this.isAbsent = isAbsent; }
 
 	/**
 	 * 获取员工是否加班(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsWorkOvertime() {
-		return isWorkOvertime;
-	}
+	public Boolean getIsWorkOvertime() { return isWorkOvertime; }
 
 	/**
 	 * 设置员工是否加班(Integer)
 	 * 
 	 * @param isWorkOvertime
 	 */
-	public void setIsWorkOvertime(Boolean isWorkOvertime) {
-		this.isWorkOvertime = isWorkOvertime;
-	}
+	public void setIsWorkOvertime(Boolean isWorkOvertime) { this.isWorkOvertime = isWorkOvertime; }
 
 	/**
 	 * 获取员工加班时长(Long)
 	 * 
 	 * @return
 	 */
-	public Long getWorkOvertimeTimeDuration() {
-		return workOvertimeTimeDuration;
-	}
+	public Long getWorkOvertimeTimeDuration() { return workOvertimeTimeDuration; }
 
 	/**
 	 * 设置员工加班时长(Long)
 	 * 
 	 * @param workOvertimeTimeDuration
 	 */
-	public void setWorkOvertimeTimeDuration(Long workOvertimeTimeDuration) {
-		this.workOvertimeTimeDuration = workOvertimeTimeDuration;
-	}
+	public void setWorkOvertimeTimeDuration(Long workOvertimeTimeDuration) { this.workOvertimeTimeDuration = workOvertimeTimeDuration; }
 
 	/**
 	 * 获取当天是否为法定节假日(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsHoliday() {
-		return isHoliday;
-	}
+	public Boolean getIsHoliday() { return isHoliday; }
 
 	/**
 	 * 设置当天是否为法定节假日(Integer)
 	 * 
 	 * @param isHoliday
 	 */
-	public void setIsHoliday(Boolean isHoliday) {
-		this.isHoliday = isHoliday;
-	}
+	public void setIsHoliday(Boolean isHoliday) { this.isHoliday = isHoliday; }
 
 	/**
 	 * 获取员工出勤时长(分钟)(Long)
 	 * 
 	 * @return
 	 */
-	public Long getWorkTimeDuration() {
-		return workTimeDuration;
-	}
+	public Long getWorkTimeDuration() { return workTimeDuration; }
 
 	/**
 	 * 设置员工出勤时长(分钟)(Long)
 	 * 
 	 * @param workTimeDuration
 	 */
-	public void setWorkTimeDuration(Long workTimeDuration) {
-		this.workTimeDuration = workTimeDuration;
-	}
+	public void setWorkTimeDuration(Long workTimeDuration) { this.workTimeDuration = workTimeDuration; }
 
 	/**
 	 * 获取员工出勤天数(0,0.5,1)(Double)
 	 * 
 	 * @return
 	 */
-	public Double getAttendance() {
-		return attendance;
-	}
+	public Double getAttendance() { return attendance; }
 
 	/**
 	 * 设置员工出勤天数(0,0.5,1)(Double)
 	 * 
 	 * @param attendance
 	 */
-	public void setAttendance(Double attendance) {
-		this.attendance = attendance;
-	}
+	public void setAttendance(Double attendance) { this.attendance = attendance; }
 
 	/**
 	 * 获取员工上班打卡时间(String)
 	 * 
 	 * @return
 	 */
-	public String getOnDutyTime() {
-		return onDutyTime;
-	}
+	public String getOnDutyTime() { return onDutyTime; }
 
 	/**
 	 * 设置员工上班打卡时间(String)
 	 * 
 	 * @param onDutyTime
 	 */
-	public void setOnDutyTime(String onDutyTime) {
-		this.onDutyTime = onDutyTime;
-	}
+	public void setOnDutyTime(String onDutyTime) { this.onDutyTime = onDutyTime; }
 
 	/**
 	 * 获取员工下班打卡时间(String)
 	 * 
 	 * @return
 	 */
-	public String getOffDutyTime() {
-		return offDutyTime;
-	}
+	public String getOffDutyTime() { return offDutyTime; }
 
 	/**
 	 * 设置员工下班打卡时间(String)
 	 * 
 	 * @param offDutyTime
 	 */
-	public void setOffDutyTime(String offDutyTime) {
-		this.offDutyTime = offDutyTime;
-	}
+	public void setOffDutyTime(String offDutyTime) { this.offDutyTime = offDutyTime; }
 
 	/**
 	 * 获取员工打卡记录分析状态:0-未分析 1-已分析 -1-分析有错误(String)
 	 * 
 	 * @return
 	 */
-	public Integer getRecordStatus() {
-		return recordStatus;
-	}
+	public Integer getRecordStatus() { return recordStatus; }
 
 	/**
 	 * 设置员工打卡记录分析状态:0-未分析 1-已分析 -1-分析有错误(String)
 	 * 
 	 * @param recordStatus
 	 */
-	public void setRecordStatus(Integer recordStatus) {
-		this.recordStatus = recordStatus;
-	}
+	public void setRecordStatus(Integer recordStatus) { this.recordStatus = recordStatus; }
 
 	/**
 	 * 获取员工打卡当天是否调休的工作日(String)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsWorkday() {
-		return isWorkday;
-	}
+	public Boolean getIsWorkday() { return isWorkday; }
 
 	/**
 	 * 设置员工打卡当天是否调休的工作日(String)
 	 * 
 	 * @param isWorkday
 	 */
-	public void setIsWorkday(Boolean isWorkday) {
-		this.isWorkday = isWorkday;
-	}
+	public void setIsWorkday(Boolean isWorkday) { this.isWorkday = isWorkday; }
 
 	/**
 	 * 获取员工打卡当天是否周末(String)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsWeekend() {
-		return isWeekend;
-	}
+	public Boolean getIsWeekend() { return isWeekend; }
 
 	/**
 	 * 设置员工打卡当天是否周末(String)
 	 * 
 	 * @param isWeekend
 	 */
-	public void setIsWeekend(Boolean isWeekend) {
-		this.isWeekend = isWeekend;
-	}
+	public void setIsWeekend(Boolean isWeekend) { this.isWeekend = isWeekend; }
 
 	/**
 	 * 获取员工打卡记录分析处理说明:系统分析时自动填写(String)
 	 * 
 	 * @return
 	 */
-	public String getDescription() {
-		return description;
-	}
+	public String getDescription() { return description; }
 
 	/**
 	 * 设置员工打卡记录分析处理说明:系统分析时自动填写(String)
 	 * 
 	 * @param description
 	 */
-	public void setDescription(String description) {
-		this.description = description;
-	}
+	public void setDescription(String description) { this.description = description; }
 
 	/**
 	 * 获取员工所属顶层组织名称(String)
 	 * 
 	 * @return
 	 */
-	public String getTopUnitName() {
-		return topUnitName;
-	}
+	public String getTopUnitName() { return topUnitName; }
 
 	/**
 	 * 设置员工所属顶层组织名称(String)
 	 * 
 	 * @param topUnitName
 	 */
-	public void setTopUnitName(String topUnitName) {
-		this.topUnitName = topUnitName;
-	}
+	public void setTopUnitName(String topUnitName) { this.topUnitName = topUnitName; }
 
 	/**
 	 * 获取员工所属组织名称(String)
 	 * 
 	 * @return
 	 */
-	public String getUnitName() {
-		return unitName;
-	}
+	public String getUnitName() { return unitName; }
 
 	/**
 	 * 设置员工所属组织名称(String)
 	 * 
 	 * @param unitName
 	 */
-	public void setUnitName(String unitName) {
-		this.unitName = unitName;
-	}
+	public void setUnitName(String unitName) { this.unitName = unitName; }
 
 	/**
 	 * 获取员工打卡记录所在年份(String)
 	 * 
 	 * @return
 	 */
-	public String getYearString() {
-		return yearString;
-	}
+	public String getYearString() { return yearString; }
 
 	/**
 	 * 设置员工打卡记录所在年份(String)
 	 * 
 	 * @param yearString
 	 */
-	public void setYearString(String yearString) {
-		this.yearString = yearString;
-	}
+	public void setYearString(String yearString) { this.yearString = yearString; }
 
 	/**
 	 * 获取员工打卡记录所在月份(String)
 	 * 
 	 * @return
 	 */
-	public String getMonthString() {
-		return monthString;
-	}
+	public String getMonthString() { return monthString; }
 
 	/**
 	 * 设置员工打卡记录所在月份(String)
 	 * 
 	 * @param monthString
 	 */
-	public void setMonthString(String monthString) {
-		this.monthString = monthString;
-	}
+	public void setMonthString(String monthString) { this.monthString = monthString; }
 
 	/**
 	 * 获取员工是否处于休假中(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsGetSelfHolidays() {
-		return isGetSelfHolidays;
-	}
+	public Boolean getIsGetSelfHolidays() { return isGetSelfHolidays; }
 
 	/**
 	 * 设置员工是否处于休假中(Integer)
 	 * 
 	 * @param isGetSelfHolidays
 	 */
-	public void setIsGetSelfHolidays(Boolean isGetSelfHolidays) {
-		this.isGetSelfHolidays = isGetSelfHolidays;
-	}
+	public void setIsGetSelfHolidays(Boolean isGetSelfHolidays) { this.isGetSelfHolidays = isGetSelfHolidays; }
 
 	/**
 	 * 获取休假时段:无,上午,下午,全天(String)
 	 * 
 	 * @return
 	 */
-	public String getSelfHolidayDayTime() {
-		return selfHolidayDayTime;
-	}
+	public String getSelfHolidayDayTime() { return selfHolidayDayTime; }
 
 	/**
 	 * 设置休假时段:无,上午,下午,全天(String)
 	 * 
 	 * @param selfHolidayDayTime
 	 */
-	public void setSelfHolidayDayTime(String selfHolidayDayTime) {
-		this.selfHolidayDayTime = selfHolidayDayTime;
-	}
+	public void setSelfHolidayDayTime(String selfHolidayDayTime) { this.selfHolidayDayTime = selfHolidayDayTime; }
 
 	/**
 	 * 获取员工休假天数:0,0.5,1(String)
 	 * 
 	 * @return
 	 */
-	public Double getGetSelfHolidayDays() {
-		return getSelfHolidayDays;
-	}
+	public Double getGetSelfHolidayDays() { return getSelfHolidayDays; }
 
 	/**
 	 * 设置员工休假天数:0,0.5,1(String)
 	 * 
 	 * @param getSelfHolidayDays
 	 */
-	public void setGetSelfHolidayDays(Double getSelfHolidayDays) {
-		this.getSelfHolidayDays = getSelfHolidayDays;
-	}
+	public void setGetSelfHolidayDays(Double getSelfHolidayDays) { this.getSelfHolidayDays = getSelfHolidayDays; }
 
 	/**
 	 * 获取员工缺勤天数:0,0.5,1(String)
 	 * 
 	 * @return
 	 */
-	public Double getAbsence() {
-		return absence;
-	}
+	public Double getAbsence() { return absence; }
 
 	/**
 	 * 设置员工缺勤天数:0,0.5,1(String)
 	 * 
 	 * @param absence
 	 */
-	public void setAbsence(Double absence) {
-		this.absence = absence;
-	}
+	public void setAbsence(Double absence) { this.absence = absence; }
 
 	/**
 	 * 获取员工打卡记录分析结果申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过
 	 * 
 	 * @return
 	 */
-	public Integer getAppealStatus() {
-		return appealStatus;
-	}
+	public Integer getAppealStatus() { return appealStatus; }
 
 	/**
 	 * 获取员工打卡记录分析结果申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过
 	 * 
 	 * @param appealStatus
 	 */
-	public void setAppealStatus(Integer appealStatus) {
-		this.appealStatus = appealStatus;
-	}
+	public void setAppealStatus(Integer appealStatus) { this.appealStatus = appealStatus; }
 
 	/**
 	 * 获取员工打卡记录分析结果申诉简要理由(String)
 	 * 
 	 * @return
 	 */
-	public String getAppealReason() {
-		return appealReason;
-	}
+	public String getAppealReason() { return appealReason; }
 
 	/**
 	 * 设置员工打卡记录分析结果申诉简要理由(String)
 	 * 
 	 * @param appealReason
 	 */
-	public void setAppealReason(String appealReason) {
-		this.appealReason = appealReason;
-	}
+	public void setAppealReason(String appealReason) { this.appealReason = appealReason; }
 
 	/**
 	 * 获取员工打卡记录分析结果申诉详细理由(String)
 	 * 
 	 * @return
 	 */
-	public String getAppealDescription() {
-		return appealDescription;
-	}
+	public String getAppealDescription() { return appealDescription; }
 
 	/**
 	 * 设置员工打卡记录分析结果申诉详细理由(String)
 	 * 
 	 * @param appealDescription
 	 */
-	public void setAppealDescription(String appealDescription) {
-		this.appealDescription = appealDescription;
-	}
+	public void setAppealDescription(String appealDescription) { this.appealDescription = appealDescription; }
 
 	/**
 	 * 获取员工缺勤时段:无,上午,下午,全天(String)
 	 * 
 	 * @return
 	 */
-	public String getAbsentDayTime() {
-		return absentDayTime;
-	}
+	public String getAbsentDayTime() { return absentDayTime; }
 
 	/**
 	 * 设置员工缺勤时段:无,上午,下午,全天(String)
 	 * 
 	 * @param absentDayTime
 	 */
-	public void setAbsentDayTime(String absentDayTime) {
-		this.absentDayTime = absentDayTime;
-	}
+	public void setAbsentDayTime(String absentDayTime) { this.absentDayTime = absentDayTime; }
 
 	/**
 	 * 获取员工打卡异常时段:无,上午,下午,全天(String)
 	 * 
 	 * @return
 	 */
-	public String getAbnormalDutyDayTime() {
-		return abnormalDutyDayTime;
-	}
+	public String getAbnormalDutyDayTime() { return abnormalDutyDayTime; }
 
 	/**
 	 * 设置员工打卡异常时段:无,上午,下午,全天(String)
 	 * 
 	 * @param abnormalDutyDayTime
 	 */
-	public void setAbnormalDutyDayTime(String abnormalDutyDayTime) {
-		this.abnormalDutyDayTime = abnormalDutyDayTime;
-	}
+	public void setAbnormalDutyDayTime(String abnormalDutyDayTime) { this.abnormalDutyDayTime = abnormalDutyDayTime; }
 
 	/**
 	 * 获取员工是否打卡异常(Integer)
 	 * 
 	 * @return
 	 */
-	public Boolean getIsAbnormalDuty() {
-		return isAbnormalDuty;
-	}
+	public Boolean getIsAbnormalDuty() { return isAbnormalDuty; }
 
 	/**
 	 * 设置员工是否打卡异常(Integer)
 	 * 
 	 * @param isAbnormalDuty
 	 */
-	public void setIsAbnormalDuty(Boolean isAbnormalDuty) {
-		this.isAbnormalDuty = isAbnormalDuty;
-	}
+	public void setIsAbnormalDuty(Boolean isAbnormalDuty) { this.isAbnormalDuty = isAbnormalDuty; }
 
-	public String getCycleYear() {
-		return cycleYear;
-	}
+	public String getCycleYear() { return cycleYear; }
 
-	public void setCycleYear(String cycleYear) {
-		this.cycleYear = cycleYear;
-	}
+	public void setCycleYear(String cycleYear) { this.cycleYear = cycleYear; }
 
-	public String getCycleMonth() {
-		return cycleMonth;
-	}
+	public String getCycleMonth() { return cycleMonth; }
 
-	public void setCycleMonth(String cycleMonth) {
-		this.cycleMonth = cycleMonth;
-	}
+	public void setCycleMonth(String cycleMonth) { this.cycleMonth = cycleMonth; }
 
-	public String getArchiveTime() {
-		return archiveTime;
-	}
+	public String getArchiveTime() { return archiveTime; }
 
-	public void setArchiveTime(String archiveTime) {
-		this.archiveTime = archiveTime;
-	}
+	public void setArchiveTime(String archiveTime) { this.archiveTime = archiveTime; }
 
-	public String getAppealProcessor() {
-		return appealProcessor;
-	}
+	public String getAppealProcessor() { return appealProcessor; }
 
-	public void setAppealProcessor(String appealProcessor) {
-		this.appealProcessor = appealProcessor;
-	}
+	public void setAppealProcessor(String appealProcessor) { this.appealProcessor = appealProcessor; }
+
+
+	public String getMiddayRestStartTime() { return middayRestStartTime; }
+
+	public void setMiddayRestStartTime(String middayRestStartTime) { this.middayRestStartTime = middayRestStartTime; }
+
+	public String getMiddayRestEndTime() { return middayRestEndTime; }
+
+	public void setMiddayRestEndTime(String middayRestEndTime) { this.middayRestEndTime = middayRestEndTime; }
 
 	/**
 	 * 清除对该条数据信息的分析结果

+ 40 - 12
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceScheduleSetting.java

@@ -14,6 +14,9 @@ import com.x.base.core.entity.SliceJpaObject;
 import com.x.base.core.entity.annotation.CheckPersist;
 import com.x.base.core.entity.annotation.ContainerEntity;
 import com.x.base.core.project.annotation.FieldDescribe;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+import java.util.Date;
 
 @ContainerEntity(dumpSize = 1000, type = ContainerEntity.Type.content, reference = ContainerEntity.Reference.strong)
 @Entity
@@ -59,18 +62,21 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + topUnitName_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	private String topUnitName;
 
 	public static final String unitName_FIELDNAME = "unitName";
 	@FieldDescribe("组织名称")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + unitName_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	private String unitName;
 
 	public static final String unitOu_FIELDNAME = "unitOu";
 	@FieldDescribe("组织编号")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitOu_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + unitOu_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	private String unitOu;
 
@@ -80,12 +86,30 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	private String onDutyTime;
 
+	public static final String middayRestStartTime_FIELDNAME = "middayRestStartTime";
+	@FieldDescribe("午休开始时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + onDutyTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestStartTime;
+
+	public static final String middayRestEndTime_FIELDNAME = "middayRestEndTime";
+	@FieldDescribe("午休结束时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestEndTime;
+
 	public static final String offDutyTime_FIELDNAME = "offDutyTime";
 	@FieldDescribe("下班时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String offDutyTime;
 
+	public static final String middayRestOpen_FIELDNAME = "middayRestOpen";
+	@FieldDescribe("是否启用午休:0-不启用 1-启用")
+	@Column( name = ColumnNamePrefix + lateStartTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private Integer middayRestOpen = 0;
+
 	public static final String lateStartTime_FIELDNAME = "lateStartTime";
 	@FieldDescribe("迟到起算时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + lateStartTime_FIELDNAME )
@@ -120,21 +144,25 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 		this.unitOu = unitOu;
 	}
 
-	public String getOnDutyTime() {
-		return onDutyTime;
-	}
+	public String getOnDutyTime() { return onDutyTime; }
 
-	public void setOnDutyTime(String onDutyTime) {
-		this.onDutyTime = onDutyTime;
-	}
+	public void setOnDutyTime(String onDutyTime) { this.onDutyTime = onDutyTime; }
 
-	public String getOffDutyTime() {
-		return offDutyTime;
-	}
+	public String getMiddayRestStartTime() { return middayRestStartTime; }
 
-	public void setOffDutyTime(String offDutyTime) {
-		this.offDutyTime = offDutyTime;
-	}
+	public void setMiddayRestStartTime(String middayRestStartTime) { this.middayRestStartTime = middayRestStartTime; }
+
+	public String getMiddayRestEndTime() { return middayRestEndTime; }
+
+	public void setMiddayRestEndTime(String middayRestEndTime) { this.middayRestEndTime = middayRestEndTime; }
+
+	public Integer getMiddayRestOpen() { return middayRestOpen; }
+
+	public void setMiddayRestOpen(Integer middayRestOpen) { this.middayRestOpen = middayRestOpen; }
+
+	public String getOffDutyTime() { return offDutyTime; }
+
+	public void setOffDutyTime(String offDutyTime) { this.offDutyTime = offDutyTime; }
 
 	public String getLateStartTime() {
 		return lateStartTime;

+ 12 - 6
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkDayConfig.java

@@ -54,33 +54,39 @@ public class AttendanceWorkDayConfig extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String configName_FIELDNAME = "configName";
 	@FieldDescribe("配置项名称")
-	@Column(name = "xconfigName", length = JpaObject.length_96B)
+	@Column(length = JpaObject.length_96B, name = ColumnNamePrefix + configName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String configName = "";
 
+	public static final String configYear_FIELDNAME = "configYear";
 	@FieldDescribe("配置年份")
-	@Column(name = "xconfigYear", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String configYear = "2016";
 
+	public static final String configMonth_FIELDNAME = "configMonth";
 	@FieldDescribe("配置月份")
-	@Column(name = "xconfigMonth", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String configMonth = "";
 
+	public static final String configDate_FIELDNAME = "configDate";
 	@FieldDescribe("配置日期")
-	@Column(name = "xconfigDate", length = JpaObject.length_32B)
+	@Column(length = JpaObject.length_32B, name = ColumnNamePrefix + configDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String configDate = "";
 
+	public static final String configType_FIELDNAME = "configType";
 	@FieldDescribe("配置类型:Holiday|Workday")
-	@Column(name = "xconfigType", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configType_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String configType = "Holiday";
 
+	public static final String description_FIELDNAME = "description";
 	@FieldDescribe("配置说明")
-	@Column(name = "xdescription", length = JpaObject.length_255B)
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + description_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String description = "";
 

+ 14 - 7
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkPlace.java

@@ -55,38 +55,45 @@ public class AttendanceWorkPlace extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String placeName_FIELDNAME = "placeName";
 	@FieldDescribe("场所名称")
-	@Column(name = "xplaceName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + placeName_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String placeName = "";
 
+	public static final String placeAlias_FIELDNAME = "placeAlias";
 	@FieldDescribe("场所别名")
-	@Column(name = "xplaceAlias", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + placeAlias_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String placeAlias = "";
 
+	public static final String creator_FIELDNAME = "creator";
 	@FieldDescribe("创建人")
-	@Column(name = "xcreator", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + creator_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String creator = "";
 
+	public static final String longitude_FIELDNAME = "longitude";
 	@FieldDescribe("经度")
-	@Column(name = "xlongitude", length = JpaObject.length_32B)
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + longitude_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String longitude = null;
 
+	public static final String latitude_FIELDNAME = "latitude";
 	@FieldDescribe("纬度")
-	@Column(name = "xlatitude", length = JpaObject.length_32B)
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + latitude_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String latitude = null;
 
+	public static final String errorRange_FIELDNAME = "errorRange";
 	@FieldDescribe("误差范围")
-	@Column(name = "xerrorRange")
+	@Column( name = ColumnNamePrefix + errorRange_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private Integer errorRange = 200;
 
+	public static final String description_FIELDNAME = "description";
 	@FieldDescribe("说明备注")
-	@Column(name = "xdescription", length = JpaObject.length_255B)
+	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + description_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	private String description = null;
 

+ 14 - 9
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/DingdingQywxSyncRecord.java

@@ -46,39 +46,44 @@ public class DingdingQywxSyncRecord extends SliceJpaObject  {
      * =============================================================================
      * =====
      */
-
+    public static final String startTime_FIELDNAME = "startTime";
     @FieldDescribe("同步开始时间")
-    @Column(name = ColumnNamePrefix + "syncStartTime")
+    @Column( name = ColumnNamePrefix + startTime_FIELDNAME )
     private Date startTime;
 
+    public static final String endTime_FIELDNAME = "endTime";
     @FieldDescribe("同步结束时间")
-    @Column(name = ColumnNamePrefix + "syncEndTime")
+    @Column( name = ColumnNamePrefix + endTime_FIELDNAME )
     private Date endTime;
 
     public static final String syncType_qywx = "qywx";
     public static final String syncType_dingding = "dingding";
+    public static final String type_FIELDNAME = "type";
     @FieldDescribe("同步类型,qywx(企业微信同步) , dingding(钉钉同步)")
-    @Column(name = ColumnNamePrefix + "type", length = length_32B)
+    @Column( length = length_32B, name = ColumnNamePrefix + type_FIELDNAME )
     private String type;
 
+    public static final String dateFrom_FIELDNAME = "dateFrom";
     @FieldDescribe("同步打卡记录的开始时间")
-    @Column(name = ColumnNamePrefix + "dateFrom")
+    @Column( name = ColumnNamePrefix + dateFrom_FIELDNAME )
     private long dateFrom;
 
+    public static final String dateTo_FIELDNAME = "dateTo";
     @FieldDescribe("同步打卡记录的结束时间, 起始与结束工作日最多相隔7天")
-    @Column(name = ColumnNamePrefix + "dateTo")
+    @Column( name = ColumnNamePrefix + dateTo_FIELDNAME )
     private long dateTo;
 
     public static final String status_loading = "loading";
     public static final String status_end = "end";
     public static final String status_error = "error";
+    public static final String status_FIELDNAME = "status";
     @FieldDescribe("同步状态,loading(正在进行) , end(结束) , error(执行异常)")
-    @Column(name = ColumnNamePrefix + "status", length = length_32B)
+    @Column( length = length_32B, name = ColumnNamePrefix + status_FIELDNAME )
     private String status;
 
-
+    public static final String exceptionMessage_FIELDNAME = "exceptionMessage";
     @FieldDescribe("异常信息")
-    @Column(name = ColumnNamePrefix + "exceptionMessage", length = length_255B)
+    @Column( length = length_255B, name = ColumnNamePrefix + exceptionMessage_FIELDNAME )
     private String exceptionMessage;
 
 

+ 26 - 15
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingPersonForMonth.java

@@ -50,64 +50,75 @@ public class StatisticDingdingPersonForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String o2User_FIELDNAME = "o2User";
 	@FieldDescribe("O2用户")
-	@Column(name = ColumnNamePrefix + "o2User", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2User_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2User;
 
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到次数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
-
 	public Long getResultNormal() {
 		return resultNormal;
 	}

+ 26 - 16
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForDay.java

@@ -50,65 +50,75 @@ public class StatisticDingdingUnitForDay extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
-
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤人数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到人数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到人数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
-
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到人数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工人数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡人数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
-
 	public Long getResultNormal() {
 		return resultNormal;
 	}

+ 24 - 13
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForMonth.java

@@ -51,56 +51,67 @@ public class StatisticDingdingUnitForMonth extends SliceJpaObject {
 	 * =====
 	 */
 
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到人数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到人数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到人数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工人数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡人数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
 	public Long getResultNormal() {

+ 30 - 15
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticPersonForMonth.java

@@ -64,69 +64,84 @@ public class StatisticPersonForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String employeeName_FIELDNAME = "employeeName";
 	@FieldDescribe("员工姓名")
-	@Column(name = "xemployeeName", length = JpaObject.length_96B)
+	@Column( length = JpaObject.length_96B, name = ColumnNamePrefix + employeeName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String employeeName;
 
+	public static final String unitName_FIELDNAME = "unitName";
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("应出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Double workDayCount;
 
+	public static final String onDutyDayCount_FIELDNAME = "onDutyDayCount";
 	@FieldDescribe("实际出勤天数")
-	@Column(name = "xonDutyDayCount")
+	@Column( name = ColumnNamePrefix + onDutyDayCount_FIELDNAME )
 	private Double onDutyDayCount;
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("签退次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足次数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 
 	public String getEmployeeName() {

+ 26 - 14
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxPersonForMonth.java

@@ -50,61 +50,73 @@ public class StatisticQywxPersonForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String o2User_FIELDNAME = "o2User";
 	@FieldDescribe("O2用户")
-	@Column(name = ColumnNamePrefix + "o2User", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2User_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2User;
 
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
 	public Long getOutsideDutyTimes() {

+ 29 - 18
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForDay.java

@@ -50,64 +50,75 @@ public class StatisticQywxUnitForDay extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
-
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
-	@CheckPersist(allowEmpty = false)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
+	@CheckPersist(allowEmpty = false )
 	private String o2Unit;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
-	@CheckPersist(allowEmpty = false)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
+	@CheckPersist(allowEmpty = false )
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
-	@CheckPersist(allowEmpty = false)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
+	@CheckPersist(allowEmpty = false )
 	private String statisticDate;
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
-
 	public Long getResultNormal() {
 		return resultNormal;
 	}

+ 24 - 14
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForMonth.java

@@ -50,57 +50,67 @@ public class StatisticQywxUnitForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
-
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String xworkDayCount_FIELDNAME = "xworkDayCount";
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + xworkDayCount_FIELDNAME )
 	private Long workDayCount;
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 
 	public Long getResultNormal() {

+ 28 - 14
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForDay.java

@@ -64,64 +64,78 @@ public class StatisticTopUnitForDay extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 
+	public static final String onSelfHolidayEmployeeCount_FIELDNAME = "onSelfHolidayEmployeeCount";
 	@FieldDescribe("休假人数")
-	@Column(name = "xonSelfHolidayEmployeeCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayEmployeeCount_FIELDNAME )
 	private Double onSelfHolidayEmployeeCount;
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 
 	public String getTopUnitName() {

+ 26 - 13
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForMonth.java

@@ -64,59 +64,72 @@ public class StatisticTopUnitForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人天数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人天数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假人天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人次")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人次")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 
 	public String getTopUnitName() {

+ 30 - 15
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForDay.java

@@ -70,69 +70,84 @@ public class StatisticUnitForDay extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String unitName_FIELDNAME = "unitName";
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 
+	public static final String onSelfHolidayEmployeeCount_FIELDNAME = "onSelfHolidayEmployeeCount";
 	@FieldDescribe("休假人数")
-	@Column(name = "xonSelfHolidayEmployeeCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayEmployeeCount_FIELDNAME )
 	private Double onSelfHolidayEmployeeCount;
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 
 	public String getUnitName() {

+ 28 - 14
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForMonth.java

@@ -89,64 +89,78 @@ public class StatisticUnitForMonth extends SliceJpaObject {
 	 * =============================================================================
 	 * =====
 	 */
+	public static final String unitName_FIELDNAME = "unitName";
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假人天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人次")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 
 	public String getUnitName() {