3 Commits be6eeb6858 ... 1a6b0c49e3

Author SHA1 Message Date
  zhentao 1a6b0c49e3 wyc 2 weeks ago
  zhentao 796aa7333d Merge branch 'caolinxuan' into wyc 2 weeks ago
  caolinxuan 14aad067b6 clx 2 weeks ago

+ 105 - 51
src/main/java/com/zhentao/moment/service/impl/UserMomentsServiceImpl.java

@@ -333,15 +333,42 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
         if (commentsDto.getContent()==null){
             return Result.error(400,"评论不能为空");
         }
-        commentsDto.setReplyTo(Long.valueOf(commentsDto.getMomentId()));
-        commentsDto.setReplyToUser(userMoments.getUserId());
+        // 区别一级评论和回复评论
+        if (commentsDto.getReplyTo()!=null){
+            //非一级评论
+            //使用前端传递的replyToUser
+            momentComments.setReplyTo(commentsDto.getReplyTo());
+            if (commentsDto.getReplyToUser()!=null){
+                momentComments.setReplyToUser(commentsDto.getReplyToUser());
+            }else{
+                //查询被回复评论的用户id
+                MomentComments repliedComment = momentCommentsMapper.selectById(commentsDto.getReplyTo());
+                if (repliedComment!=null){
+                    momentComments.setReplyToUser(repliedComment.getUserId());
+                }
+            }
+        }else{
+//            一级评论
+            commentsDto.setReplyTo(null);
+            commentsDto.setReplyToUser(userMoments.getUserId());
+
+        }
         momentComments.setMomentId(Long.valueOf(commentsDto.getMomentId()));
         momentComments.setContent(commentsDto.getContent());
-        momentComments.setReplyToUser(commentsDto.getReplyToUser());
-        momentComments.setReplyTo(commentsDto.getReplyTo());
         momentCommentsMapper.insert(momentComments);
+//        返回评论携带被回复的用户信息
+        Map<String,Object> map= new HashMap<>();
+        map.put("commentId",momentComments.getCommentId());
+        map.put("replyToUser",momentComments.getReplyToUser());
+        map.put("replyToUserName",getUserNameById(momentComments.getReplyToUser()));// 获取被回复的用户名
         return Result.OK(200,"评论成功");
     }
+
+    private String getUserNameById(Long userId) {
+        UserLogin userLogin=userLoginMapper.selectById(userId);
+        return userLogin!=null ? userLogin.getNickName():"未知用户";
+    }
+
     //  查询点赞列表
     @Override
     public Result likeList(Long uid, MonmentDto monmentDto) {
@@ -485,12 +512,12 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
             userMomentsMapper.selectPage(allMomentsPage, allMomentQuery);
             List<UserMoments> allUserMoments = allMomentsPage.getRecords();
 
-            // 5. 提取所有动态相关用户ID(原有代码)
+            // 5. 提取所有动态相关用户ID
             Set<Long> allUserIds = allUserMoments.stream()
                     .map(UserMoments::getUserId)
                     .collect(Collectors.toSet());
 
-            // 6. 批量查询所有动态相关用户信息(原有代码)
+            // 6. 批量查询所有动态相关用户信息
             QueryWrapper<UserLogin> userQuery = new QueryWrapper<>();
             userQuery.in("id", allUserIds);
             List<UserLogin> users = userLoginMapper.selectList(userQuery);
@@ -502,7 +529,7 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
                     .map(UserMoments::getMomentId)
                     .collect(Collectors.toList());
 
-            // 8. 批量查询当前用户对所有动态的点赞状态(性能优化点)
+            // 8. 批量查询当前用户对所有动态的点赞状态
             Map<Long, Boolean> likedStatusMap = new HashMap<>();
             if (!allMomentIds.isEmpty()) {
                 QueryWrapper<MomentLikes> batchLikeQuery = new QueryWrapper<>();
@@ -517,17 +544,16 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
                 }
             }
 
-            // 9. 处理动态数据,添加用户信息和点赞状态(优化后)
+            // 9. 处理动态数据,添加用户信息和点赞状态
             List<Map<String, Object>> momentList = allUserMoments.stream()
                     .map(moment -> {
                         Map<String, Object> momentMap = wrapMomentWithUser(moment, userMap);
-                        // 从批量查询结果中获取点赞状态,避免重复查询
                         momentMap.put("isLiked", likedStatusMap.getOrDefault(moment.getMomentId(), false));
                         return momentMap;
                     })
                     .collect(Collectors.toList());
 
-            // 10. 处理点赞和评论(原有代码,略作优化
+            // 10. 处理点赞和评论(构建评论树
             Map<Long, Object> allLikesAndComments = new HashMap<>();
             if (!allMomentIds.isEmpty()) {
                 // 批量查询所有动态的点赞
@@ -598,46 +624,20 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
                             })
                             .collect(Collectors.toList());
 
