Преглед на файлове

钉钉考勤统计表 数据统计功能

fancy преди 5 години
родител
ревизия
7ad744003d
променени са 19 файла, в които са добавени 1467 реда и са изтрити 12 реда
  1. 128 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingPersonStatisticQueue.java
  2. 141 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingUnitStatisticQueue.java
  3. 17 4
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/ThisApplication.java
  4. 312 7
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/DingdingAttendanceFactory.java
  5. 2 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/ActionApplication.java
  6. 10 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/DingdingStatisticJaxrsFilter.java
  7. 34 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/ActionStatisticPersonMonthData.java
  8. 34 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/ActionStatisticUnitDayData.java
  9. 41 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/DingdingAttendanceAction.java
  10. 15 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingdingstatistic/ActionTest.java
  11. 6 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingdingstatistic/BaseAction.java
  12. 48 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingdingstatistic/DingdingAttendanceStatisticAction.java
  13. 37 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/schedule/DingdingAttendanceStatisticPersonScheduleTask.java
  14. 37 0
      o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/schedule/DingdingAttendanceStatisticScheduleTask.java
  15. 9 0
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/PersistenceProperties.java
  16. 202 0
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingPersonForMonth.java
  17. 202 0
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForDay.java
  18. 190 0
      o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForMonth.java
  19. 2 1
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_attendance_assemble_control.java

+ 128 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingPersonStatisticQueue.java

