diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java index 49726e7e..ecb964fb 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PendingMessageNewController.java @@ -27,6 +27,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; @@ -231,6 +232,12 @@ public class PendingMessageNewController implements PendingMessageClient { return CommonResponse.success(todoManager.revokeByBizCode(param)); } + @Override + public CommonResponse revokeByTemplateCode(RevokeByTemplateCodeRequest param) { + log.info("revokeByTemplateCode, request={}", JSON.toJSONString(param)); + return CommonResponse.success(todoManager.revokeByTemplateCode(param)); + } + @Override public CommonResponse revokeById(RevokePendingMessageByIdRequest param) { log.info("revokeById, request={}", JSON.toJSONString(param)); diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PrivateMessageController.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PrivateMessageController.java index 57688605..ec96eb36 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PrivateMessageController.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/controller/PrivateMessageController.java @@ -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(){ diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java index 549e230d..5c54c8e7 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/impl/MessageTemplateRouterServiceImpl.java @@ -16,15 +16,6 @@ import cn.axzo.msg.center.service.enums.RouterCategoryEnum; import cn.axzo.msg.center.utils.UUIDUtil; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - import java.util.Collection; import java.util.Collections; import java.util.List; @@ -35,6 +26,14 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * @description diff --git a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java index a573cbe6..7f186e33 100644 --- a/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java +++ b/inside-notices/src/main/java/cn/axzo/msg/center/message/service/todo/manage/TodoManager.java @@ -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 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 advanceFailLogger = () -> { // rerun no state query in case of race condition diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddChannelTemplateRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddChannelTemplateRequest.java new file mode 100644 index 00000000..79ca1afc --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddChannelTemplateRequest.java @@ -0,0 +1,12 @@ +package cn.axzo.msg.center.api.request; + +import lombok.Getter; +import lombok.Setter; + +/** + * @author yanglin + */ +@Setter +@Getter +public class AddChannelTemplateRequest { +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddMnsChannelRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddMnsChannelRequest.java new file mode 100644 index 00000000..9e898343 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/AddMnsChannelRequest.java @@ -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); + } +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/ExpansionInfo.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/ExpansionInfo.java new file mode 100644 index 00000000..41b91457 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/ExpansionInfo.java @@ -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 { + + /** + * 扩展参数. + *

这个是很早之前就有的字段了, 不确定是否有其它人在使用, 因此保留为String类型 + */ + private String expansion; + + /** + * 指定短信发送渠道 + *

不指定的情况下使用默认渠道, 当前为阿里云 + */ + 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; + } + +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsMockReq.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsMockReq.java deleted file mode 100644 index 9fce66ef..00000000 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsMockReq.java +++ /dev/null @@ -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; -} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsSendCodeV2Req.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsSendCodeV2Req.java index 3c584ab8..d13d0014 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsSendCodeV2Req.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/MnsSendCodeV2Req.java @@ -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); + } } diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/SendMessageRequestDto.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/SendMessageRequestDto.java index 4deed8b2..953e803e 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/SendMessageRequestDto.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/SendMessageRequestDto.java @@ -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 params = new HashMap<>(); - /** 扩展参数 */ - private String expansion; -} +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/UpdateMnsTemplateContentRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/UpdateMnsTemplateContentRequest.java new file mode 100644 index 00000000..a6559137 --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/api/request/UpdateMnsTemplateContentRequest.java @@ -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; + +} diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MnsChannel.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MnsChannel.java new file mode 100644 index 00000000..b1453d7a --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/enums/MnsChannel.java @@ -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; +} \ No newline at end of file diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java index 73c84b75..2bdb9763 100644 --- a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/client/PendingMessageClient.java @@ -18,6 +18,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; @@ -271,6 +272,12 @@ public interface PendingMessageClient { @PostMapping(value = "/pending-message/revoke/by-biz-code", produces = {MediaType.APPLICATION_JSON_VALUE}) CommonResponse revokeByTemplateCodeBizCode(@RequestBody @Valid CompletePendingMessageRequest param); + /** + * 通过待办模版撤回所有不是终态的待办 + */ + @PostMapping(value = "/pending-message/revoke/by-template-code", produces = {MediaType.APPLICATION_JSON_VALUE}) + CommonResponse revokeByTemplateCode(@RequestBody @Valid RevokeByTemplateCodeRequest param); + /** * 通过ID撤销代办 * diff --git a/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/RevokeByTemplateCodeRequest.java b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/RevokeByTemplateCodeRequest.java new file mode 100644 index 00000000..7f31f51c --- /dev/null +++ b/msg-center-api/src/main/java/cn/axzo/msg/center/service/pending/request/RevokeByTemplateCodeRequest.java @@ -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); + } + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ChannelHandlerEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ChannelHandlerEnum.java index 541e6471..7bacd999 100644 --- a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ChannelHandlerEnum.java +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ChannelHandlerEnum.java @@ -22,6 +22,7 @@ public enum ChannelHandlerEnum implements EnumBase { CHUANG_LAN("chuanglan", "chuangLanSmsSendManager", "创蓝"), SUB_MAIL("sub_mail", "subMailSmsSendManager", "赛邮"), LIAN_LU("lian_lu", "lianLuSmsSendManager", "联麓"), + REGULATORY_GAOXIN("regulatory_gaoxin", "regulatoryGaoxinManager", "监管机构: 高新") ; private final String code; diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/MessageChannelEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/MessageChannelEnum.java index 8d853017..5de4be02 100644 --- a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/MessageChannelEnum.java +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/MessageChannelEnum.java @@ -21,6 +21,7 @@ public enum MessageChannelEnum implements EnumBase { CHUANG_LAN("chuanglan", "创蓝云智"), SUB_MAIL("sub_mail", "赛邮"), LIAN_LU("lian_lu", "联麓"), + REGULATORY_GAOXIN("regulatory_gaoxin", "监管机构: 高新") ; private final String code; diff --git a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ReturnCodeEnum.java b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ReturnCodeEnum.java index 1c6c65cf..452a7d54 100644 --- a/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ReturnCodeEnum.java +++ b/msg-notices/msg-notices-common/src/main/java/cn/axzo/msg/center/notices/common/enums/ReturnCodeEnum.java @@ -27,6 +27,7 @@ public enum ReturnCodeEnum implements EnumBase { MESSAGE_TEMPLATE_NOT_EXIST(10003, "短信模板不存在"), MESSAGE_CHANNEL_NOT_VALID(10004, "无可用消息渠道"), MESSAGE_TEMPLATE_NOT_VALID(10005, "短信模板不可用"), + MESSAGE_CHANNEL_EXISTS(10006, "短信渠道已存在"), ; diff --git a/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/center/notices/integration/client/impl/RegulatoryGaoxinClient.java b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/center/notices/integration/client/impl/RegulatoryGaoxinClient.java new file mode 100644 index 00000000..b186aa06 --- /dev/null +++ b/msg-notices/msg-notices-integration/src/main/java/cn/axzo/msg/center/notices/integration/client/impl/RegulatoryGaoxinClient.java @@ -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 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 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; + } + + /** + * 给短信内容添加签名并编码 + *

+ * 需要对内容使用GBK编码 + *

+ * + * @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); + } +} \ No newline at end of file diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/MessageChannelRouter.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/MessageChannelRouter.java index 63a958df..97602dee 100644 --- a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/MessageChannelRouter.java +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/MessageChannelRouter.java @@ -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); } diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MessageSendRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MessageSendRequestDto.java index 8da6abbd..04e6d93a 100644 --- a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MessageSendRequestDto.java +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MessageSendRequestDto.java @@ -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; } diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MnsRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MnsRequestDto.java index a51cf27f..38eae300 100644 --- a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MnsRequestDto.java +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/MnsRequestDto.java @@ -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 params; - /** - * 扩展参数 - */ - private String expansion; - private Object internalObj; public T getInternalObj(Class clazz) { diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/AddMnsAppRequest.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/AddMnsAppRequest.java new file mode 100644 index 00000000..7d63d934 --- /dev/null +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/AddMnsAppRequest.java @@ -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; +} diff --git a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java index 4dcde9f4..0e7ac8d7 100644 --- a/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java +++ b/msg-notices/msg-notices-manager-api/src/main/java/cn/axzo/msg/center/notices/manager/api/dto/request/plat/CreateTemplateRequestDto.java @@ -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; } diff --git a/msg-notices/msg-notices-manager/pom.xml b/msg-notices/msg-notices-manager/pom.xml index fe154d9e..bf2c1a96 100644 --- a/msg-notices/msg-notices-manager/pom.xml +++ b/msg-notices/msg-notices-manager/pom.xml @@ -20,6 +20,10 @@ + + cn.axzo.msgcenter + msg-center-common + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/MessageChannelRouteImpl.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/MessageChannelRouteImpl.java index 1db29a35..e71c03e8 100644 --- a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/MessageChannelRouteImpl.java +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/MessageChannelRouteImpl.java @@ -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)) { // 未指定渠道 diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/RegulatoryGaoxinManager.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/RegulatoryGaoxinManager.java new file mode 100644 index 00000000..2bb6b2ed --- /dev/null +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/RegulatoryGaoxinManager.java @@ -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(); + } + +} \ No newline at end of file diff --git a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/SmsSendManagerComposite.java b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/SmsSendManagerComposite.java index 88c6bb9e..a25bf387 100644 --- a/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/SmsSendManagerComposite.java +++ b/msg-notices/msg-notices-manager/src/main/java/cn/axzo/msg/center/notices/manager/SmsSendManagerComposite.java @@ -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()); diff --git a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/center/notices/service/api/PlatService.java b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/center/notices/service/api/PlatService.java index b6e27f79..51265f2d 100644 --- a/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/center/notices/service/api/PlatService.java +++ b/msg-notices/msg-notices-service-api/src/main/java/cn/axzo/msg/center/notices/service/api/PlatService.java @@ -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 listAllApps(); + + void addApp(AddMnsAppRequest request); } diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MNSNoticesApiImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MNSNoticesApiImpl.java index 1d2f0b43..d647dfa2 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MNSNoticesApiImpl.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MNSNoticesApiImpl.java @@ -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(); diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MessageServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MessageServiceImpl.java index 7687dd31..726b12b5 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MessageServiceImpl.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/MessageServiceImpl.java @@ -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; } diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java index 444a93a7..8f3b0518 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/PlatServiceImpl.java @@ -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 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 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 query = new LambdaQueryWrapper<>(); - query.eq(MNSMessageTemplate::getTemplateNo, request.getTemplateNo()) + query.eq(MNSMessageTemplate::getTemplateNo, request.getInnerTemplateNo()) .eq(MNSMessageTemplate::getIsDelete, YesNoEnum.NO.getCode()); List 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 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 query = new LambdaQueryWrapper<>(); + query.eq(MNSMessageApp::getAppCode, request.getAppCode()); + List 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); + } } diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/SmsServiceImpl.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/SmsServiceImpl.java index 493e0dc4..bc01278f 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/SmsServiceImpl.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/impl/SmsServiceImpl.java @@ -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 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())); diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/manager/SmsManager.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/manager/SmsManager.java index eb91fb3a..26732fa7 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/manager/SmsManager.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/manager/SmsManager.java @@ -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 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 param, String appCode, String templateNo, Integer code) { - if (!isSendMnsCode) { - return; - } + public void sendMnsCode(String phoneNumber, Map 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); } } diff --git a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/request/SendCodeV2Req.java b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/request/SendCodeV2Req.java index 4521e141..3ba9aead 100644 --- a/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/request/SendCodeV2Req.java +++ b/msg-notices/msg-notices-service/src/main/java/cn/axzo/msg/center/notices/service/request/SendCodeV2Req.java @@ -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 = "手机号不能为空") diff --git a/start/src/test/java/cn/axzo/msg/center/api/MNSNoticesApiTest.java b/start/src/test/java/cn/axzo/msg/center/api/MNSNoticesApiTest.java new file mode 100644 index 00000000..192de9ac --- /dev/null +++ b/start/src/test/java/cn/axzo/msg/center/api/MNSNoticesApiTest.java @@ -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 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); + } + +} \ No newline at end of file