feat(core): 新增人设与标签模块及接口

- 新增 KeyboardCharacter/Tag 实体、Mapper、Service 及 VO
- 新增 CharacterController 与 TagController 提供 /list 接口
- 放开 /character/list、/tag/list 免登录访问
- 补充对应 XML 查询与 .gitignore 忽略 CLAUDE.md
This commit is contained in:
2025-12-03 15:25:59 +08:00
parent 6c7bec8ad3
commit 23dbfb64c4
17 changed files with 404 additions and 3 deletions

3
.gitignore vendored
View File

@@ -31,4 +31,5 @@ build/
!**/src/test/**/build/ !**/src/test/**/build/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
/CLAUDE.md

View File

@@ -66,7 +66,9 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/demo/testSearch", "/demo/testSearch",
"/demo/tsetSearchText", "/demo/tsetSearchText",
"/file/upload", "/file/upload",
"/user/logout" "/user/logout",
"/tag/list",
"/character/list"
}; };
} }
@Bean @Bean

View File

@@ -0,0 +1,40 @@
package com.yolo.keyborad.controller;
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.vo.character.KeyboardCharacterRespVO;
import com.yolo.keyborad.model.vo.tags.TagsRespVO;
import com.yolo.keyborad.service.KeyboardCharacterService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:23
*/
@RestController
@Slf4j
@RequestMapping("/character")
@Tag(name = "人设信息")
public class CharacterController {
@Resource
private KeyboardCharacterService characterService;
@GetMapping("/list")
@Operation(summary = "人设列表", description = "人设列表接口按 rank 排名")
public BaseResponse<List<KeyboardCharacterRespVO>> list() {
List<KeyboardCharacter> list = characterService.selectListWithRank();
return ResultUtils.success(BeanUtil.copyToList(list, KeyboardCharacterRespVO.class));
}
}

View File

@@ -0,0 +1,39 @@
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.KeyboardTag;
import com.yolo.keyborad.model.vo.tags.TagsRespVO;
import com.yolo.keyborad.service.TagService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:10
*/
@RestController
@Slf4j
@RequestMapping("/tag")
@Tag(name = "人设标签")
public class TagController {
@Resource
private TagService tagService;
@GetMapping("/list")
@Operation(summary = "标签列表", description = "标签列表接口")
public BaseResponse<List<TagsRespVO>> list() {
List<KeyboardTag> list = tagService.selectList();
return ResultUtils.success(BeanUtil.copyToList(list, TagsRespVO.class));
}
}

View File

@@ -0,0 +1,12 @@
package com.yolo.keyborad.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yolo.keyborad.model.entity.KeyboardCharacter;
/*
* @author: ziin
* @date: 2025/12/3 14:18
*/
public interface KeyboardCharacterMapper extends BaseMapper<KeyboardCharacter> {
}

View File

@@ -0,0 +1,12 @@
package com.yolo.keyborad.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yolo.keyborad.model.entity.KeyboardTag;
/*
* @author: ziin
* @date: 2025/12/3 14:09
*/
public interface KeyboardTagMapper extends BaseMapper<KeyboardTag> {
}

View File

@@ -0,0 +1,63 @@
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 14:18
*/
@Schema
@Data
@TableName("keyboard_character")
public class KeyboardCharacter {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description="主键 Id")
private Long id;
@TableField(value = "title")
@Schema(description="标题")
private String title;
@TableField(value = "\"character_background\"")
@Schema(description="背景描述")
private String characterBackground;
@TableField(value = "avatar_url")
@Schema(description="角色头像")
private String avatarUrl;
@TableField(value = "download")
@Schema(description="下载次数")
private String download;
@TableField(value = "tag")
@Schema(description="标签id")
private Long tag;
@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 = "prompt")
@Schema(description="人设提示词")
private String prompt;
@TableField(value = "\"rank\"")
@Schema(description="排名顺序")
private Integer rank;
}

View File

@@ -0,0 +1,40 @@
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 14:09
*/
@Schema
@Data
@TableName(value = "keyboard_tag")
public class KeyboardTag {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description="主键 id")
private Integer id;
@TableField(value = "tag_name")
@Schema(description="标签名")
private String tagName;
@TableField(value = "created_at")
@Schema(description="创建时间")
private Date createdAt;
@TableField(value = "updated_at")
@Schema(description="更新时间")
private Date updatedAt;
@TableField(value = "deleted")
@Schema(description="是否删除")
private Boolean deleted;
}

