Преглед на файлове

feat : 用户注册, 修改密码的接口代码提交

bilingfeng преди 2 години
родител
ревизия
09b155f1a3

+ 36 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/entity/User.java

@@ -3,6 +3,9 @@ package com.zanxiang.sdk.domain.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.zanxiang.sdk.domain.enums.AccountStatusEnum;
+import com.zanxiang.sdk.domain.params.RegisterMobileParam;
+import com.zanxiang.sdk.domain.params.RegisterPasswordParam;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -107,4 +110,37 @@ public class User {
      * 更改时间
      */
     private LocalDateTime updateTime;
+
+    /**
+     * 用户名密码注册
+     *
+     * @param param    : 注册参数
+     * @param password : 密码
+     */
+    public User(RegisterPasswordParam param, String password) {
+        this.username = param.getUsername();
+        this.password = password;
+        this.deviceId = param.getDeviceId();
+        this.deviceType = param.getDeviceType();
+        this.status = AccountStatusEnum.NORMAL_STATUS.getStatus();
+        this.createTime = LocalDateTime.now();
+        this.updateTime = this.createTime;
+    }
+
+    /**
+     * 用户手机注册
+     *
+     * @param param    : 注册参数
+     * @param password : 密码
+     */
+    public User(RegisterMobileParam param, String password) {
+        this.username = param.getMobile();
+        this.regMobile = param.getMobile();
+        this.password = password;
+        this.deviceId = param.getDeviceId();
+        this.deviceType = param.getDeviceType();
+        this.status = AccountStatusEnum.NORMAL_STATUS.getStatus();
+        this.createTime = LocalDateTime.now();
+        this.updateTime = this.createTime;
+    }
 }

+ 33 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/entity/WordCheck.java

@@ -0,0 +1,33 @@
+package com.zanxiang.sdk.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description : 敏感词检测
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@TableName("h_word_check")
+public class WordCheck {
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 敏感词
+     */
+    private String word;
+}

+ 5 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/LoginMobileParam.java

@@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonAlias;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import javax.validation.constraints.NotBlank;
+
 /**
  * @author : lingfeng
  * @time : 2022-06-07
@@ -16,18 +18,21 @@ public class LoginMobileParam extends CommonParam {
     /**
      * 验证码类型
      */
+    @NotBlank(message = "验证码类型不可为空")
     @JsonAlias("sms-type")
     private Integer type;
 
     /**
      * 手机号
      */
+    @NotBlank(message = "手机号不可为空")
     @JsonAlias("sms-mobile")
     private String mobile;
 
     /**
      * 验证码
      */
+    @NotBlank(message = "验证码不可为空")
     @JsonAlias("sms-code")
     private String code;
 }

+ 45 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/RegisterMobileParam.java

@@ -0,0 +1,45 @@
+package com.zanxiang.sdk.domain.params;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-13
+ * @description : 手机注册参数
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RegisterMobileParam extends CommonParam {
+
+    /**
+     * 验证码类型
+     */
+    @NotBlank(message = "验证码类型不可为空")
+    @JsonAlias("sms-type")
+    private Integer type;
+
+    /**
+     * 手机号
+     */
+    @NotBlank(message = "手机号不可为空")
+    @JsonAlias("sms-mobile")
+    private String mobile;
+
+    /**
+     * 验证码
+     */
+    @NotBlank(message = "验证码不可为空")
+    @JsonAlias("sms-code")
+    private String code;
+
+    /**
+     * 密码
+     */
+    @NotBlank(message = "登陆密码不可为空")
+    @JsonAlias("mem-password")
+    private String password;
+}

+ 31 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/RegisterPasswordParam.java

@@ -0,0 +1,31 @@
+package com.zanxiang.sdk.domain.params;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description : 用户名密码注册
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RegisterPasswordParam extends CommonParam {
+
+    /**
+     * 用户名
+     */
+    @JsonAlias("mem-username")
+    @NotBlank(message = "注册用户名字不可为空")
+    private String username;
+
+    /**
+     * 密码
+     */
+    @NotBlank(message = "注册密码不可为空")
+    @JsonAlias("mem-password")
+    private String password;
+}

+ 50 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/domain/params/UpdatePasswordParam.java

@@ -0,0 +1,50 @@
+package com.zanxiang.sdk.domain.params;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description : 修改密码参数
+ */
+@Data
+public class UpdatePasswordParam {
+
+    /**
+     * 用户名
+     */
+    @JsonAlias("mem-username")
+    @NotBlank(message = "注册用户名字不可为空")
+    private String username;
+
+    /**
+     * 新密码
+     */
+    @NotBlank(message = "新密码不可为空")
+    @JsonAlias("mem-password")
+    private String password;
+
+    /**
+     * 验证码类型
+     */
+    @NotBlank(message = "验证码类型不可为空")
+    @JsonAlias("sms-type")
+    private Integer type;
+
+    /**
+     * 手机号
+     */
+    @NotBlank(message = "手机号不可为空")
+    @JsonAlias("sms-mobile")
+    private String mobile;
+
+    /**
+     * 验证码
+     */
+    @NotBlank(message = "验证码不可为空")
+    @JsonAlias("sms-code")
+    private String code;
+}

