Browse Source

短信验证码

chao 4 years ago
parent
commit
e59395546c

+ 0 - 11
pom.xml

@@ -52,17 +52,6 @@
             <groupId>org.mybatis.spring.boot</groupId>
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
             <version>2.1.4</version>
             <version>2.1.4</version>
-        </dependency>
-        <dependency>
-            <groupId>com.github.pagehelper</groupId>
-            <artifactId>pagehelper-spring-boot-starter</artifactId>
-            <version>1.3.0</version>
-            <exclusions>
-                <exclusion>
-                    <artifactId>mybatis-spring-boot-starter</artifactId>
-                    <groupId>org.mybatis.spring.boot</groupId>
-                </exclusion>
-            </exclusions>
         </dependency>
         </dependency>
 		<dependency>
 		<dependency>
 			<groupId>org.projectlombok</groupId>
 			<groupId>org.projectlombok</groupId>

+ 6 - 7
src/main/java/com/caimei365/user/controller/UserApi.java

@@ -32,19 +32,18 @@ public class UserApi {
         return userService.getCaptchaImage(platformType);
         return userService.getCaptchaImage(platformType);
     }
     }
 
 
-
     /**
     /**
-     * 短信验证码
+     * 获取短信验证码
      * spi旧接口:/user/activateCodeByReg
      * spi旧接口:/user/activateCodeByReg
-     * @param mobile
+     * @param mobile           手机号
      * @param activateCodeType 1:找回密码,2:手机号注册机构,3:供应商注册
      * @param activateCodeType 1:找回密码,2:手机号注册机构,3:供应商注册
-     * @param imgCode
-     * @param token
-     * @return
+     * @param imgCode          图片验证码
+     * @param token            图片验证码token
+     * @param platformType     0:www,1:crm/h5,2:小程序
      */
      */
     @GetMapping("/sms/code")
     @GetMapping("/sms/code")
     public JsonModel getSmsCode(String mobile, String activateCodeType, String imgCode, String token, Integer platformType) {
     public JsonModel getSmsCode(String mobile, String activateCodeType, String imgCode, String token, Integer platformType) {
-        return null;//loginService.activateCodeByReg(mobile, activateCodeType, imgCode, token, platformType);
+        return userService.getSmsCode(mobile, activateCodeType, imgCode, token, platformType);
     }
     }
 
 
 
 

+ 22 - 0
src/main/java/com/caimei365/user/mapper/BaseUserDao.java

@@ -0,0 +1,22 @@
+package com.caimei365.user.mapper;
+
+import com.caimei365.user.model.BaseUser;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/3/5
+ */
+@Mapper
+public interface BaseUserDao {
+    /**
+     * 根据手机号或邮箱获取用户
+     *
+     * @param mobileOrEmail
+     * @return
+     */
+    BaseUser selectByMobileOrEmail(@Param("mobileOrEmail") String mobileOrEmail, @Param("source") String source);
+}

+ 23 - 0
src/main/java/com/caimei365/user/service/UserService.java

@@ -15,6 +15,29 @@ public interface UserService {
      * 获取图片验证码
      * 获取图片验证码
      *
      *
      * @param platformType 0:www,1:crm/h5,2:小程序
      * @param platformType 0:www,1:crm/h5,2:小程序
+     * @return Map<String, Object>
      */
      */
     JsonModel<Map<String, Object>> getCaptchaImage(Integer platformType);
     JsonModel<Map<String, Object>> getCaptchaImage(Integer platformType);
+
+    /**
+     * 校验图片验证码
+     *
+     * @param token        图片验证码token
+     * @param imgCode      图片验证码
+     * @param platformType 0:www,1:crm/h5,2:小程序
+     * @return Boolean
+     */
+    Boolean checkCaptchaImage(String token, String imgCode, Integer platformType);
+
+    /**
+     * 获取短信验证码
+     *
+     * @param mobile           手机号
+     * @param activateCodeType 1:找回密码,2:手机号注册机构,3:供应商注册
+     * @param imgCode          图片验证码
+     * @param token            图片验证码token
+     * @param platformType     0:www,1:crm/h5,2:小程序
+     * @return void
+     */
+    JsonModel getSmsCode(String mobile, String activateCodeType, String imgCode, String token, Integer platformType);
 }
 }

