Explorar o código

完善计算加班完成时间。

zhengqiang %!s(int64=4) %!d(string=hai) anos
pai
achega
66989b5dae

+ 2 - 3
common/src/main/java/com/jpsoft/shinestar/modules/base/dao/WorkOverPersonDAO.java

@@ -22,9 +22,8 @@ public interface WorkOverPersonDAO {
     List<WorkOverPerson> list();
     List<WorkOverPerson> search(Map<String,Object> searchParams, List<Sort> sortList);
     List<WorkOverPerson> findByWorkOverId(String workOverId);
-    WorkOverPerson findByPersonIdAndDate(Long personId, Date attendanceDate);
+    WorkOverPerson findOneByPersonIdAndDate(Long personId, Date attendanceDate);
     List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate);
-    WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
-
+    WorkOverPerson findOneByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
     List<Map> findUnFinishByDate(Date startDate, Date endDate);
 }

+ 4 - 2
common/src/main/java/com/jpsoft/shinestar/modules/base/service/WorkOverPersonService.java

@@ -24,11 +24,13 @@ public interface WorkOverPersonService {
 
     List<WorkOverPerson> findByWorkOverId(String workOverId);
 
-    WorkOverPerson findByPersonIdAndDate(Long personId, Date attendanceDate);
+    WorkOverPerson findOneByPersonIdAndDate(Long personId, Date attendanceDate);
 
     List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate);
 
-    WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
+    WorkOverPerson findOneByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
 
     List<Map> findUnFinishByDate(Date startDate, Date endDate);
+
+    int updateFinishTime(String day);
 }

+ 108 - 4
common/src/main/java/com/jpsoft/shinestar/modules/base/service/impl/WorkOverPersonServiceImpl.java

@@ -2,14 +2,24 @@ package com.jpsoft.shinestar.modules.base.service.impl;
 
 import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
+import com.jpsoft.shinestar.modules.base.entity.PersonDeviceLog;
+import com.jpsoft.shinestar.modules.base.service.PersonDeviceLogService;
 import com.jpsoft.shinestar.modules.base.service.WorkOverPersonService;
 import com.jpsoft.shinestar.modules.base.dao.WorkOverPersonDAO;
 import com.jpsoft.shinestar.modules.base.entity.WorkOverPerson;
+import com.jpsoft.shinestar.modules.base.service.WorkOverService;
 import com.jpsoft.shinestar.modules.common.dto.Sort;
+import com.jpsoft.shinestar.modules.sys.entity.DataDictionary;
+import com.jpsoft.shinestar.modules.sys.service.DataDictionaryService;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import org.joda.time.Minutes;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -18,6 +28,7 @@ import java.util.Map;
  * @author 墨鱼_mo
  * @date 2021-5-21 9:21
  */
