Commit 43759dff by Future

用户相关接口提供

parent bce7f015
File mode changed from 100755 to 100644
package com.wecloud.im.enums;
import io.geekidea.springbootplus.framework.common.enums.BaseEnum;
/**
* @Author wenzhida
* @Date 2022/2/21 18:25
* @Description 验证码验证场景枚举
*/
public enum VerifySceneEnum implements BaseEnum {
/**
* 1 - 用户注册
*/
REGISTER(1, "用户注册"),
/**
* 2 - 重置密码验证
*/
RESET_PWD(2, "重置密码验证"),
/**
* 3 - 更换手机号绑定
*/
CHANGE_PHONE(3, "更换手机号绑定");
VerifySceneEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
private final Integer code;
private final String desc;
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getDesc() {
return this.desc;
}
}
package com.wecloud.im.user.constant;
/**
* @Author wenzhida
* @Date 2022/2/21 22:10
* @Description redis前缀常量
*/
public class RedisKeyPrefixConstant {
/**
* 验证码前缀
*/
public static final String VERIFY_CODE_PREFIX = "verify_code_";
}
package com.wecloud.im.user.controller;
import com.wecloud.im.enums.VerifySceneEnum;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.param.ChangePhoneParam;
import com.wecloud.im.user.param.ResetPasswordParam;
import com.wecloud.im.user.param.UserLoginParam;
import com.wecloud.im.user.param.UserRegisterParam;
import com.wecloud.im.user.service.UserService;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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;
/**
* @Author wenzhida
* @Date 2022/2/21 17:05
* @Description 用户控制器
*/
@Slf4j
@RestController
@RequestMapping("/user")
@Api(value = "用户相关API", tags = {"用户"})
public class UserController extends BaseController {
@Autowired
private UserService userService;
@PostMapping("/register")
@ApiOperation(value = "用户注册接口")
public ApiResult<Boolean> register(@RequestBody @Validated UserRegisterParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.REGISTER.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.registerUser(param);
return ApiResult.ok();
}
@PostMapping("/login")
@ApiOperation(value = "用户登录接口")
public ApiResult<Boolean> login(@RequestBody @Validated UserLoginParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
userService.loginUser(param);
return ApiResult.ok();
}
@PostMapping("/resetPassword")
@ApiOperation(value = "重置密码接口")
public ApiResult<Boolean> resetPassword(@RequestBody @Validated ResetPasswordParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.RESET_PWD.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.resetPassword(param);
return ApiResult.ok();
}
@PostMapping("/changePhone")
@ApiOperation(value = "更换手机号接口")
public ApiResult<Boolean> changePhone(@RequestBody @Validated ChangePhoneParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.CHANGE_PHONE.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.changePhone(param);
return ApiResult.ok();
}
}
package com.wecloud.im.user.controller;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.param.SendVerifyCodeParam;
import com.wecloud.im.ws.utils.RedisUtils;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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.time.Duration;
/**
* @Author wenzhida
* @Date 2022/2/21 17:05
* @Description 验证码相关控制器
*/
@Slf4j
@RestController
@RequestMapping("/verify")
@Api(value = "验证码相关API", tags = {"验证码"})
public class VerifyCodeController extends BaseController {
@Autowired
private RedisUtils redisUtils;
/**
* 发送验证码接口
*/
@PostMapping("/sendVerificationCode")
@ApiOperation(value = "发送验证码接口")
public ApiResult<Boolean> generateVerificationCode(@RequestBody @Validated SendVerifyCodeParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
// String verificationCode = this.generateVerifyCode();
String verificationCode = "666666";
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(param.getVerifyScene()).append(param.getPhone()).toString();
redisUtils.addKey(key, verificationCode, Duration.ofSeconds(3 * 60));
// todo 接入短信验证码
return ApiResult.ok();
}
/**
* 生成短信验证码
* @return
*/
private String generateVerifyCode() {
Integer verifyCode;
verifyCode = (int) ((Math.random() * 9 + 1) * 100000);
return verifyCode.toString();
}
}
package com.wecloud.im.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/2/21 16:58
* @Description 用户信息
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "用户信息")
public class User extends BaseEntity {
private static final long serialVersionUID = -8075685205533406087L;
@NotNull(message = "主键id不能为空")
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.INPUT)
private Long id;
@ApiModelProperty("手机号码")
private String phone;
@ApiModelProperty("身份证号码")
private String idCardNo;
@ApiModelProperty("邮箱号码")
private String email;
@ApiModelProperty("密码")
private String password;
@ApiModelProperty("性别")
private Integer sex;
@ApiModelProperty("头像")
private String headPortrait;
@ApiModelProperty("昵称")
private String nickName;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("修改时间")
private Date updateTime;
}
package com.wecloud.im.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wecloud.im.user.entity.User;
import org.springframework.stereotype.Repository;
/**
* @Author wenzhida
* @Date 2022/2/21 17:03
* @Description 用户 Mapper
*/
@Repository
public interface UserMapper extends BaseMapper<User> {
}
package com.wecloud.im.user.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 23:10
* @Description 更换手机号入参
*/
@Data
public class ChangePhoneParam implements Serializable {
private static final long serialVersionUID = -4477687567118083363L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
private String verifyCode;
}
package com.wecloud.im.user.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 22:57
* @Description 重置密码接口
*/
@Data
public class ResetPasswordParam implements Serializable {
private static final long serialVersionUID = 387632352343954534L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
private String password;
}
package com.wecloud.im.user.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 生成验证码入参
*/
@Data
public class SendVerifyCodeParam implements Serializable {
private static final long serialVersionUID = 565144491185523650L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
private String phone;
/**
* 验证场景 1-用户注册 2-重置密码验证 3-更换手机号绑定
* @see com.wecloud.im.enums.VerifySceneEnum
*/
@NotNull(message = "验证场景不可为空")
private Integer verifyScene;
}
package com.wecloud.im.user.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 用户登录入参
*/
@Data
public class UserLoginParam implements Serializable {
private static final long serialVersionUID = 9182337935301787778L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
private String phone;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
private String password;
}
package com.wecloud.im.user.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/21 18:15
* @Description 用户注册入参
*/
@Data
public class UserRegisterParam implements Serializable {
private static final long serialVersionUID = 6026490500445982659L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
private String password;
}
package com.wecloud.im.user.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.protobuf.ServiceException;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.user.entity.User;
import com.wecloud.im.user.mapper.UserMapper;
import com.wecloud.im.user.param.ChangePhoneParam;
import com.wecloud.im.user.param.ResetPasswordParam;
import com.wecloud.im.user.param.UserLoginParam;
import com.wecloud.im.user.param.UserRegisterParam;
import com.wecloud.im.ws.utils.RedisUtils;
import com.wecloud.utils.AesUtil;
import com.wecloud.utils.SnowflakeUtil;
import io.geekidea.springbootplus.framework.common.exception.BusinessException;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @Author wenzhida
* @Date 2022/2/21 17:05
* @Description 用户服务接口
*/
@Service
public class UserService extends BaseServiceImpl<UserMapper, User> {
@Autowired
private RedisUtils redisUtils;
/**
* 注册用户
* @param param
*/
public void registerUser(UserRegisterParam param) {
User userExist = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (userExist != null) {
throw new BusinessException("已存在此电话号码用户");
}
User user = new User();
user.setId(SnowflakeUtil.getId());
user.setPhone(param.getPhone());
user.setPassword(AesUtil.encrypt(param.getPassword()));
user.setCreateTime(new Date());
this.save(user);
}
/**
* 用户登录
* @param param
*/
public void loginUser(UserLoginParam param) {
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (!param.getPassword().equals(AesUtil.decrypt(user.getPassword()))) {
throw new BusinessException("账户或密码错误");
}
}
/**
* 重置密码
* @param param
*/
public void resetPassword(ResetPasswordParam param) {
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (user == null) {
throw new BusinessException("查无此用户");
}
user.setPassword(AesUtil.encrypt(param.getPassword()));
this.updateById(user);
}
/**
* 更换手机号码
* @param param
*/
public void changePhone(ChangePhoneParam param) {
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (user == null) {
throw new BusinessException("查无此用户");
}
user.setPhone(param.getPhone());
this.updateById(user);
}
/**
* 校验短信验证码
* @param verifyCode
* @param redisKey
*/
public void verifySMSVerifyCode(String verifyCode, String redisKey) {
String verifyCodeInRedis = redisUtils.getKey(redisKey);
if (verifyCodeInRedis == null || !verifyCodeInRedis.equals(verifyCode)) {
throw new BusinessException("短信验证码不正确");
}
redisUtils.delKey(redisKey);
}
}
package com.wecloud.utils;
import io.geekidea.springbootplus.framework.common.exception.BusinessException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @Author wenzhida
* @Date 2022/2/21 22:26
* @Description 加解密工具类
*/
public class AesUtil {
public static final String ALGORITHM = "AES";
/**
* AES/CBC/NOPaddin
* AES 默认模式
* 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
* IvParameterSpec(key.getBytes());
* NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
*/
public static final String TRANSFORMATION = "AES/CBC/NOPadding";
public static final String key = "1234567812345678";
/***
* 加密
* @param original 需要加密的参数(注意必须是16位)
* @return
* @throws Exception
*/
public static String encrypt(String original) {
try {
// 获取Cipher
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// 生成密钥
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// 指定模式(加密)和密钥
// 创建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// 加密
byte[] bytes = cipher.doFinal(original.getBytes());
return Base64Util.encryptBASE64(bytes);
} catch (Exception e) {
throw new BusinessException("加密出现错误");
}
}
/**
* 解密
*
* @param encrypted 需要解密的参数
* @return
* @throws Exception
*/
public static String decrypt(String encrypted) {
try {
// 获取Cipher
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// 生成密钥
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// 指定模式(解密)和密钥
// 创建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.DECRYPT_MODE, keySpec);
// 解密
byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
return new String(bytes);
} catch (Exception e) {
throw new BusinessException("解密出现错误");
}
}
}
package com.wecloud.utils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* @Author wenzhida
* @Date 2022/2/21 22:37
* @Description BASE64加密/解密
*/
public class Base64Util {
/***
* BASE64解密
* @param key
* @return
* @throws Exception
*/
public static byte[] decryBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
/***
* BASE64加密
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encode(key);
}
}
-- 在feature-cluster 2021年12月22日之后,需要执行的的sql增量脚本 -- 在feature-cluster 2021年12月22日之后,需要执行的的sql增量脚本
...@@ -73,3 +73,25 @@ ALTER TABLE im_conversation ADD COLUMN muted tinyint NOT NULL DEFAULT '1' COMMEN ...@@ -73,3 +73,25 @@ ALTER TABLE im_conversation ADD COLUMN muted tinyint NOT NULL DEFAULT '1' COMMEN
ALTER TABLE im_conversation_members ADD COLUMN muted tinyint NOT NULL DEFAULT '1' COMMENT '禁言开关 1-未禁言 2-禁言'; ALTER TABLE im_conversation_members ADD COLUMN muted tinyint NOT NULL DEFAULT '1' COMMENT '禁言开关 1-未禁言 2-禁言';
CREATE TABLE `im_user`
(
`id` bigint NOT NULL COMMENT '主键id',
`phone` varchar(32) DEFAULT NULL COMMENT '手机号码',
`id_card_no` varchar(32) DEFAULT NULL COMMENT '身份证号码',
`email` varchar(32) DEFAULT NULL COMMENT '邮箱号码',
`password` varchar(32) DEFAULT NULL COMMENT '密码',
`sex` tinyint DEFAULT NULL COMMENT '性别 1-男 2-女',
`head_portrait` varchar(1000) DEFAULT NULL COMMENT '头像',
`nickname` varchar(30) DEFAULT NULL COMMENT '昵称',
`create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `phone` (`phone`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment