diff --git a/docs/tasks/任务8-Sprint-1-获取当前用户信息接口.md b/docs/tasks/任务8-Sprint-1-获取当前用户信息接口.md new file mode 100644 index 0000000..9e037ee --- /dev/null +++ b/docs/tasks/任务8-Sprint-1-获取当前用户信息接口.md @@ -0,0 +1,163 @@ +## 任务名称: 获取当前用户信息 +### 目标: +- 了解DTO的使用 +- 掌握mapstruct的使用 +- 掌握如何获取当前用户 + +### 预备知识: +- [列出完成该任务前学生应具备的基础知识或先修技能,如特定编程语言基础、框架了解等。] + +### 操作步骤: +1. **引入mapstruct依赖** +> MapStruct是一个开源的Java库,它通过注解处理器自动创建对象之间的映射代码。这个库的主要目的是减少在处理对象转换时的手动编写样板代码,尤其是当需要在不同领域模型、数据传输对象(DTOs)或数据库实体之间进行映射时。 +> +> 使用MapStruct,你只需要定义一个映射接口,该接口声明了源对象和目标对象之间的转换方法。MapStruct会自动生成接口的实现,这个实现包含了实际的属性映射逻辑。这种方法使得映射代码保持清晰、简洁且类型安全。 +2. **创建UserDto类** +```java +package com.lk.paopao.dto; + +import lombok.Value; +import java.io.Serializable; + +@Value +public class UserDto implements Serializable { + Long id; + String nickname; + String username; + String phone; + Byte status; + String avatar; + Long balance; + Boolean isAdmin; +} + +``` +> @Value 是 Lombok 库提供的一个注解,用于简化 Java 类的编写。当这个注解应用在一个类上时,Lombok 会自动为类的所有字段生成以下内容: +- 私有字段(Private fields):所有字段默认变为私有,并且没有公共访问器(getter 和 setter)。 +- 构造器:生成一个全参数的构造器,用于初始化所有字段。 +- final 字段:如果字段没有初始化,Lombok 会将其声明为 final,并要求在构造器中提供初始值。 +- equals() 和 hashCode():生成 equals() 和 hashCode() 方法,基于所有字段进行比较。 +- toString():生成 toString() 方法,显示类实例的字段值。 +- 不可变性(Immutability):默认情况下,类是不可变的,这意味着一旦创建,对象的状态就不能改变。字段默认都是 final 的,除非显式声明它们不是。 + +3. **创建UserMapper接口** + +```java +package com.lk.paopao.mapper; + +import com.lk.paopao.entity.User; +import com.lk.paopao.dto.UserDto; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@Mapper(componentModel = "spring") +public interface UserMapper { + User toEntity(UserDto userDto); + + UserDto toDto(User user); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + User partialUpdate(UserDto userDto, @MappingTarget User user); +} +``` +**代码中用到的注解解释:** +- @Mapper: 这是一个 MapStruct 注解,用于创建一个映射接口。 +- componentModel = "spring": 这个参数指定了生成的映射器类应该使用 Spring 的组件模型,这样可以在 Spring 应用程序中自动注册。 +- @BeanMapping: 这个注解用于配置映射方法。 +- nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE: 这个参数指定了当目标对象中的某个属性为 null 时,是否忽略该属性的映射。 +- @MappingTarget: 这个注解用于指定目标对象,用于更新目标对象。 + +4. **在AuthService中添加获取当前用户方法** +```java +/** + * 获取当前登录的用户详情。 + * @return 当前登录的UserDetails对象 + * @throws AuthFailedException 如果无法获取当前用户详情,则抛出异常 + */ + public UserDetails getCurrentUserDetails() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication.getPrincipal() instanceof UserDetails) { + return (UserDetails) authentication.getPrincipal(); + } + throw new AuthFailedException("找不到用户在线信息"); + } + + /** + * 获取当前登录的用户信息。 + * @return 当前登录的用户信息 + * @throws AuthFailedException 如果无法获取当前用户信息,则抛出异常 + */ + public User getCurrentUser() { + // 通过当前用户详情获取用户信息 + return userRepository.findByUsername(getCurrentUserDetails().getUsername()).orElseThrow(()->new AuthFailedException("找不到用户在线信息")); + } +``` +5. **创建UserService类** +```java +package com.lk.paopao.service; + +import com.lk.paopao.dto.UserDto; +import com.lk.paopao.mapper.UserMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UserService { + @Autowired + private UserMapper userMapper; + @Autowired + private AuthService authService; + + /** + * 获取当前用户的基本信息 + * @return UserDto 当前用户的数据传输对象 + */ + public UserDto info(){ + return userMapper.toDto(authService.getCurrentUser()); + } +} +``` +6. **创建UserController类** +```java +package com.lk.paopao.controller; + +import com.lk.paopao.dto.UserDto; +import com.lk.paopao.dto.rest.response.DataResult; +import com.lk.paopao.dto.rest.response.ResultUtil; +import com.lk.paopao.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${app.version}/user") +public class UserController { + + @Autowired + private UserService userService; + + @GetMapping("/info") + public DataResult info() { + return ResultUtil.ok(userService.info()); + } +} +``` +7. **测试** + +### 技术/工具需求: +- [列出完成任务所需的技术栈、工具、软件版本等。] + +### 成功标准: +- [明确完成任务的评判标准,如代码功能实现、性能指标、测试通过条件等。] + +### 扩展学习(可选): +- [提供一些额外学习资源或挑战性任务,鼓励学有余力的学生进一步探索。] + +### 评估与反馈: +- [说明如何提交作业、代码审查的标准、或任何反馈收集机制。] + +### 时间估算: +- [给出预计完成该任务所需的时间,帮助学生合理安排学习计划。] \ No newline at end of file