package imageaudit import ( "fmt" "service/api/consts" imageauditproto "service/api/proto/imageaudit/proto" imageaudittaskproto "service/api/proto/imageaudittask/proto" "service/bizcommon/util" "service/dbstruct" "service/library/logger" "github.com/gin-gonic/gin" goproto "google.golang.org/protobuf/proto" ) // 图像审核任务控制块 // ActionId设计初衷:由于图像审核是定时任务触发的批量作业,如果在一次作业间隔有针对同一个图像媒体的多次更新,则会提交关于它的多次审核,需要配合乐观锁保证数据一致性 type ImageAuditTaskControlBlock struct { // 静态元素 ActionId string // 审核动作id号,由图像审核实体数据库四要素拼接而成,用于指示对数据库-表-单条数据-图像字段的审核动作 ImageAuditTask *dbstruct.ImageAuditTask // 审核任务 RollbackFunc func() error // 审核失败时的回退方法 // 操作对象 Images []*dbstruct.MediaComponent // 被审核的图像序列 // 动态元素 IsTaskPassed bool // 任务状态,仅当任务已确定完成,即已完成审核任务的分片数 = 审核任务分片数时,才有意义 AuditedFragmentsNum int // 已完成审核任务的分片数 IsGivingNoticeToBatch bool // 是否进行批处理 } // 新建图像审核任务块 func NewImageAuditTaskControlBlock(task *dbstruct.ImageAuditTask, rollbackFunc func() error) (tcb *ImageAuditTaskControlBlock) { if task == nil || task.AuditedMedia == nil { return } fragmentNum := len(util.DerefInt64Slice(task.AuditedMedia.ImageIds)) if fragmentNum == 0 { return } task.BatchId = goproto.String(defaultImageAuditTaskScheduler.batchId) task.Status = goproto.Int64(consts.ImageAudit_Created) if fragmentNum == 1 { task.IsFragmented = goproto.Int64(0) task.FragmentsNum = goproto.Int64(1) } else { task.IsFragmented = goproto.Int64(1) task.FragmentsNum = goproto.Int64(int64(fragmentNum)) } tcb = &ImageAuditTaskControlBlock{ ActionId: fmt.Sprintf("%v%v%v%v", util.DerefString(task.AssociativeDatabase), util.DerefString(task.AssociativeTableName), util.DerefInt64(task.AssociativeTableId), util.DerefString(task.AssociativeTableColumn)), ImageAuditTask: task, RollbackFunc: rollbackFunc, IsTaskPassed: true, AuditedFragmentsNum: 0, IsGivingNoticeToBatch: false, } return } func AddTask(task *ImageAuditTaskControlBlock) { if err := task.Prepare(); err != nil { logger.Error("ImageAuditTaskPrepareException: %v", err) return } defaultImageAuditTaskScheduler.AddTask(task) } // 将图像审核任务信息写入数据库,准备送审 func (task *ImageAuditTaskControlBlock) Prepare() (err error) { if task == nil { return fmt.Errorf("task is nil, check your input") } // 1.写入图像审核表 if util.DerefInt64(task.ImageAuditTask.IsFragmented) == 1 { if task.Images, err = prepareFragmentedImageAuditTask(task.ImageAuditTask); err != nil { return err } } else { if err := prepareNotFragmentedImageAuditTask(task.ImageAuditTask); err != nil { return err } task.Images = make([]*dbstruct.MediaComponent, 1) task.Images[0] = task.ImageAuditTask.AuditedMedia } // 2.写入图像审核任务表 if err := _DefaultImageAuditTask.OpCreate(&gin.Context{}, &imageaudittaskproto.OpCreateReq{ ImageAuditTask: task.ImageAuditTask, }); err != nil { logger.Error("Imageaudittask OpCreate failed: %v", err) return err } return nil } // 根据任务信息,创建单个图片的图片审核,并存入数据库,返回images func prepareFragmentedImageAuditTask(task *dbstruct.ImageAuditTask) (images []*dbstruct.MediaComponent, err error) { ctx := &gin.Context{} fragmentsNum := util.DerefInt64(task.FragmentsNum) images = make([]*dbstruct.MediaComponent, fragmentsNum) imageAudits := make([]*dbstruct.ImageAudit, fragmentsNum) // 将媒体拆分为单个图像并存入图片审核表 imageIds := util.DerefInt64Slice(task.AuditedMedia.ImageIds) for i, imageId := range imageIds { images[i] = &dbstruct.MediaComponent{ ImageIds: util.Int64Slice([]int64{imageId}), } imageAudits[i] = &dbstruct.ImageAudit{ AuditedMedia: images[i], BatchId: task.BatchId, Status: goproto.Int64(consts.ImageAudit_Created), } } if err = _DefaultImageAudit.OpCreateFragmentGroup(ctx, &imageauditproto.OpCreateBatchReq{ ImageAudits: imageAudits, FragmentsNum: fragmentsNum, }); err != nil { logger.Error("Imageaudit OpCreateFragmentGroup failed: %v", err) return } auditFragmentIds := make([]string, fragmentsNum) for i, imageaudit := range imageAudits { auditFragmentIds[i] = util.DerefString(imageaudit.Id) } task.ImageAuditFragmentIds = &auditFragmentIds return } func prepareNotFragmentedImageAuditTask(task *dbstruct.ImageAuditTask) (err error) { ctx := &gin.Context{} imageAudit := &dbstruct.ImageAudit{ AuditedMedia: task.AuditedMedia, BatchId: task.BatchId, Status: goproto.Int64(consts.ImageAudit_Created), } if err = _DefaultImageAudit.OpCreate(ctx, &imageauditproto.OpCreateReq{ ImageAudit: imageAudit, }); err != nil { logger.Error("Imageaudit OpCreate failed: %v", err) return } task.ImageAuditId = imageAudit.Id return }