diff --git a/clients/java/wechat-ferry-mvn/CHANGELOG.md b/clients/java/wechat-ferry-mvn/CHANGELOG.md index 16889ee..cf6c553 100644 --- a/clients/java/wechat-ferry-mvn/CHANGELOG.md +++ b/clients/java/wechat-ferry-mvn/CHANGELOG.md @@ -1,10 +1,43 @@ ## v39.3.3 +### 功能列表 + +| 接口名 | 地址 | 是否支持 | 备注 | +|----------------|-------------------|------|-------------------| +| 查询登录状态 | /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 | √ | 已测试 | + ### 已知BUG - 1.发送表情微信客户端闪退 - `待修复` - 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复` +### 2024-12-24 + +#### ⛰️ Features + +- 执行数据库查询SQL请求接口API地址修改 +- 业务代码迁移至业务类中,并补充日志信息 +- 联系人特殊类型支持配置文件自定义 +- 接口入参新增为空校验 +- 说明文档更新 +- 配置文件有更新 + ### 2024-12-23 #### ⛰️ Features diff --git a/clients/java/wechat-ferry-mvn/pom.xml b/clients/java/wechat-ferry-mvn/pom.xml index 0ef4844..2b2e584 100644 --- a/clients/java/wechat-ferry-mvn/pom.xml +++ b/clients/java/wechat-ferry-mvn/pom.xml @@ -53,6 +53,11 @@ 1.18.30 provided + + + javax.validation + validation-api + io.springfox 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 b2bf852..2e9b673 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 @@ -48,7 +48,7 @@ public class WeChatConfiguration { // client.printContacts(client.getContacts()); // 获取数据库 - log.info("dbs: {}", wechatSocketClient.getDbNames()); + // log.info("dbs: {}", wechatSocketClient.getDbNames()); // 获取数据库下的表 String db = "MicroMsg.db"; 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 32e0578..46893a9 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 @@ -29,6 +29,18 @@ public class WeChatFerryProperties { */ private Integer socketPort; + /** + * 联系人类型-官方杂号,禁止与其他分类重复(格式:代码|名称) + * 使用时记得需要提取代码或者名称匹配 + */ + private List contactsTypeMixed; + + /** + * 联系人类型-公众号,禁止与其他分类重复(格式:代码|名称) + * 使用时记得需要提取代码或者名称匹配 + */ + private List contactsTypeOfficial; + /** * 需要开启消息处理的群 */ 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 c52f92a..e52f160 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 @@ -22,6 +22,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfSendTextMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; +import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; @@ -79,46 +80,40 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); } - @ApiOperation(value = "获取消息类型", notes = "queryMsgTypeList") + @ApiOperation(value = "获取消息类型列表", notes = "queryMsgTypeList") @PostMapping(value = "/list/msgType") public TResponse> queryMsgTypeList() { List list = weChatDllService.queryMsgTypeList(); return TResponse.ok(ResponseCodeEnum.SUCCESS, list); } - @ApiOperation(value = "获取联系人", notes = "queryContactsList") + @ApiOperation(value = "获取联系人列表", notes = "queryContactsList") @PostMapping(value = "/list/contacts") public TResponse> queryContactsList() { List list = weChatDllService.queryContactsList(); return TResponse.ok(ResponseCodeEnum.SUCCESS, list); } - @ApiOperation(value = "获取数据库所有表名称", notes = "queryDatabaseAllTableName") + @ApiOperation(value = "获取数据库表名称列表", notes = "queryDbTableNameList") @PostMapping(value = "/list/dbTableName") - public TResponse> queryDatabaseAllTableName() { - List list = weChatDllService.queryDatabaseAllTableName(); + public TResponse> queryDbTableNameList() { + List list = weChatDllService.queryDbTableNameList(); return TResponse.ok(ResponseCodeEnum.SUCCESS, list); } - @ApiOperation(value = "获取可查询数据库", notes = "queryDatabaseSql") - @PostMapping(value = "/list/dbSql") - public TResponse> queryDatabaseSql(@Validated @RequestBody WxPpWcfDatabaseSqlReq request) { - List list = weChatDllService.queryDatabaseSql(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - } - - @ApiOperation(value = "获取指定数据库中的表", notes = "queryDatabaseTable") + @ApiOperation(value = "获取指定数据库中的表列表", notes = "queryDbTableList") @PostMapping(value = "/list/dbTable") - public TResponse> queryDatabaseTable(@Validated @RequestBody WxPpWcfDatabaseTableReq request) { - List list = weChatDllService.queryDatabaseTable(request); + public TResponse> queryDbTableList(@Validated @RequestBody WxPpWcfDatabaseTableReq request) { + List list = weChatDllService.queryDbTableList(request); return TResponse.ok(ResponseCodeEnum.SUCCESS, list); } - // @ApiOperation(value = "获取语音消息", notes = "queryMsgTypeList") - // @PostMapping(value = "/list/voiceMsg") - // public TResponse queryVoiceMsg() { - // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); - // } + @ApiOperation(value = "执行数据库查询SQL", notes = "execDbQuerySql") + @PostMapping(value = "/exec/dbQuerySql") + public TResponse> execDbQuerySql(@Validated @RequestBody WxPpWcfDatabaseSqlReq request) { + List list = weChatDllService.execDbQuerySql(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, list); + } @ApiOperation(value = "查询群成员", notes = "queryGroupMember") @PostMapping(value = "/list/groupMember") @@ -130,45 +125,17 @@ public class WeChatDllController { @ApiOperation(value = "发送消息汇总入口", notes = "sendMsgMaster") @PostMapping(value = "/send/msgMaster") public TResponse sendMsgMaster(@Validated @RequestBody String jsonString) { - + // todo return TResponse.ok(ResponseCodeEnum.SUCCESS); } - @ApiOperation(value = "发送文本消息(可 @)", notes = "sendTextMsg") + @ApiOperation(value = "发送文本消息", notes = "sendTextMsg") @PostMapping(value = "/send/textMsg") public TResponse sendTextMsg(@Validated @RequestBody WxPpWcfSendTextMsgReq request) { WxPpWcfSendTextMsgResp resp = weChatDllService.sendTextMsg(request); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); } - @ApiOperation(value = "发送图片消息", notes = "sendImageMsg") - @PostMapping(value = "/send/imageMsg") - public TResponse sendImageMsg(@Validated @RequestBody WxPpWcfSendImageMsgReq request) { - WxPpWcfSendImageMsgResp resp = weChatDllService.sendImageMsg(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); - } - - @ApiOperation(value = "发送文件消息", notes = "sendFileMsg") - @PostMapping(value = "/send/fileMsg") - public TResponse sendFileMsg(@Validated @RequestBody WxPpWcfSendFileMsgReq request) { - WxPpWcfSendFileMsgResp resp = weChatDllService.sendFileMsg(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); - } - - @ApiOperation(value = "发送XML消息", notes = "sendXmlMsg") - @PostMapping(value = "/send/xmlMsg") - public TResponse sendXmlMsg(@Validated @RequestBody WxPpWcfSendXmlMsgReq request) { - WxPpWcfSendXmlMsgResp resp = weChatDllService.sendXmlMsg(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); - } - - @ApiOperation(value = "发送表情消息", notes = "sendEmojiMsg") - @PostMapping(value = "/send/emojiMsg") - public TResponse sendEmojiMsg(@Validated @RequestBody WxPpWcfSendEmojiMsgReq request) { - WxPpWcfSendEmojiMsgResp resp = weChatDllService.sendEmojiMsg(request); - return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); - } - @ApiOperation(value = "发送富文本消息", notes = "sendRichTextMsg") @PostMapping(value = "/send/richTextMsg") public TResponse sendRichTextMsg(@Validated @RequestBody WxPpWcfSendRichTextMsgReq request) { @@ -176,6 +143,34 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); } + @ApiOperation(value = "发送XML消息", notes = "sendXmlMsg") + @PostMapping(value = "/send/xmlMsg") + public TResponse sendXmlMsg(@Validated @RequestBody WxPpWcfSendXmlMsgReq request) { + WxPpWcfSendXmlMsgResp resp = weChatDllService.sendXmlMsg(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); + } + + @ApiOperation(value = "发送图片消息", notes = "sendImageMsg") + @PostMapping(value = "/send/imageMsg") + public TResponse sendImageMsg(@Validated @RequestBody WxPpWcfSendImageMsgReq request) { + WxPpWcfSendImageMsgResp resp = weChatDllService.sendImageMsg(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); + } + + @ApiOperation(value = "发送表情消息", notes = "sendEmojiMsg") + @PostMapping(value = "/send/emojiMsg") + public TResponse sendEmojiMsg(@Validated @RequestBody WxPpWcfSendEmojiMsgReq request) { + WxPpWcfSendEmojiMsgResp resp = weChatDllService.sendEmojiMsg(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); + } + + @ApiOperation(value = "发送文件消息", notes = "sendFileMsg") + @PostMapping(value = "/send/fileMsg") + public TResponse sendFileMsg(@Validated @RequestBody WxPpWcfSendFileMsgReq request) { + WxPpWcfSendFileMsgResp resp = weChatDllService.sendFileMsg(request); + return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); + } + @ApiOperation(value = "拍一拍群友", notes = "patOnePat") @PostMapping(value = "/patOnePat") public TResponse patOnePat(@Validated @RequestBody WxPpWcfPatOnePatMsgReq request) { @@ -183,6 +178,12 @@ public class WeChatDllController { return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); } + // @ApiOperation(value = "获取语音消息", notes = "queryMsgTypeList") + // @PostMapping(value = "/list/voiceMsg") + // public TResponse queryVoiceMsg() { + // return TResponse.ok(ResponseCodeEnum.SUCCESS, list); + // } + // @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/WxPpWcfDatabaseSqlReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseSqlReq.java index c306644..9ba95e4 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseSqlReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseSqlReq.java @@ -1,5 +1,7 @@ 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; @@ -17,12 +19,14 @@ public class WxPpWcfDatabaseSqlReq { /** * 数据库名称 */ + @NotBlank(message = "数据库名称不能为空") @ApiModelProperty(value = "数据库名称") private String databaseName; /** * SQL语句 */ + @NotBlank(message = "SQL语句不能为空") @ApiModelProperty(value = "SQL语句") private String sqlText; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseTableReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseTableReq.java index e49bbdb..c5df0c6 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseTableReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfDatabaseTableReq.java @@ -1,5 +1,7 @@ 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; @@ -17,6 +19,7 @@ public class WxPpWcfDatabaseTableReq { /** * 数据库名称 */ + @NotBlank(message = "数据库名称不能为空") @ApiModelProperty(value = "数据库名称") private String databaseName; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfGroupMemberReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfGroupMemberReq.java index fe5b006..a9b43a0 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfGroupMemberReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfGroupMemberReq.java @@ -1,5 +1,7 @@ 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; @@ -17,6 +19,7 @@ public class WxPpWcfGroupMemberReq { /** * 群编号 */ + @NotBlank(message = "群编号不能为空") @ApiModelProperty(value = "群编号") private String groupNo; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPatOnePatMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPatOnePatMsgReq.java index 387b93e..ac8594d 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPatOnePatMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfPatOnePatMsgReq.java @@ -1,5 +1,7 @@ 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; @@ -19,13 +21,15 @@ public class WxPpWcfPatOnePatMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; /** - * 要拍的wxid + * 要拍的人的wxid */ - @ApiModelProperty(value = "要拍的wxid") + @NotBlank(message = "要拍的人的wxid不能为空") + @ApiModelProperty(value = "要拍的人的wxid") private String patUser; } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java index c481b8f..653724a 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendEmojiMsgReq.java @@ -1,5 +1,7 @@ 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; @@ -18,6 +20,7 @@ public class WxPpWcfSendEmojiMsgReq { * 资源路径-本地表情路径 * 需要确保图片路径正确,建议使用绝对路径(使用双斜杠\\) */ + @NotBlank(message = "资源路径不能为空") @ApiModelProperty(value = "资源路径-本地表情路径") private String resourcePath; @@ -26,6 +29,7 @@ public class WxPpWcfSendEmojiMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java index 4ab499a..4ba4c35 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendFileMsgReq.java @@ -1,5 +1,7 @@ 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; @@ -17,6 +19,7 @@ public class WxPpWcfSendFileMsgReq { /** * 资源路径-本地文件路径 */ + @NotBlank(message = "资源路径不能为空") @ApiModelProperty(value = "资源路径-本地文件路径") private String resourcePath; @@ -25,6 +28,7 @@ public class WxPpWcfSendFileMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java index 44e5870..3498b5e 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendImageMsgReq.java @@ -1,5 +1,7 @@ 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; @@ -20,6 +22,7 @@ public class WxPpWcfSendImageMsgReq { * 如:`C:/Projs/WeChatRobot/TEQuant.jpeg` * 或 `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg` */ + @NotBlank(message = "资源路径不能为空") @ApiModelProperty(value = "资源路径-本地图片地址") private String resourcePath; @@ -28,6 +31,7 @@ public class WxPpWcfSendImageMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendRichTextMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendRichTextMsgReq.java index 0b9dca9..f4774d5 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendRichTextMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendRichTextMsgReq.java @@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import javax.validation.constraints.NotBlank; + /** * 请求入参-个微WCF发送富文本消息 * @@ -19,6 +21,7 @@ public class WxPpWcfSendRichTextMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java index 1ea0c32..042efe5 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendTextMsgReq.java @@ -1,11 +1,13 @@ 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; -import java.util.List; - /** * 请求入参-个微WCF发送文本消息 * @@ -21,6 +23,7 @@ public class WxPpWcfSendTextMsgReq { * 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @) * 换行使用 `\\\\n` (单杠) */ + @NotBlank(message = "消息文本不能为空") @ApiModelProperty(value = "消息文本") private String msgText; @@ -29,6 +32,7 @@ public class WxPpWcfSendTextMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendXmlMsgReq.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendXmlMsgReq.java index 12ff1e3..00c5e6b 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendXmlMsgReq.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/request/WxPpWcfSendXmlMsgReq.java @@ -1,5 +1,8 @@ package com.wechat.ferry.entity.vo.request; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -19,12 +22,14 @@ public class WxPpWcfSendXmlMsgReq { * 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx) * 群聊为 roomid(xxxxxxxxxx@chatroom) */ + @NotBlank(message = "消息接收人不能为空") @ApiModelProperty(value = "消息接收人") private String recipient; /** * XML报文内容 */ + @NotBlank(message = "XML报文内容不能为空") @ApiModelProperty(value = "XML报文内容") private String xmlContent; @@ -35,9 +40,10 @@ public class WxPpWcfSendXmlMsgReq { private String resourcePath; /** - * xml类型,如:0x21 为小程序 + * XML类型,如:21 为小程序 */ - @ApiModelProperty(value = "xml类型") - private Integer xmlType; + @NotNull(message = "XML类型不能为空") + @ApiModelProperty(value = "XML类型") + private String xmlType; } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseFieldResp.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseFieldResp.java index b8d461e..e7d050b 100644 --- a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseFieldResp.java +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseFieldResp.java @@ -30,6 +30,6 @@ public class WxPpWcfDatabaseFieldResp { * 字段值 */ @ApiModelProperty(value = "字段值") - private String value; + private Object value; } diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java new file mode 100644 index 0000000..00369c1 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/entity/vo/response/WxPpWcfDatabaseTableResp.java @@ -0,0 +1,29 @@ +package com.wechat.ferry.entity.vo.response; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求出参-个微WCF数据库表 + * + * @author chandler + * @date 2024/12/24 13:40 + */ +@Data +@ApiModel(value = "wxPpWcfDatabaseRowResp", description = "个微WCF数据库表查询请求出参") +public class WxPpWcfDatabaseTableResp { + + /** + * 表名 + */ + @ApiModelProperty(value = "表名") + private String tableName; + + /** + * SQL + */ + @ApiModelProperty(value = "SQL") + private String sql; + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/DatabaseNameEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/DatabaseNameEnum.java new file mode 100644 index 0000000..0b52035 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/DatabaseNameEnum.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/24 15:10 + */ +@Getter +@AllArgsConstructor +public enum DatabaseNameEnum { + + /** + * MicroMsg- + */ + MICRO_MSG("MicroMsg.db", ""), + + /** + * 未匹配上 + */ + 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(DatabaseNameEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static DatabaseNameEnum getCodeMap(String code) { + return codeMap.getOrDefault(code, UN_MATCH); + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/TableNameEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/TableNameEnum.java new file mode 100644 index 0000000..a05aa57 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/TableNameEnum.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/24 15:24 + */ +@Getter +@AllArgsConstructor +public enum TableNameEnum { + + /** + * CONTACT-联系人 + */ + CONTACT("Contact", "联系人", ""), + + /** + * 未匹配上 + */ + UN_MATCH("", null, ""), + + // 结束 + ; + + private final String code; + private final String name; + private final String db; + + /** + * map集合 key:code val:枚举 + */ + public static final Map codeMap = Arrays.stream(values()).collect(Collectors.toMap(TableNameEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static TableNameEnum getCodeMap(String code) { + return codeMap.getOrDefault(code, UN_MATCH); + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsMixedEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsMixedEnum.java new file mode 100644 index 0000000..b3775a0 --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsMixedEnum.java @@ -0,0 +1,90 @@ +package com.wechat.ferry.enums; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.util.ObjectUtils; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 枚举-微信联系人-官方杂号 + * + * @author chandler + * @date 2024/12/24 16:01 + */ +@Getter +@AllArgsConstructor +public enum WxContactsMixedEnum { + + /** + * fmessage-朋友推荐消息 + */ + F_MESSAGE("fmessage", "朋友推荐消息"), + + /** + * medianote-语音记事本 + */ + MEDIA_NOTE("medianote", "语音记事本"), + + /** + * floatbottle-漂流瓶 + */ + FLOAT_BOTTLE("floatbottle", "漂流瓶"), + + /** + * filehelper-文件传输助手 + */ + FILE_HELPER("filehelper", "文件传输助手"), + + /** + * newsapp-新闻 + */ + NEWS_APP("newsapp", "新闻"), + + /** + * newsapp-微信团队 + */ + WEI_XIN("weixin", "微信团队"), + + /** + * 未匹配上 + */ + 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(WxContactsMixedEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static WxContactsMixedEnum getCodeMap(String code) { + return codeMap.getOrDefault(code, UN_MATCH); + } + + /** + * map集合 key:code val:名称 + */ + public static Map toCodeNameMap() { + Map map = new HashMap<>(); + for (WxContactsMixedEnum val : WxContactsMixedEnum.values()) { + if (!ObjectUtils.isEmpty(val.getCode())) { + map.put(val.getCode(), val.getName()); + } + } + return map; + } + +} diff --git a/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsOfficialEnum.java b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsOfficialEnum.java new file mode 100644 index 0000000..4bba47a --- /dev/null +++ b/clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsOfficialEnum.java @@ -0,0 +1,85 @@ +package com.wechat.ferry.enums; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.util.ObjectUtils; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 枚举-微信联系人-公众号 + * + * @author chandler + * @date 2024/12/24 16:36 + */ +@Getter +@AllArgsConstructor +public enum WxContactsOfficialEnum { + + /** + * wxid_2876568766325-应用宝-yingyongbao + */ + YING_YONG_BAO("wxid_2876568766325", "应用宝"), + + /** + * wxid_2965349653612-i黑马-iheima + */ + I_HEI_MA("wxid_2965349653612", "i黑马"), + + /** + * wxid_4302923029011-丁香医生-DingXiangYiSheng + */ + DING_XIANG_YI_SHENG("wxid_4302923029011", "丁香医生"), + + /** + * mphelper-公众平台安全助手 + */ + MP_HELPER("mphelper", "公众平台安全助手"), + + /** + * weixinguanhaozhushou-微信公众平台-weixingongzhong + */ + WEI_XIN_GONG_ZHONG("weixinguanhaozhushou", "微信公众平台"), + + /** + * 未匹配上 + */ + 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(WxContactsOfficialEnum::getCode, v -> v)); + + /** + * 根据code获取枚举 + */ + public static WxContactsOfficialEnum getCodeMap(String code) { + return codeMap.getOrDefault(code, UN_MATCH); + } + + /** + * map集合 key:code val:名称 + */ + public static Map toCodeNameMap() { + Map map = new HashMap<>(); + for (WxContactsOfficialEnum val : WxContactsOfficialEnum.values()) { + if (!ObjectUtils.isEmpty(val.getCode())) { + map.put(val.getCode(), val.getName()); + } + } + return map; + } + +} 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 c7eed8d..7f34ad4 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 @@ -2,9 +2,7 @@ package com.wechat.ferry.handle; import java.nio.ByteBuffer; 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; @@ -13,20 +11,15 @@ import org.springframework.util.ObjectUtils; import com.alibaba.fastjson2.JSONObject; import com.sun.jna.Native; import com.wechat.ferry.entity.dto.WxPpMsgDTO; -import com.wechat.ferry.entity.proto.Wcf; import com.wechat.ferry.entity.proto.Wcf.DbQuery; import com.wechat.ferry.entity.proto.Wcf.DbRow; -import com.wechat.ferry.entity.proto.Wcf.DbTable; 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.RpcContact; -import com.wechat.ferry.entity.proto.Wcf.UserInfo; import com.wechat.ferry.entity.proto.Wcf.Verification; import com.wechat.ferry.entity.proto.Wcf.WxMsg; -import com.wechat.ferry.enums.SexEnum; import com.wechat.ferry.service.SDK; import com.wechat.ferry.utils.HttpClientUtil; import com.wechat.ferry.utils.XmlJsonConvertUtil; @@ -149,53 +142,6 @@ public class WeChatSocketClient { return false; } - /** - * 获得微信客户端登录的微信ID - * - * @return 微信ID - */ - public String getSelfWxId() { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_SELF_WXID_VALUE).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - return rsp.getStr(); - } - return ""; - } - - /** - * 获取所有消息类型 - * - * @return 消息类型集合 - */ - public Map getMsgTypes() { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_MSG_TYPES_VALUE).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - return rsp.getTypes().getTypesMap(); - } - return Wcf.MsgTypes.newBuilder().build().getTypesMap(); - } - - /** - * 获取所有联系人 - * "fmessage": "朋友推荐消息", - * "medianote": "语音记事本", - * "floatbottle": "漂流瓶", - * "filehelper": "文件传输助手", - * "newsapp": "新闻", - * - * @return 联系人列表 - */ - public List getContacts() { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_CONTACTS_VALUE).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - return rsp.getContacts().getContactsList(); - } - return Wcf.RpcContacts.newBuilder().build().getContactsList(); - } - /** * 获取sql执行结果 * @@ -213,141 +159,6 @@ public class WeChatSocketClient { return null; } - /** - * 获取所有数据库名 - * - * @return 数据库名称列表 - */ - public List getDbNames() { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_DB_NAMES_VALUE).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - return rsp.getDbs().getNamesList(); - } - return Wcf.DbNames.newBuilder().build().getNamesList(); - } - - /** - * 获取指定数据库中的所有表 - * - * @param db 数据库名称 - * @return 数据库中表列表 - */ - public Map getDbTables(String db) { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_DB_TABLES_VALUE).setStr(db).build(); - Response rsp = sendCmd(req); - Map tables = new HashMap<>(); - if (rsp != null) { - for (DbTable tbl : rsp.getTables().getTablesList()) { - tables.put(tbl.getName(), tbl.getSql()); - } - } - return tables; - } - - /** - * @param msg: 消息内容(如果是 @ 消息则需要有跟 @ 的人数量相同的 @) - * @param receiver: 消息接收人,私聊为 wxid(wxid_xxxxxxxxxxxxxx),群聊为 - * roomid(xxxxxxxxxx@chatroom) - * @param aters: 群聊时要 @ 的人(私聊时为空字符串),多个用逗号分隔。@所有人 用 - * notify@all(必须是群主或者管理员才有权限) - * @return int - * @Description 发送文本消息 - * @author Changhua - * @example sendText(" Hello @ 某人1 @ 某人2 ", " xxxxxxxx @ chatroom ", - * "wxid_xxxxxxxxxxxxx1,wxid_xxxxxxxxxxxxx2"); - */ - public int sendText(String msg, String receiver, String aters) { - Wcf.TextMsg textMsg = Wcf.TextMsg.newBuilder().setMsg(msg).setReceiver(receiver).setAters(aters).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_TXT_VALUE).setTxt(textMsg).build(); - log.debug("sendText: {}", bytesToHex(req.toByteArray())); - Response rsp = sendCmd(req); - int ret = -1; - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - - /** - * 发送图片消息 - * - * @param path 图片地址 - * @param receiver 接收者微信id - * @return 发送结果状态码 - */ - public int sendImage(String path, String receiver) { - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_IMG_VALUE).setFile(pathMsg).build(); - log.debug("sendImage: {}", bytesToHex(req.toByteArray())); - Response rsp = sendCmd(req); - int ret = -1; - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - - /** - * 发送文件消息 - * - * @param path 文件地址 - * @param receiver 接收者微信id - * @return 发送结果状态码 - */ - public int sendFile(String path, String receiver) { - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build(); - log.debug("sendFile: {}", bytesToHex(req.toByteArray())); - Response rsp = sendCmd(req); - int ret = -1; - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - - /** - * 发送Xml消息 - * - * @param receiver 接收者微信id - * @param xml xml内容 - * @param path 路径 - * @param type 类型 - * @return 发送结果状态码 - */ - public int sendXml(String receiver, String xml, String path, int type) { - Wcf.XmlMsg xmlMsg = Wcf.XmlMsg.newBuilder().setContent(xml).setReceiver(receiver).setPath(path).setType(type).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_XML_VALUE).setXml(xmlMsg).build(); - log.debug("sendXml: {}", bytesToHex(req.toByteArray())); - Response rsp = sendCmd(req); - int ret = -1; - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - - /** - * 发送表情消息 - * - * @param path 表情路径 - * @param receiver 消息接收者 - * @return 发送结果状态码 - */ - @Deprecated - public int sendEmotion(String path, String receiver) { - Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(path).setReceiver(receiver).build(); - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_SEND_EMOTION_VALUE).setFile(pathMsg).build(); - log.debug("sendEmotion: {}", bytesToHex(req.toByteArray())); - Response rsp = sendCmd(req); - int ret = -1; - if (rsp != null) { - ret = rsp.getStatus(); - } - return ret; - } - /** * 接收好友请求 * @@ -402,20 +213,6 @@ public class WeChatSocketClient { return ret == 1; } - /** - * 获取个人信息 - * - * @return 个人信息 - */ - public UserInfo getUserInfo() { - Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_USER_INFO_VALUE).build(); - Response rsp = sendCmd(req); - if (rsp != null) { - return rsp.getUi(); - } - return null; - } - public boolean getIsReceivingMsg() { return isReceivingMsg; } @@ -434,10 +231,11 @@ public class WeChatSocketClient { * * @param wxMsgXml XML消息 * @param wxMsgContent 消息内容 + * @param selfWxId 自己的微信id * @return 是否 */ - public boolean isAtMeMsg(String wxMsgXml, String wxMsgContent) { - String format = String.format("", getSelfWxId()); + public boolean isAtMeMsg(String wxMsgXml, String wxMsgContent, String selfWxId) { + String format = String.format("", selfWxId); boolean isAtAll = wxMsgContent.startsWith("@所有人") || wxMsgContent.startsWith("@all"); if (wxMsgXml.contains(format) && !isAtAll) { return true; @@ -517,21 +315,6 @@ public class WeChatSocketClient { } } - public void printContacts(List contacts) { - for (RpcContact c : contacts) { - int value = c.getGender(); - String gender; - if (SexEnum.BOY.getCode().equals(String.valueOf(value))) { - gender = "男"; - } else if (SexEnum.GIRL.getCode().equals(String.valueOf(value))) { - gender = "女"; - } else { - gender = "未知"; - } - log.info("{}, {}, {}, {}, {}, {}, {}", c.getWxid(), c.getName(), c.getCode(), c.getCountry(), c.getProvince(), c.getCity(), gender); - } - } - public void printWxMsg(WxMsg msg) { WxPpMsgDTO dto = new WxPpMsgDTO(); dto.setIsSelf(msg.getIsSelf()); @@ -551,7 +334,7 @@ public class WeChatSocketClient { log.info("收到消息: {}", jsonString); } - private String bytesToHex(byte[] bytes) { + public String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); 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 4284f45..b998b8c 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 @@ -14,6 +14,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfSendTextMsgReq; import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; +import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; @@ -45,6 +46,7 @@ public interface WeChatDllService { /** * 获取登录微信内部识别号UID + * 获得微信客户端登录的微信ID * * @return 微信内部识别号UID * @@ -64,7 +66,7 @@ public interface WeChatDllService { WxPpWcfLoginInfoResp queryLoginWeChatInfo(); /** - * 获取所有消息类型 + * 获取消息类型列表 * * @return 消息类型列表 * @@ -74,7 +76,7 @@ public interface WeChatDllService { List queryMsgTypeList(); /** - * 获取所有联系人 + * 获取联系人列表 * * @return 联系人列表 * @@ -84,28 +86,17 @@ public interface WeChatDllService { List queryContactsList(); /** - * 获取数据库所有表名称 + * 获取数据库表名称列表 * * @return 数据库名称列表 * * @author chandler * @date 2024-10-02 17:53 */ - List queryDatabaseAllTableName(); + List queryDbTableNameList(); /** - * 获取可查询数据库 - * - * @param request 请求入参 - * @return 数据库记录 - * - * @author chandler - * @date 2024-10-02 17:52 - */ - List queryDatabaseSql(WxPpWcfDatabaseSqlReq request); - - /** - * 获取数据库表 + * 获取指定数据库中的所有表 * * @param request 请求入参 * @return 数据库记录 @@ -113,7 +104,18 @@ public interface WeChatDllService { * @author chandler * @date 2024-10-02 17:52 */ - List queryDatabaseTable(WxPpWcfDatabaseTableReq request); + List queryDbTableList(WxPpWcfDatabaseTableReq request); + + /** + * 执行数据库查询SQL + * + * @param request 请求入参 + * @return 数据库记录 + * + * @author chandler + * @date 2024-10-02 17:52 + */ + List execDbQuerySql(WxPpWcfDatabaseSqlReq request); /** * 查询群成员 @@ -140,26 +142,15 @@ public interface WeChatDllService { WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request); /** - * 发送图片消息 + * 发送富文本消息 * * @param request 请求入参 * @return 消息发送返回 * * @author chandler - * @date 2024-10-04 23:06 + * @date 2024-10-06 15:48 */ - WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request); - - /** - * 发送文件消息 - * - * @param request 请求入参 - * @return 消息发送返回 - * - * @author chandler - * @date 2024-10-04 23:15 - */ - WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request); + WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request); /** * 发送XML消息 @@ -172,6 +163,17 @@ public interface WeChatDllService { */ WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request); + /** + * 发送图片消息 + * + * @param request 请求入参 + * @return 消息发送返回 + * + * @author chandler + * @date 2024-10-04 23:06 + */ + WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request); + /** * 发送表情消息 * @@ -184,15 +186,15 @@ public interface WeChatDllService { WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request); /** - * 发送富文本消息 + * 发送文件消息 * * @param request 请求入参 * @return 消息发送返回 * * @author chandler - * @date 2024-10-06 15:48 + * @date 2024-10-04 23:15 */ - WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request); + WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq 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 6cf4feb..6a2b61c 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 @@ -3,7 +3,6 @@ package com.wechat.ferry.service.impl; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -35,6 +34,7 @@ import com.wechat.ferry.entity.vo.request.WxPpWcfSendXmlMsgReq; import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseFieldResp; import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; +import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseTableResp; import com.wechat.ferry.entity.vo.response.WxPpWcfGroupMemberResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; @@ -45,8 +45,11 @@ import com.wechat.ferry.entity.vo.response.WxPpWcfSendPatOnePatMsgResp; 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.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; @@ -76,37 +79,53 @@ public class WeChatDllServiceImpl implements WeChatDllService { @Override public Boolean loginStatus() { + long startTime = System.currentTimeMillis(); Boolean status = wechatSocketClient.isLogin(); - log.info("[查询]-[登录状态]-status:{}", status); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[登录状态]-耗时:{}ms,status:{}", (endTime - startTime), status); return status; } @Override public String queryLoginWeChatUid() { - String weChatUid = wechatSocketClient.getSelfWxId(); - log.info("[查询]-[登录微信UID]-weChatUid:{}", weChatUid); + long startTime = System.currentTimeMillis(); + String weChatUid = ""; + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_SELF_WXID_VALUE).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + if (!ObjectUtils.isEmpty(rsp)) { + weChatUid = rsp.getStr(); + } + long endTime = System.currentTimeMillis(); + log.info("[查询]-[登录微信UID]-耗时:{}ms, weChatUid:{}", (endTime - startTime), weChatUid); return weChatUid; } @Override public WxPpWcfLoginInfoResp queryLoginWeChatInfo() { + long startTime = System.currentTimeMillis(); WxPpWcfLoginInfoResp resp = new WxPpWcfLoginInfoResp(); - Wcf.UserInfo userInfo = wechatSocketClient.getUserInfo(); - if (!ObjectUtils.isEmpty(userInfo)) { + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_USER_INFO_VALUE).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getUi())) { + Wcf.UserInfo userInfo = rsp.getUi(); resp.setWeChatUid(userInfo.getWxid()); resp.setWeChatNickname(userInfo.getName()); resp.setPhone(userInfo.getMobile()); resp.setHomePath(userInfo.getHome()); } - log.info("[查询]-[获取登录微信信息]-resp:{}", resp); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[获取登录微信信息]-耗时:{}ms,登录信息:{}", (endTime - startTime), resp); return resp; } @Override public List queryMsgTypeList() { + long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); - Map msgTypeMap = wechatSocketClient.getMsgTypes(); - if (!CollectionUtils.isEmpty(msgTypeMap)) { + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_MSG_TYPES_VALUE).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + if (!ObjectUtils.isEmpty(rsp)) { + Map msgTypeMap = rsp.getTypes().getTypesMap(); WxPpWcfMsgTypeResp resp; for (Map.Entry entry : msgTypeMap.entrySet()) { resp = new WxPpWcfMsgTypeResp(); @@ -115,15 +134,19 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(resp); } } - log.info("[查询]-[所有消息类型]-共查到:{}条", list.size()); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[所有消息类型]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override public List queryContactsList() { + long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); - List rpcContactList = wechatSocketClient.getContacts(); - if (!CollectionUtils.isEmpty(rpcContactList)) { + Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_CONTACTS_VALUE).build(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getContacts()) && !CollectionUtils.isEmpty(rsp.getContacts().getContactsList())) { + List rpcContactList = rsp.getContacts().getContactsList(); for (Wcf.RpcContact rpcContact : rpcContactList) { WxPpWcfContactsResp vo = new WxPpWcfContactsResp(); vo.setWeChatUid(rpcContact.getWxid()); @@ -151,32 +174,14 @@ public class WeChatDllServiceImpl implements WeChatDllService { } // 微信类型 if (!ObjectUtils.isEmpty(rpcContact.getWxid())) { - List mixedNoList = new ArrayList<>(); - // 朋友推荐消息 - mixedNoList.add("fmessage"); - // 语音记事本 - mixedNoList.add("medianote"); - // 漂流瓶 - mixedNoList.add("floatbottle"); - // 文件传输助手 - mixedNoList.add("filehelper"); - // 新闻 - mixedNoList.add("newsapp"); - // 微信团队 - mixedNoList.add("weixin"); - // 微信支付 wxzhifu - // mixedNoList.add("gh_3dfda90e39d6"); - // 微信公开课 wx-gongkaike - // mixedNoList.add("gh_c46cbbfa1de9"); - // 微信运动 WeRun-WeChat - // mixedNoList.add("gh_43f2581f6fd6"); - // 微信游戏 game - // mixedNoList.add("gh_25d9ac85a4bc"); - // 微信开发者 - // mixedNoList.add("gh_56fc3b00cc4f"); - // 微信搜一搜 wechat_search - // mixedNoList.add("gh_f08f54ae25a4"); + // 官方杂号集合 + 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()); @@ -185,7 +190,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { // 群聊 @im.chatroom 这种是很早之前的格式,单独例举 vo.setType(WxContactsTypeEnum.GROUP.getCode()); vo.setTypeLabel(WxContactsTypeEnum.GROUP.getName()); - } else if (mixedNoList.contains(rpcContact.getWxid())) { + } else if (mixedNoMap.containsKey(rpcContact.getWxid())) { // 官方杂号 vo.setType(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getCode()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getName()); @@ -193,14 +198,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { // 微信公众号 vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); - } else if ("wxid_2876568766325".equals(rpcContact.getWxid()) || "wxid_2965349653612".equals(rpcContact.getWxid()) - || "wxid_4302923029011".equals(rpcContact.getWxid()) || "mphelper".equals(rpcContact.getWxid()) - || "weixinguanhaozhushou".equals(rpcContact.getWxid())) { - // 应用宝 yingyongbao wxid_2876568766325 - // i黑马 iheima wxid_2965349653612 - // 丁香医生 DingXiangYiSheng wxid_4302923029011 - // 公众平台安全助手 mphelper - // 微信公众平台 weixingongzhong weixinguanhaozhushou + } else if (officialMap.containsKey(rpcContact.getWxid())) { vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); } else { @@ -212,19 +210,49 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(vo); } } - log.info("[查询]-[联系人]-共查到:{}条", list.size()); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[联系人]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override - public List queryDatabaseAllTableName() { - List list = wechatSocketClient.getDbNames(); - log.info("[查询]-[数据库名称列表]-共查到:{}条", list.size()); + public List queryDbTableNameList() { + long startTime = System.currentTimeMillis(); + 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); + if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getDbs()) && !CollectionUtils.isEmpty(rsp.getDbs().getNamesList())) { + list = rsp.getDbs().getNamesList(); + } + long endTime = System.currentTimeMillis(); + log.info("[查询]-[数据库名称列表]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override - public List queryDatabaseSql(WxPpWcfDatabaseSqlReq request) { + public List queryDbTableList(WxPpWcfDatabaseTableReq request) { + long startTime = System.currentTimeMillis(); + 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(); + Wcf.Response rsp = wechatSocketClient.sendCmd(req); + if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getTables()) && !CollectionUtils.isEmpty(rsp.getTables().getTablesList())) { + WxPpWcfDatabaseTableResp resp; + for (Wcf.DbTable tbl : rsp.getTables().getTablesList()) { + resp = new WxPpWcfDatabaseTableResp(); + resp.setTableName(tbl.getName()); + resp.setSql(tbl.getSql()); + list.add(resp); + } + } + long endTime = System.currentTimeMillis(); + log.info("[查询]-[数据库表列表]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); + return list; + } + + @Override + public List execDbQuerySql(WxPpWcfDatabaseSqlReq request) { + long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); List wcfList = wechatSocketClient.querySql(request.getDatabaseName(), request.getSqlText()); if (!CollectionUtils.isEmpty(wcfList)) { @@ -233,9 +261,15 @@ public class WeChatDllServiceImpl implements WeChatDllService { List fieldVoList = new ArrayList<>(); for (Wcf.DbField dbField : dbRow.getFieldsList()) { WxPpWcfDatabaseFieldResp fieldVo = new WxPpWcfDatabaseFieldResp(); + Object value; + if (ObjectUtils.isEmpty(dbField.getType())) { + log.warn("未知的SQL类型: {}", dbField.getType()); + value = dbField.getContent().toByteArray(); + } else { + value = convertSqlVal(dbField.getType(), dbField.getContent()); + } fieldVo.setType(String.valueOf(dbField.getType())); fieldVo.setColumn(dbField.getColumn()); - String value = (String)converterSqlVal(dbField.getType(), dbField.getContent()); fieldVo.setValue(value); fieldVoList.add(fieldVo); } @@ -243,30 +277,23 @@ public class WeChatDllServiceImpl implements WeChatDllService { list.add(rowVo); } } - log.info("[查询]-[获取可查询数据库]-wcfList:{}", wcfList); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[执行数据库查询SQL]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } - @Override - public List queryDatabaseTable(WxPpWcfDatabaseTableReq request) { - log.info("[查询]-[查询表]-request:{}", request); - Map wcfMap = wechatSocketClient.getDbTables(request.getDatabaseName()); - // TODO 待建模 - log.info("[查询]-[查询表]-查到:{}", wcfMap); - return Collections.emptyList(); - } - @Override public List queryGroupMember(WxPpWcfGroupMemberReq request) { + long startTime = System.currentTimeMillis(); List list = new ArrayList<>(); // 查询群成员 List wcfList = new ArrayList<>(); if (!ObjectUtils.isEmpty(request.getGroupNo())) { - wcfList = - wechatSocketClient.querySql("MicroMsg.db", "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';"); + wcfList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), + "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';"); } // 查询联系人 - List dbList = wechatSocketClient.querySql("MicroMsg.db", "SELECT UserName, NickName, Type FROM Contact;"); + List dbList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), "SELECT UserName, NickName, Type FROM Contact;"); Map dbMap = new HashMap<>(); if (!CollectionUtils.isEmpty(dbList)) { for (Wcf.DbRow dbRow : dbList) { @@ -276,11 +303,11 @@ public class WeChatDllServiceImpl implements WeChatDllService { for (Wcf.DbField dbField : dbFieldList) { if ("UserName".equals(dbField.getColumn())) { vo = new WxPpWcfGroupMemberResp(); - String content = (String)converterSqlVal(dbField.getType(), dbField.getContent()); + String content = (String)convertSqlVal(dbField.getType(), dbField.getContent()); vo.setWeChatUid(content); } if ("NickName".equals(dbField.getColumn())) { - String content = (String)converterSqlVal(dbField.getType(), dbField.getContent()); + String content = (String)convertSqlVal(dbField.getType(), dbField.getContent()); vo.setGroupNickName(content); dbMap.put(vo.getWeChatUid(), vo.getGroupNickName()); } @@ -320,12 +347,14 @@ public class WeChatDllServiceImpl implements WeChatDllService { } } } - log.info("[查询]-[查询群成员]-共查到:{}条", list.size()); + long endTime = System.currentTimeMillis(); + log.info("[查询]-[查询群成员]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime)); return list; } @Override public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { + long startTime = System.currentTimeMillis(); log.info("[发送消息]-[文本消息]-入参打印:{}", request); String atUser = ""; if (request.getIsAtAll()) { @@ -337,85 +366,136 @@ public class WeChatDllServiceImpl implements WeChatDllService { 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 = wechatSocketClient.sendText(request.getMsgText(), request.getRecipient(), atUser); - log.info("[发送消息]-[文本消息]-处理结束"); + 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 WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { - WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); - int state = wechatSocketClient.sendImage(request.getResourcePath(), request.getRecipient()); - // 转发处理 - String stringJson = JSON.toJSONString(request); - sendMsgForward(stringJson, state); - return null; - } - - @Override - public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) { - int state = wechatSocketClient.sendFile(request.getResourcePath(), request.getRecipient()); + 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 = 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) { - int state = wechatSocketClient.sendXml(request.getRecipient(), request.getXmlContent(), request.getResourcePath(), request.getXmlType()); + 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 = judgeSendMsgState(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 = 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) { - int state = wechatSocketClient.sendEmotion(request.getResourcePath(), request.getRecipient()); + 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 WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq 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 wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); - Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); - int state = judgeState(rsp); + 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 = judgeState(rsp); + int state = judgeSendMsgState(rsp); // 转发处理 String stringJson = JSON.toJSONString(request); sendMsgForward(stringJson, state); + long endTime = System.currentTimeMillis(); + log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime)); return null; } /** * 获取SQL类型 - * - * @return 函数 * * @param type 转换类型 + * @return 函数 * * @author chandler * @date 2024-10-05 12:54 @@ -440,7 +520,7 @@ public class WeChatDllServiceImpl implements WeChatDllService { * @author chandler * @date 2024-10-05 12:54 */ - public Object converterSqlVal(int type, ByteString content) { + public Object convertSqlVal(int type, ByteString content) { // 根据每一列的类型转换 Function converter = getSqlType(type); if (converter != null) { @@ -535,7 +615,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { } /** - * 判断CMD调用状态 + * 判断发送消息状态 + * 0 为成功,其他失败 * * @param rsp 响应参数 * @return 状态 @@ -543,7 +624,8 @@ public class WeChatDllServiceImpl implements WeChatDllService { * @author chandler * @date 2024-12-23 21:53 */ - private int judgeState(Wcf.Response rsp) { + private int judgeSendMsgState(Wcf.Response rsp) { + // 0 为成功,其他失败 int state = -1; if (rsp != null) { state = rsp.getStatus(); @@ -551,4 +633,31 @@ public class WeChatDllServiceImpl implements WeChatDllService { return state; } + /** + * 转换联系人类型配置 + * + * @param list 配置参数 + * @return map key:code val:name + * + * @author chandler + * @date 2024-12-24 16:55 + */ + private 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/resources/application.yml b/clients/java/wechat-ferry-mvn/src/main/resources/application.yml index 2713663..fc9a8c2 100644 --- a/clients/java/wechat-ferry-mvn/src/main/resources/application.yml +++ b/clients/java/wechat-ferry-mvn/src/main/resources/application.yml @@ -26,6 +26,12 @@ wechat: dll-path: E:\WeChatFerry\clients\java\wechat-ferry-mvn\dll\sdk.dll # socket端口 socket-port: 10086 + # 联系人类型-官方杂号,禁止与其他分类重复(格式:代码|名称) + contacts-type-mixed: + - filehelper|文件传输助手 + # 联系人类型-公众号,禁止与其他分类重复(格式:代码|名称) + contacts-type-official: + - weixinguanhaozhushou|微信公众平台 # 需要开启消息处理的群 open-msg-groups: - 53257911728@chatroom