package MessageHandlers import ( "context" "encoding/json" "entgo.io/ent/dialect/sql" "github.com/zeromicro/go-zero/core/logx" "strconv" "strings" "time" "wechat-api/ent" "wechat-api/ent/label" "wechat-api/ent/labellog" "wechat-api/ent/labelrelationship" "wechat-api/ent/wx" "wechat-api/internal/pkg/wechat_ws" "wechat-api/internal/svc" "wechat-api/workphone" ) type FriendPushNoticeHandler struct { svcCtx *svc.ServiceContext } func NewFriendPushNoticeHandler(svcCtx *svc.ServiceContext) *FriendPushNoticeHandler { return &FriendPushNoticeHandler{ svcCtx: svcCtx, } } func (f *FriendPushNoticeHandler) Handler(msg *wechat_ws.MsgJsonObject) error { if msg.MsgType == "FriendPushNotice" { message := workphone.FriendPushNoticeMessage{} err := json.Unmarshal([]byte(msg.Message), &message) if err != nil { return err } // 拿到租户 id wx_info, err := f.svcCtx.DB.Wx.Query(). Where( wx.WxidEQ(message.WeChatId), // Additional filter by organizationId ). Only(context.TODO()) //hookClient := hook.NewHook("", "", "") for _, friend := range message.Friends { friendType := 1 //if friend.Type == 1 { // friendType = 2 // _ = hookClient.RequestChatRoomInfo(friend.FriendId, message.WeChatId) //} else { // friendType = 1 //} _, err = f.svcCtx.DB.Contact.Create(). SetWxWxid(message.WeChatId). SetType(friendType). SetWxid(friend.FriendId). SetAccount(friend.FriendNo). SetNickname(friend.FriendNick). SetMarkname(friend.Memo). SetHeadimg(friend.Avatar). //SetSex(cast.ToInt(friend.Gender)). SetOrganizationID(wx_info.OrganizationID). OnConflict(). UpdateNewValues(). SetType(friendType). SetOrganizationID(wx_info.OrganizationID). ID(context.TODO()) if err != nil { logx.Error("Contact.Create: ", wx_info.OrganizationID) return err } } } return nil } type FriendPushNoticeTypeHandler struct { svcCtx *svc.ServiceContext } func NewFriendPushNoticeTypeHandler(svcCtx *svc.ServiceContext) *FriendPushNoticeTypeHandler { return &FriendPushNoticeTypeHandler{ svcCtx: svcCtx, } } // Handle 实现 MessageHandlerStrategy 接口 func (f *FriendPushNoticeTypeHandler) Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject, svcCtx *svc.ServiceContext) error { message := workphone.FriendPushNoticeMessage{} err := json.Unmarshal([]byte(msg.Message), &message) logx.Infof("msg.Message 的内容是:%s", msg.Message) if err != nil { logx.Errorf("Unmarshal.fail") return err } // 拿到租户 id wxInfo, err := svcCtx.DB.Wx.Query(). Where( wx.WxidEQ(message.WeChatId), // Additional filter by organizationId ).Only(ctx) if err != nil { return err } var labelRelationshipCreates []*ent.LabelRelationshipCreate for _, friend := range message.Friends { var friendId uint64 friendType := 1 friendId, err = svcCtx.DB.Contact.Create(). SetWxWxid(message.WeChatId). SetType(friendType). SetWxid(friend.FriendId). SetAccount(friend.FriendNo). SetNickname(friend.FriendNick). SetMarkname(friend.Memo). SetHeadimg(friend.Avatar). SetOrganizationID(wxInfo.OrganizationID). OnConflict(). UpdateNewValues(). SetType(friendType). SetOrganizationID(wxInfo.OrganizationID). 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 == "" { logx.Infof("没有labelIds 失败, wx_wxId=%v", message.WeChatId) continue } //获取labelId,并且按照逗号去分割成数组 labelIdsStr := friend.LabelIds var ids []int ids, err = ParseCSVToIntSlice(labelIdsStr) if err != nil { logx.Infof("labelstring切割失败, labelIds=%v", labelIdsStr) continue } //转换成labelIds的切片,去labelLog里 用labelId in 查下一下数据。 //labelIds := strings.Split(labelIdsStr, ",") //ids, _ = ParseCSVToIntSlice(labelIdsStr) LabelLogs, err := svcCtx.DB.LabelLog.Query(). Where(labellog.LabelIDIn(ids...)). Where(labellog.WxID(message.WeChatId)). All(ctx) if err != nil || len(LabelLogs) == 0 { logx.Error("labelLog.Query.fail: 跳过 || 或者查询失败", 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.Error("label not found.fail: ", wxInfo.OrganizationID) continue } //svcCtx.DB.LabelRelationship.Create(). // SetOrganizationID(wxInfo.OrganizationID). // SetContactID(friendId). // SetLabelID(labelInfo.ID). // SetAccount(friend.FriendNo). // SetNickname(friend.FriendNick). // SetMarkname(friend.Memo). // SetHeadimg(friend.Avatar). // SetOrganizationID(wxInfo.OrganizationID). // OnConflict(). // UpdateNewValues(). // SetType(friendType). // SetOrganizationID(wxInfo.OrganizationID). // ID(ctx) //生成批量的关系数据 待插入 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 { 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 err } } return nil } func ParseCSVToIntSlice(csv string) ([]int, error) { if csv == "" { return nil, nil } parts := strings.Split(csv, ",") var result []int for _, p := range parts { trimmed := strings.TrimSpace(p) if trimmed == "" { continue // 忽略空字符串 } n, err := strconv.Atoi(trimmed) if err != nil { logx.Error("无法将 %s 转换为整数: %v", trimmed, err) continue // 忽略无效字符 } result = append(result, n) } return result, nil }