package repository import ( "github.com/rovina/zsp-backend/internal/model" "gorm.io/gorm" ) type ContractRepository interface { CreateWithFiles(contract *model.Contract, files []model.ContractFile) error CreateFiles(files []model.ContractFile) error BatchInsert(files []model.ContractFile) error List(contractType string) ([]model.Contract, error) GetByID(id uint) (*model.Contract, error) Update(contract *model.Contract) error Delete(id uint) error DeleteFilesByContractIDExcept(contractID uint, keepIDs []uint) error UpdateWithFiles(contract *model.Contract, keepFileIDs []uint, newFiles []model.ContractFile) error } type contractRepository struct { db *gorm.DB } func NewContractRepository(db *gorm.DB) ContractRepository { return &contractRepository{db: db} } func (r *contractRepository) CreateFiles(files []model.ContractFile) error { return r.db.Create(&files).Error } func (r *contractRepository) CreateWithFiles(contract *model.Contract, files []model.ContractFile) error { return r.db.Transaction(func(tx *gorm.DB) error { if err := tx.Create(contract).Error; err != nil { return err } for i := range files { files[i].ContractID = contract.ID } if len(files) > 0 { if err := tx.Create(&files).Error; err != nil { return err } } return nil }) } func (r *contractRepository) BatchInsert(files []model.ContractFile) error { return r.db.Create(&files).Error } func (r *contractRepository) List(contractType string) ([]model.Contract, error) { var list []model.Contract query := r.db.Model(&model.Contract{}).Order("create_time DESC") if contractType != "" { query = query.Where("contract_type = ?", contractType) } err := query.Preload("Files").Find(&list).Error return list, err } func (r *contractRepository) GetByID(id uint) (*model.Contract, error) { var c model.Contract err := r.db.Preload("Files").First(&c, id).Error if err != nil { return nil, err } return &c, nil } func (r *contractRepository) Update(contract *model.Contract) error { return r.db.Save(contract).Error } func (r *contractRepository) Delete(id uint) error { return r.db.Transaction(func(tx *gorm.DB) error { if err := tx.Where("contract_id = ?", id).Delete(&model.ContractFile{}).Error; err != nil { return err } return tx.Delete(&model.Contract{}, id).Error }) } func (r *contractRepository) DeleteFilesByContractIDExcept(contractID uint, keepIDs []uint) error { if len(keepIDs) == 0 { return r.db.Where("contract_id = ?", contractID).Delete(&model.ContractFile{}).Error } return r.db.Where("contract_id = ? AND id NOT IN ?", contractID, keepIDs).Delete(&model.ContractFile{}).Error } func (r *contractRepository) UpdateWithFiles(contract *model.Contract, keepFileIDs []uint, newFiles []model.ContractFile) error { return r.db.Transaction(func(tx *gorm.DB) error { if err := tx.Save(contract).Error; err != nil { return err } if len(keepFileIDs) == 0 { if err := tx.Where("contract_id = ?", contract.ID).Delete(&model.ContractFile{}).Error; err != nil { return err } } else { if err := tx.Where("contract_id = ? AND id NOT IN ?", contract.ID, keepFileIDs).Delete(&model.ContractFile{}).Error; err != nil { return err } } for i := range newFiles { newFiles[i].ContractID = contract.ID } if len(newFiles) > 0 { if err := tx.Create(&newFiles).Error; err != nil { return err } } return nil }) }