View File

@@ -1,7 +1,6 @@
package com.yolo.keyborad.model.entity; package com.yolo.keyborad.model.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;

View File

@@ -0,0 +1,41 @@
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 14:18
*/
@Schema
@Data
public class KeyboardCharacterRespVO {
@Schema(description="主键 Id")
private Long id;
@Schema(description="标题")
private String title;
@Schema(description="背景描述")
private String characterBackground;
@Schema(description="角色头像")
private String avatarUrl;
@Schema(description="下载次数")
private String download;
@Schema(description="标签id")
private Long tag;
@Schema(description="排名顺序")
private Integer rank;
}

View File

@@ -0,0 +1,26 @@
package com.yolo.keyborad.model.vo.tags;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
/*
* @author: ziin
* @date: 2025/12/3 14:12
*/
@Data
public class TagsRespVO {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description="主键 id")
private Integer id;
@TableField(value = "tag_name")
@Schema(description="标签名")
private String tagName;
}

View File

@@ -0,0 +1,17 @@
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 java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:18
*/
public interface KeyboardCharacterService extends IService<KeyboardCharacter>{
List<KeyboardCharacter> selectListWithRank();
}

View File

@@ -0,0 +1,15 @@
package com.yolo.keyborad.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yolo.keyborad.model.entity.KeyboardTag;
import java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:11
*/
public interface TagService extends IService<KeyboardTag> {
List<KeyboardTag> selectList();
}

View File

@@ -0,0 +1,30 @@
package com.yolo.keyborad.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yolo.keyborad.mapper.KeyboardCharacterMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yolo.keyborad.model.entity.KeyboardCharacter;
import com.yolo.keyborad.service.KeyboardCharacterService;
import java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:18
*/
@Service
public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterMapper, KeyboardCharacter> implements KeyboardCharacterService{
@Resource
private KeyboardCharacterMapper keyboardCharacterMapper;
@Override
public List<KeyboardCharacter> selectListWithRank() {
return keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
.eq(KeyboardCharacter::getDeleted, false)
.orderByDesc(KeyboardCharacter::getRank));
}
}

View File

@@ -0,0 +1,27 @@
package com.yolo.keyborad.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yolo.keyborad.mapper.KeyboardTagMapper;
import com.yolo.keyborad.model.entity.KeyboardTag;
import com.yolo.keyborad.service.TagService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
/*
* @author: ziin
* @date: 2025/12/3 14:12
*/
@Service
public class TagServiceImpl extends ServiceImpl<KeyboardTagMapper, KeyboardTag> implements TagService {
@Resource
private KeyboardTagMapper keyboardTagMapper;
@Override
public List<KeyboardTag> selectList() {
return keyboardTagMapper.selectList(new
QueryWrapper<KeyboardTag>().eq("deleted", false));
}
}

View File

@@ -0,0 +1,22 @@
<?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.KeyboardCharacterMapper">
<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_background" jdbcType="VARCHAR" property="characterBackground" />
<result column="avatar_url" jdbcType="VARCHAR" property="avatarUrl" />
<result column="download" jdbcType="VARCHAR" property="download" />
<result column="tag" jdbcType="BIGINT" property="tag" />
<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="prompt" jdbcType="VARCHAR" property="prompt" />
<result column="rank" jdbcType="INTEGER" property="rank" />
</resultMap>
<sql id="Base_Column_List">
id, title, "character_background", avatar_url, download, tag, deleted, created_at,
updated_at, prompt, "rank"
</sql>
</mapper>

View File

@@ -0,0 +1,15 @@
<?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.KeyboardTagMapper">
<resultMap id="BaseResultMap" type="com.yolo.keyborad.model.entity.KeyboardTag">
<!--@Table keyboard_tag-->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="tag_name" jdbcType="VARCHAR" property="tagName" />
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
<result column="deleted" jdbcType="BOOLEAN" property="deleted" />
</resultMap>
<sql id="Base_Column_List">
id, tag_name, created_at, updated_at, deleted
</sql>
</mapper>