feat(themes): 支持主题标签数组存储与按风格查询
- 新增 StringArrayTypeHandler 实现 PostgreSQL text[] ↔ Java String[] 映射 - 将 theme_tag 字段类型由 VARCHAR 改为 ARRAY,实体与 VO 同步调整为 String[] - 移除废弃的 selectAllThemes 方法,统一使用 selectThemesByStyle(Long) - 9999 风格 ID 保留查询全部上架主题逻辑,其余按风格过滤 - 开放 /themes/listByStyle 接口免鉴权,并修正 theme_status=true 查询条件
This commit is contained in:
@@ -85,7 +85,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
"/character/list",
|
||||
"/user/resetPassWord",
|
||||
"/chat/talk",
|
||||
"/chat/save_embed"
|
||||
"/chat/save_embed",
|
||||
"/themes/listByStyle"
|
||||
};
|
||||
}
|
||||
@Bean
|
||||
|
||||
@@ -30,9 +30,6 @@ public class ThemesController {
|
||||
@Resource
|
||||
private KeyboardThemesService themesService;
|
||||
|
||||
@Resource
|
||||
private KeyboardThemesService keyboardThemesService;
|
||||
|
||||
@Resource
|
||||
private KeyboardThemeStylesService keyboardThemeStylesService;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ 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 com.yolo.keyborad.typehandler.StringArrayTypeHandler;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
@@ -30,9 +31,9 @@ public class KeyboardThemes {
|
||||
@Schema(description="键盘价格")
|
||||
private BigDecimal themePrice;
|
||||
|
||||
@TableField(value = "theme_tag")
|
||||
@TableField(value = "theme_tag", typeHandler = StringArrayTypeHandler.class)
|
||||
@Schema(description="主题标签")
|
||||
private String themeTag;
|
||||
private String[] themeTag;
|
||||
|
||||
@TableField(value = "theme_download")
|
||||
@Schema(description="主题下载次数")
|
||||
|
||||
@@ -34,7 +34,7 @@ public class KeyboardThemesRespVO {
|
||||
* 主题标签
|
||||
*/
|
||||
@Schema(description = "主题标签")
|
||||
private String themeTag;
|
||||
private String[] themeTag;
|
||||
|
||||
/**
|
||||
* 主题下载次数
|
||||
|
||||
@@ -12,12 +12,6 @@ import java.util.List;
|
||||
|
||||
public interface KeyboardThemesService extends IService<KeyboardThemes>{
|
||||
|
||||
/**
|
||||
* 查询所有主题列表(未删除且上架)
|
||||
* @return 主题列表
|
||||
*/
|
||||
List<KeyboardThemesRespVO> selectAllThemes();
|
||||
|
||||
/**
|
||||
* 按主题风格查询主题列表(未删除且上架)
|
||||
* @param themeStyle 主题风格
|
||||
|
||||
@@ -17,27 +17,19 @@ import com.yolo.keyborad.service.KeyboardThemesService;
|
||||
@Service
|
||||
public class KeyboardThemesServiceImpl extends ServiceImpl<KeyboardThemesMapper, KeyboardThemes> implements KeyboardThemesService {
|
||||
|
||||
@Override
|
||||
public List<KeyboardThemesRespVO> selectAllThemes() {
|
||||
List<KeyboardThemes> themesList = this.lambdaQuery()
|
||||
.eq(KeyboardThemes::getDeleted, false)
|
||||
.eq(KeyboardThemes::getThemeStatus, false)
|
||||
.list();
|
||||
return BeanUtil.copyToList(themesList, KeyboardThemesRespVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KeyboardThemesRespVO> selectThemesByStyle(Long themeStyle) {
|
||||
if (themeStyle == 9999) {
|
||||
List<KeyboardThemes> themesList = this.lambdaQuery()
|
||||
.eq(KeyboardThemes::getDeleted, false)
|
||||
.eq(KeyboardThemes::getThemeStatus, false)
|
||||
.eq(KeyboardThemes::getThemeStatus, true)
|
||||
.list();
|
||||
return BeanUtil.copyToList(themesList, KeyboardThemesRespVO.class);
|
||||
}
|
||||
List<KeyboardThemes> themesList = this.lambdaQuery()
|
||||
.eq(KeyboardThemes::getDeleted, false)
|
||||
.eq(KeyboardThemes::getThemeStatus, false)
|
||||
.eq(KeyboardThemes::getThemeStatus, true)
|
||||
.eq(KeyboardThemes::getThemeStyle, themeStyle)
|
||||
.list();
|
||||
return BeanUtil.copyToList(themesList, KeyboardThemesRespVO.class);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.yolo.keyborad.typehandler;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* String数组类型处理器,用于处理PostgreSQL的数组类型
|
||||
* @author: ziin
|
||||
* @date: 2025/12/9
|
||||
*/
|
||||
@MappedTypes({String[].class})
|
||||
@MappedJdbcTypes({JdbcType.ARRAY, JdbcType.VARCHAR})
|
||||
public class StringArrayTypeHandler extends BaseTypeHandler<String[]> {
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException {
|
||||
if (parameter == null || parameter.length == 0) {
|
||||
ps.setNull(i, Types.ARRAY);
|
||||
} else {
|
||||
Connection conn = ps.getConnection();
|
||||
Array array = conn.createArrayOf("text", parameter);
|
||||
ps.setArray(i, array);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
return getArray(rs.getArray(columnName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
return getArray(rs.getArray(columnIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
return getArray(cs.getArray(columnIndex));
|
||||
}
|
||||
|
||||
private String[] getArray(Array array) throws SQLException {
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
Object[] objects = (Object[]) array.getArray();
|
||||
if (objects == null || objects.length == 0) {
|
||||
return new String[0];
|
||||
}
|
||||
String[] result = new String[objects.length];
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
result[i] = objects[i] == null ? null : objects[i].toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,23 @@ spring:
|
||||
username: root
|
||||
password: 123asd
|
||||
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
# 设置 mapper 包的日志级别为 DEBUG,打印 SQL 语句
|
||||
com.yolo.keyborad.mapper: DEBUG
|
||||
# 设置根日志级别
|
||||
root: INFO
|
||||
# Spring 框架日志
|
||||
org.springframework: INFO
|
||||
# MyBatis 日志
|
||||
org.mybatis: DEBUG
|
||||
pattern:
|
||||
# 彩色控制台日志格式
|
||||
# 时间-无颜色,日志级别-根据级别变色,进程ID-品红,线程-黄色,类名-青色,消息-默认色
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} | %clr(%-5level){highlight} %clr(${PID:- }){magenta} | %clr(%-15thread){yellow} %clr(%-50logger{50}){cyan} | %msg%n"
|
||||
|
||||
|
||||
knife4j:
|
||||
enable: true
|
||||
openapi:
|
||||
|
||||
@@ -3,4 +3,28 @@ spring:
|
||||
driver-class-name: org.postgresql.Driver
|
||||
url: jdbc:postgresql://localhost:5432/keyborad_db
|
||||
username: root
|
||||
password: 123asd
|
||||
password: 123asd
|
||||
|
||||
# 生产环境日志配置
|
||||
logging:
|
||||
level:
|
||||
# 生产环境不打印 SQL 日志
|
||||
com.yolo.keyborad.mapper: INFO
|
||||
# 设置根日志级别
|
||||
root: INFO
|
||||
# Spring 框架日志
|
||||
org.springframework: WARN
|
||||
# MyBatis 日志
|
||||
org.mybatis: WARN
|
||||
pattern:
|
||||
# 生产环境控制台日志格式
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} | %clr(%-5level){highlight} %clr(${PID:- }){magenta} | %clr(%-15thread){yellow} %clr(%-50logger{50}){cyan} | %msg%n"
|
||||
# 文件日志格式(无颜色代码)
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} | %-5level ${PID:- } | %-15thread %-50logger{50} | %msg%n"
|
||||
file:
|
||||
# 生产环境日志文件路径
|
||||
name: logs/keyborad-backend.log
|
||||
# 日志文件大小限制
|
||||
max-size: 10MB
|
||||
# 保留的日志文件数量
|
||||
max-history: 30
|
||||
|
||||
@@ -28,6 +28,10 @@ spring:
|
||||
port: 6379
|
||||
host: localhost
|
||||
database: 0
|
||||
# 启用 ANSI 彩色输出
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
|
||||
server:
|
||||
port: 7529
|
||||
@@ -46,6 +50,8 @@ mybatis-plus:
|
||||
logic-delete-field: isDelete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
|
||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||
# 扫描 TypeHandler 包
|
||||
type-handlers-package: com.yolo.keyborad.typehandler
|
||||
|
||||
appid: loveKeyboard
|
||||
appsecret: kZJM39HYvhxwbJkG1fmquQRVkQiLAh2H
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
|
||||
<result column="prompt" jdbcType="VARCHAR" property="prompt" />
|
||||
<result column="rank" jdbcType="INTEGER" property="rank" />
|
||||
<result column="emoji" jdbcType="BOOLEAN" property="emoji" />
|
||||
<result column="emoji" jdbcType="VARCHAR" property="emoji" />
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
id, character_name, "character_background", avatar_url, download, tag, deleted, created_at,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="theme_name" jdbcType="VARCHAR" property="themeName" />
|
||||
<result column="theme_price" jdbcType="NUMERIC" property="themePrice" />
|
||||
<result column="theme_tag" jdbcType="VARCHAR" property="themeTag" />
|
||||
<result column="theme_tag" jdbcType="ARRAY" property="themeTag" typeHandler="com.yolo.keyborad.typehandler.StringArrayTypeHandler" />
|
||||
<result column="theme_download" jdbcType="VARCHAR" property="themeDownload" />
|
||||
<result column="theme_style" jdbcType="BIGINT" property="themeStyle" />
|
||||
<result column="theme_status" jdbcType="BOOLEAN" property="themeStatus" />
|
||||
|
||||
Reference in New Issue
Block a user