diff --git a/docs/api doc/分页 获取post接口.md b/docs/api doc/分页 获取post接口.md index e8f4831..bde6fe0 100644 --- a/docs/api doc/分页 获取post接口.md +++ b/docs/api doc/分页 获取post接口.md @@ -180,7 +180,7 @@ GET /v1/posts?type=1716477250320&style=newest&page=1&page_size=20 ### 9 响应示例(错误) ```json -{ "code": 10001, "message": "验证码无效" } +{ "code": 10001, "msg": "验证码无效" } ``` ### 10 错误响应码参考 diff --git a/docs/api doc/收藏和取消收藏接口.md b/docs/api doc/收藏和取消收藏接口.md new file mode 100644 index 0000000..bcb156e --- /dev/null +++ b/docs/api doc/收藏和取消收藏接口.md @@ -0,0 +1,86 @@ +# RESTFul API 文档 + +## 收藏和取消收藏接口 + +### 1 接口描述 +收藏文章和取消对文章的收藏 + +### 2 请求URL +`/v1/post/collection` + +### 3 请求方式 +**POST** + +### 4 请求头 +| 头字段 | 必填 | 数据类型 | 描述 | +| ------------ | ---- | ------------- | -------------------------------- | +| | | || + +### 1.5 请求体参数 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | 示例 | 允许空值 | +|----------| ---- |------| ------- |------| ----------- | ----- | +| id | 是 | 长整型 | | 文章id | | | + +### 6 请求示例 +```http +POST /v1/post/star +Host: {apiAddress} +Content-Type: application/json + +{ + "id": 123440 +} +``` + +### 7 返回参数说明 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|------| ---- | -------- | -------- | ---------------------------- | +| code | 是 | 整型 | | 错误码,200表示成功 | +| msg | 否 | 字符串 | 1-50字符 | 错误信息描述 | +| data | 否 | json | | 具体业务数据 | + +data结构说明: + +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|--------| ---- |---------|-------------------------|-----------| +| status | 是 | boolean | 收藏成功 true, 取消收藏成功 false | | + + +### 8 响应示例(成功) + +```json + { + "code": 0, + "msg": "success", + "data": { + "status": true + } +} +``` +### 9 响应示例(错误) +```json +{ "code": 10001, "msg": "验证码无效" } +``` + +### 10 错误响应码参考 +更多响应错误码及含义,请参阅[API响应码表](URL/for/api/responseCode/table)。 + +### 11 安全性与认证 +此API要求调用方在`Authorization`头中携带经过Bearer认证的令牌。 + +### 12 测试环境 +访问测试环境以进行接口调试: +[https://test.apiAddress.com](https://test.apiAddress.com) + +### 13 版本管理 +本API通过URI路径进行版本控制。请在请求URL中包含`/v1`以使用当前版本。 + +### 14 更新记录 + + +### 15 联系支持 +如需帮助或对API有任何疑问,请通过电子邮件与我们联系:[support@api.com](mailto:support@api.com)。 + +### 16 反馈与建议 +发现文档问题或有改进建议?请填写[反馈表单](https://forms.api.com/feedback)与我们分享。 + diff --git a/docs/api doc/点赞和取消点赞接口.md b/docs/api doc/点赞和取消点赞接口.md new file mode 100644 index 0000000..87439f7 --- /dev/null +++ b/docs/api doc/点赞和取消点赞接口.md @@ -0,0 +1,86 @@ +# RESTFul API 文档 + +## 点赞和取消点赞接口 + +### 1 接口描述 +点赞文章和取消对文章的点赞 + +### 2 请求URL +`/v1/post/star` + +### 3 请求方式 +**POST** + +### 4 请求头 +| 头字段 | 必填 | 数据类型 | 描述 | +| ------------ | ---- | ------------- | -------------------------------- | +| | | || + +### 1.5 请求体参数 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | 示例 | 允许空值 | +|----------| ---- |------| ------- |------| ----------- | ----- | +| id | 是 | 长整型 | | 文章id | | | + +### 6 请求示例 +```http +POST /v1/post/star +Host: {apiAddress} +Content-Type: application/json + +{ + "id": 123440 +} +``` + +### 7 返回参数说明 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|------| ---- | -------- | -------- | ---------------------------- | +| code | 是 | 整型 | | 错误码,200表示成功 | +| msg | 否 | 字符串 | 1-50字符 | 错误信息描述 | +| data | 否 | json | | 具体业务数据 | + +data结构说明: + +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|--------| ---- |---------|-------------------------|-----------| +| status | 是 | boolean | 点赞成功 true, 取消点赞成功 false | | + + +### 8 响应示例(成功) + +```json + { + "code": 0, + "msg": "success", + "data": { + "status": true + } +} +``` +### 9 响应示例(错误) +```json +{ "code": 10001, "msg": "验证码无效" } +``` + +### 10 错误响应码参考 +更多响应错误码及含义,请参阅[API响应码表](URL/for/api/responseCode/table)。 + +### 11 安全性与认证 +此API要求调用方在`Authorization`头中携带经过Bearer认证的令牌。 + +### 12 测试环境 +访问测试环境以进行接口调试: +[https://test.apiAddress.com](https://test.apiAddress.com) + +### 13 版本管理 +本API通过URI路径进行版本控制。请在请求URL中包含`/v1`以使用当前版本。 + +### 14 更新记录 + + +### 15 联系支持 +如需帮助或对API有任何疑问,请通过电子邮件与我们联系:[support@api.com](mailto:support@api.com)。 + +### 16 反馈与建议 +发现文档问题或有改进建议?请填写[反馈表单](https://forms.api.com/feedback)与我们分享。 + diff --git a/docs/api doc/用户注册接口.md b/docs/api doc/用户注册接口.md index 00ca989..cc39503 100644 --- a/docs/api doc/用户注册接口.md +++ b/docs/api doc/用户注册接口.md @@ -22,7 +22,7 @@ ### 1.6 请求示例 ```http -POST /api/user/signup +POST /v1/auth/register Host: {apiAddress} Content-Type: application/json diff --git a/docs/api doc/获取当前用户对某个动态的收藏状态接口.md b/docs/api doc/获取当前用户对某个动态的收藏状态接口.md new file mode 100644 index 0000000..ac4a0d4 --- /dev/null +++ b/docs/api doc/获取当前用户对某个动态的收藏状态接口.md @@ -0,0 +1,80 @@ +# RESTFul API 文档 + +## 获取当前用户对某个动态的收藏状态 + +### 1 接口描述 +获得当前登录用户对指定动态的收藏状态 + +### 2 请求URL +`/v1/post/collection` + +### 3 请求方式 +**GET** + +### 4 请求头 +| 头字段 | 必填 | 数据类型 | 描述 | +| ------------ | ---- | ------------- | -------------------------------- | +| | | || + +### 1.5 Query参数 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | 示例 | 允许空值 | +|----------| ---- |------| ------- |------| ----------- | ----- | +| id | 是 | 长整型 | | 文章id | | | + +### 6 请求示例 +```http +GET /v1/post/collection?id=100 +``` + +### 7 返回参数说明 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|------| ---- | -------- | -------- | ---------------------------- | +| code | 是 | 整型 | | 错误码,200表示成功 | +| msg | 否 | 字符串 | 1-50字符 | 错误信息描述 | +| data | 否 | json | | 具体业务数据 | + +data结构说明: + +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|--------| ---- |---------|---------------------|-----------| +| status | 是 | boolean | | 已收藏 true, 未收藏 false| + + +### 8 响应示例(成功) + +```json + { + "code": 0, + "msg": "success", + "data": { + "status": true + } +} +``` +### 9 响应示例(错误) +```json +{ "code": 10001, "msg": "验证码无效" } +``` + +### 10 错误响应码参考 +更多响应错误码及含义,请参阅[API响应码表](URL/for/api/responseCode/table)。 + +### 11 安全性与认证 +此API要求调用方在`Authorization`头中携带经过Bearer认证的令牌。 + +### 12 测试环境 +访问测试环境以进行接口调试: +[https://test.apiAddress.com](https://test.apiAddress.com) + +### 13 版本管理 +本API通过URI路径进行版本控制。请在请求URL中包含`/v1`以使用当前版本。 + +### 14 更新记录 + + +### 15 联系支持 +如需帮助或对API有任何疑问,请通过电子邮件与我们联系:[support@api.com](mailto:support@api.com)。 + +### 16 反馈与建议 +发现文档问题或有改进建议?请填写[反馈表单](https://forms.api.com/feedback)与我们分享。 + diff --git a/docs/api doc/获取当前用户对某个动态的点赞状态接口.md b/docs/api doc/获取当前用户对某个动态的点赞状态接口.md new file mode 100644 index 0000000..3b10751 --- /dev/null +++ b/docs/api doc/获取当前用户对某个动态的点赞状态接口.md @@ -0,0 +1,80 @@ +# RESTFul API 文档 + +## 获取当前用户对某个动态的点赞状态 + +### 1 接口描述 +获得当前登录用户对指定动态的点赞状态 + +### 2 请求URL +`/v1/post/star` + +### 3 请求方式 +**GET** + +### 4 请求头 +| 头字段 | 必填 | 数据类型 | 描述 | +| ------------ | ---- | ------------- | -------------------------------- | +| | | || + +### 1.5 Query参数 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | 示例 | 允许空值 | +|----------| ---- |------| ------- |------| ----------- | ----- | +| id | 是 | 长整型 | | 文章id | | | + +### 6 请求示例 +```http +GET /v1/post/star?id=100 +``` + +### 7 返回参数说明 +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|------| ---- | -------- | -------- | ---------------------------- | +| code | 是 | 整型 | | 错误码,200表示成功 | +| msg | 否 | 字符串 | 1-50字符 | 错误信息描述 | +| data | 否 | json | | 具体业务数据 | + +data结构说明: + +| 参数名称 | 必填 | 数据类型 | 约束条件 | 描述 | +|--------| ---- |---------|---------------------|-----------------------| +| status | 是 | boolean | | 已点赞 true, 未点赞 false | + + +### 8 响应示例(成功) + +```json + { + "code": 0, + "msg": "success", + "data": { + "status": true + } +} +``` +### 9 响应示例(错误) +```json +{ "code": 10001, "msg": "验证码无效" } +``` + +### 10 错误响应码参考 +更多响应错误码及含义,请参阅[API响应码表](URL/for/api/responseCode/table)。 + +### 11 安全性与认证 +此API要求调用方在`Authorization`头中携带经过Bearer认证的令牌。 + +### 12 测试环境 +访问测试环境以进行接口调试: +[https://test.apiAddress.com](https://test.apiAddress.com) + +### 13 版本管理 +本API通过URI路径进行版本控制。请在请求URL中包含`/v1`以使用当前版本。 + +### 14 更新记录 + + +### 15 联系支持 +如需帮助或对API有任何疑问,请通过电子邮件与我们联系:[support@api.com](mailto:support@api.com)。 + +### 16 反馈与建议 +发现文档问题或有改进建议?请填写[反馈表单](https://forms.api.com/feedback)与我们分享。 + diff --git a/docs/tasks/任务11-Sprint-2-点赞和收藏动态.md b/docs/tasks/任务11-Sprint-2-点赞和收藏动态.md index c1c000b..a41b8c0 100644 --- a/docs/tasks/任务11-Sprint-2-点赞和收藏动态.md +++ b/docs/tasks/任务11-Sprint-2-点赞和收藏动态.md @@ -1,15 +1,215 @@ ## 任务名称: 点赞和收藏动态 ### 目标: -- [简要说明此任务旨在达成的具体学习目标或技能提升点。] +- 巩固练习: 熟练掌握基于spring boot开发的基本步骤 ### 预备知识: -- [列出完成该任务前学生应具备的基础知识或先修技能,如特定编程语言基础、框架了解等。] ### 操作步骤: -1. **步骤1**: [详细描述第一步操作,包括使用的工具、命令或技术要点。] -2. **步骤2**: [继续描述后续步骤,确保每一步都清晰、可执行。] - ... - [根据需要添加更多步骤] +#### 1. API文档 + +[点赞和取消点赞接口](../api%20doc/点赞和取消点赞接口.md) + +[获取当前用户对某个动态的点赞状态接口](../api%20doc/获取当前用户对某个动态的点赞状态接口.md) + +[收藏和取消收藏接口](../api%20doc/收藏和取消收藏接口.md) + +[获取当前用户对某个动态的收藏状态接口](../api%20doc/获取当前用户对某个动态的收藏状态接口.md) + +#### 2. 数据模型设计和实现 + +##### 2.1 实体类 + +**PostStar** +```java +@Entity +public class PostStar extends BaseAuditingEntity{ + + @Comment("POST ID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; + + @Comment("用户ID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; +} +``` + +**PostCollection** + +```java +@Entity +public class PostCollection extends BaseAuditingEntity{ + + @Comment("POST ID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; + + @Comment("用户ID") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + +} +``` + +##### 2.2 DTO + +**PostStarDTO** +```java +@Value +public class PostStarDto { + Long id; + PostDto post; + UserDto user; + @JsonSerialize(using = MillisecondToSecondSerializer.class) + Long createdOn; + @JsonSerialize(using = MillisecondToSecondSerializer.class) + Long modifiedOn; +} + +``` +**PostCollectionDTO** + +```java +@Value +public class PostCollectionDto { + + Long id; + PostDto post; + UserDto user; + @JsonSerialize(using = MillisecondToSecondSerializer.class) + Long createdOn; + @JsonSerialize(using = MillisecondToSecondSerializer.class) + Long modifiedOn; +} + +``` + +##### 2.3 Mapper + +**PostStarMapper** + +```java +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING) +public interface PostStarMapper { + PostStar toEntity(PostStarDto postStarDto); + + PostStarDto toDto(PostStar postStar); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + PostStar partialUpdate(PostStarDto postStarDto, @MappingTarget PostStar postStar); +} +``` + +**PostCollectionMapper** +```java + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING) +public interface PostCollectionMapper { + PostCollection toEntity(PostCollectionDto postCollectionDto); + + PostCollectionDto toDto(PostCollection postCollection); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + PostCollection partialUpdate(PostCollectionDto postCollectionDto, @MappingTarget PostCollection postCollection); +} + +``` + + +#### 3. JPA接口 + +**PostStarRepository** +```java + +public interface PostStarRepository extends JpaRepository { + Optional findByUserIdAndPostId(Long postId, Long userId); +} +``` + +**PostCollectionRepository** +```java + + +public interface PostCollectionRepository extends JpaRepository { + Optional findByUserIdAndPostId(Long userId, Long postId); +} +``` + +#### 4. 业务逻辑 + +在PostService中添加处理点赞的方法: + +```java + +/** + * 判断当前用户是对指定文章否已点赞 + * @param postId + * @return + */ + public boolean currentUserHasStarred(Long postId){ + User user = authService.getCurrentUser(); + return postStarRepository.findByUserIdAndPostId(user.getId(), postId).isPresent(); + } + + /** + * 点赞文章 + * @param postId 文章ID + * @return 如果点赞成功返回true,如果已点过赞则返回false + */ + public boolean toggleStar(long postId){ + // 获取当前用户 + User user = authService.getCurrentUser(); + // 确认文章存在 + Post post = postRepository.findById(postId).orElseThrow(()->new ResourceNotFoundException("Post","id="+postId)); + // 确认用户是否已点赞 + PostStar postStar = postStarRepository.findByUserIdAndPostId(user.getId(),postId).orElse(null); + if(postStar==null){ + // 如果未点赞,则创建点赞记录并更新文章点赞数 + postStar = new PostStar(); + postStar.setPost(post); + postStar.setUser(user); + postStarRepository.save(postStar); + post.setUpvoteCount(post.getUpvoteCount()+1); + postRepository.save(post); + return true; + } + // 如果已点赞,则删除点赞记录并更新文章点赞数 + postStarRepository.delete(postStar); + post.setUpvoteCount(post.getUpvoteCount()-1); + postRepository.save(post); + return false; + } +``` +对于收藏的处理与点赞类似,不再赘述。 + +#### 5. RestController + +在PostController中添加点赞相关的接口: +```java + + @GetMapping("/post/star") + public DataResult> currentHasStarred(@PathParam("id") Long postId) { + Map result = new HashMap<>(); + result.put("status", postService.currentUserHasStarred(postId)); + return ResultUtil.ok(result); + } + @PostMapping("/post/star") + public DataResult> toggleStar(@RequestBody Map payload) { + boolean stared = postService.toggleStar(payload.get("id")); + Map result = new HashMap<>(); + result.put("status", stared); + return ResultUtil.ok(result); + } + + +``` +收藏的接口与点赞类似,不再赘述。 + + ### 技术/工具需求: - [列出完成任务所需的技术栈、工具、软件版本等。] diff --git a/src/main/java/com/lk/paopao/controller/PostController.java b/src/main/java/com/lk/paopao/controller/PostController.java index ec84ee5..54c3782 100644 --- a/src/main/java/com/lk/paopao/controller/PostController.java +++ b/src/main/java/com/lk/paopao/controller/PostController.java @@ -50,6 +50,14 @@ public class PostController { result.put("status", postService.currentUserHasStarred(postId)); return ResultUtil.ok(result); } + @PostMapping("/post/star") + public DataResult> toggleStar(@RequestBody Map payload) { + boolean stared = postService.toggleStar(payload.get("id")); + Map result = new HashMap<>(); + result.put("status", stared); + return ResultUtil.ok(result); + } + @GetMapping("/post/collection") public DataResult> currentHasCollected(@PathParam("id") Long postId) { @@ -57,4 +65,13 @@ public class PostController { result.put("status", postService.currentUserHasCollected(postId)); return ResultUtil.ok(result); } + + @PostMapping("/post/collection") + public DataResult> toggleCollection(@RequestBody Map payload) { + boolean collected = postService.toggleCollection(payload.get("id")); + Map result = new HashMap<>(); + result.put("status", collected); + return ResultUtil.ok(result); + } + } diff --git a/src/main/java/com/lk/paopao/entity/PostCollection.java b/src/main/java/com/lk/paopao/entity/PostCollection.java index 10cf256..52e6585 100644 --- a/src/main/java/com/lk/paopao/entity/PostCollection.java +++ b/src/main/java/com/lk/paopao/entity/PostCollection.java @@ -14,7 +14,6 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Index(name = "idx_post_collection_post_id", columnList = "post_id"), @Index(name = "idx_post_collection_user_id", columnList = "user_id") }) -@EntityListeners(AuditingEntityListener.class) public class PostCollection extends BaseAuditingEntity{ @Comment("POST ID") diff --git a/src/main/java/com/lk/paopao/entity/PostStar.java b/src/main/java/com/lk/paopao/entity/PostStar.java index 399c4e1..6753d08 100644 --- a/src/main/java/com/lk/paopao/entity/PostStar.java +++ b/src/main/java/com/lk/paopao/entity/PostStar.java @@ -14,7 +14,6 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Index(name = "idx_post_star_post_id", columnList = "post_id"), @Index(name = "idx_post_star_user_id", columnList = "user_id") }) -@EntityListeners(AuditingEntityListener.class) public class PostStar extends BaseAuditingEntity{ @Comment("POST ID") diff --git a/src/main/java/com/lk/paopao/service/PostService.java b/src/main/java/com/lk/paopao/service/PostService.java index a1b87fe..e965852 100644 --- a/src/main/java/com/lk/paopao/service/PostService.java +++ b/src/main/java/com/lk/paopao/service/PostService.java @@ -3,10 +3,7 @@ package com.lk.paopao.service; import com.lk.paopao.dto.PostDto; import com.lk.paopao.dto.rest.request.PostRequest; import com.lk.paopao.dto.rest.response.Paged; -import com.lk.paopao.entity.Post; -import com.lk.paopao.entity.PostContent; -import com.lk.paopao.entity.Tag; -import com.lk.paopao.entity.User; +import com.lk.paopao.entity.*; import com.lk.paopao.exception.ResourceNotFoundException; import com.lk.paopao.mapper.PostMapper; import com.lk.paopao.mapper.TagMapper; @@ -53,6 +50,7 @@ public class PostService { @Autowired PostCollectionRepository postCollectionRepository; + private static final Logger log = LoggerFactory.getLogger(PostService.class); /** * 根据文章ID获取文章详情 @@ -196,13 +194,84 @@ public class PostService { return new Paged<>(dtos,posts.getTotalElements(),posts.getNumber()+1,posts.getSize()); } + /** + * 判断当前用户是对指定文章否已点赞 + * @param postId + * @return + */ public boolean currentUserHasStarred(Long postId){ User user = authService.getCurrentUser(); return postStarRepository.findByUserIdAndPostId(user.getId(), postId).isPresent(); } + /** + * 点赞文章 + * @param postId 文章ID + * @return 如果点赞成功返回true,如果已点过赞则返回false + */ + public boolean toggleStar(long postId){ + // 获取当前用户 + User user = authService.getCurrentUser(); + // 确认文章存在 + Post post = postRepository.findById(postId).orElseThrow(()->new ResourceNotFoundException("Post","id="+postId)); + // 确认用户是否已点赞 + PostStar postStar = postStarRepository.findByUserIdAndPostId(user.getId(),postId).orElse(null); + if(postStar==null){ + // 如果未点赞,则创建点赞记录并更新文章点赞数 + postStar = new PostStar(); + postStar.setPost(post); + postStar.setUser(user); + postStarRepository.save(postStar); + post.setUpvoteCount(post.getUpvoteCount()+1); + postRepository.save(post); + return true; + } + // 如果已点赞,则删除点赞记录并更新文章点赞数 + postStarRepository.delete(postStar); + post.setUpvoteCount(post.getUpvoteCount()-1); + postRepository.save(post); + return false; + } + + /** + * 判断当前用户是否收藏了指定文章 + * @param postId + * @return + */ public boolean currentUserHasCollected(Long postId){ User user = authService.getCurrentUser(); return postCollectionRepository.findByUserIdAndPostId(user.getId(), postId).isPresent(); } + + /** + * 切换帖子的收藏状态。 + * 如果用户还未收藏该帖子,则收藏它,并增加帖子的收藏计数;如果已经收藏,则取消收藏,并减少帖子的收藏计数。 + * + * @param postId 帖子的ID。 + * @return 如果收藏状态切换成功返回true,如果之前已经是取消收藏的状态则返回false。 + */ + public boolean toggleCollection(Long postId){ + // 获取当前用户 + User user = authService.getCurrentUser(); + // 查找帖子,如果找不到则抛出异常 + Post post = postRepository.findById(postId).orElseThrow(()->new ResourceNotFoundException("Post","id="+postId)); + // 查找对应的收藏记录,如果不存在则返回null + PostCollection collection = postCollectionRepository.findByUserIdAndPostId(user.getId(), postId).orElse(null); + if(collection==null){ + // 创建新的收藏记录并保存 + collection = new PostCollection(); + collection.setPost(post); + collection.setUser(user); + postCollectionRepository.save(collection); + // 更新帖子的收藏计数 + post.setUpvoteCount(post.getCollectionCount()+1); + postRepository.save(post); + return true; + } + // 如果已经存在收藏记录,则删除收藏记录,并更新帖子的收藏计数 + postCollectionRepository.delete(collection); + post.setCollectionCount(post.getCollectionCount()-1); + postRepository.save(post); + return false; + } }