小結:
1、
每一個表單都是一份各個組件組成的 JSON Schema,表單設計器的輸出是一份描述表單字段的 JSON Schema,表單設計完成后 JSON Schema 將被存儲到數據庫中。表單發布后,前端渲染器再根據 JSON Schema 渲染表單。表單中每一個組件對應 Schema 數組中的一個對象,該組件的所有字段的信息都是存儲在對象中,所以每次對表單的組件增刪都是增刪 JSON Schema 對應的對象 ,修改具體組件的屬性則是修改對應的對象。
流程開放平台表單引擎的設計與實現 https://mp.weixin.qq.com/s/axzWrLUgb8A4psEiWsZJ3Q
流程開放平台表單引擎的設計與實現
1
背景和業務痛點
58 的 OA 系統中存在上百個業務表單與審批流程,每個表單都需要單獨開發,而且每個表單上線之后,都經常出現與其他表單重復的小需求,這些問題導致了 OA 系統上線新表單及維護舊表單的效率非常低,大概每兩周只能上線一個業務表單或審批流程。因此,58 企業平台開始着手嘗試使用技術手段提高此類業務表單與審批流程的開發上線效率,解決這些重復的、有規律的表單頁面與審批流程的開發維護效率問題。低代碼、0 代碼平台是一種通過盡可能少的代碼就可以快速生成應用程序的開發平台。通過所見即所得的方式,使沒有技術背景的運營人員也可以使用拖拽組件和預設的流程模型來創建應用程序,避免讓研發團隊重復開發相似需求,提高業務表單與流程的研發效率。本篇文章主要介紹 58 流程開放平台中表單設計器和渲染器的設計與實現。
2
架構設計和模塊拆解
2.1 整體設計
流程開放平台面對的用戶主要分為兩類:配置表單用戶、使用表單用戶。
1)配置表單的用戶主要是產品運營或職能崗位的用戶。表單的配置信息可以由用戶在流程開放平台的表單設計器中編輯產生,也可以由第三方業務系統根據流程開放平台的協議自動化的構建出來。
2)填寫表單的用戶可以在集成了表單渲染器的頁面中填寫、提交、查看表單數據,並查看表單相應的審批流程信息。
每一個表單都是一份各個組件組成的 JSON Schema,表單設計器的輸出是一份描述表單字段的 JSON Schema,表單設計完成后 JSON Schema 將被存儲到數據庫中。表單發布后,前端渲染器再根據 JSON Schema 渲染表單。表單中每一個組件對應 Schema 數組中的一個對象,該組件的所有字段的信息都是存儲在對象中,所以每次對表單的組件增刪都是增刪 JSON Schema 對應的對象 ,修改具體組件的屬性則是修改對應的對象。借助表單設計器,不但將開發人員從應對業務變更的頻繁改動中解放出來,同時大大提高了非專業開發人的生產力,減少了溝通成本。
2.2 表單設計器
表單設計器的作用,主要是提供一個可視化界面,讓用戶能夠通過所見即所得的方式,快速編輯出可被解析渲染的 JSON Schema。在實際業務場景中,表單由多個用戶輸入類組件和基礎信息類組件組成,用戶輸入類組件包含多種形式:文本、數字、單選,多選,附件以及明細等。基礎信息類組件也有很多:姓名,工號,公司主體,銀行賬號,辦公地點等。Schema 中的對象除了需要描述組件類型外,還需要描述組件本身的行為,例如單選組件的下拉選項是手動添加,還是設置接口拉取;單行文本組件的值是由接口獲取,還是用戶填寫,是否必填,是否加密等。某些業務場景下還需要添加更加復雜的設置,比如各個組件之間有沒有內容聯動(用戶在一個組件中輸入了內容之后,是否需要自動地填充或修改另外一個組件的內容),有沒有顯隱聯動(一個組件的顯隱由另外一個或多個組件控制,用戶在一個組件中輸入了內容之后,是否需要自動地控制另一個組件顯示或隱藏)。有了這些描述后,表單渲染器才能根據 Schema 渲染出符合預期的表單。表單設計器為左中右三欄布局:左側是組件列表,列出了設計器支持的表單組件;中間部分是畫布,左側的組件可直接拖拽到畫布中,並支持組件調整順序、刪除操作;右側是表單字段的配置區域,在畫布中選中一個組件,右側將展示此字段的所有屬性,用戶可在此處設置字段標題、描述、排列方式等。

