diff --git a/README.md b/README.md index ccb4fd46..11e643ac 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # inside-notices 站内信消息通知模块 -# message-notices +# msg-notices 短信消息通知模块 # wx-notices 微信消息通知模块 diff --git a/wx-notices/src/main/java/cn/axzo/msgcenter/Main.java b/inside-notices/src/main/java/cn/axzo/inside/notices/Main.java similarity index 77% rename from wx-notices/src/main/java/cn/axzo/msgcenter/Main.java rename to inside-notices/src/main/java/cn/axzo/inside/notices/Main.java index ab2d5480..444c1c15 100644 --- a/wx-notices/src/main/java/cn/axzo/msgcenter/Main.java +++ b/inside-notices/src/main/java/cn/axzo/inside/notices/Main.java @@ -1,4 +1,4 @@ -package cn.axzo.msgcenter; +package cn.axzo.inside.notices; public class Main { public static void main(String[] args) { diff --git a/msg-center-webapi/src/main/java/cn/axzo/msgcenter/Main.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/Main.java similarity index 50% rename from msg-center-webapi/src/main/java/cn/axzo/msgcenter/Main.java rename to msg-center-api/src/main/java/cn/axzo/msg/center/api/Main.java index ab2d5480..7ba0e1cb 100644 --- a/msg-center-webapi/src/main/java/cn/axzo/msgcenter/Main.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/Main.java @@ -1,7 +1,8 @@ -package cn.axzo.msgcenter; +package cn.axzo.msg.center.api; public class Main { + public static void main(String[] args) { - System.out.println("Hello world!"); + System.out.println("aa"); } -} \ No newline at end of file +} diff --git a/message-notices/src/main/java/cn/axzo/msgcenter/Main.java b/msg-center-webapi/src/main/java/cn/axzo/msg/center/webapi/Main.java similarity index 76% rename from message-notices/src/main/java/cn/axzo/msgcenter/Main.java rename to msg-center-webapi/src/main/java/cn/axzo/msg/center/webapi/Main.java index ab2d5480..5c856f11 100644 --- a/message-notices/src/main/java/cn/axzo/msgcenter/Main.java +++ b/msg-center-webapi/src/main/java/cn/axzo/msg/center/webapi/Main.java @@ -1,4 +1,4 @@ -package cn.axzo.msgcenter; +package cn.axzo.msg.center.webapi; public class Main { public static void main(String[] args) { diff --git a/msg-notices/msg-notices-client/pom.xml b/msg-notices/msg-notices-client/pom.xml new file mode 100644 index 00000000..0a2f2813 --- /dev/null +++ b/msg-notices/msg-notices-client/pom.xml @@ -0,0 +1,92 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.client + msg-notices-client + + + 8 + 8 + UTF-8 + + + + + + cn.axzo.mns + mns-http-api + + + org.springframework.boot + spring-boot-starter-web + + + cn.axzo.framework + axzo-logger-spring-boot-starter + + + org.apache.httpcomponents + httpclient + + + com.xuxueli + xxl-job-core + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + cn.axzo.trade + trade-data-security-spring-boot-starter + + + cn.hutool + hutool-all + + + cn.axzo.msg.notices.service.api + msg-notices-service-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.common + msg-notices-common + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.integration + msg-notices-integration + 1.0.0-SNAPSHOT + compile + + + + + mns-client + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/Bootstrap.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/Bootstrap.java new file mode 100644 index 00000000..5d76787e --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/Bootstrap.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.client; + +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +/** + * 消息通知服务启动类 + * + * @author zhaoyong_sh + * @see Bootstrap + * @since 2021-05-17 15:41 + */ +@Slf4j +@MapperScan(basePackages = {"cn.axzo.msg.notices.dao.mapper"}) +@SpringBootApplication(scanBasePackages = {"cn.axzo.mns"}) +@EnableFeignClients(basePackages = "cn.axzo.log") +public class Bootstrap { + + public static void main(String[] args) { + log.info("axzo mns begin starting..."); + SpringApplication.run(Bootstrap.class, args); + log.info("axzo mns start success"); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/annotation/PlatCheckSign.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/annotation/PlatCheckSign.java new file mode 100644 index 00000000..287ee77a --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/annotation/PlatCheckSign.java @@ -0,0 +1,15 @@ +package cn.axzo.msg.notices.client.annotation; + +import java.lang.annotation.*; + +/** + * 平台验签 + * + * @author wangjibo + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PlatCheckSign { + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/aspect/PlatCheckSignAspect.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/aspect/PlatCheckSignAspect.java new file mode 100644 index 00000000..60452cb6 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/aspect/PlatCheckSignAspect.java @@ -0,0 +1,103 @@ +package cn.axzo.msg.notices.client.aspect; + +import cn.axzo.msg.notices.client.annotation.PlatCheckSign; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.hutool.crypto.SecureUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Objects; + +@Slf4j +@Aspect +@Order(1) +@Component +public class PlatCheckSignAspect { + + private static final String appKey = "mns"; + + // mns-plat 32位小写 + private static final String appSecret = "dd744893b1a3470269d0f687961ed3b2"; + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)") + public void requestMapping() { + } + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.PostMapping)") + public void postMapping() { + } + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.GetMapping)") + public void getMapping() { + } + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.PutMapping)") + public void putMapping() { + } + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.DeleteMapping)") + public void deleteMapping() { + } + + @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.PatchMapping)") + public void patchMapping() { + } + + @Pointcut("requestMapping() || postMapping() || getMapping() || putMapping() || deleteMapping()|| patchMapping()") + public void mappingAnnotations() { + } + + /** + * 切入含有@PlatCheckSign && @RestController 注解的类 + */ + @Before(value = "@within(platCheckSign) && @within(restController)") + public void classHandler(JoinPoint joinPoint, PlatCheckSign platCheckSign, RestController restController) { + handle(joinPoint, platCheckSign); + } + + /** + * 切入含有@PlatCheckSign && @RequestMapping/@PostMapping/@GetMapping/@PutMapping/@DeleteMapping/@PatchMapping 之一注解的方法 + */ + @Before(value = "@annotation(platCheckSign) && mappingAnnotations()") + public void methodHandler(JoinPoint joinPoint, PlatCheckSign platCheckSign) { + handle(joinPoint, platCheckSign); + } + + @SneakyThrows + public void handle(JoinPoint joinPoint, PlatCheckSign platCheckSign) { + // 验签 + sign(); + } + + private void sign() { + HttpServletRequest httpRequest = ((ServletRequestAttributes) Objects + .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); + String reqAppKey = httpRequest.getHeader("appKey"); + String reqBusinessNo = httpRequest.getHeader("businessNo"); + String reqTimestamp = httpRequest.getHeader("timestamp"); + String reqSign = httpRequest.getHeader("sign"); + + if(!StringUtils.equals(appKey, reqAppKey)){ + throw new BizException(ReturnCodeEnum.FAIL,"验签失败"); + } + String msg = "appKey=" + reqAppKey + "&appSecret="+ appSecret + "&businessNo=" + (reqBusinessNo == null ? "" : reqBusinessNo) + "×tamp=" + reqTimestamp; + log.info(msg); + String checkSign = SecureUtil.md5(msg); + log.info(checkSign); + if(!StringUtils.equals(checkSign, reqSign)){ + throw new BizException(ReturnCodeEnum.FAIL,"验签失败"); + } + } +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/DatasourceConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/DatasourceConfig.java new file mode 100644 index 00000000..a15ebdae --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/DatasourceConfig.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.client.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; + +/** + * 数据库配置 + * + * @author zhaoyong_sh + * @see DatasourceConfig + * @since 2021-05-27 16:27 + */ +@Configuration +public class DatasourceConfig { + + @Bean(name = "transactionTemplate") + public TransactionTemplate transactionTemplate(DataSource dataSource) { + TransactionTemplate transactionTemplate = new TransactionTemplate(); + DataSourceTransactionManager platformTransactionManager = new DataSourceTransactionManager(); + platformTransactionManager.setDataSource(dataSource); + transactionTemplate.setTransactionManager(platformTransactionManager); + return transactionTemplate; + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/EntityMetaObjectHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/EntityMetaObjectHandler.java new file mode 100644 index 00000000..24449e4c --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/EntityMetaObjectHandler.java @@ -0,0 +1,46 @@ +package cn.axzo.msg.notices.client.config; + +import cn.axzo.msg.notices.dao.persistence.BaseEntity; +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; + +import java.util.Date; + +@Slf4j +public class EntityMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + Object entity = metaObject.getOriginalObject(); + Date now = new Date(); + if (entity instanceof BaseEntity) { + //默认有值不覆盖 + this.fillStrategy(metaObject, "createAt", now); + this.fillStrategy(metaObject, "updateAt", now); + } + + if (entity instanceof BaseOwnEntity) { + //默认有值不覆盖 + this.fillStrategy(metaObject, "createBy", ""); + this.fillStrategy(metaObject, "updateBy", ""); + } + } + + @Override + public void updateFill(MetaObject metaObject) { + Object entity = metaObject.getOriginalObject(); + if (entity instanceof BaseEntity) { + //强制覆盖 + this.setFieldValByName("updateAt", new Date(), metaObject); + } + + if (entity instanceof BaseOwnEntity) { + //强制覆盖 + this.setFieldValByName("updateBy", "", metaObject); + } + } + + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/LoggerConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/LoggerConfig.java new file mode 100644 index 00000000..7bdbca56 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/LoggerConfig.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.client.config; + +import cn.azxo.framework.common.logger.MethodAroundLogAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 日志配置 + * + * @author zhaoyong + * @see LoggerConfig + * @since 2021-08-19 20:09 + */ +@Configuration +public class LoggerConfig { + + @Bean + public MethodAroundLogAspect methodAroundLogAspect(){ + return new MethodAroundLogAspect(); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/MybatisPlusConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/MybatisPlusConfig.java new file mode 100644 index 00000000..c8c2aa98 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/MybatisPlusConfig.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.client.config; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Mybatis Plus Config + * + * @author zhaoyong_sh + * @see MybatisPlusConfig + * @since 2021-05-19 10:24 + */ +@Configuration +public class MybatisPlusConfig { + + /** + * 默认不配置分页插件的,会使用人RowBound进行分页,实际上是逻辑分页,物理上不会分页,也就是查询出来 + * 缓存中再分页;这样对于数据量比较多的情况,不合适,因此需要配置这个分页拦截器来实现物理的分页; + * @return + */ + @Bean + public PaginationInterceptor paginationInterceptor() { + PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); + // 设置分页的最大条数 + return paginationInterceptor; + } + + @Bean + public EntityMetaObjectHandler EntityMetaObjectHandler() { + return new EntityMetaObjectHandler(); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/RestTemplateConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/RestTemplateConfig.java new file mode 100644 index 00000000..d14b5d57 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/RestTemplateConfig.java @@ -0,0 +1,80 @@ +package cn.axzo.msg.notices.client.config; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** + * @ClassName RestTemplateConfig + * @Description 服务调用模板配置 + * @Author xinxiang_jiang@foxmail.com + * @Date 2020/10/21 3:17 + * @Version 1.0 + **/ +@Configuration +public class RestTemplateConfig { + + @Value("${http.pool.max.total:200}") + private int maxTotal; + + @Value("${http.pool.default-max-per-route:100}") + private int defaultMaxPerRoute; + + @Value("${http.pool.connect.timeout:20000}") + private int connectTimeout; + + @Value("${http.pool.connection.request.timeout:20000}") + private int connectionRequestTimeout; + + @Value("${http.pool.socket.timeout:60000}") + private int socketTimeout; + + @Value("${http.pool.validate.after.inactivity:2000}") + private int validateAfterInactivity; + + @Bean("restTemplate") + public RestTemplate notifyTemplate() { + return new RestTemplate(httpRequestFactory()); + } + + @Bean + public ClientHttpRequestFactory httpRequestFactory() { + return new HttpComponentsClientHttpRequestFactory(httpClient()); + } + + @Bean + public HttpClient httpClient() { + Registry registry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); + connectionManager.setMaxTotal(maxTotal); + connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); + connectionManager.setValidateAfterInactivity(validateAfterInactivity); + RequestConfig requestConfig = RequestConfig.custom() + //服务器返回数据(response)的时间,超过抛出read timeout + .setSocketTimeout(socketTimeout) + //连接上服务器(握手成功)的时间,超出抛出connect timeout + .setConnectTimeout(connectTimeout) + //从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool + .setConnectionRequestTimeout(connectionRequestTimeout) + .build(); + return HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(connectionManager) + .build(); + } +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/WebMvcConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/WebMvcConfig.java new file mode 100644 index 00000000..9828b445 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/WebMvcConfig.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.client.config; + +import cn.azxo.framework.common.logger.WebLogMdcHandlerInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * Spring MVC Config + * + * @author zhaoyong_sh + * @see WebMvcConfig + * @since 2021-05-20 20:27 + */ +@Configuration +@EnableWebMvc +public class WebMvcConfig implements WebMvcConfigurer { + + /** + * 添加拦截器 + * @param registry + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new WebLogMdcHandlerInterceptor()); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/XxlJobConfig.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/XxlJobConfig.java new file mode 100644 index 00000000..ccdb3f29 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/config/XxlJobConfig.java @@ -0,0 +1,63 @@ +package cn.axzo.msg.notices.client.config; + +import cn.azxo.framework.common.service.JobParamResolver; +import cn.azxo.framework.common.spring.condition.NonLocalEnvironment; +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Xxl Job Config + * + * @author zhaoyong_sh + * @see XxlJobConfig + * @since 2021-05-19 10:26 + */ +@Slf4j +@Configuration +public class XxlJobConfig { + + @Value("${xxl.job.admin.addresses}") + private String adminAddresses; + + @Value("${xxl.job.executor.appName}") + private String appName; + + @Value("${xxl.job.executor.ip:}") + private String ip; + + @Value("${xxl.job.executor.port}") + private int port; + + @Value("${xxl.job.accessToken:}") + private String accessToken; + + @Value("${xxl.job.executor.logPath:}") + private String logPath; + + @Value("${xxl.job.executor.logRetentionDays}") + private int logRetentionDays; + + @Bean + @NonLocalEnvironment + public XxlJobSpringExecutor xxlJobExecutor() { + log.info(">>>>>>>>>>> axzo mns service xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAppname(appName); + xxlJobSpringExecutor.setIp(ip); + xxlJobSpringExecutor.setPort(port); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setLogPath(logPath); + xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); + return xxlJobSpringExecutor; + } + + @Bean + public JobParamResolver jobParamResolver(){ + return new JobParamResolver(); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/IndexController.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/IndexController.java new file mode 100644 index 00000000..f4224920 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/IndexController.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.client.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * 心跳控制器 + * + * @author zhaoyong_sh + * @see IndexController + * @since 2021-04-29 11:32 + */ +@RestController +public class IndexController { + + @RequestMapping(value = "/checkDeath", method = RequestMethod.GET) + public String index(){ + return "ok"; + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageCallbackController.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageCallbackController.java new file mode 100644 index 00000000..ed61b363 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageCallbackController.java @@ -0,0 +1,77 @@ +package cn.axzo.msg.notices.client.controller; + +import cn.axzo.msg.notices.common.enums.MessageChannelEnum; +import cn.axzo.msg.notices.common.lang.LoggerTemplate; +import cn.axzo.msg.notices.common.utils.KeyUtils; +import cn.axzo.msg.notices.integration.client.DingDingClient; +import cn.axzo.msg.notices.manager.api.dto.request.AliMessageCallbackRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.ChuangLanSmsReportRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.AliCallbackResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.ChuangLanCallbackResponseDto; +import cn.axzo.msg.notices.service.api.MessageCallbackService; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + + +/** + * @author: szg + * @Date: 2021/5/28 15:49 + * @Description: 消息回调处理 + */ +@Slf4j +@RestController +@RequestMapping(value = "/webApi") +public class MessageCallbackController { + + @Resource(name = "messageCallbackService") + private MessageCallbackService messageCallbackService; + + @Resource(name = "dingDingClient") + private DingDingClient dingDingClient; + + @Resource(name = "loggerTemplate") + private LoggerTemplate loggerTemplate; + + + /** + * 阿里云回调 + * @param request + * @return + */ + @PostMapping(value = "/ali/status/callback") + public AliCallbackResponseDto aliCallbackHandle( + @RequestBody List request) { + log.info("MessageCallbackController#aliCallbackHandle request param is {}", + JSON.toJSONString(request)); + return messageCallbackService.aliCallbackHandle(request); + } + + + /** + * 创蓝回调 + * @param request + * @return + */ + @GetMapping(value = "/chuangLan/status/callback") + public ChuangLanCallbackResponseDto chuangLanCallbackHandle(ChuangLanSmsReportRequestDto request){ + log.info("MessageCallbackController#chuangLanCallbackHandle request param is {}", JSON.toJSONString(request)); + + if(StringUtils.isBlank(request.getMsgid()) || + StringUtils.isBlank(request.getMobile()) || + StringUtils.isBlank(request.getUid())) { + dingDingClient.notifyChannelCallback(MessageChannelEnum.CHUANG_LAN.getCode(), + JSON.toJSONString(request), "msgId and mobile and uid must not be null"); + log.info("MessageCallbackController#chuangLanCallbackHandle request param format is error"); + return ChuangLanCallbackResponseDto.success(); + } + + String traceId = KeyUtils.getKey(request.getMsgid(), request.getMobile()); + return loggerTemplate.execute(()-> messageCallbackService.chuangLanCallbackHandle(request),traceId); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageNotifyController.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageNotifyController.java new file mode 100644 index 00000000..64455b41 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/MessageNotifyController.java @@ -0,0 +1,59 @@ +package cn.axzo.msg.notices.client.controller; + +import cn.axzo.msg.notices.common.annotation.PushOperation; +import cn.axzo.mns.http.api.MessageNotifyApi; +import cn.axzo.mns.http.model.request.SendBatchMessageRequest; +import cn.axzo.mns.http.model.request.SendMobileMessageRequest; +import cn.axzo.msg.notices.manager.api.dto.request.SendMessageRequestDto; +import cn.axzo.msg.notices.service.api.MessageService; +import cn.azxo.framework.common.logger.MethodAroundLog; +import cn.azxo.framework.common.model.CommonResponse; +import cn.azxo.framework.common.utils.LogUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 消息发送 Controller + * + * @author zhaoyong_sh + * @see MessageNotifyController + * @since 2021-05-20 11:33 + */ +@RestController +@Slf4j +public class MessageNotifyController implements MessageNotifyApi { + + @Resource + private MessageService messageService; + + @Resource + private GenericConversionService genericConversionService; + + @Override + @MethodAroundLog(source = "业务方", target = "mns", value = "发送单条短信") + @PushOperation("发送短信") + public CommonResponse sendMobileMessage(@RequestBody @Valid SendMobileMessageRequest request) { + // 转换对象 + SendMessageRequestDto requestDto = genericConversionService.convert(request, SendMessageRequestDto.class); + + // 发送短信 + messageService.sendMessage(requestDto); + + // 响应请求 + return CommonResponse.success(); + } + + @Override + @MethodAroundLog(source = "业务方", target = "mns", value = "发送批量短信", requestExcludeName = {"smsContents"}) + public CommonResponse sendBatchMessage(@RequestBody @Valid SendBatchMessageRequest request) { + + LogUtil.error("请联系管理员,批量发送短信功能已弃用"); + return CommonResponse.fail("请联系管理员,批量发送短信功能已弃用"); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/PlatController.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/PlatController.java new file mode 100644 index 00000000..3630d5a3 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/controller/PlatController.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.notices.client.controller; + + +import cn.axzo.msg.notices.client.annotation.PlatCheckSign; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.manager.api.dto.request.plat.CreateTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.plat.QueryTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.plat.QueryTemplateResponseDto; +import cn.axzo.msg.notices.service.api.PlatService; +import cn.azxo.framework.common.model.CommonResponse; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RequestMapping("/plat") +@RestController +@PlatCheckSign +public class PlatController { + + @Resource + private PlatService platService; + + @PostMapping("/create") + public CommonResponse createTemplate(@RequestBody CreateTemplateRequestDto request){ + platService.createTemplate(request); + return CommonResponse.success(); + } + + @RequestMapping("/getByTemplateNo") + public CommonResponse getByTemplateNo(String templateNo){ + return CommonResponse.success(platService.getByTemplateNo(templateNo)); + } + + @PostMapping("/list") + public CommonResponse> list(@RequestBody QueryTemplateRequestDto request){ + return CommonResponse.success(platService.list(request)); + } + + @GetMapping("/delete") + public CommonResponse delete(String templateNo){ + platService.delete(templateNo); + return CommonResponse.success(); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendBatchMessageRequestToDtoConverter.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendBatchMessageRequestToDtoConverter.java new file mode 100644 index 00000000..576130ef --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendBatchMessageRequestToDtoConverter.java @@ -0,0 +1,47 @@ +package cn.axzo.msg.notices.client.converters; + +import cn.axzo.mns.http.model.request.SendBatchMessageRequest; +import cn.axzo.mns.http.model.request.SmsContent; +import cn.axzo.msg.notices.manager.api.dto.request.SendBatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.List; + +/** + * SendBatchMessageRequest 转换器 + * + * @author zhaoyong + * @see SendBatchMessageRequestToDtoConverter + * @since 2021-08-07 16:37 + */ +@Component +public class SendBatchMessageRequestToDtoConverter implements + Converter { + + @Override + public SendBatchMessageRequestDto convert(SendBatchMessageRequest source) { + Assert.notNull(source, "source must not be null"); + SendBatchMessageRequestDto dto = new SendBatchMessageRequestDto(); + dto.setRequestNo(source.getRequestNo()); + dto.setAppCode(source.getAppCode()); + dto.setSendType(source.getSendType()); + dto.setTemplateNo(source.getTemplateNo()); + List smsContents = source.getSmsContents(); + if(CollectionUtils.isNotEmpty(smsContents)) { + List smsDtos = new ArrayList<>(); + for (SmsContent content : smsContents) { + SmsContentDto smsDto = new SmsContentDto(); + smsDto.setPhoneNo(content.getPhoneNo()); + smsDto.setTemplateParams(content.getTemplateParams()); + smsDtos.add(smsDto); + } + dto.setSmsContentDtos(smsDtos); + } + return dto; + } +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendMobileMessageRequestToDtoConverter.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendMobileMessageRequestToDtoConverter.java new file mode 100644 index 00000000..3f2a0b73 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/converters/SendMobileMessageRequestToDtoConverter.java @@ -0,0 +1,33 @@ +package cn.axzo.msg.notices.client.converters; + +import cn.axzo.mns.http.model.request.SendMobileMessageRequest; +import cn.axzo.msg.notices.manager.api.dto.request.SendMessageRequestDto; +import cn.hutool.core.lang.Assert; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +/** + * 发送消息请求对象 VO 转 dto + * + * @author zhaoyong_sh + * @see SendMobileMessageRequestToDtoConverter + * @since 2021-05-27 18:27 + */ +@Component +public class SendMobileMessageRequestToDtoConverter implements + Converter { + + @Override + public SendMessageRequestDto convert(SendMobileMessageRequest source) { + Assert.notNull(source, "source must not be null"); + SendMessageRequestDto dto = new SendMessageRequestDto(); + dto.setRequestNo(source.getRequestNo()); + dto.setAppCode(source.getAppCode()); + dto.setPhoneNo(source.getPhoneNo()); + dto.setTemplateNo(source.getTemplateNo()); + dto.setParams(source.getParams()); + dto.setExpansion(source.getExpansion()); + return dto; + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/handler/ControllerExceptionHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/handler/ControllerExceptionHandler.java new file mode 100644 index 00000000..a3512812 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/handler/ControllerExceptionHandler.java @@ -0,0 +1,76 @@ +package cn.axzo.msg.notices.client.handler; + +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.integration.client.DingDingClient; +import cn.azxo.framework.common.model.CommonResponse; +import cn.azxo.framework.common.utils.LogUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.annotation.Resource; + +/** + * Spring MVC 统一异常处理 + * + * @author zhaoyong_sh + * @see ControllerExceptionHandler + * @since 2021-05-17 15:44 + */ +@Slf4j +@RestControllerAdvice +public class ControllerExceptionHandler { + + @Resource(name = "dingDingClient") + private DingDingClient dingDingClient; + + @ExceptionHandler(value = BizException.class) + public CommonResponse bizException(BizException e){ + log.warn("[mns] ControllerExceptionHandler.bizException Exception", e); + return CommonResponse.error(e.getBizCode(), e.getMessage()); + } + + @ExceptionHandler(value = IllegalArgumentException.class) + public CommonResponse handleIllegalArgumentException(IllegalArgumentException e) { + LogUtil.error("[mns] ControllerExceptionHandler.handleIllegalArgumentException Exception message ", e); + return CommonResponse.error(ReturnCodeEnum.INVALID_PARAMETER.getCode(), e.getMessage()); + } + + @ExceptionHandler(value = DuplicateKeyException.class) + public CommonResponse handleDuplicateKeyException(DuplicateKeyException e) { + LogUtil.error("[mns] ControllerExceptionHandler.handleDuplicateKeyException Exception message ", e); + return CommonResponse.error(ReturnCodeEnum.REPEATED_REQUEST.getCode(), e.getCause().getMessage()); + } + + @ExceptionHandler(value = Exception.class) + public CommonResponse handleOtherException(Exception e) { + LogUtil.error(LogUtil.ErrorType.ERROR_SYSTEM, "[mns] ControllerExceptionHandler.handleOtherException Exception", e); + return CommonResponse.error(ReturnCodeEnum.SYSTEM_ERROR.getCode(), ReturnCodeEnum.SYSTEM_ERROR.getMessage()); + } + + @ExceptionHandler(value = Throwable.class) + public CommonResponse handleThrowableException(Throwable e) { + LogUtil.error(LogUtil.ErrorType.ERROR_SYSTEM, "[mns] ControllerExceptionHandler.handleThrowableException Exception", e); + return CommonResponse.error(ReturnCodeEnum.SYSTEM_ERROR.getCode(), ReturnCodeEnum.SYSTEM_ERROR.getMessage()); + } + + @ExceptionHandler(value = MethodArgumentNotValidException.class) + public CommonResponse handleArgumentValidException(MethodArgumentNotValidException e){ + log.warn("[mns] ControllerExceptionHandler.handleArgumentValidException Exception", e.getMessage()); + BindingResult bindingResult = e.getBindingResult(); + StringBuilder errorMsg = new StringBuilder(); + for (FieldError fieldError : bindingResult.getFieldErrors()) { + if (-1 == errorMsg.indexOf(fieldError.getDefaultMessage())) { + errorMsg.append(fieldError.getDefaultMessage()).append(","); + } + } + errorMsg.deleteCharAt(errorMsg.length() - 1); + return CommonResponse.error(ReturnCodeEnum.INVALID_PARAMETER.getCode(), errorMsg.toString()); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerRequestBodyAdvice.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerRequestBodyAdvice.java new file mode 100644 index 00000000..e420affb --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerRequestBodyAdvice.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.client.interceptor; + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter; + +import java.lang.reflect.Type; + +/** + * 请求对象打印日志 + * + * @author zhaoyong_sh + * @see LoggerRequestBodyAdvice + * @since 2021-05-19 10:31 + */ +@Slf4j +@ControllerAdvice +public class LoggerRequestBodyAdvice extends RequestBodyAdviceAdapter { + + @Override + public boolean supports(MethodParameter methodParameter, Type targetType, + Class> converterType) { + return methodParameter.hasParameterAnnotation(RequestBody.class); + } + + @Override + public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, + Class> converterType) { + String simpleClassName = parameter.getDeclaringClass().getSimpleName(); + String methodName = parameter.getMethod().getName(); + log.info(simpleClassName + "#" + methodName + " request body is {}", JSON.toJSONString(body)); + return body; + } +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerResponseBodyAdvice.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerResponseBodyAdvice.java new file mode 100644 index 00000000..b98e8512 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/interceptor/LoggerResponseBodyAdvice.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.client.interceptor; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +/** + * 统一日志打印 + * + * @author zhaoyong_sh + * @see LoggerResponseBodyAdvice + * @since 2021-05-19 10:28 + */ +@Slf4j +@ControllerAdvice +public class LoggerResponseBodyAdvice implements ResponseBodyAdvice { + + @Override + public boolean supports(MethodParameter methodParameter, Class aClass) { + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, + ServerHttpRequest request, ServerHttpResponse response) { + String path = request.getURI().getPath(); + if(!CommonConstants.HEARTBEAT_URI.equals(path)) { + log.info("axzo mns request path : " + path + ", response is {}", JSON.toJSONString(body)); + } + return body; + } + +} + diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerCallback.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerCallback.java new file mode 100644 index 00000000..4c751ed1 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerCallback.java @@ -0,0 +1,19 @@ +package cn.axzo.msg.notices.client.task; + +/** + * 任务日志模板回调 + * + * @author zhaoyong_sh + * @see JobLoggerCallback + * @since 2021-05-20 19:20 + */ +@FunctionalInterface +public interface JobLoggerCallback { + + /** + * 任务操作 + * @return + */ + T doInExecute(); + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerTemplate.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerTemplate.java new file mode 100644 index 00000000..a263300c --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/JobLoggerTemplate.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.client.task; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +/** + * 任务日志模板类 + * + * @author zhaoyong_sh + * @see JobLoggerTemplate + * @since 2021-05-20 19:19 + */ +@Component("jobLoggerTemplate") +public class JobLoggerTemplate { + + public T execute(JobLoggerCallback action){ + String uuid = UUID.randomUUID().toString(); + MDC.put(CommonConstants.CTX_LOG_ID_MDC, uuid); + try { + return action.doInExecute(); + } finally { + MDC.clear(); + } + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/LoggerJobHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/LoggerJobHandler.java new file mode 100644 index 00000000..d8271383 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/LoggerJobHandler.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.client.task; + +import cn.axzo.msg.notices.service.api.TaskService; +import cn.azxo.framework.common.service.JobParamResolver; +import com.xxl.job.core.biz.model.ReturnT; + +import javax.annotation.Resource; + +/** + * 日志 + * + * @author zhaoyong + * @see LoggerJobHandler + * @since 2021-08-24 20:56 + */ +public abstract class LoggerJobHandler { + + @Resource(name = "jobParamResolver") + protected JobParamResolver jobParamResolver; + + @Resource(name = "taskService") + protected TaskService taskService; + + @Resource(name = "jobLoggerTemplate") + protected JobLoggerTemplate jobLoggerTemplate; + + public abstract ReturnT execute(String param); + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/BatchMessageRequestCountCompensation.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/BatchMessageRequestCountCompensation.java new file mode 100644 index 00000000..d7a60ee2 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/BatchMessageRequestCountCompensation.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.compensation; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 批量请求计数补偿 + * + * @author zhaoyong + * @see BatchMessageRequestCountCompensation + * @since 2021-08-24 20:55 + */ +@Slf4j +@Component +public class BatchMessageRequestCountCompensation extends LoggerJobHandler { + + @Override + @XxlJob(value = "batchMessageRequestCountCompensation") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("BatchMessageRequestCountCompensation.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("BatchMessageRequestCountCompensation.execute task request is {}", JSON.toJSONString(request)); + taskService.batchMessageRequestCountCompensation(request); + } catch (Exception e) { + LogUtil.error("BatchMessageRequestCountCompensation.execute is error", e); + return ReturnT.FAIL; + } + log.info("BatchMessageRequestCountCompensation.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageRequestSplitCompensation.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageRequestSplitCompensation.java new file mode 100644 index 00000000..0166a43f --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageRequestSplitCompensation.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.compensation; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 实时批量消息请求拆分补偿任务 + * + * @author zhaoyong + * @see RealBatchMessageRequestSplitCompensation + * @since 2021-08-24 12:59 + */ +@Slf4j +@Component +public class RealBatchMessageRequestSplitCompensation extends LoggerJobHandler { + + @Override + @XxlJob(value = "realBatchMessageRequestSplitCompensation") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("RealBatchMessageRequestSplitCompensation.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("RealBatchMessageRequestSplitCompensation.execute task request is {}", JSON.toJSONString(request)); + taskService.realBatchMessageRequestSplitCompensation(request); + } catch (Exception e) { + LogUtil.error("RealBatchMessageRequestSplitCompensation.execute is error", e); + return ReturnT.FAIL; + } + log.info("RealBatchMessageRequestSplitCompensation.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageSplitCompensation.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageSplitCompensation.java new file mode 100644 index 00000000..189ff6e4 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/RealBatchMessageSplitCompensation.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.compensation; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 实时批量消息拆分补偿任务 + * + * @author zhaoyong + * @see RealBatchMessageSplitCompensation + * @since 2021-08-24 13:00 + */ +@Slf4j +@Component +public class RealBatchMessageSplitCompensation extends LoggerJobHandler { + + @Override + @XxlJob(value = "realBatchMessageSplitCompensation") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("RealBatchMessageSplitCompensation.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("RealBatchMessageSplitCompensation.execute task request is {}", JSON.toJSONString(request)); + taskService.realBatchMessageSplitCompensation(request); + } catch (Exception e) { + LogUtil.error("RealBatchMessageSplitCompensation.execute is error", e); + return ReturnT.FAIL; + } + log.info("RealBatchMessageSplitCompensation.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/SendMessageExceptionCompensation.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/SendMessageExceptionCompensation.java new file mode 100644 index 00000000..bbca0847 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/compensation/SendMessageExceptionCompensation.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.compensation; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 发送短信异常补偿 + * + * @author zhaoyong_sh + * @see SendMessageExceptionCompensation + * @since 2021-05-19 15:44 + */ +@Slf4j +@Component +public class SendMessageExceptionCompensation extends LoggerJobHandler { + + @Override + @XxlJob(value = "sendMessageExceptionCompensation") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("SendMessageExceptionCompensation.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("SendMessageExceptionCompensation.execute task request is {}", JSON.toJSONString(request)); + taskService.aliYunProcessSendMessageException(request); + } catch (Exception e) { + LogUtil.error("SendMessageExceptionCompensation.execute is error", e); + return ReturnT.FAIL; + } + log.info("SendMessageExceptionCompensation.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageRequestSplitJobHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageRequestSplitJobHandler.java new file mode 100644 index 00000000..dc1a5763 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageRequestSplitJobHandler.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.process; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * BatchMessageRequest 短信拆分批次 + * + * @author szg + * @see BatchMessageRequestSplitJobHandler + * @since 2021-08-11 15:44 + */ +@Slf4j +@Component +public class BatchMessageRequestSplitJobHandler extends LoggerJobHandler { + + @Override + @XxlJob(value = "batchMessageRequestSplitHandle") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("BatchMessageRequestSplitJobHandler.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("BatchMessageRequestSplitJobHandler.execute task request is {}", JSON.toJSONString(request)); + taskService.batchMessageRequestSplitHandle(request); + } catch (Exception e) { + LogUtil.error("BatchMessageRequestSplitJobHandler.execute is error", e); + return ReturnT.FAIL; + } + log.info("BatchMessageRequestSplitJobHandler.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSendJobHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSendJobHandler.java new file mode 100644 index 00000000..9f14e33e --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSendJobHandler.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.process; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 批量发送短信 + * + * @author szg + * @see BatchMessageSendJobHandler + * @since 2021-08-11 15:44 + */ +@Slf4j +@Component +public class BatchMessageSendJobHandler extends LoggerJobHandler { + + @Override + @XxlJob(value = "batchSendMessage") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("BatchMessageSendJobHandler.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("BatchMessageSendJobHandler.execute task request is {}", JSON.toJSONString(request)); + taskService.batchSendMessage(request); + } catch (Exception e) { + LogUtil.error("BatchMessageSendJobHandler.execute is error", e); + return ReturnT.FAIL; + } + log.info("BatchMessageSendJobHandler.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSplitJobHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSplitJobHandler.java new file mode 100644 index 00000000..297889e0 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/BatchMessageSplitJobHandler.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.client.task.process; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 短信批次拆分成每一个短信 + * + * @author szg + * @see BatchMessageSplitJobHandler + * @since 2021-08-11 15:44 + */ +@Slf4j +@Component +public class BatchMessageSplitJobHandler extends LoggerJobHandler { + + @Override + @XxlJob(value = "batchMessageSendSplitHandle") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("BatchMessageSplitJobHandler.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("BatchMessageSplitJobHandler.execute task request is {}", JSON.toJSONString(request)); + taskService.batchMessageSendSplitHandle(request); + } catch (Exception e) { + LogUtil.error("BatchMessageSplitJobHandler.execute is error", e); + return ReturnT.FAIL; + } + log.info("BatchMessageSplitJobHandler.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/MessageProcessingJobHandler.java b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/MessageProcessingJobHandler.java new file mode 100644 index 00000000..b328c757 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/java/cn/axzo/msg/notices/client/task/process/MessageProcessingJobHandler.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.client.task.process; + +import cn.axzo.msg.notices.client.task.LoggerJobHandler; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Classname MessageProcessingJobHandler + * @Author: szg + * @Date: 2021年05月28日 17:14 + * @Description: 补偿回调未成功的短信 + */ +@Slf4j +@Component +public class MessageProcessingJobHandler extends LoggerJobHandler { + + @Override + @XxlJob(value = "messageProcessingJobHandler") + public ReturnT execute(String param) { + return jobLoggerTemplate.execute(() -> { + log.info("MessageProcessingJobHandler.execute task Start ......"); + try { + JobPageRequest request = jobParamResolver.resolver(param); + log.info("MessageProcessingJobHandler.execute task request is {}", JSON.toJSONString(request)); + taskService.aliYunMessageProcessingHandle(request); + } catch (Exception e) { + LogUtil.error("MessageProcessingJobHandler.execute is error", e); + return ReturnT.FAIL; + } + log.info("MessageProcessingJobHandler.execute task End ......"); + return ReturnT.SUCCESS; + }); + } + +} diff --git a/msg-notices/msg-notices-client/src/main/resources/bootstrap.yml b/msg-notices/msg-notices-client/src/main/resources/bootstrap.yml new file mode 100644 index 00000000..78677f0d --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/resources/bootstrap.yml @@ -0,0 +1,18 @@ +spring: + application: + name: mns + cloud: + nacos: + config: + server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80} + file-extension: yaml + namespace: ${NACOS_NAMESPACE_ID:35eada10-9574-4db8-9fea-bc6a4960b6c7} + prefix: ${spring.application.name} + profiles: + active: ${NACOS_PROFILES_ACTIVE:dev} + main: + allow-bean-definition-overriding: true + +logging: + level: + com.alibaba.nacos.client.config.impl: WARN \ No newline at end of file diff --git a/msg-notices/msg-notices-client/src/main/resources/logback-spring.xml b/msg-notices/msg-notices-client/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..922ff245 --- /dev/null +++ b/msg-notices/msg-notices-client/src/main/resources/logback-spring.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-common/pom.xml b/msg-notices/msg-notices-common/pom.xml new file mode 100644 index 00000000..c4d85b7b --- /dev/null +++ b/msg-notices/msg-notices-common/pom.xml @@ -0,0 +1,89 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.common + msg-notices-common + + + 8 + 8 + UTF-8 + + + + + cn.axzo.framework + axzo-common + + + org.apache.skywalking + apm-toolkit-logback-1.x + + + org.springframework.boot + spring-boot-starter-data-redis + + + net.logstash.logback + logstash-logback-encoder + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.cloud + spring-cloud-context + + + javax.validation + validation-api + + + org.hibernate.validator + hibernate-validator + + + org.redisson + redisson + + + com.alibaba + fastjson + + + joda-time + joda-time + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + + + cn.hutool + hutool-all + + + com.google.guava + guava + + + org.projectlombok + lombok + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/ApiRequestLog.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/ApiRequestLog.java new file mode 100644 index 00000000..6e1e4cf9 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/ApiRequestLog.java @@ -0,0 +1,17 @@ +package cn.axzo.msg.notices.common.annotation; + +import java.lang.annotation.*; + +/** + * 保存请求日志注解 + * + * @author zhaoyong_sh + * @see ApiRequestLog + * @since 2021-05-28 10:44 + */ +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ApiRequestLog { + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/PushOperation.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/PushOperation.java new file mode 100644 index 00000000..0e20935a --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/annotation/PushOperation.java @@ -0,0 +1,14 @@ +package cn.axzo.msg.notices.common.annotation; + +import java.lang.annotation.*; + +/** + * @author wangli + * @since 2022/12/22 10:37 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface PushOperation { + String value(); +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/AliyunConstants.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/AliyunConstants.java new file mode 100644 index 00000000..1c18a629 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/AliyunConstants.java @@ -0,0 +1,15 @@ +package cn.axzo.msg.notices.common.constans; + +/** + * 阿里云常量类 + * + * @author zhaoyong_sh + * @see AliyunConstants + * @since 2021-05-19 14:46 + */ +public abstract class AliyunConstants { + + /** 成功响应码 */ + public static String SUCCESS_CODE = "OK"; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CacheConstants.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CacheConstants.java new file mode 100644 index 00000000..c6042e51 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CacheConstants.java @@ -0,0 +1,42 @@ +package cn.axzo.msg.notices.common.constans; + +/** + * 缓存常量 + * + * @author zhaoyong + * @see CacheConstants + * @since 2021-08-20 22:54 + */ +public abstract class CacheConstants { + + /** + * 不存在的键存为NA + */ + public static final String REDIS_NULL_VALUE = "NA"; + + /** + * 空值缓存秒数 + */ + public static final int NULL_VALUE_CACHE_SECONDS = 5 * 60; + + /** + * 模板参数缓存秒数 + */ + public static final int TEMPLATE_PARAM_CACHE_SECONDS = 7 * 24 * 60 * 60; + + /** + * 项目名称 + */ + public static final String MNS = "mns"; + + /** + * 消息模板 + */ + public static final String MESSAGE_TEMPLATE = "template"; + + /** + * 参数 + */ + public static final String PARAM = "param"; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/ChuangLanConstants.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/ChuangLanConstants.java new file mode 100644 index 00000000..281cc792 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/ChuangLanConstants.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.common.constans; + +/** + * 创蓝常量类 + * + * @author zhaoyong + * @see ChuangLanConstants + * @since 2021-08-10 13:48 + */ +public abstract class ChuangLanConstants { + + /** 成功响应码 */ + public static String SUCCESS_CODE = "0"; + + /** 回调消息成功状态 */ + public static String MESSAGE_CALLBACK_SUCCESS_STATUS = "DELIVRD"; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CommonConstants.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CommonConstants.java new file mode 100644 index 00000000..c810a4e4 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/constans/CommonConstants.java @@ -0,0 +1,46 @@ +package cn.axzo.msg.notices.common.constans; + +import java.util.regex.Pattern; + +/** + * 通用常量类 + * + * @author zhaoyong_sh + * @see CommonConstants + * @since 2021-05-19 10:29 + */ +public abstract class CommonConstants { + + /** MDC 日志 KEY */ + public static final String CTX_LOG_ID_MDC = "ctxLogId"; + + /** 心跳 URI */ + public static final String HEARTBEAT_URI = "/checkDeath"; + + /** 逗号分隔符 */ + public static final String COMMA_SYMBOL = ","; + + /** 最大重试次数 */ + public static final int MAX_RETRY_COUNT = 3; + + /** 验证码短信 code */ + public static final String CODE = "code"; + + /** 钉钉 text 消息类型 */ + public static final String DING_TEXT_MESSAGE_TYPE = "text"; + + /** 默认环境 */ + public static final String DEFAULT_ENV = "dev"; + + /** Mock 渠道 */ + public static final String MOCK_CHANNEL = "mock"; + + /** 指定渠道 */ + public static final String ASSIGN_CHANNEL = "assign_channel"; + + /** + * 消息模板变量表达式 + */ + public static final Pattern MESSAGE_TEMPLATE_PARAM_PATTERN = Pattern.compile("(\\$\\{)([\\w]+)(\\})"); + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BaseBatchMessageContext.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BaseBatchMessageContext.java new file mode 100644 index 00000000..a0e674b4 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BaseBatchMessageContext.java @@ -0,0 +1,35 @@ +package cn.axzo.msg.notices.common.domain; + +import cn.axzo.msg.notices.common.utils.KeyUtils; +import lombok.Data; + +/** + * 批量上下文基类 + * + * @author zhaoyong + * @see BaseBatchMessageContext + * @since 2021-08-11 14:14 + */ +@Data +public abstract class BaseBatchMessageContext { + + /** + * 应用码 + */ + private String appCode; + + /** + * 应用请求号 + */ + private String appRequestNo; + + /** + * 批次号 + */ + private String batchNo; + + public String getMessageKey(){ + return KeyUtils.getKey(appCode, appRequestNo); + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageCountContext.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageCountContext.java new file mode 100644 index 00000000..a22831b9 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageCountContext.java @@ -0,0 +1,25 @@ +package cn.axzo.msg.notices.common.domain; + +import lombok.Data; + +/** + * 批量消息计数上下文 + * + * @author zhaoyong + * @see BatchMessageCountContext + * @since 2021-08-11 14:17 + */ +@Data +public class BatchMessageCountContext extends BaseBatchMessageContext { + + + /** + * 成功条数 + */ + private int successNum; + /** + * 失败条数 + */ + private int failNum; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageSendContext.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageSendContext.java new file mode 100644 index 00000000..210d1a17 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/BatchMessageSendContext.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.notices.common.domain; + +import lombok.Data; + +/** + * 批量消息上下文 + * + * @author zhaoyong + * @see BatchMessageSendContext + * @since 2021-08-10 14:09 + */ +@Data +public class BatchMessageSendContext extends BaseBatchMessageContext { + + /** + * 内部模板号 + */ + private String innerTemplateNo; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/MessageContext.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/MessageContext.java new file mode 100644 index 00000000..19866686 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/MessageContext.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.notices.common.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 消息上下文 + * + * @author zhaoyong_sh + * @see MessageContext + * @since 2021-05-27 16:15 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MessageContext { + + /** 重试次数 */ + private Integer retryCount; + + /** 重试规则 */ + private String notifyRule; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContext.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContext.java new file mode 100644 index 00000000..c03fd620 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContext.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.notices.common.domain; + +import lombok.Data; + +/** + * 服务上下文 + * + * @author zhaoyong + * @see ServiceContext + * @since 2021-08-19 19:46 + */ +@Data +public class ServiceContext { + + /** + * 渠道响应对象 + */ + private Object channelResponse; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContextHolder.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContextHolder.java new file mode 100644 index 00000000..7c50150f --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/domain/ServiceContextHolder.java @@ -0,0 +1,46 @@ +package cn.axzo.msg.notices.common.domain; + +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.azxo.framework.common.utils.LogUtil; +import lombok.extern.slf4j.Slf4j; + +/** + * 服务上下文本地变量 + * + * @author zhaoyong + * @see ServiceContextHolder + * @since 2021-08-19 19:47 + */ +@Slf4j +public class ServiceContextHolder { + + private static ThreadLocal tl = new ThreadLocal<>(); + + public static ServiceContext get() { + if (tl.get() == null) { + LogUtil.error("service context not exist"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR); + } + return tl.get(); + } + + public static void set(ServiceContext sc) { + if (tl.get() != null) { + LogUtil.error("service context not null"); + tl.remove(); + } + tl.set(sc); + } + + public static void cleanUp() { + try { + if (tl.get() != null) { + tl.remove(); + } + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + } + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AliyunSmsStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AliyunSmsStatusEnum.java new file mode 100644 index 00000000..01172b56 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AliyunSmsStatusEnum.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 阿里云状态 + * + * @Author: LiuYang + * @Date: 2021/5/25 15:57 + */ +@AllArgsConstructor +@Getter +public enum AliyunSmsStatusEnum { + + OK("OK", "发送成功"), + DAY_LIMIT_CONTROL("isv.DAY_LIMIT_CONTROL", "已经达到您在控制台设置的短信日发送量限额值"), + SMS_SIGN_ILLEGAL("isv.SMS_SIGN_ILLEGAL","签名禁止使用"), + OUT_OF_SERVICE("isv.OUT_OF_SERVICE", "签名禁止使用"), + SYSTEM_ERROR("isp.SYSTEM_ERROR", "请重新调用接口,如仍存在此情况请创建工单反馈工程师查看"), + BUSINESS_LIMIT_CONTROL("isv.BUSINESS_LIMIT_CONTROL", "短信发送频率超限"), + AMOUNT_NOT_ENOUGH("isv.AMOUNT_NOT_ENOUGH", "短信发送频率超限"), + ; + + private String code; + private String msg; + + + } diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AvailableStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AvailableStatusEnum.java new file mode 100644 index 00000000..c28e8f55 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/AvailableStatusEnum.java @@ -0,0 +1,23 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; + +/** + * @Author: LiuYang + * @Date: 2021/5/24 11:52 + */ +@Getter +public enum AvailableStatusEnum { + // 可用 + AVAILABLE(1), + // 不可用 + NOT_AVAILABLE(0) + ; + + private Integer status; + + AvailableStatusEnum(Integer status) { + this.status = status; + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageRequestStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageRequestStatusEnum.java new file mode 100644 index 00000000..1bb59ffa --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageRequestStatusEnum.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @Classname BatchMessageRequestStatusEnum + * @Author: szg + * @Date: 2021年08月09日 14:32 + * @Description: + */ +@RequiredArgsConstructor +@Getter +public enum BatchMessageRequestStatusEnum { + +// 0:初始化;1:已拆分完成;2:发送成功;3:部分成功;4:全部失败 + INITIALIZE(0, "初始化"), + SPLIT_COMPLETED(1, "已拆分完成"), + SEND_SUCCESS(2, "发送成功"), + PARTIAL_SUCCESS(3, "部分成功"), + ALL_FAILED(4, "全部失败"); + + private final Integer code; + + private final String message; + + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageStatusEnum.java new file mode 100644 index 00000000..1d1c785d --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchMessageStatusEnum.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @Classname BatchMessageStatusEnum + * @Author: szg + * @Date: 2021年08月09日 14:32 + * @Description: + */ +@RequiredArgsConstructor +@Getter +public enum BatchMessageStatusEnum { + +// 0:初始化;1:已拆分完成;2:发送成功;3:部分成功;4:全部失败 + INITIALIZE(0, "初始化"), + SPLIT_COMPLETED(1, "已拆分完成"), + PROCESSING(2, "处理中"), + SEND_SUCCESS(3, "发送成功"), + PARTIAL_SUCCESS(4, "部分成功"), + ALL_FAILED(5, "全部失败"); + + private final Integer code; + + private final String message; + + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchSendTypeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchSendTypeEnum.java new file mode 100644 index 00000000..bdece689 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/BatchSendTypeEnum.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 发送类型 + * + * 1:实时;2:非实时 + * + * @author zhaoyong + * @see BatchSendTypeEnum + * @since 2021-08-07 16:30 + */ +@RequiredArgsConstructor +@Getter +public enum BatchSendTypeEnum implements EnumBase { + + /** + * 批量发送类型 + */ + REALTIME(1, "实时"), + NOT_REALTIME(2, "非实时"), + ; + + private final Integer code; + + private final String message; + + public static boolean isRealtime(Integer code){ + return REALTIME.getCode().equals(code); + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChannelHandlerEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChannelHandlerEnum.java new file mode 100644 index 00000000..905b98fc --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChannelHandlerEnum.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 渠道处理枚举类 + * + * @author zhaoyong + * @see ChannelHandlerEnum + * @since 2021-08-19 11:37 + */ +@RequiredArgsConstructor +@Getter +public enum ChannelHandlerEnum implements EnumBase { + + /** + * 渠道对应处理类 + */ + ALI_YUN("aliyun", "aliyunSmsSendManager"), + CHUANG_LAN("chuanglan", "chuangLanSmsSendManager"), + ; + + private final String code; + private final String message; + + public static ChannelHandlerEnum getByCode(String code) { + for (ChannelHandlerEnum value : ChannelHandlerEnum.values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChuangLanStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChuangLanStatusEnum.java new file mode 100644 index 00000000..4d729ba9 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ChuangLanStatusEnum.java @@ -0,0 +1,19 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @Auther: szg + * @Date: 2021/8/10 16:16 + * @Description: + */ +@RequiredArgsConstructor +@Getter +public enum ChuangLanStatusEnum { + SUCCESS("000000", "成功"), + FAIL("111111", "成功"); + + private final String code; + private final String msg; +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/EnumBase.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/EnumBase.java new file mode 100644 index 00000000..9886f295 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/EnumBase.java @@ -0,0 +1,24 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 枚举抽象类 + * + * @author zhaoyong_sh + * @see EnumBase + * @since 2021-03-29 18:15 + */ +public interface EnumBase { + + /** + * 枚举 code + * @return + */ + T getCode(); + + /** + * 枚举描述信息 + * @return + */ + String getMessage(); + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/IsDeletedEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/IsDeletedEnum.java new file mode 100644 index 00000000..cad85daf --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/IsDeletedEnum.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 是否枚举类 + * + * @author zhaoyong + * @see IsDeletedEnum + * @since 2021-08-07 19:35 + */ +@RequiredArgsConstructor +@Getter +public enum IsDeletedEnum implements EnumBase { + + /** + * 是否枚举类 + */ + NO(0, "未删除"), + YES(1, "删除"), + ; + + private final Integer code; + + private final String message; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/LockKeyEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/LockKeyEnum.java new file mode 100644 index 00000000..f2591cc8 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/LockKeyEnum.java @@ -0,0 +1,17 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 锁 + * @Author: LiuYang + * @Date: 2021/5/24 14:01 + */ +public enum LockKeyEnum { + + // 消息 + MESSAGE + ; + + public String relate(String str) { + return this.name().concat(":").concat(str); + } +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageChannelEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageChannelEnum.java new file mode 100644 index 00000000..3abe5ada --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageChannelEnum.java @@ -0,0 +1,35 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 消息渠道 + * + * @Author: LiuYang + * @Date: 2021/5/24 16:39 + */ +@RequiredArgsConstructor +@Getter +public enum MessageChannelEnum implements EnumBase { + + /** + * 消息渠道 + */ + ALIYUN("aliyun", "阿里云"), + CHUANG_LAN("chuanglan", "创蓝云智"), + ; + + private final String code; + private final String message; + + public static MessageChannelEnum getByCode(String code) { + for (MessageChannelEnum value : MessageChannelEnum.values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageCommonStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageCommonStatusEnum.java new file mode 100644 index 00000000..51a3439c --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageCommonStatusEnum.java @@ -0,0 +1,26 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 消息通用状态 备:以后介入多渠道,响应状态都要包装成我们自己的 + * + * @Author: LiuYang + * @Date: 2021/5/25 16:07 + */ +@AllArgsConstructor +@Getter +public enum MessageCommonStatusEnum { + + OK("发送成功"), + EXCEPTION("发送异常"), + FAIL("发送失败") + ; + + /** + * 响应消息 + */ + private String message; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageMockEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageMockEnum.java new file mode 100644 index 00000000..2adce858 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageMockEnum.java @@ -0,0 +1,14 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 消息mock枚举 + * @Author: LiuYang + * @Date: 2021/5/28 16:06 + */ +public enum MessageMockEnum { + NONE, + MOCK, + ALI_YUN + ; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageSendTypeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageSendTypeEnum.java new file mode 100644 index 00000000..9b138517 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageSendTypeEnum.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 短信发送类型 + * + * @author zhaoyong + * @see MessageSendTypeEnum + * @since 2021-08-19 20:42 + */ +@AllArgsConstructor +@Getter +public enum MessageSendTypeEnum implements EnumBase { + + /** + * 短信发送类型 + */ + SINGLE("SINGLE", "部分成功"), + BATCH("BATCH", "全部失败"); + + private final String code; + + private final String message; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageStatusEnum.java new file mode 100644 index 00000000..85081d06 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageStatusEnum.java @@ -0,0 +1,56 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; + +/** + * 消息状态枚举类 + * + * @author zhaoyong_sh + * @see MessageStatusEnum + * @since 2021-05-19 18:17 + */ +@RequiredArgsConstructor +@Getter +public enum MessageStatusEnum implements EnumBase { + + /** + * 消息状态枚举类 + */ + INIT("INIT", "初始化"), + PROCESSING("PROCESSING", "处理中"), + EXCEPTION("EXCEPTION", "处理异常"), + FAIL("FAIL", "处理失败"), + SUCCESS("SUCCESS", "成功"), + ; + + private final String code; + + private final String message; + + public static MessageStatusEnum getByCode(String code) { + if(StringUtils.isBlank(code)) { + return null; + } + for (MessageStatusEnum statusEnum : MessageStatusEnum.values()) { + if (statusEnum.getCode().equals(code)) { + return statusEnum; + } + } + return null; + } + + public static String getSuccessCode(Boolean isSuccess) { + + if (Objects.isNull(isSuccess)) { + return null; + } + if (isSuccess){ + return SUCCESS.getCode(); + } + return FAIL.getCode(); + } +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTemplateTypeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTemplateTypeEnum.java new file mode 100644 index 00000000..653978d0 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTemplateTypeEnum.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 消息模板类型 + * + * 模板类型(1:验证码;2:短信通知;3:推广短信;4:群发助手) + * + * @author zhaoyong + * @see MessageTemplateTypeEnum + * @since 2021-07-12 13:34 + */ +@RequiredArgsConstructor +@Getter +public enum MessageTemplateTypeEnum implements EnumBase { + + /** + * 发送短信状态 + */ + VERIFICATION_CODE(1, "验证码"), + SHORT_NOTE(2, "短信通知"), + PROMOTIONAL(3, "推广短信"), + BROADCAST(4, "群发助手"), + ; + + private final Integer code; + + private final String message; + + public static boolean isShortNote(Integer code) { + return VERIFICATION_CODE.getCode().equals(code); + } + + public static MessageTemplateTypeEnum getByCode(Integer code){ + for (MessageTemplateTypeEnum value : MessageTemplateTypeEnum.values()) { + if (value.getCode().equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTypeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTypeEnum.java new file mode 100644 index 00000000..cfea686b --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/MessageTypeEnum.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 消息类型 + * @Author: LiuYang + * @Date: 2021/5/24 16:16 + */ +public enum MessageTypeEnum { + + M("邮件"), + S("短信"); + + /** + * 备注 + */ + private String remark; + + MessageTypeEnum (String remark) { + this.remark = remark; + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/NotifyTypeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/NotifyTypeEnum.java new file mode 100644 index 00000000..6a5c7774 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/NotifyTypeEnum.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 通知类型 + * @Author: LiuYang + * @Date: 2021/5/24 16:18 + */ +public enum NotifyTypeEnum { + REAL("实时发送"), + BATCH("批量发送"), + DELAY("延迟发送"); + + private String remark; + + NotifyTypeEnum(String remark) { + this.remark = remark; + } +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/RetryingFlagEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/RetryingFlagEnum.java new file mode 100644 index 00000000..0aa2edbd --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/RetryingFlagEnum.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.common.enums; + +/** + * 重试标记 + * @Author: LiuYang + * @Date: 2021/5/24 16:27 + */ +public enum RetryingFlagEnum { + N("未重试"), + Y("重试中") + ; + + private String remark; + + RetryingFlagEnum(String remark) { + this.remark = remark; + } +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ReturnCodeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ReturnCodeEnum.java new file mode 100644 index 00000000..d2629729 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/ReturnCodeEnum.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 系统返回码枚举类 + * + * @author zhaoyong_sh + * @see ReturnCodeEnum + * @since 2021-05-17 15:57 + */ +@RequiredArgsConstructor +@Getter +public enum ReturnCodeEnum implements EnumBase { + + /** + * 系统返回码枚举类 + */ + SUCCESS(200, "success"), + SYSTEM_ERROR(500, "system error"), + FAIL(400, "service exception"), + + INVALID_PARAMETER(10001, "无效的参数"), + REPEATED_REQUEST(10002, "重复的请求"), + MESSAGE_TEMPLATE_NOT_EXIST(10003, "短信模板不存在"), + MESSAGE_CHANNEL_NOT_VALID(10004, "无可用消息渠道"), + MESSAGE_TEMPLATE_NOT_VALID(10005, "短信模板不可用"), + + ; + + private final Integer code; + + private final String message; + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/SendDetailsStatusEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/SendDetailsStatusEnum.java new file mode 100644 index 00000000..43708f1f --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/SendDetailsStatusEnum.java @@ -0,0 +1,56 @@ +package cn.axzo.msg.notices.common.enums; + +import cn.axzo.msg.notices.common.exception.BizException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 查询阿里云发送详情状态枚举 + * + * @author zhaoyong_sh + * @see SendDetailsStatusEnum + * @since 2021-05-19 15:00 + */ +@RequiredArgsConstructor +@Getter +public enum SendDetailsStatusEnum implements EnumBase { + + /** + * 发送短信状态 + */ + WAIT_RECEIPT(1L, "等待回执"), + FAIL(2L, "发送失败"), + SUCCESS(3L, "发送成功"), + ; + + private final Long code; + + private final String message; + + public static SendDetailsStatusEnum getByCode(Long code) { + if(code == null) { + return null; + } + for (SendDetailsStatusEnum statusEnum : SendDetailsStatusEnum.values()) { + if (statusEnum.getCode().equals(code)) { + return statusEnum; + } + } + return null; + } + + public static String getMappingCode(SendDetailsStatusEnum statusEnum) { + if(WAIT_RECEIPT == statusEnum) { + return MessageStatusEnum.PROCESSING.getCode(); + } + if(FAIL == statusEnum) { + return MessageStatusEnum.FAIL.getCode(); + } + if(SUCCESS == statusEnum) { + return MessageStatusEnum.SUCCESS.getCode(); + } + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "status enum must not be null"); + } + + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/YesNoEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/YesNoEnum.java new file mode 100644 index 00000000..06a8ec7e --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/enums/YesNoEnum.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 是否枚举类 + * + * @author zhaoyong + * @see YesNoEnum + * @since 2021-08-07 19:35 + */ +@RequiredArgsConstructor +@Getter +public enum YesNoEnum implements EnumBase { + + /** + * 是否枚举类 + */ + NO(0, "否"), + YES(1, "是"), + ; + + private final Integer code; + + private final String message; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/exception/BizException.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/exception/BizException.java new file mode 100644 index 00000000..f6d498fd --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/exception/BizException.java @@ -0,0 +1,90 @@ +package cn.axzo.msg.notices.common.exception; + +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * 业务异常 + * + * @author zhaoyong_sh + * @see BizException + * @since 2021-05-17 15:56 + */ +@Getter +@Setter +public class BizException extends RuntimeException { + + private Integer bizCode; + + private String message; + + /** + * 需返回的业务数据 + */ + private Object data; + + public BizException(Integer bizCode) { + this.bizCode = bizCode; + } + + public BizException(ReturnCodeEnum returnCode) { + super(returnCode.getMessage()); + this.bizCode = returnCode.getCode(); + this.message = returnCode.getMessage(); + } + + public BizException(ReturnCodeEnum returnCode, String message) { + super(returnCode.getMessage()); + this.bizCode = returnCode.getCode(); + this.message = message; + } + + public BizException(Integer bizCode, Throwable cause) { + super(null, cause); + this.bizCode = bizCode; + } + + public BizException(Integer bizCode, String message, Object data) { + super(message); + this.bizCode = bizCode; + this.message = message; + this.data = data; + } + + public BizException(Integer bizCode, String message, Object data, Throwable cause) { + super(message, cause); + this.bizCode = bizCode; + this.message = message; + this.data = data; + } + + public static void error(boolean b, ReturnCodeEnum returnCode){ + if(!b){ + throw new BizException(returnCode.getCode(), returnCode.getMessage(), null); + } + } + + public static void error(boolean b, ReturnCodeEnum returnCode, String message){ + if(!b){ + throw new BizException(returnCode.getCode(), message, null); + } + } + + public static void error(boolean b, Integer bizCode, String message) { + if(!b){ + throw new BizException(bizCode, message, null); + } + } + + public static void error(boolean b, Integer bizCode, String message, Object data) { + if(!b){ + throw new BizException(bizCode, message, data); + } + } + + public static void error(ReturnCodeEnum returnCode){ + throw new BizException(returnCode.getCode(), returnCode.getMessage(), null); + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallback.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallback.java new file mode 100644 index 00000000..57fa2649 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallback.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.common.lang; + +/** + * 日志回调 + * + * @author zhaoyong + * @see LoggerCallback + * @since 2021-08-06 18:40 + */ +public interface LoggerCallback { + + /** + * 任务操作 + * @return + */ + T doInExecute(); + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallbackWithoutResult.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallbackWithoutResult.java new file mode 100644 index 00000000..eae7d6a0 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerCallbackWithoutResult.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.common.lang; + +/** + * 日志模板没有响应对象 + * + * @author zhaoyong + * @see LoggerCallbackWithoutResult + * @since 2021-08-10 14:32 + */ +public abstract class LoggerCallbackWithoutResult implements + LoggerCallback { + + @Override + public Object doInExecute() { + doInExecuteWithoutResult(); + return null; + } + + public abstract void doInExecuteWithoutResult(); + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerTemplate.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerTemplate.java new file mode 100644 index 00000000..0c4ee99e --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/LoggerTemplate.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.common.lang; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +/** + * 日志模板 + * + * @author zhaoyong + * @see LoggerTemplate + * @since 2021-08-06 18:40 + */ +@Component("loggerTemplate") +public class LoggerTemplate { + + public T execute(LoggerCallback action, String traceId){ + if(StringUtils.isBlank(traceId)) { + String uuid = UUID.randomUUID().toString(); + MDC.put(CommonConstants.CTX_LOG_ID_MDC, uuid); + } else { + MDC.put(CommonConstants.CTX_LOG_ID_MDC, traceId); + } + try { + return action.doInExecute(); + } finally { + MDC.clear(); + } + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/Page.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/Page.java new file mode 100644 index 00000000..90e8764b --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/Page.java @@ -0,0 +1,38 @@ +package cn.axzo.msg.notices.common.lang; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页对象 + * + * @author zhaoyong_sh + * @see Page + * @since 2021-05-19 18:13 + */ +@Data +public class Page implements Serializable { + + /** + * 页码(从第1页开始) + */ + private Long pageNum; + + /** + * 每页条数 + */ + private Long pageSize; + + /** + * 总记录数 + */ + private Long totalElements; + + /** + * 数据 + */ + private List list; + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/PageRequest.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/PageRequest.java new file mode 100644 index 00000000..201711b8 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/lang/PageRequest.java @@ -0,0 +1,25 @@ +package cn.axzo.msg.notices.common.lang; + +import lombok.Data; + +/** + * 分页请求通用 + * + * @author zhaoyong_sh + * @see PageRequest + * @since 2021-05-19 18:01 + */ +@Data +public class PageRequest { + + /** + * 页码 + */ + private int pageNum = 1; + + /** + * 每页大小 + */ + private int pageSize = 15; + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/DateUtils.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/DateUtils.java new file mode 100644 index 00000000..ff818fa6 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/DateUtils.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.common.utils; + +import org.joda.time.DateTime; + +import java.util.Date; + +/** + * 日期工具类 + * + * @author zhaoyong_sh + * @see DateUtils + * @since 2021-05-27 16:19 + */ +public abstract class DateUtils { + + public static Date plusSeconds(int seconds){ + DateTime dateTime = DateTime.now().plusSeconds(seconds); + return dateTime.toDate(); + } + +} diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/KeyUtils.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/KeyUtils.java new file mode 100644 index 00000000..d2e827c9 --- /dev/null +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/notices/common/utils/KeyUtils.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.common.utils; + +import com.google.common.base.Joiner; + +/** + * Key 生成工具类 + * + * @author zhaoyong_sh + * @see KeyUtils + * @since 2021-03-29 18:18 + */ +public abstract class KeyUtils { + + public static String getKey(String... params){ + if(params == null || params.length == 0){ + return null; + } + Joiner joiner = Joiner.on(":"); + return joiner.join(params); + } + +} diff --git a/msg-notices/msg-notices-dao/pom.xml b/msg-notices/msg-notices-dao/pom.xml new file mode 100644 index 00000000..cdc82794 --- /dev/null +++ b/msg-notices/msg-notices-dao/pom.xml @@ -0,0 +1,59 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.dao + msg-notices-dao + + + 8 + 8 + UTF-8 + + + + + cn.axzo.msg.notices.common + msg-notices-common + ${revision} + + + mysql + mysql-connector-java + + + com.zaxxer + HikariCP + + + org.springframework.boot + spring-boot-starter-jdbc + + + com.baomidou + mybatis-plus-boot-starter + + + org.apache.velocity + velocity-engine-core + compile + + + com.baomidou + mybatis-plus-generator + + + cn.axzo.trade + trade-data-security-base + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/CodeGenerator.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/CodeGenerator.java new file mode 100644 index 00000000..b3498c34 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/CodeGenerator.java @@ -0,0 +1,196 @@ +package cn.axzo.msg.notices.dao; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; +import java.util.Scanner; + +/** + * 通用响应对象 + * + * @author zhaoyong_sh + * @see CodeGenerator + * @since 2021-05-19 10:53 + */ +public class CodeGenerator { + + public static String DRIVER_NAME = "com.mysql.jdbc.Driver"; +// public static String URL = "jdbc:mysql://rm-bp1qpff9er81dmgw7ko.mysql.rds.aliyuncs.com:3311/mns-dev?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=GMT%2b8&useSSL=true&verifyServerCertificate=false"; +// public static String USERNAME = "mns"; +// public static String PASSWORD = "79AIDoSJjUb5oCaE"; + + public static String URL = "jdbc:mysql://localhost:3306/test"; + public static String USERNAME = "carl"; + public static String PASSWORD = "123456"; + + public static String SUPPER_MAPPER_CLASS = "com.baomidou.mybatisplus.core.mapper.BaseMapper"; + public static String BASE_PACKAGE = "cn.axzo.msg.notices.dao"; + public static String ENTITY_PACKAGE = "entity"; + public static String MAPPER_PACKAGE = "mapper"; + public static String SERVICE_PACKAGE = "repository"; + public static String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl"; + public static String CONTROLLER_PACKAGE = ""; + public static String PROJECT_PATH = System.getProperty("user.dir") + "/mns-dal"; + public static String MAPPER_OUT_PATH = PROJECT_PATH + "/src/main/resources/mapper"; + public static String PROJECT_RESOURCE_PATH = PROJECT_PATH + "/src/main/java"; + public static String MAPPER_XML_PACKAGE = PROJECT_PATH + "/src/main/resources/mapper"; + + public static String AUTHOR = "szg"; + static String[] includeTables; + static String[] excludeTables; + + static { + // 做一些配置 + } + + public static String scanner(String tip) { + Scanner scanner = new Scanner(System.in); + StringBuilder help = new StringBuilder(); + help.append("请输入" + tip + ":"); + System.out.println(help.toString()); + if (scanner.hasNext()) { + String ipt = scanner.next(); + if (StringUtils.isNotEmpty(ipt)) { + return ipt; + } + } + throw new MybatisPlusException("请输入正确的" + tip + "!"); + } + + /** + * 获取数据库配置 + * @return + */ + public static DataSourceConfig dataSourceConfig() { + return new DataSourceConfig() + .setDbType(DbType.MYSQL) + .setDriverName(DRIVER_NAME) + .setUrl(URL) + .setUsername(USERNAME) + .setPassword(PASSWORD); + } + + /** + * 获取策略配置,哪些表需要生成,哪些不需要生成 + * @return + */ + public static StrategyConfig strategyConfig() { + return new StrategyConfig() + .setTablePrefix("tb_") + .setNaming(NamingStrategy.underline_to_camel) // 下划线转成驼峰命名 + .setColumnNaming(NamingStrategy.underline_to_camel) + .setInclude(scanner("表名,多个以逗号分开:").split(",")) + .setExclude(excludeTables) + .setSuperMapperClass(SUPPER_MAPPER_CLASS) // 继承的Mapper父类 + .setEntityBuilderModel(true) // 是否设置未Builder类 + .setEntityLombokModel(true) // 是否Lombok类 + .setRestControllerStyle(true) // Controller 为 RestController 模式 + .setEntityTableFieldAnnotationEnable(true); + } + + /** + * 包配置(生成的Entity、Xml、Mapper、Controller、Service存放的问题) + * @return + */ + public static PackageConfig packageConfig() { + return new PackageConfig() + .setParent(BASE_PACKAGE) + .setEntity(ENTITY_PACKAGE) + .setController(CONTROLLER_PACKAGE) + .setMapper(MAPPER_PACKAGE) + .setService(SERVICE_PACKAGE) + .setServiceImpl(SERVICE_IMPL_PACKAGE) + ; + } + + /** + * 自动注入配置 + * @return + */ + public static InjectionConfig injectionConfig() { + + return new InjectionConfig() { + @Override + public void initMap() { +// Map map = new HashMap(); +// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp"); +// this.setMap(map); + } + }.setFileOutConfigList( + Collections.singletonList(new FileOutConfig("/templates/mapper.xml.vm") { + // 自定义输出文件目录 + @Override + public String outputFile(TableInfo tableInfo) { + return MAPPER_OUT_PATH + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; + } + }) + ); + } + + /** + * 模板配置 + * 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy + * 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置: + * @return + */ + public static TemplateConfig templateConfig() { + return new TemplateConfig() + .setController("") // 不生成Controller类 + .setServiceImpl("templates/serviceimpl.java") + .setXml(null); // 必须setXml(null),不然会在项目目录下构建xml文件 + + } + + /** + * 全局配置 + * @return + */ + public static GlobalConfig globalConfig() { + return new GlobalConfig() + .setOutputDir(PROJECT_RESOURCE_PATH)// 输出目录 + .setFileOverride(false) // 是否覆盖文件 + .setActiveRecord(true) // 开启 activeRecord 模式 + .setEnableCache(false) // XML 二级缓存 + .setBaseResultMap(true) // XML ResultMap + .setBaseColumnList(true)// XML columList + .setDateType(DateType.ONLY_DATE) + .setIdType(IdType.AUTO) + .setAuthor(AUTHOR) + .setEntityName("%s") + .setXmlName("%sMapper") + .setMapperName("%sMapper") + .setServiceName("%sDao") + .setServiceImplName("%sDaoImpl"); + } + + /** + * 生成代码 + */ + public static void generate() { + AutoGenerator autoGenerator = new AutoGenerator() + .setGlobalConfig(globalConfig()) + .setDataSource(dataSourceConfig()) + .setStrategy(strategyConfig()) + .setPackageInfo(packageConfig()) + .setCfg(injectionConfig()) + .setTemplate(templateConfig()) + ; + + autoGenerator.execute(); + } + + public static void main(String[] args) { + generate(); + } + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageQuery.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageQuery.java new file mode 100644 index 00000000..7449a3f5 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageQuery.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.dao.domain; + +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询 + * + * @author zhaoyong_sh + * @see BatchMessageQuery + * @since 2021-05-19 18:06 + */ +@Data +public class BatchMessageQuery extends PageQuery { + + private Long id; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + + /** + * 发送类型 + */ + private Integer sendType; + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageRequestQuery.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageRequestQuery.java new file mode 100644 index 00000000..9ebe3e1c --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageRequestQuery.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.dao.domain; + +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询 + * + * @author zhaoyong_sh + * @see BatchMessageRequestQuery + * @since 2021-05-19 18:06 + */ +@Data +public class BatchMessageRequestQuery extends PageQuery { + + private Long id; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + + /** + * 发送方式 + */ + private Integer sendType; +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageStatisticsResponseDto.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageStatisticsResponseDto.java new file mode 100644 index 00000000..a8b99637 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/BatchMessageStatisticsResponseDto.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.dao.domain; + + +import lombok.Data; + +/** + * @Classname BatchMessageStatisticsResponseDto + * @Author: szg + * @Date: 2021年08月10日 20:32 + * @Description: 批次发送情况统计 + */ +@Data +public class BatchMessageStatisticsResponseDto { + + private Integer failCount; + + private Integer successCount; + + private Integer totalCount; + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageQuery.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageQuery.java new file mode 100644 index 00000000..8dc2d2d9 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageQuery.java @@ -0,0 +1,44 @@ +package cn.axzo.msg.notices.dao.domain; + +import cn.axzo.msg.notices.dao.entity.Message; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询 + * + * @author zhaoyong_sh + * @see MessageQuery + * @since 2021-05-19 18:06 + */ +@Data +public class MessageQuery extends PageQuery { + + /** + * 主键 + */ + private Long id; + + /** + * 渠道码 + */ + private String channelCode; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageRedoQuery.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageRedoQuery.java new file mode 100644 index 00000000..5d43447f --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MessageRedoQuery.java @@ -0,0 +1,38 @@ +package cn.axzo.msg.notices.dao.domain; + +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询 + * + * @author zhaoyong_sh + * @see MessageRedoQuery + * @since 2021-05-19 18:06 + */ +@Data +public class MessageRedoQuery extends PageQuery { + + private Long id; + + private String channelCode; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MyPage.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MyPage.java new file mode 100644 index 00000000..5e71abeb --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/MyPage.java @@ -0,0 +1,24 @@ +package cn.axzo.msg.notices.dao.domain; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +/** + * 分页对象 + * + * @author zhaoyong_sh + * @see MyPage + * @since 2021-05-19 18:06 + */ +public class MyPage extends Page { + + public MyPage() {} + + public MyPage(Integer current, Integer size) { + current = current == null || current <= 0 ? 1: current; + size = size == null || size <= 0 ? 15 : size; + this.current = current; + this.size = size; + this.isSearchCount = true; + } +} + diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/PageQuery.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/PageQuery.java new file mode 100644 index 00000000..1d4f68a4 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/PageQuery.java @@ -0,0 +1,31 @@ +package cn.axzo.msg.notices.dao.domain; + +import lombok.Getter; +import lombok.Setter; + +/** + * 分页查询类 + * + * @author zhaoyong_sh + * @see PageQuery + * @since 2021-05-19 18:05 + */ +@Getter +@Setter +public class PageQuery { + + /** + * 页码 + */ + private int pageNum = 1; + + /** + * 每页大小 + */ + private int pageSize = 15; + + public MyPage toPage() { + return new MyPage<>(pageNum, pageSize); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/SuccessAndFailNUm.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/SuccessAndFailNUm.java new file mode 100644 index 00000000..dc385ca2 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/domain/SuccessAndFailNUm.java @@ -0,0 +1,19 @@ +package cn.axzo.msg.notices.dao.domain; + +import lombok.Data; + +/** + * 成功与失败数 + * + * @author zhaoyong + * @see SuccessAndFailNUm + * @since 2021-08-24 21:15 + */ +@Data +public class SuccessAndFailNUm { + + private Integer successNum; + + private Integer failNum; + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessage.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessage.java new file mode 100644 index 00000000..ac8baa42 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessage.java @@ -0,0 +1,166 @@ +package cn.axzo.msg.notices.dao.entity; + +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 com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 渠道模板变量序列表 + *

