diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 7329d187d..b6d00f690 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -78,6 +78,7 @@ func main() { { thirdGroup.POST("/tencent_cloud_storage_credential", apiThird.TencentCloudStorageCredential) thirdGroup.POST("/minio_storage_credential", apiThird.MinioStorageCredential) + thirdGroup.POST("/minio_upload", apiThird.MinioUploadFile) } //Message chatGroup := r.Group("/msg") diff --git a/internal/api/third/minio_init.go b/internal/api/third/minio_init.go index a5a8cbe4f..564d19a1e 100644 --- a/internal/api/third/minio_init.go +++ b/internal/api/third/minio_init.go @@ -10,13 +10,18 @@ import ( url2 "net/url" ) +var ( + minioClient *minio.Client +) + func MinioInit() { + log.NewInfo("", utils.GetSelfFuncName()) minioUrl, err := url2.Parse(config.Config.Credential.Minio.Endpoint) if err != nil { log.NewError("", utils.GetSelfFuncName(), "parse failed, please check config/config.yaml", err.Error()) return } - minioClient, err := minio.New(minioUrl.Host, &minio.Options{ + minioClient, err = minio.New(minioUrl.Host, &minio.Options{ Creds: credentials.NewStaticV4(config.Config.Credential.Minio.AccessKeyID, config.Config.Credential.Minio.SecretAccessKey, ""), Secure: false, }) diff --git a/internal/api/third/minio_storage_credential.go b/internal/api/third/minio_storage_credential.go index f4862c062..65758c3fb 100644 --- a/internal/api/third/minio_storage_credential.go +++ b/internal/api/third/minio_storage_credential.go @@ -8,12 +8,63 @@ import ( "Open_IM/pkg/common/token_verify" _ "Open_IM/pkg/common/token_verify" "Open_IM/pkg/utils" + "context" "github.com/gin-gonic/gin" + "github.com/minio/minio-go/v7" _ "github.com/minio/minio-go/v7" cr "github.com/minio/minio-go/v7/pkg/credentials" "net/http" ) +func MinioUploadFile(c *gin.Context) { + var ( + req apiStruct.MinioUploadFileReq + resp apiStruct.MinioUploadFileResp + ) + if err := c.BindJSON(&req); err != nil { + log.NewError("0", utils.GetSelfFuncName(), "BindJSON failed ", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + return + } + log.NewInfo(req.OperationID, utils.GetSelfFuncName(), req) + switch req.FileType { + case constant.VideoType: + snapShotFile, _ := c.FormFile("snapShot") + snapShotFileObj, err := snapShotFile.Open() + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "Open file error", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + } + snapShotNewName, snapShotNewType := utils.GetNewFileNameAndContentType(snapShotFile.Filename) + _, err = minioClient.PutObject(context.Background(), config.Config.Credential.Minio.Bucket, snapShotNewName, snapShotFileObj, snapShotFile.Size, minio.PutObjectOptions{ContentType: snapShotNewType}) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "PutObject snapShotFile error", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + } + resp.SnapshotURL = config.Config.Credential.Minio.Endpoint + "/" + config.Config.Credential.Minio.Bucket + "/" + snapShotNewName + resp.SnapshotNewName = snapShotNewName + } + file, _ := c.FormFile("file") + fileObj, err := file.Open() + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "Open file error", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": "invalid file path" + err.Error()}) + return + } + newName, newType := utils.GetNewFileNameAndContentType(file.Filename) + _, err = minioClient.PutObject(context.Background(), config.Config.Credential.Minio.Bucket, newName, fileObj, file.Size, minio.PutObjectOptions{ContentType: newType}) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "open file error") + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": "invalid file path" + err.Error()}) + return + } + resp.NewName = newName + resp.URL = config.Config.Credential.Minio.Endpoint + "/" + config.Config.Credential.Minio.Bucket + "/" + newName + log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp) + c.JSON(http.StatusOK, gin.H{"errCode": 0, "errMsg": "", "data": resp}) + return +} + func MinioStorageCredential(c *gin.Context) { var ( req apiStruct.MinioStorageCredentialReq diff --git a/pkg/base_info/minio_api_struct.go b/pkg/base_info/minio_api_struct.go index f15997053..d031244ed 100644 --- a/pkg/base_info/minio_api_struct.go +++ b/pkg/base_info/minio_api_struct.go @@ -6,8 +6,20 @@ type MinioStorageCredentialReq struct { type MiniostorageCredentialResp struct { SecretAccessKey string `json:"secretAccessKey"` - AccessKeyID string `json:"accessKeyID"` - SessionToken string `json:"sessionToken"` - BucketName string `json:"bucketName"` - StsEndpointURL string `json:"stsEndpointURL"` + AccessKeyID string `json:"accessKeyID"` + SessionToken string `json:"sessionToken"` + BucketName string `json:"bucketName"` + StsEndpointURL string `json:"stsEndpointURL"` +} + +type MinioUploadFileReq struct { + OperationID string `json:"operationID"` + FileType int `json:"fileType"` +} + +type MinioUploadFileResp struct { + URL string `json:"URL"` + NewName string `json:"newName"` + SnapshotURL string `json:"snapshotURL" binding:"omitempty"` + SnapshotNewName string `json:"snapshotName" binding:"omitempty"` } diff --git a/pkg/common/constant/constant.go b/pkg/common/constant/constant.go index 8f0494d53..2efb3da82 100644 --- a/pkg/common/constant/constant.go +++ b/pkg/common/constant/constant.go @@ -159,6 +159,10 @@ const ( //callback callbackHandleCode CallbackHandleSuccess = 0 CallbackHandleFailed = 1 + + // minioUpload + OtherType = 1 + VideoType = 2 ) var ContentType2PushContent = map[int64]string{ diff --git a/pkg/proto/tag/tag.proto b/pkg/proto/tag/tag.proto new file mode 100644 index 000000000..e69de29bb diff --git a/pkg/utils/file.go b/pkg/utils/file.go index 15ce153b0..c72f6fc3d 100644 --- a/pkg/utils/file.go +++ b/pkg/utils/file.go @@ -1,6 +1,11 @@ package utils -import "os" +import ( + "fmt" + "math/rand" + "os" + "time" +) // Determine whether the given path is a folder func IsDir(path string) bool { @@ -20,3 +25,12 @@ func IsFile(path string) bool { func MkDir(path string) error { return os.MkdirAll(path, os.ModePerm) } + +func GetNewFileNameAndContentType(fileType string) (string, string) { + newName := fmt.Sprintf("%d-%d%s", time.Now().UnixNano(), rand.Int(), fileType) + contentType := "" + if fileType == "img" { + contentType = "image/" + fileType[1:] + } + return newName, contentType +}