REQ-2874: 政务-添加高新区短信渠道

This commit is contained in:
yanglin 2024-08-16 09:23:13 +08:00
parent cf4e019789
commit 53340ab36f
25 changed files with 560 additions and 28 deletions

View File

@ -1,12 +1,19 @@
package cn.axzo.msg.center.message.controller;
import cn.axzo.msg.center.api.MNSNoticesApi;
import cn.axzo.msg.center.api.MessageAPIV3;
import cn.axzo.msg.center.api.request.AddMnsChannelRequest;
import cn.axzo.msg.center.api.request.MnsSendCodeV2Req;
import cn.axzo.msg.center.api.request.SendMessageRequestDto;
import cn.axzo.msg.center.api.request.UpdateMnsTemplateContentRequest;
import cn.axzo.msg.center.api.request.v3.MessageSendReqV3;
import cn.axzo.msg.center.api.request.v3.SearchMessageReqV3;
import cn.axzo.msg.center.api.request.v3.SearchPendingMessageReq;
import cn.axzo.msg.center.api.request.v3.SearchTodoLogReq;
import cn.axzo.msg.center.api.request.v3.SetImSendPriorityRequest;
import cn.axzo.msg.center.api.request.v3.UpdateMnsChannelTemplateRequest;
import cn.axzo.msg.center.dal.MNSMessageTemplateDao;
import cn.axzo.msg.center.domain.entity.MNSMessageTemplate;
import cn.axzo.msg.center.im.service.IMService;
import cn.axzo.msg.center.inside.notices.service.impl.TodoSearchService;
import cn.axzo.msg.center.inside.notices.service.impl.v3.MessageRecordServiceV3;
@ -15,9 +22,11 @@ import cn.axzo.msg.center.message.service.group.GroupTemplateService;
import cn.axzo.msg.center.message.service.impl.person.PersonService;
import cn.axzo.msg.center.message.service.todo.manage.TodoManager;
import cn.axzo.msg.center.message.xxl.MigrateOldMsgHotDataJob;
import cn.axzo.msg.center.notices.manager.api.MessageChannelRouter;
import cn.axzo.msg.center.notices.manager.api.MessageTemplateManager;
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.CreateTemplateRequestDto;
import cn.axzo.msg.center.notices.service.api.PlatService;
import cn.axzo.msg.center.service.pending.request.RevokeByTemplateCodeRequest;
import cn.axzo.trade.web.annotation.EnableResponseAdvice;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
@ -33,11 +42,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import javax.validation.Valid;
import java.util.Map;
@ -64,6 +68,9 @@ public class PrivateMessageController {
private final MessageTemplateManager messageTemplateManager;
private final PlatService platService;
private final ConfigurableEnvironment configurableEnvironment;
private final MNSNoticesApi mnsNoticesApi;
private final MessageChannelRouter messageChannelRouter;
private final MNSMessageTemplateDao mnsMessageTemplateDao;
@PostMapping("/sendPendingMessage")
@EnableResponseAdvice(enable = false)
@ -71,6 +78,12 @@ public class PrivateMessageController {
return todoManager.send(request);
}
@PostMapping("/revokeTodoByTemplateCode")
@EnableResponseAdvice(enable = false)
public Object revokeTodoByTemplateCode(@RequestBody @Valid RevokeByTemplateCodeRequest request) {
return todoManager.revokeByTemplateCode(request);
}
@PostMapping("/sendByEventMapping")
@EnableResponseAdvice(enable = false)
public Object sendByEventMapping(@RequestBody @Valid MessageSendReqV3 request) {
@ -161,6 +174,33 @@ public class PrivateMessageController {
return "created";
}
@PostMapping("/sendSms")
@EnableResponseAdvice(enable = false)
public Object sendSms(@RequestBody @Valid SendMessageRequestDto request) {
return mnsNoticesApi.sendMessage(request);
}
@PostMapping("/sendSmsCode")
@EnableResponseAdvice(enable = false)
public Object sendSmsCode(@RequestBody @Valid MnsSendCodeV2Req request) {
return mnsNoticesApi.sendCodeV2(request);
}
@PostMapping("/addMnsChannel")
@EnableResponseAdvice(enable = false)
public Object addMnsChannel(@RequestBody @Valid AddMnsChannelRequest request){
return messageChannelRouter.addChannel(request);
}
@PostMapping("/updateMnsTemplateContent")
@EnableResponseAdvice(enable = false)
public Object updateMnsTemplateContent(@RequestBody @Valid UpdateMnsTemplateContentRequest request) {
return mnsMessageTemplateDao.lambdaUpdate()
.eq(MNSMessageTemplate::getTemplateNo, request.getInnerTemplateCode())
.set(MNSMessageTemplate::getTemplateContent, request.getTemplateContent())
.update();
}
@PostMapping("/listMnsApps")
@EnableResponseAdvice(enable = false)
public Object listMnsApps(){

View File

@ -34,6 +34,7 @@ import cn.axzo.msg.center.service.pending.request.CompletePendingBySubCodeReques
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.CompletePendingMessageRequest;
import cn.axzo.msg.center.service.pending.request.PresetButtonPressedRequest;
import cn.axzo.msg.center.service.pending.request.RevokeByTemplateCodeRequest;
import cn.axzo.msg.center.service.pending.request.RevokePendingMessageByIdRequest;
import cn.axzo.msg.center.service.pending.request.SetHideRequest;
import cn.axzo.msg.center.service.pending.request.TodoHandoverRequest;
@ -441,6 +442,18 @@ public class TodoManager {
return true;
}
@Transactional(rollbackFor = Exception.class)
public boolean revokeByTemplateCode(RevokeByTemplateCodeRequest request) {
TodoRequestContext ctx = TodoRequestContext.create("revokeByTemplateCode", request);
StateAdvanceResult advanceResult = advanceState(ctx, execAdvanceBuilder()
.eq(Todo::getTemplateCode, request.getTemplateCode())
.set(Todo::getState, PendingMessageStateEnum.RETRACT));
if (!advanceResult.isAdvanced())
return false;
todoLogger.logTodoRevoked(ctx, advanceResult.getAdvancedTodos());
return true;
}
// !! update
/**

View File

@ -0,0 +1,12 @@
package cn.axzo.msg.center.api.request;
import lombok.Getter;
import lombok.Setter;
/**
* @author yanglin
*/
@Setter
@Getter
public class AddChannelTemplateRequest {
}

View File

@ -0,0 +1,30 @@
package cn.axzo.msg.center.api.request;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author yanglin
*/
@Setter
@Getter
public class AddMnsChannelRequest {
@NotBlank(message = "渠道名称不能为空")
private String channelCode;
@NotBlank(message = "渠道名称不能为空")
private String channelName;
@NotNull(message = "优先级不能为空")
private Integer priority;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -31,4 +31,9 @@ public class MnsSendCodeV2Req extends MnsMockReq {
private String appCode;
@NotBlank(message = "templateNo参数不参为空")
private String templateNo;
/**
* 扩展参数, {@link SendMessageRequestDto#getExpansion()}里面的作用一样
*/
private String expansion;
}

View File

@ -40,7 +40,13 @@ public class SendMessageRequestDto {
/** 短信模板变更 */
@NotNull(message = "params must not be null")
private Map<String, Object> params = new HashMap<>();
/** 扩展参数 */
/**
* 扩展参数.
* 指定渠道为高新政务: String expansion = "{\"assign_channel\": \"regulatory_gaoxin\"}";
* 不指定渠道时, 使用默认渠道 (当前为阿里云)
* <p/> 这个是很早之前就有的字段了, 不确定是否有其它人在使用, 因此保留为String类型
*/
private String expansion;
}

View File

@ -0,0 +1,21 @@
package cn.axzo.msg.center.api.request;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* @author yanglin
*/
@Setter
@Getter
public class UpdateMnsTemplateContentRequest {
@NotBlank(message = "模板编号不能为空")
private String innerTemplateCode;
@NotBlank(message = "模板内容不能为空")
private String templateContent;
}

View File

@ -0,0 +1,30 @@
package cn.axzo.msg.center.service.pending.request;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author yanglin
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RevokeByTemplateCodeRequest implements Serializable {
/**
* 模版编码
*/
private String templateCode;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -22,6 +22,7 @@ public enum ChannelHandlerEnum implements EnumBase<String> {
CHUANG_LAN("chuanglan", "chuangLanSmsSendManager", "创蓝"),
SUB_MAIL("sub_mail", "subMailSmsSendManager", "赛邮"),
LIAN_LU("lian_lu", "lianLuSmsSendManager", "联麓"),
REGULATORY_GAOXIN("regulatory_gaoxin", "regulatoryGaoxinManager", "监管机构: 高新")
;
private final String code;

View File

@ -21,6 +21,7 @@ public enum MessageChannelEnum implements EnumBase<String> {
CHUANG_LAN("chuanglan", "创蓝云智"),
SUB_MAIL("sub_mail", "赛邮"),
LIAN_LU("lian_lu", "联麓"),
REGULATORY_GAOXIN("regulatory_gaoxin", "监管机构: 高新")
;
private final String code;

View File

@ -27,6 +27,7 @@ public enum ReturnCodeEnum implements EnumBase<Integer> {
MESSAGE_TEMPLATE_NOT_EXIST(10003, "短信模板不存在"),
MESSAGE_CHANNEL_NOT_VALID(10004, "无可用消息渠道"),
MESSAGE_TEMPLATE_NOT_VALID(10005, "短信模板不可用"),
MESSAGE_CHANNEL_EXISTS(10006, "短信渠道已存在"),
;

View File

@ -0,0 +1,208 @@
package cn.axzo.msg.center.notices.integration.client.impl;
import cn.hutool.core.net.URLEncoder;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* 信息中心短信服务组件
*
* @author liuqibin@axzo.cn
* @date 2023-12-11
*/
@Log4j2
@RefreshScope
@Configuration
public class RegulatoryGaoxinClient {
/**
* 帐号
*/
@Value("${regulatory.sms.corpId}")
private String corpId;
/**
* 密码
*/
@Value("${regulatory.sms.pwd}")
private String pwd;
/**
* 短信签名
*/
@Value("${regulatory.sms.signName}")
private String signName;
/**
* 平台地址
*/
@Value("${regulatory.sms.url}")
private String url;
/**
* 直接根据短信内容进行发送
*
* @param phone 手机号
* @param content 短信内容
*/
public String send(String phone, String content) {
//参数判断
if (StrUtil.isBlank(phone) || StrUtil.isBlank(content)) {
log.warn("必要参数(手机号、内容)信息为空,无法执行短信发送");
return null;
}
//组装请求参数
String requestParam = this.createParam(
phone, content, StrUtil.EMPTY_JSON, Boolean.FALSE
);
//执行发送
return this.executeSend(requestParam);
}
/**
* 创建请求参数
*
* @param phone 手机号
* @param content 短信内容模板
* @param params json参数
* @return 请求参数
*/
private String createParam(String phone, String content, String params, Boolean formatContent) {
//格式化短信内容信息
if (BooleanUtil.isTrue(formatContent)) {
content = this.formatContent(content, params);
}
//添加签名并进行编码
String encodeContent = this.addSignAndEncodeContent(content);
if (StrUtil.isBlank(encodeContent)) {
log.warn("短信内容信息处理失败,无法进行参数组装操作");
return StrUtil.EMPTY;
}
//组装参数并返回
Map<String, String> param = Maps.newHashMap();
param.put("CorpID", corpId);
param.put("Pwd", pwd);
param.put("Mobile", phone);
param.put("Content", encodeContent);
return HttpUtil.toParams(param);
}
/**
* 执行发送
*
* @param param 参数
*/
private String executeSend(String param) {
try {
//构建url
String requestUrl = this.createUrl(param);
log.info("发送政务短信请求: {}", requestUrl);
//执行请求
String result = HttpUtil.post(
requestUrl, StrUtil.EMPTY_JSON
);
//打印发送结果
log.info("短信发送完成,本次执行短信发送的结果为:{}", result);
return result;
} catch (Exception e) {
log.error("执行短信发送出错,错误信息为:", e);
}
return null;
}
/**
* 构建请求链接信息
*
* @param params 请求参数
* @return 请求链接
*/
private String createUrl(String params) {
return url.concat("?")
.concat(params);
}
/**
* 格式化短信内容
*
* @param template 短信模板
* @param params json参数
* @return 短信内容
*/
private String formatContent(String template, String params) {
//转换为json
JSONObject parsed = JSON.parseObject(params);
//处理参数
String paramTag;
String key;
Object val;
for (Map.Entry<String, Object> entry : parsed.entrySet()) {
key = entry.getKey();
val = entry.getValue();
if (StrUtil.isBlank(key) || ObjectUtil.isNull(val)) {
return StrUtil.EMPTY;
}
paramTag = this.createParamTag(key);
if (StrUtil.isBlank(paramTag)) {
return StrUtil.EMPTY;
}
template = template.replaceAll(paramTag, String.valueOf(val));
}
//返回处理结果
return template;
}
/**
* 给短信内容添加签名并编码
* <p>
* 需要对内容使用GBK编码
* </p>
*
* @param content 短信内容
* @return 添加签名
*/
private String addSignAndEncodeContent(String content) {
if (StrUtil.isBlank(content)) {
return StrUtil.EMPTY;
}
return URLEncoder.ALL.encode(
content.concat(signName), CharsetUtil.CHARSET_GBK
);
}
/**
* 创建参数标识${param}
*
* @param paramName 参数名称
* @return 参数标识
*/
private String createParamTag(String paramName) {
if (StrUtil.isBlank(paramName)) {
return StrUtil.EMPTY;
}
return StrUtil.BACKSLASH.concat("$")
.concat(StrUtil.BACKSLASH).concat(StrUtil.DELIM_START)
.concat(paramName).concat(StrUtil.BACKSLASH)
.concat(StrUtil.DELIM_END);
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.notices.manager.api;
import cn.axzo.msg.center.api.request.AddMnsChannelRequest;
import cn.axzo.msg.center.domain.entity.MNSMessageChannel;
/**
@ -30,4 +31,5 @@ public interface MessageChannelRouter {
*/
MNSMessageChannel route(String condition, String innerTemplateCode);
String addChannel(AddMnsChannelRequest request);
}

View File

@ -1,5 +1,7 @@
package cn.axzo.msg.center.notices.manager.api.dto.request;
import cn.axzo.msg.center.domain.entity.MNSChannelMessageTemplate;
import cn.axzo.msg.center.domain.entity.MNSMessageTemplate;
import lombok.Data;
import java.util.Map;
@ -47,4 +49,17 @@ public class MessageSendRequestDto {
*/
private String requestChannelNo;
/**
* 短信模版
*/
private MNSMessageTemplate template;
/**
* 渠道模版信息
*/
private MNSChannelMessageTemplate channelTemplate;
/**
* 原始请求
*/
private MnsRequestDto request;
}

View File

@ -1,10 +1,12 @@
package cn.axzo.msg.center.notices.manager.api.dto.request;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
@ -51,6 +53,12 @@ public class MnsRequestDto {
private Object internalObj;
public JSONObject parseExpansion() {
if (StringUtils.isBlank(expansion))
return new JSONObject();
return JSON.parseObject(expansion);
}
public <T> T getInternalObj(Class<T> clazz) {
return clazz.isInstance(internalObj) ? clazz.cast(internalObj) : null;
}

View File

@ -21,12 +21,12 @@ public class CreateTemplateRequestDto {
/**
* 短信模板编码
*/
private String templateNo;
private String innerTemplateNo;
/**
* 阿里短信模板编码
*/
private String templateAliNo;
private String channelTemplateCode;
/**
* 标题
@ -42,4 +42,9 @@ public class CreateTemplateRequestDto {
* 模板原因
*/
private String remark;
/**
* 渠道
*/
private String channel;
}

View File

@ -20,6 +20,10 @@
</properties>
<dependencies>
<dependency>
<groupId>cn.axzo.msgcenter</groupId>
<artifactId>msg-center-common</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.notices.manager;
import cn.axzo.msg.center.api.request.AddMnsChannelRequest;
import cn.axzo.msg.center.dal.MNSMessageChannelDao;
import cn.axzo.msg.center.domain.entity.MNSMessageChannel;
import cn.axzo.msg.center.notices.common.constans.CommonConstants;
@ -16,7 +17,12 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
/**
* 消息渠道路由实现类
@ -73,6 +79,21 @@ public class MessageChannelRouteImpl implements MessageChannelRouter {
.orElse(null);
}
@Override
public String addChannel(AddMnsChannelRequest request) {
MNSMessageChannel savedChannel = mnsMessageChannelDao.lambdaQuery()
.eq(MNSMessageChannel::getChannelCode, request.getChannelCode())
.last("LIMIT 1")
.one();
BizException.error(savedChannel == null, ReturnCodeEnum.MESSAGE_CHANNEL_EXISTS);
MNSMessageChannel channel = new MNSMessageChannel();
channel.setChannelCode(request.getChannelCode());
channel.setChannelName(request.getChannelName());
channel.setPriority(request.getPriority());
mnsMessageChannelDao.save(channel);
return channel.getId() + "";
}
private String parseCondition(String condition) {
if (StringUtils.isEmpty(condition)) {
// 未指定渠道

View File

@ -0,0 +1,54 @@
package cn.axzo.msg.center.notices.manager;
import cn.axzo.msg.center.common.utils.PlaceholderResolver;
import cn.axzo.msg.center.notices.integration.client.impl.RegulatoryGaoxinClient;
import cn.axzo.msg.center.notices.manager.api.SmsSendManager;
import cn.axzo.msg.center.notices.manager.api.dto.request.BatchMessageSendRequestDto;
import cn.axzo.msg.center.notices.manager.api.dto.request.MessageSendRequestDto;
import cn.axzo.msg.center.notices.manager.api.dto.response.BatchMessageSendResponseDto;
import cn.axzo.msg.center.notices.manager.api.dto.response.SendSmsCommonResponseDto;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 政务系统
*
* @author yanglin
*/
@Slf4j
@RequiredArgsConstructor
@Service("regulatoryGaoxinManager")
public class RegulatoryGaoxinManager implements SmsSendManager {
private static final String USE_CHANNEL_CONTENT = "use_channel_content";
private final RegulatoryGaoxinClient regulatoryGaoxinClient;
@Override
public SendSmsCommonResponseDto sendMessage(MessageSendRequestDto request) {
log.info("[RegulatoryAuthorityManager#sendMessage] -> 政务 - 发送sms {}", JSON.toJSONString(request));
JSONObject expansion = request.getRequest().parseExpansion();
Boolean useChannelContent = expansion.getBoolean(USE_CHANNEL_CONTENT);
if (useChannelContent == null) useChannelContent = false;
String templateContent = useChannelContent
? request.getChannelTemplate().getTemplateContent()
: request.getTemplate().getTemplateContent();
String content = PlaceholderResolver.getDefaultResolver().resolveByMap(
templateContent, request.getTemplateMap());
String respStr = regulatoryGaoxinClient.send(request.getPhoneNo(), content);
SendSmsCommonResponseDto result = new SendSmsCommonResponseDto();
result.setBizId(respStr);
result.setRequestId("");
result.setMessage("");
return result;
}
@Override
public BatchMessageSendResponseDto sendBatchMessage(BatchMessageSendRequestDto requestDto) {
throw new UnsupportedOperationException();
}
}

View File

@ -69,6 +69,7 @@ public class SmsSendManagerComposite implements SmsSendManager, ApplicationConte
saveMessageChannelLog(request, e);
throw e;
} catch (Exception e) {
log.warn("SmsSendManagerComposite#sendMessage is Exception", e);
LogUtil.error("SmsSendManagerComposite#sendMessage is Exception", e);
// 保存渠道日志
saveMessageChannelLog(request, e.getMessage());

View File

@ -173,6 +173,9 @@ public class MessageServiceImpl implements MessageService, EnvironmentAware {
dto.setTemplateMap(request.getParams());
dto.setAppRequestNo(message.getRequestNo());
dto.setRequestChannelNo(message.getMessageOrderNo());
dto.setTemplate(messageTemplate);
dto.setChannelTemplate(channelTemplate);
dto.setRequest(request);
SendSmsCommonResponseDto response = smsSendManagerComposite.sendMessage(dto);
messageManager.updateToProcessing(response.getBizId(), response.getRequestId(), message.getId());
mnsLimiter.setSendSuccess(request);

View File

@ -52,8 +52,7 @@ public class PlatServiceImpl implements PlatService {
@Override
@Transactional(rollbackFor = Exception.class)
public void createTemplate(CreateTemplateRequestDto request) {
String remark = request.getRemark();
ChannelHandlerEnum channel = parseChannel(remark);
ChannelHandlerEnum channel = parseChannel(request.getChannel());
checkCreateTemplate(request, channel);
insertMessageApp(request.getServiceName());
@ -62,10 +61,13 @@ public class PlatServiceImpl implements PlatService {
insertChannelMessageTemplate(request, channel);
insertMessageTemplateParam(request.getTemplateAliNo(), request.getTemplateContent());
insertMessageTemplateParam(request.getChannelTemplateCode(), request.getTemplateContent());
}
private ChannelHandlerEnum parseChannel(String expStr) {
private ChannelHandlerEnum parseChannel(String channelCode) {
ChannelHandlerEnum channel = ChannelHandlerEnum.getByCode(channelCode);
if (channel != null)
return channel;
return ChannelHandlerEnum.ALI_YUN;
}
@ -99,11 +101,11 @@ public class PlatServiceImpl implements PlatService {
if (request.getMessageTemplateType() == null) {
throw new BizException(ReturnCodeEnum.FAIL, "模板类型不能为空");
}
if (StringUtils.isBlank(request.getTemplateNo())) {
throw new BizException(ReturnCodeEnum.FAIL, "短信模板编码不能为空");
if (StringUtils.isBlank(request.getInnerTemplateNo())) {
throw new BizException(ReturnCodeEnum.FAIL, "内部短信模板编码不能为空");
}
if (StringUtils.isBlank(request.getTemplateAliNo())) {
throw new BizException(ReturnCodeEnum.FAIL, "阿里短信模板编码不能为空");
if (StringUtils.isBlank(request.getChannelTemplateCode())) {
throw new BizException(ReturnCodeEnum.FAIL, "渠道短信模板编码不能为空");
}
if (StringUtils.isBlank(request.getTitle())) {
throw new BizException(ReturnCodeEnum.FAIL, "标题不能为空");
@ -114,15 +116,15 @@ public class PlatServiceImpl implements PlatService {
// 判断短信编码是否存在
LambdaQueryWrapper<MNSChannelMessageTemplate> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MNSChannelMessageTemplate::getChannelCode, channel.getCode());
queryWrapper.eq(MNSChannelMessageTemplate::getTemplateNo, request.getTemplateAliNo());
queryWrapper.eq(MNSChannelMessageTemplate::getTemplateNo, request.getChannelTemplateCode());
// 一个内部模板可以映射多个渠道商
queryWrapper.eq(MNSChannelMessageTemplate::getInnerTemplateNo, request.getTemplateNo());
queryWrapper.eq(MNSChannelMessageTemplate::getInnerTemplateNo, request.getInnerTemplateNo());
List<MNSChannelMessageTemplate> list = mnsChannelMessageTemplateMapper.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(list)) {
MNSChannelMessageTemplate channelMessageTemplate = list.get(0);
String templateNo = channelMessageTemplate.getTemplateNo();
String innerTemplateNo = channelMessageTemplate.getInnerTemplateNo();
String templatNo = templateNo.equals(request.getTemplateAliNo()) ? templateNo : innerTemplateNo;
String templatNo = templateNo.equals(request.getChannelTemplateCode()) ? templateNo : innerTemplateNo;
throw new BizException(ReturnCodeEnum.FAIL, "模板编码已存在:" + templatNo);
}
}
@ -132,14 +134,14 @@ public class PlatServiceImpl implements PlatService {
*/
private void insertMessageTemplate(CreateTemplateRequestDto request) {
LambdaQueryWrapper<MNSMessageTemplate> query = new LambdaQueryWrapper<>();
query.eq(MNSMessageTemplate::getTemplateNo, request.getTemplateNo())
query.eq(MNSMessageTemplate::getTemplateNo, request.getInnerTemplateNo())
.eq(MNSMessageTemplate::getIsDelete, YesNoEnum.NO.getCode());
List<MNSMessageTemplate> messageTemplates = mnsMessageTemplateMapper.selectList(query);
if (CollectionUtils.isNotEmpty(messageTemplates)) {
return;
}
MNSMessageTemplate messageTemplate = new MNSMessageTemplate();
messageTemplate.setTemplateNo(request.getTemplateNo());
messageTemplate.setTemplateNo(request.getInnerTemplateNo());
messageTemplate.setTitle(request.getTitle());
messageTemplate.setType(request.getMessageTemplateType());
messageTemplate.setTemplateContent(request.getTemplateContent());
@ -155,9 +157,15 @@ public class PlatServiceImpl implements PlatService {
* 插入 ChannelMessageTemplate
*/
private void insertChannelMessageTemplate(CreateTemplateRequestDto request, ChannelHandlerEnum channel) {
List<MNSChannelMessageTemplate> templates = mnsChannelMessageTemplateMapper.selectList(
query(MNSChannelMessageTemplate.class)
.eq(MNSChannelMessageTemplate::getChannelCode, channel.getCode())
.eq(MNSChannelMessageTemplate::getTemplateNo, request.getChannelTemplateCode())
.eq(MNSChannelMessageTemplate::getInnerTemplateNo, request.getInnerTemplateNo()));
if (CollectionUtils.isNotEmpty(templates)) return;
MNSChannelMessageTemplate channelMessageTemplate = new MNSChannelMessageTemplate();
channelMessageTemplate.setInnerTemplateNo(request.getTemplateNo());
channelMessageTemplate.setTemplateNo(request.getTemplateAliNo());
channelMessageTemplate.setInnerTemplateNo(request.getInnerTemplateNo());
channelMessageTemplate.setTemplateNo(request.getChannelTemplateCode());
channelMessageTemplate.setChannelCode(channel.getCode());
channelMessageTemplate.setChannelName(channel.getDesc());
channelMessageTemplate.setTitle(request.getTitle());

View File

@ -32,7 +32,6 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -75,7 +74,7 @@ public class SmsManager extends BaseManager implements SmsGateway {
* @return
*/
public int sendSmsCode(SendCodeV2Req req) {
sendMnsCode(req.getPhone(), req.getParam(), req.getAppCode(),req.getTemplateNo(), req.getCode());
sendMnsCode(req.getPhone(), req.getParam(), req.getAppCode(),req.getTemplateNo(), req.getCode(), req.getExpansion());
log.info("发送验证码 手机号{} -- 参数 {} -- 应用程序code {} -- 模板编号templateCode {}", req.getPhone(), req.getParam(), req.getAppCode(),req.getTemplateNo());
return req.getCode();
}
@ -183,7 +182,7 @@ public class SmsManager extends BaseManager implements SmsGateway {
}
}
public void sendMnsCode(String phoneNumber, Map<String, Object> param, String appCode, String templateNo, Integer code) {
public void sendMnsCode(String phoneNumber, Map<String, Object> param, String appCode, String templateNo, Integer code, String expansion) {
if (!isSendMnsCode) {
return;
}
@ -194,6 +193,7 @@ public class SmsManager extends BaseManager implements SmsGateway {
request.setParams(param);
request.setRequestNo(UUID.randomUUID().toString());
request.setInternalObj(MnsType.VERIFY_CODE);
request.setExpansion(expansion);
messageService.sendMessage(request);
}
}

View File

@ -1,5 +1,6 @@
package cn.axzo.msg.center.notices.service.request;
import cn.axzo.msg.center.api.request.SendMessageRequestDto;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -31,4 +32,9 @@ public class SendCodeV2Req extends MockReq {
private String appCode;
@NotBlank(message = "templateNo参数不参为空")
private String templateNo;
/**
* 扩展参数, {@link SendMessageRequestDto#getExpansion()}里面的作用一样
*/
private String expansion;
}

View File

@ -0,0 +1,37 @@
package cn.axzo.msg.center.api;
import cn.axzo.msg.center.MsgCenterApplication;
import cn.axzo.msg.center.api.request.MnsSendCodeV2Req;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author yanglin
*/
@SpringBootTest(classes = MsgCenterApplication.class)
@RequiredArgsConstructor(onConstructor_ = @Autowired)
class MNSNoticesApiTest {
private final MNSNoticesApi mNSNoticesApi;
@Test
void exec() {
HashMap<String, Object> param = new HashMap<>();
int code = 15;
param.put("code", code);
MnsSendCodeV2Req req = new MnsSendCodeV2Req();
req.setCode(code);
req.setAppCode("pudge");
req.setTemplateNo("pudge_100000031_regulatory");
req.setParam(param);
req.setPhone("18608045398");
mNSNoticesApi.sendCodeV2(req);
}
}