Jelajahi Sumber

新增手机验证码登录

wangliang 1 tahun lalu
induk
melakukan
846320e93b

+ 82 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/dto/VerifyCodeCheckDto.java

@@ -0,0 +1,82 @@
+package com.qmth.sop.business.bean.dto;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.sop.common.base.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description: 短信验证码校验dto
+ * @Author: CaoZixuan
+ * @Date: 2021-10-09
+ */
+public class VerifyCodeCheckDto extends BaseEntity {
+
+    @ApiModelProperty(value = "机构id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long orgId;
+
+    @ApiModelProperty(value = "发送用户id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    @ApiModelProperty(value = "发送用户手机号")
+    private String mobilePhone;
+
+    @ApiModelProperty(value = "到期时间")
+    private Long expireTime;
+
+    @ApiModelProperty(value = "延期时间(分钟)")
+    private Integer validPeriod;
+
+    @ApiModelProperty(value = "四位验证码")
+    private String verifyCode;
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getMobilePhone() {
+        return mobilePhone;
+    }
+
+    public void setMobilePhone(String mobilePhone) {
+        this.mobilePhone = mobilePhone;
+    }
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public Integer getValidPeriod() {
+        return validPeriod;
+    }
+
+    public void setValidPeriod(Integer validPeriod) {
+        this.validPeriod = validPeriod;
+    }
+
+    public String getVerifyCode() {
+        return verifyCode;
+    }
+
+    public void setVerifyCode(String verifyCode) {
+        this.verifyCode = verifyCode;
+    }
+}

+ 4 - 2
sop-business/src/main/java/com/qmth/sop/business/entity/BasicVerifyCode.java

@@ -46,9 +46,10 @@ public class BasicVerifyCode extends BaseEntity implements Serializable {
 
     }
 
-    public BasicVerifyCode(Long userId, String mobileNumber, Long expireTime, Integer validPeriod, String verifyCode) {
+    public BasicVerifyCode(Long userId, Long orgId, String mobileNumber, Long expireTime, Integer validPeriod, String verifyCode) {
         setId(SystemConstant.getDbUuid());
         this.userId = userId;
+        this.orgId = orgId;
         this.mobileNumber = mobileNumber;
         this.expireTime = expireTime;
         this.validPeriod = validPeriod;
@@ -57,8 +58,9 @@ public class BasicVerifyCode extends BaseEntity implements Serializable {
         setCreateTime(System.currentTimeMillis());
     }
 
-    public void updateVerifyCodeInfo(Long userId, Long expireTime, Integer validPeriod, String verifyCode) {
+    public void updateVerifyCodeInfo(Long userId, Long orgId, Long expireTime, Integer validPeriod, String verifyCode) {
         this.expireTime = expireTime;
+        this.orgId = orgId;
         this.validPeriod = validPeriod;
         this.verifyCode = verifyCode;
         setUpdateId(userId);

+ 19 - 0
sop-business/src/main/java/com/qmth/sop/business/mapper/SysUserMapper.java

@@ -1,6 +1,7 @@
 package com.qmth.sop.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.sop.business.bean.dto.VerifyCodeCheckDto;
 import com.qmth.sop.business.bean.result.SysUserResult;
 import com.qmth.sop.business.entity.SysUser;
 import org.apache.ibatis.annotations.Param;
@@ -32,4 +33,22 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
      * @return
      */
     List<SysUserResult> findSysUserResultList(@Param("orgId") Long orgId);
+
+    /**
+     * 根据用户(id和手机号)查询验证码发送几率
+     *
+     * @param userId       用户id
+     * @param mobileNumber 用户手机号
+     * @return 更新条数
+     */
+    int updateVerifyCodeExpiredTime(@Param("userId") Long userId, @Param("mobileNumber") String mobileNumber);
+
+    /**
+     * 根据用户(id和手机号)查询验证码发送几率
+     *
+     * @param userId       用户id
+     * @param mobileNumber 用户手机号
+     * @return 验证码记录结果
+     */
+    List<VerifyCodeCheckDto> findVerifyCodeByUser(@Param("userId") Long userId, @Param("mobileNumber") String mobileNumber);
 }

+ 17 - 0
sop-business/src/main/java/com/qmth/sop/business/service/SysUserService.java

@@ -45,4 +45,21 @@ public interface SysUserService extends IService<SysUser> {
      * @return
      */
     List<SysUserResult> findSysUserResultList(Long orgId);
+
+    /**
+     * 强行过期用户手机号验证码(过期时间改为验证码发送时间)
+     *
+     * @param userId       用户id
+     * @param mobileNumber 用户手机号
+     */
+    void expiredVerifyCode(Long userId, String mobileNumber);
+
+    /**
+     * 校验短信验证码
+     *
+     * @param userId       用户id
+     * @param mobileNumber 用户手机号
+     * @param code         验证码
+     */
+    void checkSmsCode(Long userId, String mobileNumber, String code);
 }

+ 2 - 2
sop-business/src/main/java/com/qmth/sop/business/service/impl/BasicVerifyCodeServiceImpl.java

@@ -77,9 +77,9 @@ public class BasicVerifyCodeServiceImpl extends ServiceImpl<BasicVerifyCodeMappe
                 Optional.ofNullable(sysConfigSmsExpiredTime).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置短信验证码有效时间"));
                 Integer codeExpiredTime = Integer.parseInt(sysConfigSmsExpiredTime.getConfigValue());
                 if (Objects.isNull(basicVerifyCode)) {
-                    basicVerifyCode = new BasicVerifyCode(sysUser.getId(), mobileNumber, SystemConstant.processMiniute(Duration.ofMinutes(2)), codeExpiredTime, verifyCode);
+                    basicVerifyCode = new BasicVerifyCode(sysUser.getId(), sysUser.getOrgId(), mobileNumber, SystemConstant.processMiniute(Duration.ofMinutes(2)), codeExpiredTime, verifyCode);
                 } else {
-                    basicVerifyCode.updateVerifyCodeInfo(sysUser.getId(), SystemConstant.processMiniute(Duration.ofMinutes(2)), codeExpiredTime, verifyCode);
+                    basicVerifyCode.updateVerifyCodeInfo(sysUser.getId(), sysUser.getOrgId(), SystemConstant.processMiniute(Duration.ofMinutes(2)), codeExpiredTime, verifyCode);
                 }
                 this.saveOrUpdate(basicVerifyCode);
             } else {

+ 48 - 0
sop-business/src/main/java/com/qmth/sop/business/service/impl/SysUserServiceImpl.java

@@ -4,9 +4,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.core.enums.Platform;
 import com.qmth.sop.business.bean.auth.AuthBean;
 import com.qmth.sop.business.bean.auth.ExpireTimeBean;
+import com.qmth.sop.business.bean.dto.VerifyCodeCheckDto;
 import com.qmth.sop.business.bean.result.LoginResult;
 import com.qmth.sop.business.bean.result.SysUserResult;
 import com.qmth.sop.business.cache.CommonCacheService;
+import com.qmth.sop.business.entity.SysConfig;
 import com.qmth.sop.business.entity.SysRole;
 import com.qmth.sop.business.entity.SysUser;
 import com.qmth.sop.business.entity.TBSession;
@@ -21,6 +23,7 @@ import com.qmth.sop.common.util.IpUtil;
 import com.qmth.sop.common.util.ServletUtil;
 import com.qmth.sop.common.util.SessionUtil;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.security.NoSuchAlgorithmException;
@@ -125,4 +128,49 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     public List<SysUserResult> findSysUserResultList(Long orgId) {
         return this.baseMapper.findSysUserResultList(orgId);
     }
+
+    /**
+     * 强行过期用户手机号验证码(过期时间改为验证码发送时间)
+     *
+     * @param userId       用户id
+     * @param mobileNumber 用户手机号
+     */
+    @Override
+    @Transactional
+    public void expiredVerifyCode(Long userId, String mobileNumber) {
+        SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SYS_CODE_ENABLE);
+        Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未启用短信验证码"));
+        Boolean enable = Boolean.valueOf(sysConfig.getConfigValue());
+        if (enable) {
+            int count = this.baseMapper.updateVerifyCodeExpiredTime(userId, mobileNumber);
+            if (count != 1) {
+                throw ExceptionResultEnum.ERROR.exception("验证码过期失败");
+            }
+        }
+    }
+
+    @Override
+    public void checkSmsCode(Long userId, String mobileNumber, String code) {
+        SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SYS_CODE_ENABLE);
+        Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未启用短信验证码"));
+        Boolean enable = Boolean.valueOf(sysConfig.getConfigValue());
+        if (enable) {
+            SysConfig sysConfigNormal = commonCacheService.addSysConfigCache(SystemConstant.SMS_NORMAL_CODE);
+            Optional.ofNullable(sysConfigNormal).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置万能短信验证码"));
+            if (!sysConfigNormal.getConfigValue().equals(code)) {
+                List<VerifyCodeCheckDto> verifyCodeCheckDtoList = this.baseMapper.findVerifyCodeByUser(userId, mobileNumber);
+                if (verifyCodeCheckDtoList.size() < 1) {
+                    throw ExceptionResultEnum.ERROR.exception("验证码错误");
+                }
+                VerifyCodeCheckDto accessControl = verifyCodeCheckDtoList.get(0);
+                if (accessControl == null || !accessControl.getVerifyCode().equals(code)) {
+                    throw ExceptionResultEnum.ERROR.exception("验证码错误");
+                }
+
+                if (new Date(accessControl.getExpireTime()).before(new Date())) {
+                    throw ExceptionResultEnum.ERROR.exception("验证码已过期");
+                }
+            }
+        }
+    }
 }

+ 38 - 0
sop-business/src/main/resources/mapper/SysUserMapper.xml

@@ -35,4 +35,42 @@
         so.id
         order by su.login_name
     </select>
+
+    <update id="updateVerifyCodeExpiredTime">
+        UPDATE basic_verify_code SET expire_time = create_time
+        <where>
+            <if test="mobileNumber != null and mobileNumber != ''">
+                and mobile_number = #{mobileNumber}
+            </if>
+            <if test="userId != null and userId != ''">
+                and user_id = #{userId}
+            </if>
+        </where>
+    </update>
+
+    <select id="findVerifyCodeByUser" resultType="com.qmth.sop.business.bean.dto.VerifyCodeCheckDto">
+        SELECT
+        id,
+        org_id AS orgId,
+        user_id AS userId,
+        mobile_number AS mobileNumber,
+        expire_time AS expireTime,
+        valid_period AS validPeriod,
+        verify_code AS verifyCode,
+        create_id AS createId,
+        create_time AS createTime,
+        update_id AS updateId,
+        update_time AS updateTime
+        FROM
+        basic_verify_code
+        <where>
+            <if test="userId != null and userId != ''">
+                AND user_id = #{userId}
+            </if>
+            <if test="mobileNumber != null and mobileNumber != ''">
+                AND mobile_number = #{mobileNumber}
+            </if>
+        </where>
+        ORDER BY update_time DESC
+    </select>
 </mapper>

+ 9 - 4
sop-server/src/main/java/com/qmth/sop/server/api/SysController.java

@@ -103,6 +103,7 @@ public class SysController {
                 throw ExceptionResultEnum.ERROR.exception("查出多个用户");
             }
             sysUser = sysUserList.get(0);
+            Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未查询到用户"));
 
             if (!Objects.equals(sysUser.getPassword(), login.getPassword())) {
                 throw ExceptionResultEnum.ERROR.exception("用户名或密码错误");
@@ -114,9 +115,6 @@ public class SysController {
             SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SMS_NORMAL_CODE);
             Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置万能短信验证码"));
 
-            if (!Objects.equals(sysConfig.getConfigValue().trim(), login.getCode().trim())) {
-
-            }
             sysUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getMobileNumber, login.getMobileNumber()));
             if (CollectionUtils.isEmpty(sysUserList)) {
                 throw ExceptionResultEnum.ERROR.exception("用户不存在");
@@ -125,8 +123,15 @@ public class SysController {
                 throw ExceptionResultEnum.ERROR.exception("查出多个用户");
             }
             sysUser = sysUserList.get(0);
+            Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未查询到用户"));
+
+            // 校验验证码
+            sysUserService.checkSmsCode(sysUser.getId(), sysUser.getMobileNumber(), login.getCode());
+
+            if (!Objects.equals(sysConfig.getConfigValue().trim(), login.getCode().trim())) {
+                sysUserService.expiredVerifyCode(sysUser.getId(), sysUser.getMobileNumber());
+            }
         }
-        Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未查询到用户"));
         return ResultUtil.ok(sysUserService.login(login.getPassword(), sysUser, AppSourceEnum.SYSTEM));
     }