数据库构建

创建数据库

image-20251228151201214

用户表创建

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码(加密存储)',
  `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邮箱',
  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手机号',
  `user_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色code',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姓名',
  `avatar` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '头像',
  `status` tinyint NULL DEFAULT 1 COMMENT '状态(0:禁用,1:正常)',
  `created_at` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `uk_username`(`username` ASC) USING BTREE,
  UNIQUE INDEX `uk_email`(`email` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户信息表' ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'test', '$2a$10$iul6jocLsH.A4gN1QUpgDexDq6KO89syHjUkRD3NbA1L6CTVrNRMO', '1796145118@qq.com', '15345678111', 'USER', 'ainio', '/files/bussiness/user_avatar/1763198720591.jpg', 1, '2025-05-14 10:03:12', '2025-11-15 17:25:26', '男');
INSERT INTO `user` VALUES (2, 'admin', '$2a$10$JXCy/159QjA5hJBzy6DYmeOhQSb00nmjeMPJdrfUIUc1HUPYZ98ea', '123456789@qq.com', '13345678910', 'ADMIN', 'admin', '/files/bussiness/user_avatar/1763198163777.jpg', 1, '2025-05-14 11:05:08', '2025-11-15 17:16:04', '男');
INSERT INTO `user` VALUES (4, 'test1', '$2a$10$WM6WQHi9AwRkORfy9TE8PerZ/vRnkK81WUv1d.3KvKvdEzUqqGTiy', '1111@qq.com', '13123456789', 'USER', NULL, '/files/bussiness/user_avatar/1759645666149.jpg', 1, '2025-10-05 14:27:30', '2025-10-05 14:32:46', '男');

SET FOREIGN_KEY_CHECKS = 1;

用户登录接口实现

用户实体

package top.yxqz.springboot.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * 用户实体类
 * @author 余小小
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
@Schema(description = "用户实体类")
public class User {

    @TableId(type = IdType.AUTO)
    @Schema(description = "用户ID")
    private Long id;

    @Schema(description = "用户名")
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 50, message = "用户名长度必须在3到50个字符之间")
    @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用户名只能包含字母、数字和下划线")
    private String username;

    @Schema(description = "密码")
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 100, message = "密码长度必须在6到100个字符之间")
    private String password;

    @Schema(description = "邮箱")
    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    @Size(max = 100, message = "邮箱长度不能超过100个字符")
    private String email;

    @Schema(description = "手机号")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String phone;

    @Schema(description = "用户类型")
    @TableField("user_type")
    private String userType;

    @Schema(description = "姓名")
    @Size(max = 50, message = "姓名长度不能超过50个字符")
    private String name;

    @Schema(description = "头像")
    @Size(max = 200, message = "头像路径长度不能超过200个字符")
    private String avatar;

    @Schema(description = "状态(0:禁用,1:正常)")
    private Integer status;

    @Schema(description = "创建时间")
    @TableField(value = "created_at", fill = FieldFill.INSERT)
    private LocalDateTime createdAt;

    @Schema(description = "更新时间")
    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;

    @Schema(description = "性别")
    private String sex;

    /**
     * 是否为管理员
     */
    public boolean isAdmin() {
        return "ADMIN".equals(this.userType);
    }

    /**
     * 是否为普通用户
     */
    public boolean isUser() {
        return "USER".equals(this.userType);
    }

    /**
     * 是否为正常状态
     */
    public boolean isActive() {
        return this.status != null && this.status == 1;
    }

    /**
     * 是否被禁用
     */
    public boolean isDisabled() {
        return this.status != null && this.status == 0;
    }

    /**
     * 获取用户类型显示名称
     */
    public String getUserTypeDisplayName() {
        if (userType == null) {
            return "未知";
        }
        switch (userType) {
            case "ADMIN":
                return "管理员";
            case "USER":
                return "普通用户";
            default:
                return "未知";
        }
    }

    /**
     * 获取用户状态显示名称
     */
    public String getStatusDisplayName() {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 1:
                return "正常";
            case 0:
                return "禁用";
            default:
                return "未知";
        }
    }

    /**
     * 获取显示名称(优先使用姓名,其次用户名)
     */
    public String getDisplayName() {
        if (name != null && !name.trim().isEmpty()) {
            return name;
        }
        return username;
    }
}

