diff --git a/backend/internal/handler/generate.go b/backend/internal/handler/generate.go index 7ec2df0..458eb4a 100755 --- a/backend/internal/handler/generate.go +++ b/backend/internal/handler/generate.go @@ -4,9 +4,11 @@ import ( "context" "fmt" "net/http" + "strconv" "sync" "time" + "gen2d/internal/db" "gen2d/internal/logger" "gen2d/internal/model" "gen2d/internal/service" @@ -101,6 +103,9 @@ func Generate(c *gin.Context) { }, }) + // 将任务记录写入数据库(用于任务列表查询) + go saveTaskToDB(c.Request.Context(), projectID, taskID, req) + // 返回 taskId c.JSON(http.StatusOK, model.OK(GenerateResponse{TaskID: taskID})) @@ -191,6 +196,9 @@ func updateTaskProgress(taskID, status, stage string, progress int) { r.task.Stage = stage r.task.Progress = progress taskStore.Store(taskID, r) + + // 同步更新数据库状态 + updateTaskInDB(taskID, status, stage, "", progress) } func updateFailed(taskID, errMsg string) { @@ -202,6 +210,9 @@ func updateFailed(taskID, errMsg string) { r.task.Status = "failed" r.task.Error = errMsg taskStore.Store(taskID, r) + + // 同步更新数据库状态 + updateTaskInDB(taskID, "failed", r.task.Stage, errMsg, r.task.Progress) } // GetTask 查询任务信息。 @@ -234,3 +245,46 @@ func GetAssets(c *gin.Context) { Metadata: r.metadata, })) } + +// saveTaskToDB 将任务记录保存到数据库。 +func saveTaskToDB(ctx context.Context, projectID, taskID string, req GenerateRequest) { + // "default" 工程没有数据库记录,跳过 + if projectID == "default" { + return + } + + projectIDUint, err := strconv.ParseUint(projectID, 10, 32) + if err != nil { + logger.FromCtx(ctx).Error("failed to parse projectID", "projectID", projectID, "error", err) + return + } + + task := &model.Task{ + ExternalID: taskID, + ProjectID: uint(projectIDUint), + Prompt: req.Prompt, + AssetType: req.AssetType, + Status: "pending", + Progress: 0, + RetryCount: 0, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + } + + if err := db.GetDB().WithContext(ctx).Create(task).Error; err != nil { + logger.FromCtx(ctx).Error("failed to save task to db", "taskID", taskID, "error", err) + } +} + +// updateTaskInDB 更新数据库中的任务状态。 +func updateTaskInDB(taskID string, status, stage, error string, progress int) { + db.GetDB().Model(&model.Task{}). + Where("external_id = ?", taskID). + Updates(map[string]interface{}{ + "status": status, + "stage": stage, + "progress": progress, + "error": error, + "updated_at": time.Now(), + }) +} diff --git a/backend/internal/model/task.go b/backend/internal/model/task.go index a62ab60..a34558b 100644 --- a/backend/internal/model/task.go +++ b/backend/internal/model/task.go @@ -4,15 +4,16 @@ import "time" // Task 任务数据模型,对应数据库表。 type Task struct { - ID uint `gorm:"primaryKey" json:"id"` - ProjectID uint `gorm:"index" json:"-"` - Prompt string `gorm:"type:text" json:"prompt"` - AssetType string `gorm:"size:50" json:"assetType"` - Status string `gorm:"size:20;default:'pending'" json:"status"` - Stage string `gorm:"size:50" json:"stage,omitempty"` - Progress int `gorm:"default:0" json:"progress"` - RetryCount int `gorm:"default:0" json:"retryCount"` - Error string `gorm:"type:text" json:"error,omitempty"` + ID uint `gorm:"primaryKey" json:"id"` + ExternalID string `gorm:"size:100;index" json:"externalId,omitempty"` // 外部任务ID,关联内存中的taskID + ProjectID uint `gorm:"index" json:"-"` + Prompt string `gorm:"type:text" json:"prompt"` + AssetType string `gorm:"size:50" json:"assetType"` + Status string `gorm:"size:20;default:'pending'" json:"status"` + Stage string `gorm:"size:50" json:"stage,omitempty"` + Progress int `gorm:"default:0" json:"progress"` + RetryCount int `gorm:"default:0" json:"retryCount"` + Error string `gorm:"type:text" json:"error,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt,omitempty"` }