package qywx import ( "bytes" "context" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "path" "time" ) type Other struct { auth *Auth } func NewOther(auth *Auth) *Other { return &Other{ auth: auth, } } func (g *Other) UploadMediaWithUrl(ctx context.Context, fileUrl, mediaType, corpid, corpsecret string) (uploadRes *UploadMediaRes, err error) { // 1. 获取AccessToken auth, err := g.auth.GetAccessToken(ctx, corpid, corpsecret) if err != nil { return nil, fmt.Errorf("获取AccessToken失败: %v", err) } // 2. 下载文件 client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Get(fileUrl) if err != nil { return nil, fmt.Errorf("下载文件失败: %v", err) } defer resp.Body.Close() // 检查响应状态 if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("下载文件状态码错误: %d", resp.StatusCode) } // 3. 准备上传请求(修正点:使用正确的上传API) uploadUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s", auth.AccessToken, mediaType) // 4. 创建multipart表单 body := &bytes.Buffer{} writer := multipart.NewWriter(body) // 从URL提取文件名(或使用默认名) filename := path.Base(fileUrl) if filename == "/" || filename == "." { filename = fmt.Sprintf("file_%d.dat", time.Now().Unix()) } part, err := writer.CreateFormFile("media", filename) if err != nil { return nil, fmt.Errorf("创建表单文件失败: %v", err) } // 5. 流式传输文件内容 if _, err = io.Copy(part, resp.Body); err != nil { return nil, fmt.Errorf("写入文件内容失败: %v", err) } // 6. 关闭writer if err = writer.Close(); err != nil { return nil, fmt.Errorf("关闭writer失败: %v", err) } // 7. 发送上传请求 req, err := http.NewRequest("POST", uploadUrl, body) if err != nil { return nil, fmt.Errorf("创建请求失败: %v", err) } req.Header.Set("Content-Type", writer.FormDataContentType()) uploadResp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("上传请求失败: %v", err) } defer uploadResp.Body.Close() // 8. 解析响应 respBody, err := io.ReadAll(uploadResp.Body) if err != nil { return nil, fmt.Errorf("读取响应失败: %v", err) } if err = json.Unmarshal(respBody, &uploadRes); err != nil { return nil, fmt.Errorf("解析响应失败: %v", err) } if uploadRes.Errcode != 0 { return nil, fmt.Errorf("上传失败 [code=%d]: %s", uploadRes.Errcode, uploadRes.Errmsg) } return }