用户类型枚举

package top.yxqz.springboot.enums;

import lombok.Getter;

/**
 * 用户类型枚举
 * @author 余小小
 */
@Getter
public enum UserType {
    
    USER("USER", "普通用户"),
    ADMIN("ADMIN", "管理员");

    private final String code;
    private final String description;

    UserType(String code, String description) {
        this.code = code;
        this.description = description;
    }

    /**
     * 根据代码获取枚举
     */
    public static UserType fromCode(String code) {
        if (code == null) {
            return null;
        }
        for (UserType type : UserType.values()) {
            if (type.getCode().equals(code)) {
                return type;
            }
        }
        throw new IllegalArgumentException("未知的用户类型代码: " + code);
    }

    /**
     * 验证用户类型代码是否有效
     */
    public static boolean isValidCode(String code) {
        if (code == null) {
            return false;
        }
        for (UserType type : UserType.values()) {
            if (type.getCode().equals(code)) {
                return true;
            }
        }
        return false;
    }
}

用户状态枚举

package top.yxqz.springboot.enums;

import lombok.Getter;

/**
 * 用户状态枚举
 * @author 余小小
 */
@Getter
public enum UserStatus {
    
    DISABLED(0, "禁用"),
    NORMAL(1, "正常");

    private final Integer code;
    private final String description;

    UserStatus(Integer code, String description) {
        this.code = code;
        this.description = description;
    }

    /**
     * 根据代码获取枚举
     */
    public static UserStatus fromCode(Integer code) {
        if (code == null) {
            return null;
        }
        for (UserStatus status : UserStatus.values()) {
            if (status.getCode().equals(code)) {
                return status;
            }
        }
        throw new IllegalArgumentException("未知的用户状态代码: " + code);
    }

    /**
     * 验证用户状态代码是否有效
     */
    public static boolean isValidCode(Integer code) {
        if (code == null) {
            return false;
        }
        for (UserStatus status : UserStatus.values()) {
            if (status.getCode().equals(code)) {
                return true;
            }
        }
        return false;
    }
}

用户Mapper接口

package top.yxqz.kindergraten.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import top.yxqz.kindergraten.entity.User;

/**
 * 用户数据访问层
 * @author 余小小
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

}

用户登录服务

  1. 用户查询
    使用 LambdaQueryWrapper 构建查询条件
    支持通过用户名或邮箱进行登录(OR 条件)
    调用 userMapper.selectOne() 查询用户
  2. 验证逻辑
    用户存在性检查:如果查询结果为 null,抛出"用户不存在"异常
    密码验证:使用 BCryptPasswordEncoder 的 matches 方法验证密码
    用户状态检查:验证用户是否处于激活状态(isActive())
  3. Token 生成与响应构建
    使用 JwtTokenUtils.generateToken() 生成 JWT 令牌
    令牌包含用户 ID、用户名和用户类型信息
    使用 UserConvert.entityToDetailResponse() 转换用户实体为详情响应 DTO
    使用 UserConvert.buildLoginResponse() 构建登录响应
  4. 异常处理
    使用 try-catch 结构捕获不同类型的异常
    业务异常(BusinessException)直接抛出
    其他异常记录日志并抛出 ServiceException
  5. 安全特性
    使用 BCrypt 算法对密码进行哈希处理和验证
    支持多因素登录(用户名/邮箱)
    用户状态验证防止已禁用账户登录
package top.yxqz.kindergraten.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import top.yxqz.kindergraten.dto.command.UserLoginCommandDTO;
import top.yxqz.kindergraten.dto.response.UserDetailResponseDTO;
import top.yxqz.kindergraten.dto.response.UserLoginResponseDTO;
import top.yxqz.kindergraten.entity.User;
import top.yxqz.kindergraten.exception.BusinessException;
import top.yxqz.kindergraten.exception.ServiceException;
import top.yxqz.kindergraten.mapper.UserMapper;
import top.yxqz.kindergraten.service.convert.UserConvert;
import top.yxqz.kindergraten.util.JwtTokenUtils;


import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户业务逻辑层
 * @author ftfx
 */
