Explorar el Código

修复长时间未回复打标问题

boweniac hace 4 meses
padre
commit
d6117fd064

+ 228 - 0
crontask/send_wx_on_timeout.go

@@ -6,15 +6,28 @@ import (
 	"time"
 	"wechat-api/ent"
 	"wechat-api/ent/custom_types"
+	"wechat-api/ent/labelrelationship"
 	"wechat-api/ent/messagerecords"
 	"wechat-api/ent/sopnode"
 	"wechat-api/ent/sopstage"
 	"wechat-api/ent/soptask"
+	"wechat-api/internal/utils/dberrorhandler"
 )
 
 func (l *CronTask) sendWxOnTimeout() {
 	ctx := context.Background()
 	startTime := time.Now()
+	sopTask, _ := l.svcCtx.DB.SopTask.Query().
+		Where(
+			soptask.StatusEQ(3),
+			soptask.DeletedAtIsNil(),
+		).
+		All(l.ctx)
+	sopTasks := make([]uint64, 0)
+	for _, st := range sopTask {
+		sopTasks = append(sopTasks, st.ID)
+	}
+	sopStages, _ := l.svcCtx.DB.SopStage.Query().Where(sopstage.TaskIDIn(sopTasks...), sopstage.DeletedAtIsNil()).All(l.ctx)
 
 	// 查询所有 no_reply_condition 值非 0  的 sop_node 记录
 	nodes, err := l.svcCtx.DB.SopNode.Query().
@@ -142,6 +155,27 @@ func (l *CronTask) sendWxOnTimeout() {
 						}
 					}
 				}
+
+				// 查询当前联系人的标签关系
+				currentLabelRelationships, _ := l.svcCtx.DB.LabelRelationship.Query().Where(labelrelationship.ContactID(s.ContactID)).All(l.ctx)
+
+				if currentLabelRelationships == nil {
+					continue
+				}
+				// 提取当前标签ID
+				var currentLabelIds []uint64
+				for _, relationship := range currentLabelRelationships {
+					currentLabelIds = append(currentLabelIds, relationship.LabelID)
+				}
+				contact := &ent.Contact{
+					ID:     s.ContactID,
+					Type:   s.ContentType,
+					WxWxid: s.BotWxid,
+					Wxid:   s.ContactWxid,
+				}
+				if node.ActionLabelAdd != nil || node.ActionLabelDel != nil {
+					_ = l.AddLabelRelationships(sopStages, *contact, currentLabelIds, node.ActionLabelAdd, node.ActionLabelDel, s.OrganizationID)
+				}
 			}
 		}
 	}
@@ -158,3 +192,197 @@ func splitString(input string) []string {
 	// Split the input string based on the pattern
 	return re.Split(input, -1)
 }
+
+func (l *CronTask) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, addLabelIds []uint64, delLabelIds []uint64, organizationId 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
+	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 delLabelIds {
+		delLabelIdSet[id] = struct{}{}
+	}
+
+	if addLabelIds != nil {
+		// 遍历 addLabelIds,找出不在 currentLabelIds 中的元素
+		for _, id := range addLabelIds {
+			if _, ce := currentLabelIdSet[id]; !ce {
+				if _, re := delLabelIdSet[id]; !re {
+					newLabelIds = append(newLabelIds, id)
+				}
+			}
+		}
+
+		if len(newLabelIds) > 0 {
+			// 创建需要新增的标签关系
+			for _, id := range newLabelIds {
+				currentLabelIdSet[id] = struct{}{}
+				_, err = l.svcCtx.DB.LabelRelationship.Create().
+					SetLabelID(id).
+					SetContactID(contact.ID).
+					SetOrganizationID(organizationId).
+					Save(l.ctx)
+				if err != nil {
+					//_ = tx.Rollback()
+					return dberrorhandler.DefaultEntError(l.Logger, err, nil)
+				}
+			}
+
+			// 合并 currentLabelIds 和 newLabelIds
+			currentLabelIds = append(currentLabelIds, newLabelIds...)
+		}
+	}
+	if delLabelIds != nil {
+		// 遍历 delLabelIds,找出在 currentLabelIds 中的元素
+		for _, id := range delLabelIds {
+			if _, exists := currentLabelIdSet[id]; exists {
+				remLabelIds = append(newLabelIds, id)
+				delete(currentLabelIdSet, id)
+			}
+		}
+
+		if len(remLabelIds) > 0 {
+			_, err = l.svcCtx.DB.LabelRelationship.Delete().Where(labelrelationship.LabelIDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
+			if err != nil {
+				//_ = tx.Rollback()
+				return dberrorhandler.DefaultEntError(l.Logger, err, nil)
+			}
+		}
+	}
+
+	if len(newLabelIds) == 0 && len(remLabelIds) == 0 {
+		return nil
+	}
+	for id := range currentLabelIdSet {
+		finalLabelIds = append(finalLabelIds, id)
+	}
+	// 遍历 sop_stages,找出满足条件的 stage
+	for _, stage := range sopStages {
+		if stage.ConditionType == 1 && isLabelIdListMatchFilter(finalLabelIds, stage.ConditionOperator, stage.ConditionList) {
+			// 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
+			_, err := l.svcCtx.DB.MessageRecords.Query().
+				Where(
+					messagerecords.ContactWxid(contact.Wxid),
+					messagerecords.SourceType(3),
+					messagerecords.SourceID(stage.ID),
+					messagerecords.SubSourceID(0),
+				).
+				Only(l.ctx)
+			if !ent.IsNotFound(err) {
+				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
+					}
+					_, _ = l.svcCtx.DB.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(l.ctx)
+
+					//if err != nil {
+					//	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 = l.svcCtx.DB.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 stage.ActionLabelAdd != nil || stage.ActionLabelDel != nil {
+				// 递归调用 AddLabelRelationships
+				err = l.AddLabelRelationships(sopStages, contact, finalLabelIds, stage.ActionLabelAdd, stage.ActionLabelDel, organizationId)
+				if err != nil {
+					//_ = tx.Rollback()
+					return err
+				}
+			}
+		}
+
+	}
+
+	// 所有操作成功,提交事务
+	//err = tx.Commit()
+	//if err != nil {
+	//	return dberrorhandler.DefaultEntError(l.Logger, err, nil)
+	//}
+	return nil
+}
+
+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 {
+			return false
+		} else if conditionOperator == 2 && match {
+			return true
+		}
+	}
+
+	return conditionOperator == 1
+}

