halo,大家好,我是 132 唔,经过四天时间,c站的 3.0 重构终于告一段落啦
重构真的是,最不合算的重复劳动了 可是每次重构,都或多或少的,学到新东西
之前的 2.0 重构的文章,在这里:github.com/frontend9/f…
重构背景
v2 版本一来,经过接近一年的时间,随着c站业务的发展,已经出现一些问题 比如我们的番剧系统,需要更加强大的索引 比如我们的 ugc 版权,需要更加合理的上传审核机制 等等 加上多人协作,代码质量每况愈下
本来是打算等到 vue3 发版再重构的来着,但是还是没能忍得住,就提前重构了
目标
- 对代码进行重新梳理,提高代码质量,减小维护成本
- 对各个端进行重构,更完美的服务业务,更有利于下次重构
开始
后端 API 重构
重构的开端还是从 API 开始 本次后端重构,最主要的是重构了番剧索引接口
其实这个场景在视频网站中非常多见,对于后端来说,是个一对多,多对多的问题 上个版本 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不能用通配符*
可惜,捣鼓了好久,还是不能很好的解决 最终我很后悔这次尝试,我从一开始就应该坚定立场
面试官你再敢问,我就不解释,反代送给你
新番时间表
之前我们是后台手动设置,很不够傻瓜化
这次决定做成自动的 方法就是对数据的重新遍历
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()
其实这种通过当前日期来自动归类数据的小技巧,还是经常用用 能缩减很多维护量的
标签
但是其实不用,因为无论怎么选择,最终对应的都是字符串而已 在此之前,先搞定,多个参数怎么在 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