Selaa lähdekoodia

feature 代码提交

xiahan 1 vuosi sitten
vanhempi
commit
f76072d676

+ 34 - 0
bs-common/src/main/java/com/rongwei/safecommon/config/ThreadPoolConfig.java

@@ -0,0 +1,34 @@
+package com.rongwei.safecommon.config;
+
+import cn.hutool.core.thread.ExecutorBuilder;
+import cn.hutool.core.thread.ThreadFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ThreadPoolConfig class
+ *
+ * @author XH
+ * @date 2023/12/18
+ */
+
+@Configuration
+public class ThreadPoolConfig {
+    public static final String NAME_PRE="custom-";
+
+    @Bean("customThreadPool")
+    public static ThreadPoolExecutor getExecutor(){
+        return  ExecutorBuilder.create()
+                .setCorePoolSize(8)
+                .setMaxPoolSize(16)
+                .setKeepAliveTime(60, TimeUnit.SECONDS)
+                .setHandler(new ThreadPoolExecutor.CallerRunsPolicy())
+                .setAllowCoreThreadTimeOut(true)
+                .setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(NAME_PRE).build())
+                .build();
+    }
+
+}

+ 7 - 1
bs-common/src/main/java/com/rongwei/safecommon/fegin/CXCommonFeginClient.java

@@ -1,16 +1,22 @@
 package com.rongwei.safecommon.fegin;
 
 import com.rongwei.rwcommon.base.R;
+import com.rongwei.rwcommon.vo.MailDo;
 import com.rongwei.rwcommonentity.commonservers.vo.SysNotifyAnnounceVo;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.MediaType;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.multipart.MultipartFile;
 
-@FeignClient(value = "rw-common-server",fallback = CXHysitx.class)
+@FeignClient(value = "cx-feign",fallback = CXHysitx.class)
 public interface CXCommonFeginClient {
     @PostMapping("sys/sysnotifyannounce/saveOrUpdate")
+    @Async("customThreadPool")
     void sendNotify(@RequestBody SysNotifyAnnounceVo sysNotifyAnnounceVo);
+
+    @PostMapping("/mail/sendHtmlMail")
+    R sendHtmlMail(@RequestBody MailDo Mail);
 }

+ 9 - 0
bs-common/src/main/java/com/rongwei/safecommon/fegin/CXHysitx.java

@@ -1,9 +1,12 @@
 package com.rongwei.safecommon.fegin;
 
+import com.rongwei.rwcommon.base.R;
+import com.rongwei.rwcommon.vo.MailDo;
 import com.rongwei.rwcommonentity.commonservers.vo.SysNotifyAnnounceVo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * Hysitx class
@@ -19,4 +22,10 @@ public class CXHysitx implements CXCommonFeginClient {
     public void sendNotify(SysNotifyAnnounceVo sysNotifyAnnounceVo) {
         log.error("发送消息通知失败!通知内容为:{}", sysNotifyAnnounceVo);
     }
+
+    @Override
+    public R sendHtmlMail(MailDo mailDo) {
+        log.error("邮件发送失败,数据为{}",mailDo);
+        return R.error();
+    }
 }

+ 1 - 0
bs-common/src/main/java/com/rongwei/safecommon/utils/CXCommonUtils.java

@@ -11,6 +11,7 @@ import com.rongwei.safecommon.fegin.CXCommonFeginClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;

+ 25 - 0
rw-training/training-common/src/main/java/com/rongwei/trainingcommon/sys/service/SendNotifyService.java

@@ -0,0 +1,25 @@
+package com.rongwei.trainingcommon.sys.service;
+
+import com.rongwei.training.domain.PlanDo;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * SendNotifyService class
+ *
+ * @author XH
+ * @date 2023/12/15
+ */
+public interface SendNotifyService {
+
+    /**
+     * 考试截止提醒邮件
+     */
+    void endReminderEmail();
+
+    void trainingPlan();
+
+
+    void questionnaireSurvey();
+}

