Merge pull request #1 from PathfinderAx/develop

自测完毕
This commit is contained in:
chandler 2024-12-24 21:01:48 +08:00 committed by GitHub
commit 720c695aef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 702 additions and 411 deletions

View File

@ -1,10 +1,43 @@
## v39.3.3 ## 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 ### 已知BUG
- 1.发送表情微信客户端闪退 - `待修复` - 1.发送表情微信客户端闪退 - `待修复`
- 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复` - 2.发送富文本包含thumbnailUrl参数会导致消息发送不出去 - `待修复`
### 2024-12-24
#### ⛰️ Features
- 执行数据库查询SQL请求接口API地址修改
- 业务代码迁移至业务类中,并补充日志信息
- 联系人特殊类型支持配置文件自定义
- 接口入参新增为空校验
- 说明文档更新
- 配置文件有更新
### 2024-12-23 ### 2024-12-23
#### ⛰️ Features #### ⛰️ Features

View File

@ -53,6 +53,11 @@
<version>1.18.30</version> <version>1.18.30</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- 参数校验 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- swagger3包--> <!-- swagger3包-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>

View File

@ -48,7 +48,7 @@ public class WeChatConfiguration {
// client.printContacts(client.getContacts()); // client.printContacts(client.getContacts());
// 获取数据库 // 获取数据库
log.info("dbs: {}", wechatSocketClient.getDbNames()); // log.info("dbs: {}", wechatSocketClient.getDbNames());
// 获取数据库下的表 // 获取数据库下的表
String db = "MicroMsg.db"; String db = "MicroMsg.db";

View File

@ -29,6 +29,18 @@ public class WeChatFerryProperties {
*/ */
private Integer socketPort; private Integer socketPort;
/**
* 联系人类型-官方杂号禁止与其他分类重复(格式代码|名称)
* 使用时记得需要提取代码或者名称匹配
*/
private List<String> contactsTypeMixed;
/**
* 联系人类型-公众号禁止与其他分类重复(格式代码|名称)
* 使用时记得需要提取代码或者名称匹配
*/
private List<String> contactsTypeOfficial;
/** /**
* 需要开启消息处理的群 * 需要开启消息处理的群
*/ */

View File

@ -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.request.WxPpWcfSendXmlMsgReq;
import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; 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.WxPpWcfGroupMemberResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp;
@ -79,46 +80,40 @@ public class WeChatDllController {
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
} }
@ApiOperation(value = "获取消息类型", notes = "queryMsgTypeList") @ApiOperation(value = "获取消息类型列表", notes = "queryMsgTypeList")
@PostMapping(value = "/list/msgType") @PostMapping(value = "/list/msgType")
public TResponse<List<WxPpWcfMsgTypeResp>> queryMsgTypeList() { public TResponse<List<WxPpWcfMsgTypeResp>> queryMsgTypeList() {
List<WxPpWcfMsgTypeResp> list = weChatDllService.queryMsgTypeList(); List<WxPpWcfMsgTypeResp> list = weChatDllService.queryMsgTypeList();
return TResponse.ok(ResponseCodeEnum.SUCCESS, list); return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
} }
@ApiOperation(value = "获取联系人", notes = "queryContactsList") @ApiOperation(value = "获取联系人列表", notes = "queryContactsList")
@PostMapping(value = "/list/contacts") @PostMapping(value = "/list/contacts")
public TResponse<List<WxPpWcfContactsResp>> queryContactsList() { public TResponse<List<WxPpWcfContactsResp>> queryContactsList() {
List<WxPpWcfContactsResp> list = weChatDllService.queryContactsList(); List<WxPpWcfContactsResp> list = weChatDllService.queryContactsList();
return TResponse.ok(ResponseCodeEnum.SUCCESS, list); return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
} }
@ApiOperation(value = "获取数据库所有表名称", notes = "queryDatabaseAllTableName") @ApiOperation(value = "获取数据库表名称列表", notes = "queryDbTableNameList")
@PostMapping(value = "/list/dbTableName") @PostMapping(value = "/list/dbTableName")
public TResponse<List<String>> queryDatabaseAllTableName() { public TResponse<List<String>> queryDbTableNameList() {
List<String> list = weChatDllService.queryDatabaseAllTableName(); List<String> list = weChatDllService.queryDbTableNameList();
return TResponse.ok(ResponseCodeEnum.SUCCESS, list); return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
} }
@ApiOperation(value = "获取可查询数据库", notes = "queryDatabaseSql") @ApiOperation(value = "获取指定数据库中的表列表", notes = "queryDbTableList")
@PostMapping(value = "/list/dbSql")
public TResponse<List<WxPpWcfDatabaseRowResp>> queryDatabaseSql(@Validated @RequestBody WxPpWcfDatabaseSqlReq request) {
List<WxPpWcfDatabaseRowResp> list = weChatDllService.queryDatabaseSql(request);
return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
}
@ApiOperation(value = "获取指定数据库中的表", notes = "queryDatabaseTable")
@PostMapping(value = "/list/dbTable") @PostMapping(value = "/list/dbTable")
public TResponse<List<String>> queryDatabaseTable(@Validated @RequestBody WxPpWcfDatabaseTableReq request) { public TResponse<List<WxPpWcfDatabaseTableResp>> queryDbTableList(@Validated @RequestBody WxPpWcfDatabaseTableReq request) {
List<String> list = weChatDllService.queryDatabaseTable(request); List<WxPpWcfDatabaseTableResp> list = weChatDllService.queryDbTableList(request);
return TResponse.ok(ResponseCodeEnum.SUCCESS, list); return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
} }
// @ApiOperation(value = "获取语音消息", notes = "queryMsgTypeList") @ApiOperation(value = "执行数据库查询SQL", notes = "execDbQuerySql")
// @PostMapping(value = "/list/voiceMsg") @PostMapping(value = "/exec/dbQuerySql")
// public TResponse<Object> queryVoiceMsg() { public TResponse<List<WxPpWcfDatabaseRowResp>> execDbQuerySql(@Validated @RequestBody WxPpWcfDatabaseSqlReq request) {
// return TResponse.ok(ResponseCodeEnum.SUCCESS, list); List<WxPpWcfDatabaseRowResp> list = weChatDllService.execDbQuerySql(request);
// } return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
}
@ApiOperation(value = "查询群成员", notes = "queryGroupMember") @ApiOperation(value = "查询群成员", notes = "queryGroupMember")
@PostMapping(value = "/list/groupMember") @PostMapping(value = "/list/groupMember")
@ -130,45 +125,17 @@ public class WeChatDllController {
@ApiOperation(value = "发送消息汇总入口", notes = "sendMsgMaster") @ApiOperation(value = "发送消息汇总入口", notes = "sendMsgMaster")
@PostMapping(value = "/send/msgMaster") @PostMapping(value = "/send/msgMaster")
public TResponse<WxPpWcfSendTextMsgResp> sendMsgMaster(@Validated @RequestBody String jsonString) { public TResponse<WxPpWcfSendTextMsgResp> sendMsgMaster(@Validated @RequestBody String jsonString) {
// todo
return TResponse.ok(ResponseCodeEnum.SUCCESS); return TResponse.ok(ResponseCodeEnum.SUCCESS);
} }
@ApiOperation(value = "发送文本消息(可 @", notes = "sendTextMsg") @ApiOperation(value = "发送文本消息", notes = "sendTextMsg")
@PostMapping(value = "/send/textMsg") @PostMapping(value = "/send/textMsg")
public TResponse<WxPpWcfSendTextMsgResp> sendTextMsg(@Validated @RequestBody WxPpWcfSendTextMsgReq request) { public TResponse<WxPpWcfSendTextMsgResp> sendTextMsg(@Validated @RequestBody WxPpWcfSendTextMsgReq request) {
WxPpWcfSendTextMsgResp resp = weChatDllService.sendTextMsg(request); WxPpWcfSendTextMsgResp resp = weChatDllService.sendTextMsg(request);
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
} }
@ApiOperation(value = "发送图片消息", notes = "sendImageMsg")
@PostMapping(value = "/send/imageMsg")
public TResponse<WxPpWcfSendImageMsgResp> 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<WxPpWcfSendFileMsgResp> 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<WxPpWcfSendXmlMsgResp> 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<WxPpWcfSendEmojiMsgResp> sendEmojiMsg(@Validated @RequestBody WxPpWcfSendEmojiMsgReq request) {
WxPpWcfSendEmojiMsgResp resp = weChatDllService.sendEmojiMsg(request);
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
}
@ApiOperation(value = "发送富文本消息", notes = "sendRichTextMsg") @ApiOperation(value = "发送富文本消息", notes = "sendRichTextMsg")
@PostMapping(value = "/send/richTextMsg") @PostMapping(value = "/send/richTextMsg")
public TResponse<WxPpWcfSendRichTextMsgResp> sendRichTextMsg(@Validated @RequestBody WxPpWcfSendRichTextMsgReq request) { public TResponse<WxPpWcfSendRichTextMsgResp> sendRichTextMsg(@Validated @RequestBody WxPpWcfSendRichTextMsgReq request) {
@ -176,6 +143,34 @@ public class WeChatDllController {
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
} }
@ApiOperation(value = "发送XML消息", notes = "sendXmlMsg")
@PostMapping(value = "/send/xmlMsg")
public TResponse<WxPpWcfSendXmlMsgResp> 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<WxPpWcfSendImageMsgResp> 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<WxPpWcfSendEmojiMsgResp> 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<WxPpWcfSendFileMsgResp> sendFileMsg(@Validated @RequestBody WxPpWcfSendFileMsgReq request) {
WxPpWcfSendFileMsgResp resp = weChatDllService.sendFileMsg(request);
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
}
@ApiOperation(value = "拍一拍群友", notes = "patOnePat") @ApiOperation(value = "拍一拍群友", notes = "patOnePat")
@PostMapping(value = "/patOnePat") @PostMapping(value = "/patOnePat")
public TResponse<WxPpWcfSendPatOnePatMsgResp> patOnePat(@Validated @RequestBody WxPpWcfPatOnePatMsgReq request) { public TResponse<WxPpWcfSendPatOnePatMsgResp> patOnePat(@Validated @RequestBody WxPpWcfPatOnePatMsgReq request) {
@ -183,6 +178,12 @@ public class WeChatDllController {
return TResponse.ok(ResponseCodeEnum.SUCCESS, resp); return TResponse.ok(ResponseCodeEnum.SUCCESS, resp);
} }
// @ApiOperation(value = "获取语音消息", notes = "queryMsgTypeList")
// @PostMapping(value = "/list/voiceMsg")
// public TResponse<Object> queryVoiceMsg() {
// return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
// }
// @ApiOperation(value = "撤回消息", notes = "queryMsgTypeList") // @ApiOperation(value = "撤回消息", notes = "queryMsgTypeList")
// @PostMapping(value = "/list/msgType") // @PostMapping(value = "/list/msgType")
// public TResponse<Object> queryMsgTypeList() { // public TResponse<Object> queryMsgTypeList() {

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -17,12 +19,14 @@ public class WxPpWcfDatabaseSqlReq {
/** /**
* 数据库名称 * 数据库名称
*/ */
@NotBlank(message = "数据库名称不能为空")
@ApiModelProperty(value = "数据库名称") @ApiModelProperty(value = "数据库名称")
private String databaseName; private String databaseName;
/** /**
* SQL语句 * SQL语句
*/ */
@NotBlank(message = "SQL语句不能为空")
@ApiModelProperty(value = "SQL语句") @ApiModelProperty(value = "SQL语句")
private String sqlText; private String sqlText;

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -17,6 +19,7 @@ public class WxPpWcfDatabaseTableReq {
/** /**
* 数据库名称 * 数据库名称
*/ */
@NotBlank(message = "数据库名称不能为空")
@ApiModelProperty(value = "数据库名称") @ApiModelProperty(value = "数据库名称")
private String databaseName; private String databaseName;

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -17,6 +19,7 @@ public class WxPpWcfGroupMemberReq {
/** /**
* 群编号 * 群编号
*/ */
@NotBlank(message = "群编号不能为空")
@ApiModelProperty(value = "群编号") @ApiModelProperty(value = "群编号")
private String groupNo; private String groupNo;

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -19,13 +21,15 @@ public class WxPpWcfPatOnePatMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;
/** /**
* 要拍的wxid * 要拍的人的wxid
*/ */
@ApiModelProperty(value = "要拍的wxid") @NotBlank(message = "要拍的人的wxid不能为空")
@ApiModelProperty(value = "要拍的人的wxid")
private String patUser; private String patUser;
} }

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -18,6 +20,7 @@ public class WxPpWcfSendEmojiMsgReq {
* 资源路径-本地表情路径 * 资源路径-本地表情路径
* 需要确保图片路径正确建议使用绝对路径使用双斜杠\\ * 需要确保图片路径正确建议使用绝对路径使用双斜杠\\
*/ */
@NotBlank(message = "资源路径不能为空")
@ApiModelProperty(value = "资源路径-本地表情路径") @ApiModelProperty(value = "资源路径-本地表情路径")
private String resourcePath; private String resourcePath;
@ -26,6 +29,7 @@ public class WxPpWcfSendEmojiMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -17,6 +19,7 @@ public class WxPpWcfSendFileMsgReq {
/** /**
* 资源路径-本地文件路径 * 资源路径-本地文件路径
*/ */
@NotBlank(message = "资源路径不能为空")
@ApiModelProperty(value = "资源路径-本地文件路径") @ApiModelProperty(value = "资源路径-本地文件路径")
private String resourcePath; private String resourcePath;
@ -25,6 +28,7 @@ public class WxPpWcfSendFileMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;

View File

@ -1,5 +1,7 @@
package com.wechat.ferry.entity.vo.request; package com.wechat.ferry.entity.vo.request;
import javax.validation.constraints.NotBlank;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -20,6 +22,7 @@ public class WxPpWcfSendImageMsgReq {
* `C:/Projs/WeChatRobot/TEQuant.jpeg` * `C:/Projs/WeChatRobot/TEQuant.jpeg`
* `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg` * `https://raw.githubusercontent.com/lich0821/WeChatFerry/master/assets/TEQuant.jpg`
*/ */
@NotBlank(message = "资源路径不能为空")
@ApiModelProperty(value = "资源路径-本地图片地址") @ApiModelProperty(value = "资源路径-本地图片地址")
private String resourcePath; private String resourcePath;
@ -28,6 +31,7 @@ public class WxPpWcfSendImageMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;

