Files
wechat_ipad_pro/api/service/userService.go
2026-02-17 13:06:23 +08:00

553 lines
19 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"encoding/hex"
"fmt"
"strconv"
"time"
"xiawan/wx/api/req"
"xiawan/wx/api/vo"
"xiawan/wx/clientsdk/baseinfo"
"xiawan/wx/clientsdk/baseutils"
"xiawan/wx/clientsdk/proxynet"
"xiawan/wx/db"
"xiawan/wx/db/table"
"xiawan/wx/protobuf/wechat"
"xiawan/wx/srv/wxcore"
"xiawan/wx/srv/wxface"
"github.com/gin-gonic/gin"
"github.com/gogo/protobuf/proto"
)
// logOutService 退出登录
func LogOutService(queryKey string) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
// 在退出登录前先清理WebSocket连接
currentTaskMgr := connect.GetWXTaskMgr()
if taskMgr, ok := currentTaskMgr.(*wxcore.WXTaskMgr); ok {
wsTask := taskMgr.SocketMsgTask
userUUID := wxAccount.GetUserInfo().UUID
// 清理WebSocket连接
existingConn := wsTask.GetWebSocket(userUUID)
if existingConn != nil {
fmt.Println("退出登录时清理WebSocket连接:", userUUID)
existingConn.Close()
wsTask.DeleteWebSocket(userUUID)
}
// 禁用WebSocket功能
wsTask.SetWebSocketEnabled(false)
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SendLogoutRequest()
if err != nil {
return vo.NewFail(err.Error())
}
return vo.NewSuccess(gin.H{}, "退出成功!")
})
}
// SendDelContactService 删除好友
func SendDelContactService(queryKey string, m req.DelContactModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SendDelContactRequest(m.DelUserName)
if err != nil {
return vo.NewFail(err.Error())
}
return vo.NewSuccess(gin.H{}, "删除成功!")
})
}
// OnlineInfoService 获取登录设备信息
func OnlineInfoService(queryKey string) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
} else if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("账号离线,自动上线失败loginState == " + strconv.Itoa(int(wxAccount.GetLoginState())))
}
reqInvoker := iwxConnect.GetWXReqInvoker()
resp, err := reqInvoker.SendOnlineInfo()
if err != nil {
return vo.NewFail(err.Error())
}
deviceInfoList := make([]gin.H, 0)
for _, deviceInfo := range resp.GetOnlineList() {
deviceInfoList = append(deviceInfoList, gin.H{
"deviceType": deviceInfo.GetDeviceType(),
"deviceId": hex.EncodeToString(deviceInfo.GetDeviceID()),
"clientKey": deviceInfo.GetClientKey(),
"onlineStatus": deviceInfo.GetOnlineStatus(),
})
}
return vo.NewSuccessObj(gin.H{
"onlineCount": resp.GetOnlineCount(),
"onlineList": deviceInfoList,
}, "")
})
}
// GetProfileService 获取个人资料详细信息
func GetProfileService(queryKey string) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
} else if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("账号离线,自动上线失败loginState == " + strconv.Itoa(int(wxAccount.GetLoginState())))
}
reqInvoker := iwxConnect.GetWXReqInvoker()
/*err := reqInvoker.SendGetProfileRequest()
if err != nil {
return vo.NewFail("获取个人资料失败")
}*/
profile, err := reqInvoker.SendGetProfileNewRequest()
if err != nil {
return vo.NewFail("获取个人资料失败")
}
return vo.NewSuccessObj(profile, "")
})
}
// SendModifyUserInfoRequest 修改资料
func SendModifyUserInfoRequestService(queryKey string, m req.ModifyUserInfo) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SendModifyUserInfoRequest(m.City, m.Country, m.NickName, m.Province, m.Signature, m.Sex, m.InitFlag)
if err != nil {
return vo.NewFail("修改资料失败!")
}
return vo.NewSuccessObj(nil, "修改资料成功!")
})
}
// 修改名称
func UpdateNickNameService(queryKey string, m req.UpdateNickNameModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SendUpdateNickNameRequest(m.Scene, m.Val)
if err != nil {
return vo.NewFail("修改名称失败!")
}
return vo.NewSuccessObj(nil, "修改成功!")
})
}
// 设置名称
func SetNickNameService(queryKey string, m req.UpdateNickNameModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SendUpdateNickNameRequest(m.Scene, m.Val)
if err != nil {
return vo.NewFail("修改失败!")
}
return vo.NewSuccessObj(nil, "修改成功!")
})
}
// 修改姓别
func SetSexService(queryKey string, m req.UpdateSexModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !connect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := connect.GetWXReqInvoker()
err := reqInvoker.SetSexService(m.Sex, m.Country, m.City, m.Province)
if err != nil {
return vo.NewFail("修改失败!")
}
return vo.NewSuccessObj(nil, "修改成功!")
})
}
func GetRedisSyncMsgService(queryKey string) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(connect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := connect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
} else if !connect.CheckOnLineStatus() {
return vo.NewFail("账号离线,自动上线失败loginState == " + strconv.Itoa(int(wxAccount.GetLoginState())))
}
reqInvoker := connect.GetWXReqInvoker()
resp, err := reqInvoker.SendWxSyncMsg(queryKey)
// 如果没有同步到数据则返回
cmdList := resp.GetCmdList()
syncCount := cmdList.GetCount()
messageResp := new(table.SyncMessageResponse)
// 遍历同步的信息和群
itemList := cmdList.GetItemList()
for index := uint32(0); index < syncCount; index++ {
item := itemList[index]
itemID := item.GetCmdId()
// 同步到消息
if itemID == baseinfo.CmdIDAddMsg {
addMsg := &wechat.AddMsg{}
err := proto.Unmarshal(item.CmdBuf.Data, addMsg)
if err != nil {
baseutils.PrintLog(err.Error())
continue
}
}
messageResp.SetMessage(item.GetCmdBuf().GetData(), int32(itemID))
}
//发布同步信息消息
if err != nil {
return vo.NewFail(err.Error())
}
messageResp.Key = resp.KeyBuf
return vo.NewSuccessObj(*messageResp, "成功")
})
}
// SendChangePwdRequestService 更改密码
func SendChangePwdRequestService(queryKey string, m req.SendChangePwdRequestModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
resp, err := reqInvoker.SendChangePwdRequest(m.OldPass, m.NewPass, m.OpCode)
if err != nil {
return vo.NewFail("SendChangePwdRequestService err:" + err.Error())
}
return vo.NewSuccessObj(resp, "")
})
}
// 上传头像
func UploadHeadImageService(queryKey string, m req.UploadHeadImageModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
resp, err := reqInvoker.UploadHeadImage(m.Base64)
if err != nil {
return vo.NewFail("SendChangePwdRequestService err:" + err.Error())
}
return vo.NewSuccessObj(resp, "成功")
})
}
// endModifyRemarkRequestService 修改备注
func SendModifyRemarkRequestService(queryKey string, m req.SendModifyRemarkRequestModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
err := reqInvoker.SendModifyRemarkRequest(m.UserName, m.RemarkName)
if err != nil {
return vo.NewFail("SendChangePwdRequestService err:" + err.Error())
}
return vo.NewSuccessObj(nil, "成功")
})
}
// UpdateAutoPassService 修改加好友需要验证属性
func UpdateAutoPassService(queryKey string, m req.UpdateAutopassModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
err := reqInvoker.UpdateAutopassRequest(m.SwitchType)
if err != nil {
return vo.NewFail("UpdateAutoPassService err:" + err.Error())
}
return vo.NewSuccessObj(nil, "成功")
})
}
// 设置微信号
func SetWechatService(queryKey string, m req.AlisaModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
rsp, err := reqInvoker.SetWechatRequest(m.Alisa)
if err != nil {
return vo.NewFail("UpdateAutoPassService err:" + err.Error())
}
return vo.NewSuccessObj(rsp, "成功")
})
}
// 修改步数
func UpdateStepNumberService(queryKey string, m req.UpdateStepNumberModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
rsp, err := reqInvoker.UpdateStepNumberRequest(m.Number)
if err != nil {
return vo.NewFail("UpdateStepNumberService err:" + err.Error())
}
return vo.NewSuccessObj(rsp, "成功")
})
}
// 获取步数
func GetUserRankLikeCountService(queryKey string, m req.UserRankLikeModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
rsp, err := reqInvoker.SendGetUserRankLikeCountRequest(m.RankId)
if err != nil {
return vo.NewFail("UpdateStepNumberService err:" + err.Error())
}
return vo.NewSuccessObj(rsp, "成功")
})
}
// 设置添加我的方式
func SetFunctionSwitchService(queryKey string, m req.WxFunctionSwitchModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
req := &wechat.FunctionSwitch{
FunctionId: proto.Uint32(m.Function),
SwitchValue: proto.Uint32(m.Value),
}
buffer, err := proto.Marshal(req)
cmdItem := baseinfo.ModifyItem{
CmdID: 0x17,
Len: uint32(len(buffer)),
Data: buffer,
}
var cmdItems []*baseinfo.ModifyItem
cmdItems = append(cmdItems, &cmdItem)
err = reqInvoker.SendOplogRequest(cmdItems)
if err != nil {
return vo.NewFail("SetFunctionSwitchService err:" + err.Error())
}
return vo.NewSuccessObj("ok", "成功")
})
}
// 设置拍一拍名称
func SetSendPatService(queryKey string, m req.SetSendPatModel) vo.DTO {
return checkExIdPerformNoCreateConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
wxAccount := iwxConnect.GetWXAccount()
loginState := wxAccount.GetLoginState()
//判断在线情况
if !iwxConnect.CheckOnLineStatus() {
return vo.NewFail("你已退出登录")
} else if loginState == baseinfo.MMLoginStateNoLogin {
return vo.NewFail("该账号需要重新登录loginState == MMLoginStateNoLogin ")
}
reqInvoker := iwxConnect.GetWXReqInvoker()
req := &wechat.PatMod{
Value: proto.Int64(8),
Name: proto.String(m.Value),
}
buffer, err := proto.Marshal(req)
cmdItem := baseinfo.ModifyItem{
CmdID: 222,
Len: uint32(len(buffer)),
Data: buffer,
}
var cmdItems []*baseinfo.ModifyItem
cmdItems = append(cmdItems, &cmdItem)
err = reqInvoker.SendOplogRequest(cmdItems)
if err != nil {
return vo.NewFail("SetSendPatService err:" + err.Error())
}
return vo.NewSuccessObj("ok", "成功")
})
}
// SetProxyService 修改socks5代理
func SetProxyService(queryKey string, model req.GetLoginQrCodeModel) vo.DTO {
key := fmt.Sprintf("%s%s", "wechat:Proxy:", queryKey)
// 判断代理为空,清除 redis 缓存
if len(model.Proxy) == 0 {
//删除缓存
db.DelObj(key)
}
return getExistWxConnect(queryKey, func(iwxConnect wxface.IWXConnect, newIWXConnect bool) vo.DTO {
if iwxConnect == nil {
return vo.NewFail("链接不存在! 但代理缓存已重置Proxy:【" + model.Proxy + "】")
}
wxAccount := iwxConnect.GetWXAccount()
errMsg := ""
newProxyUrl := ""
oldProxyUrl := wxAccount.GetUserInfo().GetProxyUrl()
// 断开连接后 之后重新使用新代理建立连接
iwxConnect.Stop()
// 等待 500 毫秒
time.Sleep(time.Millisecond * 500)
// 判断是否删除代理
if len(model.Proxy) == 0 {
// 删除代理
wxAccount.GetUserInfo().RemoveProxy()
newProxyUrl = ""
} else {
// 修改代理
proxyInfo := proxynet.ParseWXProxyInfo(model.Proxy)
dialer := proxyInfo.GetDialer()
if dialer != nil {
wxAccount := iwxConnect.GetWXAccount()
wxAccount.GetUserInfo().SetProxy(proxyInfo)
newProxyUrl = wxAccount.GetUserInfo().GetProxyUrl()
} else {
errMsg = "代理链接格式错误, 正确示例socks5://username:password@ipv4:port"
}
}
if len(errMsg) > 0 {
return vo.NewFail(errMsg)
}
// 重新二次登录
go func() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("设置代理: %v\n", r)
}
}()
// 等 500 毫秒后重新初始化
time.Sleep(time.Millisecond * 500)
InitLoginStatusService(queryKey, false, true, model)
//存redis缓存
error := db.SETObj(key, model)
if error != nil {
}
}()
return vo.NewSuccess(gin.H{
"oldProxyUrl": oldProxyUrl,
"newProxyUrl": newProxyUrl,
}, errMsg)
})
}