Browse Source

1)配置模版后立即自动生成生效日期到今年和次年的作息, 2)定时任务在每年11月15日自动生成下一年的作息。3)修改作息模版后,自动修改生效日期后的已生成的作息 4)以最新修改为准,包括模版和app单日修改

zhulu 1 year ago
parent
commit
d65d8c362a

+ 10 - 1
project_data/sql/0.0.6/quartz/quartz.sql

@@ -1,2 +1,11 @@
 -- 每天更新履职任务状态 调整为没小时执行一次,解决营业前、中、后的任务 到时间后任务状态变为已逾期的问题
-UPDATE `sys_job` SET `cron_expression` = '0 0 * * * ?' WHERE `job_name` = '每天更新履职任务状态';
+UPDATE `sys_job` SET `cron_expression` = '0 0 * * * ?' WHERE `job_name` = '每天更新履职任务状态';
+
+-- 更新作息生成周期 在每年11月15日自动生成下一年的作息
+UPDATE `sys_job`
+SET
+    `invoke_target` = 'WorkTimeTask.generateNextYear',
+    `cron_expression` = '1 1 0 15 11 ?',
+    `job_name` = '生成下一年作息'
+WHERE
+        `job_name` = '生成下个月作息';

+ 6 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/RemoteWorkTimeService.java

@@ -44,4 +44,10 @@ public interface RemoteWorkTimeService {
      */
     @GetMapping("/work/timeSet/generateNextMonth")
     void generateNextMonth();
+
+    /**
+     * 生成下个月作息
+     */
+    @GetMapping("/work/timeSet/generateYearMonth")
+    void generateYearMonth();
 }

+ 5 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/factory/RemoteWorkTimesFallbackFactory.java

@@ -68,6 +68,11 @@ public class RemoteWorkTimesFallbackFactory implements FallbackFactory<RemoteWor
 
             }
 
+            @Override
+            public void generateYearMonth() {
+
+            }
+
 
         };
     }

+ 7 - 0
soc-modules/soc-modules-job/src/main/java/com/xunmei/job/task/WorkTimeTask.java

@@ -22,4 +22,11 @@ public class WorkTimeTask {
         workTimeService.generateNextMonth();
         log.info("生成下个月作息的任务执行结束,当前任务 id:{},当前时间:{}", id, new Date());
     }
+
+    public void generateNextYear()
+    {   String id = UUID.fastUUID().toString();
+        log.info("开始执行生成下一年作息的任务,当前任务 id:{},当前时间:{}", id, new Date());
+        workTimeService.generateYearMonth();
+        log.info("生成下一年作息的任务执行结束,当前任务 id:{},当前时间:{}", id, new Date());
+    }
 }

+ 7 - 0
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/controller/SysWorkTimeSetController.java

@@ -129,4 +129,11 @@ public class SysWorkTimeSetController extends BaseController {
         sysWorkTimeSetService.generateNextMonth();
         return AjaxResult.success("开始生成下个月作息!");
     }
+
+    @ApiOperation(value = "按作息模板生成下一年作息")
+    @GetMapping(value = "/generateYearMonth")
+    public AjaxResult generateNextYear() {
+        sysWorkTimeSetService.generateNextYear();
+        return AjaxResult.success("开始按作息模板生成下一年作息!");
+    }
 }

+ 2 - 0
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/service/ISysWorkTimeSetService.java

@@ -76,4 +76,6 @@ public interface ISysWorkTimeSetService extends IService<SysWorkTimeSet> {
     AjaxResult workTimePageList(SysWorkTimeSet sysWorkTimeSet) throws ParseException;
 
     void generateNextMonth();
+
+    void generateNextYear();
 }

+ 221 - 16
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/service/impl/SysWorkTimeSetServiceImpl.java

@@ -275,28 +275,44 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
         return sysWorkTimeSet;
     }
 
