package base import ( "bytes" "dashoo.cn/opms_libary/myerrors" "dashoo.cn/opms_libary/plugin/dingtalk/context" "encoding/json" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" "os" "path/filepath" "strings" ) const BaseApiUrl = "https://api.dingtalk.com" //Base 微信公众平台,基本类 type Base struct { *context.Context } //HTTPGetWithAccessToken 自动加上access_token变量的GET调用, //如果失败,会清空AccessToken cache, 再试一次 func (c *Base) HTTPGetWithAccessToken(url string, param map[string]interface{}) (resp []byte, err error) { retry := 1 Do: var accessToken string accessToken, err = c.GetAccessToken() if err != nil { return } var target = "" if strings.Contains(url, "http") { target = fmt.Sprintf("%s?access_token=%s", url, accessToken) } else { if strings.Contains(url, "?") { target = fmt.Sprintf("%s%s&x-acs-dingtalk-access-token=%s", BaseApiUrl, url, accessToken) } else { target = fmt.Sprintf("%s%s?x-acs-dingtalk-access-token=%s", BaseApiUrl, url, accessToken) } } //双重for-range for k, v := range param { target = fmt.Sprintf("%s&%s=%v", target, k, v) } var response *http.Response response, err = http.Get(target) if err != nil { return } defer response.Body.Close() fmt.Println(response.StatusCode, response.Status) resp, err = ioutil.ReadAll(response.Body) if err != nil { if retry > 0 { retry-- c.CleanAccessTokenCache() goto Do } return } return } //HTTPPostJSONWithAccessToken post json 自动加上access token, 并retry func (c *Base) HTTPPostJSONWithAccessToken(url string, obj interface{}) (resp []byte, err error) { retry := 1 Do: var accessToken string accessToken, err = c.GetAccessToken() if err != nil { return } var target = "" if strings.Contains(url, "http") { target = fmt.Sprintf("%s?access_token=%s", url, accessToken) } else { if strings.Contains(url, "?") { target = fmt.Sprintf("%s%s", BaseApiUrl, url) } else { target = fmt.Sprintf("%s%s", BaseApiUrl, url) } } resp, err = PostJSON(target, obj, accessToken) if err != nil { if retry > 0 { retry-- c.CleanAccessTokenCache() goto Do } return } return } //PostJSON post json 数据请求 func PostJSON(url string, obj interface{}, token string) ([]byte, error) { jsonData, err := json.Marshal(obj) if err != nil { return nil, err } jsonData = bytes.Replace(jsonData, []byte("\\u003c"), []byte("<"), -1) jsonData = bytes.Replace(jsonData, []byte("\\u003e"), []byte(">"), -1) jsonData = bytes.Replace(jsonData, []byte("\\u0026"), []byte("&"), -1) body := bytes.NewBuffer(jsonData) req, _ := http.NewRequest("POST", url, body) // 比如说设置个token req.Header.Set("x-acs-dingtalk-access-token", token) // 再设置个json req.Header.Set("Content-Type", "application/json") response, err := (&http.Client{}).Do(req) if err != nil { return nil, err } defer response.Body.Close() fmt.Println(response.StatusCode, response.Status) if response.StatusCode != http.StatusOK { return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", url, response.StatusCode) } return ioutil.ReadAll(response.Body) } // HTTPPostFormDataWithAccessToken 使用multipart/form-data POST上传文件 func (c *Base) HTTPPostFormDataWithAccessToken(url string, obj map[string]string) (resp []byte, err error) { retry := 1 Do: var accessToken string accessToken, err = c.GetAccessToken() if err != nil { return } var target = "" if strings.Contains(url, "http") { target = fmt.Sprintf("%s?access_token=%s", url, accessToken) } else { if strings.Contains(url, "?") { target = fmt.Sprintf("%s%s", BaseApiUrl, url) } else { target = fmt.Sprintf("%s%s", BaseApiUrl, url) } } resp, err = PostFormData(target, obj, accessToken) if err != nil { if retry > 0 { retry-- c.CleanAccessTokenCache() goto Do } return } return } // PostFormData form-data 提交数据 func PostFormData(url string, bodyData map[string]string, token string) ([]byte, error) { // Create a new buffer to store the form data body := new(bytes.Buffer) writer := multipart.NewWriter(body) // Create a new form file field fileField, err := writer.CreateFormFile(bodyData["____fileData"], filepath.Base(bodyData["____filePath"])) if err != nil { return nil, myerrors.New(500, err, err.Error()) } // 读取文件 file, err := os.Open(bodyData["____filePath"]) if err != nil { return nil, err } defer file.Close() // Copy the file contents to the form file field _, err = io.Copy(fileField, file) if err != nil { return nil, myerrors.New(500, err, err.Error()) } for key, val := range bodyData { if !strings.Contains(key, "----") { _ = writer.WriteField(key, val) } } // Close the writer to finalize the form data err = writer.Close() if err != nil { return nil, myerrors.New(500, err, err.Error()) } // Create a new HTTP request with the form data request, err := http.NewRequest("POST", url, body) if err != nil { return nil, myerrors.New(500, err, err.Error()) } // Set the Content-Type header to multipart/form-data request.Header.Set("Content-Type", writer.FormDataContentType()) // Send the request and get the response response, err := (&http.Client{}).Do(request) if err != nil { return nil, err } defer response.Body.Close() fmt.Println(response.StatusCode, response.Status) if response.StatusCode != http.StatusOK { return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", url, response.StatusCode) } return ioutil.ReadAll(response.Body) }