Browse Source

Merge remote-tracking branch 'origin/yzz' into lzy

# Conflicts:
#	Marketplace/src/main/resources/application.yml
lzy 2 months ago
parent
commit
a2b7cf7bc0
87 changed files with 4805 additions and 17 deletions
  1. 43 0
      Marketplace/pom.xml
  2. 20 0
      Marketplace/src/main/java/com/dt/config/DisableDefaultWebSocketConfig.java
  3. 130 0
      Marketplace/src/main/java/com/dt/shequ/controller/ChatController.java
  4. 128 0
      Marketplace/src/main/java/com/dt/shequ/controller/ChatHistoryController.java
  5. 116 0
      Marketplace/src/main/java/com/dt/shequ/controller/CommentController.java
  6. 78 0
      Marketplace/src/main/java/com/dt/shequ/controller/MongoTestController.java
  7. 45 0
      Marketplace/src/main/java/com/dt/shequ/controller/PostLikeController.java
  8. 342 0
      Marketplace/src/main/java/com/dt/shequ/controller/PostsController.java
  9. 83 0
      Marketplace/src/main/java/com/dt/shequ/controller/UserYzzController.java
  10. 52 0
      Marketplace/src/main/java/com/dt/shequ/domain/CommentLike.java
  11. 76 0
      Marketplace/src/main/java/com/dt/shequ/domain/PostComment.java
  12. 52 0
      Marketplace/src/main/java/com/dt/shequ/domain/PostLike.java
  13. 9 0
      Marketplace/src/main/java/com/dt/shequ/domain/PostLikeParam.java
  14. 45 0
      Marketplace/src/main/java/com/dt/shequ/domain/PostMedia.java
  15. 79 0
      Marketplace/src/main/java/com/dt/shequ/domain/Posts.java
  16. 90 0
      Marketplace/src/main/java/com/dt/shequ/domain/TopicReplies.java
  17. 80 0
      Marketplace/src/main/java/com/dt/shequ/domain/Topics.java
  18. 125 0
      Marketplace/src/main/java/com/dt/shequ/domain/User.java
  19. 52 0
      Marketplace/src/main/java/com/dt/shequ/domain/UserFollow.java
  20. 75 0
      Marketplace/src/main/java/com/dt/shequ/domain/UserInfo.java
  21. 13 0
      Marketplace/src/main/java/com/dt/shequ/dto/CommentDTO.java
  22. 11 0
      Marketplace/src/main/java/com/dt/shequ/dto/LikeDTO.java
  23. 10 0
      Marketplace/src/main/java/com/dt/shequ/dto/ParamsDto.java
  24. 9 0
      Marketplace/src/main/java/com/dt/shequ/dto/ParamsGZdto.java
  25. 61 0
      Marketplace/src/main/java/com/dt/shequ/dto/PostCommentDto.java
  26. 11 0
      Marketplace/src/main/java/com/dt/shequ/dto/TopicCommentdto.java
  27. 232 0
      Marketplace/src/main/java/com/dt/shequ/dto/TopicRepliesDto.java
  28. 73 0
      Marketplace/src/main/java/com/dt/shequ/dto/TopicsDto.java
  29. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/CommentLikeMapper.java
  30. 21 0
      Marketplace/src/main/java/com/dt/shequ/mapper/PostCommentMapper.java
  31. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/PostLikeMapper.java
  32. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/PostMediaMapper.java
  33. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/PostsMapper.java
  34. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/TopicRepliesMapper.java
  35. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/TopicsMapper.java
  36. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/UserFollowMapper.java
  37. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/UserInfoMapper.java
  38. 20 0
      Marketplace/src/main/java/com/dt/shequ/mapper/UserMapper.java
  39. 105 0
      Marketplace/src/main/java/com/dt/shequ/netty/NettyWebSocketServer.java
  40. 121 0
      Marketplace/src/main/java/com/dt/shequ/netty/UserSessionManager.java
  41. 144 0
      Marketplace/src/main/java/com/dt/shequ/netty/WebSocketFrameHandler.java
  42. 44 0
      Marketplace/src/main/java/com/dt/shequ/pojo/UserYzz.java
  43. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/CommentLikeService.java
  44. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/PostCommentService.java
  45. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/PostLikeService.java
  46. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/PostMediaService.java
  47. 46 0
      Marketplace/src/main/java/com/dt/shequ/service/PostsService.java
  48. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/TopicRepliesService.java
  49. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/TopicsService.java
  50. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/UserFollowService.java
  51. 13 0
      Marketplace/src/main/java/com/dt/shequ/service/UserInfoService.java
  52. 14 0
      Marketplace/src/main/java/com/dt/shequ/service/UserService.java
  53. 23 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/CommentLikeServiceImpl.java
  54. 85 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/PostCommentServiceImpl.java
  55. 75 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/PostLikeServiceImpl.java
  56. 23 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/PostMediaServiceImpl.java
  57. 330 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/PostsServiceImpl.java
  58. 23 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/TopicRepliesServiceImpl.java
  59. 22 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/TopicsServiceImpl.java
  60. 22 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/UserFollowServiceImpl.java
  61. 22 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/UserInfoServiceImpl.java
  62. 22 0
      Marketplace/src/main/java/com/dt/shequ/service/impl/UserServiceImpl.java
  63. 45 0
      Marketplace/src/main/java/com/dt/shequ/util/AppHttpCodeEnum.java
  64. 34 0
      Marketplace/src/main/java/com/dt/shequ/util/Constant.java
  65. 159 0
      Marketplace/src/main/java/com/dt/shequ/util/ResponseResult.java
  66. 54 0
      Marketplace/src/main/java/com/dt/shequ/util/Result.java
  67. 28 0
      Marketplace/src/main/java/com/dt/shequ/utils/MessageUtils.java
  68. 84 0
      Marketplace/src/main/java/com/dt/shequ/utils/QiniuUtils.java
  69. 292 0
      Marketplace/src/main/java/com/dt/shequ/utils/TextModerationPlusDemo.java
  70. 71 0
      Marketplace/src/main/java/com/dt/shequ/vo/Result.java
  71. 91 0
      Marketplace/src/main/java/com/dt/shequ/websocket/pojo/ChatMessage.java
  72. 54 0
      Marketplace/src/main/java/com/dt/shequ/websocket/pojo/Message.java
  73. 57 0
      Marketplace/src/main/java/com/dt/shequ/websocket/pojo/ResultMessage.java
  74. 20 2
      Marketplace/src/main/java/com/dt/user/pojo/User.java
  75. 3 2
      Marketplace/src/main/java/com/dt/user/service/impl/UserServiceImpl.java
  76. 3 2
      Marketplace/src/main/java/com/dt/user/vo/UserLoginVO.java
  77. 4 2
      Marketplace/src/main/java/com/dt/util/FaceEngineUtil.java
  78. 19 9
      Marketplace/src/main/resources/application.yml
  79. 20 0
      Marketplace/src/main/resources/mapper/CommentLikeMapper.xml
  80. 26 0
      Marketplace/src/main/resources/mapper/PostCommentMapper.xml
  81. 20 0
      Marketplace/src/main/resources/mapper/PostLikeMapper.xml
  82. 20 0
      Marketplace/src/main/resources/mapper/PostMediaMapper.xml
  83. 27 0
      Marketplace/src/main/resources/mapper/PostsMapper.xml
  84. 32 0
      Marketplace/src/main/resources/mapper/TopicRepliesMapper.xml
  85. 30 0
      Marketplace/src/main/resources/mapper/TopicsMapper.xml
  86. 20 0
      Marketplace/src/main/resources/mapper/UserFollowMapper.xml
  87. 26 0
      Marketplace/src/main/resources/mapper/UserInfoMapper.xml

+ 43 - 0
Marketplace/pom.xml

@@ -143,6 +143,49 @@
             <artifactId>spring-security-crypto</artifactId>
             <version>5.7.6</version>
         </dependency>
+<!--        yzz-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-mongodb</artifactId>
+        </dependency>
+        <!-- Netty依赖 -->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.1.94.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <!--七牛云-->
+        <dependency>
+            <groupId>com.qiniu</groupId>
+            <artifactId>qiniu-java-sdk</artifactId>
+            <version>7.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>green20220302</artifactId>
+            <version>2.2.8</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.50</version>
+        </dependency>
+<!--        yzz-->
     </dependencies>
     <dependencyManagement>
         <dependencies>

+ 20 - 0
Marketplace/src/main/java/com/dt/config/DisableDefaultWebSocketConfig.java

