Qing 1 год назад
Родитель
Сommit
330994171c

+ 5 - 0
novel-demo/src/main/java/com/sf/config/CorsProperties.java

@@ -10,5 +10,10 @@ import java.util.List;
 @ConfigurationProperties(prefix = "novel.cors")
 public class CorsProperties {
 
+    // novel:
+    //  # 跨域配置
+    //  cors:
+    //    # 允许跨域的域名
+    //    allow-origins:
     private List<String> allowOrigins;
 }

+ 0 - 18
novel-demo/src/main/java/com/sf/controller/BookChapterController.java

@@ -1,18 +0,0 @@
-package com.sf.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.stereotype.Controller;
-
-/**
- * <p>
- * 小说章节 前端控制器
- * </p>
- *
- * @author baomidou
- * @since 2024-05-25
- */
-@Controller
-@RequestMapping("/bookChapter")
-public class BookChapterController {
-
-}

+ 0 - 18
novel-demo/src/main/java/com/sf/controller/BookContentController.java

@@ -1,18 +0,0 @@
-package com.sf.controller;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.stereotype.Controller;
-
-/**
- * <p>
- * 小说内容 前端控制器
- * </p>
- *
- * @author baomidou
- * @since 2024-05-25
- */
-@Controller
-@RequestMapping("/bookContent")
-public class BookContentController {
-
-}

+ 50 - 5
novel-demo/src/main/java/com/sf/controller/BookInfoController.java

@@ -1,12 +1,17 @@
 package com.sf.controller;
 
+import com.sf.dto.RestResp;
+import com.sf.dto.resp.BookChapterRespDto;
+import com.sf.dto.resp.BookContentAboutRespDto;
+import com.sf.dto.resp.BookInfoRespDto;
 import com.sf.entity.BookInfo;
+import com.sf.service.IBookChapterService;
+import com.sf.service.IBookContentService;
 import com.sf.service.IBookInfoService;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 
@@ -19,17 +24,57 @@ import java.util.List;
  * @since 2024-05-25
  */
 @RestController
-@RequestMapping("/bookInfo")
+@RequestMapping("/api/front/book")
 public class BookInfoController {
 
     @Autowired
     private IBookInfoService bookInfoService;
 
-    // http://localhost:8888/bookInfo/list
+    @Autowired
+    private IBookChapterService bookChapterService;
+
+    @Autowired
+    private IBookContentService bookContentService;
+
+    // http://localhost:8888/api/front/book/list
     @GetMapping("/list")
     public List<BookInfo> list(){
         // 不需要编写sql语句  直接进行增删改查操作
         return bookInfoService.list();
     }
 
+    // http://127.0.0.1:8888/api/front/book/{id}
+    @GetMapping("/{id}")
+    public RestResp<BookInfoRespDto> getBookInfoById(@PathVariable Long id){
+        // getById是mybatis plus提供的方法
+        // 从对应表中 where id = '' 中的数据取出
+        // mapper中 对应的方法叫  selectById
+        BookInfo bookInfo = bookInfoService.getById(id);
+        // 可以手动创建dto对象
+//        BookInfoRespDto bookInfoRespDto = BookInfoRespDto.builder()
+//                .id(bookInfo.getId())
+//                .bookName(bookInfo.getBookName())
+//                .build();
+        // 如果实体类的属性和dto的属性 名字相同
+        BookInfoRespDto bookInfoRespDto = BookInfoRespDto.builder().build();
+        // 拷贝属性  从bookInfo中拷贝同名属性 bookInfoRespDto
+        BeanUtils.copyProperties(bookInfo,bookInfoRespDto);
+        return RestResp.ok(bookInfoRespDto);
+    }
+
+    // http://127.0.0.1:8888/api/front/book/chapter/list?bookId=1337872597996539904
+    @GetMapping("/chapter/list")
+    public RestResp<List<BookChapterRespDto>> listChapters(@RequestParam("bookId") Long bookId){
+        // 根据传进来的参数 bookId 去查询对应书籍的章节信息
+        List<BookChapterRespDto> chapterRespDtos = bookChapterService.getBookChapterByBookId(bookId);
+        return RestResp.ok(chapterRespDtos);
+    }
+
+    // http://127.0.0.1:8888/api/front/book/content/{chapterId}
+    @GetMapping("/content/{chapterId}")
+    public RestResp<BookContentAboutRespDto> getBookContentAbout(
+            @PathVariable("chapterId") Long chapterId) {
+        BookContentAboutRespDto bookContentAbout = bookContentService.getBookContentAbout(chapterId);
+        return RestResp.ok(bookContentAbout);
+    }
 }

