Explorar el Código

Merge branch 'develop' into 'fix/Calendar.load_execption'

# Conflicts:
#   o2web/source/x_component_process_FormDesigner/Module/Form/skin/styles_mobile-blue-flat.json
蔡祥熠 hace 5 años
padre
commit
826c8a8ad8
Se han modificado 100 ficheros con 5480 adiciones y 2766 borrados
  1. 21 0
      o2server/configSample/clientInit.json
  2. 265 0
      o2server/configSample/components.json
  3. 21 0
      o2server/configSample/portal.json
  4. 8 0
      o2server/configSample/pushConfig.json
  5. 9 5
      o2server/x_attendance_assemble_control/pom.xml
  6. 35 55
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java
  7. 119 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueAttendanceDetailStatistic.java
  8. 2 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingAttendance.java
  9. 2 4
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingPersonStatistic.java
  10. 2 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingUnitStatistic.java
  11. 66 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueuePersonAttendanceDetailAnalyse.java
  12. 2 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxAttendanceSync.java
  13. 2 3
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxPersonStatistic.java
  14. 2 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxUnitStatistic.java
  15. 17 9
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java
  16. 26 5
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailMobileFactory.java
  17. 10 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealAudit.java
  18. 13 3
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealCheck.java
  19. 34 27
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealCreate.java
  20. 118 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealCreateWithWorkFlow.java
  21. 0 112
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealProcessFirst.java
  22. 0 114
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealProcessSecond.java
  23. 0 228
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAttendanceDetailAppeal.java
  24. 0 46
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAttendanceDetailArchive.java
  25. 146 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionWorkFlowSync.java
  26. 56 4
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/AttendanceAppealInfoAction.java
  27. 12 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ExceptionAppealAuditInfoNotExists.java
  28. 1 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionListMobileWithFilter.java
  29. 447 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionListMyMobileRecordToday.java
  30. 74 60
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionReciveAttendance.java
  31. 29 29
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionReciveAttendanceMobile.java
  32. 23 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/AttendanceDetailMobileAction.java
  33. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionDelete.java
  34. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/ActionSave.java
  35. 5 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancestatisticalcycle/BaseAction.java
  36. 6 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionDelete.java
  37. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceworkdayconfig/ActionSave.java
  38. 14 10
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDelete.java
  39. 13 13
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionDeleteByWfDocId.java
  40. 18 21
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/selfholiday/ActionSave.java
  41. 2 27
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/processor/thread/OperatorDataAnalyse.java
  42. 55 15
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceAppealInfoService.java
  43. 71 9
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceAppealInfoServiceAdv.java
  44. 306 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseCoreService.java
  45. 401 767
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseService.java
  46. 104 13
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseServiceAdv.java
  47. 206 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseSignProxy1.java
  48. 247 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseSignProxy2.java
  49. 285 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailAnalyseSignProxy3.java
  50. 1 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseService.java
  51. 3 7
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileAnalyseServiceAdv.java
  52. 5 1
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailMobileService.java
  53. 53 87
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceDetailServiceAdv.java
  54. 2 2
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceSettingService.java
  55. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticRequireLogServiceAdv.java
  56. 111 63
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticServiceAdv.java
  57. 44 26
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleService.java
  58. 29 13
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceStatisticalCycleServiceAdv.java
  59. 21 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceWorkDayConfigService.java
  60. 4 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceWorkDayConfigServiceAdv.java
  61. 107 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/ComposeDetailWithMobileInSignProxy1.java
  62. 153 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/ComposeDetailWithMobileInSignProxy2.java
  63. 198 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/ComposeDetailWithMobileInSignProxy3.java
  64. 3 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/UserManagerService.java
  65. 244 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/WorkFlowSyncService.java
  66. 1 1
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAdmin.java
  67. 14 11
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAppealAuditInfo.java
  68. 148 152
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAppealInfo.java
  69. 135 258
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetail.java
  70. 27 2
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetailMobile.java
  71. 5 4
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDingtalkDetail.java
  72. 5 5
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceEmployeeConfig.java
  73. 5 4
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceQywxDetail.java
  74. 68 20
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceScheduleSetting.java
  75. 0 1
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceSetting.java
  76. 12 6
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkDayConfig.java
  77. 14 7
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceWorkPlace.java
  78. 126 198
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/DateOperation.java
  79. 14 9
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/DingdingQywxSyncRecord.java
  80. 26 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingPersonForMonth.java
  81. 26 16
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForDay.java
  82. 24 13
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForMonth.java
  83. 30 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticPersonForMonth.java
  84. 26 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxPersonForMonth.java
  85. 29 18
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForDay.java
  86. 24 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticQywxUnitForMonth.java
  87. 28 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForDay.java
  88. 26 13
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticTopUnitForMonth.java
  89. 30 15
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForDay.java
  90. 28 14
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticUnitForMonth.java
  91. 177 105
      o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject.java
  92. 15 21
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/build/CreateConfigSample.java
  93. 9 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ClientInit.java
  94. 1 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/exception/PromptException.java
  95. 1 1
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/service/BBSConfigSettingService.java
  96. 9 0
      o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/service/BBSForumSubjectStatisticService.java
  97. 21 5
      o2server/x_calendar_assemble_control/src/main/java/com/x/calendar/assemble/control/service/CalendarService.java
  98. 1 1
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/categoryinfo/ActionDelete.java
  99. 2 3
      o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueDocumentDelete.java
  100. 84 0
      o2server/x_hotpic_assemble_control/src/main/java/com/x/hotpic/assemble/control/jaxrs/hotpic/HotPictureInfoCipherAction.java

+ 21 - 0
o2server/configSample/clientInit.json

@@ -0,0 +1,21 @@
+{
+  "enable": false,
+  "center": [
+    {}
+  ],
+  "footer": "",
+  "title": "",
+  "app_protocol": "auto",
+  "loginPage": {
+    "###enable": "是否启用定制的登录页面.###",
+    "###portal": "登录的门户.###",
+    "###page": "登录页面.###"
+  },
+  "###enable": "是否启用.###",
+  "###center": "center节点信息.###",
+  "###footer": "网页底部说明.###",
+  "###title": "网页头部说明.###",
+  "###app_protocol": "APP使用协议,auto,http,https.###",
+  "###loginPage": "登录页面配置.###",
+  "###webSocketEnable": "是否启用webSocket###"
+}

+ 265 - 0
o2server/configSample/components.json

@@ -0,0 +1,265 @@
+{
+  "systems": [
+    {
+      "name": "Setting",
+      "path": "Setting",
+      "title": "系统设置",
+      "iconPath": "appicon.png",
+      "orderNumber": 1.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Org",
+      "path": "Org",
+      "title": "组织管理",
+      "iconPath": "appicon.png",
+      "orderNumber": 2.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "cmsManager",
+      "path": "cms.Column",
+      "title": "内容管理平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 3.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "cms",
+      "path": "cms.Index",
+      "title": "信息平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 12.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "ApplicationExplorer",
+      "path": "process.ApplicationExplorer",
+      "title": "流程管理平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 4.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "PortalExplorer",
+      "path": "portal.PortalExplorer",
+      "title": "门户管理平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 5.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "DataExplorer",
+      "path": "query.QueryExplorer",
+      "title": "数据中心平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 6.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "service.ServiceManager",
+      "path": "service.ServiceManager",
+      "title": "服务管理平台",
+      "iconPath": "appicon.png",
+      "orderNumber": 7.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "AppMarket",
+      "path": "AppMarket",
+      "title": "应用市场",
+      "iconPath": "appicon.png",
+      "orderNumber": 8.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "AppCenter",
+      "path": "AppCenter",
+      "title": "应用管理",
+      "iconPath": "appicon.png",
+      "orderNumber": 9.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "LogViewer",
+      "path": "LogViewer",
+      "title": "日志",
+      "iconPath": "appicon.png",
+      "orderNumber": 10.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Profile",
+      "path": "Profile",
+      "title": "个人设置",
+      "iconPath": "appicon.png",
+      "orderNumber": 11.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "BAM",
+      "path": "BAM",
+      "title": "流程监控",
+      "iconPath": "appicon.png",
+      "orderNumber": 12.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "TaskCenter",
+      "path": "process.TaskCenter",
+      "title": "办公中心",
+      "iconPath": "appicon.png",
+      "orderNumber": 13.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Homepage",
+      "path": "Homepage",
+      "title": "首页",
+      "iconPath": "appicon.png",
+      "orderNumber": 14.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "HotArticle",
+      "path": "HotArticle",
+      "title": "热点",
+      "iconPath": "appicon.png",
+      "orderNumber": 15.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "File",
+      "path": "File",
+      "title": "云文件",
+      "iconPath": "appicon.png",
+      "orderNumber": 16.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Note",
+      "path": "Note",
+      "title": "便签",
+      "iconPath": "appicon.png",
+      "orderNumber": 17.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Meeting",
+      "path": "Meeting",
+      "title": "会议管理",
+      "iconPath": "appicon.png",
+      "orderNumber": 18.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "OnlineMeeting",
+      "path": "OnlineMeeting",
+      "title": "网络会议",
+      "iconPath": "appicon.png",
+      "orderNumber": 19.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Attendance",
+      "path": "Attendance",
+      "title": "考勤管理",
+      "iconPath": "appicon.png",
+      "orderNumber": 20.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Forum",
+      "path": "Forum",
+      "title": "论坛",
+      "iconPath": "appicon.png",
+      "orderNumber": 21.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Minder",
+      "path": "Minder",
+      "title": "脑图编辑器",
+      "iconPath": "appicon.png",
+      "orderNumber": 22.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Calendar",
+      "path": "Calendar",
+      "title": "日程安排",
+      "iconPath": "appicon.png",
+      "orderNumber": 23.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "ANN",
+      "path": "ANN",
+      "title": "神经网络",
+      "iconPath": "appicon.png",
+      "orderNumber": 24.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    },
+    {
+      "name": "Search",
+      "path": "Search",
+      "title": "搜索",
+      "iconPath": "appicon.png",
+      "orderNumber": 25.0,
+      "type": "system",
+      "allowList": [],
+      "dentyList": []
+    }
+  ],
+  "###systems": "默认模块###"
+}

+ 21 - 0
o2server/configSample/portal.json

@@ -0,0 +1,21 @@
+{
+  "indexPage": {
+    "enable": false,
+    "portal": "",
+    "page": "",
+    "###enable": "是否启用定制的首页面.###",
+    "###portal": "指定首页面所属的portal,可以用id,name,alias.###",
+    "###page": "指定的首页面,可以使用name,alias,id###"
+  },
+  "loginPage": {
+    "enable": false,
+    "portal": "",
+    "page": "",
+    "###enable": "是否启用定制登录页面.###",
+    "###portal": "指定登录页面所属的portal,可以用id,name,alias.###",
+    "###page": "指定的登录页面,可以使用name,alias,id###"
+  },
+  "###urlMapping": "url转换配置.###",
+  "###indexPage": "定制首页面设置.###",
+  "###loginPage": "定制登录页面设置.###"
+}

+ 8 - 0
o2server/configSample/pushConfig.json

@@ -0,0 +1,8 @@
+{
+  "enable": false,
+  "appKey": "9aca7cc20fe0cc987cd913ca",
+  "masterSecret": "96ee7e2e0daffd51bac57815",
+  "###enable": "是否启用.###",
+  "###appKey": "极光推送应用的AppKey###",
+  "###masterSecret": "极光推送应用的Master Secret###"
+}

+ 9 - 5
o2server/x_attendance_assemble_control/pom.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <?xml version="1.0"?>
 <project
 <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>
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 	<parent>
 		<groupId>o2oa</groupId>
 		<groupId>o2oa</groupId>
@@ -24,7 +24,11 @@
 			<groupId>o2oa</groupId>
 			<groupId>o2oa</groupId>
 			<artifactId>x_organization_core_express</artifactId>
 			<artifactId>x_organization_core_express</artifactId>
 		</dependency>
 		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>o2oa</groupId>
+            <artifactId>x_processplatform_core_entity</artifactId>
+        </dependency>
+    </dependencies>
 	<build>
 	<build>
 		<plugins>
 		<plugins>
 			<plugin>
 			<plugin>
@@ -122,4 +126,4 @@
 			</plugin>
 			</plugin>
 		</plugins>
 		</plugins>
 	</build>
 	</build>
-</project>
+</project>

+ 35 - 55
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/common/date/DateOperation.java

@@ -149,26 +149,25 @@ public class DateOperation {
 		}
 		}
 		return dateString;
 		return dateString;
 	}
 	}
-	
+
 	/**
 	/**
 	 * 得到某日期加上或减去天数后的日期,day为负数时减去
 	 * 得到某日期加上或减去天数后的日期,day为负数时减去
-	 * 
-	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd"
-	 * @throws Exception 
+	 * @param dateString
+	 * @param day
+	 * @param style
+	 * @return
+	 * @throws Exception
 	 */
 	 */
 	public  String getDayAdd(String dateString, int day, String style) throws Exception {
 	public  String getDayAdd(String dateString, int day, String style) throws Exception {
 		Date date = getDateFromString(dateString, style);
 		Date date = getDateFromString(dateString, style);
 		return getDayAdd(date, day);
 		return getDayAdd(date, day);
 	}
 	}
-	
+
 	/**
 	/**
 	 * 得到某日期加上或减去天数后的日期,day为负数时减去
 	 * 得到某日期加上或减去天数后的日期,day为负数时减去
-	 * 
 	 * @param date
 	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd"
+	 * @param day
+	 * @return
 	 */
 	 */
 	public  String getDayAdd(Date date, int day) {
 	public  String getDayAdd(Date date, int day) {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
@@ -190,13 +189,12 @@ public class DateOperation {
 		calendar.add(Calendar.MONTH, month);
 		calendar.add(Calendar.MONTH, month);
 		return format1.format(calendar.getTime());
 		return format1.format(calendar.getTime());
 	}
 	}
-	
+
 	/**
 	/**
 	 * 得到某日期加上或减去分钟后的日期,min为负数时减去
 	 * 得到某日期加上或减去分钟后的日期,min为负数时减去
-	 * 
 	 * @param date
 	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd HH:mi:ss"
+	 * @param min
+	 * @return
 	 */
 	 */
 	public  String getMinutesAdd(Date date, int min) {
 	public  String getMinutesAdd(Date date, int min) {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
@@ -204,11 +202,10 @@ public class DateOperation {
 		calendar.add(Calendar.MINUTE, min);
 		calendar.add(Calendar.MINUTE, min);
 		return format3.format(calendar.getTime());
 		return format3.format(calendar.getTime());
 	}
 	}
+
 	/**
 	/**
 	 * 得到某日期的日
 	 * 得到某日期的日
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getDay(Date date) {
 	public  String getDay(Date date) {
@@ -227,11 +224,10 @@ public class DateOperation {
 		}
 		}
 		return Integer.parseInt(result);
 		return Integer.parseInt(result);
 	}
 	}
+
 	/**
 	/**
 	 * 得到某日期的月份
 	 * 得到某日期的月份
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getMonth(Date date) {
 	public  String getMonth(Date date) {
@@ -253,9 +249,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某日期的年份
 	 * 得到某日期的年份
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getYear(Date date) {
 	public  String getYear(Date date) {
@@ -274,11 +268,10 @@ public class DateOperation {
 		}
 		}
 		return Integer.parseInt(result);
 		return Integer.parseInt(result);
 	}
 	}
+
 	/**
 	/**
 	 * 得到某日期的小时
 	 * 得到某日期的小时
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getHour(Date date) {
 	public  String getHour(Date date) {
@@ -288,31 +281,28 @@ public class DateOperation {
 			return "0";
 			return "0";
 		}
 		}
 	}
 	}
+
 	/**
 	/**
 	 * 得到某日期的分钟
 	 * 得到某日期的分钟
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getMinites(Date date) {
 	public  String getMinites(Date date) {
 		return format12.format(date);
 		return format12.format(date);
 	}
 	}
+
 	/**
 	/**
 	 * 得到某日期的秒
 	 * 得到某日期的秒
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 */
 	 */
 	public  String getSeconds(Date date) {
 	public  String getSeconds(Date date) {
 		return format13.format(date);
 		return format13.format(date);
 	}
 	}
+
 	/**
 	/**
 	 * 得到某年有多少天
 	 * 得到某年有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM-dd"
+	 * @param date
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -325,9 +315,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某年有多少天
 	 * 得到某年有多少天
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -340,9 +328,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某年有多少天
 	 * 得到某年有多少天
-	 * 
-	 * @param String
-	 *            year "yyyy"
+	 * @param year
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -355,9 +341,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某月有多少天
 	 * 得到某月有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM-dd"
+	 * @param date
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -369,9 +353,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某月有多少天
 	 * 得到某月有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM"
+	 * @param date
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -384,9 +366,7 @@ public class DateOperation {
 
 
 	/**
 	/**
 	 * 得到某月有多少天
 	 * 得到某月有多少天
-	 * 
-	 * @param Date
-	 *            date
+	 * @param date
 	 * @return
 	 * @return
 	 * @throws ParseException
 	 * @throws ParseException
 	 */
 	 */
@@ -468,12 +448,12 @@ public class DateOperation {
 		dayNumber = (date2.getTime() - date1.getTime()) / mins;
 		dayNumber = (date2.getTime() - date1.getTime()) / mins;
 		return dayNumber;
 		return dayNumber;
 	}
 	}
+
 	/**
 	/**
-	 * 
-	 * 日期格式转换
-	 * 从YYYY-MM-DD转换到YYYYMMDD
-	 * @param date
-	 * @throws ParseException 
+	 * 日期格式转换 从YYYY-MM-DD转换到YYYYMMDD
+	 * @param dateString
+	 * @return
+	 * @throws ParseException
 	 */
 	 */
 	public  String changeDateFormat(String dateString) throws ParseException{
 	public  String changeDateFormat(String dateString) throws ParseException{
 		Date date;
 		Date date;

+ 119 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueAttendanceDetailStatistic.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 QueueAttendanceDetailStatistic extends AbstractQueue<String> {
+
+    private static final Logger logger = LoggerFactory.getLogger(QueueAttendanceDetailStatistic.class);
+
+    @Override
+    protected void execute( String logId ) throws Exception {
+        AttendanceStatisticRequireLogServiceAdv statisticRequireLogServiceAdv = new AttendanceStatisticRequireLogServiceAdv();
+        AttendanceWorkDayConfigServiceAdv workDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+        AttendanceStatisticServiceAdv statisticServiceAdv = new AttendanceStatisticServiceAdv();
+        AttendanceStatisticalCycleServiceAdv statisticalCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+        AttendanceStatisticRequireLog log = statisticRequireLogServiceAdv.get(logId);
+
+        Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+        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 = workDayConfigServiceAdv.getAllWorkDayConfigWithCache(false );
+            } catch ( Exception e ) {
+                logger.warn("【统计】系统在查询当月有打卡记录的员工姓名列表时发生异常!" );
+                logger.error(e);
+            }
+
+            try{//查询所有的考勤统计周期信息,并且组织成MAP
+                statisticalCycleMap = statisticalCycleServiceAdv.getAllStatisticalCycleMapWithCache(false);
+            }catch(Exception e){
+                logger.warn( "【统计】系统在查询并且组织所有的考勤统计周期信息时发生异常。" );
+                logger.error(e);
+            }
+
+            //先处理所有的统计错误
+            try {
+                logger.debug( false, "准备处理恢复的统计错误信息, 所有错误统计将会重新计算......" );
+                statisticRequireLogServiceAdv.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 = statisticalCycleServiceAdv.getStatisticCycleByEmployee( log, statisticalCycleMap, false );
+                } catch (Exception e) {
+                    logger.warn("【统计】系统在根据统计需求记录信息查询统计周期信息时发生异常!" );
+                    logger.error(e);
+                }
+                if( attendanceStatisticalCycle != null ){
+                    try{
+                        statisticServiceAdv.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{
+                    statisticServiceAdv.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{
+                    statisticServiceAdv.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{
+                    statisticServiceAdv.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{
+                    statisticServiceAdv.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 );
+        }
+    }
+}

+ 2 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingAttendanceQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingAttendance.java

@@ -34,9 +34,9 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class DingdingAttendanceQueue extends AbstractQueue<DingdingQywxSyncRecord> {
+public class QueueDingdingAttendance extends AbstractQueue<DingdingQywxSyncRecord> {
 
 
-    private static final Logger logger = LoggerFactory.getLogger(DingdingAttendanceQueue.class);
+    private static final Logger logger = LoggerFactory.getLogger(QueueDingdingAttendance.class);
 
 
     @Override
     @Override
     protected void execute(DingdingQywxSyncRecord record) throws Exception {
     protected void execute(DingdingQywxSyncRecord record) throws Exception {

+ 2 - 4
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingPersonStatisticQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingPersonStatistic.java

@@ -2,8 +2,6 @@ package com.x.attendance.assemble.control;
 
 
 import com.x.attendance.entity.AttendanceDingtalkDetail;
 import com.x.attendance.entity.AttendanceDingtalkDetail;
 import com.x.attendance.entity.StatisticDingdingPersonForMonth;
 import com.x.attendance.entity.StatisticDingdingPersonForMonth;
-import com.x.attendance.entity.StatisticDingdingUnitForDay;
-import com.x.attendance.entity.StatisticDingdingUnitForMonth;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.project.Application;
 import com.x.base.core.project.Application;
@@ -25,8 +23,8 @@ import java.util.List;
  * Created by fancyLou on 2020-04-05.
  * Created by fancyLou on 2020-04-05.
  * Copyright © 2020 O2. All rights reserved.
  * Copyright © 2020 O2. All rights reserved.
  */
  */
-public class DingdingPersonStatisticQueue extends AbstractQueue<Date> {
-    private static final Logger logger = LoggerFactory.getLogger(DingdingPersonStatisticQueue.class);
+public class QueueDingdingPersonStatistic extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(QueueDingdingPersonStatistic.class);
 
 
     @Override
     @Override
     protected void execute(Date date) throws Exception {
     protected void execute(Date date) throws Exception {

+ 2 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingUnitStatisticQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueDingdingUnitStatistic.java

@@ -19,8 +19,8 @@ import java.util.List;
  * Created by fancyLou on 2020-04-05.
  * Created by fancyLou on 2020-04-05.
  * Copyright © 2020 O2. All rights reserved.
  * Copyright © 2020 O2. All rights reserved.
  */
  */
-public class DingdingUnitStatisticQueue extends AbstractQueue<Date> {
-    private static final Logger logger = LoggerFactory.getLogger(DingdingUnitStatisticQueue.class);
+public class QueueDingdingUnitStatistic extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(QueueDingdingUnitStatistic.class);
 
 
     @Override
     @Override
     protected void execute(Date date) throws Exception {
     protected void execute(Date date) throws Exception {

+ 66 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueuePersonAttendanceDetailAnalyse.java

@@ -0,0 +1,66 @@
+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.AttendanceDetail;
+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 net.sf.ehcache.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 对单个员工的打卡信息进行分析的队列
+ */
+public class QueuePersonAttendanceDetailAnalyse extends AbstractQueue<String> {
+
+    private static final Logger logger = LoggerFactory.getLogger(QueuePersonAttendanceDetailAnalyse.class);
+
+    @Override
+    protected void execute( String detailId ) throws Exception {
+        AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+        AttendanceStatisticalCycleServiceAdv statisticalCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+        AttendanceDetailAnalyseServiceAdv detailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
+        AttendanceDetailServiceAdv detailServiceAdv = new AttendanceDetailServiceAdv();
+        AttendanceDetail record = detailServiceAdv.get( detailId );
+        if( record != null ){
+            logger.debug("system try to analyse attendance detail for person, Id:" + record.getId() );
+
+            Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+            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 );
+        }
+
+    }
+
+
+}

+ 2 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QywxAttendanceSyncQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxAttendanceSync.java

@@ -33,9 +33,9 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
-public class QywxAttendanceSyncQueue  extends AbstractQueue<DingdingQywxSyncRecord> {
+public class QueueQywxAttendanceSync extends AbstractQueue<DingdingQywxSyncRecord> {
 
 
-    private static final Logger logger = LoggerFactory.getLogger(QywxAttendanceSyncQueue.class);
+    private static final Logger logger = LoggerFactory.getLogger(QueueQywxAttendanceSync.class);
 
 
 
 
     @Override
     @Override

+ 2 - 3
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QywxPersonStatisticQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxPersonStatistic.java

@@ -1,6 +1,5 @@
 package com.x.attendance.assemble.control;
 package com.x.attendance.assemble.control;
 
 
-import com.x.attendance.entity.AttendanceDingtalkDetail;
 import com.x.attendance.entity.AttendanceQywxDetail;
 import com.x.attendance.entity.AttendanceQywxDetail;
 import com.x.attendance.entity.StatisticQywxPersonForMonth;
 import com.x.attendance.entity.StatisticQywxPersonForMonth;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
@@ -25,8 +24,8 @@ import java.util.stream.Collectors;
  * Created by fancyLou on 2020-04-05.
  * Created by fancyLou on 2020-04-05.
  * Copyright © 2020 O2. All rights reserved.
  * Copyright © 2020 O2. All rights reserved.
  */
  */
-public class QywxPersonStatisticQueue extends AbstractQueue<Date> {
-    private static final Logger logger = LoggerFactory.getLogger(QywxPersonStatisticQueue.class);
+public class QueueQywxPersonStatistic extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(QueueQywxPersonStatistic.class);
 
 
     @Override
     @Override
     protected void execute(Date date) throws Exception {
     protected void execute(Date date) throws Exception {

+ 2 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QywxUnitStatisticQueue.java → o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/QueueQywxUnitStatistic.java

@@ -18,8 +18,8 @@ import java.util.stream.Collectors;
  * Created by fancyLou on 2020-04-05.
  * Created by fancyLou on 2020-04-05.
  * Copyright © 2020 O2. All rights reserved.
  * Copyright © 2020 O2. All rights reserved.
  */
  */
-public class QywxUnitStatisticQueue extends AbstractQueue<Date> {
-    private static final Logger logger = LoggerFactory.getLogger(QywxUnitStatisticQueue.class);
+public class QueueQywxUnitStatistic extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(QueueQywxUnitStatistic.class);
 
 
     @Override
     @Override
     protected void execute(Date date) throws Exception {
     protected void execute(Date date) throws Exception {

+ 17 - 9
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java

@@ -16,25 +16,29 @@ public class ThisApplication {
 		return context;
 		return context;
 	}
 	}
 
 
-	public static DingdingAttendanceQueue dingdingQueue = new DingdingAttendanceQueue();
-	public static QywxAttendanceSyncQueue qywxQueue = new QywxAttendanceSyncQueue();
-	public static QywxUnitStatisticQueue unitQywxStatisticQueue = new QywxUnitStatisticQueue();
-	public static QywxPersonStatisticQueue personQywxStatisticQueue = new QywxPersonStatisticQueue();
+	public static QueueDingdingAttendance dingdingQueue = new QueueDingdingAttendance();
+	public static QueueQywxAttendanceSync qywxQueue = new QueueQywxAttendanceSync();
+	public static QueueQywxUnitStatistic unitQywxStatisticQueue = new QueueQywxUnitStatistic();
+	public static QueueQywxPersonStatistic personQywxStatisticQueue = new QueueQywxPersonStatistic();
+	public static QueueDingdingPersonStatistic personStatisticQueue = new QueueDingdingPersonStatistic();
+	public static QueueDingdingUnitStatistic unitStatisticQueue = new QueueDingdingUnitStatistic();
 
 
-	public static DingdingPersonStatisticQueue personStatisticQueue = new DingdingPersonStatisticQueue();
-	public static DingdingUnitStatisticQueue unitStatisticQueue = new DingdingUnitStatisticQueue();
+	public static QueuePersonAttendanceDetailAnalyse detailAnalyseQueue = new QueuePersonAttendanceDetailAnalyse();
+	public static QueueAttendanceDetailStatistic detailStatisticQueue = new QueueAttendanceDetailStatistic();
 
 
 
 
 	public static void init() throws Exception {
 	public static void init() throws Exception {
 		try {
 		try {
+
 			new AttendanceSettingService().initAllSystemConfig();
 			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())) {
 			if (BooleanUtils.isTrue(Config.dingding().getAttendanceSyncEnable())) {
 				dingdingQueue.start();
 				dingdingQueue.start();
 				personStatisticQueue.start();
 				personStatisticQueue.start();
 				unitStatisticQueue.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(DingdingAttendanceStatisticScheduleTask.class, "0 0 3 * * ?");
 //				context.schedule(DingdingAttendanceStatisticPersonScheduleTask.class, "0 0 3 * * ?");
 //				context.schedule(DingdingAttendanceStatisticPersonScheduleTask.class, "0 0 3 * * ?");
@@ -45,6 +49,10 @@ public class ThisApplication {
 				personQywxStatisticQueue.start();
 				personQywxStatisticQueue.start();
 				context.schedule(QywxAttendanceSyncScheduleTask.class, "0 0 1 * * ?");
 				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) {
 		} catch (Exception e) {
 			e.printStackTrace();
 			e.printStackTrace();
 		}
 		}

+ 26 - 5
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/AttendanceDetailMobileFactory.java

@@ -24,13 +24,13 @@ public class AttendanceDetailMobileFactory extends AbstractFactory {
 	}
 	}
 
 
 	public List<String> listByEmployeeNameDateAndTime( String empName, String recordDateString, String signTime ) throws Exception {
 	public List<String> listByEmployeeNameDateAndTime( String empName, String recordDateString, String signTime ) throws Exception {
-		if( empName == null || empName.isEmpty() ){
+		if( StringUtils.isEmpty( empName ) ){
 			throw new Exception("empName is null!");
 			throw new Exception("empName is null!");
 		}
 		}
-		if( recordDateString == null || recordDateString.isEmpty() ){
+		if( StringUtils.isEmpty( recordDateString ) ){
 			throw new Exception("recordDateString is null!");
 			throw new Exception("recordDateString is null!");
 		}
 		}
-		if( signTime == null || signTime.isEmpty() ){
+		if( StringUtils.isEmpty( signTime ) ){
 			throw new Exception("signTime is null!");
 			throw new Exception("signTime is null!");
 		}
 		}
 		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
 		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
@@ -52,10 +52,10 @@ public class AttendanceDetailMobileFactory extends AbstractFactory {
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
 	public List<AttendanceDetailMobile> listAttendanceDetailMobileWithEmployee( String empName, String recordDateString) throws Exception {
 	public List<AttendanceDetailMobile> listAttendanceDetailMobileWithEmployee( String empName, String recordDateString) throws Exception {
-		if( empName == null || empName.isEmpty() ){
+		if( StringUtils.isEmpty( empName ) ){
 			throw new Exception("empName is null!");
 			throw new Exception("empName is null!");
 		}
 		}
-		if( recordDateString == null || recordDateString.isEmpty() ){
+		if( StringUtils.isEmpty( recordDateString ) ){
 			throw new Exception("recordDateString is null!");
 			throw new Exception("recordDateString is null!");
 		}
 		}
 		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
 		EntityManager em = this.entityManagerContainer().get(AttendanceDetailMobile.class);
@@ -140,6 +140,27 @@ public class AttendanceDetailMobileFactory extends AbstractFactory {
 		return em.createQuery(cq.where(p)).setMaxResults( selectTotal ).getResultList();
 		return em.createQuery(cq.where(p)).setMaxResults( selectTotal ).getResultList();
 	}
 	}
 
 
+	public List<AttendanceDetailMobile> listAttendanceDetailMobile( String distinguishedName, String signDate ) throws Exception {
+		if( StringUtils.isEmpty( distinguishedName ) ){
+			throw new Exception("distinguishedName is null!");
+		}
+		if( StringUtils.isEmpty( signDate ) ){
+			throw new Exception("signDate is null!");
+		}
+		EntityManager em = this.entityManagerContainer().get( AttendanceDetailMobile.class );
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<AttendanceDetailMobile> cq = cb.createQuery(AttendanceDetailMobile.class);
+		Root<AttendanceDetailMobile> root = cq.from(AttendanceDetailMobile.class);
+		Predicate p = cb.isNotNull( root.get( AttendanceDetailMobile_.id ) );
+		if( StringUtils.isNotEmpty( distinguishedName ) ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.empNo ), distinguishedName ) );
+		}
+		if( StringUtils.isNotEmpty( signDate ) ){
+			p = cb.and( p, cb.equal( root.get( AttendanceDetailMobile_.recordDateString ), signDate ) );
+		}
+		return em.createQuery(cq.where(p)).setMaxResults( 100 ).getResultList();
+	}
+
 	public AttendanceDetailMobile get(String id) throws Exception {
 	public AttendanceDetailMobile get(String id) throws Exception {
 		return this.entityManagerContainer().find(id, AttendanceDetailMobile.class );
 		return this.entityManagerContainer().find(id, AttendanceDetailMobile.class );
 	}
 	}

+ 10 - 2
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealAudit.java

@@ -10,6 +10,7 @@ import com.google.gson.JsonElement;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.Logger;
@@ -19,8 +20,7 @@ public class ActionAppealAudit extends BaseAction {
 
 
 	private static Logger logger = LoggerFactory.getLogger(ActionAppealAudit.class);
 	private static Logger logger = LoggerFactory.getLogger(ActionAppealAudit.class);
 
 
-	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson,
-			JsonElement jsonElement) throws Exception {
+	protected ActionResult<Wo> execute(HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
 		Wo wo = new Wo();
 		Wo wo = new Wo();
 		List<String> ids = null;
 		List<String> ids = null;
@@ -144,8 +144,13 @@ public class ActionAppealAudit extends BaseAction {
 
 
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 
 
+		@FieldDescribe("需要复核的ID列表")
 		private List<String> ids = null;
 		private List<String> ids = null;
 
 
+		@FieldDescribe("审批意见")
+		private String opinion1;
+
+		@FieldDescribe("申诉人的身份,考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定.")
 		private String identity = null;
 		private String identity = null;
 
 
 		public String getIdentity() {
 		public String getIdentity() {
@@ -164,6 +169,9 @@ public class ActionAppealAudit extends BaseAction {
 			this.ids = ids;
 			this.ids = ids;
 		}
 		}
 
 
+		public String getOpinion1() { return opinion1; }
+
+		public void setOpinion1(String opinion1) { this.opinion1 = opinion1; }
 	}
 	}
 
 
 	public static class Wo {
 	public static class Wo {

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

@@ -4,12 +4,14 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
+import javax.persistence.Column;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.Logger;
@@ -134,14 +136,19 @@ public class ActionAppealCheck extends BaseAction {
 		return result;
 		return result;
 	}
 	}
 	
 	
-public static class Wi extends AttendanceAppealInfo {
+	public static class Wi extends AttendanceAppealInfo {
 		
 		
 		private static final long serialVersionUID = -5076990764713538973L;
 		private static final long serialVersionUID = -5076990764713538973L;
 		
 		
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
-		
+
+		@FieldDescribe("需要复核的ID列表")
 		private List<String> ids = null;
 		private List<String> ids = null;
 
 
+		@FieldDescribe("复核意见")
+		private String opinion2;
+
+		@FieldDescribe("申诉人的身份,考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定.")
 		private String identity = null;
 		private String identity = null;
 
 
 		public String getIdentity() {
 		public String getIdentity() {
@@ -159,7 +166,10 @@ public static class Wi extends AttendanceAppealInfo {
 		public void setIds(List<String> ids) {
 		public void setIds(List<String> ids) {
 			this.ids = ids;
 			this.ids = ids;
 		}
 		}
-		
+
+		public String getOpinion2() { return opinion2; }
+
+		public void setOpinion2(String opinion2) { this.opinion2 = opinion2; }
 	}
 	}
 	
 	
 	public static class Wo {
 	public static class Wo {

+ 34 - 27
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealCreate.java

@@ -3,9 +3,11 @@ package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.entity.AppealConfig;
 import com.x.attendance.entity.AppealConfig;
+import com.x.attendance.entity.AttendanceAppealAuditInfo;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceDetail;
 import com.x.attendance.entity.AttendanceDetail;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.jaxrs.WoId;
@@ -23,6 +25,7 @@ public class ActionAppealCreate extends BaseAction {
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
 		AttendanceAppealInfo attendanceAppealInfo = null;
 		AttendanceAppealInfo attendanceAppealInfo = null;
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
 		AttendanceDetail attendanceDetail = null;
 		AttendanceDetail attendanceDetail = null;
 		String appealAuditPersonName = null;
 		String appealAuditPersonName = null;
 		String appealCheckPersonName = null;
 		String appealCheckPersonName = null;
@@ -59,13 +62,7 @@ public class ActionAppealCreate extends BaseAction {
 				logger.error(e, effectivePerson, request, null);
 				logger.error(e, effectivePerson, request, null);
 			}
 			}
 		}
 		}
-		
-		if (check) {
-			// 利用打卡记录中的信息,创建一个申诉信息记录
-			attendanceAppealInfo = attendanceSettingServiceAdv.composeAppealInfoWithDetailInfo( attendanceDetail, 
-					wrapIn.getReason(), wrapIn.getAppealReason(),  wrapIn.getSelfHolidayType(),  wrapIn.getAddress(), 
-					wrapIn.getStartTime(),  wrapIn.getEndTime(),  wrapIn.getAppealDescription() );
-		}
+
 		if (check) {
 		if (check) {
 			try {
 			try {
 				appeal_auditor_type = attendanceSettingServiceAdv.getValueByCode( "APPEAL_AUDITOR_TYPE" );
 				appeal_auditor_type = attendanceSettingServiceAdv.getValueByCode( "APPEAL_AUDITOR_TYPE" );
@@ -79,19 +76,30 @@ public class ActionAppealCreate extends BaseAction {
 				logger.error( e, effectivePerson, request, null);
 				logger.error( e, effectivePerson, request, null);
 			}
 			}
 		}
 		}
+
+		if (check) {
+			// 利用打卡记录中的信息,创建一个申诉信息记录
+			attendanceAppealInfo = attendanceSettingServiceAdv.composeAppealInfoWithDetailInfo( attendanceDetail, 
+					wrapIn.getReason(), wrapIn.getAppealReason(),  wrapIn.getSelfHolidayType(),  wrapIn.getAddress(), 
+					wrapIn.getStartTime(),  wrapIn.getEndTime(),  wrapIn.getAppealDescription() );
+			// 创建一个申诉审批记录信息
+			attendanceAppealAuditInfo = new AttendanceAppealAuditInfo();
+			attendanceAppealAuditInfo.setId( attendanceAppealInfo.getId());
+			attendanceAppealAuditInfo.setDetailId( attendanceDetail.getId() );
+		}
+
 		
 		
 		//查询申诉审核人
 		//查询申诉审核人
 		if (check) {
 		if (check) {
 			if( StringUtils.isNotEmpty( appeal_auditor_type ) ) {
 			if( StringUtils.isNotEmpty( appeal_auditor_type ) ) {
 				try {
 				try {
-//					System.out.println("personName:" + personName );
-//					System.out.println("attendanceAppealInfo.getUnitName():" + attendanceAppealInfo.getUnitName() );
-//					System.out.println("wrapIn.getIdentity():" + wrapIn.getIdentity() );
 					appealAuditPersonName = attendanceAppealInfoServiceAdv.getAppealAuditPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
 					appealAuditPersonName = attendanceAppealInfoServiceAdv.getAppealAuditPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
 					if( StringUtils.isNotEmpty( appealAuditPersonName )){
 					if( StringUtils.isNotEmpty( appealAuditPersonName )){
 						appealAuditPersonName = userManagerService.getPersonNameByIdentity(appealAuditPersonName);
 						appealAuditPersonName = userManagerService.getPersonNameByIdentity(appealAuditPersonName);
-						attendanceAppealInfo.setProcessPerson1( appealAuditPersonName );
+						attendanceAppealAuditInfo.setProcessPerson1( appealAuditPersonName );
+						attendanceAppealAuditInfo.setCurrentProcessor( appealAuditPersonName );
 						attendanceAppealInfo.setCurrentProcessor( appealAuditPersonName );// 将第一个处理人设置为当前处理人
 						attendanceAppealInfo.setCurrentProcessor( appealAuditPersonName );// 将第一个处理人设置为当前处理人
+						attendanceAppealAuditInfo.setAuditFlowType( AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN );
 					}
 					}
 				}catch( Exception e ) {
 				}catch( Exception e ) {
 					check = false;
 					check = false;
@@ -112,7 +120,8 @@ public class ActionAppealCreate extends BaseAction {
 				if( StringUtils.isEmpty(appeal_auditor_type)) {
 				if( StringUtils.isEmpty(appeal_auditor_type)) {
 					message = "申诉审核人类别未配置!";
 					message = "申诉审核人类别未配置!";
 				}else if( "无".equals( appeal_auditor_type.trim() )){//当前人处理
 				}else if( "无".equals( appeal_auditor_type.trim() )){//当前人处理
-					attendanceAppealInfo.setProcessPerson1( effectivePerson.getDistinguishedName() );
+					attendanceAppealAuditInfo.setProcessPerson1( effectivePerson.getDistinguishedName() );
+					attendanceAppealAuditInfo.setCurrentProcessor( effectivePerson.getDistinguishedName() );// 将第一个处理人设置为当前处理人
 					attendanceAppealInfo.setCurrentProcessor( effectivePerson.getDistinguishedName() );// 将第一个处理人设置为当前处理人
 					attendanceAppealInfo.setCurrentProcessor( effectivePerson.getDistinguishedName() );// 将第一个处理人设置为当前处理人
 				}else if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equals( appeal_auditor_type )){
 				}else if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equals( appeal_auditor_type )){
 					unitLevelName = userManagerService.getUnitLevelNameWithName( attendanceDetail.getUnitName() );
 					unitLevelName = userManagerService.getUnitLevelNameWithName( attendanceDetail.getUnitName() );
@@ -136,7 +145,7 @@ public class ActionAppealCreate extends BaseAction {
 			if( StringUtils.isNotEmpty( appeal_checker_type ) && !"无".equals( appeal_auditor_type  ) ) {
 			if( StringUtils.isNotEmpty( appeal_checker_type ) && !"无".equals( appeal_auditor_type  ) ) {
 				try {
 				try {
 					appealCheckPersonName = attendanceAppealInfoServiceAdv.getAppealCheckPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
 					appealCheckPersonName = attendanceAppealInfoServiceAdv.getAppealCheckPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
-					attendanceAppealInfo.setProcessPerson2( appealCheckPersonName );
+					attendanceAppealAuditInfo.setProcessPerson2( appealCheckPersonName );
 				}catch( Exception e ) {
 				}catch( Exception e ) {
 					check = false;
 					check = false;
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据根据考勤人员查询申诉复核人信息时发生异常!personName:"+personName );
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据根据考勤人员查询申诉复核人信息时发生异常!personName:"+personName );
@@ -177,13 +186,13 @@ public class ActionAppealCreate extends BaseAction {
 		//查询申诉审核人所属组织
 		//查询申诉审核人所属组织
 		if (check) {
 		if (check) {
 			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
 			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
-				attendanceAppealInfo.setProcessPersonUnit1(
+				attendanceAppealAuditInfo.setProcessPersonUnit1(
 						attendanceAppealInfoServiceAdv.getPersonUnitName( appealAuditPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
 						attendanceAppealInfoServiceAdv.getPersonUnitName( appealAuditPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
 			}else {
 			}else {
 				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
 				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
 				if( StringUtils.isNotEmpty( appealAuditPersonName ) ) {
 				if( StringUtils.isNotEmpty( appealAuditPersonName ) ) {
 					try {//获取审核人组织信息
 					try {//获取审核人组织信息
-						attendanceAppealInfo.setProcessPersonUnit1( userManagerService.getUnitNameWithPersonName( appealAuditPersonName ));
+						attendanceAppealAuditInfo.setProcessPersonUnit1( userManagerService.getUnitNameWithPersonName( appealAuditPersonName ));
 					}catch( Exception e ) {
 					}catch( Exception e ) {
 						check = false;
 						check = false;
 						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取组织信息时发生异常。");
 						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取组织信息时发生异常。");
@@ -196,9 +205,9 @@ public class ActionAppealCreate extends BaseAction {
 		}
 		}
 		//根据所属组织名称查询申诉审核人所属顶层组织
 		//根据所属组织名称查询申诉审核人所属顶层组织
 		if (check) {
 		if (check) {
-			if( StringUtils.isNotEmpty( attendanceAppealInfo.getProcessPersonUnit1() )) {
+			if( StringUtils.isNotEmpty( attendanceAppealAuditInfo.getProcessPersonUnit1() )) {
 				try {
 				try {
-					attendanceAppealInfo.setProcessPersonTopUnit1( userManagerService.getTopUnitNameWithUnitName( attendanceAppealInfo.getProcessPersonUnit1() ) );
+					attendanceAppealAuditInfo.setProcessPersonTopUnit1( userManagerService.getTopUnitNameWithUnitName( attendanceAppealAuditInfo.getProcessPersonUnit1() ) );
 				}catch( Exception e ) {
 				}catch( Exception e ) {
 					check = false;
 					check = false;
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取顶层组织信息时发生异常。");
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取顶层组织信息时发生异常。");
@@ -212,12 +221,12 @@ public class ActionAppealCreate extends BaseAction {
 		//查询申诉复核人所属组织
 		//查询申诉复核人所属组织
 		if (check) {
 		if (check) {
 			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
 			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
-				attendanceAppealInfo.setProcessPersonUnit2( attendanceAppealInfoServiceAdv.getPersonUnitName( appealCheckPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
+				attendanceAppealAuditInfo.setProcessPersonUnit2( attendanceAppealInfoServiceAdv.getPersonUnitName( appealCheckPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
 			}else {
 			}else {
 				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
 				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
 				if( appealCheckPersonName != null  && !appealCheckPersonName.isEmpty() ) {
 				if( appealCheckPersonName != null  && !appealCheckPersonName.isEmpty() ) {
 					try {//获取复核人组织信息
 					try {//获取复核人组织信息
-						attendanceAppealInfo.setProcessPersonUnit2( userManagerService.getUnitNameWithPersonName( appealCheckPersonName ));
+						attendanceAppealAuditInfo.setProcessPersonUnit2( userManagerService.getUnitNameWithPersonName( appealCheckPersonName ));
 					}catch( Exception e ) {
 					}catch( Exception e ) {
 						check = false;
 						check = false;
 						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取组织信息时发生异常。");
 						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取组织信息时发生异常。");
@@ -230,9 +239,9 @@ public class ActionAppealCreate extends BaseAction {
 		}
 		}
 		//根据所属组织名称查询申诉复核人所属顶层组织
 		//根据所属组织名称查询申诉复核人所属顶层组织
 		if (check) {
 		if (check) {
-			if( StringUtils.isNotEmpty(attendanceAppealInfo.getProcessPersonUnit2())) {
+			if( StringUtils.isNotEmpty(attendanceAppealAuditInfo.getProcessPersonUnit2())) {
 				try {//获取复核人顶层组织信息
 				try {//获取复核人顶层组织信息
-					attendanceAppealInfo.setProcessPersonTopUnit2(  userManagerService.getTopUnitNameWithUnitName( attendanceAppealInfo.getProcessPersonUnit2()) );
+					attendanceAppealAuditInfo.setProcessPersonTopUnit2(  userManagerService.getTopUnitNameWithUnitName( attendanceAppealAuditInfo.getProcessPersonUnit2()) );
 				}catch( Exception e ) {
 				}catch( Exception e ) {
 					check = false;
 					check = false;
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取顶层组织信息时发生异常。");
 					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取顶层组织信息时发生异常。");
@@ -245,8 +254,8 @@ public class ActionAppealCreate extends BaseAction {
 		//保存申诉信息
 		//保存申诉信息
 		if (check) {
 		if (check) {
 			try {
 			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.saveNewAppeal( attendanceAppealInfo );
-				result.setData(new Wo(id));
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.saveNewAppeal( attendanceAppealInfo, attendanceAppealAuditInfo );
+				result.setData(new Wo(attendanceAppealInfo.getId()));
 			} catch (Exception e) {
 			} catch (Exception e) {
 				check = false;
 				check = false;
 				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在保存考勤申诉信息息时发生异常。");
 				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在保存考勤申诉信息息时发生异常。");
@@ -260,7 +269,7 @@ public class ActionAppealCreate extends BaseAction {
 				attendanceNoticeService.notifyAttendanceAppealProcessness1Message(attendanceAppealInfo);
 				attendanceNoticeService.notifyAttendanceAppealProcessness1Message(attendanceAppealInfo);
 			} catch (Exception e) {
 			} catch (Exception e) {
 				check = false;
 				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "申诉信息提交成功,向申诉当前处理人发送通知消息发生异常!name:"+attendanceAppealInfo.getProcessPerson1());
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "申诉信息提交成功,向申诉当前处理人发送通知消息发生异常!name:"+attendanceAppealAuditInfo.getProcessPerson1());
 				result.error(exception);
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 				logger.error(e, effectivePerson, request, null);
 			}
 			}
@@ -274,9 +283,7 @@ public class ActionAppealCreate extends BaseAction {
 		
 		
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
 
 
-		/**
-		 * 考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定
-		 */
+		@FieldDescribe("申诉人的身份,考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定.")
 		private String identity = null;
 		private String identity = null;
 
 
 		public String getIdentity() {
 		public String getIdentity() {

+ 118 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealCreateWithWorkFlow.java

@@ -0,0 +1,118 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import com.google.gson.JsonElement;
+import com.x.attendance.assemble.control.ExceptionWrapInConvert;
+import com.x.attendance.entity.AppealConfig;
+import com.x.attendance.entity.AttendanceAppealAuditInfo;
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ActionAppealCreateWithWorkFlow extends BaseAction {
+	
+	private static  Logger logger = LoggerFactory.getLogger( ActionAppealCreateWithWorkFlow.class );
+	
+	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
+		AttendanceDetail attendanceDetail = null;
+		Wi wrapIn = null;
+		Boolean check = true;
+
+		try {
+			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
+			if( StringUtils.isEmpty( wrapIn.getJobId() )){
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess("使用流程启动申诉时,工作流的jobId不允许为空");
+				result.error(exception);
+			}
+		} catch (Exception e) {
+			check = false;
+			Exception exception = new ExceptionWrapInConvert(e, jsonElement);
+			result.error(exception);
+			logger.error(e, effectivePerson, request, null);
+		}
+
+		if (check) {
+			try {
+				attendanceDetail = attendanceDetailServiceAdv.get( id );
+				if ( attendanceDetail == null ) {
+					check = false;
+					Exception exception = new ExceptionAttendanceDetailNotExists(id);
+					result.error( exception );
+				}
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询员工打卡信息时发生异常!ID:"+id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+
+		if (check) {
+			// 利用打卡记录中的信息,创建一个申诉信息记录
+			attendanceAppealInfo = attendanceSettingServiceAdv.composeAppealInfoWithDetailInfo( attendanceDetail, 
+					wrapIn.getReason(), wrapIn.getAppealReason(),  wrapIn.getSelfHolidayType(),  wrapIn.getAddress(), 
+					wrapIn.getStartTime(),  wrapIn.getEndTime(),  wrapIn.getAppealDescription() );
+			// 创建一个申诉审批记录信息
+			attendanceAppealAuditInfo = new AttendanceAppealAuditInfo();
+			attendanceAppealAuditInfo.setId( attendanceAppealInfo.getId());
+			attendanceAppealAuditInfo.setDetailId( attendanceDetail.getId() );
+			attendanceAppealAuditInfo.setAuditFlowType( AppealConfig.APPEAL_AUDIFLOWTYPE_WORKFLOW );
+			attendanceAppealAuditInfo.setWorkId( wrapIn.getJobId());
+		}
+
+		//保存申诉信息
+		if (check) {
+			try {
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.saveNewAppeal( attendanceAppealInfo, attendanceAppealAuditInfo );
+				result.setData(new Wo(attendanceAppealInfo.getId()));
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在保存考勤申诉信息息时发生异常。");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		return result;
+	}
+	
+	public static class Wi extends AttendanceAppealInfo {
+		
+		private static final long serialVersionUID = -5076990764713538973L;
+		
+		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
+
+		@FieldDescribe("申诉人的身份,考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定.")
+		private String identity = null;
+
+		@FieldDescribe("考勤流程的JOBID.")
+		private String jobId = null;
+
+		public String getJobId() { return jobId; }
+
+		public void setJobId(String jobId) { this.jobId = jobId; }
+
+		public String getIdentity() { return identity; }
+
+		public void setIdentity(String identity) { this.identity = identity; }
+	}
+	
+	public static class Wo extends WoId {
+		public Wo( String id ) {
+			setId( id );
+		}
+	}
+}

+ 0 - 112
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealProcessFirst.java

@@ -1,112 +0,0 @@
-package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import com.google.gson.JsonElement;
-import com.x.attendance.assemble.control.ExceptionWrapInConvert;
-import com.x.attendance.entity.AttendanceAppealInfo;
-import com.x.base.core.entity.JpaObject;
-import com.x.base.core.project.http.ActionResult;
-import com.x.base.core.project.http.EffectivePerson;
-import com.x.base.core.project.jaxrs.WoId;
-import com.x.base.core.project.logger.Logger;
-import com.x.base.core.project.logger.LoggerFactory;
-
-public class ActionAppealProcessFirst extends BaseAction {
-	
-	private static  Logger logger = LoggerFactory.getLogger( ActionAppealProcessFirst.class );
-	
-	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
-		ActionResult<Wo> result = new ActionResult<>();
-		String unitName = null;
-		String topUnitName = null;
-		AttendanceAppealInfo attendanceAppealInfo = null;
-		Wi wrapIn = null;
-		Boolean check = true;
-
-		try {
-			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
-		} catch (Exception e) {
-			check = false;
-			Exception exception = new ExceptionWrapInConvert(e, jsonElement);
-			result.error(exception);
-			logger.error(e, effectivePerson, request, null);
-		}
-
-		if (check) {
-			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get(id);
-				if (attendanceAppealInfo == null) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealNotExists(id);
-					result.error(exception);
-				}
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询考勤申诉信息数据时发生异常。ID:"+ id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			try {
-				unitName = userManagerService.getUnitNameWithPersonName(effectivePerson.getDistinguishedName());
-				if (unitName != null) {
-					topUnitName = userManagerService.getTopUnitNameWithUnitName( unitName );
-				} else {
-					check = false;
-					Exception exception = new ExceptionPersonHasNoUnit(effectivePerson.getDistinguishedName());
-					result.error(exception);
-				}
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统根据员工姓名查询组织信息时发生异常!name:"+effectivePerson.getDistinguishedName());
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.firstProcessAttendanceAppeal(id, unitName, topUnitName, effectivePerson.getDistinguishedName(), // processorName
-						new Date(), // processTime
-						wrapIn.getOpinion1(), // opinion
-						wrapIn.getStatus() // status审批状态:0-待处理,1-审批通过,-1-审批不能过,2-需要下一次审批
-				);
-				result.setData(new Wo(id));
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		return result;
-	}
-	
-	public static class Wi extends AttendanceAppealInfo {
-		
-		private static final long serialVersionUID = -5076990764713538973L;
-		
-		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
-
-		private String identity = null;
-
-		public String getIdentity() {
-			return identity;
-		}
-
-		public void setIdentity(String identity) {
-			this.identity = identity;
-		}
-	}
-	
-	public static class Wo extends WoId {
-		public Wo( String id ) {
-			setId( id );
-		}
-	}
-}

+ 0 - 114
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAppealProcessSecond.java

@@ -1,114 +0,0 @@
-package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import com.google.gson.JsonElement;
-import com.x.attendance.assemble.control.ExceptionWrapInConvert;
-import com.x.attendance.entity.AttendanceAppealInfo;
-import com.x.base.core.entity.JpaObject;
-import com.x.base.core.project.http.ActionResult;
-import com.x.base.core.project.http.EffectivePerson;
-import com.x.base.core.project.jaxrs.WoId;
-import com.x.base.core.project.logger.Logger;
-import com.x.base.core.project.logger.LoggerFactory;
-
-public class ActionAppealProcessSecond extends BaseAction {
-	
-	private static Logger logger = LoggerFactory.getLogger( ActionAppealProcessSecond.class );
-	
-	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
-		ActionResult<Wo> result = new ActionResult<>();
-		String unitName = null;
-		String topUnitName = null;
-		AttendanceAppealInfo attendanceAppealInfo = null;
-		Wi wrapIn = null;
-		Boolean check = true;
-
-		try {
-			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
-		} catch (Exception e) {
-			check = false;
-			Exception exception = new ExceptionWrapInConvert(e, jsonElement);
-			result.error(exception);
-			logger.error(e, effectivePerson, request, null);
-		}
-
-		if (check) {
-			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get(id);
-				if (attendanceAppealInfo == null) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealNotExists(id);
-					result.error(exception);
-				}
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询考勤申诉信息记录数据时发生异常。ID:"+ id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			try {
-				unitName = userManagerService.getUnitNameWithPersonName(effectivePerson.getDistinguishedName());
-				if (unitName != null) {
-					topUnitName = userManagerService.getTopUnitNameWithUnitName( unitName );
-				} else {
-					check = false;
-					Exception exception = new ExceptionPersonHasNoUnit(effectivePerson.getDistinguishedName());
-					result.error(exception);
-				}
-			} catch (Exception e) {
-				check = false;
-				result.error(e);
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统根据员工姓名查询组织信息时发生异常!name:"+effectivePerson.getDistinguishedName());
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.secondProcessAttendanceAppeal(id, unitName, topUnitName, effectivePerson.getDistinguishedName(), // processorName
-						new Date(), // processTime
-						wrapIn.getOpinion2(), // opinion
-						wrapIn.getStatus() // status
-				);
-				result.setData(new Wo(id));
-			} catch (Exception e) {
-				check = false;
-				result.error(e);
-				Exception exception = new ExceptionAttendanceAppealProcess(e, id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		return result;
-	}
-	
-	public static class Wi extends AttendanceAppealInfo {
-		
-		private static final long serialVersionUID = -5076990764713538973L;
-		
-		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
-
-		private String identity = null;
-
-		public String getIdentity() {
-			return identity;
-		}
-
-		public void setIdentity(String identity) {
-			this.identity = identity;
-		}
-	}
-	
-	public static class Wo extends WoId {
-		public Wo( String id ) {
-			setId( id );
-		}
-	}
-}

+ 0 - 228
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAttendanceDetailAppeal.java

@@ -1,228 +0,0 @@
-package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import com.x.attendance.entity.AppealConfig;
-import org.apache.commons.lang3.StringUtils;
-
-import com.google.gson.JsonElement;
-import com.x.attendance.assemble.control.ExceptionWrapInConvert;
-import com.x.attendance.entity.AttendanceAppealInfo;
-import com.x.attendance.entity.AttendanceDetail;
-import com.x.base.core.entity.JpaObject;
-import com.x.base.core.project.http.ActionResult;
-import com.x.base.core.project.http.EffectivePerson;
-import com.x.base.core.project.jaxrs.WoId;
-import com.x.base.core.project.logger.Logger;
-import com.x.base.core.project.logger.LoggerFactory;
-
-public class ActionAttendanceDetailAppeal extends BaseAction {
-	
-	private static Logger logger = LoggerFactory.getLogger( ActionAttendanceDetailAppeal.class );
-	
-	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
-		ActionResult<Wo> result = new ActionResult<>();
-		AttendanceAppealInfo attendanceAppealInfo = null;
-		AttendanceDetail attendanceDetail = null;
-		String appealAuditPersonName = null;
-		String appealCheckPersonName = null;
-		String appeal_auditor_type = null;
-		String appeal_checker_type = null;
-		String personName = null;
-		Wi wrapIn = null;
-		Boolean check = true;
-
-		try {
-			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
-		} catch (Exception e) {
-			check = false;
-			Exception exception = new ExceptionWrapInConvert(e, jsonElement);
-			result.error(exception);
-			logger.error(e, effectivePerson, request, null);
-		}
-		if (check) {
-			try {
-				attendanceDetail = attendanceDetailServiceAdv.get( id );
-				if ( attendanceDetail == null ) {
-					check = false;
-					Exception exception = new ExceptionAttendanceDetailNotExists(id);
-					result.error(exception);
-				}else {
-					personName = attendanceDetail.getEmpName();
-				}
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询员工打卡信息时发生异常!ID:"+id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			// 利用打卡记录中的信息,创建一个申诉信息记录
-			attendanceAppealInfo = attendanceSettingServiceAdv.composeAppealInfoWithDetailInfo(attendanceDetail, 
-					wrapIn.getReason(), wrapIn.getAppealReason(),  wrapIn.getSelfHolidayType(),  wrapIn.getAddress(), 
-					wrapIn.getStartTime(),  wrapIn.getEndTime(),  wrapIn.getAppealDescription() );
-		}
-		if (check) {
-			try {
-				appeal_auditor_type = attendanceSettingServiceAdv.getValueByCode( "APPEAL_AUDITOR_TYPE" );
-				appeal_checker_type = attendanceSettingServiceAdv.getValueByCode( "APPEAL_CHECKER_TYPE" );
-			}catch( Exception e ) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess( e, "系统在获取申诉审核配置时发生异常!" );
-				result.error( exception);
-				logger.error( e, effectivePerson, request, null);
-			}
-		}
-		//查询申诉审核人
-		if (check) {
-			if( StringUtils.isNotEmpty( appeal_auditor_type ) ) {
-				try {
-					appealAuditPersonName = attendanceAppealInfoServiceAdv.getAppealAuditPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
-					attendanceAppealInfo.setProcessPerson1( appealAuditPersonName );
-					attendanceAppealInfo.setCurrentProcessor( appealAuditPersonName );// 将第一个处理人设置为当前处理人
-				}catch( Exception e ) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据根据考勤人员查询申诉审核人信息时发生异常!personName:"+personName );
-					result.error(exception);
-					logger.warn( "系统在根据根据考勤人员查询申诉审核人信息时发生异常!personName:"+personName );
-					logger.error(e, effectivePerson, request, null);
-				}
-			}
-		}
-		//查询申诉复核人
-		if (check) {
-			if( StringUtils.isNotEmpty( appeal_checker_type ) ) {
-				try {
-					appealCheckPersonName = attendanceAppealInfoServiceAdv.getAppealCheckPerson( personName, attendanceAppealInfo.getUnitName(), wrapIn.getIdentity() );
-					attendanceAppealInfo.setProcessPerson2( appealCheckPersonName );
-				}catch( Exception e ) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据根据考勤人员查询申诉复核人信息时发生异常!personName:"+personName );
-					result.error(exception);
-					logger.warn( "系统在根据根据考勤人员查询申诉复核人信息时发生异常!personName:"+personName );
-					logger.error(e, effectivePerson, request, null);
-				}
-			}
-		}
-		//查询申诉审核人所属组织
-		if (check) {
-			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
-				attendanceAppealInfo.setProcessPersonUnit1( attendanceAppealInfoServiceAdv.getPersonUnitName( appealAuditPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
-			}else {
-				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
-				if( appealAuditPersonName != null  && !appealAuditPersonName.isEmpty() ) {
-					try {//获取审核人组织信息
-						attendanceAppealInfo.setProcessPersonUnit1( userManagerService.getUnitNameWithPersonName( appealAuditPersonName ));
-					}catch( Exception e ) {
-						check = false;
-						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取组织信息时发生异常。");
-						result.error(exception);
-						logger.warn( "系统在根据审核人获取组织信息时发生异常!personName:"+appealAuditPersonName );
-						logger.error(e, effectivePerson, request, null);
-					}
-				}
-			}
-		}
-		//根据所属组织名称查询申诉审核人所属顶层组织
-		if (check) {
-			if( attendanceAppealInfo.getProcessPersonUnit1() != null  && !attendanceAppealInfo.getProcessPersonUnit1().isEmpty() ) {
-				try {
-					attendanceAppealInfo.setProcessPersonTopUnit1( userManagerService.getTopUnitNameWithUnitName( attendanceAppealInfo.getProcessPersonUnit1() ) );
-				}catch( Exception e ) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据审核人获取顶层组织信息时发生异常。");
-					result.error(exception);
-					logger.warn( "系统在根据审核人获取顶层组织信息时发生异常!personName:"+appealAuditPersonName );
-					logger.error(e, effectivePerson, request, null);
-				}
-			}
-		}
-		//查询申诉复核人所属组织
-		if (check) {
-			if( AppealConfig.APPEAL_AUDITTYPE_UNITDUTY.equalsIgnoreCase( appeal_auditor_type ) ) {
-				attendanceAppealInfo.setProcessPersonUnit2( attendanceAppealInfoServiceAdv.getPersonUnitName( appealCheckPersonName, attendanceDetail.getUnitName(), wrapIn.getIdentity() ) );
-			}else {
-				//汇报对象,指定人以及人员属性中指定的人员,根据人员姓名取首选组织(第一个)
-				if( appealCheckPersonName != null  && !appealCheckPersonName.isEmpty() ) {
-					try {//获取复核人组织信息
-						attendanceAppealInfo.setProcessPersonUnit2( userManagerService.getUnitNameWithPersonName( appealCheckPersonName ));
-					}catch( Exception e ) {
-						check = false;
-						Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取组织信息时发生异常。");
-						result.error(exception);
-						logger.warn( "系统在根据审核人获取组织信息时发生异常!personName:"+appealCheckPersonName );
-						logger.error(e, effectivePerson, request, null);
-					}
-				}
-			}
-		}
-		//根据所属组织名称查询申诉复核人所属顶层组织
-		if (check) {
-			if( attendanceAppealInfo.getProcessPersonUnit2() != null  && !attendanceAppealInfo.getProcessPersonUnit2().isEmpty() ) {
-				try {//获取复核人顶层组织信息
-					attendanceAppealInfo.setProcessPersonTopUnit2(  userManagerService.getTopUnitNameWithUnitName( attendanceAppealInfo.getProcessPersonUnit2()) );
-				}catch( Exception e ) {
-					check = false;
-					Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据复核人获取顶层组织信息时发生异常。");
-					result.error(exception);
-					logger.warn( "系统在根据审核人获取顶层组织信息时发生异常!personName:"+appealCheckPersonName );
-					logger.error(e, effectivePerson, request, null);
-				}
-			}
-		}
-		//保存申诉信息
-		if (check) {
-			try {
-				attendanceAppealInfo = attendanceAppealInfoServiceAdv.saveNewAppeal( attendanceAppealInfo );
-				result.setData(new Wo(id));
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在保存考勤申诉信息息时发生异常。");
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		if (check) {
-			// 填充申诉信息内容 - 申诉信息成功生成.尝试向当前处理人[" + attendanceAppealInfo.getCurrentProcessor() + "]发送消息通知......
-			try {
-				attendanceNoticeService.notifyAttendanceAppealProcessness1Message(attendanceAppealInfo);
-			} catch (Exception e) {
-				check = false;
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "申诉信息提交成功,向申诉当前处理人发送通知消息发生异常!name:"+attendanceAppealInfo.getProcessPerson1());
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		return result;
-	}
-	
-	public static class Wi extends AttendanceAppealInfo {
-		
-		private static final long serialVersionUID = -5076990764713538973L;
-		
-		public static List<String> Excludes = new ArrayList<String>(JpaObject.FieldsUnmodify);
-
-		/**
-		 * 考勤人员身份:如果考勤人员属于多个组织,可以选择一个身份进行申诉信息绑定
-		 */
-		private String identity = null;
-
-		public String getIdentity() {
-			return identity;
-		}
-
-		public void setIdentity(String identity) {
-			this.identity = identity;
-		}
-	}
-	
-	public static class Wo extends WoId {
-		public Wo( String id ) {
-			setId( id );
-		}
-	}
-}

+ 0 - 46
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionAttendanceDetailArchive.java

@@ -1,46 +0,0 @@
-package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang3.StringUtils;
-import com.x.base.core.project.http.ActionResult;
-import com.x.base.core.project.http.EffectivePerson;
-import com.x.base.core.project.jaxrs.WoId;
-import com.x.base.core.project.logger.Logger;
-import com.x.base.core.project.logger.LoggerFactory;
-
-public class ActionAttendanceDetailArchive extends BaseAction {
-	
-	private static  Logger logger = LoggerFactory.getLogger( ActionAttendanceDetailArchive.class );
-	
-	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
-		ActionResult<Wo> result = new ActionResult<>();
-
-		if ( StringUtils.isNotEmpty( id )) { // 归档指定的考勤申诉记录
-			try {
-				attendanceAppealInfoServiceAdv.archive(id);
-				result.setData(new Wo(id));
-			} catch (Exception e) {
-				result.error(e);
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "归档考勤打卡申诉信息时发生异常。ID:" + id);
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		} else { // 归档所有的考勤申诉记录
-			try {
-				attendanceAppealInfoServiceAdv.archiveAll();
-			} catch (Exception e) {
-				Exception exception = new ExceptionAttendanceAppealProcess(e, "归档全部考勤申诉信息数据时发生异常");
-				result.error(exception);
-				logger.error(e, effectivePerson, request, null);
-			}
-		}
-		return result;
-	}
-	
-	public static class Wo extends WoId {
-		public Wo( String id ) {
-			setId( id );
-		}
-	}
-}

+ 146 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ActionWorkFlowSync.java

@@ -0,0 +1,146 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import com.google.gson.JsonElement;
+import com.x.attendance.assemble.control.ExceptionWrapInConvert;
+import com.x.attendance.assemble.control.service.WorkFlowSyncService;
+import com.x.attendance.entity.AttendanceAppealAuditInfo;
+import com.x.attendance.entity.AttendanceAppealInfo;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WoId;
+import com.x.base.core.project.logger.Logger;
+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.ArrayList;
+import java.util.List;
+
+public class ActionWorkFlowSync extends BaseAction {
+	
+	private static  Logger logger = LoggerFactory.getLogger( ActionWorkFlowSync.class );
+	
+	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id, JsonElement jsonElement ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		AttendanceAppealInfo attendanceAppealInfo = null;
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
+		WorkFlowSyncService.WoWorkComplex woWorkComplex = null;
+		ActionAppealCreate.Wi wrapIn = null;
+		Boolean check = true;
+
+		if (check) {
+			if ( StringUtils.isNotEmpty( id )) {
+				check = false;
+				result.error(new Exception("传入的workId为空,或者不合法,无法同步流程数据。"));
+			}
+		}
+
+		if (check) {
+			try {
+				wrapIn = this.convertToWrapIn(jsonElement, ActionAppealCreate.Wi.class);
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionWrapInConvert(e, jsonElement);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+
+		if (check) {
+			if( wrapIn.getStatus() != 0 & wrapIn.getStatus() != 1 &wrapIn.getStatus() != -1 &wrapIn.getStatus() != 9 ){
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess( "传入的申诉状态不合法。status:" + wrapIn.getStatus());
+				result.error(exception);
+			}
+		}
+
+		if (check) {
+			try {
+				attendanceAppealInfo = attendanceAppealInfoServiceAdv.get(id);
+				if( attendanceAppealInfo == null ){
+					check = false;
+					Exception exception = new ExceptionAttendanceAppealNotExists( id );
+					result.error(exception);
+				}
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询考勤申诉记录数据时发生异常。ID:" + id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+
+		if (check) {
+			try {
+				attendanceAppealAuditInfo = attendanceAppealInfoServiceAdv.getAppealAuditInfo(id);
+				if( attendanceAppealAuditInfo == null ){
+					check = false;
+					Exception exception = new ExceptionAppealAuditInfoNotExists( id );
+					result.error(exception);
+				}
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在根据ID查询考勤申诉审批记录数据时发生异常。ID:" + id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+
+		if (check) {
+			try {
+				woWorkComplex = WorkFlowSyncService.getWorkComplex( attendanceAppealAuditInfo.getWorkId() );
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在获取考勤打卡申诉流程信息时发生异常。ID:" + attendanceAppealAuditInfo.getWorkId() );
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+
+		if (check) {
+			try {
+				String processorName = null;
+				String activityType = null;
+
+				if(ListTools.isEmpty( woWorkComplex.getTaskList() )){
+					processorName = null;
+				}else{
+					processorName = woWorkComplex.getTaskList().get(0).getIdentity();
+				}
+				activityType = woWorkComplex.getActivity().getActivityType().name();
+
+				attendanceAppealInfoServiceAdv.syncAppealStatus( attendanceAppealInfo, activityType, processorName, wrapIn.getStatus() );
+
+				result.setData(new Wo(id));
+			} catch (Exception e) {
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "系统在同步考勤打卡申诉流程信息时发生异常。ID:" + id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		return result;
+	}
+
+	public static class Wi {
+
+		@FieldDescribe("申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过.")
+		private Integer status = null;
+
+		public Integer getStatus() {
+			return status;
+		}
+
+		public void setStatus(Integer status) {
+			this.status = status;
+		}
+	}
+
+	public static class Wo extends WoId {
+		public Wo( String id ) {
+			setId( id );
+		}
+	}
+}

+ 56 - 4
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/AttendanceAppealInfoAction.java

@@ -83,13 +83,12 @@ public class AttendanceAppealInfoAction extends StandardJaxrsAction {
 
 
 	/**
 	/**
 	 * 对某条打卡记录进行申诉
 	 * 对某条打卡记录进行申诉
-	 * 
+	 * @param asyncResponse
 	 * @param request
 	 * @param request
 	 * @param id
 	 * @param id
-	 * @param wrapIn
-	 * @return
+	 * @param jsonElement
 	 */
 	 */
-	@JaxrsMethodDescribe(value = "根据ID对考勤结果申诉信息提起申诉", action = ActionAppealCreate.class)
+	@JaxrsMethodDescribe(value = "根据ID对考勤结果申诉信息提起申诉", action = ActionAppealCreate.class )
 	@PUT
 	@PUT
 	@Path("appeal/{id}")
 	@Path("appeal/{id}")
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
 	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
@@ -112,6 +111,36 @@ public class AttendanceAppealInfoAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 	}
 
 
+	/**
+	 * 对某条打卡记录进行申诉
+	 * @param asyncResponse
+	 * @param request
+	 * @param id
+	 * @param jsonElement
+	 */
+	@JaxrsMethodDescribe(value = "根据ID对考勤结果申诉信息提起申诉", action = ActionAppealCreateWithWorkFlow.class )
+	@PUT
+	@Path("workflow/appeal/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void createWithWorkFlow(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+					   @JaxrsParameterDescribe("考勤申诉信息ID") @PathParam("id") String id, JsonElement jsonElement) {
+		ActionResult<ActionAppealCreateWithWorkFlow.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		Boolean check = true;
+		if (check) {
+			try {
+				result = new ActionAppealCreateWithWorkFlow().execute(request, effectivePerson, id, jsonElement);
+			} catch (Exception e) {
+				result = new ActionResult<>();
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "根据ID对打卡结果进行申诉时发生异常!");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
 	@JaxrsMethodDescribe(value = "根据ID列表对考勤申诉信息进行审核操作, 参数:ids(申诉ID列表),opinion(审核意见), status(审核状态:1-通过;2-需要进行复核;-1-不通过)", action = ActionAppealAudit.class)
 	@JaxrsMethodDescribe(value = "根据ID列表对考勤申诉信息进行审核操作, 参数:ids(申诉ID列表),opinion(审核意见), status(审核状态:1-通过;2-需要进行复核;-1-不通过)", action = ActionAppealAudit.class)
 	@PUT
 	@PUT
 	@Path("audit")
 	@Path("audit")
@@ -228,4 +257,27 @@ public class AttendanceAppealInfoAction extends StandardJaxrsAction {
 		}
 		}
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 	}
+
+	@JaxrsMethodDescribe(value = "根据考勤申诉ID,更新流程的审批信息", action = ActionWorkFlowSync.class)
+	@GET
+	@Path("workflow/sync/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void archive(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+						@JaxrsParameterDescribe("考勤申诉信息ID") @PathParam("id") String id, JsonElement jsonElement) {
+		ActionResult<ActionWorkFlowSync.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		Boolean check = true;
+		if (check) {
+			try {
+				result = new ActionWorkFlowSync().execute(request, effectivePerson, id, jsonElement);
+			} catch (Exception e) {
+				result = new ActionResult<>();
+				Exception exception = new ExceptionAttendanceAppealProcess(e, "根据ID对打卡结果进行归档时发生异常!");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
 }
 }

+ 12 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendanceappealinfo/ExceptionAppealAuditInfoNotExists.java

@@ -0,0 +1,12 @@
+package com.x.attendance.assemble.control.jaxrs.attendanceappealinfo;
+
+import com.x.base.core.project.exception.PromptException;
+
+class ExceptionAppealAuditInfoNotExists extends PromptException {
+
+	private static final long serialVersionUID = 1859164370743532895L;
+
+	public ExceptionAppealAuditInfoNotExists(String id ) {
+		super("员工打卡申诉审批信息不存在!ID:" + id );
+	}
+}

+ 1 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionListMobileWithFilter.java

@@ -170,6 +170,7 @@ public class ActionListMobileWithFilter extends BaseAction {
 		}
 		}
 		result.setCount(total);
 		result.setCount(total);
 		result.setData(wraps);
 		result.setData(wraps);
+
 		return result;
 		return result;
 	}
 	}
 
 

+ 447 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionListMyMobileRecordToday.java

@@ -0,0 +1,447 @@
+package com.x.attendance.assemble.control.jaxrs.attendancedetail;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.logger.Logger;
+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.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 查询登录者当天的所有移动打卡信息
+ */
+public class ActionListMyMobileRecordToday extends BaseAction {
+
+	private static  Logger logger = LoggerFactory.getLogger(ActionListMyMobileRecordToday.class);
+	private DateOperation dateOperation = new DateOperation();
+
+	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson ) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		EffectivePerson currentPerson = this.effectivePerson(request);
+		List<WoMobileRecord> wraps = new ArrayList<>();
+		List<AttendanceDetailMobile> attendanceDetailMobileList = null;
+		Long total = 0L;
+		Boolean check = true;
+		AttendanceScheduleSetting scheduleSetting = null;
+		WoScheduleSetting woScheduleSetting = null;
+		String signDate = dateOperation.getDateStringFromDate( new Date(), "YYYY-MM-DD");
+
+		//先查询该员工所有的考勤数据
+		if (check) {
+			try {
+				attendanceDetailMobileList = attendanceDetailServiceAdv.listAttendanceDetailMobile( effectivePerson.getDistinguishedName(), signDate );
+			} catch (Exception e) {
+				check = false;
+				Exception exception = new ExceptionAttendanceDetailProcess(e,
+						"根据条件查询员工手机打卡信息列表时发生异常.DistinguishedName:" + effectivePerson.getDistinguishedName() + ",Date:" + signDate);
+				result.error(exception);
+				logger.error(e, currentPerson, request, null);
+			}
+		}
+
+		if (check) {
+			if ( ListTools.isNotEmpty(attendanceDetailMobileList)) {
+				try {
+					wraps = WoMobileRecord.copier.copy(attendanceDetailMobileList);
+				} catch (Exception e) {
+					check = false;
+					Exception exception = new ExceptionAttendanceDetailProcess(e, "系统在转换员工手机打卡信息为输出对象时发生异常.");
+					result.error(exception);
+					logger.error(e, currentPerson, request, null);
+				}
+			}
+		}
+
+		//根据最后一次打卡信息,计算下一次打卡的信息
+		WoSignFeature woSignFeature = null;
+		if (check
+				&& !StringUtils.equalsAnyIgnoreCase("xadmin", effectivePerson.getName())
+				&& !StringUtils.equalsAnyIgnoreCase("cipher", effectivePerson.getName())) {
+			//打卡策略:1-两次打卡(上午上班,下午下班) 2-三次打卡(上午上班,下午下班加中午一次共三次) 3-四次打卡(上午下午都打上班下班卡)
+			scheduleSetting = attendanceScheduleSettingServiceAdv.getAttendanceScheduleSettingWithPerson( effectivePerson.getDistinguishedName(), effectivePerson.getDebugger() );
+
+			if( scheduleSetting != null ){
+				woScheduleSetting = WoScheduleSetting.copier.copy(scheduleSetting);
+
+				if( woScheduleSetting.getSignProxy() == 3 ){
+					//3-四次打卡(上午下午都打上班下班卡)
+					woSignFeature = getWoSignFeatureWithProxy3(wraps, woScheduleSetting);
+				}else if( woScheduleSetting.getSignProxy() == 2 ){
+					//2-三次打卡(上午上班,下午下班加中午一次共三次)
+					woSignFeature = getWoSignFeatureWithProxy2(wraps, woScheduleSetting);
+				}else{
+					//1-两次打卡(上午上班,下午下班)
+					woSignFeature = getWoSignFeatureWithProxy1(wraps, woScheduleSetting);
+				}
+			}
+			if( woSignFeature != null ){
+				woSignFeature.setSignDate( signDate );
+			}
+		}
+
+		Wo wo = new Wo();
+		wo.setRecords( wraps );
+		wo.setFeature( woSignFeature );
+		wo.setScheduleSetting( woScheduleSetting );
+		result.setCount(total);
+		result.setData(wo);
+
+		return result;
+	}
+
+	/**
+	 * 计算下一次打卡是什么打卡
+	 * 3-四次打卡(上午下午都打上班下班卡)
+	 *
+	 * @param wraps
+	 * @param scheduleSetting
+	 * @return
+	 */
+	private WoSignFeature getWoSignFeatureWithProxy3(List<WoMobileRecord> wraps, AttendanceScheduleSetting scheduleSetting) throws Exception {
+		WoSignFeature woSignFeature = new WoSignFeature();
+		Date now = new Date();
+		Date onDutyTime = null, offDutyTime = null;
+		Date morningOffdutyTime = null, afternoonOndutyTime = null;
+		String todayDateStr = dateOperation.getDateStringFromDate( now, "YYYY-MM-DD");
+		SignRecordStatus signRecordStatus = null;
+
+		if( StringUtils.isEmpty( scheduleSetting.getMiddayRestStartTime())){
+			return null;
+		}
+
+		if( StringUtils.isEmpty( scheduleSetting.getMiddayRestEndTime())){
+			return null;
+		}
+
+		//计算,上班下班时间
+		onDutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getOnDutyTime() );
+		morningOffdutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getMiddayRestStartTime() );
+		afternoonOndutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getMiddayRestEndTime() );
+		offDutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getOffDutyTime() );
+
+		signRecordStatus = getSignRecordStatus( wraps, onDutyTime, morningOffdutyTime, afternoonOndutyTime, offDutyTime );
+
+		if( ListTools.isEmpty( wraps )){
+			//一次都没有打过,看看当前时间是上班还是下午,如果是上午,就是上午签到,如果是下午,就是下午签到
+			if( now.after(afternoonOndutyTime)){
+				//在下午下班时间之后了,下午上班签到打卡
+				woSignFeature.setSignSeq(1);
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON_ONDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getOnDutyTime());
+			}else{
+				woSignFeature.setSignSeq(1);
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_ONDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getOnDutyTime());
+			}
+		}else{
+			woSignFeature.setSignSeq(2);
+			//当前是什么区间
+			if( onDutyTime.after(now)){
+				//上午上班之前,无论几次,都只可能是上午的下班卡
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_MORNING_OFFDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getMiddayRestStartTime());
+				woSignFeature.setSignSeq(2);
+			}else if( now.after(onDutyTime) && morningOffdutyTime.after(now)){
+				//上午上班时段: 上午签退
+				woSignFeature.setSignSeq(2);
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_MORNING_OFFDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getMiddayRestStartTime());
+			}else if( now.after(morningOffdutyTime) && afternoonOndutyTime.after( now )){
+				//午休时段:前一次打卡有可能上午签到卡,可能下午签到卡
+				if( signRecordStatus.alreadyOnduty ){ //已经上午签到过了,只有一次卡,应该就是签到
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_MORNING_OFFDUTY );
+					woSignFeature.setSignTime(scheduleSetting.getMiddayRestStartTime());
+				}else if( signRecordStatus.alreadyAfternoonOnDuty){
+					//如果上午没有签到,是下午的签到的话,第二次就应该是下午签退打卡了
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+					woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+				}
+			}else if( now.after(afternoonOndutyTime) && offDutyTime.after(now)){
+				//下午上班时段,如果前一次是下午签到,那么下一次就应该是下午签退了,否则,就是下午签到
+				if( signRecordStatus.alreadyAfternoonOnDuty){
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY  );
+					woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+				}else{
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON_ONDUTY  );
+					woSignFeature.setSignTime(scheduleSetting.getMiddayRestEndTime());
+				}
+			}else{
+				//下午下班之后,只可能是下午的签到签退卡了
+				if( signRecordStatus.alreadyAfternoonOnDuty){
+					woSignFeature.setSignSeq(-1);
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY  );
+					woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+				}else{
+					woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON_ONDUTY  );
+					woSignFeature.setSignTime(scheduleSetting.getMiddayRestEndTime());
+				}
+			}
+		}
+		return woSignFeature;
+	}
+
+	/**
+	 * 计算下一次打卡是什么打卡
+	 * 2-三次打卡(上午上班,下午下班加中午一次共三次)
+	 *
+	 * @param wraps
+	 * @param scheduleSetting
+	 * @return
+	 */
+	private WoSignFeature getWoSignFeatureWithProxy2(List<WoMobileRecord> wraps, AttendanceScheduleSetting scheduleSetting) throws Exception {
+		WoSignFeature woSignFeature = new WoSignFeature();
+		SignRecordStatus signRecordStatus = null;
+
+		Date now = new Date();
+		Date middayRestEndTime = null;
+		Date onDutyTime = null, offDutyTime = null;
+		Date morningOffdutyTime = null, afternoonOndutyTime = null;
+		String todayDateStr = dateOperation.getDateStringFromDate( now, "YYYY-MM-DD");
+
+		//计算,上班下班时间
+		onDutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getOnDutyTime() );
+		morningOffdutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getMiddayRestStartTime() );
+		afternoonOndutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getMiddayRestEndTime() );
+		offDutyTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getOffDutyTime() );
+
+		signRecordStatus = getSignRecordStatus( wraps, onDutyTime, morningOffdutyTime, afternoonOndutyTime, offDutyTime );
+
+		if( ListTools.isEmpty( wraps )){
+			//一次都没有打过,不管几点,都是上班打卡
+			woSignFeature.setSignSeq(1);
+			woSignFeature.setCheckinType( "上班签到" );
+			woSignFeature.setSignTime(scheduleSetting.getOnDutyTime());
+		}else{
+			//打了一次,之后,有可能是中午签到打卡,有可能是下午下班签退打卡
+			if( wraps.size() == 1 ){
+				woSignFeature.setSignSeq(2);
+				//第一次打卡,肯定是打了上班卡,第二次就可能是午休或者下班卡了
+				if( StringUtils.isNotEmpty( scheduleSetting.getMiddayRestEndTime())){
+					middayRestEndTime = dateOperation.getDateFromString( todayDateStr + " " + scheduleSetting.getMiddayRestEndTime() );
+					//看当前时间,有没有过中午签到时间
+					if( middayRestEndTime !=null && middayRestEndTime.before( now )){
+						//在午休结束之后了,就是下班打卡了,上班和午休都缺卡了
+						woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+						woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+					}else{
+						//午休卡
+						woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON );
+						woSignFeature.setSignTime(scheduleSetting.getMiddayRestEndTime());
+					}
+				}
+			}else if( wraps.size() == 2 ){
+				if( StringUtils.isNotEmpty( scheduleSetting.getMiddayRestEndTime())) {
+					middayRestEndTime = dateOperation.getDateFromString(todayDateStr + " " + scheduleSetting.getMiddayRestEndTime());
+					//只可能是签退卡了,如果签退卡都打了,那么就是不需要再打卡了。
+					//判断是否已经打了下班签退卡,看看是否有午休结束时间之后的打卡
+					Boolean exists_offDuty = false;
+					Date signTime = null;
+					for( WoMobileRecord record : wraps ){
+						signTime = dateOperation.getDateFromString(todayDateStr + " " + record.getSignTime() );
+						if( signTime.after( middayRestEndTime )){
+							exists_offDuty = true;
+							break;
+						}
+					}
+					if( exists_offDuty ){
+						woSignFeature.setSignSeq(-1);
+						woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+						woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+					}else{
+						woSignFeature.setSignSeq(3);
+						woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+						woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+					}
+				}
+			}else{
+				woSignFeature.setSignSeq(-1);
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+			}
+		}
+
+		return woSignFeature;
+	}
+
+	/**
+	 * 计算下一次打卡是什么打卡
+	 * 1-两次打卡(上午上班,下午下班)
+	 * @param wraps
+	 * @param scheduleSetting
+	 * @return
+	 */
+	private WoSignFeature getWoSignFeatureWithProxy1(List<WoMobileRecord> wraps, AttendanceScheduleSetting scheduleSetting) {
+		WoSignFeature woSignFeature = new WoSignFeature();
+		if( ListTools.isEmpty( wraps )){
+			//一次都没有打过,不管几点,都是上班打卡
+			woSignFeature.setSignSeq(1);
+			woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_ONDUTY );
+			woSignFeature.setSignTime(scheduleSetting.getOnDutyTime());
+		}else{
+			//打了一次,就是下班打卡,打了两次,就没有了
+			if( wraps.size() == 1 ){
+				woSignFeature.setSignSeq(2);
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+			}else{
+				woSignFeature.setSignSeq(-1); //没有需要的打卡了
+				woSignFeature.setCheckinType( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY );
+				woSignFeature.setSignTime(scheduleSetting.getOffDutyTime());
+			}
+		}
+		return woSignFeature;
+	}
+
+	private SignRecordStatus getSignRecordStatus(List<WoMobileRecord> wraps, Date onDutyTime, Date morningOffdutyTime, Date afternoonOndutyTime, Date offDutyTime) {
+		SignRecordStatus signRecordStatus = new SignRecordStatus();
+		if( ListTools.isNotEmpty( wraps )){
+			for( WoMobileRecord record : wraps ){
+				if( StringUtils.equalsAnyIgnoreCase( AttendanceDetailMobile.CHECKIN_TYPE_ONDUTY, record.getCheckin_type() )){
+					signRecordStatus.setAlreadyOnduty( true );
+				}
+				if( StringUtils.equalsAnyIgnoreCase( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON, record.getCheckin_type() )){
+					signRecordStatus.setAlreadyAfternoon( true );
+				}
+				if( StringUtils.equalsAnyIgnoreCase( AttendanceDetailMobile.CHECKIN_TYPE_MORNING_OFFDUTY, record.getCheckin_type() )){
+					signRecordStatus.setAlreadyMorningOffDuty( true );
+				}
+				if( StringUtils.equalsAnyIgnoreCase( AttendanceDetailMobile.CHECKIN_TYPE_AFTERNOON_ONDUTY, record.getCheckin_type() )){
+					signRecordStatus.setAlreadyAfternoonOnDuty( true );
+				}
+				if( StringUtils.equalsAnyIgnoreCase( AttendanceDetailMobile.CHECKIN_TYPE_OFFDUTY, record.getCheckin_type() )){
+					signRecordStatus.setAlreadyOffDuty( true );
+				}
+			}
+		}
+		return signRecordStatus;
+	}
+
+	public static class SignRecordStatus {
+
+		@FieldDescribe("是否上午上班打卡过了ONDUTY")
+		private Boolean alreadyOnduty = false;
+
+		@FieldDescribe("是否上午下班打卡过了MORNING_OFFDUTY.")
+		private Boolean alreadyMorningOffDuty = false;
+
+		@FieldDescribe("是否下午上班打卡过了AFTERNOON_ONDUTY")
+		private Boolean alreadyAfternoonOnDuty = false;
+
+		@FieldDescribe("是否下午下班打卡过了OFFDUTY.")
+		private Boolean alreadyOffDuty = false;
+
+		@FieldDescribe("是否午间打卡过了AfternoonSign.")
+		private Boolean alreadyAfternoon = false;
+
+		public Boolean getAlreadyOnduty() { return alreadyOnduty; }
+
+		public void setAlreadyOnduty(Boolean alreadyOnduty) { this.alreadyOnduty = alreadyOnduty; }
+
+		public Boolean getAlreadyMorningOffDuty() { return alreadyMorningOffDuty; }
+
+		public void setAlreadyMorningOffDuty(Boolean alreadyMorningOffDuty) { this.alreadyMorningOffDuty = alreadyMorningOffDuty; }
+
+		public Boolean getAlreadyAfternoonOnDuty() { return alreadyAfternoonOnDuty; }
+
+		public void setAlreadyAfternoonOnDuty(Boolean alreadyAfternoonOnDuty) { this.alreadyAfternoonOnDuty = alreadyAfternoonOnDuty; }
+
+		public Boolean getAlreadyOffDuty() { return alreadyOffDuty; }
+
+		public void setAlreadyOffDuty(Boolean alreadyOffDuty) { this.alreadyOffDuty = alreadyOffDuty; }
+
+		public Boolean getAlreadyAfternoon() { return alreadyAfternoon; }
+
+		public void setAlreadyAfternoon(Boolean alreadyAfternoon) { this.alreadyAfternoon = alreadyAfternoon; }
+	}
+
+	public static class Wo{
+
+		@FieldDescribe("所有的打卡记录.")
+		private List<WoMobileRecord> records;
+
+		@FieldDescribe("个人相关的排班信息")
+		private WoScheduleSetting scheduleSetting;
+
+		@FieldDescribe("下一次打卡信息")
+		private WoSignFeature feature;
+
+		public WoScheduleSetting getScheduleSetting() { return scheduleSetting; }
+
+		public void setScheduleSetting(WoScheduleSetting scheduleSetting) { this.scheduleSetting = scheduleSetting; }
+
+		public List<WoMobileRecord> getRecords() { return records; }
+
+		public void setRecords(List<WoMobileRecord> records) { this.records = records; }
+
+		public WoSignFeature getFeature() { return feature; }
+
+		public void setFeature(WoSignFeature feature) { this.feature = feature; }
+	}
+
+	public static class WoMobileRecord extends AttendanceDetailMobile {
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static WrapCopier<AttendanceDetailMobile, WoMobileRecord> copier = WrapCopierFactory.wo(AttendanceDetailMobile.class,
+				WoMobileRecord.class, null, JpaObject.FieldsInvisible);
+	}
+
+	public static class WoScheduleSetting extends AttendanceScheduleSetting {
+
+		private static final long serialVersionUID = -5076990764713538973L;
+
+		public static WrapCopier<AttendanceScheduleSetting, WoScheduleSetting> copier = WrapCopierFactory.wo(AttendanceScheduleSetting.class,
+				WoScheduleSetting.class, null, JpaObject.FieldsInvisible);
+	}
+
+	public static class WoSignFeature{
+
+		@FieldDescribe("下一次打卡次数,第一次为1")
+		private Integer signSeq = 1;
+
+		@FieldDescribe("打卡日期:yyyy-mm-dd.")
+		private String signDate = null;
+
+		@FieldDescribe("打卡时间:HH:mi:ss.")
+		private String signTime = null;
+
+		@FieldDescribe("打卡操作名称:上班打卡|下班打卡|午休打卡|上午下班打卡|下午上班打卡(根据不同的打卡策略稍有不同)....")
+		private String checkinType = "上班打卡";
+
+		@FieldDescribe("最晚打卡时间")
+		private Date latestSignTime;
+
+		public String getSignTime() { return signTime; }
+
+		public void setSignTime(String signTime) { this.signTime = signTime; }
+
+		public Integer getSignSeq() { return signSeq; }
+
+		public void setSignSeq(Integer signSeq) { this.signSeq = signSeq; }
+
+		public String getSignDate() { return signDate; }
+
+		public void setSignDate(String signDate) { this.signDate = signDate; }
+
+		public String getCheckinType() { return checkinType; }
+
+		public void setCheckinType(String checkinType) { this.checkinType = checkinType; }
+
+		public Date getLatestSignTime() { return latestSignTime; }
+
+		public void setLatestSignTime(Date latestSignTime) { this.latestSignTime = latestSignTime; }
+
+	}
+}

+ 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.google.gson.JsonElement;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 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.AttendanceDetail;
 import com.x.attendance.entity.AttendanceScheduleSetting;
 import com.x.attendance.entity.AttendanceScheduleSetting;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 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 {
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
-		Wi wrapIn = null;
-		Date datetime = null;
-		List<String> ids_temp = null;
 		DateOperation dateOperation = new DateOperation();
 		DateOperation dateOperation = new DateOperation();
 		AttendanceDetail attendanceDetail = new AttendanceDetail();
 		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;
 		Boolean check = true;
 
 
+		Wi wrapIn = null;
 		try {
 		try {
 			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
 			wrapIn = this.convertToWrapIn(jsonElement, Wi.class);
 		} catch (Exception e) {
 		} catch (Exception e) {
@@ -59,6 +59,9 @@ public class ActionReciveAttendance extends BaseAction {
 				result.error(exception);
 				result.error(exception);
 			}
 			}
 		}
 		}
+
+		Date datetime = null;
+
 		if (check) {
 		if (check) {
 			try {
 			try {
 				datetime = dateOperation.getDateFromString(wrapIn.getRecordDateString());
 				datetime = dateOperation.getDateFromString(wrapIn.getRecordDateString());
@@ -86,6 +89,7 @@ public class ActionReciveAttendance extends BaseAction {
 				}
 				}
 			}
 			}
 		}
 		}
+
 		if (check) {
 		if (check) {
 			if (wrapIn.getOffDutyTime() != null && wrapIn.getOffDutyTime().trim().length() > 0) {
 			if (wrapIn.getOffDutyTime() != null && wrapIn.getOffDutyTime().trim().length() > 0) {
 				try {
 				try {
@@ -110,63 +114,73 @@ public class ActionReciveAttendance extends BaseAction {
 				logger.error(e, effectivePerson, request, null);
 				logger.error(e, effectivePerson, request, null);
 			}
 			}
 		}
 		}
+
 		if (check) {
 		if (check) {
+			//分析保存好的考勤数据
 			try {
 			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;
 		return result;
 	}
 	}
 	
 	

+ 29 - 29
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/attendancedetail/ActionReciveAttendanceMobile.java

@@ -1,10 +1,9 @@
 package com.x.attendance.assemble.control.jaxrs.attendancedetail;
 package com.x.attendance.assemble.control.jaxrs.attendancedetail;
 
 
 import java.util.Date;
 import java.util.Date;
-import java.util.List;
 
 
+import javax.persistence.Column;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
@@ -41,40 +40,29 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 		}
 		}
 
 
 		if( check ){
 		if( check ){
-			if( wrapIn.getRecordAddress() == null || wrapIn.getRecordAddress().isEmpty() ){
-				check = false;
-				Exception exception = new ExceptionAddressEmpty();
-				result.error( exception );
-				//logger.error( e, currentPerson, request, null);
-			}else{
+			if( StringUtils.isNotEmpty(wrapIn.getRecordAddress()) ){
 				attendanceDetailMobile.setRecordAddress( wrapIn.getRecordAddress() );
 				attendanceDetailMobile.setRecordAddress( wrapIn.getRecordAddress() );
 			}
 			}
 		}
 		}
 		if( check ){
 		if( check ){
-			if( wrapIn.getLatitude() == null || wrapIn.getLatitude().isEmpty() ){
-				check = false;
-				Exception exception = new ExceptionLatitudeEmpty();
-				result.error( exception );
-				//logger.error( e, currentPerson, request, null);
-			}else{
+			if( StringUtils.isNotEmpty(wrapIn.getLatitude())){
 				attendanceDetailMobile.setLatitude( wrapIn.getLatitude() );
 				attendanceDetailMobile.setLatitude( wrapIn.getLatitude() );
 			}
 			}
 		}
 		}
 		if( check ){
 		if( check ){
-			if( wrapIn.getLongitude() == null || wrapIn.getLongitude().isEmpty() ){
-				check = false;
-				Exception exception = new ExceptionLongitudeEmpty();
-				result.error( exception );
-				//logger.error( e, currentPerson, request, null);
-			}else{
+			if( StringUtils.isNotEmpty(wrapIn.getLongitude())){
 				attendanceDetailMobile.setLongitude( wrapIn.getLongitude() );
 				attendanceDetailMobile.setLongitude( wrapIn.getLongitude() );
 			}
 			}
 		}
 		}
+
 		if( check ){
 		if( check ){
 			attendanceDetailMobile.setEmpName( currentPerson.getDistinguishedName() );
 			attendanceDetailMobile.setEmpName( currentPerson.getDistinguishedName() );
+			attendanceDetailMobile.setCheckin_time(wrapIn.getCheckin_time());
+			attendanceDetailMobile.setCheckin_type(wrapIn.getCheckin_type());
 		}
 		}
+
 		if( check ){
 		if( check ){
-			if( wrapIn.getSignTime() != null && wrapIn.getSignTime().trim().length() > 0 ){
+			if( StringUtils.isNotEmpty(wrapIn.getSignTime()) ){
 				try{
 				try{
 					datetime = dateOperation.getDateFromString( wrapIn.getSignTime() );
 					datetime = dateOperation.getDateFromString( wrapIn.getSignTime() );
 					attendanceDetailMobile.setSignTime( dateOperation.getDateStringFromDate( datetime, "HH:mm:ss") ); //打卡时间
 					attendanceDetailMobile.setSignTime( dateOperation.getDateStringFromDate( datetime, "HH:mm:ss") ); //打卡时间
@@ -87,6 +75,12 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 			}else{//打卡时间没有填写就填写为当前时间
 			}else{//打卡时间没有填写就填写为当前时间
 				attendanceDetailMobile.setSignTime( dateOperation.getNowTime() ); //打卡时间
 				attendanceDetailMobile.setSignTime( dateOperation.getNowTime() ); //打卡时间
 			}
 			}
+
+			if( wrapIn.checkin_time < 1500000000000L ){ //无效
+				attendanceDetailMobile.setCheckin_time( new Date().getTime() ); //打卡时间
+			}else{//打卡时间没有填写就填写为当前时间
+				attendanceDetailMobile.setCheckin_time( wrapIn.checkin_time ); //打卡时间
+			}
 		}
 		}
 		if( check ){
 		if( check ){
 			if( StringUtils.isNotEmpty( wrapIn.getRecordDateString() ) ){
 			if( StringUtils.isNotEmpty( wrapIn.getRecordDateString() ) ){
@@ -108,7 +102,6 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 			if( StringUtils.isNotEmpty( wrapIn.getId() )){
 			if( StringUtils.isNotEmpty( wrapIn.getId() )){
 				attendanceDetailMobile.setId( wrapIn.getId() );
 				attendanceDetailMobile.setId( wrapIn.getId() );
 			}
 			}
-			
 			attendanceDetailMobile.setSignDescription( wrapIn.getSignDescription() );
 			attendanceDetailMobile.setSignDescription( wrapIn.getSignDescription() );
 			try {
 			try {
 				attendanceDetailMobile = attendanceDetailServiceAdv.save( attendanceDetailMobile );
 				attendanceDetailMobile = attendanceDetailServiceAdv.save( attendanceDetailMobile );
@@ -120,11 +113,10 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 				logger.error( e, currentPerson, request, null);
 				logger.error( e, currentPerson, request, null);
 			}
 			}
 		}
 		}
-		
-		if( check ){
-			//对该员工的所有移动考勤数据进行一个整合
-			attendanceDetailServiceAdv.pushToDetail( currentPerson.getDistinguishedName(), attendanceDetailMobile.getRecordDateString() );
 
 
+		if( check ){
+			//对该员工的所有移动考勤数据进行一个整合,并且立即send到分析队列
+			attendanceDetailServiceAdv.pushToDetail( currentPerson.getDistinguishedName(), attendanceDetailMobile.getRecordDateString(), effectivePerson.getDebugger() );
 		}
 		}
 		return result;
 		return result;
 	}
 	}
@@ -141,7 +133,13 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 		private String empName;
 		private String empName;
 
 
 		@FieldDescribe( "打卡记录日期字符串:yyyy-mm-dd, 必须填写." )
 		@FieldDescribe( "打卡记录日期字符串:yyyy-mm-dd, 必须填写." )
-		private String recordDateString;	
+		private String recordDateString;
+
+		@FieldDescribe("打卡类型。字符串,目前有:上午上班打卡,上午下班打卡,下午上班打卡,下午下班打卡,外出打卡,午间打卡")
+		private String checkin_type;
+
+		@FieldDescribe("打卡时间。Unix时间戳")
+		private long checkin_time;
 
 
 		@FieldDescribe( "打卡时间: hh24:mi:ss, 必须填写." )
 		@FieldDescribe( "打卡时间: hh24:mi:ss, 必须填写." )
 		private String signTime;
 		private String signTime;
@@ -215,7 +213,6 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 		public void setOptSystemName(String optSystemName) {
 		public void setOptSystemName(String optSystemName) {
 			this.optSystemName = optSystemName;
 			this.optSystemName = optSystemName;
 		}
 		}
-		
 		public String getEmpNo() {
 		public String getEmpNo() {
 			return empNo;
 			return empNo;
 		}
 		}
@@ -240,7 +237,10 @@ public class ActionReciveAttendanceMobile extends BaseAction {
 		public void setId(String id) {
 		public void setId(String id) {
 			this.id = id;
 			this.id = id;
 		}
 		}
-		
+		public String getCheckin_type() { return checkin_type; }
+		public void setCheckin_type(String checkin_type) { this.checkin_type = checkin_type; }
+		public long getCheckin_time() { return checkin_time; }
+		public void setCheckin_time(long checkin_time) { this.checkin_time = checkin_time; }
 	}
 	}
 	
 	
 	public static class Wo extends WoId {
 	public static class Wo extends WoId {

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

@@ -58,6 +58,29 @@ public class AttendanceDetailMobileAction extends StandardJaxrsAction {
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
 	}
 	}
 
 
+	@JaxrsMethodDescribe(value = "查询登录者当天的所有移动打卡信息记录", action = ActionListMyMobileRecordToday.class)
+	@Path("my")
+	@GET
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listMyRecords(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request ) {
+		ActionResult<ActionListMyMobileRecordToday.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		Boolean check = true;
+
+		if (check) {
+			try {
+				result = new ActionListMyMobileRecordToday().execute( request, effectivePerson );
+			} catch (Exception e) {
+				result = new ActionResult<>();
+				Exception exception = new ExceptionAttendanceDetailProcess(e, "查询登录者当天的所有移动打卡信息记录时发生异常!");
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
 	@JaxrsMethodDescribe(value = "移动打卡信息记录明细查询", action = ActionListMobileWithFilter.class)
 	@JaxrsMethodDescribe(value = "移动打卡信息记录明细查询", action = ActionListMobileWithFilter.class)
 	@Path("filter/list/page/{page}/count/{count}")
 	@Path("filter/list/page/{page}/count/{count}")
 	@PUT
 	@PUT

+ 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.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckRemoveType;
 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.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.jaxrs.WoId;
@@ -28,6 +29,9 @@ public class ActionDelete extends BaseAction {
 				emc.beginTransaction(AttendanceStatisticalCycle.class);
 				emc.beginTransaction(AttendanceStatisticalCycle.class);
 				emc.remove(attendanceStatisticalCycle, CheckRemoveType.all);
 				emc.remove(attendanceStatisticalCycle, CheckRemoveType.all);
 				emc.commit();
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceStatisticalCycle.class );
+
 				result.setData(new Wo(id));
 				result.setData(new Wo(id));
 			}
 			}
 		} catch (Exception e) {
 		} 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.entity.annotation.CheckPersistType;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
 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.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.jaxrs.WoId;
@@ -80,6 +81,9 @@ public class ActionSave extends BaseAction {
 					emc.persist(attendanceStatisticalCycle, CheckPersistType.all);
 					emc.persist(attendanceStatisticalCycle, CheckPersistType.all);
 				}
 				}
 				emc.commit();
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceStatisticalCycle.class );
+
 				result.setData(new Wo(attendanceStatisticalCycle.getId()));
 				result.setData(new Wo(attendanceStatisticalCycle.getId()));
 			} catch (Exception e) {
 			} catch (Exception e) {
 				e.printStackTrace();
 				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.common.date.DateOperation;
 import com.x.attendance.assemble.control.service.UserManagerService;
 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 com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import net.sf.ehcache.Ehcache;
 
 
 public class BaseAction extends StandardJaxrsAction{
 public class BaseAction extends StandardJaxrsAction{
-	
+
+	protected Ehcache cache = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
 	protected UserManagerService userManagerService = new UserManagerService();
 	protected UserManagerService userManagerService = new UserManagerService();
 	protected DateOperation dateOperation = new DateOperation();
 	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;
 package com.x.attendance.assemble.control.jaxrs.attendanceworkdayconfig;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+
+import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckRemoveType;
 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.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.jaxrs.WoId;
@@ -29,6 +32,9 @@ public class ActionDelete extends BaseAction {
 				emc.beginTransaction(AttendanceWorkDayConfig.class);
 				emc.beginTransaction(AttendanceWorkDayConfig.class);
 				emc.remove(attendanceWorkDayConfig, CheckRemoveType.all);
 				emc.remove(attendanceWorkDayConfig, CheckRemoveType.all);
 				emc.commit();
 				emc.commit();
+
+				ApplicationCache.notify( AttendanceWorkDayConfig.class );
+
 				result.setData(new Wo(id));
 				result.setData(new Wo(id));
 			}
 			}
 		} catch (Exception e) {
 		} 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.entity.annotation.CheckPersistType;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopier;
 import com.x.base.core.project.bean.WrapCopierFactory;
 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.ActionResult;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.http.EffectivePerson;
 import com.x.base.core.project.jaxrs.WoId;
 import com.x.base.core.project.jaxrs.WoId;
@@ -95,6 +96,9 @@ public class ActionSave extends BaseAction {
 							attendanceWorkDayConfig.setConfigMonth(dateOperation.getMonth(date));
 							attendanceWorkDayConfig.setConfigMonth(dateOperation.getMonth(date));
 							emc.persist(attendanceWorkDayConfig, CheckPersistType.all);
 							emc.persist(attendanceWorkDayConfig, CheckPersistType.all);
 							emc.commit();
 							emc.commit();
+
+							ApplicationCache.notify( AttendanceWorkDayConfig.class );
+
 							result.setData(new Wo(attendanceWorkDayConfig.getId()));
 							result.setData(new Wo(attendanceWorkDayConfig.getId()));
 						} catch (Exception e) {
 						} catch (Exception e) {
 							Exception exception = new ExceptionWorkDayConfigProcess(e,
 							Exception exception = new ExceptionWorkDayConfigProcess(e,

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

@@ -4,6 +4,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
@@ -22,31 +24,33 @@ public class ActionDelete extends BaseAction {
 	
 	
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, String id ) throws Exception {
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		EffectivePerson currentPerson = this.effectivePerson(request);
 		EffectivePerson currentPerson = this.effectivePerson(request);
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+
 			//先判断需要操作的应用信息是否存在,根据ID进行一次查询,如果不存在不允许继续操作
 			//先判断需要操作的应用信息是否存在,根据ID进行一次查询,如果不存在不允许继续操作
 			AttendanceSelfHoliday attendanceSelfHoliday = emc.find(id, AttendanceSelfHoliday.class);
 			AttendanceSelfHoliday attendanceSelfHoliday = emc.find(id, AttendanceSelfHoliday.class);
 			if (null == attendanceSelfHoliday) {
 			if (null == attendanceSelfHoliday) {
 				Exception exception = new ExceptionSelfHolidayNotExists( id );
 				Exception exception = new ExceptionSelfHolidayNotExists( id );
 				result.error( exception );
 				result.error( exception );
-				//logger.error( e, currentPerson, request, null);
 			}else{
 			}else{
 				emc.beginTransaction( AttendanceSelfHoliday.class );
 				emc.beginTransaction( AttendanceSelfHoliday.class );
 				emc.remove( attendanceSelfHoliday, CheckRemoveType.all );
 				emc.remove( attendanceSelfHoliday, CheckRemoveType.all );
 				emc.commit();
 				emc.commit();
 				result.setData( new Wo(id) );
 				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 ) ){
+//					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger()  );
+//				}
 				if( ListTools.isNotEmpty( ids ) ){
 				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);
+					for( String _id : ids ){
+						try { //分析保存好的考勤数据
+							ThisApplication.detailAnalyseQueue.send( _id );
+						} catch ( Exception e1 ) {
+							e1.printStackTrace();
+						}
 					}
 					}
-					attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger()  );
 				}
 				}
 			}			
 			}			
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {

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

@@ -1,13 +1,12 @@
 package com.x.attendance.assemble.control.jaxrs.selfholiday;
 package com.x.attendance.assemble.control.jaxrs.selfholiday;
 
 
 import java.util.List;
 import java.util.List;
-import java.util.Map;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 
 
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.Business;
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 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.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckRemoveType;
 import com.x.base.core.entity.annotation.CheckRemoveType;
@@ -26,7 +25,6 @@ public class ActionDeleteByWfDocId extends BaseAction {
 		logger.debug( effectivePerson, ">>>>>>>>>>method delete has been called, try to delete attendanceSelfHoliday{'wfDocId':'" + wfDocId + "'}......");
 		logger.debug( effectivePerson, ">>>>>>>>>>method delete has been called, try to delete attendanceSelfHoliday{'wfDocId':'" + wfDocId + "'}......");
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
 		EffectivePerson currentPerson = this.effectivePerson(request);
 		EffectivePerson currentPerson = this.effectivePerson(request);
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 		
 		
 		logger.debug( effectivePerson, ">>>>>>>>>>user " + currentPerson.getDistinguishedName() + "try to delete AttendanceSelfHoliday......");
 		logger.debug( effectivePerson, ">>>>>>>>>>user " + currentPerson.getDistinguishedName() + "try to delete AttendanceSelfHoliday......");
 		List<String> ids = null;
 		List<String> ids = null;
@@ -48,18 +46,20 @@ public class ActionDeleteByWfDocId extends BaseAction {
 						logger.debug( effectivePerson, ">>>>>>>>>>System delete attendanceSelfHoliday success......");
 						logger.debug( effectivePerson, ">>>>>>>>>>System delete attendanceSelfHoliday success......");
 
 
 						// 应该只需要重新分析该用户在请假期间已经存在的打卡数据即可
 						// 应该只需要重新分析该用户在请假期间已经存在的打卡数据即可
-						ids = attendanceDetailAnalyseServiceAdv.getAnalyseAttendanceDetailIds(
+						ids = attendanceDetailAnalyseServiceAdv.listAnalyseAttendanceDetailIds(
 								attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(),
 								attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(),
-								attendanceSelfHoliday.getEndTime());
-						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);
+								attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
+//						if ( ListTools.isNotEmpty( ids ) ) {
+//							attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), effectivePerson.getDebugger() );
+//						}
+						if( ListTools.isNotEmpty( ids ) ){
+							for( String id : ids ){
+								try { //分析保存好的考勤数据
+									ThisApplication.detailAnalyseQueue.send( id );
+								} catch ( Exception e1 ) {
+									e1.printStackTrace();
+								}
 							}
 							}
-							attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger() );
 						}
 						}
 					}
 					}
 				}
 				}

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

@@ -2,6 +2,7 @@ package com.x.attendance.assemble.control.jaxrs.selfholiday;
 
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
 import com.x.attendance.assemble.control.ExceptionWrapInConvert;
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceSelfHoliday;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
@@ -16,6 +17,7 @@ import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.ListTools;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
@@ -24,12 +26,9 @@ public class ActionSave extends BaseAction {
 	private static  Logger logger = LoggerFactory.getLogger( ActionSave.class );
 	private static  Logger logger = LoggerFactory.getLogger( ActionSave.class );
 	
 	
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
 	protected ActionResult<Wo> execute( HttpServletRequest request, EffectivePerson effectivePerson, JsonElement jsonElement ) throws Exception {
-		logger.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" );
-		logger.info("++++++++++++++++++++++调用接口:com.x.attendance.assemble.control.jaxrs.selfholiday.ActionSave......" );
 		ActionResult<Wo> result = new ActionResult<>();
 		ActionResult<Wo> result = new ActionResult<>();
 		Wi wrapIn = null;
 		Wi wrapIn = null;
 		List<AttendanceSelfHoliday> holidayList = null;
 		List<AttendanceSelfHoliday> holidayList = null;
-		Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
 
 
 		//获取到当前用户信息
 		//获取到当前用户信息
 		EffectivePerson currentPerson = this.effectivePerson(request);
 		EffectivePerson currentPerson = this.effectivePerson(request);
@@ -47,7 +46,6 @@ public class ActionSave extends BaseAction {
 		if( check ){
 		if( check ){
 			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 				AttendanceSelfHoliday attendanceSelfHoliday = null;
 				AttendanceSelfHoliday attendanceSelfHoliday = null;
-//				AttendanceSelfHoliday attendanceSelfHoliday = new AttendanceSelfHoliday();
 
 
 				if( wrapIn != null && StringUtils.isNoneEmpty( wrapIn.getEmployeeName() )
 				if( wrapIn != null && StringUtils.isNoneEmpty( wrapIn.getEmployeeName() )
 						&& StringUtils.isNoneEmpty( wrapIn.getEmployeeNumber() )
 						&& StringUtils.isNoneEmpty( wrapIn.getEmployeeNumber() )
@@ -60,11 +58,11 @@ public class ActionSave extends BaseAction {
 					if(StringUtils.isNotEmpty( wrapIn.getBatchFlag() ) ){
 					if(StringUtils.isNotEmpty( wrapIn.getBatchFlag() ) ){
 						holidayList = attendanceSelfHolidayServiceAdv.listWithBatchFlag( wrapIn.getBatchFlag() );
 						holidayList = attendanceSelfHolidayServiceAdv.listWithBatchFlag( wrapIn.getBatchFlag() );
 						if(ListTools.isNotEmpty( holidayList )){
 						if(ListTools.isNotEmpty( holidayList )){
-							logger.info("++++++++先根据batchFlag删除原来的数据,然后再进行新数据的保存+++++++++" );
+							logger.info("先根据batchFlag删除原来的数据,然后再进行新数据的保存" );
 							for( AttendanceSelfHoliday holiday : holidayList ){
 							for( AttendanceSelfHoliday holiday : holidayList ){
 								emc.remove( emc.find(holiday.getId(), AttendanceSelfHoliday.class ), CheckRemoveType.all );
 								emc.remove( emc.find(holiday.getId(), AttendanceSelfHoliday.class ), CheckRemoveType.all );
 							}
 							}
-							logger.info("++++++++删除" + holidayList.size() + "条旧请假信息数据。" );
+							logger.info("删除" + holidayList.size() + "条旧请假信息数据。" );
 						}
 						}
 					}
 					}
 
 
@@ -75,7 +73,7 @@ public class ActionSave extends BaseAction {
 							//更新已经存在的信息
 							//更新已经存在的信息
 							wrapIn.copyTo( attendanceSelfHoliday );
 							wrapIn.copyTo( attendanceSelfHoliday );
 							attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
 							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);
 							emc.check( attendanceSelfHoliday, CheckPersistType.all);
 						}else{
 						}else{
 							attendanceSelfHoliday = new AttendanceSelfHoliday();
 							attendanceSelfHoliday = new AttendanceSelfHoliday();
@@ -83,7 +81,7 @@ public class ActionSave extends BaseAction {
 							//使用参数传入的ID作为记录的ID
 							//使用参数传入的ID作为记录的ID
 							attendanceSelfHoliday.setId( wrapIn.getId() );
 							attendanceSelfHoliday.setId( wrapIn.getId() );
 							attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
 							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);
 							emc.persist( attendanceSelfHoliday, CheckPersistType.all);
 						}
 						}
 					}else{
 					}else{
@@ -92,7 +90,7 @@ public class ActionSave extends BaseAction {
 
 
 						wrapIn.copyTo( attendanceSelfHoliday );
 						wrapIn.copyTo( attendanceSelfHoliday );
 						attendanceSelfHoliday.setBatchFlag(wrapIn.getBatchFlag());
 						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);
 						emc.persist( attendanceSelfHoliday, CheckPersistType.all);
 						result.setData( new Wo( attendanceSelfHoliday.getId() ) );
 						result.setData( new Wo( attendanceSelfHoliday.getId() ) );
 					}
 					}
@@ -101,26 +99,26 @@ public class ActionSave extends BaseAction {
 					
 					
 					//根据员工休假数据来记录与这条数据相关的统计需求记录
 					//根据员工休假数据来记录与这条数据相关的统计需求记录
 					//new AttendanceDetailAnalyseService().recordStatisticRequireLog( attendanceSelfHoliday );
 					//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 ) ){
 					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);
+						for( String id : ids ){
+							try { //分析保存好的考勤数据
+								ThisApplication.detailAnalyseQueue.send( id );
+							} catch ( Exception e1 ) {
+								e1.printStackTrace();
+							}
 						}
 						}
-						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetails( attendanceSelfHoliday.getEmployeeName(), attendanceSelfHoliday.getStartTime(), attendanceSelfHoliday.getEndTime(), topUnitAttendanceStatisticalCycleMap, effectivePerson.getDebugger()  );
 					}
 					}
 				}else{
 				}else{
 					if( jsonElement == null ){
 					if( jsonElement == null ){
-						logger.info("++++++++传入的员工请假信息JSON数据为空......" );
+						logger.debug("传入的员工请假信息JSON数据为空......" );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的员工请假信息JSON数据为空,无法保存数据信息,请检查数据内容!" );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的员工请假信息JSON数据为空,无法保存数据信息,请检查数据内容!" );
 						result.error( exception );
 						result.error( exception );
 					}else {
 					}else {
-						logger.info("++++++++传入的数据不符合请假数据接口要求......" );
+						logger.debug("传入的数据不符合请假数据接口要求......" );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的数据不符合请假数据接口要求,请检查数据内容:" + jsonElement.getAsString() );
 						Exception exception = new ExceptionSelfHolidayProcess( "传入的数据不符合请假数据接口要求,请检查数据内容:" + jsonElement.getAsString() );
 						result.error( exception );
 						result.error( exception );
 					}
 					}
@@ -132,7 +130,6 @@ public class ActionSave extends BaseAction {
 				logger.error( e, currentPerson, request, null);
 				logger.error( e, currentPerson, request, null);
 			}
 			}
 		}
 		}
-		logger.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" );
 		return result;
 		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{
 public class OperatorDataAnalyse implements Runnable{
 
 
 	private static  Logger logger = LoggerFactory.getLogger( OperatorDataAnalyse.class );
 	private static  Logger logger = LoggerFactory.getLogger( OperatorDataAnalyse.class );
-	private AttendanceSelfHolidayServiceAdv attendanceSelfHolidayServiceAdv = null;
 	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = null;
 	private AttendanceDetailServiceAdv attendanceDetailServiceAdv = null;
-	private AttendanceScheduleSettingServiceAdv attendanceScheduleSettingServiceAdv = null;
 	private AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = null;
 	private AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = null;
 	private StatusSystemImportOpt statusSystemImportOpt = null;
 	private StatusSystemImportOpt statusSystemImportOpt = null;
 	private EntityAnalyseData entityAnalyseData = null;
 	private EntityAnalyseData entityAnalyseData = null;
@@ -30,8 +28,6 @@ public class OperatorDataAnalyse implements Runnable{
 	private Boolean debugger = false;
 	private Boolean debugger = false;
 	
 	
 	public OperatorDataAnalyse( EntityAnalyseData entityAnalyseData, Boolean debugger ) {
 	public OperatorDataAnalyse( EntityAnalyseData entityAnalyseData, Boolean debugger ) {
-		attendanceScheduleSettingServiceAdv = new AttendanceScheduleSettingServiceAdv();
-		attendanceSelfHolidayServiceAdv = new AttendanceSelfHolidayServiceAdv();
 		attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
 		attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
 		statusSystemImportOpt = StatusSystemImportOpt.getInstance();
 		statusSystemImportOpt = StatusSystemImportOpt.getInstance();
 		attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
 		attendanceDetailServiceAdv = new AttendanceDetailServiceAdv();
@@ -45,40 +41,19 @@ public class OperatorDataAnalyse implements Runnable{
 	}
 	}
 	
 	
 	private void execute( EntityAnalyseData entityAnalyseData ) {
 	private void execute( EntityAnalyseData entityAnalyseData ) {
-		List<String> ids_temp = null;
 		List<String> detail_ids = entityAnalyseData.getDetailIds();
 		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;
 		AttendanceDetail detail = null;
 		
 		
 		statusSystemImportOpt.setProcessing( true );
 		statusSystemImportOpt.setProcessing( true );
 		statusSystemImportOpt.setProcessing_analysis( true );
 		statusSystemImportOpt.setProcessing_analysis( true );
 		
 		
 		if ( detail_ids != null && !detail_ids.isEmpty() ) {
 		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 ) {
 			for ( String id: detail_ids ) {
 				try {
 				try {
 					detail = attendanceDetailServiceAdv.get( id );
 					detail = attendanceDetailServiceAdv.get( id );
 					if ( detail != null ) {
 					if ( detail != null ) {
-						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
+						attendanceDetailAnalyseServiceAdv.analyseAttendanceDetail( detail, debugger );
 						statusSystemImportOpt.increaseProcess_analysis_count(1);
 						statusSystemImportOpt.increaseProcess_analysis_count(1);
 					} else {
 					} else {
 						statusSystemImportOpt.increaseProcess_analysis_error(1);
 						statusSystemImportOpt.increaseProcess_analysis_error(1);

+ 55 - 15
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceAppealInfoService.java

@@ -3,12 +3,13 @@ package com.x.attendance.assemble.control.service;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceAppealAuditInfo;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceAppealInfo;
 import com.x.attendance.entity.AttendanceDetail;
 import com.x.attendance.entity.AttendanceDetail;
-import com.x.attendance.entity.DateOperation;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckPersistType;
@@ -43,22 +44,37 @@ public class AttendanceAppealInfoService {
 		}
 		}
 	}
 	}
 
 
-	public AttendanceAppealInfo save( EntityManagerContainer emc, AttendanceAppealInfo attendanceAppealInfo ) throws Exception {
+	public AttendanceAppealInfo save( EntityManagerContainer emc, AttendanceAppealInfo attendanceAppealInfo, AttendanceAppealAuditInfo attendanceAppealAuditInfo ) throws Exception {
 		AttendanceDetail attendanceDetail = null;
 		AttendanceDetail attendanceDetail = null;
 		AttendanceAppealInfo attendanceAppealInfo_temp = null;
 		AttendanceAppealInfo attendanceAppealInfo_temp = null;
-		emc.beginTransaction(AttendanceAppealInfo.class);
-		emc.beginTransaction(AttendanceDetail.class);
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo_temp = null;
+
 		attendanceAppealInfo_temp = emc.find( attendanceAppealInfo.getId(), AttendanceAppealInfo.class);
 		attendanceAppealInfo_temp = emc.find( attendanceAppealInfo.getId(), AttendanceAppealInfo.class);
+		attendanceAppealAuditInfo_temp = emc.find( attendanceAppealInfo.getId(), AttendanceAppealAuditInfo.class);
 		attendanceDetail = emc.find( attendanceAppealInfo.getDetailId(), AttendanceDetail.class);
 		attendanceDetail = emc.find( attendanceAppealInfo.getDetailId(), AttendanceDetail.class);
+
 		if( attendanceDetail == null ){
 		if( attendanceDetail == null ){
 			throw new Exception("attendance detail info not exists.");
 			throw new Exception("attendance detail info not exists.");
 		}else{
 		}else{
+			emc.beginTransaction( AttendanceDetail.class );
+			emc.beginTransaction( AttendanceAppealInfo.class );
+			emc.beginTransaction( AttendanceAppealAuditInfo.class );
+
 			if ( attendanceAppealInfo_temp != null ) {
 			if ( attendanceAppealInfo_temp != null ) {
 				attendanceAppealInfo.copyTo( attendanceAppealInfo_temp, JpaObject.FieldsUnmodify );
 				attendanceAppealInfo.copyTo( attendanceAppealInfo_temp, JpaObject.FieldsUnmodify );
 				emc.check( attendanceAppealInfo_temp, CheckPersistType.all );				
 				emc.check( attendanceAppealInfo_temp, CheckPersistType.all );				
 			}else{
 			}else{
 				emc.persist( attendanceAppealInfo, CheckPersistType.all);
 				emc.persist( attendanceAppealInfo, CheckPersistType.all);
 			}
 			}
+
+			if ( attendanceAppealAuditInfo_temp != null ) {
+				attendanceAppealAuditInfo.copyTo( attendanceAppealAuditInfo_temp, JpaObject.FieldsUnmodify );
+				attendanceAppealAuditInfo.setId(attendanceAppealInfo.getId());
+				emc.check( attendanceAppealAuditInfo_temp, CheckPersistType.all );
+			}else{
+				emc.persist( attendanceAppealAuditInfo, CheckPersistType.all);
+			}
+
 			//将打卡记录表里的打卡数据置为正在申诉中
 			//将打卡记录表里的打卡数据置为正在申诉中
 			attendanceDetail.setAppealStatus(1);
 			attendanceDetail.setAppealStatus(1);
 			attendanceDetail.setAppealProcessor( attendanceAppealInfo.getCurrentProcessor() );
 			attendanceDetail.setAppealProcessor( attendanceAppealInfo.getCurrentProcessor() );
@@ -72,21 +88,34 @@ public class AttendanceAppealInfoService {
 
 
 	public AttendanceAppealInfo updateAppealProcessInfoForFirstProcess(EntityManagerContainer emc, String id, String unitName,
 	public AttendanceAppealInfo updateAppealProcessInfoForFirstProcess(EntityManagerContainer emc, String id, String unitName,
 			String topUnitName, String processor, Date processTime, String opinion, Integer status, Boolean autoCommit ) throws Exception {
 			String topUnitName, String processor, Date processTime, String opinion, Integer status, Boolean autoCommit ) throws Exception {
+
 		AttendanceAppealInfo attendanceAppealInfo = emc.find(id, AttendanceAppealInfo.class);
 		AttendanceAppealInfo attendanceAppealInfo = emc.find(id, AttendanceAppealInfo.class);
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = emc.find(id, AttendanceAppealAuditInfo.class);
 		if( attendanceAppealInfo == null ){
 		if( attendanceAppealInfo == null ){
 			throw new Exception( "attendanceAppealInfo{'id':'"+ id +"'} not exists." );
 			throw new Exception( "attendanceAppealInfo{'id':'"+ id +"'} not exists." );
 		}
 		}
 		if( autoCommit ){
 		if( autoCommit ){
 			emc.beginTransaction(AttendanceAppealInfo.class);
 			emc.beginTransaction(AttendanceAppealInfo.class);
+			emc.beginTransaction(AttendanceAppealAuditInfo.class);
 		}
 		}
-		attendanceAppealInfo.setProcessPersonUnit1( unitName );
-		attendanceAppealInfo.setProcessPersonTopUnit1(topUnitName);
-		attendanceAppealInfo.setProcessPerson1( processor );
-		attendanceAppealInfo.setProcessTime1(new Date());
-		attendanceAppealInfo.setOpinion1( opinion );
+		if( attendanceAppealAuditInfo == null ){
+			attendanceAppealAuditInfo = new AttendanceAppealAuditInfo();
+			attendanceAppealAuditInfo.setId( attendanceAppealInfo.getId() );
+			emc.persist( attendanceAppealAuditInfo, CheckPersistType.all );
+		}
+		attendanceAppealAuditInfo.setProcessPersonUnit1( unitName );
+		attendanceAppealAuditInfo.setProcessPersonTopUnit1(topUnitName);
+		attendanceAppealAuditInfo.setProcessPerson1( processor );
+		if( processTime == null ){
+			attendanceAppealAuditInfo.setProcessTime1( new Date() );
+		}else{
+			attendanceAppealAuditInfo.setProcessTime1( processTime );
+		}
+		attendanceAppealAuditInfo.setOpinion1( opinion );
 		attendanceAppealInfo.setStatus( status );
 		attendanceAppealInfo.setStatus( status );
 		emc.check(attendanceAppealInfo, CheckPersistType.all);
 		emc.check(attendanceAppealInfo, CheckPersistType.all);
-		
+		emc.check(attendanceAppealAuditInfo, CheckPersistType.all);
+
 		if( autoCommit ){
 		if( autoCommit ){
 			emc.commit();
 			emc.commit();
 		}
 		}
@@ -97,17 +126,28 @@ public class AttendanceAppealInfoService {
 			String unitName, String topUnitName, String processor, Date processTime, String opinion,
 			String unitName, String topUnitName, String processor, Date processTime, String opinion,
 			Integer status, Boolean autoCommit ) throws Exception {
 			Integer status, Boolean autoCommit ) throws Exception {
 		AttendanceAppealInfo attendanceAppealInfo = emc.find(id, AttendanceAppealInfo.class);
 		AttendanceAppealInfo attendanceAppealInfo = emc.find(id, AttendanceAppealInfo.class);
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = emc.find(id, AttendanceAppealAuditInfo.class);
 		if( attendanceAppealInfo == null ){
 		if( attendanceAppealInfo == null ){
 			throw new Exception( "attendanceAppealInfo{'id':'"+ id +"'} not exists." );
 			throw new Exception( "attendanceAppealInfo{'id':'"+ id +"'} not exists." );
 		}
 		}
 		if( autoCommit ){
 		if( autoCommit ){
 			emc.beginTransaction(AttendanceAppealInfo.class);
 			emc.beginTransaction(AttendanceAppealInfo.class);
+			emc.beginTransaction(AttendanceAppealAuditInfo.class);
+		}
+		if( attendanceAppealAuditInfo == null ){
+			attendanceAppealAuditInfo = new AttendanceAppealAuditInfo();
+			attendanceAppealAuditInfo.setId( attendanceAppealInfo.getId() );
+			emc.persist( attendanceAppealAuditInfo, CheckPersistType.all );
+		}
+		attendanceAppealAuditInfo.setProcessPersonUnit2( unitName );
+		attendanceAppealAuditInfo.setProcessPersonTopUnit2(topUnitName);
+		attendanceAppealAuditInfo.setProcessPerson2( processor );
+		if( processTime == null ){
+			attendanceAppealAuditInfo.setProcessTime2( new Date() );
+		}else{
+			attendanceAppealAuditInfo.setProcessTime2(processTime);
 		}
 		}
-		attendanceAppealInfo.setProcessPersonUnit2( unitName );
-		attendanceAppealInfo.setProcessPersonTopUnit2(topUnitName);
-		attendanceAppealInfo.setProcessPerson2( processor );
-		attendanceAppealInfo.setProcessTime2(new Date());
-		attendanceAppealInfo.setOpinion2( opinion );
+		attendanceAppealAuditInfo.setOpinion2( opinion );
 		attendanceAppealInfo.setStatus( status );
 		attendanceAppealInfo.setStatus( status );
 		emc.check(attendanceAppealInfo, CheckPersistType.all);
 		emc.check(attendanceAppealInfo, CheckPersistType.all);
 		
 		

+ 71 - 9
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/service/AttendanceAppealInfoServiceAdv.java

@@ -2,10 +2,7 @@ package com.x.attendance.assemble.control.service;
 
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.Business;
-import com.x.attendance.entity.AppealConfig;
-import com.x.attendance.entity.AttendanceAppealInfo;
-import com.x.attendance.entity.AttendanceDetail;
-import com.x.attendance.entity.AttendanceSetting;
+import com.x.attendance.entity.*;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckPersistType;
@@ -47,9 +44,9 @@ public class AttendanceAppealInfoServiceAdv {
 		}
 		}
 	}
 	}
 
 
-	public AttendanceAppealInfo saveNewAppeal( AttendanceAppealInfo attendanceAppealInfo ) throws Exception {
+	public AttendanceAppealInfo saveNewAppeal( AttendanceAppealInfo attendanceAppealInfo, AttendanceAppealAuditInfo attendanceAppealAuditInfo ) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceAppealInfoService.save( emc, attendanceAppealInfo );	
+			return attendanceAppealInfoService.save( emc, attendanceAppealInfo, attendanceAppealAuditInfo );
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
 			throw e;
 			throw e;
 		}
 		}
@@ -233,23 +230,28 @@ public class AttendanceAppealInfoServiceAdv {
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
 	public AttendanceAppealInfo firstProcessAttendanceAppeal( String id, String unitName, String topUnitName, String processor, Date processTime, String opinion, Integer status ) throws Exception {
 	public AttendanceAppealInfo firstProcessAttendanceAppeal( String id, String unitName, String topUnitName, String processor, Date processTime, String opinion, Integer status ) throws Exception {
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
 		AttendanceAppealInfo attendanceAppealInfo = null;
 		AttendanceAppealInfo attendanceAppealInfo = null;
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			//修改申诉信息状态和处理过程信息
 			//修改申诉信息状态和处理过程信息
+			emc.beginTransaction( AttendanceAppealAuditInfo.class );
 			emc.beginTransaction( AttendanceAppealInfo.class );
 			emc.beginTransaction( AttendanceAppealInfo.class );
 			emc.beginTransaction( AttendanceDetail.class );
 			emc.beginTransaction( AttendanceDetail.class );
 			attendanceAppealInfo = attendanceAppealInfoService.updateAppealProcessInfoForFirstProcess( emc, id, unitName, topUnitName, processor, processTime, opinion, status, false );
 			attendanceAppealInfo = attendanceAppealInfoService.updateAppealProcessInfoForFirstProcess( emc, id, unitName, topUnitName, processor, processTime, opinion, status, false );
 			if( attendanceAppealInfo != null ){
 			if( attendanceAppealInfo != null ){
+				attendanceAppealAuditInfo = emc.find( id, AttendanceAppealAuditInfo.class );
 				if ( status == 1 ) {
 				if ( status == 1 ) {
 					attendanceAppealInfo.setCurrentProcessor( null );
 					attendanceAppealInfo.setCurrentProcessor( null );
 					attendanceDetailService.updateAppealProcessStatus( emc, id, 9, false );
 					attendanceDetailService.updateAppealProcessStatus( emc, id, 9, false );
 					attendanceNoticeService.notifyAttendanceAppealAcceptMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName() );
 					attendanceNoticeService.notifyAttendanceAppealAcceptMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName() );
 				} else if ( status == 2 ) {// 如果需要继续第二级审批
 				} else if ( status == 2 ) {// 如果需要继续第二级审批
 					//判断是否存在用户的复核人信息
 					//判断是否存在用户的复核人信息
-					if( attendanceAppealInfo.getProcessPerson2() == null || attendanceAppealInfo.getProcessPerson2().isEmpty() ) {
+					if( attendanceAppealAuditInfo.getProcessPerson2() == null || attendanceAppealAuditInfo.getProcessPerson2().isEmpty() ) {
 						attendanceDetailService.updateAppealProcessStatus( emc, id, 1, false );
 						attendanceDetailService.updateAppealProcessStatus( emc, id, 1, false );
-						attendanceAppealInfo.setCurrentProcessor( attendanceAppealInfo.getProcessPerson2() );
+						attendanceAppealAuditInfo.setCurrentProcessor( attendanceAppealAuditInfo.getProcessPerson2() );
+						attendanceAppealInfo.setCurrentProcessor( attendanceAppealAuditInfo.getProcessPerson2() );
 						emc.check( attendanceAppealInfo, CheckPersistType.all );
 						emc.check( attendanceAppealInfo, CheckPersistType.all );
+						emc.check( attendanceAppealAuditInfo, CheckPersistType.all );
 						attendanceNoticeService.notifyAttendanceAppealProcessness2Message( attendanceAppealInfo );
 						attendanceNoticeService.notifyAttendanceAppealProcessness2Message( attendanceAppealInfo );
 					}
 					}
 				} else {// 如果审批不通过
 				} else {// 如果审批不通过
@@ -265,15 +267,30 @@ public class AttendanceAppealInfoServiceAdv {
 		return attendanceAppealInfo;
 		return attendanceAppealInfo;
 	}
 	}
 
 
+	/**
+	 *
+	 * @param id
+	 * @param unitName
+	 * @param topUnitName
+	 * @param processor
+	 * @param processTime
+	 * @param opinion
+	 * @param status //申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过
+	 * @return
+	 * @throws Exception
+	 */
 	public AttendanceAppealInfo secondProcessAttendanceAppeal( String id, String unitName, String topUnitName,
 	public AttendanceAppealInfo secondProcessAttendanceAppeal( String id, String unitName, String topUnitName,
 			String processor, Date processTime, String opinion, Integer status ) throws Exception {
 			String processor, Date processTime, String opinion, Integer status ) throws Exception {
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
 		AttendanceAppealInfo attendanceAppealInfo = null;
 		AttendanceAppealInfo attendanceAppealInfo = null;
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			//修改申诉信息状态和处理过程信息
 			//修改申诉信息状态和处理过程信息
+			emc.beginTransaction( AttendanceAppealAuditInfo.class );
 			emc.beginTransaction( AttendanceAppealInfo.class );
 			emc.beginTransaction( AttendanceAppealInfo.class );
 			emc.beginTransaction( AttendanceDetail.class );
 			emc.beginTransaction( AttendanceDetail.class );
 			attendanceAppealInfo = attendanceAppealInfoService.updateAppealProcessInfoForSecondProcess( emc, id, unitName, topUnitName, processor, processTime, opinion, status, false );
 			attendanceAppealInfo = attendanceAppealInfoService.updateAppealProcessInfoForSecondProcess( emc, id, unitName, topUnitName, processor, processTime, opinion, status, false );
 			if( attendanceAppealInfo != null ){
 			if( attendanceAppealInfo != null ){
+				attendanceAppealAuditInfo = emc.find( id, AttendanceAppealAuditInfo.class );
 				if ( status == 1 ) {
 				if ( status == 1 ) {
 					attendanceDetailService.updateAppealProcessStatus( emc, id, 9, false );
 					attendanceDetailService.updateAppealProcessStatus( emc, id, 9, false );
 					attendanceNoticeService.notifyAttendanceAppealAcceptMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName() );
 					attendanceNoticeService.notifyAttendanceAppealAcceptMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName() );
@@ -282,6 +299,7 @@ public class AttendanceAppealInfoServiceAdv {
 					attendanceNoticeService.notifyAttendanceAppealRejectMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName());
 					attendanceNoticeService.notifyAttendanceAppealRejectMessage( attendanceAppealInfo, attendanceAppealInfo.getEmpName());
 				}
 				}
 				attendanceAppealInfo.setCurrentProcessor( null );
 				attendanceAppealInfo.setCurrentProcessor( null );
+				attendanceAppealAuditInfo.setCurrentProcessor( null );
 			}
 			}
 			emc.commit();
 			emc.commit();
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
@@ -347,5 +365,49 @@ public class AttendanceAppealInfoServiceAdv {
 		}
 		}
 	}
 	}
 
 
-	
+
+	public AttendanceAppealAuditInfo getAppealAuditInfo(String id) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			emc.find( id, AttendanceAppealAuditInfo.class );
+		} catch ( Exception e ) {
+			throw e;
+		}
+		return null;
+	}
+
+
+	/**
+	 * 申诉状态:0-未申诉,1-申诉中,-1-申诉未通过,9-申诉通过
+	 * @param attendanceAppealInfo
+	 * @param activityType
+	 * @param currentProcessor
+	 * @param status
+	 * @throws Exception
+	 */
+	public void syncAppealStatus( AttendanceAppealInfo attendanceAppealInfo, String activityType, String currentProcessor, Integer status ) throws Exception {
+
+		AttendanceAppealAuditInfo attendanceAppealAuditInfo = null;
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			attendanceAppealInfo = emc.find( attendanceAppealInfo.getId(), AttendanceAppealInfo.class );
+			attendanceAppealAuditInfo = emc.find( attendanceAppealInfo.getId(), AttendanceAppealAuditInfo.class );
+
+			emc.beginTransaction( AttendanceAppealInfo.class );
+			emc.beginTransaction( AttendanceAppealAuditInfo.class );
+
+			attendanceAppealInfo.setStatus(status);
+			if( StringUtils.equalsAnyIgnoreCase( "end", activityType )){//审核结束了
+				attendanceAppealInfo.setCurrentProcessor( null );
+				attendanceAppealAuditInfo.setCurrentProcessor( null );
+			}else{
+				attendanceAppealInfo.setCurrentProcessor( currentProcessor );
+				attendanceAppealAuditInfo.setCurrentProcessor( currentProcessor );
+			}
+			emc.commit();
+		} catch ( Exception e ) {
+			throw e;
+		}
+
+
+
+	}
 }
 }

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

@@ -0,0 +1,306 @@
+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 static 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 scheduleSetting
+	 * @throws Exception 
+	 */
+	AttendanceDetail analyseCore( AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger ) throws Exception {
+		if( dateOperation == null ){
+			dateOperation = new DateOperation();
+		}
+		if( detail == null ){
+			throw new Exception("detail is null!" );
+		}
+		if( scheduleSetting == null ){
+			throw new Exception("scheduleSetting is null, empName:" + detail.getEmpName() );
+		}
+		//根据考勤打卡规则来判断启用何种规则来进行考勤结果分析
+		if( 2 == scheduleSetting.getSignProxy() ){
+			//2、一天三次打卡:打上班,下班两次卡外,中午休息时间也需要打一次卡,以确保员工在公司活动
+			detail = new AttendanceDetailAnalyseSignProxy2().analyse(detail, scheduleSetting, debugger);
+		}else if( 3 == scheduleSetting.getSignProxy() ){
+			//3、一天四次打卡:打上午上班,上午下班,下午上班,下午下班四次卡
+			detail = new AttendanceDetailAnalyseSignProxy3().analyse(detail, scheduleSetting, debugger);
+		}else{
+			//1、一天只打上下班两次卡
+			detail = new AttendanceDetailAnalyseSignProxy1().analyse(detail, scheduleSetting, debugger);
+		}
+		return detail;
+	}
+
+	static Date getAfternoonOndutyTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		if( StringUtils.isNotEmpty( detail.getMorningOffdutyTime()) ){
+			try {
+				logger.debug( debugger, "格式化[下午上班签到时间]afternoonOndutyTime=" +  detail.getRecordDateString() + " " + detail.getAfternoonOnDutyTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getAfternoonOnDutyTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,afternoonOndutyTime=" + detail.getRecordDateString() + " " + detail.getAfternoonOnDutyTime() );
+				logger.warn( "系统进行时间转换时发生异常,afternoonOndutyTime=" + detail.getRecordDateString() + " " + detail.getAfternoonOnDutyTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>上午下班签退时间为空!");
+		}
+		return null;
+	}
+
+	static Date getMorningOffdutyTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		if( StringUtils.isNotEmpty( detail.getMorningOffdutyTime()) ){
+			try {
+				logger.debug( debugger, "格式化[上午下班签退时间]morningOffdutyTime=" +  detail.getRecordDateString() + " " + detail.getMorningOffdutyTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getMorningOffdutyTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,morningOffdutyTime=" + detail.getRecordDateString() + " " + detail.getMorningOffdutyTime() );
+				logger.warn( "系统进行时间转换时发生异常,morningOffdutyTime=" + detail.getRecordDateString() + " " + detail.getMorningOffdutyTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>上午下班签退时间为空!");
+		}
+		return null;
+	}
+
+	static Date getAbsenceStartTimeFromDetail(AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger) {
+		if( StringUtils.isNotEmpty( scheduleSetting.getAbsenceStartTime() ) ){
+			try {
+				logger.debug( debugger, ">>>>>>>>>>格式化[缺勤起算时间]absenceStartTime=" +  detail.getRecordDateString() + " " + scheduleSetting.getAbsenceStartTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + scheduleSetting.getAbsenceStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getAbsenceStartTime() );
+				logger.warn( "系统进行时间转换时发生异常,absenceStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getAbsenceStartTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>上午缺勤时间设置为空!系统将不判上午缺勤情况");
+		}
+		return null;
+	}
+
+	static Date getLeaveEarlyStartTimeFromDetail(AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger) {
+		if( StringUtils.isNotEmpty( scheduleSetting.getLeaveEarlyStartTime() ) ){
+			try {
+				logger.debug( debugger, ">>>>>>>>>>格式化[早退起算时间]leaveEarlyStartTime=" +  detail.getRecordDateString() + " " + scheduleSetting.getLeaveEarlyStartTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + scheduleSetting.getLeaveEarlyStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getLeaveEarlyStartTime() );
+				logger.warn( "系统进行时间转换时发生异常,leaveEarlyStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getLeaveEarlyStartTime() );
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>早退时间设置为空!系统将不判断早退情况");
+		}
+		return null;
+	}
+
+	static Date getLateStartTimeFromDetail(AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger) {
+		if( StringUtils.isNotEmpty( scheduleSetting.getLateStartTime() ) ){
+			try {
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + scheduleSetting.getLateStartTime() );
+			} catch (Exception e) {
+				detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getLateStartTime() );
+				logger.warn( "系统进行时间转换时发生异常,lateStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getLateStartTime());
+				logger.error(e);
+			}
+		}else{
+			logger.debug( debugger, ">>>>>>>>>>迟到时间设置为空!系统将不判断迟到情况");
+		}
+		return null;
+	}
+
+
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的上午下班(中午休息开始)打卡时间
+	 * @param detail
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 */
+	static Date getMiddleRestStartTimeFromDetail(AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "middleRestEndTime " );
+			}else{
+				if( scheduleSetting.getMiddayRestStartTime() != null ){
+					logger.debug(debugger, "middleRestStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestStartTime());
+					return dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestStartTime());
+				}
+			}
+		} catch (Exception e) {
+			detail.setDescription(detail.getDescription() + "; 系统进行时间转换时发生异常,middleRestStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestStartTime() + " - " + scheduleSetting.getMiddayRestEndTime());
+			logger.debug(debugger, "系统进行时间转换时发生异常,middleRestStartTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestStartTime() + " - " + scheduleSetting.getMiddayRestEndTime());
+			logger.error(e);
+		}
+		return null;
+	}
+
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的下午上班(中午休息结束)打卡时间
+	 * @param detail
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 */
+	static Date getMiddleRestEndTimeFromDetail(AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "middleRestEndTime " );
+			}else{
+				if( scheduleSetting.getMiddayRestEndTime() != null ){
+					logger.debug(debugger, "middleRestEndTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestEndTime());
+					return dateOperation.getDateFromString(detail.getRecordDateString() + " " + detail.getMiddayRestEndTime());
+				}
+			}
+		} catch (Exception e) {
+			detail.setDescription(detail.getDescription() + "; 系统进行时间转换时发生异常,middleRestEndTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestStartTime() + " - " + scheduleSetting.getMiddayRestEndTime());
+			logger.debug(debugger, "系统进行时间转换时发生异常,middleRestEndTime=" + detail.getRecordDateString() + " " + scheduleSetting.getMiddayRestStartTime() + " - " + scheduleSetting.getMiddayRestEndTime());
+			logger.error(e);
+		}
+		return null;
+	}
+
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的上班打卡时间
+	 * @param detail
+	 * @param debugger
+	 * @return
+	 */
+	static Date getOnWorkTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "onWorkTime " );
+			}else{
+				logger.debug( debugger, "onWorkTime=" +  detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+			}
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime() );
+			logger.debug( debugger, "系统进行时间转换时发生异常,onWorkTime=" + detail.getRecordDateString() + " " + detail.getOnWorkTime());
+			logger.error(e);
+		}
+		return null;
+	}
+
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的上班打卡时间
+	 * @param detail
+	 * @param debugger
+	 * @return
+	 */
+	static Date getOffWorkTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "offWorkTime为空 " );
+			}else{
+				logger.debug( debugger, "offWorkTime=" +  detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			}
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			logger.debug( debugger, "系统进行时间转换时发生异常,offWorkTime=" + detail.getRecordDateString() + " " + detail.getOffWorkTime() );
+			logger.error(e);
+		}
+		return null;
+	}
+
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的上班实际签到时间
+	 * @param detail
+	 * @param debugger
+	 * @return
+	 */
+	static Date getOnDutyTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "onDutyTime为空 " );
+			}else{
+				logger.debug( debugger, "onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+			}
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime() );
+			logger.debug( debugger, "系统进行时间转换时发生异常,onDutyTime=" + detail.getRecordDateString() + " " + detail.getOnDutyTime());
+			logger.error(e);
+		}
+		return null;
+	}
+	/**
+	 * 根据已经完善过的考勤打卡记录,获取当天的上班实际签退时间
+	 * @param detail
+	 * @param debugger
+	 * @return
+	 */
+	static Date getOffDutyTimeFromDetail(AttendanceDetail detail, Boolean debugger) {
+		try {
+			if( StringUtils.isEmpty( detail.getOnDutyTime() ) ){
+				logger.debug( debugger, "offDutyTime " );
+			}else{
+				logger.debug( debugger, "offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+				return dateOperation.getDateFromString( detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+			}
+		} catch (Exception e) {
+			detail.setDescription( detail.getDescription() + "; 系统进行时间转换时发生异常,offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime() );
+			logger.debug( debugger, "系统进行时间转换时发生异常,offDutyTime=" + detail.getRecordDateString() + " " + detail.getOffDutyTime());
+			logger.error(e);
+		}
+		return null;
+	}
+
+	/**
+	 * 分析打卡信息,为打卡数据增加缺勤天数信息,默认为0,每次递增0.5天
+	 * @param detail
+	 */
+	static void increaseAbsenceStatusForAttendanceDetail(AttendanceDetail detail) {
+		Double absence = detail.getAbsence();
+		if (absence < 1.0) {
+			detail.setAbsence( absence + 0.5 );
+		}
+	}
+
+	//
+
+	/**
+	 * 分析打卡信息,为打卡数据计算出勤天数信息,默认为1,每次递减0.5天
+	 * @param detail
+	 */
+	static void increaseAttendanceStatusForAttendanceDetail(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.List;
 import java.util.Map;
 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 org.apache.commons.lang3.StringUtils;
 
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
@@ -30,23 +35,26 @@ import com.x.base.core.project.logger.LoggerFactory;
  *
  *
  */
  */
 public class AttendanceDetailAnalyseService {
 public class AttendanceDetailAnalyseService {
-	
+
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseService.class );
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseService.class );
 	private AttendanceSelfHolidayService attendanceSelfHolidayService = new AttendanceSelfHolidayService();
 	private AttendanceSelfHolidayService attendanceSelfHolidayService = new AttendanceSelfHolidayService();
 	private AttendanceScheduleSettingService attendanceScheduleSettingService = new AttendanceScheduleSettingService();
 	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 DateOperation dateOperation = new DateOperation();
 	private UserManagerService userManagerService = new UserManagerService();
 	private UserManagerService userManagerService = new UserManagerService();
-	
+
 	/**
 	/**
-	 * 根据员工姓名,开始日期和结束日期获取日期范围内所有的打卡记录信息ID列表,从开始日期0点,到结束日期23点59分
+	 * 根据员工姓名\开始日期\结束日期查询日期范围内所有的打卡记录信息ID列表<br/>
+	 * 时间从开始日期0点,到结束日期23点59分
 	 * @param empName
 	 * @param empName
 	 * @param startDate
 	 * @param startDate
 	 * @param endDate
 	 * @param endDate
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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;
 		Business business = null;
 		List<String> ids = null;
 		List<String> ids = null;
 		String startDateString = null, endDateString = null;
 		String startDateString = null, endDateString = null;
@@ -56,113 +64,154 @@ public class AttendanceDetailAnalyseService {
 		ids = business.getAttendanceDetailFactory().getUserAnalysenessDetails( empName, startDateString, endDateString);
 		ids = business.getAttendanceDetailFactory().getUserAnalysenessDetails( empName, startDateString, endDateString);
 		return ids;
 		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;
 			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;
 			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{
 			try{
-				analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+				analyseAttendanceDetail( emc, detail, workDayConfigList, statisticalCycleMap, debugger );
 			}catch(Exception e){
 			}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.error(e);
 			}
 			}
 		}
 		}
-		logger.info( "employee attendance details by empname, startdate and end date analyse over!" );;
+
+		logger.debug( "employee attendance detail analyse over!" );
 		return true;
 		return true;
 	}
 	}
-	
+
 	/**
 	/**
 	 * 对一组的打卡信息数据进行分析
 	 * 对一组的打卡信息数据进行分析
+	 * @param emc
 	 * @param detailList
 	 * @param detailList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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() ){
 		if( detailList == null || detailList.isEmpty() ){
 			return true;
 			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;
 		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{
 			try{
-				analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );
+				analyseAttendanceDetail( emc, detail, workDayConfigList, statisticalCycleMap, debugger );
 			}catch(Exception e){
 			}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.error(e);
 			}
 			}
 		}
 		}
-		logger.info( "employee attendance detail analyse over!" );
+		logger.info( "employee attendance details by empname, startdate and end date analyse over!" );;
 		return true;
 		return true;
 	}
 	}
 
 
 	/**
 	/**
-	 * 对单条的打卡数据分析统计周期
-	 * 包装成List使用另一个方法进行操作:analyseAttendanceDetails
-	 * 
-	 * @param detail
+	 * 对单条的打卡数据进行分析
+	 * @param emc
+	 * @param detailId
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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 emc
 	 * @param detail
 	 * @param detail
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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 ){
 		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{
 		}else{
 			logger.info( "detail为空,无法继续进行分析。" );
 			logger.info( "detail为空,无法继续进行分析。" );
 		}
 		}
@@ -173,106 +222,120 @@ public class AttendanceDetailAnalyseService {
 	 * 对单条的打卡数据进行详细分析
 	 * 对单条的打卡数据进行详细分析
 	 * @param emc
 	 * @param emc
 	 * @param detail
 	 * @param detail
-	 * @param attendanceWorkDayConfigList
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param workDayConfigList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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;
 		List<String> ids_temp = null;
-		AttendanceScheduleSetting attendanceScheduleSetting = null;
-		List<AttendanceSelfHoliday> attendanceSelfHolidayList = null;
+		AttendanceScheduleSetting scheduleSetting = null;
+		List<AttendanceSelfHoliday> selfHolidayList = null;
 		if( detail != null ){
 		if( detail != null ){
 			try{
 			try{
+				//查询员工休假记录
 				ids_temp = attendanceSelfHolidayService.getByPersonName( emc, detail.getEmpName() );
 				ids_temp = attendanceSelfHolidayService.getByPersonName( emc, detail.getEmpName() );
 				if( ids_temp != null && !ids_temp.isEmpty() ) {
 				if( ids_temp != null && !ids_temp.isEmpty() ) {
-					attendanceSelfHolidayList = attendanceSelfHolidayService.list( emc, ids_temp );
+					selfHolidayList = attendanceSelfHolidayService.list( emc, ids_temp );
 				}
 				}
 			}catch( Exception e ){
 			}catch( Exception e ){
 				logger.warn( "system list attendance self holiday info ids with employee name got an exception.empname:" + detail.getEmpName() );
 				logger.warn( "system list attendance self holiday info ids with employee name got an exception.empname:" + detail.getEmpName() );
 				logger.error(e);
 				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{
 		}else{
 			logger.warn( "attendance detail is null, system can not analyse." );
 			logger.warn( "attendance detail is null, system can not analyse." );
 		}
 		}
 		return false;
 		return false;
 	}
 	}
-	
+
 	/**
 	/**
 	 * 对单条的打卡数据进行详细分析
 	 * 对单条的打卡数据进行详细分析
 	 * @param emc
 	 * @param emc
 	 * @param detail
 	 * @param detail
-	 * @param attendanceScheduleSetting
-	 * @param attendanceSelfHolidayList
-	 * @param attendanceWorkDayConfigList
-	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param scheduleSetting
+	 * @param selfHolidayList
+	 * @param workDayConfigList
+	 * @param statisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @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{
 			Boolean debugger ) throws Exception{
+
 		if( detail != null ){
 		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;
 			Boolean check = true;
-			Date recordDate = null;
-			
-			if( attendanceScheduleSetting == null ){
+
+
+			if( scheduleSetting == null ){
 				check = false;
 				check = false;
 				saveAnalyseResultAndStatus( emc, detail.getId(), -1, "未查询到员工[" + detail.getEmpName() + "]所在组织的排班信息" );
 				saveAnalyseResultAndStatus( emc, detail.getId(), -1, "未查询到员工[" + detail.getEmpName() + "]所在组织的排班信息" );
 			}
 			}
-			
+
+			//初始化考勤打卡记录
 			if( check ){
 			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{
 					try{
+						//把日期字符串转换为日期对象,便于比较计算
 						recordDate = dateOperation.getDateFromString( detail.getRecordDateString());
 						recordDate = dateOperation.getDateFromString( detail.getRecordDateString());
 					}catch(Exception e){
 					}catch(Exception e){
 						saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性recordDate,日期recordDateString:" + detail.getRecordDateString() );
 						saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性recordDate,日期recordDateString:" + detail.getRecordDateString() );
 						check = false;
 						check = false;
 					}
 					}
+					if( recordDate != null ){ detail.setRecordDate( recordDate ); }
 				}else{
 				}else{
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性为空" );
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统格式化记录的打卡日期发生异常,未能设置日期格式的打卡时间属性为空" );
 					check = false;
 					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( 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 {
 					}else {
 						detail.setUnitName( userManagerService.getUnitNameWithPersonName( detail.getEmpName() ) );
 						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 ){
 			if( check ){
 				try{
 				try{
-					setSelfHolidays( detail, attendanceSelfHolidayList, dateOperation, debugger );
+					composeSelfHolidaysForAttendanceDetail( detail, selfHolidayList, dateOperation, debugger );
 				}catch( Exception e ){
 				}catch( Exception e ){
 					check = false;
 					check = false;
 					logger.warn( "system analyse employee self holiday for detail got an exception." + detail.getEmpName() );
 					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, "系统在根据打卡信息,请假信息分析员工请假情况时发生异常" );
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在根据打卡信息,请假信息分析员工请假情况时发生异常" );
 				}
 				}
 			}
 			}
+
 			if( check ){
 			if( check ){
 				try{
 				try{
 					detail.setIsWeekend( dateOperation.isWeekend( detail.getRecordDate() ));
 					detail.setIsWeekend( dateOperation.isWeekend( detail.getRecordDate() ));
@@ -290,9 +354,10 @@ public class AttendanceDetailAnalyseService {
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是周末时发生异常, recordDate:" + detail.getRecordDateString() );
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是周末时发生异常, recordDate:" + detail.getRecordDateString() );
 				}
 				}
 			}
 			}
+
 			if( check ){
 			if( check ){
 				try{
 				try{
-					detail.setIsHoliday( isHoliday( detail, attendanceWorkDayConfigList, dateOperation ) );
+					detail.setIsHoliday( isHoliday( detail, workDayConfigList, dateOperation ) );
 				}catch( Exception e ){
 				}catch( Exception e ){
 					check = false;
 					check = false;
 					logger.warn( "system analyse record date may be holiday got an exception." + detail.getRecordDateString() );
 					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() );
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是节假日时发生异常, recordDate:"+ detail.getRecordDateString() );
 				}
 				}
 			}
 			}
+
 			if( check ){
 			if( check ){
 				try{
 				try{
-					detail.setIsWorkday( isWorkday( detail, attendanceWorkDayConfigList, dateOperation ) );
+					detail.setIsWorkday( isWorkday( detail, workDayConfigList, dateOperation ) );
 				}catch( Exception e ){
 				}catch( Exception e ){
 					check = false;
 					check = false;
 					logger.warn( "system analyse record date may be workday got an exception." + detail.getRecordDateString() );
 					logger.warn( "system analyse record date may be workday got an exception." + detail.getRecordDateString() );
 					logger.error(e);
 					logger.error(e);
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是工作日时发生异常" );
 					saveAnalyseResultAndStatus( emc, detail.getId(), -1, "系统在分析打卡日期是否是工作日时发生异常" );
 				}
 				}
-			}	
+			}
+
 			if( check ){
 			if( check ){
 				try{
 				try{
-					analyseAttendanceDetailStatisticCycle( detail, topUnitAttendanceStatisticalCycleMap, debugger );
+					composeStatisticCycleForAttendanceDetail( detail, statisticalCycleMap, debugger );
 				}catch( Exception e ){
 				}catch( Exception e ){
 					check = false;
 					check = false;
 					logger.warn( "system analyse detail statistic cycle got an exception." + detail.getEmpName() );
 					logger.warn( "system analyse detail statistic cycle got an exception." + detail.getEmpName() );
@@ -322,7 +389,8 @@ public class AttendanceDetailAnalyseService {
 			}
 			}
 			if( check ){
 			if( check ){
 				try{
 				try{
-					analyseAttendanceDetail( detail, attendanceScheduleSetting, dateOperation, debugger );
+					//使用分析核心算法进行考勤状态分析
+					detail = attendanceDetailAnalyseCoreService.analyseCore( detail, scheduleSetting, debugger );
 				}catch( Exception e ){
 				}catch( Exception e ){
 					check = false;
 					check = false;
 					logger.warn( "system analyse detail by on and off work time for advance analyse got an exception." + detail.getEmpName() );
 					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 ){
 			if( check ){
+				//保存打卡数据分析结果
 				emc.beginTransaction( AttendanceDetail.class );
 				emc.beginTransaction( AttendanceDetail.class );
 				detail.setRecordStatus( 1 );
 				detail.setRecordStatus( 1 );
 				detail.setDescription("员工打卡记录分析完成!" );
 				detail.setDescription("员工打卡记录分析完成!" );
 				emc.check( detail, CheckPersistType.all );
 				emc.check( detail, CheckPersistType.all );
 				emc.commit();
 				emc.commit();
 			}
 			}
+
 			if( check ){
 			if( check ){
 				//分析成功根据打卡数据来记录与这条数据相关的统计需求记录
 				//分析成功根据打卡数据来记录与这条数据相关的统计需求记录
 				recordStatisticRequireLog( detail, debugger );
 				recordStatisticRequireLog( detail, debugger );
@@ -347,268 +417,95 @@ public class AttendanceDetailAnalyseService {
 		}
 		}
 		return false;
 		return false;
 	}
 	}
+
 	/**
 	/**
-	 * 根据打卡数据来记录与这条数据相关的统计需求记录
+	 * 分析打卡信息,为打卡数据计算考勤周期信息
+	 *
 	 * @param detail
 	 * @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;
 		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 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{
 			}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();
 	}
 	}
 }
 }

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

@@ -3,7 +3,6 @@ package com.x.attendance.assemble.control.service;
 import com.x.attendance.entity.*;
 import com.x.attendance.entity.*;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
-
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
@@ -14,38 +13,130 @@ import java.util.Map;
  *
  *
  */
  */
 public class AttendanceDetailAnalyseServiceAdv {
 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 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()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.analyseAttendanceDetail( emc, detail, attendanceScheduleSetting, selfHolidays, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+			return detailAnalyseService.listAnalyseAttendanceDetailIds( emc, empName, startDate, endDate );
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
-	
-	public Boolean analyseAttendanceDetail( AttendanceDetail detail, List<AttendanceWorkDayConfig> attendanceWorkDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger) throws Exception {
+
+	/**
+	 * 对一组的打卡信息数据进行分析
+	 * @param detailIds
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetailWithIds( List<String> detailIds, Boolean debugger ) throws Exception{
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.analyseAttendanceDetail( emc, detail, attendanceWorkDayConfigList, topUnitAttendanceStatisticalCycleMap, debugger );	
+			return detailAnalyseService.analyseAttendanceDetailWithIds( emc, detailIds, debugger );
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
 			throw 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 detailAnalyseService.analyseAttendanceDetails( emc, detailList, debugger );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
 
 
-	public List<String> getAnalyseAttendanceDetailIds( String employeeName, Date startTime, Date endTime ) 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()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
-			return attendanceDetailAnalyseService.getAnalyseAttendanceDetailIds( emc, employeeName, startTime, endTime );	
+			return detailAnalyseService.analyseAttendanceDetails( emc, detailList, statisticalCycleMap, debugger );
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
 			throw 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;
+		}
+	}
+
+	/**
+	 * 对单条的打卡数据进行分析
+	 * @param detailId
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean analyseAttendanceDetail( String detailId, Boolean debugger ) throws Exception{
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			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()) {
 		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 ) {
 		} catch ( Exception e ) {
 			throw e;
 			throw e;
 		}
 		}

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

@@ -0,0 +1,206 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+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.Date;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 1、一天只打上下班两次卡
+ */
+class AttendanceDetailAnalyseSignProxy1 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseSignProxy1.class );
+	private DateOperation dateOperation = new DateOperation();
+
+	/**
+	 * 对打卡策略1,一天上午上班,下午下班两次打卡策略分析当前的考勤打卡记录
+	 * @param detail
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 */
+	public AttendanceDetail analyse( AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger ) throws Exception {
+		Date onDutyTime = null, offDutyTime = null;
+		Date onWorkTime = null, offWorkTime = null;
+		Date lateStartTime = null, leaveEarlyStartTime = null, absenceStartTime = null, afternoonStartTime = null;
+
+		//周末,并且未调休为工作日或者是节假日
+		Boolean isNotWorkDay = ( detail.getIsWeekend() && !detail.getIsWorkday()) || detail.getIsHoliday();
+
+		//员工请假状态
+		Boolean isSelfHoliday_FullDay = detail.getIsGetSelfHolidays() && "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Morning = detail.getIsGetSelfHolidays() && "上午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Afternoon = detail.getIsGetSelfHolidays() && "下午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday = isSelfHoliday_Afternoon || isSelfHoliday_Morning || isSelfHoliday_FullDay;
+
+		//先初始化当前打卡信息中的上下班时间要求,该要求是是根据员工所在组织排班信息获取到的
+		onWorkTime = AttendanceDetailAnalyseCoreService.getOnWorkTimeFromDetail( detail, debugger );
+		offWorkTime = AttendanceDetailAnalyseCoreService.getOffWorkTimeFromDetail( detail, debugger );
+		lateStartTime = AttendanceDetailAnalyseCoreService.getLateStartTimeFromDetail( detail, scheduleSetting, debugger );
+		leaveEarlyStartTime = AttendanceDetailAnalyseCoreService.getLeaveEarlyStartTimeFromDetail( detail, scheduleSetting, debugger );
+		absenceStartTime = AttendanceDetailAnalyseCoreService.getAbsenceStartTimeFromDetail( detail, scheduleSetting, debugger );
+		afternoonStartTime = AttendanceDetailAnalyseCoreService.getMiddleRestEndTimeFromDetail( detail, scheduleSetting, debugger );
+
+		if ( onWorkTime != null && offWorkTime != null ) {
+			logger.debug( debugger, "上下班排班信息获取正常:onWorkTime=" +  onWorkTime + ", offWorkTime="+offWorkTime );
+			onDutyTime = AttendanceDetailAnalyseCoreService.getOnDutyTimeFromDetail( detail, debugger );
+			offDutyTime = AttendanceDetailAnalyseCoreService.getOffDutyTimeFromDetail( detail, debugger );
+
+			//规则:如果员工没有签到并且没有签退,一条打卡时间都没有,那么可能会是算缺勤的
+			if ( onDutyTime == null && offDutyTime == null ) {
+				//如果员工已经全天请假了,则不算缺勤,考勤结果正常
+				if( isSelfHoliday_FullDay || isNotWorkDay ){
+					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{
+				detail.setAttendance( 1.0 );//默认为全天出勤了
+				detail.setIsAbsent( false );//默认为未缺勤
+				detail.setAbsence( 0.0 );//默认为未缺勤
+
+				//上午如果员工已经签到
+				if( onDutyTime != null ){
+
+					logger.debug( debugger, "上午打过卡,时间:onDutyTime=" + onDutyTime );
+
+					//缺勤起算时间:absenceStartTimes可以不配置,如果不配置,则为null,则不会在为打卡时间过晚而导致缺勤
+					//上午签到过了,如果排班设置里已经配置过了缺勤起算时间,那么判断员工是否已经缺勤,如果未休假,则视为缺勤半天
+					if( absenceStartTime != null && onDutyTime.after( absenceStartTime )){
+						logger.debug( debugger, "上午打卡时间晚于缺勤计时时间:" + absenceStartTime );
+						//判断员工是否已经请假过了
+						if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假不计出勤,但请过假了不算缺勤" );
+							detail.setIsAbsent( false );
+							detail.setAbsence(0.0);
+						}else{
+							logger.debug( debugger, "没请假,缺勤半天" );
+							detail.setAbsentDayTime("上午");
+							detail.setIsAbsent( true );
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);//递增缺勤天数 + 0.5
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);//递减出勤天数 - 0.5
+						}
+					}else if( lateStartTime != null && onDutyTime.after( lateStartTime )){
+						//上午签到过了,并没有超过缺勤起算时间,如果排班设置里已经配置过了迟到起算时间,那么判断员工是否已经迟到,如果未休假也不是周末的话
+						logger.debug( debugger, "上午打卡时间晚于迟到计时时间......" );
+						if( isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请过假了不算迟到" );
+							detail.setLateTimeDuration( 0L ); //请假了不算迟到
+							detail.setIsLate( false );//请假了不算迟到
+						}else{
+							//迟到计算从上班时间开始计算,不是迟到起算时间
+							long minutes = dateOperation.getMinutes( onWorkTime, onDutyTime );
+							detail.setLateTimeDuration( minutes );//没请假算迟到时长
+							detail.setIsLate( true );//没请假算迟到
+							logger.debug( debugger, "计迟到一次,迟到时长:minutes=" + minutes );
+						}
+
+					}
+				}else{
+					logger.debug( debugger, "员工上午缺卡" );
+					if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+						logger.debug( debugger, "请假不计考勤,不需要打卡,不算异常" );
+						detail.setIsAbsent( false );
+						detail.setAbnormalDutyDayTime("无");
+						detail.setIsAbnormalDuty( false );
+					}else{
+						logger.debug(debugger, "没打卡,没请假,工作日,算缺勤。");
+						detail.setAbnormalDutyDayTime("上午");
+						detail.setIsAbnormalDuty(true);
+						detail.setAbsentDayTime("上午");
+						detail.setIsAbsent(true);
+						AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+						AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+					}
+					logger.debug( debugger, "上午工作时长, 未打卡:minutes= 0 分钟。" );
+					detail.setWorkTimeDuration( 0L );
+				}
+
+				//如果下午员工已经签退
+				if( offDutyTime != null ){
+					long minutes = 0L;
+					logger.debug( debugger, "早退计时时间:leaveEarlyStartTime=" + leaveEarlyStartTime );
+					if( leaveEarlyStartTime != null && offDutyTime.before( leaveEarlyStartTime )){
+						logger.debug( debugger, "下午打卡时间早于早退计时时间" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假、休息天不计考勤,不算出勤,不算早退" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							minutes = dateOperation.getMinutes( offDutyTime, offWorkTime );//计算早退时长
+							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
+							detail.setIsLeaveEarlier( true );
+						}
+					}
+					//下午已经签退了,现在计算全天的工作时长
+					if( afternoonStartTime != null ){ //已经配置过了下午上班时间
+						minutes = dateOperation.getMinutes( afternoonStartTime, offDutyTime);
+						logger.debug( debugger, "计算下午工作时长, 从"+ afternoonStartTime +"到" + offDutyTime + " :minutes=" + minutes + "分钟。" );
+						logger.debug( debugger, "计算全天工作时长, "+ detail.getWorkTimeDuration() +"+" + minutes + "=" + detail.getWorkTimeDuration() + minutes + "分钟。" );
+						detail.setWorkTimeDuration( detail.getWorkTimeDuration() + minutes );//记录上午的工作时长 + 下午工作时长
+					}else{
+						minutes = dateOperation.getMinutes( onDutyTime, offDutyTime);
+						detail.setWorkTimeDuration( minutes );//记录上午的工作时长 + 下午工作时长
+						logger.debug( debugger, "直接计算全天工作时长, 从"+ onDutyTime +"到" + offDutyTime + " :minutes=" + minutes + "分钟。" );
+					}
+				}else{
+					//员工未签退:有两种情况,还没有到打卡时间,或者说没有打卡
+					//如果打卡是今天,但是今天还没有结束
+					if( detail.getRecordDateString().equals( dateOperation.getNowDate() )) {
+//						detail.setAbnormalDutyDayTime("无");
+//						detail.setIsAbnormalDuty(false);
+						logger.debug( debugger, "今天还未结束,先不分析结果。" );
+					}else {
+						logger.debug( debugger, "员工下午未打卡,属于异常状态,缺卡" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假或者非工作日不计考勤,不需要打卡,不算异常状态" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							if(StringUtils.isNotEmpty( detail.getAbnormalDutyDayTime() )){
+								detail.setAbnormalDutyDayTime("上午|下午");
+							}else {
+								detail.setAbnormalDutyDayTime("下午");
+							}
+							if(StringUtils.isNotEmpty( detail.getAbsentDayTime() )){
+								detail.setAbsentDayTime("全天");
+							}else{
+								detail.setAbsentDayTime("下午");
+							}
+							detail.setIsAbnormalDuty(true);
+							detail.setIsAbsent(true);
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+							logger.debug( debugger, "没请假,未打卡,算缺卡和缺勤状态。" );
+						}
+
+						//员工未签退,计算全天的工作时长,下午的时长不计算
+//						detail.setWorkTimeDuration( 0L );
+						logger.debug( debugger, "员工未签退,全天工作时长暂时记为0分钟,等待补卡或者补提请假申请。" );
+					}
+				}
+			}
+			detail.setRecordStatus( 1 );
+		}else{
+			logger.warn( "上下班排班信未正确配置,无法正常分析考勤记录:onWorkTime=" +  onWorkTime + ", offWorkTime="+offWorkTime );
+		}
+		return detail;
+	}
+}

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

@@ -0,0 +1,247 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+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.Date;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 2、一天三次打卡:打上班,下班两次卡外,中午休息时间也需要打一次卡,以确保员工在公司活动
+ *
+ */
+class AttendanceDetailAnalyseSignProxy2 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseSignProxy2.class );
+	private DateOperation dateOperation = new DateOperation();
+
+	/**
+	 * 对打卡策略1,一天上午上班,下午下班两次打卡策略分析当前的考勤打卡记录
+	 * @param detail
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 */
+	public AttendanceDetail analyse( AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger ) throws Exception {
+		Date onWorkTime = null, offWorkTime = null;
+		Date onDutyTime = null, offDutyTime = null, middleDutyTime = null;
+		Date lateStartTime = null, leaveEarlyStartTime = null, absenceStartTime = null, morningEndTime = null, afternoonStartTime = null;
+
+		//周末,并且未调休为工作日或者是节假日
+		Boolean isNotWorkDay = ( detail.getIsWeekend() && !detail.getIsWorkday()) || detail.getIsHoliday();
+
+		//员工请假状态
+		Boolean isSelfHoliday_FullDay = detail.getIsGetSelfHolidays() && "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Morning = detail.getIsGetSelfHolidays() && "上午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Afternoon = detail.getIsGetSelfHolidays() && "下午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday = isSelfHoliday_Afternoon || isSelfHoliday_Morning || isSelfHoliday_FullDay;
+
+		//先初始化当前打卡信息中的上下班时间要求,该要求是是根据员工所在组织排班信息获取到的
+		onWorkTime = AttendanceDetailAnalyseCoreService.getOnWorkTimeFromDetail( detail, debugger );
+		offWorkTime = AttendanceDetailAnalyseCoreService.getOffWorkTimeFromDetail( detail, debugger );
+		middleDutyTime = AttendanceDetailAnalyseCoreService.getMorningOffdutyTimeFromDetail( detail, debugger );
+
+		lateStartTime = AttendanceDetailAnalyseCoreService.getLateStartTimeFromDetail( detail, scheduleSetting, debugger );
+		leaveEarlyStartTime = AttendanceDetailAnalyseCoreService.getLeaveEarlyStartTimeFromDetail( detail, scheduleSetting, debugger );
+		absenceStartTime = AttendanceDetailAnalyseCoreService.getAbsenceStartTimeFromDetail( detail, scheduleSetting, debugger );
+		morningEndTime = AttendanceDetailAnalyseCoreService.getMiddleRestStartTimeFromDetail( detail, scheduleSetting, debugger );
+		afternoonStartTime = AttendanceDetailAnalyseCoreService.getMiddleRestEndTimeFromDetail( detail, scheduleSetting, debugger );
+
+		if ( onWorkTime != null && offWorkTime != null && morningEndTime != null && afternoonStartTime != null ) {
+			logger.debug( debugger, "上下班排班信息获取正常:onWorkTime=" +  onWorkTime + ", morningEndTime="+morningEndTime + ", afternoonStartTime="+afternoonStartTime + ", offWorkTime="+offWorkTime );
+			logger.debug( debugger, "上下班签到信息获取正常:onDutyTime=" +  onDutyTime + ", middleDutyTime="+middleDutyTime + ", offDutyTime="+offDutyTime );
+
+			onDutyTime = AttendanceDetailAnalyseCoreService.getOnDutyTimeFromDetail( detail, debugger );
+			offDutyTime = AttendanceDetailAnalyseCoreService.getOffDutyTimeFromDetail( detail, debugger );
+
+			//规则:如果员工没有签到并且没有签退,一条打卡时间都没有,那么可能会是算缺勤的
+			if ( onDutyTime == null && offDutyTime == null ) {
+				//如果员工已经全天请假了,则不算缺勤,考勤结果正常
+				if( isSelfHoliday_FullDay || isNotWorkDay ){
+					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{
+				detail.setAttendance( 1.0 );//默认为全天出勤了
+				detail.setIsAbsent( false );//默认为未缺勤
+				detail.setAbsence( 0.0 );//默认为未缺勤
+
+				//=========================================================================================================
+				//=====上午  如果员工已经签到================================================================================
+				//=========================================================================================================
+				if( onDutyTime != null ){
+
+					logger.debug( debugger, "上午打过卡,时间:onDutyTime=" + onDutyTime );
+
+					//缺勤起算时间:absenceStartTimes可以不配置,如果不配置,则为null,则不会在为打卡时间过晚而导致缺勤
+					//上午签到过了,如果排班设置里已经配置过了缺勤起算时间,那么判断员工是否已经缺勤,如果未休假,则视为缺勤半天
+					if( absenceStartTime != null && onDutyTime.after( absenceStartTime )){
+						logger.debug( debugger, "上午打卡时间晚于缺勤计时时间:" + absenceStartTime );
+						//判断员工是否已经请假过了
+						if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假不计出勤,但请过假了不算缺勤" );
+							detail.setIsAbsent( false );
+							detail.setAbsence(0.0);
+						}else{
+							logger.debug( debugger, "没请假,缺勤半天" );
+							detail.setAbsentDayTime("上午");
+							detail.setIsAbsent( true );
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);//递增缺勤天数 + 0.5
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);//递减出勤天数 - 0.5
+						}
+					}else if( lateStartTime != null && onDutyTime.after( lateStartTime )){
+						//上午签到过了,并没有超过缺勤起算时间,如果排班设置里已经配置过了迟到起算时间,那么判断员工是否已经迟到,如果未休假也不是周末的话
+						logger.debug( debugger, "上午打卡时间晚于迟到计时时间......" );
+						if( isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请过假了不算迟到" );
+							detail.setLateTimeDuration( 0L ); //请假了不算迟到
+							detail.setIsLate( false );//请假了不算迟到
+						}else{
+							//迟到计算从上班时间开始计算,不是迟到起算时间
+							long minutes = dateOperation.getMinutes( onWorkTime, onDutyTime );
+							detail.setLateTimeDuration( minutes );//没请假算迟到时长
+							detail.setIsLate( true );//没请假算迟到
+							logger.debug( debugger, "计迟到一次,迟到时长:minutes=" + minutes );
+						}
+
+					}
+				}else{
+					logger.debug( debugger, "员工上午缺卡" );
+					if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+						logger.debug( debugger, "请假不计考勤,不需要打卡,不算异常" );
+						detail.setIsAbsent( false );
+						detail.setAbnormalDutyDayTime("无");
+						detail.setIsAbnormalDuty( false );
+					}else{
+						logger.debug(debugger, "没打卡,没请假,工作日,算缺勤。");
+						detail.setAbnormalDutyDayTime("上午");
+						detail.setIsAbnormalDuty(true);
+						detail.setAbsentDayTime("上午");
+						detail.setIsAbsent(true);
+						AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+						AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+					}
+					logger.debug( debugger, "上午工作时长, 未打卡:minutes= 0 分钟。" );
+					detail.setWorkTimeDuration( 0L );
+				}
+
+				//=========================================================================================================
+				//=====中午  如果员工已经签到, 中午签到只是一个记录 ,如果未签到,则记录中缺卡 ================================================================================
+				//=========================================================================================================
+				if( middleDutyTime == null ){
+					if ( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ) {
+						logger.debug(debugger, "请假不计考勤,不算出勤");
+						detail.setIsAbsent(false);
+						detail.setAbsence(0.0);
+					} else {
+						logger.debug(debugger, "没请假,中午缺卡");
+						if(StringUtils.isNotEmpty( detail.getAbnormalDutyDayTime() )){
+							detail.setAbnormalDutyDayTime("上午|中午");
+						}else {
+							detail.setAbnormalDutyDayTime("中午");
+						}
+						detail.setIsAbnormalDuty(true);
+					}
+				}
+
+				//=========================================================================================================
+				//=====下午  如果员工已经签退================================================================================
+				//=========================================================================================================
+				if( offDutyTime != null ){
+					long minutes = 0L;
+					logger.debug( debugger, "早退计时时间:leaveEarlyStartTime=" + leaveEarlyStartTime );
+					if( leaveEarlyStartTime != null && offDutyTime.before( leaveEarlyStartTime )){
+						logger.debug( debugger, "下午打卡时间早于早退计时时间" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假、休息天不计考勤,不算出勤,不算早退" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							minutes = dateOperation.getMinutes( offDutyTime, offWorkTime );//计算早退时长
+							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
+							detail.setIsLeaveEarlier( true );
+						}
+					}
+//					else if ((leaveEarlyStartTime != null && offDutyTime.after(leaveEarlyStartTime)) && offDutyTime.before(offWorkTime)) {
+//						//打卡在早退起算之后,并在下班时间之前
+//						logger.debug(debugger, "下午打卡时间晚于早退计时时间早于下班时间......");
+//						if ( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ) {
+//							logger.debug(debugger, "请假不计考勤,出勤只算半天,但请过假了不算早退");
+//							detail.setLeaveEarlierTimeDuration(0L);
+//							detail.setIsLeaveEarlier(false);
+//						} else {
+//							minutes = dateOperation.getMinutes(offDutyTime, offWorkTime);//计算早退时长
+//							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
+//							detail.setIsLeaveEarlier(true);
+//						}
+//					}
+					//下午已经签退了,现在计算全天的工作时长
+					if( afternoonStartTime != null ){ //已经配置过了下午上班时间
+						minutes = dateOperation.getMinutes( afternoonStartTime, offDutyTime);
+						logger.debug( debugger, "计算下午工作时长, 从"+ afternoonStartTime +"到" + offDutyTime + " :minutes=" + minutes + "分钟。" );
+						logger.debug( debugger, "直接计算全天工作时长, "+ detail.getWorkTimeDuration() +"+" + minutes + "=" + detail.getWorkTimeDuration() + minutes + "分钟。" );
+						detail.setWorkTimeDuration( detail.getWorkTimeDuration() + minutes );//记录上午的工作时长 + 下午工作时长
+					}else{
+						minutes = dateOperation.getMinutes( onDutyTime, offDutyTime);
+						logger.debug( debugger, "直接计算全天工作时长, 从"+ onDutyTime +"到" + offDutyTime + " :minutes=" + minutes + "分钟。" );
+					}
+				}else{
+					//员工未签退:有两种情况,还没有到打卡时间,或者说没有打卡
+					//如果打卡是今天,但是今天还没有结束
+					if( detail.getRecordDateString().equals( dateOperation.getNowDate() )) {
+//						detail.setAbnormalDutyDayTime("无");
+//						detail.setIsAbnormalDuty(false);
+						logger.debug( debugger, "今天还未结束,先不分析结果。" );
+					}else {
+						logger.debug( debugger, "员工下午未打卡,属于异常状态,缺卡" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假或者非工作日不计考勤,不需要打卡,不算异常状态" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							if(StringUtils.isNotEmpty( detail.getAbnormalDutyDayTime() )){
+								detail.setAbnormalDutyDayTime("上午|下午");
+							}else {
+								detail.setAbnormalDutyDayTime("下午");
+							}
+							if(StringUtils.isNotEmpty( detail.getAbsentDayTime() )){
+								detail.setAbsentDayTime("全天");
+							}else{
+								detail.setAbsentDayTime("下午");
+							}
+							detail.setIsAbnormalDuty(true);
+							detail.setIsAbsent(true);
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+							logger.debug( debugger, "没请假,未打卡,算缺卡和缺勤状态。" );
+						}
+
+						//员工未签退,计算全天的工作时长,下午的时长不计算
+						detail.setWorkTimeDuration( 0L );
+						logger.debug( debugger, "员工未签退,全天工作时长暂时记为0分钟,等待补卡或者补提请假申请。" );
+					}
+				}
+			}
+			detail.setRecordStatus( 1 );
+		}else{
+			logger.warn( "上下班排班信未正确配置,无法正常分析考勤记录:onWorkTime=" +  onWorkTime + ", morningEndTime="+morningEndTime + ", afternoonStartTime="+afternoonStartTime + ", offWorkTime="+offWorkTime );
+		}
+		return detail;
+	}
+}

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

@@ -0,0 +1,285 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+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.Date;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 2、一天三次打卡:打上班,下班两次卡外,中午休息时间也需要打一次卡,以确保员工在公司活动
+ *
+ */
+class AttendanceDetailAnalyseSignProxy3 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailAnalyseSignProxy3.class );
+	private DateOperation dateOperation = new DateOperation();
+
+	/**
+	 * 3、一天四次打卡:打上午上班,上午下班,下午上班,下午下班四次卡
+	 * @param detail
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 */
+	public AttendanceDetail analyse( AttendanceDetail detail, AttendanceScheduleSetting scheduleSetting, Boolean debugger ) throws Exception {
+		Date onWorkTime = null, offWorkTime = null;
+		Date onDutyTime = null, offDutyTime = null, morningOffdutyTime = null, afternoonOndutyTime = null;
+		Date lateStartTime = null, leaveEarlyStartTime = null, absenceStartTime = null, morningEndTime = null, afternoonStartTime = null;
+
+		//周末,并且未调休为工作日或者是节假日
+		Boolean isNotWorkDay = ( detail.getIsWeekend() && !detail.getIsWorkday()) || detail.getIsHoliday();
+
+		//员工请假状态
+		Boolean isSelfHoliday_FullDay = detail.getIsGetSelfHolidays() && "全天".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Morning = detail.getIsGetSelfHolidays() && "上午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday_Afternoon = detail.getIsGetSelfHolidays() && "下午".equalsIgnoreCase( detail.getSelfHolidayDayTime() );
+		Boolean isSelfHoliday = isSelfHoliday_Afternoon || isSelfHoliday_Morning || isSelfHoliday_FullDay;
+
+		//先初始化当前打卡信息中的上下班时间要求,该要求是是根据员工所在组织排班信息获取到的
+		onWorkTime = AttendanceDetailAnalyseCoreService.getOnWorkTimeFromDetail( detail, debugger );
+		offWorkTime = AttendanceDetailAnalyseCoreService.getOffWorkTimeFromDetail( detail, debugger );
+		onDutyTime = AttendanceDetailAnalyseCoreService.getOnDutyTimeFromDetail( detail, debugger );
+		offDutyTime = AttendanceDetailAnalyseCoreService.getOffDutyTimeFromDetail( detail, debugger );
+		morningOffdutyTime = AttendanceDetailAnalyseCoreService.getMorningOffdutyTimeFromDetail( detail, debugger );
+		afternoonOndutyTime = AttendanceDetailAnalyseCoreService.getAfternoonOndutyTimeFromDetail( detail, debugger );
+
+		lateStartTime = AttendanceDetailAnalyseCoreService.getLateStartTimeFromDetail( detail, scheduleSetting, debugger );
+		leaveEarlyStartTime = AttendanceDetailAnalyseCoreService.getLeaveEarlyStartTimeFromDetail( detail, scheduleSetting, debugger );
+		absenceStartTime = AttendanceDetailAnalyseCoreService.getAbsenceStartTimeFromDetail( detail, scheduleSetting, debugger );
+		morningEndTime = AttendanceDetailAnalyseCoreService.getMiddleRestStartTimeFromDetail( detail, scheduleSetting, debugger );
+		afternoonStartTime = AttendanceDetailAnalyseCoreService.getMiddleRestEndTimeFromDetail( detail, scheduleSetting, debugger );
+
+
+		if ( onWorkTime != null && offWorkTime != null && morningEndTime != null && afternoonStartTime != null ) {
+			logger.debug( debugger, "上下班排班信息获取正常:onWorkTime=" +  onWorkTime + ", morningEndTime="+morningEndTime + ", afternoonStartTime="+afternoonStartTime + ", offWorkTime="+offWorkTime );
+			logger.debug( debugger, "上下班签到信息获取正常:onDutyTime=" +  onDutyTime + ", morningOffdutyTime="+morningOffdutyTime + ", afternoonOndutyTime="+afternoonOndutyTime + ", offDutyTime="+offDutyTime );
+
+			//规则:如果员工没有签到并且没有签退,一条打卡时间都没有,那么可能会是算缺勤的
+			if ( onDutyTime == null && offDutyTime == null ) {
+				//如果员工已经全天请假了,则不算缺勤,考勤结果正常
+				if( isSelfHoliday_FullDay || isNotWorkDay ){
+					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{
+				detail.setAttendance( 1.0 );//默认为全天出勤了
+				detail.setIsAbsent( false );//默认为未缺勤
+				detail.setAbsence( 0.0 );//默认为未缺勤
+
+				//=========================================================================================================
+				//=====上午  如果员工已经签到================================================================================
+				//=========================================================================================================
+				if( onDutyTime != null ){
+					logger.debug( debugger, "上午打过卡,时间:onDutyTime=" + onDutyTime );
+					//缺勤起算时间:absenceStartTimes可以不配置,如果不配置,则为null,则不会在为打卡时间过晚而导致缺勤
+					//上午签到过了,如果排班设置里已经配置过了缺勤起算时间,那么判断员工是否已经缺勤,如果未休假,则视为缺勤半天
+					if( absenceStartTime != null && onDutyTime.after( absenceStartTime )){
+						logger.debug( debugger, "上午打卡时间晚于缺勤计时时间:" + absenceStartTime );
+						//判断员工是否已经请假过了
+						if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假不计出勤,但请过假了不算缺勤" );
+							detail.setIsAbsent( false );
+							detail.setAbsence(0.0);
+						}else{
+							logger.debug( debugger, "没请假,缺勤半天" );
+							detail.setAbsentDayTime("上午");
+							detail.setIsAbsent( true );
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);//递增缺勤天数 + 0.5
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);//递减出勤天数 - 0.5
+						}
+					}else if( lateStartTime != null && onDutyTime.after( lateStartTime )){
+						//上午签到过了,并没有超过缺勤起算时间,如果排班设置里已经配置过了迟到起算时间,那么判断员工是否已经迟到,如果未休假也不是周末的话
+						logger.debug( debugger, "上午打卡时间晚于迟到计时时间......" );
+						if( isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请过假了不算迟到" );
+							detail.setLateTimeDuration( 0L ); //请假了不算迟到
+							detail.setIsLate( false );//请假了不算迟到
+						}else{
+							//迟到计算从上班时间开始计算,不是迟到起算时间
+							long minutes = dateOperation.getMinutes( onWorkTime, onDutyTime );
+							detail.setLateTimeDuration( minutes );//没请假算迟到时长
+							detail.setIsLate( true );//没请假算迟到
+							logger.debug( debugger, "计迟到一次,迟到时长:minutes=" + minutes );
+						}
+
+					}
+				}else{
+					logger.debug( debugger, "员工上午缺卡" );
+					if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+						logger.debug( debugger, "请假不计考勤,不需要打卡,不算异常" );
+						detail.setIsAbsent( false );
+						detail.setAbnormalDutyDayTime("无");
+						detail.setIsAbnormalDuty( false );
+					}else{
+						logger.debug(debugger, "没打卡,没请假,工作日,算缺勤。");
+						detail.setAbnormalDutyDayTime("上午");
+						detail.setIsAbnormalDuty(true);
+						detail.setAbsentDayTime("上午");
+						detail.setIsAbsent(true);
+						AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+						AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+					}
+					logger.debug( debugger, "上午工作时长, 未打卡:minutes= 0 分钟。" );
+					detail.setWorkTimeDuration( 0L );
+				}
+
+				//=========================================================================================================
+				//=====上午  如果员工已经签退 morningOffdutyTime================================================================================
+				//=========================================================================================================
+				if( morningOffdutyTime != null ){//打卡签退,上午不判断是否早退
+					long minutes = 0L;
+					//上午已经签退了,现在计算上午的工作时长
+					minutes = dateOperation.getMinutes( onDutyTime, morningOffdutyTime);
+					detail.setWorkTimeDuration( minutes );
+					logger.debug( debugger, "直接计算上午工作时长, 从"+ onDutyTime +"到" + morningOffdutyTime + " :minutes=" + minutes + "分钟。" );
+				}else{
+					//看看时间是否已经到了下午上班时间
+					if( new Date().before(afternoonStartTime )){
+						logger.debug( debugger, "上午还未结束,先不分析结果。" );
+					}else{
+						logger.debug( debugger, "员工上午未签退,属于异常状态,缺卡" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假或者非工作日不计考勤,不需要打卡,不算异常状态" );
+//							detail.setLeaveEarlierTimeDuration( 0L );
+//							detail.setIsLeaveEarlier( false );
+						}else{
+							detail.setAbnormalDutyDayTime("上午");
+							detail.setAbsentDayTime("上午");
+							detail.setIsAbnormalDuty(true);
+							detail.setIsAbsent(true);
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+							logger.debug( debugger, "没请假,未打卡,算缺卡和缺勤状态。" );
+						}
+						//员工未签退,计算全天的工作时长,下午的时长不计算
+						detail.setWorkTimeDuration( 0L );
+						logger.debug( debugger, "员工未签退,上午工作时长暂时记为0分钟,等待补卡或者补提请假申请。" );
+					}
+				}
+
+				//=========================================================================================================
+				//=====下午  如果员工已经签退 afternoonOndutyTime================================================================================
+				//=========================================================================================================
+				if( afternoonOndutyTime != null ){
+					logger.debug( debugger, "下午打卡签到,时间:afternoonOndutyTime=" + afternoonOndutyTime );
+				}else{
+					if( new Date().after( afternoonStartTime )){
+						logger.debug( debugger, "员工下午上班缺卡" );
+						if(  isSelfHoliday_Morning || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假不计考勤,不需要打卡,不算异常" );
+//							detail.setIsAbsent( false );
+//							detail.setAbnormalDutyDayTime("无");
+//							detail.setIsAbnormalDuty( false );
+						}else{
+							logger.debug(debugger, "没打卡,没请假,工作日,算缺勤。");
+							detail.setAbnormalDutyDayTime("下午");
+							detail.setIsAbnormalDuty(true);
+							detail.setAbsentDayTime("下午");
+							detail.setIsAbsent(true);
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+						}
+						logger.debug( debugger, "下午工作时长, 未打卡:minutes= 0 分钟。" );
+//						detail.setWorkTimeDuration( 0L );
+					}
+				}
+
+				//=========================================================================================================
+				//=====下午  如果员工已经签退================================================================================
+				//=========================================================================================================
+				if( offDutyTime != null ){
+					long minutes = 0L;
+					logger.debug( debugger, "早退计时时间:leaveEarlyStartTime=" + leaveEarlyStartTime );
+					if( leaveEarlyStartTime != null && offDutyTime.before( leaveEarlyStartTime )){
+						logger.debug( debugger, "下午打卡时间早于早退计时时间" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假、休息天不计考勤,不算出勤,不算早退" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							minutes = dateOperation.getMinutes( offDutyTime, offWorkTime );//计算早退时长
+							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
+							detail.setIsLeaveEarlier( true );
+						}
+					}
+//					else if ((leaveEarlyStartTime != null && offDutyTime.after(leaveEarlyStartTime)) && offDutyTime.before(offWorkTime)) {
+//						//打卡在早退起算之后,并在下班时间之前
+//						logger.debug(debugger, "下午打卡时间晚于早退计时时间早于下班时间......");
+//						if ( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ) {
+//							logger.debug(debugger, "请假不计考勤,出勤只算半天,但请过假了不算早退");
+//							detail.setLeaveEarlierTimeDuration(0L);
+//							detail.setIsLeaveEarlier(false);
+//						} else {
+//							minutes = dateOperation.getMinutes(offDutyTime, offWorkTime);//计算早退时长
+//							detail.setLeaveEarlierTimeDuration(minutes); //早退时长
+//							detail.setIsLeaveEarlier(true);
+//						}
+//					}
+					//下午已经签退了,现在计算全天的工作时长
+					if( afternoonStartTime != null ){ //已经配置过了下午上班时间
+						minutes = dateOperation.getMinutes( afternoonStartTime, offDutyTime);
+						logger.debug( debugger, "计算下午工作时长, 从"+ afternoonStartTime +"到" + offDutyTime + " :minutes=" + minutes + "分钟。" );
+						logger.debug( debugger, "直接计算全天工作时长, "+ detail.getWorkTimeDuration() +"+" + minutes + "=" + detail.getWorkTimeDuration() + minutes + "分钟。" );
+						detail.setWorkTimeDuration( detail.getWorkTimeDuration() + minutes );//记录上午的工作时长 + 下午工作时长
+					}
+				}else{
+					//员工未签退:有两种情况,还没有到打卡时间,或者说没有打卡
+					//如果打卡是今天,但是今天还没有结束
+					if( detail.getRecordDateString().equals( dateOperation.getNowDate() )) {
+						detail.setAbnormalDutyDayTime("无");
+						detail.setIsAbnormalDuty(false);
+						logger.debug( debugger, "今天还未结束,先不分析结果。" );
+					}else {
+						logger.debug( debugger, "员工下午未打卡,属于异常状态,缺卡" );
+						if( isSelfHoliday_Afternoon || isSelfHoliday_Afternoon || isNotWorkDay ){
+							logger.debug( debugger, "请假或者非工作日不计考勤,不需要打卡,不算异常状态" );
+							detail.setLeaveEarlierTimeDuration( 0L );
+							detail.setIsLeaveEarlier( false );
+						}else{
+							if(StringUtils.isNotEmpty( detail.getAbnormalDutyDayTime() )){
+								detail.setAbnormalDutyDayTime("上午|下午");
+							}else {
+								detail.setAbnormalDutyDayTime("下午");
+							}
+							if(StringUtils.isNotEmpty( detail.getAbsentDayTime() )){
+								detail.setAbsentDayTime("全天");
+							}else{
+								detail.setAbsentDayTime("下午");
+							}
+							detail.setIsAbnormalDuty(true);
+							detail.setIsAbsent(true);
+							AttendanceDetailAnalyseCoreService.increaseAbsenceStatusForAttendanceDetail(detail);
+							AttendanceDetailAnalyseCoreService.increaseAttendanceStatusForAttendanceDetail(detail);
+							logger.debug( debugger, "没请假,未打卡,算缺卡和缺勤状态。" );
+						}
+
+						//员工未签退,计算全天的工作时长,下午的时长不计算
+//						detail.setWorkTimeDuration( 0L );
+						logger.debug( debugger, "员工未签退,全天工作时长暂时记为0分钟,等待补卡或者补提请假申请。" );
+					}
+				}
+			}
+			detail.setRecordStatus( 1 );
+		}else{
+			logger.warn( "上下班排班信未正确配置,无法正常分析考勤记录:onWorkTime=" +  onWorkTime + ", morningEndTime="+morningEndTime + ", afternoonStartTime=" +  afternoonStartTime + ", offWorkTime="+offWorkTime );
+		}
+		return detail;
+	}
+}

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

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

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

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

@@ -36,5 +36,9 @@ public class AttendanceDetailMobileService {
 		return business.getAttendanceDetailMobileFactory().listAttendanceDetailMobileWithEmployee( distinguishedName, recordDateString );
 		return business.getAttendanceDetailMobileFactory().listAttendanceDetailMobileWithEmployee( distinguishedName, recordDateString );
 	}
 	}
 
 
-	
+
+    public List<AttendanceDetailMobile> listAttendanceDetailMobile(EntityManagerContainer emc, String distinguishedName, String signDate) throws Exception {
+		Business business =  new Business( emc );
+		return business.getAttendanceDetailMobileFactory().listAttendanceDetailMobile( distinguishedName, signDate );
+    }
 }
 }

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

@@ -4,15 +4,13 @@ import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.attendance.entity.*;
+import com.x.base.core.entity.JpaObject;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.Business;
-import com.x.attendance.entity.AttendanceDetail;
-import com.x.attendance.entity.AttendanceDetailMobile;
-import com.x.attendance.entity.AttendanceEmployeeConfig;
-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.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckPersistType;
@@ -25,9 +23,10 @@ public class AttendanceDetailServiceAdv {
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailServiceAdv.class );
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceDetailServiceAdv.class );
 	private AttendanceDetailService attendanceDetailService = new AttendanceDetailService();
 	private AttendanceDetailService attendanceDetailService = new AttendanceDetailService();
 	private AttendanceDetailMobileService attendanceDetailMobileService = new AttendanceDetailMobileService();
 	private AttendanceDetailMobileService attendanceDetailMobileService = new AttendanceDetailMobileService();
-	protected AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
-	protected AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
-	protected AttendanceStatisticalCycleServiceAdv attendanceStatisticCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
+	private AttendanceScheduleSettingService attendanceScheduleSettingService = new AttendanceScheduleSettingService();
+//	protected AttendanceDetailAnalyseServiceAdv attendanceDetailAnalyseServiceAdv = new AttendanceDetailAnalyseServiceAdv();
+//	protected AttendanceWorkDayConfigServiceAdv attendanceWorkDayConfigServiceAdv = new AttendanceWorkDayConfigServiceAdv();
+//	protected AttendanceStatisticalCycleServiceAdv attendanceStatisticCycleServiceAdv = new AttendanceStatisticalCycleServiceAdv();
 	
 	
 	public AttendanceDetail get( String id ) throws Exception {
 	public AttendanceDetail get( String id ) throws Exception {
 		if( id == null || id.isEmpty() ){
 		if( id == null || id.isEmpty() ){
@@ -213,6 +212,14 @@ public class AttendanceDetailServiceAdv {
 		}
 		}
 	}
 	}
 
 
+	public List<AttendanceDetailMobile> listAttendanceDetailMobile(String distinguishedName, String signDate) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			return attendanceDetailMobileService.listAttendanceDetailMobile( emc, distinguishedName, signDate );
+		} catch ( Exception e ) {
+			throw e;
+		}
+	}
+
 	public AttendanceDetailMobile getMobile(String id) throws Exception {
 	public AttendanceDetailMobile getMobile(String id) throws Exception {
 		if( id == null || id.isEmpty() ){
 		if( id == null || id.isEmpty() ){
 			return null;
 			return null;
@@ -224,47 +231,47 @@ public class AttendanceDetailServiceAdv {
 		}
 		}
 	}
 	}
 
 
-	public void pushToDetail(String distinguishedName, String recordDateString ) throws Exception {
+	/**
+	 * 根据所有的移动打卡记录来组织一个完整的打卡记录
+	 * @param distinguishedName
+	 * @param recordDateString
+	 * @throws Exception
+	 */
+	public void pushToDetail(String distinguishedName, String recordDateString, Boolean debugger ) throws Exception {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			List<AttendanceDetailMobile> mobileDetails = attendanceDetailMobileService.listAttendanceDetailMobileWithEmployee( emc, distinguishedName, recordDateString );
 			List<AttendanceDetailMobile> mobileDetails = attendanceDetailMobileService.listAttendanceDetailMobileWithEmployee( emc, distinguishedName, recordDateString );
 			if( ListTools.isNotEmpty( mobileDetails )) {
 			if( ListTools.isNotEmpty( mobileDetails )) {
-				AttendanceDetailMobile mobileDetail = mobileDetails.get( 0 );
-				String onDutyTime = getOnDutyTime( mobileDetails );
-				String offDutyTime = getOffDutyTime( mobileDetails );
-				
-				AttendanceDetail detail = attendanceDetailService.listDetailWithEmployee( emc, distinguishedName, recordDateString );
-				if( detail == null ) {
-					detail = new AttendanceDetail();
-					detail.setEmpNo( mobileDetail.getEmpNo() );
-					detail.setEmpName( mobileDetail.getEmpName() );
-					if( mobileDetail.getRecordDate() != null ) {
-						detail.setYearString( dateOperation.getYear( mobileDetail.getRecordDate() ) );
-						detail.setMonthString( dateOperation.getMonth( mobileDetail.getRecordDate() ) );
-					}
-					detail.setRecordDateString( mobileDetail.getRecordDateString() );
-					detail.setOnDutyTime( onDutyTime );
-					detail.setOffDutyTime( offDutyTime );
-					detail.setRecordStatus( 0 );
-					detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );	
-					
+				AttendanceDetail detail_old = attendanceDetailService.listDetailWithEmployee( emc, distinguishedName, recordDateString );
+				AttendanceDetail detail = null;
+
+				AttendanceScheduleSetting scheduleSetting = attendanceScheduleSettingService.getAttendanceScheduleSettingWithPerson( distinguishedName, debugger );
+				if( scheduleSetting == null ){
+					throw new Exception("scheduleSetting is null, empName:" + distinguishedName );
+				}
+
+				//获取打卡策略:两次,三次还是四次
+				//根据考勤打卡规则来判断启用何种规则来进行考勤结果分析
+				if( 2 == scheduleSetting.getSignProxy() ){
+					//2、一天三次打卡:打上班,下班两次卡外,中午休息时间也需要打一次卡,以确保员工在公司活动
+					detail = new ComposeDetailWithMobileInSignProxy2().compose( mobileDetails, scheduleSetting, debugger);
+				}else if( 3 == scheduleSetting.getSignProxy() ){
+					//3、一天四次打卡:打上午上班,上午下班,下午上班,下午下班四次卡
+					detail = new ComposeDetailWithMobileInSignProxy3().compose( mobileDetails, scheduleSetting, debugger);
+				}else{
+					//1、一天只打上下班两次卡
+					detail = new ComposeDetailWithMobileInSignProxy1().compose( mobileDetails, scheduleSetting, debugger);
+				}
+
+				if( detail_old == null ) {
+					detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );
 					emc.beginTransaction( AttendanceDetail.class );
 					emc.beginTransaction( AttendanceDetail.class );
 					emc.persist( detail , CheckPersistType.all );
 					emc.persist( detail , CheckPersistType.all );
 					emc.commit();
 					emc.commit();
+					detail_old = detail;
 				}else {
 				}else {
-					detail.setEmpNo( mobileDetail.getEmpNo() );
-					detail.setEmpName( mobileDetail.getEmpName() );
-					if( mobileDetail.getRecordDate() != null ) {
-						detail.setYearString( dateOperation.getYear( mobileDetail.getRecordDate() ) );
-						detail.setMonthString( dateOperation.getMonth( mobileDetail.getRecordDate() ) );
-					}
-					detail.setRecordDateString( mobileDetail.getRecordDateString() );
-					detail.setOnDutyTime( onDutyTime );
-					detail.setOffDutyTime( offDutyTime );
-					detail.setRecordStatus( 0 );
-					detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );	
-					
 					emc.beginTransaction( AttendanceDetail.class );
 					emc.beginTransaction( AttendanceDetail.class );
-					emc.check( detail , CheckPersistType.all );
+					detail.copyTo( detail_old, JpaObject.FieldsUnmodify);
+					emc.check( detail_old , CheckPersistType.all );
 					emc.commit();
 					emc.commit();
 				}
 				}
 
 
@@ -274,18 +281,12 @@ public class AttendanceDetailServiceAdv {
 					emc.check( detailMobile , CheckPersistType.all );
 					emc.check( detailMobile , CheckPersistType.all );
 				}
 				}
 				emc.commit();
 				emc.commit();
-				
-				List<AttendanceWorkDayConfig> attendanceWorkDayConfigList = null;
-				Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap = null;
+
+				//分析保存好的考勤数据
 				try {
 				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_old.getId() );
+				} catch ( Exception e1 ) {
+					e1.printStackTrace();
 				}
 				}
 			}
 			}
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
@@ -293,40 +294,5 @@ public class AttendanceDetailServiceAdv {
 		}
 		}
 	}
 	}
 
 
-	private String getOffDutyTime( List<AttendanceDetailMobile> mobileDetails ) throws Exception {
-		Date offDutyTime = null;
-		Date signTime = null;
-		String offDutyTimeString = null;
-		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
-			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
-				signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
-				if( offDutyTime != null && signTime != null && offDutyTime.before( signTime )) {
-					offDutyTime = signTime;
-					offDutyTimeString = detailMobile.getSignTime();
-				}else if( offDutyTime == null ){
-					offDutyTime = signTime;
-					offDutyTimeString = detailMobile.getSignTime();
-				}
-			}
-		}
-		return offDutyTimeString;
-	}
 
 
-	private String getOnDutyTime(List<AttendanceDetailMobile> mobileDetails) throws Exception {
-		Date onDutyTime = null;
-		Date signTime = null;
-		String onDutyTimeString = null;
-		for( AttendanceDetailMobile detailMobile : mobileDetails ) {
-			signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
-			if( onDutyTime != null && signTime != null && onDutyTime.after( signTime )) {
-				onDutyTime = signTime;
-				onDutyTimeString = detailMobile.getSignTime();
-			}else if( onDutyTime == null ){
-				onDutyTime = signTime;
-				onDutyTimeString = detailMobile.getSignTime();
-			}
-		}
-		return onDutyTimeString;
-	}
-	
 }
 }

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

@@ -130,7 +130,7 @@ public class AttendanceSettingService {
 		type = "select";
 		type = "select";
 		selectContent = AppealConfig.APPEAL_AUDIFLOWTYPE_WORKFLOW + "|" + AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN;
 		selectContent = AppealConfig.APPEAL_AUDIFLOWTYPE_WORKFLOW + "|" + AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN;
 		isMultiple = false;
 		isMultiple = false;
-		description = "考勤结果申诉审核人确定方式:可选值:"+AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN+"|"+ AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN +"。此配置控制考勤结果申诉流程为自定义流程或者内置审批步骤(审核-复核)。";
+		description = "考勤结果申诉审核人确定方式:可选值:"+AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN+"|"+ AppealConfig.APPEAL_AUDIFLOWTYPE_WORKFLOW +"。此配置控制考勤结果申诉流程为自定义流程或者内置审批步骤(审核-复核)。";
 		try {
 		try {
 			checkAndInitSystemConfig("APPEAL_AUDIFLOWTYPE", "考勤结果申诉流程类型", value, description, type, selectContent, isMultiple, ++ordernumber );
 			checkAndInitSystemConfig("APPEAL_AUDIFLOWTYPE", "考勤结果申诉流程类型", value, description, type, selectContent, isMultiple, ++ordernumber );
 		} catch (Exception e) {
 		} catch (Exception e) {
@@ -138,7 +138,7 @@ public class AttendanceSettingService {
 			logger.error(e);
 			logger.error(e);
 		}
 		}
 
 
-		value = "";
+		value = "";
 		type = "text";
 		type = "text";
 		selectContent = null;
 		selectContent = null;
 		isMultiple = false;
 		isMultiple = false;

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

@@ -42,4 +42,8 @@ public class AttendanceStatisticRequireLogServiceAdv {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
+
+    public void resetStatisticError() throws Exception {
+		attendanceStatisticRequireLogService.resetStatisticError();
+	}
 }
 }

+ 111 - 63
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.List;
 import java.util.Map;
 import java.util.Map;
 
 
+import com.x.attendance.assemble.control.ThisApplication;
 import com.x.attendance.entity.AttendanceStatisticRequireLog;
 import com.x.attendance.entity.AttendanceStatisticRequireLog;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
 import com.x.attendance.entity.AttendanceWorkDayConfig;
@@ -20,36 +21,34 @@ import com.x.base.core.project.logger.LoggerFactory;
 public class AttendanceStatisticServiceAdv {
 public class AttendanceStatisticServiceAdv {
 	
 	
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticServiceAdv.class );
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticServiceAdv.class );
-	private AttendanceWorkDayConfigService attendanceWorkDayConfigService = new AttendanceWorkDayConfigService();
+//	private AttendanceWorkDayConfigService attendanceWorkDayConfigService = new AttendanceWorkDayConfigService();
 	private AttendanceStatisticRequireLogService attendanceStatisticRequireLogService = new AttendanceStatisticRequireLogService();
 	private AttendanceStatisticRequireLogService attendanceStatisticRequireLogService = new AttendanceStatisticRequireLogService();
 	private AttendanceStatisticService attendanceStatisticService = new AttendanceStatisticService();
 	private AttendanceStatisticService attendanceStatisticService = new AttendanceStatisticService();
-	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
+//	private AttendanceStatisticalCycleService attendanceStatisticalCycleService = new AttendanceStatisticalCycleService();
 
 
 	/**
 	/**
 	 * 根据统计年份月份列表来对每个月的数据进行统计
 	 * 根据统计年份月份列表来对每个月的数据进行统计
 	 */
 	 */
 	public void doStatistic( Boolean debugger ) {
 	public void doStatistic( Boolean debugger ) {
 		logger.debug( debugger, ">>>>>>>>>>>系统正准备开始进行数据统计......" );
 		logger.debug( debugger, ">>>>>>>>>>>系统正准备开始进行数据统计......" );
-		AttendanceStatisticalCycle attendanceStatisticalCycle  = null;
-		List<AttendanceWorkDayConfig> workDayConfigList = null;
+//		AttendanceStatisticalCycle attendanceStatisticalCycle  = null;
+//		List<AttendanceWorkDayConfig> workDayConfigList = null;
 		List<AttendanceStatisticRequireLog> attendanceStatisticRequireLogList = 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 {
 		try {
@@ -78,22 +77,28 @@ public class AttendanceStatisticServiceAdv {
 		}		
 		}		
 		
 		
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
-			for( AttendanceStatisticRequireLog attendanceStatisticRequireLog : attendanceStatisticRequireLogList ){
-				logger.debug( debugger, ">>>>>>>>>>>系统准备统计[员工每月统计], 员工:" + attendanceStatisticRequireLog.getStatisticKey() + ", 统计月份:" + attendanceStatisticRequireLog.getStatisticYear() + "-" +attendanceStatisticRequireLog.getStatisticMonth() );
+			for( AttendanceStatisticRequireLog log : attendanceStatisticRequireLogList ){
+				//统计考勤数据,发送到执行队列
 				try {
 				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);
 			logger.error(e);
 		}
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
 		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);
 			logger.error(e);
 		}
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
 		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);
 			logger.error(e);
 		}
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
 		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);
 			logger.error(e);
 		}
 		}
 		if( attendanceStatisticRequireLogList != null && !attendanceStatisticRequireLogList.isEmpty() ){
 		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, ">>>>>>>>>>>系统数据统计运行完成." );
 		logger.debug( debugger, ">>>>>>>>>>>系统数据统计运行完成." );
@@ -424,5 +453,24 @@ public class AttendanceStatisticServiceAdv {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
-	
+
+    public void statisticEmployeeAttendanceForMonth(AttendanceStatisticRequireLog log, AttendanceStatisticalCycle attendanceStatisticalCycle, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap) throws Exception {
+		attendanceStatisticService.statisticEmployeeAttendanceForMonth( log, attendanceStatisticalCycle, workDayConfigList, statisticalCycleMap);
+	}
+
+	public void statisticUnitAttendanceForMonth(AttendanceStatisticRequireLog log, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap) throws Exception {
+		attendanceStatisticService.statisticUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap );
+	}
+
+	public void statisticTopUnitAttendanceForMonth(AttendanceStatisticRequireLog log, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap) throws Exception {
+		attendanceStatisticService.statisticTopUnitAttendanceForMonth( log, workDayConfigList, statisticalCycleMap);
+	}
+
+	public void statisticUnitAttendanceForDay(AttendanceStatisticRequireLog log, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap, boolean b) throws Exception {
+		attendanceStatisticService.statisticUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap, false );
+	}
+
+	public void statisticTopUnitAttendanceForDay(AttendanceStatisticRequireLog log, List<AttendanceWorkDayConfig> workDayConfigList, Map<String, Map<String, List<AttendanceStatisticalCycle>>> statisticalCycleMap) throws Exception {
+		attendanceStatisticService.statisticTopUnitAttendanceForDay( log, workDayConfigList, statisticalCycleMap );
+	}
 }
 }

+ 44 - 26
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.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckPersistType;
 import com.x.base.core.entity.annotation.CheckRemoveType;
 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.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
 
 
 public class AttendanceStatisticalCycleService {
 public class AttendanceStatisticalCycleService {
-	
+
+	private Ehcache cache_AttendanceStatisticalCycle = ApplicationCache.instance().getCache( AttendanceStatisticalCycle.class);
+
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleService.class );
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleService.class );
 	private UserManagerService userManagerService = new UserManagerService();
 	private UserManagerService userManagerService = new UserManagerService();
 	private DateOperation dateOperation = new DateOperation();
 	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 {
 	public List<AttendanceStatisticalCycle> listAll(EntityManagerContainer emc) throws Exception {
 		Business business =  new Business( emc );
 		Business business =  new Business( emc );
 		return business.getAttendanceStatisticalCycleFactory().listAll();
 		return business.getAttendanceStatisticalCycleFactory().listAll();
@@ -41,22 +63,24 @@ public class AttendanceStatisticalCycleService {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
-	
+
+
 	/**
 	/**
-	 * TODO 将所有的统计周期配置信息组织成一个大的Map
+	 * 将所有的统计周期配置信息组织成一个大的Map
 	 * @param emc
 	 * @param emc
-	 * @param cycles
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
 	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getCycleMapFormAllCycles( EntityManagerContainer emc, Boolean debugger ) throws Exception{
 	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getCycleMapFormAllCycles( EntityManagerContainer emc, Boolean debugger ) throws Exception{
 		return getCycleMapFormAllCycles( emc, listAll(emc), debugger );
 		return getCycleMapFormAllCycles( emc, listAll(emc), debugger );
 	}
 	}
-	
+
 	/**
 	/**
-	 * TODO 将指定的统计周期配置信息列表组织成一个大的Map
+	 * 将指定的统计周期配置信息列表组织成一个大的Map
 	 * @param emc
 	 * @param emc
 	 * @param cycles
 	 * @param cycles
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
@@ -87,14 +111,12 @@ public class AttendanceStatisticalCycleService {
 	}
 	}
 
 
 	/**
 	/**
-	 * TODO 根据顶层组织,组织,年月获取一个统计周期配置
-	 * 如果不存在,则新建一个周期配置
-	 * 
+	 * 根据顶层组织,组织,年月获取一个统计周期配置 如果不存在,则新建一个周期配置
 	 * @param q_topUnitName
 	 * @param q_topUnitName
 	 * @param q_unitName
 	 * @param q_unitName
-	 * @param startDate
-	 * @param endDate
+	 * @param recordDate
 	 * @param topUnitAttendanceStatisticalCycleMap
 	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
@@ -113,7 +135,7 @@ public class AttendanceStatisticalCycleService {
 		if( topUnitAttendanceStatisticalCycleMap != null ){
 		if( topUnitAttendanceStatisticalCycleMap != null ){
 			unitCycleInfoEntity = analyseStatisticCycleWithUnitName( q_topUnitName, q_unitName, topUnitAttendanceStatisticalCycleMap, debugger );
 			unitCycleInfoEntity = analyseStatisticCycleWithUnitName( q_topUnitName, q_unitName, topUnitAttendanceStatisticalCycleMap, debugger );
 		}else{
 		}else{
-			logger.debug( debugger, ">>>>>>>>>>统计周期配置为空,顶层组织为*组织为*,系统中没有任何配置");
+			logger.debug( debugger, "统计周期配置为空,顶层组织为*组织为*,系统中没有任何配置");
 			unitCycleInfoEntity = new UnitCycleInfoEntity();
 			unitCycleInfoEntity = new UnitCycleInfoEntity();
 			unitCycleInfoEntity.setTopUnitName( "*" );
 			unitCycleInfoEntity.setTopUnitName( "*" );
 			unitCycleInfoEntity.setUnitName( "*" );
 			unitCycleInfoEntity.setUnitName( "*" );
@@ -125,13 +147,13 @@ public class AttendanceStatisticalCycleService {
 				cycleStartDate = temp.getCycleStartDate();
 				cycleStartDate = temp.getCycleStartDate();
 				cycleEndDate = temp.getCycleEndDate();
 				cycleEndDate = temp.getCycleEndDate();
 				if( recordDate.getTime() >= cycleStartDate.getTime() && recordDate.getTime() <= cycleEndDate.getTime() ){
 				if( recordDate.getTime() >= cycleStartDate.getTime() && recordDate.getTime() <= cycleEndDate.getTime() ){
-					logger.debug( debugger, ">>>>>>>>>>根据时间对比获取到合适的周期:" + recordDate + "," + cycleStartDate + " ~ " + cycleEndDate);
+					logger.debug( debugger, "根据时间对比获取到合适的周期:" + recordDate + "," + cycleStartDate + " ~ " + cycleEndDate);
 					return temp;
 					return temp;
 				}
 				}
 			}
 			}
 		}
 		}
 		if( !hasConfig ){
 		if( !hasConfig ){
-			logger.debug( debugger, ">>>>>>>>>>未查询到合适的周期,根据打卡信息创建一条自然月的周期");
+			logger.debug( debugger, "未查询到合适的周期,根据打卡信息创建一条自然月的周期");
 			//说明没有找到任何相关的配置,那么新创建一条配置
 			//说明没有找到任何相关的配置,那么新创建一条配置
 			//创建并且持久化一条统计周期配置
 			//创建并且持久化一条统计周期配置
 			attendanceStatisticalCycle = createNewCycleInfo( recordDate, q_topUnitName, q_unitName );			
 			attendanceStatisticalCycle = createNewCycleInfo( recordDate, q_topUnitName, q_unitName );			
@@ -167,7 +189,7 @@ public class AttendanceStatisticalCycleService {
 		if( topUnitAttendanceStatisticalCycleMap != null ){
 		if( topUnitAttendanceStatisticalCycleMap != null ){
 			unitCycleInfoEntity = analyseStatisticCycleWithUnitName( q_topUnitName, q_unitName, topUnitAttendanceStatisticalCycleMap, debugger );
 			unitCycleInfoEntity = analyseStatisticCycleWithUnitName( q_topUnitName, q_unitName, topUnitAttendanceStatisticalCycleMap, debugger );
 		}else{
 		}else{
-			logger.debug( debugger, ">>>>>>>>>>统计周期配置为空,顶层组织为*组织为*,系统中没有任何配置");
+			logger.debug( debugger, "统计周期配置为空,顶层组织为*组织为*,系统中没有任何配置");
 			unitCycleInfoEntity = new UnitCycleInfoEntity();
 			unitCycleInfoEntity = new UnitCycleInfoEntity();
 			unitCycleInfoEntity.setTopUnitName( "*" );
 			unitCycleInfoEntity.setTopUnitName( "*" );
 			unitCycleInfoEntity.setUnitName( "*" );
 			unitCycleInfoEntity.setUnitName( "*" );
@@ -182,11 +204,11 @@ public class AttendanceStatisticalCycleService {
 				}
 				}
 			}
 			}
 		}else{
 		}else{
-			logger.debug( debugger, ">>>>>>>>>>根据顶层组织[" +topUnitName+ "]和组织["+unitName+"]未获取到任何周期数据,需要创建新的统计周期数据......");
+			logger.debug( debugger, "根据顶层组织[" +topUnitName+ "]和组织["+unitName+"]未获取到任何周期数据,需要创建新的统计周期数据......");
 		}
 		}
 		
 		
 		if( !hasConfig ){
 		if( !hasConfig ){
-			logger.debug( debugger, ">>>>>>>>>>未查询到合适的周期,根据打卡信息创建一条自然月的周期");
+			logger.debug( debugger, "未查询到合适的周期,根据打卡信息创建一条自然月的周期");
 			//说明没有找到任何相关的配置,那么新创建一条配置
 			//说明没有找到任何相关的配置,那么新创建一条配置
 			Date day = dateOperation.getDateFromString( cycleYear + "-" + cycleMonth + "-01");
 			Date day = dateOperation.getDateFromString( cycleYear + "-" + cycleMonth + "-01");
 			//创建并且持久化一条统计周期配置
 			//创建并且持久化一条统计周期配置
@@ -196,16 +218,12 @@ public class AttendanceStatisticalCycleService {
 		}
 		}
 		return null;
 		return null;
 	}
 	}
-	
+
 	/**
 	/**
-	 * 根据顶层组织,组织,年月获取一个统计周期配置
-	 * 如果不存在,则新建一个周期配置
-	 * 
-	 * @param q_topUnitName
-	 * @param q_unitName
-	 * @param cycleYear
-	 * @param cycleMonth
+	 * 根据顶层组织,组织,年月获取一个统计周期配置 如果不存在,则新建一个周期配置
+	 * @param attendanceStatisticRequireLog
 	 * @param topUnitAttendanceStatisticalCycleMap
 	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */

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

@@ -8,6 +8,7 @@ import java.util.Map;
 
 
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.assemble.common.date.DateOperation;
 import com.x.attendance.entity.AttendanceDetail;
 import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceStatisticRequireLog;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.attendance.entity.AttendanceStatisticalCycle;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
@@ -16,7 +17,7 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
 
 
 public class AttendanceStatisticalCycleServiceAdv {
 public class AttendanceStatisticalCycleServiceAdv {
-	
+
 	private AttendanceStatisticalCycleService attendanceStatisticCycleService = new AttendanceStatisticalCycleService();
 	private AttendanceStatisticalCycleService attendanceStatisticCycleService = new AttendanceStatisticalCycleService();
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleServiceAdv.class );
 	private static  Logger logger = LoggerFactory.getLogger( AttendanceStatisticalCycleServiceAdv.class );
 	private UserManagerService userManagerService = new UserManagerService();
 	private UserManagerService userManagerService = new UserManagerService();
@@ -28,12 +29,12 @@ public class AttendanceStatisticalCycleServiceAdv {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
-	
+
 	/**
 	/**
 	 * 将所有的周期配置组织成一个Map便于查询操作
 	 * 将所有的周期配置组织成一个Map便于查询操作
-	 * @param cycles
+	 * @param debugger
 	 * @return
 	 * @return
-	 * @throws Exception 
+	 * @throws Exception
 	 */
 	 */
 	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getCycleMapFormAllCycles( Boolean debugger ) throws Exception{
 	public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getCycleMapFormAllCycles( Boolean debugger ) throws Exception{
 		List<AttendanceStatisticalCycle> cycles = null;
 		List<AttendanceStatisticalCycle> cycles = null;
@@ -278,16 +279,14 @@ public class AttendanceStatisticalCycleServiceAdv {
 		}
 		}
 		return null;
 		return null;
 	}
 	}
-	
+
 	/**
 	/**
-	 * 根据顶层组织,组织,年月获取一个统计周期配置
-	 * 如果不存在,则新建一个周期配置
-	 * 
-	 * @param q_topUnitName
-	 * @param q_unitName
+	 * 根据顶层组织,组织,年月获取一个统计周期配置 如果不存在,则新建一个周期配置
+	 * @param employeeName
 	 * @param cycleYear
 	 * @param cycleYear
 	 * @param cycleMonth
 	 * @param cycleMonth
 	 * @param topUnitAttendanceStatisticalCycleMap
 	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
 	 * @return
 	 * @return
 	 * @throws Exception
 	 * @throws Exception
 	 */
 	 */
@@ -417,11 +416,12 @@ public class AttendanceStatisticalCycleServiceAdv {
 		}
 		}
 		return null;
 		return null;
 	}
 	}
-	
+
 	/**
 	/**
 	 * 将单个对象放到一个List里,并且去重复
 	 * 将单个对象放到一个List里,并且去重复
 	 * @param cycle
 	 * @param cycle
-	 * @param topUnitCycles
+	 * @param unitCycles
+	 * @param debugger
 	 * @return
 	 * @return
 	 */
 	 */
 	public List<AttendanceStatisticalCycle> putDistinctCycleInList( AttendanceStatisticalCycle cycle, List<AttendanceStatisticalCycle> unitCycles, Boolean debugger ) {
 	public List<AttendanceStatisticalCycle> putDistinctCycleInList( AttendanceStatisticalCycle cycle, List<AttendanceStatisticalCycle> unitCycles, Boolean debugger ) {
@@ -446,6 +446,22 @@ public class AttendanceStatisticalCycleServiceAdv {
 		//如果循环完了,证明不存在,要添加一个对象
 		//如果循环完了,证明不存在,要添加一个对象
 		unitCycles.add( cycle );
 		unitCycles.add( cycle );
 		return unitCycles;
 		return unitCycles;
-	}	
+	}
+
+    public Map<String, Map<String, List<AttendanceStatisticalCycle>>> getAllStatisticalCycleMapWithCache(boolean debugger) throws Exception {
+		return attendanceStatisticCycleService.getAllStatisticalCycleMapWithCache(debugger);
+    }
+
+	/**
+	 * 根据顶层组织,组织,年月获取一个统计周期配置 如果不存在,则新建一个周期配置
+	 * @param attendanceStatisticRequireLog
+	 * @param topUnitAttendanceStatisticalCycleMap
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public AttendanceStatisticalCycle getStatisticCycleByEmployee( AttendanceStatisticRequireLog attendanceStatisticRequireLog, Map<String, Map<String, List<AttendanceStatisticalCycle>>> topUnitAttendanceStatisticalCycleMap, Boolean debugger ) throws Exception{
+		return attendanceStatisticCycleService.getStatisticCycleByEmployee( attendanceStatisticRequireLog, topUnitAttendanceStatisticalCycleMap, debugger);
+	}
 }
 }
 
 

+ 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.attendance.entity.AttendanceWorkDayConfig;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.factory.EntityManagerContainerFactory;
 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 {
 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 {
 	public AttendanceWorkDayConfig get( EntityManagerContainer emc, String id ) throws Exception {
 		if( id == null || id.isEmpty() ){
 		if( id == null || id.isEmpty() ){
 			return null;
 			return null;

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

@@ -40,4 +40,8 @@ public class AttendanceWorkDayConfigServiceAdv {
 			throw e;
 			throw e;
 		}
 		}
 	}
 	}
+
+    public List<AttendanceWorkDayConfig> getAllWorkDayConfigWithCache(Boolean debugger) throws Exception {
+		return attendanceWorkDayConfigService.getAllWorkDayConfigWithCache(debugger);
+    }
 }
 }

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

@@ -0,0 +1,107 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 1、一天只打上下班两次卡
+ */
+class ComposeDetailWithMobileInSignProxy1 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( ComposeDetailWithMobileInSignProxy1.class );
+	private DateOperation dateOperation = new DateOperation();
+
+
+	/**
+	 * 组织一个完整的打卡记录
+	 * 1、上班打卡时间:最早的一次打卡就是上班打卡时间(考虑一下有没有配置中午休息时间,如果有午休时间,上班打卡需要按时间来计算)
+	 * 2、下班打卡时间:第二次以后的打卡都是下班打卡,取最晚的一次
+	 * @param mobileDetails
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public AttendanceDetail compose(List<AttendanceDetailMobile> mobileDetails, AttendanceScheduleSetting scheduleSetting, Boolean debugger) throws Exception {
+		AttendanceDetailMobile mobileDetail = mobileDetails.get( 0 );
+		String onDutyTime = getOnDutyTime( mobileDetails );
+		String offDutyTime = getOffDutyTime( mobileDetails );
+
+		//组织员工当天的考勤打卡记录
+		AttendanceDetail detail = new AttendanceDetail();
+		detail.setEmpNo( mobileDetail.getEmpNo() );
+		detail.setEmpName( mobileDetail.getEmpName() );
+		if( mobileDetail.getRecordDate() != null ) {
+			detail.setYearString( dateOperation.getYear( mobileDetail.getRecordDate() ) );
+			detail.setMonthString( dateOperation.getMonth( mobileDetail.getRecordDate() ) );
+		}
+		detail.setRecordDateString( mobileDetail.getRecordDateString() );
+		detail.setOnDutyTime( onDutyTime );
+		if( StringUtils.equals(offDutyTime, onDutyTime ) ){
+			detail.setOffDutyTime( null );
+		}else{
+			detail.setOffDutyTime( offDutyTime ); //最晚的一次打卡作为当天的下班签退打卡
+		}
+		detail.setRecordStatus( 0 );
+		detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );
+		return detail;
+	}
+
+	/**
+	 * 将最晚的一次打卡时间设置为下班打卡时间
+	 * @param mobileDetails
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOffDutyTime( List<AttendanceDetailMobile> mobileDetails ) throws Exception {
+		Date offDutyTime = null;
+		Date signTime = null;
+		String offDutyTimeString = null;
+		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
+			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+				signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+				if( offDutyTime != null && signTime != null && offDutyTime.before( signTime )) {
+					offDutyTime = signTime;
+					offDutyTimeString = detailMobile.getSignTime();
+				}else if( offDutyTime == null ){
+					offDutyTime = signTime;
+					offDutyTimeString = detailMobile.getSignTime();
+				}
+			}
+		}
+		return offDutyTimeString;
+	}
+
+	/**
+	 * 将第一次打卡时间,设置为上班打卡时间
+	 * @param mobileDetails
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOnDutyTime(List<AttendanceDetailMobile> mobileDetails) throws Exception {
+		Date onDutyTime = null;
+		Date signTime = null;
+		String onDutyTimeString = null;
+		for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+			signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+			if( onDutyTime != null && signTime != null && onDutyTime.after( signTime )) {
+				onDutyTime = signTime;
+				onDutyTimeString = detailMobile.getSignTime();
+			}else if( onDutyTime == null ){
+				onDutyTime = signTime;
+				onDutyTimeString = detailMobile.getSignTime();
+			}
+		}
+		return onDutyTimeString;
+	}
+}

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

@@ -0,0 +1,153 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import org.apache.commons.lang3.StringUtils;
+
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 2、一天三次打卡:打上班,下班两次卡外,中午休息时间也需要打一次卡,以确保员工在公司活动
+ */
+class ComposeDetailWithMobileInSignProxy2 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( ComposeDetailWithMobileInSignProxy2.class );
+	private DateOperation dateOperation = new DateOperation();
+
+	/**
+	 * 组织一个完整的打卡记录,有午休时间记录
+	 * 1、上班打卡时间:最早的一次打卡就是上班打卡时间
+	 * 2、中午打卡时间,计算午休开始和结束时间内,最晚的那一次打卡时间作为午休打卡时间
+	 * 3、下班打卡时间:取最晚的一次打卡
+	 * @param mobileDetails
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public AttendanceDetail compose(List<AttendanceDetailMobile> mobileDetails, AttendanceScheduleSetting scheduleSetting, Boolean debugger) throws Exception {
+		AttendanceDetailMobile mobileDetail = mobileDetails.get( 0 );
+		String onDutyTime = getOnDutyTime( mobileDetails );
+		String offDutyTime = getOffDutyTime( mobileDetails );
+
+		if(StringUtils.isEmpty( scheduleSetting.getMiddayRestStartTime() )){
+			scheduleSetting.setMiddayRestStartTime("11:30");
+		}
+
+		if(StringUtils.isEmpty( scheduleSetting.getMiddayRestEndTime() )){
+			scheduleSetting.setMiddayRestStartTime("13:30");
+		}
+
+		String morningOffdutyTime = getMorningOffDutyTime( mobileDetails, scheduleSetting.getMiddayRestStartTime(), scheduleSetting.getMiddayRestEndTime() );
+
+		//组织员工当天的考勤打卡记录
+		AttendanceDetail detail = new AttendanceDetail();
+		detail.setEmpNo( mobileDetail.getEmpNo() );
+		detail.setEmpName( mobileDetail.getEmpName() );
+		if( mobileDetail.getRecordDate() != null ) {
+			detail.setYearString( dateOperation.getYear( mobileDetail.getRecordDate() ) );
+			detail.setMonthString( dateOperation.getMonth( mobileDetail.getRecordDate() ) );
+		}
+		detail.setRecordDateString( mobileDetail.getRecordDateString() );
+		detail.setOnDutyTime( onDutyTime ); //最早的一次打卡作为当天的上班签到打卡
+		if( StringUtils.equals(morningOffdutyTime, onDutyTime )){
+			detail.setMorningOffdutyTime( null );
+		}else{
+			detail.setMorningOffdutyTime( morningOffdutyTime ); //午休打卡时间
+		}
+		if( StringUtils.equals(offDutyTime, onDutyTime ) || StringUtils.equals(morningOffdutyTime, offDutyTime ) ){
+			detail.setOffDutyTime( null );
+		}else{
+			detail.setOffDutyTime( offDutyTime ); //最晚的一次打卡作为当天的下班签退打卡
+		}
+		detail.setRecordStatus( 0 );
+		detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );
+		return detail;
+	}
+
+	/**
+	 * 计算午休开始和结束时间内,最晚的那一次打卡时间作为午休打卡时间
+	 * @param mobileDetails
+	 * @param middayRestStartTime
+	 * @param middayRestEndTime
+	 * @return
+	 */
+	private String getMorningOffDutyTime(List<AttendanceDetailMobile> mobileDetails, String middayRestStartTime, String middayRestEndTime) throws Exception {
+		Date moningOndutyTime = null;
+		Date signTime = null, restStartTime=null, restEndTime = null;
+		String resultTime = null;
+		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
+			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+				signTime = dateOperation.getDateFromString( detailMobile.getSignTime() );
+				restStartTime = dateOperation.getDateFromString( middayRestStartTime );
+				restEndTime = dateOperation.getDateFromString( middayRestEndTime );
+				if( moningOndutyTime != null && signTime != null && restStartTime.before( signTime ) && restEndTime.after( signTime )) {
+					if( moningOndutyTime.before( signTime ) ){
+						moningOndutyTime = signTime;
+						resultTime = detailMobile.getSignTime();
+					}
+				}else if( moningOndutyTime == null ){
+					moningOndutyTime = signTime;
+					resultTime = detailMobile.getSignTime();
+				}
+			}
+		}
+		return resultTime;
+	}
+
+	/**
+	 * 将最晚的一次打卡时间设置为下班打卡时间
+	 * @param mobileDetails
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOffDutyTime( List<AttendanceDetailMobile> mobileDetails ) throws Exception {
+		Date offDutyTime = null;
+		Date signTime = null;
+		String offDutyTimeString = null;
+		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
+			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+				signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+				if( offDutyTime != null && signTime != null && offDutyTime.before( signTime )) {
+					offDutyTime = signTime;
+					offDutyTimeString = detailMobile.getSignTime();
+				}else if( offDutyTime == null ){
+					offDutyTime = signTime;
+					offDutyTimeString = detailMobile.getSignTime();
+				}
+			}
+		}
+		return offDutyTimeString;
+	}
+
+	/**
+	 * 将第一次打卡时间,设置为上班打卡时间
+	 * @param mobileDetails
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOnDutyTime(List<AttendanceDetailMobile> mobileDetails) throws Exception {
+		Date onDutyTime = null;
+		Date signTime = null;
+		String onDutyTimeString = null;
+		for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+			signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+			if( onDutyTime != null && signTime != null && onDutyTime.after( signTime )) {
+				onDutyTime = signTime;
+				onDutyTimeString = detailMobile.getSignTime();
+			}else if( onDutyTime == null ){
+				onDutyTime = signTime;
+				onDutyTimeString = detailMobile.getSignTime();
+			}
+		}
+		return onDutyTimeString;
+	}
+}

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

@@ -0,0 +1,198 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.common.date.DateOperation;
+import com.x.attendance.entity.AttendanceDetail;
+import com.x.attendance.entity.AttendanceDetailMobile;
+import com.x.attendance.entity.AttendanceScheduleSetting;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 考勤打卡记录分析服务类
+ * 3、一天四次打卡:打上午上班,上午下班,下午上班,下午下班四次卡
+ */
+class ComposeDetailWithMobileInSignProxy3 {
+	
+	private static  Logger logger = LoggerFactory.getLogger( ComposeDetailWithMobileInSignProxy3.class );
+	private DateOperation dateOperation = new DateOperation();
+
+	/**
+	 * 组织一个完整的打卡记录,有午休时间记录
+	 * 1、上午上班打卡时间:上午上班时段中,最早的一次打卡时间就是上午上班打卡时间
+	 * 2、上午下班打卡时间:上午上班时段中,最晚的一次打卡时间就是上午下班打卡时间
+	 * 3、下午上班打卡时间:下午上班时段中,最早的一次打卡时间就是下午上班打卡时间
+	 * 3、下午下班打卡时间:下午上班时段中,最晚的一次打卡时间就是下午下班打卡时间
+	 * @param mobileDetails
+	 * @param scheduleSetting
+	 * @param debugger
+	 * @return
+	 * @throws Exception
+	 */
+	public AttendanceDetail compose(List<AttendanceDetailMobile> mobileDetails, AttendanceScheduleSetting scheduleSetting, Boolean debugger) throws Exception {
+		AttendanceDetailMobile mobileDetail = mobileDetails.get( 0 );
+		if(StringUtils.isEmpty( scheduleSetting.getMiddayRestStartTime() )){
+			scheduleSetting.setMiddayRestStartTime("11:30");
+		}
+		if(StringUtils.isEmpty( scheduleSetting.getMiddayRestEndTime() )){
+			scheduleSetting.setMiddayRestStartTime("13:30");
+		}
+		String middayRestStartTime = scheduleSetting.getMiddayRestStartTime();
+		String middayRestEndTime = scheduleSetting.getMiddayRestEndTime();
+		String onWorkTimeStr = scheduleSetting.getOnDutyTime();
+		String offWorkTimeStr = scheduleSetting.getOffDutyTime();
+		String onDutyTime = getOnDutyTime( mobileDetails, middayRestStartTime );
+		String offDutyTime = getOffDutyTime( mobileDetails, middayRestEndTime );
+		String morningOffdutyTime = getMorningOffDutyTime(mobileDetails, onWorkTimeStr, middayRestEndTime);
+		String afternoonOndutyTime = getAfternoonOnDutyTime( mobileDetails, middayRestStartTime, offWorkTimeStr );
+
+		//组织员工当天的考勤打卡记录
+		AttendanceDetail detail = new AttendanceDetail();
+		detail.setEmpNo( mobileDetail.getEmpNo() );
+		detail.setEmpName( mobileDetail.getEmpName() );
+		if( mobileDetail.getRecordDate() != null ) {
+			detail.setYearString( dateOperation.getYear( mobileDetail.getRecordDate() ) );
+			detail.setMonthString( dateOperation.getMonth( mobileDetail.getRecordDate() ) );
+		}
+		detail.setRecordDateString( mobileDetail.getRecordDateString() );
+		detail.setOnDutyTime( onDutyTime ); //上午上班签到打卡
+		detail.setMorningOffdutyTime( morningOffdutyTime ); //上午下班打卡
+		detail.setAfternoonOnDutyTime( afternoonOndutyTime ); //下午上班打卡
+		detail.setOffDutyTime( offDutyTime ); //下午下班签退打卡
+		detail.setRecordStatus( 0 );
+		detail.setBatchName( "FromMobile_" + dateOperation.getNowTimeChar() );
+		return detail;
+	}
+
+	/**
+	 * 计算上午下班打卡时间:离上午上班时间最近的一次打卡时间
+	 * 取上午上班之后,到下午上班之前最晚的打卡记录
+	 *
+	 * @param mobileDetails
+	 * @param onWorkTimeStr 上午上班时间
+	 * @param middayRestEndTime 下午上班时间
+	 * @return
+	 */
+	private String getMorningOffDutyTime(List<AttendanceDetailMobile> mobileDetails, String onWorkTimeStr, String middayRestEndTime) throws Exception {
+		Date moningOffdutyTime = null;
+		Date signTime = null, afternoonOnDutyTime = null, onWorkTime = null;
+		String result = null;
+		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
+			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+				signTime = dateOperation.getDateFromString( detailMobile.getSignTime() );
+				afternoonOnDutyTime = dateOperation.getDateFromString( middayRestEndTime );
+				onWorkTime = dateOperation.getDateFromString( onWorkTimeStr );
+
+				//去掉上午上班前和下午上班后的打卡信息
+				if( signTime.before( onWorkTime ) || signTime.after( afternoonOnDutyTime )){
+					continue;
+				}
+				if( moningOffdutyTime != null && signTime != null && moningOffdutyTime.before( signTime ) ) {
+					moningOffdutyTime = signTime;
+					result = detailMobile.getSignTime();
+				}else if( moningOffdutyTime == null ){
+					moningOffdutyTime = signTime;
+					result = detailMobile.getSignTime();
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 计算下午上班打卡:离下午上班时间最近的一次打卡时间
+	 * 取上午下班之后,下午下班之前最早的一次打卡时间
+	 * @param mobileDetails
+	 * @param middayRestStartTime
+	 * @param offWorkTimeStr
+	 * @return
+	 */
+	private String getAfternoonOnDutyTime(List<AttendanceDetailMobile> mobileDetails, String middayRestStartTime, String offWorkTimeStr ) throws Exception {
+		Date afternoonOnDutyTime = null;
+		Date signTime = null, morningOffWorkTime=null, offWorkTime = null;
+		String result = null;
+		if( ListTools.isNotEmpty( mobileDetails ) && mobileDetails.size() >=2 ) {
+			for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+				signTime = dateOperation.getDateFromString( detailMobile.getSignTime() );
+				morningOffWorkTime = dateOperation.getDateFromString( middayRestStartTime );
+				offWorkTime = dateOperation.getDateFromString( offWorkTimeStr );
+
+				//上午下班之前的打卡和下午下班之后的打卡不算,取上午下班后到下午下班之前最量的一次打卡
+				if( signTime.before(morningOffWorkTime) || signTime.after( offWorkTime )){
+					continue;
+				}
+				if( afternoonOnDutyTime != null && signTime != null && signTime.before( afternoonOnDutyTime )) {
+					afternoonOnDutyTime = signTime;
+					result = detailMobile.getSignTime();
+				}else if( afternoonOnDutyTime == null ){
+					afternoonOnDutyTime = signTime;
+					result = detailMobile.getSignTime();
+				}
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 将下午上班之后所有的打卡中最晚的一次作为当天下午下班的签退打卡
+	 *
+	 * @param mobileDetails
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOffDutyTime( List<AttendanceDetailMobile> mobileDetails, String middayRestEndTime ) throws Exception {
+		Date offDutyTime = null, signTime = null, afterOndutyTime=null;
+		String result = null;
+
+		for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+			signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+			afterOndutyTime = dateOperation.getDateFromString( middayRestEndTime );
+			//下午上班前的打卡就不算到下午下班打卡了
+			if( signTime.before( afterOndutyTime )){
+				continue;
+			}
+			if( offDutyTime != null && signTime != null && offDutyTime.before( signTime )) {
+				offDutyTime = signTime;
+				result = detailMobile.getSignTime();
+			}else if( offDutyTime == null ){
+				offDutyTime = signTime;
+				result = detailMobile.getSignTime();
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 将第一次打卡时间,设置为上班打卡时间
+	 * 只可能在第一区间和第二区间,在上午下班时间之前打卡才能算当天上午的上班打卡
+	 * @param mobileDetails
+	 * @param middayRestStartTime
+	 * @return
+	 * @throws Exception
+	 */
+	private String getOnDutyTime(List<AttendanceDetailMobile> mobileDetails, String middayRestStartTime ) throws Exception {
+		Date onDutyTime = null, signTime = null, morningOffdutyTime=null;
+		String result = null;
+
+		for( AttendanceDetailMobile detailMobile : mobileDetails ) {
+			signTime = dateOperation.getDateFromString(detailMobile.getSignTime() );
+			morningOffdutyTime = dateOperation.getDateFromString( middayRestStartTime );
+			//排除在上午下班时间之后的打卡
+			if( signTime.after( morningOffdutyTime )){
+				continue;
+			}
+			if( onDutyTime != null && signTime != null && onDutyTime.after( signTime )) {
+				onDutyTime = signTime;
+				result = detailMobile.getSignTime();
+			}else if( onDutyTime == null ){
+				onDutyTime = signTime;
+				result = detailMobile.getSignTime();
+			}
+		}
+		return result;
+	}
+}

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

@@ -69,6 +69,9 @@ public class UserManagerService {
 		Business business = null;
 		Business business = null;
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
 			business = new Business(emc);
 			business = new Business(emc);
+			if( StringUtils.equalsAnyIgnoreCase( "xadmin", identity ) || StringUtils.equalsAnyIgnoreCase( "cipher", identity ) ){
+				return null;
+			}
 			return business.organization().unit().getWithIdentity( identity );
 			return business.organization().unit().getWithIdentity( identity );
 		} catch ( Exception e ) {
 		} catch ( Exception e ) {
 			throw e;
 			throw e;

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

@@ -0,0 +1,244 @@
+package com.x.attendance.assemble.control.service;
+
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.connection.ActionResponse;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.x_processplatform_assemble_surface;
+import com.x.processplatform.core.entity.content.*;
+import com.x.processplatform.core.entity.element.ActivityType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WorkFlowSyncService {
+
+	public static WoWorkComplex getWorkComplex( String workId ) throws Exception {
+		String serviceUri = "work/" + workId;
+		ActionResponse resp = ThisApplication.context().applications().getQuery(
+				x_processplatform_assemble_surface.class, serviceUri
+		);
+		WoWorkComplex wo = resp.getData( WoWorkComplex.class );
+		return wo;
+	}
+
+	public static class WoWorkComplex extends GsonPropertyObject {
+
+		@FieldDescribe("活动节点")
+		private WoActivity activity;
+
+		@FieldDescribe("工作")
+		private WoWork work;
+
+		@FieldDescribe("待办对象列表")
+		private List<WoTask> taskList = new ArrayList<>();
+
+		@FieldDescribe("工作日志对象")
+		private List<WoWorkLog> workLogList = new ArrayList<>();
+
+		public WoActivity getActivity() {
+			return activity;
+		}
+
+		public WoWork getWork() {
+			return work;
+		}
+
+		public List<WoWorkLog> getWorkLogList() {
+			return workLogList;
+		}
+
+		public void setActivity(WoActivity activity) {
+			this.activity = activity;
+		}
+
+		public void setWork(WoWork work) {
+			this.work = work;
+		}
+
+		public void setWorkLogList(List<WoWorkLog> workLogList) {
+			this.workLogList = workLogList;
+		}
+
+		public List<WoTask> getTaskList() {
+			return taskList;
+		}
+
+		public void setTaskList(List<WoTask> taskList) {
+			this.taskList = taskList;
+		}
+	}
+
+	public static class WoActivity extends GsonPropertyObject {
+
+		private String id;
+
+		private String name;
+
+		private String description;
+
+		private String alias;
+
+		private String position;
+
+		private ActivityType activityType;
+
+		private String resetRange;
+
+		private Integer resetCount;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getDescription() {
+			return description;
+		}
+
+		public void setDescription(String description) {
+			this.description = description;
+		}
+
+		public String getAlias() {
+			return alias;
+		}
+
+		public void setAlias(String alias) {
+			this.alias = alias;
+		}
+
+		public String getPosition() {
+			return position;
+		}
+
+		public void setPosition(String position) {
+			this.position = position;
+		}
+
+		public ActivityType getActivityType() {
+			return activityType;
+		}
+
+		public void setActivityType(ActivityType activityType) {
+			this.activityType = activityType;
+		}
+
+		public String getId() {
+			return id;
+		}
+
+		public void setId(String id) {
+			this.id = id;
+		}
+
+		public Integer getResetCount() {
+			return resetCount;
+		}
+
+		public void setResetCount(Integer resetCount) {
+			this.resetCount = resetCount;
+		}
+
+		public String getResetRange() {
+			return resetRange;
+		}
+
+		public void setResetRange(String resetRange) {
+			this.resetRange = resetRange;
+		}
+
+	}
+
+	public static class WoWork extends Work {
+
+		private static final long serialVersionUID = 3269592171662996253L;
+
+		static WrapCopier<Work, WoWork> copier = WrapCopierFactory.wo(Work.class, WoWork.class, null,
+				JpaObject.FieldsInvisible);
+	}
+
+	public static class WoWorkLog extends WorkLog {
+
+		private static final long serialVersionUID = 1307569946729101786L;
+
+		public static WrapCopier<WorkLog, WoWorkLog> copier = WrapCopierFactory.wo(WorkLog.class, WoWorkLog.class, null,
+				JpaObject.FieldsInvisible);
+
+		private List<WoTaskCompleted> taskCompletedList;
+
+		private List<WoTask> taskList;
+
+		private Integer currentTaskIndex;
+
+		public Integer getCurrentTaskIndex() {
+			return currentTaskIndex;
+		}
+
+		public void setCurrentTaskIndex(Integer currentTaskIndex) {
+			this.currentTaskIndex = currentTaskIndex;
+		}
+
+		public List<WoTaskCompleted> getTaskCompletedList() {
+			return taskCompletedList;
+		}
+
+		public void setTaskCompletedList(List<WoTaskCompleted> taskCompletedList) {
+			this.taskCompletedList = taskCompletedList;
+		}
+
+		public List<WoTask> getTaskList() {
+			return taskList;
+		}
+
+		public void setTaskList(List<WoTask> taskList) {
+			this.taskList = taskList;
+		}
+
+	}
+
+	public static class WoTask extends Task {
+
+		private static final long serialVersionUID = 2279846765261247910L;
+
+		public static WrapCopier<Task, WoTask> copier = WrapCopierFactory.wo(Task.class, WoTask.class, null,
+				JpaObject.FieldsInvisible);
+
+	}
+
+	public static class WoRead extends Read {
+
+		private static final long serialVersionUID = -8067704098385000667L;
+
+		public static WrapCopier<Read, WoRead> copier = WrapCopierFactory.wo(Read.class, WoRead.class, null,
+				JpaObject.FieldsInvisible);
+
+	}
+
+	public static class WoTaskCompleted extends TaskCompleted {
+
+		private static final long serialVersionUID = -7253999118308715077L;
+
+		public static WrapCopier<TaskCompleted, WoTaskCompleted> copier = WrapCopierFactory.wo(TaskCompleted.class,
+				WoTaskCompleted.class, null, JpaObject.FieldsInvisible);
+		private Long rank;
+
+		public Long getRank() {
+			return rank;
+		}
+
+		public void setRank(Long rank) {
+			this.rank = rank;
+		}
+
+	}
+
+
+
+}

+ 1 - 1
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAdmin.java

@@ -79,7 +79,7 @@ public class AttendanceAdmin extends SliceJpaObject {
 
 
 	public static final String admin_FIELDNAME = "admin";
 	public static final String admin_FIELDNAME = "admin";
 	@FieldDescribe("管理员标识")
 	@FieldDescribe("管理员标识")
-	@Column(length = JpaObject.length_96B, name = ColumnNamePrefix + adminName_FIELDNAME)
+	@Column(length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + admin_FIELDNAME)
 	@Index(name = TABLE + IndexNameMiddle + adminName_FIELDNAME)
 	@Index(name = TABLE + IndexNameMiddle + adminName_FIELDNAME)
 	private String admin = "";
 	private String admin = "";
 
 

+ 14 - 11
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAppealAuditInfo.java

@@ -59,10 +59,20 @@ public class AttendanceAppealAuditInfo extends SliceJpaObject {
 	private String detailId;
 	private String detailId;
 
 
 	public static final String auditFlowType_FIELDNAME = "auditFlowType";
 	public static final String auditFlowType_FIELDNAME = "auditFlowType";
-	@FieldDescribe("审批方式:WORKFLOW|BUILTIN")
+	@FieldDescribe("审批方式:WORKFLOW|BUILTIN,使用自定义流程或者使用内置流程")
 	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + auditFlowType_FIELDNAME)
 	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + auditFlowType_FIELDNAME)
 	private String auditFlowType = AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN;
 	private String auditFlowType = AppealConfig.APPEAL_AUDIFLOWTYPE_BUILTIN;
 
 
+	public static final String workId_FIELDNAME = "workId";
+	@FieldDescribe("自定义审批流程WorkID")
+	@Column( length = JpaObject.length_id, name = ColumnNamePrefix + workId_FIELDNAME)
+	private String workId;
+
+	public static final String lastFlowSyncTime_FIELDNAME = "lastFlowSyncTime";
+	@FieldDescribe("上次进行状态同步时间")
+	@Column( name = ColumnNamePrefix + lastFlowSyncTime_FIELDNAME)
+	private Date lastFlowSyncTime;
+
 	public static final String currentProcessor_FIELDNAME = "currentProcessor";
 	public static final String currentProcessor_FIELDNAME = "currentProcessor";
 	@FieldDescribe("当前审核人")
 	@FieldDescribe("当前审核人")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + currentProcessor_FIELDNAME)
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + currentProcessor_FIELDNAME)
@@ -120,23 +130,16 @@ public class AttendanceAppealAuditInfo extends SliceJpaObject {
 	@Column( name = ColumnNamePrefix + processTime2_FIELDNAME )
 	@Column( name = ColumnNamePrefix + processTime2_FIELDNAME )
 	private Date processTime2;
 	private Date processTime2;
 
 
-	public static final String auditFlowId_FIELDNAME = "auditFlowId";
-	@FieldDescribe("自定义审批流程ID")
-	@Column( length = JpaObject.length_id, name = ColumnNamePrefix + auditFlowType_FIELDNAME)
-	private String auditFlowId;
 
 
-	public static final String lastFlowSyncTime_FIELDNAME = "lastFlowSyncTime";
-	@FieldDescribe("上次进行状态同步时间")
-	@Column( name = ColumnNamePrefix + lastFlowSyncTime_FIELDNAME)
-	private Date lastFlowSyncTime;
+	public void setCurrentProcessor(String currentProcessor) { this.currentProcessor = currentProcessor; }
 
 
 	public String getAuditFlowType() { return auditFlowType; }
 	public String getAuditFlowType() { return auditFlowType; }
 
 
 	public void setAuditFlowType(String auditFlowType) { this.auditFlowType = auditFlowType; }
 	public void setAuditFlowType(String auditFlowType) { this.auditFlowType = auditFlowType; }
 
 
-	public String getAuditFlowId() { return auditFlowId; }
+	public String getWorkId() { return workId; }
 
 
-	public void setAuditFlowId(String auditFlowId) { this.auditFlowId = auditFlowId; }
+	public void setWorkId(String workId) { this.workId = workId; }
 
 
 	public Date getLastFlowSyncTime() { return lastFlowSyncTime; }
 	public Date getLastFlowSyncTime() { return lastFlowSyncTime; }
 
 

+ 148 - 152
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceAppealInfo.java

@@ -70,18 +70,18 @@ public class AttendanceAppealInfo extends SliceJpaObject {
 	private String detailId;
 	private String detailId;
 
 
 	public static final String empName_FIELDNAME = "empName";
 	public static final String empName_FIELDNAME = "empName";
-	@FieldDescribe("申诉员工标识")
+	@FieldDescribe("申诉员工标识:distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + empName_FIELDNAME)
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + empName_FIELDNAME)
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String empName;
 	private String empName;
 
 
 	public static final String topUnitName_FIELDNAME = "topUnitName";
 	public static final String topUnitName_FIELDNAME = "topUnitName";
-	@FieldDescribe("员工所属顶层组织")
+	@FieldDescribe("员工所属顶层组织distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME)
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME)
 	private String topUnitName;
 	private String topUnitName;
 
 
 	public static final String unitName_FIELDNAME = "unitName";
 	public static final String unitName_FIELDNAME = "unitName";
-	@FieldDescribe("员工所属组织名称")
+	@FieldDescribe("员工所属组织名称distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME)
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME)
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 	private String unitName;
@@ -165,67 +165,67 @@ public class AttendanceAppealInfo extends SliceJpaObject {
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + archiveTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + archiveTime_FIELDNAME )
 	private String archiveTime;
 	private String archiveTime;
 
 
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPerson1_FIELDNAME = "processPerson1";
-	@FieldDescribe("审批人一")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPerson1_FIELDNAME)
-	private String processPerson1;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPersonUnit1_FIELDNAME = "processPersonUnit1";
-	@FieldDescribe("审批人组织一")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonUnit1_FIELDNAME)
-	private String processPersonUnit1;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPersonTopUnit1_FIELDNAME = "processPersonTopUnit1";
-	@FieldDescribe("审批人顶层组织一")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonTopUnit1_FIELDNAME)
-	private String processPersonTopUnit1;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String opinion1_FIELDNAME = "opinion1";
-	@FieldDescribe("审批意见一")
-	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + opinion1_FIELDNAME )
-	private String opinion1;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processTime1_FIELDNAME = "processTime1";
-	@FieldDescribe("审批日期一")
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column( name = ColumnNamePrefix + processTime1_FIELDNAME)
-	private Date processTime1;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPerson2_FIELDNAME = "processPerson2";
-	@FieldDescribe("审批人二")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPerson2_FIELDNAME)
-	private String processPerson2;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPersonUnit2_FIELDNAME = "processPersonUnit2";
-	@FieldDescribe("审批人组织二")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonUnit2_FIELDNAME )
-	private String processPersonUnit2;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processPersonTopUnit2_FIELDNAME = "processPersonTopUnit2";
-	@FieldDescribe("审批人顶层组织二")
-	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonTopUnit2_FIELDNAME )
-	private String processPersonTopUnit2;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String opinion2_FIELDNAME = "opinion2";
-	@FieldDescribe("审批意见二")
-	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + opinion2_FIELDNAME )
-	private String opinion2;
-
-	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
-	public static final String processTime2_FIELDNAME = "processTime2";
-	@FieldDescribe("审批日期二")
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column( name = ColumnNamePrefix + processTime2_FIELDNAME )
-	private Date processTime2;
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPerson1_FIELDNAME = "processPerson1";
+////	@FieldDescribe("审批人一")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPerson1_FIELDNAME)
+//	private String processPerson1;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPersonUnit1_FIELDNAME = "processPersonUnit1";
+////	@FieldDescribe("审批人组织一")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonUnit1_FIELDNAME)
+//	private String processPersonUnit1;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPersonTopUnit1_FIELDNAME = "processPersonTopUnit1";
+////	@FieldDescribe("审批人顶层组织一")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonTopUnit1_FIELDNAME)
+//	private String processPersonTopUnit1;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String opinion1_FIELDNAME = "opinion1";
+////	@FieldDescribe("审批意见一")
+//	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + opinion1_FIELDNAME )
+//	private String opinion1;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processTime1_FIELDNAME = "processTime1";
+////	@FieldDescribe("审批日期一")
+//	@Temporal(TemporalType.TIMESTAMP)
+//	@Column( name = ColumnNamePrefix + processTime1_FIELDNAME)
+//	private Date processTime1;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPerson2_FIELDNAME = "processPerson2";
+////	@FieldDescribe("审批人二")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPerson2_FIELDNAME)
+//	private String processPerson2;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPersonUnit2_FIELDNAME = "processPersonUnit2";
+////	@FieldDescribe("审批人组织二")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonUnit2_FIELDNAME )
+//	private String processPersonUnit2;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processPersonTopUnit2_FIELDNAME = "processPersonTopUnit2";
+////	@FieldDescribe("审批人顶层组织二")
+//	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + processPersonTopUnit2_FIELDNAME )
+//	private String processPersonTopUnit2;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String opinion2_FIELDNAME = "opinion2";
+////	@FieldDescribe("审批意见二")
+//	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + opinion2_FIELDNAME )
+//	private String opinion2;
+//
+//	//2020-05-15 新版本取消此属性,审批信息在AttendanceAppealAuditInfo里记录
+//	public static final String processTime2_FIELDNAME = "processTime2";
+////	@FieldDescribe("审批日期二")
+//	@Temporal(TemporalType.TIMESTAMP)
+//	@Column( name = ColumnNamePrefix + processTime2_FIELDNAME )
+//	private Date processTime2;
 
 
 	public String getDetailId() {
 	public String getDetailId() {
 		return detailId;
 		return detailId;
@@ -315,94 +315,6 @@ public class AttendanceAppealInfo extends SliceJpaObject {
 		this.appealDescription = appealDescription;
 		this.appealDescription = appealDescription;
 	}
 	}
 
 
-	public String getProcessPerson1() {
-		return processPerson1;
-	}
-
-	public void setProcessPerson1(String processPerson1) {
-		this.processPerson1 = processPerson1;
-	}
-
-	public String getProcessPersonUnit1() {
-		return processPersonUnit1;
-	}
-
-	public void setProcessPersonUnit1(String processPersonUnit1) {
-		this.processPersonUnit1 = processPersonUnit1;
-	}
-
-	public String getProcessPersonTopUnit1() {
-		return processPersonTopUnit1;
-	}
-
-	public void setProcessPersonTopUnit1(String processPersonTopUnit1) {
-		this.processPersonTopUnit1 = processPersonTopUnit1;
-	}
-
-	public String getOpinion1() {
-		return opinion1;
-	}
-
-	public void setOpinion1(String opinion1) {
-		this.opinion1 = opinion1;
-	}
-
-	public Date getProcessTime1() {
-		return processTime1;
-	}
-
-	public void setProcessTime1(Date processTime1) {
-		this.processTime1 = processTime1;
-	}
-
-	public String getAppealDateString() {
-		return appealDateString;
-	}
-
-	public void setAppealDateString(String appealDateString) {
-		this.appealDateString = appealDateString;
-	}
-
-	public String getProcessPerson2() {
-		return processPerson2;
-	}
-
-	public void setProcessPerson2(String processPerson2) {
-		this.processPerson2 = processPerson2;
-	}
-
-	public String getProcessPersonUnit2() {
-		return processPersonUnit2;
-	}
-
-	public void setProcessPersonUnit2(String processPersonUnit2) {
-		this.processPersonUnit2 = processPersonUnit2;
-	}
-
-	public String getProcessPersonTopUnit2() {
-		return processPersonTopUnit2;
-	}
-
-	public void setProcessPersonTopUnit2(String processPersonTopUnit2) {
-		this.processPersonTopUnit2 = processPersonTopUnit2;
-	}
-
-	public String getOpinion2() {
-		return opinion2;
-	}
-
-	public void setOpinion2(String opinion2) {
-		this.opinion2 = opinion2;
-	}
-
-	public Date getProcessTime2() {
-		return processTime2;
-	}
-
-	public void setProcessTime2(Date processTime2) {
-		this.processTime2 = processTime2;
-	}
-
 	public String getCurrentProcessor() {
 	public String getCurrentProcessor() {
 		return currentProcessor;
 		return currentProcessor;
 	}
 	}
@@ -458,4 +370,88 @@ public class AttendanceAppealInfo extends SliceJpaObject {
 	public void setArchiveTime(String archiveTime) {
 	public void setArchiveTime(String archiveTime) {
 		this.archiveTime = archiveTime;
 		this.archiveTime = archiveTime;
 	}
 	}
+
+	public String getAppealDateString() {
+		return appealDateString;
+	}
+
+	public void setAppealDateString(String appealDateString) {
+		this.appealDateString = appealDateString;
+	}
+
+//	public String getProcessPerson1() {
+//		return processPerson1;
+//	}
+//
+//	public void setProcessPerson1(String processPerson1) {
+//		this.processPerson1 = processPerson1;
+//	}
+//
+//	public String getProcessPersonUnit1() {
+//		return processPersonUnit1;
+//	}
+//
+//	public void setProcessPersonUnit1(String processPersonUnit1) {
+//		this.processPersonUnit1 = processPersonUnit1;
+//	}
+//
+//	public String getProcessPersonTopUnit1() {
+//		return processPersonTopUnit1;
+//	}
+//
+//	public void setProcessPersonTopUnit1(String processPersonTopUnit1) { this.processPersonTopUnit1 = processPersonTopUnit1; }
+//
+//	public String getOpinion1() {
+//		return opinion1;
+//	}
+//
+//	public void setOpinion1(String opinion1) {
+//		this.opinion1 = opinion1;
+//	}
+//
+//	public Date getProcessTime1() {
+//		return processTime1;
+//	}
+//
+//	public void setProcessTime1(Date processTime1) {
+//		this.processTime1 = processTime1;
+//	}
+//
+//	public String getProcessPerson2() {
+//		return processPerson2;
+//	}
+//
+//	public void setProcessPerson2(String processPerson2) {
+//		this.processPerson2 = processPerson2;
+//	}
+//
+//	public String getProcessPersonUnit2() {
+//		return processPersonUnit2;
+//	}
+//
+//	public void setProcessPersonUnit2(String processPersonUnit2) {
+//		this.processPersonUnit2 = processPersonUnit2;
+//	}
+//
+//	public String getProcessPersonTopUnit2() {
+//		return processPersonTopUnit2;
+//	}
+//
+//	public void setProcessPersonTopUnit2(String processPersonTopUnit2) { this.processPersonTopUnit2 = processPersonTopUnit2; }
+//
+//	public String getOpinion2() {
+//		return opinion2;
+//	}
+//
+//	public void setOpinion2(String opinion2) {
+//		this.opinion2 = opinion2;
+//	}
+//
+//	public Date getProcessTime2() {
+//		return processTime2;
+//	}
+//
+//	public void setProcessTime2(Date processTime2) {
+//		this.processTime2 = processTime2;
+//	}
 }
 }

+ 135 - 258
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetail.java

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

+ 27 - 2
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDetailMobile.java

@@ -12,6 +12,7 @@ import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 import javax.persistence.TemporalType;
 import javax.persistence.UniqueConstraint;
 import javax.persistence.UniqueConstraint;
 
 
+import com.x.base.core.entity.AbstractPersistenceProperties;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
@@ -70,8 +71,8 @@ public class AttendanceDetailMobile extends SliceJpaObject {
 	private String empNo;
 	private String empNo;
 
 
 	public static final String empName_FIELDNAME = "empName";
 	public static final String empName_FIELDNAME = "empName";
-	@FieldDescribe("员工姓名")
-	@Column( length = JpaObject.length_96B, name = ColumnNamePrefix + empName_FIELDNAME )
+	@FieldDescribe("员工姓名distinguishedName")
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + empName_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String empName;
 	private String empName;
 
 
@@ -88,6 +89,23 @@ public class AttendanceDetailMobile extends SliceJpaObject {
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private Date recordDate;
 	private Date recordDate;
 
 
+	public static final String CHECKIN_TYPE_ONDUTY = "上午上班打卡";
+	public static final String CHECKIN_TYPE_MORNING_OFFDUTY = "上午下班打卡";
+	public static final String CHECKIN_TYPE_AFTERNOON_ONDUTY = "下午上班打卡";
+	public static final String CHECKIN_TYPE_OFFDUTY = "下午下班打卡";
+	public static final String CHECKIN_TYPE_AFTERNOON = "午间打卡";
+	//	public static final String CHECKIN_TYPE_OUTSIDE = "外出打卡";
+
+	public static final String checkin_type_FIELDNAME = "checkin_type";
+	@FieldDescribe("打卡类型。字符串,目前有:上午上班打卡,上午下班打卡,下午上班打卡,下午下班打卡,外出打卡,午间打卡")
+	@Column(name = ColumnNamePrefix + checkin_type_FIELDNAME, length = length_32B)
+	private String checkin_type;
+
+	public static final String checkin_time_FIELDNAME = "checkin_time";
+	@FieldDescribe("打卡时间。Unix时间戳")
+	@Column(name = ColumnNamePrefix + checkin_time_FIELDNAME )
+	private long checkin_time;
+
 	public static final String signTime_FIELDNAME = "signTime";
 	public static final String signTime_FIELDNAME = "signTime";
 	@FieldDescribe("打卡时间")
 	@FieldDescribe("打卡时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + signTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + signTime_FIELDNAME )
@@ -245,4 +263,11 @@ public class AttendanceDetailMobile extends SliceJpaObject {
 		this.recordStatus = recordStatus;
 		this.recordStatus = recordStatus;
 	}
 	}
 
 
+	public String getCheckin_type() { return checkin_type; }
+
+	public void setCheckin_type(String checkin_type) { this.checkin_type = checkin_type; }
+
+	public long getCheckin_time() { return checkin_time; }
+
+	public void setCheckin_time(long checkin_time) { this.checkin_time = checkin_time; }
 }
 }

+ 5 - 4
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceDingtalkDetail.java

@@ -1,6 +1,7 @@
 package com.x.attendance.entity;
 package com.x.attendance.entity;
 
 
 
 
+import com.x.base.core.entity.AbstractPersistenceProperties;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.SliceJpaObject;
 import com.x.base.core.entity.SliceJpaObject;
 import com.x.base.core.entity.annotation.ContainerEntity;
 import com.x.base.core.entity.annotation.ContainerEntity;
@@ -56,13 +57,13 @@ public class AttendanceDingtalkDetail extends SliceJpaObject  {
     private String userId;
     private String userId;
 
 
     public static final String o2User_FIELDNAME = "o2User";
     public static final String o2User_FIELDNAME = "o2User";
-    @FieldDescribe("O2OA用户")
-    @Column( length = length_128B, name = ColumnNamePrefix + o2User_FIELDNAME )
+    @FieldDescribe("O2OA用户distinguishedName")
+    @Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + o2User_FIELDNAME )
     private String o2User;
     private String o2User;
 
 
     public static final String o2Unit_FIELDNAME = "o2Unit";
     public static final String o2Unit_FIELDNAME = "o2Unit";
-    @FieldDescribe("O2OA用户所在的组织")
-    @Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
+    @FieldDescribe("O2OA用户所在的组织distinguishedName")
+    @Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + o2Unit_FIELDNAME )
     private String o2Unit;
     private String o2Unit;
 
 
     public static final String baseCheckTime_FIELDNAME = "baseCheckTime";
     public static final String baseCheckTime_FIELDNAME = "baseCheckTime";

+ 5 - 5
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceEmployeeConfig.java

@@ -55,19 +55,19 @@ public class AttendanceEmployeeConfig extends SliceJpaObject {
 	 * =====
 	 * =====
 	 */
 	 */
 	public static final String topUnitName_FIELDNAME = "topUnitName";
 	public static final String topUnitName_FIELDNAME = "topUnitName";
-	@FieldDescribe("顶层组织名称")
+	@FieldDescribe("顶层组织名称distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String topUnitName = "";
 	private String topUnitName = "";
 
 
 	public static final String topUnitOu_FIELDNAME = "topUnitOu";
 	public static final String topUnitOu_FIELDNAME = "topUnitOu";
-	@FieldDescribe("顶层组织编号")
+	@FieldDescribe("顶层组织编号distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitOu_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitOu_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String topUnitOu = "";
 	private String topUnitOu = "";
 
 
 	public static final String unitName_FIELDNAME = "unitName";
 	public static final String unitName_FIELDNAME = "unitName";
-	@FieldDescribe("组织名称")
+	@FieldDescribe("组织名称distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String unitName = "";
 	private String unitName = "";
@@ -79,8 +79,8 @@ public class AttendanceEmployeeConfig extends SliceJpaObject {
 	private String unitOu = "";
 	private String unitOu = "";
 
 
 	public static final String employeeName_FIELDNAME = "employeeName";
 	public static final String employeeName_FIELDNAME = "employeeName";
-	@FieldDescribe("员工姓名")
-	@Column( length = JpaObject.length_96B, name = ColumnNamePrefix + employeeName_FIELDNAME )
+	@FieldDescribe("员工姓名distinguishedName")
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + employeeName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String employeeName = "";
 	private String employeeName = "";
 
 

+ 5 - 4
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceQywxDetail.java

@@ -1,6 +1,7 @@
 package com.x.attendance.entity;
 package com.x.attendance.entity;
 
 
 
 
+import com.x.base.core.entity.AbstractPersistenceProperties;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.JpaObject;
 import com.x.base.core.entity.SliceJpaObject;
 import com.x.base.core.entity.SliceJpaObject;
 import com.x.base.core.entity.annotation.ContainerEntity;
 import com.x.base.core.entity.annotation.ContainerEntity;
@@ -46,13 +47,13 @@ public class AttendanceQywxDetail extends SliceJpaObject  {
 
 
 
 
     public static final String o2User_FIELDNAME = "o2User";
     public static final String o2User_FIELDNAME = "o2User";
-    @FieldDescribe("O2用户")
-    @Column(name = ColumnNamePrefix + o2User_FIELDNAME, length = length_128B)
+    @FieldDescribe("O2用户distinguishedName")
+    @Column(name = ColumnNamePrefix + o2User_FIELDNAME, length = AbstractPersistenceProperties.organization_name_length)
     private String o2User;
     private String o2User;
 
 
     public static final String o2Unit_FIELDNAME = "o2Unit";
     public static final String o2Unit_FIELDNAME = "o2Unit";
-    @FieldDescribe("O2用户所在的组织")
-    @Column(name = ColumnNamePrefix + o2Unit_FIELDNAME, length = length_128B)
+    @FieldDescribe("O2用户所在的组织distinguishedName")
+    @Column(name = ColumnNamePrefix + o2Unit_FIELDNAME, length = AbstractPersistenceProperties.organization_name_length)
     private String o2Unit;
     private String o2Unit;
 
 
     public static final String userid_FIELDNAME = "userid";
     public static final String userid_FIELDNAME = "userid";

+ 68 - 20
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.CheckPersist;
 import com.x.base.core.entity.annotation.ContainerEntity;
 import com.x.base.core.entity.annotation.ContainerEntity;
 import com.x.base.core.project.annotation.FieldDescribe;
 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)
 @ContainerEntity(dumpSize = 1000, type = ContainerEntity.Type.content, reference = ContainerEntity.Reference.strong)
 @Entity
 @Entity
@@ -57,53 +60,86 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 	 * =====
 	 * =====
 	 */
 	 */
 	public static final String topUnitName_FIELDNAME = "topUnitName";
 	public static final String topUnitName_FIELDNAME = "topUnitName";
-	@FieldDescribe("顶层组织名称")
+	@FieldDescribe("顶层组织名称distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + topUnitName_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String topUnitName;
 	private String topUnitName;
 
 
 	public static final String unitName_FIELDNAME = "unitName";
 	public static final String unitName_FIELDNAME = "unitName";
-	@FieldDescribe("组织名称")
+	@FieldDescribe("组织名称distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + unitName_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String unitName;
 	private String unitName;
 
 
 	public static final String unitOu_FIELDNAME = "unitOu";
 	public static final String unitOu_FIELDNAME = "unitOu";
-	@FieldDescribe("组织编号")
+	@FieldDescribe("组织编号distinguishedName")
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitOu_FIELDNAME )
 	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitOu_FIELDNAME )
+	@Index(name = TABLE + IndexNameMiddle + unitOu_FIELDNAME)
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String unitOu;
 	private String unitOu;
 
 
 	public static final String onDutyTime_FIELDNAME = "onDutyTime";
 	public static final String onDutyTime_FIELDNAME = "onDutyTime";
-	@FieldDescribe("上班时间")
+	@FieldDescribe("上午上班时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + onDutyTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + onDutyTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String onDutyTime;
 	private String onDutyTime;
 
 
+	public static final String middayRestStartTime_FIELDNAME = "middayRestStartTime";
+	@FieldDescribe("午休开始时间|上午下班时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + middayRestStartTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestStartTime;
+
+	public static final String middayRestEndTime_FIELDNAME = "middayRestEndTime";
+	@FieldDescribe("午休结束时间|下午上班时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + middayRestEndTime_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String middayRestEndTime;
+
 	public static final String offDutyTime_FIELDNAME = "offDutyTime";
 	public static final String offDutyTime_FIELDNAME = "offDutyTime";
-	@FieldDescribe("下班时间")
+	@FieldDescribe("下午下班时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + offDutyTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String offDutyTime;
 	private String offDutyTime;
 
 
+	public static final String signProxy_FIELDNAME = "signProxy";
+	@FieldDescribe("打卡策略:1-两次打卡(上午上班,下午下班) 2-三次打卡(上午上班,下午下班加中午一次共三次) 3-四次打卡(上午下午都打上班下班卡)")
+	@Column( name = ColumnNamePrefix + signProxy_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private Integer signProxy = 0;
+
 	public static final String lateStartTime_FIELDNAME = "lateStartTime";
 	public static final String lateStartTime_FIELDNAME = "lateStartTime";
-	@FieldDescribe("迟到起算时间")
+	@FieldDescribe("上午上班迟到起算时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + lateStartTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + lateStartTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String lateStartTime;
 	private String lateStartTime;
 
 
+	public static final String lateStartTimeAfternoon_FIELDNAME = "lateStartTimeAfternoon";
+	@FieldDescribe("下午上班迟到起算时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + lateStartTimeAfternoon_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String lateStartTimeAfternoon;
+
 	public static final String absenceStartTime_FIELDNAME = "absenceStartTime";
 	public static final String absenceStartTime_FIELDNAME = "absenceStartTime";
-	@FieldDescribe("缺勤起算时间")
+	@FieldDescribe("缺勤起算时间:第一次打卡在什么时间算是当天缺勤")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + absenceStartTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + absenceStartTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String absenceStartTime;
 	private String absenceStartTime;
 
 
 	public static final String leaveEarlyStartTime_FIELDNAME = "leaveEarlyStartTime";
 	public static final String leaveEarlyStartTime_FIELDNAME = "leaveEarlyStartTime";
-	@FieldDescribe("早退起算时间")
+	@FieldDescribe("下午早退起算时间")
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + leaveEarlyStartTime_FIELDNAME )
 	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + leaveEarlyStartTime_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String leaveEarlyStartTime;
 	private String leaveEarlyStartTime;
 
 
+	public static final String leaveEarlyStartTimeMorning_FIELDNAME = "leaveEarlyStartTimeMorning";
+	@FieldDescribe("上午早退起算时间")
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + leaveEarlyStartTimeMorning_FIELDNAME )
+	@CheckPersist(allowEmpty = true)
+	private String leaveEarlyStartTimeMorning;
+
 	public String getUnitName() {
 	public String getUnitName() {
 		return unitName;
 		return unitName;
 	}
 	}
@@ -120,21 +156,25 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 		this.unitOu = unitOu;
 		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 getSignProxy() { return signProxy == null? 1:signProxy; }
+
+	public void setSignProxy(Integer signProxy) { this.signProxy = signProxy; }
+
+	public String getOffDutyTime() { return offDutyTime; }
+
+	public void setOffDutyTime(String offDutyTime) { this.offDutyTime = offDutyTime; }
 
 
 	public String getLateStartTime() {
 	public String getLateStartTime() {
 		return lateStartTime;
 		return lateStartTime;
@@ -167,4 +207,12 @@ public class AttendanceScheduleSetting extends SliceJpaObject {
 	public void setTopUnitName(String topUnitName) {
 	public void setTopUnitName(String topUnitName) {
 		this.topUnitName = topUnitName;
 		this.topUnitName = topUnitName;
 	}
 	}
+
+	public String getLateStartTimeAfternoon() { return lateStartTimeAfternoon; }
+
+	public void setLateStartTimeAfternoon(String lateStartTimeAfternoon) { this.lateStartTimeAfternoon = lateStartTimeAfternoon; }
+
+	public String getLeaveEarlyStartTimeMorning() { return leaveEarlyStartTimeMorning; }
+
+	public void setLeaveEarlyStartTimeMorning(String leaveEarlyStartTimeMorning) { this.leaveEarlyStartTimeMorning = leaveEarlyStartTimeMorning; }
 }
 }

+ 0 - 1
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/AttendanceSetting.java

@@ -71,7 +71,6 @@ public class AttendanceSetting extends SliceJpaObject {
 	public static final String configValue_FIELDNAME = "configValue";
 	public static final String configValue_FIELDNAME = "configValue";
 	@FieldDescribe("配置内容")
 	@FieldDescribe("配置内容")
 	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + configValue_FIELDNAME )
 	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + configValue_FIELDNAME )
-	@CheckPersist(allowEmpty = false)
 	private String configValue;
 	private String configValue;
 
 
 	public static final String valueType_FIELDNAME = "valueType";
 	public static final String valueType_FIELDNAME = "valueType";

+ 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("配置项名称")
 	@FieldDescribe("配置项名称")
-	@Column(name = "xconfigName", length = JpaObject.length_96B)
+	@Column(length = JpaObject.length_96B, name = ColumnNamePrefix + configName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String configName = "";
 	private String configName = "";
 
 
+	public static final String configYear_FIELDNAME = "configYear";
 	@FieldDescribe("配置年份")
 	@FieldDescribe("配置年份")
-	@Column(name = "xconfigYear", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String configYear = "2016";
 	private String configYear = "2016";
 
 
+	public static final String configMonth_FIELDNAME = "configMonth";
 	@FieldDescribe("配置月份")
 	@FieldDescribe("配置月份")
-	@Column(name = "xconfigMonth", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String configMonth = "";
 	private String configMonth = "";
 
 
+	public static final String configDate_FIELDNAME = "configDate";
 	@FieldDescribe("配置日期")
 	@FieldDescribe("配置日期")
-	@Column(name = "xconfigDate", length = JpaObject.length_32B)
+	@Column(length = JpaObject.length_32B, name = ColumnNamePrefix + configDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String configDate = "";
 	private String configDate = "";
 
 
+	public static final String configType_FIELDNAME = "configType";
 	@FieldDescribe("配置类型:Holiday|Workday")
 	@FieldDescribe("配置类型:Holiday|Workday")
-	@Column(name = "xconfigType", length = JpaObject.length_16B)
+	@Column(length = JpaObject.length_16B, name = ColumnNamePrefix + configType_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String configType = "Holiday";
 	private String configType = "Holiday";
 
 
+	public static final String description_FIELDNAME = "description";
 	@FieldDescribe("配置说明")
 	@FieldDescribe("配置说明")
-	@Column(name = "xdescription", length = JpaObject.length_255B)
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + description_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String description = "";
 	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("场所名称")
 	@FieldDescribe("场所名称")
-	@Column(name = "xplaceName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + placeName_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String placeName = "";
 	private String placeName = "";
 
 
+	public static final String placeAlias_FIELDNAME = "placeAlias";
 	@FieldDescribe("场所别名")
 	@FieldDescribe("场所别名")
-	@Column(name = "xplaceAlias", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + placeAlias_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String placeAlias = "";
 	private String placeAlias = "";
 
 
+	public static final String creator_FIELDNAME = "creator";
 	@FieldDescribe("创建人")
 	@FieldDescribe("创建人")
-	@Column(name = "xcreator", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + creator_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String creator = "";
 	private String creator = "";
 
 
+	public static final String longitude_FIELDNAME = "longitude";
 	@FieldDescribe("经度")
 	@FieldDescribe("经度")
-	@Column(name = "xlongitude", length = JpaObject.length_32B)
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + longitude_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String longitude = null;
 	private String longitude = null;
 
 
+	public static final String latitude_FIELDNAME = "latitude";
 	@FieldDescribe("纬度")
 	@FieldDescribe("纬度")
-	@Column(name = "xlatitude", length = JpaObject.length_32B)
+	@Column( length = JpaObject.length_32B, name = ColumnNamePrefix + latitude_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String latitude = null;
 	private String latitude = null;
 
 
+	public static final String errorRange_FIELDNAME = "errorRange";
 	@FieldDescribe("误差范围")
 	@FieldDescribe("误差范围")
-	@Column(name = "xerrorRange")
+	@Column( name = ColumnNamePrefix + errorRange_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private Integer errorRange = 200;
 	private Integer errorRange = 200;
 
 
+	public static final String description_FIELDNAME = "description";
 	@FieldDescribe("说明备注")
 	@FieldDescribe("说明备注")
-	@Column(name = "xdescription", length = JpaObject.length_255B)
+	@Column( length = JpaObject.length_255B, name = ColumnNamePrefix + description_FIELDNAME )
 	@CheckPersist(allowEmpty = true)
 	@CheckPersist(allowEmpty = true)
 	private String description = null;
 	private String description = null;
 
 

+ 126 - 198
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/DateOperation.java

@@ -8,8 +8,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.List;
 
 
 
 
-
-public class DateOperation {
+class DateOperation {
 	/**
 	/**
 	 * 根据样式得到格式化对象SimpleDateFormat
 	 * 根据样式得到格式化对象SimpleDateFormat
 	 * @param date
 	 * @param date
@@ -150,27 +149,26 @@ public class DateOperation {
 		}
 		}
 		return dateString;
 		return dateString;
 	}
 	}
-	
-	/**
-	 * 得到某日期加上或减去天数后的日期,day为负数时减去
-	 * 
-	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd"
-	 * @throws Exception 
+
+    /**
+     * 得到某日期加上或减去天数后的日期,day为负数时减去
+	 * @param dateString
+     * @param day
+     * @param style
+     * @return
+     * @throws Exception
 	 */
 	 */
 	public  String getDayAdd(String dateString, int day, String style) throws Exception {
 	public  String getDayAdd(String dateString, int day, String style) throws Exception {
 		Date date = getDateFromString(dateString, style);
 		Date date = getDateFromString(dateString, style);
 		return getDayAdd(date, day);
 		return getDayAdd(date, day);
 	}
 	}
-	
-	/**
-	 * 得到某日期加上或减去天数后的日期,day为负数时减去
-	 * 
+
+    /**
+     * 得到某日期加上或减去天数后的日期,day为负数时减去
 	 * @param date
 	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd"
-	 */
+     * @param day
+     * @return
+     */
 	public  String getDayAdd(Date date, int day) {
 	public  String getDayAdd(Date date, int day) {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
 		calendar.setTime(date);
 		calendar.setTime(date);
@@ -191,27 +189,25 @@ public class DateOperation {
 		calendar.add(Calendar.MONTH, month);
 		calendar.add(Calendar.MONTH, month);
 		return format1.format(calendar.getTime());
 		return format1.format(calendar.getTime());
 	}
 	}
-	
-	/**
-	 * 得到某日期加上或减去分钟后的日期,min为负数时减去
-	 * 
+
+    /**
+     * 得到某日期加上或减去分钟后的日期,min为负数时减去
 	 * @param date
 	 * @param date
-	 * @param month
-	 * @return "yyyy-MM-dd HH:mi:ss"
-	 */
+     * @param min
+     * @return
+     */
 	public  String getMinutesAdd(Date date, int min) {
 	public  String getMinutesAdd(Date date, int min) {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
 		calendar.setTime(date);
 		calendar.setTime(date);
 		calendar.add(Calendar.MINUTE, min);
 		calendar.add(Calendar.MINUTE, min);
 		return format3.format(calendar.getTime());
 		return format3.format(calendar.getTime());
 	}
 	}
-	/**
-	 * 得到某日期的日
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+
+    /**
+     * 得到某日期的日
+	 * @param date
+     * @return
+     */
 	public  String getDay(Date date) {
 	public  String getDay(Date date) {
 		try{
 		try{
 			return format10.format(date);
 			return format10.format(date);
@@ -228,13 +224,12 @@ public class DateOperation {
 		}
 		}
 		return Integer.parseInt(result);
 		return Integer.parseInt(result);
 	}
 	}
-	/**
-	 * 得到某日期的月份
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+
+    /**
+     * 得到某日期的月份
+	 * @param date
+     * @return
+     */
 	public  String getMonth(Date date) {
 	public  String getMonth(Date date) {
 		try{
 		try{
 			return format9.format(date);
 			return format9.format(date);
@@ -253,12 +248,10 @@ public class DateOperation {
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某日期的年份
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+     * 得到某日期的年份
+	 * @param date
+     * @return
+     */
 	public  String getYear(Date date) {
 	public  String getYear(Date date) {
 		try{
 		try{
 			return format8.format(date);
 			return format8.format(date);
@@ -275,13 +268,12 @@ public class DateOperation {
 		}
 		}
 		return Integer.parseInt(result);
 		return Integer.parseInt(result);
 	}
 	}
-	/**
-	 * 得到某日期的小时
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+
+    /**
+     * 得到某日期的小时
+	 * @param date
+     * @return
+     */
 	public  String getHour(Date date) {
 	public  String getHour(Date date) {
 		try{
 		try{
 			return format11.format(date);
 			return format11.format(date);
@@ -289,48 +281,43 @@ public class DateOperation {
 			return "0";
 			return "0";
 		}
 		}
 	}
 	}
-	/**
-	 * 得到某日期的分钟
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+
+    /**
+     * 得到某日期的分钟
+	 * @param date
+     * @return
+     */
 	public  String getMinites(Date date) {
 	public  String getMinites(Date date) {
 		return format12.format(date);
 		return format12.format(date);
 	}
 	}
-	/**
-	 * 得到某日期的秒
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 */
+
+    /**
+     * 得到某日期的秒
+	 * @param date
+     * @return
+     */
 	public  String getSeconds(Date date) {
 	public  String getSeconds(Date date) {
 		return format13.format(date);
 		return format13.format(date);
 	}
 	}
-	/**
-	 * 得到某年有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM-dd"
-	 * @return
-	 * @throws ParseException
+
+    /**
+     * 得到某年有多少天
+	 * @param date
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	@SuppressWarnings("static-access")
 	@SuppressWarnings("static-access")
-	public int getDaysForYear(String date) throws ParseException {
+	public  int getDaysForYear(String date) throws ParseException {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
-		calendar.setTime( format1.parse(date) );
+		calendar.setTime(format1.parse(date));
 		return calendar.get(calendar.DAY_OF_YEAR);
 		return calendar.get(calendar.DAY_OF_YEAR);
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某年有多少天
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 * @throws ParseException
+     * 得到某年有多少天
+	 * @param date
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	@SuppressWarnings("static-access")
 	@SuppressWarnings("static-access")
 	public  int getDaysForYear(Date date) throws ParseException {
 	public  int getDaysForYear(Date date) throws ParseException {
@@ -340,12 +327,10 @@ public class DateOperation {
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某年有多少天
-	 * 
-	 * @param String
-	 *            year "yyyy"
-	 * @return
-	 * @throws ParseException
+     * 得到某年有多少天
+	 * @param year
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	@SuppressWarnings("static-access")
 	@SuppressWarnings("static-access")
 	public  int getDaysForYear_YYYY(String year) throws ParseException {
 	public  int getDaysForYear_YYYY(String year) throws ParseException {
@@ -355,12 +340,10 @@ public class DateOperation {
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某月有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM-dd"
-	 * @return
-	 * @throws ParseException
+     * 得到某月有多少天
+	 * @param date
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	public  int getDaysForMonth(String date) throws ParseException {
 	public  int getDaysForMonth(String date) throws ParseException {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
@@ -369,12 +352,10 @@ public class DateOperation {
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某月有多少天
-	 * 
-	 * @param String
-	 *            date "yyyy-MM"
-	 * @return
-	 * @throws ParseException
+     * 得到某月有多少天
+	 * @param date
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	@SuppressWarnings("static-access")
 	@SuppressWarnings("static-access")
 	public  int getDaysForMonth_MM(String date) throws ParseException {
 	public  int getDaysForMonth_MM(String date) throws ParseException {
@@ -384,12 +365,10 @@ public class DateOperation {
 	}
 	}
 
 
 	/**
 	/**
-	 * 得到某月有多少天
-	 * 
-	 * @param Date
-	 *            date
-	 * @return
-	 * @throws ParseException
+     * 得到某月有多少天
+	 * @param date
+     * @return
+     * @throws ParseException
 	 */
 	 */
 	public  int getDaysForMonth(Date date) throws ParseException {
 	public  int getDaysForMonth(Date date) throws ParseException {
 		Calendar calendar = Calendar.getInstance();
 		Calendar calendar = Calendar.getInstance();
@@ -435,8 +414,9 @@ public class DateOperation {
 	 * @param date1 yyyy-MM-dd HH:mm:ss
 	 * @param date1 yyyy-MM-dd HH:mm:ss
 	 * @param date2 yyyy-MM-dd HH:mm:ss
 	 * @param date2 yyyy-MM-dd HH:mm:ss
 	 * @return
 	 * @return
+	 * @throws ParseException 
 	 */
 	 */
-	public  long getDeff(String date1,String date2) {
+	public  long getDeff(String date1,String date2) throws ParseException {
 		long dayNumber = 0;
 		long dayNumber = 0;
 		// 1小时=60分钟=3600秒=3600000
 		// 1小时=60分钟=3600秒=3600000
 		long mins = 60L * 1000L;
 		long mins = 60L * 1000L;
@@ -451,13 +431,9 @@ public class DateOperation {
 		}else{
 		}else{
 			df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 			df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 		}
 		}
-		try {
-			java.util.Date d1 = df.parse(date1);
-			java.util.Date d2 = df.parse(date2);
-			dayNumber = (d2.getTime() - d1.getTime()) / mins;
-		} catch (Exception e) {
-			//logger.error( "系统获取得到两个时间之前的分差发生异常",  e);
-		}
+		Date d1 = df.parse(date1);
+		Date d2 = df.parse(date2);
+		dayNumber = (d2.getTime() - d1.getTime()) / mins;
 		return dayNumber;
 		return dayNumber;
 	}
 	}
 	/**
 	/**
@@ -468,24 +444,18 @@ public class DateOperation {
 	 */
 	 */
 	public long getDeff(Date date1,Date date2) {
 	public long getDeff(Date date1,Date date2) {
 		long dayNumber = 0;
 		long dayNumber = 0;
-		// 1小时=60分钟=3600秒=3600000
 		long mins = 60L * 1000L;
 		long mins = 60L * 1000L;
-		// long day= 24L * 60L * 60L * 1000L;计算天数之差
-		try {
-			dayNumber = (date2.getTime() - date1.getTime()) / mins;
-		} catch (Exception e) {
-			//logger.error( "系统获取得到两个时间之前的分差发生异常",  e);
-		}
+		dayNumber = (date2.getTime() - date1.getTime()) / mins;
 		return dayNumber;
 		return dayNumber;
 	}
 	}
-	/**
-	 * 
-	 * 日期格式转换
-	 * 从YYYY-MM-DD转换到YYYYMMDD
-	 * @param date
-	 * @throws ParseException 
+
+    /**
+     * 日期格式转换 从YYYY-MM-DD转换到YYYYMMDD
+	 * @param dateString
+     * @return
+     * @throws ParseException
 	 */
 	 */
-	public  String changeDateFormat(String dateString){
+	public  String changeDateFormat(String dateString) throws ParseException{
 		Date date;
 		Date date;
 		String reslut = null;
 		String reslut = null;
 		try {
 		try {
@@ -495,14 +465,8 @@ public class DateOperation {
 			date = format1.parse(dateString);
 			date = format1.parse(dateString);
 			reslut = format5.format(date);
 			reslut = format5.format(date);
 		} catch (ParseException e) {
 		} catch (ParseException e) {
-			try {
-				date = format1.parse("0000-00-00");
-			} catch (ParseException e1) {
-				//logger.error( "系统日期格式转换发生异常",  e1);
-			}
-			//logger.error( "系统日期格式转换发生异常",  e);
+			date = format1.parse("0000-00-00");
 		}
 		}
-		
 		return reslut;
 		return reslut;
 	}
 	}
 	
 	
@@ -539,41 +503,27 @@ public class DateOperation {
 	public  final SimpleDateFormat format14 = new SimpleDateFormat("yyyy-MM");
 	public  final SimpleDateFormat format14 = new SimpleDateFormat("yyyy-MM");
 	
 	
 	
 	
-	public  String getStartOfWeek(String dateString){
+	public  String getStartOfWeek(String dateString) throws Exception{
 		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
 		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
-		try {
-			Date date = format.parse(dateString);
-			Calendar cal = Calendar.getInstance();
-			cal.setTime(date);
-			cal.setFirstDayOfWeek(Calendar.MONDAY);
-			int tmp = cal.get(Calendar.DAY_OF_WEEK) - 1;
-			if (0 == tmp) {
-				tmp = 7;
-			}
-			cal.add(Calendar.DATE, -(tmp-1));
-			return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 00:00:00";
-		} catch (ParseException e) {
-			//logger.error( "系统getStartOfWeek日期格式转换发生异常",  e);
-		} catch (Exception e) {
-			//logger.error( "系统getStartOfWeek发生异常",  e);
+		Date date = format.parse(dateString);
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.setFirstDayOfWeek(Calendar.MONDAY);
+		int tmp = cal.get(Calendar.DAY_OF_WEEK) - 1;
+		if (0 == tmp) {
+			tmp = 7;
 		}
 		}
-		return null;
+		cal.add(Calendar.DATE, -(tmp-1));
+		return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 00:00:00";
 	}
 	}
 	
 	
-	public  String getEndOfWeek(String dateString){
-		try {
-			Date date = getDateFromString(getStartOfWeek(dateString), "yyyy-MM-dd HH:mm:ss");
-			Calendar cal = Calendar.getInstance();
-			cal.setTime(date);
-			cal.setFirstDayOfWeek(Calendar.MONDAY);
-			cal.add(Calendar.DATE, 6);
-			return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 23:59:59";
-		} catch (ParseException e) {
-			e.printStackTrace();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-		return null;
+	public  String getEndOfWeek(String dateString) throws Exception{
+		Date date = getDateFromString(getStartOfWeek(dateString), "yyyy-MM-dd HH:mm:ss");
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.setFirstDayOfWeek(Calendar.MONDAY);
+		cal.add(Calendar.DATE, 6);
+		return getDateStringFromDate(cal.getTime(), "yyyy-MM-dd") + " 23:59:59";
 	}
 	}
 	
 	
 	
 	
@@ -588,11 +538,7 @@ public class DateOperation {
 	public String getDateCNString( String dateString, String style ) throws Exception{
 	public String getDateCNString( String dateString, String style ) throws Exception{
 		StringBuffer ch_date_string = new StringBuffer();
 		StringBuffer ch_date_string = new StringBuffer();
 		Date _date = null;
 		Date _date = null;
-		try{
-			_date = getDateFromString( dateString, style );
-		}catch(Exception e){
-			//logger.error( "系统getDateCNString日期格式转换发生异常",  e);
-		}
+		_date = getDateFromString( dateString, style );
 		if(_date == null ){
 		if(_date == null ){
 			_date = new Date();
 			_date = new Date();
 		}
 		}
@@ -624,11 +570,7 @@ public class DateOperation {
 	public String getDateCNString2( String dateString, String style ) throws Exception{
 	public String getDateCNString2( String dateString, String style ) throws Exception{
 		StringBuffer ch_date_string = new StringBuffer();
 		StringBuffer ch_date_string = new StringBuffer();
 		Date _date = null;
 		Date _date = null;
-		try{
-			_date = getDateFromString( dateString, style );
-		}catch(Exception e){
-		//	logger.error( "系统getDateCNString2日期格式转换发生异常",  e);
-		}
+		_date = getDateFromString( dateString, style );
 		if(_date == null ){
 		if(_date == null ){
 			_date = new Date();
 			_date = new Date();
 		}
 		}
@@ -658,28 +600,14 @@ public class DateOperation {
 	 * 结果从1开始
 	 * 结果从1开始
 	 * @param dateString yyyy-mm-dd
 	 * @param dateString yyyy-mm-dd
 	 * @return
 	 * @return
+	 * @throws Exception 
 	 */
 	 */
-	public  int getWeekNumOfYear( String dateString ){
-		try {
-			Date date = getDateFromString( dateString , "yyyy-MM-dd");
-			Calendar cal = Calendar.getInstance();
-			cal.setTime(date);
-			cal.setFirstDayOfWeek(2);//设置每周的第一天是星期一
-	        //月份有问题(这里的月份开始计数为0)
-	        //本年的第几天,在计算时间间隔的时候有用
-	        //System.out.println("一年中的天数:" + cal.get(Calendar.DAY_OF_YEAR));
-	        //System.out.println("一年中的周数:" + cal.get(Calendar.WEEK_OF_YEAR));
-	        //即本月的第几周
-	        //System.out.println("一月中的周数:" + cal.get(Calendar.WEEK_OF_MONTH));
-	        //即一周中的第几天(这里是以周日为第一天的)
-	        //System.out.println("一周中的天数:" + cal.get(Calendar.DAY_OF_WEEK));
-			return cal.get(Calendar.WEEK_OF_YEAR);
-		} catch (ParseException e) {
-			//logger.error( "系统getWeekNumOfYear日期格式转换发生异常",  e);
-		} catch (Exception e) {
-			//logger.error( "系统getWeekNumOfYear发生异常",  e);
-		}
-		return -1;
+	public  int getWeekNumOfYear( String dateString ) throws Exception{
+		Date date = getDateFromString( dateString , "yyyy-MM-dd");
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.setFirstDayOfWeek(2); //设置每周的第一天是星期一
+		return cal.get(Calendar.WEEK_OF_YEAR);
 	}
 	}
 	
 	
 	/**
 	/**
@@ -687,7 +615,7 @@ public class DateOperation {
 	 * @param recordDate
 	 * @param recordDate
 	 * @return
 	 * @return
 	 */
 	 */
-	public boolean isWeekend(Date recordDate) {
+	public boolean isWeekend( Date recordDate ) {
 		Calendar cal = Calendar.getInstance();
 		Calendar cal = Calendar.getInstance();
 	    cal.setTime( recordDate );
 	    cal.setTime( recordDate );
 	    if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
 	    if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
@@ -751,7 +679,7 @@ public class DateOperation {
 		}
 		}
 		return result;
 		return result;
 	}
 	}
-
+	
 	/**
 	/**
 	 * 获取日期所在月份的第一天
 	 * 获取日期所在月份的第一天
 	 * @param recordDate
 	 * @param recordDate
@@ -803,7 +731,7 @@ public class DateOperation {
 	 * @throws Exception 
 	 * @throws Exception 
 	 */
 	 */
 	public Date getLastDateInMonth(Date recordDate) throws Exception {
 	public Date getLastDateInMonth(Date recordDate) throws Exception {
-		Date lastDate = getLastDayOfMonth(recordDate);
+		Date lastDate = getLastDayOfMonth( recordDate );
 		return getDateFromString( getDateStringFromDate( lastDate, "yyyy-MM-dd") );
 		return getDateFromString( getDateStringFromDate( lastDate, "yyyy-MM-dd") );
 	}
 	}
 	
 	

+ 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("同步开始时间")
     @FieldDescribe("同步开始时间")
-    @Column(name = ColumnNamePrefix + "syncStartTime")
+    @Column( name = ColumnNamePrefix + startTime_FIELDNAME )
     private Date startTime;
     private Date startTime;
 
 
+    public static final String endTime_FIELDNAME = "endTime";
     @FieldDescribe("同步结束时间")
     @FieldDescribe("同步结束时间")
-    @Column(name = ColumnNamePrefix + "syncEndTime")
+    @Column( name = ColumnNamePrefix + endTime_FIELDNAME )
     private Date endTime;
     private Date endTime;
 
 
     public static final String syncType_qywx = "qywx";
     public static final String syncType_qywx = "qywx";
     public static final String syncType_dingding = "dingding";
     public static final String syncType_dingding = "dingding";
+    public static final String type_FIELDNAME = "type";
     @FieldDescribe("同步类型,qywx(企业微信同步) , dingding(钉钉同步)")
     @FieldDescribe("同步类型,qywx(企业微信同步) , dingding(钉钉同步)")
-    @Column(name = ColumnNamePrefix + "type", length = length_32B)
+    @Column( length = length_32B, name = ColumnNamePrefix + type_FIELDNAME )
     private String type;
     private String type;
 
 
+    public static final String dateFrom_FIELDNAME = "dateFrom";
     @FieldDescribe("同步打卡记录的开始时间")
     @FieldDescribe("同步打卡记录的开始时间")
-    @Column(name = ColumnNamePrefix + "dateFrom")
+    @Column( name = ColumnNamePrefix + dateFrom_FIELDNAME )
     private long dateFrom;
     private long dateFrom;
 
 
+    public static final String dateTo_FIELDNAME = "dateTo";
     @FieldDescribe("同步打卡记录的结束时间, 起始与结束工作日最多相隔7天")
     @FieldDescribe("同步打卡记录的结束时间, 起始与结束工作日最多相隔7天")
-    @Column(name = ColumnNamePrefix + "dateTo")
+    @Column( name = ColumnNamePrefix + dateTo_FIELDNAME )
     private long dateTo;
     private long dateTo;
 
 
     public static final String status_loading = "loading";
     public static final String status_loading = "loading";
     public static final String status_end = "end";
     public static final String status_end = "end";
     public static final String status_error = "error";
     public static final String status_error = "error";
+    public static final String status_FIELDNAME = "status";
     @FieldDescribe("同步状态,loading(正在进行) , end(结束) , error(执行异常)")
     @FieldDescribe("同步状态,loading(正在进行) , end(结束) , error(执行异常)")
-    @Column(name = ColumnNamePrefix + "status", length = length_32B)
+    @Column( length = length_32B, name = ColumnNamePrefix + status_FIELDNAME )
     private String status;
     private String status;
 
 
-
+    public static final String exceptionMessage_FIELDNAME = "exceptionMessage";
     @FieldDescribe("异常信息")
     @FieldDescribe("异常信息")
-    @Column(name = ColumnNamePrefix + "exceptionMessage", length = length_255B)
+    @Column( length = length_255B, name = ColumnNamePrefix + exceptionMessage_FIELDNAME )
     private String exceptionMessage;
     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用户")
 	@FieldDescribe("O2用户")
-	@Column(name = ColumnNamePrefix + "o2User", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2User_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2User;
 	private String o2User;
 
 
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 	private String o2Unit;
 
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到次数")
 	@FieldDescribe("严重迟到次数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 	private Long seriousLateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
-
 	public Long getResultNormal() {
 	public Long getResultNormal() {
 		return resultNormal;
 		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用户所在的组织")
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 	private String o2Unit;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 	private String statisticDate;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤人数")
 	@FieldDescribe("出勤人数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到人数")
 	@FieldDescribe("上班签到人数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到人数")
 	@FieldDescribe("下班签到人数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
-
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到人数")
 	@FieldDescribe("严重迟到人数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 	private Long seriousLateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工人数")
 	@FieldDescribe("旷工人数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡人数")
 	@FieldDescribe("未打卡人数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
-
 	public Long getResultNormal() {
 	public Long getResultNormal() {
 		return resultNormal;
 		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用户所在的组织")
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 	private String o2Unit;
 
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到人数")
 	@FieldDescribe("上班签到人数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到人数")
 	@FieldDescribe("下班签到人数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String seriousLateTimes_FIELDNAME = "seriousLateTimes";
 	@FieldDescribe("严重迟到人数")
 	@FieldDescribe("严重迟到人数")
-	@Column(name = "xSeriousLateTimes")
+	@Column( name = ColumnNamePrefix + seriousLateTimes_FIELDNAME )
 	private Long seriousLateTimes;
 	private Long seriousLateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工人数")
 	@FieldDescribe("旷工人数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡人数")
 	@FieldDescribe("未打卡人数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
 	public Long getResultNormal() {
 	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("员工姓名")
 	@FieldDescribe("员工姓名")
-	@Column(name = "xemployeeName", length = JpaObject.length_96B)
+	@Column( length = JpaObject.length_96B, name = ColumnNamePrefix + employeeName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String employeeName;
 	private String employeeName;
 
 
+	public static final String unitName_FIELDNAME = "unitName";
 	@FieldDescribe("组织名称")
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 	private String unitName;
 
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 	private String topUnitName;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("应出勤天数")
 	@FieldDescribe("应出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Double workDayCount;
 	private Double workDayCount;
 
 
+	public static final String onDutyDayCount_FIELDNAME = "onDutyDayCount";
 	@FieldDescribe("实际出勤天数")
 	@FieldDescribe("实际出勤天数")
-	@Column(name = "xonDutyDayCount")
+	@Column( name = ColumnNamePrefix + onDutyDayCount_FIELDNAME )
 	private Double onDutyDayCount;
 	private Double onDutyDayCount;
 
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤天数")
 	@FieldDescribe("缺勤天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 	private Double absenceDayCount;
 
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假天数")
 	@FieldDescribe("休假天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 	private Double onSelfHolidayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("签到次数")
 	@FieldDescribe("签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("签退次数")
 	@FieldDescribe("签退次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足次数")
 	@FieldDescribe("工时不足次数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 	private Long lackOfTimeCount;
 
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 	private Long abNormalDutyCount;
 
 
 	public String getEmployeeName() {
 	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用户")
 	@FieldDescribe("O2用户")
-	@Column(name = ColumnNamePrefix + "o2User", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2User_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2User;
 	private String o2User;
 
 
+	public static final String o2Unit_FIELDNAME = "o2Unit";
 	@FieldDescribe("O2用户所在的组织")
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 	private String o2Unit;
 
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 	private Long outsideDutyTimes;
 
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
 	public Long getOutsideDutyTimes() {
 	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用户所在的组织")
 	@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;
 	private String o2Unit;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@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;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
 	@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;
 	private String statisticDate;
 
 
+	public static final String workDayCount_FIELDNAME = "workDayCount";
 	@FieldDescribe("出勤天数")
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + workDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 	private Long outsideDutyTimes;
 
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
-
 	public Long getResultNormal() {
 	public Long getResultNormal() {
 		return resultNormal;
 		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用户所在的组织")
 	@FieldDescribe("O2用户所在的组织")
-	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@Column( length = length_128B, name = ColumnNamePrefix + o2Unit_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String o2Unit;
 	private String o2Unit;
 
 
-
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String xworkDayCount_FIELDNAME = "xworkDayCount";
 	@FieldDescribe("出勤天数")
 	@FieldDescribe("出勤天数")
-	@Column(name = "xworkDayCount")
+	@Column( name = ColumnNamePrefix + xworkDayCount_FIELDNAME )
 	private Long workDayCount;
 	private Long workDayCount;
 
 
+	public static final String onDutyTimes_FIELDNAME = "onDutyTimes";
 	@FieldDescribe("上班签到次数")
 	@FieldDescribe("上班签到次数")
-	@Column(name = "xonDutyTimes")
+	@Column( name = ColumnNamePrefix + onDutyTimes_FIELDNAME )
 	private Long onDutyTimes;
 	private Long onDutyTimes;
 
 
+	public static final String offDutyTimes_FIELDNAME = "offDutyTimes";
 	@FieldDescribe("下班签到次数")
 	@FieldDescribe("下班签到次数")
-	@Column(name = "xoffDutyTimes")
+	@Column( name = ColumnNamePrefix + offDutyTimes_FIELDNAME )
 	private Long offDutyTimes;
 	private Long offDutyTimes;
 
 
+	public static final String outsideDutyTimes_FIELDNAME = "outsideDutyTimes";
 	@FieldDescribe("外出签到次数")
 	@FieldDescribe("外出签到次数")
-	@Column(name = "xoutsideDutyTimes")
+	@Column( name = ColumnNamePrefix + outsideDutyTimes_FIELDNAME )
 	private Long outsideDutyTimes;
 	private Long outsideDutyTimes;
 
 
+	public static final String resultNormal_FIELDNAME = "resultNormal";
 	@FieldDescribe("正常签到次数")
 	@FieldDescribe("正常签到次数")
-	@Column(name = "xresultNormal")
+	@Column( name = ColumnNamePrefix + resultNormal_FIELDNAME )
 	private Long resultNormal;
 	private Long resultNormal;
 
 
+	public static final String lateTimes_FIELDNAME = "lateTimes";
 	@FieldDescribe("迟到次数")
 	@FieldDescribe("迟到次数")
-	@Column(name = "xlateTimes")
+	@Column( name = ColumnNamePrefix + lateTimes_FIELDNAME )
 	private Long lateTimes;
 	private Long lateTimes;
 
 
+	public static final String leaveEarlyTimes_FIELDNAME = "leaveEarlyTimes";
 	@FieldDescribe("早退次数")
 	@FieldDescribe("早退次数")
-	@Column(name = "xleaveEarlyTimes")
+	@Column( name = ColumnNamePrefix + leaveEarlyTimes_FIELDNAME )
 	private Long leaveEarlyTimes;
 	private Long leaveEarlyTimes;
 
 
+	public static final String absenteeismTimes_FIELDNAME = "absenteeismTimes";
 	@FieldDescribe("旷工次数")
 	@FieldDescribe("旷工次数")
-	@Column(name = "xAbsenteeismTimes")
+	@Column( name = ColumnNamePrefix + absenteeismTimes_FIELDNAME )
 	private Long absenteeismTimes;
 	private Long absenteeismTimes;
 
 
+	public static final String notSignedCount_FIELDNAME = "notSignedCount";
 	@FieldDescribe("未打卡次数")
 	@FieldDescribe("未打卡次数")
-	@Column(name = "xNotSignedCount")
+	@Column( name = ColumnNamePrefix + notSignedCount_FIELDNAME )
 	private Long notSignedCount;
 	private Long notSignedCount;
 
 
 	public Long getResultNormal() {
 	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("顶层组织名称")
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 	private String topUnitName;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 	private String statisticDate;
 
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 	private Double employeeCount;
 
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 	private Double onDutyEmployeeCount;
 
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人数")
 	@FieldDescribe("缺勤人数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 	private Double absenceDayCount;
 
 
+	public static final String onSelfHolidayEmployeeCount_FIELDNAME = "onSelfHolidayEmployeeCount";
 	@FieldDescribe("休假人数")
 	@FieldDescribe("休假人数")
-	@Column(name = "xonSelfHolidayEmployeeCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayEmployeeCount_FIELDNAME )
 	private Double onSelfHolidayEmployeeCount;
 	private Double onSelfHolidayEmployeeCount;
 
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 	private Long onDutyCount;
 
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 	private Long offDutyCount;
 
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 	private Long lateCount;
 
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 	private Long leaveEarlyCount;
 
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人数")
 	@FieldDescribe("工时不足人数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 	private Long lackOfTimeCount;
 
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 	private Long abNormalDutyCount;
 
 
 	public String getTopUnitName() {
 	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("顶层组织名称")
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 	private String topUnitName;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人天数")
 	@FieldDescribe("应出勤人天数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 	private Double employeeCount;
 
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人天数")
 	@FieldDescribe("实际出勤人天数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 	private Double onDutyEmployeeCount;
 
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人天数")
 	@FieldDescribe("缺勤人天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 	private Double absenceDayCount;
 
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假人天数")
 	@FieldDescribe("休假人天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 	private Double onSelfHolidayCount;
 
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 	private Long onDutyCount;
 
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 	private Long offDutyCount;
 
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 	private Long lateCount;
 
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 	private Long leaveEarlyCount;
 
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人次")
 	@FieldDescribe("工时不足人次")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 	private Long lackOfTimeCount;
 
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人次")
 	@FieldDescribe("异常打卡人次")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 	private Long abNormalDutyCount;
 
 
 	public String getTopUnitName() {
 	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("组织名称")
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 	private String unitName;
 
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 	private String topUnitName;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String statisticDate_FIELDNAME = "statisticDate";
 	@FieldDescribe("统计日期")
 	@FieldDescribe("统计日期")
-	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticDate_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticDate;
 	private String statisticDate;
 
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 	private Double employeeCount;
 
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 	private Double onDutyEmployeeCount;
 
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人数")
 	@FieldDescribe("缺勤人数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 	private Double absenceDayCount;
 
 
+	public static final String onSelfHolidayEmployeeCount_FIELDNAME = "onSelfHolidayEmployeeCount";
 	@FieldDescribe("休假人数")
 	@FieldDescribe("休假人数")
-	@Column(name = "xonSelfHolidayEmployeeCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayEmployeeCount_FIELDNAME )
 	private Double onSelfHolidayEmployeeCount;
 	private Double onSelfHolidayEmployeeCount;
 
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 	private Long onDutyCount;
 
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 	private Long offDutyCount;
 
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 	private Long lateCount;
 
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 	private Long leaveEarlyCount;
 
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人数")
 	@FieldDescribe("工时不足人数")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 	private Long lackOfTimeCount;
 
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 	private Long abNormalDutyCount;
 
 
 	public String getUnitName() {
 	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("组织名称")
 	@FieldDescribe("组织名称")
-	@Column(name = "xunitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + unitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String unitName;
 	private String unitName;
 
 
+	public static final String topUnitName_FIELDNAME = "topUnitName";
 	@FieldDescribe("顶层组织名称")
 	@FieldDescribe("顶层组织名称")
-	@Column(name = "xtopUnitName", length = AbstractPersistenceProperties.organization_name_length)
+	@Column( length = AbstractPersistenceProperties.organization_name_length, name = ColumnNamePrefix + topUnitName_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String topUnitName;
 	private String topUnitName;
 
 
+	public static final String statisticYear_FIELDNAME = "statisticYear";
 	@FieldDescribe("统计年份")
 	@FieldDescribe("统计年份")
-	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticYear_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticYear;
 	private String statisticYear;
 
 
+	public static final String statisticMonth_FIELDNAME = "statisticMonth";
 	@FieldDescribe("统计月份")
 	@FieldDescribe("统计月份")
-	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@Column( length = JpaObject.length_16B, name = ColumnNamePrefix + statisticMonth_FIELDNAME )
 	@CheckPersist(allowEmpty = false)
 	@CheckPersist(allowEmpty = false)
 	private String statisticMonth;
 	private String statisticMonth;
 
 
+	public static final String employeeCount_FIELDNAME = "employeeCount";
 	@FieldDescribe("应出勤人数")
 	@FieldDescribe("应出勤人数")
-	@Column(name = "xemployeeCount")
+	@Column( name = ColumnNamePrefix + employeeCount_FIELDNAME )
 	private Double employeeCount;
 	private Double employeeCount;
 
 
+	public static final String onDutyEmployeeCount_FIELDNAME = "onDutyEmployeeCount";
 	@FieldDescribe("实际出勤人数")
 	@FieldDescribe("实际出勤人数")
-	@Column(name = "xonDutyEmployeeCount")
+	@Column( name = ColumnNamePrefix + onDutyEmployeeCount_FIELDNAME )
 	private Double onDutyEmployeeCount;
 	private Double onDutyEmployeeCount;
 
 
+	public static final String absenceDayCount_FIELDNAME = "absenceDayCount";
 	@FieldDescribe("缺勤人天数")
 	@FieldDescribe("缺勤人天数")
-	@Column(name = "xabsenceDayCount")
+	@Column( name = ColumnNamePrefix + absenceDayCount_FIELDNAME )
 	private Double absenceDayCount;
 	private Double absenceDayCount;
 
 
+	public static final String onSelfHolidayCount_FIELDNAME = "onSelfHolidayCount";
 	@FieldDescribe("休假人天数")
 	@FieldDescribe("休假人天数")
-	@Column(name = "xonSelfHolidayCount")
+	@Column( name = ColumnNamePrefix + onSelfHolidayCount_FIELDNAME )
 	private Double onSelfHolidayCount;
 	private Double onSelfHolidayCount;
 
 
+	public static final String onDutyCount_FIELDNAME = "onDutyCount";
 	@FieldDescribe("签到人数")
 	@FieldDescribe("签到人数")
-	@Column(name = "xonDutyCount")
+	@Column( name = ColumnNamePrefix + onDutyCount_FIELDNAME )
 	private Long onDutyCount;
 	private Long onDutyCount;
 
 
+	public static final String offDutyCount_FIELDNAME = "offDutyCount";
 	@FieldDescribe("签退人数")
 	@FieldDescribe("签退人数")
-	@Column(name = "xoffDutyCount")
+	@Column( name = ColumnNamePrefix + offDutyCount_FIELDNAME )
 	private Long offDutyCount;
 	private Long offDutyCount;
 
 
+	public static final String lateCount_FIELDNAME = "lateCount";
 	@FieldDescribe("迟到人数")
 	@FieldDescribe("迟到人数")
-	@Column(name = "xlateCount")
+	@Column( name = ColumnNamePrefix + lateCount_FIELDNAME )
 	private Long lateCount;
 	private Long lateCount;
 
 
+	public static final String leaveEarlyCount_FIELDNAME = "leaveEarlyCount";
 	@FieldDescribe("早退人数")
 	@FieldDescribe("早退人数")
-	@Column(name = "xleaveEarlyCount")
+	@Column( name = ColumnNamePrefix + leaveEarlyCount_FIELDNAME )
 	private Long leaveEarlyCount;
 	private Long leaveEarlyCount;
 
 
+	public static final String lackOfTimeCount_FIELDNAME = "lackOfTimeCount";
 	@FieldDescribe("工时不足人次")
 	@FieldDescribe("工时不足人次")
-	@Column(name = "xlackOfTimeCount")
+	@Column( name = ColumnNamePrefix + lackOfTimeCount_FIELDNAME )
 	private Long lackOfTimeCount;
 	private Long lackOfTimeCount;
 
 
+	public static final String abNormalDutyCount_FIELDNAME = "abNormalDutyCount";
 	@FieldDescribe("异常打卡人数")
 	@FieldDescribe("异常打卡人数")
-	@Column(name = "xabNormalDutyCount")
+	@Column( name = ColumnNamePrefix + abNormalDutyCount_FIELDNAME )
 	private Long abNormalDutyCount;
 	private Long abNormalDutyCount;
 
 
 	public String getUnitName() {
 	public String getUnitName() {

+ 177 - 105
o2server/x_base_core_project/src/main/java/com/x/base/core/entity/StorageObject.java

@@ -16,6 +16,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.CacheStrategy;
 import org.apache.commons.vfs2.CacheStrategy;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
 import org.apache.commons.vfs2.FileSystemManager;
 import org.apache.commons.vfs2.FileSystemManager;
 import org.apache.commons.vfs2.FileSystemOptions;
 import org.apache.commons.vfs2.FileSystemOptions;
 import org.apache.commons.vfs2.cache.NullFilesCache;
 import org.apache.commons.vfs2.cache.NullFilesCache;
@@ -34,17 +35,14 @@ public abstract class StorageObject extends SliceJpaObject {
 
 
 	private static FileSystemManager FILESYSTEMANAGERINSTANCE;
 	private static FileSystemManager FILESYSTEMANAGERINSTANCE;
 
 
-	private FileSystemManager getFileSystemManager() throws Exception {
+	private synchronized FileSystemManager getFileSystemManager() throws Exception {
 		if (FILESYSTEMANAGERINSTANCE == null) {
 		if (FILESYSTEMANAGERINSTANCE == null) {
-			synchronized (StorageObject.class) {
-				if (FILESYSTEMANAGERINSTANCE == null) {
-					StandardFileSystemManager fs = new StandardFileSystemManager();
-					fs.setFilesCache(new NullFilesCache());
-					fs.setCacheStrategy(CacheStrategy.ON_RESOLVE);
-					fs.init();
-					FILESYSTEMANAGERINSTANCE = fs;
-				}
-			}
+			StandardFileSystemManager fs = new StandardFileSystemManager();
+			fs.setFilesCache(new NullFilesCache());
+			fs.setCacheStrategy(CacheStrategy.ON_RESOLVE);
+			fs.init();
+			FILESYSTEMANAGERINSTANCE = fs;
+
 		}
 		}
 		return FILESYSTEMANAGERINSTANCE;
 		return FILESYSTEMANAGERINSTANCE;
 	}
 	}
@@ -119,12 +117,13 @@ public abstract class StorageObject extends SliceJpaObject {
 		return this.updateContent(mapping, input);
 		return this.updateContent(mapping, input);
 	}
 	}
 
 
-	/** 更新Content内容 */
-	public Long updateContent(StorageMapping mapping, byte[] bytes) throws Exception {
-		try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
-			return updateContent(mapping, bais);
-		}
-	}
+	// /** 更新Content内容 */
+	// public Long updateContent(StorageMapping mapping, byte[] bytes) throws
+	// Exception {
+	// try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+	// return updateContent(mapping, bais);
+	// }
+	// }
 
 
 	/** 更新Content内容 */
 	/** 更新Content内容 */
 	public Long updateContent(StorageMapping mapping, byte[] bytes, String name) throws Exception {
 	public Long updateContent(StorageMapping mapping, byte[] bytes, String name) throws Exception {
@@ -148,6 +147,69 @@ public abstract class StorageObject extends SliceJpaObject {
 
 
 	/** 更新Content内容 */
 	/** 更新Content内容 */
 	public Long updateContent(StorageMapping mapping, InputStream input) throws Exception {
 	public Long updateContent(StorageMapping mapping, InputStream input) throws Exception {
+		return updateContent(mapping, IOUtils.toByteArray(input));
+		// long length = -1L;
+		// FileSystemManager manager = this.getFileSystemManager();
+		// String prefix = this.getPrefix(mapping);
+		// String path = this.path();
+		// if (StringUtils.isEmpty(path)) {
+		// throw new Exception("path can not be empty.");
+		// }
+		// FileSystemOptions options = this.getOptions(mapping);
+		// try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+		// /* 由于可以在传输过程中取消传输,先拷贝到内存 */
+		// IOUtils.copyLarge(input, baos);
+		// FileObject fo = null;
+		// OutputStream output = null;
+		// try {
+		// /*
+		// * 需要进行两次判断,在前端使用nginx分发的情况下,可能同时触发多个文件的上传,多个文件同时上传可能会同时创建文件的存储目录,会在后台导致错误
+		// * org.apache.commons.vfs2.FileSystemException: Could not create folder
+		// *
+		// "ftp://processPlatform:***@o2.server01.com:20040/20200601/1beb018a-5009-4baa-a9ef-7e903f9d48ef".
+		// * 这种情况下再次发起请求尝试获取文件可以解决这个问题.
+		// */
+		// try {
+		// fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options);
+		// output = fo.getContent().getOutputStream();
+		// } catch (FileSystemException fse) {
+		// // 此段代码全部关闭对象,并要进行webdav判断进行关闭。
+		// if (null != output) {
+		// output.close();
+		// }
+		// if (null != fo) {
+		// if (!Objects.equals(StorageProtocol.webdav, mapping.getProtocol())) {
+		// /* webdav关闭会试图去关闭commons.httpClient */
+		// manager.closeFileSystem(fo.getFileSystem());
+		// }
+		// fo.close();
+		// }
+		// fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options);
+		// output = fo.getContent().getOutputStream();
+		// }
+		// length = IOUtils.copyLarge(new ByteArrayInputStream(baos.toByteArray()),
+		// output);
+		// this.setLength(length);
+		// if (!Objects.equals(StorageProtocol.webdav, mapping.getProtocol())) {
+		// /* webdav关闭会试图去关闭commons.httpClient */
+		// manager.closeFileSystem(fo.getFileSystem());
+		// }
+		// } finally {
+		// if (null != output) {
+		// output.close();
+		// }
+		// if (null != fo) {
+		// fo.close();
+		// }
+		// }
+		// }
+		// this.setStorage(mapping.getName());
+		// this.setLastUpdateTime(new Date());
+		// return length;
+	}
+
+	/** 更新Content内容 */
+	public Long updateContent(StorageMapping mapping, byte[] bytes) throws Exception {
 		long length = -1L;
 		long length = -1L;
 		FileSystemManager manager = this.getFileSystemManager();
 		FileSystemManager manager = this.getFileSystemManager();
 		String prefix = this.getPrefix(mapping);
 		String prefix = this.getPrefix(mapping);
@@ -156,21 +218,31 @@ public abstract class StorageObject extends SliceJpaObject {
 			throw new Exception("path can not be empty.");
 			throw new Exception("path can not be empty.");
 		}
 		}
 		FileSystemOptions options = this.getOptions(mapping);
 		FileSystemOptions options = this.getOptions(mapping);
-		try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-			/* 由于可以在传输过程中取消传输,先拷贝到内存 */
-			IOUtils.copyLarge(input, baos);
+		/*
+		 * 需要进行两次判断,在前端使用nginx分发的情况下,可能同时触发多个文件的上传,多个文件同时上传可能会同时创建文件的存储目录,会在后台导致错误
+		 * org.apache.commons.vfs2.FileSystemException: Could not create folder
+		 * "ftp://processPlatform:***@o2.server01.com:20040/20200601/1beb018a-5009-4baa-a9ef-7e903f9d48ef".
+		 * 这种情况下再次发起请求尝试获取文件可以解决这个问题.
+		 */
+		for (int i = 0; i < 2; i++) {
 			try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options);
 			try (FileObject fo = manager.resolveFile(prefix + PATHSEPARATOR + path, options);
 					OutputStream output = fo.getContent().getOutputStream()) {
 					OutputStream output = fo.getContent().getOutputStream()) {
-				length = IOUtils.copyLarge(new ByteArrayInputStream(baos.toByteArray()), output);
+				length = IOUtils.copyLarge(new ByteArrayInputStream(bytes), output);
 				this.setLength(length);
 				this.setLength(length);
 				if (!Objects.equals(StorageProtocol.webdav, mapping.getProtocol())) {
 				if (!Objects.equals(StorageProtocol.webdav, mapping.getProtocol())) {
 					/* webdav关闭会试图去关闭commons.httpClient */
 					/* webdav关闭会试图去关闭commons.httpClient */
 					manager.closeFileSystem(fo.getFileSystem());
 					manager.closeFileSystem(fo.getFileSystem());
 				}
 				}
+				this.setStorage(mapping.getName());
+				this.setLastUpdateTime(new Date());
+				break;
+			} catch (FileSystemException fse) {
+				if (i != 0) {
+					// 第一次错误先跳过,直接执行第二次.如果第二次错误那么报错.
+					throw fse;
+				}
 			}
 			}
 		}
 		}
-		this.setStorage(mapping.getName());
-		this.setLastUpdateTime(new Date());
 		return length;
 		return length;
 	}
 	}
 
 
@@ -245,38 +317,38 @@ public abstract class StorageObject extends SliceJpaObject {
 			throw new Exception("storage protocol is null.");
 			throw new Exception("storage protocol is null.");
 		}
 		}
 		switch (mapping.getProtocol()) {
 		switch (mapping.getProtocol()) {
-		// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
-		// tar, temp, webdav, zip, cifs, mime;
-		case ftp:
-			// ftp://[ username[: password]@] hostname[: port][ relative-path]
-			prefix = "ftp://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
-					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
-					+ mapping.getPort();
-			break;
-		case ftps:
-			// ftps://[ username[: password]@] hostname[: port][ relative-path]
-			prefix = "ftps://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
-					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
-					+ mapping.getPort();
-			break;
-		case cifs:
-			// smb://[ username[: password]@] hostname[: port][ absolute-path]
-			prefix = "smb://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
-					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
-					+ mapping.getPort();
-			break;
-		case webdav:
-			// webdav://[ username[: password]@] hostname[: port][ absolute-path]
-			prefix = "webdav://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
-					+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
-					+ mapping.getPort();
-			break;
-		case file:
-			// [file://] absolute-path
-			prefix = "file://";
-			break;
-		default:
-			break;
+			// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
+			// tar, temp, webdav, zip, cifs, mime;
+			case ftp:
+				// ftp://[ username[: password]@] hostname[: port][ relative-path]
+				prefix = "ftp://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
+						+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+						+ mapping.getPort();
+				break;
+			case ftps:
+				// ftps://[ username[: password]@] hostname[: port][ relative-path]
+				prefix = "ftps://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
+						+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+						+ mapping.getPort();
+				break;
+			case cifs:
+				// smb://[ username[: password]@] hostname[: port][ absolute-path]
+				prefix = "smb://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
+						+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+						+ mapping.getPort();
+				break;
+			case webdav:
+				// webdav://[ username[: password]@] hostname[: port][ absolute-path]
+				prefix = "webdav://" + URLEncoder.encode(mapping.getUsername(), DefaultCharset.name) + ":"
+						+ URLEncoder.encode(mapping.getPassword(), DefaultCharset.name) + "@" + mapping.getHost() + ":"
+						+ mapping.getPort();
+				break;
+			case file:
+				// [file://] absolute-path
+				prefix = "file://";
+				break;
+			default:
+				break;
 		}
 		}
 		return prefix + (StringUtils.isEmpty(mapping.getPrefix()) ? "" : ("/" + mapping.getPrefix()));
 		return prefix + (StringUtils.isEmpty(mapping.getPrefix()) ? "" : ("/" + mapping.getPrefix()));
 	}
 	}
@@ -287,57 +359,57 @@ public abstract class StorageObject extends SliceJpaObject {
 			throw new Exception("storage protocol is null.");
 			throw new Exception("storage protocol is null.");
 		}
 		}
 		switch (mapping.getProtocol()) {
 		switch (mapping.getProtocol()) {
-		// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
-		// tar, temp, webdav, zip, cifs, mime;
-		case ftp:
-			FtpFileSystemConfigBuilder ftpBuilder = FtpFileSystemConfigBuilder.getInstance();
-			/*
-			 * 如果使用被动模式在阿里云centos7下会经常性出现无法连接 Caused by: java.net.ConnectException:
-			 * Connection timed out (Connection timed out) at
-			 * java.net.PlainSocketImpl.socketConnect(Native Method) at
-			 * java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
-			 * at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.
-			 * java:206) at
-			 * java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at
-			 * java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at
-			 * java.net.Socket.connect(Socket.java:589)
-			 */
-			ftpBuilder.setPassiveMode(opts, Config.vfs().getFtp().getPassive());
-			// builder.setPassiveMode(opts, false);
-			// builder.setPassiveMode(opts, true);
-			/** 强制不校验IP */
-			ftpBuilder.setRemoteVerification(opts, false);
-			// FtpFileType.BINARY is the default
-			ftpBuilder.setFileType(opts, FtpFileType.BINARY);
-			ftpBuilder.setConnectTimeout(opts, 10000);
-			ftpBuilder.setSoTimeout(opts, 10000);
-			ftpBuilder.setControlEncoding(opts, DefaultCharset.name);
-			break;
-		case ftps:
-			FtpsFileSystemConfigBuilder ftpsBuilder = FtpsFileSystemConfigBuilder.getInstance();
-			ftpsBuilder.setPassiveMode(opts, Config.vfs().getFtp().getPassive());
-			/** 强制不校验IP */
-			ftpsBuilder.setRemoteVerification(opts, false);
-			// FtpFileType.BINARY is the default
-			ftpsBuilder.setFileType(opts, FtpFileType.BINARY);
-			ftpsBuilder.setConnectTimeout(opts, 10000);
-			ftpsBuilder.setSoTimeout(opts, 10000);
-			ftpsBuilder.setControlEncoding(opts, DefaultCharset.name);
-			break;
-		case cifs:
-			break;
-		case webdav:
-			WebdavFileSystemConfigBuilder webdavBuilder = (WebdavFileSystemConfigBuilder) WebdavFileSystemConfigBuilder
-					.getInstance();
-			webdavBuilder.setConnectionTimeout(opts, 10000);
-			webdavBuilder.setSoTimeout(opts, 10000);
-			webdavBuilder.setUrlCharset(opts, DefaultCharset.name);
-			// webdavBuilder.setVersioning(opts, true);
-			break;
-		case file:
-			break;
-		default:
-			break;
+			// bzip2,file, ftp, ftps, gzip, hdfs, http, https, jar, ram, res, sftp,
+			// tar, temp, webdav, zip, cifs, mime;
+			case ftp:
+				FtpFileSystemConfigBuilder ftpBuilder = FtpFileSystemConfigBuilder.getInstance();
+				/*
+				 * 如果使用被动模式在阿里云centos7下会经常性出现无法连接 Caused by: java.net.ConnectException:
+				 * Connection timed out (Connection timed out) at
+				 * java.net.PlainSocketImpl.socketConnect(Native Method) at
+				 * java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
+				 * at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.
+				 * java:206) at
+				 * java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at
+				 * java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at
+				 * java.net.Socket.connect(Socket.java:589)
+				 */
+				ftpBuilder.setPassiveMode(opts, Config.vfs().getFtp().getPassive());
+				// builder.setPassiveMode(opts, false);
+				// builder.setPassiveMode(opts, true);
+				/** 强制不校验IP */
+				ftpBuilder.setRemoteVerification(opts, false);
+				// FtpFileType.BINARY is the default
+				ftpBuilder.setFileType(opts, FtpFileType.BINARY);
+				ftpBuilder.setConnectTimeout(opts, 10000);
+				ftpBuilder.setSoTimeout(opts, 10000);
+				ftpBuilder.setControlEncoding(opts, DefaultCharset.name);
+				break;
+			case ftps:
+				FtpsFileSystemConfigBuilder ftpsBuilder = FtpsFileSystemConfigBuilder.getInstance();
+				ftpsBuilder.setPassiveMode(opts, Config.vfs().getFtp().getPassive());
+				/** 强制不校验IP */
+				ftpsBuilder.setRemoteVerification(opts, false);
+				// FtpFileType.BINARY is the default
+				ftpsBuilder.setFileType(opts, FtpFileType.BINARY);
+				ftpsBuilder.setConnectTimeout(opts, 10000);
+				ftpsBuilder.setSoTimeout(opts, 10000);
+				ftpsBuilder.setControlEncoding(opts, DefaultCharset.name);
+				break;
+			case cifs:
+				break;
+			case webdav:
+				WebdavFileSystemConfigBuilder webdavBuilder = (WebdavFileSystemConfigBuilder) WebdavFileSystemConfigBuilder
+						.getInstance();
+				webdavBuilder.setConnectionTimeout(opts, 10000);
+				webdavBuilder.setSoTimeout(opts, 10000);
+				webdavBuilder.setUrlCharset(opts, DefaultCharset.name);
+				// webdavBuilder.setVersioning(opts, true);
+				break;
+			case file:
+				break;
+			default:
+				break;
 		}
 		}
 		return opts;
 		return opts;
 	}
 	}

+ 15 - 21
o2server/x_base_core_project/src/main/java/com/x/base/core/project/build/CreateConfigSample.java

@@ -11,28 +11,26 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.commons.lang3.reflect.MethodUtils;
-
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.annotation.FieldDescribe;
 import com.x.base.core.project.config.AppStyle;
 import com.x.base.core.project.config.AppStyle;
 import com.x.base.core.project.config.CenterServer;
 import com.x.base.core.project.config.CenterServer;
+import com.x.base.core.project.config.ClientInit;
 import com.x.base.core.project.config.Collect;
 import com.x.base.core.project.config.Collect;
 import com.x.base.core.project.config.Communicate;
 import com.x.base.core.project.config.Communicate;
+import com.x.base.core.project.config.Components;
 import com.x.base.core.project.config.ConfigObject;
 import com.x.base.core.project.config.ConfigObject;
 import com.x.base.core.project.config.Dingding;
 import com.x.base.core.project.config.Dingding;
 import com.x.base.core.project.config.DumpRestoreData;
 import com.x.base.core.project.config.DumpRestoreData;
 import com.x.base.core.project.config.DumpRestoreStorage;
 import com.x.base.core.project.config.DumpRestoreStorage;
 import com.x.base.core.project.config.Exmail;
 import com.x.base.core.project.config.Exmail;
-import com.x.base.core.project.config.ExternalDataSource;
 import com.x.base.core.project.config.LogLevel;
 import com.x.base.core.project.config.LogLevel;
 import com.x.base.core.project.config.Meeting;
 import com.x.base.core.project.config.Meeting;
 import com.x.base.core.project.config.Messages;
 import com.x.base.core.project.config.Messages;
 import com.x.base.core.project.config.Node;
 import com.x.base.core.project.config.Node;
 import com.x.base.core.project.config.Person;
 import com.x.base.core.project.config.Person;
+import com.x.base.core.project.config.Portal;
 import com.x.base.core.project.config.ProcessPlatform;
 import com.x.base.core.project.config.ProcessPlatform;
+import com.x.base.core.project.config.PushConfig;
 import com.x.base.core.project.config.Qiyeweixin;
 import com.x.base.core.project.config.Qiyeweixin;
 import com.x.base.core.project.config.Query;
 import com.x.base.core.project.config.Query;
 import com.x.base.core.project.config.Token;
 import com.x.base.core.project.config.Token;
@@ -44,6 +42,11 @@ import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.tools.DefaultCharset;
 import com.x.base.core.project.tools.DefaultCharset;
 
 
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
+
 public class CreateConfigSample {
 public class CreateConfigSample {
 
 
 	private static Logger logger = LoggerFactory.getLogger(CreateConfigSample.class);
 	private static Logger logger = LoggerFactory.getLogger(CreateConfigSample.class);
@@ -54,25 +57,28 @@ public class CreateConfigSample {
 		List<Class<?>> classes = new ArrayList<Class<?>>();
 		List<Class<?>> classes = new ArrayList<Class<?>>();
 		classes.add(AppStyle.class);
 		classes.add(AppStyle.class);
 		classes.add(CenterServer.class);
 		classes.add(CenterServer.class);
+		classes.add(ClientInit.class);
 		classes.add(Collect.class);
 		classes.add(Collect.class);
+		classes.add(Communicate.class);
+		classes.add(Components.class);
 		classes.add(Dingding.class);
 		classes.add(Dingding.class);
 		classes.add(DumpRestoreData.class);
 		classes.add(DumpRestoreData.class);
 		classes.add(DumpRestoreStorage.class);
 		classes.add(DumpRestoreStorage.class);
+		classes.add(Exmail.class);
 		classes.add(LogLevel.class);
 		classes.add(LogLevel.class);
 		classes.add(Meeting.class);
 		classes.add(Meeting.class);
 		classes.add(Messages.class);
 		classes.add(Messages.class);
 		classes.add(Node.class);
 		classes.add(Node.class);
 		classes.add(Person.class);
 		classes.add(Person.class);
+		classes.add(Portal.class);
 		classes.add(ProcessPlatform.class);
 		classes.add(ProcessPlatform.class);
+		classes.add(PushConfig.class);
 		classes.add(Qiyeweixin.class);
 		classes.add(Qiyeweixin.class);
 		classes.add(Query.class);
 		classes.add(Query.class);
 		classes.add(Token.class);
 		classes.add(Token.class);
 		classes.add(Vfs.class);
 		classes.add(Vfs.class);
 		classes.add(WorkTime.class);
 		classes.add(WorkTime.class);
 		classes.add(ZhengwuDingding.class);
 		classes.add(ZhengwuDingding.class);
-		//classes.add(ExternalDataSource.class);
-		classes.add(Exmail.class);
-		classes.add(Communicate.class);
 
 
 		Collections.sort(classes, new Comparator<Class<?>>() {
 		Collections.sort(classes, new Comparator<Class<?>>() {
 			public int compare(Class<?> c1, Class<?> c2) {
 			public int compare(Class<?> c1, Class<?> c2) {
@@ -90,21 +96,9 @@ public class CreateConfigSample {
 			logger.print("create file:{}.", file.getAbsoluteFile());
 			logger.print("create file:{}.", file.getAbsoluteFile());
 			FileUtils.write(file, XGsonBuilder.toJson(map), DefaultCharset.charset);
 			FileUtils.write(file, XGsonBuilder.toJson(map), DefaultCharset.charset);
 		}
 		}
-		//convertExternalDataSource2ExternalDataSources(dir);
 		renameNode(dir);
 		renameNode(dir);
 	}
 	}
 
 
-//	private static void convertExternalDataSource2ExternalDataSources(File dir) throws Exception, IOException {
-//		File file_externalDataSource = new File(dir, "externalDataSources.json");
-//		File file_externalDataSources = new File(dir, "externalDataSources.json");
-//		JsonElement jsonElement = XGsonBuilder.instance().fromJson(
-//				FileUtils.readFileToString(file_externalDataSource, DefaultCharset.charset), JsonElement.class);
-//		List<JsonElement> list = new ArrayList<>();
-//		list.add(jsonElement);
-//		FileUtils.writeStringToFile(file_externalDataSources, XGsonBuilder.toJson(list), DefaultCharset.charset);
-//		file_externalDataSource.delete();
-//	}
-
 	private static void renameNode(File dir) throws Exception, IOException {
 	private static void renameNode(File dir) throws Exception, IOException {
 		File file_node = new File(dir, "node.json");
 		File file_node = new File(dir, "node.json");
 		File file_node_local = new File(dir, "node_127.0.0.1.json");
 		File file_node_local = new File(dir, "node_127.0.0.1.json");

+ 9 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/ClientInit.java

@@ -44,6 +44,10 @@ public class ClientInit extends ConfigObject {
 
 
 	public static class LoginPage extends ConfigObject {
 	public static class LoginPage extends ConfigObject {
 
 
+		public static LoginPage defaultInstance() {
+			return new LoginPage();
+		}
+
 		@FieldDescribe("是否启用定制的登录页面.")
 		@FieldDescribe("是否启用定制的登录页面.")
 		private Boolean enable;
 		private Boolean enable;
 		@FieldDescribe("登录的门户.")
 		@FieldDescribe("登录的门户.")
@@ -78,6 +82,11 @@ public class ClientInit extends ConfigObject {
 
 
 	public static class CenterAddress extends ConfigObject {
 	public static class CenterAddress extends ConfigObject {
 
 
+
+		public static CenterAddress defaultInstance() {
+			return new CenterAddress();
+		}
+
 		private String port;
 		private String port;
 
 
 		private String host;
 		private String host;

+ 1 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/exception/PromptException.java

@@ -1,6 +1,6 @@
 package com.x.base.core.project.exception;
 package com.x.base.core.project.exception;
 
 
-import org.slf4j.helpers.MessageFormatter;
+import com.x.base.core.project.logger.MessageFormatter;
 
 
 public abstract class PromptException extends Exception {
 public abstract class PromptException extends Exception {
 
 

+ 1 - 1
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/service/BBSConfigSettingService.java

@@ -262,7 +262,7 @@ public class BBSConfigSettingService{
 		type = "text";
 		type = "text";
 		selectContent = null;
 		selectContent = null;
 		isMultiple = false;
 		isMultiple = false;
-		description = "论坛标题Tail:全站网页标题内容的后缀内容。默认' - O2OA办公软件管理系统',可以为空。";
+		description = "论坛标题Tail:全站网页标题内容的后缀内容。可以为空。";
 		try {
 		try {
 			checkAndInitSystemConfig("BBS_TITLE_TAIL", "论坛标题Tail", value, description, type, selectContent, isMultiple,  ++ordernumber );
 			checkAndInitSystemConfig("BBS_TITLE_TAIL", "论坛标题Tail", value, description, type, selectContent, isMultiple,  ++ordernumber );
 		} catch (Exception e) {
 		} catch (Exception e) {

+ 9 - 0
o2server/x_bbs_assemble_control/src/main/java/com/x/bbs/assemble/control/service/BBSForumSubjectStatisticService.java

@@ -44,9 +44,11 @@ public class BBSForumSubjectStatisticService {
 								sectionInfo.setSubjectTotalToday( count.longValue() );
 								sectionInfo.setSubjectTotalToday( count.longValue() );
 								count = business.replyInfoFactory().countReplyForTodayBySectionId( mainSectionInfo.getId() );
 								count = business.replyInfoFactory().countReplyForTodayBySectionId( mainSectionInfo.getId() );
 								sectionInfo.setReplyTotalToday( count.longValue() );
 								sectionInfo.setReplyTotalToday( count.longValue() );
+
 								if( StringUtils.isEmpty( sectionInfo.getReplyMessageNotifyType() )){
 								if( StringUtils.isEmpty( sectionInfo.getReplyMessageNotifyType() )){
 									sectionInfo.setReplyMessageNotifyType("0,0,0");
 									sectionInfo.setReplyMessageNotifyType("0,0,0");
 								}
 								}
+
 								emc.check( sectionInfo, CheckPersistType.all );
 								emc.check( sectionInfo, CheckPersistType.all );
 							}
 							}
 						}
 						}
@@ -59,9 +61,11 @@ public class BBSForumSubjectStatisticService {
 						mainSectionInfo.setSubjectTotalToday( count.longValue() );
 						mainSectionInfo.setSubjectTotalToday( count.longValue() );
 						count = business.replyInfoFactory().countReplyForTodayBySectionId( mainSectionInfo.getId() );
 						count = business.replyInfoFactory().countReplyForTodayBySectionId( mainSectionInfo.getId() );
 						mainSectionInfo.setReplyTotalToday( count.longValue() );
 						mainSectionInfo.setReplyTotalToday( count.longValue() );
+
 						if( StringUtils.isEmpty( mainSectionInfo.getReplyMessageNotifyType() )){
 						if( StringUtils.isEmpty( mainSectionInfo.getReplyMessageNotifyType() )){
 							mainSectionInfo.setReplyMessageNotifyType("0,0,0");
 							mainSectionInfo.setReplyMessageNotifyType("0,0,0");
 						}
 						}
+
 						emc.check( mainSectionInfo, CheckPersistType.all );
 						emc.check( mainSectionInfo, CheckPersistType.all );
 					}
 					}
 				}
 				}
@@ -78,6 +82,11 @@ public class BBSForumSubjectStatisticService {
 				f.setSubjectTotalToday( count.longValue() );
 				f.setSubjectTotalToday( count.longValue() );
 				count = business.replyInfoFactory().countForTodayByForumId( f.getId() );
 				count = business.replyInfoFactory().countForTodayByForumId( f.getId() );
 				f.setReplyTotalToday( count.longValue() );
 				f.setReplyTotalToday( count.longValue() );
+
+				if( StringUtils.isEmpty( f.getReplyMessageNotifyType() )){
+					f.setReplyMessageNotifyType("0,0,0");
+				}
+
 				emc.check( f, CheckPersistType.all );
 				emc.check( f, CheckPersistType.all );
 				emc.commit();
 				emc.commit();
 			}catch( Exception e ){
 			}catch( Exception e ){

+ 21 - 5
o2server/x_calendar_assemble_control/src/main/java/com/x/calendar/assemble/control/service/CalendarService.java

@@ -167,9 +167,9 @@ public class CalendarService {
 	public List<String> listWithCondition( EntityManagerContainer emc,  String name, String type, String source, String createor,
 	public List<String> listWithCondition( EntityManagerContainer emc,  String name, String type, String source, String createor,
 			 List<String> inFilterCalendarIds, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 			 List<String> inFilterCalendarIds, String personName, List<String> unitNames, List<String> groupNames ) throws Exception {
 		Business business =  new Business( emc );
 		Business business =  new Business( emc );
-		//如果用户没有自己可管理的日历,则创建一个新的日历
+
+		//同步,避免前端的连续调用导致多条个人日历
 		List<String> ids = business.calendarFactory().listMyCalender( personName );
 		List<String> ids = business.calendarFactory().listMyCalender( personName );
-		
 		if( ListTools.isEmpty( ids ) ) {
 		if( ListTools.isEmpty( ids ) ) {
 			//创建一个自己的默认日历
 			//创建一个自己的默认日历
 			Calendar calendar = new Calendar();
 			Calendar calendar = new Calendar();
@@ -186,16 +186,32 @@ public class CalendarService {
 			calendar.setManageablePersonList( new ArrayList<>() );
 			calendar.setManageablePersonList( new ArrayList<>() );
 			calendar.setPublishablePersonList( new ArrayList<>() );
 			calendar.setPublishablePersonList( new ArrayList<>() );
 			calendar.setViewablePersonList( new ArrayList<>() );
 			calendar.setViewablePersonList( new ArrayList<>() );
-			
+
 			addStringToList( personName, calendar.getManageablePersonList() );
 			addStringToList( personName, calendar.getManageablePersonList() );
 			addStringToList( personName, calendar.getPublishablePersonList() );
 			addStringToList( personName, calendar.getPublishablePersonList() );
 			addStringToList( personName, calendar.getViewablePersonList() );
 			addStringToList( personName, calendar.getViewablePersonList() );
-			
+
+			queryForAddNewPersonalDefaultCalendar(emc, personName,calendar );
+
+		}
+		return business.calendarFactory().listWithCondition( name, type, source, createor, inFilterCalendarIds, personName, unitNames, groupNames );
+	}
+
+	/**
+	 * 同步方法,避免前端的连续调用导致多条个人日历信息
+	 * @param emc
+	 * @param personName
+	 * @param calendar
+	 * @throws Exception
+	 */
+	private synchronized void queryForAddNewPersonalDefaultCalendar(EntityManagerContainer emc, String personName, Calendar calendar) throws Exception {
+		Business business =  new Business( emc );
+		List<String> ids = business.calendarFactory().listMyCalender( personName );
+		if( ListTools.isEmpty( ids )){
 			emc.beginTransaction( Calendar.class );
 			emc.beginTransaction( Calendar.class );
 			emc.persist( calendar, CheckPersistType.all );
 			emc.persist( calendar, CheckPersistType.all );
 			emc.commit();
 			emc.commit();
 		}
 		}
-		return business.calendarFactory().listWithCondition( name, type, source, createor, inFilterCalendarIds, personName, unitNames, groupNames );
 	}
 	}
 
 
 	/**
 	/**

+ 1 - 1
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/jaxrs/categoryinfo/ActionDelete.java

@@ -51,6 +51,7 @@ public class ActionDelete extends BaseAction {
 		if (check) {
 		if (check) {
 			Long count = documentServiceAdv.countByCategoryId( id );
 			Long count = documentServiceAdv.countByCategoryId( id );
 			if ( count > 0 ) {
 			if ( count > 0 ) {
+				check = false;
 				Exception exception = new ExceptionEditNotAllowed( "该分类中仍有" + count + "个文档,请删除所有文档后再删除分类信息!");
 				Exception exception = new ExceptionEditNotAllowed( "该分类中仍有" + count + "个文档,请删除所有文档后再删除分类信息!");
 				result.error(exception);
 				result.error(exception);
 			}
 			}
@@ -75,7 +76,6 @@ public class ActionDelete extends BaseAction {
 				ApplicationCache.notify( CategoryInfo.class );
 				ApplicationCache.notify( CategoryInfo.class );
 				ApplicationCache.notify( ViewCategory.class );
 				ApplicationCache.notify( ViewCategory.class );
 			} catch (Exception e) {
 			} catch (Exception e) {
-				check = false;
 				Exception exception = new ExceptionCategoryInfoProcess(e, "分类信息在删除时发生异常。ID:" + id);
 				Exception exception = new ExceptionCategoryInfoProcess(e, "分类信息在删除时发生异常。ID:" + id);
 				result.error(exception);
 				result.error(exception);
 				logger.error(e, effectivePerson, request, null);
 				logger.error(e, effectivePerson, request, null);

+ 2 - 3
o2server/x_cms_assemble_control/src/main/java/com/x/cms/assemble/control/queue/QueueDocumentDelete.java

@@ -13,10 +13,9 @@ public class QueueDocumentDelete extends AbstractQueue<String> {
 	//{application}/{infoId}
 	//{application}/{infoId}
 	public void execute( String docId ) throws Exception {
 	public void execute( String docId ) throws Exception {
 		try {
 		try {
-			ThisApplication.context().applications().deleteQuery(
-					x_hotpic_assemble_control.class, "cms/" + docId
-			);
+			ThisApplication.context().applications().deleteQuery( x_hotpic_assemble_control.class, "cipher/hotpic/cms/" + docId );
 		}catch( Exception e ) {
 		}catch( Exception e ) {
+			e.printStackTrace();
 		}		
 		}		
 	}
 	}
 }
 }

+ 84 - 0
o2server/x_hotpic_assemble_control/src/main/java/com/x/hotpic/assemble/control/jaxrs/hotpic/HotPictureInfoCipherAction.java

@@ -15,6 +15,7 @@ import com.x.base.core.project.jaxrs.ResponseFactory;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 import com.x.base.core.project.jaxrs.StandardJaxrsAction;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.Logger;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.ListTools;
 import com.x.base.core.project.tools.SortTools;
 import com.x.base.core.project.tools.SortTools;
 import com.x.hotpic.assemble.control.service.HotPictureInfoServiceAdv;
 import com.x.hotpic.assemble.control.service.HotPictureInfoServiceAdv;
 import com.x.hotpic.entity.HotPictureInfo;
 import com.x.hotpic.entity.HotPictureInfo;
@@ -42,6 +43,89 @@ public class HotPictureInfoCipherAction extends StandardJaxrsAction {
 			.wo(HotPictureInfo.class, WrapOutHotPictureInfo.class, null, WrapOutHotPictureInfo.Excludes);
 			.wo(HotPictureInfo.class, WrapOutHotPictureInfo.class, null, WrapOutHotPictureInfo.Excludes);
 	private Ehcache cache = ApplicationCache.instance().getCache(HotPictureInfo.class);
 	private Ehcache cache = ApplicationCache.instance().getCache(HotPictureInfo.class);
 
 
+
+	@JaxrsMethodDescribe(value = "根据CMS文档ID删除热点信息", action= StandardJaxrsAction.class )
+	@DELETE
+	@Path("cms/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void deleteCms(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+					@PathParam("id") String id) {
+		ActionResult<WrapOutString> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		WrapOutString wrap = null;
+		List<HotPictureInfo> hotPictureInfos = null;
+		Boolean check = true;
+
+		if (check) {
+			if (id == null || id.isEmpty() || "(0)".equals(id)) {
+				check = false;
+				Exception exception = new InfoIdEmptyException();
+				result.error(exception);
+			}
+		}
+		if( check ){
+			try {
+				hotPictureInfos = hotPictureInfoService.listByApplicationInfoId(HotPictureInfo.APPLICATION_CMS, id );
+				if(ListTools.isNotEmpty( hotPictureInfos )){
+					for( HotPictureInfo hotPictureInfo : hotPictureInfos ){
+						hotPictureInfoService.delete( hotPictureInfo.getId() );
+					}
+					ApplicationCache.notify(HotPictureInfo.class);
+				}
+			} catch (Exception e) {
+				Exception exception = new InfoQueryByIdException(e, id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		WrapOutString wrapOutString =  new WrapOutString();
+		wrapOutString.setValue( id );
+		result.setData( wrapOutString );
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "根据BBS主贴ID删除热点信息", action= StandardJaxrsAction.class )
+	@DELETE
+	@Path("bbs/{id}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void deleteBBS(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+						  @PathParam("id") String id) {
+		ActionResult<WrapOutString> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		WrapOutString wrap = null;
+		List<HotPictureInfo> hotPictureInfos = null;
+		Boolean check = true;
+
+		if (check) {
+			if (id == null || id.isEmpty() || "(0)".equals(id)) {
+				check = false;
+				Exception exception = new InfoIdEmptyException();
+				result.error(exception);
+			}
+		}
+		if( check ){
+			try {
+				hotPictureInfos = hotPictureInfoService.listByApplicationInfoId(HotPictureInfo.APPLICATION_BBS, id );
+				if(ListTools.isNotEmpty( hotPictureInfos )){
+					for( HotPictureInfo hotPictureInfo : hotPictureInfos ){
+						hotPictureInfoService.delete( hotPictureInfo.getId() );
+					}
+					ApplicationCache.notify(HotPictureInfo.class);
+				}
+			} catch (Exception e) {
+				Exception exception = new InfoQueryByIdException(e, id);
+				result.error(exception);
+				logger.error(e, effectivePerson, request, null);
+			}
+		}
+		WrapOutString wrapOutString =  new WrapOutString();
+		wrapOutString.setValue( id );
+		result.setData( wrapOutString );
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
 	@JaxrsMethodDescribe(value = "根据ID获取单个热图信息", action= StandardJaxrsAction.class )
 	@JaxrsMethodDescribe(value = "根据ID获取单个热图信息", action= StandardJaxrsAction.class )
 	@GET
 	@GET
 	@Path("{id}")
 	@Path("{id}")

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio