一、项目开篇:为什么要基于若依框架开发项目
为什么要基于若依框架开发?
-
快速开发:若依框架提供了许多现成的模块和工具 ,能够快速搭建起一个基本的应用框架 ,从而减少了开发的时间和工作量。
-
高度可定制性:若依框架提供了丰富的插件和扩展点,可以根据项目的需求进行定制和扩展,满足不同项目的特定需求。
-
简化开发流程:若依框架提供了许多常用的功能模块 ,如权限管理、数据字典、定时任务等,能够简化开发流程 ,提高开发效率。
-
易于维护和管理:若依框架采用了模块化的设计,代码结构清晰,易于维护和管理,有助于降低项目的维护成本。
-
社区支持和更新迭代:若依框架有一个活跃的开发社区,能够及时提供技术支持和更新迭代,保证项目的稳定性和安全性。
-
已毕业学员的强烈需要
本章的主题就是完成基于若依框架的前后端项目开发环境的搭建 ,熟悉若依框架前后端代码的结构 并进行简单的二次开发。
二、若依框架简介和若依框架中的版本选择
1、基本介绍
若依(RuoYi)框架是一款基于Spring Boot、Spring Cloud等开源框架搭建的企业级开发平台 。它的主要目标是提供全面的解决方案 ,以简化企业级应用开发 ,提高开发效率。以下是对若依框架的详细介绍:
-
模块化设计 :若依框架采用模块化的设计,使得应用可以根据需求进行灵活的扩展和定制。每个模块都可以独立部署和升级,这大大提高了系统的可维护性和可扩展性。
-
前后端分离:框架采用前后端分离的开发模式,后端专注于数据处理和API接口的提供,前端则负责页面的展示和用户交互。这种模式使得前后端职责明确,进一步提高了开发效率和代码的可维护性。
-
权限管理 :若依框架提供了完善的用户权限管理功能 ,包括角色管理、菜单授权、部门管理等,便于对系统权限进行灵活的配置和管理。
-
代码生成器 :框架内置代码生成器,能够快速生成前后端代码 ,减少重复劳动,提高开发效率。通过简单的配置即可生成基础的增删改查代码。
-
定时任务 :若依框架集成了定时任务模块 ,支持动态添加定时任务, 可以通过界面对定时任务进行管理与调度。此外,框架还能实时查看系统运行日志和在线用户信息,监控服务状态和性能。
-
易于集成 :若依框架可以轻松地与其他常用技术栈集成,如MySQL、Redis、消息队列等。这使得开发者可以根据项目需求灵活地选择合适的技术组件,降低技术门槛和成本。
此外,若依框架还集成了许多常用功能模块,如文件上传下载、消息推送、数据字典、日志管理等。
总的来说,若依框架是一款功能丰富、易于扩展和定制的企业级开发平台,适用于各种Web应用程序的开发。它能够帮助开发者快速构建功能完备的应用,提高开发效率,降低维护成本。
若依框架分为四个版本:
-
前后端不分离版本RuoYi(单体)
-
前后端分离版RuoYi-Vue(单体)本项目使用版本
-
微服务版本RuoYi-Cloud
-
移动端版RuoYi-App
前三个版本都提供了前后端的项目,移动端版本可以适配RuoYi-Vue和RuoYi-Cloud的后端项目
2、RuoYi-Vue前后端分离版
咱们课程中重点讲解的是RuoYi-Vue前后端分离版本,
文档地址:介绍 | RuoYi
(1)概述
RuoYi-Vue 是一个 JavaEE 企业级快速开发平台,基于经典技术组合(SpringBoot、SpringSecurity、MyBatis、Jwt、Vue),
内置模块有:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。
在线定时任务配置;支持集群,支持多数据源,支持分布式事务。
演示地址:若依管理系统
(2)技术选型
1、系统环境
-
Java EE 8 ---> jdk 11
-
Servlet 3.0
-
Apache Maven 3
2、主框架
-
Spring Boot 2.5.x
-
Spring Framework 5.2.x
-
Spring Security 5.2.x 安全框架
3、持久层
-
Apache MyBatis 3.5.x ---> MyBatis Plus
-
Hibernate Validation 6.0.x 校验框架
-
Alibaba Druid 1.2.x
4、视图层
-
Vue 2.6.x ----> Vue3
-
Axios 0.21.x
-
Element 2.15.x ----> Element Plus
三、环境搭建
熟悉了若依的基本情况之后,下面,咱们就快速上手,来把这个框架搭建起来,并且需要顺利跑起来
1、准备工作
基础软件准备
| 官方推荐 | 优化升级 |
|---|---|
| JDK >= 1.8 (推荐1.8版本) | 升级为JDK 11 资料中提供了安装包 |
| Maven >= 3.0 | 不需要安装,直接使用IDEA中自带的Maven即可 |
| Node >= 12 | 前端代码由vue2升级为vue3,需要Node 18及以上的版本 |
| Mysql >= 5.7.0 (推荐5.7版本) | 升级为MySQL 8 |
| Redis >= 3.0 | 本地启动 |
一般企业中服务器都是部署了一些项目中公用的基础环境,比如MySQL、Redis等这些。这些服务都是部署在linux服务器中,这些服务可能是部署在公司的一个机房 中,也有可能是云服务器(中小企业居多)。
在咱们教学的过程中,为了还原更真实的企业环境,咱们可以在VMWare软件中来部署linux服务器,当做咱们开发中的公用服务器 ,具体的VMWare服务配置请参考如下链接:虚拟机环境说明
在目前提供的虚拟机环境中已经使用docker安装了对应的基础环境,docker ps查看