@@ -0,0 +1,128 @@
+package com.x.attendance.assemble.control;
+
+import com.x.attendance.entity.AttendanceDingtalkDetail;
+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.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.Application;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.organization.Person;
+import com.x.base.core.project.organization.Unit;
+import com.x.base.core.project.queue.AbstractQueue;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.ListTools;
+import com.x.base.core.project.x_organization_assemble_control;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class DingdingPersonStatisticQueue extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(DingdingPersonStatisticQueue.class);
+
+    @Override
+    protected void execute(Date date) throws Exception {
+        logger.info("开始执行人员钉钉考勤统计。。。time:"+DateTools.format(date));
+        try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            Business business = new Business(emc);
+            saveStatisticPersonForMonth(business, emc, date);
+        }
+    }
+
+
+    private void saveStatisticPersonForMonth(Business business, EntityManagerContainer emc, Date date) throws Exception {
+        String dateString = DateTools.format(date, DateTools.format_yyyyMMdd);
+        String year = dateString.substring(0, 4);
+        String month = dateString.substring(5, 7);
+
+        Application app = ThisApplication.context().applications().randomWithWeight(x_organization_assemble_control.class.getName());
+        //开始分页查询人员
+        boolean hasNextPerson = true;
+        int personPageSize = 50;
+        //人员查询地址
+        String uri = "person/list/(0)/next/50";
+        while (hasNextPerson) {
+            List<Person> list = ThisApplication.context().applications()
+                    .getQuery(false, app, uri).getDataAsList(Person.class);
+            if (list != null && list.size() > 0) {
+                for (Person person : list) {
+                    List<String> ids = business.dingdingAttendanceFactory()
+                            .getStatPersonForMonthIds(year, month, person.getDistinguishedName());
+                    emc.beginTransaction(StatisticDingdingPersonForMonth.class);
+                    if (ids != null && ids.size() > 0) {
+                        for (String item : ids) {
+                            StatisticDingdingPersonForMonth personForMonth_temp = emc.find(item, StatisticDingdingPersonForMonth.class);
+                            emc.remove(personForMonth_temp);
+                        }
+                    }
+                    StatisticDingdingPersonForMonth personForMonth = new StatisticDingdingPersonForMonth();
+                    personForMonth.setStatisticYear(year);
+                    personForMonth.setStatisticMonth(month);
+                    personForMonth.setO2Unit(getUnitWithPerson(person.getDistinguishedName(), business));
+                    personForMonth.setO2User(person.getDistinguishedName());
+                    Long onduty = business.dingdingAttendanceFactory().dingdingPersonForMonthDutyTimesCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.OnDuty);
+                    personForMonth.setWorkDayCount(onduty);
+                    personForMonth.setOnDutyTimes(onduty);
+                    personForMonth.setOffDutyTimes(business.dingdingAttendanceFactory().dingdingPersonForMonthDutyTimesCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.OffDuty));
+                    personForMonth.setLateTimes(business.dingdingAttendanceFactory().dingdingPersonForMonthTimeResultCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.TIMERESULT_Late));
+                    personForMonth.setLeaveEarlyTimes(business.dingdingAttendanceFactory().dingdingPersonForMonthTimeResultCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.TIMERESULT_Early));
+                    personForMonth.setAbsenteeismTimes(business.dingdingAttendanceFactory().dingdingPersonForMonthTimeResultCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.TIMERESULT_Absenteeism));
+                    personForMonth.setNotSignedCount(business.dingdingAttendanceFactory().dingdingPersonForMonthTimeResultCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.TIMERESULT_NotSigned));
+                    personForMonth.setSeriousLateTimes(business.dingdingAttendanceFactory().dingdingPersonForMonthTimeResultCount(year, month,
+                            person.getDistinguishedName(), AttendanceDingtalkDetail.TIMERESULT_SeriousLate));
+                    emc.persist(personForMonth);
+                    emc.commit();
+                }
+
+                //是否还有更多用户
+                if (list.size() < personPageSize) {
+                    logger.info("统计钉钉考勤个人数据 结束。。。。。。。。。。。。。。。");
+                    hasNextPerson = false;
+                } else {
+                    //还有更多用户继续查询
+                    uri = "person/list/" + list.get(list.size() - 1).getDistinguishedName() + "/next/50";
+                }
+            }else {
+                //没有用户查询到结束
+                logger.info("统计钉钉考勤个人数据 结束。。。。。。。。。。。。。。。");
+                hasNextPerson = false;
+            }
+        }
+    }
+
+    private String getUnitWithPerson(String person, Business business) throws Exception {
+        String result = null;
+        Integer level = 0;
+        Unit unit = null;
+        List<String> unitNames = business.organization().unit().listWithPerson( person );
+        if( ListTools.isNotEmpty( unitNames ) ) {
+            for( String unitName : unitNames ) {
+                if( StringUtils.isNotEmpty( unitName ) && !"null".equals( unitName ) ) {
+                    unit = business.organization().unit().getObject( unitName );
+                    if( level < unit.getLevel() ) {
+                        level = unit.getLevel();
+                        result = unitName;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+
+
+
+}

+ 141 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/DingdingUnitStatisticQueue.java

@@ -0,0 +1,141 @@
+package com.x.attendance.assemble.control;
+
+import com.x.attendance.entity.AttendanceDingtalkDetail;
+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.factory.EntityManagerContainerFactory;
+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 com.x.base.core.project.tools.DateTools;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class DingdingUnitStatisticQueue extends AbstractQueue<Date> {
+    private static final Logger logger = LoggerFactory.getLogger(DingdingUnitStatisticQueue.class);
+
+    @Override
+    protected void execute(Date date) throws Exception {
+        logger.info("开始执行组织钉钉考勤统计。。。time:"+DateTools.format(date));
+        try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            Business business = new Business(emc);
+            saveStatisticUnitForDay(business, emc, date);
+        }
+    }
+
+
+
+    /**
+     * 单位 日统计
+     * @param business
+     * @param emc
+     * @param date
+     * @throws Exception
+     */
+    private void saveStatisticUnitForDay(Business business, EntityManagerContainer emc, Date date) throws Exception{
+        String dateString = DateTools.format(date, DateTools.format_yyyyMMdd);
+        String year = dateString.substring(0, 4);
+        String month = dateString.substring(5, 7);
+        String day = dateString.substring(8, 10);
+        List<String> units = business.dingdingAttendanceFactory().dingdingUnitDistinct(dateString);
+        if (units != null && !units.isEmpty()) {
+            for (String unit : units) {
+                if (StringUtils.isEmpty(unit)){
+                    continue;
+                }
+                List<String> ids = business.dingdingAttendanceFactory().getStatUnitForDayIds(year, month, day, unit);
+                emc.beginTransaction(StatisticDingdingUnitForDay.class);
+                if (ids != null && ids.size() > 0) {
+                    for (String item : ids) {
+                        StatisticDingdingUnitForDay statisticTopUnitForDay_tmp = emc.find(item, StatisticDingdingUnitForDay.class);
+                        emc.remove(statisticTopUnitForDay_tmp);
+                    }
+                }
+                //for day
+                StatisticDingdingUnitForDay unitForDay = new StatisticDingdingUnitForDay();
+                unitForDay.setO2Unit(unit);
+                unitForDay.setStatisticYear(year);
+                unitForDay.setStatisticMonth(month);
+                unitForDay.setStatisticDate(day);
+                Long on = business.dingdingAttendanceFactory().dingdingUnitForDayDutyTimesCount(dateString, unit, AttendanceDingtalkDetail.OnDuty);
+                unitForDay.setWorkDayCount(on);
+                unitForDay.setOnDutyTimes(on);
+                unitForDay.setOffDutyTimes(business.dingdingAttendanceFactory().
+                        dingdingUnitForDayDutyTimesCount(dateString, unit, AttendanceDingtalkDetail.OffDuty));
+                unitForDay.setLateTimes(business.dingdingAttendanceFactory().dingdingUnitForDayTimeResultCount(dateString, unit,
+                        AttendanceDingtalkDetail.TIMERESULT_Late));
+                unitForDay.setLeaveEarlyTimes(business.dingdingAttendanceFactory().dingdingUnitForDayTimeResultCount(dateString, unit,
+                        AttendanceDingtalkDetail.TIMERESULT_Early));
+                unitForDay.setNotSignedCount(business.dingdingAttendanceFactory().dingdingUnitForDayTimeResultCount(dateString, unit,
+                        AttendanceDingtalkDetail.TIMERESULT_NotSigned));
+                unitForDay.setAbsenteeismTimes(business.dingdingAttendanceFactory().dingdingUnitForDayTimeResultCount(dateString, unit,
+                        AttendanceDingtalkDetail.TIMERESULT_Absenteeism));
+                unitForDay.setSeriousLateTimes(business.dingdingAttendanceFactory().dingdingUnitForDayTimeResultCount(dateString, unit,
+                        AttendanceDingtalkDetail.TIMERESULT_SeriousLate));
+                emc.persist(unitForDay);
+                emc.commit();
+            }
+
+            saveStatisticUnitForMonth(business, emc, units, year, month);
+        }
+
+
+    }
+
+    /**
+     * 单位月统计
+     * @param business
+     * @param emc
+     * @param units
+     * @param year
+     * @param month
+     * @throws Exception
+     */
+    private void saveStatisticUnitForMonth(Business business, EntityManagerContainer emc, List<String> units,
+                                           String year, String month) throws Exception {
+
+        for (String unit : units) {
+            if (StringUtils.isEmpty(unit)){
+                continue;
+            }
+            Long workDay = business.dingdingAttendanceFactory().sumWorkDayUnitForDayWithMonth(year, month, unit);
+            Long onduty = business.dingdingAttendanceFactory().sumOnDutyUnitForDayWithMonth(year, month, unit);
+            Long offDuty = business.dingdingAttendanceFactory().sumOffDutyUnitForDayWithMonth(year, month, unit);
+            Long late = business.dingdingAttendanceFactory().sumLateTimesUnitForDayWithMonth(year, month, unit);
+            Long leaveearly = business.dingdingAttendanceFactory().sumLeaveEarlyUnitForDayWithMonth(year, month, unit);
+            Long notSign = business.dingdingAttendanceFactory().sumNotSignedUnitForDayWithMonth(year, month, unit);
+            Long absenteeism = business.dingdingAttendanceFactory().sumAbsenteeismUnitForDayWithMonth(year, month, unit);
+            Long serious = business.dingdingAttendanceFactory().sumSeriousLateUnitForDayWithMonth(year, month, unit);
+            List<String> list = business.dingdingAttendanceFactory().getStatUnitForMonthIds(year, month, unit);
+            emc.beginTransaction(StatisticDingdingUnitForMonth.class);
+            if (list != null && list.size() > 0) {
+                for (String item : list) {
+                    StatisticDingdingUnitForMonth statisticTopUnitForMonth_tmp = emc.find(item, StatisticDingdingUnitForMonth.class);
+                    emc.remove(statisticTopUnitForMonth_tmp);
+                }
+            }
+            StatisticDingdingUnitForMonth unitForMonth = new StatisticDingdingUnitForMonth();
+            unitForMonth.setO2Unit(unit);
+            unitForMonth.setStatisticYear(year);
+            unitForMonth.setStatisticMonth(month);
+            unitForMonth.setWorkDayCount(workDay);
+            unitForMonth.setOnDutyTimes(onduty);
+            unitForMonth.setOffDutyTimes(offDuty);
+            unitForMonth.setLateTimes(late);
+            unitForMonth.setLeaveEarlyTimes(leaveearly);
+            unitForMonth.setNotSignedCount(notSign);
+            unitForMonth.setAbsenteeismTimes(absenteeism);
+            unitForMonth.setSeriousLateTimes(serious);
+            emc.persist(unitForMonth);
+            emc.commit();
+        }
+
+    }
+}

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

@@ -2,10 +2,7 @@ package com.x.attendance.assemble.control;
 
 import com.x.attendance.assemble.control.processor.monitor.MonitorFileDataOpt;
 import com.x.attendance.assemble.control.processor.thread.DataProcessThreadFactory;
-import com.x.attendance.assemble.control.schedule.AttendanceStatisticTask;
-import com.x.attendance.assemble.control.schedule.DingdingAttendanceSyncScheduleTask;
-import com.x.attendance.assemble.control.schedule.MobileRecordAnalyseTask;
-import com.x.attendance.assemble.control.schedule.QywxAttendanceSyncScheduleTask;
+import com.x.attendance.assemble.control.schedule.*;
 import com.x.attendance.assemble.control.service.AttendanceSettingService;
 import com.x.base.core.project.Context;
 import com.x.base.core.project.config.Config;
@@ -21,6 +18,8 @@ public class ThisApplication {
 
 	public static DingdingAttendanceQueue dingdingQueue = new DingdingAttendanceQueue();
 	public static QywxAttendanceSyncQueue qywxQueue = new QywxAttendanceSyncQueue();
+	public static DingdingPersonStatisticQueue personStatisticQueue = new DingdingPersonStatisticQueue();
+	public static DingdingUnitStatisticQueue unitStatisticQueue = new DingdingUnitStatisticQueue();
 
 	public static void init() throws Exception {
 		try {
@@ -29,7 +28,11 @@ public class ThisApplication {
 			context.schedule(MobileRecordAnalyseTask.class, "0 0/10 * * * ?");
 			if (BooleanUtils.isTrue(Config.dingding().getAttendanceSyncEnable())) {
 				dingdingQueue.start();
+				personStatisticQueue.start();
+				unitStatisticQueue.start();
 				context.schedule(DingdingAttendanceSyncScheduleTask.class, "0 0 1 * * ?");
+				context().schedule(DingdingAttendanceStatisticScheduleTask.class, "0 0 3 * * ?");
+				context().schedule(DingdingAttendanceStatisticPersonScheduleTask.class, "0 0 3 * * ?");
 			}
 			if (BooleanUtils.isTrue(Config.qiyeweixin().getAttendanceSyncEnable())) {
 				qywxQueue.start();
@@ -56,6 +59,16 @@ public class ThisApplication {
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
+		try {
+			personStatisticQueue.stop();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		try {
+			unitStatisticQueue.stop();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 		try {
 			qywxQueue.stop();
 		} catch (Exception e) {

+ 312 - 7
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/factory/DingdingAttendanceFactory.java

@@ -5,13 +5,16 @@ import com.x.attendance.assemble.control.Business;
 import com.x.attendance.assemble.control.exception.DingdingFindNoArgumentError;
 import com.x.attendance.assemble.control.exception.QywxFindNoArgumentError;
 import com.x.attendance.entity.*;
-import com.x.base.core.project.tools.StringTools;
+import com.x.base.core.project.tools.DateTools;
+import org.apache.commons.lang3.time.DateUtils;
 
 import javax.persistence.EntityManager;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import javax.persistence.metamodel.SingularAttribute;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
@@ -22,10 +25,10 @@ public class DingdingAttendanceFactory extends AbstractFactory {
     }
 
 
-
     /**
      * 查询所有同步记录
-     * @param type  DingdingQywxSyncRecord.syncType_dingding DingdingQywxSyncRecord.syncType_qywx
+     *
+     * @param type DingdingQywxSyncRecord.syncType_dingding DingdingQywxSyncRecord.syncType_qywx
      * @return
      * @throws Exception
      */
@@ -41,18 +44,19 @@ public class DingdingAttendanceFactory extends AbstractFactory {
 
     /**
      * 查询冲突的钉钉同步记录
+     *
      * @param fromTime
      * @param toTime
      * @return
      * @throws Exception
      */
-    public  List<DingdingQywxSyncRecord> findConflictSyncRecord(long fromTime, long toTime) throws Exception {
+    public List<DingdingQywxSyncRecord> findConflictSyncRecord(long fromTime, long toTime) throws Exception {
         EntityManager em = this.entityManagerContainer().get(DingdingQywxSyncRecord.class);
         CriteriaBuilder cb = em.getCriteriaBuilder();
         CriteriaQuery<DingdingQywxSyncRecord> query = cb.createQuery(DingdingQywxSyncRecord.class);
         Root<DingdingQywxSyncRecord> root = query.from(DingdingQywxSyncRecord.class);
         Predicate p = cb.equal(root.get(DingdingQywxSyncRecord_.type), DingdingQywxSyncRecord.syncType_dingding);
-        Predicate p1  = cb.or(cb.between(root.get(DingdingQywxSyncRecord_.dateFrom), fromTime, toTime), cb.between(root.get(DingdingQywxSyncRecord_.dateTo), fromTime, toTime));
+        Predicate p1 = cb.or(cb.between(root.get(DingdingQywxSyncRecord_.dateFrom), fromTime, toTime), cb.between(root.get(DingdingQywxSyncRecord_.dateTo), fromTime, toTime));
         p = cb.and(p, p1);
         query.select(root).where(p);
         return em.createQuery(query).getResultList();
@@ -60,6 +64,7 @@ public class DingdingAttendanceFactory extends AbstractFactory {
 
     /**
      * 根据用户查询一段时间内的打开数据
+     *
      * @param startTime
      * @param endTime
      * @param userId
@@ -83,7 +88,7 @@ public class DingdingAttendanceFactory extends AbstractFactory {
         if (userId != null && !userId.isEmpty()) {
             if (p != null) {
                 p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.userId), userId));
-            }else {
+            } else {
                 p = cb.equal(root.get(AttendanceDingtalkDetail_.userId), userId);
             }
         }
@@ -93,6 +98,7 @@ public class DingdingAttendanceFactory extends AbstractFactory {
 
     /**
      * 企业微信 打卡数据查询
+     *
      * @param startTime
      * @param endTime
      * @param userId
@@ -117,7 +123,7 @@ public class DingdingAttendanceFactory extends AbstractFactory {
         if (userId != null && !userId.isEmpty()) {
             if (p != null) {
                 p = cb.and(p, cb.equal(root.get(AttendanceQywxDetail_.userid), userId));
-            }else {
+            } else {
                 p = cb.equal(root.get(AttendanceQywxDetail_.userid), userId);
             }
         }
@@ -125,4 +131,303 @@ public class DingdingAttendanceFactory extends AbstractFactory {
         return em.createQuery(query).getResultList();
 
     }
+
+
+    ////////////////////////////////统计/////////////////////////////
+
+    /**
+     * 钉钉考勤 个人统计
+     * @param year
+     * @param month
+     * @param person
+     * @param duty
+     * @return
+     * @throws Exception
+     */
+    public Long dingdingPersonForMonthDutyTimesCount(String year, String month, String person, String duty) throws Exception {
+        Date start = monthFirstDay(year, month);
+        Date end = monthLastDay(year, month);
+        EntityManager em = this.entityManagerContainer().get(AttendanceDingtalkDetail.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<AttendanceDingtalkDetail> root = query.from(AttendanceDingtalkDetail.class);
+        Predicate p = cb.between(root.get(AttendanceDingtalkDetail_.userCheckTime), start.getTime(), end.getTime());
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.o2User), person));
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.checkType), duty));
+        query.select(cb.count(root)).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long dingdingPersonForMonthTimeResultCount(String year, String month, String person, String timeresult) throws Exception {
+        Date start = monthFirstDay(year, month);
+        Date end = monthLastDay(year, month);
+        EntityManager em = this.entityManagerContainer().get(AttendanceDingtalkDetail.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<AttendanceDingtalkDetail> root = query.from(AttendanceDingtalkDetail.class);
+        Predicate p = cb.between(root.get(AttendanceDingtalkDetail_.userCheckTime), start.getTime(), end.getTime());
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.o2User), person));
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.timeResult), timeresult));
+        query.select(cb.count(root)).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+
+
+    /**
+     * StatisticDingdingPersonForMonth ids
+     * @param year
+     * @param month
+     * @param person
+     * @return
+     * @throws Exception
+     */
+    public List<String> getStatPersonForMonthIds(String year, String month, String person) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingPersonForMonth.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<String> query = cb.createQuery(String.class);
+        Root<StatisticDingdingPersonForMonth> root = query.from(StatisticDingdingPersonForMonth.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingPersonForMonth_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingPersonForMonth_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingPersonForMonth_.o2User), person));
+        query.select(root.get(StatisticDingdingPersonForMonth_.id)).where(p);
+        return em.createQuery(query).getResultList();
+    }
+
+    /**
+     * 钉钉考勤 部门出勤人数 、上班签到人数、下班班签到人数
+     *
+     * @param date yyyy-MM-dd
+     * @param unit 单位
+     * @param duty OnDuty OffDuty
+     * @return
+     * @throws Exception
+     */
+    public Long dingdingUnitForDayDutyTimesCount(String date, String unit, String duty) throws Exception {
+        Date startTime = DateTools.parse(date);
+        startTime = startOneDate(startTime);
+        Date endTime = endOneDate(startTime);
+        EntityManager em = this.entityManagerContainer().get(AttendanceDingtalkDetail.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<AttendanceDingtalkDetail> root = query.from(AttendanceDingtalkDetail.class);
+        Predicate p = null;
+        long start = startTime.getTime();
+        long end = endTime.getTime();
+        p = cb.between(root.get(AttendanceDingtalkDetail_.userCheckTime), start, end);
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.o2Unit), unit));
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.checkType), duty));
+        query.select(cb.count(root)).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long dingdingUnitForDayTimeResultCount(String date, String unit, String timeresult) throws Exception {
+
+        Date startTime = DateTools.parse(date);
+        startTime = startOneDate(startTime);
+        Date endTime = endOneDate(startTime);
+        EntityManager em = this.entityManagerContainer().get(AttendanceDingtalkDetail.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<AttendanceDingtalkDetail> root = query.from(AttendanceDingtalkDetail.class);
+        Predicate p = null;
+        long start = startTime.getTime();
+        long end = endTime.getTime();
+        p = cb.between(root.get(AttendanceDingtalkDetail_.userCheckTime), start, end);
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.o2Unit), unit));
+        p = cb.and(p, cb.equal(root.get(AttendanceDingtalkDetail_.timeResult), timeresult));
+        query.select(cb.count(root)).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    /**
+     * 查询所有有数据的组织 去重的
+     * @param date
+     * @return
+     * @throws Exception
+     */
+    public List<String> dingdingUnitDistinct(String date) throws Exception {
+        Date startTime = DateTools.parse(date);
+        startTime = startOneDate(startTime);
+        Date endTime = endOneDate(startTime);
+        EntityManager em = this.entityManagerContainer().get(AttendanceDingtalkDetail.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<String> query = cb.createQuery(String.class);
+        Root<AttendanceDingtalkDetail> root = query.from(AttendanceDingtalkDetail.class);
+        Predicate p = cb.between(root.get(AttendanceDingtalkDetail_.userCheckTime), startTime.getTime(), endTime.getTime());
+        query.select(root.get(AttendanceDingtalkDetail_.o2Unit)).where(p).distinct(true);
+        return em.createQuery(query).getResultList();
+    }
+
+
+    /**
+     * 获取StatitsticDingdingForMonth ids
+     * @param year
+     * @param month
+     * @param unit
+     * @return
+     * @throws Exception
+     */
+    public List<String> getStatUnitForMonthIds(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForMonth.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<String> query = cb.createQuery(String.class);
+        Root<StatisticDingdingUnitForMonth> root = query.from(StatisticDingdingUnitForMonth.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForMonth_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForMonth_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForMonth_.o2Unit), unit));
+        query.select(root.get(StatisticDingdingUnitForMonth_.id)).where(p);
+        return em.createQuery(query).getResultList();
+    }
+
+    public List<String> getStatUnitForDayIds(String year, String month, String day, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<String> query = cb.createQuery(String.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticDate), day));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(root.get(StatisticDingdingUnitForDay_.id)).where(p);
+        return em.createQuery(query).getResultList();
+    }
+
+
+
+    public Long sumWorkDayUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.workDayCount))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long sumOnDutyUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.onDutyTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+    public Long sumOffDutyUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.offDutyTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+    public Long sumLateTimesUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.lateTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+    public Long sumLeaveEarlyUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.leaveEarlyTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long sumNotSignedUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.notSignedCount))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long sumAbsenteeismUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.absenteeismTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+    public Long sumSeriousLateUnitForDayWithMonth(String year, String month, String unit) throws Exception {
+        EntityManager em = this.entityManagerContainer().get(StatisticDingdingUnitForDay.class);
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> query = cb.createQuery(Long.class);
+        Root<StatisticDingdingUnitForDay> root = query.from(StatisticDingdingUnitForDay.class);
+        Predicate p = cb.equal(root.get(StatisticDingdingUnitForDay_.statisticYear), year);
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.statisticMonth), month));
+        p = cb.and(p, cb.equal(root.get(StatisticDingdingUnitForDay_.o2Unit), unit));
+        query.select(cb.sum(root.get(StatisticDingdingUnitForDay_.seriousLateTimes))).where(p);
+        return em.createQuery(query).getSingleResult();
+    }
+
+
+
+
+    private Date monthLastDay(String year, String month) throws Exception {
+        Calendar cal = Calendar.getInstance();
+        int yearInt = Integer.parseInt(year);
+        cal.set(Calendar.YEAR, yearInt);
+        int monthInt = Integer.parseInt(month);
+        cal.set(Calendar.MONTH, monthInt);
+        cal.set(Calendar.DAY_OF_MONTH, 1);
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 59);
+        cal.set(Calendar.SECOND, 59);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.add(Calendar.DAY_OF_MONTH, -1);
+        return cal.getTime();
+    }
+    private Date monthFirstDay(String year, String month) throws Exception {
+        Calendar cal = Calendar.getInstance();
+        int yearInt = Integer.parseInt(year);
+        cal.set(Calendar.YEAR, yearInt);
+        int monthInt = Integer.parseInt(month);
+        cal.set(Calendar.MONTH, monthInt-1);
+        cal.set(Calendar.DATE, 1);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
+    private Date startOneDate(Date date) throws Exception {
+        return DateTools.floorDate(date, null);
+    }
+
+    private Date endOneDate(Date date) throws Exception {
+        Calendar cal = DateUtils.toCalendar(date);
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 59);
+        cal.set(Calendar.SECOND, 59);
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
 }

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

@@ -19,6 +19,7 @@ import com.x.attendance.assemble.control.jaxrs.attendancestatisticalcycle.Attend
 import com.x.attendance.assemble.control.jaxrs.attendancestatisticrequirelog.AttendanceStatisticRequireLogAction;
 import com.x.attendance.assemble.control.jaxrs.attendanceworkdayconfig.AttendanceWorkDayConfigAction;
 import com.x.attendance.assemble.control.jaxrs.dingding.DingdingAttendanceAction;
+import com.x.attendance.assemble.control.jaxrs.dingdingstatistic.DingdingAttendanceStatisticAction;
 import com.x.attendance.assemble.control.jaxrs.fileimport.AttendanceDetailFileImportAction;
 import com.x.attendance.assemble.control.jaxrs.qywx.QywxAttendanceAction;
 import com.x.attendance.assemble.control.jaxrs.selfholiday.AttendanceSelfHolidayAction;
@@ -52,6 +53,7 @@ public class ActionApplication extends AbstractActionApplication {
 		this.classes.add(AttendanceStatisticRequireLogAction.class);
 		this.classes.add(DingdingAttendanceAction.class);
 		this.classes.add(QywxAttendanceAction.class);
+		this.classes.add(DingdingAttendanceStatisticAction.class);
 		return this.classes;
 	}
 

