浏览代码

工作报告定时发送

fuyuhchuan 9 月之前
父节点
当前提交
e28f35f9ad

+ 13 - 0
service-iot/service-iot-api/src/main/java/com/usky/iot/RemotePmService.java

@@ -0,0 +1,13 @@
+package com.usky.iot;
+
+
+import com.usky.iot.factory.RemotePmFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@FeignClient(contextId = "remoteIotService", value = "service-iot" , fallbackFactory = RemotePmFactory.class)
+public interface RemotePmService {
+
+    @GetMapping("/executeTimedSending")
+    void executeTimedSending();
+}

+ 34 - 0
service-iot/service-iot-api/src/main/java/com/usky/iot/factory/RemotePmFactory.java

@@ -0,0 +1,34 @@
+package com.usky.iot.factory;
+
+import com.usky.common.core.exception.FeignBadRequestException;
+import com.usky.iot.RemotePmService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * 用户服务降级处理
+ *
+ * @author ruoyi
+ */
+@Component
+public class RemotePmFactory implements FallbackFactory<RemotePmService>
+{
+    private static final Logger log = LoggerFactory.getLogger(RemotePmFactory.class);
+
+    @Override
+    public RemotePmService create(Throwable throwable)
+    {
+        log.error("用户服务调用失败:{}", throwable.getMessage());
+        return new RemotePmService()
+        {
+            @Override
+            public void executeTimedSending() {
+                throw new FeignBadRequestException(500,"公告报告定时发送异常"+throwable.getMessage());
+            }
+
+        };
+    }
+}

+ 32 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/api/PmTimedSendingApi.java

@@ -0,0 +1,32 @@
+package com.usky.iot.controller.api;
+
+import com.usky.iot.RemotePmService;
+import com.usky.iot.service.PmWorkReportService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+
+/**
+ * <p>
+ *  数据统一查询 前端控制器
+ * </p>
+ *
+ */
+@RestController
+public class PmTimedSendingApi implements RemotePmService {
+
+    @Autowired
+    private PmWorkReportService pmWorkReportService;
+
+    @Override
+    public void executeTimedSending() {
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+        String formattedDateTime = now.format(formatter);
+        LocalDateTime parsedDateTime = LocalDateTime.parse(formattedDateTime, formatter);
+        pmWorkReportService.timedSending(parsedDateTime);
+    }
+}

+ 2 - 1
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmWorkReportController.java

@@ -1,6 +1,7 @@
 package com.usky.iot.controller.web;
 
 
+import com.aliyuncs.exceptions.ClientException;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.iot.domain.PmWorkReport;
 import com.usky.iot.service.PmProjectService;
