package api import ( "box-cost/conf" "box-cost/db/model" "box-cost/log" "fmt" "os" "path" "strings" "time" "github.com/gin-gonic/gin" "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs" ) func CreateObsClient() (*obs.ObsClient, error) { obsConf := conf.AppConfig.Obs return obs.New(obsConf.AccessKeyId, obsConf.SecrateKey, obsConf.Endpoint) } // u/xxx/img/up/timps.png func ServiceObsCreateImagePolicy(c *gin.Context, apictx *ApiSession) (interface{}, error) { body := struct { Ext string }{} err := c.ShouldBindJSON(&body) if err != nil { return nil, NewError("参数解析错误!") } if len(body.Ext) < 1 { return nil, NewError("上传文件的扩展名不能为空") } fkey := fmt.Sprintf("u/%s/images/uploads/%v.%s", apictx.User.Parent, time.Now().UnixNano(), body.Ext) client, err := CreateObsClient() if err != nil { return nil, NewError("创建ObsClient 失败!") } defer func() { client.Close() }() // 除key,policy,signature外,表单上传时的其他参数,支持的值: // acl // cache-control // content-type // content-disposition // content-encoding // expires bucketName := apictx.Svc.Conf.Obs.Bucket result, err := client.CreateBrowserBasedSignature(&obs.CreateBrowserBasedSignatureInput{ Bucket: bucketName, Key: fkey, Expires: 300, FormParams: map[string]string{ "x-obs-acl": "public-read", }, }) if err != nil { return nil, NewLogWithError(err) } obsConf := conf.AppConfig.Obs out := map[string]interface{}{ "accessKeyId": obsConf.AccessKeyId, "originPolicy": result.OriginPolicy, "policy": result.Policy, "signature": result.Signature, "host": fmt.Sprintf("//%s.%s", bucketName, obsConf.Endpoint), "key": fkey, } return out, nil } func ServiceObsList(c *gin.Context, apictx *ApiSession) (interface{}, error) { prefix := c.Query("prefix") if len(prefix) < 1 { return nil, NewError("prefix不能为空") } client, err := CreateObsClient() if err != nil { return nil, NewError("创建ObsClient 失败!") } defer func() { client.Close() }() bucketName := apictx.Svc.Conf.Obs.Bucket result, err := client.ListObjects(&obs.ListObjectsInput{ Bucket: bucketName, ListObjsInput: obs.ListObjsInput{ Prefix: prefix, Delimiter: "/", }, }) if err != nil { return nil, err } fmt.Println("result=>", prefix) fmt.Println(result.CommonPrefixes, result.IsTruncated) out := []*model.ObsItem{} imgExts := map[string]bool{".jpeg": true, ".jpg": true, ".gif": true, ".png": true, ".svg": true, ".bmp": true} for k, v := range result.Contents { fmt.Println(k, v.Key, v.LastModified, v.Size) if prefix == v.Key { continue } isDirSuffix := strings.HasSuffix(v.Key, "/") isDir := (isDirSuffix && v.Size == 0) isImage := false originKey := strings.ToLower(v.Key) if !isDir && imgExts[path.Ext(originKey)] { isImage = true } keys := strings.Split(v.Key, "/") name := "" if isDir { name = keys[len(keys)-2] } else { name = keys[len(keys)-1] } obsConf := conf.AppConfig.Obs url := "" if !isDir { url = fmt.Sprintf("//%s.%s/%s", bucketName, obsConf.Endpoint, v.Key) } out = append(out, &model.ObsItem{ Name: name, Size: uint64(v.Size), IsImage: isImage, Url: url, IsDir: isDir, LastModified: v.LastModified, }) } for _, v := range result.CommonPrefixes { keys := strings.Split(v, "/") name := keys[len(keys)-2] out = append(out, &model.ObsItem{ Name: name, IsImage: false, IsDir: true, }) } outMap := map[string]interface{}{ "list": out, "isTruncated": result.IsTruncated, } return outMap, nil } // 管理后台上传文件 func ServiceObsUploadPolicy(c *gin.Context, apictx *ApiSession) (interface{}, error) { body := struct { Key string }{} err := c.ShouldBindJSON(&body) if err != nil { return nil, NewError("参数解析错误!") } if len(body.Key) < 1 { return nil, NewError("上传文件的key不能为空") } client, err := CreateObsClient() if err != nil { return nil, NewError("创建ObsClient 失败!") } defer func() { client.Close() }() bucketName := apictx.Svc.Conf.Obs.Bucket result, err := client.CreateBrowserBasedSignature(&obs.CreateBrowserBasedSignatureInput{ Bucket: bucketName, Key: body.Key, Expires: 600, FormParams: map[string]string{ "x-obs-acl": "public-read", }, }) if err != nil { return nil, NewLogWithError(err) } obsConf := conf.AppConfig.Obs out := map[string]interface{}{ "accessKeyId": obsConf.AccessKeyId, "originPolicy": result.OriginPolicy, "policy": result.Policy, "signature": result.Signature, "host": fmt.Sprintf("https://%s.%s", bucketName, obsConf.Endpoint), "key": body.Key, "saveType": conf.SaveType_Obs, } return out, nil } func ServiceObsRemove(c *gin.Context, apictx *ApiSession) (interface{}, error) { body := struct { Key string }{} err := c.ShouldBindJSON(&body) if err != nil { return nil, NewError("参数解析错误!") } if len(body.Key) < 1 { return nil, NewError("文件的key不能为空") } client, err := CreateObsClient() if err != nil { return nil, NewError("创建ObsClient 失败!") } defer func() { client.Close() }() bucketName := apictx.Svc.Conf.Obs.Bucket result, err := client.DeleteObject(&obs.DeleteObjectInput{ Bucket: bucketName, Key: body.Key, }) if err != nil { return nil, err } return result, nil } func ServiceObsCreateFolder(c *gin.Context, apictx *ApiSession) (interface{}, error) { body := struct { Key string }{} err := c.ShouldBindJSON(&body) if err != nil { return nil, NewError("参数解析错误!") } if len(body.Key) < 1 { return nil, NewError("文件的key不能为空") } client, err := CreateObsClient() if err != nil { return nil, NewError("创建ObsClient 失败!") } defer func() { client.Close() }() bucketName := apictx.Svc.Conf.Obs.Bucket result, err := client.PutObject(&obs.PutObjectInput{ PutObjectBasicInput: obs.PutObjectBasicInput{ ObjectOperationInput: obs.ObjectOperationInput{ Bucket: bucketName, Key: body.Key, ACL: obs.AclPublicRead, }, }, }) if err != nil { return nil, err } return result, nil } func UploadFile(obsClient *obs.ObsClient, bucketName string, fpath string, obsDir string) *model.OssType { _, obsname := path.Split(fpath) keyFormat := "%s/%s" if strings.HasSuffix(obsDir, "/") { keyFormat = "%s%s" } obsKey := fmt.Sprintf(keyFormat, obsDir, obsname) input := &obs.PutFileInput{} input.Bucket = bucketName input.Key = obsKey input.SourceFile = fpath fpathExt := path.Ext(fpath) isGzFile := fpathExt == ".gz" if isGzFile { input.ContentType = "text/plain" input.Metadata = map[string]string{"Content-Encoding": "gzip"} } result, err := obsClient.PutFile(input) isUploadOk := true if err != nil { log.Errorf("upload obs fail %s", fpath) log.Error(err) isUploadOk = false } if result.StatusCode != 200 { isUploadOk = false } if !isUploadOk { result, err = obsClient.PutFile(input) if err != nil { log.Errorf("upload obs fail2 %s", fpath) log.Error(err) return &model.OssType{} } if result.StatusCode != 200 { return &model.OssType{} } } if isGzFile { metaRet, err := obsClient.SetObjectMetadata(&obs.SetObjectMetadataInput{ Bucket: bucketName, Key: obsKey, ContentEncoding: "gzip", ContentType: "text/plain", }) fmt.Println(metaRet, err) if err != nil { metaRet, err = obsClient.SetObjectMetadata(&obs.SetObjectMetadataInput{ Bucket: bucketName, Key: obsKey, ContentEncoding: "gzip", ContentType: "text/plain", }) fmt.Println(metaRet, err) } } fi, err := os.Stat(fpath) size := int64(1) if err == nil { size = fi.Size() } obsConf := conf.AppConfig.Obs return &model.OssType{Url: fmt.Sprintf("//%s.%s/%s", bucketName, obsConf.Endpoint, obsKey), Size: int64(size)} }