use the request context

This commit is contained in:
MaysWind
2025-08-02 00:10:12 +08:00
parent 56a3905df1
commit cad53d0bfc
8 changed files with 59 additions and 54 deletions
+3
View File
@@ -1,7 +1,10 @@
package core package core
import "context"
// Context is the base context of ezBookkeeping // Context is the base context of ezBookkeeping
type Context interface { type Context interface {
context.Context
GetContextId() string GetContextId() string
GetClientLocale() string GetClientLocale() string
} }
+17 -16
View File
@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/datastore" "github.com/mayswind/ezbookkeeping/pkg/datastore"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/mail" "github.com/mayswind/ezbookkeeping/pkg/mail"
@@ -98,43 +99,43 @@ type ServiceUsingStorage struct {
} }
// ExistsAvatar returns whether the user avatar exists from the current avatar object storage // ExistsAvatar returns whether the user avatar exists from the current avatar object storage
func (s *ServiceUsingStorage) ExistsAvatar(uid int64, fileExtension string) (bool, error) { func (s *ServiceUsingStorage) ExistsAvatar(ctx core.Context, uid int64, fileExtension string) (bool, error) {
return s.container.ExistsAvatar(s.getUserAvatarPath(uid, fileExtension)) return s.container.ExistsAvatar(ctx, s.getUserAvatarPath(uid, fileExtension))
} }
// ReadAvatar returns the user avatar from the current avatar object storage // ReadAvatar returns the user avatar from the current avatar object storage
func (s *ServiceUsingStorage) ReadAvatar(uid int64, fileExtension string) (storage.ObjectInStorage, error) { func (s *ServiceUsingStorage) ReadAvatar(ctx core.Context, uid int64, fileExtension string) (storage.ObjectInStorage, error) {
return s.container.ReadAvatar(s.getUserAvatarPath(uid, fileExtension)) return s.container.ReadAvatar(ctx, s.getUserAvatarPath(uid, fileExtension))
} }
// SaveAvatar returns whether save the user avatar into the current avatar object storage successfully // SaveAvatar returns whether save the user avatar into the current avatar object storage successfully
func (s *ServiceUsingStorage) SaveAvatar(uid int64, object storage.ObjectInStorage, fileExtension string) error { func (s *ServiceUsingStorage) SaveAvatar(ctx core.Context, uid int64, object storage.ObjectInStorage, fileExtension string) error {
return s.container.SaveAvatar(s.getUserAvatarPath(uid, fileExtension), object) return s.container.SaveAvatar(ctx, s.getUserAvatarPath(uid, fileExtension), object)
} }
// DeleteAvatar returns whether delete the user avatar from the current avatar object storage successfully // DeleteAvatar returns whether delete the user avatar from the current avatar object storage successfully
func (s *ServiceUsingStorage) DeleteAvatar(uid int64, fileExtension string) error { func (s *ServiceUsingStorage) DeleteAvatar(ctx core.Context, uid int64, fileExtension string) error {
return s.container.DeleteAvatar(s.getUserAvatarPath(uid, fileExtension)) return s.container.DeleteAvatar(ctx, s.getUserAvatarPath(uid, fileExtension))
} }
// ExistsTransactionPicture returns whether the transaction picture exists from the current transaction picture object storage // ExistsTransactionPicture returns whether the transaction picture exists from the current transaction picture object storage
func (s *ServiceUsingStorage) ExistsTransactionPicture(uid int64, pictureId int64, fileExtension string) (bool, error) { func (s *ServiceUsingStorage) ExistsTransactionPicture(ctx core.Context, uid int64, pictureId int64, fileExtension string) (bool, error) {
return s.container.ExistsTransactionPicture(s.getTransactionPicturePath(uid, pictureId, fileExtension)) return s.container.ExistsTransactionPicture(ctx, s.getTransactionPicturePath(uid, pictureId, fileExtension))
} }
// ReadTransactionPicture returns the transaction picture from the current transaction picture object storage // ReadTransactionPicture returns the transaction picture from the current transaction picture object storage
func (s *ServiceUsingStorage) ReadTransactionPicture(uid int64, pictureId int64, fileExtension string) (storage.ObjectInStorage, error) { func (s *ServiceUsingStorage) ReadTransactionPicture(ctx core.Context, uid int64, pictureId int64, fileExtension string) (storage.ObjectInStorage, error) {
return s.container.ReadTransactionPicture(s.getTransactionPicturePath(uid, pictureId, fileExtension)) return s.container.ReadTransactionPicture(ctx, s.getTransactionPicturePath(uid, pictureId, fileExtension))
} }
// SaveTransactionPicture returns whether save the transaction picture into the current transaction picture object storage successfully // SaveTransactionPicture returns whether save the transaction picture into the current transaction picture object storage successfully
func (s *ServiceUsingStorage) SaveTransactionPicture(uid int64, pictureId int64, object storage.ObjectInStorage, fileExtension string) error { func (s *ServiceUsingStorage) SaveTransactionPicture(ctx core.Context, uid int64, pictureId int64, object storage.ObjectInStorage, fileExtension string) error {
return s.container.SaveTransactionPicture(s.getTransactionPicturePath(uid, pictureId, fileExtension), object) return s.container.SaveTransactionPicture(ctx, s.getTransactionPicturePath(uid, pictureId, fileExtension), object)
} }
// DeleteTransactionPicture returns whether delete the transaction picture from the current transaction picture object storage successfully // DeleteTransactionPicture returns whether delete the transaction picture from the current transaction picture object storage successfully
func (s *ServiceUsingStorage) DeleteTransactionPicture(uid int64, pictureId int64, fileExtension string) error { func (s *ServiceUsingStorage) DeleteTransactionPicture(ctx core.Context, uid int64, pictureId int64, fileExtension string) error {
return s.container.DeleteTransactionPicture(s.getTransactionPicturePath(uid, pictureId, fileExtension)) return s.container.DeleteTransactionPicture(ctx, s.getTransactionPicturePath(uid, pictureId, fileExtension))
} }
func (s *ServiceUsingStorage) getUserAvatarPath(uid int64, fileExtension string) string { func (s *ServiceUsingStorage) getUserAvatarPath(uid int64, fileExtension string) string {
+2 -2
View File
@@ -159,7 +159,7 @@ func (s *TransactionPictureService) GetPictureByPictureId(c core.Context, uid in
return nil, errs.ErrTransactionPictureExtensionInvalid return nil, errs.ErrTransactionPictureExtensionInvalid
} }
pictureFile, err := s.ReadTransactionPicture(pictureInfo.Uid, pictureInfo.PictureId, pictureInfo.PictureExtension) pictureFile, err := s.ReadTransactionPicture(c, pictureInfo.Uid, pictureInfo.PictureId, pictureInfo.PictureExtension)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, errs.ErrTransactionPictureNoExists return nil, errs.ErrTransactionPictureNoExists
@@ -199,7 +199,7 @@ func (s *TransactionPictureService) UploadPicture(c core.Context, pictureInfo *m
pictureInfo.CreatedUnixTime = time.Now().Unix() pictureInfo.CreatedUnixTime = time.Now().Unix()
pictureInfo.UpdatedUnixTime = time.Now().Unix() pictureInfo.UpdatedUnixTime = time.Now().Unix()
err := s.SaveTransactionPicture(pictureInfo.Uid, pictureInfo.PictureId, pictureFile, pictureInfo.PictureExtension) err := s.SaveTransactionPicture(c, pictureInfo.Uid, pictureInfo.PictureId, pictureFile, pictureInfo.PictureExtension)
if err != nil { if err != nil {
return err return err
+4 -4
View File
@@ -162,7 +162,7 @@ func (s *UserService) GetUserAvatar(c core.Context, uid int64, fileExtension str
return nil, errs.ErrUserAvatarExtensionInvalid return nil, errs.ErrUserAvatarExtensionInvalid
} }
avatarFile, err := s.ReadAvatar(user.Uid, user.CustomAvatarType) avatarFile, err := s.ReadAvatar(c, user.Uid, user.CustomAvatarType)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, errs.ErrUserAvatarNoExists return nil, errs.ErrUserAvatarNoExists
@@ -371,7 +371,7 @@ func (s *UserService) UpdateUserAvatar(c core.Context, uid int64, avatarFile mul
defer avatarFile.Close() defer avatarFile.Close()
err := s.SaveAvatar(uid, avatarFile, fileExtension) err := s.SaveAvatar(c, uid, avatarFile, fileExtension)
if err != nil { if err != nil {
return err return err
@@ -394,7 +394,7 @@ func (s *UserService) UpdateUserAvatar(c core.Context, uid int64, avatarFile mul
} }
if fileExtension != oldFileExtension && oldFileExtension != "" { if fileExtension != oldFileExtension && oldFileExtension != "" {
err = s.DeleteAvatar(uid, oldFileExtension) err = s.DeleteAvatar(c, uid, oldFileExtension)
if err != nil { if err != nil {
log.Warnf(c, "[users.UpdateUserAvatar] failed to delete old avatar with extension \"%s\" for user \"uid:%d\", because %s", oldFileExtension, uid, err.Error()) log.Warnf(c, "[users.UpdateUserAvatar] failed to delete old avatar with extension \"%s\" for user \"uid:%d\", because %s", oldFileExtension, uid, err.Error())
@@ -410,7 +410,7 @@ func (s *UserService) RemoveUserAvatar(c core.Context, uid int64, fileExtension
return errs.ErrUserIdInvalid return errs.ErrUserIdInvalid
} }
err := s.DeleteAvatar(uid, fileExtension) err := s.DeleteAvatar(c, uid, fileExtension)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return err return err
+5 -4
View File
@@ -5,6 +5,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/settings" "github.com/mayswind/ezbookkeeping/pkg/settings"
"github.com/mayswind/ezbookkeeping/pkg/utils" "github.com/mayswind/ezbookkeeping/pkg/utils"
) )
@@ -28,17 +29,17 @@ func NewLocalFileSystemObjectStorage(config *settings.Config, pathPrefix string)
} }
// Exists returns whether the file exists // Exists returns whether the file exists
func (s *LocalFileSystemObjectStorage) Exists(path string) (bool, error) { func (s *LocalFileSystemObjectStorage) Exists(ctx core.Context, path string) (bool, error) {
return utils.IsExists(s.getFinalPath(path)) return utils.IsExists(s.getFinalPath(path))
} }
// Read returns the object instance according to specified the file path // Read returns the object instance according to specified the file path
func (s *LocalFileSystemObjectStorage) Read(path string) (ObjectInStorage, error) { func (s *LocalFileSystemObjectStorage) Read(ctx core.Context, path string) (ObjectInStorage, error) {
return os.Open(s.getFinalPath(path)) return os.Open(s.getFinalPath(path))
} }
// Save returns whether save the object instance successfully // Save returns whether save the object instance successfully
func (s *LocalFileSystemObjectStorage) Save(path string, object ObjectInStorage) error { func (s *LocalFileSystemObjectStorage) Save(ctx core.Context, path string, object ObjectInStorage) error {
finalPath := s.getFinalPath(path) finalPath := s.getFinalPath(path)
if err := os.MkdirAll(filepath.Dir(finalPath), os.ModePerm); err != nil { if err := os.MkdirAll(filepath.Dir(finalPath), os.ModePerm); err != nil {
@@ -59,7 +60,7 @@ func (s *LocalFileSystemObjectStorage) Save(path string, object ObjectInStorage)
} }
// Delete returns whether delete the object according to specified the file path successfully // Delete returns whether delete the object according to specified the file path successfully
func (s *LocalFileSystemObjectStorage) Delete(path string) error { func (s *LocalFileSystemObjectStorage) Delete(ctx core.Context, path string) error {
return os.Remove(s.getFinalPath(path)) return os.Remove(s.getFinalPath(path))
} }
+5 -8
View File
@@ -9,6 +9,7 @@ import (
"github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7/pkg/credentials"
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/settings" "github.com/mayswind/ezbookkeeping/pkg/settings"
) )
@@ -64,8 +65,7 @@ func NewMinIOObjectStorage(config *settings.Config, pathPrefix string) (*MinIOOb
} }
// Exists returns whether the file exists // Exists returns whether the file exists
func (s *MinIOObjectStorage) Exists(path string) (bool, error) { func (s *MinIOObjectStorage) Exists(ctx core.Context, path string) (bool, error) {
ctx := context.Background()
objectInfo, err := s.minIOClient.StatObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.StatObjectOptions{}) objectInfo, err := s.minIOClient.StatObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.StatObjectOptions{})
if err == nil && !objectInfo.IsDeleteMarker { if err == nil && !objectInfo.IsDeleteMarker {
@@ -76,22 +76,19 @@ func (s *MinIOObjectStorage) Exists(path string) (bool, error) {
} }
// Read returns the object instance according to specified the file path // Read returns the object instance according to specified the file path
func (s *MinIOObjectStorage) Read(path string) (ObjectInStorage, error) { func (s *MinIOObjectStorage) Read(ctx core.Context, path string) (ObjectInStorage, error) {
ctx := context.Background()
return s.minIOClient.GetObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.GetObjectOptions{}) return s.minIOClient.GetObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.GetObjectOptions{})
} }
// Save returns whether save the object instance successfully // Save returns whether save the object instance successfully
func (s *MinIOObjectStorage) Save(path string, object ObjectInStorage) error { func (s *MinIOObjectStorage) Save(ctx core.Context, path string, object ObjectInStorage) error {
ctx := context.Background()
_, err := s.minIOClient.PutObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), object, -1, minio.PutObjectOptions{}) _, err := s.minIOClient.PutObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), object, -1, minio.PutObjectOptions{})
return err return err
} }
// Delete returns whether delete the object according to specified the file path successfully // Delete returns whether delete the object according to specified the file path successfully
func (s *MinIOObjectStorage) Delete(path string) error { func (s *MinIOObjectStorage) Delete(ctx core.Context, path string) error {
ctx := context.Background()
return s.minIOClient.RemoveObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.RemoveObjectOptions{}) return s.minIOClient.RemoveObject(ctx, s.minIOConfig.Bucket, s.getFinalPath(path), minio.RemoveObjectOptions{})
} }
+6 -4
View File
@@ -1,9 +1,11 @@
package storage package storage
import "github.com/mayswind/ezbookkeeping/pkg/core"
// ObjectStorage represents an object storage to store file object // ObjectStorage represents an object storage to store file object
type ObjectStorage interface { type ObjectStorage interface {
Exists(path string) (bool, error) Exists(ctx core.Context, path string) (bool, error)
Read(path string) (ObjectInStorage, error) Read(ctx core.Context, path string) (ObjectInStorage, error)
Save(path string, object ObjectInStorage) error Save(ctx core.Context, path string, object ObjectInStorage) error
Delete(path string) error Delete(ctx core.Context, path string) error
} }
+17 -16
View File
@@ -1,6 +1,7 @@
package storage package storage
import ( import (
"github.com/mayswind/ezbookkeeping/pkg/core"
"github.com/mayswind/ezbookkeeping/pkg/errs" "github.com/mayswind/ezbookkeeping/pkg/errs"
"github.com/mayswind/ezbookkeeping/pkg/settings" "github.com/mayswind/ezbookkeeping/pkg/settings"
) )
@@ -41,43 +42,43 @@ func InitializeStorageContainer(config *settings.Config) error {
} }
// ExistsAvatar returns whether the avatar file exists from the current avatar object storage // ExistsAvatar returns whether the avatar file exists from the current avatar object storage
func (s *StorageContainer) ExistsAvatar(path string) (bool, error) { func (s *StorageContainer) ExistsAvatar(ctx core.Context, path string) (bool, error) {
return s.AvatarCurrentStorage.Exists(path) return s.AvatarCurrentStorage.Exists(ctx, path)
} }
// ReadAvatar returns the avatar file from the current avatar object storage // ReadAvatar returns the avatar file from the current avatar object storage
func (s *StorageContainer) ReadAvatar(path string) (ObjectInStorage, error) { func (s *StorageContainer) ReadAvatar(ctx core.Context, path string) (ObjectInStorage, error) {
return s.AvatarCurrentStorage.Read(path) return s.AvatarCurrentStorage.Read(ctx, path)
} }
// SaveAvatar returns whether save the avatar file into the current avatar object storage successfully // SaveAvatar returns whether save the avatar file into the current avatar object storage successfully
func (s *StorageContainer) SaveAvatar(path string, object ObjectInStorage) error { func (s *StorageContainer) SaveAvatar(ctx core.Context, path string, object ObjectInStorage) error {
return s.AvatarCurrentStorage.Save(path, object) return s.AvatarCurrentStorage.Save(ctx, path, object)
} }
// DeleteAvatar returns whether delete the avatar file from the current avatar object storage successfully // DeleteAvatar returns whether delete the avatar file from the current avatar object storage successfully
func (s *StorageContainer) DeleteAvatar(path string) error { func (s *StorageContainer) DeleteAvatar(ctx core.Context, path string) error {
return s.AvatarCurrentStorage.Delete(path) return s.AvatarCurrentStorage.Delete(ctx, path)
} }
// ExistsTransactionPicture returns whether the transaction picture file exists from the current transaction picture object storage // ExistsTransactionPicture returns whether the transaction picture file exists from the current transaction picture object storage
func (s *StorageContainer) ExistsTransactionPicture(path string) (bool, error) { func (s *StorageContainer) ExistsTransactionPicture(ctx core.Context, path string) (bool, error) {
return s.TransactionPictureCurrentStorage.Exists(path) return s.TransactionPictureCurrentStorage.Exists(ctx, path)
} }
// ReadTransactionPicture returns the transaction picture file from the current transaction picture object storage // ReadTransactionPicture returns the transaction picture file from the current transaction picture object storage
func (s *StorageContainer) ReadTransactionPicture(path string) (ObjectInStorage, error) { func (s *StorageContainer) ReadTransactionPicture(ctx core.Context, path string) (ObjectInStorage, error) {
return s.TransactionPictureCurrentStorage.Read(path) return s.TransactionPictureCurrentStorage.Read(ctx, path)
} }
// SaveTransactionPicture returns whether save the transaction picture file into the current transaction picture object storage successfully // SaveTransactionPicture returns whether save the transaction picture file into the current transaction picture object storage successfully
func (s *StorageContainer) SaveTransactionPicture(path string, object ObjectInStorage) error { func (s *StorageContainer) SaveTransactionPicture(ctx core.Context, path string, object ObjectInStorage) error {
return s.TransactionPictureCurrentStorage.Save(path, object) return s.TransactionPictureCurrentStorage.Save(ctx, path, object)
} }
// DeleteTransactionPicture returns whether delete the transaction picture file from the current transaction picture object storage successfully // DeleteTransactionPicture returns whether delete the transaction picture file from the current transaction picture object storage successfully
func (s *StorageContainer) DeleteTransactionPicture(path string) error { func (s *StorageContainer) DeleteTransactionPicture(ctx core.Context, path string) error {
return s.TransactionPictureCurrentStorage.Delete(path) return s.TransactionPictureCurrentStorage.Delete(ctx, path)
} }
func newObjectStorage(config *settings.Config, pathPrefix string) (ObjectStorage, error) { func newObjectStorage(config *settings.Config, pathPrefix string) (ObjectStorage, error) {