tuqin
2026-11-03 5d8a5addb80d0f1663862963b76a1a4a7d9295fd
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -32,6 +32,9 @@
import cn.iocoder.yudao.module.hrm.dal.mysql.salary.HrmSalaryStructureMapper;
import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import lombok.extern.slf4j.Slf4j;
import cn.iocoder.yudao.module.hrm.enums.HrmOvertimeTypeEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -44,6 +47,7 @@
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -60,6 +64,7 @@
 */
@Service
@Validated
@Slf4j
public class HrmSalaryCalculationServiceImpl implements HrmSalaryCalculationService {
    /**
@@ -89,6 +94,8 @@
    private HrmNoRedisDAO noRedisDAO;
    @Resource
    private DeptApi deptApi;
    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;
    @Resource
    private HrmDeductionService deductionService;
    @Resource
@@ -491,6 +498,8 @@
            salaryCalculationMapper.updateById(salaryCalculation);
            // 记录周期
            period = salaryCalculation.getPeriod();
            // 确认后给该员工发送工资条通知(失败不影响确认主流程)
            sendPayslipNotice(salaryCalculation);
        }
        // 检查该周期是否所有核算记录都已确认,自动生成发放台账
@@ -502,6 +511,39 @@
    /**
     * 检查该周期是否所有核算记录都已确认,如果全部确认则自动生成发放台账
     */
    /**
     * 工资条通知的站内信模板编码
     *
     * 对应 system_notify_template.code = salary_payslip_notice
     */
    private static final String TEMPLATE_CODE_PAYSLIP = "salary_payslip_notice";
    /**
     * 给员工发送工资条通知(APP 站内信)
     *
     * 通知失败只记日志,不影响核算确认主流程
     */
    private void sendPayslipNotice(HrmSalaryCalculationDO calculation) {
        if (calculation == null || calculation.getUserId() == null) {
            return;
        }
        try {
            NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO();
            reqDTO.setUserId(calculation.getUserId());
            reqDTO.setTemplateCode(TEMPLATE_CODE_PAYSLIP);
            Map<String, Object> params = new HashMap<>();
            params.put("period", calculation.getPeriod());
            params.put("actualSalary", calculation.getActualSalary());
            reqDTO.setTemplateParams(params);
            notifyMessageSendApi.sendSingleMessageToAdmin(reqDTO);
            log.info("[sendPayslipNotice] 工资条通知已发送,userId={}, period={}",
                    calculation.getUserId(), calculation.getPeriod());
        } catch (Exception e) {
            log.warn("[sendPayslipNotice] 工资条通知发送失败,userId={}, period={}",
                    calculation.getUserId(), calculation.getPeriod(), e);
        }
    }
    private void autoGeneratePaymentIfAllConfirmed(String period) {
        // 查询该周期所有核算记录
        List<HrmSalaryCalculationDO> allCalculations = salaryCalculationMapper.selectListByPeriod(period);