瀏覽代碼

0805 拆解novel-home 整合openfeign

Qing 10 月之前
父節點
當前提交
d1c9f2f9b1
共有 30 個文件被更改,包括 905 次插入31 次删除
  1. 5 1
      novel-cloud-demo/novel-book/novel-book-api/pom.xml
  2. 18 0
      novel-cloud-demo/novel-book/novel-book-api/src/main/java/com/sf/book/client/BookFeign.java
  3. 116 0
      novel-cloud-demo/novel-book/novel-book-api/src/main/java/com/sf/book/dto/BookInfoRespDto.java
  4. 40 3
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookChapterController.java
  5. 31 2
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookContentController.java
  6. 0 13
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookInfoController.java
  7. 23 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/inner/InnerBookController.java
  8. 29 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookChapterAboutRespDto.java
  9. 66 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookChapterRespDto.java
  10. 35 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookContentAboutRespDto.java
  11. 7 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IBookChapterService.java
  12. 3 1
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IBookContentService.java
  13. 10 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IInnerBookService.java
  14. 84 1
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/BookChapterServiceImpl.java
  15. 79 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/BookContentServiceImpl.java
  16. 34 0
      novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/InnerBookServiceImpl.java
  17. 4 0
      novel-cloud-demo/novel-core/src/main/java/com/sf/core/dto/RestResp.java
  18. 4 1
      novel-cloud-demo/novel-core/src/main/java/com/sf/core/util/GeneUtils.java
  19. 7 0
      novel-cloud-demo/novel-home/pom.xml
  20. 6 1
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/NovelHomeApplication.java
  21. 24 8
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/controller/HomeBookController.java
  22. 18 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/controller/HomeFriendLinkController.java
  23. 57 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/dto/resp/HomeBookRespDto.java
  24. 58 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/entity/HomeFriendLink.java
  25. 16 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/mapper/HomeFriendLinkMapper.java
  26. 4 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/IHomeBookService.java
  27. 16 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/IHomeFriendLinkService.java
  28. 86 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/impl/HomeBookServiceImpl.java
  29. 20 0
      novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/impl/HomeFriendLinkServiceImpl.java
  30. 5 0
      novel-cloud-demo/novel-home/src/main/resources/mapper/HomeFriendLinkMapper.xml

+ 5 - 1
novel-cloud-demo/novel-book/novel-book-api/pom.xml

@@ -18,6 +18,10 @@
     </properties>
 
     <dependencies>
-
+        <dependency>
+            <groupId>com.sf</groupId>
+            <artifactId>novel-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>

+ 18 - 0
novel-cloud-demo/novel-book/novel-book-api/src/main/java/com/sf/book/client/BookFeign.java

@@ -0,0 +1,18 @@
+package com.sf.book.client;
+
+import com.sf.book.dto.BookInfoRespDto;
+import com.sf.core.dto.RestResp;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+// 把feign的客户端写在api
+@FeignClient("novel-book-service")
+public interface BookFeign {
+
+    @PostMapping("/api/inner/book/listBookInfoByIds")
+    RestResp<List<BookInfoRespDto>> listBookInfoByIds(List<Long> bookIds);
+}

+ 116 - 0
novel-cloud-demo/novel-book/novel-book-api/src/main/java/com/sf/book/dto/BookInfoRespDto.java

