ソースを参照

feat[litemall-core]: 支持阿里云短信

Junling Bu 6 年 前
コミット
488a830e9a

+ 6 - 0
litemall-core/pom.xml

@@ -17,6 +17,12 @@
         </dependency>
 
         <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.0.3</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>

+ 122 - 0
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/AliyunSmsSender.java

@@ -0,0 +1,122 @@
+package org.linlinjava.litemall.core.notify;
+
+import com.aliyuncs.CommonRequest;
+import com.aliyuncs.CommonResponse;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.exceptions.ServerException;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.profile.DefaultProfile;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.linlinjava.litemall.core.util.JacksonUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/*
+ * 阿里云短信服务
+ */
+public class AliyunSmsSender implements SmsSender {
+    private final Log logger = LogFactory.getLog(AliyunSmsSender.class);
+
+    private String regionId;
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String sign;
+
+    public String getRegionId() {
+        return regionId;
+    }
+
+    public void setRegionId(String regionId) {
+        this.regionId = regionId;
+    }
+
+    public String getAccessKeyId() {
+        return accessKeyId;
+    }
+
+    public void setAccessKeyId(String accessKeyId) {
+        this.accessKeyId = accessKeyId;
+    }
+
+    public String getAccessKeySecret() {
+        return accessKeySecret;
+    }
+
+    public void setAccessKeySecret(String accessKeySecret) {
+        this.accessKeySecret = accessKeySecret;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    @Override
+    public SmsResult send(String phone, String content) {
+        SmsResult smsResult = new SmsResult();
+        smsResult.setSuccessful(false);
+        return smsResult;
+    }
+
+    @Override
+    public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
+        DefaultProfile profile = DefaultProfile.getProfile(this.regionId, this.accessKeyId, this.accessKeySecret);
+        IAcsClient client = new DefaultAcsClient(profile);
+
+        CommonRequest request = new CommonRequest();
+        request.setMethod(MethodType.POST);
+        request.setDomain("dysmsapi.aliyuncs.com");
+        request.setVersion("2017-05-25");
+        request.setAction("SendSms");
+        request.putQueryParameter("RegionId", this.regionId);
+        request.putQueryParameter("PhoneNumbers", phone);
+        request.putQueryParameter("SignName", this.sign);
+        request.putQueryParameter("TemplateCode", templateId);
+        /*
+          NOTE:阿里云短信和腾讯云短信这里存在不一致
+          腾讯云短信模板参数是数组,因此短信模板形式如 “短信参数{1}, 短信参数{2}”
+          阿里云短信模板参数是JSON,因此短信模板形式如“短信参数{param1}, 短信参数{param2}”
+          为了保持统一,我们假定阿里云短信里面的参数是code,code1,code2...
+
+          如果开发者在阿里云短信申请的模板参数是其他命名,请开发者自行调整这里的代码,或者直接写死。
+         */
+        String templateParam = "{}";
+        if(params.length == 1){
+            Map<String, String> data = new HashMap<>();
+            data.put("code", params[0]);
+            templateParam = JacksonUtil.toJson(data);
+        }
+        else if(params.length > 1){
+            Map<String, String> data = new HashMap<>();
+            data.put("code", params[0]);
+            for(int i = 1; i < params.length; i++){
+                data.put("code" + i, params[i]);
+            }
+            templateParam = JacksonUtil.toJson(data);
+        }
+        request.putQueryParameter("TemplateParam", templateParam);
+
+        try {
+            CommonResponse response = client.getCommonResponse(request);
+            SmsResult smsResult = new SmsResult();
+            smsResult.setSuccessful(true);
+            smsResult.setResult(response);
+            return smsResult;
+        } catch (ServerException e) {
+            e.printStackTrace();
+        } catch (ClientException e) {
+            e.printStackTrace();
+        }
+
+        SmsResult smsResult = new SmsResult();
+        smsResult.setSuccessful(false);
+        return smsResult;
+    }
+}

+ 2 - 5
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyService.java

@@ -66,8 +66,7 @@ public class NotifyService {
             return;
         }
 
-        int templateId = Integer.parseInt(templateIdStr);
-        smsSender.sendWithTemplate(phoneNumber, templateId, params);
+        smsSender.sendWithTemplate(phoneNumber, templateIdStr, params);
     }
 
     /**
@@ -82,9 +81,7 @@ public class NotifyService {
         if (smsSender == null)
             return null;
 
-        int templateId = Integer.parseInt(getTemplateId(notifyType, smsTemplate));
-
-        return smsSender.sendWithTemplate(phoneNumber, templateId, params);
+        return smsSender.sendWithTemplate(phoneNumber, getTemplateId(notifyType, smsTemplate), params);
     }
 
     /**

+ 2 - 3
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SmsSender.java

@@ -13,10 +13,9 @@ public interface SmsSender {
 
     /**
      * 通过短信模版发送短信息
-     *
-     * @param phone      接收通知的电话号码
+     *  @param phone      接收通知的电话号码
      * @param templateId 通知模板ID
      * @param params     通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
      */
