publish_sop_task_logic.go 7.0 KB

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