package audio import ( "context" consts "media/consts/audio" dto "media/model/dto/audio" entity "media/model/entity/audio" "gitea.com/red-future/common/db/gfdb" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" ) var TranscribeTask = new(transcribeTaskDao) type transcribeTaskDao struct{} // Insert 创建任务 func (d *transcribeTaskDao) Insert(ctx context.Context, data *entity.TranscribeTask) (id int64, err error) { // FieldsEx 排除空 result 字段(JSONB 列不支持空串 '') r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Data(data). FieldsEx(entity.TranscribeTaskCols.Result). Insert() if err != nil { return 0, err } return r.LastInsertId() } // GetByTaskID 根据taskId获取任务 func (d *transcribeTaskDao) GetByTaskID(ctx context.Context, taskID string) (res *entity.TranscribeTask, err error) { r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Where(entity.TranscribeTaskCols.TaskID, taskID). One() if err != nil { return nil, err } if r == nil { return nil, nil } err = r.Struct(&res) return } // UpdateProgress 更新任务进度 func (d *transcribeTaskDao) UpdateProgress(ctx context.Context, taskID string, progress int) (rows int64, err error) { r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Data(g.Map{ entity.TranscribeTaskCols.Progress: progress, }). Where(entity.TranscribeTaskCols.TaskID, taskID). Update() if err != nil { return 0, err } return r.RowsAffected() } // UpdateTaskRunning 将任务更新为运行中 func (d *transcribeTaskDao) UpdateTaskRunning(ctx context.Context, taskID string, progress int) (rows int64, err error) { r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Data(g.Map{ entity.TranscribeTaskCols.Status: consts.TaskStatusRunning, entity.TranscribeTaskCols.Progress: progress, }). Where(entity.TranscribeTaskCols.TaskID, taskID). Update() if err != nil { return 0, err } return r.RowsAffected() } // UpdateResult 更新任务成功状态(result: 完整结果JSON) func (d *transcribeTaskDao) UpdateResult(ctx context.Context, taskID, result string, successCount, failCount int) (rows int64, err error) { r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Data(g.Map{ entity.TranscribeTaskCols.Status: consts.TaskStatusSuccess, entity.TranscribeTaskCols.Progress: 100, entity.TranscribeTaskCols.Result: result, entity.TranscribeTaskCols.SuccessFiles: successCount, entity.TranscribeTaskCols.FailFiles: failCount, entity.TranscribeTaskCols.ErrorMessage: "", }). Where(entity.TranscribeTaskCols.TaskID, taskID). Update() if err != nil { return 0, err } return r.RowsAffected() } // UpdateError 更新任务错误(失败后) func (d *transcribeTaskDao) UpdateError(ctx context.Context, taskID string, errMsg string) (rows int64, err error) { r, err := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable). Data(g.Map{ entity.TranscribeTaskCols.Status: consts.TaskStatusFailed, entity.TranscribeTaskCols.ErrorMessage: errMsg, }). Where(entity.TranscribeTaskCols.TaskID, taskID). Update() if err != nil { return 0, err } return r.RowsAffected() } // List 获取任务列表 func (d *transcribeTaskDao) List(ctx context.Context, req *dto.ListTaskReq) (res []entity.TranscribeTask, total int, err error) { model := d.buildListFilter(ctx, req) model.OrderDesc(entity.TranscribeTaskCols.CreatedAt) if req.Page != nil { model.Page(int(req.Page.PageNum), int(req.Page.PageSize)) } r, total, err := model.AllAndCount(false) if err != nil { return } err = r.Structs(&res) return } // buildListFilter 构建列表过滤 func (d *transcribeTaskDao) buildListFilter(ctx context.Context, req *dto.ListTaskReq) *gdb.Model { model := gfdb.DB(ctx).Model(ctx, consts.TranscribeTaskTable).Model model.Where(entity.TranscribeTaskCols.Status, req.Status) model.OmitEmptyWhere() return model } // EntityToItem 将实体转为DTO项 // 注意: 不返回 result 字段(数据在 detailList 结构化返回中,避免与 result JSON 重复) // // result 仅在回调通知时直接使用 task.Result func EntityToItem(e *entity.TranscribeTask) dto.TranscribeTaskItem { item := dto.TranscribeTaskItem{ ID: e.Id, TaskID: e.TaskID, Status: e.Status, Progress: e.Progress, TotalFiles: e.TotalFiles, SuccessFiles: e.SuccessFiles, FailFiles: e.FailFiles, Model: e.Model, Language: e.Language, Threshold: e.Threshold, InputType: e.InputType, InputData: e.InputData, FileNames: e.FileNames, CallbackURL: e.CallbackURL, ErrorMessage: e.ErrorMessage, } if e.CreatedAt != nil { item.CreatedAt = gconv.Int64(e.CreatedAt.Timestamp()) } if e.UpdatedAt != nil { item.UpdatedAt = gconv.Int64(e.UpdatedAt.Timestamp()) } return item } // EntityToProgress 将实体转为进度DTO func EntityToProgress(e *entity.TranscribeTask) dto.GetProgressRes { return dto.GetProgressRes{ TaskID: e.TaskID, Status: e.Status, Progress: e.Progress, } } // DetailEntityToItem 将明细实体转为DTO项 func DetailEntityToItem(e *entity.TranscribeTaskDetail) dto.TranscribeTaskDetailItem { return dto.TranscribeTaskDetailItem{ ID: e.Id, TaskID: e.TaskID, FileIndex: e.FileIndex, FileName: e.FileName, TranscribedText: e.TranscribedText, Scenes: e.Scenes, AudioSize: e.AudioSize, AudioDuration: e.AudioDuration, Model: e.Model, Language: e.Language, ErrorMessage: e.ErrorMessage, } }