From c4dbc9e475d885814296bf011c0320ad85d14783 Mon Sep 17 00:00:00 2001 From: ziin Date: Wed, 3 Dec 2025 16:29:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(character):=20=E6=96=B0=E5=A2=9E=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BA=BA=E8=AE=BE=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=B9=B6=E6=94=AF=E6=8C=81=E9=82=AE=E7=AE=B1=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CharacterController 增加 /listByUser 端点,返回当前用户已购人设 - KeyboardCharacterService 新增 selectListByUserId(),通过 Sa-Token 取当前用户 ID - 引入 KeyboardUserCharacter 中间表及对应 Mapper、VO - UserController 增加 /login 端点,支持邮箱+密码登录 - 统一将实体与 VO 的 title 字段更名为 characterName - 补充错误码 USER_NOT_FOUND,调整 Sa-Token 白名单与 Redis 依赖 --- pom.xml | 12 ++++++ .../com/yolo/keyborad/common/ErrorCode.java | 3 +- .../keyborad/config/SaTokenConfigure.java | 6 ++- .../controller/CharacterController.java | 9 ++++ .../keyborad/controller/UserController.java | 11 +++++ .../mapper/KeyboardUserCharacterMapper.java | 12 ++++++ .../keyborad/model/dto/user/UserLoginDTO.java | 13 ++++++ .../model/entity/KeyboardCharacter.java | 4 +- .../model/entity/KeyboardUserCharacter.java | 43 +++++++++++++++++++ .../vo/character/KeyboardCharacterRespVO.java | 2 +- .../vo/character/KeyboardUserCharacterVO.java | 28 ++++++++++++ .../service/KeyboardCharacterService.java | 4 ++ .../yolo/keyborad/service/UserService.java | 4 ++ .../impl/KeyboardCharacterServiceImpl.java | 28 ++++++++++++ .../service/impl/UserServiceImpl.java | 22 ++++++++++ .../mapper/KeyboardCharacter‌Mapper.xml | 4 +- .../mapper/KeyboardUserCharacterMapper.xml | 16 +++++++ 17 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java create mode 100644 src/main/java/com/yolo/keyborad/model/dto/user/UserLoginDTO.java create mode 100644 src/main/java/com/yolo/keyborad/model/entity/KeyboardUserCharacter.java create mode 100644 src/main/java/com/yolo/keyborad/model/vo/character/KeyboardUserCharacterVO.java create mode 100644 src/main/resources/mapper/KeyboardUserCharacterMapper.xml diff --git a/pom.xml b/pom.xml index 5b58885..2c21ea9 100644 --- a/pom.xml +++ b/pom.xml @@ -207,6 +207,18 @@ sa-token-spring-boot3-starter 1.44.0 + + + cn.dev33 + sa-token-redis-template + 1.44.0 + + + + + org.apache.commons + commons-pool2 + diff --git a/src/main/java/com/yolo/keyborad/common/ErrorCode.java b/src/main/java/com/yolo/keyborad/common/ErrorCode.java index 94f9452..86e9807 100644 --- a/src/main/java/com/yolo/keyborad/common/ErrorCode.java +++ b/src/main/java/com/yolo/keyborad/common/ErrorCode.java @@ -27,7 +27,8 @@ public enum ErrorCode { TOKEN_KICK_OUT(40107, "令牌已被踢下线"), TOKEN_FREEZE(40108, "令牌已被冻结"), TOKEN_NO_PREFIX(40109, "未按照指定前缀提交令牌"), - FILE_NAME_ERROR(40002, "文件名错误"); + FILE_NAME_ERROR(40002, "文件名错误"), + USER_NOT_FOUND(40401, "用户不存在"); /** * 状态码 */ diff --git a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java index a36ba09..84bdb67 100644 --- a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java +++ b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java @@ -68,7 +68,11 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/file/upload", "/user/logout", "/tag/list", - "/character/list" + "/character/list", + "/character/detail", + "/character/listByTag", + "/user/login", + "/character/listByUser" }; } @Bean diff --git a/src/main/java/com/yolo/keyborad/controller/CharacterController.java b/src/main/java/com/yolo/keyborad/controller/CharacterController.java index 3b8d569..c6835fe 100644 --- a/src/main/java/com/yolo/keyborad/controller/CharacterController.java +++ b/src/main/java/com/yolo/keyborad/controller/CharacterController.java @@ -1,11 +1,14 @@ package com.yolo.keyborad.controller; +import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; import com.yolo.keyborad.common.BaseResponse; import com.yolo.keyborad.common.ResultUtils; import com.yolo.keyborad.model.entity.KeyboardCharacter; import com.yolo.keyborad.model.entity.KeyboardTag; +import com.yolo.keyborad.model.entity.KeyboardUserCharacter; import com.yolo.keyborad.model.vo.character.KeyboardCharacterRespVO; +import com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO; import com.yolo.keyborad.model.vo.tags.TagsRespVO; import com.yolo.keyborad.service.KeyboardCharacterService; import io.swagger.v3.oas.annotations.Operation; @@ -53,4 +56,10 @@ public class CharacterController { return ResultUtils.success(BeanUtil.copyToList(list, KeyboardCharacterRespVO.class)); } + @GetMapping("/listByUser") + @Operation(summary = "用户人设列表", description = "用户人设列表接口") + public BaseResponse> userList() { + List keyboardCharacters = characterService.selectListByUserId(); + return ResultUtils.success(BeanUtil.copyToList(keyboardCharacters, KeyboardUserCharacterVO.class)); + } } diff --git a/src/main/java/com/yolo/keyborad/controller/UserController.java b/src/main/java/com/yolo/keyborad/controller/UserController.java index e0f12e6..bf8d808 100644 --- a/src/main/java/com/yolo/keyborad/controller/UserController.java +++ b/src/main/java/com/yolo/keyborad/controller/UserController.java @@ -4,14 +4,17 @@ import cn.dev33.satoken.stp.StpUtil; import com.yolo.keyborad.common.BaseResponse; import com.yolo.keyborad.common.ResultUtils; import com.yolo.keyborad.model.dto.AppleLoginReq; +import com.yolo.keyborad.model.dto.user.UserLoginDTO; import com.yolo.keyborad.model.vo.user.KeyboardUserRespVO; import com.yolo.keyborad.service.IAppleService; +import com.yolo.keyborad.service.UserService; 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 lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** @@ -29,6 +32,9 @@ public class UserController { @Resource private IAppleService appleService; + @Resource + private UserService userService; + /** * 苹果登录 * @@ -48,4 +54,9 @@ public class UserController { return ResultUtils.success(true); } + @PostMapping("/login") + @Operation(summary = "登录", description = "登录接口") + public BaseResponse login(@RequestBody UserLoginDTO userLoginDTO) { + return ResultUtils.success(userService.login(userLoginDTO)); + } } diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java new file mode 100644 index 0000000..2f6d18d --- /dev/null +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java @@ -0,0 +1,12 @@ +package com.yolo.keyborad.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yolo.keyborad.model.entity.KeyboardUserCharacter; + +/* +* @author: ziin +* @date: 2025/12/3 15:43 +*/ + +public interface KeyboardUserCharacterMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/model/dto/user/UserLoginDTO.java b/src/main/java/com/yolo/keyborad/model/dto/user/UserLoginDTO.java new file mode 100644 index 0000000..372a5da --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/dto/user/UserLoginDTO.java @@ -0,0 +1,13 @@ +package com.yolo.keyborad.model.dto.user; + +import lombok.Data; + +/* + * @author: ziin + * @date: 2025/12/3 16:06 + */ +@Data +public class UserLoginDTO { + private String mail; + private String password; +} diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java index cdc9397..e50fa4a 100644 --- a/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java @@ -21,9 +21,9 @@ public class KeyboardCharacter { @Schema(description="主键 Id") private Long id; - @TableField(value = "title") + @TableField(value = "character_name") @Schema(description="标题") - private String title; + private String characterName; @TableField(value = "\"character_background\"") @Schema(description="背景描述") diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserCharacter.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserCharacter.java new file mode 100644 index 0000000..5e7fba9 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardUserCharacter.java @@ -0,0 +1,43 @@ +package com.yolo.keyborad.model.entity; + +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 java.util.Date; +import lombok.Data; + +/* +* @author: ziin +* @date: 2025/12/3 15:43 +*/ + +@Schema +@Data +@TableName(value = "keyboard_user_character") +public class KeyboardUserCharacter { + @TableId(value = "id", type = IdType.AUTO) + @Schema(description="主键 Id") + private Long id; + + @TableField(value = "character_id") + @Schema(description="键盘人设 id") + private Long characterId; + + @TableField(value = "deleted") + @Schema(description="是否删除") + private Boolean deleted; + + @TableField(value = "created_at") + @Schema(description="创建时间") + private Date createdAt; + + @TableField(value = "updated_at") + @Schema(description="更新时间") + private Date updatedAt; + + @TableField(value = "user_id") + @Schema(description="用户 id") + private Long userId; +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardCharacterRespVO.java b/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardCharacterRespVO.java index af254b0..6174e6a 100644 --- a/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardCharacterRespVO.java +++ b/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardCharacterRespVO.java @@ -21,7 +21,7 @@ public class KeyboardCharacterRespVO { private Long id; @Schema(description="标题") - private String title; + private String characterName; @Schema(description="背景描述") diff --git a/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardUserCharacterVO.java b/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardUserCharacterVO.java new file mode 100644 index 0000000..e9cb0bd --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/vo/character/KeyboardUserCharacterVO.java @@ -0,0 +1,28 @@ +package com.yolo.keyborad.model.vo.character; + +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.util.Date; + +/* +* @author: ziin +* @date: 2025/12/3 15:43 +*/ + +@Schema +@Data +@TableName(value = "keyboard_user_character") +public class KeyboardUserCharacterVO { + @TableId(value = "id", type = IdType.AUTO) + @Schema(description="主键 Id") + private Long id; + + @Schema(description = "人设名") + private String characterName; + +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java index 610c3b5..2f93337 100644 --- a/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java +++ b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java @@ -3,6 +3,7 @@ package com.yolo.keyborad.service; import com.yolo.keyborad.model.entity.KeyboardCharacter; import com.baomidou.mybatisplus.extension.service.IService; import com.yolo.keyborad.model.entity.KeyboardTag; +import com.yolo.keyborad.model.entity.KeyboardUserCharacter; import java.util.List; /* @@ -16,4 +17,7 @@ public interface KeyboardCharacterService extends IService{ List selectListWithRank(); List selectListByTag(Long tagId); + + List selectListByUserId(); + } diff --git a/src/main/java/com/yolo/keyborad/service/UserService.java b/src/main/java/com/yolo/keyborad/service/UserService.java index c6ebf89..9911c88 100644 --- a/src/main/java/com/yolo/keyborad/service/UserService.java +++ b/src/main/java/com/yolo/keyborad/service/UserService.java @@ -1,7 +1,9 @@ package com.yolo.keyborad.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.yolo.keyborad.model.dto.user.UserLoginDTO; import com.yolo.keyborad.model.entity.KeyboardUser; +import com.yolo.keyborad.model.vo.user.KeyboardUserRespVO; /* * @author: ziin @@ -12,4 +14,6 @@ public interface UserService extends IService { KeyboardUser selectUserWithSubjectId(String sub); KeyboardUser createUserWithSubjectId(String sub); + + KeyboardUserRespVO login(UserLoginDTO userLoginDTO); } diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java index d2de9f8..a31e35f 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java @@ -1,8 +1,12 @@ package com.yolo.keyborad.service.impl; +import cn.dev33.satoken.stp.StpUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.yolo.keyborad.mapper.KeyboardCharacterMapper; +import com.yolo.keyborad.mapper.KeyboardUserCharacterMapper; +import com.yolo.keyborad.model.entity.KeyboardUserCharacter; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -21,6 +25,9 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListWithRank() { return keyboardCharacterMapper.selectList(new LambdaQueryWrapper() @@ -35,4 +42,25 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListByUserId() { + long loginId = StpUtil.getLoginIdAsLong(); + + List keyboardUserCharacters = keyboardUserCharacterMapper.selectList(new LambdaQueryWrapper() + .eq(KeyboardUserCharacter::getDeleted, false) + .eq(KeyboardUserCharacter::getUserId, loginId)); + + List characterIds = keyboardUserCharacters.stream() + .map(KeyboardUserCharacter::getCharacterId) + .toList(); + if (CollectionUtils.isEmpty(characterIds)) { + return null; + } + + return keyboardCharacterMapper.selectList(new LambdaQueryWrapper() + .eq(KeyboardCharacter::getDeleted, false) + .in(KeyboardCharacter::getId, characterIds)); + + } } diff --git a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java index 408dd75..68bbf80 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/UserServiceImpl.java @@ -1,11 +1,17 @@ package com.yolo.keyborad.service.impl; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yolo.keyborad.common.ErrorCode; +import com.yolo.keyborad.exception.BusinessException; import com.yolo.keyborad.mapper.KeyboardUserMapper; +import com.yolo.keyborad.model.dto.user.UserLoginDTO; import com.yolo.keyborad.model.entity.KeyboardUser; +import com.yolo.keyborad.model.vo.user.KeyboardUserRespVO; import com.yolo.keyborad.service.UserService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -40,4 +46,20 @@ public class UserServiceImpl extends ServiceImpl() + .eq(KeyboardUser::getEmail, userLoginDTO.getMail()) + .eq(KeyboardUser::getPassword, userLoginDTO.getPassword()) + .eq(KeyboardUser::getStatus, false)); + if (keyboardUser == null) { + throw new BusinessException(ErrorCode.USER_NOT_FOUND); + } + StpUtil.login(keyboardUser.getId()); + KeyboardUserRespVO keyboardUserRespVO = BeanUtil.copyProperties(keyboardUser, KeyboardUserRespVO.class); + keyboardUserRespVO.setToken(StpUtil.getTokenValue()); + return keyboardUserRespVO; + } } diff --git a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml index c4e5535..6d28caa 100644 --- a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml +++ b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml @@ -4,7 +4,7 @@ - + @@ -16,7 +16,7 @@ - id, title, "character_background", avatar_url, download, tag, deleted, created_at, + id, character_name, "character_background", avatar_url, download, tag, deleted, created_at, updated_at, prompt, "rank" \ No newline at end of file diff --git a/src/main/resources/mapper/KeyboardUserCharacterMapper.xml b/src/main/resources/mapper/KeyboardUserCharacterMapper.xml new file mode 100644 index 0000000..c57e9d0 --- /dev/null +++ b/src/main/resources/mapper/KeyboardUserCharacterMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + id, character_id, deleted, created_at, updated_at, user_id + + \ No newline at end of file