-                    // 获取当前动态的评论列表
+                    // 获取当前动态的评论
                     List<MomentComments> comments = commentsMap.getOrDefault(momentId, Collections.emptyList());
-                    List<Map<String, Object>> commentList = comments.stream()
-                            .map(comment -> {
-                                Map<String, Object> commentInfo = new HashMap<>();
-                                commentInfo.put("id", comment.getCommentId());
-                                commentInfo.put("userId", comment.getUserId());
-                                commentInfo.put("content", comment.getContent());
-
-                                if (comment.getCreatedAt() != null) {
-                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                                    commentInfo.put("createdAt", sdf.format(comment.getCreatedAt()));
-                                }
-
-                                commentInfo.put("replyTo", comment.getReplyTo());
-                                commentInfo.put("replyToUser", comment.getReplyToUser());
+                    List<Map<String, Object>> commentTree = buildCommentTree(comments, likeCommentUserMap);
 
-                                UserLogin user = likeCommentUserMap.get(comment.getUserId());
-                                if (user != null) {
-                                    Map<String, Object> userInfo = new HashMap<>();
-                                    userInfo.put("id", user.getId().toString());
-                                    userInfo.put("username", user.getUserUsername());
-                                    userInfo.put("avatar", user.getAvatar());
-                                    commentInfo.put("userInfo", userInfo);
-                                }
-                                return commentInfo;
-                            })
-                            .collect(Collectors.toList());
-
-                    // 封装点赞评论信息
                     momentInfo.put("likeList", likeList);
-                    momentInfo.put("commentList", commentList);
+                    momentInfo.put("commentTree", commentTree);
                     momentInfo.put("likeCount", likeList.size());
-                    momentInfo.put("commentCount", commentList.size());
+                    momentInfo.put("commentCount", commentTree.size());
 
                     allLikesAndComments.put(momentId, momentInfo);
                 }
             }
 
-            // 11. 封装最终结果(原有代码)
+            // 11. 封装最终结果
             Map<String, Object> resultMap = new HashMap<>();
             resultMap.put("userInfo", userLogin);
             resultMap.put("moments", momentList);