@@ -49,7 +50,7 @@ public class PmWorkReportController {
      * @param
      */
     @PostMapping("/add")
-    public void add(@RequestBody PmWorkReport pmWorkReport) {
+    public void add(@RequestBody PmWorkReport pmWorkReport)  throws ClientException {
         pmWorkReportService.addReport(pmWorkReport);
     }
 

+ 16 - 1
service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmWorkReport.java

@@ -112,7 +112,22 @@ public class PmWorkReport implements Serializable {
     private Integer readFlag;
 
     /**
-     * 是否发送钉钉 默认:0,否;1:是
+     * 是否发送钉钉 (默认:0,否;1:是)
      */
     private Integer sendDingTalk;
+
+    /**
+     * 定时时间
+     */
+    private LocalDateTime timingTime;
+
+    /**
+     * 报告状态(默认1,0:保存状态;1:发送状态)
+     */
+    private Integer reportStatus;
+
+    /**
+     * 是否定时(默认0:否,1:是)
+     */
+    private Integer isRegularlySend;
 }

+ 5 - 4
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmWorkReportService.java

@@ -1,9 +1,11 @@
 package com.usky.iot.service;
 
+import com.aliyuncs.exceptions.ClientException;
 import com.usky.iot.domain.PmWorkContent;
 import com.usky.iot.domain.PmWorkReport;
 import com.usky.common.mybatis.core.CrudService;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 
@@ -30,7 +32,7 @@ public interface PmWorkReportService extends CrudService<PmWorkReport> {
      * 新增、编辑工作报告
      * @param pmWorkReport 工作报告
      */
-    void addReport(PmWorkReport pmWorkReport);
+    void addReport(PmWorkReport pmWorkReport)  throws ClientException;
 
 
     /**
@@ -40,8 +42,7 @@ public interface PmWorkReportService extends CrudService<PmWorkReport> {
     List<Map<String, Object>> countTime();
 
     /**
-     * 同步钉钉
-     * @param workReport 工作报告
+     * 定时发送
      */
-    void sendDingTalkDailyReport(PmWorkReport workReport, List<PmWorkContent> workContents);
+    void timedSending(LocalDateTime time);
 }

+ 313 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/config/DingTalkAndMessage.java

@@ -0,0 +1,313 @@
+package com.usky.iot.service.config;
+
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
+import com.aliyun.tea.TeaException;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.DingTalkClient;
+import com.dingtalk.api.request.OapiReportCreateRequest;
+import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
+import com.dingtalk.api.response.OapiReportCreateResponse;
+import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.iot.constant.dingTalkConstant;
+import com.usky.iot.domain.MceMbuser;
+import com.usky.iot.domain.PmReceive;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.mapper.MceMbuserMapper;
+import com.usky.iot.mapper.PmReceiveMapper;
+import com.usky.iot.mapper.PmWorkReportMapper;
+import com.usky.iot.mapper.SysUserMapper;
+import com.usky.iot.service.PmWorkContentService;
+import com.usky.system.RemoteMceService;
+import com.usky.system.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Async;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @description:TODO
+ * @author: fu
+ * @create: 2024-07-30 10:32
+ */
+@Slf4j
+@Configuration
+public class DingTalkAndMessage {
+
+    private static final String INFO_TITLE = "报告提醒";
+    private static final String INFO_CONTENT = "的报告";
+    private static final int INFO_TYPE = 5;
+
+    @Autowired
+    private RemoteMceService remoteMceService;
+
+    @Autowired
+    private PmWorkContentService pmWorkContentService;
+
+    @Autowired
+    private PmReceiveMapper pmReceiveMapper;
+
+    @Autowired
+    private MceMbuserMapper mceMbuserMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private PmWorkReportMapper pmWorkReportMapper;
+
+    /**
+     * 指定请求
+     *
+     * @return
+     * @throws Exception
+     */
+    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
+        config.protocol = "https";
+        config.regionId = "central";
+        config.method = "POST";
+        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
+    }
+
+    /**
+     * 获取钉钉企业内部AccessToken
+     *
+     * @return
+     * @throws Exception
+     */
+    public String getDingTalkToken() {
+        GetAccessTokenResponse responseBody = new GetAccessTokenResponse();
+        com.aliyun.dingtalkoauth2_1_0.Client client = null;
+        try {
+            client = createClient();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
+                .setAppKey(dingTalkConstant.DING_TALK_CLIENT_ID)
+                .setAppSecret(dingTalkConstant.DING_TALK_CLIENT_SECRET);
+        try {
+            responseBody = client.getAccessToken(getAccessTokenRequest);
+        } catch (TeaException err) {
+            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                // err 中含有 code 和 message 属性,可帮助开发定位问题
+            }
+        } catch (Exception _err) {
+            TeaException err = new TeaException(_err.getMessage(), _err);
+            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                // err 中含有 code 和 message 属性,可帮助开发定位问题
+            }
+        }
+        return responseBody.getBody().accessToken;
+    }
+
+    /**
+     * 获取钉钉userId
+     *
+     * @param userId 平台userid
+     * @return
+     */
+    public String getDingTalkUserId(Long userId) {
+        String dingTalkId = "";
+        LambdaQueryWrapper<MceMbuser> dingTalkQuery = Wrappers.lambdaQuery();
+        dingTalkQuery.select(MceMbuser::getDingTalkId, MceMbuser::getUserId)
+                .eq(MceMbuser::getUserId, userId);
+        MceMbuser mceMbuser = mceMbuserMapper.selectOne(dingTalkQuery);
+        if (mceMbuser != null) {
+            String dingId = mceMbuser.getDingTalkId();
+            if (StringUtils.isNotBlank(dingId)) {
+                return mceMbuser.getDingTalkId();
+            }
+        }
+        LambdaQueryWrapper<SysUser> phoneQuery = Wrappers.lambdaQuery();
+        phoneQuery.select(SysUser::getPhonenumber, SysUser::getUserName)
+                .eq(SysUser::getUserId, userId);
+        SysUser user = sysUserMapper.selectOne(phoneQuery);
+        String mobile = user.getPhonenumber();
+        try {
+            String accessToken = getDingTalkToken();
+            DingTalkClient client = new DefaultDingTalkClient(dingTalkConstant.DING_TALK_USERID_URL);
+            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
+            req.setMobile(mobile);
+            OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
+            ObjectMapper objectMapper = new ObjectMapper();
+            JsonNode rootNode = objectMapper.readTree(rsp.getBody());
+            JsonNode resultNode = rootNode.get("result");
+            dingTalkId = resultNode.get("userid").asText();
+        } catch (Exception e) {
+            log.error("获取钉钉用户ID失败", e);
+        }
+        if (mceMbuser != null) {
+            mceMbuser.setDingTalkId(dingTalkId);
+            mceMbuser.setUpdateBy(SecurityUtils.getUsername());
+            mceMbuser.setUpdateTime(LocalDateTime.now());
+            mceMbuserMapper.update(mceMbuser, dingTalkQuery);
+        } else {
+            MceMbuser mbuser = new MceMbuser();
+            mbuser.setDingTalkId(dingTalkId);
+            mbuser.setPhone(mobile);
+            mbuser.setUserId(userId);
+            mbuser.setCreateBy(user.getUserName());
+            mbuser.setCreateTime(LocalDateTime.now());
+            mceMbuserMapper.insert(mbuser);
+        }
+        return dingTalkId;
+    }
+
+    @Async("asyncServiceExecutor")//异步发送
+    public void sendDingTalkDailyReport(PmWorkReport workReport, List<PmWorkContent> workContents) {
+        String ccToStr = workReport.getCcTo();
+        String[] items = ccToStr.split(",");
+        try {
+            List<Long> userIds = new ArrayList<>();
+            //Thread.sleep(30000);
+            for (String item : items) {
+                long number = Long.parseLong(item.trim());
+                userIds.add(number);
+            }
+            List<String> ccTo = new ArrayList<>();
+            for (Long userId : userIds) {
+                String dingTalkUserId = getDingTalkUserId(userId);
+                ccTo.add(dingTalkUserId);
+            }
+            String reportCoordinateWork = workReport.getCoordinateWork();
+            String reportTomorrowPlan = workReport.getTomorrowPlan();
+            String coordinateWork1 = "-";
+            String tomorrowPlan1 = "-";
+            if (reportCoordinateWork != null && reportCoordinateWork != "") {
+                coordinateWork1 = reportCoordinateWork;
+            }
+            if (reportTomorrowPlan != null && reportTomorrowPlan != "") {
+                tomorrowPlan1 = reportTomorrowPlan;
+            }
+
+            StringBuilder contentBuilder = new StringBuilder();
+            for (PmWorkContent content : workContents) {
+                String projectName = content.getProjectName();
+                BigDecimal workTime = content.getWorkTime();
+                String workContent = content.getWorkContent();
+                StringBuilder markdown = new StringBuilder();
+                markdown.append("#### ").append(projectName).append(" ").append(workTime).append("h\n\n");
+                markdown.append("<span style=\"font-size: 18px;\">").append(workContent).append("\n").append("</span>");
+                contentBuilder.append(markdown);
+            }
+            String completedWork = contentBuilder.toString();
+            DingTalkClient client = new DefaultDingTalkClient(dingTalkConstant.DING_TALK_CREATE_DAILY_REPORT_URL);
+            OapiReportCreateRequest req = new OapiReportCreateRequest();
+            OapiReportCreateRequest.OapiCreateReportParam obj1 = new OapiReportCreateRequest.OapiCreateReportParam();
+            List<OapiReportCreateRequest.OapiReportContentVo> list3 = new ArrayList<>();
+            OapiReportCreateRequest.OapiReportContentVo completedWorkD = new OapiReportCreateRequest.OapiReportContentVo();
+            completedWorkD.setSort(0L);
+            completedWorkD.setType(1L);
+            completedWorkD.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
+            completedWorkD.setContent(completedWork);
+            completedWorkD.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_COMPLETED_WORK);
+            list3.add(completedWorkD);
+            OapiReportCreateRequest.OapiReportContentVo tomorrowPlan = new OapiReportCreateRequest.OapiReportContentVo();
+            tomorrowPlan.setSort(1L);
+            tomorrowPlan.setType(1L);
+            tomorrowPlan.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
+            tomorrowPlan.setContent(tomorrowPlan1);
+            tomorrowPlan.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_TOMORROW_PLAN);
+            list3.add(tomorrowPlan);
+            OapiReportCreateRequest.OapiReportContentVo coordinateWork = new OapiReportCreateRequest.OapiReportContentVo();
+            coordinateWork.setSort(2L);
+            coordinateWork.setType(1L);
+            coordinateWork.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
+            coordinateWork.setContent(coordinateWork1);
+            coordinateWork.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_COORDINATE_WORK);
+            list3.add(coordinateWork);
+            obj1.setContents(list3);
+            obj1.setToUserids(ccTo);
+            obj1.setTemplateId(dingTalkConstant.DING_TALK_DAILY_REPORT_TEMPLATE_ID);
+            obj1.setToChat(dingTalkConstant.DING_TALK_DAILY_REPORT_TO_CHAT);
+            obj1.setDdFrom(dingTalkConstant.DING_TALK_CORP_ID);
+            obj1.setUserid(getDingTalkUserId(SecurityUtils.getUserId()));
+            //obj1.setToCids(dingTalkConstant.DING_TALK_DAILY_REPORT_TO_CIDS);//发送到群,群id
+            req.setCreateReportParam(obj1);
+            OapiReportCreateResponse rsp = client.execute(req, getDingTalkToken());
+            if (rsp.isSuccess()) {
+                log.info("钉钉报告发送成功");
+                workReport.setReportStatus(1);
+                pmWorkReportMapper.updateById(workReport);
+            } else {
+                log.error("钉钉报告发送失败: " + rsp.getErrmsg());
+            }
+        } catch (Exception e) {
+            log.error("钉钉报告发送消息时发生异常", e);
+        }
+    }
+
+
+    @Async("asyncServiceExecutor")
+    public void sendAsyncMessage(PmWorkReport newReport) {
+        List<Long> userId = new ArrayList<>();
+        if (!newReport.getCcTo().isEmpty()) {
+            userId = Optional.ofNullable(newReport.getCcTo())
+                    .map(ccTo -> Arrays.stream(ccTo.split(","))
+                            .map(Long::parseLong)
+                            .collect(Collectors.toList()))
+                    .orElse(Collections.emptyList());
+        }
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("infoTitle", INFO_TITLE);
+        jsonObject.put("infoContent", SecurityUtils.getLoginUser().getSysUser().getNickName() + INFO_CONTENT);
+        jsonObject.put("infoType", INFO_TYPE);
+        jsonObject.put("id", newReport.getId());
+        jsonObject.put("infoTypeName", INFO_TITLE);
+        if (userId != null && !userId.isEmpty()) {
+            jsonObject.put("userIds", userId);
+        }
+        try {
+            // 推送消息中心
+            ApiResult<Void> voidApiResult = remoteMceService.addMce(jsonObject.toString());
+
+            if (voidApiResult.isSuccess()) {
+                log.info("报告消息发送成功!");
+                //存入消息接收表
+                receiveMessages(userId, newReport.getId());
+            } else {
+                log.error("报告消息发送失败!");
+            }
+        } catch (Exception e) {
+            log.error("报告发送消息时发生异常", e);
+        }
+    }
+
+    private void receiveMessages(List<Long> ids, Integer reportId) {
+        List<SysUser> users = pmWorkContentService.nickNames(ids);
+        if (ids.size() > 0) {
+            for (Long id : ids) {
+                PmReceive pmReceive = new PmReceive();
+                pmReceive.setReceiverId(id);
+                pmReceive.setReportId(reportId);
+                pmReceive.setTenantId(SecurityUtils.getTenantId());
+                pmReceive.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
+                pmReceive.setCreateBy(SecurityUtils.getUsername());
+                pmReceive.setCreateTime(LocalDateTime.now());
+                for (SysUser user : users) {
+                    if (user.getUserId().equals(id)) {
+                        pmReceive.setReceiverName(user.getUserName());
+                    }
+                }
+                pmReceive.setReadFlag(0);
+                pmReceiveMapper.insert(pmReceive);
+            }
+        }
+    }
+}
+

