Merge branch 'refs/heads/feature/REQ-2874' into dev
This commit is contained in:
commit
a1eaced14c
@ -26,6 +26,7 @@ import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticForWork
|
||||
import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticRequest;
|
||||
import cn.axzo.msg.center.service.pending.request.PersonTodoToBeDoneStatRequest;
|
||||
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;
|
||||
@ -224,6 +225,12 @@ public class PendingMessageNewController implements PendingMessageClient {
|
||||
return CommonResponse.success(todoManager.revokeByBizCode(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<Boolean> revokeByTemplateCode(RevokeByTemplateCodeRequest param) {
|
||||
log.info("revokeByTemplateCode, request={}", JSON.toJSONString(param));
|
||||
return CommonResponse.success(todoManager.revokeByTemplateCode(param));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<Boolean> revokeById(RevokePendingMessageByIdRequest param) {
|
||||
log.info("revokeById, request={}", JSON.toJSONString(param));
|
||||
|
||||
@ -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;
|
||||
@ -14,10 +21,12 @@ import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
|
||||
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.AddMnsAppRequest;
|
||||
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;
|
||||
@ -53,12 +62,14 @@ public class PrivateMessageController {
|
||||
private final TodoSearchService todoSearchService;
|
||||
private final TodoManager todoManager;
|
||||
private final GroupTemplateService groupTemplateService;
|
||||
private final MigrateOldMsgHotDataJob migrateOldMsgHotDataJob;
|
||||
private final PersonService personService;
|
||||
private final IMService imService;
|
||||
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)
|
||||
@ -66,6 +77,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) {
|
||||
@ -127,35 +144,61 @@ public class PrivateMessageController {
|
||||
return new ObjectMapper(yamlFactory).writeValueAsString(map);
|
||||
}
|
||||
|
||||
@PostMapping("/migrateOldMsgHotData")
|
||||
@EnableResponseAdvice(enable = false)
|
||||
public Object migrateOldMsgHotData(
|
||||
@RequestBody(required = false) MigrateOldMsgHotDataJob.Param param) {
|
||||
migrateOldMsgHotDataJob.tryExecute(param, true);
|
||||
return "submitted";
|
||||
}
|
||||
|
||||
@PostMapping("/setImSendPriority")
|
||||
@EnableResponseAdvice(enable = false)
|
||||
public Object setImSendPriority(@RequestBody @Valid SetImSendPriorityRequest request) {
|
||||
return imService.setImSendPriority(request);
|
||||
}
|
||||
|
||||
@PostMapping("/updateMnsChannelTemplate")
|
||||
@PostMapping("/updateMnsChannelTemplateCode")
|
||||
@EnableResponseAdvice(enable = false)
|
||||
public Object updateMnsChannelTemplate(@RequestBody @Valid UpdateMnsChannelTemplateRequest request) {
|
||||
public Object updateMnsChannelTemplateCode(@RequestBody @Valid UpdateMnsChannelTemplateRequest request) {
|
||||
int size = messageTemplateManager.changeChannelTemplateCode(
|
||||
request.getChannelCode(), request.getSrcTemplateCode(), request.getDestTemplateCode());
|
||||
return String.format("updated templates: %d", size);
|
||||
}
|
||||
|
||||
@PostMapping("/addMnsApp")
|
||||
@EnableResponseAdvice(enable = false)
|
||||
public Object addMnsApp(@RequestBody @Valid AddMnsAppRequest request) {
|
||||
platService.addApp(request);
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@PostMapping("/createMnsTemplate")
|
||||
@EnableResponseAdvice(enable = false)
|
||||
public String createMnsTemplate(@RequestBody CreateTemplateRequestDto request){
|
||||
public String createMnsTemplate(@RequestBody @Valid CreateTemplateRequestDto request){
|
||||
platService.createTemplate(request);
|
||||
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(){
|
||||
|
||||
@ -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;
|
||||
@ -103,13 +104,13 @@ public class TodoManager {
|
||||
|
||||
public List<PushPendingMessageDTO> send(TodoRequestContext ctx, PendingMessagePushParam request) {
|
||||
// 10 seconds at most
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
try {
|
||||
return transactionTemplate.execute(unused -> sendImpl(ctx, request));
|
||||
} catch (DuplicateKeyException e) {
|
||||
log.info("Try to save todo but todo business already exists, request={}. " +
|
||||
"retryCount={}", request, i, e);
|
||||
Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
|
||||
Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
throw new ServiceException("服务器内部错误");
|
||||
@ -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
|
||||
|
||||
/**
|
||||
@ -622,6 +635,9 @@ public class TodoManager {
|
||||
|
||||
// !! advance state
|
||||
|
||||
/**
|
||||
* 如果有状态变化, 会发MQ通知以及触发工人终端重新拉待办
|
||||
*/
|
||||
private StateAdvanceResult advanceState(TodoRequestContext ctx, StateAdvanceBuilder builder) {
|
||||
Supplier<BusinessTodos> advanceFailLogger = () -> {
|
||||
// rerun no state query in case of race condition
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package cn.axzo.msg.center.api.request;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class AddChannelTemplateRequest {
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package cn.axzo.msg.center.api.request;
|
||||
|
||||
import cn.axzo.basics.common.util.AssertUtil;
|
||||
import cn.axzo.msg.center.service.enums.MnsChannel;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Slf4j
|
||||
@Setter
|
||||
@Getter
|
||||
public class ExpansionInfo {
|
||||
|
||||
/**
|
||||
* 扩展参数.
|
||||
* <p/> 这个是很早之前就有的字段了, 不确定是否有其它人在使用, 因此保留为String类型
|
||||
*/
|
||||
private String expansion;
|
||||
|
||||
/**
|
||||
* 指定短信发送渠道
|
||||
* <p/>不指定的情况下使用默认渠道, 当前为阿里云
|
||||
*/
|
||||
public void setChannel(MnsChannel channel) {
|
||||
AssertUtil.notNull(channel, "channel must not be null");
|
||||
addExpansion("assign_channel", channel.getCode());
|
||||
}
|
||||
|
||||
public void addExpansion(String key, Object value) {
|
||||
JSONObject obj = parseExpansion();
|
||||
obj.put(key, value);
|
||||
expansion = obj.toJSONString();
|
||||
}
|
||||
|
||||
public JSONObject parseExpansion() {
|
||||
JSONObject obj = null;
|
||||
if (StringUtils.isNotBlank(expansion)) {
|
||||
try {
|
||||
obj = JSONObject.parseObject(expansion);
|
||||
} catch (Exception e) {
|
||||
log.warn("parse expansion error, expansion={}", expansion, e);
|
||||
}
|
||||
}
|
||||
if (obj == null)
|
||||
obj = new JSONObject();
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
package cn.axzo.msg.center.api.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 类描述: mock
|
||||
*
|
||||
* @author zhangtianyu
|
||||
* @date 2022/2/17 5:12 PM
|
||||
**/
|
||||
@Data
|
||||
public class MnsMockReq {
|
||||
private boolean notMock = true;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package cn.axzo.msg.center.api.request;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@ -14,7 +15,7 @@ import java.util.HashMap;
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class MnsSendCodeV2Req extends MnsMockReq {
|
||||
public class MnsSendCodeV2Req extends ExpansionInfo {
|
||||
|
||||
/** 手机号 */
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
@ -31,4 +32,9 @@ public class MnsSendCodeV2Req extends MnsMockReq {
|
||||
private String appCode;
|
||||
@NotBlank(message = "templateNo参数不参为空")
|
||||
private String templateNo;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,9 @@ package cn.axzo.msg.center.api.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
@ -18,11 +19,11 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Data
|
||||
public class SendMessageRequestDto {
|
||||
@Setter
|
||||
@Getter
|
||||
public class SendMessageRequestDto extends ExpansionInfo {
|
||||
|
||||
/** 请求号 */
|
||||
@NotBlank(message = "request no must not be null")
|
||||
private String requestNo;
|
||||
|
||||
/** 应用接入码 */
|
||||
@ -40,7 +41,5 @@ public class SendMessageRequestDto {
|
||||
/** 短信模板变更 */
|
||||
@NotNull(message = "params must not be null")
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 扩展参数 */
|
||||
private String expansion;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package cn.axzo.msg.center.service.enums;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public enum MnsChannel {
|
||||
// 政务: 高新渠道. 政府渠道, 请勿随意使用
|
||||
REGULATORY_GAOXIN("regulatory_gaoxin"),
|
||||
// 阿里云 (当前默认)
|
||||
ALIYUN("aliyun")
|
||||
;
|
||||
|
||||
private final String code;
|
||||
}
|
||||
@ -17,6 +17,7 @@ import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticForWork
|
||||
import cn.axzo.msg.center.service.pending.request.PendingMessageStatisticRequest;
|
||||
import cn.axzo.msg.center.service.pending.request.PersonTodoToBeDoneStatRequest;
|
||||
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;
|
||||
@ -267,6 +268,12 @@ public interface PendingMessageClient {
|
||||
@PostMapping(value = "/pending-message/revoke/by-biz-code", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||
CommonResponse<Boolean> revokeByTemplateCodeBizCode(@RequestBody @Valid CompletePendingMessageRequest param);
|
||||
|
||||
/**
|
||||
* 通过待办模版撤回所有不是终态的待办
|
||||
*/
|
||||
@PostMapping(value = "/pending-message/revoke/by-template-code", produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||
CommonResponse<Boolean> revokeByTemplateCode(@RequestBody @Valid RevokeByTemplateCodeRequest param);
|
||||
|
||||
/**
|
||||
* 通过ID撤销代办
|
||||
*
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
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 javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class RevokeByTemplateCodeRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 模版编码
|
||||
*/
|
||||
@NotBlank(message = "templateCode is required")
|
||||
private String templateCode;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJSONString(this);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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, "短信渠道已存在"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
package cn.axzo.msg.center.notices.manager.api.dto.request;
|
||||
|
||||
import cn.axzo.msg.center.api.request.ExpansionInfo;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -16,8 +19,9 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Data
|
||||
public class MnsRequestDto {
|
||||
@Setter
|
||||
@Getter
|
||||
public class MnsRequestDto extends ExpansionInfo {
|
||||
|
||||
/**
|
||||
* 请求号
|
||||
@ -44,11 +48,6 @@ public class MnsRequestDto {
|
||||
*/
|
||||
private Map<String, Object> params;
|
||||
|
||||
/**
|
||||
* 扩展参数
|
||||
*/
|
||||
private String expansion;
|
||||
|
||||
private Object internalObj;
|
||||
|
||||
public <T> T getInternalObj(Class<T> clazz) {
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.msg.center.notices.manager.api.dto.request.plat;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class AddMnsAppRequest {
|
||||
@NotBlank(message = "appCode不能为空")
|
||||
private String appCode;
|
||||
@NotBlank(message = "remark不能为空")
|
||||
private String remark;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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)) {
|
||||
// 未指定渠道
|
||||
|
||||
@ -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("[RegulatoryGaoxinManager#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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
|
||||
@ -3,6 +3,7 @@ package cn.axzo.msg.center.notices.service.api;
|
||||
|
||||
import cn.axzo.msg.center.domain.entity.MNSMessageApp;
|
||||
import cn.axzo.msg.center.notices.common.lang.Page;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.AddMnsAppRequest;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.CreateTemplateRequestDto;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.QueryTemplateRequestDto;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.response.plat.QueryTemplateResponseDto;
|
||||
@ -34,4 +35,6 @@ public interface PlatService {
|
||||
void delete(String templateNo);
|
||||
|
||||
List<MNSMessageApp> listAllApps();
|
||||
|
||||
void addApp(AddMnsAppRequest request);
|
||||
}
|
||||
|
||||
@ -26,7 +26,9 @@ import cn.axzo.msg.center.notices.service.response.CodeStatusRes;
|
||||
import cn.axzo.msg.center.notices.service.response.SendCodeRes;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -64,6 +66,8 @@ public class MNSNoticesApiImpl implements MNSNoticesApi {
|
||||
BeanUtils.copyProperties(request, mnsRequestDto);
|
||||
log.info("request value={},mnsRequestDto value={}", JSONUtil.toJsonStr(request),JSONUtil.toJsonStr(mnsRequestDto));
|
||||
try {
|
||||
if (StringUtils.isBlank(mnsRequestDto.getRequestNo()))
|
||||
mnsRequestDto.setRequestNo(UuidUtils.generateUuid());
|
||||
mnsRequestDto.setInternalObj(MnsType.BIZ);
|
||||
messageService.sendMessage(mnsRequestDto);
|
||||
return CommonResponse.success();
|
||||
|
||||
@ -153,7 +153,7 @@ public class MessageServiceImpl implements MessageService, EnvironmentAware {
|
||||
messageManager.saveMessage(message);
|
||||
|
||||
// 如果模拟发短信成功,则直接设置状态并为成功
|
||||
if (shouldSkip(request)) {
|
||||
if (shouldSkip(request.getPhoneNo())) {
|
||||
successMessageAndSendDingDing(request, message, messageTemplate);
|
||||
return;
|
||||
}
|
||||
@ -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);
|
||||
@ -371,15 +374,14 @@ public class MessageServiceImpl implements MessageService, EnvironmentAware {
|
||||
* 是否跳过
|
||||
* @return
|
||||
*/
|
||||
private boolean shouldSkip(MnsRequestDto request){
|
||||
String cellphone = request.getPhoneNo();
|
||||
public boolean shouldSkip(String phone){
|
||||
// 白名单包含
|
||||
if(checkCandidate(userCellphoneProperties.getWhitelist(), cellphone)) {
|
||||
if(checkCandidate(userCellphoneProperties.getWhitelist(), phone)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 黑名单包含
|
||||
if(checkCandidate(userCellphoneProperties.getBlacklist(), cellphone)) {
|
||||
if(checkCandidate(userCellphoneProperties.getBlacklist(), phone)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ import cn.axzo.msg.center.notices.common.enums.ChannelHandlerEnum;
|
||||
import cn.axzo.msg.center.notices.common.enums.ReturnCodeEnum;
|
||||
import cn.axzo.msg.center.notices.common.exception.BizException;
|
||||
import cn.axzo.msg.center.notices.common.lang.Page;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.AddMnsAppRequest;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.CreateTemplateRequestDto;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.request.plat.QueryTemplateRequestDto;
|
||||
import cn.axzo.msg.center.notices.manager.api.dto.response.plat.QueryTemplateResponseDto;
|
||||
@ -52,8 +53,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 +62,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 +102,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 +117,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 +135,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 +158,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());
|
||||
@ -266,4 +275,20 @@ public class PlatServiceImpl implements PlatService {
|
||||
return mnsMessageAppMapper.selectList(query(MNSMessageApp.class).
|
||||
eq(MNSMessageApp::getIsDelete, TableIsDeleteEnum.NORMAL.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addApp(AddMnsAppRequest request) {
|
||||
LambdaQueryWrapper<MNSMessageApp> query = new LambdaQueryWrapper<>();
|
||||
query.eq(MNSMessageApp::getAppCode, request.getAppCode());
|
||||
List<MNSMessageApp> messageApps = mnsMessageAppMapper.selectList(query);
|
||||
if (CollectionUtils.isNotEmpty(messageApps)) {
|
||||
return;
|
||||
}
|
||||
MNSMessageApp messageApp = new MNSMessageApp();
|
||||
messageApp.setAppCode(request.getAppCode());
|
||||
messageApp.setAppName(request.getAppCode());
|
||||
messageApp.setRemark(request.getRemark());
|
||||
messageApp.setStatus(1);
|
||||
mnsMessageAppMapper.insert(messageApp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.msg.center.notices.service.impl;
|
||||
|
||||
import cn.axzo.basics.common.exception.ServiceException;
|
||||
import cn.axzo.msg.center.notices.manager.support.UserCellphoneProperties;
|
||||
import cn.axzo.msg.center.notices.service.SmsService;
|
||||
import cn.axzo.msg.center.notices.service.manager.SmsManager;
|
||||
import cn.axzo.msg.center.notices.service.request.CodeStatusReq;
|
||||
@ -9,22 +10,18 @@ import cn.axzo.msg.center.notices.service.response.CodeStatusRes;
|
||||
import cn.axzo.msg.center.notices.service.response.SendCodeRes;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RefreshScope
|
||||
public class SmsServiceImpl implements SmsService {
|
||||
|
||||
@Value("${phone.whites}")
|
||||
private List<String> phoneWrites;
|
||||
@Value("${phone.returnCode}")
|
||||
private Boolean returnCode;
|
||||
@Resource(name = "userCellphoneProperties")
|
||||
private UserCellphoneProperties userCellphoneProperties;
|
||||
@Resource
|
||||
private SmsManager smsManager;
|
||||
|
||||
@ -43,7 +40,7 @@ public class SmsServiceImpl implements SmsService {
|
||||
public CodeStatusRes getPhoneCodeStatus(CodeStatusReq req) {
|
||||
CodeStatusRes res = new CodeStatusRes();
|
||||
// 手机号再白名单中存在 则不验证
|
||||
if (phoneWrites.contains(req.getPhoneNumber())) {
|
||||
if (userCellphoneProperties.getWhitelist().contains(req.getPhoneNumber())) {
|
||||
return res;
|
||||
}
|
||||
Integer code = smsManager.getSmsCode(req.getPhoneNumber(), String.valueOf(req.getType()));
|
||||
|
||||
@ -27,12 +27,10 @@ import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.http.MethodType;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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;
|
||||
@ -58,24 +56,19 @@ public class SmsManager extends BaseManager implements SmsGateway {
|
||||
@Resource
|
||||
private MessageService messageService;
|
||||
|
||||
@Value("${phone.isSendMnsCode}")
|
||||
private boolean isSendMnsCode;
|
||||
|
||||
private static final HashMap<String,String> messageErrMsg = new HashMap<>();
|
||||
static {
|
||||
messageErrMsg.put("isv.MOBILE_NUMBER_ILLEGAL", "非法手机号");
|
||||
messageErrMsg.put("isv.DOMESTIC_NUMBER_NOT_SUPPORTED", "国际/港澳台不支持发送境内号码");
|
||||
}
|
||||
|
||||
public static final Integer SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* 发送验证码`
|
||||
* @param req
|
||||
* @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,10 +176,7 @@ public class SmsManager extends BaseManager implements SmsGateway {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMnsCode(String phoneNumber, Map<String, Object> param, String appCode, String templateNo, Integer code) {
|
||||
if (!isSendMnsCode) {
|
||||
return;
|
||||
}
|
||||
public void sendMnsCode(String phoneNumber, Map<String, Object> param, String appCode, String templateNo, Integer code, String expansion) {
|
||||
MnsRequestDto request = new MnsRequestDto();
|
||||
request.setAppCode(appCode);
|
||||
request.setPhoneNo(phoneNumber);
|
||||
@ -194,6 +184,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package cn.axzo.msg.center.notices.service.request;
|
||||
|
||||
import cn.axzo.msg.center.api.request.ExpansionInfo;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@ -14,7 +15,7 @@ import java.util.HashMap;
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SendCodeV2Req extends MockReq {
|
||||
public class SendCodeV2Req extends ExpansionInfo {
|
||||
|
||||
/** 手机号 */
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user