Merge branch 'master' into feature/wx

This commit is contained in:
陈宁 2023-05-26 18:48:17 +08:00
commit aebfc317bd
244 changed files with 12359 additions and 8 deletions

View File

@ -2,7 +2,7 @@
# inside-notices
站内信消息通知模块
# message-notices
# msg-notices
短信消息通知模块
# wx-notices
微信消息通知模块

View File

@ -1,4 +1,4 @@
package cn.axzo.msgcenter;
package cn.axzo.inside.notices;
public class Main {
public static void main(String[] args) {

View File

@ -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");
}
}
}

View File

@ -1,4 +1,4 @@
package cn.axzo.msgcenter;
package cn.axzo.msg.center.webapi;
public class Main {
public static void main(String[] args) {

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>msg-notices</artifactId>
<groupId>cn.axzo.msgcenter</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.axzo.msg.notices.client</groupId>
<artifactId>msg-notices-client</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--<dependency>
<groupId>cn.axzo.mns</groupId>
<artifactId>mns-service</artifactId>
</dependency>-->
<dependency>
<groupId>cn.axzo.mns</groupId>
<artifactId>mns-http-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.framework</groupId>
<artifactId>axzo-logger-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.trade</groupId>
<artifactId>trade-data-security-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.msg.notices.service.api</groupId>
<artifactId>msg-notices-service-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.axzo.msg.notices.common</groupId>
<artifactId>msg-notices-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.axzo.msg.notices.integration</groupId>
<artifactId>msg-notices-integration</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>mns-client</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -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");
}
}

View File

@ -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 {
}

View File

@ -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) + "&timestamp=" + reqTimestamp;
log.info(msg);
String checkSign = SecureUtil.md5(msg);
log.info(checkSign);
if(!StringUtils.equals(checkSign, reqSign)){
throw new BizException(ReturnCodeEnum.FAIL,"验签失败");
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>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();
}
}

View File

@ -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());
}
}

View File

@ -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();
}
}

View File

@ -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";
}
}

View File

@ -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<AliMessageCallbackRequestDto> 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);
}
}

View File

@ -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("请联系管理员,批量发送短信功能已弃用");
}
}

View File

@ -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<Object> createTemplate(@RequestBody CreateTemplateRequestDto request){
platService.createTemplate(request);
return CommonResponse.success();
}
@RequestMapping("/getByTemplateNo")
public CommonResponse<QueryTemplateResponseDto> getByTemplateNo(String templateNo){
return CommonResponse.success(platService.getByTemplateNo(templateNo));
}
@PostMapping("/list")
public CommonResponse<Page<QueryTemplateResponseDto>> list(@RequestBody QueryTemplateRequestDto request){
return CommonResponse.success(platService.list(request));
}
@GetMapping("/delete")
public CommonResponse<Object> delete(String templateNo){
platService.delete(templateNo);
return CommonResponse.success();
}
}

View File

@ -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<SendBatchMessageRequest, SendBatchMessageRequestDto> {
@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<SmsContent> smsContents = source.getSmsContents();
if(CollectionUtils.isNotEmpty(smsContents)) {
List<SmsContentDto> 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;
}
}

View File

@ -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<SendMobileMessageRequest, SendMessageRequestDto> {
@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;
}
}

View File

@ -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());
}
}

View File

@ -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<? extends HttpMessageConverter<?>> converterType) {
return methodParameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> converterType) {
String simpleClassName = parameter.getDeclaringClass().getSimpleName();
String methodName = parameter.getMethod().getName();
log.info(simpleClassName + "#" + methodName + " request body is {}", JSON.toJSONString(body));
return body;
}
}

View File

@ -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;
}
}

View File

@ -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<T> {
/**
* 任务操作
* @return
*/
T doInExecute();
}

View File

@ -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> T execute(JobLoggerCallback<T> action){
String uuid = UUID.randomUUID().toString();
MDC.put(CommonConstants.CTX_LOG_ID_MDC, uuid);
try {
return action.doInExecute();
} finally {
MDC.clear();
}
}
}

View File

@ -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<String> execute(String param);
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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<String> 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;
});
}
}

View File

@ -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

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<configuration>
<!-- 导入安心筑全局日志配置 -->
<include resource="logback/logback-axzo.xml" />
<!-- 覆盖开发环境日志配置 -->
<springProfile name="local,dev">
<logger name="cn.axzo" level="DEBUG" />
</springProfile>
</configuration>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>msg-notices</artifactId>
<groupId>cn.axzo.msgcenter</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.axzo.msg.notices.common</groupId>
<artifactId>msg-notices-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.axzo.framework</groupId>
<artifactId>axzo-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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 {
}

View File

@ -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();
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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]+)(\\})");
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<ServiceContext> 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);
}
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Integer> {
/**
* 批量发送类型
*/
REALTIME(1, "实时"),
NOT_REALTIME(2, "非实时"),
;
private final Integer code;
private final String message;
public static boolean isRealtime(Integer code){
return REALTIME.getCode().equals(code);
}
}

View File

@ -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<String> {
/**
* 渠道对应处理类
*/
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;
}
}

View File

@ -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;
}

View File

@ -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<T> {
/**
* 枚举 code
* @return
*/
T getCode();
/**
* 枚举描述信息
* @return
*/
String getMessage();
}

View File

@ -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<Integer> {
/**
* 是否枚举类
*/
NO(0, "未删除"),
YES(1, "删除"),
;
private final Integer code;
private final String message;
}

View File

@ -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);
}
}

View File

@ -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<String> {
/**
* 消息渠道
*/
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;
}
}

View File

@ -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;
}

View File

@ -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
;
}

View File

