diff --git a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java index 5f3c807..664ff07 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java +++ b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java @@ -73,4 +73,11 @@ public class SendAccountConstant { public static final String SMS_PREFIX = "sms_"; + /** + * 短信账号code + */ + public static final Integer TENCENT_SMS_CODE = 10; + public static final Integer YUN_PIAN_SMS_CODE = 20; + + } diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/account/YunPianSmsAccount.java b/austin-common/src/main/java/com/java3y/austin/common/dto/account/YunPianSmsAccount.java new file mode 100644 index 0000000..361fe3c --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/account/YunPianSmsAccount.java @@ -0,0 +1,45 @@ +package com.java3y.austin.common.dto.account; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 云片账号信息 + * + * 参数示例: + * [{"sms_20":{"url":"https://sms.yunpian.com/v2/sms/tpl_batch_send.json","apikey":"ca55d4c8544444444444622221b5cd7","tpl_id":"533332222282","supplierId":20,"supplierName":"云片"}}] + * + * @author 3y + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class YunPianSmsAccount { + + /** + * apikey + */ + private String apikey; + /** + * tplId + */ + private String tplId; + + /** + * api相关 + */ + private String url; + + /** + * 标识渠道商Id + */ + private Integer supplierId; + + /** + * 标识渠道商名字 + */ + private String supplierName; +} diff --git a/austin-common/src/main/java/com/java3y/austin/common/enums/SmsStatus.java b/austin-common/src/main/java/com/java3y/austin/common/enums/SmsStatus.java index 285280c..8bbdf67 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/enums/SmsStatus.java +++ b/austin-common/src/main/java/com/java3y/austin/common/enums/SmsStatus.java @@ -15,7 +15,8 @@ public enum SmsStatus { SEND_SUCCESS(10,"调用渠道接口发送成功"), RECEIVE_SUCCESS(20,"用户收到短信(收到渠道短信回执,状态成功)"), - RECEIVE_FAIL(30, "用户收不到短信(收到渠道短信回执,状态失败)"); + RECEIVE_FAIL(30, "用户收不到短信(收到渠道短信回执,状态失败)"), + SEND_FAIL(40, "调用渠道接口发送失败"); private Integer code; private String description; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/MessageTypeSmsConfig.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/MessageTypeSmsConfig.java new file mode 100644 index 0000000..d831854 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/MessageTypeSmsConfig.java @@ -0,0 +1,30 @@ +package com.java3y.austin.handler.domain.sms; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 对于每种消息类型的 短信配置 + * + * @author 3y + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MessageTypeSmsConfig { + + /** + * 权重(决定着流量的占比) + */ + private Integer weights; + + /** + * script名称 + */ + private String scriptName; + +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/SmsParam.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/SmsParam.java index bcf9f1e..74eee4f 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/SmsParam.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/SmsParam.java @@ -28,10 +28,4 @@ public class SmsParam { * 发送文案 */ private String content; - - /** - * 发送账号 - */ - private Integer sendAccount; - } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/YunPianSendResult.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/YunPianSendResult.java new file mode 100644 index 0000000..61c5bcf --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/sms/YunPianSendResult.java @@ -0,0 +1,81 @@ +package com.java3y.austin.handler.domain.sms; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@NoArgsConstructor +@Data +public class YunPianSendResult { + + /** + * totalCount + */ + @JSONField(name = "total_count") + private Integer totalCount; + /** + * totalFee + */ + @JSONField(name = "total_fee") + private String totalFee; + /** + * unit + */ + @JSONField(name = "unit") + private String unit; + /** + * data + */ + @JSONField(name = "data") + private List data; + + /** + * DataDTO + */ + @NoArgsConstructor + @Data + public static class DataDTO { + /** + * httpStatusCode + */ + @JSONField(name = "http_status_code") + private Integer httpStatusCode; + /** + * code + */ + @JSONField(name = "code") + private Integer code; + /** + * msg + */ + @JSONField(name = "msg") + private String msg; + /** + * count + */ + @JSONField(name = "count") + private Integer count; + /** + * fee + */ + @JSONField(name = "fee") + private Integer fee; + /** + * unit + */ + @JSONField(name = "unit") + private String unit; + /** + * mobile + */ + @JSONField(name = "mobile") + private String mobile; + /** + * sid + */ + @JSONField(name = "sid") + private String sid; + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java index 013fd15..f02044a 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java @@ -4,14 +4,11 @@ import com.alibaba.fastjson.JSON; import com.google.common.base.Throwables; import com.java3y.austin.common.domain.TaskInfo; import com.java3y.austin.common.dto.model.MiniProgramContentModel; -import com.java3y.austin.common.dto.model.OfficialAccountsContentModel; import com.java3y.austin.common.enums.ChannelType; import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; -import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import com.java3y.austin.handler.handler.BaseHandler; import com.java3y.austin.handler.handler.Handler; -import com.java3y.austin.handler.script.MiniProgramAccountService; -import com.java3y.austin.handler.script.OfficialAccountService; +import com.java3y.austin.handler.wechat.MiniProgramAccountService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java index 7e6707b..1246043 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java @@ -8,7 +8,7 @@ import com.java3y.austin.common.enums.ChannelType; import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import com.java3y.austin.handler.handler.BaseHandler; import com.java3y.austin.handler.handler.Handler; -import com.java3y.austin.handler.script.OfficialAccountService; +import com.java3y.austin.handler.wechat.OfficialAccountService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/SmsHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/SmsHandler.java index e833a3e..a3fb691 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/SmsHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/SmsHandler.java @@ -3,14 +3,19 @@ package com.java3y.austin.handler.handler.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.ctrip.framework.apollo.Config; +import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; import com.google.common.base.Throwables; +import com.java3y.austin.common.constant.AustinConstant; import com.java3y.austin.common.domain.TaskInfo; import com.java3y.austin.common.dto.model.SmsContentModel; import com.java3y.austin.common.enums.ChannelType; +import com.java3y.austin.handler.domain.sms.MessageTypeSmsConfig; import com.java3y.austin.handler.domain.sms.SmsParam; import com.java3y.austin.handler.handler.BaseHandler; import com.java3y.austin.handler.handler.Handler; -import com.java3y.austin.handler.script.SmsScript; +import com.java3y.austin.handler.script.SmsScriptHolder; import com.java3y.austin.support.dao.SmsRecordDao; import com.java3y.austin.support.domain.SmsRecord; import lombok.extern.slf4j.Slf4j; @@ -18,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Random; /** * 短信发送处理 @@ -36,7 +42,10 @@ public class SmsHandler extends BaseHandler implements Handler { private SmsRecordDao smsRecordDao; @Autowired - private SmsScript smsScript; + private SmsScriptHolder smsScriptHolder; + + @ApolloConfig("boss.austin") + private Config config; @Override @@ -45,14 +54,20 @@ public class SmsHandler extends BaseHandler implements Handler { .phones(taskInfo.getReceiver()) .content(getSmsContent(taskInfo)) .messageTemplateId(taskInfo.getMessageTemplateId()) - .sendAccount(taskInfo.getSendAccount()) .build(); try { - List recordList = smsScript.send(smsParam); - if (!CollUtil.isEmpty(recordList)) { - smsRecordDao.saveAll(recordList); + /** + * 1、动态配置做流量负载 + * 2、发送短信 + */ + MessageTypeSmsConfig[] messageTypeSmsConfigs = loadBalance(getMessageTypeSmsConfig(taskInfo.getMsgType())); + for (MessageTypeSmsConfig messageTypeSmsConfig : messageTypeSmsConfigs) { + List recordList = smsScriptHolder.route(messageTypeSmsConfig.getScriptName()).send(smsParam); + if (CollUtil.isNotEmpty(recordList)) { + smsRecordDao.saveAll(recordList); + return true; + } } - return true; } catch (Exception e) { log.error("SmsHandler#handler fail:{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam)); @@ -60,6 +75,71 @@ public class SmsHandler extends BaseHandler implements Handler { return false; } + /** + * 流量负载 + * 根据配置的权重优先走某个账号,并取出一个备份的 + * + * @param messageTypeSmsConfigs + */ + private MessageTypeSmsConfig[] loadBalance(List messageTypeSmsConfigs) { + + int total = 0; + for (MessageTypeSmsConfig channelConfig : messageTypeSmsConfigs) { + total += channelConfig.getWeights(); + } + + // 生成一个随机数[1,total],看落到哪个区间 + Random random = new Random(); + int index = random.nextInt(total) + 1; + + MessageTypeSmsConfig supplier = null; + MessageTypeSmsConfig supplierBack = null; + for (int i = 0; i < messageTypeSmsConfigs.size(); ++i) { + if (index <= messageTypeSmsConfigs.get(i).getWeights()) { + supplier = messageTypeSmsConfigs.get(i); + + int j = (i + 1) % messageTypeSmsConfigs.size(); // 取下一个供应商 + if (i == j) { + return new MessageTypeSmsConfig[]{supplier}; + } + supplierBack = messageTypeSmsConfigs.get(j); + return new MessageTypeSmsConfig[]{supplier, supplierBack}; + } + index -= messageTypeSmsConfigs.get(i).getWeights(); + } + return null; + } + + /** + * 每种类型都会有其下发渠道账号的配置(流量占比也会配置里面) + *

+ * 样例: + * key:msg_type_sms_config + * value:[{"message_type_10":[{"weights":80,"scriptName":"TencentSmsScript"},{"weights":20,"scriptName":"YunPianSmsScript"}]},{"message_type_20":[{"weights":20,"scriptName":"YunPianSmsScript"}]},{"message_type_30":[{"weights":20,"scriptName":"TencentSmsScript"}]},{"message_type_40":[{"weights":20,"scriptName":"TencentSmsScript"}]}] + * 通知类短信有两个发送渠道 TencentSmsScript 占80%流量,YunPianSmsScript占20%流量 + * 营销类短信只有一个发送渠道 YunPianSmsScript + * 验证码短信只有一个发送渠道 TencentSmsScript + * + * @param msgType + * @return + */ + private List getMessageTypeSmsConfig(Integer msgType) { + + String apolloKey = "msg_type_sms_config"; + String messagePrefix = "message_type_"; + + String property = config.getProperty(apolloKey, AustinConstant.APOLLO_DEFAULT_VALUE_JSON_ARRAY); + JSONArray jsonArray = JSON.parseArray(property); + for (int i = 0; i < jsonArray.size(); i++) { + JSONArray array = jsonArray.getJSONObject(i).getJSONArray(messagePrefix + msgType); + if (CollUtil.isNotEmpty(array)) { + List result = JSON.parseArray(JSON.toJSONString(array), MessageTypeSmsConfig.class); + return result; + } + } + return null; + } + /** * 如果有输入链接,则把链接拼在文案后 *

diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/SmsReceipt.java b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/SmsReceipt.java new file mode 100644 index 0000000..79f1e90 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/SmsReceipt.java @@ -0,0 +1,55 @@ +package com.java3y.austin.handler.receipt; + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.base.Throwables; +import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.TencentSmsAccount; +import com.java3y.austin.common.enums.SmsStatus; +import com.java3y.austin.support.config.SupportThreadPoolConfig; +import com.java3y.austin.support.domain.SmsRecord; +import com.tencentcloudapi.sms.v20210111.SmsClient; +import com.tencentcloudapi.sms.v20210111.models.PullSmsSendStatus; +import com.tencentcloudapi.sms.v20210111.models.PullSmsSendStatusRequest; +import com.tencentcloudapi.sms.v20210111.models.PullSmsSendStatusResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 拉取短信回执信息 + * + * @author 3y + */ +@Component +@Slf4j +public class SmsReceipt { + + @Autowired + private TencentSmsReceipt tencentSmsReceipt; + + @Autowired + private YunPianSmsReceipt yunPianSmsReceipt; + + @PostConstruct + private void init() { + SupportThreadPoolConfig.getPendingSingleThreadPool().execute(() -> { + while (true) { + tencentSmsReceipt.pull(); + yunPianSmsReceipt.pull(); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + } + } + }); + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/TencentSmsReceipt.java b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/TencentSmsReceipt.java index e59f67a..704422e 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/TencentSmsReceipt.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/TencentSmsReceipt.java @@ -13,13 +13,11 @@ import com.java3y.austin.support.dao.SmsRecordDao; import com.java3y.austin.support.domain.SmsRecord; import com.java3y.austin.support.utils.AccountUtils; import com.tencentcloudapi.common.Credential; -import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.profile.ClientProfile; import com.tencentcloudapi.common.profile.HttpProfile; import com.tencentcloudapi.sms.v20210111.SmsClient; import com.tencentcloudapi.sms.v20210111.models.*; import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -30,7 +28,7 @@ import java.util.List; /** - * 拉取短信回执信息 + * 拉取腾讯云短信回执信息 * * @author 3y */ @@ -45,60 +43,55 @@ public class TencentSmsReceipt { @Autowired private SmsRecordDao smsRecordDao; - @PostConstruct - private void init() { + + /** + * 拉取消息并入库 + */ + public void pull() { // 获取腾讯云账号信息 TencentSmsAccount account = accountUtils.getAccount(10, SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.class); - - SupportThreadPoolConfig.getPendingSingleThreadPool().execute(() -> { - - while (true) { - try { - SmsClient client = getSmsClient(account); - - // 每次拉取10条 - PullSmsSendStatusRequest req = new PullSmsSendStatusRequest(); - req.setLimit(10L); - req.setSmsSdkAppId(account.getSmsSdkAppId()); - - PullSmsSendStatusResponse resp = client.PullSmsSendStatus(req); - List smsRecordList = new ArrayList<>(); - if (resp != null && resp.getPullSmsSendStatusSet() != null && resp.getPullSmsSendStatusSet().length > 0) { - log.debug("receipt sms:{}", JSON.toJSONString(resp.getPullSmsSendStatusSet())); - for (PullSmsSendStatus pullSmsSendStatus : resp.getPullSmsSendStatusSet()) { - SmsRecord smsRecord = SmsRecord.builder() - .sendDate(Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN))) - .messageTemplateId(0L) - .phone(Long.valueOf(pullSmsSendStatus.getSubscriberNumber())) - .supplierId(account.getSupplierId()) - .supplierName(account.getSupplierName()) - .msgContent("") - .seriesId(pullSmsSendStatus.getSerialNo()) - .chargingNum(0) - .status("SUCCESS".equals(pullSmsSendStatus.getReportStatus()) ? SmsStatus.RECEIVE_SUCCESS.getCode() : SmsStatus.RECEIVE_FAIL.getCode()) - .reportContent(pullSmsSendStatus.getDescription()) - .updated(Math.toIntExact(pullSmsSendStatus.getUserReceiveTime())) - .created(Math.toIntExact(DateUtil.currentSeconds())) - .build(); - smsRecordList.add(smsRecord); - } - } - if (!CollUtil.isEmpty(smsRecordList)) { - smsRecordDao.saveAll(smsRecordList); - } - Thread.sleep(200); - } catch (Exception e) { - log.error("TencentSmsReceipt#init fail!{}", Throwables.getStackTraceAsString(e)); + try { + SmsClient client = getSmsClient(account); + + // 每次拉取10条 + PullSmsSendStatusRequest req = new PullSmsSendStatusRequest(); + req.setLimit(10L); + req.setSmsSdkAppId(account.getSmsSdkAppId()); + + PullSmsSendStatusResponse resp = client.PullSmsSendStatus(req); + List smsRecordList = new ArrayList<>(); + if (resp != null && resp.getPullSmsSendStatusSet() != null && resp.getPullSmsSendStatusSet().length > 0) { + log.debug("receipt sms:{}", JSON.toJSONString(resp.getPullSmsSendStatusSet())); + for (PullSmsSendStatus pullSmsSendStatus : resp.getPullSmsSendStatusSet()) { + SmsRecord smsRecord = SmsRecord.builder() + .sendDate(Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN))) + .messageTemplateId(0L) + .phone(Long.valueOf(pullSmsSendStatus.getSubscriberNumber())) + .supplierId(account.getSupplierId()) + .supplierName(account.getSupplierName()) + .msgContent("") + .seriesId(pullSmsSendStatus.getSerialNo()) + .chargingNum(0) + .status("SUCCESS".equals(pullSmsSendStatus.getReportStatus()) ? SmsStatus.RECEIVE_SUCCESS.getCode() : SmsStatus.RECEIVE_FAIL.getCode()) + .reportContent(pullSmsSendStatus.getDescription()) + .updated(Math.toIntExact(pullSmsSendStatus.getUserReceiveTime())) + .created(Math.toIntExact(DateUtil.currentSeconds())) + .build(); + smsRecordList.add(smsRecord); } } - - }); - + if (!CollUtil.isEmpty(smsRecordList)) { + smsRecordDao.saveAll(smsRecordList); + } + } catch (Exception e) { + log.error("TencentSmsReceipt#init fail!{}", Throwables.getStackTraceAsString(e)); + } } /** * 构造smsClient + * * @param account * @return */ diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/receipt/YunPianSmsReceipt.java b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/YunPianSmsReceipt.java new file mode 100644 index 0000000..1e6442d --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/receipt/YunPianSmsReceipt.java @@ -0,0 +1,25 @@ +package com.java3y.austin.handler.receipt; + + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + + +/** + * 拉取云片网短信回执信息 + * + * @author 3y + */ +@Component +@Slf4j +public class YunPianSmsReceipt { + /** + * 拉取消息并入库 + */ + public void pull() { + + } + +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/BaseSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/BaseSmsScript.java new file mode 100644 index 0000000..931cb5c --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/BaseSmsScript.java @@ -0,0 +1,42 @@ +package com.java3y.austin.handler.script; + + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.PostConstruct; +import java.lang.annotation.Annotation; + +/** + * sms发送脚本的抽象类 + * + * @author 3y + */ +@Slf4j +public abstract class BaseSmsScript implements SmsScript { + + @Autowired + private SmsScriptHolder smsScriptHolder; + + @PostConstruct + public void registerProcessScript() { + if (ArrayUtils.isEmpty(this.getClass().getAnnotations())) { + log.error("BaseSmsScript can not find annotation!"); + return; + } + Annotation handlerAnnotations = null; + for (Annotation annotation : this.getClass().getAnnotations()) { + if (annotation instanceof SmsScriptHandler) { + handlerAnnotations = annotation; + break; + } + } + if (handlerAnnotations == null) { + log.error("handler annotations not declared"); + return; + } + //注册handler + smsScriptHolder.putHandler(((SmsScriptHandler) handlerAnnotations).value(), this); + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScript.java index 94560ec..35d6e98 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScript.java @@ -17,8 +17,8 @@ public interface SmsScript { * 发送短信 * @param smsParam * @return 渠道商接口返回值 - * @throws Exception + */ - List send(SmsParam smsParam) throws Exception; + List send(SmsParam smsParam); } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHandler.java new file mode 100644 index 0000000..7b285e8 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHandler.java @@ -0,0 +1,27 @@ +package com.java3y.austin.handler.script; + +import org.springframework.stereotype.Component; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * 标识 短信渠道 + * + * @author 3y + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +@Component +public @interface SmsScriptHandler { + + /** + * 这里输入脚本名 + * + * @return + */ + String value(); +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHolder.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHolder.java new file mode 100644 index 0000000..b02244e --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/SmsScriptHolder.java @@ -0,0 +1,25 @@ +package com.java3y.austin.handler.script; + + +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * sendAccount->SmsScript的映射关系 + * + * @author 3y + */ +@Component +public class SmsScriptHolder { + + private Map handlers = new HashMap<>(8); + + public void putHandler(String scriptName, SmsScript handler) { + handlers.put(scriptName, handler); + } + public SmsScript route(String scriptName) { + return handlers.get(scriptName); + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java index f3bb434..3412560 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java @@ -4,11 +4,15 @@ import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.base.Throwables; import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.TencentSmsAccount; import com.java3y.austin.common.enums.SmsStatus; import com.java3y.austin.handler.domain.sms.SmsParam; -import com.java3y.austin.common.dto.account.TencentSmsAccount; +import com.java3y.austin.handler.script.BaseSmsScript; import com.java3y.austin.handler.script.SmsScript; +import com.java3y.austin.handler.script.SmsScriptHandler; import com.java3y.austin.support.domain.SmsRecord; import com.java3y.austin.support.utils.AccountUtils; import com.tencentcloudapi.common.Credential; @@ -20,7 +24,6 @@ import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; import com.tencentcloudapi.sms.v20210111.models.SendStatus; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Date; @@ -33,9 +36,10 @@ import java.util.List; * 2. 推荐直接使用SDK调用 * 3. 推荐使用API Explorer 生成代码 */ -@Service + @Slf4j -public class TencentSmsScript implements SmsScript { +@SmsScriptHandler("TencentSmsScript") +public class TencentSmsScript extends BaseSmsScript implements SmsScript { private static final Integer PHONE_NUM = 11; @@ -43,12 +47,17 @@ public class TencentSmsScript implements SmsScript { private AccountUtils accountUtils; @Override - public List send(SmsParam smsParam) throws Exception { - TencentSmsAccount tencentSmsAccount = accountUtils.getAccount(smsParam.getSendAccount(), SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.class); - SmsClient client = init(tencentSmsAccount); - SendSmsRequest request = assembleReq(smsParam, tencentSmsAccount); - SendSmsResponse response = client.SendSms(request); - return assembleSmsRecord(smsParam, response, tencentSmsAccount); + public List send(SmsParam smsParam) { + try { + TencentSmsAccount tencentSmsAccount = accountUtils.getAccount(SendAccountConstant.TENCENT_SMS_CODE, SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.class); + SmsClient client = init(tencentSmsAccount); + SendSmsRequest request = assembleReq(smsParam, tencentSmsAccount); + SendSmsResponse response = client.SendSms(request); + return assembleSmsRecord(smsParam, response, tencentSmsAccount); + } catch (Exception e) { + log.error("TencentSmsScript#send fail:{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam)); + return null; + } } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/YunPianSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/YunPianSmsScript.java new file mode 100644 index 0000000..d3df125 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/YunPianSmsScript.java @@ -0,0 +1,108 @@ +package com.java3y.austin.handler.script.impl; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.Header; +import cn.hutool.http.HttpRequest; +import com.alibaba.fastjson.JSON; +import com.google.common.base.Throwables; +import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.YunPianSmsAccount; +import com.java3y.austin.common.enums.SmsStatus; +import com.java3y.austin.handler.domain.sms.SmsParam; +import com.java3y.austin.handler.domain.sms.YunPianSendResult; +import com.java3y.austin.handler.script.BaseSmsScript; +import com.java3y.austin.handler.script.SmsScript; +import com.java3y.austin.handler.script.SmsScriptHandler; +import com.java3y.austin.support.domain.SmsRecord; +import com.java3y.austin.support.utils.AccountUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * @author 3y + * @date 2022年5月23日 + * 发送短信接入文档:https://www.yunpian.com/official/document/sms/zh_CN/domestic_list + */ +@Slf4j +@SmsScriptHandler("YunPianSmsScript") +public class YunPianSmsScript extends BaseSmsScript implements SmsScript { + @Autowired + private AccountUtils accountUtils; + + @Override + public List send(SmsParam smsParam) { + + try { + YunPianSmsAccount account = accountUtils.getAccount(SendAccountConstant.YUN_PIAN_SMS_CODE, SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, YunPianSmsAccount.class); + Map params = assembleParam(smsParam, account); + + String result = HttpRequest.post(account.getUrl()) + .header(Header.CONTENT_TYPE.getValue(), "application/x-www-form-urlencoded;charset=utf-8;") + .header(Header.ACCEPT.getValue(), "application/json;charset=utf-8;") + .form(params) + .timeout(2000) + .execute().body(); + YunPianSendResult yunPianSendResult = JSON.parseObject(result, YunPianSendResult.class); + return assembleSmsRecord(smsParam, yunPianSendResult, account); + } catch (Exception e) { + log.error("YunPianSmsScript#send fail:{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam)); + return null; + } + + } + + /** + * 组装参数 + * + * @param smsParam + * @param account + * @return + */ + private Map assembleParam(SmsParam smsParam, YunPianSmsAccount account) { + Map params = new HashMap<>(); + params.put("apikey", account.getApikey()); + params.put("mobile", StringUtils.join(smsParam.getPhones(), StrUtil.C_COMMA)); + params.put("tpl_id", account.getTplId()); + params.put("tpl_value", ""); + return params; + } + + + private List assembleSmsRecord(SmsParam smsParam, YunPianSendResult response, YunPianSmsAccount account) { + if (response == null || ArrayUtil.isEmpty(response.getData())) { + return null; + } + + List smsRecordList = new ArrayList<>(); + + for (YunPianSendResult.DataDTO datum : response.getData()) { + SmsRecord smsRecord = SmsRecord.builder() + .sendDate(Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN))) + .messageTemplateId(smsParam.getMessageTemplateId()) + .phone(Long.valueOf(datum.getMobile())) + .supplierId(account.getSupplierId()) + .supplierName(account.getSupplierName()) + .msgContent(smsParam.getContent()) + .seriesId(datum.getSid()) + .chargingNum(Math.toIntExact(datum.getCount())) + .status("0".equals(datum.getCode()) ? SmsStatus.SEND_SUCCESS.getCode() : SmsStatus.SEND_FAIL.getCode()) + .reportContent(datum.getMsg()) + .created(Math.toIntExact(DateUtil.currentSeconds())) + .updated(Math.toIntExact(DateUtil.currentSeconds())) + .build(); + + smsRecordList.add(smsRecord); + } + + return smsRecordList; + } + + +} + diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/MiniProgramAccountService.java similarity index 89% rename from austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java rename to austin-handler/src/main/java/com/java3y/austin/handler/wechat/MiniProgramAccountService.java index 7a4b6da..a0ef4b3 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/MiniProgramAccountService.java @@ -1,4 +1,4 @@ -package com.java3y.austin.handler.script; +package com.java3y.austin.handler.wechat; import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java similarity index 91% rename from austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java rename to austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java index 8451869..4014db2 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/OfficialAccountService.java @@ -1,4 +1,4 @@ -package com.java3y.austin.handler.script; +package com.java3y.austin.handler.wechat; import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/MiniProgramAccountServiceImpl.java similarity index 97% rename from austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java rename to austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/MiniProgramAccountServiceImpl.java index ddb2e21..6c400bf 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/MiniProgramAccountServiceImpl.java @@ -1,4 +1,4 @@ -package com.java3y.austin.handler.script.impl; +package com.java3y.austin.handler.wechat.impl; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; @@ -9,7 +9,7 @@ import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import com.java3y.austin.common.constant.SendAccountConstant; import com.java3y.austin.common.dto.account.WeChatMiniProgramAccount; import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; -import com.java3y.austin.handler.script.MiniProgramAccountService; +import com.java3y.austin.handler.wechat.MiniProgramAccountService; import com.java3y.austin.support.utils.AccountUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java similarity index 96% rename from austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java rename to austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java index a0f68fc..7766713 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/wechat/impl/OfficialAccountServiceImpl.java @@ -1,9 +1,9 @@ -package com.java3y.austin.handler.script.impl; +package com.java3y.austin.handler.wechat.impl; import com.java3y.austin.common.constant.SendAccountConstant; import com.java3y.austin.common.dto.account.WeChatOfficialAccount; import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; -import com.java3y.austin.handler.script.OfficialAccountService; +import com.java3y.austin.handler.wechat.OfficialAccountService; import com.java3y.austin.support.utils.AccountUtils; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.mp.api.WxMpService; diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AfterParamCheckAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AfterParamCheckAction.java index 8c97488..ee44492 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AfterParamCheckAction.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AfterParamCheckAction.java @@ -15,6 +15,7 @@ import com.java3y.austin.support.pipeline.ProcessContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -29,18 +30,23 @@ import java.util.stream.Collectors; @Service public class AfterParamCheckAction implements BusinessProcess { - public static final String PHONE_REGEX_EXP = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[0-9])|(18[0-9])|(19[1,8,9]))\\d{8}$"; + public static final String EMAIL_REGEX_EXP = "[a-zA-Z0-9]+@[a-zA-Z0-9]+\\\\.[a-zA-Z0-9]+"; + + public static final HashMap CHANNEL_REGEX_EXP = new HashMap<>(); + static { + CHANNEL_REGEX_EXP.put(IdType.PHONE.getCode(), PHONE_REGEX_EXP); + CHANNEL_REGEX_EXP.put(IdType.EMAIL.getCode(), EMAIL_REGEX_EXP); + } + @Override public void process(ProcessContext context) { SendTaskModel sendTaskModel = context.getProcessModel(); List taskInfo = sendTaskModel.getTaskInfo(); - // 1. 过滤掉不合法的手机号 - filterIllegalPhoneNum(taskInfo); - - // 2. + // 1. 过滤掉不合法的手机号、邮件 + filterIllegalReceiver(taskInfo); if (CollUtil.isEmpty(taskInfo)) { context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.CLIENT_BAD_PARAMETERS)); @@ -48,31 +54,35 @@ public class AfterParamCheckAction implements BusinessProcess { } /** - * 如果指定类型是手机号,且渠道是发送短信,检测输入手机号是否合法 - * + * 如果指定类型是手机号,检测输入手机号是否合法 + * 如果指定类型是邮件,检测输入邮件是否合法 * @param taskInfo */ - private void filterIllegalPhoneNum(List taskInfo) { + private void filterIllegalReceiver(List taskInfo) { Integer idType = CollUtil.getFirst(taskInfo.iterator()).getIdType(); - Integer sendChannel = CollUtil.getFirst(taskInfo.iterator()).getSendChannel(); - - if (IdType.PHONE.getCode().equals(idType) && ChannelType.SMS.getCode().equals(sendChannel)) { - Iterator iterator = taskInfo.iterator(); + filter(taskInfo, CHANNEL_REGEX_EXP.get(idType)); + } - // 利用正则找出不合法的手机号 - while (iterator.hasNext()) { - TaskInfo task = iterator.next(); - Set illegalPhone = task.getReceiver().stream() - .filter(phone -> !ReUtil.isMatch(PHONE_REGEX_EXP, phone)) - .collect(Collectors.toSet()); + /** + * 利用正则过滤掉不合法的接收者 + * + * @param taskInfo + * @param regexExp + */ + private void filter(List taskInfo, String regexExp) { + Iterator iterator = taskInfo.iterator(); + while (iterator.hasNext()) { + TaskInfo task = iterator.next(); + Set illegalPhone = task.getReceiver().stream() + .filter(phone -> !ReUtil.isMatch(regexExp, phone)) + .collect(Collectors.toSet()); - if (CollUtil.isNotEmpty(illegalPhone)) { - task.getReceiver().removeAll(illegalPhone); - log.error("messageTemplateId:{} find illegal phone!{}", task.getMessageTemplateId(), JSON.toJSONString(illegalPhone)); - } - if (CollUtil.isEmpty(task.getReceiver())) { - iterator.remove(); - } + if (CollUtil.isNotEmpty(illegalPhone)) { + task.getReceiver().removeAll(illegalPhone); + log.error("messageTemplateId:{} find illegal receiver!{}", task.getMessageTemplateId(), JSON.toJSONString(illegalPhone)); + } + if (CollUtil.isEmpty(task.getReceiver())) { + iterator.remove(); } } } diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/PreParamCheckAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/PreParamCheckAction.java index 2c1d152..4e48e07 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/PreParamCheckAction.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/PreParamCheckAction.java @@ -11,6 +11,7 @@ import com.java3y.austin.support.pipeline.ProcessContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -23,6 +24,11 @@ import java.util.stream.Collectors; @Service public class PreParamCheckAction implements BusinessProcess { + /** + * 最大的人数 + */ + private static final Integer BATCH_RECEIVER_SIZE = 100; + @Override public void process(ProcessContext context) { SendTaskModel sendTaskModel = context.getProcessModel(); @@ -30,13 +36,13 @@ public class PreParamCheckAction implements BusinessProcess { Long messageTemplateId = sendTaskModel.getMessageTemplateId(); List messageParamList = sendTaskModel.getMessageParamList(); - // 没有传入 消息模板Id 或者 messageParam + // 1.没有传入 消息模板Id 或者 messageParam if (messageTemplateId == null || CollUtil.isEmpty(messageParamList)) { context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.CLIENT_BAD_PARAMETERS)); return; } - // 过滤 receiver=null 的messageParam + // 2.过滤 receiver=null 的messageParam List resultMessageParamList = messageParamList.stream() .filter(messageParam -> !StrUtil.isBlank(messageParam.getReceiver())) .collect(Collectors.toList()); @@ -44,7 +50,13 @@ public class PreParamCheckAction implements BusinessProcess { context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.CLIENT_BAD_PARAMETERS)); return; } - sendTaskModel.setMessageParamList(resultMessageParamList); + + // 3.过滤receiver大于100的请求 + if (messageParamList.stream().anyMatch(messageParam -> messageParam.getReceiver().split(StrUtil.COMMA).length > BATCH_RECEIVER_SIZE)) { + context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.TOO_MANY_RECEIVER)); + return; + } + } } diff --git a/austin-service-api/src/main/java/com/java3y/austin/service/api/domain/MessageParam.java b/austin-service-api/src/main/java/com/java3y/austin/service/api/domain/MessageParam.java index 95aa2f8..509efa2 100644 --- a/austin-service-api/src/main/java/com/java3y/austin/service/api/domain/MessageParam.java +++ b/austin-service-api/src/main/java/com/java3y/austin/service/api/domain/MessageParam.java @@ -23,6 +23,7 @@ public class MessageParam { /** * @Description: 接收者 * 多个用,逗号号分隔开 + * 【不能大于100个】 * 必传 */ private String receiver; diff --git a/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java b/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java index 5d08a57..77f4c7f 100644 --- a/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java +++ b/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java @@ -21,7 +21,7 @@ public class AccountUtils { private Config config; /** - * (key:smsAccount)短信参数示例:[{"sms_10":{"url":"sms.tencentcloudapi.com","region":"ap-guangzhou","secretId":"AKIDhDUUDfffffMEqBF1WljQq","secretKey":"B4h39yWnfffff7D2btue7JErDJ8gxyi","smsSdkAppId":"140025","templateId":"11897","signName":"Java3y公众号","supplierId":10,"supplierName":"腾讯云"}}] + * (key:smsAccount)短信参数示例:[{"sms_10":{"url":"sms.tencentcloudapi.com","region":"ap-guangzhou","secretId":"AKIDhDUUDfrmQnvmMfhSw95lCMEqBF1WljQq","secretKey":"B4h39yWnnX0C6k7D2btue7JErDJ8gxyi","smsSdkAppId":"1400592125","templateId":"1182097","signName":"Java3y公众号","supplierId":10,"supplierName":"腾讯云"}},{"sms_20":{"url":"https://sms.yunpian.com/v2/sms/tpl_batch_send.json","apikey":"ca55d4c856d72e5d589361c4511b5cd7","tpl_id":"5236082","supplierId":20,"supplierName":"云片"}}] * (key:emailAccount)邮件参数示例:[{"email_10":{"host":"smtp.qq.com","port":465,"user":"403686131@qq.com","pass":"","from":"403686131@qq.com"}}] * (key:enterpriseWechatAccount)企业微信参数示例:[{"enterprise_wechat_10":{"corpId":"wwf87603333e00069c","corpSecret":"-IFWxS2222QxzPIorNVUQn144444D915DM","agentId":10044442,"token":"rXROB3333Kf6i","aesKey":"MKZtoFxHIM44444M7ieag3r9ZPUsl"}}] * (key:dingDingRobotAccount) 钉钉自定义机器人参数示例:[{"ding_ding_robot_10":{"secret":"SEC996d8d9d4768aded74114faae924f229229de444475a1c295d64fedf","webhook":"https://oapi.dingtalk.com/robot/send?access_token=8d03b644ffb6534b203d87333367328b0c3003d164715d2c6c6e56"}}] @@ -42,4 +42,7 @@ public class AccountUtils { return null; } + + + } diff --git a/austin-web/src/main/java/com/java3y/austin/web/service/impl/DataServiceImpl.java b/austin-web/src/main/java/com/java3y/austin/web/service/impl/DataServiceImpl.java index 15f3727..5a9b6b1 100644 --- a/austin-web/src/main/java/com/java3y/austin/web/service/impl/DataServiceImpl.java +++ b/austin-web/src/main/java/com/java3y/austin/web/service/impl/DataServiceImpl.java @@ -197,14 +197,4 @@ public class DataServiceImpl implements DataService { } return businessId; } - - public static void main(String[] args) { - - Long time = 1653140847 * 1000L; - - String format = DateUtil.format(new Date(time), DatePattern.NORM_DATETIME_PATTERN); - - System.out.println(format - ); - } }