From 300f3262814d273ea792d1541f13afd9f18a0354 Mon Sep 17 00:00:00 2001
From: Xubx <1827135378@qq.com>
Date: Tue, 19 Nov 2024 14:35:22 +0800
Subject: [PATCH] =?UTF-8?q?=E7=82=B9=E8=B5=9E=EF=BC=8C=E6=94=B6=E8=97=8F?=
=?UTF-8?q?=EF=BC=8C=E6=B5=8F=E8=A7=88=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/compiler.xml | 11 +-
pom.xml | 5 +
.../xubx/springboot_01demo/Task/DataSync.java | 294 +++++++++++++++++
.../configuration/RedisConfig.java | 27 ++
.../configuration/constantConfiguration.java | 43 +++
.../controller/BlogsController.java | 107 +++++-
.../controller/MessagesController.java | 12 +-
.../controller/RelationshipController.java | 32 +-
.../controller/UserController.java | 197 ++++++++---
.../blog/{addBlogDto.java => AddBlogDto.java} | 2 +-
.../dto/blog/CollectBlogDto.java | 19 ++
.../dto/blog/GetUserBlogsDto.java | 23 ++
.../dto/user/EditMaterialDto.java | 20 ++
.../dto/user/NewFavoritesDto.java | 26 ++
.../mapper/BlogLikeMapper.java | 7 +
.../springboot_01demo/mapper/BlogsMapper.java | 106 +++++-
.../mapper/RelationshipMapper.java | 10 +-
.../mapper/UserFavoriteBlogMapper.java | 7 +
.../mapper/UserFavoriteMapper.java | 7 +
.../springboot_01demo/mapper/UserMapper.java | 5 +-
.../xubx/springboot_01demo/pojo/BlogLike.java | 24 ++
.../xubx/springboot_01demo/pojo/Blogs.java | 9 +-
.../springboot_01demo/pojo/Relationship.java | 2 +-
.../com/xubx/springboot_01demo/pojo/User.java | 80 ++---
.../springboot_01demo/pojo/UserFavorite.java | 41 +++
.../pojo/UserFavoriteBlog.java | 20 ++
.../service/BlogService.java | 21 +-
.../service/UserService.java | 43 ++-
.../service/impl/BlogsServiceImpl.java | 308 +++++++++++++++++-
.../service/impl/CommentServiceImpl.java | 4 +-
.../service/impl/RelationshipServiceImpl.java | 6 +-
.../service/impl/UserServiceImpl.java | 260 +++++++++++++--
.../utils/token/RequestHolder.java | 6 +-
.../utils/token/TokenGenerate.java | 8 +-
.../springboot_01demo/vo/GetBlogDetailVo.java | 54 +++
.../springboot_01demo/vo/getUserInfoVo.java | 44 +++
src/main/resources/application.yml | 4 +-
src/main/resources/mapper/BlogLikeMapper.xml | 6 +
src/main/resources/mapper/BlogsMapper.xml | 49 +++
.../resources/mapper/RelationshipMapper.xml | 3 +
.../mapper/UserFavoriteBlogMapper.xml | 6 +
.../resources/mapper/UserFavoriteMapper.xml | 6 +
src/main/resources/mapper/UserMapper.xml | 4 -
43 files changed, 1778 insertions(+), 190 deletions(-)
create mode 100644 src/main/java/com/xubx/springboot_01demo/Task/DataSync.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/configuration/RedisConfig.java
rename src/main/java/com/xubx/springboot_01demo/dto/blog/{addBlogDto.java => AddBlogDto.java} (94%)
create mode 100644 src/main/java/com/xubx/springboot_01demo/dto/blog/CollectBlogDto.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/dto/blog/GetUserBlogsDto.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/dto/user/EditMaterialDto.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/dto/user/NewFavoritesDto.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/mapper/BlogLikeMapper.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteBlogMapper.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteMapper.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/pojo/BlogLike.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/pojo/UserFavorite.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/pojo/UserFavoriteBlog.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/vo/GetBlogDetailVo.java
create mode 100644 src/main/java/com/xubx/springboot_01demo/vo/getUserInfoVo.java
create mode 100644 src/main/resources/mapper/BlogLikeMapper.xml
create mode 100644 src/main/resources/mapper/UserFavoriteBlogMapper.xml
create mode 100644 src/main/resources/mapper/UserFavoriteMapper.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 3b1b933..fd9a529 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -7,13 +7,20 @@
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index bc02df4..60c27a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,11 @@
fastjson
1.2.83
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.12.5
+
io.springfox
springfox-swagger2
diff --git a/src/main/java/com/xubx/springboot_01demo/Task/DataSync.java b/src/main/java/com/xubx/springboot_01demo/Task/DataSync.java
new file mode 100644
index 0000000..add3617
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/Task/DataSync.java
@@ -0,0 +1,294 @@
+package com.xubx.springboot_01demo.Task;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.xubx.springboot_01demo.configuration.constantConfiguration;
+import com.xubx.springboot_01demo.mapper.BlogLikeMapper;
+import com.xubx.springboot_01demo.mapper.BlogsMapper;
+import com.xubx.springboot_01demo.mapper.UserFavoriteBlogMapper;
+import com.xubx.springboot_01demo.pojo.BlogLike;
+import com.xubx.springboot_01demo.pojo.Blogs;
+import com.xubx.springboot_01demo.pojo.UserFavoriteBlog;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Component
+@Slf4j
+public class DataSync {
+ @Resource
+ RedisTemplate redisTemplate;
+ @Resource
+ BlogsMapper blogsMapper;
+ @Resource
+ BlogLikeMapper blogLikeMapper;
+ @Resource
+ UserFavoriteBlogMapper userFavoriteBlogMapper;
+ @Autowired
+ ObjectMapper objectMapper;
+
+ /**
+ * 博客浏览数的数据同步 ,每小时执行一次
+ */
+// @Scheduled(cron = "0 0 * * * ?")
+ @Scheduled(cron = "0 * * * * ?")
+ public void viewCountSync() {
+ log.info("博客浏览数的数据同步定时任务执行");
+
+ String lockKey = constantConfiguration.BLOG_VIEW_COUNT_SYNC_LOCK;
+ Boolean isLock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 60, TimeUnit.SECONDS));
+ if (Boolean.TRUE.equals(isLock)) {
+ try {
+ Set viewCountKeys = redisTemplate.keys(constantConfiguration.BLOG_VIEW_COUNT + "*");
+ if (viewCountKeys != null) {
+ for (String key : viewCountKeys) {
+ String blogIdStr = key.split(":")[2];
+ String expirekey = constantConfiguration.BLOG_VIEW_COUNT + blogIdStr + ":expired";
+
+ Boolean isExpired = Boolean.TRUE.equals(redisTemplate.hasKey(expirekey))
+ && Boolean.parseBoolean((String) redisTemplate.opsForValue().get(expirekey));
+ // 如果标签存在 则进行数据的更新,若不存在则表示数据已经同步 或者数据还没被更新
+ if (Boolean.TRUE.equals(isExpired)) {
+ String viewCount = (String) redisTemplate.opsForValue().get(key);
+ if (viewCount != null) {
+ //更新数据
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.eq(Blogs::getId, blogIdStr)
+ .set(Blogs::getViewCount, viewCount);
+ blogsMapper.update(null, updateWrapper);
+ // 删除逻辑过期标志
+ redisTemplate.delete(expirekey);
+ }
+ }
+ }
+ }
+ } finally {
+ redisTemplate.delete(lockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,博客浏览数的数据同步任务无法执行");
+ }
+ }
+
+ /**
+ * 博客点赞数的数据同步定时任务执行
+ */
+ @Scheduled(cron = "0 * * * * ?")
+ public void likeCountSync() {
+ log.info("博客点赞数的数据同步定时任务执行");
+ String lockKey = constantConfiguration.BLOG_LIKE_COUNT_SYNC_LOCK;
+ Boolean isLock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 60, TimeUnit.SECONDS));
+
+ if (Boolean.TRUE.equals(isLock)) {
+ try {
+ Set likeCountKeys = redisTemplate.keys(constantConfiguration.BLOG_LIKE_COUNT + "*");
+ if (likeCountKeys != null) {
+ for (String key : likeCountKeys) {
+ String blogIdStr = key.split(":")[2];
+ String likeCountExpireKey = constantConfiguration.BLOG_LIKE_COUNT + blogIdStr + ":expired";
+
+ Boolean countExpireFlag = Boolean.TRUE.equals(redisTemplate.hasKey(likeCountExpireKey))
+ && Boolean.parseBoolean((String) redisTemplate.opsForValue().get(likeCountExpireKey));
+
+ if (Boolean.TRUE.equals(countExpireFlag)) {
+ String likeCount = (String) redisTemplate.opsForValue().get(key);
+ if (likeCount != null) {
+ // 更新点赞次数到数据库
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.eq(Blogs::getId, blogIdStr).set(Blogs::getLikeCount, Integer.parseInt(likeCount));
+ blogsMapper.update(null, updateWrapper);
+
+ // 删除逻辑过期标志
+ redisTemplate.delete(likeCountExpireKey);
+ }
+ }
+ }
+ }
+ } finally {
+ redisTemplate.delete(lockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,博客点赞数的数据同步任务无法执行");
+ }
+ }
+
+ /**
+ * 博客点赞用户Hash集合的增量数据同步定时任务执行
+ */
+ @Scheduled(cron = "0 * * * * ?") //TODO 每小时执行一次
+ public void likeUserSync() {
+ log.info("博客点赞用户Hash集合的增量数据同步定时任务执行");
+ String lockKey = constantConfiguration.BLOG_LIKE_USERHASH_SYNC_LOCK;
+ Boolean isLock = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 60, TimeUnit.SECONDS));
+
+ if (Boolean.TRUE.equals(isLock)) {
+ try {
+ Set likeUserKeys = redisTemplate.keys(constantConfiguration.BLOG_LIKE_HASH + "*");
+ if (likeUserKeys != null) {
+ for (String key : likeUserKeys) {
+ String blogIdStr = key.split(":")[2];
+ String likeUserExpireKey = constantConfiguration.BLOG_LIKE_HASH + blogIdStr + ":expired";
+
+ Boolean userHashExpireFlag = Boolean.TRUE.equals(redisTemplate.hasKey(likeUserExpireKey))
+ && Boolean.parseBoolean((String) redisTemplate.opsForValue().get(likeUserExpireKey));
+
+ if (Boolean.TRUE.equals(userHashExpireFlag)) {
+ // 获取博客点赞用户集合中的所有用户ID
+ Set userIds = redisTemplate.opsForHash().keys(constantConfiguration.BLOG_LIKE_HASH + blogIdStr);
+ if (userIds != null) {
+ for (String userId : userIds) {
+ String likeStatus = (String) redisTemplate.opsForHash().get(constantConfiguration.BLOG_LIKE_HASH + blogIdStr, userId);
+ if ("true".equals(likeStatus)) {
+ // 插入数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(BlogLike::getBlogId, blogIdStr).eq(BlogLike::getUserId, userId);
+ BlogLike blogLike = blogLikeMapper.selectOne(queryWrapper);
+
+ if (blogLike == null) {
+ BlogLike newBlogLike = new BlogLike();
+ newBlogLike.setBlogId(Integer.valueOf(blogIdStr));
+ newBlogLike.setUserId(Integer.valueOf(userId));
+ newBlogLike.setCreatedTime(Timestamp.valueOf(LocalDateTime.now()));
+ blogLikeMapper.insert(newBlogLike);
+ }
+ } else if ("false".equals(likeStatus)) {
+ // 用户取消点赞 则删除记录
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(BlogLike::getBlogId, blogIdStr).eq(BlogLike::getUserId, userId);
+ blogLikeMapper.delete(queryWrapper);
+ }
+ }
+ // 删除逻辑过期标志和哈希数据
+ redisTemplate.delete(likeUserExpireKey);
+ redisTemplate.delete(constantConfiguration.BLOG_LIKE_HASH + blogIdStr);
+ }
+ }
+ }
+ }
+ } finally {
+ redisTemplate.delete(lockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,博客点赞用户Hash集合的增量数据同步任务无法执行");
+ }
+ }
+
+ /**
+ * 博客收藏数的数据同步定时任务
+ */
+ @Scheduled(cron = "0 * * * * ?") //TODO 每小时执行一次
+ public void collectCountSync() {
+ log.info("博客收藏数的数据同步定时任务执行");
+ String lockKey = constantConfiguration.BLOG_COLLECT_COUNT_SYNC_LOCK;
+ Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "LOCKED", 30, TimeUnit.MINUTES);
+
+ if (Boolean.TRUE.equals(lockAcquired)) {
+ try {
+ Set collectCountKeys = redisTemplate.keys(constantConfiguration.BLOG_COLLECT_COUNT + "*");
+ if (collectCountKeys != null) {
+ for (String key : collectCountKeys) {
+ String blogIdStr = key.split(":")[2];
+ String collectCountExpireKey = constantConfiguration.BLOG_COLLECT_COUNT + blogIdStr + ":expired";
+
+ Boolean countExpireFlag = Boolean.TRUE.equals(redisTemplate.hasKey(collectCountExpireKey))
+ && Boolean.parseBoolean((String) redisTemplate.opsForValue().get(collectCountExpireKey));
+
+ if (Boolean.TRUE.equals(countExpireFlag)) {
+ String collectCount = (String) redisTemplate.opsForValue().get(key);
+ if (collectCount != null) {
+ // 更新收藏次数到数据库
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.eq(Blogs::getId, blogIdStr).set(Blogs::getCollectCount, Integer.parseInt(collectCount));
+ blogsMapper.update(null, updateWrapper);
+
+ // 删除逻辑过期标志
+ redisTemplate.delete(collectCountExpireKey);
+ }
+ }
+ }
+ }
+ } finally {
+ redisTemplate.delete(lockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,跳过此次收藏数同步任务");
+ }
+ }
+
+ /**
+ * 博客收藏增量数据同步
+ *
+ * @throws JsonProcessingException
+ */
+ @Scheduled(cron = "0 * * * * ?") //TODO 每小时执行一次
+ public void collectUserSync() {
+ log.info("博客收藏用户Hash集合的数据同步定时任务执行");
+ String lockKey = constantConfiguration.BLOG_COLLECT_USERHASH_SYNC_LOCK;
+ Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "LOCKED", 30, TimeUnit.MINUTES);
+
+ if (Boolean.TRUE.equals(lockAcquired)) {
+ try {
+ // TODO 应该是同时获取到了逻辑过期标志的Key,需要进行去除
+ Set collectUserKeys = redisTemplate.keys(constantConfiguration.BLOG_COLLECT_HASH + "*");
+ if (collectUserKeys != null) {
+ for (String key : collectUserKeys) {
+ String favoriteIdStr = key.split(":")[2];
+ String collectUserExpireKey = constantConfiguration.BLOG_COLLECT_HASH + favoriteIdStr + ":expired";
+
+ Boolean userExpireFlag = Boolean.TRUE.equals(redisTemplate.hasKey(collectUserExpireKey))
+ && Boolean.parseBoolean((String) redisTemplate.opsForValue().get(collectUserExpireKey));
+ if (Boolean.TRUE.equals(userExpireFlag)) {
+ // 获取博客收藏用户集合中的所有博客
+ Set blogSet = redisTemplate.opsForHash().keys(constantConfiguration.BLOG_COLLECT_HASH + favoriteIdStr);
+ if (blogSet != null) {
+ for (String blogIdStr : blogSet) {
+ // 根据用户的收藏状态,更新数据
+ String collectStatus = (String) redisTemplate.opsForHash().get(constantConfiguration.BLOG_COLLECT_HASH + favoriteIdStr, blogIdStr);
+ if ("true".equals(collectStatus)) {
+ // 如果数据库中没有该数据则插入数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(UserFavoriteBlog::getBlogId, blogIdStr).eq(UserFavoriteBlog::getFavoriteId, favoriteIdStr);
+ UserFavoriteBlog userFavoriteBlog = userFavoriteBlogMapper.selectOne(queryWrapper);
+ if (userFavoriteBlog == null) {
+ userFavoriteBlog = new UserFavoriteBlog();
+ userFavoriteBlog.setBlogId(Integer.valueOf(blogIdStr));
+ userFavoriteBlog.setFavoriteId(Integer.valueOf(favoriteIdStr));
+ userFavoriteBlogMapper.insert(userFavoriteBlog);
+ }
+ } else if ("false".equals(collectStatus)) {
+ // 用户取消收藏 删除数据
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(UserFavoriteBlog::getBlogId, blogIdStr).eq(UserFavoriteBlog::getFavoriteId, favoriteIdStr);
+ userFavoriteBlogMapper.delete(queryWrapper);
+ }
+ }
+ // 删除逻辑过期标志和Hash集合
+ redisTemplate.delete(collectUserExpireKey);
+ redisTemplate.delete(constantConfiguration.BLOG_COLLECT_HASH + favoriteIdStr);
+ }
+
+ }
+ }
+ }
+ } finally {
+ redisTemplate.delete(lockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,跳过此次收藏用户Hash集合的数据同步任务");
+ }
+ }
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/configuration/RedisConfig.java b/src/main/java/com/xubx/springboot_01demo/configuration/RedisConfig.java
new file mode 100644
index 0000000..de642c2
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/configuration/RedisConfig.java
@@ -0,0 +1,27 @@
+package com.xubx.springboot_01demo.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+@Configuration
+public class RedisConfig {
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
+ RedisTemplate template = new RedisTemplate<>();
+ template.setConnectionFactory(connectionFactory);
+
+ // 设置 Key 和 Value 的序列化方式为 String
+ template.setKeySerializer(new StringRedisSerializer());
+ template.setValueSerializer(new StringRedisSerializer());
+
+ // 设置 Hash Key 和 Hash Value 的序列化方式为 String
+ template.setHashKeySerializer(new StringRedisSerializer());
+ template.setHashValueSerializer(new StringRedisSerializer());
+
+ template.afterPropertiesSet();
+ return template;
+ }
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/configuration/constantConfiguration.java b/src/main/java/com/xubx/springboot_01demo/configuration/constantConfiguration.java
index eebd57a..0aeea28 100644
--- a/src/main/java/com/xubx/springboot_01demo/configuration/constantConfiguration.java
+++ b/src/main/java/com/xubx/springboot_01demo/configuration/constantConfiguration.java
@@ -13,4 +13,47 @@ public class constantConfiguration {
public static final int Offline = 0;
//用户在线
public static final int Online = 1;
+ // 博客点赞数
+ public static final String BLOG_LIKE_COUNT = "blog:likeCount:";
+ // 用户的总被点赞数
+ public static final String USER_TOTAL_LIKE_COUNT = "user:totalLikeCount:";
+ // 博客点赞用户集合
+ public static final String BLOG_LIKE_SET = "blog:likeUsers:";
+ // 博客点赞用户哈希
+ public static final String BLOG_LIKE_HASH = "blog:likeHash:";
+ public static final String BLOG_LIKE_COUNT_SYNC_LOCK = "blog:likeCountSyncLock:";
+ public static final String BLOG_LIKE_USERHASH_SYNC_LOCK = "blog:likeUserHashSyncLock:";
+
+ // 博客浏览数
+ public static final String BLOG_VIEW_COUNT = "blog:viewCount:";
+ // 博客浏览用户集合
+ public static final String BLOG_VIEW_SET = "blog:viewUsers:";
+ public static final String BLOG_VIEW_COUNT_SYNC_LOCK = "blog:viewCountSyncLock:";
+
+ //用户的总访问量
+ public static final String USER_TOTAL_VIEW_COUNT = "user:totalViewCount:";
+ //用户的博客总数量
+ public static final String USER_TOTAL_BLOG_COUNT = "user:totalBlogCount:";
+
+ // 博客评论数
+ public static final String BLOG_COMMENT_COUNT = "blog:commentCount:";
+ // 用户的总被评论数
+ public static final String USER_TOTAL_COMMENT_COUNT = "user:totalCommentCount:";
+
+ // 博客收藏数
+ public static final String BLOG_COLLECT_COUNT = "blog:collectCount:";
+ // 用户的总被收藏数
+ public static final String USER_TOTAL_COLLECT_COUNT = "user:totalCollectCount:";
+ // 博客收藏用户集合
+ public static final String BLOG_COLLECT_SET = "blog:collectUsers:";
+ public static final String BLOG_COLLECT_HASH = "blog:collectHash:";
+ public static final String BLOG_COLLECT_LOCK = "blog:collectLock:";
+ public static final String BLOG_COLLECT_COUNT_SYNC_LOCK = "blog:collectCountSyncLock:";
+ public static final String BLOG_COLLECT_USERHASH_SYNC_LOCK = "blog:collectUserHashSyncLock:";
+
+ //用户的总被分享数
+ public static final String USER_TOTAL_SHARE_COUNT = "user:totalShareCount:";
+
+ // 用户的总粉丝数量
+ public static final String USER_TOTAL_FOLLOWER_COUNT = "user:totalFollowerCount:";
}
diff --git a/src/main/java/com/xubx/springboot_01demo/controller/BlogsController.java b/src/main/java/com/xubx/springboot_01demo/controller/BlogsController.java
index 07e69fa..08825f6 100644
--- a/src/main/java/com/xubx/springboot_01demo/controller/BlogsController.java
+++ b/src/main/java/com/xubx/springboot_01demo/controller/BlogsController.java
@@ -1,15 +1,17 @@
package com.xubx.springboot_01demo.controller;
import com.alibaba.fastjson.JSONObject;
-import com.xubx.springboot_01demo.dto.blog.addBlogDto;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.xubx.springboot_01demo.dto.blog.AddBlogDto;
+import com.xubx.springboot_01demo.dto.blog.CollectBlogDto;
+import com.xubx.springboot_01demo.dto.blog.GetUserBlogsDto;
+import com.xubx.springboot_01demo.dto.user.NewFavoritesDto;
import com.xubx.springboot_01demo.pojo.Blogs;
import com.xubx.springboot_01demo.service.BlogService;
-import com.xubx.springboot_01demo.utils.api.Result;
+import com.xubx.springboot_01demo.vo.GetBlogDetailVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
@@ -41,20 +43,84 @@ public class BlogsController {
/**
* 获取博客详情
*
- * @param id
+ * @param blogId
* @return
*/
@GetMapping("/getBlogDetail")
@ApiOperation("获取博客详情")
- public ResponseEntity getBlogDetail(@RequestParam("blogId") int id) {
- log.info("获取博客详情,ID: {}", id);
- Blogs blog = blogService.findByIdBlogs(id);
- if (blog == null) {
- return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
+ public ResponseEntity> getBlogDetail(@RequestParam("blogId") int blogId) {
+ log.info("获取博客详情,ID: {}", blogId);
+ GetBlogDetailVo getBlogDetailVo = blogService.findByIdBlogs(blogId);
+
+ if (getBlogDetailVo == null) {
+ return ResponseEntity.status(HttpStatus.NOT_FOUND).body("博客不存在");
}
- return ResponseEntity.ok(blog);
+ return ResponseEntity.ok(getBlogDetailVo);
}
+ /**
+ * 浏览博客,增加阅读数
+ *
+ * @param blogId
+ * @return {@link ResponseEntity }<{@link String }>
+ */
+ @GetMapping("/viewBlog")
+ @ApiOperation("浏览博客")
+ public ResponseEntity viewBlog(@RequestParam("blogId") int blogId) {
+ log.info("浏览博客,ID: {}", blogId);
+
+ try {
+ blogService.viewBlog(blogId);
+ return ResponseEntity.ok("博客浏览成功");
+ } catch (Exception e) {
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("博客浏览失败");
+ }
+ }
+
+ /**
+ * 当前用户点赞博客
+ *
+ * @param blogId
+ * @return {@link ResponseEntity }<{@link String }>
+ */
+ @GetMapping("/likeBlog")
+ @ApiOperation("点赞博客")
+ public ResponseEntity likeBlog(@RequestParam("blogId") int blogId) {
+ log.info("点赞博客,ID: {}", blogId);
+
+ try {
+ blogService.likeBlog(blogId);
+ return ResponseEntity.ok("接口调用成功");
+ } catch (Exception e) {
+ log.error("博客点赞失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("博客点赞失败");
+ }
+ }
+
+ /**
+ * 收藏博客
+ * @param collectBlogDto
+ * @return {@link ResponseEntity }<{@link String }>
+ */
+ @PostMapping("/collectBlog")
+ @ApiOperation("收藏博客")
+ public ResponseEntity collectBlog(@Valid @RequestBody CollectBlogDto collectBlogDto, BindingResult bindingResult) {
+ log.info("收藏博客,ID: {}", collectBlogDto);
+
+ if (bindingResult.hasErrors()) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(bindingResult.getFieldError().getDefaultMessage());
+ }
+
+ try {
+ blogService.collectBlog(collectBlogDto);
+ return ResponseEntity.ok("接口调用成功");
+ } catch (Exception e) {
+ log.error("博客收藏失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("博客收藏失败");
+ }
+ }
+
+
/**
* 新增博客
*
@@ -62,7 +128,7 @@ public class BlogsController {
*/
@PostMapping("/addBlog")
@ApiOperation("新增博客")
- public ResponseEntity addBlog(@Valid @RequestBody addBlogDto blogs, BindingResult bindingResult) {
+ public ResponseEntity addBlog(@Valid @RequestBody AddBlogDto blogs, BindingResult bindingResult) {
log.info("新增博客入参:{}", JSONObject.toJSONString(blogs));
if (bindingResult.hasErrors()) {
@@ -101,5 +167,22 @@ public class BlogsController {
return ResponseEntity.ok("博客删除成功");
}
+ @PostMapping("/getUserBlogs")
+ @ApiOperation("获取用户博客")
+ public ResponseEntity> getUserBlogs(@Valid @RequestBody GetUserBlogsDto getUserBlogsDto, BindingResult bindingResult) {
+ log.info("获取用户博客,{}", getUserBlogsDto);
+
+ if (bindingResult.hasErrors()) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
+ }
+
+ try {
+ Page blogs = blogService.findBlogsByUserId(getUserBlogsDto);
+ return ResponseEntity.ok(blogs);
+ } catch (Exception e) {
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
+ }
+ }
+
}
diff --git a/src/main/java/com/xubx/springboot_01demo/controller/MessagesController.java b/src/main/java/com/xubx/springboot_01demo/controller/MessagesController.java
index aa7e75f..0694a82 100644
--- a/src/main/java/com/xubx/springboot_01demo/controller/MessagesController.java
+++ b/src/main/java/com/xubx/springboot_01demo/controller/MessagesController.java
@@ -29,7 +29,7 @@ public class MessagesController {
@PostMapping("/sendMessages")
public ResponseEntity> sendMessages(@RequestBody SendMesDto sendMesDto) {
try {
- sendMesDto.setSender(RequestHolder.getuserId());
+// sendMesDto.setSender(RequestHolder.getuserId());
messagesService.sendMessages(sendMesDto);
Result result = new Result<>();
result.setCode(200);
@@ -43,9 +43,9 @@ public class MessagesController {
}
}
- @GetMapping("/getMessages")
- public Result> getMessages(@RequestParam("recipient") String recipient) {
- List messages = messagesService.getMessages(RequestHolder.getuserId(), recipient);
- return Result.ok("查询成功", messages);
- }
+// @GetMapping("/getMessages")
+// public Result> getMessages(@RequestParam("recipient") String recipient) {
+//// List messages = messagesService.getMessages(RequestHolder.getuserId(), recipient);
+//// return Result.ok("查询成功", messages);
+// }
}
diff --git a/src/main/java/com/xubx/springboot_01demo/controller/RelationshipController.java b/src/main/java/com/xubx/springboot_01demo/controller/RelationshipController.java
index a81c098..379efde 100644
--- a/src/main/java/com/xubx/springboot_01demo/controller/RelationshipController.java
+++ b/src/main/java/com/xubx/springboot_01demo/controller/RelationshipController.java
@@ -46,7 +46,7 @@ public class RelationshipController {
@ApiOperation("发送添加请求")
@GetMapping("/addRequest")
public ResponseEntity> requestFriend(@RequestParam("username") String username){
- String userId = RequestHolder.getuserId();
+ String userId = RequestHolder.getuserId().toString();
try {
relationshipService.requestFriend(userId, username);
// 成功返回
@@ -118,21 +118,21 @@ public class RelationshipController {
*
* @param relationshipDto
*/
- @ApiOperation("删除好友")
- @PostMapping("/removeFriend")
- public void removeFriend(@RequestBody RelationshipDto relationshipDto) {
- relationshipService.removeFriend(RequestHolder.getuserId(), relationshipDto.getFriend());
- }
-
- /**
- * 获取好友列表
- * @return
- */
- @ApiOperation("获取好友列表")
- @GetMapping("/getFriends")
- public List getFriends() {
- return relationshipService.getFriends(RequestHolder.getuserId());
- }
+// @ApiOperation("删除好友")
+// @PostMapping("/removeFriend")
+// public void removeFriend(@RequestBody RelationshipDto relationshipDto) {
+// relationshipService.removeFriend(RequestHolder.getuserId(), relationshipDto.getFriend());
+// }
+//
+// /**
+// * 获取好友列表
+// * @return
+// */
+// @ApiOperation("获取好友列表")
+// @GetMapping("/getFriends")
+// public List getFriends() {
+// return relationshipService.getFriends(RequestHolder.getuserId());
+// }
}
diff --git a/src/main/java/com/xubx/springboot_01demo/controller/UserController.java b/src/main/java/com/xubx/springboot_01demo/controller/UserController.java
index 4ac8313..96be57e 100644
--- a/src/main/java/com/xubx/springboot_01demo/controller/UserController.java
+++ b/src/main/java/com/xubx/springboot_01demo/controller/UserController.java
@@ -2,22 +2,30 @@ package com.xubx.springboot_01demo.controller;
import com.alibaba.fastjson.JSONObject;
+import com.xubx.springboot_01demo.dto.user.EditMaterialDto;
+import com.xubx.springboot_01demo.dto.user.NewFavoritesDto;
+import com.xubx.springboot_01demo.pojo.Blogs;
import com.xubx.springboot_01demo.pojo.User;
+import com.xubx.springboot_01demo.pojo.UserFavorite;
import com.xubx.springboot_01demo.service.UserService;
import com.xubx.springboot_01demo.utils.token.RequestHolder;
import com.xubx.springboot_01demo.utils.token.TokenGenerate;
+import com.xubx.springboot_01demo.vo.getUserInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
+import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
+import java.util.List;
@RestController //注解标识这是一个控制器类
@CrossOrigin //加上CrossOrigin可解决跨域问题
@@ -28,8 +36,6 @@ public class UserController {
@Resource
UserService userService;
// 注入session
- @Resource
- private HttpSession session;
/**
* 用户注册
@@ -67,16 +73,17 @@ public class UserController {
*/
@PostMapping("/login")
@ApiOperation("用户登录")
- public String login(@RequestBody User user) {
- log.info("用户登录:{}", user.getUsername());
- //登陆
- if (userService.findUserByUsername(user)) {
- String token = new TokenGenerate().generateToken(user.getUsername());
- //将username存入session
- session.setAttribute("username", user.getUsername());
- return token;
+ public ResponseEntity login(@RequestBody User user) {
+ log.info("用户登录:{}", user);
+
+ // 调用 Service 中的登录方法
+ String token = userService.login(user);
+
+ if (token != null) {
+ return ResponseEntity.ok(token);
+ } else {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("登录失败,用户名或密码错误");
}
- return "false";
}
/**
@@ -85,9 +92,9 @@ public class UserController {
* @return
*/
@GetMapping("/getUsername")
- @ApiOperation("获取用户名")
+ @ApiOperation("获取当前用户名")
public String getUserName() {
- return RequestHolder.getuserId();
+ return userService.getUser("").getUsername();
}
/**
@@ -95,22 +102,22 @@ public class UserController {
*
* @return
*/
- @RequestMapping("/uploadAvatar")
- @ApiOperation("上传头像")
- public void uploadAvatar(MultipartFile file) throws IOException {
- String pType = file.getContentType();
- pType = pType.substring(pType.indexOf("/") + 1);
- if ("jpeg".equals(pType)) {
- pType = "jpg";
- }
- long time = System.currentTimeMillis();
- String currentWorkingDirectory = System.getProperty("user.dir");
- String relativePath = "/images/avatar/" + time + "." + pType;
- String absolutePath = currentWorkingDirectory + "/static" + relativePath;
- file.transferTo(new File(absolutePath));
- System.out.println("导入数据库的路径:" + relativePath + "当前用户:" + RequestHolder.getuserId());
- userService.addAvatar(relativePath, RequestHolder.getuserId());
- }
+// @RequestMapping("/uploadAvatar")
+// @ApiOperation("上传头像")
+// public void uploadAvatar(MultipartFile file) throws IOException {
+// String pType = file.getContentType();
+// pType = pType.substring(pType.indexOf("/") + 1);
+// if ("jpeg".equals(pType)) {
+// pType = "jpg";
+// }
+// long time = System.currentTimeMillis();
+// String currentWorkingDirectory = System.getProperty("user.dir");
+// String relativePath = "/images/avatar/" + time + "." + pType;
+// String absolutePath = currentWorkingDirectory + "/static" + relativePath;
+// file.transferTo(new File(absolutePath));
+// System.out.println("导入数据库的路径:" + relativePath + "当前用户Id:" + RequestHolder.getuserId());
+// userService.addAvatar(relativePath, RequestHolder.getuserId());
+// }
/**
* 获取头像
@@ -120,9 +127,7 @@ public class UserController {
@GetMapping("/getAvatar")
@ApiOperation("获取头像")
public String getAvatar() {
- String path = userService.getAvatar(RequestHolder.getuserId());
- System.out.println("发给前端的路径:" + path);
- return path;
+ return userService.getUser("").getAvatar();
}
/**
@@ -134,11 +139,14 @@ public class UserController {
@GetMapping("usernameChange")
@ApiOperation("修改用户名")
public ResponseEntity usernameChange(@RequestParam("username") String username) {
- if (userService.usernameChange(RequestHolder.getuserId(), username)) {
- RequestHolder.add(username);
+ log.info("修改用户名:{}", username);
+
+ try {
+ userService.usernameChange(username);
return ResponseEntity.ok("修改成功!");
+ } catch (Exception e) {
+ return ResponseEntity.ok("修改失败!");
}
- return ResponseEntity.ok("该用户已存在!");
}
/**
@@ -148,22 +156,119 @@ public class UserController {
* @param newPassword
* @return
*/
- @GetMapping("passwordChange")
- @ApiOperation("修改密码")
- public ResponseEntity passwordChange(@RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword) {
- if (userService.passwordChange(RequestHolder.getuserId(), oldPassword, newPassword)) {
- return ResponseEntity.ok("修改成功!");
+// @GetMapping("passwordChange")
+// @ApiOperation("修改密码")
+// public ResponseEntity passwordChange(@RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword) {
+// if (userService.passwordChange(RequestHolder.getuserId(), oldPassword, newPassword)) {
+// return ResponseEntity.ok("修改成功!");
+// }
+// return ResponseEntity.ok("原密码输入错误!");
+// }
+//
+// /**
+// * 查看是否有好友请求
+// *
+// * @return
+// */
+// @GetMapping("/checkFriendRequest")
+// public JSONObject haveFriendRequest() {
+// return userService.checkFriendRequest(RequestHolder.getuserId());
+// }
+
+ /**
+ * 获取用户信息
+ *
+ * @return {@link ResponseEntity }<{@link getUserInfoVo }>
+ */
+ @GetMapping("/getUserInfo")
+ @ApiOperation("获取用户信息")
+ public ResponseEntity getUserInfo(@RequestParam("userId") String userId) {
+ log.info("获取用户信息:{}", userId);
+
+ try {
+ return ResponseEntity.ok(userService.getUserInfo(userId));
+ } catch (Exception e) {
+ log.info("获取用户信息失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
+ }
+ }
+
+ @PostMapping("/editMaterial")
+ @ApiOperation("修改用户资料")
+ public ResponseEntity editMaterial(@RequestBody EditMaterialDto editMaterialDto) {
+ log.info("修改用户资料");
+ try {
+ userService.editMaterial(editMaterialDto);
+ return ResponseEntity.ok("修改成功!");
+ } catch (Exception e) {
+ return ResponseEntity.ok("修改失败!");
}
- return ResponseEntity.ok("原密码输入错误!");
}
/**
- * 查看是否有好友请求
+ * 新建收藏夹
*
- * @return
+ * @param newFavorites
+ * @return {@link ResponseEntity }<{@link String }>
*/
- @GetMapping("/checkFriendRequest")
- public JSONObject haveFriendRequest() {
- return userService.checkFriendRequest(RequestHolder.getuserId());
+ @PostMapping("/newFavorites")
+ @ApiOperation("新建收藏夹")
+ public ResponseEntity newFavorites(@Valid @RequestBody NewFavoritesDto newFavorites, BindingResult bindingResult) {
+ log.info("新建收藏夹,入参:{}", JSONObject.toJSONString(newFavorites));
+
+ if (bindingResult.hasErrors()) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(bindingResult.getFieldError().getDefaultMessage());
+ }
+
+ Integer userId = RequestHolder.getuserId();
+ if (userId == null) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户未登录");
+ }
+
+ try {
+ String result = userService.newFavorites(newFavorites);
+ if (result != null) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
+ }
+ return ResponseEntity.ok("收藏夹创建成功");
+ } catch (Exception e) {
+ log.error("新建收藏夹失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("新建收藏夹失败");
+ }
+ }
+
+ /**
+ * 获取用户收藏夹列表
+ * @return {@link ResponseEntity }<{@link List }<{@link UserFavorite }>>
+ */
+ @GetMapping("/getFavorites")
+ @ApiOperation("获取收藏夹列表")
+ public ResponseEntity> getUserFavorites(@RequestParam("userId") String userId) {
+ log.info("获取收藏夹列表");
+
+ try {
+ return ResponseEntity.ok(userService.getUserFavorites(userId));
+ } catch (Exception e) {
+ log.error("获取收藏夹列表失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
+ }
+ }
+
+ /**
+ * 获取收藏夹内的博客
+ * @param favoriteId
+ * @return {@link ResponseEntity }<{@link List }<{@link Blogs }>>
+ */
+ @GetMapping("/getBlogsByFavoriteId")
+ @ApiOperation("根据收藏夹id获取收藏夹内的博客")
+ public ResponseEntity> getBlogsByFavoriteId(@RequestParam("favoriteId") String favoriteId) {
+ log.info("根据收藏夹id获取收藏夹内的博客: {}", favoriteId);
+
+ try {
+ return ResponseEntity.ok(userService.getBlogsByFavoriteId(favoriteId));
+ } catch (Exception e) {
+ log.error("根据收藏夹id获取收藏夹内的博客失败", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("根据收藏夹id获取收藏夹内的博客失败");
+ }
}
}
diff --git a/src/main/java/com/xubx/springboot_01demo/dto/blog/addBlogDto.java b/src/main/java/com/xubx/springboot_01demo/dto/blog/AddBlogDto.java
similarity index 94%
rename from src/main/java/com/xubx/springboot_01demo/dto/blog/addBlogDto.java
rename to src/main/java/com/xubx/springboot_01demo/dto/blog/AddBlogDto.java
index 2119a6e..4f8a772 100644
--- a/src/main/java/com/xubx/springboot_01demo/dto/blog/addBlogDto.java
+++ b/src/main/java/com/xubx/springboot_01demo/dto/blog/AddBlogDto.java
@@ -12,7 +12,7 @@ import javax.validation.constraints.NotBlank;
* @date 2024/11/01
*/
@Data
-public class addBlogDto {
+public class AddBlogDto {
@NotBlank
private String title;
diff --git a/src/main/java/com/xubx/springboot_01demo/dto/blog/CollectBlogDto.java b/src/main/java/com/xubx/springboot_01demo/dto/blog/CollectBlogDto.java
new file mode 100644
index 0000000..783af19
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/dto/blog/CollectBlogDto.java
@@ -0,0 +1,19 @@
+package com.xubx.springboot_01demo.dto.blog;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 收藏博客入参
+ * @author Xubx
+ * @date 2024/11/03
+ */
+@Data
+public class CollectBlogDto {
+ @NotBlank
+ private Integer blogId;
+
+ @NotBlank
+ private Integer favoriteId;
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/dto/blog/GetUserBlogsDto.java b/src/main/java/com/xubx/springboot_01demo/dto/blog/GetUserBlogsDto.java
new file mode 100644
index 0000000..0c31398
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/dto/blog/GetUserBlogsDto.java
@@ -0,0 +1,23 @@
+package com.xubx.springboot_01demo.dto.blog;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 获取用户博客入参
+ * @author Xubx
+ * @date 2024/11/03
+ */
+@Data
+public class GetUserBlogsDto {
+ @NotBlank
+ private String userId;
+
+ @NotBlank
+ private int page;
+
+ @NotBlank
+ private int pageSize;
+
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/dto/user/EditMaterialDto.java b/src/main/java/com/xubx/springboot_01demo/dto/user/EditMaterialDto.java
new file mode 100644
index 0000000..d0fbb6a
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/dto/user/EditMaterialDto.java
@@ -0,0 +1,20 @@
+package com.xubx.springboot_01demo.dto.user;
+
+import lombok.Data;
+
+/**
+ * 修改用户资料入参
+ * @author Xubx
+ * @date 2024/11/02
+ */
+@Data
+public class EditMaterialDto {
+ private String username;
+
+ private String avatar;
+
+ private String gender;
+
+ private String bio;
+
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/dto/user/NewFavoritesDto.java b/src/main/java/com/xubx/springboot_01demo/dto/user/NewFavoritesDto.java
new file mode 100644
index 0000000..081fa06
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/dto/user/NewFavoritesDto.java
@@ -0,0 +1,26 @@
+package com.xubx.springboot_01demo.dto.user;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 新建收藏夹入参
+ * @author Xubx
+ * @date 2024/11/03
+ */
+@Data
+@ApiModel("新建收藏夹入参")
+public class NewFavoritesDto {
+ @NotBlank
+ @ApiModelProperty("收藏夹名称")
+ private String name;
+
+ @ApiModelProperty("收藏夹描述")
+ private String description;
+
+ @ApiModelProperty("收藏夹状态:默认是0 公开,1 私密")
+ private Integer favoriteStatus;
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/BlogLikeMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/BlogLikeMapper.java
new file mode 100644
index 0000000..0521238
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/BlogLikeMapper.java
@@ -0,0 +1,7 @@
+package com.xubx.springboot_01demo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xubx.springboot_01demo.pojo.BlogLike;
+
+public interface BlogLikeMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/BlogsMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/BlogsMapper.java
index 479a46e..c5d5991 100644
--- a/src/main/java/com/xubx/springboot_01demo/mapper/BlogsMapper.java
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/BlogsMapper.java
@@ -1,7 +1,8 @@
package com.xubx.springboot_01demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.xubx.springboot_01demo.dto.blog.addBlogDto;
+import com.xubx.springboot_01demo.dto.blog.AddBlogDto;
+import com.xubx.springboot_01demo.dto.blog.CollectBlogDto;
import com.xubx.springboot_01demo.pojo.Blogs;
import java.util.List;
@@ -12,7 +13,7 @@ public interface BlogsMapper extends BaseMapper {
//根据id获取博客
Blogs findByIdBlogs(int id);
//新增博客
- void addBlogs(addBlogDto blogs);
+ void addBlogs(AddBlogDto blogs);
//更新博客
void updateBlogs(Blogs blogs);
//删除博客
@@ -24,4 +25,105 @@ public interface BlogsMapper extends BaseMapper {
* @param categoryId
*/
void insertCategory(int blogId, String categoryId);
+
+ /**
+ * 获取该用户总访问量
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalViewCount(Integer userId);
+
+ /**
+ * 获取该用户总博客数
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalBlogCount(Integer userId);
+
+ /**
+ * 获取该用户被收藏总数
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalCollectCount(Integer userId);
+
+ /**
+ * 获取该用户被点赞总数
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalLikeCount(Integer userId);
+
+ /**
+ * 获取该用户被评论总数
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalCommentCount(Integer userId);
+
+ /**
+ * 获取该用户被分享总数
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalShareCount(Integer userId);
+
+ /**
+ * 获取某个博客的该用户的点赞状态
+ * @param blogId
+ * @param userId
+ * @return {@link Integer }
+ */
+ Integer getLikeStatus(int blogId, Integer userId);
+
+ /**
+ * 获取某个博客的该用户的收藏状态
+ * @param blogId
+ * @param userId
+ * @return {@link Integer }
+ */
+ Integer getCollectStatus(int blogId, Integer userId);
+
+ /**
+ * 获取某个博客的点赞数
+ * @param blogId
+ * @return {@link Integer }
+ */
+ String getLikeCount(int blogId);
+
+ /**
+ * 获取某个博客的浏览数
+ * @param blogId
+ * @return {@link Object }
+ */
+ String getViewCount(int blogId);
+
+ /**
+ * 获取某个博客的收藏数
+ * @param blogId
+ * @return {@link Object }
+ */
+ String getCollectCount(int blogId);
+
+ /**
+ * 获取某个博客的评论数
+ * @param blogId
+ * @return {@link Object }
+ */
+ String getCommentCount(int blogId);
+
+ /**
+ * 当前用户进行博客的收藏
+ * @param collectBlogDto
+ */
+ void collectBlog(CollectBlogDto collectBlogDto);
+
+ List getBlogsByFavoriteId(String favoriteId);
+
+ /**
+ * 获取该博客的所有点赞用户id
+ * @param blogId
+ * @return {@link List }<{@link String }>
+ */
+ List getUserIdsByBlogId(String blogId);
}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/RelationshipMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/RelationshipMapper.java
index c59d761..617d7c2 100644
--- a/src/main/java/com/xubx/springboot_01demo/mapper/RelationshipMapper.java
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/RelationshipMapper.java
@@ -1,12 +1,13 @@
package com.xubx.springboot_01demo.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xubx.springboot_01demo.pojo.Relationship;
import com.xubx.springboot_01demo.pojo.User;
import com.xubx.springboot_01demo.vo.UserListVo;
import java.util.List;
-public interface RelationshipMapper {
+public interface RelationshipMapper extends BaseMapper {
//1. 查询用户接口
List findUserByUsername(String currentName,String username);
//2.添加用户接口
@@ -19,4 +20,11 @@ public interface RelationshipMapper {
List getFriends(String username);
//6.查看是否有好友请求
List checkFriendRequest(String getuserId);
+
+ /**
+ * 获取粉丝数量
+ * @param userId
+ * @return {@link Integer }
+ */
+ String getTotalFollowerCount(Integer userId);
}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteBlogMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteBlogMapper.java
new file mode 100644
index 0000000..c83a651
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteBlogMapper.java
@@ -0,0 +1,7 @@
+package com.xubx.springboot_01demo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xubx.springboot_01demo.pojo.UserFavoriteBlog;
+
+public interface UserFavoriteBlogMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteMapper.java
new file mode 100644
index 0000000..21ed479
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/UserFavoriteMapper.java
@@ -0,0 +1,7 @@
+package com.xubx.springboot_01demo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xubx.springboot_01demo.pojo.UserFavorite;
+
+public interface UserFavoriteMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/mapper/UserMapper.java b/src/main/java/com/xubx/springboot_01demo/mapper/UserMapper.java
index 332c28f..75f280d 100644
--- a/src/main/java/com/xubx/springboot_01demo/mapper/UserMapper.java
+++ b/src/main/java/com/xubx/springboot_01demo/mapper/UserMapper.java
@@ -1,10 +1,9 @@
package com.xubx.springboot_01demo.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xubx.springboot_01demo.pojo.User;
-public interface UserMapper {
- //1. 查询用户接口
- User findUserByUsername(String username);
+public interface UserMapper extends BaseMapper {
//2.添加用户接口
void insertUser(User user);
//3.添加头像接口
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/BlogLike.java b/src/main/java/com/xubx/springboot_01demo/pojo/BlogLike.java
new file mode 100644
index 0000000..8937f3a
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/BlogLike.java
@@ -0,0 +1,24 @@
+package com.xubx.springboot_01demo.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+@Data
+@TableName("blog_like")
+public class BlogLike {
+ @TableField("id")
+ private int id;
+
+ @TableField("blog_id")
+ private Integer blogId;
+
+ @TableField("user_id")
+ private Integer userId;
+
+ @TableField("created_time")
+ private Timestamp createdTime;
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/Blogs.java b/src/main/java/com/xubx/springboot_01demo/pojo/Blogs.java
index 9ffe3d3..402bc64 100644
--- a/src/main/java/com/xubx/springboot_01demo/pojo/Blogs.java
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/Blogs.java
@@ -25,7 +25,7 @@ public class Blogs implements Serializable {
*/
@ApiModelProperty(value = "id")
@TableId(type = IdType.AUTO)
- private int id;
+ private Integer id;
@ApiModelProperty(value = "标题")
private String title;
@@ -40,7 +40,7 @@ public class Blogs implements Serializable {
private String coverImage;
@ApiModelProperty(value = "作者id")
- private String authorId;
+ private Integer authorId;
@ApiModelProperty(value = "点赞数")
private int likeCount;
@@ -48,8 +48,11 @@ public class Blogs implements Serializable {
@ApiModelProperty(value = "浏览数")
private int viewCount;
+ @ApiModelProperty(value = "评论数")
+ private int commentCount;
+
@ApiModelProperty(value = "收藏数")
- private int favoriteCount;
+ private int collectCount;
@ApiModelProperty(value = "分享数")
private int shareCount;
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/Relationship.java b/src/main/java/com/xubx/springboot_01demo/pojo/Relationship.java
index 8db42ad..e915a8e 100644
--- a/src/main/java/com/xubx/springboot_01demo/pojo/Relationship.java
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/Relationship.java
@@ -3,7 +3,7 @@ package com.xubx.springboot_01demo.pojo;
import java.sql.Timestamp;
public class Relationship {
- private int id;
+ private Integer id;
/**用户名*/
private String username;
/**好友*/
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/User.java b/src/main/java/com/xubx/springboot_01demo/pojo/User.java
index efb9ada..42c0f1f 100644
--- a/src/main/java/com/xubx/springboot_01demo/pojo/User.java
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/User.java
@@ -2,70 +2,52 @@ package com.xubx.springboot_01demo.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
import java.io.Serializable;
+import java.sql.Timestamp;
/**
* 用户实体类
*/
+@Data
+@ApiModel
+@TableName("user")
public class User implements Serializable {
- private int id;
- /** 用户名*/
+ private Integer id;
+
+ @ApiModelProperty(value = "用户名")
private String username;
- /** 密码*/
+
+ @ApiModelProperty(value = "密码")
private String password;
- /** 头像*/
+
+ @ApiModelProperty(value = "头像")
+ @TableField("avatar")
private String avatar;
- /** 用户状态*/
- private int state;
- @Override
- public String toString() {
- return "User{" +
- "username='" + username + '\'' +
- ", password='" + password + '\'' +
- ", avatar='" + avatar + '\'' +
- ", state=" + state +
- '}';
- }
+ @ApiModelProperty(value = "用户状态")
+ private int status;
- public int getId() {
- return id;
- }
+ @ApiModelProperty(value = "用户邮箱")
+ private String email;
- public void setId(int id) {
- this.id = id;
- }
+ @ApiModelProperty(value = "用户性别")
+ private String gender;
- public String getUsername() {
- return username;
- }
+ @ApiModelProperty(value = "个人简介")
+ @TableField("bio")
+ private String bio;
- public void setUsername(String username) {
- this.username = username;
- }
+ @ApiModelProperty(value = "创建时间")
+ @TableField("created_time")
+ private Timestamp createdTime;
- public String getPassword() {
- return password;
- }
+ @ApiModelProperty(value = "更新时间")
+ @TableField("updated_time")
+ private Timestamp updateTime;
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getAvatar() {
- return avatar;
- }
-
- public void setAvatar(String avatar) {
- this.avatar = avatar;
- }
-
- public int getState() {
- return state;
- }
-
- public void setState(int state) {
- this.state = state;
- }
}
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/UserFavorite.java b/src/main/java/com/xubx/springboot_01demo/pojo/UserFavorite.java
new file mode 100644
index 0000000..9c7e588
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/UserFavorite.java
@@ -0,0 +1,41 @@
+package com.xubx.springboot_01demo.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+@Data
+@ApiModel(value = "UserFavorite", description = "用户收藏")
+@TableName("user_favorite")
+public class UserFavorite implements Serializable {
+ private int id;
+
+ @TableField("name")
+ @ApiModelProperty(value = "收藏名称")
+ private String name;
+
+ @TableField("description")
+ @ApiModelProperty(value = "收藏描述")
+ private String description;
+
+ @TableField("blog_count")
+ @ApiModelProperty(value = "收藏夹内博客数量")
+ private Integer blogCount;
+
+ @TableField("user_id")
+ @ApiModelProperty(value = "用户id")
+ private Integer userId;
+
+ @TableField("favorite_status")
+ @ApiModelProperty(value = "收藏状态: 默认是公开,可选私密")
+ private String favoriteStatus;
+
+ @TableField("created_time")
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createdTime;
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/pojo/UserFavoriteBlog.java b/src/main/java/com/xubx/springboot_01demo/pojo/UserFavoriteBlog.java
new file mode 100644
index 0000000..4ad1ea5
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/pojo/UserFavoriteBlog.java
@@ -0,0 +1,20 @@
+package com.xubx.springboot_01demo.pojo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "UserFavorite", description = "用户收藏夹博客中间表")
+@TableName("user_favorite_blog")
+public class UserFavoriteBlog {
+ private int id;
+
+ @TableField("favorite_id")
+ private Integer favoriteId;
+
+ @TableField("blog_id")
+ private Integer blogId;
+
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/service/BlogService.java b/src/main/java/com/xubx/springboot_01demo/service/BlogService.java
index 00f84bd..2b56c2d 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/BlogService.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/BlogService.java
@@ -1,7 +1,13 @@
package com.xubx.springboot_01demo.service;
-import com.xubx.springboot_01demo.dto.blog.addBlogDto;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.xubx.springboot_01demo.dto.blog.AddBlogDto;
+import com.xubx.springboot_01demo.dto.blog.CollectBlogDto;
+import com.xubx.springboot_01demo.dto.blog.GetUserBlogsDto;
+import com.xubx.springboot_01demo.dto.user.NewFavoritesDto;
import com.xubx.springboot_01demo.pojo.Blogs;
+import com.xubx.springboot_01demo.vo.GetBlogDetailVo;
import java.util.List;
@@ -10,11 +16,20 @@ public interface BlogService {
List findAllBlogs();
//根据id获取博客
- Blogs findByIdBlogs(int id);
+ GetBlogDetailVo findByIdBlogs(int blogId);
//添加博客
- void addBlogs(addBlogDto blogs);
+ void addBlogs(AddBlogDto blogs);
//更新博客
void updateBlogs(Blogs blogs);
//删除博客
void deleteBlogs(int id);
+
+ Page findBlogsByUserId(GetUserBlogsDto getUserBlogsDto);
+
+ void viewBlog(int blogId);
+
+ void likeBlog(int blogId);
+
+ void collectBlog(CollectBlogDto collectBlogDto) throws JsonProcessingException;
+
}
diff --git a/src/main/java/com/xubx/springboot_01demo/service/UserService.java b/src/main/java/com/xubx/springboot_01demo/service/UserService.java
index fb9a095..e0b471a 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/UserService.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/UserService.java
@@ -1,25 +1,58 @@
package com.xubx.springboot_01demo.service;
import com.alibaba.fastjson.JSONObject;
-import com.xubx.springboot_01demo.pojo.Relationship;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.xubx.springboot_01demo.dto.user.EditMaterialDto;
+import com.xubx.springboot_01demo.dto.user.NewFavoritesDto;
+import com.xubx.springboot_01demo.pojo.Blogs;
import com.xubx.springboot_01demo.pojo.User;
-import com.xubx.springboot_01demo.utils.api.Result;
+import com.xubx.springboot_01demo.pojo.UserFavorite;
+import com.xubx.springboot_01demo.vo.getUserInfoVo;
import java.util.List;
public interface UserService {
//登陆判断
- Boolean findUserByUsername(User user);
+ String login(User user);
//新增用户
Boolean insertUser(User user);
//添加头像
- void addAvatar(String path,String username);
+ void addAvatar(String path,String userId);
//获取头像地址
String getAvatar(String name);
//5.修改用户名
- boolean usernameChange(String usernameNow,String username);
+ void usernameChange(String username);
//6.修改密码
boolean passwordChange(String username,String oldPassword,String newPassword);
JSONObject checkFriendRequest(String getuserId);
+
+ User getUser(String getUserId);
+
+ getUserInfoVo getUserInfo(String getuserId);
+
+ /**
+ *修改用户信息
+ */
+ void editMaterial(EditMaterialDto editMaterialDto);
+
+ /**
+ * 新建收藏夹
+ * @param newFavorites
+ */
+ String newFavorites(NewFavoritesDto newFavorites);
+
+ /**
+ * 获取用户的收藏夹
+ * @param userId
+ * @return {@link List }<{@link UserFavorite }>
+ */
+ List getUserFavorites(String userId);
+
+ /**
+ * 根据收藏夹id获取收藏夹中的博客
+ * @param favoriteId
+ * @return {@link List }<{@link Blogs }>
+ */
+ List getBlogsByFavoriteId(String favoriteId) throws JsonProcessingException;
}
diff --git a/src/main/java/com/xubx/springboot_01demo/service/impl/BlogsServiceImpl.java b/src/main/java/com/xubx/springboot_01demo/service/impl/BlogsServiceImpl.java
index dafd256..8d8c4ac 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/impl/BlogsServiceImpl.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/impl/BlogsServiceImpl.java
@@ -1,33 +1,155 @@
package com.xubx.springboot_01demo.service.impl;
-import com.xubx.springboot_01demo.dto.blog.addBlogDto;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.xubx.springboot_01demo.configuration.constantConfiguration;
+import com.xubx.springboot_01demo.dto.blog.AddBlogDto;
+import com.xubx.springboot_01demo.dto.blog.CollectBlogDto;
+import com.xubx.springboot_01demo.dto.blog.GetUserBlogsDto;
import com.xubx.springboot_01demo.mapper.BlogsMapper;
import com.xubx.springboot_01demo.pojo.Blogs;
+import com.xubx.springboot_01demo.pojo.User;
import com.xubx.springboot_01demo.service.BlogService;
+import com.xubx.springboot_01demo.service.UserService;
import com.xubx.springboot_01demo.utils.token.RequestHolder;
+import com.xubx.springboot_01demo.vo.GetBlogDetailVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
@Service
+@Slf4j
public class BlogsServiceImpl implements BlogService {
@Resource
BlogsMapper blogsMapper;
+
+ @Autowired
+ UserService userService;
+
+ @Resource
+ RedisTemplate redisTemplate;
+
@Override
public List findAllBlogs() {
return blogsMapper.findAllBlogs();
}
+ @Autowired
+ ObjectMapper objectMapper;
+
+
+ /**
+ * 获取博客的详情
+ *
+ * @param blogId
+ * @return {@link GetBlogDetailVo }
+ */
@Override
- public Blogs findByIdBlogs(int id) {
- return blogsMapper.findByIdBlogs(id);
+ public GetBlogDetailVo findByIdBlogs(int blogId) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(Blogs::getId, blogId);
+ Blogs blog = blogsMapper.selectOne(queryWrapper);
+
+ GetBlogDetailVo getBlogDetailVo = new GetBlogDetailVo();
+ getBlogDetailVo.setId(blog.getId());
+ getBlogDetailVo.setTitle(blog.getTitle());
+ getBlogDetailVo.setContent(blog.getContent());
+ getBlogDetailVo.setAuthorId(blog.getAuthorId());
+ getBlogDetailVo.setCreatedTime(blog.getCreatedTime());
+ getBlogDetailVo.setUpdatedTime(blog.getUpdatedTime());
+ // 获取动态计数信息:点赞数、浏览数、收藏数、评论数
+ //TODO 使用 Redis 分布式锁来确保只有一个线程能够从数据库中获取并更新缓存
+ getBlogDetailVo.setLikeCount(getCachedCount(constantConfiguration.BLOG_LIKE_COUNT + blogId, () -> blogsMapper.getLikeCount(blogId)));
+ getBlogDetailVo.setViewCount(getCachedCount(constantConfiguration.BLOG_VIEW_COUNT + blogId, () -> blogsMapper.getViewCount(blogId)));
+ getBlogDetailVo.setCollectCount(getCachedCount(constantConfiguration.BLOG_COLLECT_COUNT + blogId, () -> blogsMapper.getCollectCount(blogId)));
+ getBlogDetailVo.setCommentCount(getCachedCount(constantConfiguration.BLOG_COMMENT_COUNT + blogId, () -> blogsMapper.getCommentCount(blogId)));
+
+ // 获取动态信息的状态:点赞状态,收藏状态
+ getBlogDetailVo.setLikeStatus(getCachedSet(constantConfiguration.BLOG_LIKE_SET + blogId, () -> blogsMapper.getLikeStatus(blogId, RequestHolder.getuserId())));
+ getBlogDetailVo.setCollectStatus(getCachedSet(constantConfiguration.BLOG_COLLECT_SET + blogId, () -> blogsMapper.getCollectStatus(blogId, RequestHolder.getuserId())));
+ // 手动设置额外字段
+ User author = userService.getUser(String.valueOf(blog.getAuthorId()));
+ if (author != null) {
+ getBlogDetailVo.setAuthorName(author.getUsername());
+ getBlogDetailVo.setAvatar(author.getAvatar());
+ }
+
+ return getBlogDetailVo;
+ }
+
+ /**
+ * 检查是否有该博客的动态计数,若无,则从数据库中查询并更新redis,若有,则直接从redis中获取
+ *
+ * @param key
+ * @param dbQuery
+ * @return int
+ */
+ private String getCachedCount(String key, Supplier dbQuery) {
+ String countExpiredKey = key + ":expired"; //逻辑过期的key
+ // 尝试从 Redis 中获取计数
+ String count = (String) redisTemplate.opsForValue().get(key);
+
+ // 如果缓存中没有,则从数据库获取并写入缓存
+ if (count == null) {
+ count = dbQuery.get();
+ if (count != null) {
+ redisTemplate.opsForValue().set(key, count.toString());
+
+ // 如果逻辑过期标志不存在,则创建并设置为 23 小时,确保缓存到期前同步
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(countExpiredKey))) {
+ redisTemplate.opsForValue().set(countExpiredKey, "true", 23, TimeUnit.HOURS);
+ }
+ } else {
+ count = "0"; // 如果数据库也没有数据,返回默认值 0
+ }
+ }
+
+ return count;
+ }
+
+ /**
+ * 检查redis的set集合中是否存在该用户,若无,将当前用户的点赞状态更新至redis
+ *
+ * @param key
+ * @param dbQuery
+ * @return {@link Integer }
+ */
+ private Integer getCachedSet(String key, Supplier dbQuery) {
+ String userId = RequestHolder.getuserId().toString();
+ String blogId = key.split(":")[2];
+
+ // 首先检查 Redis 中是否存在该 key
+ Boolean keyExists = redisTemplate.hasKey(key);
+ if (Boolean.FALSE.equals(keyExists)) {
+ // 如果 Redis 中没有该 key,从数据库中获取点赞状态
+ Integer status = dbQuery.get();
+
+ // 获取该博客用户集合存入redis的set中
+ List userIds = blogsMapper.getUserIdsByBlogId(blogId);
+ if (userIds != null && !userIds.isEmpty()) {
+ redisTemplate.opsForSet().add(key, userIds.toArray());
+ }
+ return status;
+ } else {
+ // 如果 Redis 中存在 key,检查用户是否在 Set 中
+ Boolean exists = redisTemplate.opsForSet().isMember(key, userId);
+ return exists ? 1 : 0;
+ }
}
@Override
- public void addBlogs(addBlogDto blogDto) {
+ public void addBlogs(AddBlogDto blogDto) {
LocalDateTime now = LocalDateTime.now();
// 博客内容的插入
Blogs blog = new Blogs();
@@ -55,4 +177,182 @@ public class BlogsServiceImpl implements BlogService {
public void deleteBlogs(int id) {
blogsMapper.deleteBlogs(id);
}
+
+ /**
+ * 根据用户id查询博客
+ *
+ * @param getUserBlogsDto
+ * @return {@link List }<{@link Blogs }>
+ */
+ @Override
+ public Page findBlogsByUserId(GetUserBlogsDto getUserBlogsDto) {
+ User user = userService.getUser(getUserBlogsDto.getUserId());
+ Page pageRequest = new Page<>(getUserBlogsDto.getPage(), getUserBlogsDto.getPageSize());
+
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(Blogs::getAuthorId, user.getId())
+ .orderByDesc(Blogs::getCreatedTime);
+ return blogsMapper.selectPage(pageRequest, queryWrapper);
+
+ }
+
+ /**
+ * 浏览博客增加博客阅读数,查看redis中是否有该key,若无则从数据库中获取
+ *
+ * @param blogId
+ */
+ @Override
+ public void viewBlog(int blogId) {
+ String userId = RequestHolder.getuserId().toString(); // 获取当前用户 ID
+
+ // 定义 Redis 键
+ String viewUserKey = constantConfiguration.BLOG_VIEW_SET + blogId; // 存放访问用户的 Set,带1小时过期
+ String viewCountKey = constantConfiguration.BLOG_VIEW_COUNT + blogId; // 存放浏览数,带7天过期
+ String viewCountExpireKey = constantConfiguration.BLOG_VIEW_COUNT + blogId + ":expired";// 逻辑过期标志
+
+ // 检查用户是否在 1 小时内访问过该博客
+ Boolean isFirstView = redisTemplate.opsForSet().isMember(viewUserKey, userId);
+
+ if (isFirstView == null || !isFirstView) {
+ // 如果用户未访问或 Redis key 不存在,增加浏览数
+ redisTemplate.opsForSet().add(viewUserKey, userId);
+ redisTemplate.expire(viewUserKey, 1, TimeUnit.HOURS);
+
+ // 检查浏览数 key 是否存在
+ String currentViewCount = (String) redisTemplate.opsForValue().get(viewCountKey);
+ if (currentViewCount == null) {
+ // 如果 Redis 中浏览数 key 不存在,从数据库获取并缓存
+ currentViewCount = blogsMapper.getViewCount(blogId);
+ redisTemplate.opsForValue().set(viewCountKey, currentViewCount);
+
+ // 设置逻辑过期标志,确保缓存到期前会被同步到数据库
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(viewCountExpireKey))) {
+ redisTemplate.opsForValue().set(viewCountExpireKey, "true", 23, TimeUnit.HOURS);
+ }
+ }
+
+ redisTemplate.opsForValue().increment(viewCountKey);
+ // 如果逻辑过期标志尚未存在,则创建并设置过期时间
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(viewCountExpireKey))) {
+ redisTemplate.opsForValue().set(viewCountExpireKey, "true", 23, TimeUnit.HOURS);
+ }
+ }
+ }
+
+ /**
+ * 点赞博客增加博客点赞数
+ *
+ * @param blogId
+ */
+ @Override
+ public void likeBlog(int blogId) {
+ String userId = RequestHolder.getuserId().toString(); // 获取用户ID
+
+ if (userId == null) {
+ throw new IllegalStateException("用户未登录");
+ }
+ String likeUserKey = constantConfiguration.BLOG_LIKE_SET + blogId; // 用于存放点赞用户的 Set
+
+ String likeCountKey = constantConfiguration.BLOG_LIKE_COUNT + blogId; // 用于存放点赞数
+ String likeCountExpireKey = constantConfiguration.BLOG_LIKE_COUNT + blogId + ":expired"; // 逻辑过期标志
+ String likeUserHashKey = constantConfiguration.BLOG_LIKE_HASH + blogId;// 用于存放点赞用户信息的 Hash
+ String likeUserHashExpireKey = constantConfiguration.BLOG_LIKE_HASH + blogId + ":expired";
+
+ // 检查是否已点赞,并确保没有发生空指针异常
+ Boolean isFirstLike = redisTemplate.opsForSet().isMember(likeUserKey, userId);
+
+ if (isFirstLike == null || !isFirstLike) {
+ redisTemplate.opsForSet().add(likeUserKey, userId);
+ redisTemplate.opsForValue().increment(likeCountKey);
+ redisTemplate.opsForHash().put(likeUserHashKey, userId, "true");
+
+ // 设置过期时间仅在首次操作集合时
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(likeCountExpireKey))) {
+ redisTemplate.opsForValue().set(likeCountExpireKey, "true", 25, TimeUnit.HOURS);
+ }
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(likeUserHashExpireKey))) {
+ redisTemplate.opsForValue().set(likeUserHashExpireKey, "true", 25, TimeUnit.HOURS);
+ }
+ } else {
+ redisTemplate.opsForSet().remove(likeUserKey, userId);
+ redisTemplate.opsForValue().decrement(likeCountKey);
+ redisTemplate.opsForHash().put(likeUserHashKey, userId, "false");
+
+ // 设置逻辑过期标志,以确保下次同步到数据库
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(likeCountExpireKey))) {
+ redisTemplate.opsForValue().set(likeCountExpireKey, "true", 25, TimeUnit.HOURS);
+ }
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(likeUserHashExpireKey))) {
+ redisTemplate.opsForValue().set(likeUserHashExpireKey, "true", 25, TimeUnit.HOURS);
+ }
+ }
+ }
+
+ /**
+ * 收藏博客 增加博客收藏数 用户收藏夹 博客收藏中间表
+ *
+ * @param collectBlogDto
+ */
+ @Override
+ public void collectBlog(CollectBlogDto collectBlogDto) {
+ String userId = RequestHolder.getuserId().toString(); // 获取用户ID
+ String blogId = collectBlogDto.getBlogId().toString();
+ Integer favoritesId = collectBlogDto.getFavoriteId();
+ if (userId == null) {
+ throw new IllegalStateException("用户未登录");
+ }
+ String collectLockKey = constantConfiguration.BLOG_COLLECT_LOCK + blogId;
+ // 尝试获取锁,设置锁的过期时间为10秒,防止死锁
+ Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(collectLockKey, "LOCKED", 10, TimeUnit.SECONDS);
+
+ if (Boolean.TRUE.equals(lockAcquired)) {
+ try {
+ String collectUserKey = constantConfiguration.BLOG_COLLECT_SET + blogId; // 用于存放收藏用户的 Set
+ String collectCountKey = constantConfiguration.BLOG_COLLECT_COUNT + blogId; // 用于存放收藏数
+ String collectCountExpireKey = constantConfiguration.BLOG_COLLECT_COUNT + blogId + ":expired"; // 用于存放收藏数
+ String blogCollectBlogsHashKey = constantConfiguration.BLOG_COLLECT_HASH + favoritesId;
+ String blogCollectBlogsHashExpiredKey = constantConfiguration.BLOG_COLLECT_HASH + favoritesId + ":expired";
+
+ // 检查是否已收藏,并确保没有发生空指针异常
+ Boolean isFirstCollect = redisTemplate.opsForSet().isMember(collectUserKey, userId);
+// Blogs blog = blogsMapper.selectById(collectBlogDto.getBlogId());
+// String blogJson = objectMapper.writeValueAsString(blog);
+
+ if (isFirstCollect == null || !isFirstCollect) {
+ // 收藏
+ redisTemplate.opsForSet().add(collectUserKey, userId);
+ redisTemplate.opsForValue().increment(collectCountKey);
+
+ // 将收藏的博客缓存到用户收藏夹的博客列表中
+ redisTemplate.opsForHash().put(blogCollectBlogsHashKey, blogId, "true");
+
+ // 设置逻辑过期时间 确保能同步到数据中
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(collectCountExpireKey))) {
+ redisTemplate.opsForValue().set(collectCountExpireKey, "true", 23, TimeUnit.HOURS);
+ }
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(blogCollectBlogsHashExpiredKey))) {
+ redisTemplate.opsForValue().set(blogCollectBlogsHashExpiredKey, "true", 23, TimeUnit.HOURS);
+ }
+ } else {
+ // 取消收藏
+ redisTemplate.opsForSet().remove(collectUserKey, userId);
+ redisTemplate.opsForValue().decrement(collectCountKey);
+ redisTemplate.opsForHash().put(blogCollectBlogsHashKey, blogId, "false");
+
+ // 设置逻辑过期时间 确保能同步到数据中
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(collectCountExpireKey))) {
+ redisTemplate.opsForValue().set(collectCountExpireKey, "true", 23, TimeUnit.HOURS);
+ }
+ if (!Boolean.TRUE.equals(redisTemplate.hasKey(blogCollectBlogsHashExpiredKey))) {
+ redisTemplate.opsForValue().set(blogCollectBlogsHashExpiredKey, "true", 23, TimeUnit.HOURS);
+ }
+ }
+ } finally {
+ // 释放锁
+ redisTemplate.delete(collectLockKey);
+ }
+ } else {
+ log.warn("无法获取分布式锁,用户 {} 收藏博客 {} 操作被跳过", userId, blogId);
+ }
+ }
}
diff --git a/src/main/java/com/xubx/springboot_01demo/service/impl/CommentServiceImpl.java b/src/main/java/com/xubx/springboot_01demo/service/impl/CommentServiceImpl.java
index 8abb689..a6d10ae 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/impl/CommentServiceImpl.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/impl/CommentServiceImpl.java
@@ -18,6 +18,8 @@ import java.util.List;
public class CommentServiceImpl implements CommentService {
@Resource
CommentMapper commentMapper;
+ @Resource
+ UserService userService;
@Override
public List findAllComment(int article_id) {
return commentMapper.findAllComment(article_id);
@@ -28,7 +30,7 @@ public class CommentServiceImpl implements CommentService {
Comment comment1 = new Comment();
//对象属性拷贝
BeanUtils.copyProperties(comment,comment1);
- comment1.setUsername(RequestHolder.getuserId());
+ comment1.setUsername(userService.getUser("").getUsername());
System.out.println(comment1);
commentMapper.addComment(comment1);
}
diff --git a/src/main/java/com/xubx/springboot_01demo/service/impl/RelationshipServiceImpl.java b/src/main/java/com/xubx/springboot_01demo/service/impl/RelationshipServiceImpl.java
index 2d52ea0..beb6db2 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/impl/RelationshipServiceImpl.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/impl/RelationshipServiceImpl.java
@@ -5,6 +5,7 @@ import com.xubx.springboot_01demo.mapper.RelationshipMapper;
import com.xubx.springboot_01demo.pojo.Relationship;
import com.xubx.springboot_01demo.pojo.User;
import com.xubx.springboot_01demo.service.RelationshipService;
+import com.xubx.springboot_01demo.service.UserService;
import com.xubx.springboot_01demo.utils.token.RequestHolder;
import com.xubx.springboot_01demo.vo.UserListVo;
import com.xubx.springboot_01demo.vo.UserVo;
@@ -20,6 +21,8 @@ public class RelationshipServiceImpl implements RelationshipService {
@Resource
RelationshipMapper relationshipMapper;
+ @Resource
+ UserService userService;
/**
@@ -31,8 +34,9 @@ public class RelationshipServiceImpl implements RelationshipService {
@Override
public List queryUser(String username) {
List userDtos = new ArrayList<>();
+
//将User转换为UserDto
- for(User u : relationshipMapper.findUserByUsername(RequestHolder.getuserId(),username)){
+ for(User u : relationshipMapper.findUserByUsername(userService.getUser("").getUsername(),username)){
UserVo userDto = new UserVo();
//将User的属性复制到UserDto
BeanUtils.copyProperties(u,userDto);
diff --git a/src/main/java/com/xubx/springboot_01demo/service/impl/UserServiceImpl.java b/src/main/java/com/xubx/springboot_01demo/service/impl/UserServiceImpl.java
index a637d24..76001b6 100644
--- a/src/main/java/com/xubx/springboot_01demo/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/xubx/springboot_01demo/service/impl/UserServiceImpl.java
@@ -3,17 +3,38 @@ package com.xubx.springboot_01demo.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.xubx.springboot_01demo.configuration.constantConfiguration;
+import com.xubx.springboot_01demo.dto.user.EditMaterialDto;
+import com.xubx.springboot_01demo.dto.user.NewFavoritesDto;
+import com.xubx.springboot_01demo.mapper.BlogsMapper;
import com.xubx.springboot_01demo.mapper.RelationshipMapper;
+import com.xubx.springboot_01demo.mapper.UserFavoriteMapper;
import com.xubx.springboot_01demo.mapper.UserMapper;
+import com.xubx.springboot_01demo.pojo.Blogs;
import com.xubx.springboot_01demo.pojo.Relationship;
import com.xubx.springboot_01demo.pojo.User;
+import com.xubx.springboot_01demo.pojo.UserFavorite;
import com.xubx.springboot_01demo.service.UserService;
-import com.xubx.springboot_01demo.utils.api.Result;
+import com.xubx.springboot_01demo.utils.token.RequestHolder;
+import com.xubx.springboot_01demo.utils.token.TokenGenerate;
+import com.xubx.springboot_01demo.vo.getUserInfoVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import javax.servlet.http.HttpSession;
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
//Service进行具体的业务处理
@Service
@@ -22,28 +43,45 @@ public class UserServiceImpl implements UserService {
UserMapper userMapper;
@Resource
RelationshipMapper relationshipMapper;
+ @Resource
+ BlogsMapper blogMapper;
+ @Resource
+ UserFavoriteMapper userFavoriteMapper;
+ @Autowired
+ RedisTemplate redisTemplate;
+ @Resource
+ private HttpSession session;
+ @Autowired
+ ObjectMapper objectMapper;
//登陆,获取User对象
- @Override
- public Boolean findUserByUsername(User user) {
- try {
- User userByUsername = userMapper.findUserByUsername(user.getUsername());
+ public String login(User user) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(User::getUsername, user.getUsername());
+ User userByUsername = userMapper.selectOne(queryWrapper);
+ RequestHolder.add(userByUsername.getId());
- if (Objects.equals(userByUsername.getPassword(), user.getPassword())) {
- return true;
- }
- return false;
- } catch (Exception e) {
- System.out.println(e);
- return false;
+ // 校验用户是否存在以及密码是否匹配
+ if (userByUsername != null && Objects.equals(userByUsername.getPassword(), user.getPassword())) {
+ // 生成 Token
+ String token = new TokenGenerate().generateToken(userByUsername.getId());
+ // 将用户名存入 session 中
+ session.setAttribute("username", userByUsername.getUsername());
+ return token;
}
+
+ // 登录失败返回 null
+ return null;
}
//注册,新增
@Override
public Boolean insertUser(User user) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(User::getUsername, user.getUsername());
+
// 检查用户名是否已存在
- if (userMapper.findUserByUsername(user.getUsername()) != null) {
+ if (userMapper.selectOne(queryWrapper) != null) {
return false;
}
// 用户名不存在,插入新用户
@@ -52,8 +90,11 @@ public class UserServiceImpl implements UserService {
}
@Override
- public void addAvatar(String path, String username) {
- userMapper.addAvatar(path, username);
+ public void addAvatar(String path, String userId) {
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.eq(User::getId, userId)
+ .set(User::getAvatar, path);
+ userMapper.update(null, updateWrapper);
}
@Override
@@ -62,13 +103,11 @@ public class UserServiceImpl implements UserService {
}
@Override
- public boolean usernameChange(String usernameNow, String username) {
- // 检查用户名是否已存在
- if (userMapper.findUserByUsername(username) != null) {
- return false;
- }
- userMapper.usernameChange(usernameNow, username);
- return true;
+ public void usernameChange(String username) {
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.eq(User::getId, RequestHolder.getuserId())
+ .set(User::getUsername, username);
+ userMapper.update(null, updateWrapper);
}
@Override
@@ -100,4 +139,181 @@ public class UserServiceImpl implements UserService {
result.put("friendRequests", jsonArray);
return result;
}
+
+ /**
+ * 获取用户
+ *
+ * @param userId
+ * @return {@link User }
+ */
+ @Override
+ public User getUser(String userId) {
+ User user;
+ if (userId != null && !userId.equals("")) {
+ user = userMapper.selectById(userId);
+ } else {
+ // 如果userId为空,则获取当前登录用户的userId
+ user = userMapper.selectById(RequestHolder.getuserId());
+ }
+ return user;
+ }
+
+ /**
+ * 获取用户信息
+ *
+ * @param userId
+ * @return {@link getUserInfoVo }
+ */
+ @Override
+ public getUserInfoVo getUserInfo(String userId) {
+ User user = getUser(userId);
+ final Integer finalUserId = user.getId();
+
+ getUserInfoVo getUserInfoVo = new getUserInfoVo();
+ getUserInfoVo.setUsername(user.getUsername());
+ getUserInfoVo.setAvatar(user.getAvatar());
+ getUserInfoVo.setBio(user.getBio());
+ getUserInfoVo.setJoinBlogTime(user.getCreatedTime());
+ getUserInfoVo.setTotalViewCount(getCachedValue(constantConfiguration.USER_TOTAL_VIEW_COUNT + finalUserId, () -> blogMapper.getTotalViewCount(finalUserId)));
+ getUserInfoVo.setTotalBlogCount(getCachedValue(constantConfiguration.USER_TOTAL_BLOG_COUNT + finalUserId, () -> blogMapper.getTotalBlogCount(finalUserId)));
+ getUserInfoVo.setTotalCollectCount(getCachedValue(constantConfiguration.USER_TOTAL_COLLECT_COUNT + finalUserId, () -> blogMapper.getTotalCollectCount(finalUserId)));
+ getUserInfoVo.setTotalLikeCount(getCachedValue(constantConfiguration.USER_TOTAL_LIKE_COUNT + finalUserId, () -> blogMapper.getTotalLikeCount(finalUserId)));
+ getUserInfoVo.setTotalCommentCount(getCachedValue(constantConfiguration.USER_TOTAL_COMMENT_COUNT + finalUserId, () -> blogMapper.getTotalCommentCount(finalUserId)));
+ getUserInfoVo.setTotalShareCount(getCachedValue(constantConfiguration.USER_TOTAL_SHARE_COUNT + finalUserId, () -> blogMapper.getTotalShareCount(finalUserId)));
+ getUserInfoVo.setTotalFollowerCount(getCachedValue(constantConfiguration.USER_TOTAL_FOLLOWER_COUNT + finalUserId, () -> relationshipMapper.getTotalFollowerCount(finalUserId)));
+ return getUserInfoVo;
+ }
+
+ /**
+ * 获取缓存值通用方法
+ *
+ * @param key
+ * @param dbQuery
+ * @return {@link Integer }
+ */
+ private String getCachedValue(String key, Supplier dbQuery) {
+ String value = (String) redisTemplate.opsForValue().get(key);
+ if (value == null) {
+ value = dbQuery.get();
+ redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
+ }
+ return value;
+ }
+
+ /**
+ * 修改个人资料
+ */
+ @Override
+ public void editMaterial(EditMaterialDto editMaterialDto) {
+ LocalDateTime now = LocalDateTime.now();
+ User user = new User();
+ user.setId(RequestHolder.getuserId());
+ user.setUsername(editMaterialDto.getUsername());
+ user.setAvatar(editMaterialDto.getAvatar());
+ user.setGender(editMaterialDto.getGender());
+ user.setBio(editMaterialDto.getBio());
+ user.setUpdateTime(Timestamp.valueOf(now));
+ userMapper.updateById(user);
+ }
+
+ /**
+ * 新建收藏夹
+ *
+ * @param newFavorites
+ */
+ @Override
+ public String newFavorites(NewFavoritesDto newFavorites) {
+ // 检查标题是否已存在
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(UserFavorite::getName, newFavorites.getName())
+ .eq(UserFavorite::getUserId, RequestHolder.getuserId());
+ int count = userFavoriteMapper.selectCount(wrapper);
+
+ if (count > 0) {
+ return "该收藏夹已存在";
+ } else {
+ UserFavorite userFavorite = new UserFavorite();
+ userFavorite.setName(newFavorites.getName());
+ userFavorite.setUserId(RequestHolder.getuserId());
+ userFavorite.setDescription(newFavorites.getDescription());
+ userFavorite.setCreatedTime(Timestamp.valueOf(LocalDateTime.now()));
+ // 检查是否由收藏夹状态
+ if (newFavorites.getFavoriteStatus() != null) {
+ userFavorite.setFavoriteStatus("私密");
+ } else {
+ userFavorite.setFavoriteStatus("公开");
+ }
+ userFavoriteMapper.insert(userFavorite);
+ return null; // 创建成功,无错误消息
+ }
+
+ }
+
+ /**
+ * 获取用户的收藏夹列表
+ *
+ * @param userId
+ * @return {@link List }<{@link UserFavorite }>
+ */
+ @Override
+ public List getUserFavorites(String userId) {
+ Integer currentUserId = RequestHolder.getuserId();
+
+ if (currentUserId == null) {
+ throw new IllegalStateException("用户未登录");
+ }
+
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ // 首先判断是否是获取当前用户的收藏夹列表
+ if (userId == null || userId.isEmpty() || userId.equals(currentUserId.toString())) {
+ // 获取当前用户的全部收藏夹
+ // TODO 收藏夹中的博客数量不是实时的
+ wrapper.eq(UserFavorite::getUserId, currentUserId)
+ .orderByDesc(UserFavorite::getCreatedTime);
+ return userFavoriteMapper.selectList(wrapper);
+ } else {
+ // 获取指定用户的公开的收藏夹
+ wrapper.eq(UserFavorite::getUserId, userId)
+ .eq(UserFavorite::getFavoriteStatus, "公开")
+ .orderByDesc(UserFavorite::getCreatedTime);
+ return userFavoriteMapper.selectList(wrapper);
+ }
+ }
+
+ /**
+ * 获取收藏夹中的博客列表
+ *
+ * @param favoriteId
+ * @return {@link List }<{@link Blogs }>
+ */
+ @Override
+ public List getBlogsByFavoriteId(String favoriteId) {
+ Integer userId = RequestHolder.getuserId();
+ if (userId == null) {
+ throw new IllegalStateException("用户未登录");
+ }
+
+ // 首先获取数据库中的数据
+ List blogsFromDb = blogMapper.getBlogsByFavoriteId(favoriteId);
+
+ // 然后获取缓存中的数据
+ String userCollectBlogsHashKey = constantConfiguration.BLOG_COLLECT_HASH + favoriteId;
+ if (redisTemplate.hasKey(userCollectBlogsHashKey)) {
+ // 缓存中有数据,需要拼接到数据库获取到的数据
+ Set blogSet = redisTemplate.opsForHash().keys(userCollectBlogsHashKey);
+ if (blogSet != null && !blogSet.isEmpty()) {
+ for (String blogIdStr : blogSet) {
+ String collectStatus = (String) redisTemplate.opsForHash().get(userCollectBlogsHashKey, blogIdStr);
+ Blogs blog = blogMapper.findByIdBlogs(Integer.parseInt(blogIdStr));
+ if ("true".equals(collectStatus)) {
+ blogsFromDb.add(blog);
+ } else if ("false".equals(collectStatus)) {
+ blogsFromDb.remove(blog);
+ }
+ }
+ }
+ }
+ return blogsFromDb;
+ }
+
}
diff --git a/src/main/java/com/xubx/springboot_01demo/utils/token/RequestHolder.java b/src/main/java/com/xubx/springboot_01demo/utils/token/RequestHolder.java
index efcfdd3..8e6fce0 100644
--- a/src/main/java/com/xubx/springboot_01demo/utils/token/RequestHolder.java
+++ b/src/main/java/com/xubx/springboot_01demo/utils/token/RequestHolder.java
@@ -4,13 +4,13 @@ package com.xubx.springboot_01demo.utils.token;
* 用于存储当前用户的id
*/
public class RequestHolder {
- private static final ThreadLocal userHolder = new ThreadLocal<>();
+ private static final ThreadLocal userHolder = new ThreadLocal<>();
- public static void add(String userId) {
+ public static void add(Integer userId) {
userHolder.set(userId);
}
- public static String getuserId() {
+ public static Integer getuserId() {
return userHolder.get();
}
diff --git a/src/main/java/com/xubx/springboot_01demo/utils/token/TokenGenerate.java b/src/main/java/com/xubx/springboot_01demo/utils/token/TokenGenerate.java
index 9d594dd..04128ca 100644
--- a/src/main/java/com/xubx/springboot_01demo/utils/token/TokenGenerate.java
+++ b/src/main/java/com/xubx/springboot_01demo/utils/token/TokenGenerate.java
@@ -12,13 +12,13 @@ public class TokenGenerate {
private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000;
private static final String TOKEN_SECRET = "tokenqkj"; //密钥盐
- public String generateToken(String username) {
+ public String generateToken(int userId) {
String token = null;
try {
Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
token = JWT.create()
.withIssuer("auth0")
- .withClaim("username", username)
+ .withClaim("userId", userId)
.withExpiresAt(expiresAt)
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (Exception e) {
@@ -38,10 +38,10 @@ public class TokenGenerate {
}
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT jwt = verifier.verify(token);
- RequestHolder.add(jwt.getClaim("username").asString());
+ RequestHolder.add(jwt.getClaim("userId").asInt());
System.out.println("认证通过:");
System.out.println("issuer: " + jwt.getIssuer());
- System.out.println("username: " + jwt.getClaim("username").asString());
+ System.out.println("userId: " + jwt.getClaim("userId").asString());
System.out.println("过期时间: " + jwt.getExpiresAt());
return true;
} catch (Exception e) {
diff --git a/src/main/java/com/xubx/springboot_01demo/vo/GetBlogDetailVo.java b/src/main/java/com/xubx/springboot_01demo/vo/GetBlogDetailVo.java
new file mode 100644
index 0000000..6ebc265
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/vo/GetBlogDetailVo.java
@@ -0,0 +1,54 @@
+package com.xubx.springboot_01demo.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+@Data
+@ApiModel(value = "getBlogDetail", description = "获取博客详情")
+public class GetBlogDetailVo {
+ private int id;
+
+ @ApiModelProperty(value = "标题")
+ private String title;
+
+
+ @ApiModelProperty(value = "内容")
+ private String content;
+
+ @ApiModelProperty(value = "作者ID")
+ private Integer authorId;
+
+ @ApiModelProperty(value = "作者名")
+ private String authorName;
+
+ @ApiModelProperty(value = "作者头像")
+ private String avatar;
+
+ @ApiModelProperty(value = "点赞数")
+ private String likeCount;
+
+ @ApiModelProperty(value = "点赞状态: 0未点赞 1已点赞")
+ private int likeStatus;
+
+ @ApiModelProperty(value = "浏览数")
+ private String viewCount;
+
+ @ApiModelProperty(value = "评论数")
+ private String commentCount;
+
+ @ApiModelProperty(value = "收藏数")
+ private String collectCount;
+
+ @ApiModelProperty(value = "收藏状态:0未收藏 1已收藏")
+ private int collectStatus;
+
+ @ApiModelProperty(value = "更新时间")
+ private Timestamp updatedTime;
+
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createdTime;
+
+}
diff --git a/src/main/java/com/xubx/springboot_01demo/vo/getUserInfoVo.java b/src/main/java/com/xubx/springboot_01demo/vo/getUserInfoVo.java
new file mode 100644
index 0000000..a8b69ae
--- /dev/null
+++ b/src/main/java/com/xubx/springboot_01demo/vo/getUserInfoVo.java
@@ -0,0 +1,44 @@
+package com.xubx.springboot_01demo.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+@Data
+@ApiModel(description = "获取当前用户信息出参")
+public class getUserInfoVo {
+ @ApiModelProperty(value = "用户名")
+ private String username;
+
+ @ApiModelProperty(value = "头像")
+ private String avatar;
+
+ @ApiModelProperty(value = "个人简介")
+ private String bio;
+
+ @ApiModelProperty(value = "总访问量")
+ private String totalViewCount;
+
+ @ApiModelProperty(value = "总博客数")
+ private String totalBlogCount;
+
+ @ApiModelProperty(value = "粉丝数量")
+ private String totalFollowerCount;
+
+ @ApiModelProperty(value = "总收藏数")
+ private String totalCollectCount;
+
+ @ApiModelProperty(value = "加入时间")
+ private Timestamp joinBlogTime;
+
+ @ApiModelProperty(value = "总点赞数")
+ private String totalLikeCount;
+
+ @ApiModelProperty(value = "总评论数")
+ private String totalCommentCount;
+
+ @ApiModelProperty(value = "总分享数")
+ private String totalShareCount;
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index ed6b1ca..9c008a7 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -11,6 +11,7 @@ spring:
host: 62.234.217.137
port: 6379
password: LSHCwjr6ZN4hzCxS
+ database: 0
web:
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
@@ -27,4 +28,5 @@ logging:
qiniu:
accessKey: McJYQOg3S6PhkljCg2DQeggBQTcGcUZyK_s6vkxy
secretKey: 5hUuHs-BEzJIEKPCEj292h14evv5L59bDSZuYXa-
- bucket: xubx-blog
\ No newline at end of file
+ bucket: xubx-blog
+
diff --git a/src/main/resources/mapper/BlogLikeMapper.xml b/src/main/resources/mapper/BlogLikeMapper.xml
new file mode 100644
index 0000000..ce6e7fb
--- /dev/null
+++ b/src/main/resources/mapper/BlogLikeMapper.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/BlogsMapper.xml b/src/main/resources/mapper/BlogsMapper.xml
index 22ae3fb..22cecf3 100644
--- a/src/main/resources/mapper/BlogsMapper.xml
+++ b/src/main/resources/mapper/BlogsMapper.xml
@@ -19,6 +19,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -29,6 +74,10 @@
insert into blog_category(blog_id, category_id)
values (#{blogId}, #{categoryId})
+
+ insert into user_favorite_blog(blog_id, favorite_id)
+ values (#{blogId}, #{favoriteId})
+
diff --git a/src/main/resources/mapper/RelationshipMapper.xml b/src/main/resources/mapper/RelationshipMapper.xml
index 9dcb33f..3e7a3db 100644
--- a/src/main/resources/mapper/RelationshipMapper.xml
+++ b/src/main/resources/mapper/RelationshipMapper.xml
@@ -57,4 +57,7 @@
and status = 0
and initiator != #{username}
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserFavoriteBlogMapper.xml b/src/main/resources/mapper/UserFavoriteBlogMapper.xml
new file mode 100644
index 0000000..f55b48a
--- /dev/null
+++ b/src/main/resources/mapper/UserFavoriteBlogMapper.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserFavoriteMapper.xml b/src/main/resources/mapper/UserFavoriteMapper.xml
new file mode 100644
index 0000000..423a1ab
--- /dev/null
+++ b/src/main/resources/mapper/UserFavoriteMapper.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml
index 1852461..6387236 100644
--- a/src/main/resources/mapper/UserMapper.xml
+++ b/src/main/resources/mapper/UserMapper.xml
@@ -9,10 +9,6 @@
-
-
insert into user(username, password) values(#{username}, #{password})