feat(web): 新增博客首页文章、分类、标签及博客设置相关接口
- 新增ArticleController提供首页文章分页查询接口 - 实现ArticleService及其实现类,支持分页查询文章及其分类标签关联信息 - 扩展ArticleCategoryRelRepository和ArticleTagRelRepository,支持批量查询文章关联分类和标签 - 新增CategoryController及CategoryService,实现前台分类列表查询接口 - 新增TagController及TagService,实现前台标签列表查询接口 - 新增BlogSettingsController及BlogSettingsService,支持博客配置信息查询 - 添加相应的请求响应VO,包含文章、分类、标签及博客设置数据结构 - 移除无用的User模型代码,简化项目结构
This commit is contained in:
1
.idea/ApifoxUploaderProjectSetting.xml
generated
1
.idea/ApifoxUploaderProjectSetting.xml
generated
@@ -5,6 +5,7 @@
|
||||
<option name="apiProjectIds">
|
||||
<array>
|
||||
<option value="<byte-array>rO0ABXNyADZjb20uaXRhbmdjZW50LmlkZWEucGx1Z2luLmFwaS5hY2NvdW50LlByb2plY3RBbmRNb2R1bGUAAAAAAAAAAQIAFVoABmVuYWJsZUwACG1vZHVsZUlkdAASTGphdmEvbGFuZy9TdHJpbmc7TAAGb3RoZXIxcQB+AAFMAAdvdGhlcjEwcQB+AAFMAAdvdGhlcjExcQB+AAFMAAdvdGhlcjEycQB+AAFMAAZvdGhlcjJxAH4AAUwABm90aGVyM3EAfgABTAAGb3RoZXI0cQB+AAFMAAZvdGhlcjVxAH4AAUwABm90aGVyNnEAfgABTAAGb3RoZXI3cQB+AAFMAAZvdGhlcjhxAH4AAUwABm90aGVyOXEAfgABTAAKcGF0aEJlZm9yZXEAfgABTAANcHJvamVjdEZvbGRlcnEAfgABTAAPcHJvamVjdEZvbGRlcklkcQB+AAFMAAlwcm9qZWN0SWRxAH4AAUwAC3Byb2plY3ROYW1lcQB+AAFMAAxzY2hlbWFGb2xkZXJxAH4AAUwACHNjaGVtYUlkcQB+AAF4cAF0ACp3ZWJsb2ctc3ByaW5nYm9vdC53ZWJsb2ctbW9kdWxlLWFkbWluLm1haW50AAc3MjIwMjQ1cHBwdAAHNjY1NzM5NHQAC2JyYW5jaC1tYWludAAM6buY6K6k5qih5Z2XcHBwcHB0AAB0AAnmoLnnm67lvZV0AAEwdAAHNzQ4NDkxM3QABVdCbG9ncQB+AAlxAH4ACg==</byte-array>" />
|
||||
<option value="<byte-array>rO0ABXNyADZjb20uaXRhbmdjZW50LmlkZWEucGx1Z2luLmFwaS5hY2NvdW50LlByb2plY3RBbmRNb2R1bGUAAAAAAAAAAQIAFVoABmVuYWJsZUwACG1vZHVsZUlkdAASTGphdmEvbGFuZy9TdHJpbmc7TAAGb3RoZXIxcQB+AAFMAAdvdGhlcjEwcQB+AAFMAAdvdGhlcjExcQB+AAFMAAdvdGhlcjEycQB+AAFMAAZvdGhlcjJxAH4AAUwABm90aGVyM3EAfgABTAAGb3RoZXI0cQB+AAFMAAZvdGhlcjVxAH4AAUwABm90aGVyNnEAfgABTAAGb3RoZXI3cQB+AAFMAAZvdGhlcjhxAH4AAUwABm90aGVyOXEAfgABTAAKcGF0aEJlZm9yZXEAfgABTAANcHJvamVjdEZvbGRlcnEAfgABTAAPcHJvamVjdEZvbGRlcklkcQB+AAFMAAlwcm9qZWN0SWRxAH4AAUwAC3Byb2plY3ROYW1lcQB+AAFMAAxzY2hlbWFGb2xkZXJxAH4AAUwACHNjaGVtYUlkcQB+AAF4cAF0ACF3ZWJsb2ctc3ByaW5nYm9vdC53ZWJsb2ctd2ViLm1haW50AAc3MjIwMjQ1cHBwdAAHNjY1NzM5NHQAC2JyYW5jaC1tYWludAAM6buY6K6k5qih5Z2XcHBwcHB0AAB0AAnmoLnnm67lvZV0AAEwdAAHNzQ4NDkxM3QABVdCbG9ncQB+AAlxAH4ACg==</byte-array>" />
|
||||
</array>
|
||||
</option>
|
||||
<option name="treeNodes" value="<byte-array>rO0ABXNyABdqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDTATlwQbMD7AgABWgALYWNjZXNzT3JkZXJ4cgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAnQABzM0MjU5MzBzcgAuY29tLml0YW5nY2VudC5pZGVhLnBsdWdpbi5hcGkuYWNjb3VudC5UcmVlTm9kZQAAAAAAAAABAgAQTAAHYWxsUGF0aHQAEkxqYXZhL2xhbmcvU3RyaW5nO1sAFGJyYW5jaEFuZFZlcnNpb25JdGVtdABLW0xjb20vaXRhbmdjZW50L2lkZWEvcGx1Z2luL2RpYWxvZy9jb21wb25lbnQvYWNjb3VudC9BY2NvdW50UmlnaHRQYW5lbEl0ZW07TAAUYnJhbmNoSWRBbmRWZXJzaW9uSWRxAH4ABUwACGNoaWxkcmVudAAPTGphdmEvdXRpbC9NYXA7TAAKZm9sZGVyVHlwZXEAfgAFTAAIZnVsbFBhdGhxAH4ABUwAA2tleXEAfgAFWwAJbW9kZWxJdGVtcQB+AAZMAAhtb2R1bGVJZHEAfgAFTAAEbmFtZXEAfgAFTAAIcGFyZW50SWRxAH4ABUwACXByb2plY3RJZHEAfgAFTAALcHJvamVjdE5hbWVxAH4ABUwABnRlYW1JZHEAfgAFTAAIdGVhbU5hbWVxAH4ABUwABHR5cGV0ADBMY29tL2l0YW5nY2VudC9pZGVhL3BsdWdpbi9hcGkvYWNjb3VudC9Ob2RlVHlwZTt4cHQADOS4quS6uuWboumYn3Bwc3EAfgAAP0AAAAAAAAx3CAAAABAAAAABdAAHNzQ4NDkxM3NxAH4ABHQAEuS4quS6uuWboumYny9XQmxvZ3Bwc3EAfgAAP0AAAAAAAAB3CAAAABAAAAAAeABwcHEAfgAMcHB0AA9XQmxvZyAoNzQ4NDkxMyl0AAczNDI1OTMwcQB+AAx0AAVXQmxvZ3EAfgARcH5yAC5jb20uaXRhbmdjZW50LmlkZWEucGx1Z2luLmFwaS5hY2NvdW50Lk5vZGVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAHUFJPSkVDVHgAcHBxAH4AA3BwcQB+AApwcHBxAH4AA3EAfgAKfnEAfgATdAAEVEVBTXQABzM5NjY0MDlzcQB+AAR0AAlIYW5zZXJEZXZwcHNxAH4AAD9AAAAAAAAMdwgAAAAQAAAAAXQABzc0NjI0NzJzcQB+AAR0ABlIYW5zZXJEZXYvSU4tQUktaW50ZXJ2aWV3cHBzcQB+AAA/QAAAAAAAAHcIAAAAEAAAAAB4AHBwcQB+AB1wcHQAGUlOLUFJLWludGVydmlldyAoNzQ2MjQ3Mil0AAczOTY2NDA5cQB+AB10AA9JTi1BSS1pbnRlcnZpZXdxAH4AInBxAH4AFXgAcHBxAH4AGXBwcQB+ABtwcHBxAH4AGXEAfgAbcQB+ABd4AA==</byte-array>" />
|
||||
|
||||
@@ -17,4 +17,6 @@ public interface ArticleCategoryRelRepository extends JpaRepository<ArticleCateg
|
||||
ArticleCategoryRel findByArticleId(Long articleId);
|
||||
|
||||
List<ArticleCategoryRel> findByCategoryId(Long categoryId);
|
||||
|
||||
List<ArticleCategoryRel> findByArticleIdIn(List<Long> articleIds);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface ArticleTagRelRepository extends JpaRepository<ArticleTagRel, Long> {
|
||||
@@ -16,4 +17,6 @@ public interface ArticleTagRelRepository extends JpaRepository<ArticleTagRel, Lo
|
||||
List<ArticleTagRel> findByArticleId(Long articleId);
|
||||
|
||||
List<ArticleTagRel> findByTagId(Long tagId);
|
||||
|
||||
List<ArticleTagRel> findByArticleIdIn(Collection<Long> articleIds);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,13 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface CategoryRepository extends JpaRepository<Category, Long>, JpaSpecificationExecutor<Category> {
|
||||
boolean existsCategoryByName(String name);
|
||||
|
||||
Page<Category> findAll(Specification<Category> specification, Pageable pageable);
|
||||
|
||||
List<Category> findAllByIdIn(Collection<Long> ids);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.hanserwei.web.controller;
|
||||
|
||||
import com.hanserwei.common.aspect.ApiOperationLog;
|
||||
import com.hanserwei.common.utils.PageResponse;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListReqVO;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListRspVO;
|
||||
import com.hanserwei.web.service.ArticleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 文章控制器
|
||||
*
|
||||
* @author hanserwei
|
||||
*/
|
||||
@RestController
|
||||
public class ArticleController {
|
||||
|
||||
@Resource
|
||||
private ArticleService articleService;
|
||||
|
||||
/**
|
||||
* 获取首页文章分页数据
|
||||
*/
|
||||
@PostMapping("/article/list")
|
||||
@ApiOperationLog(description = "获取首页文章分页数据")
|
||||
public PageResponse<FindIndexArticlePageListRspVO> findArticlePageList(@RequestBody FindIndexArticlePageListReqVO findIndexArticlePageListReqVO) {
|
||||
return articleService.findArticlePageList(findIndexArticlePageListReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.hanserwei.web.controller;
|
||||
|
||||
import com.hanserwei.common.aspect.ApiOperationLog;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.blogsetting.FindBlogSettingsDetailRspVO;
|
||||
import com.hanserwei.web.service.BlogSettingsService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 博客设置控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/blog/settings")
|
||||
public class BlogSettingsController {
|
||||
|
||||
@Resource
|
||||
private BlogSettingsService blogSettingsService;
|
||||
|
||||
/**
|
||||
* 获取博客设置详情
|
||||
*/
|
||||
@PostMapping("/detail")
|
||||
@ApiOperationLog(description = "前台获取博客详情")
|
||||
public Response<FindBlogSettingsDetailRspVO> findDetail() {
|
||||
return blogSettingsService.findDetail();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.hanserwei.web.controller;
|
||||
|
||||
import com.hanserwei.common.aspect.ApiOperationLog;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.category.FindCategoryListRspVO;
|
||||
import com.hanserwei.web.service.CategoryService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分类控制器
|
||||
*
|
||||
* @author hanserwei
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/category")
|
||||
public class CategoryController {
|
||||
|
||||
@Resource
|
||||
private CategoryService categoryService;
|
||||
|
||||
/**
|
||||
* 前台获取分类列表
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
@ApiOperationLog(description = "前台获取分类列表")
|
||||
public Response<List<FindCategoryListRspVO>> findCategoryList() {
|
||||
return categoryService.findCategoryList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.hanserwei.web.controller;
|
||||
|
||||
import com.hanserwei.common.aspect.ApiOperationLog;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.tag.FindTagListRspVO;
|
||||
import com.hanserwei.web.service.TagService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 标签控制器
|
||||
*
|
||||
* @author hanserwei
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/tag")
|
||||
public class TagController {
|
||||
|
||||
@Resource
|
||||
private TagService tagService;
|
||||
|
||||
/**
|
||||
* 获取标签列表
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
@ApiOperationLog(description = "前台获取标签列表")
|
||||
public Response<List<FindTagListRspVO>> findTagList() {
|
||||
return tagService.findTagList();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.hanserwei.web.model;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class User {
|
||||
// 用户名
|
||||
@NotBlank(message = "用户名不能为空") // 注解确保用户名不为空
|
||||
private String username;
|
||||
// 性别
|
||||
@NotNull(message = "性别不能为空") // 注解确保性别不为空
|
||||
private Integer sex;
|
||||
|
||||
// 年龄
|
||||
@NotNull(message = "年龄不能为空")
|
||||
@Min(value = 18, message = "年龄必须大于或等于 18") // 注解确保年龄大于等于 18
|
||||
@Max(value = 100, message = "年龄必须小于或等于 100") // 注解确保年龄小于等于 100
|
||||
private Integer age;
|
||||
|
||||
// 邮箱
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
@Email(message = "邮箱格式不正确") // 注解确保邮箱格式正确
|
||||
private String email;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.hanserwei.web.model.vo.article;
|
||||
|
||||
import com.hanserwei.common.model.BasePageQuery;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Builder
|
||||
public class FindIndexArticlePageListReqVO extends BasePageQuery {
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.hanserwei.web.model.vo.article;
|
||||
|
||||
import com.hanserwei.web.model.vo.category.FindCategoryListRspVO;
|
||||
import com.hanserwei.web.model.vo.tag.FindTagListRspVO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class FindIndexArticlePageListRspVO {
|
||||
/**
|
||||
* 文章id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 封面url
|
||||
*/
|
||||
private String cover;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 摘要
|
||||
*/
|
||||
private String summary;
|
||||
/**
|
||||
* 文章分类
|
||||
*/
|
||||
private FindCategoryListRspVO category;
|
||||
|
||||
/**
|
||||
* 文章标签
|
||||
*/
|
||||
private List<FindTagListRspVO> tags;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.hanserwei.web.model.vo.blogsetting;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
|
||||
/*
|
||||
* 博客设置详情响应VO
|
||||
*/
|
||||
public class FindBlogSettingsDetailRspVO {
|
||||
/**
|
||||
* 博客Logo
|
||||
*/
|
||||
private String logo;
|
||||
/**
|
||||
* 博客名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 作者名称
|
||||
*/
|
||||
private String author;
|
||||
/**
|
||||
* 博客介绍
|
||||
*/
|
||||
private String introduction;
|
||||
/**
|
||||
* 作者头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* GitHub主页
|
||||
*/
|
||||
private String githubHomepage;
|
||||
/**
|
||||
* CSDN主页
|
||||
*/
|
||||
private String csdnHomepage;
|
||||
/**
|
||||
* Gitee主页
|
||||
*/
|
||||
private String giteeHomepage;
|
||||
/**
|
||||
* 知乎主页
|
||||
*/
|
||||
private String zhihuHomepage;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.hanserwei.web.model.vo.category;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class FindCategoryListRspVO {
|
||||
/**
|
||||
* 分类id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 分类名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.hanserwei.web.model.vo.tag;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class FindTagListRspVO {
|
||||
/**
|
||||
* 标签id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 标签名称
|
||||
*/
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.hanserwei.web.service;
|
||||
|
||||
import com.hanserwei.common.utils.PageResponse;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListReqVO;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListRspVO;
|
||||
|
||||
public interface ArticleService {
|
||||
/**
|
||||
* 获取首页文章分页数据
|
||||
*
|
||||
* @param findIndexArticlePageListReqVO 获取首页文章分页数据请求参数
|
||||
* @return 响应
|
||||
*/
|
||||
PageResponse<FindIndexArticlePageListRspVO> findArticlePageList(FindIndexArticlePageListReqVO findIndexArticlePageListReqVO);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.hanserwei.web.service;
|
||||
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.blogsetting.FindBlogSettingsDetailRspVO;
|
||||
|
||||
public interface BlogSettingsService {
|
||||
/**
|
||||
* 获取博客设置信息
|
||||
*
|
||||
* @return 响应
|
||||
*/
|
||||
Response<FindBlogSettingsDetailRspVO> findDetail();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.hanserwei.web.service;
|
||||
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.category.FindCategoryListRspVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CategoryService {
|
||||
/**
|
||||
* 获取分类列表
|
||||
*
|
||||
* @return 分类列表
|
||||
*/
|
||||
Response<List<FindCategoryListRspVO>> findCategoryList();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.hanserwei.web.service;
|
||||
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.tag.FindTagListRspVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TagService {
|
||||
/**
|
||||
* 获取标签列表
|
||||
*
|
||||
* @return 标签列表
|
||||
*/
|
||||
Response<List<FindTagListRspVO>> findTagList();
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.hanserwei.web.service.impl;
|
||||
|
||||
import com.hanserwei.common.domain.dataobject.*;
|
||||
import com.hanserwei.common.domain.repository.*;
|
||||
import com.hanserwei.common.utils.PageHelper;
|
||||
import com.hanserwei.common.utils.PageResponse;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListReqVO;
|
||||
import com.hanserwei.web.model.vo.article.FindIndexArticlePageListRspVO;
|
||||
import com.hanserwei.web.model.vo.category.FindCategoryListRspVO;
|
||||
import com.hanserwei.web.model.vo.tag.FindTagListRspVO;
|
||||
import com.hanserwei.web.service.ArticleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ArticleServiceImpl implements ArticleService {
|
||||
@Resource
|
||||
private ArticleRepository articleRepository;
|
||||
@Resource
|
||||
private CategoryRepository categoryRepository;
|
||||
@Resource
|
||||
private ArticleContentRepository articleContentRepository;
|
||||
@Resource
|
||||
private ArticleCategoryRelRepository articleCategoryRelRepository;
|
||||
@Resource
|
||||
private TagRepository tagRepository;
|
||||
@Resource
|
||||
private ArticleTagRelRepository articleTagRelRepository;
|
||||
|
||||
@Override
|
||||
public PageResponse<FindIndexArticlePageListRspVO> findArticlePageList(FindIndexArticlePageListReqVO findIndexArticlePageListReqVO) {
|
||||
// 查询文章主体数据
|
||||
PageResponse<Article> articlePageResponse = PageHelper.findPageList(articleRepository,
|
||||
findIndexArticlePageListReqVO,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
e -> e);
|
||||
List<Article> articleList = articlePageResponse.getData();
|
||||
List<FindIndexArticlePageListRspVO> vos = null;
|
||||
if (!CollectionUtils.isEmpty(articleList)) {
|
||||
vos = articleList.stream().map(e -> {
|
||||
FindIndexArticlePageListRspVO vo = new FindIndexArticlePageListRspVO();
|
||||
BeanUtils.copyProperties(e, vo);
|
||||
// 手动设置 createTime,因为 Instant 无法自动转换为 LocalDateTime
|
||||
if (e.getCreateTime() != null) {
|
||||
vo.setCreateTime(java.time.LocalDateTime.ofInstant(e.getCreateTime(), java.time.ZoneId.systemDefault()));
|
||||
}
|
||||
return vo;
|
||||
}).toList();
|
||||
// 拿到所有文章的 ID 集合
|
||||
List<Long> articleIds = articleList.stream().map(Article::getId).toList();
|
||||
|
||||
// 第二步:设置文章所属分类
|
||||
// 根据文章 ID 批量查询所有关联记录
|
||||
List<ArticleCategoryRel> articleCategoryRelList = articleCategoryRelRepository.findByArticleIdIn(articleIds);
|
||||
// 获取所有分类ID
|
||||
List<Long> categoryIds = articleCategoryRelList.stream()
|
||||
.map(ArticleCategoryRel::getCategoryId)
|
||||
.distinct()
|
||||
.toList();
|
||||
// 查询所有分类
|
||||
List<Category> categories = categoryRepository.findAllByIdIn(categoryIds);
|
||||
// 转 Map, 方便后续根据分类 ID 拿到对应的分类名称
|
||||
Map<Long, String> categoryIdNameMap = categories.stream().collect(Collectors.toMap(Category::getId, Category::getName));
|
||||
|
||||
vos.forEach(vo -> {
|
||||
Long currentArticleId = vo.getId();
|
||||
// 过滤出当前文章对应的关联数据
|
||||
Optional<ArticleCategoryRel> optional = articleCategoryRelList.stream()
|
||||
.filter(e -> Objects.equals(e.getArticleId(), currentArticleId))
|
||||
.findAny();
|
||||
// 如果不为空
|
||||
if (optional.isPresent()) {
|
||||
ArticleCategoryRel articleCategoryRel = optional.get();
|
||||
Long categoryId = articleCategoryRel.getCategoryId();
|
||||
// 通过分类 ID 从 map 中拿到对应的分类名称
|
||||
String categoryName = categoryIdNameMap.get(categoryId);
|
||||
FindCategoryListRspVO findCategoryListRspVO = FindCategoryListRspVO.builder()
|
||||
.id(categoryId)
|
||||
.name(categoryName)
|
||||
.build();
|
||||
// 设置到当前 vo 类中
|
||||
vo.setCategory(findCategoryListRspVO);
|
||||
}
|
||||
});
|
||||
// 第三步:设置文章标签
|
||||
// 查询所有标签
|
||||
List<Tag> allTagList = tagRepository.findAll();
|
||||
// 转 Map, 方便后续根据标签 ID 拿到对应的标签名称
|
||||
Map<Long, String> tagIdNameMap = allTagList.stream().collect(Collectors.toMap(Tag::getId, Tag::getName));
|
||||
// 拿到所有文章的标签关联记录
|
||||
List<ArticleTagRel> articleTagRelList = articleTagRelRepository.findByArticleIdIn(articleIds);
|
||||
vos.forEach(vo -> {
|
||||
Long currentArticleId = vo.getId();
|
||||
// 过滤出当前文章对应的关联标签数据
|
||||
List<ArticleTagRel> currentArticleTagRelList = articleTagRelList.stream()
|
||||
.filter(e -> Objects.equals(e.getArticleId(), currentArticleId))
|
||||
.toList();
|
||||
List<FindTagListRspVO> findTagListRspVOS = new ArrayList<>();
|
||||
// 将关联记录 DO 转 VO, 并设置对应的标签名称
|
||||
currentArticleTagRelList.forEach(e -> {
|
||||
Long tagId = e.getTagId();
|
||||
String tagName = tagIdNameMap.get(tagId);
|
||||
FindTagListRspVO findTagListRspVO = FindTagListRspVO.builder()
|
||||
.id(tagId)
|
||||
.name(tagName)
|
||||
.build();
|
||||
findTagListRspVOS.add(findTagListRspVO);
|
||||
});
|
||||
// 设置转换后的标签数据
|
||||
vo.setTags(findTagListRspVOS);
|
||||
});
|
||||
}
|
||||
PageResponse<FindIndexArticlePageListRspVO> findIndexArticlePageListRspVOPageResponse = new PageResponse<>();
|
||||
BeanUtils.copyProperties(articlePageResponse, findIndexArticlePageListRspVOPageResponse);
|
||||
findIndexArticlePageListRspVOPageResponse.setData(vos);
|
||||
return findIndexArticlePageListRspVOPageResponse;
|
||||
}
|
||||
|
||||
public ArticleContentRepository getArticleContentRepository() {
|
||||
return articleContentRepository;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.hanserwei.web.service.impl;
|
||||
|
||||
import com.hanserwei.common.domain.repository.BlogSettingsRepository;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.blogsetting.FindBlogSettingsDetailRspVO;
|
||||
import com.hanserwei.web.service.BlogSettingsService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BlogSettingsServiceImpl implements BlogSettingsService {
|
||||
|
||||
@Resource
|
||||
private BlogSettingsRepository blogSettingsRepository;
|
||||
|
||||
|
||||
@Override
|
||||
public Response<FindBlogSettingsDetailRspVO> findDetail() {
|
||||
return blogSettingsRepository.findById(1L)
|
||||
.map(e -> {
|
||||
FindBlogSettingsDetailRspVO vo = FindBlogSettingsDetailRspVO.builder()
|
||||
.author(e.getAuthor())
|
||||
.logo(e.getLogo())
|
||||
.name(e.getName())
|
||||
.introduction(e.getIntroduction())
|
||||
.avatar(e.getAvatar())
|
||||
.githubHomepage(e.getGithubHomepage())
|
||||
.csdnHomepage(e.getCsdnHomepage())
|
||||
.giteeHomepage(e.getGiteeHomepage())
|
||||
.zhihuHomepage(e.getZhihuHomepage())
|
||||
.build();
|
||||
return Response.success(vo);
|
||||
})
|
||||
.orElse(Response.success(null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.hanserwei.web.service.impl;
|
||||
|
||||
import com.hanserwei.common.domain.dataobject.Category;
|
||||
import com.hanserwei.common.domain.repository.CategoryRepository;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.category.FindCategoryListRspVO;
|
||||
import com.hanserwei.web.service.CategoryService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CategoryServiceImpl implements CategoryService {
|
||||
|
||||
@Resource
|
||||
private CategoryRepository categoryRepository;
|
||||
|
||||
@Override
|
||||
public Response<List<FindCategoryListRspVO>> findCategoryList() {
|
||||
List<Category> categoryList = categoryRepository.findAll();
|
||||
List<FindCategoryListRspVO> vos = null;
|
||||
if (!CollectionUtils.isEmpty(categoryList)) {
|
||||
vos = categoryList.stream().map(category -> {
|
||||
FindCategoryListRspVO vo = new FindCategoryListRspVO();
|
||||
vo.setId(category.getId());
|
||||
vo.setName(category.getName());
|
||||
return vo;
|
||||
}).toList();
|
||||
}
|
||||
return Response.success(vos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.hanserwei.web.service.impl;
|
||||
|
||||
import com.hanserwei.common.domain.dataobject.Tag;
|
||||
import com.hanserwei.common.domain.repository.TagRepository;
|
||||
import com.hanserwei.common.utils.Response;
|
||||
import com.hanserwei.web.model.vo.tag.FindTagListRspVO;
|
||||
import com.hanserwei.web.service.TagService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class TagServiceImpl implements TagService {
|
||||
|
||||
@Resource
|
||||
private TagRepository tagRepository;
|
||||
|
||||
@Override
|
||||
public Response<List<FindTagListRspVO>> findTagList() {
|
||||
List<Tag> tagList = tagRepository.findAll();
|
||||
List<FindTagListRspVO> tagListVO = null;
|
||||
if (!CollectionUtils.isEmpty(tagList)) {
|
||||
tagListVO = tagList.stream().map(tag -> FindTagListRspVO.builder()
|
||||
.id(tag.getId())
|
||||
.name(tag.getName())
|
||||
.build()).toList();
|
||||
}
|
||||
return Response.success(tagListVO);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user