From b809fb9a6be293bc69c6b6dec0ab831f970011a2 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Thu, 6 Mar 2025 17:20:05 +0800 Subject: [PATCH] =?UTF-8?q?3.6=20=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86+?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=9D=91=E7=9A=84=E4=BF=AE=E5=A4=8D=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=E5=88=86=E9=A1=B5=E6=8F=92=E4=BB=B6=E3=80=81long?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 ++ .../aop/AuthInterceptor.java | 58 +++++++++ .../config/JacksonConfig.java | 69 +++++++++++ .../config/MybatisPlusConfig.java | 26 ++++ .../constant/UserConstant.java | 5 +- .../controller/UserController.java | 95 ++++++++++++++- .../model/dto/user/UserAddRequest.java | 39 ++++++ .../dto/{ => user}/UserLoginRequest.java | 2 +- .../model/dto/user/UserQueryRequest.java | 44 +++++++ .../dto/{ => user}/UserRegisterRequest.java | 2 +- .../model/dto/user/UserUpdateRequest.java | 39 ++++++ .../smilepicturebackend/model/vo/UserVO.java | 51 ++++++++ .../service/UserService.java | 13 ++ .../service/impl/UserServiceImpl.java | 113 ++++++++++++++++-- 14 files changed, 552 insertions(+), 16 deletions(-) create mode 100644 src/main/java/edu/whut/smilepicturebackend/aop/AuthInterceptor.java create mode 100644 src/main/java/edu/whut/smilepicturebackend/config/JacksonConfig.java create mode 100644 src/main/java/edu/whut/smilepicturebackend/config/MybatisPlusConfig.java create mode 100644 src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserAddRequest.java rename src/main/java/edu/whut/smilepicturebackend/model/dto/{ => user}/UserLoginRequest.java (86%) create mode 100644 src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserQueryRequest.java rename src/main/java/edu/whut/smilepicturebackend/model/dto/{ => user}/UserRegisterRequest.java (88%) create mode 100644 src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserUpdateRequest.java create mode 100644 src/main/java/edu/whut/smilepicturebackend/model/vo/UserVO.java diff --git a/pom.xml b/pom.xml index 6ab3ae9..e1ee83c 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,11 @@ org.springframework.security spring-security-crypto + + + com.baomidou + mybatis-plus-jsqlparser-4.9 + com.mysql mysql-connector-j @@ -64,6 +69,13 @@ + + com.baomidou + mybatis-plus-bom + 3.5.9 + pom + import + org.springframework.boot spring-boot-dependencies diff --git a/src/main/java/edu/whut/smilepicturebackend/aop/AuthInterceptor.java b/src/main/java/edu/whut/smilepicturebackend/aop/AuthInterceptor.java new file mode 100644 index 0000000..27010db --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/aop/AuthInterceptor.java @@ -0,0 +1,58 @@ +package edu.whut.smilepicturebackend.aop; + +import edu.whut.smilepicturebackend.annotation.AuthCheck; +import edu.whut.smilepicturebackend.exception.BusinessException; +import edu.whut.smilepicturebackend.exception.ErrorCode; +import edu.whut.smilepicturebackend.model.entity.User; +import edu.whut.smilepicturebackend.model.enums.UserRoleEnum; +import edu.whut.smilepicturebackend.service.UserService; +import lombok.RequiredArgsConstructor; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +@Aspect +@Component +@RequiredArgsConstructor +public class AuthInterceptor { + + private final UserService userService; + + /** + * 执行拦截 + * + * @param joinPoint 切入点 + * @param authCheck 权限校验注解 + */ + @Around("@annotation(authCheck)") + public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable { + String mustRole = authCheck.mustRole(); + RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); + HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); + // 获取当前登录用户 + User loginUser = userService.getLoginUser(request); + UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole); + // 如果不需要权限,放行 + if (mustRoleEnum == null) { + return joinPoint.proceed(); + } + // 以下的代码:必须有权限,才会通过 + UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole()); + if (userRoleEnum == null) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + // 要求必须有管理员权限,但用户没有管理员权限,拒绝 + if (UserRoleEnum.ADMIN.equals(mustRoleEnum) && !UserRoleEnum.ADMIN.equals(userRoleEnum)) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR); + } + // 通过权限校验,放行 + return joinPoint.proceed(); + } +} diff --git a/src/main/java/edu/whut/smilepicturebackend/config/JacksonConfig.java b/src/main/java/edu/whut/smilepicturebackend/config/JacksonConfig.java new file mode 100644 index 0000000..3f6be99 --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/config/JacksonConfig.java @@ -0,0 +1,69 @@ +package edu.whut.smilepicturebackend.config; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.*; +import com.fasterxml.jackson.datatype.jsr310.ser.*; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +@Configuration +public class JacksonConfig { + + private static final String DATE_FORMAT = "yyyy-MM-dd"; + private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private static final String TIME_FORMAT = "HH:mm:ss"; + + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() { + return builder -> { + // 1) 忽略未知属性 + builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + // 2) 全局日期格式(对于 Date 类型) + builder.simpleDateFormat(DATETIME_FORMAT); + + // 3) Java 8 Time 类型的序列化/反序列化 + JavaTimeModule javaTime = new JavaTimeModule(); + javaTime.addSerializer( + LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT)) + ); + javaTime.addSerializer( + LocalDate.class, + new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT)) + ); + javaTime.addSerializer( + LocalTime.class, + new LocalTimeSerializer(DateTimeFormatter.ofPattern(TIME_FORMAT)) + ); + javaTime.addDeserializer( + LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT)) + ); + javaTime.addDeserializer( + LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATE_FORMAT)) + ); + javaTime.addDeserializer( + LocalTime.class, + new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TIME_FORMAT)) + ); + builder.modules(javaTime); + + // 4) 将所有 long / Long 类型序列化成 String + SimpleModule longToString = new SimpleModule(); + longToString.addSerializer(Long.class, ToStringSerializer.instance); + longToString.addSerializer(Long.TYPE, ToStringSerializer.instance); + builder.modules(longToString); + }; + } +} diff --git a/src/main/java/edu/whut/smilepicturebackend/config/MybatisPlusConfig.java b/src/main/java/edu/whut/smilepicturebackend/config/MybatisPlusConfig.java new file mode 100644 index 0000000..9e46f2f --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/config/MybatisPlusConfig.java @@ -0,0 +1,26 @@ +package edu.whut.smilepicturebackend.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@MapperScan("edu.whut.smilepicturebackend.mapper") +public class MybatisPlusConfig { + + /** + * 拦截器配置 + * + * @return {@link MybatisPlusInterceptor} + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/constant/UserConstant.java b/src/main/java/edu/whut/smilepicturebackend/constant/UserConstant.java index 362cef7..717d7db 100644 --- a/src/main/java/edu/whut/smilepicturebackend/constant/UserConstant.java +++ b/src/main/java/edu/whut/smilepicturebackend/constant/UserConstant.java @@ -9,7 +9,10 @@ public interface UserConstant { * 用户登录态键 */ String USER_LOGIN_STATE = "user_login"; - + /** + * 创建用户默认密码 + */ + String USER_DEFAULT= "12345678"; // region 权限 /** diff --git a/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java b/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java index 2c87a94..7fb4b04 100644 --- a/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java +++ b/src/main/java/edu/whut/smilepicturebackend/controller/UserController.java @@ -1,18 +1,26 @@ package edu.whut.smilepicturebackend.controller; +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import edu.whut.smilepicturebackend.annotation.AuthCheck; import edu.whut.smilepicturebackend.common.BaseResponse; +import edu.whut.smilepicturebackend.common.DeleteRequest; import edu.whut.smilepicturebackend.common.ResultUtils; +import edu.whut.smilepicturebackend.constant.UserConstant; +import edu.whut.smilepicturebackend.exception.BusinessException; import edu.whut.smilepicturebackend.exception.ErrorCode; import edu.whut.smilepicturebackend.exception.ThrowUtils; -import edu.whut.smilepicturebackend.model.dto.UserLoginRequest; -import edu.whut.smilepicturebackend.model.dto.UserRegisterRequest; +import edu.whut.smilepicturebackend.model.dto.user.*; import edu.whut.smilepicturebackend.model.entity.User; import edu.whut.smilepicturebackend.model.vo.LoginUserVO; +import edu.whut.smilepicturebackend.model.vo.UserVO; import edu.whut.smilepicturebackend.service.UserService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import java.util.List; @RestController @@ -65,4 +73,87 @@ public class UserController { boolean result = userService.userLogout(request); return ResultUtils.success(result); } + + /** + * 创建用户 + */ + @PostMapping("/add") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse createUser(@RequestBody UserAddRequest userAddRequest) { + // 参数非空校验 + ThrowUtils.throwIf(userAddRequest == null, ErrorCode.PARAMS_ERROR); + // 调用 Service 完成业务逻辑 + long userId = userService.createUser(userAddRequest); + return ResultUtils.success(userId); + } + + /** + * 根据 id 获取用户(仅管理员) + */ + @GetMapping("/get") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse getUserById(long id) { + ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR); + User user = userService.getById(id); + ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR); + return ResultUtils.success(user); + } + + /** + * 根据 id 获取包装类(脱敏) + */ + @GetMapping("/get/vo") + public BaseResponse getUserVOById(long id) { + BaseResponse response = getUserById(id); + User user = response.getData(); + return ResultUtils.success(userService.getUserVO(user)); + } + + /** + * 删除用户 + */ + @PostMapping("/delete") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse deleteUser(@RequestBody DeleteRequest deleteRequest) { + if (deleteRequest == null || deleteRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + boolean b = userService.removeById(deleteRequest.getId()); + return ResultUtils.success(b); + } + + /** + * 更新用户 + */ + @PostMapping("/update") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse updateUser(@RequestBody UserUpdateRequest userUpdateRequest) { + if (userUpdateRequest == null || userUpdateRequest.getId() == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + User user = new User(); + BeanUtils.copyProperties(userUpdateRequest, user); + boolean result = userService.updateById(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return ResultUtils.success(true); + } + + /** + * 分页获取用户封装列表(仅管理员) + * + * @param userQueryRequest 查询请求参数 + */ + @PostMapping("/list/page/vo") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse> listUserVOByPage(@RequestBody UserQueryRequest userQueryRequest) { + ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAMS_ERROR); + long current = userQueryRequest.getCurrent(); //页号 + long pageSize = userQueryRequest.getPageSize(); + Page userPage = userService.page(new Page<>(current, pageSize), + userService.getQueryWrapper(userQueryRequest)); + Page userVOPage = new Page<>(current, pageSize, userPage.getTotal()); + List userVOList = userService.getUserVOList(userPage.getRecords()); + userVOPage.setRecords(userVOList); + return ResultUtils.success(userVOPage); + } } diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserAddRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserAddRequest.java new file mode 100644 index 0000000..8538791 --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserAddRequest.java @@ -0,0 +1,39 @@ +package edu.whut.smilepicturebackend.model.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户创建请求 + */ +@Data +public class UserAddRequest implements Serializable { + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 用户简介 + */ + private String userProfile; + + /** + * 用户角色: user, admin + */ + private String userRole; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/UserLoginRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserLoginRequest.java similarity index 86% rename from src/main/java/edu/whut/smilepicturebackend/model/dto/UserLoginRequest.java rename to src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserLoginRequest.java index 7788626..be44943 100644 --- a/src/main/java/edu/whut/smilepicturebackend/model/dto/UserLoginRequest.java +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserLoginRequest.java @@ -1,4 +1,4 @@ -package edu.whut.smilepicturebackend.model.dto; +package edu.whut.smilepicturebackend.model.dto.user; import lombok.Data; diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserQueryRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserQueryRequest.java new file mode 100644 index 0000000..f656036 --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserQueryRequest.java @@ -0,0 +1,44 @@ +package edu.whut.smilepicturebackend.model.dto.user; + + +import edu.whut.smilepicturebackend.common.PageRequest; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * 用户查询请求 + */ + +@EqualsAndHashCode(callSuper = true) +@Data +public class UserQueryRequest extends PageRequest implements Serializable { + + /** + * id + */ + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 账号 + */ + private String userAccount; + + /** + * 简介 + */ + private String userProfile; + + /** + * 用户角色:user/admin/ban + */ + private String userRole; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserRegisterRequest.java similarity index 88% rename from src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java rename to src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserRegisterRequest.java index 342b386..228a710 100644 --- a/src/main/java/edu/whut/smilepicturebackend/model/dto/UserRegisterRequest.java +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserRegisterRequest.java @@ -1,4 +1,4 @@ -package edu.whut.smilepicturebackend.model.dto; +package edu.whut.smilepicturebackend.model.dto.user; import lombok.Data; diff --git a/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserUpdateRequest.java b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserUpdateRequest.java new file mode 100644 index 0000000..366b724 --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/model/dto/user/UserUpdateRequest.java @@ -0,0 +1,39 @@ +package edu.whut.smilepicturebackend.model.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 更新用户请求 + */ +@Data +public class UserUpdateRequest implements Serializable { + + /** + * id + */ + private Long id; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 简介 + */ + private String userProfile; + + /** + * 用户角色:user/admin + */ + private String userRole; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/model/vo/UserVO.java b/src/main/java/edu/whut/smilepicturebackend/model/vo/UserVO.java new file mode 100644 index 0000000..66f32a6 --- /dev/null +++ b/src/main/java/edu/whut/smilepicturebackend/model/vo/UserVO.java @@ -0,0 +1,51 @@ +package edu.whut.smilepicturebackend.model.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户视图(脱敏) + */ +@Data +public class UserVO implements Serializable { + + /** + * id + */ + private Long id; + + /** + * 账号 + */ + private String userAccount; + + /** + * 用户昵称 + */ + private String userName; + + /** + * 用户头像 + */ + private String userAvatar; + + /** + * 用户简介 + */ + private String userProfile; + + /** + * 用户角色:user/admin + */ + private String userRole; + + + /** + * 创建时间 + */ + private Date createTime; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/edu/whut/smilepicturebackend/service/UserService.java b/src/main/java/edu/whut/smilepicturebackend/service/UserService.java index faf927c..2c4b8d1 100644 --- a/src/main/java/edu/whut/smilepicturebackend/service/UserService.java +++ b/src/main/java/edu/whut/smilepicturebackend/service/UserService.java @@ -1,10 +1,15 @@ package edu.whut.smilepicturebackend.service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; +import edu.whut.smilepicturebackend.model.dto.user.UserAddRequest; +import edu.whut.smilepicturebackend.model.dto.user.UserQueryRequest; import edu.whut.smilepicturebackend.model.entity.User; import edu.whut.smilepicturebackend.model.vo.LoginUserVO; +import edu.whut.smilepicturebackend.model.vo.UserVO; import javax.servlet.http.HttpServletRequest; +import java.util.List; /** * @author 张三 @@ -68,4 +73,12 @@ public interface UserService extends IService { * @return */ boolean userLogout(HttpServletRequest request); + + UserVO getUserVO(User user); + + List getUserVOList(List userList); + + QueryWrapper getQueryWrapper(UserQueryRequest userQueryRequest); + + long createUser(UserAddRequest userAddRequest); } diff --git a/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java b/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java index 890cd41..9b28d03 100644 --- a/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java +++ b/src/main/java/edu/whut/smilepicturebackend/service/impl/UserServiceImpl.java @@ -1,23 +1,37 @@ package edu.whut.smilepicturebackend.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import edu.whut.smilepicturebackend.annotation.AuthCheck; +import edu.whut.smilepicturebackend.common.BaseResponse; +import edu.whut.smilepicturebackend.common.ResultUtils; import edu.whut.smilepicturebackend.constant.UserConstant; import edu.whut.smilepicturebackend.exception.BusinessException; import edu.whut.smilepicturebackend.exception.ErrorCode; +import edu.whut.smilepicturebackend.exception.ThrowUtils; +import edu.whut.smilepicturebackend.model.dto.user.UserAddRequest; +import edu.whut.smilepicturebackend.model.dto.user.UserQueryRequest; import edu.whut.smilepicturebackend.model.entity.User; import edu.whut.smilepicturebackend.model.enums.UserRoleEnum; import edu.whut.smilepicturebackend.model.vo.LoginUserVO; +import edu.whut.smilepicturebackend.model.vo.UserVO; import edu.whut.smilepicturebackend.service.UserService; import edu.whut.smilepicturebackend.mapper.UserMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.GetMapping; import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** @@ -101,26 +115,24 @@ public class UserServiceImpl extends ServiceImpl if (userPassword.length() < 8) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码错误"); } - // 2. 对用户传递的密码进行加密 - String encryptPassword = getEncryptPassword(userPassword); - // 3. 查询数据库中的用户是否存在 - LambdaQueryWrapper lambda = new LambdaQueryWrapper<>(); - lambda - .eq(User::getUserAccount, userAccount) - .eq(User::getUserPassword, encryptPassword); + // 2. 根据账号查询用户(不带密码) + LambdaQueryWrapper lambda = Wrappers.lambdaQuery(); + lambda.eq(User::getUserAccount, userAccount); User user = this.baseMapper.selectOne(lambda); - // 不存在,抛异常 if (user == null) { - log.info("user login failed, userAccount cannot match userPassword"); + throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或者密码错误"); + } + // 3. 用 BCryptPasswordEncoder 去校验明文密码 vs 数据库里存的加密密码 + if (!passwordEncoder.matches(userPassword, user.getUserPassword())) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或者密码错误"); } // 4. 保存用户的登录态 request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, user); return this.getLoginUserVO(user); - } + /** - * 获取脱敏类的用户信息 + * 获取脱敏后的用户信息(无密码) * * @param user 用户 * @return 脱敏后的用户信息 @@ -135,6 +147,38 @@ public class UserServiceImpl extends ServiceImpl return loginUserVO; } + /** + * 获得脱敏后的用户信息(无密码、更新、编辑时间) + * + * @param user + * @return + */ + @Override + public UserVO getUserVO(User user) { + if (user == null) { + return null; + } + UserVO userVO = new UserVO(); + BeanUtil.copyProperties(user, userVO); + return userVO; + } + + /** + * 获取脱敏后的用户列表 + * + * @param userList + * @return + */ + @Override + public List getUserVOList(List userList) { + if (CollUtil.isEmpty(userList)) { + return new ArrayList<>(); + } + return userList.stream() + .map(this::getUserVO) + .collect(Collectors.toList()); + } + @Override public User getLoginUser(HttpServletRequest request) { // 判断是否已经登录 @@ -169,6 +213,53 @@ public class UserServiceImpl extends ServiceImpl request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE); return true; } + + /** + * 查询条件 + * @param userQueryRequest + * @return + */ + @Override + public QueryWrapper getQueryWrapper(UserQueryRequest userQueryRequest) { + if (userQueryRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空"); + } + Long id = userQueryRequest.getId(); + String userName = userQueryRequest.getUserName(); + String userAccount = userQueryRequest.getUserAccount(); + String userProfile = userQueryRequest.getUserProfile(); + String userRole = userQueryRequest.getUserRole(); + String sortField = userQueryRequest.getSortField(); + String sortOrder = userQueryRequest.getSortOrder(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(ObjUtil.isNotNull(id), "id", id); + queryWrapper.eq(StrUtil.isNotBlank(userRole), "userRole", userRole); + queryWrapper.like(StrUtil.isNotBlank(userAccount), "userAccount", userAccount); + queryWrapper.like(StrUtil.isNotBlank(userName), "userName", userName); + queryWrapper.like(StrUtil.isNotBlank(userProfile), "userProfile", userProfile); + queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), sortOrder.equals("ascend"), sortField); + return queryWrapper; + } + + /** + * 创建用户 + */ + @Override + public long createUser(UserAddRequest req) { + // 1. DTO -> entity + User user = new User(); + BeanUtil.copyProperties(req, user); + + // 2. 设定默认密码并加密 + String encoded = passwordEncoder.encode(UserConstant.USER_DEFAULT); + user.setUserPassword(encoded); + + // 3.插入数据库 + boolean result = this.save(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return user.getId(); + } + }