package com.ruoyi.staff.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.project.system.service.ISysNoticeService; import com.ruoyi.staff.dto.SaveStaffSchedulingDto; import com.ruoyi.staff.dto.StaffSchedulingDto; import com.ruoyi.staff.mapper.StaffSchedulingMapper; import com.ruoyi.staff.pojo.StaffOnJob; import com.ruoyi.staff.pojo.StaffScheduling; import com.ruoyi.staff.mapper.StaffOnJobMapper; import com.ruoyi.staff.service.StaffSchedulingService; import com.ruoyi.staff.vo.SearchSchedulingVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; import java.math.BigDecimal; import java.time.Duration; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * @author buhuazhen * @description 针对表【staff_scheduling】的数据库操作Service实现 * @createDate 2025-09-03 14:50:34 */ @Slf4j @Service @RequiredArgsConstructor public class StaffSchedulingServiceImpl extends ServiceImpl implements StaffSchedulingService { private final StaffSchedulingMapper staffSchedulingMapper; private final StaffOnJobMapper staffOnJobMapper; private final SysUserMapper sysUserMapper; private final ISysNoticeService sysNoticeService; @Lazy @Resource private StaffSchedulingService staffSchedulingService; @Override public void saveStaffScheduling(SaveStaffSchedulingDto saveStaffSchedulingDto) { StaffScheduling staffScheduling = new StaffScheduling(); BeanUtils.copyProperties(saveStaffSchedulingDto, staffScheduling); // 开始计算时间 Duration duration = Duration.between(staffScheduling.getWorkStartTime(), staffScheduling.getWorkEndTime()); long hours = duration.toHours(); // 0.5 double minutes = (duration.toMinutes() % 60) / 60.0; // minutes = minutes < 0.5 ? 0 : 0.5; 公司一般以0.5为标准计算 staffScheduling.setWorkHours(BigDecimal.valueOf(hours + minutes)); staffSchedulingService.saveOrUpdate(staffScheduling); // 发送排班通知 sendSchedulingNotification(staffScheduling); } /** * 发送排班通知给被排班人员 * @param staffScheduling 排班信息 */ private void sendSchedulingNotification(StaffScheduling staffScheduling) { try { if (staffScheduling.getStaffId() == null || staffScheduling.getStaffId().isEmpty()) { return; } // 解析员工ID列表 List staffIds = Arrays.stream(staffScheduling.getStaffId().split(",")) .map(String::trim) .filter(s -> !s.isEmpty()) .map(Long::parseLong) .collect(Collectors.toList()); if (staffIds.isEmpty()) { return; } // 查询员工档案 List staffList = staffOnJobMapper.selectList(Wrappers.lambdaQuery() .in(StaffOnJob::getId, staffIds) .eq(StaffOnJob::getStaffState, 1)); if (staffList.isEmpty()) { return; } // 获取员工编号列表 List staffNos = staffList.stream() .map(StaffOnJob::getStaffNo) .filter(s -> s != null && !s.isEmpty()) .collect(Collectors.toList()); if (staffNos.isEmpty()) { return; } // 查询系统用户 List users = sysUserMapper.selectList(Wrappers.lambdaQuery() .in(SysUser::getUserName, staffNos) .eq(SysUser::getStatus, "0")); if (users.isEmpty()) { log.warn("排班通知:未找到对应的系统用户"); return; } // 格式化日期时间 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); String workDateStr = staffScheduling.getWorkDate() != null ? new java.text.SimpleDateFormat("yyyy-MM-dd").format(staffScheduling.getWorkDate()) : ""; String startTimeStr = staffScheduling.getWorkStartTime() != null ? staffScheduling.getWorkStartTime().format(timeFormatter) : ""; String endTimeStr = staffScheduling.getWorkEndTime() != null ? staffScheduling.getWorkEndTime().format(timeFormatter) : ""; // 构建通知内容 String title = "排班通知"; String message = String.format("您好,您已被安排在 %s 上班,工作时间:%s - %s", workDateStr, startTimeStr, endTimeStr); // 发送通知给所有被排班人员 List userIds = users.stream() .map(SysUser::getUserId) .collect(Collectors.toList()); sysNoticeService.simpleNoticeByUser(title, message, userIds, "/scheduling"); log.info("已向 {} 名员工发送排班通知", userIds.size()); } catch (Exception e) { log.error("发送排班通知失败:{}", e.getMessage(), e); } } @Override public IPage listPage(SearchSchedulingVo vo) { Page page = new Page<>(vo.getCurrent(), vo.getSize()); return staffSchedulingMapper.listPage(page, vo); } @Override public StaffScheduling getCurrentUserLatestScheduling() { LoginUser loginUser = SecurityUtils.getLoginUser(); return staffSchedulingMapper.selectOne(new LambdaQueryWrapper() .like(StaffScheduling::getStaffId,loginUser.getUserId()) .orderByDesc(StaffScheduling::getWorkEndTime) .last("LIMIT 1")); } }