框架說明
該框架是本人學習過程中本著只有自己動手操作一遍才能真正理解,和遇到對應問題並解決問題的思路。和為了能在開發相應系統時能快速搭建出相關框架而做出的基於NetCore3.1+Vue的RBAC通用許可權框架。
只有在敲的過程中才能遇見細節上的問題,成長無非就是發現問題、思考問題、解決問題、總結沉澱,後面才能去規避和提高程式碼質量。
如有發現什麼錯誤,請聯絡我,將第一時間改正。互相學習,共同進步。
不要只光看,最終要的是要自己敲,不自己敲的話,當遇到了還是不會、一臉懵的!
前端測試地址 lion.levy.net.cn , 可以自己註冊,也可使用已有賬號密碼登入。請不要用已有賬號修改或刪除系統已有資料,謝謝配合
前端程式碼地址 Gitee GitHub
後端介面地址 lion.levy.net.cn
後端程式碼地址 Gitee GitHub
** 如果您覺得對您有幫助的話,可以給個start,謝謝 **
專案框架圖
EntityFrameworkCore CodeFirist開發 支援 MySql/SqlServer
資料遷移時自動生成種子資料,Quartz 表結構還請自行通過docs檔案中對應資料庫型別檔案,執行新增表語句
非同步 async/await 開發
採用類似倉儲模式開發,封裝底層常用資料庫方法
Nlog日誌記錄,可記錄請求日誌/異常日誌等,除錯階段列印SQL語句
支援AOP切面程式設計,如日誌、快取、事務處理等
許可權管理系統支援多租戶多許可權管理,頁面動態管理頁面&按鈕許可權
採用自定義JWT身份認證,可自帶引數,驗證過期時間,滑動無感重新頒發Token
支援Redis 和 Memory 兩種快取
使用三方DI AutoFac,實行批量註冊,支援屬性注入
採用Automapper做物件對映,並支援擴充套件方法直接對映。
使用 Quartz.net做任務排程,支援叢集排程(未測試該情況,程式碼中有註釋說明),支援反射呼叫本地程式集方式,支援呼叫API方式
使用Swagger提供API文件,並實現介面文件中填寫授權資訊方便除錯。
支援CORS跨域,當前使用的是全跨域模式。
支援監控心跳檢查HealthChecks,可實現對其它網頁或服務的檢查和通知。(程式碼沒寫,如需要,可聯絡我獲取。通知支援釘釘和企業微信等)
支援RabbitMq訊息佇列,實現了死信佇列和延遲佇列。
支援docker部署,支援docker中部署同一網段
可配合Jenkins加 Sonar 做CI/CD & 程式碼質量檢查
Nginx可配置實現負載均衡
可配置 IpRateLimiting 做API限流處理(此前配置試過,沒有起到效果,可能哪個地方衝突了),若需要,也可根據redis實現一個簡易版的
多租戶許可權設計表
詳細說明
Deleted、CreatedTime、CreatedBy、UpdatedTime、UpdatedBy 為常用表預設欄位,可自行擴充套件增加Remark、Status、Sort等為表通用欄位。特別說明,若資料量很大的表,可將非關鍵欄位拆分出來,減小表大小,提高查詢速度。
- 資料都是按頁存在,頁儲存空間有限,將非關鍵資訊存另外的一個表,關鍵資訊表所存資料頁就少,查詢速度就相應的提高了。 個人理解
Sys_Tenant租戶表
- 租戶相當於是將系統租給某個公司使用,租戶表管理公司企業資訊,這裡表結構只是給了一個示例。
- 若有什麼想要控制,就設計成相應的表,若資料資源固定則設計為字典表。
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
TenantId | 主鍵 | bigint | TRUE |
TenantName | 租戶名稱 | nvarchar(50) | |
Remark | 備註 | nvarchar(32) | |
State | 狀態:1-啟用;-1-禁用 | int | |
CreatedTime | 建立時間 | datetime |
sys_user使用者表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
UserId | 主鍵 | bigint | TRUE |
TenantId | 租戶ID | bigint | |
NickName | 使用者名稱 | nvarchar(30) | |
PassWord | 密碼 | nvarchar(512) | |
nvarchar(128) | |||
Sex | 性別:0-女;1-男 | int | |
State | 狀態:1-啟用;-1-禁用 | int | |
CreatedTime | 建立時間 | datetime | |
CreatedBy | 建立人 | bigint | |
UpdatedTime | 修改時間 | datetime | |
UpdatedBy | 修改人 | bigint |
Sys_Role角色表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
RoleId | 主鍵 | bigint | TRUE |
TenantId | 租戶ID | bigint | |
RoleName | 角色名稱 | nvarchar(25) | |
RoleDesc | 角色描述 | nvarchar(128) | |
Deleted | 邏輯刪除標誌 | tinyint | |
CreatedTime | 建立時間 | datetime | |
CreatedBy | 建立人 | bigint | |
UpdatedTime | 修改時間 | datetime | |
UpdatedBy | 修改人 | bigint |
Sys_User_Role_Relation使用者角色關係表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
UserId | 使用者ID | bigint | TRUE |
RoleId | 角色Id | bigint | TRUE |
TenantId | 租戶ID | bigint | TRUE |
State | 狀態:1-啟用;-1-禁用 | int | |
Deleted | 邏輯刪除標誌 | tinyint | |
CreatedTime | 建立時間 | datetime | |
CreatedBy | 建立人 | bigint | |
UpdatedTime | 修改時間 | datetime | |
UpdatedBy | 修改人 | bigint |
Sys_Menu許可權資源表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
MenuId | 主鍵,自定義 | nvarchar(40) | TRUE |
MenuName | 資源名稱 | nvarchar(64) | |
ParentMenuId | 父級Id--無限級選單(長度加大) | nvarchar(40) | |
Level | 選單層級 | int | |
Url | 資源地址 | nvarchar(256) | |
Type | 資源型別:1:選單 2:按鈕 | int | |
Icon | 圖示 | nvarchar(128) | |
OrderIndex | 順序 | int | |
Deleted | 邏輯刪除標誌 | tinyint | |
CreatedTime | 建立時間 | datetime | |
CreatedBy | 建立人 | bigint | |
UpdatedTime | 修改時間 | datetime | |
UpdatedBy | 修改人 | bigint |
Sys_Role_Menu_Relation角色資源關係表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
MenuId | 資源ID | nvarchar(40) | TRUE |
RoleId | 角色Id | bigint | TRUE |
TenantId | 租戶ID | bigint | TRUE |
State | 狀態:1-啟用;-1-禁用 | int | |
Deleted | 邏輯刪除標誌 | tinyint | |
CreatedTime | 建立時間 | datetime | |
CreatedBy | 建立人 | bigint | |
UpdatedTime | 修改時間 | datetime | |
UpdatedBy | 修改人 | bigint |
- 排程相關-額外建立的管理表
Sys_Quartz排程任務綜合表
欄位名 | 說明 | 型別 | 主鍵 |
---|---|---|---|
JobGroup | 任務分組 | nvarchar(200) | TRUE |
JobName | 任務名稱 | nvarchar(200) | TRUE |
JobType | 任務型別:0-無,1-api,2-程式集 | int | |
BeginTime | 開始時間 | datetime | |
EndTime | 結束時間 | datetime | |
Cron | Cron表示式 | nvarchar(40) | |
RunTimes | 執行次數 | int | |
IntervalSecond | 迴圈次數 | int | |
TriggerType | 任務型別:0-無,1-cron,2-簡單型別 | int | |
RequestPath | API地址或請求類程式集名稱 | nvarchar(56) | |
RequestMethod | API請求型別或請求類地址 | nvarchar(40) | |
RequestParameters | 請求Body引數 | nvarchar(512) | |
Headers | 請求頭引數 | nvarchar(256) | |
Priority | 執行優先順序,等級越高,相同時間先執行 | int | |
Description | 任務描述 | nvarchar(256) | |
NotifyEmail | 通知郵箱 | nvarchar(128) | |
MailMessage | 郵件通知型別:0-不通知,1-錯誤通知,2-全量通知 | int | |
TriggerState | 暫停 錯誤 阻塞 完成 等 | int | |
PreviousFireTime | 上次執行時間 | datetime | |
NextFireTime | 下次執行時間 | datetime | |
CreatedTime | 建立時間 | datetime |
效果圖
當使用者註冊使用,便是一個租戶,租戶也就代表是一個公司群體,可以以該賬號建立子賬號,給子賬號分配頁面及按鈕許可權。
介面文件
使用者介面
角色管理介面
系統管理選單介面
排程任務介面
排程-介面及cron介面
排程-程式集反射方式建立介面
排程日誌介面
後端拉取執行
-
需配置
appsettings.json
中的相關資訊 配置郵箱傳送人資訊,本專案配置的是QQ郵箱,請根據需要配置,用以註冊和找回密碼的簡訊傳送 -
需配置
appsettings.json
中的相關資訊 配置資料庫連結資訊,執行資料庫遷移命令(檢視第7點),執行完成後,根據doc檔案中選擇Quartz
對應資料庫指令碼語言建立相關表。 -
配置NLog.config檔案資料庫相關資訊,用於記錄日誌,根據使用資料庫選擇相應連結,並配置資料庫連結
-
需配置
appsettings.json
中的相關資訊Redis
連結資訊 -
需配置
appsettings.json
中的相關資訊RabbitMQ
連結資訊 -
需配置
appsettings.json
中的相關資訊Redis
連結資訊 -
在
LionFrame.Data
專案中有個種子資料資料夾,在資料遷移時會新增相關資訊
前端專案請參考 前端系列
在部落格中之前已經寫過前端系列,可參考下,有不清楚的地方可在個人簡介中找到我的聯絡方式。若有什麼錯誤的地方也歡迎指正~
釋出到docker中
可參考專案中的docs資料夾下的 同一網路部署到Docker中 檔案。因為我這邊redis和mysql已經在之前就已經建立過了,所以此次只做了 MQ和專案釋出到同一網段中,其它的可如法炮製。喜歡玩的也可以使用docker-compose
來進行編寫第一次的釋出指令碼,因為多環境的問題,建議使用docker-compose
,可快速的進行部署,也可避免命令敲錯等情況。
只有初次釋出時配置可能比較麻煩,後面基本就只有專案需要多次釋出,可引入jenkins 做 CI/CD,基本支援中小企業使用
若專案做的比較大可升級K8S,做彈性伸縮,nginx做負載均衡等等、
前端專案這裡由於是騰訊雲的學生伺服器,比較卡頓,故申請了一個騰訊雲的免費6個月的儲存桶COS進行釋出前端專案。
netcore3.1 釋出到docker中所遇到的坑及解決
由於docker中沒有圖片的依賴元件,在我們生成二維碼的時候的時候需要使用到System.Drawing.Common
來使用 Image、Bitmap 等型別,通過docker logs 可檢視到如下異常
System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libgdiplus': The specified module could not be found.
解決方法,在dockerfile
中加上如下語句RUN apt-get update && apt-get install -y libgdiplus
由於國內網路原因,此處可能需要下載數十分鐘,為了提高資料,可在dockerfile
中加上RUN cp sources.list /etc/apt/
一句話,使用映象源,來提高下載速度,sources.list
檔案在docs資料夾中有提供。
這樣就能解決圖片的問題
ps:小插曲,其實最開始我在這樣處理後還是不能生成圖片、日誌中也看不到錯誤,只知道容器在呼叫二維碼生成介面時就會退出,起先還以為是dockerfile引入有問題,
在各大網站查詢相關訊息,部落格園/csdn/stackoverflow/github等網站上查詢。
在這個網址上 https://github.com/dotnet/dotnet-docker/issues/618 看到人家都是這樣解決的,為啥我就不行
不禁陷入了沉思,突然想到可能是程式碼的問題,換了生成驗證碼的方式, 驚奇的發現可以了。有的時候得換一種思考的方式。