+ * + * @author szg + * @since 2021-08-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("batch_message") +public class BatchMessage extends Model { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * APP请求号 + */ + @TableField("request_no") + private String requestNo; + + /** + * 批次号 + */ + @TableField("batch_no") + private String batchNo; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * 内部模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 渠道模板号 + */ + @TableField("channel_template_no") + private String channelTemplateNo; + + /** + * 请求渠道号 + */ + @TableField("message_order_no") + private String messageOrderNo; + + /** + * 消息内容 + */ + @TableField("sms_content") + private String smsContent; + + /** + * 渠道码 + */ + @TableField("channel_code") + private String channelCode; + + /** + * 批次数量 + */ + @TableField("batch_size") + private Integer batchSize; + + /** + * 成功数 + */ + @TableField("success_count") + private Integer successCount; + + /** + * 失败数 + */ + @TableField("fail_count") + private Integer failCount; + + /** + * 发送类型(1:实时;2:非实时) + */ + @TableField("send_type") + private Integer sendType; + + /** + * 状态(0:初始化;1:已拆分完成;2:处理中;3:发送成功;4:部分成功;5:全部失败) + */ + @TableField("status") + private Integer status; + + /** + * 提交渠道成功数 + */ + @TableField("submit_success_num") + private Integer submitSuccessNum; + + /** + * 提交渠道失败数 + */ + @TableField("submit_fail_num") + private Integer submitFailNum; + + /** + * 消息ID + */ + @TableField("channel_msg_id") + private String channelMsgId; + + @TableField("channel_return_code") + private String channelReturnCode; + + /** + * 渠道响应信息 + */ + @TableField("channel_error_msg") + private String channelErrorMsg; + + /** + * 创建时间 + */ + @TableField("create_at") + private Date createAt; + + /** + * 修改时间 + */ + @TableField("update_at") + private Date updateAt; + + /** + * 是否删除(0:未删除;1:已删除) + */ + @TableField("is_delete") + private Integer isDelete; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessageRequest.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessageRequest.java new file mode 100644 index 00000000..b04d061e --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/BatchMessageRequest.java @@ -0,0 +1,127 @@ +package cn.axzo.msg.notices.dao.entity; + +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 com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 渠道模板变量序列表 + *

+ * + * @author szg + * @since 2021-08-09 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("batch_message_request") +public class BatchMessageRequest extends Model { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * APP请求号 + */ + @TableField("request_no") + private String requestNo; + + /** + * 内部模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 消息内容 + */ + @TableField("sms_content") + private String smsContent; + + /** + * 总数量 + */ + @TableField("total_size") + private Integer totalSize; + + /** + * 成功数 + */ + @TableField("success_count") + private Integer successCount; + + /** + * 失败数 + */ + @TableField("fail_count") + private Integer failCount; + + /** + * 重复手机号数 + */ + @TableField("repeat_count") + private Integer repeatCount; + + /** + * 发送类型(1:实时;2:非实时) + */ + @TableField("send_type") + private Integer sendType; + + /** + * 状态(0:初始化;1:已拆分完成;2:发送成功;3:部分成功;4:全部失败) + */ + @TableField("status") + private Integer status; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 创建时间 + */ + @TableField("create_at") + private Date createAt; + + /** + * 修改时间 + */ + @TableField("update_at") + private Date updateAt; + + /** + * 是否删除(0:未删除;1:已删除) + */ + @TableField("is_delete") + private Integer isDelete; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/ChannelMessageTemplate.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/ChannelMessageTemplate.java new file mode 100644 index 00000000..ab34b5c8 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/ChannelMessageTemplate.java @@ -0,0 +1,105 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.common.enums.YesNoEnum; +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 渠道消息模板表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("channel_message_template") +public class ChannelMessageTemplate extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 内部模板号 + */ + @TableField("inner_template_no") + private String innerTemplateNo; + + /** + * 渠道模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 渠道码 + */ + @TableField("channel_code") + private String channelCode; + + /** + * 渠道名称 + */ + @TableField("channel_name") + private String channelName; + + /** + * 模板名称 + */ + @TableField("title") + private String title; + + /** + * 模板内容 + */ + @TableField("template_content") + private String templateContent; + + /** + * 模板类型(1:验证码;2:短信通知;3:推广短信;4:群发助手) + */ + @TableField("type") + private Integer type; + + /** + * 状态(0:不可用;1:可用) + */ + @TableField("status") + private Integer status; + + /** + * 模板是否有变量(0:没有;1:有) + */ + @TableField("has_param") + private Integer hasParam; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 申请原因 + */ + @TableField("reason") + private String reason; + + + @Override + protected Serializable pkVal() { + return this.id; + } + + public boolean hasParam() { + return YesNoEnum.YES.getCode().equals(hasParam); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/Message.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/Message.java new file mode 100644 index 00000000..7461c18a --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/Message.java @@ -0,0 +1,132 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import cn.axzo.trade.datasecurity.core.annotation.CryptField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 消息记录表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message") +public class Message extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * APP请求号 + */ + @TableField("request_no") + private String requestNo; + + /** + * 批次号 + */ + @TableField("batch_no") + private String batchNo; + + /** + * 请求渠道号 + */ + @TableField("message_order_no") + private String messageOrderNo; + + /** + * 消息类型(M:邮件;S:短信) + */ + @TableField("message_type") + private String messageType; + + /** + * 通知类型(REAL:实时发送;BATCH:批量发送;DELAY:延迟发送) + */ + @TableField("notify_type") + private String notifyType; + + /** + * 状态(INIT:初始化;PROCESSING:处理中;EXCEPTION:处理异常;FAIL:处理失败;SUCCESS:成功) + */ + @TableField("status") + private String status; + + /** + * 渠道码 + */ + @TableField("channel_code") + private String channelCode; + + /** + * 渠道名称 + */ + @TableField("channel_name") + private String channelName; + + /** + * 模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 内容 + */ + @TableField("subject") + @CryptField + private String subject; + + /** + * 通知地址 + */ + @TableField("target_address") + @CryptField + private String targetAddress; + + /** + * 发送回执ID(阿里云) + */ + @TableField("channel_biz_id") + private String channelBizId; + + /** + * 渠道响应请求 ID(阿里云) + */ + @TableField("channel_request_id") + private String channelRequestId; + + /** + * 通知策略(30, 60, 120) + */ + @TableField("notify_rule") + private String notifyRule; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageApp.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageApp.java new file mode 100644 index 00000000..8479b751 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageApp.java @@ -0,0 +1,64 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 消息应用表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_app") +public class MessageApp extends BaseOwnEntity { + + private static final long serialVersionUID = 1L; + + /** + * 应用码 + */ + @TableField("app_code") + private String appCode; + + /** + * 应用名称 + */ + @TableField("app_name") + private String appName; + + /** + * 状态(0:无效;1有效) + */ + @TableField("status") + private Integer status; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 扩展信息(json) + */ + @TableField("extension") + private String extension; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannel.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannel.java new file mode 100644 index 00000000..8cfd6fde --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannel.java @@ -0,0 +1,63 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 消息渠道表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_channel") +public class MessageChannel extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 渠道码 + */ + @TableField("channel_code") + private String channelCode; + + /** + * 渠道名称 + */ + @TableField("channel_name") + private String channelName; + + /** + * 渠道名称 + */ + @TableField("priority") + private Integer priority; + + /** + * 渠道状态(0:不可用,1:可用 + */ + @TableField("status") + private Integer status; + + /** + * 渠道配置扩展 + */ + @TableField("config_json") + private String configJson; + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannelLog.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannelLog.java new file mode 100644 index 00000000..41d52fb0 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageChannelLog.java @@ -0,0 +1,78 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import cn.axzo.trade.datasecurity.core.annotation.CryptField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 请求消息渠道日志表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_channel_log") +public class MessageChannelLog extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * APP请求号 + */ + @TableField("app_request_no") + private String appRequestNo; + + /** + * 请求渠道号 + */ + @TableField("message_order_no") + private String messageOrderNo; + + /** + * 通知地址 + */ + @CryptField + @TableField("target_address") + private String targetAddress; + + /** + * 回调数据 + */ + @TableField("callback_data") + private String callbackData; + + /** + * 定时任务响应数据 + */ + @TableField("task_data") + private String taskData; + + /** + * 响应对象 + */ + @TableField("response_data") + private String responseData; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRedo.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRedo.java new file mode 100644 index 00000000..0c38326b --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRedo.java @@ -0,0 +1,137 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 消息重试表 + *

+ * + * @author szg + * @since 2021-05-27 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_redo") +public class MessageRedo extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * APP请求号 + */ + @TableField("request_no") + private String requestNo; + + /** + * 请求渠道号 + */ + @TableField("message_order_no") + private String messageOrderNo; + + /** + * 重试请求渠道号 + */ + @TableField("redo_order_no") + private String redoOrderNo; + + /** + * 渠道回执id + */ + @TableField("channel_biz_id") + private String channelBizId; + + /** + * 消息类型(M:邮件;S:短信) + */ + @TableField("message_type") + private String messageType; + + /** + * 通知类型(REAL:实时发送;BATCH:批量发送;DELAY:延迟发送) + */ + @TableField("notify_type") + private String notifyType; + + /** + * 状态(INIT:初始化;PROCESSING:处理中;EXCEPTION:处理异常;FAIL:处理失败;SUCCESS:成功) + */ + @TableField("status") + private String status; + + /** + * 渠道码 + */ + @TableField("channel_code") + private String channelCode; + + /** + * 渠道名称 + */ + @TableField("channel_name") + private String channelName; + + /** + * 模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 内容 + */ + @TableField("subject") + private String subject; + + /** + * 通知地址 + */ + @TableField("target_address") + private String targetAddress; + + /** + * 重试标记(N:未重度;Y:重试中) + */ + @TableField("retrying_flag") + private String retryingFlag; + + /** + * 重试次数 + */ + @TableField("retry_count") + private Integer retryCount; + + /** + * 通知策略(30, 60, 120) + */ + @TableField("notify_rule") + private String notifyRule; + + /** + * 重试时间 + */ + @TableField("retry_at") + private Date retryAt; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRequestLog.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRequestLog.java new file mode 100644 index 00000000..2f72613c --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageRequestLog.java @@ -0,0 +1,65 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import cn.axzo.trade.datasecurity.core.annotation.CryptField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 外部系统请求表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_request_log") +public class MessageRequestLog extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 应用no + */ + @TableField("app_no") + private String appNo; + + /** + * APP请求号 + */ + @TableField("request_no") + private String requestNo; + + /** + * 请求方法 + */ + @TableField("method_name") + private String methodName; + + /** + * 请求体 + */ + @TableField("request_body") + @CryptField + private String requestBody; + + /** + * 响应体 + */ + @TableField("response_body") + private String responseBody; + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplate.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplate.java new file mode 100644 index 00000000..1f217c29 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplate.java @@ -0,0 +1,86 @@ +package cn.axzo.msg.notices.dao.entity; + +import cn.axzo.msg.notices.common.enums.YesNoEnum; +import cn.axzo.msg.notices.dao.persistence.BaseOwnEntity; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 内部消息模板表 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_template") +public class MessageTemplate extends BaseOwnEntity { + + private static final long serialVersionUID=1L; + + /** + * 模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 模板名称 + */ + @TableField("title") + private String title; + + /** + * 模板类型(1:验证码;2:短信通知;3:推广短信;4:群发助手) + */ + @TableField("type") + private Integer type; + + /** + * 模板内容 + */ + @TableField("template_content") + private String templateContent; + + /** + * 状态(0:不可用;1:可用) + */ + @TableField("status") + private Integer status; + + /** + * 模板是否有变量(0:没有;1:有) + */ + @TableField("has_param") + private Integer hasParam; + + /** + * 申请原因 + */ + @TableField("reason") + private String reason; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + @Override + protected Serializable pkVal() { + return this.id; + } + + public boolean hasParam() { + return YesNoEnum.YES.getCode().equals(hasParam); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplateParam.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplateParam.java new file mode 100644 index 00000000..41c1167b --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/entity/MessageTemplateParam.java @@ -0,0 +1,103 @@ +package cn.axzo.msg.notices.dao.entity; + +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 com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 渠道模板变量序列表 + *

+ * + * @author szg + * @since 2021-08-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("message_template_param") +public class MessageTemplateParam extends Model { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 渠道模板号 + */ + @TableField("template_no") + private String templateNo; + + /** + * 变量名称 + */ + @TableField("param_name") + private String paramName; + + /** + * 变量描述 + */ + @TableField("param_desc") + private String paramDesc; + + /** + * 变量排序(升序:数字越小,排在越前) + */ + @TableField("param_order") + private Integer paramOrder; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 创建时间 + */ + @TableField("create_at") + private Date createAt; + + /** + * 修改时间 + */ + @TableField("update_at") + private Date updateAt; + + /** + * 创建人 + */ + @TableField("create_by") + private String createBy; + + /** + * 修改人 + */ + @TableField("update_by") + private String updateBy; + + /** + * 是否删除(0:未删除;1:已删除) + */ + @TableField("is_delete") + private Integer isDelete; + + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageMapper.java new file mode 100644 index 00000000..9664abca --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageMapper.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.domain.BatchMessageStatisticsResponseDto; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 渠道模板变量序列表 Mapper 接口 + *

+ * + * @author szg + * @since 2021-08-09 + */ +public interface BatchMessageMapper extends BaseMapper { + + BatchMessageStatisticsResponseDto getStatisticsMessageInfo(@Param("appNo") String appNo, + @Param("requestNo") String requestNo); + + BatchMessage getByChannelMsgIdAndLock(@Param("msgId") String msgId); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageRequestMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageRequestMapper.java new file mode 100644 index 00000000..8d364878 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/BatchMessageRequestMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 渠道模板变量序列表 Mapper 接口 + *

+ * + * @author szg + * @since 2021-08-09 + */ +public interface BatchMessageRequestMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/ChannelMessageTemplateMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/ChannelMessageTemplateMapper.java new file mode 100644 index 00000000..b3798963 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/ChannelMessageTemplateMapper.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 渠道消息模板表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface ChannelMessageTemplateMapper extends BaseMapper { + + /** + * 按照短信编码删除 + */ + Integer deleteByTemplateNo(@Param("templateNo") String templateNo); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageAppMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageAppMapper.java new file mode 100644 index 00000000..986f4fd4 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageAppMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageApp; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 消息应用表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageAppMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelLogMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelLogMapper.java new file mode 100644 index 00000000..ca830233 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelLogMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageChannelLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 请求消息渠道日志表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageChannelLogMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelMapper.java new file mode 100644 index 00000000..4eb2ddb6 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageChannelMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageChannel; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 消息渠道表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageChannelMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageMapper.java new file mode 100644 index 00000000..dbf24540 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.Message; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 消息记录表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRedoMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRedoMapper.java new file mode 100644 index 00000000..6e780ec4 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRedoMapper.java @@ -0,0 +1,8 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface MessageRedoMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRequestLogMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRequestLogMapper.java new file mode 100644 index 00000000..f02f209e --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageRequestLogMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 外部系统请求表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageRequestLogMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateMapper.java new file mode 100644 index 00000000..7d374741 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateMapper.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 内部消息模板表 Mapper 接口 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageTemplateMapper extends BaseMapper { + /** + * 按照短信编码删除 + */ + Integer deleteByTemplateNo(@Param("templateNo") String templateNo); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateParamMapper.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateParamMapper.java new file mode 100644 index 00000000..f06bb9e0 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/mapper/MessageTemplateParamMapper.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.mapper; + +import cn.axzo.msg.notices.dao.entity.MessageTemplateParam; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 渠道模板变量序列表 Mapper 接口 + *

+ * + * @author szg + * @since 2021-08-07 + */ +public interface MessageTemplateParamMapper extends BaseMapper { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseDataEntity.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseDataEntity.java new file mode 100644 index 00000000..f4935cad --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseDataEntity.java @@ -0,0 +1,13 @@ +package cn.axzo.msg.notices.dao.persistence; + +import com.baomidou.mybatisplus.extension.activerecord.Model; + +/** + * Entity 支持类 + * + * @author Smile + * @date 2019/3/26 17:33 + */ +public abstract class BaseDataEntity> extends BaseEntity { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseEntity.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseEntity.java new file mode 100644 index 00000000..f03f5ce5 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseEntity.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.notices.dao.persistence; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +import java.util.Date; + +/** + * 实体的基类 + * + * @author Smile + */ +@Data +public abstract class BaseEntity> extends Model { + + /** + * id + */ + @TableId(type = IdType.AUTO) + protected Long id; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + protected Date createAt; + + /** + * 修改时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + protected Date updateAt; + + /** + * 是否删除 + */ + @TableLogic + @TableField("is_delete") + protected Integer isDelete; + + { + isDelete = 0; + } +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseOwnEntity.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseOwnEntity.java new file mode 100644 index 00000000..044c7d67 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/persistence/BaseOwnEntity.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.dao.persistence; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; + +/** + * Entity 支持类 + * + * @author Smile + * @date 2019/3/26 17:33 + */ +@Data +public abstract class BaseOwnEntity> extends BaseDataEntity { + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + protected String createBy; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.UPDATE) + protected String updateBy; +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageDao.java new file mode 100644 index 00000000..579de115 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageDao.java @@ -0,0 +1,35 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.domain.BatchMessageQuery; +import cn.axzo.msg.notices.dao.domain.BatchMessageStatisticsResponseDto; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 渠道模板变量序列表 服务类 + *

+ * + * @author szg + * @since 2021-08-09 + */ +public interface BatchMessageDao extends IService { + + IPage queryByPage(BatchMessageQuery query); + + BatchMessage queryBatchMessage(String batchNo); + + boolean updateBatchMessage(BatchMessage batchMessage, String batchNo); + + BatchMessage getByChannelMsgIdAndLock(String msgId); + + boolean updateChannelInfo(String channelCode, String templateNo, String batchNo); + + BatchMessageStatisticsResponseDto getStatisticsMessageInfo(String appNo, String requestNo); + + Boolean updateStatusById(Long id, Integer status); + + Boolean updateBachMessageInfoById(Long id, Integer status, Integer successCount, + Integer failCount); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageRequestDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageRequestDao.java new file mode 100644 index 00000000..88652bfe --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/BatchMessageRequestDao.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.domain.BatchMessageRequestQuery; +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 渠道模板变量序列表 服务类 + *

+ * + * @author szg + * @since 2021-08-09 + */ +public interface BatchMessageRequestDao extends IService { + + IPage queryByPage(BatchMessageRequestQuery query); + + BatchMessageRequest queryBatchMessage(String appCode, String requestNo); + + boolean updateStatusById(Long id, Integer status); + + boolean updateBatchMessageRequestInfoById(Long id, Integer status, Integer successCount, + Integer failCount); + + boolean updateRequestSuccess(String remark, Long id); + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/ChannelMessageTemplateDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/ChannelMessageTemplateDao.java new file mode 100644 index 00000000..001c0e3a --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/ChannelMessageTemplateDao.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 渠道消息模板表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface ChannelMessageTemplateDao extends IService { + + ChannelMessageTemplate queryByTemplateNo(String innerTemplateNo, String channelCode); + + ChannelMessageTemplate queryByChannelTemplateNo(String channelTemplateNo); + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageAppDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageAppDao.java new file mode 100644 index 00000000..7d2091f2 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageAppDao.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageApp; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 消息应用表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageAppDao extends IService { + + /** + * 通过appCode获取 + * @param appCode + * @return + */ + MessageApp queryByAppCode(String appCode); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelDao.java new file mode 100644 index 00000000..5a374a34 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelDao.java @@ -0,0 +1,23 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageChannel; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + *

+ * 消息渠道表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageChannelDao extends IService { + + /** + * 获取可用的渠道 + * @return + */ + List queryAvailable(); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelLogDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelLogDao.java new file mode 100644 index 00000000..e0aa4cce --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageChannelLogDao.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageChannelLog; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 请求消息渠道日志表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageChannelLogDao extends IService { + + boolean updateCallbackDate(String toJSONString, String messageOrderNo); + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageDao.java new file mode 100644 index 00000000..00009d43 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageDao.java @@ -0,0 +1,75 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.domain.MessageQuery; +import cn.axzo.msg.notices.dao.entity.Message; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 消息记录表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageDao extends IService { + + /** + * 分页查询消息 + * @param query + * @return + */ + IPage queryByPage(MessageQuery query); + + /** + * 渠道网络异常 + * @param id + * @return + */ + boolean channelException(Long id); + + Boolean updateExceptionToFail(String messageOrderNo); + + /** + * 通过批次号和手机号查询message + * @param batchNo + * @param mobile + * @return + */ + Message getByBatchNoAndPhone(String batchNo, String mobile); + + /** + * 根据渠道响应查询 + * @param channelMsgId + * @param mobile + * @return + */ + Message getByChannelMsgId(String channelMsgId, String mobile); + + /** + * 更新批量消息渠道消息 + * @param channelCode + * @param channelName + * @param batchNo + * @return + */ + boolean updateBatchMessageChannelInfo(String channelCode, String channelName, String batchNo); + + /** + * 更新所有批量消息失败 + * @param errorMsg + * @param batchNo + * @return + */ + boolean updateAllBatchMessageFail(String errorMsg, String batchNo); + + /** + * 更新消息状态和备注 + * @param id + * @param status + * @param remark + * @return + */ + boolean updateStatusAndRemarkById(Long id, String status, String remark); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRedoDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRedoDao.java new file mode 100644 index 00000000..0e52ad75 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRedoDao.java @@ -0,0 +1,15 @@ +package cn.axzo.msg.notices.dao.repository; + + +import cn.axzo.msg.notices.dao.domain.MessageRedoQuery; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; + +public interface MessageRedoDao extends IService { + + IPage queryByPage(MessageRedoQuery query); + + boolean updateExceptionToFail(Long id); + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRequestLogDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRequestLogDao.java new file mode 100644 index 00000000..7687236e --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageRequestLogDao.java @@ -0,0 +1,16 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 外部系统请求表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageRequestLogDao extends IService { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateDao.java new file mode 100644 index 00000000..adda4c07 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateDao.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 内部消息模板表 服务类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +public interface MessageTemplateDao extends IService { + + /** + * 通过模板号查询 + * @param templateNo + * @return + */ + MessageTemplate queryByTemplateNo(String templateNo); +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateParamDao.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateParamDao.java new file mode 100644 index 00000000..f6f556d4 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/MessageTemplateParamDao.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.dao.repository; + +import cn.axzo.msg.notices.dao.entity.MessageTemplateParam; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +/** + *

+ * 渠道模板变量序列表 服务类 + *

+ * + * @author szg + * @since 2021-08-07 + */ +public interface MessageTemplateParamDao extends IService { + + List getByTemplateNo(String templateNo); + + List getAllMessageTemplateParams(); + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageDaoImpl.java new file mode 100644 index 00000000..dfb441ac --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageDaoImpl.java @@ -0,0 +1,106 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.IsDeletedEnum; +import cn.axzo.msg.notices.dao.domain.BatchMessageQuery; +import cn.axzo.msg.notices.dao.domain.BatchMessageStatisticsResponseDto; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.dao.mapper.BatchMessageMapper; +import cn.axzo.msg.notices.dao.repository.BatchMessageDao; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; + +import javax.annotation.Resource; +import java.util.Objects; + +/** + *

+ * 渠道模板变量序列表 Dao实现类 + *

+ * + * @author szg + * @since 2021-08-09 + */ +@Repository("batchMessageDao") +public class BatchMessageDaoImpl extends ServiceImpl implements BatchMessageDao { + + @Resource + private BatchMessageMapper batchMessageMapper; + + @Override + public IPage queryByPage(BatchMessageQuery query) { + + return this.page(query.toPage(), new LambdaQueryWrapper() + .eq(query.getId() != null, BatchMessage::getId, query.getId()) + .ge(query.getStartCreateTime() != null, BatchMessage::getCreateAt, query.getStartCreateTime()) + .le(query.getEndCreateTime() != null, BatchMessage::getCreateAt, query.getEndCreateTime()) + .in(CollectionUtils.isNotEmpty(query.getStatuses()), BatchMessage::getStatus, query.getStatuses()) + .eq(Objects.nonNull(query.getSendType()),BatchMessage::getSendType,query.getSendType()) + .eq(BatchMessage::getIsDelete, 0) + .orderByDesc(BatchMessage::getCreateAt) + ); + } + + @Override + public BatchMessage queryBatchMessage(String batchNo) { + return this.lambdaQuery() + .eq(BatchMessage::getBatchNo, batchNo) + .eq(BatchMessage::getIsDelete, IsDeletedEnum.NO.getCode()) + .one(); + } + + @Override + public boolean updateBatchMessage(BatchMessage batchMessage, String batchNo) { + return this.update(batchMessage, new UpdateWrapper() + .eq("batch_no", batchNo) + .eq("is_delete", IsDeletedEnum.NO.getCode())); + } + + @Override + public boolean updateChannelInfo(String channelCode, String channelTemplateNo, String batchNo) { + return this.lambdaUpdate() + .set(BatchMessage::getChannelCode, channelCode) + .set(BatchMessage::getChannelTemplateNo, channelTemplateNo) + .eq(BatchMessage::getBatchNo, batchNo) + .eq(BatchMessage::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + + @Override + public BatchMessageStatisticsResponseDto getStatisticsMessageInfo(String appNo, + String requestNo) { + + return batchMessageMapper.getStatisticsMessageInfo(appNo,requestNo); + } + + @Override + public Boolean updateStatusById(Long id, Integer status) { + return lambdaUpdate() + .set(BatchMessage::getStatus,status) + .eq(BatchMessage::getId,id) + .eq(BatchMessage::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + + @Override + public Boolean updateBachMessageInfoById(Long id, Integer status, + Integer successCount, Integer failCount) { + return lambdaUpdate() + .set(BatchMessage::getStatus, status) + .set(BatchMessage::getSuccessCount,successCount) + .set(BatchMessage::getFailCount,failCount) + .eq(BatchMessage::getId, id) + .eq(BatchMessage::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + + @Override + public BatchMessage getByChannelMsgIdAndLock(String msgId) { + return batchMessageMapper.getByChannelMsgIdAndLock(msgId); + + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageRequestDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageRequestDaoImpl.java new file mode 100644 index 00000000..d461a6ef --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/BatchMessageRequestDaoImpl.java @@ -0,0 +1,81 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.BatchMessageStatusEnum; +import cn.axzo.msg.notices.dao.domain.BatchMessageRequestQuery; +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import cn.axzo.msg.notices.dao.mapper.BatchMessageRequestMapper; +import cn.axzo.msg.notices.dao.repository.BatchMessageRequestDao; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Repository; + +import java.util.Objects; + +/** + *

+ * 渠道模板变量序列表 Dao实现类 + *

+ * + * @author szg + * @since 2021-08-09 + */ +@Repository("batchMessageRequestDao") +public class BatchMessageRequestDaoImpl extends + ServiceImpl implements BatchMessageRequestDao { + + @Override + public IPage queryByPage(BatchMessageRequestQuery query) { + + return this.page(query.toPage(), new LambdaQueryWrapper() + .eq(query.getId() != null, BatchMessageRequest::getId, query.getId()) + .ge(query.getStartCreateTime() != null, BatchMessageRequest::getCreateAt, query.getStartCreateTime()) + .le(query.getEndCreateTime() != null, BatchMessageRequest::getCreateAt, query.getEndCreateTime()) + .in(CollectionUtils.isNotEmpty(query.getStatuses()), BatchMessageRequest::getStatus, query.getStatuses()) + .eq(Objects.nonNull(query.getSendType()),BatchMessageRequest::getSendType,query.getSendType()) + .eq(BatchMessageRequest::getIsDelete, 0) + .orderByDesc(BatchMessageRequest::getCreateAt) + ); + + } + + @Override + public BatchMessageRequest queryBatchMessage(String appCode, String requestNo) { + return this.lambdaQuery() + .eq(BatchMessageRequest::getAppNo, appCode) + .eq(BatchMessageRequest::getRequestNo, requestNo) + .one(); + } + + @Override + public boolean updateStatusById(Long id, Integer status) { + return lambdaUpdate() + .set(BatchMessageRequest::getStatus,status) + .eq(BatchMessageRequest::getId,id) + .eq(BatchMessageRequest::getIsDelete, 0) + .update(); + } + + @Override + public boolean updateBatchMessageRequestInfoById(Long id, Integer status, + Integer successCount, Integer failCount) { + return lambdaUpdate() + .set(BatchMessageRequest::getStatus,status) + .set(BatchMessageRequest::getSuccessCount,successCount) + .set(BatchMessageRequest::getFailCount,failCount) + .eq(BatchMessageRequest::getId,id) + .eq(BatchMessageRequest::getIsDelete, 0) + .update(); + } + + @Override + public boolean updateRequestSuccess(String remark, Long id) { + return lambdaUpdate() + .set(BatchMessageRequest::getRemark, remark) + .set(BatchMessageRequest::getStatus, BatchMessageStatusEnum.SEND_SUCCESS.getCode()) + .eq(BatchMessageRequest::getId, id) + .update(); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/ChannelMessageTemplateDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/ChannelMessageTemplateDaoImpl.java new file mode 100644 index 00000000..8fb3daa2 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/ChannelMessageTemplateDaoImpl.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.dao.mapper.ChannelMessageTemplateMapper; +import cn.axzo.msg.notices.dao.repository.ChannelMessageTemplateDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +/** + *

+ * 渠道消息模板表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("channelMessageTemplateDao") +public class ChannelMessageTemplateDaoImpl extends ServiceImpl implements ChannelMessageTemplateDao { + + @Override + public ChannelMessageTemplate queryByTemplateNo(String innerTemplateNo, String channelCode) { + return this.lambdaQuery() + .eq(ChannelMessageTemplate::getInnerTemplateNo, innerTemplateNo) + .eq(ChannelMessageTemplate::getChannelCode, channelCode) + .one(); + } + + @Override + public ChannelMessageTemplate queryByChannelTemplateNo(String channelTemplateNo) { + return this.lambdaQuery().eq(ChannelMessageTemplate::getTemplateNo, channelTemplateNo) + .eq(ChannelMessageTemplate::getIsDelete, 0) + .one(); + } +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageAppDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageAppDaoImpl.java new file mode 100644 index 00000000..19de8222 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageAppDaoImpl.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.dao.entity.MessageApp; +import cn.axzo.msg.notices.dao.mapper.MessageAppMapper; +import cn.axzo.msg.notices.dao.repository.MessageAppDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +/** + *

+ * 消息应用表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageAppDao") +public class MessageAppDaoImpl extends ServiceImpl implements MessageAppDao { + + @Override + public MessageApp queryByAppCode(String appCode) { + return this.lambdaQuery() + .eq(MessageApp::getAppCode, appCode) + .one(); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelDaoImpl.java new file mode 100644 index 00000000..127cd4e8 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelDaoImpl.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.AvailableStatusEnum; +import cn.axzo.msg.notices.dao.entity.MessageChannel; +import cn.axzo.msg.notices.dao.mapper.MessageChannelMapper; +import cn.axzo.msg.notices.dao.repository.MessageChannelDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + *

+ * 消息渠道表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageChannelDao") +public class MessageChannelDaoImpl extends ServiceImpl implements MessageChannelDao { + + @Override + public List queryAvailable() { + return this.lambdaQuery() + .eq(MessageChannel::getStatus, AvailableStatusEnum.AVAILABLE.getStatus()) + .list(); + } +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelLogDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelLogDaoImpl.java new file mode 100644 index 00000000..2e34b1a0 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageChannelLogDaoImpl.java @@ -0,0 +1,30 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.IsDeletedEnum; +import cn.axzo.msg.notices.dao.entity.MessageChannelLog; +import cn.axzo.msg.notices.dao.mapper.MessageChannelLogMapper; +import cn.axzo.msg.notices.dao.repository.MessageChannelLogDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +/** + *

+ * 请求消息渠道日志表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageChannelLogDao") +public class MessageChannelLogDaoImpl extends ServiceImpl implements MessageChannelLogDao { + + @Override + public boolean updateCallbackDate(String callbackDate, String messageOrderNo) { + return this.lambdaUpdate() + .set(MessageChannelLog::getCallbackData, callbackDate) + .eq(MessageChannelLog::getMessageOrderNo, messageOrderNo) + .eq(MessageChannelLog::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageDaoImpl.java new file mode 100644 index 00000000..a84dcb74 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageDaoImpl.java @@ -0,0 +1,110 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.IsDeletedEnum; +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.dao.domain.MessageQuery; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.mapper.MessageMapper; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Repository; + +import java.util.Date; + +/** + *

+ * 消息记录表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageDao") +public class MessageDaoImpl extends ServiceImpl implements MessageDao { + + @Override + public IPage queryByPage(MessageQuery query) { + return this.page(query.toPage(), new LambdaQueryWrapper() + .eq(query.getId() != null, Message::getId, query.getId()) + .ge(query.getStartCreateTime() != null, Message::getCreateAt, query.getStartCreateTime()) + .le(query.getEndCreateTime() != null, Message::getCreateAt, query.getEndCreateTime()) + .in(CollectionUtils.isNotEmpty(query.getStatuses()), Message::getStatus, query.getStatuses()) + .eq(StringUtils.isNoneBlank(query.getChannelCode()), Message::getChannelCode, query.getChannelCode()) + .eq(Message::getIsDelete, IsDeletedEnum.NO.getCode()) + .orderByDesc(Message::getCreateAt)); + } + + @Override + public boolean channelException(Long id) { + return this.lambdaUpdate() + .set(Message::getStatus, MessageStatusEnum.EXCEPTION.getCode()) + .set(Message::getUpdateAt, new Date()) + .eq(Message::getId, id) + .eq(Message::getStatus, MessageStatusEnum.INIT.getCode()) + .update(); + } + + @Override + public Boolean updateExceptionToFail(String messageOrderNo) { + return lambdaUpdate() + .set(Message::getStatus, MessageStatusEnum.FAIL.getCode()) + .eq(Message::getMessageOrderNo, messageOrderNo) + .eq(Message::getStatus, MessageStatusEnum.EXCEPTION.getCode()) + .update(); + } + + @Override + public Message getByBatchNoAndPhone(String batchNo, String mobile) { + return lambdaQuery() + .eq(Message::getBatchNo,batchNo) + .eq(Message::getTargetAddress,mobile) + .eq(Message::getStatus,MessageStatusEnum.INIT.getCode()) + .eq(Message::getIsDelete,0) + .one(); + } + + @Override + public Message getByChannelMsgId(String channelMsgId, String mobile) { + return lambdaQuery() + .eq(Message::getTargetAddress,mobile) + .eq(Message::getChannelRequestId, channelMsgId) + .eq(Message::getIsDelete,0) + .one(); + } + + @Override + public boolean updateBatchMessageChannelInfo(String channelCode, String channelName, String batchNo) { + return lambdaUpdate() + .set(Message::getChannelCode, channelCode) + .set(Message::getChannelName, channelName) + .eq(Message::getBatchNo, batchNo) + .eq(Message::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + + @Override + public boolean updateAllBatchMessageFail(String errorMsg, String batchNo) { + return lambdaUpdate() + .set(Message::getRemark, errorMsg) + .set(Message::getStatus, MessageStatusEnum.FAIL.getCode()) + .eq(Message::getBatchNo, batchNo) + .eq(Message::getIsDelete, IsDeletedEnum.NO.getCode()) + .update(); + } + + @Override + public boolean updateStatusAndRemarkById(Long id, String status, String remark) { + + return lambdaUpdate() + .eq(Message::getId,id) + .set(Message::getStatus,status) + .set(Message::getUpdateAt, new Date()) + .set(!StringUtils.isEmpty(remark),Message::getRemark,remark) + .update(); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRedoDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRedoDaoImpl.java new file mode 100644 index 00000000..fa3f9968 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRedoDaoImpl.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.IsDeletedEnum; +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.common.enums.RetryingFlagEnum; +import cn.axzo.msg.notices.dao.domain.MessageRedoQuery; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.dao.mapper.MessageRedoMapper; +import cn.axzo.msg.notices.dao.repository.MessageRedoDao; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Repository; + +@Repository("messageRedoDao") +public class MessageRedoDaoImpl extends ServiceImpl implements MessageRedoDao { + + @Override + public IPage queryByPage(MessageRedoQuery query) { + return this.page(query.toPage(), new LambdaQueryWrapper() + .eq(query.getId() != null, MessageRedo::getId, query.getId()) + .ge(query.getStartCreateTime() != null, MessageRedo::getCreateAt, query.getStartCreateTime()) + .le(query.getEndCreateTime() != null, MessageRedo::getCreateAt, query.getEndCreateTime()) + .in(CollectionUtils.isNotEmpty(query.getStatuses()), MessageRedo::getStatus, query.getStatuses()) + .eq(StringUtils.isNoneBlank(query.getChannelCode()), MessageRedo::getChannelCode, query.getChannelCode()) + .eq(MessageRedo::getRetryingFlag, RetryingFlagEnum.Y.name()) + .eq(MessageRedo::getIsDelete, IsDeletedEnum.NO.getCode()) + .orderByDesc(MessageRedo::getCreateAt)); + } + + @Override + public boolean updateExceptionToFail(Long id) { + return lambdaUpdate() + .set(MessageRedo::getStatus, MessageStatusEnum.FAIL.getCode()) + .eq(MessageRedo::getId, id) + .eq(MessageRedo::getStatus, MessageStatusEnum.EXCEPTION.getCode()) + .update(); + } +} \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRequestLogDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRequestLogDaoImpl.java new file mode 100644 index 00000000..6cb66ffe --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageRequestLogDaoImpl.java @@ -0,0 +1,20 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; +import cn.axzo.msg.notices.dao.mapper.MessageRequestLogMapper; +import cn.axzo.msg.notices.dao.repository.MessageRequestLogDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +/** + *

+ * 外部系统请求表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageRequestLogDao") +public class MessageRequestLogDaoImpl extends ServiceImpl implements MessageRequestLogDao { + +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateDaoImpl.java new file mode 100644 index 00000000..c7ea71a3 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateDaoImpl.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import cn.axzo.msg.notices.dao.mapper.MessageTemplateMapper; +import cn.axzo.msg.notices.dao.repository.MessageTemplateDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +/** + *

+ * 内部消息模板表 Dao实现类 + *

+ * + * @author zhaoyong + * @since 2021-05-19 + */ +@Repository("messageTemplateDao") +public class MessageTemplateDaoImpl extends ServiceImpl implements MessageTemplateDao { + + + @Override + public MessageTemplate queryByTemplateNo(String templateNo) { + return this.lambdaQuery() + .eq(MessageTemplate::getTemplateNo, templateNo) + .one(); + } +} diff --git a/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateParamDaoImpl.java b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateParamDaoImpl.java new file mode 100644 index 00000000..34343147 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/java/cn/axzo/msg/notices/dao/repository/impl/MessageTemplateParamDaoImpl.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.dao.repository.impl; + +import cn.axzo.msg.notices.common.enums.IsDeletedEnum; +import cn.axzo.msg.notices.dao.entity.MessageTemplateParam; +import cn.axzo.msg.notices.dao.mapper.MessageTemplateParamMapper; +import cn.axzo.msg.notices.dao.repository.MessageTemplateParamDao; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + *

+ * 渠道模板变量序列表 Dao实现类 + *

+ * + * @author szg + * @since 2021-08-07 + */ +@Repository("messageTemplateParamDao") +public class MessageTemplateParamDaoImpl extends ServiceImpl implements + MessageTemplateParamDao { + + @Override + public List getByTemplateNo(String templateNo) { + return this.lambdaQuery().eq(MessageTemplateParam::getTemplateNo, templateNo) + .eq(MessageTemplateParam::getIsDelete, IsDeletedEnum.NO.getCode()) + .orderByAsc(MessageTemplateParam::getParamOrder) + .list(); + } + + @Override + public List getAllMessageTemplateParams() { + return this.lambdaQuery() + .eq(MessageTemplateParam::getIsDelete, IsDeletedEnum.NO.getCode()) + .list(); + } + +} diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageMapper.xml new file mode 100644 index 00000000..d24364ff --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, request_no, batch_no, app_no, template_no, channel_template_no, message_order_no, sms_content, batch_size, success_count, fail_count, send_type, status, submit_success_num, submit_fail_num, channel_msg_id, channel_code, channel_return_code, channel_error_msg, create_at, update_at, is_delete + + + + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageRequestMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageRequestMapper.xml new file mode 100644 index 00000000..e98da982 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/BatchMessageRequestMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id, app_no, request_no, template_no, sms_content, total_size, success_count, fail_count, repeat_count, send_type, status, remark, create_at, update_at, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/ChannelMessageTemplateMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/ChannelMessageTemplateMapper.xml new file mode 100644 index 00000000..ec4375d3 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/ChannelMessageTemplateMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, inner_template_no, template_no, channel_code, channel_name, title, template_content, type, status, has_param, remark, reason, create_at, update_at, create_by, update_by, is_delete + + + delete from channel_message_template where inner_template_no = #{templateNo} + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageAppMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageAppMapper.xml new file mode 100644 index 00000000..95f71c03 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageAppMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + id, app_code, app_name, status, remark, extension, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelLogMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelLogMapper.xml new file mode 100644 index 00000000..6de71096 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelLogMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, app_no, app_request_no, message_order_no, target_address, response_data, callback_data, task_data, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelMapper.xml new file mode 100644 index 00000000..4874b523 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageChannelMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + id, channel_code, channel_name, status, priority, config_json, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageMapper.xml new file mode 100644 index 00000000..dc8ee9aa --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, app_no, request_no, message_order_no, message_type, notify_type, status, channel_code, channel_name, template_no, subject, target_address, channel_biz_id, channel_request_id, notify_rule, remark, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRedoMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRedoMapper.xml new file mode 100644 index 00000000..0093470f --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRedoMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, app_no, request_no, message_order_no, redo_order_no,channel_biz_id, message_type, notify_type, + `status`, channel_code, channel_name, template_no, subject, target_address, retrying_flag, + retry_count, notify_rule, retry_at, create_at, update_at, create_by, update_by, is_delete + + \ No newline at end of file diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRequestLogMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRequestLogMapper.xml new file mode 100644 index 00000000..0e158209 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageRequestLogMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + id, app_no, request_no, method_name, request_body, response_body, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateMapper.xml new file mode 100644 index 00000000..2fcd5ce9 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, template_no, title, template_content, type, status, reason, remark, create_at, update_at, create_by, update_by, is_delete + + + delete from message_template where template_no = #{templateNo} + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateParamMapper.xml b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateParamMapper.xml new file mode 100644 index 00000000..bb498934 --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/mapper/MessageTemplateParamMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + id, template_no, param_name, param_desc, param_order, remark, create_at, update_at, create_by, update_by, is_delete + + + diff --git a/msg-notices/msg-notices-dao/src/main/resources/templates/serviceimpl.java.vm b/msg-notices/msg-notices-dao/src/main/resources/templates/serviceimpl.java.vm new file mode 100644 index 00000000..ec6a4c0a --- /dev/null +++ b/msg-notices/msg-notices-dao/src/main/resources/templates/serviceimpl.java.vm @@ -0,0 +1,26 @@ +package ${package.ServiceImpl}; + +import ${package.Entity}.${entity}; +import ${package.Mapper}.${table.mapperName}; +import ${package.Service}.${table.serviceName}; +import ${superServiceImplClassPackage}; +import org.springframework.stereotype.Repository; + +/** + *

+ * $!{table.comment} Dao实现类 + *

+ * + * @author ${author} + * @since ${date} + */ +@Repository("${table.serviceName.substring(0,1).toLowerCase().concat(${table.serviceName.substring(1)})}") +#if(${kotlin}) +open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} { + + } +#else +public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} { + +} +#end diff --git a/msg-notices/msg-notices-http-api/pom.xml b/msg-notices/msg-notices-http-api/pom.xml new file mode 100644 index 00000000..0409d9d2 --- /dev/null +++ b/msg-notices/msg-notices-http-api/pom.xml @@ -0,0 +1,41 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.http.api + msg-notices-http-api + + + 8 + 8 + UTF-8 + + + + + cn.axzo.framework + axzo-common + + + javax.validation + validation-api + + + org.hibernate.validator + hibernate-validator + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/api/MessageNotifyApi.java b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/api/MessageNotifyApi.java new file mode 100644 index 00000000..904078cd --- /dev/null +++ b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/api/MessageNotifyApi.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.http.api.api; + + +import cn.axzo.msg.notices.http.api.request.SendBatchMessageRequest; +import cn.axzo.msg.notices.http.api.request.SendMobileMessageRequest; +import cn.azxo.framework.common.model.CommonResponse; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * 短信通知接口 + * + * @author zhaoyong_sh + * @see MessageNotifyApi + * @since 2021-05-20 11:27 + */ +@FeignClient( + name = "mns", + url = "http://mns:8989" +) +public interface MessageNotifyApi { + + /** + * 发送手机短信 + * @param request + * @return + */ + @RequestMapping(value = "/api/v1/message/send", method = RequestMethod.POST) + CommonResponse sendMobileMessage(SendMobileMessageRequest request); + + /** + * 批量发送短信 + * @param request + * @return + */ + @RequestMapping(value = "/api/v1/message/batch", method = RequestMethod.POST) + CommonResponse sendBatchMessage(SendBatchMessageRequest request); + +} diff --git a/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendBatchMessageRequest.java b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendBatchMessageRequest.java new file mode 100644 index 00000000..2b845533 --- /dev/null +++ b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendBatchMessageRequest.java @@ -0,0 +1,56 @@ +package cn.axzo.msg.notices.http.api.request; + +import cn.azxo.framework.common.annotation.ValidNumberValue; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 批量发送短信请求 + * + * @author zhaoyong + * @see SendBatchMessageRequest + * @since 2021-08-05 12:50 + */ +@Data +public class SendBatchMessageRequest { + + /** + * 请求号 + */ + @NotBlank(message = "request no must not be null") + private String requestNo; + + /** + * 应用接入码 + */ + @NotBlank(message = "app code must not be null") + private String appCode; + + /** + * 消息模板号 + */ + @NotBlank(message = "templateNo must not be null") + private String templateNo; + + /** + * 发送类型 + * + * 1:实时;2:非实时 + * + */ + @NotNull(message = "sendType must not be null") + @ValidNumberValue(value = {1, 2}, message = "sendType must be in {value}") + private Integer sendType; + + /** + * 消息内容 + */ + @Valid + @NotNull(message = "smsContents must not be null") + private List smsContents; + +} diff --git a/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendMobileMessageRequest.java b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendMobileMessageRequest.java new file mode 100644 index 00000000..176e65d8 --- /dev/null +++ b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SendMobileMessageRequest.java @@ -0,0 +1,42 @@ +package cn.axzo.msg.notices.http.api.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.HashMap; +import java.util.Map; + +/** + * 发送手机信息请求类 + * + * @author zhaoyong_sh + * @see SendMobileMessageRequest + * @since 2021-05-20 11:28 + */ +@Data +public class SendMobileMessageRequest { + + /** 请求号 */ + @NotBlank(message = "request no must not be null") + private String requestNo; + + /** 应用接入码 */ + @NotBlank(message = "app code must not be null") + private String appCode; + + /** 短信模板号 */ + @NotBlank(message = "template no must not be null") + private String templateNo; + + /** 电话号码 */ + @NotBlank(message = "phone no must not be null") + private String phoneNo; + + /** 短信模板变更 */ + @NotNull(message = "params must not be null") + private Map params = new HashMap<>(); + /** 扩展参数 */ + private String expansion; + +} diff --git a/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SmsContent.java b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SmsContent.java new file mode 100644 index 00000000..4f275441 --- /dev/null +++ b/msg-notices/msg-notices-http-api/src/main/java/cn/axzo/msg/notices/http/api/request/SmsContent.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.http.api.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 短信上下文 + * + * @author zhaoyong + * @see SmsContent + * @since 2021-08-05 15:05 + */ +@Data +public class SmsContent { + + /** + * 手机号 + */ + @NotBlank(message = "phoneNo must not be null") + private String phoneNo; + + /** + * 模板参数 + * 使用无变量模板时,可不带templateParams参数 + */ + private String templateParams; + +} diff --git a/msg-notices/msg-notices-integration/pom.xml b/msg-notices/msg-notices-integration/pom.xml new file mode 100644 index 00000000..717cb45e --- /dev/null +++ b/msg-notices/msg-notices-integration/pom.xml @@ -0,0 +1,39 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.integration + msg-notices-integration + + + 8 + 8 + UTF-8 + + + + + cn.axzo.msg.notices.common + msg-notices-common + ${revision} + + + com.aliyun + dysmsapi20170525 + 2.0.4 + + + org.springframework + spring-web + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliYunSmsClient.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliYunSmsClient.java new file mode 100644 index 00000000..d4c3d4a1 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliYunSmsClient.java @@ -0,0 +1,42 @@ +package cn.axzo.msg.notices.integration.client; + +import cn.axzo.msg.notices.common.enums.SendDetailsStatusEnum; +import cn.axzo.msg.notices.integration.dto.request.SendSmsCommonRequest; +import cn.axzo.msg.notices.integration.dto.response.SendSmsCommonResponse; + +/** + * 短信服务 + * + * @author zhaoyong_sh + * @see AliYunSmsClient + * @since 2021-05-19 12:38 + */ +public interface AliYunSmsClient { + + /** + * 查询异常短信发送详情 + * @param cellphone + * @param sendDate + * @param outId + * @return + */ + SendDetailsStatusEnum queryExceptionSendDetails(String cellphone, String sendDate, String outId); + + /** + * 查询处理中短信发送详情 + * @param cellphone + * @param sendDate + * @param bizId + * @return + */ + SendDetailsStatusEnum queryProcessingSendDetail(String cellphone, String sendDate, String bizId); + + + /** + * 通过 + * @param request + * @return + */ + SendSmsCommonResponse sendSms(SendSmsCommonRequest request) throws Exception; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliyunSmsClientFactory.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliyunSmsClientFactory.java new file mode 100644 index 00000000..fd769cac --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/AliyunSmsClientFactory.java @@ -0,0 +1,31 @@ +package cn.axzo.msg.notices.integration.client; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.teaopenapi.models.Config; +import lombok.SneakyThrows; +import org.springframework.stereotype.Component; + +/** + * 阿里云 SMS 客户端工厂 + * + * @author zhaoyong_sh + * @see AliyunSmsClientFactory + * @since 2021-05-19 14:02 + */ +@Component("aliyunSmsClientFactory") +public class AliyunSmsClientFactory { + + @SneakyThrows + public Client getClient(String accessKeyId, String accessKeySecret) { + Config config = new Config() + // 您的AccessKey ID + .setAccessKeyId(accessKeyId) + // 您的AccessKey Secret + .setAccessKeySecret(accessKeySecret) + // Endpoint + .setEndpoint("dysmsapi.aliyuncs.com"); + Client client = new Client(config); + return client; + } + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/ChuangLanSmsClient.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/ChuangLanSmsClient.java new file mode 100644 index 00000000..6c7a67f9 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/ChuangLanSmsClient.java @@ -0,0 +1,17 @@ +package cn.axzo.msg.notices.integration.client; + +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.dto.response.ChuangLanSmsResponse; + +/** + * 创蓝短信客户端 + * + * @author zhaoyong + * @see ChuangLanSmsClient + * @since 2021-08-07 16:57 + */ +public interface ChuangLanSmsClient { + + ChuangLanSmsResponse sendMessage(MessageRequest request); + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/DingDingClient.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/DingDingClient.java new file mode 100644 index 00000000..7ccec8e1 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/DingDingClient.java @@ -0,0 +1,50 @@ +package cn.axzo.msg.notices.integration.client; + +/** + * 钉钉客户端 + * + * @author zhaoyong + * @see DingDingClient + * @since 2021-07-12 11:59 + */ +public interface DingDingClient { + + /** + * 钉钉群通知验证码 + * @param mobile + * @param title + * @param param + */ + void notifyMockMessage(String mobile, String title, String param); + + /** + * 单条短信发送失败 + * @param templateNo + * @param requestNo + * @param errorMsg + */ + void notifySingleMessage(String templateNo, String requestNo, String errorMsg); + + /** + * 批量短信发送失败 + * @param templateNo + * @param batchNo + * @param errorMsg + */ + void notifyBatchMessage(String templateNo, String batchNo, String errorMsg); + + /** + * 渠道回调异常 + * @param channelName + * @param callbackData + * @param errorMsg + */ + void notifyChannelCallback(String channelName, String callbackData, String errorMsg); + + /** + * RocketMQ 不可用 + * @param errorMsg + */ + void notifyRocketMqError(String errorMsg); + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/AliYunSmsClientImpl.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/AliYunSmsClientImpl.java new file mode 100644 index 00000000..0cc567fb --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/AliYunSmsClientImpl.java @@ -0,0 +1,217 @@ +package cn.axzo.msg.notices.integration.client.impl; + +import cn.axzo.msg.notices.common.constans.AliyunConstants; +import cn.axzo.msg.notices.common.domain.ServiceContextHolder; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.enums.SendDetailsStatusEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.integration.client.AliYunSmsClient; +import cn.axzo.msg.notices.integration.client.AliyunSmsClientFactory; +import cn.axzo.msg.notices.integration.dto.request.SendSmsCommonRequest; +import cn.axzo.msg.notices.integration.dto.response.SendSmsCommonResponse; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.*; +import com.aliyun.dysmsapi20170525.models.QuerySendDetailsResponseBody.QuerySendDetailsResponseBodySmsSendDetailDTOs; +import com.aliyun.dysmsapi20170525.models.QuerySendDetailsResponseBody.QuerySendDetailsResponseBodySmsSendDetailDTOsSmsSendDetailDTO; +import com.aliyun.teautil.models.RuntimeOptions; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Optional; + +/** + * 阿里云短信服务 + * + * @author zhaoyong_sh + * @see AliYunSmsClientImpl + * @since 2021-05-19 12:39 + */ +@Slf4j +@Service("aliYunSmsClient") +public class AliYunSmsClientImpl implements AliYunSmsClient { + + @Resource(name = "aliyunSmsClientFactory") + private AliyunSmsClientFactory aliyunSmsClientFactory; + + @Value("${sms.aliyun.accessKeyId}") + private String accessKeyId; + + @Value("${sms.aliyun.accessSecret}") + private String accessSecret; + + @Value("${sms.aliyun.signName}") + private String signName; + + @Override + public SendDetailsStatusEnum queryExceptionSendDetails(String cellphone, String sendDate, + String outId) { + RuntimeOptions runtime = new RuntimeOptions(); + QuerySendDetailsRequest request = new QuerySendDetailsRequest(); + request.setCurrentPage(1L); + request.setPageSize(50L); + request.setPhoneNumber(cellphone); + request.setSendDate(sendDate); + QuerySendDetailsResponse response; + try { + log.info("AliyunSmsService#queryExceptionSendDetails request param is {}", cellphone); + response = getClient().querySendDetailsWithOptions(request, runtime); + log.info("AliyunSmsService#queryExceptionSendDetails response is {}", + JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("AliyunSmsService#queryExceptionSendDetails is error", e); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "query send details fail"); + } + List sendDetailDTOS = checkResponse( + response); + if (CollectionUtils.isEmpty(sendDetailDTOS)) { + return null; + } + Optional matchOutIdOptional = + sendDetailDTOS.stream().filter(v -> outId.equals(v.getOutId())).findFirst(); + if (!matchOutIdOptional.isPresent()) { + return null; + } + QuerySendDetailsResponseBodySmsSendDetailDTOsSmsSendDetailDTO dto = matchOutIdOptional.get(); + SendDetailsStatusEnum sendStatusEnum = SendDetailsStatusEnum.getByCode(dto.getSendStatus()); + BizException.error(sendStatusEnum != null, ReturnCodeEnum.SYSTEM_ERROR, + "非法的响应值:" + dto.getSendStatus()); + return sendStatusEnum; + } + + @Override + public SendDetailsStatusEnum queryProcessingSendDetail(String cellphone, String sendDate, + String bizId) { + RuntimeOptions runtime = new RuntimeOptions(); + QuerySendDetailsRequest request = new QuerySendDetailsRequest(); + request.setCurrentPage(1L); + request.setPageSize(50L); + request.setPhoneNumber(cellphone); + request.setSendDate(sendDate); + request.setBizId(bizId); + QuerySendDetailsResponse response; + try { + log.info("AliyunSmsService#queryExceptionSendDetails request param is {}", cellphone); + response = getClient().querySendDetailsWithOptions(request, runtime); + log.info("AliyunSmsService#queryExceptionSendDetails response is {}", + JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("AliyunSmsService#queryExceptionSendDetails is error", e); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "query send details fail"); + } + List sendDetailDTOS = checkResponse( + response); + if (CollectionUtils.isEmpty(sendDetailDTOS)) { + return null; + } + QuerySendDetailsResponseBodySmsSendDetailDTOsSmsSendDetailDTO dto = sendDetailDTOS.get(0); + SendDetailsStatusEnum sendStatusEnum = SendDetailsStatusEnum.getByCode(dto.getSendStatus()); + BizException.error(sendStatusEnum != null, ReturnCodeEnum.SYSTEM_ERROR, + "非法的响应值:" + dto.getSendStatus()); + return sendStatusEnum; + } + + @Override + public SendSmsCommonResponse sendSms(SendSmsCommonRequest request) { + log.info("[发送sms方法调用] -> {}", JSON.toJSONString(request)); + Client client = getClient(); + SendSmsRequest aliyunRequest = new SendSmsRequest(); + aliyunRequest.setPhoneNumbers(request.getPhoneNo()); + aliyunRequest.setOutId(request.getRequestChannelNo()); + aliyunRequest.setSignName(signName); + aliyunRequest.setTemplateCode(request.getTemplateCode()); + aliyunRequest.setTemplateParam(JSON.toJSONString(request.getTemplateMap())); + log.info("[mns <- aliyun]AliyunSmsService.sendSms response is {}", JSON.toJSONString(aliyunRequest)); + SendSmsResponse response; + try { + response = client.sendSms(aliyunRequest); + log.info("[mns <- aliyun]AliyunSmsService.sendSms response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- aliyun]AliyunSmsService.sendSms is fail", e); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "invoke aliyun fail"); + } + + // 添加响应到上下文 + ServiceContextHolder.get().setChannelResponse(response); + + // 检查响应 + SendSmsResponseBody responseBody = checkSendResponse(response); + + // 响应转换 + SendSmsCommonResponse smsResponse = new SendSmsCommonResponse(); + smsResponse.setRequestId(responseBody.getRequestId()); + smsResponse.setMessage(responseBody.getMessage()); + smsResponse.setBizId(responseBody.getBizId()); + smsResponse.setCode(responseBody.getCode()); + return smsResponse; + } + + /** + * 获取客户端 + * + * @return + */ + private Client getClient() { + return aliyunSmsClientFactory.getClient(accessKeyId, accessSecret); + } + + /** + * 检查发送短信结果 + * @param response + * @return + */ + private SendSmsResponseBody checkSendResponse(SendSmsResponse response) { + if (response == null) { + log.info("AliyunSmsService#checkSendResponse response is null"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "aliyun response is null"); + } + SendSmsResponseBody responseBody = response.getBody(); + if (responseBody == null) { + log.info("AliyunSmsService#checkSendResponse response body is null"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "aliyun response body is null"); + } + if (!AliyunConstants.SUCCESS_CODE.equals(responseBody.getCode())) { + String message = responseBody.getMessage(); + log.info("AliyunSmsService#checkResponse is fail, error message : {}", message); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, message); + } + return responseBody; + } + + /** + * 检查查询短信发送详情响应 + * + * @param response + * @return + */ + private List checkResponse( + QuerySendDetailsResponse response) { + if (response == null) { + log.info("AliyunSmsService#checkResponse response is null"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "aliyun response is null"); + } + QuerySendDetailsResponseBody responseBody = response.getBody(); + if (responseBody == null) { + log.info("AliyunSmsService#checkResponse response body is null"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "aliyun response body is null"); + } + if (!AliyunConstants.SUCCESS_CODE.equals(responseBody.getCode())) { + String message = responseBody.getMessage(); + log.info("AliyunSmsService#checkResponse is fail, error message : {}", message); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, message); + } + QuerySendDetailsResponseBodySmsSendDetailDTOs smsSendDetailDTOs = responseBody + .getSmsSendDetailDTOs(); + if (smsSendDetailDTOs == null) { + log.info("AliyunSmsService#checkResponse sms send details is null"); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "sms send details is null"); + } + return smsSendDetailDTOs.getSmsSendDetailDTO(); + } + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/ChuangLanSmsClientImpl.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/ChuangLanSmsClientImpl.java new file mode 100644 index 00000000..66ad0f60 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/ChuangLanSmsClientImpl.java @@ -0,0 +1,85 @@ +package cn.axzo.msg.notices.integration.client.impl; + +import cn.axzo.msg.notices.common.constans.ChuangLanConstants; +import cn.axzo.msg.notices.common.domain.ServiceContextHolder; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.integration.client.ChuangLanSmsClient; +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.dto.response.ChuangLanSmsResponse; +import cn.axzo.msg.notices.integration.support.ChuangLanMessageRequestResolver; +import cn.axzo.msg.notices.integration.support.ChuangLanMessageRequestResolverFactory; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * 创蓝短信客户端实现类 + * + * @author zhaoyong + * @see ChuangLanSmsClientImpl + * @since 2021-08-07 17:02 + */ +@Slf4j +@Component("chuangLanSmsClient") +public class ChuangLanSmsClientImpl implements ChuangLanSmsClient { + + @Resource(name = "chuangLanMessageRequestResolverFactory") + private ChuangLanMessageRequestResolverFactory factory; + + @Resource(name = "restTemplate") + private RestTemplate restTemplate; + + @Override + public ChuangLanSmsResponse sendMessage(MessageRequest request) { + log.info("[manager -> client]ChuangLanSmsClientImpl.sendBatchMessage request param is {}", JSON.toJSONString(request)); + + // 获取请求参数解析器 + ChuangLanMessageRequestResolver requestResolver = factory.getService(request.getMessageTemplateType()); + BizException.error(requestResolver != null, + ReturnCodeEnum.INVALID_PARAMETER, "不支持的模板类型 : " + request.getMessageTemplateType()); + + // 获取发送创蓝短信请求类 + BaseSmsRequest smsRequest = requestResolver.resolve(request); + log.info("[mns -> chuanglan]ChuangLanSmsClientImpl.sendBatchMessage request param is {}", JSON.toJSONString(smsRequest)); + + // 发送短信 + ChuangLanSmsResponse response; + try { + response = restTemplate.postForObject(request.getRequestUrl(), + smsRequest, ChuangLanSmsResponse.class); + } catch (Exception e) { + LogUtil.error("[mns -> chuanglan]ChuangLanSmsClientImpl.sendBatchMessage is fail.", e); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "invoke chuanglang fail"); + } + + // 添加响应对象 + ServiceContextHolder.get().setChannelResponse(response); + + // 检查响应对象 + checkResponse(response); + + log.info("[mns <- chuanglan]ChuangLanSmsClientImpl.sendBatchMessage response is {}", JSON.toJSONString(response)); + + // 返回响应 + return response; + } + + /** + * 检查响应信息 + * @param response + */ + private void checkResponse(ChuangLanSmsResponse response) { + if(response == null) { + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "response is null"); + } + if(!ChuangLanConstants.SUCCESS_CODE.equals(response.getCode())) { + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR.getCode(), response.getErrorMsg(), response); + } + } +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/DingDingClientImpl.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/DingDingClientImpl.java new file mode 100644 index 00000000..93846804 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/client/impl/DingDingClientImpl.java @@ -0,0 +1,178 @@ +package cn.axzo.msg.notices.integration.client.impl; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import cn.axzo.msg.notices.integration.client.DingDingClient; +import cn.axzo.msg.notices.integration.dto.request.At; +import cn.axzo.msg.notices.integration.dto.request.DingMessageRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageText; +import cn.axzo.msg.notices.integration.dto.response.DingMessageResponse; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * 钉钉客户端实现类 + * + * @author zhaoyong + * @see DingDingClientImpl + * @since 2021-07-12 12:00 + */ +@Slf4j +@Service("dingDingClient") +@RefreshScope +public class DingDingClientImpl implements DingDingClient, EnvironmentAware { + + public static final String NOTIFY_VERIFICATION_CODE = "https://oapi.dingtalk.com/robot/send?access_token=ac574ebc7f9f5c197f6a58e122332689a5b5b75a3b7e4413e67b33bba4e95af6"; + + public static final String NOTIFY_BATCH_MESSAGE = "https://oapi.dingtalk.com/robot/send?access_token=65845830bc350344abdcb2c196a0dafe100053a812ff47d65ce1f395f12ec484"; + + public static final String NOTIFY_SINGLE_MESSAGE = "https://oapi.dingtalk.com/robot/send?access_token=9fb3a8a8f1c827ddb07e2e138b21351845e9381b62aa206e0c06333b0e4c95f7"; + + public static final String NOTIFY_MQ_MESSAGE = "https://oapi.dingtalk.com/robot/send?access_token=bff5747081dccd33d57276ffc67a4b2d7caca550081b0d1c8e5f7af9cf473221"; + + public static final String NOTIFY_CHANNEL_CALLBACK = "https://oapi.dingtalk.com/robot/send?access_token=cf51872a50040a2a7ac88397de2c8c9fad6e37059d2525ced3084d2d6781af05"; + + @Resource(name = "restTemplate") + private RestTemplate restTemplate; + + private final static String NOTIFY_MESSAGE_FORMAT = "主题:短信 Mock\n环境: %s \n手机号: %s \n模板名称: %s \n短信内容: %s"; + + private final static String BATCH_MESSAGE_FORMAT = "主题:批量短信发送失败\n环境: %s \n消息模板号: %s \n批次号: %s \n错误信息: %s"; + + private final static String SINGLE_MESSAGE_FORMAT = "主题:单条短信发送失败\n环境: %s \n消息模板号: %s \n请求号: %s \n错误信息: %s"; + + private final static String MQ_MESSAGE_FORMAT = "主题:RocketMQ异常\n环境: %s \n错误信息: %s"; + + private final static String CHANNEL_CALLBACK_FORMAT = "主题:渠道回调异常\n环境: %s \n渠道名称: %s \n回调信息: %s \n错误信息: %s"; + + private Environment environment; + + @Value("${dingDing.at:false}") + private boolean dingDingAt; + + @Override + public void notifyMockMessage(String mobile, String title, String param) { + try { + DingMessageRequest request = new DingMessageRequest(); + request.setMsgtype(CommonConstants.DING_TEXT_MESSAGE_TYPE); + MessageText text = new MessageText(); + String content = String.format(NOTIFY_MESSAGE_FORMAT, getProfile(), mobile, title, param); + text.setContent(content); + request.setText(text); + if(dingDingAt){ + At at = new At(); + at.setAtMobiles(Lists.newArrayList(mobile)); + request.setAt(at); + } + log.info("[mns -> ding] DingDingClientImpl.notify request param is {}", JSON.toJSONString(request)); + DingMessageResponse response = restTemplate.postForObject(NOTIFY_VERIFICATION_CODE, request, DingMessageResponse.class); + log.info("[mns <- ding] DingDingClientImpl.notify response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- ding] DingDingClientImpl.notify response is error", e); + } + } + + @Override + public void notifySingleMessage(String templateNo, String requestNo, String errorMsg) { + try { + DingMessageRequest request = new DingMessageRequest(); + request.setMsgtype(CommonConstants.DING_TEXT_MESSAGE_TYPE); + MessageText text = new MessageText(); + String content = String.format(SINGLE_MESSAGE_FORMAT, getProfile(), templateNo, requestNo, errorMsg); + text.setContent(content); + request.setText(text); + At at = new At(); + at.setAtMobiles(Lists.newArrayList("13585844124", "15928328930", "17605414211")); + request.setAt(at); + log.info("[mns -> ding] DingDingClientImpl.notifySingleMessage request param is {}", JSON.toJSONString(request)); + DingMessageResponse response = restTemplate.postForObject(NOTIFY_SINGLE_MESSAGE, request, DingMessageResponse.class); + log.info("[mns <- ding] DingDingClientImpl.notifySingleMessage response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- ding] DingDingClientImpl.notifySingleMessage response is error", e); + } + } + + @Override + public void notifyBatchMessage(String templateNo, String batchNo, String errorMsg) { + try { + DingMessageRequest request = new DingMessageRequest(); + request.setMsgtype(CommonConstants.DING_TEXT_MESSAGE_TYPE); + MessageText text = new MessageText(); + String content = String.format(BATCH_MESSAGE_FORMAT, getProfile(), templateNo, batchNo, errorMsg); + text.setContent(content); + request.setText(text); + At at = new At(); + at.setAtMobiles(Lists.newArrayList("13585844124", "15928328930", "17605414211")); + request.setAt(at); + log.info("[mns -> ding] DingDingClientImpl.notifyBatchMessage request param is {}", JSON.toJSONString(request)); + DingMessageResponse response = restTemplate.postForObject(NOTIFY_BATCH_MESSAGE, request, DingMessageResponse.class); + log.info("[mns <- ding] DingDingClientImpl.notifyBatchMessage response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- ding] DingDingClientImpl.notifyBatchMessage response is error", e); + } + } + + @Override + public void notifyChannelCallback(String channelName, String callbackData, String errorMsg) { + try { + DingMessageRequest request = new DingMessageRequest(); + request.setMsgtype(CommonConstants.DING_TEXT_MESSAGE_TYPE); + MessageText text = new MessageText(); + String content = String.format(CHANNEL_CALLBACK_FORMAT, getProfile(), channelName, callbackData, errorMsg); + text.setContent(content); + request.setText(text); + At at = new At(); + at.setAtMobiles(Lists.newArrayList("13585844124", "15928328930", "17605414211")); + request.setAt(at); + log.info("[mns -> ding] DingDingClientImpl.notifyChannelCallback request param is {}", JSON.toJSONString(request)); + DingMessageResponse response = restTemplate.postForObject(NOTIFY_CHANNEL_CALLBACK, request, DingMessageResponse.class); + log.info("[mns <- ding] DingDingClientImpl.notifyChannelCallback response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- ding] DingDingClientImpl.notifyChannelCallback response is error", e); + } + } + + @Override + public void notifyRocketMqError(String errorMsg) { + try { + DingMessageRequest request = new DingMessageRequest(); + request.setMsgtype(CommonConstants.DING_TEXT_MESSAGE_TYPE); + MessageText text = new MessageText(); + String content = String.format(MQ_MESSAGE_FORMAT, getProfile(), errorMsg); + text.setContent(content); + request.setText(text); + At at = new At(); + at.setAtMobiles(Lists.newArrayList("13585844124", "15928328930", "17605414211")); + request.setAt(at); + log.info("[mns -> ding] DingDingClientImpl.notifyRocketMqError request param is {}", JSON.toJSONString(request)); + DingMessageResponse response = restTemplate.postForObject(NOTIFY_MQ_MESSAGE, request, DingMessageResponse.class); + log.info("[mns <- ding] DingDingClientImpl.notifyRocketMqError response is {}", JSON.toJSONString(response)); + } catch (Exception e) { + LogUtil.error("[mns <- ding] DingDingClientImpl.notifyRocketMqError response is error", e); + } + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + private String getProfile() { + String[] activeProfiles = environment.getActiveProfiles(); + if(ArrayUtils.isEmpty(activeProfiles)) { + return CommonConstants.DEFAULT_ENV; + } + return activeProfiles[0]; + } + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/At.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/At.java new file mode 100644 index 00000000..ad600393 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/At.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +import java.util.List; + +/** + * 钉钉群 @ 通知人 + * + * @author zhaoyong + * @see At + * @since 2021-07-12 11:31 + */ +@Data +public class At { + + private List atMobiles; + + private boolean isAtAll; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/BaseSmsRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/BaseSmsRequest.java new file mode 100644 index 00000000..10f77a8b --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/BaseSmsRequest.java @@ -0,0 +1,58 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +/** + * 创蓝短信基础请求类 + * + * @author zhaoyong + * @see BaseSmsRequest + * @since 2021-08-07 17:16 + */ +@Data +public class BaseSmsRequest { + + /** + * 必传 + * + * API账号,管理后台获取 + */ + private String account; + /** + * 必传 + * + * API密码,管理后台获取(8-16位) + */ + private String password; + /** + * 必传 + * + * 审核通过的签名以及模板,长度不超过536个字符 + */ + private String msg; + /** + * 非必传 + * + * 定时发送短信时间,格式为yyyyMMddHHmm,值小于或等于当前时间则立即发送,默认立即发送;且定时时间在7天以内 + */ + private String sendtime; + /** + * 非必传 + * + * 是否需要状态报告,默认false;如需状态报告则传”true” + */ + private String report; + /** + * 非必传 + * + * 下发短信号码扩展码,纯数字,需保证手机端口号加自定义扩展码总位数不超过20位,建议1-3位,如需上行短信推送或拉取则必填 + */ + private String extend; + /** + * 非必传 + * + * 该条短信在您业务系统内的ID,一般可以设置订单号或者短信发送记录流水号,用于区分短信业务,总位数不超过40位 + */ + private String uid; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/DingMessageRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/DingMessageRequest.java new file mode 100644 index 00000000..361f399a --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/DingMessageRequest.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +/** + * 钉钉消息请求类 + * + * @author zhaoyong + * @see DingMessageRequest + * @since 2021-07-12 13:16 + */ +@Data +public class DingMessageRequest { + + private String msgtype; + + private MessageText text; + + private At at; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageRequest.java new file mode 100644 index 00000000..6c973fa4 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageRequest.java @@ -0,0 +1,48 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import lombok.Data; + +/** + * 批量消息请求类 + * + * @author zhaoyong + * @see MessageRequest + * @since 2021-08-07 17:28 + */ +@Data +public class MessageRequest { + + /** + * 模板消息类型 + */ + private MessageTemplateTypeEnum messageTemplateType; + + /** + * 渠道请求号 + */ + private String requestChannelNo; + + /** + * 短信请求地址 + */ + private String requestUrl; + + /** + * 模板内容 + */ + private String templateContent; + + /** + * 模板内容是否有参数 + */ + private boolean hasParam; + + /** + * 消息内容 + */ + private String smsContent; + + + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageText.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageText.java new file mode 100644 index 00000000..3df9530c --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/MessageText.java @@ -0,0 +1,10 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +@Data +public class MessageText { + + private String content; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SendSmsCommonRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SendSmsCommonRequest.java new file mode 100644 index 00000000..cafebe14 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SendSmsCommonRequest.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * @Author: LiuYang + * @Date: 2021/5/21 11:38 + */ +@NoArgsConstructor +@Data +public class SendSmsCommonRequest { + + /** + * 发送的手机号集合 + */ + private String phoneNo; + + /** + * 模板编号 + */ + private String templateCode; + + /** + * 模板参数 + */ + private Map templateMap; + + /** 渠道请求号 */ + private String requestChannelNo; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsCommonRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsCommonRequest.java new file mode 100644 index 00000000..fb272db7 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsCommonRequest.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +/** + * 相同内容群发接口请求类 + * + * @author zhaoyong + * @see SmsCommonRequest + * @since 2021-08-03 18:54 + */ +@Data +public class SmsCommonRequest extends BaseSmsRequest { + + /** + * 必传 + * + * 接收的手机号,多个手机号使用英文逗号间隔,一次不要超过1000个; + */ + private String phone; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsVariableRequest.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsVariableRequest.java new file mode 100644 index 00000000..c3e749dd --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/request/SmsVariableRequest.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.integration.dto.request; + +import lombok.Data; + +/** + * 相同内容变量接口请求类 + * + * @author zhaoyong + * @see SmsVariableRequest + * @since 2021-08-03 18:54 + */ +@Data +public class SmsVariableRequest extends BaseSmsRequest { + + /** + * 必传 + * + * 手机号码和变量参数,多组参数使用英文分号区分;此字段上限支持 1000个参数组。格式不符的参数,系统自动会过滤掉 + */ + private String params; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/ChuangLanSmsResponse.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/ChuangLanSmsResponse.java new file mode 100644 index 00000000..5c5572f0 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/ChuangLanSmsResponse.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.integration.dto.response; + +import lombok.Data; + +/** + * 创蓝短信响应 + * + * @author zhaoyong + * @see ChuangLanSmsResponse + * @since 2021-08-07 18:26 + */ +@Data +public class ChuangLanSmsResponse { + + /** + * 提交响应状态码,返回“0”表示提交成功(详细参考提交响应状态码) + */ + private String code; + /** + * 状态码说明(提交成功返回空) + */ + private String errorMsg; + /** + * 消息id + */ + private String msgId; + /** + * 响应时间 + */ + private String time; + /** + * 失败条数 + */ + private int successNum; + /** + * 成功条数 + */ + private int failNum; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/DingMessageResponse.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/DingMessageResponse.java new file mode 100644 index 00000000..0045e6bd --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/DingMessageResponse.java @@ -0,0 +1,18 @@ +package cn.axzo.msg.notices.integration.dto.response; + +import lombok.Data; + +/** + * 钉钉请求响应类 + * + * @author zhaoyong + * @see DingMessageResponse + * @since 2021-07-12 11:02 + */ +@Data +public class DingMessageResponse { + + private int errcode; + private String errmsg; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/SendSmsCommonResponse.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/SendSmsCommonResponse.java new file mode 100644 index 00000000..3d873103 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/dto/response/SendSmsCommonResponse.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.integration.dto.response; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Author: LiuYang + * @Date: 2021/5/21 11:38 + */ +@NoArgsConstructor +@Data +public class SendSmsCommonResponse { + + /** + * 请求ID + */ + private String requestId; + + /** + * 响应消息 + */ + private String message; + + /** + * 回执ID + */ + private String bizId; + + /** + * 响应码 + */ + private String code; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/AbstractChuangLanMessageRequestResolver.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/AbstractChuangLanMessageRequestResolver.java new file mode 100644 index 00000000..45cb3950 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/AbstractChuangLanMessageRequestResolver.java @@ -0,0 +1,31 @@ +package cn.axzo.msg.notices.integration.support; + +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.dto.request.SmsCommonRequest; +import cn.axzo.msg.notices.integration.dto.request.SmsVariableRequest; + +/** + * 创蓝短信请求解析抽象类 + * + * @author zhaoyong + * @see AbstractChuangLanMessageRequestResolver + * @since 2021-08-07 18:07 + */ +public abstract class AbstractChuangLanMessageRequestResolver implements ChuangLanMessageRequestResolver { + + public BaseSmsRequest getBaseSmsRequest(MessageRequest request){ + if(request.isHasParam()) { + SmsVariableRequest result = new SmsVariableRequest(); + result.setUid(request.getRequestChannelNo()); + result.setParams(request.getSmsContent()); + return result; + } else { + SmsCommonRequest result = new SmsCommonRequest(); + result.setUid(request.getRequestChannelNo()); + result.setPhone(request.getSmsContent()); + return result; + } + } + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanAccountProperties.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanAccountProperties.java new file mode 100644 index 00000000..b7b5d67c --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanAccountProperties.java @@ -0,0 +1,38 @@ +package cn.axzo.msg.notices.integration.support; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 创蓝不同账户信息配置类 + * + * @author zhaoyong + * @see ChuangLanAccountProperties + * @since 2021-08-26 11:24 + */ +@Data +@Configuration +@RefreshScope +public class ChuangLanAccountProperties { + + @Value("${chuanlan.member.account}") + private String memberAccount; + + @Value("${chuanlan.member.password}") + private String memberPassword; + + @Value("${chuanlan.notice.account}") + private String noticeAccount; + + @Value("${chuanlan.notice.password}") + private String noticePassword; + + @Value("${chuanlan.verification.account}") + private String verificationAccount; + + @Value("${chuanlan.verification.password}") + private String verificationPassword; + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolver.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolver.java new file mode 100644 index 00000000..d6688f85 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolver.java @@ -0,0 +1,24 @@ +package cn.axzo.msg.notices.integration.support; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.azxo.framework.common.spring.SimpleRegisterableService; + +/** + * 创蓝消息请求解析器 + * + * @author zhaoyong + * @see ChuangLanMessageRequestResolver + * @since 2021-08-07 17:26 + */ +public interface ChuangLanMessageRequestResolver extends SimpleRegisterableService { + + /** + * 发送消息请求解析器 + * @param request + * @return + */ + BaseSmsRequest resolve(MessageRequest request); + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolverFactory.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolverFactory.java new file mode 100644 index 00000000..08daa2cd --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/ChuangLanMessageRequestResolverFactory.java @@ -0,0 +1,28 @@ +package cn.axzo.msg.notices.integration.support; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import cn.azxo.framework.common.spring.AbstractSimpleRegisterableServiceFactory; +import org.springframework.stereotype.Component; + +/** + * 创蓝消息请求解析器工厂类 + * + * @author zhaoyong + * @see ChuangLanMessageRequestResolverFactory + * @since 2021-08-07 18:17 + */ +@Component("chuangLanMessageRequestResolverFactory") +public class ChuangLanMessageRequestResolverFactory extends + AbstractSimpleRegisterableServiceFactory { + + @Override + protected String getFactoryName() { + return "创蓝消息请求解析器工厂类"; + } + + @Override + protected Class getServiceClazz() { + return ChuangLanMessageRequestResolver.class; + } + +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanMemberMessageRequestResolver.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanMemberMessageRequestResolver.java new file mode 100644 index 00000000..c2406744 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanMemberMessageRequestResolver.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.integration.support.impl; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.support.AbstractChuangLanMessageRequestResolver; +import cn.axzo.msg.notices.integration.support.ChuangLanAccountProperties; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 创蓝会员营销短信请求类 + * + * @author zhaoyong + * @see ChuangLanMemberMessageRequestResolver + * @since 2021-08-07 17:53 + */ +@Component +public class ChuangLanMemberMessageRequestResolver extends AbstractChuangLanMessageRequestResolver { + + @Resource(name = "chuangLanAccountProperties") + private ChuangLanAccountProperties chuangLanAccountProperties; + + @Override + public BaseSmsRequest resolve(MessageRequest request) { + BaseSmsRequest result = getBaseSmsRequest(request); + result.setAccount(chuangLanAccountProperties.getMemberAccount()); + result.setPassword(chuangLanAccountProperties.getMemberPassword()); + result.setReport("true"); + result.setMsg(request.getTemplateContent()); + return result; + } + + @Override + public MessageTemplateTypeEnum getRouteKey() { + return MessageTemplateTypeEnum.PROMOTIONAL; + } +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanNoticeMessageRequestResolver.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanNoticeMessageRequestResolver.java new file mode 100644 index 00000000..48fb855d --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanNoticeMessageRequestResolver.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.integration.support.impl; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.support.AbstractChuangLanMessageRequestResolver; +import cn.axzo.msg.notices.integration.support.ChuangLanAccountProperties; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 创蓝通知短信请求类 + * + * @author zhaoyong + * @see ChuangLanNoticeMessageRequestResolver + * @since 2021-08-07 17:53 + */ +@Component +public class ChuangLanNoticeMessageRequestResolver extends AbstractChuangLanMessageRequestResolver { + + @Resource(name = "chuangLanAccountProperties") + private ChuangLanAccountProperties chuangLanAccountProperties; + + @Override + public BaseSmsRequest resolve(MessageRequest request) { + BaseSmsRequest result = getBaseSmsRequest(request); + result.setAccount(chuangLanAccountProperties.getNoticeAccount()); + result.setPassword(chuangLanAccountProperties.getNoticePassword()); + result.setReport("true"); + result.setMsg(request.getTemplateContent()); + return result; + } + + @Override + public MessageTemplateTypeEnum getRouteKey() { + return MessageTemplateTypeEnum.SHORT_NOTE; + } +} diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanVerificationCodeMessageRequestResolver.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanVerificationCodeMessageRequestResolver.java new file mode 100644 index 00000000..8d413e01 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/notices/integration/support/impl/ChuangLanVerificationCodeMessageRequestResolver.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.integration.support.impl; + +import cn.axzo.msg.notices.common.enums.MessageTemplateTypeEnum; +import cn.axzo.msg.notices.integration.dto.request.BaseSmsRequest; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.support.AbstractChuangLanMessageRequestResolver; +import cn.axzo.msg.notices.integration.support.ChuangLanAccountProperties; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 创蓝验证码短信请求类 + * + * @author zhaoyong + * @see ChuangLanVerificationCodeMessageRequestResolver + * @since 2021-08-07 17:53 + */ +@Component +public class ChuangLanVerificationCodeMessageRequestResolver extends AbstractChuangLanMessageRequestResolver { + + @Resource(name = "chuangLanAccountProperties") + private ChuangLanAccountProperties chuangLanAccountProperties; + + @Override + public BaseSmsRequest resolve(MessageRequest request) { + BaseSmsRequest result = getBaseSmsRequest(request); + result.setAccount(chuangLanAccountProperties.getVerificationAccount()); + result.setPassword(chuangLanAccountProperties.getVerificationPassword()); + result.setReport("true"); + result.setMsg(request.getTemplateContent()); + return result; + } + + @Override + public MessageTemplateTypeEnum getRouteKey() { + return MessageTemplateTypeEnum.VERIFICATION_CODE; + } +} diff --git a/msg-notices/msg-notices-manager-api/pom.xml b/msg-notices/msg-notices-manager-api/pom.xml new file mode 100644 index 00000000..987d77e2 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/pom.xml @@ -0,0 +1,44 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + + + 8 + 8 + UTF-8 + + + + + cn.axzo.msg.notices.common + msg-notices-common + + + cn.axzo.msg.notices.dao + msg-notices-dao + + + cn.axzo.msg.notices.dao + msg-notices-dao + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.common + msg-notices-common + 1.0.0-SNAPSHOT + compile + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageManger.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageManger.java new file mode 100644 index 00000000..4d5c1168 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageManger.java @@ -0,0 +1,39 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageRequestDto; + +/** + * @Auther: szg + * @Date: 2021/8/9 17:16 + * @Description: + */ +public interface BatchMessageManger { + + /** + * 根据条件分页查询发送批次 + * @param dto + * @return + */ + Page queryByPage(BatchMessageRequestDto dto); + + /** + * 查询批量消息 + * @param batchNo + * @return + */ + BatchMessage queryBatchMessage(String batchNo); + + /** + * 发送批次拆分消息 + * @param batchMessage + */ + boolean batchMessageSplitToMessage(BatchMessage batchMessage); + + /** + * 按照批次发送消息、更新状态和回执单号 + * @param batchMessage + */ + void sendBatchMessageAndHandleReceipt(BatchMessage batchMessage); +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageRequestManger.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageRequestManger.java new file mode 100644 index 00000000..b10d31bd --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/BatchMessageRequestManger.java @@ -0,0 +1,59 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageRequestDto; + +import java.util.List; + +/** + * @Auther: szg + * @Date: 2021/8/9 14:07 + * @Description: + */ +public interface BatchMessageRequestManger { + + /** + * 保存批量请求对象 + * @param batchMessageRequest + * @return + */ + boolean saveBatchMessageRequest(BatchMessageRequest batchMessageRequest); + + /** + * 分页查询 + * @param dto + * @return + */ + Page queryPageByBatchMessageQueryRequestDto(BatchMessageRequestDto dto); + + /** + * 批量短信拆分批次和生成批次 + * @param requestDto + */ + List batchMessageRequestSplitAndSave(BatchMessageRequest requestDto); + + /** + * 查询批量短信请求 + * @param appCode + * @param requestNo + * @return + */ + BatchMessageRequest queryBatchMessage(String appCode, String requestNo); + + /** + * 修改统计信息 + * @param batchMessageRequest + */ + void handleBatchMessageRequestStatistics(BatchMessageRequest batchMessageRequest); + + /** + * 修改短信批量请求为成功 + * + * @param remark + * @param id + * @return + */ + boolean updateRequestSuccess(String remark, Long id); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageChannelRouter.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageChannelRouter.java new file mode 100644 index 00000000..cef9067a --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageChannelRouter.java @@ -0,0 +1,21 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.dao.entity.MessageChannel; + +/** + * 消息渠道路由 + * + * @author zhaoyong_sh + * @see MessageChannelRouter + * @since 2021-05-27 15:03 + */ +public interface MessageChannelRouter { + + /** + * 消息渠道路由 + * @param condition + * @return + */ + MessageChannel route(String condition); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageManager.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageManager.java new file mode 100644 index 00000000..48571589 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageManager.java @@ -0,0 +1,113 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.manager.api.dto.request.MessageQueryRequestDto; + +/** + * 消息记录管理类 + * + * @author zhaoyong_sh + * @see MessageManager + * @since 2021-05-19 15:54 + */ +public interface MessageManager { + + /** + * 分页查询消息记录 + * + * @param requestDto + * @return + */ + Page queryPageByMessageQueryRequestDto(MessageQueryRequestDto requestDto); + + /** + * 保存消息 + * + * @param message + * @return + */ + boolean saveMessage(Message message); + + /** + * 保存重试消息 + * + * @param messageRedo + * @return + */ + boolean saveMessageRedo(MessageRedo messageRedo); + + /** + * 更新为处理中 + * + * @param bizId + * @param requestId + * @param id + * @return + */ + boolean updateToProcessing(String bizId, String requestId, Long id); + + /** + * 渠道业务异常 + * + * @param id + * @return + */ + boolean updateToFail(Long id); + + /** + * 网络异常 + * + * @param id + * @param messageRedo + * @return + */ + boolean updateToException(MessageRedo messageRedo, Long id); + + /** + * 修改定时任务异常到查询状态 + * + * @param targetStatus + * @param id + * @return + */ + boolean updateExceptionToQueryStatus(String targetStatus, Long id); + + /** + * 根据messageOrderNo和phoneNumber查询message + * + * @param messageOrderNo + * @param phoneNumber + * @return + */ + Message queryMessageByMessageOrderNoAndPhoneNumber(String messageOrderNo,String channelBizId, String phoneNumber); + + /** + * 根据id更新状态 + * + * @param id + * @param status + * @return + */ + boolean updateProcessingMessageStatusById(Long id, String status); + + /** + * 根据messageOrderNo更新状态 + * + * @param messageOrderNo + * @param status + * @return + */ + boolean updateMessageStatusByMessageOrderNo(String messageOrderNo, String status); + + /** + * 更新为成功 + * @param bizId + * @param requestId + * @param id + * @return + */ + boolean updateToSuccess(String bizId, String requestId, Long id); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRedoManger.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRedoManger.java new file mode 100644 index 00000000..0558bc23 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRedoManger.java @@ -0,0 +1,59 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.common.domain.MessageContext; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.manager.api.dto.request.MessageRedoQueryRequestDto; + +import java.util.Date; + +/** + * 消息重试 + */ +public interface MessageRedoManger { + + /** + * 查询重试消息 + * @param requestDto + * @return + */ + Page queryPageByMessageRedoQueryRequestDto(MessageRedoQueryRequestDto requestDto); + + /** + * 根据重试单号和手机号查询重试消息信息 + * @param redoOrderNo + * @param phoneNumber + * @return + */ + MessageRedo queryMessageRedoByRedoOrderNoAndPhoneNumber(String redoOrderNo, String bizId, String phoneNumber); + + /** + * 根据id更新重试状态 + * @param id + * @param oldStatus + * @param newStatus + * @return + */ + boolean updateMessageRedoStatusById(Long id, String oldStatus, String newStatus); + + /** + * 通过message来新增 + * @param message + */ + void saveByMessage(Message message); + + boolean lockMessage(MessageContext context, Long id); + + boolean updateRetry(Date retryAt, Long id); + + boolean updateExceptionToFail(Long id, String messageOrderNo); + + /** + * 更新重试渠道回执id + * @param id + * @param bizId + * @return + */ + boolean updateMessageRedoChannelById(Long id, String bizId,String redoMessageNo); +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRequestLogManager.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRequestLogManager.java new file mode 100644 index 00000000..a2a5c1bc --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageRequestLogManager.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; + +/** + * 请求日志处理类 + * + * @author zhaoyong_sh + * @see MessageRequestLogManager + * @since 2021-05-28 10:50 + */ +public interface MessageRequestLogManager { + + /** + * 保存请求日志 + * @param requestLog + * @return + */ + Long saveRequestLog(MessageRequestLog requestLog); + + /** + * 修改请求日志 + * @param responseBody + * @param id + * @return + */ + boolean updateRequestLog(String responseBody, Long id); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateManager.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateManager.java new file mode 100644 index 00000000..c120b794 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateManager.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; + +import java.util.List; + +/** + * 消息模板处理类 + * + * @author zhaoyong_sh + * @see MessageTemplateManager + * @since 2021-05-27 20:23 + */ +public interface MessageTemplateManager { + + /** + * 验证内部模板 + * @param innerTemplateNo + * @return + */ + MessageTemplate queryAndCheckInnerTemplate(String innerTemplateNo); + + /** + * 获取渠道模板 + * @param innerTemplateNo + * @param channelCode + * @return + */ + ChannelMessageTemplate queryChannelTemplate(String innerTemplateNo, String channelCode); + + /** + * 查询模板变量 + * @param innerTemplateNo + * @return + */ + List queryTemplateParam(String innerTemplateNo); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateParamManager.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateParamManager.java new file mode 100644 index 00000000..fc5eec88 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/MessageTemplateParamManager.java @@ -0,0 +1,23 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; + +import java.util.List; + +/** + * 消息模板参数 + * + * @author zhaoyong + * @see MessageTemplateParamManager + * @since 2021-08-20 21:34 + */ +public interface MessageTemplateParamManager { + + /** + * 根据模板号查询 + * @param templateCode + * @return + */ + List getByCode(String templateCode); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/RetryStrategy.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/RetryStrategy.java new file mode 100644 index 00000000..2dba2ee5 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/RetryStrategy.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.common.domain.MessageContext; + +import java.util.List; + +/** + * 重试策略 + * + * @author zhaoyong_sh + * @see RetryStrategy + * @since 2021-05-19 10:39 + */ +public interface RetryStrategy { + + /** + * 获取通知时间列表 + * @return + */ + List getRetryStrategy(); + + /** + * 获取下一次通知秒数 + * @param context + * @return + */ + Integer getNextNotifySecond(MessageContext context); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/SmsSendManager.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/SmsSendManager.java new file mode 100644 index 00000000..09098d14 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/SmsSendManager.java @@ -0,0 +1,33 @@ +package cn.axzo.msg.notices.manager.api; + +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.BatchMessageSendResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; + +/** + * sms 管理者 + * @Author: LiuYang + * @Date: 2021/5/21 15:39 + */ +public interface SmsSendManager { + + /** + * 发送短信 + * + * @param requestDto + * @return + * @throws Exception + */ + SendSmsCommonResponseDto sendMessage(MessageSendRequestDto requestDto); + + /** + * 发送批量短信 + * + * TODO 多个渠道请求对象响应对象需求统一 + * @param requestDto + * @return + */ + BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto); + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/AliMessageCallbackRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/AliMessageCallbackRequestDto.java new file mode 100644 index 00000000..74c99c94 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/AliMessageCallbackRequestDto.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 阿里云短信回调对象 + */ + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AliMessageCallbackRequestDto { + + private String phone_number; + + private String send_time; + + private String report_time; + + private Boolean success; + + private String err_code; + + private String err_msg; + + private String sms_size; + + private String biz_id; + + private String out_id; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BaseRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BaseRequestDto.java new file mode 100644 index 00000000..88458e49 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BaseRequestDto.java @@ -0,0 +1,19 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.Data; + +/** + * 基础请求对象 + * + * @author zhaoyong_sh + * @see BaseRequestDto + * @since 2021-05-28 11:01 + */ +@Data +public class BaseRequestDto { + + private String appCode; + + private String requestNo; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageRequestDto.java new file mode 100644 index 00000000..751e728f --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageRequestDto.java @@ -0,0 +1,41 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import cn.axzo.msg.notices.common.lang.PageRequest; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询请求 + * + * @author zhaoyong_sh + * @see BatchMessageRequestDto + * @since 2021-05-19 18:02 + */ +@Data +public class BatchMessageRequestDto extends PageRequest { + + private Long id; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + + /** + * 发送类型 + */ + private Integer sendType; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageSendRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageSendRequestDto.java new file mode 100644 index 00000000..135113e4 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/BatchMessageSendRequestDto.java @@ -0,0 +1,47 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import cn.axzo.msg.notices.common.utils.KeyUtils; +import lombok.Data; + +import java.util.List; + +/** + * 批量短信请求 + * + * @author zhaoyong + * @see BatchMessageSendRequestDto + * @since 2021-08-07 18:56 + */ +@Data +public class BatchMessageSendRequestDto { + + /** + * 应用码 + */ + private String appCode; + /** + * 应用请求号 + */ + private String appRequestNo; + /** + * 批次号 + */ + private String batchNo; + /** + * 渠道请求号 + */ + private String requestChannelNo; + /** + * 内部模板号 + */ + private String innerTemplateNo; + /** + * 消息内容 + */ + private List smsContentDtos; + + public String getMessageKey(){ + return KeyUtils.getKey(appCode, appRequestNo); + } + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/ChuangLanSmsReportRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/ChuangLanSmsReportRequestDto.java new file mode 100644 index 00000000..4ef7e52c --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/ChuangLanSmsReportRequestDto.java @@ -0,0 +1,46 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.Data; + +/** + * + * @author szg + * @Description:状态报告响应实体类 + */ +@Data +public class ChuangLanSmsReportRequestDto { + + /** + * 消息ID + */ + private String msgid; + /** + * 状态更新时间 + */ + private String reportTime; + /** + * 接收短信的手机号码 + */ + private String mobile; + /** + * 状态(详细参考状态报告状态码) + */ + private String status; + /** + * 253平台收到运营商回复状态报告的时间,格式yyMMddHHmmss + */ + private String notifyTime; + /** + * 状态说明 + */ + private String statusDesc; + /** + * 该条短信在您业务系统内的ID,如订单号或者短信发送记录流水号 + */ + private String uid; + /** + * 下发短信计费条数 + */ + private String length; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageQueryRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageQueryRequestDto.java new file mode 100644 index 00000000..e7e065ef --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageQueryRequestDto.java @@ -0,0 +1,44 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import cn.axzo.msg.notices.common.lang.PageRequest; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询请求 + * + * @author zhaoyong_sh + * @see MessageQueryRequestDto + * @since 2021-05-19 18:02 + */ +@Data +public class MessageQueryRequestDto extends PageRequest { + + /** + * 主键 + */ + private Long id; + + /** + * 渠道码 + */ + private String channelCode; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageRedoQueryRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageRedoQueryRequestDto.java new file mode 100644 index 00000000..d9d7585a --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageRedoQueryRequestDto.java @@ -0,0 +1,38 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import cn.axzo.msg.notices.common.lang.PageRequest; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 消息查询请求 + * + * @author zhaoyong_sh + * @see MessageRedoQueryRequestDto + * @since 2021-05-19 18:02 + */ +@Data +public class MessageRedoQueryRequestDto extends PageRequest { + + private Long id; + + private String channelCode; + + /** + * 状态 + */ + private List statuses; + + /** + * 创建开始时间 + */ + private Date startCreateTime; + + /** + * 创建结束时间 + */ + private Date endCreateTime; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageSendRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageSendRequestDto.java new file mode 100644 index 00000000..95e353f3 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/MessageSendRequestDto.java @@ -0,0 +1,50 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.Data; + +import java.util.Map; + +/** + * 发送短信请求类 + * + * @author zhaoyong_sh + * @see MessageSendRequestDto + * @since 2021-05-27 17:30 + */ +@Data +public class MessageSendRequestDto { + + /** + * app_code + */ + private String appCode; + /** + * 渠道码 + */ + private String channelCode; + /** + * 手机号 + */ + private String phoneNo; + /** + * 内部模板号 + */ + private String innerTemplateNo; + /** + * 渠道模板号 + */ + private String templateNo; + /** + * 模板变量内容 + */ + private Map templateMap; + /** + * app请求号 + */ + private String appRequestNo; + /** + * 渠道请求编号 + */ + private String requestChannelNo; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendBatchMessageRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendBatchMessageRequestDto.java new file mode 100644 index 00000000..4b742007 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendBatchMessageRequestDto.java @@ -0,0 +1,49 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 发送消息请求 + * @Author: LiuYang + * @Date: 2021/5/20 18:12 + */ +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class SendBatchMessageRequestDto { + + /** + * 请求号 + */ + private String requestNo; + + /** + * 应用接入码 + */ + private String appCode; + + /** + * 消息模板号 + */ + private String templateNo; + + /** + * 发送类型 + * + * 1:实时;2:非实时 + * + */ + private Integer sendType; + + /** + * 消息内容 + */ + private List smsContentDtos; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendMessageRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendMessageRequestDto.java new file mode 100644 index 00000000..6478c5d7 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SendMessageRequestDto.java @@ -0,0 +1,51 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * 发送消息请求 + * @Author: LiuYang + * @Date: 2021/5/20 18:12 + */ +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Data +public class SendMessageRequestDto { + + /** + * 请求号 + */ + private String requestNo; + + /** + * 接入码 + */ + private String appCode; + + /** + * 短信模板号 + */ + private String templateNo; + + /** + * 电话号码 + */ + private String phoneNo; + + /** + * 参数 + */ + private Map params; + + /** + * 扩展参数 + */ + private String expansion; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SmsContentDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SmsContentDto.java new file mode 100644 index 00000000..4f264bc2 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/SmsContentDto.java @@ -0,0 +1,26 @@ +package cn.axzo.msg.notices.manager.api.dto.request; + +import lombok.Data; + +/** + * 消息内容 + * + * @author zhaoyong + * @see SmsContentDto + * @since 2021-08-07 16:34 + */ +@Data +public class SmsContentDto { + + /** + * 手机号 + */ + private String phoneNo; + + /** + * 模板参数 + * 使用无变量模板时,可不带templateParams参数 + */ + private String templateParams; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java new file mode 100644 index 00000000..4cef618f --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java @@ -0,0 +1,45 @@ +package cn.axzo.msg.notices.manager.api.dto.request.plat; + +import lombok.Data; + +/** + * 创建模板参数 + */ +@Data +public class CreateTemplateRequestDto { + + /** + * 服务名称 + */ + private String serviceName; + + /** + * 模板类型(1:验证码;2:短信通知;3:推广短信;4:群发助手) + */ + private Integer messageTemplateType; + + /** + * 短信模板编码 + */ + private String templateNo; + + /** + * 阿里短信模板编码 + */ + private String templateAliNo; + + /** + * 标题 + */ + private String title; + + /** + * 模板内容 + */ + private String templateContent; + + /** + * 模板原因 + */ + private String remark; +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/QueryTemplateRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/QueryTemplateRequestDto.java new file mode 100644 index 00000000..f516cc90 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/request/plat/QueryTemplateRequestDto.java @@ -0,0 +1,33 @@ +package cn.axzo.msg.notices.manager.api.dto.request.plat; + +import cn.axzo.msg.notices.dao.domain.PageQuery; +import lombok.Data; + +/** + * 查询模板参数 + */ +@Data +public class QueryTemplateRequestDto extends PageQuery { + + /** + * 模版类型 + */ + private Integer messageTemplateType; + /** + * 服务名 + */ + private String serviceName; + /** + * ali模版编码 + */ + private String templateAliNo; + /** + * axzo模版编码 + */ + private String templateNo; + /** + * 标题 + */ + private String title; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/AliCallbackResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/AliCallbackResponseDto.java new file mode 100644 index 00000000..ebbbedd1 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/AliCallbackResponseDto.java @@ -0,0 +1,22 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AliCallbackResponseDto { + + private Integer code; + + private String msg; + + public static AliCallbackResponseDto success(){ + return new AliCallbackResponseDto(0, "success"); + } + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/BatchMessageSendResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/BatchMessageSendResponseDto.java new file mode 100644 index 00000000..0f1eee49 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/BatchMessageSendResponseDto.java @@ -0,0 +1,40 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +import lombok.Data; + +/** + * 批量发送短信响应类 + * + * @author zhaoyong + * @see BatchMessageSendResponseDto + * @since 2021-08-07 18:57 + */ +@Data +public class BatchMessageSendResponseDto { + + /** + * 提交响应状态码,返回“0”表示提交成功(详细参考提交响应状态码) + */ + private String code; + /** + * 状态码说明(提交成功返回空) + */ + private String errorMsg; + /** + * 消息id + */ + private String msgId; + /** + * 响应时间 + */ + private String time; + /** + * 失败条数 + */ + private int successNum; + /** + * 成功条数 + */ + private int failNum; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/ChuangLanCallbackResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/ChuangLanCallbackResponseDto.java new file mode 100644 index 00000000..a6682434 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/ChuangLanCallbackResponseDto.java @@ -0,0 +1,25 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +import cn.axzo.msg.notices.common.enums.ChuangLanStatusEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ChuangLanCallbackResponseDto { + + private String clcode; + + public static ChuangLanCallbackResponseDto success(){ + return new ChuangLanCallbackResponseDto(ChuangLanStatusEnum.SUCCESS.getCode()); + } + + public static ChuangLanCallbackResponseDto fail(){ + return new ChuangLanCallbackResponseDto(ChuangLanStatusEnum.FAIL.getCode()); + } + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendMessageResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendMessageResponseDto.java new file mode 100644 index 00000000..a1810ef5 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendMessageResponseDto.java @@ -0,0 +1,10 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +/** + * 发送消息响应 + * @Author: LiuYang + * @Date: 2021/5/20 18:13 + */ +public class SendMessageResponseDto { + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendSmsCommonResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendSmsCommonResponseDto.java new file mode 100644 index 00000000..e82f6f41 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/SendSmsCommonResponseDto.java @@ -0,0 +1,35 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +import cn.axzo.msg.notices.common.enums.MessageCommonStatusEnum; +import lombok.Data; + +/** + * 消息发送通用结果 + * @Author: LiuYang + * @Date: 2021/5/25 15:59 + */ +@Data +public class SendSmsCommonResponseDto { + + /** + * 响应码 + */ + private MessageCommonStatusEnum status; + + /** + * 响应消息 + */ + private String message; + + /** + * 回执ID + */ + private String bizId; + + /** + * 请求ID + */ + private String requestId; + + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/TemplateParamDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/TemplateParamDto.java new file mode 100644 index 00000000..38aeca44 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/TemplateParamDto.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.notices.manager.api.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 模板参数 + * + * @author zhaoyong + * @see TemplateParamDto + * @since 2021-08-20 21:41 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TemplateParamDto { + + /** + * 模板编号 + */ + private String templateNo; + + /** + * 参数名称 + */ + private String paramName; + + /** + * 参数顺序 + */ + private Integer paramOrder; + +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/plat/QueryTemplateResponseDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/plat/QueryTemplateResponseDto.java new file mode 100644 index 00000000..2a78e52f --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/notices/manager/api/dto/response/plat/QueryTemplateResponseDto.java @@ -0,0 +1,50 @@ +package cn.axzo.msg.notices.manager.api.dto.response.plat; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class QueryTemplateResponseDto { + + /** + * 主键id + */ + private Long id; + /** + * 模版状态 + */ + private Integer messageTemplateStatus; + /** + * 模版类型 + */ + private Integer messageTemplateType; + /** + * 原因 + */ + private String reason; + /** + * 备注 + */ + private String remark; + /** + * 服务名 + */ + private String serviceName; + /** + * 阿里短信模版编码 + */ + private String templateAliNo; + /** + * 模版内容 + */ + private String templateContent; + /** + * 模版编码 + */ + private String templateNo; + /** + * 标题 + */ + private String title; +} diff --git a/msg-notices/msg-notices-manager/pom.xml b/msg-notices/msg-notices-manager/pom.xml new file mode 100644 index 00000000..c4aaedfb --- /dev/null +++ b/msg-notices/msg-notices-manager/pom.xml @@ -0,0 +1,55 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.manager + msg-notices-manager + + + 8 + 8 + UTF-8 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + cn.axzo.platform + axzo-log-api + + + org.apache.tomcat.embed + tomcat-embed-core + + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.dao + msg-notices-dao + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.integration + msg-notices-integration + 1.0.0-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/AliyunSmsSendManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/AliyunSmsSendManagerImpl.java new file mode 100644 index 00000000..b29eaa91 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/AliyunSmsSendManagerImpl.java @@ -0,0 +1,56 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.integration.client.impl.AliYunSmsClientImpl; +import cn.axzo.msg.notices.integration.dto.request.SendSmsCommonRequest; +import cn.axzo.msg.notices.integration.dto.response.SendSmsCommonResponse; +import cn.axzo.msg.notices.manager.api.SmsSendManager; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.BatchMessageSendResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * sms服务 + * + * @Author: LiuYang + * @Date: 2021/5/25 16:04 + */ +@Slf4j +@Service("aliyunSmsSendManager") +public class AliyunSmsSendManagerImpl implements SmsSendManager { + + @Resource + private AliYunSmsClientImpl aliyunSmsService; + + @Override + public SendSmsCommonResponseDto sendMessage(MessageSendRequestDto requestDto) { + log.info("[AliyunSmsSendManagerImpl#sendMessage] -> aliyun - 发送sms {}", JSON.toJSONString(requestDto)); + // 请求转换 + SendSmsCommonRequest request = new SendSmsCommonRequest(); + request.setPhoneNo(requestDto.getPhoneNo()); + request.setTemplateCode(requestDto.getTemplateNo()); + request.setTemplateMap(requestDto.getTemplateMap()); + request.setRequestChannelNo(requestDto.getRequestChannelNo()); + + // 发送短信 + SendSmsCommonResponse response = aliyunSmsService.sendSms(request); + + // 响应请求 + SendSmsCommonResponseDto result = new SendSmsCommonResponseDto(); + result.setBizId(response.getBizId()); + result.setRequestId(response.getRequestId()); + result.setMessage(result.getMessage()); + return result; + } + + @Override + public BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto) { + throw new UnsupportedOperationException(); + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageMangerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageMangerImpl.java new file mode 100644 index 00000000..0677f44a --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageMangerImpl.java @@ -0,0 +1,164 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.enums.BatchMessageStatusEnum; +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.common.enums.MessageTypeEnum; +import cn.axzo.msg.notices.common.enums.NotifyTypeEnum; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.domain.BatchMessageQuery; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.repository.BatchMessageDao; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import cn.axzo.msg.notices.manager.api.BatchMessageManger; +import cn.axzo.msg.notices.manager.api.SmsSendManager; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import cn.azxo.framework.common.utils.LogUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @Classname BatchMessageMangerImpl + * @Author: szg + * @Date: 2021年08月09日 17:17 + * @Description: + */ +@Service("batchMessageManger") +@Slf4j +public class BatchMessageMangerImpl implements BatchMessageManger { + + @Resource(name = "messageDao") + private MessageDao messageDao; + + @Resource(name = "batchMessageDao") + private BatchMessageDao batchMessageDao; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Resource(name = "smsSendManagerComposite") + private SmsSendManager smsSendManagerComposite; + + @Resource(name = "genericConversionService") + private GenericConversionService genericConversionService; + + @Override + public Page queryByPage(BatchMessageRequestDto requestDto) { + BatchMessageQuery query = new BatchMessageQuery(); + BeanUtils.copyProperties(requestDto, query); + IPage messagePage = batchMessageDao.queryByPage(query); + if (messagePage == null) { + log.info("BatchMessageMangerImpl.queryByPage result is null"); + return null; + } + Page result = new Page<>(); + result.setPageNum(messagePage.getCurrent()); + result.setPageSize(messagePage.getSize()); + result.setTotalElements(messagePage.getTotal()); + result.setList(messagePage.getRecords()); + return result; + } + + @Override + public BatchMessage queryBatchMessage(String batchNo) { + return batchMessageDao.queryBatchMessage(batchNo); + } + + @Override + public boolean batchMessageSplitToMessage(BatchMessage batchMessage) { + List messages = initMessageList(batchMessage); + if (CollectionUtils.isEmpty(messages)) { + log.info("BatchMessageMangerImpl.batchMessageSplitToMessage initMessageList result is null "); + return false; + } + return transactionTemplate.execute(status -> { + Boolean updateRes = batchMessageDao + .updateStatusById(batchMessage.getId(), BatchMessageStatusEnum.SPLIT_COMPLETED.getCode()); + if (updateRes) { + return messageDao.saveBatch(messages); + } + return false; + }); + } + + @Override + public void sendBatchMessageAndHandleReceipt(BatchMessage batchMessage) { + if (Objects.isNull(batchMessage)) { + log.info("BatchMessageMangerImpl.sendBatchMessageAndHandleReceipt batchMessage is null"); + return; + } + BatchMessageSendRequestDto requestDto = genericConversionService + .convert(batchMessage, BatchMessageSendRequestDto.class); + //1.变更状态 + batchMessageDao.updateStatusById(batchMessage.getId(),BatchMessageStatusEnum.PROCESSING.getCode()); + //2.发送消息 + try { + log.info("开始发送短信批次->BatchMessageMangerImpl.sendBatchMessageAndHandleReceipt BatchMessage = {}", + JSON.toJSONString(requestDto)); + smsSendManagerComposite.sendBatchMessage(requestDto); + }catch (Exception e){ + LogUtil.error( + "发送短信批次失败->BatchMessageMangerImpl.sendBatchMessageAndHandleReceipt BatchMessage = {} ", + JSON.toJSONString(requestDto)); + } + } + + /** + * 初始化短信模板 + * + * @param request + * @return + */ + private List initMessageList(BatchMessage request) { + + String smsContent = request.getSmsContent(); + if (StringUtils.isEmpty(smsContent)) { + return null; + } + List totalList = JSON.parseArray(smsContent, SmsContentDto.class); + if (CollectionUtils.isEmpty(totalList)) { + return null; + } + List messageList = new ArrayList<>(); + for (SmsContentDto smsContentDto : totalList) { + if (Objects.isNull(smsContentDto)) { + continue; + } + + Message message = new Message(); + message.setAppNo(request.getAppNo()); + message.setRequestNo(request.getRequestNo()); + message.setBatchNo(request.getRequestNo()); + message.setMessageOrderNo(IdUtil.simpleUUID()); + message.setMessageType(MessageTypeEnum.S.name()); + message.setNotifyType(NotifyTypeEnum.BATCH.name()); + message.setStatus(MessageStatusEnum.INIT.getCode()); + message.setChannelCode("batch"); + message.setChannelName("batch"); + message.setTemplateNo(request.getTemplateNo()); + message.setSubject(JSON.toJSONString(smsContentDto.getTemplateParams())); + message.setTargetAddress(smsContentDto.getPhoneNo()); + message.setBatchNo(request.getBatchNo()); + message.setNotifyRule(""); + message.setRemark(""); + messageList.add(message); + } + + return messageList; + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageRequestMangerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageRequestMangerImpl.java new file mode 100644 index 00000000..508b89a8 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/BatchMessageRequestMangerImpl.java @@ -0,0 +1,199 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.enums.BatchMessageRequestStatusEnum; +import cn.axzo.msg.notices.common.enums.BatchMessageStatusEnum; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.domain.BatchMessageRequestQuery; +import cn.axzo.msg.notices.dao.domain.BatchMessageStatisticsResponseDto; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.dao.entity.BatchMessageRequest; +import cn.axzo.msg.notices.dao.repository.BatchMessageDao; +import cn.axzo.msg.notices.dao.repository.BatchMessageRequestDao; +import cn.axzo.msg.notices.manager.api.BatchMessageRequestManger; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import cn.azxo.framework.common.utils.LogUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @Classname BatchMessageRequestMangerImpl + * @Author: szg + * @Date: 2021年08月09日 14:10 + * @Description: + */ +@RefreshScope +@Service("batchMessageRequestManger") +@Slf4j +public class BatchMessageRequestMangerImpl implements BatchMessageRequestManger { + + @Resource + private BatchMessageRequestDao batchMessageRequestDao; + + @Resource + private BatchMessageDao batchMessageDao; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Value("${batch.request.splitSize:100}") + private Integer splitSize; + + @Override + public boolean saveBatchMessageRequest(BatchMessageRequest batchMessageRequest) { + return batchMessageRequestDao.save(batchMessageRequest); + } + + @Override + public Page queryPageByBatchMessageQueryRequestDto( + BatchMessageRequestDto requestDto) { + BatchMessageRequestQuery query = new BatchMessageRequestQuery(); + BeanUtils.copyProperties(requestDto, query); + IPage messagePage = batchMessageRequestDao.queryByPage(query); + if (messagePage == null) { + return null; + } + Page result = new Page<>(); + result.setPageNum(messagePage.getCurrent()); + result.setPageSize(messagePage.getSize()); + result.setTotalElements(messagePage.getTotal()); + result.setList(messagePage.getRecords()); + return result; + } + + @Override + public List batchMessageRequestSplitAndSave(BatchMessageRequest batchMessageRequest) { + + String smsContent = batchMessageRequest.getSmsContent(); + if (StringUtils.isEmpty(smsContent)) { + log.info("BatchMessageRequestMangerImpl.batchMessageRequestSplitAndSave smsContent is null"); + return Lists.newArrayList(); + } + List totalList = JSON.parseArray(smsContent, SmsContentDto.class); + if (CollectionUtils.isEmpty(totalList)) { + log.info("BatchMessageRequestMangerImpl.batchMessageRequestSplitAndSave totalList is null"); + return Lists.newArrayList(); + } + List> split = ListUtil.split(totalList, splitSize); + //保存batch_message + List batchMessageList = new ArrayList<>(); + for (List dtoList : split) { + if (CollectionUtils.isEmpty(dtoList)) { + log.info("BatchMessageRequestMangerImpl.batchMessageRequestSplitAndSave split is null"); + continue; + } + BatchMessage batchMessage = buildBatchMessage(batchMessageRequest, dtoList); + batchMessageList.add(batchMessage); + } + + boolean result = transactionTemplate.execute(status ->{ + boolean updateRes = batchMessageRequestDao.updateStatusById(batchMessageRequest.getId(), + BatchMessageRequestStatusEnum.SPLIT_COMPLETED.getCode()); + if (updateRes){ + return batchMessageDao.saveBatch(batchMessageList); + } + return false; + }); + + if(result) { + return batchMessageList.stream().map(v -> v.getBatchNo()).collect(Collectors.toList()); + } + + return Lists.newArrayList(); + } + + @Override + public BatchMessageRequest queryBatchMessage(String appCode, String requestNo) { + return batchMessageRequestDao.queryBatchMessage(appCode, requestNo); + } + + @Override + public boolean updateRequestSuccess(String remark, Long id) { + return batchMessageRequestDao.updateRequestSuccess(remark, id); + } + + @Override + public void handleBatchMessageRequestStatistics(BatchMessageRequest request) { + if (Objects.isNull(request)) { + LogUtil.error("批次处理完成消息 handleBatchMessageRequestInfoUpdate batchMessageRequest is null"); + return; + } + // 统计 batch_message + BatchMessageStatisticsResponseDto responseDto = batchMessageDao + .getStatisticsMessageInfo(request.getAppNo(), request.getRequestNo()); + + if (Objects.isNull(responseDto)) { + LogUtil.error( + "批次处理完成消息 handleBatchMessageRequestInfoUpdate 统计 BatchMessageStatisticsResponseDto is null"); + return; + } + + //batchMessageRequest状态处理 + Integer batchMessageRequestStatus = getBatchMessageRequestStatus(request, + responseDto); + //更新此次统计 + batchMessageRequestDao + .updateBatchMessageRequestInfoById(request.getId(), batchMessageRequestStatus, + responseDto.getSuccessCount(), responseDto.getFailCount()); + } + + /** + * 构建批量消息 + * @param batchMessageRequest + * @param dtoList + * @return + */ + private BatchMessage buildBatchMessage(BatchMessageRequest batchMessageRequest, + List dtoList) { + BatchMessage batchMessage = new BatchMessage(); + batchMessage.setAppNo(batchMessageRequest.getAppNo()); + batchMessage.setRequestNo(batchMessageRequest.getRequestNo()); + batchMessage.setBatchNo(IdUtil.simpleUUID()); + batchMessage.setTemplateNo(batchMessageRequest.getTemplateNo()); + batchMessage.setMessageOrderNo(IdUtil.simpleUUID()); + batchMessage.setSmsContent(JSON.toJSONString(dtoList)); + batchMessage.setBatchSize(dtoList.size()); + batchMessage.setSendType(batchMessageRequest.getSendType()); + batchMessage.setStatus(BatchMessageStatusEnum.INITIALIZE.getCode()); + batchMessage.setChannelMsgId(""); + batchMessage.setChannelCode(""); + batchMessage.setChannelErrorMsg(""); + return batchMessage; + } + + /** + * 获取状态 + * @param batchMessageRequest + * @param responseDto + * @return + */ + private Integer getBatchMessageRequestStatus(BatchMessageRequest batchMessageRequest, + BatchMessageStatisticsResponseDto responseDto) { + Integer batchMessageRequestStatus = BatchMessageRequestStatusEnum.PARTIAL_SUCCESS.getCode(); + //处理状态 + if (Objects.equals(batchMessageRequest.getTotalSize(), responseDto.getSuccessCount())) { + batchMessageRequestStatus = BatchMessageRequestStatusEnum.SEND_SUCCESS.getCode(); + } else if (Objects.equals(batchMessageRequest.getTotalSize(), responseDto.getFailCount())) { + batchMessageRequestStatus = BatchMessageRequestStatusEnum.ALL_FAILED.getCode(); + } + return batchMessageRequestStatus; + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/ChuangLanSmsSendManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/ChuangLanSmsSendManagerImpl.java new file mode 100644 index 00000000..9b60fbbb --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/ChuangLanSmsSendManagerImpl.java @@ -0,0 +1,279 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.domain.BatchMessageCountContext; +import cn.axzo.msg.notices.common.enums.*; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.dao.repository.BatchMessageDao; +import cn.axzo.msg.notices.dao.repository.ChannelMessageTemplateDao; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import cn.axzo.msg.notices.integration.client.ChuangLanSmsClient; +import cn.axzo.msg.notices.integration.client.DingDingClient; +import cn.axzo.msg.notices.integration.dto.request.MessageRequest; +import cn.axzo.msg.notices.integration.dto.response.ChuangLanSmsResponse; +import cn.axzo.msg.notices.manager.api.SmsSendManager; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.BatchMessageSendResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; +import cn.axzo.msg.notices.manager.support.ChuangLanMessageContentSupport; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionSynchronizationAdapter; +import org.springframework.transaction.support.TransactionSynchronizationManager; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.annotation.Resource; + +/** + * 创蓝短信发送 Manager + * + * @author zhaoyong + * @see ChuangLanSmsSendManagerImpl + * @since 2021-08-07 19:06 + */ +@Slf4j +@Service("chuangLanSmsSendManager") +public class ChuangLanSmsSendManagerImpl implements SmsSendManager { + + @Resource(name = "chuangLanSmsClient") + private ChuangLanSmsClient chuangLanSmsClient; + + @Resource(name = "channelMessageTemplateDao") + private ChannelMessageTemplateDao templateDao; + + @Resource(name = "messageDao") + private MessageDao messageDao; + + @Resource(name = "batchMessageDao") + private BatchMessageDao batchMessageDao; + + @Resource(name = "dingDingClient") + private DingDingClient dingDingClient; + + @Resource(name = "chuangLanMessageContentSupport") + private ChuangLanMessageContentSupport chuangLanMessageContentSupport; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Resource(name = "genericConversionService") + private GenericConversionService genericConversionService; + + /** 相同内容群发接口 URL */ + private final static String COMMON_URL = "http://smssh1.253.com/msg/v1/send/json"; + + /** 相同内容变量接口 URL */ + private final static String VARIABLE_URL = "http://smssh1.253.com/msg/variable/json"; + + @Override + public SendSmsCommonResponseDto sendMessage(MessageSendRequestDto requestDto) { + String channelCode = MessageChannelEnum.CHUANG_LAN.getCode(); + // 获取渠道模板 + ChannelMessageTemplate template = + templateDao.queryByTemplateNo(requestDto.getInnerTemplateNo(), channelCode); + BizException.error(template != null, ReturnCodeEnum.SYSTEM_ERROR, "渠道模板不能为空"); + + MessageRequest request = new MessageRequest(); + boolean hasParam = template.hasParam(); + request.setHasParam(hasParam); + if(hasParam) { + request.setRequestUrl(VARIABLE_URL); + } else { + request.setRequestUrl(COMMON_URL); + } + String smsContent = chuangLanMessageContentSupport.getSingleSmsContent(requestDto, template, hasParam); + request.setSmsContent(smsContent); + MessageTemplateTypeEnum typeEnum = MessageTemplateTypeEnum.getByCode(template.getType()); + request.setMessageTemplateType(typeEnum); + request.setTemplateContent(template.getTemplateContent()); + request.setRequestChannelNo(MessageSendTypeEnum.SINGLE.getCode()); + + // 发送单条短信 + ChuangLanSmsResponse response = chuangLanSmsClient.sendMessage(request); + SendSmsCommonResponseDto result = new SendSmsCommonResponseDto(); + result.setRequestId(response.getMsgId()); + result.setMessage(result.getMessage()); + return result; + } + + @Override + public BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto) { + log.info("ChuangLanSmsManagerImpl.sendBatchMessage request param is {}", JSON.toJSONString(requestDto)); + String channelCode = MessageChannelEnum.CHUANG_LAN.getCode(); + String channelName = MessageChannelEnum.CHUANG_LAN.getMessage(); + + // 获取渠道模板 + ChannelMessageTemplate template = + templateDao.queryByTemplateNo(requestDto.getInnerTemplateNo(), channelCode); + BizException.error(template != null, ReturnCodeEnum.SYSTEM_ERROR, "渠道模板不能为空"); + + // 修改批量短信渠道和渠道模板 + transactionTemplate.executeWithoutResult(status -> { + batchMessageDao.updateChannelInfo(channelCode, template.getTemplateNo(), requestDto.getBatchNo()); + messageDao.updateBatchMessageChannelInfo(channelCode, channelName, requestDto.getBatchNo()); + }); + + MessageRequest request = new MessageRequest(); + boolean hasParam = template.hasParam(); + request.setHasParam(hasParam); + if(hasParam) { + request.setRequestUrl(VARIABLE_URL); + } else { + request.setRequestUrl(COMMON_URL); + } + String smsContent = chuangLanMessageContentSupport.getBatchSmsContent(requestDto, template, hasParam); + request.setSmsContent(smsContent); + MessageTemplateTypeEnum typeEnum = MessageTemplateTypeEnum.getByCode(template.getType()); + request.setMessageTemplateType(typeEnum); + request.setTemplateContent(template.getTemplateContent()); + request.setRequestChannelNo(MessageSendTypeEnum.BATCH.getCode()); + try { + // 发送批量短信 + ChuangLanSmsResponse response = chuangLanSmsClient.sendMessage(request); + + transactionTemplate.executeWithoutResult(status -> { + if(response.getFailNum() == requestDto.getSmsContentDtos().size()) { + // 失败提交数为总条数 + updateBatchMessageToFail(requestDto, response); + } else { + // 失败提交数小于总条数 + updateAfterChannelResponse(requestDto, response); + } + }); + + return genericConversionService.convert(response, BatchMessageSendResponseDto.class); + } catch (BizException e) { + LogUtil.error("ChuangLanSmsManagerImpl.sendBatchMessage is BizException.", e); + + transactionTemplate.executeWithoutResult(status -> { + updateBatchMessageToFail(requestDto, e); + }); + throw e; + } + } + + /** + * 提交渠道成功 + * @param requestDto + * @param response + */ + private void updateAfterChannelResponse(BatchMessageSendRequestDto requestDto, ChuangLanSmsResponse response) { + BatchMessage batchMessage = new BatchMessage(); + batchMessage.setChannelReturnCode(response.getCode()); + batchMessage.setChannelErrorMsg(response.getErrorMsg()); + batchMessage.setChannelMsgId(response.getMsgId()); + batchMessage.setFailCount(response.getFailNum()); + batchMessage.setSubmitFailNum(response.getFailNum()); + batchMessage.setSubmitSuccessNum(response.getSuccessNum()); + batchMessageDao.updateBatchMessage(batchMessage, requestDto.getBatchNo()); + } + + /** + * 提交渠道全部失败 + * @param requestDto + * @param response + */ + private void updateBatchMessageToFail(BatchMessageSendRequestDto requestDto, ChuangLanSmsResponse response){ + // 更新 batch_message 表 + BatchMessage batchMessage = new BatchMessage(); + batchMessage.setStatus(BatchMessageStatusEnum.ALL_FAILED.getCode()); + batchMessage.setSubmitFailNum(response.getFailNum()); + batchMessage.setSubmitSuccessNum(response.getSuccessNum()); + batchMessage.setChannelReturnCode(response.getCode()); + batchMessage.setChannelErrorMsg(response.getErrorMsg()); + batchMessage.setChannelMsgId(response.getMsgId()); + batchMessageDao.updateBatchMessage(batchMessage, requestDto.getBatchNo()); + + // 更新 message 表 + messageDao.updateAllBatchMessageFail(response.getErrorMsg(), requestDto.getBatchNo()); + + // 事务提交后操作 + doAfterCommit(requestDto, response, null); + } + + /** + * 提交渠道异常 + * @param requestDto + * @param e + */ + private void updateBatchMessageToFail(BatchMessageSendRequestDto requestDto, BizException e) { + BatchMessage batchMessage = new BatchMessage(); + batchMessage.setChannelReturnCode(e.getBizCode() + ""); + batchMessage.setChannelErrorMsg(e.getMessage()); + batchMessage.setStatus(BatchMessageStatusEnum.ALL_FAILED.getCode()); + int batchSize = requestDto.getSmsContentDtos().size(); + batchMessage.setFailCount(batchSize); + batchMessage.setSubmitFailNum(batchSize); + batchMessage.setChannelErrorMsg(e.getMessage()); + batchMessageDao.updateBatchMessage(batchMessage, requestDto.getBatchNo()); + + // 更新 message 表 + messageDao.updateAllBatchMessageFail(e.getMessage(), requestDto.getBatchNo()); + + // 事务提交后操作 + doAfterCommit(requestDto, null, e); + } + + /** + * 事务提交后操作(必须依赖事务) + * @param request + */ + private void doAfterCommit(BatchMessageSendRequestDto request + , ChuangLanSmsResponse response, BizException e) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){ + @Override + public void afterCommit() { + // 获取消息内容 + BatchMessageCountContext context = getMessageContext(request, response, e); + + // remove rocketmq + + // 发送钉钉消息 + dingDingClient.notifyBatchMessage(request.getInnerTemplateNo(), request.getBatchNo(), getErrorMsg(response, e)); + } + }); + } + + /** + * 获取消息上下文 + * @param request + * @param response + * @param e + * @return + */ + private BatchMessageCountContext getMessageContext(BatchMessageSendRequestDto request + , ChuangLanSmsResponse response, BizException e){ + boolean hasException = false; + if(e != null) { + hasException = true; + } + BatchMessageCountContext context = new BatchMessageCountContext(); + context.setAppCode(request.getAppCode()); + context.setAppRequestNo(request.getAppRequestNo()); + context.setBatchNo(request.getBatchNo()); + if(hasException) { + context.setFailNum(request.getSmsContentDtos().size()); + } else { + context.setFailNum(response.getFailNum()); + } + return context; + } + + /** + * 获取错误信息 + * @return + */ + private String getErrorMsg(ChuangLanSmsResponse response, BizException e) { + if(e != null) { + return e.getMessage(); + } else { + return response.getErrorMsg(); + } + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageChannelRouteImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageChannelRouteImpl.java new file mode 100644 index 00000000..620dbdb4 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageChannelRouteImpl.java @@ -0,0 +1,84 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import cn.axzo.msg.notices.common.enums.AvailableStatusEnum; +import cn.axzo.msg.notices.common.enums.MessageChannelEnum; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.dao.entity.MessageChannel; +import cn.axzo.msg.notices.dao.repository.MessageChannelDao; +import cn.axzo.msg.notices.manager.api.MessageChannelRouter; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +/** + * 消息渠道路由实现类 + * + * @author zhaoyong_sh + * @see MessageChannelRouteImpl + * @since 2021-05-27 15:04 + */ +@Service("messageChannelRoute") +public class MessageChannelRouteImpl implements MessageChannelRouter { + + @Resource(name = "messageChannelDao") + private MessageChannelDao messageChannelDao; + + @Override + public MessageChannel route(String condition) { + List messageChannels = messageChannelDao.queryAvailable(); + + BizException.error(CollectionUtils.isNotEmpty(messageChannels), ReturnCodeEnum.MESSAGE_CHANNEL_NOT_VALID); + Optional messageChannelOptional = messageChannels.stream() + // 有效渠道 + .filter(this::isValid) + // 条件过滤 + .filter(messageChannel -> conditionFilter(condition, messageChannel)) + // 优先级越小,排在越前 + .sorted(Comparator.comparing(MessageChannel::getPriority)) + // 查询优先级最高的一个 + .findFirst(); + return messageChannelOptional.orElse(null); + } + + /** + * 渠道是否有效 + * @param messageChannel + * @return + */ + private boolean isValid(MessageChannel messageChannel){ + return AvailableStatusEnum.AVAILABLE.getStatus().equals(messageChannel.getStatus()); + } + + /** + * 条件路由 + * @param condition + * @param messageChannel + * @return + */ + private boolean conditionFilter(String condition, MessageChannel messageChannel){ + try { + JSONObject conditionJO = JSON.parseObject(condition); + // 指定路由渠道 + String channelCode = conditionJO.getString(CommonConstants.ASSIGN_CHANNEL); + if(StringUtils.isNoneBlank(channelCode)) { + MessageChannelEnum channelEnum = MessageChannelEnum.getByCode(channelCode); + if(channelEnum != null) { + return channelCode.equals(messageChannel.getChannelCode()); + } + } + return true; + } catch (Exception e) { + return true; + } + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageManagerImpl.java new file mode 100644 index 00000000..cd319657 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageManagerImpl.java @@ -0,0 +1,151 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.domain.MessageQuery; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.dao.persistence.BaseEntity; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import cn.axzo.msg.notices.dao.repository.MessageRedoDao; +import cn.axzo.msg.notices.manager.api.MessageManager; +import cn.axzo.msg.notices.manager.api.dto.request.MessageQueryRequestDto; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.Objects; + +/** + * 消息记录管理实现类 + * + * @author zhaoyong_sh + * @see MessageManagerImpl + * @since 2021-05-19 18:04 + */ +@Service("messageManager") +public class MessageManagerImpl implements MessageManager { + + @Resource(name = "messageDao") + private MessageDao messageDao; + + @Resource(name = "messageRedoDao") + private MessageRedoDao messageRedoDao; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Override + public Page queryPageByMessageQueryRequestDto(MessageQueryRequestDto requestDto) { + MessageQuery query = new MessageQuery(); + BeanUtils.copyProperties(requestDto, query); + IPage messagePage = messageDao.queryByPage(query); + if (messagePage == null) { + return null; + } + Page result = new Page<>(); + result.setPageNum(messagePage.getCurrent()); + result.setPageSize(messagePage.getSize()); + result.setTotalElements(messagePage.getTotal()); + result.setList(messagePage.getRecords()); + return result; + } + + @Override + public boolean saveMessage(Message message) { + return messageDao.save(message); + } + + @Override + public boolean saveMessageRedo(MessageRedo messageRedo) { + return messageRedoDao.save(messageRedo); + } + + @Override + public boolean updateToProcessing(String bizId, String requestId, Long id) { + return messageDao.lambdaUpdate() + .set(StringUtils.isNoneBlank(bizId), Message::getChannelBizId, bizId) + .set(StringUtils.isNoneBlank(requestId), Message::getChannelRequestId, requestId) + .set(Message::getStatus, MessageStatusEnum.PROCESSING.getCode()) + .set(Message::getUpdateAt, new Date()) + .eq(Message::getId, id) + .eq(Message::getStatus, MessageStatusEnum.INIT.getCode()) + .update(); + } + + @Override + public boolean updateToFail(Long id) { + return messageDao.lambdaUpdate() + .set(Message::getStatus, MessageStatusEnum.FAIL.getCode()) + .set(Message::getUpdateAt, new Date()) + .eq(Message::getId, id) + .eq(Message::getStatus, MessageStatusEnum.INIT.getCode()) + .update(); + } + + @Override + public boolean updateToException(MessageRedo messageRedo, Long id) { + return transactionTemplate.execute(status -> { + messageDao.channelException(id); + return messageRedoDao.save(messageRedo); + }); + } + + @Override + public boolean updateExceptionToQueryStatus(String targetStatus, Long id) { + return messageDao.lambdaUpdate().eq(Message::getId, id) + .eq(Message::getStatus, MessageStatusEnum.EXCEPTION.getCode()) + .set(Message::getStatus, targetStatus) + .update(); + } + + + @Override + public Message queryMessageByMessageOrderNoAndPhoneNumber(String messageOrderNo,String channelBizId, + String phoneNumber) { + return messageDao.lambdaQuery() + .eq(Objects.nonNull(messageOrderNo),Message::getMessageOrderNo, messageOrderNo) + .eq(Objects.nonNull(channelBizId),Message::getChannelBizId, channelBizId) + .eq(Message::getTargetAddress, phoneNumber) + .eq(Message::getIsDelete, 0) + .one(); + } + + @Override + public boolean updateProcessingMessageStatusById(Long id, String status) { + return messageDao + .lambdaUpdate() + .eq(Message::getId, id) + .eq(Message::getIsDelete, 0) + .eq(Message::getStatus,MessageStatusEnum.PROCESSING.getCode()) + .set(Message::getStatus, status) + .update(); + } + + @Override + public boolean updateMessageStatusByMessageOrderNo(String messageOrderNo, String status) { + return messageDao + .lambdaUpdate() + .eq(Message::getMessageOrderNo, messageOrderNo) + .eq(Message::getIsDelete, 0) + .set(Message::getStatus, status) + .update(); + } + + @Override + public boolean updateToSuccess(String bizId, String requestId, Long id) { + return messageDao.lambdaUpdate() + .set(StringUtils.isNoneBlank(bizId), Message::getChannelBizId, bizId) + .set(StringUtils.isNoneBlank(requestId), Message::getChannelRequestId, requestId) + .set(Message::getStatus, MessageStatusEnum.SUCCESS.getCode()) + .set(BaseEntity::getUpdateAt, new Date()) + .eq(BaseEntity::getId, id) + .eq(Message::getStatus, MessageStatusEnum.INIT.getCode()) + .update(); + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRedoMangerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRedoMangerImpl.java new file mode 100644 index 00000000..4149bfd7 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRedoMangerImpl.java @@ -0,0 +1,133 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.domain.MessageContext; +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.common.enums.RetryingFlagEnum; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.domain.MessageRedoQuery; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import cn.axzo.msg.notices.dao.repository.MessageRedoDao; +import cn.axzo.msg.notices.manager.api.MessageRedoManger; +import cn.axzo.msg.notices.manager.api.dto.request.MessageRedoQueryRequestDto; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.Date; + +/** + * 消息重试 + * @author szg + */ +@Service("messageRedoManger") +public class MessageRedoMangerImpl implements MessageRedoManger { + + @Resource(name = "messageDao") + private MessageDao messageDao; + + @Resource + private MessageRedoDao messageRedoDao; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Override + public Page queryPageByMessageRedoQueryRequestDto(MessageRedoQueryRequestDto requestDto) { + MessageRedoQuery query = new MessageRedoQuery(); + BeanUtils.copyProperties(requestDto, query); + IPage messagePage = messageRedoDao.queryByPage(query); + if (messagePage == null) { + return null; + } + Page result = new Page<>(); + result.setPageNum(messagePage.getCurrent()); + result.setPageSize(messagePage.getSize()); + result.setTotalElements(messagePage.getTotal()); + result.setList(messagePage.getRecords()); + return result; + } + + @Override + public MessageRedo queryMessageRedoByRedoOrderNoAndPhoneNumber(String redoOrderNo, String bizId, String phoneNumber) { + return messageRedoDao.lambdaQuery() + .eq(!StringUtils.isEmpty(redoOrderNo),MessageRedo::getRedoOrderNo,redoOrderNo) + .eq(!StringUtils.isEmpty(bizId),MessageRedo::getChannelBizId,bizId) + .eq(MessageRedo::getTargetAddress,phoneNumber) + .eq(MessageRedo::getIsDelete,0) + .one(); + } + + @Override + public boolean updateMessageRedoStatusById(Long id, String oldStatus, String newStatus) { + messageRedoDao.lambdaUpdate() + .set(MessageRedo::getStatus,newStatus) + .eq(MessageRedo::getStatus,oldStatus) + .eq(MessageRedo::getId,id) + .eq(MessageRedo::getIsDelete,0) + .update(); + return false; + } + + @Override + public void saveByMessage(Message message) { + MessageRedo messageRedo = new MessageRedo(); + messageRedo.setAppNo(message.getAppNo()); + messageRedo.setRequestNo(message.getRequestNo()); + messageRedo.setMessageOrderNo(message.getMessageOrderNo()); + messageRedo.setRedoOrderNo(message.getChannelCode()); + messageRedo.setMessageType(message.getMessageType()); + messageRedo.setNotifyType(message.getNotifyType()); + messageRedo.setStatus(MessageStatusEnum.INIT.getCode()); + messageRedo.setChannelCode(message.getChannelCode()); + messageRedo.setChannelName(message.getChannelName()); + messageRedo.setTemplateNo(message.getTemplateNo()); + messageRedo.setSubject(message.getSubject()); + messageRedo.setTargetAddress(message.getTargetAddress()); + messageRedo.setRetryingFlag(RetryingFlagEnum.N.name()); + messageRedo.setRetryCount(0); + messageRedo.insert(); + } + + @Override + public boolean lockMessage(MessageContext context, Long id) { + Integer retryCount = context.getRetryCount() + 1; + context.setRetryCount(retryCount); + return messageRedoDao.lambdaUpdate() + .set(MessageRedo::getRetryCount, retryCount) + .set(MessageRedo::getRetryingFlag, RetryingFlagEnum.N.name()) + .eq(MessageRedo::getId, id).update(); + } + + @Override + public boolean updateRetry(Date retryAt, Long id) { + return messageRedoDao.lambdaUpdate() + .set(MessageRedo::getRetryAt, retryAt) + .set(MessageRedo::getRetryingFlag, RetryingFlagEnum.Y.name()) + .eq(MessageRedo::getId, id) + .update(); + } + + @Override + public boolean updateExceptionToFail(Long id, String messageOrderNo) { + return transactionTemplate.execute(status -> { + messageRedoDao.updateExceptionToFail(id); + return messageDao.updateExceptionToFail(messageOrderNo); + }); + } + + @Override + public boolean updateMessageRedoChannelById(Long id, String bizId,String redoMessageNo) { + return messageRedoDao.lambdaUpdate() + .set(MessageRedo::getChannelBizId, bizId) + .set(MessageRedo::getRedoOrderNo,redoMessageNo) + .eq(MessageRedo::getId, id) + .eq(MessageRedo::getIsDelete,0) + .update(); + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRequestLogManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRequestLogManagerImpl.java new file mode 100644 index 00000000..7bd3fc51 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageRequestLogManagerImpl.java @@ -0,0 +1,36 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; +import cn.axzo.msg.notices.dao.repository.MessageRequestLogDao; +import cn.axzo.msg.notices.manager.api.MessageRequestLogManager; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 请求日志处理实现类 + * + * @author zhaoyong_sh + * @see MessageRequestLogManagerImpl + * @since 2021-05-28 10:51 + */ +@Service("messageRequestLogManager") +public class MessageRequestLogManagerImpl implements MessageRequestLogManager { + + @Resource(name = "messageRequestLogDao") + private MessageRequestLogDao messageRequestLogDao; + + @Override + public Long saveRequestLog(MessageRequestLog requestLog) { + messageRequestLogDao.save(requestLog); + return requestLog.getId(); + } + + @Override + public boolean updateRequestLog(String responseBody, Long id) { + return messageRequestLogDao.lambdaUpdate() + .set(MessageRequestLog::getResponseBody, responseBody) + .eq(MessageRequestLog::getId, id) + .update(); + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateManagerImpl.java new file mode 100644 index 00000000..4e4be921 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateManagerImpl.java @@ -0,0 +1,62 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.enums.AvailableStatusEnum; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import cn.axzo.msg.notices.dao.repository.ChannelMessageTemplateDao; +import cn.axzo.msg.notices.dao.repository.MessageTemplateDao; +import cn.axzo.msg.notices.manager.api.MessageTemplateManager; +import cn.axzo.msg.notices.manager.api.MessageTemplateParamManager; +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 消息模板处理实现类 + * + * @author zhaoyong_sh + * @see MessageTemplateManagerImpl + * @since 2021-05-27 20:26 + */ +@Service("messageTemplateManager") +public class MessageTemplateManagerImpl implements MessageTemplateManager { + + @Resource(name = "messageTemplateDao") + private MessageTemplateDao messageTemplateDao; + + @Resource(name = "channelMessageTemplateDao") + private ChannelMessageTemplateDao channelMessageTemplateDao; + + @Resource(name = "messageTemplateParamManager") + private MessageTemplateParamManager messageTemplateParamManager; + + @Override + public MessageTemplate queryAndCheckInnerTemplate(String innerTemplateNo) { + MessageTemplate messageTemplate = messageTemplateDao.queryByTemplateNo(innerTemplateNo); + BizException.error(messageTemplate != null, ReturnCodeEnum.MESSAGE_TEMPLATE_NOT_EXIST); + BizException + .error(AvailableStatusEnum.AVAILABLE.getStatus().equals(messageTemplate.getStatus()), + ReturnCodeEnum.MESSAGE_TEMPLATE_NOT_VALID); + return messageTemplate; + } + + @Override + public ChannelMessageTemplate queryChannelTemplate(String innerTemplateNo, String channelCode) { + ChannelMessageTemplate channelMessageTemplate = channelMessageTemplateDao + .queryByTemplateNo(innerTemplateNo, channelCode); + BizException.error(channelMessageTemplate != null, ReturnCodeEnum.MESSAGE_TEMPLATE_NOT_EXIST); + BizException + .error(AvailableStatusEnum.AVAILABLE.getStatus().equals(channelMessageTemplate.getStatus()), + ReturnCodeEnum.MESSAGE_TEMPLATE_NOT_VALID); + return channelMessageTemplate; + } + + @Override + public List queryTemplateParam(String innerTemplateNo) { + return messageTemplateParamManager.getByCode(innerTemplateNo); + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateParamManagerImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateParamManagerImpl.java new file mode 100644 index 00000000..b7d19b3d --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/MessageTemplateParamManagerImpl.java @@ -0,0 +1,133 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.utils.KeyUtils; +import cn.axzo.msg.notices.dao.entity.MessageTemplateParam; +import cn.axzo.msg.notices.dao.repository.MessageTemplateParamDao; +import cn.axzo.msg.notices.manager.api.MessageTemplateParamManager; +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static cn.axzo.msg.notices.common.constans.CacheConstants.*; + +/** + * 消息模板参数 Manager + * + * @author zhaoyong + * @see MessageTemplateParamManagerImpl + * @since 2021-08-20 22:44 + */ +@Slf4j +@Service("messageTemplateParamManager") +public class MessageTemplateParamManagerImpl implements MessageTemplateParamManager { + + @Resource(name = "messageTemplateParamDao") + private MessageTemplateParamDao messageTemplateParamDao; + + @Resource(name = "stringRedisTemplate") + private StringRedisTemplate stringRedisTemplate; + + @PostConstruct + public void init() { + List templateParams = messageTemplateParamDao.getAllMessageTemplateParams(); + + if(CollectionUtils.isEmpty(templateParams)) { + log.info("MessageTemplateParamManager.init message template params size is zero"); + return; + } + + Map> templateParamIndex = templateParams.stream() + .map(v -> build(v)) + .collect(Collectors.groupingBy(v -> getCacheKey(v.getTemplateNo()))); + + templateParamIndex.forEach((k, v) -> { + // 参数排序 + List sortedValue = v.stream().sorted(Comparator.comparing(o -> o.getParamOrder(), + Comparator.comparingInt(o -> o))).collect(Collectors.toList()); + + // 构建缓存 + buildCache(k, sortedValue); + }); + + } + + @Override + public List getByCode(String templateCode) { + // 获取缓存 key + String cacheKey = getCacheKey(templateCode); + + // 从缓存中获取对象 + String value = stringRedisTemplate.opsForValue().get(cacheKey); + + // 不存在对象 + if(REDIS_NULL_VALUE.equals(value)){ + return null; + } + + // 对象不为空 + List templateParamInCache = JSON.parseArray(value, TemplateParamDto.class); + if(CollectionUtils.isNotEmpty(templateParamInCache)) { + return templateParamInCache; + } + + // 查询数据库信息 + List result = messageTemplateParamDao.getByTemplateNo(templateCode); + if(result == null) { + // 防止缓存恶意穿透 + stringRedisTemplate.opsForValue().set(cacheKey, REDIS_NULL_VALUE, NULL_VALUE_CACHE_SECONDS, TimeUnit.SECONDS); + return null; + } + + // 对象转换 + List paramDtos = result.stream().map(v -> build(v)) + .collect(Collectors.toList()); + + // 构建缓存 + buildCache(cacheKey, paramDtos); + + return paramDtos; + } + + /** + * 获取分组 KEY + * @param templateNo + * @return + */ + private String getCacheKey(String templateNo) { + return KeyUtils.getKey(MNS, MESSAGE_TEMPLATE, PARAM, templateNo); + } + + /** + * 构建缓存 + * @param cacheKey + * @param dtos + */ + private void buildCache(String cacheKey, List dtos){ + stringRedisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(dtos), TEMPLATE_PARAM_CACHE_SECONDS, TimeUnit.SECONDS); + } + + /** + * 构建参数 + * @param param + * @return + */ + private TemplateParamDto build(MessageTemplateParam param){ + return TemplateParamDto.builder() + .templateNo(param.getTemplateNo()) + .paramName(param.getParamName()) + .paramOrder(param.getParamOrder()) + .build(); + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/RetryStrategyImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/RetryStrategyImpl.java new file mode 100644 index 00000000..3ffcb704 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/RetryStrategyImpl.java @@ -0,0 +1,82 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.constans.CommonConstants; +import cn.axzo.msg.notices.common.domain.MessageContext; +import cn.axzo.msg.notices.manager.api.RetryStrategy; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 重试策略实现类 + * + * @author zhaoyong_sh + * @see RetryStrategyImpl + * @since 2021-05-19 10:42 + */ +@Slf4j +@Service("retryStrategy") +public class RetryStrategyImpl implements RetryStrategy { + + @Value("${notice.retry.rule}") + private String noticeRetryRule; + + @Override + public List getRetryStrategy() { + List retryStrategyList = parseRetryStrategy(noticeRetryRule); + if(retryStrategyList.size() > CommonConstants.MAX_RETRY_COUNT) { + return retryStrategyList.subList(0, CommonConstants.MAX_RETRY_COUNT); + } + return retryStrategyList; + } + + @Override + public Integer getNextNotifySecond(MessageContext context) { + if(context == null) { + return null; + } + if(context.getRetryCount() == null) { + return null; + } + if(StringUtils.isEmpty(context.getNotifyRule())) { + return null; + } + String notifyRule = context.getNotifyRule(); + final List notifyRules = Lists.newArrayList(); + Splitter.on(CommonConstants.COMMA_SYMBOL).split(notifyRule).forEach(e -> notifyRules.add(Integer.parseInt(e))); + log.info("notify message get notify rule {}", notifyRules.toString()); + if(context.getRetryCount() >= notifyRules.size()) { + return null; + } + return notifyRules.get(context.getRetryCount()); + } + + /** + * 解析重试策略 + * @param notifyRule + * @return + */ + private List parseRetryStrategy(String notifyRule) { + List delaySeconds = Lists.newArrayList(); + for(String strategy : notifyRule.split(CommonConstants.COMMA_SYMBOL)){ + try { + int delaySecond = Integer.parseInt(strategy); + delaySeconds.add(delaySecond); + } catch (Exception e) { + delaySeconds.clear(); + break; + } + } + if(CollectionUtils.isEmpty(delaySeconds)){ + return Lists.newArrayList(30, 60, 60); + } + return delaySeconds; + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/SmsSendManagerComposite.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/SmsSendManagerComposite.java new file mode 100644 index 00000000..c1a47dab --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/SmsSendManagerComposite.java @@ -0,0 +1,232 @@ +package cn.axzo.msg.notices.manager; + +import cn.axzo.msg.notices.common.domain.ServiceContext; +import cn.axzo.msg.notices.common.domain.ServiceContextHolder; +import cn.axzo.msg.notices.common.enums.ChannelHandlerEnum; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.dao.entity.MessageChannelLog; +import cn.axzo.msg.notices.manager.api.SmsSendManager; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.BatchMessageSendResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + +/** + * 消息发送聚合类 + * + * @author zhaoyong + * @see SmsSendManagerComposite + * @since 2021-08-19 10:51 + */ +@Slf4j +@Component("smsSendManagerComposite") +public class SmsSendManagerComposite implements SmsSendManager, ApplicationContextAware { + + private ApplicationContext applicationContext; + + @Override + public SendSmsCommonResponseDto sendMessage(MessageSendRequestDto request) { + // 根据渠道码获取实现类 + ChannelHandlerEnum handler = ChannelHandlerEnum.getByCode(request.getChannelCode()); + BizException.error(handler != null, ReturnCodeEnum.SYSTEM_ERROR, + "不支持的渠道码:" + request.getChannelCode()); + + SmsSendManager sendManager = applicationContext.getBean(handler.getMessage(), SmsSendManager.class); + + // 渲染请求 + renderRequest(request); + + // 服务上下文 + ServiceContextHolder.set(new ServiceContext()); + + try { + // 发送短信 + SendSmsCommonResponseDto response = sendManager.sendMessage(request); + + // 保存渠道日志 + saveMessageChannelLog(request, ServiceContextHolder.get().getChannelResponse()); + + // 响应结果 + return response; + } catch (BizException e) { + LogUtil.error("SmsSendManagerComposite#sendMessage is BizException", e); + // 保存渠道日志 + saveMessageChannelLog(request, e); + throw e; + } catch (Exception e) { + LogUtil.error("SmsSendManagerComposite#sendMessage is Exception", e); + // 保存渠道日志 + saveMessageChannelLog(request, e.getMessage()); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "system error"); + } finally { + ServiceContextHolder.cleanUp(); + } + } + + @Override + public BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto) { + // 指定渠道 + ChannelHandlerEnum handler = ChannelHandlerEnum.CHUANG_LAN; + + // 根据渠道码获取实现类 + SmsSendManager smsSendManager = applicationContext.getBean(handler.getMessage(), SmsSendManager.class); + + // 服务上下文 + ServiceContextHolder.set(new ServiceContext()); + try { + // 发送短信 + BatchMessageSendResponseDto response = smsSendManager.sendBatchMessage(requestDto); + + // 保存渠道日志 + saveMessageChannelLog(requestDto, ServiceContextHolder.get().getChannelResponse()); + + // 响应结果 + return response; + } catch (BizException e) { + LogUtil.error("SmsSendManagerComposite#sendBatchMessage is BizException", e); + // 保存渠道日志 + saveMessageChannelLog(requestDto, e); + throw e; + } catch (Exception e) { + LogUtil.error("SmsSendManagerComposite#sendBatchMessage is Exception", e); + // 保存渠道日志 + saveMessageChannelLog(requestDto, e.getMessage()); + throw new BizException(ReturnCodeEnum.SYSTEM_ERROR, "system error"); + } finally { + ServiceContextHolder.cleanUp(); + } + } + + /** + * 渲染请求 + * @param request + */ + private void renderRequest(MessageSendRequestDto request) { + // 获取模板参数 + Map templateMap = request.getTemplateMap(); + + // 处理短信字符串变量参数超长问题 + Map renderTemplateMap = handleSmsParamsSize(templateMap); + + // 修改模板参数 + request.setTemplateMap(renderTemplateMap); + } + + /** + * 处理短信字符串变量参数超长问题 + * @param templateMap + * @return + */ + private Map handleSmsParamsSize(Map templateMap) { + if (CollectionUtils.isEmpty(templateMap)){ + return templateMap; + } + Iterator> entries = templateMap.entrySet().iterator(); + + while (entries.hasNext()) { + Entry entry = entries.next(); + Object value = entry.getValue(); + String key = entry.getKey(); + if (Objects.nonNull(value)){ + if (value instanceof String){ + String handledStr = handleSmsVariableSize(String.valueOf(value)); + templateMap.put(key,handledStr); + } + } + } + return templateMap; + } + + /** + * 处理短信参数长度 + * @param str + * @return + */ + private String handleSmsVariableSize(String str) { + if (str != null) { + int size = str.length(); + if ( size <= 25 ) { + return str; + } + return str.substring(0, 22) + "..."; + } + return ""; + } + + /** + * 保存单条短信渠道日志 + * @param requestDto + * @param response + * @param response + */ + private void saveMessageChannelLog(MessageSendRequestDto requestDto, Object response) { + MessageChannelLog log = new MessageChannelLog(); + log.setAppNo(requestDto.getAppCode()); + log.setAppRequestNo(requestDto.getAppRequestNo()); + log.setMessageOrderNo(requestDto.getRequestChannelNo()); + log.setTargetAddress(requestDto.getPhoneNo()); + log.setUpdateAt(new Date()); + log.setCreateAt(new Date()); + String responseData = getResponseData(response); + log.setResponseData(responseData); + log.insert(); + } + + + + /** + * 保存批量短信渠道日志 + * @param requestDto + * @param response + */ + private void saveMessageChannelLog(BatchMessageSendRequestDto requestDto, Object response) { + MessageChannelLog log = new MessageChannelLog(); + log.setAppNo(requestDto.getAppCode()); + log.setAppRequestNo(requestDto.getAppRequestNo()); + log.setMessageOrderNo(requestDto.getRequestChannelNo()); + log.setTargetAddress(requestDto.getMessageKey()); + log.setUpdateAt(new Date()); + log.setCreateAt(new Date()); + String responseData = getResponseData(response); + log.setResponseData(responseData); + log.insert(); + } + + /** + * 获取响应数据 + * @param response + * @return + */ + private String getResponseData(Object response){ + if(response instanceof BizException) { + BizException exception = BizException.class.cast(response); + if(exception.getData() != null) { + return JSON.toJSONString(exception.getData()); + } else { + return JSON.toJSONString(exception.getMessage()); + } + } else { + return JSON.toJSONString(response); + } + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanBatchMessageRequestDtoConverter.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanBatchMessageRequestDtoConverter.java new file mode 100644 index 00000000..9e2d06c0 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanBatchMessageRequestDtoConverter.java @@ -0,0 +1,37 @@ +package cn.axzo.msg.notices.manager.converter; + +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import com.alibaba.fastjson.JSON; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import java.util.List; + +/** + * @Classname ChuangLanBatchMessageRequestDtoConverter + * @Author: szg + * @Date: 2021年08月10日 11:51 + * @Description: + */ +@Component +public class ChuangLanBatchMessageRequestDtoConverter implements + Converter { + + @Override + public BatchMessageSendRequestDto convert(BatchMessage source) { + Assert.notNull(source, "source must not be null"); + BatchMessageSendRequestDto requestDto = new BatchMessageSendRequestDto(); + requestDto.setAppCode(source.getAppNo()); + requestDto.setAppRequestNo(source.getRequestNo()); + requestDto.setRequestChannelNo(source.getMessageOrderNo()); + requestDto.setInnerTemplateNo(source.getTemplateNo()); + requestDto.setBatchNo(source.getBatchNo()); + List dtos = JSON + .parseArray(source.getSmsContent(), SmsContentDto.class); + requestDto.setSmsContentDtos(dtos); + return requestDto; + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanSmsResponseDtoToVoConverter.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanSmsResponseDtoToVoConverter.java new file mode 100644 index 00000000..267c868e --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/converter/ChuangLanSmsResponseDtoToVoConverter.java @@ -0,0 +1,31 @@ +package cn.axzo.msg.notices.manager.converter; + +import cn.axzo.msg.notices.integration.dto.response.ChuangLanSmsResponse; +import cn.axzo.msg.notices.manager.api.dto.response.BatchMessageSendResponseDto; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +/** + * DTO -> VO + * + * @author zhaoyong + * @see ChuangLanSmsResponseDtoToVoConverter + * @since 2021-08-07 20:32 + */ +@Component +public class ChuangLanSmsResponseDtoToVoConverter implements Converter { + + @Override + public BatchMessageSendResponseDto convert(ChuangLanSmsResponse source) { + Assert.notNull(source, "source must not be null"); + BatchMessageSendResponseDto response = new BatchMessageSendResponseDto(); + response.setCode(source.getCode()); + response.setErrorMsg(source.getErrorMsg()); + response.setSuccessNum(source.getSuccessNum()); + response.setFailNum(source.getFailNum()); + response.setMsgId(source.getMsgId()); + response.setTime(source.getTime()); + return response; + } +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ApiRequestLogAspect.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ApiRequestLogAspect.java new file mode 100644 index 00000000..7caeb0b0 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ApiRequestLogAspect.java @@ -0,0 +1,61 @@ +package cn.axzo.msg.notices.manager.support; + +import cn.axzo.msg.notices.common.annotation.ApiRequestLog; +import cn.axzo.msg.notices.dao.entity.MessageRequestLog; +import cn.axzo.msg.notices.manager.api.MessageRequestLogManager; +import cn.axzo.msg.notices.manager.api.dto.request.BaseRequestDto; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 切面日志实现类 + * + * @author zhaoyong_sh + * @see ApiRequestLogAspect + * @since 2021-05-28 10:45 + */ +@Aspect +@Slf4j +@Component +public class ApiRequestLogAspect { + + @Resource(name = "messageRequestLogManager") + private MessageRequestLogManager messageRequestLogManager; + + @Around("@annotation(apiRequestLog)") + public Object methodHandler(ProceedingJoinPoint jp, ApiRequestLog apiRequestLog) throws Throwable { + Object[] params = jp.getArgs(); + Object param = params[0]; + Signature signature = jp.getSignature(); + // 方法名 + String methodName = signature.getName(); + // 类名 + String typeName = signature.getDeclaringType().getSimpleName(); + log.info("保存请求日志:{}.{} Begin Request : {}", typeName, methodName, JSON.toJSONString(param)); + // 保存requestLog + BaseRequestDto baseRequestDto = BeanUtil.copyProperties(param, BaseRequestDto.class); + MessageRequestLog requestLog = new MessageRequestLog(); + requestLog.setAppNo(baseRequestDto.getAppCode()); + requestLog.setRequestNo(baseRequestDto.getRequestNo()); + requestLog.setMethodName(methodName); + requestLog.setRequestBody(JSON.toJSONString(param)); + Long requestLogId = messageRequestLogManager.saveRequestLog(requestLog); + log.info("执行方法"); + Object result = jp.proceed(); + if(result != null) { + messageRequestLogManager.updateRequestLog(JSON.toJSONString(result), requestLogId); + log.info("返回Controller应答:{}", JSONUtil.toJsonStr(result)); + } + return result; + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ChuangLanMessageContentSupport.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ChuangLanMessageContentSupport.java new file mode 100644 index 00000000..25aa84a8 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ChuangLanMessageContentSupport.java @@ -0,0 +1,162 @@ +package cn.axzo.msg.notices.manager.support; + +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.manager.api.MessageTemplateParamManager; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 创兰消息内部解析类 + * + * @author zhaoyong + * @see ChuangLanMessageContentSupport + * @since 2021-08-19 10:14 + */ +@Component("chuangLanMessageContentSupport") +public class ChuangLanMessageContentSupport { + + @Resource(name = "messageTemplateParamManager") + private MessageTemplateParamManager messageTemplateParamManager; + + /** + * 获取单条消息内容 + * @param requestDto + * @param hasParam + * @return + */ + public String getSingleSmsContent(MessageSendRequestDto requestDto + , ChannelMessageTemplate template, boolean hasParam){ + if(hasParam) { + return getSingleVariableSmsContent(requestDto, template); + } else { + return getSingleCommonSmsContent(requestDto); + } + } + + /** + * 获取批量消息内容 + * @param requestDto + * @param hasParam + * @return + */ + public String getBatchSmsContent(BatchMessageSendRequestDto requestDto + , ChannelMessageTemplate template, boolean hasParam){ + if(hasParam) { + return getBatchVariableSmsContent(requestDto, template); + } else { + return getBatchCommonSmsContent(requestDto); + } + } + + /** + * 获取相同内容变量接口消息内容 + * @param requestDto + * @return + */ + private String getSingleVariableSmsContent(MessageSendRequestDto requestDto, ChannelMessageTemplate template){ + // 查询消息模板中的变量名称列表 + List messageTemplateParams = messageTemplateParamManager.getByCode(template.getInnerTemplateNo()); + BizException.error(CollectionUtils.isNotEmpty(messageTemplateParams), + ReturnCodeEnum.SYSTEM_ERROR, "变量模板顺序参数不能为空"); + + // 把对象转换成变量名称字符串列表 + List paramNames = messageTemplateParams.stream().map(v -> v.getParamName()) + .collect(Collectors.toList()); + + // 定义单条消息中参数列表 + List singleMessageParams = new ArrayList<>(); + // 第一个变量一定是手机号 + String phoneNo = requestDto.getPhoneNo(); + singleMessageParams.add(phoneNo); + // 按照数据库定义的顺序查询模板变量的值 + for (String paramName : paramNames) { + // 获取业务方传入的变量值 + Object paramValue = requestDto.getTemplateMap().get(paramName); + BizException.error(paramValue != null, ReturnCodeEnum.INVALID_PARAMETER, paramName + "不能为空"); + // 添加到单条消息中参数列表 + singleMessageParams.add(paramValue.toString()); + } + // 单条消息以逗号拼接成消息体 + return singleMessageParams.stream().collect(Collectors.joining(",")); + } + + /** + * 获取相同内容群发接口消息内容 + * @param requestDto + * @return + */ + private String getSingleCommonSmsContent(MessageSendRequestDto requestDto) { + return requestDto.getPhoneNo(); + } + + /** + * 获取相同内容变量接口消息内容 + * @param requestDto + * @return + */ + private String getBatchVariableSmsContent(BatchMessageSendRequestDto requestDto, ChannelMessageTemplate template){ + // 查询消息模板中的变量名称列表 + List messageTemplateParams = messageTemplateParamManager.getByCode(template.getInnerTemplateNo()); + BizException.error(CollectionUtils.isNotEmpty(messageTemplateParams), + ReturnCodeEnum.SYSTEM_ERROR, "变量模板顺序参数不能为空"); + + // 把对象转换成变量名称字符串列表 + List paramNames = messageTemplateParams.stream().map(v -> v.getParamName()) + .collect(Collectors.toList()); + + // 获取请求参数短信内容列表 + List dtos = requestDto.getSmsContentDtos(); + + // 定义单条消息列表,列表内容为 手机号,变量值1,变量值2,变量值3... + List singleMessages = new ArrayList<>(); + + // 遍历请求参数短信内容列表 + for (SmsContentDto dto : dtos) { + // 定义单条消息中参数列表 + List singleMessageParams = new ArrayList<>(); + // 第一个变量一定是手机号 + String phoneNo = dto.getPhoneNo(); + singleMessageParams.add(phoneNo); + JSONObject templateParams = JSON.parseObject(dto.getTemplateParams()); + // 按照数据库定义的顺序查询模板变量的值 + for (String paramName : paramNames) { + // 获取业务方传入的变量值 + String paramValue = templateParams.getString(paramName); + // 添加到单条消息中参数列表 + singleMessageParams.add(paramValue); + } + // 单条消息以逗号拼接成消息体 + String singleMessage = singleMessageParams.stream().collect(Collectors.joining(",")); + singleMessages.add(singleMessage); + } + // 批量消息以分号拼接 + return singleMessages.stream().collect(Collectors.joining(";")); + } + + /** + * 获取相同内容群发接口消息内容 + * @param requestDto + * @return + */ + private String getBatchCommonSmsContent(BatchMessageSendRequestDto requestDto) { + // 获取请求参数短信内容列表 + List dtos = requestDto.getSmsContentDtos(); + + // 相同内容群发接口以逗号拼接手机号 + return dtos.stream().map(v -> v.getPhoneNo()).collect(Collectors.joining(",")); + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ConversionServiceConfig.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ConversionServiceConfig.java new file mode 100644 index 00000000..6af5ba9e --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/ConversionServiceConfig.java @@ -0,0 +1,27 @@ +package cn.axzo.msg.notices.manager.support; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.GenericConversionService; + +import java.util.List; + +/** + * 自动转换配置类 + * + * @author zhaoyong_sh + * @see ConversionServiceConfig + * @since 2021-05-27 18:26 + */ +@Configuration +public class ConversionServiceConfig { + + @Bean("genericConversionService") + public GenericConversionService genericConversionService(List converters){ + GenericConversionService conversionService = new GenericConversionService(); + converters.forEach(converter -> conversionService.addConverter(converter)); + return conversionService; + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/PushOperationAspect.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/PushOperationAspect.java new file mode 100644 index 00000000..4ac0cc21 --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/PushOperationAspect.java @@ -0,0 +1,99 @@ +package cn.axzo.msg.notices.manager.support; + +import cn.axzo.log.platform.client.LogPlatClient; +import cn.axzo.log.platform.client.model.OperateLogReq; +import cn.axzo.msg.notices.common.annotation.PushOperation; +import com.alibaba.fastjson.JSON; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.Objects; + +/** + * @author wangli + * @since 2022/12/22 10:38 + */ +@Aspect +@Component +public class PushOperationAspect { + private static final Logger log = LoggerFactory.getLogger(PushOperationAspect.class); + @Autowired + private LogPlatClient logPlatClient; + + @Pointcut("@annotation(cn.axzo.msg.notices.common.annotation.PushOperation)") + public void pointcut() { + } + + @Before("@annotation(operation)") + public void before(JoinPoint point, PushOperation operation) { + try { + OperateLogReq req = OperateLogReq.builder() + .serviceName(getHeader("server-app-id")) + .featureName(operation.value()) + .operateTime(new Date()) + .identityId(0L) + .identityUserName("") + .identityType(0) + .operateBefore("{}") + .operateParam(buildRequest(point).toString()) + .operateAfter("{}") + .workspaceId(0L) + .operateType(1) + .build(); + logPlatClient.createOperateLog(req); + }catch (Exception e){ + log.warn("无法正常调用日志管理服务: {}", e.getMessage()); + } + } + + /** + * 获取Http头中的header + * + * @return String + */ + public static String getHeader(String headerName) { + HttpServletRequest request = getRequest(); + return Objects.requireNonNull(request).getHeader(headerName); + } + + /** + * 获取HttpRequest + * + * @return HttpServletRequest + */ + public static HttpServletRequest getRequest() { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (Objects.nonNull(requestAttributes)) { + return requestAttributes.getRequest(); + } + return null; + } + + private static StringBuilder buildRequest(JoinPoint point) { + LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); + String[] parameterNames = u.getParameterNames(((MethodSignature) point.getSignature()).getMethod()); + Object[] args = point.getArgs(); + StringBuilder sb = new StringBuilder(); + if (args != null && parameterNames != null) { + for (int i = 0; i < args.length; i++) { + sb.append(parameterNames[i]); + sb.append("="); + sb.append(JSON.toJSONString(args[i])); + } + } + return sb; + } + +} diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/UserCellphoneProperties.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/UserCellphoneProperties.java new file mode 100644 index 00000000..9c56559a --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/notices/manager/support/UserCellphoneProperties.java @@ -0,0 +1,34 @@ +package cn.axzo.msg.notices.manager.support; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用户手机配置类 + * + * @author zhaoyong + * @see UserCellphoneProperties + * @since 2021-07-12 16:34 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "user.cellphone") +@RefreshScope +public class UserCellphoneProperties { + + /** + * 白名单 + */ + private List whitelist = new ArrayList<>(); + + /** + * 黑名单 + */ + private List blacklist = new ArrayList<>(); + +} diff --git a/msg-notices/msg-notices-service-api/pom.xml b/msg-notices/msg-notices-service-api/pom.xml new file mode 100644 index 00000000..b3797524 --- /dev/null +++ b/msg-notices/msg-notices-service-api/pom.xml @@ -0,0 +1,44 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.service.api + msg-notices-service-api + + + 8 + 8 + UTF-8 + + + + + cn.axzo.msg.notices.common + msg-notices-common + + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.common + msg-notices-common + 1.0.0-SNAPSHOT + compile + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageCallbackService.java b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageCallbackService.java new file mode 100644 index 00000000..c741b0e4 --- /dev/null +++ b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageCallbackService.java @@ -0,0 +1,29 @@ +package cn.axzo.msg.notices.service.api; + +import cn.axzo.msg.notices.manager.api.dto.request.AliMessageCallbackRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.ChuangLanSmsReportRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.AliCallbackResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.ChuangLanCallbackResponseDto; + +import java.util.List; + +/** + * 消息回调处理 + */ +public interface MessageCallbackService { + + /** + * 阿里云短信回调处理 + * @param request + * @return + */ + AliCallbackResponseDto aliCallbackHandle(List request); + + /** + * 创蓝短信回调处理 + * @param request + * @return + */ + ChuangLanCallbackResponseDto chuangLanCallbackHandle(ChuangLanSmsReportRequestDto request); + +} diff --git a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageService.java b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageService.java new file mode 100644 index 00000000..621cec7f --- /dev/null +++ b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/MessageService.java @@ -0,0 +1,26 @@ +package cn.axzo.msg.notices.service.api; + +import cn.axzo.msg.notices.manager.api.dto.request.SendBatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SendMessageRequestDto; + +/** + * 消息服务 + * @Author: LiuYang + * @Date: 2021/5/20 13:53 + */ +public interface MessageService { + + /** + * 发送消息 + * @param request + * @return + */ + void sendMessage(SendMessageRequestDto request); + + /** + * 批量发送短信 + * @param request + */ + void sendBatchMessage(SendBatchMessageRequestDto request); + +} diff --git a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/PlatService.java b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/PlatService.java new file mode 100644 index 00000000..badf9941 --- /dev/null +++ b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/PlatService.java @@ -0,0 +1,32 @@ +package cn.axzo.msg.notices.service.api; + + +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.manager.api.dto.request.plat.CreateTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.plat.QueryTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.plat.QueryTemplateResponseDto; + +public interface PlatService { + + /* + * 创建短信模板 + */ + void createTemplate(CreateTemplateRequestDto request); + + /** + * 通过短信模板获取模板信息 + */ + QueryTemplateResponseDto getByTemplateNo(String templateNo); + + /** + * 分页查询 + * @param request + * @return + */ + Page list(QueryTemplateRequestDto request); + + /* + * 删除短信模板 + */ + void delete(String templateNo); +} diff --git a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/TaskService.java b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/TaskService.java new file mode 100644 index 00000000..01449419 --- /dev/null +++ b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/notices/service/api/TaskService.java @@ -0,0 +1,61 @@ +package cn.axzo.msg.notices.service.api; + +import cn.azxo.framework.common.model.JobPageRequest; + +/** + * 定时任务服务类 + * + * @author zhaoyong_sh + * @see TaskService + * @since 2021-05-19 15:47 + */ +public interface TaskService { + + /** + * 处理短信发送异常(阿里云) + * @param request + */ + void aliYunProcessSendMessageException(JobPageRequest request); + + /** + * 发送中的短信补偿(阿里云) + * @param request + */ + void aliYunMessageProcessingHandle(JobPageRequest request); + + /** + * 短信拆分发送批次 + * @param request + */ + void batchMessageRequestSplitHandle(JobPageRequest request); + + /** + * 短信发送批次拆分 + */ + void batchMessageSendSplitHandle(JobPageRequest request); + + /** + * 按照批次批量发送消息 + * @param request + */ + void batchSendMessage(JobPageRequest request); + + /** + * 实时批量消息请求拆分补偿任务 + * @param request + */ + void realBatchMessageRequestSplitCompensation(JobPageRequest request); + + /** + * 实时批量消息拆分补偿任务 + * @param request + */ + void realBatchMessageSplitCompensation(JobPageRequest request); + + /** + * 批量请求计数补偿 + * @param request + */ + void batchMessageRequestCountCompensation(JobPageRequest request); + +} diff --git a/msg-notices/msg-notices-service/pom.xml b/msg-notices/msg-notices-service/pom.xml new file mode 100644 index 00000000..4623dad4 --- /dev/null +++ b/msg-notices/msg-notices-service/pom.xml @@ -0,0 +1,79 @@ + + + + msg-notices + cn.axzo.msgcenter + ${revision} + ../pom.xml + + 4.0.0 + + cn.axzo.msg.notices.service + msg-notices-service + + + 8 + 8 + UTF-8 + + + + + cn.axzo.msg.notices.service.api + msg-notices-service-api + + + cn.axzo.msg.notices.manager + msg-notices-manager + + + org.springframework.cloud + spring-cloud-context + + + cn.axzo.msg.notices.service.api + msg-notices-service-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.dao + msg-notices-dao + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.manager.api + msg-notices-manager-api + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.integration + msg-notices-integration + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.manager + msg-notices-manager + 1.0.0-SNAPSHOT + compile + + + cn.axzo.msg.notices.manager + msg-notices-manager + 1.0.0-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageCallbackServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageCallbackServiceImpl.java new file mode 100644 index 00000000..39045235 --- /dev/null +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageCallbackServiceImpl.java @@ -0,0 +1,280 @@ +package cn.axzo.msg.notices.service; + +import cn.axzo.msg.notices.common.constans.ChuangLanConstants; +import cn.axzo.msg.notices.common.domain.BatchMessageCountContext; +import cn.axzo.msg.notices.common.enums.BatchMessageStatusEnum; +import cn.axzo.msg.notices.common.enums.MessageSendTypeEnum; +import cn.axzo.msg.notices.common.enums.MessageStatusEnum; +import cn.axzo.msg.notices.dao.entity.BatchMessage; +import cn.axzo.msg.notices.dao.entity.Message; +import cn.axzo.msg.notices.dao.entity.MessageRedo; +import cn.axzo.msg.notices.dao.repository.BatchMessageDao; +import cn.axzo.msg.notices.dao.repository.MessageChannelLogDao; +import cn.axzo.msg.notices.dao.repository.MessageDao; +import cn.axzo.msg.notices.manager.api.MessageManager; +import cn.axzo.msg.notices.manager.api.MessageRedoManger; +import cn.axzo.msg.notices.manager.api.dto.request.AliMessageCallbackRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.ChuangLanSmsReportRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.AliCallbackResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.ChuangLanCallbackResponseDto; +import cn.axzo.msg.notices.service.api.MessageCallbackService; +import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionSynchronizationAdapter; +import org.springframework.transaction.support.TransactionSynchronizationManager; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +/** + * @author: szg + * @Date: 2021/5/28 15:49 + * @Description: 处理回执消息 + */ +@Slf4j +@Service("messageCallbackService") +public class MessageCallbackServiceImpl implements MessageCallbackService { + + @Resource(name = "messageManager") + private MessageManager messageManager; + + @Resource(name = "messageRedoManger") + private MessageRedoManger messageRedoManger; + + @Resource(name = "messageDao") + private MessageDao messageDao; + + @Resource(name = "messageChannelLogDao") + private MessageChannelLogDao messageChannelLogDao; + + @Resource(name = "batchMessageDao") + private BatchMessageDao batchMessageDao; + + @Resource(name = "transactionTemplate") + private TransactionTemplate transactionTemplate; + + @Override + public AliCallbackResponseDto aliCallbackHandle(List request) { + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback request {}", JSON.toJSONString(request)); + if (CollectionUtils.isEmpty(request)) { + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback request is null"); + return AliCallbackResponseDto.success(); + } + + for (AliMessageCallbackRequestDto messageInfo : request) { + if (Objects.isNull(messageInfo)) { + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback message is null"); + continue; + } + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback message is {}", JSON.toJSONString(messageInfo)); + String messageStatus = MessageStatusEnum.getSuccessCode(messageInfo.getSuccess()); + + try { + transactionTemplate.executeWithoutResult(status -> { + Message message = + messageManager.queryMessageByMessageOrderNoAndPhoneNumber( + messageInfo.getOut_id(), messageInfo.getBiz_id(), messageInfo.getPhone_number()); + if (Objects.nonNull(message)) { + // 第一次回调 + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback message is first"); + messageManager.updateProcessingMessageStatusById(message.getId(), messageStatus); + } else { + log.info("MessageCallbackServiceImpl.aliCallbackHandle callback message is retry"); + // 重试 + sendRetryHandle(messageInfo, messageStatus); + } + }); + } catch (Exception e) { + LogUtil.error("MessageCallbackServiceImpl.aliCallbackHandle is error", e); + } + } + return AliCallbackResponseDto.success(); + } + + @Override + public ChuangLanCallbackResponseDto chuangLanCallbackHandle( + ChuangLanSmsReportRequestDto request) { + if (Objects.isNull(request)) { + log.info("MessageCallbackServiceImpl.chuangLanCallbackHandle request is null"); + return ChuangLanCallbackResponseDto.success(); + } + log.info("MessageCallbackServiceImpl.chuangLanCallbackHandle request is {}", JSON.toJSONString(request)); + + try { + if(MessageSendTypeEnum.SINGLE.getCode().equals(request.getUid())) { + transactionTemplate.executeWithoutResult(status -> { + Message message = messageDao + .getByChannelMsgId(request.getMsgid(), request.getMobile()); + if (Objects.isNull(message)) { + log.info("创蓝短信回调 MessageCallbackServiceImpl.chuangLanCallbackHandle message is null"); + return; + } + String messageStatus = MessageStatusEnum.FAIL.getCode(); + if (Objects.equals(request.getStatus(), ChuangLanConstants.MESSAGE_CALLBACK_SUCCESS_STATUS)) { + messageStatus = MessageStatusEnum.SUCCESS.getCode(); + } + messageDao + .updateStatusAndRemarkById(message.getId(), messageStatus, request.getStatusDesc()); + + messageChannelLogDao.updateCallbackDate(JSON.toJSONString(request), message.getMessageOrderNo()); + }); + } else { + transactionTemplate.executeWithoutResult(status -> { + BatchMessage batchMessage = batchMessageDao.getByChannelMsgIdAndLock(request.getMsgid()); + if (Objects.isNull(batchMessage)) { + log.info("MessageCallbackServiceImpl.chuangLanCallbackHandle batchMessage is null"); + return; + } + log.info("MessageCallbackServiceImpl.chuangLanCallbackHandle batchMessage is {}", + JSON.toJSONString(batchMessage)); + //回调成功处理 + Message message = messageDao + .getByBatchNoAndPhone(batchMessage.getBatchNo(), request.getMobile()); + if (Objects.isNull(message)) { + log.info("创蓝短信回调 MessageCallbackServiceImpl.chuangLanCallbackHandle message is null"); + return; + } + //更新message 和 batchMessage 表 + updateMessageAndBatchMessage(request, message, batchMessage); + }); + } + } catch (Exception e) { + LogUtil.error("MessageCallbackServiceImpl.chuangLanCallbackHandle is error", e); + } + + return ChuangLanCallbackResponseDto.success(); + } + + /** + * 修改 batch_message 和 message + * @param request + * @param message + * @param batchMessage + */ + private void updateMessageAndBatchMessage(ChuangLanSmsReportRequestDto request, Message message, + BatchMessage batchMessage) { + log.info("MessageCallbackServiceImpl.updateMessageAndBatchMessage batchMessage is {}", + batchMessage); + log.info("MessageCallbackServiceImpl.updateMessageAndBatchMessage message is {}", message); + //处理message相关 + handleMessageAndBatchMessageInfo(request, message, batchMessage); + //当前批次已经全部回调完成发送消息更新上游状态 + if (Objects.equals(batchMessage.getBatchSize(), + batchMessage.getSuccessCount() + batchMessage.getFailCount())) { + //事务提交后发送消息 + log.info( + "MessageCallbackServiceImpl.updateMessageAndBatchMessage 消息批次处理完成发送mq消息 batchMessage is {}", + JSON.toJSONString(batchMessage)); + doAfterCommit(batchMessage); + } + } + + /** + * 事务提交后操作(必须依赖事务) + * + * @param batchMessage + */ + private void doAfterCommit(BatchMessage batchMessage) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { + @Override + public void afterCommit() { + sendCountMessageToMq(batchMessage); + } + }); + } + + /** + * 发送消息到 MQ + * @param batchMessage + */ + private void sendCountMessageToMq(BatchMessage batchMessage) { + BatchMessageCountContext context = new BatchMessageCountContext(); + context.setAppCode(batchMessage.getAppNo()); + context.setAppRequestNo(batchMessage.getRequestNo()); + context.setBatchNo(batchMessage.getBatchNo()); + context.setSuccessNum(batchMessage.getSuccessCount()); + context.setFailNum(batchMessage.getFailCount()); + // remove rocketmq + } + + /** + * 处理 batch_message 和 message + * @param request + * @param message + * @param batchMessage + */ + private void handleMessageAndBatchMessageInfo(ChuangLanSmsReportRequestDto request, + Message message, + BatchMessage batchMessage) { + Integer successCount = 0; + Integer failCount = 1; + String messageStatus = MessageStatusEnum.FAIL.getCode(); + if (Objects.equals(request.getStatus(), ChuangLanConstants.MESSAGE_CALLBACK_SUCCESS_STATUS)) { + messageStatus = MessageStatusEnum.SUCCESS.getCode(); + successCount = 1; + failCount = 0; + } + + successCount = batchMessage.getSuccessCount() + successCount; + failCount = batchMessage.getFailCount() + failCount; + + //上层发送mq消息时会用到 + batchMessage.setSuccessCount(successCount); + batchMessage.setFailCount(failCount); + + //处理BatchMessage状态 + Integer batchMessageStatus = handBatchMessageStatus(batchMessage, failCount,successCount); + boolean updateRes = messageDao + .updateStatusAndRemarkById(message.getId(), messageStatus, request.getStatusDesc()); + //更新BachMessage + if (updateRes) { + batchMessageDao + .updateBachMessageInfoById(batchMessage.getId(), batchMessageStatus, successCount, + failCount); + } + } + + /** + * 修改 batch_message 状态 + * @param batchMessage + * @param failCount + * @param successCount + * @return + */ + private Integer handBatchMessageStatus(BatchMessage batchMessage, Integer failCount, + Integer successCount) { + + Integer batchMessageStatus = BatchMessageStatusEnum.PARTIAL_SUCCESS.getCode(); + if (Objects.equals(successCount, batchMessage.getBatchSize())) { + //全部成功 + batchMessageStatus = BatchMessageStatusEnum.SEND_SUCCESS.getCode(); + } else if (Objects.equals(failCount, batchMessage.getBatchSize())) { + //还未全部完成回调 部分成功 + batchMessageStatus = BatchMessageStatusEnum.ALL_FAILED.getCode(); + } + return batchMessageStatus; + } + + /** + * 消息重试 + * @param messageInfo + * @param status + */ + private void sendRetryHandle(AliMessageCallbackRequestDto messageInfo, String status) { + MessageRedo messageRedo = + messageRedoManger.queryMessageRedoByRedoOrderNoAndPhoneNumber( + messageInfo.getOut_id(), messageInfo.getBiz_id(), messageInfo.getPhone_number()); + if (Objects.nonNull(messageRedo)) { + messageRedoManger + .updateMessageRedoStatusById(messageRedo.getId(), MessageStatusEnum.EXCEPTION.getCode(), + status); + messageManager.updateMessageStatusByMessageOrderNo(messageRedo.getMessageOrderNo(), status); + } + } + +} diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageServiceImpl.java new file mode 100644 index 00000000..90fbfe76 --- /dev/null +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/MessageServiceImpl.java @@ -0,0 +1,502 @@ +package cn.axzo.msg.notices.service; + +import cn.axzo.msg.notices.common.annotation.ApiRequestLog; +import cn.axzo.msg.notices.common.constans.CommonConstants; +import cn.axzo.msg.notices.common.domain.BatchMessageSendContext; +import cn.axzo.msg.notices.common.domain.MessageContext; +import cn.axzo.msg.notices.common.enums.*; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.common.utils.DateUtils; +import cn.axzo.msg.notices.dao.entity.*; +import cn.axzo.msg.notices.dao.repository.MessageAppDao; +import cn.axzo.msg.notices.integration.client.DingDingClient; +import cn.axzo.msg.notices.manager.api.*; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SendBatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SendMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.SmsContentDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; +import cn.axzo.msg.notices.manager.api.dto.response.TemplateParamDto; +import cn.axzo.msg.notices.manager.support.UserCellphoneProperties; +import cn.axzo.msg.notices.service.api.MessageService; +import cn.azxo.framework.common.logger.MethodAroundLog; +import cn.azxo.framework.common.utils.LogUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.PhoneUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.stream.Collectors; + +/** + * 消息服务 + * + * @Author: LiuYang + * @Date: 2021/5/20 18:23 + */ +@Slf4j +@Service +@RefreshScope +public class MessageServiceImpl implements MessageService, EnvironmentAware { + + @Resource(name = "messageAppDao") + private MessageAppDao messageAppDao; + + @Resource(name = "messageTemplateManager") + private MessageTemplateManager messageTemplateManager; + + @Resource(name = "messageManager") + private MessageManager messageManager; + + @Resource(name = "messageChannelRoute") + private MessageChannelRouter messageChannelRouter; + + @Resource(name = "retryStrategy") + private RetryStrategy retryStrategy; + + @Resource(name = "smsSendManagerComposite") + private SmsSendManager smsSendManagerComposite; + + @Resource(name = "batchMessageRequestManger") + private BatchMessageRequestManger batchMessageRequestManger; + + @Resource(name = "dingDingClient") + private DingDingClient dingDingClient; + + @Resource(name = "userCellphoneProperties") + private UserCellphoneProperties userCellphoneProperties; + + @Value("${prod.profile.string:master}") + private String prodProfileString; + + @Value("${enable.send.single.message:0}") + private Integer enableSendSingleMessage; + + @Value("${enable.send.batch.message:1}") + private Integer enableSendBatchMessage; + + private Environment environment; + + @Override + @ApiRequestLog + @MethodAroundLog(source = "Controller", target = "Service", value = "发送单条短信") + public void sendMessage(SendMessageRequestDto request) { + log.info("[MessageServiceImpl#sendMessage] request starting {}", JSON.toJSONString(request)); + + try { + // 检查上游是否可调用 + checkAppCode(request.getAppCode()); + + //手机号格式校验 + boolean isLegalPhone = PhoneUtil.isPhone(request.getPhoneNo()); + BizException.error(isLegalPhone, ReturnCodeEnum.INVALID_PARAMETER, "非法的手机号:" + request.getPhoneNo()); + + // 查询并校验 + MessageTemplate messageTemplate = messageTemplateManager + .queryAndCheckInnerTemplate(request.getTemplateNo()); + + // 通过路由获取可用消息渠道 + String condition = getChannelRouteCondition(request); + MessageChannel messageChannel = messageChannelRouter.route(condition); + BizException.error(messageChannel != null, ReturnCodeEnum.MESSAGE_CHANNEL_NOT_VALID); + log.info("[MessageServiceImpl#sendMessage] 选择渠道为 {}", JSON.toJSONString(messageChannel)); + + // 生成短信记录 + Message message = initMessage(request, messageChannel, messageTemplate); + log.info("[MessageServiceImpl#sendMessage] 生成短信模板 {}", JSON.toJSONString(message)); + + // 保存消息 + messageManager.saveMessage(message); + + // 如果模拟发短信成功,则直接设置状态并为成功 + if (shouldSkip(request)) { + successMessageAndSendDingDing(request, message, messageTemplate); + return; + } + + // 获取真实短信模板 + ChannelMessageTemplate channelTemplate = messageTemplateManager + .queryChannelTemplate(request.getTemplateNo(), messageChannel.getChannelCode()); + + // 发送短信 + try { + MessageSendRequestDto dto = new MessageSendRequestDto(); + dto.setAppCode(request.getAppCode()); + dto.setChannelCode(message.getChannelCode()); + dto.setPhoneNo(message.getTargetAddress()); + dto.setInnerTemplateNo(messageTemplate.getTemplateNo()); + dto.setTemplateNo(channelTemplate.getTemplateNo()); + dto.setTemplateMap(request.getParams()); + dto.setAppRequestNo(message.getRequestNo()); + dto.setRequestChannelNo(message.getMessageOrderNo()); + SendSmsCommonResponseDto response = smsSendManagerComposite.sendMessage(dto); + messageManager.updateToProcessing(response.getBizId(), response.getRequestId(), message.getId()); + } catch (BizException e) { + messageManager.updateToFail(message.getId()); + throw e; + } + } catch (Exception e) { + dingDingClient.notifySingleMessage(request.getTemplateNo(), request.getRequestNo(), e.getMessage()); + throw e; + } + } + + @Override + @MethodAroundLog(source = "Controller", target = "Service", value = "发送批量短信", requestExcludeName = {"smsContentDtos"}) + public void sendBatchMessage(SendBatchMessageRequestDto request) { + // 检查上游是否可调用 + checkAppCode(request.getAppCode()); + + // 过滤重复手机号 + List filterContentDtos = filterMobileRepeated(request); + + // 获取重复手机号条数 + int repeatNum = getRepeatedNum(request, filterContentDtos); + + // 查询并校验 + MessageTemplate messageTemplate = messageTemplateManager.queryAndCheckInnerTemplate(request.getTemplateNo()); + + // 验证请求参数 + if(messageTemplate.hasParam()) { + checkTemplateParam(request); + } + + // 保存批量短信请求 + BatchMessageRequest entity = saveBatchMessageRequest(request, filterContentDtos, repeatNum); + + // 是否允许发送批量消息 + if(YesNoEnum.NO.getCode().equals(enableSendBatchMessage)) { + // 更新批量消息请求为成功 + batchMessageRequestManger.updateRequestSuccess(CommonConstants.MOCK_CHANNEL, entity.getId()); + return; + } + + // 实时直接发送 MQ + if(BatchSendTypeEnum.isRealtime(request.getSendType())) { + sendToMQ(request); + } + } + + /** + * 设置消息成功,如果是验证码消息发送钉钉消息 + * @param request + * @param message + * @param template + */ + private void successMessageAndSendDingDing(SendMessageRequestDto request, + Message message, MessageTemplate template) { + message.setStatus(MessageStatusEnum.SUCCESS.getCode()); + message.setChannelCode(CommonConstants.MOCK_CHANNEL); + message.setChannelName(CommonConstants.MOCK_CHANNEL); + message.updateById(); + + String messageContent = parse(template.getTemplateContent(), request.getParams()); + dingDingClient.notifyMockMessage(request.getPhoneNo(), template.getTitle(), messageContent); + } + + /** + * 过滤重复手机号数据 + * @param request + */ + private List filterMobileRepeated(SendBatchMessageRequestDto request) { + List contentDtos = request.getSmsContentDtos(); + if(CollectionUtils.isEmpty(contentDtos)) { + throw new BizException(ReturnCodeEnum.INVALID_PARAMETER, "短信内容不能为空"); + } + return contentDtos.stream() + .filter(distinctByKey(dto -> dto.getPhoneNo())) + .collect(Collectors.toList()); + } + + /** + * 过滤函数 + * @param keyExtractor + * @param + * @return + */ + private Predicate distinctByKey(Function keyExtractor) { + Map seen = new ConcurrentHashMap<>(); + return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + } + + /** + * 获取重复手机号条数 + * @param request + * @param dtos + * @return + */ + private int getRepeatedNum(SendBatchMessageRequestDto request, List dtos) { + int sourceSize = request.getSmsContentDtos().size(); + int finalSize = dtos.size(); + return sourceSize - finalSize; + } + + /** + * 获取渠道路由条件 + * @param request + * @return + */ + private String getChannelRouteCondition(SendMessageRequestDto request) { + Map condition = new HashMap<>(16); + try { + JSONObject expansionJo = JSON.parseObject(request.getExpansion()); + String channelCode = expansionJo.getString(CommonConstants.ASSIGN_CHANNEL); + if(StringUtils.isNoneBlank(channelCode)) { + MessageChannelEnum messageChannelEnum = MessageChannelEnum.getByCode(channelCode); + if(messageChannelEnum != null) { + condition.put(CommonConstants.ASSIGN_CHANNEL, channelCode); + } + } + } catch (Exception e) { + // do nothing + } + return JSON.toJSONString(condition); + } + + /** + * 初始化重试表 + * @param message + * @return + */ + private MessageRedo initRedo(Message message) { + MessageRedo redo = new MessageRedo(); + redo.setAppNo(message.getAppNo()); + redo.setRequestNo(message.getRequestNo()); + redo.setMessageOrderNo(message.getMessageOrderNo()); + // 重试number由每次重试的时候生成 + redo.setRedoOrderNo(""); + redo.setMessageType(message.getMessageType()); + redo.setNotifyType(message.getNotifyType()); + redo.setStatus(MessageStatusEnum.EXCEPTION.getCode()); + redo.setChannelCode(message.getChannelCode()); + redo.setChannelName(message.getChannelName()); + redo.setTemplateNo(message.getTemplateNo()); + redo.setSubject(message.getSubject()); + redo.setTargetAddress(message.getTargetAddress()); + redo.setRetryingFlag(RetryingFlagEnum.Y.name()); + redo.setRetryCount(0); + redo.setNotifyRule(message.getNotifyRule()); + MessageContext messageContext = MessageContext.builder().retryCount(0) + .notifyRule(message.getNotifyRule()).build(); + Integer nextNotifySecond = retryStrategy.getNextNotifySecond(messageContext); + Date nextNotifyTime = DateUtils.plusSeconds(nextNotifySecond); + redo.setRetryAt(nextNotifyTime); + return redo; + } + + /** + * 初始化短信模板 + * + * @param request + * @param messageChannel + * @param messageTemplate + * @return + */ + private Message initMessage(SendMessageRequestDto request, + MessageChannel messageChannel, MessageTemplate messageTemplate) { + Message message = new Message(); + message.setAppNo(request.getAppCode()); + message.setRequestNo(request.getRequestNo()); + message.setBatchNo(request.getRequestNo()); + message.setMessageOrderNo(IdUtil.simpleUUID()); + message.setMessageType(MessageTypeEnum.S.name()); + message.setNotifyType(NotifyTypeEnum.REAL.name()); + message.setStatus(MessageStatusEnum.INIT.getCode()); + message.setChannelCode(messageChannel.getChannelCode()); + message.setChannelName(messageChannel.getChannelName()); + message.setTemplateNo(messageTemplate.getTemplateNo()); + // subject 不能为空 + message.setSubject(JSON.toJSONString(request.getParams())); + message.setTargetAddress(request.getPhoneNo()); + String notifyRule = retryStrategy.getRetryStrategy() + .stream().map(integer -> integer + "").collect(Collectors.joining(",")); + message.setNotifyRule(notifyRule); + message.setRemark(""); + return message; + } + + /** + * 检查appNo + * + * @param appCode + */ + private void checkAppCode(String appCode) { + MessageApp app = messageAppDao.queryByAppCode(appCode); + if (app == null) { + throw new BizException(ReturnCodeEnum.INVALID_PARAMETER,"调用失败, appNo校验失败"); + } + if (AvailableStatusEnum.NOT_AVAILABLE.getStatus().equals(app.getStatus())) { + throw new BizException(ReturnCodeEnum.INVALID_PARAMETER,"调用失败, appNo校验失败"); + } + } + + /** + * 是否跳过 + * @return + */ + private boolean shouldSkip(SendMessageRequestDto request){ + String cellphone = request.getPhoneNo(); + // 白名单包含 + if(checkCandidate(userCellphoneProperties.getWhitelist(), cellphone)) { + return false; + } + + // 黑名单包含 + if(checkCandidate(userCellphoneProperties.getBlacklist(), cellphone)) { + return true; + } + + // 生产环境 + if(isMaster()) { + return false; + } + + return true; + } + + /** + * 配置是否包含候选者 + * @param configList + * @param candidate + * @return + */ + private boolean checkCandidate(List configList, String candidate) { + if(CollectionUtils.isEmpty(configList)){ + return false; + } + Optional containCandidateOptional = configList.stream().filter(v -> v.equals(candidate)).findFirst(); + return containCandidateOptional.isPresent(); + } + + /** + * 检查短信模板参数 + * @param request + */ + private void checkTemplateParam(SendBatchMessageRequestDto request) { + List templateParams = messageTemplateManager.queryTemplateParam(request.getTemplateNo()); + BizException.error(CollectionUtils.isNotEmpty(templateParams), + ReturnCodeEnum.SYSTEM_ERROR, "变量模板参数名称列表未配置"); + + request.getSmsContentDtos().stream().forEach(content -> { + try { + JSONObject paramJo = JSON.parseObject(content.getTemplateParams()); + templateParams.stream() + .filter(param -> paramJo.get(param.getParamName()) != null) + .findAny() + .orElseThrow(() -> new BizException(ReturnCodeEnum.INVALID_PARAMETER, "手机号:" + content.getPhoneNo() + ",参数不合法")); + } catch (Exception e) { + throw new BizException(ReturnCodeEnum.INVALID_PARAMETER, e.getMessage()); + } + }); + } + + /** + * 保存批量短信请求 + * @param request + * @param filterContentDtos + * @param repeatNum + */ + private BatchMessageRequest saveBatchMessageRequest(SendBatchMessageRequestDto request, + List filterContentDtos, int repeatNum) { + BatchMessageRequest entity = new BatchMessageRequest(); + entity.setAppNo(request.getAppCode()); + entity.setRequestNo(request.getRequestNo()); + entity.setTemplateNo(request.getTemplateNo()); + entity.setSmsContent(JSON.toJSONString(filterContentDtos)); + entity.setTotalSize(request.getSmsContentDtos().size()); + entity.setRepeatCount(repeatNum); + entity.setSendType(request.getSendType()); + entity.setStatus(BatchMessageRequestStatusEnum.INITIALIZE.getCode()); + batchMessageRequestManger.saveBatchMessageRequest(entity); + return entity; + } + + /** + * 实时消息 MQ 处理 + * @param request + */ + private void sendToMQ(SendBatchMessageRequestDto request) { + BatchMessageSendContext context = new BatchMessageSendContext(); + context.setAppCode(request.getAppCode()); + context.setAppRequestNo(request.getRequestNo()); + context.setInnerTemplateNo(request.getTemplateNo()); + String messageKey = context.getMessageKey(); + log.info("MessageServiceImpl.sendBatchMessage request no {}", messageKey); + // remove rocketmq + } + + /** + * 是否生产环境 + * @return + */ + private boolean isMaster(){ + String[] activeProfiles = environment.getActiveProfiles(); + if(ArrayUtils.isEmpty(activeProfiles)) { + return false; + } + boolean isMaster = prodProfileString.equals(activeProfiles[0]); + if(isMaster) { + return true; + } else { + return YesNoEnum.YES.getCode().equals(enableSendSingleMessage); + } + } + + /** + * 解析短信模板 + * @param content + * @param params + * @return + */ + private String parse(String content, Map params) { + if(MapUtils.isEmpty(params)) { + return content; + } + try { + Map kvs = new HashMap<>(); + for (Entry paramEntry : params.entrySet()) { + String key = paramEntry.getKey(); + Object value = paramEntry.getValue(); + if(value != null) { + kvs.put(key, paramEntry.getValue().toString()); + } else { + kvs.put(key, ""); + } + } + Matcher m = CommonConstants.MESSAGE_TEMPLATE_PARAM_PATTERN.matcher(content); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String group = m.group().replace("${", "").replace("}", ""); + m.appendReplacement(sb, kvs.get(group)); + } + //把符合的数据追加到sb尾 + m.appendTail(sb); + return sb.toString(); + } catch (Exception e) { + LogUtil.error("MessageServiceImpl.parse is error", e); + return content; + } + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } +} diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/PlatServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/PlatServiceImpl.java new file mode 100644 index 00000000..c0b5022e --- /dev/null +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/PlatServiceImpl.java @@ -0,0 +1,215 @@ +package cn.axzo.msg.notices.service; + +import cn.axzo.msg.notices.common.enums.ChannelHandlerEnum; +import cn.axzo.msg.notices.common.enums.ReturnCodeEnum; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.dao.entity.ChannelMessageTemplate; +import cn.axzo.msg.notices.dao.entity.MessageApp; +import cn.axzo.msg.notices.dao.entity.MessageTemplate; +import cn.axzo.msg.notices.dao.mapper.ChannelMessageTemplateMapper; +import cn.axzo.msg.notices.dao.mapper.MessageAppMapper; +import cn.axzo.msg.notices.dao.mapper.MessageTemplateMapper; +import cn.axzo.msg.notices.manager.api.dto.request.plat.CreateTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.plat.QueryTemplateRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.plat.QueryTemplateResponseDto; +import cn.axzo.msg.notices.service.api.PlatService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service("platService") +public class PlatServiceImpl implements PlatService { + + @Resource + private ChannelMessageTemplateMapper channelMessageTemplateMapper; + + @Resource + private MessageTemplateMapper messageTemplateMapper; + + @Resource + private MessageAppMapper messageAppMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public void createTemplate(CreateTemplateRequestDto request) { + + checkCreateTemplate(request); + + insertMessageApp(request.getServiceName()); + + insertMessageTemplate(request); + + insertChannelMessageTemplate(request); + + } + + /** + * 插入app + */ + private void insertMessageApp(String serviceName) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(MessageApp::getAppCode, serviceName); + List messageApps = messageAppMapper.selectList(query); + if (CollectionUtils.isNotEmpty(messageApps)) { + return; + } + MessageApp messageApp = new MessageApp(); + messageApp.setAppCode(serviceName); + messageApp.setAppName(serviceName); + messageApp.setStatus(1); + messageAppMapper.insert(messageApp); + } + + /** + * 参数校验 + */ + private void checkCreateTemplate(CreateTemplateRequestDto request) { + if(request == null){ + throw new BizException(ReturnCodeEnum.FAIL,"参数不能为空"); + } + if(request.getServiceName() == null){ + throw new BizException(ReturnCodeEnum.FAIL,"服务名称不能为空"); + } + if(request.getMessageTemplateType() == null){ + throw new BizException(ReturnCodeEnum.FAIL,"模板类型不能为空"); + } + if(StringUtils.isBlank(request.getTemplateNo())){ + throw new BizException(ReturnCodeEnum.FAIL,"短信模板编码不能为空"); + } + if(StringUtils.isBlank(request.getTemplateAliNo())){ + throw new BizException(ReturnCodeEnum.FAIL,"阿里短信模板编码不能为空"); + } + if(StringUtils.isBlank(request.getTitle())){ + throw new BizException(ReturnCodeEnum.FAIL,"标题不能为空"); + } + if(StringUtils.isBlank(request.getTemplateContent())){ + throw new BizException(ReturnCodeEnum.FAIL,"模板内容不能为空"); + } + // 判断短信编码是否存在 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ChannelMessageTemplate::getChannelCode, ChannelHandlerEnum.ALI_YUN.getCode()); + queryWrapper.eq(ChannelMessageTemplate::getTemplateNo, request.getTemplateAliNo()); + queryWrapper.or().eq(ChannelMessageTemplate::getInnerTemplateNo, request.getTemplateNo()); + List list = channelMessageTemplateMapper.selectList(queryWrapper); + if(CollectionUtils.isNotEmpty(list)){ + ChannelMessageTemplate channelMessageTemplate = list.get(0); + String templateNo = channelMessageTemplate.getTemplateNo(); + String innerTemplateNo = channelMessageTemplate.getInnerTemplateNo(); + String templatNo = templateNo.equals(request.getTemplateAliNo()) ? templateNo : innerTemplateNo; + throw new BizException(ReturnCodeEnum.FAIL,"模板编码已存在:" + templatNo); + } + } + + /** + * 插入 MessageTemplate + */ + private void insertMessageTemplate(CreateTemplateRequestDto request) { + MessageTemplate messageTemplate = new MessageTemplate(); + messageTemplate.setTemplateNo(request.getTemplateNo()); + messageTemplate.setTitle(request.getTitle()); + messageTemplate.setType(request.getMessageTemplateType()); + messageTemplate.setTemplateContent(request.getTemplateContent()); + messageTemplate.setStatus(1); + messageTemplate.setHasParam(1); + messageTemplate.setReason(request.getTitle()); + messageTemplate.setRemark("短信模板统一入库-plat" + (StringUtils.isBlank(request.getRemark()) ? "" : ": " + request.getRemark())); + messageTemplateMapper.insert(messageTemplate); + } + + + /** + * 插入 ChannelMessageTemplate + */ + private void insertChannelMessageTemplate(CreateTemplateRequestDto request) { + ChannelMessageTemplate channelMessageTemplate = new ChannelMessageTemplate(); + channelMessageTemplate.setInnerTemplateNo(request.getTemplateNo()); + channelMessageTemplate.setTemplateNo(request.getTemplateAliNo()); + channelMessageTemplate.setChannelCode("aliyun"); + channelMessageTemplate.setChannelName("阿里云"); + channelMessageTemplate.setTitle(request.getTitle()); + channelMessageTemplate.setTemplateContent(request.getTemplateContent()); + channelMessageTemplate.setType(request.getMessageTemplateType()); + channelMessageTemplate.setStatus(1); + channelMessageTemplate.setHasParam(1); + channelMessageTemplate.setRemark("短信模板统一入库-plat" + (StringUtils.isBlank(request.getRemark()) ? "" : ": " + request.getRemark())); + channelMessageTemplate.setReason(request.getTitle()); + channelMessageTemplateMapper.insert(channelMessageTemplate); + } + + + @Override + public QueryTemplateResponseDto getByTemplateNo(String templateNo) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ChannelMessageTemplate::getInnerTemplateNo, templateNo); + queryWrapper.eq(ChannelMessageTemplate::getChannelCode, ChannelHandlerEnum.ALI_YUN.getCode()); + ChannelMessageTemplate channelMessageTemplate = channelMessageTemplateMapper.selectOne(queryWrapper); + return channelMessageTemplate == null ? null : QueryTemplateResponseDto.builder() + .id(channelMessageTemplate.getId()) + .messageTemplateStatus(channelMessageTemplate.getStatus()) + .messageTemplateType(channelMessageTemplate.getType()) + .reason(channelMessageTemplate.getReason()) + .remark(channelMessageTemplate.getRemark()) + .serviceName(channelMessageTemplate.getInnerTemplateNo().split("_")[0]) + .templateAliNo(channelMessageTemplate.getTemplateNo()) + .templateContent(channelMessageTemplate.getTemplateContent()) + .templateNo(channelMessageTemplate.getInnerTemplateNo()) + .title(channelMessageTemplate.getTitle()) + .build(); + } + + @Override + public Page list(QueryTemplateRequestDto request) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ChannelMessageTemplate::getChannelCode, ChannelHandlerEnum.ALI_YUN.getCode()); + queryWrapper.eq(request.getMessageTemplateType() != null, ChannelMessageTemplate::getType, request.getMessageTemplateType()); + queryWrapper.like(StringUtils.isNoneBlank(request.getServiceName()), ChannelMessageTemplate::getInnerTemplateNo, request.getServiceName()); + queryWrapper.like(StringUtils.isNoneBlank(request.getTemplateAliNo()), ChannelMessageTemplate::getTemplateNo, request.getTemplateAliNo()); + queryWrapper.like(StringUtils.isNoneBlank(request.getTemplateNo()), ChannelMessageTemplate::getInnerTemplateNo, request.getTemplateNo()); + queryWrapper.like(StringUtils.isNoneBlank(request.getTitle()), ChannelMessageTemplate::getTitle, request.getTitle()); + queryWrapper.orderByDesc(ChannelMessageTemplate::getCreateAt); + + com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(); + page.setCurrent(request.getPageNum()); + page.setSize(request.getPageSize()); + + com.baomidou.mybatisplus.extension.plugins.pagination.Page messagePage = channelMessageTemplateMapper.selectPage(page, queryWrapper); + + Page result = new Page<>(); + result.setPageNum(messagePage.getCurrent()); + result.setPageSize(messagePage.getSize()); + result.setTotalElements(messagePage.getTotal()); + result.setList(messagePage.getRecords().stream().map(data -> QueryTemplateResponseDto.builder() + .id(data.getId()) + .messageTemplateStatus(data.getStatus()) + .messageTemplateType(data.getType()) + .reason(data.getReason()) + .remark(data.getRemark()) + .serviceName(data.getInnerTemplateNo().split("_")[0]) + .templateAliNo(data.getTemplateNo()) + .templateContent(data.getTemplateContent()) + .templateNo(data.getInnerTemplateNo()) + .title(data.getTitle()) + .build()).collect(Collectors.toList())); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(String templateNo) { + if(StringUtils.isBlank(templateNo)){ + throw new BizException(ReturnCodeEnum.FAIL,"短信模板编码不能为空"); + } + messageTemplateMapper.deleteByTemplateNo(templateNo); + + channelMessageTemplateMapper.deleteByTemplateNo(templateNo); + } +} diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/TaskServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/TaskServiceImpl.java new file mode 100644 index 00000000..99d0c63e --- /dev/null +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/notices/service/TaskServiceImpl.java @@ -0,0 +1,424 @@ +package cn.axzo.msg.notices.service; + +import cn.axzo.msg.notices.common.domain.MessageContext; +import cn.axzo.msg.notices.common.enums.*; +import cn.axzo.msg.notices.common.exception.BizException; +import cn.axzo.msg.notices.common.lang.Page; +import cn.axzo.msg.notices.common.utils.DateUtils; +import cn.axzo.msg.notices.dao.entity.*; +import cn.axzo.msg.notices.dao.repository.ChannelMessageTemplateDao; +import cn.axzo.msg.notices.integration.client.AliYunSmsClient; +import cn.axzo.msg.notices.manager.api.*; +import cn.axzo.msg.notices.manager.api.dto.request.BatchMessageRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageQueryRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageRedoQueryRequestDto; +import cn.axzo.msg.notices.manager.api.dto.request.MessageSendRequestDto; +import cn.axzo.msg.notices.manager.api.dto.response.SendSmsCommonResponseDto; +import cn.axzo.msg.notices.service.api.TaskService; +import cn.azxo.framework.common.model.JobPageRequest; +import cn.azxo.framework.common.utils.LogUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 定时任务服务实现类 + * + * @author zhaoyong_sh + * @see TaskServiceImpl + * @since 2021-05-19 15:48 + */ +@Slf4j +@Service("taskService") +public class TaskServiceImpl implements TaskService { + + @Resource(name = "messageManager") + private MessageManager messageManager; + + @Resource(name = "messageRedoManger") + private MessageRedoManger messageRedoManger; + + @Resource(name = "aliYunSmsClient") + private AliYunSmsClient aliYunSmsClient; + + @Resource(name = "smsSendManagerComposite") + private SmsSendManager smsSendManagerComposite; + + @Resource(name = "retryStrategy") + private RetryStrategy retryStrategy; + + @Resource(name = "batchMessageRequestManger") + private BatchMessageRequestManger batchMessageRequestManger; + + @Resource(name = "batchMessageManger") + private BatchMessageManger batchMessageManger; + + @Resource(name = "channelMessageTemplateDao") + private ChannelMessageTemplateDao channelMessageTemplateDao; + + @Value("${realtime.batch.message.threshold.minutes:10}") + private Integer thresholdMinutes; + + @Override + public void aliYunProcessSendMessageException(JobPageRequest request) { + log.info("TaskServiceImpl#aliYunProcessSendMessageException request param is {}", JSON.toJSONString(request)); + MessageRedoQueryRequestDto requestDto = new MessageRedoQueryRequestDto(); + requestDto.setStartCreateTime(request.getStartTime()); + if(StringUtils.isNoneBlank(request.getReferenceNo())) { + requestDto.setId(Long.valueOf(request.getReferenceNo())); + } else { + requestDto.setChannelCode(MessageChannelEnum.ALIYUN.getCode()); + requestDto.setEndCreateTime(request.getEndTime()); + requestDto.setPageSize(request.getPageSize()); + requestDto.setStatuses(Lists.newArrayList(MessageStatusEnum.EXCEPTION.getCode())); + } + Page messagePage = messageRedoManger.queryPageByMessageRedoQueryRequestDto(requestDto); + if(messagePage == null) { + log.info("TaskServiceImpl.aliYunProcessSendMessageException result is null"); + return; + } + List redoMessages = messagePage.getList(); + + if(CollectionUtils.isEmpty(redoMessages)){ + log.info("TaskServiceImpl.aliYunProcessSendMessageException result size is null"); + return; + } + log.info("TaskServiceImpl.aliYunProcessSendMessageException result size is {}", redoMessages.size()); + log.info("短信发送异常重试列表-------{}",JSON.toJSONString(redoMessages)); + for (MessageRedo redoMessage : redoMessages) { + String dateFormat = DateUtil.format(redoMessage.getCreateAt(), DatePattern.PURE_DATE_PATTERN); + SendDetailsStatusEnum statusEnum = aliYunSmsClient + .queryExceptionSendDetails(redoMessage.getTargetAddress(), dateFormat, redoMessage.getMessageOrderNo()); + if(statusEnum != null) { + // 更新状态 + String messageStatus = SendDetailsStatusEnum.getMappingCode(statusEnum); + messageManager.updateExceptionToQueryStatus(messageStatus, redoMessage.getId()); + messageRedoManger.updateMessageRedoStatusById(redoMessage.getId(),MessageStatusEnum.EXCEPTION.getCode(),messageStatus); + } else { + // 锁定消息 + MessageContext context = MessageContext.builder().retryCount(redoMessage.getRetryCount()) + .notifyRule(redoMessage.getNotifyRule()).build(); + messageRedoManger.lockMessage(context, redoMessage.getId()); + + ChannelMessageTemplate channelMessageTemplate = channelMessageTemplateDao + .queryByTemplateNo(redoMessage.getTemplateNo(), redoMessage.getChannelCode()); + if (Objects.isNull(channelMessageTemplate)){ + LogUtil.error("短信重试渠道模板不存在--{}",JSON.toJSONString(redoMessage)); + continue; + } + // 发送消息 + String redoOrderNo = IdUtil.simpleUUID(); + log.info("当前发送短信的重试单号为===={}",redoOrderNo); + MessageSendRequestDto dto = new MessageSendRequestDto(); + dto.setAppCode(redoMessage.getAppNo()); + dto.setChannelCode(redoMessage.getChannelCode()); + dto.setPhoneNo(redoMessage.getTargetAddress()); + dto.setTemplateMap(JSON.parseObject(redoMessage.getSubject())); + dto.setAppRequestNo(redoMessage.getRequestNo()); + dto.setRequestChannelNo(redoOrderNo); + dto.setTemplateNo(channelMessageTemplate.getTemplateNo()); + try { + SendSmsCommonResponseDto sendSmsCommonResponseDto = smsSendManagerComposite.sendMessage(dto); + log.info("短信重试返回=========={}",JSON.toJSONString(sendSmsCommonResponseDto)); + if (Objects.nonNull(sendSmsCommonResponseDto)){ + messageRedoManger.updateMessageRedoChannelById(redoMessage.getId(),sendSmsCommonResponseDto.getBizId(),dto.getRequestChannelNo()); + } + } catch (BizException e) { + messageRedoManger.updateExceptionToFail(redoMessage.getId(), redoMessage.getRedoOrderNo()); + } catch (Exception e) { + // 获取下次重试秒数 + Integer nextNotifySecond = retryStrategy.getNextNotifySecond(context); + // 到达最大重试次数,更新消息为失败 + if(nextNotifySecond == null) { + messageRedoManger.updateExceptionToFail(redoMessage.getId(), redoMessage.getRedoOrderNo()); + } else { + Date retryAt = DateUtils.plusSeconds(nextNotifySecond); + messageRedoManger.updateRetry(retryAt, redoMessage.getId()); + } + } + } + } + + } + + @Override + public void aliYunMessageProcessingHandle(JobPageRequest request) { + log.info("TaskServiceImpl#aliYunMessageProcessingHandle request param is {}", JSON.toJSONString(request)); + MessageQueryRequestDto dto = new MessageQueryRequestDto(); + dto.setStartCreateTime(null); + if(StringUtils.isNoneBlank(request.getReferenceNo())) { + dto.setId(Long.valueOf(request.getReferenceNo())); + } else { + dto.setChannelCode(MessageChannelEnum.ALIYUN.getCode()); + dto.setStartCreateTime(request.getStartTime()); + dto.setEndCreateTime(request.getEndTime()); + dto.setPageSize(request.getPageSize()); + dto.setStatuses(Lists.newArrayList(MessageStatusEnum.PROCESSING.getCode())); + } + Page messagePage = messageManager.queryPageByMessageQueryRequestDto(dto); + if(messagePage == null) { + log.info("TaskServiceImpl.aliYunMessageProcessingHandle result is null"); + return; + } + List messages = messagePage.getList(); + + if(CollectionUtils.isEmpty(messages)){ + log.info("TaskServiceImpl.aliYunMessageProcessingHandle result size is null"); + return; + } + log.info("TaskServiceImpl.aliYunMessageProcessingHandle result size is {}", messages.size()); + for (Message message : messages) { + String dateFormat = DateUtil.format(message.getCreateAt(), DatePattern.PURE_DATE_PATTERN); + //查询短信状态 + SendDetailsStatusEnum statusEnum = aliYunSmsClient + .queryProcessingSendDetail(message.getTargetAddress(), dateFormat, message.getChannelBizId()); + String messageStatus; + if( Objects.isNull(statusEnum)) { + // 查询不到的更新状态为异常 + messageStatus = MessageStatusEnum.FAIL.getCode(); + }else{ + messageStatus = SendDetailsStatusEnum.getMappingCode(statusEnum); + //发送中的话,不做处理 + if (MessageStatusEnum.PROCESSING.getCode().equals(messageStatus)){ + continue; + } + } + // 更新状态 + messageManager.updateProcessingMessageStatusById(message.getId(),messageStatus); + } + + } + + @Override + public void batchMessageRequestSplitHandle(JobPageRequest request) { + log.info("TaskServiceImpl#batchMessageRequestSplitHandle request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageRequestStatusEnum.INITIALIZE.getCode(), BatchSendTypeEnum.NOT_REALTIME.getCode()); + log.info("TaskServiceImpl#batchMessageRequestSplitHandle request dto is {}", + JSON.toJSONString(dto)); + Page requestPage = batchMessageRequestManger + .queryPageByBatchMessageQueryRequestDto(dto); + if (requestPage == null || CollectionUtils + .isEmpty(requestPage.getList())) { + log.info("TaskServiceImpl.batchMessageRequestSplitHandle result is null"); + return; + } + List list = requestPage.getList(); + log.info("TaskServiceImpl.batchMessageRequestSplitHandle result size is {}", list.size()); + list.forEach(batchMessageRequest -> { + //拆分 batch_message_request 到 batch_message + log.info("TaskServiceImpl.batchMessageRequestSplitHandle 开始拆分 batchMessageRequest = {}", + JSON.toJSONString(batchMessageRequest)); + batchMessageRequestManger.batchMessageRequestSplitAndSave(batchMessageRequest); + + }); + } + + + @Override + public void batchMessageSendSplitHandle(JobPageRequest request) { + log.info("TaskServiceImpl#batchMessageSendSplitHandle request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageStatusEnum.INITIALIZE.getCode(), BatchSendTypeEnum.NOT_REALTIME.getCode()); + log.info("TaskServiceImpl#batchMessageSendSplitHandle request dto is {}", + JSON.toJSONString(dto)); + Page page = batchMessageManger.queryByPage(dto); + if (page == null || CollectionUtils + .isEmpty(page.getList())) { + log.info("TaskServiceImpl.batchMessageSendSplitHandle result is null"); + return; + } + List list = page.getList(); + log.info("TaskServiceImpl.batchMessageSendSplitHandle result size is {}", list.size()); + list.forEach(batchMessage -> { + //拆分批次保存到message和更新状态为拆分完成 + log.info("TaskServiceImpl.batchMessageSendSplitHandle 开始拆分 batchMessage = {}", + JSON.toJSONString(batchMessage)); + batchMessageManger.batchMessageSplitToMessage(batchMessage); + }); + + } + + @Override + public void batchSendMessage(JobPageRequest request) { + log.info("TaskServiceImpl#batchSendMessage request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageStatusEnum.SPLIT_COMPLETED.getCode(), BatchSendTypeEnum.NOT_REALTIME.getCode()); + log.info("TaskServiceImpl#batchSendMessage request dto is {}", + JSON.toJSONString(dto)); + Page page = batchMessageManger.queryByPage(dto); + if (page == null || CollectionUtils + .isEmpty(page.getList())) { + log.info("TaskServiceImpl.batchSendMessage result is null"); + return; + } + List list = page.getList(); + log.info("TaskServiceImpl.batchSendMessage result size is {}", list.size()); + list.forEach(batchMessage -> { + //发送短信、更新状态和回执单号 + log.info("TaskServiceImpl.batchSendMessage 开始才分批次 batchMessage = {}",batchMessage); + batchMessageManger.sendBatchMessageAndHandleReceipt(batchMessage); + }); + + } + + @Override + public void realBatchMessageRequestSplitCompensation(JobPageRequest request) { + log.info("TaskServiceImpl#realBatchMessageRequestSplitCompensation request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageRequestStatusEnum.INITIALIZE.getCode(), BatchSendTypeEnum.REALTIME.getCode()); + log.info("TaskServiceImpl#realBatchMessageRequestSplitCompensation request dto is {}", + JSON.toJSONString(dto)); + Page batchMessageRequestPage = batchMessageRequestManger + .queryPageByBatchMessageQueryRequestDto(dto); + if (batchMessageRequestPage == null || CollectionUtils + .isEmpty(batchMessageRequestPage.getList())) { + log.info("TaskServiceImpl.realBatchMessageRequestSplitCompensation result is null"); + return; + } + + batchMessageRequestPage.getList().stream() + .filter(v -> canCompensation(v.getCreateAt(), thresholdMinutes)) + .forEach(batchMessageRequest -> { + //拆分 batch_message_request 到 batch_message + log.info("TaskServiceImpl.realBatchMessageRequestSplitCompensation 开始拆分 batchMessageRequest = {}", + JSON.toJSONString(batchMessageRequest)); + + // 拆分短信 + List batchNos = batchMessageRequestManger.batchMessageRequestSplitAndSave(batchMessageRequest); + + // 消息幂等 + if(CollectionUtils.isEmpty(batchNos)) { + log.info("TaskServiceImpl.realBatchMessageRequestSplitCompensation is idempotent {}", + JSON.toJSONString(batchMessageRequest)); + return; + } + log.info("TaskServiceImpl.realBatchMessageRequestSplitCompensation size is {}", batchNos.size()); + + // remove rocketmq + }); + } + + @Override + public void realBatchMessageSplitCompensation(JobPageRequest request) { + log.info("TaskServiceImpl#realBatchMessageSplitCompensation request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageStatusEnum.INITIALIZE.getCode(), BatchSendTypeEnum.REALTIME.getCode()); + log.info("TaskServiceImpl#realBatchMessageSplitCompensation request dto is {}", + JSON.toJSONString(dto)); + Page page = batchMessageManger.queryByPage(dto); + if (page == null || CollectionUtils + .isEmpty(page.getList())) { + log.info("TaskServiceImpl.realBatchMessageSplitCompensation result is null"); + return; + } + List list = page.getList().stream() + .filter(v -> canCompensation(v.getCreateAt(), thresholdMinutes)) + .collect(Collectors.toList()); + log.info("TaskServiceImpl.realBatchMessageSplitCompensation size is {}", list.size()); + + list.forEach(message -> { + //拆分批次保存到message和更新状态为拆分完成 + log.info("TaskServiceImpl.realBatchMessageSplitCompensation 开始拆分 message = {}", + JSON.toJSONString(message)); + + // 批量消息拆分为 Message + boolean result = batchMessageManger.batchMessageSplitToMessage(message); + + if(!result) { + log.info("TaskServiceImpl.realBatchMessageSplitCompensation is idempotent {}", + JSON.toJSONString(message)); + return; + } + + // 发送渠道消息 + try { + batchMessageManger.sendBatchMessageAndHandleReceipt(message); + } catch (Exception e) { + // TODO 发送消息到钉钉 + LogUtil.error("TaskServiceImpl.realBatchMessageSplitCompensation send channel fail", e); + } + }); + } + + @Override + public void batchMessageRequestCountCompensation(JobPageRequest request) { + log.info("TaskServiceImpl#batchMessageRequestCountCompensation request param is {}", + JSON.toJSONString(request)); + BatchMessageRequestDto dto = buildBatchMessageRequestDto(request, + BatchMessageRequestStatusEnum.SPLIT_COMPLETED.getCode(), null); + + Page messagePage = batchMessageRequestManger + .queryPageByBatchMessageQueryRequestDto(dto); + if (messagePage == null || CollectionUtils + .isEmpty(messagePage.getList())) { + log.info("TaskServiceImpl.batchMessageRequestCountCompensation result is null"); + return; + } + + List list = messagePage.getList(); + log.info("TaskServiceImpl.batchMessageRequestCountCompensation result size is {}", list.size()); + + list.stream().filter(v -> canCompensation(v.getCreateAt(), thresholdMinutes * 3)) + .forEach(v -> { + log.info("TaskServiceImpl.batchMessageRequestCountCompensation request no is {}", v.getRequestNo()); + + batchMessageRequestManger.handleBatchMessageRequestStatistics(v); + }); + } + + /** + * 构建请求对象 + * @param request + * @param status + * @param sendType + * @return + */ + private BatchMessageRequestDto buildBatchMessageRequestDto(JobPageRequest request, + Integer status, Integer sendType) { + BatchMessageRequestDto dto = new BatchMessageRequestDto(); + if (StringUtils.isNoneBlank(request.getReferenceNo())) { + dto.setId(Long.valueOf(request.getReferenceNo())); + }else { + dto.setStartCreateTime(request.getStartTime()); + dto.setEndCreateTime(request.getEndTime()); + dto.setPageSize(request.getPageSize()); + dto.setStatuses(Lists.newArrayList(status)); + dto.setSendType(sendType); + } + return dto; + } + + /** + * 超过10分钟(默认)没有执行能够补偿 + * @param createAt + * @return + */ + private boolean canCompensation(Date createAt, int plusMinutes){ + DateTime createDateTime = new DateTime(createAt); + Date createAtPlusThresholdMinutes = createDateTime.plusMinutes(plusMinutes).toDate(); + Date currentTime = new Date(); + return createAtPlusThresholdMinutes.before(currentTime); + } + + +} diff --git a/message-notices/pom.xml b/msg-notices/pom.xml similarity index 61% rename from message-notices/pom.xml rename to msg-notices/pom.xml index ffd6df3f..da8f3e3e 100644 --- a/message-notices/pom.xml +++ b/msg-notices/pom.xml @@ -10,7 +10,19 @@ 4.0.0 - message-notices + msg-notices + pom + + msg-notices-client + msg-notices-common + msg-notices-dao + msg-notices-http-api + msg-notices-integration + msg-notices-manager + msg-notices-manager-api + msg-notices-service + msg-notices-service-api + 8 diff --git a/pom.xml b/pom.xml index 63477990..1b0660f9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ msg-center-api msg-center-webapi msg-center-common + msg-notices diff --git a/inside-notices/src/main/java/cn/axzo/msgcenter/Main.java b/wx-notices/src/main/java/cn/axzo/wx/notices/Main.java similarity index 80% rename from inside-notices/src/main/java/cn/axzo/msgcenter/Main.java rename to wx-notices/src/main/java/cn/axzo/wx/notices/Main.java index ab2d5480..1ff71c73 100644 --- a/inside-notices/src/main/java/cn/axzo/msgcenter/Main.java +++ b/wx-notices/src/main/java/cn/axzo/wx/notices/Main.java @@ -1,4 +1,4 @@ -package cn.axzo.msgcenter; +package cn.axzo.wx.notices; public class Main { public static void main(String[] args) {