feat(character): 新增用户人设列表接口并支持邮箱登录
- CharacterController 增加 /listByUser 端点,返回当前用户已购人设 - KeyboardCharacterService 新增 selectListByUserId(),通过 Sa-Token 取当前用户 ID - 引入 KeyboardUserCharacter 中间表及对应 Mapper、VO - UserController 增加 /login 端点,支持邮箱+密码登录 - 统一将实体与 VO 的 title 字段更名为 characterName - 补充错误码 USER_NOT_FOUND,调整 Sa-Token 白名单与 Redis 依赖
This commit is contained in:
12
pom.xml
12
pom.xml
@@ -207,6 +207,18 @@
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<version>1.44.0</version>
|
||||
</dependency>
|
||||
<!-- Sa-Token 整合 RedisTemplate -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-template</artifactId>
|
||||
<version>1.44.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 提供 Redis 连接池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 添加Hibernate Validator作为Bean Validation提供程序 -->
|
||||
<dependency>
|
||||
|
||||
@@ -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, "用户不存在");
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<List<KeyboardUserCharacterVO>> userList() {
|
||||
List<KeyboardCharacter> keyboardCharacters = characterService.selectListByUserId();
|
||||
return ResultUtils.success(BeanUtil.copyToList(keyboardCharacters, KeyboardUserCharacterVO.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<KeyboardUserRespVO> login(@RequestBody UserLoginDTO userLoginDTO) {
|
||||
return ResultUtils.success(userService.login(userLoginDTO));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<KeyboardUserCharacter> {
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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="背景描述")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class KeyboardCharacterRespVO {
|
||||
private Long id;
|
||||
|
||||
@Schema(description="标题")
|
||||
private String title;
|
||||
private String characterName;
|
||||
|
||||
|
||||
@Schema(description="背景描述")
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<KeyboardCharacter>{
|
||||
List<KeyboardCharacter> selectListWithRank();
|
||||
|
||||
List<KeyboardCharacter> selectListByTag(Long tagId);
|
||||
|
||||
List<KeyboardCharacter> selectListByUserId();
|
||||
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
KeyboardUser selectUserWithSubjectId(String sub);
|
||||
|
||||
KeyboardUser createUserWithSubjectId(String sub);
|
||||
|
||||
KeyboardUserRespVO login(UserLoginDTO userLoginDTO);
|
||||
}
|
||||
|
||||
@@ -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<KeyboardCharacterM
|
||||
@Resource
|
||||
private KeyboardCharacterMapper keyboardCharacterMapper;
|
||||
|
||||
@Resource
|
||||
private KeyboardUserCharacterMapper keyboardUserCharacterMapper;
|
||||
|
||||
@Override
|
||||
public List<KeyboardCharacter> selectListWithRank() {
|
||||
return keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
|
||||
@@ -35,4 +42,25 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterM
|
||||
.eq(KeyboardCharacter::getTag, tagId)
|
||||
.orderByDesc(KeyboardCharacter::getRank));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KeyboardCharacter> selectListByUserId() {
|
||||
long loginId = StpUtil.getLoginIdAsLong();
|
||||
|
||||
List<KeyboardUserCharacter> keyboardUserCharacters = keyboardUserCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardUserCharacter>()
|
||||
.eq(KeyboardUserCharacter::getDeleted, false)
|
||||
.eq(KeyboardUserCharacter::getUserId, loginId));
|
||||
|
||||
List<Long> characterIds = keyboardUserCharacters.stream()
|
||||
.map(KeyboardUserCharacter::getCharacterId)
|
||||
.toList();
|
||||
if (CollectionUtils.isEmpty(characterIds)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
|
||||
.eq(KeyboardCharacter::getDeleted, false)
|
||||
.in(KeyboardCharacter::getId, characterIds));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<KeyboardUserMapper, KeyboardUse
|
||||
keyboardUserMapper.insert(keyboardUser);
|
||||
return keyboardUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyboardUserRespVO login(UserLoginDTO userLoginDTO) {
|
||||
KeyboardUser keyboardUser = keyboardUserMapper.selectOne(
|
||||
new LambdaQueryWrapper<KeyboardUser>()
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<resultMap id="BaseResultMap" type="com.yolo.keyborad.model.entity.KeyboardCharacter">
|
||||
<!--@Table keyboard_character-->
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="title" jdbcType="VARCHAR" property="title" />
|
||||
<result column="character_name" jdbcType="VARCHAR" property="characterName" />
|
||||
<result column="character_background" jdbcType="VARCHAR" property="characterBackground" />
|
||||
<result column="avatar_url" jdbcType="VARCHAR" property="avatarUrl" />
|
||||
<result column="download" jdbcType="VARCHAR" property="download" />
|
||||
@@ -16,7 +16,7 @@
|
||||
<result column="rank" jdbcType="INTEGER" property="rank" />
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
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"
|
||||
</sql>
|
||||
</mapper>
|
||||
16
src/main/resources/mapper/KeyboardUserCharacterMapper.xml
Normal file
16
src/main/resources/mapper/KeyboardUserCharacterMapper.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.yolo.keyborad.mapper.KeyboardUserCharacterMapper">
|
||||
<resultMap id="BaseResultMap" type="com.yolo.keyborad.model.entity.KeyboardUserCharacter">
|
||||
<!--@Table keyboard_user_character-->
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="character_id" jdbcType="BIGINT" property="characterId" />
|
||||
<result column="deleted" jdbcType="BOOLEAN" property="deleted" />
|
||||
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
|
||||
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
|
||||
<result column="user_id" jdbcType="BIGINT" property="userId" />
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
id, character_id, deleted, created_at, updated_at, user_id
|
||||
</sql>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user