update_label_relationships_logic.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. package label_relationship
  2. import (
  3. "context"
  4. "github.com/suyuan32/simple-admin-common/msg/errormsg"
  5. "regexp"
  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/soptask"
  12. "wechat-api/internal/svc"
  13. "wechat-api/internal/types"
  14. "wechat-api/internal/utils/dberrorhandler"
  15. "github.com/zeromicro/go-zero/core/logx"
  16. )
  17. type UpdateLabelRelationshipsLogic struct {
  18. logx.Logger
  19. ctx context.Context
  20. svcCtx *svc.ServiceContext
  21. }
  22. func NewUpdateLabelRelationshipsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLabelRelationshipsLogic {
  23. return &UpdateLabelRelationshipsLogic{
  24. Logger: logx.WithContext(ctx),
  25. ctx: ctx,
  26. svcCtx: svcCtx}
  27. }
  28. func (l *UpdateLabelRelationshipsLogic) UpdateLabelRelationships(req *types.LabelRelationshipsInfo) (resp *types.BaseMsgResp, err error) {
  29. organizationId := l.ctx.Value("organizationId").(uint64)
  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. // 获取联系人信息
  36. c, err := tx.Contact.Query().Where(contact.ID(*req.ContactId), contact.OrganizationIDEQ(organizationId)).Only(l.ctx)
  37. // 获取联系人当前已关联的标签
  38. currentLabelRelationships, err := tx.LabelRelationship.Query().Where(labelrelationship.ContactID(*req.ContactId)).All(l.ctx)
  39. if err != nil {
  40. _ = tx.Rollback()
  41. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  42. }
  43. // 提取当前标签ID
  44. var currentLabelIds []uint64
  45. for _, relationship := range currentLabelRelationships {
  46. currentLabelIds = append(currentLabelIds, relationship.LabelID)
  47. }
  48. // 对比新旧标签ID,找出需要新增和移除的标签
  49. addLabelIds, removeLabelIds := compareLabelIds(req.LabelIds, currentLabelIds)
  50. // 如果 req.UpdateType 为空,或 req.UpdateType 的值为 “all” 时
  51. if req.UpdateType == nil || *req.UpdateType == "all" {
  52. // 删除需要移除的标签关系
  53. l.Logger.Errorf("------------------------removeLabelIds--------------------------- %+v\n", removeLabelIds)
  54. for _, id := range removeLabelIds {
  55. _, err := tx.LabelRelationship.
  56. Delete().
  57. Where(
  58. labelrelationship.ContactID(*req.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. }
  68. // 创建需要新增的标签关系
  69. l.Logger.Errorf("------------------------addLabelIds--------------------------- %+v\n", addLabelIds)
  70. for _, id := range addLabelIds {
  71. _, _ = tx.LabelRelationship.Create().
  72. SetLabelID(id).
  73. SetContactID(*req.ContactId).
  74. SetOrganizationID(organizationId).
  75. Save(l.ctx)
  76. //if err != nil {
  77. // return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  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. stageMap := make(map[uint64]*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. for _, stage := range stages {
  104. stageMap[stage.ID] = stage
  105. }
  106. //sopStages = append(sopStages, stages...)
  107. }
  108. // 所有操作成功,提交事务
  109. err = tx.Commit()
  110. if err != nil {
  111. return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
  112. }
  113. err = l.AddLabelRelationships(stageMap, *c, req.LabelIds, organizationId)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
  118. }
  119. func (l *UpdateLabelRelationshipsLogic) AddLabelRelationships(sopStages map[uint64]*ent.SopStage, contact ent.Contact, currentLabelIds []uint64, organizationId uint64) (err error) {
  120. // 遍历 sop_stages,找出满足条件的 stage
  121. for key, stage := range sopStages {
  122. if stage != nil && stage.ConditionType == 1 && isLabelIdListMatchFilter(currentLabelIds, stage.ConditionOperator, stage.ConditionList) {
  123. // 开始事务
  124. tx, err := l.svcCtx.DB.Tx(context.Background())
  125. if err != nil {
  126. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  127. }
  128. // 判断是否有 contact_wxid、source_type、source_id、sub_source_id 相同的记录
  129. _, err = tx.MessageRecords.Query().
  130. Where(
  131. messagerecords.ContactWxid(contact.Wxid),
  132. messagerecords.SourceType(3),
  133. messagerecords.SourceID(stage.ID),
  134. messagerecords.SubSourceID(0),
  135. ).
  136. Only(l.ctx)
  137. if err == nil {
  138. continue
  139. }
  140. // 判断ActionMessage是否为空
  141. sourceType := 3
  142. if stage.ActionMessage != nil {
  143. for i, message := range stage.ActionMessage {
  144. meta := custom_types.Meta{}
  145. if message.Meta != nil {
  146. meta.Filename = message.Meta.Filename
  147. }
  148. _, err = tx.MessageRecords.Create().
  149. SetNotNilBotWxid(&contact.WxWxid).
  150. SetNotNilContactID(&contact.ID).
  151. SetNotNilContactType(&contact.Type).
  152. SetNotNilContactWxid(&contact.Wxid).
  153. SetNotNilContentType(&message.Type).
  154. SetNotNilContent(&message.Content).
  155. SetMeta(meta).
  156. SetNotNilSourceType(&sourceType).
  157. SetNotNilSourceID(&stage.ID).
  158. SetSubSourceID(uint64(i)).
  159. SetOrganizationID(organizationId).
  160. Save(l.ctx)
  161. if err != nil {
  162. _ = tx.Rollback()
  163. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  164. }
  165. }
  166. }
  167. if stage.ActionForward != nil {
  168. if stage.ActionForward.Wxid != "" {
  169. forwardWxids := splitString(stage.ActionForward.Wxid)
  170. for _, forwardWxid := range forwardWxids {
  171. for i, message := range stage.ActionForward.Action {
  172. meta := custom_types.Meta{}
  173. if message.Meta != nil {
  174. meta.Filename = message.Meta.Filename
  175. }
  176. _, err = tx.MessageRecords.Create().
  177. SetBotWxid(contact.WxWxid).
  178. SetContactID(0).
  179. SetContactType(0).
  180. SetContactWxid(forwardWxid).
  181. SetContentType(message.Type).
  182. SetContent(message.Content).
  183. SetMeta(meta).
  184. SetSourceType(sourceType).
  185. SetSourceID(stage.ID).
  186. SetSubSourceID(contact.ID + uint64(i)).
  187. SetOrganizationID(organizationId).
  188. Save(l.ctx)
  189. if err != nil {
  190. _ = tx.Rollback()
  191. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  192. }
  193. }
  194. }
  195. }
  196. }
  197. if stage.ActionLabelAdd != nil || stage.ActionLabelDel != nil {
  198. // 获取 addLabelIds 中不在 currentLabelIds 中的标签ID
  199. var newLabelIds []uint64
  200. var remLabelIds []uint64
  201. var finalLabelIds []uint64
  202. // 创建一个映射,用于快速查找 currentLabelIds 中的元素
  203. currentLabelIdSet := make(map[uint64]struct{})
  204. for _, id := range currentLabelIds {
  205. currentLabelIdSet[id] = struct{}{}
  206. }
  207. delLabelIdSet := make(map[uint64]struct{})
  208. for _, id := range stage.ActionLabelDel {
  209. delLabelIdSet[id] = struct{}{}
  210. }
  211. if stage.ActionLabelAdd != nil {
  212. // 遍历 addLabelIds,找出不在 currentLabelIds 中的元素
  213. for _, id := range stage.ActionLabelAdd {
  214. if _, ce := currentLabelIdSet[id]; !ce {
  215. if _, re := delLabelIdSet[id]; !re {
  216. newLabelIds = append(newLabelIds, id)
  217. }
  218. }
  219. }
  220. if len(newLabelIds) > 0 {
  221. // 创建需要新增的标签关系
  222. for _, id := range newLabelIds {
  223. _, err = tx.LabelRelationship.Create().
  224. SetLabelID(id).
  225. SetContactID(contact.ID).
  226. SetOrganizationID(organizationId).
  227. Save(l.ctx)
  228. if err != nil {
  229. _ = tx.Rollback()
  230. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  231. }
  232. }
  233. }
  234. // 合并 currentLabelIds 和 newLabelIds
  235. currentLabelIds = append(currentLabelIds, newLabelIds...)
  236. }
  237. if stage.ActionLabelDel != nil {
  238. // 遍历 delLabelIds,找出在 currentLabelIds 中的元素
  239. for _, id := range stage.ActionLabelDel {
  240. if _, exists := currentLabelIdSet[id]; exists {
  241. remLabelIds = append(remLabelIds, id)
  242. delete(currentLabelIdSet, id)
  243. }
  244. }
  245. l.Logger.Errorf("------------------------stage.ActionLabelDel--------------------------- %+v\n", stage.ActionLabelDel)
  246. l.Logger.Errorf("------------------------remLabelIds--------------------------- %+v\n", stage.ActionLabelDel)
  247. if len(remLabelIds) > 0 {
  248. _, err = tx.LabelRelationship.Delete().Where(labelrelationship.LabelIDIn(remLabelIds...), labelrelationship.ContactIDEQ(contact.ID), labelrelationship.OrganizationIDEQ(organizationId)).Exec(l.ctx)
  249. if err != nil {
  250. //_ = tx.Rollback()
  251. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  252. }
  253. }
  254. }
  255. // 所有操作成功,提交事务
  256. err = tx.Commit()
  257. if err != nil {
  258. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  259. }
  260. if len(newLabelIds) == 0 && len(remLabelIds) == 0 {
  261. return nil
  262. }
  263. for id := range currentLabelIdSet {
  264. finalLabelIds = append(finalLabelIds, id)
  265. }
  266. // 递归调用 AddLabelRelationships
  267. sopStages[key] = nil
  268. err = l.AddLabelRelationships(sopStages, contact, finalLabelIds, organizationId)
  269. if err != nil {
  270. return err
  271. }
  272. return nil
  273. } else {
  274. // 所有操作成功,提交事务
  275. err = tx.Commit()
  276. if err != nil {
  277. return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  278. }
  279. }
  280. }
  281. }
  282. // 所有操作成功,提交事务
  283. //err = tx.Commit()
  284. //if err != nil {
  285. // return dberrorhandler.DefaultEntError(l.Logger, err, nil)
  286. //}
  287. return nil
  288. }
  289. // compareLabelIds compares the new label ids with the current ones and returns the ids to be added and removed
  290. func compareLabelIds(newLabelIds []uint64, currentLabelIds []uint64) (addLabelIds []uint64, removeLabelIds []uint64) {
  291. newLabelIdSet := make(map[uint64]struct{}, len(newLabelIds))
  292. for _, id := range newLabelIds {
  293. newLabelIdSet[id] = struct{}{}
  294. }
  295. for _, id := range currentLabelIds {
  296. if _, ok := newLabelIdSet[id]; ok {
  297. delete(newLabelIdSet, id)
  298. } else {
  299. removeLabelIds = append(removeLabelIds, id)
  300. }
  301. }
  302. for id := range newLabelIdSet {
  303. addLabelIds = append(addLabelIds, id)
  304. }
  305. return
  306. }
  307. func isLabelIdListMatchFilter(labelIdList []uint64, conditionOperator int, conditionList []custom_types.Condition) bool {
  308. labelIdSet := make(map[uint64]struct{})
  309. for _, id := range labelIdList {
  310. labelIdSet[id] = struct{}{}
  311. }
  312. for _, condition := range conditionList {
  313. match := false
  314. for _, id := range condition.LabelIdList {
  315. if _, ok := labelIdSet[id]; ok {
  316. match = true
  317. break
  318. }
  319. }
  320. if condition.Equal == 2 {
  321. match = !match
  322. }
  323. if (conditionOperator == 1 && !match) || (conditionOperator == 2 && match) {
  324. return match
  325. }
  326. }
  327. return conditionOperator == 1
  328. }
  329. func splitString(input string) []string {
  330. // Define the regular expression pattern to match Chinese comma, English comma, and Chinese enumeration comma
  331. pattern := `[,,、]`
  332. re := regexp.MustCompile(pattern)
  333. // Split the input string based on the pattern
  334. return re.Split(input, -1)
  335. }