Bladeren bron

feat: 系统通用通知功能初次提交

linwenhua 3 jaren geleden
bovenliggende
commit
43881dc827
42 gewijzigde bestanden met toevoegingen van 1894 en 0 verwijderingen
  1. 26 0
      smsb-customer-manager-adapter/src/main/java/com/inspur/customer/web/controller/InformTestController.java
  2. 258 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/CommonInformServiceImpl.java
  3. 36 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/InformMessageContentRecordServiceImpl.java
  4. 94 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/InformMessageRecordServiceImpl.java
  5. 21 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/AbstractMessageHandler.java
  6. 45 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/EmailMessageHandler.java
  7. 25 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/NoteMessageHandler.java
  8. 45 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/WeChatAppletMessageHandler.java
  9. 47 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/WeChatMessageHandler.java
  10. 98 0
      smsb-customer-manager-app/src/main/java/com/inspur/customer/service/tenant/TenantExceptionInformStrategyServiceImpl.java
  11. 1 0
      smsb-customer-manager-app/src/main/resources/appletMessage/AiAuditCreditInsufficientWarn.RTF
  12. 7 0
      smsb-customer-manager-app/src/main/resources/email/AiAuditCreditInsufficientWarn.html
  13. 30 0
      smsb-customer-manager-app/src/main/resources/weChat/AiAuditCreditInsufficientWarn.json
  14. 4 0
      smsb-customer-manager-client/pom.xml
  15. 43 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/CommonInformService.java
  16. 18 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/InformMessageContentRecordService.java
  17. 26 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/InformMessageRecordService.java
  18. 34 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/client/tenant/TenantExceptionInformStrategyService.java
  19. 63 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/InformLevelEnum.java
  20. 51 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/InformTypeEnum.java
  21. 49 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/MessageTemplateEnum.java
  22. 60 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CommonInformCO.java
  23. 21 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CommonMessageCO.java
  24. 40 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CustomerBaseException.java
  25. 71 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformAddressees.java
  26. 44 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformMessageContentRecordDto.java
  27. 55 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformMessageRecordDto.java
  28. 61 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformResult.java
  29. 59 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformStrategy.java
  30. 110 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/tenant/ExceptionInformStrategyCmd.java
  31. 55 0
      smsb-customer-manager-client/src/main/java/com/inspur/customer/object/tenant/TenantExceptionInformStrategyCO.java
  32. 14 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/inform/InformMessageContentRecordMapper.java
  33. 13 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/inform/InformMessageRecordMapper.java
  34. 13 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/tenant/TenantExceptionInformStrategyMapper.java
  35. 48 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/inform/InformMessageContentRecordDO.java
  36. 81 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/inform/InformMessageRecordDO.java
  37. 32 0
      smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/tenant/TenantExceptionInformStrategyDO.java
  38. 5 0
      smsb-customer-manager-infrastructure/src/main/resources/mapper/inform/InformMessageContentRecordMapper.xml
  39. 5 0
      smsb-customer-manager-infrastructure/src/main/resources/mapper/inform/InformMessageRecordMapper.xml
  40. 5 0
      smsb-customer-manager-infrastructure/src/main/resources/mapper/tenant/TenantExceptionInformStrategyMapper.xml
  41. 2 0
      smsb-customer-manager-start-web/src/main/java/com/inspur/customer/SmsbCustomerWebApplication.java
  42. 79 0
      smsb-customer-manager-start-web/src/test/java/com/inspur/customer/MessageHandlerTest.java

+ 26 - 0
smsb-customer-manager-adapter/src/main/java/com/inspur/customer/web/controller/InformTestController.java

@@ -0,0 +1,26 @@
+package com.inspur.customer.web.controller;
+
+import com.inspur.customer.client.inform.CommonInformService;
+import com.inspur.customer.context.inform.InformTypeEnum;
+import com.inspur.customer.object.inform.CommonInformCO;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-04 14:37
+ **/
+@RestController
+public class InformTestController {
+
+    @DubboReference
+    private CommonInformService commonInformService;
+
+    @PostMapping("inform/test")
+    public void testInform(@RequestBody CommonInformCO commonInformCO) {
+        commonInformCO.setTypeEnum(InformTypeEnum.AI_AUDIT_CREDIT_INSUFFICIENT_WARN);
+        commonInformService.commonInform(commonInformCO);
+    }
+}

+ 258 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/CommonInformServiceImpl.java