详细说明如下:
| 软件名称 | 说明 |
|---|---|
| MySQL | 默认用户名:root,默认密码:heima123,端口:3306 |
| Redis | 默认密码:123456,端口:6379 |
运行中州养老项目,需要使用到MySQL和Redis,因此,这两个服务已经设置了开机自启,后面咱们的课程中会详细讲解和使用Redis
2、虚拟机环境说明
(1)挂载虚拟机
找到资料中的虚拟机镜像文件夹,解压后双击 CentOS 7 64位.vmx即可挂载到虚拟机中(需提前安装好VMWare)
编辑虚拟机-CD/DVD选择03虚拟机镜像中文件
网络适配器VMnet8(NAT模式)
双击后,在弹出的对话框中选择:我已移动此虚拟机,不让ip+1
(2)设置虚拟网络
因为此虚拟机已设置静态的ip地址,项目一采用的网段是192.168.100.0,所以为了减少环境网络的配置,可以手动设置虚拟机中NAT网卡的网段
设置步骤:
①:找到虚拟机的编辑按钮,打开虚拟网络编辑器
②:选中NAT模式的网卡,在下面的子网IP的输入框中手动 设置为:192.168.100.0,确定保存即可
DHCP设置也要改成192.168.100.128、192.168.100.254

③:右键虚拟机-->设置-->网络适配器-->自定义:选择Vmnet8(NAT模式)

④:启动服务器(网络设置完成后再启动服务器)
(2)FinalShell客户端链接
此虚拟机的静态ip为:192.168.100.168,防火墙已关闭,可以直接使用客户端连接
以FinalSehll工具为例:

注意:此虚拟机的用户名:root,密码:1234
2、运行后端项目
(1)下载代码
由于若依提供的代码的包名和项目名和咱们的需求不一致,因此这里暂时不要采用Git克隆的方式下载代码,直接下载ZIP包到本地,然后先替换所有的包名和项目名,再使用IDEA打开项目
注意注意:同学你好,为了避免若依官方代码更新后和后续课程中出现不一致的情况,这里强烈建议不要从gitee上拉取代码,直接使用课程资料中提供的后端初始代码:RuoYi-Vue-master.zip,和前端初始代码:RuoYi-Vue3-master.zip。这样就能确保初始代码环境和后续课程中保持一致,避免出现各种版本兼容的问题。
(2)包名全局替换
-
从官方下载的代码中所有包名都为com.rouyi,且数据库连接信息需要修改,此时,咱们可以借助若依框架修改器来一键修改:
-
可以使用资料中提供的若依框架修改器
请参考下方截图进行修改哦

- 修改完成之后,修改器会自动导出一个新的目录,将目录复制到你的代码目录中,然后使用idea打开即可:

打开项目后,先修改项目和模块使用的JDK版本为11。
- 修改pom.xml文件中JDK的版本为11

(3)maven配置
打开之后,需要配置maven的本地仓库,由于pom文件中引入的依赖较多,如果你的网络不稳定,建议将资料中的本地仓库先解压到自己的Maven仓库中

idea中的配置


- 修改idea中的项目编码为utf-8

(4)数据库准备和配置
-
数据库使用的MySQL 8
-
默认的用户名:root
-
默认的密码:heima123
-
在idea中创建数据库并导入项目中的基础表结构和数据
- 创建数据库 zzyl,可以打开项目根目录下的sql/ry_2025xxxx.sql文件:

打开这个文件,在最上方添加以下内容:
sql
create database if not exists zzyl;
use zzyl;
- 导入修改后的的sql/ry_2025xxxx.sql文件
sql执行成功以后,修改数据库连接,找到zzyl-admin模块中的resources目录下的application-druid.yml
TypeScript
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.100.168:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: heima123
(5)Redis配置
找到ruoyi-admin模块中的resources目录下的application.yml,如下配置:
TypeScript
# Spring配置
spring:
redis:
# 地址
host: 192.168.100.168
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: 123456
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
(6)运行项目
找到ruoyi-admin模块中的运行com.ruoyi.RuoYiApplication.java,出现如下图表示启动成功。
html
(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙
.-------. ____ __
| _ _ \ \ \ / /
| ( ' ) | \ _. / '
|(_ o _) / _( )_ .'
| (_,_).' __ ___(_ o _)'
| |\ \ | || |(_,_)'
| | \ `' /| `-' /
| | \ / \ /
''-' `'-' `-..-'
3、将后端代码上传到Gitee
项目运行起来后,要将代码托管到gitee仓库中,方便维护。
先将当前的master分支上传到gitee ,然后在master分支上创建一个develop分支;
将来,每一章的业务开发都要在develop分支上创建出一个子分支,子分支的命名规则为:dev+章数,例如本章的子分支为dev03,下一章的为dev04,依此类推。
每一章的代码在子分支测试完毕后,要合并到develop分支,下一章再从develop分支创建出一个新的分支。
4、运行前端项目
(1)前提
咱们要运行的前端项目,使用的是vue3,需要使用node 18版本以上
如果没有安装node18或者更高版本的同学,可以在资料中找到对应的安装包进行安装
(2)代码下载
目前下载的代码中,其中ruoyi-ui这个目录就是前端的代码,不过这个代码是基于vue2开发的

如果需要使用vue2为基础开发语言的前端,就可以使用上述的代码,运行方式跟下方描述相同
咱们需要使用基于vue3开发的代码,官方推荐的地址:GitHub - yangzongzhuan/RuoYi-Vue3: :tada: (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统 · GitHub
由于从github下载代码速度比较慢,已经将当前代码同步了一份到gitee中,地址如下:https://gitee.com/alexisyang/ruo-yi-vue3-master.git
也可以在本章的资料中找到代码压缩包,解压到代码目录,解压后,建议修改一下项目名(如:zzyl-vue3),再使用VSCode打开

注意注意:同学你好,为了避免若依官方代码更新后和后续课程中出现不一致的情况,这里强烈建议直接使用资料中提供的前端初始代码:RuoYi-Vue3-master.zip,这样就能确保初始代码环境和后续课程中保持一致啦
(3)安装依赖和项目运行
进入到代码的根目录,然后执行以下命令:
XML
npm install

(4)修改配置
打开前端根目录下的vite.config.js文件,把目标地址改为若依后端的服务地址,如下图:

前端默认端口是80,由于Windows10操作系统上的80端口会被系统进程占用,最好提前修改好端口,再启动前端项目:
javascript
// vite 相关配置
server: {
port: 88,
host: true,
open: true,
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: baseUrl,
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
},
// springdoc proxy
'^/v3/api-docs/(.*)': {
target: baseUrl,
changeOrigin: true,
}
}
},
(5)启动项目
如果依赖已经安装完成,配置也已修改,则可以直接启动项目
javascript
npm run dev
启动成功之后的效果:
html
D:\ZZYL\Code\zzyl-vue3>npm run dev
> ruoyi@3.8.9 dev
> vite
VITE v5.3.2 ready in 675 ms
➜ Local: http://localhost:88/
➜ Network: http://172.16.17.61:88/
➜ Network: http://192.168.138.1:88/
➜ Network: http://192.168.100.1:88/
➜ press h + enter to show help
启动前后端成功后,会自动打开浏览器访问页面,地址:http://localhost:88/

5、将前端代码上传到Gitee
项目运行起来后,要将代码托管到gitee仓库中,方便维护。
先将当前的master分支上传到gitee,然后在master分支上创建一个develop分支;
将来,每一章的业务开发都要在develop分支上创建出一个子分支,子分支的命名规则为:dev+章数,例如本章的子分支为dev03,下一章的为dev04,依此类推。
每一章的代码在子分支测试完毕后,要合并到develop分支,下一章再从develop分支创建出一个新的分支。
四、后端代码
1、项目结构
下面是idea打开项目后的截图

官方文档的介绍
java
com.ruoyi
├── ruoyi-admin // 后台服务 存放 controller
├── common // 工具类
│ └── annotation// 自定义注解
│ └── config // 全局配置
│ └── constant // 通用常量
│ └── core // 核心控制
│ └── enums // 通用枚举
│ └── exception // 通用异常
│ └── filter // 过滤器处理
│ └── utils // 通用类处理
├── framework // 框架核心
│ └── aspectj // 注解实现
│ └── config // 系统配置
│ └── datasource// 数据权限
│ └── interceptor// 拦截器
│ └── manager // 异步处理
│ └── security // 权限控制
│ └── web // 前端控制
├── ruoyi-generator // 代码生成(可移除)
├── ruoyi-quartz // 定时任务(可移除)
├── ruoyi-system // 系统代码 存放 domain,mapper,service
├── ruoyi-xxxxxx // 其他模块
模块间的依赖关系

2、项目的配置
项目中的配置文件都在ruoyi-admin模块下,如下图:

-
i18n:国际化处理
-
META-INF:存储了项目的元信息(描述数据的数据),无需修改
-
mybatis:mybatis相关的配置信息
-
application.yml:项目中的核心配置
-
application-druid.yml:数据库连接配置
-
banner.txt:默认的banner图标信息,项目启动,控制台打印显示
-
logback.xml:日志配置
最主要的两个配置文件:application.yml和application-druid.yml
- application.yml
TypeScript
# 项目相关配置
ruoyi:
# 名称
name: RuoYi
# 版本
version: 3.8.9
# 版权年份
copyrightYear: 2025
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数,默认为100
accept-count: 1000
threads:
# tomcat最大线程数,默认为200
max: 800
# Tomcat启动初始化的线程数,默认值10
min-spare: 100
# 日志配置
logging:
level:
com.zzyl: debug
org.springframework: warn
# 用户配置
user:
password:
# 密码最大错误次数
maxRetryCount: 5
# 密码锁定时间(默认10分钟)
lockTime: 10
# Spring配置
spring:
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# redis 配置
redis:
# 地址
host: 192.168.100.168
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password: 123456
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期(默认30分钟)
expireTime: 30
# MyBatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.zzyl.**.domain
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
# 请求前缀
pathMapping: /dev-api
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
- application-druid.yml
TypeScript
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://192.168.100.168:3306/zzyl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: heima123
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
3、项目的表结构
刚才咱们已经导入了关于若依的表结构,若依中默认提供了19张表,咱们可以先简单熟悉一下每个表代表的含义:

表结构说明及关系
| 表名 | 说明 | 关系 |
|---|---|---|
| gen_table | 代码生成业务表 | 代码生成 |
| gen_table_column | 代码生成业务表字段 | 代码生成 |
| sys_config | 参数配置表 | 数据字典 |
| sys_dict_data | 字典数据表 | 数据字典 |
| sys_dict_type | 字典类型表 | 数据字典 |
| sys_job | 定时任务调度表 | 定时任务 |
| sys_job_log | 定时任务调度日志表 | 定时任务 |
| sys_logininfor | 系统访问记录 | 日志 |
| sys_oper_log | 操作日志记录 | 日志 |
| sys_notice | 通知公告表 | |
| sys_menu | 菜单表 | 权限 |
| sys_dept | 部门表 | 权限 |
| sys_post | 岗位信息表 | 权限 |
| sys_role | 角色信息表 | 权限 |
| sys_role_dept | 角色和部门关联表 | 权限 |
| sys_role_menu | 角色和菜单关联表 | 权限 |
| sys_user | 用户信息表 | 权限 |
| sys_user_post | 用户与岗位关联表 | 权限 |
| sys_user_role | 用户和角色关联表 | 权限 |
五、前端代码
1、项目结构
如下图:

详细目录或文件说明:
javascript
├── bin // 执行脚本
├── public // 公共文件
│ ├── favicon.ico // favicon图标
├── src // 源代码
│ ├── api // 所有请求,后台的api接口,开发时经常操作的目录
│ ├── assets // 主题 字体等静态资源
│ ├── components // 全局公用组件
│ ├── directive // 全局指令
│ ├── layout // 布局
│ ├── plugins // 通用方法
│ ├── router // 路由
│ ├── store // 全局 store管理
│ ├── utils // 全局公用方法
│ ├── views // view,存储vue组件,开发时经常操作的目录
│ ├── App.vue // 根组件
│ ├── main.js // 入口 加载组件 初始化等
│ ├── permission.js // 权限管理
│ └── settings.js // 系统配置
├── vite // 前端构建工具
├── .env.development // 开发环境配置
├── .env.production // 生产环境配置
├── .env.staging // 测试环境配置
├── .gitignore // git 忽略项
├── LICENSE // 许可证
├── package-lock.json // 锁定项目依赖的具体版本号
├── package.json // 配置项目的信息、名称、版本号、描述信息等
├── pnpm-lock.yaml // 锁定项目依赖的具体版本号
└── vite.config.js // 用于配置 Vue.js 项目的全局选项,可修改后台访问接口的路径
2、核心配置
在开发阶段,配置的修改是较少的,主要关于一个配置文件即可--->vite.config.js
java
import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import createVitePlugins from './vite/plugins'
const baseUrl = 'http://localhost:8080' // 后端接口
// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
const { VITE_APP_ENV } = env
return {
// 部署生产环境和开发环境下的URL。
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
base: VITE_APP_ENV === 'production' ? '/' : '/',
plugins: createVitePlugins(env, command === 'build'),
resolve: {
// https://cn.vitejs.dev/config/#resolve-alias
alias: {
// 设置路径
'~': path.resolve(__dirname, './'),
// 设置别名
'@': path.resolve(__dirname, './src')
},
// https://cn.vitejs.dev/config/#resolve-extensions
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
// 打包配置
build: {
// https://vite.dev/config/build-options.html
sourcemap: command === 'build' ? false : 'inline',
outDir: 'dist',
assetsDir: 'assets',
chunkSizeWarningLimit: 2000,
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
}
}
},
// vite 相关配置
server: {
port: 88,
host: true,
open: true,
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: baseUrl,
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
},
// springdoc proxy
'^/v3/api-docs/(.*)': {
target: baseUrl,
changeOrigin: true,
}
}
},
css: {
postcss: {
plugins: [
{
postcssPlugin: 'internal:charset-removal',
AtRule: {
charset: (atRule) => {
if (atRule.name === 'charset') {
atRule.remove()
}
}
}
}
]
}
}
}
})
-
别名
-
~代表./ -
@代表src目录
-
-
前端服务端口--->
port: 80,咱们已经修改为88了 -
后端服务地址--->
target: baseUrlconst baseUrl = '``http://localhost:8080``' // 后端接口
-
路径重写--->
rewrite: (p) => p.replace(/^\/dev-api/, '')
六、功能快速开发
熟悉了前后端项目的结构之后,接下来,咱们正式开始项目功能的开发
若依提供的代码生成功能 ,可以基于表结构快速生成前后端的代码,下面,咱们快速感受一下代码生成功能的强大吧
1、准备工作
咱们首先开发的是护理项目模块,咱们需要准备两部分内容,一个是一级菜单,第二个是表结构
(1)菜单
咱们要开发的模块是护理项目模块,而护理项目是子菜单,咱们需要先在若依项目中创建一个服务管理的一级菜单,方便对服务管理下的功能进行分类
最终的效果:

准备主菜单-->**服务管理,**详细配置,如下:

点击确定后,刷新页面,可以看到多了一个服务管理的一级菜单
(2)表结构
护理项目表结构定义如下:
sql
CREATE TABLE `nursing_project` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称',
`order_no` int DEFAULT NULL COMMENT '排序号',
`unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '单位',
`price` decimal(10,2) DEFAULT NULL COMMENT '价格',
`image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片',
`nursing_requirement` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '护理要求',
`status` int NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
`create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人',
`update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=84 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理项目表';
执行以上sql,生成对应的数据库表

2、代码生成
(1)生成
找到系统工具 -->代码生成 ,然后点击导入按钮

选中nursing_project表结构,点击确定

在代码生成列表中,可以看到新增了一条数据

该数据对应了5个按钮
预览生成后的代码
修改代码生成的配置(常用)
删除这条数据
同步表结构(导入之后改动表的情况)
下载离线代码包
(2)配置
在生成之前,咱们需要对代码生成做一些配置,咱们可以点击修改按钮,可以看到有三部分的配置
-
基本信息
-
字段信息
-
生成信息
下图是**基本信息,**可以根据自己的需求修改:表、实体、表描述、作者相关的数据

下图是字段信息,详细描述如下图:
| 字段信息 | 描述 |
|---|---|
| 字段列名 | 表中的字段列名称 |
| 字段描述 | 字段的描述,自动读取建表语句中的comment信息,可根据实际情况更改 |
| 物理类型 | 数据库所对应的字段类型 |
| Java类型 | Java实体类中属性的类型,可改,例如,状态字段:Long类型可以修改为Integer |
| Java属性 | Java实体类中所对应的属性名称 |
| 插入 | 新增的时候,需要插入的字段 |
| 编辑 | 修改的时候,需要插入的字段 |
| 列表 | 列表查询需要展示的字段 |
| 查询 | 列表查询,需要的条件字段 |
| 查询方式 | 与上面查询条件配合,选择对应的查询方式 |
| 必填 | 在插入和新增的时候,这个字段是否是必填项,可生成校验 |
| 显示类型 | 前端代码使用的组件类型,可根据实际情况选择 |
| 字典类型 | 字典管理是用来维护可枚举的数据的,如下拉框、单选按钮等,支持自定义 |

