diff --git a/deliver-backend/deliver-backend-server/pom.xml b/deliver-backend/deliver-backend-server/pom.xml index a0cd6d54e76760534ca62f3efff049a7fb1cb37c..46d1a066c1d0de740a47967bf888bca3ac6d4bdb 100644 --- a/deliver-backend/deliver-backend-server/pom.xml +++ b/deliver-backend/deliver-backend-server/pom.xml @@ -93,6 +93,11 @@ spring-boot-starter-validation + + com.aliyun + alibabacloud-dysmsapi20170525 + + diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/SmsClient.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/SmsClient.java index 219c1006f1345d20448073a801c66373c6bafdaa..4d3c9559cfe2acf02cabaed086f7a1ca421c4bed 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/SmsClient.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/SmsClient.java @@ -1,5 +1,8 @@ package com.oszero.deliver.server.client.sms; +import com.oszero.deliver.server.model.app.SmsApp; +import com.oszero.deliver.server.model.dto.common.SendTaskDto; + /** * 短信客户端接口 * @@ -7,4 +10,7 @@ package com.oszero.deliver.server.client.sms; * @version 1.0.0 */ public interface SmsClient { + + void sendSms(SmsApp smsApp, SendTaskDto sendTaskDto); + } diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/factory/SmsFactory.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/factory/SmsFactory.java index 5c5fabf84412c4e9215ff0bc51f519bf6e04697a..4e3a62cf8f94af7eef2f147f7f52fdc341575d36 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/factory/SmsFactory.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/factory/SmsFactory.java @@ -1,13 +1,32 @@ package com.oszero.deliver.server.client.sms.factory; -import org.springframework.stereotype.Service; +import com.oszero.deliver.server.client.sms.SmsClient; +import com.oszero.deliver.server.client.sms.impl.AliYunSmsClient; +import com.oszero.deliver.server.client.sms.impl.TenCentSmsClient; +import com.oszero.deliver.server.enums.SmsProvideTypeEnum; +import com.oszero.deliver.server.exception.MessageException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; /** - * 短信客户端工厂 * * @author oszero * @version 1.0.0 */ -@Service +@Component +@RequiredArgsConstructor public class SmsFactory { + + private final AliYunSmsClient aliYunSmsClient; + private final TenCentSmsClient tenCentSmsClient; + + public SmsClient getClient(String smsProvide){ + if(SmsProvideTypeEnum.aliyun.getMessage().equals(smsProvide)){ + return aliYunSmsClient; + }else if(SmsProvideTypeEnum.tencent.getMessage().equals(smsProvide)){ + return tenCentSmsClient; + }else { + throw new MessageException("暂时不提供指定短信服务提供商:"+smsProvide); + } + } } diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/AliYunSmsClient.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/AliYunSmsClient.java index abea657c70cbb2b4778da069fa1bbda0ed081067..6beac4d2accf9ab15b054c817f2241777888cc14 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/AliYunSmsClient.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/AliYunSmsClient.java @@ -1,7 +1,21 @@ package com.oszero.deliver.server.client.sms.impl; +import com.aliyun.auth.credentials.Credential; +import com.aliyun.auth.credentials.provider.StaticCredentialProvider; +import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient; +import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse; +import com.oszero.deliver.server.client.sms.SmsClient; +import com.oszero.deliver.server.exception.MessageException; +import com.oszero.deliver.server.model.app.SmsApp; +import com.oszero.deliver.server.model.app.smsapp.AliYunSmsApp; +import com.oszero.deliver.server.model.dto.common.SendTaskDto; +import darabonba.core.client.ClientOverrideConfiguration; import org.springframework.stereotype.Service; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + /** * 短信客户端阿里云实现 * @@ -9,5 +23,56 @@ import org.springframework.stereotype.Service; * @version 1.0.0 */ @Service -public class AliYunSmsClient { +public class AliYunSmsClient implements SmsClient { + + private static final String Template_Param = "templateParam"; + private static final String Endpoint_Override = "dysmsapi.aliyuncs.com"; + + @Override + public void sendSms(SmsApp smsApp, SendTaskDto sendTaskDto) { + String s = sendTaskDto.getUsers().toString(); + String phoneNumbers = s.substring(1, s.length()-1); + AliYunSmsApp aliYunSmsApp = (AliYunSmsApp) smsApp; + + + StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder() + // 此处以把AccessKey 和 AccessKeySecret 保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里 + // 强烈建议不要把 AccessKey 和 AccessKeySecret 保存到代码里,会存在密钥泄漏风险 + .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")) + .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")) + .build()); + + AsyncClient client = null; + try { + client = AsyncClient.builder() + .credentialsProvider(provider) + .overrideConfiguration( + ClientOverrideConfiguration.create() + .setEndpointOverride(Endpoint_Override) + ) + .build(); + + + SendSmsRequest sendSmsRequest = SendSmsRequest.builder() + .phoneNumbers(phoneNumbers) + .signName(aliYunSmsApp.getSignName()) + .templateCode(aliYunSmsApp.getTemplateCode()) + .templateParam((String) sendTaskDto.getParamMap().get(Template_Param)) + .build(); + + + CompletableFuture response = client.sendSms(sendSmsRequest); + + SendSmsResponse resp = response.get(); + } catch (InterruptedException e) { + throw new MessageException("短信发送失败" + e.getMessage()); + } catch (ExecutionException e) { + throw new MessageException("短信发送失败" + e.getMessage()); + } finally { + client.close(); + } + + } + + } diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/TenCentSmsClient.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/TenCentSmsClient.java new file mode 100644 index 0000000000000000000000000000000000000000..87119d89a3ebc27e0c32c1ed476d52d48fa5a4b0 --- /dev/null +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/client/sms/impl/TenCentSmsClient.java @@ -0,0 +1,20 @@ +package com.oszero.deliver.server.client.sms.impl; + +import com.oszero.deliver.server.client.sms.SmsClient; +import com.oszero.deliver.server.model.app.SmsApp; +import com.oszero.deliver.server.model.dto.common.SendTaskDto; +import org.springframework.stereotype.Service; + +/** + * 短信客户端腾讯云实现 + * + * @author oszero + * @version 1.0.0 + */ +@Service +public class TenCentSmsClient implements SmsClient { + @Override + public void sendSms(SmsApp smsApp, SendTaskDto sendTaskDto) { + // TODO: 2023/12/13 接入腾讯云 + } +} diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/enums/SmsProvideTypeEnum.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/enums/SmsProvideTypeEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..0ea1fe08a20168a1d31245055a946c918500d70c --- /dev/null +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/enums/SmsProvideTypeEnum.java @@ -0,0 +1,35 @@ +package com.oszero.deliver.server.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +/** + * 短信服务提供商枚举 + * + * @author oszero + * @version 1.0.0 + */ +@Getter +@ToString +@AllArgsConstructor +public enum SmsProvideTypeEnum { + + aliyun(0,"aliyun"), + tencent(1,"tencent"); + + private final Integer code; + private final String message; + + + public static SmsProvideTypeEnum getInstanceByCode(Integer code) { + for (SmsProvideTypeEnum item : values() + ) { + if (item.getCode().equals(code)) { + return item; + } + } + return null; + } + +} diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/handler/impl/SmsHandler.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/handler/impl/SmsHandler.java index 95809a5cd51d630bf6a480eba52197cb79486b3a..7ad475407aeb64cc3df65d9ca08013749f874aa0 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/handler/impl/SmsHandler.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/handler/impl/SmsHandler.java @@ -1,11 +1,20 @@ package com.oszero.deliver.server.handler.impl; +import cn.hutool.json.JSONUtil; +import com.oszero.deliver.server.client.sms.SmsClient; import com.oszero.deliver.server.client.sms.factory.SmsFactory; +import com.oszero.deliver.server.enums.SmsProvideTypeEnum; +import com.oszero.deliver.server.exception.MessageException; import com.oszero.deliver.server.handler.BaseHandler; +import com.oszero.deliver.server.model.app.SmsApp; +import com.oszero.deliver.server.model.app.smsapp.AliYunSmsApp; +import com.oszero.deliver.server.model.app.smsapp.TenCentSmsApp; import com.oszero.deliver.server.model.dto.common.SendTaskDto; import com.oszero.deliver.server.web.service.MessageRecordService; import org.springframework.stereotype.Component; +import java.util.Map; + /** * 短信消费者处理器 * @@ -14,6 +23,7 @@ import org.springframework.stereotype.Component; */ @Component public class SmsHandler extends BaseHandler { + private static final String SMS_Provide = "smsProvide"; private final SmsFactory smsFactory; @@ -24,6 +34,24 @@ public class SmsHandler extends BaseHandler { @Override protected void handle(SendTaskDto sendTaskDto) throws Exception { + Map map= sendTaskDto.getParamMap(); + String appConfig = sendTaskDto.getAppConfig(); + String sms = (String) map.get(SMS_Provide); + SmsApp rightProvideApp = getRightProvideApp(sms,appConfig); + SmsClient smsProvide = smsFactory.getClient(sms); + smsProvide.sendSms(rightProvideApp,sendTaskDto); + } + private SmsApp getRightProvideApp(String sms,String appConfig ){ + for(SmsProvideTypeEnum item: SmsProvideTypeEnum.values()){ + if(item.getMessage().equals(sms)){ + if(SmsProvideTypeEnum.aliyun.getMessage().equals(sms)){ + return JSONUtil.toBean(appConfig, AliYunSmsApp.class); + }else if(SmsProvideTypeEnum.tencent.getMessage().equals(sms)){ + return JSONUtil.toBean(appConfig, TenCentSmsApp.class); + } + } + } + throw new MessageException("没有指定的短信服务App:"+sms); } } diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/SmsApp.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/SmsApp.java index c52c9e99bf4432c9adf079ee5565a01f9ff708c1..f2694e56cacc835fd05c9d5449b6b2f7ca274805 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/SmsApp.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/SmsApp.java @@ -1,17 +1,10 @@ package com.oszero.deliver.server.model.app; -import lombok.*; - /** * 短信 APP 配置 * * @author oszero * @version 1.0.0 */ -@Data -@Builder -//@AllArgsConstructor -@NoArgsConstructor -@EqualsAndHashCode(callSuper = true) -public class SmsApp extends AppConfig { +public abstract class SmsApp extends AppConfig { } diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/AliYunSmsApp.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/AliYunSmsApp.java new file mode 100644 index 0000000000000000000000000000000000000000..f14d6c82928de818f3dfbab8f5bce6bbfc4a0ef2 --- /dev/null +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/AliYunSmsApp.java @@ -0,0 +1,22 @@ +package com.oszero.deliver.server.model.app.smsapp; + +import com.oszero.deliver.server.model.app.SmsApp; +import lombok.*; + +/** + * 阿里云短信 APP 配置 + * + * @author oszero + * @version 1.0.0 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class AliYunSmsApp extends SmsApp { + + private String signName; + private String templateCode; + +} diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/TenCentSmsApp.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/TenCentSmsApp.java new file mode 100644 index 0000000000000000000000000000000000000000..e2b403dda4232f04a19218b5998cad7b3e536fa8 --- /dev/null +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/model/app/smsapp/TenCentSmsApp.java @@ -0,0 +1,12 @@ +package com.oszero.deliver.server.model.app.smsapp; + +import com.oszero.deliver.server.model.app.SmsApp; + +/** + * 阿里云短信 APP 配置 + * + * @author oszero + * @version 1.0.0 + */ +public class TenCentSmsApp extends SmsApp { +} diff --git a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/pretreatment/link/paramcheck/sms/SmsParamCheck.java b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/pretreatment/link/paramcheck/sms/SmsParamCheck.java index 7536efa2c86c13130a787a5d15fc9f8828ac7119..43ea6072abe2af0e03f76232adf6134261cb557c 100644 --- a/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/pretreatment/link/paramcheck/sms/SmsParamCheck.java +++ b/deliver-backend/deliver-backend-server/src/main/java/com/oszero/deliver/server/pretreatment/link/paramcheck/sms/SmsParamCheck.java @@ -18,6 +18,8 @@ public class SmsParamCheck implements MessageLink { public void process(LinkContext context) { SendTaskDto sendTaskDto = context.getProcessModel(); + // TODO: 2023/12/13 参数校验 + MessageLinkTraceUtils.recordMessageLifecycleInfoLog(sendTaskDto, "完成短信消息参数校验"); } } diff --git a/deliver-backend/pom.xml b/deliver-backend/pom.xml index 6f8d8082c10511ddbe502ed16ed79fcec2b06306..8b125d0ecd373aac507a540df7151cb218ab4664 100644 --- a/deliver-backend/pom.xml +++ b/deliver-backend/pom.xml @@ -39,10 +39,17 @@ 3.5.4 1.2.16 2.2.3 + + 2.0.24 + + com.aliyun + alibabacloud-dysmsapi20170525 + ${aliyun-sms-sdk-version} + cn.hutool hutool-all diff --git a/deliver-front/vue/components.d.ts b/deliver-front/vue/components.d.ts index 523f42c79cd467f652f39bea4dbdcd2e3aad871f..2fbde0d8124c71a284ed64fb67145caf76f2f2c3 100644 --- a/deliver-front/vue/components.d.ts +++ b/deliver-front/vue/components.d.ts @@ -13,22 +13,15 @@ declare module 'vue' { ACard: typeof import('ant-design-vue/es')['Card'] ACardMeta: typeof import('ant-design-vue/es')['CardMeta'] ACol: typeof import('ant-design-vue/es')['Col'] - ADescriptions: typeof import('ant-design-vue/es')['Descriptions'] - ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem'] ADivider: typeof import('ant-design-vue/es')['Divider'] - ADrawer: typeof import('ant-design-vue/es')['Drawer'] AForm: typeof import('ant-design-vue/es')['Form'] AFormItem: typeof import('ant-design-vue/es')['FormItem'] AInput: typeof import('ant-design-vue/es')['Input'] - AInputGroup: typeof import('ant-design-vue/es')['InputGroup'] - AInputNumber: typeof import('ant-design-vue/es')['InputNumber'] ALayout: typeof import('ant-design-vue/es')['Layout'] ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] ALayoutFooter: typeof import('ant-design-vue/es')['LayoutFooter'] ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] - AList: typeof import('ant-design-vue/es')['List'] - AListItem: typeof import('ant-design-vue/es')['ListItem'] AMenu: typeof import('ant-design-vue/es')['Menu'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AModal: typeof import('ant-design-vue/es')['Modal'] @@ -46,7 +39,6 @@ declare module 'vue' { ATable: typeof import('ant-design-vue/es')['Table'] ATag: typeof import('ant-design-vue/es')['Tag'] ATooltip: typeof import('ant-design-vue/es')['Tooltip'] - AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger'] Banner: typeof import('./src/components/Banner/index.vue')['default'] Code: typeof import('./src/components/Code/index.vue')['default'] Echarts: typeof import('./src/components/Echarts/index.vue')['default']