@@ -0,0 +1,258 @@
+package com.inspur.customer.service.inform;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.inspur.customer.client.inform.CommonInformService;
+import com.inspur.customer.client.inform.InformMessageRecordService;
+import com.inspur.customer.client.keycloak.KeycloakService;
+import com.inspur.customer.client.tenant.TenantExceptionInformStrategyService;
+import com.inspur.customer.context.inform.MessageTemplateEnum;
+import com.inspur.customer.object.inform.*;
+import com.inspur.customer.object.keycloak.KeycloakUserCO;
+import com.inspur.customer.object.tenant.ExceptionInformStrategyCmd;
+import com.inspur.customer.object.tenant.TenantExceptionInformStrategyCO;
+import com.inspur.customer.service.inform.handler.EmailMessageHandler;
+import com.inspur.customer.service.inform.handler.NoteMessageHandler;
+import com.inspur.customer.service.inform.handler.WeChatAppletMessageHandler;
+import com.inspur.customer.service.inform.handler.WeChatMessageHandler;
+import com.inspur.inform.client.email.SmsbEmailService;
+import com.inspur.inform.client.sms.SmsbSmsService;
+import com.inspur.inform.client.wechat.IWeChatService;
+import com.inspur.inform.client.wechat.applet.IWxAppletUserMessageService;
+import com.inspur.inform.object.applet.message.WxAppletUserMessageDto;
+import com.inspur.inform.object.message.EmailMessage;
+import com.inspur.inform.object.message.SmsMessage;
+import com.inspur.inform.object.message.WechatMessage;
+import com.inspur.logging.object.EventBaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.annotation.DubboService;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * common inform service impl
+ * @author linwenhua
+ * @date 2022-06-29 15:30
+ **/
+@Slf4j
+@DubboService(interfaceClass = CommonInformService.class)
+public class CommonInformServiceImpl implements CommonInformService {
+
+    @Resource
+    private ObjectMapper objectMapper;
+
+    @Resource
+    private EmailMessageHandler emailMessageHandler;
+    @Resource
+    private NoteMessageHandler noteMessageHandler;
+    @Resource
+    private WeChatMessageHandler weChatMessageHandler;
+    @Resource
+    private WeChatAppletMessageHandler weChatAppletMessageHandler;
+
+    @DubboReference
+    private KeycloakService keycloakService;
+    @DubboReference
+    private TenantExceptionInformStrategyService tenantExceptionInformStrategyService;
+    @DubboReference
+    private InformMessageRecordService informMessageRecordService;
+
+    @DubboReference(async = true)
+    private SmsbEmailService smsbEmailService;
+    @DubboReference(async = true)
+    private SmsbSmsService smsbSmsService;
+    @DubboReference(async = true)
+    private IWeChatService weChatService;
+    @DubboReference(async = true)
+    private IWxAppletUserMessageService wxAppletUserMessageService;
+
+    @Override
+    public void commonInform(CommonInformCO informCo) {
+        // get base user
+        List<KeycloakUserCO> users = keycloakService.getUsersByIds(Collections.singletonList(informCo.getUserId()));
+        // get strategy
+        TenantExceptionInformStrategyCO informStrategyCo = tenantExceptionInformStrategyService.getTenantInformStrategyCache(informCo.getTenant());
+        ExceptionInformStrategyCmd informStrategyCmd = informStrategyCo.getStrategy().get(String.valueOf(informCo.getTypeEnum().getLevel().getId()));
+        switch (informCo.getTypeEnum().getLevel()) {
+            case HINT : {
+                log.info("hint");
+                break;
+            }
+            case INTERMEDIATE: {
+                log.info("intermediate");
+                //todo replace get user method
+                users.addAll(keycloakService.getUsersInRole("ROLE_SUPER_ADMIN"));
+                break;
+            }
+            case URGENT : {
+                log.info("urgent");
+                //todo replace get user method
+                users.addAll(keycloakService.getUsersInRole("ROLE_SUPER_ADMIN"));
+                break;
+            }
+            default : {
+                log.info("not support");
+                throw new EventBaseException("类型错误", 500);
+            }
+        }
+        // execute inform
+        executeInformUserCmd(informCo, informStrategyCmd, users);
+    }
+
+    @Override
+    public void tenantLevelInform(CommonInformCO informCo) {
+        log.info("tenant level: {}", informCo.getTenant());
+        // get user
+        List<KeycloakUserCO> users = keycloakService.getGroupSupervisor(informCo.getTenant());
+        // get strategy
+        TenantExceptionInformStrategyCO informStrategyCo = tenantExceptionInformStrategyService.getTenantInformStrategyCache(informCo.getTenant());
+        ExceptionInformStrategyCmd informStrategyCmd = informStrategyCo.getStrategy().get(String.valueOf(informCo.getTypeEnum().getLevel().getId()));
+        // execute inform
+        executeInformUserCmd(informCo, informStrategyCmd, users);
+    }
+
+    @Override
+    public void departmentLevelInform(CommonInformCO informCo) {
+        log.info("department level: {}", informCo.getOrg());
+        // get user
+        List<KeycloakUserCO> users = keycloakService.getGroupAdmin(informCo.getOrg());
+        // get strategy
+        TenantExceptionInformStrategyCO informStrategyCo = tenantExceptionInformStrategyService.getTenantInformStrategyCache(informCo.getTenant());
+        ExceptionInformStrategyCmd informStrategyCmd = informStrategyCo.getStrategy().get(String.valueOf(informCo.getTypeEnum().getLevel().getId()));
+        // execute inform
+        executeInformUserCmd(informCo, informStrategyCmd, users);
+    }
+
+    @Override
+    public void singleInformMethod(CommonInformCO informCo) {
+        log.info("single inform level: {}", informCo.getUserId());
+        List<KeycloakUserCO> users = keycloakService.getUsersByIds(Collections.singletonList(informCo.getUserId()));
+        // get strategy
+        TenantExceptionInformStrategyCO informStrategyCo = tenantExceptionInformStrategyService.getTenantInformStrategyCache(informCo.getTenant());
+        ExceptionInformStrategyCmd informStrategyCmd = informStrategyCo.getStrategy().get(String.valueOf(informCo.getTypeEnum().getLevel().getId()));
+        // execute inform
+        executeInformUserCmd(informCo, informStrategyCmd, users);
+    }
+
+    private void executeInformUserCmd(CommonInformCO informCo, ExceptionInformStrategyCmd informStrategyCmd, List<KeycloakUserCO> users) {
+        InformAddressees addressees = new InformAddressees(users.size());
+        users.forEach(user -> {
+            log.info("user: {}", user);
+            addressees.addPhone(user.getPhone());
+            addressees.addEmailAddressee(user.getEmail());
+            addressees.addOpenId(user.getWechat());
+            addressees.addUserId(user.getId());
+        });
+        try {
+            // save record
+            Long contentId = this.saveSendRecord(informCo, informStrategyCmd, users);
+            // send message
+            InformResult informResult = sendMessage(informCo, informStrategyCmd, addressees);
+            // update record
+            updateSendRecord(informResult, contentId, informStrategyCmd, addressees.getUserIds());
+        } catch (JsonProcessingException e) {
+            log.error("序列化出错: {}", e.getMessage(), e);
+            throw new CustomerBaseException("参数序列化出错", 500);
+        } catch (IOException e) {
+            log.error("模板转换出错: {}", e.getMessage(), e);
+            throw new CustomerBaseException("模板转换出错", 500);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private InformResult sendMessage(CommonInformCO informCo, ExceptionInformStrategyCmd informStrategyCmd, InformAddressees addressees) throws Exception {
+        MessageTemplateEnum templateEnum = informCo.getTypeEnum().getTemplateEnum();
+        // inform result
+        InformResult informResult = new InformResult();
+        if (Boolean.TRUE.equals(informStrategyCmd.getEmail())) {
+            EmailMessage emailMessage = emailMessageHandler.makeEmailMessage(informCo.getEmailMessage(), templateEnum.getEmail(), addressees.getEmailAddressees());
+            log.info("email");
+            informResult.setEmailResult(smsbEmailService.asyncSendEmail(emailMessage));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getNote())) {
+            SmsMessage smsMessage = noteMessageHandler.makeSmsMessage(informCo.getNoteMessage(), addressees.getPhones(), templateEnum.getNote());
+            log.info("note");
+            informResult.setNoteResult(smsbSmsService.asyncSend(smsMessage));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getWechat())) {
+            WechatMessage wechatMessage = weChatMessageHandler.makeWeChatMessage(informCo.getWeChatMessage(), addressees.getOpenIds(), templateEnum.getWechat());
+            log.info("wechat");
+            informResult.setWeChatResult(weChatService.asyncSend(wechatMessage));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getWechatApplet())) {
+            WxAppletUserMessageDto wxAppletUserMessageDto = weChatAppletMessageHandler.makeWeChatAppletMessage(informCo.getWeChatAppletMessage(), templateEnum.getApplet());
+            log.info("applet");
+            informResult.setWeChatAppletResult(wxAppletUserMessageService.asyncInsertBatch(wxAppletUserMessageDto, addressees.getUserIds()));
+        }
+        return informResult;
+    }
+
+    private Long saveSendRecord(CommonInformCO informCo, ExceptionInformStrategyCmd informStrategyCmd, List<KeycloakUserCO> users) throws JsonProcessingException {
+        InformMessageRecordDto messageRecordDto = new InformMessageRecordDto();
+        messageRecordDto.setTenant(informCo.getTenant());
+        messageRecordDto.setOrg(informCo.getOrg());
+        Map<String, String> messageMap = new HashMap<>(4);
+        if (Boolean.TRUE.equals(informStrategyCmd.getEmail())) {
+            messageMap.put(InformMessageRecordDto.EMAIL_KEY, objectMapper.writeValueAsString(informCo.getEmailMessage()));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getNote())) {
+            messageMap.put(InformMessageRecordDto.NOTE_KEY, objectMapper.writeValueAsString(informCo.getNoteMessage()));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getWechat())) {
+            messageMap.put(InformMessageRecordDto.WECHAT_KEY, objectMapper.writeValueAsString(informCo.getWeChatMessage()));
+        }
+        if (Boolean.TRUE.equals(informStrategyCmd.getWechatApplet())) {
+            messageMap.put(InformMessageRecordDto.WECHAT_APPLET_KEY, objectMapper.writeValueAsString(informCo.getWeChatAppletMessage()));
+        }
+        messageRecordDto.setMessageMap(messageMap);
+        return informMessageRecordService.saveRecord(users, informStrategyCmd, messageRecordDto);
+    }
+
+    private void updateSendRecord(InformResult informResult, Long contentId, ExceptionInformStrategyCmd informStrategyCmd, List<String> userIds) {
+        CompletableFuture[] completableFutures = setFutureCombine(informResult, informStrategyCmd.getCount());
+        for (CompletableFuture completableFuture : completableFutures) {
+            log.info("com: {}", completableFuture);
+        }
+        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(completableFutures);
+        completableFuture.whenComplete((result, error) -> {
+            log.info("error: {}", error);
+            log.info("update result flag");
+            informResult.updateResultFlag();
+        });
+        // update record
+        informMessageRecordService.updateRecord(contentId, informResult.getResultFlag());
+    }
+
+    public CompletableFuture[] setFutureCombine(InformResult informResult, Integer size) {
+        int index = 0;
+        CompletableFuture[] completableFutures = new CompletableFuture[size];
+        if (informResult.getNoteResult() != null) {
+            log.info("index: {}", index);
+            completableFutures[index] = informResult.getNoteResult();
+            index++;
+        }
+        if (informResult.getEmailResult() != null) {
+            log.info("index: {}", index);
+            completableFutures[index] = informResult.getEmailResult();
+            index++;
+        }
+        if (informResult.getWeChatResult() != null) {
+            log.info("index: {}", index);
+            completableFutures[index] = informResult.getWeChatResult();
+            index++;
+        }
+        if (informResult.getWeChatAppletResult() != null) {
+            log.info("index: {}", index);
+            completableFutures[index] = informResult.getWeChatAppletResult();
+        }
+        return completableFutures;
+    }
+}

+ 36 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/InformMessageContentRecordServiceImpl.java

