企业级自定义表单引擎解决方案(二)--架构及核心模块设计
先總體介紹一下大概的架構(gòu)和核心模塊設(shè)計。先上一張整體設(shè)計圖
概念還是有點多,有一些概念可能比較新,如果熟悉K2自定義表單,可能比較好理解一些。代碼地址:https://gitee.com/kuangqifu/sprite,或者QQ交流:523477776
對核心的一些功能模塊進行總體介紹如下(用.net core實現(xiàn),其他語言整體設(shè)計思路相差不大)
基礎(chǔ)設(shè)施:
自定義表單主要涉及到數(shù)據(jù)存儲,包括表單定義信息和真實的業(yè)務(wù)表存儲管理,可支持不同的數(shù)據(jù)庫存儲,Redis主要用在緩存更新通知上,Redis不存儲表單定義緩存
基礎(chǔ)組件:
表單基礎(chǔ)框架,.net core實現(xiàn),用Dapper做ORM存儲,封裝了UnitOfWork,另外還包括了模塊管理、租戶/應(yīng)用管理等基礎(chǔ)功能,不包括權(quán)限相關(guān)功能。
表單定義本地緩存:
表單定義信息對于自定義表單來說,訪問特別的頻繁,真實業(yè)務(wù)變更極少,需要不少的過濾查詢,如果存儲到Redis,涉及到頻繁的訪問以及數(shù)據(jù)過濾,對整體性能影響也比較大,所以這里考慮把表單定義信息存儲到每一個應(yīng)用程序內(nèi)存中,直接從內(nèi)存中訪問表單定義信息,表單定義信息改變時,通知所有應(yīng)用表單定義對應(yīng)的數(shù)據(jù)已經(jīng)更新,應(yīng)用程序讀取數(shù)據(jù)時,會從數(shù)據(jù)庫讀取最新的數(shù)據(jù)存儲到內(nèi)存中。表單定義信息還會存儲到瀏覽器Indexdb中,一條總的原則就是訪問自定義表單定義信息一定要快,就近獲取。
基礎(chǔ)數(shù)據(jù)本地緩存:
數(shù)據(jù)字典(用戶信息)也可以存儲到本地緩存,管理方式同表單定義本地緩存,數(shù)據(jù)字典變更極少,訪問大;業(yè)務(wù)表往往只存儲用戶Id,展示需要用戶名稱,所以也存儲到本地緩存中。
緩存變更通知:
修改了表單定義信息或者數(shù)據(jù)字典等,通過Redis通知所有應(yīng)用程序清空本地緩存,再次讀取數(shù)據(jù)時,應(yīng)用程序從數(shù)據(jù)庫或者接口讀取數(shù)據(jù)再填充到內(nèi)存中。如果檢測到Redis斷開連接,則直接從數(shù)據(jù)庫或者接口讀取數(shù)據(jù),待Redis恢復(fù),再從內(nèi)存讀取數(shù)據(jù)。Redis可由其他有發(fā)布訂閱中間件服務(wù)替換。
CurrentUser:
只提供接口定義,對接具體的框架實現(xiàn)具體的邏輯,比如框架使用Abp框架,則從Abp的ICurrentUser讀取用戶當(dāng)前用戶信息。
微服務(wù)調(diào)用組件:
暫時未遷移,見作者其他博客描述。
租戶/應(yīng)用配置管理:
對自定義表單數(shù)據(jù)在租戶和應(yīng)用級別進行隔離,以支持Saas服務(wù)。
Sprite Comon:
自定義表單公共組件/模塊
動態(tài)Sql:
自定義表單比較核心的內(nèi)容之一,所有對業(yè)務(wù)表的常規(guī)CRUD,都是通過動態(tài)拼接Sql語句完成以及動態(tài)參數(shù),這里面涉及到大量的JObject操作,也就是開發(fā)者用得比較多的Newtonsoft.Json組件部分內(nèi)容。
動態(tài)查詢條件:
對Sql的參數(shù)查詢,查詢條件定義為一棵查詢樹,然后根據(jù)樹完成Sql查詢條件Where子句的字符串拼接。
動態(tài)表達式:
也是一棵樹,每一個節(jié)點為一種函數(shù)或者取值,比如邏輯表達式、日期轉(zhuǎn)換函數(shù)、從方法獲取值、固定值等,根據(jù)根節(jié)點類型返回對應(yīng)動態(tài)值
表單規(guī)則:
自定義表單靈魂所在,有了表單規(guī)則定義,才能稱之為表單引擎,可定義視圖或者表單規(guī)則;
表單規(guī)則事件:
比如用戶列表視圖新增按鈕點擊事件,部門樹用戶列表表單部門樹視圖樹節(jié)點選中節(jié)點變化事件,用戶列表視圖彈出對話框保存事件等,可以是視圖/表單本身或者控件觸發(fā),也可以是子表單/子視圖本身或者控件觸發(fā)
表單規(guī)則執(zhí)行:
當(dāng)某一個規(guī)則定義的事件被觸發(fā),可定義執(zhí)行一系列執(zhí)行動作,比如"用戶列表視圖新增按鈕點擊事件"觸發(fā)時,定義執(zhí)行設(shè)置用戶列表選中部門參數(shù)、獲取用戶列表查詢參數(shù)定義、執(zhí)行后端獲取用戶分頁數(shù)據(jù)方法、將執(zhí)行結(jié)果傳遞給用戶列表等一系列動作。再比如"用戶列表視圖彈出對話框保存事件"事件觸發(fā),驗證用戶Item視圖、驗證通過
定義時和運行時驗證:
自定義表單不需要寫代碼,則驗證就顯得非常的重要了,定義時各個模型之前數(shù)據(jù)是否正確,規(guī)則定義是否正確,運行時參數(shù)等是否正確等
序列化:
表單定義存儲往往是結(jié)構(gòu)化的數(shù)據(jù),很多定義信息可能以字符串的方式存儲,但JS前端往往需要Json數(shù)據(jù),則需要進行序列化與反序列化操作。
Sprite Object:
自定義表單對象管理,包括對象、屬性、方法
Object管理:
Object管理與業(yè)務(wù)表需要完全同步,添加Object時,需要動態(tài)生成業(yè)務(wù)表的創(chuàng)建Sql語句,并在業(yè)務(wù)庫中創(chuàng)建具體業(yè)務(wù)表,業(yè)務(wù)表名稱與Object的Name字段對應(yīng),動態(tài)Sql是根據(jù)Object定義信息拼接Sql語句并在真實業(yè)務(wù)庫中執(zhí)行Sql語句。
Property管理:
Object定義表,Property定義字段,自定義表單定義一些審計相關(guān)的字段并進行維護,包括Creator,CreationTime,IsDeleted等
Method管理:
定義方法,可以是執(zhí)行Sql語句、調(diào)用微服務(wù)、反射調(diào)用,并包括方法能夠成功執(zhí)行的附加信息定義,并對執(zhí)行參數(shù)進行驗證,對業(yè)務(wù)表常規(guī)的操作已經(jīng)定義到了自定義表單中,比如Create,Update,Get,List,PageList,TreeList等,不需要格外定義方法
業(yè)務(wù)表管理:
對Object和Property的管理,同步更新業(yè)務(wù)表表結(jié)構(gòu),他們之間需要完全的對應(yīng)。
Sprite View and Form:
視圖管理:
自定義表單最小功能單元定義,比如用戶Item,用戶列表視圖,部門樹視圖等,抽離出Item視圖、列表視圖、樹視圖等各個單元視圖。
表單管理:
自定義表單視圖容器,表單不處理任何具體業(yè)務(wù),只是將各種視圖聚合起來統(tǒng)一管理,可以對視圖進行布局,可以定義規(guī)則在視圖與視圖之間傳遞數(shù)據(jù)等。
視圖/表單控件:
統(tǒng)一定義不同視圖/表單固定區(qū)域的控件,比如列表視圖查詢區(qū)域控件,列表功能控件,新增,刷新,批量刪除等,或者列表行控件等,再或者表單流程相關(guān)控制按鈕
視圖/表單Wrap管理:
視圖或者表單只定義自身需要的功能,但用到哪些地方自身是不知道的,比如用戶Item視圖放入用戶列表彈出框中,部門樹表單用Card布局等
視圖/表單行列管理:
按照Grid布局,定義常規(guī)的行列布局管理
子視圖/子表單:
表單列或者視圖列的內(nèi)容可以是子表單或者子視圖,運行時當(dāng)發(fā)現(xiàn)是子視圖或者子表單,則動態(tài)再加載配置的視圖或者表單。
視圖/表單版本管理:
視圖或者表單本身或者任何關(guān)聯(lián)數(shù)據(jù)改變,都會重新生成版本號,并通知所有應(yīng)用對應(yīng)緩存變更并刪除應(yīng)用本地緩存,瀏覽器每請求一個頁面,發(fā)現(xiàn)視圖或者表單版本號改變了也會更新瀏覽器本地存儲數(shù)據(jù)。
視圖/表單規(guī)則管理:
視圖和表單都可以定義自身規(guī)則,規(guī)則見上文描述。
宿主框架:
計劃將自定義表單宿主到Abp Vnext框架中,Abp框架負責(zé)登錄認證,用戶角色管理,菜單操作權(quán)限管理等,自定義表單公開Api供使用端調(diào)用,當(dāng)然,使用其他框架做為宿主也是一樣的。另外,工作流引擎這塊,之前是用WWF研發(fā)的一套產(chǎn)品,但是微軟沒有計劃將其遷移到.net core,基本就宣告了死刑,所以之前的文章也就停止了;流程引擎這塊后續(xù)是會重新編寫,流程引擎+表單引擎,這塊自定義表單最終的形態(tài),不過不都是后話了,自定義表單完全可以獨立存在。
前端(個人是做后端的,前端水平有限):
前端的復(fù)雜程度不亞于后端,很多東西是需要配合后端一起定義的,前端+后端,才能形成一個整體。
前端可以是不同的架構(gòu),不同的應(yīng)用,可以是瀏覽器,winform等,都是調(diào)用Api,這里選擇的是瀏覽器,技術(shù)選擇的是vue,框架選擇的是and design for vue
Ant Design for Vue:
使用此框架,可替換其他框架,但各個控件需要做相應(yīng)的修改。
視圖:
定義視圖Layout、Item、列表、Tree等視圖。
表單:
定義普通表單、Div表單等
Wrap管理:
對視圖或表單進行包裝,包括Div、對話框、Card布局等各種包裝。
視圖/表單控件:
對前端各種控件進行二次封裝,注入規(guī)則,允許觸發(fā)事件和執(zhí)行規(guī)則。
瀏覽器數(shù)據(jù)緩存:
比較核心的內(nèi)容,自定義表單內(nèi)容設(shè)計變更,需要即使的通知前端,同是自定義表單定義信息訪問又必須快速,不能有明顯的性能損失。IndexedDb存儲視圖/表單定義等信息,每次打開一個頁面時,遍歷所有關(guān)聯(lián)的視圖和表單Id和版本信息,與后端緩存數(shù)據(jù)進行比較,不同則更新本地緩存。
表單規(guī)則注冊與執(zhí)行:
前端靈魂所在,視圖、表單、控件在創(chuàng)建的時候,都會注入規(guī)則,用戶進行某個操作時,如果有對應(yīng)的事件定義,則找到規(guī)則定義,進而找到一系列視圖/表單/空間執(zhí)行一系列規(guī)定。
動態(tài)表達式:
為一棵樹,同后端動態(tài)表達式比較類似。
自定義功能:
自定義表單也不可能抽象出所有的數(shù)據(jù)模型,特殊的業(yè)務(wù)可編寫代碼,完全自定義功能實現(xiàn)。后端一些報表或者某些業(yè)務(wù)模塊,開發(fā)人員自己寫業(yè)務(wù)邏輯,通過微服務(wù)或者反射配置方法,執(zhí)行具體的自定義功能。前端則可編寫不同的自定義控件,并注冊到Vue框架中,自定義表單在某個功能上配置自定義控件名稱即可。
前端技術(shù)選型不要選擇angular,angular的動態(tài)控件比較死板,動態(tài)控件不能動態(tài)添加指令,還有其他很多限制,基本上斷了自定義表單的路了。
總結(jié)
以上是生活随笔為你收集整理的企业级自定义表单引擎解决方案(二)--架构及核心模块设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle函数->TRIM(去掉
- 下一篇: C#之判断字母大小、字母转ACII码