c站(clicli.us)3.0 重構經驗分享

132發表於2019-04-13

halo,大家好,我是 132 唔,經過四天時間,c站的 3.0 重構終於告一段落啦

c站(clicli.us)3.0 重構經驗分享

重構真的是,最不合算的重複勞動了 可是每次重構,都或多或少的,學到新東西

之前的 2.0 重構的文章,在這裡:github.com/frontend9/f…

重構背景

v2 版本一來,經過接近一年的時間,隨著c站業務的發展,已經出現一些問題 比如我們的番劇系統,需要更加強大的索引 比如我們的 ugc 版權,需要更加合理的上傳稽核機制 等等 加上多人協作,程式碼質量每況愈下

本來是打算等到 vue3 發版再重構的來著,但是還是沒能忍得住,就提前重構了

目標

  1. 對程式碼進行重新梳理,提高程式碼質量,減小維護成本
  2. 對各個端進行重構,更完美的服務業務,更有利於下次重構

開始

後端 API 重構

重構的開端還是從 API 開始 本次後端重構,最主要的是重構了番劇索引介面

image
場景主要就是,這種索引的場景,其中,分類、狀態等,單選,標籤多選,條件間取交集,標籤取並集

其實這個場景在視訊網站中非常多見,對於後端來說,是個一對多,多對多的問題 上個版本 c站 使用了 redis 來做這個邏輯

略複雜,這個版本,使用了更簡單的方式,拼接字串

var query string
if status != "" && status != "nowait" {
	query = fmt.Sprintf(`AND posts.status ='%s'`, status)
}

if sort != "" {
	query += fmt.Sprintf(`AND posts.sort ='%s'`, sort)
}

if uid != 0 {
	query += fmt.Sprintf(`AND posts.uid ='%d'`, uid)
}

if status == "nowait" {
	query += `AND NOT posts.status='wait'`
}
···
這樣就會根據引數,拼成一個字串
為了防止所有引數都沒有的情況,可以預設攜帶一個 1=1
```sql
sqlRaw := fmt.Sprintf(`SELECT posts.id,posts.title,posts.content,posts.status,posts.sort,posts.tag,posts.time,users.id,users.name,users.qq FROM posts LEFT JOIN users ON posts.uid = users.id 
WHERE 1=1 %s ORDER BY time DESC`, query)
複製程式碼

這樣就可以做成一個完美的查詢介面啦,一個介面搞定一切查詢的 case

介面預覽:api.clicli.us/posts?statu…

然後對於使用者介面等,同時也做了類似的調整 然後後端就沒啥啦

前端

前端的重構,其實就是重新寫了 API,大概提幾個要點吧

###. 跨域

跨域是個很尷尬的問題,之前面試還一直被問,我當時是咋說的來著?

不解釋,就是反代 這次最坑的是,我真的是,三天重構時間,因為我沒有去反代,浪費了一天時間

最主要的是非簡單請求的 options攜帶 cookie 的問題 據說,需要同時滿足兩個條件:

withcredentials必須設定為true, origin不能用萬用字元*

可惜,搗鼓了好久,還是不能很好的解決 最終我很後悔這次嘗試,我從一開始就應該堅定立場

面試官你再敢問,我就不解釋,反代送給你

新番時間表

c站(clicli.us)3.0 重構經驗分享
場景如圖,需要一個從 週一到週日 的新番表

之前我們是後臺手動設定,很不夠傻瓜化

這次決定做成自動的 方法就是對資料的重新遍歷

let ret = {
            1: [],
            2: [],
            3: [],
            4: [],
            5: [],
            6: [],
            0: [],
          }
res.data.posts.forEach(item => {
     let day = new Date(item.time).getDay()
     ret[day].push(item)
 })
this.items = ret
複製程式碼

ret 一個以數字為 key 的 物件,分別代表了週一到週日,0 為週日 然後渲染就很容易啦

<li v-for="item in items[activeIndex]">
   <router-link :to="'/play/gv'+item.id">
       <img :src="getSuo(item.content)" :alt="item.title">
       <div class="text">
          <div class="title">{{item.title}}</div>
       </div>
   </router-link>
 </li>
複製程式碼

activeIndex 就是今天的 getDay()

其實這種通過當前日期來自動歸類資料的小技巧,還是經常用用 能縮減很多維護量的

標籤

QQ圖片20190413202947
場景如圖,就是標籤的選擇和去選擇 通常,很多人喜歡用多選框來做,然後通過 label 去繫結樣式等等

但是其實不用,因為無論怎麼選擇,最終對應的都是字串而已 在此之前,先搞定,多個引數怎麼在 url 裡傳遞

GET /posts?tag=標籤1+標籤2

後端拿到的,其實是兩個標籤中間,有一個空格 標籤1 標籤2

也就是說,我們選擇多少個標籤,只需要用空格去追加字串即可

selectTag(item) {
    if (this.state.tag.includes(item)) {
      this.setState({
        tag: this.state.tag.replace(` ${item}`, '')
      })
    } else {
      this.setState({
        tag: this.state.tag + ` ${item}`
      })
    }
  }
複製程式碼

通過 includes ,包含這個字串就高亮,再點選就是移除字串,取消高亮 一個非常簡單的標籤功能就搞定了

然後,好像就沒有然後了::>_<::

APP

app 是由 @jwchan1996 小哥哥負責更新的,我只是打輔助,不知道他會不會發文章呢::>_<::

然後我遇到了一個問題,就是版本釋出的坑,我們每次釋出,都沒有好的版本控制

導致很多人下載不到最新的版本,也沒辦法上架應用商店

所以想了個辦法,釋出到 npm 上,每次就可以 @latest 啦,哈哈哈

總結

細細想來,這次重構確實,沒什麼新的東西

都怪我尿性使然,等不及 vue 3

不過等 vue3 發版,我們還會繼續重構,到時候再來一波分享吧

連結

c站首頁:clicli.us c站原創頁:clicli.us/explore

APP 永久最新下載地址:unpkg.com/@clicli/app

github 開源地址:github.com/acgzone

介面文件:github.com/acgzone/acg…

相關文章