@@ -0,0 +1,36 @@
+package com.inspur.customer.service.inform;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.inspur.customer.client.inform.InformMessageContentRecordService;
+import com.inspur.customer.infrastructure.mapper.inform.InformMessageContentRecordMapper;
+import com.inspur.customer.infrastructure.object.inform.InformMessageContentRecordDO;
+import com.inspur.customer.object.inform.InformMessageContentRecordDto;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.beans.BeanUtils;
+
+import javax.annotation.Resource;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-01 10:08
+ **/
+@Slf4j
+@DubboService(interfaceClass = InformMessageContentRecordService.class)
+public class InformMessageContentRecordServiceImpl extends ServiceImpl<InformMessageContentRecordMapper, InformMessageContentRecordDO> implements InformMessageContentRecordService {
+
+    @Resource
+    private ObjectMapper objectMapper;
+
+    @Override
+    public Long saveContentRecord(InformMessageContentRecordDto informMessageContentRecordDto) throws JsonProcessingException {
+        InformMessageContentRecordDO informMessageContentRecordDo = new InformMessageContentRecordDO();
+        BeanUtils.copyProperties(informMessageContentRecordDto, informMessageContentRecordDo);
+        // transform to json
+        informMessageContentRecordDo.setMessageMapJson(objectMapper.writeValueAsString(informMessageContentRecordDto.getMessageMap()));
+        this.save(informMessageContentRecordDo);
+        return informMessageContentRecordDo.getId();
+    }
+}

+ 94 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/InformMessageRecordServiceImpl.java

@@ -0,0 +1,94 @@
+package com.inspur.customer.service.inform;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.inspur.customer.client.inform.InformMessageContentRecordService;
+import com.inspur.customer.client.inform.InformMessageRecordService;
+import com.inspur.customer.infrastructure.mapper.inform.InformMessageRecordMapper;
+import com.inspur.customer.infrastructure.object.inform.InformMessageRecordDO;
+import com.inspur.customer.object.inform.InformMessageContentRecordDto;
+import com.inspur.customer.object.inform.InformMessageRecordDto;
+import com.inspur.customer.object.keycloak.KeycloakUserCO;
+import com.inspur.customer.object.tenant.ExceptionInformStrategyCmd;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.beans.BeanUtils;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-30 17:40
+ **/
+@Slf4j
+@DubboService(interfaceClass = InformMessageRecordService.class)
+public class InformMessageRecordServiceImpl extends ServiceImpl<InformMessageRecordMapper, InformMessageRecordDO> implements InformMessageRecordService {
+
+    @DubboReference
+    private InformMessageContentRecordService informMessageContentRecordService;
+
+    @Override
+    public Long saveRecord(List<KeycloakUserCO> users, ExceptionInformStrategyCmd informStrategyCmd, InformMessageRecordDto informMessageRecordDto) throws JsonProcessingException {
+        List<InformMessageRecordDO> informMessageRecordDos = new ArrayList<>(users.size());
+        // save content
+        Long contentId = this.saveMessageContent(informMessageRecordDto, informStrategyCmd, users.size());
+        users.forEach(user -> {
+            InformMessageRecordDO informMessageRecordDo = new InformMessageRecordDO();
+            BeanUtils.copyProperties(informMessageRecordDto, informMessageRecordDo);
+            // set inform flag
+            informMessageRecordDo.setInformFlag(getInformFlag(user, informStrategyCmd));
+            // status default 0
+            informMessageRecordDo.setInformStatus(0);
+            informMessageRecordDo.setContentId(contentId);
+            informMessageRecordDo.setUserId(user.getId());
+            informMessageRecordDos.add(informMessageRecordDo);
+        });
+        this.saveBatch(informMessageRecordDos, informMessageRecordDos.size());
+        return contentId;
+    }
+
+    @Override
+    public void updateRecord(Long contentId, Integer informStatus) {
+        log.info("update send record: {}", contentId);
+        BitSet informBitMap = BitSet.valueOf(new byte[]{informStatus.byteValue()});
+        List<InformMessageRecordDO> messageRecordDos = this.list(Wrappers
+            .<InformMessageRecordDO>lambdaQuery()
+            .eq(InformMessageRecordDO::getContentId, contentId));
+        messageRecordDos.forEach(record -> {
+            BitSet userBitMap = record.getBitMap();
+            userBitMap.and(informBitMap);
+            if (userBitMap.isEmpty()) {
+                record.setInformStatus(0);
+            } else {
+                record.setInformFlag((int) userBitMap.toByteArray()[0]);
+            }
+        });
+        this.updateBatchById(messageRecordDos);
+    }
+
+    private Long saveMessageContent(InformMessageRecordDto informMessageRecordDto, ExceptionInformStrategyCmd informStrategyCmd, Integer size) throws JsonProcessingException {
+        InformMessageContentRecordDto informMessageContentRecordDto = new InformMessageContentRecordDto();
+        informMessageContentRecordDto.setTenant(informMessageRecordDto.getTenant());
+        informMessageContentRecordDto.setUsers(size);
+        informMessageContentRecordDto.setMessageMap(informMessageRecordDto.getMessageMap());
+        informMessageContentRecordDto.setInformFlag(informStrategyCmd.getStrategyFlag());
+        return informMessageContentRecordService.saveContentRecord(informMessageContentRecordDto);
+    }
+
+    private Integer getInformFlag(KeycloakUserCO keycloakUserCo, ExceptionInformStrategyCmd informStrategyCmd) {
+        log.info("user: {}", keycloakUserCo);
+        BitSet userBitSet = keycloakUserCo.getInformFlag();
+        BitSet strategyBitSet = informStrategyCmd.getStrategySet();
+        userBitSet.and(strategyBitSet);
+        log.info("userBitSet: {}", userBitSet);
+        log.info("strategy: {}", strategyBitSet);
+        if (userBitSet.isEmpty()) {
+            return 0;
+        }
+        return (int) userBitSet.toByteArray()[0];
+    }
+}

+ 21 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/AbstractMessageHandler.java

@@ -0,0 +1,21 @@
+package com.inspur.customer.service.inform.handler;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-01 15:44
+ **/
+public class AbstractMessageHandler {
+
+    protected String getTemplate(String filePath) throws IOException {
+        ClassPathResource classPathResource = new ClassPathResource(filePath);
+        InputStream inputStream = classPathResource.getInputStream();
+        return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+    }
+}

+ 45 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/EmailMessageHandler.java

@@ -0,0 +1,45 @@
+package com.inspur.customer.service.inform.handler;
+
+import com.inspur.customer.object.inform.CommonMessageCO;
+import com.inspur.inform.object.message.EmailMessage;
+import org.apache.commons.io.IOUtils;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * email message content handler
+ * @author linwenhua
+ * @date 2022-07-01 10:58
+ **/
+@Component
+public class EmailMessageHandler extends AbstractMessageHandler {
+
+    private static final String FILE_PATH_PRE = "email/";
+
+    private static final String FILE_PATH_SUF = ".html";
+
+    public EmailMessage makeEmailMessage(CommonMessageCO commonMessageCo, String fileName, List<String> addressees) throws IOException {
+        // get content
+        String filePath = FILE_PATH_PRE + fileName + FILE_PATH_SUF;
+        String content = getTemplate(filePath);
+        Iterator<String> integer = commonMessageCo.getMessageMap().keySet().iterator();
+        String key;
+        while (integer.hasNext()) {
+            key = integer.next();
+            content = content.replaceFirst(key, commonMessageCo.getMessageMap().get(key));
+        }
+        // set email message
+        // todo attach file and subject
+        EmailMessage emailMessage = new EmailMessage();
+        emailMessage.setAddressees(addressees);
+        emailMessage.setEmailContent(content);
+        emailMessage.setSubject(commonMessageCo.getSubject());
+        return emailMessage;
+    }
+}

+ 25 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/NoteMessageHandler.java

@@ -0,0 +1,25 @@
+package com.inspur.customer.service.inform.handler;
+
+import com.inspur.customer.object.inform.CommonMessageCO;
+import com.inspur.inform.object.message.SmsMessage;
+import com.inspur.inform.object.message.sms.SmsbSmsTemplateType;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * note message content handler
+ * @author linwenhua
+ * @date 2022-07-01 10:57
+ **/
+@Component
+public class NoteMessageHandler extends AbstractMessageHandler {
+
+    public SmsMessage makeSmsMessage(CommonMessageCO commonMessageCo, List<String> phones, Integer smsType) {
+        SmsMessage message = new SmsMessage();
+        message.setPhones(phones);
+        message.setTemplateParam(commonMessageCo.getMessageMap());
+        message.setTemplateType(SmsbSmsTemplateType.getTypeById(smsType));
+        return message;
+    }
+}

+ 45 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/WeChatAppletMessageHandler.java

