徐州網(wǎng)站app開發(fā)我贏網(wǎng)客服系統(tǒng)
若依環(huán)境
介紹
?若依是一款快速開發(fā)平臺(tái)(低代碼),用于快速構(gòu)建企業(yè)級(jí)后臺(tái)管理系統(tǒng),它提供了許多常用的功能模塊和組件,包括權(quán)限管理、代碼生成、工作流、消息中心等
官方地址: https://www.ruoyi.vip/
- ?基于Spring Boot和Spring Cloud?:采用現(xiàn)代化的微服務(wù)架構(gòu),利用Spring Boot和Spring Cloud提供的便捷開發(fā)和部署特性
- ?模塊化設(shè)計(jì)?:功能模塊之間解耦,易于擴(kuò)展和定制
- ?多租戶支持?:支持多租戶管理,可以為不同的租戶提供獨(dú)立的數(shù)據(jù)和功能
- ?代碼生成器?:提供代碼生成器,可以快速生成CRUD代碼,減少重復(fù)工作
- ?完善的權(quán)限管理?:提供靈活的權(quán)限管理功能,支持角色權(quán)限劃分、數(shù)據(jù)權(quán)限控制等
- ?友好的界面?:提供現(xiàn)代化的界面設(shè)計(jì),用戶友好,易于操作。
通過若依,開發(fā)人員可以快速搭建穩(wěn)健、高效的企業(yè)級(jí)應(yīng)用,提高開發(fā)效率和產(chǎn)品質(zhì)量
若依版本
若依官方針對(duì)不同開發(fā)需求提供了多個(gè)版本的框架,每個(gè)版本都有其獨(dú)特的特點(diǎn)和適用場(chǎng)景
- RuoYi(SpringBoot+Bootstrap):前后端混合開發(fā)版本,適用于小型項(xiàng)目
- RuoYi-Vue(SpringBoot+Vue):前后端分離版本,適用于中型項(xiàng)目
- RuoYi-Cloud(SpringCloud+Vue):微服務(wù)版本,適用于大型項(xiàng)目
- RuoYi-App(SpringCloud+Uniapp):移動(dòng)端版本
若依框架因其強(qiáng)大的功能和靈活性,吸引了眾多第三方開發(fā)者基于其核心架構(gòu)進(jìn)行擴(kuò)展和優(yōu)化,從而形成了豐富的生態(tài)系統(tǒng)
- RuoYi-Vue3(前端升級(jí)Vue3 Element Plus Vite) https://github.com/yangzongzhuan/RuoYi-Vue3
- RuoYi-Vue-Plus(后端集成Mybatis-Plus、Hutool、OSS存儲(chǔ)、分布式鎖等組件) https://gitee.com/dromara/RuoYi-Vue-Plus
RuoYi-Vue
RuoYi-Vue版本,采用了前后端分離的單體架構(gòu)設(shè)計(jì):
軟件環(huán)境:JDK(11)、MySQL(8) 、Redis (5)、Maven(3.6)、NodeJS(16)
技術(shù)選型:Spring Boot、Spring Security、MyBatis、Jwt、Vue3、Element-Plus
官方地址:https://gitee.com/y_project/RuoYi-Vue
擴(kuò)展地址:https://gitee.com/ys-gitee/RuoYi-Vue3
后端代碼
初始化項(xiàng)目
通過idea克隆若依源碼,倉(cāng)庫(kù)地址:https://gitee.com/y_project/RuoYi-Vue.git
使用idea打開項(xiàng)目后,等待環(huán)境檢查(主要是Maven下載項(xiàng)目依賴)
準(zhǔn)備MySQL
1、創(chuàng)建數(shù)據(jù)庫(kù)ry-vue
2、執(zhí)行下圖的sql腳本文件,完成導(dǎo)入
3、導(dǎo)入后ry-vue
庫(kù)內(nèi)置30張表
在ruoyi-admin
模塊下,編輯resources
目錄下的application-druid.yml
,修改數(shù)據(jù)庫(kù)連接
# 數(shù)據(jù)源配置
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主庫(kù)數(shù)據(jù)源master:url: 數(shù)據(jù)庫(kù)地址username: 數(shù)據(jù)庫(kù)賬號(hào)password: 數(shù)據(jù)庫(kù)密碼
準(zhǔn)備Redis
在redis解壓目錄下,執(zhí)行redis-server.exe redis.windows.conf
啟動(dòng)
在ruoyi-admin
模塊下,resources
目錄下的application.yml
,可以設(shè)置redis密碼等相關(guān)信息
項(xiàng)目運(yùn)行
在ruoyi-admin
模塊下,運(yùn)行com.ruoyi.RuoYiApplication.java
,出現(xiàn)如下圖表示啟動(dòng)成功
后端運(yùn)行成功可以通過([http://localhost:8080 )訪問,但是不會(huì)出現(xiàn)靜態(tài)頁(yè)面,可以繼續(xù)參考下面步驟部署前端,然后通過前端地址來訪問。
前端代碼
初始化項(xiàng)目
進(jìn)入開發(fā)目錄下,使用vscode命令code
打開項(xiàng)目
# 克隆vue3項(xiàng)目
git clone https://gitee.com/ys-gitee/RuoYi-Vue3.git# 通過vscode打開項(xiàng)目
code ./RuoYi-Vue3
項(xiàng)目運(yùn)行
在vscode終端中輸入以下命令:
# 安裝環(huán)境
npm install# 啟動(dòng)服務(wù)
npm run dev
打開瀏覽器,輸入:([http://localhost:80) 默認(rèn)賬戶/密碼 admin/admin123
)若能正確展示登錄頁(yè)面,并能成功登錄,菜單及頁(yè)面展示正常,則表明環(huán)境搭建成功
若依入門
在若依項(xiàng)目成功搭建之后,深入了解其代碼生成器功能是掌握框架的重要一環(huán)。
接下來,我們將利用若依框架的代碼生成器實(shí)現(xiàn)CRM系統(tǒng)中的課程管理功能,這將使我們能夠?qū)嶋H體驗(yàn)并掌握如何在項(xiàng)目中有效使用這一工具。
功能需求
實(shí)現(xiàn)CRM系統(tǒng)中的課程管理功能,涵蓋增加、刪除、修改和查詢課程信息的完整前后端代碼。
原型地址:https://app.mockplus.cn/run/prototype/_lwaPYSV9Ue6/byFT7QUzmCqJ/2AadzZnerRIDo?cps=collapse&isShare=true
代碼生成
提供課程表
DROP TABLE IF EXISTS `tb_course`;
CREATE TABLE `tb_course` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '課程id',`code` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '課程編碼',`subject` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '課程學(xué)科',`name` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '課程名稱',`price` int DEFAULT NULL COMMENT '價(jià)格(元)',`applicable_person` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '適用人群',`info` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL COMMENT '課程介紹',`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',`update_time` timestamp NULL DEFAULT NULL COMMENT '更新時(shí)間',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin COMMENT='課程管理';INSERT INTO `tb_course` VALUES (1,'cp123456','javaEE','JavaSE基礎(chǔ)',199,'小白學(xué)員','JavaSE基礎(chǔ)','2024-04-20 09:57:35','2024-04-20 09:57:35'), (2,'cp123457','javaEE','JavaWeb',188,'初級(jí)開發(fā)者','JavaWeb','2024-04-20 09:57:35','2024-04-20 09:57:35'),(3,'cp123458','Python+大數(shù)據(jù)','Python入門',555,'小白學(xué)員','Python入門','2024-04-20 09:57:35','2024-04-20 09:57:35'),(4,'cp123459','Python+大數(shù)據(jù)','PythonWeb',88,'初級(jí)開發(fā)者','PythonWeb','2024-04-20 09:57:35','2024-04-20 09:57:35'),(5,'cp123460','鴻蒙應(yīng)用開發(fā)','鴻蒙入門',99,'小白學(xué)員','鴻蒙入門','2024-04-20 09:57:35','2024-04-20 09:57:35'),(6,'cp123461','鴻蒙應(yīng)用開發(fā)','鴻蒙商城實(shí)戰(zhàn)',59,'初級(jí)開發(fā)者','鴻蒙商城實(shí)戰(zhàn)','2024-04-20 09:57:35','2024-04-20 09:57:35');
系統(tǒng)導(dǎo)入
登錄系統(tǒng)(系統(tǒng)工具 -> 代碼生成 -> 導(dǎo)入課程表)
配置代碼
代碼生成列表中找到課程表(可預(yù)覽、編輯、同步、刪除生成配置)

點(diǎn)擊生成
點(diǎn)擊生成代碼,得到一個(gè)ruoyi.zip

解壓后得到:后端代碼、前端代碼、菜單sql

代碼導(dǎo)入
導(dǎo)入課程菜單
執(zhí)行sql腳本,導(dǎo)入菜單數(shù)據(jù)
導(dǎo)入后端代碼
將生成的后端代碼和mapper文件,導(dǎo)入ruoyi-admin
模塊中
注意:如果導(dǎo)入后的代碼重啟后沒生效,可以通過maven先clean再啟動(dòng)
導(dǎo)入前端代碼
將生成的前端代碼,導(dǎo)入ruoyi-ui
模塊中
訪問測(cè)試
代碼生成器默認(rèn)生成的課程管理模塊在系統(tǒng)工具菜單下,打開測(cè)試CRUD功能
代碼位置
新建一個(gè)模塊 ruoyi-crm
將代碼復(fù)制到crm模塊中
在父工程的pom.xml中鎖定crm模塊的版本
在admin模塊中引入crm模塊
功能詳解
我們將對(duì)若依的通用功能進(jìn)行詳解。本章內(nèi)容分為三個(gè)重點(diǎn)部分:
系統(tǒng)管理
權(quán)限系統(tǒng)
若依提供了企業(yè)級(jí)通用權(quán)限系統(tǒng),可以給不同的人設(shè)置不同的權(quán)限,然后每個(gè)人登錄系統(tǒng)后可以看到不同的頁(yè)面按鈕
如果要實(shí)現(xiàn)這樣的權(quán)限控制,需要依靠一個(gè)RBAC(基于角色的訪問控制)模型,通過角色來分配和管理用戶的菜單權(quán)限
此權(quán)限模型下設(shè)計(jì)的核心數(shù)據(jù)表有五張,分別是用戶表–中間表–角色表–中間表–權(quán)限表
select sm.* from sys_user suleft join sys_user_role sur on su.user_id = sur.user_idleft join sys_role sr on sur.role_id = sr.role_idleft join sys_role_menu srm on sr.role_id = srm.role_idleft join sys_menu sm on srm.menu_id = sm.menu_id
where su.user_id = 2
接下來,我們可以嘗試自己來創(chuàng)建一個(gè)角色,然后來關(guān)聯(lián)人員和權(quán)限
基礎(chǔ)數(shù)據(jù)
活動(dòng)管理
課程管理
角色
用戶
數(shù)據(jù)字典
若依內(nèi)置的數(shù)據(jù)字典,用于維護(hù)系統(tǒng)中常見的靜態(tài)數(shù)據(jù)。例如:性別、狀態(tài)…
功能包括:字典類型管理、字典數(shù)據(jù)管理
設(shè)計(jì)到表有兩張
接下來我們將課程管理的學(xué)科字段改為數(shù)據(jù)字典維護(hù)
實(shí)現(xiàn)步驟:
①添加字典類型和數(shù)據(jù)
②修改代碼生成信息
③下載代碼,導(dǎo)入前端
參數(shù)設(shè)置
參數(shù)設(shè)置:對(duì)系統(tǒng)中的參數(shù)進(jìn)行動(dòng)態(tài)維護(hù)。
關(guān)閉登錄驗(yàn)證碼
通知公告
RuoYi的通知公告功能提供了一個(gè)方便的方式來發(fā)布和管理通知、公告和新聞等信息。管理員可以創(chuàng)建、編輯和刪除通知(支持富文本編輯和附件上傳)。
系統(tǒng)將信息發(fā)送給指定的用戶、部門或角色。用戶可以通過系統(tǒng)界面或電子郵件接收通知,從而確保信息及時(shí)傳達(dá)(這部分需要自己開發(fā))。
通知公告功能有助于組織內(nèi)部溝通和信息傳遞,提高了工作效率和信息共享。
日志管理
登錄日志
- 記錄用戶的登錄信息,包括登錄時(shí)間和地點(diǎn)(IP地址)。
- 幫助管理員監(jiān)控登錄行為,及時(shí)發(fā)現(xiàn)任何可疑的登錄嘗試。
- 同樣提供搜索和篩選功能,方便查找特定用戶的登錄歷史。

操作日志
- 記錄用戶在系統(tǒng)中的所有操作,如查看、修改數(shù)據(jù)等。
- 幫助管理員檢查誰(shuí)做了什么,以及何時(shí)做的,確保數(shù)據(jù)準(zhǔn)確無(wú)誤。
- 可以快速搜索和找到特定的操作記錄,便于管理和審查。

系統(tǒng)監(jiān)控
監(jiān)控相關(guān)
若依提供了一些列強(qiáng)大的監(jiān)控工具,能夠幫助開發(fā)者和運(yùn)維快速了解應(yīng)用程序的性能狀態(tài)。
- 在線用戶:
- 管理員可以看到當(dāng)前誰(shuí)在系統(tǒng)里,他們什么時(shí)候登錄的,從哪里登錄的,屬于哪個(gè)部門。
- 如果有人沒權(quán)限還賴著不走,管理員可以一鍵讓他們下線,保證系統(tǒng)的安全。
- 數(shù)據(jù)監(jiān)控:
- 管理員可以實(shí)時(shí)看到系統(tǒng)的各項(xiàng)指標(biāo),比如資源使用情況,數(shù)據(jù)庫(kù)狀態(tài)等。
- 通過圖表可以直觀地看出系統(tǒng)是否健康,如果出現(xiàn)問題,系統(tǒng)會(huì)發(fā)出警報(bào)。
- 服務(wù)監(jiān)控:
- 管理員可以監(jiān)控系統(tǒng)中各個(gè)服務(wù)是否正常運(yùn)行,以及它們的性能指標(biāo)。
- 如果服務(wù)出現(xiàn)問題,系統(tǒng)會(huì)立即通知管理員,并通過儀表板展示,方便管理員快速了解情況。
- 緩存監(jiān)控:
- 管理員可以監(jiān)控系統(tǒng)的緩存使用情況,比如緩存是否經(jīng)常被用到,緩存的大小等。
- 系統(tǒng)還可以自動(dòng)清理緩存,保持?jǐn)?shù)據(jù)的新鮮度,如果緩存有問題,也會(huì)發(fā)出警報(bào)。
定時(shí)任務(wù)
若依為定時(shí)任務(wù)功能提供方便友好的web界面,實(shí)現(xiàn)動(dòng)態(tài)管理任務(wù)。
每間隔5秒,控制臺(tái)輸出系統(tǒng)時(shí)間。
①創(chuàng)建任務(wù)類
②添加任務(wù)規(guī)則
- 任務(wù)名稱:自定義,如:定時(shí)查詢?nèi)蝿?wù)狀態(tài)
- 任務(wù)分組:根據(jù)字典
sys_job_group
配置,可自行進(jìn)行配置 - 調(diào)用目標(biāo)字符串:設(shè)置后臺(tái)任務(wù)方法名稱參數(shù)
- 執(zhí)行表達(dá)式:可查詢官方
cron
表達(dá)式介紹 - 執(zhí)行策略:定時(shí)任務(wù)自定義執(zhí)行策略
- 并發(fā)執(zhí)行:是否需要多個(gè)任務(wù)間同時(shí)執(zhí)行
③啟動(dòng)任務(wù)
系統(tǒng)工具
表單構(gòu)建
表單構(gòu)建允許用戶通過拖放等可視化操作創(chuàng)建表單,比如用來收集數(shù)據(jù)的表格或調(diào)查問卷。
可以自定義表單的各個(gè)部分,比如添加不同的輸入項(xiàng)和設(shè)置驗(yàn)證規(guī)則,無(wú)需編寫代碼。
提供了導(dǎo)出數(shù)據(jù)、導(dǎo)入數(shù)據(jù)、分享表單和設(shè)置權(quán)限的功能,方便數(shù)據(jù)管理和共享。
通過表單構(gòu)建工具,單獨(dú)制作一個(gè)添加課程的表單頁(yè)面。
實(shí)現(xiàn)步驟:
①制作表單并導(dǎo)出
②復(fù)制到前端工程
③創(chuàng)建動(dòng)態(tài)菜單
代碼生成
- 自動(dòng)化工具,可以快速生成項(xiàng)目中常用的代碼,如數(shù)據(jù)庫(kù)操作類、后端控制器、前端頁(yè)面等。
- 支持根據(jù)數(shù)據(jù)庫(kù)的表結(jié)構(gòu)反向生成代碼,減少手動(dòng)編寫的工作量。
- 提供三種生成模板:單表、 樹表、主子表(一對(duì)多),可以生成適用于Spring Boot、MyBatis等流行框架的代碼,提高開發(fā)效率和代碼質(zhì)量。
- 樹表是一種展示層級(jí)數(shù)據(jù)的表格,能展開折疊,清晰呈現(xiàn)父子關(guān)系,便于管理。
代碼生成配置主表實(shí)現(xiàn)細(xì)節(jié):
系統(tǒng)接口
Swagger,能夠自動(dòng)生成 API 的同步在線文檔,并提供Web界面進(jìn)行接口調(diào)用和測(cè)試。
核心的注解,主要包含以下幾個(gè):
注解 | 位置 | 說明 |
---|---|---|
@ApiModel | 類(通常是實(shí)體類) | 描述實(shí)體類的作用 |
@ApiModelProperty | 屬性 | 描述實(shí)體類的屬性 |
@Api | 類 | 加載Controller類上,表示對(duì)類的說明 |
@ApiOperation | 方法 | 說明方法的用途、作用 |
@ApiImplicitParams | 方法 | 表示一組參數(shù)說明 |
@ApiImplicitParam | 方法 | 用在@ApiImplicitParams注解中,指定一個(gè)請(qǐng)求參數(shù)的各個(gè)方面的屬性 |
項(xiàng)目結(jié)構(gòu)
在功能的講解過程中,涉及的前后端項(xiàng)目的結(jié)構(gòu)和配置文件,我們還比較陌生,為了更好的使用若依進(jìn)行項(xiàng)目開發(fā),所以接下來,我們開始進(jìn)入項(xiàng)目結(jié)構(gòu)這部分內(nèi)容的學(xué)習(xí)
后端結(jié)構(gòu)
com.ruoyi
├── ruoyi-admin // 后臺(tái)服務(wù)模塊
│ └── web // 內(nèi)置功能的表現(xiàn)層
│ └── RuoYiApplication // 若依項(xiàng)目啟動(dòng)類
├── ruoyi-common // 通用工具模塊
│ └── annotation // 自定義注解
│ └── config // 全局配置
│ └── constant // 通用常量
│ └── core // 核心控制
│ └── enums // 通用枚舉
│ └── exception // 通用異常
│ └── filter // 過濾器處理
│ └── utils // 通用類處理
│ └── xss // 自定義xss校驗(yàn)
├── ruoyi-framework // 框架核心模塊
│ └── aspectj // AOP配置
│ └── config // 系統(tǒng)配置
│ └── datasource // 多數(shù)據(jù)源配置
│ └── interceptor // 攔截器
│ └── manager // 異步處理
│ └── security // 權(quán)限控制
│ └── web // 前端控制
├── ruoyi-generator // 代碼生成模塊(可移除)
├── ruoyi-quartz // 定時(shí)任務(wù)模塊(可移除)
├── ruoyi-system // 系統(tǒng)代碼模塊
│ └── domain // 系統(tǒng)代碼的實(shí)體類
│ └── mapper // 系統(tǒng)代碼的持久層
│ └── service // 系統(tǒng)代碼的業(yè)務(wù)層
項(xiàng)目中的配置文件都在ruoyi-admin模塊下,如下圖:
- i18n:國(guó)際化處理
- META-INF:存儲(chǔ)了項(xiàng)目的元信息(描述數(shù)據(jù)的數(shù)據(jù)),無(wú)需修改
- mybatis:mybatis相關(guān)的配置信息
- application.yml:項(xiàng)目中的核心配置
- application-druid.yml:數(shù)據(jù)庫(kù)連接配置
- banner.txt:默認(rèn)的banner圖標(biāo)信息,項(xiàng)目啟動(dòng),控制臺(tái)打印顯示
- logback.xml:日志配置
最主要的兩個(gè)配置文件:application.yml
# 項(xiàng)目相關(guān)配置
ruoyi:# 名稱name: RuoYi# 版本version: 3.8.7# 版權(quán)年份copyrightYear: 2024# 文件路徑 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)profile: D:/ruoyi/uploadPath# 獲取ip地址開關(guān)addressEnabled: false# 驗(yàn)證碼類型 math 數(shù)字計(jì)算 char 字符驗(yàn)證captchaType: math# 開發(fā)環(huán)境配置
server:# 服務(wù)器的HTTP端口,默認(rèn)為8080port: 8080servlet:# 應(yīng)用的訪問路徑context-path: /tomcat:# tomcat的URI編碼uri-encoding: UTF-8# 連接數(shù)滿后的排隊(duì)數(shù),默認(rèn)為100accept-count: 1000threads:# tomcat最大線程數(shù),默認(rèn)為200max: 800# Tomcat啟動(dòng)初始化的線程數(shù),默認(rèn)值10min-spare: 100# 日志配置
logging:level:com.ruoyi: debugorg.springframework: warn# 用戶配置
user:password:# 密碼最大錯(cuò)誤次數(shù)maxRetryCount: 5# 密碼鎖定時(shí)間(默認(rèn)10分鐘)lockTime: 10# Spring配置
spring:# 資源信息messages:# 國(guó)際化資源文件路徑basename: i18n/messagesprofiles:active: druid# 文件上傳servlet:multipart:# 單個(gè)文件大小max-file-size: 10MB# 設(shè)置總上傳的文件大小max-request-size: 20MB# 服務(wù)模塊devtools:restart:# 熱部署開關(guān)enabled: true# redis 配置redis:# 地址host: localhost# 端口,默認(rèn)為6379port: 6379# 數(shù)據(jù)庫(kù)索引database: 0# 密碼password: 123456# 連接超時(shí)時(shí)間timeout: 10slettuce:pool:# 連接池中的最小空閑連接min-idle: 0# 連接池中的最大空閑連接max-idle: 8# 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)max-active: 8# #連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)max-wait: -1ms# token配置
token:# 令牌自定義標(biāo)識(shí)header: Authorization# 令牌密鑰secret: abcdefghijklmnopqrstuvwxyz# 令牌有效期(默認(rèn)30分鐘)expireTime: 30# MyBatis配置
mybatis:# 搜索指定包別名typeAliasesPackage: com.ruoyi.**.domain# 配置mapper的掃描,找到所有的mapper.xml映射文件mapperLocations: classpath*:mapper/**/*Mapper.xml# 加載全局的配置文件configLocation: classpath:mybatis/mybatis-config.xml# PageHelper分頁(yè)插件
pagehelper:helperDialect: mysqlsupportMethodsArguments: trueparams: count=countSql# Swagger配置
swagger:# 是否開啟swaggerenabled: true# 請(qǐng)求前綴pathMapping: /dev-api# 防止XSS攻擊
xss:# 過濾開關(guān)enabled: true# 排除鏈接(多個(gè)用逗號(hào)分隔)excludes: /system/notice# 匹配鏈接urlPatterns: /system/*,/monitor/*,/tool/*
各個(gè)模塊之間的依賴關(guān)系:
前端結(jié)構(gòu)
ruoyi-vue3
├── bin // 執(zhí)行腳本
├── html // IE低版本提示頁(yè)
├── node_modules // 第三方依賴庫(kù)
├── public // 公共資源
│ ├── favicon.ico // favicon圖標(biāo)
├── src // 源代碼
│ ├── api // 所有請(qǐng)求
│ ├── assets // 靜態(tài)資源
│ ├── components // 全局公用組件
│ ├── directive // 全局指令
│ ├── layout // 布局
│ ├── plugins // 通用插件
│ ├── router // 路由配置
│ ├── store // 狀態(tài)管理
│ ├── utils // 全局公用方法
│ ├── views // 視圖組件
│ ├── App.vue // 入口組件
│ ├── main.js // 入口文件
│ ├── permission.js // 權(quán)限管理
│ └── settings.js // 系統(tǒng)配置
├── vite // 構(gòu)建工具
├── .env.development // 開發(fā)環(huán)境配置
├── .env.production // 生產(chǎn)環(huán)境配置
├── .env.staging // 測(cè)試環(huán)境配置
├── .gitignore // git 忽略項(xiàng)
├── index.html // 入口頁(yè)面
├── package.json // 項(xiàng)目配置文件(相當(dāng)于pom.xml)
└── vue.config.js // Vue項(xiàng)目的配置信息(相當(dāng)于application.yml)
表結(jié)構(gòu)
ruoyi-vue
數(shù)據(jù)庫(kù)設(shè)計(jì)包含了多個(gè)表結(jié)構(gòu),用于支持系統(tǒng)的各種功能模塊
這些表可以根據(jù)它們的功能和用途進(jìn)行分類,以便在后期使用時(shí)能夠快速定位和理解
以下是對(duì)這些表結(jié)構(gòu)的分類和簡(jiǎn)要說明
源碼閱讀
本章我們將圍繞入門案例生成的課程管理進(jìn)行講解,包含前后端代碼的分析,以及前后端代碼交互的流程,通過這部分的學(xué)習(xí),不僅能讓我們掌握若依的基礎(chǔ)業(yè)務(wù)邏輯,在此基礎(chǔ)上還能為我們?nèi)蘸蟮亩ㄖ崎_發(fā)提供強(qiáng)有力的支撐。
前端代碼分析
找到src/views/course/course/index.vue文件,護(hù)理項(xiàng)目的前端代碼已經(jīng)添加了詳細(xì)的注釋,如下:
<template><div class="app-container"><!-- 搜索表單 start --><el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> <el-form-item label="課程編碼" prop="code"><el-inputv-model="queryParams.code"placeholder="請(qǐng)輸入課程編碼"clearable@keyup.enter="handleQuery"/></el-form-item><el-form-item label="課程學(xué)科" prop="subject"><el-select v-model="queryParams.subject" placeholder="請(qǐng)選擇課程學(xué)科" clearable><el-optionv-for="dict in course_subject":key="dict.value":label="dict.label":value="dict.value"/></el-select></el-form-item><el-form-item label="課程名稱" prop="name"><el-inputv-model="queryParams.name"placeholder="請(qǐng)輸入課程名稱"clearable@keyup.enter="handleQuery"/></el-form-item><el-form-item label="適用人群" prop="applicablePerson"><el-inputv-model="queryParams.applicablePerson"placeholder="請(qǐng)輸入適用人群"clearable@keyup.enter="handleQuery"/></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button><el-button icon="Refresh" @click="resetQuery">重置</el-button></el-form-item></el-form><!-- 搜索表單 end --><!-- 按鈕區(qū)域 start --><el-row :gutter="10" class="mb8"><el-col :span="1.5"><el-buttontype="primary"plainicon="Plus"@click="handleAdd"v-hasPermi="['course:course:add']">新增</el-button></el-col><el-col :span="1.5"><el-buttontype="success"plainicon="Edit":disabled="single"@click="handleUpdate"v-hasPermi="['course:course:edit']">修改</el-button></el-col><el-col :span="1.5"><el-buttontype="danger"plainicon="Delete":disabled="multiple"@click="handleDelete"v-hasPermi="['course:course:remove']">刪除</el-button></el-col><el-col :span="1.5"><el-buttontype="warning"plainicon="Download"@click="handleExport"v-hasPermi="['course:course:export']">導(dǎo)出</el-button></el-col><right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar></el-row><!-- 按鈕區(qū)域end --><!-- 數(shù)據(jù)展示表格 start --><el-table v-loading="loading" :data="courseList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /><el-table-column label="課程id" align="center" prop="id" /><el-table-column label="課程編碼" align="center" prop="code" /><el-table-column label="課程學(xué)科" align="center" prop="subject"><template #default="scope"><dict-tag :options="course_subject" :value="scope.row.subject"/></template></el-table-column><el-table-column label="課程名稱" align="center" prop="name" /><el-table-column label="價(jià)格" align="center" prop="price" /><el-table-column label="適用人群" align="center" prop="applicablePerson" /><el-table-column label="課程介紹" align="center" prop="info" /><el-table-column label="操作" align="center" class-name="small-padding fixed-width"><template #default="scope"><el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['course:course:edit']">修改</el-button><el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['course:course:remove']">刪除</el-button></template></el-table-column></el-table><!-- 數(shù)據(jù)展示表格 end --><!-- 分頁(yè)區(qū)域 start --><paginationv-show="total>0":total="total"v-model:page="queryParams.pageNum"v-model:limit="queryParams.pageSize"@pagination="getList"/><!-- 分頁(yè)區(qū)域 end --><!-- 添加或修改課程管理對(duì)話框 --><el-dialog :title="title" v-model="open" width="500px" append-to-body><el-form ref="courseRef" :model="form" :rules="rules" label-width="80px"><el-form-item label="課程編碼" prop="code"><el-input v-model="form.code" placeholder="請(qǐng)輸入課程編碼" /></el-form-item><el-form-item label="課程學(xué)科" prop="subject"><el-select v-model="form.subject" placeholder="請(qǐng)選擇課程學(xué)科"><el-optionv-for="dict in course_subject":key="dict.value":label="dict.label":value="dict.value"></el-option></el-select></el-form-item><el-form-item label="課程名稱" prop="name"><el-input v-model="form.name" placeholder="請(qǐng)輸入課程名稱" /></el-form-item><el-form-item label="價(jià)格" prop="price"><el-input v-model="form.price" placeholder="請(qǐng)輸入價(jià)格" /></el-form-item><el-form-item label="適用人群" prop="applicablePerson"><el-input v-model="form.applicablePerson" placeholder="請(qǐng)輸入適用人群" /></el-form-item><el-form-item label="課程介紹" prop="info"><el-input v-model="form.info" placeholder="請(qǐng)輸入課程介紹" /></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button type="primary" @click="submitForm">確 定</el-button><el-button @click="cancel">取 消</el-button></div></template></el-dialog></div>
</template><script setup name="Course">// 引入后端api接口
import { listCourse, getCourse, delCourse, addCourse, updateCourse } from "@/api/course/course";
// 獲取當(dāng)前實(shí)例代理對(duì)象,用于訪問組件數(shù)據(jù)、方法
const { proxy } = getCurrentInstance();
// 獲取課程學(xué)科的數(shù)據(jù)字典
const { course_subject } = proxy.useDict('course_subject');
// 列表數(shù)據(jù)
const courseList = ref([]);
// 是否顯示彈框
const open = ref(false);
// 是否顯示加載狀態(tài)
const loading = ref(true);
// 是否顯示搜索欄
const showSearch = ref(true);
// 復(fù)選框,被選中id的數(shù)組
const ids = ref([]);
// 復(fù)選框,是否單選,用于高亮修改、刪除按鈕
const single = ref(true);
// 復(fù)選框,是否多選,僅高亮刪除按鈕
const multiple = ref(true);
// 總(記錄)條數(shù)
const total = ref(0);
// 用于區(qū)分新增、修改對(duì)話框標(biāo)題
const title = ref("");
// 定義reactive響應(yīng)式對(duì)象
const data = reactive({// 新增或修改表單數(shù)據(jù)form: {},// 搜索條件參數(shù)queryParams: {pageNum: 1,pageSize: 10,code: null,subject: null,name: null,applicablePerson: null,},// 表單校驗(yàn)規(guī)則rules: {code: [{ required: true, message: "課程編碼不能為空", trigger: "blur" }],subject: [{ required: true, message: "課程學(xué)科不能為空", trigger: "change" }],name: [{ required: true, message: "課程名稱不能為空", trigger: "blur" }],price: [{ required: true, message: "價(jià)格不能為空", trigger: "blur" }],applicablePerson: [{ required: true, message: "適用人群不能為空", trigger: "blur" }],info: [{ required: true, message: "課程介紹不能為空", trigger: "blur" }],}
});
// 將data對(duì)象的三個(gè)屬性,轉(zhuǎn)換為ref響應(yīng)式對(duì)象
const { queryParams, form, rules } = toRefs(data);/** 查詢課程管理列表 */
function getList() {loading.value = true;listCourse(queryParams.value).then(response => {courseList.value = response.rows;total.value = response.total;loading.value = false;});
}// 取消按鈕
function cancel() {open.value = false;reset();
}// 表單重置
function reset() {form.value = {id: null,code: null,subject: null,name: null,price: null,applicablePerson: null,info: null,createTime: null,updateTime: null};proxy.resetForm("courseRef");
}/** 搜索按鈕操作 */
function handleQuery() {queryParams.value.pageNum = 1;getList();
}/** 重置按鈕操作 */
function resetQuery() {proxy.resetForm("queryRef");handleQuery();
}// 多選框選中數(shù)據(jù)
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.valuegetCourse(_id).then(response => {form.value = response.data;open.value = true;title.value = "修改課程管理";});
}/** 提交按鈕 */
function submitForm() {proxy.$refs["courseRef"].validate(valid => {if (valid) {if (form.value.id != null) {updateCourse(form.value).then(response => {proxy.$modal.msgSuccess("修改成功");open.value = false;getList();});} else {addCourse(form.value).then(response => {proxy.$modal.msgSuccess("新增成功");open.value = false;getList();});}}});
}/** 刪除按鈕操作 */
function handleDelete(row) {const _ids = row.id || ids.value;proxy.$modal.confirm('是否確認(rèn)刪除課程管理編號(hào)為"' + _ids + '"的數(shù)據(jù)項(xiàng)?').then(function() {return delCourse(_ids);}).then(() => {getList();proxy.$modal.msgSuccess("刪除成功");}).catch(() => {});
}/** 導(dǎo)出按鈕操作 */
function handleExport() {proxy.download('course/course/export', { ...queryParams.value}, `course_${new Date().getTime()}.xlsx`)
}// 頁(yè)面加載時(shí)執(zhí)行-查詢課程管理列表
getList();
</script>
后端代碼分析
CourseController
ruoyi-admin模塊下找到這個(gè)類:com.ruoyi.web.controller.course.CourseController里面有5個(gè)對(duì)應(yīng)的方法接口,詳細(xì)代碼如下:
package com.sky.course.controller;import com.sky.common.annotation.Log;
import com.sky.common.core.controller.BaseController;
import com.sky.common.core.domain.AjaxResult;
import com.sky.common.core.page.TableDataInfo;
import com.sky.common.enums.BusinessType;
import com.sky.common.utils.poi.ExcelUtil;
import com.sky.course.domain.Course;
import com.sky.course.service.ICourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.util.List;/*** 課程管理Controller** @author itheima*/
@RestController
@RequestMapping("/course/course")
public class CourseController extends BaseController
{@Autowiredprivate ICourseService courseService;/*** 查詢課程管理列表*/@PreAuthorize("@ss.hasPermi('course:course:list')")@GetMapping("/list")public TableDataInfo list(Course course){//1. 開啟分頁(yè)startPage();//2. 查詢課程列表List<Course> list = courseService.selectCourseList(course);//3. 返回表格分頁(yè)數(shù)據(jù)對(duì)象return getDataTable(list);}/*** 導(dǎo)出課程管理列表*/@PreAuthorize("@ss.hasPermi('course:course:export')")@Log(title = "課程管理", businessType = BusinessType.EXPORT)@PostMapping("/export")public void export(HttpServletResponse response, Course course){List<Course> list = courseService.selectCourseList(course);ExcelUtil<Course> util = new ExcelUtil<Course>(Course.class);util.exportExcel(response, list, "課程管理數(shù)據(jù)");}/*** 獲取課程管理詳細(xì)信息*/@PreAuthorize("@ss.hasPermi('course:course:query')")@GetMapping(value = "/{id}")public AjaxResult getInfo(@PathVariable("id") Long id){return success(courseService.selectCourseById(id));}/*** 新增課程管理*/@PreAuthorize("@ss.hasPermi('course:course:add')")@Log(title = "課程管理", businessType = BusinessType.INSERT)@PostMappingpublic AjaxResult add(@RequestBody Course course){return toAjax(courseService.insertCourse(course));}/*** 修改課程管理*/@PreAuthorize("@ss.hasPermi('course:course:edit')")@Log(title = "課程管理", businessType = BusinessType.UPDATE)@PutMappingpublic AjaxResult edit(@RequestBody Course course){return toAjax(courseService.updateCourse(course));}/*** 刪除課程管理*/@PreAuthorize("@ss.hasPermi('course:course:remove')")@Log(title = "課程管理", businessType = BusinessType.DELETE)@DeleteMapping("/{ids}")public AjaxResult remove(@PathVariable Long[] ids){return toAjax(courseService.deleteCourseByIds(ids));}
}
BaseController
Controller繼承了BaseController,其中BaseController詳細(xì)定義如下圖:
TableDataInfo
分頁(yè)查詢統(tǒng)一返回對(duì)象:表格分頁(yè)數(shù)據(jù)對(duì)象
AjaxResult
增刪改查統(tǒng)一返回對(duì)象:操作消息提醒
BaseEntity
所有實(shí)體類默認(rèn)繼承的BaseEntity基類
權(quán)限注解
@PreAuthorize 注解是 Spring Security 框架中用來做權(quán)限檢查的。
它在運(yùn)行方法前先驗(yàn)證權(quán)限,權(quán)限夠就放行,不夠就攔截。
權(quán)限控制流程圖
前后端交互
接口文檔
跨域
在前端開發(fā)中,跨域是一個(gè)常見的問題,特別是在使用Vue框架進(jìn)行開發(fā)時(shí)??缬蚴侵冈跒g覽器中發(fā)送的AJAX請(qǐng)求的目標(biāo)地址與當(dāng)前頁(yè)面的地址不在同一個(gè)域下,這會(huì)導(dǎo)致瀏覽器的同源策略產(chǎn)生限制,從而阻止了跨域請(qǐng)求的發(fā)送。然而,我們可以通過代理服務(wù)器來解決這個(gè)問題。
代理服務(wù)器是位于客戶端和目標(biāo)服務(wù)器之間的一臺(tái)服務(wù)器,它接收客戶端發(fā)送的請(qǐng)求,并將請(qǐng)求轉(zhuǎn)發(fā)給目標(biāo)服務(wù)器。通過在代理服務(wù)器上進(jìn)行請(qǐng)求轉(zhuǎn)發(fā),可以繞過瀏覽器的同源策略限制,從而實(shí)現(xiàn)跨域請(qǐng)求。
在vue.config.js文件中添加以下內(nèi)容:
外觀調(diào)整
接下來我們將利用這些知識(shí),實(shí)現(xiàn)外賣管理系統(tǒng)的業(yè)務(wù)功能開發(fā)
修改包名
若依框架修改器是一個(gè)可以一鍵修改RuoYi框架包名、項(xiàng)目名等的工具。
地址:https://gitee.com/lpf_project/RuoYi-MT/releases
資料中已提供,將項(xiàng)目打成壓縮包,直接修改即可:
頁(yè)面調(diào)整
如果使用若依框架項(xiàng)目做為腳手架,那么我們肯定需要在頁(yè)面顯示中,符合自己公司或者項(xiàng)目的標(biāo)識(shí)才行,需要更換的地方很多,我們依次來解決它
- 瀏覽器標(biāo)簽頁(yè)logo標(biāo)識(shí)、標(biāo)題
- 系統(tǒng)頁(yè)面中的logo標(biāo)識(shí)、標(biāo)題
- 去除源碼地址 & 文檔地址
- 主題風(fēng)格和菜單圖標(biāo)
- 登錄名稱及背景圖
瀏覽器標(biāo)簽頁(yè)icon、標(biāo)題
找到資料中的logo圖標(biāo),替換前端項(xiàng)目中的public文件夾,刪除原有的favicon.ico,把新拷貝過來的logo更名為favicon.ico即可
找到根目錄下的index.html文件,把title更換為自己想要的內(nèi)容即可
系統(tǒng)頁(yè)面中的logo、標(biāo)題
找到資料中的logo文件,替換 src/assets/logo/logo.png文件
若依的系統(tǒng)頁(yè)面標(biāo)題引用的是開發(fā)環(huán)境的配置,我們只需要修改開發(fā)的環(huán)境的VITE_APP_TITLE屬性即可
去除源碼 & 文檔
主題和自定義圖標(biāo)
在目前的前端項(xiàng)目中,已經(jīng)提供了非常便利的操作方式,可以切換主題的風(fēng)格
操作:點(diǎn)擊右上角的頭像,可以找到**布局設(shè)置,**如下操作
在前端代碼中也有對(duì)應(yīng)的操作,更好主題風(fēng)格文件位置:src/setting.js
更換主題顏色文件位置:src/store/modules/settings.js
訪問阿里巴巴矢量圖庫(kù),搜索圖標(biāo):https://www.iconfont.cn/search/index?searchType=icon&q=%E8%8F%9C%E5%93%81%E7%AE%A1%E7%90%86
將下載好的圖標(biāo)復(fù)制到src/assets/icons/svg目錄下,就可以給指定菜單設(shè)置圖標(biāo)了
登錄頁(yè)面中標(biāo)題、背景圖
登錄名稱和背景圖,我們可以直接找到登錄的組件進(jìn)行修改即可
組件位置:src/views/login.vue
學(xué)習(xí)視頻
[外鏈圖片轉(zhuǎn)存中…(img-u7cNdLru-1725849664177)]
[外鏈圖片轉(zhuǎn)存中…(img-cPH8fMp9-1725849664178)]
瀏覽器標(biāo)簽頁(yè)icon、標(biāo)題
找到資料中的logo圖標(biāo),替換前端項(xiàng)目中的public文件夾,刪除原有的favicon.ico,把新拷貝過來的logo更名為favicon.ico即可
[外鏈圖片轉(zhuǎn)存中…(img-xmN5sX79-1725849664178)]
找到根目錄下的index.html文件,把title更換為自己想要的內(nèi)容即可
[外鏈圖片轉(zhuǎn)存中…(img-ggmE9jNj-1725849664178)]
系統(tǒng)頁(yè)面中的logo、標(biāo)題
找到資料中的logo文件,替換 src/assets/logo/logo.png文件
[外鏈圖片轉(zhuǎn)存中…(img-0Vz5lATJ-1725849664178)]
若依的系統(tǒng)頁(yè)面標(biāo)題引用的是開發(fā)環(huán)境的配置,我們只需要修改開發(fā)的環(huán)境的VITE_APP_TITLE屬性即可
[外鏈圖片轉(zhuǎn)存中…(img-BixADlWw-1725849664178)]
去除源碼 & 文檔
[外鏈圖片轉(zhuǎn)存中…(img-fCem5lcp-1725849664179)]
主題和自定義圖標(biāo)
在目前的前端項(xiàng)目中,已經(jīng)提供了非常便利的操作方式,可以切換主題的風(fēng)格
操作:點(diǎn)擊右上角的頭像,可以找到**布局設(shè)置,**如下操作
[外鏈圖片轉(zhuǎn)存中…(img-Dvzorq3B-1725849664179)]
在前端代碼中也有對(duì)應(yīng)的操作,更好主題風(fēng)格文件位置:src/setting.js
[外鏈圖片轉(zhuǎn)存中…(img-SFjXJCRs-1725849664179)]
更換主題顏色文件位置:src/store/modules/settings.js
[外鏈圖片轉(zhuǎn)存中…(img-3mqrNe9K-1725849664179)]
訪問阿里巴巴矢量圖庫(kù),搜索圖標(biāo):https://www.iconfont.cn/search/index?searchType=icon&q=%E8%8F%9C%E5%93%81%E7%AE%A1%E7%90%86
[外鏈圖片轉(zhuǎn)存中…(img-ceRqudBL-1725849664179)]
將下載好的圖標(biāo)復(fù)制到src/assets/icons/svg目錄下,就可以給指定菜單設(shè)置圖標(biāo)了
[外鏈圖片轉(zhuǎn)存中…(img-7sG47hEf-1725849664180)]
登錄頁(yè)面中標(biāo)題、背景圖
登錄名稱和背景圖,我們可以直接找到登錄的組件進(jìn)行修改即可
組件位置:src/views/login.vue
[外鏈圖片轉(zhuǎn)存中…(img-I8ACWziX-1725849664180)]
[外鏈圖片轉(zhuǎn)存中…(img-3h4S7KQY-1725849664180)]
學(xué)習(xí)視頻
https://www.bilibili.com/video/BV1pf421B71v