Bladeren bron

请假时长

shiqian 3 jaren geleden
bovenliggende
commit
9e49231ad9

+ 40 - 0
boman-common/boman-common-core/src/main/java/com/boman/common/core/utils/DateUtils.java

@@ -49,6 +49,36 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
         return new Date();
     }
 
+    /**
+     * 当天的开始时间
+     */
+    public static Date getTodayStart() {
+        String time = getDate() + " 00:00:00";
+        return strToDate(time, YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * 指定日期的的开始时间
+     */
+    public static Date getDayStartFromTime(String time) {
+        return strToDate(time + " 00:00:00", YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * 指定日期的的结束时间
+     */
+    public static Date getDayEndFromTime(String time) {
+        return strToDate(time + " 23:59:59", YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * 当天的结束时间
+     */
+    public static Date getTodayEnd() {
+        String time = getDate() + " 23:59:59";
+        return strToDate(time, YYYY_MM_DD_HH_MM_SS);
+    }
+
     public static Date strToDate(String strDate, String format) {
         SimpleDateFormat formatter = new SimpleDateFormat(format);
         ParsePosition pos = new ParsePosition(0);
@@ -68,6 +98,16 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
         return dateTimeNow(YYYY);
     }
 
+    public static long calcMinutes(Date before, Date after) {
+        long beforeTime = before.getTime(), afterTime = after.getTime();
+        return (afterTime - beforeTime) / 1000 / 60;
+    }
+
+    public static long calcDays(Date before, Date after) {
+        long beforeTime = before.getTime(), afterTime = after.getTime();
+        return (afterTime - beforeTime) / 1000 / 60 / 60 / 24;
+    }
+
 
     public static String getMonth() {
         Calendar calendar = Calendar.getInstance();

+ 22 - 5
boman-web-core/src/main/java/com/boman/web/core/controller/AttendanceController.java

@@ -1,14 +1,23 @@
 package com.boman.web.core.controller;
 
+import com.alibaba.fastjson.JSONObject;
+import com.boman.common.core.utils.DateUtils;
 import com.boman.domain.dto.AjaxResult;
+import com.boman.domain.dto.Base64Dto;
 import com.boman.domain.dto.ClockOnDto;
 import com.boman.domain.dto.FormDataDto;
 import com.boman.web.core.service.attendance.AttendanceService;
+import com.boman.web.core.service.attendance.rules.AttendanceRulesService;
+import com.boman.web.core.utils.LeaveFromUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.sql.Timestamp;
+import java.util.Date;
 import java.util.Map;
 
+import static com.boman.web.core.utils.LeaveFromUtils.packTimes;
+
 /**
  * @author shiqian
  * @date 2021年06月03日 15:41
@@ -19,6 +28,8 @@ public class AttendanceController {
 
     @Resource
     private AttendanceService service;
+    @Resource
+    private AttendanceRulesService rulesService;
 
     /**
      * 功能描述: 打卡
@@ -103,13 +114,19 @@ public class AttendanceController {
         return service.findDate(date, userId);
     }
 
-    /**
-     * 请假通过后,修改考勤表对应时间的是否请假
-     * @param dto
-     * @return
-     */
     @PostMapping("/updateAttendance")
     public AjaxResult updateAttendance(FormDataDto dto) {
         return service.updateAttendance(dto);
     }
+
+    @PostMapping("/calcTime")
+    public AjaxResult test(@RequestBody JSONObject dto) {
+        Date startTime = dto.getDate("leavefrom_start_time");
+        Date endTime = dto.getDate("leavefrom_end_time");
+        Long deptId = dto.getLong("dept_id");
+        JSONObject rule = rulesService.listByDeptId(deptId);
+        long minutes = LeaveFromUtils.calcTimes(startTime, endTime, null, rule);
+        return AjaxResult.success("成功", packTimes(minutes));
+    }
+    
 }

+ 4 - 1
boman-web-core/src/main/java/com/boman/web/core/service/TableServiceCmdService.java

@@ -353,9 +353,12 @@ public class TableServiceCmdService {
                             }
                         }
                         // dateTime
-                        if (NEED_CONVERT_DATE_LIST.contains(columnType)) {
+                        if (DATE.equals(columnType)) {
                             column.setColumnValue(getStrDate(json.getTimestamp(columnName)));
+                        } else if (DATETIME.equals(columnType)) {
+                            column.setColumnValue(getStrTimeStamp(json.getTimestamp(columnName)));
                         }
+
                         // fk
                         if (isNotEmpty(column.getForeignKey())) {
                             Object value = json.get(columnName);

+ 293 - 0
boman-web-core/src/main/java/com/boman/web/core/utils/LeaveFromUtils.java

@@ -0,0 +1,293 @@
+package com.boman.web.core.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+
+import static com.boman.common.core.utils.DateUtils.*;
+import static com.boman.common.core.utils.obj.ObjectUtils.isEmpty;
+import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;
+import static com.boman.domain.constant.AttendanceRulesConst.*;
+
+/**
+ * @author shiqian
+ * @date 2021年08月05日 13:50
+ **/
+public class LeaveFromUtils {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(LeaveFromUtils.class);
+
+
+    /**
+     * 功能描述:
+     *
+     * @param startTime    请假开始时间
+     * @param endTime      请假结束时间
+     * @param yearMonthDay 递归的时候需要,传的是结束时间当天的yyyyMMdd
+     * @param rule         规则
+     * @return long 请假的总分钟数
+     */
+    public static long calcTimes(Date startTime, Date endTime, String yearMonthDay, JSONObject rule) {
+        long minutes = 0;
+        requireNonNull(startTime, "请假开始时间为空");
+        requireNonNull(endTime, "请假结束时间为空");
+        requireNonNull(rule, "未配置部门上下班规则");
+        if (endTime.before(startTime)) {
+            throw new IllegalArgumentException("请假结束时间必须大约开始时间");
+        } else if (endTime.equals(startTime)) {
+            return minutes;
+        }
+
+        // 递归的时候,这些时间不能以当天时间来算,而应该以请假结束时间所在的那一天来算(递归时使用)
+        // 规定上午上班时间 规定上午下班时间 规定下午上班时间 规定下午下班时间
+        Date amStart, amEnd, pmStart, pmEnd;
+        if (isEmpty(yearMonthDay)) {
+            amStart = strToDate(packRuleTime(rule.getString(ATTENDANCE_RULES_START_TIME)), YYYY_MM_DD_HH_MM_SS);
+            amEnd = strToDate(packRuleTime(rule.getString(ATTENDANCE_RULES_END_TIME)), YYYY_MM_DD_HH_MM_SS);
+            pmStart = strToDate(packRuleTime(rule.getString(ATTENDANCE_RULES_START_TIME_PM)), YYYY_MM_DD_HH_MM_SS);
+            pmEnd = strToDate(packRuleTime(rule.getString(ATTENDANCE_RULES_END_TIME_PM)), YYYY_MM_DD_HH_MM_SS);
+        } else {
+            String hourAmStart = rule.getString(ATTENDANCE_RULES_START_TIME);
+            String hourAmEnd = rule.getString(ATTENDANCE_RULES_END_TIME);
+            String hourPmStart = rule.getString(ATTENDANCE_RULES_START_TIME_PM);
+            String hourPmEnd = rule.getString(ATTENDANCE_RULES_END_TIME_PM);
+            amStart = strToDate(packRuleTime(yearMonthDay, hourAmStart), YYYY_MM_DD_HH_MM_SS);
+            amEnd = strToDate(packRuleTime(yearMonthDay, hourAmEnd), YYYY_MM_DD_HH_MM_SS);
+            pmStart = strToDate(packRuleTime(yearMonthDay, hourPmStart), YYYY_MM_DD_HH_MM_SS);
+            pmEnd = strToDate(packRuleTime(yearMonthDay, hourPmEnd), YYYY_MM_DD_HH_MM_SS);
+        }
+
+        // 一天的开始时间   一天的结束时间
+        Date todayStart = getTodayStart(), todayEnd = getTodayEnd();
+
+        // startTime 00:00 - 9:00
+        if (afterEq(startTime, todayStart) && beforeEq(startTime, amStart)) {
+            // 9:00 - 12:00
+            if (afterEq(endTime, amStart) && beforeEq(endTime, amEnd)) {
+                return calcMinutes(amStart, endTime);
+            } else if (afterEq(endTime, amEnd) && beforeEq(endTime, pmStart)) {
+                return calcMinutes(amStart, amEnd);
+            } else if (afterEq(endTime, pmStart) && beforeEq(endTime, pmEnd)) {
+                // 14:00 -  17:00
+                // 上午总时长
+                minutes = calcMinutes(amStart, amEnd);
+                // 下午请假时长
+                minutes += calcMinutes(pmStart, endTime);
+                return minutes;
+            } else if (afterEq(endTime, pmEnd) && beforeEq(endTime, todayEnd)) {
+                // 17:00 - 23:59 当天(言外之意就是请了一整天假)
+                minutes = calcMinutes(amStart, amEnd);
+                minutes += calcMinutes(pmStart, pmEnd);
+                return minutes;
+            } else if (endTime.after(todayEnd)) {
+                int dayOfStartTime = getDayFromTime(startTime);
+                int dayOfEndTime = getDayFromTime(endTime);
+                int days = dayOfEndTime - dayOfStartTime;
+                // 一整天请假时长
+                minutes = getWholeDayLeaveFrom(amStart, amEnd, pmStart, pmEnd);
+
+                // 规定的第二天上午(或者 第三天及以后)上班时间
+                startTime = amStart;
+                startTime = addDays(startTime, days);
+
+                // 请假到第二天
+                if (days != 1) {
+                    minutes += (days - 1) * minutes;
+                }
+                minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                return minutes;
+            }
+
+        } else if (afterEq(startTime, amStart) && beforeEq(startTime, amEnd)) {
+            // startTime 9:00 - 12:00
+            // endTime 9:00 - 12:00
+            if (afterEq(endTime, amStart) && beforeEq(endTime, amEnd)) {
+                return calcMinutes(startTime, endTime);
+                // 12:00 - 14:00之间
+            } else if (afterEq(endTime, amEnd) && beforeEq(endTime, pmStart)) {
+                return calcMinutes(startTime, amEnd);
+            } else if (afterEq(endTime, pmStart) && beforeEq(endTime, pmEnd)) {
+                // 14:00 -  17:00
+                // 上午总时长
+                minutes = calcMinutes(startTime, amEnd);
+                // 下午请假时长
+                minutes += calcMinutes(pmStart, endTime);
+                return minutes;
+            } else if (afterEq(endTime, pmEnd) && beforeEq(endTime, todayEnd)) {
+                // 17:00 - 23:59 当天(言外之意就是请了一整天假)
+                minutes = calcMinutes(startTime, amEnd);
+                minutes += calcMinutes(pmStart, pmEnd);
+                return minutes;
+            } else if (endTime.after(todayEnd)) {
+                int dayOfStartTime = getDayFromTime(startTime);
+                int dayOfEndTime = getDayFromTime(endTime);
+                int days = dayOfEndTime - dayOfStartTime;
+                // 头一天请假时长
+                minutes = getWholeDayLeaveFrom(startTime, amEnd, pmStart, pmEnd);
+
+                // 规定的第二天上午(或者 第三天及以后)上班时间
+                startTime = amStart;
+                startTime = addDays(startTime, days);
+
+                // 请假到第二天
+                if (days == 1) {
+                    minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                    return minutes;
+                } else {
+                    // 一整天请假时长
+                    minutes += (days - 1) * getWholeDayLeaveFrom(amStart, amEnd, pmStart, pmEnd);
+                    minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                    return minutes;
+                }
+            }
+        } else if (afterEq(startTime, amEnd) && beforeEq(startTime, pmStart)) {
+            // startTime 12:00 - 14:00
+            if (afterEq(endTime, pmStart) && beforeEq(endTime, pmEnd)) {
+                // 14:00 -  17:00
+                return calcMinutes(pmStart, endTime);
+            } else if (afterEq(endTime, pmEnd) && beforeEq(endTime, todayEnd)) {
+                // 17:00 - 23:59
+                return calcMinutes(pmStart, pmEnd);
+            } else if (endTime.after(todayEnd)) {
+                // 请假到第二天
+                int dayOfStartTime = getDayFromTime(startTime);
+                int dayOfEndTime = getDayFromTime(endTime);
+                int days = dayOfEndTime - dayOfStartTime;
+                // 头一天请假时长
+                minutes = getWholeDayLeaveFrom(null, null, pmStart, pmEnd);
+
+                // 规定的第二天上午(或者 第三天及以后)上班时间
+                startTime = amStart;
+                startTime = addDays(startTime, days);
+
+                // 请假到第二天
+                if (days == 1) {
+                    minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                    return minutes;
+                } else {
+                    minutes += (days - 1) * getWholeDayLeaveFrom(amStart, amEnd, pmStart, pmEnd);
+                    minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                    return minutes;
+                }
+            }
+        } else if (afterEq(startTime, pmStart) && beforeEq(startTime, pmEnd)) {
+            // startTime 14:00 - 17:00
+            if (afterEq(endTime, pmStart) && beforeEq(endTime, pmEnd)) {
+                // 14:00 -  17:00
+                return calcMinutes(startTime, endTime);
+            } else if (afterEq(endTime, pmEnd) && beforeEq(endTime, todayEnd)) {
+                // 17:00 - 23:59
+                return calcMinutes(startTime, pmEnd);
+            } else if (endTime.after(todayEnd)) {
+                // 请假到第二天
+                // 请假到第二天
+                int dayOfStartTime = getDayFromTime(startTime);
+                int dayOfEndTime = getDayFromTime(endTime);
+                int days = dayOfEndTime - dayOfStartTime;
+                // 头一天请假时长
+                minutes = getWholeDayLeaveFrom(null, null, startTime, pmEnd);
+
+                // 规定的第二天上午(或者 第三天及以后)上班时间
+                startTime = amStart;
+                startTime = addDays(startTime, days);
+
+                // 请假到第二天
+                if (days != 1) {
+                    minutes += (days - 1) * getWholeDayLeaveFrom(amStart, amEnd, pmStart, pmEnd);
+                }
+                minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                return minutes;
+            }
+        } else if (afterEq(startTime, pmEnd) && beforeEq(startTime, todayEnd)) {
+            // startTime 17:00 - 23:59 实际就等于是第二天的上班时间开始算请假时长
+            // 规定的第二天上午(或者 第三天及以后)上班时间
+            int tomorrowStartTime = getDayFromTime(startTime);
+            int dayOfEndTime = getDayFromTime(endTime);
+            int days = dayOfEndTime - tomorrowStartTime;
+
+            if (days == 1) {
+                startTime = amStart;
+                startTime = addDays(startTime, 1);
+                return calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+            } else {
+                minutes += calcTimes(startTime, endTime, getYearMonthDayFromTime(endTime), rule);
+                minutes += (days - 1) * getWholeDayLeaveFrom(amStart, amEnd, pmStart, pmEnd);
+                return minutes;
+            }
+        }
+
+        return minutes;
+    }
+
+    public static boolean beforeEq(Date one, Date another) {
+        return (one.before(another) || one.equals(another));
+    }
+
+
+    public static boolean afterEq(Date one, Date another) {
+        return (one.after(another) || one.equals(another));
+    }
+
+    public static String packTimes(long minutes) {
+        long hours = minutes / 60;
+        long minute = minutes % 60;
+        String h = hours + "小时";
+        return minute <= 0 ? h : h + minute + "分钟";
+    }
+
+    public static String packRuleTime(String time) {
+        String yyyyMmdd = getDate();
+        return yyyyMmdd + " " + time + ":00";
+    }
+
+    public static String packRuleTime(String yyyyMmdd, String hour) {
+        return yyyyMmdd + " " + hour + ":00";
+    }
+
+
+    /**
+     * 功能描述: 2021-11-10 15:15:15 => 10
+     *
+     * @param time 2021-11-10 15:15:15
+     * @return 时间中的日期(day)
+     */
+    public static int getDayFromTime(Date time) {
+        String strTime = dateTime1(time);
+        String substring = strTime.substring(8, 10);
+        return Integer.parseInt(substring);
+    }
+
+    /**
+     * 功能描述: (amEnd - amStart) + (pmEnd - pmStart) 总请假时长
+     *
+     * @param amStart 规定上午上班时间
+     * @param amEnd   规定上午下班时间
+     * @param pmStart 规定下午上班时间
+     * @param pmEnd   规定下午上班时间
+     * @return 总请假时长
+     */
+    public static long getWholeDayLeaveFrom(Date amStart, Date amEnd, Date pmStart, Date pmEnd) {
+        long minutes = 0;
+        if (amStart != null && amEnd != null) {
+            minutes = calcMinutes(amStart, amEnd);
+        }
+
+        minutes += calcMinutes(pmStart, pmEnd);
+        return minutes;
+    }
+
+
+    /**
+     * 功能描述: 2021-08-06 16:10:24 => 2021-08-06
+     *
+     * @param time time 2021-08-06 16:10:24
+     * @return 2021-08-06
+     */
+    public static String getYearMonthDayFromTime(Date time) {
+        String strTime = dateTime1(time);
+        return strTime.substring(0, 10);
+    }
+
+}