commit
720c695aef
33
clients/java/wechat-ferry-mvn/CHANGELOG.md
vendored
33
clients/java/wechat-ferry-mvn/CHANGELOG.md
vendored
@ -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
|
||||
|
5
clients/java/wechat-ferry-mvn/pom.xml
vendored
5
clients/java/wechat-ferry-mvn/pom.xml
vendored
@ -53,6 +53,11 @@
|
||||
<version>1.18.30</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<!-- swagger3包-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
|
@ -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";
|
||||
|
@ -29,6 +29,18 @@ public class WeChatFerryProperties {
|
||||
*/
|
||||
private Integer socketPort;
|
||||
|
||||
/**
|
||||
* 联系人类型-官方杂号,禁止与其他分类重复(格式:代码|名称)
|
||||
* 使用时记得需要提取代码或者名称匹配
|
||||
*/
|
||||
private List<String> contactsTypeMixed;
|
||||
|
||||
/**
|
||||
* 联系人类型-公众号,禁止与其他分类重复(格式:代码|名称)
|
||||
* 使用时记得需要提取代码或者名称匹配
|
||||
*/
|
||||
private List<String> contactsTypeOfficial;
|
||||
|
||||
/**
|
||||
* 需要开启消息处理的群
|
||||
*/
|
||||
|
@ -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<List<WxPpWcfMsgTypeResp>> queryMsgTypeList() {
|
||||
List<WxPpWcfMsgTypeResp> list = weChatDllService.queryMsgTypeList();
|
||||
return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取联系人", notes = "queryContactsList")
|
||||
@ApiOperation(value = "获取联系人列表", notes = "queryContactsList")
|
||||
@PostMapping(value = "/list/contacts")
|
||||
public TResponse<List<WxPpWcfContactsResp>> queryContactsList() {
|
||||
List<WxPpWcfContactsResp> list = weChatDllService.queryContactsList();
|
||||
return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取数据库所有表名称", notes = "queryDatabaseAllTableName")
|
||||
@ApiOperation(value = "获取数据库表名称列表", notes = "queryDbTableNameList")
|
||||
@PostMapping(value = "/list/dbTableName")
|
||||
public TResponse<List<String>> queryDatabaseAllTableName() {
|
||||
List<String> list = weChatDllService.queryDatabaseAllTableName();
|
||||
public TResponse<List<String>> queryDbTableNameList() {
|
||||
List<String> list = weChatDllService.queryDbTableNameList();
|
||||
return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取可查询数据库", notes = "queryDatabaseSql")
|
||||
@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")
|
||||
@ApiOperation(value = "获取指定数据库中的表列表", notes = "queryDbTableList")
|
||||
@PostMapping(value = "/list/dbTable")
|
||||
public TResponse<List<String>> queryDatabaseTable(@Validated @RequestBody WxPpWcfDatabaseTableReq request) {
|
||||
List<String> list = weChatDllService.queryDatabaseTable(request);
|
||||
public TResponse<List<WxPpWcfDatabaseTableResp>> queryDbTableList(@Validated @RequestBody WxPpWcfDatabaseTableReq request) {
|
||||
List<WxPpWcfDatabaseTableResp> list = weChatDllService.queryDbTableList(request);
|
||||
return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
}
|
||||
|
||||
// @ApiOperation(value = "获取语音消息", notes = "queryMsgTypeList")
|
||||
// @PostMapping(value = "/list/voiceMsg")
|
||||
// public TResponse<Object> queryVoiceMsg() {
|
||||
// return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
// }
|
||||
@ApiOperation(value = "执行数据库查询SQL", notes = "execDbQuerySql")
|
||||
@PostMapping(value = "/exec/dbQuerySql")
|
||||
public TResponse<List<WxPpWcfDatabaseRowResp>> execDbQuerySql(@Validated @RequestBody WxPpWcfDatabaseSqlReq request) {
|
||||
List<WxPpWcfDatabaseRowResp> 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<WxPpWcfSendTextMsgResp> 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<WxPpWcfSendTextMsgResp> 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<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")
|
||||
@PostMapping(value = "/send/richTextMsg")
|
||||
public TResponse<WxPpWcfSendRichTextMsgResp> 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<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")
|
||||
@PostMapping(value = "/patOnePat")
|
||||
public TResponse<WxPpWcfSendPatOnePatMsgResp> 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<Object> queryVoiceMsg() {
|
||||
// return TResponse.ok(ResponseCodeEnum.SUCCESS, list);
|
||||
// }
|
||||
|
||||
// @ApiOperation(value = "撤回消息", notes = "queryMsgTypeList")
|
||||
// @PostMapping(value = "/list/msgType")
|
||||
// public TResponse<Object> queryMsgTypeList() {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,6 @@ public class WxPpWcfDatabaseFieldResp {
|
||||
* 字段值
|
||||
*/
|
||||
@ApiModelProperty(value = "字段值")
|
||||
private String value;
|
||||
private Object value;
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
48
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/DatabaseNameEnum.java
vendored
Normal file
48
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/DatabaseNameEnum.java
vendored
Normal 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集合 key:code 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);
|
||||
}
|
||||
|
||||
}
|
49
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/TableNameEnum.java
vendored
Normal file
49
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/TableNameEnum.java
vendored
Normal 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集合 key:code 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);
|
||||
}
|
||||
|
||||
}
|
90
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsMixedEnum.java
vendored
Normal file
90
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsMixedEnum.java
vendored
Normal 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集合 key:code 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集合 key:code 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;
|
||||
}
|
||||
|
||||
}
|
85
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsOfficialEnum.java
vendored
Normal file
85
clients/java/wechat-ferry-mvn/src/main/java/com/wechat/ferry/enums/WxContactsOfficialEnum.java
vendored
Normal 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集合 key:code 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集合 key:code 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;
|
||||
}
|
||||
|
||||
}
|
@ -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<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执行结果
|
||||
*
|
||||
@ -213,141 +159,6 @@ public class WeChatSocketClient {
|
||||
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: 消息接收人,私聊为 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("<atuserlist><![CDATA[%s]]></atuserlist>", getSelfWxId());
|
||||
public boolean isAtMeMsg(String wxMsgXml, String wxMsgContent, String selfWxId) {
|
||||
String format = String.format("<atuserlist><![CDATA[%s]]></atuserlist>", 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<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) {
|
||||
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));
|
||||
|
@ -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<WxPpWcfMsgTypeResp> queryMsgTypeList();
|
||||
|
||||
/**
|
||||
* 获取所有联系人
|
||||
* 获取联系人列表
|
||||
*
|
||||
* @return 联系人列表
|
||||
*
|
||||
@ -84,28 +86,17 @@ public interface WeChatDllService {
|
||||
List<WxPpWcfContactsResp> queryContactsList();
|
||||
|
||||
/**
|
||||
* 获取数据库所有表名称
|
||||
* 获取数据库表名称列表
|
||||
*
|
||||
* @return 数据库名称列表
|
||||
*
|
||||
* @author chandler
|
||||
* @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 请求入参
|
||||
* @return 数据库记录
|
||||
@ -113,7 +104,18 @@ public interface WeChatDllService {
|
||||
* @author chandler
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 发送图片消息
|
||||
* 发送富文本消息
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 拍一拍
|
||||
|
@ -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<WxPpWcfMsgTypeResp> queryMsgTypeList() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
List<WxPpWcfMsgTypeResp> list = new ArrayList<>();
|
||||
Map<Integer, String> 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<Integer, String> msgTypeMap = rsp.getTypes().getTypesMap();
|
||||
WxPpWcfMsgTypeResp resp;
|
||||
for (Map.Entry<Integer, String> 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<WxPpWcfContactsResp> queryContactsList() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
List<WxPpWcfContactsResp> list = new ArrayList<>();
|
||||
List<Wcf.RpcContact> 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<Wcf.RpcContact> 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<String> 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<String, String> mixedNoMap = WxContactsMixedEnum.toCodeNameMap();
|
||||
mixedNoMap.putAll(convertContactsTypeProperties(weChatFerryProperties.getContactsTypeMixed()));
|
||||
// 公众号
|
||||
Map<String, String> 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<String> queryDatabaseAllTableName() {
|
||||
List<String> list = wechatSocketClient.getDbNames();
|
||||
log.info("[查询]-[数据库名称列表]-共查到:{}条", list.size());
|
||||
public List<String> queryDbTableNameList() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
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;
|
||||
}
|
||||
|
||||
@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<Wcf.DbRow> wcfList = wechatSocketClient.querySql(request.getDatabaseName(), request.getSqlText());
|
||||
if (!CollectionUtils.isEmpty(wcfList)) {
|
||||
@ -233,9 +261,15 @@ public class WeChatDllServiceImpl implements WeChatDllService {
|
||||
List<WxPpWcfDatabaseFieldResp> 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<String> queryDatabaseTable(WxPpWcfDatabaseTableReq request) {
|
||||
log.info("[查询]-[查询表]-request:{}", request);
|
||||
Map<String, String> wcfMap = wechatSocketClient.getDbTables(request.getDatabaseName());
|
||||
// TODO 待建模
|
||||
log.info("[查询]-[查询表]-查到:{}", wcfMap);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WxPpWcfGroupMemberResp> queryGroupMember(WxPpWcfGroupMemberReq request) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
List<WxPpWcfGroupMemberResp> list = new ArrayList<>();
|
||||
// 查询群成员
|
||||
List<Wcf.DbRow> 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<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<>();
|
||||
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<byte[], Object> 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<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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user