+    /**
+     * 1)配置模版后立即自动生成生效日期到今年和次年的作息,
+     * 2)定时任务在每年11月15日自动生成下一年的作息。
+     * 3)修改作息模版后,自动修改生效日期后的已生成的作息
+     * 4)以最新修改为准,包括模版和app单日修改
+     * @param request
+     * @return
+     */
     @Transactional(rollbackFor = Exception.class)
     @Override
     public AjaxResult add(SysWorkTimeSet request) {
+        if(ObjectUtil.isNull(request.getEffectiveDate())){
+            return error("作息模板的生效日期不能为空");
+        }
+
         if(DateUtil.endOfDay(DateTime.now()).after(request.getEffectiveDate()))
         {
             return error("作息模板的生效日期必须大于今天");
         }
+
+        if(CollectionUtils.isEmpty(request.getOrgIds()))
+        {
+            return error("作息模板机构不能为空");
+        }
+
         List<Long> orgIds = request.getOrgIds();
+
         for (Long oid : orgIds) {
             List<SysWorkTimeSet> sysWorkTimeSets = baseMapper.selectList(new LambdaQueryWrapper<SysWorkTimeSet>().eq(SysWorkTimeSet::getOrgId, oid));
-//如果id为空表示是新增,需要判断是否存在相同机构相同时间的模板
+            //如果id为空表示是新增,需要判断是否存在相同机构相同时间的模板
             if (request.getId() == null && sysWorkTimeSets.size() > 0) {
                 return error("机构'" + orgService.getById(oid).getName() + "'已存在作息模板,一个机构只允许同时存在一个作息模板");
             }
         }
-        int year = Calendar.getInstance().get(Calendar.YEAR);
-
-        if (request.getEffectiveDate() != null) {
-            year = new DateHelper(request.getEffectiveDate()).getYear();
-        }
+//        int year = Calendar.getInstance().get(Calendar.YEAR);
+        int year = new DateHelper(request.getEffectiveDate()).getYear();
 
-        if (CollectionUtils.isNotEmpty(orgIds)) {
+//        if (CollectionUtils.isNotEmpty(orgIds)) {
             List<SysWorkTimeSet> sets = new ArrayList<>();
             SysWorkTimeSet set = null;
             SysOrg org = null;
@@ -345,14 +361,13 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
             }
             //清除可能存在的旧作息数据
             sysWorkTimeSetDayofweekMapper.delete(new LambdaQueryWrapper<SysWorkTimeSetDayofweek>().in(SysWorkTimeSetDayofweek::getWorkTimeSetId, workTimeSetIds));
-            for (SysWorkTimeSetDayofweek s :
-                    dayOfWeeks) {
+            for (SysWorkTimeSetDayofweek s : dayOfWeeks) {
                 sysWorkTimeSetDayofweekMapper.insert(s);
             }
             if (CollectionUtils.isNotEmpty(dayOfWeeks)) {
-                changeOrgWorkTime(sets, dayOfWeeks, request.getEffectiveDate(), orgIds, request.getCheckDataResult());
+                changeOrgWorkTime(sets, request.getEffectiveDate(), orgIds);
             }
-        }
+//        }
         return success();
     }
 
@@ -449,6 +464,93 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
         }
     }
 
