211 lines
8.9 KiB
C#
211 lines
8.9 KiB
C#
|
|
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
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 公众号授权
|
|||
|
|
/// </summary>
|
|||
|
|
public class OpenController : BaseController
|
|||
|
|
{
|
|||
|
|
private readonly ILoggerService _loggerService;
|
|||
|
|
public OpenController(ILoggerService loggerService)
|
|||
|
|
{
|
|||
|
|
_loggerService = loggerService;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 发起授权页的体验URL
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public async Task<IActionResult> 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);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取预授权码以及跳转地址
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public async Task<IActionResult> 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});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取公众号可用的token
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="appid">公众号appid</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public async Task<IActionResult> 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 });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 微信服务器会不间断推送最新的Ticket(10分钟一次),需要在此方法中更新缓存
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
[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("");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 授权事件接收URL
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="appId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
[HttpPost]
|
|||
|
|
public async Task<IActionResult> 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<CustomMessageContext> 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";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|