diff --git a/.idea/mybatisx/templates.xml b/.idea/mybatisx/templates.xml
index 47f2860..f2e668e 100644
--- a/.idea/mybatisx/templates.xml
+++ b/.idea/mybatisx/templates.xml
@@ -39,6 +39,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -47,8 +67,8 @@
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/config/MpConfig.java b/community-8073/src/main/java/com/ivmiku/tutorial/config/MpConfig.java
new file mode 100644
index 0000000..3d4bdfc
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/config/MpConfig.java
@@ -0,0 +1,15 @@
+package com.ivmiku.tutorial.config;
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+@Configuration
+public class MpConfig {
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ return interceptor;
+ }
+}
\ No newline at end of file
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java
index 561c3ac..fbf5ab1 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java
@@ -2,6 +2,7 @@ package com.ivmiku.tutorial.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import com.ivmiku.tutorial.entity.Comment;
import com.ivmiku.tutorial.entity.Pages;
@@ -209,8 +210,7 @@ public class CommentController {
public Result getPostComments(@PathVariable("postId") Long postId, @RequestBody Pages pages) {
logger.info("获取帖子ID:{}的评论列表", postId);
logger.info("获取pageSize:{}", pages.getPageSize());
- System.out.println("aaaaaa" + pages.getPageSize());
- PageInfo comments = commentService.getPostComments(postId, pages.getPageNum(), pages.getPageSize());
+ IPage comments = commentService.getPostComments(postId, pages.getPageNum(), pages.getPageSize());
return Result.ok(comments);
}
@@ -224,7 +224,7 @@ public class CommentController {
@Operation(summary = "获取评论下的所有回复")
public Result getCommentReplies(@PathVariable Long commentId, @RequestBody Pages pages) {
logger.info("获取评论ID:{}的回复列表", commentId);
- PageInfo replies = commentService.getCommentReplies(commentId, pages.getPageNum(), pages.getPageSize());
+ IPage replies = commentService.getCommentReplies(commentId, pages.getPageNum(), pages.getPageSize());
return Result.ok(replies);
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunityController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunityController.java
index 8ec25a2..90142a7 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunityController.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunityController.java
@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import com.ivmiku.tutorial.entity.Community;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.CommunityService;
+import com.ivmiku.tutorial.service.CommunitytagService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.models.annotations.OpenAPI30;
import org.apiguardian.api.API;
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunitytagController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunitytagController.java
new file mode 100644
index 0000000..ca1644b
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommunitytagController.java
@@ -0,0 +1,47 @@
+package com.ivmiku.tutorial.controller;
+
+import com.ivmiku.tutorial.entity.Communitytag;
+import com.ivmiku.tutorial.response.Result;
+import com.ivmiku.tutorial.service.CommunitytagService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@RestController
+@RequestMapping("/communityTags")
+public class CommunitytagController {
+
+ @Resource
+ private CommunitytagService communitytagService;
+
+ @PostMapping("/create")
+ public Result createCommunityTag(@RequestBody Communitytag communityTag) {
+ communitytagService.createCommunityTag(communityTag);
+ return Result.ok();
+ }
+
+ @PutMapping("/update/{id}")
+ public Result updateCommunityTag(@PathVariable Long id, @RequestBody Communitytag communityTag) {
+ communitytagService.updateCommunityTag(id, communityTag);
+ return Result.ok();
+ }
+
+ @DeleteMapping("/delete/{id}")
+ public Result deleteCommunityTag(@PathVariable Long id) {
+ communitytagService.deleteCommunityTag(id);
+ return Result.ok();
+ }
+
+ @GetMapping("/get/{id}")
+ public Result getCommunityTag(@PathVariable Long id) {
+ Communitytag communityTag = communitytagService.getCommunityTagById(id);
+ return Result.ok(communityTag);
+ }
+
+ @GetMapping("/list/{communityId}")
+ public Result getCommunityTagListByCommunityId(@PathVariable Long communityId) {
+ List tags = communitytagService.getCommunityTagListByCommunityId(communityId);
+ return Result.ok(tags);
+ }
+}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/InteractionController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/InteractionController.java
index d2a33f6..7e18427 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/controller/InteractionController.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/InteractionController.java
@@ -2,12 +2,17 @@ package com.ivmiku.tutorial.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.lang.hash.Hash;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ivmiku.tutorial.entity.Post;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.InteractionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
/**
* InteractionController 是处理用户与帖子的收藏、点赞以及对评论的点赞功能的控制器类。
@@ -104,4 +109,35 @@ public class InteractionController {
interactionService.unlikeComment(userOpenid, commentId);
return Result.ok();
}
+
+
+ /**
+ * 我的收藏接口
+ * @return
+ */
+ @GetMapping("/getFavoritePosts")
+ public Result getFavoritePosts() {
+ String userOpenid = StpUtil.getLoginIdAsString();
+ log.info("用户 {} 正在获取收藏的帖子", userOpenid);
+ IPage favoritePost = interactionService.getFavoritePosts(userOpenid);
+ HashMap data = new HashMap<>();
+ if (favoritePost != null) {
+ log.info("用户 {} 收藏的帖子获取成功", userOpenid);
+ data.put("total", favoritePost.getTotal());
+ data.put("list", favoritePost.getRecords());
+ return Result.ok(data);
+ }
+ return Result.ok("用户未发表帖子");
+ }
+
+ /**
+ * 统计我的获赞数量 笔记数量 收藏数量
+ */
+ @GetMapping("/getLikeCount")
+ public Result getLikeCount() {
+ String userOpenid = StpUtil.getLoginIdAsString();
+ log.info("用户 {} 正在获取用户获赞的数量", userOpenid);
+ HashMap res = interactionService.getLikeCount(userOpenid);
+ return Result.ok();
+ }
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/PostController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/PostController.java
index 6e0fb22..52a4d70 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/controller/PostController.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/PostController.java
@@ -2,6 +2,7 @@ package com.ivmiku.tutorial.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import com.ivmiku.tutorial.entity.Pages;
import com.ivmiku.tutorial.entity.Post;
@@ -15,7 +16,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.sql.Timestamp;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* 帖子控制器,用于处理帖子相关的HTTP请求。
@@ -81,7 +84,8 @@ public class PostController {
@GetMapping("/get/{id}")
public Result getPost(@PathVariable Long id) {
logger.info("开始获取帖子ID:{}的详细信息", id);
- Post post = postService.getPostById(id); // 调用服务层根据ID查询帖子
+ String userId = StpUtil.getLoginIdAsString();
+ Post post = postService.getPostById(id, userId); // 调用服务层根据ID查询帖子
if (post != null) {
logger.info("帖子ID:{}的详细信息获取成功", id);
} else {
@@ -110,24 +114,27 @@ public class PostController {
/**
* 用户获取自己所有帖子的信息
- * @return 当前用户帖子列表
+ * @return 当前用户帖子列表与该用户的总发布数量
*/
@GetMapping("/getPostList")
public Result getPostList(@RequestBody Pages pages) {
logger.info("开始获取帖子列表");
String userId = StpUtil.getLoginIdAsString(); // 获取当前登录用户的ID
- PageInfo posts = postService.getPostList(userId, pages.getPageNum(), pages.getPageSize());
- return Result.ok(posts); // 调用服务层获取帖子列表
+ IPage posts = postService.getPostList(userId, pages.getPageNum(), pages.getPageSize());
+ Map data = new HashMap<>();
+ data.put("total", posts.getTotal());
+ data.put("posts", posts);
+ return Result.ok(data); // 调用服务层获取帖子列表
}
/**
* 社区获取自己所有帖子的信息
* @return 当前用户帖子列表
*/
- @GetMapping("/getCommunityPostList{communityId}")
+ @GetMapping("/getCommunityPostList/{communityId}")
public Result getCommunityPostList(@PathVariable("communityId") Long communityId, @RequestBody Pages pages) {
logger.info("开始获取帖子列表");
- PageInfo posts = postService.getCommunityPostList(communityId, pages.getPageNum(), pages.getPageSize());
+ IPage posts = postService.getCommunityPostList(communityId, pages.getPageNum(), pages.getPageSize());
return Result.ok(posts); // 调用服务层获取帖子列表
}
@@ -136,7 +143,7 @@ public class PostController {
* @return
*/
@GetMapping("/official")
- public PageInfo getOfficialPosts(@RequestBody Pages pages) {
+ public IPage getOfficialPosts(@RequestBody Pages pages) {
return postService.getOfficialPosts(pages.getPageNum(), pages.getPageSize());
}
@@ -145,7 +152,7 @@ public class PostController {
* @return
*/
@GetMapping("/nonOfficial")
- public PageInfo getNonOfficialPosts(@RequestBody Pages pages) {
+ public IPage getNonOfficialPosts(@RequestBody Pages pages) {
return postService.getNonOfficialPosts(pages.getPageNum(), pages.getPageSize());
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/entity/BrowingHistory.java b/community-8073/src/main/java/com/ivmiku/tutorial/entity/BrowingHistory.java
new file mode 100644
index 0000000..fc963e3
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/entity/BrowingHistory.java
@@ -0,0 +1,30 @@
+package com.ivmiku.tutorial.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @TableName browing_history
+ */
+@TableName(value ="browing_history")
+@Data
+public class BrowingHistory implements Serializable {
+ @TableId(type = IdType.AUTO)
+ private Long browingId;
+
+ private String userOpenid;
+
+
+ private Long postId;
+
+
+ private Date createAt;
+
+ @TableLogic
+ private Integer isDelete;
+
+ private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/entity/Communitytag.java b/community-8073/src/main/java/com/ivmiku/tutorial/entity/Communitytag.java
new file mode 100644
index 0000000..9d0d8f8
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/entity/Communitytag.java
@@ -0,0 +1,27 @@
+package com.ivmiku.tutorial.entity;
+
+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 java.io.Serializable;
+import lombok.Data;
+
+/**
+ * @TableName communitytag
+ */
+@TableName(value ="communitytag")
+@Data
+public class Communitytag implements Serializable {
+
+ @TableId
+ private Long smallCTagId;
+
+ private String cTagName;
+
+ private Long cId;
+
+ private Integer isDelete;
+
+ private static final long serialVersionUID = 1L;
+}
\ No newline at end of file
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/BrowingHistoryMapper.java b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/BrowingHistoryMapper.java
new file mode 100644
index 0000000..09e62fa
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/BrowingHistoryMapper.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.ivmiku.tutorial.entity.BrowingHistory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author rog
+* @description 针对表【browing_history】的数据库操作Mapper
+* @createDate 2024-08-23 11:29:33
+* @Entity com.ivmiku.tutorial.entity.BrowingHistory
+*/
+public interface BrowingHistoryMapper extends BaseMapper {
+
+}
+
+
+
+
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/CommunitytagMapper.java b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/CommunitytagMapper.java
new file mode 100644
index 0000000..641085c
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/CommunitytagMapper.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.ivmiku.tutorial.entity.Communitytag;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author rog
+* @description 针对表【communitytag】的数据库操作Mapper
+* @createDate 2024-08-16 09:40:06
+* @Entity com.ivmiku.tutorial.entity.Communitytag
+*/
+public interface CommunitytagMapper extends BaseMapper {
+
+}
+
+
+
+
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/LikeMapper.java b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/LikeMapper.java
index b951e47..77b9297 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/LikeMapper.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/LikeMapper.java
@@ -2,6 +2,8 @@ package com.ivmiku.tutorial.mapper;
import com.ivmiku.tutorial.entity.Likee;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
/**
* @author rog
@@ -11,6 +13,14 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface LikeMapper extends BaseMapper {
+ // 获取帖子获赞数
+ @Select("SELECT SUM(like_count) FROM posts WHERE user_openid = #{userOpenid}")
+ Long getPostLikeCount(@Param("userOpenid") String userOpenid);
+
+ // 获取评论获赞数
+ @Select("SELECT SUM(like_count) FROM comments WHERE user_openid = #{userOpenid}")
+ Long getCommentLikeCount(@Param("userOpenid") String userOpenid);
+
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/BrowingHistoryService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/BrowingHistoryService.java
new file mode 100644
index 0000000..2ba13dd
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/BrowingHistoryService.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.service;
+
+import com.ivmiku.tutorial.entity.BrowingHistory;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+* @author rog
+* @description 针对表【browing_history】的数据库操作Service
+* @createDate 2024-08-23 11:29:33
+*/
+public interface BrowingHistoryService extends IService {
+
+ void deleteBrowingRecordById(Long browingId);
+
+ void deleteBrowingRecordsByIds(List browingIds);
+}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/CommentService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/CommentService.java
index acb020c..5d17878 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/CommentService.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/CommentService.java
@@ -1,5 +1,6 @@
package com.ivmiku.tutorial.service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import com.ivmiku.tutorial.entity.Comment;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -50,9 +51,9 @@ public interface CommentService extends IService {
void deleteComment(Long commentId, String userId);
- PageInfo getPostComments(Long postId, int pageNum, int pageSize);
+ IPage getPostComments(Long postId, int pageNum, int pageSize);
- PageInfo getCommentReplies(Long commentId, int pageNum, int pageSize);
+ IPage getCommentReplies(Long commentId, int pageNum, int pageSize);
/**
* 回复评论。
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/CommunitytagService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/CommunitytagService.java
new file mode 100644
index 0000000..4561c71
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/CommunitytagService.java
@@ -0,0 +1,24 @@
+package com.ivmiku.tutorial.service;
+
+import com.ivmiku.tutorial.entity.Communitytag;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+* @author rog
+* @description 针对表【communitytag】的数据库操作Service
+* @createDate 2024-08-16 09:40:06
+*/
+public interface CommunitytagService extends IService {
+
+ void createCommunityTag(Communitytag communityTag);
+
+ void updateCommunityTag(Long id, Communitytag communityTag);
+
+ void deleteCommunityTag(Long id);
+
+ Communitytag getCommunityTagById(Long id);
+
+ List getCommunityTagListByCommunityId(Long communityId);
+}
\ No newline at end of file
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/InteractionService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/InteractionService.java
index 981a552..bf8c9f0 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/InteractionService.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/InteractionService.java
@@ -1,5 +1,11 @@
package com.ivmiku.tutorial.service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ivmiku.tutorial.entity.Post;
+
+import java.util.HashMap;
+import java.util.List;
+
/**
* InteractionService接口定义用户对帖子和评论的收藏与点赞操作。
*/
@@ -10,4 +16,8 @@ public interface InteractionService {
void unlikePost(String userOpenid, Long postId);
void likeComment(String userOpenid, Long commentId);
void unlikeComment(String userOpenid, Long commentId);
+
+ IPage getFavoritePosts(String userOpenid);
+
+ HashMap getLikeCount(String userOpenid);
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/PostService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/PostService.java
index 0a37130..05a2a2d 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/PostService.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/PostService.java
@@ -1,5 +1,6 @@
package com.ivmiku.tutorial.service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import com.ivmiku.tutorial.entity.Post;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -8,17 +9,18 @@ import java.util.List;
public interface PostService extends IService {
void createPost(Post post);
- Post getPostById(Long postId);
+ Post getPostById(Long postId, String userOpenid);
+
void updatePost(Long postId, String userId, Post post);
void deletePost(Long postId, String userId);
- PageInfo getPostList(String userId, int pageNum, int pageSize);
+ IPage getPostList(String userId, int pageNum, int pageSize);
- PageInfo getCommunityPostList(Long communityId, int pageNum, int pageSize);
+ IPage getCommunityPostList(Long communityId, int pageNum, int pageSize);
- PageInfo getOfficialPosts(int pageNum, int pageSize);
+ IPage getOfficialPosts(int pageNum, int pageSize);
- PageInfo getNonOfficialPosts(int pageNum, int pageSize);
+ IPage getNonOfficialPosts(int pageNum, int pageSize);
void changePublic(Long postId, Integer isPublic);
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/BrowingHistoryServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/BrowingHistoryServiceImpl.java
new file mode 100644
index 0000000..4c6e129
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/BrowingHistoryServiceImpl.java
@@ -0,0 +1,60 @@
+package com.ivmiku.tutorial.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ivmiku.tutorial.entity.BrowingHistory;
+import com.ivmiku.tutorial.service.BrowingHistoryService;
+import com.ivmiku.tutorial.mapper.BrowingHistoryMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+* @author rog
+* @description 针对表【browing_history】的数据库操作Service实现
+* @createDate 2024-08-23 11:29:33
+*/
+@Service
+@Slf4j
+public class BrowingHistoryServiceImpl extends ServiceImpl
+ implements BrowingHistoryService{
+
+ private static final Logger logger = LoggerFactory.getLogger(BrowingHistoryServiceImpl.class);
+ @Override
+ public void deleteBrowingRecordById(Long browingId) {
+ logger.info("开始删除浏览记录,浏览记录ID:{}", browingId);
+ BrowingHistory browingHistory = getById(browingId);
+ if (browingHistory != null) {
+ browingHistory.setIsDelete(1); // 标记为已删除
+ updateById(browingHistory);
+ logger.info("浏览记录ID:{} 删除成功", browingId);
+ } else {
+ logger.warn("浏览记录ID:{} 不存在", browingId);
+ }
+ }
+
+ @Override
+ public void deleteBrowingRecordsByIds(List browingIds) {
+ logger.info("开始批量删除浏览记录,浏览记录ID列表:{}", browingIds);
+ if (browingIds != null && !browingIds.isEmpty()) {
+ List browingHistories = listByIds(browingIds);
+ if (!browingHistories.isEmpty()) {
+ for (BrowingHistory browingHistory : browingHistories) {
+ browingHistory.setIsDelete(1); // 标记为已删除
+ }
+ updateBatchById(browingHistories); // 批量更新删除状态
+ logger.info("批量删除浏览记录成功");
+ } else {
+ logger.warn("提供的浏览记录ID列表中没有找到匹配的记录");
+ }
+ } else {
+ logger.warn("浏览记录ID列表为空,无法删除");
+ }
+ }
+}
+
+
+
+
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java
index 72587b2..67acb96 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java
@@ -2,6 +2,8 @@ package com.ivmiku.tutorial.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ivmiku.tutorial.entity.Comment;
@@ -103,16 +105,17 @@ public class CommentServiceImpl extends ServiceImpl impl
* @return List 返回评论列表
*/
@Override
- public PageInfo getPostComments(Long postId, int pageNum, int pageSize) {
+ public IPage getPostComments(Long postId, int pageNum, int pageSize) {
logger.info("开始获取帖子ID:{}的评论列表,第{}页,每页{}条", postId, pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
// 查询评论
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getPostId, postId).eq(Comment::getIsDeleted, 0);
- List comments = commentMapper.selectList(wrapper);
+ IPage comments = commentMapper.selectPage(page, wrapper);
if (comments != null) {
logger.info("获取帖子ID:{}的评论列表成功", postId);
@@ -121,7 +124,7 @@ public class CommentServiceImpl extends ServiceImpl impl
}
// 使用 PageInfo 包装结果
- return new PageInfo<>(comments);
+ return comments;
}
@@ -132,16 +135,16 @@ public class CommentServiceImpl extends ServiceImpl impl
* @return List 返回回复列表
*/
@Override
- public PageInfo getCommentReplies(Long commentId, int pageNum, int pageSize) {
+ public IPage getCommentReplies(Long commentId, int pageNum, int pageSize) {
logger.info("开始获取评论ID:{}的回复列表,第{}页,每页{}条", commentId, pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
-
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
// 查询回复
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getParentCommentId, commentId).eq(Comment::getIsDeleted, 0);
- List replies = commentMapper.selectList(wrapper);
+ IPage replies = commentMapper.selectPage(page, wrapper);
if (replies != null) {
logger.info("获取评论ID:{}的回复列表成功", commentId);
@@ -150,7 +153,7 @@ public class CommentServiceImpl extends ServiceImpl impl
}
// 使用 PageInfo 包装结果
- return new PageInfo<>(replies);
+ return replies;
}
/**
* 回复评论。
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommunitytagServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommunitytagServiceImpl.java
new file mode 100644
index 0000000..2396be0
--- /dev/null
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommunitytagServiceImpl.java
@@ -0,0 +1,50 @@
+package com.ivmiku.tutorial.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ivmiku.tutorial.entity.Communitytag;
+import com.ivmiku.tutorial.service.CommunitytagService;
+import com.ivmiku.tutorial.mapper.CommunitytagMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+* @author rog
+* @description 针对表【communitytag】的数据库操作Service实现
+* @createDate 2024-08-16 09:40:06
+*/
+@Service
+public class CommunitytagServiceImpl extends ServiceImpl
+ implements CommunitytagService{
+
+ @Override
+ public void createCommunityTag(Communitytag communityTag) {
+ this.save(communityTag);
+ }
+
+ @Override
+ public void updateCommunityTag(Long id, Communitytag communityTag) {
+ communityTag.setSmallCTagId(id);
+ this.updateById(communityTag);
+ }
+
+ @Override
+ public void deleteCommunityTag(Long id) {
+ this.removeById(id);
+ }
+
+ @Override
+ public Communitytag getCommunityTagById(Long id) {
+ return this.getById(id);
+ }
+
+ @Override
+ public List getCommunityTagListByCommunityId(Long communityId) {
+ return this.lambdaQuery().eq(Communitytag::getCId, communityId).list();
+ }
+
+}
+
+
+
+
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/InteractionServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/InteractionServiceImpl.java
index 4ff63bf..1a4f10c 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/InteractionServiceImpl.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/InteractionServiceImpl.java
@@ -1,15 +1,22 @@
package com.ivmiku.tutorial.service.impl;
+import cn.hutool.core.lang.hash.Hash;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ivmiku.tutorial.entity.Favorite;
import com.ivmiku.tutorial.entity.Likee;
+import com.ivmiku.tutorial.entity.Post;
import com.ivmiku.tutorial.mapper.FavoriteMapper;
import com.ivmiku.tutorial.mapper.LikeMapper;
import com.ivmiku.tutorial.service.InteractionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ivmiku.tutorial.service.PostService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
/**
* InteractionServiceImpl 实现了 InteractionService 接口,处理用户对帖子和评论的收藏与点赞操作。
@@ -24,6 +31,9 @@ public class InteractionServiceImpl implements InteractionService {
@Resource
private LikeMapper likeMapper;
+ @Resource
+ private PostService postService;
+
@Override
public void favoritePost(String userOpenid, Long postId) {
log.info("User {} is favoriting post {}", userOpenid, postId);
@@ -95,4 +105,60 @@ public class InteractionServiceImpl implements InteractionService {
likeMapper.updateById(likee);
}
}
+
+ @Override
+ public IPage getFavoritePosts(String userOpenid) {
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(Favorite::getUserOpenid, userOpenid);
+ List favorites = favoriteMapper.selectList(wrapper);
+ if (favorites != null && !favorites.isEmpty()) {
+ List postIds = favorites.stream().map(Favorite::getPostId).toList();
+ return postService.getPostList(userOpenid, 1, 10);
+ }
+ return null;
+ }
+
+ @Override
+ public HashMap getLikeCount(String userOpenid) {
+ HashMap res = new HashMap<>();
+
+ // 获取帖子获赞数
+ Long postLikeCount = likeMapper.getPostLikeCount(userOpenid);
+ // 获取评论获赞数
+ Long commentLikeCount = likeMapper.getCommentLikeCount(userOpenid);
+
+ // 如果帖子获赞数不为空,加入结果
+ if (postLikeCount != null) {
+ res.put("postLikeCount", postLikeCount);
+ } else {
+ res.put("postLikeCount", 0L); // 如果为空,设置为0
+ }
+
+ // 如果评论获赞数不为空,加入结果
+ if (commentLikeCount != null) {
+ res.put("commentLikeCount", commentLikeCount);
+ } else {
+ res.put("commentLikeCount", 0L); // 如果为空,设置为0
+ }
+
+ // 计算总的获赞数
+ Long totalLikeCount = (postLikeCount == null ? 0 : postLikeCount) +
+ (commentLikeCount == null ? 0 : commentLikeCount);
+
+ res.put("totalLikeCount", totalLikeCount);
+
+ // 获取收藏数量
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(Favorite::getUserOpenid, userOpenid);
+ Long favoriteCount = favoriteMapper.selectCount(wrapper);
+
+ if (favoriteCount != null) {
+ res.put("favoriteCount", favoriteCount);
+ } else {
+ res.put("favoriteCount", 0L); // 如果为空,设置为0
+ }
+ Long myTotalPost = getFavoritePosts(userOpenid).getTotal();
+ res.put("myTotalPost", myTotalPost);
+ return res;
+ }
}
diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/PostServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/PostServiceImpl.java
index 69dc5c4..98d7adc 100644
--- a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/PostServiceImpl.java
+++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/PostServiceImpl.java
@@ -1,19 +1,20 @@
package com.ivmiku.tutorial.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ivmiku.tutorial.entity.BrowingHistory;
import com.ivmiku.tutorial.entity.Post;
import com.ivmiku.tutorial.mapper.PostMapper;
+import com.ivmiku.tutorial.service.BrowingHistoryService;
import com.ivmiku.tutorial.service.PostService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-
import java.sql.Timestamp;
-import java.util.List;
+import java.util.Date;
@Service
public class PostServiceImpl extends ServiceImpl implements PostService {
@@ -23,6 +24,9 @@ public class PostServiceImpl extends ServiceImpl implements Po
@Autowired
private PostMapper postMapper;
+ @Autowired
+ private BrowingHistoryService browingHistoryService;
+
@Override
public void createPost(Post post) {
logger.info("开始创建帖子");
@@ -34,15 +38,24 @@ public class PostServiceImpl extends ServiceImpl implements Po
}
@Override
- public Post getPostById(Long postId) {
- logger.info("开始根据ID获取帖子详情,帖子ID:{}", postId);
- LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(Post::getIsPublic, 1);
- Post post = postMapper.selectById(wrapper);
- if (post == null) {
- logger.warn("帖子ID:{}不存在", postId);
+ public Post getPostById(Long postId, String userOpenid) {
+ logger.info("用户openid:{} 开始根据ID获取帖子详情,帖子ID:{}", userOpenid, postId);
+
+ // 查找帖子信息
+ Post post = postMapper.selectById(postId);
+ if (post == null || post.getIsDeleted() == 1) {
+ logger.warn("帖子ID:{}不存在或已删除", postId);
return null;
}
+
+ // 创建浏览记录
+ BrowingHistory browingHistory = new BrowingHistory();
+ browingHistory.setUserOpenid(userOpenid);
+ browingHistory.setPostId(postId);
+ browingHistory.setCreateAt(new Date());
+ browingHistory.setIsDelete(0); // 未删除标记
+ browingHistoryService.save(browingHistory);
+ logger.info("用户openid:{}的浏览记录创建成功", userOpenid);
return post;
}
@@ -70,83 +83,83 @@ public class PostServiceImpl extends ServiceImpl implements Po
}
@Override
- public PageInfo getPostList(String userId, int pageNum, int pageSize) {
+ public IPage getPostList(String userId, int pageNum, int pageSize) {
logger.info("用户ID:{}开始获取帖子列表,第{}页,每页{}条", userId, pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
-
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Post::getUserOpenid, userId);
wrapper.eq(Post::getIsDeleted, 0);
wrapper.eq(Post::getIsPublic, 1);
- List posts = postMapper.selectList(wrapper);
+ IPage posts = postMapper.selectPage(page, wrapper);
// 使用PageInfo封装分页结果
- PageInfo pageInfo = new PageInfo<>(posts);
+// PageInfo pageInfo = new PageInfo<>(posts);
- return pageInfo;
+ return posts;
}
@Override
- public PageInfo getCommunityPostList(Long communityId, int pageNum, int pageSize) {
+ public IPage getCommunityPostList(Long communityId, int pageNum, int pageSize) {
logger.info("开始获取社区ID:{}的帖子列表,第{}页,每页{}条", communityId, pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
-
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Post::getCommunityId, communityId);
wrapper.eq(Post::getIsDeleted, 0);
wrapper.eq(Post::getIsPublic, 1);
- List posts = postMapper.selectList(wrapper);
+ IPage posts = postMapper.selectPage(page, wrapper);
// 使用PageInfo封装分页结果
- PageInfo pageInfo = new PageInfo<>(posts);
+// PageInfo pageInfo = new PageInfo<>(posts);
- return pageInfo;
+ return posts;
}
@Override
- public PageInfo getOfficialPosts(int pageNum, int pageSize) {
+ public IPage getOfficialPosts(int pageNum, int pageSize) {
logger.info("开始获取所有官方创建的帖子,第{}页,每页{}条", pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
-
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Post::getIsOfficial, 1);
wrapper.eq(Post::getIsDeleted, 0);
wrapper.eq(Post::getIsPublic, 1);
- List posts = postMapper.selectList(wrapper);
+ IPage posts = postMapper.selectPage(page, wrapper);
// 使用PageInfo封装分页结果
- PageInfo pageInfo = new PageInfo<>(posts);
+// PageInfo pageInfo = new PageInfo<>(posts);
- return pageInfo;
+ return posts;
}
@Override
- public PageInfo getNonOfficialPosts(int pageNum, int pageSize) {
+ public IPage getNonOfficialPosts(int pageNum, int pageSize) {
logger.info("开始获取所有非官方创建的帖子,第{}页,每页{}条", pageNum, pageSize);
// 设置分页参数
- PageHelper.startPage(pageNum, pageSize);
-
+// PageHelper.startPage(pageNum, pageSize);
+ IPage page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Post::getIsOfficial, 0);
wrapper.eq(Post::getIsDeleted, 0);
wrapper.eq(Post::getIsPublic, 1);
- List posts = postMapper.selectList(wrapper);
+ IPage posts = postMapper.selectPage(page, wrapper);
// 使用PageInfo封装分页结果
- PageInfo pageInfo = new PageInfo<>(posts);
+// PageInfo pageInfo = new PageInfo<>(posts);
- return pageInfo;
+ return posts;
}
@Override
diff --git a/community-8073/src/main/resources/application-dev.properties b/community-8073/src/main/resources/application-dev.properties
index b25407e..abec73c 100644
--- a/community-8073/src/main/resources/application-dev.properties
+++ b/community-8073/src/main/resources/application-dev.properties
@@ -27,3 +27,7 @@ minio.accessKey=minio_root
minio.secretKey=minio_123456
minio.bucketName=haixia
+## Nacos??
+#spring.cloud.nacos.discovery.server-addr=/192.168.146.1:8848
+#dubbo.registry.address=nacos:///192.168.146.1:8848
+
diff --git a/community-8073/src/main/resources/mapper/BrowingHistoryMapper.xml b/community-8073/src/main/resources/mapper/BrowingHistoryMapper.xml
new file mode 100644
index 0000000..cb4fe77
--- /dev/null
+++ b/community-8073/src/main/resources/mapper/BrowingHistoryMapper.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ browing_id,user_openid,post_id,
+ create_at,is_delete
+
+
diff --git a/community-8073/src/main/resources/mapper/CommunitytagMapper.xml b/community-8073/src/main/resources/mapper/CommunitytagMapper.xml
new file mode 100644
index 0000000..a995906
--- /dev/null
+++ b/community-8073/src/main/resources/mapper/CommunitytagMapper.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ small_c_tag_id,c_tag_name,c_id,
+ is_delete
+
+
diff --git a/navigate-8432/pom.xml b/navigate-8432/pom.xml
index 97f02c0..e3aa5f4 100644
--- a/navigate-8432/pom.xml
+++ b/navigate-8432/pom.xml
@@ -29,6 +29,7 @@
com.baomidou
mybatis-plus-spring-boot3-starter
+ 3.5.7
com.alibaba.cloud
@@ -103,5 +104,10 @@
tencentcloud-sdk-java-tts
3.1.1076
+
+ com.tencentcloudapi
+ tencentcloud-sdk-java-asr
+ 3.1.1083
+
\ No newline at end of file
diff --git a/navigate-8432/src/main/java/com/ivmiku/tutorial/controller/AssistantController.java b/navigate-8432/src/main/java/com/ivmiku/tutorial/controller/AssistantController.java
index afef15d..c32bcee 100644
--- a/navigate-8432/src/main/java/com/ivmiku/tutorial/controller/AssistantController.java
+++ b/navigate-8432/src/main/java/com/ivmiku/tutorial/controller/AssistantController.java
@@ -24,11 +24,4 @@ public class AssistantController {
}
return Result.ok(map);
}
-
- @GetMapping("/tts")
- public Object textToSpeech(@RequestParam String input) {
- Map map = new HashMap<>();
- map.put("content", assistantService.textToSpeech(input));
- return Result.ok(map);
- }
}
diff --git a/navigate-8432/src/main/java/com/ivmiku/tutorial/entity/Guidance.java b/navigate-8432/src/main/java/com/ivmiku/tutorial/entity/Guidance.java
new file mode 100644
index 0000000..9b16ab0
--- /dev/null
+++ b/navigate-8432/src/main/java/com/ivmiku/tutorial/entity/Guidance.java
@@ -0,0 +1,14 @@
+package com.ivmiku.tutorial.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@TableName("guidance")
+@Data
+public class Guidance {
+ @TableId
+ private String id;
+ private String tag;
+ private String content;
+}
diff --git a/navigate-8432/src/main/java/com/ivmiku/tutorial/mapper/GuidanceMapper.java b/navigate-8432/src/main/java/com/ivmiku/tutorial/mapper/GuidanceMapper.java
new file mode 100644
index 0000000..4bdea0f
--- /dev/null
+++ b/navigate-8432/src/main/java/com/ivmiku/tutorial/mapper/GuidanceMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.Guidance;
+
+public interface GuidanceMapper extends BaseMapper {
+
+}
diff --git a/navigate-8432/src/main/java/com/ivmiku/tutorial/service/AssistantService.java b/navigate-8432/src/main/java/com/ivmiku/tutorial/service/AssistantService.java
index f060c58..c06c723 100644
--- a/navigate-8432/src/main/java/com/ivmiku/tutorial/service/AssistantService.java
+++ b/navigate-8432/src/main/java/com/ivmiku/tutorial/service/AssistantService.java
@@ -2,11 +2,15 @@ package com.ivmiku.tutorial.service;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
-import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.ivmiku.tutorial.entity.Guidance;
+import com.ivmiku.tutorial.mapper.GuidanceMapper;
import com.ivmiku.tutorial.utils.SnowflakeUtil;
-import com.tencentcloudapi.common.AbstractModel;
+import com.tencentcloudapi.asr.v20190614.AsrClient;
+import com.tencentcloudapi.asr.v20190614.models.SentenceRecognitionRequest;
+import com.tencentcloudapi.asr.v20190614.models.SentenceRecognitionResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
@@ -14,18 +18,23 @@ import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.tts.v20190823.TtsClient;
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceRequest;
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceResponse;
+import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
@Service
public class AssistantService {
+ @Resource
+ private GuidanceMapper guidanceMapper;
+
private final String auth = "bad1f6cad39a4c26aa9fe9e4324e096f:ZDczMDIwOTg3NjlhODdmYWVjYTY0YjM1";
private final String secretId = "AKID09INNYxYEFFJH3g9VhljVF3qbDiFdx50";
private final String secretKey = "KajjcNyNaaUCqQroqpzNoMtTHNj4Lbil";
- public Map getResponse(String userInput) {
+ public Map getAiResponse(String userInput) {
Map message1 = new HashMap<>();
message1.put("role", "system");
message1.put("content", "模仿语音助手,对用户的问题给出简短的回答");
@@ -74,4 +83,75 @@ public class AssistantService {
throw new RuntimeException(e);
}
}
+
+ public String speechRecognition(String content, Integer length) {
+ try{
+ Credential cred = new Credential(secretId, secretKey);
+ HttpProfile httpProfile = new HttpProfile();
+ httpProfile.setEndpoint("asr.tencentcloudapi.com");
+ ClientProfile clientProfile = new ClientProfile();
+ clientProfile.setHttpProfile(httpProfile);
+ AsrClient client = new AsrClient(cred, "", clientProfile);
+ SentenceRecognitionRequest req = new SentenceRecognitionRequest();
+ req.setEngSerViceType("16k_zh");
+ req.setSourceType(1L);
+ req.setVoiceFormat("wav");
+ req.setData(content);
+ req.setDataLen(Long.valueOf(length));
+ SentenceRecognitionResponse resp = client.SentenceRecognition(req);
+ return resp.getResult();
+ } catch (TencentCloudSDKException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String searchGuidance(String tag) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.like("tag", tag);
+ List list = guidanceMapper.selectList(queryWrapper);
+ if (list.isEmpty()) {
+ return null;
+ }
+ return list.getFirst().getContent();
+ }
+
+ public String extractTag(String query) {
+ Map message1 = new HashMap<>();
+ message1.put("role", "system");
+ message1.put("content", "根据给出的句子的意思,从以下标签中返回最匹配的一个:安全带、安检、飞机");
+ Map message2 = new HashMap<>();
+ message2.put("role", "user");
+ message2.put("content", query);
+ JSONArray array = new JSONArray();
+ array.add(message1);
+ array.add(message2);
+ JSONObject params = new JSONObject();
+ params.put("model", "general");
+ params.put("messages", array);
+ HttpResponse response = HttpRequest.post("https://spark-api-open.xf-yun.com/v1/chat/completions")
+ .header("Content-Type", "application/json")
+ .header("Authorization", "Bearer " + auth)
+ .body(params.toJSONString())
+ .execute();
+ JSONObject result = JSONObject.parseObject(response.body());
+ response.close();
+ if (result.getInteger("code") != 0) {
+ return null;
+ }
+ JSONArray choices = result.getJSONArray("choices");
+ JSONObject message = choices.getJSONObject(0);
+ return String.valueOf(message.getJSONObject("message"));
+ }
+
+ public Map getResponse(String query) {
+ Map result = new HashMap<>();
+ String tag = extractTag(query);
+ String content;
+ content = searchGuidance(tag);
+ if (content != null) {
+ result.put("content", content);
+ return result;
+ }
+ return getAiResponse(query);
+ }
}
diff --git a/user-8072/pom.xml b/user-8072/pom.xml
index 7b5121b..5ca0ed8 100644
--- a/user-8072/pom.xml
+++ b/user-8072/pom.xml
@@ -117,6 +117,14 @@
commons
1.0-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/config/MybatisPlusConfig.java b/user-8072/src/main/java/com/ivmiku/tutorial/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..71ed480
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/config/MybatisPlusConfig.java
@@ -0,0 +1,24 @@
+package com.ivmiku.tutorial.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@MapperScan("com.ivmiku.tutorial.mapper")
+public class MybatisPlusConfig {
+
+ /**
+ * 添加分页插件
+ */
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
+ return interceptor;
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java b/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java
new file mode 100644
index 0000000..d9ee381
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java
@@ -0,0 +1,27 @@
+package com.ivmiku.tutorial.config;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMqConfig {
+ @Bean
+ public Queue queue1() {
+ return new Queue("queue1",true);
+ }
+
+ @Bean
+ public FanoutExchange exchange1() {
+ return new FanoutExchange("exchange1",true, false);
+ }
+
+ @Bean
+ public Binding binding1() {
+ return BindingBuilder.bind(queue1()).to(exchange1());
+ }
+}
+
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/config/SaTokenConfigure.java b/user-8072/src/main/java/com/ivmiku/tutorial/config/SaTokenConfigure.java
new file mode 100644
index 0000000..85ca18f
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/config/SaTokenConfigure.java
@@ -0,0 +1,15 @@
+package com.ivmiku.tutorial.config;
+
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ // 注册 Sa-Token 拦截器,打开注解式鉴权功能
+ registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/config/WebSocketConfig.java b/user-8072/src/main/java/com/ivmiku/tutorial/config/WebSocketConfig.java
new file mode 100644
index 0000000..b36ddc7
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/config/WebSocketConfig.java
@@ -0,0 +1,34 @@
+package com.ivmiku.tutorial.config;
+
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletException;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
+import org.springframework.web.util.WebAppRootListener;
+
+@Configuration
+public class WebSocketConfig implements ServletContextInitializer {
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter (){
+ return new ServerEndpointExporter();
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ servletContext.addListener(WebAppRootListener.class);
+ servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize","102400000");
+ }
+
+ @Bean
+ public ServletServerContainerFactoryBean createWebSocketContainer() {
+ ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
+ // 在此处设置bufferSize
+ container.setMaxTextMessageBufferSize(50*1024*1024);
+ container.setMaxBinaryMessageBufferSize(50*1024*1024);
+ container.setMaxSessionIdleTimeout(15 * 60000L);
+ return container;
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/controller/MessageController.java b/user-8072/src/main/java/com/ivmiku/tutorial/controller/MessageController.java
new file mode 100644
index 0000000..326b872
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/controller/MessageController.java
@@ -0,0 +1,39 @@
+package com.ivmiku.tutorial.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import com.alibaba.fastjson2.JSON;
+import com.ivmiku.tutorial.entity.HistoryQuery;
+import com.ivmiku.tutorial.response.Result;
+import com.ivmiku.tutorial.service.MessageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.ParseException;
+
+@SaCheckLogin
+@RestController
+@RequestMapping("/api/message")
+public class MessageController {
+ @Autowired
+ private MessageService messageService;
+
+ @PostMapping("/history")
+ public Object getChatHistory(@RequestBody HistoryQuery input) throws ParseException {
+ Result result = Result.ok();
+ if (input.getStartDate() != null && input.getEndDate() != null) {
+ result.setData(messageService.getChatHistoryByDate(input.getUser1Id(), input.getUser2Id(), input.getStartDate(), input.getEndDate(), input.getPage(), input.getSize()));
+ } else {
+ if (input.getPage() <= 0 || input.getSize() <=0) {
+ return Result.error("请输入合法分页参数");
+ } else {
+ result.setData(messageService.getChatHistory(input.getUser1Id(), input.getUser2Id(), input.getPage(), input.getSize()));
+ }
+ }
+ return JSON.toJSON(result);
+ }
+
+ @GetMapping("/list")
+ public Object getChatList(@RequestParam String user_id, @RequestParam int page, @RequestParam int size) {
+ return Result.ok(messageService.getChatList(user_id, page, size));
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/controller/RelationController.java b/user-8072/src/main/java/com/ivmiku/tutorial/controller/RelationController.java
new file mode 100644
index 0000000..d7dcc88
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/controller/RelationController.java
@@ -0,0 +1,42 @@
+package com.ivmiku.tutorial.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.stp.StpUtil;
+import com.ivmiku.tutorial.entity.IgnoreUser;
+import com.ivmiku.tutorial.response.Result;
+import com.ivmiku.tutorial.service.RelationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@SaCheckLogin
+@RestController
+@RequestMapping("/api/relation")
+public class RelationController {
+ @Autowired
+ private RelationService relationService;
+
+ @PostMapping("/ignore")
+ public Object ignoreUser(@RequestBody IgnoreUser input) {
+ relationService.IgnoreUser(input.getUserId(), input.getToIgnore());
+ return Result.ok();
+ }
+
+ @GetMapping("subscribe")
+ public Object subscribe(@RequestParam String subId) {
+ String userId = (String) StpUtil.getLoginId();
+ relationService.subscribe(userId, subId);
+ return Result.ok();
+ }
+
+ @GetMapping("fan")
+ public Object getFanList(@RequestParam int page, @RequestParam int size) {
+ String userId = (String) StpUtil.getLoginId();
+ return Result.ok(relationService.getFanList(userId, page, size));
+ }
+
+ @GetMapping("follow")
+ public Object getFollowList(@RequestParam int page, @RequestParam int size) {
+ String userId = (String) StpUtil.getLoginId();
+ return Result.ok(relationService.getSubList(userId, page, size));
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java b/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java
new file mode 100644
index 0000000..993c05f
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java
@@ -0,0 +1,142 @@
+package com.ivmiku.tutorial.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.alibaba.fastjson2.JSON;
+import com.ivmiku.tutorial.entity.Message;
+import com.ivmiku.tutorial.service.MessageService;
+import com.ivmiku.tutorial.service.RelationService;
+import com.ivmiku.tutorial.utils.DateUtil;
+import com.ivmiku.tutorial.utils.MessageUtil;
+import jakarta.websocket.*;
+import jakarta.websocket.server.PathParam;
+import jakarta.websocket.server.ServerEndpoint;
+import org.springframework.amqp.core.ExchangeTypes;
+import org.springframework.amqp.rabbit.annotation.Exchange;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.QueueBinding;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Controller;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static jakarta.websocket.CloseReason.CloseCodes.CLOSED_ABNORMALLY;
+
+@Controller
+@ServerEndpoint(value = "/chat/{satoken}")
+public class WebSocketServer implements ApplicationContextAware {
+ public static Map sessionMap = new ConcurrentHashMap<>();
+
+ public static Map controlMap = new HashMap<>();
+
+ private static ApplicationContext applicationContext;
+
+ @Autowired
+ private MessageService messageService;
+
+ private RabbitTemplate rabbitTemplate;
+
+ private RelationService relationService;
+
+ @OnMessage
+ public void onMessage(String message, Session session) throws IOException {
+ Message msg = JSON.parseObject(message, Message.class);
+ msg.setDate(DateUtil.getCurrentTime());
+ if (MessageUtil.checkMessage(msg.getMessage())) {
+ session.getBasicRemote().sendText("发送的信息含有敏感词,请进行调整");
+ if (!controlMap.containsKey(msg.getFromId())){
+ controlMap.put(msg.getFromId(), 0);
+ }
+ if (controlMap.get(msg.getFromId()) == 4){
+ session.getBasicRemote().sendText("由于多次违反社区规则,您已被封禁1小时");
+ session.close(new CloseReason(CLOSED_ABNORMALLY, "账号被封禁"));
+ StpUtil.kickout(msg.getFromId());
+ StpUtil.disable(msg.getFromId(), 3600);
+ controlMap.put(msg.getFromId(), 0);
+ }
+ controlMap.put(msg.getFromId(), controlMap.get(msg.getFromId())+1);
+ } else
+ if (relationService.ifIgnored(msg.getToId(), msg.getFromId())) {
+ session.getBasicRemote().sendText("您已被对方屏蔽");
+ } else {
+ rabbitTemplate.convertAndSend("exchange1", "", JSON.toJSONString(msg));
+ }
+ }
+
+
+ @OnOpen
+ public void onOpen(Session session, EndpointConfig endpointConfig, @PathParam("satoken") String satoken) throws IOException {
+ String userId = (String) StpUtil.getLoginIdByToken(satoken);
+ if (userId == null) {
+ session.getBasicRemote().sendText("Invalid Token");
+ session.close();
+ }
+ this.messageService = WebSocketServer.applicationContext.getBean(MessageService.class);
+ this.rabbitTemplate = WebSocketServer.applicationContext.getBean(RabbitTemplate.class);
+ this.relationService = WebSocketServer.applicationContext.getBean(RelationService.class);
+ sessionMap.put(userId, session);
+ List unreadList = messageService.getUnreadMsg(userId);
+ for(Message msg : unreadList) {
+ session.getBasicRemote().sendText(JSON.toJSONString(msg));
+ }
+ }
+
+ @OnClose
+ public void onClose(CloseReason closeReason, Session session){
+ sessionMap.remove(session.getId());
+ }
+
+ @OnError
+ public void onError(Throwable throwable) throws IOException {
+ throwable.printStackTrace();
+ }
+
+ public void sendToUser(Message msg) throws IOException, ParseException {
+ if (sessionMap.containsKey(msg.getToId())){
+ sessionMap.get(msg.getToId()).getBasicRemote().sendText(JSON.toJSONString(msg));
+ }
+ else {
+ messageService.insertUnreadMsg(msg.getToId(), msg);
+ }
+ msg.setChatId(messageService.getChatId(msg.getFromId(), msg.getToId()));
+ messageService.insertToMysql(msg);
+ messageService.insertToRedis(msg);
+ }
+
+ public void sendToPublic(Message msg) throws IOException, ParseException {
+ for (Session session : sessionMap.values()) {
+ session.getBasicRemote().sendText(JSON.toJSONString(msg));
+ }
+ msg.setChatId(messageService.getChatId(msg.getFromId(), msg.getToId()));
+ messageService.insertToMysql(msg);
+ messageService.insertToRedis(msg);
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ WebSocketServer.applicationContext = applicationContext;
+ }
+
+ @RabbitHandler
+ @RabbitListener(bindings = @QueueBinding(
+ value = @Queue(),
+ exchange = @Exchange(value = "exchange1",type = ExchangeTypes.FANOUT)
+ ))
+ public void sendMsg(String message) throws IOException, ParseException {
+ Message msg = JSON.parseObject(message, Message.class);
+ if (sessionMap.containsKey(msg.getToId())) {
+ sessionMap.get(msg.getToId()).getBasicRemote().sendText(JSON.toJSONString(msg));
+ }
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/ChatId.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/ChatId.java
new file mode 100644
index 0000000..7da0f60
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/ChatId.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * @author Aurora
+ */
+@Data
+@TableName("chatid")
+public class ChatId {
+ @TableId(type = IdType.ASSIGN_ID)
+ private String id;
+ private String user1Id;
+ private String user2Id;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/Friend.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Friend.java
new file mode 100644
index 0000000..11cb2e4
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Friend.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Aurora
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("friend")
+public class Friend {
+ private String user1Id;
+ private String user2Id;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/FriendQuery.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/FriendQuery.java
new file mode 100644
index 0000000..b31d876
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/FriendQuery.java
@@ -0,0 +1,12 @@
+package com.ivmiku.tutorial.entity;
+
+import lombok.Data;
+
+/**
+ * @author Aurora
+ */
+@Data
+public class FriendQuery {
+ private String user1Id;
+ private String user2Id;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/HistoryQuery.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/HistoryQuery.java
new file mode 100644
index 0000000..8b6149e
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/HistoryQuery.java
@@ -0,0 +1,16 @@
+package com.ivmiku.tutorial.entity;
+
+import lombok.Data;
+
+/**
+ * @author Aurora
+ */
+@Data
+public class HistoryQuery {
+ private String user1Id;
+ private String user2Id;
+ private int page;
+ private int size;
+ private String startDate;
+ private String endDate;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/IgnoreUser.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/IgnoreUser.java
new file mode 100644
index 0000000..d3c592f
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/IgnoreUser.java
@@ -0,0 +1,21 @@
+package com.ivmiku.tutorial.entity;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Aurora
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("blacklist")
+public class IgnoreUser {
+ @JSONField(ordinal = 1)
+ private String userId;
+ @JSONField(ordinal = 2)
+ private String toIgnore;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/Message.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Message.java
new file mode 100644
index 0000000..e96f45a
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Message.java
@@ -0,0 +1,25 @@
+package com.ivmiku.tutorial.entity;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Aurora
+ */
+@Data
+@TableName("message")
+public class Message implements Serializable {
+ @JSONField(ordinal = 1)
+ private String chatId;
+ @JSONField(ordinal = 2)
+ private String fromId;
+ @JSONField(ordinal = 3)
+ private String toId;
+ @JSONField(ordinal = 4)
+ private String message;
+ @JSONField(ordinal = 5)
+ private String date;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/SubUser.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/SubUser.java
new file mode 100644
index 0000000..60bccb5
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/SubUser.java
@@ -0,0 +1,18 @@
+package com.ivmiku.tutorial.entity;
+
+import lombok.Data;
+
+@Data
+public class SubUser {
+ private String id;
+ private String username;
+ private String avatarUrl;
+
+ public static SubUser setUser(User user) {
+ SubUser subUser = new SubUser();
+ subUser.setId(user.getOpenid());
+ subUser.setUsername(user.getNickname());
+ subUser.setAvatarUrl(user.getAvatarUrl());
+ return subUser;
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java
new file mode 100644
index 0000000..054070f
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java
@@ -0,0 +1,13 @@
+package com.ivmiku.tutorial.entity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * @author Aurora
+ */
+@TableName("subscribe")
+@Data
+public class Subscribe {
+ private Long id;
+ private Long subId;
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/mapper/BlackListMapper.java b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/BlackListMapper.java
new file mode 100644
index 0000000..7d99648
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/BlackListMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.IgnoreUser;
+
+public interface BlackListMapper extends BaseMapper {
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/mapper/ChatIdMapper.java b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/ChatIdMapper.java
new file mode 100644
index 0000000..ec9ddaa
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/ChatIdMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.ChatId;
+
+public interface ChatIdMapper extends BaseMapper {
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/mapper/FriendMapper.java b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/FriendMapper.java
new file mode 100644
index 0000000..32ea471
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/FriendMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.Friend;
+
+public interface FriendMapper extends BaseMapper {
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/mapper/MessageMapper.java b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/MessageMapper.java
new file mode 100644
index 0000000..b6d5ee1
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/MessageMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.Message;
+
+public interface MessageMapper extends BaseMapper {
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java
new file mode 100644
index 0000000..53d67c9
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java
@@ -0,0 +1,8 @@
+package com.ivmiku.tutorial.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ivmiku.tutorial.entity.Subscribe;
+
+public interface SubscribeMapper extends BaseMapper {
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java b/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java
new file mode 100644
index 0000000..d7e3c88
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java
@@ -0,0 +1,236 @@
+package com.ivmiku.tutorial.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ivmiku.tutorial.entity.ChatId;
+import com.ivmiku.tutorial.entity.Message;
+import com.ivmiku.tutorial.mapper.ChatIdMapper;
+import com.ivmiku.tutorial.mapper.MessageMapper;
+import com.ivmiku.tutorial.utils.RedisUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author Aurora
+ */
+@Service
+public class MessageService {
+ @Autowired
+ private MessageMapper messageMapper;
+
+ @Autowired
+ private ChatIdMapper chatIdMapper;
+
+ @Autowired
+ private RedisUtil redisUtil;
+
+ /**
+ * 获取会话id
+ * @param user1Id 用户1id
+ * @param user2Id 用户2id
+ * @return 查询结果
+ */
+ public String getChatId(String user1Id, String user2Id) {
+ if (Objects.equals(user1Id, "public") || Objects.equals(user2Id, "public")) {
+ return "0";
+ }
+ String id1, id2;
+ if (user1Id.compareTo(user2Id) < 0) {
+ id1 = user1Id;
+ id2 = user2Id;
+ } else {
+ id1 = user2Id;
+ id2 = user1Id;
+ }
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("user1_id", id1);
+ queryWrapper.eq("user2_id", id2);
+ ChatId chatId = chatIdMapper.selectOne(queryWrapper);
+ if (chatId == null) {
+ chatId = new ChatId();
+ chatId.setUser1Id(id1);
+ chatId.setUser2Id(id2);
+ chatIdMapper.insert(chatId);
+ }
+ return chatIdMapper.selectOne(queryWrapper).getId();
+ }
+
+ /**
+ * 聊天记录写redis
+ * @param msg 要写入的信息
+ * @throws ParseException
+ */
+ @Async
+ public void insertToRedis(Message msg) throws ParseException {
+ if (!(msg.getMessage().length() >1000)) {
+ if (redisUtil.getZsetSize("history:" + msg.getChatId()) >= 50) {
+ redisUtil.zsetRightPop("history:" + msg.getChatId());
+ }
+ redisUtil.zsetAdd("history:" + msg.getChatId(), msg);
+ redisUtil.setExpireTime("history:" + msg.getChatId());
+ }
+ }
+
+ /**
+ * 聊天记录写入mysql
+ * @param msg 要写入的消息
+ */
+ @Async
+ public void insertToMysql(Message msg) {
+ if (!(msg.getMessage().length() >1000)) {
+ messageMapper.insert(msg);
+ }
+ }
+
+ /**
+ * 未读消息写入redis
+ * @param userId 用户id
+ * @param msg 未读消息
+ */
+ @Async
+ public void insertUnreadMsg(String userId, Message msg) {
+ redisUtil.listAdd("unread:" + userId, msg);
+ }
+
+ /**
+ * 获取未读消息列表
+ * @param userId 用户id
+ * @return 查询结果
+ */
+ public List getUnreadMsg(String userId) {
+ List result = redisUtil.listGet("unread:" + userId, 0, -1);
+ redisUtil.listClear(userId);
+ return result;
+ }
+
+ /**
+ * 从数据库获取聊天记录
+ * @param chatId 会话id
+ * @param current 分页参数
+ * @param size 分页参数
+ * @return 返回的查询结果
+ */
+ public List getChatHistoryFromDB(String chatId, int current, int size) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ Page page = new Page<>(current, size);
+ queryWrapper.eq("chat_id", chatId);
+ queryWrapper.orderByDesc("date");
+ return messageMapper.selectPage(page, queryWrapper).getRecords();
+ }
+
+ /**
+ * 从数据库获取聊天记录,查询一定范围内
+ * @param chatId 会话id
+ * @param current 分页参数
+ * @param size 分页参数
+ * @param startDate 开始日期
+ * @param endDate 结束日期
+ * @return 返回的查询结果
+ */
+ public List getChatHistoryFromDBByDate(String chatId, int current, int size, String startDate, String endDate) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.between("date", startDate, endDate);
+ Page page = new Page<>(current, size);
+ queryWrapper.eq("chat_id", chatId);
+ queryWrapper.orderByDesc("date");
+ return messageMapper.selectPage(page, queryWrapper).getRecords();
+ }
+
+ /**
+ * redis获取聊天记录
+ * @param chatId 会话id
+ * @param s 开始
+ * @param e 结束
+ * @return 查询结果
+ */
+ public List getChatHistoryFromRedis(String chatId, int s, int e) {
+ return redisUtil.zsetGet("history:" + chatId, s, e);
+ }
+
+ /**
+ * 查询聊天记录
+ * @param user1Id 用户1id
+ * @param user2Id 用户2id
+ * @param page 分页参数
+ * @param size 分页参数
+ * @return 查询结果
+ * @throws ParseException
+ */
+ public List getChatHistory(String user1Id, String user2Id, int page, int size) throws ParseException {
+ int start = page * size - size;
+ int end = page * size - 1;
+ String chatId = getChatId(user1Id, user2Id);
+ loadCache(chatId);
+ List result = new ArrayList<>(redisUtil.zsetGet("history:" + chatId, start, end));
+ if ((end -start + 1) == result.size()) {
+ return result;
+ }
+ int redisSize = result.size();
+ List dbList = getChatHistoryFromDB(chatId, ((end - result.size()) / size) + 1, size);
+ result.addAll(dbList.subList(redisSize, dbList.size()));
+ redisUtil.refreshExpire("history:" + chatId);
+ return result;
+ }
+
+ /**
+ * 在一定时间范围内查询聊天记录
+ * @param user1Id 用户1id
+ * @param user2Id 用户2id
+ * @param startDate 开始日期
+ * @param endDate 结束日期
+ * @param page 分页参数
+ * @param size 分页参数
+ * @return 查询结果
+ * @throws ParseException
+ */
+ public List getChatHistoryByDate(String user1Id, String user2Id, String startDate, String endDate, int page, int size) throws ParseException {
+ int start = page * size - size;
+ int end = page * size - 1;
+ String chatId = getChatId(user1Id, user2Id);
+ loadCache(chatId);
+ List result = new ArrayList<>(redisUtil.zsetGetByDate("history:" + chatId, startDate, endDate, start, size));
+ redisUtil.refreshExpire("history:" + chatId);
+ if (result.size() == (end - start + 1)) {
+ return result;
+ }
+ int redisSize = result.size();
+ List dbList = getChatHistoryFromDBByDate(chatId, ((end - result.size()) / size) + 1, size, startDate, endDate).subList(result.size(), size);
+ result.addAll(dbList.subList(redisSize, dbList.size()));
+ return result;
+ }
+
+ /**
+ * 获取会话列表
+ * @param userId 用户id
+ * @param current 分页参数
+ * @param size 分页参数
+ * @return 查询结果
+ */
+ public List getChatList(String userId, int current, int size) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("user1_id", userId).or().eq("user2_id", userId);
+ queryWrapper.orderByDesc("id");
+ Page page = new Page<>(current, size);
+ return chatIdMapper.selectPage(page, queryWrapper).getRecords();
+ }
+
+ /**
+ * 加载聊天记录到redis
+ * @param chatId 会话id
+ * @throws ParseException
+ */
+ public void loadCache(String chatId) throws ParseException {
+ if (!redisUtil.ifExist("history:" + chatId)) {
+ List list = getChatHistoryFromDB(chatId, 1, 20);
+ for (Message message : list) {
+ insertToRedis(message);
+ }
+ }
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/service/RelationService.java b/user-8072/src/main/java/com/ivmiku/tutorial/service/RelationService.java
new file mode 100644
index 0000000..8dc4bd3
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/service/RelationService.java
@@ -0,0 +1,120 @@
+package com.ivmiku.tutorial.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import com.ivmiku.tutorial.entity.*;
+import com.ivmiku.tutorial.mapper.BlackListMapper;
+import com.ivmiku.tutorial.mapper.FriendMapper;
+import com.ivmiku.tutorial.mapper.SubscribeMapper;
+import com.ivmiku.tutorial.utils.RedisUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Aurora
+ */
+@Service
+public class RelationService {
+ @Autowired
+ private BlackListMapper blackListMapper;
+
+ @Autowired
+ private FriendMapper friendMapper;
+
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ private SubscribeMapper subscribeMapper;
+
+ @Autowired
+ private UserService userService;
+
+ /**
+ * 屏蔽用户
+ * @param userId 用户id
+ * @param toIgnore 要屏蔽的用户id
+ */
+ public void IgnoreUser(String userId, String toIgnore) {
+ blackListMapper.insert(new IgnoreUser(userId, toIgnore));
+ if (redisUtil.ifExist("blacklist:" + userId)) {
+ redisUtil.listAdd("blacklist:" + userId, toIgnore);
+ }
+ }
+
+ /**
+ * 查询用户是否屏蔽了该用户
+ * @param userId 用户id
+ * @param ignoreId 要查询的id
+ * @return 查询结果
+ */
+ public boolean ifIgnored(String userId, String ignoreId) {
+ loadCache(userId);
+ List blackList = redisUtil.getStringList("blacklist:" + userId, 0, -1);
+ redisUtil.refreshExpire("blacklist:" + userId);
+ return blackList.contains(ignoreId);
+ }
+
+ /**
+ * 加载缓存
+ * @param userId 用户id
+ */
+ public void loadCache(String userId) {
+ if (!redisUtil.ifExist("blacklist:" + userId)) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("user_id", userId);
+ List list = blackListMapper.selectList(queryWrapper);
+ List result = new ArrayList<>();
+ if (list != null) {
+ for (IgnoreUser object : list) {
+ result.add(object.getToIgnore());
+ }
+ }
+ for (String toIgnore : result) {
+ redisUtil.listAdd("blacklist:" + userId, toIgnore);
+ }
+ redisUtil.setExpireTime("blacklist:" + userId);
+ }
+ }
+
+ public void subscribe(String id, String toId) {
+ Subscribe subscribe = new Subscribe();
+ subscribe.setId(Long.valueOf(id));
+ subscribe.setSubId(Long.valueOf(toId));
+ subscribeMapper.insert(subscribe);
+ }
+
+ public List getFanList(String userId, int page, int size) {
+ List list = new ArrayList<>();
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ Page pager = new Page<>(page, size);
+ queryWrapper.eq("sub_id", userId);
+ List array = subscribeMapper.selectPage(pager, queryWrapper).getRecords();
+ for (Subscribe subscribe : array) {
+ String queryId = String.valueOf(subscribe.getId());
+ User user = userService.selectUserById(queryId);
+ SubUser subUser = SubUser.setUser(user);
+ list.add(subUser);
+ }
+ return list;
+ }
+
+ public List getSubList(String userId, int page, int size) {
+ List list = new ArrayList<>();
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ Page pager = new Page<>(page, size);
+ queryWrapper.eq("id", userId);
+ List array = subscribeMapper.selectPage(pager, queryWrapper).getRecords();
+ for (Subscribe subscribe : array) {
+ String queryId = String.valueOf(subscribe.getSubId());
+ User user = userService.selectUserById(queryId);
+ SubUser subUser = SubUser.setUser(user);
+ list.add(subUser);
+ }
+ return list;
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/service/UserService.java b/user-8072/src/main/java/com/ivmiku/tutorial/service/UserService.java
new file mode 100644
index 0000000..86c6c77
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/service/UserService.java
@@ -0,0 +1,16 @@
+package com.ivmiku.tutorial.service;
+
+import com.ivmiku.tutorial.entity.User;
+import com.ivmiku.tutorial.mapper.UserMapper;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserService {
+ @Resource
+ private UserMapper userMapper;
+
+ public User selectUserById(String id) {
+ return userMapper.selectById(id);
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/utils/DateUtil.java b/user-8072/src/main/java/com/ivmiku/tutorial/utils/DateUtil.java
new file mode 100644
index 0000000..8430632
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/utils/DateUtil.java
@@ -0,0 +1,43 @@
+package com.ivmiku.tutorial.utils;
+
+import jakarta.annotation.PostConstruct;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * @author Aurora
+ */
+public class DateUtil {
+ /**
+ * 获取当前时间
+ * @return 当前时间字符串
+ */
+ public static String getCurrentTime() {
+ Date date = new Date();
+ SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return ft.format(date);
+ }
+
+ /**
+ * 转换为时间戳
+ * @param time 时间字符串
+ * @return 时间戳
+ * @throws ParseException
+ */
+ public static long toTimeSig(String time) throws ParseException {
+ SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = ft.parse(time);
+ return date.getTime();
+ }
+
+ /**
+ * 设置当前时区GMT+8
+ */
+ @PostConstruct
+ public void setTimeZone() {
+ TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
+ }
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/utils/MessageUtil.java b/user-8072/src/main/java/com/ivmiku/tutorial/utils/MessageUtil.java
new file mode 100644
index 0000000..da73040
--- /dev/null
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/utils/MessageUtil.java
@@ -0,0 +1,36 @@
+package com.ivmiku.tutorial.utils;
+
+import com.ivmiku.tutorial.service.RelationService;
+import org.springframework.stereotype.Component;
+
+/**
+ * 敏感词检测
+ * @author Aurora
+ */
+@Component
+public class MessageUtil {
+ private static final String[] SENSITIVE = {"你妈", "你妈逼的"};
+
+ private static RelationService relationService = null;
+
+ public MessageUtil(RelationService relationService) {
+ MessageUtil.relationService = relationService;
+ }
+
+ /**
+ * 查看发送的信息是否含有敏感词
+ * @param message 要发送的信息
+ * @return 检查结果
+ */
+ public static boolean checkMessage(String message) {
+ if (message != null) {
+ for(String keyword : SENSITIVE) {
+ if (message.contains(keyword)){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java b/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java
index 8ff2877..4f03f73 100644
--- a/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java
+++ b/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java
@@ -1,9 +1,18 @@
package com.ivmiku.tutorial.utils;
+import com.alibaba.fastjson2.JSON;
+import com.ivmiku.tutorial.entity.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
/**
* @author Aurora
*/
@@ -12,11 +21,97 @@ public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
- public void insertKey(String userId, String sessionKey) {
- redisTemplate.opsForValue().set("sessionkey:" + userId, sessionKey);
+ public void listAdd(String key, Object value) {
+ redisTemplate.opsForList().leftPush(key, value);
}
- public String getKey(String userId) {
- return (String) redisTemplate.opsForValue().get("sessionkey:" + userId);
+ public List listGet(String key, int s, int e) {
+ List