+ 19 - 1
hook/message.go

@@ -5,6 +5,8 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/gorilla/websocket"
+	"path/filepath"
+	"strings"
 	"wechat-api/workphone"
 )
 
@@ -128,13 +130,17 @@ func (h *Hook) SendPicMsg(wxid, picpath, diyfilename, wxWxid string) (err error)
 			}
 		}(conn)
 		encodedString := base64.StdEncoding.EncodeToString([]byte(picpath))
+		contentType := "File"
+		if isImageFile(diyfilename) {
+			contentType = "Picture"
+		}
 
 		message := map[string]interface{}{
 			"MsgType": "TalkToFriendTask",
 			"Content": map[string]interface{}{
 				"WeChatId":    wxWxid,
 				"FriendId":    wxid,
-				"ContentType": "File",
+				"ContentType": contentType,
 				"Content":     encodedString,
 			},
 		}
@@ -194,3 +200,15 @@ func (h *Hook) SendPicMsgLocal(wxid, picpath string) (err error) {
 	}
 	return
 }
+
+func isImageFile(filename string) bool {
+	ext := strings.ToLower(filepath.Ext(filename))
+	imageExtensions := []string{".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp"}
+
+	for _, extToCheck := range imageExtensions {
+		if ext == extToCheck {
+			return true
+		}
+	}
+	return false
+}

+ 8 - 5
internal/logic/sop_task/publish_sop_task_logic.go

@@ -74,7 +74,7 @@ func (l *PublishSopTaskLogic) PublishSopTask(req *types.IDReq) (resp *types.Base
 		}
 
 		sopStages, err := l.svcCtx.DB.SopStage.Query().
-			Where(sopstage.HasSopTaskWith(soptask.OrganizationIDEQ(organizationId))).
+			Where(sopstage.HasSopTaskWith(soptask.OrganizationIDEQ(organizationId), soptask.StatusEQ(3), soptask.DeletedAtIsNil()), sopstage.DeletedAtIsNil()).
 			All(l.ctx)
 		if err != nil {
 			//_ = tx.Rollback()
@@ -249,6 +249,7 @@ func (l *PublishSopTaskLogic) AddLabelRelationships(sopStages []*ent.SopStage, c
 		if len(newLabelIds) > 0 {
 			// 创建需要新增的标签关系
 			for _, id := range newLabelIds {
+				currentLabelIdSet[id] = struct{}{}
 				_, err = l.svcCtx.DB.LabelRelationship.Create().
 					SetLabelID(id).
 					SetContactID(contact.ID).
@@ -275,7 +276,7 @@ func (l *PublishSopTaskLogic) AddLabelRelationships(sopStages []*ent.SopStage, c
 		}
 
 		if len(remLabelIds) > 0 {
-			_, err = l.svcCtx.DB.LabelRelationship.Delete().Where(labelrelationship.IDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
+			_, err = l.svcCtx.DB.LabelRelationship.Delete().Where(labelrelationship.LabelIDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
 			if err != nil {
 				//_ = tx.Rollback()
 				return dberrorhandler.DefaultEntError(l.Logger, err, nil)
@@ -303,7 +304,7 @@ func (l *PublishSopTaskLogic) AddLabelRelationships(sopStages []*ent.SopStage, c
 					messagerecords.SubSourceID(0),
 				).
 				Only(l.ctx)
-			if err != nil {
+			if !ent.IsNotFound(err) {
 				continue
 			}
 			// 判断ActionMessage是否为空
@@ -410,8 +411,10 @@ func isLabelIdListMatchFilter(labelIdList []uint64, conditionOperator int, condi
 			match = !match
 		}
 
-		if (conditionOperator == 1 && !match) || (conditionOperator == 2 && match) {
-			return match
+		if conditionOperator == 1 && !match {
+			return false
+		} else if conditionOperator == 2 && match {
+			return true
 		}
 	}