@Slf4j
@Service
public class UserService {

    @Resource
    private UserMapper userMapper;

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 用户登录
     * @param loginDTO 登录命令
     * @return 登录响应
     */
    public UserLoginResponseDTO login(UserLoginCommandDTO loginDTO) {
        try {
            // 根据用户名或邮箱查找用户
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, loginDTO.getUsername())
                    .or()
                    .eq(User::getEmail, loginDTO.getUsername());
            User user = userMapper.selectOne(queryWrapper);


            if (user == null) {
                throw new BusinessException("用户不存在");
            }

            // 验证密码
            if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
                throw new BusinessException("用户名或密码错误");
            }

            // 检查用户状态
            if (!user.isActive()) {
                throw new BusinessException("账号已被禁用,请联系管理员");
            }

            // 生成JWT token
            String token = JwtTokenUtils.generateToken(user.getId(), user.getUsername(), user.getUserType());

            // 构建响应
            UserDetailResponseDTO userInfo = UserConvert.entityToDetailResponse(user);
            return UserConvert.buildLoginResponse(token, userInfo);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("用户登录失败", e);
            throw new ServiceException("登录失败,请稍后重试");
        }
    }




}

用户登录DTO

package top.yxqz.kindergraten.dto.command;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;

/**
 * 用户登录命令DTO
 * @author 余小小
 */
@Data
@Schema(description = "用户登录命令")
public class UserLoginCommandDTO {

    @Schema(description = "用户名或邮箱", example = "admin")
    @NotBlank(message = "用户名或邮箱不能为空")
    @Size(max = 100, message = "用户名或邮箱长度不能超过100个字符")
    private String username;

    @Schema(description = "密码", example = "123456")
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 50, message = "密码长度必须在6到50个字符之间")
    private String password;
}

用户登录响应

package top.yxqz.kindergraten.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 用户登录响应DTO
 * @author 余小小
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户登录响应")
public class UserLoginResponseDTO {

    @Schema(description = "用户信息")
    private UserDetailResponseDTO userInfo;

    @Schema(description = "访问令牌")
    private String token;

    @Schema(description = "角色代码")
    private String roleType;

}

用户详情相应

package top.yxqz.kindergraten.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * 用户详情响应DTO
 * @author 余小小
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户详情响应")
public class UserDetailResponseDTO {

    @Schema(description = "用户ID", example = "1")
    private Long id;

    @Schema(description = "用户名", example = "admin")
    private String username;

    @Schema(description = "邮箱", example = "admin@drone.com")
    private String email;

    @Schema(description = "姓名", example = "系统管理员")
    private String name;

    @Schema(description = "头像", example = "/avatars/admin.jpg")
    private String avatar;

    @Schema(description = "手机号", example = "13800138000")
    private String phone;

    @Schema(description = "性别", example = "男")
    private String sex;

    @Schema(description = "用户类型", example = "ADMIN")
    private String userType;

    @Schema(description = "用户类型显示名称", example = "管理员")
    private String userTypeDisplayName;

    @Schema(description = "用户状态", example = "1")
    private Integer status;

    @Schema(description = "用户状态显示名称", example = "正常")
    private String statusDisplayName;

    @Schema(description = "显示名称", example = "系统管理员")
    private String displayName;

    @Schema(description = "创建时间")
    private LocalDateTime createdAt;

    @Schema(description = "更新时间")
    private LocalDateTime updatedAt;
}

用户接口控制层

