diff --git a/config.yaml.sample b/config.yaml.sample index 4b66e9e8..e765a454 100644 --- a/config.yaml.sample +++ b/config.yaml.sample @@ -61,6 +61,11 @@ S3: # Amazon S3 存储配置 Endpoint: s3.amazonaws.com Bucket: paopao Domain: +LocalOSS: # 本地文件OSS存储配置 + SavePath: data/paopao-ce/oss + Secure: False + Bucket: paopao + Domain: 127.0.0.1:8008 MySQL: # MySQL数据库 Username: paopao Password: paopao diff --git a/global/setting.go b/global/setting.go index 75889707..73a3b8be 100644 --- a/global/setting.go +++ b/global/setting.go @@ -19,6 +19,7 @@ var ( AliOSSSetting *setting.AliOSSSettingS MinIOSetting *setting.MinIOSettingS S3Setting *setting.S3SettingS + LocalOSSSetting *setting.LocalOSSSettingS JWTSetting *setting.JWTSettingS LoggerFileSetting *setting.LoggerFileSettingS LoggerZincSetting *setting.LoggerZincSettingS diff --git a/init.go b/init.go index 7cc5369b..d89fe701 100644 --- a/init.go +++ b/init.go @@ -84,6 +84,7 @@ func setupSetting() error { "JWT": &global.JWTSetting, "AliOSS": &global.AliOSSSetting, "MinIO": &global.MinIOSetting, + "LocalOSS": &global.LocalOSSSetting, "S3": &global.S3Setting, } if err = setting.Unmarshal(objects); err != nil { diff --git a/internal/core/assets.go b/internal/core/assets.go index d2bf7228..a0e4eea6 100644 --- a/internal/core/assets.go +++ b/internal/core/assets.go @@ -1,5 +1,5 @@ package core type AttachmentCheckService interface { - Check(cUrl string) error + Check(uri string) error } diff --git a/internal/dao/dao.go b/internal/dao/dao.go index 9f6080a2..47530fb3 100644 --- a/internal/dao/dao.go +++ b/internal/dao/dao.go @@ -14,6 +14,7 @@ var ( _ core.ObjectStorageService = (*aliossServant)(nil) _ core.ObjectStorageService = (*minioServant)(nil) _ core.ObjectStorageService = (*s3Servant)(nil) + _ core.ObjectStorageService = (*localossServant)(nil) _ core.AttachmentCheckService = (*attachmentCheckServant)(nil) ) @@ -22,6 +23,11 @@ type dataServant struct { zinc *zinc.ZincClient } +type localossServant struct { + savePath string + domain string +} + type aliossServant struct { bucket *oss.Bucket domain string @@ -56,6 +62,9 @@ func NewObjectStorageService() (oss core.ObjectStorageService) { } else if global.CfgIf("S3") { oss = newS3Servent() global.Logger.Infoln("use S3 as object storage") + } else if global.CfgIf("LocalOSS") { + oss = newLocalossServent() + global.Logger.Infoln("use LocalOSS as object storage") } else { // default use AliOSS oss = newAliossServent() diff --git a/internal/dao/oss_local.go b/internal/dao/oss_local.go new file mode 100644 index 00000000..333a547d --- /dev/null +++ b/internal/dao/oss_local.go @@ -0,0 +1,71 @@ +package dao + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "time" + + "github.com/rocboss/paopao-ce/global" +) + +func newLocalossServent() *localossServant { + savePath, err := filepath.Abs(global.LocalOSSSetting.SavePath) + if err != nil { + global.Logger.Fatalf("get localOSS save path err: %v", err) + } + + return &localossServant{ + savePath: savePath + "/" + global.LocalOSSSetting.Bucket + "/", + domain: getOssDomain(), + } +} + +func (s *localossServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string) (string, error) { + saveDir := s.savePath + filepath.Dir(objectKey) + err := os.MkdirAll(saveDir, 0750) + if err != nil && !os.IsExist(err) { + return "", err + } + + savePath := s.savePath + objectKey + writer, err := os.Create(savePath) + if err != nil { + return "", err + } + defer writer.Close() + + written, err := io.Copy(writer, reader) + if err != nil { + return "", err + } + if written != objectSize { + os.Remove(savePath) + return "", errors.New("put object not complete") + } + + return s.domain + objectKey, nil +} + +func (s *localossServant) SignURL(objectKey string, expiredInSec int64) (string, error) { + if expiredInSec < 0 { + return "", fmt.Errorf("invalid expires: %d, expires must bigger than 0", expiredInSec) + } + expiration := time.Now().Unix() + expiredInSec + + // Fixed: Just make things simple and simple now so return an veiry simple sign url. + // Maybe make another process logic for sign url in future but not now. + uri := fmt.Sprintf("%s%s?expired=%d", s.domain, objectKey, expiration) + return uri, nil +} + +func (s *localossServant) ObjectURL(objetKey string) string { + return s.domain + objetKey +} + +func (s *localossServant) ObjectKey(objectUrl string) string { + return strings.Replace(objectUrl, s.domain, "", -1) +} diff --git a/internal/dao/utils.go b/internal/dao/utils.go index e7d37f55..2185adbe 100644 --- a/internal/dao/utils.go +++ b/internal/dao/utils.go @@ -19,6 +19,11 @@ func getOssDomain() string { } // TODO: will not work well need test in real world return uri + global.S3Setting.Domain + "/" + global.S3Setting.Bucket + "/" + } else if global.CfgIf("LocalOSS") { + if !global.LocalOSSSetting.Secure { + uri = "http://" + } + return uri + global.LocalOSSSetting.Domain + "/oss/" + global.LocalOSSSetting.Bucket + "/" } - return "" + return uri + global.AliOSSSetting.Domain + "/" } diff --git a/internal/routers/router.go b/internal/routers/router.go index f735bc2a..d290a81d 100644 --- a/internal/routers/router.go +++ b/internal/routers/router.go @@ -2,9 +2,11 @@ package routers import ( "net/http" + "path/filepath" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + "github.com/rocboss/paopao-ce/global" "github.com/rocboss/paopao-ce/internal/middleware" "github.com/rocboss/paopao-ce/internal/routers/api" ) @@ -21,8 +23,11 @@ func NewRouter() *gin.Engine { corsConfig.AddAllowHeaders("Authorization") e.Use(cors.New(corsConfig)) - // 按需注册静态资源路由 - registerStatick(e) + // 按需注册 静态资源、LocalOSS 路由 + { + registerStatick(e) + routeLocalOSS(e) + } // v1 group api r := e.Group("/v1") @@ -184,3 +189,18 @@ func NewRouter() *gin.Engine { }) return e } + +// routeLocalOSS register LocalOSS route if neeed +func routeLocalOSS(e *gin.Engine) { + if !global.CfgIf("LocalOSS") { + return + } + + savePath, err := filepath.Abs(global.LocalOSSSetting.SavePath) + if err != nil { + global.Logger.Fatalf("get localOSS save path err: %v", err) + } + e.Static("/oss", savePath) + + global.Logger.Infof("register LocalOSS route in /oss on save path: %s", savePath) +} diff --git a/pkg/setting/settting.go b/pkg/setting/settting.go index f880247e..d8abaffd 100644 --- a/pkg/setting/settting.go +++ b/pkg/setting/settting.go @@ -107,6 +107,13 @@ type AliOSSSettingS struct { Domain string } +type LocalOSSSettingS struct { + SavePath string + Secure bool + Bucket string + Domain string +} + type RedisSettingS struct { Host string Password string diff --git a/web/build/info.json b/web/build/info.json index a01cac23..f430d3b0 100644 --- a/web/build/info.json +++ b/web/build/info.json @@ -1,4 +1,4 @@ { - "version": "", - "buildTime": "" + "version": "3", + "buildTime": "2022-06-08 23:29:43" } \ No newline at end of file