zhentao 1 week ago
parent
commit
0e66169324

+ 64 - 13
src/main/java/com/zhentao/moment/controller/MonmentController.java

@@ -1,14 +1,15 @@
 package com.zhentao.moment.controller;
 
+import com.zhentao.moment.dto.CommentsDto;
 import com.zhentao.moment.dto.MonmentDto;
 import com.zhentao.moment.service.UserMomentsService;
 import com.zhentao.tool.TokenUtils;
 import com.zhentao.vo.Result;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
 
 @RestController
 @RequestMapping("monment")
@@ -17,16 +18,66 @@ public class MonmentController {
     private UserMomentsService userMomentsService;
 //    发布朋友圈
     @RequestMapping("sendMonment")
-    public Result sendMonment(@RequestHeader String  token,@RequestBody MonmentDto monmentDto){
+    public Result sendMonment(@RequestHeader String  token,@ModelAttribute MonmentDto monmentDto){
         return userMomentsService.sendMonment(token,monmentDto);
     }
-////    查看所有朋友圈
-//    @RequestMapping("getAllMonment")
+//    朋友圈的个人信息
+    @RequestMapping("userinfo")
+    public Result userinfo(@RequestHeader String token){
+        return Result.OK(userMomentsService.userinfo(token),"查询成功");
+    }
+
 //    删除朋友圈
-//    @RequestMapping("deleteMonment")
-//    public Result deleteMonment(@RequestHeader String token,@RequestBody MonmentDto monmentDto){
-//        String uid = TokenUtils.getUserIdFromToken(token);
-//        monmentDto.setUid(Long.valueOf(uid));
-//        return userMomentsService.deleteMonment(monmentDto);
-//    }
+    @RequestMapping("deleteMonment")
+    public Result deleteMonment(@RequestHeader String token,@RequestBody MonmentDto monmentDto){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        monmentDto.setUid(Long.valueOf(uid));
+        return userMomentsService.deleteMonment(token,monmentDto);
+    }
+//    查看我的朋友圈
+    @RequestMapping("getMyMonment")
+    public Result getMyMonment(@RequestHeader String token){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        return Result.OK(userMomentsService.getMyMonment(Long.valueOf(uid)),"查询成功");
+    }
+//    查看好友的朋友圈
+    @RequestMapping("getFriendMonment")
+    public Result getFriendMonment(@RequestHeader String token){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        return Result.OK(userMomentsService.getFriendMonment(Long.valueOf(uid)),"查询成功");
+    }
+//    点赞接口
+    @RequestMapping("likeMonment")
+    public Result likeMonment(@RequestHeader String token,@RequestBody MonmentDto monmentDto){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        monmentDto.setUid(Long.valueOf(uid));
+        return userMomentsService.likeMonment(Long.valueOf(uid),monmentDto);
+    }
+    //  评论朋友圈
+    @RequestMapping("commentMonment")
+    public Result commentMonment(@RequestHeader String token, @RequestBody CommentsDto commentsDto){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        commentsDto.setUserId(Long.valueOf(uid));
+        return userMomentsService.commentsMonment(Long.valueOf(uid),commentsDto);
+    }
+    //  查询点赞列表
+    @RequestMapping("likeList")
+    public Result likeList(@RequestHeader String token,@RequestBody MonmentDto monmentDto){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        monmentDto.setUid(Long.valueOf(uid));
+        return userMomentsService.likeList(Long.valueOf(uid),monmentDto);
+    }
+    //  查询评论列表
+    @RequestMapping("commentList")
+    public Result commentList(@RequestHeader String token,@RequestBody CommentsDto commentsDto){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        commentsDto.setUserId(Long.valueOf(uid));
+        return userMomentsService.commentList(Long.valueOf(uid),commentsDto);
+    }
+//    更改朋友圈背景图
+    @RequestMapping("updateBackground")
+    public Result updateBackground(@RequestHeader String token,@RequestParam("file") MultipartFile file){
+        String uid = TokenUtils.getUserIdFromToken(token);
+        return userMomentsService.updateBackground(Long.valueOf(uid),file);
+    }
 }

+ 6 - 3
src/main/java/com/zhentao/moment/domain/MomentComments.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.io.Serializable;
 import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
 /**
@@ -16,7 +18,7 @@ import lombok.Data;
 @Data
 public class MomentComments implements Serializable {
     /**
-     * 
+     *
      */
     @TableId(type = IdType.AUTO)
     private Long commentId;
@@ -24,6 +26,7 @@ public class MomentComments implements Serializable {
     /**
      * 动态ID
      */
+    @JsonFormat(shape = JsonFormat.Shape.STRING)
     private Long momentId;
 
     /**
@@ -47,7 +50,7 @@ public class MomentComments implements Serializable {
     private Long replyToUser;
 
     /**
-     * 
+     *
      */
     private Date createdAt;
 
@@ -106,4 +109,4 @@ public class MomentComments implements Serializable {
         sb.append("]");
         return sb.toString();
     }
-}
+}

