wordpress 單頁案例seo全網(wǎng)優(yōu)化指南
1.代碼生成器
1.1源碼分析
代碼生成器分為兩個(gè)部分:
第一部分涉及將業(yè)務(wù)表結(jié)構(gòu)導(dǎo)入到系統(tǒng)中
第二部分是點(diǎn)擊生成按鈕,系統(tǒng)將根據(jù)表結(jié)構(gòu)生成相應(yīng)的前后端代碼,并提供下載。
1.表結(jié)構(gòu)說明
gen_table
:存儲(chǔ)業(yè)務(wù)表的基本信息 ,它對(duì)應(yīng)于配置代碼基本信息和生成信息的頁面
gen_table_column
:存儲(chǔ)業(yè)務(wù)表的字段信息 它對(duì)應(yīng)于配置代碼字段信息的頁面。
這兩張表是一對(duì)多的關(guān)系,一張業(yè)務(wù)表可以有多個(gè)字段的信息,所以在字段信息表中有個(gè)外鍵table_id指向
2.目錄結(jié)構(gòu)
3.查詢數(shù)據(jù)庫列表
當(dāng)管理員在界面上點(diǎn)擊導(dǎo)入按鈕時(shí),會(huì)彈出一個(gè)對(duì)話框,此時(shí),前端需要向后端發(fā)送請(qǐng)求,查詢數(shù)據(jù)庫并返回到前端,展示當(dāng)前項(xiàng)目庫中所有待導(dǎo)入的業(yè)務(wù)表。
<select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">select table_name, table_comment, create_time, update_time from information_schema.tableswhere table_schema = (select database())AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'AND table_name NOT IN (select table_name from gen_table)<if test="tableName != null and tableName != ''">AND lower(table_name) like lower(concat('%', #{tableName}, '%'))</if><if test="tableComment != null and tableComment != ''">AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))</if><if test="params.beginTime != null and params.beginTime != ''"><!-- 開始時(shí)間檢索 -->AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')</if><if test="params.endTime != null and params.endTime != ''"><!-- 結(jié)束時(shí)間檢索 -->AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')</if>order by create_time desc</select>
4.導(dǎo)入表結(jié)構(gòu)
當(dāng)管理員對(duì)話框中選中需要導(dǎo)入的業(yè)務(wù)表,點(diǎn)擊確定按鈕,此時(shí),前端需要向后端發(fā)送請(qǐng)求,保存業(yè)務(wù)表的基本信息和字段信息
5.生成代碼
6.問題分析
(1)每次生成代碼都需要修改作者,去除實(shí)體類前綴過于繁瑣,現(xiàn)在我們可以修改generator.yml
配置文件來調(diào)整為自己項(xiàng)目的
(2)實(shí)體類支持Lombok,Controller類支持Swagger
需要Velocity模板引擎
1.2Velocity模版引擎
Velocity是一個(gè)基于Java的模板引擎,可以通過特定的語法獲取在java對(duì)象的數(shù)據(jù) , 填充到模板中,從而實(shí)現(xiàn)界面和java代碼的分離 !
1.基礎(chǔ)語法
Velocity中的變量有兩類
-
在模板中定義變量:
#set
開頭,比如#set($name = "velocity")
-
獲取變量的的值:
$name
或者${name}
獲取對(duì)象中的數(shù)據(jù)
循環(huán)
循環(huán)遍歷普通集合
循環(huán)遍歷對(duì)象
if判斷
在條件判斷中,velocity支持常見的關(guān)系操作符,比如:&&(與), ||(或), !(非)
2.Lombok集成
(1)導(dǎo)入坐標(biāo)(已完成)
在dkd-common
模塊的pom.xml
中添加lombok坐標(biāo)
(2)修改模板
在dkd-generator
模塊的domain.java.vm
模板中添加lombok注解
修改完成之后,重啟項(xiàng)目,找到代碼生成的功能,通過代碼預(yù)覽可以查看實(shí)體類的代碼:
3.Swagger集成
(1)修改模板
在dkd-generator
模塊的 controller.java.vm
模板中添加Swagger注解
返回結(jié)果改為R<>
2.RBAC權(quán)限控制
Spring Security是一個(gè)功能強(qiáng)大的Java安全框架,它提供了全面的安全認(rèn)證和授權(quán)的支持。
1)認(rèn)證(Authentication) 在Spring Security的世界里,認(rèn)證就像用戶登錄時(shí)提交的用戶名和密碼,系統(tǒng)通過這些信息來驗(yàn)證“你是誰”。
2)授權(quán)(Authorization) 授權(quán)是確認(rèn)用戶在通過認(rèn)證之后,是否有權(quán)限執(zhí)行某些操作或訪問特定資源。
2.1SpringSecurity配置
Spring Security的配置類是實(shí)現(xiàn)安全控制的核心部分
開啟Spring Security各種功能,以確保Web應(yīng)用程序的安全性,包括認(rèn)證、授權(quán)、會(huì)話管理、過濾器添加等。
2.2用戶登錄流程
在ruoyi-framework
模塊中com.ruoyi.framework.web.service.SysLoginService
類的login
方法處理登錄邏輯
-
驗(yàn)證碼校驗(yàn)
-
登錄前置校驗(yàn)
-
SS認(rèn)證管理器用戶校驗(yàn),調(diào)用執(zhí)行UserDetailsServiceImpl.loadUserByUsername
-
認(rèn)證通過后,創(chuàng)建登錄用戶對(duì)象LoginUser包括用戶ID、部門ID、用戶信息和用戶權(quán)限信息
-
-
登錄成功,記錄日志
-
修改用戶表更新登錄信息
-
生成token
2.3獲取用戶角色和權(quán)限
在ruoyi-framework
模塊中com.ruoyi.framework.web.service.SysPermissionService
類
-
getRolePermission查詢?cè)撚脩艚巧?/p>
-
getMenuPermission查詢?cè)撚脩魴?quán)限(菜單)集合用set集合,一個(gè)用戶可能有多個(gè)角色,多個(gè)角色的權(quán)限可能有重復(fù)的
頁面權(quán)限
2.4獲取動(dòng)態(tài)菜單路由
2.5權(quán)限注解
1.源碼分析
在若依框架中,權(quán)限的驗(yàn)證最核心的是使用的Spring Security的提供的權(quán)限注解`@PreAuthorize `
- @PreAuthorize 是 Spring Security 框架中提供的一個(gè)安全注解,用于實(shí)現(xiàn)基于注解的訪問控制。它允許開發(fā)者在**方法級(jí)別**上聲明特定的安全約束,以確保只有滿足指定條件的用戶才能調(diào)用該方法
- 當(dāng) @PreAuthorize 注解被應(yīng)用于某個(gè)方法時(shí),Spring Security 在**該方法執(zhí)行前**會(huì)先對(duì)當(dāng)前認(rèn)證的用戶進(jìn)行權(quán)限檢查。如果檢查通過,方法調(diào)用得以繼續(xù);否則,框架會(huì)拋出相應(yīng)的權(quán)限異常(如 AccessDeniedException),阻止方法執(zhí)行。
2.權(quán)限方法
3.公開接口
如果有些接口是不需要驗(yàn)證權(quán)限可以公開訪問的,這個(gè)時(shí)候就需要我們給接口放行。
使用注解方式,只需要在Controller
的類或方法上加入@Anonymous
該注解即可
3.異步任務(wù)管理器
主要用于處理一些不需要即時(shí)返回結(jié)果的后臺(tái)任務(wù),從而提高應(yīng)用程序的整體性能
// 多線程執(zhí)行任務(wù)me()創(chuàng)建單例對(duì)象(餓漢式)
AsyncManager.me().execute(AsyncFactory.createTimerTask());
若依異步任務(wù)管理器是一個(gè)單例對(duì)象使用了線程池+異步工廠(產(chǎn)生任務(wù)用)
-
com.dkd.framework.manager.AsyncManager 異步任務(wù)管理器
-
com.dkd.framework.manager.factory.AsyncFactory 異步線程工廠
1、 AsyncManager.me()獲取AsyncManager對(duì)象
2、調(diào)用execute方法,執(zhí)行TimerTask任務(wù)(記錄登錄日志),它實(shí)現(xiàn)了runnable接口,由線程Thread去執(zhí)行
3、execute方法內(nèi)部調(diào)用ScheduledExecutorService異步操作任務(wù)調(diào)度線程池的schedule方法用于延遲10毫秒執(zhí)行一個(gè)任務(wù)
4.操作日志
在需要被記錄日志的controller
方法上添加@Log
注解,使用方法如下:
@Log(title = "訂單管理", businessType = BusinessType.INSERT)
public AjaxResult add(...)
{return toAjax(...);
}
若依操作日志使用了自定義注解+AOP切面+異步任務(wù)管理器
-
com.ruoyi.common.annotation.Log 自定義注解
-
com.ruoyi.framework.aspectj.LogAspect 在一個(gè)aop切面類
-
通過實(shí)現(xiàn)AOP切面編程,對(duì)目標(biāo)方法進(jìn)行攔截(標(biāo)注Log注解的方法),實(shí)現(xiàn)了操作日志的自動(dòng)記錄
-
異步任務(wù)管理器來將任務(wù)(記錄操作日志到數(shù)據(jù)庫)交給線程池來完成
-
5.定時(shí)任務(wù)
5.1源碼分析
1.表結(jié)構(gòu)說明
sys_job
表(一):這是核心的定時(shí)任務(wù)表,用于存儲(chǔ)定時(shí)任務(wù)的配置信息,如任務(wù)名稱、任務(wù)組、執(zhí)行的類全名、執(zhí)行的參數(shù)、cron表達(dá)式等
sys_job_log
表(多):用于記錄定時(shí)任務(wù)的執(zhí)行日志,包括任務(wù)的開始執(zhí)行時(shí)間、結(jié)束執(zhí)行時(shí)間、執(zhí)行結(jié)果等
2.Quartz體系結(jié)構(gòu)
3.Quartz核心API
4.定時(shí)任務(wù)執(zhí)行
5.添加定時(shí)任務(wù)
6.定時(shí)任務(wù)狀態(tài)修改
剛才我們分析新增定時(shí)任務(wù)的源碼時(shí),發(fā)現(xiàn)了任務(wù)在初始化時(shí)是處于暫停狀態(tài)的。
如果要啟動(dòng)任務(wù),可以在頁面進(jìn)行任務(wù)狀態(tài)的開關(guān)控制,所以接下來我們對(duì)此功能的源碼進(jìn)行分析
5.2集群模式
首先我們來聊下為什么需要quartz集群
在單機(jī)模式下,默認(rèn)所有的jobDetail
和trigger
都存儲(chǔ)在內(nèi)存中。這樣做的好處是讀取速度快,但缺點(diǎn)也很明顯:一旦服務(wù)器故障,所有的任務(wù)數(shù)據(jù)就會(huì)丟失,這就是所謂的單點(diǎn)故障問題。
還有如果在一個(gè)高峰時(shí)段,比如上午9點(diǎn),需要觸發(fā)500個(gè)任務(wù),這將給服務(wù)器帶來巨大的負(fù)載壓力。這不僅影響性能,還可能引發(fā)服務(wù)中斷。
缺點(diǎn):單點(diǎn)故障、負(fù)載壓力大
為了解決這些問題,我們可以部署多個(gè)服務(wù)器節(jié)點(diǎn),將任務(wù)信息存儲(chǔ)到數(shù)據(jù)庫中。這樣,多個(gè)節(jié)點(diǎn)就可以通過共享數(shù)據(jù)庫來協(xié)調(diào)任務(wù)的執(zhí)行,形成Quartz集群模式。
這種方式不僅解決了單點(diǎn)故障問題,還能通過負(fù)載均衡提升效率。
集群模式的優(yōu)勢(shì)
-
高可用性:即使某個(gè)節(jié)點(diǎn)出現(xiàn)問題,其他節(jié)點(diǎn)仍然可以正常運(yùn)行。
-
負(fù)載均衡:將任務(wù)分散到不同的節(jié)點(diǎn)執(zhí)行,避免單個(gè)節(jié)點(diǎn)過載。
實(shí)現(xiàn)
1.導(dǎo)入sql
將若依提供的quartz.sql
導(dǎo)入到數(shù)據(jù)庫中
2.開啟配置
打開dkd-quartz
模塊中ScheduleConfig
配置類注釋
3.節(jié)點(diǎn)復(fù)制
首先修改當(dāng)前SpringBoot的啟動(dòng)類的名稱
我們?cè)偬砑?#xff08;復(fù)制)一個(gè)SpringBoot的啟動(dòng)配置
-Dserver.port=8081
4.觀察數(shù)據(jù)庫
重啟項(xiàng)目即可,觀察數(shù)據(jù)庫,已存入jobDetail和trigger,多個(gè)服務(wù)器節(jié)點(diǎn)可以實(shí)現(xiàn)共享
6.數(shù)據(jù)權(quán)限
在系統(tǒng)中,權(quán)限的分配和控制主要依賴于角色。每個(gè)角色可以被賦予不同的菜單權(quán)限和數(shù)據(jù)權(quán)限,用戶則通過他們的角色來繼承這些權(quán)限,進(jìn)而決定他們能訪問哪些系統(tǒng)資源。
目前,系統(tǒng)支持以下五種數(shù)據(jù)權(quán)限類型:
-
全部數(shù)據(jù)權(quán)限:無限制訪問所有數(shù)據(jù),相當(dāng)于擁有最高權(quán)限的通行證。
-
自定數(shù)據(jù)權(quán)限:用戶可以根據(jù)自己的需求設(shè)定訪問特定數(shù)據(jù)的規(guī)則。
-
部門數(shù)據(jù)權(quán)限:只能訪問自己所在部門的數(shù)據(jù),限制在本部門范圍內(nèi)。
-
部門及以下數(shù)據(jù)權(quán)限:可以訪問自己部門及下屬部門的數(shù)據(jù),適用于管理層級(jí)。
-
僅本人數(shù)據(jù)權(quán)限:只能訪問和操作自己的數(shù)據(jù),保障個(gè)人隱私和數(shù)據(jù)隔離。
1.源碼
1、若依系統(tǒng)的數(shù)據(jù)權(quán)限設(shè)計(jì)主要通過用戶、角色、部門表建立關(guān)系,實(shí)現(xiàn)對(duì)數(shù)據(jù)的訪問控制:
2、在需要數(shù)據(jù)權(quán)限控制方法上添加@DataScope
注解,其中d
和u
用來表示表的別名
3、在mybatis
查詢底部標(biāo)簽添加數(shù)據(jù)范圍過濾
其作用就是相當(dāng)于在一個(gè) select 語句后面拼接一個(gè) and 條件語句,來實(shí)現(xiàn)查詢限制
若依數(shù)據(jù)權(quán)限底層使用了自定義注解+AOP切面+SQL拼接
-
com.dkd.common.annotation.DataScope 自定義注解
-
com.ruoyi.framework.aspectj.DataScopeAspect:切面類
-
通過實(shí)現(xiàn)AOP編程,對(duì)目標(biāo)方法進(jìn)行攔截(標(biāo)注DataScope 注解的方法),實(shí)現(xiàn)了構(gòu)建數(shù)據(jù)范圍SQL過濾條件
-
僅實(shí)體繼承`BaseEntity`才會(huì)進(jìn)行處理,`SQL`語句會(huì)存放到`BaseEntity`對(duì)象中的`params`屬性中,然后在`xml`中通過`${params.dataScope}`獲取拼接后的語句。
2.改造
需求
我們有一個(gè)系統(tǒng)登錄日志,里面記錄了所有用戶的登錄信息。
但是,并不是所有人都應(yīng)該看到所有的日志數(shù)據(jù)。所以,我們需要根據(jù)用戶的角色來控制他們能查看的數(shù)據(jù)范圍。
(1)添加權(quán)限注解
在dkd-system
模塊的com.dkd.system.service.impl.SysLogininforServiceImpl
在服務(wù)層的方法上使用 @DataScope
注解
(2)添加表字段
如果sys_logininfo
業(yè)務(wù)表需要實(shí)現(xiàn)數(shù)據(jù)權(quán)限,需要有dept_id
和user_id
這兩個(gè)字段。
(3)添加實(shí)體屬性
在dkd-system
模塊的com.dkd.system.domain.SysLogininfor
實(shí)體類中,需要有deptId
和userId
這兩個(gè)屬性。
(4)修改映射文件
在dkd-system
模塊的com.dkd.system.domain.SysLogininforMapper.xml
映射文件中,通過動(dòng)態(tài)拼接 SQL,實(shí)現(xiàn)數(shù)據(jù)范圍的過濾
(5)異步工廠調(diào)整
在dkd-framework
模塊的com.dkd.framework.manager.factory.AsyncFactory
異步工廠創(chuàng)建登錄日志任務(wù)時(shí),需要有deptId
和userId
這兩個(gè)屬性。