From 980e26f1e96ac555d16d9b05de3cbd7e01285899 Mon Sep 17 00:00:00 2001 From: huangge1199 Date: Mon, 30 Jun 2025 16:28:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9D=97=EF=BC=9A?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 14 +++ .../picture/common/DeleteRequest.java | 22 +++++ .../picture/common/PageRequest.java | 33 +++++++ .../picture/config/JsonConfig.java | 31 ++++++ .../picture/config/MybatisPlusConfig.java | 32 ++++++ .../picture/controller/UserController.java | 98 ++++++++++++++++++- .../model/dto/user/UserAddRequest.java | 43 ++++++++ .../model/dto/user/UserLoginRequest.java | 2 +- .../model/dto/user/UserQueryRequest.java | 45 +++++++++ .../model/dto/user/UserUpdateRequest.java | 42 ++++++++ .../huangge1199/picture/model/vo/UserVO.java | 68 +++++++++++++ .../picture/service/UserService.java | 27 +++++ .../picture/service/impl/UserServiceImpl.java | 47 +++++++++ 13 files changed, 501 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/huangge1199/picture/common/DeleteRequest.java create mode 100644 src/main/java/com/huangge1199/picture/common/PageRequest.java create mode 100644 src/main/java/com/huangge1199/picture/config/JsonConfig.java create mode 100644 src/main/java/com/huangge1199/picture/config/MybatisPlusConfig.java create mode 100644 src/main/java/com/huangge1199/picture/model/dto/user/UserAddRequest.java create mode 100644 src/main/java/com/huangge1199/picture/model/dto/user/UserQueryRequest.java create mode 100644 src/main/java/com/huangge1199/picture/model/dto/user/UserUpdateRequest.java create mode 100644 src/main/java/com/huangge1199/picture/model/vo/UserVO.java diff --git a/pom.xml b/pom.xml index 20946a2..f14fffc 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,12 @@ mybatis-plus-boot-starter 3.5.12 + + + com.baomidou + mybatis-plus-jsqlparser-4.9 + + org.springframework.boot @@ -69,9 +75,17 @@ pom import + + com.baomidou + mybatis-plus-bom + 3.5.9 + pom + import + + diff --git a/src/main/java/com/huangge1199/picture/common/DeleteRequest.java b/src/main/java/com/huangge1199/picture/common/DeleteRequest.java new file mode 100644 index 0000000..2b9627e --- /dev/null +++ b/src/main/java/com/huangge1199/picture/common/DeleteRequest.java @@ -0,0 +1,22 @@ +package com.huangge1199.picture.common; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 通用的删除请求类 + * + * @author huangge1199 + * @since 2025/6/30 16:21:47 + */ +@Data +public class DeleteRequest implements Serializable { + + /** + * id + */ + private Long id; + + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/huangge1199/picture/common/PageRequest.java b/src/main/java/com/huangge1199/picture/common/PageRequest.java new file mode 100644 index 0000000..c0d7677 --- /dev/null +++ b/src/main/java/com/huangge1199/picture/common/PageRequest.java @@ -0,0 +1,33 @@ +package com.huangge1199.picture.common; + +import lombok.Data; + +/** + * 通用的分页请求类 + * + * @author huangge1199 + * @since 2025/6/30 16:07:29 + */ +@Data +public class PageRequest { + + /** + * 当前页号 + */ + private int current = 1; + + /** + * 页面大小 + */ + private int pageSize = 10; + + /** + * 排序字段 + */ + private String sortField; + + /** + * 排序顺序(默认升序) + */ + private String sortOrder = "descend"; +} diff --git a/src/main/java/com/huangge1199/picture/config/JsonConfig.java b/src/main/java/com/huangge1199/picture/config/JsonConfig.java new file mode 100644 index 0000000..3e570bd --- /dev/null +++ b/src/main/java/com/huangge1199/picture/config/JsonConfig.java @@ -0,0 +1,31 @@ +package com.huangge1199.picture.config; + +import org.springframework.boot.jackson.JsonComponent; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import org.springframework.context.annotation.Bean; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +/** + * Spring MVC Json 配置 + * + * @author huangge1199 + * @since 2025/6/30 16:27:00 + */ +@JsonComponent +public class JsonConfig { + + /** + * 添加 Long 转 json 精度丢失的配置 + */ + @Bean + public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + SimpleModule module = new SimpleModule(); + module.addSerializer(Long.class, ToStringSerializer.instance); + module.addSerializer(Long.TYPE, ToStringSerializer.instance); + objectMapper.registerModule(module); + return objectMapper; + } +} diff --git a/src/main/java/com/huangge1199/picture/config/MybatisPlusConfig.java b/src/main/java/com/huangge1199/picture/config/MybatisPlusConfig.java new file mode 100644 index 0000000..73c9de8 --- /dev/null +++ b/src/main/java/com/huangge1199/picture/config/MybatisPlusConfig.java @@ -0,0 +1,32 @@ +package com.huangge1199.picture.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; + +/** + * MybatisPlusConfig + * + * @author huangge1199 + * @since 2025/6/30 16:24:12 + */ +@Configuration +@MapperScan("com.huangge1199.picture.mapper") +public class MybatisPlusConfig { + + /** + * 拦截器配置 + * + * @return {@link MybatisPlusInterceptor} + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } +} diff --git a/src/main/java/com/huangge1199/picture/controller/UserController.java b/src/main/java/com/huangge1199/picture/controller/UserController.java index bedc9f9..5b46b3d 100644 --- a/src/main/java/com/huangge1199/picture/controller/UserController.java +++ b/src/main/java/com/huangge1199/picture/controller/UserController.java @@ -1,17 +1,24 @@ package com.huangge1199.picture.controller; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.huangge1199.picture.annotation.AuthCheck; +import com.huangge1199.picture.common.DeleteRequest; import com.huangge1199.picture.common.R; +import com.huangge1199.picture.constant.UserConstant; import com.huangge1199.picture.exception.ErrorCode; +import com.huangge1199.picture.exception.MyException; import com.huangge1199.picture.exception.ThrowUtils; -import com.huangge1199.picture.model.dto.user.UserLoginRequest; -import com.huangge1199.picture.model.dto.user.UserRegisterRequest; +import com.huangge1199.picture.model.dto.user.*; import com.huangge1199.picture.model.entity.User; import com.huangge1199.picture.model.vo.LoginUserVO; +import com.huangge1199.picture.model.vo.UserVO; import com.huangge1199.picture.service.UserService; +import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import java.util.List; /** * 用户 @@ -70,6 +77,93 @@ public class UserController { return R.ok(result); } + /** + * 创建用户 + */ + @PostMapping("/add") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public R addUser(@RequestBody UserAddRequest userAddRequest) { + ThrowUtils.throwIf(userAddRequest == null, ErrorCode.PARAMS_ERROR); + User user = new User(); + BeanUtils.copyProperties(userAddRequest, user); + // 默认密码 12345678 + final String defaultPassword = "12345678"; + String encryptPassword = userService.getEncryptPassword(defaultPassword); + user.setUserPassword(encryptPassword); + boolean result = userService.save(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return R.ok(user.getId()); + } + + /** + * 根据 id 获取用户(仅管理员) + */ + @GetMapping("/get") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public R getUserById(long id) { + ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR); + User user = userService.getById(id); + ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR); + return R.ok(user); + } + + /** + * 根据 id 获取包装类 + */ + @GetMapping("/get/vo") + public R getUserVoById(long id) { + R response = getUserById(id); + User user = response.getData(); + return R.ok(userService.getUserVO(user)); + } + + /** + * 删除用户 + */ + @PostMapping("/delete") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public R deleteUser(@RequestBody DeleteRequest deleteRequest) { + if (deleteRequest == null || deleteRequest.getId() <= 0) { + throw new MyException(ErrorCode.PARAMS_ERROR); + } + boolean b = userService.removeById(deleteRequest.getId()); + return R.ok(b); + } + + /** + * 更新用户 + */ + @PostMapping("/update") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public R updateUser(@RequestBody UserUpdateRequest userUpdateRequest) { + if (userUpdateRequest == null || userUpdateRequest.getId() == null) { + throw new MyException(ErrorCode.PARAMS_ERROR); + } + User user = new User(); + BeanUtils.copyProperties(userUpdateRequest, user); + boolean result = userService.updateById(user); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + return R.ok(true); + } + + /** + * 分页获取用户封装列表(仅管理员) + * + * @param userQueryRequest 查询请求参数 + */ + @PostMapping("/list/page/vo") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public R> 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 R.ok(userVoPage); + } } diff --git a/src/main/java/com/huangge1199/picture/model/dto/user/UserAddRequest.java b/src/main/java/com/huangge1199/picture/model/dto/user/UserAddRequest.java new file mode 100644 index 0000000..097a341 --- /dev/null +++ b/src/main/java/com/huangge1199/picture/model/dto/user/UserAddRequest.java @@ -0,0 +1,43 @@ +package com.huangge1199.picture.model.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户创建请求 + * + * @author huangge1199 + * @since 2025/6/30 16:04:58 + */ +@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; +} + diff --git a/src/main/java/com/huangge1199/picture/model/dto/user/UserLoginRequest.java b/src/main/java/com/huangge1199/picture/model/dto/user/UserLoginRequest.java index 18b5c2c..5a5138e 100644 --- a/src/main/java/com/huangge1199/picture/model/dto/user/UserLoginRequest.java +++ b/src/main/java/com/huangge1199/picture/model/dto/user/UserLoginRequest.java @@ -5,7 +5,7 @@ import lombok.Data; import java.io.Serializable; /** - * UserLoginRequest + * 用户登录请求 * * @author huangge1199 * @since 2025/6/30 15:24:45 diff --git a/src/main/java/com/huangge1199/picture/model/dto/user/UserQueryRequest.java b/src/main/java/com/huangge1199/picture/model/dto/user/UserQueryRequest.java new file mode 100644 index 0000000..4840630 --- /dev/null +++ b/src/main/java/com/huangge1199/picture/model/dto/user/UserQueryRequest.java @@ -0,0 +1,45 @@ +package com.huangge1199.picture.model.dto.user; + +import com.huangge1199.picture.common.PageRequest; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + * 用户查询请求 + * + * @author huangge1199 + * @since 2025/6/30 16:05:56 + */ +@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; +} diff --git a/src/main/java/com/huangge1199/picture/model/dto/user/UserUpdateRequest.java b/src/main/java/com/huangge1199/picture/model/dto/user/UserUpdateRequest.java new file mode 100644 index 0000000..1fa8387 --- /dev/null +++ b/src/main/java/com/huangge1199/picture/model/dto/user/UserUpdateRequest.java @@ -0,0 +1,42 @@ +package com.huangge1199.picture.model.dto.user; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 更新用户请求 + * + * @author huangge1199 + * @since 2025/6/30 16:06:37 + */ +@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; +} diff --git a/src/main/java/com/huangge1199/picture/model/vo/UserVO.java b/src/main/java/com/huangge1199/picture/model/vo/UserVO.java new file mode 100644 index 0000000..61d660e --- /dev/null +++ b/src/main/java/com/huangge1199/picture/model/vo/UserVO.java @@ -0,0 +1,68 @@ +package com.huangge1199.picture.model.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户视图(脱敏) + * + * @author huangge1199 + * @since 2025/6/30 16:08:38 + */ +@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 vipExpireTime; + + /** + * 会员兑换码 + */ + private String vipCode; + + /** + * 会员编号 + */ + private Long vipNumber; + + /** + * 创建时间 + */ + private Date createTime; + + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/huangge1199/picture/service/UserService.java b/src/main/java/com/huangge1199/picture/service/UserService.java index eca9dcd..a312c33 100644 --- a/src/main/java/com/huangge1199/picture/service/UserService.java +++ b/src/main/java/com/huangge1199/picture/service/UserService.java @@ -1,10 +1,14 @@ package com.huangge1199.picture.service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.huangge1199.picture.model.dto.user.UserQueryRequest; import com.huangge1199.picture.model.entity.User; import com.baomidou.mybatisplus.extension.service.IService; import com.huangge1199.picture.model.vo.LoginUserVO; +import com.huangge1199.picture.model.vo.UserVO; import javax.servlet.http.HttpServletRequest; +import java.util.List; /** * @author hyy @@ -65,5 +69,28 @@ public interface UserService extends IService { */ boolean userLogout(HttpServletRequest request); + /** + * 获得脱敏后的用户信息 + * + * @param user 用户信息 + * @return 脱敏后的用户信息 + */ + UserVO getUserVO(User user); + + /** + * 获得脱敏后的用户信息列表 + * + * @param userList 用户信息列表 + * @return 脱敏后的用户列表 + */ + List getUserVOList(List userList); + + /** + * 获取查询条件 + * @param userQueryRequest + * @return + */ + QueryWrapper getQueryWrapper(UserQueryRequest userQueryRequest); + } diff --git a/src/main/java/com/huangge1199/picture/service/impl/UserServiceImpl.java b/src/main/java/com/huangge1199/picture/service/impl/UserServiceImpl.java index b8dfe51..1b6d786 100644 --- a/src/main/java/com/huangge1199/picture/service/impl/UserServiceImpl.java +++ b/src/main/java/com/huangge1199/picture/service/impl/UserServiceImpl.java @@ -1,22 +1,30 @@ package com.huangge1199.picture.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.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.huangge1199.picture.constant.UserConstant; import com.huangge1199.picture.exception.ErrorCode; import com.huangge1199.picture.exception.MyException; +import com.huangge1199.picture.model.dto.user.UserQueryRequest; import com.huangge1199.picture.model.entity.User; import com.huangge1199.picture.model.enums.UserRoleEnum; import com.huangge1199.picture.model.vo.LoginUserVO; +import com.huangge1199.picture.model.vo.UserVO; import com.huangge1199.picture.service.UserService; import com.huangge1199.picture.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** * @author hyy @@ -145,6 +153,45 @@ public class UserServiceImpl extends ServiceImpl return true; } + @Override + public UserVO getUserVO(User user) { + if (user == null) { + return null; + } + UserVO userVO = new UserVO(); + BeanUtils.copyProperties(user, userVO); + return userVO; + } + + @Override + public List getUserVOList(List userList) { + if (CollUtil.isEmpty(userList)) { + return new ArrayList<>(); + } + return userList.stream().map(this::getUserVO).collect(Collectors.toList()); + } + + @Override + public QueryWrapper getQueryWrapper(UserQueryRequest userQueryRequest) { + if (userQueryRequest == null) { + throw new MyException(ErrorCode.PARAMS_ERROR, "请求参数为空"); + } + Long id = userQueryRequest.getId(); + String userAccount = userQueryRequest.getUserAccount(); + String userName = userQueryRequest.getUserName(); + 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), "ascend".equals(sortOrder), sortField); + return queryWrapper; + } }