@@ -0,0 +1,116 @@
+package com.sf.book.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class BookInfoRespDto {
+
+    /**
+     * ID
+     */
+    @Schema(description = "小说ID")
+    private Long id;
+
+    /**
+     * 类别ID
+     */
+    @Schema(description = "类别ID")
+    private Long categoryId;
+
+    /**
+     * 类别名
+     */
+    @Schema(description = "类别名")
+    private String categoryName;
+
+    /**
+     * 小说封面地址
+     */
+    @Schema(description = "小说封面地址")
+    private String picUrl;
+
+    /**
+     * 小说名
+     */
+    @Schema(description = "小说名")
+    private String bookName;
+
+    /**
+     * 作家id
+     */
+    @Schema(description = "作家id")
+    private Long authorId;
+
+    /**
+     * 作家名
+     */
+    @Schema(description = "作家名")
+    private String authorName;
+
+    /**
+     * 书籍描述
+     */
+    @Schema(description = "书籍描述")
+    private String bookDesc;
+
+    /**
+     * 书籍状态;0-连载中 1-已完结
+     */
+    @Schema(description = "书籍状态;0-连载中 1-已完结")
+    private Integer bookStatus;
+
+    /**
+     * 点击量
+     */
+    @Schema(description = "点击量")
+    private Long visitCount;
+
+    /**
+     * 总字数
+     */
+    @Schema(description = "总字数")
+    private Integer wordCount;
+
+    /**
+     * 评论数
+     */
+    @Schema(description = "评论数")
+    private Integer commentCount;
+
+    /**
+     * 首章节ID
+     */
+    @Schema(description = "首章节ID")
+    private Long firstChapterId;
+
+    /**
+     * 最新章节ID
+     */
+    @Schema(description = "最新章节ID")
+    private Long lastChapterId;
+
+    /**
+     * 最新章节名
+     */
+    @Schema(description = "最新章节名")
+    private String lastChapterName;
+
+    /**
+     * 最新章节更新时间
+     */
+    @Schema(description = "最新章节更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    private LocalDateTime updateTime;
+
+
+}

+ 40 - 3
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookChapterController.java

@@ -1,7 +1,20 @@
 package com.sf.book.controller;
 
+import com.sf.book.dto.resp.BookChapterAboutRespDto;
+import com.sf.book.dto.resp.BookChapterRespDto;
+import com.sf.book.service.IBookChapterService;
+import com.sf.core.dto.RestResp;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
 
 /**
  * <p>
@@ -11,8 +24,32 @@ import org.springframework.stereotype.Controller;
  * @author baomidou
  * @since 2024-08-05
  */
-@Controller
-@RequestMapping("/bookChapter")
+@Tag(name = "BookChapterController", description = "书籍章节模块")
+@RestController
 public class BookChapterController {
 
-}
+    @Autowired
+    private IBookChapterService bookChapterService;
+
+    // http://127.0.0.1:8900/api/front/book/chapter/list?bookId=1337872597996539904
+    // @RequestParam注解 用于从请求参数中获取参数
+    @Operation(summary = "章节列表接口")
+    @GetMapping("/api/front/book/chapter/list")
+    public RestResp<List<BookChapterRespDto>> listChapters(
+            @Parameter(description = "书籍id") @RequestParam("bookId") Long bookId){
+        // 根据传进来的参数 bookId 去查询对应书籍的章节信息
+        List<BookChapterRespDto> chapterRespDtos = bookChapterService.getBookChapterByBookId(bookId);
+        return RestResp.ok(chapterRespDtos);
+    }
+
+
+    // 最新章节请求
+    // http://127.0.0.1:8900/api/front/book/last_chapter/about?bookId=1431630596354977794
+    @Operation(summary = "最新章节接口")
+    @GetMapping("/api/front/book/last_chapter/about")
+    public RestResp<BookChapterAboutRespDto> lastChapterAbout(@RequestParam("bookId") Long bookId) {
+        BookChapterAboutRespDto chapterAboutRespDto = bookChapterService.lastChapterAbout(bookId);
+        return RestResp.ok(chapterAboutRespDto);
+    }
+
+}

+ 31 - 2
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookContentController.java

@@ -1,7 +1,16 @@
 package com.sf.book.controller;
 
+import com.sf.book.dto.resp.BookContentAboutRespDto;
+import com.sf.book.service.IBookContentService;
+import com.sf.core.dto.RestResp;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
@@ -11,8 +20,28 @@ import org.springframework.stereotype.Controller;
  * @author baomidou
  * @since 2024-08-05
  */
-@Controller
-@RequestMapping("/bookContent")
+@Tag(name = "BookContentController", description = "章节内容模块")
+@RestController
 public class BookContentController {
 
+    @Autowired
+    private IBookContentService bookContentService;
+
+    // http://127.0.0.1:8900/api/front/book/content/1445988184596992002  真正的请求
+    // http://127.0.0.1:8888/api/front/book/content/{chapterId}  请求接口的声明
+    // 当请求的参数在url中时,使用@PathVariable注解 注解会从{}所在的位置提取参数
+    // 编写功能的思路
+    // 明确接口的路径和参数接收方式(controller层) -> 明确接口的返回结果(controller层 -> 明确实现的逻辑(service层)
+
+    // 所有返回结果都是RestResp  不同的是 其中data的类型  所有的data都是dto(data transfer object 数据传输对象)
+    // 当实体类和dto大致相同时  也不能返回实体类本身  因为实体类是对应数据库中的表  而dto是对外提供的接口
+    // 复杂的接口  不会只对应一张表中的数据  而是将多张表中查询的数据进行组合
+    @Operation(summary = "获取章节内容接口")
+    @GetMapping("/api/front/book/content/{chapterId}")
+    public RestResp<BookContentAboutRespDto> getBookContentAbout(
+            @PathVariable("chapterId") Long chapterId) {
+        // controller打包service层的处理结果
+        BookContentAboutRespDto bookContentAbout = bookContentService.getBookContentAbout(chapterId);
+        return RestResp.ok(bookContentAbout);
+    }
 }

+ 0 - 13
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/BookInfoController.java

