package service import ( "context" "fmt" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/minio/minio-go/v7" "github.com/pkg/errors" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "io" "mime/multipart" "net/http" "net/url" "path" "time" ) var maxFileByte int64 = 20971520 //20M type DocLibSvc struct{} func GetFileContentType(out multipart.File) (contentType string, err error) { buffer := make([]byte, 512) _, err = out.Read(buffer) if err != nil { return } contentType = http.DetectContentType(buffer) return } func (d *DocLibSvc) AddFile(c *gin.Context) (fileUrl string, err error) { var ( uploadFile *multipart.FileHeader uploadFd multipart.File minioClient *minio.Client ext string contentType string ) uploadFile, err = c.FormFile("upload_file") if err != nil { err = errors.Wrap(err, "上传的文件不存在") return } if uploadFile.Size > maxFileByte { err = errors.New("超过上传最大限制") return } uploadFd, err = uploadFile.Open() if err != nil { err = errors.Wrap(err, "打开文件失败") return } defer uploadFd.Close() ext = path.Ext(uploadFile.Filename) contentType, err = GetFileContentType(uploadFd) if err != nil { err = errors.Wrap(err, "获取ContentType失败") return } uploadFd.Seek(0, 0) //上传文件到minio minioClient, err = client.GetMinioConnect() if err != nil { err = errors.Wrap(err, "getMinio") return } id := uuid.NewString() _, err = minioClient.PutObject(c, conf.Options.MinioBucket, fmt.Sprintf("%s%s", id, ext), uploadFd, uploadFile.Size, minio.PutObjectOptions{ ContentType: contentType, UserMetadata: map[string]string{ "name": uploadFile.Filename, }, }) if err != nil { err = errors.Wrap(err, "上传文件失败") return } fileUrl = fmt.Sprintf("%s/%s/%s%s", conf.Options.MinioServer, conf.Options.MinioBucket, id, ext) return } // GetFile 读取minio文件 func (d DocLibSvc) GetFile(fileName string) (obj io.Reader, err error) { minioClient, err := client.GetMinioConnect() if err != nil { err = errors.Wrap(err, "getMinio") return } object, err := minioClient.GetObject(context.Background(), conf.Options.MinioBucket, fileName, minio.GetObjectOptions{}) if err != nil { err = errors.Wrap(err, "download object error") return } obj = io.Reader(object) return obj, nil //localFile, err := os.CreateIndex("C:/Users/25238/Desktop/123456.xlsx") //if err != nil { // log.Fatalf("create local object error " + err.Error()) //} //_, err = io.Copy(localFile, object) //if err != nil { // log.Fatalf("write object from object to local file error " + err.Error()) // return //} } func (d DocLibSvc) DownloadFile(ctx *gin.Context, req request.DocLibGetReq) (docUrl *url.URL, err error) { var ( minioClient *minio.Client ) minioClient, err = client.GetMinioConnect() if err != nil { err = errors.Wrap(err, "getMinio") return } remotePath := fmt.Sprintf("%s%s", req.FileName, req.Ext) reqParams := make(url.Values) switch req.Opt { case "info": return case "preview": reqParams.Set("response-Content-Type", req.Ext) case "download": reqParams.Set("response-Content-Disposition", fmt.Sprintf("attachment; filename=%s%s", req.FileName, req.Ext)) reqParams.Set("response-Content-Type", "application/octet-stream") reqParams.Set("response-Content-Transfer-Encoding", "binary") } docUrl, err = minioClient.PresignedGetObject(ctx, conf.Options.MinioBucket, remotePath, time.Second*60*60, reqParams) if err != nil { err = errors.Wrap(err, "get file url from minio fail") return } return }