diff --git a/xdclass-common/src/main/java/net/jieyuu/constant/CacheKey.java b/xdclass-common/src/main/java/net/jieyuu/constant/CacheKey.java new file mode 100644 index 0000000..697ba96 --- /dev/null +++ b/xdclass-common/src/main/java/net/jieyuu/constant/CacheKey.java @@ -0,0 +1,8 @@ +package net.jieyuu.constant; + +public class CacheKey { + /** + * 注册验证码,第一个是类型,第二个是接收号码 + */ + public final static String CHECK_CODE_KEY="code:%s:%s"; +} diff --git a/xdclass-common/src/main/java/net/jieyuu/enums/SendCodeEnum.java b/xdclass-common/src/main/java/net/jieyuu/enums/SendCodeEnum.java index ec731b3..e3a633d 100644 --- a/xdclass-common/src/main/java/net/jieyuu/enums/SendCodeEnum.java +++ b/xdclass-common/src/main/java/net/jieyuu/enums/SendCodeEnum.java @@ -1,5 +1,10 @@ package net.jieyuu.enums; + public enum SendCodeEnum { + + /** + * 用户注册 + */ USER_REGISTER; } diff --git a/xdclass-common/src/main/java/net/jieyuu/utils/CommonUtil.java b/xdclass-common/src/main/java/net/jieyuu/utils/CommonUtil.java index 5740321..ab1e618 100644 --- a/xdclass-common/src/main/java/net/jieyuu/utils/CommonUtil.java +++ b/xdclass-common/src/main/java/net/jieyuu/utils/CommonUtil.java @@ -105,4 +105,12 @@ public class CommonUtil { //截取前32位 .substring(0, 32); } + + /** + * 获取当前时间戳 + * @return + */ + public static long getCurrentTimestamp(){ + return System.currentTimeMillis(); + } } diff --git a/xdclass-user-service/src/main/java/net/jieyuu/component/MinioUtils.java b/xdclass-user-service/src/main/java/net/jieyuu/component/MinioUtils.java index 3ccf610..464ec08 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/component/MinioUtils.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/component/MinioUtils.java @@ -4,7 +4,6 @@ package net.jieyuu.component; import io.minio.*; import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; -import lombok.Data; import net.jieyuu.utils.CommonUtil; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +22,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; + import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; diff --git a/xdclass-user-service/src/main/java/net/jieyuu/controller/UserController.java b/xdclass-user-service/src/main/java/net/jieyuu/controller/UserController.java index ad04a5f..e2b5833 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/controller/UserController.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/controller/UserController.java @@ -5,8 +5,11 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import net.jieyuu.enums.BizCodeEnum; +import net.jieyuu.request.UserRegisterRequest; import net.jieyuu.service.AddressService; import net.jieyuu.service.FileService; +import net.jieyuu.service.NotifyService; +import net.jieyuu.service.UserService; import net.jieyuu.utils.JsonData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -30,6 +33,10 @@ public class UserController { AddressService addressService; @Autowired FileService fileService; + @Autowired + UserService userService; + @Autowired + private NotifyService notifyService; @ApiOperation("根据id查询地址详情") @GetMapping("detail/{address_id}") @@ -52,9 +59,24 @@ public class UserController { @RequestPart("file") MultipartFile file) throws IOException { String result = fileService.uploadUserHeadImg(file); - return result!=null?JsonData.buildSuccess(result):JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL); + return result != null ? JsonData.buildSuccess(result) : JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL); } + /** + * 用户注册 + * + * @param registerRequest + * @return + */ + @ApiOperation("用户注册") + @PostMapping(value = "register") + public JsonData register( + @ApiParam(value = "用户注册对象", required = true) + @RequestBody UserRegisterRequest registerRequest) { + userService.register(registerRequest); + + return JsonData.buildSuccess(); + } } diff --git a/xdclass-user-service/src/main/java/net/jieyuu/request/UserRegisterRequest.java b/xdclass-user-service/src/main/java/net/jieyuu/request/UserRegisterRequest.java new file mode 100644 index 0000000..6d008e4 --- /dev/null +++ b/xdclass-user-service/src/main/java/net/jieyuu/request/UserRegisterRequest.java @@ -0,0 +1,32 @@ +package net.jieyuu.request; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "用户注册实体类") +public class UserRegisterRequest { + + @ApiModelProperty(value = "用户名", example = "123456") + private String name; + + @ApiModelProperty(value = "密码", example = "123456") + private String pwd; + + @ApiModelProperty(value = "头像地址", example = "123456") + private String headImg; + + @ApiModelProperty(value = "用户签名", example = "123456") + private String slogan; + + @ApiModelProperty(value = "性别", example = "1") + private Integer sex; + + @ApiModelProperty(value = "邮箱", example = "645634619@qq.com") + private String mail; + + @ApiModelProperty(value = "验证码", example = "645634619@qq.com") + private String code; + +} diff --git a/xdclass-user-service/src/main/java/net/jieyuu/service/NotifyService.java b/xdclass-user-service/src/main/java/net/jieyuu/service/NotifyService.java index 84d7b3d..32d930a 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/service/NotifyService.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/service/NotifyService.java @@ -5,5 +5,20 @@ import net.jieyuu.utils.JsonData; public interface NotifyService { + /** + * 发送验证码 + * @param sendCodeType + * @param to + * @return + */ public JsonData sendCode(SendCodeEnum sendCodeType, String to); + + /** + * 确认验证码是否合法 + * @param sendCodeEnum + * @param to + * @param code + * @return + */ + public boolean checkCode(SendCodeEnum sendCodeEnum,String to,String code); } diff --git a/xdclass-user-service/src/main/java/net/jieyuu/service/UserService.java b/xdclass-user-service/src/main/java/net/jieyuu/service/UserService.java index 478af4d..a8c3d92 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/service/UserService.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/service/UserService.java @@ -2,6 +2,8 @@ package net.jieyuu.service; import net.jieyuu.model.UserDO; import com.baomidou.mybatisplus.extension.service.IService; +import net.jieyuu.request.UserRegisterRequest; +import net.jieyuu.utils.JsonData; /** *

@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface UserService extends IService { + JsonData register(UserRegisterRequest userRegisterRequest); } diff --git a/xdclass-user-service/src/main/java/net/jieyuu/service/impl/NotifyServiceImpl.java b/xdclass-user-service/src/main/java/net/jieyuu/service/impl/NotifyServiceImpl.java index 5119e9e..55d51e5 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/service/impl/NotifyServiceImpl.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/service/impl/NotifyServiceImpl.java @@ -1,16 +1,22 @@ package net.jieyuu.service.impl; + import lombok.extern.slf4j.Slf4j; import net.jieyuu.component.MailService; +import net.jieyuu.constant.CacheKey; +import net.jieyuu.enums.BizCodeEnum; import net.jieyuu.enums.SendCodeEnum; import net.jieyuu.service.NotifyService; import net.jieyuu.utils.CheckUtil; import net.jieyuu.utils.CommonUtil; import net.jieyuu.utils.JsonData; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import java.util.concurrent.TimeUnit; + @Slf4j @Service public class NotifyServiceImpl implements NotifyService { @@ -21,14 +27,27 @@ public class NotifyServiceImpl implements NotifyService { @Autowired private RedisTemplate redisTemplate; - public static final String SUBJECT = "验证码"; - public static final String CONTENT = "您的验证码是%s,有效时间为60秒"; + /** + * 验证码标题 + */ + private static final String SUBJECT = "验证码"; + + /** + * 验证码格式 + * todo 对60s的思考 + */ + private static final String CONTENT = "您的验证码是%s,有效时间为60秒"; + + /** + * 十分钟有效 + */ + private static final int CODE_EXPIRED = 60 * 1000 * 10; /** * 前置判断:判断是否重复发送 * 1 存储验证码到缓存 - * + *

* 2 发送验证码 * 后置 存储发送记录 * @@ -38,17 +57,64 @@ public class NotifyServiceImpl implements NotifyService { */ @Override public JsonData sendCode(SendCodeEnum sendCodeType, String to) { + + String cacheKey = String.format(CacheKey.CHECK_CODE_KEY, SendCodeEnum.USER_REGISTER.name(), to); + String cacheValue = (String) redisTemplate.opsForValue().get(cacheKey); + + //判断是否为空 + //然后判断60秒内是否重复 + if (StringUtils.isNotBlank(cacheValue)) { + long ttl = Long.parseLong(cacheValue.split("_")[1]); + // 判断 当前时间戳-获取时间戳 是否大于60s + if (CommonUtil.getCurrentTimestamp() - ttl < 1000 * 60) { + log.info("重复发送验证码,时间间隔:{} 秒", (CommonUtil.getCurrentTimestamp() - ttl) / 1000); + return JsonData.buildResult(BizCodeEnum.CODE_LIMITED); + } + } + + //拼接验证码 2322_时间戳 + long currentTimestamp = CommonUtil.getCurrentTimestamp(); + //生成验证码 + String code = CommonUtil.getRandomCode(6); + String value = code + "_" + currentTimestamp; + redisTemplate.opsForValue().set(cacheKey, value, CODE_EXPIRED, TimeUnit.MILLISECONDS); if (CheckUtil.isEmail(to)) { //邮箱验证码 - String code = CommonUtil.getRandomCode(6); mailService.sendMail(to, SUBJECT, String.format(CONTENT, code)); return JsonData.buildSuccess(); - } else if (CheckUtil.isPhone(to)) { //短信验证码 } - return null; + return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR); + } + + /** + * 检验验证码 + * + * @param sendCodeEnum + * @param to + * @param code + * @return + */ + @Override + public boolean checkCode(SendCodeEnum sendCodeEnum, String to, String code) { + //读取缓存 + String cacheKey = String.format(CacheKey.CHECK_CODE_KEY, sendCodeEnum.name(), to); + String cacheValue = (String) redisTemplate.opsForValue().get(cacheKey); + + if (StringUtils.isNotBlank(cacheValue)) { + //截取 + String cacheCode = cacheValue.split("_")[0]; + //判断 + if (cacheCode.equals(code)) { + //删除验证码 + redisTemplate.delete(cacheKey); + return true; + } + + } + return false; } } diff --git a/xdclass-user-service/src/main/java/net/jieyuu/service/impl/UserServiceImpl.java b/xdclass-user-service/src/main/java/net/jieyuu/service/impl/UserServiceImpl.java index 958a0e6..5ab6e01 100644 --- a/xdclass-user-service/src/main/java/net/jieyuu/service/impl/UserServiceImpl.java +++ b/xdclass-user-service/src/main/java/net/jieyuu/service/impl/UserServiceImpl.java @@ -1,20 +1,105 @@ package net.jieyuu.service.impl; +import lombok.extern.slf4j.Slf4j; +import net.jieyuu.enums.BizCodeEnum; +import net.jieyuu.enums.SendCodeEnum; import net.jieyuu.model.UserDO; import net.jieyuu.mapper.UserMapper; +import net.jieyuu.request.UserRegisterRequest; +import net.jieyuu.service.NotifyService; import net.jieyuu.service.UserService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.jieyuu.utils.JsonData; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Date; + /** *

- * 服务实现类 + * 服务实现类 *

* * @author jieyuu * @since 2024-02-12 */ @Service +@Slf4j public class UserServiceImpl extends ServiceImpl implements UserService { + @Autowired + NotifyService notifyService; + + @Autowired + UserMapper userMapper; + + /** + * 用户注册 + * 邮箱验证码验证 + * 密码加密 TODO + * 账号唯一性检查 TODO + * 插入数据库 + * 新注册用户福利发放 TODO + * + * @param userRegisterRequest + * @return + */ + @Override + public JsonData register(UserRegisterRequest userRegisterRequest) { + boolean checkCode = false; + //校验验证码 + if (StringUtils.isNotBlank(userRegisterRequest.getMail())) { + checkCode = notifyService.checkCode(SendCodeEnum.USER_REGISTER, userRegisterRequest.getMail(), userRegisterRequest.getCode()); + } + + if (!checkCode) { + //验证码错误 + return JsonData.buildResult(BizCodeEnum.CODE_CAPTCHA); + } + + UserDO userDO = new UserDO(); + BeanUtils.copyProperties(userRegisterRequest, userDO); + + //设置创建时间 + userDO.setCreateTime(new Date()); + //todo 思考老师的设置是否有问题 +// userDO.setSlogan(""); + //todo 设置密码 加密 +// userDO.setPwd(userRegisterRequest.getPwd()); + + //账号唯一性检查 todo + if (checkUnique(userDO.getMail())) { + //插入数据库 + int rows = userMapper.insert(userDO); + log.info("rows:{},注册成功{}", rows, userDO.toString()); + + //新用户创建成功,初始化,发福利 todo + userRegisterInitTask(userDO); + return JsonData.buildSuccess(); + + } else { + return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT); + } + } + + + /** + * 校验用户账号唯一 + * @param mail + * @return + */ + private boolean checkUnique(String mail) { + return false; + + } + + /** + * 用户注册,初始化福利信息 todo + * @param userDO + */ + private void userRegisterInitTask(UserDO userDO) { + + } }