瀏覽代碼

0722 接口梳理

Qing 9 月之前
父節點
當前提交
4d5a1fc8e2
共有 28 個文件被更改,包括 292 次插入48 次删除
  1. 19 10
      novel-demo/pom.xml
  2. 0 2
      novel-demo/src/main/java/com/sf/NovelDemoApplication.java
  3. 14 11
      novel-demo/src/main/java/com/sf/config/GsonConfig.java
  4. 2 0
      novel-demo/src/main/java/com/sf/config/MybatisPlusConfig.java
  5. 1 2
      novel-demo/src/main/java/com/sf/config/SwaggerConfig.java
  6. 1 0
      novel-demo/src/main/java/com/sf/config/TokenInterceptor.java
  7. 18 0
      novel-demo/src/main/java/com/sf/controller/AuthorInfoController.java
  8. 10 6
      novel-demo/src/main/java/com/sf/controller/BookInfoController.java
  9. 1 0
      novel-demo/src/main/java/com/sf/controller/HomeBookController.java
  10. 1 1
      novel-demo/src/main/java/com/sf/controller/HomeFriendLinkController.java
  11. 3 0
      novel-demo/src/main/java/com/sf/controller/UserInfoController.java
  12. 3 0
      novel-demo/src/main/java/com/sf/dto/req/UserLoginReqDto.java
  13. 83 0
      novel-demo/src/main/java/com/sf/entity/AuthorInfo.java
  14. 2 2
      novel-demo/src/main/java/com/sf/jdk17/sealed/Car.java
  15. 1 1
      novel-demo/src/main/java/com/sf/jdk17/sealed/Service.java
  16. 16 0
      novel-demo/src/main/java/com/sf/mapper/AuthorInfoMapper.java
  17. 16 0
      novel-demo/src/main/java/com/sf/service/IAuthorInfoService.java
  18. 10 0
      novel-demo/src/main/java/com/sf/service/IBookInfoService.java
  19. 20 0
      novel-demo/src/main/java/com/sf/service/impl/AuthorInfoServiceImpl.java
  20. 39 6
      novel-demo/src/main/java/com/sf/service/impl/BookInfoServiceImpl.java
  21. 2 0
      novel-demo/src/main/java/com/sf/service/impl/HomeBookServiceImpl.java
  22. 1 0
      novel-demo/src/main/java/com/sf/service/impl/UserInfoServiceImpl.java
  23. 4 0
      novel-demo/src/main/java/com/sf/util/CaptchaUtils.java
  24. 12 5
      novel-demo/src/main/java/com/sf/util/GeneUtils.java
  25. 2 0
      novel-demo/src/main/resources/application.yml
  26. 5 0
      novel-demo/src/main/resources/mapper/AuthorInfoMapper.xml
  27. 6 2
      novel-demo/src/main/resources/mapper/BookInfoMapper.xml
  28. 二進制
      novel-demo/src/main/resources/static/images/9338815f3b444c69a84367a25cb9a8f2.jpeg

+ 19 - 10
novel-demo/pom.xml

@@ -17,8 +17,11 @@
     <properties>
         <java.version>17</java.version>
         <jjwt.version>0.11.5</jjwt.version>
+        <!-- 使用属性properties 统一版本的引入 -->
+        <mybatis-plus.version>3.5.4</mybatis-plus.version>
     </properties>
     <dependencies>
+        <!-- web项目 也代表启动时嵌入tomcat容器 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
@@ -52,13 +55,16 @@
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
-            <version>3.5.4</version>
+<!--            <version>3.5.4</version>-->
+            <version>${mybatis-plus.version}</version>
         </dependency>
 
+        <!-- mybatis plus代码生成 -->
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-generator</artifactId>
-            <version>3.5.4</version>
+<!--            <version>3.5.4</version>-->
+            <version>${mybatis-plus.version}</version>
         </dependency>
 
         <dependency>
@@ -67,13 +73,7 @@
             <version>2.3.32</version>
         </dependency>
 
-
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-
+        <!-- 提供swagger功能  可以测试接口 -->
         <dependency>
             <groupId>org.springdoc</groupId>
             <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
@@ -86,18 +86,20 @@
             <version>2.0.2</version>
         </dependency>
 
+        <!-- 使用hutool 生成验证码图片 -->
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
             <version>5.8.27</version>
         </dependency>
+
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-commons</artifactId>
             <version>3.3.0</version>
         </dependency>
 
