浏览代码

Merge branch 'task-657-lcd-wechatDepartment' into debug

# Conflicts:
#	internal/logic/Wxhook/get_friends_and_groups_logic.go
lichangdong 1 天之前
父节点
当前提交
4354823c03

+ 2 - 2
ent/contact.go

@@ -27,7 +27,7 @@ type Contact struct {
 	DeletedAt time.Time `json:"deleted_at,omitempty"`
 	// 属主微信id
 	WxWxid string `json:"wx_wxid,omitempty"`
-	// 联系人类型:1好友,2群组,3公众号,4企业微信联系人
+	// 联系人类型:1好友,2群组,3公众号,4企业微信联系人,5同事
 	Type int `json:"type,omitempty"`
 	// 微信id 公众号微信ID
 	Wxid string `json:"wxid,omitempty"`
@@ -57,7 +57,7 @@ type Contact struct {
 	V3 string `json:"v3,omitempty"`
 	// 机构 ID
 	OrganizationID uint64 `json:"organization_id,omitempty"`
-	// 内容类型:1-微信 2-whatsapp
+	// 内容类型:1-微信 2-whatsapp 3-企微
 	Ctype uint64 `json:"ctype,omitempty"`
 	// 年龄
 	Cage int `json:"cage,omitempty"`

+ 2 - 2
ent/migrate/schema.go

@@ -363,7 +363,7 @@ var (
 		{Name: "status", Type: field.TypeUint8, Nullable: true, Comment: "Status 1: normal 2: ban | 状态 1 正常 2 禁用", Default: 1},
 		{Name: "deleted_at", Type: field.TypeTime, Nullable: true, Comment: "Delete Time | 删除日期"},
 		{Name: "wx_wxid", Type: field.TypeString, Comment: "属主微信id", Default: ""},
-		{Name: "type", Type: field.TypeInt, Nullable: true, Comment: "联系人类型:1好友,2群组,3公众号,4企业微信联系人", Default: 1},
+		{Name: "type", Type: field.TypeInt, Nullable: true, Comment: "联系人类型:1好友,2群组,3公众号,4企业微信联系人,5同事", Default: 1},
 		{Name: "wxid", Type: field.TypeString, Comment: "微信id 公众号微信ID", Default: ""},
 		{Name: "account", Type: field.TypeString, Comment: "微信账号", Default: ""},
 		{Name: "nickname", Type: field.TypeString, Comment: "微信昵称 群备注名称", Default: ""},
@@ -378,7 +378,7 @@ var (
 		{Name: "gname", Type: field.TypeString, Comment: "群组名称", Default: ""},
 		{Name: "v3", Type: field.TypeString, Comment: "v3数据", Default: ""},
 		{Name: "organization_id", Type: field.TypeUint64, Nullable: true, Comment: "机构 ID", Default: 1},
-		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp", Default: 1},
+		{Name: "ctype", Type: field.TypeUint64, Comment: "内容类型:1-微信 2-whatsapp 3-企微", Default: 1},
 		{Name: "cage", Type: field.TypeInt, Comment: "年龄", Default: 0},
 		{Name: "cname", Type: field.TypeString, Comment: "姓名", Default: ""},
 		{Name: "carea", Type: field.TypeString, Comment: "地区", Default: ""},

+ 2 - 2
ent/schema/contact.go

@@ -23,7 +23,7 @@ func (Contact) Fields() []ent.Field {
 			Comment("属主微信id"),
 		field.Int("type").Optional().Default(1).
 			Annotations(entsql.WithComments(true)).
-			Comment("联系人类型:1好友,2群组,3公众号,4企业微信联系人"),
+			Comment("联系人类型:1好友,2群组,3公众号,4企业微信联系人,5同事"),
 		field.String("wxid").Default("").
 			Annotations(entsql.WithComments(true)).
 			Comment("微信id 公众号微信ID"),
@@ -66,7 +66,7 @@ func (Contact) Fields() []ent.Field {
 		field.Uint64("organization_id").Optional().Default(1).
 			Comment("机构 ID").
 			Annotations(entsql.WithComments(true)),
-		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp"),
+		field.Uint64("ctype").Default(1).Comment("内容类型:1-微信 2-whatsapp 3-企微"),
 		field.Int("cage").Default(0).Comment("年龄"),
 		field.String("cname").Default("").Comment("姓名"),
 		field.String("carea").Default("").Comment("地区"),

+ 2 - 2
internal/pkg/wechat_ws/wecom_ws_client.go

@@ -281,8 +281,8 @@ func (c *WecomWsClient) DeviceAuth() error {
 		"AccessToken": "",
 		"MsgType":     "DeviceAuthReq",
 		"Content": map[string]interface{}{
-			"AuthType":   3,
-			"Credential": "",
+			"AuthType":   2,
+			"Credential": "bGNka2Y6QWExMjM0NTY=",
 		},
 	}
 	transportMessageJSON, err := json.Marshal(message)

+ 84 - 0
internal/service/MessageHandlers/wecom/contact_push_notice.go

@@ -0,0 +1,84 @@
+package wecom
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/zeromicro/go-zero/core/logx"
+	"sync"
+	"wechat-api/ent/wx"
+	"wechat-api/internal/pkg/wechat_ws"
+	"wechat-api/internal/svc"
+	"wechat-api/workphone/wecom"
+)
+
+type ContactPushNoticeHandler struct {
+	svcCtx  *svc.ServiceContext
+	lockMap sync.Map // 微信号 -> *sync.Mutex
+}
+
+func NewContactPushNoticeHandler(svcCtx *svc.ServiceContext) *ContactPushNoticeHandler {
+	return &ContactPushNoticeHandler{
+		svcCtx: svcCtx,
+	}
+}
+
+// Handle 实现 MessageHandlerStrategy 接口
+func (f *ContactPushNoticeHandler) Handle(ctx context.Context, msg *wechat_ws.MsgJsonObject, svcCtx *svc.ServiceContext) error {
+	message := wecom.ContactPushNoticeMessage{}
+	err := json.Unmarshal([]byte(msg.Message), &message)
+	logx.Infof("ContactPushNoticeMessage.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 ctype uint64
+	ctype = 3
+	for _, friend := range message.Contacts {
+		//Wxid := strconv.FormatInt(friend.RemoteId, 10)
+
+		friendType := 5
+		var sex int
+		if friend.Gender == "Male" {
+			sex = 1
+		} else if friend.Gender == "Female" {
+			sex = 2
+		} else {
+			sex = 0
+		}
+		//修改拉黑后的状态被重置
+		_, err = svcCtx.DB.Contact.Create().
+			SetWxWxid(message.WxId).
+			SetType(friendType).
+			SetWxid(friend.RemoteId).
+			SetNickname(friend.Name).
+			SetMarkname(friend.Alias).
+			SetHeadimg(friend.Avatar).
+			SetSex(sex).
+			SetCtype(ctype).
+			SetOrganizationID(wxInfo.OrganizationID).
+			OnConflict().
+			UpdateWxWxid().
+			UpdateWxid().
+			UpdateType().
+			UpdateNickname().
+			UpdateMarkname().
+			UpdateHeadimg().
+			UpdateOrganizationID().
+			UpdateSex().
+			UpdateCtype().
+			ID(ctx)
+		if err != nil {
+			logx.Errorf("Contact.Create 失败, OrgID=%d, err=%v", wxInfo.OrganizationID, err)
+			return err
+		}
+	}
+	return nil
+}

+ 1 - 0
internal/service/MessageHandlers/wecom_strategies.go

@@ -10,5 +10,6 @@ func GetWecomStrategies() map[string]func(*svc.ServiceContext) MessageHandlerStr
 		"TaskResultNotice":    toStrategy(NewTaskResultNoticeHandler),
 		"CustomerPushNotice":  toStrategy(wecom.NewCustomerPushNoticeHandler),
 		"UserLabelPushNotice": toStrategy(wecom.NewUserLabelPushNotice),
+		"ContactPushNotice":   toStrategy(wecom.NewContactPushNoticeHandler),
 	}
 }

+ 5 - 7
proto/wecom/WContactPushNotice.proto

@@ -2,10 +2,8 @@ syntax = "proto3";
 package Im.Scrm.Ww.Proto; //命名空间约定
 option go_package = "./workphone/wecom";
 
-import "wecom/WTransport.proto";
-
 message ContactPushNoticeMessage {
-    int64 WxId = 1; // 设备企业WX号
+    string WxId = 1; // 设备企业WX号
     repeated ContactMessage Contacts = 2; // 好友信息模型 多个
     int32 Size = 3;
     int32 Count = 4;
@@ -14,7 +12,7 @@ message ContactPushNoticeMessage {
 }
 
 message ContactMessage {
-    int64 RemoteId = 1; //唯一id
+    string RemoteId = 1; //唯一id
     // RemoteId>>48==20 App;
     // RemoteId>>48==28 微信用户;
     // RemoteId>>48==33,34 外部客户;
@@ -28,8 +26,8 @@ message ContactMessage {
     string Job = 6; // 职位
     string Mobile = 7;
     string UnionId = 8;
-    EnumGender Gender = 9;
-    repeated int64 DepartIds = 10; // 所属部门id
-    int64 Attr = 11; // 属性 (attr & 64) == 64 || (attr & 33554432) == 33554432 已激活企业微信
+    string Gender = 9;
+    repeated string DepartIds = 10; // 所属部门id
+    string Attr = 11; // 属性 (attr & 64) == 64 || (attr & 33554432) == 33554432 已激活企业微信
     //int64 CorpId = 12;
 }

+ 34 - 37
workphone/wecom/WContactPushNotice.pb.go

@@ -23,7 +23,7 @@ const (
 
 type ContactPushNoticeMessage struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
-	WxId          int64                  `protobuf:"varint,1,opt,name=WxId,proto3" json:"WxId,omitempty"`        // 设备企业WX号
+	WxId          string                 `protobuf:"bytes,1,opt,name=WxId,proto3" json:"WxId,omitempty"`         // 设备企业WX号
 	Contacts      []*ContactMessage      `protobuf:"bytes,2,rep,name=Contacts,proto3" json:"Contacts,omitempty"` // 好友信息模型 多个
 	Size          int32                  `protobuf:"varint,3,opt,name=Size,proto3" json:"Size,omitempty"`
 	Count         int32                  `protobuf:"varint,4,opt,name=Count,proto3" json:"Count,omitempty"`
@@ -63,11 +63,11 @@ func (*ContactPushNoticeMessage) Descriptor() ([]byte, []int) {
 	return file_wecom_WContactPushNotice_proto_rawDescGZIP(), []int{0}
 }
 
-func (x *ContactPushNoticeMessage) GetWxId() int64 {
+func (x *ContactPushNoticeMessage) GetWxId() string {
 	if x != nil {
 		return x.WxId
 	}
-	return 0
+	return ""
 }
 
 func (x *ContactPushNoticeMessage) GetContacts() []*ContactMessage {
@@ -107,23 +107,23 @@ func (x *ContactPushNoticeMessage) GetTaskId() int64 {
 
 type ContactMessage struct {
 	state    protoimpl.MessageState `protogen:"open.v1"`
-	RemoteId int64                  `protobuf:"varint,1,opt,name=RemoteId,proto3" json:"RemoteId,omitempty"` //唯一id
+	RemoteId string                 `protobuf:"bytes,1,opt,name=RemoteId,proto3" json:"RemoteId,omitempty"` //唯一id
 	// RemoteId>>48==20 App;
 	// RemoteId>>48==28 微信用户;
 	// RemoteId>>48==33,34 外部客户;
 	// RemoteId>>48==39 群机器人;
 	// RemoteId>>48==30 内部客服;
 	// RemoteId>>48==32 VIP客户;
-	AcctId        string     `protobuf:"bytes,2,opt,name=AcctId,proto3" json:"AcctId,omitempty"` // 企业内部id
-	Name          string     `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"`     //
-	Alias         string     `protobuf:"bytes,4,opt,name=Alias,proto3" json:"Alias,omitempty"`
-	Avatar        string     `protobuf:"bytes,5,opt,name=Avatar,proto3" json:"Avatar,omitempty"`
-	Job           string     `protobuf:"bytes,6,opt,name=Job,proto3" json:"Job,omitempty"` // 职位
-	Mobile        string     `protobuf:"bytes,7,opt,name=Mobile,proto3" json:"Mobile,omitempty"`
-	UnionId       string     `protobuf:"bytes,8,opt,name=UnionId,proto3" json:"UnionId,omitempty"`
-	Gender        EnumGender `protobuf:"varint,9,opt,name=Gender,proto3,enum=Im.Scrm.Ww.Proto.EnumGender" json:"Gender,omitempty"`
-	DepartIds     []int64    `protobuf:"varint,10,rep,packed,name=DepartIds,proto3" json:"DepartIds,omitempty"` // 所属部门id
-	Attr          int64      `protobuf:"varint,11,opt,name=Attr,proto3" json:"Attr,omitempty"`                  // 属性 (attr & 64) == 64 || (attr & 33554432) == 33554432 已激活企业微信
+	AcctId        string   `protobuf:"bytes,2,opt,name=AcctId,proto3" json:"AcctId,omitempty"` // 企业内部id
+	Name          string   `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"`     //
+	Alias         string   `protobuf:"bytes,4,opt,name=Alias,proto3" json:"Alias,omitempty"`
+	Avatar        string   `protobuf:"bytes,5,opt,name=Avatar,proto3" json:"Avatar,omitempty"`
+	Job           string   `protobuf:"bytes,6,opt,name=Job,proto3" json:"Job,omitempty"` // 职位
+	Mobile        string   `protobuf:"bytes,7,opt,name=Mobile,proto3" json:"Mobile,omitempty"`
+	UnionId       string   `protobuf:"bytes,8,opt,name=UnionId,proto3" json:"UnionId,omitempty"`
+	Gender        string   `protobuf:"bytes,9,opt,name=Gender,proto3" json:"Gender,omitempty"`
+	DepartIds     []string `protobuf:"bytes,10,rep,name=DepartIds,proto3" json:"DepartIds,omitempty"` // 所属部门id
+	Attr          string   `protobuf:"bytes,11,opt,name=Attr,proto3" json:"Attr,omitempty"`           // 属性 (attr & 64) == 64 || (attr & 33554432) == 33554432 已激活企业微信
 	unknownFields protoimpl.UnknownFields
 	sizeCache     protoimpl.SizeCache
 }
@@ -158,11 +158,11 @@ func (*ContactMessage) Descriptor() ([]byte, []int) {
 	return file_wecom_WContactPushNotice_proto_rawDescGZIP(), []int{1}
 }
 
-func (x *ContactMessage) GetRemoteId() int64 {
+func (x *ContactMessage) GetRemoteId() string {
 	if x != nil {
 		return x.RemoteId
 	}
-	return 0
+	return ""
 }
 
 func (x *ContactMessage) GetAcctId() string {
@@ -214,52 +214,52 @@ func (x *ContactMessage) GetUnionId() string {
 	return ""
 }
 
-func (x *ContactMessage) GetGender() EnumGender {
+func (x *ContactMessage) GetGender() string {
 	if x != nil {
 		return x.Gender
 	}
-	return EnumGender_UnknownGender
+	return ""
 }
 
-func (x *ContactMessage) GetDepartIds() []int64 {
+func (x *ContactMessage) GetDepartIds() []string {
 	if x != nil {
 		return x.DepartIds
 	}
 	return nil
 }
 
-func (x *ContactMessage) GetAttr() int64 {
+func (x *ContactMessage) GetAttr() string {
 	if x != nil {
 		return x.Attr
 	}
-	return 0
+	return ""
 }
 
 var File_wecom_WContactPushNotice_proto protoreflect.FileDescriptor
 
 const file_wecom_WContactPushNotice_proto_rawDesc = "" +
 	"\n" +
-	"\x1ewecom/WContactPushNotice.proto\x12\x10Im.Scrm.Ww.Proto\x1a\x16wecom/WTransport.proto\"\xc2\x01\n" +
+	"\x1ewecom/WContactPushNotice.proto\x12\x10Im.Scrm.Ww.Proto\"\xc2\x01\n" +
 	"\x18ContactPushNoticeMessage\x12\x12\n" +
-	"\x04WxId\x18\x01 \x01(\x03R\x04WxId\x12<\n" +
+	"\x04WxId\x18\x01 \x01(\tR\x04WxId\x12<\n" +
 	"\bContacts\x18\x02 \x03(\v2 .Im.Scrm.Ww.Proto.ContactMessageR\bContacts\x12\x12\n" +
 	"\x04Size\x18\x03 \x01(\x05R\x04Size\x12\x14\n" +
 	"\x05Count\x18\x04 \x01(\x05R\x05Count\x12\x12\n" +
 	"\x04Page\x18\x05 \x01(\x05R\x04Page\x12\x16\n" +
-	"\x06TaskId\x18\x06 \x01(\x03R\x06TaskId\"\xb2\x02\n" +
+	"\x06TaskId\x18\x06 \x01(\x03R\x06TaskId\"\x94\x02\n" +
 	"\x0eContactMessage\x12\x1a\n" +
-	"\bRemoteId\x18\x01 \x01(\x03R\bRemoteId\x12\x16\n" +
+	"\bRemoteId\x18\x01 \x01(\tR\bRemoteId\x12\x16\n" +
 	"\x06AcctId\x18\x02 \x01(\tR\x06AcctId\x12\x12\n" +
 	"\x04Name\x18\x03 \x01(\tR\x04Name\x12\x14\n" +
 	"\x05Alias\x18\x04 \x01(\tR\x05Alias\x12\x16\n" +
 	"\x06Avatar\x18\x05 \x01(\tR\x06Avatar\x12\x10\n" +
 	"\x03Job\x18\x06 \x01(\tR\x03Job\x12\x16\n" +
 	"\x06Mobile\x18\a \x01(\tR\x06Mobile\x12\x18\n" +
-	"\aUnionId\x18\b \x01(\tR\aUnionId\x124\n" +
-	"\x06Gender\x18\t \x01(\x0e2\x1c.Im.Scrm.Ww.Proto.EnumGenderR\x06Gender\x12\x1c\n" +
+	"\aUnionId\x18\b \x01(\tR\aUnionId\x12\x16\n" +
+	"\x06Gender\x18\t \x01(\tR\x06Gender\x12\x1c\n" +
 	"\tDepartIds\x18\n" +
-	" \x03(\x03R\tDepartIds\x12\x12\n" +
-	"\x04Attr\x18\v \x01(\x03R\x04AttrB\x13Z\x11./workphone/wecomb\x06proto3"
+	" \x03(\tR\tDepartIds\x12\x12\n" +
+	"\x04Attr\x18\v \x01(\tR\x04AttrB\x13Z\x11./workphone/wecomb\x06proto3"
 
 var (
 	file_wecom_WContactPushNotice_proto_rawDescOnce sync.Once
@@ -277,16 +277,14 @@ var file_wecom_WContactPushNotice_proto_msgTypes = make([]protoimpl.MessageInfo,
 var file_wecom_WContactPushNotice_proto_goTypes = []any{
 	(*ContactPushNoticeMessage)(nil), // 0: Im.Scrm.Ww.Proto.ContactPushNoticeMessage
 	(*ContactMessage)(nil),           // 1: Im.Scrm.Ww.Proto.ContactMessage
-	(EnumGender)(0),                  // 2: Im.Scrm.Ww.Proto.EnumGender
 }
 var file_wecom_WContactPushNotice_proto_depIdxs = []int32{
 	1, // 0: Im.Scrm.Ww.Proto.ContactPushNoticeMessage.Contacts:type_name -> Im.Scrm.Ww.Proto.ContactMessage
-	2, // 1: Im.Scrm.Ww.Proto.ContactMessage.Gender:type_name -> Im.Scrm.Ww.Proto.EnumGender
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
+	1, // [1:1] is the sub-list for method output_type
+	1, // [1:1] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
 }
 
 func init() { file_wecom_WContactPushNotice_proto_init() }
@@ -294,7 +292,6 @@ func file_wecom_WContactPushNotice_proto_init() {
 	if File_wecom_WContactPushNotice_proto != nil {
 		return
 	}
-	file_wecom_WTransport_proto_init()
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{