**注意: 4.x 目前尚無開源和個人版**
可以把3.x和4.x看成2個不同的項目,下面列出詳細變化:
## 一. 項目拆分
> 項目名帶 pro 或 plus 的表示企業商用版或個人學習版,不帶 pro 或 plus 的表示對應的開源版
3.x 一個lamp-cloud項目,通過配置即可任意切換租戶模式,3.x 的全部項目包括:
- lamp-util(lamp-util-plus):工具類
- lamp-cloud(lamp-cloud-plus): spring cloud 版 后臺
- lamp-boot(lamp-boot-plus):spring boot 版 后臺
- lamp-web: vue2 + element-ui 版 前臺
- lamp-web-plus: vue3 + ant design vue 版 前臺 (僅企業版擁有)
- lamp-job(lamp-job-plus): 定時任務
- lamp-generator(lamp-generator-plus): 代碼生成
4.x 之后,除了 lamp-util-pro、lamp-generator-pro、lamp-job-pro 等工具類項目會共用, 其他的租戶模式,業務流程可能會不一致,會視情況會獨立多個項目,大家根據情況進行選擇:
#### 4.x 的公共項目
- lamp-util-pro (lamp-util)(已完成)
- lamp-generator-pro(lamp-generator)(已完成)
- lamp-job-pro(lamp-job)(已完成)
##### 4.x 的 大租戶小門店模式(DATASOURCE_COLUMN) (僅企業版擁有)
-
lamp-cloud-pro-datasource-column (已完成)
- lamp-web-pro-datasource-column(已完成)
- lamp-boot-pro-datasource-column (已完成)
##### 4.x 的 字段模式(COLUMN) (已完成)
-
lamp-cloud-pro-column (lamp-cloud-column)
- lamp-web-pro-column(lamp-web-column)
- lamp-boot-pro-column(lamp-boot-column)
##### 4.x 的 普通模式(NONE) (即將發布)
-
lamp-cloud-pro-none (lamp-cloud-none)
- lamp-web-pro-none (lamp-web-none)
- lamp-boot-pro-none(lamp-boot-none)
## 二. 服務合并
為了方便新手入門、降低系統部署成本、降低系統復雜度,隧對服務做了合并。
| 3.x 擁有服務 | 4.x 擁有服務 |
| --------------------- | ------------------- |
| lamp-authority-server | lamp-base-server |
| lamp-file-server | lamp-base-server |
| lamp-msg-server | lamp-base-server |
| lamp-oauth-server | lamp-oauth-server |
| lamp-tenant-server | lamp-system-server |
| lamp-gateway-server | lamp-gateway-server |
- lamp-system-server: 對應開發運營系統的功能接口
- lamp-base-server: 對應基礎平臺的功能接口
- lamp-oauth-server:對應登錄、菜單獲取、權限獲取、個人信息獲取等
- lamp-gateway-server:路由、token鑒權、URI鑒權等
> 合并原因? file 和 msg 服務的業務比較單一,而且也是比較基礎的功能
------
## 三. 數據庫變化
為了方便新手入門、降低系統部署成本、降低系統復雜度,隧對租戶數據庫做了合并。
| 3.x 擁有數據庫 | 4.x 擁有數據庫 | 備注 |
| ---------------------- | ----------------------- | ------------------------------ |
| lamp_defaults | lamp_ds_c_defaults | 所有租戶都相同的數據放在默認庫 |
| lamp_base_{租戶編碼} | lamp_ds_c_base_{租戶ID} | 租戶自己的數據,放在base庫 |
| lamp_extend_{租戶編碼} | lamp_ds_c_base_{租戶ID} | |
- datasource_column 模式庫名為:lamp_ds_c_defaults、lamp_ds_c_base_{租戶ID}
- datasource 模式庫名為:lamp_defaults、lamp_base_{租戶ID}
- column 模式庫名為:lamp_column
- none 模式庫名為:lamp_none
> 合并后,并不是指 不支持1個租戶配置多個租戶庫! 通過修改配置文件可以輕松實現調整數據庫。
## 四. 租戶數據的使用發生變化
3.x 除了租戶的創建相關的表和數據是全局庫(lamp_defaults庫),所有的租戶數據都在租戶庫(lamp_base_xxx或lamp_extend_xxx) 。 這樣做的好處是方便租戶擁有自己個性數據,但弊端也很明顯,對于一些全局數據,每個租戶都需要自己維護一份,后期發生改變,需要每個租戶都一起修改全局數據。 比如: 菜單、字典等數據。
> 對于菜單的配置,應該是全局僅有一份,而且只有讓系統開發方進行增刪改操作。租戶應該只有菜單的授權操作,即給不同的角色分配不同的菜單。
> 對于字典數據,應該是全局有一份系統內置的字典,租戶擁有一些自定義字典項(字典是字典的分類,字典項是字典的明細),租戶可以新增、修改或刪除字典項,但不會對全局字典造成影響。租戶讀取字典數據時,應先查詢自己是否有自己的字典,若自己沒有配置個性的字典,在讀取系統全局的字典。
上述的功能在3.x是不支持的,但在4.x得到了很好的解決。
------
## 五. 功能變化
- 菜單管理:更名為:資源維護
3.x 的菜單管理,需要每個租戶都維護1份`菜單`(c_menu) 和 `資源`(c_resource),即c_menu和c_resource存放在租戶庫(lamp_base_xxx),**當菜單變動時,需要調整所有租戶的菜單數據**。
4.x 的資源維護 將菜單、視圖(可以理解為隱藏菜單)、按鈕、字段、接口 統稱為資源,其中前4種資源存放在 `def_resource` 表通過type字段區分,URI存放在 def_resource_api 表,且存放在全局的lamp_defaults庫。
> 后面提到的`資源`都是這幾種類型的一個統稱,根據上下文可以是任意一種類型的資源, 甚至應用都可以理解為一種資源,因為應用是需要分配權限的,只是應用是給企業授權,資源是給企業下的員工授權。
```
* 菜單:頁面上可以點擊的菜單,可以是1級、2級、n級 (有些系統會區分為目錄和菜單,本系統都統稱為菜單)
* 視圖:隱藏的菜單,在頁面上看不見,但需要注冊到router中。常用于詳情頁,復雜的編輯頁等。
* 按鈕:頁面上的新增、刪除、修改、導入、下載等按鈕。
* 字段:控制頁面上不同人,能看到不一樣的字段。 可以控制顯示、隱藏、脫敏、是否可以編輯等。(功能尚未完善)
* 接口:菜單或視圖調用的所有接口,員工擁有菜單或視圖后,就應該擁有此菜單或視圖下的所有接口權限。
```
好處: 資源本應該是全局的,后期新增、修改或刪除 `菜單`、`uri`、`字段`、`按鈕`時,只需要調整全局的資源數據,即可影響所有租戶。 而資源數據是不允許租戶自己配置的,所以調整到了defaults庫。
- 角色管理:角色權限維護
4.x和3.x功能上沒有太大的調整,但在3.x基礎上增強了角色管理的邏輯:
- **3.x版本每次新增一個資源,都需要給每個租戶的超管綁定這個新增的資源**, 4.x 的每個租戶都內置一個`租戶管理員`,租戶管理員默認擁有管理租戶的所有權限,且他的權限是無需分配和刪除的,后期系統新增資源,也無需分配權限給這個租戶管理員角色。
- 給角色綁定資源時做了限制:①勾選了子資源,必定要勾選所有的父; ②取消了父資源,必定取消所有的子;③增加資源全選按鈕;
- 給角色綁定員工,為了優化員工過多的問題,調整為實時綁定、實時取消綁定。
- 字典管理:字典維護 + 個性字典
3.x 的字典管理,需要每個租戶都維護1份字典數據, 即c_dictionary存放在租戶庫(lamp_base_xxx),所有租戶都需要維護整個系統所需要的全部字典, **當字典變動時,需要調整所有租戶的字典數據。**
4.x 分為`字典維護`和`個性字典`,字典維護 維護的是全局的字典,個性字典維護每個租戶自己的字典項,租戶可以新增、修改或刪除字典項,但不會對全局字典造成影響。租戶讀取字典數據時,應先查詢自己是否有自己的字典,若自己沒有配置個性的字典,在讀取系統全局的字典。
- 參數管理:參數維護 + 個性參數
同 字典維護 + 個性字典
- 地區管理:地區維護
增加了導出地區json文件的功能,地址數據調整后,重新生成json文件,供前端使用。前端選擇級聯地區數據時,直接讀取json文件內容,加快響應速度。
- 應用管理:客戶端維護
維護你們系統的客戶端,比如:小程序端、安卓端、IOS端、WEB端等,然后將client_id和client_secret分配給對應的客戶端,接口請求時后臺接口時,攜帶client_id和client_secret, 方便日后做統計或其他限制。
- 登錄日志:登錄日志 + 登錄日志
在基礎平臺的登錄日志是租戶自己的登錄日志,在開發運營系統查看的登錄日志是**所有租戶**的登錄日志。
------
## 六. 新增功能
- 租戶體系
在3.x的基礎上,4.x 優化了以下功能:
1. 租戶在線創建
2. 在線初始化各個微服務數據源
3. 在線初始化各個租戶的數據庫建表腳本和初始數據
4. 每個租戶的數據源失敗重連
5. 數據源鏈接情況查看
6. 租戶擁有的應用授權、續期、查看
7. 租戶擁有的租戶管理員綁定、解綁、查看
- 應用體系
? 平臺級的SAAS系統,往往擁有多個`自建應用`或`第三方應用`,在`應用管理` ->`應用維護` 中創建好`自建應用`,配置好應用的資源,然后給企業授予相應的應用權限后, 用戶即可切換到對應的應用,并使用應用下的功能。 對于`第三方應用` 經過簡單的單點登錄對接,即可實現單點登錄。
? 同時,給企業授權應用時,還支持給不同的企業授權不同的資源,即對于同一個應用,不同的租戶可以擁有不同的功能(菜單)。
- 用戶體系
? 3.x 系統中,一個用戶,若同時屬于多個租戶,必須創建多個賬號。
? 4.x 用戶體系,使用身份證(或其他唯一標識)作為用戶的唯一標識,當你屬于多個租戶時,用戶在登錄系統后,可以切換自己的身份,即可操作不同租戶的數據。而每個租戶通過員工表和全局用戶表做好映射。
- 員工體系
- 每個員工可以有多個部門,并設置主部門
- 可以給部門分配一個部門的角色,部門下的員工擁有部門角色的權限
- 可以給員工分配角色
- 也可以在角色界面綁定員工
## 七. 分層
3.x 應用分層采用 Controller -> Service -> Mapper ,領域模型采用DTO、Entity。
> 3.x 的分層是最簡單,最易于理解的分層,但隨著不斷的出現復雜的業務,所有邏輯都放在Service層已經不在合適,故而對其改造。但3.x和4.x的分層,并沒有絕對的誰好誰壞,對于業務極其簡單,只為快速交付的項目,3.x的分層更加便捷;而4.x的分層更適合于長期迭代、業務復雜、對接第三方的系統。
4.x 應用分層采用 Controller -> Biz -> Service -> Manager -> Mapper ,領域模式采用VO、DTO、Query、Entity等。
1. 應用分層 (借鑒阿里規范,調整成適合本項目的分層模型)
圖中默認上層依賴于下層,箭頭關系表示可直接依賴,如:開放接口層可以依賴于
Controller 層,也可以直接依賴于 Biz、Service 層,依此類推。

- 開放接口層:開放給其他第三方調用的接口,可直接封裝Service方法暴露成PRC接口;通過Web封裝成HTTP接口等
- 終端顯示層:各個端的默認渲染層。如:模板引擎渲染、移動端展示、Vue展示等
- 請求處理層(Controller):主要是對訪問控制進行轉發,各類基本參數校驗,或者不復用的業務簡單處理等 。
- 分布式事務業務邏輯層(Biz)**(可選)**:具于分布式事務、跨庫操作(查詢和寫入)的業務邏輯服務層。若業務無分布式事務或跨庫操作Controller可以直接調用Service層,Biz層一定不能加`Transactional`注解,否則動態數據源跨庫操作將會時效。
- 業務邏輯層(Service):相對具體的業務邏輯服務層,只保證單個數據源本地事務。對多個Manager的組合復用。
- 通用處理層(Manager):通用業務處理層, 它有如下特征:
1) 對 Service 層通用能力的下沉,如緩存方案、中間件通用處理。
2) 與 DAO 層交互,對多個 DAO 的組合復用。
3) 繼承Mybatis-plus的ServiceImpl接口,封裝了單表的業務操作。
- 數據持久層(Mapper/Dao):數據訪問層,與底層 MySQL、Oracle、Hbase、OB 等進行數據交互。
- 緩存或第三方接口:包括其它部門 RPC 開放接口,基礎平臺,其它公司的 HTTP 接口。
> 1. biz的方法都是跨數據源或跨服務的且需要保證事務的;service的save方法更加貼切實際業務,可操作多個表,并組合邏輯;manager 的save方法只負責單個表的保存操作(可以對字段進行一些默認值設置), mapper 的insert 方法只負責原封不動的插入數據庫。
> 2. 調用只能從上往下,不能反著調用,最好也不要平層調用,嚴禁平層交叉調用。
2. 領域模型
- Entity: 跟數據庫表一一對應
- DTO:數據傳輸對象,Service或Manager 使用的對象
- Query:數據查詢對象,各層接收上層的查詢請求。建議超過3個參數的查詢進行封裝。
- VO:顯示層對象,Controller層接收和返回參數。
## 八、請求頭
3.x 版本,系統每次請求攜帶的請求頭為:
- Authorization: Basic {Base64加密的客戶端id和密碼}
- tenant: {Base64加密的租戶編碼}
- token: Bearer {JWT 生成的token}
4.x 版本,系統每次請求攜帶的請求頭為:
- Authorization: {Base64加密的客戶端id和密碼}
- TenantId: {雪花算法生成的租戶ID}
- Token: {JWT 生成的token}
- ApplicationId: {雪花算法生成的應用ID}
區別:
1. Authorization的值去除了Basic前綴。
2. tenant(加密租戶編碼)變更為TenantId(雪花租戶ID)。
3. token變更為Token,并將值除去了Bearer前綴。
4. 新增了ApplicationId(雪花應用ID),用于記錄請求來自那個應用。
調整理由: 方便新手入門成本、降低出錯率、降低系統復雜度。Base64加密無加密意義,還徒增項目的復雜度。
> 有朋友可能覺得不加密不安全,可以自行思考如何進行安全的加密傳輸。
>
> 1. 可以使用 https 協議
> 2. 請求頭明文參數不安全,普通的參數明文傳輸就安全了嗎?請求頭要加密,普通參數也要想辦法加密。
> 3. 3.x版本使用Base64加密請求頭基本無意義,因為直接Base64解密即可。
## 九、權限配置、分配和鑒權
名詞解釋:
1. 配置:通過系統的數據庫或UI,為需要**鑒權**的配置全局唯一的**資源編碼[^1]**。
2. 分配:先給角色綁定**資源[^2]**,在將角色分配給用戶[^3](或給用戶綁定角色)
3. 鑒權:鑒定用戶是否擁有訪問某些**資源**的權限
[^1]: 資源編碼:確定資源的唯一編碼,全系統不能重復
[^2]: 資源:3.x 的菜單表(c_menu) + 資源表(c_resource) = 4.x的資源表(def_resource) + 資源接口表(def_resource_api),4.x的資源包括:菜單、視圖(隱藏的菜單)、按鈕、URI(API)、字段等,你要你想通過權限來控制不同的人看到或訪問不同的東西,它都可以稱作資源。(注意區分通過業務狀態控制顯示/隱藏和通過權限控制顯示/隱藏的區別!)
[^3]: 用戶:3.x沒有用戶和員工的概念;4.x一個用戶可以屬于多企業,在不同的企業擁有不同的員工身份。
| 異同點 | 3.x | 4.x |
| ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 在那配置資源? | 系統管理 -> 菜單管理 | 開發運營系統 -> 應用管理 -> 資源維護 |
| 在那分配權限? | 系統管理 -> 角色管理 | 1. 基礎平臺 -> 系統功能 -> 角色權限維護<br/>2. 用戶中心 -> 員工維護 |
| URI權限在那鑒權? | 后端服務AOP攔截鑒權 | 網關統一攔截URI請求鑒權 |
| 按鈕權限在那鑒權? | 自定義指令 | 自定義指令 或 filter方式 |
| 菜單權限在那鑒權? | 后端控制菜單數據! | 后端控制菜單數據! |
| 字段權限在那鑒權? | 不支持 | 自定義指令 或 filter方式 |
| 表結構 | c_menu + c_resource | def_resource + def_resource_api |
| 表所在數據庫 | 租戶庫 (lamp_base_{租戶編碼}) | 默認庫(lamp_defaults) |
| 缺點 | 1. 每個租戶都需要維護一份相同的資源數據,且不能讓租戶自己修改。<br/> 2. 每次調整資源數據,需要更新所有的租戶庫。 | 需要跨庫查詢。 |
| 優點 | 查詢方便 | 資源表全局唯一,僅由開發者維護,不易出錯。 |
## 十、分布式事務
3.x 沒有主動在業務上使用分布式事務,二次開發時可以根據你們自身需求來決定是否使用seata。
4.x 的業務發生了巨大的變化,為了使得流程更加貼合實際,所以DATASOURCE、DATASOURCE_COLUMN模式必須使用seata!介意使用分布式事務的可以根據情況等待COLUMN模式發布。
- 簡介
- 會員版
- 3.x和4.x的區別
- 新手必讀
- 如何高效提問
- 項目地址
- 項目截圖
- 架構介紹
- 開發規范
- 租戶模式介紹
- lamp-web和lamp-web-plus的區別
- lamp-cloud和lamp-boot區別
- 免費視頻&軟件下載
- 文檔反饋
- lamp-cloud
- 服務介紹
- 環境要求
- 工程導入
- nacos啟動(單機版)
- nacos啟動(集群版)
- 將配置文件導入Nacos
- seata啟動(單機版)
- DATASOURCE模式啟動(會員版)
- SCHEMA模式啟動
- COLUMN模式
- NONE模式
- lamp-web啟動
- lamp-web生產部署
- lamp-web-plus啟動(會員版)
- lamp-web-plus生產部署
- lamp-boot
- 環境要求
- 工程導入
- DATASOURCE模式啟動(會員版)
- SCHEMA模式啟動
- COLUMN模式啟動
- NONE模式啟動
- lamp-web啟動
- lamp-web生產部署
- lamp-web-plus啟動(會員版)
- lamp-web-plus生產部署
- 功能介紹
- 租戶設置
- 數據源配置(會員版)
- 租戶管理
- 超級用戶
- 工作臺
- 通知公告
- 組織管理
- 機構管理
- 崗位管理
- 用戶管理
- 資源中心
- 消息中心
- 短息模版
- 短信中心
- 附件管理
- 流程管理
- 流程部署
- 模型管理
- 系統設置
- 菜單管理
- 角色管理
- 字典管理
- 地區管理
- 參數管理
- 操作日志
- 登錄日志
- 在線用戶
- 應用管理
- 網關管理
- 限流規則
- 組織訪問
- 開發者管理
- 定時任務
- 接口文檔
- Nacos
- 服務監控
- 數據庫監控
- 緩存監控
- zipkin監控
- SkyWalking監控
- 常用配置
- 如何保證我的代碼能更新到最新代碼
- 序列化和反序列化
- 修改日志級別
- 文件上傳&下載&預覽
- 修改租戶模式
- 分頁
- 導入導出
- 請求放行(忽略token&忽略URI權限&忽略租戶編碼)
- 異常處理
- 全局返回
- 參數校驗(會員版)
- 系統日志
- 自研權限認證(URI、按鈕、菜單)
- 數據權限(舊)
- 數據庫配置
- Mybatis配置
- 更多數據庫/數據源/Mybaits配置
- Redis(緩存)配置
- RabbitMq配置
- 灰度發布
- 上手開發
- 表結構整理
- 項目結構&依賴&調用流程介紹
- 生成一個新服務
- 生成后端代碼
- 生成前端lamp-web代碼
- 生成前端項目lamp-web-plus代碼
- 跨域處理
- Swagger文檔調試技巧
- FeignClient接口調用
- 多租戶實現原理
- 分布式事務
- Zipkin配置(過時)
- SkyWalking配置
- 代碼生成器和自動回顯組件使用介紹
- lamp-util原理解析
- 全局注解(lamp-annotation)
- 核心包(lamp-core)
- 自動回顯(lamp-echo-starter)
- 權限控制(lamp-security-starter)
- 當前登錄用戶信息(lamp-jwt-starter)
- 緩存(lamp-cache-starter)
- SpringBoot全局配置(lamp-boot-util)
- SpringCloud全局配置(lamp-cloud-starter)
- 數據源&持久層配置(lamp-databases)
- 對象屬性復制(lamp-dozer-starter)
- 操作日志(lamp-log-starter)
- 消息隊列(lamp-mq-starter)
- 在線文檔(lamp-swagger2-starter)
- 前后端表單統一驗證(lamp-validator-starter)
- 防止Xss攻擊(lamp-xss-starter)
- 生產部署
- 部署前言
- jar部署