@@ -4,18 +4,14 @@ import com.sf.book.dto.req.BookSearchReqDto;
 import com.sf.book.dto.req.BookVisitReqDto;
 import com.sf.book.dto.resp.BookCategoryRespDto;
 import com.sf.book.dto.resp.BookInfoRespDto;
-import com.sf.book.service.IBookChapterService;
 import com.sf.book.service.IBookInfoService;
 import com.sf.core.dto.PageRespDto;
 import com.sf.core.dto.RestResp;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.stereotype.Controller;
 
 import java.util.List;
 
@@ -89,15 +85,6 @@ public class BookInfoController {
     }
 
 
-    // 最新章节请求
-    // http://127.0.0.1:8888/api/front/book/last_chapter/about?bookId=1431630596354977794
-//    @Operation(summary = "最新章节接口")
-//    @GetMapping("/api/front/book/last_chapter/about")
-//    public RestResp<BookChapterAboutRespDto> lastChapterAbout(@RequestParam("bookId") Long bookId) {
-//        BookChapterAboutRespDto chapterAboutRespDto = bookChapterService.lastChapterAbout(bookId);
-//        return RestResp.ok(chapterAboutRespDto);
-//    }
-
     @Operation(summary = "增加小说点击量接口")
     @PostMapping("/api/front/book/visit")
     public RestResp<Void> addVisitCount(@Parameter(description = "小说ID")

+ 23 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/controller/inner/InnerBookController.java

@@ -0,0 +1,23 @@
+package com.sf.book.controller.inner;
+
+import com.sf.book.dto.resp.BookInfoRespDto;
+import com.sf.book.service.IInnerBookService;
+import com.sf.core.dto.RestResp;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+// 提供给内部微服务调用的控制器
+@RestController
+@RequiredArgsConstructor
+public class InnerBookController {
+
+    private final IInnerBookService innerBookService;
+
+    @PostMapping("/api/inner/book/listBookInfoByIds")
+    public RestResp<List<BookInfoRespDto>> listBookInfoByIds(@RequestBody List<Long> bookIds) {
+        List<BookInfoRespDto> bookInfoRespDtos = innerBookService.listBookInfoByIds(bookIds);
+        return RestResp.ok(bookInfoRespDtos);
+    }
+}

+ 29 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookChapterAboutRespDto.java

@@ -0,0 +1,29 @@
+package com.sf.book.dto.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class BookChapterAboutRespDto {
+
+    private BookChapterRespDto chapterInfo;
+
+    /**
+     * 章节总数
+     */
+    @Schema(description = "章节总数")
+    private Long chapterTotal;
+
+    /**
+     * 内容概要(30字)
+     */
+    @Schema(description = " 内容概要(30字)")
+    private String contentSummary;
+
+}

+ 66 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookChapterRespDto.java

@@ -0,0 +1,66 @@
+package com.sf.book.dto.resp;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BookChapterRespDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 章节ID
+     */
+    @Schema(description = "章节ID")
+    private Long id;
+
+    /**
+     * 小说ID
+     */
+    @Schema(description = "小说ID")
+    private Long bookId;
+
+    /**
+     * 章节号
+     */
+    @Schema(description = "章节号")
+    private Integer chapterNum;
+
+    /**
+     * 章节名
+     */
+    @Schema(description = "章节名")
+    private String chapterName;
+
+    /**
+     * 章节字数
+     */
+    @Schema(description = "章节字数")
+    private Integer chapterWordCount;
+
+    /**
+     * 章节更新时间
+     */
+    @Schema(description = "章节更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    private LocalDateTime chapterUpdateTime;
+
+    /**
+     * 是否收费;1-收费 0-免费
+     */
+    @Schema(description = "是否收费;1-收费 0-免费")
+    private Integer isVip;
+
+}

+ 35 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/dto/resp/BookContentAboutRespDto.java

@@ -0,0 +1,35 @@
+package com.sf.book.dto.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 小说内容相关 响应DTO
+ *
+ * @author xiongxiaoyang
+ * @date 2022/5/15
+ */
+@Data
+@Builder
+public class BookContentAboutRespDto {
+
+    /**
+     * 小说信息  book_info表中获取的信息
+     */
+    @Schema(description = "小说信息")
+    private BookInfoRespDto bookInfo;
+
+    /**
+     * 章节信息 book_chapter表中获取的信息
+     */
+    @Schema(description = "章节信息")
+    private BookChapterRespDto chapterInfo;
+
+    /**
+     * 章节内容 book_content表中获取的信息
+     */
+    @Schema(description = "章节内容")
+    private String bookContent;
+
+}

+ 7 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IBookChapterService.java

@@ -1,8 +1,12 @@
 package com.sf.book.service;
 
+import com.sf.book.dto.resp.BookChapterAboutRespDto;
+import com.sf.book.dto.resp.BookChapterRespDto;
 import com.sf.book.entity.BookChapter;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * <p>
  * 小说章节 服务类
@@ -13,4 +17,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IBookChapterService extends IService<BookChapter> {
 
+    List<BookChapterRespDto> getBookChapterByBookId(Long bookId);
+
+    BookChapterAboutRespDto lastChapterAbout(Long bookId);
 }

+ 3 - 1
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IBookContentService.java

@@ -1,5 +1,6 @@
 package com.sf.book.service;
 
+import com.sf.book.dto.resp.BookContentAboutRespDto;
 import com.sf.book.entity.BookContent;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -12,5 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @since 2024-08-05
  */
 public interface IBookContentService extends IService<BookContent> {
-
+    BookContentAboutRespDto getBookContentAbout(Long chapterId);
 }
+

+ 10 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/IInnerBookService.java

@@ -0,0 +1,10 @@
+package com.sf.book.service;
+
+import com.sf.book.dto.resp.BookInfoRespDto;
+
+import java.util.List;
+
+public interface IInnerBookService {
+
+    List<BookInfoRespDto> listBookInfoByIds(List<Long> bookIds);
+}

+ 84 - 1
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/BookChapterServiceImpl.java

@@ -1,11 +1,21 @@
 package com.sf.book.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sf.book.dto.resp.BookChapterAboutRespDto;
+import com.sf.book.dto.resp.BookChapterRespDto;
 import com.sf.book.entity.BookChapter;
+import com.sf.book.entity.BookContent;
 import com.sf.book.mapper.BookChapterMapper;
+import com.sf.book.mapper.BookContentMapper;
 import com.sf.book.service.IBookChapterService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * <p>
  * 小说章节 服务实现类
@@ -17,4 +27,77 @@ import org.springframework.stereotype.Service;
 @Service
 public class BookChapterServiceImpl extends ServiceImpl<BookChapterMapper, BookChapter> implements IBookChapterService {
 
-}
+    @Autowired
+    private BookChapterMapper bookChapterMapper;
+
+    @Autowired
+    private BookContentMapper bookContentMapper;
+
+    @Override
+    public List<BookChapterRespDto> getBookChapterByBookId(Long bookId) {
+        // select * from book_chapter where book_id = '';
+        LambdaQueryWrapper<BookChapter> queryWrapper = new LambdaQueryWrapper();
+        queryWrapper.eq(BookChapter::getBookId, bookId);
+        List<BookChapter> bookChapters = bookChapterMapper.selectList(queryWrapper);
+        // 使用普通的方式转换成DTO
+        List<BookChapterRespDto> chapterRespDtos = new ArrayList<>();
+        bookChapters.forEach(bookChapter -> {
+            BookChapterRespDto chapterRespDto = new BookChapterRespDto();
+            BeanUtils.copyProperties(bookChapter, chapterRespDto);
+            // 补充不同名的属性
+            chapterRespDto.setChapterUpdateTime(bookChapter.getUpdateTime());
+            chapterRespDtos.add(chapterRespDto);
+        });
+        // stream流的写法
+        List<BookChapterRespDto> chapterRespDtos2 = bookChapters.stream().map(bookChapter -> {
+            return BookChapterRespDto.builder()
+                    .id(bookChapter.getId())
+                    .bookId(bookChapter.getBookId())
+                    .chapterName(bookChapter.getChapterName())
+                    .chapterNum(bookChapter.getChapterNum())
+                    .chapterWordCount(bookChapter.getWordCount())
+                    .chapterUpdateTime(bookChapter.getUpdateTime())
+                    .isVip(bookChapter.getIsVip().intValue())
+                    .build();
+        }).toList();
+        return chapterRespDtos2;
+    }
+
+
+    @Override
+    public BookChapterAboutRespDto lastChapterAbout(Long bookId) {
+        // 1 通过book_info表中的last_chapter_id返回
+        // 2 直接通过book_chapter表中查询
+        // select count(*) from book_chapter where book_id='1334318182169681920'
+        // select * from book_chapter where book_id='1334318182169681920' and chapter_num=48
+        LambdaQueryWrapper<BookChapter> queryWrapper = new LambdaQueryWrapper();
+        queryWrapper.eq(BookChapter::getBookId, bookId);
+        Long count = bookChapterMapper.selectCount(queryWrapper);
+
+        BookChapterAboutRespDto chapterAboutRespDto = new BookChapterAboutRespDto();
+        if (count > 0) {
+            queryWrapper.eq(BookChapter::getChapterNum, count - 1);
+            BookChapter bookChapter = bookChapterMapper.selectOne(queryWrapper);
+            BookChapterRespDto chapterRespDto = BookChapterRespDto.builder()
+                    .id(bookChapter.getId())
+                    .bookId(bookChapter.getBookId())
+                    .chapterName(bookChapter.getChapterName())
+                    .chapterNum(bookChapter.getChapterNum())
+                    .chapterWordCount(bookChapter.getWordCount())
+                    .chapterUpdateTime(bookChapter.getUpdateTime())
+                    .isVip(bookChapter.getIsVip().intValue())
+                    .build();
+            chapterAboutRespDto.setChapterInfo(chapterRespDto);
+
+            // 设置内容概要
+            LambdaQueryWrapper<BookContent> contentQueryWrapper = new LambdaQueryWrapper();
+            contentQueryWrapper.eq(BookContent::getChapterId, bookChapter.getId());
+            BookContent bookContent = bookContentMapper.selectOne(contentQueryWrapper);
+            String subString = bookContent.getContent().substring(0, 30);
+            chapterAboutRespDto.setContentSummary(subString);
+        }
+        chapterAboutRespDto.setChapterTotal(count);
+
+        return chapterAboutRespDto;
+    }
+}