@@ -0,0 +1,45 @@
+package com.inspur.customer.service.inform.handler;
+
+import com.inspur.customer.object.inform.CommonMessageCO;
+import com.inspur.inform.constants.UserMsgType;
+import com.inspur.inform.object.applet.message.WxAppletUserMessageDto;
+import org.apache.commons.io.IOUtils;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+
+/**
+ * weChat applet message content handler
+ * @author linwenhua
+ * @date 2022-07-01 10:58
+ **/
+@Component
+public class WeChatAppletMessageHandler extends AbstractMessageHandler {
+
+    private static final String FILE_PATH_PRE = "appletMessage/";
+
+    private static final String FILE_PATH_SUF = ".RTF";
+
+    public WxAppletUserMessageDto makeWeChatAppletMessage(CommonMessageCO commonMessageCo, String fileName) throws IOException {
+        // get content
+        String filePath = FILE_PATH_PRE + fileName + FILE_PATH_SUF;
+        String content = getTemplate(filePath);
+        Iterator<String> integer = commonMessageCo.getMessageMap().keySet().iterator();
+        String key;
+        while (integer.hasNext()) {
+            key = integer.next();
+            content = content.replaceFirst(key, commonMessageCo.getMessageMap().get(key));
+        }
+        WxAppletUserMessageDto wxAppletUserMessageDto = new WxAppletUserMessageDto();
+        wxAppletUserMessageDto.setSubject(commonMessageCo.getSubject());
+        //todo type level pic
+        wxAppletUserMessageDto.setType(UserMsgType.SYSTEM.getType());
+        wxAppletUserMessageDto.setPic(0);
+        wxAppletUserMessageDto.setMessage(content);
+        return wxAppletUserMessageDto;
+    }
+}

+ 47 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/inform/handler/WeChatMessageHandler.java

@@ -0,0 +1,47 @@
+package com.inspur.customer.service.inform.handler;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.inspur.customer.object.inform.CommonMessageCO;
+import com.inspur.inform.object.message.WechatKeyword;
+import com.inspur.inform.object.message.WechatMessage;
+import com.inspur.inform.object.message.WechatRealMessage;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.List;
+
+/**
+ * weChat message content handler
+ * @author linwenhua
+ * @date 2022-07-01 10:57
+ **/
+@Component
+public class WeChatMessageHandler extends AbstractMessageHandler {
+
+    @Resource
+    private ObjectMapper objectMapper;
+
+    private static final String FILE_PATH_PRE = "weChat/";
+
+    private static final String FILE_PATH_SUF = ".json";
+
+    public WechatMessage makeWeChatMessage(CommonMessageCO commonMessageCo, List<String> openIds, String fileName) throws IOException {
+        WechatRealMessage wechatRealMessage = getRealMessge(fileName);
+        commonMessageCo.getMessageMap().forEach((key, word) -> {
+            WechatKeyword wechatKeyword = wechatRealMessage.getData().get(key);
+            String keywordValue = wechatKeyword.getValue();
+            String[] words = word.split("/");
+            wechatKeyword.setValue(MessageFormat.format(keywordValue, words));
+        });
+        return new WechatMessage(wechatRealMessage, openIds);
+    }
+
+    private WechatRealMessage getRealMessge(String fileName) throws IOException {
+        // get content
+        String filePath = FILE_PATH_PRE + fileName + FILE_PATH_SUF;
+        String content = getTemplate(filePath);
+        return objectMapper.readValue(content, WechatRealMessage.class);
+    }
+}

+ 98 - 0
smsb-customer-manager-app/src/main/java/com/inspur/customer/service/tenant/TenantExceptionInformStrategyServiceImpl.java

@@ -0,0 +1,98 @@
+package com.inspur.customer.service.tenant;
+
+import com.alibaba.cola.dto.SingleResponse;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.inspur.customer.client.tenant.TenantExceptionInformStrategyService;
+import com.inspur.customer.infrastructure.mapper.tenant.TenantExceptionInformStrategyMapper;
+import com.inspur.customer.infrastructure.object.tenant.TenantExceptionInformStrategyDO;
+import com.inspur.customer.object.tenant.ExceptionInformStrategyCmd;
+import com.inspur.customer.object.tenant.TenantExceptionInformStrategyCO;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * tenant exception inform strategy service implement
+ * @author linwenhua
+ * @date 2022-06-08 11:49
+ **/
+@DubboService(interfaceClass = TenantExceptionInformStrategyService.class)
+public class TenantExceptionInformStrategyServiceImpl extends ServiceImpl<TenantExceptionInformStrategyMapper, TenantExceptionInformStrategyDO> implements TenantExceptionInformStrategyService {
+
+    @Override
+    @CacheEvict(value = "msr:tenant:informStrategy", key = "#informStrategyCo.getTenant()")
+    public SingleResponse<TenantExceptionInformStrategyCO> setInformStrategy(TenantExceptionInformStrategyCO informStrategyCo) {
+        TenantExceptionInformStrategyDO informStrategyDO = changeToInformStrategyDo(informStrategyCo);
+        this.saveOrUpdate(informStrategyDO);
+        return SingleResponse.of(informStrategyCo);
+    }
+
+    @Override
+    public SingleResponse<TenantExceptionInformStrategyCO> getTenantInformStrategy(String tenant) {
+        TenantExceptionInformStrategyDO informStrategyDO = this.getById(tenant);
+        if (informStrategyDO == null) {
+            return SingleResponse.of(getDefaultStrategy(tenant));
+        }
+        return SingleResponse.of(changeToInformStrategyCo(informStrategyDO));
+    }
+
+    @Override
+    @Cacheable(value = "msr:tenant:informStrategy", key = "#tenant")
+    public TenantExceptionInformStrategyCO getTenantInformStrategyCache(String tenant) {
+        TenantExceptionInformStrategyDO informStrategyDo = this.getById(tenant);
+        // if user didn't not set strategy, return default
+        if (informStrategyDo == null) {
+            return getDefaultStrategy(tenant);
+        }
+        return changeToInformStrategyCo(informStrategyDo);
+    }
+
+    /**
+     * change to do
+     * @param informStrategyCo co
+     * @return do
+     */
+    private TenantExceptionInformStrategyDO changeToInformStrategyDo(TenantExceptionInformStrategyCO informStrategyCo) {
+        TenantExceptionInformStrategyDO informStrategyDO = new TenantExceptionInformStrategyDO();
+        informStrategyDO.setTenant(informStrategyCo.getTenant());
+        informStrategyDO.setHintLevelFlag(informStrategyCo.getInformFlagByLevel(TenantExceptionInformStrategyCO.HINT_LEVEL_KEY));
+        informStrategyDO.setMiddleLevelFlag(informStrategyCo.getInformFlagByLevel(TenantExceptionInformStrategyCO.MIDDLE_LEVEL_KEY));
+        informStrategyDO.setUrgencyLevelFlag(informStrategyCo.getInformFlagByLevel(TenantExceptionInformStrategyCO.URGENT_LEVEL_KEY));
+        return informStrategyDO;
+    }
+
+    /**
+     * change to co
+     * @param informStrategyDo do
+     * @return co
+     */
+    private TenantExceptionInformStrategyCO changeToInformStrategyCo(TenantExceptionInformStrategyDO informStrategyDo) {
+        TenantExceptionInformStrategyCO informStrategyCo = new TenantExceptionInformStrategyCO(informStrategyDo.getTenant());
+        informStrategyCo.updateStrategy(TenantExceptionInformStrategyCO.HINT_LEVEL_KEY, new ExceptionInformStrategyCmd(informStrategyDo.getHintLevelFlag()));
+        informStrategyCo.updateStrategy(TenantExceptionInformStrategyCO.MIDDLE_LEVEL_KEY, new ExceptionInformStrategyCmd(informStrategyDo.getMiddleLevelFlag()));
+        informStrategyCo.updateStrategy(TenantExceptionInformStrategyCO.URGENT_LEVEL_KEY, new ExceptionInformStrategyCmd(informStrategyDo.getUrgencyLevelFlag()));
+        // TODO special inform
+        informStrategyCo.updateStrategy(TenantExceptionInformStrategyCO.TENANT_LEVEL_KEY, new ExceptionInformStrategyCmd(15));
+        informStrategyCo.updateStrategy(TenantExceptionInformStrategyCO.DEPARTMENT_LEVEL, new ExceptionInformStrategyCmd(15));
+        return informStrategyCo;
+    }
+
+    /**
+     * if user didn't set strategy, return default one
+     * @param tenant tenant identifier
+     * @return strategy
+     */
+    private TenantExceptionInformStrategyCO getDefaultStrategy(String tenant) {
+        TenantExceptionInformStrategyCO informStrategyCo = new TenantExceptionInformStrategyCO(tenant);
+        Map<String, ExceptionInformStrategyCmd> strategyMap = new HashMap<>(3);
+        strategyMap.put(TenantExceptionInformStrategyCO.HINT_LEVEL_KEY, new ExceptionInformStrategyCmd(14));
+        strategyMap.put(TenantExceptionInformStrategyCO.MIDDLE_LEVEL_KEY, new ExceptionInformStrategyCmd(15));
+        strategyMap.put(TenantExceptionInformStrategyCO.URGENT_LEVEL_KEY, new ExceptionInformStrategyCmd(15));
+        informStrategyCo.setStrategy(strategyMap);
+        return informStrategyCo;
+    }
+
+}

