Browse Source

feat: 内部 api 客户端迁移

kvii 1 month ago
parent
commit
d7500da609
3 changed files with 201 additions and 0 deletions
  1. 96 0
      common/clients/file.go
  2. 16 0
      common/clients/form.go
  3. 89 0
      common/clients/public.go

+ 96 - 0
common/clients/file.go

@@ -0,0 +1,96 @@
+package clients
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"io"
+	"mime/multipart"
+	"net/http"
+
+	"go.uber.org/zap"
+)
+
+// PostScreenShotReq 申报截图上传参数
+type PostScreenShotReq struct {
+	Name   string // 文件名
+	TaxNo  string // 税号
+	Period string // 账期
+}
+
+// 申报截图上传响应
+type PostScreenshotResp struct {
+	Path string `json:"path"` // 截图路径
+}
+
+// FileClient 文件客户端
+type FileClient struct {
+	Client *http.Client // 客户端
+	Logger *zap.Logger  // 日志
+}
+
+// PostScreenShotBytes 上传文件 返回上传的 url 参数 bs 为文件内容
+func (c FileClient) PostScreenShotBytes(ctx context.Context, bs []byte, p PostScreenShotReq) (string, error) {
+	return c.PostScreenShot(ctx, bytes.NewReader(bs), p)
+}
+
+// PostScreenShot 上传截图 返回上传的 url
+func (c FileClient) PostScreenShot(ctx context.Context, r io.Reader, p PostScreenShotReq) (string, error) {
+	var b bytes.Buffer
+	mw, err := c.writeMultipart(&b, p, r)
+	if err != nil {
+		return "", err
+	}
+
+	const u = "https://file.listensoft.net/api/v1/uploadsbjt"
+	req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, &b)
+	if err != nil {
+		return "", err
+	}
+	req.Header.Set("Content-Type", mw.FormDataContentType())
+
+	c.Logger.Debug("上传截图", zap.String("url", u), zap.String("name", p.Name))
+	resp, err := c.Client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	bs, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+	var response PostScreenshotResp
+	err = json.Unmarshal(bs, &response)
+	if err != nil {
+		return "", err
+	}
+	path := response.Path
+	c.Logger.Debug("上传截图成功", zap.String("name", p.Name), zap.String("path", path))
+	return path, nil
+}
+
+func (c FileClient) writeMultipart(w io.Writer, param PostScreenShotReq, r io.Reader) (*multipart.Writer, error) {
+	mw := multipart.NewWriter(w)
+	err := writeFileFromReader(mw, "file", param.Name, r)
+	if err != nil {
+		return nil, err
+	}
+	err = mw.WriteField("tax_no", param.TaxNo)
+	if err != nil {
+		return nil, err
+	}
+	err = mw.WriteField("period", param.Period)
+	if err != nil {
+		return nil, err
+	}
+	err = mw.WriteField("type", "etax")
+	if err != nil {
+		return nil, err
+	}
+	err = mw.Close()
+	if err != nil {
+		return nil, err
+	}
+	return mw, nil
+}

+ 16 - 0
common/clients/form.go

@@ -0,0 +1,16 @@
+package clients
+
+import (
+	"io"
+	"mime/multipart"
+)
+
+// 将 reader 写入到 multipart writer 的指定字段中
+func writeFileFromReader(mw *multipart.Writer, field, name string, r io.Reader) error {
+	w, err := mw.CreateFormFile(field, name)
+	if err != nil {
+		return err
+	}
+	_, err = io.Copy(w, r)
+	return err
+}

+ 89 - 0
common/clients/public.go

@@ -0,0 +1,89 @@
+// Package clients 提供一些内部接口的 http client 实现
+package clients
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"io"
+	"mime/multipart"
+	"net/http"
+
+	"go.uber.org/zap"
+)
+
+type PostApiResp[T any] struct {
+	Data T `json:"data"`
+}
+
+type PostFileResp struct {
+	Url string `json:"url"`
+}
+
+// PublicClient 公共文件客户端
+type PublicClient struct {
+	Client *http.Client // 客户端
+	Logger *zap.Logger  // 日志
+}
+
+// PostFileBytes 上传文件 返回上传的 url 参数 bs 为文件内容
+func (c PublicClient) PostFileBytes(ctx context.Context, name string, bs []byte) (string, error) {
+	return c.PostFile(ctx, name, bytes.NewReader(bs))
+}
+
+// PostFile 上传文件 返回上传的 url
+func (c PublicClient) PostFile(ctx context.Context, name string, r io.Reader) (string, error) {
+	var b bytes.Buffer
+	mw, err := c.writeMultipart(&b, name, r)
+	if err != nil {
+		return "", err
+	}
+
+	const u = "https://public.listensoft.net/api/uploadFile"
+	req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, &b)
+	if err != nil {
+		return "", err
+	}
+	req.Header.Set("Content-Type", mw.FormDataContentType())
+
+	c.Logger.Debug("上传文件", zap.String("url", u), zap.String("name", name))
+	resp, err := c.Client.Do(req)
+	if err != nil {
+		return "", err
+	}
+	defer resp.Body.Close()
+
+	bs, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return "", err
+	}
+	var response PostApiResp[PostFileResp]
+	err = json.Unmarshal(bs, &response)
+	if err != nil {
+		return "", err
+	}
+	fu := response.Data.Url
+	c.Logger.Debug("上传文件成功", zap.String("name", name), zap.String("fileUrl", fu))
+	return fu, nil
+}
+
+func (c PublicClient) writeMultipart(w io.Writer, name string, r io.Reader) (*multipart.Writer, error) {
+	mw := multipart.NewWriter(w)
+	err := writeFileFromReader(mw, "upFile", name, r)
+	if err != nil {
+		return nil, err
+	}
+	err = mw.WriteField("path", "/mnt/bank/banks/")
+	if err != nil {
+		return nil, err
+	}
+	err = mw.WriteField("name", name)
+	if err != nil {
+		return nil, err
+	}
+	err = mw.Close()
+	if err != nil {
+		return nil, err
+	}
+	return mw, nil
+}