From 3eb2edbe858e1dcd0b682401484b7b40b796d834 Mon Sep 17 00:00:00 2001 From: ikmkj <1@qq,com> Date: Mon, 16 Jun 2025 20:55:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(user):=20=E6=96=B0=E5=A2=9E=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=B3=A8=E5=86=8C=E3=80=81=E7=99=BB=E5=BD=95=E5=92=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增用户实体类和相关控制器、服务类 - 实现用户注册、登录和删除功能 - 添加用户token生成和验证逻辑 -优化密码存储,使用加密算法 --- biji-houdaun/pom.xml | 7 +++ .../bijihoudaun/config/Knife4jConfig.java | 47 ++++++++++++++++ .../config/RestTemplateConfig.java | 14 +++++ .../controller/ImageController.java | 14 ++++- .../controller/MarkdownController.java | 20 ++++++- .../controller/UserController.java | 55 +++++++++++++++++++ .../com/test/bijihoudaun/entity/Image.java | 18 ++++-- .../test/bijihoudaun/entity/MarkdownFile.java | 13 ++++- .../com/test/bijihoudaun/entity/User.java | 12 +++- .../test/bijihoudaun/service/UserService.java | 7 +++ .../service/impl/UserServiceImpl.java | 31 +++++++++-- .../test/bijihoudaun/util/PasswordUtils.java | 27 +++++++++ 12 files changed, 250 insertions(+), 15 deletions(-) create mode 100644 biji-houdaun/src/main/java/com/test/bijihoudaun/config/Knife4jConfig.java create mode 100644 biji-houdaun/src/main/java/com/test/bijihoudaun/config/RestTemplateConfig.java create mode 100644 biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java create mode 100644 biji-houdaun/src/main/java/com/test/bijihoudaun/util/PasswordUtils.java diff --git a/biji-houdaun/pom.xml b/biji-houdaun/pom.xml index d486d64..e8a2c58 100644 --- a/biji-houdaun/pom.xml +++ b/biji-houdaun/pom.xml @@ -87,6 +87,13 @@ org.springframework.boot spring-boot-starter-web + + + org.springframework.security + spring-security-core + 5.7.1 + + diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/config/Knife4jConfig.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/config/Knife4jConfig.java new file mode 100644 index 0000000..e0f60f4 --- /dev/null +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/config/Knife4jConfig.java @@ -0,0 +1,47 @@ +package com.test.bijihoudaun.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springdoc.core.models.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class Knife4jConfig { + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("API文档") + .version("1.0") + .description("系统API文档") + + ); + } + @Bean + public GroupedOpenApi commonApi() { + return GroupedOpenApi.builder() + .group("图片接口") + .pathsToMatch("/api/images/**") + .build(); + } + + @Bean + public GroupedOpenApi tokenApi() { + return GroupedOpenApi.builder() + .group("markdown接口") + .pathsToMatch("/api/markdown/**") + .build(); + } + + @Bean + public GroupedOpenApi LotteryResultsApi() { + return GroupedOpenApi.builder() + .group("用户接口") + .pathsToMatch("/api/user/**") + .build(); + } + + +} diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/config/RestTemplateConfig.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/config/RestTemplateConfig.java new file mode 100644 index 0000000..4385c32 --- /dev/null +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/config/RestTemplateConfig.java @@ -0,0 +1,14 @@ +package com.test.bijihoudaun.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java index 96145ec..0c54c63 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java @@ -3,13 +3,19 @@ package com.test.bijihoudaun.controller; import com.test.bijihoudaun.entity.Image; import com.test.bijihoudaun.service.ImageService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; - +@Tag(name = "markdown接口") @RestController @RequestMapping("/api/images") public class ImageController { @@ -17,6 +23,12 @@ public class ImageController { @Autowired private ImageService imageService; + @Operation(summary = "上传图片") + @Parameters({ + @Parameter(name = "userId", description = "用户id", required = true), + @Parameter(name = "markdownId", description = "markdownid", required = true), + @Parameter(name = "file", description = "图片文件", required = true) + }) @PostMapping public ResponseEntity uploadImage( @RequestParam Integer userId, diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java index 9e9d978..e66b885 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java @@ -2,10 +2,14 @@ package com.test.bijihoudaun.controller; import com.test.bijihoudaun.entity.MarkdownFile; import com.test.bijihoudaun.service.MarkdownFileService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; - +@Tag(name = "markdown接口") @RestController @RequestMapping("/api/markdown") public class MarkdownController { @@ -13,6 +17,13 @@ public class MarkdownController { @Autowired private MarkdownFileService markdownFileService; + @Operation(summary = "创建markdown文件") + @Parameters({ + @Parameter(name = "userId", description = "用户id",required = true), + @Parameter(name = "title", description = "标题",required = true), + @Parameter(name = "fileName", description = "文件名",required = true), + @Parameter(name = "content", description = "内容",required = true) + }) @PostMapping public ResponseEntity createMarkdown( @RequestParam Integer userId, @@ -26,7 +37,12 @@ public class MarkdownController { return ResponseEntity.ok(file); } - @PutMapping("/{id}") + @Operation(summary = "更新Markdown文件") + @Parameters({ + @Parameter(name = "id", description = "Markdown文件ID", required = true), + @Parameter(name = "content", description = "Markdown文件内容", required = true) + }) + @PostMapping("/{id}") public ResponseEntity updateMarkdown( @PathVariable Integer id, @RequestBody String content) { diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java new file mode 100644 index 0000000..6b35223 --- /dev/null +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java @@ -0,0 +1,55 @@ +package com.test.bijihoudaun.controller; + +import com.test.bijihoudaun.common.response.R; +import com.test.bijihoudaun.entity.User; +import com.test.bijihoudaun.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +@Tag(name = "用户接口") +@RestController +@RequestMapping("/api/user") +public class UserController { + @Autowired + private UserService userService; + + @Operation(summary = "用户注册") + @Parameters({ + @Parameter(name = "username", description = "用户名",required = true), + @Parameter(name = "password", description = "密码",required = true), + @Parameter(name = "email", description = "邮箱",required = true) + }) + @PostMapping("/register") + public R register(String username, String password, String email){ + return R.success(userService.register(username,password,email)); + } + + @Operation(summary = "用户登录") + @Parameters({ + @Parameter(name = "username", description = "用户名",required = true), + @Parameter(name = "password", description = "密码",required = true) + }) + @PostMapping("/login") + public R login(String username, String password){ + return R.success(userService.login(username,password)); + } + + @Operation(summary = "用户删除") + @Parameters({ + @Parameter(name = "id", description = "用户id",required = true) + }) + @DeleteMapping("/deleteUser") + public R deleteUser(Integer id){ + userService.deleteUser(id); + return R.success("删除成功"); + } + + + +} diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/Image.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/Image.java index e1be22e..fe15352 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/Image.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/Image.java @@ -4,27 +4,37 @@ 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 lombok.Data; import java.time.LocalDateTime; @Data +@Schema(name = "图片实体") @TableName("image") public class Image { + @Schema(description = "图片id",implementation = Long.class) @TableId(type = IdType.AUTO) - private Integer id; - private Integer userId; - private Integer markdownId; + private Long id; + @Schema(description = "图片名称",implementation = Long.class ) + private Long userId; + @Schema(description = "图片名称",implementation = Long.class ) + private Long markdownId; + @Schema(description = "图片名称",implementation = String.class ) @TableField("original_name") private String originalName; + @Schema(description = "图片名称",implementation = String.class ) @TableField("stored_name") private String storedName; + @Schema(description = "图片名称",implementation = String.class ) private String url; - private Integer size; + @Schema(description = "图片大小",implementation = Long.class ) + private Long size; + @Schema(description = "图片类型",implementation = String.class ) @TableField("content_type") private String contentType; diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java index e50aad5..7e25db3 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java @@ -4,22 +4,31 @@ 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 lombok.Data; import java.time.LocalDateTime; @Data +@Schema(name = "文本实体") @TableName("markdown_file") public class MarkdownFile { + @Schema(description = "文本id",implementation = Long.class) @TableId(type = IdType.AUTO) - private Integer id; - private Integer userId; + private Long id; + @Schema(description = "用户id",implementation = Long.class) + private Long userId; + @Schema(description = "文本标题",implementation = String.class) private String title; + @Schema(description = "文本内容",implementation = String.class) @TableField("file_name") private String fileName; + @Schema(description = "文本内容",implementation = String.class) private String content; + @Schema(description = "创建时间",implementation = LocalDateTime.class) private LocalDateTime createdAt; + @Schema(description = "更新时间",implementation = LocalDateTime.class) private LocalDateTime updatedAt; } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/User.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/User.java index eeaa309..f86ec3c 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/User.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/User.java @@ -3,20 +3,30 @@ package com.test.bijihoudaun.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; @Data +@Schema(name = "用户实体") @TableName("user") public class User { + @Schema(description = "用户id",implementation = Long.class) @TableId(type = IdType.AUTO) - private Integer id; + private Long id; + @Schema(description = "用户名",implementation = String.class) private String username; + @Schema(description = "密码",implementation = String.class) private String password; + @Schema(description = "邮箱",implementation = String.class) private String email; + @Schema(description = "用户创建时间",implementation = String.class) private LocalDateTime createdAt; + @Schema(description = "用户更新时间",implementation = String.class) private LocalDateTime updatedAt; + @Schema(description = "用户token",implementation = String.class) private String token; + @Schema(description = "用户token过期时间",implementation = String.class) private LocalDateTime tokenEnddata; } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java index d475f47..d74d78a 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java @@ -26,4 +26,11 @@ public interface UserService extends IService { * @param id 用户id */ void deleteUser(Integer id); + + /** + * 查询用户token是否过期 + * @param id 用户id + * @return Boolean + */ + Boolean isTokenExpired(Long id,String token); } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java index 96fa5f7..23d1020 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java @@ -1,12 +1,13 @@ package com.test.bijihoudaun.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.test.bijihoudaun.entity.User; import com.test.bijihoudaun.mapper.UserMapper; import com.test.bijihoudaun.service.UserService; +import com.test.bijihoudaun.util.PasswordUtils; +import com.test.bijihoudaun.util.UuidV7; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -20,6 +21,7 @@ public class UserServiceImpl extends ServiceImpl implements Us @Override public User register(String username, String password, String email) { + String encrypt = PasswordUtils.encrypt(password); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getUsername, username); if (this.count(queryWrapper) > 0) { @@ -32,7 +34,7 @@ public class UserServiceImpl extends ServiceImpl implements Us } User user = new User(); user.setUsername(username); - user.setPassword(password); + user.setPassword(encrypt); user.setEmail(email); user.setCreatedAt(LocalDateTime.now()); userMapper.insert(user); @@ -42,13 +44,32 @@ public class UserServiceImpl extends ServiceImpl implements Us @Override public User login(String username, String password) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(User::getUsername, username) - .eq(User::getPassword, password); - return userMapper.selectOne(queryWrapper); + queryWrapper.eq(User::getUsername, username); + User user = userMapper.selectOne(queryWrapper); + boolean verify = PasswordUtils.verify(password, user.getPassword()); + if (!verify) { + throw new RuntimeException("密码错误"); + } + user.setToken(UuidV7.uuidNoHyphen()); + // 过期时间:当前时间+3天的时间 + user.setTokenEnddata(LocalDateTime.now().plusDays(3)); + userMapper.updateById(user); + return user; } @Override public void deleteUser(Integer id) { userMapper.deleteById(id); } + + @Override + public Boolean isTokenExpired(Long id, String token) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(User::getId, id) + .eq(User::getToken, token); + User user = getOne(queryWrapper); + // 新增过期检查 + return user != null && LocalDateTime.now().isBefore(user.getTokenEnddata()); + + } } \ No newline at end of file diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/util/PasswordUtils.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/util/PasswordUtils.java new file mode 100644 index 0000000..2daa3c5 --- /dev/null +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/util/PasswordUtils.java @@ -0,0 +1,27 @@ +package com.test.bijihoudaun.util; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +public class PasswordUtils { + // 初始化加密器(工作因子默认10) + private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + + /** + * 加密密码 + * @param rawPassword 原始密码 + * @return 加密后的哈希值(包含salt) + */ + public static String encrypt(String rawPassword) { + return encoder.encode(rawPassword); + } + + /** + * 验证密码 + * @param rawPassword 用户输入的原始密码 + * @param encodedPassword 数据库存储的加密密码 + * @return 是否匹配 + */ + public static boolean verify(String rawPassword, String encodedPassword) { + return encoder.matches(rawPassword, encodedPassword); + } +}