接口优化

This commit is contained in:
2025-09-08 17:54:12 +08:00
parent e20030f10d
commit d42d689bd7
84 changed files with 6403 additions and 4310 deletions
@@ -1,99 +1,88 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.response.BaseResponse;
import com.emotion.entity.Achievement;
import com.emotion.dto.request.achievement.*;
import com.emotion.dto.response.achievement.AchievementResponse;
import com.emotion.service.AchievementService;
import org.springframework.beans.BeanUtils;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 成就控制器
*
* @author emotion-museum
* @date 2025-07-23
* @date 2025-09-08
*/
@RestController
@RequestMapping("/achievement")
@Tag(name = "成就管理", description = "成就的增删改查功能")
public class AchievementController {
@Autowired
private AchievementService achievementService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询成就
*/
@Operation(summary = "分页查询成就", description = "分页查询成就列表")
@GetMapping("/page")
public Result<PageResult<AchievementResponse>> getPage(@Validated PageRequest request) {
IPage<Achievement> page = achievementService.getPage(request);
List<AchievementResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<AchievementResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
public Result<PageResult<AchievementResponse>> getPage(@Validated AchievementPageRequest request) {
PageResult<AchievementResponse> pageResult = achievementService.getPageWithResponse(request);
return Result.success(pageResult);
}
/**
* 根据ID获取成就
*/
@GetMapping("/{id}")
public Result<AchievementResponse> getById(@PathVariable String id) {
Achievement achievement = achievementService.getById(id);
if (achievement == null) {
@Operation(summary = "根据ID获取成就", description = "根据ID获取成就详情")
@GetMapping("/detail")
public Result<AchievementResponse> getById(@RequestParam String id) {
AchievementResponse response = achievementService.getAchievementResponseById(id);
if (response == null) {
return Result.notFound("成就不存在");
}
return Result.success(convertToResponse(achievement));
return Result.success(response);
}
/**
* 创建成就
*/
@PostMapping
public Result<AchievementResponse> create(@RequestBody Achievement achievement) {
boolean saved = achievementService.save(achievement);
if (!saved) {
@Operation(summary = "创建成就", description = "创建新的成就")
@PostMapping("/create")
public Result<AchievementResponse> create(@RequestBody @Validated AchievementCreateRequest request) {
AchievementResponse response = achievementService.createAchievementWithResponse(request);
if (response == null) {
return Result.error("创建失败");
}
return Result.success(convertToResponse(achievement));
return Result.success("创建成功", response);
}
/**
* 更新成就
*/
@PutMapping("/{id}")
public Result<AchievementResponse> update(@PathVariable String id, @RequestBody Achievement achievement) {
achievement.setId(id);
boolean updated = achievementService.updateById(achievement);
if (!updated) {
@Operation(summary = "更新成就", description = "更新指定成就")
@PutMapping("/update")
public Result<AchievementResponse> update(@RequestBody @Validated AchievementUpdateRequest request) {
AchievementResponse response = achievementService.updateAchievementWithResponse(request);
if (response == null) {
return Result.error("更新失败");
}
Achievement updatedAchievement = achievementService.getById(id);
return Result.success(convertToResponse(updatedAchievement));
return Result.success("更新成功", response);
}
/**
* 删除成就
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
@Operation(summary = "删除成就", description = "删除指定成就")
@DeleteMapping("/delete")
public Result<Void> delete(@RequestParam String id) {
boolean deleted = achievementService.removeById(id);
if (!deleted) {
return Result.error("删除失败");
@@ -104,55 +93,48 @@ public class AchievementController {
/**
* 根据分类查询成就
*/
@GetMapping("/category/{category}")
public Result<List<AchievementResponse>> getByCategory(@PathVariable String category) {
List<Achievement> achievements = achievementService.getByCategory(category);
List<AchievementResponse> responses = achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@Operation(summary = "根据分类查询成就", description = "根据分类查询成就列表")
@GetMapping("/byCategory")
public Result<List<AchievementResponse>> getByCategory(@RequestParam String category) {
List<AchievementResponse> responses = achievementService.getByCategoryWithResponse(category);
return Result.success(responses);
}
/**
* 根据稀有度查询成就
*/
@GetMapping("/rarity/{rarity}")
public Result<List<AchievementResponse>> getByRarity(@PathVariable String rarity) {
List<Achievement> achievements = achievementService.getByRarity(rarity);
List<AchievementResponse> responses = achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@Operation(summary = "根据稀有度查询成就", description = "根据稀有度查询成就列表")
@GetMapping("/byRarity")
public Result<List<AchievementResponse>> getByRarity(@RequestParam String rarity) {
List<AchievementResponse> responses = achievementService.getByRarityWithResponse(rarity);
return Result.success(responses);
}
/**
* 查询已解锁的成就
*/
@Operation(summary = "查询已解锁的成就", description = "查询已解锁的成就列表")
@GetMapping("/unlocked")
public Result<List<AchievementResponse>> getUnlockedAchievements() {
List<Achievement> achievements = achievementService.getUnlockedAchievements();
List<AchievementResponse> responses = achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
List<AchievementResponse> responses = achievementService.getUnlockedAchievementsWithResponse();
return Result.success(responses);
}
/**
* 查询未解锁的成就
*/
@Operation(summary = "查询未解锁的成就", description = "查询未解锁的成就列表")
@GetMapping("/locked")
public Result<List<AchievementResponse>> getLockedAchievements() {
List<Achievement> achievements = achievementService.getLockedAchievements();
List<AchievementResponse> responses = achievements.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
List<AchievementResponse> responses = achievementService.getLockedAchievementsWithResponse();
return Result.success(responses);
}
/**
* 统计已解锁成就数量
*/
@GetMapping("/count/unlocked")
@Operation(summary = "统计已解锁成就数量", description = "统计已解锁成就数量")
@GetMapping("/unlockedCount")
public Result<Long> countUnlockedAchievements() {
Long count = achievementService.countUnlockedAchievements();
return Result.success(count);
@@ -161,7 +143,8 @@ public class AchievementController {
/**
* 统计未解锁成就数量
*/
@GetMapping("/count/locked")
@Operation(summary = "统计未解锁成就数量", description = "统计未解锁成就数量")
@GetMapping("/lockedCount")
public Result<Long> countLockedAchievements() {
Long count = achievementService.countLockedAchievements();
return Result.success(count);
@@ -170,9 +153,10 @@ public class AchievementController {
/**
* 解锁成就
*/
@PutMapping("/{id}/unlock")
public Result<Void> unlockAchievement(@PathVariable String id) {
boolean unlocked = achievementService.unlockAchievement(id, java.time.LocalDateTime.now());
@Operation(summary = "解锁成就", description = "解锁指定成就")
@PutMapping("/unlock")
public Result<Void> unlockAchievement(@RequestBody @Validated AchievementUnlockRequest request) {
boolean unlocked = achievementService.unlockAchievement(request.getId(), LocalDateTime.now());
if (!unlocked) {
return Result.error("解锁失败");
}
@@ -182,9 +166,10 @@ public class AchievementController {
/**
* 更新成就进度
*/
@PutMapping("/{id}/progress")
public Result<Void> updateProgress(@PathVariable String id, @RequestParam Double progress) {
boolean updated = achievementService.updateProgress(id, progress);
@Operation(summary = "更新成就进度", description = "更新指定成就的进度")
@PutMapping("/updateProgress")
public Result<Void> updateProgress(@RequestBody @Validated AchievementProgressUpdateRequest request) {
boolean updated = achievementService.updateProgress(request.getId(), request.getProgress());
if (!updated) {
return Result.error("更新进度失败");
}
@@ -192,36 +177,12 @@ public class AchievementController {
}
/**
* 转换为响应对象
* 查询最近解锁的成就
*/
private AchievementResponse convertToResponse(Achievement achievement) {
AchievementResponse response = new AchievementResponse();
BeanUtils.copyProperties(achievement, response);
response.setId(achievement.getId());
if (achievement.getCreateTime() != null) {
response.setCreateTime(achievement.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (achievement.getUpdateTime() != null) {
response.setUpdateTime(achievement.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return response;
@Operation(summary = "查询最近解锁的成就", description = "查询最近解锁的成就列表")
@GetMapping("/recent")
public Result<List<AchievementResponse>> getRecentlyUnlocked(@RequestParam(defaultValue = "10") Integer limit) {
List<AchievementResponse> responses = achievementService.getRecentlyUnlockedWithResponse(limit);
return Result.success(responses);
}
/**
* 成就响应类
*/
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
public static class AchievementResponse extends BaseResponse {
private String title;
private String description;
private String category;
private String rarity;
private String conditionType;
private String conditionValue;
private Double progress;
private String unlockedTime;
private Integer isHidden;
private String iconUrl;
}
}
}
@@ -5,6 +5,8 @@ import com.emotion.dto.request.AiChatRequest;
import com.emotion.dto.request.AiSummaryRequest;
import com.emotion.dto.request.GuestChatRequest;
import com.emotion.dto.request.ConversationCreateRequest;
import com.emotion.dto.request.ChatStatsRequest;
import com.emotion.dto.request.GuestUserInfoRequest;
import com.emotion.dto.response.AiChatResponse;
import com.emotion.dto.response.AiSummaryResponse;
import com.emotion.dto.response.AiStatusResponse;
@@ -12,19 +14,14 @@ import com.emotion.dto.response.ChatStatsResponse;
import com.emotion.dto.response.GuestChatResponse;
import com.emotion.dto.response.GuestUserInfoResponse;
import com.emotion.dto.response.ConversationResponse;
import com.emotion.entity.Conversation;
import com.emotion.service.AiChatService;
import com.emotion.service.MessageService;
import com.emotion.service.ConversationService;
import com.emotion.util.UserContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import java.util.Map;
/**
* AI聊天控制器
@@ -40,34 +37,16 @@ public class AiChatController {
@Autowired
private AiChatService aiChatService;
@Autowired
private MessageService messageService;
@Autowired
private ConversationService conversationService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 发送聊天消息
*/
@PostMapping("/chat")
public Result<AiChatResponse> sendChatMessage(@Valid @RequestBody AiChatRequest request) {
log.info("收到AI聊天请求: conversationId={}, userId={}, message={}",
request.getConversationId(), request.getUserId(), request.getMessage());
// 调用AI服务
String aiReply = aiChatService.sendChatMessage(request.getConversationId(), request.getMessage(),
request.getUserId());
// 构建响应
AiChatResponse response = new AiChatResponse();
response.setConversationId(request.getConversationId());
response.setUserMessage(request.getMessage());
response.setAiReply(aiReply);
response.setUserId(request.getUserId());
response.setTimestamp(System.currentTimeMillis());
log.info("收到AI聊天请求: conversationId={}, userId={}, message={}",
request.getConversationId(), request.getUserId(), request.getMessage());
// 调用AI服务
AiChatResponse response = aiChatService.sendChatMessage(request);
return Result.success(response);
}
@@ -77,18 +56,9 @@ public class AiChatController {
@PostMapping("/summary")
public Result<AiSummaryResponse> generateSummary(@Valid @RequestBody AiSummaryRequest request) {
log.info("收到对话总结请求: conversationId={}, userId={}", request.getConversationId(), request.getUserId());
// 调用AI总结服务
String summary = aiChatService.generateConversationSummary(request.getConversationId(),
request.getUserId());
// 构建响应
AiSummaryResponse response = new AiSummaryResponse();
response.setConversationId(request.getConversationId());
response.setSummary(summary);
response.setUserId(request.getUserId());
response.setTimestamp(System.currentTimeMillis());
// 调用AI总结服务
AiSummaryResponse response = aiChatService.generateConversationSummary(request);
return Result.success(response);
}
@@ -99,15 +69,7 @@ public class AiChatController {
public Result<AiStatusResponse> getServiceStatus() {
log.info("获取AI服务状态");
boolean available = aiChatService.isServiceAvailable();
String status = aiChatService.getServiceStatus();
// 构建响应
AiStatusResponse response = new AiStatusResponse();
response.setAvailable(available);
response.setStatus(status);
response.setTimestamp(System.currentTimeMillis());
AiStatusResponse response = aiChatService.getServiceStatus();
return Result.success(response);
}
@@ -115,124 +77,48 @@ public class AiChatController {
* 获取聊天记录统计
*/
@GetMapping("/stats")
public Result<ChatStatsResponse> getChatStats(@RequestParam(required = false) String userId,
@RequestParam(required = false) String conversationId) {
log.info("获取聊天统计: userId={}, conversationId={}", userId, conversationId);
public Result<ChatStatsResponse> getChatStats(@Valid ChatStatsRequest request) {
log.info("获取聊天统计: userId={}, conversationId={}", request.getUserId(), request.getConversationId());
// 构建响应
ChatStatsResponse response = new ChatStatsResponse();
if (userId != null && !userId.trim().isEmpty()) {
Long userConversationCount = conversationService.countByUserId(userId);
Long activeConversationCount = conversationService.countActiveByUserId(userId);
response.setUserConversationCount(userConversationCount);
response.setActiveConversationCount(activeConversationCount);
}
if (conversationId != null && !conversationId.trim().isEmpty()) {
Long conversationMessageCount = messageService.countByConversationId(conversationId);
response.setConversationMessageCount(conversationMessageCount);
}
response.setTimestamp(System.currentTimeMillis());
return Result.success(response);
}
/**
* 访客聊天(不需要登录)
*/
@PostMapping("/guest/chat")
public Result<GuestChatResponse> guestChat(@Valid @RequestBody GuestChatRequest request,
HttpServletRequest httpRequest) {
String clientIp = getClientIp(httpRequest);
log.info("访客聊天请求: {}, IP: {}", request.getMessage(), clientIp);
// 调用AI服务
Map<String, Object> aiResponse = aiChatService.guestChat(request.getMessage(), clientIp);
// 构建响应
GuestChatResponse response = new GuestChatResponse();
response.setMessage((String) aiResponse.get("message"));
response.setMessageId((String) aiResponse.get("messageId"));
response.setTimestamp((Long) aiResponse.get("timestamp"));
response.setError((Boolean) aiResponse.get("error"));
return Result.success("发送成功", response);
}
/**
* 获取访客用户信息
*/
@GetMapping("/guest/user/info")
public Result<GuestUserInfoResponse> getGuestUserInfo(HttpServletRequest request) {
String clientIp = getClientIp(request);
log.info("获取访客用户信息: IP={}", clientIp);
// 调用AI服务
Map<String, Object> userInfo = aiChatService.getGuestUserInfo(clientIp);
// 构建响应
GuestUserInfoResponse response = new GuestUserInfoResponse();
response.setId((String) userInfo.get("id"));
response.setUsername((String) userInfo.get("username"));
response.setNickname((String) userInfo.get("nickname"));
response.setType((String) userInfo.get("type"));
response.setClientIp((String) userInfo.get("clientIp"));
response.setUserCreateTime((Long) userInfo.get("createTime"));
return Result.success(response);
}
/**
* 创建对话
*/
@PostMapping("/conversation/create")
public Result<ConversationResponse> createConversation(@Valid @RequestBody ConversationCreateRequest request,
HttpServletRequest httpRequest) {
log.info("创建对话请求: userId={}, title={}", request.getUserId(), request.getTitle());
String clientIp = getClientIp(httpRequest);
// 调用AI服务创建对话
Map<String, Object> aiConversation = aiChatService.createConversation(request.getUserId(),
request.getTitle());
// 创建数据库对话记录
Conversation conversation = conversationService.createConversation(
request.getUserId(),
request.getTitle(),
request.getType() != null ? request.getType() : "user");
// 构建响应
ConversationResponse response = new ConversationResponse();
BeanUtils.copyProperties(conversation, response);
response.setId(conversation.getId());
if (conversation.getCreateTime() != null) {
response.setCreateTime(conversation.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (conversation.getUpdateTime() != null) {
response.setUpdateTime(conversation.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return Result.success("创建成功", response);
ChatStatsResponse response = aiChatService.getChatStats(request);
return Result.success(response);
}
/**
* 获取客户端IP
* 访客聊天(不需要登录)
*/
private String getClientIp(HttpServletRequest request) {
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
return xForwardedFor.split(",")[0].trim();
}
@PostMapping("/guestChat")
public Result<GuestChatResponse> guestChat(@Valid @RequestBody GuestChatRequest request,
HttpServletRequest httpRequest) {
String clientIp = UserContextUtils.getClientIpAddress(httpRequest);
log.info("访客聊天请求: {}, IP: {}", request.getMessage(), clientIp);
String xRealIp = request.getHeader("X-Real-IP");
if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
return xRealIp;
}
return request.getRemoteAddr();
GuestChatResponse response = aiChatService.guestChat(request, clientIp);
return Result.success("发送成功", response);
}
}
/**
* 获取访客用户信息
*/
@GetMapping("/guestUserInfo")
public Result<GuestUserInfoResponse> getGuestUserInfo(HttpServletRequest request) {
String clientIp = UserContextUtils.getClientIpAddress(request);
log.info("获取访客用户信息: IP={}", clientIp);
GuestUserInfoResponse response = aiChatService.getGuestUserInfo(clientIp);
return Result.success(response);
}
/**
* 创建对话
*/
@PostMapping("/createConversation")
public Result<ConversationResponse> createConversation(@Valid @RequestBody ConversationCreateRequest request,
HttpServletRequest httpRequest) {
log.info("创建对话请求: userId={}, title={}", request.getUserId(), request.getTitle());
String clientIp = UserContextUtils.getClientIpAddress(httpRequest);
ConversationResponse response = aiChatService.createConversation(request, clientIp);
return Result.success("创建成功", response);
}
}
@@ -9,6 +9,7 @@ import com.emotion.dto.response.CaptchaResponse;
import com.emotion.dto.response.UserInfoResponse;
import com.emotion.service.AuthService;
import com.emotion.service.TokenService;
import com.emotion.util.UserContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -52,10 +53,9 @@ public class AuthController {
/**
* 获取当前用户信息
*/
@GetMapping("/user/info")
@GetMapping("/userInfo")
public Result<UserInfoResponse> getCurrentUserInfo(HttpServletRequest request) {
String token = extractToken(request);
UserInfoResponse userInfo = tokenService.getUserInfoByToken(token);
UserInfoResponse userInfo = tokenService.getUserInfoByToken(request);
return Result.success(userInfo);
}
@@ -73,15 +73,14 @@ public class AuthController {
*/
@PostMapping("/logout")
public Result<Void> logout(HttpServletRequest request) {
String token = extractToken(request);
authService.logoutByToken(token);
authService.logoutByToken(request);
return Result.success();
}
/**
* 刷新访问令牌
*/
@PostMapping("/refresh")
@PostMapping("/refreshToken")
public Result<AuthResponse> refreshToken(@Valid @RequestBody RefreshTokenRequest request) {
AuthResponse response = authService.refreshToken(request.getRefreshToken());
return Result.success("令牌刷新成功", response);
@@ -90,14 +89,9 @@ public class AuthController {
/**
* 验证访问令牌
*/
@GetMapping("/validate")
@GetMapping("/validateToken")
public Result<Boolean> validateToken(HttpServletRequest request) {
String token = extractToken(request);
if (token == null) {
return Result.success(false);
}
boolean isValid = authService.validateToken(token);
boolean isValid = authService.validateToken(request);
return Result.success(isValid);
}
@@ -106,15 +100,14 @@ public class AuthController {
*/
@GetMapping("/username")
public Result<String> getUsernameFromToken(HttpServletRequest request) {
String token = extractToken(request);
String username = tokenService.getUsernameByToken(token);
String username = tokenService.getUsernameByToken(request);
return Result.success(username);
}
/**
* 检查账号是否存在
*/
@GetMapping("/check-account")
@GetMapping("/checkAccount")
public Result<Boolean> checkAccount(@RequestParam String account) {
boolean exists = authService.existsByAccount(account);
return Result.success(exists);
@@ -123,7 +116,7 @@ public class AuthController {
/**
* 检查邮箱是否存在
*/
@GetMapping("/check-email")
@GetMapping("/checkEmail")
public Result<Boolean> checkEmail(@RequestParam String email) {
boolean exists = authService.existsByEmail(email);
return Result.success(exists);
@@ -132,27 +125,9 @@ public class AuthController {
/**
* 检查手机号是否存在
*/
@GetMapping("/check-phone")
@GetMapping("/checkPhone")
public Result<Boolean> checkPhone(@RequestParam String phone) {
boolean exists = authService.existsByPhone(phone);
return Result.success(exists);
}
/**
* 从请求中提取访问令牌
*/
private String extractToken(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
return authHeader.substring(7);
}
// 也可以从请求参数中获取
String tokenParam = request.getParameter("token");
if (tokenParam != null && !tokenParam.trim().isEmpty()) {
return tokenParam.trim();
}
return null;
}
}
@@ -1,6 +1,6 @@
package com.emotion.controller;
import com.emotion.dto.websocket.ChatRequest;
import com.emotion.dto.request.WebSocketRequest;
import com.emotion.dto.websocket.ConnectRequest;
import com.emotion.service.WebSocketService;
import lombok.extern.slf4j.Slf4j;
@@ -14,14 +14,15 @@ import javax.validation.Valid;
import java.security.Principal;
/**
* 优化的WebSocket聊天控制器
* 使用规范的请求对象封装参数
* WebSocket聊天控制器
* 使用规范的请求对象封装参数,符合项目开发规则
*
* @author emotion-museum
* @date 2025-07-23
* @date 2025-09-08
*/
@Slf4j
@Controller
@MessageMapping("/chat")
public class ChatWebSocketController {
@Autowired
@@ -29,111 +30,55 @@ public class ChatWebSocketController {
/**
* 处理聊天消息
* @param chatRequest 聊天请求对象
* @param headerAccessor 消息头访问器
* @param principal 用户主体
*
* @param webSocketRequest WebSocket请求对象
* @param headerAccessor 消息头访问器
* @param principal 用户主体
*/
@MessageMapping("/chat.send")
public void handleChatMessage(@Valid @Payload ChatRequest chatRequest,
SimpMessageHeaderAccessor headerAccessor,
Principal principal) {
try {
log.info("收到WebSocket聊天消息: {}", chatRequest);
// 获取会话ID
String sessionId = headerAccessor.getSessionId();
// 如果请求中没有发送者ID,尝试从Principal获取
if (chatRequest.getSenderId() == null && principal != null) {
chatRequest.setSenderId(principal.getName());
}
// 如果还是没有发送者ID,使用会话ID作为访客ID
if (chatRequest.getSenderId() == null) {
chatRequest.setSenderId("guest_" + sessionId);
chatRequest.setSenderType(ChatRequest.SenderType.GUEST);
}
// 设置时间戳
if (chatRequest.getTimestamp() == null) {
chatRequest.setTimestamp(System.currentTimeMillis());
}
// 处理聊天消息
webSocketService.handleChatMessage(chatRequest, sessionId, principal);
} catch (Exception e) {
log.error("处理WebSocket聊天消息失败", e);
}
@MessageMapping("/send")
public void handleChatMessage(@Valid @Payload WebSocketRequest webSocketRequest,
SimpMessageHeaderAccessor headerAccessor,
Principal principal) {
String sessionId = headerAccessor.getSessionId();
webSocketService.handleChatMessage(webSocketRequest, sessionId, principal);
}
/**
* 处理用户连接
*
* @param connectRequest 连接请求对象
* @param headerAccessor 消息头访问器
* @param principal 用户主体
* @param principal 用户主体
*/
@MessageMapping("/chat.connect")
@MessageMapping("/connect")
public void connectUser(@Payload ConnectRequest connectRequest,
SimpMessageHeaderAccessor headerAccessor,
Principal principal) {
try {
String sessionId = headerAccessor.getSessionId();
log.info("用户连接WebSocket: connectRequest={}, sessionId={}, principal={}",
connectRequest, sessionId, principal);
// 如果请求中没有用户ID,尝试从Principal获取
if (connectRequest.getUserId() == null && principal != null) {
connectRequest.setUserId(principal.getName());
}
// 设置连接时间戳
if (connectRequest.getTimestamp() == null) {
connectRequest.setTimestamp(System.currentTimeMillis());
}
// 处理用户连接
webSocketService.handleUserConnect(connectRequest, sessionId, principal);
} catch (Exception e) {
log.error("处理用户WebSocket连接失败", e);
}
SimpMessageHeaderAccessor headerAccessor,
Principal principal) {
String sessionId = headerAccessor.getSessionId();
webSocketService.handleUserConnect(connectRequest, sessionId, principal);
}
/**
* 处理用户断开连接
*
* @param headerAccessor 消息头访问器
* @param principal 用户主体
* @param principal 用户主体
*/
@MessageMapping("/chat.disconnect")
@MessageMapping("/disconnect")
public void disconnectUser(SimpMessageHeaderAccessor headerAccessor, Principal principal) {
try {
String sessionId = headerAccessor.getSessionId();
log.info("用户断开WebSocket连接: sessionId={}, principal={}", sessionId, principal);
// 处理用户断开连接
webSocketService.handleUserDisconnect(sessionId, principal);
} catch (Exception e) {
log.error("处理用户WebSocket断开连接失败", e);
}
String sessionId = headerAccessor.getSessionId();
webSocketService.handleUserDisconnect(sessionId, principal);
}
/**
* 处理心跳消息
*
* @param headerAccessor 消息头访问器
* @param principal 用户主体
* @param principal 用户主体
*/
@MessageMapping("/chat.heartbeat")
@MessageMapping("/heartbeat")
public void heartbeat(SimpMessageHeaderAccessor headerAccessor, Principal principal) {
try {
String sessionId = headerAccessor.getSessionId();
// 处理心跳消息
webSocketService.handleHeartbeat(sessionId, principal);
} catch (Exception e) {
log.error("处理WebSocket心跳失败", e);
}
String sessionId = headerAccessor.getSessionId();
webSocketService.handleHeartbeat(sessionId, principal);
}
}
}
@@ -1,22 +1,17 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.response.BaseResponse;
import com.emotion.entity.Comment;
import com.emotion.dto.request.comment.CommentCreateRequest;
import com.emotion.dto.request.comment.CommentUpdateRequest;
import com.emotion.dto.request.comment.CommentPageRequest;
import com.emotion.dto.response.comment.CommentResponse;
import com.emotion.service.CommentService;
import org.springframework.beans.BeanUtils;
import com.emotion.util.UserContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 评论控制器
*
@@ -30,114 +25,44 @@ public class CommentController {
@Autowired
private CommentService commentService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询评论
*/
@GetMapping("/page")
public Result<PageResult<CommentResponse>> getPage(@Validated PageRequest request) {
IPage<Comment> page = commentService.getPage(request);
List<CommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
@GetMapping(value = "/page")
public Result<PageResult<CommentResponse>> getCommentPage(@Validated CommentPageRequest request) {
PageResult<CommentResponse> pageResult = commentService.getPage(request);
return Result.success(pageResult);
}
/**
* 根据帖子ID分页查询评论
*/
@GetMapping("/post/{postId}/page")
public Result<PageResult<CommentResponse>> getPageByPostId(@PathVariable String postId, @Validated PageRequest request) {
IPage<Comment> page = commentService.getPageByPostId(request, postId);
List<CommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询评论
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<CommentResponse>> getPageByUserId(@PathVariable String userId, @Validated PageRequest request) {
IPage<Comment> page = commentService.getPageByUserId(request, userId);
List<CommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据ID获取评论
*/
@GetMapping("/{id}")
public Result<CommentResponse> getById(@PathVariable String id) {
Comment comment = commentService.getById(id);
if (comment == null) {
return Result.notFound("评论不存在");
}
return Result.success(convertToResponse(comment));
}
/**
* 创建评论
*/
@PostMapping
public Result<CommentResponse> create(@RequestBody @Validated CommentCreateRequest request) {
Comment comment = commentService.createComment(
request.getPostId(),
request.getUserId(),
request.getContent(),
request.getReplyToId()
);
return Result.success(convertToResponse(comment));
@PostMapping(value = "/create")
public Result<CommentResponse> createComment(@RequestBody @Validated CommentCreateRequest request) {
// 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID
String currentUserId = UserContextUtils.getCurrentUserId();
if (currentUserId != null) {
request.setUserId(currentUserId);
}
CommentResponse response = commentService.create(request);
return Result.success(response);
}
/**
* 更新评论
*/
@PutMapping("/{id}")
public Result<CommentResponse> update(@PathVariable String id, @RequestBody Comment comment) {
comment.setId(id);
boolean updated = commentService.updateById(comment);
if (!updated) {
return Result.error("更新失败");
}
Comment updatedComment = commentService.getById(id);
return Result.success(convertToResponse(updatedComment));
@PutMapping(value = "/update")
public Result<CommentResponse> updateComment(@RequestBody @Validated CommentUpdateRequest request) {
CommentResponse response = commentService.update(request);
return Result.success(response);
}
/**
* 删除评论
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
boolean deleted = commentService.removeById(id);
@DeleteMapping(value = "/delete")
public Result<Void> deleteComment(@RequestParam String id) {
boolean deleted = commentService.delete(id);
if (!deleted) {
return Result.error("删除失败");
}
@@ -145,105 +70,14 @@ public class CommentController {
}
/**
* 根据帖子ID查询顶级评论
* 根据ID获取评论
*/
@GetMapping("/post/{postId}/top-level")
public Result<List<CommentResponse>> getTopLevelCommentsByPostId(@PathVariable String postId) {
List<Comment> comments = commentService.getTopLevelCommentsByPostId(postId);
List<CommentResponse> responses = comments.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 根据评论ID查询回复
*/
@GetMapping("/{commentId}/replies")
public Result<List<CommentResponse>> getRepliesByCommentId(@PathVariable String commentId) {
List<Comment> replies = commentService.getRepliesByCommentId(commentId);
List<CommentResponse> responses = replies.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 统计帖子的评论数量
*/
@GetMapping("/post/{postId}/count")
public Result<Long> countByPostId(@PathVariable String postId) {
Long count = commentService.countByPostId(postId);
return Result.success(count);
}
/**
* 点赞评论
*/
@PutMapping("/{id}/like")
public Result<Void> likeComment(@PathVariable String id) {
boolean updated = commentService.updateLikes(id, 1);
if (!updated) {
return Result.error("点赞失败");
@GetMapping(value = "/detail")
public Result<CommentResponse> getCommentById(@RequestParam String id) {
CommentResponse response = commentService.getById(id);
if (response == null) {
return Result.notFound("评论不存在");
}
return Result.success();
return Result.success(response);
}
/**
* 取消点赞评论
*/
@PutMapping("/{id}/unlike")
public Result<Void> unlikeComment(@PathVariable String id) {
boolean updated = commentService.updateLikes(id, -1);
if (!updated) {
return Result.error("取消点赞失败");
}
return Result.success();
}
/**
* 转换为响应对象
*/
private CommentResponse convertToResponse(Comment comment) {
CommentResponse response = new CommentResponse();
BeanUtils.copyProperties(comment, response);
response.setId(comment.getId());
if (comment.getCreateTime() != null) {
response.setCreateTime(comment.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (comment.getUpdateTime() != null) {
response.setUpdateTime(comment.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return response;
}
/**
* 评论创建请求
*/
@lombok.Data
public static class CommentCreateRequest {
@NotBlank(message = "帖子ID不能为空")
private String postId;
@NotBlank(message = "用户ID不能为空")
private String userId;
@NotBlank(message = "评论内容不能为空")
private String content;
private String replyToId;
}
/**
* 评论响应类
*/
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
public static class CommentResponse extends BaseResponse {
private String postId;
private String userId;
private String content;
private String replyToId;
private Integer likes;
}
}
}
@@ -1,22 +1,16 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.response.BaseResponse;
import com.emotion.entity.CommunityPost;
import com.emotion.dto.request.community.CommunityPostCreateRequest;
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 org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 社区帖子控制器
*
@@ -24,266 +18,60 @@ import java.util.stream.Collectors;
* @date 2025-07-23
*/
@RestController
@RequestMapping("/community-post")
@RequestMapping("/communityPost")
public class CommunityPostController {
@Autowired
private CommunityPostService communityPostService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询帖子
*/
@GetMapping("/page")
public Result<PageResult<CommunityPostResponse>> getPage(@Validated PageRequest request) {
IPage<CommunityPost> page = communityPostService.getPage(request);
List<CommunityPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommunityPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 分页查询公开帖子
*/
@GetMapping("/public/page")
public Result<PageResult<CommunityPostResponse>> getPublicPostsPage(@Validated PageRequest request) {
IPage<CommunityPost> page = communityPostService.getPublicPostsPage(request);
List<CommunityPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommunityPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询帖子
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<CommunityPostResponse>> getPageByUserId(@PathVariable String userId, @Validated PageRequest request) {
IPage<CommunityPost> page = communityPostService.getPageByUserId(request, userId);
List<CommunityPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CommunityPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
@GetMapping(value = "/page")
public Result<PageResult<CommunityPostResponse>> getPage(@Validated CommunityPostPageRequest request) {
PageResult<CommunityPostResponse> pageResult = communityPostService.getPage(request);
return Result.success(pageResult);
}
/**
* 根据ID获取帖子
*/
@GetMapping("/{id}")
public Result<CommunityPostResponse> getById(@PathVariable String id) {
CommunityPost post = communityPostService.getById(id);
if (post == null) {
@GetMapping(value = "/detail")
public Result<CommunityPostResponse> getById(@RequestParam String id) {
CommunityPostResponse response = communityPostService.getById(id);
if (response == null) {
return Result.notFound("帖子不存在");
}
// 增加浏览数
communityPostService.incrementViewCount(id);
return Result.success(convertToResponse(post));
return Result.success(response);
}
/**
* 创建帖子
*/
@PostMapping
@PostMapping(value = "/create")
public Result<CommunityPostResponse> create(@RequestBody @Validated CommunityPostCreateRequest request) {
CommunityPost post = communityPostService.createPost(
request.getUserId(),
request.getTitle(),
request.getContent(),
request.getType(),
request.getLocationId(),
request.getTags(),
request.getIsPrivate()
);
return Result.success(convertToResponse(post));
CommunityPostResponse response = communityPostService.create(request);
return Result.success(response);
}
/**
* 更新帖子
*/
@PutMapping("/{id}")
public Result<CommunityPostResponse> update(@PathVariable String id, @RequestBody CommunityPost post) {
post.setId(id);
boolean updated = communityPostService.updateById(post);
if (!updated) {
return Result.error("更新失败");
}
CommunityPost updatedPost = communityPostService.getById(id);
return Result.success(convertToResponse(updatedPost));
@PutMapping(value = "/update")
public Result<CommunityPostResponse> update(@RequestBody @Validated CommunityPostUpdateRequest request) {
CommunityPostResponse response = communityPostService.update(request);
return Result.success(response);
}
/**
* 删除帖子
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
boolean deleted = communityPostService.removeById(id);
@DeleteMapping(value = "/delete")
public Result<Void> delete(@RequestParam String id) {
boolean deleted = communityPostService.delete(id);
if (!deleted) {
return Result.error("删除失败");
}
return Result.success();
}
/**
* 根据类型查询帖子
*/
@GetMapping("/type/{type}")
public Result<List<CommunityPostResponse>> getByType(@PathVariable String type) {
List<CommunityPost> posts = communityPostService.getByType(type);
List<CommunityPostResponse> responses = posts.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 根据地点ID查询帖子
*/
@GetMapping("/location/{locationId}")
public Result<List<CommunityPostResponse>> getByLocationId(@PathVariable String locationId) {
List<CommunityPost> posts = communityPostService.getByLocationId(locationId);
List<CommunityPostResponse> responses = posts.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 查询最受欢迎的帖子
*/
@GetMapping("/popular")
public Result<List<CommunityPostResponse>> getMostLikedPosts(@RequestParam(defaultValue = "10") Integer limit) {
List<CommunityPost> posts = communityPostService.getMostLikedPosts(limit);
List<CommunityPostResponse> responses = posts.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 查询最新的帖子
*/
@GetMapping("/latest")
public Result<List<CommunityPostResponse>> getLatestPosts(@RequestParam(defaultValue = "10") Integer limit) {
List<CommunityPost> posts = communityPostService.getLatestPosts(limit);
List<CommunityPostResponse> responses = posts.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 点赞帖子
*/
@PutMapping("/{id}/like")
public Result<Void> likePost(@PathVariable String id) {
boolean updated = communityPostService.updateLikes(id, 1);
if (!updated) {
return Result.error("点赞失败");
}
return Result.success();
}
/**
* 取消点赞帖子
*/
@PutMapping("/{id}/unlike")
public Result<Void> unlikePost(@PathVariable String id) {
boolean updated = communityPostService.updateLikes(id, -1);
if (!updated) {
return Result.error("取消点赞失败");
}
return Result.success();
}
/**
* 根据标签搜索帖子
*/
@GetMapping("/search/tag")
public Result<List<CommunityPostResponse>> getByTag(@RequestParam String tag) {
List<CommunityPost> posts = communityPostService.getByTag(tag);
List<CommunityPostResponse> responses = posts.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 转换为响应对象
*/
private CommunityPostResponse convertToResponse(CommunityPost post) {
CommunityPostResponse response = new CommunityPostResponse();
BeanUtils.copyProperties(post, response);
response.setId(post.getId());
if (post.getCreateTime() != null) {
response.setCreateTime(post.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (post.getUpdateTime() != null) {
response.setUpdateTime(post.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return response;
}
/**
* 帖子创建请求
*/
@lombok.Data
public static class CommunityPostCreateRequest {
@NotBlank(message = "用户ID不能为空")
private String userId;
@NotBlank(message = "标题不能为空")
private String title;
@NotBlank(message = "内容不能为空")
private String content;
private String type;
private String locationId;
private String tags;
private Integer isPrivate;
}
/**
* 帖子响应类
*/
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
public static class CommunityPostResponse extends BaseResponse {
private String userId;
private String title;
private String content;
private String type;
private String locationId;
private String tags;
private Integer likes;
private Integer viewCount;
private Integer commentCount;
private Integer isPrivate;
}
}
}
@@ -1,22 +1,17 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.request.ConversationCreateRequest;
import com.emotion.dto.request.ConversationPageRequest;
import com.emotion.dto.response.ConversationResponse;
import com.emotion.entity.Conversation;
import com.emotion.service.ConversationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 对话控制器
@@ -31,95 +26,51 @@ public class ConversationController {
@Autowired
private ConversationService conversationService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询对话
*/
@GetMapping("/page")
public Result<PageResult<ConversationResponse>> getPage(@Valid PageRequest request) {
IPage<Conversation> page = conversationService.getPage(request);
List<ConversationResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<ConversationResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询对话
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<ConversationResponse>> getPageByUserId(@PathVariable String userId,
@Valid PageRequest request) {
IPage<Conversation> page = conversationService.getPageByUserId(request, userId);
List<ConversationResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<ConversationResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
@GetMapping(value = "/page")
public Result<PageResult<ConversationResponse>> getPage(@Valid ConversationPageRequest request) {
PageResult<ConversationResponse> pageResult = conversationService.getPageWithResponse(request);
return Result.success(pageResult);
}
/**
* 根据ID获取对话
*/
@GetMapping("/{id}")
public Result<ConversationResponse> getById(@PathVariable String id) {
Conversation conversation = conversationService.getById(id);
if (conversation == null) {
@GetMapping(value = "/detail")
public Result<ConversationResponse> getById(@RequestParam String id) {
ConversationResponse response = conversationService.getConversationResponseById(id);
if (response == null) {
return Result.notFound("对话不存在");
}
return Result.success(convertToResponse(conversation));
return Result.success(response);
}
/**
* 创建对话
*/
@PostMapping
@PostMapping(value = "/create")
public Result<ConversationResponse> create(@Valid @RequestBody ConversationCreateRequest request,
HttpServletRequest httpRequest) {
String clientIp = getClientIp(httpRequest);
Conversation conversation = conversationService.createConversation(
request.getUserId(),
request.getTitle(),
null // cozeConversationId
);
return Result.success(convertToResponse(conversation));
ConversationResponse response = conversationService.createConversationWithResponse(request, httpRequest);
return Result.success(response);
}
/**
* 更新对话
*/
@PutMapping("/{id}")
public Result<ConversationResponse> update(@PathVariable String id, @RequestBody Conversation conversation) {
conversation.setId(id);
boolean updated = conversationService.updateById(conversation);
if (!updated) {
return Result.error("更新失败");
}
Conversation updatedConversation = conversationService.getById(id);
return Result.success(convertToResponse(updatedConversation));
@PutMapping(value = "/update")
public Result<ConversationResponse> update(@RequestBody ConversationCreateRequest request) {
ConversationResponse response = conversationService.updateConversationWithResponse(request);
return Result.success(response);
}
/**
* 删除对话
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
@DeleteMapping(value = "/delete")
public Result<Void> delete(@RequestParam String id) {
boolean deleted = conversationService.removeById(id);
if (!deleted) {
return Result.error("删除失败");
@@ -127,93 +78,35 @@ public class ConversationController {
return Result.success();
}
/**
* 根据用户ID查询对话
*/
@GetMapping("/user/{userId}")
public Result<List<ConversationResponse>> getByUserId(@PathVariable String userId) {
List<Conversation> conversations = conversationService.getByUserId(userId);
List<ConversationResponse> responses = conversations.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 获取活跃对话
*/
@GetMapping("/active")
@GetMapping(value = "/active")
public Result<List<ConversationResponse>> getActiveConversations() {
// 暂时返回空列表,因为接口中没有这个方法
return Result.success();
List<ConversationResponse> responses = conversationService.getActiveConversationsWithResponse();
return Result.success(responses);
}
/**
* 获取归档对话
*/
@GetMapping("/archived")
@GetMapping(value = "/archived")
public Result<List<ConversationResponse>> getArchivedConversations() {
// 暂时返回空列表,因为接口中没有这个方法
List<ConversationResponse> responses = conversationService.getArchivedConversationsWithResponse();
return Result.success(responses);
}
/**
* 更新对话状态
*/
@PutMapping(value = "/status")
public Result<Void> updateConversationStatus(
@RequestParam String id,
@RequestParam String status) {
boolean updated = conversationService.updateConversationStatus(id, status);
if (!updated) {
return Result.error("更新状态失败");
}
return Result.success();
}
/**
* 归档对话
*/
@PutMapping("/{id}/archive")
public Result<Void> archiveConversation(@PathVariable String id) {
// 暂时返回成功,因为接口中没有这个方法
return Result.success();
}
/**
* 激活对话
*/
@PutMapping("/{id}/activate")
public Result<Void> activateConversation(@PathVariable String id) {
// 暂时返回成功,因为接口中没有这个方法
return Result.success();
}
/**
* 统计用户对话数量
*/
@GetMapping("/user/{userId}/count")
public Result<Long> countByUserId(@PathVariable String userId) {
Long count = conversationService.countByUserId(userId);
return Result.success(count);
}
/**
* 获取客户端IP
*/
private String getClientIp(HttpServletRequest request) {
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
return xForwardedFor.split(",")[0];
}
String xRealIp = request.getHeader("X-Real-IP");
if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
return xRealIp;
}
return request.getRemoteAddr();
}
/**
* 转换为响应对象
*/
private ConversationResponse convertToResponse(Conversation conversation) {
ConversationResponse response = new ConversationResponse();
BeanUtils.copyProperties(conversation, response);
response.setId(conversation.getId());
if (conversation.getCreateTime() != null) {
response.setCreateTime(conversation.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (conversation.getUpdateTime() != null) {
response.setUpdateTime(conversation.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return response;
}
}
}
@@ -1,20 +1,17 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.response.BaseResponse;
import com.emotion.entity.CozeApiCall;
import com.emotion.dto.request.coze.CozeApiCallPageRequest;
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 org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import java.math.BigDecimal;
/**
* Coze API调用记录控制器
@@ -29,229 +26,54 @@ public class CozeApiCallController {
@Autowired
private CozeApiCallService cozeApiCallService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询API调用记录
*/
@GetMapping("/page")
public Result<PageResult<CozeApiCallResponse>> getPage(@Validated PageRequest request) {
IPage<CozeApiCall> page = cozeApiCallService.getPage(request);
List<CozeApiCallResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CozeApiCallResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据会话ID分页查询API调用记录
*/
@GetMapping("/conversation/{conversationId}/page")
public Result<PageResult<CozeApiCallResponse>> getPageByConversationId(@PathVariable String conversationId, @Validated PageRequest request) {
IPage<CozeApiCall> page = cozeApiCallService.getPageByConversationId(request, conversationId);
List<CozeApiCallResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CozeApiCallResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询API调用记录
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<CozeApiCallResponse>> getPageByUserId(@PathVariable String userId, @Validated PageRequest request) {
IPage<CozeApiCall> page = cozeApiCallService.getPageByUserId(request, userId);
List<CozeApiCallResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<CozeApiCallResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
@GetMapping(value = "/page")
public Result<PageResult<CozeApiCallResponse>> getCozeApiCallPage(@Validated CozeApiCallPageRequest request) {
PageResult<CozeApiCallResponse> pageResult = cozeApiCallService.getPage(request);
return Result.success(pageResult);
}
/**
* 根据ID获取API调用记录
*/
@GetMapping("/{id}")
public Result<CozeApiCallResponse> getById(@PathVariable String id) {
CozeApiCall apiCall = cozeApiCallService.getById(id);
if (apiCall == null) {
@GetMapping(value = "/detail")
public Result<CozeApiCallResponse> getCozeApiCallById(@RequestParam String id) {
CozeApiCallResponse response = cozeApiCallService.getById(id);
if (response == null) {
return Result.notFound("API调用记录不存在");
}
return Result.success(convertToResponse(apiCall));
}
/**
* 根据Bot ID查询API调用记录
*/
@GetMapping("/bot/{botId}")
public Result<List<CozeApiCallResponse>> getByBotId(@PathVariable String botId) {
List<CozeApiCall> apiCalls = cozeApiCallService.getByBotId(botId);
List<CozeApiCallResponse> responses = apiCalls.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 根据状态查询API调用记录
*/
@GetMapping("/status/{status}")
public Result<List<CozeApiCallResponse>> getByStatus(@PathVariable String status) {
List<CozeApiCall> apiCalls = cozeApiCallService.getByStatus(status);
List<CozeApiCallResponse> responses = apiCalls.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 根据请求类型查询API调用记录
*/
@GetMapping("/request-type/{requestType}")
public Result<List<CozeApiCallResponse>> getByRequestType(@PathVariable String requestType) {
List<CozeApiCall> apiCalls = cozeApiCallService.getByRequestType(requestType);
List<CozeApiCallResponse> responses = apiCalls.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 统计用户的API调用次数
*/
@GetMapping("/user/{userId}/count")
public Result<Long> countByUserId(@PathVariable String userId) {
Long count = cozeApiCallService.countByUserId(userId);
return Result.success(count);
}
/**
* 统计Bot的API调用次数
*/
@GetMapping("/bot/{botId}/count")
public Result<Long> countByBotId(@PathVariable String botId) {
Long count = cozeApiCallService.countByBotId(botId);
return Result.success(count);
}
/**
* 统计指定状态的API调用次数
*/
@GetMapping("/status/{status}/count")
public Result<Long> countByStatus(@PathVariable String status) {
Long count = cozeApiCallService.countByStatus(status);
return Result.success(count);
}
/**
* 统计用户的Token使用量
*/
@GetMapping("/user/{userId}/tokens")
public Result<Long> sumTokensByUserId(@PathVariable String userId) {
Long totalTokens = cozeApiCallService.sumTokensByUserId(userId);
return Result.success(totalTokens);
}
/**
* 统计用户的API调用费用
*/
@GetMapping("/user/{userId}/cost")
public Result<java.math.BigDecimal> sumCostByUserId(@PathVariable String userId) {
java.math.BigDecimal totalCost = cozeApiCallService.sumCostByUserId(userId);
return Result.success(totalCost);
}
/**
* 查询失败的API调用记录
*/
@GetMapping("/failed")
public Result<List<CozeApiCallResponse>> getFailedCalls() {
List<CozeApiCall> apiCalls = cozeApiCallService.getFailedCalls();
List<CozeApiCallResponse> responses = apiCalls.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 查询超时的API调用记录
*/
@GetMapping("/timeout")
public Result<List<CozeApiCallResponse>> getTimeoutCalls() {
List<CozeApiCall> apiCalls = cozeApiCallService.getTimeoutCalls();
List<CozeApiCallResponse> responses = apiCalls.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
return Result.success(responses);
}
/**
* 根据追踪ID查询API调用记录
*/
@GetMapping("/trace/{traceId}")
public Result<CozeApiCallResponse> getByTraceId(@PathVariable String traceId) {
CozeApiCall apiCall = cozeApiCallService.getByTraceId(traceId);
if (apiCall == null) {
return Result.notFound("API调用记录不存在");
}
return Result.success(convertToResponse(apiCall));
return Result.success(response);
}
/**
* 创建API调用记录
*/
@PostMapping
public Result<CozeApiCallResponse> create(@RequestBody CozeApiCall apiCall) {
boolean saved = cozeApiCallService.save(apiCall);
if (!saved) {
return Result.error("创建失败");
}
return Result.success(convertToResponse(apiCall));
@PostMapping(value = "/create")
public Result<CozeApiCallResponse> createCozeApiCall(@RequestBody @Validated CozeApiCallCreateRequest request) {
CozeApiCallResponse response = cozeApiCallService.create(request);
return Result.success(response);
}
/**
* 更新API调用记录
*/
@PutMapping("/{id}")
public Result<CozeApiCallResponse> update(@PathVariable String id, @RequestBody CozeApiCall apiCall) {
apiCall.setId(id);
boolean updated = cozeApiCallService.updateById(apiCall);
if (!updated) {
return Result.error("更新失败");
@PutMapping(value = "/update")
public Result<CozeApiCallResponse> updateCozeApiCall(@RequestBody @Validated CozeApiCallUpdateRequest request) {
CozeApiCallResponse response = cozeApiCallService.update(request);
if (response == null) {
return Result.error("更新失败,记录不存在");
}
CozeApiCall updatedApiCall = cozeApiCallService.getById(id);
return Result.success(convertToResponse(updatedApiCall));
return Result.success(response);
}
/**
* 删除API调用记录
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
boolean deleted = cozeApiCallService.removeById(id);
@DeleteMapping(value = "/delete")
public Result<Void> deleteCozeApiCall(@RequestParam String id) {
boolean deleted = cozeApiCallService.delete(id);
if (!deleted) {
return Result.error("删除失败");
}
@@ -259,49 +81,47 @@ public class CozeApiCallController {
}
/**
* 转换为响应对象
* 统计用户的API调用次数
*/
private CozeApiCallResponse convertToResponse(CozeApiCall apiCall) {
CozeApiCallResponse response = new CozeApiCallResponse();
BeanUtils.copyProperties(apiCall, response);
response.setId(apiCall.getId());
if (apiCall.getCreateTime() != null) {
response.setCreateTime(apiCall.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (apiCall.getUpdateTime() != null) {
response.setUpdateTime(apiCall.getUpdateTime().format(DATE_TIME_FORMATTER));
}
if (apiCall.getStartTime() != null) {
response.setStartTime(apiCall.getStartTime().format(DATE_TIME_FORMATTER));
}
if (apiCall.getEndTime() != null) {
response.setEndTime(apiCall.getEndTime().format(DATE_TIME_FORMATTER));
}
return response;
@GetMapping(value = "/countByUser")
public Result<Long> countByUserId(@RequestParam String userId) {
Long count = cozeApiCallService.countByUserId(userId);
return Result.success(count);
}
/**
* API调用记录响应类
* 统计Bot的API调用次数
*/
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
public static class CozeApiCallResponse extends BaseResponse {
private String conversationId;
private String messageId;
private String userId;
private String botId;
private String requestType;
private String requestUrl;
private String requestBody;
private Integer responseStatus;
private String responseBody;
private String aiReply;
private Integer totalTokens;
private java.math.BigDecimal cost;
private String status;
private String finalStatus;
private String startTime;
private String endTime;
private String traceId;
@GetMapping(value = "/countByBot")
public Result<Long> countByBotId(@RequestParam String botId) {
Long count = cozeApiCallService.countByBotId(botId);
return Result.success(count);
}
}
/**
* 统计指定状态的API调用次数
*/
@GetMapping(value = "/countByStatus")
public Result<Long> countByStatus(@RequestParam String status) {
Long count = cozeApiCallService.countByStatus(status);
return Result.success(count);
}
/**
* 统计用户的Token使用量
*/
@GetMapping(value = "/tokensByUser")
public Result<Long> sumTokensByUserId(@RequestParam String userId) {
Long totalTokens = cozeApiCallService.sumTokensByUserId(userId);
return Result.success(totalTokens);
}
/**
* 统计用户的API调用费用
*/
@GetMapping(value = "/costByUser")
public Result<BigDecimal> sumCostByUserId(@RequestParam String userId) {
BigDecimal totalCost = cozeApiCallService.sumCostByUserId(userId);
return Result.success(totalCost);
}
}
@@ -1,27 +1,19 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.BasePageRequest;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.DiaryCommentCreateRequest;
import com.emotion.dto.request.DiaryCommentPageRequest;
import com.emotion.dto.response.DiaryCommentResponse;
import com.emotion.entity.DiaryComment;
import com.emotion.service.DiaryCommentService;
import com.emotion.service.DiaryPostService;
import com.emotion.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import com.emotion.util.UserContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 日记评论控制器
@@ -30,7 +22,7 @@ import java.util.stream.Collectors;
* @date 2025-07-23
*/
@RestController
@RequestMapping("/diary-comment")
@RequestMapping("/diaryComment")
public class DiaryCommentController {
@Autowired
@@ -39,152 +31,79 @@ public class DiaryCommentController {
@Autowired
private DiaryPostService diaryPostService;
@Autowired
private UserService userService;
@Autowired
private ObjectMapper objectMapper;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询评论
*/
@GetMapping("/page")
public Result<PageResult<DiaryCommentResponse>> getPage(@Validated BasePageRequest request) {
IPage<DiaryComment> page = diaryCommentService.getPage(request);
List<DiaryCommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryCommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据日记ID分页查询评论
*/
@GetMapping("/diary/{diaryId}/page")
public Result<PageResult<DiaryCommentResponse>> getPageByDiaryId(@PathVariable String diaryId,
@Validated BasePageRequest request) {
IPage<DiaryComment> page = diaryCommentService.getPageByDiaryId(diaryId, request);
List<DiaryCommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryCommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询评论
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<DiaryCommentResponse>> getPageByUserId(@PathVariable String userId,
@Validated BasePageRequest request) {
IPage<DiaryComment> page = diaryCommentService.getPageByUserId(userId, request);
List<DiaryCommentResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryCommentResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
@GetMapping(value = "/page")
public Result<PageResult<DiaryCommentResponse>> getPage(@Validated DiaryCommentPageRequest request) {
PageResult<DiaryCommentResponse> pageResult = diaryCommentService.getPageWithResponse(request);
return Result.success(pageResult);
}
/**
* 获取评论树结构
*/
@GetMapping("/diary/{diaryId}/tree")
public Result<List<DiaryCommentResponse>> getCommentTree(@PathVariable String diaryId) {
List<DiaryComment> comments = diaryCommentService.getCommentTree(diaryId);
List<DiaryCommentResponse> responses = comments.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@GetMapping(value = "/commentTree")
public Result<List<DiaryCommentResponse>> getCommentTree(@RequestParam String diaryId) {
List<DiaryCommentResponse> responses = diaryCommentService.getCommentTreeWithResponse(diaryId);
return Result.success(responses);
}
/**
* 根据ID获取评论详情
*/
@GetMapping("/{id}")
public Result<DiaryCommentResponse> getById(@PathVariable String id) {
DiaryComment comment = diaryCommentService.getById(id);
if (comment == null) {
@GetMapping(value = "/detail")
public Result<DiaryCommentResponse> getById(@RequestParam String id) {
DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id);
if (response == null) {
return Result.notFound("评论不存在");
}
return Result.success(convertToResponse(comment));
return Result.success(response);
}
/**
* 创建评论
*/
@PostMapping
@PostMapping(value = "/create")
public Result<DiaryCommentResponse> create(@Valid @RequestBody DiaryCommentCreateRequest request) {
DiaryComment comment = diaryCommentService.createComment(
request.getDiaryId(),
request.getUserId(),
request.getContent(),
request.getImages(),
request.getParentCommentId(),
request.getIsAnonymous()
);
// 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID
String currentUserId = UserContextUtils.getCurrentUserId();
if (currentUserId != null) {
request.setUserId(currentUserId);
}
DiaryCommentResponse response = diaryCommentService.createCommentWithResponse(request);
// 更新日记的评论数
diaryPostService.incrementCommentCount(request.getDiaryId());
diaryPostService.updateLastCommentTime(request.getDiaryId());
return Result.success(convertToResponse(comment));
return Result.success(response);
}
/**
* 更新评论
*/
@PutMapping("/{id}")
public Result<DiaryCommentResponse> update(@PathVariable String id, @Valid @RequestBody DiaryCommentCreateRequest request) {
boolean updated = diaryCommentService.updateComment(id, request.getContent(), request.getImages());
if (!updated) {
return Result.error("更新失败");
}
DiaryComment updatedComment = diaryCommentService.getById(id);
return Result.success(convertToResponse(updatedComment));
@PutMapping(value = "/update")
public Result<DiaryCommentResponse> update(@Valid @RequestBody DiaryCommentCreateRequest request) {
DiaryCommentResponse response = diaryCommentService.updateCommentWithResponse(request);
return Result.success(response);
}
/**
* 删除评论
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
DiaryComment comment = diaryCommentService.getById(id);
if (comment == null) {
return Result.error("评论不存在");
}
@DeleteMapping(value = "/delete")
public Result<Void> delete(@RequestParam String id) {
boolean deleted = diaryCommentService.deleteComment(id);
if (!deleted) {
return Result.error("删除失败");
}
// 更新日记的评论数
diaryPostService.decrementCommentCount(comment.getDiaryId());
DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id);
if (response != null) {
diaryPostService.decrementCommentCount(response.getDiaryId());
}
return Result.success();
}
@@ -192,20 +111,18 @@ public class DiaryCommentController {
/**
* 软删除评论
*/
@DeleteMapping("/{id}/soft")
public Result<Void> softDelete(@PathVariable String id) {
DiaryComment comment = diaryCommentService.getById(id);
if (comment == null) {
return Result.error("评论不存在");
}
@DeleteMapping(value = "/softDelete")
public Result<Void> softDelete(@RequestParam String id) {
boolean deleted = diaryCommentService.softDeleteComment(id);
if (!deleted) {
return Result.error("删除失败");
}
// 更新日记的评论数
diaryPostService.decrementCommentCount(comment.getDiaryId());
DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id);
if (response != null) {
diaryPostService.decrementCommentCount(response.getDiaryId());
}
return Result.success();
}
@@ -213,20 +130,18 @@ public class DiaryCommentController {
/**
* 恢复评论
*/
@PutMapping("/{id}/restore")
public Result<Void> restore(@PathVariable String id) {
DiaryComment comment = diaryCommentService.getById(id);
if (comment == null) {
return Result.error("评论不存在");
}
@PutMapping(value = "/restore")
public Result<Void> restore(@RequestParam String id) {
boolean restored = diaryCommentService.restoreComment(id);
if (!restored) {
return Result.error("恢复失败");
}
// 更新日记的评论数
diaryPostService.incrementCommentCount(comment.getDiaryId());
DiaryCommentResponse response = diaryCommentService.getCommentResponseById(id);
if (response != null) {
diaryPostService.incrementCommentCount(response.getDiaryId());
}
return Result.success();
}
@@ -234,8 +149,8 @@ public class DiaryCommentController {
/**
* 点赞评论
*/
@PostMapping("/{id}/like")
public Result<Void> like(@PathVariable String id) {
@PostMapping(value = "/like")
public Result<Void> like(@RequestParam String id) {
boolean liked = diaryCommentService.incrementLikeCount(id);
if (!liked) {
return Result.error("点赞失败");
@@ -246,8 +161,8 @@ public class DiaryCommentController {
/**
* 取消点赞评论
*/
@DeleteMapping("/{id}/like")
public Result<Void> unlike(@PathVariable String id) {
@DeleteMapping(value = "/unlike")
public Result<Void> unlike(@RequestParam String id) {
boolean unliked = diaryCommentService.decrementLikeCount(id);
if (!unliked) {
return Result.error("取消点赞失败");
@@ -258,75 +173,12 @@ public class DiaryCommentController {
/**
* 设置置顶状态
*/
@PutMapping("/{id}/top/{isTop}")
public Result<Void> setTop(@PathVariable String id, @PathVariable Integer isTop) {
@PutMapping(value = "/setTop")
public Result<Void> setTop(@RequestParam String id, @RequestParam Integer isTop) {
boolean set = diaryCommentService.setTop(id, isTop);
if (!set) {
return Result.error("设置置顶状态失败");
}
return Result.success();
}
/**
* 统计日记评论数量
*/
@GetMapping("/diary/{diaryId}/count")
public Result<Long> countByDiaryId(@PathVariable String diaryId) {
Long count = diaryCommentService.countByDiaryId(diaryId);
return Result.success(count);
}
/**
* 统计用户评论数量
*/
@GetMapping("/user/{userId}/count")
public Result<Long> countByUserId(@PathVariable String userId) {
Long count = diaryCommentService.countByUserId(userId);
return Result.success(count);
}
/**
* 统计回复数量
*/
@GetMapping("/parent/{parentCommentId}/replies/count")
public Result<Long> countReplies(@PathVariable String parentCommentId) {
Long count = diaryCommentService.countReplies(parentCommentId);
return Result.success(count);
}
/**
* 转换实体为响应DTO
*/
private DiaryCommentResponse convertToResponse(DiaryComment comment) {
DiaryCommentResponse response = new DiaryCommentResponse();
BeanUtils.copyProperties(comment, response);
// 转换时间格式
if (comment.getPublishTime() != null) {
response.setPublishTime(comment.getPublishTime().format(DATE_TIME_FORMATTER));
}
if (comment.getLastReplyTime() != null) {
response.setLastReplyTime(comment.getLastReplyTime().format(DATE_TIME_FORMATTER));
}
if (comment.getCreateTime() != null) {
response.setCreateTime(comment.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (comment.getUpdateTime() != null) {
response.setUpdateTime(comment.getUpdateTime().format(DATE_TIME_FORMATTER));
}
// 转换JSON字段
try {
if (comment.getImages() != null) {
response.setImages(objectMapper.readValue(comment.getImages(), new TypeReference<List<String>>() {}));
}
if (comment.getMetadata() != null) {
response.setMetadata(objectMapper.readValue(comment.getMetadata(), Object.class));
}
} catch (JsonProcessingException e) {
// 忽略JSON解析错误
}
return response;
}
}
}
@@ -1,30 +1,18 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.BasePageRequest;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.DiaryPostCreateRequest;
import com.emotion.dto.request.DiaryPostPageRequest;
import com.emotion.dto.request.DiaryPostUpdateRequest;
import com.emotion.dto.response.DiaryPostResponse;
import com.emotion.entity.DiaryPost;
import com.emotion.service.DiaryPostService;
import com.emotion.service.DiaryCommentService;
import com.emotion.service.UserService;
import com.emotion.service.AiChatService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import com.emotion.util.UserContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import com.emotion.entity.DiaryComment;
/**
* 用户日记控制器
@@ -33,161 +21,75 @@ import com.emotion.entity.DiaryComment;
* @date 2025-07-23
*/
@RestController
@RequestMapping("/diary-post")
@RequestMapping("/diaryPost")
public class DiaryPostController {
@Autowired
private DiaryPostService diaryPostService;
@Autowired
private DiaryCommentService diaryCommentService;
@Autowired
private UserService userService;
@Autowired
private AiChatService aiChatService;
@Autowired
private ObjectMapper objectMapper;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询日记
*/
@GetMapping("/page")
public Result<PageResult<DiaryPostResponse>> getPage(@Validated BasePageRequest request) {
IPage<DiaryPost> page = diaryPostService.getPage(request);
List<DiaryPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID分页查询日记
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<DiaryPostResponse>> getPageByUserId(@PathVariable String userId,
@Validated BasePageRequest request) {
IPage<DiaryPost> page = diaryPostService.getPageByUserId(userId, request);
List<DiaryPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 根据用户ID查询公开日记
*/
@GetMapping("/user/{userId}/public/page")
public Result<PageResult<DiaryPostResponse>> getPublicPageByUserId(@PathVariable String userId,
@Validated BasePageRequest request) {
IPage<DiaryPost> page = diaryPostService.getPublicPageByUserId(userId, request);
List<DiaryPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
}
/**
* 查询精选日记
*/
@GetMapping("/featured/page")
public Result<PageResult<DiaryPostResponse>> getFeaturedPage(@Validated BasePageRequest request) {
IPage<DiaryPost> page = diaryPostService.getFeaturedPage(request);
List<DiaryPostResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<DiaryPostResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
@GetMapping(value = "/page")
public Result<PageResult<DiaryPostResponse>> getPage(@Validated DiaryPostPageRequest request) {
return Result.success(diaryPostService.getPageWithResponse(request));
}
/**
* 根据ID获取日记详情
*/
@GetMapping("/{id}")
public Result<DiaryPostResponse> getById(@PathVariable String id) {
DiaryPost diaryPost = diaryPostService.getById(id);
if (diaryPost == null) {
@GetMapping(value = "/detail")
public Result<DiaryPostResponse> getById(@RequestParam String id) {
DiaryPostResponse response = diaryPostService.getDiaryPostResponseById(id);
if (response == null) {
return Result.notFound("日记不存在");
}
// 增加浏览数
diaryPostService.incrementViewCount(id);
return Result.success(convertToResponse(diaryPost));
return Result.success(response);
}
/**
* 创建日记
*/
@PostMapping
@PostMapping(value = "/create")
public Result<DiaryPostResponse> create(@Valid @RequestBody DiaryPostCreateRequest request) {
DiaryPost diaryPost = diaryPostService.createDiaryPost(request);
return Result.success(convertToResponse(diaryPost));
// 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID
String currentUserId = UserContextUtils.getCurrentUserId();
if (currentUserId != null) {
request.setUserId(currentUserId);
}
return Result.success(diaryPostService.createDiaryPostWithResponse(request));
}
/**
* 发表日记并生成AI评论
*/
@PostMapping("/publish")
@PostMapping(value = "/publish")
public Result<DiaryPostResponse> publish(@Valid @RequestBody DiaryPostCreateRequest request) {
// 从上下文中获取当前用户ID,而不是直接使用请求中的用户ID
String currentUserId = UserContextUtils.getCurrentUserId();
if (currentUserId != null) {
request.setUserId(currentUserId);
}
return Result.success(diaryPostService.publishDiaryWithAiComment(request));
}
/**
* 更新日记
*/
@PutMapping("/{id}")
public Result<DiaryPostResponse> update(@PathVariable String id, @Valid @RequestBody DiaryPostUpdateRequest request) {
boolean updated = diaryPostService.updateDiaryPost(id, request);
if (!updated) {
@PutMapping(value = "/update")
public Result<DiaryPostResponse> update(@Valid @RequestBody DiaryPostUpdateRequest request) {
DiaryPostResponse response = diaryPostService.updateDiaryPostWithResponse(request);
if (response == null) {
return Result.error("更新失败");
}
DiaryPost updatedDiaryPost = diaryPostService.getById(id);
return Result.success(convertToResponse(updatedDiaryPost));
return Result.success(response);
}
/**
* 删除日记
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
@DeleteMapping(value = "/delete")
public Result<Void> delete(@RequestParam String id) {
boolean deleted = diaryPostService.deleteDiaryPost(id);
if (!deleted) {
return Result.error("删除失败");
@@ -198,8 +100,8 @@ public class DiaryPostController {
/**
* 软删除日记
*/
@DeleteMapping("/{id}/soft")
public Result<Void> softDelete(@PathVariable String id) {
@DeleteMapping(value = "/softDelete")
public Result<Void> softDelete(@RequestParam String id) {
boolean deleted = diaryPostService.softDeleteDiaryPost(id);
if (!deleted) {
return Result.error("删除失败");
@@ -210,8 +112,8 @@ public class DiaryPostController {
/**
* 恢复日记
*/
@PutMapping("/{id}/restore")
public Result<Void> restore(@PathVariable String id) {
@PutMapping(value = "/restore")
public Result<Void> restore(@RequestParam String id) {
boolean restored = diaryPostService.restoreDiaryPost(id);
if (!restored) {
return Result.error("恢复失败");
@@ -222,8 +124,8 @@ public class DiaryPostController {
/**
* 点赞日记
*/
@PostMapping("/{id}/like")
public Result<Void> like(@PathVariable String id) {
@PostMapping(value = "/like")
public Result<Void> like(@RequestParam String id) {
boolean liked = diaryPostService.incrementLikeCount(id);
if (!liked) {
return Result.error("点赞失败");
@@ -234,8 +136,8 @@ public class DiaryPostController {
/**
* 取消点赞日记
*/
@DeleteMapping("/{id}/like")
public Result<Void> unlike(@PathVariable String id) {
@DeleteMapping(value = "/unlike")
public Result<Void> unlike(@RequestParam String id) {
boolean unliked = diaryPostService.decrementLikeCount(id);
if (!unliked) {
return Result.error("取消点赞失败");
@@ -246,8 +148,8 @@ public class DiaryPostController {
/**
* 分享日记
*/
@PostMapping("/{id}/share")
public Result<Void> share(@PathVariable String id) {
@PostMapping(value = "/share")
public Result<Void> share(@RequestParam String id) {
boolean shared = diaryPostService.incrementShareCount(id);
if (!shared) {
return Result.error("分享失败");
@@ -258,8 +160,8 @@ public class DiaryPostController {
/**
* 设置精选状态
*/
@PutMapping("/{id}/featured/{featured}")
public Result<Void> setFeatured(@PathVariable String id, @PathVariable Integer featured) {
@PutMapping(value = "/setFeatured")
public Result<Void> setFeatured(@RequestParam String id, @RequestParam Integer featured) {
boolean set = diaryPostService.setFeatured(id, featured);
if (!set) {
return Result.error("设置精选状态失败");
@@ -270,90 +172,12 @@ public class DiaryPostController {
/**
* 设置置顶优先级
*/
@PutMapping("/{id}/priority/{priority}")
public Result<Void> setPriority(@PathVariable String id, @PathVariable Integer priority) {
@PutMapping(value = "/setPriority")
public Result<Void> setPriority(@RequestParam String id, @RequestParam Integer priority) {
boolean set = diaryPostService.setPriority(id, priority);
if (!set) {
return Result.error("设置优先级失败");
}
return Result.success();
}
/**
* 统计用户日记数量
*/
@GetMapping("/user/{userId}/count")
public Result<Long> countByUserId(@PathVariable String userId) {
Long count = diaryPostService.countByUserId(userId);
return Result.success(count);
}
/**
* 统计用户公开日记数量
*/
@GetMapping("/user/{userId}/public/count")
public Result<Long> countPublicByUserId(@PathVariable String userId) {
Long count = diaryPostService.countPublicByUserId(userId);
return Result.success(count);
}
/**
* 统计精选日记数量
*/
@GetMapping("/featured/count")
public Result<Long> countFeatured() {
Long count = diaryPostService.countFeatured();
return Result.success(count);
}
/**
* 转换实体为响应DTO
*/
private DiaryPostResponse convertToResponse(DiaryPost diaryPost) {
DiaryPostResponse response = new DiaryPostResponse();
BeanUtils.copyProperties(diaryPost, response);
// 转换时间格式
if (diaryPost.getPublishTime() != null) {
response.setPublishTime(diaryPost.getPublishTime().format(DATE_TIME_FORMATTER));
}
if (diaryPost.getLastCommentTime() != null) {
response.setLastCommentTime(diaryPost.getLastCommentTime().format(DATE_TIME_FORMATTER));
}
if (diaryPost.getAiCommentTime() != null) {
response.setAiCommentTime(diaryPost.getAiCommentTime().format(DATE_TIME_FORMATTER));
}
if (diaryPost.getCreateTime() != null) {
response.setCreateTime(diaryPost.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (diaryPost.getUpdateTime() != null) {
response.setUpdateTime(diaryPost.getUpdateTime().format(DATE_TIME_FORMATTER));
}
// 转换JSON字段
try {
if (diaryPost.getImages() != null) {
response.setImages(objectMapper.readValue(diaryPost.getImages(), new TypeReference<List<String>>() {}));
}
if (diaryPost.getVideos() != null) {
response.setVideos(objectMapper.readValue(diaryPost.getVideos(), new TypeReference<List<String>>() {}));
}
if (diaryPost.getTags() != null) {
response.setTags(objectMapper.readValue(diaryPost.getTags(), new TypeReference<List<String>>() {}));
}
if (diaryPost.getAiKeywords() != null) {
response.setAiKeywords(objectMapper.readValue(diaryPost.getAiKeywords(), new TypeReference<List<String>>() {}));
}
if (diaryPost.getAiEmotionAnalysis() != null) {
response.setAiEmotionAnalysis(objectMapper.readValue(diaryPost.getAiEmotionAnalysis(), Object.class));
}
if (diaryPost.getMetadata() != null) {
response.setMetadata(objectMapper.readValue(diaryPost.getMetadata(), Object.class));
}
} catch (JsonProcessingException e) {
// 忽略JSON解析错误
}
return response;
}
}
}
@@ -1,24 +1,22 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.dto.request.PageRequest;
import com.emotion.dto.response.BaseResponse;
import com.emotion.entity.EmotionAnalysis;
import com.emotion.dto.request.EmotionAnalysisCreateRequest;
import com.emotion.dto.request.EmotionAnalysisPageRequest;
import com.emotion.dto.request.EmotionAnalysisUpdateRequest;
import com.emotion.dto.response.EmotionAnalysisResponse;
import com.emotion.service.EmotionAnalysisService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 情绪分析控制器
@@ -33,108 +31,74 @@ public class EmotionAnalysisController {
@Autowired
private EmotionAnalysisService emotionAnalysisService;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 分页查询情绪分析记录
*/
@GetMapping("/page")
public Result<PageResult<EmotionAnalysisResponse>> getPage(@Validated PageRequest request) {
IPage<EmotionAnalysis> page = emotionAnalysisService.getPage(request);
List<EmotionAnalysisResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<EmotionAnalysisResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
public Result<PageResult<EmotionAnalysisResponse>> getPage(@Validated EmotionAnalysisPageRequest request) {
return Result.success(emotionAnalysisService.getPageWithResponse(request));
}
/**
* 根据用户ID分页查询情绪分析记录
*/
@GetMapping("/user/{userId}/page")
public Result<PageResult<EmotionAnalysisResponse>> getPageByUserId(@PathVariable String userId, @Validated PageRequest request) {
IPage<EmotionAnalysis> page = emotionAnalysisService.getPageByUserId(request, userId);
List<EmotionAnalysisResponse> responses = page.getRecords().stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
PageResult<EmotionAnalysisResponse> pageResult = new PageResult<>();
pageResult.setCurrent(page.getCurrent());
pageResult.setSize(page.getSize());
pageResult.setTotal(page.getTotal());
pageResult.setPages(page.getPages());
pageResult.setRecords(responses);
return Result.success(pageResult);
@GetMapping("/user/page")
public Result<PageResult<EmotionAnalysisResponse>> getPageByUserId(
@RequestParam String userId,
@Validated EmotionAnalysisPageRequest request) {
return Result.success(emotionAnalysisService.getPageByUserIdWithResponse(userId, request));
}
/**
* 根据ID获取情绪分析记录
*/
@GetMapping("/{id}")
public Result<EmotionAnalysisResponse> getById(@PathVariable String id) {
EmotionAnalysis analysis = emotionAnalysisService.getById(id);
if (analysis == null) {
@GetMapping
public Result<EmotionAnalysisResponse> getById(@RequestParam String id) {
EmotionAnalysisResponse response = emotionAnalysisService.getEmotionAnalysisResponseById(id);
if (response == null) {
return Result.notFound("情绪分析记录不存在");
}
return Result.success(convertToResponse(analysis));
return Result.success(response);
}
/**
* 根据消息ID获取情绪分析记录
*/
@GetMapping("/message/{messageId}")
public Result<EmotionAnalysisResponse> getByMessageId(@PathVariable String messageId) {
EmotionAnalysis analysis = emotionAnalysisService.getByMessageId(messageId);
if (analysis == null) {
@GetMapping("/message")
public Result<EmotionAnalysisResponse> getByMessageId(@RequestParam String messageId) {
EmotionAnalysisResponse response = emotionAnalysisService.getEmotionAnalysisResponseByMessageId(messageId);
if (response == null) {
return Result.notFound("情绪分析记录不存在");
}
return Result.success(convertToResponse(analysis));
return Result.success(response);
}
/**
* 创建情绪分析记录
*/
@PostMapping
public Result<EmotionAnalysisResponse> create(@RequestBody @Validated EmotionAnalysisCreateRequest request) {
EmotionAnalysis analysis = emotionAnalysisService.createEmotionAnalysis(
request.getMessageId(),
request.getUserId(),
request.getPrimaryEmotion(),
request.getPolarity(),
request.getIntensity(),
request.getConfidence()
);
return Result.success(convertToResponse(analysis));
public Result<EmotionAnalysisResponse> create(@RequestBody @Valid EmotionAnalysisCreateRequest request) {
return Result.success(emotionAnalysisService.createEmotionAnalysisWithResponse(request));
}
/**
* 更新情绪分析记录
*/
@PutMapping("/{id}")
public Result<EmotionAnalysisResponse> update(@PathVariable String id, @RequestBody EmotionAnalysis analysis) {
analysis.setId(id);
boolean updated = emotionAnalysisService.updateById(analysis);
if (!updated) {
@PutMapping
public Result<EmotionAnalysisResponse> update(@RequestBody @Valid EmotionAnalysisUpdateRequest request) {
EmotionAnalysisResponse response = emotionAnalysisService.updateEmotionAnalysisWithResponse(request);
if (response == null) {
return Result.error("更新失败");
}
EmotionAnalysis updatedAnalysis = emotionAnalysisService.getById(id);
return Result.success(convertToResponse(updatedAnalysis));
return Result.success(response);
}
/**
* 删除情绪分析记录
*/
@DeleteMapping("/{id}")
public Result<Void> delete(@PathVariable String id) {
boolean deleted = emotionAnalysisService.removeById(id);
@DeleteMapping
public Result<Void> delete(@RequestParam String id) {
boolean deleted = emotionAnalysisService.deleteEmotionAnalysis(id);
if (!deleted) {
return Result.error("删除失败");
}
@@ -144,59 +108,53 @@ public class EmotionAnalysisController {
/**
* 根据主要情绪查询分析记录
*/
@GetMapping("/emotion/{primaryEmotion}")
public Result<List<EmotionAnalysisResponse>> getByPrimaryEmotion(@PathVariable String primaryEmotion) {
List<EmotionAnalysis> analyses = emotionAnalysisService.getByPrimaryEmotion(primaryEmotion);
List<EmotionAnalysisResponse> responses = analyses.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@GetMapping("/emotion")
public Result<List<EmotionAnalysisResponse>> getByPrimaryEmotion(@RequestParam String primaryEmotion) {
List<EmotionAnalysisResponse> responses = emotionAnalysisService
.getEmotionAnalysisResponsesByPrimaryEmotion(primaryEmotion);
return Result.success(responses);
}
/**
* 根据情绪极性查询分析记录
*/
@GetMapping("/polarity/{polarity}")
public Result<List<EmotionAnalysisResponse>> getByPolarity(@PathVariable String polarity) {
List<EmotionAnalysis> analyses = emotionAnalysisService.getByPolarity(polarity);
List<EmotionAnalysisResponse> responses = analyses.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@GetMapping("/polarity")
public Result<List<EmotionAnalysisResponse>> getByPolarity(@RequestParam String polarity) {
List<EmotionAnalysisResponse> responses = emotionAnalysisService
.getEmotionAnalysisResponsesByPolarity(polarity);
return Result.success(responses);
}
/**
* 根据用户ID和情绪类型查询分析记录
*/
@GetMapping("/user/{userId}/emotion/{primaryEmotion}")
public Result<List<EmotionAnalysisResponse>> getByUserIdAndEmotion(@PathVariable String userId, @PathVariable String primaryEmotion) {
List<EmotionAnalysis> analyses = emotionAnalysisService.getByUserIdAndEmotion(userId, primaryEmotion);
List<EmotionAnalysisResponse> responses = analyses.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@GetMapping("/user/emotion")
public Result<List<EmotionAnalysisResponse>> getByUserIdAndEmotion(
@RequestParam String userId,
@RequestParam String primaryEmotion) {
List<EmotionAnalysisResponse> responses = emotionAnalysisService
.getEmotionAnalysisResponsesByUserIdAndEmotion(userId, primaryEmotion);
return Result.success(responses);
}
/**
* 根据时间范围查询用户情绪分析记录
*/
@GetMapping("/user/{userId}/time-range")
@GetMapping("/user/time-range")
public Result<List<EmotionAnalysisResponse>> getByUserIdAndTimeRange(
@PathVariable String userId,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@RequestParam String userId,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
List<EmotionAnalysis> analyses = emotionAnalysisService.getByUserIdAndTimeRange(userId, startTime, endTime);
List<EmotionAnalysisResponse> responses = analyses.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
List<EmotionAnalysisResponse> responses = emotionAnalysisService
.getEmotionAnalysisResponsesByUserIdAndTimeRange(userId, startTime, endTime);
return Result.success(responses);
}
/**
* 统计用户的情绪分析记录数量
*/
@GetMapping("/user/{userId}/count")
public Result<Long> countByUserId(@PathVariable String userId) {
@GetMapping("/user/count")
public Result<Long> countByUserId(@RequestParam String userId) {
Long count = emotionAnalysisService.countByUserId(userId);
return Result.success(count);
}
@@ -204,20 +162,20 @@ public class EmotionAnalysisController {
/**
* 查询用户最近的情绪分析记录
*/
@GetMapping("/user/{userId}/recent")
public Result<List<EmotionAnalysisResponse>> getRecentByUserId(@PathVariable String userId, @RequestParam(defaultValue = "10") Integer limit) {
List<EmotionAnalysis> analyses = emotionAnalysisService.getRecentByUserId(userId, limit);
List<EmotionAnalysisResponse> responses = analyses.stream()
.map(this::convertToResponse)
.collect(Collectors.toList());
@GetMapping("/user/recent")
public Result<List<EmotionAnalysisResponse>> getRecentByUserId(
@RequestParam String userId,
@RequestParam(defaultValue = "10") Integer limit) {
List<EmotionAnalysisResponse> responses = emotionAnalysisService
.getEmotionAnalysisResponsesRecentByUserId(userId, limit);
return Result.success(responses);
}
/**
* 查询用户的平均情绪强度
*/
@GetMapping("/user/{userId}/avg-intensity")
public Result<Double> getAvgIntensityByUserId(@PathVariable String userId) {
@GetMapping("/user/avg-intensity")
public Result<Double> getAvgIntensityByUserId(@RequestParam String userId) {
Double avgIntensity = emotionAnalysisService.getAvgIntensityByUserId(userId);
return Result.success(avgIntensity);
}
@@ -225,63 +183,9 @@ public class EmotionAnalysisController {
/**
* 查询用户最常见的情绪类型
*/
@GetMapping("/user/{userId}/most-frequent-emotion")
public Result<String> getMostFrequentEmotionByUserId(@PathVariable String userId) {
@GetMapping("/user/most-frequent-emotion")
public Result<String> getMostFrequentEmotionByUserId(@RequestParam String userId) {
String emotion = emotionAnalysisService.getMostFrequentEmotionByUserId(userId);
return Result.success(emotion);
}
/**
* 转换为响应对象
*/
private EmotionAnalysisResponse convertToResponse(EmotionAnalysis analysis) {
EmotionAnalysisResponse response = new EmotionAnalysisResponse();
BeanUtils.copyProperties(analysis, response);
response.setId(analysis.getId());
if (analysis.getCreateTime() != null) {
response.setCreateTime(analysis.getCreateTime().format(DATE_TIME_FORMATTER));
}
if (analysis.getUpdateTime() != null) {
response.setUpdateTime(analysis.getUpdateTime().format(DATE_TIME_FORMATTER));
}
return response;
}
/**
* 情绪分析创建请求
*/
@lombok.Data
public static class EmotionAnalysisCreateRequest {
@NotBlank(message = "消息ID不能为空")
private String messageId;
@NotBlank(message = "用户ID不能为空")
private String userId;
@NotBlank(message = "主要情绪不能为空")
private String primaryEmotion;
private String polarity;
@NotNull(message = "情绪强度不能为空")
private Double intensity;
@NotNull(message = "置信度不能为空")
private Double confidence;
}
/**
* 情绪分析响应类
*/
@lombok.Data
@lombok.EqualsAndHashCode(callSuper = true)
public static class EmotionAnalysisResponse extends BaseResponse {
private String messageId;
private String userId;
private String primaryEmotion;
private String polarity;
private Double intensity;
private Double confidence;
private String emotionDetails;
}
}
}
@@ -1,8 +1,11 @@
package com.emotion.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.emotion.common.PageResult;
import com.emotion.common.Result;
import com.emotion.entity.EmotionRecord;
import com.emotion.dto.request.EmotionRecordCreateRequest;
import com.emotion.dto.request.EmotionRecordPageRequest;
import com.emotion.dto.request.EmotionRecordUpdateRequest;
import com.emotion.dto.response.EmotionRecordResponse;
import com.emotion.service.EmotionRecordService;
import com.emotion.util.CurrentUserUtil;
import io.swagger.v3.oas.annotations.Operation;
@@ -11,10 +14,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
/**
* 情绪记录控制器
@@ -36,29 +43,16 @@ public class EmotionRecordController {
* 创建情绪记录
*/
@PostMapping
public Result<Map<String, Object>> createRecord(@RequestBody Map<String, Object> request) {
log.info("创建情绪记录: {}", request);
@Operation(summary = "创建情绪记录", description = "创建新的情绪记录")
public Result<EmotionRecordResponse> createRecord(@RequestBody @Valid EmotionRecordCreateRequest request) {
log.info("创建情绪记录: userId={}", request.getUserId());
try {
Map<String, Object> record = new HashMap<>();
record.put("id", "record-" + System.currentTimeMillis());
record.put("userId", request.get("userId"));
record.put("recordDate", request.get("recordDate"));
record.put("emotionType", request.get("emotionType"));
record.put("intensity", request.get("intensity"));
record.put("triggers", request.get("triggers"));
record.put("description", request.get("description"));
record.put("tags", request.get("tags"));
record.put("weather", request.get("weather"));
record.put("location", request.get("location"));
record.put("activity", request.get("activity"));
record.put("createTime", LocalDateTime.now());
return Result.success("创建成功", record);
} catch (Exception e) {
log.error("创建情绪记录失败: {}", e.getMessage());
return Result.error("创建失败");
}
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
request.setUserId(userId);
EmotionRecordResponse response = emotionRecordService.createEmotionRecordWithResponse(request);
return Result.success("创建成功", response);
}
/**
@@ -66,30 +60,20 @@ public class EmotionRecordController {
*/
@Operation(summary = "获取用户情绪记录列表", description = "分页获取当前用户的情绪记录,按创建时间倒序")
@GetMapping("/user")
public Result<IPage<EmotionRecord>> getRecordList(
@Parameter(description = "页码,从1开始") @RequestParam(defaultValue = "1") Integer current,
@Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) {
public Result<PageResult<EmotionRecordResponse>> getRecordList(
@Validated EmotionRecordPageRequest request) {
try {
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
log.info("获取用户情绪记录列表: userId={}, current={}, size={}", userId, current, size);
log.info("获取用户情绪记录列表: userId={}, current={}, size={}", userId, request.getCurrent(), request.getSize());
IPage<EmotionRecord> page = emotionRecordService.getByUserIdWithPage(userId, current, size);
PageResult<EmotionRecordResponse> page = emotionRecordService.getPageByUserIdWithResponse(userId, request);
log.info("获取用户情绪记录成功: userId={}, total={}, records={}",
userId, page.getTotal(), page.getRecords().size());
log.info("获取用户情绪记录成功: userId={}, total={}, records={}",
userId, page.getTotal(), page.getRecords().size());
return Result.success(page);
} catch (IllegalStateException e) {
log.warn("用户认证失败: {}", e.getMessage());
return Result.error(e.getMessage());
} catch (Exception e) {
log.error("获取用户情绪记录失败", e);
return Result.error("获取情绪记录失败: " + e.getMessage());
}
return Result.success(page);
}
/**
@@ -97,138 +81,82 @@ public class EmotionRecordController {
*/
@Operation(summary = "获取用户最近情绪记录", description = "获取当前用户最近的情绪记录列表")
@GetMapping("/user/recent")
public Result<List<EmotionRecord>> getRecentRecords(
public Result<List<EmotionRecordResponse>> getRecentRecords(
@Parameter(description = "限制数量") @RequestParam(defaultValue = "5") Integer limit) {
try {
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
log.info("获取用户最近情绪记录: userId={}, limit={}", userId, limit);
log.info("获取用户最近情绪记录: userId={}, limit={}", userId, limit);
List<EmotionRecord> records = emotionRecordService.getRecentByUserId(userId, limit);
List<EmotionRecordResponse> records = emotionRecordService.getRecentByUserIdWithResponse(userId, limit);
log.info("获取用户最近情绪记录成功: userId={}, records={}", userId, records.size());
log.info("获取用户最近情绪记录成功: userId={}, records={}", userId, records.size());
return Result.success(records);
} catch (IllegalStateException e) {
log.warn("用户认证失败: {}", e.getMessage());
return Result.error(e.getMessage());
} catch (Exception e) {
log.error("获取用户最近情绪记录失败", e);
return Result.error("获取最近记录失败: " + e.getMessage());
}
return Result.success(records);
}
/**
* 获取情绪记录详情
*/
@GetMapping("/{recordId}")
public Result<Map<String, Object>> getRecord(@PathVariable String recordId) {
log.info("获取情绪记录详情: {}", recordId);
@Operation(summary = "获取情绪记录详情", description = "根据ID获取情绪记录详情")
@GetMapping
public Result<EmotionRecordResponse> getRecord(@RequestParam String id) {
log.info("获取情绪记录详情: {}", id);
try {
Map<String, Object> record = new HashMap<>();
record.put("id", recordId);
record.put("userId", "user123");
record.put("recordDate", LocalDate.now());
record.put("emotionType", "joy");
record.put("intensity", 0.8);
record.put("triggers", "完成了重要项目");
record.put("description", "今天心情很好,完成了一个重要的项目");
record.put("tags", Arrays.asList("工作", "成就感"));
record.put("weather", "晴天");
record.put("location", "办公室");
record.put("activity", "工作");
record.put("createTime", LocalDateTime.now());
return Result.success(record);
} catch (Exception e) {
log.error("获取情绪记录详情失败: {}", e.getMessage());
return Result.error("获取详情失败");
EmotionRecordResponse response = emotionRecordService.getEmotionRecordResponseById(id);
if (response == null) {
return Result.notFound("情绪记录不存在");
}
return Result.success(response);
}
/**
* 更新情绪记录
*/
@PutMapping("/{recordId}")
public Result<Map<String, Object>> updateRecord(@PathVariable String recordId,
@RequestBody Map<String, Object> request) {
log.info("更新情绪记录: {}", recordId);
@Operation(summary = "更新情绪记录", description = "更新指定的情绪记录")
@PutMapping
public Result<EmotionRecordResponse> updateRecord(@RequestBody @Valid EmotionRecordUpdateRequest request) {
log.info("更新情绪记录: {}", request.getId());
try {
Map<String, Object> record = new HashMap<>();
record.put("id", recordId);
record.put("emotionType", request.get("emotionType"));
record.put("intensity", request.get("intensity"));
record.put("triggers", request.get("triggers"));
record.put("description", request.get("description"));
record.put("tags", request.get("tags"));
record.put("updateTime", LocalDateTime.now());
return Result.success("更新成功", record);
} catch (Exception e) {
log.error("更新情绪记录失败: {}", e.getMessage());
return Result.error("更新失败");
EmotionRecordResponse response = emotionRecordService.updateEmotionRecordWithResponse(request);
if (response == null) {
return Result.notFound("情绪记录不存在");
}
return Result.success("更新成功", response);
}
/**
* 删除情绪记录
*/
@DeleteMapping("/{recordId}")
public Result<String> deleteRecord(@PathVariable String recordId) {
log.info("删除情绪记录: {}", recordId);
@Operation(summary = "删除情绪记录", description = "删除指定的情绪记录")
@DeleteMapping
public Result<String> deleteRecord(@RequestParam String id) {
log.info("删除情绪记录: {}", id);
try {
return Result.success("删除成功");
} catch (Exception e) {
log.error("删除情绪记录失败: {}", e.getMessage());
return Result.error("删除失败");
boolean deleted = emotionRecordService.deleteEmotionRecord(id);
if (!deleted) {
return Result.notFound("情绪记录不存在");
}
return Result.success("删除成功");
}
/**
* 获取情绪统计
*/
@GetMapping("/stats/{userId}")
public Result<Map<String, Object>> getEmotionStats(@PathVariable String userId,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
@Operation(summary = "获取情绪统计", description = "获取当前用户的情绪统计信息")
@GetMapping("/stats")
public Result<Map<String, Object>> getEmotionStats(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
// 从上下文中获取当前用户ID
String userId = CurrentUserUtil.requireCurrentUserId();
log.info("获取情绪统计: userId={}, startDate={}, endDate={}", userId, startDate, endDate);
try {
Map<String, Object> stats = new HashMap<>();
// 情绪类型分布
Map<String, Integer> emotionDistribution = new HashMap<>();
emotionDistribution.put("joy", 15);
emotionDistribution.put("sadness", 5);
emotionDistribution.put("anger", 3);
emotionDistribution.put("fear", 2);
emotionDistribution.put("surprise", 8);
emotionDistribution.put("neutral", 12);
stats.put("emotionDistribution", emotionDistribution);
stats.put("totalRecords", 45);
stats.put("averageIntensity", 0.72);
stats.put("mostFrequentEmotion", "joy");
stats.put("emotionTrend", "improving");
return Result.success(stats);
} catch (Exception e) {
log.error("获取情绪统计失败: {}", e.getMessage());
return Result.error("获取统计失败");
}
Map<String, Object> stats = emotionRecordService.getEmotionStats(userId, startDate, endDate);
return Result.success(stats);
}
/**
* 获取随机情绪类型
*/
private String getRandomEmotion() {
String[] emotions = {"joy", "sadness", "anger", "fear", "surprise", "neutral"};
return emotions[new Random().nextInt(emotions.length)];
}
}
}