浏览代码

1.发送薪资邮件逻辑调整,以两个QQ邮箱轮流发送邮件并随机休眠2-4s/封,且接口调整为异步
2.表修改,新增字段salary_year与salary_month
3.邮件发送记录接口新增年月查询条件

GouGengquan 1 天之前
父节点
当前提交
ca4beeddff

+ 11 - 1
biz-base/src/main/resources/application-local.yml

@@ -86,7 +86,17 @@ posyspath:  /Users/wuwei/pageoffice
 mail:
   configs:
     # 邮箱信息
-    - business-name: hr_payslip
+    - business-name: hr_payslip_01
+      host: smtp.qq.com #host
+      port: 465 #端口
+      protocol: smtp #协议
+      username: xxxxxx@qq.com #邮箱
+      password: xxxxxx #密码或授权码
+      default-encoding: UTF-8
+      auth: true #smtp auth
+      SSL-enable: true #ssl加密是否开启
+      SSL-required: true #ssl加密是否必须
+    - business-name: hr_payslip_02
       host: smtp.qq.com #host
       port: 465 #端口
       protocol: smtp #协议

+ 2 - 1
common/src/main/java/com/dayou/configuration/AsyncManager.java

@@ -301,7 +301,8 @@ public class AsyncManager {
     public enum AsyncBiz implements CodeMsgEnumInterface<String, String> {
         BROKERAGE_SETTLE("BROKERAGE_SETTLE","提成结算"),
 
-        PACKAGING_EVALUATE_REMAIN("PACKAGING_EVALUATE_REMAIN","打包评价提醒消息")
+        PACKAGING_EVALUATE_REMAIN("PACKAGING_EVALUATE_REMAIN","打包评价提醒消息"),
+        HR_PAYSLIP_EMAIL_SEND("HR_PAYSLIP_EMAIL_SEND","发送薪资邮件")
         ;
 
         private String key;

+ 9 - 1
dao/src/main/resources/mapper/HrPayslipEmailMapper.xml

@@ -41,7 +41,9 @@
                email.deleted,
                email.created,
                email.modified,
-               user.name AS operatorName
+               user.name AS operatorName,
+               salary_month,
+               salary_year
         FROM hr_payslip_email AS email
         LEFT JOIN user ON user.id = email.operator_id
         WHERE email.deleted = 0
@@ -52,6 +54,12 @@
             <if test="hrPayslipEmail.recipientName != null">
                 AND email.recipient_name = #{hrPayslipEmail.recipientName}
             </if>
+            <if test="hrPayslipEmail.salaryYear != null">
+                AND email.salary_year = #{hrPayslipEmail.salaryYear}
+            </if>
+            <if test="hrPayslipEmail.salaryMonth != null">
+                AND email.salary_month = #{hrPayslipEmail.salaryMonth}
+            </if>
         </if>
     </select>
 

+ 13 - 0
domain/src/main/java/com/dayou/entity/HrPayslipEmail.java

@@ -82,5 +82,18 @@ public class HrPayslipEmail extends BaseEntity {
     @ExportCell(columnName = "失败原因(发送失败才有)")
     private String failureReason;
 
+    /**
+     * 薪资发放年份
+     */
+    @ImportCell
+    @ExportCell(columnName = "薪资发放年份")
+    private Integer salaryYear;
+
+    /**
+     * 薪资发放月份
+     */
+    @ImportCell
+    @ExportCell(columnName = "薪资发放月份")
+    private Integer salaryMonth;
 
 }

+ 84 - 42
service/src/main/java/com/dayou/service/impl/HrPayslipEmailServiceImpl.java

@@ -1,5 +1,7 @@
 package com.dayou.service.impl;
 
+import cn.hutool.core.util.RandomUtil;
+import com.dayou.configuration.AsyncManager;
 import com.dayou.configuration.MailSenderConfig;
 import com.dayou.dto.PayslipMailMessageDTO;
 import com.dayou.entity.HrPayslipEmail;
@@ -18,6 +20,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
 import java.time.LocalDateTime;
 import java.util.*;
 
@@ -45,7 +48,8 @@ public class HrPayslipEmailServiceImpl extends ServiceImpl<HrPayslipEmailMapper,
 
     /**
      * 分页查询邮件发送记录
-     * @param page 分页
+     *
+     * @param page           分页
      * @param hrPayslipEmail 查询参数
      * @return Page<HrPayslipEmailVO>
      */
@@ -67,51 +71,89 @@ public class HrPayslipEmailServiceImpl extends ServiceImpl<HrPayslipEmailMapper,
      */
     @Override
     public Boolean sendEmailBatch(MultipartFile file, String subject, String year, String month) throws Exception {
+
+        Long userId = LoginContext.getCurrentUserId();
+        // 异步执行的时候,主线程结束,临时文件就会被清空,会报错 系统找不到指定的文件, 所以把这一步放到外面先执行
         ExcelPlusUtil<PayslipMailMessageDTO> util = new ExcelPlusUtil<>(PayslipMailMessageDTO.class);
         List<PayslipMailMessageDTO> dtoList = util.importExcel(file.getInputStream());
-        // 构建邮件发送
-        JavaMailSenderImpl mailSender = senderConfig.getSenderByBusiness("hr_payslip");
-        //创建MimeMessage对象
-        MimeMessage mimeMessage = mailSender.createMimeMessage();
-        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
-        //邮件发送人
-        messageHelper.setFrom(Objects.requireNonNull(mailSender.getUsername()));
-
-        // 循环发送邮件
-        for (PayslipMailMessageDTO dto : dtoList) {
-            HrPayslipEmail hrPayslipEmail = new HrPayslipEmail();
-            try {
-                // 保存发送信息
-                hrPayslipEmail.setOperatorId(LoginContext.getCurrentUserId());
-                hrPayslipEmail.setSenderEmail(mailSender.getUsername());
-                hrPayslipEmail.setRecipientEmail(dto.getEmail());
-                hrPayslipEmail.setRecipientName(dto.getName());
-                hrPayslipEmail.setIdNo(dto.getIdNo());
-                hrPayslipEmail.setDepartment(dto.getDepartment());
-                hrPayslipEmail.setSendTime(LocalDateTime.now());
-
-                // 发送邮件
-                dto.setYear(year);
-                dto.setMonth(month);
-                messageHelper.setTo(dto.getEmail());
-                messageHelper.setSubject(subject);
-                // 根据ftl模板构建html内容
-                String html = buildHtml(dto);
-                // 发送html需要设置为true
-                messageHelper.setText(html, true);
-                mailSender.send(messageHelper.getMimeMessage());
-                // 发送成功状态true
-                hrPayslipEmail.setSendingStatus(true);
-            } catch (Exception sendException) { // 单个邮件发送失败手动捕获处理
-                log.error("邮箱:" + dto.getEmail() + "的薪资邮件发送失败" + sendException.getMessage());
-                // 发送失败状态false
-                hrPayslipEmail.setSendingStatus(false);
-                hrPayslipEmail.setFailureReason(sendException.getMessage());
+        AsyncManager.me().execute(new AsyncManager.BizHandler() {
+
+            @Override
+            public Boolean validBefore() {
+                return Boolean.TRUE;
             }
-            // 保存邮件发送记录
-            this.save(hrPayslipEmail);
 
-        }
+            @Override
+            public Object doCustom() {
+                try {
+                    // 记录发件次数
+                    int sendCount = 0;
+                    // 默认使用的邮箱
+                    String businessName = "hr_payslip_01";
+                    // 循环发送邮件
+                    for (PayslipMailMessageDTO dto : dtoList) {
+                        // 避免频率限制,使用两个邮箱交替发送
+                        if (sendCount == 1) {
+                            // 避免频率限制, 随机休眠2-4s
+                            Thread.sleep(RandomUtil.randomInt(2000, 4000));
+                            sendCount = 0;
+                            switch (businessName) {
+                                case "hr_payslip_01":
+                                    businessName = "hr_payslip_02";
+                                    break;
+                                case "hr_payslip_02":
+                                    businessName = "hr_payslip_01";
+                                    break;
+                            }
+                        }
+                        // 构建邮件发送
+                        JavaMailSenderImpl mailSender = senderConfig.getSenderByBusiness(businessName);
+                        //创建MimeMessage对象
+                        MimeMessage mimeMessage = mailSender.createMimeMessage();
+                        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
+                        //邮件发送人
+                        messageHelper.setFrom(Objects.requireNonNull(mailSender.getUsername()));
+                        HrPayslipEmail hrPayslipEmail = new HrPayslipEmail();
+                        try {
+                            // 保存发送信息
+                            hrPayslipEmail.setOperatorId(userId);
+                            hrPayslipEmail.setSenderEmail(mailSender.getUsername());
+                            hrPayslipEmail.setRecipientEmail(dto.getEmail());
+                            hrPayslipEmail.setRecipientName(dto.getName());
+                            hrPayslipEmail.setIdNo(dto.getIdNo());
+                            hrPayslipEmail.setDepartment(dto.getDepartment());
+                            hrPayslipEmail.setSendTime(LocalDateTime.now());
+                            hrPayslipEmail.setSalaryYear(Integer.valueOf(year));
+                            hrPayslipEmail.setSalaryMonth(Integer.valueOf(month));
+
+                            // 发送邮件
+                            dto.setYear(year);
+                            dto.setMonth(month);
+                            messageHelper.setTo(dto.getEmail());
+                            messageHelper.setSubject(subject);
+                            // 根据ftl模板构建html内容
+                            String html = buildHtml(dto);
+                            // 发送html需要设置为true
+                            messageHelper.setText(html, true);
+                            mailSender.send(messageHelper.getMimeMessage());
+                            // 发送成功状态true
+                            hrPayslipEmail.setSendingStatus(true);
+                            sendCount++;
+                        } catch (Exception sendException) { // 单个邮件发送失败手动捕获处理
+                            log.error("邮箱:" + dto.getEmail() + "的薪资邮件发送失败" + sendException.getMessage());
+                            // 发送失败状态false
+                            hrPayslipEmail.setSendingStatus(false);
+                            hrPayslipEmail.setFailureReason(sendException.getMessage());
+                        }
+                        // 保存邮件发送记录
+                        hrPayslipEmailMapper.insert(hrPayslipEmail);
+                    }
+                }catch (Exception e) {
+                    log.error("薪资邮件发送失败:" + e.getMessage());
+                }
+                return null;
+            }
+        });
         return Boolean.TRUE;
     }
 

+ 6 - 4
sql/update_sql.sql

@@ -1003,11 +1003,12 @@ CREATE TABLE `assets_complaint`
   DEFAULT CHARSET = utf8mb4 COMMENT ='资产业务项目投诉表';
 
 /**
-  日期:2025-07-25
+  日期:2025-07-29
   修改人:苟耕铨
   未更新到test-env
  */
 #  新增人力资源_薪资(工资条)通知邮件表
+DROP TABLE IF EXISTS `hr_payslip_email`;
 CREATE TABLE `hr_payslip_email`
 (
     `id`              bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '自增主键',
@@ -1020,11 +1021,12 @@ CREATE TABLE `hr_payslip_email`
     `send_time`       datetime     NOT NULL COMMENT '发送时间',
     `sending_status`  bit(1)       NOT NULL DEFAULT b'0' COMMENT '发送状态',
     `failure_reason`  text COMMENT '失败原因(发送失败才有)',
+    `salary_year`     int(11)      NOT NULL COMMENT '薪资发放年份',
+    `salary_month`    int(11)      NOT NULL COMMENT '薪资发放月份',
     `deleted`         bit(1)       NOT NULL DEFAULT b'0' COMMENT '逻辑删除标识:1:删除 0:未删除',
     `created`         datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `modified`        timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '修改时间',
     PRIMARY KEY (`id`),
-    KEY `sender_id` (`operator_id`) USING BTREE
+    KEY `operator_id` (`operator_id`) USING BTREE
 ) ENGINE = InnoDB
-  AUTO_INCREMENT = 5
-  DEFAULT CHARSET = utf8mb4 COMMENT ='人力资源_薪资(工资条)通知邮件';
+  DEFAULT CHARSET = utf8mb4 COMMENT ='人力资源_薪资(工资条)通知邮件';