+ 87 - 0
src/main/java/com/caimei365/user/service/impl/UserServiceImpl.java

@@ -1,10 +1,16 @@
 package com.caimei365.user.service.impl;
 package com.caimei365.user.service.impl;
 
 
+import com.caimei365.user.mapper.BaseUserDao;
+import com.caimei365.user.model.BaseUser;
 import com.caimei365.user.model.JsonModel;
 import com.caimei365.user.model.JsonModel;
 import com.caimei365.user.service.RedisService;
 import com.caimei365.user.service.RedisService;
 import com.caimei365.user.service.UserService;
 import com.caimei365.user.service.UserService;
+import com.caimei365.user.utils.AliyunSmsUtil;
+import com.caimei365.user.utils.CodeUtil;
 import com.caimei365.user.utils.ImageCaptchaUtil;
 import com.caimei365.user.utils.ImageCaptchaUtil;
+import com.caimei365.user.utils.ValidateUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
@@ -24,6 +30,8 @@ public class UserServiceImpl implements UserService {
 
 
     @Resource
     @Resource
     private RedisService redisService;
     private RedisService redisService;
+    @Resource
+    private BaseUserDao baseUserDao;
 
 
     /**
     /**
      * 获取图片验证码
      * 获取图片验证码
@@ -54,4 +62,83 @@ public class UserServiceImpl implements UserService {
             return JsonModel.error("获取图片验证码异常", null);
             return JsonModel.error("获取图片验证码异常", null);
         }
         }
     }
     }
+
+    /**
+     * 校验图片验证码
+     *
+     * @param token        图片验证码token
+     * @param imgCode      图片验证码
+     * @param platformType 0:www,1:crm/h5,2:小程序
+     * @return Boolean
+     */
+    @Override
+    public Boolean checkCaptchaImage(String token, String imgCode, Integer platformType) {
+        if (token.isEmpty() || imgCode.isEmpty()){
+            return false;
+        }
+        String captchaKey = ImageCaptchaUtil.getCaptchaKey(token, platformType);
+        String captchaCode = (String) redisService.get(captchaKey);
+        if (!captchaCode.isEmpty() && StringUtils.equalsIgnoreCase(imgCode, captchaCode)) {
+            // 校验成功
+            return true;
+        }
+        // 不管验证是否成功删除旧的图片验证码
+        redisService.remove(captchaKey);
+        return false;
+    }
+
+    /**
+     * 获取短信验证码
+     *
+     * @param mobile           手机号
+     * @param activateCodeType 1:找回密码,2:手机号注册机构,3:供应商注册
+     * @param imgCode          图片验证码
+     * @param token            图片验证码token
+     * @param platformType     0:www,1:crm/h5,2:小程序
+     */
+    @Override
+    public JsonModel getSmsCode(String mobile, String activateCodeType, String imgCode, String token, Integer platformType) {
+        Boolean checkFlag = checkCaptchaImage(token, imgCode, platformType);
+        if (checkFlag) {
+            // 验证手机号
+            JsonModel mobileModel = ValidateUtil.validateMobile(mobile);
+            if (mobileModel.getCode() == -1) {
+                return mobileModel;
+            }
+            boolean sendFlag = false;
+            // 生成六位验证码
+            String randomCode = CodeUtil.generateCodeInt(6);
+            // 根据手机号查询用户
+            BaseUser baseUser = baseUserDao.selectByMobileOrEmail(mobile, "www");
+            if ("1".equals(activateCodeType)) {
+                if (null == baseUser) {
+                    return JsonModel.error("该手机号尚未注册");
+                }
+                // 修改密码
+                sendFlag = AliyunSmsUtil.sendSms(mobile, 1, "{code:" + randomCode + "}");
+            } else {
+                if (null != baseUser) {
+                    return JsonModel.error("该手机号已被使用");
+                }
+                if ("2".equals(activateCodeType)) {
+                    // 机构用户(自主)注册
+                    sendFlag = AliyunSmsUtil.sendSms(mobile, 8, "{code:"+ randomCode +"}");
+                } else if ("3".equals(activateCodeType)) {
+                    // 供应商(自主)注册
+                    sendFlag = AliyunSmsUtil.sendSms(mobile, 9, "{code:"+ randomCode +"}");
+                } else {
+                    return JsonModel.error("参数错误:activateCodeType");
+                }
+            }
+            if (sendFlag) {
+                redisService.set("code:"+mobile, randomCode, 1800L);
+                log.info("你发送的手机验证码: " + randomCode);
+            } else {
+                return JsonModel.error("验证码发送失败!请稍后重试");
+            }
+        } else {
+            return JsonModel.error("图片验证码错误");
+        }
+        return JsonModel.success("发送验证码成功");
+    }
 }
 }

