Skip to main content

WAdmin

萌新必读

简介

yudao-vue-pro (opens new window),RuoYi-Vue 全新 Pro 版本,优化重构所有功能。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + UniApp 微信小程序,支持 RBAC 动态权限、数据权限、SaaS 多租户、Flowable 工作流、三方登录、支付、短信、商城等功能。

功能列表

芋道,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。

  • 管理后台的电脑端:Vue3 提供 element-plus (opens new window)vben(ant-design-vue) (opens new window)两个版本,Vue2 提供 element-ui (opens new window)版本
  • 管理后台的移动端:采用 uni-app (opens new window)方案,一份代码多终端适配,同时支持 APP、小程序、H5!
  • 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson
  • 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等
  • 消息队列可使用 Event、Redis、RabbitMQ、Kafka、RocketMQ 等
  • 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统,支持 SSO 单点登录
  • 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能
  • 支持 SaaS 多租户系统,可自定义每个租户的权限,提供透明化的多租户底层封装
  • 工作流使用 Flowable,支持动态表单、在线设计流程、会签 / 或签、多种任务分配方式
  • 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验
  • 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款
  • 集成阿里云、腾讯云等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务
  • 集成报表设计器、大屏设计器,通过拖拽即可生成酷炫的报表与大屏

内置功能

系统内置多种多种业务功能,可以用于快速你的业务系统:

功能分层

  • 系统功能
  • 基础设施
  • 工作流程
  • 支付系统
  • 会员中心
  • 数据报表
  • 商城系统
  • 微信公众号

友情提示:本项目基于 RuoYi-Vue 修改,重构优化后端的代码,美化前端的界面。

  • 额外新增的功能,我们使用 🚀 标记。
  • 重新实现的功能,我们使用 ⭐️ 标记。

🙂 所有功能,都通过 单元测试 保证高质量。

系统功能

功能描述
用户管理用户是系统操作者,该功能主要完成系统用户配置
⭐️在线用户当前系统中活跃用户状态监控,支持手动踢下线
角色管理角色菜单权限分配、设置角色按机构进行数据范围权限划分
菜单管理配置系统菜单、操作权限、按钮权限标识等,本地缓存提供性能
部门管理配置系统组织机构(公司、部门、小组),树结构展现支持数据权限
岗位管理配置系统用户所属担任职务
🚀租户管理配置系统租户,支持 SaaS 场景下的多租户功能
🚀租户套餐配置租户套餐,自定每个租户的菜单、操作、按钮的权限
字典管理对系统中经常使用的一些较为固定的数据进行维护
🚀短信管理短信渠道、短息模板、短信日志,对接阿里云等主流短信平台
🚀邮件管理邮箱账号、邮件模版、邮件发送日志,支持所有邮件平台
🚀站内信系统内的消息通知,支持站内信模版、站内信消息
🚀操作日志系统正常操作日志记录和查询,集成 Swagger 生成日志内容
⭐️登录日志系统登录日志记录查询,包含登录异常
🚀错误码管理系统所有错误码的管理,可在线修改错误提示,无需重启服务
通知公告系统通知公告信息发布维护
🚀敏感词配置系统敏感词,支持标签分组
🚀应用管理管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式
🚀地区管理展示省份、城市、区镇等城市信息,支持 IP 对应城市

#基础设施

功能描述
🚀代码生成前后端代码的生成(Java、Vue、SQL、单元测试),支持 CRUD 下载
🚀系统接口基于 Swagger 自动生成相关的 RESTful API 接口文档
🚀数据库文档基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式
表单构建拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件
🚀配置管理对系统动态配置常用参数,支持 SpringBoot 加载
🚀文件服务支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等
🚀文件服务支持本地文件存储,同时支持兼容 Amazon S3 协议的云服务、开源组件
🚀API 日志包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题
MySQL 监控监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈
Redis 监控监控 Redis 数据库的使用情况,使用的 Redis Key 管理
🚀消息队列基于 Redis 实现消息队列,Stream 提供集群消费,Pub/Sub 提供广播消费
🚀Java 监控基于 Spring Boot Admin 实现 Java 应用的监控
🚀链路追踪接入 SkyWalking 组件,实现链路追踪
🚀日志中心接入 SkyWalking 组件,实现日志中心
🚀分布式锁基于 Redis 实现分布式锁,满足并发场景
🚀幂等组件基于 Redis 实现幂等组件,解决重复请求问题
🚀服务保障基于 Resilience4j 实现服务的稳定性,包括限流、熔断等功能
🚀日志服务轻量级日志中心,查看远程服务器的日志
🚀单元测试基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等

#工作流程

功能描述
🚀流程模型配置工作流的流程模型,支持文件导入与在线设计流程图,提供 7 种任务分配规则
🚀流程表单拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件
🚀用户分组自定义用户分组,可用于工作流的审批分组
🚀我的流程查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线
🚀待办任务查看自己【未】审批的工作任务,支持通过、不通过、转发、委派、退回等操作
🚀已办任务查看自己【已】审批的工作任务,未来会支持回退操作
🚀OA 请假作为业务自定义接入工作流的使用示例,只需创建请求对应的工作流程,即可进行审批

#支付系统

功能描述
🚀应用信息配置商户的应用信息,对接支付宝、微信等多个支付渠道
🚀支付订单查看用户发起的支付宝、微信等的【支付】订单
🚀退款订单查看用户发起的支付宝、微信等的【退款】订单
🚀回调通知查看支付回调业务的【支付】【退款】的通知结果
🚀接入示例提供接入支付系统的【支付】【退款】的功能实战

#数据报表

功能描述
🚀报表设计器支持数据报表、图形报表、打印设计等
🚀大屏设计器拖拽生成数据大屏,内置几十种图表组件

#微信公众号