package top.yxqz.kindergraten.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import top.yxqz.kindergraten.common.Result;
import top.yxqz.kindergraten.dto.command.UserLoginCommandDTO;
import top.yxqz.kindergraten.dto.response.UserDetailResponseDTO;
import top.yxqz.kindergraten.dto.response.UserLoginResponseDTO;
import top.yxqz.kindergraten.service.UserService;
import top.yxqz.kindergraten.util.JwtTokenUtils;


/**
 * 用户管理控制器
 * @author 余小小
 */
@Tag(name = "用户管理")
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    /**
     * 用户登录
     */
    @Operation(summary = "用户登录")
    @PostMapping("/login")
    public Result<UserLoginResponseDTO> login(@Valid @RequestBody UserLoginCommandDTO loginDTO) {
        log.info("用户登录请求: {}", loginDTO.getUsername());
        UserLoginResponseDTO response = userService.login(loginDTO);
        return Result.success("登录成功", response);
    }




}

JWT解析工具

package top.yxqz.kindergraten.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.yxqz.kindergraten.dto.response.UserDetailResponseDTO;

import java.util.Date;

/**
 * JWT工具类 - 用于JWT token的生成、验证和用户信息获取
 *
 * 主要功能:
 * 1. 生成JWT token(包含userId、username、roleType)
 * 2. 验证JWT token有效性和过期检查
 * 3. 从请求属性中获取当前用户信息(由JwtAuthenticationFilter设置)
 *
 * 使用说明:
 * - Token的解析和提取由JwtAuthenticationFilter负责
 * - Controller中使用getCurrentUser()和getCurrentUserId()获取当前用户信息
 * - 不要直接操作token,所有token相关逻辑在Filter中处理
 *
 * Token传输规范:
 * - 只支持标准的 Authorization: Bearer <token> 方式
 *
 * 安全特性:
 * - 使用HMAC256算法签名
 * - Token有效期7天
 * - 完善的异常处理和日志记录
 */
@Slf4j
public class JwtTokenUtils {

    /**
     * JWT密钥
     */
    private static final String SECRET = "drone_management_system_jwt_secret_key_2024";

    /**
     * Token过期时间(7天)
     */
    private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000L;

    /**
     * Token发行者
     */
    private static final String ISSUER = "drone-management-system";

    /**
     * 生成JWT token
     * @param userId 用户ID
     * @param username 用户名
     * @param roleType 角色代码
     * @return JWT token
     */
    public static String generateToken(Long userId, String username, String roleType) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            Date expireDate = new Date(System.currentTimeMillis() + EXPIRE_TIME);

            return JWT.create()
                    .withClaim("userId", userId)
                    .withClaim("username", username)
                    .withClaim("roleType", roleType)
                    .withExpiresAt(expireDate)
                    .withIssuedAt(new Date())
                    .withIssuer(ISSUER)
                    .sign(algorithm);
        } catch (Exception e) {
            log.error("生成JWT token失败", e);
            throw new RuntimeException("生成JWT token失败", e);
        }
    }

    /**
     * 验证JWT token有效性
     * @param token JWT token
     * @return 解码后的JWT
     * @throws JWTVerificationException token验证失败
     */
    public static DecodedJWT verifyToken(String token) throws JWTVerificationException {
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer(ISSUER)
                .build();
        return verifier.verify(token);
    }

    /**
     * 检查token是否过期
     * @param token JWT token
     * @return 是否过期
     */
    public static boolean isTokenExpired(String token) {
        try {
            DecodedJWT jwt = verifyToken(token);
            return jwt.getExpiresAt().before(new Date());
        } catch (Exception e) {
            return true;
        }
    }

    /**
     * 获取当前请求的用户ID(从RequestContextHolder获取)
     * @return 当前用户ID,获取失败返回null
     */
    public static Long getCurrentUserId() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                Object userId = request.getAttribute("currentUserId");
                if (userId instanceof Long) {
                    return (Long) userId;
                }
            }
        } catch (Exception e) {
            log.error("获取当前用户ID失败", e);
        }
        return null;
    }

    /**
     * 获取当前请求的用户信息(从请求属性中获取)
     * 注意:此方法依赖于JwtAuthenticationFilter设置的请求属性
     * @return 当前用户对象,获取失败返回null
     */
    public static UserDetailResponseDTO getCurrentUser() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                return (UserDetailResponseDTO)request.getAttribute("currentUser");
            }
        } catch (Exception e) {
            log.error("获取当前用户对象失败", e);
        }
        return null;
    }

    /**
     * 获取当前用户ID的字符串形式
     * @return 当前用户ID字符串,获取失败返回null
     */
    public static String getCurrentUserIdAsString() {
        Long userId = getCurrentUserId();
        return userId != null ? String.valueOf(userId) : null;
    }

    /**
     * 获取当前用户类型/角色
     * @return 当前用户类型,获取失败返回null
     */
    public static String getCurrentUserType() {
        UserDetailResponseDTO currentUser = getCurrentUser();
        if(currentUser==null)return null;
        return currentUser.getUserType();

    }

    /**
     * 判断当前用户是否为管理员
     * @return 是否为管理员
     */
    public static boolean isAdmin() {


                return "ADMIN".equals(getCurrentUserType());


    }
}

