241 lines
10 KiB
C#
Raw Normal View History

2025-04-24 18:31:27 +08:00
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
}
}