+ 12 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/mapper/WordCheckMapper.java

@@ -0,0 +1,12 @@
+package com.zanxiang.sdk.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.sdk.domain.entity.WordCheck;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description : ${description}
+ */
+public interface WordCheckMapper extends BaseMapper<WordCheck> {
+}

+ 26 - 2
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/IUserService.java

@@ -4,8 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.common.domain.ResultVo;
 import com.zanxiang.sdk.domain.dto.UserDTO;
 import com.zanxiang.sdk.domain.entity.User;
-import com.zanxiang.sdk.domain.params.LoginMobileParam;
-import com.zanxiang.sdk.domain.params.LoginPasswordParam;
+import com.zanxiang.sdk.domain.params.*;
 import com.zanxiang.sdk.domain.vo.UserLoginVO;
 
 import javax.servlet.http.HttpServletRequest;
@@ -17,6 +16,23 @@ import javax.servlet.http.HttpServletRequest;
  */
 public interface IUserService extends IService<User> {
 
+    /**
+     * 普通注册
+     *
+     * @param registerPasswordParam : 用户名密码注册参数
+     * @return : 返回注册结果
+     */
+    ResultVo<UserLoginVO> registerPassword(RegisterPasswordParam registerPasswordParam, HttpServletRequest request);
+
+    /**
+     * 手机注册
+     *
+     * @param registerMobileParam : 手机注册参数
+     * @param request             : HttpServletRequest
+     * @return : 返回注册结果
+     */
+    ResultVo<UserLoginVO> registerMobile(RegisterMobileParam registerMobileParam, HttpServletRequest request);
+
     /**
      * 用户名密码登录
      *
@@ -35,6 +51,14 @@ public interface IUserService extends IService<User> {
      */
     ResultVo<UserLoginVO> loginMobile(LoginMobileParam loginMobileParam, HttpServletRequest request);
 
+    /**
+     * 用户重置密码
+     *
+     * @param updatePasswordParam : 修改密码的参数
+     * @return : 返回修改结果
+     */
+    ResultVo updatePassword(UpdatePasswordParam updatePasswordParam);
+
     /**
      * 检查用户手机号是否存在
      *

+ 20 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/IWordCheckService.java

@@ -0,0 +1,20 @@
+package com.zanxiang.sdk.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.sdk.domain.entity.WordCheck;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description :
+ */
+public interface IWordCheckService extends IService<WordCheck> {
+
+    /**
+     * 查询敏感词
+     *
+     * @param word : 需要匹配的词汇
+     * @return : 返回是否存在
+     */
+    boolean hasWord(String word);
+}

+ 202 - 8
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/UserServiceImpl.java

@@ -2,6 +2,7 @@ package com.zanxiang.sdk.service.Impl;
 
 import com.alibaba.nacos.common.utils.MD5Utils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.common.domain.ResultVo;
 import com.zanxiang.common.enums.HttpStatusEnum;
@@ -13,20 +14,19 @@ import com.zanxiang.sdk.domain.dto.UserDTO;
 import com.zanxiang.sdk.domain.entity.User;
 import com.zanxiang.sdk.domain.enums.AccountStatusEnum;
 import com.zanxiang.sdk.domain.enums.CmfSaltEnum;
-import com.zanxiang.sdk.domain.params.LoginMobileParam;
-import com.zanxiang.sdk.domain.params.LoginPasswordParam;
+import com.zanxiang.sdk.domain.params.*;
 import com.zanxiang.sdk.domain.vo.UserLoginVO;
 import com.zanxiang.sdk.mapper.UserMapper;
-import com.zanxiang.sdk.service.ISmsService;
-import com.zanxiang.sdk.service.IUserLoginLogService;
-import com.zanxiang.sdk.service.IUserService;
-import com.zanxiang.sdk.service.IUserTokenService;
+import com.zanxiang.sdk.service.*;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletRequest;
 import java.security.NoSuchAlgorithmException;
+import java.time.LocalDateTime;
 import java.util.Objects;
 
 /**
@@ -47,11 +47,167 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
     @Autowired
     private IUserLoginLogService userLoginLogService;
 
+    @Autowired
+    private IWordCheckService wordCheckService;
+
+    /**
+     * 普通注册
+     *
+     * @param registerPasswordParam : 用户名密码注册参数
+     * @return : 返回注册结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ResultVo<UserLoginVO> registerPassword(RegisterPasswordParam registerPasswordParam, HttpServletRequest request) {
+        String username = registerPasswordParam.getUsername();
+        String password = registerPasswordParam.getPassword();
+        //用户名密码校验
+        HttpStatusEnum checkRegisterEnum = this.checkRegister(username, password);
+        if (!Objects.equals(checkRegisterEnum, HttpStatusEnum.SUCCESS)) {
+            return new ResultVo<>(checkRegisterEnum);
+        }
+        //创建用户信息
+        User user = new User(registerPasswordParam, this.cmfPassword(password));
+        super.save(user);
+        //登录的ip
+        String realIp = IpUtils.getRealIp(request);
+        //插入用户登录记录
+        userLoginLogService.addUserLoginLog(realIp, user, registerPasswordParam.getGameId());
+        //获取token
+        String userToken = userTokenService.getUserToken(user.getId(), user.getDeviceType());
+        //返回用户token
+        return new ResultVo<>(new UserLoginVO(userToken));
+    }
+
+    /**
+     * 手机注册
+     *
+     * @param registerMobileParam : 手机注册参数
+     * @param request             : HttpServletRequest
+     * @return : 返回注册结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ResultVo<UserLoginVO> registerMobile(RegisterMobileParam registerMobileParam, HttpServletRequest request) {
+        Integer type = registerMobileParam.getType();
+        String mobile = registerMobileParam.getMobile();
+        String code = registerMobileParam.getCode();
+        String password = registerMobileParam.getPassword();
+        //校验手机验证码
+        HttpStatusEnum codeCheckEnum = smsService.smsCheck(type, mobile, code);
+        if (!Objects.equals(codeCheckEnum, HttpStatusEnum.SUCCESS)) {
+            return new ResultVo<>(codeCheckEnum);
+        }
+        //判断手机号是否已经注册
+        if (super.count(new LambdaQueryWrapper<User>().eq(User::getMobile, mobile)) > 0) {
+            return new ResultVo<>(HttpStatusEnum.PHONE_IS_REG);
+        }
+        //验证密码是否合规
+        HttpStatusEnum passwordCheckEnum = this.checkPassword(password);
+        if (!Objects.equals(passwordCheckEnum, HttpStatusEnum.SUCCESS)) {
+            return new ResultVo<>(passwordCheckEnum);
+        }
+        //创建用户信息
+        User user = new User(registerMobileParam, this.cmfPassword(password));
+        super.save(user);
+        //获取token
+        String userToken = userTokenService.getUserToken(user.getId(), user.getDeviceType());
+        //登录的ip
+        String realIp = IpUtils.getRealIp(request);
+        //插入用户登录记录
+        userLoginLogService.addUserLoginLog(realIp, user, registerMobileParam.getGameId());
+        //返回用户token
+        return new ResultVo<>(new UserLoginVO(userToken));
+    }
+
+    /**
+     * 登录用户名密码合规检测
+     *
+     * @param username : 用户名验证
+     * @param password : 密码验证
+     * @return : 返回验证结果
+     */
+    private HttpStatusEnum checkRegister(String username, String password) {
+        if (Strings.isBlank(username)) {
+            return HttpStatusEnum.USERNAME_EMPTY;
+        }
+        //用户名长度验证
+        if (username.length() < 4) {
+            return HttpStatusEnum.USERNAME_TOO_SHORT;
+        }
+        if (username.length() > 32) {
+            return HttpStatusEnum.USERNAME_TOO_LONG;
+        }
+        //合规验证
+        if (username.matches("/\\s/") || username.matches("/^ZN/i") || !username.matches("/^[a-zA-Z0-9]+$/i")) {
+            return HttpStatusEnum.USERNAME_BAD_CHAR;
+        }
+        //用户名不是手机号, 用户名只能是数字和字母
+        if (!StringUtils.checkPhone(username) && !username.matches("/^(?![^a-zA-Z]+$).{4,32}$/")) {
+            return HttpStatusEnum.USERNAME_BAD_CHAR;
+        }
+        //判断用户名是否存在敏感词
+        if (wordCheckService.hasWord(username)) {
+            return HttpStatusEnum.USERNAME_SENSITIVE;
+        }
+        //判断用户名是否已存在
+        if (super.count(new LambdaQueryWrapper<User>().eq(User::getUsername, username)) > 0) {
+            return HttpStatusEnum.USERNAME_EXISTS;
+        }
+        //密码验证
+        return this.checkPassword(password);
+    }
+
+    /**
+     * 密码合规检测
+     *
+     * @param password : 密码验证
+     * @return : 返回验证结果
+     */
+    private HttpStatusEnum checkPassword(String password) {
+        if (Strings.isBlank(password)) {
+            return HttpStatusEnum.PASSWORD_EMPTY;
+        }
+        if (password.length() < 6) {
+            return HttpStatusEnum.PASSWORD_TOO_SHORT;
+        }
+        if (password.length() > 32) {
+            return HttpStatusEnum.PASSWORD_TOO_LONG;
+        }
+        if (password.matches("/\\s/") || !password.matches("A([a-zA-Z0-9~`#$%^&*!@.,()\\\\{}|:;?<>]){6,32}$")) {
+            return HttpStatusEnum.PASSWORD_BAD_CHAR;
+        }
+        return HttpStatusEnum.SUCCESS;
+    }
+
+    /**
+     * 用户昵称合规检测
+     *
+     * @param nickname : 用户昵称
+     * @return : 检测结果
+     */
+    private HttpStatusEnum checkNickname(String nickname) {
+        if (Strings.isBlank(nickname)) {
+            return HttpStatusEnum.NICKNAME_EMPTY;
+        }
+        if (nickname.length() < 4) {
+            return HttpStatusEnum.NICKNAME_TOO_SHORT;
+        }
+        if (nickname.length() > 32) {
+            return HttpStatusEnum.NICKNAME_TOO_LONG;
+        }
+        //判断昵称是否存在敏感词
+        if (wordCheckService.hasWord(nickname)) {
+            return HttpStatusEnum.NICKNAME_SENSITIVE;
+        }
+        return HttpStatusEnum.SUCCESS;
+    }
+
     /**
      * 用户名密码登录
      *
      * @param userLoginParam : 登录参数
-     * @param request : HttpServletRequest
+     * @param request        : HttpServletRequest
      * @return : 返回登录token
      */
     @Override
@@ -95,7 +251,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
      * 手机号登录
      *
      * @param loginMobileParam : 手机号登录参数
-     * @param request : HttpServletRequest
+     * @param request          : HttpServletRequest
      * @return : 返回登录信息
      */
     @Override
@@ -129,6 +285,44 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
         return new ResultVo<>(new UserLoginVO(userToken));
     }
 