功能描述
🚀账号管理配置接入的微信公众号,可支持多个公众号
🚀数据统计统计公众号的用户增减、累计用户、消息概况、接口分析等数据
🚀粉丝管理查看已关注、取关的粉丝列表,可对粉丝进行同步、打标签等操作
🚀消息管理查看粉丝发送的消息列表,可主动回复粉丝消息
🚀自动回复自动回复粉丝发送的消息,支持关注回复、消息回复、关键字回复
🚀标签管理对公众号的标签进行创建、查询、修改、删除等操作
🚀菜单管理自定义公众号的菜单,也可以从公众号同步菜单
🚀素材管理管理公众号的图片、语音、视频等素材,支持在线播放语音、视频
🚀图文草稿箱新增常用的图文素材到草稿箱,可发布到公众号
🚀图文发表记录查看已发布成功的图文素材,支持删除操作

#商城系统

功能图

功能图

#会员中心

功能描述
🚀会员管理会员是 C 端的消费者,该功能用于会员的搜索与管理
🚀会员标签对会员的标签进行创建、查询、修改、删除等操作
🚀会员等级对会员的等级、成长值进行管理,可用于订单折扣等会员权益
🚀会员分组对会员进行分组,用于用户画像、内容推送等运营手段
🚀积分签到回馈给签到、消费等行为的积分,会员可订单抵现、积分兑换等途径消耗

快速启动

启动后端项目

yudao-server (opens new window)是后端项目,提供管理后台、用户 APP 的 RESTful API 接口。

#5.1 编译项目

第一步,使用 IDEA 打开 Terminal 终端,在 根目录 下直接执行 mvn clean install package '-Dmaven.test.skip=true' 命令,将项目进行初始化的打包,预计需要 1 分钟左右。成功后,控制台日志如下:

[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:12 min
[INFO] Finished at: 2022-02-12T09:52:38+08:00
[INFO] Final Memory: 250M/2256M
[INFO] ------------------------------------------------------------------------

JDK 版本的选择?

如下的 JDK 版本,是艿艿在本地测试通过的

  • JDK 8 版本:尽量保证 >= 1.8.0_144
  • JDK 11 版本:尽量保证 >= 11.0.14
  • JDK 17 版本:尽量保证 >= 17.0.2

如果 JDK 版本过低,包括 JDK 的小版本过低,也会 mvn 编译报错。例如说: “编译器(1.8.0_40)中出现编译错误“。此处,升级下 JDK 版本即可。

Maven 补充说明:

① 只有首次需要执行 Maven 命令,解决基础 pom.xml 文件不存在,导致报 BaseDbUnitTest 类不存在的问题。

② 如果执行报 Unknown lifecycle phase “.test.skip=true” 错误,使用 mvn clean install package -Dmaven.test.skip=true 即可。

#5.2 启动项目

第二步,执行 YudaoServerApplication (opens new window)类,进行启动。

启动还是报类不存在?

可能是 IDEA 的 bug,点击 [File -> Invalidate Caches] 菜单,清空下缓存,重启后在试试看。

启动后端项目

启动完成后,使用浏览器访问 http://127.0.0.1:48080 (opens new window)地址,返回如下 JSON 字符串,说明成功。

友情提示:注意,默认配置下,后端项目启动在 48080 端口。

{
"code": 401,
"data": null,
"msg": "账号未登录"
}

如果报 “Command line is too long” 错误,参考 《Intellij IDEA 运行时报 Command line is too long 解决方法 》 (opens new window)文章解决,或者直接点击 YudaoServerApplication 蓝字部分!

“Command line is too long” 错误

#5.3 启动其它模块

考虑到启动速度,默认值启动 system 系统服务,infra 基础设施两个模块。如果你需要启动其它模块,可以参考下面的文档:

启动前端项目

项目的管理后台有 4 个版本:

#1.1 Vue3 + element-plus 版本

yudao-ui-admin-vue3 (opens new window)是前端 Vue3 管理后台项目。

① 克隆 https://github.com/yudaocode/yudao-ui-admin-vue3.git (opens new window)项目,并 Star 关注下该项目。

② 在根目录执行如下命令,进行启动:

# 安装 pnpm,提升依赖的安装速度
npm config set registry https://registry.npmjs.org
npm install -g pnpm
# 安装依赖
pnpm install

# 启动服务
npm run dev

③ 启动完成后,浏览器会自动打开 http://localhost:80 (opens new window)地址,可以看到前端界面。

前端界面

友情提示:Vue3 使用 Vite 构建,所以它存在如下的情况,都是正常的:

  1. 项目启动很快,浏览器打开需要等待 1 分钟左右,请保持耐心。
  2. 点击菜单,感觉会有一点卡顿,因为 Vite 采用懒加载机制。不用担心,最终部署到生产环境,就不存在这个问题了。

详细说明,可见 《为什么有人说 Vite 快,有人却说 Vite 慢?》 (opens new window)文章。

疑问:我是前端工程师,不想启动后端项目,怎么办?

可以将上述的 npm run dev 命令,替代成 npm run front 命令。

远程 演示环境的后端服务,只允许 GET 请求,不允许 POSTPUTDELETE 等请求。

#1.4 Vue2 + uni-app 版本

yudao-ui-admin-uniapp (opens new window)是前端 uni-app 管理后台项目。

① 克隆 https://github.com/yudaocode/yudao-ui-admin-uniapp.git (opens new window)项目,并 Star 关注下该项目。

② 下载 HBuilder (opens new window)工具,并进行安装。

③ 点击 HBuilder 的 [文件 -> 导入 -> 从本地项目导入...] 菜单,选择项目的 yudao-ui-admin-uniapp 目录。

④ 执行如下命令,安装 npm 依赖:

# 安装 npm 依赖
npm i

⑤ 点击 HBuilder 的 [运行 -> 运行到内置浏览器] 菜单,使用 H5 的方式运行。成功后,界面如下图所示:

前端界面

友情提示:登录时,滑块验证码,在内存浏览器可能存在兼容性的问题,此时使用 Chrome 浏览器,并使用“开发者工具”,设置为 iPhone 12 Pro 模式!

疑问:我是前端工程师,不想启动后端项目,怎么办?

修改 config.js 配置文件的 baseUrl 后端服务的地址为 'http://api-dashboard.yudao.iocoder.cn。如下图所示:

修改  配置文件的  后端服务的地址

远程 演示环境的后端服务,只允许 GET 请求,不允许 POSTPUTDELETE 等请求。

#2. uni-app 商城移动端

yudao-mall-uniapp (opens new window)是前端 uni-app 商城移动端项目。

前置任务:

需要参考 《商城手册 —— 功能开启》 文档,将商城的后端启动。

① 克隆 https://github.com/yudaocode/yudao-mall-uniapp (opens new window)项目,并 Star 关注下该项目。

② 下载 HBuilder (opens new window)工具,并进行安装。

③ 点击 HBuilder 的 [文件 -> 导入 -> 从本地项目导入...] 菜单,选择克隆的 yudao-mall-uniapp 目录

④ 点击 HBuilder 的 [运行 -> 运行到内置浏览器] 菜单,使用 H5 的方式运行。成功后,界面如下图所示:

前端界面

疑问:我是前端工程师,不想启动后端项目,怎么办?

修改 request.js 的后端服务的地址为 'http://api-dashboard.yudao.iocoder.cn/。如下图所示:

修改  配置文件的  后端服务的地址

远程 演示环境的后端服务,只允许 GET 请求,不允许 POSTPUTDELETE 等请求。

接口文档

项目使用 Swagger 实现 RESTful API 的接口文档,提供两种解决方案:

*【推荐】 Apifox (opens new window):强大的 API 工具,支持 API 文档、API 调试、API Mock、API 自动化测试

  • Knife4j:简易的 API 工具,仅支持 API 文档、API 调试

为什么选择 Swagger 呢?

Swagger 通过 Java 注解实现 API 接口文档的编写。相比使用 Java 注释的方式,注解提供更加规范的接口定义方式,开发体验更好。

如果你没有学习 Swagger,可以阅读 《芋道 Spring Boot API 接口文档 Swagger 入门 》 (opens new window)文章。

#1. Apifox 使用

本小节,我们来将项目中的 API 接口,一键导入到 Apifox 中,并使用它发起一次 API 的调用。

#1.1 下载工具

点击 Apifox (opens new window)首页,下载对应的 Apifox 桌面版。如下图所示:

为什么要下载 Apifox 桌面版?

艿艿已经卸载 Postman,使用 Apifox 进行替代。国产软件,yyds 永远滴神!

国内很多互联网公司,包括百度、阿里、腾讯、字节跳动等等在内,都在使用 Apifox 作为 API 工具。

Apifox 下载

解压后,双击进行安装即可。黑色界面,非常酷炫。

Apifox 界面

#1.2 API 导入

① 先点击「示例项目」,再点击「+」按钮,选择「导入」选项。

Apifox 界面 —— 导入

② 先选择「URL 导入」按钮,填写 Swagger 数据 URL 为 http://127.0.0.1:48080/v3/api-docs

Apifox 界面 —— Swagger

③ 先点击「提交」按钮,再点击「确认导入」按钮,完成 API 接口的导入。

Apifox 界面 —— Swagger

④ 导入完成后,点击「接口管理」按钮,可以查看到 API 列表。

Apifox 界面 —— 接口管理

#1.3 API 调试

① 先点击右上角「请选择环境」,再点击「管理环境」选项,填写测试环境的地址为 http://127.0.0.1:48080,并进行保存。

Apifox 界面 —— 管理环境

② 点击「管理后台 —— 认证」的「使用账号密码登录」接口,查看该 API 接口的定义。

Apifox 界面 —— 认证

③ 点击「运行」按钮,填写 Headers 的 tenant-id 为 1,再点击 Body 的「自动生成」按钮,最后点击「发送」按钮。

Apifox 界面 —— 认证

注意,登录接口不要填写 socialTypesocialCodesocialState 这三个参数,它们是三方登录的参数。一定要去掉,不然会报错噢!

#1.4 常见问题

问题 ①:分页 GET 请求时,如果有 createTime 这种时间类型的数组参数,会报错。如下图所示:

Apifox 常见问题 1

答:把 createTime 左右两边的 [] 去掉,即可解决。

#2. Knife4j 使用

浏览器访问 http://127.0.0.1:48080/doc.html (opens new window)地址,使用 Knife4j 查看 API 接口文档。

Knife4j 界面

① 点击任意一个接口,进行接口的调用测试。这里,使用「管理后台 - 用户个中心」的“获得登录用户信息”举例子。

② 点击左侧「调试」按钮,并将请求头部的 header-idAuthorization 勾选上。

其中,header-id 为租户编号,Authorization"Bearer test" 后面为用户编号(模拟哪个用户操作)。

如果不勾选,会出现 "请求的租户标识未传递,请进行排查""账号未登录" 错误。

③ 点击「发送」按钮,即可发起一次 API 的调用。

Knife4j 调试

#3. Swagger 技术组件

① 在 yudao-spring-boot-starter-web (opens new window)技术组件的 swagger (opens new window)包,实现了对 Swagger 的封装。

② 如果想要禁用 Swagger 功能,可通过 springdoc.api-docs.enable 配置项为 false。一般情况下,建议 prod 生产环境进行禁用,避免发生安全问题。

Swagger 关闭

技术选型

#技术架构图

架构图

#👻 后端

#系统环境
框架说明版本学习指南
JDKJava 开发工具包>= 1.8.0书单(opens new window)
MavenJava 管理与构建工具>= 3.5.0书单(opens new window)
Nginx高性能 Web 服务器-文档(opens new window)
#主框架
框架说明版本学习指南
Spring Boot(opens new window)应用开发框架2.7.13文档(opens new window)
Spring MVC(opens new window)MVC 框架5.3.24文档(opens new window)
Spring Security(opens new window)Spring 安全框架5.7.6文档(opens new window)
Hibernate Validator(opens new window)参数校验组件6.2.5文档(opens new window)
#存储层
框架说明版本学习指南
MySQL(opens new window)数据库服务器>= 5.7书单(opens new window)
Druid(opens new window)JDBC 连接池、监控组件1.2.18文档(opens new window)
MyBatis Plus(opens new window)MyBatis 增强工具包3.5.3.1文档(opens new window)
Dynamic Datasource(opens new window)动态数据源3.6.1文档(opens new window)
Redis(opens new window)key-value 数据库>= 5.0书单(opens new window)
Redisson(opens new window)Redis 客户端3.17.7文档(opens new window)
#中间件
框架说明版本学习指南
Flowable(opens new window)工作流引擎6.8.0文档(opens new window)
Quartz(opens new window)任务调度组件2.3.2文档(opens new window)
Resilience4j(opens new window)服务保障组件1.7.1文档(opens new window)
#系统监控
框架说明版本学习指南
Spring Boot Admin(opens new window)Spring Boot 监控平台2.7.10文档(opens new window)
SkyWalking(opens new window)分布式应用追踪系统8.5.0文档(opens new window)
#单元测试
框架说明版本学习指南
JUnit(opens new window)Java 单元测试框架5.8.2-
Mockito(opens new window)Java Mock 框架4.8.0-
#其它工具
框架说明版本学习指南
Springdoc(opens new window)Swagger 文档1.6.15文档(opens new window)
Jackson(opens new window)JSON 工具库2.13.3
MapStruct(opens new window)Java Bean 转换1.5.5.Final文档(opens new window)
Lombok(opens new window)消除冗长的 Java 代码1.18.26文档(opens new window)

#👾 前端

#管理后台(Vue3 + ElementPlus)
框架说明版本
Vue(opens new window)vue 框架3.2.45
Vite(opens new window)开发与构建工具4.0.1
Element Plus(opens new window)Element Plus2.2.26
TypeScript(opens new window)JavaScript 的超集4.9.4
pinia(opens new window)Vue 存储库 替代 vuex52.0.28
vueuse(opens new window)常用工具集9.6.0
vxe-table(opens new window)vue 最强表单4.3.7
vue-i18n(opens new window)国际化9.2.2
vue-router(opens new window)vue 路由4.1.6
windicss(opens new window)下一代工具优先的 CSS 框架3.5.6
iconify(opens new window)在线图标库3.0.0
wangeditor(opens new window)富文本编辑器5.1.23
#管理后台(Vue3 + Vben + Ant-Design-Vue)
框架说明版本
Vue(opens new window)Vue 框架3.2.47
Vite(opens new window)开发与构建工具4.3.0
ant-design-vue(opens new window)ant-design-vue3.2.17
TypeScript(opens new window)JavaScript 的超集5.0.4
pinia(opens new window)Vue 存储库 替代 vuex52.0.34
vueuse(opens new window)常用工具集9.13.0
vue-i18n(opens new window)国际化9.2.2
vue-router(opens new window)Vue 路由4.1.6
windicss(opens new window)下一代工具优先的 CSS 框架3.5.6
iconify(opens new window)在线图标库3.1.0
#管理后台(Vue2)
框架说明版本学习指南
Node(opens new window)JavaScript 运行时环境>= 12-
Vue(opens new window)JavaScript 框架2.7.14书单(opens new window)
Vue Element Admin(opens new window)后台前端解决方案2.5.10
#管理后台(uni-app)
框架说明版本
uni-app跨平台框架2.0.0
uni-ui(opens new window)基于 uni-app 的 UI 框架1.4.20
#用户 App
框架说明版本学习指南
Vue(opens new window)JavaScript 框架2.6.12书单(opens new window)
UniApp(opens new window)小程序、H5、App 的统一框架--

项目结构

项目结构

#👻 后端结构

后端采用模块化的架构,按照功能拆分成多个 Maven Module,提升开发与研发的效率,带来更好的可维护性。

一共有类 Maven Module:

Maven Module作用
yudao-dependenciesMaven 依赖版本管理
yudao-frameworkJava 框架拓展
yudao-module-xxxXXX 功能的 Module 模块
yudao-server管理后台 + 用户 App 的服务端

下面,我们来逐个看看。

#1. yudao-dependencies

该模块是一个 Maven Bom,只有一个 pom.xml (opens new window)文件,定义项目中所有 Maven 依赖的版本号,解决依赖冲突问题。

详细的解释,可见 《微服务中使用 Maven BOM 来管理你的版本依赖 》 (opens new window)文章。

从定位上来说,它和 Spring Boot 的 spring-boot-starter-parent (opens new window)和 Spring Cloud 的 spring-cloud-dependencies (opens new window)是一致的。

实际上,ruoyi-vue-pro 本质上还是个单体项目,直接在根目录 pom.xml (opens new window)管理依赖版本会更加方便,也符合绝大多数程序员的认知。但是要额外考虑一个场景,如果每个 yudao-module-xxx 模块都维护在一个独立的 Git 仓库,那么 yudao-dependencies 就可以在多个 yudao-module-xxx 模块下复用。

#2. yudao-framework

该模块是 ruoyi-vue-pro 项目的框架封装,其下的每个 Maven Module 都是一个组件,分成两种类型:

① 技术组件:技术相关的组件封装,例如说 MyBatis、Redis 等等。

Maven Module作用
yudao-common定义基础 pojo 类、枚举、工具类等
yudao-spring-boot-starter-webWeb 封装,提供全局异常、访问日志等
yudao-spring-boot-starter-security认证授权,基于 Spring Security 实现
yudao-spring-boot-starter-mybatis数据库操作,基于 MyBatis Plus 实现
yudao-spring-boot-starter-redis缓存操作,基于 Spring Data Redis + Redisson 实现
yudao-spring-boot-starter-mq消息队列,基于 Redis 实现,支持集群消费和广播消费
yudao-spring-boot-starter-job定时任务,基于 Quartz 实现,支持集群模式
yudao-spring-boot-starter-flowable工作流,基于 Flowable 实现
yudao-spring-boot-starter-protection服务保障,提供幂等、分布式锁、限流、熔断等功能
yudao-spring-boot-starter-file文件客户端,支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、SFTP、数据库等
yudao-spring-boot-starter-excelExcel 导入导出,基于 EasyExcel 实现
yudao-spring-boot-starter-monitor服务监控,提供链路追踪、日志服务、指标收集等功能
yudao-spring-boot-starter-captcha验证码 Captcha,提供滑块验证码
yudao-spring-boot-starter-test单元测试,基于 Junit + Mockito 实现
yudao-spring-boot-starter-banner控制台 Banner,启动打印各种提示
yudao-spring-boot-starter-desensitize脱敏组件:支持 JSON 返回数据时,将邮箱、手机等字段进行脱敏

② 业务组件:业务相关的组件封装,例如说数据字典、操作日志等等。如果是业务组件,名字会包含 biz 关键字。

Maven Module作用
yudao-spring-boot-starter-biz-tenantSaaS 多租户
yudao-spring-boot-starter-biz-data-permissionn数据权限
yudao-spring-boot-starter-biz-dict数据字典
yudao-spring-boot-starter-biz-operatelog操作日志
yudao-spring-boot-starter-biz-pay支付客户端,对接微信支付、支付宝等支付平台
yudao-spring-boot-starter-biz-sms短信客户端,对接阿里云、腾讯云等短信服务
yudao-spring-boot-starter-biz-social社交客户端,对接微信公众号、小程序、企业微信、钉钉等三方授权平台
yudao-spring-boot-starter-biz-weixin微信客户端,对接微信的公众号、开放平台等
yudao-spring-boot-starter-biz-error-code全局错误码
yudao-spring-boot-starter-biz-ip地区 & IP 库

每个组件,包含两部分:

  1. core 包:组件的核心封装,拓展相关的功能。
  2. config 包:组件的 Spring Boot 自动配置。

 示例

#3. yudao-module-xxx

该模块是 XXX 功能的 Module 模块,目前内置了 8 个模块。

项目说明是否必须
yudao-module-system系统功能
yudao-module-infra基础设施
yudao-module-member会员中心x
yudao-module-bpm工作流程x
yudao-module-pay支付系统x
yudao-module-report大屏报表x
yudao-module-mall商城系统x
yudao-module-mp微信公众号x

每个模块包含两个 Maven Module,分别是:

Maven Module作用
yudao-module-xxx-api提供给其它模块的 API 定义
yudao-module-xxx-biz模块的功能的具体实现

例如说,yudao-module-infra 想要访问 yudao-module-system 的用户、部门等数据,需要引入 yudao-module-system-api 子模块。示例如下:

引用的示例

疑问:为什么设计 yudao-module-xxx-api 模块呢?

  1. 明确需要提供给其它模块的 API 定义,方便未来迁移微服务架构。
  2. 模块之间可能会存在相互引用的情况,虽然说从系统设计上要尽量避免,但是有时在快速迭代的情况下,可能会出现。此时,通过只引用对方模块的 API 子模块,解决相互引用导致 Maven 无法打包的问题。

yudao-module-xxx-api 子模块的项目结构如下:

 项目结构

所在包作用示例
apiApi 接口提供给其它模块的 API 接口AdminUserApi(opens new window)
apiDTO 类Api 接口的入参 ReqDTO、出参 RespDTOLoginLogCreateReqDTO (opens new window)DeptRespDTO(opens new window)
enumsEnum 类字段的枚举LoginLogTypeEnum(opens new window)
enumsDictTypeConstants 类数据字典的枚举DictTypeConstants(opens new window)
enumsErrorCodeConstants 类错误码的枚举ErrorCodeConstants(opens new window)

yudao-module-xxx-biz 子模块的项目结构如下:

 项目结构

所在包作用示例
apiApiImpl 类提供给其它模块的 API 实现类AdminUserApiImpl(opens new window)
controler.adminController 类提供给管理后台的 RESTful API,默认以 admin-api/ 作为前缀。 例如 admin-api/system/auth/login 登录接口AuthController(opens new window)
controler.adminVO 类Admin Controller 接口的入参 ReqVO、出参 RespVOAuthLoginReqVO (opens new window)AuthLoginRespVO(opens new window)
controler.appController 类,以 App 为前缀提供给用户 App 的 RESTful API,默认以 app-api/ 作为前缀。 例如 app-api/member/auth/login 登录接口AppAuthController(opens new window)
controler.appVO 类,以 App 为前缀App Controller 接口的入参 ReqVO、出参 RespVOAppAuthLoginReqVO (opens new window)AppAuthLoginRespVO(opens new window)
controler.http 文件IDEA Http Client 插件 (opens new window),模拟请求 RESTful 接口AuthController.http(opens new window)
serviceService 接口业务逻辑的接口定义AdminUserService(opens new window)
serviceServiceImpl 类业务逻辑的实现类AdminUserServiceImpl(opens new window)
dal-Data Access Layer,数据访问层
dal.dataobjectDO 类Data Object,映射数据库表、或者 Redis 对象AdminUserDO(opens new window)
dal.mysqlMapper 接口数据库的操作AdminUserMapper(opens new window)
dal.redisRedisDAO 类Redis 的操作LoginUserRedisDAO(opens new window)
convertConvert 接口DTO / VO / DO 等对象之间的转换器UserConvert(opens new window)
jobJob 类定时任务DemoJob(opens new window)
mq-Message Queue,消息队列
mq.messageMessage 类发送和消费的消息SmsSendMessage(opens new window)
mq.producerProducer 类消息的生产者SmsProducer(opens new window)
mq.consumerProducer 类消息的消费者SmsSendConsumer(opens new window)
framework-模块自身的框架封装framework(opens new window)

疑问:为什么 Controller 分成 Admin 和 App 两种?

提供给 Admin 和 App 的 RESTful API 接口是不同的,拆分后更加清晰。

疑问:为什么 VO 分成 Admin 和 App 两种?

相同功能的 RESTful API 接口,对于 Admin 和 App 传入的参数、返回的结果都可能是不同的。例如说,Admin 查询某个用户的基本信息时,可以返回全部字段;而 App 查询时,不会返回 mobile 手机等敏感字段。

疑问:为什么 DO 不作为 Controller 的出入参?

  1. 明确每个 RESTful API 接口的出入参。例如说,创建部门时,只需要传入 name、parentId 字段,使用 DO 接参就会导致 type、createTime、creator 等字段可以被传入,导致前端同学一脸懵逼。
  2. 每个 RESTful API 有自己独立的 VO,可以更好的设置 Swagger 注解、Validator 校验规则,而让 DO 保持整洁,专注映射好数据库表。

疑问:为什么操作 Redis 需要通过 RedisDAO?

Service 直接使用 RedisTemplate 操作 Redis,导致大量 Redis 的操作细节和业务逻辑杂糅在一起,导致代码不够整洁。通过 RedisDAO 类,将每个 Redis Key 像一个数据表一样对待,清晰易维护。

总结来说,每个模块采用三层架构 + 非严格分层,如下图所示:

项目分层

疑问:如果 message 需要跨模块共享,类似 api 的效果,可以怎么做?

可以在 yudao-module-xxx-api 子模块下,新建一个 message 包,可参考 MemberUserCreateMessage 类。

#4. yudao-server

该模块是后端 Server 的主项目,通过引入需要 yudao-module-xxx 业务模块,从而实现提供 RESTful API 给 yudao-ui-admin-vue3yudao-mall-uniapp 等前端项目。

本质上来说,它就是个空壳(容器)!如下图所示:

 项目

#👾 前端结构

前端一共有六个项目,分别是:

项目说明
yudao-ui-admin-vue3(opens new window)基于 Vue3 + element-plus 实现的管理后台
yudao-ui-admin-vben(opens new window)基于 Vue3 + vben(ant-design-vue) 实现的管理后台
yudao-ui-admin-vue2(opens new window)基于 Vue2 + element-ui 实现的管理后台
yudao-ui-go-view(opens new window)基于 Vue3 + naive-ui 实现的大屏报表
yudao-ui-admin-uniapp(opens new window)基于 uni-app + uni-ui 实现的管理后台的小程序
yudao-mall-uniapp(opens new window)基于 uni-app + uview 实现的用户 App
#1. yudao-admin-ui-vue3
.
├── .github # github workflows 相关
├── .husky # husky 配置
├── .vscode # vscode 配置
├── mock # 自定义 mock 数据及配置
├── public # 静态资源
├── src # 项目代码
│ ├── api # api接口管理
│ ├── assets # 静态资源
│ ├── components # 公用组件
│ ├── hooks # 常用hooks
│ ├── layout # 布局组件
│ ├── locales # 语言文件
│ ├── plugins # 外部插件
│ ├── router # 路由配置
│ ├── store # 状态管理
│ ├── styles # 全局样式
│ ├── utils # 全局工具类
│ ├── views # 路由页面
│ ├── App.vue # 入口vue文件
│ ├── main.ts # 主入口文件
│ └── permission.ts # 路由拦截
├── types # 全局类型
├── .env.base # 本地开发环境 环境变量配置
├── .env.dev # 打包到开发环境 环境变量配置
├── .env.gitee # 针对 gitee 的环境变量 可忽略
├── .env.pro # 打包到生产环境 环境变量配置
├── .env.test # 打包到测试环境 环境变量配置
├── .eslintignore # eslint 跳过检测配置
├── .eslintrc.js # eslint 配置
├── .gitignore # git 跳过配置
├── .prettierignore # prettier 跳过检测配置
├── .stylelintignore # stylelint 跳过检测配置
├── .versionrc 自动生成版本号及更新记录配置
├── CHANGELOG.md # 更新记录
├── commitlint.config.js # git commit 提交规范配置
├── index.html # 入口页面
├── package.json
├── .postcssrc.js # postcss 配置
├── prettier.config.js # prettier 配置
├── README.md # 英文 README
├── README.zh-CN.md # 中文 README
├── stylelint.config.js # stylelint 配置
├── tsconfig.json # typescript 配置
├── vite.config.ts # vite 配置
└── windi.config.ts # windicss 配置
#2. yudao-ui-admin-vben
.
├── build # 打包脚本相关
│ ├── config # 配置文件
│ ├── generate # 生成器
│ ├── script # 脚本
│ └── vite # vite配置
├── mock # mock文件夹
├── public # 公共静态资源目录
├── src # 主目录
│ ├── api # 接口文件
│ ├── assets # 资源文件
│ │ ├── icons # icon sprite 图标文件夹
│ │ ├── images # 项目存放图片的文件夹
│ │ └── svg # 项目存放svg图片的文件夹
│ ├── components # 公共组件
│ ├── design # 样式文件
│ ├── directives # 指令
│ ├── enums # 枚举/常量
│ ├── hooks # hook
│ │ ├── component # 组件相关hook
│ │ ├── core # 基础hook
│ │ ├── event # 事件相关hook
│ │ ├── setting # 配置相关hook
│ │ └── web # web相关hook
│ ├── layouts # 布局文件
│ │ ├── default # 默认布局
│ │ ├── iframe # iframe布局
│ │ └── page # 页面布局
│ ├── locales # 多语言
│ ├── logics # 逻辑
│ ├── main.ts # 主入口
│ ├── router # 路由配置
│ ├── settings # 项目配置
│ │ ├── componentSetting.ts # 组件配置
│ │ ├── designSetting.ts # 样式配置
│ │ ├── encryptionSetting.ts # 加密配置
│ │ ├── localeSetting.ts # 多语言配置
│ │ ├── projectSetting.ts # 项目配置
│ │ └── siteSetting.ts # 站点配置
│ ├── store # 数据仓库
│ ├── utils # 工具类
│ └── views # 页面
├── test # 测试
│ └── server # 测试用到的服务
│ ├── api # 测试服务器
│ ├── upload # 测试上传服务器
│ └── websocket # 测试ws服务器
├── types # 类型文件
├── vite.config.ts # vite配置文件
└── windi.config.ts # windcss配置文件
4. yudao-admin-ui-uniapp

TODO 待补充

#5. yudao-mall-uniapp

建设中,基于 uniapp 实现...

#6. yudao-ui-go-view

TODO 待补充

代码热加载

在日常开发中,我们需要经常修改 Java 代码,手动重启项目,查看修改后的效果。如果在项目小时,重启速度比较快,等待的时间是较短的。但是随着项目逐渐变大,重启的速度变慢,等待时间 1-2 min 是比较常见的。

这样就导致我们开发效率降低,影响我们的下班时间,哈哈哈~

那么是否有方式能够实现,在我们修改完 Java 代码之后,能够不重启项目呢?答案是有的,通过 代码热加载 的方式。实现方案有三种:

  1. spring-boot-devtools【不推荐】
  2. IDEA 自带 HowSwap 功能【推荐】
  3. JRebel 插件【最推荐】

#1. spring-boot-devtools

spring-boot-devtools (opens new window)是 Spring Boot 提供的开发者工具,它会监控当前应用所在的 classpath 下的文件发生变化,进行自动重启

devtools 存在重启速度较慢的问题,所以不推荐!

#2. IDEA 自带 HowSwap 功能

该功能是 IDEA Ultimate 旗舰版的专属功能,不支持 IDEA Community 社区版。

#2.1 如何使用

① 设置 Spring Boot 启动类,开启 HotSwap 功能。如下图所示:

IDEA 配置热加载

② Debug 运行该启动类,等待项目启动完成。

③ 每次修改 Java 代码后,点击左下角的「热加载」按钮,即可实现代码热加载。如下图所示:

IDEA 代码热加载

#2.2 存在问题

IDEA 自带 HowSwap 功能,支持比较有限,很多修改都不支持。例如说:

  • 只能增加方法或字段但不可以减少方法或字段
  • 只能增加可见性不能减少
  • 只能维持已有方法的签名而不能修改等等。

你可以认为,只支持方法内的代码修改热加载。

如果想要相对完美的方案,建议使用 JRebel 插件。

#3. JRebel 插件【最推荐】

JRebel 插件是目前最好用的热加载插件,它支持 IDEA Ultimate 旗舰版、Community 社区版。

#3.1 如何安装

① 点击 https://plugins.jetbrains.com/plugin/4441-jrebel-and-xrebel/versions (opens new window)地址,必须下载 2022.4.1 版本。如下图所示:

JRebel 下载

② 打开 [Preference -> Plugins] 菜单,点击「Install Plugin from Disk...」按钮,选择刚下载的 JRebel 插件的压缩包。如下图所示:

JRebel 安装

安装完成后,需要重启 IDEA 生效。

③ 打开 [Preference -> JRebel & XRebel] 菜单,输入 GUID address 为 https://jrebel.qekang.com/1e67ec1b-122f-4708-87d0-c1995dc0cdaa ,邮件随便写,完成 JRebel 的激活。如下图所示:

JRebel 激活

之后,点击「Work Offline」按钮,设置 JRebel 为离线,避免因为网络问题导致激活失效。如下图所示:

JRebel 离线

#3.2 如何使用

① 点击「Debug With JRebel」按钮,使用 JRebel 启动项目。如下图所示:

JRebel 启动项目

② 每次修改 Java 代码后,点击左下角的「热加载」按钮,即可实现代码热加载。如下图所示:

JRebel 代码热加载

一键改包

项目提供了 ProjectReactor (opens new window)程序,支持一键改包,包括 Maven 的 groupIdartifactId、Java 的根 package、前端的 title、数据库的 SQL 配置、应用的 application.yaml 配置文件等等。效果如下图所示:

效果

友情提示:修改包名后,未来合并最新的代码可能会有一定的成本。

#操作步骤

① 第一步,使用 IDEA (opens new window)克隆 https://github.com/YunaiV/ruoyi-vue-pro (opens new window)仓库的最新代码,并给该仓库一个 Star (opens new window)

② 第二步,打开 ProjectReactor 类,填写 groupIdNewartifactIdNewpackageNameNewtitleNew 属性。如下图所示:

效果

③ 第三步,执行 ProjectReactor 的 #main(String[] args) 方法,它会基于当前项目,复制一个新项目到 projectBaseDirNew 目录,并进行相关的改名逻辑。

13:02:36.765 [main] INFO cn.iocoder.yudao.ProjectReactor - [main][开始获得需要重写的文件]
13:02:41.530 [main] INFO cn.iocoder.yudao.ProjectReactor - [main][需要重写的文件数量:2825,预计需要 5-10 秒]
13:02:45.799 [main] INFO cn.iocoder.yudao.ProjectReactor - [main][重写完成]

④ 第四步,使用 IDEA 打开 projectBaseDirNew 目录,参考 《开发指南 —— 快速启动》 文档,进行项目的启动。注意,一定要重新执行 SQL 的导入!!!

删除功能

项目内置功能较多,会存在一些你可能用不到的功能。一般的情况下,建议通过设置该功能对应的菜单为【禁用】,实现功能的“删除”。如下图所示:

设置菜单为禁用

后续,如果你又需要使用到该功能,只需要设置该功能对应的菜单为【开启】即可。

🙂 当然,如果你希望彻底删除功能,那么就需要采用删除代码的方式。整个过程如下:

① 【菜单】第一步,使用管理后台的菜单管理,删除对应的菜单、按钮。 ② 【数据库表】第二步,删除对应的数据库表。 ③ 【后端代码】第三步,删除对应的 Controller、Service、数据库实体等后端代码;然后启动后端项目,若存在代码报错,则继续删除相关联的代码,之后如此反复,直到成功。 ④ 【前端代码】第四步,删除对应的 View 和 API 等前端代码;然后启动前端项目,若存在代码报错,则继续删除相关联的代码,之后如此反复,直到成功。

下面,我们来举一些例子。

#删除「多租户」功能

  • 对应功能的文档:多租户
  • 对应的关键字是 tenant
#第一步,删除菜单

删除“租户管理“下的所有菜单,从最里层的按钮开始。如下图所示:

删除“租户管理“菜单

#第二步,删除数据库表

删除 system_tenantsystem_tenant_package 表。如下图所示:

删除数据库表

#第三步,删除后端代码

① 删除 yudao-module-system-api 模块的 api/tenant (opens new window)包。

② 删除 yudao-module-system-api 模块的 ErrorCodeConstants (opens new window)类中,和租户、租户套餐相关的错误码。如下图所示:

删除错误码

如果想删除的更干净,可以把 system_error_code 表中,对应编号的错误码也都删除一下。

③ 删除 yudao-module-system-biz 模块的如下包:

④ 删除 yudao-spring-boot-starter-biz-tenant (opens new window)模块。

然后,使用 IDEA 搜索 yudao-spring-boot-starter-biz-tenant 关键字,删除 Maven 中所有对它的定义与引用。如下图所示:

删除  使用

之后,使用 IDEA 刷新下 Maven 依赖。如下图所示:

租户-刷新Maven依赖

⑤ 运行 YudaoServerApplication 启动类,会报 cn.iocoder.yudao.framework.tenant.core.db 不存在的错误,需要将继承 TenantBaseDO 的数据库实体,都改成继承 BaseDO 基类。

租户-修改继承BaseDO类

⑥ 运行 YudaoServerApplication 启动类,会报 cn.iocoder.yudao.framework.tenant.core.aop 不存在的错误,需要去除对 @TenantIgnore 注解的使用。如下图所示:

租户-删除@TenantIgnore注解

⑦ 运行 YudaoServerApplication 启动类,会报 cn.iocoder.yudao.module.system.service.tenant 不存在的错误,需要去除对 TenantService 的使用。如下图所示:

租户-删除TenantService的使用

⑧ 运行 YudaoServerApplication 启动类,会报 cn.iocoder.yudao.framework.tenant.core.context 不存在的错误,需要去除对 TenantContextHolder 的使用。如下图所示:

租户-删除TenantContextHolder的使用

⑨ 运行 YudaoServerApplication 启动类,终于成功了!!!

ps:可以将 application.yaml 配置文件中,对应的 yudao.tenant 配置项给进一步删除。

#第四步,删除前端代码

yudao-admin-ui 为示例~

① 删除 View 和 API 的前端代码:

② 在 yudao-admin-ui 目录下,执行 npm run local 成功。访问登录页,结果访问白屏。需要清理 login.vue 页,涉及 tenant 关键字的代码。例如说:

清理 login.vue 的代码

刷新,成功访问登录界面。

③ 在 yudao-admin-ui 目录下,搜索 tenantTenant 关键字,可进一步清理多租户的代码。例如说:

进一步清理前端代码

#第五步,测试验收

至此,我们已经完成了多租户的代码删除,还是蛮艰辛的~

后续,你可以简单测试一下,看看是不是删除代码,导致一些小问题。

内网穿透

在和外部系统对接时,经常需要将本地的服务,暴露到外网中。这时候,就需要使用内网穿透工具了。例如说:支付宝回调、微信支付回调、微信公众号接入、微信小程序接入等等。

常见的内网穿透工具,例如说,ngrok (opens new window)frp (opens new window)natapa (opens new window)等等。

这里,我们使用 natapp 作为内网穿透工具,转发到后端的 48080 端口。

#1. 第一步,购买隧道

访问 https://natapp.cn/tunnel/buy/free (opens new window)地址,免费购买一个隧道。如下图所示:

免费购买一个隧道

#2. 第二步,启动隧道

购买完成后,参考 《NATAPP 1 分钟快速新手图文教程》 (opens new window)文档,将 natapp 进行启动。如下图所示:

启动隧道

达梦数据库专属

#1. DM 数据库的安装

可以使用 Windows 或 Docker 等多种方式。

注意,目前我们使用的是 DM 8.0 的版本。

#1.1 Windows 方式

参考 官方文档(opens new window)

① 下载 Windows 版本(20230928):https://download.dameng.com/eco/adapter/DM8/202310/dm8_20230928_x86_win_64.zip(opens new window)

② 傻瓜式安装、数据库实例化,一路下去就好,不用修改任何参数。

#1.2 Docker 方式

参考 官方文档(opens new window)

① 下载 Docker 镜像 (版本: 20230808):https://download.dameng.com/eco/dm8/dm8_20230808_rev197096_x86_rh6_64_single.tar(opens new window)

② 执行如下脚本,启动 Docker 服务:

docker load -i dm8_20230808_rev197096_x86_rh6_64_single.tar

docker run -d -p 5236:5236 \
--restart=unless-stopped \
--name dm8_test \
--privileged=true \
-e PAGE_SIZE=16 \
-e LD_LIBRARY_PATH=/opt/dmdbms/binn \
-e EXTENT_SIZE=32 \
-e BLANK_PAD_MODE=1 \
-e LOG_SIZE=1024 \
-e UNICODE_FLAG=1 \
-e LENGTH_IN_CHAR=1 \
-e INSTANCE_NAME=dm8_test \
-v $PWD/dm8_test:/opt/dmdbms/data \
dm8_single:dm8_20230808_rev197096_x86_rh6_64

备注:可以尝试使用大小写不敏感配置 -e CASE_SENSITIVE=N。需要停止并删除容器后,删除 dm8_test 目录,重新docker run

#2. 数据库导入

使用 DM 管理工具 (opens new window)进行数据的导入。如果你不是很了解,已可以看看文档:

具体步骤如下:

① 使用 DM 管理工具,新建一个名字为 RUOYI_VUE_PRO 的 schema 模式。如下图所示:

新建模式

为什么名字是 RUOYI_VUE_PRO 呢?

因为稍后使用的 sql/dm/ruoyi-vue-pro-dm8.sql 文件,使用的 schema 是它噢。后续跑通了,你可以按照自己的修改。

② 点击 DM 管理工具的 [执行 -> 执行脚本] 菜单,选中项目中的 sql/dm/ruoyi-vue-pro-dm8.sql 文件,之后点击 [绿色箭头] 进行执行即可。

#3. 项目启动

① 修改 yudao-spring-boot-starter-mybatis 模块的 pom.xml 文件,将 DM 依赖的 DmJdbcDriver18optional 移除。如下图所示:

数据库依赖

注意,需要使用 IDEA 刷新下 Maven 的依赖。

② 修改 application-local.yaml 配置文件,将数据库的 urlusernamepassword 修改为 DM 数据库。例如说:

数据库连接配置

③ 后续启动项目,就可以了。

#4. 补充说明

② 工作流的适配,可参考 《Flowable6.8(6.x 版本通用)整合集成达梦 8 数据库(DM8)详解,解决自动生成表时 dmn 相关表语法报错问题》 (opens new window)

http://1.119.164.247:8090/module-new/#%F0%9F%91%8D-%E7%9B%B8%E5%85%B3%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B