From 7b7e99c0e150a60b127234615b4cb5f8a20e1caf Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Fri, 27 Dec 2024 18:24:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E8=81=94=E7=B3=BB?= =?UTF-8?q?=E4=BA=BA=E7=BE=A4=E7=BB=84=E7=9B=91=E6=8E=A7=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wechat/ferry/aggregation/.gitkeep | 3 + .../ferry/aggregation/facade/ChatRoomDo.java | 15 ++ .../ferry/aggregation/facade/ContactDo.java | 187 ++++++++++++++++++ .../wechat/ferry/entity/po/wcf/ChatRoom.java | 35 ++++ .../ferry/entity/po/wcf/ChatRoomInfo.java | 47 +++++ .../wechat/ferry/entity/po/wcf/Contact.java | 77 ++++++++ .../entity/po/wcf/ContactHeadImgUrl.java | 35 ++++ .../ferry/entity/po/wcf/RevokeMsgStorage.java | 35 ++++ .../wechat/ferry/enums/MsgEventTypeEnum.java | 48 +++++ .../service/impl/WeChatDllServiceImpl.java | 38 +--- .../ferry/task/ContactGroupMonitorTask.java | 170 ++++++++++++++++ .../ferry/task/LeaveGroupMonitorTask.java | 92 --------- 12 files changed, 656 insertions(+), 126 deletions(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/.gitkeep create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ChatRoomDo.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ContactDo.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoom.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoomInfo.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/Contact.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ContactHeadImgUrl.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/RevokeMsgStorage.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgEventTypeEnum.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/ContactGroupMonitorTask.java delete mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/.gitkeep b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ChatRoomDo.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ChatRoomDo.java new file mode 100644 index 0000000..586b4a5 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ChatRoomDo.java @@ -0,0 +1,15 @@ +package com.wechat.ferry.aggregation.facade; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * 聚合模型类-联系人 + * + * @author chandler + * @date 2023-06-08 22:39:53 + */ +@Slf4j +@Data +public class ChatRoomDo { +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ContactDo.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ContactDo.java new file mode 100644 index 0000000..de13658 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/aggregation/facade/ContactDo.java @@ -0,0 +1,187 @@ +package com.wechat.ferry.aggregation.facade; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; + +import com.wechat.ferry.config.WeChatFerryProperties; +import com.wechat.ferry.entity.po.wcf.Contact; +import com.wechat.ferry.entity.proto.Wcf; +import com.wechat.ferry.enums.DatabaseNameEnum; +import com.wechat.ferry.enums.WxContactsMixedEnum; +import com.wechat.ferry.enums.WxContactsOfficialEnum; +import com.wechat.ferry.enums.WxContactsTypeEnum; +import com.wechat.ferry.handle.WeChatSocketClient; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +/** + * 聚合模型类-联系人 + * + * @author chandler + * @date 2023-06-08 22:39:53 + */ +@Slf4j +@Data +public class ContactDo extends Contact { + + /** + * 微信内部识别号UID + */ + @ApiModelProperty(value = "微信内部识别号UID") + private String weChatUid; + + /** + * 联系人类型 + */ + @ApiModelProperty(value = "联系人类型") + private String contactType; + + /** + * 根据自定义SQL查询联系人列表 + * + * @param wechatSocketClient 通信客户端 + * @param weChatFerryProperties 配置文件 + * + * @author chandler + * @date 2024-12-27 16:06 + */ + public List queryContactListBySql(WeChatSocketClient wechatSocketClient, WeChatFerryProperties weChatFerryProperties) { + List list = new ArrayList<>(); + // 查询联系人 + List dbContactList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), + "SELECT UserName, Alias, NickName, DelFlag, VerifyFlag, Remark, LabelIDList, DomainList, ChatRoomType, HeadImgMd5, Type FROM Contact;"); + if (!CollectionUtils.isEmpty(dbContactList)) { + for (Wcf.DbRow dbRow : dbContactList) { + List dbFieldList = dbRow.getFieldsList(); + if (!ObjectUtils.isEmpty(dbFieldList)) { + ContactDo po; + for (Wcf.DbField dbField : dbFieldList) { + po = new ContactDo(); + String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); + // 用户名 + if ("UserName".equals(dbField.getColumn())) { + po.setUserName(content); + po.setWeChatUid(content); + // 设置类型 + String type = convertContactType(content, weChatFerryProperties); + po.setContactType(type); + } + // 用户名 + if ("Alias".equals(dbField.getColumn())) { + po.setAlias(content); + } + // 昵称 + if ("NickName".equals(dbField.getColumn())) { + po.setNickname(content); + } + // 删除标志 + if ("DelFlag".equals(dbField.getColumn())) { + po.setDelFlag(Integer.valueOf(content)); + } + // + if ("VerifyFlag".equals(dbField.getColumn())) { + po.setVerifyFlag(Integer.valueOf(content)); + } + // + if ("Remark".equals(dbField.getColumn())) { + po.setRemark(content); + } + // + if ("LabelIDList".equals(dbField.getColumn())) { + po.setLabelIdList(content); + } + // + if ("DomainList".equals(dbField.getColumn())) { + po.setDomainList(content); + } + // + if ("ChatRoomType".equals(dbField.getColumn())) { + po.setChatRoomType(Integer.valueOf(content)); + } + // + if ("HeadImgMd5".equals(dbField.getColumn())) { + po.setHeadImgMd5(content); + } + } + } + } + } + return list; + } + + /** + * 转换联系人类型 + * 类型判断,存在优先级的,官方杂号优先级高于微信公众号(如果定义重复了,常规禁止重复,手机端和电脑端分类不同) + * + * @param weChatUid 微信识别号 + * @param weChatFerryProperties 配置文件 + * + * @author chandler + * @date 2024-12-27 15:56 + */ + public static String convertContactType(String weChatUid, WeChatFerryProperties weChatFerryProperties) { + String type = ""; + // 官方杂号集合 + Map mixedNoMap = WxContactsMixedEnum.toCodeNameMap(); + mixedNoMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeMixed())); + // 公众号 + Map officialMap = WxContactsOfficialEnum.toCodeNameMap(); + officialMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeOfficial())); + + // 类型判断,存在优先级的,官方杂号优先级高于微信公众号(如果定义重复了,常规禁止重复,手机端和电脑端分类不同) + if (weChatUid.endsWith(WxContactsTypeEnum.WORK.getAffix())) { + // 企微 + type = WxContactsTypeEnum.WORK.getCode(); + } else if (weChatUid.endsWith(WxContactsTypeEnum.GROUP.getAffix()) || weChatUid.endsWith("@im.chatroom")) { + // 群聊 @im.chatroom 这种是很早之前的格式,单独例举 + type = WxContactsTypeEnum.GROUP.getCode(); + } else if (mixedNoMap.containsKey(weChatUid)) { + // 官方杂号 + type = WxContactsTypeEnum.OFFICIAL_MIXED_NO.getCode(); + } else if (weChatUid.startsWith(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getAffix())) { + // 微信公众号 + type = WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode(); + } else if (officialMap.containsKey(weChatUid)) { + type = WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode(); + } else { + // 个微 + type = WxContactsTypeEnum.PERSON.getCode(); + } + return type; + } + + /** + * 转换联系人类型配置 + * + * @param list 配置参数 + * @return map key:code val:name + * + * @author chandler + * @date 2024-12-24 16:55 + */ + public static Map convertContactsTypeProperties(List list) { + Map map = new HashMap<>(); + if (!CollectionUtils.isEmpty(list)) { + for (String str : list) { + String key = str; + String val = str; + // 存在名称则分割 + if (str.contains("|")) { + int index = str.indexOf("|"); + key = str.substring(0, index); + val = str.substring(index + 1); + } + map.put(key, val); + } + } + return map; + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoom.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoom.java new file mode 100644 index 0000000..3f685c2 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoom.java @@ -0,0 +1,35 @@ +package com.wechat.ferry.entity.po.wcf; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 实体类-群信息表 + * + * @author chandler + * @date 2024-12-27 10:01 + */ +@Data +@ApiModel(value = "ChatRoom", description = "群信息表") +public class ChatRoom { + + /** + * 群名称 + */ + @ApiModelProperty(value = "群名称") + private String chatRoomName; + + /** + * 用户名称列表 + */ + @ApiModelProperty(value = "用户名称列表") + private String userNameList; + + /** + * 显示名称列表 + */ + @ApiModelProperty(value = "显示名称列表") + private String displayNameList; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoomInfo.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoomInfo.java new file mode 100644 index 0000000..fa078e6 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ChatRoomInfo.java @@ -0,0 +1,47 @@ +package com.wechat.ferry.entity.po.wcf; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 实体类-群详细信息表 + * + * @author chandler + * @date 2024-12-27 10:03 + */ +@Data +@ApiModel(value = "ChatRoomInfo", description = "群详细信息表") +public class ChatRoomInfo { + + /** + * 群名称 + */ + @ApiModelProperty(value = "群名称") + private String chatRoomName; + + /** + * 群公告 + */ + @ApiModelProperty(value = "群公告") + private String announcement; + + /** + * 公告编辑者 + */ + @ApiModelProperty(value = "公告编辑者") + private String announcementEditor; + + /** + * 公告发布时间 + */ + @ApiModelProperty(value = "公告发布时间") + private String announcementPublishTime; + + /** + * 群状态 + */ + @ApiModelProperty(value = "群状态") + private Integer chatRoomStatus; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/Contact.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/Contact.java new file mode 100644 index 0000000..fa18dab --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/Contact.java @@ -0,0 +1,77 @@ +package com.wechat.ferry.entity.po.wcf; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 实体类-联系人表 + * + * @author chandler + * @date 2024-12-27 09:47 + */ +@Data +@ApiModel(value = "Contact对象", description = "联系人表") +public class Contact { + + /** + * 用户名 + */ + @ApiModelProperty(value = "用户名") + private String userName; + + /** + * 别名 + */ + @ApiModelProperty(value = "别名") + private String alias; + + /** + * 昵称 + */ + @ApiModelProperty(value = "昵称") + private String nickname; + + /** + * 删除标志 + */ + @ApiModelProperty(value = "删除标志") + private Integer delFlag; + + /** + * 验证标志 + */ + @ApiModelProperty(value = "验证标志") + private Integer verifyFlag; + + /** + * 备注 + */ + @ApiModelProperty(value = "备注") + private String remark; + + /** + * 标签ID列表 + */ + @ApiModelProperty(value = "标签ID列表") + private String labelIdList; + + /** + * 域名列表 + */ + @ApiModelProperty(value = "域名列表") + private String domainList; + + /** + * 群类型 + */ + @ApiModelProperty(value = "群类型") + private Integer chatRoomType; + + /** + * 头像MD5 + */ + @ApiModelProperty(value = "头像MD5") + private String headImgMd5; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ContactHeadImgUrl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ContactHeadImgUrl.java new file mode 100644 index 0000000..2379c96 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/ContactHeadImgUrl.java @@ -0,0 +1,35 @@ +package com.wechat.ferry.entity.po.wcf; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 实体类-联系人头像信息表 + * + * @author chandler + * @date 2024-12-27 09:59 + */ +@Data +@ApiModel(value = "ContactHeadImgUrl对象", description = "联系人头像信息表") +public class ContactHeadImgUrl { + + /** + * 用户名 + */ + @ApiModelProperty(value = "用户名") + private String userName; + + /** + * 小头像URL + */ + @ApiModelProperty(value = "小头像URL") + private String smallHeadIngUrl; + + /** + * 大头像URL + */ + @ApiModelProperty(value = "大头像URL") + private String bigHeadIngUrl; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/RevokeMsgStorage.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/RevokeMsgStorage.java new file mode 100644 index 0000000..b7889a5 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/po/wcf/RevokeMsgStorage.java @@ -0,0 +1,35 @@ +package com.wechat.ferry.entity.po.wcf; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 实体类-撤回消息存储表 + * + * @author chandler + * @date 2024-12-27 10:08 + */ +@Data +@ApiModel(value = "RevokeMsgStorage对象", description = "撤回消息存储表") +public class RevokeMsgStorage { + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private Integer createTime; + + /** + * 消息服务ID + */ + @ApiModelProperty(value = "消息服务ID") + private Integer msgSvrId; + + /** + * 撤回服务ID + */ + @ApiModelProperty(value = "撤回服务ID") + private Integer revokeSvrId; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgEventTypeEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgEventTypeEnum.java new file mode 100644 index 0000000..ae137c1 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgEventTypeEnum.java @@ -0,0 +1,48 @@ +package com.wechat.ferry.enums; + +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 枚举-消息事件类型 + * + * @author chandler + * @date 2024/12/27 18:09 + */ +@Getter +@AllArgsConstructor +public enum MsgEventTypeEnum { + + /** + * 1-注入成功 + */ + INJECT("1", "注入成功"), + + /** + * 未匹配上 + */ + UN_MATCH("", null), + + // 结束 + ; + + private final String code; + private final String name; + + /** + * map集合 key:code val:枚举 + */ + public static final Map codeMap = Arrays.stream(values()).collect(Collectors.toMap(MsgEventTypeEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static MsgEventTypeEnum getCodeMap(String code) { + return codeMap.getOrDefault(code, UN_MATCH); + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java index 1eee7fb..da0c5e0 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatDllServiceImpl.java @@ -15,6 +15,7 @@ import org.springframework.util.ObjectUtils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.google.protobuf.InvalidProtocolBufferException; +import com.wechat.ferry.aggregation.facade.ContactDo; import com.wechat.ferry.config.WeChatFerryProperties; import com.wechat.ferry.entity.proto.Wcf; import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; @@ -50,8 +51,6 @@ import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; import com.wechat.ferry.enums.DatabaseNameEnum; import com.wechat.ferry.enums.MsgCallbackTypeEnum; import com.wechat.ferry.enums.SexEnum; -import com.wechat.ferry.enums.WxContactsMixedEnum; -import com.wechat.ferry.enums.WxContactsOfficialEnum; import com.wechat.ferry.enums.WxContactsTypeEnum; import com.wechat.ferry.handle.WeChatSocketClient; import com.wechat.ferry.service.WeChatDllService; @@ -176,38 +175,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { } // 微信类型 if (!ObjectUtils.isEmpty(rpcContact.getWxid())) { - // 官方杂号集合 - Map mixedNoMap = WxContactsMixedEnum.toCodeNameMap(); - mixedNoMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeMixed())); - // 公众号 - Map officialMap = WxContactsOfficialEnum.toCodeNameMap(); - officialMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeOfficial())); - - // 类型判断,存在优先级的,官方杂号优先级高于微信公众号(如果定义重复了,常规禁止重复,手机端和电脑端分类不同) - if (rpcContact.getWxid().endsWith(WxContactsTypeEnum.WORK.getAffix())) { - // 企微 - vo.setType(WxContactsTypeEnum.WORK.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.WORK.getName()); - } else if (rpcContact.getWxid().endsWith(WxContactsTypeEnum.GROUP.getAffix()) || rpcContact.getWxid().endsWith("@im.chatroom")) { - // 群聊 @im.chatroom 这种是很早之前的格式,单独例举 - vo.setType(WxContactsTypeEnum.GROUP.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.GROUP.getName()); - } else if (mixedNoMap.containsKey(rpcContact.getWxid())) { - // 官方杂号 - vo.setType(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getName()); - } else if (rpcContact.getWxid().startsWith(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getAffix())) { - // 微信公众号 - vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); - } else if (officialMap.containsKey(rpcContact.getWxid())) { - vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); - } else { - // 个微 - vo.setType(WxContactsTypeEnum.PERSON.getCode()); - vo.setTypeLabel(WxContactsTypeEnum.PERSON.getName()); - } + String type = ContactDo.convertContactType(rpcContact.getWxid(), weChatFerryProperties); + vo.setType(type); + vo.setTypeLabel(WxContactsTypeEnum.getCodeMap(rpcContact.getWxid()).getName()); } list.add(vo); } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/ContactGroupMonitorTask.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/ContactGroupMonitorTask.java new file mode 100644 index 0000000..537021c --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/ContactGroupMonitorTask.java @@ -0,0 +1,170 @@ +package com.wechat.ferry.task; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.wechat.ferry.aggregation.facade.ContactDo; +import com.wechat.ferry.config.WeChatFerryProperties; +import com.wechat.ferry.entity.po.wcf.Contact; +import com.wechat.ferry.enums.WxContactsTypeEnum; +import com.wechat.ferry.handle.WeChatSocketClient; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class ContactGroupMonitorTask { + + private WeChatSocketClient wechatSocketClient; + + @Autowired + public void setWechatSocketClient(WeChatSocketClient wechatSocketClient) { + this.wechatSocketClient = wechatSocketClient; + } + + @Resource + private WeChatFerryProperties weChatFerryProperties; + + /** + * 全部联系人信息集合 key:微信标识-weChatUid val:联系人信息 + */ + private final Map allContactDoMap = new HashMap<>(); + + /** + * 个微联系人信息集合 key:微信标识-weChatUid val:联系人信息 + */ + private final Map ppContactDoMap = new HashMap<>(); + + /** + * 企微联系人信息集合 key:微信标识-weChatUid val:联系人信息 + */ + private final Map cpContactDoMap = new HashMap<>(); + + /** + * 群组信息集合 key:群ID val:群名称 + */ + private final Map groupMap = new HashMap<>(); + + /** + * 群成员信息集合 key:群ID val:微信标识-weChatUid + */ + private final Map> groupMemberMap = new HashMap<>(); + + /** + * 初始化标志 + */ + private Boolean initFlag = false; + + @Scheduled(cron = "0 0/2 * * * ?") + public void scheduled() { + ContactDo contactDo = new ContactDo(); + // 查询联系人 + List contactList = contactDo.queryContactListBySql(wechatSocketClient, weChatFerryProperties); + // 调用联系人监控处理 + contactMonitor(contactList); + initFlag = true; + log.info("[定时任务]-[重置签到]-结束"); + } + + // 联系人监控 + private void contactMonitor(List contactList) { + // 新增个微联系人 + List addPpContactList = new ArrayList<>(); + // 删除个微联系人 + List deletePpContactList = new ArrayList<>(); + // 新增企微联系人 + List addCpContactList = new ArrayList<>(); + // 删除企微联系人 + List deleteCpContactList = new ArrayList<>(); + // 新增群组 + List addGroupList = new ArrayList<>(); + // 退出群组 + List deleteGroupList = new ArrayList<>(); + // 本次的联系人标识列表 + List nowContactIdList = new ArrayList<>(); + + // 开始匹配 + if (!CollectionUtils.isEmpty(contactList)) { + for (ContactDo contactDo : contactList) { + nowContactIdList.add(contactDo.getWeChatUid()); + if (!initFlag) { + // 首次初始化 + allContactDoMap.put(contactDo.getWeChatUid(), contactDo); + if (WxContactsTypeEnum.PERSON.getCode().equals(contactDo.getContactType())) { + // 个微-初始化 + ppContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } else if (WxContactsTypeEnum.WORK.getCode().equals(contactDo.getContactType())) { + // 企业微信-初始化 + cpContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } else if (WxContactsTypeEnum.GROUP.getCode().equals(contactDo.getContactType())) { + // 群组-初始化 + groupMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } + } else { + // 非首次 + if (!ppContactDoMap.containsKey(contactDo.getWeChatUid())) { + // 个微-新增 + addPpContactList.add(contactDo.getWeChatUid()); + ppContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } else if (!cpContactDoMap.containsKey(contactDo.getContactType())) { + // 企业微信-新增 + addCpContactList.add(contactDo.getWeChatUid()); + cpContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } else if (!groupMap.containsKey(contactDo.getContactType())) { + // 群组-新增 + addGroupList.add(contactDo.getWeChatUid()); + groupMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } + } + } + + // 初始化完成 + if (initFlag) { + // 个微 + for (Map.Entry entry : ppContactDoMap.entrySet()) { + if (!nowContactIdList.contains(entry.getKey())) { + // 个微-删除 + deletePpContactList.add(entry.getKey()); + } + } + // 企微 + for (Map.Entry entry : cpContactDoMap.entrySet()) { + if (!nowContactIdList.contains(entry.getKey())) { + // 企微-删除 + deleteCpContactList.add(entry.getKey()); + } + } + // 群组 + for (Map.Entry entry : groupMap.entrySet()) { + if (!nowContactIdList.contains(entry.getKey())) { + // 群组-删除 + deleteGroupList.add(entry.getKey()); + log.info("\"{}\"离开了群聊"); + } + } + } + } + log.info("[定时任务]-[联系人监控]-个微新增:{},个微删除:{},企微新增:{},企微删除:{},群组新增:{},群组删除:{}", addPpContactList, deletePpContactList, addCpContactList, + deleteCpContactList, addGroupList, deleteGroupList); + } + + // 监控群成员 + private void groupMemberMonitor() { + if (!groupMap.isEmpty()) { + List groupIdList = new ArrayList<>(groupMap.keySet()); + for (String groupId : groupIdList) { + // 查询 + } + } + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java deleted file mode 100644 index 51e7dea..0000000 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.wechat.ferry.task; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import com.wechat.ferry.entity.dto.WxPpUserDTO; -import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; -import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; -import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; -import com.wechat.ferry.enums.WxContactsTypeEnum; -import com.wechat.ferry.service.WeChatDllService; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Component -public class LeaveGroupMonitorTask { - - private WeChatDllService weChatDllService; - - @Autowired - public void setWeChatDllService(WeChatDllService weChatDllService) { - this.weChatDllService = weChatDllService; - } - - /** - * 群成员信息集合 key:群ID val:微信标识-weChatUid - */ - private final Map> wxPpGroupMemberMap = new HashMap<>(); - - @Scheduled(cron = "0 0/2 * * * ?") - public void scheduled() { - // 群变动 - List groupList = new ArrayList<>(); - List contactsList = weChatDllService.queryContactsList(); - if (!CollectionUtils.isEmpty(contactsList)) { - for (WxPpWcfContactsResp vo : contactsList) { - if (WxContactsTypeEnum.GROUP.getCode().equals(vo.getType())) { - groupList.add(vo.getWeChatUid()); - } - } - // 清理我不在的群 - for (Map.Entry> entry : wxPpGroupMemberMap.entrySet()) { - if (!groupList.contains(entry.getKey())) { - log.info("该账号自身退出了[{}]群组", entry.getKey()); - } - } - } - - // 群成员变动 - if (!CollectionUtils.isEmpty(groupList)) { - WxPpWcfGroupMemberReq request; - for (String gid : groupList) { - request = new WxPpWcfGroupMemberReq(); - request.setGroupNo(gid); - List dbGroupMemberList = weChatDllService.queryGroupMemberList(request); - if (!CollectionUtils.isEmpty(dbGroupMemberList)) { - // 现在的群成员 - Map nowGroupMemberMap = new HashMap<>(); - for (WxPpWcfGroupMemberResp groupMember : dbGroupMemberList) { - nowGroupMemberMap.put(groupMember.getWeChatUid(), groupMember.getGroupNickName()); - } - - Map oldGroupMemberMap = new HashMap<>(); - // 判断之前有没有这个群 - if (wxPpGroupMemberMap.containsKey(gid)) { - // 之前有这个群 - oldGroupMemberMap = wxPpGroupMemberMap.get(gid); - // 遍历之前的群 - for (Map.Entry entry : oldGroupMemberMap.entrySet()) { - if (!nowGroupMemberMap.containsKey(entry.getKey())) { - log.info("{}-{},这个人退出了[{}]群组", entry.getKey(), entry.getValue(), gid); - } - } - } else { - // 之前没这个群 - wxPpGroupMemberMap.put(gid, nowGroupMemberMap); - } - } - } - } - log.info("[定时任务]-[重置签到]-结束"); - } - -}