表單設計器可以從零開始,或者在已有的 JSON Schema 基礎上,編輯 JSON Schema 的內容,最后輸出 Schema。表單設計器的功能可以用下圖表示:

為了能夠讓運營人員快速編輯每個組件的配置,表單設計器中提供了組件配置區域,用戶無需關心前后端技術或 JSON Schema 的具體格式,表單設計器負責將用戶配置的結果轉化成 JSON Schema,同時也負責將 Schema 解析成設計器配置區域中的選項。
2.3 表單渲染器
表單渲染器是 58 流程開放平台的另一個核心模塊。負責解析 JSON Schema,並將其中定義的組件渲染到頁面中。相比傳統的表單開發模式,引入表單渲染器有以下優勢與劣勢:-優勢:1)研發環節減少,需要投入的人力、溝通成本減少,研發成本降低。2)表單需求變化時,無需前端修改發版,只需在表單設計器重新配置,生成新的 JSON,需求交付更快。-劣勢:1)需要加載多余的組件,性能相對而言更差。2)如果業務場景需要渲染器無法覆蓋的能力,比如組件交互邏輯過於靈活,則可能無法支持。

表單渲染器是如何把 JSON Schema 中的對象回顯成組件呢?我們采取的方法是遍歷 JSON Schema,根據其中每個組件描述中的類型定義,對應的從組件庫中找到組件,然后動態構建整個表單的布局、組件結構,並為每個組件添加相應的事件回調。
當我們從后端接口讀取 JSON 文件之后,表單渲染器會按照 Schema 協議加載和渲染該 JSON 的內容。那么,這個加載和渲染是怎樣的一個過程呢?如下圖所示:<template>
<el-row class="render-content">
<el-col
v-for="item in formConfig"
:key="item.name"
class="render-content-item-box"
:span="Number(item.attributes.width)"
>
<component :is="`${item.type}Form`" ref="formItem" :detail-index="index" :item="item" />
</el-col>
</el-row>
</template>
Schema 協議的設計
Schema 協議的格式非常重要,它必須簡單、易懂,這樣可以比較方便的由設計器輸出,而且要高效率、可擴展,這樣方便渲染器渲染,也更准確的表達頁面的所有信息。Schema協議的JSON格式由來
本平台設計的 JSON 格式整體上成樹型結構,每一個節點是一個對象,每個節點的屬性或功能被標記在對象的字段中,節點的共有屬性放在樹頂層的節點中,特殊屬性 visibileProps、contentProps 來描述聯動關系。而由於是樹型結構,通過 children 字段屬性指定子節點,所以理解起來也非常簡單。以一個請假申請單為例:

藍色框內頁面元素可以提取為基礎組件和明細容器類組件。每一個組件就是一個節點,是一個對象,對應的 JSON 節點格式就是:
[{
"name": "applicantName",
"type": "ApplicantName",
"label": "申請人",
"value": "",
}, {
"name": "applicantDept",
"type": "ApplicantDept",
"label": "申請人部門",
"value": "",
}, {
"name": "applicantJobNum",
"type": "ApplicantNum",
"label": "申請人工號",
"value": "",
}, {
"type": "Detail",
"label": "明細",
"name": "AsZJ1634892182751",
"value": "",
"children": [{
"type": "SingleSelect",
"label": "請加類型",
"value": "",
}, {
"type": "DateTimeRange",
"label": "日期區間",
"name": "nPiG1634892209750",
"value": "",
}],
}, {
"type": "MultiLine",
"label": "請假原因",
"name": "NnDD1634892259871",
"value": "",
}, {
"name": "KBTA1615274618115",
"label": "請假期間聯系方式",
"type": "SingleLine",
"value": "",
}]
設計節點基礎信息
針對具體的節點,選中節點的時候右邊顯示所有可以設置的屬性可以進行單獨設置。如下圖選中單選—請假類型所示:
props 對應的屬性就是該節點自己設置的獨有屬性
{
"type": "SingleSelect",
"label": "請加類型",
"title": "單選",
"name": "cnQu1634892188818",
"showDeleteIcon": false,
"value": "",
"props": {
"width": "12",
"optionsWarn": false,
"placeholder": "請選擇",
"helpUrl": "https://pan.58corp.com/oashare/1610166607390700",
"radioType": "0",
"options": [{
"value": "Yuyr1634883484964",
"label": "選項一",
"repeatKey": false
}],
"url": "https://xxx",
"token": "請輸入token",
"key": "",
"required": true,
"encrypt": false,
"emptyError": false,
"canChangeUrl": false,
"print": true
},
"key": "cXrV1634892188818"
}
設計節點聯動信息
其中聯動關系的設計也比較關鍵。普通的 JSON 是很難表達一些動態信息的。比如 A 節點是否顯示,是由 B 字段的值是否等於 10 來決定的。這一邏輯,在動態表單領域被稱為“顯隱聯動”。如果 A 節點的值是由 B 組件的值控制的,當 B 節點的值變化時,會調用接口返回A組件的值,這一邏輯,在動態表單領域被稱為“內容聯動”。如下圖所示請假類型由時長節點控制顯隱和內容:

我們的設計是把所有控制請假類型節點的信息都放在該節點的屬性上。分別為 visibileProps , contentProps。
綜上,就是 Schema 協議設計的全過程。{
"type": "SingleSelect",
"label": "請加類型",
"title": "單選",
"name": "cnQu1634892188818",
"showDeleteIcon": false,
"value": "",
"props": {
"width": "12",
"optionsWarn": false,
"placeholder": "請選擇",
"helpUrl": "https://pan.58corp.com/oashare/1610166607390700",
"radioType": "0",
"options": [{
"value": "Yuyr1634883484964",
"label": "選項一",
"repeatKey": false
}],
"url": "https://xxx",
"token": "請輸入token",
"key": "",
"required": true,
"encrypt": false,
"emptyError": false,
"canChangeUrl": false,
"print": true
},
"visibileProps": [
[{
"labelName": {
"value": "nPiG1634892209750",
"label": "時長",
"type": "DateTimeRange",
},
"condition": "==",
"labelValue": "10"
}]
],
"contentProps": {
"watchTools": [{
"label": "日期區間",
"value": "nPiG1634892209750",
"disabled": false
}],
"url": "https://test.com",
"token": "kkkktestsssss"
},
"key": "cXrV1634892188818",
}
3
階段成果
依靠低代碼拖拽生成表單,58 企業平台創建、修改表單的效率得到了大幅提升,需求積壓排隊等待時長明顯減少,需求的響應速度獲得了提升。
如上圖所示,零代碼平台相比傳統方式,表單業務的開發上線效率提升了 3 倍,同時降低了表單業務的技術門檻,過去需要研發同學寫代碼才能做到的事情,現在產品運營同學完全可以自己完成了。以 OA 系統為例,2021 年 1 月至 7 月,流程開放平台支撐了 100+ 個表單,覆蓋了 OA 系統中 80% 的表單,月辦結量 7W+ 單。流程開放平台支持除了支持通過后台設計器配置表單以外,還支持通過 API 提單,目前已支持了 OA 等 8 個業務系統。另外,在需要管理后台的業務場景中,也存在着許多類似的表單頁面前端需求。為了提高這類前端需求的開發效率,流程開放平台在自身的技術上進行了抽象封裝,開發了表單 SDK。相比以往從 0 開始搭建開發表單需求,基於表單 SDK 進行開發不需要編寫大量的頁面、樣式、交互相關的代碼,可以節省大量的開發時間。目前,流程開放平台的表單 SDK 已在 5 個項目中得到的應用。