23
This commit is contained in:
240
MyCode.Project.WebApi/Areas/Wechat/Controllers/WeController.cs
Normal file
240
MyCode.Project.WebApi/Areas/Wechat/Controllers/WeController.cs
Normal file
@@ -0,0 +1,240 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using MyCode.Project.Domain.Message.Response.User;
|
||||
using MyCode.Project.Infrastructure.Constant;
|
||||
using MyCode.Project.WebApi.Controllers;
|
||||
using MyCode.Project.Domain.Config;
|
||||
using MyCode.Project.Services;
|
||||
using MyCode.Project.Infrastructure.Common;
|
||||
using MyCode.Project.Domain.Message.Request.User;
|
||||
using MyCode.Project.Infrastructure.Enumeration;
|
||||
using MyCode.Project.WebApi.App_Filter;
|
||||
using System.Web;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Senparc.Weixin.MP;
|
||||
using Senparc.Weixin.MP.MessageHandlers;
|
||||
using Senparc.NeuChar.Context;
|
||||
using Senparc.NeuChar.Entities;
|
||||
using System.Xml.Linq;
|
||||
using MyCode.Project.Services.CustomMessageHandler;
|
||||
using MyCode.Project.Domain.Dtos.Common;
|
||||
using MyCode.Project.Domain.Message.Response.Wechat;
|
||||
using MyCode.Project.Infrastructure.Cache;
|
||||
using MyCode.Project.Infrastructure.Exceptions;
|
||||
|
||||
namespace MyCode.Project.WebApi.Areas.Wechat.Controllers
|
||||
{
|
||||
public class WeController : BaseWechatController
|
||||
{
|
||||
|
||||
private readonly IMyCodeCacheService _myCodeCacheService;
|
||||
private IMemberService _memberService;
|
||||
|
||||
public WeController(IMyCodeCacheService myCodeCacheService
|
||||
, IMemberService memberService)
|
||||
{
|
||||
_myCodeCacheService = myCodeCacheService;
|
||||
_memberService = memberService;
|
||||
}
|
||||
|
||||
#region WeCallBack(微信回调)
|
||||
/// <summary>
|
||||
/// 微信回调1
|
||||
/// </summary>
|
||||
[AllowAnonymous, IgnoreResultHandle, HttpGet, HttpPost, ActionName("WeCallBack")]
|
||||
|
||||
public void WeCallBack()
|
||||
{
|
||||
var context = CurrentHttpContext;
|
||||
string signature = context.Request["signature"];
|
||||
string timestamp = context.Request["timestamp"];
|
||||
string nonce = context.Request["nonce"];
|
||||
string echostr = context.Request["echostr"];
|
||||
|
||||
//get method -检验是否微信的回调,不是则不执行
|
||||
if (CheckSignature.Check(signature, timestamp, nonce, SystemConfig.WeToken))
|
||||
{
|
||||
// string postStr = @" <xml><ToUserName><![CDATA[gh_9022339a2c40]]></ToUserName>
|
||||
//<FromUserName><![CDATA[onGWJs5LvcR2NbYMJF2VyRhVH9XU]]></FromUserName>
|
||||
//<CreateTime>1576747572</CreateTime>
|
||||
//<MsgType><![CDATA[event]]></MsgType>
|
||||
//<Event><![CDATA[subscribe]]></Event>
|
||||
//<EventKey><![CDATA[]]></EventKey>
|
||||
//</xml>";
|
||||
Stream s = System.Web.HttpContext.Current.Request.InputStream;//此方法是对System.Web.HttpContext.Current.Request.InputStream的封装,可直接代码
|
||||
string postStr = "";
|
||||
if (s != null && s.Length > 0)
|
||||
{
|
||||
s.Position = 0; //当你读取完之后必须把stream的读取位置设为开始
|
||||
StreamReader reader = new StreamReader(s, System.Text.Encoding.UTF8);
|
||||
postStr = reader.ReadToEnd().ToString();
|
||||
}
|
||||
|
||||
//byte[] b = new byte[s.Length];
|
||||
//s.Read(b, 0, (int)s.Length);
|
||||
//string postStr = Encoding.UTF8.GetString(b);
|
||||
//LogHelper.Info(postStr);
|
||||
|
||||
var weixinContext = MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>.GlobalWeixinContext.MessageQueue.FirstOrDefault();
|
||||
var recordCount = MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>.GlobalWeixinContext.MaxRecordCount;
|
||||
if (string.IsNullOrEmpty(postStr))
|
||||
{
|
||||
context.Response.Output.Write(echostr);
|
||||
context.Response.End();
|
||||
return;
|
||||
}
|
||||
var doc = XDocument.Parse(postStr);
|
||||
var maxRecordCount = 1;
|
||||
var messageHandler = new CustomMessageHandler(doc, null, maxRecordCount);
|
||||
messageHandler.OmitRepeatedMessage = true;
|
||||
messageHandler.Execute();
|
||||
|
||||
//LogHelper.Info("RequestMessages:" + messageHandler.RequestMessage);
|
||||
if (messageHandler.TextResponseMessage != null)
|
||||
{
|
||||
//LogHelper.Info("ResponseMessages:" + messageHandler.TextResponseMessage);
|
||||
context.Response.Output.Write(messageHandler.TextResponseMessage);
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 接收消息
|
||||
/// <summary>
|
||||
/// 接收微信发送的XML消息并且解析
|
||||
/// </summary>
|
||||
private void ReceiveXml()
|
||||
{
|
||||
Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
|
||||
byte[] requestByte = new byte[requestStream.Length];
|
||||
requestStream.Read(requestByte, 0, (int)requestStream.Length);
|
||||
string requestStr = Encoding.UTF8.GetString(requestByte);
|
||||
|
||||
if (!string.IsNullOrEmpty(requestStr))
|
||||
{
|
||||
//封装请求类
|
||||
XmlDocument requestDocXml = new XmlDocument();
|
||||
requestDocXml.LoadXml(requestStr);
|
||||
XmlElement rootElement = requestDocXml.DocumentElement;
|
||||
WxXmlModel WxXmlModel2 = new WxXmlModel();
|
||||
WxXmlModel2.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
|
||||
WxXmlModel2.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
|
||||
WxXmlModel2.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
|
||||
WxXmlModel2.MsgType = rootElement.SelectSingleNode("MsgType").InnerText;
|
||||
|
||||
switch (WxXmlModel2.MsgType)
|
||||
{
|
||||
case "text"://文本
|
||||
WxXmlModel2.Content = rootElement.SelectSingleNode("Content").InnerText;
|
||||
break;
|
||||
case "image"://图片
|
||||
WxXmlModel2.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
|
||||
break;
|
||||
case "event"://事件
|
||||
WxXmlModel2.Event = rootElement.SelectSingleNode("Event").InnerText;
|
||||
if (WxXmlModel2.Event != "TEMPLATESENDJOBFINISH")//关注类型
|
||||
{
|
||||
WxXmlModel2.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ResponseXML(WxXmlModel2);//回复消息
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 回复消息
|
||||
private void ResponseXML(WxXmlModel WxXmlModel)
|
||||
{
|
||||
QrCodeApi QrCodeApi = new QrCodeApi();
|
||||
|
||||
string XML = "";
|
||||
switch (WxXmlModel.MsgType)
|
||||
{
|
||||
case "text"://文本回复
|
||||
XML = MyCode.Project.Infrastructure.Common.ResponseMessage.GetText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.Content);
|
||||
break;
|
||||
case "event":
|
||||
switch (WxXmlModel.Event)
|
||||
{
|
||||
case "subscribe":
|
||||
if (string.IsNullOrEmpty(WxXmlModel.EventKey))
|
||||
{
|
||||
XML = MyCode.Project.Infrastructure.Common.ResponseMessage.GetText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, "关注成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
XML = MyCode.Project.Infrastructure.Common.ResponseMessage.SubScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码先关注后推送事件
|
||||
}
|
||||
break;
|
||||
case "SCAN":
|
||||
XML = MyCode.Project.Infrastructure.Common.ResponseMessage.ScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码已关注 直接推送事件
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default://默认回复
|
||||
break;
|
||||
}
|
||||
HttpContext.Current.Response.Write(XML);
|
||||
HttpContext.Current.Response.End();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OpenId(获取OpenId,授权自动跳转;)
|
||||
/// <summary>
|
||||
/// H5授权token,获取OpenId,授权自动跳转;
|
||||
/// </summary>
|
||||
[AllowAnonymous, IgnoreResultHandle, HttpGet, HttpPost, ActionName("openid")]
|
||||
public void OpenId(string url, int? introcode = null)
|
||||
{
|
||||
//拿到code后的跳转链接
|
||||
var redirectUrl = $"{SystemConfig.WeixinApiUrl}/api/Wechat/We/UserInfoCallback";
|
||||
|
||||
var openIdResp = new OpenIdResp();
|
||||
|
||||
var tempCacheKey = Guid.NewGuid();
|
||||
|
||||
//解码
|
||||
url = HttpUtility.UrlDecode(url);
|
||||
|
||||
//授权成功之后的跳转链接
|
||||
openIdResp.RedirectUrl = url;
|
||||
|
||||
|
||||
|
||||
_myCodeCacheService.Set(tempCacheKey.ToString(), openIdResp);
|
||||
|
||||
//执行跳转链接,userinfo跳转
|
||||
var weixinOAuth2Url = $"https://open.weixin.qq.com/connect/oauth2/authorize?appid={SystemConfig.WeAppid}&redirect_uri={HttpUtility.UrlEncode(redirectUrl)}&response_type=code&scope=snsapi_userinfo&state={tempCacheKey}#wechat_redirect";
|
||||
|
||||
CurrentHttpContext.Response.Redirect(weixinOAuth2Url);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UserInfoCallback(带用户信息的回调)
|
||||
[AllowAnonymous, IgnoreResultHandle, HttpGet, HttpPost, ActionName("UserInfoCallback")]
|
||||
public void UserInfoCallback(string code, string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(code)) { throw new BaseException("code为空"); }
|
||||
|
||||
var redirectUrl = _memberService.GetWXOAuthRedirectUrlByUserInfo(state, code);
|
||||
|
||||
CurrentHttpContext.Response.Redirect(redirectUrl);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user