+    private void changeOrgWorkTime(List<SysWorkTimeSet> sets,Date effectiveDate, List<Long> orgIds) {
+        //如果生效年份等于当前年份,那么就重新生成生效日期后当年以及下一年的作息时间
+        int effectiveYear = new DateHelper(effectiveDate).getYear();
+        int dateNowYear = new DateHelper(new Date()).getYear();
+
+        // 如果模板的生效日期不是当年,则通过定时任务去生成下一年的作息
+        if (effectiveYear == dateNowYear) {
+            // 获取当前时间的Calendar实例
+            Calendar cal = Calendar.getInstance();
+            //设置年份
+            cal.set(Calendar.YEAR, effectiveYear + 2);
+            // DAY_OF_YEAR的值按照年份的第一天从1开始,设置为0可以得到前一年的最后一天
+            cal.set(Calendar.DAY_OF_YEAR, 0);
+            cal.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            //删除模板生效日期后的作息时间及下个年的作息时间,模板生成时直接覆盖手动设置的作息,谁后修改或后生成谁生效
+            Map<String, Object> map = new HashMap<>();
+            map.put("effectiveDate", effectiveDate);
+            map.put("lastDayOfNextMonth", DateUtil.format(cal.getTime(), "yyyy-MM-dd"));
+            map.put("orgIds", orgIds);
+            sysWorkTimeMapper.deleteOrgWorkTimeByMonth(map);
+            //获取不需要生成的日期 (模板生成时直接覆盖手动设置的作息,谁后修改或后生成谁生效,所有不需要在获取不需要生成的日期)
+            List<SysWorkTime> list = new ArrayList<>();
+            //添加当月生效日期后的作息时间及下个月的作息时间
+            final List<DateTime> dateTimeList = DateUtil.rangeToList(effectiveDate, cal.getTime(), DateField.DAY_OF_MONTH);
+            List<SysWorkTime> workTimeEditDtoListAll = new ArrayList<>();
+            for (SysWorkTimeSet workTime : sets) {
+                List<SysWorkTime> workTimeEditDtoList = new ArrayList<>();
+                for (DateTime time : dateTimeList) {
+                    Optional<SysWorkTimeSetDayofweek> dayOfWeekSetNew = workTime.getDayOfWeeks().stream().filter(w -> w.getDayOfWeek() == time.dayOfWeek() && ObjectUtil.isNotNull(w.getIsWorkday()) && w.getIsWorkday() > 0).findFirst();
+                    SysWorkTimeSetDayofweek dayOfWeekSet = dayOfWeekSetNew.orElse(null);
+                    boolean isEnable = ObjectUtil.isNotNull(dayOfWeekSet) && dayOfWeekSet.getIsWorkday() > 0;
+                    SysWorkTime dto = new SysWorkTime();
+                    dto.setDate(time);
+                    dto.setIsEnable(isEnable ? 1L : 0);
+
+                    if (ObjectUtil.isNull(dayOfWeekSet) || !(dayOfWeekSet.getIsWorkday() > 0)) {
+                        Optional<SysWorkTimeSetDayofweek> firstWorkDay = workTime.getDayOfWeeks().stream().filter(f -> f.getIsWorkday() > 0).findFirst();
+                        dayOfWeekSet = firstWorkDay.orElseGet(SysWorkTimeSetDayofweek::new);
+                    }
+                    dto.setWorkTime(dayOfWeekSet.getWorkTime());
+                    dto.setWorkOffTime(dayOfWeekSet.getWorkOffTime());
+                    dto.setOpenTime(dayOfWeekSet.getOpenTime());
+                    dto.setCloseTime(dayOfWeekSet.getCloseTime());
+                    dto.setNoonbreakStart(dayOfWeekSet.getNoonbreakStart());
+                    dto.setNoonbreakEnd(dayOfWeekSet.getNoonbreakEnd());
+                    workTimeEditDtoList.add(dto);
+                }
+                workTimeEditDtoListAll.addAll(workTimeEditDtoList);
+            }
+            if (CollectionUtils.isNotEmpty(workTimeEditDtoListAll)) {
+                SysWorkTimeSet requesta = new SysWorkTimeSet();
+                requesta.setOrgIds(orgIds);
+                //获取所有的作息配置
+                List<SysWorkTimeSet> listSet = sysWorkTimeSetMapper.selectWorkTimeSetList(requesta);
+                for (Long orgId : orgIds) {
+                    List<SysWorkTimeSet> listSetOrg = listSet.stream().filter(f -> f.getOrgId().equals(orgId) && f.getEffectiveDate().getTime() != effectiveDate.getTime()).collect(Collectors.toList());
+                    if (CollectionUtils.isNotEmpty(listSetOrg)) {
+                        List<Date> dateList = new ArrayList<>();
+                        dateList.add(effectiveDate);
+                        listSetOrg.forEach(f -> {
+                            dateList.add(f.getEffectiveDate());
+                        });
+                        //dateList排序
+                        dateList.sort(Comparator.comparing(Date::getTime));
+                        //取出request.getEffectiveDate()在dateList中的位置
+                        int index = dateList.indexOf(effectiveDate);
+                        if (index != dateList.size() - 1) {
+                            Date effectiveDateNext = dateList.get(index + 1);
+                            //取出workTimeEditDtoListAll中ymd_date在EffectiveDate和effectiveDateNext之间的数据
+                            List<SysWorkTime> workTimeEditDtoList = workTimeEditDtoListAll.stream().filter(f -> f.getDate().getTime() >= effectiveDate.getTime() && f.getDate().getTime() < effectiveDateNext.getTime()).collect(Collectors.toList());
+                            List<Date> remDates = workTimeEditDtoList.stream().map(SysWorkTime::getDate).collect(Collectors.toList());
+                            workTimeService.remove(new LambdaQueryWrapper<SysWorkTime>().eq(SysWorkTime::getOrgId, orgId).in(SysWorkTime::getYmdDate, remDates).eq(SysWorkTime::getIsManual, 0));
+                            batchnew(orgId, workTimeEditDtoList, list);
+                        } else {
+                            workTimeService.remove(new LambdaQueryWrapper<SysWorkTime>().eq(SysWorkTime::getOrgId, orgId).ge(SysWorkTime::getYmdDate, effectiveDate).eq(SysWorkTime::getIsManual, 0));
+                            batchnew(orgId, workTimeEditDtoListAll, list);
+                        }
+                    } else {
+                        batchnew(orgId, workTimeEditDtoListAll, list);
+                    }
+
+                }
+            }
+        }
+    }
+
+
     public List<SysWorkTime> batchnew(Long orgId, List<SysWorkTime> workTimeDtoList, List<SysWorkTime> list) {
         // 小于现在时间的不允许修改
         final Date now = DateUtil.beginOfDay(new Date());
@@ -491,8 +593,7 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
 //            sysWorkTimeMapper.insert(s);
 //            workTimeList.add(s);
 //        }
-        for (SysWorkTime s :
-                list1) {
+        for (SysWorkTime s : list1) {
 
             s.setYmdDate(s.getDate());
             s.setYmdDay(Long.valueOf(s.getYmd().getDay()));
@@ -591,6 +692,52 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
         generateWorkTime(year, calendar.get(Calendar.MONTH));
     }
 
+    /**
+     * 生成下个月的作息
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void generateNextYear() {
+        List<DateTime> dateTimeList= getNextYearDateList();
+        generateWorkTime(dateTimeList);
+    }
+
+    /**
+     * 获取下一月生成作息的日期列表
+     * @return
+     */
+    public List<DateTime> getNextMonthDateList(){
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        calendar.add(Calendar.MONTH, 1);
+        final Date date = com.xunmei.common.core.utils.DateHelper.getDate(calendar.getTime());
+        final com.xunmei.common.core.utils.DateHelper dateTime = new com.xunmei.common.core.utils.DateHelper(date);
+        final Date start = dateTime.monthStart();
+        final Date end = dateTime.monthEnd();
+        final List<DateTime> dateTimeList = DateUtil.rangeToList(start, end, DateField.DAY_OF_MONTH);
+        return dateTimeList;
+    }
+
+    /**
+     * 获取下一年生成作息的日期列表
+     * @return
+     */
+    public List<DateTime> getNextYearDateList(){
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        calendar.add(Calendar.YEAR, 1);
+        calendar.set(Calendar.DAY_OF_YEAR, 1);
+        final Date date = com.xunmei.common.core.utils.DateHelper.getDate(calendar.getTime());
+        final com.xunmei.common.core.utils.DateHelper dateTime = new com.xunmei.common.core.utils.DateHelper(date);
+        final Date start = dateTime.yearStart();
+        final Date end = dateTime.yearEnd();
+        final List<DateTime> dateTimeList = DateUtil.rangeToList(start, end, DateField.DAY_OF_MONTH);
+        return dateTimeList;
+    }
+
+
+
     @Transactional(rollbackFor = Exception.class)
     public void generateWorkTime(int year, int month) {
         Calendar calendar = Calendar.getInstance();
@@ -676,18 +823,76 @@ public class SysWorkTimeSetServiceImpl extends ServiceImpl<SysWorkTimeSetMapper,
 //                list1 = workTimeEditDtos;
 //            }
             list1 = workTimeEditDtos;
-            batch(dayMap.getKey(), date, list1);
+            batch(dayMap.getKey(),list1);
         }
 
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    public void generateWorkTime(List<DateTime> dateTimeList) {
+        List<SysWorkTimeSet> workTimes = this.list(new LambdaQueryWrapper<SysWorkTimeSet>());
+        Map<Long, List<SysWorkTimeSet>> group = workTimes.stream()
+                .sorted(Comparator.comparing(SysWorkTimeSet::getEffectiveDate).reversed())
+                .collect(Collectors.groupingBy(SysWorkTimeSet::getOrgId));
+
+        List<SysWorkTime> workTimeEditDtoList = new ArrayList<>();
+        for (DateTime time : dateTimeList) {
+            Date date1 = time.toJdkDate();
+            System.out.println("date1:" + date1);
+            //for(Long orgId:group.keySet()) {
+            for (Map.Entry<Long, List<SysWorkTimeSet>> setMap : group.entrySet()) {
+                Optional<SysWorkTimeSet> ws = setMap.getValue().stream().filter(w -> date1.after(w.getEffectiveDate()) || DateUtil.isSameDay(date1, w.getEffectiveDate())).findFirst();
+                if (!ws.isPresent()) {
+                    continue;
+                }
+                SysWorkTimeSet set = ws.get();
+                List<SysWorkTimeSetDayofweek> temp = this.sysWorkTimeSetDayofweekMapper.selectList(new LambdaQueryWrapper<SysWorkTimeSetDayofweek>().eq(SysWorkTimeSetDayofweek::getWorkTimeSetId, set.getId()));
+                set.setDayOfWeeks(temp);
+                Long i = (long) time.dayOfWeek();
+                SysWorkTimeSetDayofweek dayOfWeekSet = temp.stream().filter(e -> e.getDayOfWeek().equals(i)).findFirst().orElse(null);
+
+                boolean isEnable = ObjectUtil.isNotNull(dayOfWeekSet) && dayOfWeekSet.getIsWorkday() > 0;
+                SysWorkTime dto = new SysWorkTime();
+                dto.setDate(time);
+                dto.setOrgId(setMap.getKey());
+                dto.setIsEnable(isEnable ? 1L : 0L);
+                if (ObjectUtil.isNull(dayOfWeekSet) || !(dayOfWeekSet.getIsWorkday() > 0)) {
+                    Optional<SysWorkTimeSetDayofweek> firstWorkDay = set.getDayOfWeeks().stream().filter(f -> f.getIsWorkday() > 0).findFirst();
+                    if (firstWorkDay.isPresent()) {
+                        dayOfWeekSet = firstWorkDay.orElseGet(SysWorkTimeSetDayofweek::new);
+                    }
+                }
+                //dto.setIsEnable(dayOfWeekSet.getIsWorkday());
+//                workTimeEditDtoList.add(dto);
+                dto.setWorkTime(dayOfWeekSet.getWorkTime());
+                dto.setWorkOffTime(dayOfWeekSet.getWorkOffTime());
+                dto.setOpenTime(dayOfWeekSet.getOpenTime());
+                dto.setCloseTime(dayOfWeekSet.getCloseTime());
+                dto.setNoonbreakStart(dayOfWeekSet.getNoonbreakStart());
+                dto.setNoonbreakEnd(dayOfWeekSet.getNoonbreakEnd());
+                workTimeEditDtoList.add(dto);
+            }
+        }
+
+        Map<Long, List<SysWorkTime>> groupDay = workTimeEditDtoList.stream().collect(Collectors.groupingBy(SysWorkTime::getOrgId));
+        //自动生成时覆盖按日维护的的作息,谁后生成或者后修改谁生效, 删除下一年已有的作息
+        final LambdaQueryWrapper<SysWorkTime> sysWorkTimeLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        sysWorkTimeLambdaQueryWrapper.ge(SysWorkTime::getYmdDate,dateTimeList.get(0).toString("yyyy-MM-dd"));
+        sysWorkTimeLambdaQueryWrapper.le(SysWorkTime::getYmdDate,dateTimeList.get(dateTimeList.size()-1).toString("yyyy-MM-dd"));
+        sysWorkTimeMapper.delete(sysWorkTimeLambdaQueryWrapper);
+
+        for (Map.Entry<Long, List<SysWorkTime>> dayMap : groupDay.entrySet()) {
+            batch(dayMap.getKey(), dayMap.getValue());
+        }
+    }
+
+
     /**
      * @param orgId
-     * @param month
      * @param workTimeEditDtoList
      */
     @Transactional
-    public void batch(final Long orgId, final Date month, final List<SysWorkTime> workTimeEditDtoList) {
+    public void batch(final Long orgId, final List<SysWorkTime> workTimeEditDtoList) {
         // 小于现在时间的不允许修改
         final Date now = DateUtil.beginOfDay(new Date());
         List<SysWorkTime> workTimeList = StreamHelper.to(workTimeEditDtoList, workTimeEditDto -> {