+ 10 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/DingdingStatisticJaxrsFilter.java

@@ -0,0 +1,10 @@
+package com.x.attendance.assemble.control.jaxrs;
+
+import com.x.base.core.project.jaxrs.ManagerUserJaxrsFilter;
+
+import javax.servlet.annotation.WebFilter;
+
+
+@WebFilter(urlPatterns = "/jaxrs/dingdingstatistic/*", asyncSupported = true)
+public class DingdingStatisticJaxrsFilter extends ManagerUserJaxrsFilter {
+}

+ 34 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/ActionStatisticPersonMonthData.java

@@ -0,0 +1,34 @@
+package com.x.attendance.assemble.control.jaxrs.dingding;
+
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.attendance.assemble.control.jaxrs.dingding.exception.SearchArgEmptyException;
+import com.x.attendance.assemble.control.jaxrs.dingdingstatistic.BaseAction;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.jaxrs.WrapBoolean;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.DateTools;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class ActionStatisticPersonMonthData extends BaseAction {
+
+    private static final Logger logger = LoggerFactory.getLogger(ActionStatisticPersonMonthData.class);
+
+    ActionResult<WrapBoolean> execute(String year, String month) throws Exception{
+        ActionResult<WrapBoolean> result = new ActionResult<WrapBoolean>();
+        if (StringUtils.isEmpty(year) || StringUtils.isEmpty(month)) {
+            throw new SearchArgEmptyException();
+        }
+        logger.info("开始执行全部人员考勤信息统计 year:"+year+", month:"+month);
+        Date date = DateTools.parse(year+"-"+month+"-01");
+        ThisApplication.personStatisticQueue.send(date);
+        result.setData(new WrapBoolean(true));
+        return result;
+    }
+}

