package wxrouter import ( "errors" "fmt" "time" "xiawan/wx/clientsdk" "xiawan/wx/clientsdk/baseinfo" "xiawan/wx/clientsdk/baseutils" "xiawan/wx/db" "xiawan/wx/protobuf/wechat" "xiawan/wx/srv/wxcore" "xiawan/wx/srv/wxface" ) // WXManualAuthRouter 扫码登陆响应路由 type WXManualAuthRouter struct { wxcore.WXBaseRouter } // Handle 处理conn业务的方法 func (glqr *WXManualAuthRouter) Handle(wxResp wxface.IWXResponse) error { defer wxcore.TryE("WXManualAuthRouter Handle") currentWXConn := wxResp.GetWXConncet() currentWXAccount := currentWXConn.GetWXAccount() currentCache := currentWXConn.GetWXCache() currentInvoker := currentWXConn.GetWXReqInvoker() currentUserInfo := currentWXAccount.GetUserInfo() currentPackHeader := wxResp.GetPackHeader() currentWXSyncMgr := currentWXConn.GetWXSyncMgr() //currentWXFileHelperMgr := currentWXConn.GetWXFileHelperMgr() // 解析扫码登陆响应 var manualResponse wechat.ManualAuthResponse err := clientsdk.ParseResponseData(currentUserInfo, currentPackHeader, &manualResponse) if err != nil { // 请求出问题了,判断是否掉线,并重连 time.Sleep(1 * time.Second) go currentWXConn.CheckOnLineStatusLogin() return err } retCode := manualResponse.GetBaseResponse().GetRet() // 重定向 switch retCode { case baseinfo.MMErrIdcRedirect: currentUserInfo.ShortHost = manualResponse.GetDnsInfo().GetNewHostList().GetList()[1].GetSubstitute() currentUserInfo.LongHost = manualResponse.GetDnsInfo().GetNewHostList().GetList()[0].GetSubstitute() //提交登录日志 db.SetLoginLog("ManualAuth", currentWXAccount, fmt.Sprintf("重定向登录 ShortHost :%s,LongHost:%s", currentUserInfo.ShortHost, currentUserInfo.LongHost), retCode) // 关闭重新启动,再次发送登陆请求 currentWXConn.Stop() time.Sleep(2 * time.Second) _ = currentWXConn.Start() qrcodeInfo := currentCache.GetQrcodeInfo() if qrcodeInfo.QrCodePassword == "" { return currentInvoker.SendManualAuthByDeviceIdRequest() } else { return currentInvoker.SendManualAuthRequest(qrcodeInfo.QrCodePassword, qrcodeInfo.QrCodeWxId) } case baseinfo.MMOk: //取基本信息 accountInfo := manualResponse.GetAccountInfo() currentUserInfo.SetWxId(accountInfo.GetWxid()) currentUserInfo.NickName = accountInfo.GetNickName() // 协商密钥 currentUserInfo.ConsultSessionKey(manualResponse.GetAuthParam().GetEcdhKey().GetKey().GetBuffer(), manualResponse.AuthParam.SessionKey.Key) // AutoAuthKey currentUserInfo.SetAutoKey(manualResponse.AuthParam.AutoAuthKey.Buffer) // 随机一个字符红包AesKey currentUserInfo.GenHBKey() // 如果数据库有存储这个微信号的信息 if len(currentUserInfo.FavSyncKey) <= 0 { // 刷新收藏同步Key oldUserInfo := db.GetUserInfoByWXID(currentUserInfo.WxId) if oldUserInfo != nil { currentUserInfo.FavSyncKey = oldUserInfo.FavSyncKey } } // 开始发送心跳包 currentWXConn.SendHeartBeatWaitingSeconds(10) // 设置登陆状态,发送提示 currentWXAccount.SetLoginState(baseinfo.MMLoginStateOnLine) go func() { // 如果开了切号, 不管登录什么, 数据库里面都是iPad的设备信息 db.UpdateLoginStatus(currentUserInfo.GetUserName(), int32(currentWXAccount.GetLoginState()), "登录成功!") // 获取账号的wxProfile currentInvoker.SendGetProfileRequest() // 获取联系人标签列表 currentInvoker.SendGetContactLabelListRequest(false) // 获取CDNDns信息 currentInvoker.SendGetCDNDnsRequest() // 开始发送二次登录包 currentWXConn.SendAutoAuthWaitingMinutes(60) // 初始化通讯录 // contactSeq := currentCache.GetContactSeq() // currentInvoker.SendInitContactRequest(contactSeq) currentCache.SetInitContactFinished(true) // 同步消息 currentWXSyncMgr.SendNewSyncRequest() // 同步收藏 // currentWXSyncMgr.SendFavSyncRequest() // 打印当前链接状态 currentWXConn.GetWXServer().GetWXConnectMgr().ShowConnectInfo() //currentWXFileHelperMgr.AddNewTipMsg("上线成功!") //currentWXFileHelperMgr.AddNewTipMsg("系统正在初始化...") //redis 发布消息 发布登录状态 //db.PublishLoginState(currentWXAccount.GetUserInfo().UUID, currentWXAccount.GetLoginState()) //Mysql 提交登录日志 currentUserInfo.UpdateLastLoginTime() // 更新上次手动登录时间 // 手动登录成功: 扫码登录、62登录、16登录等等 db.SetLoginLog("ManualAuth", currentWXAccount, "登录成功!", retCode) fmt.Println("currentUserInfo扫码登录响应路由", currentUserInfo.DeviceInfo) db.SaveUserInfo(currentUserInfo) go func() { time.Sleep(10 * time.Second) if !currentCache.IsInitNewSyncFinished() { fmt.Println("[回调修复] 登录后自动设置初始化完成标志,确保回调正常工作") currentCache.SetInitNewSyncFinished(true) } }() /*time.Sleep(time.Second * 10) currentWXConn.Stop()*/ }() default: // 登陆失败 errMsg := manualResponse.GetBaseResponse().GetErrMsg().GetStr() baseutils.PrintLog(errMsg) // 将登录失败的错误信息保存到状态缓存中,这样前端就能获取到验证码URL等错误信息 db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: nil, Ret: retCode, Msg: "登录失败:" + errMsg, }) //Mysql 提交登录日志 //db.SetLoginLog("ManualAuth", currentWXAccount, errMsg, retCode) //Mysql 保存用户信息 //db.SaveUserInfo(currentUserInfo) //Mysql 保存登录状态 //db.UpdateLoginStatus(currentUserInfo.GetUserName(), retCode, errMsg) currentWXConn.Stop() //redis 发布消息 发布登录状态 //db.PublishLoginState(currentWXAccount.GetUserInfo().UUID, currentWXAccount.GetLoginState()) fmt.Println("登录失败:" + errMsg) return errors.New("login failed:" + errMsg) } return nil }