AttendanceConfigServiceImpl.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package com.ylx.attendanceconfig.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import cn.hutool.core.util.ObjectUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  7. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  8. import com.ylx.attendanceconfig.domain.AttendanceDeductionRule;
  9. import com.ylx.attendanceconfig.domain.AttendanceRule;
  10. import com.ylx.attendanceconfig.domain.dto.AttendanceDeductionRuleDTO;
  11. import com.ylx.attendanceconfig.domain.dto.AttendanceRuleAddDTO;
  12. import com.ylx.attendanceconfig.domain.vo.AttendanceDeductionRuleVO;
  13. import com.ylx.attendanceconfig.domain.vo.AttendanceRuleDetailVO;
  14. import com.ylx.attendanceconfig.mapper.AttendanceDeductionRuleMapper;
  15. import com.ylx.attendanceconfig.mapper.AttendanceRuleMapper;
  16. import com.ylx.attendanceconfig.service.AttendanceConfigService;
  17. import com.ylx.common.exception.ServiceException;
  18. import com.ylx.common.utils.SecurityUtils;
  19. import lombok.extern.slf4j.Slf4j;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.transaction.annotation.Transactional;
  22. import javax.annotation.Resource;
  23. import java.math.BigDecimal;
  24. import java.time.LocalDateTime;
  25. import java.util.Comparator;
  26. import java.util.List;
  27. import java.util.stream.Collectors;
  28. @Slf4j
  29. @Service
  30. public class AttendanceConfigServiceImpl implements AttendanceConfigService {
  31. @Resource
  32. private AttendanceRuleMapper attendanceRuleMapper;
  33. @Resource
  34. private AttendanceDeductionRuleMapper attendanceDeductionRuleMapper;
  35. private static final int NOT_DELETE = 0;
  36. private static final int DELETE = 1;
  37. private static final int ENABLED = 1;
  38. private static final int DISABLED = 0;
  39. private static final int EARLY_LEAVE_DEDUCTION = 1;
  40. @Override
  41. @Transactional(rollbackFor = Exception.class)
  42. public void addAttendanceRule(AttendanceRuleAddDTO dto) {
  43. checkRuleParam(dto);
  44. AttendanceRule rule = new AttendanceRule();
  45. rule.setRuleName(StrUtil.blankToDefault(StrUtil.trim(dto.getRuleName()), "默认考勤规则"));
  46. rule.setBasicWorkHours(dto.getBasicWorkHours());
  47. rule.setWorkDurationRuleEnabled(dto.getWorkDurationRuleEnabled());
  48. rule.setStatus(ObjectUtil.defaultIfNull(dto.getStatus(), ENABLED));
  49. rule.setIsDelete(NOT_DELETE);
  50. rule.setCreateBy(SecurityUtils.getUsername());
  51. rule.setUpdateBy(SecurityUtils.getUsername());
  52. int insertRuleResult = attendanceRuleMapper.insert(rule);
  53. if (insertRuleResult <= 0 || ObjectUtil.isNull(rule.getId())) {
  54. throw new ServiceException("新增考勤规则失败");
  55. }
  56. if (dto.getWorkDurationRuleEnabled() == ENABLED) {
  57. List<AttendanceDeductionRuleDTO> sortedRules = sortDeductionRules(dto.getDeductionRules());
  58. for (int i = 0; i < sortedRules.size(); i++) {
  59. AttendanceDeductionRuleDTO deductionDto = sortedRules.get(i);
  60. AttendanceDeductionRule deductionRule = new AttendanceDeductionRule();
  61. deductionRule.setRuleId(rule.getId());
  62. deductionRule.setRuleType(ObjectUtil.defaultIfNull(deductionDto.getRuleType(), EARLY_LEAVE_DEDUCTION));
  63. deductionRule.setStartMinutes(deductionDto.getStartMinutes());
  64. deductionRule.setEndMinutes(deductionDto.getEndMinutes());
  65. deductionRule.setDeductAmount(deductionDto.getDeductAmount());
  66. deductionRule.setSortOrder(i + 1);
  67. deductionRule.setIsDelete(NOT_DELETE);
  68. deductionRule.setCreateBy(SecurityUtils.getUsername());
  69. deductionRule.setUpdateBy(SecurityUtils.getUsername());
  70. int insertDeductionResult = attendanceDeductionRuleMapper.insert(deductionRule);
  71. if (insertDeductionResult <= 0) {
  72. throw new ServiceException("新增考勤扣款区间失败");
  73. }
  74. }
  75. }
  76. }
  77. @Override
  78. public List<AttendanceRuleDetailVO> listAttendanceRules() {
  79. List<AttendanceRule> ruleList = attendanceRuleMapper.selectList(new LambdaQueryWrapper<AttendanceRule>()
  80. .orderByDesc(AttendanceRule::getCreateTime));
  81. return ruleList.stream()
  82. .map(this::toDetailVO)
  83. .collect(Collectors.toList());
  84. }
  85. @Override
  86. @Transactional(rollbackFor = Exception.class)
  87. public void deleteAttendanceRule(Long id) {
  88. if (ObjectUtil.isNull(id) || id <= 0) {
  89. throw new ServiceException("考勤规则ID不正确");
  90. }
  91. AttendanceRule rule = attendanceRuleMapper.selectOne(new LambdaQueryWrapper<AttendanceRule>()
  92. .eq(AttendanceRule::getId, id)
  93. .eq(AttendanceRule::getIsDelete, NOT_DELETE));
  94. if (ObjectUtil.isNull(rule)) {
  95. throw new ServiceException("考勤规则不存在或已删除");
  96. }
  97. String username = SecurityUtils.getUsername();
  98. LocalDateTime now = LocalDateTime.now();
  99. int updateRuleResult = attendanceRuleMapper.update(null, new LambdaUpdateWrapper<AttendanceRule>()
  100. .eq(AttendanceRule::getId, id)
  101. .eq(AttendanceRule::getIsDelete, NOT_DELETE)
  102. .set(AttendanceRule::getIsDelete, DELETE)
  103. .set(AttendanceRule::getUpdateBy, username)
  104. .set(AttendanceRule::getUpdateTime, now));
  105. if (updateRuleResult <= 0) {
  106. throw new ServiceException("删除考勤规则失败");
  107. }
  108. attendanceDeductionRuleMapper.update(null, new LambdaUpdateWrapper<AttendanceDeductionRule>()
  109. .eq(AttendanceDeductionRule::getRuleId, id)
  110. .eq(AttendanceDeductionRule::getIsDelete, NOT_DELETE)
  111. .set(AttendanceDeductionRule::getIsDelete, DELETE)
  112. .set(AttendanceDeductionRule::getUpdateBy, username)
  113. .set(AttendanceDeductionRule::getUpdateTime, now));
  114. }
  115. @Override
  116. @Transactional(rollbackFor = Exception.class)
  117. public void deleteDeductionRule(Long id) {
  118. if (ObjectUtil.isNull(id) || id <= 0) {
  119. throw new ServiceException("扣款区间ID不正确");
  120. }
  121. AttendanceDeductionRule deductionRule = attendanceDeductionRuleMapper.selectOne(
  122. new LambdaQueryWrapper<AttendanceDeductionRule>()
  123. .eq(AttendanceDeductionRule::getId, id));
  124. if (ObjectUtil.isNull(deductionRule)) {
  125. throw new ServiceException("扣款区间不存在或已删除");
  126. }
  127. int updateResult = attendanceDeductionRuleMapper.deleteById(id);
  128. if (updateResult <= 0) {
  129. throw new ServiceException("删除扣款区间失败");
  130. }
  131. }
  132. private void checkRuleParam(AttendanceRuleAddDTO dto) {
  133. if (ObjectUtil.isNull(dto)) {
  134. throw new ServiceException("考勤规则参数不能为空");
  135. }
  136. if (ObjectUtil.isNull(dto.getBasicWorkHours()) || dto.getBasicWorkHours().compareTo(BigDecimal.ZERO) <= 0) {
  137. throw new ServiceException("基本工作时长必须大于0");
  138. }
  139. if (dto.getWorkDurationRuleEnabled() != ENABLED && dto.getWorkDurationRuleEnabled() != DISABLED) {
  140. throw new ServiceException("工作时长规则值不正确");
  141. }
  142. if (ObjectUtil.isNotNull(dto.getStatus()) && dto.getStatus() != ENABLED && dto.getStatus() != DISABLED) {
  143. throw new ServiceException("考勤规则状态值不正确");
  144. }
  145. if (dto.getWorkDurationRuleEnabled() == ENABLED) {
  146. checkDeductionRules(dto.getDeductionRules());
  147. }
  148. }
  149. private void checkDeductionRules(List<AttendanceDeductionRuleDTO> deductionRules) {
  150. if (CollectionUtil.isEmpty(deductionRules)) {
  151. throw new ServiceException("启用工作时长规则时,扣款区间不能为空");
  152. }
  153. List<AttendanceDeductionRuleDTO> sortedRules = sortDeductionRules(deductionRules);
  154. int expectedStartMinutes = 1;
  155. for (AttendanceDeductionRuleDTO deductionRule : sortedRules) {
  156. if (ObjectUtil.defaultIfNull(deductionRule.getRuleType(), EARLY_LEAVE_DEDUCTION) != EARLY_LEAVE_DEDUCTION) {
  157. throw new ServiceException("扣款规则类型不正确");
  158. }
  159. if (ObjectUtil.isNull(deductionRule.getStartMinutes()) || deductionRule.getStartMinutes() <= 0) {
  160. throw new ServiceException("开始分钟数必须大于0");
  161. }
  162. if (ObjectUtil.isNull(deductionRule.getEndMinutes()) || deductionRule.getEndMinutes() < deductionRule.getStartMinutes()) {
  163. throw new ServiceException("结束分钟数不能小于开始分钟数");
  164. }
  165. if (ObjectUtil.isNull(deductionRule.getDeductAmount()) || deductionRule.getDeductAmount().compareTo(BigDecimal.ZERO) < 0) {
  166. throw new ServiceException("扣款金额不能小于0");
  167. }
  168. if (deductionRule.getStartMinutes() != expectedStartMinutes) {
  169. throw new ServiceException("扣款区间必须从1分钟开始且连续");
  170. }
  171. expectedStartMinutes = deductionRule.getEndMinutes() + 1;
  172. }
  173. }
  174. private List<AttendanceDeductionRuleDTO> sortDeductionRules(List<AttendanceDeductionRuleDTO> deductionRules) {
  175. return deductionRules.stream()
  176. .sorted(Comparator.comparing(AttendanceDeductionRuleDTO::getStartMinutes))
  177. .collect(Collectors.toList());
  178. }
  179. private AttendanceRuleDetailVO toDetailVO(AttendanceRule rule) {
  180. AttendanceRuleDetailVO vo = new AttendanceRuleDetailVO();
  181. BeanUtil.copyProperties(rule, vo);
  182. vo.setDeductionRules(getDeductionRuleVOList(rule.getId()));
  183. return vo;
  184. }
  185. private List<AttendanceDeductionRuleVO> getDeductionRuleVOList(Long ruleId) {
  186. List<AttendanceDeductionRule> deductionRules = attendanceDeductionRuleMapper.selectList(
  187. new LambdaQueryWrapper<AttendanceDeductionRule>()
  188. .eq(AttendanceDeductionRule::getRuleId, ruleId)
  189. .orderByAsc(AttendanceDeductionRule::getSortOrder)
  190. .orderByAsc(AttendanceDeductionRule::getStartMinutes));
  191. return deductionRules.stream().map(entity -> {
  192. AttendanceDeductionRuleVO vo = new AttendanceDeductionRuleVO();
  193. BeanUtil.copyProperties(entity, vo);
  194. return vo;
  195. }).collect(Collectors.toList());
  196. }
  197. }