+ 34 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/ActionStatisticUnitDayData.java

@@ -0,0 +1,34 @@
+package com.x.attendance.assemble.control.jaxrs.dingding;
+
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.attendance.assemble.control.jaxrs.dingding.exception.SearchArgEmptyException;
+import com.x.attendance.assemble.control.jaxrs.dingdingstatistic.BaseAction;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.jaxrs.WrapBoolean;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.DateTools;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class ActionStatisticUnitDayData extends BaseAction {
+
+    private static final Logger logger = LoggerFactory.getLogger(ActionStatisticUnitDayData.class);
+
+    ActionResult<WrapBoolean> execute(String year, String month, String day) throws Exception{
+        ActionResult<WrapBoolean> result = new ActionResult<WrapBoolean>();
+        if (StringUtils.isEmpty(year) || StringUtils.isEmpty(month) || StringUtils.isEmpty(day)) {
+            throw new SearchArgEmptyException();
+        }
+        logger.info("开始执行全部部门考勤信息统计 year:"+year+", month:"+month);
+        Date date = DateTools.parse(year+"-"+month+"-"+day);
+        ThisApplication.unitStatisticQueue.send(date);
+        result.setData(new WrapBoolean(true));
+        return result;
+    }
+}

+ 41 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingding/DingdingAttendanceAction.java

@@ -107,4 +107,45 @@ public class DingdingAttendanceAction extends StandardJaxrsAction {
     }
 
 
+
+    @JaxrsMethodDescribe(value = "钉钉考勤全部个人数据统计", action = ActionStatisticPersonMonthData.class)
+    @GET
+    @Path("statistic/person/year/{year}/month/{month}")
+    @Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public void statisticPerson(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+                         @JaxrsParameterDescribe("年份: yyyy") @PathParam("year") String year,
+                         @JaxrsParameterDescribe("月份: MM") @PathParam("month") String month) {
+        ActionResult<WrapBoolean> result = new ActionResult<>();
+        EffectivePerson effectivePerson = this.effectivePerson(request);
+        try {
+            result = new ActionStatisticPersonMonthData().execute(year, month);
+        }catch (Exception e) {
+            logger.error(e, effectivePerson, request, null);
+            result.error(e);
+        }
+        asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+    }
+
+
+    @JaxrsMethodDescribe(value = "钉钉考勤全部组织数据统计", action = ActionStatisticUnitDayData.class)
+    @GET
+    @Path("statistic/unit/year/{year}/month/{month}/day/{day}")
+    @Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public void statisticUnit(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+                                @JaxrsParameterDescribe("年份: yyyy") @PathParam("year") String year,
+                                @JaxrsParameterDescribe("月份: MM") @PathParam("month") String month,
+                                @JaxrsParameterDescribe("日期: dd") @PathParam("day") String day) {
+        ActionResult<WrapBoolean> result = new ActionResult<>();
+        EffectivePerson effectivePerson = this.effectivePerson(request);
+        try {
+            result = new ActionStatisticUnitDayData().execute(year, month, day);
+        }catch (Exception e) {
+            logger.error(e, effectivePerson, request, null);
+            result.error(e);
+        }
+        asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+    }
+
 }

+ 15 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingdingstatistic/ActionTest.java