-
+        <!-- 使用jwt来做用户登录信息加密和校验 -->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt-api</artifactId>
@@ -129,6 +131,13 @@
             <version>2.11.0</version>
         </dependency>
 
+        <!-- springboot测试的依赖 提供@SpringBootTest注解等功能 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 0 - 2
novel-demo/src/main/java/com/sf/NovelDemoApplication.java

@@ -1,11 +1,9 @@
 package com.sf;
 
-import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
-@MapperScan("com.sf.mapper")
 public class NovelDemoApplication {
 
     public static void main(String[] args) {

+ 14 - 11
novel-demo/src/main/java/com/sf/config/GsonConfig.java

@@ -16,17 +16,21 @@ import java.time.format.DateTimeFormatter;
 @Configuration
 public class GsonConfig {
     //序列化
-    final static JsonSerializer<LocalDateTime> jsonSerializerDateTime = (localDateTime, type, jsonSerializationContext)
-            -> new JsonPrimitive(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-    final static JsonSerializer<LocalDate> jsonSerializerDate = (localDate, type, jsonSerializationContext)
-            -> new JsonPrimitive(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+    final static JsonSerializer<LocalDateTime> jsonSerializerDateTime =
+            (localDateTime, type, jsonSerializationContext)
+                    -> new JsonPrimitive(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+    final static JsonSerializer<LocalDate> jsonSerializerDate =
+            (localDate, type, jsonSerializationContext)
+                    -> new JsonPrimitive(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
     //反序列化
-    final static JsonDeserializer<LocalDateTime> jsonDeserializerDateTime = (jsonElement, type, jsonDeserializationContext)
-            -> LocalDateTime.parse(jsonElement.getAsJsonPrimitive().getAsString(),
-            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-    final static JsonDeserializer<LocalDate> jsonDeserializerDate = (jsonElement, type, jsonDeserializationContext)
-            -> LocalDate.parse(jsonElement.getAsJsonPrimitive().getAsString(),
-            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+    final static JsonDeserializer<LocalDateTime> jsonDeserializerDateTime =
+            (jsonElement, type, jsonDeserializationContext)
+                    -> LocalDateTime.parse(jsonElement.getAsJsonPrimitive().getAsString(),
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+    final static JsonDeserializer<LocalDate> jsonDeserializerDate =
+            (jsonElement, type, jsonDeserializationContext)
+                    -> LocalDate.parse(jsonElement.getAsJsonPrimitive().getAsString(),
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
 
     @Bean
     public Gson gson() {
@@ -40,5 +44,4 @@ public class GsonConfig {
                 .create();
     }
 
-
 }

+ 2 - 0
novel-demo/src/main/java/com/sf/config/MybatisPlusConfig.java

@@ -3,10 +3,12 @@ package com.sf.config;
 import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
+@MapperScan("com.sf.mapper")
 public class MybatisPlusConfig {
 
     // 将拦截器注入到spring容器中

+ 1 - 2
novel-demo/src/main/java/com/sf/config/SwaggerConfig.java

@@ -14,8 +14,7 @@ public class SwaggerConfig {
     @Bean
     public OpenAPI openAPI(){
         OpenAPI openAPI = new OpenAPI();
-        openAPI.info(
-                new Info().title("阅读类门户网站").description("基于springboot和mybatis-plus实现").version("v1.0"));
+        openAPI.info(new Info().title("阅读类门户网站").description("基于springboot和mybatis-plus实现").version("v1.0"));
         return openAPI;
     }
 }

+ 1 - 0
novel-demo/src/main/java/com/sf/config/TokenInterceptor.java

@@ -42,6 +42,7 @@ public class TokenInterceptor implements HandlerInterceptor {
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
 //        System.out.println("controller执行完成");
+        // 使用ThreadLocal要注意 使用完需要删除数据 不然可能一直占用内存 导致内存溢出
         UserHolder.clearUserId();
         HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
     }

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

@@ -0,0 +1,18 @@
+package com.sf.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 作者信息 前端控制器
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-07-22
+ */
+@Controller
+@RequestMapping("/authorInfo")
+public class AuthorInfoController {
+
+}

+ 10 - 6
novel-demo/src/main/java/com/sf/controller/BookInfoController.java

@@ -40,28 +40,32 @@ public class BookInfoController {
         return bookInfoService.list();
     }
 
-    @Operation(summary = "小说信息查询接口")
     // http://127.0.0.1:8888/api/front/book/{id}
+    @Operation(summary = "小说信息查询接口")
     @GetMapping("/api/front/book/{id}")
     public RestResp<BookInfoRespDto> getBookInfoById(
             @Parameter(description = "小说id") @PathVariable("id") Long id){
         // getById是mybatis plus提供的方法
         // 从对应表中 where id = '' 中的数据取出
         // mapper中 对应的方法叫  selectById
-        BookInfo bookInfo = bookInfoService.getById(id);
+//        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);
+//        // 如果实体类的属性和dto的属性 名字相同
+//        BookInfoRespDto bookInfoRespDto = BookInfoRespDto.builder().build();
+//        // 拷贝属性  从bookInfo中拷贝同名属性 bookInfoRespDto
+//        BeanUtils.copyProperties(bookInfo,bookInfoRespDto);
+
+        // 改造成调用service层
+        BookInfoRespDto bookInfoRespDto = bookInfoService.getBookInfo(id);
         return RestResp.ok(bookInfoRespDto);
     }
 
     // http://127.0.0.1:8888/api/front/search/books?keyword=&pageSize=10&pageNum=2
+    @Operation(summary = "查询书籍列表接口")
     @GetMapping("/api/front/search/books")
     public RestResp<PageRespDto<BookInfoRespDto>> searchBooks(BookSearchReqDto bookSearchReqDto){
         PageRespDto<BookInfoRespDto> pageRespDto = bookInfoService.searchBooks(bookSearchReqDto);

+ 1 - 0
novel-demo/src/main/java/com/sf/controller/HomeBookController.java

@@ -21,6 +21,7 @@ import java.util.List;
  * @author baomidou
  * @since 2024-05-25
  */
+// 首页接口控制器
 @RestController
 @RequestMapping("/api/front/home")
 // 跨域问题

+ 1 - 1
novel-demo/src/main/java/com/sf/controller/HomeFriendLinkController.java

@@ -26,7 +26,7 @@ public class HomeFriendLinkController {
     @Autowired
     private IHomeBookService homeBookService;
 
-    @GetMapping("friend_Link/list")
+    @GetMapping("/friend_Link/list")
     public RestResp<List<HomeFriendLinkRespDto>> listHomeFriendLinks() {
         List<HomeFriendLinkRespDto> homeFriendLinkRespDtos = homeBookService.listHomeFriendLinks();
         return RestResp.ok(homeFriendLinkRespDtos);

+ 3 - 0
novel-demo/src/main/java/com/sf/controller/UserInfoController.java

@@ -34,6 +34,7 @@ public class UserInfoController {
     @Autowired
     private IBookCommentService bookCommentService;
 
+    @Operation(summary = "获取验证码接口")
     @GetMapping("/api/front/resource/img_verify_code")
     public RestResp<ImgVerifyCodeRespDto> getImgVerifyCode() throws IOException {
         ImgVerifyCodeRespDto imgVerifyCodeRespDto = userInfoService.getImgVerifyCode();
@@ -42,6 +43,7 @@ public class UserInfoController {
 
     // @RequestBody 代表接受的请求参数  是json结构的对象
     // 和@ResponseBody 相对应
+    @Operation(summary = "申请注册接口")
     @PostMapping("/api/front/user/register")
     public RestResp<UserRegisterRespDto> register(@RequestBody UserRegisterReqDto userRegisterReqDto) {
         UserRegisterRespDto respDto = userInfoService.register(userRegisterReqDto);
@@ -59,6 +61,7 @@ public class UserInfoController {
     }
 
     // http://127.0.0.1:8888/api/front/user/login
+    @Operation(summary = "用户登录接口")
     @PostMapping("/api/front/user/login")
     public RestResp<UserLoginRespDto> login(@RequestBody UserLoginReqDto userLoginReqDto) {
         UserLoginRespDto userLoginRespDto = userInfoService.login(userLoginReqDto);

+ 3 - 0
novel-demo/src/main/java/com/sf/dto/req/UserLoginReqDto.java

@@ -1,5 +1,6 @@
 package com.sf.dto.req;
 
+import io.swagger.v3.oas.annotations.Parameter;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -12,6 +13,8 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 public class UserLoginReqDto {
 
+    @Parameter(description = "用户名")
     private String username;
+    @Parameter(description = "密码")
     private String password;
 }

+ 83 - 0
novel-demo/src/main/java/com/sf/entity/AuthorInfo.java

@@ -0,0 +1,83 @@
+package com.sf.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;
+import lombok.ToString;
+
+/**
+ * <p>
+ * 作者信息
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-07-22
+ */
+@Getter
+@Setter
+@ToString
+@TableName("author_info")
+public class AuthorInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 邀请码
+     */
+    private String inviteCode;
+
+    /**
+     * 笔名
+     */
+    private String penName;
+
+    /**
+     * 手机号码
+     */
+    private String telPhone;
+
+    /**
+     * QQ或微信账号
+     */
+    private String chatAccount;
+
+    /**
+     * 电子邮箱
+     */
+    private String email;
+
+    /**
+     * 作品方向;0-男频 1-女频
+     */
+    private Integer workDirection;
+
+    /**
+     * 0:正常;1-封禁
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 2 - 2
novel-demo/src/main/java/com/sf/jdk17/Car.java → novel-demo/src/main/java/com/sf/jdk17/sealed/Car.java

@@ -1,5 +1,5 @@
-package com.sf.jdk17;
+package com.sf.jdk17.sealed;
 
 // 在声明实现类的时候  被non-sealed 不封闭的 关键词来描述
-public non-sealed class Car implements Service{
+public non-sealed class Car implements Service {
 }

+ 1 - 1
novel-demo/src/main/java/com/sf/jdk17/Service.java → novel-demo/src/main/java/com/sf/jdk17/sealed/Service.java

@@ -1,4 +1,4 @@
-package com.sf.jdk17;
+package com.sf.jdk17.sealed;
 
 // 封闭的接口  只能通过被允许的类来实现
 public sealed interface Service permits Car {

+ 16 - 0
novel-demo/src/main/java/com/sf/mapper/AuthorInfoMapper.java

@@ -0,0 +1,16 @@
+package com.sf.mapper;
+
+import com.sf.entity.AuthorInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 作者信息 Mapper 接口
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-07-22
+ */
+public interface AuthorInfoMapper extends BaseMapper<AuthorInfo> {
+
+}

+ 16 - 0
novel-demo/src/main/java/com/sf/service/IAuthorInfoService.java

@@ -0,0 +1,16 @@
+package com.sf.service;
+
+import com.sf.entity.AuthorInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 作者信息 服务类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-07-22
+ */
+public interface IAuthorInfoService extends IService<AuthorInfo> {
+
+}

+ 10 - 0
novel-demo/src/main/java/com/sf/service/IBookInfoService.java

@@ -21,10 +21,20 @@ import java.util.List;
 // IService是mybatisplus提供的 基础服务接口
 public interface IBookInfoService extends IService<BookInfo> {
 
+    /**
+     * 书籍查询
+     * @param bookSearchReqDto
+     * @return
+     */
     PageRespDto<BookInfoRespDto> searchBooks(BookSearchReqDto bookSearchReqDto);
 
     List<BookCategoryRespDto> listCategory(Integer workDirection);
 
+    /**
+     * 书籍信息查询
+     */
+    BookInfoRespDto getBookInfo(Long id);
+
 
     /**
      * 小说点击榜查询

+ 20 - 0
novel-demo/src/main/java/com/sf/service/impl/AuthorInfoServiceImpl.java

@@ -0,0 +1,20 @@
+package com.sf.service.impl;
+
+import com.sf.entity.AuthorInfo;
+import com.sf.mapper.AuthorInfoMapper;
+import com.sf.service.IAuthorInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 作者信息 服务实现类
+ * </p>
+ *
+ * @author baomidou
+ * @since 2024-07-22
+ */
+@Service
+public class AuthorInfoServiceImpl extends ServiceImpl<AuthorInfoMapper, AuthorInfo> implements IAuthorInfoService {
+
+}

+ 39 - 6
novel-demo/src/main/java/com/sf/service/impl/BookInfoServiceImpl.java

@@ -8,11 +8,14 @@ import com.sf.dto.resp.BookInfoRespDto;
 import com.sf.dto.resp.BookRankRespDto;
 import com.sf.dto.resp.PageRespDto;
 import com.sf.entity.BookCategory;
+import com.sf.entity.BookChapter;
 import com.sf.entity.BookInfo;
 import com.sf.mapper.BookCategoryMapper;
+import com.sf.mapper.BookChapterMapper;
 import com.sf.mapper.BookInfoMapper;
 import com.sf.service.IBookInfoService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -27,16 +30,18 @@ import java.util.List;
  * @author baomidou
  * @since 2024-05-25
  */
-// ServiceImpl 是mybatisplus提供的服务基础实现类
+// ServiceImpl 是mybatis plus提供的服务基础实现类
+// 如果要自动注入的对象较多 此时 @Autowired也会冗余
 @Service
+@RequiredArgsConstructor
 public class BookInfoServiceImpl extends ServiceImpl<BookInfoMapper, BookInfo>
         implements IBookInfoService {
 
-    @Autowired
-    private BookInfoMapper bookInfoMapper;
-
-    @Autowired
-    private BookCategoryMapper bookCategoryMapper;
+    // 当类中声明了注解 @RequiredArgsConstructor时  可以简化自动注入的使用
+    // 在属性前 增加final修饰
+    private final BookInfoMapper bookInfoMapper;
+    private final BookCategoryMapper bookCategoryMapper;
+    private final BookChapterMapper bookChapterMapper;
 
     // 分页的本质是limit  select * from book_info
     @Override
@@ -58,6 +63,9 @@ public class BookInfoServiceImpl extends ServiceImpl<BookInfoMapper, BookInfo>
 //        bookInfoMapper.selectPage(page,wrapper);
 
         // 还可以使用mybatis自身的sql语句来实现
+        // select * from book_info limit 10,10
+        // select count(*) from book_info
+        // 第2页/每页10条  总页数 100(总记录数)/10(每页大小)=10页
         List<BookInfo> bookInfos = bookInfoMapper.searchBooks(page, bookSearchReqDto);
         List<BookInfoRespDto> bookInfoRespDtos = bookInfos.stream().map(bookInfo -> {
             BookInfoRespDto bookInfoRespDto = new BookInfoRespDto();
@@ -82,6 +90,31 @@ public class BookInfoServiceImpl extends ServiceImpl<BookInfoMapper, BookInfo>
                         .build()).toList();
     }
 
+
+    @Override
+    public BookInfoRespDto getBookInfo(Long id) {
+        // select * from book_info where id = ''
+        BookInfo bookInfo = bookInfoMapper.selectById(id);
+        // 如果实体类的属性和dto的属性 名字相同
+        BookInfoRespDto bookInfoRespDto = BookInfoRespDto.builder().build();
+        // 拷贝属性  从bookInfo中拷贝同名属性 bookInfoRespDto
+        BeanUtils.copyProperties(bookInfo,bookInfoRespDto);
+
+        // 增加首章id
+        // select * from book_chapter where book_id='' and chapter_num=0
+        LambdaQueryWrapper<BookChapter> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(BookChapter::getBookId, id);
+        queryWrapper.eq(BookChapter::getChapterNum,0);
+        // selectList 返回多条数据  selectOne是返回一条数据
+        BookChapter bookChapter = bookChapterMapper.selectOne(queryWrapper);
+        // 因为首章也可能没有
+        if(bookChapter != null){
+            // ctrl + shift + ↑ / ↓
+            bookInfoRespDto.setFirstChapterId(bookChapter.getId());
+        }
+        return bookInfoRespDto;
+    }
+
     @Override
     public List<BookRankRespDto> listVisitRankBooks() {
         LambdaQueryWrapper<BookInfo> bookInfoQueryWrapper = new LambdaQueryWrapper<>();

+ 2 - 0
novel-demo/src/main/java/com/sf/service/impl/HomeBookServiceImpl.java

@@ -80,6 +80,8 @@ public class HomeBookServiceImpl extends ServiceImpl<HomeBookMapper, HomeBook> i
         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));
 

+ 1 - 0
novel-demo/src/main/java/com/sf/service/impl/UserInfoServiceImpl.java

@@ -35,6 +35,7 @@ import java.util.concurrent.TimeUnit;
 @Service
 public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {
 
+    // 不使用redis时  使用的本地存储(内存存储)
     static HashMap<String, String> captcha = new HashMap<String, String>();
 
     @Autowired

+ 4 - 0
novel-demo/src/main/java/com/sf/util/CaptchaUtils.java

@@ -5,8 +5,11 @@ import cn.hutool.captcha.LineCaptcha;
 import cn.hutool.captcha.generator.RandomGenerator;
 import org.springframework.data.util.Pair;
 
+// 处理验证码的工具类
 public class CaptchaUtils {
 
+    // 获取一个随机的 四位数字的验证码
+    // 返回一对数据Pair  第一个数据是随机的对应值 如“1234” 第二个数据是生成的图片base64字符串
     public static Pair<String, String> getImageBase64() {
         // 随机生成器
         // 参数对应  生成几位数字的验证码  设置宽高
@@ -22,6 +25,7 @@ public class CaptchaUtils {
         System.out.println(imageBase64);
         System.out.println("-----------------");
 
+        // 构造一个pair对象
         Pair<String, String> pair = Pair.of(code, imageBase64);
         return pair;
     }

+ 12 - 5
novel-demo/src/main/java/com/sf/util/GeneUtils.java

@@ -10,6 +10,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+// 代码生成工具
 public class GeneUtils {
 
     public static void main(String[] args) {
@@ -24,7 +25,8 @@ public class GeneUtils {
 //        list.add("book_category"); // 书籍种类表
 //        list.add("home_friend_link"); // 首页友情链接表
 //        list.add("user_info"); // 用户信息表
-        list.add("book_comment"); // 书籍评论表
+//        list.add("book_comment"); // 书籍评论表
+        list.add("author_info"); // 作者信息表
 
         // 快速生成器
         FastAutoGenerator.create("jdbc:mysql://localhost:3306/novel-cloud?useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai",
@@ -33,15 +35,19 @@ public class GeneUtils {
                 .globalConfig(builder -> {
                     builder.author("baomidou") // 设置作者
 //                            .enableSwagger() // 开启 swagger 模式
-                            .outputDir("src/main/java/"); // 指定输出目录
-//                            .outputDir("src\\main\\java\\"); // 指定输出目录
+                            .outputDir("src/main/java/"); // 指定输出目录  mac/linux系统
+//                            .outputDir("src\\main\\java\\"); // 指定输出目录  windows系统
                 })
                 // 数据源配置
                 .dataSourceConfig(builder ->
                         builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                             int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                             if (typeCode == Types.SMALLINT) {
-                                // 自定义类型转换
+                                // 自定义类型转换  smallint - short - int
+                                return DbColumnType.INTEGER;
+                            }
+                            if(typeCode == Types.TINYINT){
+                                // tinyint - byte - int
                                 return DbColumnType.INTEGER;
                             }
                             return typeRegistry.getColumnType(metaInfo);
@@ -58,7 +64,8 @@ public class GeneUtils {
                 // 策略配置
                 .strategyConfig(builder ->
 //                                builder.addInclude("book_info") // 设置需要生成的表名
-                                builder.addInclude(list) // 设置需要生成的表名
+//                        builder.addInclude("book_info","user_info") // 可以通过多个参数 传入表名
+                                builder.addInclude(list).entityBuilder().enableLombok() // 设置需要生成的表名
 //                                .addTablePrefix("t_", "c_") // 设置过滤表前缀
                 )
                 .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板

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

@@ -7,9 +7,11 @@ novel:
       # - http://localhost:8080
   jwt:
     secret: E66559580A1ADF48CDD928516062F12E
+
 server:
   port: 8888
 # server.port=8888
+
 spring:
   application:
     name: novel-demo

+ 5 - 0
novel-demo/src/main/resources/mapper/AuthorInfoMapper.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.mapper.AuthorInfoMapper">
+
+</mapper>

+ 6 - 2
novel-demo/src/main/resources/mapper/BookInfoMapper.xml

@@ -2,13 +2,15 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.sf.mapper.BookInfoMapper">
 
+    <!-- 使用mybatis的动态sql 来根据不同的入参 拼接不同的sql -->
     <select id="searchBooks" resultType="com.sf.entity.BookInfo">
         select
         id,category_id,category_name,book_name,author_id,author_name,word_count,last_chapter_name
         from book_info where word_count > 0
+        <!-- 使用模糊查询 -->
         <if test="dto.keyword != null and dto.keyword != ''">
-            and (book_name like concat('%',#{dto.keyword},'%') or author_name like
-            concat('%',#{dto.keyword},'%'))
+            and (book_name like concat('%',#{dto.keyword},'%') or
+                 author_name like concat('%',#{dto.keyword},'%'))
         </if>
         <if test="dto.workDirection != null">
             and work_direction = #{dto.workDirection}
@@ -22,6 +24,7 @@
         <if test="dto.bookStatus != null">
             and book_status = #{dto.bookStatus}
         </if>
+        <!-- 判断字数所在区间 -->
         <if test="dto.wordCountMin != null">
             and word_count >= #{dto.wordCountMin}
         </if>
@@ -31,6 +34,7 @@
         <if test="dto.updateTimeMin != null">
             and last_chapter_update_time >= #{dto.updateTimeMin}
         </if>
+        <!-- 如果是给字段赋值  使用#{} category_id='1' 否则使用${} order by word_count -->
         <if test="dto.sort != null">
             order by ${dto.sort}
         </if>

二進制
novel-demo/src/main/resources/static/images/9338815f3b444c69a84367a25cb9a8f2.jpeg