open_api_lib.go 2.2 KB
package openlib

import (
	"bytes"
	"context"
	"encoding/json"
	"github.com/zeromicro/go-zero/core/mapping"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc/pkg/gateway"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
)

type OpenApiService struct {
	gateway.Service
}

func (svc *OpenApiService) PutFile(ctx context.Context, request RequestPutFile) (*DataPutFile, error) {
	var result DataPutFile
	r, _ := buildRequest(ctx, http.MethodPost, svc.Host+"/v1/vod/putObject", request)
	response, err := svc.GetService().DoRequest(r)
	if err != nil {
		return nil, err
	}
	if err := svc.HandlerResponse(ctx, r, response, nil, &result); err != nil {
		return nil, err
	}
	return &result, nil
}

func buildRequest(ctx context.Context, method, tmpUrl string, data any) (*http.Request, error) {
	u, err := url.Parse(tmpUrl)
	if err != nil {
		return nil, err
	}

	var val map[string]map[string]any
	if data != nil {
		val, err = mapping.Marshal(data)
		if err != nil {
			return nil, err
		}
	}

	var reader io.Reader
	jsonVars, hasJsonBody := val["json"]
	if hasJsonBody {
		var buf bytes.Buffer
		enc := json.NewEncoder(&buf)
		if err := enc.Encode(jsonVars); err != nil {
			return nil, err
		}

		reader = &buf
	}

	req, err := http.NewRequestWithContext(ctx, method, u.String(), reader)
	if err != nil {
		return nil, err
	}
	fileVars, hasFile := val["file"]
	if hasFile {
		if err = fillFile(req, fileVars); err != nil {
			return nil, err
		}
	}
	if hasJsonBody {
		req.Header.Set("Content-Type", "application/json; charset=utf-8")
	}

	return req, nil
}

func fillFile(req *http.Request, val map[string]any) error {
	if len(val) == 0 {
		return nil
	}
	pr, pw := io.Pipe()
	bodyWriter := multipart.NewWriter(pw)
	go func() {
		for k, v := range val {
			fileWriter, err := bodyWriter.CreateFormFile(k, k)
			if err != nil {
				return
			}
			//fh, err := os.Open(v.(string))
			//if err != nil {
			//	return err
			//}
			fh := bytes.NewBuffer(v.([]byte))
			// iocopy
			_, err = io.Copy(fileWriter, fh)
			if err != nil {
				return
			}
		}
		bodyWriter.Close()
		pw.Close()
	}()
	req.Header.Set("Content-Type", bodyWriter.FormDataContentType())
	req.Body = ioutil.NopCloser(pr)
	req.Header.Set("Transfer-Encoding", "chunked")
	return nil
}