feat: 重构模块

This commit is contained in:
ageerle
2025-04-10 17:25:23 +08:00
parent 3be9005f95
commit 2509099146
653 changed files with 1000 additions and 165766 deletions

View File

@@ -1,352 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.ruoyi.common.wechat.itchat4j.core.Core;
import org.ruoyi.common.wechat.itchat4j.core.CoreManage;
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
import org.ruoyi.common.wechat.itchat4j.utils.enums.StorageLoginInfoEnum;
import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 微信小工具,如获好友列表,根据昵称查找好友或群等
*
* @author https://github.com/yaphone
* @date 创建时间2017年5月4日 下午10:49:16
* @version 1.0
*
* @author WesleyOne 修改
*/
public class WechatTools implements LogInterface {
/**
* 返回好友昵称列表
* @param uniqueKey
* @return
*/
public static List<String> getContactNickNameList(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
List<String> contactNickNameList = new ArrayList<String>();
for (JSONObject o : core.getContactList()) {
contactNickNameList.add(o.getString("NickName"));
// 顺便刷下缓存
core.getUserInfoMap().put(o.getString("NickName"),o);
core.getUserInfoMap().put(o.getString("UserName"),o);
}
return contactNickNameList;
}
/**
* 返回好友完整信息列表
* @param uniqueKey
* @return
*/
public static List<JSONObject> getContactList(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
return core.getContactList();
}
/**
* 返回群列表
* @param uniqueKey
* @return
*/
public static List<JSONObject> getGroupList(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
return core.getGroupList();
}
/**
* 获取群NickName列表
* @param uniqueKey
* @return
*/
public static List<String> getGroupNickNameList(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
List<String> groupNickNameList = new ArrayList<String>();
for (JSONObject o : core.getGroupList()) {
groupNickNameList.add(o.getString("NickName"));
}
return groupNickNameList;
}
/**
* 获取群所有成员信息
* @param groupId
* @param uniqueKey
* @return
*/
public static JSONArray getGroupMemberByGroupId(String groupId, String uniqueKey){
Core core = CoreManage.getInstance(uniqueKey);
JSONObject jsonObject = core.getGroupInfoMap().get(groupId);
if (jsonObject == null){
return new JSONArray();
}
return jsonObject.getJSONArray("MemberList");
}
/**
* 通过群成员ID获取昵称
* @param groupId
* @param uniqueKey
* @param memberId
* @return
*/
public static String getMemberNickName(String groupId, String uniqueKey, String memberId){
JSONArray members = getGroupMemberByGroupId(groupId, uniqueKey);
int size = members.size();
if (size > 0){
for (int i=0;i<size;i++){
JSONObject jsonObject = members.getJSONObject(i);
if (memberId.equals(jsonObject.getString("UserName"))){
return jsonObject.getString("NickName");
}
}
}
return "";
}
/**
* 退出微信
*
* @author https://github.com/yaphone
* @date 2017年5月18日 下午11:56:54
*/
public static void logout(String uniqueKey) {
webWxLogout(uniqueKey);
}
private static boolean webWxLogout(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
String url = String.format(URLEnum.WEB_WX_LOGOUT.getUrl(),
core.getLoginInfo().get(StorageLoginInfoEnum.url.getKey()));
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("redirect", "1"));
params.add(new BasicNameValuePair("type", "1"));
params.add(
new BasicNameValuePair("skey", (String) core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey())));
try {
HttpEntity entity = core.getMyHttpClient().doGet(url, params, false, null);
String text = EntityUtils.toString(entity, Consts.UTF_8);
return true;
} catch (Exception e) {
LOG.debug(e.getMessage());
} finally {
// 强制退出,提示相关线程退出
core.setAlive(false);
}
return false;
}
public static void setUserInfo(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
for (JSONObject o : core.getContactList()) {
core.getUserInfoMap().put(o.getString("NickName"), o);
core.getUserInfoMap().put(o.getString("UserName"), o);
}
}
/**
*
* 根据用户昵称设置备注名称
*
* @date 2017年5月27日 上午12:21:40
* @param nickName
* @param remName
*/
public static void remarkNameByNickName(String nickName, String remName, String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
String url = String.format(URLEnum.WEB_WX_REMARKNAME.getUrl(), core.getLoginInfo().get("url"),
core.getLoginInfo().get(StorageLoginInfoEnum.pass_ticket.getKey()));
Map<String, Object> msgMap = new HashMap<String, Object>(8);
Map<String, Object> msgMap_BaseRequest = new HashMap<String, Object>(8);
msgMap.put("CmdId", 2);
msgMap.put("RemarkName", remName);
msgMap.put("UserName", core.getUserInfoMap().get(nickName).get("UserName"));
msgMap_BaseRequest.put("Uin", core.getLoginInfo().get(StorageLoginInfoEnum.wxuin.getKey()));
msgMap_BaseRequest.put("Sid", core.getLoginInfo().get(StorageLoginInfoEnum.wxsid.getKey()));
msgMap_BaseRequest.put("Skey", core.getLoginInfo().get(StorageLoginInfoEnum.skey.getKey()));
msgMap_BaseRequest.put("DeviceID", core.getLoginInfo().get(StorageLoginInfoEnum.deviceid.getKey()));
msgMap.put("BaseRequest", msgMap_BaseRequest);
try {
String paramStr = JSON.toJSONString(msgMap);
HttpEntity entity = core.getMyHttpClient().doPost(url, paramStr);
// String result = EntityUtils.toString(entity, Consts.UTF_8);
LOG.info("修改备注" + remName);
} catch (Exception e) {
LOG.error("remarkNameByUserName", e);
}
}
/**
* 获取微信在线状态
*
* @date 2017年6月16日 上午12:47:46
* @return
*/
public static boolean getWechatStatus(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
return core.isAlive();
}
/**
*
* @param userName
* @param nickName
* @return
*/
private static JSONObject getContactByNickNameAndUserName(String userName, String nickName, String uniqueKey){
Core core = CoreManage.getInstance(uniqueKey);
// 通过userName查询
if (StringUtils.isNotEmpty(userName) && StringUtils.isEmpty(nickName)){
for (JSONObject contact:core.getContactList()){
if (userName.equals(contact.getString("UserName"))){
return contact;
}
}
}
// 通过群昵称查询
if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(userName)){
for (JSONObject contact:core.getContactList()){
if (nickName.equals(contact.getString("NickName"))){
return contact;
}
}
}
// 通过userName和昵称联合查
if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(nickName)){
for (JSONObject contact:core.getContactList()){
if (nickName.equals(contact.getString("NickName")) && userName.equals(contact.getString("UserName"))){
return contact;
}
}
}
return null;
}
/**
* 通过群id查找群昵称
* @param userName
* @return
*/
public static String getContactNickNameByUserName(String userName, String uniqueKey){
JSONObject contact = getContactByNickNameAndUserName(userName,null, uniqueKey);
if (contact!=null && StringUtils.isNotEmpty(contact.getString("NickName"))){
return contact.getString("NickName");
}else{
return "";
}
}
/**
* 通过群昵称查找群id
* @param nickName
* @return
*/
public static String getContactUserNameByNickName(String nickName, String uniqueKey){
JSONObject contact = getContactByNickNameAndUserName(null,nickName,uniqueKey);
if (contact!=null && StringUtils.isNotEmpty(contact.getString("UserName"))){
return contact.getString("UserName");
}else{
return null;
}
}
/**
* 通过userName或昵称查找群信息
* @param userName
* @return
*/
private static JSONObject getGroupByNickNameAndUserName(String userName, String nickName, String uniqueKey){
Core core = CoreManage.getInstance(uniqueKey);
// 通过userName查询
if (StringUtils.isNotEmpty(userName) && StringUtils.isEmpty(nickName)){
for (JSONObject group:core.getGroupList()){
if (userName.equals(group.getString("UserName"))){
return group;
}
}
}
// 通过群昵称查询
if (StringUtils.isNotEmpty(nickName) && StringUtils.isEmpty(userName)){
for (JSONObject group:core.getGroupList()){
if (nickName.equals(group.getString("NickName"))){
return group;
}
}
}
// 通过userName和昵称联合查
if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(nickName)){
for (JSONObject group:core.getGroupList()){
if (nickName.equals(group.getString("NickName")) && userName.equals(group.getString("UserName"))){
return group;
}
}
}
return null;
}
/**
* 通过群id查找群昵称
* @param userName
* @return
*/
public static String getGroupNickNameByUserName(String userName, String uniqueKey){
JSONObject group = getGroupByNickNameAndUserName(userName,null,uniqueKey);
if (group!=null && StringUtils.isNotEmpty(group.getString("NickName"))){
return group.getString("NickName");
}else{
return "";
}
}
/**
* 通过群昵称查找群id
* @param nickName
* @return
*/
public static String getGroupUserNameByNickName(String nickName, String uniqueKey){
JSONObject group = getGroupByNickNameAndUserName(null,nickName, uniqueKey);
if (group!=null && StringUtils.isNotEmpty(group.getString("UserName"))){
return group.getString("UserName");
}else{
return null;
}
}
/**
* 通过UserName查找NickName
* 只查群名和好友名
* @param userName
* @param uniqueKey
* @return
*/
public static String getNickNameByUserName(String userName, String uniqueKey){
if (userName.startsWith("@@")){
return getGroupNickNameByUserName(userName,uniqueKey);
}else if (userName.startsWith("@")){
return getContactNickNameByUserName(userName,uniqueKey);
}else {
return "";
}
}
}

View File

@@ -1,37 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.io.Serializable;
/**
* AppInfo
*
* @author https://github.com/yaphone
* @date 创建时间2017年7月3日 下午10:38:14
* @version 1.0
*
*/
public class AppInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int type;
private String appId;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
}

View File

