febs-common/febs-common-core/src/main/java/cc/mrbird/febs/common/core/constant/DicCode.java
@@ -91,4 +91,9 @@ * 相关证件 */ public final static String CERTIFICATE_LIST = "certificateList"; /** * 转正状态 */ public final static String PROBATIONS_TATUS = "probationStatus"; } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java
@@ -299,8 +299,44 @@ Map<String, Object> dataTable = FebsUtil.getDataTable(this.empBaseInfoService.findInsuranceEmpBaseInfos(request, empBaseinfo)); return new FebsResponse().data(dataTable); } @ApiOperation(value = "退休提醒人员基本信息翻页列表") @GetMapping("retire/alert") @PreAuthorize("hasAuthority('empBaseinfo:list')") public FebsResponse retirementAlertEmpBaseInfoList(QueryRequest request, EmpBaseInfo empBaseinfo) { Map<String, Object> dataTable = FebsUtil.getDataTable(this.empBaseInfoService.findRetirementEmpBaseInfos(request, empBaseinfo)); return new FebsResponse().data(dataTable); } @ApiOperation(value = "退休解骋") @PostMapping("retire/dismiss") @PreAuthorize("hasAuthority('empBaseinfo:dimission')") public void retireDismissionEmp(EmpDimissionLog empDimissionLog) throws FebsException { try { empDimissionLog.setDimissionDate(new Date()); this.empBaseInfoService.closeEmpArchives(empDimissionLog); } catch (Exception e) { String message = "退休解骋员工失败"; log.error(message, e); throw new FebsException(message); } } @ApiOperation(value = "转正提醒人员基本信息翻页列表") @GetMapping("probation/alert") @PreAuthorize("hasAuthority('empBaseinfo:list')") public FebsResponse probationAlertEmpBaseInfoList(QueryRequest request, EmpBaseInfo empBaseinfo) { Map<String, Object> dataTable = FebsUtil.getDataTable(this.empBaseInfoService.findProbationEmpBaseInfos(request, empBaseinfo)); return new FebsResponse().data(dataTable); } @ApiOperation(value = "设置人员转正信息") @PostMapping("probation/change") @PreAuthorize("hasAuthority('empBaseinfo:dimission')") public void probationChangeEmpBaseInfo(EmpBaseInfo empBaseinfo) { this.empBaseInfoService.probationEmpBaseInfo(empBaseinfo); } @ApiOperation(value = "导出员工") @RequestMapping(value = "export/insurance",method= RequestMethod.POST) @PostMapping(value = "export/insurance") @ControllerEndpoint(operation = "导出社保提醒数据", exceptionMessage = "导出Excel失败") public void exportInsuranceWithField(QueryRequest request, HttpServletResponse response, String exportField,EmpBaseInfo empBaseinfo) throws IOException { request.setPageSize(25535); febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpContractInfoController.java
@@ -1,18 +1,17 @@ package cc.mrbird.febs.server.hr.controller; import cc.mrbird.febs.server.hr.annotation.ControllerEndpoint; import cc.mrbird.febs.server.hr.entity.EmpAccidentCases; import cc.mrbird.febs.server.hr.entity.EmpContractInfo; import cc.mrbird.febs.server.hr.service.IEmpContractInfoService; import cc.mrbird.febs.common.core.entity.FebsResponse; import cc.mrbird.febs.common.core.entity.QueryRequest; import cc.mrbird.febs.common.core.exception.FebsException; import cc.mrbird.febs.common.core.utils.FebsUtil; import cc.mrbird.febs.server.hr.annotation.ControllerEndpoint; import cc.mrbird.febs.server.hr.entity.EmpContractInfo; import cc.mrbird.febs.server.hr.service.IEmpContractInfoService; import com.wuwenze.poi.ExcelKit; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -153,4 +152,16 @@ throw new FebsException(message); } } @RequestMapping(value = "retire/rehire", method = RequestMethod.POST) @PreAuthorize("hasAuthority('empContractinfo:add')") public void retireRehireEmpContract(@Valid EmpContractInfo empContractinfo) throws FebsException { try { this.empContractinfoService.retireRehireEmpContract(empContractinfo); } catch (Exception e) { String message = "续签员工合同信息失败"; log.error(message, e); throw new FebsException(message); } } } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java
@@ -1,27 +1,24 @@ package cc.mrbird.febs.server.hr.entity; import java.io.Serializable; import java.time.LocalDate; import java.util.Date; import cc.mrbird.febs.common.core.annotation.FieldInfo; import cc.mrbird.febs.common.core.converter.TimeConverter; import cc.mrbird.febs.common.core.utils.DateDeSerializer; import cc.mrbird.febs.common.core.utils.DateSerializer; import cc.mrbird.febs.common.core.utils.DateTimeDeserializer; import cc.mrbird.febs.common.core.utils.DateTimeSerializer; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.wuwenze.poi.annotation.Excel; import com.wuwenze.poi.annotation.ExcelField; import lombok.Data; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.Version; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotBlank; import java.io.Serializable; import java.util.Date; /** * name:EmpBaseinfo @@ -435,4 +432,24 @@ @FieldInfo(name = "annualLeave", type = "int", explain = "年假天数") @TableField("annualLeave") private Integer annualLeave = 0; @FieldInfo(name = "probationDate", type = "date", explain = "转正日期") @TableField("probationDate") @JsonSerialize(using = DateSerializer.class) @JsonDeserialize(using = DateDeSerializer.class) @DateTimeFormat(pattern = "yyyy-MM-dd") @ExcelField(value = "转正日期", writeConverter = TimeConverter.class) private Date probationDate; @FieldInfo(name = "probationStatus", type = "varchar", explain = "转正状态:0-待转正,1-已转正,2-解聘,3-延期") @TableField("probationStatus") private String probationStatus = ""; @FieldInfo(name = "probationStatusName", type = "varchar", explain = "转正状态") @TableField(exist = false) private String probationStatusName = ""; @FieldInfo(name = "retirementReminded", type = "tinyint", explain = "是否已提醒退休。0-未提醒 1-已提醒") @TableField("retirementReminded") private Integer retirementReminded = 0; } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java
@@ -220,4 +220,10 @@ "</script>") int updateDeptName(); @Update("<script> " + " update t_emp_baseinfo set retirementReminded=#{retirementReminded}, \n" + " modifier=#{operatorId}, \n" + " modifyTime=now() where empId=#{empId}; \n" + "</script>") int updateRetirementReminded(@Param("empId") String empId,@Param("retirementReminded") String retirementReminded,@Param("operatorId") String operatorId); } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java
@@ -249,4 +249,30 @@ * @return IPage<EmpBaseinfo> */ IPage<EmpBaseInfo> findInsuranceEmpBaseInfos(QueryRequest request, EmpBaseInfo empBaseInfo); /** * 获取到龄退休提醒员工 查询(分页) * * @param request QueryRequest * @param empBaseInfo empBaseinfo * @return IPage<EmpBaseinfo> */ IPage<EmpBaseInfo> findRetirementEmpBaseInfos(QueryRequest request, EmpBaseInfo empBaseInfo); /** * 查询当月待转正员工 查询(分页) * * @param request QueryRequest * @param empBaseInfo empBaseinfo * @return IPage<EmpBaseinfo> */ IPage<EmpBaseInfo> findProbationEmpBaseInfos(QueryRequest request, EmpBaseInfo empBaseInfo); /** * 待转正员工转正,如果转正状态为转正或延期,则只更新员工信息对应的内容,如果为2则更新内容的同时要关闭员工档案 * * @param empBaseInfo empBaseinfo */ void probationEmpBaseInfo(EmpBaseInfo empBaseInfo); } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpContractInfoService.java
@@ -1,9 +1,8 @@ package cc.mrbird.febs.server.hr.service; import cc.mrbird.febs.common.core.entity.QueryRequest; import cc.mrbird.febs.common.core.entity.system.DicItem; import cc.mrbird.febs.server.hr.entity.EmpContractInfo; import cc.mrbird.febs.common.core.entity.QueryRequest; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; @@ -119,4 +118,6 @@ * @return void */ void continueEmpContract(EmpContractInfo empContractinfo); void retireRehireEmpContract(EmpContractInfo empContractinfo); } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java
@@ -43,6 +43,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.time.LocalDate; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -1512,6 +1513,65 @@ return iPage; } @Override public IPage<EmpBaseInfo> findRetirementEmpBaseInfos(QueryRequest request, EmpBaseInfo empBaseInfo) { Page<EmpBaseInfo> page = new Page<>(request.getPageNum(), request.getPageSize()); SortUtil.handlePageSort(request, page, "birthDate", FebsConstant.ORDER_ASC, true); return empBaseInfoMapper.selectPageVo(page, createRetirementAlertQueryWrapper(empBaseInfo)); } @Override public IPage<EmpBaseInfo> findProbationEmpBaseInfos(QueryRequest request, EmpBaseInfo empBaseInfo) { Page<EmpBaseInfo> page = new Page<>(request.getPageNum(), request.getPageSize()); SortUtil.handlePageSort(request, page, "probationDate", FebsConstant.ORDER_ASC, true); IPage<EmpBaseInfo> iPage = empBaseInfoMapper.selectPageVo(page, createProbationAlertQueryWrapper(empBaseInfo)); List<EmpBaseInfo> list = iPage.getRecords(); List<DicItem> dicItems = CastUtil.castList(redisService.get("dicItems"), DicItem.class); list.forEach(item -> { item.setProbationStatusName(dicItems.stream() .filter(k -> DicCode.PROBATIONS_TATUS.equals(k.getDicCode()) && k.getDicItemCode().equals(item.getProbationStatus())) .findFirst() .map(DicItem::getDicItemName) .orElse("未知")); item.setInsuranceTypeName(dicItems.stream() .filter(k -> DicCode.INSURANCETYPE.equals(k.getDicCode()) && k.getDicItemCode().equals(item.getInsuranceType())) .findFirst() .map(DicItem::getDicItemName) .orElse("未知")); }); iPage.setRecords(list); return iPage; } @Override @Transactional(rollbackFor = Exception.class) public void probationEmpBaseInfo(EmpBaseInfo empBaseInfo) { String operatorId = Optional.of(FebsUtil.getUserId()).orElse("1"); LambdaUpdateWrapper<EmpBaseInfo> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(EmpBaseInfo::getEmpId, empBaseInfo.getEmpId()) .set(EmpBaseInfo::getProbationDate, empBaseInfo.getProbationDate()) .set(EmpBaseInfo::getProbationStatus, empBaseInfo.getProbationStatus()) .set(EmpBaseInfo::getModifier, operatorId) .set(EmpBaseInfo::getModifyTime, new Date()); this.update(updateWrapper); if (empBaseInfo.getProbationStatus().equals("2")) { // 如果是解骋,需要关闭员工档案 EmpDimissionLog dimissionLog = new EmpDimissionLog(); dimissionLog.setDimissionDate(empBaseInfo.getProbationDate()); dimissionLog.setDimissionType("5"); dimissionLog.setEmpIds(empBaseInfo.getEmpId().toString()); dimissionLog.setEntryDates(DateUtil.format(empBaseInfo.getEntryDate(), "yyyy-MM-dd")); dimissionLog.setDeptNames(empBaseInfo.getDeptName()); dimissionLog.setAfterOperation("1"); this.closeEmpArchives(dimissionLog); } } /** * 根据设置的参数计算员工的年假 * @@ -1542,67 +1602,107 @@ } private QueryWrapper<EmpBaseInfo> createInsuranceAlertQueryWrapper(EmpBaseInfo empBaseInfo) { String INSURANCE_TYPE_FOUR_ONE = "7"; String INSURANCE_TYPE_FOUR_TWO = "6"; QueryWrapper<EmpBaseInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("a.DelFlag", "0"); queryWrapper.eq("a.empStatus", "0"); int fourOneWoman = getRedisConfigWithDefault("four_one_woman", 39); int fourOneMan = getRedisConfigWithDefault("four_one_man", 45); int fourTwoWoman = getRedisConfigWithDefault("four_two_woman", 46); int fourTwoMan = getRedisConfigWithDefault("four_two_man", 55); queryWrapper.and(wrapper -> wrapper .nested(inner -> inner .eq("a.insuranceType", INSURANCE_TYPE_FOUR_TWO) .and(ageWrapper -> buildAgeCondition(ageWrapper, fourTwoMan, fourTwoWoman)) ).or().nested(inner -> inner .eq("a.insuranceType", INSURANCE_TYPE_FOUR_ONE) .and(ageWrapper -> buildAgeCondition(ageWrapper, fourOneMan, fourOneWoman)) ).or().nested(inner -> inner .and(noInsuranceWrapper -> noInsuranceWrapper .isNull("a.insuranceType") .or().eq("a.insuranceType", "") ) ) ); return queryWrapper; } private void buildAgeCondition(QueryWrapper<EmpBaseInfo> wrapper, int manAge, int womanAge) { wrapper.nested(inner -> inner .gt("a.age", manAge).eq("a.sex", "1") ).or().nested(inner -> inner .gt("a.age", womanAge).eq("a.sex", "2") ); } private int getRedisConfigWithDefault(String key, int defaultValue) { try { Object value = redisService.get(key); if (value == null) { log.warn("Redis配置 [{}] 不存在,使用默认值:{}"); return defaultValue; } return Integer.parseInt(value.toString()); } catch (Exception e) { log.warn("Redis配置 [{}] 解析失败,使用默认值:{}"); return defaultValue; } } private QueryWrapper<EmpBaseInfo> createRetirementAlertQueryWrapper(EmpBaseInfo empBaseInfo) { QueryWrapper<EmpBaseInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("a.DelFlag", 0); //人员的状态,0-在职 1-离职 2-退休 queryWrapper.eq("a.empStatus", "0"); // 未提醒 queryWrapper.eq("a.retirementReminded", 0); if (StringUtils.isNotBlank(empBaseInfo.getSex())) { queryWrapper.in("a.sex", empBaseInfo.getSex()); } //男,1 女,2 (非深户)四险二档,6(非深户)四险一档,7 int four_one_woman = Integer.parseInt(redisService.get("four_one_woman").toString()); int four_one_man = Integer.parseInt(redisService.get("four_one_man").toString()); int four_two_woman = Integer.parseInt(redisService.get("four_two_woman").toString()); int four_two_man = Integer.parseInt(redisService.get("four_two_man").toString()); if (StringUtils.isBlank(empBaseInfo.getInsuranceType())) { String targetYearMonthForMan = DateUtil.format(DateUtil.offsetMonth(new Date(), -60 * 12), "yyyy-MM"); String targetYearMonthForWoman = DateUtil.format(DateUtil.offsetMonth(new Date(), -50 * 12), "yyyy-MM"); // 查询条件: // 1. 男性:出生年月 <= 60 年前的本月(即当月或之前满 60 岁) // 2. 女性:出生年月 <= 50 年前的本月(即当月或之前满 50 岁) // 3. 未处理退休提醒 queryWrapper.and(wrapper -> wrapper .nested(inner -> inner .eq("a.insuranceType", "6") // insuranceType = '6' .and(nestedInner -> nestedInner .nested(ageSexWrapper -> ageSexWrapper .gt("a.age", four_two_man) // age > 55 .eq("a.sex", "1") // sex = '1' ).or().nested(ageSexWrapper -> ageSexWrapper .gt("a.age", four_two_woman) // age > 46 .eq("a.sex", "2") // sex = '2' ) ) .eq("a.sex", "1") // sex = '1' (男) .le("DATE_FORMAT(a.birthdate, '%Y-%m')", targetYearMonthForMan) // 生日在当前月份 ).or().nested(inner -> inner .eq("a.insuranceType", "7") // insuranceType = '7' .and(nestedInner -> nestedInner .nested(ageSexWrapper -> ageSexWrapper .gt("a.age", four_one_man) // age > 45 .eq("a.sex", "1") // sex = '1' ).or().nested(ageSexWrapper -> ageSexWrapper .gt("a.age", four_one_woman) // age > 39 .eq("a.sex", "2") // sex = '2' ) ) .eq("a.sex", "2") // sex = '2' (女) .le("DATE_FORMAT(a.birthdate, '%Y-%m')", targetYearMonthForWoman) // 生日在当前月份 ) ); } else { queryWrapper.eq("a.insuranceType", empBaseInfo.getInsuranceType()); if (empBaseInfo.getInsuranceType().equals("7")) { queryWrapper.and(wrapper -> wrapper.nested(inner -> inner .gt("a.age", four_one_man) // age > 45 .eq("a.sex", "1") // sex='1' ).or().nested(inner -> inner .gt("a.age", four_one_woman) // age > 39 .eq("a.sex", "2") // sex='2' )); } else if (empBaseInfo.getInsuranceType().equals("6")) { queryWrapper.and(wrapper -> wrapper.nested(inner -> inner .gt("a.age", four_two_man) // age > 55 .eq("a.sex", "1") // sex='1' ).or().nested(inner -> inner .gt("a.age", four_two_woman) // age > 46 .eq("a.sex", "2") // sex='2' )); return queryWrapper; } } //queryWrapper.in("c.dept_Id", remoteDeptService.userRightDepts().split(StringConstant.COMMA)); private QueryWrapper<EmpBaseInfo> createProbationAlertQueryWrapper(EmpBaseInfo empBaseInfo) { QueryWrapper<EmpBaseInfo> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("a.DelFlag", 0) .eq("a.empStatus", "0"); // 获取当前月份第一天和下月第一天 LocalDate now = LocalDate.now(); LocalDate startOfMonth = now.withDayOfMonth(1); LocalDate startOfNextMonth = startOfMonth.plusMonths(1); // 转正日期在当月范围内:[当月第一天, 下月第一天) queryWrapper.ge("a.probationDate", startOfMonth) .lt("a.probationDate", startOfNextMonth); // 转正状态条件:查询状态为 0 或 3 的员工 queryWrapper.in("a.probationStatus", "0", "3"); return queryWrapper; } } febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpContractInfoServiceImpl.java
@@ -15,10 +15,10 @@ import cc.mrbird.febs.server.hr.entity.EmpBaseInfo; import cc.mrbird.febs.server.hr.entity.EmpContractInfo; import cc.mrbird.febs.server.hr.feign.IRemoteDeptService; import cc.mrbird.febs.server.hr.mapper.EmpBaseInfoMapper; import cc.mrbird.febs.server.hr.mapper.EmpContractInfoMapper; import cc.mrbird.febs.server.hr.service.IEmpBaseInfoService; import cc.mrbird.febs.server.hr.service.IEmpContractInfoService; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -54,6 +54,7 @@ private final EmpContractInfoMapper empContractinfoMapper; private final IRemoteDeptService remoteDeptService; private final IEmpBaseInfoService empBaseInfoService; private final EmpBaseInfoMapper empBaseInfoMapper; private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser()) .map(u -> u.getUserId().toString()) .orElse("1"); @@ -308,4 +309,16 @@ //设置不再提醒 empContractinfoMapper.updateEmpContractRemind(contractId); } @Override @Transactional(rollbackFor = Exception.class) public void retireRehireEmpContract(EmpContractInfo empContractinfo) { // 1.将原来合同状态为解除 empContractinfoMapper.terminateContract(Collections.singletonList(String.valueOf(empContractinfo.getEmpId())), operatorId); // 2.创建一份新合同信息 empContractinfo.setDelFlag(0); this.createEmpContractinfo(empContractinfo); // 不再提醒 empBaseInfoMapper.updateRetirementReminded(empContractinfo.getEmpId().toString(), "1", operatorId); } }