package dataengine import ( daoEntity "cid/model/entity/dataengine" "context" "github.com/bwmarrin/snowflake" "github.com/gogf/gf/v2/frame/g" ) // MaterialVerifyLogDAO 素材校验日志数据访问层 type MaterialVerifyLogDAO struct{} // MaterialVerifyLog DAO单例 var MaterialVerifyLog = new(MaterialVerifyLogDAO) // TableName 表名 const MaterialVerifyLogTable = "material_verify_log" // Create 创建校验日志 func (d *MaterialVerifyLogDAO) Create(ctx context.Context, log *daoEntity.MaterialVerifyLog) (id int64, err error) { // GoFrame v2.10.0 pgsql 驱动不支持 RETURNING/LastInsertId // 且 gfdb insertHook 会覆盖 id,无法从外部获取钩子生成的 ID // 手动生成 Snowflake ID 并直接插入(绕过 gfdb 钩子) node, err := snowflake.NewNode(1) if err != nil { g.Log().Errorf(ctx, "创建Snowflake节点失败: %v", err) return 0, err } snowflakeID := node.Generate().Int64() _, err = g.DB("cid").Model(MaterialVerifyLogTable).Data(g.Map{ "id": snowflakeID, "tenant_id": log.TenantID, "material_type": log.MaterialType, "material_id": log.MaterialID, "source_table": log.SourceTable, "source_id": log.SourceID, "account_id": log.AccountID, "verify_status": log.VerifyStatus, }).Insert() if err != nil { g.Log().Errorf(ctx, "创建校验日志失败: %v", err) return 0, err } return snowflakeID, nil } // GetByID 根据ID获取日志 func (d *MaterialVerifyLogDAO) GetByID(ctx context.Context, id int64) (*daoEntity.MaterialVerifyLog, error) { var result daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). One() if err != nil { return nil, err } if r.IsEmpty() { return nil, nil } if err = r.Struct(&result); err != nil { return nil, err } return &result, nil } // GetByTaskID 根据任务ID获取日志 func (d *MaterialVerifyLogDAO) GetByTaskID(ctx context.Context, taskID string) (*daoEntity.MaterialVerifyLog, error) { var result daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.TaskID, taskID). One() if err != nil { return nil, err } if r.IsEmpty() { return nil, nil } if err = r.Struct(&result); err != nil { return nil, err } return &result, nil } // GetByMaterialID 根据素材ID获取日志列表 func (d *MaterialVerifyLogDAO) GetByMaterialID(ctx context.Context, materialID string) ([]daoEntity.MaterialVerifyLog, error) { var result []daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.MaterialID, materialID). OrderDesc(daoEntity.MaterialVerifyLogCols.CreatedAt). All() if err != nil { return nil, err } if err = r.Structs(&result); err != nil { return nil, err } return result, nil } // GetBySource 根据来源获取日志 func (d *MaterialVerifyLogDAO) GetBySource(ctx context.Context, sourceTable string, sourceID int64) ([]daoEntity.MaterialVerifyLog, error) { var result []daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.SourceTable, sourceTable). Where(daoEntity.MaterialVerifyLogCols.SourceID, sourceID). OrderDesc(daoEntity.MaterialVerifyLogCols.CreatedAt). All() if err != nil { return nil, err } if err = r.Structs(&result); err != nil { return nil, err } return result, nil } // UpdateVerifyResult 更新校验结果 func (d *MaterialVerifyLogDAO) UpdateVerifyResult(ctx context.Context, id int64, verifyStatus string, suggestion, label, resultType int, responseResult string, checkTime int64) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.VerifyStatus: verifyStatus, daoEntity.MaterialVerifyLogCols.Suggestion: suggestion, daoEntity.MaterialVerifyLogCols.Label: label, daoEntity.MaterialVerifyLogCols.ResultType: resultType, daoEntity.MaterialVerifyLogCols.ResponseResult: responseResult, daoEntity.MaterialVerifyLogCols.CheckTime: checkTime, }).Update() if err != nil { g.Log().Errorf(ctx, "更新校验日志结果失败: %v", err) return err } return nil } // UpdateError 更新错误信息 func (d *MaterialVerifyLogDAO) UpdateError(ctx context.Context, id int64, verifyStatus string, errorMsg string) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.VerifyStatus: verifyStatus, daoEntity.MaterialVerifyLogCols.ErrorMsg: errorMsg, }).Update() if err != nil { g.Log().Errorf(ctx, "更新校验日志错误失败: %v", err) return err } return nil } // UpdateTaskID 更新任务ID func (d *MaterialVerifyLogDAO) UpdateTaskID(ctx context.Context, id int64, taskID string) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.TaskID: taskID, }).Update() if err != nil { return err } return nil } // UpdateDuration 更新处理耗时 func (d *MaterialVerifyLogDAO) UpdateDuration(ctx context.Context, id int64, durationMs int64) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.DurationMs: durationMs, }).Update() if err != nil { return err } return nil } // UpdateRequestParams 更新请求参数 func (d *MaterialVerifyLogDAO) UpdateRequestParams(ctx context.Context, id int64, requestParams string) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.RequestParams: requestParams, }).Update() if err != nil { return err } return nil } // GetByCondition 根据条件分页查询 func (d *MaterialVerifyLogDAO) GetByCondition(ctx context.Context, condition map[string]interface{}, page, pageSize int) ([]daoEntity.MaterialVerifyLog, int, error) { var result []daoEntity.MaterialVerifyLog m := g.DB("cid").Model(MaterialVerifyLogTable) for k, v := range condition { m.Where(k, v) } total, err := m.Count() if err != nil { return nil, 0, err } r, err := m. OrderDesc(daoEntity.MaterialVerifyLogCols.CreatedAt). Page(page, pageSize). All() if err != nil { return nil, 0, err } if err = r.Structs(&result); err != nil { return nil, 0, err } return result, int(total), nil } // CountByStatus 按状态统计 func (d *MaterialVerifyLogDAO) CountByStatus(ctx context.Context, verifyStatus string) (int, error) { count, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.VerifyStatus, verifyStatus). Count() if err != nil { return 0, err } return int(count), nil } // GetStats 获取统计信息 func (d *MaterialVerifyLogDAO) GetStats(ctx context.Context) (map[string]int, error) { stats := make(map[string]int) statuses := []struct { statusKey string statusVal string }{ {"pending", daoEntity.VerifyStatusPending}, {"verified", daoEntity.VerifyStatusVerified}, {"rejected", daoEntity.VerifyStatusRejected}, } var totalCount int for _, item := range statuses { count, err := d.CountByStatus(ctx, item.statusVal) if err != nil { continue } stats[item.statusKey] = count totalCount += count } stats["total"] = totalCount return stats, nil } // GetPendingResults 获取待查询结果的日志(状态为pending且有taskID) func (d *MaterialVerifyLogDAO) GetPendingResults(ctx context.Context, limit int) ([]daoEntity.MaterialVerifyLog, error) { var result []daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.VerifyStatus, daoEntity.VerifyStatusPending). WhereNotNull(daoEntity.MaterialVerifyLogCols.TaskID). Where(daoEntity.MaterialVerifyLogCols.TaskID + " != ''"). OrderAsc(daoEntity.MaterialVerifyLogCols.CreatedAt). Limit(limit). All() if err != nil { g.Log().Errorf(ctx, "查询待处理结果日志失败: %v", err) return nil, err } if err = r.Structs(&result); err != nil { g.Log().Errorf(ctx, "转换待处理结果日志失败: %v", err) return nil, err } return result, nil } // GetLastRejectedLogByMaterialID 根据素材ID获取最后一条失败的校验日志 func (d *MaterialVerifyLogDAO) GetLastRejectedLogByMaterialID(ctx context.Context, materialID string, verifyStatus string) (*daoEntity.MaterialVerifyLog, error) { var result daoEntity.MaterialVerifyLog r, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.MaterialID, materialID). Where(daoEntity.MaterialVerifyLogCols.VerifyStatus, verifyStatus). OrderDesc(daoEntity.MaterialVerifyLogCols.CreatedAt). One() if err != nil { return nil, err } if r.IsEmpty() { return nil, nil } if err = r.Struct(&result); err != nil { return nil, err } return &result, nil } // UpdateRiskDescription 更新风险描述 func (d *MaterialVerifyLogDAO) UpdateRiskDescription(ctx context.Context, id int64, riskDescription string) error { _, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.Id, id). Data(g.Map{ daoEntity.MaterialVerifyLogCols.RiskDescription: riskDescription, }).Update() if err != nil { g.Log().Errorf(ctx, "更新风险描述失败: %v", err) return err } return nil } // CountPendingResults 统计待查询结果的数量 func (d *MaterialVerifyLogDAO) CountPendingResults(ctx context.Context) (int, error) { count, err := g.DB("cid").Model(MaterialVerifyLogTable). Where(daoEntity.MaterialVerifyLogCols.VerifyStatus, daoEntity.VerifyStatusPending). WhereNotNull(daoEntity.MaterialVerifyLogCols.TaskID). Where(daoEntity.MaterialVerifyLogCols.TaskID + " != ''"). Count() if err != nil { return 0, err } return int(count), nil }