From d1a0018d1b8f5bb0069ea59f371051b89b61ed30 Mon Sep 17 00:00:00 2001 From: Peanut Date: Sat, 23 May 2026 23:27:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=A8=E9=87=8F=20Controller=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=B8=AD=E6=96=87=E6=B3=A8=E8=A7=A3=E8=A1=A5?= =?UTF-8?q?=E5=85=A8=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 39 个 Controller 全部添加 @Tag/@Operation/@Parameter 中文注解(共 278 个 @Operation) - 分 3 批实施:Batch 1 AI+社区(7)、Batch 2 情绪+日记+互动(11)、Batch 3 其他(13) - 已有注解的 8 个 Controller 不重复修改 - 编译验证通过:mvn clean install -DskipTests — BUILD SUCCESS Co-Authored-By: Claude Opus 4.7 --- .../controller/AchievementController.java | 15 +- .../emotion/controller/AiChatController.java | 10 + .../controller/AiRoutingController.java | 35 +- .../controller/AnalyticsController.java | 3 + .../com/emotion/controller/AsrController.java | 7 +- .../controller/ChatWebSocketController.java | 17 +- .../emotion/controller/CommentController.java | 13 +- .../controller/CommunityPostController.java | 13 +- .../controller/ConversationController.java | 22 +- .../controller/CozeApiCallController.java | 26 +- .../controller/DiaryCommentController.java | 49 +- .../controller/DiaryPostController.java | 37 +- .../controller/DictionaryController.java | 35 +- .../controller/EmotionAnalysisController.java | 17 +- .../controller/EmotionRecordController.java | 34 +- .../controller/EmotionSummaryController.java | 6 +- .../controller/EpicScriptController.java | 22 +- .../controller/GrowthTopicController.java | 17 +- .../controller/GuestUserController.java | 15 +- .../emotion/controller/HealthController.java | 7 +- .../controller/LifeEventController.java | 18 +- .../controller/LifePathController.java | 17 +- .../emotion/controller/MessageController.java | 17 +- .../emotion/controller/RewardController.java | 13 +- .../controller/SocialContentController.java | 18 +- .../controller/SocialInsightController.java | 14 +- .../TopicInteractionController.java | 15 +- .../com/emotion/controller/TtsController.java | 18 +- .../controller/UserProfileController.java | 14 +- .../controller/UserStatsController.java | 17 +- .../analytics/AnalyticsPreferenceItem.java | 2 + .../analytics/AnalyticsTopEventItem.java | 6 + .../analytics/AnalyticsTrendItem.java | 1 + ...5-23-all-controller-chinese-annotations.md | 1579 +++++++++++++++++ 34 files changed, 2014 insertions(+), 135 deletions(-) create mode 100644 docs/superpowers/plans/2026-05-23-all-controller-chinese-annotations.md diff --git a/backend-single/src/main/java/com/emotion/controller/AchievementController.java b/backend-single/src/main/java/com/emotion/controller/AchievementController.java index e1abbf8..d886a97 100644 --- a/backend-single/src/main/java/com/emotion/controller/AchievementController.java +++ b/backend-single/src/main/java/com/emotion/controller/AchievementController.java @@ -6,6 +6,7 @@ import com.emotion.dto.request.achievement.*; import com.emotion.dto.response.achievement.AchievementResponse; import com.emotion.service.AchievementService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -16,7 +17,7 @@ import java.util.List; /** * 成就控制器 - * + * * @author huazhongmin * @date 2025-09-08 */ @@ -43,7 +44,7 @@ public class AchievementController { */ @Operation(summary = "根据ID获取成就", description = "根据ID获取成就详情") @GetMapping("/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "成就 ID") @RequestParam String id) { AchievementResponse response = achievementService.getAchievementResponseById(id); if (response == null) { return Result.notFound("成就不存在"); @@ -82,7 +83,7 @@ public class AchievementController { */ @Operation(summary = "删除成就", description = "删除指定成就") @DeleteMapping("/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "成就 ID") @RequestParam String id) { boolean deleted = achievementService.removeById(id); if (!deleted) { return Result.error("删除失败"); @@ -95,7 +96,7 @@ public class AchievementController { */ @Operation(summary = "根据分类查询成就", description = "根据分类查询成就列表") @GetMapping("/byCategory") - public Result> getByCategory(@RequestParam String category) { + public Result> getByCategory(@Parameter(description = "分类") @RequestParam String category) { List responses = achievementService.getByCategoryWithResponse(category); return Result.success(responses); } @@ -105,7 +106,7 @@ public class AchievementController { */ @Operation(summary = "根据稀有度查询成就", description = "根据稀有度查询成就列表") @GetMapping("/byRarity") - public Result> getByRarity(@RequestParam String rarity) { + public Result> getByRarity(@Parameter(description = "稀有度") @RequestParam String rarity) { List responses = achievementService.getByRarityWithResponse(rarity); return Result.success(responses); } @@ -181,8 +182,8 @@ public class AchievementController { */ @Operation(summary = "查询最近解锁的成就", description = "查询最近解锁的成就列表") @GetMapping("/recent") - public Result> getRecentlyUnlocked(@RequestParam(defaultValue = "10") Integer limit) { + public Result> getRecentlyUnlocked(@Parameter(description = "排名数量限制") @RequestParam(defaultValue = "10") Integer limit) { List responses = achievementService.getRecentlyUnlockedWithResponse(limit); return Result.success(responses); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/AiChatController.java b/backend-single/src/main/java/com/emotion/controller/AiChatController.java index 2513b86..11b69de 100644 --- a/backend-single/src/main/java/com/emotion/controller/AiChatController.java +++ b/backend-single/src/main/java/com/emotion/controller/AiChatController.java @@ -15,6 +15,8 @@ import com.emotion.dto.response.GuestUserInfoResponse; import com.emotion.dto.response.ConversationResponse; import com.emotion.service.AiChatService; import com.emotion.util.UserContextUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -31,6 +33,7 @@ import javax.validation.Valid; @Slf4j @RestController @RequestMapping("/ai") +@Tag(name = "AI 聊天", description = "AI 智能对话聊天接口,支持普通聊天、总结、状态查询、访客模式等") public class AiChatController { @Autowired @@ -39,6 +42,7 @@ public class AiChatController { /** * 发送聊天消息 */ + @Operation(summary = "发送 AI 聊天消息", description = "向 AI 发送聊天消息,返回 AI 回复。支持指定会话 ID 和用户 ID。") @PostMapping("/chat") public Result sendChatMessage(@Valid @RequestBody AiChatRequest request) { log.info("收到AI聊天请求: conversationId={}, userId={}, message={}", @@ -52,6 +56,7 @@ public class AiChatController { /** * 生成对话总结 */ + @Operation(summary = "获取 AI 聊天总结", description = "获取指定会话的 AI 聊天总结,概括对话要点。") @PostMapping("/summary") public Result generateSummary(@Valid @RequestBody AiSummaryRequest request) { log.info("收到对话总结请求: conversationId={}, userId={}", request.getConversationId(), request.getUserId()); @@ -64,6 +69,7 @@ public class AiChatController { /** * 获取AI服务状态 */ + @Operation(summary = "获取 AI 状态", description = "获取当前 AI 服务的运行状态信息。") @GetMapping("/status") public Result getServiceStatus() { log.info("获取AI服务状态"); @@ -75,6 +81,7 @@ public class AiChatController { /** * 获取聊天记录统计 */ + @Operation(summary = "获取聊天统计数据", description = "获取指定时间范围内的聊天统计数据,包括消息数、Token 消耗等。") @GetMapping("/stats") public Result getChatStats(@Valid ChatStatsRequest request) { log.info("获取聊天统计: userId={}, conversationId={}", request.getUserId(), request.getConversationId()); @@ -86,6 +93,7 @@ public class AiChatController { /** * 访客聊天(不需要登录) */ + @Operation(summary = "访客模式聊天", description = "未登录用户通过访客模式与 AI 进行对话,无需 token 认证。") @PostMapping("/guestChat") public Result guestChat(@Valid @RequestBody GuestChatRequest request, HttpServletRequest httpRequest) { @@ -99,6 +107,7 @@ public class AiChatController { /** * 获取访客用户信息 */ + @Operation(summary = "获取访客用户信息", description = "根据访客 ID 获取对应的用户信息。") @GetMapping("/guestUserInfo") public Result getGuestUserInfo(HttpServletRequest request) { String clientIp = UserContextUtils.getClientIpAddress(request); @@ -111,6 +120,7 @@ public class AiChatController { /** * 创建对话 */ + @Operation(summary = "创建对话会话", description = "为当前用户创建一个新的 AI 对话会话。") @PostMapping("/createConversation") public Result createConversation(@Valid @RequestBody ConversationCreateRequest request, HttpServletRequest httpRequest) { diff --git a/backend-single/src/main/java/com/emotion/controller/AiRoutingController.java b/backend-single/src/main/java/com/emotion/controller/AiRoutingController.java index 28eef15..4ec9bc1 100644 --- a/backend-single/src/main/java/com/emotion/controller/AiRoutingController.java +++ b/backend-single/src/main/java/com/emotion/controller/AiRoutingController.java @@ -16,6 +16,9 @@ import com.emotion.service.AiProviderService; import com.emotion.service.AiRuntimeService; import com.emotion.service.AiSceneBindingService; import com.emotion.util.UserContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -35,6 +38,7 @@ import java.util.concurrent.CompletableFuture; @Slf4j @RestController @RequestMapping("/ai") +@Tag(name = "AI 路由管理", description = "AI 服务提供商路由管理接口,包括 Provider/Endpoint/Scene 的 CRUD、调用日志、运行时测试和流式测试") public class AiRoutingController { private final AiProviderService providerService; @@ -55,63 +59,75 @@ public class AiRoutingController { this.runtimeService = runtimeService; } + @Operation(summary = "查询 Provider 列表", description = "查询所有可见的 AI Provider 列表。") @GetMapping("/providers") public Result> providers() { return Result.success(providerService.listVisible()); } + @Operation(summary = "创建 Provider", description = "创建一个新的 AI Provider 配置。") @PostMapping("/providers") public Result createProvider(@RequestBody AiProvider provider) { return Result.success(providerService.saveProvider(provider)); } + @Operation(summary = "更新 Provider", description = "更新已有的 AI Provider 配置。") @PutMapping("/providers") public Result updateProvider(@RequestBody AiProvider provider) { return Result.success(providerService.updateProvider(provider)); } + @Operation(summary = "删除 Provider", description = "根据 ID 删除指定的 AI Provider 配置。") @DeleteMapping("/providers") - public Result deleteProvider(@RequestParam String id) { + public Result deleteProvider(@Parameter(description = "Provider ID", required = true) @RequestParam String id) { providerService.removeById(id); return Result.success(); } + @Operation(summary = "查询 Endpoint 列表", description = "查询所有可见的 AI Endpoint 配置列表。") @GetMapping("/endpoints") public Result> endpoints() { return Result.success(endpointConfigService.listVisible()); } + @Operation(summary = "获取 Endpoint 测试模板", description = "根据 Endpoint ID 获取对应的测试模板。") @GetMapping("/endpoints/test-template") - public Result endpointTestTemplate(@RequestParam String id) { + public Result endpointTestTemplate(@Parameter(description = "Endpoint ID", required = true) @RequestParam String id) { return Result.success(runtimeService.buildEndpointTestTemplate(id)); } + @Operation(summary = "创建 Endpoint", description = "创建一个新的 AI Endpoint 配置。") @PostMapping("/endpoints") public Result createEndpoint(@RequestBody AiEndpointConfig endpoint) { return Result.success(endpointConfigService.saveEndpoint(endpoint)); } + @Operation(summary = "更新 Endpoint", description = "更新已有的 AI Endpoint 配置。") @PutMapping("/endpoints") public Result updateEndpoint(@RequestBody AiEndpointConfig endpoint) { return Result.success(endpointConfigService.updateEndpoint(endpoint)); } + @Operation(summary = "删除 Endpoint", description = "根据 ID 删除指定的 AI Endpoint 配置。") @DeleteMapping("/endpoints") - public Result deleteEndpoint(@RequestParam String id) { + public Result deleteEndpoint(@Parameter(description = "Endpoint ID", required = true) @RequestParam String id) { endpointConfigService.removeById(id); return Result.success(); } + @Operation(summary = "查询 Scene 列表", description = "查询所有可见的 AI Scene 绑定配置列表。") @GetMapping("/scenes") public Result> scenes() { return Result.success(sceneBindingService.listVisible()); } + @Operation(summary = "获取 Scene 测试模板", description = "根据场景编码获取对应的测试模板。") @GetMapping("/scenes/test-template") - public Result sceneTestTemplate(@RequestParam String sceneCode) { + public Result sceneTestTemplate(@Parameter(description = "场景编码", required = true) @RequestParam String sceneCode) { return Result.success(runtimeService.buildSceneTestTemplate(sceneCode)); } + @Operation(summary = "创建 Scene", description = "创建一个新的 AI Scene 绑定配置。") @PostMapping("/scenes") public Result createScene(@RequestBody AiSceneBinding scene) { if (scene.getIsEnabled() == null) { @@ -124,29 +140,34 @@ public class AiRoutingController { return Result.success(scene); } + @Operation(summary = "更新 Scene", description = "更新已有的 AI Scene 绑定配置。") @PutMapping("/scenes") public Result updateScene(@RequestBody AiSceneBinding scene) { sceneBindingService.updateById(scene); return Result.success(sceneBindingService.getById(scene.getId())); } + @Operation(summary = "删除 Scene", description = "根据 ID 删除指定的 AI Scene 绑定配置。") @DeleteMapping("/scenes") - public Result deleteScene(@RequestParam String id) { + public Result deleteScene(@Parameter(description = "Scene ID", required = true) @RequestParam String id) { sceneBindingService.removeById(id); return Result.success(); } + @Operation(summary = "查询调用日志", description = "查询 AI 调用日志列表,支持限制返回数量。") @GetMapping("/call-logs") - public Result> callLogs(@RequestParam(required = false) Integer limit) { + public Result> callLogs(@Parameter(description = "返回数量限制") @RequestParam(required = false) Integer limit) { return Result.success(callLogService.latest(limit)); } + @Operation(summary = "运行时测试", description = "对指定的 AI 配置进行运行时连通性测试,支持同步和流式模式。") @PostMapping("/runtime/test") public Result runtimeTest(@RequestBody JSONObject payload) { AiRuntimeRequest request = withCurrentUser(AiRuntimeRequest.fromPayload(payload)); return Result.success(runtimeService.test(request)); } + @Operation(summary = "流式运行时测试", description = "对指定的 AI 配置进行流式运行时连通性测试,以 SSE 事件流返回结果。") @PostMapping("/runtime/stream") public SseEmitter runtimeStream(@RequestBody JSONObject payload) { AiRuntimeRequest request = withCurrentUser(AiRuntimeRequest.fromPayload(payload)); @@ -162,6 +183,7 @@ public class AiRoutingController { return emitter; } + @Operation(summary = "Endpoint 运行时测试", description = "对指定的 Endpoint 进行运行时连通性测试。") @PostMapping("/endpoint/test") public Result endpointTest(@RequestBody JSONObject payload) { String endpointId = payload.getString("endpointId"); @@ -170,6 +192,7 @@ public class AiRoutingController { return Result.success(runtimeService.testEndpoint(endpointId, inputMap)); } + @Operation(summary = "Endpoint 流式测试", description = "对指定的 Endpoint 进行流式运行时测试,以 SSE 事件流返回结果。") @PostMapping("/endpoint/stream") public SseEmitter endpointStream(@RequestBody JSONObject payload) { String endpointId = payload.getString("endpointId"); diff --git a/backend-single/src/main/java/com/emotion/controller/AnalyticsController.java b/backend-single/src/main/java/com/emotion/controller/AnalyticsController.java index ac6c199..d9479d2 100644 --- a/backend-single/src/main/java/com/emotion/controller/AnalyticsController.java +++ b/backend-single/src/main/java/com/emotion/controller/AnalyticsController.java @@ -6,6 +6,8 @@ import com.emotion.dto.response.analytics.AnalyticsBatchResponse; import com.emotion.service.AnalyticsService; import com.emotion.util.JwtUtil; import com.emotion.util.UserContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; @@ -18,6 +20,7 @@ import javax.validation.Valid; @RestController @RequestMapping("/analytics") +@Tag(name = "事件分析", description = "前端行为事件上报和分析接口") public class AnalyticsController { @Autowired diff --git a/backend-single/src/main/java/com/emotion/controller/AsrController.java b/backend-single/src/main/java/com/emotion/controller/AsrController.java index 7334a5f..4f341a5 100644 --- a/backend-single/src/main/java/com/emotion/controller/AsrController.java +++ b/backend-single/src/main/java/com/emotion/controller/AsrController.java @@ -4,6 +4,9 @@ import com.emotion.common.Result; import com.emotion.dto.response.asr.AsrTranscribeResponse; import com.emotion.service.AsrService; import com.emotion.util.UserContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; @@ -12,6 +15,7 @@ import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/asr") +@Tag(name = "语音识别(ASR)", description = "语音转文字识别接口") public class AsrController { private final AsrService asrService; @@ -20,8 +24,9 @@ public class AsrController { this.asrService = asrService; } + @Operation(summary = "语音转文字", description = "上传音频文件并将其转换为文字内容。") @PostMapping("/transcribe") - public Result transcribe(@RequestPart("file") MultipartFile file) { + public Result transcribe(@Parameter(description = "音频文件") @RequestPart("file") MultipartFile file) { if (UserContextHolder.getCurrentUserId() == null) { return Result.unauthorized(); } diff --git a/backend-single/src/main/java/com/emotion/controller/ChatWebSocketController.java b/backend-single/src/main/java/com/emotion/controller/ChatWebSocketController.java index d9a64a5..c3a0055 100644 --- a/backend-single/src/main/java/com/emotion/controller/ChatWebSocketController.java +++ b/backend-single/src/main/java/com/emotion/controller/ChatWebSocketController.java @@ -3,6 +3,8 @@ package com.emotion.controller; import com.emotion.dto.request.WebSocketRequest; import com.emotion.dto.websocket.ConnectRequest; import com.emotion.service.WebSocketService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.MessageMapping; @@ -16,13 +18,14 @@ import java.security.Principal; /** * WebSocket聊天控制器 * 使用规范的请求对象封装参数,符合项目开发规则 - * + * * @author huazhongmin * @date 2025-09-08 */ @Slf4j @Controller @MessageMapping("/chat") +@Tag(name = "WebSocket 聊天", description = "基于 WebSocket 的实时 AI 聊天通信接口") public class ChatWebSocketController { @Autowired @@ -30,11 +33,12 @@ public class ChatWebSocketController { /** * 处理聊天消息 - * + * * @param webSocketRequest WebSocket请求对象 * @param headerAccessor 消息头访问器 * @param principal 用户主体 */ + @Operation(summary = "发送聊天消息", description = "向 AI 发送聊天消息,触发流式响应。") @MessageMapping("/send") public void handleChatMessage(@Valid @Payload WebSocketRequest webSocketRequest, SimpMessageHeaderAccessor headerAccessor, @@ -45,11 +49,12 @@ public class ChatWebSocketController { /** * 处理用户连接 - * + * * @param connectRequest 连接请求对象 * @param headerAccessor 消息头访问器 * @param principal 用户主体 */ + @Operation(summary = "用户连接", description = "处理用户 WebSocket 连接建立。") @MessageMapping("/connect") public void connectUser(@Payload ConnectRequest connectRequest, SimpMessageHeaderAccessor headerAccessor, @@ -60,10 +65,11 @@ public class ChatWebSocketController { /** * 处理用户断开连接 - * + * * @param headerAccessor 消息头访问器 * @param principal 用户主体 */ + @Operation(summary = "用户断开连接", description = "处理用户 WebSocket 连接断开。") @MessageMapping("/disconnect") public void disconnectUser(SimpMessageHeaderAccessor headerAccessor, Principal principal) { String sessionId = headerAccessor.getSessionId(); @@ -72,10 +78,11 @@ public class ChatWebSocketController { /** * 处理心跳消息 - * + * * @param headerAccessor 消息头访问器 * @param principal 用户主体 */ + @Operation(summary = "心跳检测", description = "处理客户端心跳消息,保持 WebSocket 连接活跃。") @MessageMapping("/heartbeat") public void heartbeat(SimpMessageHeaderAccessor headerAccessor, Principal principal) { String sessionId = headerAccessor.getSessionId(); diff --git a/backend-single/src/main/java/com/emotion/controller/CommentController.java b/backend-single/src/main/java/com/emotion/controller/CommentController.java index 2ccb7d8..4e67226 100644 --- a/backend-single/src/main/java/com/emotion/controller/CommentController.java +++ b/backend-single/src/main/java/com/emotion/controller/CommentController.java @@ -8,6 +8,9 @@ import com.emotion.dto.request.comment.CommentPageRequest; import com.emotion.dto.response.comment.CommentResponse; import com.emotion.service.CommentService; import com.emotion.util.UserContextUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,6 +23,7 @@ import org.springframework.web.bind.annotation.*; */ @RestController @RequestMapping("/comment") +@Tag(name = "评论管理", description = "评论的查询、创建、更新和删除接口") public class CommentController { @Autowired @@ -28,6 +32,7 @@ public class CommentController { /** * 分页查询评论 */ + @Operation(summary = "分页查询评论", description = "根据条件分页查询评论列表。") @GetMapping(value = "/page") public Result> getCommentPage(@Validated CommentPageRequest request) { PageResult pageResult = commentService.getPage(request); @@ -37,6 +42,7 @@ public class CommentController { /** * 创建评论 */ + @Operation(summary = "创建评论", description = "对指定目标发表一条新评论。") @PostMapping(value = "/create") public Result createComment(@RequestBody @Validated CommentCreateRequest request) { // 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID @@ -51,6 +57,7 @@ public class CommentController { /** * 更新评论 */ + @Operation(summary = "更新评论", description = "修改已有评论的内容。") @PutMapping(value = "/update") public Result updateComment(@RequestBody @Validated CommentUpdateRequest request) { CommentResponse response = commentService.update(request); @@ -60,8 +67,9 @@ public class CommentController { /** * 删除评论 */ + @Operation(summary = "删除评论", description = "删除指定的评论。") @DeleteMapping(value = "/delete") - public Result deleteComment(@RequestParam String id) { + public Result deleteComment(@Parameter(description = "评论 ID", required = true) @RequestParam String id) { boolean deleted = commentService.delete(id); if (!deleted) { return Result.error("删除失败"); @@ -72,8 +80,9 @@ public class CommentController { /** * 根据ID获取评论 */ + @Operation(summary = "获取评论详情", description = "根据 ID 获取评论的详细信息。") @GetMapping(value = "/detail") - public Result getCommentById(@RequestParam String id) { + public Result getCommentById(@Parameter(description = "评论 ID", required = true) @RequestParam String id) { CommentResponse response = commentService.getById(id); if (response == null) { return Result.notFound("评论不存在"); diff --git a/backend-single/src/main/java/com/emotion/controller/CommunityPostController.java b/backend-single/src/main/java/com/emotion/controller/CommunityPostController.java index d3e127a..55e715d 100644 --- a/backend-single/src/main/java/com/emotion/controller/CommunityPostController.java +++ b/backend-single/src/main/java/com/emotion/controller/CommunityPostController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.community.CommunityPostUpdateRequest; import com.emotion.dto.request.community.CommunityPostPageRequest; import com.emotion.dto.response.community.CommunityPostResponse; import com.emotion.service.CommunityPostService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,6 +22,7 @@ import org.springframework.web.bind.annotation.*; */ @RestController @RequestMapping("/communityPost") +@Tag(name = "社区帖子管理", description = "社区帖子的查询、创建、更新和删除接口") public class CommunityPostController { @Autowired @@ -27,6 +31,7 @@ public class CommunityPostController { /** * 分页查询帖子 */ + @Operation(summary = "分页查询社区帖子", description = "根据条件分页查询社区帖子列表。") @GetMapping(value = "/page") public Result> getPage(@Validated CommunityPostPageRequest request) { PageResult pageResult = communityPostService.getPage(request); @@ -36,8 +41,9 @@ public class CommunityPostController { /** * 根据ID获取帖子 */ + @Operation(summary = "获取帖子详情", description = "根据 ID 获取社区帖子的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "帖子 ID", required = true) @RequestParam String id) { CommunityPostResponse response = communityPostService.getById(id); if (response == null) { return Result.notFound("帖子不存在"); @@ -48,6 +54,7 @@ public class CommunityPostController { /** * 创建帖子 */ + @Operation(summary = "创建社区帖子", description = "发布一篇新的社区帖子。") @PostMapping(value = "/create") public Result create(@RequestBody @Validated CommunityPostCreateRequest request) { CommunityPostResponse response = communityPostService.create(request); @@ -57,6 +64,7 @@ public class CommunityPostController { /** * 更新帖子 */ + @Operation(summary = "更新社区帖子", description = "修改已有的社区帖子内容。") @PutMapping(value = "/update") public Result update(@RequestBody @Validated CommunityPostUpdateRequest request) { CommunityPostResponse response = communityPostService.update(request); @@ -66,8 +74,9 @@ public class CommunityPostController { /** * 删除帖子 */ + @Operation(summary = "删除社区帖子", description = "删除指定的社区帖子。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "帖子 ID", required = true) @RequestParam String id) { boolean deleted = communityPostService.delete(id); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/controller/ConversationController.java b/backend-single/src/main/java/com/emotion/controller/ConversationController.java index 68839fe..bc5e3a3 100644 --- a/backend-single/src/main/java/com/emotion/controller/ConversationController.java +++ b/backend-single/src/main/java/com/emotion/controller/ConversationController.java @@ -6,6 +6,9 @@ import com.emotion.dto.request.ConversationCreateRequest; import com.emotion.dto.request.ConversationPageRequest; import com.emotion.dto.response.ConversationResponse; import com.emotion.service.ConversationService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -15,12 +18,13 @@ import java.util.List; /** * 对话控制器 - * + * * @author huazhongmin * @date 2025-07-23 */ @RestController @RequestMapping("/conversation") +@Tag(name = "会话管理", description = "AI 对话会话的查询、创建、更新、删除和状态管理接口") public class ConversationController { @Autowired @@ -29,6 +33,7 @@ public class ConversationController { /** * 分页查询对话 */ + @Operation(summary = "分页查询会话", description = "分页查询当前用户的对话会话列表。") @GetMapping(value = "/page") public Result> getPage(@Valid ConversationPageRequest request) { PageResult pageResult = conversationService.getPageWithResponse(request); @@ -38,8 +43,9 @@ public class ConversationController { /** * 根据ID获取对话 */ + @Operation(summary = "获取会话详情", description = "根据 ID 获取会话的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "会话 ID") @RequestParam String id) { ConversationResponse response = conversationService.getConversationResponseById(id); if (response == null) { return Result.notFound("对话不存在"); @@ -50,6 +56,7 @@ public class ConversationController { /** * 创建对话 */ + @Operation(summary = "创建会话", description = "创建一个新的 AI 对话会话。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody ConversationCreateRequest request, HttpServletRequest httpRequest) { @@ -60,6 +67,7 @@ public class ConversationController { /** * 更新对话 */ + @Operation(summary = "更新会话", description = "修改已有会话的标题等属性。") @PutMapping(value = "/update") public Result update(@RequestBody ConversationCreateRequest request) { ConversationResponse response = conversationService.updateConversationWithResponse(request); @@ -69,8 +77,9 @@ public class ConversationController { /** * 删除对话 */ + @Operation(summary = "删除会话", description = "删除指定的对话会话。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "会话 ID") @RequestParam String id) { boolean deleted = conversationService.removeById(id); if (!deleted) { return Result.error("删除失败"); @@ -81,6 +90,7 @@ public class ConversationController { /** * 获取活跃对话 */ + @Operation(summary = "获取活跃会话", description = "获取当前用户最近的活跃会话列表。") @GetMapping(value = "/active") public Result> getActiveConversations() { List responses = conversationService.getActiveConversationsWithResponse(); @@ -90,6 +100,7 @@ public class ConversationController { /** * 获取归档对话 */ + @Operation(summary = "获取归档会话", description = "获取当前用户已归档的会话列表。") @GetMapping(value = "/archived") public Result> getArchivedConversations() { List responses = conversationService.getArchivedConversationsWithResponse(); @@ -99,9 +110,10 @@ public class ConversationController { /** * 更新对话状态 */ + @Operation(summary = "获取会话状态", description = "获取指定会话的当前状态信息。") @PutMapping(value = "/status") public Result updateConversationStatus( - @RequestParam String id, + @Parameter(description = "会话 ID") @RequestParam String id, @RequestParam String status) { boolean updated = conversationService.updateConversationStatus(id, status); if (!updated) { @@ -109,4 +121,4 @@ public class ConversationController { } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/CozeApiCallController.java b/backend-single/src/main/java/com/emotion/controller/CozeApiCallController.java index fdc85dc..07b6b6c 100644 --- a/backend-single/src/main/java/com/emotion/controller/CozeApiCallController.java +++ b/backend-single/src/main/java/com/emotion/controller/CozeApiCallController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.coze.CozeApiCallCreateRequest; import com.emotion.dto.request.coze.CozeApiCallUpdateRequest; import com.emotion.dto.response.coze.CozeApiCallResponse; import com.emotion.service.CozeApiCallService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,6 +24,7 @@ import java.math.BigDecimal; */ @RestController @RequestMapping("/coze-api-call") +@Tag(name = "Coze API 调用记录", description = "Coze API 调用记录的查询、创建、更新和删除接口") public class CozeApiCallController { @Autowired @@ -29,6 +33,7 @@ public class CozeApiCallController { /** * 分页查询API调用记录 */ + @Operation(summary = "分页查询调用记录", description = "根据条件分页查询 Coze API 调用记录。") @GetMapping(value = "/page") public Result> getCozeApiCallPage(@Validated CozeApiCallPageRequest request) { PageResult pageResult = cozeApiCallService.getPage(request); @@ -38,8 +43,9 @@ public class CozeApiCallController { /** * 根据ID获取API调用记录 */ + @Operation(summary = "获取调用记录详情", description = "根据 ID 获取单条调用记录的详细信息。") @GetMapping(value = "/detail") - public Result getCozeApiCallById(@RequestParam String id) { + public Result getCozeApiCallById(@Parameter(description = "调用记录 ID", required = true) @RequestParam String id) { CozeApiCallResponse response = cozeApiCallService.getById(id); if (response == null) { return Result.notFound("API调用记录不存在"); @@ -50,6 +56,7 @@ public class CozeApiCallController { /** * 创建API调用记录 */ + @Operation(summary = "创建调用记录", description = "新增一条 Coze API 调用记录。") @PostMapping(value = "/create") public Result createCozeApiCall(@RequestBody @Validated CozeApiCallCreateRequest request) { CozeApiCallResponse response = cozeApiCallService.create(request); @@ -59,6 +66,7 @@ public class CozeApiCallController { /** * 更新API调用记录 */ + @Operation(summary = "更新调用记录", description = "更新已有的 Coze API 调用记录。") @PutMapping(value = "/update") public Result updateCozeApiCall(@RequestBody @Validated CozeApiCallUpdateRequest request) { CozeApiCallResponse response = cozeApiCallService.update(request); @@ -71,8 +79,9 @@ public class CozeApiCallController { /** * 删除API调用记录 */ + @Operation(summary = "删除调用记录", description = "删除指定的 Coze API 调用记录。") @DeleteMapping(value = "/delete") - public Result deleteCozeApiCall(@RequestParam String id) { + public Result deleteCozeApiCall(@Parameter(description = "调用记录 ID", required = true) @RequestParam String id) { boolean deleted = cozeApiCallService.delete(id); if (!deleted) { return Result.error("删除失败"); @@ -83,8 +92,9 @@ public class CozeApiCallController { /** * 统计用户的API调用次数 */ + @Operation(summary = "按用户统计调用量", description = "统计指定用户在时间范围内的 Coze API 调用次数。") @GetMapping(value = "/countByUser") - public Result countByUserId(@RequestParam String userId) { + public Result countByUserId(@Parameter(description = "用户 ID", required = true) @RequestParam String userId) { Long count = cozeApiCallService.countByUserId(userId); return Result.success(count); } @@ -92,8 +102,9 @@ public class CozeApiCallController { /** * 统计Bot的API调用次数 */ + @Operation(summary = "按 Bot 统计调用量", description = "统计指定 Bot 的 Coze API 调用次数。") @GetMapping(value = "/countByBot") - public Result countByBotId(@RequestParam String botId) { + public Result countByBotId(@Parameter(description = "Bot ID", required = true) @RequestParam String botId) { Long count = cozeApiCallService.countByBotId(botId); return Result.success(count); } @@ -101,6 +112,7 @@ public class CozeApiCallController { /** * 统计指定状态的API调用次数 */ + @Operation(summary = "按状态统计调用量", description = "按调用状态统计 Coze API 调用次数。") @GetMapping(value = "/countByStatus") public Result countByStatus(@RequestParam String status) { Long count = cozeApiCallService.countByStatus(status); @@ -110,8 +122,9 @@ public class CozeApiCallController { /** * 统计用户的Token使用量 */ + @Operation(summary = "按用户统计 Token 消耗", description = "统计指定用户的 Token 总消耗量。") @GetMapping(value = "/tokensByUser") - public Result sumTokensByUserId(@RequestParam String userId) { + public Result sumTokensByUserId(@Parameter(description = "用户 ID", required = true) @RequestParam String userId) { Long totalTokens = cozeApiCallService.sumTokensByUserId(userId); return Result.success(totalTokens); } @@ -119,8 +132,9 @@ public class CozeApiCallController { /** * 统计用户的API调用费用 */ + @Operation(summary = "按用户统计费用", description = "统计指定用户的 API 调用总费用。") @GetMapping(value = "/costByUser") - public Result sumCostByUserId(@RequestParam String userId) { + public Result sumCostByUserId(@Parameter(description = "用户 ID", required = true) @RequestParam String userId) { BigDecimal totalCost = cozeApiCallService.sumCostByUserId(userId); return Result.success(totalCost); } diff --git a/backend-single/src/main/java/com/emotion/controller/DiaryCommentController.java b/backend-single/src/main/java/com/emotion/controller/DiaryCommentController.java index c20b0bf..e3158f2 100644 --- a/backend-single/src/main/java/com/emotion/controller/DiaryCommentController.java +++ b/backend-single/src/main/java/com/emotion/controller/DiaryCommentController.java @@ -8,6 +8,9 @@ import com.emotion.dto.response.DiaryCommentResponse; import com.emotion.service.DiaryCommentService; import com.emotion.service.DiaryPostService; import com.emotion.util.UserContextUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -23,6 +26,7 @@ import java.util.List; */ @RestController @RequestMapping("/diaryComment") +@Tag(name = "日记评论管理", description = "日记评论的查询、创建、更新、删除、点赞、置顶等接口") public class DiaryCommentController { @Autowired @@ -34,6 +38,7 @@ public class DiaryCommentController { /** * 分页查询评论 */ + @Operation(summary = "分页查询评论", description = "分页查询指定日记的评论列表。") @GetMapping(value = "/page") public Result> getPage(@Validated DiaryCommentPageRequest request) { PageResult pageResult = diaryCommentService.getPageWithResponse(request); @@ -43,8 +48,9 @@ public class DiaryCommentController { /** * 获取评论树结构 */ + @Operation(summary = "获取评论树", description = "以树形结构获取日记的评论及其回复列表。") @GetMapping(value = "/commentTree") - public Result> getCommentTree(@RequestParam String diaryId) { + public Result> getCommentTree(@Parameter(description = "日记 ID") @RequestParam String diaryId) { List responses = diaryCommentService.getCommentTreeWithResponse(diaryId); return Result.success(responses); } @@ -52,8 +58,9 @@ public class DiaryCommentController { /** * 根据ID获取评论详情 */ + @Operation(summary = "获取评论详情", description = "根据 ID 获取评论详情。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "评论 ID") @RequestParam String id) { DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id); if (response == null) { return Result.notFound("评论不存在"); @@ -64,6 +71,7 @@ public class DiaryCommentController { /** * 创建评论 */ + @Operation(summary = "创建评论", description = "对指定日记发表一条新评论或回复。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody DiaryCommentCreateRequest request) { // 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID @@ -72,17 +80,18 @@ public class DiaryCommentController { request.setUserId(currentUserId); } DiaryCommentResponse response = diaryCommentService.createCommentWithResponse(request); - + // 更新日记的评论数 diaryPostService.incrementCommentCount(request.getDiaryId()); diaryPostService.updateLastCommentTime(request.getDiaryId()); - + return Result.success(response); } /** * 更新评论 */ + @Operation(summary = "更新评论", description = "修改已有评论的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody DiaryCommentCreateRequest request) { DiaryCommentResponse response = diaryCommentService.updateCommentWithResponse(request); @@ -92,65 +101,69 @@ public class DiaryCommentController { /** * 删除评论 */ + @Operation(summary = "删除评论", description = "永久删除指定评论。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "评论 ID") @RequestParam String id) { boolean deleted = diaryCommentService.deleteComment(id); if (!deleted) { return Result.error("删除失败"); } - + // 更新日记的评论数 DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id); if (response != null) { diaryPostService.decrementCommentCount(response.getDiaryId()); } - + return Result.success(); } /** * 软删除评论 */ + @Operation(summary = "软删除评论", description = "将评论标记为已删除状态。") @DeleteMapping(value = "/softDelete") - public Result softDelete(@RequestParam String id) { + public Result softDelete(@Parameter(description = "评论 ID") @RequestParam String id) { boolean deleted = diaryCommentService.softDeleteComment(id); if (!deleted) { return Result.error("删除失败"); } - + // 更新日记的评论数 DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id); if (response != null) { diaryPostService.decrementCommentCount(response.getDiaryId()); } - + return Result.success(); } /** * 恢复评论 */ + @Operation(summary = "恢复评论", description = "恢复已软删除的评论。") @PutMapping(value = "/restore") - public Result restore(@RequestParam String id) { + public Result restore(@Parameter(description = "评论 ID") @RequestParam String id) { boolean restored = diaryCommentService.restoreComment(id); if (!restored) { return Result.error("恢复失败"); } - + // 更新日记的评论数 DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id); if (response != null) { diaryPostService.incrementCommentCount(response.getDiaryId()); } - + return Result.success(); } /** * 点赞评论 */ + @Operation(summary = "点赞评论", description = "对指定评论进行点赞。") @PostMapping(value = "/like") - public Result like(@RequestParam String id) { + public Result like(@Parameter(description = "评论 ID") @RequestParam String id) { boolean liked = diaryCommentService.incrementLikeCount(id); if (!liked) { return Result.error("点赞失败"); @@ -161,8 +174,9 @@ public class DiaryCommentController { /** * 取消点赞评论 */ + @Operation(summary = "取消点赞评论", description = "取消对指定评论的点赞。") @DeleteMapping(value = "/unlike") - public Result unlike(@RequestParam String id) { + public Result unlike(@Parameter(description = "评论 ID") @RequestParam String id) { boolean unliked = diaryCommentService.decrementLikeCount(id); if (!unliked) { return Result.error("取消点赞失败"); @@ -173,12 +187,13 @@ public class DiaryCommentController { /** * 设置置顶状态 */ + @Operation(summary = "置顶评论", description = "将指定评论设为置顶显示。") @PutMapping(value = "/setTop") - public Result setTop(@RequestParam String id, @RequestParam Integer isTop) { + public Result setTop(@Parameter(description = "评论 ID") @RequestParam String id, @RequestParam Integer isTop) { boolean set = diaryCommentService.setTop(id, isTop); if (!set) { return Result.error("设置置顶状态失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/DiaryPostController.java b/backend-single/src/main/java/com/emotion/controller/DiaryPostController.java index baa6b03..edced57 100644 --- a/backend-single/src/main/java/com/emotion/controller/DiaryPostController.java +++ b/backend-single/src/main/java/com/emotion/controller/DiaryPostController.java @@ -8,6 +8,9 @@ import com.emotion.dto.request.DiaryPostUpdateRequest; import com.emotion.dto.response.DiaryPostResponse; import com.emotion.service.DiaryPostService; import com.emotion.util.UserContextUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,6 +25,7 @@ import javax.validation.Valid; */ @RestController @RequestMapping("/diaryPost") +@Tag(name = "日记管理", description = "用户日记帖子的查询、创建、发布、更新、删除、点赞、分享等接口") public class DiaryPostController { @Autowired @@ -30,6 +34,7 @@ public class DiaryPostController { /** * 分页查询日记 */ + @Operation(summary = "分页查询日记", description = "根据条件分页查询当前用户的日记帖子列表。") @GetMapping(value = "/page") public Result> getPage(@Validated DiaryPostPageRequest request) { return Result.success(diaryPostService.getPageWithResponse(request)); @@ -38,8 +43,9 @@ public class DiaryPostController { /** * 根据ID获取日记详情 */ + @Operation(summary = "获取日记详情", description = "根据 ID 获取日记帖子的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "日记 ID") @RequestParam String id) { DiaryPostResponse response = diaryPostService.getDiaryPostResponseById(id); if (response == null) { return Result.notFound("日记不存在"); @@ -50,6 +56,7 @@ public class DiaryPostController { /** * 创建日记 */ + @Operation(summary = "创建日记", description = "创建一篇新的日记帖子。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody DiaryPostCreateRequest request) { // 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID @@ -63,6 +70,7 @@ public class DiaryPostController { /** * 发表日记并生成AI评论 */ + @Operation(summary = "发布日记", description = "将草稿状态的日记帖子发布为正式内容。") @PostMapping(value = "/publish") public Result publish(@Valid @RequestBody DiaryPostCreateRequest request) { // 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID @@ -76,6 +84,7 @@ public class DiaryPostController { /** * 更新日记 */ + @Operation(summary = "更新日记", description = "修改已有日记帖子的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody DiaryPostUpdateRequest request) { DiaryPostResponse response = diaryPostService.updateDiaryPostWithResponse(request); @@ -88,8 +97,9 @@ public class DiaryPostController { /** * 删除日记 */ + @Operation(summary = "删除日记", description = "永久删除指定的日记帖子。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "日记 ID") @RequestParam String id) { boolean deleted = diaryPostService.deleteDiaryPost(id); if (!deleted) { return Result.error("删除失败"); @@ -100,8 +110,9 @@ public class DiaryPostController { /** * 软删除日记 */ + @Operation(summary = "软删除日记", description = "将日记帖子标记为已删除状态(可恢复)。") @DeleteMapping(value = "/softDelete") - public Result softDelete(@RequestParam String id) { + public Result softDelete(@Parameter(description = "日记 ID") @RequestParam String id) { boolean deleted = diaryPostService.softDeleteDiaryPost(id); if (!deleted) { return Result.error("删除失败"); @@ -112,8 +123,9 @@ public class DiaryPostController { /** * 恢复日记 */ + @Operation(summary = "恢复日记", description = "将已软删除的日记帖子恢复为正常状态。") @PutMapping(value = "/restore") - public Result restore(@RequestParam String id) { + public Result restore(@Parameter(description = "日记 ID") @RequestParam String id) { boolean restored = diaryPostService.restoreDiaryPost(id); if (!restored) { return Result.error("恢复失败"); @@ -124,8 +136,9 @@ public class DiaryPostController { /** * 点赞日记 */ + @Operation(summary = "点赞日记", description = "对指定日记帖子进行点赞操作。") @PostMapping(value = "/like") - public Result like(@RequestParam String id) { + public Result like(@Parameter(description = "日记 ID") @RequestParam String id) { boolean liked = diaryPostService.incrementLikeCount(id); if (!liked) { return Result.error("点赞失败"); @@ -136,8 +149,9 @@ public class DiaryPostController { /** * 取消点赞日记 */ + @Operation(summary = "取消点赞日记", description = "取消对指定日记帖子的点赞。") @DeleteMapping(value = "/unlike") - public Result unlike(@RequestParam String id) { + public Result unlike(@Parameter(description = "日记 ID") @RequestParam String id) { boolean unliked = diaryPostService.decrementLikeCount(id); if (!unliked) { return Result.error("取消点赞失败"); @@ -148,8 +162,9 @@ public class DiaryPostController { /** * 分享日记 */ + @Operation(summary = "分享日记", description = "将指定日记帖子分享给其他用户。") @PostMapping(value = "/share") - public Result share(@RequestParam String id) { + public Result share(@Parameter(description = "日记 ID") @RequestParam String id) { boolean shared = diaryPostService.incrementShareCount(id); if (!shared) { return Result.error("分享失败"); @@ -160,8 +175,9 @@ public class DiaryPostController { /** * 设置精选状态 */ + @Operation(summary = "设置精选日记", description = "将指定日记帖子标记为精选内容。") @PutMapping(value = "/setFeatured") - public Result setFeatured(@RequestParam String id, @RequestParam Integer featured) { + public Result setFeatured(@Parameter(description = "日记 ID") @RequestParam String id, @RequestParam Integer featured) { boolean set = diaryPostService.setFeatured(id, featured); if (!set) { return Result.error("设置精选状态失败"); @@ -172,12 +188,13 @@ public class DiaryPostController { /** * 设置置顶优先级 */ + @Operation(summary = "设置日记优先级", description = "修改指定日记帖子的优先级排序。") @PutMapping(value = "/setPriority") - public Result setPriority(@RequestParam String id, @RequestParam Integer priority) { + public Result setPriority(@Parameter(description = "日记 ID") @RequestParam String id, @RequestParam Integer priority) { boolean set = diaryPostService.setPriority(id, priority); if (!set) { return Result.error("设置优先级失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/DictionaryController.java b/backend-single/src/main/java/com/emotion/controller/DictionaryController.java index 5c5c83f..3c9f633 100644 --- a/backend-single/src/main/java/com/emotion/controller/DictionaryController.java +++ b/backend-single/src/main/java/com/emotion/controller/DictionaryController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.dictionary.DictionaryUpdateRequest; import com.emotion.dto.response.dictionary.DictionaryResponse; import com.emotion.common.PageResult; import com.emotion.common.Result; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -15,12 +18,13 @@ import java.util.List; /** * 字典Controller - * + * * @author huazhongmin * @date 2025-12-22 */ @RestController @RequestMapping("/dictionary") +@Tag(name = "字典管理", description = "数据字典的查询、创建、更新和删除接口") public class DictionaryController { @Autowired @@ -28,10 +32,11 @@ public class DictionaryController { /** * 创建字典 - * + * * @param request 创建请求 * @return 创建结果 */ + @Operation(summary = "创建字典项", description = "创建一个新的数据字典项。") @PostMapping public Result createDictionary(@Validated @RequestBody DictionaryCreateRequest request) { return dictionaryService.createDictionary(request); @@ -39,10 +44,11 @@ public class DictionaryController { /** * 更新字典 - * + * * @param request 更新请求 * @return 更新结果 */ + @Operation(summary = "更新字典项", description = "修改已有数据字典项的内容。") @PutMapping public Result updateDictionary(@Validated @RequestBody DictionaryUpdateRequest request) { return dictionaryService.updateDictionary(request); @@ -50,32 +56,35 @@ public class DictionaryController { /** * 删除字典 - * + * * @param id 字典ID * @return 删除结果 */ + @Operation(summary = "删除字典项", description = "删除指定的数据字典项。") @DeleteMapping("/delete") - public Result deleteDictionary(@RequestParam String id) { + public Result deleteDictionary(@Parameter(description = "字典 ID") @RequestParam String id) { return dictionaryService.deleteDictionary(id); } /** * 获取字典详情 - * + * * @param id 字典ID * @return 字典详情 */ + @Operation(summary = "获取字典详情", description = "根据 ID 获取字典项的详细信息。") @GetMapping("/detail") - public Result getDictionary(@RequestParam String id) { + public Result getDictionary(@Parameter(description = "字典 ID") @RequestParam String id) { return dictionaryService.getDictionary(id); } /** * 分页查询字典 - * + * * @param request 分页请求 * @return 分页结果 */ + @Operation(summary = "分页查询字典", description = "分页查询数据字典列表。") @GetMapping("/list") public Result> listDictionaries(DictionaryPageRequest request) { return dictionaryService.listDictionaries(request); @@ -83,23 +92,25 @@ public class DictionaryController { /** * 根据字典类型查询字典集合 - * + * * @param dictType 字典类型 * @return 字典集合 */ + @Operation(summary = "根据类型查询字典", description = "根据字典类型查询字典集合。") @GetMapping("/byType") - public Result> getDictionariesByType(@RequestParam String dictType) { + public Result> getDictionariesByType(@Parameter(description = "字典类型") @RequestParam String dictType) { return dictionaryService.getDictionariesByType(dictType); } /** * 根据字典类型查询启用的字典集合 - * + * * @param dictType 字典类型 * @return 启用的字典集合 */ + @Operation(summary = "查询启用的字典", description = "根据字典类型查询启用的字典集合。") @GetMapping("/enabledByType") - public Result> getEnabledDictionariesByType(@RequestParam String dictType) { + public Result> getEnabledDictionariesByType(@Parameter(description = "字典类型") @RequestParam String dictType) { return dictionaryService.getEnabledDictionariesByType(dictType); } } \ No newline at end of file diff --git a/backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java b/backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java index f519dfb..ee58445 100644 --- a/backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java +++ b/backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.EmotionAnalysisPageRequest; import com.emotion.dto.request.EmotionAnalysisUpdateRequest; import com.emotion.dto.response.EmotionAnalysisResponse; import com.emotion.service.EmotionAnalysisService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -16,12 +19,13 @@ import java.util.List; /** * 情绪分析控制器 - * + * * @author huazhongmin * @date 2025-07-23 */ @RestController @RequestMapping("/emotionAnalysis") +@Tag(name = "情绪分析管理", description = "情绪分析记录的查询、创建、更新和删除接口") public class EmotionAnalysisController { @Autowired @@ -30,6 +34,7 @@ public class EmotionAnalysisController { /** * 分页查询情绪分析记录 */ + @Operation(summary = "分页查询情绪分析", description = "根据条件分页查询情绪分析记录列表。") @GetMapping(value = "/page") public Result> getPage(@Validated EmotionAnalysisPageRequest request) { return Result.success(emotionAnalysisService.getPageWithResponse(request)); @@ -38,8 +43,9 @@ public class EmotionAnalysisController { /** * 根据ID获取情绪分析记录 */ + @Operation(summary = "获取分析详情", description = "根据 ID 获取情绪分析报告的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "分析 ID") @RequestParam String id) { EmotionAnalysisResponse response = emotionAnalysisService.getEmotionAnalysisResponseById(id); if (response == null) { return Result.notFound("情绪分析记录不存在"); @@ -50,6 +56,7 @@ public class EmotionAnalysisController { /** * 创建情绪分析记录 */ + @Operation(summary = "创建情绪分析", description = "基于情绪记录数据创建一条新的 AI 情绪分析报告。") @PostMapping(value = "/create") public Result create(@RequestBody @Valid EmotionAnalysisCreateRequest request) { return Result.success(emotionAnalysisService.createEmotionAnalysisWithResponse(request)); @@ -58,6 +65,7 @@ public class EmotionAnalysisController { /** * 更新情绪分析记录 */ + @Operation(summary = "更新情绪分析", description = "修改已有情绪分析报告的内容。") @PutMapping(value = "/update") public Result update(@RequestBody @Valid EmotionAnalysisUpdateRequest request) { EmotionAnalysisResponse response = emotionAnalysisService.updateEmotionAnalysisWithResponse(request); @@ -70,12 +78,13 @@ public class EmotionAnalysisController { /** * 删除情绪分析记录 */ + @Operation(summary = "删除情绪分析", description = "删除指定的情绪分析记录。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "分析 ID") @RequestParam String id) { boolean deleted = emotionAnalysisService.deleteEmotionAnalysis(id); if (!deleted) { return Result.error("删除失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/EmotionRecordController.java b/backend-single/src/main/java/com/emotion/controller/EmotionRecordController.java index 20d1350..a94b37e 100644 --- a/backend-single/src/main/java/com/emotion/controller/EmotionRecordController.java +++ b/backend-single/src/main/java/com/emotion/controller/EmotionRecordController.java @@ -8,6 +8,9 @@ import com.emotion.dto.request.EmotionRecordUpdateRequest; import com.emotion.dto.response.EmotionRecordResponse; import com.emotion.service.EmotionRecordService; import com.emotion.util.UserContextUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +29,7 @@ import java.util.Map; */ @RestController @RequestMapping("/emotionRecord") +@Tag(name = "情绪记录管理", description = "用户情绪记录的查询、创建、更新、删除和统计接口") public class EmotionRecordController { private static final Logger log = LoggerFactory.getLogger(EmotionRecordController.class); @@ -36,14 +40,15 @@ public class EmotionRecordController { /** * 创建情绪记录 */ + @Operation(summary = "创建情绪记录", description = "记录用户当天的情绪数据,包括类型、强度、触发因素等。") @PostMapping(value = "/create") public Result createRecord(@RequestBody @Valid EmotionRecordCreateRequest request) { log.info("创建情绪记录: userId={}", request.getUserId()); - + // 从上下文中获取当前用户ID String userId = UserContextUtils.requireCurrentUserId(); request.setUserId(userId); - + EmotionRecordResponse response = emotionRecordService.createEmotionRecordWithResponse(request); return Result.success("创建成功", response); } @@ -51,6 +56,7 @@ public class EmotionRecordController { /** * 分页查询情绪记录 */ + @Operation(summary = "分页查询情绪记录", description = "根据日期范围、情绪类型等条件分页查询情绪记录。") @GetMapping(value = "/page") public Result> getPage(@Validated EmotionRecordPageRequest request) { // 从上下文中获取当前用户ID @@ -69,10 +75,11 @@ public class EmotionRecordController { /** * 获取情绪记录详情 */ + @Operation(summary = "获取记录详情", description = "根据 ID 获取情绪记录的详细信息。") @GetMapping(value = "/detail") - public Result getRecord(@RequestParam String id) { + public Result getRecord(@Parameter(description = "记录 ID") @RequestParam String id) { log.info("获取情绪记录详情: {}", id); - + EmotionRecordResponse response = emotionRecordService.getEmotionRecordResponseById(id); if (response == null) { return Result.notFound("情绪记录不存在"); @@ -83,10 +90,11 @@ public class EmotionRecordController { /** * 更新情绪记录 */ + @Operation(summary = "更新情绪记录", description = "修改已有情绪记录的内容。") @PutMapping(value = "/update") public Result updateRecord(@RequestBody @Valid EmotionRecordUpdateRequest request) { log.info("更新情绪记录: {}", request.getId()); - + EmotionRecordResponse response = emotionRecordService.updateEmotionRecordWithResponse(request); if (response == null) { return Result.notFound("情绪记录不存在"); @@ -97,10 +105,11 @@ public class EmotionRecordController { /** * 删除情绪记录 */ + @Operation(summary = "删除情绪记录", description = "删除指定的情绪记录。") @DeleteMapping(value = "/delete") - public Result deleteRecord(@RequestParam String id) { + public Result deleteRecord(@Parameter(description = "记录 ID") @RequestParam String id) { log.info("删除情绪记录: {}", id); - + boolean deleted = emotionRecordService.deleteEmotionRecord(id); if (!deleted) { return Result.notFound("情绪记录不存在"); @@ -111,18 +120,19 @@ public class EmotionRecordController { /** * 获取情绪统计 */ + @Operation(summary = "获取情绪统计", description = "统计指定时间范围内的情绪数据分布。") @GetMapping(value = "/stats") public Result> getEmotionStats( @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) { - + // 从上下文中获取当前用户ID String userId = UserContextUtils.requireCurrentUserId(); - + log.info("获取情绪统计: userId={}, startDate={}, endDate={}", userId, startDate, endDate); - + Map stats = emotionRecordService.getEmotionStats(userId, startDate, endDate); - + return Result.success(stats); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/EmotionSummaryController.java b/backend-single/src/main/java/com/emotion/controller/EmotionSummaryController.java index a0f34ec..3f23ec2 100644 --- a/backend-single/src/main/java/com/emotion/controller/EmotionSummaryController.java +++ b/backend-single/src/main/java/com/emotion/controller/EmotionSummaryController.java @@ -34,7 +34,7 @@ public class EmotionSummaryController { /** * 生成用户当天的情绪记录总结 */ - @Operation(summary = "生成用户当天的情绪记录总结", description = "基于用户当天的聊天记录生成情绪分析和记录") + @Operation(summary = "生成情绪总结", description = "基于指定时间范围的情绪记录数据,生成 AI 情绪总结报告。") @PostMapping(value = "/generate") public Result generateEmotionSummary( @RequestBody @Valid EmotionSummaryGenerateRequest request) { @@ -56,7 +56,7 @@ public class EmotionSummaryController { /** * 获取用户情绪记录总结状态 */ - @Operation(summary = "获取用户情绪记录总结状态", description = "检查用户今天是否已经生成过情绪记录") + @Operation(summary = "查询总结状态", description = "查询指定时间段内是否已生成情绪总结及其状态。") @GetMapping(value = "/status") public Result getEmotionSummaryStatus( @Validated EmotionSummaryStatusRequest request) { @@ -69,4 +69,4 @@ public class EmotionSummaryController { return Result.success(response); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/EpicScriptController.java b/backend-single/src/main/java/com/emotion/controller/EpicScriptController.java index bf5566e..c13c8f3 100644 --- a/backend-single/src/main/java/com/emotion/controller/EpicScriptController.java +++ b/backend-single/src/main/java/com/emotion/controller/EpicScriptController.java @@ -10,6 +10,9 @@ import com.emotion.dto.response.EpicScriptInspirationResponse; import com.emotion.dto.response.EpicScriptResponse; import com.emotion.dto.response.InspirationSuggestionResponse; import com.emotion.service.EpicScriptService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -25,6 +28,7 @@ import java.util.List; */ @RestController @RequestMapping("/epicScript") +@Tag(name = "爽文剧本管理", description = "爽文剧本的查询、创建、更新、删除和灵感推荐接口") public class EpicScriptController { @Autowired @@ -33,6 +37,7 @@ public class EpicScriptController { /** * 分页查询当前用户的爽文剧本 */ + @Operation(summary = "分页查询爽文剧本", description = "分页查询当前用户的爽文剧本列表。") @GetMapping(value = "/page") public Result> getPage(@Validated EpicScriptPageRequest request) { PageResult pageResult = epicScriptService.getPageByCurrentUser(request); @@ -42,23 +47,27 @@ public class EpicScriptController { /** * 获取当前用户的所有爽文剧本列表 */ + @Operation(summary = "获取爽文剧本列表", description = "获取当前用户的所有爽文剧本列表。") @GetMapping(value = "/listAll") public Result> getList() { List scripts = epicScriptService.getListByCurrentUser(); return Result.success(scripts); } + @Operation(summary = "获取灵感推荐", description = "获取系统推荐的灵感建议列表。") @GetMapping(value = "/inspiration/recommendations") public Result> getInspirationRecommendations() { return Result.success(epicScriptService.getInspirationRecommendations()); } + @Operation(summary = "获取随机灵感", description = "随机获取指定数量的灵感建议。") @GetMapping(value = "/inspiration/random") public Result> getRandomInspirations( - @RequestParam(required = false, defaultValue = "3") Integer size) { + @Parameter(description = "灵感数量") @RequestParam(required = false, defaultValue = "3") Integer size) { return Result.success(epicScriptService.getRandomInspirations(size)); } + @Operation(summary = "从灵感生成剧本", description = "基于选定的灵感建议生成爽文剧本。") @PostMapping(value = "/inspiration/generate") public Result generateFromInspiration( @Valid @RequestBody EpicScriptInspirationRequest request) { @@ -77,8 +86,9 @@ public class EpicScriptController { /** * 根据ID获取爽文剧本详情 */ + @Operation(summary = "获取剧本详情", description = "根据 ID 获取爽文剧本的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "剧本 ID") @RequestParam String id) { EpicScriptResponse script = epicScriptService.getScriptById(id); if (script == null) { return Result.notFound("爽文剧本不存在"); @@ -89,6 +99,7 @@ public class EpicScriptController { /** * 创建爽文剧本 */ + @Operation(summary = "创建爽文剧本", description = "创建一个新的爽文剧本。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody EpicScriptCreateRequest request) { EpicScriptResponse script = epicScriptService.createScript(request); @@ -101,6 +112,7 @@ public class EpicScriptController { /** * 更新爽文剧本 */ + @Operation(summary = "更新爽文剧本", description = "修改已有爽文剧本的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody EpicScriptUpdateRequest request) { EpicScriptResponse script = epicScriptService.updateScript(request); @@ -113,8 +125,9 @@ public class EpicScriptController { /** * 选中剧本(取消其他选中状态) */ + @Operation(summary = "选中剧本", description = "选中指定剧本并取消其他剧本的选中状态。") @PutMapping(value = "/select") - public Result select(@RequestParam String id) { + public Result select(@Parameter(description = "剧本 ID") @RequestParam String id) { EpicScriptResponse script = epicScriptService.selectScript(id); if (script == null) { return Result.error("选中失败"); @@ -125,8 +138,9 @@ public class EpicScriptController { /** * 删除爽文剧本 */ + @Operation(summary = "删除爽文剧本", description = "删除指定的爽文剧本。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "剧本 ID") @RequestParam String id) { boolean deleted = epicScriptService.deleteScript(id); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/controller/GrowthTopicController.java b/backend-single/src/main/java/com/emotion/controller/GrowthTopicController.java index bdb8da4..83033b5 100644 --- a/backend-single/src/main/java/com/emotion/controller/GrowthTopicController.java +++ b/backend-single/src/main/java/com/emotion/controller/GrowthTopicController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.growth.GrowthTopicPageRequest; import com.emotion.dto.request.growth.GrowthTopicUpdateRequest; import com.emotion.dto.response.growth.GrowthTopicResponse; import com.emotion.service.GrowthTopicService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -15,12 +18,13 @@ import javax.validation.Valid; /** * 成长话题控制器 - * + * * @author huazhongmin * @date 2025-09-08 */ @RestController @RequestMapping("/growthTopic") +@Tag(name = "成长话题管理", description = "成长话题的查询、创建、更新和删除接口") public class GrowthTopicController { @Autowired @@ -29,6 +33,7 @@ public class GrowthTopicController { /** * 分页查询成长话题 */ + @Operation(summary = "分页查询成长话题", description = "分页查询成长话题列表。") @GetMapping(value = "/page") public Result> getPage(@Validated GrowthTopicPageRequest request) { PageResult pageResult = growthTopicService.getPageWithResponse(request); @@ -38,8 +43,9 @@ public class GrowthTopicController { /** * 根据ID获取成长话题 */ + @Operation(summary = "获取话题详情", description = "根据 ID 获取成长话题的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "话题 ID") @RequestParam String id) { GrowthTopicResponse response = growthTopicService.getGrowthTopicResponseById(id); if (response == null) { return Result.notFound("成长话题不存在"); @@ -50,6 +56,7 @@ public class GrowthTopicController { /** * 创建成长话题 */ + @Operation(summary = "创建成长话题", description = "创建一个新的成长话题。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody GrowthTopicCreateRequest request) { GrowthTopicResponse response = growthTopicService.createGrowthTopicWithResponse(request); @@ -59,6 +66,7 @@ public class GrowthTopicController { /** * 更新成长话题 */ + @Operation(summary = "更新成长话题", description = "修改已有成长话题的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody GrowthTopicUpdateRequest request) { GrowthTopicResponse response = growthTopicService.updateGrowthTopicWithResponse(request); @@ -71,12 +79,13 @@ public class GrowthTopicController { /** * 删除成长话题 */ + @Operation(summary = "删除成长话题", description = "删除指定的成长话题。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "话题 ID") @RequestParam String id) { boolean deleted = growthTopicService.deleteGrowthTopic(id); if (!deleted) { return Result.error("删除失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/GuestUserController.java b/backend-single/src/main/java/com/emotion/controller/GuestUserController.java index e90c32a..9ea970f 100644 --- a/backend-single/src/main/java/com/emotion/controller/GuestUserController.java +++ b/backend-single/src/main/java/com/emotion/controller/GuestUserController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.guest.GuestUserPageRequest; import com.emotion.dto.request.guest.GuestUserUpdateRequest; import com.emotion.dto.response.guest.GuestUserResponse; import com.emotion.service.GuestUserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -15,12 +18,13 @@ import javax.validation.Valid; /** * 访客用户控制器 - * + * * @author huazhongmin * @date 2025-09-08 */ @RestController @RequestMapping("/guestUser") +@Tag(name = "访客用户管理", description = "访客用户的查询、创建、更新和删除接口") public class GuestUserController { @Autowired @@ -29,6 +33,7 @@ public class GuestUserController { /** * 分页查询访客用户 */ + @Operation(summary = "分页查询访客用户", description = "分页查询访客用户列表。") @GetMapping(value = "/page") public Result> getPage(@Validated GuestUserPageRequest request) { PageResult pageResult = guestUserService.getPageWithResponse(request); @@ -38,8 +43,9 @@ public class GuestUserController { /** * 根据ID获取访客用户 */ + @Operation(summary = "获取访客详情", description = "根据 ID 获取访客用户的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "访客 ID") @RequestParam String id) { GuestUserResponse response = guestUserService.getGuestUserResponseById(id); if (response == null) { return Result.notFound("访客用户不存在"); @@ -50,6 +56,7 @@ public class GuestUserController { /** * 创建访客用户 */ + @Operation(summary = "创建访客用户", description = "创建一个新的访客用户。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody GuestUserCreateRequest request) { GuestUserResponse response = guestUserService.createGuestUserWithResponse(request); @@ -59,6 +66,7 @@ public class GuestUserController { /** * 更新访客用户 */ + @Operation(summary = "更新访客用户", description = "修改已有访客用户的信息。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody GuestUserUpdateRequest request) { GuestUserResponse response = guestUserService.updateGuestUserWithResponse(request); @@ -71,8 +79,9 @@ public class GuestUserController { /** * 删除访客用户 */ + @Operation(summary = "删除访客用户", description = "删除指定的访客用户。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "访客 ID") @RequestParam String id) { boolean deleted = guestUserService.deleteGuestUser(id); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/controller/HealthController.java b/backend-single/src/main/java/com/emotion/controller/HealthController.java index a431073..d308496 100644 --- a/backend-single/src/main/java/com/emotion/controller/HealthController.java +++ b/backend-single/src/main/java/com/emotion/controller/HealthController.java @@ -2,6 +2,8 @@ package com.emotion.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -11,11 +13,12 @@ import java.util.Map; /** * 健康检查控制器 - * + * * @author huazhongmin * @date 2025-07-23 */ @RestController +@Tag(name = "健康检查", description = "系统健康状态检查接口") public class HealthController { private static final Logger log = LoggerFactory.getLogger(HealthController.class); @@ -23,6 +26,7 @@ public class HealthController { /** * 健康检查 */ + @Operation(summary = "系统健康检查", description = "返回系统各组件的健康状态,包括数据库、Redis 等。") @GetMapping("/health") public Map health() { log.info("健康检查请求"); @@ -40,6 +44,7 @@ public class HealthController { /** * 服务信息 */ + @Operation(summary = "获取服务信息", description = "返回服务的基本信息,包括版本号、构建时间等。") @GetMapping("/health/info") public Map info() { log.info("服务信息请求"); diff --git a/backend-single/src/main/java/com/emotion/controller/LifeEventController.java b/backend-single/src/main/java/com/emotion/controller/LifeEventController.java index fae6738..8d4fa57 100644 --- a/backend-single/src/main/java/com/emotion/controller/LifeEventController.java +++ b/backend-single/src/main/java/com/emotion/controller/LifeEventController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.LifeEventPageRequest; import com.emotion.dto.request.LifeEventUpdateRequest; import com.emotion.dto.response.LifeEventResponse; import com.emotion.service.LifeEventService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,6 +29,7 @@ import java.util.Map; */ @RestController @RequestMapping("/lifeEvent") +@Tag(name = "生命事件管理", description = "生命事件的查询、创建、更新和删除接口") public class LifeEventController { @Autowired @@ -34,6 +38,7 @@ public class LifeEventController { /** * 分页查询当前用户的生命事件 */ + @Operation(summary = "分页查询生命事件", description = "分页查询生命事件列表。") @GetMapping(value = "/page") public Result> getPage(@Validated LifeEventPageRequest request) { PageResult pageResult = lifeEventService.getPageByCurrentUser(request); @@ -43,6 +48,7 @@ public class LifeEventController { /** * 获取当前用户的所有生命事件列表 */ + @Operation(summary = "获取生命事件列表", description = "获取当前用户的所有生命事件列表。") @GetMapping(value = "/list") public Result> getList() { List events = lifeEventService.getListByCurrentUser(); @@ -52,8 +58,9 @@ public class LifeEventController { /** * 根据ID获取生命事件详情 */ + @Operation(summary = "获取生命事件详情", description = "根据 ID 获取生命事件的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "事件 ID") @RequestParam String id) { LifeEventResponse event = lifeEventService.getEventById(id); if (event == null) { return Result.notFound("生命事件不存在"); @@ -64,6 +71,7 @@ public class LifeEventController { /** * 创建生命事件 */ + @Operation(summary = "创建生命事件", description = "创建一个新的生命事件。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody LifeEventCreateRequest request) { LifeEventResponse event = lifeEventService.createEvent(request); @@ -76,6 +84,7 @@ public class LifeEventController { /** * 更新生命事件 */ + @Operation(summary = "更新生命事件", description = "修改已有生命事件的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody LifeEventUpdateRequest request) { LifeEventResponse event = lifeEventService.updateEvent(request); @@ -88,14 +97,16 @@ public class LifeEventController { /** * 删除生命事件 */ + @Operation(summary = "删除生命事件", description = "删除指定的生命事件。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "事件 ID") @RequestParam String id) { boolean deleted = lifeEventService.deleteEvent(id); if (!deleted) { return Result.error("删除失败"); } return Result.success(); } + @Operation(summary = "AI 辅助生成内容", description = "根据标题和内容调用 AI 生成生命事件的解读文本、标签等信息。") @PostMapping(value = "/ai-assist") public Result> aiAssist(@RequestBody Map request) { String title = stringValue(request.get("title"), "这段经历"); @@ -116,6 +127,7 @@ public class LifeEventController { return Result.success(data); } + @Operation(summary = "聊天占位接口", description = "返回聊天功能的占位回复和建议问题。") @PostMapping(value = "/chat-placeholder") public Result> chatPlaceholder(@RequestBody Map request) { String title = stringValue(request.get("title"), "这段经历"); @@ -126,6 +138,7 @@ public class LifeEventController { return Result.success(data); } + @Operation(summary = "分享占位接口", description = "返回分享功能的占位文本和分享信息。") @PostMapping(value = "/share-placeholder") public Result> sharePlaceholder(@RequestBody Map request) { String title = stringValue(request.get("title"), "人生经历"); @@ -137,6 +150,7 @@ public class LifeEventController { return Result.success(data); } + @Operation(summary = "收藏占位接口", description = "返回收藏功能的占位响应。") @PostMapping(value = "/favorite-placeholder") public Result> favoritePlaceholder(@RequestBody Map request) { String id = stringValue(request.get("id"), ""); diff --git a/backend-single/src/main/java/com/emotion/controller/LifePathController.java b/backend-single/src/main/java/com/emotion/controller/LifePathController.java index 0d4d727..4cff8a8 100644 --- a/backend-single/src/main/java/com/emotion/controller/LifePathController.java +++ b/backend-single/src/main/java/com/emotion/controller/LifePathController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.LifePathPageRequest; import com.emotion.dto.request.LifePathUpdateRequest; import com.emotion.dto.response.LifePathResponse; import com.emotion.service.LifePathService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,6 +25,7 @@ import java.util.List; */ @RestController @RequestMapping("/lifePath") +@Tag(name = "实现路径管理", description = "人生剧本实现路径的查询、创建、更新和删除接口") public class LifePathController { @Autowired @@ -30,6 +34,7 @@ public class LifePathController { /** * 分页查询当前用户的实现路径 */ + @Operation(summary = "分页查询实现路径", description = "分页查询当前用户的实现路径列表。") @GetMapping(value = "/page") public Result> getPage(@Validated LifePathPageRequest request) { PageResult pageResult = lifePathService.getPageByCurrentUser(request); @@ -39,6 +44,7 @@ public class LifePathController { /** * 获取当前用户的所有实现路径列表 */ + @Operation(summary = "获取实现路径列表", description = "获取当前用户的所有实现路径列表。") @GetMapping(value = "/listAll") public Result> getList() { List paths = lifePathService.getListByCurrentUser(); @@ -48,8 +54,9 @@ public class LifePathController { /** * 根据剧本ID获取实现路径 */ + @Operation(summary = "根据剧本ID获取路径", description = "根据剧本 ID 获取对应的实现路径。") @GetMapping(value = "/byScript") - public Result getByScriptId(@RequestParam String scriptId) { + public Result getByScriptId(@Parameter(description = "剧本 ID") @RequestParam String scriptId) { LifePathResponse path = lifePathService.getByScriptId(scriptId); if (path == null) { return Result.notFound("实现路径不存在"); @@ -60,8 +67,9 @@ public class LifePathController { /** * 根据ID获取实现路径详情 */ + @Operation(summary = "获取路径详情", description = "根据 ID 获取实现路径的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "路径 ID") @RequestParam String id) { LifePathResponse path = lifePathService.getPathById(id); if (path == null) { return Result.notFound("实现路径不存在"); @@ -72,6 +80,7 @@ public class LifePathController { /** * 创建实现路径 */ + @Operation(summary = "创建实现路径", description = "创建一条新的实现路径。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody LifePathCreateRequest request) { LifePathResponse path = lifePathService.createPath(request); @@ -84,6 +93,7 @@ public class LifePathController { /** * 更新实现路径 */ + @Operation(summary = "更新实现路径", description = "修改已有实现路径的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody LifePathUpdateRequest request) { LifePathResponse path = lifePathService.updatePath(request); @@ -96,8 +106,9 @@ public class LifePathController { /** * 删除实现路径 */ + @Operation(summary = "删除实现路径", description = "删除指定的实现路径。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "路径 ID") @RequestParam String id) { boolean deleted = lifePathService.deletePath(id); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/controller/MessageController.java b/backend-single/src/main/java/com/emotion/controller/MessageController.java index e30ac22..c95c277 100644 --- a/backend-single/src/main/java/com/emotion/controller/MessageController.java +++ b/backend-single/src/main/java/com/emotion/controller/MessageController.java @@ -8,6 +8,9 @@ import com.emotion.dto.request.MessageSearchRequest; import com.emotion.dto.request.MessageRecentRequest; import com.emotion.dto.response.MessageResponse; import com.emotion.service.MessageService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -24,6 +27,7 @@ import javax.validation.Valid; @RestController @RequestMapping("/message") @Slf4j +@Tag(name = "消息管理", description = "会话消息的查询、创建、搜索、更新和删除接口") public class MessageController { @Autowired @@ -32,6 +36,7 @@ public class MessageController { /** * 创建消息 */ + @Operation(summary = "创建消息", description = "在指定会话中创建一条新消息。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody MessageCreateRequest request) { MessageResponse response = messageService.createMessageFromRequest(request); @@ -41,8 +46,9 @@ public class MessageController { /** * 根据ID获取消息 */ + @Operation(summary = "获取消息详情", description = "根据 ID 获取消息的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "消息 ID") @RequestParam String id) { MessageResponse response = messageService.getMessageById(id); if (response == null) { return Result.notFound("消息不存在"); @@ -53,6 +59,7 @@ public class MessageController { /** * 分页查询消息 */ + @Operation(summary = "分页查询消息", description = "分页查询指定会话的消息列表。") @GetMapping(value = "/page") public Result> getPage(@Validated MessagePageRequest request) { PageResult pageResult = messageService.getPageWithResponse(request); @@ -62,6 +69,7 @@ public class MessageController { /** * 搜索消息 */ + @Operation(summary = "搜索消息", description = "根据关键词在指定会话中搜索消息内容。") @PostMapping(value = "/search") public Result> search(@Valid @RequestBody MessageSearchRequest request) { PageResult pageResult = messageService.searchWithResponse(request); @@ -71,6 +79,7 @@ public class MessageController { /** * 获取最近的消息 */ + @Operation(summary = "获取最近消息", description = "获取指定会话最近的消息列表。") @PostMapping(value = "/recent") public Result> getRecentMessages(@Valid @RequestBody MessageRecentRequest request) { PageResult pageResult = messageService.getRecentWithResponse(request); @@ -80,6 +89,7 @@ public class MessageController { /** * 更新消息 */ + @Operation(summary = "更新消息", description = "修改指定消息的内容。") @PutMapping(value = "/update") public Result update(@RequestParam String id, @RequestParam String content) { MessageResponse response = messageService.updateMessage(id, content); @@ -92,12 +102,13 @@ public class MessageController { /** * 删除消息 */ + @Operation(summary = "删除消息", description = "删除指定的消息记录。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "消息 ID") @RequestParam String id) { boolean deleted = messageService.deleteMessage(id); if (!deleted) { return Result.error("删除失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/RewardController.java b/backend-single/src/main/java/com/emotion/controller/RewardController.java index 4aa21fd..7c4daaf 100644 --- a/backend-single/src/main/java/com/emotion/controller/RewardController.java +++ b/backend-single/src/main/java/com/emotion/controller/RewardController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.reward.RewardPageRequest; import com.emotion.dto.request.reward.RewardUpdateRequest; import com.emotion.dto.response.reward.RewardResponse; import com.emotion.service.RewardService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,6 +24,7 @@ import javax.validation.Valid; */ @RestController @RequestMapping("/reward") +@Tag(name = "奖励管理", description = "奖励的查询、创建、更新和删除接口") public class RewardController { @Autowired @@ -29,6 +33,7 @@ public class RewardController { /** * 分页查询奖励 */ + @Operation(summary = "分页查询奖励", description = "分页查询奖励列表。") @GetMapping(value = "/page") public Result> getPage(@Validated RewardPageRequest request) { PageResult pageResult = rewardService.getPageWithResponse(request); @@ -38,8 +43,9 @@ public class RewardController { /** * 根据ID获取奖励 */ + @Operation(summary = "获取奖励详情", description = "根据 ID 获取奖励的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "奖励 ID") @RequestParam String id) { RewardResponse response = rewardService.getRewardResponseById(id); if (response == null) { return Result.notFound("奖励不存在"); @@ -50,6 +56,7 @@ public class RewardController { /** * 创建奖励 */ + @Operation(summary = "创建奖励", description = "创建一个新的奖励。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody RewardCreateRequest request) { RewardResponse response = rewardService.createRewardWithResponse(request); @@ -59,6 +66,7 @@ public class RewardController { /** * 更新奖励 */ + @Operation(summary = "更新奖励", description = "修改已有奖励的信息。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody RewardUpdateRequest request) { RewardResponse response = rewardService.updateRewardWithResponse(request); @@ -71,8 +79,9 @@ public class RewardController { /** * 删除奖励 */ + @Operation(summary = "删除奖励", description = "删除指定的奖励。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "奖励 ID") @RequestParam String id) { boolean deleted = rewardService.deleteReward(id); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/controller/SocialContentController.java b/backend-single/src/main/java/com/emotion/controller/SocialContentController.java index 6ef99a8..da8dc15 100644 --- a/backend-single/src/main/java/com/emotion/controller/SocialContentController.java +++ b/backend-single/src/main/java/com/emotion/controller/SocialContentController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.social.SocialContentManualImportRequest; import com.emotion.dto.response.social.SocialContentItemResponse; import com.emotion.service.SocialContentService; import com.emotion.util.UserContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -27,11 +30,13 @@ import java.util.List; @Validated @RestController @RequestMapping("/social/content") +@Tag(name = "社交内容管理", description = "社交媒体内容的导入、截图、审核等接口") public class SocialContentController { @Autowired private SocialContentService socialContentService; + @Operation(summary = "手动导入社交内容", description = "通过上传文本内容手动导入社交媒体数据。") @PostMapping("/manual") public Result manualImport(@Valid @RequestBody SocialContentManualImportRequest request) { String userId = currentUserId(); @@ -45,6 +50,7 @@ public class SocialContentController { } } + @Operation(summary = "链接导入社交内容", description = "通过社交媒体链接 URL 导入内容。") @PostMapping("/link") public Result linkImport(@Valid @RequestBody SocialContentLinkImportRequest request) { String userId = currentUserId(); @@ -58,8 +64,9 @@ public class SocialContentController { } } + @Operation(summary = "截图导入社交内容", description = "通过上传截图图片来导入社交媒体内容。") @PostMapping("/screenshot") - public Result screenshotImport(@RequestParam String platform, + public Result screenshotImport(@Parameter(description = "平台名称", required = true) @RequestParam String platform, @RequestPart("file") MultipartFile file) { String userId = currentUserId(); if (userId == null) { @@ -72,6 +79,7 @@ public class SocialContentController { } } + @Operation(summary = "获取社交内容列表", description = "查询所有已导入的社交媒体内容列表。") @GetMapping("/list") public Result> list() { String userId = currentUserId(); @@ -81,8 +89,9 @@ public class SocialContentController { return Result.success(socialContentService.listByUser(userId)); } + @Operation(summary = "更新内容审核状态", description = "修改指定社交内容的审核状态(通过/拒绝)。") @PutMapping("/{id}/approval") - public Result updateApproval(@PathVariable String id, + public Result updateApproval(@Parameter(description = "内容 ID", required = true) @PathVariable String id, @RequestBody SocialContentApprovalRequest request) { String userId = currentUserId(); if (userId == null) { @@ -95,9 +104,10 @@ public class SocialContentController { return Result.success(response); } + @Operation(summary = "删除社交内容", description = "删除指定的社交媒体内容记录。") @DeleteMapping("/{id}") - public Result delete(@PathVariable String id, - @RequestParam(required = false, defaultValue = "true") Boolean keepConfirmedInsights) { + public Result delete(@Parameter(description = "内容 ID", required = true) @PathVariable String id, + @Parameter(description = "是否保留已确认的洞察") @RequestParam(required = false, defaultValue = "true") Boolean keepConfirmedInsights) { String userId = currentUserId(); if (userId == null) { return Result.unauthorized(); diff --git a/backend-single/src/main/java/com/emotion/controller/SocialInsightController.java b/backend-single/src/main/java/com/emotion/controller/SocialInsightController.java index e91b36a..0474cff 100644 --- a/backend-single/src/main/java/com/emotion/controller/SocialInsightController.java +++ b/backend-single/src/main/java/com/emotion/controller/SocialInsightController.java @@ -6,6 +6,9 @@ import com.emotion.dto.request.social.SocialInsightUpdateRequest; import com.emotion.dto.response.social.SocialProfileInsightResponse; import com.emotion.service.SocialInsightService; import com.emotion.util.UserContextHolder; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -24,11 +27,13 @@ import java.util.List; @Validated @RestController @RequestMapping("/social/insight") +@Tag(name = "社交洞察管理", description = "社交媒体洞察生成、查询和更新接口") public class SocialInsightController { @Autowired private SocialInsightService socialInsightService; + @Operation(summary = "生成社交洞察", description = "基于用户社交数据生成 AI 分析洞察报告。") @PostMapping("/generate") public Result> generate(@RequestBody(required = false) SocialInsightGenerateRequest request) { String userId = currentUserId(); @@ -38,8 +43,9 @@ public class SocialInsightController { return Result.success(socialInsightService.generateInsights(userId, request)); } + @Operation(summary = "获取洞察列表", description = "查询当前用户的所有社交洞察记录。") @GetMapping("/list") - public Result> list(@RequestParam(required = false) String status) { + public Result> list(@Parameter(description = "洞察状态") @RequestParam(required = false) String status) { String userId = currentUserId(); if (userId == null) { return Result.unauthorized(); @@ -47,8 +53,9 @@ public class SocialInsightController { return Result.success(socialInsightService.listByUser(userId, status)); } + @Operation(summary = "更新洞察记录", description = "更新已有洞察的状态或备注信息。") @PutMapping("/{id}") - public Result update(@PathVariable String id, + public Result update(@Parameter(description = "洞察 ID", required = true) @PathVariable String id, @Valid @RequestBody SocialInsightUpdateRequest request) { String userId = currentUserId(); if (userId == null) { @@ -65,8 +72,9 @@ public class SocialInsightController { } } + @Operation(summary = "删除洞察记录", description = "删除指定的社交洞察记录。") @DeleteMapping("/{id}") - public Result delete(@PathVariable String id) { + public Result delete(@Parameter(description = "洞察 ID", required = true) @PathVariable String id) { String userId = currentUserId(); if (userId == null) { return Result.unauthorized(); diff --git a/backend-single/src/main/java/com/emotion/controller/TopicInteractionController.java b/backend-single/src/main/java/com/emotion/controller/TopicInteractionController.java index d7446c3..494d2c9 100644 --- a/backend-single/src/main/java/com/emotion/controller/TopicInteractionController.java +++ b/backend-single/src/main/java/com/emotion/controller/TopicInteractionController.java @@ -7,6 +7,9 @@ import com.emotion.dto.request.TopicInteractionPageRequest; import com.emotion.dto.request.TopicInteractionUpdateRequest; import com.emotion.dto.response.TopicInteractionResponse; import com.emotion.service.TopicInteractionService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,6 +24,7 @@ import javax.validation.Valid; */ @RestController @RequestMapping("/topicInteraction") +@Tag(name = "话题互动管理", description = "话题互动记录的查询、创建、更新和删除接口") public class TopicInteractionController { @Autowired @@ -29,6 +33,7 @@ public class TopicInteractionController { /** * 分页查询话题互动 */ + @Operation(summary = "分页查询互动记录", description = "分页查询话题互动记录列表。") @GetMapping(value = "/page") public Result> getPage(@Validated TopicInteractionPageRequest request) { PageResult pageResult = topicInteractionService.getPageWithResponse(request); @@ -38,8 +43,9 @@ public class TopicInteractionController { /** * 根据ID获取话题互动 */ + @Operation(summary = "获取互动详情", description = "根据 ID 获取互动记录的详细信息。") @GetMapping(value = "/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "互动 ID") @RequestParam String id) { TopicInteractionResponse response = topicInteractionService.getTopicInteractionResponseById(id); if (response == null) { return Result.notFound("话题互动不存在"); @@ -50,6 +56,7 @@ public class TopicInteractionController { /** * 创建话题互动 */ + @Operation(summary = "创建互动记录", description = "创建一条新的话题互动记录。") @PostMapping(value = "/create") public Result create(@Valid @RequestBody TopicInteractionCreateRequest request) { TopicInteractionResponse response = topicInteractionService.createTopicInteractionWithResponse(request); @@ -59,6 +66,7 @@ public class TopicInteractionController { /** * 更新话题互动 */ + @Operation(summary = "更新互动记录", description = "修改已有话题互动的内容。") @PutMapping(value = "/update") public Result update(@Valid @RequestBody TopicInteractionUpdateRequest request) { TopicInteractionResponse response = topicInteractionService.updateTopicInteractionWithResponse(request); @@ -71,12 +79,13 @@ public class TopicInteractionController { /** * 删除话题互动 */ + @Operation(summary = "删除互动记录", description = "删除指定的话题互动记录。") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "互动 ID") @RequestParam String id) { boolean deleted = topicInteractionService.deleteTopicInteraction(id); if (!deleted) { return Result.error("删除失败"); } return Result.success(); } -} \ No newline at end of file +} diff --git a/backend-single/src/main/java/com/emotion/controller/TtsController.java b/backend-single/src/main/java/com/emotion/controller/TtsController.java index c399f7c..02fefa0 100644 --- a/backend-single/src/main/java/com/emotion/controller/TtsController.java +++ b/backend-single/src/main/java/com/emotion/controller/TtsController.java @@ -4,6 +4,9 @@ import com.emotion.common.Result; import com.emotion.dto.request.tts.TtsTaskCreateRequest; import com.emotion.dto.response.tts.TtsTaskResponse; import com.emotion.service.TtsTaskService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; @@ -25,6 +28,7 @@ import java.util.concurrent.TimeUnit; @RestController @RequestMapping("/tts") +@Tag(name = "语音合成(TTS)", description = "文字转语音任务创建和查询接口") public class TtsController { private final TtsTaskService ttsTaskService; @@ -36,6 +40,7 @@ public class TtsController { this.ttsTaskService = ttsTaskService; } + @Operation(summary = "创建语音合成任务", description = "根据文本内容创建语音合成任务,返回任务信息。") @PostMapping("/tasks") public Result create(@Valid @RequestBody TtsTaskCreateRequest request) { try { @@ -45,21 +50,24 @@ public class TtsController { } } + @Operation(summary = "获取语音合成任务详情", description = "根据任务 ID 获取语音合成任务的详细信息。") @GetMapping("/tasks/{id}") - public Result detail(@PathVariable String id) { + public Result detail(@Parameter(description = "任务 ID") @PathVariable String id) { TtsTaskResponse response = ttsTaskService.getTask(id); return response == null ? Result.notFound("TTS task not found") : Result.success(response); } + @Operation(summary = "根据来源查询语音合成任务", description = "根据来源类型和来源 ID 查询已存在的语音合成任务。") @GetMapping("/tasks/by-source") - public Result bySource(@RequestParam String sourceType, - @RequestParam String sourceId, - @RequestParam(required = false) String voice) { + public Result bySource(@Parameter(description = "来源类型") @RequestParam String sourceType, + @Parameter(description = "来源 ID") @RequestParam String sourceId, + @Parameter(description = "音色") @RequestParam(required = false) String voice) { return Result.success(ttsTaskService.getBySource(sourceType, sourceId, voice)); } + @Operation(summary = "获取音频文件", description = "返回已合成的音频音频文件(MP3 或 WAV 格式)。") @GetMapping("/audio/{filename:.+}") - public ResponseEntity audio(@PathVariable String filename) { + public ResponseEntity audio(@Parameter(description = "音频文件名") @PathVariable String filename) { if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) { return ResponseEntity.badRequest().build(); } diff --git a/backend-single/src/main/java/com/emotion/controller/UserProfileController.java b/backend-single/src/main/java/com/emotion/controller/UserProfileController.java index 76335cd..d766aa3 100644 --- a/backend-single/src/main/java/com/emotion/controller/UserProfileController.java +++ b/backend-single/src/main/java/com/emotion/controller/UserProfileController.java @@ -25,7 +25,7 @@ import java.util.List; */ @RestController @RequestMapping("/user-profile") -@Tag(name = "用户档案管理", description = "用户生命档案的增删改查和查询功能") +@Tag(name = "用户档案管理", description = "用户档案的查询、创建、更新、删除和 AI 设置管理接口") public class UserProfileController { @Autowired @@ -34,6 +34,7 @@ public class UserProfileController { /** * 新增档案 */ + @Operation(summary = "创建用户档案", description = "为当前用户创建个人档案,包含昵称、MBTI 人格类型、童年经历等。") @PostMapping("/create") public Result create(@Valid @RequestBody UserProfileCreateRequest request) { UserProfileResponse response = userProfileService.createProfile(request); @@ -43,8 +44,9 @@ public class UserProfileController { /** * 删除档案 */ + @Operation(summary = "删除用户档案", description = "删除指定的用户档案。") @DeleteMapping("/delete") - public Result delete(@RequestParam String id) { + public Result delete(@Parameter(description = "档案 ID") @RequestParam String id) { boolean success = userProfileService.deleteProfile(id); if (success) { return Result.success(); @@ -56,6 +58,7 @@ public class UserProfileController { /** * 修改档案 */ + @Operation(summary = "更新用户档案", description = "更新当前用户的个人档案信息。") @PutMapping("/update") public Result update(@Valid @RequestBody UserProfileUpdateRequest request) { UserProfileResponse response = userProfileService.updateProfile(request); @@ -65,8 +68,9 @@ public class UserProfileController { /** * 根据ID查询详情 */ + @Operation(summary = "获取档案详情", description = "根据 ID 获取用户档案详情。") @GetMapping("/detail") - public Result getById(@RequestParam String id) { + public Result getById(@Parameter(description = "档案 ID") @RequestParam String id) { UserProfileResponse response = userProfileService.getProfileById(id); if (response == null) { return Result.notFound("档案不存在"); @@ -77,6 +81,7 @@ public class UserProfileController { /** * 获取当前登录用户的档案 */ + @Operation(summary = "获取当前用户档案", description = "获取当前登录用户的个人档案信息。") @GetMapping("/me") public Result getCurrentProfile() { UserProfileResponse response = userProfileService.getCurrentUserProfile(); @@ -87,6 +92,7 @@ public class UserProfileController { /** * 分页查询 */ + @Operation(summary = "分页查询用户档案", description = "分页查询用户档案列表。") @GetMapping("/page") public Result> getPage(@Validated UserProfilePageRequest request) { PageResult pageResult = userProfileService.getProfilePage(request); @@ -96,6 +102,7 @@ public class UserProfileController { /** * 列表查询 */ + @Operation(summary = "列表查询用户档案", description = "列表查询用户档案。") @GetMapping("/list") public Result> getList(@Validated UserProfilePageRequest request) { List list = userProfileService.getProfileList(request); @@ -107,6 +114,7 @@ public class UserProfileController { * 将childhood、peak、valley数据迁移到生命事件表 * 注意:此接口为一次性数据迁移接口,迁移完成后可删除 */ + @Operation(summary = "迁移生活事件", description = "将生活事件模块的数据迁移到用户档案中。") @PostMapping("/migrateLifeEvents") public Result migrateLifeEvents() { int count = userProfileService.migrateLifeEventsFromProfiles(); diff --git a/backend-single/src/main/java/com/emotion/controller/UserStatsController.java b/backend-single/src/main/java/com/emotion/controller/UserStatsController.java index d306cfd..64e5d8f 100644 --- a/backend-single/src/main/java/com/emotion/controller/UserStatsController.java +++ b/backend-single/src/main/java/com/emotion/controller/UserStatsController.java @@ -8,6 +8,9 @@ import com.emotion.dto.request.UserStatsPageRequest; import com.emotion.dto.request.UserStatsUpdateValueRequest; import com.emotion.dto.response.UserStatsResponse; import com.emotion.service.UserStatsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -18,13 +21,14 @@ import java.util.List; /** * 用户统计控制器 - * + * * @author huazhongmin * @date 2025-07-23 */ @RestController @RequestMapping("/userStats") @Validated +@Tag(name = "用户统计管理", description = "用户统计数据的查询、创建、更新、增量操作和重新计算接口") public class UserStatsController { @Autowired @@ -33,6 +37,7 @@ public class UserStatsController { /** * 分页查询用户统计 */ + @Operation(summary = "分页查询用户统计", description = "分页查询用户统计数据。") @GetMapping(value = "/page") public Result> getPage(@Validated UserStatsPageRequest request) { PageResult pageResult = userStatsService.getPageWithResponse(request); @@ -42,6 +47,7 @@ public class UserStatsController { /** * 创建或更新用户统计 */ + @Operation(summary = "创建或更新用户统计", description = "创建新用户统计数据或更新已有数据。") @PostMapping(value = "/createOrUpdate") public Result createOrUpdate(@Valid @RequestBody UserStatsCreateRequest request) { UserStatsResponse stats = userStatsService.createOrUpdateUserStatsWithResponse(request); @@ -51,6 +57,7 @@ public class UserStatsController { /** * 更新用户统计值 */ + @Operation(summary = "更新用户统计值", description = "直接更新指定统计项的值。") @PutMapping(value = "/updateStatsValue") public Result updateStatsValue(@Valid @RequestBody UserStatsUpdateValueRequest request) { boolean updated = userStatsService.updateStatsValue(request); @@ -63,6 +70,7 @@ public class UserStatsController { /** * 增加用户统计值 */ + @Operation(summary = "增加用户统计值", description = "对指定统计项进行增量累加操作。") @PutMapping(value = "/incrementStatsValue") public Result incrementStatsValue(@Valid @RequestBody UserStatsIncrementRequest request) { boolean updated = userStatsService.incrementStatsValue(request); @@ -75,8 +83,9 @@ public class UserStatsController { /** * 重新计算用户统计 */ + @Operation(summary = "重新计算用户统计", description = "基于原始数据重新计算用户的统计值。") @PutMapping(value = "/recalculateUserStats") - public Result recalculateUserStats(@RequestParam String userId) { + public Result recalculateUserStats(@Parameter(description = "用户 ID") @RequestParam String userId) { boolean recalculated = userStatsService.recalculateUserStats(userId); if (!recalculated) { return Result.error("重新计算失败"); @@ -87,6 +96,7 @@ public class UserStatsController { /** * 重新计算所有用户统计 */ + @Operation(summary = "重新计算所有用户统计", description = "重新计算所有用户的统计值(管理员操作)。") @PutMapping(value = "/recalculateAll") public Result recalculateAllUserStats() { boolean recalculated = userStatsService.recalculateAllUserStats(); @@ -99,8 +109,9 @@ public class UserStatsController { /** * 删除过期的统计数据 */ + @Operation(summary = "删除过期统计数据", description = "清理超过指定天数的过期统计数据。") @DeleteMapping(value = "/deleteExpired") - public Result deleteExpiredStats(@RequestParam(defaultValue = "30") Integer days) { + public Result deleteExpiredStats(@Parameter(description = "过期天数阈值") @RequestParam(defaultValue = "30") Integer days) { boolean deleted = userStatsService.deleteExpiredStats(days); if (!deleted) { return Result.error("删除失败"); diff --git a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsPreferenceItem.java b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsPreferenceItem.java index edf78a9..421adff 100644 --- a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsPreferenceItem.java +++ b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsPreferenceItem.java @@ -11,7 +11,9 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class AnalyticsPreferenceItem { private String dimension; + private String dimensionLabel; private String value; + private String valueLabel; private long count; private long users; } diff --git a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTopEventItem.java b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTopEventItem.java index c943d96..436e176 100644 --- a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTopEventItem.java +++ b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTopEventItem.java @@ -11,7 +11,13 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class AnalyticsTopEventItem { private String eventName; + private String eventLabel; private String eventType; + private String eventTypeLabel; + private String pagePath; + private String pageLabel; + private String apiPath; + private String apiLabel; private long count; private long users; } diff --git a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTrendItem.java b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTrendItem.java index 4ac24b3..90d7ca2 100644 --- a/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTrendItem.java +++ b/backend-single/src/main/java/com/emotion/dto/response/analytics/AnalyticsTrendItem.java @@ -12,6 +12,7 @@ import lombok.NoArgsConstructor; public class AnalyticsTrendItem { private String bucket; private String eventName; + private String eventLabel; private long count; private long users; } diff --git a/docs/superpowers/plans/2026-05-23-all-controller-chinese-annotations.md b/docs/superpowers/plans/2026-05-23-all-controller-chinese-annotations.md new file mode 100644 index 0000000..0fdaa2d --- /dev/null +++ b/docs/superpowers/plans/2026-05-23-all-controller-chinese-annotations.md @@ -0,0 +1,1579 @@ +# 全量 Controller 接口中文注解实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 为 backend-single 下全部 39 个 Controller 及其关联 Request DTO 补全 OpenAPI 中文注解(@Tag/@Operation/@Parameter/@Schema),使接口文档页面可通过清晰的中文描述理解每个接口的作用和参数含义。 + +**Architecture:** 在不改变现有代码结构和业务逻辑的前提下,为每个 Controller 类添加 `@Tag` 注解、为每个 public 方法添加 `@Operation` 注解、为 `@RequestParam`/`@PathVariable` 参数添加 `@Parameter` 注解、为被 Controller 直接引用的 Request DTO 字段添加 `@Schema` 注解。分 3 批实施,每批完成后编译验证。 + +**Tech Stack:** Spring Boot 2.7, Knife4j 4.3.0 (OpenAPI 3), Java 17, Maven + +**重要规范:** +- `import io.swagger.v3.oas.annotations.tags.Tag;` +- `import io.swagger.v3.oas.annotations.Operation;` +- `import io.swagger.v3.oas.annotations.Parameter;` +- `import io.swagger.v3.oas.annotations.media.Schema;` +- `@Tag` 注解加在 `@RequestMapping` 下方 +- `@Operation` 注解加在 HTTP 方法注解(@GetMapping 等)上方 +- `@Parameter` 注解加在 `@RequestParam`/`@PathVariable` 之前 +- 所有描述使用中文 + +--- + +## Task 1: Batch 1 — AI + 社区(7 个 Controller + 关联 DTO) + +### Task 1.1: AiChatController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AiChatController.java` +- Modify: `backend-single/src/main/java/com/com/emotion/dto/request/AiChatRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/AiSummaryRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/GuestChatRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/ConversationCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/ChatStatsRequest.java` + +- [ ] **Step 1: 为 AiChatController 添加 @Tag 和 @Operation 注解** + +```java +// 在类级别添加 import +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; + +// 在 @RequestMapping 下方添加 @Tag +@RestController +@RequestMapping("/aiChat") +@Tag(name = "AI 聊天", description = "AI 智能对话聊天接口,支持普通聊天、总结、状态查询、访客模式等") +public class AiChatController { +``` + +为每个方法添加 @Operation 注解(加在 @GetMapping/@PostMapping 等上方): + +```java + @Operation(summary = "发送 AI 聊天消息", description = "向 AI 发送聊天消息,返回 AI 回复。支持指定会话 ID 和用户 ID。") + @PostMapping(value = "/chat") + public Result chat(@Valid @RequestBody AiChatRequest request) { +``` + +```java + @Operation(summary = "获取 AI 聊天总结", description = "获取指定会话的 AI 聊天总结,概括对话要点。") + @PostMapping(value = "/summary") + public Result summary(@Valid @RequestBody AiSummaryRequest request) { +``` + +```java + @Operation(summary = "获取 AI 状态", description = "获取当前 AI 服务的运行状态信息。") + @GetMapping(value = "/status") + public Result getStatus() { +``` + +```java + @Operation(summary = "获取聊天统计数据", description = "获取指定时间范围内的聊天统计数据,包括消息数、Token 消耗等。") + @PostMapping(value = "/stats") + public Result getStats(@Valid @RequestBody ChatStatsRequest request) { +``` + +```java + @Operation(summary = "访客模式聊天", description = "未登录用户通过访客模式与 AI 进行对话,无需 token 认证。") + @PostMapping(value = "/guestChat") + public Result guestChat(@Valid @RequestBody GuestChatRequest request) { +``` + +```java + @Operation(summary = "获取访客用户信息", description = "根据访客 ID 获取对应的用户信息。") + @GetMapping(value = "/guestUserInfo") + public Result getGuestUserInfo(@Parameter(description = "访客 ID") @RequestParam String guestId) { +``` + +```java + @Operation(summary = "创建对话会话", description = "为当前用户创建一个新的 AI 对话会话。") + @PostMapping(value = "/createConversation") + public Result createConversation(@Valid @RequestBody ConversationCreateRequest request) { +``` + +- [ ] **Step 2: 为 AiChatRequest 添加 @Schema 注解** + +```java +import io.swagger.v3.oas.annotations.media.Schema; + +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "AI 聊天请求") +public class AiChatRequest extends BaseRequest { + + @Schema(description = "会话 ID") + private String conversationId; + + @Schema(description = "消息内容") + @NotBlank(message = "消息内容不能为空") + private String message; + + @Schema(description = "用户 ID") + private String userId; +} +``` + +- [ ] **Step 3: 为其他 Request DTO 添加 @Schema 注解** + +AiSummaryRequest: +```java +@Schema(description = "AI 聊天总结请求") +public class AiSummaryRequest extends BaseRequest { + @Schema(description = "会话 ID") + private String conversationId; +} +``` + +GuestChatRequest: +```java +@Schema(description = "访客聊天请求") +public class GuestChatRequest { + @Schema(description = "消息内容") + private String message; + @Schema(description = "访客 ID") + private String guestId; +} +``` + +ConversationCreateRequest: +```java +@Schema(description = "创建对话会话请求") +public class ConversationCreateRequest { + @Schema(description = "会话标题") + private String title; + @Schema(description = "初始消息内容") + private String initialMessage; +} +``` + +ChatStatsRequest: +```java +@Schema(description = "聊天统计查询请求") +public class ChatStatsRequest extends BaseRequest { + @Schema(description = "开始日期") + private String startDate; + @Schema(description = "结束日期") + private String endDate; + @Schema(description = "统计维度: daily-按天, weekly-按周, monthly-按月") + private String granularity; +} +``` + +### Task 1.2: AiRoutingController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AiRoutingController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/ai/AiRuntimeRequest.java` + +- [ ] **Step 1: 为 AiRoutingController 添加注解** + +```java +@RestController +@RequestMapping("/aiRouting") +@Tag(name = "AI 路由管理", description = "AI 服务提供商路由管理接口,包括 Provider/Endpoint/Scene 的 CRUD、调用日志、运行时测试和流式测试") +public class AiRoutingController { +``` + +关键方法注解示例(其余方法类似处理): + +```java + @Operation(summary = "创建 AI Provider", description = "创建一个新的 AI 服务提供商配置。") + @PostMapping(value = "/providers/create") + public Result createProvider(...) { +``` + +```java + @Operation(summary = "获取 Provider 列表", description = "分页查询所有 AI 服务提供商配置。") + @GetMapping(value = "/providers/list") + public Result> listProviders(...) { +``` + +```java + @Operation(summary = "运行时测试", description = "对指定的 AI 配置进行运行时连通性测试,支持同步和流式模式。") + @PostMapping(value = "/runtime/test") + public Result runtimeTest(@Valid @RequestBody AiRuntimeRequest request) { +``` + +```java + @Operation(summary = "流式运行时测试", description = "对指定的 AI 配置进行流式运行时连通性测试,以 SSE 事件流返回结果。") + @PostMapping(value = "/runtime/stream-test") + public SseEmitter streamRuntimeTest(@Valid @RequestBody AiRuntimeRequest request) { +``` + +- [ ] **Step 2: 为 AiRuntimeRequest 添加 @Schema 注解** + +```java +@Schema(description = "AI 运行时测试请求") +public class AiRuntimeRequest { + @Schema(description = "AI 配置 ID") + private String configId; + @Schema(description = "测试消息内容") + private String message; +} +``` + +### Task 1.3: CozeApiCallController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/CozeApiCallController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/coze/CozeApiCallPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/coze/CozeApiCallCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/coze/CozeApiCallUpdateRequest.java` + +- [ ] **Step 1: 为 CozeApiCallController 添加 @Tag 注解** + +```java +@RestController +@RequestMapping("/cozeApiCall") +@Tag(name = "Coze API 调用记录", description = "Coze API 调用记录的查询、创建、更新和删除接口") +public class CozeApiCallController { +``` + +- [ ] **Step 2: 为每个方法添加 @Operation** + +```java + @Operation(summary = "分页查询调用记录", description = "根据条件分页查询 Coze API 调用记录。") + @PostMapping(value = "/page") + public Result> page(...) { +``` + +```java + @Operation(summary = "获取调用记录详情", description = "根据 ID 获取单条调用记录的详细信息。") + @GetMapping(value = "/detail") + public Result detail(@Parameter(description = "调用记录 ID") @RequestParam String id) { +``` + +```java + @Operation(summary = "创建调用记录", description = "新增一条 Coze API 调用记录。") + @PostMapping(value = "/create") + public Result create(...) { +``` + +```java + @Operation(summary = "更新调用记录", description = "更新已有的 Coze API 调用记录。") + @PostMapping(value = "/update") + public Result update(...) { +``` + +```java + @Operation(summary = "删除调用记录", description = "删除指定的 Coze API 调用记录。") + @DeleteMapping(value = "/delete") + public Result delete(@Parameter(description = "调用记录 ID") @RequestParam String id) { +``` + +```java + @Operation(summary = "按用户统计调用量", description = "统计指定用户在时间范围内的 Coze API 调用次数。") + @GetMapping(value = "/countByUser") + public Result countByUser(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "按 Bot 统计调用量", description = "统计指定 Bot 的 Coze API 调用次数。") + @GetMapping(value = "/countByBot") + public Result countByBot(@Parameter(description = "Bot ID") @RequestParam String botId) { +``` + +```java + @Operation(summary = "按状态统计调用量", description = "按调用状态统计 Coze API 调用次数。") + @GetMapping(value = "/countByStatus") + public Result> countByStatus() { +``` + +```java + @Operation(summary = "按用户统计 Token 消耗", description = "统计指定用户的 Token 总消耗量。") + @GetMapping(value = "/tokensByUser") + public Result tokensByUser(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "按用户统计费用", description = "统计指定用户的 API 调用总费用。") + @GetMapping(value = "/costByUser") + public Result costByUser(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +- [ ] **Step 3: 为 Request DTO 添加 @Schema** + +CozeApiCallPageRequest: +```java +@Schema(description = "Coze API 调用记录分页查询请求") +public class CozeApiCallPageRequest extends PageRequest { + @Schema(description = "用户 ID") + private String userId; + @Schema(description = "Bot ID") + private String botId; + @Schema(description = "调用状态") + private String status; +} +``` + +CozeApiCallCreateRequest: +```java +@Schema(description = "创建 Coze API 调用记录请求") +public class CozeApiCallCreateRequest { + @Schema(description = "用户 ID") + private String userId; + @Schema(description = "Bot ID") + private String botId; + @Schema(description = "请求参数 JSON") + private String requestParams; + @Schema(description = "响应结果 JSON") + private String responseBody; + @Schema(description = "Token 消耗量") + private Long tokenCount; +} +``` + +CozeApiCallUpdateRequest: +```java +@Schema(description = "更新 Coze API 调用记录请求") +public class CozeApiCallUpdateRequest { + @Schema(description = "调用记录 ID") + private String id; + @Schema(description = "调用状态") + private String status; + @Schema(description = "错误信息") + private String errorMessage; +} +``` + +### Task 1.4: CommunityPostController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/CommunityPostController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/community/CommunityPostCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/community/CommunityPostUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/community/CommunityPostPageRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/communityPost") +@Tag(name = "社区帖子管理", description = "社区帖子的查询、创建、更新和删除接口") +public class CommunityPostController { +``` + +```java + @Operation(summary = "分页查询社区帖子", description = "根据条件分页查询社区帖子列表。") + @PostMapping(value = "/page") +``` + +```java + @Operation(summary = "获取帖子详情", description = "根据 ID 获取社区帖子的详细信息。") + @GetMapping(value = "/detail") +``` + +```java + @Operation(summary = "创建社区帖子", description = "发布一篇新的社区帖子。") + @PostMapping(value = "/create") +``` + +```java + @Operation(summary = "更新社区帖子", description = "修改已有的社区帖子内容。") + @PostMapping(value = "/update") +``` + +```java + @Operation(summary = "删除社区帖子", description = "删除指定的社区帖子。") + @DeleteMapping(value = "/delete") +``` + +- [ ] **Step 2: DTO @Schema** + +CommunityPostCreateRequest 各字段加 @Schema(description = "帖子标题")、@Schema(description = "帖子内容") 等。 +CommunityPostUpdateRequest 各字段加 @Schema(description = "帖子 ID")、@Schema(description = "更新后的标题") 等。 +CommunityPostPageRequest 各字段加 @Schema(description = "页码")、@Schema(description = "每页数量") 等。 + +### Task 1.5: CommentController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/CommentController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/comment/CommentCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/comment/CommentUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/comment/CommentPageRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/comment") +@Tag(name = "评论管理", description = "评论的查询、创建、更新和删除接口") +public class CommentController { +``` + +```java + @Operation(summary = "分页查询评论", description = "根据条件分页查询评论列表。") + @PostMapping(value = "/page") +``` + +```java + @Operation(summary = "创建评论", description = "对指定目标发表一条新评论。") + @PostMapping(value = "/create") +``` + +```java + @Operation(summary = "更新评论", description = "修改已有评论的内容。") + @PostMapping(value = "/update") +``` + +```java + @Operation(summary = "删除评论", description = "删除指定的评论。") + @DeleteMapping(value = "/delete") +``` + +```java + @Operation(summary = "获取评论详情", description = "根据 ID 获取评论的详细信息。") + @GetMapping(value = "/detail") +``` + +### Task 1.6: SocialContentController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/SocialContentController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/social/SocialContentManualImportRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/social/SocialContentLinkImportRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/social/SocialContentApprovalRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/socialContent") +@Tag(name = "社交内容管理", description = "社交媒体内容的导入、截图、审核等接口") +public class SocialContentController { +``` + +```java + @Operation(summary = "手动导入社交内容", description = "通过上传文本内容手动导入社交媒体数据。") + @PostMapping(value = "/manual") +``` + +```java + @Operation(summary = "链接导入社交内容", description = "通过社交媒体链接 URL 导入内容。") + @PostMapping(value = "/link") +``` + +```java + @Operation(summary = "截图导入社交内容", description = "通过上传截图图片来导入社交媒体内容。") + @PostMapping(value = "/screenshot") +``` + +```java + @Operation(summary = "获取社交内容列表", description = "查询所有已导入的社交媒体内容列表。") + @GetMapping(value = "/list") +``` + +```java + @Operation(summary = "更新内容审核状态", description = "修改指定社交内容的审核状态(通过/拒绝)。") + @PutMapping(value = "/updateApproval") +``` + +```java + @Operation(summary = "删除社交内容", description = "删除指定的社交媒体内容记录。") + @DeleteMapping(value = "/delete") +``` + +### Task 1.7: SocialInsightController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/SocialInsightController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/social/SocialInsightGenerateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/social/SocialInsightUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/socialInsight") +@Tag(name = "社交洞察管理", description = "社交媒体洞察生成、查询和更新接口") +public class SocialInsightController { +``` + +```java + @Operation(summary = "生成社交洞察", description = "基于用户社交数据生成 AI 分析洞察报告。") + @PostMapping(value = "/generate") +``` + +```java + @Operation(summary = "获取洞察列表", description = "查询当前用户的所有社交洞察记录。") + @GetMapping(value = "/list") +``` + +```java + @Operation(summary = "更新洞察记录", description = "更新已有洞察的状态或备注信息。") + @PutMapping(value = "/update") +``` + +```java + @Operation(summary = "删除洞察记录", description = "删除指定的社交洞察记录。") + @DeleteMapping(value = "/delete/{id}") +``` + +### Task 1.8: Batch 1 编译验证 + +- [ ] **Step 1: 编译验证** + +```bash +cd backend-single +mvn clean install -pl :backend-single -am -DskipTests +``` + +Expected: BUILD SUCCESS,无编译错误。 + +- [ ] **Step 2: 提交 Batch 1 改动** + +```bash +git add backend-single/src/main/java/com/emotion/controller/AiChatController.java +git add backend-single/src/main/java/com/emotion/controller/AiRoutingController.java +# ... 添加 Batch 1 所有修改的文件 +git commit -m "feat: Batch 1 — AI + 社区 Controller 中文注解补全" +``` + +--- + +## Task 2: Batch 2 — 情绪 + 日记 + 互动(11 个 Controller + 关联 DTO) + +### Task 2.1: EmotionAnalysisController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionAnalysisCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionAnalysisPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionAnalysisUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/emotionAnalysis") +@Tag(name = "情绪分析管理", description = "情绪分析记录的查询、创建、更新和删除接口") +public class EmotionAnalysisController { +``` + +```java + @Operation(summary = "分页查询情绪分析", description = "根据条件分页查询情绪分析记录列表。") + @PostMapping(value = "/page") +``` + +```java + @Operation(summary = "创建情绪分析", description = "基于情绪记录数据创建一条新的 AI 情绪分析报告。") + @PostMapping(value = "/create") +``` + +```java + @Operation(summary = "获取分析详情", description = "根据 ID 获取情绪分析报告的详细信息。") + @GetMapping(value = "/detail") +``` + +```java + @Operation(summary = "更新情绪分析", description = "修改已有情绪分析报告的内容。") + @PutMapping(value = "/update") +``` + +```java + @Operation(summary = "删除情绪分析", description = "删除指定的情绪分析记录。") + @DeleteMapping(value = "/delete") +``` + +### Task 2.2: EmotionRecordController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/EmotionRecordController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionRecordCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionRecordPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionRecordUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/emotionRecord") +@Tag(name = "情绪记录管理", description = "用户情绪记录的查询、创建、更新、删除和统计接口") +public class EmotionRecordController { +``` + +```java + @Operation(summary = "创建情绪记录", description = "记录用户当天的情绪数据,包括类型、强度、触发因素等。") + @PostMapping(value = "/create") +``` + +```java + @Operation(summary = "分页查询情绪记录", description = "根据日期范围、情绪类型等条件分页查询情绪记录。") + @PostMapping(value = "/page") +``` + +```java + @Operation(summary = "获取记录详情", description = "根据 ID 获取情绪记录的详细信息。") + @GetMapping(value = "/detail") +``` + +```java + @Operation(summary = "更新情绪记录", description = "修改已有情绪记录的内容。") + @PutMapping(value = "/update") +``` + +```java + @Operation(summary = "删除情绪记录", description = "删除指定的情绪记录。") + @DeleteMapping(value = "/delete") +``` + +```java + @Operation(summary = "获取情绪统计", description = "统计指定时间范围内的情绪数据分布。") + @GetMapping(value = "/stats") +``` + +### Task 2.3: EmotionSummaryController 补充注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/EmotionSummaryController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionSummaryGenerateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EmotionSummaryStatusRequest.java` + +- [ ] **Step 1: 补充缺失的 @Operation 注解** + +该 Controller 已有 `@Tag("情绪总结管理")` 和部分 @Operation。检查缺失的方法级注解并补充。 + +```java + @Operation(summary = "生成情绪总结", description = "基于指定时间范围的情绪记录数据,生成 AI 情绪总结报告。") + @PostMapping(value = "/generate") +``` + +```java + @Operation(summary = "查询总结状态", description = "查询指定时间段内是否已生成情绪总结及其状态。") + @PostMapping(value = "/status") +``` + +### Task 2.4: DiaryPostController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/DiaryPostController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/DiaryPostCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/DiaryPostPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/DiaryPostUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/diaryPost") +@Tag(name = "日记管理", description = "用户日记帖子的查询、创建、发布、更新、删除、点赞、分享等接口") +public class DiaryPostController { +``` + +13 个方法的 @Operation 注解(逐一添加): + +```java + @Operation(summary = "分页查询日记", description = "根据条件分页查询当前用户的日记帖子列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取日记详情", description = "根据 ID 获取日记帖子的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建日记", description = "创建一篇新的日记帖子。") + @PostMapping(value = "/create") + + @Operation(summary = "发布日记", description = "将草稿状态的日记帖子发布为正式内容。") + @PostMapping(value = "/publish") + + @Operation(summary = "更新日记", description = "修改已有日记帖子的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除日记", description = "永久删除指定的日记帖子。") + @DeleteMapping(value = "/delete") + + @Operation(summary = "软删除日记", description = "将日记帖子标记为已删除状态(可恢复)。") + @PutMapping(value = "/softDelete") + + @Operation(summary = "恢复日记", description = "将已软删除的日记帖子恢复为正常状态。") + @PutMapping(value = "/restore") + + @Operation(summary = "点赞日记", description = "对指定日记帖子进行点赞操作。") + @PostMapping(value = "/like") + + @Operation(summary = "取消点赞日记", description = "取消对指定日记帖子的点赞。") + @PostMapping(value = "/unlike") + + @Operation(summary = "分享日记", description = "将指定日记帖子分享给其他用户。") + @PostMapping(value = "/share") + + @Operation(summary = "设置精选日记", description = "将指定日记帖子标记为精选内容。") + @PutMapping(value = "/setFeatured") + + @Operation(summary = "设置日记优先级", description = "修改指定日记帖子的优先级排序。") + @PutMapping(value = "/setPriority") +``` + +### Task 2.5: DiaryCommentController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/DiaryCommentController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/DiaryCommentCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/DiaryCommentPageRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/diaryComment") +@Tag(name = "日记评论管理", description = "日记评论的查询、创建、更新、删除、点赞、置顶等接口") +public class DiaryCommentController { +``` + +11 个方法逐一添加 @Operation: + +```java + @Operation(summary = "分页查询评论", description = "分页查询指定日记的评论列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取评论树", description = "以树形结构获取日记的评论及其回复列表。") + @GetMapping(value = "/commentTree") + + @Operation(summary = "获取评论详情", description = "根据 ID 获取评论详情。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建评论", description = "对指定日记发表一条新评论或回复。") + @PostMapping(value = "/create") + + @Operation(summary = "更新评论", description = "修改已有评论的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除评论", description = "永久删除指定评论。") + @DeleteMapping(value = "/delete") + + @Operation(summary = "软删除评论", description = "将评论标记为已删除状态。") + @PutMapping(value = "/softDelete") + + @Operation(summary = "恢复评论", description = "恢复已软删除的评论。") + @PutMapping(value = "/restore") + + @Operation(summary = "点赞评论", description = "对指定评论进行点赞。") + @PostMapping(value = "/like") + + @Operation(summary = "取消点赞评论", description = "取消对指定评论的点赞。") + @PostMapping(value = "/unlike") + + @Operation(summary = "置顶评论", description = "将指定评论设为置顶显示。") + @PutMapping(value = "/setTop") +``` + +### Task 2.6: GrowthTopicController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/GrowthTopicController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/growth/GrowthTopicCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/growth/GrowthTopicPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/growth/GrowthTopicUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/growthTopic") +@Tag(name = "成长话题管理", description = "成长话题的查询、创建、更新和删除接口") +public class GrowthTopicController { +``` + +```java + @Operation(summary = "分页查询成长话题", description = "分页查询成长话题列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取话题详情", description = "根据 ID 获取成长话题的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建成长话题", description = "创建一个新的成长话题。") + @PostMapping(value = "/create") + + @Operation(summary = "更新成长话题", description = "修改已有成长话题的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除成长话题", description = "删除指定的成长话题。") + @DeleteMapping(value = "/delete") +``` + +### Task 2.7: TopicInteractionController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/TopicInteractionController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/TopicInteractionCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/TopicInteractionPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/TopicInteractionUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/topicInteraction") +@Tag(name = "话题互动管理", description = "话题互动记录的查询、创建、更新和删除接口") +public class TopicInteractionController { +``` + +5 个方法添加 @Operation: + +```java + @Operation(summary = "分页查询互动记录", description = "分页查询话题互动记录列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取互动详情", description = "根据 ID 获取互动记录的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建互动记录", description = "创建一条新的话题互动记录。") + @PostMapping(value = "/create") + + @Operation(summary = "更新互动记录", description = "修改已有话题互动的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除互动记录", description = "删除指定的话题互动记录。") + @DeleteMapping(value = "/delete") +``` + +### Task 2.8: ConversationController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/ConversationController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/ConversationPageRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/conversation") +@Tag(name = "会话管理", description = "AI 对话会话的查询、创建、更新、删除和状态管理接口") +public class ConversationController { +``` + +8 个方法添加 @Operation: + +```java + @Operation(summary = "分页查询会话", description = "分页查询当前用户的对话会话列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取会话详情", description = "根据 ID 获取会话的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建会话", description = "创建一个新的 AI 对话会话。") + @PostMapping(value = "/create") + + @Operation(summary = "更新会话", description = "修改已有会话的标题等属性。") + @PutMapping(value = "/update") + + @Operation(summary = "删除会话", description = "删除指定的对话会话。") + @DeleteMapping(value = "/delete") + + @Operation(summary = "获取活跃会话", description = "获取当前用户最近的活跃会话列表。") + @GetMapping(value = "/active") + + @Operation(summary = "获取归档会话", description = "获取当前用户已归档的会话列表。") + @GetMapping(value = "/archived") + + @Operation(summary = "获取会话状态", description = "获取指定会话的当前状态信息。") + @GetMapping(value = "/status") +``` + +### Task 2.9: MessageController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/MessageController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/MessageCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/MessagePageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/MessageSearchRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/MessageRecentRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/message") +@Tag(name = "消息管理", description = "会话消息的查询、创建、搜索、更新和删除接口") +public class MessageController { +``` + +7 个方法添加 @Operation: + +```java + @Operation(summary = "创建消息", description = "在指定会话中创建一条新消息。") + @PostMapping(value = "/create") + + @Operation(summary = "获取消息详情", description = "根据 ID 获取消息的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "分页查询消息", description = "分页查询指定会话的消息列表。") + @PostMapping(value = "/page") + + @Operation(summary = "搜索消息", description = "根据关键词在指定会话中搜索消息内容。") + @PostMapping(value = "/search") + + @Operation(summary = "获取最近消息", description = "获取指定会话最近的消息列表。") + @PostMapping(value = "/recent") + + @Operation(summary = "更新消息", description = "修改指定消息的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除消息", description = "删除指定的消息记录。") + @DeleteMapping(value = "/delete") +``` + +### Task 2.10: UserProfileController 补充注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/UserProfileController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfilePageRequest.java` + +- [ ] **Step 1: 补充 @Operation 注解(该 Controller 已有 @Tag 但方法级注解缺失)** + +```java + @Operation(summary = "分页查询用户档案", description = "分页查询用户档案列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取档案详情", description = "根据 ID 获取用户档案详情。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建用户档案", description = "为当前用户创建个人档案,包含昵称、MBTI 人格类型、童年经历等。") + @PostMapping(value = "/create") + + @Operation(summary = "更新用户档案", description = "更新当前用户的个人档案信息。") + @PutMapping(value = "/update") + + @Operation(summary = "删除用户档案", description = "删除指定的用户档案。") + @DeleteMapping(value = "/delete") + + @Operation(summary = "迁移生活事件", description = "将生活事件模块的数据迁移到用户档案中。") + @PostMapping(value = "/migrateLifeEvents") + + @Operation(summary = "获取档案 AI 设置", description = "获取用户档案关联的 AI 配置信息。") + @GetMapping(value = "/getAiSettings") + + @Operation(summary = "更新档案 AI 设置", description = "更新用户档案关联的 AI 配置。") + @PostMapping(value = "/updateAiSettings") +``` + +### Task 2.11: AchievementController 补充注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AchievementController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/achievement/AchievementCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/achievement/AchievementPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/achievement/AchievementUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/achievement/AchievementProgressUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/achievement/AchievementUnlockRequest.java` + +- [ ] **Step 1: 补充 @Parameter 注解(已有 @Tag 和 @Operation,但缺少 @RequestParam 的 @Parameter)** + +为所有 `@RequestParam` 参数添加 `@Parameter(description = "...")` 注解: + +```java + @Operation(summary = "分页查询成就", description = "分页查询成就列表。") + @PostMapping(value = "/page") + public Result> page(@Validated AchievementPageRequest request) { +``` + +```java + @Operation(summary = "获取成就详情", description = "根据 ID 获取成就详情。") + @GetMapping(value = "/detail") + public Result getById(@Parameter(description = "成就 ID") @RequestParam String id) { +``` + +```java + @Operation(summary = "创建成就", description = "创建一个新的成就。") + @PostMapping(value = "/create") + + @Operation(summary = "更新成就", description = "更新指定成就的信息。") + @PostMapping(value = "/update") + + @Operation(summary = "删除成就", description = "删除指定的成就。") + @DeleteMapping(value = "/delete") + + @Operation(summary = "获取用户成就列表", description = "获取指定用户的所有成就及其进度。") + @GetMapping(value = "/userAchievements") + public Result> getUserAchievements(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "更新成就进度", description = "更新指定成就的完成进度。") + @PostMapping(value = "/updateProgress") + public Result updateProgress(@Valid @RequestBody AchievementProgressUpdateRequest request) { +``` + +```java + @Operation(summary = "解锁成就", description = "解锁指定成就(标记为已完成)。") + @PostMapping(value = "/unlock") + public Result unlock(@Valid @RequestBody AchievementUnlockRequest request) { +``` + +```java + @Operation(summary = "获取成就统计", description = "获取用户的成就统计数据。") + @GetMapping(value = "/stats") + public Result getStats(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "检查成就达成", description = "检查指定用户是否有新成就可以达成。") + @PostMapping(value = "/checkAchievement") + public Result> checkAchievement(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "批量检查成就达成", description = "批量检查多个用户的成就达成情况。") + @PostMapping(value = "/batchCheckAchievement") + public Result>> batchCheckAchievement(@Parameter(description = "用户 ID 列表") @RequestBody List userIds) { +``` + +```java + @Operation(summary = "重置成就进度", description = "重置指定成就的完成进度。") + @PostMapping(value = "/resetProgress") + public Result resetProgress(@Parameter(description = "成就 ID") @RequestParam String achievementId, @Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +```java + @Operation(summary = "获取成就排行榜", description = "获取用户成就完成数量的排行榜。") + @GetMapping(value = "/leaderboard") + public Result> getLeaderboard(@Parameter(description = "排名数量限制") @RequestParam(defaultValue = "10") Integer limit) { +``` + +```java + @Operation(summary = "获取用户排名", description = "获取指定用户在成就排行榜中的排名。") + @GetMapping(value = "/userRank") + public Result getUserRank(@Parameter(description = "用户 ID") @RequestParam String userId) { +``` + +### Task 2.12: Batch 2 编译验证 + +- [ ] **Step 1: 编译验证** + +```bash +cd backend-single +mvn clean install -pl :backend-single -am -DskipTests +``` + +Expected: BUILD SUCCESS + +- [ ] **Step 2: 提交 Batch 2 改动** + +```bash +git add backend-single/src/main/java/com/emotion/controller/EmotionAnalysisController.java +# ... 添加 Batch 2 所有修改的文件 +git commit -m "feat: Batch 2 — 情绪 + 日记 + 互动 Controller 中文注解补全" +``` + +--- + +## Task 3: Batch 3 — 其他(13 个 Controller + 关联 DTO) + +### Task 3.1: LifePathController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/LifePathController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifePathCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifePathPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifePathUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/lifePath") +@Tag(name = "实现路径管理", description = "人生剧本实现路径的查询、创建、更新和删除接口") +public class LifePathController { +``` + +7 个方法添加 @Operation: + +```java + @Operation(summary = "分页查询实现路径", description = "分页查询当前用户的实现路径列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取实现路径列表", description = "获取当前用户的所有实现路径列表。") + @GetMapping(value = "/listAll") + + @Operation(summary = "根据剧本ID获取路径", description = "根据剧本 ID 获取对应的实现路径。") + @GetMapping(value = "/byScript") + + @Operation(summary = "获取路径详情", description = "根据 ID 获取实现路径的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建实现路径", description = "创建一条新的实现路径。") + @PostMapping(value = "/create") + + @Operation(summary = "更新实现路径", description = "修改已有实现路径的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "删除实现路径", description = "删除指定的实现路径。") + @DeleteMapping(value = "/delete") +``` + +为 @RequestParam 添加 @Parameter: + +```java + public Result getByScriptId(@Parameter(description = "剧本 ID") @RequestParam String scriptId) { + public Result getById(@Parameter(description = "路径 ID") @RequestParam String id) { + public Result delete(@Parameter(description = "路径 ID") @RequestParam String id) { +``` + +### Task 3.2: RewardController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/RewardController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/reward/RewardCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/reward/RewardPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/reward/RewardUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/reward") +@Tag(name = "奖励管理", description = "奖励的查询、创建、更新和删除接口") +public class RewardController { +``` + +5 个方法添加 @Operation: + +```java + @Operation(summary = "分页查询奖励", description = "分页查询奖励列表。") + @GetMapping(value = "/page") + + @Operation(summary = "获取奖励详情", description = "根据 ID 获取奖励的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建奖励", description = "创建一个新的奖励。") + @PostMapping(value = "/create") + + @Operation(summary = "更新奖励", description = "修改已有奖励的信息。") + @PutMapping(value = "/update") + + @Operation(summary = "删除奖励", description = "删除指定的奖励。") + @DeleteMapping(value = "/delete") +``` + +### Task 3.3: UserStatsController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/UserStatsController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/UserStatsCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/UserStatsIncrementRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/UserStatsPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/UserStatsUpdateValueRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/userStats") +@Tag(name = "用户统计管理", description = "用户统计数据的查询、创建、更新、增量操作和重新计算接口") +public class UserStatsController { +``` + +8 个方法添加 @Operation + @Parameter: + +```java + @Operation(summary = "分页查询用户统计", description = "分页查询用户统计数据。") + @GetMapping(value = "/page") + + @Operation(summary = "创建或更新用户统计", description = "创建新用户统计数据或更新已有数据。") + @PostMapping(value = "/createOrUpdate") + + @Operation(summary = "更新用户统计值", description = "直接更新指定统计项的值。") + @PutMapping(value = "/updateStatsValue") + + @Operation(summary = "增加用户统计值", description = "对指定统计项进行增量累加操作。") + @PutMapping(value = "/incrementStatsValue") + + @Operation(summary = "重新计算用户统计", description = "基于原始数据重新计算用户的统计值。") + @PutMapping(value = "/recalculateUserStats") + public Result recalculateUserStats(@Parameter(description = "用户 ID") @RequestParam String userId) { + + @Operation(summary = "重新计算所有用户统计", description = "重新计算所有用户的统计值(管理员操作)。") + @PutMapping(value = "/recalculateAll") + + @Operation(summary = "删除过期统计数据", description = "清理超过指定天数的过期统计数据。") + @DeleteMapping(value = "/deleteExpired") + public Result deleteExpiredStats(@Parameter(description = "过期天数阈值", required = false) @RequestParam(defaultValue = "30") Integer days) { +``` + +### Task 3.4: EpicScriptController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/EpicScriptController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EpicScriptCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EpicScriptUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EpicScriptPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/EpicScriptInspirationRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/epicScript") +@Tag(name = "爽文剧本管理", description = "爽文剧本的查询、创建、更新、删除和灵感推荐接口") +public class EpicScriptController { +``` + +11 个方法添加 @Operation: + +```java + @Operation(summary = "分页查询爽文剧本", description = "分页查询当前用户的爽文剧本列表。") + @PostMapping(value = "/page") + + @Operation(summary = "获取爽文剧本列表", description = "获取当前用户的所有爽文剧本列表。") + @GetMapping(value = "/listAll") + + @Operation(summary = "获取灵感推荐", description = "获取系统推荐的灵感建议列表。") + @GetMapping(value = "/inspiration/recommendations") + + @Operation(summary = "获取随机灵感", description = "随机获取指定数量的灵感建议。") + @GetMapping(value = "/inspiration/random") + public Result> getRandomInspirations(@Parameter(description = "灵感数量", required = false) @RequestParam(required = false, defaultValue = "3") Integer size) { + + @Operation(summary = "从灵感生成剧本", description = "基于选定的灵感建议生成爽文剧本。") + @PostMapping(value = "/inspiration/generate") + + @Operation(summary = "获取剧本详情", description = "根据 ID 获取爽文剧本的详细信息。") + @GetMapping(value = "/detail") + + @Operation(summary = "创建爽文剧本", description = "创建一个新的爽文剧本。") + @PostMapping(value = "/create") + + @Operation(summary = "更新爽文剧本", description = "修改已有爽文剧本的内容。") + @PutMapping(value = "/update") + + @Operation(summary = "选中剧本", description = "选中指定剧本并取消其他剧本的选中状态。") + @PutMapping(value = "/select") + + @Operation(summary = "删除爽文剧本", description = "删除指定的爽文剧本。") + @DeleteMapping(value = "/delete") +``` + +### Task 3.5: DictionaryController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/DictionaryController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/dictionary/DictionaryCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/dictionary/DictionaryPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/dictionary/DictionaryUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/dictionary") +@Tag(name = "字典管理", description = "数据字典的查询、创建、更新和删除接口") +public class DictionaryController { +``` + +5 个方法添加 @Operation。 + +### Task 3.6: GuestUserController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/GuestUserController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/guest/GuestUserCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/guest/GuestUserPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/guest/GuestUserUpdateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/guestUser") +@Tag(name = "访客用户管理", description = "访客用户的查询、创建、更新和删除接口") +public class GuestUserController { +``` + +5 个方法添加 @Operation。 + +### Task 3.7: TtsController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/TtsController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/tts/TtsTaskCreateRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/tts") +@Tag(name = "语音合成(TTS)", description = "文字转语音任务创建和查询接口") +public class TtsController { +``` + +方法添加 @Operation。 + +### Task 3.8: AsrController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AsrController.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/asr") +@Tag(name = "语音识别(ASR)", description = "语音转文字识别接口") +public class AsrController { +``` + +方法添加 @Operation。 + +### Task 3.9: HealthController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/HealthController.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/health") +@Tag(name = "健康检查", description = "系统健康状态检查接口") +public class HealthController { +``` + +方法添加 @Operation(summary = "系统健康检查", description = "返回系统各组件的健康状态,包括数据库、Redis 等。")。 + +### Task 3.10: LifeEventController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/LifeEventController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifeEventCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifeEventUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/LifeEventPageRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/lifeEvent") +@Tag(name = "生命事件管理", description = "生命事件的查询、创建、更新和删除接口") +public class LifeEventController { +``` + +5 个方法添加 @Operation。 + +### Task 3.11: ChatWebSocketController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/ChatWebSocketController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/WebSocketRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/ws/chat") +@Tag(name = "WebSocket 聊天", description = "基于 WebSocket 的实时 AI 聊天通信接口") +public class ChatWebSocketController { +``` + +方法添加 @Operation。 + +### Task 3.12: AnalyticsController 注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AnalyticsController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/analytics/AnalyticsEventBatchRequest.java` + +- [ ] **Step 1: Controller 注解** + +```java +@RestController +@RequestMapping("/analytics") +@Tag(name = "事件分析", description = "前端行为事件上报和分析接口") +public class AnalyticsController { +``` + +方法添加 @Operation。 + +### Task 3.13: AiConfigController 补充注解 + +**Files:** +- Modify: `backend-single/src/main/java/com/emotion/controller/AiConfigController.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigCreateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigUpdateRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigPageRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigEnableRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigDefaultRequest.java` +- Modify: `backend-single/src/main/java/com/emotion/dto/request/aiconfig/AiConfigTestUpdateRequest.java` + +- [ ] **Step 1: 补充缺失的 @Operation 注解(已有 @Tag 但方法级注解不全)** + +为每个缺失的方法添加 @Operation。 + +### Task 3.14: Batch 3 编译验证 + +- [ ] **Step 1: 编译验证** + +```bash +cd backend-single +mvn clean install -pl :backend-single -am -DskipTests +``` + +Expected: BUILD SUCCESS + +- [ ] **Step 2: 提交 Batch 3 改动** + +```bash +git add backend-single/src/main/java/com/emotion/controller/LifePathController.java +# ... 添加 Batch 3 所有修改的文件 +git commit -m "feat: Batch 3 — 其他 Controller 中文注解补全" +``` + +--- + +## Task 4: 全量 DTO @Schema 注解补充 + +以下为各批次的 DTO 文件补充清单。所有 `@Schema` 注解格式统一: + +```java +@Schema(description = "中文描述") +private String fieldName; +``` + +### Batch 1 DTO 列表(21 个文件) + +| 文件路径 | 关键字段 | +|---------|---------| +| `dto/request/AiChatRequest.java` | conversationId-会话 ID, message-消息内容, userId-用户 ID | +| `dto/request/AiSummaryRequest.java` | conversationId-会话 ID | +| `dto/request/GuestChatRequest.java` | message-消息内容, guestId-访客 ID | +| `dto/request/ConversationCreateRequest.java` | title-会话标题, initialMessage-初始消息 | +| `dto/request/ChatStatsRequest.java` | startDate-开始日期, endDate-结束日期, granularity-统计维度 | +| `dto/request/ai/AiRuntimeRequest.java` | configId-配置 ID, message-测试消息 | +| `dto/request/coze/CozeApiCallPageRequest.java` | userId-用户 ID, botId-Bot ID, status-调用状态 | +| `dto/request/coze/CozeApiCallCreateRequest.java` | userId-用户 ID, botId-Bot ID, requestParams-请求参数, responseBody-响应结果, tokenCount-Token 消耗 | +| `dto/request/coze/CozeApiCallUpdateRequest.java` | id-记录 ID, status-调用状态, errorMessage-错误信息 | +| `dto/request/community/CommunityPostCreateRequest.java` | title-帖子标题, content-帖子内容, type-帖子类型 | +| `dto/request/community/CommunityPostUpdateRequest.java` | id-帖子 ID, title-标题, content-内容 | +| `dto/request/community/CommunityPostPageRequest.java` | keyword-关键词, type-帖子类型 | +| `dto/request/comment/CommentCreateRequest.java` | targetId-目标 ID, targetType-目标类型, content-评论内容, parentId-父评论 ID | +| `dto/request/comment/CommentUpdateRequest.java` | id-评论 ID, content-评论内容 | +| `dto/request/comment/CommentPageRequest.java` | targetId-目标 ID, targetType-目标类型 | +| `dto/request/social/SocialContentManualImportRequest.java` | content-内容文本, platform-平台名称 | +| `dto/request/social/SocialContentLinkImportRequest.java` | url-社交媒体链接 | +| `dto/request/social/SocialContentApprovalRequest.java` | contentId-内容 ID, approved-是否通过 | +| `dto/request/social/SocialInsightGenerateRequest.java` | userId-用户 ID, dateRange-日期范围 | +| `dto/request/social/SocialInsightUpdateRequest.java` | id-洞察 ID, status-状态 | + +### Batch 2 DTO 列表(17 个文件) + +| 文件路径 | 关键字段 | +|---------|---------| +| `dto/request/EmotionAnalysisCreateRequest.java` | userId-用户 ID, startDate-开始日期, endDate-结束日期 | +| `dto/request/EmotionAnalysisPageRequest.java` | userId-用户 ID, startDate-开始日期 | +| `dto/request/EmotionAnalysisUpdateRequest.java` | id-分析 ID, analysisContent-分析内容 | +| `dto/request/EmotionRecordCreateRequest.java` | userId-用户 ID, recordDate-记录日期, emotionType-情绪类型, intensity-情绪强度, triggers-触发因素, description-描述, tags-标签, weather-天气, location-地点, activity-活动, people-相关人物, notes-备注 | +| `dto/request/EmotionRecordPageRequest.java` | startDate-开始日期, endDate-结束日期, emotionType-情绪类型 | +| `dto/request/EmotionRecordUpdateRequest.java` | id-记录 ID, emotionType-情绪类型, intensity-情绪强度, description-描述 | +| `dto/request/EmotionSummaryGenerateRequest.java` | startDate-开始日期, endDate-结束日期 | +| `dto/request/EmotionSummaryStatusRequest.java` | startDate-开始日期, endDate-结束日期 | +| `dto/request/DiaryPostCreateRequest.java` | title-日记标题, content-日记内容, mood-心情, tags-标签 | +| `dto/request/DiaryPostPageRequest.java` | startDate-开始日期, endDate-结束日期, keyword-关键词 | +| `dto/request/DiaryPostUpdateRequest.java` | id-日记 ID, title-标题, content-内容 | +| `dto/request/DiaryCommentCreateRequest.java` | diaryId-日记 ID, content-评论内容, parentId-父评论 ID | +| `dto/request/DiaryCommentPageRequest.java` | diaryId-日记 ID | +| `dto/request/growth/GrowthTopicCreateRequest.java` | title-话题标题, content-话题内容, category-话题分类 | +| `dto/request/growth/GrowthTopicPageRequest.java` | keyword-关键词, category-分类 | +| `dto/request/growth/GrowthTopicUpdateRequest.java` | id-话题 ID, title-标题, content-内容 | +| `dto/request/TopicInteractionCreateRequest.java` | topicId-话题 ID, actionType-互动类型, content-互动内容 | +| `dto/request/TopicInteractionPageRequest.java` | topicId-话题 ID, userId-用户 ID | +| `dto/request/TopicInteractionUpdateRequest.java` | id-互动 ID, content-互动内容 | +| `dto/request/ConversationPageRequest.java` | keyword-关键词, status-会话状态 | +| `dto/request/MessageCreateRequest.java` | conversationId-会话 ID, content-消息内容, messageType-消息类型 | +| `dto/request/MessagePageRequest.java` | conversationId-会话 ID, startDate-开始日期, endDate-结束日期 | +| `dto/request/MessageSearchRequest.java` | conversationId-会话 ID, keyword-搜索关键词 | +| `dto/request/MessageRecentRequest.java` | conversationId-会话 ID, limit-数量限制 | +| `dto/request/userprofile/UserProfileCreateRequest.java` | nickname-昵称, gender-性别, zodiac-星座, profession-职业, mbti-MBTI 人格类型, hobbies-兴趣爱好, childhoodDate-童年经历日期, childhoodContent-童年经历描述, peakDate-高光时刻日期, peakContent-高光时刻描述, valleyDate-低谷时期日期, valleyContent-低谷时期描述, futureVision-未来期许, idealLife-理想生活状态 | +| `dto/request/userprofile/UserProfileUpdateRequest.java` | 同 Create,增加 id-档案 ID | +| `dto/request/userprofile/UserProfilePageRequest.java` | keyword-关键词 | +| `dto/request/achievement/AchievementCreateRequest.java` | name-成就名称, description-成就描述, icon-成就图标, requiredCount-所需次数 | +| `dto/request/achievement/AchievementPageRequest.java` | keyword-关键词, type-成就类型 | +| `dto/request/achievement/AchievementUpdateRequest.java` | id-成就 ID, name-成就名称, description-成就描述 | +| `dto/request/achievement/AchievementProgressUpdateRequest.java` | achievementId-成就 ID, progress-进度值 | +| `dto/request/achievement/AchievementUnlockRequest.java` | achievementId-成就 ID, userId-用户 ID | + +### Batch 3 DTO 列表(21 个文件) + +| 文件路径 | 关键字段 | +|---------|---------| +| `dto/request/LifePathCreateRequest.java` | scriptId-关联剧本 ID, title-路径标题, content-路径内容 | +| `dto/request/LifePathPageRequest.java` | scriptId-剧本 ID | +| `dto/request/LifePathUpdateRequest.java` | id-路径 ID, title-标题, content-内容 | +| `dto/request/reward/RewardCreateRequest.java` | name-奖励名称, description-奖励描述, type-奖励类型, cost-所需积分 | +| `dto/request/reward/RewardPageRequest.java` | keyword-关键词, type-奖励类型 | +| `dto/request/reward/RewardUpdateRequest.java` | id-奖励 ID, name-名称, description-描述 | +| `dto/request/UserStatsCreateRequest.java` | userId-用户 ID, statsKey-统计项键, statsValue-统计值 | +| `dto/request/UserStatsIncrementRequest.java` | userId-用户 ID, statsKey-统计项键, incrementValue-增量值 | +| `dto/request/UserStatsPageRequest.java` | userId-用户 ID, statsKey-统计项键 | +| `dto/request/UserStatsUpdateValueRequest.java` | userId-用户 ID, statsKey-统计项键, newValue-新值 | +| `dto/request/EpicScriptCreateRequest.java` | title-剧本标题, content-剧本内容, inspirationId-灵感 ID | +| `dto/request/EpicScriptUpdateRequest.java` | id-剧本 ID, title-标题, content-内容 | +| `dto/request/EpicScriptPageRequest.java` | keyword-关键词 | +| `dto/request/EpicScriptInspirationRequest.java` | inspirationId-灵感 ID, theme-主题 | +| `dto/request/dictionary/DictionaryCreateRequest.java` | dictType-字典类型, dictKey-字典键, dictValue-字典值 | +| `dto/request/dictionary/DictionaryPageRequest.java` | dictType-字典类型 | +| `dto/request/dictionary/DictionaryUpdateRequest.java` | id-字典 ID, dictValue-字典值 | +| `dto/request/guest/GuestUserCreateRequest.java` | guestId-访客 ID, nickname-昵称 | +| `dto/request/guest/GuestUserPageRequest.java` | keyword-关键词 | +| `dto/request/guest/GuestUserUpdateRequest.java` | id-用户 ID, nickname-昵称 | +| `dto/request/tts/TtsTaskCreateRequest.java` | sourceType-来源类型, sourceId-来源 ID, voice-语音类型 | +| `dto/request/LifeEventCreateRequest.java` | eventType-事件类型, eventDate-事件日期, timeMode-时间模式, title-事件标题, content-事件内容, aiReply-AI 疗愈回复, emotionType-情绪类型, emotionScore-情绪评分, tags-标签 | +| `dto/request/LifeEventUpdateRequest.java` | id-事件 ID, title-标题, content-内容 | +| `dto/request/LifeEventPageRequest.java` | eventType-事件类型, startDate-开始日期, endDate-结束日期 | +| `dto/request/WebSocketRequest.java` | type-消息类型, content-消息内容, conversationId-会话 ID | +| `dto/request/analytics/AnalyticsEventBatchRequest.java` | events-事件列表 | +| `dto/request/aiconfig/AiConfigCreateRequest.java` | configName-配置名称, configKey-配置键值, configType-配置类型, provider-服务提供商, apiBaseUrl-API 地址, apiToken-API 令牌, modelName-模型名称, usageScenario-使用场景 | +| `dto/request/aiconfig/AiConfigUpdateRequest.java` | id-配置 ID + 同 Create 字段 | +| `dto/request/aiconfig/AiConfigPageRequest.java` | keyword-关键词, configType-配置类型 | +| `dto/request/aiconfig/AiConfigEnableRequest.java` | id-配置 ID, enabled-是否启用 | +| `dto/request/aiconfig/AiConfigDefaultRequest.java` | id-配置 ID | +| `dto/request/aiconfig/AiConfigTestUpdateRequest.java` | id-配置 ID, testName-测试名称 | + +### DTO @Schema 注解通用模板 + +对每个 DTO 文件,添加以下 import(如果尚未存在): + +```java +import io.swagger.v3.oas.annotations.media.Schema; +``` + +在类级别添加: + +```java +@Schema(description = "XX 请求") +public class XxxRequest { +``` + +为每个字段添加: + +```java +@Schema(description = "中文描述") +private String fieldName; +``` + +注意:@NotBlank/@NotNull/@Size 等校验注解保持原位置不变,@Schema 放在其上方或下方均可。 + +--- + +## Task 5: 全量验收与最终验证 + +- [ ] **Step 1: 全量编译** + +```bash +cd backend-single +mvn clean install -pl :backend-single -am -DskipTests +``` + +- [ ] **Step 2: 启动服务验证 OpenAPI 同步** + +启动后端服务,访问 Knife4j 文档页面,验证所有接口均以中文描述显示。 + +- [ ] **Step 3: 前端接口管理页面验证** + +访问管理后台接口管理页面,点击"手动同步"按钮,确保所有新注解的接口都能正确同步到数据库。 + +- [ ] **Step 4: 提交所有改动** + +```bash +git add . +git commit -m "feat: 全量 Controller 及 DTO 中文注解补全完成" +```