文章首发于:clawhub.club


终于把图片上传写完了,主要思路就是用户上传图片,各种校验之后,主节点全部请求图床API(同步多协程),其他节点异步多协程请求,最后结果都存储mysql中,给客户返回一个唯一的虚拟url。

请求样例:

image.png
就是简单的图片上传,目前还没加上鉴权。

响应:

1
2
3
4
5
6
7
8
{
"code": 200,
"msg": "ok",
"data": {
"fileName": "LOGO2.png",
"url": "/2019/04/09/RcNaV1Jy-LOGO2.png"
}
}

库中存储

后期根据main_url获取真实可用的图床url,需要请求时302,并且发现不可用时,重新将根节点中的文件取出,上传到失效图库,并且更新mysql,当然这是异步操作。
image.png

核心代码

根节点处理,使用工作池。

1
2
3
4
5
6
7
8
9
//根节点处理,使用工作池
var wg sync.WaitGroup
for _, api := range setting.AppSetting.RootSiteApi {
wg.Add(1)
//协程处理根节点
go dealRootSite(email, api, imgMime, imgName, mainUrl, fileContent, h, &wg)

}
wg.Wait()
1
2
3
4
5
6
//根节点处理
func dealRootSite(email, api, imgMime, imgName, mainUrl string, fileContent []byte, h *multipart.FileHeader, wg *sync.WaitGroup) {
WhichApi(email, api, imgMime, imgName, mainUrl, fileContent, h)
wg.Done()
}

其他节点处理,直接协程跑。

1
2
3
4
5
//异步分发
for _, api := range setting.AppSetting.OtherSiteApi {
go WhichApi(email, api, imgMime, imgName, mainUrl, fileContent, h)

}

调用API逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

//使用图床api
func WhichApi(email, api, imgMime, imgName, mainUrl string, fileContent []byte, h *multipart.FileHeader) {
var url string
//API图床选择
switch api {
case "Local":
showUrl, _, _, _ := server.UpLoadToLocal(imgName, fileContent)
url = showUrl
case "SouGou":
url = server.UpLoadToSouGou(fileContent)
case "Sina":
if setting.BedSetting.Sina.OpenSinaPicStore == false {
url = ""
} else {
url = server.UpLoadToSina(fileContent, imgMime)
}
case "Smms":
url = server.UploadToSmms(fileContent, imgName)
case "CC":
durl, _ := server.UploadToCC(fileContent, imgName, imgMime)
url = durl
case "Flickr": //雅虎图片服务器,国内访问吃力
if setting.BedSetting.Flickr.OpenFlickrStore == false {
url = ""
} else {
file, err := h.Open()
if err != nil {
}
url = server.UploadToFlickr(file, h.Filename)
}
case "Baidu":
url = server.UploadToBaidu(fileContent, imgName)
case "Qihoo":
url = server.UploadToQihoo(fileContent, imgName, imgMime)
case "NetEasy":
url = server.UploadToNetEasy(fileContent, imgName, imgMime)
case "Jd":
url = server.UploadToJd(fileContent, imgName, imgMime)
case "JueJin":
url = server.UploadToJueJin(fileContent, imgName, imgMime)
case "Ali":
url = server.UploadToAli(fileContent, imgName, imgMime)
case "Open":
url = server.UpLoadToPublicSina(fileContent, imgName, imgMime)
}
if url != "" {
// api email mainUrl url imgName imgMime 入库
_ = dao.Insert(api, email, mainUrl, url, imgName, imgMime)
}

只是学习使用,不知道会不会有啥问题,慢慢来。
项目地址:
https://github.com/ClawHub/go-figure-bed