vue+golang實(shí)現(xiàn)上傳微信頭像功能


<button class="avatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :src="avatarUrl" class="avatar-img"></image>
</button>
// 微信頭像修改
onChooseAvatar(e) {
this.uploadFile(e.detail.avatarUrl)
},
/* 上傳頭像轉(zhuǎn)化格式*/
uploadFile(avatarUrl){
uni.uploadFile({
url: this.fetch.fileUrl() + '/api/upload/uploadimages',//后臺(tái)接口
filePath: avatarUrl,// 上傳圖片 url
name:'image',
header: {
'content-type': 'multipart/form-data',
'token': uni.getStorageSync('token')
}, // header 值
success: res => {
let obj = JSON.parse(res.data)
console.log('obj', obj)
if (obj. status == 'True') {
this.avatarUrl = obj.data
} else {
this.common.toast(obj.msg)
}
},
fail: e => {
this.common.toast("上傳失敗")
}
});
},
api后臺(tái)接收文件
/*
* @Author: lmy
* @Date: 2023-10-26 15:12:13
* @LastEditors: lmy
* @LastEditTime: 2023-10-27 10:40:14
* @FilePath: \Project_UNI-APP_API\Main_Upload_Images.go
* @Description: 正式版
*/
package main
import (
"bytes"
"io"
"net/http"
"path"
"strings"
"cntotal.com/sbjapi/xfileserviceapi"
"cntotal.com/sbjbase/xjson"
"cntotal.com/sbjlog"
)
// uploadImages 上傳圖片
func uploadImages(w http.ResponseWriter, r *http.Request) {
apiWriteHandler("", verifyUploadImages, &APIContext{Writer: w, Request: r, IsReadBody: true}, false)
}
// verifyUploadImages 上傳圖片
func verifyUploadImages(a *APIContext) bool {
defer func() {
if err := recover(); err != nil {
sbjlog.ExcLog("100", "[%s]verifyUploadImages-小程序登錄:%s", a.Flag.Code, err)
}
}()
uploadFile, handle, err := a.Request.FormFile("image")
ext := strings.ToLower(path.Ext(handle.Filename))
if ext != ".jpg" && ext != ".png" && ext != ".jpeg" {
a.Resp.Msg = "只支持jpg/jpeg/png圖片上傳"
return false
}
var buff = new(bytes.Buffer)
_, _ = io.Copy(buff, uploadFile)
buffByte := buff.Bytes()
dataStr, err := xfileserviceapi.UploadTempFile(handle.Filename, &buffByte)
if err != nil {
sbjlog.Debug("xfileserviceapi.UploadTempFile 上傳圖片失敗,圖片名稱:%v,err:%v ", handle.Filename, err)
a.Resp.Msg = "上傳圖片失敗"
return false
}
returnData := xjson.JSONToMapString(dataStr)
fileurl := returnData["fileurl"]
if fileurl == "" {
a.Resp.Msg = "上傳圖片失敗"
return false
}
a.Resp.Data = fileurl
a.Resp.Msg = "上傳圖片成功"
return true
}
上傳文件接口
package main
import (
"net/http"
"strings"
"cntotal.com/sbjbase"
"cntotal.com/sbjlog"
systemdb "cntotal.com/ProjectDBLibrary/system/DB"
"cntotal.com/sbjbase/xalgorithm"
"cntotal.com/sbjbase/xjson"
)
// 上傳臨時(shí)文件
func type23(w http.ResponseWriter, r *http.Request) {
apiWriteHandler("23", verify23, &APIContext{Writer: w, Request: r})
}
// 上傳臨時(shí)文件
func verify23(a *APIContext) bool {
var err error
fileName := a.WordData["fileName"]
uploadType := a.WordData["uploadType"] // 上傳方式 10=覆蓋上傳 | 為空代表非覆蓋,生成隨機(jī)文件名
Tp := a.WordData["Tp"]
CheckKey := a.WordData["CheckKey"]
//檢驗(yàn)CheckKey
sCheckKey := xalgorithm.MD5ToUpper32(xalgorithm.MD5ToUpper32(xalgorithm.MD5ToUpper32(fileName + Tp)[:15]))
if CheckKey != sCheckKey {
a.Resp.Msg = "CheckKey 驗(yàn)證不通過(guò)"
return false
}
//驗(yàn)證參數(shù)值
if fileName == "" {
a.Resp.Msg = "fileName臨時(shí)文件名不能為空"
return false
}
//寫入文件日志
var systemFileLog systemdb.SystemFileLog
systemFileLog.Status = 10 // 狀態(tài) = 正常
systemFileLog.EnvironmentType = runEnvironment // 環(huán)境變量
systemFileLog.Pid = a.ProgramID // 上傳程序ID
systemFileLog.Type = 10 // 類型=上傳
systemFileLog.FileType = 40 // 文件類型 40=臨時(shí)文件
systemFileLog.IP = a.RequestIP // 上傳IP
//處理保存 文件屬性
fileProgramID := a.ProgramID //文件歸屬程序 (關(guān)系到文件的路徑寫入)
if a.WordData["isProjectFile"] == "1" {
fileProgramID = a.ProgramID / 100 * 100 //取整數(shù) 710020 / 100 = 710000
}
// 定義是否隨機(jī)文件名 | 如果不是覆蓋上傳,則填充隨機(jī)文件名
randomName := uploadType != "10"
// 獲取保存文件路徑信息
saveFilePath := getPathWithTempFile(fileProgramID, fileName, randomName)
systemFileLog.FilePath = saveFilePath.FilePath
// systemFileLog.FilePath, _, filename, fileext = GetPathWithTempFile(fileProgramID, tempPath)
if strings.Index(saveFilePath.FileName, ".") == 0 {
a.Resp.Msg = "文件名格式不正確"
return false
}
if indexStringArray(tempFileExt, saveFilePath.FileExt) == -1 {
a.Resp.Msg = "不滿足臨時(shí)文件文件格式"
return false
}
// 因?yàn)閿?shù)據(jù)已經(jīng)轉(zhuǎn)為了base64 ,源文件大小 * 133% = 現(xiàn)在大小 。 所以當(dāng)前大小 / 133% = 原文件大小
// 提前判斷的原因:在前面提前讀取判斷防止無(wú)效讀取文件,避免流量損失
if a.Request.ContentLength*3/4 > int64(tempFileSize) {
a.Resp.Msg = "臨時(shí)文件文件超出大小" + getMegabytesString(fileSize) + "限制"
return false
}
// 讀取數(shù)據(jù)保存到指定路徑 | 并計(jì)算文件md5
var tfMd5 string
systemFileLog.FileLength, tfMd5, err = readBodyFileToPath(a.Request, systemFileLog.FilePath)
if err != nil {
sbjlog.Debug("verify23-readBodyFileToCacheDir Error:%s", err.Error())
a.Resp.Msg = "讀取上傳文件出現(xiàn)異常"
return false
}
// 寫入臨時(shí)文件上傳日志
sflid := systemdb.InsertSystemFileLog(systemFileLog)
if sflid < 1 {
a.Resp.Msg = "新增文件日志失敗"
return false
}
a.Resp.Data, _ = sbjbase.AESEncrypt(
xjson.MapToJSON(
map[string]interface{}{
"fileid": sflid,
"fileurl": fileHost + strings.TrimPrefix(systemFileLog.FilePath, "./"),
"filemd5": tfMd5}),
CheckKey[:16])
return true
}
上傳臨時(shí)文件方法
// readBodyFileToCacheDir 讀取傳輸?shù)奈募4娴骄彺嫖募A
// 返回 臨時(shí)存儲(chǔ)地址,文件MD5,錯(cuò)誤信息
func readBodyFileToCacheDir(r *http.Request) (filepath string, filesize int, md5Str string, err error) {
filepath = cacheFileDir + fmt.Sprintf("%s_%s.temp", time.Now().Format("20060102150405"), xstring.RandomString(12, ""))
filesize, md5Str, err = readBodyFileToPath(r, filepath)
return
}
// readBodyFileToPath 從Body中讀取文件保存到指定路徑
func readBodyFileToPath(r *http.Request, filepath string) (filesize int, md5Str string, err error) {
var f *os.File
f, err = os.Create(filepath)
if err != nil {
return
}
defer f.Close()
// 按照Base64 編碼分塊讀取數(shù)據(jù)到文件 ? 問(wèn)題:未到限定步長(zhǎng)
_, err = xbinary.Copy(f, r.Body, 32*1024, xbinary.EncodeBase64)
if err != nil {
return
}
// 重置一下位置
f.Seek(0, 0)
var file os.FileInfo
file, err = f.Stat()
if err != nil {
return
}
filesize = int(file.Size())
if filesize <= 0 {
err = errors.New("文件內(nèi)容為空")
return
}
// 把文件重新讀出來(lái) 分塊進(jìn)行 MD5
md5Str, err = xalgorithm.MD5BlocksToUpper32(f, 32*1024, xalgorithm.EncodeHexLower)
return
}
到此這篇關(guān)于vue+golang上傳微信頭像的文章就介紹到這了,更多相關(guān)vue上傳微信頭像內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot+vue實(shí)現(xiàn)七牛云頭像的上傳
- vue3?頭像上傳?組件功能實(shí)現(xiàn)
- vue實(shí)現(xiàn)頭像上傳功能
- Vue?vant-ui使用van-uploader實(shí)現(xiàn)頭像上傳功能
- 利用nodeJS+vue圖片上傳實(shí)現(xiàn)更新頭像的過(guò)程
- Springboot+Vue-Cropper實(shí)現(xiàn)頭像剪切上傳效果
- vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁(yè)面的方法
- 詳解Vue+axios+Node+express實(shí)現(xiàn)文件上傳(用戶頭像上傳)
- node+vue實(shí)現(xiàn)用戶注冊(cè)和頭像上傳的實(shí)例代碼
相關(guān)文章
vue3+elementplus前端生成圖片驗(yàn)證碼完整代碼舉例
在開發(fā)過(guò)程中有時(shí)候需要使用圖片驗(yàn)證碼進(jìn)行增加安全強(qiáng)度,在點(diǎn)擊圖片時(shí)更新新的圖片驗(yàn)證碼,記錄此功能,以便后期使用,這篇文章主要給大家介紹了關(guān)于vue3+elementplus前端生成圖片驗(yàn)證碼的相關(guān)資料,需要的朋友可以參考下2024-03-03
vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問(wèn)題解決
這篇文章主要介紹了vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問(wèn)題解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Vue實(shí)現(xiàn)DateRange選擇器的禁選功能
在基于Vue.js構(gòu)建的應(yīng)用程序中,處理日期選擇器是一個(gè)常見(jiàn)的需求,尤其是在涉及到日期范圍的選擇時(shí),Vue提供了多種方式來(lái)實(shí)現(xiàn)日期選擇器的功能,并允許我們對(duì)這些組件進(jìn)行高度定制,本文將深入探討如何在Vue應(yīng)用中實(shí)現(xiàn)DateRange選擇器的禁選功能,需要的朋友可以參考下2024-10-10
基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn)
這篇文章主要介紹了基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
使用vscode格式化文檔無(wú)效的解決辦法(vue代碼格式化文檔無(wú)效)
這篇文章主要給大家介紹了關(guān)于使用vscode格式化文檔無(wú)效的解決辦法,也就是vue代碼格式化文檔無(wú)效,這是最近突然遇到的一個(gè)問(wèn)題,這里給大家介紹一下解決的辦法,需要的朋友可以參考下2023-08-08
el-form表單el-form-item驗(yàn)證規(guī)則里prop一次驗(yàn)證兩個(gè)或多個(gè)值問(wèn)題
這篇文章主要介紹了el-form表單el-form-item驗(yàn)證規(guī)則里prop一次驗(yàn)證兩個(gè)或多個(gè)值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05

