forked from kidgrow-microservices-platform

zhaoxiaohao
2020-08-15 f6646d87aceda231e2f3a73670ec708ec8fca0a9
Merge branch 'dev' of http://192.168.2.240:7070/r/kidgrow-microservices-platform into dev
2 files modified
15 files added
1114 ■■■■■ changed files
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/feign/SmsChuangLanService.java 29 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/feign/fallback/SmsChuangLanServiceFallbackFactory.java 27 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/model/ConstantSMS.java 9 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/model/SmsModel.java 28 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/client/SmsClient.java 216 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/exception/SmsException.java 31 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/service/AliyunSmsService.java 44 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/template/BatchSmsTemplate.java 26 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/template/SmsTemplate.java 27 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/util/AliyunSmsUtils.java 175 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/util/SmsChuangLanUtils.java 63 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/filecenter/config/AliyunOSSAutoConfigure.java 31 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/config/SmsAutoConfiguration.java 46 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/config/SmsProperties.java 37 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/controller/SmsController.java 133 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/lanchuang/controller/SmsChuangLanController.java 156 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/resources/application.yml 36 ●●●●● patch | view | raw | blame | history
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/feign/SmsChuangLanService.java
New file
@@ -0,0 +1,29 @@
package com.kidgrow.sms.feign;
import com.kidgrow.common.constant.ServiceNameConstants;
import com.kidgrow.common.model.ResultBody;
import com.kidgrow.sms.feign.fallback.SmsChuangLanServiceFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: <br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/27 22:04 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@FeignClient(value = ServiceNameConstants.SMS_SERVICE_SERVER,
        fallbackFactory = SmsChuangLanServiceFallbackFactory.class, decode404 = true)