+ 72 - 0
novel-demo/src/main/java/com/sf/dto/resp/BookChapterRespDto.java

@@ -0,0 +1,72 @@
+package com.sf.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;
+
+/**
+ * 小说章节 响应DTO
+ *
+ * @author xiongxiaoyang
+ * @date 2022/5/15
+ */
+@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-demo/src/main/java/com/sf/dto/resp/BookContentAboutRespDto.java

@@ -0,0 +1,35 @@
+package com.sf.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 {
+
+    /**
+     * 小说信息
+     */
+    @Schema(description = "小说信息")
+    private BookInfoRespDto bookInfo;
+
+    /**
+     * 章节信息
+     */
+    @Schema(description = "章节信息")
+    private BookChapterRespDto chapterInfo;
+
+    /**
+     * 章节内容
+     */
+    @Schema(description = "章节内容")
+    private String bookContent;
+
+}

+ 122 - 0
novel-demo/src/main/java/com/sf/dto/resp/BookInfoRespDto.java

@@ -0,0 +1,122 @@
+package com.sf.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.time.LocalDateTime;
+
+/**
+ * 小说信息 响应DTO
+ *
+ * @author xiongxiaoyang
+ * @date 2022/5/15
+ */
+@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;
+
+
+}

+ 4 - 0
novel-demo/src/main/java/com/sf/service/IBookChapterService.java

@@ -1,8 +1,11 @@
 package com.sf.service;
 
+import com.sf.dto.resp.BookChapterRespDto;
 import com.sf.entity.BookChapter;
 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 IBookChapterService extends IService<BookChapter> {
 
+    List<BookChapterRespDto> getBookChapterByBookId(Long bookId);
 }

+ 2 - 1
novel-demo/src/main/java/com/sf/service/IBookContentService.java

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

+ 39 - 0
novel-demo/src/main/java/com/sf/service/impl/BookChapterServiceImpl.java

@@ -1,11 +1,18 @@
 package com.sf.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.sf.dto.resp.BookChapterRespDto;
 import com.sf.entity.BookChapter;
 import com.sf.mapper.BookChapterMapper;
 import com.sf.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 +24,36 @@ import org.springframework.stereotype.Service;
 @Service
 public class BookChapterServiceImpl extends ServiceImpl<BookChapterMapper, BookChapter> implements IBookChapterService {
 
+    @Autowired
+    private BookChapterMapper bookChapterMapper;
+
+    @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;
+    }
 }

+ 74 - 0
novel-demo/src/main/java/com/sf/service/impl/BookContentServiceImpl.java

@@ -1,9 +1,20 @@
 package com.sf.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.sf.dto.resp.BookChapterRespDto;
+import com.sf.dto.resp.BookContentAboutRespDto;
+import com.sf.dto.resp.BookInfoRespDto;
+import com.sf.entity.BookChapter;
 import com.sf.entity.BookContent;
+import com.sf.entity.BookInfo;
+import com.sf.mapper.BookChapterMapper;
 import com.sf.mapper.BookContentMapper;
+import com.sf.mapper.BookInfoMapper;
 import com.sf.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 +28,67 @@ 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) {
+        // 查询章节信息
+        // select * from book_chapter where id = 'chapterId';
+        BookChapter bookChapter = bookChapterMapper.selectById(chapterId);
+        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();
+//        BeanUtils.copyProperties(bookChapter, bookChapterDto);
+
+        // 查询章节内容
+        // 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();
+
+        // 组装数据并返回
+        return BookContentAboutRespDto.builder()
+                .bookInfo(bookInfoDto)
+                .chapterInfo(bookChapterDto)
+                .bookContent(content)
+                .build();
+    }
 }

+ 7 - 0
novel-demo/src/main/resources/application.yml

@@ -7,6 +7,7 @@ novel:
       # - http://localhost:8080
 server:
   port: 8888
+# server.port=8888
 spring:
   application:
     name: novel-demo
@@ -14,3 +15,9 @@ spring:
     password: root123456
     url: jdbc:mysql://localhost:3306/novel-cloud?useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
+  jackson:
+    generator:
+      # JSON 序列化时,将所有 Number 类型的属性都转为 String 类型返回,避免前端数据精度丢失的问题。
+      # 由于 Javascript 标准规定所有数字处理都应使用 64 位 IEEE 754 浮点值完成,
+      # 结果是某些 64 位整数值无法准确表示(尾数只有 51 位宽)
+      write-numbers-as-strings: true