+    /**
+     * 用户重置密码
+     *
+     * @param updatePasswordParam : 修改密码的参数
+     * @return : 返回修改结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ResultVo updatePassword(UpdatePasswordParam updatePasswordParam) {
+        String mobile = updatePasswordParam.getMobile();
+        Integer type = updatePasswordParam.getType();
+        String code = updatePasswordParam.getCode();
+        String username = updatePasswordParam.getUsername();
+        String password = updatePasswordParam.getPassword();
+        //根据用户名查询用户信息
+        User user = super.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
+        if (user == null) {
+            return new ResultVo<>(HttpStatusEnum.USERNAME_NOT_EXISTS);
+        }
+        //短信验证码校验
+        HttpStatusEnum httpStatusEnum = smsService.smsCheck(type, mobile, code);
+        if (!Objects.equals(httpStatusEnum, HttpStatusEnum.SUCCESS)) {
+            return new ResultVo<>(httpStatusEnum);
+        }
+        //密码校验
+        HttpStatusEnum checkPasswordEnum = this.checkPassword(password);
+        if (!Objects.equals(checkPasswordEnum, HttpStatusEnum.SUCCESS)) {
+            return new ResultVo<>(checkPasswordEnum);
+        }
+        //修改用户密码
+        super.update(new LambdaUpdateWrapper<User>()
+                .set(User::getPassword, this.cmfPassword(password))
+                .set(User::getUpdateTime, LocalDateTime.now())
+                .eq(User::getId, user.getId()));
+        //返回修改成功
+        return new ResultVo(HttpStatusEnum.SUCCESS);
+    }
+
     /**
      * 密码cfm加密
      *

+ 34 - 0
game-module/game-sdk/src/main/java/com/zanxiang/sdk/service/Impl/WordCheckServiceImpl.java

@@ -0,0 +1,34 @@
+package com.zanxiang.sdk.service.Impl;
+
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.sdk.domain.entity.WordCheck;
+import com.zanxiang.sdk.mapper.WordCheckMapper;
+import com.zanxiang.sdk.service.IWordCheckService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-14
+ * @description : 敏感词
+ */
+@Slf4j
+@Service
+public class WordCheckServiceImpl extends ServiceImpl<WordCheckMapper, WordCheck> implements IWordCheckService {
+
+    /**
+     * 查询敏感词
+     *
+     * @param word : 需要匹配的词汇
+     * @return : 返回是否存在
+     */
+    @Override
+    public boolean hasWord(String word) {
+        List<WordCheck> wordCheckList = super.list(new LambdaQueryWrapper<WordCheck>().eq(WordCheck::getWord, word));
+        return CollectionUtils.isNotEmpty(wordCheckList);
+    }
+}

+ 4 - 0
game-module/game-sdk/src/main/resources/mapper/WordCheckMapper.xml

@@ -0,0 +1,4 @@
+<?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.zanxiang.sdk.mapper.WordCheckMapper">
+</mapper>