package MinIORelateController import ( "dsSzxy/Business/MinIORelate/MinIORelateDao" "dsSzxy/Utils/CommonUtil" "dsSzxy/Utils/ConfigUtil" "dsSzxy/Utils/MinioUtil" "dsSzxy/Utils/ObsUtil" "dsSzxy/Utils/ObsUtil/obs" "dsSzxy/Utils/RedisUtil" "fmt" "github.com/gin-gonic/gin" "github.com/minio/minio-go/v6" "net/http" "net/url" "path" "strings" "time" ) //模块的路由配置1 func Routers(r *gin.RouterGroup) { rr := r.Group("/minioRelate") rr.GET("/getPostPolicyInfo", getPostPolicyInfo) rr.GET("/generatePreviewUrl", generatePreviewUrl) rr.GET("/saveFileInfo", saveFileInfo) rr.GET("/getFileDownLoadUrl", getFileDownLoadUrl) } /** 功能:根据ID获取文件的下载地址和原始文件名 */ func getFileDownLoadUrl(c *gin.Context) { id := c.Query("id") if id == "" { c.JSON(http.StatusOK, gin.H{"success": false, "info": "文件id参数不允许为空!"}) return } resMap, err := MinIORelateDao.GetDownLoadUrl(id) if err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "获取文件信息失败!"}) return } if len(resMap) == 0 { c.JSON(http.StatusOK, gin.H{"success": false, "info": "未查询到文件信息!"}) return } originName := resMap["origin_name"] storageKey := resMap["storage_key"] storageBucket := resMap["storage_bucket"] infix := "?response-content-disposition=attachment%3BfileName%2A%3DUTF-8%27%27" downloadUrl := ConfigUtil.MinioDownloadPrefix + storageBucket + "/" + storageKey + infix + url.QueryEscape(url.QueryEscape(originName)) c.JSON(http.StatusOK, gin.H{"success": true, "download_url": downloadUrl}) } /** 功能:前台直传文件成功后,保存上传文件相间信息 作者:吴缤 日期:2021-07-06 */ func saveFileInfo(c *gin.Context) { id := c.Query("id") if id == "" { c.JSON(http.StatusOK, gin.H{"success": false, "info": "文件id参数不允许为空!"}) return } systemId := c.Query("systemid") if systemId == "" { c.JSON(http.StatusOK, gin.H{"success": false, "info": "系统ID不允许为空!"}) return } redisFileMap := RedisUtil.HMGETALL("file_" + id) if len(redisFileMap) == 0 { c.JSON(http.StatusOK, gin.H{"success": false, "info": "文件id不存在!"}) return } fileKey := redisFileMap["key"] fileOriginName := redisFileMap["origin_name"] fileUrlPrefix := redisFileMap["url"] fileBucket := redisFileMap["bucket"] minioClient, err := MinioUtil.GetMinioClient() if err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "minio无法连接!"}) return } //获取文件信息 objInfo, objErr := minioClient.StatObject(fileBucket, fileKey, minio.StatObjectOptions{}) if objErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "在存储中未找到文件!"}) return } fileSize := CommonUtil.ConvertInt64ToString(objInfo.Size) fileMd5 := objInfo.ETag fileMap := make(map[string]string) fileMap["id"] = id fileMap["origin_name"] = fileOriginName fileMap["storage_key"] = fileKey fileMap["storage_bucket"] = fileBucket fileMap["storage_url_prefix"] = fileUrlPrefix fileMap["file_size"] = fileSize fileMap["file_md5"] = fileMd5 fileMap["system_id"] = systemId insertErr := MinIORelateDao.InsertFileInfo(fileMap) if insertErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "写入数据库失败!"}) return } //删除redis中的信息 RedisUtil.DEL("file_" + id) c.JSON(http.StatusOK, gin.H{"success": true, "info": "成功!"}) } /** 功能:生成预览地址 作者:吴缤 日期:2021-07-05 */ func generatePreviewUrl(c *gin.Context) { id := c.Query("id") if id == "" { c.JSON(http.StatusOK, gin.H{"success": false, "info": "id参数不允许为空!"}) return } //根据ID获取数据库中该文件的key key, err := MinIORelateDao.GetFileKey(id) if err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "获取存储中的key异常!" + err.Error()}) return } obsClient, obsClientErr := ObsUtil.GetObsClient() if obsClientErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "获取OBS客户端异常!" + obsClientErr.Error()}) return } MetadataInput := &obs.GetObjectMetadataInput{} MetadataInput.Bucket = ConfigUtil.ObsBucket MetadataInput.Key = "crh/" + key _, metadataErr := obsClient.GetObjectMetadata(MetadataInput) //metadataErr不等于nil说明OBS上没有文件需要上传 if metadataErr != nil { minioClient, minioClientErr := MinioUtil.GetMinioClient() if minioClientErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "获取MinIO客户端异常!" + minioClientErr.Error()}) return } //获取minio中的文件流 minioObject, getObjErr := minioClient.GetObject(ConfigUtil.MinioBucket, key, minio.GetObjectOptions{}) if getObjErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "获取文件信息异常!" + getObjErr.Error()}) return } input := &obs.PutObjectInput{} input.Bucket = ConfigUtil.ObsBucket input.Key = "crh/" + key input.Body = minioObject _, putObjErr := obsClient.PutObject(input) if putObjErr != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "文件上传至OBS异常!" + putObjErr.Error()}) return } } obsClient.Close() c.JSON(http.StatusOK, gin.H{"success": true, "url": ConfigUtil.PreviewPrefix + key}) } /** 功能:获取前台上传时所需要相关信息 作者:吴缤 日期:2021-07-05 */ func getPostPolicyInfo(c *gin.Context) { fileName := c.Query("filename") if fileName == "" { c.JSON(http.StatusOK, gin.H{"success": false, "info": "文件名称不允许为空!"}) return } extension := path.Ext(fileName) minioClient, err := MinioUtil.GetMinioClient() if err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "minio无法连接!"}) return } //生成一个文件名 id := CommonUtil.GetUUID() policy := minio.NewPostPolicy() //Bucket名称 policy.SetBucket(ConfigUtil.MinioBucket) policy.SetKey(id[0:2] + "/" + id + extension) //1天有效期 policy.SetExpires(time.Now().UTC().AddDate(0, 0, 1)) url, formData, err := minioClient.PresignedPostPolicy(policy) if err != nil { c.JSON(http.StatusOK, gin.H{"success": false, "info": "minio生成签名失败!"}) return } policyMap := make(map[string]interface{}) for k, v := range formData { policyMap[strings.Replace(k, "-", "_", -1)] = v } policyMap["url"] = fmt.Sprintf("%s", url) policyMap["id"] = id policyMap["origin_name"] = fileName //将生产的签名存入redis中,以备后用 RedisUtil.HMSET("file_"+id, policyMap) //设置redis中的KEY有效期为1个小时 RedisUtil.EXPIRE("file_"+id, 3600) policyMap["success"] = true c.JSON(http.StatusOK, policyMap) }