Adapted from ddcat-ai/open-ai-canvas#339 Original commit: fcdbe2aa833f31f683f709b7f409a0534ed78e20 Refs #339 Co-authored-by: 宇熙 <101980758+yuxiwl@users.noreply.github.com>
159 lines
5.3 KiB
Go
159 lines
5.3 KiB
Go
package repository
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"infinite-canvas/backend/internal/model"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var ErrAnnouncementImageDraftUnavailable = errors.New("announcement image draft unavailable")
|
|
var ErrAnnouncementImageReferenced = errors.New("announcement image is still referenced")
|
|
|
|
func (r *Repository) CreateAnnouncementImageDraft(draft *model.AnnouncementImageDraft) error {
|
|
return r.db.Create(draft).Error
|
|
}
|
|
|
|
func (r *Repository) AnnouncementImageDraftForUser(userID string, resourceID string) (*model.AnnouncementImageDraft, error) {
|
|
var draft model.AnnouncementImageDraft
|
|
if err := r.db.First(&draft, "resource_id = ? AND user_id = ?", resourceID, userID).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &draft, nil
|
|
}
|
|
|
|
func (r *Repository) DeleteAnnouncementImageDraft(userID string, resourceID string) error {
|
|
return r.db.Where("resource_id = ? AND user_id = ?", resourceID, userID).Delete(&model.AnnouncementImageDraft{}).Error
|
|
}
|
|
|
|
func (r *Repository) StaleAnnouncementImageDrafts(before time.Time, limit int) ([]model.AnnouncementImageDraft, error) {
|
|
if limit <= 0 || limit > 200 {
|
|
limit = 50
|
|
}
|
|
var drafts []model.AnnouncementImageDraft
|
|
err := r.db.Where("created_at < ?", before).Order("created_at asc").Limit(limit).Find(&drafts).Error
|
|
return drafts, err
|
|
}
|
|
|
|
func (r *Repository) CreateAnnouncementWithImage(announcement *model.Announcement) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
if err := consumeAnnouncementImageDraft(tx, announcement.CreatedBy, announcement.ImageResourceID); err != nil {
|
|
return err
|
|
}
|
|
return tx.Create(announcement).Error
|
|
})
|
|
}
|
|
|
|
func (r *Repository) UpdateAnnouncementWithImage(announcement *model.Announcement, draftUserID string, newDraftResourceID string, oldResource *model.Resource, deletionJob *model.ResourceDeletionJob) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
if err := consumeAnnouncementImageDraft(tx, draftUserID, newDraftResourceID); err != nil {
|
|
return err
|
|
}
|
|
result := tx.Model(&model.Announcement{}).Where("id = ?", announcement.ID).Updates(map[string]any{
|
|
"title": announcement.Title,
|
|
"content": announcement.Content,
|
|
"image_resource_id": announcement.ImageResourceID,
|
|
"level": announcement.Level,
|
|
"pinned": announcement.Pinned,
|
|
"status": announcement.Status,
|
|
"published_at": announcement.PublishedAt,
|
|
"closed_at": announcement.ClosedAt,
|
|
"updated_at": announcement.UpdatedAt,
|
|
})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected != 1 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
if err := tx.Where("announcement_id = ?", announcement.ID).Delete(&model.UserAnnouncementRead{}).Error; err != nil {
|
|
return err
|
|
}
|
|
if oldResource == nil {
|
|
return nil
|
|
}
|
|
var referenceCount int64
|
|
if err := tx.Model(&model.Announcement{}).Where("image_resource_id = ?", oldResource.ID).Count(&referenceCount).Error; err != nil {
|
|
return err
|
|
}
|
|
if referenceCount > 0 {
|
|
return ErrAnnouncementImageReferenced
|
|
}
|
|
if err := tx.Where("resource_id = ?", oldResource.ID).Delete(&model.ArkPrivateAssetBinding{}).Error; err != nil {
|
|
return err
|
|
}
|
|
if err := tx.Where("resource_id = ?", oldResource.ID).Delete(&model.AnnouncementImageDraft{}).Error; err != nil {
|
|
return err
|
|
}
|
|
deleted := tx.Where("id = ? AND user_id = ?", oldResource.ID, oldResource.UserID).Delete(&model.Resource{})
|
|
if deleted.Error != nil {
|
|
return deleted.Error
|
|
}
|
|
if deleted.RowsAffected != 1 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
if deletionJob != nil {
|
|
return tx.Create(deletionJob).Error
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *Repository) DiscardAnnouncementImageDraft(userID string, resource *model.Resource, deletionJob *model.ResourceDeletionJob) error {
|
|
if resource == nil {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
var draft model.AnnouncementImageDraft
|
|
if err := tx.First(&draft, "resource_id = ? AND user_id = ?", resource.ID, userID).Error; err != nil {
|
|
return err
|
|
}
|
|
var referenceCount int64
|
|
if err := tx.Model(&model.Announcement{}).Where("image_resource_id = ?", resource.ID).Count(&referenceCount).Error; err != nil {
|
|
return err
|
|
}
|
|
if referenceCount > 0 {
|
|
return ErrAnnouncementImageReferenced
|
|
}
|
|
if err := tx.Where("resource_id = ?", resource.ID).Delete(&model.ArkPrivateAssetBinding{}).Error; err != nil {
|
|
return err
|
|
}
|
|
deleted := tx.Where("id = ? AND user_id = ?", resource.ID, userID).Delete(&model.Resource{})
|
|
if deleted.Error != nil {
|
|
return deleted.Error
|
|
}
|
|
if deleted.RowsAffected != 1 {
|
|
return gorm.ErrRecordNotFound
|
|
}
|
|
if err := tx.Delete(&draft).Error; err != nil {
|
|
return err
|
|
}
|
|
if deletionJob != nil {
|
|
return tx.Create(deletionJob).Error
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *Repository) AnnouncementImageReferenceCount(resourceID string) (int64, error) {
|
|
var count int64
|
|
err := r.db.Model(&model.Announcement{}).Where("image_resource_id = ?", resourceID).Count(&count).Error
|
|
return count, err
|
|
}
|
|
|
|
func consumeAnnouncementImageDraft(tx *gorm.DB, userID string, resourceID string) error {
|
|
if resourceID == "" {
|
|
return nil
|
|
}
|
|
result := tx.Where("resource_id = ? AND user_id = ?", resourceID, userID).Delete(&model.AnnouncementImageDraft{})
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.RowsAffected != 1 {
|
|
return ErrAnnouncementImageDraftUnavailable
|
|
}
|
|
return nil
|
|
}
|