View File

@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank;
/** /**
* 请求入参-个微WCF发送富文本消息 * 请求入参-个微WCF发送富文本消息
* *
@ -19,6 +21,7 @@ public class WxPpWcfSendRichTextMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;

View File

@ -1,11 +1,13 @@
package com.wechat.ferry.entity.vo.request; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* 请求入参-个微WCF发送文本消息 * 请求入参-个微WCF发送文本消息
* *
@ -21,6 +23,7 @@ public class WxPpWcfSendTextMsgReq {
* 消息内容如果是 @ 消息则需要有跟 @ 的人数量相同的 @ * 消息内容如果是 @ 消息则需要有跟 @ 的人数量相同的 @
* 换行使用 `\\\\n` 单杠 * 换行使用 `\\\\n` 单杠
*/ */
@NotBlank(message = "消息文本不能为空")
@ApiModelProperty(value = "消息文本") @ApiModelProperty(value = "消息文本")
private String msgText; private String msgText;
@ -29,6 +32,7 @@ public class WxPpWcfSendTextMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;

View File

@ -1,5 +1,8 @@
package com.wechat.ferry.entity.vo.request; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -19,12 +22,14 @@ public class WxPpWcfSendXmlMsgReq {
* 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx * 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx
* 群聊为 roomidxxxxxxxxxx@chatroom * 群聊为 roomidxxxxxxxxxx@chatroom
*/ */
@NotBlank(message = "消息接收人不能为空")
@ApiModelProperty(value = "消息接收人") @ApiModelProperty(value = "消息接收人")
private String recipient; private String recipient;
/** /**
* XML报文内容 * XML报文内容
*/ */
@NotBlank(message = "XML报文内容不能为空")
@ApiModelProperty(value = "XML报文内容") @ApiModelProperty(value = "XML报文内容")
private String xmlContent; private String xmlContent;
@ -35,9 +40,10 @@ public class WxPpWcfSendXmlMsgReq {
private String resourcePath; private String resourcePath;
/** /**
* xml类型0x21 为小程序 * XML类型21 为小程序
*/ */
@ApiModelProperty(value = "xml类型") @NotNull(message = "XML类型不能为空")
private Integer xmlType; @ApiModelProperty(value = "XML类型")
private String xmlType;
} }

