diff --git a/Debate_backend/src/main/java/com/learning/newdemo/controller/DebateHistoryController.java b/Debate_backend/src/main/java/com/learning/newdemo/controller/DebateHistoryController.java new file mode 100644 index 0000000..136aec7 --- /dev/null +++ b/Debate_backend/src/main/java/com/learning/newdemo/controller/DebateHistoryController.java @@ -0,0 +1,58 @@ +package com.learning.newdemo.controller; + +import com.learning.newdemo.common.Result; +import com.learning.newdemo.entity.DebateHistory; +import com.learning.newdemo.service.DebateHistoryService; +import com.learning.newdemo.util.JwtUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 辩论历史记录控制器 + * 处理与辩论历史记录相关的HTTP请求 + */ +@RestController // 标识为RESTful控制器 +@RequestMapping("/api/debate-history") // 基础请求路径 +@RequiredArgsConstructor // Lombok注解,自动生成构造函数注入依赖 +public class DebateHistoryController { + + // 依赖注入 + private final DebateHistoryService historyService; + private final JwtUtil jwtUtil; + + /** + * 保存辩论历史记录接口 + * @param history 前端传来的辩论历史数据(自动反序列化为对象) + * @param token 认证令牌(从请求头获取) + * @return 统一响应结果 + */ + @PostMapping // 处理POST请求 + public Result saveHistory(@RequestBody DebateHistory history, + @RequestHeader("Authorization") String token) { + // 从JWT令牌中解析用户ID + Integer userId = jwtUtil.getUserIdFromToken(token); + // 设置记录关联的用户ID + if (userId == null) { + return Result.error(401, "无效的认证令牌"); + } + history.setUserId(userId); + // 调用服务层保存记录 + historyService.saveDebateHistory(history); + // 返回成功响应 + return Result.success(); + } + + /** + * 获取用户辩论历史记录接口 + * @param token 认证令牌(从请求头获取) + * @return 包含历史记录列表的统一响应结果 + */ + @GetMapping // 处理GET请求 + public Result> getHistories(@RequestHeader("Authorization") String token) { + Integer userId = jwtUtil.getUserIdFromToken(token); + // 调用服务层获取记录并包装返回 + return Result.success(historyService.getHistoriesByUser(userId)); + } +} diff --git a/Debate_backend/src/main/java/com/learning/newdemo/mapper/DebateHistoryMapper.java b/Debate_backend/src/main/java/com/learning/newdemo/mapper/DebateHistoryMapper.java index f78b5bb..a569998 100644 --- a/Debate_backend/src/main/java/com/learning/newdemo/mapper/DebateHistoryMapper.java +++ b/Debate_backend/src/main/java/com/learning/newdemo/mapper/DebateHistoryMapper.java @@ -1,59 +1,95 @@ package com.learning.newdemo.mapper; import com.learning.newdemo.entity.DebateHistory; -import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.*; import java.util.List; +/** + * 辩论历史记录数据访问层接口 + * 定义所有与辩论历史记录表相关的数据库操作 + */ public interface DebateHistoryMapper { + /** - * 插入辩论记录 - * @param debateHistory 辩论记录 - * @return 影响行数 + * 插入新的辩论记录 + * @param debateHistory 包含辩论详细信息的实体对象 + * @return 插入操作影响的行数(通常为1) */ + @Insert("INSERT INTO debate_history(user_id, argument_id, topic, position, total_rounds, debate_content, review_result) " + + "VALUES(#{userId}, #{argumentId}, #{topic}, #{position}, #{totalRounds}, #{debateContent}, #{reviewResult})") + @Options(useGeneratedKeys = true, keyProperty = "id") // 获取自增主键 int insert(DebateHistory debateHistory); /** - * 根据用户ID查询辩论记录 - * @param userId 用户ID - * @return 辩论记录列表 + * 根据用户ID查询所有辩论记录(按时间倒序) + * @param userId 用户唯一标识 + * @return 该用户的所有辩论记录列表 */ + @Select("SELECT * FROM debate_history WHERE user_id = #{userId} ORDER BY create_time DESC") List selectByUserId(@Param("userId") Integer userId); /** - * 根据用户ID查询最新的i条辩论记录 + * 获取用户最新的指定数量的辩论记录 * @param userId 用户ID - * @param limit 记录条数 - * @return 最新的i条辩论记录 + * @param limit 要获取的记录数量 + * @return 最新的辩论记录列表 */ + @Select("SELECT * FROM debate_history WHERE user_id = #{userId} ORDER BY create_time DESC LIMIT #{limit}") List selectLatestByUserId(@Param("userId") Integer userId, @Param("limit") Integer limit); /** - * 根据立论记录ID查询辩论记录 + * 根据关联的立论记录ID查询辩论记录 * @param argumentId 立论记录ID - * @return 辩论记录列表 + * @return 相关联的辩论记录列表 */ + @Select("SELECT * FROM debate_history WHERE argument_id = #{argumentId} ORDER BY create_time DESC") List selectByArgumentId(@Param("argumentId") Integer argumentId); /** - * 根据主键查询辩论记录 - * @param id 主键ID - * @return 辩论记录 + * 根据主键ID查询单条辩论记录 + * @param id 记录主键ID + * @return 对应的辩论记录实体 */ + @Select("SELECT * FROM debate_history WHERE id = #{id}") DebateHistory selectByPrimaryKey(@Param("id") Integer id); /** - * 更新复盘分析内容 - * @param id 辩论记录ID - * @param reviewResult 复盘分析内容 - * @return 影响行数 + * 更新辩论记录的复盘分析内容 + * @param id 要更新的记录ID + * @param reviewResult 新的复盘内容 + * @return 更新操作影响的行数 */ + @Update("UPDATE debate_history SET review_result = #{reviewResult} WHERE id = #{id}") int updateReviewResult(@Param("id") Integer id, @Param("reviewResult") String reviewResult); /** - * 查询辩论记录及其关联的立论内容 + * 查询辩论记录及其关联的立论内容(联合查询) * @param id 辩论记录ID - * @return 包含立论内容的辩论记录 + * @return 包含完整立论内容的辩论记录实体 */ + @Select("SELECT dh.*, ah.topic AS argument_topic, ah.argument_content " + + "FROM debate_history dh LEFT JOIN argument_history ah ON dh.argument_id = ah.id " + + "WHERE dh.id = #{id}") DebateHistory selectWithArgument(@Param("id") Integer id); + + /** + * 清理用户超出限制的历史记录(保留最新的10条) + * @param userId 用户ID + * @return 被删除的记录数量 + */ + @Delete("DELETE FROM debate_history WHERE user_id = #{userId} AND id NOT IN " + + "(SELECT id FROM (SELECT id FROM debate_history WHERE user_id = #{userId} " + + "ORDER BY create_time DESC LIMIT 10) t)") + int cleanOverflowHistories(@Param("userId") Integer userId); + + /** + * 根据辩论主题关键词搜索记录(新增方法) + * @param userId 用户ID + * @param keyword 搜索关键词 + * @return 匹配的记录列表 + */ + @Select("SELECT * FROM debate_history WHERE user_id = #{userId} AND topic LIKE CONCAT('%',#{keyword},'%') " + + "ORDER BY create_time DESC") + List searchByKeyword(@Param("userId") Integer userId, @Param("keyword") String keyword); } diff --git a/Debate_backend/src/main/java/com/learning/newdemo/service/DebateHistoryService.java b/Debate_backend/src/main/java/com/learning/newdemo/service/DebateHistoryService.java new file mode 100644 index 0000000..1e72157 --- /dev/null +++ b/Debate_backend/src/main/java/com/learning/newdemo/service/DebateHistoryService.java @@ -0,0 +1,9 @@ +package com.learning.newdemo.service; + +import com.learning.newdemo.entity.DebateHistory; +import java.util.List; + +public interface DebateHistoryService { + void saveDebateHistory(DebateHistory history); + List getHistoriesByUser(Integer userId); +} diff --git a/Debate_backend/src/main/java/com/learning/newdemo/service/impl/DebateHistoryServiceImpl.java b/Debate_backend/src/main/java/com/learning/newdemo/service/impl/DebateHistoryServiceImpl.java new file mode 100644 index 0000000..2ad2633 --- /dev/null +++ b/Debate_backend/src/main/java/com/learning/newdemo/service/impl/DebateHistoryServiceImpl.java @@ -0,0 +1,31 @@ +// DebateHistoryServiceImpl.java +package com.learning.newdemo.service.impl; + +import com.learning.newdemo.entity.DebateHistory; +import com.learning.newdemo.mapper.DebateHistoryMapper; +import com.learning.newdemo.service.DebateHistoryService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional +public class DebateHistoryServiceImpl implements DebateHistoryService { + + private final DebateHistoryMapper historyMapper; + + @Override + public void saveDebateHistory(DebateHistory history) { + historyMapper.insert(history); + // 清理超出10条的旧记录 + historyMapper.cleanOverflowHistories(history.getUserId()); + } + + @Override + public List getHistoriesByUser(Integer userId) { + return historyMapper.selectLatestByUserId(userId, 10); + } +} diff --git a/Debate_backend/src/main/java/com/learning/newdemo/util/JwtUtil.java b/Debate_backend/src/main/java/com/learning/newdemo/util/JwtUtil.java index a745f68..2efbcaf 100644 --- a/Debate_backend/src/main/java/com/learning/newdemo/util/JwtUtil.java +++ b/Debate_backend/src/main/java/com/learning/newdemo/util/JwtUtil.java @@ -109,4 +109,31 @@ public class JwtUtil { byte[] keyBytes = Decoders.BASE64.decode(secret); return Keys.hmacShaKeyFor(keyBytes); } + /** + * 解析Token并返回Claims对象 + * @param token JWT令牌 + * @return 包含负载信息的Claims对象 + */ + public Claims parseToken(String token) { + // 去除可能的"Bearer "前缀 + if (token != null && token.startsWith("Bearer ")) { + token = token.substring(7); + } + return getClaimsFromToken(token); + } + + /** + * 从token中获取用户ID + * @param token JWT令牌 + * @return 用户ID + */ + public Integer getUserIdFromToken(String token) { + try { + Claims claims = parseToken(token); + return claims.get("userId", Integer.class); + } catch (Exception e) { + return null; + } + } + } \ No newline at end of file diff --git a/Debate_backend/target/classes/com/learning/newdemo/NewDemoApplication.class b/Debate_backend/target/classes/com/learning/newdemo/NewDemoApplication.class index 388ed9d..f79830e 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/NewDemoApplication.class and b/Debate_backend/target/classes/com/learning/newdemo/NewDemoApplication.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/common/Result.class b/Debate_backend/target/classes/com/learning/newdemo/common/Result.class index 17902a3..6b3c970 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/common/Result.class and b/Debate_backend/target/classes/com/learning/newdemo/common/Result.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/config/CorsConfig.class b/Debate_backend/target/classes/com/learning/newdemo/config/CorsConfig.class index 73e11c0..3bbbc45 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/config/CorsConfig.class and b/Debate_backend/target/classes/com/learning/newdemo/config/CorsConfig.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/config/GlobalExceptionHandler.class b/Debate_backend/target/classes/com/learning/newdemo/config/GlobalExceptionHandler.class index da8a936..d8e9c0a 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/config/GlobalExceptionHandler.class and b/Debate_backend/target/classes/com/learning/newdemo/config/GlobalExceptionHandler.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/config/RestTemplateConfig.class b/Debate_backend/target/classes/com/learning/newdemo/config/RestTemplateConfig.class index f96619c..c5af04f 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/config/RestTemplateConfig.class and b/Debate_backend/target/classes/com/learning/newdemo/config/RestTemplateConfig.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/controller/WxAIController.class b/Debate_backend/target/classes/com/learning/newdemo/controller/WxAIController.class index f2d6c40..b136fa9 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/controller/WxAIController.class and b/Debate_backend/target/classes/com/learning/newdemo/controller/WxAIController.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/controller/WxLoginController.class b/Debate_backend/target/classes/com/learning/newdemo/controller/WxLoginController.class index bf1946c..b1f61a2 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/controller/WxLoginController.class and b/Debate_backend/target/classes/com/learning/newdemo/controller/WxLoginController.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/entity/WxUser.class b/Debate_backend/target/classes/com/learning/newdemo/entity/WxUser.class index 2727c47..ee772e0 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/entity/WxUser.class and b/Debate_backend/target/classes/com/learning/newdemo/entity/WxUser.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/mapper/WxUserMapper.class b/Debate_backend/target/classes/com/learning/newdemo/mapper/WxUserMapper.class index a9b6094..fae010a 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/mapper/WxUserMapper.class and b/Debate_backend/target/classes/com/learning/newdemo/mapper/WxUserMapper.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/WxArgumentService.class b/Debate_backend/target/classes/com/learning/newdemo/service/WxArgumentService.class index 27113b1..d8eabf7 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/WxArgumentService.class and b/Debate_backend/target/classes/com/learning/newdemo/service/WxArgumentService.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/WxDebateService.class b/Debate_backend/target/classes/com/learning/newdemo/service/WxDebateService.class index 72c1833..c29f778 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/WxDebateService.class and b/Debate_backend/target/classes/com/learning/newdemo/service/WxDebateService.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/WxReviewService.class b/Debate_backend/target/classes/com/learning/newdemo/service/WxReviewService.class index cee8393..dccd6e5 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/WxReviewService.class and b/Debate_backend/target/classes/com/learning/newdemo/service/WxReviewService.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/WxUserService.class b/Debate_backend/target/classes/com/learning/newdemo/service/WxUserService.class index 7676664..ab1450c 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/WxUserService.class and b/Debate_backend/target/classes/com/learning/newdemo/service/WxUserService.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxArgumentServiceImpl.class b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxArgumentServiceImpl.class index 784723a..32f48a1 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxArgumentServiceImpl.class and b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxArgumentServiceImpl.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxDebateServiceImpl.class b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxDebateServiceImpl.class index 5bb5452..90f4229 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxDebateServiceImpl.class and b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxDebateServiceImpl.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxReviewServiceImpl.class b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxReviewServiceImpl.class index e7d3b41..cbb0627 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxReviewServiceImpl.class and b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxReviewServiceImpl.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxUserServiceImpl.class b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxUserServiceImpl.class index 426cea4..c83f16f 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxUserServiceImpl.class and b/Debate_backend/target/classes/com/learning/newdemo/service/impl/WxUserServiceImpl.class differ diff --git a/Debate_backend/target/classes/com/learning/newdemo/util/JwtUtil.class b/Debate_backend/target/classes/com/learning/newdemo/util/JwtUtil.class index b6c742c..18d189a 100644 Binary files a/Debate_backend/target/classes/com/learning/newdemo/util/JwtUtil.class and b/Debate_backend/target/classes/com/learning/newdemo/util/JwtUtil.class differ diff --git a/database/database.sql b/database/database.sql index 350ac16..fa536e2 100644 --- a/database/database.sql +++ b/database/database.sql @@ -1,6 +1,6 @@ -create database if not exists wx_miniapp default charset utf8mb4; +create database if not exists wx_miniApp default charset utf8mb4; -use wx_miniapp; +use wx_miniApp; CREATE TABLE IF NOT EXISTS `wx_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', @@ -16,4 +16,20 @@ CREATE TABLE IF NOT EXISTS `wx_user` ( `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_openid` (`openid`) COMMENT 'openid唯一索引' -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信用户表'; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信用户表'; + + +-- 在现有database.sql文件末尾添加(不要删除原有内容) +CREATE TABLE IF NOT EXISTS `debate_history` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL COMMENT '关联用户ID', + `topic` varchar(255) NOT NULL COMMENT '辩题', + `stance` enum('正方','反方') NOT NULL COMMENT '持方', + `content` text COMMENT '辩论内容JSON', + `review` text COMMENT 'AI复盘内容', + `rounds` smallint(6) DEFAULT 0 COMMENT '辩论轮数', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `idx_user_time` (`user_id`, `create_time`), + CONSTRAINT `fk_user_history` FOREIGN KEY (`user_id`) REFERENCES `wx_user` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='辩论历史记录表'; diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 0000000..cee4e3d --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,31 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +projectJDK: 17 #(Applied in CI/CD pipeline) + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +#Specify Qodana linter for analysis (Applied in CI/CD pipeline) +linter: jetbrains/qodana-jvm-community:latest