From 5227b81acbb23efdbda2ed83e832b6e9cd23de99 Mon Sep 17 00:00:00 2001 From: ziin Date: Wed, 10 Dec 2025 15:55:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(themes):=20=E6=94=AF=E6=8C=81=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E6=A0=87=E7=AD=BE=E6=95=B0=E7=BB=84=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E4=B8=8E=E6=8C=89=E9=A3=8E=E6=A0=BC=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 StringArrayTypeHandler 实现 PostgreSQL text[] ↔ Java String[] 映射 - 将 theme_tag 字段类型由 VARCHAR 改为 ARRAY,实体与 VO 同步调整为 String[] - 移除废弃的 selectAllThemes 方法,统一使用 selectThemesByStyle(Long) - 9999 风格 ID 保留查询全部上架主题逻辑,其余按风格过滤 - 开放 /themes/listByStyle 接口免鉴权,并修正 theme_status=true 查询条件 --- .../keyborad/config/SaTokenConfigure.java | 3 +- .../keyborad/controller/ThemesController.java | 3 - .../keyborad/model/entity/KeyboardThemes.java | 5 +- .../model/vo/themes/KeyboardThemesRespVO.java | 2 +- .../service/KeyboardThemesService.java | 6 -- .../impl/KeyboardThemesServiceImpl.java | 12 +--- .../typehandler/StringArrayTypeHandler.java | 59 +++++++++++++++++++ src/main/resources/application-dev.yml | 18 +++++- src/main/resources/application-prod.yml | 26 +++++++- src/main/resources/application.yml | 6 ++ .../mapper/KeyboardCharacter‌Mapper.xml | 2 +- .../resources/mapper/KeyboardThemesMapper.xml | 2 +- 12 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/yolo/keyborad/typehandler/StringArrayTypeHandler.java diff --git a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java index a1084b1..37c66a7 100644 --- a/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java +++ b/src/main/java/com/yolo/keyborad/config/SaTokenConfigure.java @@ -85,7 +85,8 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/character/list", "/user/resetPassWord", "/chat/talk", - "/chat/save_embed" + "/chat/save_embed", + "/themes/listByStyle" }; } @Bean diff --git a/src/main/java/com/yolo/keyborad/controller/ThemesController.java b/src/main/java/com/yolo/keyborad/controller/ThemesController.java index f949629..c931a26 100644 --- a/src/main/java/com/yolo/keyborad/controller/ThemesController.java +++ b/src/main/java/com/yolo/keyborad/controller/ThemesController.java @@ -30,9 +30,6 @@ public class ThemesController { @Resource private KeyboardThemesService themesService; - @Resource - private KeyboardThemesService keyboardThemesService; - @Resource private KeyboardThemeStylesService keyboardThemeStylesService; diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardThemes.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardThemes.java index 0eb2a7d..9f8cd3b 100644 --- a/src/main/java/com/yolo/keyborad/model/entity/KeyboardThemes.java +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardThemes.java @@ -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="主题下载次数") diff --git a/src/main/java/com/yolo/keyborad/model/vo/themes/KeyboardThemesRespVO.java b/src/main/java/com/yolo/keyborad/model/vo/themes/KeyboardThemesRespVO.java index cf9c5e2..11fe630 100644 --- a/src/main/java/com/yolo/keyborad/model/vo/themes/KeyboardThemesRespVO.java +++ b/src/main/java/com/yolo/keyborad/model/vo/themes/KeyboardThemesRespVO.java @@ -34,7 +34,7 @@ public class KeyboardThemesRespVO { * 主题标签 */ @Schema(description = "主题标签") - private String themeTag; + private String[] themeTag; /** * 主题下载次数 diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardThemesService.java b/src/main/java/com/yolo/keyborad/service/KeyboardThemesService.java index 7636b81..fb697bc 100644 --- a/src/main/java/com/yolo/keyborad/service/KeyboardThemesService.java +++ b/src/main/java/com/yolo/keyborad/service/KeyboardThemesService.java @@ -12,12 +12,6 @@ import java.util.List; public interface KeyboardThemesService extends IService{ - /** - * 查询所有主题列表(未删除且上架) - * @return 主题列表 - */ - List selectAllThemes(); - /** * 按主题风格查询主题列表(未删除且上架) * @param themeStyle 主题风格 diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardThemesServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardThemesServiceImpl.java index 25c9655..e48b189 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/KeyboardThemesServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardThemesServiceImpl.java @@ -17,27 +17,19 @@ import com.yolo.keyborad.service.KeyboardThemesService; @Service public class KeyboardThemesServiceImpl extends ServiceImpl implements KeyboardThemesService { - @Override - public List selectAllThemes() { - List themesList = this.lambdaQuery() - .eq(KeyboardThemes::getDeleted, false) - .eq(KeyboardThemes::getThemeStatus, false) - .list(); - return BeanUtil.copyToList(themesList, KeyboardThemesRespVO.class); - } @Override public List selectThemesByStyle(Long themeStyle) { if (themeStyle == 9999) { List themesList = this.lambdaQuery() .eq(KeyboardThemes::getDeleted, false) - .eq(KeyboardThemes::getThemeStatus, false) + .eq(KeyboardThemes::getThemeStatus, true) .list(); return BeanUtil.copyToList(themesList, KeyboardThemesRespVO.class); } List 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); diff --git a/src/main/java/com/yolo/keyborad/typehandler/StringArrayTypeHandler.java b/src/main/java/com/yolo/keyborad/typehandler/StringArrayTypeHandler.java new file mode 100644 index 0000000..eecba80 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/typehandler/StringArrayTypeHandler.java @@ -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 { + + @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; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index e1298ef..140e733 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -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: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 6a95f3a..d0a1dbe 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -3,4 +3,28 @@ spring: driver-class-name: org.postgresql.Driver url: jdbc:postgresql://localhost:5432/keyborad_db username: root - password: 123asd \ No newline at end of file + 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 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3975393..4948bf6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -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 diff --git a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml index c58f8d4..fc9e2a4 100644 --- a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml +++ b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml @@ -14,7 +14,7 @@ - + id, character_name, "character_background", avatar_url, download, tag, deleted, created_at, diff --git a/src/main/resources/mapper/KeyboardThemesMapper.xml b/src/main/resources/mapper/KeyboardThemesMapper.xml index 2fca6cb..19c3a90 100644 --- a/src/main/resources/mapper/KeyboardThemesMapper.xml +++ b/src/main/resources/mapper/KeyboardThemesMapper.xml @@ -7,7 +7,7 @@ - +