View File

@ -30,6 +30,6 @@ public class WxPpWcfDatabaseFieldResp {
* 字段值 * 字段值
*/ */
@ApiModelProperty(value = "字段值") @ApiModelProperty(value = "字段值")
private String value; private Object value;
} }

View File

@ -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;
}

View File

@ -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集合 keycode val枚举
*/
public static final Map<String, DatabaseNameEnum> codeMap = Arrays.stream(values()).collect(Collectors.toMap(DatabaseNameEnum::getCode, v -> v));
/**
* 根据code获取枚举
*/
public static DatabaseNameEnum getCodeMap(String code) {
return codeMap.getOrDefault(code, UN_MATCH);
}
}

View File

@ -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集合 keycode val枚举
*/
public static final Map<String, TableNameEnum> codeMap = Arrays.stream(values()).collect(Collectors.toMap(TableNameEnum::getCode, v -> v));
/**
* 根据code获取枚举
*/
public static TableNameEnum getCodeMap(String code) {
return codeMap.getOrDefault(code, UN_MATCH);
}
}

View File

@ -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集合 keycode val枚举
*/
public static final Map<String, WxContactsMixedEnum> 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集合 keycode val名称
*/
public static Map<String, String> toCodeNameMap() {
Map<String, String> map = new HashMap<>();
for (WxContactsMixedEnum val : WxContactsMixedEnum.values()) {
if (!ObjectUtils.isEmpty(val.getCode())) {
map.put(val.getCode(), val.getName());
}
}
return map;
}
}

View File

@ -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集合 keycode val枚举
*/
public static final Map<String, WxContactsOfficialEnum> 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集合 keycode val名称
*/
public static Map<String, String> toCodeNameMap() {
Map<String, String> map = new HashMap<>();
for (WxContactsOfficialEnum val : WxContactsOfficialEnum.values()) {
if (!ObjectUtils.isEmpty(val.getCode())) {
map.put(val.getCode(), val.getName());
}
}
return map;
}
}