+ 6 - 3
src/main/java/com/zhentao/moment/domain/MomentLikes.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.io.Serializable;
 import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
 /**
@@ -16,7 +18,7 @@ import lombok.Data;
 @Data
 public class MomentLikes implements Serializable {
     /**
-     * 
+     *
      */
     @TableId(type = IdType.AUTO)
     private Long likeId;
@@ -24,6 +26,7 @@ public class MomentLikes implements Serializable {
     /**
      * 动态ID
      */
+    @JsonFormat(shape = JsonFormat.Shape.STRING)
     private Long momentId;
 
     /**
@@ -32,7 +35,7 @@ public class MomentLikes implements Serializable {
     private Long userId;
 
     /**
-     * 
+     *
      */
     private Date createdAt;
 
@@ -82,4 +85,4 @@ public class MomentLikes implements Serializable {
         sb.append("]");
         return sb.toString();
     }
-}
+}

+ 5 - 2
src/main/java/com/zhentao/moment/domain/MomentMedias.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
 /**
@@ -15,7 +17,7 @@ import lombok.Data;
 @Data
 public class MomentMedias implements Serializable {
     /**
-     * 
+     *
      */
     @TableId(type = IdType.AUTO)
     private Long mediaId;
@@ -23,6 +25,7 @@ public class MomentMedias implements Serializable {
     /**
      * 动态ID
      */
+    @JsonFormat(shape = JsonFormat.Shape.STRING)
     private Long momentId;
 
     /**
@@ -89,4 +92,4 @@ public class MomentMedias implements Serializable {
         sb.append("]");
         return sb.toString();
     }
-}
+}

+ 13 - 5
src/main/java/com/zhentao/moment/domain/UserMoments.java

@@ -6,6 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zhentao.user.domain.UserLogin;
 import lombok.Data;
 
 /**
@@ -16,9 +20,10 @@ import lombok.Data;
 @Data
 public class UserMoments implements Serializable {
     /**
-     * 
+     *
      */
     @TableId(type = IdType.AUTO)
+    @JsonFormat(shape = JsonFormat.Shape.STRING)
     private Long momentId;
 
     /**
@@ -35,7 +40,9 @@ public class UserMoments implements Serializable {
      * 内容类型(1-文本,2-图片,3-视频)
      */
     private Integer contentType;
-
+    private String url;
+    private String filename;
+    private Long filesize;
     /**
      * 可见性(0-公开,1-仅好友,2-私密)
      */
@@ -47,15 +54,16 @@ public class UserMoments implements Serializable {
     private String location;
 
     /**
-     * 
+     *
      */
     private Date createdAt;
 
     /**
-     * 
+     *
      */
     private Date updatedAt;
 
+
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
 
@@ -114,4 +122,4 @@ public class UserMoments implements Serializable {
         sb.append("]");
         return sb.toString();
     }
-}
+}

+ 6 - 0
src/main/java/com/zhentao/moment/dto/MonmentDto.java

@@ -1,14 +1,20 @@
 package com.zhentao.moment.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 @Data
 public class MonmentDto {
+//    @JsonFormat(shape = JsonFormat.Shape.STRING)
+    private String momentId;
     private Long uid;
     private Integer visible;//是否可见  1公开  2好友 3自己
     private String content;//发布内容
 //    private MultipartFile urlImage;
     private Integer contentType;//文章类型
     private String location;
+    private List<MultipartFile> files;
 }

+ 24 - 17
src/main/java/com/zhentao/moment/enums/ContentTypeEnum.java

@@ -11,24 +11,31 @@ public enum ContentTypeEnum {
         this.code = code;
         this.desc = desc;
     }
