Sfoglia il codice sorgente

1.年假提交

main
wangqiang 15 ore fa
parent
commit
65c2b54928

+ 1
- 10
zs-manager/src/main/java/com/ruoyi/zhushi/controller/NjBalanceManageController.java Vedi File

@@ -4,10 +4,8 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.zhushi.entity.*;
import com.ruoyi.zhushi.service.NjBalanceManageService;
import com.ruoyi.zhushi.service.NjRuleConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,13 +27,6 @@ public class NjBalanceManageController extends BaseController {
@Autowired
private NjBalanceManageService njBalanceManageService;

@Autowired
private NjRuleConfigService njRuleConfigService;

@Autowired
private ISysUserService userService;


// 查询当前用户考勤组
@GetMapping("/query")
public TableDataInfo<NjBalanceManageDTO> query(NjBalanceManageDTO njBalanceManageDTO, PageQuery pageQuery) {
@@ -46,7 +37,7 @@ public class NjBalanceManageController extends BaseController {
// 生成年假信息
@GetMapping("/generateYearBalance")
public void generateYearBalance() {
njBalanceManageService.generateYearBalance("dingshi", null);
njBalanceManageService.generateYearBalance("1", null);
}



+ 42
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/controller/NjBalanceManageDetailController.java Vedi File

@@ -0,0 +1,42 @@
package com.ruoyi.zhushi.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.zhushi.entity.NjBalanceManageDetailDTO;
import com.ruoyi.zhushi.service.NjBalanceManageDetailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 打卡控制台
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/nj/balance/manage/detail")
@Slf4j
public class NjBalanceManageDetailController extends BaseController {

@Autowired
private NjBalanceManageDetailService njBalanceManageDetailService;

// 查询年假申请信息
@GetMapping("/query")
public TableDataInfo<NjBalanceManageDetailDTO> query(NjBalanceManageDetailDTO njBalanceManageDetailDTO, PageQuery pageQuery) {
return njBalanceManageDetailService.queryPageList(njBalanceManageDetailDTO, pageQuery);
}


// 年假申请
@PostMapping("/apply")
public R<Void> insert(@Validated(AddGroup.class) @RequestBody NjBalanceManageDetailDTO njBalanceManageDetailDTO) {
return toAjax(njBalanceManageDetailService.insert(njBalanceManageDetailDTO));
}


}

+ 21
- 4
zs-manager/src/main/java/com/ruoyi/zhushi/controller/NjRuleConfigController.java Vedi File

@@ -26,25 +26,42 @@ public class NjRuleConfigController extends BaseController {
private NjRuleConfigService njRuleConfigService;


// 查询当前用户考勤组
/**
* 查询规则
* @param njRuleConfigDTO
* @param pageQuery
* @return
*/
@GetMapping("/queryRuleConfig")
public TableDataInfo<NjRuleConfigDTO> queryRule(NjRuleConfigDTO njRuleConfigDTO, PageQuery pageQuery) {
return njRuleConfigService.queryRuleConfig(njRuleConfigDTO, pageQuery);
}

// 新增规则
/**
* 新增规则
* @param njRuleConfigDTO
* @return
*/
@PostMapping("/addRuleConfig")
public R<Boolean> addRule(@RequestBody NjRuleConfigDTO njRuleConfigDTO) {
return R.ok(njRuleConfigService.addRule(njRuleConfigDTO));
}

// 删除规则
/**
* 删除规则
* @param id
* @return
*/
@GetMapping("/delRule")
public R<Integer> delRule(@RequestParam("id") long id) {
return R.ok(njRuleConfigService.delRule(id));
}

// 删除用户
/**
* 删除这个规则下选择的用户
* @param id 用户id
* @return
*/
@DeleteMapping("/delUser/{id}")
public R<Void> delUser(@PathVariable Long id) {
return toAjax(njRuleConfigService.delUser(id));

+ 50
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/entity/NjBalanceManageDetail.java Vedi File

@@ -0,0 +1,50 @@
package com.ruoyi.zhushi.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;

import java.math.BigDecimal;

/**
* 年假申请明细表
*/
@Data
@TableName("nj_balance_manage_detail")
public class NjBalanceManageDetail extends BaseEntity {
/** 主键ID */
@TableId(value = "id", type = IdType.AUTO)
private long id;

/** 员工编号 */
@TableField(value = "`user_id`")
private long userId;

/** 员工姓名 */
@TableField(value = "`user_name`")
private String userName;

/** 员工姓名 */
@TableField(value = "`nick_name`")
private String nickName;

/** 部门名称 */
@TableField(value = "`dept_name`")
private String deptName;


/** 已使用天数 */
@TableField(value = "`used_day`")
private BigDecimal usedDay;

/** 申请日期 可能是多个日期的拼接 */
@TableField(value = "`apply_dates`")
private String applyDates;

/** 状态 */
@TableField(value = "`is_enable`")
private Boolean isEnable;
}

+ 33
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/entity/NjBalanceManageDetailDTO.java Vedi File

@@ -0,0 +1,33 @@
package com.ruoyi.zhushi.entity;

import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;

import java.math.BigDecimal;

/**
* 年假申请明细DTO
*/
@Data
public class NjBalanceManageDetailDTO extends BaseEntity {
/** 主键ID */
private long id;

/** 员工编号 */
private long userId;

/** 员工姓名 */
private String userName;

/** 员工姓名 */
private String nickName;

/** 部门名称 */
private String deptName;
/** 已使用天数 */
private BigDecimal usedDay;
/** 申请日期 可能是多个日期的拼接 */
private String applyDates;
/** 状态 */
private Boolean isEnable;
}

+ 11
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/mapper/NjBalanceManageDetailMapper.java Vedi File

@@ -0,0 +1,11 @@
package com.ruoyi.zhushi.mapper;

import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.zhushi.entity.NjBalanceManageDetail;
import com.ruoyi.zhushi.entity.NjBalanceManageDetailDTO;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface NjBalanceManageDetailMapper extends BaseMapperPlus<NjBalanceManageDetailMapper, NjBalanceManageDetail, NjBalanceManageDetailDTO> {

}

+ 17
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/service/NjBalanceManageDetailService.java Vedi File

@@ -0,0 +1,17 @@
package com.ruoyi.zhushi.service;

import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.zhushi.entity.NjBalanceManageDTO;
import com.ruoyi.zhushi.entity.NjBalanceManageDetail;
import com.ruoyi.zhushi.entity.NjBalanceManageDetailDTO;

import java.util.List;

public interface NjBalanceManageDetailService {

TableDataInfo<NjBalanceManageDetailDTO> queryPageList(NjBalanceManageDetailDTO njBalanceManageDetailDTO, PageQuery pageQuery);

boolean insert(NjBalanceManageDetailDTO njBalanceManageDetailDTO);

}

+ 5
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/service/NjBalanceManageService.java Vedi File

@@ -19,5 +19,10 @@ public interface NjBalanceManageService {

int update(NjBalanceManageDTO njBalanceManageDTO);

/**
*
* @param flag 0 手动调用 1定时任务生成
* @param njRuleConfigDTO 0时必传 1 为null
*/
void generateYearBalance(String flag, NjRuleConfigDTO njRuleConfigDTO);
}

+ 85
- 0
zs-manager/src/main/java/com/ruoyi/zhushi/service/impl/NjBalanceManageDetailServiceImpl.java Vedi File

@@ -0,0 +1,85 @@
package com.ruoyi.zhushi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.zhushi.entity.NjBalanceManage;
import com.ruoyi.zhushi.entity.NjBalanceManageDetail;
import com.ruoyi.zhushi.entity.NjBalanceManageDetailDTO;
import com.ruoyi.zhushi.mapper.NjBalanceManageDetailMapper;
import com.ruoyi.zhushi.mapper.NjBalanceManageMapper;
import com.ruoyi.zhushi.service.NjBalanceManageDetailService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
@Transactional()
public class NjBalanceManageDetailServiceImpl implements NjBalanceManageDetailService {

@Autowired
private NjBalanceManageMapper njBalanceManageMapper;
@Autowired
private NjBalanceManageDetailMapper njBalanceManageDetailMapper;
@Autowired
private ISysUserService iSysUserService;
//查询年假申请信息
@Override
public TableDataInfo<NjBalanceManageDetailDTO> queryPageList(NjBalanceManageDetailDTO njBalanceManageDetailDTO, PageQuery pageQuery) {
LambdaQueryWrapper<NjBalanceManageDetail> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(njBalanceManageDetailDTO.getUserName()!= null, NjBalanceManageDetail::getUserName, njBalanceManageDetailDTO.getUserName());
queryWrapper.like(njBalanceManageDetailDTO.getNickName()!= null, NjBalanceManageDetail::getNickName, njBalanceManageDetailDTO.getNickName());
IPage<NjBalanceManageDetailDTO> njBalanceManageDTOS = njBalanceManageDetailMapper.selectVoPage(pageQuery.build(), queryWrapper, NjBalanceManageDetailDTO.class);
return TableDataInfo.build(njBalanceManageDTOS);
}

//单条插入
@Override
public boolean insert(NjBalanceManageDetailDTO njBalanceManageDetailDTO) {
NjBalanceManageDetail njBalanceManageDetail = new NjBalanceManageDetail();
BeanUtils.copyProperties(njBalanceManageDetailDTO,njBalanceManageDetail);
SysUser sysUser = iSysUserService.selectUserById(njBalanceManageDetailDTO.getUserId());
njBalanceManageDetail.setUserName(sysUser.getUserName());
njBalanceManageDetail.setNickName(sysUser.getNickName());
njBalanceManageDetail.setDeptName(sysUser.getDept().getDeptName());
njBalanceManageDetail.setIsEnable(true);
//年假申请明细 插入
int i = njBalanceManageDetailMapper.insert(njBalanceManageDetail);
int j = 0;
//年假余额表 修改已使用和未使用年假
if (i==1) {
//查询这个用户
BigDecimal used_days = new BigDecimal(0);
QueryWrapper detailQuery =new QueryWrapper();
detailQuery.select("sum(used_day) used_days");
detailQuery.eq("user_id",njBalanceManageDetailDTO.getUserId());
List<Map> detailList= njBalanceManageDetailMapper.selectMaps(detailQuery);
if (detailList!=null&&detailList.size()>0) {
Map map =detailList.get(0);
used_days = (BigDecimal )map.get("used_days");
}
UpdateWrapper<NjBalanceManage> updateWrapper = new UpdateWrapper();
updateWrapper.set("used_day",used_days);
updateWrapper.setSql("unused_day = annual_leave - " + used_days);
updateWrapper.eq("user_id",njBalanceManageDetailDTO.getUserId());
j = njBalanceManageMapper.update(null,updateWrapper);
}
if (i==1&&j==1) {
return true;
} else {
throw new RuntimeException("插入失败!请联系软件部门");
}

}

}

+ 147
- 236
zs-manager/src/main/java/com/ruoyi/zhushi/service/impl/NjBalanceManageServiceImpl.java Vedi File

@@ -1,37 +1,34 @@
package com.ruoyi.zhushi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.zhushi.entity.*;
import com.ruoyi.zhushi.mapper.NjBalanceManageMapper;
import com.ruoyi.zhushi.mapper.NjRuleConfigAndUserMapper;
import com.ruoyi.zhushi.mapper.NjRuleConfigMapper;
import com.ruoyi.zhushi.mapper.*;
import com.ruoyi.zhushi.service.NjBalanceManageService;
import com.ruoyi.zhushi.util.Constans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class NjBalanceManageServiceImpl implements NjBalanceManageService {

@Autowired
private NjBalanceManageMapper njBalanceManageMapper;
@Autowired
private NjBalanceManageDetailMapper njBalanceManageDetailMapper;

@Autowired
private NjRuleConfigMapper njRuleConfigMapper;
@@ -40,13 +37,9 @@ public class NjBalanceManageServiceImpl implements NjBalanceManageService {
private NjRuleConfigAndUserMapper njRuleConfigAndUserMapper;

@Autowired
private ISysUserService userService;

private DkRecordMapper dkRecordMapper;
@Override
public TableDataInfo<NjBalanceManageDTO> queryPageList(NjBalanceManageDTO njBalanceManageDTO, PageQuery pageQuery) {
// 获取当前登录用户的ID
LoginUser loginUser = LoginHelper.getLoginUser();
String username = loginUser.getUsername();
LambdaQueryWrapper<NjBalanceManage> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(njBalanceManageDTO.getUserName()!= null, NjBalanceManage::getUserName, njBalanceManageDTO.getUserName());
queryWrapper.eq(njBalanceManageDTO.getNickName()!= null, NjBalanceManage::getNickName, njBalanceManageDTO.getNickName());
@@ -76,231 +69,126 @@ public class NjBalanceManageServiceImpl implements NjBalanceManageService {
return i;
}

/**
* 计算年假 保存年假规则会调用 定时任务每年1月1日会调用这个接口
* @param flag 0 手动调用 1定时任务生成
* @param dto 0时必传 1 为null
*/
@Override
public void generateYearBalance(String flag, NjRuleConfigDTO dto) {
// 查询年假配置管理
// List<NjRuleConfigDTO> njRuleConfigDTOS = njRuleConfigService.queryAll();
LambdaQueryWrapper<NjRuleConfig> queryWrapper = Wrappers.lambdaQuery();
List<NjRuleConfigDTO> njRuleConfigDTOS = new ArrayList<>();
if(flag.equals("dingshi")){
if("1".equals(flag)){
njRuleConfigDTOS = njRuleConfigMapper.selectVoList(queryWrapper, NjRuleConfigDTO.class);
}
if(flag.equals("shoudong")){
if("0".equals(flag)){
njRuleConfigDTOS.add(dto);
}
// 遍历所有年假配置,判断是否适用全部人员,判断年假的生成方式
for (NjRuleConfigDTO njRuleConfigDTO : njRuleConfigDTOS) {
// 获取人员适用范围true 全员, fale 指定人员
Boolean applicableRange = njRuleConfigDTO.getApplicableRange();
// 定义存储人员
// 用户年假集合
List<NjBalanceManage> njBalanceManages = new ArrayList<>();
//全部用户
if(applicableRange){
// 全员
// 查询所有人员
SysUser user = new SysUser();
List<SysUser> list = userService.selectUserList(user);
List<JSONObject> jsonObjects = dkRecordMapper.queryAllUsers(null);
// 遍历人员生成年假记录
for (SysUser sysUser : list) {
NjBalanceManage njBalanceManage = new NjBalanceManage();
for (JSONObject sysUser : jsonObjects) {
Long userId = sysUser.getLong("userId");
// 根据 人员id 查询年假信息 如果存在就跟新年假信息
njBalanceManage.setUserId(sysUser.getUserId());
LambdaQueryWrapper<NjBalanceManage> queryWrapper1 = new LambdaQueryWrapper<>();
queryWrapper1.eq(NjBalanceManage::getUserId, sysUser.getUserId());
int year = LocalDate.now().getYear();
queryWrapper1.apply("YEAR(create_time) = {}", year);
NjBalanceManage njBalanceManage1 = njBalanceManageMapper.selectOne(queryWrapper1);
if (BeanUtil.isNotEmpty(njBalanceManage1)) {
njBalanceManage = njBalanceManage1;
QueryWrapper<NjBalanceManage> njQueryWrapper = new QueryWrapper<>();
njQueryWrapper.eq("user_id", userId);
njQueryWrapper.ge("create_time", LocalDateTime.now());
NjBalanceManage njBalanceManage = njBalanceManageMapper.selectOne(njQueryWrapper);
if (BeanUtil.isNotEmpty(njBalanceManage)) {
njBalanceManage = new NjBalanceManage();
}

// 获取人员id
Long userId = sysUser.getUserId();
njBalanceManage.setUserId(userId);
// 获取人员名称
String userName = sysUser.getUserName();
njBalanceManage.setUserName(userName);
// 获取人员昵称
String nickName = sysUser.getNickName();
njBalanceManage.setNickName(nickName);

// 获取人员部门名称
String deptName = sysUser.getDept().getDeptName();
njBalanceManage.setDeptName(deptName);

// 判断年假发放规则
Integer annualLeaveTiers = njRuleConfigDTO.getAnnualLeaveTiers();
// 获取入职时间
LocalDate joinedDate = sysUser.getJoinedDate();
// 根据入职时间计算 (年假天数 = 入职当年剩余日历天数 / 365 × 5)
if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_0){
// 获取入职当年的最后一天
LocalDate lastDayOfYear = joinedDate.withDayOfMonth(31).withMonth(12);
LocalDate now = LocalDate.now();
// 计算从入职日期(不含)到年底(含)的天数差
long remainingDay = ChronoUnit.DAYS.between(joinedDate, now) + 1;
BigDecimal annualLeave = BigDecimal.valueOf(remainingDay).divide(BigDecimal.valueOf(365), 1, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(5));
njBalanceManage.setAnnualLeave(annualLeave);
// 剩余天数
njBalanceManage.setUnusedDay(annualLeave);
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_5){
// 获取当前年的一月一日
LocalDate now1 = LocalDate.now();
LocalDate localDate = now1.withDayOfYear(1);
// 判断是否满一年
boolean oneYearCompleted = isOneYearCompleted(joinedDate, now1);
if(oneYearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else {
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
}
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_10){
// 获取当前年的一月一日
LocalDate now2 = LocalDate.now();
LocalDate localDate = now2.withDayOfYear(1);
// 判断是否满一年
boolean yearCompleted = isYearsCompleted(joinedDate, annualLeaveTiers);
if(yearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
}
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_15) {
// 获取当前年的一月一日
LocalDate now3 = LocalDate.now();
LocalDate localDate = now3.withDayOfYear(1);
// 判断是否满一年
boolean yearCompleted = isYearsCompleted(joinedDate, 20);
if(yearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
//2.2 查询明细表中的已使用年假
BigDecimal used_days = new BigDecimal(0);
QueryWrapper detailQuery =new QueryWrapper();
detailQuery.select("sum(used_day) used_days");
detailQuery.eq("user_id",userId);
List<Map> detailList= njBalanceManageDetailMapper.selectMaps(detailQuery);
if (detailList!=null&&detailList.size()>0) {
Map map =detailList.get(0);
if (map!=null) {
used_days = (BigDecimal )map.get("used_days");
}
}

// 获取入职时间
LocalDate joinedDate = sysUser.get("joinedDate") == null ? LocalDate.now() : (LocalDate)sysUser.get("joinedDate") ;
//年假总额
njBalanceManage.setAnnualLeave(new BigDecimal(calculateAnnualLeave(joinedDate)));
// 已使用天数
njBalanceManage.setUsedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUsedDay(used_days);
// 剩余天数 = 年假总额 - 已使用年假
njBalanceManage.setUnusedDay(njBalanceManage.getAnnualLeave().subtract(used_days));
//上年结转
njBalanceManage.setLastYearUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
// 转态
njBalanceManage.setIsEnable(true);
// 获取用户信息
njBalanceManage.setUserId(userId);
njBalanceManage.setUserName((String)sysUser.get("userName"));
njBalanceManage.setNickName((String)sysUser.get("nickName"));
njBalanceManage.setDeptName((String)sysUser.get("deptName"));
njBalanceManages.add(njBalanceManage);
}

// 指定人员
}else {
// 查询指定人员根据配置id
//指定用户
// 1.根据年假配置查询下面的用户
LambdaQueryWrapper<NjRuleConfigAndUser> queryWrapper1 = Wrappers.lambdaQuery();
queryWrapper1.eq(NjRuleConfigAndUser::getNjRuleConfigId, njRuleConfigDTO.getId());
List<NjRuleConfigAndUserDTO> njRuleConfigAndUserDTOS = njRuleConfigAndUserMapper.selectVoList(queryWrapper1);
//2.根据用户入职时间 计算对于的年假额度
for (NjRuleConfigAndUserDTO njRuleConfigAndUserDTO : njRuleConfigAndUserDTOS) {
NjBalanceManage njBalanceManage = new NjBalanceManage();

// 根据 人员id 查询年假信息 如果存在就跟新年假信息
//2.1 根据 人员id 查询年假信息
LambdaQueryWrapper<NjBalanceManage> queryWrapper2 = new LambdaQueryWrapper<>();
queryWrapper2.eq(NjBalanceManage::getUserId, njRuleConfigAndUserDTO.getUserId());
int year = LocalDate.now().getYear();
queryWrapper2.apply("YEAR(create_time) = {0}", year);
NjBalanceManage njBalanceManage1 = njBalanceManageMapper.selectOne(queryWrapper2);
if (BeanUtil.isNotEmpty(njBalanceManage1)) {
njBalanceManage = njBalanceManage1;
NjBalanceManage njBalanceManage = njBalanceManageMapper.selectOne(queryWrapper2);
if (njBalanceManage==null) {
njBalanceManage = new NjBalanceManage();
}

// 获取人员id
Long userId = njRuleConfigAndUserDTO.getUserId();
njBalanceManage.setUserId(userId);
// 获取人员名称
String userName = njRuleConfigAndUserDTO.getUserName();
njBalanceManage.setUserName(userName);
// 获取人员昵称
String nickName = njRuleConfigAndUserDTO.getNickName();
njBalanceManage.setNickName(nickName);

// 获取人员部门名称
String deptName = njRuleConfigAndUserDTO.getDeptName();
njBalanceManage.setDeptName(deptName);
//2.2 查询明细表中的已使用年假
BigDecimal used_days = new BigDecimal(0);
QueryWrapper detailQuery =new QueryWrapper();
detailQuery.select("sum(used_day) used_days");
detailQuery.eq("user_id",njRuleConfigAndUserDTO.getUserId());
List<Map> detailList= njBalanceManageDetailMapper.selectMaps(detailQuery);
if (detailList!=null&&detailList.size()>0) {
Map map =detailList.get(0);
if (map!=null) {
used_days = (BigDecimal )map.get("used_days");
}
}

// 判断年假发放规则
Integer annualLeaveTiers = njRuleConfigDTO.getAnnualLeaveTiers();
// 获取入职时间
LocalDate joinedDate = njRuleConfigAndUserDTO.getJoinedDate() == null ? LocalDate.now() : njRuleConfigAndUserDTO.getJoinedDate();

// 根据入职时间计算 (年假天数 = 入职当年剩余日历天数 / 365 × 5)
if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_0){
// 获取入职当年的最后一天
LocalDate lastDayOfYear = joinedDate.withDayOfMonth(31).withMonth(12);
LocalDate now = LocalDate.now();

// 计算从入职日期(不含)到年底(含)的天数差
long remainingDay = ChronoUnit.DAYS.between(joinedDate, now) + 1;
BigDecimal annualLeave = BigDecimal.valueOf(remainingDay).divide(BigDecimal.valueOf(365), 1, RoundingMode.HALF_DOWN).multiply(BigDecimal.valueOf(5));
njBalanceManage.setAnnualLeave(annualLeave);
// 剩余天数
njBalanceManage.setUnusedDay(annualLeave);
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_5){
// 获取当前年的一月一日
LocalDate now1 = LocalDate.now();
LocalDate localDate = now1.withDayOfYear(1);
// 判断是否满一年
boolean oneYearCompleted = isOneYearCompleted(joinedDate, localDate);
if(oneYearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else {
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
}
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_10){
// 获取当前年的一月一日
LocalDate now2 = LocalDate.now();
LocalDate localDate = now2.withDayOfYear(1);
// 判断是否满一年
boolean yearCompleted = isYearsCompleted(joinedDate, annualLeaveTiers);
if(yearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
}
}else if(annualLeaveTiers == Constans.ANNUALLEAVETIERS_15) {
// 获取当前年的一月一日
LocalDate now3 = LocalDate.now();
LocalDate localDate = now3.withDayOfYear(1);
// 判断是否满一年
boolean yearCompleted = isYearsCompleted(joinedDate, 20);
if(yearCompleted)
{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(annualLeaveTiers));
// 剩余天数
njBalanceManage.setUnusedDay(BigDecimal.valueOf(annualLeaveTiers));
}else{
njBalanceManage.setAnnualLeave(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
}
}
//年假总额
njBalanceManage.setAnnualLeave(new BigDecimal(calculateAnnualLeave(joinedDate)));
// 已使用天数
njBalanceManage.setUsedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
njBalanceManage.setUsedDay(used_days);
// 剩余天数 = 年假总额 - 已使用年假
njBalanceManage.setUnusedDay(njBalanceManage.getAnnualLeave().subtract(used_days));
//上年结转
njBalanceManage.setLastYearUnusedDay(BigDecimal.valueOf(Constans.ANNUALLEAVETIERS_0));
// 转态
njBalanceManage.setIsEnable(true);
// 获取用户信息
njBalanceManage.setUserId(njRuleConfigAndUserDTO.getUserId());
njBalanceManage.setUserName(njRuleConfigAndUserDTO.getUserName());
njBalanceManage.setNickName(njRuleConfigAndUserDTO.getNickName());
njBalanceManage.setDeptName(njRuleConfigAndUserDTO.getDeptName());

njBalanceManages.add(njBalanceManage);
}
}
@@ -310,59 +198,82 @@ public class NjBalanceManageServiceImpl implements NjBalanceManageService {
}
}


/**
* 判断入职是否已满一年(到指定日期)
* @param hireDate 入职日期
* @param targetDate 目标日期
* @return true表示已满一年,false表示未满
* 年假计算
* 年假发放规则 入职满一年(5天):5, 入职满10年(10天):10,入职满20年(15天):15
* 1年:
* (当年年末-入职满1年日期)/当年天数 * 5
* 10年:
* (入职满10年日期-当年年初)/当年天数*5+(当年年末-入职满10年日期)/当年天数 * 10
* 20年:
* (入职满20年日期-当年年初)/当年天数*10+(当年年末-入职满20年日期)/当年天数 *15
* 最后的年假结果去掉小数,假如是7.99天 也按照7天算
* 下面举一个例子假设:
* 员工a 20240603入职
* 员工b 20150603入职
* 员工c 20050603入职
* 年假分别为:
* 员工a 2天
* 员工b 7天
* 员工c 12天
* @param hireDate
* @return
*/
public static boolean isOneYearCompleted(LocalDate hireDate, LocalDate targetDate) {
// 计算两个日期之间的年、月、日差
Period period = Period.between(hireDate, targetDate);

// 判断是否满一年:年份差大于1,或年份差等于1且月份和日期都满足
return period.getYears() > 1 ||
(period.getYears() == 1 &&
period.getMonths() == 0 &&
period.getDays() >= 0);
}
public static int calculateAnnualLeave(LocalDate hireDate) {
LocalDate now = LocalDate.now();
int currentYear = now.getYear();
LocalDate startOfYear = LocalDate.of(currentYear, 1, 1);
LocalDate endOfYear = LocalDate.of(currentYear, 12, 31);
long daysOfYear = ChronoUnit.DAYS.between(startOfYear, endOfYear) + 1;

LocalDate oneYearDate = hireDate.plusYears(1);
LocalDate tenYearDate = hireDate.plusYears(10);
LocalDate twentyYearDate = hireDate.plusYears(20);

/**
* 判断入职是否已满指定年限(到当前日期)
* @param hireDate 入职日期(java.time.LocalDate)
* @param targetYears 目标年限(如10、20)
* @return true:已满指定年限;false:未满
*/
public static boolean isYearsCompleted(LocalDate hireDate, int targetYears) {
LocalDate now = LocalDate.now(); // 当前日期
return isYearsCompleted(hireDate, now, targetYears);
}
double annualLeave = 0;

/**
* 判断入职是否已满指定年限(到自定义目标日期)
* @param hireDate 入职日期
* @param targetDate 目标日期(如某个特定时间点)
* @param targetYears 目标年限
* @return true:已满指定年限;false:未满
*/
public static boolean isYearsCompleted(LocalDate hireDate, LocalDate targetDate, int targetYears) {
// 计算入职日期到目标日期的时间差(年、月、日)
Period period = Period.between(hireDate, targetDate);
int yearsDiff = period.getYears(); // 年份差
if (oneYearDate.isAfter(endOfYear)) {
// 未满一年
return 0;
}

if (tenYearDate.isAfter(endOfYear)) {
// 满1年 不满10年
LocalDate begin = oneYearDate.isBefore(startOfYear) ? startOfYear : oneYearDate;
long days = ChronoUnit.DAYS.between(begin, endOfYear) + 1;
annualLeave = (days * 5.0) / daysOfYear;
} else if (twentyYearDate.isAfter(endOfYear)) {
// 满10年 不满20年
LocalDate firstStart = startOfYear;
LocalDate firstEnd = tenYearDate.isAfter(startOfYear) ? tenYearDate.minusDays(1) : startOfYear.minusDays(1);
long firstDays = ChronoUnit.DAYS.between(firstStart, firstEnd) + 1;
if (firstDays < 0) firstDays = 0;

// 核心判断逻辑:
// 1. 年份差 > 目标年限 → 已满
// 2. 年份差 == 目标年限 → 需精确到月和日(如入职日为2013-05-10,满10年需到2023-05-10及之后)
if (yearsDiff > targetYears) {
return true;
} else if (yearsDiff == targetYears) {
// 月份差 >= 0,且月份相等时日期差 >= 0 → 已满
return period.getMonths() > 0
|| (period.getMonths() == 0 && period.getDays() >= 0);
LocalDate secondStart = tenYearDate.isBefore(startOfYear) ? startOfYear : tenYearDate;
long secondDays = ChronoUnit.DAYS.between(secondStart, endOfYear) + 1;

annualLeave = (firstDays * 5.0 + secondDays * 10.0) / daysOfYear;
} else {
return false;
// 满20年
if (twentyYearDate.isBefore(startOfYear)) {
// 全年都满20年,全部按15天
annualLeave = 15.0;
} else if (twentyYearDate.isAfter(endOfYear)) {
// 实际不会到这一步,但保险加上
annualLeave = 10.0;
} else {
// 当前年内刚满20年,按10 + 15规则
LocalDate firstEnd = twentyYearDate.minusDays(1);
long firstDays = ChronoUnit.DAYS.between(startOfYear, firstEnd) + 1;

LocalDate secondStart = twentyYearDate;
long secondDays = ChronoUnit.DAYS.between(secondStart, endOfYear) + 1;

annualLeave = (firstDays * 10.0 + secondDays * 15.0) / daysOfYear;
}
}

return (int) annualLeave;
}
}

+ 2
- 2
zs-manager/src/main/java/com/ruoyi/zhushi/service/impl/NjRuleConfigServiceImpl.java Vedi File

@@ -68,8 +68,7 @@ public class NjRuleConfigServiceImpl implements NjRuleConfigService {
njRuleConfigMapper.insertOrUpdate(njRuleConfig);
// 根据规则更新年假信息
if(BeanUtil.isNotEmpty(njRuleConfig.getId())){
// njYearLeaveService.updateYearLeave(njRuleConfig.getId());
njBalanceManageService.generateYearBalance("shoudong", njRuleConfigDTO);
njBalanceManageService.generateYearBalance("0", njRuleConfigDTO);
}
// 定义集合
List<NjRuleConfigAndUser> njRuleConfigAndUsers = new ArrayList<>();
@@ -92,6 +91,7 @@ public class NjRuleConfigServiceImpl implements NjRuleConfigService {
njRuleConfigAndUser.setUserName(member.getUserName());
njRuleConfigAndUser.setNickName(member.getNickName());
njRuleConfigAndUser.setJoinedDate(member.getJoinedDate());
njRuleConfigAndUser.setDeptName(member.getDeptName());
njRuleConfigAndUsers.add(njRuleConfigAndUser);
}
}

+ 9
- 7
zs-manager/src/main/resources/mapper/DkRecordMapper.xml Vedi File

@@ -41,17 +41,19 @@

<select id="queryAllUsers" resultType="com.alibaba.fastjson.JSONObject">
SELECT
user_id userId,
user_name userName,
nick_name nickName
u.user_id userId,
u.user_name userName,
u.nick_name nickName,
d.dept_name deptName,
u.joined_date joinedDate
FROM
sys_user u
sys_user u inner join sys_dept d on u.dept_id=d.dept_id
WHERE
del_flag = 0
u.del_flag = 0
AND u.dept_id IN ( SELECT dept_id FROM sys_dept WHERE FIND_IN_SET( '100', ancestors ) OR dept_id = 100 )
AND user_id != 1
AND u.user_id != 1
<if test="attendanceGroupIds != null and attendanceGroupIds.size() > 0">
AND user_id IN (
AND u.user_id IN (
SELECT user_id
FROM dk_check_in_attendance_team_and_user
WHERE attendance_team_id IN

Loading…
Annulla
Salva