package wxrouter import ( "errors" "strings" "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" "github.com/gogo/protobuf/proto" ) // WXCheckQrcodeRouter 检测二维码状态响应路由 type WXCheckQrcodeRouter struct { wxcore.WXBaseRouter } // Handle 处理conn业务的方法 func (cqr *WXCheckQrcodeRouter) Handle(wxResp wxface.IWXResponse) error { defer wxcore.TryE("WXCheckQrcodeRouter Handle") currentWXConn := wxResp.GetWXConncet() currentAccount := currentWXConn.GetWXAccount() currentInvoker := currentWXConn.GetWXReqInvoker() currentCache := currentWXConn.GetWXCache() currentUserInfo := currentAccount.GetUserInfo() // 解析检测二维码响应 var checkResp wechat.CheckLoginQRCodeResponse err := clientsdk.ParseResponseData(currentUserInfo, wxResp.GetPackHeader(), &checkResp) if err != nil { // 请求出问题了,判断是否掉线,并重连 currentWXConn.Stop() return err } // 解密出现问题,说明协议出现了问题 qrcodeInfo := currentCache.GetQrcodeInfo() retBytes, err := baseutils.AesDecryptByteKey(checkResp.LoginQrcodeNotifyPkg.NotifyData.Buffer, qrcodeInfo.QrCodeKey) if err != nil { // 请求出问题了,应该关闭链接 currentWXConn.Stop() return err } lgQrNotify := &wechat.LoginQRCodeNotify{} err = proto.Unmarshal(retBytes, lgQrNotify) if err != nil { // 请求出问题了,应该关闭链接 currentWXConn.Stop() return err } errMsg := "" if lgQrNotify.GetState() == 2 { // 每秒查一次数据库太频繁了,这里改为仅在扫码成功后查一次 bind, _ := db.IsLicenseBind(currentUserInfo.UUID) if bind != nil && len(lgQrNotify.GetWxid()) > 0 && lgQrNotify.GetWxid() != bind.WxId { errMsg = "该授权码(KEY)已绑定其他微信号, 请换一个KEY" } } // 添加扫码状态缓存 db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: lgQrNotify, Msg: errMsg, }) if len(errMsg) != 0 { // 当前 License 已绑定其他微信号, 需要更换 License currentWXConn.Stop() return errors.New(errMsg) } str := byteArrayToString(retBytes) ticketValue := extractTicketValue(str) // fmt.Println(ticketValue, 111111111111) if ticketValue != "" { // 赋值ticketValue currentUserInfo.Ticket = ticketValue currentUserInfo.LoginDataInfo.Ticket = ticketValue db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: lgQrNotify, Msg: "请提交验证码后登录", Ret: int32(0), }) } if lgQrNotify.GetState() == 2 { // 扫码成功发送登录包 err := currentInvoker.SendManualAuthRequest(lgQrNotify.GetWxnewpass(), lgQrNotify.GetWxid()) if err != nil { // 在停止连接前,确保扫码状态被正确持久化保存 db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: lgQrNotify, Msg: "登录包发送失败:" + err.Error(), Ret: int32(300), }) // 确保状态被保存后再停止连接 time.Sleep(time.Millisecond * 200) currentWXConn.Stop() return err } go func() { // 3 秒后发送指令 time.Sleep(3 * time.Second) currentCache.SetScanFinish(true) // 扫码完成后再次更新状态缓存,确保登录成功的状态被持久化 db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: lgQrNotify, Msg: "登录成功", Ret: int32(0), }) }() } else if lgQrNotify.GetState() == 4 { // 在停止连接前,确保状态被正确保存 db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{ LoginQRCodeNotify: lgQrNotify, Msg: "二维码失效", Ret: int32(301), }) // 确保状态被保存后再停止连接 time.Sleep(time.Millisecond * 200) currentWXConn.Stop() return errors.New("WXCheckQrcodeRouter err: 二维码失效") } else { currentUserInfo.HeadURL = lgQrNotify.GetHeadImgUrl() err := currentWXConn.GetWXReqInvoker().SendCheckLoginQrcodeRequest(qrcodeInfo.QrCodeUUID, qrcodeInfo.QrCodeKey) if err != nil { currentWXConn.Stop() return err } time.Sleep(time.Second) } return nil } func byteArrayToString(data []byte) string { return string(data) } func extractTicketValue(str string) string { index := strings.Index(str, "ticket=") if index == -1 { return "" } return str[index+len("ticket="):] }