package cn.iocoder.yudao.module.hrm.dal.mysql.employee; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeContractDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; import java.time.LocalDate; import java.util.List; /** * 员工合同 Mapper * * @author 超级管理员 */ @Mapper public interface HrmEmployeeContractMapper extends BaseMapperX { /** * 到期提醒天数 */ int REMIND_DAYS = 30; /** * 合同状态:待生效 */ int STATUS_PENDING = 1; /** * 合同状态:生效中 */ int STATUS_ACTIVE = 2; /** * 合同状态:即将到期 */ int STATUS_EXPIRING_SOON = 3; /** * 合同状态:已到期 */ int STATUS_EXPIRED = 4; /** * 解除终止状态:正常 */ int TERMINATE_NORMAL = 0; /** * 解除终止状态:已解除 */ int TERMINATE_CANCELED = 1; /** * 解除终止状态:已终止 */ int TERMINATE_TERMINATED = 2; default PageResult selectPage(HrmEmployeeContractPageReqVO reqVO, LocalDate today) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() .likeIfPresent(HrmEmployeeContractDO::getContractNo, reqVO.getContractNo()) .eqIfPresent(HrmEmployeeContractDO::getEmployeeId, reqVO.getEmployeeId()) .eqIfPresent(HrmEmployeeContractDO::getContractType, reqVO.getContractType()) .eqIfPresent(HrmEmployeeContractDO::getContractTermType, reqVO.getContractTermType()) .eqIfPresent(HrmEmployeeContractDO::getTerminateStatus, reqVO.getTerminateStatus()) .orderByDesc(HrmEmployeeContractDO::getId); // 动态状态筛选(与 terminateStatus 互斥,优先按状态筛选) if (reqVO.getStatus() != null) { appendStatusCondition(query, reqVO.getStatus(), today); } else if (reqVO.getExpiryType() != null) { appendExpiryCondition(query, reqVO.getExpiryType(), today); } return selectPage(reqVO, query); } /** * 拼接动态状态筛选条件 * * @param status 合同状态:1-待生效 2-生效中 3-即将到期 4-已到期 5-已解除 6-已终止 */ default void appendStatusCondition(LambdaQueryWrapperX query, Integer status, LocalDate today) { switch (status) { case STATUS_PENDING: // 待生效 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .gt(HrmEmployeeContractDO::getStartDate, today); break; case STATUS_ACTIVE: // 生效中:未解除/终止,已开始,且未结束(含无固定期限) query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .le(HrmEmployeeContractDO::getStartDate, today) .and(w -> w.isNull(HrmEmployeeContractDO::getEndDate) .or().ge(HrmEmployeeContractDO::getEndDate, today)); break; case STATUS_EXPIRING_SOON: // 即将到期 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .le(HrmEmployeeContractDO::getStartDate, today) .ge(HrmEmployeeContractDO::getEndDate, today) .le(HrmEmployeeContractDO::getEndDate, today.plusDays(REMIND_DAYS)); break; case STATUS_EXPIRED: // 已到期 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .isNotNull(HrmEmployeeContractDO::getEndDate) .lt(HrmEmployeeContractDO::getEndDate, today); break; case 5: // 已解除 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_CANCELED); break; case 6: // 已终止 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_TERMINATED); break; default: break; } } /** * 拼接到期类型筛选条件(待办提醒用) * * @param expiryType 到期类型:1-即将到期 2-已到期 */ default void appendExpiryCondition(LambdaQueryWrapperX query, Integer expiryType, LocalDate today) { if (expiryType == 1) { // 即将到期 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .le(HrmEmployeeContractDO::getStartDate, today) .between(HrmEmployeeContractDO::getEndDate, today, today.plusDays(REMIND_DAYS)); } else if (expiryType == 2) { // 已到期 query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .isNotNull(HrmEmployeeContractDO::getEndDate) .lt(HrmEmployeeContractDO::getEndDate, today); } } /** * 统计即将到期的合同数量(供待办/首页提醒) */ default Long selectCountByExpiring(LocalDate today) { return selectCount(new LambdaQueryWrapperX() .eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL) .le(HrmEmployeeContractDO::getStartDate, today) .between(HrmEmployeeContractDO::getEndDate, today, today.plusDays(REMIND_DAYS))); } /** * 查询同一员工时间重叠的未解除/未终止合同 * * @param employeeId 员工ID * @param startDate 新合同开始日期 * @param endDate 新合同结束日期(无固定期限为 null,视为无限长) * @param excludeId 需要排除的合同ID(更新时传自身 id,创建时传 null) * @return 重叠的合同列表 */ default List selectOverlapping(Long employeeId, LocalDate startDate, LocalDate endDate, Long excludeId) { LambdaQueryWrapperX query = new LambdaQueryWrapperX(); query.eq(HrmEmployeeContractDO::getEmployeeId, employeeId); query.eq(HrmEmployeeContractDO::getTerminateStatus, TERMINATE_NORMAL); if (excludeId != null) { query.ne(HrmEmployeeContractDO::getId, excludeId); } if (endDate != null) { // 新合同有结束日期:与已存在合同的 [startDate, endDate] 区间存在交集即冲突 query.lt(HrmEmployeeContractDO::getStartDate, endDate); query.and(w -> w.isNull(HrmEmployeeContractDO::getEndDate) .or().gt(HrmEmployeeContractDO::getEndDate, startDate)); } // 新合同无固定期限(endDate 为 null):员工存在任意未解除/终止合同即冲突 return selectList(query); } /** * 清除该员工全部合同的"当前合同"标记 * * @param employeeId 员工ID */ default void clearCurrentByEmployee(Long employeeId) { update(null, new LambdaUpdateWrapper() .eq(HrmEmployeeContractDO::getEmployeeId, employeeId) .set(HrmEmployeeContractDO::getIsCurrent, false)); } /** * 查询员工的全部合同(按创建时间倒序) * * @param employeeId 员工ID * @return 合同列表 */ default List selectListByEmployee(Long employeeId) { return selectList(new LambdaQueryWrapperX() .eq(HrmEmployeeContractDO::getEmployeeId, employeeId) .orderByDesc(HrmEmployeeContractDO::getId)); } }