update_label_relationships_logic.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package label_relationship
  2. import (
  3. "context"
  4. "github.com/suyuan32/simple-admin-common/msg/errormsg"
  5. "wechat-api/ent"
  6. "wechat-api/ent/contact"
  7. "wechat-api/ent/custom_types"
  8. "wechat-api/ent/labelrelationship"
  9. "wechat-api/ent/messagerecords"
  10. "wechat-api/ent/soptask"
  11. "wechat-api/internal/svc"
  12. "wechat-api/internal/types"
  13. "wechat-api/internal/utils/dberrorhandler"
  14. "github.com/zeromicro/go-zero/core/logx"
  15. )
  16. type UpdateLabelRelationshipsLogic struct {
  17. logx.Logger
  18. ctx context.Context
  19. svcCtx *svc.ServiceContext
  20. }
  21. func NewUpdateLabelRelationshipsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLabelRelationshipsLogic {
  22. return &UpdateLabelRelationshipsLogic{
  23. Logger: logx.WithContext(ctx),
  24. ctx: ctx,
  25. svcCtx: svcCtx}
  26. }
  27. func (l *UpdateLabelRelationshipsLogic) UpdateLabelRelationships(req *types.LabelRelationshipsInfo) (resp *types.BaseMsgResp, err error) {
  28. // 获取联系人信息
  29. c, err := l.svcCtx.DB.Contact.Query().Where(contact.ID(*req.ContactId)).Only(l.ctx)
  30. // 获取联系人当前已关联的标签
  31. currentLabelRelationships, err := l.svcCtx.DB.LabelRelationship.Query().Where(labelrelationship.ContactID(*req.ContactId)).All(l.ctx)
  32. if err != nil {
  33. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  34. }
  35. // 提取当前标签ID
  36. var currentLabelIds []uint64
  37. for _, relationship := range currentLabelRelationships {
  38. currentLabelIds = append(currentLabelIds, relationship.LabelID)
  39. }
  40. // 对比新旧标签ID,找出需要新增和移除的标签
  41. addLabelIds, removeLabelIds := compareLabelIds(req.LabelIds, currentLabelIds)
  42. // 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时
  43. if req.UpdateType == nil || *req.UpdateType == "all" {
  44. // 删除需要移除的标签关系
  45. for _, id := range removeLabelIds {
  46. _, err := l.svcCtx.DB.LabelRelationship.
  47. Delete().
  48. Where(
  49. labelrelationship.ContactID(*req.ContactId),
  50. labelrelationship.LabelID(id),
  51. ).
  52. Exec(l.ctx)
  53. if err != nil {
  54. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  55. }
  56. }
  57. }
  58. // 创建需要新增的标签关系
  59. for _, id := range addLabelIds {
  60. _, _ = l.svcCtx.DB.LabelRelationship.Create().
  61. SetLabelID(id).
  62. SetContactID(*req.ContactId).
  63. Save(l.ctx)
  64. //if err != nil {
  65. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  66. //}
  67. }
  68. currentLabelIds = req.LabelIds
  69. // 获取所有 status 为 3 且 bot_wxid_list 包含 c.wx_wxid 的 sop_task
  70. sopTasks, err := l.svcCtx.DB.SopTask.Query().Where(soptask.Status(3)).All(l.ctx)
  71. if err != nil {
  72. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  73. }
  74. var filteredSopTasks []*ent.SopTask
  75. for _, task := range sopTasks {
  76. for _, botWxid := range task.BotWxidList {
  77. if botWxid == c.WxWxid {
  78. filteredSopTasks = append(filteredSopTasks, task)
  79. break
  80. }
  81. }
  82. }
  83. // 获取所有 filteredSopTasks 的 sop_stages
  84. var sopStages []*ent.SopStage
  85. for _, task := range filteredSopTasks {
  86. stages, err := task.QueryTaskStages().All(l.ctx)
  87. if err != nil {
  88. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  89. }
  90. sopStages = append(sopStages, stages...)
  91. }
  92. err = l.AddLabelRelationships(sopStages, *c, currentLabelIds)
  93. if err != nil {
  94. return nil, err
  95. }
  96. return &types.BaseMsgResp{
  97. Code: 0,
  98. Msg: errormsg.Success,
  99. }, nil
  100. }
  101. func (l *UpdateLabelRelationshipsLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64) (err error) {
  102. // 遍历 sop_stages,找出满足条件的 stage
  103. for _, stage := range sopStages {
  104. if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) {
  105. // 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
  106. _, err = l.svcCtx.DB.MessageRecords.Query().
  107. Where(
  108. messagerecords.ContactWxid(contact.Wxid),
  109. messagerecords.SourceType(3),
  110. messagerecords.SourceID(stage.ID),
  111. messagerecords.SubSourceID(0),
  112. ).
  113. Only(l.ctx)
  114. if err == nil {
  115. continue
  116. }
  117. // 判断ActionMessage是否为空
  118. sourceType := 3
  119. if stage.ActionMessage != nil {
  120. for _, message := range stage.ActionMessage {
  121. _, _ = l.svcCtx.DB.MessageRecords.Create().
  122. SetNotNilBotWxid(&contact.WxWxid).
  123. SetNotNilContactID(&contact.ID).
  124. SetNotNilContactType(&contact.Type).
  125. SetNotNilContactWxid(&contact.Wxid).
  126. SetNotNilContentType(&message.Type).
  127. SetNotNilContent(&message.Content).
  128. SetNotNilSourceType(&sourceType).
  129. SetNotNilSourceID(&stage.ID).
  130. Save(l.ctx)
  131. //if err != nil {
  132. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  133. //}
  134. }
  135. }
  136. if stage.ActionLabel != nil {
  137. // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID
  138. var newLabelIds []uint64
  139. // 创建一个映射,用于快速查找 currentLabelIds 中的元素
  140. currentLabelIdSet := make(map[uint64]struct{})
  141. for _, id := range currentLabelIds {
  142. currentLabelIdSet[id] = struct{}{}
  143. }
  144. // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素
  145. for _, id := range stage.ActionLabel {
  146. if _, exists := currentLabelIdSet[id]; !exists {
  147. newLabelIds = append(newLabelIds, id)
  148. }
  149. }
  150. if len(newLabelIds) == 0 {
  151. return nil
  152. }
  153. // 创建需要新增的标签关系
  154. for _, id := range newLabelIds {
  155. _, err = l.svcCtx.DB.LabelRelationship.Create().
  156. SetLabelID(id).
  157. SetContactID(contact.ID).
  158. Save(l.ctx)
  159. //if err != nil {
  160. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  161. //}
  162. }
  163. // 合并 currentLabelIds 和 newLabelIds
  164. currentLabelIds = append(currentLabelIds, newLabelIds...)
  165. // 递归调用 AddLabelRelationships
  166. err = l.AddLabelRelationships(sopStages, contact, currentLabelIds)
  167. if err != nil {
  168. return err
  169. }
  170. }
  171. }
  172. }
  173. return nil
  174. }
  175. // compareLabelIds compares the new label ids with the current ones and returns the ids to be added and removed
  176. func compareLabelIds(newLabelIds []uint64, currentLabelIds []uint64) (addLabelIds []uint64, removeLabelIds []uint64) {
  177. newLabelIdSet := make(map[uint64]struct{}, len(newLabelIds))
  178. for _, id := range newLabelIds {
  179. newLabelIdSet[id] = struct{}{}
  180. }
  181. for _, id := range currentLabelIds {
  182. if _, ok := newLabelIdSet[id]; ok {
  183. delete(newLabelIdSet, id)
  184. } else {
  185. removeLabelIds = append(removeLabelIds, id)
  186. }
  187. }
  188. for id := range newLabelIdSet {
  189. addLabelIds = append(addLabelIds, id)
  190. }
  191. return
  192. }
  193. func isLabelIdListMatchFilter(labelIdList []uint64, conditionOperator int, conditionList []custom_types.Condition) bool {
  194. labelIdSet := make(map[uint64]struct{})
  195. for _, id := range labelIdList {
  196. labelIdSet[id] = struct{}{}
  197. }
  198. for _, condition := range conditionList {
  199. match := false
  200. for _, id := range condition.LabelIdList {
  201. if _, ok := labelIdSet[id]; ok {
  202. match = true
  203. break
  204. }
  205. }
  206. if condition.Equal == 2 {
  207. match = !match
  208. }
  209. if (conditionOperator == 1 && !match) || (conditionOperator == 2 && match) {
  210. return match
  211. }
  212. }
  213. return conditionOperator == 1
  214. }