• <table id="5bpl0"></table>

    <td id="5bpl0"></td>
    <td id="5bpl0"><ruby id="5bpl0"></ruby></td>

    <bdo id="5bpl0"></bdo>

    當前位置:首頁 > 短網址資訊 > 正文內容

    權限申請審批流程設計

    摘要

    目前Do平臺下各類資源比較多(像任性、駕駛艙、烽火、數據集市等等),對應的各種角色也比較多,需要對do平臺的每個用戶進行權限控制。Do平臺功能權限申請之前都是通過發送郵件的方式提交申請,對于審批人來說,工作較為繁瑣,容易出錯。為方便審批人實現一鍵通過或者一鍵駁回的審批功能,同時也為使用戶權限申請的流程規范化,設計此權限申請產品。下面主要介紹權限申請中審批流程的設計。


    1. 業務流程介紹 


    下面是權限申請的業務流程圖:



    主要有以下幾個模塊:

    1)用戶提交申請:        

    用戶通過do平臺權限申請入口頁面提交申請,用戶可以根據自己的角色,選擇不同類型的申請(代理商、RD、非RD)。用戶提交的申請內容會以快照的方式保存,快照的方式便于申請內容需求擴展,同時減少前后端邏輯交互,減小開發交流成本。


    2)創建審批流程        

    用戶提交申請之后,會根據用戶提交的申請內容,動態的創建審批流程,后面內容會詳細介紹。


    3)審批人審批        

    審批人可以通過do平臺權限申請頁面(我的審批)、workflow、HI等三種方式進行審批。workflow是運維部提供的一個工作流服務,通過接入workflow,可以復用郵件提醒、HI審批等功能,豐富用戶體驗。如果審批人通過workflow、HI方式審批,我們無法立即得到該審批信息(因為workflow不會回調任何接口),所以我們通過CT任務的方式定時掃描申請單狀態信息,同步到自己系統。



    2. 審批流程設計


    審批流程如下:



    1)存儲設計       

    由于每個節點只有一個審批人,因此在設計工作流時,建了兩張mysql表:auth_apply(存儲用戶提交的申請,一條記錄代表一個申請)、auth_approve(存儲審批流程,一條記錄代表一個審批節點,auth_apply表中的一個申請對應該表中多個審批節點)。這樣的設計能夠完全滿足現有需求,但是這并不是一個標準的工作流設計(沒有考慮一個節點多個審批人情況),這也為后續功能擴展帶來了麻煩。


    2)代碼框架       

    由于代理商、RD、非RD申請大體的審批流程是一樣的,但是具體到審批流程的每一步可能又不一樣,為此采用“模板方法模式”來設計。



    Service_Data_ApplySave為抽象基類,模板方法createApplyAndApprove()給出了整個審批流程業務邏輯的骨架,包括一些列抽象操作:genAuditors()生成審批人(包括workflow的審批人)、createApplyWorkFlow()調用workflow接口生成申請單、saveApply()保存申請內容、createApprove()創建本地審批流。Service_Data_AgentApplySave、Service_Data_NordApplySave、Service_Data_RdApplySave等各子類實現相應的抽象方法即可。


    3)接入workflow      

    由于workflow在創建審批流程時,必須提前配置好流程模板,而且不同類型的審批流程需要創建不同的流程模板,所以需要根據業務邏輯推斷可能出現的審批流程情況,提前手動創建好流程模板(這種方式極不靈活,也促使后續迭代想辦法盡量減少創建流程模板的操作)。


    3. 審批流程功能迭代


    權限申請產品到現在為止經歷了兩次迭代,而這兩次迭代都對代碼進行了重構。


    3.1 迭代1.0


    1)需求:

    1. 在最終審批人中增加多個人審批, 有其中一人審批通過并授權即可

    2. 如果申請的ad-hoc表中,有托管庫中的表,需要將托管表的所有人的上級加入到審批流程


    2)需求分析:

    要滿足上面兩個需求,就必須實現一個節點支持多個審批人,同時節點也要區分操作方式(“與”和“或”,“與”表示該節點所有人都通過,則該節點通過;“或”表示該節點任意一人通過,則該節點通過)。


    3)設計方案:       

    對審批流程進行了簡單的重構:增加auth_approve_user表(用于存儲每個節點的審批人,一條記錄對應一個審批人,一個節點可能對應多條記錄),同時auth_approve表增加mode字段,用于判斷該節點操作方式。由于增加了一張mysql表,為了兼容老的數據(用戶已經提交的單子),就必須在新代碼上線前將老的數據按一定的邏輯導入新表中,為了保證導入老數據后,在代碼上線前不再有新數據進入,就必須讓線上服務在這個上線過程中(導入老數據、代碼上線)不可用,這就是上文所說的“麻煩”,不過這個“麻煩”可以接受,因此沒有專門去開發平滑遷移的方案。


    由于需求2需要在審批流程增加一個節點,該節點是“與”操作節點,workflow不支持動態添加審批人,因此必須去修改流程模板。這里就涉及到并發問題(在創建審批流程時,不能同時有多個進程修改該“與”節點審批人),為此增加了鎖機制(下文介紹實現方法),來避免這種并發問題。

          

    抽象類Service_Data_ApplySave增加獲取鎖和釋放鎖的方法(使用redis來標記某個流程模板是否正在被修改),Service_Data_RdApplySave類增加相關業務方法,如下圖:



    4)redis實現鎖機制方法:

          

    1.進程A獲取鎖:$get = hincrby($key, $processId, 1); 如果$get等于1,則A成功獲取鎖,A操作完畢后釋放鎖:$get = hincrby($key, $processId, -1);;

          

    2.進程B獲取鎖:$get = hincrby($key, $processId, 1); 發現$get大于1,說明鎖已被占用,B獲取鎖失敗,同時進行回滾操作:$get = hincrby($key, $processId, -1);

          

    3.進程B每隔一段時間重新進行獲取鎖的操作,直到成功獲取。


    該鎖機制實現方法比較簡單,強依賴redis服務,其他優缺點就不在此討論了。



    3.2 迭代2.0


    1)需求:

    1.特殊審批流程增加VP審批節點

    2.審批委托功能:A可委托B幫其審批


    2)需求分析:       

    上面兩個需求都要增加workflow流程模板,同時修改相關代碼。我們已經根據之前的需求增加了很多個workflow流程模板了,而這次的需求又要增加流程模板??梢钥吹?,由于接入workflow的方式極不靈活,當涉及到流程修改時,都要大篇幅的修改代碼邏輯,導致開發成本比較高。


    3)設計方案:       

    通過如上分析,決定在這次迭代時,對創建審批流程的代碼進行底層的重構,通過這次重構,希望能夠在以后功能擴展時,盡量減少創建workflow流程模板的操作,盡量只增加業務代碼而不是修改與workflow相關的代碼甚至底層邏輯。重構后的代碼框架如下:



    此次重構主要是對創建審批流程進行細化、解耦(與接入workflow解耦),主要思想就是通過將流程步驟細化,將接入workflow從業務邏輯拆解出來,從而達到解耦目的,如下圖所示:




    將genAuditors()方法拆解成genMyAuditors()、ifModifyToOneState()、repaceProxyAuditor()、genWorkflowAuditors()、selectWorkflowTpl()等方法(圖中綠色),createApplyWorkFlow()方法拆解成getUpdateProcessLock()、updateWorkflowTplAuditors()、createApplyWorkFlow()、freeUpdateProcessLock()等方法(圖中藍色),其中紅色虛線框內的方法是生成審批人的步驟,黑色虛線框內的方法是接入workflow的步驟。


    重構后,添加workflow流程模板不在依賴業務邏輯,而是根據審批流程節點個數和類型(“與”和“或”)來添加模板,如下圖所示:



    4)重構后的優點:

          

    1.實現業務邏輯與接入workflow解耦        

    用戶提交的申請,可能是不同類型的(代理商、RD、非RD),也可能是特殊申請,還有可能涉及tuoguan庫表的申請等等,因此會有不同的業務邏輯來處理。重構前,是根據業務邏輯來選擇workflow的流程模板,這樣的話,生成審批人和接入workflow是耦合在一起的(重構前的genAuditors()里包含了生成workflow的審批人genWorkflowAuditors()和選擇workflow流程模板selectWorkflowTpl()),他們都是業務邏輯的一部分;重構后,根據業務邏輯來生成審批人,然后根據生成的審批人來選擇workflow的流程模板,這樣就把接入workflow從業務邏輯中拆分出來,從而實現解耦,如下圖所示。


     2.減小功能擴展及維護成本       

    實現接入workflow與業務邏輯解耦,會給以后審批流程功能修改帶來極大便利:只需關注業務邏輯變化,增加或修改生成審批人的邏輯,而不需要去修改接入workflow的邏輯,功能擴展更加靈活,從而減小新功能開發及維護成本。


    5)重構之后存在的缺點:

           

    1.性能影響     

    重構之后,每次接入workflow時,都要去修改選好的workflow流程模板的每個節點的審批人(因為一個流程模板可能被多個業務邏輯使用到),而這在重構前是不需要的(只需要修改部分模板部分節點審批人),這對性能是有影響的,不過考慮到“提交申請”接口的訪問量并不大,因此是可以接受的。

           

    2.額外增加鎖機制        

    為了避免兩個進程同時修改同一個workflow流程模板,就必須要額外去增加鎖機制解決并發問題(鎖機制同樣使用redis實現,方法同上)。


    4. 總結


    每一次功能迭代,如果都需要修改大量代碼,甚至大篇幅改動原有邏輯,那么就要考慮重構了。其實重構不只是在功能迭代時,當我們在開發過程中,發現部分功能修改需要很大開發及維護成本,這時也要考慮重構自己的代碼。當然,我們在產品開發中還是要盡量避免重構,畢竟重構是要開發成本的。因此在產品開發初期,要深入了解產品需求,與產品經理多交流,盡可能多的去預測未來產品需求變化,并為此做相關設計,從而減少后期重構。

    掃描二維碼推送至手機訪問。

    版權聲明:本文由短鏈接發布,如需轉載請注明出處。

    本文鏈接:http://www.virginiabusinesslawupdate.com/article_432.html

    分享給朋友:

    相關文章

    百度:我們不造車,Apollo只是人工智能的搬運工

    百度:我們不造車,Apollo只是人工智能的搬運工

    [ FT12短網址 ] 百度在Apollo生態中承擔的角色更像是供應商,但是與傳統零部件供應商不同的是,百度將不主要依賴于車企采購產品或技術的方式盈利,百度的盈利模式還有進一步的想象空間,而且在百度內部也還沒完全考慮成熟...

    賭博、自殺、精神?。篎T12短網址帶你揭秘重度電競玩家的真實生活

    英國《衛報》日前發表文章稱,全球成長速度最快的體育運動項目是什么?許多人可能會認為是足球。其實答案并不是它,而是電子競技。但越來越多的影響證明,電子競技對相關人員是有害的。以下為文章內容摘要:  如果過去的四分之一個世紀有人不在地球上,那么...

    百度牽手浪潮打造ABC一體機背后:要做未來的手機和筆電

    百度牽手浪潮打造ABC一體機背后:要做未來的手機和筆電

    [ FT12短網址 ] 9月26日下午,在NVIDIA GTC China大會上,浪潮人工智能與高性能產品部總經理劉軍與百度云事業部技術委員會主席張發恩接受了億歐等國內知名媒體采訪,首次揭開了ABC一體機背后的故事。前不久,百度云...

    用PHP代碼批量生成百度、新浪短網址,打造最炫的api接口

    看了幾個短網址API服務,于是把它們整理出來,方便以后使用,目前,提供靠譜的短網址API接口的公司不多(google、baidu、新浪微博、網易等),而像騰訊微博、淘寶這幾個巨子的短網址服務都是僅供內部使用.1 google、baidu、網...

    人人網,微博等網站在分享url的時候都會轉換成短鏈接,這樣有什么好處?

    比如 http://u6.gg/baidu【李卿的回答(9票)】:正如@sqybi 所說,初衷應該是微博類網站為了縮短字數,畢竟這些地方惜字如金。前幾位都說到了垃圾外鏈的問題,其實這個并不是大問題,是可以用nofollow屬性來處...

    FT12短網址:面對人工智能的飛速發展,我們更要保持頭腦清醒

    FT12短網址:面對人工智能的飛速發展,我們更要保持頭腦清醒

    [ FT12短網址 ] 人工智能的成功使用主要在以下方面:語音、圖畫辨認、電商/引薦、博弈、更深層次的對立網絡;人工智能在AlphaGo上的使用顯然成功了,但在教學、醫療范疇很難仿制;AI技術的風口在于深度學習?!揪幷甙?..

    發表評論

    訪客

    ◎歡迎參與討論,請在這里發表您的看法和觀點。
    一本色综合网久久
  • <table id="5bpl0"></table>

    <td id="5bpl0"></td>
    <td id="5bpl0"><ruby id="5bpl0"></ruby></td>

    <bdo id="5bpl0"></bdo>