package label_relationship import ( "context" "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/soptask" "wechat-api/internal/svc" "wechat-api/internal/types" "wechat-api/internal/utils/dberrorhandler" "github.com/zeromicro/go-zero/core/logx" ) type BatchUpdateLabelRelationshipsLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewBatchUpdateLabelRelationshipsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchUpdateLabelRelationshipsLogic { return &BatchUpdateLabelRelationshipsLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx} } func (l *BatchUpdateLabelRelationshipsLogic) BatchUpdateLabelRelationships(req *types.BatchLabelRelationshipsInfo) (resp *types.BaseMsgResp, err error) { organizationId := l.ctx.Value("organizationId").(uint64) // 遍历所有联系人 for _, contactId := range req.ContactIds { // 开始事务 tx, err := l.svcCtx.DB.Tx(context.Background()) if err != nil { return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } // 获取联系人信息 c, err := tx.Contact.Query().Where(contact.ID(contactId), contact.OrganizationIDEQ(organizationId)).Only(l.ctx) // 获取联系人当前已关联的标签 currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(contactId)).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) } // 对比新旧标签ID,找出需要新增和移除的标签 changeLabelIds, finalLabelIds := compareLabelIdsForIncrement(req.LabelIds, currentLabelIds, req.UpdateType) // 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时 if req.UpdateType == -1 { // 删除需要移除的标签关系 for _, id := range changeLabelIds { _, err := tx.LabelRelationship. Delete(). Where( labelrelationship.ContactID(contactId), labelrelationship.LabelID(id), ). Exec(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } } } else { // 创建需要新增的标签关系 for _, id := range changeLabelIds { _, _ = tx.LabelRelationship.Create(). SetLabelID(id). SetContactID(contactId). SetOrganizationID(organizationId). Save(l.ctx) //if err != nil { // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) //} } } // 获取所有 status 为 3 且 bot_wxid_list 包含 c.wx_wxid 的 sop_task sopTasks, err := tx.SopTask.Query().Where(soptask.Status(3), soptask.OrganizationIDEQ(organizationId)).All(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } var filteredSopTasks []*ent.SopTask for _, task := range sopTasks { for _, botWxid := range task.BotWxidList { if botWxid == c.WxWxid { filteredSopTasks = append(filteredSopTasks, task) break } } } // 获取所有 filteredSopTasks 的 sop_stages var sopStages []*ent.SopStage for _, task := range filteredSopTasks { stages, err := task.QueryTaskStages().All(l.ctx) if err != nil { _ = tx.Rollback() return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } sopStages = append(sopStages, stages...) } // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return nil, dberrorhandler.DefaultEntError(l.Logger, err, req) } err = l.AddLabelRelationships(sopStages, *c, finalLabelIds, organizationId, l.ctx, l.Logger) if err != nil { _ = tx.Rollback() return nil, err } } return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil } func (l *BatchUpdateLabelRelationshipsLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, organizationId uint64, ctx context.Context, logger logx.Logger) (err error) { for _, stage := range sopStages { if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) { // 开始事务 tx, err := l.svcCtx.DB.Tx(context.Background()) if err != nil { return dberrorhandler.DefaultEntError(l.Logger, err, nil) } // 判断是否有 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(ctx) if err == nil { continue } // 判断ActionMessage是否为空 sourceType := 3 if stage.ActionMessage != nil { for i, message := range stage.ActionMessage { meta := custom_types.Meta{} if message.Meta != nil { meta.Filename = message.Meta.Filename } _, err = tx.MessageRecords.Create(). SetNotNilBotWxid(&contact.WxWxid). SetNotNilContactID(&contact.ID). SetNotNilContactType(&contact.Type). SetNotNilContactWxid(&contact.Wxid). SetNotNilContentType(&message.Type). SetNotNilContent(&message.Content). SetMeta(meta). SetNotNilSourceType(&sourceType). SetNotNilSourceID(&stage.ID). SetSubSourceID(uint64(i)). SetOrganizationID(organizationId). Save(ctx) if err != nil { _ = tx.Rollback() return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } } if stage.ActionForward != nil { if stage.ActionForward.Wxid != "" { forwardWxids := splitString(stage.ActionForward.Wxid) for _, forwardWxid := range forwardWxids { for i, message := range stage.ActionForward.Action { meta := custom_types.Meta{} if message.Meta != nil { meta.Filename = message.Meta.Filename } _, err = tx.MessageRecords.Create(). SetBotWxid(contact.WxWxid). SetContactID(0). SetContactType(0). SetContactWxid(forwardWxid). SetContentType(message.Type). SetContent(message.Content). SetMeta(meta). SetSourceType(sourceType). SetSourceID(stage.ID). SetSubSourceID(contact.ID + uint64(i)). SetOrganizationID(organizationId). Save(l.ctx) if err != nil { _ = tx.Rollback() return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } } } } if stage.ActionLabelAdd != nil || stage.ActionLabelDel != nil { // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID var newLabelIds []uint64 var remLabelIds []uint64 var finalLabelIds []uint64 // 创建一个映射,用于快速查找 currentLabelIds 中的元素 currentLabelIdSet := make(map[uint64]struct{}) for _, id := range currentLabelIds { currentLabelIdSet[id] = struct{}{} } delLabelIdSet := make(map[uint64]struct{}) for _, id := range stage.ActionLabelDel { delLabelIdSet[id] = struct{}{} } if stage.ActionLabelAdd != nil { // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素 for _, id := range stage.ActionLabelAdd { if _, ce := currentLabelIdSet[id]; !ce { if _, re := delLabelIdSet[id]; !re { newLabelIds = append(newLabelIds, id) } } } if len(newLabelIds) > 0 { // 创建需要新增的标签关系 for _, id := range newLabelIds { _, err = tx.LabelRelationship.Create(). SetLabelID(id). SetContactID(contact.ID). SetOrganizationID(organizationId). Save(ctx) if err != nil { _ = tx.Rollback() return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } // 合并 currentLabelIds 和 newLabelIds currentLabelIds = append(currentLabelIds, newLabelIds...) } } if stage.ActionLabelDel != nil { // 遍历 delLabelIds,找出在 currentLabelIds 中的元素 for _, id := range stage.ActionLabelDel { if _, exists := currentLabelIdSet[id]; exists { remLabelIds = append(newLabelIds, id) delete(currentLabelIdSet, id) } } if len(remLabelIds) > 0 { _, err = tx.LabelRelationship.Delete().Where(labelrelationship.IDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx) if err != nil { //_ = tx.Rollback() return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } } // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return dberrorhandler.DefaultEntError(l.Logger, err, nil) } if len(newLabelIds) == 0 && len(remLabelIds) == 0 { return nil } for id := range currentLabelIdSet { finalLabelIds = append(finalLabelIds, id) } // 递归调用 AddLabelRelationships err = l.AddLabelRelationships(sopStages, contact, finalLabelIds, organizationId, ctx, logger) if err != nil { return err } return nil } else { // 所有操作成功,提交事务 err = tx.Commit() if err != nil { return dberrorhandler.DefaultEntError(l.Logger, err, nil) } } } } // 所有操作成功,提交事务 //err = tx.Commit() //if err != nil { // return dberrorhandler.DefaultEntError(l.Logger, err, nil) //} return nil } // compareLabelIds compares the new label ids with the current ones and returns the ids to be added and removed func compareLabelIdsForIncrement(newLabelIds []uint64, currentLabelIds []uint64, updateType int) (changeLabelIds []uint64, finalLabelIds []uint64) { currentLabelIdsSet := make(map[uint64]struct{}, len(currentLabelIds)) for _, id := range currentLabelIds { currentLabelIdsSet[id] = struct{}{} } for _, id := range newLabelIds { if updateType == 1 { if _, ok := currentLabelIdsSet[id]; ok { delete(currentLabelIdsSet, id) } else { changeLabelIds = append(changeLabelIds, id) finalLabelIds = append(finalLabelIds, id) } } else { if _, ok := currentLabelIdsSet[id]; ok { delete(currentLabelIdsSet, id) changeLabelIds = append(changeLabelIds, id) } } } for id := range currentLabelIdsSet { finalLabelIds = append(finalLabelIds, id) } return }