update_label_relationships_logic.go 7.8 KB

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