View File

@ -2,9 +2,7 @@ package com.wechat.ferry.handle;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
@ -13,20 +11,15 @@ import org.springframework.util.ObjectUtils;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.sun.jna.Native; import com.sun.jna.Native;
import com.wechat.ferry.entity.dto.WxPpMsgDTO; 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.DbQuery;
import com.wechat.ferry.entity.proto.Wcf.DbRow; 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.DecPath;
import com.wechat.ferry.entity.proto.Wcf.Functions; import com.wechat.ferry.entity.proto.Wcf.Functions;
import com.wechat.ferry.entity.proto.Wcf.MemberMgmt; import com.wechat.ferry.entity.proto.Wcf.MemberMgmt;
import com.wechat.ferry.entity.proto.Wcf.Request; import com.wechat.ferry.entity.proto.Wcf.Request;
import com.wechat.ferry.entity.proto.Wcf.Response; 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.Verification;
import com.wechat.ferry.entity.proto.Wcf.WxMsg; import com.wechat.ferry.entity.proto.Wcf.WxMsg;
import com.wechat.ferry.enums.SexEnum;
import com.wechat.ferry.service.SDK; import com.wechat.ferry.service.SDK;
import com.wechat.ferry.utils.HttpClientUtil; import com.wechat.ferry.utils.HttpClientUtil;
import com.wechat.ferry.utils.XmlJsonConvertUtil; import com.wechat.ferry.utils.XmlJsonConvertUtil;
@ -149,53 +142,6 @@ public class WeChatSocketClient {
return false; 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<Integer, String> 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<RpcContact> 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执行结果 * 获取sql执行结果
* *
@ -213,141 +159,6 @@ public class WeChatSocketClient {
return null; return null;
} }
/**
* 获取所有数据库名
*
* @return 数据库名称列表
*/
public List<String> 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<String, String> getDbTables(String db) {
Request req = Request.newBuilder().setFuncValue(Functions.FUNC_GET_DB_TABLES_VALUE).setStr(db).build();
Response rsp = sendCmd(req);
Map<String, String> tables = new HashMap<>();
if (rsp != null) {
for (DbTable tbl : rsp.getTables().getTablesList()) {
tables.put(tbl.getName(), tbl.getSql());
}
}
return tables;
}
/**
* @param msg: 消息内容如果是 @ 消息则需要有跟 @ 的人数量相同的 @
* @param receiver: 消息接收人私聊为 wxidwxid_xxxxxxxxxxxxxx群聊为
* roomidxxxxxxxxxx@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 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() { public boolean getIsReceivingMsg() {
return isReceivingMsg; return isReceivingMsg;
} }
@ -434,10 +231,11 @@ public class WeChatSocketClient {
* *
* @param wxMsgXml XML消息 * @param wxMsgXml XML消息
* @param wxMsgContent 消息内容 * @param wxMsgContent 消息内容
* @param selfWxId 自己的微信id
* @return 是否 * @return 是否
*/ */
public boolean isAtMeMsg(String wxMsgXml, String wxMsgContent) { public boolean isAtMeMsg(String wxMsgXml, String wxMsgContent, String selfWxId) {
String format = String.format("<atuserlist><![CDATA[%s]]></atuserlist>", getSelfWxId()); String format = String.format("<atuserlist><![CDATA[%s]]></atuserlist>", selfWxId);
boolean isAtAll = wxMsgContent.startsWith("@所有人") || wxMsgContent.startsWith("@all"); boolean isAtAll = wxMsgContent.startsWith("@所有人") || wxMsgContent.startsWith("@all");
if (wxMsgXml.contains(format) && !isAtAll) { if (wxMsgXml.contains(format) && !isAtAll) {
return true; return true;
@ -517,21 +315,6 @@ public class WeChatSocketClient {
} }
} }
public void printContacts(List<RpcContact> 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) { public void printWxMsg(WxMsg msg) {
WxPpMsgDTO dto = new WxPpMsgDTO(); WxPpMsgDTO dto = new WxPpMsgDTO();
dto.setIsSelf(msg.getIsSelf()); dto.setIsSelf(msg.getIsSelf());
@ -551,7 +334,7 @@ public class WeChatSocketClient {
log.info("收到消息: {}", jsonString); log.info("收到消息: {}", jsonString);
} }
private String bytesToHex(byte[] bytes) { public String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (byte b : bytes) { for (byte b : bytes) {
sb.append(String.format("%02x", b)); sb.append(String.format("%02x", b));

View File

@ -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.request.WxPpWcfSendXmlMsgReq;
import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp; import com.wechat.ferry.entity.vo.response.WxPpWcfContactsResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; 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.WxPpWcfGroupMemberResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp;
@ -45,6 +46,7 @@ public interface WeChatDllService {
/** /**
* 获取登录微信内部识别号UID * 获取登录微信内部识别号UID
* 获得微信客户端登录的微信ID
* *
* @return 微信内部识别号UID * @return 微信内部识别号UID
* *
@ -64,7 +66,7 @@ public interface WeChatDllService {
WxPpWcfLoginInfoResp queryLoginWeChatInfo(); WxPpWcfLoginInfoResp queryLoginWeChatInfo();
/** /**
* 获取所有消息类型 * 获取消息类型列表
* *
* @return 消息类型列表 * @return 消息类型列表
* *
@ -74,7 +76,7 @@ public interface WeChatDllService {
List<WxPpWcfMsgTypeResp> queryMsgTypeList(); List<WxPpWcfMsgTypeResp> queryMsgTypeList();
/** /**
* 获取所有联系人 * 获取联系人列表
* *
* @return 联系人列表 * @return 联系人列表
* *
@ -84,28 +86,17 @@ public interface WeChatDllService {
List<WxPpWcfContactsResp> queryContactsList(); List<WxPpWcfContactsResp> queryContactsList();
/** /**
* 获取数据库所有表名称 * 获取数据库表名称列表
* *
* @return 数据库名称列表 * @return 数据库名称列表
* *
* @author chandler * @author chandler
* @date 2024-10-02 17:53 * @date 2024-10-02 17:53
*/ */
List<String> queryDatabaseAllTableName(); List<String> queryDbTableNameList();
/** /**
* 获取可查询数据库 * 获取指定数据库中的所有表
*
* @param request 请求入参
* @return 数据库记录
*
* @author chandler
* @date 2024-10-02 17:52
*/
List<WxPpWcfDatabaseRowResp> queryDatabaseSql(WxPpWcfDatabaseSqlReq request);
/**
* 获取数据库表
* *
* @param request 请求入参 * @param request 请求入参
* @return 数据库记录 * @return 数据库记录
@ -113,7 +104,18 @@ public interface WeChatDllService {
* @author chandler * @author chandler
* @date 2024-10-02 17:52 * @date 2024-10-02 17:52
*/ */
List<String> queryDatabaseTable(WxPpWcfDatabaseTableReq request); List<WxPpWcfDatabaseTableResp> queryDbTableList(WxPpWcfDatabaseTableReq request);
/**
* 执行数据库查询SQL
*
* @param request 请求入参
* @return 数据库记录
*
* @author chandler
* @date 2024-10-02 17:52
*/
List<WxPpWcfDatabaseRowResp> execDbQuerySql(WxPpWcfDatabaseSqlReq request);
/** /**
* 查询群成员 * 查询群成员
@ -140,26 +142,15 @@ public interface WeChatDllService {
WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request); WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request);
/** /**
* 发送图片消息 * 发送富文本消息
* *
* @param request 请求入参 * @param request 请求入参
* @return 消息发送返回 * @return 消息发送返回
* *
* @author chandler * @author chandler
* @date 2024-10-04 23:06 * @date 2024-10-06 15:48
*/ */
WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request); WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request);
/**
* 发送文件消息
*
* @param request 请求入参
* @return 消息发送返回
*
* @author chandler
* @date 2024-10-04 23:15
*/
WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request);
/** /**
* 发送XML消息 * 发送XML消息
@ -172,6 +163,17 @@ public interface WeChatDllService {
*/ */
WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request); 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); WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request);
/** /**
* 发送富文本消息 * 发送文件消息
* *
* @param request 请求入参 * @param request 请求入参
* @return 消息发送返回 * @return 消息发送返回
* *
* @author chandler * @author chandler
* @date 2024-10-06 15:48 * @date 2024-10-04 23:15
*/ */
WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request); WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request);
/** /**
* 拍一拍 * 拍一拍

View File

@ -3,7 +3,6 @@ package com.wechat.ferry.service.impl;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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.WxPpWcfContactsResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseFieldResp; import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseFieldResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfDatabaseRowResp; 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.WxPpWcfGroupMemberResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp; import com.wechat.ferry.entity.vo.response.WxPpWcfLoginInfoResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfMsgTypeResp; 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.WxPpWcfSendRichTextMsgResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp; import com.wechat.ferry.entity.vo.response.WxPpWcfSendTextMsgResp;
import com.wechat.ferry.entity.vo.response.WxPpWcfSendXmlMsgResp; 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.MsgFwdTypeEnum;
import com.wechat.ferry.enums.SexEnum; 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.enums.WxContactsTypeEnum;
import com.wechat.ferry.handle.WeChatSocketClient; import com.wechat.ferry.handle.WeChatSocketClient;
import com.wechat.ferry.service.WeChatDllService; import com.wechat.ferry.service.WeChatDllService;
@ -76,37 +79,53 @@ public class WeChatDllServiceImpl implements WeChatDllService {
@Override @Override
public Boolean loginStatus() { public Boolean loginStatus() {
long startTime = System.currentTimeMillis();
Boolean status = wechatSocketClient.isLogin(); Boolean status = wechatSocketClient.isLogin();
log.info("[查询]-[登录状态]-status:{}", status); long endTime = System.currentTimeMillis();
log.info("[查询]-[登录状态]-耗时:{}msstatus:{}", (endTime - startTime), status);
return status; return status;
} }
@Override @Override
public String queryLoginWeChatUid() { public String queryLoginWeChatUid() {
String weChatUid = wechatSocketClient.getSelfWxId(); long startTime = System.currentTimeMillis();
log.info("[查询]-[登录微信UID]-weChatUid:{}", weChatUid); 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; return weChatUid;
} }
@Override @Override
public WxPpWcfLoginInfoResp queryLoginWeChatInfo() { public WxPpWcfLoginInfoResp queryLoginWeChatInfo() {
long startTime = System.currentTimeMillis();
WxPpWcfLoginInfoResp resp = new WxPpWcfLoginInfoResp(); WxPpWcfLoginInfoResp resp = new WxPpWcfLoginInfoResp();
Wcf.UserInfo userInfo = wechatSocketClient.getUserInfo(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_USER_INFO_VALUE).build();
if (!ObjectUtils.isEmpty(userInfo)) { Wcf.Response rsp = wechatSocketClient.sendCmd(req);
if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getUi())) {
Wcf.UserInfo userInfo = rsp.getUi();
resp.setWeChatUid(userInfo.getWxid()); resp.setWeChatUid(userInfo.getWxid());
resp.setWeChatNickname(userInfo.getName()); resp.setWeChatNickname(userInfo.getName());
resp.setPhone(userInfo.getMobile()); resp.setPhone(userInfo.getMobile());
resp.setHomePath(userInfo.getHome()); resp.setHomePath(userInfo.getHome());
} }
log.info("[查询]-[获取登录微信信息]-resp:{}", resp); long endTime = System.currentTimeMillis();
log.info("[查询]-[获取登录微信信息]-耗时:{}ms登录信息:{}", (endTime - startTime), resp);
return resp; return resp;
} }
@Override @Override
public List<WxPpWcfMsgTypeResp> queryMsgTypeList() { public List<WxPpWcfMsgTypeResp> queryMsgTypeList() {
long startTime = System.currentTimeMillis();
List<WxPpWcfMsgTypeResp> list = new ArrayList<>(); List<WxPpWcfMsgTypeResp> list = new ArrayList<>();
Map<Integer, String> msgTypeMap = wechatSocketClient.getMsgTypes(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_MSG_TYPES_VALUE).build();
if (!CollectionUtils.isEmpty(msgTypeMap)) { Wcf.Response rsp = wechatSocketClient.sendCmd(req);
if (!ObjectUtils.isEmpty(rsp)) {
Map<Integer, String> msgTypeMap = rsp.getTypes().getTypesMap();
WxPpWcfMsgTypeResp resp; WxPpWcfMsgTypeResp resp;
for (Map.Entry<Integer, String> entry : msgTypeMap.entrySet()) { for (Map.Entry<Integer, String> entry : msgTypeMap.entrySet()) {
resp = new WxPpWcfMsgTypeResp(); resp = new WxPpWcfMsgTypeResp();
@ -115,15 +134,19 @@ public class WeChatDllServiceImpl implements WeChatDllService {
list.add(resp); list.add(resp);
} }
} }
log.info("[查询]-[所有消息类型]-共查到:{}条", list.size()); long endTime = System.currentTimeMillis();
log.info("[查询]-[所有消息类型]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime));
return list; return list;
} }
@Override @Override
public List<WxPpWcfContactsResp> queryContactsList() { public List<WxPpWcfContactsResp> queryContactsList() {
long startTime = System.currentTimeMillis();
List<WxPpWcfContactsResp> list = new ArrayList<>(); List<WxPpWcfContactsResp> list = new ArrayList<>();
List<Wcf.RpcContact> rpcContactList = wechatSocketClient.getContacts(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_GET_CONTACTS_VALUE).build();
if (!CollectionUtils.isEmpty(rpcContactList)) { Wcf.Response rsp = wechatSocketClient.sendCmd(req);
if (!ObjectUtils.isEmpty(rsp) && !ObjectUtils.isEmpty(rsp.getContacts()) && !CollectionUtils.isEmpty(rsp.getContacts().getContactsList())) {
List<Wcf.RpcContact> rpcContactList = rsp.getContacts().getContactsList();
for (Wcf.RpcContact rpcContact : rpcContactList) { for (Wcf.RpcContact rpcContact : rpcContactList) {
WxPpWcfContactsResp vo = new WxPpWcfContactsResp(); WxPpWcfContactsResp vo = new WxPpWcfContactsResp();
vo.setWeChatUid(rpcContact.getWxid()); vo.setWeChatUid(rpcContact.getWxid());
@ -151,32 +174,14 @@ public class WeChatDllServiceImpl implements WeChatDllService {
} }
// 微信类型 // 微信类型
if (!ObjectUtils.isEmpty(rpcContact.getWxid())) { if (!ObjectUtils.isEmpty(rpcContact.getWxid())) {
List<String> mixedNoList = new ArrayList<>(); // 官方杂号集合
// 朋友推荐消息 Map<String, String> mixedNoMap = WxContactsMixedEnum.toCodeNameMap();
mixedNoList.add("fmessage"); mixedNoMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeMixed()));
// 语音记事本 // 公众号
mixedNoList.add("medianote"); Map<String, String> officialMap = WxContactsOfficialEnum.toCodeNameMap();
// 漂流瓶 officialMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeOfficial()));
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");
// 类型判断,存在优先级的官方杂号优先级高于微信公众号(如果定义重复了常规禁止重复手机端和电脑端分类不同)
if (rpcContact.getWxid().endsWith(WxContactsTypeEnum.WORK.getAffix())) { if (rpcContact.getWxid().endsWith(WxContactsTypeEnum.WORK.getAffix())) {
// 企微 // 企微
vo.setType(WxContactsTypeEnum.WORK.getCode()); vo.setType(WxContactsTypeEnum.WORK.getCode());
@ -185,7 +190,7 @@ public class WeChatDllServiceImpl implements WeChatDllService {
// 群聊 @im.chatroom 这种是很早之前的格式单独例举 // 群聊 @im.chatroom 这种是很早之前的格式单独例举
vo.setType(WxContactsTypeEnum.GROUP.getCode()); vo.setType(WxContactsTypeEnum.GROUP.getCode());
vo.setTypeLabel(WxContactsTypeEnum.GROUP.getName()); 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.setType(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getCode());
vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getName()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_MIXED_NO.getName());
@ -193,14 +198,7 @@ public class WeChatDllServiceImpl implements WeChatDllService {
// 微信公众号 // 微信公众号
vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode());
vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName());
} else if ("wxid_2876568766325".equals(rpcContact.getWxid()) || "wxid_2965349653612".equals(rpcContact.getWxid()) } else if (officialMap.containsKey(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
vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode()); vo.setType(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getCode());
vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName()); vo.setTypeLabel(WxContactsTypeEnum.OFFICIAL_ACCOUNT.getName());
} else { } else {
@ -212,19 +210,49 @@ public class WeChatDllServiceImpl implements WeChatDllService {
list.add(vo); list.add(vo);
} }
} }
log.info("[查询]-[联系人]-共查到:{}条", list.size()); long endTime = System.currentTimeMillis();
log.info("[查询]-[联系人]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime));
return list; return list;
} }
@Override @Override
public List<String> queryDatabaseAllTableName() { public List<String> queryDbTableNameList() {
List<String> list = wechatSocketClient.getDbNames(); long startTime = System.currentTimeMillis();
log.info("[查询]-[数据库名称列表]-共查到:{}条", list.size()); List<String> 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; return list;
} }
@Override @Override
public List<WxPpWcfDatabaseRowResp> queryDatabaseSql(WxPpWcfDatabaseSqlReq request) { public List<WxPpWcfDatabaseTableResp> queryDbTableList(WxPpWcfDatabaseTableReq request) {
long startTime = System.currentTimeMillis();
log.info("[查询]-[数据库表列表]-request:{}", request);
List<WxPpWcfDatabaseTableResp> 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<WxPpWcfDatabaseRowResp> execDbQuerySql(WxPpWcfDatabaseSqlReq request) {
long startTime = System.currentTimeMillis();
List<WxPpWcfDatabaseRowResp> list = new ArrayList<>(); List<WxPpWcfDatabaseRowResp> list = new ArrayList<>();
List<Wcf.DbRow> wcfList = wechatSocketClient.querySql(request.getDatabaseName(), request.getSqlText()); List<Wcf.DbRow> wcfList = wechatSocketClient.querySql(request.getDatabaseName(), request.getSqlText());
if (!CollectionUtils.isEmpty(wcfList)) { if (!CollectionUtils.isEmpty(wcfList)) {
@ -233,9 +261,15 @@ public class WeChatDllServiceImpl implements WeChatDllService {
List<WxPpWcfDatabaseFieldResp> fieldVoList = new ArrayList<>(); List<WxPpWcfDatabaseFieldResp> fieldVoList = new ArrayList<>();
for (Wcf.DbField dbField : dbRow.getFieldsList()) { for (Wcf.DbField dbField : dbRow.getFieldsList()) {
WxPpWcfDatabaseFieldResp fieldVo = new WxPpWcfDatabaseFieldResp(); 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.setType(String.valueOf(dbField.getType()));
fieldVo.setColumn(dbField.getColumn()); fieldVo.setColumn(dbField.getColumn());
String value = (String)converterSqlVal(dbField.getType(), dbField.getContent());
fieldVo.setValue(value); fieldVo.setValue(value);
fieldVoList.add(fieldVo); fieldVoList.add(fieldVo);
} }
@ -243,30 +277,23 @@ public class WeChatDllServiceImpl implements WeChatDllService {
list.add(rowVo); list.add(rowVo);
} }
} }
log.info("[查询]-[获取可查询数据库]-wcfList:{}", wcfList); long endTime = System.currentTimeMillis();
log.info("[查询]-[执行数据库查询SQL]-共查到:{}条,耗时:{}ms", list.size(), (endTime - startTime));
return list; return list;
} }
@Override
public List<String> queryDatabaseTable(WxPpWcfDatabaseTableReq request) {
log.info("[查询]-[查询表]-request:{}", request);
Map<String, String> wcfMap = wechatSocketClient.getDbTables(request.getDatabaseName());
// TODO 待建模
log.info("[查询]-[查询表]-查到:{}", wcfMap);
return Collections.emptyList();
}
@Override @Override
public List<WxPpWcfGroupMemberResp> queryGroupMember(WxPpWcfGroupMemberReq request) { public List<WxPpWcfGroupMemberResp> queryGroupMember(WxPpWcfGroupMemberReq request) {
long startTime = System.currentTimeMillis();
List<WxPpWcfGroupMemberResp> list = new ArrayList<>(); List<WxPpWcfGroupMemberResp> list = new ArrayList<>();
// 查询群成员 // 查询群成员
List<Wcf.DbRow> wcfList = new ArrayList<>(); List<Wcf.DbRow> wcfList = new ArrayList<>();
if (!ObjectUtils.isEmpty(request.getGroupNo())) { if (!ObjectUtils.isEmpty(request.getGroupNo())) {
wcfList = wcfList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(),
wechatSocketClient.querySql("MicroMsg.db", "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';"); "SELECT RoomData FROM ChatRoom WHERE ChatRoomName = '" + request.getGroupNo() + "';");
} }
// 查询联系人 // 查询联系人
List<Wcf.DbRow> dbList = wechatSocketClient.querySql("MicroMsg.db", "SELECT UserName, NickName, Type FROM Contact;"); List<Wcf.DbRow> dbList = wechatSocketClient.querySql(DatabaseNameEnum.MICRO_MSG.getCode(), "SELECT UserName, NickName, Type FROM Contact;");
Map<String, String> dbMap = new HashMap<>(); Map<String, String> dbMap = new HashMap<>();
if (!CollectionUtils.isEmpty(dbList)) { if (!CollectionUtils.isEmpty(dbList)) {
for (Wcf.DbRow dbRow : dbList) { for (Wcf.DbRow dbRow : dbList) {
@ -276,11 +303,11 @@ public class WeChatDllServiceImpl implements WeChatDllService {
for (Wcf.DbField dbField : dbFieldList) { for (Wcf.DbField dbField : dbFieldList) {
if ("UserName".equals(dbField.getColumn())) { if ("UserName".equals(dbField.getColumn())) {
vo = new WxPpWcfGroupMemberResp(); vo = new WxPpWcfGroupMemberResp();
String content = (String)converterSqlVal(dbField.getType(), dbField.getContent()); String content = (String)convertSqlVal(dbField.getType(), dbField.getContent());
vo.setWeChatUid(content); vo.setWeChatUid(content);
} }
if ("NickName".equals(dbField.getColumn())) { if ("NickName".equals(dbField.getColumn())) {
String content = (String)converterSqlVal(dbField.getType(), dbField.getContent()); String content = (String)convertSqlVal(dbField.getType(), dbField.getContent());
vo.setGroupNickName(content); vo.setGroupNickName(content);
dbMap.put(vo.getWeChatUid(), vo.getGroupNickName()); 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; return list;
} }
@Override @Override
public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) { public WxPpWcfSendTextMsgResp sendTextMsg(WxPpWcfSendTextMsgReq request) {
long startTime = System.currentTimeMillis();
log.info("[发送消息]-[文本消息]-入参打印:{}", request); log.info("[发送消息]-[文本消息]-入参打印:{}", request);
String atUser = ""; String atUser = "";
if (request.getIsAtAll()) { if (request.getIsAtAll()) {
@ -337,85 +366,136 @@ public class WeChatDllServiceImpl implements WeChatDllService {
atUser = String.join(",", 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 为成功其他失败 // 0 为成功其他失败
int state = wechatSocketClient.sendText(request.getMsgText(), request.getRecipient(), atUser); int state = judgeSendMsgState(rsp);
log.info("[发送消息]-[文本消息]-处理结束");
// 转发处理 // 转发处理
String stringJson = JSON.toJSONString(request); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); sendMsgForward(stringJson, state);
long endTime = System.currentTimeMillis();
log.info("[发送消息]-[文本消息]-处理结束,耗时:{}ms", (endTime - startTime));
return null; return null;
} }
@Override @Override
public WxPpWcfSendImageMsgResp sendImageMsg(WxPpWcfSendImageMsgReq request) { public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) {
WxPpWcfSendImageMsgResp resp = new WxPpWcfSendImageMsgResp(); long startTime = System.currentTimeMillis();
int state = wechatSocketClient.sendImage(request.getResourcePath(), request.getRecipient()); log.info("[发送消息]-[富文本消息]-入参打印:{}", request);
// 转发处理 Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle())
String stringJson = JSON.toJSONString(request); .setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient())
sendMsgForward(stringJson, state); .build();
return null; 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);
@Override int state = judgeSendMsgState(rsp);
public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) {
int state = wechatSocketClient.sendFile(request.getResourcePath(), request.getRecipient());
// 转发处理 // 转发处理
String stringJson = JSON.toJSONString(request); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); sendMsgForward(stringJson, state);
long endTime = System.currentTimeMillis();
log.info("[发送消息]-[富文本消息]-处理结束,耗时:{}ms", (endTime - startTime));
return null; return null;
} }
@Override @Override
public WxPpWcfSendXmlMsgResp sendXmlMsg(WxPpWcfSendXmlMsgReq request) { 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); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); 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; return null;
} }
@Deprecated @Deprecated
@Override @Override
public WxPpWcfSendEmojiMsgResp sendEmojiMsg(WxPpWcfSendEmojiMsgReq request) { 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); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); sendMsgForward(stringJson, state);
long endTime = System.currentTimeMillis();
log.info("[发送消息]-[表情消息]-处理结束,耗时:{}ms", (endTime - startTime));
return null; return null;
} }
@Override @Override
public WxPpWcfSendRichTextMsgResp sendRichTextMsg(WxPpWcfSendRichTextMsgReq request) { public WxPpWcfSendFileMsgResp sendFileMsg(WxPpWcfSendFileMsgReq request) {
Wcf.RichText richTextMsg = Wcf.RichText.newBuilder().setName(request.getName()).setAccount(request.getAccount()).setTitle(request.getTitle()) long startTime = System.currentTimeMillis();
.setDigest(request.getDigest()).setUrl(request.getJumpUrl()).setThumburl(request.getThumbnailUrl()).setReceiver(request.getRecipient()) log.info("[发送消息]-[文件消息]-入参打印:{}", request);
.build(); Wcf.PathMsg pathMsg = Wcf.PathMsg.newBuilder().setPath(request.getResourcePath()).setReceiver(request.getRecipient()).build();
Wcf.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_RICH_TXT_VALUE).setRt(richTextMsg).build(); Wcf.Request req = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_FILE_VALUE).setFile(pathMsg).build();
Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); log.debug("sendFile: {}", wechatSocketClient.bytesToHex(req.toByteArray()));
int state = judgeState(rsp); Wcf.Response rsp = wechatSocketClient.sendCmd(req);
int state = judgeSendMsgState(rsp);
// 转发处理 // 转发处理
String stringJson = JSON.toJSONString(request); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); sendMsgForward(stringJson, state);
long endTime = System.currentTimeMillis();
log.info("[发送消息]-[文件消息]-处理结束,耗时:{}ms", (endTime - startTime));
return null; return null;
} }
@Override @Override
public WxPpWcfSendPatOnePatMsgResp patOnePat(WxPpWcfPatOnePatMsgReq request) { 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.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.Request wcfReq = Wcf.Request.newBuilder().setFuncValue(Wcf.Functions.FUNC_SEND_PAT_MSG_VALUE).setPm(patMsg).build();
Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq); Wcf.Response rsp = wechatSocketClient.sendCmd(wcfReq);
int state = judgeState(rsp); int state = judgeSendMsgState(rsp);
// 转发处理 // 转发处理
String stringJson = JSON.toJSONString(request); String stringJson = JSON.toJSONString(request);
sendMsgForward(stringJson, state); sendMsgForward(stringJson, state);
long endTime = System.currentTimeMillis();
log.info("[发送消息]-[拍一拍消息]-处理结束,耗时:{}ms", (endTime - startTime));
return null; return null;
} }
/** /**
* 获取SQL类型 * 获取SQL类型
*
* @return 函数
* *
* @param type 转换类型 * @param type 转换类型
* @return 函数
* *
* @author chandler * @author chandler
* @date 2024-10-05 12:54 * @date 2024-10-05 12:54
@ -440,7 +520,7 @@ public class WeChatDllServiceImpl implements WeChatDllService {
* @author chandler * @author chandler
* @date 2024-10-05 12:54 * @date 2024-10-05 12:54
*/ */
public Object converterSqlVal(int type, ByteString content) { public Object convertSqlVal(int type, ByteString content) {
// 根据每一列的类型转换 // 根据每一列的类型转换
Function<byte[], Object> converter = getSqlType(type); Function<byte[], Object> converter = getSqlType(type);
if (converter != null) { if (converter != null) {
@ -535,7 +615,8 @@ public class WeChatDllServiceImpl implements WeChatDllService {
} }
/** /**
* 判断CMD调用状态 * 判断发送消息状态
* 0 为成功其他失败
* *
* @param rsp 响应参数 * @param rsp 响应参数
* @return 状态 * @return 状态
@ -543,7 +624,8 @@ public class WeChatDllServiceImpl implements WeChatDllService {
* @author chandler * @author chandler
* @date 2024-12-23 21:53 * @date 2024-12-23 21:53
*/ */
private int judgeState(Wcf.Response rsp) { private int judgeSendMsgState(Wcf.Response rsp) {
// 0 为成功其他失败
int state = -1; int state = -1;
if (rsp != null) { if (rsp != null) {
state = rsp.getStatus(); state = rsp.getStatus();
@ -551,4 +633,31 @@ public class WeChatDllServiceImpl implements WeChatDllService {
return state; return state;
} }
/**
* 转换联系人类型配置
*
* @param list 配置参数
* @return map key:code val:name
*
* @author chandler
* @date 2024-12-24 16:55
*/
private Map<String, String> convertContactsTypeProperties(List<String> list) {
Map<String, String> 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;
}
} }

View File

@ -26,6 +26,12 @@ wechat:
dll-path: E:\WeChatFerry\clients\java\wechat-ferry-mvn\dll\sdk.dll dll-path: E:\WeChatFerry\clients\java\wechat-ferry-mvn\dll\sdk.dll
# socket端口 # socket端口
socket-port: 10086 socket-port: 10086
# 联系人类型-官方杂号,禁止与其他分类重复(格式:代码|名称)
contacts-type-mixed:
- filehelper|文件传输助手
# 联系人类型-公众号,禁止与其他分类重复(格式:代码|名称)
contacts-type-official:
- weixinguanhaozhushou|微信公众平台
# 需要开启消息处理的群 # 需要开启消息处理的群
open-msg-groups: open-msg-groups:
- 53257911728@chatroom - 53257911728@chatroom