123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package wecom
- import (
- "context"
- "encoding/json"
- "entgo.io/ent/dialect/sql"
- "fmt"
- "github.com/zeromicro/go-zero/core/logx"
- "strconv"
- "sync"
- "time"
- "wechat-api/ent"
- "wechat-api/ent/label"
- "wechat-api/ent/labellog"
- "wechat-api/ent/labelrelationship"
- "wechat-api/ent/wx"
- "wechat-api/internal/lock"
- "wechat-api/internal/pkg/wechat_ws"
- "wechat-api/internal/svc"
- "wechat-api/workphone/wecom"
- )
- type CustomerPushNoticeHandler struct {
- svcCtx *svc.ServiceContext
- lockMap sync.Map // 微信号 -> *sync.Mutex
- }
- func NewCustomerPushNoticeHandler(svcCtx *svc.ServiceContext) *CustomerPushNoticeHandler {
- return &CustomerPushNoticeHandler{
- svcCtx: svcCtx,
- }
- }
- // Handle 实现 MessageHandlerStrategy 接口
- func (f *CustomerPushNoticeHandler) Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject, svcCtx *svc.ServiceContext) error {
- message := wecom.CustomerPushNoticeMessage{}
- err := json.Unmarshal([]byte(msg.Message), &message)
- logx.Infof("CustomerPushNotice.Message 的内容是:%s", msg.Message)
- if err != nil {
- logx.Errorf("Unmarshal.fail")
- return err
- }
- wxInfo, err := svcCtx.DB.Wx.Query().
- Where(
- wx.WxidEQ(message.WxId), // Additional filter by organizationId
- ).Only(ctx)
- if err != nil {
- return err
- }
- var labelRelationshipCreates []*ent.LabelRelationshipCreate
- var ctype uint64
- ctype = 3
- for _, friend := range message.Contacts {
- var friendId uint64
- //Wxid := strconv.FormatInt(friend.RemoteId, 10)
- friendType := 1
- if friend.Suffix == "微信" {
- friendType = 1
- } else {
- friendType = 4
- }
- list := friend.PhoneRemark
- var phone string
- if len(list) > 0 {
- phone = list[0]
- }
- var sex int
- if friend.Gender == "Male" {
- sex = 1
- } else if friend.Gender == "Female" {
- sex = 2
- } else {
- sex = 0
- }
- //修改拉黑后的状态被重置
- friendId, err = svcCtx.DB.Contact.Create().
- SetWxWxid(message.WxId).
- SetType(friendType).
- SetWxid(friend.RemoteId).
- SetNickname(friend.Name).
- SetMarkname(friend.Remark).
- SetHeadimg(friend.Avatar).
- SetPhone(phone).
- SetSex(sex).
- SetCtype(ctype).
- SetOrganizationID(wxInfo.OrganizationID).
- OnConflict().
- UpdateWxWxid().
- UpdateWxid().
- UpdateType().
- UpdateAccount().
- UpdateNickname().
- UpdateMarkname().
- UpdateHeadimg().
- UpdateOrganizationID().
- UpdatePhone().
- UpdateSex().
- UpdateCtype().
- ID(ctx)
- if err != nil {
- logx.Errorf("Contact.Create 失败, OrgID=%d, err=%v", wxInfo.OrganizationID, err)
- return err
- }
- //判断friend里的labelId="1,2,3,4,5"为空就不处理了,不为空的时候就查下label表里有没有这个labelId,没有就插入,有就跳过
- if friend.LabelIds == nil || len(friend.LabelIds) == 0 {
- logx.Infof("没有labelIds 失败, wx_wxId=%v", message.WxId)
- continue
- }
- labelIdsStr := friend.LabelIds
- var ids []uint64
- ids, err = stringSliceToUint64Slice(labelIdsStr)
- if err != nil {
- logx.Infof("labelstring切割失败, labelIds=%v", labelIdsStr)
- continue
- }
- LabelLogs, err := svcCtx.DB.LabelLog.Query().
- Where(labellog.LabelIDIn(ids...)).
- Where(labellog.WxID(message.WxId)).
- All(ctx)
- if err != nil || len(LabelLogs) == 0 {
- logx.Infof("labelLog.Query.fail: 跳过 || 或者查询失败 组织id:%d", wxInfo.OrganizationID)
- continue
- }
- //映射本地的name + type + model + organization_id
- currentOrgID := wxInfo.OrganizationID
- for _, remoteLabel := range LabelLogs {
- labelInfo, err := svcCtx.DB.Label.Query().Where(
- label.NameEQ(remoteLabel.LabelName),
- //label.StatusEQ(remoteLabel.LabelName),
- label.OrganizationID(currentOrgID),
- ).Only(ctx)
- if err != nil || ent.IsNotFound(err) {
- logx.Infof("label id %d not found.fail: ", wxInfo.OrganizationID)
- continue
- }
- //labelId, err := strconv.ParseUint(strconv.FormatUint(labelInfo.ID, 10), 10, 64)
- if err != nil {
- fmt.Println("转换出错:", err)
- continue
- }
- _, err = svcCtx.DB.LabelRelationship.Query().Where(
- labelrelationship.LabelIDEQ(labelInfo.ID),
- //label.StatusEQ(remoteLabel.LabelName),
- labelrelationship.ContactIDEQ(friendId),
- ).Only(ctx)
- if err != nil || ent.IsNotFound(err) {
- labelRelationshipCreates = append(labelRelationshipCreates,
- svcCtx.DB.LabelRelationship.Create().
- //SetID(int(label.LabelId)).
- SetOrganizationID(wxInfo.OrganizationID).
- SetContactID(friendId).
- SetStatus(1).
- SetLabelID(labelInfo.ID).
- SetCreatedAt(time.Now()).
- SetUpdatedAt(time.Now()),
- )
- }
- }
- }
- if len(labelRelationshipCreates) > 0 {
- lock.GetWxIdLockManager().RunWithLock(message.WxId, func() {
- errShip := svcCtx.DB.LabelRelationship.CreateBulk(labelRelationshipCreates...).
- OnConflict(
- sql.ConflictColumns(labelrelationship.FieldLabelID, labelrelationship.FieldContactID),
- ).DoNothing().Exec(ctx)
- if errShip != nil {
- logx.Error("label_relationship.create.fail: ", wxInfo.OrganizationID, labelRelationshipCreates)
- }
- })
- }
- return nil
- }
- func stringSliceToUint64Slice(strSlice []string) ([]uint64, error) {
- uintSlice := make([]uint64, 0, len(strSlice))
- for _, s := range strSlice {
- n, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- fmt.Printf("转换失败: %v\n", err)
- continue // 你可以选择跳过或直接 return 报错
- }
- uintSlice = append(uintSlice, n)
- }
- return uintSlice, nil
- }
- func (f *CustomerPushNoticeHandler) getWxLock(wxid string) *sync.Mutex {
- actual, _ := f.lockMap.LoadOrStore(wxid, &sync.Mutex{})
- return actual.(*sync.Mutex)
- }
|