public void UpdateMember(MemberEntity member, AddMemberArgs args) { if (member == null || args == null) { Debug.Assert(false, "UpdateMember member== null || args == null"); return; } member.NickName = args.WeixinUser.Nickname; member.Sex = args.WeixinUser.Sex; member.City = args.WeixinUser.City; member.Country = args.WeixinUser.Country; member.Province = args.WeixinUser.Province; member.Language = args.WeixinUser.Language; member.Headimgurl = args.WeixinUser.Headimgurl; member.SubscribeTime = args.WeixinUser.SubscribeTime; member.Remark = args.WeixinUser.Remark; member.GroupId = args.WeixinUser.GroupId; member.TagList = args.WeixinUser.GetTagListString(); member.Attention = true; member.SyncFlag = args.SyncFlag; if (args.ScenicQRCodeId.HasValue) { member.ScenicQRCodeId = args.ScenicQRCodeId; } if (args.RefereeMemberId.HasValue) { member.RefereeMemberId = args.RefereeMemberId; } _dataBase.Update(member); }
public void Execute(IJobExecutionContext context) { List <MemberEntity> needUpdateMemberList = _memberManager.GetNeedUpdateList(); if (needUpdateMemberList == null || needUpdateMemberList.Count == 0) { return; } _log.Write("更新会员信息", String.Format("取得待更新会员数:{0}", needUpdateMemberList.Count), TraceEventType.Verbose); foreach (MemberEntity member in needUpdateMemberList) { DomainContext domainContext = _domainPool.GetDomainContext(member.Domain); if (domainContext == null) { _memberManager.NeedUpdate(member.Id, false); _log.Write("更新会员信息失败", "没有Domain信息\r\n" + JsonHelper.Serializer(member), TraceEventType.Warning); continue; } RequestApiResult <WeixinUser> getUserInfoResult = UserApiWrapper.GetUserInfo(domainContext, member.OpenId); if (getUserInfoResult.Success == false) { _log.Write("更新会员信息失败", JsonHelper.Serializer(getUserInfoResult), TraceEventType.Warning); continue; } if (getUserInfoResult.ApiResult.Subscribe == 0) { _memberManager.NeedUpdate(member.Id, false); continue; } AddMemberArgs args = new AddMemberArgs(); args.WeixinUser = getUserInfoResult.ApiResult; //更新当前用户信息 _memberManager.UpdateMember(member, args); _memberManager.NeedUpdate(member.Id, false); } _log.Write("更新会员信息", "更新完毕。", TraceEventType.Verbose); }
public MemberEntity AddMember(DomainContext domainContext, AddMemberArgs args) { if (args == null) { Debug.Assert(false, "AddMember args == null"); return(null); } MemberEntity member = new MemberEntity(); member.Domain = domainContext.Domain.Id; member.AppId = domainContext.AppId; member.OpenId = args.WeixinUser.OpenId; member.NickName = args.WeixinUser.Nickname; member.Sex = args.WeixinUser.Sex; member.City = args.WeixinUser.City; member.Country = args.WeixinUser.Country; member.Province = args.WeixinUser.Province; member.Language = args.WeixinUser.Language; member.Headimgurl = args.WeixinUser.Headimgurl; member.SubscribeTime = args.WeixinUser.SubscribeTime; member.Remark = args.WeixinUser.Remark; member.GroupId = args.WeixinUser.GroupId; member.TagList = args.WeixinUser.GetTagListString(); member.ScenicQRCodeId = args.ScenicQRCodeId; member.RefereeMemberId = args.RefereeMemberId; member.Attention = true; member.Point = domainContext.InitialMemberPoint; member.CardNumber = GetMemberCardNumber(domainContext.Domain.Id, domainContext.AppId); member.SyncFlag = args.SyncFlag; //TODO:初始积分要写记录表 _dataBase.Insert(member); return(member); }
private void SyncUserList(string next_openid) { RequestApiResult <WeixinGetUserListResult> getUserListResult = UserApiWrapper.GetUserList(this, next_openid); if (getUserListResult.Success == false) { EndSyncUserList("用户列表同步失败:" + getUserListResult.Message); return; } if (getUserListResult.ApiResult.Count == 0) { //将取消了关注的用户剔出来 _memberManager.UpdateUnsubscribeMemberList(this.Domain.Id, this.AppId, _syncFlag); EndSyncUserList("用户列表同步成功。"); return; } foreach (string openId in getUserListResult.ApiResult.Data.OpenIdList) { RequestApiResult <WeixinUser> getUserInfoResult = UserApiWrapper.GetUserInfo(this, openId); if (getUserInfoResult.Success == false) { _logService.Write("用户列表同步失败", getUserInfoResult.Message, TraceEventType.Error); EndSyncUserList("用户列表同步失败:" + getUserInfoResult.Message); return; } //值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 if (getUserInfoResult.ApiResult.Subscribe == 0) { continue; } //根据OpenId获取用户信息 MemberEntity member = _memberManager.GetMemberByOpenId(this.Domain.Id, this.AppId, openId); AddMemberArgs args = new AddMemberArgs(); args.WeixinUser = getUserInfoResult.ApiResult; args.SyncFlag = _syncFlag; if (member == null) { //添加新用户 member = _memberManager.AddMember(this, args); } else { //更新当前用户信息 _memberManager.UpdateMember(member, args); } } //事实上微信接口永远会返回 NextOpenId,哪怕数据只有几条不需要分次获取 if (String.IsNullOrEmpty(getUserListResult.ApiResult.NextOpenId) == false) { SyncUserList(getUserListResult.ApiResult.NextOpenId); } }
protected override string Handle(ReceivingXMLMessage_SubscribeEventMessage message, ClientDomainContext domainContext) { //用户管理-获取用户基本信息 //未认证订阅号 未认证服务号 没有此权限 RequestApiResult <WeixinUser> getUserInfoResult = UserApiWrapper.GetUserInfo(domainContext, message.FromUserName); if (getUserInfoResult.Success == false) { return(String.Empty); } if (getUserInfoResult.ApiResult.Subscribe == 0) { return(String.Empty); } #region 判断是否是扫描带参数二维码事件 //扫描带参数二维码事件 string strScenicQRCodeId = String.Empty; if (String.IsNullOrEmpty(message.EventKey) == false) { //用户未关注时,进行关注后的事件推送 if (message.EventKey.StartsWith("qrscene_")) { strScenicQRCodeId = message.EventKey.Remove(0, "qrscene_".Length); } } //获取场景二维码Id Guid?scenicQRCodeId = null; ScenicQRCodeLandingLogEntity scenicQRCodeLandingLog = null; if (String.IsNullOrEmpty(strScenicQRCodeId) == false) { Guid scenicQRCodeId2; if (Guid.TryParse(strScenicQRCodeId, out scenicQRCodeId2)) { scenicQRCodeId = scenicQRCodeId2; scenicQRCodeLandingLog = new ScenicQRCodeLandingLogEntity(); scenicQRCodeLandingLog.Domain = domainContext.Domain.Id; scenicQRCodeLandingLog.QRCodeId = scenicQRCodeId.Value; scenicQRCodeLandingLog.VisitorOpenId = message.FromUserName; scenicQRCodeLandingLog.LandingTime = DateTime.Now; } } #endregion #region 判断是否是通过RecomendUrl引流关注的 Guid?refereeMemberId = null; //如果有场景二维码ID就不用判断RecomendUrl了 if (String.IsNullOrEmpty(strScenicQRCodeId)) { RecommendUrlLogEntity recomendUrlLog = _recommendUrlManager.GetLogByOpenId(getUserInfoResult.ApiResult.OpenId); if (recomendUrlLog != null) { refereeMemberId = recomendUrlLog.UrlOwnMember; } } #endregion //根据OpenId获取用户信息 MemberEntity member = _memberManager.GetMemberByOpenId(domainContext.Domain.Id, domainContext.AppId, getUserInfoResult.ApiResult.OpenId); AddMemberArgs args = new AddMemberArgs(); args.WeixinUser = getUserInfoResult.ApiResult; args.ScenicQRCodeId = scenicQRCodeId; args.RefereeMemberId = refereeMemberId; if (member == null) { //添加新用户 member = _memberManager.AddMember(domainContext, args); //更新场景二维码计数 if (scenicQRCodeId.HasValue) { _scenicQRCodeManager.IncrementAttentionPerson(scenicQRCodeId.Value, scenicQRCodeLandingLog); } //如果通过RecomendUrl引流关注的,奖励积分 if (refereeMemberId.HasValue && domainContext.RecommendUrlSettings != null && domainContext.RecommendUrlSettings.AttentionPoint > 0) { PointTrackArgs pointTrackArgs = new PointTrackArgs(); pointTrackArgs.DomainId = domainContext.Domain.Id; pointTrackArgs.MemberId = refereeMemberId.Value; pointTrackArgs.Quantity = domainContext.RecommendUrlSettings.AttentionPoint; pointTrackArgs.Type = MemberPointTrackType.RecommendUrl; pointTrackArgs.TagName = member.NickName; pointTrackArgs.TagId = member.Id; _memberManager.PointTrack(pointTrackArgs); } //判断是否有二级上线,对其奖励积分 if (refereeMemberId.HasValue && domainContext.RecommendUrlSettings != null && domainContext.RecommendUrlSettings.Level2AttentionPoint > 0) { RefereeUplineWrapper refereeUplineWrapper = _recommendUrlManager.GetRefereeUplineList(domainContext.Domain.Id, domainContext.AppId, refereeMemberId.Value); if (refereeUplineWrapper.Upline != null) { PointTrackArgs pointTrackArgs = new PointTrackArgs(); pointTrackArgs.DomainId = domainContext.Domain.Id; pointTrackArgs.MemberId = refereeUplineWrapper.Upline.MemberId; pointTrackArgs.Quantity = domainContext.RecommendUrlSettings.Level2AttentionPoint; pointTrackArgs.Type = MemberPointTrackType.RecommendUrl; pointTrackArgs.TagName = member.NickName; pointTrackArgs.TagId = member.Id; _memberManager.PointTrack(pointTrackArgs); } } } else { //更新当前用户信息 _memberManager.UpdateMember(member, args); //更新场景二维码计数 if (scenicQRCodeId.HasValue) { _scenicQRCodeManager.IncrementLanding(scenicQRCodeId.Value, scenicQRCodeLandingLog); } } #region 关注时的自动回复 if (domainContext.AutoReplyOnSubscribe != null && String.IsNullOrEmpty(domainContext.AutoReplyOnSubscribe.Content) == false) { ResponsiveXMLMessageBase replyMessage = AutoReplyHelper.GetXMLMessage(domainContext, message.FromUserName, domainContext.AutoReplyOnSubscribe); if (replyMessage != null) { return(XMLMessageHelper.XmlSerialize(replyMessage)); } else { return(String.Empty); } } else { return(String.Empty); } #endregion }
/// <summary> ///微信网页授权回调 ///如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。 ///若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE ///http://mp.weixin.qq.com/wiki/9/01f711493b5a02f24b04365ac5d8fd95.html /// </summary> /// <returns></returns> public ActionResult OAuthCallback() { _log.Write("微信网页授权接口发起回调", HttpContext.Request.Url.ToString(), TraceEventType.Verbose); string code = HttpContext.Request.QueryString["code"]; string state = HttpContext.Request.QueryString["state"]; //第为第三方平台运营时,会返回 appId string appId = HttpContext.Request.QueryString["appid"]; //完成网页鉴权后要转回的页面地址 string redirectUrl = null; if (String.IsNullOrEmpty(state) == false) { redirectUrl = _cachingService.Get(state); } else { _log.Write("微信网页授权接口发起回调", "没有指定完成网页鉴权后要转回的页面地址: state" + HttpContext.Request.Url.ToString(), TraceEventType.Warning); return(new HttpStatusCodeResult(404)); } string domainId = HttpContext.Request.QueryString["domainId"]; if (String.IsNullOrEmpty(domainId)) { _log.Write("微信网页授权接口发起回调", "没有指定 domainId ", TraceEventType.Warning); return(new HttpStatusCodeResult(404)); } DomainContext domainContext = _domainPool.GetDomainContext(Guid.Parse(domainId)); if (domainContext == null) { _log.Write("微信网页授权接口发起回调", "指定的 domainId 不存在", TraceEventType.Warning); return(new HttpStatusCodeResult(404)); } if (domainContext.Authorizer == null) { //重定向到错误页面 return(new RedirectResult(String.Format( "~/Home/ErrorView/{0}?message={1}", domainContext.Domain.Id, "td5"))); } //只有微信认证服务号具备此权限 //用户管理-网页授权获取用户openid/用户基本信息 if (domainContext.Authorizer.AuthorizationType != EnumAuthorizationType.AuthorizedService) { //重定向到错误页面 return(new RedirectResult(String.Format( "~/Home/ErrorView/{0}?message={1}", domainContext.Domain.Id, "td4"))); } if (String.IsNullOrEmpty(code)) { //重定向到错误页面 return(new RedirectResult(String.Format( "~/Home/ErrorView/{0}?message={1}", domainContext.Domain.Id, "td1"))); } /* * 此处偶发 40029 错误,不合法的oauth_code * 40029-invalid code, hints: [ req_id: Ft6quA0644ns67 ] * https://segmentfault.com/q/1010000002739502?foxhandler=RssReadRenderProcessHandler * http://mp.weixin.qq.com/qa/11/3c20059cc944d6edf4a1124c2fd09253.html * redirect_uri后面加个随机数没用 * 通过尝试发起两次请求的方式解决 */ //通过code换取网页access_token RequestApiResult <WeixinWebAccessTokenResult> getWebAccessToken = TokenApi.GetThirdPartyWebAccessToken(domainContext.AppId, code, _configuration.ThirdParty.AppId, ThirdPartyAccessTokenGetter.Get()); if (getWebAccessToken.Success == false) { //再来一次,防止死循环,只重试一次,在URL后面加个参数以标记 if (redirectUrl.Contains("RetryGetWebAccessToken")) { _log.Write("请求网页AccessToken失败。", getWebAccessToken.Message, TraceEventType.Warning); //重定向到错误页面 return(new RedirectResult(String.Format( "~/Home/ErrorView/{0}?message={1}", domainContext.Domain.Id, "td2"))); } else { if (redirectUrl.IndexOf('?') >= 0) { redirectUrl += "&RetryGetWebAccessToken=1"; } else { redirectUrl += "?RetryGetWebAccessToken=1"; } return(new RedirectResult(redirectUrl)); } } //将OpenId保存到Session SessionContainer.SetOpenId(HttpContext, getWebAccessToken.ApiResult.OpenId); //先判断本地数据库中是否已经有了此用户信息 MemberContext memberContext = null; MemberEntity member = _memberManager.GetMemberByOpenId(domainContext.Domain.Id, domainContext.AppId, getWebAccessToken.ApiResult.OpenId); if (member != null) { if (member.Attention) { //为提高鉴权性能,此处不更新用户信息,只作标记,用windows服务后台更新 _memberManager.NeedUpdate(member.Id, true); memberContext = new MemberContext(member); SessionContainer.SetMemberContext(HttpContext, memberContext); //转回初始业务页面 return(new RedirectResult(redirectUrl)); } else { //如果用户已经取消关注,此处就不需要再调用微信的 GetUserInfo 接口了 //直接判断能不能匿名浏览即可 return(RedirectUrlOnlyOpenId(redirectUrl, domainId)); } } //在本地没有用户信息的情况下,调用weixinApi去取 //此处拿到OpenId了,接下来判断该用户是否是已关注用户 RequestApiResult <WeixinUser> getUserInfoResult = UserApiWrapper.GetUserInfo(domainContext, getWebAccessToken.ApiResult.OpenId); if (getUserInfoResult.Success == false) { //重定向到错误页面 return(new RedirectResult(String.Format( "~/Home/ErrorView/{0}?message={1}", domainContext.Domain.Id, "td3"))); } //值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 //跳转到引导关注页面 if (getUserInfoResult.ApiResult.Subscribe == 0) { //用户取消关注有消息推送 //在那时设置member中是否在关注为false return(RedirectUrlOnlyOpenId(redirectUrl, domainId)); } else { //根据OpenId获取用户信息 //添加新用户 AddMemberArgs args = new AddMemberArgs(); args.WeixinUser = getUserInfoResult.ApiResult; member = _memberManager.AddMember(domainContext, args); memberContext = new MemberContext(member); SessionContainer.SetMemberContext(HttpContext, memberContext); //转回初始业务页面 return(new RedirectResult(redirectUrl)); } }