batch_update_label_relationships_logic.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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 BatchUpdateLabelRelationshipsLogic struct {
  17. logx.Logger
  18. ctx context.Context
  19. svcCtx *svc.ServiceContext
  20. }
  21. func NewBatchUpdateLabelRelationshipsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BatchUpdateLabelRelationshipsLogic {
  22. return &BatchUpdateLabelRelationshipsLogic{
  23. Logger: logx.WithContext(ctx),
  24. ctx: ctx,
  25. svcCtx: svcCtx}
  26. }
  27. func (l *BatchUpdateLabelRelationshipsLogic) BatchUpdateLabelRelationships(req *types.BatchLabelRelationshipsInfo) (resp *types.BaseMsgResp, err error) {
  28. organizationId := l.ctx.Value("organizationId").(uint64)
  29. // 遍历所有联系人
  30. for _, contactId := range req.ContactIds {
  31. // 开始事务
  32. tx, err := l.svcCtx.DB.Tx(context.Background())
  33. if err != nil {
  34. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  35. }
  36. // 获取联系人信息
  37. c, err := tx.Contact.Query().Where(contact.ID(contactId), contact.OrganizationIDEQ(organizationId)).Only(l.ctx)
  38. // 获取联系人当前已关联的标签
  39. currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(contactId)).All(l.ctx)
  40. if err != nil {
  41. _ = tx.Rollback()
  42. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  43. }
  44. // 提取当前标签ID
  45. var currentLabelIds []uint64
  46. for _, relationship := range currentLabelRelationships {
  47. currentLabelIds = append(currentLabelIds, relationship.LabelID)
  48. }
  49. // 对比新旧标签ID,找出需要新增和移除的标签
  50. changeLabelIds, finalLabelIds := compareLabelIdsForIncrement(req.LabelIds, currentLabelIds, req.UpdateType)
  51. // 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时
  52. if req.UpdateType == -1 {
  53. // 删除需要移除的标签关系
  54. for _, id := range changeLabelIds {
  55. _, err := tx.LabelRelationship.
  56. Delete().
  57. Where(
  58. labelrelationship.ContactID(contactId),
  59. labelrelationship.LabelID(id),
  60. ).
  61. Exec(l.ctx)
  62. if err != nil {
  63. _ = tx.Rollback()
  64. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  65. }
  66. }
  67. } else {
  68. // 创建需要新增的标签关系
  69. for _, id := range changeLabelIds {
  70. _, _ = tx.LabelRelationship.Create().
  71. SetLabelID(id).
  72. SetContactID(contactId).
  73. SetOrganizationID(organizationId).
  74. Save(l.ctx)
  75. //if err != nil {
  76. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  77. //}
  78. }
  79. }
  80. // 获取所有 status 为 3 且 bot_wxid_list 包含 c.wx_wxid 的 sop_task
  81. sopTasks, err := tx.SopTask.Query().Where(soptask.Status(3), soptask.OrganizationIDEQ(organizationId)).All(l.ctx)
  82. if err != nil {
  83. _ = tx.Rollback()
  84. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  85. }
  86. var filteredSopTasks []*ent.SopTask
  87. for _, task := range sopTasks {
  88. for _, botWxid := range task.BotWxidList {
  89. if botWxid == c.WxWxid {
  90. filteredSopTasks = append(filteredSopTasks, task)
  91. break
  92. }
  93. }
  94. }
  95. // 获取所有 filteredSopTasks 的 sop_stages
  96. var sopStages []*ent.SopStage
  97. for _, task := range filteredSopTasks {
  98. stages, err := task.QueryTaskStages().All(l.ctx)
  99. if err != nil {
  100. _ = tx.Rollback()
  101. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  102. }
  103. sopStages = append(sopStages, stages...)
  104. }
  105. // 所有操作成功,提交事务
  106. err = tx.Commit()
  107. if err != nil {
  108. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  109. }
  110. err = l.AddLabelRelationships(sopStages, *c, finalLabelIds, organizationId, l.ctx, l.Logger)
  111. if err != nil {
  112. _ = tx.Rollback()
  113. return nil, err
  114. }
  115. }
  116. return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
  117. }
  118. func (l *BatchUpdateLabelRelationshipsLogic) AddLabelRelationships(sopStages []*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, organizationId uint64, ctx context.Context, logger logx.Logger) (err error) {
  119. for _, stage := range sopStages {
  120. if stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) {
  121. // 开始事务
  122. tx, err := l.svcCtx.DB.Tx(context.Background())
  123. if err != nil {
  124. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  125. }
  126. // 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
  127. _, err = tx.MessageRecords.Query().
  128. Where(
  129. messagerecords.ContactWxid(contact.Wxid),
  130. messagerecords.SourceType(3),
  131. messagerecords.SourceID(stage.ID),
  132. messagerecords.SubSourceID(0),
  133. ).
  134. Only(ctx)
  135. if err == nil {
  136. continue
  137. }
  138. // 判断ActionMessage是否为空
  139. sourceType := 3
  140. if stage.ActionMessage != nil {
  141. for i, message := range stage.ActionMessage {
  142. meta := custom_types.Meta{}
  143. if message.Meta != nil {
  144. meta.Filename = message.Meta.Filename
  145. }
  146. _, err = tx.MessageRecords.Create().
  147. SetNotNilBotWxid(&contact.WxWxid).
  148. SetNotNilContactID(&contact.ID).
  149. SetNotNilContactType(&contact.Type).
  150. SetNotNilContactWxid(&contact.Wxid).
  151. SetNotNilContentType(&message.Type).
  152. SetNotNilContent(&message.Content).
  153. SetMeta(meta).
  154. SetNotNilSourceType(&sourceType).
  155. SetNotNilSourceID(&stage.ID).
  156. SetSubSourceID(uint64(i)).
  157. SetOrganizationID(organizationId).
  158. Save(ctx)
  159. if err != nil {
  160. _ = tx.Rollback()
  161. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  162. }
  163. }
  164. }
  165. if stage.ActionForward != nil {
  166. if stage.ActionForward.Wxid != "" {
  167. forwardWxids := splitString(stage.ActionForward.Wxid)
  168. for _, forwardWxid := range forwardWxids {
  169. for i, message := range stage.ActionForward.Action {
  170. meta := custom_types.Meta{}
  171. if message.Meta != nil {
  172. meta.Filename = message.Meta.Filename
  173. }
  174. _, err = tx.MessageRecords.Create().
  175. SetBotWxid(contact.WxWxid).
  176. SetContactID(0).
  177. SetContactType(0).
  178. SetContactWxid(forwardWxid).
  179. SetContentType(message.Type).
  180. SetContent(message.Content).
  181. SetMeta(meta).
  182. SetSourceType(sourceType).
  183. SetSourceID(stage.ID).
  184. SetSubSourceID(contact.ID + uint64(i)).
  185. SetOrganizationID(organizationId).
  186. Save(l.ctx)
  187. if err != nil {
  188. _ = tx.Rollback()
  189. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  190. }
  191. }
  192. }
  193. }
  194. }
  195. if stage.ActionLabelAdd != nil || stage.ActionLabelDel != nil {
  196. // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID
  197. var newLabelIds []uint64
  198. var remLabelIds []uint64
  199. var finalLabelIds []uint64
  200. // 创建一个映射,用于快速查找 currentLabelIds 中的元素
  201. currentLabelIdSet := make(map[uint64]struct{})
  202. for _, id := range currentLabelIds {
  203. currentLabelIdSet[id] = struct{}{}
  204. }
  205. delLabelIdSet := make(map[uint64]struct{})
  206. for _, id := range stage.ActionLabelDel {
  207. delLabelIdSet[id] = struct{}{}
  208. }
  209. if stage.ActionLabelAdd != nil {
  210. // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素
  211. for _, id := range stage.ActionLabelAdd {
  212. if _, ce := currentLabelIdSet[id]; !ce {
  213. if _, re := delLabelIdSet[id]; !re {
  214. newLabelIds = append(newLabelIds, id)
  215. }
  216. }
  217. }
  218. if len(newLabelIds) > 0 {
  219. // 创建需要新增的标签关系
  220. for _, id := range newLabelIds {
  221. _, err = tx.LabelRelationship.Create().
  222. SetLabelID(id).
  223. SetContactID(contact.ID).
  224. SetOrganizationID(organizationId).
  225. Save(ctx)
  226. if err != nil {
  227. _ = tx.Rollback()
  228. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  229. }
  230. }
  231. // 合并 currentLabelIds 和 newLabelIds
  232. currentLabelIds = append(currentLabelIds, newLabelIds...)
  233. }
  234. }
  235. if stage.ActionLabelDel != nil {
  236. // 遍历 delLabelIds,找出在 currentLabelIds 中的元素
  237. for _, id := range stage.ActionLabelDel {
  238. if _, exists := currentLabelIdSet[id]; exists {
  239. remLabelIds = append(newLabelIds, id)
  240. delete(currentLabelIdSet, id)
  241. }
  242. }
  243. if len(remLabelIds) > 0 {
  244. _, err = tx.LabelRelationship.Delete().Where(labelrelationship.IDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
  245. if err != nil {
  246. //_ = tx.Rollback()
  247. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  248. }
  249. }
  250. }
  251. // 所有操作成功,提交事务
  252. err = tx.Commit()
  253. if err != nil {
  254. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  255. }
  256. if len(newLabelIds) == 0 && len(remLabelIds) == 0 {
  257. return nil
  258. }
  259. for id := range currentLabelIdSet {
  260. finalLabelIds = append(finalLabelIds, id)
  261. }
  262. // 递归调用 AddLabelRelationships
  263. err = l.AddLabelRelationships(sopStages, contact, finalLabelIds, organizationId, ctx, logger)
  264. if err != nil {
  265. return err
  266. }
  267. return nil
  268. } else {
  269. // 所有操作成功,提交事务
  270. err = tx.Commit()
  271. if err != nil {
  272. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  273. }
  274. }
  275. }
  276. }
  277. // 所有操作成功,提交事务
  278. //err = tx.Commit()
  279. //if err != nil {
  280. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  281. //}
  282. return nil
  283. }
  284. // compareLabelIds compares the new label ids with the current ones and returns the ids to be added and removed
  285. func compareLabelIdsForIncrement(newLabelIds []uint64, currentLabelIds []uint64, updateType int) (changeLabelIds []uint64, finalLabelIds []uint64) {
  286. currentLabelIdsSet := make(map[uint64]struct{}, len(currentLabelIds))
  287. for _, id := range currentLabelIds {
  288. currentLabelIdsSet[id] = struct{}{}
  289. }
  290. for _, id := range newLabelIds {
  291. if updateType == 1 {
  292. if _, ok := currentLabelIdsSet[id]; ok {
  293. delete(currentLabelIdsSet, id)
  294. } else {
  295. changeLabelIds = append(changeLabelIds, id)
  296. finalLabelIds = append(finalLabelIds, id)
  297. }
  298. } else {
  299. if _, ok := currentLabelIdsSet[id]; ok {
  300. delete(currentLabelIdsSet, id)
  301. changeLabelIds = append(changeLabelIds, id)
  302. }
  303. }
  304. }
  305. for id := range currentLabelIdsSet {
  306. finalLabelIds = append(finalLabelIds, id)
  307. }
  308. return
  309. }