+ 79 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/BookContentServiceImpl.java

@@ -1,9 +1,19 @@
 package com.sf.book.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sf.book.dto.resp.BookChapterRespDto;
+import com.sf.book.dto.resp.BookContentAboutRespDto;
+import com.sf.book.dto.resp.BookInfoRespDto;
+import com.sf.book.entity.BookChapter;
 import com.sf.book.entity.BookContent;
+import com.sf.book.entity.BookInfo;
+import com.sf.book.mapper.BookChapterMapper;
 import com.sf.book.mapper.BookContentMapper;
+import com.sf.book.mapper.BookInfoMapper;
 import com.sf.book.service.IBookContentService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -17,4 +27,73 @@ import org.springframework.stereotype.Service;
 @Service
 public class BookContentServiceImpl extends ServiceImpl<BookContentMapper, BookContent> implements IBookContentService {
 
+    @Autowired
+    private BookInfoMapper bookInfoMapper;
+
+    @Autowired
+    private BookChapterMapper bookChapterMapper;
+
+    @Autowired
+    private BookContentMapper bookContentMapper;
+
+    @Override
+    public BookContentAboutRespDto getBookContentAbout(Long chapterId) {
+        // 在service的具体实现里  先写sql 然后根据sql编写mybatis plus的代码
+        // 查询章节信息
+        // select * from book_chapter where id = 'chapterId';
+        BookChapter bookChapter = bookChapterMapper.selectById(chapterId);
+        BookChapterRespDto bookChapterDto = BookChapterRespDto.builder().build();
+//        BookChapterRespDto bookChapterDto = BookChapterRespDto.builder()
+//                .id(chapterId)
+//                .bookId(bookChapter.getBookId())
+//                .chapterNum(bookChapter.getChapterNum().intValue())
+//                .chapterName(bookChapter.getChapterName())
+//                .chapterWordCount(bookChapter.getWordCount())
+//                .chapterUpdateTime(bookChapter.getUpdateTime())
+//                .isVip(bookChapter.getIsVip().intValue())
+//                .build();
+        // 使用反射把bookChapter对象的属性值取出  赋值给bookChapterDto对象
+        // 遍历bookChapterDto对象的属性  如果bookChapter对象中有同名属性  取出赋值给bookChapterDto对象
+        BeanUtils.copyProperties(bookChapter, bookChapterDto);
+        bookChapterDto.setChapterUpdateTime(bookChapter.getUpdateTime());
+
+        // 查询章节内容
+        // select * from book_content where chapter_id = 'chapterId' limit 1;
+        LambdaQueryWrapper<BookContent> contentQueryWrapper = new LambdaQueryWrapper<>();
+        contentQueryWrapper.eq(BookContent::getChapterId, chapterId).last("LIMIT 1");
+        // selectOne 查询一条数据   selectList 查询多条数据
+        BookContent bookContent = bookContentMapper.selectOne(contentQueryWrapper);
+        String content = bookContent.getContent();
+
+        // 查询小说信息
+        // select * from book_info where id = 'bookId';
+        Long id = bookChapter.getBookId();
+        BookInfo bookInfo = bookInfoMapper.selectById(id);
+        BookInfoRespDto bookInfoDto = BookInfoRespDto.builder().build();
+        // 组装响应对象
+        BeanUtils.copyProperties(bookInfo, bookInfoDto);
+//        BookInfoRespDto bookInfoDto1 = BookInfoRespDto.builder()
+//                .id(bookInfo.getId())
+//                .bookName(bookInfo.getBookName())
+//                .bookDesc(bookInfo.getBookDesc())
+//                .bookStatus(bookInfo.getBookStatus().intValue())
+//                .authorId(bookInfo.getAuthorId())
+//                .authorName(bookInfo.getAuthorName())
+//                .categoryId(bookInfo.getCategoryId())
+//                .categoryName(bookInfo.getCategoryName())
+//                .commentCount(bookInfo.getCommentCount())
+//                .lastChapterId(bookInfo.getLastChapterId())
+//                .picUrl(bookInfo.getPicUrl())
+//                .visitCount(bookInfo.getVisitCount())
+//                .wordCount(bookInfo.getWordCount())
+//                .build();
+
+        // 组装数据并返回
+        BookContentAboutRespDto result = BookContentAboutRespDto.builder()
+                .bookInfo(bookInfoDto)
+                .chapterInfo(bookChapterDto)
+                .bookContent(content)
+                .build();
+        return result;
+    }
 }