@ -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<String> {
/**
* 短信发送类型
*/
SINGLE("SINGLE", "部分成功"),
BATCH("BATCH", "全部失败");
private final String code;
private final String message;
}

View File

@ -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<String> {
/**
* 消息状态枚举类
*/
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();
}
}

View File

@ -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<Integer> {
/**
* 发送短信状态
*/
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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Integer> {
/**
* 系统返回码枚举类
*/
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;
}

View File

@ -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<Long> {
/**
* 发送短信状态
*/
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");
}
}

View File

@ -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<Integer> {
/**
* 是否枚举类
*/
NO(0, ""),
YES(1, ""),
;
private final Integer code;
private final String message;
}

View File

@ -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);
}
}

View File

@ -0,0 +1,18 @@
package cn.axzo.msg.notices.common.lang;
/**
* 日志回调
*
* @author zhaoyong
* @see LoggerCallback
* @since 2021-08-06 18:40
*/
public interface LoggerCallback<T> {
/**
* 任务操作
* @return
*/
T doInExecute();
}

View File

@ -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<Object> {
@Override
public Object doInExecute() {
doInExecuteWithoutResult();
return null;
}
public abstract void doInExecuteWithoutResult();
}

View File

@ -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> T execute(LoggerCallback<T> 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();
}
}
}

View File

@ -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<T> implements Serializable {
/**
* 页码从第1页开始
*/
private Long pageNum;
/**
* 每页条数
*/
private Long pageSize;
/**
* 总记录数
*/
private Long totalElements;
/**
* 数据
*/
private List<T> list;
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>msg-notices</artifactId>
<groupId>cn.axzo.msgcenter</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.axzo.msg.notices.dao</groupId>
<artifactId>msg-notices-dao</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.axzo.msg.notices.common</groupId>
<artifactId>msg-notices-common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.trade</groupId>
<artifactId>trade-data-security-base</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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);
}
/**
* 包配置(生成的EntityXmlMapperControllerService存放的问题)
* @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<String, Object> map = new HashMap<String, Object>();
// map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
// this.setMap(map);
}
}.setFileOutConfigList(
Collections.<FileOutConfig>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();
}
}

View File

@ -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<BatchMessage> {
private Long id;
/**
* 状态
*/
private List<Integer> statuses;
/**
* 创建开始时间
*/
private Date startCreateTime;
/**
* 创建结束时间
*/
private Date endCreateTime;
/**
* 发送类型
*/
private Integer sendType;
}

View File

@ -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<BatchMessageRequest> {
private Long id;
/**
* 状态
*/
private List<Integer> statuses;
/**
* 创建开始时间
*/
private Date startCreateTime;
/**
* 创建结束时间
*/
private Date endCreateTime;
/**
* 发送方式
*/
private Integer sendType;
}

View File

@ -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;
}

View File

@ -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<Message> {
/**
* 主键
*/
private Long id;
/**
* 渠道码
*/
private String channelCode;
/**
* 状态
*/
private List<String> statuses;
/**
* 创建开始时间
*/
private Date startCreateTime;
/**
* 创建结束时间
*/
private Date endCreateTime;
}

View File

@ -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<MessageRedo> {
private Long id;
private String channelCode;
/**
* 状态
*/
private List<String> statuses;
/**
* 创建开始时间
*/
private Date startCreateTime;
/**
* 创建结束时间
*/
private Date endCreateTime;
}

View File

@ -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<T> extends Page<T> {
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;
}
}

View File

@ -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<T> {
/**
* 页码
*/
private int pageNum = 1;
/**
* 每页大小
*/
private int pageSize = 15;
public MyPage<T> toPage() {
return new MyPage<>(pageNum, pageSize);
}
}

View File

@ -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;
}

View File

@ -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;
/**
* <p>
* 渠道模板变量序列表
* </p>
*
* @author szg
* @since 2021-08-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("batch_message")
public class BatchMessage extends Model<BatchMessage> {
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;
}
}

View File

@ -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;
/**
* <p>
* 渠道模板变量序列表
* </p>
*
* @author szg
* @since 2021-08-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("batch_message_request")
public class BatchMessageRequest extends Model<BatchMessageRequest> {
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;
}
}

View File

@ -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;
/**
* <p>
* 渠道消息模板表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("channel_message_template")
public class ChannelMessageTemplate extends BaseOwnEntity<ChannelMessageTemplate> {
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);
}
}

View File

@ -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;
/**
* <p>
* 消息记录表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message")
public class Message extends BaseOwnEntity<Message> {
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;
}
}

View File

@ -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;
/**
* <p>
* 消息应用表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_app")
public class MessageApp extends BaseOwnEntity<MessageApp> {
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;
}
}

View File

@ -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;
/**
* <p>
* 消息渠道表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_channel")
public class MessageChannel extends BaseOwnEntity<MessageChannel> {
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;
}
}

View File

@ -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;
/**
* <p>
* 请求消息渠道日志表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_channel_log")
public class MessageChannelLog extends BaseOwnEntity<MessageChannelLog> {
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;
}
}

View File

@ -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;
/**
* <p>
* 消息重试表
* </p>
*
* @author szg
* @since 2021-05-27
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_redo")
public class MessageRedo extends BaseOwnEntity<MessageRedo> {
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;
}
}

View File

@ -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;
/**
* <p>
* 外部系统请求表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_request_log")
public class MessageRequestLog extends BaseOwnEntity<MessageRequestLog> {
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;
}
}

View File

@ -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;
/**
* <p>
* 内部消息模板表
* </p>
*
* @author zhaoyong
* @since 2021-05-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("message_template")
public class MessageTemplate extends BaseOwnEntity<MessageTemplate> {
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);
}
}

Some files were not shown because too many files have changed in this diff Show More