using Microsoft.AspNetCore.Mvc; using Nirvana.Common; using Nirvana.Common.ApiBase; using Senparc.CO2NET.AspNet.HttpUtility; using Senparc.Weixin.MP.MessageHandlers; using Senparc.Weixin.Open.ComponentAPIs; using Senparc.Weixin.Open.Containers; using Senparc.Weixin.Open.Entities.Request; using Senparc.Weixin.Open.MessageHandlers; using System; using System.Threading.Tasks; using YBDevice.Core; using YBDevice.WX.MessageHandlers; using YBDevice.WX.MessageHandlers.CustomMessageHandler; namespace YBDevice.WX.Controllers { /// /// 公众号授权 /// public class OpenController : BaseController { private readonly ILoggerService _loggerService; public OpenController(ILoggerService loggerService) { _loggerService = loggerService; } /// /// 发起授权页的体验URL /// /// public async Task OAuth(string id = "") { //获取预授权码 var preAuthCode = await ComponentContainer.TryGetPreAuthCodeAsync(component_AppId, component_Secret, true); var callbackUrl = Configs.GetString("callbackUrl");//成功回调地址 callbackUrl = $"{callbackUrl}/{id}"; var url = ComponentApi.GetComponentLoginPageUrl(component_AppId, preAuthCode, callbackUrl); return Redirect(url); } /// /// 获取预授权码以及跳转地址 /// /// public async Task GetOAuth(string userid, string type) { try { if (RedisHelpers.Exists($"authpage_{userid}")) { var userinfo = RedisHelpers.stringGet($"authpage_{userid}"); var arr = userinfo.Split('|'); if(arr.Length == 4) { return Json(new { code = ResultState.SUCCESS, message = "success", data = new { preAuthCode = arr[2], url = arr[3] } }); } } //获取预授权码 var preAuthCode = await ComponentContainer.TryGetPreAuthCodeAsync(component_AppId, component_Secret, true); var callbackUrl = Configs.GetString("callbackUrl");//成功回调地址 var url = ComponentApi.GetComponentLoginPageUrl(component_AppId, preAuthCode, callbackUrl); //保存授权信息,10分钟内有效 RedisHelpers.Insert($"authpage_{userid}", $"{userid}|{type}|{preAuthCode}|{url}", 600); callbackUrl = $"{callbackUrl}/{userid}"; return Json(new { code = ResultState.SUCCESS, message="success", data = new { preAuthCode = preAuthCode, url = url } }); } catch (Exception ex) { _loggerService.AddErrorLogger(ex, $"userid={userid},type={type}", "获取预授权码以及跳转地址"); return Json(new { code = ResultState.FAIL, message = ex.Message}); } } /// /// 获取公众号可用的token /// /// 公众号appid /// public async Task GetAccessToken(string appid) { try { var accesstoken = await AuthorizerContainer.TryGetAuthorizerAccessTokenAsync(component_AppId, appid); return Json(new { status = "success", accesstoken = accesstoken }); } catch (Exception ex) { var msg = $"appid={appid}"; _loggerService.AddErrorLogger(ex, msg, "获取公众号可用的token"); return Json(new { status = "fail", accesstoken = "", errmsg = ex.Message }); } } /// /// 微信服务器会不间断推送最新的Ticket(10分钟一次),需要在此方法中更新缓存 /// /// [HttpPost] public ActionResult Notice(PostModel postModel) { try { //var logPath = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/Open/{0}/", SystemTime.Now.ToString("yyyy-MM-dd"))); //if (!Directory.Exists(logPath)) //{ // Directory.CreateDirectory(logPath); //} postModel.Token = component_Token; postModel.EncodingAESKey = component_EncodingAESKey; postModel.AppId = component_AppId; ThirdPartyMessageHandler messageHandler = new CustomThirdPartyMessageHandler(Request.GetRequestMemoryStream(), postModel); //记录RequestMessage日志(可选) // messageHandler.EcryptRequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request.txt", SystemTime.Now.Ticks))); // messageHandler.RequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_{1}.txt", SystemTime.Now.Ticks, messageHandler.RequestMessage.AppId))); messageHandler.Execute();//执行 //记录ResponseMessage日志(可选) //using (TextWriter tw = new StreamWriter(Path.Combine(logPath, string.Format("{0}_Response_{1}.txt", SystemTime.Now.Ticks, messageHandler.RequestMessage.AppId)))) //{ // tw.WriteLine(messageHandler.ResponseMessageText); // tw.Flush(); // tw.Close(); //} return Content(messageHandler.ResponseMessageText); } catch (Exception ex) { var msg = $"{postModel.ToJson()}"; _loggerService.AddErrorLogger(ex, msg, "微信服务器会不间断推送最新的Ticket"); return Content(""); } } /// /// 授权事件接收URL /// /// /// [HttpPost] public async Task Callback(Senparc.Weixin.MP.Entities.Request.PostModel postModel) { //此处的URL格式类型为:http://sdk.weixin.senparc.com/Open/Callback/$APPID$, 在RouteConfig中进行了配置,你也可以用自己的格式,只要和开放平台设置的一致。 //处理微信普通消息,可以直接使用公众号的MessageHandler。此处的URL也可以直接填写公众号普通的URL,如本Demo中的/Weixin访问地址 //记录数据 //new LoggerApplication().InsertErrorLog(postModel.ToJson()); postModel.Token = component_Token; postModel.EncodingAESKey = component_EncodingAESKey; //根据自己后台的设置保持一致 postModel.AppId = component_AppId; //根据自己后台的设置保持一致 var maxRecordCount = 10; MessageHandler messageHandler = null; try { var checkPublish = CheckPublish(postModel); //是否在“全网发布”阶段 if (checkPublish) { messageHandler = new OpenCheckMessageHandler(Request.GetRequestMemoryStream(), postModel, 10); } else { messageHandler = new CustomMessageHandler(Request.GetRequestMemoryStream(), postModel, maxRecordCount); } if(messageHandler != null) { await messageHandler.ExecuteAsync(new System.Threading.CancellationToken());//执行微信处理过程(关键) } return new FixWeixinBugWeixinResult(messageHandler); } catch (Exception ex) { var msg = $",model={postModel.ToJson()}"; if (messageHandler != null && messageHandler.ResponseDocument != null) { msg = $"{messageHandler.ResponseDocument.ToString()},model={postModel.ToJson()}"; } _loggerService.AddErrorLogger(ex, msg, "授权事件接收URL"); return Content(""); } } private bool CheckPublish(Senparc.Weixin.MP.Entities.Request.PostModel postModel) { //小白商户助手 return postModel.AppId == "wxd5c9b0640e178bf2"; } } }