diff --git a/api/core/config.go b/api/core/config.go index 00c2f7a2..bf387d30 100644 --- a/api/core/config.go +++ b/api/core/config.go @@ -35,6 +35,13 @@ func NewDefaultConfig() *types.AppConfig { }, ApiConfig: types.ChatPlusApiConfig{}, ExtConfig: types.ChatPlusExtConfig{Token: utils.RandString(32)}, + OSS: types.OSSConfig{ + Active: "local", + Local: types.LocalStorageConfig{ + BaseURL: "http://localhost/5678/static/upload", + BasePath: "./static/upload", + }, + }, } } diff --git a/api/handler/upload_handler.go b/api/handler/upload_handler.go index 08baedf8..2a0e1cbb 100644 --- a/api/handler/upload_handler.go +++ b/api/handler/upload_handler.go @@ -22,7 +22,7 @@ func NewUploadHandler(app *core.AppServer, db *gorm.DB, manager *oss.UploaderMan } func (h *UploadHandler) Upload(c *gin.Context) { - fileURL, err := h.uploaderManager.GetActiveService().PutFile(c) + fileURL, err := h.uploaderManager.GetActiveService().PutFile(c, "file") if err != nil { resp.ERROR(c, fmt.Sprintf("文件上传失败: %s", err.Error())) return diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go index 772c5edc..7e21dd44 100644 --- a/api/handler/user_handler.go +++ b/api/handler/user_handler.go @@ -3,6 +3,7 @@ package handler import ( "chatplus/core" "chatplus/core/types" + "chatplus/service/oss" "chatplus/store" "chatplus/store/model" "chatplus/store/vo" @@ -20,13 +21,19 @@ import ( type UserHandler struct { BaseHandler - db *gorm.DB - searcher *xdb.Searcher - leveldb *store.LevelDB + db *gorm.DB + searcher *xdb.Searcher + leveldb *store.LevelDB + uploadManager *oss.UploaderManager } -func NewUserHandler(app *core.AppServer, db *gorm.DB, searcher *xdb.Searcher, levelDB *store.LevelDB) *UserHandler { - handler := &UserHandler{db: db, searcher: searcher, leveldb: levelDB} +func NewUserHandler( + app *core.AppServer, + db *gorm.DB, + searcher *xdb.Searcher, + levelDB *store.LevelDB, + manager *oss.UploaderManager) *UserHandler { + handler := &UserHandler{db: db, searcher: searcher, leveldb: levelDB, uploadManager: manager} handler.App = app return handler } @@ -256,6 +263,7 @@ func (h *UserHandler) ProfileUpdate(c *gin.Context) { } h.db.First(&user, user.Id) user.Nickname = data.Nickname + oldAvatar := user.Avatar user.Avatar = data.Avatar var chatConfig types.ChatConfig @@ -278,6 +286,14 @@ func (h *UserHandler) ProfileUpdate(c *gin.Context) { resp.ERROR(c, "更新用户信息失败") return } + + // remove the old avatar image file + if oldAvatar != data.Avatar { + err = h.uploadManager.GetActiveService().Delete(oldAvatar) + if err != nil { + logger.Error("error with delete image: ", err) + } + } resp.SUCCESS(c) } diff --git a/api/service/oss/localstorage_service.go b/api/service/oss/localstorage_service.go index 853a2686..f51a2664 100644 --- a/api/service/oss/localstorage_service.go +++ b/api/service/oss/localstorage_service.go @@ -5,7 +5,9 @@ import ( "chatplus/utils" "fmt" "github.com/gin-gonic/gin" + "os" "path/filepath" + "strings" ) type LocalStorageService struct { @@ -20,8 +22,8 @@ func NewLocalStorageService(config *types.AppConfig) LocalStorageService { } } -func (s LocalStorageService) PutFile(ctx *gin.Context) (string, error) { - file, err := ctx.FormFile("file") +func (s LocalStorageService) PutFile(ctx *gin.Context, name string) (string, error) { + file, err := ctx.FormFile(name) if err != nil { return "", fmt.Errorf("error with get form: %v", err) } @@ -54,4 +56,9 @@ func (s LocalStorageService) PutImg(imageURL string) (string, error) { return utils.GenUploadUrl(s.config.BasePath, s.config.BaseURL, filePath), nil } +func (s LocalStorageService) Delete(fileURL string) error { + filePath := strings.Replace(fileURL, s.config.BaseURL, s.config.BasePath, 1) + return os.Remove(filePath) +} + var _ Uploader = LocalStorageService{} diff --git a/api/service/oss/minio_service.go b/api/service/oss/minio_service.go index b431a238..c898189f 100644 --- a/api/service/oss/minio_service.go +++ b/api/service/oss/minio_service.go @@ -37,7 +37,7 @@ func (s MinioService) PutImg(imageURL string) (string, error) { return "", fmt.Errorf("error with download image: %v", err) } fileExt := filepath.Ext(filepath.Base(imageURL)) - filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), fileExt) + filename := fmt.Sprintf("%d%s", time.Now().UnixMicro(), fileExt) info, err := s.client.PutObject( context.Background(), s.config.Bucket, @@ -51,8 +51,8 @@ func (s MinioService) PutImg(imageURL string) (string, error) { return fmt.Sprintf("%s/%s/%s", s.config.Domain, s.config.Bucket, info.Key), nil } -func (s MinioService) PutFile(ctx *gin.Context) (string, error) { - file, err := ctx.FormFile("file") +func (s MinioService) PutFile(ctx *gin.Context, name string) (string, error) { + file, err := ctx.FormFile(name) if err != nil { return "", fmt.Errorf("error with get form: %v", err) } @@ -64,7 +64,7 @@ func (s MinioService) PutFile(ctx *gin.Context) (string, error) { defer fileReader.Close() fileExt := filepath.Ext(file.Filename) - filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), fileExt) + filename := fmt.Sprintf("%d%s", time.Now().UnixMicro(), fileExt) info, err := s.client.PutObject(ctx, s.config.Bucket, filename, fileReader, file.Size, minio.PutObjectOptions{ ContentType: file.Header.Get("Content-Type"), }) @@ -75,4 +75,9 @@ func (s MinioService) PutFile(ctx *gin.Context) (string, error) { return fmt.Sprintf("%s/%s/%s", s.config.Domain, s.config.Bucket, info.Key), nil } +func (s MinioService) Delete(fileURL string) error { + objectName := filepath.Base(fileURL) + return s.client.RemoveObject(context.Background(), s.config.Bucket, objectName, minio.RemoveObjectOptions{}) +} + var _ Uploader = MinioService{} diff --git a/api/service/oss/uploader.go b/api/service/oss/uploader.go index 318f5746..1c8df952 100644 --- a/api/service/oss/uploader.go +++ b/api/service/oss/uploader.go @@ -3,6 +3,7 @@ package oss import "github.com/gin-gonic/gin" type Uploader interface { - PutFile(ctx *gin.Context) (string, error) + PutFile(ctx *gin.Context, name string) (string, error) PutImg(imageURL string) (string, error) + Delete(fileURL string) error } diff --git a/api/utils/upload.go b/api/utils/upload.go index f614e740..d982c1d8 100644 --- a/api/utils/upload.go +++ b/api/utils/upload.go @@ -14,16 +14,16 @@ import ( // GenUploadPath 生成上传文件路径 func GenUploadPath(basePath, filename string) (string, error) { now := time.Now() - dir := fmt.Sprintf("%s/upload/%d/%d", basePath, now.Year(), now.Month()) + dir := fmt.Sprintf("%s/%d/%d", basePath, now.Year(), now.Month()) _, err := os.Stat(dir) if err != nil { err = os.MkdirAll(dir, 0755) if err != nil { - return "", fmt.Errorf("创建上传目录失败:%s", err) + return "", fmt.Errorf("error with create upload dir:%v", err) } } fileExt := filepath.Ext(filename) - return fmt.Sprintf("%s/%d%s", dir, now.UnixNano(), fileExt), nil + return fmt.Sprintf("%s/%d%s", dir, now.UnixMicro(), fileExt), nil } // GenUploadUrl 生成上传文件 URL