publish_sop_task_logic.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. // 开始事务
  31. //tx, err := l.svcCtx.DB.Tx(context.Background())
  32. //if err != nil {
  33. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  34. //}
  35. // 根据 id 查询 sop_task
  36. sopTask, err := l.svcCtx.DB.SopTask.Query().
  37. Where(
  38. soptask.ID(req.Id),
  39. soptask.Status(1),
  40. ).
  41. WithTaskStages().
  42. Only(l.ctx)
  43. if err != nil {
  44. //_ = tx.Rollback()
  45. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  46. }
  47. // 判断 sop_task 是否存在
  48. if sopTask != nil {
  49. if sopTask.BotWxidList == nil {
  50. return nil, errors.New(errormsg.ValidationError)
  51. }
  52. // 查询任务的所有 sop_stages
  53. err = l.svcCtx.DB.SopTask.UpdateOneID(req.Id).
  54. SetStatus(3).
  55. Exec(l.ctx)
  56. if err != nil {
  57. //_ = tx.Rollback()
  58. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  59. }
  60. sopStages, err := l.svcCtx.DB.SopStage.Query().All(l.ctx)
  61. if err != nil {
  62. //_ = tx.Rollback()
  63. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  64. }
  65. // 遍历 stage
  66. for _, stage := range sopTask.Edges.TaskStages {
  67. if stage.ConditionType == 1 {
  68. // 构造查询条件
  69. var predicates []predicate.Contact
  70. for _, condition := range stage.ConditionList {
  71. subPredicate := contact.HasContactRelationshipsWith(
  72. labelrelationship.LabelIDIn(condition.LabelIdList...),
  73. labelrelationship.DeletedAtIsNil())
  74. if condition.Equal == 2 {
  75. subPredicate = contact.Not(subPredicate)
  76. }
  77. predicates = append(predicates, subPredicate)
  78. }
  79. // 查询满足条件的联系人
  80. var contacts []*ent.Contact
  81. var err error
  82. sourceType := 3
  83. if stage.ConditionOperator == 1 {
  84. contacts, err = l.svcCtx.DB.Contact.Query().Where(contact.And(predicates...)).All(l.ctx)
  85. } else {
  86. contacts, err = l.svcCtx.DB.Contact.Query().Where(contact.Or(predicates...)).All(l.ctx)
  87. }
  88. if err != nil {
  89. //_ = tx.Rollback()
  90. return nil, err
  91. }
  92. // 遍历 contacts
  93. for _, c := range contacts {
  94. // 判断联系人所属微信是否包含在任务当中
  95. if sopTask.BotWxidList == nil || (sopTask.BotWxidList != nil && valueInArray(c.WxWxid, sopTask.BotWxidList)) {
  96. for i, message := range stage.ActionMessage {
  97. meta := custom_types.Meta{}
  98. if message.Meta != nil {
  99. meta.Filename = message.Meta.Filename
  100. }
  101. _, _ = l.svcCtx.DB.MessageRecords.Create().
  102. SetNotNilBotWxid(&c.WxWxid).
  103. SetNotNilContactID(&c.ID).
  104. SetNotNilContactType(&c.Type).
  105. SetNotNilContactWxid(&c.Wxid).
  106. SetNotNilContentType(&message.Type).
  107. SetNotNilContent(&message.Content).
  108. SetMeta(meta).
  109. SetNotNilSourceType(&sourceType).
  110. SetNotNilSourceID(&stage.ID).
  111. SetSubSourceID(uint64(i)).
  112. Save(l.ctx)
  113. //if err != nil {
  114. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  115. //}
  116. }
  117. // 查询当前联系人的标签关系
  118. currentLabelRelationships, err := l.svcCtx.DB.LabelRelationship.Query().Where(labelrelationship.ContactID(c.ID)).All(l.ctx)
  119. if err != nil {
  120. //_ = tx.Rollback()
  121. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  122. }
  123. // 提取当前标签ID
  124. var currentLabelIds []uint64
  125. for _, relationship := range currentLabelRelationships {
  126. currentLabelIds = append(currentLabelIds, relationship.LabelID)
  127. }
  128. if stage.ActionLabel != nil {
  129. // 递归调用 AddLabelRelationships
  130. err = l.AddLabelRelationships(sopStages, *c, currentLabelIds, stage.ActionLabel)
  131. if err != nil {
  132. //_ = tx.Rollback()
  133. return nil, err
  134. }
  135. }
  136. }
  137. }
  138. }
  139. }
  140. // 所有操作成功,提交事务
  141. //err = tx.Commit()
  142. //if err != nil {
  143. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  144. //}
  145. return &types.BaseMsgResp{Msg: errormsg.Success}, nil
  146. } else {
  147. // 所有操作成功,提交事务
  148. //err = tx.Commit()
  149. //if err != nil {
  150. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  151. //}
  152. //// 返回错误信息:任务不存在
  153. return nil, errors.New(errormsg.TargetNotFound)
  154. }
  155. }
  156. func (l *PublishSopTaskLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, addLabelIds []uint64) (err error) {
  157. //// 开始事务
  158. //tx, err := l.svcCtx.DB.Tx(context.Background())
  159. //if err != nil {
  160. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  161. //}
  162. // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID
  163. var newLabelIds []uint64
  164. // 创建一个映射,用于快速查找 currentLabelIds 中的元素
  165. currentLabelIdSet := make(map[uint64]struct{})
  166. for _, id := range currentLabelIds {
  167. currentLabelIdSet[id] = struct{}{}
  168. }
  169. // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素
  170. for _, id := range addLabelIds {
  171. if _, exists := currentLabelIdSet[id]; !exists {
  172. newLabelIds = append(newLabelIds, id)
  173. }
  174. }
  175. if len(newLabelIds) == 0 {
  176. return nil
  177. }
  178. // 创建需要新增的标签关系
  179. for _, id := range newLabelIds {
  180. _, err = l.svcCtx.DB.LabelRelationship.Create().
  181. SetLabelID(id).
  182. SetContactID(contact.ID).
  183. Save(l.ctx)
  184. if err != nil {
  185. //_ = tx.Rollback()
  186. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  187. }
  188. }
  189. // 合并 currentLabelIds 和 newLabelIds
  190. currentLabelIds = append(currentLabelIds, newLabelIds...)
  191. // 遍历 sop_stages,找出满足条件的 stage
  192. for _, stage := range sopStages {
  193. if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) {
  194. // 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
  195. _, err := l.svcCtx.DB.MessageRecords.Query().
  196. Where(
  197. messagerecords.ContactWxid(contact.Wxid),
  198. messagerecords.SourceType(3),
  199. messagerecords.SourceID(stage.ID),
  200. messagerecords.SubSourceID(0),
  201. ).
  202. Only(l.ctx)
  203. if err != nil {
  204. continue
  205. }
  206. // 判断ActionMessage是否为空
  207. sourceType := 3
  208. if stage.ActionMessage != nil {
  209. for i, message := range stage.ActionMessage {
  210. meta := custom_types.Meta{}
  211. if message.Meta != nil {
  212. meta.Filename = message.Meta.Filename
  213. }
  214. _, _ = l.svcCtx.DB.MessageRecords.Create().
  215. SetNotNilBotWxid(&contact.WxWxid).
  216. SetNotNilContactID(&contact.ID).
  217. SetNotNilContactType(&contact.Type).
  218. SetNotNilContactWxid(&contact.Wxid).
  219. SetNotNilContentType(&message.Type).
  220. SetNotNilContent(&message.Content).
  221. SetMeta(meta).
  222. SetNotNilSourceType(&sourceType).
  223. SetNotNilSourceID(&stage.ID).
  224. SetSubSourceID(uint64(i)).
  225. Save(l.ctx)
  226. //if err != nil {
  227. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  228. //}
  229. }
  230. }
  231. if stage.ActionLabel != nil {
  232. // 递归调用 AddLabelRelationships
  233. err = l.AddLabelRelationships(sopStages, contact, currentLabelIds, stage.ActionLabel)
  234. if err != nil {
  235. //_ = tx.Rollback()
  236. return err
  237. }
  238. }
  239. }
  240. }
  241. // 所有操作成功,提交事务
  242. //err = tx.Commit()
  243. //if err != nil {
  244. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  245. //}
  246. return nil
  247. }
  248. func valueInArray(val string, array []string) bool {
  249. for _, item := range array {
  250. if item == val {
  251. return true
  252. }
  253. }
  254. return false
  255. }
  256. func isLabelIdListMatchFilter(labelIdList []uint64, conditionOperator int, conditionList []custom_types.Condition) bool {
  257. labelIdSet := make(map[uint64]struct{})
  258. for _, id := range labelIdList {
  259. labelIdSet[id] = struct{}{}
  260. }
  261. for _, condition := range conditionList {
  262. match := false
  263. for _, id := range condition.LabelIdList {
  264. if _, ok := labelIdSet[id]; ok {
  265. match = true
  266. break
  267. }
  268. }
  269. if condition.Equal == 2 {
  270. match = !match
  271. }
  272. if (conditionOperator == 1 && !match) || (conditionOperator == 2 && match) {
  273. return match
  274. }
  275. }
  276. return conditionOperator == 1
  277. }