feat: ota

This commit is contained in:
zzw
2026-09-22 16:47:38 +08:00
parent fdf5825d83
commit 08b67dba70
26 changed files with 1033 additions and 178 deletions
+6 -1
View File
@@ -26,7 +26,12 @@ func Nacos(conf zrpc.RpcClientConf) zrpc.Client {
return zrpc.MustNewClient(cliConf,
zrpc.WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
zrpc.WithDialOption(grpc.WithUnaryInterceptor(request.UserClientInterceptor)),
zrpc.WithDialOption(grpc.WithDefaultCallOptions(grpc.WaitForReady(true))),
zrpc.WithDialOption(grpc.WithDefaultCallOptions(
grpc.WaitForReady(true),
// 上传文件经 base64 后可达 ~170MB+,需大于默认 4MB
grpc.MaxCallRecvMsgSize(256<<20),
grpc.MaxCallSendMsgSize(256<<20),
)),
zrpc.WithDialOption(grpc.WithConnectParams(grpc.ConnectParams{
MinConnectTimeout: 2 * time.Second,
})),
+75
View File
@@ -0,0 +1,75 @@
package request
import (
"bytes"
"encoding/base64"
"encoding/json"
"io"
"lone-services/bff/internal/response"
"lone-services/pkg/oss"
"net/http"
"path/filepath"
"strings"
)
const (
ossUploadAPIPath = "/api/v3/chore/oss/upload"
formFileField = "file"
maxUploadMemory = oss.MaxUploadBytes
)
func FormUploadMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost || r.URL.Path != ossUploadAPIPath {
next(w, r)
return
}
ct := r.Header.Get("Content-Type")
ctrl := &response.BaseController{}
if !strings.HasPrefix(strings.ToLower(ct), "multipart/form-data") {
ctrl.Error(w, response.Define(response.ErrorMissingParams, "请使用 multipart/form-data 上传,字段名为 file"))
return
}
if err := r.ParseMultipartForm(int64(maxUploadMemory)); err != nil {
ctrl.Error(w, response.Define(response.ErrorMissingParams, "解析上传文件失败"))
return
}
file, header, err := r.FormFile(formFileField)
if err != nil {
ctrl.Error(w, response.Define(response.ErrorMissingParams, "请上传文件,字段名为 file"))
return
}
defer file.Close()
content, err := io.ReadAll(io.LimitReader(file, int64(maxUploadMemory)+1))
if err != nil || len(content) == 0 {
ctrl.Error(w, response.Define(response.ErrorMissingParams, "文件内容不能为空"))
return
}
if len(content) > maxUploadMemory {
ctrl.Error(w, response.Define(response.ErrorMissingParams, "文件过大,最大 128MB"))
return
}
filename := filepath.Base(header.Filename)
if filename == "." || filename == "" {
filename = "file"
}
payload, err := json.Marshal(map[string]string{
"filename": filename,
"content": base64.StdEncoding.EncodeToString(content),
})
if err != nil {
ctrl.Fail(w)
return
}
r.Body = io.NopCloser(bytes.NewReader(payload))
r.ContentLength = int64(len(payload))
r.Header.Set("Content-Type", "application/json")
next(w, r)
}
}