折騰一個(gè)月,從重構(gòu)到再次設(shè)計(jì),管理系統(tǒng)總算接入了權(quán)限
大家好,我是 Chocolate。
大概有一個(gè)多月沒有更新文章了,最近是有一點(diǎn)點(diǎn)懶散,另外一方面這段時(shí)間深圳疫情反復(fù),居家辦公了三周,剛開始得知居家的時(shí)候還是覺得挺不錯(cuò)的,但之后狀態(tài)感覺不是很好了,也希望疫情早點(diǎn)過去,在工作日還是在公司上班要好一點(diǎn),在家上班效率也不是很高,總是容易分心。
平時(shí)大家工作雖然線上交流居多,但有時(shí)候還是會(huì)走到工位上溝通一下,這居家了之后,線上交流也是一個(gè)問題,就拿這一個(gè)月做的權(quán)限管理系統(tǒng)來說吧。
在講之前,推薦一下 hearling 的公眾號(hào),里面會(huì)分享前端設(shè)計(jì)模式以及 leetcode 算法相關(guān),同時(shí)也是一位 up 主,關(guān)注一起變強(qiáng)不變禿!
分析一下需求
怎么說呢,這個(gè)管理系統(tǒng)差不多做了一年多了,老項(xiàng)目不斷地迭代,但之前產(chǎn)品設(shè)計(jì)的時(shí)候就沒有考慮今后引入權(quán)限,做的一些功能也相對(duì)比較分散,一般有什么需求了就會(huì)往上面疊加功能。所以導(dǎo)致這次強(qiáng)行接入權(quán)限前端的工作量巨大,路由、歷史數(shù)據(jù)處理、按鈕權(quán)限、頁面 tab 權(quán)限、下拉數(shù)據(jù)處理、引進(jìn)新版角色管理,人員與角色綁定,功能與權(quán)限綁定等等,這一個(gè)月下來,幾乎是把整體代碼邏輯都看了遍,然后這改改那改改。
前端 UI 框架
在這里還要提及的就是框架問題了,這個(gè)系統(tǒng)算是老一點(diǎn)的,之前的 UI 統(tǒng)一都使用 material-ui 來開發(fā)的,就谷歌提供的開源框架,后續(xù)在使用過程中發(fā)現(xiàn)有些交互還是不太舒服,風(fēng)格和國內(nèi)還是有一些差別,這個(gè)還是看主觀上吧,因此我們更換了新的 UI,那就是 and pro,之前還寫過一篇文章,閱讀量還是不錯(cuò)的。

從引入 antd pro 開始,我就開始了各種重構(gòu)的工作,在做的時(shí)候也梳理了一遍之前的交互邏輯,代碼量也在那會(huì)逐漸增多,責(zé)任也就相應(yīng)多了起來,畢竟線上出一些邏輯問題,還是會(huì)來找我。
按鈕權(quán)限問題
其實(shí) antd pro 已經(jīng)給了權(quán)限實(shí)現(xiàn)的方案,還提供了相關(guān) hook 使用,例子如下:
//?src/access.ts
export?default?function?(initialState)?{
??return?{
????canReadFoo:?true,
????canUpdateFoo:?()?=>?true,
????canDeleteFoo:?(data)?=>?data?.status?1,?//?按業(yè)務(wù)需求自己任意定義鑒權(quán)函數(shù)
??};
}
頁面內(nèi)的權(quán)限控制示例:
import?React?from?'react';
import?{?useAccess,?Access?}?from?'umi';
const?PageA?=?(props)?=>?{
??const?{?foo?}?=?props;
??const?access?=?useAccess();?//?access?實(shí)例的成員:?canReadFoo,?canUpdateFoo,?canDeleteFoo
??if?(access.canReadFoo)?{
????//?任意操作
??}
??return?(
????
??????Can?not?read?foo?content. }>
????????Foo?content.
??????
??????Can?not?update?foo. ????????Update?foo.
??????
??????
????????Delete?foo.
??????
????
??);
};
同時(shí),還提供了 hook,使用示例如下:
const?Button=()=>{
???const??access?=??useXX();
???//?權(quán)限處理
???return?
}
看起來還是挺香的,直接使用就好了,不過...
我們的系統(tǒng)之前并不完全是按照 antd pro 來做的,總之就是比較亂,于是借鑒了其中的思想,自己實(shí)現(xiàn)了一層 access 和 useAccess。

實(shí)際效果還是不錯(cuò),其中也可以滿足產(chǎn)品的各種需求,比如有些按鈕得加上 Tooltip 文字提示,有些按鈕需要隱藏,又或是置灰狀態(tài),當(dāng)然,還有 tab 頁的顯示與隱藏等等,所以能看出來產(chǎn)品的需求是真的多...
自己實(shí)現(xiàn)的方法當(dāng)然不是一下就可以了,也會(huì)在做的過程中發(fā)現(xiàn)需要一些判斷條件,但麻煩的是我們是兩套 UI 框架共存,所以得適配兩套框架的邏輯,因此會(huì)多一層判斷。
怎么說,感覺是技術(shù)選型上留下來的債,還是要還的。
設(shè)計(jì)評(píng)審環(huán)節(jié)
可能需要吐槽一點(diǎn)的就是這個(gè)吧,前端和后端都會(huì)有一些不足的部分,后端數(shù)據(jù)表結(jié)構(gòu)也存在問題,畢竟在之前其實(shí)都沒有考慮會(huì)接入權(quán)限這一說法,所以一些接口的命名規(guī)范就不統(tǒng)一,在之后的實(shí)際開發(fā)過程中,全甩給前端做處理了,實(shí)際工作量大大提升,而在本地聯(lián)調(diào)過程中,數(shù)據(jù)庫里數(shù)據(jù)幾乎都是空的,所以權(quán)限池里面的數(shù)據(jù)都是我手動(dòng)一個(gè)一個(gè)加的,這個(gè)花費(fèi)了大量的時(shí)間。
當(dāng)時(shí)我就和導(dǎo)師商量了一番,這個(gè)接口綁定權(quán)限的后端就能做吧,當(dāng)時(shí)得到的回復(fù)就是后端數(shù)據(jù)表結(jié)構(gòu)比較亂,還要輸入對(duì)應(yīng)權(quán)限名稱啥的,處理就會(huì)比較麻煩,害...
于是,大概在家弄了一周時(shí)間,兩個(gè)人才把最后的綁定關(guān)系理清楚,將對(duì)應(yīng)的權(quán)限樹繪制了出來。
大概開發(fā)了兩周之后,關(guān)于權(quán)限與功能管理的菜單頁面做好了之后,后端的任務(wù)也就做完了,實(shí)際上就多一些新增頁面的增刪改查,后續(xù)權(quán)限的處理前端的工作量很大,于是在后兩周的時(shí)間,后端基本上沒啥事干了。
測(cè)試通過環(huán)節(jié)
在我開始寫這篇文章的那一天,我把測(cè)試發(fā)現(xiàn)的所有前端缺陷都修復(fù)了,測(cè)試同學(xué)也是看了好幾天,期間發(fā)現(xiàn)一個(gè)問題我就立即去修復(fù),最后測(cè)試通過了所有的用例,這一瞬間就感覺之前的一些不快都沒了,總算是要把這個(gè)系統(tǒng)搞上線了,感覺這過去幾周默默改 bug 日子好像也還好。
測(cè)試通過之后,會(huì)有產(chǎn)品驗(yàn)收的環(huán)節(jié),這時(shí)候又發(fā)現(xiàn)了問題,因?yàn)楝F(xiàn)在權(quán)限的控制是與接口相關(guān)的,比如我的提交按鈕其實(shí)是與某個(gè) action 相關(guān)的,也就是后端 api 嘛,所以在某個(gè)菜單功能下面,放的是一行一行接口權(quán)限,而不是產(chǎn)品所期望的增刪改查權(quán)限。
簡(jiǎn)單來說在產(chǎn)品角度來看,有些權(quán)限看起來沒必要分開,查詢的就一個(gè)行了,這時(shí)候就出現(xiàn)分歧了,就在之前說的設(shè)計(jì)評(píng)審環(huán)節(jié)階段,后端接口不統(tǒng)一,全由前端來處理,總不能把不需要的權(quán)限全部放開吧?放開了之后我的按鈕權(quán)限到底是與那個(gè)接口綁定呢?
溝通處理
這個(gè)時(shí)候產(chǎn)品找了前端和后端,就覺得這個(gè)設(shè)計(jì)不太合理,接口不等于權(quán)限,認(rèn)為我們是站在開發(fā)的角度去設(shè)計(jì),而不是一個(gè)產(chǎn)品角度。
我導(dǎo)師感覺都不太愿意去探討了,后續(xù)我被拉過去看了下,當(dāng)時(shí)心里所想就是感覺討論了也沒啥結(jié)果,既然要接入權(quán)限,僅僅只是改動(dòng)前端,后端一些接口規(guī)范性不改動(dòng),確實(shí)很難達(dá)成一致。
就比如一個(gè)編輯框,可能會(huì)因?yàn)榈谝粋€(gè)下拉框的結(jié)果會(huì)請(qǐng)求不同的接口,請(qǐng)求路徑也不一致,這個(gè)其實(shí)可以做成一個(gè)接口就好了,也方便權(quán)限控制。
這時(shí),后端同事也發(fā)現(xiàn)了其中的問題,看起來也是要改造一些接口,但實(shí)際上應(yīng)該不會(huì)改動(dòng)很多,畢竟整個(gè)開發(fā)周期都快一個(gè)月了,之前一直沒改,現(xiàn)在突然改,又會(huì)拖很長(zhǎng)進(jìn)度,況且,后端邏輯改了,前端也得跟著改,前端頁面改了,測(cè)試的一些用例可能也要再測(cè)一遍,這樣就gg了。
最后處理方式
好在分析之后其實(shí)問題不是很大,就部分接口還是得合并一下,不是說權(quán)限和接口是一對(duì)一的,權(quán)限是一個(gè)大的整體,可能會(huì)有多個(gè)接口。
這里處理方式就是如果請(qǐng)求路徑前綴相同,可以采用通配符方式。其它不好處理的情況,這塊就不是我來做的了,由我的導(dǎo)師和后端同學(xué)溝通,后面看了下,采用綁定父權(quán)限來處理,這里后端同學(xué)和前端其實(shí)都做了一點(diǎn)妥協(xié),相互再加一點(diǎn)工作量。
不管怎樣,前端肯定是要改的,后端這回也跟著改動(dòng)了,沒辦法,不改不行了。
總結(jié)與回顧
在我寫完這篇文章的時(shí)候,基本上把問題解決差不多了,上線就等產(chǎn)品安排了,在這里總結(jié)一下這段開發(fā)歷程:
首先感悟就是一個(gè)好的系統(tǒng)或者說是產(chǎn)品都是需要精心打磨的,也不是說東西一下就能做的很好,就比如上線的功能當(dāng)時(shí)可能測(cè)的沒問題了,說不定哪天又會(huì)出點(diǎn)小 bug,這也很正常,有問題就去解決問題。
第二點(diǎn)就是代碼質(zhì)量問題,想必多少都會(huì)有人吐槽前人所寫的代碼,包括我自己有時(shí)候也會(huì)發(fā)現(xiàn)一些問題,點(diǎn)擊之后發(fā)現(xiàn)提交歷史是自己就哈哈大笑,實(shí)在是太菜了。
對(duì)比我剛來公司寫的代碼和現(xiàn)在寫的代碼還是有一定差別的,所以說代碼質(zhì)量是在不斷提升,但過去堆疊的問題還是會(huì)有,其實(shí)想想還好,至少?zèng)]遇到過定義一個(gè)函數(shù)為 f,然后一堆很簡(jiǎn)略的變量名,就那種只有當(dāng)事人自己看得懂的代碼,這個(gè)是我同學(xué)遇到過的??偟膩碚f,首先不管前人寫的代碼如何,至少在當(dāng)時(shí)是把需求給交付了,現(xiàn)在遇到了就去改一改,對(duì)自己也要提高要求,不給別人留坑。
第三點(diǎn),關(guān)于產(chǎn)品的原型設(shè)計(jì),我們知道互聯(lián)網(wǎng)員工其實(shí)流動(dòng)性還挺大的,尤其是在年后,今三銀四期間,跳槽的還挺多的,所以做這個(gè)系統(tǒng)原型設(shè)計(jì)的前產(chǎn)品可能早就離職了,當(dāng)時(shí)就是這樣設(shè)計(jì)的,而后來的設(shè)計(jì)又不太一樣,所以就會(huì)存在一些差距,這誰來解決呢?
當(dāng)然是我們開發(fā)了,所以這次的開發(fā)歷程中我們就經(jīng)歷了,猶記得剛開始接到這個(gè)大需求,開設(shè)計(jì)評(píng)審然后評(píng)估工作量和時(shí)間的時(shí)候,當(dāng)時(shí)還覺得這怎么要改這么多,都還不如重新開始做了。
現(xiàn)在回頭來看,其實(shí)也還好,把工作進(jìn)行細(xì)分,一塊一塊的解決好,最后發(fā)現(xiàn)做的還可以,在這個(gè)過程中我雖然不是核心人員,核心當(dāng)然還是我導(dǎo)師,還是比較感謝導(dǎo)師的設(shè)計(jì),許多一些難點(diǎn)都能想到一個(gè)好的解決方式,我也在這個(gè)過程中參與學(xué)習(xí)到了許多,或許也是以后跳槽找工作一個(gè)能說的點(diǎn)了。
非技術(shù)類文章,就當(dāng)個(gè)人記錄啦,內(nèi)容僅做參考。
我也在 B 站拍了一個(gè)視頻版,點(diǎn)擊【閱讀原文】,即可圍觀。

學(xué)如逆水行舟,不進(jìn)則退
你若喜歡,為小獅子點(diǎn)個(gè)【在看】哦~