-
-    // 根据 code 获取枚举
-    public static ContentTypeEnum getByCode(Integer code) {
-        for (ContentTypeEnum type : values()) {
-            if (type.code.equals(code)) {
-                return type;
+    public static ContentTypeEnum getByCodeOrThrow(int code) {
+        for (ContentTypeEnum e : values()) {
+            if (e.code == code) {
+                return e;
             }
         }
-        // 不存在时可抛异常或返回默认值,根据业务决定
-        throw new IllegalArgumentException("无效的 content_type: " + code);
-    }
-
-    // getter
-    public Integer getCode() {
-        return code;
-    }
-
-    public String getDesc() {
-        return desc;
+        throw new IllegalArgumentException("不支持的内容类型:" + code);
     }
+    // 根据 code 获取枚举
+//    public static ContentTypeEnum getByCode(Integer code) {
+//        for (ContentTypeEnum type : values()) {
+//            if (type.code.equals(code)) {
+//                return type;
+//            }
+//        }
+//        // 不存在时可抛异常或返回默认值,根据业务决定
+//        throw new IllegalArgumentException("无效的 content_type: " + code);
+//    }
+//
+//    // getter
+//    public Integer getCode() {
+//        return code;
+//    }
+//
+//    public String getDesc() {
+//        return desc;
+//    }
 }

+ 23 - 3
src/main/java/com/zhentao/moment/service/UserMomentsService.java

@@ -2,8 +2,12 @@ package com.zhentao.moment.service;
 
 import com.zhentao.moment.domain.UserMoments;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhentao.moment.dto.CommentsDto;
 import com.zhentao.moment.dto.MonmentDto;
 import com.zhentao.vo.Result;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
 
 /**
 * @author 86159
@@ -11,8 +15,24 @@ import com.zhentao.vo.Result;
 * @createDate 2025-06-04 11:56:59
 */
 public interface UserMomentsService extends IService<UserMoments> {
-//  发布朋友圈
+    //  发布朋友圈
     Result sendMonment(String  token,MonmentDto monmentDto);
-//  删除朋友圈
-//    Result deleteMonment(MonmentDto monmentDto);
+    //  删除朋友圈
+    Result deleteMonment(String token,MonmentDto monmentDto);
+    //  获取用户信息
+    Result userinfo(String token);
+    //  查看我的朋友圈
+    Result getMyMonment(Long userId);
+    //  查看好友的朋友圈
+    Result getFriendMonment(Long userId);
+   //   点赞朋友圈
+    Result likeMonment(Long uid, MonmentDto monmentDto);
+    //  评论朋友圈
+    Result commentsMonment(Long userId, CommentsDto commentsDto);
+    //  查询点赞列表
+    Result likeList(Long uid, MonmentDto monmentDto);
+    //  查询评论列表
+    Result commentList(Long valueOf, CommentsDto commentsDto);
+    //    更改朋友圈背景图
+    Result updateBackground(Long valueOf, MultipartFile file);
 }

+ 440 - 29
src/main/java/com/zhentao/moment/service/impl/UserMomentsServiceImpl.java

@@ -1,18 +1,42 @@
 package com.zhentao.moment.service.impl;
 
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.PutObjectRequest;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhentao.moment.domain.MomentComments;
+import com.zhentao.moment.domain.MomentLikes;
 import com.zhentao.moment.domain.UserMoments;
+import com.zhentao.moment.dto.CommentsDto;
 import com.zhentao.moment.dto.MonmentDto;
 import com.zhentao.moment.enums.ContentTypeEnum;
+import com.zhentao.moment.mapper.MomentCommentsMapper;
+import com.zhentao.moment.mapper.MomentLikesMapper;
 import com.zhentao.moment.service.UserMomentsService;
 import com.zhentao.moment.mapper.UserMomentsMapper;
+import com.zhentao.osspicture.OssConfig;
+import com.zhentao.osspicture.OssUtil;
 import com.zhentao.tool.TokenUtils;
+import com.zhentao.user.domain.UserLogin;
+import com.zhentao.user.mapper.UserLoginMapper;
+import com.zhentao.userRelationships.domain.UserRelationships;
+import com.zhentao.userRelationships.mapper.UserRelationshipsMapper;
 import com.zhentao.utils.SensitiveWordFilter;
 import com.zhentao.utils.SnowflakeUtil;
 import com.zhentao.vo.Result;
 import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
 * @author 86159
@@ -20,10 +44,24 @@ import org.springframework.stereotype.Service;
 * @createDate 2025-06-04 11:56:59
 */
 @Service
+@Slf4j
 public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserMoments>
     implements UserMomentsService{
     @Autowired
     private UserMomentsMapper userMomentsMapper;
+    @Autowired
+    private UserLoginMapper userLoginMapper;
+    @Autowired
+    private MomentLikesMapper momentLikesMapper;
+//    @Autowired
+//    private OSSClient ossClient;
+    @Autowired
+    private OssConfig ossConfig;
+    @Autowired
+    private UserRelationshipsMapper userRelationshipsMapper;
+    @Autowired
+    private MomentCommentsMapper momentCommentsMapper;
+    //  发送朋友圈
     @Override
     public Result sendMonment(String token,MonmentDto monmentDto) {
         if (monmentDto.getContent()==null){
@@ -37,56 +75,429 @@ public class UserMomentsServiceImpl extends ServiceImpl<UserMomentsMapper, UserM
             userMoments.setMomentId(SnowflakeUtil.nextId());
             String userId = TokenUtils.getUserIdFromToken(token);
             userMoments.setUserId(Long.valueOf(userId));
+            String filter = SensitiveWordFilter.filter(monmentDto.getContent());
+            userMoments.setContent(filter);
             Integer typeCode = monmentDto.getContentType();
-            ContentTypeEnum type = ContentTypeEnum.getByCode(typeCode);
+            System.err.println(typeCode);
+            ContentTypeEnum type = ContentTypeEnum.getByCodeOrThrow(typeCode);
+            userMoments.setContentType(typeCode);
+            if (monmentDto.getFiles()!=null && !monmentDto.getFiles().isEmpty()){
+//                if (type!=ContentTypeEnum.IMAGE){
+//                    return Result.error(400,"只有图片类型支持上传多张");
+//                }
+
             switch (type){
-                case TEXT:
-                    String filter = SensitiveWordFilter.filter(monmentDto.getContent());
-                    userMoments.setContent(filter);
-                    break;
                 case IMAGE:
-                    validateImageContent(monmentDto.getContent());
-//                    userMoments.setContentType(ContentTypeEnum.IMAGE.getCode());
+                    for (MultipartFile file : monmentDto.getFiles()){
+                        if (file.isEmpty()){
+                            return Result.error(400,"图片不能为空");
+                        }
+                        validateImageContent(file);
+                    }
+                    List<String> imageUrls = new ArrayList<>();
+                    List<String> imageNames = new ArrayList<>();
+                    Long totalSize = 0L;
+                    String imageDir = ossConfig.getUpload().getImage().getDir();
+                    for (MultipartFile file : monmentDto.getFiles()){
+                        String imageFileName = userId + "/" + System.currentTimeMillis() +
+                                getFileExtension(file.getOriginalFilename());
+                        String ossFilePath = imageDir + imageFileName;
+//                        上传OSS
+                        String url = uploadToOss(file, ossFilePath);
+                        imageUrls.add(url);
+                        imageNames.add(file.getOriginalFilename());
+                        totalSize+=file.getSize();
+                    }
+                    String urlJson = "[" + imageUrls.stream()
+                            .map(url -> "\"" + url.replace("\"", "\\\"") + "\"") // 确保URL中的双引号被转义
+                            .collect(Collectors.joining(",")) + "]";
+                    userMoments.setUrl(urlJson);
+                    String nameJson = "[" + imageNames.stream()
+                            .map(name -> "\"" + name.replace("\"", "\\\"") + "\"")
+                            .collect(Collectors.joining(",")) + "]";
+                    userMoments.setFilename(nameJson);
+                    userMoments.setFilesize(totalSize);
+
                     break;
                 case VIDEO:
-                    validateVideoContent(monmentDto.getContent());
-//                    userMoments.setContentType(ContentTypeEnum.VIDEO.getCode());
+                    MultipartFile videoFile = monmentDto.getFiles().get(0);
+                    if (videoFile.isEmpty()){
+                        return Result.error(400,"视频不能为空");
+                    }
+                    validateVideoContent(videoFile);
+                    String videoDir = ossConfig.getUpload().getVideo().getDir();
+                    String videoFileName = userId + "/" + System.currentTimeMillis() +
+                            getFileExtension(videoFile.getOriginalFilename());
+                    String ossFilePath = videoDir + videoFileName;
+                    String url = uploadToOss(videoFile, ossFilePath);
+
+                    userMoments.setUrl(url);
+
+                    userMoments.setFilename(videoFile.getOriginalFilename());
+                    userMoments.setFilesize(videoFile.getSize());
                     break;
                 default:
-                    return Result.error(400,"内容类型错误");
+                return Result.error(400,"内容类型错误");
+                }
+            }
+            else if (type!=ContentTypeEnum.TEXT){
+                return Result.ERR(null,"类型上传不正确");
             }
 ////            userMoments.setContentType();
 //            userMoments.setContent(monmentDto.getContent());
+            userMoments.setVisibility(monmentDto.getVisible());
+            userMoments.setLocation(monmentDto.getLocation());
+            userMoments.setMomentId(SnowflakeUtil.nextId());
             userMomentsMapper.insert(userMoments);
+            Map<String,Object> map=new HashMap<>();
+            map.put("monmentId",userMoments.getMomentId());
+            map.put("ossFilePath",userMoments.getUrl());
+            return Result.OK(map,"发送成功");
         }catch (Exception e){
             e.printStackTrace();
+            return Result.error(500,"发送失败");
         }
-        return Result.OK(null,"发送成功");
+
     }
+   //   删除朋友圈
+    @Override
+    public Result deleteMonment(String token,MonmentDto monmentDto) {
+        if (monmentDto.getMomentId()==null){
+        return Result.error(400,"朋友圈id不能为空");
+        }
+        Long userId = Long.valueOf(TokenUtils.getUserIdFromToken(token));
+        UserMoments userMoments = userMomentsMapper.selectById(monmentDto.getMomentId());
+        if (userMoments.getMomentId()==null){
+            return Result.error(400,"没有此朋友圈");
+        }else{
+            if (!userId.equals(userMoments.getUserId())){
+                return Result.error(400,"没有权限");
+            }
+            userMomentsMapper.deleteById(monmentDto.getMomentId());
+            return Result.ERR(200,"删除成功");
+        }
 
-//    @Override
-//    public Result deleteMonment(MonmentDto monmentDto) {
-//
-//
-//    }
-
-    // 图片内容校验
-    private void validateImageContent(String content) {
-        // content 存图片 URL 列表,用逗号分隔
-        String[] imageUrls = content.split(",");
-        for (String url : imageUrls) {
-            if (!url.matches("^https?://.*\\.(png|jpg|jpeg)$")) {
-                throw new IllegalArgumentException("图片 URL 格式错误: " + url);
+    }
+   //  查询个人信息
+    @Override
+    public Result userinfo(String token) {
+        String userId = TokenUtils.getUserIdFromToken(token);
+        if (userId==null){
+            return Result.error(400,"没有userid");
+        }
+        UserLogin userLogin = userLoginMapper.selectById(userId);
+        return Result.OK(userLogin,"查询成功");
+    }
+   //   查询我的朋友圈
+    @Override
+    public Result getMyMonment(Long userId) {
+        QueryWrapper<UserMoments> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("user_id",userId);
+        queryWrapper.orderByDesc("created_at");
+        UserLogin userLogin = userLoginMapper.selectById(userId);
+        List<UserMoments> userMoments = userMomentsMapper.selectList(queryWrapper);
+        Map<String,Object> map=new HashMap<>();
+        map.put("userMoments",userMoments);
+        map.put("userLogin",userLogin);
+        return Result.OK(map,"查询成功");
+    }
+   //  查询好友的朋友圈
+    @Override
+    public Result getFriendMonment(Long userId) {
+        log.info("查询好友朋友圈,用户ID: {}", userId);
+
+        // 构建查询条件,只查询user_id=userId的好友关系
+        QueryWrapper<UserRelationships> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("user_id", userId)
+                .eq("status", 1)
+                .eq("is_blacklist", 0)
+                .eq("is_del", 0)
+                .eq("is_moments", 0)
+                .orderByDesc("created_at");
+
+        // 查询好友关系
+        List<UserRelationships> userRelationships = userRelationshipsMapper.selectList(queryWrapper);
+        log.info("查询到的好友关系数量: {}", userRelationships.size());
+
+        // 调试:打印查询到的每条好友关系
+        for (UserRelationships rel : userRelationships) {
+            log.info("好友关系: user_id={}, friend_id={}, status={}, is_blacklist={}, is_del={}, is_moments={}",
+                    rel.getUserId(), rel.getFriendId(), rel.getStatus(),
+                    rel.getIsBlacklist(), rel.getIsDel(), rel.getIsMoments());
+        }
+
+        // 提取好友ID(单向查询:直接从friend_id获取)
+        List<Long> friendIds = userRelationships.stream()
+                .map(UserRelationships::getFriendId)
+                .collect(Collectors.toList());
+
+        // 处理无好友情况
+        if (friendIds.isEmpty()) {
+            log.warn("没有找到好友,返回空结果");
+            return Result.OK(new ArrayList<>(), "没有好友的朋友圈");
+        }
+
+        // 查询好友的朋友圈
+        QueryWrapper<UserMoments> momentQuery = new QueryWrapper<>();
+        momentQuery.in("user_id", friendIds)
+                .ne("visibility",2)
+                .orderByDesc("created_at");
+        List<UserMoments> userMoments = userMomentsMapper.selectList(momentQuery);
+
+        // 关联用户信息
+        // 1. 提取朋友圈中所有不同的userId
+        Set<Long> userIdsInMoments = userMoments.stream()
+                .map(UserMoments::getUserId)
+                .collect(Collectors.toSet());
+
+        // 2. 根据userId列表查询用户信息
+        if (userIdsInMoments.isEmpty()) {
+            log.warn("好友没有发布任何朋友圈");
+            Map<String, Object> map = new HashMap<>();
+            map.put("userMoments", Collections.emptyList());
+            map.put("userList", Collections.emptyList());
+            return Result.OK(map, "查询成功");
+        }
+
+        QueryWrapper<UserLogin> userQuery = new QueryWrapper<>();
+        userQuery.in("id", userIdsInMoments);
+        List<UserLogin> users = userLoginMapper.selectList(userQuery);
+
+        // 3. 将用户信息转换为Map,根据userId查找
+        Map<Long, UserLogin> userMap = users.stream()
+                .collect(Collectors.toMap(UserLogin::getId, user -> user));
+
+        // 4. 包含用户信息的列表
+        List<Map<String, Object>> userList = userMoments.stream()
+                .map(moment -> {
+                    Map<String, Object> momentMap = new HashMap<>();
+                    BeanUtils.copyProperties(moment, momentMap);
+
+                    UserLogin user = userMap.get(moment.getUserId());
+                    if (user != null) {
+                        momentMap.put("nickName", user.getNickName());
+                        momentMap.put("avatar", user.getAvatar());
+                    }
+                    return momentMap;
+                })
+                .collect(Collectors.toList());
+
+        log.info("查询到的朋友圈数量: {}", userMoments.size());
+        Map<String, Object> map = new HashMap<>();
+        map.put("userMoments", userMoments);
+        map.put("userList", userList);
+        return Result.OK(map, "查询成功");
+    }
+   //  点赞朋友圈
+    @Override
+    public Result likeMonment(Long uid, MonmentDto monmentDto) {
+
+        if (monmentDto.getMomentId()==null){
+            return Result.error(400,"请选择要点赞的朋友圈");
+        }
+        QueryWrapper<MomentLikes> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("moment_id",monmentDto.getMomentId());
+        queryWrapper.eq("user_id",uid);
+        //  查询是否已点赞
+        MomentLikes momentLikes = momentLikesMapper.selectOne(queryWrapper);
+        if (momentLikes==null){
+         //  没有点赞
+         MomentLikes momentLikes1=new MomentLikes();
+         momentLikes1.setLikeId(SnowflakeUtil.nextId());
+         momentLikes1.setMomentId(Long.valueOf(monmentDto.getMomentId()));
+         momentLikes1.setUserId(uid);
+         momentLikesMapper.insert(momentLikes1);
+         return Result.OK(200,"点赞成功");
+        }else{
+        //   已点赞
+            momentLikesMapper.delete(queryWrapper);
+            return Result.error(400,"取消点赞");
+        }
+    }
+    //  评论朋友圈
+    @Override
+    public Result commentsMonment(Long userId, CommentsDto commentsDto) {
+        System.err.println(commentsDto.getMomentId());
+        MomentComments momentComments = new MomentComments();
+        momentComments.setUserId(userId);
+        momentComments.setCommentId(SnowflakeUtil.nextId());
+        UserMoments userMoments = userMomentsMapper.selectById(commentsDto.getMomentId());
+        System.err.println(userMoments);
+        if (userMoments==null){
+            return Result.error(400,"朋友圈不存在");
+        }
+        if (commentsDto.getContent()==null){
+            return Result.error(400,"评论不能为空");
+        }
+        commentsDto.setReplyTo(Long.valueOf(commentsDto.getMomentId()));
+        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);
+        return Result.OK(200,"评论成功");
+    }
+    //  查询点赞列表
+    @Override
+    public Result likeList(Long uid, MonmentDto monmentDto) {
+        if (monmentDto.getMomentId()==null){
+            return Result.error(400,"朋友圈id不能为空");
+        }
+        QueryWrapper<MomentLikes> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("moment_id",monmentDto.getMomentId());
+        List<MomentLikes> momentLikes = momentLikesMapper.selectList(queryWrapper);
+//        如果没有点赞
+        if (CollectionUtils.isEmpty(momentLikes)){
+            Map<String,Object> map = new HashMap<>();
+            map.put("likeList", Collections.emptyList());
+            map.put("userList", Collections.emptyList());
+            map.put("total", 0);
+            return Result.OK(map, "查询成功,暂无点赞数据");
+        }
+        // 提取去重后的用户ID列表
+        List<Long> userIds = momentLikes.stream()
+                .map(MomentLikes::getUserId)
+                .distinct()
+                .collect(Collectors.toList());
+        List<Long> userLikes=new ArrayList<>();
+        for (MomentLikes like:momentLikes){
+            userLikes.add(like.getUserId());
+        }
+        // 查询用户信息(需恢复此功能)
+        List<UserLogin> userLogins = userLoginMapper.selectBatchIds(userIds);
+        Map<Long, UserLogin> userMap = userLogins.stream()
+                .collect(Collectors.toMap(UserLogin::getId, user -> user));
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("likeList",momentLikes);
+       map.put("userList",userLogins);
+        return Result.OK(map,"查询成功");
+    }
+    //  查询评论列表
+    @Override
+    public Result commentList(Long valueOf, CommentsDto commentsDto) {
+        QueryWrapper<MomentComments> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("moment_id",commentsDto.getMomentId());
+        queryWrapper.orderByDesc("created_at");
+        List<MomentComments> momentComments = momentCommentsMapper.selectList(queryWrapper);
+//        查询朋友圈发布者信息
+        UserMoments userMoments = userMomentsMapper.selectById(commentsDto.getMomentId());
+        Long publisherId = null;
+        if (userMoments!=null){
+            publisherId = userMoments.getUserId();
+        }
+        List<Long> replyToUserIds=new ArrayList<>();  //存储每条评论的replyToUser
+        List<Long> replyToMomentIds=new ArrayList<>();      //存储每条评论的朋友圈id
+        List<String> userUsernames=new ArrayList<>();
+        for (MomentComments comment:momentComments){
+            UserLogin user = userLoginMapper.selectById(comment.getUserId());
+            if (user!=null){
+                userUsernames.add(user.getUserUsername());
             }
+            // 设置replyTo和replyToUser
+            if (comment.getReplyTo() == null) {
+                // 如果当前评论没有回复目标(直接评论朋友圈)
+                replyToMomentIds.add(comment.getMomentId()); // replyTo设为当前朋友圈ID
+                replyToUserIds.add(publisherId); // replyToUser设为朋友圈发布者ID
+            } else {
+                // 如果当前评论是回复其他评论
+                replyToMomentIds.add(comment.getReplyTo()); // replyTo设为被回复的评论ID
+                replyToUserIds.add(comment.getReplyToUser()); // replyToUser设为被回复的用户ID
+            }
+        }
+        commentsDto.setUserUsernames(userUsernames);
+        Map<String, Object> map = new HashMap<>();
+        map.put("commentList",momentComments);
+        map.put("usernames",userUsernames);
+        map.put("replyToUserIds", replyToUserIds); // 添加replyToUser
+        map.put("replyToMomentIds", replyToMomentIds); // 添加replyTo
+        return Result.OK(map,"查询成功");
+    }
+    //    更改朋友圈背景图
+    @Override
+    public Result updateBackground(Long valueOf, MultipartFile file) {
+
+        return null;
+    }
+
+
+    /**
+    * 上传到oss
+    * */
+    private String uploadToOss(MultipartFile file, String ossFilePath) throws IOException {
+        OSSClient ossClient = new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
+        String bucketName = ossConfig.getBucketName();
+
+        // 创建PutObject请求
+        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossFilePath,
+                file.getInputStream(), null);
+
+        // 设置对象元信息
+        ObjectMetadata metadata = new ObjectMetadata();
+        metadata.setContentType(file.getContentType());
+        metadata.setContentLength(file.getSize());
+        putObjectRequest.setMetadata(metadata);
+
+        // 上传文件
+        ossClient.putObject(putObjectRequest);
+
+        // 构建访问URL
+        String endpoint = ossConfig.getEndpoint();
+        String cleanEndpoint = endpoint.replaceAll("^https://", "");
+        String domain = "https://" + bucketName + "." + cleanEndpoint;
+        return domain + "/" + ossFilePath;
+    }
+
+    /**
+     * 获取文件扩展名
+     */
+    private String getFileExtension(String fileName) {
+        if (fileName == null || !fileName.contains(".")) {
+            return "";
         }
+        return fileName.substring(fileName.lastIndexOf("."));
     }
 
-    // 视频内容校验
-    private void validateVideoContent(String content) {
-        //  content 存视频 URL
-        if (!content.matches("^https?://.*\\.(mp4|avi)$")) {
-            throw new IllegalArgumentException("视频 URL 格式错误: " + content);
+    /**
+     * 验证图片内容
+     */
+    private void validateImageContent(MultipartFile file) throws Exception {
+        if (file == null || file.isEmpty()) {
+            throw new Exception("图片不能为空");
+        }
+
+        String contentType = file.getContentType();
+        if (!contentType.startsWith("image/")) {
+            throw new Exception("请上传图片格式文件");
         }
+
+        // 验证图片大小(例如限制为10MB)
+        if (file.getSize() > ossConfig.getUpload().getImage().getMaxSize()) {
+            throw new Exception("图片大小不能超过" +
+                    (ossConfig.getUpload().getImage().getMaxSize() / (1024 * 1024)) + "MB");
+        }
+    }
+
+    /**
+     * 验证视频内容
+     */
+    private void validateVideoContent(MultipartFile file) throws Exception {
+        if (file == null || file.isEmpty()) {
+            throw new Exception("视频不能为空");
+        }
+
+        String contentType = file.getContentType();
+        if (!contentType.startsWith("video/")) {
+            throw new Exception("请上传视频格式文件");
+        }
+
+        // 验证视频大小(例如限制为50MB)
+        if (file.getSize() > ossConfig.getUpload().getVideo().getMaxSize()) {
+            throw new Exception("视频大小不能超过" +
+                    (ossConfig.getUpload().getVideo().getMaxSize() / (1024 * 1024)) + "MB");
+        }
+
     }
 }
 

+ 61 - 1
src/main/java/com/zhentao/osspicture/OssConfig.java

@@ -1,6 +1,7 @@
 package com.zhentao.osspicture;
 
 import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
@@ -8,10 +9,69 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 @ConfigurationProperties(prefix = "aliyun.oss")
 public class OssConfig {
-    private String endpoint;
+    @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 String fileHost;
     private Integer urlExpireTime;
+    /**
+     //     * 上传配置
+     //     */
+    private Upload upload = new Upload();
+
+    /**
+     * 上传配置内部类
+     */
+    @Data
+    public static class Upload {
+
+        /**
+         * 图片上传配置
+         */
+        private Image image = new Image();
+
+        /**
+         * 视频上传配置
+         */
+        private Video video = new Video();
+
+        /**
+         * 图片上传配置内部类
+         */
+        @Data
+        public static class Image {
+
+            /**
+             * 图片上传目录
+             */
+            private String dir = "moments/images/";
+
+            /**
+             * 图片最大大小(字节),默认10MB
+             */
+            private long maxSize = 10 * 1024 * 1024;
+        }
+
+        /**
+         * 视频上传配置内部类
+         */
+        @Data
+        public static class Video {
+
+            /**
+             * 视频上传目录
+             */
+            private String dir = "moments/videos/";
+
+            /**
+             * 视频最大大小(字节),默认50MB
+             */
+            private long maxSize = 50 * 1024 * 1024;
+        }
+    }
 }

+ 1 - 1
src/main/java/com/zhentao/osspicture/OssUtil.java

@@ -3,11 +3,11 @@ package com.zhentao.osspicture;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.OSSClientBuilder;
 import com.aliyun.oss.model.PutObjectRequest;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.UUID;
 
 @Component

+ 0 - 4
src/main/java/com/zhentao/user/controller/UserController.java

@@ -1,10 +1,6 @@
 package com.zhentao.user.controller;
 
-import com.aliyun.oss.OSS;
-import com.aliyun.oss.OSSClientBuilder;
-import com.aliyun.oss.model.PutObjectRequest;
 import com.zhentao.config.NullLogin;
-import com.zhentao.information.service.WebSocketService;
 import com.zhentao.osspicture.OssUtil;
 import com.zhentao.tool.TokenUtils;
 import com.zhentao.user.domain.UserLogin;

+ 11 - 4
src/main/resources/application.yml

@@ -37,7 +37,14 @@ spring:
     database: 0
 aliyun:
   oss:
-    endpoint: https://oss-cn-beijing.aliyuncs.com
-    accessKeyId: LTAI5tH9VHPZwGJu4UX3hrL5
-    accessKeySecret: mbsutFJYLkzosvvKNr0DD28XSg4mqA
-    bucketName: fjj1
+    endpoint: https://oss-cn-beijing.aliyuncs.com  # OSS服务区域节点
+    accessKeyId: LTAI5tH9VHPZwGJu4UX3hrL5          # 替换为您的AccessKey ID
+    accessKeySecret: mbsutFJYLkzosvvKNr0DD28XSg4mqA  # 替换为您的AccessKey Secret
+    bucketName: fjj1             # 替换为您的Bucket名称
+    upload:
+      image:
+        dir: moments/images/                 # 图片上传目录
+        maxSize: 20971520                   # 图片最大大小(字节),默认10MB
+      video:
+        dir: moments/videos/                 # 视频上传目录
+        maxSize: 52428800