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})