yubo
2026-03-10 b97dc921008fc61a7e0d9de04dbce2956e65e178
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;
    }
}