publish_sop_task_logic.go 9.1 KB

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