diff --git a/miniprogram/content/content.go b/miniprogram/content/content.go index d53f2db..f3f1b78 100644 --- a/miniprogram/content/content.go +++ b/miniprogram/content/content.go @@ -53,9 +53,12 @@ func (content *Content) CheckImage(media string) error { if err != nil { return err } + var directory = media response, err := util.PostFile( "media", - media, + nil, + "", + directory, fmt.Sprintf(checkImageURL, accessToken), ) if err != nil { diff --git a/miniprogram/security/security.go b/miniprogram/security/security.go index 3e979a5..011ea99 100644 --- a/miniprogram/security/security.go +++ b/miniprogram/security/security.go @@ -102,7 +102,8 @@ func (security *Security) ImageCheckV1(filename string) (err error) { } uri := fmt.Sprintf(imageCheckURL, accessToken) - response, err := util.PostFile("media", filename, uri) + var directory = filename + response, err := util.PostFile("media", nil, "", directory, uri) if err != nil { return } diff --git a/officialaccount/customerservice/manager.go b/officialaccount/customerservice/manager.go index 973a86c..dc92f4b 100644 --- a/officialaccount/customerservice/manager.go +++ b/officialaccount/customerservice/manager.go @@ -212,7 +212,8 @@ func (csm *Manager) UploadHeadImg(kfAccount, fileName string) (err error) { } uri := fmt.Sprintf("%s?access_token=%s&kf_account=%s", customerServiceUploadHeadImg, accessToken, kfAccount) var response []byte - response, err = util.PostFile("media", fileName, uri) + var directory = fileName + response, err = util.PostFile("media", nil, "", directory, uri) if err != nil { return } diff --git a/officialaccount/material/material.go b/officialaccount/material/material.go index d8a43b9..bafd9bb 100644 --- a/officialaccount/material/material.go +++ b/officialaccount/material/material.go @@ -163,7 +163,7 @@ type resAddMaterial struct { } // AddMaterialFromReader 上传永久性素材(处理视频需要单独上传),从 io.Reader 中读取 -func (material *Material) AddMaterialFromReader(mediaType MediaType, filename string, reader io.Reader) (mediaID string, url string, err error) { +func (material *Material) AddMaterialFromReader(mediaType MediaType, filename string) (mediaID string, url string, err error) { if mediaType == MediaTypeVideo { err = errors.New("永久视频素材上传使用 AddVideo 方法") return diff --git a/officialaccount/material/media.go b/officialaccount/material/media.go index 316758f..1d560e0 100644 --- a/officialaccount/material/media.go +++ b/officialaccount/material/media.go @@ -3,6 +3,9 @@ package material import ( "encoding/json" "fmt" + "io" + "net/http" + "strings" "github.com/silenceper/wechat/v2/util" ) @@ -38,16 +41,32 @@ type Media struct { } // MediaUpload 临时素材上传 -func (material *Material) MediaUpload(mediaType MediaType, filename string) (media Media, err error) { +func (material *Material) MediaUpload(mediaType MediaType, url string) (media Media, err error) { var accessToken string - accessToken, err = material.GetAccessToken() - if err != nil { + if accessToken, err = material.GetAccessToken(); err != nil { return } - uri := fmt.Sprintf("%s?access_token=%s&type=%s", mediaUploadURL, accessToken, mediaType) + // 使用strings.LastIndex函数找到最后一个斜杠的位置 + lastSlashIndex := strings.LastIndex(url, "/") + // 从最后一个斜杠的位置截取到最后,获取文件名 + filename := url[lastSlashIndex+1:] + // 获取资源 + resp, err := http.Get(url) + if err != nil { + err = fmt.Errorf("get image error: %v", err) + return + } + // 读取响应到内存 + var imageData []byte + imageData, err = io.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + err = fmt.Errorf("read image error: %v", err) + return + } var response []byte - response, err = util.PostFile("media", filename, uri) + response, err = util.PostFile("media", imageData, filename, "", uri) if err != nil { return } @@ -56,7 +75,7 @@ func (material *Material) MediaUpload(mediaType MediaType, filename string) (med return } if media.ErrCode != 0 { - err = fmt.Errorf("MediaUpload error : errcode=%v , errmsg=%v", media.ErrCode, media.ErrMsg) + err = fmt.Errorf("MediaUpload error : errcode=%v, errmsg=%v", media.ErrCode, media.ErrMsg) return } return @@ -91,7 +110,8 @@ func (material *Material) ImageUpload(filename string) (url string, err error) { uri := fmt.Sprintf("%s?access_token=%s", mediaUploadImageURL, accessToken) var response []byte - response, err = util.PostFile("media", filename, uri) + var directory = filename + response, err = util.PostFile("media", nil, "", directory, uri) if err != nil { return } diff --git a/util/http.go b/util/http.go index b9b4b00..b5d4d9c 100644 --- a/util/http.go +++ b/util/http.go @@ -146,26 +146,23 @@ func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, e return responseData, contentType, err } -// PostFile 上传文件 -func PostFile(fieldName, filename, uri string) ([]byte, error) { - fields := []MultipartFormField{ - { - IsFile: true, - Fieldname: fieldName, - Filename: filename, - }, +// PostFile 支持流或文件形式上传 +func PostFile(fieldName string, data []byte, fileName string, directory string, uri string) ([]byte, error) { + var fileContent []byte + var isFile bool + // 数据为空且文件目录不为空则按文件形式上传 + if len(data) == 0 && directory != "" { + isFile = true + } else { + fileContent = data } - return PostMultipartForm(fields, uri) -} - -// PostFileFromReader 上传文件,从 io.Reader 中读取 -func PostFileFromReader(filedName, fileName, uri string, reader io.Reader) ([]byte, error) { fields := []MultipartFormField{ { - IsFile: true, - Fieldname: filedName, - Filename: fileName, - FileReader: reader, + IsFile: isFile, + Fieldname: fieldName, + Value: fileContent, + Filename: fileName, + Directory: directory, }, } return PostMultipartForm(fields, uri) @@ -173,11 +170,11 @@ func PostFileFromReader(filedName, fileName, uri string, reader io.Reader) ([]by // MultipartFormField 保存文件或其他字段信息 type MultipartFormField struct { - IsFile bool - Fieldname string - Value []byte - Filename string - FileReader io.Reader + IsFile bool + Fieldname string + Value []byte + Filename string + Directory string } // PostMultipartForm 上传文件或其他多个字段 @@ -190,30 +187,24 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte for _, field := range fields { if field.IsFile { - fileWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename) + fileWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Directory) if e != nil { err = fmt.Errorf("error writing to buffer , err=%v", e) return } - if field.FileReader == nil { - fh, e := os.Open(field.Filename) - if e != nil { - err = fmt.Errorf("error opening file , err=%v", e) - return - } - _, err = io.Copy(fileWriter, fh) - _ = fh.Close() - if err != nil { - return - } - } else { - if _, err = io.Copy(fileWriter, field.FileReader); err != nil { - return - } + fh, e := os.Open(field.Directory) + if e != nil { + err = fmt.Errorf("error opening file , err=%v", e) + return + } + defer fh.Close() + + if _, err = io.Copy(fileWriter, fh); err != nil { + return } } else { - partWriter, e := bodyWriter.CreateFormField(field.Fieldname) + partWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename) if e != nil { err = e return @@ -235,7 +226,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, resp.StatusCode) + return nil, err } respBody, err = io.ReadAll(resp.Body) return diff --git a/work/material/media.go b/work/material/media.go index b32785a..0d812ac 100644 --- a/work/material/media.go +++ b/work/material/media.go @@ -48,7 +48,8 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) { return nil, err } var response []byte - if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadImgURL, accessToken)); err != nil { + var directory = filename + if response, err = util.PostFile("media", nil, "", directory, fmt.Sprintf(uploadImgURL, accessToken)); err != nil { return nil, err } result := &UploadImgResponse{} @@ -68,7 +69,8 @@ func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempF return nil, err } var response []byte - if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil { + var directory = filename + if response, err = util.PostFile("media", nil, "", directory, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil { return nil, err } result := &UploadTempFileResponse{} @@ -89,7 +91,8 @@ func (r *Client) UploadAttachment(filename string, mediaType string, attachmentT return nil, err } var response []byte - if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadAttachment, accessToken, mediaType, attachmentType)); err != nil { + var directory = filename + if response, err = util.PostFile("media", nil, "", directory, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil { return nil, err } result := &UploadAttachmentResponse{}