下图是**生成信息,**可以按照自己的实际情况,来修改包路径,模块名称,上级菜单

(3)提交
修改完成后,点击提交按钮
等咱们修改完毕后,回到了列表页,这个时候就可以点击下载按钮,去下载代码包

下载后的代码包,解压后,包含了三部分,如下图:

main 后端的代码
vue 前端的代码
projectMenu.sql 菜单关系的sql数据
执行projectMenu.sql文件中的内容,内容为菜单的数据
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目', '2000', '1', 'project', 'nursing/project/index', 1, 0, 'C', '0', '0', 'nursing:project:list', '#', 'admin', sysdate(), '', null, '护理项目菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', 'nursing:project:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', 'nursing:project:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', 'nursing:project:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', 'nursing:project:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('护理项目导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', 'nursing:project:export', '#', 'admin', sysdate(), '', null, '');
把main目录拷贝后,找到后端ruoyi-admin模块,在main目录上点右键,选择Paste进行拷贝,效果如下:

打开vue文件夹,里面包含了两部分内容

api是指后端的接口定义代码
views中包含了vue组件的前端代码
选中这两个文件夹 ,打开前端项目,选中src目录进行拷贝,效果如下:


等代码拷贝完成后,重新启动前后端项目,打开页面,可以在服务管理 中看到子菜单护理项目,如下图

可以对护理项目进行一些操作,比如,新增、修改、删除、查询等
七、代码阅读
刚才自动生成的代码,不需要做任何修改,就可以做到基本的增删改查了,当然若依生成的代码也不是很完美,在后续的课程中,咱们还会进行修改调整。
在修改优化之前,咱们先来读一下自动生成的代码长什么样子,共分为两部分:后端和前端
1、后端代码
下面这个是控制层的代码NursingProjectController ,详细如下:
咱们可以使用AI协助来阅读以上代码,咱们可以让AI为每一行代码添加上注释,方便咱们阅读
(1)Prompt
咱们可以把整个类的代码给AI,然后在最后添加一句话: 帮我给方法上的注解和方法内的代码添加单行注释,注释要写在代码上方
AI解释后就可以很方便的阅读代码,详细如下:
java
package com.zzyl.nursing.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zzyl.common.annotation.Log;
import com.zzyl.common.core.controller.BaseController;
import com.zzyl.common.core.domain.AjaxResult;
import com.zzyl.common.enums.BusinessType;
import com.zzyl.nursing.domain.NursingProject;
import com.zzyl.nursing.service.INursingProjectService;
import com.zzyl.common.utils.poi.ExcelUtil;
import com.zzyl.common.core.page.TableDataInfo;
/**
* 护理项目Controller
*
* @author ruoyi
* @date 2025-05-16
*/
@RestController
@RequestMapping("/nursing/project")
public class NursingProjectController extends BaseController
{
@Autowired
private INursingProjectService nursingProjectService;
/**
* 查询护理项目列表
*/
// 权限校验:需具备护理项目管理列表权限
@PreAuthorize("@ss.hasPermi('nursing:project:list')")
// 映射GET请求到/list路径
@GetMapping("/list")
public TableDataInfo list(NursingProject nursingProject)
{
// 开启分页功能
startPage();
// 调用服务层查询护理项目列表
List<NursingProject> list = nursingProjectService.selectNursingProjectList(nursingProject);
// 返回分页数据表格
return getDataTable(list);
}
/**
* 导出护理项目列表
*/
// 权限校验:需具备护理项目管理导出权限
@PreAuthorize("@ss.hasPermi('nursing:project:export')")
// 记录操作日志:业务类型为导出
@Log(title = "护理项目", businessType = BusinessType.EXPORT)
// 映射POST请求到/export路径
@PostMapping("/export")
public void export(HttpServletResponse response, NursingProject nursingProject)
{
// 查询需要导出的护理项目数据
List<NursingProject> list = nursingProjectService.selectNursingProjectList(nursingProject);
// 创建Excel工具类实例
ExcelUtil<NursingProject> util = new ExcelUtil<NursingProject>(NursingProject.class);
// 执行Excel导出操作
util.exportExcel(response, list, "护理项目数据");
}
/**
* 获取护理项目详细信息
*/
// 权限校验:需具备护理项目管理查询权限
@PreAuthorize("@ss.hasPermi('nursing:project:query')")
// 映射GET请求到/{id}路径
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
// 调用服务层根据ID查询护理项目详情
return success(nursingProjectService.selectNursingProjectById(id));
}
/**
* 新增护理项目
*/
// 权限校验:需具备护理项目管理新增权限
@PreAuthorize("@ss.hasPermi('nursing:project:add')")
// 记录操作日志:业务类型为新增
@Log(title = "护理项目", businessType = BusinessType.INSERT)
// 映射POST请求到根路径
@PostMapping
public AjaxResult add(@RequestBody NursingProject nursingProject)
{
// 调用服务层插入护理项目数据
return toAjax(nursingProjectService.insertNursingProject(nursingProject));
}
/**
* 修改护理项目
*/
@PreAuthorize("@ss.hasPermi('nursing:project:edit')")
@Log(title = "护理项目", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody NursingProject nursingProject)
{
return toAjax(nursingProjectService.updateNursingProject(nursingProject));
}
/**
* 删除护理项目
*/
// 权限校验:需具备护理项目管理删除权限
@PreAuthorize("@ss.hasPermi('nursing:project:remove')")
// 记录操作日志:业务类型为删除
@Log(title = "护理项目", businessType = BusinessType.DELETE)
// 映射DELETE请求到/{ids}路径
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
// 调用服务层批量删除护理项目
return toAjax(nursingProjectService.deleteNursingProjectByIds(ids));
}
}
(2)说明
1、继承了BaseController,其中BaseController详细定义如下图:

2、符合RestFul请求风格
3、返回值有两个:TableDataInfo 和 AjaxResult
- TableDataInfo 返回分页相关数据
java
{
"total": 2,
"rows": [
{
"createBy": "admin",
"createTime": "2025-03-25 21:29:45",
"updateBy": "",
"updateTime": null,
"remark": "管理员",
"noticeId": "2",
"noticeTitle": "维护通知:2018-07-01 若依系统凌晨维护",
"noticeType": "1",
"noticeContent": "维护内容",
"status": "0"
}
],
"code": 200,
"msg": "查询成功"
}
- AjaxResult 继承了HashMap,有标准的接口响应结构
java
{"msg":"操作成功","code":200}
{
"msg": "操作成功",
"code": 200,
"data": {
"createBy": "admin",
"createTime": "2025-03-25 21:29:45",
"remark": "管理员",
"noticeId": "1",
"noticeTitle": "温馨提醒:2018-07-01 若依新版本发布啦",
"noticeType": "2",
"noticeContent": "新版本内容",
"status": "0"
}
}
4、陌生注解
-
@PreAuthorize在方法上使用,主要作用是判断当前登录人是否有权限访问该方法 ps:后面会细讲 -
@Log在方法上使用,作用是把操作这个方法的行为做一个日志记录
5、后端其他代码
- 比如service、mapper,这些代码都是基础的CRUD,操作数据使用的mybatis
6、分页逻辑
-
详细分页逻辑如下图:

当调用了startPage()方法后主要干了两件事:
-
从请求参数中获取到pageNum和pageSize两个参数,如果有其他参数也会获取,比如是orderBy参数
-
调用了PageHelper.startPage()方法,来进行分页处理
2、前端代码
(1)菜单路由规则,映射关系
知识回顾:
路由:是路径与组件的对应关系 ,可以实现不同页面间导航和视图的切换
咱们来看一下目前护理项目这个菜单的配置项,如下图

-
这个菜单的类型为菜单, 菜单需要有对应的组件路径
-
父菜单的路由地址+当前菜单的路由地址 就可以访问组件路径对应的组件
- 即: nursing/project 加载组件为 @/views/nursing/project/index.vue
(2)测试案例
在服务管理中新增一个菜单(护理安排),配置如下:
-
路由地址:arrange
-
组件路径:nursing/arrange/index

在@/views/nursing/arrange目录中新增一个index.vue组件

测试是否能正常访问这个组件