-    SmsResult sendWithTemplate(String phone, int templateId, String[] params);
+    SmsResult sendWithTemplate(String phone, String templateId, String[] params);
 }

+ 13 - 4
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/TencentSmsSender.java

@@ -15,6 +15,7 @@ public class TencentSmsSender implements SmsSender {
     private final Log logger = LogFactory.getLog(TencentSmsSender.class);
 
     private SmsSingleSender sender;
+    private String sign;
 
     public SmsSingleSender getSender() {
         return sender;
@@ -38,13 +39,15 @@ public class TencentSmsSender implements SmsSender {
             logger.error(e.getMessage(), e);
         }
 
-        return null;
+        SmsResult smsResult = new SmsResult();
+        smsResult.setSuccessful(false);
+        return smsResult;
     }
 
     @Override
-    public SmsResult sendWithTemplate(String phone, int templateId, String[] params) {
+    public SmsResult sendWithTemplate(String phone, String templateId, String[] params) {
         try {
-            SmsSingleSenderResult result = sender.sendWithParam("86", phone, templateId, params, "", "", "");
+            SmsSingleSenderResult result = sender.sendWithParam("86", phone, Integer.parseInt(templateId), params, this.sign, "", "");
             logger.debug(result);
 
             SmsResult smsResult = new SmsResult();
@@ -55,6 +58,12 @@ public class TencentSmsSender implements SmsSender {
             logger.error(e.getMessage(), e);
         }
 
-        return null;
+        SmsResult smsResult = new SmsResult();
+        smsResult.setSuccessful(false);
+        return smsResult;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
     }
 }

+ 23 - 2
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/config/NotifyAutoConfiguration.java

@@ -1,6 +1,7 @@
 package org.linlinjava.litemall.core.notify.config;
 
 import com.github.qcloudsms.SmsSingleSender;
+import org.linlinjava.litemall.core.notify.AliyunSmsSender;
 import org.linlinjava.litemall.core.notify.NotifyService;
 import org.linlinjava.litemall.core.notify.TencentSmsSender;
 import org.linlinjava.litemall.core.notify.WxTemplateSender;
@@ -33,7 +34,13 @@ public class NotifyAutoConfiguration {
 
         NotifyProperties.Sms smsConfig = properties.getSms();
         if (smsConfig.isEnable()) {
-            notifyService.setSmsSender(tencentSmsSender());
+            if(smsConfig.getActive().equals("tencent")) {
+                notifyService.setSmsSender(tencentSmsSender());
+            }
+            else if(smsConfig.getActive().equals("aliyun")) {
+                notifyService.setSmsSender(aliyunSmsSender());
+            }
+
             notifyService.setSmsTemplate(smsConfig.getTemplate());
         }
 
@@ -65,7 +72,21 @@ public class NotifyAutoConfiguration {
     public TencentSmsSender tencentSmsSender() {
         NotifyProperties.Sms smsConfig = properties.getSms();
         TencentSmsSender smsSender = new TencentSmsSender();
-        smsSender.setSender(new SmsSingleSender(smsConfig.getAppid(), smsConfig.getAppkey()));
+        NotifyProperties.Sms.Tencent tencent = smsConfig.getTencent();
+        smsSender.setSender(new SmsSingleSender(tencent.getAppid(), tencent.getAppkey()));
+        smsSender.setSign(smsConfig.getSign());
+        return smsSender;
+    }
+
+    @Bean
+    public AliyunSmsSender aliyunSmsSender() {
+        NotifyProperties.Sms smsConfig = properties.getSms();
+        AliyunSmsSender smsSender = new AliyunSmsSender();
+        NotifyProperties.Sms.Aliyun aliyun = smsConfig.getAliyun();
+        smsSender.setSign(smsConfig.getSign());
+        smsSender.setRegionId(aliyun.getRegionId());
+        smsSender.setAccessKeyId(aliyun.getAccessKeyId());
+        smsSender.setAccessKeySecret(aliyun.getAccessKeySecret());
         return smsSender;
     }
 }

+ 83 - 14
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/config/NotifyProperties.java

@@ -95,8 +95,10 @@ public class NotifyProperties {
 
     public static class Sms {
         private boolean enable;
-        private int appid;
-        private String appkey;
+        private String active;
+        private String sign;
+        private Tencent tencent;
+        private Aliyun aliyun;
         private List<Map<String, String>> template = new ArrayList<>();
 
         public boolean isEnable() {
@@ -107,28 +109,95 @@ public class NotifyProperties {
             this.enable = enable;
         }
 
-        public int getAppid() {
-            return appid;
+        public List<Map<String, String>> getTemplate() {
+            return template;
         }
 
-        public void setAppid(int appid) {
-            this.appid = appid;
+        public void setTemplate(List<Map<String, String>> template) {
+            this.template = template;
         }
 
-        public String getAppkey() {
-            return appkey;
+        public String getActive() {
+            return active;
         }
 
-        public void setAppkey(String appkey) {
-            this.appkey = appkey;
+        public void setActive(String active) {
+            this.active = active;
         }
 
-        public List<Map<String, String>> getTemplate() {
-            return template;
+        public String getSign() {
+            return sign;
         }
 
-        public void setTemplate(List<Map<String, String>> template) {
-            this.template = template;
+        public void setSign(String sign) {
+            this.sign = sign;
+        }
+
+        public Tencent getTencent() {
+            return tencent;
+        }
+
+        public void setTencent(Tencent tencent) {
+            this.tencent = tencent;
+        }
+
+        public Aliyun getAliyun() {
+            return aliyun;
+        }
+
+        public void setAliyun(Aliyun aliyun) {
+            this.aliyun = aliyun;
+        }
+
+        public static class Tencent {
+            private int appid;
+            private String appkey;
+
+            public int getAppid() {
+                return appid;
+            }
+
+            public void setAppid(int appid) {
+                this.appid = appid;
+            }
+
+            public String getAppkey() {
+                return appkey;
+            }
+
+            public void setAppkey(String appkey) {
+                this.appkey = appkey;
+            }
+        }
+
+        public static class Aliyun {
+            private String regionId;
+            private String accessKeyId;
+            private String accessKeySecret;
+
+            public String getRegionId() {
+                return regionId;
+            }
+
+            public void setRegionId(String regionId) {
+                this.regionId = regionId;
+            }
+
+            public String getAccessKeyId() {
+                return accessKeyId;
+            }
+
+            public void setAccessKeyId(String accessKeyId) {
+                this.accessKeyId = accessKeyId;
+            }
+
+            public String getAccessKeySecret() {
+                return accessKeySecret;
+            }
+
+            public void setAccessKeySecret(String accessKeySecret) {
+                this.accessKeySecret = accessKeySecret;
+            }
         }
     }
 

+ 10 - 0
litemall-core/src/main/java/org/linlinjava/litemall/core/util/JacksonUtil.java

@@ -1,5 +1,6 @@
 package org.linlinjava.litemall.core.util;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -161,4 +162,13 @@ public class JacksonUtil {
         return null;
     }
 
+    public static String toJson(Object data) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            return objectMapper.writeValueAsString(data);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }

+ 17 - 7
litemall-core/src/main/resources/application-core.yml

@@ -25,8 +25,10 @@ litemall:
     # 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
     sms:
       enable: false
-      appid: 111111111
-      appkey: xxxxxxxxxxxxxx
+      # 如果是腾讯云短信,则设置active的值tencent
+      # 如果是阿里云短信,则设置active的值aliyun
+      active: tencent
+      sign: litemall
       template:
       - name: paySucceed
         templateId: 156349
@@ -36,6 +38,14 @@ litemall:
         templateId: 158002
       - name: refund
         templateId: 159447
+      tencent:
+        appid: 111111111
+        appkey: xxxxxxxxxxxxxx
+      aliyun:
+        regionId: xxx
+        accessKeyId: xxx
+        accessKeySecret: xxx
+
 
     # 微信模版通知配置
     # 微信模版用于通知客户或者运营者,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
@@ -87,7 +97,7 @@ litemall:
   # 对象存储配置
   storage:
     # 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniu
-    active: local
+    active: tencent
     # 本地对象存储配置信息
     local:
       storagePath: storage
@@ -102,10 +112,10 @@ litemall:
     # 腾讯对象存储配置信息
     # 请参考 https://cloud.tencent.com/document/product/436/6249
     tencent:
-      secretId: 111111
-      secretKey: xxxxxx
-      region: xxxxxx
-      bucketName: litemall
+      secretId: AKIDOccMr856uoU1Tsa2MQL5aqseBUWRrb5i
+      secretKey: XqtgEhIdrupTs4ygaWlkUUXv3w3FiwuD
+      region: ap-shanghai
+      bucketName: vytech-1300096589
     # 七牛云对象存储配置信息
     qiniu:
       endpoint: http://pd5cb6ulu.bkt.clouddn.com