@@ -1,330 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.io.Serializable;
/**
* 收到的微信消息
*
* @author https://github.com/yaphone
* @date 创建时间2017年7月3日 下午10:28:06
* @version 1.0
*
*/
public class BaseMsg implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int subMsgType;
private int voiceLength;
private String fileName;
private int imgHeight;
private String toUserName;
private int hasProductId;
private int imgStatus;
private String url;
private int imgWidth;
private int forwardFlag;
private int status;
private String Ticket;
/** 推荐消息报文 **/
private RecommendInfo recommendInfo;
private long createTime;
private String newMsgId;
/** 文本消息内容 **/
private String text;
/** 消息类型 **/
private int msgType;
/** 是否为群消息 **/
private boolean groupMsg;
private String msgId;
private int statusNotifyCode;
private AppInfo appInfo;
private int appMsgType;
private String Type;
private int playLength;
private String mediaId;
private String content;
private String statusNotifyUserName;
private boolean atMe;
// 群发送者ID昵称
private String sendMemberId;
private String memberNickname;
/** 消息发送者ID **/
private String fromUserName;
private String oriContent;
private String fileSize;
private String fromNickName;
public int getSubMsgType() {
return subMsgType;
}
public void setSubMsgType(int subMsgType) {
this.subMsgType = subMsgType;
}
public int getVoiceLength() {
return voiceLength;
}
public void setVoiceLength(int voiceLength) {
this.voiceLength = voiceLength;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public int getImgHeight() {
return imgHeight;
}
public void setImgHeight(int imgHeight) {
this.imgHeight = imgHeight;
}
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public int getHasProductId() {
return hasProductId;
}
public void setHasProductId(int hasProductId) {
this.hasProductId = hasProductId;
}
public int getImgStatus() {
return imgStatus;
}
public void setImgStatus(int imgStatus) {
this.imgStatus = imgStatus;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getImgWidth() {
return imgWidth;
}
public void setImgWidth(int imgWidth) {
this.imgWidth = imgWidth;
}
public int getForwardFlag() {
return forwardFlag;
}
public void setForwardFlag(int forwardFlag) {
this.forwardFlag = forwardFlag;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getTicket() {
return Ticket;
}
public void setTicket(String ticket) {
Ticket = ticket;
}
public RecommendInfo getRecommendInfo() {
return recommendInfo;
}
public void setRecommendInfo(RecommendInfo recommendInfo) {
this.recommendInfo = recommendInfo;
}
public long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
public String getNewMsgId() {
return newMsgId;
}
public void setNewMsgId(String newMsgId) {
this.newMsgId = newMsgId;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getMsgType() {
return msgType;
}
public void setMsgType(int msgType) {
this.msgType = msgType;
}
public boolean isGroupMsg() {
return groupMsg;
}
public void setGroupMsg(boolean groupMsg) {
this.groupMsg = groupMsg;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public int getStatusNotifyCode() {
return statusNotifyCode;
}
public void setStatusNotifyCode(int statusNotifyCode) {
this.statusNotifyCode = statusNotifyCode;
}
public AppInfo getAppInfo() {
return appInfo;
}
public void setAppInfo(AppInfo appInfo) {
this.appInfo = appInfo;
}
public int getAppMsgType() {
return appMsgType;
}
public void setAppMsgType(int appMsgType) {
this.appMsgType = appMsgType;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
public int getPlayLength() {
return playLength;
}
public void setPlayLength(int playLength) {
this.playLength = playLength;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getStatusNotifyUserName() {
return statusNotifyUserName;
}
public void setStatusNotifyUserName(String statusNotifyUserName) {
this.statusNotifyUserName = statusNotifyUserName;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getOriContent() {
return oriContent;
}
public void setOriContent(String oriContent) {
this.oriContent = oriContent;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public String getMemberNickname() {
return memberNickname;
}
public void setMemberNickname(String memberNickname) {
this.memberNickname = memberNickname;
}
public String getFromNickName() {
return fromNickName;
}
public void setFromNickName(String fromNickName) {
this.fromNickName = fromNickName;
}
public String getSendMemberId() {
return sendMemberId;
}
public void setSendMemberId(String sendMemberId) {
this.sendMemberId = sendMemberId;
}
public boolean isAtMe() {
return atMe;
}
public void setAtMe(boolean atMe) {
this.atMe = atMe;
}
}

View File

@@ -1,28 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
/**
* @author WesleyOne
* @create 2018/12/21
*/
@Deprecated
public class BaseResponse {
private Integer Ret;
private String ErrMsg;
public Integer getRet() {
return Ret;
}
public void setRet(Integer ret) {
Ret = ret;
}
public String getErrMsg() {
return ErrMsg;
}
public void setErrMsg(String errMsg) {
ErrMsg = errMsg;
}
}

View File

@@ -1,306 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.util.List;
/**
* 成员信息对象
*
* 来自获取好友列表
* /cgi-bin/mmwebwx-bin/webwxgetcontact
* MemberList中单体
* @author WesleyOne
* @create 2018/12/21
*/
@Deprecated
public class Member {
private String Alias;
private Integer AppAccountFlag;
private Integer AttrStatus;
private Integer ChatRoomId;
private String City;
private Integer ContactFlag;
/**
* 群昵称
*/
private String DisplayName;
private String EncryChatRoomId;
private String HeadImgUrl;
private Integer HideInputBarFlag;
private Integer IsOwner;
private String KeyWord;
private Integer MemberCount;
private List<Member> MemberList;
private String NickName;
private Integer OwnerUin;
private String PYInitial;
private String PYQuanPin;
private String Province;
/**
* 备注名、首拼、全拼
*/
private String RemarkName;
private String RemarkPYInitial;
private String RemarkPYQuanPin;
private Integer Sex;
private String Signature;
private Integer SnsFlag;
private Integer StarFriend;
private Integer Statues;
private Integer Uin;
private Integer UniFriend;
private String UserName;
/**
* 用来判断是否是公众号或服务号的字段
*/
private String VerifyFlag;
public String getAlias() {
return Alias;
}
public void setAlias(String alias) {
Alias = alias;
}
public Integer getAppAccountFlag() {
return AppAccountFlag;
}
public void setAppAccountFlag(Integer appAccountFlag) {
AppAccountFlag = appAccountFlag;
}
public Integer getAttrStatus() {
return AttrStatus;
}
public void setAttrStatus(Integer attrStatus) {
AttrStatus = attrStatus;
}
public Integer getChatRoomId() {
return ChatRoomId;
}
public void setChatRoomId(Integer chatRoomId) {
ChatRoomId = chatRoomId;
}
public String getCity() {
return City;
}
public void setCity(String city) {
City = city;
}
public Integer getContactFlag() {
return ContactFlag;
}
public void setContactFlag(Integer contactFlag) {
ContactFlag = contactFlag;
}
public String getDisplayName() {
return DisplayName;
}
public void setDisplayName(String displayName) {
DisplayName = displayName;
}
public String getEncryChatRoomId() {
return EncryChatRoomId;
}
public void setEncryChatRoomId(String encryChatRoomId) {
EncryChatRoomId = encryChatRoomId;
}
public String getHeadImgUrl() {
return HeadImgUrl;
}
public void setHeadImgUrl(String headImgUrl) {
HeadImgUrl = headImgUrl;
}
public Integer getHideInputBarFlag() {
return HideInputBarFlag;
}
public void setHideInputBarFlag(Integer hideInputBarFlag) {
HideInputBarFlag = hideInputBarFlag;
}
public Integer getIsOwner() {
return IsOwner;
}
public void setIsOwner(Integer isOwner) {
IsOwner = isOwner;
}
public String getKeyWord() {
return KeyWord;
}
public void setKeyWord(String keyWord) {
KeyWord = keyWord;
}
public Integer getMemberCount() {
return MemberCount;
}
public void setMemberCount(Integer memberCount) {
MemberCount = memberCount;
}
public List<Member> getMemberList() {
return MemberList;
}
public void setMemberList(List<Member> memberList) {
MemberList = memberList;
}
public String getNickName() {
return NickName;
}
public void setNickName(String nickName) {
NickName = nickName;
}
public Integer getOwnerUin() {
return OwnerUin;
}
public void setOwnerUin(Integer ownerUin) {
OwnerUin = ownerUin;
}
public String getPYInitial() {
return PYInitial;
}
public void setPYInitial(String PYInitial) {
this.PYInitial = PYInitial;
}
public String getPYQuanPin() {
return PYQuanPin;
}
public void setPYQuanPin(String PYQuanPin) {
this.PYQuanPin = PYQuanPin;
}
public String getProvince() {
return Province;
}
public void setProvince(String province) {
Province = province;
}
public String getRemarkName() {
return RemarkName;
}
public void setRemarkName(String remarkName) {
RemarkName = remarkName;
}
public String getRemarkPYInitial() {
return RemarkPYInitial;
}
public void setRemarkPYInitial(String remarkPYInitial) {
RemarkPYInitial = remarkPYInitial;
}
public String getRemarkPYQuanPin() {
return RemarkPYQuanPin;
}
public void setRemarkPYQuanPin(String remarkPYQuanPin) {
RemarkPYQuanPin = remarkPYQuanPin;
}
public Integer getSex() {
return Sex;
}
public void setSex(Integer sex) {
Sex = sex;
}
public String getSignature() {
return Signature;
}
public void setSignature(String signature) {
Signature = signature;
}
public Integer getSnsFlag() {
return SnsFlag;
}
public void setSnsFlag(Integer snsFlag) {
SnsFlag = snsFlag;
}
public Integer getStarFriend() {
return StarFriend;
}
public void setStarFriend(Integer starFriend) {
StarFriend = starFriend;
}
public Integer getStatues() {
return Statues;
}
public void setStatues(Integer statues) {
Statues = statues;
}
public Integer getUin() {
return Uin;
}
public void setUin(Integer uin) {
Uin = uin;
}
public Integer getUniFriend() {
return UniFriend;
}
public void setUniFriend(Integer uniFriend) {
UniFriend = uniFriend;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getVerifyFlag() {
return VerifyFlag;
}
public void setVerifyFlag(String verifyFlag) {
VerifyFlag = verifyFlag;
}
}

View File

@@ -1,146 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.io.Serializable;
/**
* RecommendInfo
*
* @author https://github.com/yaphone
* @date 创建时间2017年7月3日 下午10:35:14
* @version 1.0
*
*/
public class RecommendInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String ticket;
private String userName;
private int sex;
private int attrStatus;
private String city;
private String nickName;
private int scene;
private String province;
private String content;
private String alias;
private String signature;
private int opCode;
private int qQNum;
private int verifyFlag;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getAttrStatus() {
return attrStatus;
}
public void setAttrStatus(int attrStatus) {
this.attrStatus = attrStatus;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getScene() {
return scene;
}
public void setScene(int scene) {
this.scene = scene;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public int getOpCode() {
return opCode;
}
public void setOpCode(int opCode) {
this.opCode = opCode;
}
public int getqQNum() {
return qQNum;
}
public void setqQNum(int qQNum) {
this.qQNum = qQNum;
}
public int getVerifyFlag() {
return verifyFlag;
}
public void setVerifyFlag(int verifyFlag) {
this.verifyFlag = verifyFlag;
}
}

View File

@@ -1,59 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType;
import java.io.Serializable;
/**
* 发送消息体
* @author WesleyOne
* @create 2019/1/7
*/
public class SendMsg implements Serializable {
private String userName;
private String nickName;
private String message;
private SendMsgType msgType;
private boolean isGroup;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SendMsgType getMsgType() {
return msgType;
}
public void setMsgType(SendMsgType msgType) {
this.msgType = msgType;
}
public boolean isGroup() {
return isGroup;
}
public void setGroup(boolean group) {
isGroup = group;
}
}

View File

@@ -1,52 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.util.List;
/**
* @author WesleyOne
* @create 2018/12/21
*/
@Deprecated
public class SyncKey {
private Integer Count;
private List<KV> List;
public Integer getCount() {
return Count;
}
public void setCount(Integer count) {
Count = count;
}
public java.util.List<KV> getList() {
return List;
}
public void setList(java.util.List<KV> list) {
List = list;
}
class KV{
private Integer Key;
private Long Val;
public Integer getKey() {
return Key;
}
public void setKey(Integer key) {
Key = key;
}
public Long getVal() {
return Val;
}
public void setVal(Long val) {
Val = val;
}
}
}

View File

@@ -1,54 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
/*
AppAccountFlag: 0
ContactFlag: 0
HeadImgFlag: 1
HeadImgUrl: "/cgi-bin/mmwebwx-bin/webwxgeticon?seq=778915892&username=@7e6934104b3cf1f92dd11344c63a06833ae54bd43b34229b5cc472c4d05eba4a&skey=@crypt_a24169c_f4c07f70afe861da5e8a6e1947044b6e"
HideInputBarFlag: 0
NickName: "[衰]晓炜"
PYInitial: ""
PYQuanPin: ""
RemarkName: ""
RemarkPYInitial: ""
RemarkPYQuanPin: ""
Sex: 1
Signature: "人工智障"
SnsFlag: 49
StarFriend: 0
Uin: 902478981
UserName: "@7e6934104b3cf1f92dd11344c63a06833ae54bd43b34229b5cc472c4d05eba4a"
VerifyFlag: 0
WebWxPluginSwitch: 0
*/
/**
* @author WesleyOne
* @create 2018/12/21
*/
@Deprecated
public class User {
private String AppAccountFlag;
private String ContactFlag;
private String HeadImgFlag;
private String HeadImgUrl;
private String HideInputBarFlag;
private String NickName;
private String PYInitial;
private String PYQuanPin;
private String RemarkName;
private String RemarkPYInitial;
private String RemarkPYQuanPin;
private String Sex;
/**
* 签名
*/
private String Signature;
private String SnsFlag;
private String StarFriend;
private String Uin;
private String UserName;
private String VerifyFlag;
private String WebWxPluginSwitch;
}

View File

@@ -1,43 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.beans;
import java.util.List;
/**
* @author WesleyOne
* @create 2018/12/21
*/
@Deprecated
public class WebWxInit {
private BaseResponse BaseResponse;
private String ChatSet;
private Long ClickReportInterval;
private Long ClientVersion;
private List<Member> ContactList;
private Integer Count;
private Integer GrayScale;
private Integer InviteStartCount;
/**
* 订阅号字段省略
* MPSubscribeMsgCount
* MPSubscribeMsgList
*/
private String SKey;
private SyncKey SyncKey;
private Long SystemTime;
private User User;
}

View File

@@ -1,34 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.client;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.CookieStore;
import java.util.HashMap;
/**
* 多开请求类管理
* @author WesleyOne
* @create 2018/12/15
*/
public class HttpClientManage {
private static HashMap<String,SingleHttpClient> clientMap = new HashMap<>(32);
public static SingleHttpClient getInstance(String uniqueKey){
return getInstance(uniqueKey,null);
}
public static SingleHttpClient getInstance(String uniqueKey,CookieStore outCookieStore) {
if (StringUtils.isEmpty(uniqueKey)){
return null;
}
SingleHttpClient client;
// outCookieStore不为空时也重新构造,主要用于热登录
if (!clientMap.containsKey(uniqueKey) || clientMap.get(uniqueKey) == null || outCookieStore != null){
client = SingleHttpClient.getInstance(outCookieStore);
clientMap.put(uniqueKey, client);
}
return clientMap.get(uniqueKey);
}
}

View File

@@ -1,187 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.client;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.ruoyi.common.wechat.itchat4j.utils.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author WesleyOne
* @create 2018/12/15
*/
public class SingleHttpClient {
private Logger logger = LoggerFactory.getLogger("UTILLOG");
private CloseableHttpClient httpClient ;
private CookieStore cookieStore;
private String uniqueKey;
public String getCookie(String name) {
List<Cookie> cookies = cookieStore.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equalsIgnoreCase(name)) {
return cookie.getValue();
}
}
return null;
}
private SingleHttpClient(CookieStore outCookieStore){
if (outCookieStore == null){
outCookieStore = new BasicCookieStore();
}
this.cookieStore = outCookieStore;
httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).setRetryHandler(new DefaultHttpRequestRetryHandler(0,false)).build();
}
private SingleHttpClient(){
this(null);
}
public static SingleHttpClient getInstance(CookieStore outCookieStore){
return new SingleHttpClient(outCookieStore);
}
/**
* 处理GET请求
*
* @author https://github.com/yaphone
* @date 2017年4月9日 下午7:06:19
* @param url
* @param params
* @return
*/
public HttpEntity doGet(String url, List<BasicNameValuePair> params, boolean redirect,
Map<String, String> headerMap) {
HttpEntity entity = null;
HttpGet httpGet = new HttpGet();
try {
if (params != null) {
String paramStr = EntityUtils.toString(new UrlEncodedFormEntity(params, Consts.UTF_8));
httpGet = new HttpGet(url + "?" + paramStr);
// System.out.println(url + "?" + paramStr);
} else {
httpGet = new HttpGet(url);
}
if (!redirect) {
// 禁止重定向
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
}
httpGet.setHeader("User-Agent", Config.USER_AGENT);
if (headerMap != null) {
Set<Map.Entry<String, String>> entries = headerMap.entrySet();
for (Map.Entry<String, String> entry : entries) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
CloseableHttpResponse response = httpClient.execute(httpGet);
entity = response.getEntity();
} catch (ClientProtocolException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
} catch (Exception e){
logger.error(e.getMessage());
}
return entity;
}
/**
* 处理POST请求
*
* @author https://github.com/yaphone
* @date 2017年4月9日 下午7:06:35
* @param url
* @param paramsStr
* @return
*/
public HttpEntity doPost(String url, String paramsStr) {
return doPost(url,paramsStr,null);
}
public HttpEntity doPost(String url, String paramsStr, Map<String, String> headerMap) {
HttpEntity entity = null;
HttpPost httpPost = new HttpPost();
try {
StringEntity params = new StringEntity(paramsStr, Consts.UTF_8);
httpPost = new HttpPost(url);
httpPost.setEntity(params);
httpPost.setHeader("Content-type", "application/json; charset=utf-8");
httpPost.setHeader("User-Agent", Config.USER_AGENT);
if (headerMap != null) {
Set<Map.Entry<String, String>> entries = headerMap.entrySet();
for (Map.Entry<String, String> entry : entries) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
CloseableHttpResponse response = httpClient.execute(httpPost);
entity = response.getEntity();
} catch (ClientProtocolException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
} catch (Exception e){
logger.error(e.getMessage());
}
return entity;
}
/**
* 上传文件到服务器
*
* @author https://github.com/yaphone
* @date 2017年5月7日 下午9:19:23
* @param url
* @param reqEntity
* @return
*/
public HttpEntity doPostFile(String url, HttpEntity reqEntity) {
HttpEntity entity = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", Config.USER_AGENT);
httpPost.setEntity(reqEntity);
try {
CloseableHttpResponse response = httpClient.execute(httpPost);
entity = response.getEntity();
} catch (Exception e) {
logger.error(e.getMessage());
}
return entity;
}
public CookieStore getCookieStore() {
return this.cookieStore;
}
public void setCookieStore(CookieStore cookieStore) {
this.cookieStore = cookieStore;
}
}

View File

@@ -1,148 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.controller;
import org.ruoyi.common.wechat.itchat4j.core.Core;
import org.ruoyi.common.wechat.itchat4j.core.CoreManage;
import org.ruoyi.common.wechat.itchat4j.core.MsgCenter;
import org.ruoyi.common.wechat.itchat4j.service.ILoginService;
import org.ruoyi.common.wechat.itchat4j.service.impl.LoginServiceImpl;
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
import org.ruoyi.common.wechat.itchat4j.utils.SleepUtils;
import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum;
import org.ruoyi.common.wechat.web.base.BaseException;
/**
* 登陆控制器
*
* @author https://github.com/yaphone
* @date 创建时间2017年5月13日 下午12:56:07
* @version 1.0
*
* @author WesleyOne 修改
*/
public class LoginController implements LogInterface {
private ILoginService loginService;
private String uniqueKey;
private Core core;
public LoginController(String uniqueKey){
this.uniqueKey = uniqueKey;
this.loginService = new LoginServiceImpl(uniqueKey);
this.core = CoreManage.getInstance(uniqueKey);
}
/**
* 获取二维码地址
* 风险:已登录账号不可调用该接口,会移除当前core信息
* @return
*/
public String login_1() throws BaseException {
if (core.isAlive()) {
LOG.warn("微信已登陆");
throw new BaseException("微信已登陆");
}
LOG.info("1.获取微信UUID");
while (loginService.getUuid() == null) {
LOG.warn("1.1. 获取微信UUID失败一秒后重新获取");
SleepUtils.sleep(1000);
}
LOG.info("2. 获取登陆二维码图片");
return URLEnum.QRCODE_URL.getUrl() + core.getUuid();
}
/**
* 确认登录
* @return
*/
public boolean login_2(){
boolean result = false;
LOG.info("3. 请扫描二维码图片,并在手机上确认");
if (!core.isAlive()) {
if (loginService.login()){
core.setAlive(true);
LOG.info(("3.1登陆成功"));
result = true;
}
}
return result;
}
/**
* 加载数据
* @return
*/
public boolean login_3() {
boolean result = true;
LOG.info("4.微信初始化");
if (!loginService.webWxInit()) {
LOG.info("4.1 微信初始化异常");
result = false;
}
if (result){
LOG.info("5. 开启微信状态通知");
loginService.wxStatusNotify();
LOG.info(String.format("欢迎回来, %s", core.getNickName()));
LOG.info("6.+++开启消息发送线程["+uniqueKey+"]+++");
Thread sendThread = new Thread(core.getThreadGroup(), () -> MsgCenter.sendMsg(uniqueKey), "SEND-" + uniqueKey);
sendThread.start();
LOG.info("8. +++开始接收消息线程["+uniqueKey+"]+++");
loginService.startReceiving();
LOG.info("9. 获取联系人信息");
loginService.webWxGetContact();
LOG.info("10. 获取群好友及群好友列表及缓存");
loginService.WebWxBatchGetContact();
}
if (!result){
core.setAlive(false);
return false;
}
core.setFinishInit(true);
return true;
}
public boolean reboot(){
core.setFinishInit(false);
// 重新加载数据
boolean result = true;
LOG.info("1.刷新初始化信息");
if (!loginService.webWxInit()) {
LOG.info("1.1 微信初始化异常");
result = false;
}
if (result){
LOG.info("2. 刷新开启微信状态通知");
loginService.wxStatusNotify();
LOG.info("3. 刷新获取联系人信息");
loginService.webWxGetContact();
LOG.info("4. 刷新获取群好友及群好友列表");
loginService.WebWxBatchGetContact();
}
if (!result){
core.setAlive(false);
return false;
}
core.setFinishInit(true);
return true;
}
}

View File

@@ -1,371 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.core;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg;
import org.ruoyi.common.wechat.itchat4j.beans.SendMsg;
import org.ruoyi.common.wechat.itchat4j.beans.User;
import org.ruoyi.common.wechat.itchat4j.client.HttpClientManage;
import org.ruoyi.common.wechat.itchat4j.client.SingleHttpClient;
import org.ruoyi.common.wechat.itchat4j.service.impl.LoginServiceImpl;
import org.ruoyi.common.wechat.itchat4j.utils.enums.parameters.BaseParaEnum;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 核心存储类,全局只保存一份,单例模式
*
* @author https://github.com/yaphone
* @author WesleyOne 修改
* @version 1.0
* @date 创建时间2017年4月23日 下午2:33:56
*/
public class Core {
private Core() {
}
private Core(String uniqueKey) {
this.uniqueKey = uniqueKey;
this.myHttpClient = HttpClientManage.getInstance(this.uniqueKey);
this.threadGroup = new ThreadGroup(this.uniqueKey);
}
protected static Core getInstance(String uniqueKey) {
return new Core(uniqueKey);
}
private String uniqueKey;
boolean alive = false;
/**
* 管理当前机器人的所有业务线程
*/
@JSONField(serialize = false)
private ThreadGroup threadGroup;
@JSONField(serialize = false)
boolean isFinishInit = false;
/**
* login,webWxInit
* 登录接口获取
*/
private String indexUrl;
private String userName;
private String nickName;
String uuid = null;
/**
* webWxInit
* InviteStartCount
* SyncKey
* synckey 随着每次获取最新消息后的返回值更新,其目的在于每次同步消息后记录一个当前同步的状态
*/
Map<String, Object> loginInfo = new HashMap<String, Object>();
/**
* webWxInit
* 登陆账号自身信息
*
* @see User
*/
private JSONObject userSelf;
/**
* 初始化/cgi-bin/mmwebwx-bin/webwxinit
* 最后一次收到正常retcode的时间秒为单位
* <p>
* synccheck刷新
*/
private long lastNormalRetcodeTime;
/**
* synccheck和webWxSync容错次数,超过退出
*/
int receivingRetryCount = 5;
@JSONField(serialize = false)
SingleHttpClient myHttpClient;
public SingleHttpClient getMyHttpClient() {
return HttpClientManage.getInstance(uniqueKey);
}
/**
* 初始话时获取联系人时创建
* @see LoginServiceImpl#webWxGetContact()
*/
/**
* memberList长度
*/
@JSONField(serialize = false)
private int memberCount = 0;
/**
* 好友+群聊+公众号+特殊账号
* 注意:不主动插入,获取时通过其他几个账号集合合并
*/
@JSONField(serialize = false)
private List<JSONObject> memberList = new ArrayList<JSONObject>();
/**
* 好友
*/
@JSONField(serialize = false)
private List<JSONObject> contactList = new ArrayList<JSONObject>();
/**
* 群
*/
@JSONField(serialize = false)
private List<JSONObject> groupList = new ArrayList<JSONObject>();
/**
* 公众号/服务号
*/
@Deprecated
@JSONField(serialize = false)
private List<JSONObject> publicUsersList = new ArrayList<JSONObject>();
/**
* 特殊账号
*/
@JSONField(serialize = false)
private List<JSONObject> specialUsersList = new ArrayList<JSONObject>();
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
/**
* synccheck和webWxSynct添加
* 异步接受消息存储
*/
@JSONField(serialize = false)
private List<BaseMsg> msgList = new ArrayList<>();
/**
* 异步发送消息存储
*/
@JSONField(serialize = false)
private List<SendMsg> sendList = new ArrayList();
/********************************
* 缓存字段,用于快速查找
********************************/
/**
* 微信昵称不能超过16位而ID比较长干脆用一个Map
* 群ID或昵称,群信息
* 注意:存在相同昵称会后者覆盖前者
* <p>
* WebWxBatchGetContact之后可以通过
* .getJSONArray("MemberList")获取群成员列表
*/
@JSONField(serialize = false)
private Map<String, JSONObject> groupInfoMap = new HashMap<>(1024);
/**
* 微信昵称不能超过16位而ID比较长干脆用一个Map
* 玩家ID或昵称玩家信息
* 注意:存在相同昵称会后者覆盖前者
*/
@JSONField(serialize = false)
private Map<String, JSONObject> userInfoMap = new HashMap<>(1024);
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
/**
* 请求参数
*/
@JSONField(serialize = false)
public Map<String, Object> getParamMap() {
return new HashMap<String, Object>(1) {
/**
*
*/
private static final long serialVersionUID = 1L;
{
Map<String, String> map = new HashMap<>(16);
for (BaseParaEnum baseRequest : BaseParaEnum.values()) {
map.put(baseRequest.para(), getLoginInfo().get(baseRequest.value()).toString());
}
put("BaseRequest", map);
}
};
}
public String getUniqueKey() {
return uniqueKey;
}
public void setUniqueKey(String uniqueKey) {
this.uniqueKey = uniqueKey;
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
if (!alive) {
this.isFinishInit = false;
}
}
public String getIndexUrl() {
return indexUrl;
}
public void setIndexUrl(String indexUrl) {
this.indexUrl = indexUrl;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Map<String, Object> getLoginInfo() {
return loginInfo;
}
public void setLoginInfo(Map<String, Object> loginInfo) {
this.loginInfo = loginInfo;
}
public JSONObject getUserSelf() {
return userSelf;
}
public void setUserSelf(JSONObject userSelf) {
this.userSelf = userSelf;
}
public long getLastNormalRetcodeTime() {
return lastNormalRetcodeTime;
}
public void setLastNormalRetcodeTime(long lastNormalRetcodeTime) {
this.lastNormalRetcodeTime = lastNormalRetcodeTime;
}
public int getReceivingRetryCount() {
return receivingRetryCount;
}
public void setReceivingRetryCount(int receivingRetryCount) {
this.receivingRetryCount = receivingRetryCount;
}
public int getMemberCount() {
return getContactList().size() + getGroupList().size() + getPublicUsersList().size() + getSpecialUsersList().size();
}
public List<JSONObject> getMemberList() {
List<JSONObject> memberList = new ArrayList<>();
memberList.addAll(this.getContactList());
memberList.addAll(this.getGroupList());
memberList.addAll(this.getPublicUsersList());
memberList.addAll(this.getSpecialUsersList());
return memberList;
}
public List<JSONObject> getContactList() {
return contactList;
}
public void setContactList(List<JSONObject> contactList) {
this.contactList = contactList;
}
public List<JSONObject> getGroupList() {
return groupList;
}
public void setGroupList(List<JSONObject> groupList) {
this.groupList = groupList;
}
public List<JSONObject> getPublicUsersList() {
return publicUsersList;
}
public void setPublicUsersList(List<JSONObject> publicUsersList) {
this.publicUsersList = publicUsersList;
}
public List<JSONObject> getSpecialUsersList() {
return specialUsersList;
}
public void setSpecialUsersList(List<JSONObject> specialUsersList) {
this.specialUsersList = specialUsersList;
}
public List<BaseMsg> getMsgList() {
return msgList;
}
public void setMsgList(List<BaseMsg> msgList) {
this.msgList = msgList;
}
public Map<String, JSONObject> getGroupInfoMap() {
return groupInfoMap;
}
public void setGroupInfoMap(Map<String, JSONObject> groupInfoMap) {
this.groupInfoMap = groupInfoMap;
}
public Map<String, JSONObject> getUserInfoMap() {
return userInfoMap;
}
public void setUserInfoMap(Map<String, JSONObject> userInfoMap) {
this.userInfoMap = userInfoMap;
}
public boolean isFinishInit() {
return isFinishInit;
}
public void setFinishInit(boolean finishInit) {
isFinishInit = finishInit;
}
public ThreadGroup getThreadGroup() {
return threadGroup;
}
public void setThreadGroup(ThreadGroup threadGroup) {
this.threadGroup = threadGroup;
}
public List<SendMsg> getSendList() {
return sendList;
}
}

View File

@@ -1,323 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.core;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.ruoyi.common.wechat.itchat4j.beans.SendMsg;
import org.ruoyi.common.wechat.itchat4j.client.HttpClientManage;
import org.ruoyi.common.wechat.itchat4j.controller.LoginController;
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType;
import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools;
import java.io.*;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
/**
* 多开管理
*
* @author WesleyOne
* @create 2018/12/13
*/
public class CoreManage implements LogInterface {
static int MAX_CORE_NUM = 50;
private static HashMap<String, Core> coreMap = new HashMap<>(MAX_CORE_NUM / 3 * 4 + 1);
// 是否热加载
public static boolean USE_HOT_RELOAD = false;
public static String HOT_RELOAD_DIR = "/Users/wesley/output/hotreload/wxwobot.hot";
public static Core getInstance(String uniqueKey) {
if (StringUtils.isEmpty(uniqueKey)) {
return null;
}
Core core;
if (!coreMap.containsKey(uniqueKey) || coreMap.get(uniqueKey) == null) {
core = Core.getInstance(uniqueKey);
coreMap.put(uniqueKey, core);
}
return coreMap.get(uniqueKey);
}
/**
* 移除
*
* @param uniqueKey
*/
public static void remove(String uniqueKey) {
if (coreMap.containsKey(uniqueKey)) {
coreMap.remove(uniqueKey);
}
}
/**
* 查询是否在线
*
* @param uniqueKey
* @return
*/
public static boolean isActive(String uniqueKey) {
if (StringUtils.isNotEmpty(uniqueKey) && coreMap.containsKey(uniqueKey) && coreMap.get(uniqueKey).isAlive()) {
return true;
}
return false;
}
/**
* 持久化
*/
public static void persistence() {
// 格式化数据
Collection<Core> valueCollection = coreMap.values();
int size = valueCollection.size();
// 没有数据不操作
if (size <= 0) {
return;
}
LOG.info("登录数据持久化中");
Iterator<Core> iterator = valueCollection.iterator();
JSONArray jsonArray = new JSONArray();
while (iterator.hasNext()) {
Core core = iterator.next();
if (core.isAlive()) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("core", core);
jsonObject.put("cookies", core.getMyHttpClient().getCookieStore().getCookies());
jsonArray.add(jsonObject);
}
}
try {
File file = new File(HOT_RELOAD_DIR);
if (!file.exists()) {
file.createNewFile();
}
// 每次覆盖
FileWriter fileWritter = new FileWriter(HOT_RELOAD_DIR, false);
fileWritter.write(jsonArray.toJSONString());
fileWritter.close();
LOG.info("登录数据持久化完成");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 启动加载持久化文件
*/
public static void reload() {
if (USE_HOT_RELOAD) {
File file = new File(HOT_RELOAD_DIR);
if (file.exists()) {
LOG.info("登录数据热加载中");
StringBuilder stringBuilder = new StringBuilder();
try {
FileReader fr = new FileReader(HOT_RELOAD_DIR);
BufferedReader bf = new BufferedReader(fr);
String str;
// 按行读取字符串
while ((str = bf.readLine()) != null) {
stringBuilder.append(str);
}
bf.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
String result = stringBuilder.toString();
if (StringUtils.isEmpty(result)) {
return;
}
JSONArray jsonArray = JSONArray.parseArray(result);
int size = jsonArray.size();
if (size > 0) {
// 封装成线程操作
for (int i = 0; i < size; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
ReloadThread reloadThread = new ReloadThread(jsonObject);
Thread thread = new Thread(reloadThread);
thread.start();
}
}
LOG.info("登录数据热加载完成");
}
}
}
private static class ReloadThread implements Runnable {
private JSONObject reloadObject;
public ReloadThread(JSONObject object) {
this.reloadObject = object;
}
@Override
public void run() {
Core core = null;
try {
/**
* 初始化Core,
* 1.获取登入的状态信息并装入CoreManage
* 2.构建ThreadGroup
* 3.获取Cookies并装入HttpClientManage
* 4.获取信息及启动线程
*/
JSONObject jsonObject = this.reloadObject;
core = jsonObject.getObject("core", Core.class);
String uniqueKey = core.getUniqueKey();
if (core.isAlive()) {
core.setThreadGroup(new ThreadGroup(uniqueKey));
coreMap.put(uniqueKey, core);
JSONArray cookiesJsonArray = jsonObject.getJSONArray("cookies");
int arraySize = cookiesJsonArray.size();
if (arraySize <= 0) {
return;
}
// 装载原cookie信息,json解析cookie异常干脆手动封装
BasicCookieStore cookieStore = new BasicCookieStore();
for (int ci = 0; ci < arraySize; ci++) {
JSONObject cookieJson = cookiesJsonArray.getJSONObject(ci);
String name = cookieJson.getString("name");
String value = cookieJson.getString("value");
String domain = cookieJson.getString("domain");
String path = cookieJson.getString("path");
Boolean persistent = cookieJson.getBoolean("persistent");
Boolean secure = cookieJson.getBoolean("secure");
Long expiryDate = cookieJson.getLong("expiryDate");
Integer version = cookieJson.getInteger("version");
BasicClientCookie cookie = new BasicClientCookie(name, value);
cookie.setDomain(domain);
cookie.setPath(path);
cookie.setSecure(secure);
cookie.setExpiryDate(new Date(expiryDate));
cookie.setVersion(version);
cookieStore.addCookie(cookie);
}
// 必须在构建client时就放入cookie
HttpClientManage.getInstance(uniqueKey, cookieStore);
//装载core信息及启动线程
LoginController login = new LoginController(uniqueKey);
if (!login.login_3()) {
// 加载失败退出
core.setAlive(false);
return;
}
LOG.info("热登录成功: {}", uniqueKey);
}
} catch (Exception e) {
e.printStackTrace();
if (core != null) {
core.setAlive(false);
core = null;
}
}
}
}
/**
* 存放新的群,昵称emoji处理
*
* @param core
* @param jsonObject
*/
public static void addNewGroup(Core core, JSONObject jsonObject) {
String userName = jsonObject.getString("UserName");
CommonTools.emojiFormatter2(jsonObject, "NickName");
// 删除重复的
core.getGroupList().removeIf(group -> userName.equals(group.getString("UserName")));
core.getGroupList().add(jsonObject);
core.getGroupInfoMap().put(jsonObject.getString("NickName"), jsonObject);
core.getGroupInfoMap().put(userName, jsonObject);
}
/**
* 存放新的联系人,昵称emoji处理
*
* @param core
* @param jsonObject
*/
public static void addNewContact(Core core, JSONObject jsonObject) {
String userName = jsonObject.getString("UserName");
CommonTools.emojiFormatter2(jsonObject, "NickName");
// 删除重复的
core.getContactList().removeIf(contact -> userName.equals(contact.getString("UserName")));
core.getContactList().add(jsonObject);
core.getUserInfoMap().put(jsonObject.getString("NickName"), jsonObject);
core.getUserInfoMap().put(userName, jsonObject);
}
/**
* 消息统一加到队列里处理1
* 用于已知UserName
*
* @param uniqueKey
* @param toUserName
* @param data
* @param type
*/
public static void addSendMsg4UserName(String uniqueKey, String toUserName, String data, SendMsgType type) {
if (StringUtils.isEmpty(uniqueKey) || StringUtils.isEmpty(toUserName) || StringUtils.isEmpty(data) || type == null) {
LOG.error("消息参数不完整 uk:{} un: {} data: {} ", uniqueKey, toUserName, data);
return;
}
SendMsg sendMsg = new SendMsg();
sendMsg.setUserName(toUserName);
sendMsg.setMessage(data);
sendMsg.setMsgType(type);
boolean isGroup = true;
if (toUserName != null && !toUserName.startsWith("@@")) {
isGroup = false;
}
sendMsg.setGroup(isGroup);
CoreManage.getInstance(uniqueKey).getSendList().add(sendMsg);
}
/**
* 消息统一加到队列里处理2
* 用于已知NickName
*
* @param uniqueKey
* @param toNickName
* @param data
* @param type
* @param isGroup
*/
public static void addSendMsg4NickName(String uniqueKey, String toNickName, String data, SendMsgType type, Boolean isGroup) {
if (StringUtils.isEmpty(uniqueKey) || StringUtils.isEmpty(toNickName) || StringUtils.isEmpty(data) || type == null) {
LOG.error("消息参数不完整 uk:{} nn: {} data: {} ", uniqueKey, toNickName, data);
return;
}
SendMsg sendMsg = new SendMsg();
sendMsg.setNickName(toNickName);
sendMsg.setMessage(data);
sendMsg.setMsgType(type);
sendMsg.setGroup(isGroup);
CoreManage.getInstance(uniqueKey).getSendList().add(sendMsg);
}
}

View File

@@ -1,273 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.core;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.wechat.itchat4j.api.MessageTools;
import org.ruoyi.common.wechat.itchat4j.api.WechatTools;
import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg;
import org.ruoyi.common.wechat.itchat4j.beans.SendMsg;
import org.ruoyi.common.wechat.itchat4j.face.IMsgHandlerFace;
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
import org.ruoyi.common.wechat.itchat4j.utils.MoreConfig;
import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgCodeEnum;
import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgTypeEnum;
import org.ruoyi.common.wechat.itchat4j.utils.enums.SendMsgType;
import org.ruoyi.common.wechat.itchat4j.utils.tools.CommonTools;
import java.util.ArrayList;
import java.util.List;
/**
* 消息处理中心
*
* @author https://github.com/yaphone
* @author WesleyOne 修改
* @version 1.0
* @date 创建时间2017年5月14日 下午12:47:50
*/
public class MsgCenter implements LogInterface {
/**
* 接收消息,放入队列
*
* @param msgList
* @return
* @author https://github.com/yaphone
* @date 2017年4月23日 下午2:30:48
*/
public static JSONArray produceMsg(JSONArray msgList, String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
JSONArray result = new JSONArray();
// 用于暂存未知群ID,最后调用webwxbatchgetcontact获取
List<String> unknowGroup = new ArrayList<>();
for (int i = 0; i < msgList.size(); i++) {
JSONObject m = msgList.getJSONObject(i);
// 是否是群消息
boolean isGroupMsg = false;
boolean isAtMe = false;
if (m.getString("FromUserName").contains("@@") || m.getString("ToUserName").contains("@@")) {
// 群聊消息
isGroupMsg = true;
if (m.getString("FromUserName").contains("@@")
&& !core.getGroupInfoMap().containsKey(m.getString("FromUserName"))) {
unknowGroup.add(m.getString("FromUserName"));
} else if (m.getString("ToUserName").contains("@@")
&& !core.getGroupInfoMap().containsKey(m.getString("ToUserName"))) {
unknowGroup.add(m.getString("ToUserName"));
}
// 群消息与普通消息不同的是在其消息体Content中会包含发送者id及":<br/>"消息,这里需要处理一下,去掉多余信息,只保留消息内容
String splitCode = ":<br/>";
if (m.getString("Content").contains(splitCode)) {
String source = m.getString("Content");
String content = source.substring(source.indexOf(splitCode) + splitCode.length());
String sendMemberId = source.substring(0, source.indexOf(splitCode));
m.put("Content", content);
m.put(MoreConfig.SEND_MEMBER_ID, sendMemberId);
if (content.contains("@" + core.getNickName())) {
isAtMe = true;
}
}
}
m.put("groupMsg", isGroupMsg);
m.put("atMe", isAtMe);
// 1.文本消息
if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_TEXT.getCode())) {
if (m.getString("Url").length() != 0) {
// 1.1分享位置 不处理
continue;
// String[] contents = m.getString("Content").split(":");
// String data = "Map";
// if (contents.length>0) {
// data = contents[0]+":"+m.getString("Url");
// }
// m.put("Type", MsgTypeEnum.MAP.getType());
// m.put("Text", data);
// LOG.warn("MAP_CONTENT: {},URL: {}",m.getString("Content"),m.getString("Url"));
/**
* MAP_CONTENT: 滨兴小区(东区):/cgi-bin/mmwebwx-bin/webwxgetpubliclinkimg?url=xxx&msgid=7525662842661720095&pictype=location,URL: http://apis.map.qq.com/uri/v1/geocoder?coord=30.191660,120.200508
*/
} else {
// 1.2 普通文本
m.put("Type", MsgTypeEnum.TEXT.getType());
CommonTools.emojiFormatter2(m, "Content");
m.put("Text", m.getString("Content"));
}
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_IMAGE.getCode())
|| m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_EMOTICON.getCode())) {
// 2.图片消息 不处理
continue;
// m.put("Type", MsgTypeEnum.PIC.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VOICE.getCode())) {
// 3.语音消息 不处理
continue;
// m.put("Type", MsgTypeEnum.VOICE.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VERIFYMSG.getCode())) {
// 4.好友确认消息 不处理
continue;
// MessageTools.addFriend(core, userName, 3, ticket); // 确认添加好友
// m.put("Type", MsgTypeEnum.VERIFYMSG.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_SHARECARD.getCode())) {
// 5.共享名片 不处理
// m.put("Type", MsgTypeEnum.NAMECARD.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_VIDEO.getCode())
|| m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MICROVIDEO.getCode())) {
// 6.视频 不处理
continue;
// m.put("Type", MsgTypeEnum.VIEDO.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_MEDIA.getCode())) {
// 7.分享链接 不处理
continue;
// m.put("Type", MsgTypeEnum.MEDIA.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_STATUSNOTIFY.getCode())) {
// 微信初始化消息 系统
m.put("Type", MsgTypeEnum.SYS.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_SYS.getCode())) {
// 系统消息 系统
m.put("Type", MsgTypeEnum.SYS.getType());
} else if (m.getInteger("MsgType").equals(MsgCodeEnum.MSGTYPE_RECALLED.getCode())) {
// 撤回消息 系统 不处理
continue;
// m.put("Type", MsgTypeEnum.SYS.getType());
} else {
LOG.error("Useless msg: {} \n {}", m.getInteger("MsgType"), m.getString("Content"));
}
/**
* 日志
* 显示收到的消息
*/
String nickName;
String memberName = "";
if (m.getBoolean("groupMsg")) {
nickName = WechatTools.getGroupNickNameByUserName(m.getString("FromUserName"), uniqueKey);
if (m.getString(MoreConfig.SEND_MEMBER_ID) != null) {
// 获取成员昵称
memberName = WechatTools.getMemberNickName(m.getString("FromUserName"), uniqueKey, m.getString(MoreConfig.SEND_MEMBER_ID));
m.put(MoreConfig.SEND_MEMBER_NICKNAMW, memberName);
}
} else {
nickName = WechatTools.getContactNickNameByUserName(m.getString("FromUserName"), uniqueKey);
}
m.put("fromNickName", nickName);
LOG.info("收到【{}】=>【{}】消息,来自: {} 内容:\n{} ",
MsgCodeEnum.fromCode(m.getInteger("MsgType")) == null ? "未知类型" + m.getInteger("MsgType") : MsgCodeEnum.fromCode(m.getInteger("MsgType")).getType(),
m.getString("Type"),
nickName + " : " + memberName,
StringUtils.isNotEmpty(m.getString("Content")) ? m.getString("Content") : "");
result.add(m);
}
return result;
}
/**
* 微信接收消息处理
*
* @param uniqueKey
* @author https://github.com/yaphone
* @date 2017年5月14日 上午10:52:34
*/
public static void handleMsg(String uniqueKey, IMsgHandlerFace msgHandler) {
Core core = CoreManage.getInstance(uniqueKey);
while (true) {
if (!core.isAlive()) {
LOG.info("停止消息处理");
break;
}
if (core.getMsgList().size() > 0 && core.getMsgList().get(0).getContent() != null) {
if (core.getMsgList().get(0).getContent().length() > 0) {
BaseMsg msg = core.getMsgList().get(0);
if (msg.getType() != null) {
try {
if (msg.getType().equals(MsgTypeEnum.TEXT.getType())) {
msgHandler.textMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.PIC.getType())) {
msgHandler.picMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.VOICE.getType())) {
msgHandler.voiceMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.VIEDO.getType())) {
msgHandler.videoMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.NAMECARD.getType())) {
msgHandler.nameCardMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.SYS.getType())) {
msgHandler.sysMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.VERIFYMSG.getType())) {
msgHandler.verifyAddFriendMsgHandle(msg);
} else if (msg.getType().equals(MsgTypeEnum.MEDIA.getType())) {
msgHandler.mediaMsgHandle(msg);
} else {
LOG.warn("暂未处理信息【{}】", msg.getType());
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
}
core.getMsgList().remove(0);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
LOG.error("消息处理中断");
break;
}
}
}
/**
* 统一发送消息
*
* @param uniqueKey
*/
public static void sendMsg(String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
while (true) {
if (core == null || !core.isAlive()) {
LOG.info("停止消息发送");
break;
}
if (CollectionUtil.isNotEmpty(core.getSendList())) {
SendMsg sendMsg = core.getSendList().get(0);
try {
String userName = sendMsg.getUserName();
String nickName = sendMsg.getNickName();
String message = sendMsg.getMessage();
boolean isGroup = sendMsg.isGroup();
SendMsgType msgType = sendMsg.getMsgType();
if (StringUtils.isNotEmpty(message) && msgType != null) {
if (StringUtils.isNotEmpty(userName)) {
MessageTools.send(userName, uniqueKey, message, msgType.toValue());
} else if (StringUtils.isNotEmpty(nickName)) {
MessageTools.sendByNickName(nickName, uniqueKey, message, msgType.toValue(), isGroup);
} else {
LOG.error("无效发送消息: {}", JSONObject.toJSONString(sendMsg));
}
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
core.getSendList().remove(0);
}
try {
// 控制发送频率
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
LOG.error("消息发送中断");
break;
}
}
}
}

View File

@@ -1,93 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.face;
import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg;
/**
* 消息处理接口
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月20日 上午12:13:49
* @version 1.0
*
* @author WesleyOne 修改
*/
public interface IMsgHandlerFace {
/**
*
* @author https://github.com/yaphone
* @date 2017年4月20日 上午12:15:00
* @param msg
* @return
*/
void textMsgHandle(BaseMsg msg);
/**
* 处理图片消息
*
* @author https://github.com/yaphone
* @date 2017年4月21日 下午11:07:06
* @param msg
* @return
*/
void picMsgHandle(BaseMsg msg);
/**
* 处理声音消息
*
* @author https://github.com/yaphone
* @date 2017年4月22日 上午12:09:44
* @param msg
* @return
*/
void voiceMsgHandle(BaseMsg msg);
/**
* 处理小视频消息
*
* @author https://github.com/yaphone
* @date 2017年4月23日 下午12:19:50
* @param msg
* @return
*/
void videoMsgHandle(BaseMsg msg);
/**
* 处理名片消息
*
* @author https://github.com/yaphone
* @date 2017年5月1日 上午12:50:50
* @param msg
* @return
*/
void nameCardMsgHandle(BaseMsg msg);
/**
* 处理系统消息
*
* @author Relyn
* @date 2017年6月21日17:43:51
* @param msg
* @return
*/
void sysMsgHandle(BaseMsg msg);
/**
* 处理确认添加好友消息
*
* @date 2017年6月28日 下午10:15:30
* @param msg
* @return
*/
void verifyAddFriendMsgHandle(BaseMsg msg);
/**
* 处理收到的文件消息
*
* @date 2017年7月21日 下午11:59:14
* @param msg
* @return
*/
void mediaMsgHandle(BaseMsg msg);
}

View File

@@ -1,85 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.service;
/**
* 登陆服务接口
*
* @author https://github.com/yaphone
* @date 创建时间2017年5月13日 上午12:07:21
* @version 1.0
*
* @author WesleyOne 修改
*/
public interface ILoginService {
/**
* 登陆
*
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:14:07
* @return
*/
boolean login();
/**
* 获取UUID
*
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:21:40
* @return
*/
String getUuid();
/**
* 获取二维码图片
* (直接获取图片链接,不下载文件)
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:13:51
* @param qrPath
* @return
*/
@Deprecated
boolean getQR(String qrPath);
/**
* web初始化
*
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:14:13
* @return
*/
boolean webWxInit();
/**
* 微信状态通知
*
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:14:24
*/
void wxStatusNotify();
/**
* 接收消息
*
* @author https://github.com/yaphone
* @date 2017年5月13日 上午12:14:37
*/
void startReceiving();
/**
* 获取微信联系人
*
* @author https://github.com/yaphone
* @date 2017年5月13日 下午2:26:18
*/
void webWxGetContact();
/**
* 批量获取联系人信息
*
* @date 2017年6月22日 下午11:24:35
*/
void WebWxBatchGetContact();
}

View File

@@ -1,78 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils;
import org.ruoyi.common.wechat.itchat4j.utils.enums.OsNameEnum;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
/**
* 配置信息
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月23日 下午2:26:21
* @version 1.0
*
*/
public class Config {
public static final String API_WXAPPID = "API_WXAPPID";
public static final String picDir = "D://org.ruoyi.common.wechat";
public static final String VERSION = "1.2.18";
public static final String BASE_URL = "https://login.weixin.qq.com";
public static final String OS = "";
public static final String DIR = "";
public static final String DEFAULT_QR = "QR.jpg";
public static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
/**
* 仅仅用于参考
*/
@Deprecated
public static final ArrayList<String> API_SPECIAL_USER = new ArrayList<String>(Arrays.asList("filehelper", "weibo",
"qqmail", "fmessage", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote",
"qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp", "meishiapp", "feedsapp", "voip",
"blogappweixin", "brandsessionholder", "weixin", "weixinreminder", "officialaccounts", "wxitil",
"notification_messages", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "userexperience_alarm"));
/**
* 获取文件目录
*
* @author https://github.com/yaphone
* @date 2017年4月8日 下午10:27:42
* @return
*/
public static String getLocalPath() {
String localPath = null;
try {
localPath = new File("").getCanonicalPath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return localPath;
}
/**
* 获取系统平台
*
* @author https://github.com/yaphone
* @date 2017年4月8日 下午10:27:53
*/
public static OsNameEnum getOsNameEnum() {
String os = System.getProperty("os.name").toUpperCase();
if (os.indexOf(OsNameEnum.DARWIN.toString()) >= 0) {
return OsNameEnum.DARWIN;
} else if (os.indexOf(OsNameEnum.WINDOWS.toString()) >= 0) {
return OsNameEnum.WINDOWS;
} else if (os.indexOf(OsNameEnum.LINUX.toString()) >= 0) {
return OsNameEnum.LINUX;
} else if (os.indexOf(OsNameEnum.MAC.toString()) >= 0) {
return OsNameEnum.MAC;
}
return OsNameEnum.OTHER;
}
}

View File

@@ -1,34 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils;
/**
* 常量
*
* @author https=//github.com/yaphone
* @date 创建时间2017年5月5日 下午11=29=04
* @version 1.0
*
*/
public class ConstantConfigEnum {
public static final int APPMSGTYPE_TEXT = 1;
public static final int APPMSGTYPE_IMG = 2;
public static final int APPMSGTYPE_AUDIO = 3;
public static final int APPMSGTYPE_VIDEO = 4;
public static final int APPMSGTYPE_URL = 5;
public static final int APPMSGTYPE_ATTACH = 6;
public static final int APPMSGTYPE_OPEN = 7;
public static final int APPMSGTYPE_EMOJI = 8;
public static final int APPMSGTYPE_VOICE_REMIND = 9;
public static final int APPMSGTYPE_SCAN_GOOD = 10;
public static final int APPMSGTYPE_GOOD = 13;
public static final int APPMSGTYPE_EMOTION = 15;
public static final int APPMSGTYPE_CARD_TICKET = 16;
public static final int APPMSGTYPE_REALTIME_SHARE_LOCATION = 17;
// public static final int APPMSGTYPE_TRANSFERS = 2e3;
public static final int APPMSGTYPE_RED_ENVELOPES = 2001;
public static final int APPMSGTYPE_READER_TYPE = 100001;
public static final int UPLOAD_MEDIA_TYPE_IMAGE = 1;
public static final int UPLOAD_MEDIA_TYPE_VIDEO = 2;
public static final int UPLOAD_MEDIA_TYPE_AUDIO = 3;
public static final int UPLOAD_MEDIA_TYPE_ATTACHMENT = 4;
}

View File

@@ -1,13 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 公共日志接口
* @author WesleyOne
* @create 2018/12/12
*/
public interface LogInterface {
public final Logger LOG = LoggerFactory.getLogger("WXROBLOG");
}

View File

@@ -1,12 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils;
/**
* @author WesleyOne
* @create 2018/12/19
*/
public class MoreConfig {
//存储群聊成员ID的键标识
public static final String SEND_MEMBER_ID = "sendMemberId";
public static final String SEND_MEMBER_NICKNAMW = "memberNickname";
}

View File

@@ -1,20 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils;
/**
* Created by xiaoxiaomo on 2017/5/6.
*/
public class SleepUtils {
/**
* 毫秒为单位
* @param time
*/
public static void sleep( long time ){
try {
Thread.sleep( time );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,64 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 消息类型
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月23日 下午12:15:00
* @version 1.0
*
*/
public enum MsgCodeEnum {
MSGTYPE_TEXT(1, "文本消息"),
MSGTYPE_IMAGE(3, "图片消息"),
MSGTYPE_VOICE(34, "语音消息"),
MSGTYPE_VERIFYMSG(37, "好友请求"),
MSGTYPE_POSSIBLEFRIEND_MSG(40, "POSSIBLEFRIEND_MSG"),
MSGTYPE_SHARECARD(42, "分享名片"),
MSGTYPE_VIDEO(43, "视频消息"),
MSGTYPE_EMOTICON(47, "表情消息"),
MSGTYPE_LOCATION(48, "位置消息"),
MSGTYPE_MEDIA(49, "分享链接"),
MSGTYPE_VOIPMSG(50, "VOIPMSG"),
MSGTYPE_STATUSNOTIFY(51, "状态通知"),
MSGTYPE_VOIPNOTIFY(52, "VOIPNOTIFY"),
MSGTYPE_VOIPINVITE(53, "VOIPINVITE"),
MSGTYPE_MICROVIDEO(62, "短视频消息"),
MSGTYPE_SYSNOTICE(9999, "SYSNOTICE"),
MSGTYPE_SYS(10000, "系统消息"),
MSGTYPE_RECALLED(10002, "撤回消息")
;
private static final Map<Integer, MsgCodeEnum> lookup = new HashMap<>();
static {
for (MsgCodeEnum s : EnumSet.allOf(MsgCodeEnum.class)){
lookup.put(s.getCode(), s);
}
}
public static MsgCodeEnum fromCode(int code) {
return lookup.get(code);
}
private int code;
private String type;
MsgCodeEnum(int code, String type) {
this.code = code;
this.type = type;
}
public int getCode() {
return code;
}
public String getType() {
return type;
}
}

View File

@@ -1,41 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
/**
* 消息类型枚举类
*
* @author https://github.com/yaphone
* @date 创建时间2017年5月13日 下午11:53:00
* @version 1.0
*
*/
public enum MsgTypeEnum {
TEXT("Text", "文本消息"),
MAP("MAP", "地理位置"),
PIC("Pic", "图片消息"),
VOICE("Voice", "语音消息"),
VIEDO("Viedo", "小视频消息"),
NAMECARD("NameCard", "名片消息"),
SYS("Sys", "系统消息"),
VERIFYMSG("VerifyMsg", "添加好友"),
// 地址分享
MEDIA("app", "文件消息");
private String type;
private String code;
MsgTypeEnum(String type, String code) {
this.type = type;
this.code = code;
}
public String getType() {
return type;
}
public String getCode() {
return code;
}
}

View File

@@ -1,13 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
/**
* 系统平台
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月8日 下午10:36:28
* @version 1.0
*
*/
public enum OsNameEnum {
WINDOWS, LINUX, DARWIN, MAC, OTHER
}

View File

@@ -1,25 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import lombok.Getter;
/**
* 返回结构枚举类
* <p>
* Created by xiaoxiaomo on 2017/5/6.
*/
@Getter
public enum ResultEnum {
SUCCESS("200", "成功"),
WAIT_CONFIRM("201", "请在手机上点击确认"),
WAIT_SCAN("400", "请扫描二维码");
private final String code;
private final String msg;
ResultEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@@ -1,49 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
public enum RetCodeEnum {
UNKOWN("9999", "未知"),
SUCCESS("0", "成功"),
TICKET_ERROR("-14", "ticket错误"),
PARAM_ERROR("1", "传入参数错误"),
NOT_LOGIN_WARN("1100", "未登录提示"),
NOT_LOGIN_CHECK("1101", "未检测到登录"),
COOKIE_INVALID_ERROR("1102", "cookie值无效"),
LOGIN_ENV_ERROR("1203", "当前登录环境异常为了安全起见请不要在web端进行登录"),
TOO_OFEN("1205", "操作频繁")
;
private static final Map<String, RetCodeEnum> lookup = new HashMap<String, RetCodeEnum>();
static {
for (RetCodeEnum s : EnumSet.allOf(RetCodeEnum.class)){
lookup.put(s.getCode(), s);
}
}
public static RetCodeEnum fromCode(String code) {
return lookup.get(code);
}
private String code;
private String type;
RetCodeEnum(String code, String type) {
this.code = code;
this.type = type;
}
public String getCode() {
return code;
}
public String getType() {
return type;
}
}

View File

@@ -1,48 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* @author WesleyOne
* @create 2018/12/21
*/
public enum SelectorEnum {
UNKOWN("9999", "未知"),
NORMAL("0", "正常"),
NEW_MSG("2", "有新消息"),
SELECTOR_3("3", "访问频繁#"),
MOD_CONTACT("4", "有人修改了自己的昵称或你修改了别人的备注"),
ADD_OR_DEL_CONTACT("6", "存在删除或者新增的好友信息"),
ENTER_OR_LEAVE_CHAT("7", "进入或离开聊天界面");
private static final Map<String, SelectorEnum> lookup = new HashMap<>();
static {
for (SelectorEnum s : EnumSet.allOf(SelectorEnum.class)) {
lookup.put(s.getCode(), s);
}
}
public static SelectorEnum fromCode(String code) {
return lookup.get(code);
}
private String code;
private String type;
SelectorEnum(String code, String type) {
this.code = code;
this.type = type;
}
public String getCode() {
return code;
}
public String getType() {
return type;
}
}

View File

@@ -1,65 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import com.jfinal.plugin.activerecord.Record;
import java.util.*;
/**
* 发送类型
* @author WesleyOne
* @create 2018/12/14
*/
public enum SendMsgType {
IMG("IMG","图片"),
FILE("FILE","文件"),
TEXT("TEXT","纯文本")
;
private String value;
private String name;
SendMsgType(String value, String name) {
this.value = value;
this.name = name;
}
private static final Map<String, SendMsgType> lookup = new HashMap<>();
public static List<Record> LIST_KV = new ArrayList<>();
static {
for (SendMsgType s : EnumSet.allOf(SendMsgType.class)){
lookup.put(s.toValue(), s);
LIST_KV.add(new Record().set("v",s.toValue()).set("n",s.toName()));
}
}
/**
* 获取枚举的值(整数值、字符串值等)
* @return
*/
public String toValue() {
return this.value;
}
public String toName() {
return this.name;
}
/**
* 根据值(整数值、字符串值等)获取相应的枚举类型
* @param value
* @return
*/
public static SendMsgType fromValue(String value) {
return lookup.get(value);
}
public boolean equal(SendMsgType type){
if (type != null && this.toValue().equals(type.toValue())){
return true;
}
return false;
}
}

View File

@@ -1,57 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* Created by xiaoxiaomo on 2017/5/7.
*/
public enum StorageLoginInfoEnum {
//URL
url("url",new String()),
fileUrl("fileUrl",new String()),
syncUrl("syncUrl",new String()),
//生成15位随机数
deviceid("deviceid",new String()),
//baseRequest
skey("skey",new String()),
wxsid("wxsid",new String()),
wxuin("wxuin",new String()),
pass_ticket("pass_ticket",new String()),
InviteStartCount("InviteStartCount",new Integer(0)),
// 登录用户登录时信息
User("User",new JSONObject()),
SyncKey("SyncKey",new JSONObject()),
synckey("synckey",new String()),
MemberCount("MemberCount",new String()),
MemberList("MemberList",new JSONArray()),
;
private String key;
private Object type;
StorageLoginInfoEnum(String key, Object type) {
this.key = key;
this.type = type;
}
public String getKey() {
return key;
}
public Object getType() {
return type;
}
}

View File

@@ -1,49 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
/**
* URL
* Created by xiaoxiaomo on 2017/5/6.
*/
public enum URLEnum {
BASE_URL("https://login.weixin.qq.com","基本的URL"),
UUID_URL(BASE_URL.url+"/jslogin","UUIDLURL"),
QRCODE_URL(BASE_URL.url+"/qrcode/","初始化URL"),
STATUS_NOTIFY_URL(BASE_URL.url+"/webwxstatusnotify?lang=zh_CN&pass_ticket=%s","微信状态通知"),
LOGIN_URL(BASE_URL.url+"/cgi-bin/mmwebwx-bin/login","登陆URL"),
INIT_URL("%s/webwxinit?r=%s&pass_ticket=%s","初始化URL"),
SYNC_CHECK_URL("/synccheck","检查心跳URL"),
WEB_WX_SYNC_URL("%s/webwxsync?sid=%s&skey=%s&pass_ticket=%s&lang=zh_CN","web微信消息同步URL"),
WEB_WX_GET_CONTACT("%s/webwxgetcontact","web微信获取联系人信息URL"),
WEB_WX_SEND_MSG("%s/webwxsendmsg","发送消息URL"),
WEB_WX_UPLOAD_MEDIA("%s/webwxuploadmedia?f=json", "上传文件到服务器"),
WEB_WX_GET_MSG_IMG("%s/webwxgetmsgimg", "下载图片消息"),
WEB_WX_GET_VOICE("%s/webwxgetvoice", "下载语音消息"),
WEB_WX_GET_VIEDO("%s/webwxgetvideo", "下载语音消息"),
WEB_WX_PUSH_LOGIN("%s/webwxpushloginurl", "不扫码登陆"),
WEB_WX_LOGOUT("%s/webwxlogout", "退出微信"),
WEB_WX_BATCH_GET_CONTACT("%s/webwxbatchgetcontact?type=ex&r=%s&lang=zh_CN&pass_ticket=%s", "查询群信息"),
WEB_WX_REMARKNAME("%s/webwxoplog?lang=zh_CN&pass_ticket=%s", "修改好友备注"),
WEB_WX_VERIFYUSER("%s/webwxverifyuser?r=%s&lang=zh_CN&pass_ticket=%s", "被动添加好友"),
WEB_WX_GET_MEDIA("%s/webwxgetmedia", "下载文件")
;
private String url;
private String msg;
URLEnum(String url, String msg) {
this.url = url;
this.msg = msg;
}
public String getUrl() {
return url;
}
}

View File

@@ -1,28 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums;
/**
* 确认添加好友Enum
*
* @author https://github.com/yaphone
* @date 创建时间2017年6月29日 下午9:47:14
* @version 1.0
*
*/
public enum VerifyFriendEnum {
ADD(2, "添加"),
ACCEPT(3, "接受");
private int code;
private String desc;
private VerifyFriendEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
}

View File

@@ -1,36 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums.parameters;
/**
*
* 基本请求参数
* 1. webWxInit 初始化
* 2. wxStatusNotify 微信状态通知
*
* <p>
* Created by xiaoxiaomo on 2017/5/7.
*/
public enum BaseParaEnum {
Uin("Uin", "wxuin"),
Sid("Sid", "wxsid"),
Skey("Skey", "skey"),
DeviceID("DeviceID", "pass_ticket");
private String para;
private String value;
BaseParaEnum(String para, String value) {
this.para = para;
this.value = value;
}
public String para() {
return para;
}
public Object value() {
return value;
}
}

View File

@@ -1,31 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums.parameters;
/**
* 登陆
* <p>
* Created by xiaoxiaomo on 2017/5/7.
*/
public enum LoginParaEnum {
LOGIN_ICON("loginicon", "true"),
UUID("uuid", ""),
TIP("tip", "0"),
R("r", ""),
_1("_", "");
private String para;
private String value;
LoginParaEnum(String para, String value) {
this.para = para;
this.value = value;
}
public String para() {
return para;
}
public String value() {
return value;
}
}

View File

@@ -1,31 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums.parameters;
/**
* 状态通知
* <p>
* Created by xiaoxiaomo on 2017/5/7.
*/
public enum StatusNotifyParaEnum {
CODE("Code", "3"),
FROM_USERNAME("FromUserName", ""),
TO_USERNAME("ToUserName", ""),
//时间戳
CLIENT_MSG_ID("ClientMsgId", "");
private String para;
private String value;
StatusNotifyParaEnum(String para, String value) {
this.para = para;
this.value = value;
}
public String para() {
return para;
}
public String value() {
return value;
}
}

View File

@@ -1,30 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.enums.parameters;
/**
* UUID
* <p>
* Created by xiaoxiaomo on 2017/5/7.
*/
public enum UUIDParaEnum {
APP_ID("appid", "wx782c26e4c19acffb"),
FUN("fun", "new"),
LANG("lang", "zh_CN"),
_1("_", "时间戳");
private String para;
private String value;
UUIDParaEnum(String para, String value) {
this.para = para;
this.value = value;
}
public String para() {
return para;
}
public String value() {
return value;
}
}

View File

@@ -1,301 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.tools;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vdurmont.emoji.EmojiParser;
import org.ruoyi.common.wechat.itchat4j.utils.Config;
import org.ruoyi.common.wechat.itchat4j.utils.enums.OsNameEnum;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 常用工具类
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月8日 下午10:59:55
* @version 1.0
*
*/
public class CommonTools {
public static boolean printQr(String qrPath) {
switch (Config.getOsNameEnum()) {
case WINDOWS:
if (Config.getOsNameEnum().equals(OsNameEnum.WINDOWS)) {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("cmd /c start " + qrPath);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case MAC:
if (Config.getOsNameEnum().equals(OsNameEnum.MAC)) {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("open " + qrPath);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
default:
break;
}
return true;
}
public static boolean clearScreen() {
switch (Config.getOsNameEnum()) {
case WINDOWS:
if (Config.getOsNameEnum().equals(OsNameEnum.WINDOWS)) {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("cmd /c " + "cls");
} catch (Exception e) {
e.printStackTrace();
}
}
break;
default:
break;
}
return true;
}
/**
* 正则表达式处理工具
*
* @author https://github.com/yaphone
* @date 2017年4月9日 上午12:27:10
* @return
*/
public static Matcher getMatcher(String regEx, String text) {
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(text);
return matcher;
}
/**
* xml解析器
*
* @author https://github.com/yaphone
* @date 2017年4月9日 下午6:24:25
* @param text
* @return
*/
public static Document xmlParser(String text) {
Document doc = null;
StringReader sr = new StringReader(text);
InputSource is = new InputSource(sr);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(is);
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
public static JSONObject structFriendInfo(JSONObject userObj) {
Map<String, Object> friendInfoTemplate = new HashMap<String, Object>();
friendInfoTemplate.put("UserName", "");
friendInfoTemplate.put("City", "");
friendInfoTemplate.put("DisplayName", "");
friendInfoTemplate.put("PYQuanPin", "");
friendInfoTemplate.put("RemarkPYInitial", "");
friendInfoTemplate.put("Province", "");
friendInfoTemplate.put("KeyWord", "");
friendInfoTemplate.put("RemarkName", "");
friendInfoTemplate.put("PYInitial", "");
friendInfoTemplate.put("EncryChatRoomId", "");
friendInfoTemplate.put("Alias", "");
friendInfoTemplate.put("Signature", "");
friendInfoTemplate.put("NickName", "");
friendInfoTemplate.put("RemarkPYQuanPin", "");
friendInfoTemplate.put("HeadImgUrl", "");
friendInfoTemplate.put("UniFriend", 0);
friendInfoTemplate.put("Sex", 0);
friendInfoTemplate.put("AppAccountFlag", 0);
friendInfoTemplate.put("VerifyFlag", 0);
friendInfoTemplate.put("ChatRoomId", 0);
friendInfoTemplate.put("HideInputBarFlag", 0);
friendInfoTemplate.put("AttrStatus", 0);
friendInfoTemplate.put("SnsFlag", 0);
friendInfoTemplate.put("MemberCount", 0);
friendInfoTemplate.put("OwnerUin", 0);
friendInfoTemplate.put("ContactFlag", 0);
friendInfoTemplate.put("Uin", 0);
friendInfoTemplate.put("StarFriend", 0);
friendInfoTemplate.put("Statues", 0);
friendInfoTemplate.put("MemberList", new ArrayList<Object>());
JSONObject r = new JSONObject();
Set<String> keySet = friendInfoTemplate.keySet();
for (String key : keySet) {
if (userObj.containsKey(key)) {
r.put(key, userObj.get(key));
} else {
r.put(key, friendInfoTemplate.get(key));
}
}
return r;
}
public static String getSynckey(JSONObject obj) {
JSONArray obj2 = obj.getJSONArray("List");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < obj2.size(); i++) {
JSONObject obj3 = (JSONObject) JSON.toJSON(obj2.get(i));
sb.append(obj3.get("Val") + "|");
}
return sb.substring(0, sb.length() - 1); // 656159784|656159911|656159873|1491905341
}
public static JSONObject searchDictList(List<JSONObject> list, String key, String value) {
JSONObject r = null;
for (JSONObject i : list) {
if (i.getString(key).equals(value)) {
r = i;
break;
}
}
return r;
}
/**
* 处理emoji表情
*
* @author https://github.com/yaphone
* @date 2017年4月23日 下午2:39:04
* @param d
* @param k
*/
public static void emojiFormatter(JSONObject d, String k) {
// Matcher matcher = getMatcher("<span class=\"emoji emoji(.{1,10})\"></span>", d.getString(k));
Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></span>", d.getString(k));
StringBuilder sb = new StringBuilder();
String content = d.getString(k);
int lastStart = 0;
while (matcher.find()) {
String str = matcher.group(1);
if (str.length() == 6) {
} else if (str.length() == 10) {
} else {
str = "&#x" + str + ";";
String tmp = content.substring(lastStart, matcher.start());
sb.append(tmp + str);
lastStart = matcher.end();
}
}
if (lastStart < content.length()) {
sb.append(content.substring(lastStart));
}
if (sb.length() != 0) {
d.put(k, EmojiParser.parseToUnicode(sb.toString()));
} else {
d.put(k, content);
}
}
/**
* 转化成alias
* @param d
* @param k
*/
public static void emojiFormatter2(JSONObject d, String k) {
Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></span>", d.getString(k));
StringBuilder sb = new StringBuilder();
String content = d.getString(k);
int lastStart = 0;
while (matcher.find()) {
String str = matcher.group(1);
if (str.length() == 6) {
} else if (str.length() == 10) {
} else {
str = "&#x" + str + ";";
String tmp = content.substring(lastStart, matcher.start());
sb.append(tmp + str);
lastStart = matcher.end();
}
}
if (lastStart < content.length()) {
sb.append(content.substring(lastStart));
}
if (sb.length() != 0) {
d.put(k, EmojiParser.parseToAliases(EmojiParser.parseToUnicode(sb.toString())));
} else {
d.put(k, content);
}
}
/**
* 消息格式化
*
* @author https://github.com/yaphone
* @date 2017年4月23日 下午4:19:08
* @param d
* @param k
*/
public static void msgFormatter(JSONObject d, String k) {
d.put(k, d.getString(k).replace("<br/>", "\n"));
emojiFormatter(d, k);
// TODO 与emoji表情有部分兼容问题目前暂未处理解码处理 d.put(k,
// StringEscapeUtils.unescapeHtml4(d.getString(k)));
}
public static void main(String[] args) {
String str2 = "三生三世<span class=\"emoji emoji1f46f\"></span>十三水<span class=\"emoji emoji1f440\"></span>";
Matcher matcher = getMatcher("<span class=\"emoji emoji(.+?)\"></span>", str2);
StringBuilder sb = new StringBuilder();
String content = str2;
int lastStart = 0;
while (matcher.find()) {
String str = matcher.group(1);
if (str.length() == 6) {
} else if (str.length() == 10) {
} else {
str = "&#x" + str + ";";
String tmp = content.substring(lastStart, matcher.start());
sb.append(tmp + str);
lastStart = matcher.end();
}
}
if (lastStart < content.length()) {
sb.append(content.substring(lastStart));
}
if (sb.length() != 0) {
System.out.println(EmojiParser.parseToUnicode(sb.toString()));
System.out.println(EmojiParser.parseToAliases(EmojiParser.parseToUnicode(sb.toString())));
System.out.println(EmojiParser.removeAllEmojis(sb.toString()));
}
}
}

View File

@@ -1,77 +0,0 @@
package org.ruoyi.common.wechat.itchat4j.utils.tools;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.ruoyi.common.wechat.itchat4j.beans.BaseMsg;
import org.ruoyi.common.wechat.itchat4j.core.Core;
import org.ruoyi.common.wechat.itchat4j.core.CoreManage;
import org.ruoyi.common.wechat.itchat4j.utils.LogInterface;
import org.ruoyi.common.wechat.itchat4j.utils.enums.MsgTypeEnum;
import org.ruoyi.common.wechat.itchat4j.utils.enums.URLEnum;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* 下载工具类
*
* @author https://github.com/yaphone
* @date 创建时间2017年4月21日 下午11:18:46
* @version 1.0
*
*/
public class DownloadTools implements LogInterface {
private static Logger logger = Logger.getLogger("UTILLOG");
/**
* 处理下载任务
*
* @author https://github.com/yaphone
* @date 2017年4月21日 下午11:00:25
* @param msg
* @param type
* @param path
* @return
*/
public static Object getDownloadFn(BaseMsg msg, String type, String path, String uniqueKey) {
Core core = CoreManage.getInstance(uniqueKey);
Map<String, String> headerMap = new HashMap<String, String>();
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
String url = "";
if (type.equals(MsgTypeEnum.PIC.getType())) {
url = String.format(URLEnum.WEB_WX_GET_MSG_IMG.getUrl(), (String) core.getLoginInfo().get("url"));
} else if (type.equals(MsgTypeEnum.VOICE.getType())) {
url = String.format(URLEnum.WEB_WX_GET_VOICE.getUrl(), (String) core.getLoginInfo().get("url"));
} else if (type.equals(MsgTypeEnum.VIEDO.getType())) {
headerMap.put("Range", "bytes=0-");
url = String.format(URLEnum.WEB_WX_GET_VIEDO.getUrl(), (String) core.getLoginInfo().get("url"));
} else if (type.equals(MsgTypeEnum.MEDIA.getType())) {
headerMap.put("Range", "bytes=0-");
url = String.format(URLEnum.WEB_WX_GET_MEDIA.getUrl(), (String) core.getLoginInfo().get("fileUrl"));
params.add(new BasicNameValuePair("sender", msg.getFromUserName()));
params.add(new BasicNameValuePair("mediaid", msg.getMediaId()));
params.add(new BasicNameValuePair("filename", msg.getFileName()));
}
params.add(new BasicNameValuePair("msgid", msg.getNewMsgId()));
params.add(new BasicNameValuePair("skey", (String) core.getLoginInfo().get("skey")));
HttpEntity entity = core.getMyHttpClient().doGet(url, params, true, headerMap);
try {
OutputStream out = new FileOutputStream(path);
byte[] bytes = EntityUtils.toByteArray(entity);
out.write(bytes);
out.flush();
out.close();
} catch (Exception e) {
logger.info(e.getMessage());
return false;
}
return null;
};
}

View File

@@ -1,11 +0,0 @@
package org.ruoyi.common.wechat.web.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 不检查登录
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface UnCheckLogin {
}

View File

@@ -1,56 +0,0 @@
package org.ruoyi.common.wechat.web.base;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 错误管理
* @author WesleyOne
* @create 2018/7/28
*/
public enum BaseError {
UNPERMISSION("09","没有操作权限"),
UNLOGIN("01","未登录或登录过期"),
OPERATION_ERR("8899","操作失败!"),
NORMAL_ERR("8999","参数异常"),
SYSTEM_ERR("9999","系统异常");
private String code;
private String msg;
BaseError(String code, String msg) {
this.code = code;
this.msg = msg;
}
private static final Map<String, BaseError> lookup = new HashMap<String, BaseError>();
static {
for (BaseError s : EnumSet.allOf(BaseError.class))
lookup.put(s.getMsg(), s);
}
/**
* 获取枚举的值(整数值、字符串值等)
* @return
*/
public String getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
/**
* 根据值(整数值、字符串值等)获取相应的枚举类型
* @param code
* @return
*/
public static BaseError fromValue(String code) {
return lookup.get(code);
}
}

View File

@@ -1,40 +0,0 @@
package org.ruoyi.common.wechat.web.base;
import java.io.Serializable;
/**
* 统一异常对象
* @author WesleyOne
* @create 2018/7/28
*/
public class BaseException extends Exception implements Serializable {
private static final long serialVersionUID = 2007525058641283836L;
private String code;
public BaseException(String code, String msg) {
super(msg);
this.code = code;
}
public BaseException(BaseError baseError) {
super(baseError.getMsg());
this.code = baseError.getCode();
}
public BaseException(String msg) {
super(msg);
this.code = BaseError.NORMAL_ERR.getCode();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}

View File

@@ -1,85 +0,0 @@
package org.ruoyi.common.wechat.web.base;
/**
* @author WesleyOne
* @create 2018/7/28
*/
public class BaseResponse<T> {
public static BaseResponse OK = new BaseResponse();
private String code = "00";
private String message = "操作成功";
private T data;
public BaseResponse() {
}
public BaseResponse(T data) {
this.data = data;
}
public BaseResponse(String code, String message) {
this.code = code;
this.message = message;
}
public static BaseResponse success(){
return new BaseResponse();
}
public static BaseResponse success(Object o){
return new BaseResponse(o);
}
public static BaseResponse error(String code,String msg){
BaseResponse r = new BaseResponse();
r.setCode(code);
r.setMessage(msg);
return r;
}
public static BaseResponse error(BaseError baseError){
BaseResponse r = new BaseResponse();
r.setCode(baseError.getCode());
r.setMessage(baseError.getMsg());
return r;
}
/**
* 未登录返回
* @return
*/
public static BaseResponse unLogin(){
BaseResponse r = new BaseResponse();
r.setCode(BaseError.UNLOGIN.getCode());
r.setMessage(BaseError.UNLOGIN.getMsg());
return r;
}
/**
* 无权限返回
* @return
*/
public static BaseResponse unPermission(){
BaseResponse r = new BaseResponse();
r.setCode(BaseError.UNPERMISSION.getCode());
r.setMessage(BaseError.UNPERMISSION.getMsg());
return r;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -1,30 +0,0 @@
package org.ruoyi.common.wechat.web.cache;
import org.ruoyi.common.wechat.web.utils.LRUCache;
import java.util.LinkedHashMap;
/**
* 简单的本地会话存储
* @author WesleyOne
* @create 2018/9/25
*/
public class UserSession {
public static LinkedHashMap<String,String> USERSESSION_CACHE = new LRUCache<String, String>(64);
public static void addUserSession(String username,String userSession){
USERSESSION_CACHE.put(username,userSession);
}
public static void delUserSession(String username){
USERSESSION_CACHE.remove(username);
}
public static boolean checkUserSession(String username,String userSession){
String s = USERSESSION_CACHE.get(username);
if (userSession!=null&&userSession.equals(s)){
return true;
}
return false;
}
}

View File

@@ -1,153 +0,0 @@
package org.ruoyi.common.wechat.web.common;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.*;
import com.jfinal.json.FastJsonFactory;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;
import org.ruoyi.common.wechat.itchat4j.core.CoreManage;
import org.ruoyi.common.wechat.web.constant.UploadConstant;
import org.ruoyi.common.wechat.web.interceptor.ExceptionInterceptor;
import org.ruoyi.common.wechat.web.model._MappingKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* JFinal项目的核心配置
* 详情查看官方文档
* https://www.jfinal.com/doc
*
* @author WesleyOne
*/
public class MyConfig extends JFinalConfig {
public final Logger LOG = LoggerFactory.getLogger(this.getClass());
public static void main(String[] args) {
UndertowServer.start(MyConfig.class, 8180, true);
}
/**
* 配置常量
*/
@Override
public void configConstant(Constants me) {
PropKit.use("appConfig.properties");
me.setDevMode(PropKit.getBoolean("devMode", false));
//上传的文件的最大50M
me.setMaxPostSize(10 * 1024 * 1024);
me.setEncoding("UTF-8");
me.setJsonFactory(new FastJsonFactory());
me.setError404View("/WEB-INF/templates/404.html");
}
/**
* 配置路由
*/
@Override
public void configRoute(Routes me) {
me.add(new MyRoute());
me.add(new OutRoute());
}
@Override
public void configEngine(Engine me) {
me.setDevMode(PropKit.use("appConfig.properties").getBoolean("devMode", false));
me.addSharedFunction("/WEB-INF/templates/bs4temp/layout.html");
me.addSharedObject("imgDomain" , UploadConstant.IMG_URL);
me.addSharedObject("filedomain" , UploadConstant.FILE_URL);
}
/**
* 配置插件
*/
@Override
public void configPlugin(Plugins me) {
// 配置 druid 数据库连接池插件
DruidPlugin druidPlugin = createDruidPlugin();
druidPlugin.addFilter(new StatFilter());
WallFilter wall = new WallFilter();
wall.setDbType("mysql");
druidPlugin.addFilter(wall);
druidPlugin.setInitialSize(1);
me.add(druidPlugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
_MappingKit.mapping(arp);
arp.setDialect(new MysqlDialect());
arp.setShowSql(PropKit.use("appConfig.properties").getBoolean("devMode", false));
arp.getEngine().setSourceFactory(new ClassPathSourceFactory());
me.add(arp);
}
public static DruidPlugin createDruidPlugin() {
return new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
}
/**
* 配置全局拦截器
*/
@Override
public void configInterceptor(Interceptors me) {
me.add(new ExceptionInterceptor());
}
/**
* 配置处理器
*/
@Override
public void configHandler(Handlers me) {
}
@Override
public void afterJFinalStart() {
System.setProperty("jsse.enableSNIExtension", "false");
// 检查文件夹(/热登录/下载根目录)是否存在
checkFileExist();
// 热登陆操作
CoreManage.reload();
}
@Override
public void beforeJFinalStop() {
CoreManage.persistence();
}
/**
* 检查文件夹(/热登录/下载根目录)是否存在
*/
private void checkFileExist() {
String hotReloadDir = PropKit.get("hotReloadDir");
String downloadPath = PropKit.get("download_path");
String logPath = PropKit.get("log_path");
File hotReloadFile = new File(hotReloadDir);
if (!hotReloadFile.exists()){
if (!hotReloadFile.mkdirs()) {
LOG.error("热加载文件夹创建失败[{}]",hotReloadDir);
}
}
File downloadFile = new File(downloadPath);
if (!downloadFile.exists()){
if (!downloadFile.mkdirs()) {
LOG.error("下载文件夹创建失败[{}]",downloadPath);
}
}
File logFile = new File(logPath);
if (!logFile.exists()){
if (!logFile.mkdirs()) {
LOG.error("日志文件夹创建失败[{}]",logPath);
}
}
}
}

View File

@@ -1,30 +0,0 @@
package org.ruoyi.common.wechat.web.common;
import com.jfinal.config.Routes;
import org.ruoyi.common.wechat.web.controller.*;
import org.ruoyi.common.wechat.web.interceptor.VisitLogInterceptor;
/**
* 管理后台路由统一管理
* @author wesleyOne
*/
public class MyRoute extends Routes {
@Override
public void config() {
//设置视图根目录
setBaseViewPath("/WEB-INF/templates");
//设置拦截器,前面的先执行
addInterceptor(new VisitLogInterceptor());
//添加路由
add("/", IndexController.class);
add("/rob",RobotController.class);
add("/robwk",RobotWorkController.class);
add("/relate",RelateController.class);
add("/kw",KeyWordController.class);
add("/upload",UploadController.class);
add("/tool",ToolController.class);
}
}

View File

@@ -1,21 +0,0 @@
package org.ruoyi.common.wechat.web.common;
import com.jfinal.config.Routes;
import org.ruoyi.common.wechat.web.controller.ExtendController;
import org.ruoyi.common.wechat.web.interceptor.VisitLogInterceptor4down;
/**
* 对外路由统一管理
* @author WesleyOne
* @create 2018/9/25
*/
public class OutRoute extends Routes {
@Override
public void config() {
//设置视图根目录
setBaseViewPath("/WEB-INF/templates");
addInterceptor(new VisitLogInterceptor4down());
//添加路由
add("/ext", ExtendController.class);
}
}

View File

@@ -1,21 +0,0 @@
package org.ruoyi.common.wechat.web.constant;
/**
* @author WesleyOne
* @create 2018/12/13
*/
public class ConfigKeys {
/**
* 默认全局关键字回复用昵称该字段超过16字符防止与用户昵称冲突
*
* http://kf.qq.com/touch/wxappfaq/150910F322eY150910eIV32Q.html?platform=14
* 微信昵称设置规则
* 最多可设置16个汉字可设置含有中文、英文、数字、符号组合的昵称但不建议设置特殊字符。
* 温馨提示1个符号相当于一个汉字2个数字/英文相当于1个汉字
*/
public static final String DEAFAULT_KEYWORD = "默认全局关键字回复用昵称-请勿修改";
public static final String DEAFAULT_WELCOME = "默认群欢迎新人用-请勿修改";
}

Some files were not shown because too many files have changed in this diff Show More