+ 1 - 0
smsb-customer-manager-app/src/main/resources/appletMessage/AiAuditCreditInsufficientWarn.RTF

@@ -0,0 +1 @@
+<div style="margin-top: 30px;display: flex;justify-content: space-between;font-size: 14px;"><div style="color: #8E929C;">库存类型:</div><div style="flex:1 1 auto;text-align: right;color: #333333;">MSR_TYPE</div></div><div style="margin-top: 30px;display: flex;justify-content: space-between;font-size: 14px;"><div style="color: #8E929C;">库存余数:</div><div style="flex:1 1 auto;text-align: right;color: #333333;">MSR_REMAINING</div></div><div style="margin-top: 30px;display: flex;justify-content: space-between;font-size: 14px;"><div style="color: #8E929C;">预警阈值:</div><div style="flex:1 1 auto;text-align: right;color: #333333;">MSR_THRESHOLD</div></div><div style="margin-top: 30px;display: flex;justify-content: space-between;font-size: 14px;"><div style="color: #8E929C;">统计日期:</div><div style="flex:1 1 auto;text-align: right;color: #333333;">MSR_WARN_DATE</div></div><div style="margin-top: 50px;font-size: 14px;color: #8E929C;">如有疑问,请及时联系管理员,谢谢。</div>

+ 7 - 0
smsb-customer-manager-app/src/main/resources/email/AiAuditCreditInsufficientWarn.html

@@ -0,0 +1,7 @@
+尊敬的用户,您好!<br>
+<br>
+&nbsp;&nbsp;您的AI机审有一条MSR_LEVEL预警,相关信息如下:<br>
+&nbsp;&nbsp;&nbsp;库存类型:MSR_TYPE<br>
+&nbsp;&nbsp;&nbsp;库存余数:MSR_REMAINING<br>
+&nbsp;&nbsp;&nbsp;预警阈值:MSR_THRESHOLD<br>
+&nbsp;&nbsp;&nbsp;统计日期: MSR_WARN_DATE<br>

+ 30 - 0
smsb-customer-manager-app/src/main/resources/weChat/AiAuditCreditInsufficientWarn.json

@@ -0,0 +1,30 @@
+{
+    "data":
+    {
+        "keyword3":
+        {
+            "value": "当前库存: {0}, 预警阈值: {1}",
+            "color": "#173177"
+        },
+        "keyword4":
+        {
+            "value": "{0}",
+            "color": "#173177"
+        },
+        "keyword1":
+        {
+            "value": "{0}",
+            "color": "#173177"
+        },
+        "keyword2":
+        {
+            "value": "无",
+            "color": "#173177"
+        },
+        "first":
+        {
+            "value": "【浪潮安播云】您的AI机审有一条 {0} 预警,请及时关注,谢谢。",
+            "color": "#173177"
+        }
+    }
+}

+ 4 - 0
smsb-customer-manager-client/pom.xml

@@ -35,6 +35,10 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 43 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/CommonInformService.java

@@ -0,0 +1,43 @@
+package com.inspur.customer.client.inform;
+
+import com.inspur.customer.object.inform.CommonInformCO;
+
+/**
+ * common inform service
+ * @author linwenhua
+ * @date 2022-06-29 14:59
+ **/
+public interface CommonInformService {
+
+    /**
+     * common inform
+     * @see com.inspur.customer.context.inform.InformLevelEnum#HINT
+     * @see com.inspur.customer.context.inform.InformLevelEnum#INTERMEDIATE
+     * @see com.inspur.customer.context.inform.InformLevelEnum#URGENT
+     * @param informCo informCo
+     */
+    void commonInform(CommonInformCO informCo);
+
+    /**
+     * tenant level inform for tenant manager
+     * @see com.inspur.customer.context.inform.InformLevelEnum#TENANT
+     * @param informCo informCO
+     */
+    void tenantLevelInform(CommonInformCO informCo);
+
+    /**
+     * department level inform for department leader
+     * @see com.inspur.customer.context.inform.InformLevelEnum#HINT
+     * @param informCo informCO
+     */
+    void departmentLevelInform(CommonInformCO informCo);
+
+    /**
+     * single inform method
+     * @see com.inspur.customer.context.inform.InformLevelEnum#SINGLE_EMAIL
+     * @see com.inspur.customer.context.inform.InformLevelEnum#SINGLE_NOTE
+     * @param informCo informCo
+     */
+    void singleInformMethod(CommonInformCO informCo);
+
+}

+ 18 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/InformMessageContentRecordService.java

@@ -0,0 +1,18 @@
+package com.inspur.customer.client.inform;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.inspur.customer.object.inform.InformMessageContentRecordDto;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:31
+ **/
+public interface InformMessageContentRecordService {
+
+    /**
+     * save content
+     * @param informMessageContentRecordDto content record
+     * @return content id
+     */
+    Long saveContentRecord(InformMessageContentRecordDto informMessageContentRecordDto) throws JsonProcessingException;
+}

+ 26 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/client/inform/InformMessageRecordService.java

@@ -0,0 +1,26 @@
+package com.inspur.customer.client.inform;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.inspur.customer.object.inform.InformMessageRecordDto;
+import com.inspur.customer.object.keycloak.KeycloakUserCO;
+import com.inspur.customer.object.tenant.ExceptionInformStrategyCmd;
+
+import java.util.List;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:31
+ **/
+public interface InformMessageRecordService {
+
+    /**
+     * save send record
+     * @param users users
+     * @param informStrategyCmd inform strategy
+     * @param informMessageRecordDto message record
+     * @return content id
+     */
+    Long saveRecord(List<KeycloakUserCO> users, ExceptionInformStrategyCmd informStrategyCmd, InformMessageRecordDto informMessageRecordDto) throws JsonProcessingException;
+
+    void updateRecord(Long contentId, Integer infromStatus);
+}

+ 34 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/client/tenant/TenantExceptionInformStrategyService.java

@@ -0,0 +1,34 @@
+package com.inspur.customer.client.tenant;
+
+
+import com.alibaba.cola.dto.SingleResponse;
+import com.inspur.customer.object.tenant.TenantExceptionInformStrategyCO;
+
+/**
+ * tenant exception inform strategy service
+ * @author linwenhua
+ * @date 2022-06-08 11:48
+ **/
+public interface TenantExceptionInformStrategyService {
+
+    /**
+     * set tenant inform strategy
+     * @param informStrategyCo strategy
+     * @return result
+     */
+    SingleResponse<TenantExceptionInformStrategyCO> setInformStrategy(TenantExceptionInformStrategyCO informStrategyCo);
+
+    /**
+     * get tenant inform strategy
+     * @param tenant tenant identifier
+     * @return result
+     */
+    SingleResponse<TenantExceptionInformStrategyCO> getTenantInformStrategy(String tenant);
+
+    /**
+     * get and cache strategy
+     * @param tenant tenant identifier
+     * @return result
+     */
+    TenantExceptionInformStrategyCO getTenantInformStrategyCache(String tenant);
+}

+ 63 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/InformLevelEnum.java