(3)代码阅读
刚才生成代码中包含了两部分内容,第一个是api,第二个是组件
咱们先来看@/api/nursing/project.js
javascript
import request from '@/utils/request'
// 查询护理项目列表
export function listProject(query) {
return request({
url: '/nursing/project/list',
method: 'get',
params: query
})
}
// 查询护理项目详细
export function getProject(id) {
return request({
url: '/nursing/project/' + id,
method: 'get'
})
}
// 新增护理项目
export function addProject(data) {
return request({
url: '/nursing/project',
method: 'post',
data: data
})
}
// 修改护理项目
export function updateProject(data) {
return request({
url: '/nursing/project',
method: 'put',
data: data
})
}
// 删除护理项目
export function delProject(id) {
return request({
url: '/nursing/project/' + id,
method: 'delete'
})
}
-
这里面的5个接口定义,与后台提供的接口是一一对应的
-
其中
@/utils/request这个js封装了拦截器和工具函数,实现了对HTTP请求和响应的统一处理和管理
咱们接下来再来看一下组件的代码,地址:src\views\nursing\project\index.vue
为了更方便阅读这个代码,咱们依然可以使用通义灵码或者是AI大模型添加注释或者解释代码
Prompt
把这个组件的代码给大模型,然后跟上一句话
你是一个资深的前端开发工程师,帮我给这个文件中的核心代码加上注释
解释后的代码如下:
javascript
<script setup name="Project">
import { listProject, getProject, delProject, addProject, updateProject } from "@/api/nursing/project"
// 获取当前组件实例
const { proxy } = getCurrentInstance()
// 数据列表
const projectList = ref([])
// 对话框开关
const open = ref(false)
// 加载状态
const loading = ref(true)
// 搜索区域显示状态
const showSearch = ref(true)
// 选中ID数组
const ids = ref([])
// 单条选择状态
const single = ref(true)
// 多条选择状态
const multiple = ref(true)
// 总记录数
const total = ref(0)
// 弹窗标题
const title = ref("")
// 响应式数据对象
const data = reactive({
form: {}, // 表单数据
queryParams: { // 查询参数
pageNum: 1,
pageSize: 10,
name: null,
status: null,
},
rules: {} // 表单验证规则
})
const { queryParams, form, rules } = toRefs(data)
/** 查询护理项目列表 */
function getList() {
loading.value = true
listProject(queryParams.value).then(response => {
projectList.value = response.rows
total.value = response.total
loading.value = false
})
}
// 取消按钮操作
function cancel() {
open.value = false
reset()
}
// 表单重置
function reset() {
form.value = {
id: null,
name: null,
orderNo: null,
unit: null,
price: null,
image: null,
nursingRequirement: null,
status: null,
createBy: null,
updateBy: null,
remark: null,
createTime: null,
updateTime: null
}
proxy.resetForm("projectRef")
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
}
// 多选框选中数据处理
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加护理项目"
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _id = row.id || ids.value
getProject(_id).then(response => {
form.value = response.data
open.value = true
title.value = "修改护理项目"
})
}
/** 提交按钮操作 */
function submitForm() {
proxy.$refs["projectRef"].validate(valid => {
if (valid) {
if (form.value.id != null) {
updateProject(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
} else {
addProject(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value
proxy.$modal.confirm('是否确认删除护理项目编号为"' + _ids + '"的数据项?').then(function() {
return delProject(_ids)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('nursing/project/export', {
...queryParams.value
}, `project_${new Date().getTime()}.xlsx`)
}
// 页面加载时获取数据
getList()
</script>
- 前端主要使用Vue3+Element plus组件进行开发
八、将业务代码迁移到新模块
在前面的功能快速开发章节中,咱们是将若依生成的功能代码直接放到了zzyl-admin模块中 ,将来,咱们的业务功能代码会越来越多,如果都放到zzyl-admin模块中,会让zzyl-admin模块显得比较乱。所以,咱们最好创建一个新模块 ,然后将功能模块的代码统一都放到新模块中。以下是具体的操作思路:
参考链接(在若依项目中创建新模块):
要求:
- 创建zzyl-nursing-platform模块,效果如下:

- 在父模块中管理zzyl-nursing-platform模块的版本:
XML
<!-- 业务模块-->
<dependency>
<groupId>com.zzyl</groupId>
<artifactId>zzyl-nursing-platform</artifactId>
<version>${zzyl.version}</version>
</dependency>
- 在zzyl-nursing-platform模块中引入zzyl-common模块
XML
<dependencies>
<dependency>
<groupId>com.zzyl</groupId>
<artifactId>zzyl-common</artifactId>
</dependency>
</dependencies>
- 在zzyl-admin模块中引入新创建的zzyl-nursing-platform模块
XML
<!-- 护理业务模块-->
<dependency>
<groupId>com.zzyl</groupId>
<artifactId>zzyl-nursing-platform</artifactId>
</dependency>
-
把护理项目相关的代码,都移动到新模块中 zzyl-nursing-platform
-
统一修改包名为
com.zzyl.nursing

-
修改完成后,重启后端程序,完成测试。
九、微实战
1、需求说明
服务管理->护理计划包含:护理项目、护理计划、护理等级共3个子模块。
-
护理项目 作为护理模块的基础数据,主要是由护理员给老人提供的护理服务,常见的有:洗头、助餐、复健运动等,护理项目分为护理计划内项目 与护理计划外项目,两者之间的区别是:前者是根据护理计划产生的,后者是由家属从微信小程序端下单支付产生的
-
护理计划 作为护理模块的基础数据,主要是与护理等级和护理项目进行绑定 ,后台管理人员在创建计划时,可选择该计划要执行哪些任护理项目;后台管理人员可以对护理计划进行增删改等操作
-
护理等级作为护理模块的基础数据,主要是与护理计划进行一对一的绑定,老人入住养老院时需要选择适合老人身体健康状况的护理等级,不同的护理等级对应的护理计划不同,不同护理计划绑定的护理项目不同,因此,价格也有区别
-
三者关系

2、表结构
sql
use zzyl;
-- 护理项目与护理计划关系表
CREATE TABLE nursing_project_plan (
id bigint NOT NULL AUTO_INCREMENT,
plan_id bigint NOT NULL COMMENT '计划id',
project_id bigint NOT NULL COMMENT '项目id',
execute_time varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '计划执行时间',
execute_cycle int NOT NULL COMMENT '执行周期 0 天 1 周 2月',
execute_frequency int NOT NULL COMMENT '执行频次',
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间(新增自动更新配置)',
create_by bigint DEFAULT NULL COMMENT '创建人id',
update_by bigint DEFAULT NULL COMMENT '更新人id',
remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (id) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1727 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理计划和项目关联表';
-- 护理计划表
CREATE TABLE nursing_plan (
id bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
sort_no int DEFAULT NULL COMMENT '排序号',
plan_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '名称',
status tinyint NOT NULL DEFAULT '0' COMMENT '状态 0禁用 1启用',
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
create_by bigint DEFAULT NULL COMMENT '创建人id',
update_by bigint DEFAULT NULL COMMENT '更新人id',
remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
PRIMARY KEY (id) USING BTREE,
UNIQUE KEY plan_name (plan_name) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=129 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理计划表';
-- 护理等级表
CREATE TABLE nursing_level (
id bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
name varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '等级名称',
plan_id bigint NOT NULL COMMENT '护理计划ID',
fee decimal(10,2) NOT NULL COMMENT '护理费用',
status tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
description varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '等级说明',
remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
create_by bigint DEFAULT NULL COMMENT '创建人id',
update_by bigint DEFAULT NULL COMMENT '更新人id',
PRIMARY KEY (id) USING BTREE,
UNIQUE KEY name (name) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='护理等级表';
3、实现要求
-
把所有业务代码的都存储在
zzyl-nursing-platform模块下 -
请使用若依的代码快速生成的功能 ,完成护理计划和护理等级的功能开发,最终效果图