@@ -0,0 +1,20 @@
+package com.dt.config;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class DisableDefaultWebSocketConfig {
+
+    /**
+     * 当netty.websocket.enabled=true时,不创建ServerEndpointExporter Bean,
+     * 这样就不会启动默认的WebSocket服务器
+     */
+    @Bean
+    @ConditionalOnProperty(name = "netty.websocket.enabled", havingValue = "false", matchIfMissing = true)
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 130 - 0
Marketplace/src/main/java/com/dt/shequ/controller/ChatController.java

@@ -0,0 +1,130 @@
+package com.dt.shequ.controller;
+
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.vo.Result;
+import com.dt.shequ.websocket.pojo.ChatMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 聊天记录控制器
+ * 提供聊天记录查询接口
+ */
+@RestController
+@RequestMapping("/api/chat")
+public class ChatController {
+    private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    /**
+     * 获取用户的聊天记录
+     * 查询当前用户与指定用户之间的聊天记录
+     *
+     * @param username 当前用户名
+     * @param targetUsername 目标用户名
+     * @return 聊天记录列表
+     */
+    @GetMapping("/history")
+    @NonLoginRequired
+    public Result<List<ChatMessage>> getChatHistory(
+            @RequestParam("username") String username,
+            @RequestParam("targetUsername") String targetUsername) {
+
+        logger.info("查询用户 {} 与 {} 之间的聊天记录", username, targetUsername);
+
+        try {
+            // 构建查询条件:(fromName=username AND toName=targetUsername) OR (fromName=targetUsername AND toName=username)
+            Criteria criteria = new Criteria().orOperator(
+                    Criteria.where("fromName").is(username).and("toName").is(targetUsername),
+                    Criteria.where("fromName").is(targetUsername).and("toName").is(username)
+            );
+
+            // 创建查询并按发送时间排序
+            Query query = Query.query(criteria).with(Sort.by(Sort.Direction.ASC, "sendTime"));
+
+            // 执行查询
+            List<ChatMessage> chatHistory = mongoTemplate.find(query, ChatMessage.class);
+
+            logger.info("查询到 {} 条聊天记录", chatHistory.size());
+
+            return Result.success(chatHistory);
+        } catch (Exception e) {
+            logger.error("查询聊天记录失败", e);
+            return Result.fail("查询聊天记录失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取用户的所有聊天记录
+     *
+     * @param username 用户名
+     * @return 所有相关的聊天记录
+     */
+    @GetMapping("/all-history")
+    @NonLoginRequired
+    public Result<List<ChatMessage>> getAllChatHistory(@RequestParam("username") String username) {
+        logger.info("查询用户 {} 的所有聊天记录", username);
+
+        try {
+            // 构建查询条件:fromName=username OR toName=username
+            Criteria criteria = new Criteria().orOperator(
+                    Criteria.where("fromName").is(username),
+                    Criteria.where("toName").is(username)
+            );
+
+            // 创建查询并按发送时间排序
+            Query query = Query.query(criteria).with(Sort.by(Sort.Direction.ASC, "sendTime"));
+
+            // 执行查询
+            List<ChatMessage> chatHistory = mongoTemplate.find(query, ChatMessage.class);
+
+            logger.info("查询到 {} 条聊天记录", chatHistory.size());
+
+            return Result.success(chatHistory);
+        } catch (Exception e) {
+            logger.error("查询所有聊天记录失败", e);
+            return Result.fail("查询所有聊天记录失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 将消息标记为已读
+     *
+     * @param messageId 消息ID
+     * @return 操作结果
+     */
+    @PutMapping("/mark-read/{messageId}")
+    @NonLoginRequired
+    public Result<Void> markMessageAsRead(@PathVariable("messageId") String messageId) {
+        logger.info("标记消息 {} 为已读", messageId);
+
+        try {
+            // 查找消息
+            ChatMessage message = mongoTemplate.findById(messageId, ChatMessage.class);
+            if (message == null) {
+                return Result.fail("消息不存在");
+            }
+
+            // 标记为已读
+            message.setRead(true);
+            mongoTemplate.save(message);
+
+            logger.info("消息已标记为已读");
+
+            return Result.success();
+        } catch (Exception e) {
+            logger.error("标记消息为已读失败", e);
+            return Result.fail("标记消息为已读失败: " + e.getMessage());
+        }
+    }
+}

+ 128 - 0
Marketplace/src/main/java/com/dt/shequ/controller/ChatHistoryController.java

@@ -0,0 +1,128 @@
+package com.dt.shequ.controller;
+
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.vo.Result;
+import com.dt.shequ.websocket.pojo.ChatMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 聊天历史记录控制器
+ * 处理前端请求的/chat/history接口
+ */
+@RestController
+@RequestMapping("/chat")
+@CrossOrigin // 允许跨域请求
+public class ChatHistoryController {
+    private static final Logger logger = LoggerFactory.getLogger(ChatHistoryController.class);
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    /**
+     * 获取聊天历史记录
+     *
+     * @param fromName 发送者用户名
+     * @param toName 接收者用户名
+     * @param pageNum 页码(从1开始)
+     * @param pageSize 每页记录数
+     * @return 聊天历史记录和分页信息
+     */
+    @GetMapping("/history")
+    @NonLoginRequired
+    public Result<Map<String, Object>> getChatHistory(
+            @RequestParam("fromName") String fromName,
+            @RequestParam("toName") String toName,
+            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
+            @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
+
+        logger.info("查询用户 {} 与 {} 之间的聊天记录, 页码: {}, 每页大小: {}", fromName, toName, pageNum, pageSize);
+
+        try {
+            // 构建查询条件:(fromName=fromName AND toName=toName) OR (fromName=toName AND toName=fromName)
+            Criteria criteria = new Criteria().orOperator(
+                    Criteria.where("fromName").is(fromName).and("toName").is(toName),
+                    Criteria.where("fromName").is(toName).and("toName").is(fromName)
+            );
+
+            // 计算总记录数
+            long total = mongoTemplate.count(Query.query(criteria), ChatMessage.class);
+
+            // 创建分页查询
+            // 注意:pageNum从1开始,但PageRequest从0开始,所以需要减1
+            Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Direction.DESC, "sendTime"));
+            Query query = Query.query(criteria).with(pageable);
+
+            // 执行查询
+            List<ChatMessage> chatHistory = mongoTemplate.find(query, ChatMessage.class);
+
+            // 构造返回结果
+            Map<String, Object> result = new HashMap<>();
+            result.put("records", chatHistory);
+            result.put("total", total);
+            result.put("pageSize", pageSize);
+            result.put("pageNum", pageNum);
+            result.put("pages", (total + pageSize - 1) / pageSize); // 计算总页数
+
+            logger.info("查询到 {} 条聊天记录,总记录数: {}", chatHistory.size(), total);
+
+            return Result.success(result);
+        } catch (Exception e) {
+            logger.error("查询聊天记录失败", e);
+            return Result.fail("查询聊天记录失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取最新的聊天记录
+     *
+     * @param fromName 发送者用户名
+     * @param toName 接收者用户名
+     * @param limit 限制返回的记录数
+     * @return 最新的聊天记录
+     */
+    @GetMapping("/latest")
+    @NonLoginRequired
+    public Result<List<ChatMessage>> getLatestChatHistory(
+            @RequestParam("fromName") String fromName,
+            @RequestParam("toName") String toName,
+            @RequestParam(value = "limit", defaultValue = "20") Integer limit) {
+
+        logger.info("查询用户 {} 与 {} 之间的最新 {} 条聊天记录", fromName, toName, limit);
+
+        try {
+            // 构建查询条件
+            Criteria criteria = new Criteria().orOperator(
+                    Criteria.where("fromName").is(fromName).and("toName").is(toName),
+                    Criteria.where("fromName").is(toName).and("toName").is(fromName)
+            );
+
+            // 创建查询并按发送时间倒序排序,限制返回记录数
+            Query query = Query.query(criteria)
+                    .with(Sort.by(Sort.Direction.DESC, "sendTime"))
+                    .limit(limit);
+
+            // 执行查询
+            List<ChatMessage> chatHistory = mongoTemplate.find(query, ChatMessage.class);
+
+            logger.info("查询到 {} 条最新聊天记录", chatHistory.size());
+
+            return Result.success(chatHistory);
+        } catch (Exception e) {
+            logger.error("查询最新聊天记录失败", e);
+            return Result.fail("查询最新聊天记录失败: " + e.getMessage());
+        }
+    }
+}

+ 116 - 0
Marketplace/src/main/java/com/dt/shequ/controller/CommentController.java

@@ -0,0 +1,116 @@
+package com.dt.shequ.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.domain.CommentLike;
+import com.dt.shequ.domain.PostComment;
+
+import com.dt.shequ.service.CommentLikeService;
+//import com.dt.shequ.service.UserService;
+import com.dt.shequ.service.impl.PostCommentServiceImpl;
+import com.dt.shequ.vo.Result;
+import com.dt.user.pojo.User;
+import com.dt.user.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping("/postcomment")
+public class CommentController {
+    @Autowired
+    private PostCommentServiceImpl commentService;
+    @Autowired
+    private CommentLikeService commentLikeService;
+    @Autowired
+    private UserService userService;
+    // 获取帖子评论列表
+    // 获取帖子评论列表
+    @GetMapping("/comments")
+    @NonLoginRequired
+    public Result getPostComments() {
+        List<PostComment> list = commentService.list();
+        for (PostComment comment : list) {
+            User byId = userService.getById(comment.getUserId());
+            comment.setUsername(byId.getUsername());
+            comment.setAvatar(byId.getAvatar());
+        }
+        return Result.success(list);
+    }
+
+    // 获取评论回复列表
+    @GetMapping("/comments/{commentId}/replies")
+    @NonLoginRequired
+    public Result getCommentReplies(
+            @PathVariable Long commentId,
+            @RequestParam(defaultValue = "1") Integer pageNum,
+            @RequestParam(defaultValue = "10") Integer pageSize) {
+        Page<PostComment> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<PostComment> wrapper = Wrappers.<PostComment>lambdaQuery()
+                .eq(PostComment::getParentId, commentId)
+                .eq(PostComment::getStatus, 1)
+                .orderByAsc(PostComment::getCreatedAt);
+        return Result.success(commentService.page(page, wrapper));
+    }
+
+    // 发表评论
+    @PostMapping("/comments")
+    @NonLoginRequired
+    public Result createComment(@RequestBody PostComment comment) {
+        comment.setCreatedAt(new Date());
+        comment.setUpdatedAt(new Date());
+        comment.setStatus(1);
+        comment.setLikeCount(0);
+        return Result.success(commentService.save(comment));
+    }
+
+    // 回复评论
+    @PostMapping("/comments/reply")
+    @NonLoginRequired
+    public Result replyComment(@RequestBody PostComment comment) {
+        // 验证父评论是否存在
+        PostComment parentComment = commentService.getById(comment.getParentId());
+        if (parentComment == null) {
+            return Result.fail("失败");
+        }
+
+        comment.setCreatedAt(new Date());
+        comment.setUpdatedAt(new Date());
+        comment.setStatus(1);
+        comment.setLikeCount(0);
+        return Result.success(commentService.save(comment));
+    }
+
+    // 点赞评论
+    @PostMapping("/comments/like")
+    @NonLoginRequired
+    public Result likeComment(@RequestBody CommentLike like) {
+        return Result.success(commentService.likeComment(like));
+    }
+
+    // 取消点赞评论
+    @PostMapping("/comments/unlike")
+    @NonLoginRequired
+    public Result unlikeComment(@RequestBody CommentLike like) {
+        return Result.success(commentService.unlikeComment(like));
+    }
+
+    // 检查评论点赞状态
+    @GetMapping("/comments/checkLike")
+    @NonLoginRequired
+    public Result checkCommentLike(
+            @RequestParam(required = true) Long commentId,
+            @RequestParam(required = true) Long userId) {
+        LambdaQueryWrapper<CommentLike> wrapper = Wrappers.<CommentLike>lambdaQuery()
+                .eq(CommentLike::getCommentId, commentId)
+                .eq(CommentLike::getUserId, userId)
+                .eq(CommentLike::getStatus, 1);
+        // 使用 commentLikeService 而不是 commentService
+        return Result.success(commentLikeService.count(wrapper) > 0);
+    }
+}
+

+ 78 - 0
Marketplace/src/main/java/com/dt/shequ/controller/MongoTestController.java

@@ -0,0 +1,78 @@
+package com.dt.shequ.controller;
+
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.vo.Result;
+import com.dt.shequ.websocket.pojo.ChatMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * MongoDB测试控制器
+ * 用于测试MongoDB连接是否正常
+ */
+@RestController
+@RequestMapping("/api/mongo-test")
+public class MongoTestController {
+    private static final Logger logger = LoggerFactory.getLogger(MongoTestController.class);
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    /**
+     * 测试MongoDB连接
+     * @return 连接测试结果
+     */
+    @GetMapping("/connection")
+    @NonLoginRequired
+    public Result<Map<String, Object>> testConnection() {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            // 获取MongoDB服务器信息
+            Map<String, Object> serverStatus = mongoTemplate.getDb().runCommand(new org.bson.Document("serverStatus", 1));
+            result.put("status", "success");
+            result.put("message", "MongoDB连接成功");
+            result.put("version", serverStatus.get("version"));
+            result.put("uptime", serverStatus.get("uptime"));
+            logger.info("MongoDB连接测试成功");
+            return Result.success(result);
+        } catch (Exception e) {
+            logger.error("MongoDB连接测试失败", e);
+            result.put("status", "error");
+            result.put("message", "MongoDB连接失败: " + e.getMessage());
+            return Result.fail("MongoDB连接失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 测试MongoDB写入
+     * @return 写入测试结果
+     */
+    @GetMapping("/write-test")
+    @NonLoginRequired
+    public Result<ChatMessage> testWrite() {
+        try {
+            // 创建测试消息
+            ChatMessage testMessage = new ChatMessage("testSender", "testReceiver", "这是一条测试消息");
+            testMessage.setSendTime(new Date());
+
+            // 保存到MongoDB
+            ChatMessage savedMessage = mongoTemplate.save(testMessage);
+
+            logger.info("MongoDB写入测试成功: {}", savedMessage);
+            return Result.success(savedMessage);
+        } catch (Exception e) {
+            logger.error("MongoDB写入测试失败", e);
+            return Result.fail("MongoDB写入失败: " + e.getMessage());
+        }
+    }
+}

+ 45 - 0
Marketplace/src/main/java/com/dt/shequ/controller/PostLikeController.java

@@ -0,0 +1,45 @@
+package com.dt.shequ.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.domain.PostLike;
+import com.dt.shequ.service.impl.PostLikeServiceImpl;
+import com.dt.shequ.vo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/commentlike")
+public class PostLikeController {
+    @Autowired
+    private PostLikeServiceImpl postLikeService;
+
+    // 点赞帖子
+    // 点赞帖子
+    @PostMapping("/posts/like")
+    @NonLoginRequired
+    public Result likePost(@RequestBody PostLike like) {
+        return Result.success(postLikeService.likePost(like));
+    }
+
+    // 取消点赞帖子
+    @PostMapping("/posts/unlike")
+    @NonLoginRequired
+    public Result unlikePost(@RequestBody PostLike like) {
+        return Result.success(postLikeService.unlikePost(like));
+    }
+
+    // 检查帖子点赞状态
+    @GetMapping("/posts/checkLike")
+    @NonLoginRequired
+    public Result checkPostLike(
+            @RequestParam(required = true) Long postId,
+            @RequestParam(required = true) Long userId) {
+        LambdaQueryWrapper<PostLike> wrapper = Wrappers.<PostLike>lambdaQuery()
+                .eq(PostLike::getPostId, postId)
+                .eq(PostLike::getUserId, userId)
+                .eq(PostLike::getStatus, 1);
+        return Result.success(postLikeService.count(wrapper) > 0);
+    }
+}

+ 342 - 0
Marketplace/src/main/java/com/dt/shequ/controller/PostsController.java

@@ -0,0 +1,342 @@
+package com.dt.shequ.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.domain.*;
+import com.dt.shequ.dto.ParamsDto;
+import com.dt.shequ.dto.ParamsGZdto;
+import com.dt.shequ.dto.TopicCommentdto;
+import com.dt.shequ.dto.TopicsDto;
+import com.dt.shequ.mapper.*;
+import com.dt.shequ.service.PostMediaService;
+import com.dt.shequ.service.PostsService;
+import com.dt.shequ.service.TopicRepliesService;
+import com.dt.shequ.service.UserInfoService;
+import com.dt.shequ.util.Result;
+import com.dt.shequ.utils.QiniuUtils;
+import com.dt.user.pojo.User;
+import com.dt.user.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/community")
+public class PostsController {
+    @Autowired
+    private PostsService postsService;
+    @Autowired
+    private PostMediaService postMediaService;
+    @Autowired
+    private CommentLikeMapper commentLikeMapper;
+    @Autowired
+    private PostCommentMapper postCommentMapper;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private UserInfoService userInfoService;
+//    获取帖子信息
+    @RequestMapping("/getPosts")
+    @NonLoginRequired
+    public Result getPosts(@RequestBody ParamsDto paramsDto){
+        return postsService.getPosts(paramsDto);
+    }
+//    根据id获取帖子信息
+    @RequestMapping("/getByid")
+    @NonLoginRequired
+    public Result getById(@RequestParam("id") Long id){
+        return postsService.getbYids(id);
+    }
+    @RequestMapping("/checkFollowStatus")
+    @NonLoginRequired
+    public Result checkFollowStatus(@RequestParam("myid") Long myid,@RequestParam("wenzhangid")Long wenzhangid){
+        return postsService.wenzhangid(myid,wenzhangid);
+    }
+//    上传七牛云图片
+    @PostMapping("/upload")
+    @NonLoginRequired
+    public Result uploadImage(@RequestParam("file") MultipartFile file){
+        try {
+            String originalFilename = file.getOriginalFilename();
+            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
+            String prefix = UUID.randomUUID().toString().replaceAll("-","");
+            String fileName = prefix + suffix;
+            QiniuUtils.upload2Qiniu(file.getBytes(),fileName);
+            String url = "http://syza1bfux.hb-bkt.clouddn.com/"+fileName;
+            return new Result(200,"上传成功",url);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new Result(500,"上传失败",null);
+        }
+    }
+//    添加帖子
+    @PostMapping("/posts")
+    @NonLoginRequired
+    public Result posts(@RequestBody Posts posts) throws Exception {
+        return postsService.addposts(posts);
+    }
+//    获取话题
+    @GetMapping("gettopic")
+    @NonLoginRequired
+    public Result gettopic(){
+        return postsService.gettopic();
+    }
+//    通过id获取帖子
+    @GetMapping("/profile")
+    @NonLoginRequired
+    public Result profile(@RequestParam("id") Integer id){
+        return postsService.profile(id);
+    }
+   //    获取热门帖子
+    @GetMapping("/hot")
+    @NonLoginRequired
+    public Result hot(@RequestParam("hotid") Integer hotid){
+        return postsService.hot(hotid);
+    }
+//        //    关注
+    @PostMapping("follow")
+    @NonLoginRequired
+    public Result follow(@RequestBody ParamsGZdto paramsGZdto){
+        return postsService.follow(paramsGZdto);
+    }
+//    取消关注
+    @PostMapping("unfollow")
+    @NonLoginRequired
+    public Result unfollow(@RequestBody ParamsGZdto paramsGZdto){
+        return postsService.unfollow(paramsGZdto);
+    }
+//    获取关注信息
+    @GetMapping("findFollow")
+    @NonLoginRequired
+    public Result findFollow(){
+        return postsService.findFollow();
+    }
+//通过id获取话题
+    @GetMapping("/topics")
+    @NonLoginRequired
+    public Result topics(@RequestParam("id") Integer id){
+        return postsService.topics(id);
+    }
+//    获取话题的评论
+    @GetMapping("/topicsgetbyid")
+    @NonLoginRequired
+    public Result topicsgetbyid(@RequestParam("id") Integer id){
+    return postsService.topicsgetbyid(id);
+    }
+//    添加话题
+    @PostMapping("/addtopices")
+    @NonLoginRequired
+    public Result addTopice(@RequestBody TopicsDto topics) throws Exception {
+        return postsService.addTopice(topics);
+    }
+    @GetMapping("/getCommentsByPostId")
+    @NonLoginRequired
+    public Result findByidsport(@RequestParam("postId")Integer postId){
+        return postsService.findbyport(postId);
+    }
+    @PostMapping("/likeComment")
+    @NonLoginRequired
+    public Result likeComment(@RequestBody CommentLike like) {
+        // 检查是否已存在点赞记录
+        LambdaQueryWrapper<CommentLike> queryWrapper = Wrappers.<CommentLike>lambdaQuery()
+                .eq(CommentLike::getCommentId, like.getCommentId())
+                .eq(CommentLike::getUserId, like.getUserId());
+
+        CommentLike existingLike = commentLikeMapper.selectOne(queryWrapper);
+
+        if (existingLike != null) {
+            // 更新现有记录
+            existingLike.setStatus(1);
+            existingLike.setUpdatedAt(new Date());
+            commentLikeMapper.updateById(existingLike);
+        } else {
+            // 插入新记录
+            commentLikeMapper.insert(like);
+        }
+
+        // 更新评论点赞数
+        LambdaUpdateWrapper<PostComment> commentWrapper = Wrappers.<PostComment>lambdaUpdate()
+                .eq(PostComment::getId, like.getCommentId())
+                .setSql("like_count = like_count + 1");
+        postCommentMapper.update(null, commentWrapper);
+
+        return new Result(200,"添加成功",null);
+    }
+
+    @PostMapping("/unlikeComment")
+    @NonLoginRequired
+    public Result unlikeComment(@RequestBody CommentLike like) {
+        // 更新点赞状态为0
+        LambdaUpdateWrapper<CommentLike> updateWrapper = Wrappers.<CommentLike>lambdaUpdate()
+                .eq(CommentLike::getCommentId, like.getCommentId())
+                .eq(CommentLike::getUserId, like.getUserId())
+                .set(CommentLike::getStatus, 0)
+                .set(CommentLike::getUpdatedAt, new Date());
+
+        commentLikeMapper.update(null, updateWrapper);
+        // 更新评论点赞数
+        LambdaUpdateWrapper<PostComment> commentWrapper = Wrappers.<PostComment>lambdaUpdate()
+                .eq(PostComment::getId, like.getCommentId())
+                .setSql("like_count = like_count - 1");
+        postCommentMapper.update(null, commentWrapper);
+
+        return new Result(200,"添加成功",null);
+
+    }
+    @GetMapping("/checkCommentLike")
+    @NonLoginRequired
+    public Result checkCommentLike(@RequestParam Long commentId, @RequestParam Long userId) {
+        LambdaQueryWrapper<CommentLike> queryWrapper = Wrappers.<CommentLike>lambdaQuery()
+                .eq(CommentLike::getCommentId, commentId)
+                .eq(CommentLike::getUserId, userId)
+                .eq(CommentLike::getStatus, 1);  // 只查询状态为1(已点赞)的记录
+
+        CommentLike like = commentLikeMapper.selectOne(queryWrapper);
+        if (like==null){
+            return new Result(200,"查询失败",null);
+        }
+        return new Result(200,"添加成功",like);
+
+    }
+    @GetMapping("getpinglun")
+    @NonLoginRequired
+    public Result countments(@RequestParam("postId") Integer postId){
+        QueryWrapper<PostComment> wrapper = new QueryWrapper<>();
+        wrapper.eq("post_id",postId);
+        List<PostComment> postComments = postCommentMapper.selectList(wrapper);
+//        List<PostComment> postComments = postCommentMapper.selectList(null);
+        return new Result(200,"查询成功",postComments.size());
+    }
+    @GetMapping("/posts/like")
+    @NonLoginRequired
+    public Result getpinglunlist(@RequestBody PostLikeParam postLikeParam){
+    return null;
+    }
+    @Autowired
+    private PostLikeMapper postLikeMapper;
+    @Autowired
+    private PostsMapper postsMapper;
+    // 检查帖子点赞状态
+    @GetMapping("/checkPostLike")
+    @NonLoginRequired
+    public Result checkPostLike(@RequestParam Long postId, @RequestParam Long userId) {
+        LambdaQueryWrapper<PostLike> queryWrapper = Wrappers.<PostLike>lambdaQuery()
+                .eq(PostLike::getPostId, postId)
+                .eq(PostLike::getUserId, userId)
+                .eq(PostLike::getStatus, 1);  // 只查询状态为1(已点赞)的记录
+
+        PostLike like = postLikeMapper.selectOne(queryWrapper);
+        return new Result(200, "查询成功", like);
+    }
+
+    // 点赞帖子
+    @PostMapping("/likePost")
+    @NonLoginRequired
+    public Result likePost(@RequestBody PostLike like) {
+        // 检查是否已存在点赞记录
+        LambdaQueryWrapper<PostLike> queryWrapper = Wrappers.<PostLike>lambdaQuery()
+                .eq(PostLike::getPostId, like.getPostId())
+                .eq(PostLike::getUserId, like.getUserId());
+
+        PostLike existingLike = postLikeMapper.selectOne(queryWrapper);
+
+        if (existingLike != null) {
+            // 更新现有记录
+            existingLike.setStatus(1);
+            existingLike.setUpdatedAt(new Date());
+            postLikeMapper.updateById(existingLike);
+        } else {
+            // 插入新记录
+            like.setCreatedAt(new Date());
+            like.setUpdatedAt(new Date());
+            like.setStatus(1);
+            postLikeMapper.insert(like);
+        }
+
+        // 更新帖子点赞数
+        LambdaUpdateWrapper<Posts> postWrapper = Wrappers.<Posts>lambdaUpdate()
+                .eq(Posts::getId, like.getPostId())
+                .setSql("like_count = like_count + 1");
+        postsMapper.update(null, postWrapper);
+
+        return new Result(200, "点赞成功", null);
+    }
+
+    // 取消点赞
+    @PostMapping("/unlikePost")
+    @NonLoginRequired
+    public Result unlikePost(@RequestBody PostLike like) {
+        // 更新点赞状态为0
+        LambdaUpdateWrapper<PostLike> updateWrapper = Wrappers.<PostLike>lambdaUpdate()
+                .eq(PostLike::getPostId, like.getPostId())
+                .eq(PostLike::getUserId, like.getUserId())
+                .set(PostLike::getStatus, 0)
+                .set(PostLike::getUpdatedAt, new Date());
+
+        postLikeMapper.update(null, updateWrapper);
+
+        // 更新帖子点赞数
+        LambdaUpdateWrapper<Posts> postWrapper = Wrappers.<Posts>lambdaUpdate()
+                .eq(Posts::getId, like.getPostId())
+                .setSql("like_count = like_count - 1");
+        postsMapper.update(null, postWrapper);
+
+        return new Result(200, "取消点赞成功", null);
+    }
+    @Autowired
+    private TopicRepliesMapper topicRepliesMapper;
+    @PostMapping("/addTopicComment")
+    @NonLoginRequired
+    public Result addTopicComment(@RequestBody TopicCommentdto topicComment) {
+        TopicReplies topicReplies = new TopicReplies();
+        topicReplies.setTopicId(topicComment.getTopicId());
+        topicReplies.setUserId(topicComment.getUserId());
+        topicReplies.setContent(topicComment.getContent());
+        topicReplies.setMediaType(topicComment.getImages());
+        int insert = topicRepliesMapper.insert(topicReplies);
+        if (insert== 1) {
+            return new Result(200, "评论成功", null);
+        }else {
+            return new Result(500, "评论失败", null);
+        }
+
+    }
+    @Autowired
+    private TopicRepliesService topicRepliesService;
+    @GetMapping("/getCanYu")
+    @NonLoginRequired
+    public Result getCanYu(@RequestParam("id") Integer id) {
+        QueryWrapper<TopicReplies> wrapper = new QueryWrapper<>();
+        wrapper.eq("topic_id", id);
+        // 添加统计不同用户的条件
+        wrapper.select("COUNT(DISTINCT user_id) as count");
+        Map<String, Object> result = topicRepliesService.getMap(wrapper);
+        Integer count = result != null ? Integer.valueOf(result.get("count").toString()) : 0;
+        return new Result(200, "参与人数", count);
+    }
+
+    @RequestMapping("findDid")
+    @NonLoginRequired
+    public Result findDid(@RequestParam("username") String username){
+        QueryWrapper<com.dt.user.pojo.User> wrapper = new QueryWrapper<>();
+        wrapper.eq("username",username);
+        User one = userService.getOne(wrapper);
+        QueryWrapper<UserInfo> wrapper1 = new QueryWrapper<>();
+        wrapper1.eq("user_id",one.getId());
+        UserInfo byId = userInfoService.getOne(wrapper1);
+        byId.setUser(one);
+        return new Result(200, "成功",byId);
+    }
+
+
+
+}
+

+ 83 - 0
Marketplace/src/main/java/com/dt/shequ/controller/UserYzzController.java

@@ -0,0 +1,83 @@
+package com.dt.shequ.controller;
+
+import com.dt.config.NonLoginRequired;
+import com.dt.shequ.netty.UserSessionManager;
+import com.dt.shequ.pojo.UserYzz;
+import com.dt.shequ.vo.Result;
+import com.dt.user.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpSession;
+import java.util.Set;
+
+@RestController
+@RequestMapping("/yzzuser")
+public class UserYzzController {
+
+    @Autowired
+    private UserSessionManager userSessionManager;
+
+
+    /**
+     * 登录
+     *
+     * @param user        提交的用户数据,包含用户名和密码
+     * @param httpSession HttpSession
+     * @return Result<Object>
+     */
+    @PostMapping("/login")
+    @NonLoginRequired
+    public Result<Object> login(@RequestBody UserYzz user, HttpSession httpSession) {
+        if (user == null || !"123456".equals(user.getPassword())) {
+            return Result.fail("用户名或密码错误");
+        }
+
+        // 保存用户信息到HttpSession
+        httpSession.setAttribute("currentUser", user.getUsername());
+
+        // 保存用户信息到UserSessionManager
+        userSessionManager.userLogin(user.getUsername());
+
+        return Result.success();
+    }
+
+    /**
+     * 获取用户名
+     *
+     * @param httpSession HttpSession
+     * @return String
+     */
+    @GetMapping("/getUsername")
+    @NonLoginRequired
+    public Result<String> getUsername(HttpSession httpSession) {
+        String username = (String) httpSession.getAttribute("currentUser");
+        if (username == null || username.isEmpty()) {
+            // 返回成功但数据为null,前端会处理
+            return Result.success(null);
+        }
+        return Result.success(username);
+    }
+
+    /**
+     * 获取所有在线用户(已连接WebSocket)
+     *
+     * @return Result<Set<String>>
+     */
+    @GetMapping("/getOnlineUsers")
+    @NonLoginRequired
+    public Result<Set<String>> getOnlineUsers() {
+        return Result.success(userSessionManager.getAllOnlineUsers());
+    }
+
+    /**
+     * 获取所有登录用户(无论是否连接WebSocket)
+     *
+     * @return Result<Set<String>>
+     */
+    @GetMapping("/getLoggedInUsers")
+    @NonLoginRequired
+    public Result<Set<String>> getLoggedInUsers() {
+        return Result.success(userSessionManager.getAllLoggedInUsers());
+    }
+}

+ 52 - 0
Marketplace/src/main/java/com/dt/shequ/domain/CommentLike.java

@@ -0,0 +1,52 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 评论点赞表
+ * @TableName comment_like
+ */
+@TableName(value ="comment_like")
+@Data
+public class CommentLike implements Serializable {
+    /**
+     * 点赞ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 评论ID
+     */
+    private Long commentId;
+
+    /**
+     * 点赞用户ID
+     */
+    private Long userId;
+
+    /**
+     * 状态:1-已点赞 0-已取消
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 76 - 0
Marketplace/src/main/java/com/dt/shequ/domain/PostComment.java

@@ -0,0 +1,76 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 帖子评论表
+ * @TableName post_comment
+ */
+@TableName(value ="post_comment")
+@Data
+public class PostComment implements Serializable {
+    /**
+     * 评论ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 帖子ID
+     */
+    private Long postId;
+
+    /**
+     * 评论用户ID
+     */
+    private Long userId;
+
+    /**
+     * 评论内容
+     */
+    private String content;
+
+    /**
+     * 父评论ID,用于回复功能,NULL表示顶级评论
+     */
+    private Long parentId;
+
+    /**
+     * 回复目标用户ID
+     */
+    private Long replyToUserId;
+
+    /**
+     * 点赞数
+     */
+    private Integer likeCount;
+
+    /**
+     * 状态:1-正常 0-已删除
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+    @TableField(exist = false)
+    private String username;
+    @TableField(exist = false)
+    private String avatar;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 52 - 0
Marketplace/src/main/java/com/dt/shequ/domain/PostLike.java

@@ -0,0 +1,52 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 帖子点赞表
+ * @TableName post_like
+ */
+@TableName(value ="post_like")
+@Data
+public class PostLike implements Serializable {
+    /**
+     * 点赞ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 帖子ID
+     */
+    private Long postId;
+
+    /**
+     * 点赞用户ID
+     */
+    private Long userId;
+
+    /**
+     * 状态:1-已点赞 0-已取消
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 9 - 0
Marketplace/src/main/java/com/dt/shequ/domain/PostLikeParam.java

@@ -0,0 +1,9 @@
+package com.dt.shequ.domain;
+
+import lombok.Data;
+
+@Data
+public class PostLikeParam {
+    private Integer postId;
+    private Integer userId;
+}

+ 45 - 0
Marketplace/src/main/java/com/dt/shequ/domain/PostMedia.java

@@ -0,0 +1,45 @@
+package com.dt.shequ.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 帖子媒体表
+ * @TableName post_media
+ */
+@Data
+public class PostMedia implements Serializable {
+    /**
+     * 媒体ID
+     */
+    private Long id;
+
+    /**
+     * 关联帖子ID
+     */
+    private Long postId;
+
+    /**
+     * 媒体类型:1-图片,2-视频
+     */
+    private Integer mediaType;
+
+    /**
+     * 媒体文件路径
+     */
+    private String mediaUrl;
+
+    /**
+     * 显示顺序
+     */
+    private Integer displayOrder;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    private static final long serialVersionUID = 1L;
+}

+ 79 - 0
Marketplace/src/main/java/com/dt/shequ/domain/Posts.java

@@ -0,0 +1,79 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 帖子表
+ * @TableName posts
+ */
+@Data
+public class Posts implements Serializable {
+    /**
+     * 帖子ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 发布用户ID
+     */
+    private Integer userId;
+
+    /**
+     * 帖子标题
+     */
+    private String title;
+
+    /**
+     * 帖子内容
+     */
+    private String content;
+
+    /**
+     * 话题标签
+     */
+    private String topic;
+
+    /**
+     * 浏览数
+     */
+    private Integer viewCount;
+
+    /**
+     * 点赞数
+     */
+    private Integer likeCount;
+
+    /**
+     * 评论数
+     */
+    private Integer commentCount;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+    private String category;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+    @TableField(exist = false)
+    private List<String> imageList;
+//    @TableField(exist = false)
+//    private List<String> videoList;
+    @TableField(exist = false)
+    private String username;
+    @TableField(exist = false)
+    private String avatar;
+
+    private static final long serialVersionUID = 1L;
+}

+ 90 - 0
Marketplace/src/main/java/com/dt/shequ/domain/TopicReplies.java

@@ -0,0 +1,90 @@
+package com.dt.shequ.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 话题回复表
+ * @TableName topic_replies
+ */
+@Data
+public class TopicReplies implements Serializable {
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 话题ID
+     */
+    private Integer topicId;
+
+    /**
+     * 用户ID
+     */
+    private Integer userId;
+
+    /**
+     * 回复内容
+     */
+    private String content;
+
+    /**
+     * 是否热门回复
+     */
+    private Integer isHot;
+
+    /**
+     * 点赞数
+     */
+    private Integer likeCount;
+
+    /**
+     * 评论数
+     */
+    private Integer commentCount;
+
+    /**
+     * 浏览量
+     */
+    private Integer viewCount;
+
+    /**
+     * 媒体列表,包含图片或视频URL
+     */
+    private String mediaList;
+
+    /**
+     * 媒体类型,1-图片,2-视频
+     */
+    private String mediaType;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    /**
+     *
+     */
+    private Date updatedAt;
+
+    /**
+     * 用户类型:0-普通用户,1-专家
+     */
+    private Integer userType;
+
+    /**
+     * 用户头衔,如"儿科 执业医师"
+     */
+    private String userTitle;
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+
+    private static final long serialVersionUID = 1L;
+}

+ 80 - 0
Marketplace/src/main/java/com/dt/shequ/domain/Topics.java

@@ -0,0 +1,80 @@
+package com.dt.shequ.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 话题表
+ * @TableName topics
+ */
+@Data
+public class Topics implements Serializable {
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 话题标题,如"国产9价HPV上市了!"
+     */
+    private String title;
+
+    /**
+     * 话题描述,如"可以打国产9价HPV疫苗了!"
+     */
+    private String description;
+
+    /**
+     * 话题详细内容,如"万泰生物6月4日发布公告,其子公司申报的9价HPV疫苗获批上市..."
+     */
+    private String content;
+
+    /**
+     * 话题分类,如"疫苗"、"育儿"、"最新"等
+     */
+    private String category;
+
+    /**
+     * 是否热门话题
+     */
+    private Integer isHot;
+
+    /**
+     * 是否新话题
+     */
+    private Integer isNew;
+
+    /**
+     * 浏览量
+     */
+    private Integer viewCount;
+
+    /**
+     * 参与人数
+     */
+    private Integer participantCount;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    /**
+     *
+     */
+    private Date updatedAt;
+
+    /**
+     * 创建者ID
+     */
+    private Integer creatorId;
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+
+    private static final long serialVersionUID = 1L;
+}

+ 125 - 0
Marketplace/src/main/java/com/dt/shequ/domain/User.java

@@ -0,0 +1,125 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户表
+ * @TableName user
+ */
+@TableName(value ="user")
+@Data
+public class User implements Serializable {
+    /**
+     * 用户ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 密码(BCrypt加密)
+     */
+    private String password;
+
+    /**
+     * 真实姓名
+     */
+    private String realName;
+
+    /**
+     * 手机号
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 头像URL
+     */
+    private String avatar;
+
+    /**
+     * 性别(0-未知,1-男,2-女)
+     */
+    private Integer gender;
+
+    /**
+     * 出生日期
+     */
+    private Date birthDate;
+
+    /**
+     * 状态(0-禁用,1-正常)
+     */
+    private Integer status;
+
+    /**
+     * 最后登录时间
+     */
+    private Date lastLoginTime;
+
+    /**
+     * 最后登录IP
+     */
+    private String lastLoginIp;
+
+    /**
+     * 最后登录设备
+     */
+    private String lastLoginDevice;
+
+    /**
+     * 人脸图片URL
+     */
+    private String faceImageUrl;
+
+    /**
+     * 是否启用人脸登录(0-禁用,1-启用)
+     */
+    private Integer faceLoginEnabled;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+
+    /**
+     * 是否删除(0-未删除,1-已删除)
+     */
+    private Integer deleted;
+    @TableField(exist = false)
+    private String bio;
+    @TableField(exist = false)
+    private String citys;
+    @TableField(exist = false)
+    private Integer guanzu;
+    @TableField(exist = false)
+    private Integer fensi;
+    @TableField(exist = false)
+    private Integer huozan;
+    @TableField(exist = false)
+    private Integer did;
+    @TableField(exist = false)
+    private String avatares;
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 52 - 0
Marketplace/src/main/java/com/dt/shequ/domain/UserFollow.java

@@ -0,0 +1,52 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户关注关系表
+ * @TableName user_follow
+ */
+@TableName(value ="user_follow")
+@Data
+public class UserFollow implements Serializable {
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 关注者ID
+     */
+    private Long followerId;
+
+    /**
+     * 被关注者ID
+     */
+    private Long followingId;
+
+    /**
+     * 关注时间
+     */
+    private Date createdAt;
+
+    /**
+     * 关注状态:1-有效 0-取消
+     */
+    private Integer status;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 75 - 0
Marketplace/src/main/java/com/dt/shequ/domain/UserInfo.java

@@ -0,0 +1,75 @@
+package com.dt.shequ.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.dt.user.pojo.User;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * @TableName user_info
+ */
+@TableName(value ="user_info")
+@Data
+public class UserInfo implements Serializable {
+    /**
+     *
+     */
+    @TableId
+    private Integer id;
+
+    /**
+     *
+     */
+    private Integer userId;
+
+    /**
+     * 简介
+     */
+    private String bio;
+
+    /**
+     * 区域
+     */
+    private String citys;
+
+    /**
+     *
+     */
+    private Integer guanzu;
+
+    /**
+     *
+     */
+    private Integer fensi;
+
+    /**
+     * 背景图片
+     */
+    private String avatares;
+
+    /**
+     *
+     */
+    private Integer huozan;
+
+    /**
+     * 账号ID
+     */
+    private String did;
+
+    /**
+     *
+     */
+    private Date createTime;
+    @TableField(exist = false)
+    private User user;
+
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/dto/CommentDTO.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+@Data
+public class CommentDTO {
+    private Long id;
+    private Long postId;
+    private Long userId;
+    private String content;
+    private Long parentId;
+    private Long replyToUserId;
+}

+ 11 - 0
Marketplace/src/main/java/com/dt/shequ/dto/LikeDTO.java

@@ -0,0 +1,11 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+@Data
+public class LikeDTO {
+    private Long id;
+    private Long userId;
+    private Long postId;
+    private Long commentId;
+}

+ 10 - 0
Marketplace/src/main/java/com/dt/shequ/dto/ParamsDto.java

@@ -0,0 +1,10 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+@Data
+public class ParamsDto {
+    private Integer pageNum;
+    private Integer pageSize;
+    private String category;
+}

+ 9 - 0
Marketplace/src/main/java/com/dt/shequ/dto/ParamsGZdto.java

@@ -0,0 +1,9 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+@Data
+public class ParamsGZdto {
+    private Long followerId;
+    private Long followingId;
+}

+ 61 - 0
Marketplace/src/main/java/com/dt/shequ/dto/PostCommentDto.java

@@ -0,0 +1,61 @@
+package com.dt.shequ.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class PostCommentDto {
+    private Long id;
+
+    /**
+     * 帖子ID
+     */
+    private Long postId;
+
+    /**
+     * 评论用户ID
+     */
+    private Long userId;
+
+    /**
+     * 评论内容
+     */
+    private String content;
+
+    /**
+     * 父评论ID,用于回复功能,NULL表示顶级评论
+     */
+    private Long parentId;
+
+    /**
+     * 回复目标用户ID
+     */
+    private Long replyToUserId;
+
+    /**
+     * 点赞数
+     */
+    private Integer likeCount;
+
+    /**
+     * 状态:1-正常 0-已删除
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+    @TableField(exist = false)
+    private String username;
+    @TableField(exist = false)
+    private String avatar;
+
+}

+ 11 - 0
Marketplace/src/main/java/com/dt/shequ/dto/TopicCommentdto.java

@@ -0,0 +1,11 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+@Data
+public class TopicCommentdto {
+    private String content;
+    private Integer topicId;
+    private Integer userId;
+    private String images;
+}

+ 232 - 0
Marketplace/src/main/java/com/dt/shequ/dto/TopicRepliesDto.java

@@ -0,0 +1,232 @@
+package com.dt.shequ.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TopicRepliesDto {
+    private Long id;
+
+    /**
+     * 话题ID
+     */
+    private Integer topicId;
+
+    /**
+     * 用户ID
+     */
+    private Integer userId;
+
+    /**
+     * 回复内容
+     */
+    private String content;
+
+    /**
+     * 是否热门回复
+     */
+    private Integer isHot;
+
+    /**
+     * 点赞数
+     */
+    private Integer likeCount;
+
+    /**
+     * 评论数
+     */
+    private Integer commentCount;
+
+    /**
+     * 浏览量
+     */
+    private Integer viewCount;
+
+    /**
+     * 媒体列表,包含图片或视频URL
+     */
+    private Object mediaList;
+
+    /**
+     * 媒体类型,1-图片,2-视频
+     */
+    private Object mediaType;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    /**
+     *
+     */
+    private Date updatedAt;
+
+    /**
+     * 用户类型:0-普通用户,1-专家
+     */
+    private Integer userType;
+
+    /**
+     * 用户头衔,如"儿科 执业医师"
+     */
+    private String userTitle;
+    private String username;
+    private String avatar;
+    private String bio;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getTopicId() {
+        return topicId;
+    }
+
+    public void setTopicId(Integer topicId) {
+        this.topicId = topicId;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Integer getIsHot() {
+        return isHot;
+    }
+
+    public void setIsHot(Integer isHot) {
+        this.isHot = isHot;
+    }
+
+    public Integer getLikeCount() {
+        return likeCount;
+    }
+
+    public void setLikeCount(Integer likeCount) {
+        this.likeCount = likeCount;
+    }
+
+    public Integer getCommentCount() {
+        return commentCount;
+    }
+
+    public void setCommentCount(Integer commentCount) {
+        this.commentCount = commentCount;
+    }
+
+    public Integer getViewCount() {
+        return viewCount;
+    }
+
+    public void setViewCount(Integer viewCount) {
+        this.viewCount = viewCount;
+    }
+
+    public Object getMediaList() {
+        return mediaList;
+    }
+
+    public void setMediaList(Object mediaList) {
+        this.mediaList = mediaList;
+    }
+
+    public Object getMediaType() {
+        return mediaType;
+    }
+
+    public void setMediaType(Object mediaType) {
+        this.mediaType = mediaType;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public Integer getUserType() {
+        return userType;
+    }
+
+    public void setUserType(Integer userType) {
+        this.userType = userType;
+    }
+
+    public String getUserTitle() {
+        return userTitle;
+    }
+
+    public void setUserTitle(String userTitle) {
+        this.userTitle = userTitle;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getBio() {
+        return bio;
+    }
+
+    public void setBio(String bio) {
+        this.bio = bio;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+
+}

+ 73 - 0
Marketplace/src/main/java/com/dt/shequ/dto/TopicsDto.java

@@ -0,0 +1,73 @@
+package com.dt.shequ.dto;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class TopicsDto {
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 话题标题,如"国产9价HPV上市了!"
+     */
+    private String title;
+
+    /**
+     * 话题描述,如"可以打国产9价HPV疫苗了!"
+     */
+    private String description;
+
+    /**
+     * 话题详细内容,如"万泰生物6月4日发布公告,其子公司申报的9价HPV疫苗获批上市..."
+     */
+    private String content;
+
+    /**
+     * 话题分类,如"疫苗"、"育儿"、"最新"等
+     */
+    private String category;
+
+    /**
+     * 是否热门话题
+     */
+    private Integer isHot;
+
+    /**
+     * 是否新话题
+     */
+    private Integer isNew;
+
+    /**
+     * 浏览量
+     */
+    private Integer viewCount;
+
+    /**
+     * 参与人数
+     */
+    private Integer participantCount;
+
+    /**
+     *
+     */
+    private Date createdAt;
+
+    /**
+     *
+     */
+    private Date updatedAt;
+
+    /**
+     * 创建者ID
+     */
+    private Integer creatorId;
+
+    /**
+     * 状态:0-禁用,1-启用
+     */
+    private Integer status;
+}

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/CommentLikeMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.CommentLike;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【comment_like(评论点赞表)】的数据库操作Mapper
+* @createDate 2025-07-04 18:58:59
+* @Entity cn.edu.scau.domain.CommentLike
+*/
+@Mapper
+public interface CommentLikeMapper extends BaseMapper<CommentLike> {
+
+}
+
+
+
+

+ 21 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/PostCommentMapper.java

@@ -0,0 +1,21 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.PostComment;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【post_comment(帖子评论表)】的数据库操作Mapper
+* @createDate 2025-07-04 18:59:00
+* @Entity cn.edu.scau.domain.PostComment
+*/
+@Mapper
+
+public interface PostCommentMapper extends BaseMapper<PostComment> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/PostLikeMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.PostLike;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【post_like(帖子点赞表)】的数据库操作Mapper
+* @createDate 2025-07-04 18:59:00
+* @Entity cn.edu.scau.domain.PostLike
+*/
+@Mapper
+public interface PostLikeMapper extends BaseMapper<PostLike> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/PostMediaMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.PostMedia;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【post_media(帖子媒体表)】的数据库操作Mapper
+* @createDate 2025-07-02 19:15:07
+* @Entity cn.edu.scau.domain.PostMedia
+*/
+@Mapper
+public interface PostMediaMapper extends BaseMapper<PostMedia> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/PostsMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.Posts;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【posts(帖子表)】的数据库操作Mapper
+* @createDate 2025-07-02 19:15:07
+* @Entity cn.edu.scau.domain.Posts
+*/
+@Mapper
+public interface PostsMapper extends BaseMapper<Posts> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/TopicRepliesMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.TopicReplies;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【topic_replies(话题回复表)】的数据库操作Mapper
+* @createDate 2025-07-03 10:04:02
+* @Entity cn.edu.scau.domain.TopicReplies
+*/
+@Mapper
+public interface TopicRepliesMapper extends BaseMapper<TopicReplies> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/TopicsMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.Topics;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【topics(话题表)】的数据库操作Mapper
+* @createDate 2025-07-03 10:04:02
+* @Entity cn.edu.scau.domain.Topics
+*/
+@Mapper
+public interface  TopicsMapper extends BaseMapper<Topics> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/UserFollowMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.UserFollow;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【user_follow(用户关注关系表)】的数据库操作Mapper
+* @createDate 2025-07-04 14:34:47
+* @Entity cn.edu.scau.domain.UserFollow
+*/
+@Mapper
+public interface UserFollowMapper extends BaseMapper<UserFollow> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/UserInfoMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.UserInfo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【user_info】的数据库操作Mapper
+* @createDate 2025-07-03 17:21:26
+* @Entity cn.edu.scau.domain.UserInfo
+*/
+@Mapper
+public interface UserInfoMapper extends BaseMapper<UserInfo> {
+
+}
+
+
+
+

+ 20 - 0
Marketplace/src/main/java/com/dt/shequ/mapper/UserMapper.java

@@ -0,0 +1,20 @@
+package com.dt.shequ.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dt.shequ.domain.User;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author 86155
+* @description 针对表【user(用户表)】的数据库操作Mapper
+* @createDate 2025-07-03 15:36:46
+* @Entity cn.edu.scau.domain.User
+*/
+//@Mapper
+//public interface UserMapper extends BaseMapper<User> {
+//
+//}
+
+
+
+

+ 105 - 0
Marketplace/src/main/java/com/dt/shequ/netty/NettyWebSocketServer.java

@@ -0,0 +1,105 @@
+package com.dt.shequ.netty;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpServerCodec;
+import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
+import io.netty.handler.stream.ChunkedWriteHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+/**
+ * Netty WebSocket 服务器
+ */
+@Component
+public class NettyWebSocketServer {
+    private static final Logger logger = LoggerFactory.getLogger(NettyWebSocketServer.class);
+
+    @Value("${netty.websocket.port:7025}")
+    private int port;
+
+    @Value("${netty.websocket.path:/ws}")
+    private String websocketPath;
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    @Autowired
+    private WebSocketFrameHandler webSocketFrameHandler;
+
+    private EventLoopGroup bossGroup;
+    private EventLoopGroup workerGroup;
+
+    /**
+     * 启动Netty WebSocket服务器
+     */
+    @PostConstruct
+    public void start() throws InterruptedException {
+        logger.info("正在启动Netty WebSocket服务器...");
+        bossGroup = new NioEventLoopGroup(1);
+        workerGroup = new NioEventLoopGroup();
+
+        try {
+            // 创建服务器端的启动对象
+            ServerBootstrap bootstrap = new ServerBootstrap();
+
+            // 配置参数
+            bootstrap.group(bossGroup, workerGroup)
+                    .channel(NioServerSocketChannel.class)
+                    .option(ChannelOption.SO_BACKLOG, 128)
+                    .childOption(ChannelOption.SO_KEEPALIVE, true)
+                    .childHandler(new ChannelInitializer<SocketChannel>() {
+                        @Override
+                        protected void initChannel(SocketChannel ch) throws Exception {
+                            // 添加处理器
+                            ch.pipeline().addLast(new HttpServerCodec());
+                            ch.pipeline().addLast(new ChunkedWriteHandler());
+                            ch.pipeline().addLast(new HttpObjectAggregator(8192));
+                            ch.pipeline().addLast(new WebSocketServerProtocolHandler(websocketPath, null, true));
+                            // 使用Spring管理的WebSocketFrameHandler实例
+                            ch.pipeline().addLast(webSocketFrameHandler);
+                        }
+                    });
+
+            // 绑定端口,启动服务器
+            ChannelFuture future = bootstrap.bind(port).sync();
+            logger.info("Netty WebSocket服务器启动成功,监听端口: {}, WebSocket路径: {}", port, websocketPath);
+
+            // 对关闭通道进行监听(不会阻塞)
+            // future.channel().closeFuture().sync();
+        } catch (Exception e) {
+            logger.error("Netty WebSocket服务器启动失败", e);
+            throw e;
+        }
+    }
+
+    /**
+     * 关闭Netty WebSocket服务器
+     */
+    @PreDestroy
+    public void stop() {
+        logger.info("正在关闭Netty WebSocket服务器...");
+        if (bossGroup != null) {
+            bossGroup.shutdownGracefully();
+        }
+        if (workerGroup != null) {
+            workerGroup.shutdownGracefully();
+        }
+        logger.info("Netty WebSocket服务器已关闭");
+    }
+}

+ 121 - 0
Marketplace/src/main/java/com/dt/shequ/netty/UserSessionManager.java

@@ -0,0 +1,121 @@
+package com.dt.shequ.netty;
+
+import io.netty.channel.Channel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 用户会话管理器,管理所有登录用户和WebSocket连接
+ */
+@Component
+public class UserSessionManager {
+    private static final Logger logger = LoggerFactory.getLogger(UserSessionManager.class);
+
+    // 保存所有登录用户,无论是否连接WebSocket
+    private static final Map<String, Boolean> loggedInUsers = new ConcurrentHashMap<>();
+
+    // 保存在线的用户,key为用户名,value为Channel对象
+    private static final Map<String, Channel> onlineUsers = new ConcurrentHashMap<>();
+
+    /**
+     * 用户登录
+     * @param username 用户名
+     */
+    public void userLogin(String username) {
+        if (username != null && !username.isEmpty()) {
+            loggedInUsers.put(username, true);
+            logger.info("用户 {} 已登录系统", username);
+        }
+    }
+
+    /**
+     * 用户登出
+     * @param username 用户名
+     */
+    public void userLogout(String username) {
+        if (username != null && !username.isEmpty()) {
+            loggedInUsers.remove(username);
+            // 如果用户有WebSocket连接,也断开连接
+            Channel channel = onlineUsers.remove(username);
+            if (channel != null && channel.isActive()) {
+                channel.close();
+            }
+            logger.info("用户 {} 已登出系统", username);
+        }
+    }
+
+    /**
+     * 用户WebSocket连接
+     * @param username 用户名
+     * @param channel WebSocket通道
+     */
+    public void userConnected(String username, Channel channel) {
+        if (username != null && !username.isEmpty()) {
+            // 确保用户已登录
+            loggedInUsers.putIfAbsent(username, true);
+            // 保存WebSocket连接
+            onlineUsers.put(username, channel);
+            logger.info("用户 {} 已连接WebSocket", username);
+        }
+    }
+
+    /**
+     * 用户WebSocket断开连接
+     * @param username 用户名
+     */
+    public void userDisconnected(String username) {
+        if (username != null && !username.isEmpty()) {
+            onlineUsers.remove(username);
+            logger.info("用户 {} 已断开WebSocket连接", username);
+        }
+    }
+
+    /**
+     * 获取所有登录用户
+     * @return 所有登录用户的用户名集合
+     */
+    public Set<String> getAllLoggedInUsers() {
+        return loggedInUsers.keySet();
+    }
+
+    /**
+     * 获取所有在线用户(已连接WebSocket)
+     * @return 所有在线用户的用户名集合
+     */
+    public Set<String> getAllOnlineUsers() {
+        return onlineUsers.keySet();
+    }
+
+    /**
+     * 获取用户的WebSocket通道
+     * @param username 用户名
+     * @return WebSocket通道,如果用户不在线则返回null
+     */
+    public Channel getUserChannel(String username) {
+        return onlineUsers.get(username);
+    }
+
+    /**
+     * 判断用户是否已登录
+     * @param username 用户名
+     * @return 是否已登录
+     */
+    public boolean isUserLoggedIn(String username) {
+        return loggedInUsers.containsKey(username);
+    }
+
+    /**
+     * 判断用户是否在线(已连接WebSocket)
+     * @param username 用户名
+     * @return 是否在线
+     */
+    public boolean isUserOnline(String username) {
+        return onlineUsers.containsKey(username);
+    }
+}
+

+ 144 - 0
Marketplace/src/main/java/com/dt/shequ/netty/WebSocketFrameHandler.java

@@ -0,0 +1,144 @@
+package com.dt.shequ.netty;
+
+import com.alibaba.fastjson2.JSON;
+import com.dt.shequ.utils.MessageUtils;
+import com.dt.shequ.websocket.pojo.ChatMessage;
+import com.dt.shequ.websocket.pojo.Message;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+import io.netty.util.AttributeKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+
+/**
+ * 处理WebSocket消息的处理器
+ */
+@Component
+@ChannelHandler.Sharable
+public class WebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
+    private static final Logger logger = LoggerFactory.getLogger(WebSocketFrameHandler.class);
+
+    // 用户名属性键
+    private static final AttributeKey<String> USERNAME_KEY = AttributeKey.valueOf("username");
+
+    @Autowired
+    private UserSessionManager userSessionManager;
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {
+        // 获取客户端发送的消息
+        String message = frame.text();
+        logger.info("收到消息: {}", message);
+
+        try {
+            // 解析消息
+            Message msg = JSON.parseObject(message, Message.class);
+            logger.info("解析后的消息对象: {}", msg);
+
+            // 如果是设置用户名的消息
+            if (msg.getType() != null && "setUsername".equals(msg.getType())) {
+                String username = msg.getFromName();
+                if (username != null && !username.isEmpty()) {
+                    // 将用户名保存到Channel的属性中
+                    ctx.channel().attr(USERNAME_KEY).set(username);
+                    // 添加到在线用户列表
+                    userSessionManager.userConnected(username, ctx.channel());
+                    logger.info("用户 {} 已连接WebSocket", username);
+
+                    // 广播在线用户列表
+                    broadcastUserList();
+                }
+            }
+            // 如果是聊天消息
+            else if (msg.getToName() != null && !msg.getToName().isEmpty()) {
+                // 获取接收方用户名
+                String toName = msg.getToName();
+                String content = msg.getMessage();
+
+                // 获取发送方用户名
+                String fromName = ctx.channel().attr(USERNAME_KEY).get();
+                logger.info("准备保存消息到MongoDB, 发送者: {}, 接收者: {}, 内容: {}", fromName, toName, content);
+//              解决聊天记录属性问题
+                try {
+                    // 将消息保存到MongoDB
+                    ChatMessage chatMessage = new ChatMessage(fromName, toName, content);
+                    mongoTemplate.save(chatMessage);
+                    logger.info("消息已成功保存到MongoDB: {}", chatMessage);
+                } catch (Exception e) {
+                    logger.error("保存消息到MongoDB失败", e);
+                }
+
+                // 获取接收方的Channel
+                Channel receiverChannel = userSessionManager.getUserChannel(toName);
+                if (receiverChannel != null) {
+                    // 构造消息
+                    String messageToSend = MessageUtils.getMessage(false, fromName, content);
+                    // 发送消息
+                    receiverChannel.writeAndFlush(new TextWebSocketFrame(messageToSend));
+                    logger.info("消息从 {} 发送到 {}: {}", fromName, toName, content);
+                } else {
+                    logger.warn("接收方 {} 不在线", toName);
+                }
+            } else {
+                logger.warn("未知的消息类型或格式不正确: {}", msg);
+            }
+        } catch (Exception e) {
+            logger.error("处理WebSocket消息时发生异常", e);
+        }
+    }
+
+    @Override
+    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
+        logger.info("客户端连接: {}", ctx.channel().remoteAddress());
+    }
+
+    @Override
+    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+        // 获取用户名
+        String username = ctx.channel().attr(USERNAME_KEY).get();
+        if (username != null) {
+            // 从在线用户列表中移除
+            userSessionManager.userDisconnected(username);
+            logger.info("用户 {} 已断开WebSocket连接", username);
+
+            // 广播在线用户列表
+            broadcastUserList();
+        }
+        logger.info("客户端断开连接: {}", ctx.channel().remoteAddress());
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        logger.error("WebSocket连接发生异常", cause);
+        ctx.close();
+    }
+
+    /**
+     * 广播在线用户列表
+     */
+    private void broadcastUserList() {
+        // 获取所有登录用户列表(无论是否连接WebSocket)
+        Set<String> userList = userSessionManager.getAllLoggedInUsers();
+
+        // 构造消息
+        String message = MessageUtils.getMessage(true, null, userList);
+
+        // 广播给所有在线用户(已连接WebSocket)
+        for (String username : userSessionManager.getAllOnlineUsers()) {
+            Channel channel = userSessionManager.getUserChannel(username);
+            if (channel != null) {
+                channel.writeAndFlush(new TextWebSocketFrame(message));
+            }
+        }
+    }
+}

+ 44 - 0
Marketplace/src/main/java/com/dt/shequ/pojo/UserYzz.java

@@ -0,0 +1,44 @@
+package com.dt.shequ.pojo;
+
+
+public class UserYzz {
+
+    private String userId;
+    private String username;
+    private String password;
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    @Override
+    public String toString() {
+        return "User{" +
+                "userId='" + userId + '\'' +
+                ", username='" + username + '\'' +
+                ", password='" + password + '\'' +
+                '}';
+    }
+
+}
+

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/CommentLikeService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.CommentLike;
+
+/**
+* @author 86155
+* @description 针对表【comment_like(评论点赞表)】的数据库操作Service
+* @createDate 2025-07-04 18:58:59
+*/
+public interface CommentLikeService extends IService<CommentLike> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/PostCommentService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.PostComment;
+
+/**
+* @author 86155
+* @description 针对表【post_comment(帖子评论表)】的数据库操作Service
+* @createDate 2025-07-04 18:59:00
+*/
+public interface PostCommentService extends IService<PostComment> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/PostLikeService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.PostLike;
+
+/**
+* @author 86155
+* @description 针对表【post_like(帖子点赞表)】的数据库操作Service
+* @createDate 2025-07-04 18:59:00
+*/
+public interface PostLikeService extends IService<PostLike> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/PostMediaService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.PostMedia;
+
+/**
+* @author 86155
+* @description 针对表【post_media(帖子媒体表)】的数据库操作Service
+* @createDate 2025-07-02 19:15:07
+*/
+public interface PostMediaService extends IService<PostMedia> {
+
+}

+ 46 - 0
Marketplace/src/main/java/com/dt/shequ/service/PostsService.java

@@ -0,0 +1,46 @@
+package com.dt.shequ.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.Posts;
+import com.dt.shequ.dto.ParamsDto;
+import com.dt.shequ.dto.ParamsGZdto;
+import com.dt.shequ.dto.TopicsDto;
+import com.dt.shequ.util.Result;
+
+/**
+* @author 86155
+* @description 针对表【posts(帖子表)】的数据库操作Service
+* @createDate 2025-07-02 19:15:07
+*/
+public interface PostsService extends IService<Posts> {
+
+    Result getPosts(ParamsDto paramsDto);
+
+    Result getbYids(Long id);
+
+    Result addposts(Posts posts) throws Exception;
+
+    Result gettopic();
+
+    Result profile(Integer id);
+
+    Result hot(Integer hotid);
+
+    Result follow(ParamsGZdto paramsGZdto);
+
+    Result unfollow(ParamsGZdto paramsGZdto);
+
+    Result findFollow();
+
+    Result topics(Integer id);
+
+    Result addTopice(TopicsDto topics) throws Exception;
+
+    Result findbyport(Integer postId);
+
+    Result topicsgetbyid(Integer id);
+
+    Result wenzhangid(Long myid, Long wenzhangid);
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/TopicRepliesService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.TopicReplies;
+
+/**
+* @author 86155
+* @description 针对表【topic_replies(话题回复表)】的数据库操作Service
+* @createDate 2025-07-03 10:04:02
+*/
+public interface TopicRepliesService extends IService<TopicReplies> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/TopicsService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.Topics;
+
+/**
+* @author 86155
+* @description 针对表【topics(话题表)】的数据库操作Service
+* @createDate 2025-07-03 10:04:02
+*/
+public interface TopicsService extends IService<Topics> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/UserFollowService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.UserFollow;
+
+/**
+* @author 86155
+* @description 针对表【user_follow(用户关注关系表)】的数据库操作Service
+* @createDate 2025-07-04 14:34:47
+*/
+public interface UserFollowService extends IService<UserFollow> {
+
+}

+ 13 - 0
Marketplace/src/main/java/com/dt/shequ/service/UserInfoService.java

@@ -0,0 +1,13 @@
+package com.dt.shequ.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.UserInfo;
+
+/**
+* @author 86155
+* @description 针对表【user_info】的数据库操作Service
+* @createDate 2025-07-03 17:21:26
+*/
+public interface UserInfoService extends IService<UserInfo> {
+
+}

+ 14 - 0
Marketplace/src/main/java/com/dt/shequ/service/UserService.java

@@ -0,0 +1,14 @@
+package com.dt.shequ.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dt.shequ.domain.User;
+
+/**
+* @author 86155
+* @description 针对表【user(用户表)】的数据库操作Service
+* @createDate 2025-07-03 15:36:46
+*/
+//public interface UserService extends IService<User> {
+//
+//}

+ 23 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/CommentLikeServiceImpl.java

@@ -0,0 +1,23 @@
+package com.dt.shequ.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.CommentLike;
+import com.dt.shequ.mapper.CommentLikeMapper;
+import com.dt.shequ.service.CommentLikeService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【comment_like(评论点赞表)】的数据库操作Service实现
+* @createDate 2025-07-04 18:58:59
+*/
+@Service
+public class CommentLikeServiceImpl extends ServiceImpl<CommentLikeMapper, CommentLike>
+    implements CommentLikeService {
+
+}
+
+
+
+

+ 85 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/PostCommentServiceImpl.java

@@ -0,0 +1,85 @@
+package com.dt.shequ.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.CommentLike;
+import com.dt.shequ.domain.PostComment;
+import com.dt.shequ.mapper.CommentLikeMapper;
+import com.dt.shequ.mapper.PostCommentMapper;
+import com.dt.shequ.service.PostCommentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+* @author 86155
+* @description 针对表【post_comment(帖子评论表)】的数据库操作Service实现
+* @createDate 2025-07-04 18:59:00
+*/
+@Service
+public class PostCommentServiceImpl extends ServiceImpl<PostCommentMapper, PostComment>
+    implements PostCommentService {
+    @Autowired
+    private CommentLikeMapper commentLikeMapper;
+    @Transactional
+    public boolean likeComment(CommentLike like) {
+        like.setCreatedAt(new Date());
+        like.setUpdatedAt(new Date());
+        like.setStatus(1);
+
+        // 更新评论点赞数
+        LambdaUpdateWrapper<PostComment> updateWrapper = Wrappers.<PostComment>lambdaUpdate()
+                .eq(PostComment::getId, like.getCommentId())
+                .setSql("like_count = like_count + 1");
+        this.update(updateWrapper);
+
+        // 保存或更新点赞记录
+        LambdaQueryWrapper<CommentLike> queryWrapper = Wrappers.<CommentLike>lambdaQuery()
+                .eq(CommentLike::getCommentId, like.getCommentId())
+                .eq(CommentLike::getUserId, like.getUserId());
+
+        CommentLike existingLike = commentLikeMapper.selectOne(queryWrapper);
+        if (existingLike != null) {
+            existingLike.setStatus(1);
+            existingLike.setUpdatedAt(new Date());
+            return commentLikeMapper.updateById(existingLike) > 0;
+        } else {
+            return commentLikeMapper.insert(like) > 0;
+        }
+    }
+
+    @Transactional
+    public boolean unlikeComment(CommentLike like) {
+        // 更新评论点赞数
+        LambdaUpdateWrapper<PostComment> updateWrapper = Wrappers.<PostComment>lambdaUpdate()
+                .eq(PostComment::getId, like.getCommentId())
+                .setSql("like_count = like_count - 1");
+        this.update(updateWrapper);
+
+        // 更新点赞状态
+        LambdaUpdateWrapper<CommentLike> likeUpdateWrapper = Wrappers.<CommentLike>lambdaUpdate()
+                .eq(CommentLike::getCommentId, like.getCommentId())
+                .eq(CommentLike::getUserId, like.getUserId())
+                .set(CommentLike::getStatus, 0)
+                .set(CommentLike::getUpdatedAt, new Date());
+
+        return commentLikeMapper.update(null, likeUpdateWrapper) > 0;
+    }
+
+    public boolean checkCommentLike(Long commentId, Long userId) {
+        LambdaQueryWrapper<CommentLike> wrapper = Wrappers.<CommentLike>lambdaQuery()
+                .eq(CommentLike::getCommentId, commentId)
+                .eq(CommentLike::getUserId, userId)
+                .eq(CommentLike::getStatus, 1);
+        return commentLikeMapper.selectCount(wrapper) > 0;
+    }
+}
+
+
+
+

+ 75 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/PostLikeServiceImpl.java

@@ -0,0 +1,75 @@
+package com.dt.shequ.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.PostLike;
+import com.dt.shequ.mapper.PostLikeMapper;
+import com.dt.shequ.service.PostLikeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+* @author 86155
+* @description 针对表【post_like(帖子点赞表)】的数据库操作Service实现
+* @createDate 2025-07-04 18:59:00
+*/
+@Service
+public class PostLikeServiceImpl extends ServiceImpl<PostLikeMapper, PostLike>
+    implements PostLikeService {
+    @Autowired
+    private PostLikeMapper postMapper;
+    @Transactional
+    public boolean likePost(PostLike like) {
+        like.setCreatedAt(new Date());
+        like.setUpdatedAt(new Date());
+        like.setStatus(1);
+
+        // 更新帖子点赞数
+        LambdaUpdateWrapper<PostLike> updateWrapper = Wrappers.<PostLike>lambdaUpdate()
+                .eq(PostLike::getId, like.getPostId())
+                .setSql("like_count = like_count + 1");
+        postMapper.update(null, updateWrapper);
+
+        // 保存或更新点赞记录
+        LambdaQueryWrapper<PostLike> queryWrapper = Wrappers.<PostLike>lambdaQuery()
+                .eq(PostLike::getPostId, like.getPostId())
+                .eq(PostLike::getUserId, like.getUserId());
+
+        PostLike existingLike = this.getOne(queryWrapper);
+        if (existingLike != null) {
+            existingLike.setStatus(1);
+            existingLike.setUpdatedAt(new Date());
+            return this.updateById(existingLike);
+        } else {
+            return this.save(like);
+        }
+    }
+
+    @Transactional
+    public boolean unlikePost(PostLike like) {
+        // 更新帖子点赞数
+        LambdaUpdateWrapper<PostLike> updateWrapper = Wrappers.<PostLike>lambdaUpdate()
+                .eq(PostLike::getId, like.getPostId())
+                .setSql("like_count = like_count - 1");
+        postMapper.update(null, updateWrapper);
+
+        // 更新点赞状态
+        LambdaUpdateWrapper<PostLike> likeUpdateWrapper = Wrappers.<PostLike>lambdaUpdate()
+                .eq(PostLike::getPostId, like.getPostId())
+                .eq(PostLike::getUserId, like.getUserId())
+                .set(PostLike::getStatus, 0)
+                .set(PostLike::getUpdatedAt, new Date());
+
+        return this.update(likeUpdateWrapper);
+    }
+}
+
+
+
+

+ 23 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/PostMediaServiceImpl.java

@@ -0,0 +1,23 @@
+package com.dt.shequ.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.PostMedia;
+import com.dt.shequ.mapper.PostMediaMapper;
+import com.dt.shequ.service.PostMediaService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【post_media(帖子媒体表)】的数据库操作Service实现
+* @createDate 2025-07-02 19:15:07
+*/
+@Service
+public class PostMediaServiceImpl extends ServiceImpl<PostMediaMapper, PostMedia>
+    implements PostMediaService {
+
+}
+
+
+
+

+ 330 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/PostsServiceImpl.java

@@ -0,0 +1,330 @@
+package com.dt.shequ.service.impl;
+
+
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.*;
+import com.dt.shequ.dto.*;
+import com.dt.shequ.mapper.*;
+import com.dt.shequ.service.PostsService;
+import com.dt.shequ.util.ResponseResult;
+import com.dt.shequ.util.Result;
+import com.dt.shequ.utils.TextModerationPlusDemo;
+import com.dt.user.mapper.UserMapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+* @author 86155
+* @description 针对表【posts(帖子表)】的数据库操作Service实现
+* @createDate 2025-07-02 19:15:07
+*/
+@Service
+public class PostsServiceImpl extends ServiceImpl<PostsMapper, Posts>
+    implements PostsService {
+    @Autowired
+    private PostsMapper postsMapper;
+    @Autowired
+    private PostMediaMapper postMediaMapper;
+    @Autowired
+    private TopicsMapper topicsMapper;
+    @Autowired
+    private UserMapper userMapper;
+    @Autowired
+    private UserInfoMapper userInfoMapper;
+    @Autowired
+    private UserFollowMapper userFollowMapper;
+    @Autowired
+    private PostCommentMapper postCommentMapper;
+    @Autowired
+    private TopicRepliesMapper topicRepliesMapper;
+    @Override
+    public Result getPosts(ParamsDto paramsDto) {
+        Page<Posts> page = new Page<>(paramsDto.getPageNum(), paramsDto.getPageSize());
+        QueryWrapper<Posts> queryWrapper = new QueryWrapper<>();
+        if (paramsDto.getCategory()!=null && paramsDto.getCategory().equals("问答")){
+            queryWrapper.eq("category",paramsDto.getCategory());
+        }
+        if (paramsDto.getCategory()!=null && paramsDto.getCategory().equals("活动")){
+            queryWrapper.eq("category",paramsDto.getCategory());
+        }
+        Page<Posts> postsPage = postsMapper.selectPage(page, queryWrapper);
+        for (Posts post : postsPage.getRecords()) {
+            com.dt.user.pojo.User user = userMapper.selectById(post.getUserId());
+//            根据用户id来获取姓名,图片等信息。
+            post.setUsername(user.getUsername());
+            post.setAvatar(user.getAvatar());
+//            post.setAvatar("https://tse2-mm.cn.bing.net/th/id/OIP-C.5OkGLT2dXMg2bxzWGO7igAHaDq?w=320&h=173&c=7&r=0&o=7&dpr=1.5&pid=1.7&rm=3");
+            List<PostMedia> postId = postMediaMapper.selectList(new QueryWrapper<PostMedia>().eq("post_id", post.getId()));
+            // 分类存储图片和视频URL
+            List<String> images = new ArrayList<>();
+            // 媒体类型:1-图片,2-视频(根据你的数据库定义调整)
+            for (PostMedia media : postId) {
+                  images.add(media.getMediaUrl());
+            }
+            post.setImageList(images);
+            System.err.println(postsPage.getRecords());
+        }
+        return new Result(200, "success",postsPage.getRecords());
+    }
+
+    @Override
+    public Result getbYids(Long id) {
+        Posts posts = postsMapper.selectById(id);
+        // 分类存储图片和视频URL
+        List<String> images = new ArrayList<>();
+        com.dt.user.pojo.User user = userMapper.selectById(posts.getUserId());
+//            根据用户id来获取姓名,图片等信息。
+        posts.setUsername(user.getUsername());
+        posts.setAvatar(user.getAvatar());
+
+//        posts.setUsername("宝妈玛丽");
+//        posts.setAvatar("https://tse2-mm.cn.bing.net/th/id/OIP-C.5OkGLT2dXMg2bxzWGO7igAHaDq?w=320&h=173&c=7&r=0&o=7&dpr=1.5&pid=1.7&rm=3");
+        List<PostMedia> postId = postMediaMapper.selectList(new QueryWrapper<PostMedia>().eq("post_id", posts.getId()));
+        for (PostMedia media : postId) {
+            images.add(media.getMediaUrl());
+        }
+        posts.setImageList(images);
+        return new Result(200, "成功",posts);
+    }
+
+    @Override
+    @Transactional
+    public Result addposts(Posts posts) throws Exception {
+        // 直接调用MyBatis-Plus的save方法,会自动回填自增主键
+        String content = posts.getContent()+posts.getTitle();
+        ResponseResult responseResult = TextModerationPlusDemo.textModerationPlus(content);
+        if(responseResult.getCode()==200){
+            int saveResult = postsMapper.insert(posts); // 假设postsService是IService<Posts>的实现类
+            if (saveResult != 1) {
+                return new Result(500, "帖子表插入失败", null);
+            }
+
+            // 自增主键已自动回填到posts对象中
+            Integer postId = posts.getId();
+            if (postId == null) {
+                return new Result(500, "获取帖子ID失败", null);
+            }
+
+            List<String> imageList = posts.getImageList();
+            if (imageList != null && !imageList.isEmpty()) {
+                Date now = new Date();
+                for (int i = 0; i < imageList.size(); i++) {
+                    PostMedia postMedia = new PostMedia();
+                    // 假设PostMedia的id仍使用雪花算法(如果PostMedia的id也是自增,移除这行)
+                    long mediaId = IdUtil.getSnowflake(2, 2).nextId();
+                    postMedia.setId(mediaId);
+                    postMedia.setPostId(Long.valueOf(postId)); // 使用回填的帖子ID
+                    postMedia.setMediaType(1);
+                    postMedia.setMediaUrl(imageList.get(i));
+                    postMedia.setDisplayOrder(i + 1);
+                    postMedia.setCreatedAt(now);
+
+                    int mediaSaveResult = postMediaMapper.insert(postMedia);
+                    if (mediaSaveResult != 1) {
+                        return new Result(500, "图片媒体表插入失败,第" + (i + 1) + "条数据异常", null);
+                    }
+
+                }
+            }
+
+
+            System.err.println("审核通过");
+            return new Result(200,"添加成功","添加成功");
+        }else {
+            return new Result(400,"审核失败,存在违规内容",null);
+        }
+
+
+
+    }
+
+    @Override
+    public Result gettopic() {
+//        List<Topics> topics = topicsMapper.selectList(null);
+        List<Topics> topics = topicsMapper.selectList(null);
+
+// 根据某个字段去重(例如:name字段)
+        List<Topics> distinctTopics = topics.stream()
+                .collect(Collectors.toMap(
+                        Topics::getTitle,  // key: 去重字段
+                        Function.identity(),  // value: 对象本身
+                        (existing, replacement) -> existing  // 冲突时保留先出现的对象
+                ))
+                .values()
+                .stream()
+                .collect(Collectors.toList());
+
+        return new Result(200, "success", distinctTopics);
+//        return new Result(200, "success",topics);
+    }
+
+    @Override
+    public Result profile(Integer id) {
+        com.dt.user.pojo.User user = userMapper.selectById(id);
+        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
+        wrapper.eq("user_id",id);
+        UserInfo userInfo = userInfoMapper.selectOne(wrapper);
+        user.setBio(userInfo.getBio());
+        user.setCitys(userInfo.getCitys());
+        user.setGuanzu(userInfo.getGuanzu());
+        user.setFensi(userInfo.getFensi());
+        user.setHuozan(userInfo.getHuozan());
+        user.setAvatares(userInfo.getAvatares());
+        return new Result(200, "success",user);
+    }
+
+    @Override
+    public Result hot(Integer hotid) {
+        QueryWrapper<Topics> wrapper = new QueryWrapper<>();
+        if (hotid==1){
+            wrapper.eq("is_hot",hotid);
+        }
+        List<Topics> topics = topicsMapper.selectList(wrapper);
+        if (topics!=null){
+            return new Result(200, "success",topics);
+
+        }else {
+            return new Result(500, "success",null);
+        }
+    }
+
+    @Override
+    public Result findFollow() {
+        List<UserFollow> userFollows = userFollowMapper.selectList(null);
+        return new Result(200, "success",userFollows);
+    }
+
+    @Override
+    public Result follow(ParamsGZdto paramsGZdto) {
+        UserFollow userFollow= new UserFollow();
+        userFollow.setFollowerId(paramsGZdto.getFollowerId());
+        userFollow.setFollowingId(paramsGZdto.getFollowingId());
+        userFollow.setCreatedAt(new Date());
+        userFollow.setStatus(1);
+        int insert = userFollowMapper.insert(userFollow);
+        if (insert==1){
+            return new Result(200, "success",null);
+        }else {
+            return new Result(500, "失败",null);
+        }
+    }
+
+    @Override
+    public Result unfollow(ParamsGZdto paramsGZdto) {
+        QueryWrapper<UserFollow> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("follower_id",paramsGZdto.getFollowerId());
+        queryWrapper.eq("following_id",paramsGZdto.getFollowingId());
+        UserFollow userFollow = userFollowMapper.selectOne(queryWrapper);
+        int i = userFollowMapper.deleteById(userFollow);
+//        if (userFollow.getStatus()==1){
+//            userFollow.setStatus(0);
+//        }else {
+//            userFollow.setStatus(1);
+//        }
+//
+//        int i = userFollowMapper.updateById(userFollow);
+        if (i==1){
+            return new Result(200, "success",null);
+        }else {
+            return new Result(500, "失败",null);
+        }
+    }
+
+    @Override
+    public Result topics(Integer id) {
+        Topics topics = topicsMapper.selectById(id);
+        return new Result(200, "success",topics);
+    }
+
+    @Override
+    public Result addTopice(TopicsDto topics) throws Exception {
+        String title = topics.getTitle();
+        String contents = topics.getContent();
+        String content = title+contents;
+        ResponseResult responseResult = TextModerationPlusDemo.textModerationPlus(content);
+        if(responseResult.getCode()==200){
+            topics.setCreatedAt(new Date());
+            Topics topics1 = new Topics();
+            BeanUtils.copyProperties(topics,topics1);
+            int insert = topicsMapper.insert(topics1);
+            System.err.println("审核通过");
+            return new Result(200,"添加成功","添加成功");
+        }else {
+            return new Result(400,"审核失败,存在违规内容",null);
+        }
+
+    }
+
+    @Override
+    public Result findbyport(Integer postId) {
+        QueryWrapper<PostComment> wrapper = new QueryWrapper<>();
+        wrapper.eq("post_id", postId);
+        List<PostComment> postComments = postCommentMapper.selectList(wrapper);
+
+        List<PostCommentDto> postCommentDtoList = new ArrayList<>();
+// 遍历查询结果并转换为DTO
+        for (PostComment comment : postComments) {
+            com.dt.user.pojo.User byId = userMapper.selectById(comment.getUserId());
+            comment.setUsername(byId.getUsername());
+            comment.setAvatar(byId.getAvatar());
+            PostCommentDto dto = new PostCommentDto();
+            BeanUtils.copyProperties(comment, dto);
+            postCommentDtoList.add(dto);
+        }
+
+        return new Result(200, null, postCommentDtoList);
+    }
+
+    @Override
+    public Result topicsgetbyid(Integer id) {
+        QueryWrapper<TopicReplies> wrapper = new QueryWrapper<>();
+        wrapper.eq("topic_id", id);
+        List<TopicReplies> topicReplies = topicRepliesMapper.selectList(wrapper);
+        List<TopicRepliesDto> topicRepliesDtoList = new ArrayList<>();
+        for (TopicReplies topicReply : topicReplies) {
+            TopicRepliesDto dto = new TopicRepliesDto();
+            topicReply.getUserId();
+            com.dt.user.pojo.User byId = userMapper.selectById(topicReply.getUserId());
+            QueryWrapper<UserInfo> wrapper1 = new QueryWrapper<>();
+            wrapper1.eq("user_id", topicReply.getUserId());
+            UserInfo userInfo = userInfoMapper.selectOne(wrapper1);
+            dto.setAvatar(byId.getAvatar());
+            dto.setUsername(byId.getUsername());
+            dto.setBio(userInfo.getBio());
+            // 把源对象(topicReply)的属性值复制到目标对象(dto)
+            BeanUtils.copyProperties(topicReply, dto);
+            topicRepliesDtoList.add(dto);
+        }
+        return new Result(200,"查询成功", topicRepliesDtoList);
+    }
+
+    @Override
+    public Result wenzhangid(Long myid, Long wenzhangid) {
+        QueryWrapper<UserFollow> wrapper = new QueryWrapper<>();
+        wrapper.eq("follower_id", myid);
+        wrapper.eq("following_id", wenzhangid);
+        UserFollow userFollow = userFollowMapper.selectOne(wrapper);
+        List<UserFollow> userFollows = userFollowMapper.selectList(null);
+        System.err.println(userFollows);
+        if (userFollow != null) {
+ return new Result(200,"关注成功", userFollow);
+        }else {
+ return new Result(200,"未关注", null);
+        }
+    }
+}
+
+
+
+

+ 23 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/TopicRepliesServiceImpl.java

@@ -0,0 +1,23 @@
+package com.dt.shequ.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.TopicReplies;
+import com.dt.shequ.mapper.TopicRepliesMapper;
+import com.dt.shequ.service.TopicRepliesService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【topic_replies(话题回复表)】的数据库操作Service实现
+* @createDate 2025-07-03 10:04:02
+*/
+@Service
+public class TopicRepliesServiceImpl extends ServiceImpl<TopicRepliesMapper, TopicReplies>
+    implements TopicRepliesService {
+
+}
+
+
+
+

+ 22 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/TopicsServiceImpl.java

@@ -0,0 +1,22 @@
+package com.dt.shequ.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.Topics;
+import com.dt.shequ.mapper.TopicsMapper;
+import com.dt.shequ.service.TopicsService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【topics(话题表)】的数据库操作Service实现
+* @createDate 2025-07-03 10:04:02
+*/
+@Service
+public class TopicsServiceImpl extends ServiceImpl<TopicsMapper, Topics>
+    implements TopicsService {
+
+}
+
+
+
+

+ 22 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/UserFollowServiceImpl.java

@@ -0,0 +1,22 @@
+package com.dt.shequ.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.UserFollow;
+import com.dt.shequ.mapper.UserFollowMapper;
+import com.dt.shequ.service.UserFollowService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【user_follow(用户关注关系表)】的数据库操作Service实现
+* @createDate 2025-07-04 14:34:47
+*/
+@Service
+public class UserFollowServiceImpl extends ServiceImpl<UserFollowMapper, UserFollow>
+    implements UserFollowService {
+
+}
+
+
+
+

+ 22 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/UserInfoServiceImpl.java

@@ -0,0 +1,22 @@
+package com.dt.shequ.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dt.shequ.domain.UserInfo;
+import com.dt.shequ.mapper.UserInfoMapper;
+import com.dt.shequ.service.UserInfoService;
+import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【user_info】的数据库操作Service实现
+* @createDate 2025-07-03 17:21:26
+*/
+@Service
+public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
+    implements UserInfoService {
+
+}
+
+
+
+

+ 22 - 0
Marketplace/src/main/java/com/dt/shequ/service/impl/UserServiceImpl.java

@@ -0,0 +1,22 @@
+//package com.dt.shequ.service.impl;
+
+//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+//import com.dt.shequ.domain.User;
+//import com.dt.shequ.mapper.UserMapper;
+////import com.dt.shequ.service.UserService;
+//import org.springframework.stereotype.Service;
+
+/**
+* @author 86155
+* @description 针对表【user(用户表)】的数据库操作Service实现
+* @createDate 2025-07-03 15:36:46
+*/
+//@Service
+//public class UserServiceImpl extends ServiceImpl<UserMapper, User>
+//    implements UserService {
+//
+//}
+
+
+
+

+ 45 - 0
Marketplace/src/main/java/com/dt/shequ/util/AppHttpCodeEnum.java

@@ -0,0 +1,45 @@
+package com.dt.shequ.util;
+
+public enum AppHttpCodeEnum {
+
+    // 成功段0
+    SUCCESS(200,"操作成功"),
+    // 登录段1~50
+    NEED_LOGIN(1,"需要登录后操作"),
+    LOGIN_PASSWORD_ERROR(2,"密码错误"),
+    // TOKEN50~100
+    TOKEN_INVALID(50,"无效的TOKEN"),
+    TOKEN_EXPIRE(51,"TOKEN已过期"),
+    TOKEN_REQUIRE(52,"TOKEN是必须的"),
+    // SIGN验签 100~120
+    SIGN_INVALID(100,"无效的SIGN"),
+    SIG_TIMEOUT(101,"SIGN已过期"),
+    // 参数错误 500~1000
+    PARAM_REQUIRE(500,"缺少参数"),
+    PARAM_INVALID(501,"无效参数"),
+    PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),
+    SERVER_ERROR(503,"服务器内部错误"),
+    // 数据错误 1000~2000
+    DATA_EXIST(1000,"数据已经存在"),
+    AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),
+    DATA_NOT_EXIST(1002,"数据不存在"),
+    // 数据错误 3000~3500
+    NO_OPERATOR_AUTH(3000,"无权限操作"),
+    NEED_ADMIND(3001,"需要管理员权限");
+
+    int code;
+    String errorMessage;
+
+    AppHttpCodeEnum(int code, String errorMessage){
+        this.code = code;
+        this.errorMessage = errorMessage;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+}

+ 34 - 0
Marketplace/src/main/java/com/dt/shequ/util/Constant.java

@@ -0,0 +1,34 @@
+package com.dt.shequ.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @ClassName: Constant
+ * @Author: 振涛教育_李小超
+ * @Date: 2024年2月26日 14:05
+ */
+public class Constant {
+
+
+
+    public static String TOKEN_NAME = "Authorization";
+
+    /**
+     * 请求响应码常量
+     */
+    public static final Integer RESPONSE_CODE_SUCCESS = 200;
+    public static final Integer RESPONSE_CODE_ERROR = 400;
+    public static final Integer RESPONSE_CODE_NO_LOGIN = 402;
+    public static final Integer RESPONSE_CODE_FORBIDDEN = 403;
+
+    public static final Map<Integer, String> RESPONSE_CODE_MAP = new HashMap<>();
+    static {
+        RESPONSE_CODE_MAP.put(RESPONSE_CODE_SUCCESS, "请求成功");
+        RESPONSE_CODE_MAP.put(RESPONSE_CODE_ERROR, "请求失败");
+        RESPONSE_CODE_MAP.put(RESPONSE_CODE_NO_LOGIN, "没有登录");
+        RESPONSE_CODE_MAP.put(RESPONSE_CODE_FORBIDDEN, "权限不足");
+    }
+    public static final String LOGIN_TOKEN_CACHE = "login:token:cache";
+
+}

+ 159 - 0
Marketplace/src/main/java/com/dt/shequ/util/ResponseResult.java

@@ -0,0 +1,159 @@
+package com.dt.shequ.util;
+
+
+
+import java.io.Serializable;
+
+/**
+ * 通用的结果返回类
+ * @param <T>
+ */
+public class ResponseResult<T> implements Serializable {
+
+    private String host;
+
+    private Integer code;
+
+    private String errorMessage;
+
+    private T data;
+
+    public ResponseResult() {
+        this.code = 200;
+    }
+
+    public ResponseResult(Integer code, T data) {
+        this.code = code;
+        this.data = data;
+    }
+
+    public ResponseResult(Integer code, String msg, T data) {
+        this.code = code;
+        this.errorMessage = msg;
+        this.data = data;
+    }
+
+    public ResponseResult(Integer code, String msg) {
+        this.code = code;
+        this.errorMessage = msg;
+    }
+
+    public static ResponseResult errorResult(int code, String msg) {
+        ResponseResult result = new ResponseResult();
+        return result.error(code, msg);
+    }
+
+    public static ResponseResult okResult(int code, String msg) {
+        ResponseResult result = new ResponseResult();
+        return result.ok(code, null, msg);
+    }
+
+    public static ResponseResult okResult(Object data) {
+        ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getErrorMessage());
+        if(data!=null) {
+            result.setData(data);
+        }
+        return result;
+    }
+
+    public static ResponseResult errorResult(AppHttpCodeEnum enums){
+        return setAppHttpCodeEnum(enums,enums.getErrorMessage());
+    }
+
+    public static ResponseResult errorResult(AppHttpCodeEnum enums, String errorMessage){
+        return setAppHttpCodeEnum(enums,errorMessage);
+    }
+
+    public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
+        return okResult(enums.getCode(),enums.getErrorMessage());
+    }
+
+    private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage){
+        return okResult(enums.getCode(),errorMessage);
+    }
+
+    public ResponseResult<?> error(Integer code, String msg) {
+        this.code = code;
+        this.errorMessage = msg;
+        return this;
+    }
+
+    public ResponseResult<?> ok(Integer code, T data) {
+        this.code = code;
+        this.data = data;
+        return this;
+    }
+
+    public ResponseResult<?> ok(Integer code, T data, String msg) {
+        this.code = code;
+        this.data = data;
+        this.errorMessage = msg;
+        return this;
+    }
+
+    public ResponseResult<?> ok(T data) {
+        this.data = data;
+        return this;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+
+    public static void main(String[] args) {
+        //前置
+        /*AppHttpCodeEnum success = AppHttpCodeEnum.SUCCESS;
+        System.out.println(success.getCode());
+        System.out.println(success.getErrorMessage());*/
+
+        //查询一个对象
+        /*Map map = new HashMap();
+        map.put("name","zhangsan");
+        map.put("age",18);
+        ResponseResult result = ResponseResult.okResult(map);
+        System.out.println(JSON.toJSONString(result));*/
+
+
+        //新增,修改,删除  在项目中统一返回成功即可
+       /* ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.SUCCESS);
+        System.out.println(JSON.toJSONString(result));*/
+
+
+        //根据不用的业务返回不同的提示信息  比如:当前操作需要登录、参数错误
+        /*ResponseResult result = ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
+        System.out.println(JSON.toJSONString(result));*/
+
+
+
+    }
+
+}

+ 54 - 0
Marketplace/src/main/java/com/dt/shequ/util/Result.java

@@ -0,0 +1,54 @@
+package com.dt.shequ.util;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @ClassName: Result 返回结果
+ *  code 响应码 代表请求成功/失败
+ *  message 响应信息
+ *  data 响应数据
+ * @Author: 振涛教育_李小超
+ * @Date: 2024年2月26日 13:58
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class    Result {
+    private Integer code;//状态码
+    private String message;//提示信息
+    private Object data;//数据
+
+    //成功响应
+    public static Result OK() {
+        return new Result(Constant.RESPONSE_CODE_SUCCESS, "操作成功", null);
+    }
+
+    public static Result OK(Object data) {
+        return new Result(Constant.RESPONSE_CODE_SUCCESS, "操作成功", data);
+    }
+
+    //失败响应
+    public static Result ERROR() {
+        return new Result(Constant.RESPONSE_CODE_ERROR, "操作失败", null);
+    }
+
+    public static Result ERROR(Object data) {
+        return new Result(Constant.RESPONSE_CODE_ERROR, "操作失败", data);
+    }
+
+    public static Result ERROR(String message) {
+        return new Result(Constant.RESPONSE_CODE_ERROR, message, null);
+    }
+
+    //未登录响应
+    public static Result NO_LOGIN(){
+        return new Result(Constant.RESPONSE_CODE_NO_LOGIN, "未登录", null);
+    }
+
+    //权限不足响应
+    public static Result FORBIDDEN(){
+        return new Result(Constant.RESPONSE_CODE_FORBIDDEN, "权限不足,禁止访问", null);
+    }
+}

+ 28 - 0
Marketplace/src/main/java/com/dt/shequ/utils/MessageUtils.java

@@ -0,0 +1,28 @@
+package com.dt.shequ.utils;
+
+
+import com.alibaba.fastjson2.JSON;
+import com.dt.shequ.websocket.pojo.ResultMessage;
+
+public class MessageUtils {
+
+    /**
+     * @param isSystemMessage 是否是系统消息,只有广播消息才是系统消息,如果是私聊消息的话,就不是系统消息
+     * @param fromName        给谁发消息,如果是系统消息的话,这个参数不需要指定
+     * @param message         消息的具体内容
+     * @return String
+     */
+    public static String getMessage(boolean isSystemMessage, String fromName, Object message) {
+        ResultMessage resultMessage = new ResultMessage();
+
+        resultMessage.setSystem(isSystemMessage);
+        resultMessage.setMessage(message);
+        if (fromName != null) {
+            resultMessage.setFromName(fromName);
+        }
+
+        return JSON.toJSONString(resultMessage);
+    }
+
+}
+

+ 84 - 0
Marketplace/src/main/java/com/dt/shequ/utils/QiniuUtils.java

@@ -0,0 +1,84 @@
+package com.dt.shequ.utils;
+
+
+
+import com.google.gson.Gson;
+import com.qiniu.common.QiniuException;
+import com.qiniu.common.Zone;
+import com.qiniu.http.Response;
+import com.qiniu.storage.BucketManager;
+import com.qiniu.storage.Configuration;
+import com.qiniu.storage.UploadManager;
+import com.qiniu.storage.model.DefaultPutRet;
+import com.qiniu.util.Auth;
+
+
+public class QiniuUtils {
+    public  static String accessKey = "ZYfkPEufV_nkUhPmljeVNQWCJfMC9Ci4bkgdTjQS";
+    public  static String secretKey = "79EFQnYTRAWYda7WQbYT3ifecRziTHaNDuwQRyG0";
+    public  static String bucket = "yzzyrhl";
+
+    public static void upload2Qiniu(String filePath,String fileName){
+        //构造一个带指定Zone对象的配置类
+        Configuration cfg = new Configuration(Zone.zone1());
+        UploadManager uploadManager = new UploadManager(cfg);
+        Auth auth = Auth.create(accessKey, secretKey);
+        String upToken = auth.uploadToken(bucket);
+        try {
+            Response response = uploadManager.put(filePath, fileName, upToken);
+            //解析上传成功的结果
+            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
+        } catch (QiniuException ex) {
+            Response r = ex.response;
+            try {
+                System.err.println(r.bodyString());
+            } catch (QiniuException ex2) {
+                //ignore
+            }
+        }
+    }
+
+    //上传文件
+    public static void upload2Qiniu(byte[] bytes, String fileName){
+        //构造一个带指定Zone对象的配置类
+        Configuration cfg = new Configuration(Zone.zone1());
+        //...其他参数参考类注释
+        UploadManager uploadManager = new UploadManager(cfg);
+
+        //默认不指定key的情况下,以文件内容的hash值作为文件名
+        String key = fileName;
+        Auth auth = Auth.create(accessKey, secretKey);
+        String upToken = auth.uploadToken(bucket);
+        try {
+            Response response = uploadManager.put(bytes, key, upToken);
+            //解析上传成功的结果
+            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
+            System.out.println(putRet.key);
+            System.out.println(putRet.hash);
+        } catch (QiniuException ex) {
+            Response r = ex.response;
+            System.err.println(r.toString());
+            try {
+                System.err.println(r.bodyString());
+            } catch (QiniuException ex2) {
+                //ignore
+            }
+        }
+    }
+
+    //删除文件
+    public static void deleteFileFromQiniu(String fileName){
+        //构造一个带指定Zone对象的配置类
+        Configuration cfg = new Configuration(Zone.zone1());
+        String key = fileName;
+        Auth auth = Auth.create(accessKey, secretKey);
+        BucketManager bucketManager = new BucketManager(auth, cfg);
+        try {
+            bucketManager.delete(bucket, key);
+        } catch (QiniuException ex) {
+            //如果遇到异常,说明删除失败
+            System.err.println(ex.code());
+            System.err.println(ex.response.toString());
+        }
+    }
+}

+ 292 - 0
Marketplace/src/main/java/com/dt/shequ/utils/TextModerationPlusDemo.java

@@ -0,0 +1,292 @@
+package com.dt.shequ.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.green20220302.Client;
+import com.aliyun.green20220302.models.TextModerationPlusRequest;
+import com.aliyun.green20220302.models.TextModerationPlusResponse;
+import com.aliyun.green20220302.models.TextModerationPlusResponseBody;
+import com.aliyun.teaopenapi.models.Config;
+import com.dt.shequ.util.ResponseResult;
+
+public class TextModerationPlusDemo {
+
+    public static void main(String[] args) throws Exception {
+        Config config = new Config();
+        /**
+         * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
+         * 常见获取环境变量方式:
+         * 方式一:
+         *     获取RAM用户AccessKey ID:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         * 方式二:
+         *     获取RAM用户AccessKey ID:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         */
+        config.setAccessKeyId("LTAI5tLBS2qNcZonMq4hDM4k");
+        config.setAccessKeySecret("IThnoZYNEErVpLfi8UYKA1WQ2dvQsz");
+        //接入区域和地址请根据实际情况修改
+        config.setRegionId("cn-shanghai");
+        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
+        //读取时超时时间,单位毫秒(ms)。
+        config.setReadTimeout(6000);
+        //连接时超时时间,单位毫秒(ms)。
+        config.setConnectTimeout(3000);
+        //设置http代理。
+        //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
+        //设置https代理。
+        //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
+        Client client = new Client(config);
+
+        JSONObject serviceParameters = new JSONObject();
+        serviceParameters.put("content", "爆炸,抢劫,色情,正常内容");
+
+        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
+        // 检测类型
+        textModerationPlusRequest.setService("llm_query_moderation");
+        textModerationPlusRequest.setServiceParameters(serviceParameters.toJSONString());
+
+        try {
+            TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
+            if (response.getStatusCode() == 200) {
+                TextModerationPlusResponseBody result = response.getBody();
+                System.out.println(JSON.toJSONString(result));
+                System.out.println("requestId = " + result.getRequestId());
+                System.out.println("code = " + result.getCode());
+                System.out.println("msg = " + result.getMessage());
+                Integer code = result.getCode();
+                if (200 == code) {
+                    TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
+                    System.out.println(JSON.toJSONString(data, true));
+                } else {
+                    System.out.println("text moderation not success. code:" + code);
+                }
+            } else {
+                System.out.println("response not success. status:" + response.getStatusCode());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    public static ResponseResult textModerationPlus(String content) throws Exception {
+        Config config = new Config();
+        /**
+         * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
+         * 常见获取环境变量方式:
+         * 方式一:
+         *     获取RAM用户AccessKey ID:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         * 方式二:
+         *     获取RAM用户AccessKey ID:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         */
+        config.setAccessKeyId("LTAI5tLBS2qNcZonMq4hDM4k");
+        config.setAccessKeySecret("IThnoZYNEErVpLfi8UYKA1WQ2dvQsz");
+        //接入区域和地址请根据实际情况修改
+        config.setRegionId("cn-shanghai");
+        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
+        //读取时超时时间,单位毫秒(ms)。
+        config.setReadTimeout(6000);
+        //连接时超时时间,单位毫秒(ms)。
+        config.setConnectTimeout(3000);
+        //设置http代理。
+        //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
+        //设置https代理。
+        //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
+        Client client = new Client(config);
+
+        JSONObject serviceParameters = new JSONObject();
+        serviceParameters.put("content", content);
+
+        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
+        // 检测类型
+        textModerationPlusRequest.setService("llm_query_moderation");
+        textModerationPlusRequest.setServiceParameters(serviceParameters.toJSONString());
+
+        try {
+            TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
+            if (response.getStatusCode() == 200) {
+                TextModerationPlusResponseBody result = response.getBody();
+                System.out.println(JSON.toJSONString(result));
+                System.out.println("requestId = " + result.getRequestId());
+                System.out.println("code = " + result.getCode());
+                System.out.println("msg = " + result.getMessage());
+                Integer code = result.getCode();
+                if (200 == code) {
+                    TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
+                    System.out.println(JSON.toJSONString(data, true));
+
+                    String getJsonString = JSON.toJSONString(data, true);
+                    //转成json对象
+                    JSONObject jsonObject = JSONObject.parseObject(getJsonString);
+                    String riskLeavel = (String) jsonObject.get("riskLevel");
+                    if(riskLeavel.equals("high")){
+                        //拒绝
+                        return ResponseResult.okResult(201,"风险登录高");
+                    }else if(riskLeavel.equals("none")){
+                        //通过
+                        return ResponseResult.okResult(200,"审核通过");
+
+                    }else{
+                        //转人工
+                        return ResponseResult.okResult(202,"转人工");
+                    }
+
+                } else {
+                    System.out.println("text moderation not success. code:" + code);
+                    return ResponseResult.okResult(202,"转人工");
+                }
+            } else {
+                System.out.println("response not success. status:" + response.getStatusCode());
+                return ResponseResult.okResult(202,"转人工");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseResult.okResult(202,"转人工");
+        }
+
+
+    }
+
+}
+
+//public class TextModerationPlusDemo {
+//
+//    public static void main(String[] args) throws Exception {
+//        Config config = new Config();
+//        /**
+//         * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
+//         * 常见获取环境变量方式:
+//         * 方式一:
+//         *     获取RAM用户AccessKey ID:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
+//         *     获取RAM用户AccessKey Secret:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+//         * 方式二:
+//         *     获取RAM用户AccessKey ID:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
+//         *     获取RAM用户AccessKey Secret:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+//         */
+//        config.setAccessKeyId("LTAI5tLBS2qNcZonMq4hDM4k");
+//        config.setAccessKeySecret("IThnoZYNEErVpLfi8UYKA1WQ2dvQsz");
+//        //接入区域和地址请根据实际情况修改
+//        config.setRegionId("cn-shanghai");
+//        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
+//        //读取时超时时间,单位毫秒(ms)。
+//        config.setReadTimeout(6000);
+//        //连接时超时时间,单位毫秒(ms)。
+//        config.setConnectTimeout(3000);
+//        //设置http代理。
+//        //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
+//        //设置https代理。
+//        //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
+//        Client client = new Client(config);
+//
+//        JSONObject serviceParameters = new JSONObject();
+//        serviceParameters.put("content", "爆炸,抢劫,色情,正常内容");
+//
+//        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
+//        // 检测类型
+//        textModerationPlusRequest.setService("llm_query_moderation");
+//        textModerationPlusRequest.setServiceParameters(serviceParameters.toJSONString());
+//
+//        try {
+//            TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
+//            if (response.getStatusCode() == 200) {
+//                TextModerationPlusResponseBody result = response.getBody();
+//                System.out.println(JSON.toJSONString(result));
+//                System.out.println("requestId = " + result.getRequestId());
+//                System.out.println("code = " + result.getCode());
+//                System.out.println("msg = " + result.getMessage());
+//                Integer code = result.getCode();
+//                if (200 == code) {
+//                    TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
+//                    System.out.println(JSON.toJSONString(data, true));
+//                } else {
+//                    System.out.println("text moderation not success. code:" + code);
+//                }
+//            } else {
+//                System.out.println("response not success. status:" + response.getStatusCode());
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//    public static ResponseResult textModerationPlus(String content) throws Exception {
+//        Config config = new Config();
+//        /**
+//         * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
+//         * 常见获取环境变量方式:
+//         * 方式一:
+//         *     获取RAM用户AccessKey ID:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
+//         *     获取RAM用户AccessKey Secret:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+//         * 方式二:
+//         *     获取RAM用户AccessKey ID:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
+//         *     获取RAM用户AccessKey Secret:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+//         */
+//        config.setAccessKeyId("LTAI5tLBS2qNcZonMq4hDM4k");
+//        config.setAccessKeySecret("IThnoZYNEErVpLfi8UYKA1WQ2dvQsz");
+//        //接入区域和地址请根据实际情况修改
+//        config.setRegionId("cn-shanghai");
+//        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
+//        //读取时超时时间,单位毫秒(ms)。
+//        config.setReadTimeout(6000);
+//        //连接时超时时间,单位毫秒(ms)。
+//        config.setConnectTimeout(3000);
+//        //设置http代理。
+//        //config.setHttpProxy("http://xx.xx.xx.xx:xxxx");
+//        //设置https代理。
+//        //config.setHttpsProxy("https://xx.xx.xx.xx:xxxx");
+//        Client client = new Client(config);
+//
+//        JSONObject serviceParameters = new JSONObject();
+//        serviceParameters.put("content", content);
+//
+//        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
+//        // 检测类型
+//        textModerationPlusRequest.setService("llm_query_moderation");
+//        textModerationPlusRequest.setServiceParameters(serviceParameters.toJSONString());
+//
+//        try {
+//            TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
+//            if (response.getStatusCode() == 200) {
+//                TextModerationPlusResponseBody result = response.getBody();
+//                System.out.println(JSON.toJSONString(result));
+//                System.out.println("requestId = " + result.getRequestId());
+//                System.out.println("code = " + result.getCode());
+//                System.out.println("msg = " + result.getMessage());
+//                Integer code = result.getCode();
+//                if (200 == code) {
+//                    TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
+//                    System.out.println(JSON.toJSONString(data, true));
+//
+//                    String getJsonString = JSON.toJSONString(data, true);
+//                    //转成json对象
+//                    JSONObject jsonObject = JSONObject.parseObject(getJsonString);
+//                    String riskLeavel = (String) jsonObject.get("riskLevel");
+//                    if(riskLeavel.equals("high")){
+//                        //拒绝
+//                        return ResponseResult.okResult(201,"风险登录高");
+//                    }else if(riskLeavel.equals("none")){
+//                        //通过
+//                        return ResponseResult.okResult(200,"审核通过");
+//
+//                    }else{
+//                        //转人工
+//                        return ResponseResult.okResult(202,"转人工");
+//                    }
+//
+//                } else {
+//                    System.out.println("text moderation not success. code:" + code);
+//                    return ResponseResult.okResult(202,"转人工");
+//                }
+//            } else {
+//                System.out.println("response not success. status:" + response.getStatusCode());
+//                return ResponseResult.okResult(202,"转人工");
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            return ResponseResult.okResult(202,"转人工");
+//        }
+//
+//
+//    }
+//
+//}

+ 71 - 0
Marketplace/src/main/java/com/dt/shequ/vo/Result.java

@@ -0,0 +1,71 @@
+package com.dt.shequ.vo;
+
+import java.io.Serializable;
+
+/**
+ * 后端统一返回结果
+ *
+ * @param <T>
+ */
+public class Result<T> implements Serializable {
+
+    private Integer code;
+    private String message;
+    private T data;
+
+    public static <T> Result<T> success() {
+        Result<T> result = new Result<>();
+        result.code = 200;
+        result.message = "success";
+        return result;
+    }
+
+    public static <T> Result<T> success(T object) {
+        Result<T> result = new Result<>();
+        result.data = object;
+        result.code = 200;
+        result.message = "success";
+        return result;
+    }
+
+    public static <T> Result<T> fail(String message) {
+        Result<T> result = new Result<>();
+        result.message = message;
+        result.code = 500;
+        return result;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "Result{" +
+                "code=" + code +
+                ", message='" + message + '\'' +
+                ", data=" + data +
+                '}';
+    }
+
+}

+ 91 - 0
Marketplace/src/main/java/com/dt/shequ/websocket/pojo/ChatMessage.java

@@ -0,0 +1,91 @@
+package com.dt.shequ.websocket.pojo;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Date;
+
+/**
+ * 用于MongoDB存储的聊天消息实体类
+ */
+@Document(collection = "chat_messages")
+public class ChatMessage {
+    @Id
+    private String id;
+    private String fromName;    // 发送者用户名
+    private String toName;      // 接收者用户名
+    private String content;     // 消息内容
+    private Date sendTime;      // 发送时间
+    private boolean isRead;     // 是否已读
+
+    public ChatMessage() {
+    }
+
+    public ChatMessage(String fromName, String toName, String content) {
+        this.fromName = fromName;
+        this.toName = toName;
+        this.content = content;
+        this.sendTime = new Date();
+        this.isRead = false;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getFromName() {
+        return fromName;
+    }
+
+    public void setFromName(String fromName) {
+        this.fromName = fromName;
+    }
+
+    public String getToName() {
+        return toName;
+    }
+
+    public void setToName(String toName) {
+        this.toName = toName;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Date getSendTime() {
+        return sendTime;
+    }
+
+    public void setSendTime(Date sendTime) {
+        this.sendTime = sendTime;
+    }
+
+    public boolean isRead() {
+        return isRead;
+    }
+
+    public void setRead(boolean read) {
+        isRead = read;
+    }
+
+    @Override
+    public String toString() {
+        return "ChatMessage{" +
+                "id='" + id + '\'' +
+                ", fromName='" + fromName + '\'' +
+                ", toName='" + toName + '\'' +
+                ", content='" + content + '\'' +
+                ", sendTime=" + sendTime +
+                ", isRead=" + isRead +
+                '}';
+    }
+}

+ 54 - 0
Marketplace/src/main/java/com/dt/shequ/websocket/pojo/Message.java

@@ -0,0 +1,54 @@
+package com.dt.shequ.websocket.pojo;
+
+/**
+ * 用于封装浏览器发送给服务端的消息数据
+ */
+public class Message {
+    private String toName;
+    private String message;
+    private String type;
+    private String fromName;
+
+    public String getToName() {
+        return toName;
+    }
+
+    public void setToName(String toName) {
+        this.toName = toName;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getFromName() {
+        return fromName;
+    }
+
+    public void setFromName(String fromName) {
+        this.fromName = fromName;
+    }
+
+    @Override
+    public String toString() {
+        return "Message{" +
+                "toName='" + toName + '\'' +
+                ", message='" + message + '\'' +
+                ", type='" + type + '\'' +
+                ", fromName='" + fromName + '\'' +
+                '}';
+    }
+
+}

+ 57 - 0
Marketplace/src/main/java/com/dt/shequ/websocket/pojo/ResultMessage.java

@@ -0,0 +1,57 @@
+package com.dt.shequ.websocket.pojo;
+
+
+/**
+ * 用来封装服务端给浏览器发送的消息数据
+ */
+
+public class ResultMessage {
+
+    private boolean isSystem;
+    private String fromName;
+    private Object message;// 如果是系统消息是数组
+
+    public ResultMessage() {
+
+    }
+
+    public ResultMessage(boolean isSystem, String fromName, Object message) {
+        this.isSystem = isSystem;
+        this.fromName = fromName;
+        this.message = message;
+    }
+
+    public boolean isSystem() {
+        return isSystem;
+    }
+
+    public void setSystem(boolean system) {
+        isSystem = system;
+    }
+
+    public String getFromName() {
+        return fromName;
+    }
+
+    public void setFromName(String fromName) {
+        this.fromName = fromName;
+    }
+
+    public Object getMessage() {
+        return message;
+    }
+
+    public void setMessage(Object message) {
+        this.message = message;
+    }
+
+    @Override
+    public String toString() {
+        return "ResultMessage{" +
+                "isSystem=" + isSystem +
+                ", fromName='" + fromName + '\'' +
+                ", message=" + message +
+                '}';
+    }
+
+}

+ 20 - 2
Marketplace/src/main/java/com/dt/user/pojo/User.java

@@ -6,7 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.io.Serializable;
 import java.util.Date;
+
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 /**
  * 用户表
@@ -14,6 +17,8 @@ import lombok.Data;
  */
 @TableName(value ="user")
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class User implements Serializable {
     /**
      * 用户ID
@@ -105,7 +110,20 @@ public class User implements Serializable {
      * 是否删除(0-未删除,1-已删除)
      */
     private Integer deleted;
-
+    @TableField(exist = false)
+    private String bio;
+    @TableField(exist = false)
+    private String citys;
+    @TableField(exist = false)
+    private Integer guanzu;
+    @TableField(exist = false)
+    private Integer fensi;
+    @TableField(exist = false)
+    private Integer huozan;
+    @TableField(exist = false)
+    private Integer did;
+    @TableField(exist = false)
+    private String avatares;
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
-}
+}

+ 3 - 2
Marketplace/src/main/java/com/dt/user/service/impl/UserServiceImpl.java

@@ -50,7 +50,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
         // 1. 根据用户名查询用户
         User user = this.getOne(new LambdaQueryWrapper<User>()
                 .eq(User::getUsername, loginDTO.getUsername()));
-        
+
         if (user == null) {
             throw new ApiException(101, "用户名或密码错误");
         }
@@ -65,6 +65,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
             throw new ApiException(101, "账号已被禁用");
         }
 
+
         // 4. 更新登录信息
         user.setLastLoginTime(new Date());
         this.updateById(user);
@@ -211,7 +212,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
             UserLoginVO loginVO = new UserLoginVO();
             BeanUtils.copyProperties(matchedUser, loginVO);
             loginVO.setToken(token);
-            
+
             return new Result(true, "人脸识别登录成功", loginVO);
         } catch (Exception e) {
             e.printStackTrace();

+ 3 - 2
Marketplace/src/main/java/com/dt/user/vo/UserLoginVO.java

@@ -6,8 +6,9 @@ import lombok.experimental.Accessors;
 @Data
 @Accessors(chain = true)
 public class UserLoginVO {
-    
+
     private Long id;
     private String username;
     private String token;
-} 
+    private String did;
+}

+ 4 - 2
Marketplace/src/main/java/com/dt/util/FaceEngineUtil.java

@@ -23,7 +23,9 @@ public class FaceEngineUtil {
 
     private static final String APP_ID = "F6mCauSNk86Jn9U21eWbehPHcyVzpNPzrbabLjXwrQds";
     private static final String SDK_KEY = "CJgKkF5UDNzWoikdYqBQtFHtbCjeuFCvLJBDnYq7LkFv";
-    private static final String ENGINE_PATH = new File("libs/WIN64").getAbsolutePath();
+//    private static final String ENGINE_PATH = new File("libs/WIN64").getAbsolutePath();
+// Windows系统专用,双反斜杠避免路径解析错误
+private static final String ENGINE_PATH = "C:\\Users\\86155\\Desktop\\gitd\\Marketplace\\libs\\WIN64";
 
     public static float faceAnalysis(String imageUrl1, MultipartFile imageUrl2) {
         FaceEngine faceEngine = new FaceEngine(ENGINE_PATH);
@@ -162,4 +164,4 @@ public class FaceEngineUtil {
             return null;
         }
     }
-}
+}

+ 19 - 9
Marketplace/src/main/resources/application.yml

@@ -19,15 +19,23 @@ spring:
     host: 101.200.59.170
     port: 6379
     database: 0
-#    template:
-#      default-type: java.lang.String
-#      enable-transaction-support: true
-#      # 序列化器配置(新增)
-#      serializer:
-#        key: string
-#        value: json
-
-
+    template:
+      default-type: java.lang.String
+      enable-transaction-support: true
+      # 序列化器配置(新增)
+      serializer:
+        key: string
+        value: json
+  data:
+    mongodb:
+      host: 101.200.59.170
+      port: 27017
+      database: chat
+netty:
+  websocket:
+    port: 7025
+    path: /chat
+    enabled: true
 
 logging:
   level:
@@ -36,6 +44,8 @@ logging:
 
 
 
+
+
 #  kafka:
 #    producer:
 #      key-serializer: org.apache.kafka.common.serialization.StringSerializer

+ 20 - 0
Marketplace/src/main/resources/mapper/CommentLikeMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.CommentLikeMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.CommentLike">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="commentId" column="comment_id" jdbcType="BIGINT"/>
+            <result property="userId" column="user_id" jdbcType="BIGINT"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,comment_id,user_id,
+        status,created_at,updated_at
+    </sql>
+</mapper>

+ 26 - 0
Marketplace/src/main/resources/mapper/PostCommentMapper.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.PostCommentMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.PostComment">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="postId" column="post_id" jdbcType="BIGINT"/>
+            <result property="userId" column="user_id" jdbcType="BIGINT"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="parentId" column="parent_id" jdbcType="BIGINT"/>
+            <result property="replyToUserId" column="reply_to_user_id" jdbcType="BIGINT"/>
+            <result property="likeCount" column="like_count" jdbcType="INTEGER"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,post_id,user_id,
+        content,parent_id,reply_to_user_id,
+        like_count,status,created_at,
+        updated_at
+    </sql>
+</mapper>

+ 20 - 0
Marketplace/src/main/resources/mapper/PostLikeMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.PostLikeMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.PostLike">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="postId" column="post_id" jdbcType="BIGINT"/>
+            <result property="userId" column="user_id" jdbcType="BIGINT"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,post_id,user_id,
+        status,created_at,updated_at
+    </sql>
+</mapper>

+ 20 - 0
Marketplace/src/main/resources/mapper/PostMediaMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.PostMediaMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.PostMedia">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="postId" column="post_id" jdbcType="BIGINT"/>
+            <result property="mediaType" column="media_type" jdbcType="TINYINT"/>
+            <result property="mediaUrl" column="media_url" jdbcType="VARCHAR"/>
+            <result property="displayOrder" column="display_order" jdbcType="INTEGER"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,post_id,media_type,
+        media_url,display_order,created_at
+    </sql>
+</mapper>

+ 27 - 0
Marketplace/src/main/resources/mapper/PostsMapper.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.PostsMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.Posts">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="userId" column="user_id" jdbcType="INTEGER"/>
+            <result property="title" column="title" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+        <result property="category" column="category" jdbcType="VARCHAR"/>
+            <result property="topic" column="topic" jdbcType="VARCHAR"/>
+            <result property="viewCount" column="view_count" jdbcType="INTEGER"/>
+            <result property="likeCount" column="like_count" jdbcType="INTEGER"/>
+            <result property="commentCount" column="comment_count" jdbcType="INTEGER"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,user_id,title,category,
+        content,topic,view_count,
+        like_count,comment_count,created_at,
+        updated_at
+    </sql>
+</mapper>

+ 32 - 0
Marketplace/src/main/resources/mapper/TopicRepliesMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.TopicRepliesMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.TopicReplies">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="topicId" column="topic_id" jdbcType="INTEGER"/>
+            <result property="userId" column="user_id" jdbcType="INTEGER"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="isHot" column="is_hot" jdbcType="TINYINT"/>
+            <result property="likeCount" column="like_count" jdbcType="INTEGER"/>
+            <result property="commentCount" column="comment_count" jdbcType="INTEGER"/>
+            <result property="viewCount" column="view_count" jdbcType="INTEGER"/>
+            <result property="mediaList" column="media_list" jdbcType="VARCHAR"/>
+            <result property="mediaType" column="media_type" jdbcType="VARCHAR"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+            <result property="userType" column="user_type" jdbcType="TINYINT"/>
+            <result property="userTitle" column="user_title" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,topic_id,user_id,
+        content,is_hot,like_count,
+        comment_count,view_count,media_list,
+        media_type,created_at,updated_at,
+        user_type,user_title,status
+    </sql>
+</mapper>

+ 30 - 0
Marketplace/src/main/resources/mapper/TopicsMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.TopicsMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.Topics">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="title" column="title" jdbcType="VARCHAR"/>
+            <result property="description" column="description" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="category" column="category" jdbcType="VARCHAR"/>
+            <result property="isHot" column="is_hot" jdbcType="TINYINT"/>
+            <result property="isNew" column="is_new" jdbcType="TINYINT"/>
+            <result property="viewCount" column="view_count" jdbcType="INTEGER"/>
+            <result property="participantCount" column="participant_count" jdbcType="INTEGER"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+            <result property="creatorId" column="creator_id" jdbcType="INTEGER"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,title,description,
+        content,category,is_hot,
+        is_new,view_count,participant_count,
+        created_at,updated_at,creator_id,
+        status
+    </sql>
+</mapper>

+ 20 - 0
Marketplace/src/main/resources/mapper/UserFollowMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.UserFollowMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.UserFollow">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="followerId" column="follower_id" jdbcType="BIGINT"/>
+            <result property="followingId" column="following_id" jdbcType="BIGINT"/>
+            <result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
+            <result property="status" column="status" jdbcType="TINYINT"/>
+            <result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,follower_id,following_id,
+        created_at,status,updated_at
+    </sql>
+</mapper>

+ 26 - 0
Marketplace/src/main/resources/mapper/UserInfoMapper.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dt.shequ.mapper.UserInfoMapper">
+
+    <resultMap id="BaseResultMap" type="com.dt.shequ.domain.UserInfo">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="userId" column="user_id" jdbcType="INTEGER"/>
+            <result property="bio" column="bio" jdbcType="VARCHAR"/>
+            <result property="citys" column="citys" jdbcType="VARCHAR"/>
+            <result property="guanzu" column="guanzu" jdbcType="INTEGER"/>
+            <result property="fensi" column="fensi" jdbcType="INTEGER"/>
+            <result property="avatares" column="avatares" jdbcType="VARCHAR"/>
+            <result property="huozan" column="huozan" jdbcType="INTEGER"/>
+            <result property="did" column="did" jdbcType="VARCHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,user_id,bio,
+        citys,guanzu,fensi,
+        avatares,huozan,did,
+        create_time
+    </sql>
+</mapper>