package sop_task import ( "context" "errors" "github.com/suyuan32/simple-admin-common/msg/errormsg" "wechat-api/ent" "wechat-api/ent/contact" "wechat-api/ent/custom_types" "wechat-api/ent/labelrelationship" "wechat-api/ent/messagerecords" "wechat-api/ent/predicate" "wechat-api/ent/soptask" "wechat-api/internal/utils/dberrorhandler" "wechat-api/internal/svc" "wechat-api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type PublishSopTaskLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewPublishSopTaskLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PublishSopTaskLogic { return &PublishSopTaskLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx} } func (l *PublishSopTaskLogic) PublishSopTask(req *types.IDReq) (resp *types.BaseMsgResp, err error) { // 开始事务 tx, err := l.svcCtx.DB.Tx(context.Background()) if err != nil { return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 根据 id 查询 sop_task sopTask, err := tx.SopTask.Query(). Where( soptask.ID(req.Id), soptask.Status(1), ). WithTaskStages(). Only(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 判断 sop_task 是否存在 if sopTask != nil { if sopTask.BotWxidList == nil { return nil, errors.New(errormsg.ValidationError) } // 查询任务的所有 sop_stages err = tx.SopTask.UpdateOneID(req.Id). SetStatus(3). Exec(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } sopStages, err := tx.SopStage.Query().All(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 遍历 stage for _, stage := range sopTask.Edges.TaskStages { if stage.ConditionType == 1 { // 构造查询条件 var predicates []predicate.Contact for _, condition := range stage.ConditionList { subPredicate := contact.HasContactRelationshipsWith(labelrelationship.LabelIDIn(condition.LabelIdList...)) if condition.Equal == 2 { subPredicate = contact.Not(subPredicate) } predicates = append(predicates, subPredicate) } // 查询满足条件的联系人 var contacts []*ent.Contact var err error sourceType := 3 if stage.ConditionOperator == 1 { contacts, err = tx.Contact.Query().Where(contact.And(predicates...)).All(l.ctx) } else { contacts, err = tx.Contact.Query().Where(contact.Or(predicates...)).All(l.ctx) } if err != nil { _ = tx.Rollback() return nil, err } // 遍历 contacts for _, c := range contacts { // 判断联系人所属微信是否包含在任务当中 if sopTask.BotWxidList == nil || (sopTask.BotWxidList != nil && valueInArray(c.WxWxid, sopTask.BotWxidList)) { for _, message := range stage.ActionMessage { _, _ = tx.MessageRecords.Create(). SetNotNilBotWxid(&c.WxWxid). SetNotNilContactID(&c.ID). SetNotNilContactType(&c.Type). SetNotNilContactWxid(&c.Wxid). SetNotNilContentType(&message.Type). SetNotNilContent(&message.Content). SetNotNilSourceType(&sourceType). SetNotNilSourceID(&stage.ID). Save(l.ctx) //if err != nil { // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) //} } // 查询当前联系人的标签关系 currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(c.ID)).All(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 提取当前标签ID var currentLabelIds []uint64 for _, relationship := range currentLabelRelationships { currentLabelIds = append(currentLabelIds, relationship.LabelID) } if stage.ActionLabel != nil { // 递归调用 AddLabelRelationships err = l.AddLabelRelationships(sopStages, *c, currentLabelIds, stage.ActionLabel) if err != nil { _ = tx.Rollback() return nil, err } } } } } } // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } return &types.BaseMsgResp{Msg: errormsg.Success}, nil } else { // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 返回错误信息:任务不存在 return nil, errors.New(errormsg.TargetNotFound) } } func (l *PublishSopTaskLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, addLabelIds []uint64) (err error) { // 开始事务 tx, err := l.svcCtx.DB.Tx(context.Background()) if err != nil { return dberrorhandler.DefaultEntError(l.Logger, err, nil) } // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID var newLabelIds []uint64 // 创建一个映射,用于快速查找 currentLabelIds 中的元素 currentLabelIdSet := make(map[uint64]struct{}) for _, id := range currentLabelIds { currentLabelIdSet[id] = struct{}{} } // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素 for _, id := range addLabelIds { if _, exists := currentLabelIdSet[id]; !exists { newLabelIds = append(newLabelIds, id) } } if len(newLabelIds) == 0 { return nil } // 创建需要新增的标签关系 for _, id := range newLabelIds { _, err = tx.LabelRelationship.Create(). SetLabelID(id). SetContactID(contact.ID). Save(l.ctx) if err != nil { _ = tx.Rollback() return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } // 合并 currentLabelIds 和 newLabelIds currentLabelIds = append(currentLabelIds, newLabelIds...) // 遍历 sop_stages,找出满足条件的 stage for _, stage := range sopStages { if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) { // 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录 _, err := tx.MessageRecords.Query(). Where( messagerecords.ContactWxid(contact.Wxid), messagerecords.SourceType(3), messagerecords.SourceID(stage.ID), messagerecords.SubSourceID(0), ). Only(l.ctx) if err != nil { continue } // 判断ActionMessage是否为空 sourceType := 3 if stage.ActionMessage != nil { for _, message := range stage.ActionMessage { _, _ = tx.MessageRecords.Create(). SetNotNilBotWxid(&contact.WxWxid). SetNotNilContactID(&contact.ID). SetNotNilContactType(&contact.Type). SetNotNilContactWxid(&contact.Wxid). SetNotNilContentType(&message.Type). SetNotNilContent(&message.Content). SetNotNilSourceType(&sourceType). SetNotNilSourceID(&stage.ID). Save(l.ctx) //if err != nil { // return dberrorhandler.DefaultEntError(l.Logger, err, nil) //} } } if stage.ActionLabel != nil { // 递归调用 AddLabelRelationships err = l.AddLabelRelationships(sopStages, contact, currentLabelIds, stage.ActionLabel) if err != nil { _ = tx.Rollback() return err } } } } // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return dberrorhandler.DefaultEntError(l.Logger, err, nil) } return nil } func valueInArray(val string, array []string) bool { for _, item := range array { if item == val { return true } } return false } func isLabelIdListMatchFilter(labelIdList []uint64, conditionOperator int, conditionList []custom_types.Condition) bool { labelIdSet := make(map[uint64]struct{}) for _, id := range labelIdList { labelIdSet[id] = struct{}{} } for _, condition := range conditionList { match := false for _, id := range condition.LabelIdList { if _, ok := labelIdSet[id]; ok { match = true break } } if condition.Equal == 2 { match = !match } if (conditionOperator == 1 && !match) || (conditionOperator == 2 && match) { return match } } return conditionOperator == 1 }