From 578f84ece732a710278e7914396e127d8a27ed8a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期日, 08 十一月 2026 10:05:18 +0800
Subject: [PATCH] feat(hrm): 排班管理联动已审批请假
---
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceHolidayServiceImpl.java | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 150 insertions(+), 6 deletions(-)
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceHolidayServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceHolidayServiceImpl.java
index 6e96e27..d7541c5 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceHolidayServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceHolidayServiceImpl.java
@@ -1,19 +1,29 @@
package cn.iocoder.yudao.module.hrm.service.attendance;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceHolidayGroupRespVO;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceHolidayPageReqVO;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceHolidayRangeCreateReqVO;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceHolidayRangeUpdateReqVO;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceHolidaySaveReqVO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceHolidayDO;
import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceHolidayMapper;
import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceHolidayTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.DayOfWeek;
import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
+import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
@@ -21,7 +31,7 @@
/**
* 鑰冨嫟鑺傚亣鏃ラ厤缃� Service 瀹炵幇绫�
*
- * @author 鑺嬮亾婧愮爜
+ * @author 瓒呯骇绠$悊鍛�
*/
@Service
@Validated
@@ -35,11 +45,46 @@
// 鏍¢獙鏃ユ湡鏄惁宸插瓨鍦ㄩ厤缃�
validateAttendanceHolidayDateExists(createReqVO.getDate());
HrmAttendanceHolidayDO attendanceHoliday = BeanUtils.toBean(createReqVO, HrmAttendanceHolidayDO.class);
- if (attendanceHoliday.getIsLegal() == null) {
- attendanceHoliday.setIsLegal(0);
- }
+ // VO 渚х敤 Boolean 鍏煎鍓嶇鍕鹃�夋鐨� true/false锛岃惤搴撶粺涓�涓� 0/1
+ attendanceHoliday.setIsLegal(Boolean.TRUE.equals(createReqVO.getIsLegal()) ? 1 : 0);
attendanceHolidayMapper.insert(attendanceHoliday);
return attendanceHoliday.getId();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Integer createAttendanceHolidayRange(HrmAttendanceHolidayRangeCreateReqVO createReqVO) {
+ if (createReqVO.getEndDate().isBefore(createReqVO.getStartDate())) {
+ throw exception(ATTENDANCE_HOLIDAY_DATE_RANGE_INVALID);
+ }
+ return insertDays(createReqVO.getName(), createReqVO.getStartDate(), createReqVO.getEndDate(),
+ createReqVO.getType(), createReqVO.getIsLegal(), createReqVO.getRemark());
+ }
+
+ /**
+ * 鎸夊ぉ鍐欏叆鑺傚亣鏃ワ紱鍐欏叆鍓嶆暣浣撴煡閲嶏紝浠讳竴鏃ユ湡宸插瓨鍦ㄥ垯鏁翠綋涓嶅啓鍏�
+ */
+ private int insertDays(String name, LocalDate startDate, LocalDate endDate,
+ Integer type, Boolean isLegal, String remark) {
+ // 鍏堟暣浣撴牎楠岋紝鍖洪棿鍐呭凡瀛樺湪浠讳竴鏃ユ湡鏃朵笉鍋氶儴鍒嗗啓鍏�
+ List<HrmAttendanceHolidayDO> existingList = attendanceHolidayMapper.selectListByDateBetween(startDate, endDate);
+ if (!existingList.isEmpty()) {
+ HrmAttendanceHolidayDO existing = existingList.get(0);
+ throw exception(ATTENDANCE_HOLIDAY_RANGE_DATE_EXISTS, existing.getDate(), existing.getName());
+ }
+ int count = 0;
+ for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
+ HrmAttendanceHolidayDO attendanceHoliday = HrmAttendanceHolidayDO.builder()
+ .name(name)
+ .date(date)
+ .type(type)
+ .isLegal(Boolean.TRUE.equals(isLegal) ? 1 : 0)
+ .remark(remark)
+ .build();
+ attendanceHolidayMapper.insert(attendanceHoliday);
+ count++;
+ }
+ return count;
}
@Override
@@ -51,13 +96,46 @@
validateAttendanceHolidayDateExists(updateReqVO.getDate());
}
HrmAttendanceHolidayDO updateObj = BeanUtils.toBean(updateReqVO, HrmAttendanceHolidayDO.class);
+ updateObj.setIsLegal(Boolean.TRUE.equals(updateReqVO.getIsLegal()) ? 1 : 0);
attendanceHolidayMapper.updateById(updateObj);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateAttendanceHolidayRange(HrmAttendanceHolidayRangeUpdateReqVO updateReqVO) {
+ // 1. 鏍¢獙鏃堕棿鑼冨洿涓庡尯闂磋褰�
+ if (updateReqVO.getEndDate().isBefore(updateReqVO.getStartDate())) {
+ throw exception(ATTENDANCE_HOLIDAY_DATE_RANGE_INVALID);
+ }
+ List<Long> ids = updateReqVO.getIds().stream().filter(Objects::nonNull).distinct().toList();
+ if (ids.isEmpty()) {
+ throw exception(ATTENDANCE_HOLIDAY_RANGE_IDS_EMPTY);
+ }
+ List<HrmAttendanceHolidayDO> oldList = attendanceHolidayMapper.selectBatchIds(ids);
+ if (oldList.size() != ids.size()) {
+ throw exception(ATTENDANCE_HOLIDAY_RANGE_NOT_EXISTS);
+ }
+ // 2. 鍒犻櫎鍖洪棿鍐呭師璁板綍锛屽啀鎸夋柊鐨勮捣姝㈡棩鏈熸暣浣撻噸鍐欙紙鍚屼竴浜嬪姟锛屽紓甯镐細鍥炴粴锛�
+ attendanceHolidayMapper.physicalDeleteByIds(ids);
+ insertDays(updateReqVO.getName(), updateReqVO.getStartDate(), updateReqVO.getEndDate(),
+ updateReqVO.getType(), updateReqVO.getIsLegal(), updateReqVO.getRemark());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAttendanceHolidayRange(List<Long> ids) {
+ List<Long> cleanIds = ids == null ? Collections.emptyList()
+ : ids.stream().filter(Objects::nonNull).distinct().toList();
+ if (cleanIds.isEmpty()) {
+ throw exception(ATTENDANCE_HOLIDAY_RANGE_IDS_EMPTY);
+ }
+ attendanceHolidayMapper.physicalDeleteByIds(cleanIds);
}
@Override
public void deleteAttendanceHoliday(Long id) {
validateAttendanceHolidayExists(id);
- attendanceHolidayMapper.deleteById(id);
+ attendanceHolidayMapper.physicalDeleteByIds(Collections.singletonList(id));
}
private void validateAttendanceHolidayExists(Long id) {
@@ -83,6 +161,72 @@
}
@Override
+ public PageResult<HrmAttendanceHolidayGroupRespVO> getAttendanceHolidayGroupPage(
+ HrmAttendanceHolidayPageReqVO pageReqVO) {
+ List<HrmAttendanceHolidayDO> list = attendanceHolidayMapper.selectListByCondition(pageReqVO);
+ if (list.isEmpty()) {
+ return new PageResult<>(Collections.emptyList(), 0L);
+ }
+ // 1. 杩炵画鏃ユ湡 + 鍚嶇О/绫诲瀷/鏄惁娉曞畾/澶囨敞涓�鑷寸殑璁板綍鍚堝苟涓轰竴琛�
+ List<HrmAttendanceHolidayGroupRespVO> groups = new ArrayList<>();
+ HrmAttendanceHolidayDO previous = null;
+ for (HrmAttendanceHolidayDO current : list) {
+ HrmAttendanceHolidayGroupRespVO last = groups.isEmpty() ? null : groups.get(groups.size() - 1);
+ boolean sameGroup = last != null && previous != null
+ && previous.getDate().plusDays(1).equals(current.getDate())
+ && sameHoliday(previous, current);
+ if (sameGroup) {
+ last.setEndDate(current.getDate());
+ last.getIds().add(current.getId());
+ last.setDayCount(last.getDayCount() + 1);
+ } else {
+ HrmAttendanceHolidayGroupRespVO group = new HrmAttendanceHolidayGroupRespVO();
+ group.setId(current.getId());
+ List<Long> ids = new ArrayList<>();
+ ids.add(current.getId());
+ group.setIds(ids);
+ group.setName(current.getName());
+ group.setDate(current.getDate());
+ group.setEndDate(current.getDate());
+ group.setDayCount(1);
+ group.setType(current.getType());
+ group.setIsLegal(current.getIsLegal());
+ group.setRemark(current.getRemark());
+ group.setCreateTime(current.getCreateTime());
+ groups.add(group);
+ }
+ previous = current;
+ }
+ // 2. 鎸夋棩鏈熷�掑簭锛屼笌閫愭棩鍒楄〃淇濇寔涓�鑷�
+ groups.sort(Comparator.comparing(HrmAttendanceHolidayGroupRespVO::getDate).reversed());
+ // 3. 鍒嗙粍鍚庡唴瀛樺垎椤�
+ return pageGroups(groups, pageReqVO);
+ }
+
+ private boolean sameHoliday(HrmAttendanceHolidayDO a, HrmAttendanceHolidayDO b) {
+ return StrUtil.equals(a.getName(), b.getName())
+ && Objects.equals(a.getType(), b.getType())
+ && Objects.equals(a.getIsLegal(), b.getIsLegal())
+ && StrUtil.equals(a.getRemark(), b.getRemark());
+ }
+
+ private PageResult<HrmAttendanceHolidayGroupRespVO> pageGroups(
+ List<HrmAttendanceHolidayGroupRespVO> groups, HrmAttendanceHolidayPageReqVO pageReqVO) {
+ long total = groups.size();
+ if (Objects.equals(PageParam.PAGE_SIZE_NONE, pageReqVO.getPageSize())) {
+ return new PageResult<>(groups, total);
+ }
+ int pageNo = pageReqVO.getPageNo() == null ? 1 : pageReqVO.getPageNo();
+ int pageSize = pageReqVO.getPageSize() == null ? 10 : pageReqVO.getPageSize();
+ int from = Math.max(0, (pageNo - 1) * pageSize);
+ if (from >= groups.size()) {
+ return new PageResult<>(Collections.emptyList(), total);
+ }
+ int to = Math.min(groups.size(), from + pageSize);
+ return new PageResult<>(new ArrayList<>(groups.subList(from, to)), total);
+ }
+
+ @Override
public List<HrmAttendanceHolidayDO> getAttendanceHolidayListByDateRange(LocalDate startDate, LocalDate endDate) {
return attendanceHolidayMapper.selectListByDateBetween(startDate, endDate);
}
@@ -100,4 +244,4 @@
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
}
-}
\ No newline at end of file
+}
--
Gitblit v1.9.3