mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
添加重置密码功能
This commit is contained in:
@@ -15,4 +15,7 @@ public class Constants {
|
||||
public static String SYSCONFIG_ENABLE_CAPTCHA = "enable_captcha";
|
||||
public static String SYSCONFIG_SESSION_TIMEOUT = "session_timeout";
|
||||
public static String SYSCONFIG_ACCOUNT_MAX_ONLINE = "account_max_online";
|
||||
public static String SYSCONFIG_RESETPWD_ENABLE = "resetpwd_enable";
|
||||
public static String SYSCONFIG_RESETPWD_TIMEOUT = "resetpwd_timeout";
|
||||
public static String SYSCONFIG_RESETPWD_MAX_FAIL_COUNT = "resetpwd_max_fail_count";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package cn.lihongjie.coal.resetPwd.controller;
|
||||
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.resetPwd.dto.ConfirmResetPasswordDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.CreateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.ResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.UpdateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.service.ResetPwdService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
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;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/resetPwd")
|
||||
@SysLog(module = "重置密码")
|
||||
@Slf4j
|
||||
public class ResetPwdController {
|
||||
@Autowired private ResetPwdService service;
|
||||
|
||||
@PostMapping("/create")
|
||||
public ResetPwdDto create(@RequestBody CreateResetPwdDto request) {
|
||||
return this.service.create(request);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public ResetPwdDto update(@RequestBody UpdateResetPwdDto request) {
|
||||
return this.service.update(request);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Object delete(@RequestBody IdRequest request) {
|
||||
this.service.delete(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
@PostMapping("/getById")
|
||||
public ResetPwdDto getById(@RequestBody IdRequest request) {
|
||||
return this.service.getById(request.getId());
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
public Page<ResetPwdDto> list(@RequestBody CommonQuery request) {
|
||||
return this.service.list(request);
|
||||
}
|
||||
|
||||
@PostMapping("/startReset")
|
||||
public String startReset(@RequestBody CreateResetPwdDto request) {
|
||||
return this.service.startReset(request);
|
||||
}
|
||||
|
||||
@PostMapping("/confirmReset")
|
||||
public Object confirmReset(@RequestBody ConfirmResetPasswordDto request) {
|
||||
this.service.confirmReset(request);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.lihongjie.coal.resetPwd.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class ConfirmResetPasswordDto extends CreateResetPwdDto{
|
||||
|
||||
private String id;
|
||||
|
||||
private String code;
|
||||
|
||||
private String password;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.lihongjie.coal.resetPwd.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
|
||||
@Data
|
||||
public class CreateResetPwdDto extends OrgCommonDto {
|
||||
private String userName;
|
||||
|
||||
|
||||
@Comment("手机号")
|
||||
private String phone;
|
||||
|
||||
|
||||
@Comment("邮箱")
|
||||
private String email;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.lihongjie.coal.resetPwd.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
import cn.lihongjie.coal.user.dto.UserDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class ResetPwdDto extends OrgCommonDto {
|
||||
private UserDto user;
|
||||
|
||||
|
||||
@Comment("手机号")
|
||||
private String phone;
|
||||
|
||||
|
||||
@Comment("邮箱")
|
||||
private String email;
|
||||
|
||||
|
||||
@Comment("验证码")
|
||||
private String code;
|
||||
|
||||
@Comment("最大失败次数, 超过之后需要重新获取验证码")
|
||||
private Integer maxFailCount;
|
||||
|
||||
|
||||
@Comment("失败次数")
|
||||
private Integer failCount;
|
||||
|
||||
|
||||
@Comment("过期时间")
|
||||
private LocalDateTime expireTime;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package cn.lihongjie.coal.resetPwd.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UpdateResetPwdDto extends OrgCommonDto {
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.lihongjie.coal.resetPwd.entity;
|
||||
|
||||
import cn.lihongjie.coal.base.entity.OrgCommonEntity;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class ResetPwdEntity extends OrgCommonEntity {
|
||||
|
||||
|
||||
@ManyToOne
|
||||
private UserEntity user;
|
||||
|
||||
|
||||
@Comment("手机号")
|
||||
private String phone;
|
||||
|
||||
|
||||
@Comment("邮箱")
|
||||
private String email;
|
||||
|
||||
|
||||
@Comment("验证码")
|
||||
private String code;
|
||||
|
||||
@Comment("最大失败次数, 超过之后需要重新获取验证码")
|
||||
private Integer maxFailCount;
|
||||
|
||||
|
||||
@Comment("失败次数")
|
||||
private Integer failCount;
|
||||
|
||||
|
||||
@Comment("过期时间")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.lihongjie.coal.resetPwd.mapper;
|
||||
|
||||
import cn.lihongjie.coal.base.mapper.BaseMapper;
|
||||
import cn.lihongjie.coal.base.mapper.CommonMapper;
|
||||
import cn.lihongjie.coal.resetPwd.dto.CreateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.ResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.UpdateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.entity.ResetPwdEntity;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.control.DeepClone;
|
||||
|
||||
@Mapper(
|
||||
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
|
||||
uses = {CommonMapper.class},
|
||||
mappingControl = DeepClone.class
|
||||
)
|
||||
public interface ResetPwdMapper extends BaseMapper<ResetPwdEntity, ResetPwdDto, CreateResetPwdDto, UpdateResetPwdDto> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package cn.lihongjie.coal.resetPwd.repository;
|
||||
|
||||
import cn.lihongjie.coal.base.dao.BaseRepository;
|
||||
import cn.lihongjie.coal.resetPwd.entity.ResetPwdEntity;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ResetPwdRepository extends BaseRepository<ResetPwdEntity> {
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package cn.lihongjie.coal.resetPwd.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.Constants;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.resetPwd.dto.ConfirmResetPasswordDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.CreateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.ResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.dto.UpdateResetPwdDto;
|
||||
import cn.lihongjie.coal.resetPwd.entity.ResetPwdEntity;
|
||||
import cn.lihongjie.coal.resetPwd.mapper.ResetPwdMapper;
|
||||
import cn.lihongjie.coal.resetPwd.repository.ResetPwdRepository;
|
||||
import cn.lihongjie.coal.sysconfig.service.SysConfigService;
|
||||
import cn.lihongjie.coal.user.entity.UserEntity;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class ResetPwdService extends BaseService<ResetPwdEntity, ResetPwdRepository> {
|
||||
@Autowired UserService userService;
|
||||
@Autowired SysConfigService sysConfigService;
|
||||
@Autowired private ResetPwdRepository repository;
|
||||
@Autowired private ResetPwdMapper mapper;
|
||||
@Autowired private ConversionService conversionService;
|
||||
|
||||
public ResetPwdDto create(CreateResetPwdDto request) {
|
||||
ResetPwdEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public ResetPwdDto update(UpdateResetPwdDto request) {
|
||||
ResetPwdEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
this.repository.deleteAllById(request.getIds());
|
||||
}
|
||||
|
||||
public ResetPwdDto getById(String id) {
|
||||
ResetPwdEntity entity = repository.get(id);
|
||||
|
||||
return mapper.toDto(entity);
|
||||
}
|
||||
|
||||
public Page<ResetPwdDto> list(CommonQuery query) {
|
||||
Page<ResetPwdEntity> page =
|
||||
repository.findAll(
|
||||
query.specification(conversionService),
|
||||
PageRequest.of(
|
||||
query.getPageNo(),
|
||||
query.getPageSize(),
|
||||
Sort.by(query.getOrders())));
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
|
||||
public String startReset(CreateResetPwdDto dto) {
|
||||
|
||||
|
||||
|
||||
if (StringUtils.isEmpty(dto.getUserName())){
|
||||
throw new RuntimeException("用户名不能为空");
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(dto.getEmail()) && StringUtils.isEmpty(dto.getPhone())){
|
||||
throw new RuntimeException("邮箱和手机号不能同时为空");
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(dto.getEmail()) && !StringUtils.isEmpty(dto.getPhone())){
|
||||
throw new RuntimeException("邮箱和手机号不能同时填写");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Optional<UserEntity> user = userService.findByUsername(dto.getUserName());
|
||||
|
||||
if (!user.isPresent()){
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(dto.getEmail()) && !dto.getEmail().equals(user.get().getEmail())){
|
||||
throw new RuntimeException("邮箱不正确");
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(dto.getPhone()) && !dto.getPhone().equals(user.get().getPhone())){
|
||||
throw new RuntimeException("手机号不正确");
|
||||
}
|
||||
|
||||
ResetPwdEntity resetPwdEntity = new ResetPwdEntity();
|
||||
resetPwdEntity.setUser(user.get());
|
||||
resetPwdEntity.setPhone(dto.getPhone());
|
||||
resetPwdEntity.setEmail(dto.getEmail());
|
||||
resetPwdEntity.setCode(ThreadLocalRandom.current().nextInt(100000, 999999) + "");
|
||||
resetPwdEntity.setFailCount(0);
|
||||
resetPwdEntity.setMaxFailCount(
|
||||
Integer.parseInt(
|
||||
sysConfigService.getConfigVal(
|
||||
Constants.SYSCONFIG_RESETPWD_MAX_FAIL_COUNT)));
|
||||
resetPwdEntity.setExpireTime(
|
||||
LocalDateTime.now()
|
||||
.plusSeconds(
|
||||
Integer.parseInt(
|
||||
sysConfigService.getConfigVal(
|
||||
Constants.SYSCONFIG_RESETPWD_TIMEOUT))));
|
||||
|
||||
this.save(resetPwdEntity);
|
||||
log.info("重置密码会话创建成功: {}", resetPwdEntity);
|
||||
|
||||
return resetPwdEntity.getId();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void confirmReset(ConfirmResetPasswordDto dto) {
|
||||
|
||||
ResetPwdEntity resetPwdEntity = this.repository.get(dto.getId());
|
||||
|
||||
if (resetPwdEntity == null){
|
||||
throw new BizException("当前重置密码会话不存在, 请重新开始重置密码");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (resetPwdEntity.getFailCount() >= resetPwdEntity.getMaxFailCount()){
|
||||
throw new BizException("当前重置密码会话失败次数过多, 请重新开始重置密码");
|
||||
}
|
||||
|
||||
if (resetPwdEntity.getExpireTime().isBefore(LocalDateTime.now())){
|
||||
throw new BizException("当前重置密码会话已过期, 请重新开始重置密码");
|
||||
}
|
||||
|
||||
if (!resetPwdEntity.getCode().equals(dto.getCode())){
|
||||
resetPwdEntity.setFailCount(resetPwdEntity.getFailCount() + 1);
|
||||
this.repository.save(resetPwdEntity);
|
||||
throw new BizException("验证码不正确");
|
||||
}
|
||||
|
||||
userService.resetPwd(resetPwdEntity.getUser().getId(), dto.getPassword());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,45 @@ class SysConfigService extends BaseService<SysConfigEntity, SysConfigRepository>
|
||||
entity.setType("2");
|
||||
repository.save(entity);
|
||||
}
|
||||
|
||||
if (!all.containsKey(Constants.SYSCONFIG_RESETPWD_ENABLE)) {
|
||||
SysConfigEntity entity = new SysConfigEntity();
|
||||
entity.setName("重置密码状态");
|
||||
entity.setCode(Constants.SYSCONFIG_RESETPWD_ENABLE);
|
||||
entity.setConfigVal("1");
|
||||
entity.setDictCode("status.type");
|
||||
entity.setMaxValue(null);
|
||||
entity.setMinValue(null);
|
||||
entity.setRegexValidator(null);
|
||||
entity.setType("3");
|
||||
repository.save(entity);
|
||||
}
|
||||
|
||||
if (!all.containsKey(Constants.SYSCONFIG_RESETPWD_TIMEOUT)) {
|
||||
SysConfigEntity entity = new SysConfigEntity();
|
||||
entity.setName("重置密码会话超时时间(s)");
|
||||
entity.setCode(Constants.SYSCONFIG_RESETPWD_TIMEOUT);
|
||||
entity.setConfigVal(TimeUnit.MINUTES.toSeconds(10) + "");
|
||||
entity.setDictCode(null);
|
||||
entity.setMaxValue((int) TimeUnit.HOURS.toSeconds(24));
|
||||
entity.setMinValue((int) TimeUnit.MINUTES.toSeconds(1));
|
||||
entity.setRegexValidator(null);
|
||||
entity.setType("2");
|
||||
repository.save(entity);
|
||||
}
|
||||
|
||||
if (!all.containsKey(Constants.SYSCONFIG_RESETPWD_MAX_FAIL_COUNT)) {
|
||||
SysConfigEntity entity = new SysConfigEntity();
|
||||
entity.setName("重置密码最多失败次数");
|
||||
entity.setCode(Constants.SYSCONFIG_RESETPWD_MAX_FAIL_COUNT);
|
||||
entity.setConfigVal(3+"");
|
||||
entity.setDictCode(null);
|
||||
entity.setMaxValue(Integer.MAX_VALUE);
|
||||
entity.setMinValue(1);
|
||||
entity.setRegexValidator(null);
|
||||
entity.setType("2");
|
||||
repository.save(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -176,6 +176,19 @@ class UserService extends BaseService<UserEntity, UserRepository> {
|
||||
return getById(request.getId());
|
||||
}
|
||||
|
||||
public void resetPwd(String userId, String password) {
|
||||
|
||||
UserEntity user =
|
||||
repository.findById(userId).orElseThrow(() -> new BizException("用户不存在"));
|
||||
|
||||
|
||||
|
||||
user.setPassword(passwordEncoder.encode(password));
|
||||
|
||||
repository.save(user);
|
||||
|
||||
}
|
||||
|
||||
public Page<UserDto> list(CommonQuery query) {
|
||||
|
||||
Page<UserEntity> page =
|
||||
|
||||
Reference in New Issue
Block a user