From 0174c97faf2e5509522202ac6084cb5c4224bb0d Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 10:42:51 +0800 Subject: [PATCH 01/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-1.=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=80=9A=E8=BF=87=E5=A5=BD=E5=8F=8B=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=202.=E6=96=B0=E5=A2=9E=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=BE=A4=E6=88=90=E5=91=98=E4=B8=BA=E5=BE=AE=E4=BF=A1=E5=A5=BD?= =?UTF-8?q?=E5=8F=8B=E6=8E=A5=E5=8F=A3=203.=E6=96=B0=E5=A2=9E=E9=82=80?= =?UTF-8?q?=E8=AF=B7=E7=BE=A4=E6=88=90=E5=91=98=E6=8E=A5=E5=8F=A3=204.?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=A0=E9=99=A4=E7=BE=A4=E6=88=90=E5=91=98?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ferry/controller/WeChatDllController.java | 69 ++-- .../WxPpWcfAddFriendGroupMemberReq.java | 34 ++ .../request/WxPpWcfDeleteGroupMemberReq.java | 34 ++ .../request/WxPpWcfInviteGroupMemberReq.java | 34 ++ .../vo/request/WxPpWcfPassFriendApplyReq.java | 42 +++ .../ferry/handle/WeChatSocketClient.java | 38 -- .../ferry/service/WeChatDllService.java | 70 +++- .../service/impl/WeChatDllServiceImpl.java | 331 +++++++++++------- 8 files changed, 442 insertions(+), 210 deletions(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfAddFriendGroupMemberReq.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDeleteGroupMemberReq.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfInviteGroupMemberReq.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java index e52f160..91b870b 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java @@ -10,9 +10,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.wechat.ferry.entity.TResponse; +import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -115,13 +119,6 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS, list); } - @ApiOperation(value = "查询群成员", notes = "queryGroupMember") - @PostMapping(value = "/list/groupMember") - public TResponse> queryGroupMember(@Validated @RequestBody WxPpWcfGroupMemberReq request) { - List list = weChatDllService.queryGroupMember(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - } - @ApiOperation(value = "发送消息汇总入口", notes = "sendMsgMaster") @PostMapping(value = "/send/msgMaster") public TResponse sendMsgMaster(@Validated @RequestBody String jsonString) { @@ -209,12 +206,40 @@ public class WeChatDllController { // } // - // @ApiOperation(value = "通过好友申请", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse friendApply(@Validated @RequestBody WxPpPatOnePatMsgReq request) { - // // WxPpSendPatOnePatMsgResp resp = weChatDllService.patOnePat(request); - // return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); - // } + @ApiOperation(value = "通过好友申请", notes = "passFriendApply") + @PostMapping(value = "/passFriendApply") + public TResponse passFriendApply(@Validated @RequestBody WxPpWcfPassFriendApplyReq request) { + weChatDllService.passFriendApply(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + + @ApiOperation(value = "添加群成员为微信好友", notes = "addFriendGroupMember") + @PostMapping(value = "/addFriend/groupMember") + public TResponse addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request) { + weChatDllService.addFriendGroupMember(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + + @ApiOperation(value = "查询群成员列表", notes = "queryGroupMemberList") + @PostMapping(value = "/groupMember/list") + public TResponse> queryGroupMemberList(@Validated @RequestBody WxPpWcfGroupMemberReq request) { + List list = weChatDllService.queryGroupMemberList(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, list); + } + + @ApiOperation(value = "邀请群成员", notes = "inviteGroupMember") + @PostMapping(value = "/groupMember/invite") + public TResponse inviteGroupMember(WxPpWcfInviteGroupMemberReq request) { + weChatDllService.inviteGroupMember(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + + @ApiOperation(value = "删除群成员", notes = "deleteGroupMember") + @PostMapping(value = "/groupMember/delete") + public TResponse deleteGroupMember(WxPpWcfDeleteGroupMemberReq request) { + weChatDllService.deleteGroupMember(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } // @ApiOperation(value = "获取朋友圈消息", notes = "queryMsgTypeList") // @PostMapping(value = "/list/msgType") @@ -233,23 +258,5 @@ public class WeChatDllController { // public TResponse queryMsgTypeList() { // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); // } - // - // @ApiOperation(value = "添加群成员", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse queryMsgTypeList() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } - // - // @ApiOperation(value = "删除群成员", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse queryMsgTypeList() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } - // - // @ApiOperation(value = "邀请群成员", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse queryMsgTypeList() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfAddFriendGroupMemberReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfAddFriendGroupMemberReq.java new file mode 100644 index 0000000..1ab873f --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfAddFriendGroupMemberReq.java @@ -0,0 +1,34 @@ +package com.wechat.ferry.entity.vo.request; + +import javax.validation.constraints.NotBlank; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 请求入参-添加群成员为好友 + * + * @author chandler + * @date 2024-12-25 09:53 + */ +@Data +@ApiModel(value = "wxPpWcfAddFriendGroupMemberReq", description = "个微WCF添加群成员为好友请求入参") +public class WxPpWcfAddFriendGroupMemberReq { + + /** + * 群编号 + */ + @NotBlank(message = "群编号不能为空") + @ApiModelProperty(value = "群编号") + private String groupNo; + + /** + * 待添加的群成员列表 + */ + @ApiModelProperty(value = "待添加的群成员列表") + private List groupMembers; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDeleteGroupMemberReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDeleteGroupMemberReq.java new file mode 100644 index 0000000..4055c09 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDeleteGroupMemberReq.java @@ -0,0 +1,34 @@ +package com.wechat.ferry.entity.vo.request; + +import java.util.List; + +import javax.validation.constraints.NotBlank; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求入参-个微WCF删除群成员 + * + * @author chandler + * @date 2024-12-25 10:01 + */ +@Data +@ApiModel(value = "wxPpWcfDeleteGroupMemberReq", description = "个微WCF删除群成员请求入参") +public class WxPpWcfDeleteGroupMemberReq { + + /** + * 群编号 + */ + @NotBlank(message = "群编号不能为空") + @ApiModelProperty(value = "群编号") + private String groupNo; + + /** + * 待删除的群成员列表 + */ + @ApiModelProperty(value = "待删除的群成员列表") + private List groupMembers; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfInviteGroupMemberReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfInviteGroupMemberReq.java new file mode 100644 index 0000000..97bd6cc --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfInviteGroupMemberReq.java @@ -0,0 +1,34 @@ +package com.wechat.ferry.entity.vo.request; + +import java.util.List; + +import javax.validation.constraints.NotBlank; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求入参-个微WCF邀请群成员 + * + * @author chandler + * @date 2024-12-25 09:51 + */ +@Data +@ApiModel(value = "wxPpWcfInviteGroupMemberReq", description = "个微WCF邀请群成员请求入参") +public class WxPpWcfInviteGroupMemberReq { + + /** + * 群编号 + */ + @NotBlank(message = "群编号不能为空") + @ApiModelProperty(value = "群编号") + private String groupNo; + + /** + * 待邀请的群成员列表 + */ + @ApiModelProperty(value = "待邀请的群成员列表") + private List groupMembers; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java new file mode 100644 index 0000000..17fd1f8 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java @@ -0,0 +1,42 @@ +package com.wechat.ferry.entity.vo.request; + +import javax.validation.constraints.NotBlank; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求入参-通过好友申请 + * + * @author chandler + * @date 2024-12-25 09:30 + */ +@Data +@ApiModel(value = "wxPpWcfPassFriendApplyReq", description = "个微WCF通过好友申请请求入参") +public class WxPpWcfPassFriendApplyReq { + + /** + * 申请人 + * v3 xml.attrib["encryptusername"] + */ + @NotBlank(message = "申请人不能为空") + @ApiModelProperty(value = "申请人") + private String applicant; + + /** + * 审核人 + * v4 xml.attrib["ticket"] + * 一般指自己,别人申请添加,自己审核是否通过 + */ + @NotBlank(message = "审核人不能为空") + @ApiModelProperty(value = "审核人") + private String reviewer; + + /** + * 场景 + */ + @ApiModelProperty(value = "场景") + private String scene; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java index 7f34ad4..d707dba 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java @@ -15,10 +15,8 @@ import com.wechat.ferry.entity.proto.Wcf.DbQuery; import com.wechat.ferry.entity.proto.Wcf.DbRow; import com.wechat.ferry.entity.proto.Wcf.DecPath; import com.wechat.ferry.entity.proto.Wcf.Functions; -import com.wechat.ferry.entity.proto.Wcf.MemberMgmt; import com.wechat.ferry.entity.proto.Wcf.Request; import com.wechat.ferry.entity.proto.Wcf.Response; -import com.wechat.ferry.entity.proto.Wcf.Verification; import com.wechat.ferry.entity.proto.Wcf.WxMsg; import com.wechat.ferry.service.SDK; import com.wechat.ferry.utils.HttpClientUtil; @@ -159,42 +157,6 @@ public class WeChatSocketClient { return null; } - /** - * 接收好友请求 - * - * @param v3 xml.attrib["encryptusername"] - * @param v4 xml.attrib["ticket"] - * @return 结果状态码 - */ - public int acceptNewFriend(String v3, String v4) { - int ret = -1; - Verification verification = Verification.newBuilder().setV3(v3).setV4(v4).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_ACCEPT_FRIEND_VALUE).setV(verification).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - - /** - * 添加群成员为微信好友 - * - * @param roomID 群ID - * @param wxIds 要加群的人列表,逗号分隔 - * @return 1 为成功,其他失败 - */ - public int addChatroomMembers(String roomID, String wxIds) { - int ret = -1; - MemberMgmt memberMgmt = MemberMgmt.newBuilder().setRoomid(roomID).setWxids(wxIds).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_ADD_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - /** * 解密图片 * diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java index b998b8c..6f47f17 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java @@ -2,9 +2,13 @@ package com.wechat.ferry.service; import java.util.List; +import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -117,17 +121,6 @@ public interface WeChatDllService { */ List execDbQuerySql(WxPpWcfDatabaseSqlReq request); - /** - * 查询群成员 - * - * @param request 请求入参 - * @return 数据库记录 - * - * @author chandler - * @date 2024-10-02 20:59 - */ - List queryGroupMember(WxPpWcfGroupMemberReq request); - /** * 发送文本消息(可 @) * @@ -207,4 +200,59 @@ public interface WeChatDllService { */ WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request); + /** + * 通过好友申请 + * + * @param request 请求入参 + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 09:38 + */ + String passFriendApply(WxPpWcfPassFriendApplyReq request); + + /** + * 添加群成员为微信好友 + * + * @param request 请求入参 + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 09:38 + */ + String addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request); + + /** + * 查询群成员列表 + * + * @param request 请求入参 + * @return 数据库记录 + * + * @author chandler + * @date 2024-10-02 20:59 + */ + List queryGroupMemberList(WxPpWcfGroupMemberReq request); + + /** + * 邀请群成员 + * + * @param request 请求入参 + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 10:02 + */ + String inviteGroupMember(WxPpWcfInviteGroupMemberReq request); + + /** + * 删除群成员 + * + * @param request 请求入参 + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 10:03 + */ + String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request); + } 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 6a2b61c..caa217d 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 @@ -21,9 +21,13 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.wechat.ferry.config.WeChatFerryProperties; import com.wechat.ferry.entity.proto.Wcf; +import com.wechat.ferry.entity.vo.request.WxPpWcfAddFriendGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseSqlReq; import com.wechat.ferry.entity.vo.request.WxPpWcfDatabaseTableReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfDeleteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -283,7 +287,177 @@ public class WeChatDllServiceImpl implements WeChatDllService { } @Override - public List queryGroupMember(WxPpWcfGroupMemberReq request) { + public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[文本消息]-入参打印:{}", request); + String atUser = ""; + if (request.getIsAtAll()) { + // 艾特全体,仅管理员有效 + atUser = "@all"; + } else { + // 处理艾特的人员 + if (!CollectionUtils.isEmpty(request.getAtUsers())) { + atUser = String.join(",", request.getAtUsers()); + } + } + Wcf.TextMsg textMsg = Wcf.TextMsg.newBuilder().setMsg(request.getMsgText()).setReceiver(request.getRecipient()).setAters(atUser).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_TXT_VALUE).setTxt(textMsg).build(); + log.debug("sendText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + // 0 为成功,其他失败 + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[富文本消息]-入参打印:{}", request); + Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle()) + .setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient()) + .build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); + log.debug("sendRichText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[富文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[XML消息]-入参打印:{}", request); + int xmlType = 0x21; + if ("21".equals(request.getXmlType())) { + // 小程序 + xmlType = 0x21; + } + Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(request.getXmlContent()).setReceiver(request.getRecipient()) + .setPath(request.getResourcePath()).setType(xmlType).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_XML_VALUE).setXml(xmlMsg).build(); + log.debug("sendXml: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[XML消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[图片消息]-入参打印:{}", request); + WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_IMG_VALUE).setFile(pathMsg).build(); + log.debug("sendImage: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[图片消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Deprecated + @Override + public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[表情消息]-入参打印:{}", request); + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); + log.debug("sendEmotion: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[表情消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[文件消息]-入参打印:{}", request); + Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); + log.debug("sendFile: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[文件消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[发送消息]-[拍一拍消息]-入参打印:{}", request); + Wcf.PatMsg patMsg = Wcf.PatMsg.newBuilder().setRoomid(request.getRecipient()).setWxid(request.getPatUser()).build(); + Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); + int state = judgeWcfCmdState(rsp); + // 转发处理 + String stringJson = JSON.toJSONString(request); + sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime)); + return null; + } + + @Override + public String passFriendApply(WxPpWcfPassFriendApplyReq request) { + long startTime = System.currentTimeMillis(); + log.info("[好友申请]-[通过好友申请]-入参打印:{}", request); + Wcf.Verification verification = Wcf.Verification.newBuilder().setV3(request.getApplicant()).setV4(request.getReviewer()).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_ACCEPT_FRIEND_VALUE).setV(verification).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + long endTime = System.currentTimeMillis(); + log.info("[好友申请]-[通过好友申请]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; + } + + @Override + public String addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request) { + long startTime = System.currentTimeMillis(); + log.info("[添加好友]-[添加群成员为好友]-入参打印:{}", request); + if (CollectionUtils.isEmpty(request.getGroupMembers())) { + log.error("[添加好友]-[添加群成员为好友]-待添加人员为空,本次操作取消"); + return ""; + } + String groupMembersStr = String.join(",", request.getGroupMembers()); + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_ADD_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + long endTime = System.currentTimeMillis(); + log.info("[添加好友]-[添加群成员为好友]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; + } + + @Override + public List queryGroupMemberList(WxPpWcfGroupMemberReq request) { long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); // 查询群成员 @@ -353,142 +527,39 @@ public class WeChatDllServiceImpl implements WeChatDllService { } @Override - public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { + public String inviteGroupMember(WxPpWcfInviteGroupMemberReq request) { long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[文本消息]-入参打印:{}", request); - String atUser = ""; - if (request.getIsAtAll()) { - // 艾特全体,仅管理员有效 - atUser = "@all"; - } else { - // 处理艾特的人员 - if (!CollectionUtils.isEmpty(request.getAtUsers())) { - atUser = String.join(",", request.getAtUsers()); - } + log.info("[群成员]-[邀请群成员加入]-入参打印:{}", request); + if (CollectionUtils.isEmpty(request.getGroupMembers())) { + log.error("[群成员]-[邀请群成员加入]-待邀请进群的人员为空,本次操作取消"); + return ""; } - Wcf.TextMsg textMsg = Wcf.TextMsg.newBuilder().setMsg(request.getMsgText()).setReceiver(request.getRecipient()).setAters(atUser).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_TXT_VALUE).setTxt(textMsg).build(); - log.debug("sendText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + String groupMembersStr = String.join(",", request.getGroupMembers()); + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_INV_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); - // 0 为成功,其他失败 - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + int state = judgeWcfCmdState(rsp); long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; + log.info("[群成员]-[邀请群成员加入]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; } @Override - public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) { + public String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request) { long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[富文本消息]-入参打印:{}", request); - Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle()) - .setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient()) - .build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); - log.debug("sendRichText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[富文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; - } - - @Override - public WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request) { - long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[XML消息]-入参打印:{}", request); - int xmlType = 0x21; - if ("21".equals(request.getXmlType())) { - // 小程序 - xmlType = 0x21; + log.info("[群成员]-[删除群成员]-入参打印:{}", request); + if (CollectionUtils.isEmpty(request.getGroupMembers())) { + log.error("[群成员]-[删除群成员]-待删除的人员为空,本次操作取消"); + return ""; } - Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(request.getXmlContent()).setReceiver(request.getRecipient()) - .setPath(request.getResourcePath()).setType(xmlType).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_XML_VALUE).setXml(xmlMsg).build(); - log.debug("sendXml: {}", wechatSocketClient.bytesToHex(req.toByteArray())); + String groupMembersStr = String.join(",", request.getGroupMembers()); + Wcf.MemberMgmt memberMgmt = Wcf.MemberMgmt.newBuilder().setRoomid(request.getGroupNo()).setWxids(groupMembersStr).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_DEL_ROOM_MEMBERS_VALUE).setM(memberMgmt).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + int state = judgeWcfCmdState(rsp); long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[XML消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; - } - - @Override - public WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { - long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[图片消息]-入参打印:{}", request); - WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_IMG_VALUE).setFile(pathMsg).build(); - log.debug("sendImage: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[图片消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; - } - - @Deprecated - @Override - public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { - long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[表情消息]-入参打印:{}", request); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); - log.debug("sendEmotion: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[表情消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; - } - - @Override - public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) { - long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[文件消息]-入参打印:{}", request); - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); - log.debug("sendFile: {}", wechatSocketClient.bytesToHex(req.toByteArray())); - Wcf.Response rsp = wechatSocketClient.sendCmd(req); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[文件消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; - } - - @Override - public WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request) { - long startTime = System.currentTimeMillis(); - log.info("[发送消息]-[拍一拍消息]-入参打印:{}", request); - Wcf.PatMsg patMsg = Wcf.PatMsg.newBuilder().setRoomid(request.getRecipient()).setWxid(request.getPatUser()).build(); - Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); - int state = judgeSendMsgState(rsp); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - long endTime = System.currentTimeMillis(); - log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime)); - return null; + log.info("[群成员]-[删除群成员]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; } /** @@ -615,8 +686,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { } /** - * 判断发送消息状态 - * 0 为成功,其他失败 + * 判断WCF的CMD调用状态 + * 有值 为成功,其他失败 * * @param rsp 响应参数 * @return 状态 @@ -624,8 +695,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { * @author chandler * @date 2024-12-23 21:53 */ - private int judgeSendMsgState(Wcf.Response rsp) { - // 0 为成功,其他失败 + private int judgeWcfCmdState(Wcf.Response rsp) { + // 有值 为成功,其他失败 int state = -1; if (rsp != null) { state = rsp.getStatus(); From e9e20155203e4dc868ef079f2a2475640e296b47 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 10:52:52 +0800 Subject: [PATCH 02/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=9B=9E=E8=B0=83=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8D=E7=A7=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ferry/config/WeChatFerryProperties.java | 16 +++--- ...TypeEnum.java => MsgCallbackTypeEnum.java} | 19 +++---- .../service/impl/WeChatDllServiceImpl.java | 54 +++++++++---------- .../service/impl/WeChatMsgServiceImpl.java | 17 +++--- .../src/main/resources/application.yml | 16 +++--- 5 files changed, 61 insertions(+), 61 deletions(-) rename clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/{MsgFwdTypeEnum.java => MsgCallbackTypeEnum.java} (58%) diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatFerryProperties.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatFerryProperties.java index 46893a9..28e5789 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatFerryProperties.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatFerryProperties.java @@ -47,24 +47,24 @@ public class WeChatFerryProperties { private List openMsgGroups; /** - * 接收消息转发开关 + * 接收消息回调开关 */ - private Boolean receiveMsgFwdSwitch = false; + private Boolean receiveMsgCallbackSwitch = false; /** - * 接收消息转发URL + * 接收消息回调地址 */ - private List receiveMsgFwdUrls; + private List receiveMsgCallbackUrls; /** - * 发送消息转发标识 1-关闭 2-全转发 3-发送成功才转发 + * 发送消息回调标识 1-关闭 2-全部回调 3-发送成功才回调 */ - private String sendMsgFwdFlag = "1"; + private String sendMsgCallbackFlag = "1"; /** - * 发送消息转发URL + * 发送消息回调地址 */ - private List sendMsgFwdUrls; + private List sendMsgCallbackUrls; /** * 调用第三方服务客户端成功状态码 diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgFwdTypeEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgCallbackTypeEnum.java similarity index 58% rename from clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgFwdTypeEnum.java rename to clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgCallbackTypeEnum.java index c9a7648..787eeb9 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgFwdTypeEnum.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/MsgCallbackTypeEnum.java @@ -8,15 +8,15 @@ import lombok.AllArgsConstructor; import lombok.Getter; /** - * 枚举-消息转发开关 - * 1-关闭 2-全转发 3-发送成功才转发 + * 枚举-消息回调开关 + * 1-关闭 2-全部回调 3-发送成功才回调 * * @author chandler * @date 2024/10/01 15:42 */ @Getter @AllArgsConstructor -public enum MsgFwdTypeEnum { +public enum MsgCallbackTypeEnum { /** * 1-关闭 @@ -24,14 +24,14 @@ public enum MsgFwdTypeEnum { CLOSE("1", "关闭"), /** - * 2-全转发 + * 2-全部回调 */ - ALL("2", "全转发"), + ALL("2", "全部回调"), /** - * 3-发送成功才转发 + * 3-发送成功才回调 */ - SUCCESS("3", "发送成功才转发"), + SUCCESS("3", "发送成功才回调"), /** * 未匹配上 @@ -47,12 +47,13 @@ public enum MsgFwdTypeEnum { /** * map集合 key:code val:枚举 */ - public static final Map codeMap = Arrays.stream(values()).collect(Collectors.toMap(MsgFwdTypeEnum::getCode, v -> v)); + public static final Map codeMap = + Arrays.stream(values()).collect(Collectors.toMap(MsgCallbackTypeEnum::getCode, v -> v)); /** * 根据code获取枚举 */ - public static MsgFwdTypeEnum getCodeMap(String code) { + public static MsgCallbackTypeEnum 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 caa217d..67418ef 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 @@ -50,7 +50,7 @@ import com.wechat.ferry.entity.vo.response.WxPpWcfSendRichTextMsgResp; import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp; import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; import com.wechat.ferry.enums.DatabaseNameEnum; -import com.wechat.ferry.enums.MsgFwdTypeEnum; +import com.wechat.ferry.enums.MsgCallbackTypeEnum; import com.wechat.ferry.enums.SexEnum; import com.wechat.ferry.enums.WxContactsMixedEnum; import com.wechat.ferry.enums.WxContactsOfficialEnum; @@ -306,9 +306,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { Wcf.Response rsp = wechatSocketClient.sendCmd(req); // 0 为成功,其他失败 int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -325,9 +325,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.debug("sendRichText: {}", wechatSocketClient.bytesToHex(req.toByteArray())); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[富文本消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -348,9 +348,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.debug("sendXml: {}", wechatSocketClient.bytesToHex(req.toByteArray())); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[XML消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -366,9 +366,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.debug("sendImage: {}", wechatSocketClient.bytesToHex(req.toByteArray())); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[图片消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -384,9 +384,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.debug("sendEmotion: {}", wechatSocketClient.bytesToHex(req.toByteArray())); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[表情消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -401,9 +401,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.debug("sendFile: {}", wechatSocketClient.bytesToHex(req.toByteArray())); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[文件消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -417,9 +417,9 @@ public class WeChatDllServiceImpl implements WeChatDllService { Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); int state = judgeWcfCmdState(rsp); - // 转发处理 + // 回调处理 String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); + sendMsgCallback(stringJson, state); long endTime = System.currentTimeMillis(); log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; @@ -624,7 +624,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { } /** - * 消息转发 + * 消息回调 * * @param jsonString json数据 * @param state cmd调用状态 @@ -632,27 +632,27 @@ public class WeChatDllServiceImpl implements WeChatDllService { * @author chandler * @date 2024-10-10 23:10 */ - private void sendMsgForward(String jsonString, Integer state) { - // 根据配置文件决定是否转发 - if (MsgFwdTypeEnum.CLOSE.getCode().equals(weChatFerryProperties.getSendMsgFwdFlag()) - || (MsgFwdTypeEnum.SUCCESS.getCode().equals(weChatFerryProperties.getSendMsgFwdFlag()) && 0 != state)) { - // 如果是关闭 或者 配置为成功才转发但发送状态为失败 的情况则取消发送 + private void sendMsgCallback(String jsonString, Integer state) { + // 根据配置文件决定是否回调 + if (MsgCallbackTypeEnum.CLOSE.getCode().equals(weChatFerryProperties.getSendMsgCallbackFlag()) + || (MsgCallbackTypeEnum.SUCCESS.getCode().equals(weChatFerryProperties.getSendMsgCallbackFlag()) && 0 != state)) { + // 如果是关闭 或者 配置为成功才回调但发送状态为失败 的情况则取消发送 return; } - // 开启转发,且转发地址不为空 - if (!CollectionUtils.isEmpty(weChatFerryProperties.getSendMsgFwdUrls())) { - for (String receiveMsgFwdUrl : weChatFerryProperties.getSendMsgFwdUrls()) { + // 开启回调,且回调地址不为空 + if (!CollectionUtils.isEmpty(weChatFerryProperties.getSendMsgCallbackUrls())) { + for (String receiveMsgFwdUrl : weChatFerryProperties.getSendMsgCallbackUrls()) { if (!receiveMsgFwdUrl.startsWith("http")) { continue; } try { String responseStr = HttpClientUtil.doPostJson(receiveMsgFwdUrl, jsonString); if (judgeSuccess(responseStr)) { - log.error("[发送消息]-消息转发外部接口,获取响应状态失败!-URL:{}", receiveMsgFwdUrl); + log.error("[发送消息]-消息回调至外部接口,获取响应状态失败!-URL:{}", receiveMsgFwdUrl); } - log.debug("[发送消息]-[转发接收到的消息]-转发消息至:{}", receiveMsgFwdUrl); + log.debug("[发送消息]-[回调接收到的消息]-回调消息至:{}", receiveMsgFwdUrl); } catch (Exception e) { - log.error("[发送消息]-消息转发接口[{}]服务异常:", receiveMsgFwdUrl, e); + log.error("[发送消息]-消息回调接口[{}]服务异常:", receiveMsgFwdUrl, e); } } } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java index 640c299..72fe5df 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java @@ -4,7 +4,6 @@ import java.util.Map; import javax.annotation.Resource; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -34,7 +33,7 @@ public class WeChatMsgServiceImpl implements WeChatMsgService { @Override public void receiveMsg(String jsonString) { // 转发接口处理 - receiveMsgForward(jsonString); + receiveMsgCallback(jsonString); // 转为JSON对象 WxPpMsgDTO dto = JSON.parseObject(jsonString, WxPpMsgDTO.class); // 有开启的群聊配置 @@ -47,21 +46,21 @@ public class WeChatMsgServiceImpl implements WeChatMsgService { log.debug("[收到消息]-[消息内容]-打印:{}", dto); } - private void receiveMsgForward(String jsonString) { - // 开启转发,且转发地址不为空 - if (weChatFerryProperties.getReceiveMsgFwdSwitch() && !CollectionUtils.isEmpty(weChatFerryProperties.getReceiveMsgFwdUrls())) { - for (String receiveMsgFwdUrl : weChatFerryProperties.getReceiveMsgFwdUrls()) { + private void receiveMsgCallback(String jsonString) { + // 开启回调,且回调地址不为空 + if (weChatFerryProperties.getReceiveMsgCallbackSwitch() && !CollectionUtils.isEmpty(weChatFerryProperties.getReceiveMsgCallbackUrls())) { + for (String receiveMsgFwdUrl : weChatFerryProperties.getReceiveMsgCallbackUrls()) { if (!receiveMsgFwdUrl.startsWith("http")) { continue; } try { String responseStr = HttpClientUtil.doPostJson(receiveMsgFwdUrl, jsonString); if (judgeSuccess(responseStr)) { - log.error("[接收消息]-消息转发外部接口,获取响应状态失败!-URL:{}", receiveMsgFwdUrl); + log.error("[接收消息]-消息回调至外部接口,获取响应状态失败!-URL:{}", receiveMsgFwdUrl); } - log.debug("[接收消息]-[转发接收到的消息]-转发消息至:{}", receiveMsgFwdUrl); + log.debug("[接收消息]-[回调接收到的消息]-回调消息至:{}", receiveMsgFwdUrl); } catch (Exception e) { - log.error("[接收消息]-消息转发接口[{}]服务异常:", receiveMsgFwdUrl, e); + log.error("[接收消息]-消息回调接口[{}]服务异常:", receiveMsgFwdUrl, e); } } } diff --git a/clients/java/wechat-ferry-mvn/src/main/resources/application.yml b/clients/java/wechat-ferry-mvn/src/main/resources/application.yml index fc9a8c2..8f78100 100644 --- a/clients/java/wechat-ferry-mvn/src/main/resources/application.yml +++ b/clients/java/wechat-ferry-mvn/src/main/resources/application.yml @@ -35,15 +35,15 @@ wechat: # 需要开启消息处理的群 open-msg-groups: - 53257911728@chatroom - # 接收消息转发开关 - receive-msg-fwd-switch: false - # 接收消息转发URL - receive-msg-fwd-urls: + # 接收消息回调开关 + receive-msg-callback-switch: false + # 接收消息回调地址 + receive-msg-callback-urls: - http://localhost:9001/msg - # 发送消息转发标识 1-关闭 2-全转发 3-发送成功才转发 - send-msg-fwd-flag: '1' - # 发送消息转发URL - send-msg-fwd-urls: + # 发送消息回调标识 1-关闭 2-全部回调 3-发送成功才回调 + send-msg-callback-flag: '1' + # 发送消息回调地址 + send-msg-callback-urls: - http://localhost:9001/msg # 调用第三方服务客户端成功状态码 third-party-ok-codes: From 8194076dd3ad3e1f717304ff01898b64baa378f4 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 11:03:02 +0800 Subject: [PATCH 03/18] docs(0): [java]-[mvn]-update CHANGELOG.md --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 54 ++++++++++++++-------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index cf6c553..451218f 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -2,30 +2,46 @@ ### 功能列表 -| 接口名 | 地址 | 是否支持 | 备注 | -|----------------|-------------------|------|-------------------| -| 查询登录状态 | /loginStatus | √ | 已测试 | -| 获取登录微信内部识别号UID | /loginWeChatUid | √ | 已测试 | -| 获取登录微信信息 | /loginWeChatInfo | √ | 已测试 | -| 获取消息类型列表 | /list/msgType | √ | 已测试 | -| 获取联系人列表 | /list/contacts | √ | 已测试 | -| 获取数据库表名称列表 | /list/dbTableName | √ | 已测试 | -| 获取指定数据库中的表列表 | /list/dbTable | √ | 已测试 | -| 执行数据库查询SQL | /exec/dbQuerySql | √ | 已测试 | -| 查询群成员 | /list/groupMember | √ | 已测试 | -| 发送消息汇总入口 | /send/msgMaster | x | 预留 | -| 发送文本消息 | /send/textMsg | x | 该版本不支持 | -| 发送富文本消息 | /send/richTextMsg | x | 缩略图参数需要为空,否则会发送失败 | -| 发送XML消息 | /send/xmlMsg | ? | 待测试 | -| 发送图片消息 | /send/imageMsg | √ | 已测试 | -| 发送表情消息 | /send/emojiMsg | x | 该版本不支持 | -| 发送文件消息 | /send/fileMsg | x | 该版本不支持 | -| 拍一拍群友 | /patOnePat | √ | 已测试 | +| 接口名 | 地址 | 是否支持 | 备注 | +|----------------|------------------------|------|-------------------| +| 查询登录状态 | /loginStatus | √ | 已测试 | +| 获取登录微信内部识别号UID | /loginWeChatUid | √ | 已测试 | +| 获取登录微信信息 | /loginWeChatInfo | √ | 已测试 | +| 获取消息类型列表 | /list/msgType | √ | 已测试 | +| 获取联系人列表 | /list/contacts | √ | 已测试 | +| 获取数据库表名称列表 | /list/dbTableName | √ | 已测试 | +| 获取指定数据库中的表列表 | /list/dbTable | √ | 已测试 | +| 执行数据库查询SQL | /exec/dbQuerySql | √ | 已测试 | +| 发送消息汇总入口 | /send/msgMaster | x | 预留 | +| 发送文本消息 | /send/textMsg | x | 该版本不支持 | +| 发送富文本消息 | /send/richTextMsg | x | 缩略图参数需要为空,否则会发送失败 | +| 发送XML消息 | /send/xmlMsg | ? | 待测试 | +| 发送图片消息 | /send/imageMsg | √ | 已测试 | +| 发送表情消息 | /send/emojiMsg | x | 该版本不支持 | +| 发送文件消息 | /send/fileMsg | x | 该版本不支持 | +| 拍一拍群友 | /patOnePat | √ | 已测试 | +| 通过好友申请 | /passFriendApply | ? | 待测试 | +| 添加群成员为微信好友 | /addFriend/groupMember | ? | 待测试 | +| 查询群成员 | /groupMember/list | √ | 已测试 | +| 邀请群成员 | /groupMember/invite | ? | 待测试 | +| 删除群成员 | /groupMember/delete | ? | 待测试 | ### 已知BUG - 1.发送表情微信客户端闪退 - `待修复` - 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复` +- 3.发送文件成功之后客户端崩溃 - `待修复` + +### 2024-12-25 + +#### ⛰️ Features + +- 新增通过好友申请接口 +- 新增添加群成员为微信好友接口 +- 新增邀请群成员接口 +- 新增删除群成员接口 +- 消息回调配置文件参数名称修改 +- ### 2024-12-24 From 70f131913744c6b7c6cf0b4f7cf49e8de70aaeb0 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 12:16:42 +0800 Subject: [PATCH 04/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-1.=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=88=B7=E6=96=B0=E6=9C=8B=E5=8F=8B=E5=9C=88=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=202.=E6=96=B0=E5=A2=9E=E6=92=A4=E5=9B=9E=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 2 ++ .../ferry/controller/WeChatDllController.java | 32 ++++++++++--------- .../vo/request/WxPpWcfPassFriendApplyReq.java | 3 ++ .../vo/request/WxPpWcfRevokeMsgReq.java | 25 +++++++++++++++ .../ferry/service/WeChatDllService.java | 21 ++++++++++++ .../service/impl/WeChatDllServiceImpl.java | 31 +++++++++++++++++- 6 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 451218f..7df6334 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -20,11 +20,13 @@ | 发送表情消息 | /send/emojiMsg | x | 该版本不支持 | | 发送文件消息 | /send/fileMsg | x | 该版本不支持 | | 拍一拍群友 | /patOnePat | √ | 已测试 | +| 撤回消息 | /revokeMsg | ? | 待测试 | | 通过好友申请 | /passFriendApply | ? | 待测试 | | 添加群成员为微信好友 | /addFriend/groupMember | ? | 待测试 | | 查询群成员 | /groupMember/list | √ | 已测试 | | 邀请群成员 | /groupMember/invite | ? | 待测试 | | 删除群成员 | /groupMember/delete | ? | 待测试 | +| 查询朋友圈 | /friendCircle | ? | 待测试 | ### 已知BUG diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java index 91b870b..f98d86b 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java @@ -18,6 +18,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; @@ -181,12 +182,12 @@ public class WeChatDllController { // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); // } - // @ApiOperation(value = "撤回消息", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse queryMsgTypeList() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } - // + @ApiOperation(value = "撤回消息", notes = "revokeMsg") + @PostMapping(value = "/revokeMsg") + public TResponse revokeMsg(@Validated @RequestBody WxPpWcfRevokeMsgReq request) { + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + // @ApiOperation(value = "转发消息", notes = "queryMsgTypeList") // @PostMapping(value = "/list/msgType") // public TResponse queryMsgTypeList() { @@ -215,7 +216,7 @@ public class WeChatDllController { @ApiOperation(value = "添加群成员为微信好友", notes = "addFriendGroupMember") @PostMapping(value = "/addFriend/groupMember") - public TResponse addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request) { + public TResponse addFriendGroupMember(@Validated @RequestBody WxPpWcfAddFriendGroupMemberReq request) { weChatDllService.addFriendGroupMember(request); return TResponse.ok(ResponseCodeEnum.SUCCESS); } @@ -229,24 +230,25 @@ public class WeChatDllController { @ApiOperation(value = "邀请群成员", notes = "inviteGroupMember") @PostMapping(value = "/groupMember/invite") - public TResponse inviteGroupMember(WxPpWcfInviteGroupMemberReq request) { + public TResponse inviteGroupMember(@Validated @RequestBody WxPpWcfInviteGroupMemberReq request) { weChatDllService.inviteGroupMember(request); return TResponse.ok(ResponseCodeEnum.SUCCESS); } @ApiOperation(value = "删除群成员", notes = "deleteGroupMember") @PostMapping(value = "/groupMember/delete") - public TResponse deleteGroupMember(WxPpWcfDeleteGroupMemberReq request) { + public TResponse deleteGroupMember(@Validated @RequestBody WxPpWcfDeleteGroupMemberReq request) { weChatDllService.deleteGroupMember(request); return TResponse.ok(ResponseCodeEnum.SUCCESS); } - // @ApiOperation(value = "获取朋友圈消息", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/msgType") - // public TResponse queryMsgTypeList() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } - // + @ApiOperation(value = "查询朋友圈", notes = "queryFriendCircle") + @PostMapping(value = "/friendCircle") + public TResponse queryFriendCircle() { + weChatDllService.queryFriendCircle(); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + // @ApiOperation(value = "下载图片、视频、文件", notes = "queryMsgTypeList") // @PostMapping(value = "/list/msgType") // public TResponse queryMsgTypeList() { diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java index 17fd1f8..1c801c5 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPassFriendApplyReq.java @@ -19,6 +19,7 @@ public class WxPpWcfPassFriendApplyReq { /** * 申请人 * v3 xml.attrib["encryptusername"] + * 加密用户名 (好友申请消息里 v3 开头的字符串) */ @NotBlank(message = "申请人不能为空") @ApiModelProperty(value = "申请人") @@ -27,6 +28,7 @@ public class WxPpWcfPassFriendApplyReq { /** * 审核人 * v4 xml.attrib["ticket"] + * Ticket (好友申请消息里 v4 开头的字符串) * 一般指自己,别人申请添加,自己审核是否通过 */ @NotBlank(message = "审核人不能为空") @@ -35,6 +37,7 @@ public class WxPpWcfPassFriendApplyReq { /** * 场景 + * 申请方式 (好友申请消息里的 scene); 为了兼容旧接口,默认为扫码添加 (30) */ @ApiModelProperty(value = "场景") private String scene; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java new file mode 100644 index 0000000..81abd17 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfRevokeMsgReq.java @@ -0,0 +1,25 @@ +package com.wechat.ferry.entity.vo.request; + +import javax.validation.constraints.NotBlank; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求入参-撤回消息 + * + * @author chandler + * @date 2024-12-25 12:00 + */ +@Data +@ApiModel(value = "wxPpWcfRevokeMsgReq", description = "个微WCF撤回消息请求入参") +public class WxPpWcfRevokeMsgReq { + + /** + * 消息编号 + */ + @ApiModelProperty(value = "场景") + private String msgId; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java index 6f47f17..94df650 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java @@ -10,6 +10,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; @@ -200,6 +201,16 @@ public interface WeChatDllService { */ WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request); + /** + * 撤回消息 + * + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 11:59 + */ + String revokeMsg(WxPpWcfRevokeMsgReq request); + /** * 通过好友申请 * @@ -255,4 +266,14 @@ public interface WeChatDllService { */ String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request); + /** + * 查询朋友圈 + * + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 11:11 + */ + String queryFriendCircle(); + } 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 67418ef..1fd9237 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 @@ -29,6 +29,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendImageMsgReq; @@ -425,6 +426,22 @@ public class WeChatDllServiceImpl implements WeChatDllService { return null; } + @Override + public String revokeMsg(WxPpWcfRevokeMsgReq request) { + long startTime = System.currentTimeMillis(); + log.info("[撤回消息]-[消息撤回]-入参打印:{}", request); + long msgId = Long.parseLong(request.getMsgId()); + Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REVOKE_MSG_VALUE).setUi64(msgId).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); + int state = judgeWcfCmdState(rsp); + // 回调处理 + String stringJson = JSON.toJSONString(request); + sendMsgCallback(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[撤回消息]-[消息撤回]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; + } + @Override public String passFriendApply(WxPpWcfPassFriendApplyReq request) { long startTime = System.currentTimeMillis(); @@ -562,6 +579,18 @@ public class WeChatDllServiceImpl implements WeChatDllService { return ""; } + @Override + public String queryFriendCircle() { + long startTime = System.currentTimeMillis(); + log.info("[查询]-[刷新朋友圈]-开始"); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REFRESH_PYQ_VALUE).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[刷新朋友圈]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; + } + /** * 获取SQL类型 * @@ -597,7 +626,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { if (converter != null) { return converter.apply(content.toByteArray()); } else { - log.warn("未知的SQL类型: {}", type); + log.warn("[SQL转换类型]-未知的SQL类型: {}", type); return content.toByteArray(); } } From 5f824074c3c604a2a82cf1511c351a9e3f38c9bc Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 14:01:44 +0800 Subject: [PATCH 05/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8E=A5=E6=94=B6=E8=BD=AC=E8=B4=A6=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 6 +++- .../ferry/controller/WeChatDllController.java | 8 +++++ .../vo/request/WxPpWcfReceiveTransferReq.java | 35 +++++++++++++++++++ .../ferry/service/WeChatDllService.java | 12 +++++++ .../service/impl/WeChatDllServiceImpl.java | 15 ++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfReceiveTransferReq.java diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 7df6334..e9d1e7e 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -27,6 +27,7 @@ | 邀请群成员 | /groupMember/invite | ? | 待测试 | | 删除群成员 | /groupMember/delete | ? | 待测试 | | 查询朋友圈 | /friendCircle | ? | 待测试 | +| 接收转账 | /receiveTransfer | ? | 待测试 | ### 已知BUG @@ -42,8 +43,11 @@ - 新增添加群成员为微信好友接口 - 新增邀请群成员接口 - 新增删除群成员接口 +- 新增刷新朋友圈接口 +- 新增撤回消息接口 +- 接收转账 +- 查询群成员请求地址变更 - 消息回调配置文件参数名称修改 -- ### 2024-12-24 diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java index f98d86b..48b780c 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/controller/WeChatDllController.java @@ -18,6 +18,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -249,6 +250,13 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS); } + @ApiOperation(value = "接收转账", notes = "receiveTransfer") + @PostMapping(value = "/receiveTransfer") + public TResponse receiveTransfer(@Validated @RequestBody WxPpWcfReceiveTransferReq request) { + weChatDllService.receiveTransfer(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS); + } + // @ApiOperation(value = "下载图片、视频、文件", notes = "queryMsgTypeList") // @PostMapping(value = "/list/msgType") // public TResponse queryMsgTypeList() { diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfReceiveTransferReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfReceiveTransferReq.java new file mode 100644 index 0000000..b7e3bea --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfReceiveTransferReq.java @@ -0,0 +1,35 @@ +package com.wechat.ferry.entity.vo.request; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求入参-个微WCF接收转账 + * + * @author chandler + * @date 2024-12-25 13:46 + */ +@Data +@ApiModel(value = "wxPpWcfReceiveTransferReq", description = "个微WCF接收转账请求入参") +public class WxPpWcfReceiveTransferReq { + + /** + * 转账人 + */ + @ApiModelProperty(value = "转账人") + private String weChatUid; + + /** + * 转账编号 transferId + */ + @ApiModelProperty(value = "转账编号") + private String transferId; + + /** + * 交易编号 Transaction id + */ + @ApiModelProperty(value = "交易编号") + private String transactionId; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java index 94df650..3290b42 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/WeChatDllService.java @@ -10,6 +10,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -276,4 +277,15 @@ public interface WeChatDllService { */ String queryFriendCircle(); + /** + * 接收转账 + * + * @param request 请求入参 + * @return 结果状态 + * + * @author chandler + * @date 2024-12-25 13:48 + */ + String receiveTransfer(WxPpWcfReceiveTransferReq request); + } 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 1fd9237..f5f5600 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 @@ -29,6 +29,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfInviteGroupMemberReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPassFriendApplyReq; import com.wechat.ferry.entity.vo.request.WxPpWcfPatOnePatMsgReq; +import com.wechat.ferry.entity.vo.request.WxPpWcfReceiveTransferReq; import com.wechat.ferry.entity.vo.request.WxPpWcfRevokeMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendEmojiMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendFileMsgReq; @@ -591,6 +592,20 @@ public class WeChatDllServiceImpl implements WeChatDllService { return ""; } + @Override + public String receiveTransfer(WxPpWcfReceiveTransferReq request) { + long startTime = System.currentTimeMillis(); + log.info("[转账]-[接收转账]-开始"); + Wcf.Transfer transfer = + Wcf.Transfer.newBuilder().setWxid(request.getWeChatUid()).setTfid(request.getTransferId()).setTaid(request.getTransferId()).build(); + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_RECV_TRANSFER_VALUE).setTf(transfer).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + int state = judgeWcfCmdState(rsp); + long endTime = System.currentTimeMillis(); + log.info("[转账]-[接收转账]-处理结束,耗时:{}ms", (endTime - startTime)); + return ""; + } + /** * 获取SQL类型 * From 9262b084bacd597a3c4812664cec3e543d8c9dad Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 15:14:46 +0800 Subject: [PATCH 06/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E5=B0=81?= =?UTF-8?q?=E8=A3=85=E6=8E=A5=E6=94=B6=E5=88=B0=E6=B6=88=E6=81=AF=E4=B9=8B?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E4=B8=9A=E5=8A=A1=E6=93=8D=E4=BD=9C=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 1 + .../wechat/ferry/entity/dto/WxPpMsgDTO.java | 2 +- .../ferry/enums/ReceiveMsgChannelEnum.java | 49 +++++++++++ .../service/impl/WeChatMsgServiceImpl.java | 16 +++- .../msg/receive/ReceiveMsgFactory.java | 84 +++++++++++++++++++ .../msg/receive/ReceiveMsgStrategy.java | 27 ++++++ .../receive/impl/SignInMsgStrategyImpl.java | 33 ++++++++ 7 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/ReceiveMsgChannelEnum.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgFactory.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgStrategy.java create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/impl/SignInMsgStrategyImpl.java diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index e9d1e7e..872ba07 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -48,6 +48,7 @@ - 接收转账 - 查询群成员请求地址变更 - 消息回调配置文件参数名称修改 +- 封装接收到消息之后的业务操作类 ### 2024-12-24 diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/dto/WxPpMsgDTO.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/dto/WxPpMsgDTO.java index b30515a..9e341df 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/dto/WxPpMsgDTO.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/dto/WxPpMsgDTO.java @@ -7,7 +7,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** - * DTO-ge微信消息 + * DTO-个微信消息 * * @author chandler * @date 2024-09-26 19:56 diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/ReceiveMsgChannelEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/ReceiveMsgChannelEnum.java new file mode 100644 index 0000000..f279c85 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/ReceiveMsgChannelEnum.java @@ -0,0 +1,49 @@ +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/25 14:15 + */ +@Getter +@AllArgsConstructor +public enum ReceiveMsgChannelEnum { + + /** + * 1-签到 + */ + SIGN_IN("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(ReceiveMsgChannelEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static ReceiveMsgChannelEnum 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/WeChatMsgServiceImpl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java index 72fe5df..5fb9cc3 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java @@ -13,6 +13,8 @@ import com.alibaba.fastjson2.JSONObject; import com.wechat.ferry.config.WeChatFerryProperties; import com.wechat.ferry.entity.dto.WxPpMsgDTO; import com.wechat.ferry.service.WeChatMsgService; +import com.wechat.ferry.strategy.msg.receive.ReceiveMsgFactory; +import com.wechat.ferry.strategy.msg.receive.ReceiveMsgStrategy; import com.wechat.ferry.utils.HttpClientUtil; import lombok.extern.slf4j.Slf4j; @@ -40,7 +42,19 @@ public class WeChatMsgServiceImpl implements WeChatMsgService { if (!CollectionUtils.isEmpty(weChatFerryProperties.getOpenMsgGroups())) { // 指定处理的群聊 if (weChatFerryProperties.getOpenMsgGroups().contains(dto.getRoomId())) { - // TODO 这里可以拓展自己需要的功能 + // TODO 模式有多种 1-根据消息类型单独调用某一个 2-全部调用,各业务类中自己决定是否继续 + if (true) { + // 因为一种消息允许进行多种处理,这里采用执行所有策略,请自行在各策略中判断是否需要执行 + for (ReceiveMsgStrategy value : ReceiveMsgFactory.getAllStrategyContainers().values()) { + value.doHandle(dto); + } + } else { + // 单独调用某一种 + // 这里自己把消息类型转为自己的枚举类型 + String handleType = "1"; + ReceiveMsgStrategy receiveMsgStrategy = ReceiveMsgFactory.getStrategy(handleType); + receiveMsgStrategy.doHandle(dto); + } } } log.debug("[收到消息]-[消息内容]-打印:{}", dto); diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgFactory.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgFactory.java new file mode 100644 index 0000000..39fb5b0 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgFactory.java @@ -0,0 +1,84 @@ +package com.wechat.ferry.strategy.msg.receive; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import com.wechat.ferry.enums.ReceiveMsgChannelEnum; +import com.wechat.ferry.exception.BizException; + +import lombok.extern.slf4j.Slf4j; + +/** + * 策略Context-消息处理-接收消息 + * 可以切换策略的Context(这里实际是Factory)类 + * + * @author chandler + * @date 2024-12-25 14:08 + */ +@Slf4j +@Component +public class ReceiveMsgFactory implements InitializingBean { + + private static final Map strategyContainerMap = new HashMap<>(); + + /** + * spring的上下文 + */ + @Resource + private ApplicationContext applicationContext; + + /** + * 实现InitializingBean的方法会在启动的时候执行afterPropertiesSet()方法 + * 将Strategy的类都按照定义好的规则(fetchKey),放入Map中 + */ + @Override + public void afterPropertiesSet() { + // 初始化时把所有的策略bean放进ioc,用于使用的时候获取 + Map strategyMap = applicationContext.getBeansOfType(ReceiveMsgStrategy.class); + strategyMap.forEach((k, v) -> { + String type = v.getStrategyType(); + log.debug("[策略Context]-[MessageNoticeSendFactory]-策略类型加载:{}", type); + strategyContainerMap.putIfAbsent(type, v); + }); + } + + /** + * 根据策略类型获取不同处理策略类 + * + * @param strategyType 策略类型 + * @return 策略类 + */ + public static ReceiveMsgStrategy getStrategy(String strategyType) { + log.debug("[策略Context]-[ReceiveMsgStrategy]-当前策略类型:{}", strategyType); + // 策略类对应的枚举 + if (!ReceiveMsgChannelEnum.codeMap.containsKey(strategyType)) { + // 当前的渠道类型未匹配到 + log.error("入参中的策略类型:{}不在枚举(ReceiveMsgChannelEnum)定义范围内,请检查数据合法性!", strategyType); + // TODO 正常所有的策略都应该在枚举中定义,但考虑到有些人是把项目集成到自己系统中,部分自己的策略类未在枚举中定义,所以这里不抛异常,但是我们建议开启 + // throw new BizException("当前策略未在枚举中定义,请先在枚举中指定"); + } + ReceiveMsgStrategy handler = strategyContainerMap.get(strategyType); + if (handler == null) { + log.error("[策略Context]-[MessageNoticeSendFactory]-策略类型:{}-未找到合适的处理器!", strategyType); + throw new BizException("未找到合适的处理器!"); + } + return handler; + } + + /** + * 获取全部策略 + * 用于需要全部执行的情况 + * + * @return 所有的策略类 + */ + public static Map getAllStrategyContainers() { + return strategyContainerMap; + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgStrategy.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgStrategy.java new file mode 100644 index 0000000..7fb0a81 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/ReceiveMsgStrategy.java @@ -0,0 +1,27 @@ +package com.wechat.ferry.strategy.msg.receive; + +import com.wechat.ferry.entity.dto.WxPpMsgDTO; + +/** + * 策略接口-消息处理-接收消息处理 + * + * @author chandler + * @date 2024-12-25 14:07 + */ +public interface ReceiveMsgStrategy { + + /** + * 获取策略的类型 + * + * @return 返回代表策略类型的字符串 + */ + String getStrategyType(); + + /** + * 具体的处理 + * + * @return 如果是多字段,可以转为JSON字符串返回,已适配不同的返回数据 + */ + String doHandle(WxPpMsgDTO dto); + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/impl/SignInMsgStrategyImpl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/impl/SignInMsgStrategyImpl.java new file mode 100644 index 0000000..7c7061a --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/msg/receive/impl/SignInMsgStrategyImpl.java @@ -0,0 +1,33 @@ +package com.wechat.ferry.strategy.msg.receive.impl; + +import com.wechat.ferry.entity.dto.WxPpMsgDTO; +import com.wechat.ferry.enums.ReceiveMsgChannelEnum; +import com.wechat.ferry.strategy.msg.receive.ReceiveMsgStrategy; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 策略实现类-接收消息-签到处理 + * + * @author chandler + * @date 2024-12-25 14:19 + */ +@Slf4j +@Component +public class SignInMsgStrategyImpl implements ReceiveMsgStrategy { + + @Override + public String getStrategyType() { + log.debug("[接收消息]-[签到处理]-匹配到:{}-{}-策略", ReceiveMsgChannelEnum.SIGN_IN.getCode(), ReceiveMsgChannelEnum.SIGN_IN.getName()); + return ReceiveMsgChannelEnum.SIGN_IN.getCode(); + } + + @Override + public String doHandle(WxPpMsgDTO dto) { + // TODO 这里写具体的操作 + // 当前是使用的所有策略类全部执行 所以这里需要控制哪种类型才处理 + log.info("签到处理"); + return ""; + } + +} From 95756c0e375fd6e77cd40907e935aa76521da443 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 18:14:17 +0800 Subject: [PATCH 07/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E5=8D=A0?= =?UTF-8?q?=E4=BD=8D=E6=96=87=E4=BB=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/wechat/ferry/strategy/.gitkeep | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/.gitkeep diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/.gitkeep b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/strategy/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file From 4fb396bd375251d69181849c4bedad3a8f84b085 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 20:31:53 +0800 Subject: [PATCH 08/18] docs: [java]-[mvn]-update CHANGELOG.md --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 872ba07..15f00b3 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -4,30 +4,30 @@ | 接口名 | 地址 | 是否支持 | 备注 | |----------------|------------------------|------|-------------------| -| 查询登录状态 | /loginStatus | √ | 已测试 | -| 获取登录微信内部识别号UID | /loginWeChatUid | √ | 已测试 | -| 获取登录微信信息 | /loginWeChatInfo | √ | 已测试 | -| 获取消息类型列表 | /list/msgType | √ | 已测试 | -| 获取联系人列表 | /list/contacts | √ | 已测试 | -| 获取数据库表名称列表 | /list/dbTableName | √ | 已测试 | -| 获取指定数据库中的表列表 | /list/dbTable | √ | 已测试 | -| 执行数据库查询SQL | /exec/dbQuerySql | √ | 已测试 | -| 发送消息汇总入口 | /send/msgMaster | x | 预留 | -| 发送文本消息 | /send/textMsg | x | 该版本不支持 | -| 发送富文本消息 | /send/richTextMsg | x | 缩略图参数需要为空,否则会发送失败 | -| 发送XML消息 | /send/xmlMsg | ? | 待测试 | -| 发送图片消息 | /send/imageMsg | √ | 已测试 | -| 发送表情消息 | /send/emojiMsg | x | 该版本不支持 | -| 发送文件消息 | /send/fileMsg | x | 该版本不支持 | -| 拍一拍群友 | /patOnePat | √ | 已测试 | -| 撤回消息 | /revokeMsg | ? | 待测试 | -| 通过好友申请 | /passFriendApply | ? | 待测试 | -| 添加群成员为微信好友 | /addFriend/groupMember | ? | 待测试 | -| 查询群成员 | /groupMember/list | √ | 已测试 | -| 邀请群成员 | /groupMember/invite | ? | 待测试 | -| 删除群成员 | /groupMember/delete | ? | 待测试 | -| 查询朋友圈 | /friendCircle | ? | 待测试 | -| 接收转账 | /receiveTransfer | ? | 待测试 | +| 查询登录状态 | /loginStatus | ✔️ | 已测试 | +| 获取登录微信内部识别号UID | /loginWeChatUid | ✔️ | 已测试 | +| 获取登录微信信息 | /loginWeChatInfo | ✔️ | 已测试 | +| 获取消息类型列表 | /list/msgType | ✔️ | 已测试 | +| 获取联系人列表 | /list/contacts | ✔️ | 已测试 | +| 获取数据库表名称列表 | /list/dbTableName | ✔️ | 已测试 | +| 获取指定数据库中的表列表 | /list/dbTable | ✔️ | 已测试 | +| 执行数据库查询SQL | /exec/dbQuerySql | ✔️ | 已测试 | +| 发送消息汇总入口 | /send/msgMaster | ❌ | 预留 | +| 发送文本消息 | /send/textMsg | ❌ | 该版本不支持 | +| 发送富文本消息 | /send/richTextMsg | ❌ | 缩略图参数需要为空,否则会发送失败 | +| 发送XML消息 | /send/xmlMsg | ❌ | 该版本不支持 | +| 发送图片消息 | /send/imageMsg | ✔️ | 已测试 | +| 发送表情消息 | /send/emojiMsg | ❌ | 该版本不支持 | +| 发送文件消息 | /send/fileMsg | ❌ | 该版本不支持 | +| 拍一拍群友 | /patOnePat | ✔️ | 已测试 | +| 撤回消息 | /revokeMsg | ❌ | 该版本不支持 | +| 通过好友申请 | /passFriendApply | ❌ | 该版本不支持 | +| 添加群成员为微信好友 | /addFriend/groupMember | ❔ | 待测试 | +| 查询群成员 | /groupMember/list | ✔️ | 已测试 | +| 邀请群成员 | /groupMember/invite | ❔ | 待测试 | +| 删除群成员 | /groupMember/delete | ❔ | 待测试 | +| 查询朋友圈 | /friendCircle | ❔ | 待测试 | +| 接收转账 | /receiveTransfer | ❌ | 该版本不支持 | ### 已知BUG From 72bf29eb9f105108603f05c90e50f7fce376d0fe Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Wed, 25 Dec 2024 20:33:38 +0800 Subject: [PATCH 09/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=BC=80=E5=90=AF=E5=BC=80=E5=85=B3=E6=94=AF=E6=8C=81?= =?UTF-8?q?ALL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wechat/ferry/service/impl/WeChatDllServiceImpl.java | 6 ++++-- .../com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) 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 f5f5600..dc41f2d 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 @@ -343,6 +343,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { if ("21".equals(request.getXmlType())) { // 小程序 xmlType = 0x21; + } else { + xmlType = Integer.parseInt(request.getXmlType()); } Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(request.getXmlContent()).setReceiver(request.getRecipient()) .setPath(request.getResourcePath()).setType(xmlType).build(); @@ -376,7 +378,6 @@ public class WeChatDllServiceImpl implements WeChatDllService { return null; } - @Deprecated @Override public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { long startTime = System.currentTimeMillis(); @@ -584,7 +585,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { public String queryFriendCircle() { long startTime = System.currentTimeMillis(); log.info("[查询]-[刷新朋友圈]-开始"); - Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REFRESH_PYQ_VALUE).build(); + // id 开始 id,0 为最新页 (string based uint64) + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REFRESH_PYQ_VALUE).setUi64(0).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); int state = judgeWcfCmdState(rsp); long endTime = System.currentTimeMillis(); diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java index 5fb9cc3..c268777 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/service/impl/WeChatMsgServiceImpl.java @@ -41,7 +41,7 @@ public class WeChatMsgServiceImpl implements WeChatMsgService { // 有开启的群聊配置 if (!CollectionUtils.isEmpty(weChatFerryProperties.getOpenMsgGroups())) { // 指定处理的群聊 - if (weChatFerryProperties.getOpenMsgGroups().contains(dto.getRoomId())) { + if (weChatFerryProperties.getOpenMsgGroups().contains(dto.getRoomId()) || weChatFerryProperties.getOpenMsgGroups().contains("ALL")) { // TODO 模式有多种 1-根据消息类型单独调用某一个 2-全部调用,各业务类中自己决定是否继续 if (true) { // 因为一种消息允许进行多种处理,这里采用执行所有策略,请自行在各策略中判断是否需要执行 From 711f77864e0bb33a2d42aed58578cd69cdc7b2b8 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Fri, 27 Dec 2024 00:23:54 +0800 Subject: [PATCH 10/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=BE=A4=E6=88=90=E5=91=98=E8=BF=94=E5=9B=9E=E7=B1=BB?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/vo/response/WxPpWcfGroupMemberResp.java | 12 ++++++++++++ .../ferry/service/impl/WeChatDllServiceImpl.java | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfGroupMemberResp.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfGroupMemberResp.java index 326e46d..cfa27a6 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfGroupMemberResp.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfGroupMemberResp.java @@ -33,4 +33,16 @@ public class WxPpWcfGroupMemberResp { @ApiModelProperty(value = "状态") private String state; + /** + * 是否自己 + */ + @ApiModelProperty(value = "是否自己") + private Boolean whetherSelf; + + /** + * 是否企微 + */ + @ApiModelProperty(value = "是否企微") + private Boolean whetherWork; + } 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 dc41f2d..b422b95 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 @@ -479,6 +479,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { public List queryGroupMemberList(WxPpWcfGroupMemberReq request) { long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); + String weChatUid = queryLoginWeChatUid(); // 查询群成员 List wcfList = new ArrayList<>(); if (!ObjectUtils.isEmpty(request.getGroupNo())) { @@ -523,6 +524,10 @@ public class WeChatDllServiceImpl implements WeChatDllService { for (Wcf.RoomData.RoomMember member : roomData.getMembersList()) { vo = new WxPpWcfGroupMemberResp(); vo.setWeChatUid(member.getWxid()); + // 是否为自己微信 + vo.setWhetherSelf(weChatUid.equals(member.getWxid())); + // 是否为企微 + vo.setWhetherWork(member.getWxid().endsWith(WxContactsTypeEnum.WORK.getAffix())); String nickName = member.getName(); if (ObjectUtils.isEmpty(nickName)) { // 如果没有设置群昵称则默认为微信名称 From d42b27568d60deba892ab59d90c1758bc4c3c00d Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Fri, 27 Dec 2024 00:24:51 +0800 Subject: [PATCH 11/18] =?UTF-8?q?docs:=20[java]-[mvn]-update=20CHANGELOG.m?= =?UTF-8?q?d=E5=92=8CREADME.MD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 63 ++++++++++++++++++- clients/java/wechat-ferry-mvn/README.MD | 41 ++++++++---- .../main/java/com/wechat/ferry/task/.gitkeep | 3 + 3 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/.gitkeep diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 15f00b3..e32710c 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -1,5 +1,14 @@ ## v39.3.3 +### 版本列表 + +下载地址:[v39.3.3](https://github.com/lich0821/WeChatFerry/releases/tag/v39.3.3) + +| 名称 | 版本 | 文件名 | +|-----------------|-----------|---------------------------| +| 微信客户端 | 3.9.11.25 | WeChatSetup-3.9.11.25.exe | +| WeChatFerry-SDK | 39.3.3 | v39.3.3.zip | + ### 功能列表 | 接口名 | 地址 | 是否支持 | 备注 | @@ -13,7 +22,7 @@ | 获取指定数据库中的表列表 | /list/dbTable | ✔️ | 已测试 | | 执行数据库查询SQL | /exec/dbQuerySql | ✔️ | 已测试 | | 发送消息汇总入口 | /send/msgMaster | ❌ | 预留 | -| 发送文本消息 | /send/textMsg | ❌ | 该版本不支持 | +| 发送文本消息 | /send/textMsg | ✔️ | 已测试 | | 发送富文本消息 | /send/richTextMsg | ❌ | 缩略图参数需要为空,否则会发送失败 | | 发送XML消息 | /send/xmlMsg | ❌ | 该版本不支持 | | 发送图片消息 | /send/imageMsg | ✔️ | 已测试 | @@ -67,4 +76,54 @@ - 适配SDK39.3.3版本 - wcf.proto文件部分字段类型修改 -- 消息转发适配多种消息类型 \ No newline at end of file +- 消息转发适配多种消息类型 + +
+ +___ + +

+ +## v39.2.4 - 推荐✨ + +### 版本列表 + +下载地址:[v39.2.4](https://github.com/lich0821/WeChatFerry/releases/tag/v39.2.4) + +| 名称 | 版本 | 文件名 | +|-----------------|-----------|---------------------------| +| 微信客户端 | 3.9.10.27 | WeChatSetup-3.9.10.27.exe | +| WeChatFerry-SDK | 39.2.4 | v39.2.4.zip | + +### 功能列表 + +| 接口名 | 地址 | 是否支持 | 备注 | +|----------------|------------------------|------|--------| +| 查询登录状态 | /loginStatus | ✔️ | 已测试 | +| 获取登录微信内部识别号UID | /loginWeChatUid | ✔️ | 已测试 | +| 获取登录微信信息 | /loginWeChatInfo | ✔️ | 已测试 | +| 获取消息类型列表 | /list/msgType | ✔️ | 已测试 | +| 获取联系人列表 | /list/contacts | ✔️ | 已测试 | +| 获取数据库表名称列表 | /list/dbTableName | ✔️ | 已测试 | +| 获取指定数据库中的表列表 | /list/dbTable | ✔️ | 已测试 | +| 执行数据库查询SQL | /exec/dbQuerySql | ✔️ | 已测试 | +| 发送消息汇总入口 | /send/msgMaster | ❌ | 预留 | +| 发送文本消息 | /send/textMsg | ✔️ | 已测试 | +| 发送富文本消息 | /send/richTextMsg | ✔️ | 已测试 | +| 发送XML消息 | /send/xmlMsg | ❌ | 该版本不支持 | +| 发送图片消息 | /send/imageMsg | ✔️ | 已测试 | +| 发送表情消息 | /send/emojiMsg | ✔️ | 已测试 | +| 发送文件消息 | /send/fileMsg | ✔️ | 已测试 | +| 拍一拍群友 | /patOnePat | ✔️ | 已测试 | +| 撤回消息 | /revokeMsg | ❌ | 该版本不支持 | +| 通过好友申请 | /passFriendApply | ❌ | 该版本不支持 | +| 添加群成员为微信好友 | /addFriend/groupMember | ❔ | 待测试 | +| 查询群成员 | /groupMember/list | ✔️ | 已测试 | +| 邀请群成员 | /groupMember/invite | ❔ | 待测试 | +| 删除群成员 | /groupMember/delete | ❔ | 待测试 | +| 查询朋友圈 | /friendCircle | ❔ | 待测试 | +| 接收转账 | /receiveTransfer | ❌ | 该版本不支持 | + +
+ +___ \ No newline at end of file diff --git a/clients/java/wechat-ferry-mvn/README.MD b/clients/java/wechat-ferry-mvn/README.MD index 9fd296b..9822992 100644 --- a/clients/java/wechat-ferry-mvn/README.MD +++ b/clients/java/wechat-ferry-mvn/README.MD @@ -13,7 +13,7 @@ |-----------------|-----------|----| | JDK | 1.8+ | √ | | Maven | 3.8+ | √ | -| 微信 | 3.9.11.25 | √ | +| 微信客户端 | 3.9.11.25 | √ | | WeChatFerry-SDK | 39.3.3 | √ | | MySQL | 8.0+ | 备用 | @@ -35,6 +35,15 @@ 把刚下载的最新发布文件解压到本项目中的 dll 文件目录下,直接替换原因文件即可 +替换 `clients/java/wechat-ferry-mvn/dll` 目录下(也可以在配置文件中改为自定义的目录) + +- sdk.dll +- spy.dll +- spy_debug.dll + +> 如果之前已经使用本项目启动过微信,此时替换发现替换不了,是因为正则运行的微信客户端正在使用该文件, +> 请退出并关闭微信客户端之后再进行替换 + ### 修改配置文件 配置文件:src/main/resources/application.yml @@ -71,15 +80,17 @@ swagger地址:http://localhost:9201/swagger-ui/index.html ### 核心依赖 -| 依赖 | 版本 | 说明 | -|---------------|--------|----------| -| Spring Boot | 2.7.18 | 基础框架 | -| protobuf-java | 3.22.2 | rpc | -| jna | 5.6.0 | 态访问系统本地库 | -| nng-java | 1.4.0 | 本地包 | -| fastjson2 | 2.0.52 | 序列化 | -| dom4j | 2.1.3 | XML解析包 | -| httpclient | 4.5.13 | 客户端请求 | +| 依赖 | 版本 | 说明 | +|---------------|-------------|----------| +| Spring Boot | 2.7.18 | 基础框架 | +| protobuf-java | 3.22.2 | rpc | +| jna | 5.6.0 | 态访问系统本地库 | +| nng-java | 1.4.0 | 本地包 | +| fastjson2 | 2.0.52 | 序列化 | +| dom4j | 2.1.3 | XML解析包 | +| httpclient | 4.5.13 | 客户端请求 | +| validation | 2.0.1.Final | 参数校验 | +| springfox | 3.0.0 | swagger3 | ### 模块结构 @@ -93,16 +104,22 @@ wechat-ferry-mvn │ ├─main 重启命令 │ │ ├─java(com.wechat.ferry) java代码目录 │ │ │ ├─config 配置 +│ │ │ ├─constant 常量 +│ │ │ ├─controller 控制层(API接口) │ │ │ ├─entity 聚合模型 │ │ │ │ ├─dto DTO模型 │ │ │ │ ├─po 数据库实体(与表结构一一对应,否则请使用DTO) │ │ │ │ ├─proto PB实体 │ │ │ │ └─vo 视图层返回体目录 │ │ │ ├─enums 枚举 +│ │ │ ├─exception 异常封装 │ │ │ ├─handle 处理层 -│ │ │ ├─service 业务接口 +│ │ │ ├─service 业务层 │ │ │ │ └─impl 业务实现类 -│ │ │ ├─utils 工具类 +│ │ │ ├─strategy 策略层 +│ │ │ │ └─impl 策略实现类(如接收到消息之后的事件处理可以放在这里) +│ │ │ ├─task 定时任务 +│ │ │ ├─utils 工具层 │ │ │ └─WcferryApplication.java 启动类 │ │ │ │ │ │resources 资源目录 diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/.gitkeep b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file From 488eb5812286849e9c82584f285b72bf51befa77 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Fri, 27 Dec 2024 09:10:09 +0800 Subject: [PATCH 12/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=80=80=E7=BE=A4=E7=9B=91=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 8 ++ .../ferry/task/LeaveGroupMonitorTask.java | 92 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index e32710c..239b55e 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -44,6 +44,14 @@ - 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复` - 3.发送文件成功之后客户端崩溃 - `待修复` +### 2024-12-27 + +#### ⛰️ Features + +- 查询群成员返回类新增字段 +- 新增退群监测功能 +- 说明文档更新 + ### 2024-12-25 #### ⛰️ Features 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 new file mode 100644 index 0000000..51e7dea --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/task/LeaveGroupMonitorTask.java @@ -0,0 +1,92 @@ +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("[定时任务]-[重置签到]-结束"); + } + +} From 571d722d94e2168b78e6e7e5ce49b95d4b6acd67 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Fri, 27 Dec 2024 11:25:03 +0800 Subject: [PATCH 13/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-1.=E6=9C=AC?= =?UTF-8?q?=E6=9C=BA=E6=B6=88=E6=81=AF=E5=9B=9E=E8=B0=83=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D=E4=BF=AE=E6=94=B9=202.=E5=85=AC=E5=85=B1=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E6=8F=90=E5=8F=96=E8=87=B3SocketClient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ferry/config/WeChatConfiguration.java | 2 +- .../ferry/handle/WeChatSocketClient.java | 60 ++++++++++++++++++- .../service/impl/WeChatDllServiceImpl.java | 50 +--------------- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatConfiguration.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatConfiguration.java index 2e9b673..7564627 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatConfiguration.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/config/WeChatConfiguration.java @@ -81,7 +81,7 @@ public class WeChatConfiguration { // 只打印 // wechatSocketClient.printWxMsg(wechatSocketClient.getMsg()); // 转发到boot项目进行消息处理 - wechatSocketClient.forwardMsg(wechatSocketClient.getMsg(), url); + wechatSocketClient.localCallbackAnalyzeMsg(wechatSocketClient.getMsg(), url); } } }); diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java index d707dba..91ad36c 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java @@ -1,14 +1,19 @@ package com.wechat.ferry.handle; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import java.util.function.Function; import org.springframework.util.ObjectUtils; import com.alibaba.fastjson2.JSONObject; +import com.google.protobuf.ByteString; import com.sun.jna.Native; import com.wechat.ferry.entity.dto.WxPpMsgDTO; import com.wechat.ferry.entity.proto.Wcf.DbQuery; @@ -310,7 +315,16 @@ public class WeChatSocketClient { } } - public void forwardMsg(WxMsg msg, String url) { + /** + * 本机回调解析消息 + * + * @param msg 消息内容 + * @param url 回调地址 + * + * @author chandler + * @date 2024-10-05 12:50 + */ + public void localCallbackAnalyzeMsg(WxMsg msg, String url) { String xml = msg.getXml(); xml = xml.replaceAll(">[\\s\\p{Zs}]*<", "><"); String content = msg.getContent(); @@ -358,10 +372,50 @@ public class WeChatSocketClient { try { String responseStr = HttpClientUtil.doPostJson(url, jsonString); if (!JSONObject.parseObject(responseStr).getString("code").equals("200")) { - log.error("本机消息转发失败!-URL:{}", url); + log.error("本机消息回调失败!-URL:{}", url); } } catch (Exception e) { - log.error("转发接口报错:", e); + log.error("本机消息回调接口报错:", e); + } + } + + /** + * 获取SQL类型 + * + * @param type 转换类型 + * @return 函数 + * + * @author chandler + * @date 2024-10-05 12:54 + */ + public Function getSqlType(int type) { + Map> sqlTypeMap = new HashMap<>(); + // 初始化SQL_TYPES 根据类型执行不同的Func + sqlTypeMap.put(1, bytes -> ByteBuffer.wrap(bytes).getInt()); + sqlTypeMap.put(2, bytes -> ByteBuffer.wrap(bytes).getFloat()); + sqlTypeMap.put(3, bytes -> new String(bytes, StandardCharsets.UTF_8)); + sqlTypeMap.put(4, bytes -> bytes); + sqlTypeMap.put(5, bytes -> null); + return sqlTypeMap.get(type); + } + + /** + * SQL转换类型 + * + * @param type 转换类型 + * @param content 待转换内容 + * + * @author chandler + * @date 2024-10-05 12:54 + */ + public Object convertSqlVal(int type, ByteString content) { + // 根据每一列的类型转换 + Function converter = getSqlType(type); + if (converter != null) { + return converter.apply(content.toByteArray()); + } else { + log.warn("[SQL转换类型]-未知的SQL类型: {}", type); + return content.toByteArray(); } } 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 b422b95..1eee7fb 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 @@ -1,12 +1,9 @@ package com.wechat.ferry.service.impl; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import javax.annotation.Resource; @@ -17,7 +14,6 @@ import org.springframework.util.ObjectUtils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.wechat.ferry.config.WeChatFerryProperties; import com.wechat.ferry.entity.proto.Wcf; @@ -272,7 +268,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { log.warn("未知的SQL类型: {}", dbField.getType()); value = dbField.getContent().toByteArray(); } else { - value = convertSqlVal(dbField.getType(), dbField.getContent()); + value = wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); } fieldVo.setType(String.valueOf(dbField.getType())); fieldVo.setColumn(dbField.getColumn()); @@ -497,11 +493,11 @@ public class WeChatDllServiceImpl implements WeChatDllService { for (Wcf.DbField dbField : dbFieldList) { if ("UserName".equals(dbField.getColumn())) { vo = new WxPpWcfGroupMemberResp(); - String content = (String)convertSqlVal(dbField.getType(), dbField.getContent()); + String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); vo.setWeChatUid(content); } if ("NickName".equals(dbField.getColumn())) { - String content = (String)convertSqlVal(dbField.getType(), dbField.getContent()); + String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); vo.setGroupNickName(content); dbMap.put(vo.getWeChatUid(), vo.getGroupNickName()); } @@ -613,46 +609,6 @@ public class WeChatDllServiceImpl implements WeChatDllService { return ""; } - /** - * 获取SQL类型 - * - * @param type 转换类型 - * @return 函数 - * - * @author chandler - * @date 2024-10-05 12:54 - */ - public Function getSqlType(int type) { - Map> sqlTypeMap = new HashMap<>(); - // 初始化SQL_TYPES 根据类型执行不同的Func - sqlTypeMap.put(1, bytes -> ByteBuffer.wrap(bytes).getInt()); - sqlTypeMap.put(2, bytes -> ByteBuffer.wrap(bytes).getFloat()); - sqlTypeMap.put(3, bytes -> new String(bytes, StandardCharsets.UTF_8)); - sqlTypeMap.put(4, bytes -> bytes); - sqlTypeMap.put(5, bytes -> null); - return sqlTypeMap.get(type); - } - - /** - * SQL转换类型 - * - * @param type 转换类型 - * @param content 待转换内容 - * - * @author chandler - * @date 2024-10-05 12:54 - */ - public Object convertSqlVal(int type, ByteString content) { - // 根据每一列的类型转换 - Function converter = getSqlType(type); - if (converter != null) { - return converter.apply(content.toByteArray()); - } else { - log.warn("[SQL转换类型]-未知的SQL类型: {}", type); - return content.toByteArray(); - } - } - /** * 转换艾特用户 * 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 14/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E8=81=94?= =?UTF-8?q?=E7=B3=BB=E4=BA=BA=E7=BE=A4=E7=BB=84=E7=9B=91=E6=8E=A7=E9=80=BB?= =?UTF-8?q?=E8=BE=91=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("[定时任务]-[重置签到]-结束"); - } - -} From 3d641826a104bb1355d2c18e91a1cb6a34a0ed9e Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Sat, 4 Jan 2025 18:52:01 +0800 Subject: [PATCH 15/18] =?UTF-8?q?feat(0):=20[java]-[mvn]-=E8=81=94?= =?UTF-8?q?=E7=B3=BB=E4=BA=BA=E7=BE=A4=E7=BB=84=E7=9B=91=E6=8E=A7=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ferry/aggregation/facade/ContactDo.java | 17 ++-- .../wechat/ferry/entity/po/wcf/Contact.java | 6 -- .../ferry/handle/WeChatSocketClient.java | 2 +- .../ferry/task/ContactGroupMonitorTask.java | 85 ++++++++++++------- 4 files changed, 65 insertions(+), 45 deletions(-) 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 index de13658..bfb43d2 100644 --- 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 @@ -43,6 +43,13 @@ public class ContactDo extends Contact { @ApiModelProperty(value = "联系人类型") private String contactType; + /** + * 展示名称 + * 有备注优先展示备注 + */ + @ApiModelProperty(value = "展示名称") + private String showName; + /** * 根据自定义SQL查询联系人列表 * @@ -56,14 +63,13 @@ public class ContactDo extends Contact { 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;"); + "SELECT UserName, Alias, DelFlag, Type, VerifyFlag, Remark, NickName, LabelIDList, DomainList, ChatRoomType, PYInitial, QuanPin, RemarkPYInitial, RemarkQuanPin, ChatRoomNotify FROM Contact;"); if (!CollectionUtils.isEmpty(dbContactList)) { for (Wcf.DbRow dbRow : dbContactList) { List dbFieldList = dbRow.getFieldsList(); if (!ObjectUtils.isEmpty(dbFieldList)) { - ContactDo po; + ContactDo po = new ContactDo(); for (Wcf.DbField dbField : dbFieldList) { - po = new ContactDo(); String content = (String)wechatSocketClient.convertSqlVal(dbField.getType(), dbField.getContent()); // 用户名 if ("UserName".equals(dbField.getColumn())) { @@ -105,11 +111,8 @@ public class ContactDo extends Contact { if ("ChatRoomType".equals(dbField.getColumn())) { po.setChatRoomType(Integer.valueOf(content)); } - // - if ("HeadImgMd5".equals(dbField.getColumn())) { - po.setHeadImgMd5(content); - } } + list.add(po); } } } 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 index fa18dab..bc1f1ef 100644 --- 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 @@ -68,10 +68,4 @@ public class Contact { @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/handle/WeChatSocketClient.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java index 91ad36c..46eb503 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java @@ -391,7 +391,7 @@ public class WeChatSocketClient { public Function getSqlType(int type) { Map> sqlTypeMap = new HashMap<>(); // 初始化SQL_TYPES 根据类型执行不同的Func - sqlTypeMap.put(1, bytes -> ByteBuffer.wrap(bytes).getInt()); + sqlTypeMap.put(1, bytes -> new String(bytes, StandardCharsets.UTF_8)); sqlTypeMap.put(2, bytes -> ByteBuffer.wrap(bytes).getFloat()); sqlTypeMap.put(3, bytes -> new String(bytes, StandardCharsets.UTF_8)); sqlTypeMap.put(4, bytes -> bytes); 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 index 537021c..897d107 100644 --- 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 @@ -14,7 +14,6 @@ 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; @@ -60,19 +59,23 @@ public class ContactGroupMonitorTask { private final Map> groupMemberMap = new HashMap<>(); /** - * 初始化标志 + * 初始化状态 */ - private Boolean initFlag = false; + private Boolean initStatus = false; - @Scheduled(cron = "0 0/2 * * * ?") + @Scheduled(cron = "0 0 0 * * ?") public void scheduled() { + if (true) { + // 目前查询的所有的联系人,未判断群组是否已退出等状态,故该功能暂不启用,仅提供一个小样例 + return; + } ContactDo contactDo = new ContactDo(); // 查询联系人 List contactList = contactDo.queryContactListBySql(wechatSocketClient, weChatFerryProperties); + log.info("[定时任务]-[联系人群组监控]-{}", contactList.size()); // 调用联系人监控处理 contactMonitor(contactList); - initFlag = true; - log.info("[定时任务]-[重置签到]-结束"); + log.info("[定时任务]-[联系人群组监控]-结束"); } // 联系人监控 @@ -89,14 +92,18 @@ public class ContactGroupMonitorTask { List addGroupList = new ArrayList<>(); // 退出群组 List deleteGroupList = new ArrayList<>(); - // 本次的联系人标识列表 - List nowContactIdList = new ArrayList<>(); + // 本次个微联系人标识列表 + List nowPpContactIdList = new ArrayList<>(); + // 本次企微联系人标识列表 + List nowCpContactIdList = new ArrayList<>(); + // 本次群组标识列表 + List nowGroupIdList = new ArrayList<>(); // 开始匹配 if (!CollectionUtils.isEmpty(contactList)) { - for (ContactDo contactDo : contactList) { - nowContactIdList.add(contactDo.getWeChatUid()); - if (!initFlag) { + // 判断全部联系人是否为空 + if (allContactDoMap.isEmpty()) { + for (ContactDo contactDo : contactList) { // 首次初始化 allContactDoMap.put(contactDo.getWeChatUid(), contactDo); if (WxContactsTypeEnum.PERSON.getCode().equals(contactDo.getContactType())) { @@ -109,52 +116,68 @@ public class ContactGroupMonitorTask { // 群组-初始化 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()); + } + log.info("[定时任务]-[联系人监控]-首次初始化成功"); + } else { + // 检测新增联系人 + for (ContactDo contactDo : contactList) { + if (WxContactsTypeEnum.PERSON.getCode().equals(contactDo.getContactType())) { + // 个微 + nowPpContactIdList.add(contactDo.getWeChatUid()); + if (!ppContactDoMap.containsKey(contactDo.getWeChatUid())) { + // 个微-新增 + addPpContactList.add(contactDo.getWeChatUid()); + ppContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } + } else if (WxContactsTypeEnum.WORK.getCode().equals(contactDo.getContactType())) { + // 企业微信 + nowCpContactIdList.add(contactDo.getWeChatUid()); + if (!cpContactDoMap.containsKey(contactDo.getWeChatUid())) { + // 企业微信-新增 + addCpContactList.add(contactDo.getWeChatUid()); + cpContactDoMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } + } else if (WxContactsTypeEnum.GROUP.getCode().equals(contactDo.getContactType())) { + // 群组 + nowGroupIdList.add(contactDo.getWeChatUid()); + if (!groupMap.containsKey(contactDo.getWeChatUid())) { + // 群组-新增 + addGroupList.add(contactDo.getWeChatUid()); + groupMap.put(contactDo.getWeChatUid(), contactDo.getNickname()); + } } } } // 初始化完成 - if (initFlag) { + if (initStatus) { // 个微 for (Map.Entry entry : ppContactDoMap.entrySet()) { - if (!nowContactIdList.contains(entry.getKey())) { + if (!nowPpContactIdList.contains(entry.getKey())) { // 个微-删除 deletePpContactList.add(entry.getKey()); } } // 企微 for (Map.Entry entry : cpContactDoMap.entrySet()) { - if (!nowContactIdList.contains(entry.getKey())) { + if (!nowCpContactIdList.contains(entry.getKey())) { // 企微-删除 deleteCpContactList.add(entry.getKey()); } } // 群组 for (Map.Entry entry : groupMap.entrySet()) { - if (!nowContactIdList.contains(entry.getKey())) { + if (!nowGroupIdList.contains(entry.getKey())) { // 群组-删除 deleteGroupList.add(entry.getKey()); log.info("\"{}\"离开了群聊"); } } + log.info("[定时任务]-[联系人监控]-个微新增:{},个微删除:{},企微新增:{},企微删除:{},群组新增:{},群组删除:{}", addPpContactList, deletePpContactList, addCpContactList, + deleteCpContactList, addGroupList, deleteGroupList); } } - log.info("[定时任务]-[联系人监控]-个微新增:{},个微删除:{},企微新增:{},企微删除:{},群组新增:{},群组删除:{}", addPpContactList, deletePpContactList, addCpContactList, - deleteCpContactList, addGroupList, deleteGroupList); + initStatus = true; } // 监控群成员 From d06ea829ace2ecf5b977ba6a38ac069f4a7d845f Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Sat, 4 Jan 2025 18:54:04 +0800 Subject: [PATCH 16/18] =?UTF-8?q?fix(300):=20[java]-[mvn]-=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=AE=A2=E6=88=B7=E7=AB=AF=E9=80=80=E5=87=BA=E5=90=8E?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E6=8E=A5=E5=8F=A3=E6=97=B6=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=8A=B6=E6=80=81=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=EF=BC=8C=E8=BF=94=E5=9B=9E=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/WeChatDllServiceImpl.java | 80 ++++++++++++++----- 1 file changed, 59 insertions(+), 21 deletions(-) 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 da0c5e0..b9e7ca8 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 @@ -52,6 +52,7 @@ import com.wechat.ferry.enums.DatabaseNameEnum; import com.wechat.ferry.enums.MsgCallbackTypeEnum; import com.wechat.ferry.enums.SexEnum; import com.wechat.ferry.enums.WxContactsTypeEnum; +import com.wechat.ferry.exception.BizException; import com.wechat.ferry.handle.WeChatSocketClient; import com.wechat.ferry.service.WeChatDllService; import com.wechat.ferry.utils.HttpClientUtil; @@ -81,6 +82,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public Boolean loginStatus() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); Boolean status = wechatSocketClient.isLogin(); long endTime = System.currentTimeMillis(); log.info("[查询]-[登录状态]-耗时:{}ms,status:{}", (endTime - startTime), status); @@ -90,6 +93,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String queryLoginWeChatUid() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); String weChatUid = ""; Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_SELF_WXID_VALUE).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -104,6 +109,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfLoginInfoResp queryLoginWeChatInfo() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); WxPpWcfLoginInfoResp resp = new WxPpWcfLoginInfoResp(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_USER_INFO_VALUE).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -122,6 +129,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List queryMsgTypeList() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); List list = new ArrayList<>(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_MSG_TYPES_VALUE).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -143,6 +152,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List queryContactsList() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); List list = new ArrayList<>(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_CONTACTS_VALUE).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -190,6 +201,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List queryDbTableNameList() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); List list = new ArrayList<>(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_DB_NAMES_VALUE).build(); Wcf.Response rsp = wechatSocketClient.sendCmd(req); @@ -204,6 +217,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List queryDbTableList(WxPpWcfDatabaseTableReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[查询]-[数据库表列表]-request:{}", request); List list = new ArrayList<>(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_DB_TABLES_VALUE).setStr(request.getDatabaseName()).build(); @@ -225,6 +240,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List execDbQuerySql(WxPpWcfDatabaseSqlReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); List list = new ArrayList<>(); List wcfList = wechatSocketClient.querySql(request.getDatabaseName(), request.getSqlText()); if (!CollectionUtils.isEmpty(wcfList)) { @@ -257,6 +274,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[文本消息]-入参打印:{}", request); String atUser = ""; if (request.getIsAtAll()) { @@ -285,6 +304,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[富文本消息]-入参打印:{}", request); Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle()) .setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient()) @@ -304,6 +325,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[XML消息]-入参打印:{}", request); int xmlType = 0x21; if ("21".equals(request.getXmlType())) { @@ -329,6 +352,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[图片消息]-入参打印:{}", request); WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); @@ -347,6 +372,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[表情消息]-入参打印:{}", request); Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); @@ -364,6 +391,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[文件消息]-入参打印:{}", request); Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); @@ -381,6 +410,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[发送消息]-[拍一拍消息]-入参打印:{}", request); Wcf.PatMsg patMsg = Wcf.PatMsg.newBuilder().setRoomid(request.getRecipient()).setWxid(request.getPatUser()).build(); Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build(); @@ -397,6 +428,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String revokeMsg(WxPpWcfRevokeMsgReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[撤回消息]-[消息撤回]-入参打印:{}", request); long msgId = Long.parseLong(request.getMsgId()); Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REVOKE_MSG_VALUE).setUi64(msgId).build(); @@ -413,6 +446,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String passFriendApply(WxPpWcfPassFriendApplyReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[好友申请]-[通过好友申请]-入参打印:{}", request); Wcf.Verification verification = Wcf.Verification.newBuilder().setV3(request.getApplicant()).setV4(request.getReviewer()).build(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_ACCEPT_FRIEND_VALUE).setV(verification).build(); @@ -426,6 +461,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String addFriendGroupMember(WxPpWcfAddFriendGroupMemberReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[添加好友]-[添加群成员为好友]-入参打印:{}", request); if (CollectionUtils.isEmpty(request.getGroupMembers())) { log.error("[添加好友]-[添加群成员为好友]-待添加人员为空,本次操作取消"); @@ -444,6 +481,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public List queryGroupMemberList(WxPpWcfGroupMemberReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); List list = new ArrayList<>(); String weChatUid = queryLoginWeChatUid(); // 查询群成员 @@ -519,6 +558,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String inviteGroupMember(WxPpWcfInviteGroupMemberReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[群成员]-[邀请群成员加入]-入参打印:{}", request); if (CollectionUtils.isEmpty(request.getGroupMembers())) { log.error("[群成员]-[邀请群成员加入]-待邀请进群的人员为空,本次操作取消"); @@ -537,6 +578,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String deleteGroupMember(WxPpWcfDeleteGroupMemberReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[群成员]-[删除群成员]-入参打印:{}", request); if (CollectionUtils.isEmpty(request.getGroupMembers())) { log.error("[群成员]-[删除群成员]-待删除的人员为空,本次操作取消"); @@ -555,6 +598,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String queryFriendCircle() { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[查询]-[刷新朋友圈]-开始"); // id 开始 id,0 为最新页 (string based uint64) Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_REFRESH_PYQ_VALUE).setUi64(0).build(); @@ -568,6 +613,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public String receiveTransfer(WxPpWcfReceiveTransferReq request) { long startTime = System.currentTimeMillis(); + // 公共校验 + checkClientStatus(); log.info("[转账]-[接收转账]-开始"); Wcf.Transfer transfer = Wcf.Transfer.newBuilder().setWxid(request.getWeChatUid()).setTfid(request.getTransferId()).setTaid(request.getTransferId()).build(); @@ -579,27 +626,6 @@ public class WeChatDllServiceImpl implements WeChatDllService { return ""; } - /** - * 转换艾特用户 - * - * @param groupNo 群组编号 - * @param atUsers 艾特的用户(名称/微信编号) - * @return 组装后的艾特用户 - * - * @author chandler - * @date 2024-10-03 11:35 - */ - public String dealAtUser(String groupNo, List atUsers) { - String atUserStr = ""; - if (!CollectionUtils.isEmpty(atUsers)) { - // 取出要艾特的用户 - for (String atUser : atUsers) { - - } - } - return atUserStr; - } - /** * 消息回调 * @@ -708,4 +734,16 @@ public class WeChatDllServiceImpl implements WeChatDllService { return map; } + /** + * 请求前检测客户端状态 + * + * @author chandler + * @date 2025-01-04 18:34 + */ + private void checkClientStatus() { + if (!wechatSocketClient.isLogin()) { + throw new BizException("微信客户端未登录或状态异常,请人工关闭本服务之后,退出微信客户端在重启本服务!"); + } + } + } From 2235b1c914acbc246f3612f126bd020dbe9666b7 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Sat, 4 Jan 2025 19:00:02 +0800 Subject: [PATCH 17/18] docs: [java]-[mvn]-update CHANGELOG.md --- clients/java/wechat-ferry-mvn/CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 239b55e..e5a9227 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -44,6 +44,16 @@ - 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复` - 3.发送文件成功之后客户端崩溃 - `待修复` +### 2025-01-04 + +#### ⛰️ Features + +- 退群监测功能关闭,待完善,目前未开启 +- 说明文档更新 + +#### 🐛 Bug fixes +- 微信端退出之后,调用接口返回客户端状态异常提示 + ### 2024-12-27 #### ⛰️ Features From d2d49774136502f86d097de6952dbd3e23dea259 Mon Sep 17 00:00:00 2001 From: chandler <1915724901@qq.com> Date: Sat, 4 Jan 2025 20:16:00 +0800 Subject: [PATCH 18/18] =?UTF-8?q?docs:=20[java]-[mvn]-=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wechat/ferry/handle/WeChatSocketClient.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java index 46eb503..55829c1 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/handle/WeChatSocketClient.java @@ -23,6 +23,7 @@ import com.wechat.ferry.entity.proto.Wcf.Functions; import com.wechat.ferry.entity.proto.Wcf.Request; import com.wechat.ferry.entity.proto.Wcf.Response; import com.wechat.ferry.entity.proto.Wcf.WxMsg; +import com.wechat.ferry.exception.BizException; import com.wechat.ferry.service.SDK; import com.wechat.ferry.utils.HttpClientUtil; import com.wechat.ferry.utils.XmlJsonConvertUtil; @@ -120,14 +121,21 @@ public class WeChatSocketClient { public Response sendCmd(Request req) { try { + // 设置超时时间 20s + cmdSocket.setSendTimeout(20000); ByteBuffer bb = ByteBuffer.wrap(req.toByteArray()); cmdSocket.send(bb); ByteBuffer ret = ByteBuffer.allocate(BUFFER_SIZE); long size = cmdSocket.receive(ret, true); return Response.parseFrom(Arrays.copyOfRange(ret.array(), 0, (int)size)); } catch (Exception e) { - log.error("命令调用失败: ", e); - return null; + if ("Timed out".equals(e.getMessage())) { + log.error("请求超时: ", e); + throw new BizException("请求超时:1.接口耗时太长,2.服务与客户端失去联系,请重启本服务!详细异常信息:" + e.getMessage()); + } else { + log.error("命令调用失败: ", e); + throw new BizException("命令调用失败:" + e.getMessage()); + } } }