+@Slf4j
 @Transactional
 @Component(value="workOverPersonService")
 public class WorkOverPersonServiceImpl implements WorkOverPersonService {
@@ -25,6 +36,15 @@ public class WorkOverPersonServiceImpl implements WorkOverPersonService {
     @Resource(name="workOverPersonDAO")
     private WorkOverPersonDAO workOverPersonDAO;
 
+    @Autowired
+    private PersonDeviceLogService personDeviceLogService;
+
+    @Autowired
+    private DataDictionaryService dataDictionaryService;
+
+    @Autowired
+    private WorkOverService workOverService;
+
     @Override
     public WorkOverPerson get(String id) {
         // TODO Auto-generated method stub
@@ -80,8 +100,8 @@ public class WorkOverPersonServiceImpl implements WorkOverPersonService {
     }
 
     @Override
-    public WorkOverPerson findByPersonIdAndDate(Long personId, Date attendanceDate) {
-        return workOverPersonDAO.findByPersonIdAndDate(personId,attendanceDate);
+    public WorkOverPerson findOneByPersonIdAndDate(Long personId, Date attendanceDate) {
+        return workOverPersonDAO.findOneByPersonIdAndDate(personId,attendanceDate);
     }
 
     @Override
@@ -90,12 +110,96 @@ public class WorkOverPersonServiceImpl implements WorkOverPersonService {
     }
 
     @Override
-    public WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes) {
-        return workOverPersonDAO.findByPersonIdAndOffsetMinute(personId,recordTime,earlyMinutes,delayMinutes);
+    public WorkOverPerson findOneByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes) {
+        return workOverPersonDAO.findOneByPersonIdAndOffsetMinute(personId,recordTime,earlyMinutes,delayMinutes);
     }
 
     @Override
     public List<Map> findUnFinishByDate(Date startDate, Date endDate) {
         return workOverPersonDAO.findUnFinishByDate(startDate, endDate);
     }
+
+    @Override
+    public int updateFinishTime(String day) {
+        int affectCount = 0;
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+            Date startDate = sdf.parse(day + " 00:00");
+            Date endDate = sdf.parse(day + " 23:59");
+
+            List<DataDictionary> ddList = dataDictionaryService.findByCatalogName("设备用途");
+
+            String scene = "";
+
+            for (DataDictionary dd : ddList) {
+                if (dd.getName().indexOf("考勤") != -1) {
+                    scene = dd.getValue();
+                    break;
+                }
+            }
+
+            //查询当天申请加班记录
+            List<Map> mapList = findUnFinishByDate(startDate, endDate);
+
+            for (Map map : mapList) {
+                String id = map.get("id_").toString();
+                Long personId = Long.valueOf(map.get("person_id").toString());
+                DateTime startTime = new DateTime((Date) map.get("start_time"));
+                DateTime endTime = new DateTime((Date) map.get("end_time"));
+
+                List<PersonDeviceLog> personDeviceLogs = personDeviceLogService.findByPersonAndDateAndScene(personId,
+                        startTime.plusHours(-1).toDate(), endTime.plusHours(2).toDate(), scene);
+
+                boolean exist = false;
+
+                //取最后一条
+                if (personDeviceLogs.size() > 0) {
+                    PersonDeviceLog personDeviceLog = personDeviceLogs.get(personDeviceLogs.size() - 1);
+
+                    //最后一条打卡记录>加班开始时间+30分钟
+                    if(personDeviceLog.getRecordTime().after(startTime.plusMinutes(30).toDate())){
+                        exist = true;
+
+                        boolean result = workOverService.punchIn(personDeviceLog.getDeviceNo(), personDeviceLog.getPersonId(), personDeviceLog.getRecordTime());
+
+                        if (result) {
+                            affectCount++;
+                        }
+                    }
+                }
+
+                if(!exist){
+                    //查询该员工半小时内是否还有加班,如果有则直接取计划结束时间作为实际完成时间
+                    WorkOverPerson nextWorkOverPerson = findOneByPersonIdAndDate(personId, endTime.plusMinutes(30).toDate());
+
+                    if (nextWorkOverPerson != null) {
+                        WorkOverPerson workOverPerson = get(id);
+
+                        if (workOverPerson.getBeginTime() == null) {
+                            workOverPerson.setBeginTime(startTime.toDate());
+                        }
+
+                        workOverPerson.setFinishTime(endTime.toDate());
+
+                        int minutes = (int) Minutes.minutesBetween(startTime, new DateTime(workOverPerson.getFinishTime())).getMinutes();
+                        workOverPerson.setDuration(minutes);
+
+                        int intHours = minutes / 60;
+                        int intMinutes = minutes % 60;
+                        workOverPerson.setDurationStr(intHours + "小时" + intMinutes + "分钟");
+
+                        workOverPerson.setUpdateTime(new Date());
+
+                        update(workOverPerson);
+                    }
+                }
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+        }
+
+        return affectCount;
+    }
 }

+ 30 - 3
common/src/main/java/com/jpsoft/shinestar/modules/base/service/impl/WorkOverServiceImpl.java

@@ -17,7 +17,6 @@ import com.jpsoft.shinestar.modules.workflow.service.ProcinstActivityService;
 import com.jpsoft.shinestar.modules.workflow.service.ProcinstService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
 import org.joda.time.DateTime;
 import org.joda.time.Minutes;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -514,7 +513,7 @@ public class WorkOverServiceImpl implements WorkOverService {
 
 		try {
 			//查询当前打卡时间是否在加班时段内
-			WorkOverPerson workOverPerson = workOverPersonService.findByPersonIdAndOffsetMinute(personId, recordTime, -60, 120);
+			WorkOverPerson workOverPerson = workOverPersonService.findOneByPersonIdAndOffsetMinute(personId, recordTime, -60, 120);
 
 			if(workOverPerson!=null) {
 				WorkOver workOver = workOverService.get(workOverPerson.getWorkOverId());
@@ -528,7 +527,7 @@ public class WorkOverServiceImpl implements WorkOverService {
 //							workOverPerson.setBeginTime(recordTime);
 //						}
 						if (workOverPerson.getFinishTime() == null) {
-							if(recordTime.after(workOverPerson.getBeginTime())) {
+							if(recordTime.after(new DateTime(workOverPerson.getBeginTime()).plusMinutes(30).toDate())) {
 								workOverPerson.setFinishTime(recordTime);
 							}
 						} else if (recordTime.after(workOverPerson.getFinishTime())) {
@@ -549,6 +548,34 @@ public class WorkOverServiceImpl implements WorkOverService {
 					workOverPersonService.update(workOverPerson);
 				}
 
+				//查询半小时前是否有加班,有时会有两个加班连起来
+				DateTime startTime = new DateTime(workOver.getStartTime());
+				WorkOverPerson prevWorkOverPerson = workOverPersonService.findOneByPersonIdAndDate(personId, startTime.plusMinutes(-30).toDate());
+
+				if(prevWorkOverPerson!=null){
+					WorkOver prevWorkOver = workOverService.get(prevWorkOverPerson.getWorkOverId());
+
+					if(prevWorkOver!=null){
+						if(prevWorkOverPerson.getBeginTime()==null){
+							prevWorkOverPerson.setBeginTime(prevWorkOver.getStartTime());
+						}
+
+						if(prevWorkOverPerson.getFinishTime()==null) {
+							workOverPerson.setFinishTime(prevWorkOver.getEndTime());
+						}
+
+						int minutes = (int) Minutes.minutesBetween(startTime, new DateTime(workOverPerson.getFinishTime())).getMinutes();
+						prevWorkOverPerson.setDuration(minutes);
+
+						int intHours = minutes / 60;
+						int intMinutes = minutes % 60;
+						prevWorkOverPerson.setDurationStr(intHours + "小时" + intMinutes + "分钟");
+						prevWorkOverPerson.setUpdateTime(new Date());
+
+						workOverPersonService.update(prevWorkOverPerson);
+					}
+				}
+
 				result = true;
 			}
 		}

+ 2 - 6
common/src/main/java/com/jpsoft/shinestar/modules/business/service/impl/WorkScheduleAttendanceServiceImpl.java

@@ -1,6 +1,5 @@
 package com.jpsoft.shinestar.modules.business.service.impl;
 
-import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
@@ -22,7 +21,6 @@ import com.jpsoft.shinestar.modules.sys.service.DataDictionaryService;
 import lombok.extern.slf4j.Slf4j;
 import org.joda.time.DateTime;
 import org.joda.time.Days;
-import org.joda.time.Hours;
 import org.joda.time.Minutes;
 import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
@@ -34,8 +32,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
-import java.net.URLEncoder;
-import java.text.MessageFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -433,7 +429,7 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
         DateTime endTime = timeMap.get("closingEndTime");
 
         //判断当前用户下班后是否被安排了加班,如果是则顺延考勤结束时间
-        WorkOverPerson workOverPerson = workOverPersonService.findByPersonIdAndDate(personId,attendanceTime.toDate());
+        WorkOverPerson workOverPerson = workOverPersonService.findOneByPersonIdAndDate(personId,attendanceTime.toDate());
 
         WorkOver workOver = null;
 
@@ -949,7 +945,7 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
                 }
             }
 
-            WorkOverPerson workOverPerson = workOverPersonService.findByPersonIdAndDate(personInfo.getId(),attendanceTime.toDate());
+            WorkOverPerson workOverPerson = workOverPersonService.findOneByPersonIdAndDate(personInfo.getId(),attendanceTime.toDate());
             WorkOver workOver = null;
 
             if(workOverPerson!=null) {

+ 5 - 2
common/src/main/resources/mapper/base/WorkOverPerson.xml

@@ -155,7 +155,7 @@
         and work_over_id = #{workOverId}
         ]]>
     </select>
-    <select id="findByPersonIdAndDate" resultMap="WorkOverPersonMap">
+    <select id="findOneByPersonIdAndDate" resultMap="WorkOverPersonMap">
         <![CDATA[
             SELECT
             a.*
@@ -193,7 +193,7 @@
                 and c.del_flag = 0
         ]]>
     </select>
-    <select id="findByPersonIdAndOffsetMinute" resultMap="WorkOverPersonMap">
+    <select id="findOneByPersonIdAndOffsetMinute" resultMap="WorkOverPersonMap">
         <![CDATA[
             SELECT
                 a.*,
@@ -207,13 +207,16 @@
                 b.person_id = #{personId}
                 and date_add(c.start_time,interval ${earlyMinutes} minute)<=#{recordTime}
                 and date_add(c.end_time,interval ${delayMinutes} minute)>=#{recordTime}
+                and (c.status_='1' or c.status_ = '4')
                 and a.del_flag=0
                 and c.del_flag = 0
+            limit 1
         ]]>
     </select>
     <select id="findUnFinishByDate" resultType="java.util.Map">
         <![CDATA[
             select
+            t1.id_,
             t4.name_,
             t3.person_id,
             t2.start_time,

+ 1 - 38
web/src/main/java/com/jpsoft/shinestar/modules/base/controller/WorkOverController.java

@@ -685,44 +685,7 @@ public class WorkOverController {
         MessageResult<Integer> messageResult = new MessageResult<>();
 
         try {
-            int affectCount = 0;
-
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
-            Date startDate = sdf.parse(day + " 00:00");
-            Date endDate = sdf.parse(day + " 23:59");
-
-            List<DataDictionary> ddList = dataDictionaryService.findByCatalogName("设备用途");
-
-            String scene = "";
-
-            for (DataDictionary dd : ddList) {
-                if (dd.getName().indexOf("考勤") != -1) {
-                    scene = dd.getValue();
-                    break;
-                }
-            }
-
-            //查询当天申请加班记录
-            List<Map> mapList = workOverPersonService.findUnFinishByDate(startDate,endDate);
-
-            for (Map map : mapList) {
-                Long personId = Long.valueOf(map.get("person_id").toString());
-                DateTime startTime = new DateTime((Date)map.get("start_time"));
-                DateTime endTime = new DateTime((Date) map.get("end_time"));
-
-                List<PersonDeviceLog> personDeviceLogs = personDeviceLogService.findByPersonAndDateAndScene(personId,
-                        startTime.plusHours(-1).toDate(), endTime.plusHours(2).toDate(), scene);
-
-                //取最后一条
-                if (personDeviceLogs.size()>0){
-                    PersonDeviceLog personDeviceLog = personDeviceLogs.get(personDeviceLogs.size()-1);
-                    boolean result = workOverService.punchIn(personDeviceLog.getDeviceNo(),personDeviceLog.getPersonId(),personDeviceLog.getRecordTime());
-
-                    if(result){
-                        affectCount++;
-                    }
-                }
-            }
+            int affectCount = workOverPersonService.updateFinishTime(day);
 
             //todo 填写具体代码
             messageResult.setData(affectCount);

+ 9 - 0
web/src/main/java/com/jpsoft/shinestar/scheduled/WorkScheduleTask.java

@@ -1,5 +1,6 @@
 package com.jpsoft.shinestar.scheduled;
 
+import com.jpsoft.shinestar.modules.base.service.WorkOverPersonService;
 import com.jpsoft.shinestar.modules.base.service.WorkShiftCompanyService;
 import com.jpsoft.shinestar.modules.business.service.WorkScheduleAttendanceService;
 import lombok.extern.slf4j.Slf4j;
@@ -20,6 +21,9 @@ public class WorkScheduleTask {
     @Autowired
     private WorkShiftCompanyService workShiftCompanyService;
 
+    @Autowired
+    private WorkOverPersonService workOverPersonService;
+
     /**
      * 每天5,18点统计昨天的考勤情况
      */
@@ -29,6 +33,11 @@ public class WorkScheduleTask {
         List<String> companyList = workShiftCompanyService.findDistinctCompanyId();
 
         DateTime prevTime = DateTime.now().minusDays(1).withTimeAtStartOfDay();
+        String prevDay = prevTime.toString("yyyy-MM-dd");
+
+        //更新加班结束时间
+        int affectCount = workOverPersonService.updateFinishTime(prevDay);
+        log.warn("更新{}加班结束时间共{}条", prevDay, affectCount);
 
         for (String companyId : companyList) {
             //查询前天考勤情况