@@ -0,0 +1,63 @@
+package com.inspur.customer.context.inform;
+
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * inform level enum
+ * @author linwenhua
+ */
+public enum InformLevelEnum {
+
+    /**
+     * test level
+     */
+    TEST(-1, "测试"),
+    /**
+     * hint level
+     */
+    HINT(0, "提示"),
+    /**
+     * intermediate level
+     */
+    INTERMEDIATE(1, "中级"),
+    /**
+     * urgent
+     */
+    URGENT(2, "紧急"),
+    /**
+     * tenant level
+     */
+    TENANT(3, "租户管理级别"),
+    /**
+     * 部门级别
+     */
+    DEPARTMENT(4, "部门领导级别"),
+    /**
+     * only email
+     */
+    SINGLE_EMAIL(10, "仅邮件通知"),
+    /**
+     * only note
+     */
+    SINGLE_NOTE(11, "仅短信通知");
+
+    @Getter
+    private final int id;
+
+    /**
+     * 预警级别
+     */
+    @Getter
+    private final String name;
+
+    public static String getLevelName(int id) {
+        return Arrays.stream(InformLevelEnum.values()).filter(informLevel -> id == informLevel.getId()).findFirst().map(InformLevelEnum::getName).orElse(null);
+    }
+
+    InformLevelEnum(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+}

+ 51 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/InformTypeEnum.java

@@ -0,0 +1,51 @@
+package com.inspur.customer.context.inform;
+
+import lombok.Getter;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:57
+ **/
+public enum InformTypeEnum {
+
+    /**
+     * phone verify
+     */
+    PHONE_VERIFY_MESSAGE("屏媒安播云平台手机绑定验证", InformLevelEnum.SINGLE_NOTE, MessageTemplateEnum.PHONE_VERIFY_TEMPLATE),
+    /**
+     * email verify
+     */
+    EMAIL_VERIFY_MESSAGE("屏媒安播云平台邮箱绑定验证", InformLevelEnum.SINGLE_EMAIL, MessageTemplateEnum.EMAIL_VERIFY_TEMPLATE),
+    /**
+     * ai 审核库存预警
+     */
+    AI_AUDIT_CREDIT_INSUFFICIENT_WARN("ai 审核库存预警", InformLevelEnum.HINT, MessageTemplateEnum.AI_AUDIT_CREDIT_INSUFFICIENT_WARN),
+    /**
+     * ai 审核不通过预警
+     */
+    AI_MEDIA_WARN("ai 审核不通过预警", InformLevelEnum.HINT, MessageTemplateEnum.AI_AUDIT_NON_COMPLIANCE)
+    ;
+
+    /**
+     * type name
+     */
+    @Getter
+    private final String name;
+
+    /**
+     * inform level
+     */
+    @Getter
+    private final InformLevelEnum level;
+
+    @Getter
+    private final MessageTemplateEnum templateEnum;
+
+    InformTypeEnum(String name, InformLevelEnum level, MessageTemplateEnum templateEnum) {
+        this.name = name;
+        this.level = level;
+        this.templateEnum = templateEnum;
+    }
+
+
+}

+ 49 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/context/inform/MessageTemplateEnum.java

@@ -0,0 +1,49 @@
+package com.inspur.customer.context.inform;
+
+import lombok.Getter;
+
+/**
+ * message template enum
+ * @author linwenhua
+ */
+
+public enum MessageTemplateEnum {
+
+    /**
+     * phone verify template
+     */
+    PHONE_VERIFY_TEMPLATE("todo", 1, "wechat",  ""),
+    /**
+     * email verify template
+     */
+    EMAIL_VERIFY_TEMPLATE("todo", 1, "wechat",  ""),
+    /**
+     * AI 审核库存
+     */
+    AI_AUDIT_CREDIT_INSUFFICIENT_WARN("AiAuditCreditInsufficientWarn", 1, "AiAuditCreditInsufficientWarn",  "AiAuditCreditInsufficientWarn"),
+    /**
+     * 媒资 AI 不通过异常
+     */
+    AI_AUDIT_NON_COMPLIANCE("EmailVerifyTemplate", 1, "wechat",  ""),
+    ;
+
+    @Getter
+    private final String email;
+
+    @Getter
+    private final Integer note;
+
+    @Getter
+    private final String wechat;
+
+    @Getter
+    private final String applet;
+
+
+    MessageTemplateEnum(String email, Integer note, String wechat, String applet) {
+        this.email = email;
+        this.note = note;
+        this.wechat = wechat;
+        this.applet = applet;
+    }
+}

+ 60 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CommonInformCO.java

@@ -0,0 +1,60 @@
+package com.inspur.customer.object.inform;
+
+import com.inspur.customer.context.inform.InformTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:40
+ **/
+@Data
+public class CommonInformCO implements Serializable {
+
+    private static final long serialVersionUID = 4485440990149055018L;
+
+    private InformTypeEnum typeEnum;
+
+    /*---------------- batch inform ----------------*/
+
+    /**
+     * tenant identifier
+     */
+    private String tenant;
+
+    /**
+     * department
+     */
+    private String org;
+
+    /*---------------- single inform ----------------*/
+
+    /**
+     * user id
+     */
+    private String userId;
+
+    /*-------------------------------- message consider to make a list  --------------------------------*/
+
+    /**
+     * email message
+     */
+    private CommonMessageCO emailMessage;
+
+    /**
+     * note message
+     */
+    private CommonMessageCO noteMessage;
+
+    /**
+     * weChat message
+     */
+    private CommonMessageCO weChatMessage;
+
+    /**
+     * weChat applet
+     */
+    private CommonMessageCO weChatAppletMessage;
+
+}

+ 21 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CommonMessageCO.java

@@ -0,0 +1,21 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:43
+ **/
+@Data
+public class CommonMessageCO implements Serializable {
+
+    private String subject;
+
+    private static final long serialVersionUID = -4561191896624275223L;
+
+    private Map<String, String> messageMap;
+
+}

+ 40 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/CustomerBaseException.java

@@ -0,0 +1,40 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Getter;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-01 16:31
+ **/
+public class CustomerBaseException extends RuntimeException{
+
+    private static final long serialVersionUID = 6432409098208302604L;
+
+    @Getter
+    private String msg;
+
+    @Getter
+    private int code = 500;
+
+    public CustomerBaseException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+
+    public CustomerBaseException(String msg, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+    }
+
+    public CustomerBaseException(String msg, int code) {
+        super(msg);
+        this.msg = msg;
+        this.code = code;
+    }
+
+    public CustomerBaseException(String msg, int code, Throwable e) {
+        super(msg, e);
+        this.msg = msg;
+        this.code = code;
+    }
+}

+ 71 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformAddressees.java

@@ -0,0 +1,71 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.lang.Nullable;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-14 09:45
+ **/
+public class InformAddressees implements Serializable {
+
+    private static final long serialVersionUID = 5978949873926901132L;
+
+    @Getter
+    private final List<String> phones;
+
+    @Getter
+    private final List<String> emailAddressees;
+
+    @Getter
+    private final List<String> openIds;
+    /**
+     * user id for applet
+     */
+    @Getter
+    List<String> userIds;
+    
+    public InformAddressees(List<String> openIds) {
+        this.phones = Collections.emptyList();
+        this.emailAddressees = Collections.emptyList();
+        this.openIds = Collections.emptyList();
+        this.userIds = Collections.emptyList();
+    }
+    
+    public InformAddressees(Integer size) {
+        phones = new ArrayList<>(size);
+        emailAddressees = new ArrayList<>(size);
+        openIds = new ArrayList<>(size);
+        userIds = new ArrayList<>(size);
+    }
+
+    public void addPhone(@Nullable String phone) {
+        if (StringUtils.isNotBlank(phone)) {
+            phones.add(phone);
+        }
+    }
+
+    public void addEmailAddressee(@Nullable String emailAddressee) {
+        if (StringUtils.isNotBlank(emailAddressee)) {
+            emailAddressees.add(emailAddressee);
+        }
+    }
+
+    public void addOpenId(@Nullable String openId) {
+        if (StringUtils.isNotBlank(openId)) {
+            openIds.add(openId);
+        }
+    }
+
+    public void addUserId(@Nullable String userId) {
+        if (StringUtils.isNotBlank(userId)) {
+            userIds.add(userId);
+        }
+    }
+}

+ 44 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformMessageContentRecordDto.java

@@ -0,0 +1,44 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:36
+ **/
+@Data
+public class InformMessageContentRecordDto implements Serializable {
+
+    private static final long serialVersionUID = -1708529192978236713L;
+
+    private Long id;
+
+    /**
+     * tenant identifier
+     */
+    private String tenant;
+
+    /**
+     * the number of user
+     */
+    private Integer users;
+
+    /**
+     * inform flag
+     * bit 0: note
+     * bit 1: email
+     * bit 2: weChat
+     * bit 3: weChat applet
+     */
+    private Integer informFlag;
+
+    /**
+     * message map
+     */
+    private Map<String, String> messageMap;
+
+    private String contentMapJson;
+}

+ 55 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformMessageRecordDto.java

@@ -0,0 +1,55 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:35
+ **/
+@Data
+public class InformMessageRecordDto implements Serializable {
+
+    private static final long serialVersionUID = -1729327083071852247L;
+
+    public static final String EMAIL_KEY = "email";
+
+    public static final String NOTE_KEY = "note";
+
+    public static final String WECHAT_KEY = "weChat";
+
+    public static final String WECHAT_APPLET_KEY = "weChatApplet";
+
+    private Long id;
+
+    /**
+     * content record id
+     * @see InformMessageContentRecordDto#getId()
+     */
+    private Long contentId;
+
+    private Integer type;
+
+    /**
+     * tenant identifier
+     */
+    private String tenant;
+
+    /**
+     * department
+     */
+    private String org;
+
+    /**
+     * user id
+     */
+    private String userId;
+
+    /**
+     * message map
+     */
+    private Map<String, String> messageMap;
+
+}

+ 61 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformResult.java

@@ -0,0 +1,61 @@
+package com.inspur.customer.object.inform;
+
+import lombok.Data;
+
+import java.util.BitSet;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-01 19:01
+ **/
+@Data
+public class InformResult {
+
+    private BitSet resultFlag = new BitSet(4);
+
+    private CompletableFuture<Integer> emailResult;
+    private CompletableFuture<Integer> noteResult;
+    private CompletableFuture<Integer> weChatResult;
+    private CompletableFuture<Integer> weChatAppletResult;
+
+    public void setEmailResult(CompletableFuture<Integer> emailResult) {
+        this.emailResult = emailResult;
+    }
+
+    public void updateResultFlag(Integer index) {
+        resultFlag.set(index);
+    }
+
+    public void updateResultFlag() {
+        if (noteResult != null) {
+            getFlagFromFuture(noteResult, 0);
+        }
+        if (emailResult != null) {
+            getFlagFromFuture(emailResult, 1);
+        }
+        if (weChatResult != null) {
+            getFlagFromFuture(weChatResult, 2);
+        }
+        if (weChatAppletResult != null) {
+            getFlagFromFuture(weChatAppletResult, 3);
+        }
+    }
+
+    public Integer getResultFlag() {
+        if (resultFlag.isEmpty()) {
+            return 0;
+        }
+        return (int) resultFlag.toByteArray()[0];
+    }
+
+    private void getFlagFromFuture(CompletableFuture<Integer> future, Integer index) {
+        future.whenComplete((result, error) -> {
+            if (error == null) {
+                resultFlag.set(index);
+            }
+        });
+    }
+
+
+}

+ 59 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/inform/InformStrategy.java

@@ -0,0 +1,59 @@
+package com.inspur.customer.object.inform;
+
+import com.inspur.customer.context.inform.InformLevelEnum;
+import lombok.Getter;
+
+import java.io.Serializable;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-30 09:50
+ **/
+public class InformStrategy implements Serializable {
+
+    private static final long serialVersionUID = -7952204074632539933L;
+
+    @Getter
+    private Boolean email;
+
+    @Getter
+    private Boolean note;
+
+    @Getter
+    private Boolean weChat;
+
+    @Getter
+    private Boolean weChatApplet;
+
+    public InformStrategy(InformLevelEnum informLevelEnum) {
+        switch (informLevelEnum) {
+            case SINGLE_EMAIL: {
+                this.email = true;
+                break;
+            }
+            case SINGLE_NOTE : {
+                this.note = true;
+                break;
+            }
+            case TEST:
+            case  HINT : {
+                this.email = true;
+                this.note = false;
+                this.weChat = true;
+                this.weChatApplet = true;
+                break;
+            }
+            case INTERMEDIATE :
+            case URGENT : {
+                this.email = true;
+                this.note = true;
+                this.weChat = true;
+                this.weChatApplet = true;
+                break;
+            }
+            default : {
+                break;
+            }
+        }
+    }
+}

+ 110 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/tenant/ExceptionInformStrategyCmd.java

@@ -0,0 +1,110 @@
+package com.inspur.customer.object.tenant;
+
+import com.alibaba.cola.dto.Command;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.BitSet;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-07 18:39
+ **/
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ExceptionInformStrategyCmd extends Command {
+
+    private static final long serialVersionUID = 6924729697795216039L;
+
+    /**
+     * inform user by note
+     */
+    private Boolean note;
+
+    /**
+     * inform user by email
+     */
+    private Boolean email;
+
+    /**
+     * inform user by wechat
+     */
+    private Boolean wechat;
+
+    /**
+     * inform user by wechatApplet
+     */
+    private Boolean wechatApplet;
+
+    public ExceptionInformStrategyCmd() {
+
+    }
+
+    public ExceptionInformStrategyCmd(Integer integerFlag) {
+        byte[] byteFlag = new byte[]{integerFlag.byteValue()};
+        setFlag(byteFlag);
+    }
+
+    /**
+     * get inform strategy flag with bit identifier
+     * 从低位开始
+     * 0 位: note 1
+     * 1 位: email 2
+     * 2 位: weChat 4
+     * 3 位: weChatApplet 8
+     * @return strategy flag
+     */
+    @JsonIgnore
+    public Integer getStrategyFlag() {
+        BitSet bitSet = getStrategySet();
+        byte[] byteFlag = bitSet.toByteArray();
+        return (int) byteFlag[0];
+    }
+
+    @JsonIgnore
+    public BitSet getStrategySet() {
+        BitSet bitSet = new BitSet(4);
+        if (Boolean.TRUE.equals(note)) {
+            bitSet.set(0);
+        }
+        if (Boolean.TRUE.equals(email)) {
+            bitSet.set(1);
+        }
+        if (Boolean.TRUE.equals(wechat)) {
+            bitSet.set(2);
+        }
+        if (Boolean.TRUE.equals(wechatApplet)) {
+            bitSet.set(3);
+        }
+        return bitSet;
+    }
+
+    @JsonIgnore
+    public Integer getCount() {
+        int count = 0;
+        if (Boolean.TRUE.equals(note)) {
+            count += 1;
+        }
+        if (Boolean.TRUE.equals(email)) {
+            count += 1;
+        }
+        if (Boolean.TRUE.equals(wechat)) {
+            count += 1;
+        }
+        if (Boolean.TRUE.equals(wechatApplet)) {
+            count += 1;
+        }
+        return count;
+    }
+
+
+    private void setFlag(byte[] byteFlag) {
+        BitSet bitSet = BitSet.valueOf(byteFlag);
+        this.note = bitSet.get(0);
+        this.email = bitSet.get(1);
+        this.wechat = bitSet.get(2);
+        this.wechatApplet = bitSet.get(3);
+    }
+
+}

+ 55 - 0
smsb-customer-manager-client/src/main/java/com/inspur/customer/object/tenant/TenantExceptionInformStrategyCO.java

@@ -0,0 +1,55 @@
+package com.inspur.customer.object.tenant;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * tenant exception inform strategy
+ * @author linwenhua
+ * @date 2022-06-07 18:37
+ **/
+@Data
+public class TenantExceptionInformStrategyCO implements Serializable {
+
+    private static final long serialVersionUID = -2981913767151035603L;
+
+    public static final String HINT_LEVEL_KEY = "0";
+
+    public static final String MIDDLE_LEVEL_KEY = "1";
+
+    public static final String URGENT_LEVEL_KEY = "2";
+
+    public static final String TENANT_LEVEL_KEY = "3";
+
+    public static final String DEPARTMENT_LEVEL = "4";
+
+    /**
+     * tenant identifier
+     */
+    private String tenant;
+
+    /**
+     * exception inform strategy
+     */
+    private Map<String, ExceptionInformStrategyCmd> strategy;
+
+    public TenantExceptionInformStrategyCO() {
+        this.strategy = new HashMap<>(4);
+    }
+
+    public TenantExceptionInformStrategyCO(String tenant) {
+        this.tenant = tenant;
+        this.strategy = new HashMap<>(4);
+    }
+
+    public Integer getInformFlagByLevel(String level) {
+        return strategy.get(level).getStrategyFlag();
+    }
+
+    public void updateStrategy(String strategyKey, ExceptionInformStrategyCmd informStrategyCmd) {
+        this.strategy.put(strategyKey, informStrategyCmd);
+    }
+}

+ 14 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/inform/InformMessageContentRecordMapper.java

@@ -0,0 +1,14 @@
+package com.inspur.customer.infrastructure.mapper.inform;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.inspur.customer.infrastructure.object.inform.InformMessageContentRecordDO;
+import com.inspur.customer.infrastructure.object.inform.InformMessageRecordDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:08
+ **/
+@Mapper
+public interface InformMessageContentRecordMapper extends BaseMapper<InformMessageContentRecordDO> {
+}

+ 13 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/inform/InformMessageRecordMapper.java

@@ -0,0 +1,13 @@
+package com.inspur.customer.infrastructure.mapper.inform;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.inspur.customer.infrastructure.object.inform.InformMessageRecordDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-29 16:08
+ **/
+@Mapper
+public interface InformMessageRecordMapper extends BaseMapper<InformMessageRecordDO> {
+}

+ 13 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/mapper/tenant/TenantExceptionInformStrategyMapper.java

@@ -0,0 +1,13 @@
+package com.inspur.customer.infrastructure.mapper.tenant;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.inspur.customer.infrastructure.object.tenant.TenantExceptionInformStrategyDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author linwenhua
+ * @date 2022-04-12 18:42
+ **/
+@Mapper
+public interface TenantExceptionInformStrategyMapper extends BaseMapper<TenantExceptionInformStrategyDO> {
+}

+ 48 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/inform/InformMessageContentRecordDO.java

@@ -0,0 +1,48 @@
+package com.inspur.customer.infrastructure.object.inform;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * message content record
+ * @author linwenhua
+ * @date 2022-06-29 15:46
+ **/
+@Data
+@TableName("inform_message_content_record")
+public class InformMessageContentRecordDO implements Serializable {
+
+    private static final long serialVersionUID = 4564437666438735274L;
+
+    /**
+     * record id
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * tenant identifier
+     */
+    @TableField("tenant")
+    private String tenant;
+
+    /**
+     * inform flag
+     * bit 0: note
+     * bit 1: email
+     * bit 2: weChat
+     * bit 3: weChat applet
+     */
+    @TableField("inform_flag")
+    private Integer informFlag;
+
+    /**
+     * message map json
+     */
+    @TableField("message_map_json")
+    private String messageMapJson;
+}

+ 81 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/inform/InformMessageRecordDO.java

@@ -0,0 +1,81 @@
+package com.inspur.customer.infrastructure.object.inform;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.BitSet;
+
+/**
+ * record of message sending
+ * @author linwenhua
+ * @date 2022-06-29 15:46
+ **/
+@Data
+@TableName("inform_message_record")
+public class InformMessageRecordDO implements Serializable {
+
+    private static final long serialVersionUID = 493815370400441472L;
+
+    @TableId
+    private Long id;
+
+    /**
+     * content record id
+     * @see InformMessageContentRecordDO#getId()
+     */
+    @TableField("content_id")
+    private Long contentId;
+
+    /**
+     * tenant identifier
+     */
+    @TableField("tenant")
+    private String tenant;
+
+    /**
+     * department
+     */
+    @TableField("org")
+    private String org;
+
+    /**
+     * user id
+     */
+    @TableField("user_id")
+    private String userId;
+
+    /**
+     * message type
+     */
+    @TableField("type")
+    private Integer type;
+
+    /**
+     * inform flag
+     * bit 0: note
+     * bit 1: email
+     * bit 2: weChat
+     * bit 3: weChat applet
+     */
+    @TableField("inform_flag")
+    private Integer informFlag;
+
+    /**
+     * inform flag
+     * bit 0: note
+     * bit 1: email
+     * bit 2: weChat
+     * bit 3: weChat applet
+     */
+    @TableField("inform_status")
+    private Integer informStatus;
+
+    public BitSet getBitMap() {
+        byte[] byteFlag = new byte[]{informFlag.byteValue()};
+        return BitSet.valueOf(byteFlag);
+    }
+
+}

+ 32 - 0
smsb-customer-manager-infrastructure/src/main/java/com/inspur/customer/infrastructure/object/tenant/TenantExceptionInformStrategyDO.java

@@ -0,0 +1,32 @@
+package com.inspur.customer.infrastructure.object.tenant;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author linwenhua
+ * @date 2022-06-08 11:41
+ **/
+@Data
+@TableName("tenant_exception_inform_strategy")
+public class TenantExceptionInformStrategyDO implements Serializable {
+
+    private static final long serialVersionUID = 4637196747617452014L;
+
+    @TableId(value = "tenant", type = IdType.INPUT)
+    private String tenant;
+
+    @TableField("hint_level_flag")
+    private Integer hintLevelFlag;
+
+    @TableField("middle_level_flag")
+    private Integer middleLevelFlag;
+
+    @TableField("urgency_level_flag")
+    private Integer urgencyLevelFlag;
+}

+ 5 - 0
smsb-customer-manager-infrastructure/src/main/resources/mapper/inform/InformMessageContentRecordMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.inspur.customer.infrastructure.mapper.inform.InformMessageContentRecordMapper">
+
+</mapper>

+ 5 - 0
smsb-customer-manager-infrastructure/src/main/resources/mapper/inform/InformMessageRecordMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.inspur.customer.infrastructure.mapper.inform.InformMessageRecordMapper">
+
+</mapper>

+ 5 - 0
smsb-customer-manager-infrastructure/src/main/resources/mapper/tenant/TenantExceptionInformStrategyMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.inspur.customer.infrastructure.mapper.tenant.TenantExceptionInformStrategyMapper">
+
+</mapper>

+ 2 - 0
smsb-customer-manager-start-web/src/main/java/com/inspur/customer/SmsbCustomerWebApplication.java

@@ -3,6 +3,7 @@ package com.inspur.customer;
 import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
 
 /**
  * 用户管理模块启动类
@@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
  * @author wangbo
  */
 @EnableDubbo
+@EnableAsync
 @SpringBootApplication
 public class SmsbCustomerWebApplication {
 

+ 79 - 0
smsb-customer-manager-start-web/src/test/java/com/inspur/customer/MessageHandlerTest.java

@@ -0,0 +1,79 @@
+package com.inspur.customer;
+
+import com.inspur.customer.object.inform.CommonMessageCO;
+import com.inspur.customer.service.inform.handler.EmailMessageHandler;
+import com.inspur.customer.service.inform.handler.WeChatAppletMessageHandler;
+import com.inspur.customer.service.inform.handler.WeChatMessageHandler;
+import com.inspur.inform.object.applet.WeChatAppletUserDataDto;
+import com.inspur.inform.object.applet.message.WxAppletUserMessageDto;
+import com.inspur.inform.object.message.EmailMessage;
+import com.inspur.inform.object.message.WechatMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author linwenhua
+ * @date 2022-07-01 13:56
+ **/
+@Slf4j
+class MessageHandlerTest {
+
+    private final EmailMessageHandler emailMessageHandler = new EmailMessageHandler();
+
+    private final WeChatAppletMessageHandler weChatAppletMessageHandler = new WeChatAppletMessageHandler();
+
+    private final WeChatMessageHandler weChatMessageHandler = new WeChatMessageHandler();
+
+    @Test
+    void testEmail() throws IOException {
+        CommonMessageCO commonMessageCo = new CommonMessageCO();
+        commonMessageCo.setSubject("测试");
+        Map<String, String> attributes = new HashMap<>(10);
+        attributes.put("MSRlevel", "紧急");
+        attributes.put("MSRdevice", "紧急");
+        attributes.put("MSRarea", "紧急");
+        attributes.put("MSRtime", "紧急");
+        commonMessageCo.setMessageMap(attributes);
+        EmailMessage emailMessage = emailMessageHandler.makeEmailMessage(commonMessageCo, "BatchDeviceEmptyOrchestration", Collections.emptyList());
+        log.info("message: {}", emailMessage);
+    }
+
+    @Test
+    void testApplet() throws IOException {
+        CommonMessageCO commonMessageCo = new CommonMessageCO();
+        commonMessageCo.setSubject("测试");
+        Map<String, String> attributes = new HashMap<>(10);
+        attributes.put("MSRlevel", "紧急");
+        attributes.put("MSRdevice", "紧急");
+        attributes.put("MSRarea", "紧急");
+        attributes.put("MSRtime", "紧急");
+        commonMessageCo.setMessageMap(attributes);
+        WxAppletUserMessageDto wxAppletUserMessageDto = weChatAppletMessageHandler.makeWeChatAppletMessage(commonMessageCo, "MultiWarn");
+        log.info("message: {}", wxAppletUserMessageDto);
+    }
+
+    @Test
+    void testWeChat() throws IOException {
+        CommonMessageCO commonMessageCo = new CommonMessageCO();
+        commonMessageCo.setSubject("测试");
+        Map<String, String> attributes = new HashMap<>(10);
+        attributes.put("keyword1", "紧急");
+        attributes.put("keyword3", "紧急");
+        commonMessageCo.setMessageMap(attributes);
+        WechatMessage wechatMessage = weChatMessageHandler.makeWeChatMessage(commonMessageCo, Collections.emptyList(), "device");
+        log.info("message: {}", wechatMessage);
+    }
+
+    @Test
+    void testBitset() {
+        BitSet bitSet = new BitSet(4);
+        bitSet.set(2);
+        log.info("size: {}", bitSet.length());
+    }
+}