parent
							
								
									e8e4a4781c
								
							
						
					
					
						commit
						74724637b7
					
				|  | @ -330,7 +330,7 @@ public class OrderServiceImpl implements OrderService { | |||
| //        if (commonResult.isError()) {
 | ||||
| //            //手动开启事务回滚
 | ||||
| //            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
 | ||||
| //            return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_PAY_FAIL.getCode());
 | ||||
| //            return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_PAY_FAIL.getValue());
 | ||||
| //        }
 | ||||
| 
 | ||||
|         // TODO: 2019-03-17 Sin 需要发送 创建成果 MQ 消息,业务扩展和统计
 | ||||
|  |  | |||
|  | @ -1,116 +0,0 @@ | |||
| package cn.iocoder.mall.admin.api; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import lombok.experimental.Accessors; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * 短信平台 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 6:33 PM | ||||
|  */ | ||||
| public interface SmsPlatform { | ||||
| 
 | ||||
|     @Data | ||||
|     @Accessors(chain = true) | ||||
|     class Result { | ||||
|         /** | ||||
|          * 编号 | ||||
|          */ | ||||
|         private String id; | ||||
|         /** | ||||
|          * 审核状态 | ||||
|          */ | ||||
|         private Integer applyStatus; | ||||
|         /** | ||||
|          * 审核内容 | ||||
|          */ | ||||
|         private String applyMessage; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 创建 | ||||
|      * | ||||
|      * @param sign | ||||
|      */ | ||||
|     Result createSign(String sign); | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 获取 | ||||
|      * | ||||
|      * @param sign | ||||
|      */ | ||||
|     Result getSign(String sign); | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 更新 | ||||
|      * | ||||
|      * @param oldSign | ||||
|      * @param sign | ||||
|      */ | ||||
|     Result updateSign(String oldSign, String sign); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 创建 | ||||
|      * | ||||
|      * @param template 模板内容 | ||||
|      * @param tplType 1 为验证码类型,其他为 null | ||||
|      */ | ||||
|     Result createTemplate(String template, Integer tplType); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 获取 | ||||
|      * | ||||
|      * @param tplId | ||||
|      */ | ||||
|     Result getTemplate(String tplId); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 更新 | ||||
|      * | ||||
|      * @param tplId 选用的哪个签名 | ||||
|      * @param template 模板内容 | ||||
|      * @param tplType 1 为验证码类型,其他为 null | ||||
|      */ | ||||
|     Result updateTemplate(String tplId, String template, Integer tplType); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 删除 | ||||
|      * | ||||
|      * @param tplId | ||||
|      * @return | ||||
|      */ | ||||
|     Result deleteTemplate(String tplId); | ||||
| 
 | ||||
| 
 | ||||
|     @Data | ||||
|     @Accessors(chain = true) | ||||
|     class SendResult { | ||||
| 
 | ||||
|         private Boolean hasSuccess; | ||||
| 
 | ||||
|         private Integer code; | ||||
| 
 | ||||
|         private String message; | ||||
| 
 | ||||
|         private List<String> success; | ||||
| 
 | ||||
|         private List<String> fail; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 短信发送 - 单个 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     SendResult singleSend(String mobile, String template); | ||||
| 
 | ||||
|     /** | ||||
|      * 短信发送 - 批量 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     SendResult batchSend(List<String> mobileList, String template); | ||||
| } | ||||
|  | @ -39,47 +39,56 @@ public interface SmsService { | |||
|      * | ||||
|      * @param sign | ||||
|      */ | ||||
|     void createSign(String sign); | ||||
|     void createSign(String sign, Integer platform); | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 获取 | ||||
|      * | ||||
|      * @param sign | ||||
|      * @param id | ||||
|      */ | ||||
|     SmsSignBO getSign(String sign); | ||||
|     SmsSignBO getSign(Integer id); | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 更新 | ||||
|      * | ||||
|      * @param oldSign | ||||
|      * @param sign | ||||
|      * @param id | ||||
|      * @param newSign | ||||
|      * @param platform | ||||
|      */ | ||||
|     void updateSign(String oldSign, String sign); | ||||
|     void updateSign(Integer id, String newSign, Integer platform); | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 更新 | ||||
|      * | ||||
|      * @param id | ||||
|      */ | ||||
|     void deleteSign(Integer id); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 创建 | ||||
|      * | ||||
|      * @param smsSignId 选用的哪个签名 | ||||
|      * @param template 模板内容 | ||||
|      * @param tplType 1 为验证码类型,其他为 null | ||||
|      * @param platform 平台 | ||||
|      */ | ||||
|     void createTemplate(Integer smsSignId, String template, Integer tplType); | ||||
|     void createTemplate(Integer smsSignId, String template, Integer platform, Integer smsType); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 获取 | ||||
|      * | ||||
|      * @param id | ||||
|      */ | ||||
|     SmsTemplateBO getTemplate(Integer id); | ||||
|     SmsTemplateBO getTemplate(Integer id, Integer platform); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 更新 | ||||
|      * | ||||
|      * @param id 模板id | ||||
|      * @param smsSignId 短期签名 | ||||
|      * @param template 模板内容 | ||||
|      * @param tplType 1 为验证码类型,其他为 null | ||||
|      * @param platform 短信平台 | ||||
|      */ | ||||
|     void updateTemplate(Integer id, String template, Integer tplType); | ||||
|     void updateTemplate(Integer id, Integer smsSignId, String template, Integer platform, Integer smsType); | ||||
| 
 | ||||
|     /** | ||||
|      * 模板 - 删除 | ||||
|  |  | |||
|  | @ -56,6 +56,7 @@ public enum AdminErrorCodeEnum { | |||
|     SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"), | ||||
|     SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"), | ||||
|     SMS_TEMPLATE_IS_EXISTENT(1002006021, "短信签名不存在"), | ||||
|     SMS_NOT_SEND_CLIENT(1002006030, "短信没有发送的client"), | ||||
|     ; | ||||
| 
 | ||||
|     private final int code; | ||||
|  |  | |||
|  | @ -0,0 +1,11 @@ | |||
| package cn.iocoder.mall.admin.api.constant; | ||||
| 
 | ||||
| /** | ||||
|  * 字典 key | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/25 3:36 PM | ||||
|  */ | ||||
| public class DictKeyConstants { | ||||
| 
 | ||||
| } | ||||
|  | @ -13,19 +13,19 @@ public enum SmsApplyStatusEnum { | |||
|     FAIL(3, "审核失败"), | ||||
|     ; | ||||
| 
 | ||||
|     private final int code; | ||||
|     private final String message; | ||||
|     private final Integer value; | ||||
|     private final String name; | ||||
| 
 | ||||
|     SmsApplyStatusEnum(int code, String message) { | ||||
|         this.code = code; | ||||
|         this.message = message; | ||||
|         this.value = code; | ||||
|         this.name = message; | ||||
|     } | ||||
| 
 | ||||
|     public int getCode() { | ||||
|         return code; | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public String getMessage() { | ||||
|         return message; | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,30 @@ | |||
| package cn.iocoder.mall.admin.api.constant; | ||||
| 
 | ||||
| /** | ||||
|  * 短信审核状态 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 12:48 PM | ||||
|  */ | ||||
| public enum SmsPlatformEnum { | ||||
| 
 | ||||
|     YunPian(1, "云片"), | ||||
|     AliYun(2, "阿里云"), | ||||
|     ; | ||||
| 
 | ||||
|     private final Integer value; | ||||
|     private final String name; | ||||
| 
 | ||||
|     SmsPlatformEnum(Integer code, String message) { | ||||
|         this.value = code; | ||||
|         this.name = message; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| package cn.iocoder.mall.admin.api.constant; | ||||
| 
 | ||||
| /** | ||||
|  * 短信审核状态 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 12:48 PM | ||||
|  */ | ||||
| public enum SmsTypeEnum { | ||||
| 
 | ||||
|     VERIFICATION_CODE(1, "验证码"), | ||||
|     NOTICE(1, "通知"), | ||||
|     MARKETING(2, "营销"), | ||||
|     ; | ||||
| 
 | ||||
|     private final Integer value; | ||||
|     private final String name; | ||||
| 
 | ||||
|     SmsTypeEnum(Integer code, String message) { | ||||
|         this.value = code; | ||||
|         this.name = message; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| } | ||||
|  | @ -31,7 +31,6 @@ | |||
|             <groupId>org.springframework</groupId> | ||||
|             <artifactId>spring-jdbc</artifactId> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>com.alibaba</groupId> | ||||
|             <artifactId>druid-spring-boot-starter</artifactId> | ||||
|  | @ -72,12 +71,22 @@ | |||
|             <artifactId>yunpian-java-sdk</artifactId> | ||||
|             <version>1.2.7</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.aliyun</groupId> | ||||
|             <artifactId>aliyun-java-sdk-core</artifactId> | ||||
|             <version>4.1.0</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!--  test  --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.junit.jupiter</groupId> | ||||
|             <artifactId>junit-jupiter-api</artifactId> | ||||
|             <version>5.4.0</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|  |  | |||
|  | @ -0,0 +1,83 @@ | |||
| package cn.iocoder.mall.admin.client; | ||||
| 
 | ||||
| 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.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Component; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 短信 AliYun client | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/25 12:28 PM | ||||
|  */ | ||||
| @Component | ||||
| public class SmsAliYunClient implements SmsClient { | ||||
| 
 | ||||
|     @Value("sms.aliYun.accessKeyId") | ||||
|     private String accessKeyId; | ||||
|     @Value("sms.aliYun.accessSecret") | ||||
|     private String accessSecret; | ||||
| 
 | ||||
|     private static final String DOMAIN = "dysmsapi.aliyuncs.com"; | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult singleSend(String mobile, String sign, String template, Map<String, String> params) { | ||||
|         IAcsClient client = getClient(); | ||||
|         CommonRequest request = new CommonRequest(); | ||||
|         request.setMethod(MethodType.POST); | ||||
|         request.setDomain(DOMAIN); | ||||
|         request.setVersion("2017-05-25"); | ||||
|         request.setAction("SendSms"); | ||||
| 
 | ||||
|         try { | ||||
|             CommonResponse response = client.getCommonResponse(request); | ||||
|             System.out.println(response.getData()); | ||||
|         } catch (ClientException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult batchSend(List<String> mobileList, String sign, String template, Map<String, String> params) { | ||||
| 
 | ||||
|         // 获取 client
 | ||||
|         IAcsClient client = getClient(); | ||||
| 
 | ||||
|         // params
 | ||||
|         CommonRequest request = new CommonRequest(); | ||||
|         request.setMethod(MethodType.POST); | ||||
|         request.setDomain(DOMAIN); | ||||
|         request.setVersion("2017-05-25"); | ||||
|         request.setAction("SendBatchSms"); | ||||
| 
 | ||||
|         try { | ||||
|             CommonResponse response = client.getCommonResponse(request); | ||||
|             System.out.println(response.getData()); | ||||
|         } catch (ServerException e) { | ||||
|             e.printStackTrace(); | ||||
|         } catch (ClientException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取 client | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     private IAcsClient getClient() { | ||||
|         return new DefaultAcsClient(DefaultProfile.getProfile("default", accessKeyId, accessSecret)); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,41 @@ | |||
| package cn.iocoder.mall.admin.client; | ||||
| 
 | ||||
| import lombok.Data; | ||||
| import lombok.experimental.Accessors; | ||||
| 
 | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 短信平台 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 6:33 PM | ||||
|  */ | ||||
| public interface SmsClient { | ||||
| 
 | ||||
|     @Data | ||||
|     @Accessors(chain = true) | ||||
|     class SendResult { | ||||
| 
 | ||||
|         private Boolean isSuccess; | ||||
| 
 | ||||
|         private Integer code; | ||||
| 
 | ||||
|         private String message; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 短信发送 - 单个 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     SendResult singleSend(String mobile, String sign, String template, Map<String, String> params); | ||||
| 
 | ||||
|     /** | ||||
|      * 短信发送 - 批量 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     SendResult batchSend(List<String> mobileList, String sign, String template, Map<String, String> params); | ||||
| } | ||||
|  | @ -0,0 +1,264 @@ | |||
| package cn.iocoder.mall.admin.client; | ||||
| 
 | ||||
| import cn.iocoder.common.framework.exception.ServiceException; | ||||
| import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsApplyStatusEnum; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import org.apache.http.HttpEntity; | ||||
| import org.apache.http.NameValuePair; | ||||
| import org.apache.http.client.entity.UrlEncodedFormEntity; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpPost; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | ||||
| import org.apache.http.message.BasicNameValuePair; | ||||
| import org.apache.http.util.EntityUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 云片 短信平台 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 6:34 PM | ||||
|  */ | ||||
| @Component | ||||
| public class SmsYunPianClient implements SmsClient { | ||||
| 
 | ||||
|     protected static final Logger LOGGER = LoggerFactory.getLogger(SmsYunPianClient.class); | ||||
| 
 | ||||
|     private static final int SUCCESS_CODE = 0; | ||||
| 
 | ||||
|     /** | ||||
|      * 云片短信 - 批量推送最大数 500,支持 1000 | ||||
|      */ | ||||
|     private static final int MAX_BATCH_SIZE = 500; | ||||
|     /** | ||||
|      * 模板 - 参数拼接 | ||||
|      */ | ||||
|     private static final String PARAM_TEMPLATE = "#%s#"; | ||||
|     /** | ||||
|      * 模板 - 签名拼接 | ||||
|      */ | ||||
|     private static final String SIGN_TEMPLATE = "【%s】%s"; | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 添加 | ||||
|      */ | ||||
|     private static final String URL_SIGN_ADD = "https://sms.yunpian.com/v2/sign/add.json"; | ||||
|     /** | ||||
|      * 签名 - 获取 | ||||
|      */ | ||||
|     private static final String URL_SIGN_GET = "https://sms.yunpian.com/v2/sign/get.json"; | ||||
|     /** | ||||
|      * 签名 - 更新 | ||||
|      */ | ||||
|     private static final String URL_SIGN_UPDATE = "https://sms.yunpian.com/v2/sign/update.json"; | ||||
|     /** | ||||
|      * 模板 - 添加 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_ADD = "https://sms.yunpian.com/v2/tpl/add.json"; | ||||
|     /** | ||||
|      * 模板 - 获取 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_GET = "https://sms.yunpian.com/v2/tpl/get.json"; | ||||
|     /** | ||||
|      * 模板 - 更新 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_UPDATE = "https://sms.yunpian.com/v2/tpl/update.json"; | ||||
|     /** | ||||
|      * 模板 - 删除 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_DELETE = "https://sms.yunpian.com/v2/tpl/del.json"; | ||||
|     /** | ||||
|      * 短信发送 - 单个 | ||||
|      */ | ||||
|     private static final String URL_SEND_SINGLE = "https://sms.yunpian.com/v2/sms/single_send.json"; | ||||
|     /** | ||||
|      * 短信发送 - 批量 | ||||
|      */ | ||||
|     private static final String URL_SEND_BATCH = "https://sms.yunpian.com/v2/sms/batch_send.json"; | ||||
| 
 | ||||
| 
 | ||||
|     //编码格式。发送编码格式统一用UTF-8
 | ||||
|     private static String ENCODING = "UTF-8"; | ||||
| 
 | ||||
|     @Value("${sms.yunPian.apiKey}") | ||||
|     private String apiKey; | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult singleSend(String mobile, String sign, String template, Map<String, String> templateParams) { | ||||
| 
 | ||||
|         // build 模板
 | ||||
|         template = buildTemplate(sign, template, templateParams); | ||||
| 
 | ||||
|         // 请求参数
 | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("mobile", mobile); | ||||
|         params.put("text", template); | ||||
|         // TODO: 2019/5/19 sin 运营商发送报告 回调
 | ||||
|         // params.put("callback_url", template);
 | ||||
|         String result = post(URL_SEND_SINGLE, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         return new SendResult() | ||||
|                 .setIsSuccess(SUCCESS_CODE == jsonObject.getInteger("code")) | ||||
|                 .setCode(jsonObject.getInteger("code")) | ||||
|                 .setMessage(jsonObject.getString("detail")); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult batchSend(List<String> mobileList, String sign, String template, Map<String, String> templateParams) { | ||||
| 
 | ||||
|         // build 模板
 | ||||
|         template = buildTemplate(sign, template, templateParams); | ||||
| 
 | ||||
|         // 最大发送数为 1000,我们设置为 500 个, 分段发送
 | ||||
|         int maxSendSize = MAX_BATCH_SIZE; | ||||
|         int maxSendSizeCount = mobileList.size() % maxSendSize; | ||||
|         int j = 0; | ||||
|         int j2 = mobileList.size(); | ||||
| 
 | ||||
|         for (int i = 0; i < maxSendSizeCount; i++) { | ||||
|             StringBuffer sendMobileStr = new StringBuffer(); | ||||
|             for (int k = j; k < j2; k++) { | ||||
|                 sendMobileStr.append(","); | ||||
|                 sendMobileStr.append(mobileList.get(k)); | ||||
|             } | ||||
| 
 | ||||
|             String dividedMobile = sendMobileStr.toString().substring(1); | ||||
| 
 | ||||
|             // 发送手机号
 | ||||
|             Map<String, String> params = new LinkedHashMap<>(); | ||||
|             params.put("apikey", apiKey); | ||||
|             params.put("mobile", dividedMobile); | ||||
|             params.put("text", template); | ||||
|             // TODO: 2019/5/19 sin 运营商发送报告 回调
 | ||||
|             // params.put("callback_url", template);
 | ||||
|             String result = post(URL_SEND_BATCH, params); | ||||
|             JSONObject jsonObject = JSON.parseObject(result); | ||||
|             if (jsonObject.containsKey("code") | ||||
|                     && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|                 throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                         jsonObject.getString("detail")); | ||||
|             } | ||||
| 
 | ||||
|             // 用于递增 maxSendSize
 | ||||
|             j = j2; | ||||
|             j2 = j + maxSendSize; | ||||
|         } | ||||
| 
 | ||||
|         return new SendResult() | ||||
|                 .setIsSuccess(true) | ||||
|                 .setCode(SUCCESS_CODE) | ||||
|                 .setMessage(null); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 构建模板 | ||||
|      * | ||||
|      * @param sign | ||||
|      * @param template | ||||
|      * @param params | ||||
|      * @return | ||||
|      */ | ||||
|     private static String buildTemplate(String sign, String template, Map<String, String> params) { | ||||
|         if (CollectionUtils.isEmpty(params)) { | ||||
|             return template; | ||||
|         } | ||||
| 
 | ||||
|         LOGGER.debug("模板构建 before -> {}", template); | ||||
| 
 | ||||
|         for (Map.Entry<String, String> entry : params.entrySet()) { | ||||
|             String paramsKey = entry.getKey(); | ||||
|             String value = entry.getValue(); | ||||
|             String paramPlace = String.format(PARAM_TEMPLATE, paramsKey); | ||||
|             template = template.replaceAll(paramPlace, value); | ||||
|         } | ||||
| 
 | ||||
|         template = String.format(SIGN_TEMPLATE, sign, template); | ||||
|         LOGGER.debug("模板构建 after -> {}", template); | ||||
|         return template; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 短信 status 和 云片状态 映射关系 | ||||
|      * | ||||
|      * @param checkStatus | ||||
|      * @return | ||||
|      */ | ||||
|     private static Integer smsStatusMapping(String checkStatus) { | ||||
|         Integer applyStatus; | ||||
|         switch (checkStatus) { | ||||
|             case "SUCCESS": | ||||
|                 applyStatus = SmsApplyStatusEnum.SUCCESS.getValue(); | ||||
|                 break; | ||||
|             case "FAIL": | ||||
|                 applyStatus = SmsApplyStatusEnum.FAIL.getValue(); | ||||
|                 break; | ||||
|             default: | ||||
|                 applyStatus = SmsApplyStatusEnum.CHECKING.getValue(); | ||||
|                 break; | ||||
|         } | ||||
|         return applyStatus; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 基于HttpClient 4.3的通用POST方法 | ||||
|      * | ||||
|      * @param url       提交的URL | ||||
|      * @param paramsMap 提交<参数,值>Map | ||||
|      * @return 提交响应 | ||||
|      */ | ||||
| 
 | ||||
|     public static String post(String url, Map<String, String> paramsMap) { | ||||
| 
 | ||||
|         // TODO: 2019/5/25 Sin 这个地方需要 记录日志
 | ||||
|         CloseableHttpClient client = HttpClients.createDefault(); | ||||
|         String responseText = ""; | ||||
|         CloseableHttpResponse response = null; | ||||
|         try { | ||||
|             HttpPost method = new HttpPost(url); | ||||
|             if (paramsMap != null) { | ||||
|                 List<NameValuePair> paramList = new ArrayList<>(); | ||||
|                 for (Map.Entry<String, String> param : paramsMap.entrySet()) { | ||||
|                     NameValuePair pair = new BasicNameValuePair(param.getKey(), | ||||
|                             param.getValue()); | ||||
|                     paramList.add(pair); | ||||
|                 } | ||||
|                 method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING)); | ||||
|             } | ||||
|             response = client.execute(method); | ||||
|             HttpEntity entity = response.getEntity(); | ||||
|             if (entity != null) { | ||||
|                 responseText = EntityUtils.toString(entity, ENCODING); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|         } finally { | ||||
|             try { | ||||
|                 response.close(); | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         LOGGER.debug("云片短信平台 res: {}", responseText); | ||||
|         return responseText; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,33 @@ | |||
| package cn.iocoder.mall.admin.dataobject; | ||||
| 
 | ||||
| import cn.iocoder.common.framework.dataobject.BaseDO; | ||||
| import lombok.Data; | ||||
| import lombok.experimental.Accessors; | ||||
| 
 | ||||
| /** | ||||
|  * 短信 client log | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/25 12:36 PM | ||||
|  */ | ||||
| @Data | ||||
| @Accessors(chain = true) | ||||
| public class SmsClientLog extends BaseDO { | ||||
| 
 | ||||
|     /** | ||||
|      * 编号 | ||||
|      */ | ||||
|     private Integer id; | ||||
|     /** | ||||
|      * 短信模板 | ||||
|      */ | ||||
|     private Integer templateId; | ||||
|     /** | ||||
|      * 短信 | ||||
|      */ | ||||
|     private String template; | ||||
|     /** | ||||
|      * 发送信息 | ||||
|      */ | ||||
|     private String message; | ||||
| } | ||||
|  | @ -22,14 +22,17 @@ public class SmsSignDO extends DeletableDO { | |||
|      * 编号 | ||||
|      */ | ||||
|     private Integer id; | ||||
|     /** | ||||
|      * 签名id 这个是第三方的 | ||||
|      */ | ||||
|     private String platformId; | ||||
|     /** | ||||
|      * 签名名称 | ||||
|      */ | ||||
|     private String sign; | ||||
|     /** | ||||
|      * 平台 | ||||
|      * | ||||
|      * 1、云片 | ||||
|      * 2、阿里云 | ||||
|      */ | ||||
|     private Integer platform; | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      * | ||||
|  |  | |||
|  | @ -28,11 +28,19 @@ public class SmsTemplateDO extends DeletableDO { | |||
|     /** | ||||
|      * 短信签名 id | ||||
|      */ | ||||
|     private String platformId; | ||||
|     private Integer platform; | ||||
|     /** | ||||
|      * 短信模板 | ||||
|      */ | ||||
|     private String template; | ||||
|     /** | ||||
|      * 短信类型 | ||||
|      * | ||||
|      * - 验证码类 | ||||
|      * - 通知类 | ||||
|      * - 营销类 | ||||
|      */ | ||||
|     private Integer smsType; | ||||
|     /** | ||||
|      * 审核状态 | ||||
|      * | ||||
|  |  | |||
|  | @ -2,7 +2,10 @@ package cn.iocoder.mall.admin.service; | |||
| 
 | ||||
| import cn.iocoder.common.framework.constant.DeletedStatusEnum; | ||||
| import cn.iocoder.common.framework.exception.ServiceException; | ||||
| import cn.iocoder.mall.admin.api.SmsPlatform; | ||||
| import cn.iocoder.mall.admin.api.DataDictService; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsApplyStatusEnum; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsPlatformEnum; | ||||
| import cn.iocoder.mall.admin.client.SmsClient; | ||||
| import cn.iocoder.mall.admin.api.SmsService; | ||||
| import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO; | ||||
| import cn.iocoder.mall.admin.api.bo.sms.PageSmsSignBO; | ||||
|  | @ -49,8 +52,13 @@ public class SmsServiceImpl implements SmsService { | |||
|     private SmsTemplateMapper smsTemplateMapper; | ||||
| 
 | ||||
|     @Autowired | ||||
|     @Qualifier("smsYunPianPlatform") | ||||
|     private SmsPlatform smsPlatform; | ||||
|     @Qualifier("smsYunPianClient") | ||||
|     private SmsClient smsYunPianClient; | ||||
|     @Autowired | ||||
|     @Qualifier("smsAliYunClient") | ||||
|     private SmsClient smsAliYunClient; | ||||
|     @Autowired | ||||
|     private DataDictService dataDictService; | ||||
| 
 | ||||
|     @Override | ||||
|     public PageSmsSignBO pageSmsSign(PageQuerySmsSignDTO queryDTO) { | ||||
|  | @ -108,26 +116,26 @@ public class SmsServiceImpl implements SmsService { | |||
| 
 | ||||
|     @Override | ||||
|     @Transactional | ||||
|     public void createSign(String sign) { | ||||
|     public void createSign(String sign, Integer platform) { | ||||
| 
 | ||||
|         // 避免重复
 | ||||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("sign", sign)); | ||||
|                 new QueryWrapper<SmsSignDO>() | ||||
|                         .eq("platform", platform) | ||||
|                         .eq("sign", sign) | ||||
|                         ); | ||||
| 
 | ||||
|         if (smsSignDO != null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 创建平台 sign
 | ||||
|         SmsPlatform.Result result = smsPlatform.createSign(sign); | ||||
| 
 | ||||
|         // 保存数据库
 | ||||
|         smsSignMapper.insert( | ||||
|                 (SmsSignDO) new SmsSignDO() | ||||
|                         .setSign(sign) | ||||
|                         .setPlatformId(result.getId()) | ||||
|                         .setApplyStatus(result.getApplyStatus()) | ||||
|                         .setPlatform(platform) | ||||
|                         .setApplyStatus(SmsApplyStatusEnum.SUCCESS.getValue()) | ||||
|                         .setDeleted(DeletedStatusEnum.DELETED_NO.getValue()) | ||||
|                         .setUpdateTime(new Date()) | ||||
|                         .setCreateTime(new Date()) | ||||
|  | @ -135,9 +143,11 @@ public class SmsServiceImpl implements SmsService { | |||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SmsSignBO getSign(String sign) { | ||||
|     public SmsSignBO getSign(Integer signId) { | ||||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("sign", sign)); | ||||
|                 new QueryWrapper<SmsSignDO>() | ||||
|                         .eq("id", signId) | ||||
|                         .eq("deleted", DeletedStatusEnum.DELETED_NO.getValue())); | ||||
| 
 | ||||
|         if (smsSignDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|  | @ -149,33 +159,49 @@ public class SmsServiceImpl implements SmsService { | |||
| 
 | ||||
|     @Override | ||||
|     @Transactional | ||||
|     public void updateSign(String oldSign, String sign) { | ||||
|     public void updateSign(Integer id, String newSign, Integer platform) { | ||||
|         // 避免重复
 | ||||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("sign", oldSign)); | ||||
|                 new QueryWrapper<SmsSignDO>() | ||||
|                         .eq("sign", newSign) | ||||
|                         .eq("platform", platform)); | ||||
| 
 | ||||
|         if (smsSignDO != null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_IS_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 更新
 | ||||
|         smsSignMapper.update( | ||||
|                 (SmsSignDO) new SmsSignDO() | ||||
|                         .setSign(newSign) | ||||
|                         .setPlatform(platform) | ||||
|                         .setUpdateTime(new Date()), | ||||
|                 new QueryWrapper<SmsSignDO>().eq("id", id) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void deleteSign(Integer id) { | ||||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>() | ||||
|                         .eq("id", id)); | ||||
| 
 | ||||
|         if (smsSignDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 更新平台
 | ||||
|         SmsPlatform.Result result = smsPlatform.updateSign(oldSign, sign); | ||||
| 
 | ||||
|         // 更新
 | ||||
|         smsSignMapper.updateById( | ||||
|                 (SmsSignDO) new SmsSignDO() | ||||
|                         .setId(smsSignDO.getId()) | ||||
|                         .setPlatformId(result.getId()) | ||||
|                         .setSign(sign) | ||||
|                         .setApplyStatus(result.getApplyStatus()) | ||||
|                         .setUpdateTime(new Date()) | ||||
|         // 更新 deleted 为 YES
 | ||||
|         smsSignMapper.delete(new UpdateWrapper<SmsSignDO>() | ||||
|                 .set("deleted", DeletedStatusEnum.DELETED_YES.getName()) | ||||
|                 .eq("id", id) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     @Transactional | ||||
|     public void createTemplate(Integer smsSignId, String template, Integer tplType) { | ||||
|     public void createTemplate(Integer smsSignId, String template, Integer platform, Integer smsType) { | ||||
| 
 | ||||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("id", smsSignId)); | ||||
|  | @ -185,28 +211,27 @@ public class SmsServiceImpl implements SmsService { | |||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 调用平台
 | ||||
|         SmsPlatform.Result result = smsPlatform | ||||
|                 .createTemplate(String.format(SMS_TEMPLATE, smsSignDO.getSign(), template), tplType); | ||||
| 
 | ||||
|         // 保存数据库
 | ||||
|         smsTemplateMapper.insert( | ||||
|                 (SmsTemplateDO) new SmsTemplateDO() | ||||
|                         .setId(null) | ||||
|                         .setSmsSignId(smsSignId) | ||||
|                         .setPlatformId(result.getId()) | ||||
|                         .setTemplate(template) | ||||
|                         .setApplyStatus(result.getApplyStatus()) | ||||
|                         .setApplyMessage(result.getApplyMessage()) | ||||
|                         .setPlatform(platform) | ||||
|                         .setSmsType(smsType) | ||||
|                         .setApplyStatus(SmsApplyStatusEnum.SUCCESS.getValue()) | ||||
|                         .setApplyMessage("") | ||||
|                         .setDeleted(DeletedStatusEnum.DELETED_NO.getValue()) | ||||
|                         .setCreateTime(new Date()) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SmsTemplateBO getTemplate(Integer id) { | ||||
|     public SmsTemplateBO getTemplate(Integer id, Integer platform) { | ||||
|         SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne( | ||||
|                 new QueryWrapper<SmsTemplateDO>().eq("id", id)); | ||||
|                 new QueryWrapper<SmsTemplateDO>() | ||||
|                         .eq("platform", platform) | ||||
|                         .eq("id", id)); | ||||
| 
 | ||||
|         if (smsTemplateDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getCode(), | ||||
|  | @ -218,7 +243,7 @@ public class SmsServiceImpl implements SmsService { | |||
| 
 | ||||
|     @Override | ||||
|     @Transactional | ||||
|     public void updateTemplate(Integer id, String template, Integer tplType) { | ||||
|     public void updateTemplate(Integer id, Integer smsSignId, String template, Integer platform, Integer smsType) { | ||||
|         SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne( | ||||
|                 new QueryWrapper<SmsTemplateDO>().eq("id", id)); | ||||
| 
 | ||||
|  | @ -230,16 +255,17 @@ public class SmsServiceImpl implements SmsService { | |||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("id", smsTemplateDO.getSmsSignId())); | ||||
| 
 | ||||
| 
 | ||||
|         SmsPlatform.Result result = smsPlatform.updateTemplate( | ||||
|                 smsTemplateDO.getPlatformId(), | ||||
|                 String.format(SMS_TEMPLATE, smsSignDO.getSign(), template), tplType); | ||||
|         if (smsSignDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         smsTemplateMapper.update( | ||||
|                 (SmsTemplateDO) new SmsTemplateDO() | ||||
|                         .setSmsSignId(smsSignId) | ||||
|                         .setTemplate(template) | ||||
|                         .setApplyStatus(result.getApplyStatus()) | ||||
|                         .setApplyMessage(result.getApplyMessage()) | ||||
|                         .setPlatform(platform) | ||||
|                         .setSmsType(smsType) | ||||
|                         .setUpdateTime(new Date()), | ||||
|                 new QueryWrapper<SmsTemplateDO>().eq("id", id) | ||||
|         ); | ||||
|  | @ -257,20 +283,17 @@ public class SmsServiceImpl implements SmsService { | |||
|                     AdminErrorCodeEnum.SMS_TEMPLATE_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 删除 平台的模板
 | ||||
|         smsPlatform.deleteTemplate(smsTemplateDO.getPlatformId()); | ||||
| 
 | ||||
|         // 删除 数据库模板
 | ||||
|         SmsTemplateDO updateTemplate =new SmsTemplateDO(); | ||||
|         updateTemplate.setDeleted(DeletedStatusEnum.DELETED_YES.getValue()); | ||||
|         smsTemplateMapper.delete(new UpdateWrapper<SmsTemplateDO>() | ||||
|                 .set("deleted", DeletedStatusEnum.DELETED_YES).eq("id", id)); | ||||
|         smsTemplateMapper.delete( | ||||
|                 new UpdateWrapper<SmsTemplateDO>() | ||||
|                         .set("deleted", DeletedStatusEnum.DELETED_YES) | ||||
|                         .eq("id", id)); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void singleSend(String mobile, Integer smsTemplateId, Map<String, String> params) { | ||||
| 
 | ||||
|         // TODO: 2019/5/21 Sin params 参数为特换到模板中
 | ||||
|         SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne( | ||||
|                 new QueryWrapper<SmsTemplateDO>().eq("id", smsTemplateId)); | ||||
| 
 | ||||
|  | @ -283,14 +306,19 @@ public class SmsServiceImpl implements SmsService { | |||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("id", smsTemplateDO.getSmsSignId())); | ||||
| 
 | ||||
|         smsPlatform.singleSend(mobile, | ||||
|                 String.format(SMS_TEMPLATE, smsSignDO.getSign(), smsTemplateDO.getTemplate())); | ||||
|         if (smsSignDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 获取 client
 | ||||
|         SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform()); | ||||
|         // 发送短信
 | ||||
|         smsClient.singleSend(mobile, smsSignDO.getSign(), smsTemplateDO.getTemplate(), params); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void batchSend(List<String> mobileList, Integer smsTemplateId, Map<String, String> params) { | ||||
|         // TODO: 2019/5/21 Sin params 参数为特换到模板中
 | ||||
| 
 | ||||
|         SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne( | ||||
|                 new QueryWrapper<SmsTemplateDO>().eq("id", smsTemplateId)); | ||||
| 
 | ||||
|  | @ -303,7 +331,37 @@ public class SmsServiceImpl implements SmsService { | |||
|         SmsSignDO smsSignDO = smsSignMapper.selectOne( | ||||
|                 new QueryWrapper<SmsSignDO>().eq("id", smsTemplateDO.getSmsSignId())); | ||||
| 
 | ||||
|         smsPlatform.batchSend(mobileList, | ||||
|                 String.format(SMS_TEMPLATE, smsSignDO.getSign(), smsTemplateDO.getTemplate())); | ||||
|         if (smsSignDO == null) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         // 获取 client
 | ||||
|         SmsClient smsClient = getSmsClient(smsTemplateDO.getPlatform()); | ||||
|         // 发送短信
 | ||||
|         smsClient.batchSend(mobileList, smsSignDO.getSign(), smsTemplateDO.getTemplate(), params); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取 sms 对于的 client | ||||
|      * | ||||
|      * @param platform | ||||
|      * @return | ||||
|      */ | ||||
|     private SmsClient getSmsClient(Integer platform) { | ||||
|         SmsClient smsClient = null; | ||||
|         if (SmsPlatformEnum.YunPian.getValue().equals(platform)) { | ||||
|             smsClient = smsYunPianClient; | ||||
|         } else if (SmsPlatformEnum.AliYun.getValue().equals(platform)) { | ||||
|             smsClient = smsAliYunClient; | ||||
|         } | ||||
| 
 | ||||
|         if (smsClient == null) { | ||||
|             throw new ServiceException( | ||||
|                     AdminErrorCodeEnum.SMS_NOT_SEND_CLIENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_NOT_SEND_CLIENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         return smsClient; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,419 +0,0 @@ | |||
| package cn.iocoder.mall.admin.service; | ||||
| 
 | ||||
| import cn.iocoder.common.framework.exception.ServiceException; | ||||
| import cn.iocoder.mall.admin.api.SmsPlatform; | ||||
| import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsApplyStatusEnum; | ||||
| import com.alibaba.fastjson.JSON; | ||||
| import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import org.apache.http.HttpEntity; | ||||
| import org.apache.http.NameValuePair; | ||||
| import org.apache.http.client.entity.UrlEncodedFormEntity; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| import org.apache.http.client.methods.HttpPost; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import org.apache.http.impl.client.HttpClients; | ||||
| import org.apache.http.message.BasicNameValuePair; | ||||
| import org.apache.http.util.EntityUtils; | ||||
| import org.assertj.core.util.Lists; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| /** | ||||
|  * 云片 短信平台 | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/16 6:34 PM | ||||
|  */ | ||||
| @Service | ||||
| public class SmsYunPianPlatform implements SmsPlatform { | ||||
| 
 | ||||
|     protected static final Logger LOGGER = LoggerFactory.getLogger(SmsPlatform.class); | ||||
| 
 | ||||
|     private static final int SUCCESS_CODE = 0; | ||||
| 
 | ||||
|     //查账户信息的http地址
 | ||||
|     private static final String URI_GET_USER_INFO = | ||||
|             "https://sms.yunpian.com/v2/user/get.json"; | ||||
| 
 | ||||
|     //智能匹配模板发送接口的http地址
 | ||||
| 
 | ||||
|     //模板发送接口的http地址
 | ||||
|     private static final String URI_TPL_SEND_SMS = | ||||
|             "https://sms.yunpian.com/v2/sms/tpl_single_send.json"; | ||||
| 
 | ||||
|     //发送语音验证码接口的http地址
 | ||||
|     private static final String URI_SEND_VOICE = | ||||
|             "https://voice.yunpian.com/v2/voice/send.json"; | ||||
| 
 | ||||
|     //绑定主叫、被叫关系的接口http地址
 | ||||
|     private static final String URI_SEND_BIND = | ||||
|             "https://call.yunpian.com/v2/call/bind.json"; | ||||
| 
 | ||||
|     //解绑主叫、被叫关系的接口http地址
 | ||||
|     private static final String URI_SEND_UNBIND = | ||||
|             "https://call.yunpian.com/v2/call/unbind.json"; | ||||
| 
 | ||||
|     /** | ||||
|      * 签名 - 添加 | ||||
|      */ | ||||
|     private static final String URL_SIGN_ADD = "https://sms.yunpian.com/v2/sign/add.json"; | ||||
|     /** | ||||
|      * 签名 - 获取 | ||||
|      */ | ||||
|     private static final String URL_SIGN_GET = "https://sms.yunpian.com/v2/sign/get.json"; | ||||
|     /** | ||||
|      * 签名 - 更新 | ||||
|      */ | ||||
|     private static final String URL_SIGN_UPDATE = "https://sms.yunpian.com/v2/sign/update.json"; | ||||
|     /** | ||||
|      * 模板 - 添加 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_ADD = "https://sms.yunpian.com/v2/tpl/add.json"; | ||||
|     /** | ||||
|      * 模板 - 获取 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_GET = "https://sms.yunpian.com/v2/tpl/get.json"; | ||||
|     /** | ||||
|      * 模板 - 更新 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_UPDATE = "https://sms.yunpian.com/v2/tpl/update.json"; | ||||
|     /** | ||||
|      * 模板 - 删除 | ||||
|      */ | ||||
|     private static final String URL_TEMPLATE_DELETE = "https://sms.yunpian.com/v2/tpl/del.json"; | ||||
|     /** | ||||
|      * 短信发送 - 单个 | ||||
|      */ | ||||
|     private static final String URL_SEND_SINGLE = "https://sms.yunpian.com/v2/sms/single_send.json"; | ||||
|     /** | ||||
|      * 短信发送 - 批量 | ||||
|      */ | ||||
|     private static final String URL_SEND_BATCH = "https://sms.yunpian.com/v2/sms/batch_send.json"; | ||||
| 
 | ||||
| 
 | ||||
|     //编码格式。发送编码格式统一用UTF-8
 | ||||
|     private static String ENCODING = "UTF-8"; | ||||
| 
 | ||||
|     @Value("${sms.apiKey}") | ||||
|     private String apiKey; | ||||
| 
 | ||||
|     @Override | ||||
|     public Result createSign(String sign) { | ||||
|         try { | ||||
|             // 存在直接 return 相当于,创建了
 | ||||
|             return getSign(sign); | ||||
|         } catch (ServiceException e) { | ||||
|             // skip 不存在会进这里,不错任何操作
 | ||||
|         } | ||||
| 
 | ||||
|         // 调用 短信平台
 | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("sign", sign); | ||||
|         params.put("notify", "true"); | ||||
|         String result = post(URL_SIGN_ADD, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         JSONObject signJSONObject = (JSONObject) jsonObject.get("sign"); | ||||
|         Integer applyState = smsStatusMapping(signJSONObject.getString("apply_state")); | ||||
|         return new Result().setId(null).setApplyStatus(applyState).setApplyMessage(null); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result getSign(String sign) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("sign", sign); | ||||
|         params.put("page_num", "1"); | ||||
|         params.put("page_size", "20"); | ||||
|         String result = post(URL_SIGN_GET, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         JSONArray jsonArray = jsonObject.getJSONArray("sign"); | ||||
|         if (jsonArray.size() <= 0) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(), | ||||
|                     AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         JSONObject signJSONObject = (JSONObject) jsonArray.get(0); | ||||
|         String checkStatus = signJSONObject.getString("check_status"); | ||||
|         String applyMessage = signJSONObject.getString("remark"); | ||||
|         Integer applyStatus = smsStatusMapping(checkStatus); | ||||
|         return new Result().setId(null).setApplyStatus(applyStatus).setApplyMessage(applyMessage); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result updateSign(String oldSign, String sign) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("old_sign", oldSign); | ||||
|         params.put("sign", sign); | ||||
|         String result = post(URL_SIGN_UPDATE, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         JSONObject signJSONObject = (JSONObject) jsonObject.get("sign"); | ||||
|         Integer applyState = smsStatusMapping(signJSONObject.getString("apply_state")); | ||||
|         return new Result().setId(null).setApplyStatus(applyState).setApplyMessage(null); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result createTemplate(String template, Integer tplType) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("tpl_content", template); | ||||
|         if (tplType != null) { | ||||
|             params.put("tplType", String.valueOf(tplType)); | ||||
|         } | ||||
|         String result = post(URL_TEMPLATE_ADD, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         String tipId = jsonObject.getString("tpl_id"); | ||||
|         String checkStatus = jsonObject.getString("check_status"); | ||||
|         String reason = jsonObject.getString("reason"); | ||||
|         Integer applyStatus = smsStatusMapping(checkStatus); | ||||
|         return new Result().setId(tipId).setApplyStatus(applyStatus).setApplyMessage(reason); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result getTemplate(String tplId) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("tpl_id", tplId); | ||||
|         String result = post(URL_TEMPLATE_GET, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         String checkStatus = jsonObject.getString("check_status"); | ||||
|         Integer applyStatus = smsStatusMapping(checkStatus); | ||||
|         String reason = jsonObject.getString("reason"); | ||||
|         return new Result().setId(tplId).setApplyStatus(applyStatus).setApplyMessage(reason); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result updateTemplate(String tplId, String template, Integer tplType) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("tpl_id", tplId); | ||||
|         params.put("tpl_content", template); | ||||
|         String result = post(URL_TEMPLATE_UPDATE, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         JSONObject templateJSONObject = (JSONObject) jsonObject.get("template"); | ||||
|         String checkStatus = templateJSONObject.getString("check_status"); | ||||
|         Integer applyStatus = smsStatusMapping(checkStatus); | ||||
|         String reason = jsonObject.getString("reason"); | ||||
|         return new Result().setId(tplId).setApplyStatus(applyStatus).setApplyMessage(reason); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result deleteTemplate(String tplId) { | ||||
| 
 | ||||
|         // 如果不存在/已删除,直接返回
 | ||||
|         try { | ||||
|             getTemplate(tplId); | ||||
|         } catch (ServiceException e) { | ||||
|             // skip
 | ||||
|             return new Result().setId(tplId).setApplyStatus(null).setApplyMessage(null); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("tpl_id", tplId); | ||||
|         String result = post(URL_TEMPLATE_DELETE, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
| 
 | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         return new Result().setId(tplId).setApplyStatus(null).setApplyMessage(null); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult singleSend(String mobile, String template) { | ||||
|         Map<String, String> params = new LinkedHashMap<>(); | ||||
|         params.put("apikey", apiKey); | ||||
|         params.put("mobile", mobile); | ||||
|         params.put("text", template); | ||||
|         // TODO: 2019/5/19 sin 运营商发送报告 回调
 | ||||
|         // params.put("callback_url", template);
 | ||||
|         String result = post(URL_TEMPLATE_DELETE, params); | ||||
|         JSONObject jsonObject = JSON.parseObject(result); | ||||
|         if (jsonObject.containsKey("code") | ||||
|                 && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|             throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                     jsonObject.getString("detail")); | ||||
|         } | ||||
| 
 | ||||
|         return new SendResult() | ||||
|                 .setHasSuccess(SUCCESS_CODE == jsonObject.getInteger("code")) | ||||
|                 .setCode(jsonObject.getInteger("code")) | ||||
|                 .setMessage(jsonObject.getString("detail")) | ||||
|                 .setSuccess(Lists.newArrayList(mobile)) | ||||
|                 .setFail(Collections.EMPTY_LIST); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SendResult batchSend(List<String> mobileList, String template) { | ||||
| 
 | ||||
|         // 最大发送数为 1000,我们设置为 500 个, 分段发送
 | ||||
|         int maxSendSize = 500; | ||||
|         int maxSendSizeCount = mobileList.size() % maxSendSize; | ||||
|         int j = 0; | ||||
|         int j2 = maxSendSize; | ||||
| 
 | ||||
|         List<String> successList = new ArrayList<>(); | ||||
|         List<String> failList = new ArrayList<>(); | ||||
|         for (int i = 0; i < maxSendSizeCount; i++) { | ||||
|             StringBuffer sendMobileStr = new StringBuffer(); | ||||
|             for (int k = j; k < j2; k++) { | ||||
|                 sendMobileStr.append(","); | ||||
|                 sendMobileStr.append(mobileList.get(k)); | ||||
|             } | ||||
| 
 | ||||
|             String dividedMobile = sendMobileStr.toString().substring(1); | ||||
| 
 | ||||
|             // 发送手机号
 | ||||
|             Map<String, String> params = new LinkedHashMap<>(); | ||||
|             params.put("apikey", apiKey); | ||||
|             params.put("mobile", dividedMobile); | ||||
|             params.put("text", template); | ||||
|             // TODO: 2019/5/19 sin 运营商发送报告 回调
 | ||||
|             // params.put("callback_url", template);
 | ||||
|             String result = post(URL_SEND_BATCH, params); | ||||
|             JSONObject jsonObject = JSON.parseObject(result); | ||||
|             if (jsonObject.containsKey("code") | ||||
|                     && !(jsonObject.getInteger("code") == SUCCESS_CODE)) { | ||||
|                 throw new ServiceException(AdminErrorCodeEnum.SMS_PLATFORM_FAIL.getCode(), | ||||
|                         jsonObject.getString("detail")); | ||||
|             } | ||||
| 
 | ||||
|             JSONArray jsonArray = jsonObject.getJSONArray("data"); | ||||
|             for (Object o : jsonArray) { | ||||
|                 JSONObject dataJSONObject = (JSONObject) o; | ||||
|                 if (SUCCESS_CODE == dataJSONObject.getInteger("code")) { | ||||
|                     successList.add(dataJSONObject.getString("mobile")); | ||||
|                 } else { | ||||
|                     failList.add(dataJSONObject.getString("mobile")); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // 用于递增 maxSendSize
 | ||||
|             j = j2; | ||||
|             j2 = j + maxSendSize; | ||||
|         } | ||||
| 
 | ||||
|         return new SendResult() | ||||
|                 .setHasSuccess(true) | ||||
|                 .setCode(SUCCESS_CODE) | ||||
|                 .setMessage(null) | ||||
|                 .setSuccess(successList) | ||||
|                 .setFail(failList); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 短信 status 和 云片状态 映射关系 | ||||
|      * | ||||
|      * @param checkStatus | ||||
|      * @return | ||||
|      */ | ||||
|     private Integer smsStatusMapping(String checkStatus) { | ||||
|         Integer applyStatus; | ||||
|         switch (checkStatus) { | ||||
|             case "SUCCESS": | ||||
|                 applyStatus = SmsApplyStatusEnum.SUCCESS.getCode(); | ||||
|                 break; | ||||
|             case "FAIL": | ||||
|                 applyStatus = SmsApplyStatusEnum.FAIL.getCode(); | ||||
|                 break; | ||||
|             default: | ||||
|                 applyStatus = SmsApplyStatusEnum.CHECKING.getCode(); | ||||
|                 break; | ||||
|         } | ||||
|         return applyStatus; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 基于HttpClient 4.3的通用POST方法 | ||||
|      * | ||||
|      * @param url       提交的URL | ||||
|      * @param paramsMap 提交<参数,值>Map | ||||
|      * @return 提交响应 | ||||
|      */ | ||||
| 
 | ||||
|     public static String post(String url, Map<String, String> paramsMap) { | ||||
|         CloseableHttpClient client = HttpClients.createDefault(); | ||||
|         String responseText = ""; | ||||
|         CloseableHttpResponse response = null; | ||||
|         try { | ||||
|             HttpPost method = new HttpPost(url); | ||||
|             if (paramsMap != null) { | ||||
|                 List<NameValuePair> paramList = new ArrayList<>(); | ||||
|                 for (Map.Entry<String, String> param : paramsMap.entrySet()) { | ||||
|                     NameValuePair pair = new BasicNameValuePair(param.getKey(), | ||||
|                             param.getValue()); | ||||
|                     paramList.add(pair); | ||||
|                 } | ||||
|                 method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING)); | ||||
|             } | ||||
|             response = client.execute(method); | ||||
|             HttpEntity entity = response.getEntity(); | ||||
|             if (entity != null) { | ||||
|                 responseText = EntityUtils.toString(entity, ENCODING); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|         } finally { | ||||
|             try { | ||||
|                 response.close(); | ||||
|             } catch (Exception e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         LOGGER.debug("云片短信平台 res: {}", responseText); | ||||
|         return responseText; | ||||
|     } | ||||
| } | ||||
|  | @ -26,7 +26,13 @@ mybatis-plus: | |||
| 
 | ||||
| # sms | ||||
| sms: | ||||
|   apiKey: d4705399e71e822fe3a90f801ed95bd9 | ||||
|   yunPian: | ||||
|     apiKey: d4705399e71e822fe3a90f801ed95bd9 | ||||
|   aliYun: | ||||
|     accessKeyId: d4705399e71e822fe3a90f801ed95bd9 | ||||
|     accessSecret: d4705399e71e822fe3a90f801ed95bd9 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # dubbo | ||||
| dubbo: | ||||
|  |  | |||
|  | @ -0,0 +1,56 @@ | |||
| package cn.iocoder.mall.admin.client; | ||||
| 
 | ||||
| import cn.iocoder.mall.admin.SystemApplicationTest; | ||||
| 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 com.google.common.collect.ImmutableMap; | ||||
| import org.assertj.core.util.Lists; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 短信 sms client test | ||||
|  * | ||||
|  * @author Sin | ||||
|  * @time 2019/5/25 12:46 PM | ||||
|  */ | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest(classes = SystemApplicationTest.class) | ||||
| public class SmsYunPianClientTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private SmsYunPianClient smsYunPianClient; | ||||
| 
 | ||||
|     private String sign = null; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setup() { | ||||
|         sign = "悦跑运动"; | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void sendMobileTest() { | ||||
|         String mobile = "13302926050"; | ||||
|         String template = "您的验证码是#code#,打死也不告诉别人哦。"; | ||||
|         smsYunPianClient.singleSend(mobile, sign, template, ImmutableMap.of("code", "1111")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void batchSendTest() { | ||||
|         String mobile = "13302926050"; | ||||
|         String template = "您的验证码是#code#,打死也不告诉别人哦。"; | ||||
|         smsYunPianClient.batchSend(Lists.newArrayList(mobile), sign, template, ImmutableMap.of("code", "2222")); | ||||
|     } | ||||
| } | ||||
|  | @ -1,10 +1,16 @@ | |||
| package cn.iocoder.mall.admin.service; | ||||
| 
 | ||||
| import cn.iocoder.common.framework.exception.ServiceException; | ||||
| import cn.iocoder.mall.admin.SystemApplicationTest; | ||||
| import cn.iocoder.mall.admin.api.SmsService; | ||||
| import cn.iocoder.mall.admin.api.bo.sms.SmsSignBO; | ||||
| import cn.iocoder.mall.admin.api.bo.sms.SmsTemplateBO; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsPlatformEnum; | ||||
| import cn.iocoder.mall.admin.api.constant.SmsTypeEnum; | ||||
| import com.google.common.collect.ImmutableMap; | ||||
| import org.assertj.core.util.Lists; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
|  | @ -21,55 +27,57 @@ import org.springframework.test.context.junit4.SpringRunner; | |||
| public class SmsServiceImplTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private SmsServiceImpl smsService; | ||||
|     private SmsService smsService; | ||||
| 
 | ||||
|     @Test | ||||
|     public void createSignTest() { | ||||
|         smsService.createSign("测试签名1"); | ||||
| //        smsService.createSign("悦跑会");
 | ||||
|         smsService.createSign("悦跑运动", SmsPlatformEnum.YunPian.getValue()); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void getSignTest() { | ||||
|         SmsSignBO smsSignBO = smsService.getSign("悦跑会"); | ||||
|         Assert.assertNotNull(smsSignBO); | ||||
|         SmsSignBO smsSignBO =  smsService.getSign(3); | ||||
|         Assert.assertNotNull("不能为空!", smsSignBO); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void updateSignTest() { | ||||
|         smsService.updateSign("测试签名2", "测试签名3"); | ||||
|         SmsSignBO newSmsSignBO = smsService.getSign("测试签名3"); | ||||
|         Assert.assertNotNull(newSmsSignBO); | ||||
|         String oldSign = "悦跑运动2"; | ||||
|         String newSign = "悦跑运动"; | ||||
|         smsService.updateSign(3, newSign, SmsPlatformEnum.YunPian.getValue()); | ||||
|         SmsSignBO smsSignBO =  smsService.getSign(3); | ||||
|         Assert.assertTrue("更新不成功!", smsSignBO.getSign().equals(newSign)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     ///
 | ||||
|     /// template
 | ||||
|     @Test | ||||
|     public void deletedSignTest() { | ||||
|         smsService.deleteSign(3); | ||||
|         Assertions.assertThrows(ServiceException.class, () -> { | ||||
|             smsService.getSign(3); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void createTemplateTest() { | ||||
|         smsService.createTemplate(1, "打死也不要告诉别人哦002 #code# ", 1); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void getTemplateTest() { | ||||
|         SmsTemplateBO smsTemplateBO = smsService.getTemplate(3); | ||||
|         Assert.assertNotNull(smsTemplateBO); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void updateTemplateTest() { | ||||
|         smsService.updateTemplate(3, "打死也不要告诉别人哦444 #code# ", 1); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void deleteTemplateTest() { | ||||
|         smsService.deleteTemplate(3); | ||||
|         String template = "您的验证码是#code#,打死也不告诉别人哦。"; | ||||
|         smsService.createTemplate(3, template, | ||||
|                 SmsPlatformEnum.YunPian.getValue(), | ||||
|                 SmsTypeEnum.VERIFICATION_CODE.getValue()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void singleSendTest() { | ||||
|         String mobile = "13302926050"; | ||||
|         smsService.singleSend(mobile, 1); | ||||
|         Integer templateId = 5; | ||||
|         smsService.singleSend(mobile, templateId, ImmutableMap.of("code", "8888")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void batchSendTest() { | ||||
|         String mobile = "13302926050"; | ||||
|         Integer templateId = 5; | ||||
|         smsService.batchSend(Lists.newArrayList(mobile), templateId, ImmutableMap.of("code", "8888")); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 sin-ning@aliyun.com
						sin-ning@aliyun.com