Prechádzať zdrojové kódy

王子文 专项培养
1) 修复了季度汇报问卷问题修改失败的问题
2) 修复了我的计划反馈问题可能会重复提交的问题
3) 每日8:00定时任务:过滤出日期为7天前的会议

wangggziwen 3 rokov pred
rodič
commit
df31c05edd

+ 79 - 0
master/src/main/java/com/ruoyi/common/thread/Trainning/MeetingFeedbackMailThread.java

@@ -0,0 +1,79 @@
+package com.ruoyi.common.thread.Trainning;
+
+import com.ruoyi.common.sendEmail.IMailService;
+
+import java.util.Date;
+
+/**
+ * @author Wang Zi Wen
+ * @email wangggziwen@163.com
+ * @date 2022/05/24 15:42:38
+ */
+public class MeetingFeedbackMailThread implements Runnable {
+
+    private IMailService mailService;
+    private String email;
+    private String username;
+    private String usernameEN;
+    private String feedbackYear;
+    private String feedbackSeason;
+
+    public MeetingFeedbackMailThread() {
+    }
+
+    public MeetingFeedbackMailThread(IMailService mailService, String email, String username, String usernameEN, String feedbackYear, String feedbackSeason) {
+        this.mailService = mailService;
+        this.email = email;
+        this.username = username;
+        this.usernameEN = usernameEN;
+        this.feedbackYear = feedbackYear;
+        this.feedbackSeason = feedbackSeason;
+    }
+
+    @Override
+    public void run() {
+        this.sendMail();
+    }
+
+    private void sendMail() {
+//        String jumpUrl = "/training/spec/myplan";
+//        //写html开始内容
+//        String start = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title></title></head><body><div style=\"background-color:#ECECEC; padding: 35px;\">" +
+//                "<table cellpadding=\"0\" align=\"center\"" +
+//                "style=\"width: 600px; margin: 0px auto; text-align: left; position: relative; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-size: 14px; font-family:微软雅黑, 黑体; line-height: 1.5; box-shadow: rgb(153, 153, 153) 0px 0px 5px; border-collapse: collapse; background-position: initial initial; background-repeat: initial initial;background:#fff;\">" +
+//                "<tbody><tr><th valign=\"middle\" style=\"height: 25px; line-height: 25px; padding: 15px 35px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #42a3d3; background-color: #49bcff; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;\">" +
+//                "<font face=\"微软雅黑\" size=\"5\" style=\"color: rgb(255, 255, 255); \">CPMS管理系统 </font><font face=\"微软雅黑\" size=\"3\" style=\"color: rgb(255, 255, 255); \">CPMS System</font></th></tr>";
+//        //表html中间内容
+//        String prime = "";
+//        String center = "<tr><td><div style=\"padding:25px 35px 40px; background-color:#fff;\"><h2 style=\"margin: 5px 0px; \">" +
+//                "<font color=\"#333333\" style=\"line-height: 20px; \"><font style=\"line-height: 22px; \" size=\"4\">" +
+//                "亲爱的call username</font><br><font style=\"line-height: 22px; \" size=\"4\">" +
+//                "Dear usernameEN</font></font></h2>" +
+//                "<p>您的培训计划有新状态:<br>" +
+//                "You have a new to-do task:<br>" +
+//                "培训内容:<b>plantName</b><br>" +
+//                "学习状态:<b>studyState</b><br>" +
+//                "学员:<b>staffName</b><br>" +
+//                "请登录<a href=\"https://cpms.basf-ypc.net.cn/cpms/index.html#jumpUrl\">CPMS管理系统</a>查看。<br>" +
+//                "Please log in the <a href=\"https://cpms.basf-ypc.net.cn/cpms/index.html#jumpUrl\">CPMS</a> to handle it.</p>" +
+//                "<p align=\"right\">date</p>" +
+//                "<div style=\"width:700px;margin:0 auto;\">" +
+//                "<div style=\"padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;\">" +
+//                "<p>此为系统邮件,请勿回复<br>This e-Mail is an automatic reminder sent by CPMS, please do not reply</p>" +
+//                "</div></div></div></td></tr>";
+//        String one = center.replaceFirst("username", username);
+//        String two = one.replaceFirst("usernameEN", usernameEN);
+//        String three = two.replaceFirst("plantName", tStPlan.getPlantName());
+//        String four = three.replaceFirst("call",call);
+//        String five = four.replaceFirst("studyState",studyState);
+//        String seven = five.replaceFirst("staffName", tStPlan.getStaffName());
+//        String result = seven.replaceFirst("date", String.valueOf(new Date())).replaceFirst("jumpUrl",jumpUrl).replaceFirst("jumpUrl",jumpUrl);
+//        prime = prime + result;
+//        //写html结尾内容
+//        String end = "</tbody></table></div></body></html>";
+//        //拼接html
+//        String html = start + prime + end;
+//        mailService.sendHtmlMail(email, "CPMS:您的培训计划"+ studyState +" (" + tStPlan.getPlantName() + ")", html);
+    }
+
+}

