feat(storage): add cos support
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -11,14 +10,9 @@ import (
|
||||
"github.com/go-playground/validator"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var ENVS = [][2]string{
|
||||
{"本地测试环境", "http://localhost:8080"},
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
IsLocal bool
|
||||
Debug bool `mapstructure:"debug"`
|
||||
@@ -36,33 +30,6 @@ type Config struct {
|
||||
}
|
||||
}
|
||||
|
||||
type ossConfig struct {
|
||||
Schema string
|
||||
Endpoint string
|
||||
AccessID string
|
||||
AccessSecret string
|
||||
Region string
|
||||
Bucket string
|
||||
Secure bool
|
||||
}
|
||||
|
||||
func (c *Config) GetOSSConfig() *ossConfig {
|
||||
oss, err := url.Parse(c.Databases.OSS)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("parse oss config error")
|
||||
}
|
||||
accessSecret, _ := oss.User.Password()
|
||||
return &ossConfig{
|
||||
Schema: oss.Scheme,
|
||||
Endpoint: oss.Host,
|
||||
AccessID: oss.User.Username(),
|
||||
AccessSecret: accessSecret,
|
||||
Region: oss.Query().Get("region"),
|
||||
Bucket: oss.Query().Get("bucket"),
|
||||
Secure: cast.ToBool(oss.Query().Get("secure")),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
c *Config
|
||||
once sync.Once
|
||||
|
||||
@@ -23,3 +23,7 @@ const (
|
||||
LogTagStaffID = "staff_id"
|
||||
LogTagTraceID = "trace_id"
|
||||
)
|
||||
|
||||
var ENVS = [][2]string{
|
||||
{"本地测试环境", "http://localhost:8080"},
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package model
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"octopus/internal/config"
|
||||
"octopus/internal/dal"
|
||||
"time"
|
||||
|
||||
@@ -37,15 +36,14 @@ type Doc struct {
|
||||
IsDeletable bool `gorm:"column:is_deletable;type:boolean;not null;default:true"` // 是否允许被删除
|
||||
IsEditable bool `gorm:"column:is_editable;type:boolean;not null;default:true"` // 是否允许编辑名称
|
||||
FolderID string `gorm:"column:folder_id;type:varchar;index:idx_folder_id"` // 文件夹ID
|
||||
OSSObjectID string `gorm:"column:oss_object_id;type:varchar"` // OSS Object ID
|
||||
ObjectName string `gorm:"column:object_name;type:varchar"` // 对象存储中对应的object_name
|
||||
CreatedBy string `gorm:"column:created_by;type:varchar;not null"` // 创建人
|
||||
|
||||
Folder *DocFolder `gorm:"foreignKey:FolderID;references:ID"`
|
||||
}
|
||||
|
||||
func (df *Doc) PresignedURL(ctx context.Context) (*url.URL, error) {
|
||||
bucket := config.Get().GetOSSConfig().Bucket
|
||||
return dal.GetMinio().PresignedGetObject(ctx, bucket, df.OSSObjectID, time.Hour, nil)
|
||||
return dal.GetStorage().PresignedGetObject(ctx, df.ObjectName, time.Hour)
|
||||
}
|
||||
|
||||
func (*Doc) TableName() string {
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"octopus/internal/config"
|
||||
"sync"
|
||||
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
"github.com/rs/zerolog/log"
|
||||
// pb "github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
var (
|
||||
ossOnce sync.Once
|
||||
ossInstance *minio.Client
|
||||
)
|
||||
|
||||
func GetMinio() *minio.Client {
|
||||
ossOnce.Do(initMinio)
|
||||
return ossInstance
|
||||
}
|
||||
|
||||
func initMinio() {
|
||||
log.Info().Msg("loading minio configs")
|
||||
|
||||
ossConfig, err := url.Parse(config.Get().Databases.OSS)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("parse oss config error")
|
||||
}
|
||||
accessSecret, _ := ossConfig.User.Password()
|
||||
// defaultConfig := &model.StorageConfig{
|
||||
// Schema: ossConfig.Scheme,
|
||||
// Endpoint: ossConfig.Host,
|
||||
// AccessID: ossConfig.User.Username(),
|
||||
// AccessSecret: accessSecret,
|
||||
// Bucket: ossConfig.Query().Get("bucket"),
|
||||
// Region: ossConfig.Query().Get("region"),
|
||||
// Secure: cast.ToBool(ossConfig.Query().Get("secure")),
|
||||
// }
|
||||
minioClient, err := minio.New(ossConfig.Host, &minio.Options{
|
||||
Creds: credentials.NewStaticV4(ossConfig.User.Username(), accessSecret, ""),
|
||||
Secure: false,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal().Msgf("minio client init error: %v", err)
|
||||
}
|
||||
|
||||
ossInstance = minioClient
|
||||
}
|
||||
31
internal/dal/storage.go
Normal file
31
internal/dal/storage.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"octopus/internal/config"
|
||||
"octopus/pkg/storage"
|
||||
"sync"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
// pb "github.com/qdrant/go-client/qdrant"
|
||||
)
|
||||
|
||||
var (
|
||||
storageOnce sync.Once
|
||||
storageInstance storage.ObjectStorage
|
||||
)
|
||||
|
||||
func GetStorage() storage.ObjectStorage {
|
||||
storageOnce.Do(initMinio)
|
||||
return storageInstance
|
||||
}
|
||||
|
||||
func initMinio() {
|
||||
log.Info().Msg("loading minio configs")
|
||||
|
||||
s, err := storage.NewObjectStorage(config.Get().Databases.OSS)
|
||||
if err != nil {
|
||||
log.Fatal().Msgf("storage client init failed: %v", err)
|
||||
}
|
||||
|
||||
storageInstance = s
|
||||
}
|
||||
@@ -29,6 +29,14 @@ func RegisterDocRouter(app *soda.Soda) {
|
||||
SetJSONRequestBody(schema.UpdateDoc{}).
|
||||
AddJSONResponse(200, schema.Doc{}).OK()
|
||||
|
||||
// get presigned url for tmp file upload
|
||||
app.Get("/docs/upload-url", nil).
|
||||
AddTags("文档管理").
|
||||
SetSummary("获取临时上传文件用的预签名URL").
|
||||
AddJWTSecurity(JWTRequired).
|
||||
SetParameters(schema.CreateUploadURL{}).
|
||||
AddJSONResponse(200, schema.UploadURL{}).OK()
|
||||
|
||||
app.Delete("/docs/:id", nil).
|
||||
AddTags("文档管理").
|
||||
SetSummary("获取文档列表").
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"octopus/pkg/tools"
|
||||
"time"
|
||||
|
||||
@@ -63,8 +64,9 @@ type DocID struct {
|
||||
}
|
||||
|
||||
type CreateDoc struct {
|
||||
Name string `json:"name" validate:"required" oai:"description=文档名称"`
|
||||
FolderID string `json:"folder_id" validate:"required" oai:"description=归属文件夹ID"`
|
||||
Name string `json:"name" validate:"required" oai:"description=文档名称"`
|
||||
ObjectName string `json:"object_name" validate:"required" oai:"description=对象存储中对应的文档对象名称"`
|
||||
FolderID string `json:"folder_id" validate:"required" oai:"description=归属文件夹ID"`
|
||||
}
|
||||
|
||||
type UpdateDoc struct {
|
||||
@@ -104,3 +106,12 @@ func (q *ListDocQuery) Validate() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateUploadURL struct {
|
||||
FileName string `query:"file_name" validate:"required" oai:"description=上传文件名"`
|
||||
}
|
||||
|
||||
type UploadURL struct {
|
||||
URL url.URL `json:"url" oai:"description=生成的预签名上传URL"`
|
||||
ObjectName string `json:"object_name" oai:"description=上传文件名"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user