+ 81 - 289
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkReportServiceImpl.java

@@ -1,34 +1,20 @@
 package com.usky.iot.service.impl;
 
-import com.alibaba.fastjson.JSONObject;
-import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
-import com.aliyun.tea.TeaException;
+import com.aliyuncs.exceptions.ClientException;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.dingtalk.api.DefaultDingTalkClient;
-import com.dingtalk.api.DingTalkClient;
-import com.dingtalk.api.request.OapiReportCreateRequest;
-import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
-import com.dingtalk.api.response.OapiReportCreateResponse;
-import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessException;
 import com.usky.common.security.utils.SecurityUtils;
-import com.usky.iot.constant.dingTalkConstant;
 import com.usky.iot.domain.*;
 import com.usky.iot.mapper.*;
 import com.usky.iot.service.PmProjectService;
 import com.usky.iot.service.PmWorkContentService;
 import com.usky.iot.service.PmWorkReportService;
 import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.iot.service.config.DingTalkAndMessage;
 import com.usky.iot.service.vo.PmProjectWorkTimeVo;
-import com.usky.system.RemoteMceService;
-import com.usky.system.domain.SysUser;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -37,9 +23,9 @@ import java.math.RoundingMode;
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
-import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 
@@ -55,9 +41,6 @@ import java.util.stream.Collectors;
 @Service
 public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMapper, PmWorkReport> implements PmWorkReportService {
 
-    private static final String INFO_TITLE = "报告提醒";
-    private static final String INFO_CONTENT = "的报告";
-    private static final int INFO_TYPE = 5;
 
     @Autowired
     private PmWorkContentMapper pmWorkContentMapper;
@@ -72,16 +55,7 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
     private PmWorkContentService pmWorkContentService;
 
     @Autowired
-    private RemoteMceService remoteMceService;
-
-    @Autowired
-    private PmReceiveMapper pmReceiveMapper;
-
-    @Autowired
-    private MceMbuserMapper mceMbuserMapper;
-
-    @Autowired
-    private SysUserMapper sysUserMapper;
+    private DingTalkAndMessage dingTalkAndMessage;
 
     /**
      * 获取时间内工作报告
@@ -218,13 +192,17 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
      */
     @Transactional
     @Override
-    public void addReport(PmWorkReport pmWorkReport) {
+    public void addReport(PmWorkReport pmWorkReport) throws ClientException {
         Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
         String userName = SecurityUtils.getUsername();
         Long userId = SecurityUtils.getUserId();
         Integer tenantId = SecurityUtils.getTenantId();
         LocalDateTime dateTime = LocalDateTime.now();
         BigDecimal totalWorkTime = BigDecimal.ZERO; //计算总工时
+        int minutesToAdd = 5;
+        LocalDateTime timingTime = pmWorkReport.getTimingTime();
+        LocalDateTime currentTimePlusMinutes = dateTime.plusMinutes(minutesToAdd);
+
         if (pmWorkReport.getWorkContents() == null) {
             throw new BusinessException("报告内容不能为空,请检查!");
         }
@@ -266,6 +244,15 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
             newReport.setTenantId(tenantId);
             newReport.setTotalHours(totalWorkTime);
             newReport.setSendDingTalk(pmWorkReport.getSendDingTalk());
+            if (pmWorkReport.getIsRegularlySend() != 0) {
+                if (timingTime != null && timingTime.isBefore(currentTimePlusMinutes)) {
+                    newReport.setIsRegularlySend(pmWorkReport.getIsRegularlySend());
+                    newReport.setTimingTime(timingTime);
+                    newReport.setReportStatus(0);
+                } else {
+                    throw new BusinessException("定时时间需大于五分钟!");
+                }
+            }
             try {
                 pmWorkReportMapper.insert(newReport);
 
@@ -302,27 +289,17 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
                 newContent.setTenantId(tenantId);
                 pmWorkContentMapper.insert(newContent);
             }
-            //推送消息中心
-            List<Long> ids = new ArrayList<>();
-            if (!newReport.getCcTo().isEmpty()) {
-                ids = Optional.ofNullable(newReport.getCcTo())
-                        .map(ccTo -> Arrays.stream(ccTo.split(","))
-                                .map(Long::parseLong)
-                                .collect(Collectors.toList()))
-                        .orElse(Collections.emptyList());
-            }
-            //sendAsyncMessage(newReport, ids);
-            List<Long> finalIds = ids;
-            CompletableFuture.runAsync(() -> {sendAsyncMessage(newReport, finalIds);});
-            //存入消息接收表
-            receiveMessages(ids, newReport.getId());
-            //是否同步钉钉
-            if (pmWorkReport.getSendDingTalk() == 1) {
-                //sendDingTalkDailyReport(pmWorkReport);
-                CompletableFuture.runAsync(() -> {
-                    sendDingTalkDailyReport(newReport, pmWorkReport.getWorkContents());
-                });
+            //非定时发送
+            if (timingTime == null) {
+                //推送消息中心
+                dingTalkAndMessage.sendAsyncMessage(newReport);
+
+                //是否同步钉钉
+                if (pmWorkReport.getSendDingTalk() == 1) {
+                    dingTalkAndMessage.sendDingTalkDailyReport(newReport, pmWorkReport.getWorkContents());
+                }
             }
+
         } else if (repeat.size() > 0) {
             PmWorkReport rp = new PmWorkReport();
             rp.setId(pmWorkReport.getId());
@@ -340,72 +317,34 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
             rp.setUpdateBy(userName);
             rp.setUpdateTime(dateTime);
             rp.setTotalHours(totalWorkTime);
-            pmWorkReportMapper.updateById(rp);
-            LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
-            queryWrapper.select(PmWorkContent::getReportId, PmWorkContent::getSubmitterId, PmWorkContent::getCreateBy, PmWorkContent::getCreateTime, PmWorkContent::getDeptId, PmWorkContent::getTenantId)
-                    .eq(PmWorkContent::getReportId, pmWorkReport.getId())
-                    .last("LIMIT 1");
-            PmWorkContent f = pmWorkContentMapper.selectOne(queryWrapper);
-            pmWorkContentService.deleteContent(pmWorkReport.getId());
-            List<PmWorkContent> contents = pmWorkReport.getWorkContents();
-            for (PmWorkContent e : contents) {
-                e.setReportId(f.getReportId());
-                e.setUpdateBy(userName);
-                e.setUpdateTime(dateTime);
-                e.setSubmitterId(f.getSubmitterId());
-                e.setCreateTime(f.getCreateTime());
-                e.setCreateBy(f.getCreateBy());
-                e.setDeptId(f.getDeptId());
-                e.setTenantId(f.getTenantId());
-                pmWorkContentMapper.insert(e);
-            }
-        }
-    }
-
-    private void receiveMessages(List<Long> ids, Integer reportId) {
-        List<SysUser> users = pmWorkContentService.nickNames(ids);
-        if (ids.size() > 0) {
-            for (Long id : ids) {
-                PmReceive pmReceive = new PmReceive();
-                pmReceive.setReceiverId(id);
-                pmReceive.setReportId(reportId);
-                pmReceive.setTenantId(SecurityUtils.getTenantId());
-                pmReceive.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
-                pmReceive.setCreateBy(SecurityUtils.getUsername());
-                pmReceive.setCreateTime(LocalDateTime.now());
-                for (SysUser user : users) {
-                    if (user.getUserId().equals(id)) {
-                        pmReceive.setReceiverName(user.getUserName());
-                    }
+            if (pmWorkReport.getIsRegularlySend() != 0) {
+                if (timingTime != null && timingTime.isBefore(currentTimePlusMinutes)) {
+                    rp.setIsRegularlySend(pmWorkReport.getIsRegularlySend());
+                    rp.setTimingTime(timingTime);
+                    rp.setReportStatus(0);
+                } else {
+                    throw new BusinessException("定时时间需大于五分钟!");
+                }
+                pmWorkReportMapper.updateById(rp);
+                LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
+                queryWrapper.select(PmWorkContent::getReportId, PmWorkContent::getSubmitterId, PmWorkContent::getCreateBy, PmWorkContent::getCreateTime, PmWorkContent::getDeptId, PmWorkContent::getTenantId)
+                        .eq(PmWorkContent::getReportId, pmWorkReport.getId())
+                        .last("LIMIT 1");
+                PmWorkContent f = pmWorkContentMapper.selectOne(queryWrapper);
+                pmWorkContentService.deleteContent(pmWorkReport.getId());
+                List<PmWorkContent> contents = pmWorkReport.getWorkContents();
+                for (PmWorkContent e : contents) {
+                    e.setReportId(f.getReportId());
+                    e.setUpdateBy(userName);
+                    e.setUpdateTime(dateTime);
+                    e.setSubmitterId(f.getSubmitterId());
+                    e.setCreateTime(f.getCreateTime());
+                    e.setCreateBy(f.getCreateBy());
+                    e.setDeptId(f.getDeptId());
+                    e.setTenantId(f.getTenantId());
+                    pmWorkContentMapper.insert(e);
                 }
-                pmReceive.setReadFlag(0);
-                pmReceiveMapper.insert(pmReceive);
-            }
-        }
-    }
-
-    @Async("asyncServiceExecutor")
-    public void sendAsyncMessage(PmWorkReport newReport, List<Long> userId) {
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("infoTitle", INFO_TITLE);
-        jsonObject.put("infoContent", SecurityUtils.getLoginUser().getSysUser().getNickName() + INFO_CONTENT);
-        jsonObject.put("infoType", INFO_TYPE);
-        jsonObject.put("id", newReport.getId());
-        jsonObject.put("infoTypeName", INFO_TITLE);
-        if (userId != null && !userId.isEmpty()) {
-            jsonObject.put("userIds", userId);
-        }
-        // 推送消息中心
-        try {
-            ApiResult<Void> voidApiResult = remoteMceService.addMce(jsonObject.toString());
-
-            if (voidApiResult.isSuccess()) {
-                log.info("报告消息发送成功!");
-            } else {
-                log.error("报告消息发送失败!");
             }
-        } catch (Exception e) {
-            log.error("发送消息时发生异常", e);
         }
     }
 
@@ -493,185 +432,38 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
         return returnList;
     }
 
-    /**
-     * 指定请求
-     *
-     * @return
-     * @throws Exception
-     */
-    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
-        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
-        config.protocol = "https";
-        config.regionId = "central";
-        config.method = "POST";
-        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
-    }
-
-    /**
-     * 获取钉钉企业内部AccessToken
-     *
-     * @return
-     * @throws Exception
-     */
-    public String getDingTalkToken() {
-        GetAccessTokenResponse responseBody = new GetAccessTokenResponse();
-        com.aliyun.dingtalkoauth2_1_0.Client client = null;
-        try {
-            client = createClient();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
-                .setAppKey(dingTalkConstant.DING_TALK_CLIENT_ID)
-                .setAppSecret(dingTalkConstant.DING_TALK_CLIENT_SECRET);
-        try {
-            responseBody = client.getAccessToken(getAccessTokenRequest);
-        } catch (TeaException err) {
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                // err 中含有 code 和 message 属性,可帮助开发定位问题
-            }
-        } catch (Exception _err) {
-            TeaException err = new TeaException(_err.getMessage(), _err);
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                // err 中含有 code 和 message 属性,可帮助开发定位问题
+    @Transactional
+    @Override
+    public void timedSending(LocalDateTime time) {
+        LambdaQueryWrapper<PmWorkReport> reports = Wrappers.lambdaQuery();
+        reports.eq(PmWorkReport::getIsRegularlySend, 1)
+                .eq(PmWorkReport::getReportStatus, 0)
+                .le(PmWorkReport::getTimingTime, time)
+                .orderByAsc(PmWorkReport::getTimingTime);
+        List<PmWorkReport> reportList = pmWorkReportMapper.selectList(reports);
+        if (!reportList.isEmpty()) {
+            List<Integer> reportIds = new ArrayList<>();
+            for (PmWorkReport report : reportList) {
+                reportIds.add(report.getId());
             }
-        }
-        return responseBody.getBody().accessToken;
-    }
-
-    /**
-     * 获取钉钉userId
-     *
-     * @param userId 平台userid
-     * @return
-     */
-    public String getDingTalkUserId(Long userId) {
-        String dingTalkId = "";
-        LambdaQueryWrapper<MceMbuser> dingTalkQuery = Wrappers.lambdaQuery();
-        dingTalkQuery.select(MceMbuser::getDingTalkId, MceMbuser::getUserId)
-                .eq(MceMbuser::getUserId, userId);
-        MceMbuser mceMbuser = mceMbuserMapper.selectOne(dingTalkQuery);
-        if (mceMbuser != null) {
-            String dingId = mceMbuser.getDingTalkId();
-            if (dingId != null && dingId != "") {
-                return mceMbuser.getDingTalkId();
+            LambdaQueryWrapper<PmWorkContent> reportContents = Wrappers.lambdaQuery();
+            reportContents.in(PmWorkContent::getReportId, reportIds);
+            List<PmWorkContent> pmWorkContentList = pmWorkContentMapper.selectList(reportContents);
+            for (PmWorkReport report : reportList) {
+                Integer id = report.getId();
+                List<PmWorkContent> workContents = new ArrayList<>();
+                for (PmWorkContent content : pmWorkContentList) {
+                    Integer reportId = content.getReportId();
+                    if (reportId == id) {
+                        workContents.add(content);
+                    }
+                }
+                dingTalkAndMessage.sendDingTalkDailyReport(report, workContents);
+                dingTalkAndMessage.sendAsyncMessage(report);
             }
         }
-        LambdaQueryWrapper<SysUser> phoneQuery = Wrappers.lambdaQuery();
-        phoneQuery.select(SysUser::getPhonenumber, SysUser::getUserName)
-                .eq(SysUser::getUserId, userId);
-        SysUser user = sysUserMapper.selectOne(phoneQuery);
-        String mobile = user.getPhonenumber();
-        try {
-            String accessToken = getDingTalkToken();
-            DingTalkClient client = new DefaultDingTalkClient(dingTalkConstant.DING_TALK_USERID_URL);
-            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
-            req.setMobile(mobile);
-            OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
-            ObjectMapper objectMapper = new ObjectMapper();
-            JsonNode rootNode = objectMapper.readTree(rsp.getBody());
-            JsonNode resultNode = rootNode.get("result");
-            dingTalkId = resultNode.get("userid").asText();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        if (mceMbuser != null) {
-            mceMbuser.setDingTalkId(dingTalkId);
-            mceMbuser.setUpdateBy(SecurityUtils.getUsername());
-            mceMbuser.setUpdateTime(LocalDateTime.now());
-            mceMbuserMapper.update(mceMbuser, dingTalkQuery);
-        } else {
-            MceMbuser mbuser = new MceMbuser();
-            mbuser.setDingTalkId(dingTalkId);
-            mbuser.setPhone(mobile);
-            mbuser.setUserId(userId);
-            mbuser.setCreateBy(user.getUserName());
-            mbuser.setCreateTime(LocalDateTime.now());
-            mceMbuserMapper.insert(mbuser);
-        }
-        return dingTalkId;
-    }
 
-    @Async("asyncServiceExecutor")//异步发送
-    @Override
-    public void sendDingTalkDailyReport(PmWorkReport workReport, List<PmWorkContent> workContents) {
-        String ccToStr = workReport.getCcTo();
-        String[] items = ccToStr.split(",");
-        List<Long> userIds = new ArrayList<>();
-        for (String item : items) {
-            long number = Long.parseLong(item.trim());
-            userIds.add(number);
-        }
-        List<String> ccTo = new ArrayList<>();
-        for (Long userId : userIds) {
-            String dingTalkUserId = getDingTalkUserId(userId);
-            ccTo.add(dingTalkUserId);
-        }
-        String reportCoordinateWork = workReport.getCoordinateWork();
-        String reportTomorrowPlan = workReport.getTomorrowPlan();
-        String coordinateWork1 = "-";
-        String tomorrowPlan1 = "-";
-        if (reportCoordinateWork != null && reportCoordinateWork != "") {
-            coordinateWork1 = reportCoordinateWork;
-        }
-        if (reportTomorrowPlan != null && reportTomorrowPlan != "") {
-            tomorrowPlan1 = reportTomorrowPlan;
-        }
 
-        StringBuilder contentBuilder = new StringBuilder();
-        for (PmWorkContent content : workContents) {
-            String projectName = content.getProjectName();
-            BigDecimal workTime = content.getWorkTime();
-            String workContent = content.getWorkContent();
-            StringBuilder markdown = new StringBuilder();
-            markdown.append("#### ").append(projectName).append(" ").append(workTime).append("h\n\n");
-            markdown.append("<span style=\"font-size: 18px;\">").append(workContent).append("\n").append("</span>");
-            contentBuilder.append(markdown);
-        }
-        String completedWork = contentBuilder.toString();
-        try {
-            DingTalkClient client = new DefaultDingTalkClient(dingTalkConstant.DING_TALK_CREATE_DAILY_REPORT_URL);
-            OapiReportCreateRequest req = new OapiReportCreateRequest();
-            OapiReportCreateRequest.OapiCreateReportParam obj1 = new OapiReportCreateRequest.OapiCreateReportParam();
-            List<OapiReportCreateRequest.OapiReportContentVo> list3 = new ArrayList<>();
-            OapiReportCreateRequest.OapiReportContentVo completedWorkD = new OapiReportCreateRequest.OapiReportContentVo();
-            completedWorkD.setSort(0L);
-            completedWorkD.setType(1L);
-            completedWorkD.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
-            completedWorkD.setContent(completedWork);
-            completedWorkD.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_COMPLETED_WORK);
-            list3.add(completedWorkD);
-            OapiReportCreateRequest.OapiReportContentVo tomorrowPlan = new OapiReportCreateRequest.OapiReportContentVo();
-            tomorrowPlan.setSort(1L);
-            tomorrowPlan.setType(1L);
-            tomorrowPlan.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
-            tomorrowPlan.setContent(tomorrowPlan1);
-            tomorrowPlan.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_TOMORROW_PLAN);
-            list3.add(tomorrowPlan);
-            OapiReportCreateRequest.OapiReportContentVo coordinateWork = new OapiReportCreateRequest.OapiReportContentVo();
-            coordinateWork.setSort(2L);
-            coordinateWork.setType(1L);
-            coordinateWork.setContentType(dingTalkConstant.DING_TALK_DAILY_REPORT_CONTENT_TYPE);
-            coordinateWork.setContent(coordinateWork1);
-            coordinateWork.setKey(dingTalkConstant.DING_TALK_DAILY_REPORT_COORDINATE_WORK);
-            list3.add(coordinateWork);
-            obj1.setContents(list3);
-            obj1.setToUserids(ccTo);
-            obj1.setTemplateId(dingTalkConstant.DING_TALK_DAILY_REPORT_TEMPLATE_ID);
-            obj1.setToChat(dingTalkConstant.DING_TALK_DAILY_REPORT_TO_CHAT);
-            obj1.setDdFrom(dingTalkConstant.DING_TALK_CORP_ID);
-            obj1.setUserid(getDingTalkUserId(SecurityUtils.getUserId()));
-            //obj1.setToCids(dingTalkConstant.DING_TALK_DAILY_REPORT_TO_CIDS);//发送到群,群id
-            req.setCreateReportParam(obj1);
-            OapiReportCreateResponse rsp = client.execute(req, getDingTalkToken());
-            if (rsp.isSuccess()) {
-                log.info("钉钉报告发送成功");
-            } else {
-                log.error("钉钉报告发送失败: " + rsp.getErrmsg());
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
     }
 
 

+ 3 - 0
service-iot/service-iot-biz/src/main/resources/mapper/iot/PmWorkReportMapper.xml

@@ -19,6 +19,9 @@
         <result column="dept_id" property="deptId" />
         <result column="tenant_id" property="tenantId" />
         <result column="send_ding_talk" property="sendDingTalk" />
+        <result column="timing_time" property="timingTime" />
+        <result column="report_status" property="reportStatus" />
+        <result column="is_regularly_send" property="isRegularlySend" />
     </resultMap>
 
 </mapper>