@@ -655,26 +655,80 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
     }
 
     /**
-     * 封装动态数据并关联用户信息,确保包含momentId
+     * 构建评论树结构(一级评论+嵌套回复)
+     */
+    private List<Map<String, Object>> buildCommentTree(List<MomentComments> comments, Map<Long, UserLogin> userMap) {
+        List<Map<String, Object>> tree = new ArrayList<>();
+        Map<Long, Map<String, Object>> commentMap = new HashMap<>();
+
+        // 第一步:初始化所有评论节点
+        for (MomentComments comment : comments) {
+            Map<String, Object> node = new HashMap<>();
+            node.put("id", comment.getCommentId());
+            node.put("content", comment.getContent());
+            node.put("replyTo", comment.getReplyTo());
+            node.put("replyToUser", comment.getReplyToUser());
+            node.put("createTime", comment.getCreatedAt() != null ?
+                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(comment.getCreatedAt()) : "");
+
+            // 填充评论者信息
+            UserLogin commentUser = userMap.get(comment.getUserId());
+            if (commentUser != null) {
+                Map<String, Object> userInfo = new HashMap<>();
+                userInfo.put("id", commentUser.getId());
+                userInfo.put("nickName", commentUser.getNickName());
+                userInfo.put("avatar", commentUser.getAvatar());
+                node.put("userInfo", userInfo);
+            }
+
+            // 填充被回复用户信息
+            if (comment.getReplyToUser() != null) {
+                UserLogin repliedUser = userMap.get(comment.getReplyToUser());
+                if (repliedUser != null) {
+                    Map<String, Object> repliedUserInfo = new HashMap<>();
+                    repliedUserInfo.put("id", repliedUser.getId());
+                    repliedUserInfo.put("nickName", repliedUser.getNickName());
+                    repliedUserInfo.put("avatar", repliedUser.getAvatar());
+                    node.put("repliedUserInfo", repliedUserInfo);
+                }
+            }
+
+            node.put("replies", new ArrayList<>());  // 初始化回复列表
+            commentMap.put(comment.getCommentId(), node);
+        }
+
+        // 第二步:构建层级关系
+        for (MomentComments comment : comments) {
+            if (comment.getReplyTo() == null) {
+                // 一级评论,加入根节点
+                tree.add(commentMap.get(comment.getCommentId()));
+            } else {
+                // 回复评论,加入父节点的replies列表
+                Map<String, Object> parentNode = commentMap.get(comment.getReplyTo());
+                if (parentNode != null) {
+                    ((List<Map<String, Object>>) parentNode.get("replies")).add(commentMap.get(comment.getCommentId()));
+                }
+            }
+        }
+
+        return tree;
+    }
+
+    /**
+     * 封装动态数据并关联用户信息
      */
     private Map<String, Object> wrapMomentWithUser(UserMoments moment, Map<Long, UserLogin> userMap) {
         Map<String, Object> momentMap = new HashMap<>();
-
-        // 手动添加所有需要的字段,确保momentId存在
         momentMap.put("momentId", moment.getMomentId().toString());
         momentMap.put("contentType", moment.getContentType());
         momentMap.put("url", moment.getUrl());
         momentMap.put("content", moment.getContent());
         momentMap.put("location", moment.getLocation());
         momentMap.put("visibility", moment.getVisibility());
+        momentMap.put("createdAt", moment.getCreatedAt() != null ?
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(moment.getCreatedAt()) : "");
 
-        // 转换日期为字符串格式
-        if (moment.getCreatedAt() != null) {
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            momentMap.put("createdAt", sdf.format(moment.getCreatedAt()));
-        }
-
-        // 手动添加用户信息,只包含必要字段
+        // 关联用户信息
         UserLogin user = userMap.get(moment.getUserId());
         if (user != null) {
             Map<String, Object> userInfo = new HashMap<>();

+ 113 - 0
src/main/java/com/zhentao/osspicture/ossController.java

@@ -0,0 +1,113 @@
+package com.zhentao.osspicture;
+
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.PutObjectRequest;
+import com.zhentao.config.NullLogin;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.Null;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/api/upload")
+public class ossController {
+
+    @Value("${aliyun.oss.endpoint}")
+    private String endpoint;
+
+    @Value("${aliyun.oss.accessKeyId}")
+    private String accessKeyId;
+
+    @Value("${aliyun.oss.accessKeySecret}")
+    private String accessKeySecret;
+
+    @Value("${aliyun.oss.bucketName}")
+    private String bucketName;
+
+    // 允许的图片格式
+    private static final String[] ALLOWED_TYPES = {
+            "image/jpeg", "image/png", "image/gif"
+    };
+
+    @PostMapping("/simple-image")
+    @NullLogin
+    public Map<String, Object> uploadSimpleImage(@RequestParam("file") MultipartFile file) {
+        Map<String, Object> result = new HashMap<>();
+
+        // 基础验证
+        if (file == null || file.isEmpty()) {
+            result.put("code", 400);
+            result.put("message", "上传图片不能为空");
+            return result;
+        }
+
+        // 验证图片格式
+        String contentType = file.getContentType();
+        if (!isValidImageType(contentType)) {
+            result.put("code", 400);
+            result.put("message", "仅支持JPG、PNG、GIF格式的图片");
+            return result;
+        }
+
+        OSS ossClient = null;
+        try {
+            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+            // 生成唯一文件名
+            String originalFilename = file.getOriginalFilename();
+            String extension = getFileExtension(originalFilename);
+            String fileName = UUID.randomUUID().toString() + "." + extension;
+
+            // 上传图片
+            PutObjectRequest putObjectRequest = new PutObjectRequest(
+                    bucketName, fileName, file.getInputStream()
+            );
+            ossClient.putObject(putObjectRequest);
+
+            // 构建访问URL
+            String endpointWithoutProtocol = endpoint.replaceFirst("^https?://", "");
+            String imageUrl = "https://" + bucketName + "." + endpointWithoutProtocol + "/" + fileName;
+
+            // 返回结果
+            result.put("code", 200);
+            result.put("message", "图片上传成功");
+            result.put("imageUrl", imageUrl);
+
+        } catch (IOException e) {
+            result.put("code", 500);
+            result.put("message", "上传失败:" + e.getMessage());
+        } finally {
+            if (ossClient != null) {
+                ossClient.shutdown();
+            }
+        }
+
+        return result;
+    }
+
+    private boolean isValidImageType(String contentType) {
+        if (contentType == null) return false;
+        for (String type : ALLOWED_TYPES) {
+            if (contentType.equalsIgnoreCase(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String getFileExtension(String fileName) {
+        if (fileName == null || !fileName.contains(".")) {
+            return "jpg";
+        }
+        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
+    }
+}

+ 0 - 2
src/main/java/com/zhentao/shouye/controller/UserShouyeController.java

@@ -17,11 +17,9 @@ public class UserShouyeController {
     @GetMapping("findAll")
     @NullLogin
     public Result findAll(@RequestHeader("token") String token){
-        System.err.println(token);
         String userIdFromToken = TokenUtils.getUserIdFromToken(token);
         UserShouyeDto userShouyeDto = new UserShouyeDto();
         userShouyeDto.setUid1(Long.valueOf(userIdFromToken));
-        System.err.println(userShouyeDto);
         return userShouyeService.findAll(userShouyeDto);
     }