+ 7 - 6
src/main/java/com/caimei365/user/utils/AliyunSmsUtil.java

@@ -11,7 +11,7 @@ import com.aliyuncs.profile.IClientProfile;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 
 
 /**
 /**
- * 阿里云短信
+ * 阿里云短信Sms
  *
  *
  * @author : Charles
  * @author : Charles
  * @date : 2021/3/5
  * @date : 2021/3/5
@@ -101,11 +101,12 @@ public class AliyunSmsUtil {
             SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
             SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
             if(sendSmsResponse.getCode() != null && "OK".equals(sendSmsResponse.getCode())) {
             if(sendSmsResponse.getCode() != null && "OK".equals(sendSmsResponse.getCode())) {
                 //请求成功
                 //请求成功
-                System.out.println("----------------阿里云短信接口返回的数据----------------");
-                System.out.println("Code=" + sendSmsResponse.getCode());
-                System.out.println("Message=" + sendSmsResponse.getMessage());
-                System.out.println("RequestId=" + sendSmsResponse.getRequestId());
-                System.out.println("BizId=" + sendSmsResponse.getBizId());
+                log.info(">----阿里云短信接口返回的数据: "
+                          +",Code="+ sendSmsResponse.getCode()
+                          +",Code=" + sendSmsResponse.getCode()
+                          +",Message=" + sendSmsResponse.getMessage()
+                          +",RequestId=" + sendSmsResponse.getRequestId()
+                          +",BizId=" + sendSmsResponse.getBizId());
                 return true;
                 return true;
             } else {
             } else {
                 return false;
                 return false;

+ 84 - 0
src/main/java/com/caimei365/user/utils/CodeUtil.java

@@ -0,0 +1,84 @@
+package com.caimei365.user.utils;
+
+import java.util.Random;
+
+public class CodeUtil {
+
+    private static char codeSequence[] = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
+            'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+            'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7',
+            '8', '9'
+    };
+
+    private static char intSequence[] = {
+            '2', '3', '4', '5', '6', '7',
+            '8', '9'
+    };
+
+    private static char stringSequence[] = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
+            'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+            'W', 'X', 'Y', 'Z'
+    };
+
+    private static char newStringSequence[] = {
+            'A', 'a', 'B', 'b', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g', 'H', 'h',
+            'L', 'N', 'n', 'Q', 'q', 'R', 'r', 'T', 't', 'Y', 'y'
+    };
+
+    public static String generateCode(int length) {
+        StringBuffer sb = new StringBuffer();
+        Random random = new Random();
+        for (int i = 0; i < codeSequence.length && i < length; ++i) {
+            sb.append(codeSequence[random.nextInt(codeSequence.length)]);
+        }
+        return sb.toString();
+    }
+
+    public static String generateCodeInt(int length) {
+        StringBuffer sb = new StringBuffer();
+        Random random = new Random();
+        for (int i = 0; i < intSequence.length && i < length; ++i) {
+            sb.append(intSequence[random.nextInt(intSequence.length)]);
+        }
+        return sb.toString();
+    }
+
+    public static String generateCodeString(int length) {
+        StringBuffer sb = new StringBuffer();
+        Random random = new Random();
+        for (int i = 0; i < stringSequence.length && i < length; ++i) {
+            sb.append(stringSequence[random.nextInt(stringSequence.length)]);
+        }
+        return sb.toString();
+    }
+
+
+    public static String getRandomCharAndNumr(int length) {
+        String val = "";
+        Random random = new Random();
+        for (int i = 0; i < length; i++) {
+            // 输出字母还是数字
+            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
+            // 字符串
+            if ("char".equalsIgnoreCase(charOrNum)) {
+                // 取得大写字母还是小写字母
+                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
+                val += (char) (choice + random.nextInt(26));
+            } else if ("num".equalsIgnoreCase(charOrNum)) {
+                val += String.valueOf(random.nextInt(10));
+            }
+        }
+        return val;
+    }
+
+    public static String generateAccount(int length) {
+        StringBuffer sb = new StringBuffer();
+        Random random = new Random();
+        for (int i = 0; i < newStringSequence.length && i < length; ++i) {
+            sb.append(newStringSequence[random.nextInt(newStringSequence.length)]);
+        }
+        return sb.toString();
+    }
+}

+ 171 - 0
src/main/java/com/caimei365/user/utils/ValidateUtil.java

@@ -0,0 +1,171 @@
+package com.caimei365.user.utils;
+
+import com.caimei365.user.model.JsonModel;
+import com.github.pagehelper.util.StringUtil;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/3/5
+ */
+public class ValidateUtil {
+    /** 手机号码验证格式 */
+    private static final String MOBILE_PATTERN = "^1[1-9]\\d{9}$";
+    /** 邮箱验证格式 */
+    private static final String EMAIL_PATTERN = "^\\s*?(.+)@(.+?)\\s*$";
+    /** 密码验证格式 */
+    private static final String PASSWORD_PATTERN = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";
+    /** 机构名称验证格式 */
+    private static final String CLUB_NAME_PATTERN = "^[a-zA-Z0-9\u4e00-\u9fa5]{1,200}$";
+    /** 用户名称验证格式 */
+    private static final String USER_CN_NAME_PATTERN = "^[\u4e00-\u9fa5]{2,8}$";
+    private static final String USER_EN_NAME_PATTERN = "^[a-zA-Z]{2,16}";
+    /** 统一社会信用代码验证格式 */
+    private static final String SOCIAL_CREDIT_CODE_PATTERN = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$";
+
+    /**
+     * 验证手机号码格式
+     *
+     * @param mobile 手机号
+     */
+    public static JsonModel validateMobile(String mobile) {
+        if (StringUtil.isEmpty(mobile) || StringUtils.isBlank(mobile)) {
+            return JsonModel.error("手机号不可为空");
+        } else {
+            Pattern pattern = Pattern.compile(MOBILE_PATTERN);
+            Matcher matcher = pattern.matcher(mobile);
+            if (matcher.matches()) {
+                return JsonModel.success();
+            } else {
+                return JsonModel.error("手机号码格式不正确");
+            }
+        }
+    }
+
+    /**
+     * 验证简单的邮箱格式
+     *
+     * @param email 邮箱
+     */
+    public static boolean validateEmail(String email) {
+        if (StringUtil.isEmpty(email) || StringUtils.isBlank(email)) {
+            return false;
+        } else {
+            Pattern pattern = Pattern.compile(EMAIL_PATTERN);
+            Matcher matcher = pattern.matcher(email);
+            return matcher.matches();
+        }
+    }
+
+    /**
+     * 密码验证
+     */
+    public static JsonModel validatePassWord(String password) {
+        if (StringUtils.isEmpty(password) || StringUtils.isBlank(password)) {
+            return JsonModel.error("密码不可为空");
+        }
+        if (password.length() > 16 || password.length() < 8) {
+            return JsonModel.error("密码长度不正确(8-16)");
+        }
+        Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
+        Matcher matcher = pattern.matcher(password);
+        if (matcher.matches()) {
+            return JsonModel.success();
+        } else {
+            return JsonModel.error("请输入8-16位字符,需字母数字组合。");
+        }
+    }
+
+    /**
+     * 确认密码验证
+     */
+    public static JsonModel validatePassWordConfirm(String password, String passWordConfirm) {
+        if (StringUtils.isEmpty(passWordConfirm) || StringUtils.isBlank(passWordConfirm)) {
+            return JsonModel.error("确认密码不可为空");
+        }
+        if (!password.equals(passWordConfirm)) {
+            return JsonModel.error("确认密码与登录密码不一致");
+        }
+        return JsonModel.success();
+    }
+
+    /**
+     * 验证机构名称
+     */
+    public static JsonModel validateClubName(String name) {
+        if (StringUtils.isEmpty(name) || StringUtils.isBlank(name)) {
+            return JsonModel.error("请填写美容机构名称");
+        } else {
+            Pattern pattern = Pattern.compile(CLUB_NAME_PATTERN);
+            Matcher matcher = pattern.matcher(name);
+            if (matcher.matches()) {
+                return JsonModel.success();
+            } else {
+                return JsonModel.error("机构名称格式不正确");
+            }
+        }
+    }
+
+    /**
+     * 验证姓名为中文:匹配2-8个中文字或不超过16位的英文
+     */
+    public static JsonModel validateUserName(String name) {
+        if (StringUtils.isEmpty(name) || StringUtils.isBlank(name) || name.length() < 2) {
+            return JsonModel.error("请输入真实名称");
+        } else {
+            // 判断中文名
+            Pattern pattern = Pattern.compile(USER_CN_NAME_PATTERN);
+            Matcher matcher = pattern.matcher(name);
+            if (matcher.find()) {
+                return JsonModel.success();
+            } else {
+                // 判断英文名
+                pattern = Pattern.compile(USER_EN_NAME_PATTERN);
+                matcher = pattern.matcher(name);
+                if (matcher.matches()) {
+                    return JsonModel.success();
+                } else {
+                    return JsonModel.error("名称格式不正确");
+                }
+            }
+        }
+    }
+
+    /**
+     * 验证地址格式:长度不超过50
+     *
+     * @param address
+     * @return JsonForm验证信息
+     */
+    public static JsonModel validateAddress(String address) {
+        if (StringUtils.isEmpty(address) || StringUtils.isBlank(address)) {
+            return JsonModel.error("请输入您的详细街道地址");
+        }
+        if (address.length() > 50) {
+            return JsonModel.error("地址过长");
+        }
+        return JsonModel.success();
+    }
+
+    /**
+     * 统一社会信用代码验证
+     */
+    public static JsonModel validateSocialCreditCode(String socialCreditCode) {
+        if (StringUtil.isEmpty(socialCreditCode) || StringUtils.isBlank(socialCreditCode)) {
+            return JsonModel.error("请输入您的统一社会信用代码");
+        } else {
+            Pattern pattern = Pattern.compile(SOCIAL_CREDIT_CODE_PATTERN);
+            Matcher matcher = pattern.matcher(socialCreditCode);
+            if (matcher.matches()) {
+                return JsonModel.success();
+            } else {
+                return JsonModel.error("统一社会信用代码格式不正确");
+            }
+        }
+    }
+}

+ 20 - 0
src/main/resources/mapper/BaseUserMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.caimei365.user.mapper.BaseUserDao">
+    <select id="selectByMobileOrEmail" resultType="com.caimei365.user.model.BaseUser">
+        select u.*,cu.mobile as operatorMobile from user u
+        left join cm_mall_operation_user cu on cu.userID = u.userID
+        where (u.bindMobile = #{mobileOrEmail}
+        or u.email = #{mobileOrEmail}
+        or (cu.mobile = #{mobileOrEmail} and cu.delFlag != 1))
+        AND u.userIdentity IN (1,2,3,4)
+        AND (u.userOrganizeID = '2' OR u.userOrganizeID IS NULL)
+        <if test="source == 'www'">
+            AND u.registerUserTypeID IN (1,3,4)
+        </if>
+        <if test="source == 'crm'">
+            AND u.registerUserTypeID IN (1,2,3,32,4)
+        </if>
+        LIMIT 1
+    </select>
+</mapper>