@@ -0,0 +1,15 @@
+package com.x.attendance.assemble.control.jaxrs.dingdingstatistic;
+
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.jaxrs.WrapBoolean;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class ActionTest extends BaseAction {
+
+    ActionResult<WrapBoolean> execute() throws Exception {
+        return new ActionResult<>();
+    }
+}

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

@@ -0,0 +1,6 @@
+package com.x.attendance.assemble.control.jaxrs.dingdingstatistic;
+
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+
+public class BaseAction extends StandardJaxrsAction {
+}

+ 48 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/jaxrs/dingdingstatistic/DingdingAttendanceStatisticAction.java

@@ -0,0 +1,48 @@
+package com.x.attendance.assemble.control.jaxrs.dingdingstatistic;
+
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.jaxrs.WrapBoolean;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+@Path("dingdingstatistic")
+@JaxrsDescribe("钉钉打卡数据统计管理")
+public class DingdingAttendanceStatisticAction extends StandardJaxrsAction {
+    private static final Logger logger = LoggerFactory.getLogger(DingdingAttendanceStatisticAction.class);
+
+
+    @JaxrsMethodDescribe(value = "测试", action = ActionTest.class)
+    @GET
+    @Path("demo")
+    @Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public void syncData(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
+        ActionResult<WrapBoolean> result = new ActionResult<>();
+        EffectivePerson effectivePerson = this.effectivePerson(request);
+        try {
+            result = new ActionTest().execute();
+        }catch (Exception e) {
+            logger.error(e, effectivePerson, request, null);
+            result.error(e);
+        }
+        asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+    }
+
+}

+ 37 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/schedule/DingdingAttendanceStatisticPersonScheduleTask.java

@@ -0,0 +1,37 @@
+package com.x.attendance.assemble.control.schedule;
+
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.schedule.AbstractJob;
+import com.x.base.core.project.tools.DateTools;
+import org.quartz.JobExecutionContext;
+
+import java.util.Date;
+
+/**
+ * 钉钉考勤结果统计定时器
+ * 每天晚上3点定时处理钉钉考勤的个人统计数据
+ * Created by fancyLou on 2020-04-05.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class DingdingAttendanceStatisticPersonScheduleTask extends AbstractJob {
+
+    private static final Logger logger = LoggerFactory.getLogger(DingdingAttendanceStatisticPersonScheduleTask.class);
+
+    @Override
+    public void schedule(JobExecutionContext jobExecutionContext) throws Exception {
+        try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            logger.info("开始执行钉钉考勤统计的程序。。。。。。。。。。。。。。。。。。。。。");
+            //前一天 0点到23点
+            Date from = new Date();
+            from = DateTools.addDay(from, -1);//前面一天
+            ThisApplication.personStatisticQueue.send(from);
+        }
+    }
+
+
+
+}

+ 37 - 0
o2server/x_attendance_assemble_control/src/main/java/com/x/attendance/assemble/control/schedule/DingdingAttendanceStatisticScheduleTask.java

@@ -0,0 +1,37 @@
+package com.x.attendance.assemble.control.schedule;
+
+import com.x.attendance.assemble.control.ThisApplication;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.schedule.AbstractJob;
+import com.x.base.core.project.tools.DateTools;
+import org.quartz.JobExecutionContext;
+
+import java.util.Date;
+
+/**
+ * 钉钉考勤结果统计定时器
+ * 每天晚上3点定时处理钉钉考勤的统计数据
+ * Created by fancyLou on 2020-04-03.
+ * Copyright © 2020 O2. All rights reserved.
+ */
+public class DingdingAttendanceStatisticScheduleTask extends AbstractJob {
+
+    private static final Logger logger = LoggerFactory.getLogger(DingdingAttendanceStatisticScheduleTask.class);
+
+    @Override
+    public void schedule(JobExecutionContext jobExecutionContext) throws Exception {
+        try ( EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+            logger.info("开始执行钉钉考勤统计的程序。。。。。。。。。。。。。。。。。。。。。");
+            //前一天 0点到23点
+            Date from = new Date();
+            from = DateTools.addDay(from, -1);//前面一天
+            ThisApplication.unitStatisticQueue.send(from);
+        }
+    }
+
+
+
+}

+ 9 - 0
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/PersistenceProperties.java