+ 1 - 1
rw-training/training-common/src/main/java/com/rongwei/trainingcommon/sys/service/impl/SendMailServiceImpl.java

@@ -314,7 +314,7 @@ public class SendMailServiceImpl implements SendMailService {
      * @param startDate
      * @return
      */
-    private long aFewDaysApart(Date startDate) {
+    public long aFewDaysApart(Date startDate) {
         Calendar startInstance = Calendar.getInstance();
         startInstance.setTime(startDate);
         LocalDate startLocalDate = LocalDate.of(startInstance.get(Calendar.YEAR), startInstance.get(Calendar.MONTH) + 1, startInstance.get(Calendar.DAY_OF_MONTH));

+ 165 - 0
rw-training/training-common/src/main/java/com/rongwei/trainingcommon/sys/service/impl/SendNotifyServiceImpl.java

@@ -0,0 +1,165 @@
+package com.rongwei.trainingcommon.sys.service.impl;
+
+import cn.hutool.core.thread.ExecutorBuilder;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.rongwei.rwcommon.base.BaseDo;
+import com.rongwei.rwcommon.utils.StringUtils;
+import com.rongwei.safecommon.utils.CXCommonUtils;
+import com.rongwei.training.domain.EmpExamDo;
+import com.rongwei.training.domain.PlanDo;
+import com.rongwei.training.domain.PlanPaperDo;
+import com.rongwei.training.domain.TrainingDemandSurveyBackupsDo;
+import com.rongwei.trainingcommon.sys.service.EmpExamService;
+import com.rongwei.trainingcommon.sys.service.PlanPaperService;
+import com.rongwei.trainingcommon.sys.service.PlanService;
+import com.rongwei.trainingcommon.sys.service.SendNotifyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.rongwei.safecommon.utils.SaveConstans.NotifyType.TRAINING;
+import static com.rongwei.safecommon.utils.SaveConstans.NotifyType.TRAININGFORM;
+
+/**
+ * SendNotifyService class
+ *
+ * @author XH
+ * @date 2023/12/15
+ */
+@Service
+public class SendNotifyServiceImpl implements SendNotifyService {
+    private final Logger log = LoggerFactory.getLogger(this.getClass().getName());
+    public static final ThreadPoolExecutor threadPool = ExecutorBuilder.create()
+            .setCorePoolSize(8)
+            .setMaxPoolSize(16)
+            .setKeepAliveTime(0, TimeUnit.SECONDS)
+            .build();
+
+    @Autowired
+    private PlanService planService;
+    @Autowired
+    private PlanPaperService planPaperService;
+    @Autowired
+    private SendMailServiceImpl sendMailService;
+    @Autowired
+    private EmpExamService empExamService;
+    public static final String CUT_OFF_TRAIN_TITLE = "培训截止提醒";
+    public static final String CUT_OFF_TRAIN_CONTENT = "培训考试将于%tF截止,请尽快参加考试。";
+    public static final String TRAIN_NOTIFY_TITLE = "我的培训";
+    public static final String TRAIN_NOTIFY_CONTENT = "%s,培训时间:%tF-%tF";
+
+    public static final String CANCEL_TRAIN_TITLE = "培训取消提醒";
+    public static final String CANCEL_TRAIN_CONTENT = "%s已取消";
+
+    public static final String QUESTIONNAIRE_SURVEY_TITLE="培训需求调查提醒";
+    public static final String QUESTIONNAIRE_SURVEY_CONTENT="%s年%s培训需求,已发布";
+
+    // 培训计划已发布
+    private static final String TRAINING_PLAN_PUBLISH = "y";
+
+    @Override
+    public void endReminderEmail() {
+        // 获取培训计划
+        List<PlanDo> planDoList = planService.list(new LambdaQueryWrapper<PlanDo>().eq(BaseDo::getDeleted, "0")
+                .eq(PlanDo::getPublish, TRAINING_PLAN_PUBLISH));
+        if (planDoList.isEmpty()) {
+            return;
+        }
+        log.info("获取到培训计划:{}", planDoList);
+        // 根据培训计划获取对应的试卷信息
+        List<PlanPaperDo> planPaperList = planPaperService.list(new LambdaQueryWrapper<PlanPaperDo>()
+                .eq(BaseDo::getDeleted, "0")
+                .in(PlanPaperDo::getTrainingplanid, planDoList.stream().map(PlanDo::getId).collect(Collectors.toSet())));
+        log.info("获取到的试卷信息:{}", planPaperList);
+        // 筛选出距离截止日期还有3天的试卷信息
+        List<PlanPaperDo> closePlanPaper = planPaperList
+                .parallelStream()
+                .filter(planPaper -> planPaper.getDeadline() != null && sendMailService.aFewDaysApart(planPaper.getDeadline()) == 3)
+                .collect(Collectors.toList());
+        if (closePlanPaper.isEmpty()) {
+            return;
+        }
+        // 即将截止的试卷Id
+        Set<String> paperId = closePlanPaper.stream().map(PlanPaperDo::getPaperid).collect(Collectors.toSet());
+        // 试卷所属的培训计划
+        Set<String> planId = closePlanPaper.stream().map(PlanPaperDo::getTrainingplanid).collect(Collectors.toSet());
+        /*****获取没有参与考试的培训员工******/
+        List<EmpExamDo> toTestInfoList = empExamService.list(new LambdaQueryWrapper<EmpExamDo>()
+                .eq(BaseDo::getDeleted, "0").eq(EmpExamDo::getExamstatus, "待考试").in(EmpExamDo::getPlanid, planId)
+                .in(EmpExamDo::getPaperid, paperId));
+        if (toTestInfoList.isEmpty()) {
+            return;
+        }
+        // 按照培训计划ID 进行分组
+        Map<String, List<EmpExamDo>> infoMap = toTestInfoList.stream()
+                .collect(Collectors.groupingBy(EmpExamDo::getPlanid, Collectors.toList()));
+        // 发送考试截止提醒邮件
+        infoMap.forEach((k, v) -> {
+            PlanDo planDo = planDoList.stream().filter(info -> info.getId().equals(k)).findFirst().get();
+            log.info("准备发送考试截止提醒邮件");
+            CXCommonUtils.sendNotify(CUT_OFF_TRAIN_TITLE, String.format(CUT_OFF_TRAIN_CONTENT, planDo.getTrainingendtimt()), "",
+                    v.stream().map(EmpExamDo::getEmpid).distinct().filter(StringUtils::isNotBlank).collect(Collectors.toList())
+                    , planDo.getId(), TRAINING);
+        });
+    }
+
+
+    @Override
+    public void trainingPlan() {
+
+    }
+
+    @Override
+    public void questionnaireSurvey() {
+
+    }
+
+    /**
+     * 问卷调查提现
+     *
+     * @param planAndUserIdMap
+     */
+    public void sendQuestionnaireSurveyNotify(List<TrainingDemandSurveyBackupsDo> saveDemandSurveyBackupsDos) {
+        // 获取用户id
+        saveDemandSurveyBackupsDos.forEach((info) -> {
+            List<String> userIds = Arrays.asList(info.getNoparticipatinguserid().split(","));
+            CXCommonUtils.sendNotify(QUESTIONNAIRE_SURVEY_TITLE, String.format(QUESTIONNAIRE_SURVEY_CONTENT, info.getYear(),
+                    info.getName()), "", userIds, info.getId(), TRAININGFORM);
+        });
+    }
+
+
+    /**
+     * 培训计划提醒
+     *
+     * @param planAndUserIdMap
+     */
+    public void sendTrainingPlanNotify(Map<PlanDo, Set<String>> planAndUserIdMap) {
+        // 获取用户id
+        planAndUserIdMap.forEach((k, v) -> {
+            CXCommonUtils.sendNotify(TRAIN_NOTIFY_TITLE, String.format(TRAIN_NOTIFY_CONTENT, k.getCoursename(),
+                    k.getTrainingstarttime(), k.getTrainingendtimt()), "", (List<String>) v, k.getId(), TRAINING);
+        });
+    }
+
+    /**
+     * 培训计划取消提醒
+     *
+     * @param planAndUserIdMap
+     */
+    public void sendTrainingPlanCancelNotify(Map<PlanDo, Set<String>> planAndUserIdMap) {
+        planAndUserIdMap.forEach((k, v) -> {
+            CXCommonUtils.sendNotify(CANCEL_TRAIN_TITLE, String.format(CANCEL_TRAIN_CONTENT, k.getCoursename()), "", (List<String>) v, null, TRAINING);
+        });
+    }
+
+}

+ 4 - 0
rw-training/training-common/src/main/java/com/rongwei/trainingcommon/sys/service/impl/TrainingDemandServiceImpl.java

@@ -71,6 +71,8 @@ public class TrainingDemandServiceImpl implements TrainingDemandService {
     private DemandSurveyContentDao demandSurveyContentDao;
     @Autowired
     private DemandSurveyUserAnswerServiceImpl demandSurveyUserAnswerService;
+    @Autowired
+    private SendNotifyServiceImpl sendNotifyService;
 
     public static final String ERROR_MSG = "问卷调查发布失败";
     /**
@@ -195,6 +197,8 @@ public class TrainingDemandServiceImpl implements TrainingDemandService {
         saveData(saveDemandSurveyBackupsDo, saveDemandSurveyCustomDetailBackupsDos,
                 saveDemandQuestionBackupsDos, saveDemandQuestionOptionBackupsDos,
                 saveDemandSurveyContentDos, saveDemandTempBackupsDo, trainingDemandSurveyDo);
+        // 发送消息提醒
+        sendNotifyService.sendQuestionnaireSurveyNotify(Arrays.asList(saveDemandSurveyBackupsDo));
         return R.ok();
     }
 

+ 1 - 1
rw-training/training-common/src/main/java/com/rongwei/trainingcommon/sys/service/impl/TrainingExamPaperServiceImpl.java

@@ -87,7 +87,7 @@ public class TrainingExamPaperServiceImpl extends ServiceImpl<ExamPaperDao, Exam
         // 校验题目数量是否足够
         String courseThemeName = questionCheck(paperSubjectAssignDos, paperSubjectAutoDos, subjectDoList);
         if (StringUtils.isNotBlank(courseThemeName)) {
-            R.errorWithMsg(courseThemeName + "的题目数不够");
+         return R.errorWithMsg(courseThemeName + "的题目数不够");
         }
         return R.ok();
     }

+ 21 - 7
rw-training/training-server/src/main/java/com/rongwei/training/controller/PlanController.java

@@ -1,22 +1,19 @@
 package com.rongwei.training.controller;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.rongwei.rwadmincommon.system.domain.SysUserDo;
-import com.rongwei.rwadmincommon.system.service.SysConfigFeignService;
 import com.rongwei.rwadmincommon.system.service.SysUserOrgService;
-import com.rongwei.rwadmincommon.system.service.SysUserService;
 import com.rongwei.rwadmincommon.system.vo.SysUserVo;
 import com.rongwei.rwcommon.base.BaseDo;
 import com.rongwei.rwcommon.base.QueryPar;
 import com.rongwei.rwcommon.base.R;
 import com.rongwei.rwcommon.utils.SecurityUtil;
 import com.rongwei.rwcommon.utils.StringUtils;
-import com.rongwei.rwcommon.vo.MailDo;
 import com.rongwei.training.domain.*;
 import com.rongwei.trainingcommon.sys.service.*;
+import com.rongwei.trainingcommon.sys.service.impl.SendNotifyServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -46,9 +43,14 @@ public class PlanController {
     @Autowired
     private PlanPaperService PlanPaperService;
     @Autowired
-    private SysUserService sysUserService;
-    @Autowired
-    private SysConfigFeignService sysConfigFeignService;
+    private SendNotifyServiceImpl sendNotifyService;
+
+    public static final String TRAIN_NOTIFY_TITLE = "我的培训";
+    public static final String TRAIN_NOTIFY_CONTENT = "%s,培训时间:%tF-%tF";
+
+    public static final String CANCEL_TRAIN_TITLE = "培训取消提醒";
+    public static final String CANCEL_TRAIN_CONTENT = "%s已取消";
+
 
     /**
      * 列表
@@ -282,6 +284,7 @@ public class PlanController {
             lambdaUpdatepaperWrapper.in(PlanPaperDo::getTrainingplanid, planIds).set(BaseDo::getDeleted, 1);
             PlanPaperService.update(lambdaUpdatepaperWrapper);
             SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
+            Map<PlanDo, Set<String>> planAndUserIdMap = new HashMap<>();
             // 删除之前发送培训计划取消邮件
             planIds.forEach(planId -> {
                 PlanDo planInfo = planService.getById(planId);
@@ -293,6 +296,7 @@ public class PlanController {
                 if (planUserIdsFromPlan.isEmpty()) {
                     return;
                 }
+                planAndUserIdMap.put(planInfo, planUserIdsFromPlan);
                 // modify at [ 2023-11-29 10:37:38 ] by xh: 取消邮件发送提醒
               /*  // 获取员工信息
                 List<SysUserDo> list = sysUserService.list(new LambdaQueryWrapper<SysUserDo>().eq(BaseDo::getDeleted, "0").in(SysUserDo::getId, planUserIdsFromPlan));
@@ -312,6 +316,9 @@ public class PlanController {
                 sysConfigFeignService.sendTextMail(mail);*/
             });
             planService.removeByIds(planIds);
+            // 培训计划取消提醒
+            sendNotifyService.sendTrainingPlanCancelNotify(planAndUserIdMap);
+
             return R.ok();
         } catch (Exception e) {
             log.error(StringUtils.spliceErrorMsg(e), e.fillInStackTrace());
@@ -326,6 +333,7 @@ public class PlanController {
         }
         // 获取所有的培训计划
         List<PlanDo> list = planService.list(new QueryWrapper<PlanDo>().lambda().in(PlanDo::getId, ids).eq(BaseDo::getDeleted, "0"));
+        Map<PlanDo, Set<String>> planAndUserIdMap = new HashMap<>();
         list.forEach(planDo -> {
             // 参与部门
             String orgIds = planDo.getIncludingorgids();
@@ -349,7 +357,13 @@ public class PlanController {
             }
             planDo.setParticipateempnum(empIdSet.size());
             planService.updateById(planDo);
+            planAndUserIdMap.put(planDo, empIdSet);
         });
+        /**
+         * 发送提醒通知
+         */
+        sendNotifyService.sendTrainingPlanNotify(planAndUserIdMap);
         return R.ok();
     }
+
 }

+ 39 - 0
rw-training/training-server/src/main/java/com/rongwei/training/controller/SendNotifyController.java

@@ -0,0 +1,39 @@
+package com.rongwei.training.controller;
+
+import com.rongwei.trainingcommon.sys.service.impl.SendNotifyServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * SendNotifyController class
+ *
+ * @author XH
+ * @date 2023/12/15
+ */
+@RestController
+@RequestMapping("/notify")
+@Slf4j
+public class SendNotifyController {
+    @Autowired
+    private SendNotifyServiceImpl sendNotifyService;
+
+    @PostMapping("/end/reminder-email")
+    public void endReminderMail() {
+        log.info("开始发送考试截止提醒邮件");
+        sendNotifyService.endReminderEmail();
+    }
+
+    @PostMapping("/training/plan")
+    public void trainingPlan() {
+        log.info("开始发送考试提醒通知");
+        sendNotifyService.trainingPlan();
+    }
+    @PostMapping("/questionnaire/survey")
+    public void questionnaireSurvey() {
+        log.info("开始发送问卷调查通知");
+        sendNotifyService.trainingPlan();
+    }
+}