Files
oneterm/backend/internal/repository/time_template.go
2025-07-16 18:11:04 +08:00

156 lines
4.9 KiB
Go

package repository
import (
"context"
"errors"
"gorm.io/gorm"
"github.com/veops/oneterm/internal/model"
)
// ITimeTemplateRepository defines the interface for time template data access
type ITimeTemplateRepository interface {
Create(ctx context.Context, template *model.TimeTemplate) error
GetByID(ctx context.Context, id int) (*model.TimeTemplate, error)
GetByName(ctx context.Context, name string) (*model.TimeTemplate, error)
List(ctx context.Context, offset, limit int, category string, active *bool) ([]*model.TimeTemplate, int64, error)
Update(ctx context.Context, template *model.TimeTemplate) error
Delete(ctx context.Context, id int) error
IncrementUsage(ctx context.Context, id int) error
GetBuiltInTemplates(ctx context.Context) ([]*model.TimeTemplate, error)
InitBuiltInTemplates(ctx context.Context) error
}
// TimeTemplateRepository implements ITimeTemplateRepository
type TimeTemplateRepository struct {
db *gorm.DB
}
// NewTimeTemplateRepository creates a new time template repository
func NewTimeTemplateRepository(db *gorm.DB) ITimeTemplateRepository {
return &TimeTemplateRepository{db: db}
}
// Create creates a new time template
func (r *TimeTemplateRepository) Create(ctx context.Context, template *model.TimeTemplate) error {
return r.db.WithContext(ctx).Create(template).Error
}
// GetByID retrieves a time template by ID
func (r *TimeTemplateRepository) GetByID(ctx context.Context, id int) (*model.TimeTemplate, error) {
var template model.TimeTemplate
err := r.db.WithContext(ctx).Where("id = ?", id).First(&template).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &template, nil
}
// GetByName retrieves a time template by name
func (r *TimeTemplateRepository) GetByName(ctx context.Context, name string) (*model.TimeTemplate, error) {
var template model.TimeTemplate
err := r.db.WithContext(ctx).Where("name = ?", name).First(&template).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &template, nil
}
// List retrieves time templates with pagination and filters
func (r *TimeTemplateRepository) List(ctx context.Context, offset, limit int, category string, active *bool) ([]*model.TimeTemplate, int64, error) {
query := r.db.WithContext(ctx).Model(&model.TimeTemplate{})
// Apply filters
if category != "" {
query = query.Where("category = ?", category)
}
if active != nil {
query = query.Where("is_active = ?", *active)
}
// Get total count
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// Apply pagination and ordering
var templates []*model.TimeTemplate
err := query.Order("is_builtin DESC, usage_count DESC, created_at DESC").
Offset(offset).
Limit(limit).
Find(&templates).Error
return templates, total, err
}
// Update updates an existing time template
func (r *TimeTemplateRepository) Update(ctx context.Context, template *model.TimeTemplate) error {
// Don't allow updating built-in templates
if template.IsBuiltIn {
return errors.New("cannot update built-in time template")
}
return r.db.WithContext(ctx).Save(template).Error
}
// Delete soft deletes a time template
func (r *TimeTemplateRepository) Delete(ctx context.Context, id int) error {
// Check if it's a built-in template
var template model.TimeTemplate
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&template).Error; err != nil {
return err
}
if template.IsBuiltIn {
return errors.New("cannot delete built-in time template")
}
return r.db.WithContext(ctx).Delete(&model.TimeTemplate{}, id).Error
}
// IncrementUsage increments the usage count of a time template
func (r *TimeTemplateRepository) IncrementUsage(ctx context.Context, id int) error {
return r.db.WithContext(ctx).Model(&model.TimeTemplate{}).
Where("id = ?", id).
UpdateColumn("usage_count", gorm.Expr("usage_count + 1")).Error
}
// GetBuiltInTemplates retrieves all built-in time templates
func (r *TimeTemplateRepository) GetBuiltInTemplates(ctx context.Context) ([]*model.TimeTemplate, error) {
var templates []*model.TimeTemplate
err := r.db.WithContext(ctx).Where("is_builtin = ?", true).
Order("category, id").
Find(&templates).Error
return templates, err
}
// InitBuiltInTemplates initializes built-in time templates
func (r *TimeTemplateRepository) InitBuiltInTemplates(ctx context.Context) error {
// Check if built-in templates already exist
var count int64
r.db.WithContext(ctx).Model(&model.TimeTemplate{}).Where("is_builtin = ?", true).Count(&count)
if count > 0 {
// Built-in templates already exist, skip initialization
return nil
}
// Create built-in templates
for _, template := range model.BuiltInTimeTemplates {
// Create a copy to avoid modifying the original
newTemplate := template
if err := r.db.WithContext(ctx).Create(&newTemplate).Error; err != nil {
return err
}
}
return nil
}