@@ -78,6 +78,15 @@ public final class PersistenceProperties extends AbstractPersistenceProperties {
 	public static class StatisticPersonForMonth {
 		public static final String table = "ATDC_STATISTIC_PERSON_FORMONTH";
 	}
+	public static class StatisticDingdingPersonForMonth {
+		public static final String table = "ATDC_STATISTIC_DD_PERSON_FORMONTH";
+	}
+	public static class StatisticDingdingUnitForMonth {
+		public static final String table = "ATDC_STATISTIC_DD_UNIT_FORMONTH";
+	}
+	public static class StatisticDingdingUnitForDay {
+		public static final String table = "ATDC_STATISTIC_DD_UNIT_FORDAY";
+	}
 	
 	public static class AttendanceWorkPlace {
 		public static final String table = "ATDC_WORK_PLACE";

+ 202 - 0
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingPersonForMonth.java

@@ -0,0 +1,202 @@
+package com.x.attendance.entity;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+import javax.persistence.*;
+
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.StatisticDingdingPersonForMonth.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.StatisticDingdingPersonForMonth.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class StatisticDingdingPersonForMonth extends SliceJpaObject {
+
+
+
+	private static final String TABLE = PersistenceProperties.StatisticDingdingPersonForMonth.table;
+	private static final long serialVersionUID = 2006440116216111693L;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	public void onPersist() throws Exception {
+	}
+	/*
+	 * =============================================================================
+	 * ===== 以上为 JpaObject 默认字段
+	 * =============================================================================
+	 * =====
+	 */
+
+	/*
+	 * =============================================================================
+	 * ===== 以下为具体不同的业务及数据表字段要求
+	 * =============================================================================
+	 * =====
+	 */
+	@FieldDescribe("O2用户")
+	@Column(name = ColumnNamePrefix + "o2User", length = length_128B)
+	@CheckPersist(allowEmpty = false)
+	private String o2User;
+
+	@FieldDescribe("O2用户所在的组织")
+	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@CheckPersist(allowEmpty = false)
+	private String o2Unit;
+
+
+	@FieldDescribe("统计年份")
+	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticYear;
+
+	@FieldDescribe("统计月份")
+	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticMonth;
+
+	@FieldDescribe("出勤天数")
+	@Column(name = "xworkDayCount")
+	private Long workDayCount;
+
+	@FieldDescribe("上班签到次数")
+	@Column(name = "xonDutyTimes")
+	private Long onDutyTimes;
+
+	@FieldDescribe("下班签到次数")
+	@Column(name = "xoffDutyTimes")
+	private Long offDutyTimes;
+
+	@FieldDescribe("迟到次数")
+	@Column(name = "xlateTimes")
+	private Long lateTimes;
+
+	@FieldDescribe("严重迟到次数")
+	@Column(name = "xSeriousLateTimes")
+	private Long seriousLateTimes;
+
+	@FieldDescribe("早退次数")
+	@Column(name = "xleaveEarlyTimes")
+	private Long leaveEarlyTimes;
+
+	@FieldDescribe("旷工次数")
+	@Column(name = "xAbsenteeismTimes")
+	private Long absenteeismTimes;
+
+	@FieldDescribe("未打卡次数")
+	@Column(name = "xNotSignedCount")
+	private Long notSignedCount;
+
+
+	public String getO2User() {
+		return o2User;
+	}
+
+	public void setO2User(String o2User) {
+		this.o2User = o2User;
+	}
+
+	public String getO2Unit() {
+		return o2Unit;
+	}
+
+	public void setO2Unit(String o2Unit) {
+		this.o2Unit = o2Unit;
+	}
+
+	public String getStatisticYear() {
+		return statisticYear;
+	}
+
+	public void setStatisticYear(String statisticYear) {
+		this.statisticYear = statisticYear;
+	}
+
+	public String getStatisticMonth() {
+		return statisticMonth;
+	}
+
+	public void setStatisticMonth(String statisticMonth) {
+		this.statisticMonth = statisticMonth;
+	}
+
+	public Long getWorkDayCount() {
+		return workDayCount;
+	}
+
+	public void setWorkDayCount(Long workDayCount) {
+		this.workDayCount = workDayCount;
+	}
+
+	public Long getOnDutyTimes() {
+		return onDutyTimes;
+	}
+
+	public void setOnDutyTimes(Long onDutyTimes) {
+		this.onDutyTimes = onDutyTimes;
+	}
+
+	public Long getOffDutyTimes() {
+		return offDutyTimes;
+	}
+
+	public void setOffDutyTimes(Long offDutyTimes) {
+		this.offDutyTimes = offDutyTimes;
+	}
+
+	public Long getLateTimes() {
+		return lateTimes;
+	}
+
+	public void setLateTimes(Long lateTimes) {
+		this.lateTimes = lateTimes;
+	}
+
+	public Long getSeriousLateTimes() {
+		return seriousLateTimes;
+	}
+
+	public void setSeriousLateTimes(Long seriousLateTimes) {
+		this.seriousLateTimes = seriousLateTimes;
+	}
+
+	public Long getLeaveEarlyTimes() {
+		return leaveEarlyTimes;
+	}
+
+	public void setLeaveEarlyTimes(Long leaveEarlyTimes) {
+		this.leaveEarlyTimes = leaveEarlyTimes;
+	}
+
+	public Long getAbsenteeismTimes() {
+		return absenteeismTimes;
+	}
+
+	public void setAbsenteeismTimes(Long absenteeismTimes) {
+		this.absenteeismTimes = absenteeismTimes;
+	}
+
+	public Long getNotSignedCount() {
+		return notSignedCount;
+	}
+
+	public void setNotSignedCount(Long notSignedCount) {
+		this.notSignedCount = notSignedCount;
+	}
+}

+ 202 - 0
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForDay.java

@@ -0,0 +1,202 @@
+package com.x.attendance.entity;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+import javax.persistence.*;
+
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.StatisticDingdingUnitForDay.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.StatisticDingdingUnitForDay.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class StatisticDingdingUnitForDay extends SliceJpaObject {
+
+
+
+	private static final String TABLE = PersistenceProperties.StatisticDingdingUnitForDay.table;
+	private static final long serialVersionUID = 2090817422412907325L;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	public void onPersist() throws Exception {
+	}
+	/*
+	 * =============================================================================
+	 * ===== 以上为 JpaObject 默认字段
+	 * =============================================================================
+	 * =====
+	 */
+
+	/*
+	 * =============================================================================
+	 * ===== 以下为具体不同的业务及数据表字段要求
+	 * =============================================================================
+	 * =====
+	 */
+
+	@FieldDescribe("O2用户所在的组织")
+	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@CheckPersist(allowEmpty = false)
+	private String o2Unit;
+
+	@FieldDescribe("统计年份")
+	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticYear;
+
+	@FieldDescribe("统计月份")
+	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticMonth;
+
+	@FieldDescribe("统计日期")
+	@Column(name = "xstatisticDate", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticDate;
+
+	@FieldDescribe("出勤人数")
+	@Column(name = "xworkDayCount")
+	private Long workDayCount;
+
+	@FieldDescribe("上班签到人数")
+	@Column(name = "xonDutyTimes")
+	private Long onDutyTimes;
+
+	@FieldDescribe("下班签到人数")
+	@Column(name = "xoffDutyTimes")
+	private Long offDutyTimes;
+
+	@FieldDescribe("迟到人数")
+	@Column(name = "xlateTimes")
+	private Long lateTimes;
+
+	@FieldDescribe("严重迟到人数")
+	@Column(name = "xSeriousLateTimes")
+	private Long seriousLateTimes;
+
+	@FieldDescribe("早退人数")
+	@Column(name = "xleaveEarlyTimes")
+	private Long leaveEarlyTimes;
+
+	@FieldDescribe("旷工人数")
+	@Column(name = "xAbsenteeismTimes")
+	private Long absenteeismTimes;
+
+	@FieldDescribe("未打卡人数")
+	@Column(name = "xNotSignedCount")
+	private Long notSignedCount;
+
+
+	public String getStatisticDate() {
+		return statisticDate;
+	}
+
+	public void setStatisticDate(String statisticDate) {
+		this.statisticDate = statisticDate;
+	}
+
+	public String getO2Unit() {
+		return o2Unit;
+	}
+
+	public void setO2Unit(String o2Unit) {
+		this.o2Unit = o2Unit;
+	}
+
+	public String getStatisticYear() {
+		return statisticYear;
+	}
+
+	public void setStatisticYear(String statisticYear) {
+		this.statisticYear = statisticYear;
+	}
+
+	public String getStatisticMonth() {
+		return statisticMonth;
+	}
+
+	public void setStatisticMonth(String statisticMonth) {
+		this.statisticMonth = statisticMonth;
+	}
+
+	public Long getWorkDayCount() {
+		return workDayCount;
+	}
+
+	public void setWorkDayCount(Long workDayCount) {
+		this.workDayCount = workDayCount;
+	}
+
+	public Long getOnDutyTimes() {
+		return onDutyTimes;
+	}
+
+	public void setOnDutyTimes(Long onDutyTimes) {
+		this.onDutyTimes = onDutyTimes;
+	}
+
+	public Long getOffDutyTimes() {
+		return offDutyTimes;
+	}
+
+	public void setOffDutyTimes(Long offDutyTimes) {
+		this.offDutyTimes = offDutyTimes;
+	}
+
+	public Long getLateTimes() {
+		return lateTimes;
+	}
+
+	public void setLateTimes(Long lateTimes) {
+		this.lateTimes = lateTimes;
+	}
+
+	public Long getSeriousLateTimes() {
+		return seriousLateTimes;
+	}
+
+	public void setSeriousLateTimes(Long seriousLateTimes) {
+		this.seriousLateTimes = seriousLateTimes;
+	}
+
+	public Long getLeaveEarlyTimes() {
+		return leaveEarlyTimes;
+	}
+
+	public void setLeaveEarlyTimes(Long leaveEarlyTimes) {
+		this.leaveEarlyTimes = leaveEarlyTimes;
+	}
+
+	public Long getAbsenteeismTimes() {
+		return absenteeismTimes;
+	}
+
+	public void setAbsenteeismTimes(Long absenteeismTimes) {
+		this.absenteeismTimes = absenteeismTimes;
+	}
+
+	public Long getNotSignedCount() {
+		return notSignedCount;
+	}
+
+	public void setNotSignedCount(Long notSignedCount) {
+		this.notSignedCount = notSignedCount;
+	}
+}

+ 190 - 0
o2server/x_attendance_core_entity/src/main/java/com/x/attendance/entity/StatisticDingdingUnitForMonth.java

@@ -0,0 +1,190 @@
+package com.x.attendance.entity;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+
+import javax.persistence.*;
+
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.StatisticDingdingUnitForMonth.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.StatisticDingdingUnitForMonth.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class StatisticDingdingUnitForMonth extends SliceJpaObject {
+
+
+
+	private static final String TABLE = PersistenceProperties.StatisticDingdingUnitForMonth.table;
+	private static final long serialVersionUID = 2831416127767736230L;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	public void onPersist() throws Exception {
+	}
+	/*
+	 * =============================================================================
+	 * ===== 以上为 JpaObject 默认字段
+	 * =============================================================================
+	 * =====
+	 */
+
+	/*
+	 * =============================================================================
+	 * ===== 以下为具体不同的业务及数据表字段要求
+	 * =============================================================================
+	 * =====
+	 */
+
+	@FieldDescribe("O2用户所在的组织")
+	@Column(name = ColumnNamePrefix + "o2Unit", length = length_128B)
+	@CheckPersist(allowEmpty = false)
+	private String o2Unit;
+
+
+	@FieldDescribe("统计年份")
+	@Column(name = "xstatisticYear", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticYear;
+
+	@FieldDescribe("统计月份")
+	@Column(name = "xstatisticMonth", length = JpaObject.length_16B)
+	@CheckPersist(allowEmpty = false)
+	private String statisticMonth;
+
+	@FieldDescribe("出勤天数")
+	@Column(name = "xworkDayCount")
+	private Long workDayCount;
+
+	@FieldDescribe("上班签到人数")
+	@Column(name = "xonDutyTimes")
+	private Long onDutyTimes;
+
+	@FieldDescribe("下班签到人数")
+	@Column(name = "xoffDutyTimes")
+	private Long offDutyTimes;
+
+	@FieldDescribe("迟到人数")
+	@Column(name = "xlateTimes")
+	private Long lateTimes;
+
+	@FieldDescribe("严重迟到人数")
+	@Column(name = "xSeriousLateTimes")
+	private Long seriousLateTimes;
+
+	@FieldDescribe("早退人数")
+	@Column(name = "xleaveEarlyTimes")
+	private Long leaveEarlyTimes;
+
+	@FieldDescribe("旷工人数")
+	@Column(name = "xAbsenteeismTimes")
+	private Long absenteeismTimes;
+
+	@FieldDescribe("未打卡人数")
+	@Column(name = "xNotSignedCount")
+	private Long notSignedCount;
+
+
+	public String getO2Unit() {
+		return o2Unit;
+	}
+
+	public void setO2Unit(String o2Unit) {
+		this.o2Unit = o2Unit;
+	}
+
+	public String getStatisticYear() {
+		return statisticYear;
+	}
+
+	public void setStatisticYear(String statisticYear) {
+		this.statisticYear = statisticYear;
+	}
+
+	public String getStatisticMonth() {
+		return statisticMonth;
+	}
+
+	public void setStatisticMonth(String statisticMonth) {
+		this.statisticMonth = statisticMonth;
+	}
+
+	public Long getWorkDayCount() {
+		return workDayCount;
+	}
+
+	public void setWorkDayCount(Long workDayCount) {
+		this.workDayCount = workDayCount;
+	}
+
+	public Long getOnDutyTimes() {
+		return onDutyTimes;
+	}
+
+	public void setOnDutyTimes(Long onDutyTimes) {
+		this.onDutyTimes = onDutyTimes;
+	}
+
+	public Long getOffDutyTimes() {
+		return offDutyTimes;
+	}
+
+	public void setOffDutyTimes(Long offDutyTimes) {
+		this.offDutyTimes = offDutyTimes;
+	}
+
+	public Long getLateTimes() {
+		return lateTimes;
+	}
+
+	public void setLateTimes(Long lateTimes) {
+		this.lateTimes = lateTimes;
+	}
+
+	public Long getSeriousLateTimes() {
+		return seriousLateTimes;
+	}
+
+	public void setSeriousLateTimes(Long seriousLateTimes) {
+		this.seriousLateTimes = seriousLateTimes;
+	}
+
+	public Long getLeaveEarlyTimes() {
+		return leaveEarlyTimes;
+	}
+
+	public void setLeaveEarlyTimes(Long leaveEarlyTimes) {
+		this.leaveEarlyTimes = leaveEarlyTimes;
+	}
+
+	public Long getAbsenteeismTimes() {
+		return absenteeismTimes;
+	}
+
+	public void setAbsenteeismTimes(Long absenteeismTimes) {
+		this.absenteeismTimes = absenteeismTimes;
+	}
+
+	public Long getNotSignedCount() {
+		return notSignedCount;
+	}
+
+	public void setNotSignedCount(Long notSignedCount) {
+		this.notSignedCount = notSignedCount;
+	}
+}

+ 2 - 1
o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_attendance_assemble_control.java

@@ -15,7 +15,8 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.attendance.entity.StatisticTopUnitForDay", "com.x.attendance.entity.StatisticTopUnitForMonth",
 		"com.x.attendance.entity.StatisticUnitForDay", "com.x.attendance.entity.StatisticUnitForMonth",
 		"com.x.attendance.entity.AttendanceDingtalkDetail", "com.x.attendance.entity.AttendanceQywxDetail",
-		"com.x.attendance.entity.DingdingQywxSyncRecord"}, storeJars = {
+		"com.x.attendance.entity.DingdingQywxSyncRecord", "com.x.attendance.entity.StatisticDingdingPersonForMonth",
+		"com.x.attendance.entity.StatisticDingdingUnitForDay", "com.x.attendance.entity.StatisticDingdingUnitForMonth"}, storeJars = {
 				"x_attendance_core_entity", "x_organization_core_express", "x_organization_core_entity" })
 public class x_attendance_assemble_control extends Deployable {
 }