Files
geo/server/internal/tenant/repository/image_repo.go
T
root 27389164b0 feat: add image management functionality
- Implemented image folder repository with CRUD operations.
- Added image reference repository for managing image references to articles.
- Created image repository for handling image assets, including listing, inserting, updating, and deleting images.
- Introduced image usage repository to track storage usage and quotas for tenants.
- Added SQL queries for image assets, folders, references, and usage.
- Developed image handler for HTTP endpoints to manage images and folders.
- Created database migration scripts for image-related tables and structures.
2026-04-16 20:40:41 +08:00

210 lines
5.6 KiB
Go

package repository
import (
"context"
"time"
"github.com/geo-platform/tenant-api/internal/tenant/repository/generated"
)
type ImageAsset struct {
ID int64
TenantID int64
FolderID *int64
ObjectKey string
Name string
SizeBytes int64
Status string
CreatedBy int64
CreatedAt time.Time
UpdatedAt time.Time
}
type ImageAssetListParams struct {
TenantID int64
FolderID *int64
SearchQuery *string
PageSize int
PageOffset int
}
type InsertImageAssetInput struct {
TenantID int64
FolderID *int64
ObjectKey string
Name string
SizeBytes int64
Status string
CreatedBy int64
}
type FolderImageSummary struct {
ID int64
ObjectKey string
SizeBytes int64
}
type ImageRepository interface {
List(ctx context.Context, params ImageAssetListParams) ([]ImageAsset, int, error)
Get(ctx context.Context, tenantID, id int64) (*ImageAsset, error)
Insert(ctx context.Context, input InsertImageAssetInput) (int64, error)
UpdateStatus(ctx context.Context, tenantID, id int64, status string) error
MarkDeleted(ctx context.Context, tenantID, id int64) error
UpdateName(ctx context.Context, tenantID, id int64, name string) error
UpdateFolder(ctx context.Context, tenantID, id int64, folderID *int64) error
ListActiveByFolder(ctx context.Context, tenantID, folderID int64) ([]FolderImageSummary, error)
MarkImagesInFolderPendingDelete(ctx context.Context, tenantID, folderID int64) error
CountUncategorized(ctx context.Context, tenantID int64) (int, error)
}
type imageRepository struct {
q generated.Querier
}
func NewImageRepository(db generated.DBTX) ImageRepository {
return &imageRepository{q: newQuerier(db)}
}
func (r *imageRepository) List(ctx context.Context, params ImageAssetListParams) ([]ImageAsset, int, error) {
listParams := generated.ListImageAssetsParams{
TenantID: params.TenantID,
FolderID: pgInt8(params.FolderID),
PageOffset: int32(params.PageOffset),
PageSize: int32(params.PageSize),
SearchQuery: pgText(params.SearchQuery),
}
rows, err := r.q.ListImageAssets(ctx, listParams)
if err != nil {
return nil, 0, err
}
total, err := r.q.CountImageAssets(ctx, generated.CountImageAssetsParams{
TenantID: params.TenantID,
FolderID: listParams.FolderID,
SearchQuery: listParams.SearchQuery,
})
if err != nil {
return nil, 0, err
}
assets := make([]ImageAsset, len(rows))
for i, row := range rows {
assets[i] = ImageAsset{
ID: row.ID,
TenantID: row.TenantID,
FolderID: nullableInt64(row.FolderID),
ObjectKey: row.ObjectKey,
Name: row.Name,
SizeBytes: row.SizeBytes,
Status: row.Status,
CreatedBy: row.CreatedBy,
CreatedAt: timeFromTimestamp(row.CreatedAt),
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
}
}
return assets, int(total), nil
}
func (r *imageRepository) Get(ctx context.Context, tenantID, id int64) (*ImageAsset, error) {
row, err := r.q.GetImageAsset(ctx, generated.GetImageAssetParams{
ID: id,
TenantID: tenantID,
})
if err != nil {
return nil, err
}
return &ImageAsset{
ID: row.ID,
TenantID: row.TenantID,
FolderID: nullableInt64(row.FolderID),
ObjectKey: row.ObjectKey,
Name: row.Name,
SizeBytes: row.SizeBytes,
Status: row.Status,
CreatedBy: row.CreatedBy,
CreatedAt: timeFromTimestamp(row.CreatedAt),
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
}, nil
}
func (r *imageRepository) Insert(ctx context.Context, input InsertImageAssetInput) (int64, error) {
return r.q.InsertImageAsset(ctx, generated.InsertImageAssetParams{
TenantID: input.TenantID,
FolderID: pgInt8(input.FolderID),
ObjectKey: input.ObjectKey,
Name: input.Name,
SizeBytes: input.SizeBytes,
Status: input.Status,
CreatedBy: input.CreatedBy,
})
}
func (r *imageRepository) UpdateStatus(ctx context.Context, tenantID, id int64, status string) error {
return r.q.UpdateImageAssetStatus(ctx, generated.UpdateImageAssetStatusParams{
Status: status,
ID: id,
TenantID: tenantID,
})
}
func (r *imageRepository) MarkDeleted(ctx context.Context, tenantID, id int64) error {
return r.q.UpdateImageAssetDeleted(ctx, generated.UpdateImageAssetDeletedParams{
ID: id,
TenantID: tenantID,
})
}
func (r *imageRepository) UpdateName(ctx context.Context, tenantID, id int64, name string) error {
return r.q.UpdateImageAssetName(ctx, generated.UpdateImageAssetNameParams{
Name: name,
ID: id,
TenantID: tenantID,
})
}
func (r *imageRepository) UpdateFolder(ctx context.Context, tenantID, id int64, folderID *int64) error {
return r.q.UpdateImageAssetFolder(ctx, generated.UpdateImageAssetFolderParams{
FolderID: pgInt8(folderID),
ID: id,
TenantID: tenantID,
})
}
func (r *imageRepository) ListActiveByFolder(ctx context.Context, tenantID, folderID int64) ([]FolderImageSummary, error) {
rows, err := r.q.ListActiveImagesByFolder(ctx, generated.ListActiveImagesByFolderParams{
TenantID: tenantID,
FolderID: pgInt8(&folderID),
})
if err != nil {
return nil, err
}
result := make([]FolderImageSummary, len(rows))
for i, row := range rows {
result[i] = FolderImageSummary{
ID: row.ID,
ObjectKey: row.ObjectKey,
SizeBytes: row.SizeBytes,
}
}
return result, nil
}
func (r *imageRepository) MarkImagesInFolderPendingDelete(ctx context.Context, tenantID, folderID int64) error {
return r.q.MarkImagesInFolderPendingDelete(ctx, generated.MarkImagesInFolderPendingDeleteParams{
TenantID: tenantID,
FolderID: pgInt8(&folderID),
})
}
func (r *imageRepository) CountUncategorized(ctx context.Context, tenantID int64) (int, error) {
count, err := r.q.CountUncategorizedImages(ctx, tenantID)
if err != nil {
return 0, err
}
return int(count), nil
}