业务异常类

package top.yxqz.kindergraten.exception;

import lombok.Getter;

/**
 * 业务异常类
 * @author 余小小
 */
@Getter
public class BusinessException extends RuntimeException {
    
    private final String code;

    public BusinessException(String message) {
        super(message);
        this.code = "BUSINESS_ERROR";
    }

    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(String message, Throwable cause) {
        super(message, cause);
        this.code = "BUSINESS_ERROR";
    }

    public BusinessException(String code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}

服务异常类

package top.yxqz.kindergraten.exception;

import lombok.Getter;

/**
 * @author ftfx
 */
@Getter
public class ServiceException extends RuntimeException {
    private final String code;
    private final String msg;

    public ServiceException(String code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public ServiceException(String msg) {
        super(msg);
        this.code = "-1";
        this.msg = msg;
    }
} 

用户转换类

package top.yxqz.kindergraten.service.convert;



import top.yxqz.kindergraten.dto.response.UserDetailResponseDTO;
import top.yxqz.kindergraten.dto.response.UserLoginResponseDTO;
import top.yxqz.kindergraten.entity.User;

import java.time.LocalDateTime;

/**
 * 用户转换类
 * @author 余小小
 */
public class UserConvert {



    /**
     * User实体转换为详情响应DTO
     * @param user User实体
     * @return 用户详情响应DTO
     */
    public static UserDetailResponseDTO entityToDetailResponse(User user) {
        return UserDetailResponseDTO.builder()
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .name(user.getName())
                .avatar(user.getAvatar())
                .phone(user.getPhone())
                .sex(user.getSex())
                .userType(user.getUserType())
                .userTypeDisplayName(user.getUserTypeDisplayName())
                .status(user.getStatus())
                .statusDisplayName(user.getStatusDisplayName())
                .displayName(user.getDisplayName())
                .createdAt(user.getCreatedAt())
                .updatedAt(user.getUpdatedAt())
                .build();
    }

    /**
     * 构建登录响应DTO
     * @param token JWT令牌
     * @param userInfo 用户信息
     * @return 登录响应DTO
     */
    public static UserLoginResponseDTO buildLoginResponse(String token, UserDetailResponseDTO userInfo) {
        return UserLoginResponseDTO.builder()
                .userInfo(userInfo)
                .token(token)
                .roleType(userInfo.getUserType())
                .build();
    }


}

接口测试

使用之前,记得修改配置(文档扫描的包路径)

image-20251228175814270

Knife4J

http://localhost:8889/doc.html

账号:admin

密码:admin

测试工具安装(apiPost)

Apipost-API 文档、设计、调试、自动化测试一体化协作平台

最后修改:2025 年 12 月 29 日
如果觉得我的文章对你有用,请随意赞赏