1. 首页
  2. 技术知识

推荐一个 Spring Boot 3 + Vue 3 的学习型开源项目,配备保姆级项目教程

项目简介


原文链接:https://www.52pojie.cn/forum.php?mod=viewthread&tid=1640957&extra=page%3D1%26filter%3Dtypeid%26typeid%3D192

novel 是一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离学习型小说项目,配备保姆级项目开发教程手把手教你从零开始开发上线一个生产级别的 Java 系统。由小说门户系统、作家后台管理系统、平台后台管理系统等多个子系统构成。包括小说推荐、作品检索、小说排行榜、小说阅读、小说评论、会员中心、作家专区、充值订阅、新闻发布等功能。


项目地址

  • 后端项目(更新中):GitHub | 码云
  • 后端微服务版本项目(待更新):GitHub | 码云
  • 前端项目(更新中):GitHub | 码云
  • 线上应用版:GitHub | 码云 |演示地址

开发环境

  • MySQL 8.0
  • Redis 7.0
  • Elasticsearch 8.2.0(可选)
  • RabbitMQ 3.10.2(可选)
  • JDK 17
  • Maven 3.8
  • IntelliJ IDEA 2021.3(可选)
  • Node 16.14

后端技术选型

技术 版本 说明
Spring Boot 3.0.0-SNAPSHOT 容器 + MVC 框架
Mybatis 3.5.9 ORM 框架
MyBatis-Plus 3.5.1 Mybatis 增强工具
JJWT 0.11.5 JWT 登录支持
Lombok 1.18.24 简化对象封装工具
Caffeine 3.1.0 本地缓存支持
Redis 7.0 分布式缓存支持
MySQL 8.0 数据库服务
Elasticsearch 8.2.0 搜索引擎服务
RabbitMQ 3.10.2 开源消息中间件
Undertow 2.2.17.Final Java 开发的高性能 Web 服务器
Docker 应用容器引擎
Jenkins 自动化部署工具
Sonarqube 代码质量控制


注:更多热门新技术待集成。


前端技术选型

技术 版本 说明
Vue.js 3.2.13 渐进式 JavaScript 框架
Vue Router 4.0.15 Vue.js 的官方路由
axios 0.27.2 基于 promise 的网络请求库
element-plus 2.2.0 基于 Vue 3,面向设计师和开发者的组件库


示例代码

代码严格遵守阿里编码规约。

/** * 小说搜索 */@Overridepublic RestResp<PageRespDto<BookInfoRespDto>> searchBooks(BookSearchReqDto condition) {    SearchResponse<EsBookDto> response = esClient.search(s -> {                SearchRequest.Builder searchBuilder = s.index(EsConsts.BookIndex.INDEX_NAME);                // 构建搜索条件                buildSearchCondition(condition, searchBuilder);                // 排序                if (!StringUtils.isBlank(condition.getSort())) {                    searchBuilder.sort(o ->                            o.field(f -> f.field(condition.getSort()).order(SortOrder.Desc))                    );                }                // 分页                searchBuilder.from((condition.getPageNum() – 1) * condition.getPageSize())                        .size(condition.getPageSize());                return searchBuilder;            },            EsBookDto.class    );    TotalHits total = response.hits().total();    List<BookInfoRespDto> list = new ArrayList<>();    List<Hit<EsBookDto>> hits = response.hits().hits();    for (Hit<EsBookDto> hit : hits) {        EsBookDto book = hit.source();        list.add(BookInfoRespDto.builder()                .id(book.getId())                .bookName(book.getBookName())                .categoryId(book.getCategoryId())                .categoryName(book.getCategoryName())                .authorId(book.getAuthorId())                .authorName(book.getAuthorName())                .wordCount(book.getWordCount())                .lastChapterName(book.getLastChapterName())                .build());    }    return RestResp.ok(PageRespDto.of(condition.getPageNum(), condition.getPageSize(), total.value(), list));}/** * 构建搜索条件 */private void buildSearchCondition(BookSearchReqDto condition, SearchRequest.Builder searchBuilder) {    BoolQuery boolQuery = BoolQuery.of(b -> {        if (!StringUtils.isBlank(condition.getKeyword())) {            // 关键词匹配            b.must((q -> q.multiMatch(t -> t                    .fields(EsConsts.BookIndex.FIELD_BOOK_NAME + “^2”                            , EsConsts.BookIndex.FIELD_AUTHOR_NAME + “^1.8”                            , EsConsts.BookIndex.FIELD_BOOK_DESC + “^0.1”)                    .query(condition.getKeyword())            )            ));        }        // 精确查询        if (Objects.nonNull(condition.getWorkDirection())) {            b.must(TermQuery.of(m -> m                    .field(EsConsts.BookIndex.FIELD_WORK_DIRECTION)                    .value(condition.getWorkDirection())            )._toQuery());        }        if (Objects.nonNull(condition.getCategoryId())) {            b.must(TermQuery.of(m -> m                    .field(EsConsts.BookIndex.FIELD_CATEGORY_ID)                    .value(condition.getCategoryId())            )._toQuery());        }        // 范围查询        if (Objects.nonNull(condition.getWordCountMin())) {            b.must(RangeQuery.of(m -> m                    .field(EsConsts.BookIndex.FIELD_WORD_COUNT)                    .gte(JsonData.of(condition.getWordCountMin()))            )._toQuery());        }        if (Objects.nonNull(condition.getWordCountMax())) {            b.must(RangeQuery.of(m -> m                    .field(EsConsts.BookIndex.FIELD_WORD_COUNT)                    .lt(JsonData.of(condition.getWordCountMax()))            )._toQuery());        }        if (Objects.nonNull(condition.getUpdateTimeMin())) {            b.must(RangeQuery.of(m -> m                    .field(EsConsts.BookIndex.FIELD_LAST_CHAPTER_UPDATE_TIME)                    .gte(JsonData.of(condition.getUpdateTimeMin().getTime()))            )._toQuery());        }        return b;    });    searchBuilder.query(q -> q.bool(boolQuery));}
部分截图

  • 首页

  • 分类索引页

  • 搜索页

  • 排行榜

  • 详情页

  • 阅读页

原创文章,作者:starterknow,如若转载,请注明出处:https://www.starterknow.com/126528.html

联系我们