public interface SmsChuangLanService {
    /**
     * feign rpc访问远程 接口
     */
    @PostMapping(value = "/smsChangLan/send")
    ResultBody sendVerificationCode(@RequestBody Map map);
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/feign/fallback/SmsChuangLanServiceFallbackFactory.java
New file
@@ -0,0 +1,27 @@
package com.kidgrow.sms.feign.fallback;
import com.kidgrow.common.model.ResultBody;
import com.kidgrow.sms.feign.SmsChuangLanService;
import feign.hystrix.FallbackFactory;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: <br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/27 22:05 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
public class SmsChuangLanServiceFallbackFactory implements FallbackFactory<SmsChuangLanService> {
    @Override
    public SmsChuangLanService create(Throwable throwable) {
        return new SmsChuangLanService() {
            @Override
            public ResultBody sendVerificationCode(Map ma) {
                return ResultBody.failed("短息调用失败");
            }
        };
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/model/ConstantSMS.java
New file
@@ -0,0 +1,9 @@
package com.kidgrow.sms.model;
import com.kidgrow.common.constant.CommonConstant;
public interface ConstantSMS {
    String PASSWORD_SMS = "PASSWORD_SMS";//修改密码 短信验证的type值
    String REGISTER_SMS = "REGISTER_SMS";//注册 短信验证的type值
    String PHONE_SMS = "PHONE_SMS";//更换手机号 短信验证的type值
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-api/src/main/java/com/kidgrow/sms/model/SmsModel.java
New file
@@ -0,0 +1,28 @@
package com.kidgrow.sms.model;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 发送短信实体类<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:18 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@ApiModel(value = "发送短信实体类")
@Data
public class SmsModel implements Serializable {
    private String phoneNumber; //手机号
    private String key; // 短信模板key
    private String code; // 短信验证码
    private Map<String,String> params; // 内容 key 值要与模板一致
    private List<String> phoneNumbers; // 群发消息时使用
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/client/SmsClient.java
New file
@@ -0,0 +1,216 @@
package com.kidgrow.sms.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.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.gson.Gson;
import com.kidgrow.sms.exception.SmsException;
import com.kidgrow.sms.template.BatchSmsTemplate;
import com.kidgrow.sms.template.SmsTemplate;
import com.kidgrow.sms.util.AliyunSmsUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.*;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云 SMS 客户端<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:07 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
public class SmsClient {
    private final IAcsClient acsClient;
    private final Map<String, SmsTemplate> smsTemplates;
    private final Gson gson = new Gson();
    @Value("${aliyun.commonRequest.domain}")
    private String domain;
    @Value("${aliyun.commonRequest.version}")
    private String version;
    @Value("${aliyun.commonRequest.action}")
    private String action;
    /**
     * Instantiates a new SmsClient.
     *
     * @param accessKeyId 阿里云短信 accessKeyId
     * @param accessKeySecret 阿里云短信 accessKeySecret
     */
    public SmsClient(final String accessKeyId, final String accessKeySecret) {
        this(accessKeyId, accessKeySecret, Collections.emptyMap());
    }
    /**
     * Instantiates a new SmsClient.
     *
     * @param accessKeyId 阿里云短信 accessKeyId
     * @param accessKeySecret 阿里云短信 accessKeySecret
     * @param smsTemplates 预置短信模板
     */
    public SmsClient(final String accessKeyId,
                     final String accessKeySecret,
                     final Map<String, SmsTemplate> smsTemplates) {
        AliyunSmsUtils.checkNotEmpty(accessKeyId, "'accessKeyId' must be not empty");
        AliyunSmsUtils.checkNotEmpty(accessKeySecret, "'accessKeySecret' must be not empty");
        final IClientProfile clientProfile = DefaultProfile.getProfile(
                "default", accessKeyId, accessKeySecret);
        this.acsClient = new DefaultAcsClient(clientProfile);
        this.smsTemplates = smsTemplates;
    }
    /**
     * Instantiates a new SmsClient.
     *
     * @param acsClient IAcsClient
     * @param smsTemplates 预置短信模板
     */
    public SmsClient(final IAcsClient acsClient, final Map<String, SmsTemplate> smsTemplates) {
        this.acsClient = acsClient;
        this.smsTemplates = smsTemplates;
    }
    /**
     * 发送短信验证码.
     *
     * @param phoneNumber 手机号码(中国)
     *
     * @return 6 位数的随机码
     */
    public int sendVerificationCode(final String smsTemplateKey, final String phoneNumber) {
        AliyunSmsUtils.checkPhoneNumber(phoneNumber);
        final SmsTemplate smsTemplate = this.smsTemplates.get(smsTemplateKey);
        Objects.requireNonNull(smsTemplate, () -> "SmsTemplate must be not null, key:" + smsTemplateKey);
        final int code = AliyunSmsUtils.randomCode();
        smsTemplate.setTemplateParam(Collections.singletonMap("code", String.valueOf(code)));
        smsTemplate.setPhoneNumbers(Collections.singletonList(phoneNumber));
        send(smsTemplate);
        return code;
    }
    /**
     * 发送消息 支持群发
     * @param smsTemplateKey
     * @param params
     * @param phoneNumbers
     */
    public void sendSmsMsg(final String smsTemplateKey, Map<String, String> params, final List<String> phoneNumbers){
        final SmsTemplate smsTemplate = this.smsTemplates.get(smsTemplateKey);
        Objects.requireNonNull(smsTemplate, () -> "SmsTemplate must be not null, key:" + smsTemplateKey);
        smsTemplate.setTemplateParam(params);
        smsTemplate.setPhoneNumbers(phoneNumbers);
        send(smsTemplate);
    }
    /**
     * 发送短信.
     *
     * @param smsTemplateKey 预置短信模板 key
     */
    public void send(final String smsTemplateKey) {
        final SmsTemplate smsTemplate = this.smsTemplates.get(smsTemplateKey);
        Objects.requireNonNull(smsTemplate, () -> "SmsTemplate must be not null, key:" + smsTemplateKey);
        send(smsTemplate);
    }
    /**
     * 发送短信.
     *
     * @param smsTemplateKey 预置短信模板 key
     * @param phoneNumbers 手机号码,优先于预置短信模板中配置的手机号码
     */
    public void send(final String smsTemplateKey, final String... phoneNumbers) {
        final SmsTemplate smsTemplate = this.smsTemplates.get(smsTemplateKey);
        Objects.requireNonNull(smsTemplate, () -> "SmsTemplate must be not null, key:" + smsTemplateKey);
        smsTemplate.setPhoneNumbers(Arrays.asList(phoneNumbers));
        send(smsTemplate);
    }
    /**
     * 发送短信.
     *
     * @param smsTemplate 短信模板
     */
    public void send(final SmsTemplate smsTemplate) {
        Objects.requireNonNull(smsTemplate);
        AliyunSmsUtils.checkSmsTemplate(smsTemplate);
        final CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain(domain);
        request.setSysVersion(version);
        request.setSysAction(action);
        request.putQueryParameter("PhoneNumbers", String.join(",", smsTemplate.getPhoneNumbers()));
        request.putQueryParameter("SignName", smsTemplate.getSignName());
        request.putQueryParameter("TemplateCode", smsTemplate.getTemplateCode());
        request.putQueryParameter("TemplateParam", AliyunSmsUtils.toJsonStr(smsTemplate.getTemplateParam()));
        try {
            final CommonResponse response = this.acsClient.getCommonResponse(request);
            AliyunSmsUtils.checkSmsResponse(response);
        }
        catch (final ClientException e) {
            throw new SmsException(e);
        }
    }
    /**
     * 批量发送短信.
     *
     * <p>
     * 批量发送短信接口,支持在一次请求中分别向多个不同的手机号码发送不同签名的短信。
     * 手机号码,签名,模板参数字段个数相同,一一对应,短信服务根据字段的顺序判断发往指定手机号码的签名。
     *
     * <p>
     * 如果您需要往多个手机号码中发送同样签名的短信,请使用 {@link #send(SmsTemplate)}。
     *
     * @param batchSmsTemplate 批量发送短信模板
     */
    public void send(final BatchSmsTemplate batchSmsTemplate) {
        Objects.requireNonNull(batchSmsTemplate);
        AliyunSmsUtils.checkBatchSmsTemplate(batchSmsTemplate);
        final CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendBatchSms");
        request.putQueryParameter("PhoneNumberJson", this.gson.toJson(batchSmsTemplate.getPhoneNumbers()));
        request.putQueryParameter("SignNameJson", this.gson.toJson(batchSmsTemplate.getSignNames()));
        request.putQueryParameter("TemplateCode", batchSmsTemplate.getTemplateCode());
        request.putQueryParameter("TemplateParamJson", this.gson.toJson(batchSmsTemplate.getTemplateParams()));
        try {
            final CommonResponse response = this.acsClient.getCommonResponse(request);
            AliyunSmsUtils.checkSmsResponse(response);
        }
        catch (final ClientException e) {
            throw new SmsException(e);
        }
    }
//    public static void main(String[] args) {
//        Map<String, SmsTemplate> smsTemplates = new HashMap<>();
//        SmsTemplate smsTemplate = SmsTemplate.builder()
//                .signName("模板名称")
//                .templateCode("模板code")
//                .addTemplateParam("code", "123456")
//                .build();
//        smsTemplates.put("aaa",smsTemplate);
//        SmsClient smsClient = new SmsClient("aaaa","aaaaa",smsTemplates);
//        smsClient.sendVerificationCode("aaa","18503198351");
//    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/exception/SmsException.java
New file
@@ -0,0 +1,31 @@
package com.kidgrow.sms.exception;
import com.kidgrow.common.exception.KidgrowException;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: <br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 08:57 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
public class SmsException extends KidgrowException {
    /**
     * Instantiates a new SmsException.
     *
     * @param message the message
     */
    public SmsException(final String message) {
        super(message);
    }
    /**
     * Instantiates a new SmsException.
     *
     * @param cause the cause
     */
    public SmsException(final Throwable cause) {
        super(cause);
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/service/AliyunSmsService.java
New file
@@ -0,0 +1,44 @@
package com.kidgrow.sms.service;
import com.kidgrow.common.model.ResultBody;
import com.kidgrow.sms.model.SmsModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 对外API 短信发送和验证码校验接口 feignClient 继承这个接口 即可调用<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:20 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@Api(tags = "短信发送服务")
public interface AliyunSmsService {
    /**
     * 发送手机验证码
     * @param smsModel
     */
    @ApiOperation(value = "发送短信验证码接口")
    @PostMapping("/send/verificationCode")
    ResultBody sendVerificationCode(@RequestBody SmsModel smsModel);
    /**
     * 校验手机验证码是否正确
     * @param smsModel
     */
    @ApiOperation(value = "验证短信验证码接口")
    @PostMapping("/validate/verificationCode")
    ResultBody validateVerificationCode(@RequestBody SmsModel smsModel);
    /**
     * 发送手机短信消息
     * @param smsModel
     */
    @ApiOperation(value = "发送手机短信消息接口")
    @PostMapping("/send/smsMsg")
    ResultBody sendSmsMsg(@RequestBody SmsModel smsModel);
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/template/BatchSmsTemplate.java
New file
@@ -0,0 +1,26 @@
package com.kidgrow.sms.template;
import lombok.*;
import java.util.List;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云调用批量模板<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:04 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@Builder(builderClassName = "Builder", toBuilder = true)
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class BatchSmsTemplate {
    private List<String> signNames;
    private String templateCode;
    private List<Map<String, String>> templateParams;
    private List<String> phoneNumbers;
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/template/SmsTemplate.java
New file
@@ -0,0 +1,27 @@
package com.kidgrow.sms.template;
import lombok.*;
import java.util.List;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云调用模板<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:04 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@Builder(builderClassName = "Builder", toBuilder = true)
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class SmsTemplate {
    private String signName;
    private String templateCode;
    private Map<String, String> templateParam;
    private List<String> phoneNumbers;
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/util/AliyunSmsUtils.java
New file
@@ -0,0 +1,175 @@
package com.kidgrow.sms.util;
import com.aliyuncs.CommonResponse;
import com.google.gson.Gson;
import com.kidgrow.sms.exception.SmsException;
import com.kidgrow.sms.template.BatchSmsTemplate;
import com.kidgrow.sms.template.SmsTemplate;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云短信服务工具类<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 08:53 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
public class AliyunSmsUtils {
    private static final String SUCCESS_CODE = "OK";
    /**
     * 宽松校验即可.
     */
    private static final String PHONE_NUMBER_REGEX = "\\d{5,}";
    /**
     * 生成随机验证码.
     *
     * @return 随机数
     */
    public static int randomCode() {
        return 100_000 + ThreadLocalRandom.current().nextInt(1_000_000 - 100_000);
    }
    /**
     * Map 转 json 字符串的简单实现.
     *
     * @param map the map
     *
     * @return the json string
     */
    public static String toJsonStr(final Map<String, String> map) {
        if (null == map || map.isEmpty()) {
            return null;
        }
        final StringBuilder sb = new StringBuilder();
        sb.append('{');
        for (final Map.Entry<String, String> entry : map.entrySet()) {
            sb.append('"')
                    .append(entry.getKey().replace("\"", "\\\""))
                    .append('"')
                    .append(':')
                    .append('"')
                    .append(entry.getValue().replace("\"", "\\\""))
                    .append('"')
                    .append(',');
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append('}');
        return sb.toString();
    }
    /**
     * 校验 SmsTemplate.
     *
     * @param template the SmsTemplate
     */
    public static void checkSmsTemplate(final SmsTemplate template) {
        checkNotEmpty(template.getSignName(), "SmsTemplate signName must be not empty");
        checkNotEmpty(template.getTemplateCode(), "SmsTemplate templateCode must be not empty");
        checkNotEmpty(template.getPhoneNumbers(), "SmsTemplate phoneNumbers must be not empty");
    }
    /**
     * 校验 BatchSmsTemplate.
     *
     * @param template the BatchSmsTemplate
     */
    public static void checkBatchSmsTemplate(final BatchSmsTemplate template) {
        checkNotEmpty(template.getSignNames(), "BatchSmsTemplate signNames must be not empty");
        checkNotEmpty(template.getPhoneNumbers(), "BatchSmsTemplate phoneNumbers must be not empty");
        checkNotEmpty(template.getTemplateCode(), "BatchSmsTemplate templateCode must be not empty");
        checkNotEmpty(template.getTemplateParams(), "BatchSmsTemplate templateParams must be not empty");
        if (template.getSignNames().size() != template.getPhoneNumbers().size()
                && template.getPhoneNumbers().size() != template.getTemplateParams().size()) {
            throw new IllegalArgumentException("BatchSmsTemplate phoneNumbers, signNames, templateParams size must be the same");
        }
    }
    /**
     * 校验 SendSmsResponse 状态.
     *
     * @param response the SendSmsResponse
     */
    public static void checkSmsResponse(final CommonResponse response) {
        if (null == response) {
            throw new SmsException("Response is null");
        }
        final Gson gson = new Gson();
        final Map<String, String> json = gson.fromJson(response.getData(), Map.class);
        if (!SUCCESS_CODE.equalsIgnoreCase(json.get("Code"))) {
            //throw new SmsException("Http status: " + response.getHttpStatus() + ", response: " + response.getData());
            throw new SmsException(response.getData());
        }
    }
    /**
     * 校验手机号码(中国).
     *
     * @param phoneNumber the phone number
     */
    public static void checkPhoneNumber(final String phoneNumber) {
        if (null == phoneNumber || !phoneNumber.matches(PHONE_NUMBER_REGEX)) {
            throw new IllegalArgumentException("Invalid phone number");
        }
    }
    /**  <br>     2018年3月已知
     中国电信号段
     133,149,153,173,177,180,181,189,199
     中国联通号段
     130,131,132,145,155,156,166,175,176,185,186
     中国移动号段
     134(0-8),135,136,137,138,139,147,150,151,152,157,158,159,178,182,183,184,187,188,198
     其他号段
     14号段以前为上网卡专属号段,如中国联通的是145,中国移动的是147等等。
     虚拟运营商
     电信:1700,1701,1702
     移动:1703,1705,1706
     联通:1704,1707,1708,1709,171
     卫星通信:148(移动) 1349
     */
    public static boolean isMobile(String str) {
        boolean b = false;
        String s2="^[1](([3][0-9])|([4][5,7,9])|([5][0-9])|([6][6])|([7][3,5,6,7,8])|([8][0-9])|([9][8,9]))[0-9]{8}$";// 验证手机号
        if(StringUtils.isNotBlank(str)){
            return str.matches(s2);
        }
        return b;
    }
    /**
     * 校验字符串不为空.
     *
     * @param str the str
     * @param message the message
     */
    public static void checkNotEmpty(final String str, final String message) {
        if (null == str || str.isEmpty()) {
            throw new IllegalArgumentException(message);
        }
    }
    /**
     * 校验集合不为空.
     *
     * @param coll the Collection
     * @param message the message
     */
    public static void checkNotEmpty(final Collection coll, final String message) {
        if (null == coll || coll.isEmpty()) {
            throw new IllegalArgumentException(message);
        }
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-biz/src/main/java/com/kidgrow/sms/util/SmsChuangLanUtils.java
New file
@@ -0,0 +1,63 @@
package com.kidgrow.sms.util;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class SmsChuangLanUtils {
    public static void main(String[] args) {
        //短信下发
        String sendUrl = "http://smssh1.253.com/msg/send/json";
        Map map = new HashMap();
        map.put("account","N2561124");//API账号
        map.put("password","Mguj6qlRWX7b5e");//API密码
        map.put("msg","123123");//短信内容
        map.put("phone","18600376209");//手机号
        map.put("report","false");//是否需要状态报告
        JSONObject js = (JSONObject) JSONObject.toJSON(map);
        System.out.println(sendSmsByPost(sendUrl,js.toString()));
    }
    public static String send(Map map,String url){
        JSONObject js = (JSONObject) JSONObject.toJSON(map);
        return sendSmsByPost(url,js.toString());
    }
    public static String sendSmsByPost(String path, String postContent) {
        URL url = null;
        try {
            url = new URL(path);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setConnectTimeout(10000);
            httpURLConnection.setReadTimeout(10000);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");
            httpURLConnection.connect();
            OutputStream os=httpURLConnection.getOutputStream();
            os.write(postContent.getBytes("UTF-8"));
            os.flush();
            StringBuilder sb = new StringBuilder();
            int httpRspCode = httpURLConnection.getResponseCode();
            if (httpRspCode == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/filecenter/config/AliyunOSSAutoConfigure.java
@@ -11,6 +11,7 @@
import com.kidgrow.filecenter.properties.FileServerProperties;
import com.kidgrow.filecenter.service.impl.AbstractIFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -20,8 +21,6 @@
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
@@ -64,6 +63,9 @@
            return fileProperties.getType();
        }
        @Value("${spring.profiles.active}")
        private String OssPathEn;
        @Override
        protected void uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception {
            String clientID = httpServletRequest.getHeader(SecurityConstants.CLIENT_HEADER);
@@ -77,7 +79,8 @@
                fileFolder = FilePath(fileInfo.getImgType(), folderByDate, null, null);
                fileUpLoadOss(fileInfo, fileFolder + fileName, file.getInputStream());
            } else {
                fileUpLoadOss(fileInfo, fileProperties.getOss().getFolder() + folderByDate + "/" + fileName, file.getInputStream());
                fileFolder = FilePath(fileInfo.getImgType(), folderByDate, null, null);
                fileUpLoadOss(fileInfo, fileFolder + fileName, file.getInputStream());
            }
        }
@@ -114,7 +117,9 @@
         */
        public String FilePath(String imgType, String folderByDate, String hospitalId, String departmentId) {
            //返回的文件路径
            String fileFolder = "";
            String fileFolder = OssPathEn+"/";
            if (StringUtils.isNotBlank(imgType)) {
                // 光片需要按照根据医院ID,科室ID,日期进行OSS存储
                if (imgType.toLowerCase().equals("xray")) {
@@ -122,34 +127,34 @@
                    String depID = httpServletRequest.getHeader(SecurityConstants.USER_DEP_ID_HEADER);
                    if (org.apache.commons.lang3.StringUtils.isBlank(hospitalID) &&
                            org.apache.commons.lang3.StringUtils.isBlank(depID)) {
                        fileFolder = "Xray/" + hospitalID + "/" + depID + "/" + folderByDate + "/";
                        fileFolder += "Xray/" + hospitalID + "/" + depID + "/" + folderByDate + "/";
                    } else {
                        if (org.apache.commons.lang3.StringUtils.isBlank(hospitalId) &&
                                org.apache.commons.lang3.StringUtils.isBlank(departmentId)) {
                            fileFolder = "Xray/" + hospitalId + "/" + departmentId + "/" + folderByDate + "/";
                            fileFolder += "Xray/" + hospitalId + "/" + departmentId + "/" + folderByDate + "/";
                        } else {
                            fileFolder = "Xray/" + folderByDate + "/";
                            fileFolder += "Xray/" + folderByDate + "/";
                        }
                    }
                } else if (imgType.toLowerCase().equals("app")) {
                    //移动端APP上传
                    if (org.apache.commons.lang3.StringUtils.isBlank(hospitalId) &&
                            org.apache.commons.lang3.StringUtils.isBlank(departmentId)) {
                        fileFolder = "AppXray/" + hospitalId + "/" + departmentId + "/" + folderByDate + "/";
                        fileFolder += "AppXray/" + hospitalId + "/" + departmentId + "/" + folderByDate + "/";
                    } else {
                        fileFolder = "AppXray/" + folderByDate + "/";
                        fileFolder += "AppXray/" + folderByDate + "/";
                    }
                }
                // 医院Logo只保存在一个目录中
                else if (imgType.toLowerCase().equals("logo")) {
                    fileFolder = "HospitalLogo/";
                    fileFolder += "HospitalLogo/";
                } else if (imgType.toLowerCase().equals("doctor")) {
                    fileFolder = "DoctorImage/";
                    fileFolder += "DoctorImage/";
                } else {
                    fileFolder = "OtherImage/" + folderByDate + "/";
                    fileFolder += "OtherImage/" + folderByDate + "/";
                }
            } else {
                fileFolder = "OtherImage/" + folderByDate + "/";
                fileFolder += "OtherImage/" + folderByDate + "/";
            }
            return fileFolder;
        }
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/config/SmsAutoConfiguration.java
New file
@@ -0,0 +1,46 @@
package com.kidgrow.sms.aliyun.config;
import com.kidgrow.sms.client.SmsClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云 SMS 自动配置<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:11 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@Configuration
@ConditionalOnClass(name = "com.aliyuncs.IAcsClient")
@EnableConfigurationProperties(SmsProperties.class)
public class SmsAutoConfiguration {
    private final SmsProperties smsProperties;
    public SmsAutoConfiguration(final SmsProperties smsProperties) {
        this.smsProperties = smsProperties;
    }
    /**
     * Configuration SmsClient bean.
     *
     * @return the sms client
     */
    @Bean
    @ConditionalOnMissingBean
    public SmsClient smsClient() {
        if (this.smsProperties.getTemplates() == null) {
            return new SmsClient(this.smsProperties.getAccessKeyId(), this.smsProperties.getAccessKeySecret());
        } else {
            return new SmsClient(
                    this.smsProperties.getAccessKeyId(),
                    this.smsProperties.getAccessKeySecret(),
                    this.smsProperties.getTemplates());
        }
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/config/SmsProperties.java
New file
@@ -0,0 +1,37 @@
package com.kidgrow.sms.aliyun.config;
import com.kidgrow.sms.template.SmsTemplate;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: 阿里云 SMS 配置属性<br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:10 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@Data
@ConfigurationProperties(prefix = "aliyun.sms")
public class SmsProperties implements InitializingBean {
    private String accessKeyId;
    private String accessKeySecret;
    private String signName;
    private Map<String, SmsTemplate> templates;
    @Override
    public void afterPropertiesSet() throws Exception {
        if (null != this.templates) {
            for (final SmsTemplate smsTemplate : this.templates.values()) {
                if (null == smsTemplate.getSignName()) {
                    smsTemplate.setSignName(this.signName);
                }
            }
        }
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/aliyun/controller/SmsController.java
New file
@@ -0,0 +1,133 @@
package com.kidgrow.sms.aliyun.controller;
import com.kidgrow.common.base.ResponseCode;
import com.kidgrow.common.model.ResultBody;
import com.kidgrow.redis.template.RedisRepository;
import com.kidgrow.sms.client.SmsClient;
import com.kidgrow.sms.exception.SmsException;
import com.kidgrow.sms.service.AliyunSmsService;
import com.kidgrow.sms.model.SmsModel;
import com.kidgrow.sms.util.AliyunSmsUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
 *
 * @Description: <br>
 * @Project: <br>
 * @CreateDate: Created in 2020/2/17 09:15 <br>
 * @Author: <a href="4345453@kidgrow.com">liuke</a>
 */
@RestController
@RequestMapping("sms")
public class SmsController implements AliyunSmsService {
    @Autowired
    private SmsClient smsClient;
    @Autowired
    private RedisRepository redisRepository;
    @Value("${sms.verificationCode.timeOut:180}")
    private Long timeOut;
    @Value("${sms.verificationCode.prefix:default}")
    private String smsPrefix;
    /**
     * 发送短信验证码
     *
     * @param smsModel
     */
    @Override
    public ResultBody sendVerificationCode(@RequestBody SmsModel smsModel) {
        String phoneNumber = smsModel.getPhoneNumber();
        String key = smsModel.getKey();
        if (StringUtils.isBlank(phoneNumber) || StringUtils.isBlank(key)) {
            return ResultBody.fail(ResponseCode.ERROR_PARAMS, "手机号或短信模板不能为空!");
        }
        if (!AliyunSmsUtils.isMobile(phoneNumber)) {
            return ResultBody.fail(ResponseCode.ERROR_PARAMS, "手机号格式不正确!");
        }
        try {
            // 发送验证码
            Integer code = smsClient.sendVerificationCode(key, phoneNumber);
            // 缓存验证码和有效期
            redisRepository.setExpire(smsPrefix + phoneNumber, code.toString(), timeOut);
//            redisRepository.expire(smsPrefix + phoneNumber, timeOut);
            return ResultBody.ok();
        } catch (SmsException smsEx) {
            smsEx.printStackTrace();
            return ResultBody.failed().msg(smsEx.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBody.failed().msg(e.getMessage());
        }
    }
    /**
     * 验证码校验
     *
     * @param smsModel
     */
    @Override
    public ResultBody validateVerificationCode(@RequestBody SmsModel smsModel) {
        String phoneNumber = smsModel.getPhoneNumber();
        String code = smsModel.getCode();
        if (StringUtils.isBlank(phoneNumber) || StringUtils.isBlank(code)) {
            return ResultBody.failed(ResponseCode.ERROR_PARAMS, "手机号或验证码不能为空!");
        }
        try {
            if (redisRepository.exists(smsPrefix + phoneNumber)) {
                String rightCode = (String) redisRepository.get(smsPrefix + phoneNumber);
                if (code.equals(rightCode)) {
                    // 验证成功 移除缓存验证码
                    redisRepository.del(smsPrefix + phoneNumber);
                    return ResultBody.ok();
                } else {
                    return ResultBody.failed(ResponseCode.ERROR_PARAMS, "验证码不正确!");
                }
            } else {
                return ResultBody.failed(ResponseCode.ERROR_PARAMS, "验证码已失效!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBody.failed("系统错误");
        }
    }
    /**
     * 发送手机短信消息
     *
     * @param smsModel
     * @return
     */
    @Override
    public ResultBody sendSmsMsg(SmsModel smsModel) {
        List<String> phoneNumbers = smsModel.getPhoneNumbers();
        String key = smsModel.getKey();
//        if ((phoneNumbers == null || phoneNumbers.isEmpty()) || StringUtils.isBlank(key)) {
//            return ResponseBuilder.buildResultError(ResponseCode.ERROR_PARAMS, "手机号或短信模板不能为空!");
//        }
        try {
            // 发送手机短信消息
            smsClient.sendSmsMsg(key, smsModel.getParams(), phoneNumbers);
            return ResultBody.ok();
        } catch (SmsException smsEx) {
            smsEx.printStackTrace();
            return ResultBody.failed(smsEx.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBody.failed(e.getMessage());
        }
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/java/com/kidgrow/sms/lanchuang/controller/SmsChuangLanController.java
New file
@@ -0,0 +1,156 @@
package com.kidgrow.sms.lanchuang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kidgrow.common.model.ResultBody;
import com.kidgrow.common.utils.DateUtils;
import com.kidgrow.redis.util.RedisUtils;
import com.kidgrow.sms.util.SmsChuangLanUtils;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@RequestMapping("smsChangLan")
@Api(tags = "创蓝短信模块")
public class SmsChuangLanController {
    @Value("${chuanglan.sms.sendUrl}")
    private String CHUANGLAN_SMS_SENDURL;
    @Value("${chuanglan.sms.account}")
    private String CHUANGLAN_SMS_ACCOUNT;
    @Value("${chuanglan.sms.password}")
    private String CHUANGLAN_SMS_PASSWORD;
    @Value("${chuanglan.sms.num}")
    private Integer CHUANGLAN_SMS_NUM;
    @Value("${chuanglan.sms.timeLimit}")
    private Integer CHUANGLAN_SMS_TIMELIMIT;
    @Autowired
    private RedisUtils redisUtils;
    /**
     * type  为类型, "type":"LOGIN_SMS"  为登录,"type":"PASSWORD_SMS" 为密码找回,"type":"REGISTER_SMS" 为
     * @param map
     * @return
     */
    @PostMapping("send")
    public ResultBody sendVerificationCode(@RequestBody Map map) {
        if(CHUANGLAN_SMS_NUM==null){
            CHUANGLAN_SMS_NUM=5;
        }
        Object phone = map.get("phone");
        if (map.get("phone")==null||"".equals(map.get("phone"))){
            return ResultBody.failed("请输入手机号");
        }
        Object type = map.get("type");
        if (map.get("type")==null||"".equals(map.get("type"))){
            return ResultBody.failed("请输入保存的类型");
        }
        String verificationCode="";
        Random random=new Random();
        for (int i = 0; i < 6; i++) {
            int i1 = random.nextInt(9);
            verificationCode+=i1;
        }
        try {
            //组装发送消息的内容
            map.put("account", CHUANGLAN_SMS_ACCOUNT);//API账号
            map.put("password", CHUANGLAN_SMS_PASSWORD);//API密码
            map.put("report","false");
            map.put("msg","您好,您的验证码是"+verificationCode);
            //在Redis中获取
            Object hget = redisUtils.hget(map.get("type").toString(), map.get("phone").toString());
            JSONObject jsonObject =new JSONObject();
            Map<String,Object> cunMap=new HashMap<>();
            cunMap.put("verificationCode",verificationCode);
            cunMap.put("count",CHUANGLAN_SMS_NUM);//总共
            if(hget==null){
                String send = SmsChuangLanUtils.send(map, CHUANGLAN_SMS_SENDURL);
                jsonObject=JSON.parseObject(send);
                String s1 = DateUtils.formatCurrentDateTime();
                cunMap.put("date",s1);
                cunMap.put("remnant",CHUANGLAN_SMS_NUM-1);//剩余
                Date date2 = DateUtils.addMilliseconds(DateUtils.parseDate(s1), CHUANGLAN_SMS_TIMELIMIT);
                cunMap.put("endTime",DateUtils.formatDateTime(date2));
            }else {
                JSONObject redisJson = JSON.parseObject(JSON.toJSONString(hget));
                Object remnantObject = redisJson.get("remnant");
                if(remnantObject instanceof Integer){
                    Integer remnant=(Integer)remnantObject;
                    if(remnant>0){
                        String send = SmsChuangLanUtils.send(map, CHUANGLAN_SMS_SENDURL);
                        jsonObject=JSON.parseObject(send);
                        String s1 = DateUtils.formatCurrentDateTime();
                        cunMap.put("date",DateUtils.formatCurrentDateTime());
                        cunMap.put("remnant",remnant-1);//剩余
                        Date date2 = DateUtils.addMilliseconds(DateUtils.parseDate(s1), CHUANGLAN_SMS_TIMELIMIT);
                        cunMap.put("endTime",DateUtils.formatDateTime(date2));
                    }else{
                        return ResultBody.failed().data("每个手机号限用"+CHUANGLAN_SMS_NUM+"次");
                    }
                }else {
                    return ResultBody.failed();
                }
            }
            if ("0".equals(jsonObject.get("code"))) {
                redisUtils.hset(map.get("type").toString(), map.get("phone").toString(),cunMap,DateUtils.getSecondsNextEarlyMorning());
//                return ResultBody.ok().data(verificationCode);
                return ResultBody.ok();
            } else {
                return ResultBody.failed();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBody.failed();
        }
    }
    @PostMapping("verification")
    public ResultBody verification(@RequestBody Map<String,Object> map){
        Object phone = map.get("phone");
        if (map.get("phone")==null||"".equals(map.get("phone"))){
            return ResultBody.failed("请输入手机号");
        }
        Object verificationCode = map.get("verificationCode");
        if (map.get("verificationCode")==null||"".equals(map.get("verificationCode"))){
            return ResultBody.failed("请输入保存的类型");
        }
        Object type = map.get("type");
        if (map.get("type")==null||"".equals(map.get("type"))){
            return ResultBody.failed("请输入保存的类型");
        }
        Object hget = redisUtils.hget(map.get("type").toString(), map.get("phone").toString());
        if(hget!=null){
            JSONObject redisJson = JSON.parseObject(JSON.toJSONString(hget));
            Object verificationCodeObject = redisJson.get("verificationCode");
            if(verificationCode.equals(verificationCodeObject)){
                Object date = redisJson.get("date");
                long time = DateUtils.addMilliseconds(DateUtils.parseDate(date.toString()), CHUANGLAN_SMS_TIMELIMIT).getTime();
                Date dateNow=new Date();
                long timeNow = dateNow.getTime();
                if(timeNow<=time){
                    return ResultBody.ok();
                }else {
                    return ResultBody.failed("验证码超时");
                }
            }else {
                return ResultBody.failed("验证码错误");
            }
        }else {
            return ResultBody.failed("该手机号没有验证码");
        }
    }
    //获取 存放 Redis的时间 秒(到今晚的秒数)
    public Long getSecondsNextEarlyMorning() {
        Date afterDay = DateUtils.getAfterDay(new Date());
        String s = DateUtils.formatDate(afterDay, null);
        Date date = DateUtils.parseDate(s);
        System.out.println(date.getTime()-System.currentTimeMillis());
        long second= (date.getTime()-System.currentTimeMillis())/1000;
        return second;
    }
}
kidgrow-business/kidgrow-filecenter/kidgrow-filecenter-server/src/main/resources/application.yml
@@ -37,6 +37,7 @@
kidgrow:
  #  fdfs:
  #    web-url: 192.168.28.130
@@ -87,3 +88,38 @@
#  trackerList: ${kidgrow.fdfs.trackerList}
#创蓝
chuanglan:
  sms:
    sendUrl: http://smssh1.253.com/msg/send/json
    account: N2561124
    password: Mguj6qlRWX7b5e
    num: 5
    timeLimit: 720000
#阿里云相关
aliyun:
  sms:
    accessKeyId: LTAIX1whVSBUUKNW
    accessKeySecret: j7UywJDoUkPRvGafKrik1pyYtEC2ys
    signName: 微课堂
    templates:
      ### 模板key
      key1:
        ## 模板code 需要在阿里云控制台设置
        templateCode: SMS_151231928 # 与阿里云设置的保持一致,模板内容需在后面加上,方便使用:****
      key2:
        templateCode: SMS_105665033 # 与阿里云设置的保持一致,模板内容需在后面加上,方便使用:****
  commonRequest:
    domain: dysmsapi.aliyuncs.com
    ## 版本号
    version: 2017-05-25
    ##
    action: SendSms
## 短信验证码过期时间,时间单位/秒
sms:
  verificationCode:
    ## 短信验证码过期时间,时间单位/秒
    timeOut: 120
    ##  缓存手机号key值前缀
    prefix: "sms:aliyun:code:"