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;
+ }
}