+ 34 - 0
novel-cloud-demo/novel-book/novel-book-service/src/main/java/com/sf/book/service/impl/InnerBookServiceImpl.java

@@ -0,0 +1,34 @@
+package com.sf.book.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sf.book.dto.resp.BookInfoRespDto;
+import com.sf.book.entity.BookInfo;
+import com.sf.book.mapper.BookInfoMapper;
+import com.sf.book.service.IInnerBookService;
+import com.sf.core.dto.RestResp;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class InnerBookServiceImpl implements IInnerBookService {
+
+    private final BookInfoMapper bookInfoMapper;
+
+    @Override
+    public List<BookInfoRespDto> listBookInfoByIds(List<Long> bookIds) {
+        // select * from book_info where id in ('','','');
+        LambdaQueryWrapper<BookInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(BookInfo::getId, bookIds);
+        List<BookInfo> bookInfoList = bookInfoMapper.selectList(queryWrapper);
+        List<BookInfoRespDto> bookInfoRespDtos = bookInfoList.stream().map(bookInfo -> {
+            BookInfoRespDto bookInfoRespDto = new BookInfoRespDto();
+            BeanUtils.copyProperties(bookInfo, bookInfoRespDto);
+            return bookInfoRespDto;
+        }).toList();
+        return bookInfoRespDtos;
+    }
+}

