UserServiceImpl.java 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package com.njuzr.eaibackend.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  5. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6. import com.njuzr.eaibackend.dto.user.PasswordChangeDTO;
  7. import com.njuzr.eaibackend.dto.user.UserDTO;
  8. import com.njuzr.eaibackend.dto.user.UserRegisterDTO;
  9. import com.njuzr.eaibackend.dto.user.UserUpdateDTO;
  10. import com.njuzr.eaibackend.enums.Role;
  11. import com.njuzr.eaibackend.exception.MyException;
  12. import com.njuzr.eaibackend.mapper.UserMapper;
  13. import com.njuzr.eaibackend.po.User;
  14. import com.njuzr.eaibackend.service.UserService;
  15. import com.njuzr.eaibackend.utils.ModelMapperUtil;
  16. import com.njuzr.eaibackend.utils.PageMapperUtil;
  17. import com.njuzr.eaibackend.vo.UserVO;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.data.redis.core.RedisTemplate;
  21. import org.springframework.http.HttpStatus;
  22. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  23. import org.springframework.security.crypto.password.PasswordEncoder;
  24. import org.springframework.stereotype.Service;
  25. import java.util.*;
  26. import java.util.stream.Collectors;
  27. @Slf4j
  28. @Service
  29. public class UserServiceImpl implements UserService {
  30. @Autowired
  31. private UserMapper userMapper;
  32. @Autowired
  33. private RedisTemplate<String, Object> redisTemplate;
  34. private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
  35. @Override
  36. public IPage<UserVO> searchUsers(Page<User> page, Long id, String name, String officialNumber, Role role) {
  37. QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // 设置查询条件
  38. // 禁止访问查询ADMIN用户
  39. if (role == Role.ADMIN) {
  40. throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase() + ":" + "被拒绝");
  41. }
  42. queryWrapper
  43. .eq(Objects.nonNull(id), "id", id)
  44. .like(StringUtils.isNotBlank(name), "name", name)
  45. .eq(StringUtils.isNotBlank(officialNumber), "official_number", officialNumber)
  46. .eq(Objects.nonNull(role), "role", role);
  47. IPage<User> targets = userMapper.selectPage(page, queryWrapper); // selectPage是内置的方法
  48. // targets.total如果为0,则说明没有符合条件的用户,但是不报错,由前端自行处理异常。
  49. return PageMapperUtil.convert(targets, record -> ModelMapperUtil.map(record, UserVO.class));
  50. }
  51. @Override
  52. public UserVO createUser(UserRegisterDTO userDTO) {
  53. // 从Redis中获取验证码
  54. final String key = "registerVerifyCode:" + userDTO.getOfficialEmail();
  55. String storedCode = (String) redisTemplate.opsForValue().get(key);
  56. if (storedCode == null) {
  57. throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码已过期");
  58. }
  59. // 验证码校验
  60. if (storedCode.equals(userDTO.getVerifyCode())) {
  61. // 检查邮箱和学号是否已存在
  62. if (!isOfficialNumberNotExists(userDTO.getOfficialNumber())) {
  63. throw new MyException(HttpStatus.BAD_REQUEST.value(), "学号已注册");
  64. }
  65. if (!isEmailNotExists(userDTO.getOfficialEmail())) {
  66. throw new MyException(HttpStatus.BAD_REQUEST.value(), "邮箱已注册");
  67. }
  68. User targetUser = ModelMapperUtil.map(userDTO, User.class);
  69. targetUser.setPassword(new BCryptPasswordEncoder().encode(targetUser.getPassword())); // 密码加密存储
  70. targetUser.setCreateTime(new Date()); // 设置创建时间
  71. int state = userMapper.insert(targetUser);
  72. log.info("state: {}", state);
  73. log.info("User创建完毕,User对象如下:" + targetUser);
  74. redisTemplate.delete(key); //注册成功后删除验证码
  75. return ModelMapperUtil.map(targetUser, UserVO.class);
  76. }
  77. else {
  78. throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码错误");
  79. }
  80. }
  81. @Override
  82. public UserVO createUserByPortal(UserRegisterDTO userDTO) {
  83. User targetUser = ModelMapperUtil.map(userDTO, User.class);
  84. targetUser.setCreateTime(new Date()); // 设置创建时间
  85. int state = userMapper.insert(targetUser);
  86. log.info("state: {}", state);
  87. log.info("User创建完毕,User对象如下:" + targetUser);
  88. return ModelMapperUtil.map(targetUser, UserVO.class);
  89. }
  90. /**
  91. * 更新用户信息
  92. *
  93. * @param userDTO
  94. * @return
  95. */
  96. @Override
  97. public UserVO updateUser(Long id, UserUpdateDTO userDTO) {
  98. UserDTO opeUser = ModelMapperUtil.map(userDTO, UserDTO.class);
  99. User user = ModelMapperUtil.map(userDTO, User.class);
  100. user.setId(id);
  101. try {
  102. int status = userMapper.updateUser(user);
  103. if (status > 0) {
  104. return ModelMapperUtil.map(userMapper.selectById(user.getId()), UserVO.class);
  105. }
  106. } catch (Exception e) {
  107. log.error("数据库更新错误,错误如下:" + e.getMessage());
  108. throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() + ":" + "数据库更新失败");
  109. }
  110. return null;
  111. }
  112. @Override
  113. public UserVO updateUserByPid(Integer pid, UserUpdateDTO userDTO) {
  114. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  115. queryWrapper.eq("pid", pid);
  116. User user = userMapper.selectOne(queryWrapper);
  117. return this.updateUser(user.getId(), userDTO);
  118. }
  119. /**
  120. * 更新密码
  121. */
  122. @Override
  123. public void updatePassword(PasswordChangeDTO passwordChangeDTO) throws MyException {
  124. User user = userMapper.selectByOfficialEmail(passwordChangeDTO.getOfficialEmail());
  125. if (user == null) {
  126. log.error("用户不存在");
  127. throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "找不到用户");
  128. }
  129. // 从Redis中获取验证码
  130. final String key = "passwordChangeVerifyCode:" + passwordChangeDTO.getOfficialEmail();
  131. String storedCode = (String) redisTemplate.opsForValue().get(key);
  132. if (storedCode == null) {
  133. throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码已过期");
  134. }
  135. // 验证码校验
  136. if (storedCode.equals(passwordChangeDTO.getVerifyCode())) {
  137. String encodedNewPassword = passwordEncoder.encode(passwordChangeDTO.getPassword());
  138. int code = userMapper.updatePassword(user.getId(), encodedNewPassword);
  139. if (code == 1) {
  140. log.info("用户更新成功");
  141. }
  142. redisTemplate.delete(key); //成功后删除验证码
  143. } else {
  144. throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码错误");
  145. }
  146. }
  147. @Override
  148. public boolean userExists(Integer pid) {
  149. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  150. queryWrapper.eq("pid", pid);
  151. return userMapper.exists(queryWrapper);
  152. }
  153. /**
  154. * 查看学号是否不存在
  155. *
  156. * @param officialNumber 学号
  157. * @return true表示不存在,false表示存在
  158. */
  159. private boolean isOfficialNumberNotExists(String officialNumber) throws MyException {
  160. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  161. queryWrapper.eq("official_number", officialNumber);
  162. User existingUser = userMapper.selectOne(queryWrapper);
  163. if (existingUser != null) {
  164. log.error("用户已存在,学号{}重复", officialNumber);
  165. throw new MyException(400, "用户已存在,请检查学号信息");
  166. }
  167. return true;
  168. }
  169. /**
  170. * 查看邮箱是否不存在
  171. *
  172. * @param email 邮箱
  173. * @return true表示不存在,false表示存在
  174. */
  175. private boolean isEmailNotExists(String email) throws MyException {
  176. QueryWrapper<User> queryWrapper = new QueryWrapper<>();
  177. queryWrapper.eq("official_email", email);
  178. User existingUser = userMapper.selectOne(queryWrapper);
  179. if (existingUser != null) {
  180. log.error("用户已存在,邮箱{}重复", email);
  181. throw new MyException(400, "用户已存在,请检查邮箱信息");
  182. }
  183. return true;
  184. }
  185. @Override
  186. public String getNameById(Long id) {
  187. if (id == null) return null;
  188. try {
  189. return userMapper.selectNameById(id);
  190. } catch (Exception e) {
  191. return null;
  192. }
  193. }
  194. @Override
  195. public Map<Long, String> getNamesByIds(Collection<Long> ids) {
  196. if (ids == null || ids.isEmpty()) return Collections.emptyMap();
  197. QueryWrapper<User> wrapper = new QueryWrapper<>();
  198. wrapper.in("id", ids);
  199. List<User> users = userMapper.selectList(wrapper);
  200. if (users == null || users.isEmpty()) return Collections.emptyMap();
  201. return users.stream().collect(Collectors.toMap(User::getId, User::getName, (a,b)->a));
  202. }
  203. }