吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9593|回复: 51
收起左侧

[Java 转载] 推荐一个 Spring Boot 3 + Vue 3 的实战型开源项目,配备保姆级项目开发教程

   关闭 [复制链接]
Java学者 发表于 2022-5-25 16:54
本帖最后由 Java学者 于 2023-1-11 20:15 编辑

项目简介

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

项目地址

开发环境

  • MySQL 8.0
  • Redis 7.0
  • Elasticsearch 8.2.0(可选)
  • RabbitMQ 3.10.2(可选)
  • XXL-JOB 2.3.1(可选)
  • JDK 17
  • Maven 3.8
  • Node 16.14

注:Elasticsearch、RabbitMQ 和 XXL-JOB 默认关闭,可通过 application.yml 配置文件中相应的 enable 配置属性开启。

后端技术选型

技术 版本 说明
Spring Boot 3.0.0 容器 + 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 分布式缓存支持
Redisson 3.17.4 分布式锁实现
MySQL 8.0 数据库服务
ShardingSphere-JDBC 5.1.1 数据库分库分表支持
Elasticsearch 8.2.0 搜索引擎服务
RabbitMQ 3.10.2 开源消息中间件
XXL-JOB 2.3.1 分布式任务调度平台
Sentinel 1.8.4 流量控制组件
Springdoc-openapi 2.0.0 Swagger 3 接口文档自动生成
Spring Boot Admin 3.0.0-M1 应用管理和监控
Undertow 2.2.17.Final Java 开发的高性能 Web 服务器
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,面向设计师和开发者的组件库

示例代码

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

/**
 * 小说搜索
 */
@Override
public 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));

}

免费评分

参与人数 15吾爱币 +14 热心值 +12 收起 理由
yaont + 1 + 1 热心回复!
一个大大大 + 1 + 1 谢谢@Thanks!
1124480274 + 1 + 1 用心讨论,共获提升!
hoddy + 1 谢谢@Thanks!
nanum + 1 + 1 谢谢@Thanks!
wpf飞鱼 + 1 + 1 谢谢@Thanks!
hug_wh + 1 谢谢@Thanks!
lydy + 1 谢谢@Thanks!
有毒的大妖怪 + 1 + 1 用心讨论,共获提升!
云之从 + 1 + 1 谢谢@Thanks!
Marbles + 1 + 1 谢谢@Thanks!
迷途的懒虫 + 1 + 1 不错,支持一下
Kuroisora + 1 + 1 谢谢@Thanks!
阿隆 + 1 + 1 热心回复!
c49573 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

RoyPenn 发表于 2022-5-25 17:00
很棒,支持下
你好港屿 发表于 2022-5-25 17:45
Mr.wang 发表于 2022-5-25 18:26
zhczlzhang 发表于 2022-5-25 19:13
做一个小说网站吗。
NCGZS 发表于 2022-5-26 23:46
大佬牛,有空学习下
hrjmo 发表于 2022-5-30 13:35
插眼,后面再看,谢谢大佬分享
daokunn 发表于 2022-6-1 16:55
这个网站界面看起来很清爽
傲天越 发表于 2022-6-1 18:16
正在学习spring boot,多谢楼主分享!!!
angel_bai 发表于 2022-6-7 08:19
谢谢分享 学习下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表