+ 4 - 0
novel-cloud-demo/novel-core/src/main/java/com/sf/core/dto/RestResp.java

@@ -1,8 +1,12 @@
 package com.sf.core.dto;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class RestResp<T> {
 
     private String code;

+ 4 - 1
novel-cloud-demo/novel-core/src/main/java/com/sf/core/util/GeneUtils.java

@@ -44,8 +44,11 @@ public class GeneUtils {
 
         List<String> list = new ArrayList<>();
         switch (moduleName) {
+            // 每个微服务只能调用自己管理的表
+            // 如果需要获取其他表的数据 调用对应微服务的接口
             case "home":
-                list.add("home_book");
+//                list.add("home_book");
+                list.add("home_friend_link"); // 首页友情链接表
                 break;
             case "book":
 //                list.add("book_info");  // 书籍表

+ 7 - 0
novel-cloud-demo/novel-home/pom.xml

@@ -25,6 +25,13 @@
 			<!-- 修改版本使用父项目即为 novel-cloud-demo的版本 -->
 			<version>${project.parent.version}</version>
 		</dependency>
+
+		<dependency>
+			<groupId>com.sf</groupId>
+			<artifactId>novel-book-api</artifactId>
+			<version>${parent.version}</version>
+		</dependency>
+
 	</dependencies>
 
 	<build>

+ 6 - 1
novel-cloud-demo/novel-home/src/main/java/com/sf/home/NovelHomeApplication.java

@@ -3,9 +3,14 @@ package com.sf.home;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 
+// 指定扫描mapper的路径
 @MapperScan("com.sf.home.mapper")
-@SpringBootApplication
+// 指定扫描feign客户端的路径
+@EnableFeignClients(basePackages = {"com.sf.book.client"})
+// 指定扫描所有bean的路径
+@SpringBootApplication(scanBasePackages = {"com.sf"})
 public class NovelHomeApplication {
 
 	public static void main(String[] args) {

+ 24 - 8
novel-cloud-demo/novel-home/src/main/java/com/sf/home/controller/HomeBookController.java

@@ -1,12 +1,19 @@
 package com.sf.home.controller;
 
+import com.sf.core.dto.RestResp;
+import com.sf.home.dto.resp.HomeBookRespDto;
 import com.sf.home.service.IHomeBookService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 /**
  * <p>
  * 小说推荐 前端控制器
@@ -15,17 +22,26 @@ import org.springframework.web.bind.annotation.RestController;
  * @author baomidou
  * @since 2024-08-05
  */
-//@Controller
-//@RequestMapping("/homeBook")
+@Tag(name = "HomeBookController", description = "首页信息模块")
 @RestController
-@RequiredArgsConstructor
+@RequestMapping("/api/front/home")
+// 跨域问题
+//@CrossOrigin(originPatterns = "*",allowCredentials = "true")
 public class HomeBookController {
 
-    private final IHomeBookService homeBookService;
+    @Autowired
+    private IHomeBookService homeBookService;
 
-    // http://localhost:8901/count
-    @GetMapping("/count")
-    public Long count(){
-        return homeBookService.count();
+    // 首页接口
+    // http://127.0.0.1:8901/api/front/home/books
+    @Operation(summary = "首页信息接口")
+    @GetMapping(value = "/books")
+    public RestResp<List<HomeBookRespDto>> books() {
+        System.out.println("HomeBookController books start");
+        // 将实际的数据处理 给到service
+        List<HomeBookRespDto> books = homeBookService.allHomeBook();
+        // code message data
+        return RestResp.ok(books);
     }
 }
+

+ 18 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/controller/HomeFriendLinkController.java

@@ -0,0 +1,18 @@
+package com.sf.home.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 友情链接 前端控制器
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-08-05
+ */
+@Controller
+@RequestMapping("/homeFriendLink")
+public class HomeFriendLinkController {
+
+}

+ 57 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/dto/resp/HomeBookRespDto.java

@@ -0,0 +1,57 @@
+package com.sf.home.dto.resp;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 首页小说推荐 响应DTO
+ *
+ * @author xiongxiaoyang
+ * @date 2022/5/13
+ */
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class HomeBookRespDto {
+
+    /**
+     * 类型;0-轮播图 1-顶部栏 2-本周强推 3-热门推荐 4-精品推荐
+     */
+    @Schema(description = "类型;0-轮播图 1-顶部栏 2-本周强推 3-热门推荐 4-精品推荐")
+    private Integer type;
+
+    /**
+     * 推荐小说ID
+     */
+    @Schema(description = "小说ID")
+    private Long bookId;
+
+    /**
+     * 小说封面地址
+     */
+    @Schema(description = "小说封面地址")
+    private String picUrl;
+
+    /**
+     * 小说名
+     */
+    @Schema(description = "小说名")
+    private String bookName;
+
+    /**
+     * 作家名
+     */
+    @Schema(description = "作家名")
+    private String authorName;
+
+    /**
+     * 书籍描述
+     */
+    @Schema(description = "书籍描述")
+    private String bookDesc;
+
+}

+ 58 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/entity/HomeFriendLink.java

@@ -0,0 +1,58 @@
+package com.sf.home.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 友情链接
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-08-05
+ */
+@Getter
+@Setter
+@TableName("home_friend_link")
+public class HomeFriendLink implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 链接名
+     */
+    private String linkName;
+
+    /**
+     * 链接url
+     */
+    private String linkUrl;
+
+    /**
+     * 排序号
+     */
+    private Integer sort;
+
+    /**
+     * 是否开启;0-不开启 1-开启
+     */
+    private Integer isOpen;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 16 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/mapper/HomeFriendLinkMapper.java

@@ -0,0 +1,16 @@
+package com.sf.home.mapper;
+
+import com.sf.home.entity.HomeFriendLink;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 友情链接 Mapper 接口
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-08-05
+ */
+public interface HomeFriendLinkMapper extends BaseMapper<HomeFriendLink> {
+
+}

+ 4 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/IHomeBookService.java

@@ -1,8 +1,11 @@
 package com.sf.home.service;
 
+import com.sf.home.dto.resp.HomeBookRespDto;
 import com.sf.home.entity.HomeBook;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * <p>
  * 小说推荐 服务类
@@ -13,4 +16,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IHomeBookService extends IService<HomeBook> {
 
+    List<HomeBookRespDto> allHomeBook();
 }

+ 16 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/IHomeFriendLinkService.java

@@ -0,0 +1,16 @@
+package com.sf.home.service;
+
+import com.sf.home.entity.HomeFriendLink;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 友情链接 服务类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-08-05
+ */
+public interface IHomeFriendLinkService extends IService<HomeFriendLink> {
+
+}

+ 86 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/impl/HomeBookServiceImpl.java

@@ -1,11 +1,24 @@
 package com.sf.home.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sf.book.client.BookFeign;
+import com.sf.book.dto.BookInfoRespDto;
+import com.sf.core.dto.RestResp;
+import com.sf.home.dto.resp.HomeBookRespDto;
 import com.sf.home.entity.HomeBook;
 import com.sf.home.mapper.HomeBookMapper;
 import com.sf.home.service.IHomeBookService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 /**
  * <p>
  * 小说推荐 服务实现类
@@ -15,6 +28,79 @@ import org.springframework.stereotype.Service;
  * @since 2024-08-05
  */
 @Service
+@RequiredArgsConstructor
 public class HomeBookServiceImpl extends ServiceImpl<HomeBookMapper, HomeBook> implements IHomeBookService {
 
+    private final HomeBookMapper homeBookMapper;
+
+    private final BookFeign bookFeign;
+
+    // 去到home_book表中取数据
+    // 再使用book_id去book_info表中找到关联数据
+    @Override
+    public List<HomeBookRespDto> allHomeBook() {
+
+        System.out.println("从Mysql中返回数据");
+        List<HomeBookRespDto> list = new ArrayList<>();
+
+        List<HomeBook> homeBookList = homeBookMapper.selectList(null);
+        // 取出所有的book_id
+        List<Long> bookIdList = new ArrayList<>();
+//        for (HomeBook homeBook : homeBookList) {
+//            bookIdList.add(homeBook.getBookId());
+//        }
+        homeBookList.forEach(homeBook -> {
+            bookIdList.add(homeBook.getBookId());
+        });
+
+        // 把直接从book_info表获取数据 变为调用novel-book中的接口
+        // 原来的逻辑是 将home_book表中的书籍id组装成list
+        // 使用in在book_info表中查到匹配的书籍信息
+
+        RestResp<List<BookInfoRespDto>> listRestResp = bookFeign.listBookInfoByIds(bookIdList);
+        List<BookInfoRespDto> data = listRestResp.getData();
+        Map<Long, BookInfoRespDto> collected =
+                data.stream().collect(Collectors.toMap(BookInfoRespDto::getId, t -> t));
+
+        homeBookList.forEach(homeBook -> {
+            BookInfoRespDto bookInfoDto = collected.get(homeBook.getBookId());
+            HomeBookRespDto homeBookRespDto = HomeBookRespDto.builder()
+                    .type(homeBook.getType().intValue())  // byte -> int
+                    .bookId(homeBook.getBookId())
+                    .picUrl(bookInfoDto.getPicUrl())
+                    .bookName(bookInfoDto.getBookName())
+                    .authorName(bookInfoDto.getAuthorName())
+                    .bookDesc(bookInfoDto.getBookDesc())
+                    .build();
+            list.add(homeBookRespDto);
+        });
+
+
+//        // 使用in
+//        // select * from book_info where id in ('','','');
+//        LambdaQueryWrapper<BookInfo> queryWrapper = new LambdaQueryWrapper<>();
+//        queryWrapper.in(BookInfo::getId, bookIdList);
+//        List<BookInfo> bookInfoList = bookInfoMapper.selectList(queryWrapper);
+//        // Map<BookId,BookInfo>
+//        // 使用了stream流的收集方法collect()  每一个BookInfo中的id作为key  每一个BookInfo自身作为value
+//        // 因为要在home_book中每行数据找到对应的书籍信息  根据bookId查询book_info
+//        // 通过map 记录bookId 和 bookInfo的对应关系 然后组装数据
+//        Map<Long, BookInfo> collected =
+//                bookInfoList.stream().collect(Collectors.toMap(BookInfo::getId, t -> t));
+//
+//        homeBookList.forEach(homeBook -> {
+//            BookInfo bookInfo = collected.get(homeBook.getBookId());
+//            HomeBookRespDto homeBookRespDto = HomeBookRespDto.builder()
+//                    .type(homeBook.getType().intValue())  // byte -> int
+//                    .bookId(homeBook.getBookId())
+//                    .picUrl(bookInfo.getPicUrl())
+//                    .bookName(bookInfo.getBookName())
+//                    .authorName(bookInfo.getAuthorName())
+//                    .bookDesc(bookInfo.getBookDesc())
+//                    .build();
+//            list.add(homeBookRespDto);
+//        });
+
+        return list;
+    }
 }

+ 20 - 0
novel-cloud-demo/novel-home/src/main/java/com/sf/home/service/impl/HomeFriendLinkServiceImpl.java

@@ -0,0 +1,20 @@
+package com.sf.home.service.impl;
+
+import com.sf.home.entity.HomeFriendLink;
+import com.sf.home.mapper.HomeFriendLinkMapper;
+import com.sf.home.service.IHomeFriendLinkService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 友情链接 服务实现类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-08-05
+ */
+@Service
+public class HomeFriendLinkServiceImpl extends ServiceImpl<HomeFriendLinkMapper, HomeFriendLink> implements IHomeFriendLinkService {
+
+}

+ 5 - 0
novel-cloud-demo/novel-home/src/main/resources/mapper/HomeFriendLinkMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sf.home.mapper.HomeFriendLinkMapper">
+
+</mapper>