refactor(core): 任务与模型协议治理 - 拆分服务职责并禁止已发起任务取消
This commit is contained in:
1 parent
7418ddfa9c
commit
633560a5d8
91 files changed
+6380
-4247
No files matched your search
@@ -27,6 +27,8 @@ var ErrTextReplayClosed = errors.New("text replay task is closed")
|
||||
|
||||
var ErrProjectAssetFolderNotEmpty = errors.New("project asset folder is not empty")
|
||||
|
||||
var ErrProjectHasActiveTasks = errors.New("project has active tasks")
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
@@ -322,6 +324,17 @@ func (r *Repository) ActiveTaskCountForUser(userID string) (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *Repository) ActiveTaskCountForProjectIDs(userID string, projectIDs []string) (int64, error) {
|
||||
if len(projectIDs) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var count int64
|
||||
err := r.db.Model(&model.Task{}).
|
||||
Where("user_id = ? AND project_id IN ? AND status IN ?", userID, projectIDs, []model.TaskStatus{model.TaskStatusQueued, model.TaskStatusRunning}).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// 任务领取以数据库租约为真相;PostgreSQL 锁行跳过竞争任务,SQLite 继续依赖条件更新保证单实例原子性。
|
||||
func (r *Repository) ClaimNextTask(owner string, leaseDuration time.Duration) (*model.Task, error) {
|
||||
var task model.Task
|
||||
@@ -854,6 +867,10 @@ func (r *Repository) SaveResource(resource *model.Resource) error {
|
||||
return r.db.Save(resource).Error
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteResource(userID string, id string) error {
|
||||
return r.db.Delete(&model.Resource{}, "id = ? AND user_id = ?", id, userID).Error
|
||||
}
|
||||
|
||||
func (r *Repository) Resource(id string) (*model.Resource, error) {
|
||||
var resource model.Resource
|
||||
if err := r.db.First(&resource, "id = ?", id).Error; err != nil {
|
||||
@@ -985,14 +1002,48 @@ func (r *Repository) UpdateProject(project *model.Project) error {
|
||||
}).Error
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteProject(userID string, id string) error {
|
||||
func (r *Repository) DeleteProject(userID string, id string, canvasUpdates []model.CanvasProject) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&model.CanvasProject{}).Where("user_id = ? AND project_id = ?", userID, id).Update("project_id", "").Error; err != nil {
|
||||
var canvasIDs []string
|
||||
if err := tx.Model(&model.CanvasProject{}).
|
||||
Where("user_id = ? AND project_id = ?", userID, id).
|
||||
Pluck("id", &canvasIDs).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
projectScopeIDs := append([]string{id}, canvasIDs...)
|
||||
var activeTaskCount int64
|
||||
if err := tx.Model(&model.Task{}).
|
||||
Where("user_id = ? AND project_id IN ? AND status IN ?", userID, projectScopeIDs, []model.TaskStatus{model.TaskStatusQueued, model.TaskStatusRunning}).
|
||||
Count(&activeTaskCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if activeTaskCount > 0 {
|
||||
return ErrProjectHasActiveTasks
|
||||
}
|
||||
if err := tx.Where("user_id = ? AND project_id = ?", userID, id).Delete(&model.CanvasShare{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("project_id = ?", id).Delete(&model.CanvasUnitLink{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, canvas := range canvasUpdates {
|
||||
result := tx.Model(&model.CanvasProject{}).
|
||||
Where("id = ? AND user_id = ? AND project_id = ?", canvas.ID, userID, id).
|
||||
Updates(map[string]any{"project_id": "", "payload_json": canvas.PayloadJSON, "updated_at": canvas.UpdatedAt})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected != 1 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
}
|
||||
var remainingCanvasCount int64
|
||||
if err := tx.Model(&model.CanvasProject{}).Where("user_id = ? AND project_id = ?", userID, id).Count(&remainingCanvasCount).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if remainingCanvasCount != 0 {
|
||||
return fmt.Errorf("项目删除时仍有 %d 个画布关联未处理", remainingCanvasCount)
|
||||
}
|
||||
shotIDs := tx.Model(&model.Shot{}).Select("id").Where("project_id = ?", id)
|
||||
if err := tx.Where("shot_id IN (?)", shotIDs).Delete(&model.ShotAssetReference{}).Error; err != nil {
|
||||
return err
|
||||
@@ -1023,6 +1074,12 @@ func (r *Repository) DeleteProject(userID string, id string) error {
|
||||
if err := tx.Where("project_id = ?", id).Delete(&model.ProjectUnit{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&model.Task{}).Where("user_id = ? AND project_id = ?", userID, id).Update("project_id", "").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&model.Session{}).Where("user_id = ? AND project_id = ?", userID, id).Update("project_id", "").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Delete(&model.Project{}, "id = ? AND user_id = ?", id, userID).Error
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user