146 lines
3.7 KiB
Go
146 lines
3.7 KiB
Go
package mysql
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
|
|
"wucher/internal/domain/dul"
|
|
filemanager "wucher/internal/domain/file_manager"
|
|
"wucher/internal/shared/pkg/uuidv7"
|
|
)
|
|
|
|
type DULRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewDULRepository(db *gorm.DB) *DULRepository {
|
|
return &DULRepository{db: db}
|
|
}
|
|
|
|
func (r *DULRepository) WithTransaction(ctx context.Context, fn func(repo dul.Repository) error) error {
|
|
if fn == nil {
|
|
return nil
|
|
}
|
|
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
return fn(&DULRepository{db: tx})
|
|
})
|
|
}
|
|
|
|
func (r *DULRepository) Create(ctx context.Context, row *dul.DUL) error {
|
|
if actor := actorUserIDFromContext(ctx); len(actor) > 0 {
|
|
row.CreatedBy = actor
|
|
row.UpdatedBy = actor
|
|
}
|
|
return r.db.WithContext(ctx).Omit(clause.Associations).Create(row).Error
|
|
}
|
|
|
|
func (r *DULRepository) Update(ctx context.Context, row *dul.DUL) error {
|
|
if actor := actorUserIDFromContext(ctx); len(actor) > 0 {
|
|
row.UpdatedBy = actor
|
|
}
|
|
return r.db.WithContext(ctx).Omit(clause.Associations).Save(row).Error
|
|
}
|
|
|
|
func (r *DULRepository) Delete(ctx context.Context, id []byte) error {
|
|
updates := map[string]any{"deleted_at": time.Now().UTC()}
|
|
if actor := actorUserIDFromContext(ctx); len(actor) > 0 {
|
|
updates["deleted_by"] = actor
|
|
updates["updated_by"] = actor
|
|
}
|
|
return r.db.WithContext(ctx).Model(&dul.DUL{}).Where("id = ? AND deleted_at IS NULL", id).Updates(updates).Error
|
|
}
|
|
|
|
func (r *DULRepository) GetByID(ctx context.Context, id []byte) (*dul.DUL, error) {
|
|
var row dul.DUL
|
|
err := r.db.WithContext(ctx).
|
|
Preload("Base").
|
|
Preload("Base.BaseCategory").
|
|
Where("id = ? AND deleted_at IS NULL", id).
|
|
First(&row).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_ = r.loadImages(ctx, []*dul.DUL{&row})
|
|
return &row, nil
|
|
}
|
|
|
|
func (r *DULRepository) List(ctx context.Context, filter, sort string, limit, offset int, baseIDs [][]byte) ([]dul.DUL, int64, error) {
|
|
var rows []dul.DUL
|
|
var total int64
|
|
|
|
query := r.db.WithContext(ctx).Model(&dul.DUL{}).Where("deleted_at IS NULL")
|
|
if len(baseIDs) > 0 {
|
|
query = query.Where("base_id IN ?", baseIDs)
|
|
}
|
|
if s := strings.TrimSpace(filter); s != "" {
|
|
like := "%" + s + "%"
|
|
query = query.Where("name LIKE ? OR info LIKE ?", like, like)
|
|
}
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if strings.TrimSpace(sort) != "" {
|
|
query = query.Order(sort)
|
|
} else {
|
|
query = query.Order("base_id ASC").Order("no ASC")
|
|
}
|
|
if limit > 0 {
|
|
query = query.Limit(limit).Offset(offset)
|
|
}
|
|
if err := query.Preload("Base").Preload("Base.BaseCategory").Find(&rows).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
ptrs := make([]*dul.DUL, 0, len(rows))
|
|
for i := range rows {
|
|
ptrs = append(ptrs, &rows[i])
|
|
}
|
|
_ = r.loadImages(ctx, ptrs)
|
|
return rows, total, nil
|
|
}
|
|
|
|
func (r *DULRepository) loadImages(ctx context.Context, rows []*dul.DUL) error {
|
|
if len(rows) == 0 {
|
|
return nil
|
|
}
|
|
refIDs := make([]string, 0, len(rows))
|
|
byRef := map[string]*dul.DUL{}
|
|
for _, row := range rows {
|
|
if row == nil || len(row.ID) != 16 {
|
|
continue
|
|
}
|
|
refID, _ := uuidv7.BytesToString(row.ID)
|
|
refIDs = append(refIDs, refID)
|
|
byRef[refID] = row
|
|
row.Images = nil
|
|
}
|
|
if len(refIDs) == 0 {
|
|
return nil
|
|
}
|
|
var attachments []filemanager.Attachment
|
|
if err := r.db.WithContext(ctx).
|
|
Preload("File").
|
|
Where("ref_type = ? AND ref_id IN ?", "dul", refIDs).
|
|
Order("sort_order ASC, created_at ASC").
|
|
Find(&attachments).Error; err != nil {
|
|
return err
|
|
}
|
|
for i := range attachments {
|
|
att := attachments[i]
|
|
row := byRef[att.RefID]
|
|
if row == nil {
|
|
continue
|
|
}
|
|
clone := att
|
|
row.Images = append(row.Images, &clone)
|
|
}
|
|
return nil
|
|
}
|