+ 6 - 2
master/src/main/java/com/ruoyi/project/training/spec/controller/TStFeedbackController.java

@@ -10,6 +10,8 @@ import com.ruoyi.project.training.spec.domain.*;
 import com.ruoyi.project.training.spec.service.ITStPlanService;
 import com.ruoyi.project.training.spec.service.ITStQuestionAnswerService;
 import com.ruoyi.project.training.spec.service.ITStSuccessorScoreService;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -27,6 +29,7 @@ import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.web.page.TableDataInfo;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 /**
  * 专项培训反馈Controller
@@ -36,6 +39,7 @@ import com.ruoyi.framework.web.page.TableDataInfo;
  */
 @RestController
 @RequestMapping("/spec/feedback")
+@EnableScheduling
 public class TStFeedbackController extends BaseController
 {
     @Autowired
@@ -53,7 +57,7 @@ public class TStFeedbackController extends BaseController
     @Autowired
     private ITStSuccessorScoreService stSuccessorScoreService;
 
-    /**
+     /**
      * 保存季度反馈内容
      * @param feedbackSeasonalVO 季度反馈数据传输对象
      * @return
@@ -78,11 +82,11 @@ public class TStFeedbackController extends BaseController
             TStQuestionAnswer answer = new TStQuestionAnswer();
             answer.setFeedbackId(feedbackId);
             answer.setQuestionId(tStQuestionAnswerArray[i].getQuestionId());
-            answer.setAnswer(tStQuestionAnswerArray[i].getAnswer());
             // 根据问题和答案获取TStQuestionAnswer对象
             TStQuestionAnswer result = tStQuestionAnswerService.selectTStQuestionAnswer(answer);
             // TStQuestionAnswer表中不存在记录
             if (result == null) {
+                answer.setAnswer(tStQuestionAnswerArray[i].getAnswer());
                 // 新增TStQuestionAnswer对象
                 tStQuestionAnswerService.insertTStQuestionAnswer(answer);
             } else {

+ 91 - 0
master/src/main/java/com/ruoyi/project/training/spec/scheduler/TStFeedbackScheduler.java

@@ -0,0 +1,91 @@
+package com.ruoyi.project.training.spec.scheduler;
+
+import com.github.stuxuhai.jpinyin.PinyinException;
+import com.github.stuxuhai.jpinyin.PinyinFormat;
+import com.github.stuxuhai.jpinyin.PinyinHelper;
+import com.ruoyi.common.sendEmail.IMailService;
+import com.ruoyi.common.thread.Trainning.MeetingFeedbackMailThread;
+import com.ruoyi.project.system.domain.SysUser;
+import com.ruoyi.project.system.service.ISysUserService;
+import com.ruoyi.project.training.spec.domain.TStFeedback;
+import com.ruoyi.project.training.spec.service.ITStFeedbackService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 专项培训反馈定时任务
+ *
+ * @author Wang Zi Wen
+ * @email wangggziwen@163.com
+ * @date 2022/05/24 13:52:00
+ */
+@Component
+@EnableScheduling
+public class TStFeedbackScheduler {
+
+    @Autowired
+    private ITStFeedbackService tStFeedbackService;
+
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Autowired
+    private IMailService mailService;
+
+    /**
+     * 会议时间一周后给学员发送邮件
+     * 每日8:00触发定时任务
+     * 扫描TStFeedback表,获取所有会议日期 = 当前日期 - 7 的记录,给学员发送邮件
+     */
+    // 生产环境触发条件:每日8:00
+//    @Scheduled(cron = "0 0 8 * * ?")
+    // 测试环境触发条件:每秒
+//    @Scheduled(cron = "0 * * * * ?")
+    private void mailSuccessorAfterMeeting() throws PinyinException {
+        // 获取所有反馈记录
+        List<TStFeedback> tStFeedbackList = tStFeedbackService.selectTStFeedbackList(null);
+
+        // 过滤出所有会议日期不为空的反馈记录
+        tStFeedbackList = tStFeedbackList.stream().filter(tStFeedback -> tStFeedback.getMeetingDate()!=null).collect(Collectors.toList());
+
+        // 过滤出会议日期为七日前的反馈记录
+        tStFeedbackList = tStFeedbackList.stream().filter(tStFeedback -> {
+            // 当前日期毫秒数
+            Long dateMillis = new Date().getTime();
+            // 会议日期毫秒数
+            Long meetingDateMillis = tStFeedback.getMeetingDate().getTime();
+            // 是否发送邮件
+            boolean sendMail = false;
+            // 当前日期和会议日期毫秒差
+            long diff = dateMillis - meetingDateMillis;
+            long minMillis = 3600 * 1000 * 24 * 7;
+            long maxMillis = 3600 * 1000 * 24 * 8;
+            // 7<=当前日期和会议日期毫秒差<8天
+            if (diff>=minMillis && diff<maxMillis) {
+                sendMail = true;
+            }
+            return sendMail;
+        }).collect(Collectors.toList());
+
+        // 发送邮件
+        for (TStFeedback feedback : tStFeedbackList) {
+            SysUser successor = sysUserService.selectUserByStaffId(feedback.getSuccessorId());
+            String email = successor.getEmail();
+            String username = successor.getNickName();
+            String usernameEN = PinyinHelper.convertToPinyinString(username, " ", PinyinFormat.WITHOUT_TONE);
+            String feedbackYear = feedback.getFeedbackYear();
+            String feedbackSeason = feedback.getFeedbackSeason();
+            MeetingFeedbackMailThread meetingFeedbackMailThread = new MeetingFeedbackMailThread(mailService, email, username, usernameEN, feedbackYear, feedbackSeason);
+            Thread thread = new Thread(meetingFeedbackMailThread);
+            thread.start();
+        }
+    }
+
+}
+

+ 7 - 2
ui/src/views/training/spec/myplan/index.vue

@@ -234,8 +234,8 @@
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="handleSaveFeedback()" v-if="feedbackDialog.studyState == 0 || feedbackDialog.studyState == 3">{{ $t('保 存') }}</el-button>
-        <el-button @click="handleSubmitFeedback()" v-if="feedbackDialog.studyState == 0 || feedbackDialog.studyState == 3">{{ $t('提 交') }}</el-button>
+        <el-button :disabled="isButtonDisabled" @click="handleSaveFeedback()" v-if="feedbackDialog.studyState == 0 || feedbackDialog.studyState == 3">{{ $t('保 存') }}</el-button>
+        <el-button :disabled="isButtonDisabled" @click="handleSubmitFeedback()" v-if="feedbackDialog.studyState == 0 || feedbackDialog.studyState == 3">{{ $t('提 交') }}</el-button>
         <el-button @click="feedbackDialog.open = false">{{ $t('返 回') }}</el-button>
       </div>
     </el-dialog>
@@ -257,6 +257,8 @@ export default {
   components: { Treeselect },
   data() {
     return {
+      // 按钮是否禁用
+      isButtonDisabled: false,
       // 报告附件参数
       docFeedback: {  // 反馈附件
         file: "",
@@ -430,6 +432,7 @@ export default {
     },
     /** 反馈处理 */
     handleFeedback(row) {
+      this.isButtonDisabled = false;
       // 加载反馈附件
       this.docFeedback.id = row.id;
       this.docFeedback.queryParams.pId = row.id
@@ -486,6 +489,7 @@ export default {
     },
     /** 反馈对话框保存处理 */
     handleSaveFeedback() {
+      this.isButtonDisabled = true;
       let feedback1 = {};
       feedback1.planId = this.feedbackDialog.planId;
       feedback1.questionId = 1;
@@ -532,6 +536,7 @@ export default {
     },
     /** 反馈对话框提交处理 */
     handleSubmitFeedback() {
+      this.isButtonDisabled = true;
       let feedback1 = {};
       feedback1.planId = this.feedbackDialog.planId;
       feedback1.questionId = 1;