忽略dll文件git

This commit is contained in:
“wanyongkang”
2023-07-29 10:19:42 +08:00
parent 7f97317bcc
commit b562aba2b1
3868 changed files with 63608 additions and 385427 deletions

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Wx.Open.Enums
{
public enum ChannelType
{
[Description("公众号")]
MP=1,
[Description("小程序")]
MiniApp=2,
[Description("短信")]
Sms=3,
[Description("小程序订阅消息")]
MiniAppSubscribe = 4,
}
}

View File

@@ -1,232 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Net;
namespace Tencent
{
class Cryptography
{
public static UInt32 HostToNetworkOrder(UInt32 inval)
{
UInt32 outval = 0;
for (int i = 0; i < 4; i++)
outval = (outval << 8) + ((inval >> (i * 8)) & 255);
return outval;
}
public static Int32 HostToNetworkOrder(Int32 inval)
{
Int32 outval = 0;
for (int i = 0; i < 4; i++)
outval = (outval << 8) + ((inval >> (i * 8)) & 255);
return outval;
}
/// <summary>
/// 解密方法
/// </summary>
/// <param name="Input">密文</param>
/// <param name="EncodingAESKey"></param>
/// <returns></returns>
///
public static string AES_decrypt(String Input, string EncodingAESKey, ref string appid)
{
byte[] Key;
Key = Convert.FromBase64String(EncodingAESKey + "=");
byte[] Iv = new byte[16];
Array.Copy(Key, Iv, 16);
byte[] btmpMsg = AES_decrypt(Input, Iv, Key);
int len = BitConverter.ToInt32(btmpMsg, 16);
len = IPAddress.NetworkToHostOrder(len);
byte[] bMsg = new byte[len];
byte[] bAppid = new byte[btmpMsg.Length - 20 - len];
Array.Copy(btmpMsg, 20, bMsg, 0, len);
Array.Copy(btmpMsg, 20+len , bAppid, 0, btmpMsg.Length - 20 - len);
string oriMsg = Encoding.UTF8.GetString(bMsg);
appid = Encoding.UTF8.GetString(bAppid);
return oriMsg;
}
public static String AES_encrypt(String Input, string EncodingAESKey, string appid)
{
byte[] Key;
Key = Convert.FromBase64String(EncodingAESKey + "=");
byte[] Iv = new byte[16];
Array.Copy(Key, Iv, 16);
string Randcode = CreateRandCode(16);
byte[] bRand = Encoding.UTF8.GetBytes(Randcode);
byte[] bAppid = Encoding.UTF8.GetBytes(appid);
byte[] btmpMsg = Encoding.UTF8.GetBytes(Input);
byte[] bMsgLen = BitConverter.GetBytes(HostToNetworkOrder(btmpMsg.Length));
byte[] bMsg = new byte[bRand.Length + bMsgLen.Length + bAppid.Length + btmpMsg.Length];
Array.Copy(bRand, bMsg, bRand.Length);
Array.Copy(bMsgLen, 0, bMsg, bRand.Length, bMsgLen.Length);
Array.Copy(btmpMsg, 0, bMsg, bRand.Length + bMsgLen.Length, btmpMsg.Length);
Array.Copy(bAppid, 0, bMsg, bRand.Length + bMsgLen.Length + btmpMsg.Length, bAppid.Length);
return AES_encrypt(bMsg, Iv, Key);
}
private static string CreateRandCode(int codeLen)
{
string codeSerial = "2,3,4,5,6,7,a,c,d,e,f,h,i,j,k,m,n,p,r,s,t,A,C,D,E,F,G,H,J,K,M,N,P,Q,R,S,U,V,W,X,Y,Z";
if (codeLen == 0)
{
codeLen = 16;
}
string[] arr = codeSerial.Split(',');
string code = "";
int randValue = -1;
Random rand = new Random(unchecked((int)DateTime.Now.Ticks));
for (int i = 0; i < codeLen; i++)
{
randValue = rand.Next(0, arr.Length - 1);
code += arr[randValue];
}
return code;
}
private static String AES_encrypt(String Input, byte[] Iv, byte[] Key)
{
var aes = new RijndaelManaged();
//秘钥的大小,以位为单位
aes.KeySize = 256;
//支持的块大小
aes.BlockSize = 128;
//填充模式
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.CBC;
aes.Key = Key;
aes.IV = Iv;
var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
byte[] xXml = Encoding.UTF8.GetBytes(Input);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = ms.ToArray();
}
String Output = Convert.ToBase64String(xBuff);
return Output;
}
private static String AES_encrypt(byte[] Input, byte[] Iv, byte[] Key)
{
var aes = new RijndaelManaged();
//秘钥的大小,以位为单位
aes.KeySize = 256;
//支持的块大小
aes.BlockSize = 128;
//填充模式
//aes.Padding = PaddingMode.PKCS7;
aes.Padding = PaddingMode.None;
aes.Mode = CipherMode.CBC;
aes.Key = Key;
aes.IV = Iv;
var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
byte[] xBuff = null;
#region PKCS7补位
byte[] msg = new byte[Input.Length + 32 - Input.Length % 32];
Array.Copy(Input, msg, Input.Length);
byte[] pad = KCS7Encoder(Input.Length);
Array.Copy(pad, 0, msg, Input.Length, pad.Length);
#endregion
#region
//ICryptoTransform transform = aes.CreateEncryptor();
//byte[] xBuff = transform.TransformFinalBlock(msg, 0, msg.Length);
#endregion
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
{
cs.Write(msg, 0, msg.Length);
}
xBuff = ms.ToArray();
}
String Output = Convert.ToBase64String(xBuff);
return Output;
}
private static byte[] KCS7Encoder(int text_length)
{
int block_size = 32;
// 计算需要填充的位数
int amount_to_pad = block_size - (text_length % block_size);
if (amount_to_pad == 0)
{
amount_to_pad = block_size;
}
// 获得补位所用的字符
char pad_chr = chr(amount_to_pad);
string tmp = "";
for (int index = 0; index < amount_to_pad; index++)
{
tmp += pad_chr;
}
return Encoding.UTF8.GetBytes(tmp);
}
/**
* 将数字转化成ASCII码对应的字符用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
static char chr(int a)
{
byte target = (byte)(a & 0xFF);
return (char)target;
}
private static byte[] AES_decrypt(String Input, byte[] Iv, byte[] Key)
{
RijndaelManaged aes = new RijndaelManaged();
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
aes.Key = Key;
aes.IV = Iv;
var decrypt = aes.CreateDecryptor(aes.Key, aes.IV);
byte[] xBuff = null;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
{
byte[] xXml = Convert.FromBase64String(Input);
byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];
Array.Copy(xXml, msg, xXml.Length);
cs.Write(xXml, 0, xXml.Length);
}
xBuff = decode2(ms.ToArray());
}
return xBuff;
}
private static byte[] decode2(byte[] decrypted)
{
int pad = (int)decrypted[decrypted.Length - 1];
if (pad < 1 || pad > 32)
{
pad = 0;
}
byte[] res = new byte[decrypted.Length - pad];
Array.Copy(decrypted, 0, res, 0, decrypted.Length - pad);
return res;
}
}
}

View File

@@ -1,309 +0,0 @@
namespace Hncore.Wx.Open
{
/// <summary>
/// 选项设置信息选项名称
/// </summary>
public enum OptionName
{
/// <summary>
/// 地理位置上报选项
/// 0 无上报
/// 1 进入会话时上报
/// 2 每5s上报
/// </summary>
location_report,
/// <summary>
/// 语音识别开关选项
/// 0 关闭语音识别
/// 1 开启语音识别
/// </summary>
voice_recognize,
/// <summary>
/// 客服开关选项
/// 0 关闭多客服
/// 1 开启多客服
/// </summary>
customer_service
}
/// <summary>
/// 公众号第三方平台推送消息类型
/// </summary>
public enum RequestInfoType
{
#region
/// <summary>
/// 推送component_verify_ticket协议
/// </summary>
component_verify_ticket,
/// <summary>
/// 推送取消授权通知
/// </summary>
unauthorized,
/// <summary>
/// 更新授权
/// </summary>
updateauthorized,
/// <summary>
/// 授权成功通知
/// </summary>
authorized,
/// <summary>
/// 小程序注册审核事件推送
/// </summary>
notify_third_fasteregister,
#endregion
#region
/// <summary>
/// 关注事件
/// </summary>
event_subscribe,
/// <summary>
/// 取消关注事件
/// </summary>
event_unsubscribe,
/// <summary>
/// 扫描关注
/// </summary>
event_subscribe_qrscene,
/// <summary>
/// 扫描已关注的事件
/// </summary>
event_SCAN,
/// <summary>
/// 上报地理位置
/// </summary>
event_LOCATION,
/// <summary>
/// 自定义菜单事件
/// </summary>
event_CLICK,
/// <summary>
/// 点击菜单跳转链接
/// </summary>
event_VIEW,
#endregion
#region
/// <summary>
/// 文本消息
/// </summary>
text,
/// <summary>
/// 图片消息
/// </summary>
image,
/// <summary>
/// 语音消息
/// </summary>
voice,
/// <summary>
/// 视频消息
/// </summary>
video,
/// <summary>
/// 音乐消息
/// </summary>
music,
/// <summary>
/// 图文消息
/// </summary>
news,
/// <summary>
/// 未知消息
/// </summary>
none
#endregion
}
/// <summary>
/// 应用授权作用域
/// </summary>
public enum OAuthScope
{
/// <summary>
/// 不弹出授权页面直接跳转只能获取用户openid
/// </summary>
snsapi_base,
/// <summary>
/// 弹出授权页面可通过openid拿到昵称、性别、所在地。并且即使在未关注的情况下只要用户授权也能获取其信息
/// </summary>
snsapi_userinfo,
/// <summary>
/// 网站应用授权登录
/// </summary>
snsapi_login,
}
/// <summary>
/// 授权方公众号类型
/// </summary>
public enum ServiceType
{
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
= 0,
= 1,
= 2
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
}
/// <summary>
/// 授权方认证类型
/// </summary>
public enum VerifyType
{
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
= -1,
= 0,
= 1,
= 2,
= 3,
= 4,
= 5
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
}
/// <summary>
/// <para>公众号/小程序授权给开发者的权限集列表(1-15为公众号权限,17-19为小程序权限)。</para>
/// <para>请注意1该字段的返回不会考虑公众号是否具备该权限集的权限因为可能部分具备请根据公众号的帐号类型和认证情况来判断公众号的接口权限。</para>
/// </summary>
public enum FuncscopeCategory
{
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
= 1,
= 2,
= 3,
= 4,
= 5,
= 6,
= 7,
= 8,
= 9,
WIFI权限 = 10,
= 11,
= 12,
= 13,
= 14,
= 15,
= 16,
_小程序 = 17,
_小程序 = 18,
_小程序 = 19,
_小程序 = 20,
_小程序 = 21,
= 22,
广 = 23,
= 24,
_小程序 = 25,
= 26,
= 27,
= 33,
= 35
#pragma warning restore CS1591 // 缺少对公共可见类型或成员的 XML 注释
}
/// <summary>
/// 小程序“修改服务器地址”接口的action类型
/// </summary>
public enum ModifyDomainAction
{
/// <summary>
/// 添加
/// </summary>
add,
/// <summary>
/// 删除
/// </summary>
delete,
/// <summary>
/// 覆盖
/// </summary>
set,
/// <summary>
/// 获取
/// </summary>
get
}
/// <summary>
/// 小程序“线上代码的可见状态”接口的action类型
/// </summary>
public enum ChangVisitStatusAction
{
open,
close
}
/// <summary>
/// 帐号类型1订阅号2服务号3小程序
/// </summary>
public enum AccountType
{
= 1,
= 2,
= 3
}
/// <summary>
/// 主体类型1企业
/// </summary>
public enum PrincipalType
{
= 1
}
/// <summary>
/// 1实名验证成功2实名验证中3实名验证失败
/// </summary>
public enum RealNameStatus
{
= 1,
= 2,
= 3
}
/// <summary>
/// 小程序昵称审核状态1审核中2审核失败3审核成功
/// </summary>
public enum AuditStat
{
= 1,
= 2,
= 3
}
/// <summary>
/// 小程序类目审核状态1审核中2审核失败3审核成功
/// </summary>
public enum AuditStatus
{
= 1,
= 2,
= 3
}
/// <summary>
/// 要授权的帐号类型
/// </summary>
public enum LoginAuthType
{
,
= 1,
= 2,
= 3
}
/// <summary>
/// 企业代码类型 1统一社会信用代码18位 2组织机构代码9位xxxxxxxx-x 3营业执照注册号(15位)
/// </summary>
public enum CodeType
{
=1,
=2,
=3
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
public class MessageHandler
{
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.MsgCenter.WxOpen.Model
{
public class WxMenuModel
{
}
}

View File

@@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
public class wechat_access_token
{
public string access_token { get; set; }
public int expires_in { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
public int errcode { get; set; }
public string errmsg { get; set; }
}
public class authorizer_info
{
public string nick_name { get; set; }
public string head_img { get; set; }
public Service_Type_Info service_type_info { get; set; }
public Verify_Type_Info verify_type_info { get; set; }
public string user_name { get; set; }
public string alias { get; set; }
public string qrcode_url { get; set; }
public bussiness_info business_info { get; set; }
public int idc { get; set; }
public string principal_name { get; set; }
public string signature { get; set; }
}
public class Service_Type_Info
{
public int id { get; set; }
}
public class Verify_Type_Info
{
public int id { get; set; }
}
public class bussiness_info
{
public int open_pay { get; set; }
public int open_shake { get; set; }
public int open_scan { get; set; }
public int open_card { get; set; }
public int open_store { get; set; }
}
/// <summary>
/// 授权信息数据模型
/// </summary>
///
public class authorization_info
{
/// <summary>
/// 授权方(物业公众号)的AppId
/// </summary>
public string authorizer_appid { get; set; }
/// <summary>
/// 授权方(物业公众号)的访问令牌AccessToken
/// </summary>
public string authorizer_access_token { get; set; }
/// <summary>
/// 授权方访问令牌的过期时间
/// </summary>
public int expires_in { get; set; }
/// <summary>
/// 授权方刷新令牌,当访问令牌过期时,使用此刷新令牌重新获取新的访问令牌(此字段要保存)
/// </summary>
public string authorizer_refresh_token { get; set; }
/// <summary>
/// 授权给开发者的权限集列表ID为1到26分别代表 1、消息管理权限 2、用户管理权限 3、帐号服务权限 4、网页服务权限 5、微信小店权限 6、微信多客服权限 7、群发与通知权限 8、微信卡券权限 9、微信扫一扫权限 10、微信连WIFI权限 11、素材管理权限 12、微信摇周边权限 13、微信门店权限 15、自定义菜单权限 16、获取认证状态及信息 17、帐号管理权限小程序 18、开发管理与数据分析权限小程序 19、客服消息管理权限小程序 20、微信登录权限小程序 21、数据分析权限小程序 22、城市服务接口权限 23、广告管理权限 24、开放平台帐号管理权限 25、 开放平台帐号管理权限(小程序) 26、微信电子发票权限 41、搜索widget的权限 请注意: 1该字段的返回不会考虑公众号是否具备该权限集的权限因为可能部分具备请根据公众号的帐号类型和认证情况来判断公众号的接口权限。
/// </summary>
public func_info[] func_info { get; set; }
}
public class func_info
{
public funcscope_category funcscope_category { get; set; }
}
public class funcscope_category
{
public int id { get; set; }
}
public class WechatThirdpartApplicationInfomation
{
public authorizer_info authorizier_info { get; set; }
public authorization_info authorization_info { get; set; }
}
}

View File

@@ -1,56 +0,0 @@
using System;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
public static class InfoTypeHelper
{
/// <summary>
/// 根据xml信息返回类型
/// 授权信息返回的是 InfoType
/// 微信交互消息和事件返回的是 MsgType
/// </summary>
/// <param name="doc"></param>
/// <returns></returns>
public static RequestInfoType GetRequestInfoType(XDocument doc)
{
var reqType = "";
var typeNode = doc.Root.Element("InfoType");
if (typeNode != null)
{
reqType = typeNode.Value;
}
else
{
typeNode = doc.Root.Element("MsgType");
reqType = typeNode.Value;
if (reqType == "event")
{
reqType = "event_" + doc.Root.Element("Event").Value;
var eventKey = doc.Root.Element("EventKey");
if (null != (eventKey) && eventKey.Value.StartsWith("qrscene_"))
{
reqType = "event_subscribe_qrscene";
}
}
}
return GetRequestInfoType(reqType);
}
/// <summary>
/// 根据xml信息返回InfoType
/// </summary>
/// <returns></returns>
public static RequestInfoType GetRequestInfoType(string str)
{
try
{
return (RequestInfoType)Enum.Parse(typeof(RequestInfoType), str, true);
}
catch
{
return RequestInfoType.none;
}
}
}
}

View File

@@ -1,16 +0,0 @@
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
/// <summary>
/// 请求消息接口
/// </summary>
public interface IMessageBase
{
string AppId { get; set; }
long CreateTime { get; set; }
RequestInfoType InfoType { get; }
Task<bool> Handler();
}
}

View File

@@ -1,38 +0,0 @@
/*
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
*/
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
/// <summary>
/// 扫描二维码关注
/// </summary>
public class MessageDefault : IMessageBase
{
public MessageDefault()
{
}
public RequestInfoType InfoType
{
get { return RequestInfoType.none; }
}
public string AppId { get; set; }
public long CreateTime { get; set; }
public async Task<bool> Handler()
{
return true;
}
}
}

View File

@@ -1,95 +0,0 @@
using Hncore.Infrastructure.Common;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// RequestMessage工厂
/// </summary>
public static class MessageFactory
{
public static IServiceCollection Service { get; set; }
/// <summary>
/// 获取XDocument转换后的IRequestMessageBase实例。
/// 如果MsgType不存在抛出UnknownRequestMsgTypeException异常
/// </summary>
/// <returns></returns>
public static IMessageBase GetRequestEntity(XDocument doc)
{
IMessageBase requestMessage = null;
RequestInfoType infoType;
try
{
infoType = InfoTypeHelper.GetRequestInfoType(doc);
switch (infoType)
{
case RequestInfoType.component_verify_ticket:
requestMessage = new MessageComponentVerifyTicket(doc);
break;
case RequestInfoType.unauthorized:
requestMessage = new MessageUnauthorized(doc);
break;
case RequestInfoType.authorized:
requestMessage = new MessageAuthorized(doc);
break;
case RequestInfoType.updateauthorized:
requestMessage = new MessageUpdateAuthorized(doc);
break;
case RequestInfoType.notify_third_fasteregister:
requestMessage = new MessageThirdFasteRegister(doc);
break;
case RequestInfoType.event_subscribe_qrscene:
requestMessage = new MessageEventSubscribeQrscene(doc);
break;
case RequestInfoType.event_SCAN:
requestMessage = new MessageEventScan(doc);
break;
case RequestInfoType.event_subscribe:
requestMessage = new MessageEventSubscribe(doc);
break;
default:
return new MessageDefault();
}
}
catch (Exception ex)
{
LogHelper.Error("MessageFactory 解析失败", ex.Message);
}
return requestMessage;
}
/// <summary>
/// 获取XDocument转换后的IRequestMessageBase实例。
/// 如果MsgType不存在抛出UnknownRequestMsgTypeException异常
/// </summary>
/// <returns></returns>
public static IMessageBase GetRequestEntity(string xml)
{
return GetRequestEntity(XDocument.Parse(xml));
}
/// <summary>
/// 获取XDocument转换后的IRequestMessageBase实例。
/// 如果MsgType不存在抛出UnknownRequestMsgTypeException异常
/// </summary>
/// <param name="stream">如Request.InputStream</param>
/// <returns></returns>
public static IMessageBase GetRequestEntity(Stream stream)
{
using (XmlReader xr = XmlReader.Create(stream))
{
var doc = XDocument.Load(xr);
return GetRequestEntity(doc);
}
}
}
}

View File

@@ -1,60 +0,0 @@
/*
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
*/
using Hncore.Pass.MsgCenter.Constant;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using Hncore.Pass.MsgCenter.Util;
namespace Hncore.Wx.Open
{
/// <summary>
/// 扫描二维码关注
/// </summary>
public class MessageEventScan : MessageMPBase
{
public MessageEventScan(XDocument doc) : base(doc)
{
this.EventKey = doc.Root.Element("EventKey").Value;
this.Ticket = doc.Root.Element("Ticket").Value;
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.event_SCAN; }
}
/// <summary>
/// 事件KEY值qrscene_为前缀后面为二维码的参数值
/// </summary>
public string EventKey { get; set; }
/// <summary>
/// 二维码的ticket可用来换取二维码图片
/// </summary>
public string Ticket { get; set; }
public override async Task<bool> Handler()
{
///参数形式 method?a=1&b=2
var dataUrl = this.EventKey;
var model = UrlHelper.ParseUrl(dataUrl);
if (model.Method == "addtag")
{
var tagid = model.Args["tagid"];
WxOpenApi.AddTag(this.AppId, new List<string>() { this.FromUserName }, tagid);
}
return true;
}
}
}

View File

@@ -1,38 +0,0 @@
/*
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>
*/
using Hncore.Infrastructure.Common;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 关注
/// </summary>
public class MessageEventSubscribe : MessageMPBase
{
public MessageEventSubscribe(XDocument doc) : base(doc)
{
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.event_subscribe; }
}
public override async Task<bool> Handler()
{
LogHelper.Info("MessageEventSubscribe", $"AppId={this.AppId},openid={this.FromUserName}");
var userInfo = await WxOpenApi.GetUserUnionIDinfo(this.AppId, this.FromUserName);
LogHelper.Info("MessageEventSubscribe_userInfo", $"AppId={this.AppId},unionid={ userInfo.unionid}");
return true;
}
}
}

View File

@@ -1,64 +0,0 @@
/*
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
*/
using Hncore.Pass.MsgCenter.Util;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 扫描二维码关注
/// </summary>
public class MessageEventSubscribeQrscene : MessageMPBase
{
public MessageEventSubscribeQrscene(XDocument doc) : base(doc)
{
this.EventKey = doc.Root.Element("EventKey").Value;
this.Ticket = doc.Root.Element("Ticket").Value;
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.event_subscribe_qrscene; }
}
/// <summary>
/// 事件KEY值qrscene_为前缀后面为二维码的参数值
/// </summary>
public string EventKey { get; set; }
/// <summary>
/// 二维码的ticket可用来换取二维码图片
/// </summary>
public string Ticket { get; set; }
public override async Task<bool> Handler()
{
///参数形式 method?a=1&b=2
var dataUrl = EventKey.TrimStart("qrscene_".ToCharArray());
var model = UrlHelper.ParseUrl(dataUrl);
if (model.Method == "addtag")
{
var tagid = model.Args["tagid"];
WxOpenApi.AddTag(this.AppId, new List<string>() { this.FromUserName }, tagid);
}
var userInfo = await WxOpenApi.GetUserUnionIDinfo(this.AppId, this.FromUserName);
return true;
}
}
}

View File

@@ -1,35 +0,0 @@
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 请求消息
/// </summary>
public class MessageMPBase : IMessageBase
{
public MessageMPBase(XDocument doc)
{
this.FromUserName = doc.Root.Element("FromUserName").Value;
this.ToUserName = doc.Root.Element("ToUserName").Value;
this.CreateTime = long.Parse(doc.Root.Element("CreateTime").Value);
}
public string AppId { get; set; }
public string FromUserName { get; set; }
public string ToUserName { get; set; }
public long CreateTime { get; set; }
public virtual RequestInfoType InfoType
{
get { return RequestInfoType.component_verify_ticket; }
}
public virtual async Task<bool> Handler()
{
return true;
}
}
}

View File

@@ -1,45 +0,0 @@
/*
<xml>
<AppId>第三方平台appid</AppId>
<CreateTime>1413192760</CreateTime>
<InfoType>authorized</InfoType>
<AuthorizerAppid>公众号appid</AuthorizerAppid>
<AuthorizationCode>授权码code</AuthorizationCode>
<AuthorizationCodeExpiredTime>过期时间</AuthorizationCodeExpiredTime>
</xml>
*/
using System;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 授权成功通知
/// </summary>
public class MessageAuthorized : MessageOpenBase
{
public MessageAuthorized(XDocument doc) : base(doc)
{
this.AuthorizerAppid = doc.Root.Element("AuthorizerAppid").Value;
this.AuthorizationCode = doc.Root.Element("AuthorizationCode").Value;
this.AuthorizationCodeExpiredTime = DateTimeOffset.Parse(doc.Root.Element("AuthorizationCodeExpiredTime").Value);
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.authorized; }
}
/// <summary>
/// 公众号appid
/// </summary>
public string AuthorizerAppid { get; set; }
/// <summary>
/// 授权码code
/// </summary>
public string AuthorizationCode { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public DateTimeOffset AuthorizationCodeExpiredTime { get; set; }
}
}

View File

@@ -1,32 +0,0 @@
using Hncore.Pass.MsgCenter.Constant;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
//<xml>
// <AppId> </AppId>
// <CreateTime>1413192605 </CreateTime>
// <InfoType> </InfoType>
// <ComponentVerifyTicket> </ComponentVerifyTicket>
//</xml>
public class MessageComponentVerifyTicket : MessageOpenBase
{
public MessageComponentVerifyTicket(XDocument doc):base(doc)
{
this.ComponentVerifyTicket = doc.Root.Element("ComponentVerifyTicket").Value;
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.component_verify_ticket; }
}
public string ComponentVerifyTicket { get; set; }
public override async Task<bool> Handler()
{
//把ticket存入redis中
return await RedisHelper.SetAsync(ConstantConfig.Redis_Psipwechat_Ticket_Key, this.ComponentVerifyTicket);
}
}
}

View File

@@ -1,28 +0,0 @@
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 请求消息
/// </summary>
public class MessageOpenBase : IMessageBase
{
public MessageOpenBase(XDocument doc)
{
this.AppId = doc.Root.Element("AppId").Value;
this.CreateTime = long.Parse(doc.Root.Element("CreateTime").Value);
}
public string AppId { get; set; }
public long CreateTime { get; set; }
public virtual RequestInfoType InfoType
{
get { return RequestInfoType.component_verify_ticket; }
}
public virtual async Task<bool> Handler()
{
return true;
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 注册审核事件推送
/// </summary>
public class MessageThirdFasteRegister : MessageOpenBase
{
public MessageThirdFasteRegister(XDocument doc) : base(doc)
{
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.notify_third_fasteregister; }
}
/// <summary>
/// 创建小程序appid
/// </summary>
public string appid { get; set; }
public string status { get; set; }
/// <summary>
/// 第三方授权码
/// </summary>
public string auth_code { get; set; }
public string msg { get; set; }
/// <summary>
/// 注册时提交的资料
/// </summary>
public info info {get;set;}
}
/// <summary>
/// 注册时提交的资料信息
/// </summary>
public class info
{
/// <summary>
/// 企业名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 企业代码
/// </summary>
public string code { get; set; }
/// <summary>
/// 企业代码类型
/// </summary>
public CodeType code_type { get; set; }
/// <summary>
/// 法人微信号
/// </summary>
public string legal_persona_wechat { get; set; }
/// <summary>
/// 法人姓名
/// </summary>
public string legal_persona_name { get; set; }
/// <summary>
/// 第三方联系电话
/// </summary>
public string component_phone { get; set; }
}
}

View File

@@ -1,44 +0,0 @@
/*
<xml>
<AppId>第三方平台appid</AppId>
<CreateTime>1413192760</CreateTime>
<InfoType>unauthorized</InfoType>
<AuthorizerAppid>公众号appid</AuthorizerAppid>
</xml>
*/
using Hncore.Infrastructure.Common;
using System;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
public class MessageUnauthorized : MessageOpenBase
{
public MessageUnauthorized(XDocument doc) : base(doc)
{
this.AuthorizerAppid = doc.Root.Element("AuthorizerAppid").Value;
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.unauthorized; }
}
public string AuthorizerAppid { get; set; }
public override async Task<bool> Handler()
{
if (!string.IsNullOrEmpty(this.AuthorizerAppid))
{
try
{
}
catch(Exception ex)
{
LogHelper.Error("MessageUnauthorized",ex.Message);
}
}
return false;
}
}
}

View File

@@ -1,36 +0,0 @@
using System;
using System.Xml.Linq;
namespace Hncore.Wx.Open
{
/// <summary>
/// 授权更新通知
/// </summary>
public class MessageUpdateAuthorized : MessageOpenBase
{
public MessageUpdateAuthorized(XDocument doc) : base(doc)
{
this.AuthorizerAppid = doc.Root.Element("AuthorizerAppid").Value;
this.AuthorizationCode = doc.Root.Element("AuthorizationCode").Value;
this.AuthorizationCodeExpiredTime = DateTimeOffset.Parse(doc.Root.Element("AuthorizationCodeExpiredTime").Value);
}
public override RequestInfoType InfoType
{
get { return RequestInfoType.updateauthorized; }
}
/// <summary>
/// 公众号appid
/// </summary>
public string AuthorizerAppid { get; set; }
/// <summary>
/// 授权码code
/// </summary>
public string AuthorizationCode { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public DateTimeOffset AuthorizationCodeExpiredTime { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 获取公众号授权连接的URL
/// </summary>
public class GetAuthenticationUrlRequest
{
public string component_appid { get; set; }
/// <summary>
/// 从<see cref="GetPreAuthCodeRequest"/>来
/// </summary>
public string pre_auth_code { get; set; }
public string redirect_uri { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Etor.Wx.Open
{
public class GetAuthorizerClientUserOpenIdRequest
{
public object AuthorizerAppId { get; set; }
public object CallbackCode { get; set; }
public object AppID { get; set; }
public object ComponentAccessToken { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
namespace Etor.Wx.Open
{
//{"authorizer_info":{"nick_name":"etor生活","head_img":"http:\/\/wx.qlogo.cn\/mmopen\/nlGmMCWo3wjyEnPPhOv2ygZbyEfyHmQHURK1odOyqGTys5kpdwFCmFo4PV6j2lCtkIWzqCJJvy9Ml7LS1XqUY3wsYn5lHKRX\/0","service_type_info":{"id":2},"verify_type_info":{"id":0},"user_name":"gh_d2ce4e1abd93","alias":"","qrcode_url":"http:\/\/mmbiz.qpic.cn\/mmbiz_jpg\/OdctpfnnOo6dEuSOQRFTK9V4ue1yxH7UGAZuKtJlN5M64Grm8tRWgSEnrYWIPlSUf2AaKwialhGWh4wLbHbZ1ng\/0","business_info":{"open_pay":0,"open_shake":0,"open_scan":0,"open_card":0,"open_store":0},"idc":1,"principal_name":"河南云拓智能科技有限公司","signature":"etor生活围绕商业综合体为周边人群提供智慧、便捷化服务的生活助手"},"authorization_info":{"authorizer_appid":"wx5cf944c37bf234ee","authorizer_refresh_token":"refreshtoken@@@fxrfTkTrpHPEHMDjGFWvljuB_JFW4VPQY7kmkbjamXY","func_info":[{"funcscope_category":{"id":1}},{"funcscope_category":{"id":15}},{"funcscope_category":{"id":4}},{"funcscope_category":{"id":7}},{"funcscope_category":{"id":2}},{"funcscope_category":{"id":3}},{"funcscope_category":{"id":11}}]}}
public class GetAuthorizerInfoRequest
{
public string component_access_token { get; set; }
public string component_appid { get; set; }
public string authorizer_appid { get; set; }
}
}

View File

@@ -1,25 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 获取<seealso cref="authorization_code"/>代表的第三方App的api执行权限
/// </summary>
public class GetAuthorizerInvokeAccessTokenRequest
{
/// <summary>
/// 第三方平台的访问令牌
/// </summary>
public string component_access_token { get; set; }
/// <summary>
/// 第三方平台的AppId
/// </summary>
public string component_appid { get; set; }
/// <summary>
/// 授权码,在公众号授权后,发送到回调地址上
/// 从<see cref="GetAuthenticationUrlRequest"/>拿到authorization_code
/// </summary>
public string authorization_code
{
get; set;
}
}
}

View File

@@ -1,17 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 获取第三方App的AccessToken
/// <see cref="GetPreAuthCodeRequest"/>使用
///
/// </summary>
public class GetComponentAccessTokenRequest
{
public string component_appid { get; set; }
public string component_appsecret { get; set; }
/// <summary>
/// <see cref="GetComponentVerifyTicketRequest"/>这个请求可以拿到
/// </summary>
public string component_verify_ticket { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 从微信推送的消息内拉取ticket
/// </summary>
public class GetComponentVerifyTicketRequest
{
public string TicketSourceServerUrl { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
namespace Etor.Wx.Open
{
public class GetPreAuthCodeRequest
{
/// <summary>
/// <see cref="GetComponentAccessTokenRequest"/>拿到的
/// </summary>
public string component_access_token { get; set; }
public string component_appid { get; set; }
}
}

View File

@@ -1,8 +0,0 @@
namespace Etor.Wx.Open
{
public class GetSavedAuthorizerInfoRequest
{
public string DomainUrl { get; set; }
public string AppId { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 获取wechat推送的ticket
/// </summary>
public class GetWechatTicketRequest
{
}
}

View File

@@ -1,51 +0,0 @@
using Hncore.Infrastructure.Extension;
using System;
using System.Collections.Generic;
namespace Etor.Wx.Open
{
public class jsapi_ticket
{
public static object get_locker = new object();
public int errcode { get; set; }
public string errmsg { get; set; }
public string ticket { get; set; }
public int expires_in { get; set; }
public int created_timestamp { get; set; }
public bool is_expired
{
get
{
var dt = (DateTime.Now.TimestampFrom19700101() - this.created_timestamp);
return errcode != 0 || dt < 0 || dt > 6000;
}
}
}
public class wx_config
{
public bool debug { get; set; }
public string appId { get; set; }
public string timestamp { get; set; }
public string nonceStr { get; set; }
public string signature { get; set; }
public List<string> jsApiList { get; set; }
}
/// <summary>
/// 获取wxjs配置请求
/// </summary>
public class GetWxJsConfigRequest
{
/// <summary>
/// 公众号appid
/// </summary>
public string Appid { get; set; }
/// <summary>
/// 当前的请求地址
/// </summary>
public string CurrentUrl { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
namespace Etor.Wx.Open
{
// {
//"component_appid":"appid_value",
//"authorizer_appid":"auth_appid_value",
//"authorizer_refresh_token":"refresh_token_value",
//}
/// <summary>
/// 刷新从<see cref="GetAuthorizerInvokeAccessTokenRequest"/>得到的AccessToken
/// </summary>
public class RefreshAuthorizerInvokeAccessTokenRequest
{
public string component_appid { get; set; }
public string authorizer_appid { get; set; }
public string authorizer_refresh_token { get; set; }
public string component_access_token { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace Hncore.Wx.Open
{
public class SaveAuthorizerInfoRequest
{
public string Domain { get; set; }
public authorizer_info AuthorizerInfo { get; set; }
public authorization_info AuthorizationInfo { get; set; }
}
}

View File

@@ -1,8 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class SaveWechatAppMenuRequest
{
}
}

View File

@@ -1,10 +0,0 @@
namespace Etor.Wx.Open
{
/// <summary>
/// 更新微信推送的票据
/// </summary>
public class UpdateWechatTicketRequest
{
public string NewTicket { get; set; }
}
}

View File

@@ -1,38 +0,0 @@
namespace Etor.Wx.Open
{
public class UploadWxImageMaterialRequest
{
/// <summary>
/// 是否永久素材
/// </summary>
public bool IsTemp { get; set; }
/// <summary>
/// image 图片 thumb 缩略图
/// </summary>
public string MediaType { get; set; }
/// <summary>
/// 图片名称
/// </summary>
public string imagename { get; set; }
/// <summary>
/// 分组id默认0
/// </summary>
public int groupid { get; set; }
/// <summary>
/// 小区/写字楼编码
/// </summary>
public string projectcode { get; set; }
/// <summary>
/// 公众号appid
/// </summary>
public string appid { get; set; }
/// <summary>
///图片地址
/// </summary>
public string url { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace Etor.Wx.Open
{
public class UploadWxMediaRequest
{
}
}

View File

@@ -1,16 +0,0 @@
namespace Etor.Wx.Open
{
public class WechatRequestBase
{
public int OwnerID { get; set; }
public int OperaterID { get; set; }
public int ProjectCode { get; set; }
protected string _url;
public string url { get { return _url; } }
public string access_token { get; set; }
}
public class WechatRequestBase<TData> : WechatRequestBase
{
public TData post_body { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class CreateQrcodeResponse : ResponseBase
{
public string ticket { get; set; }
public string url { get; set; }
}
}

View File

@@ -1,6 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetAuthenticationUrlResponse : ResponseBase
{
}
}

View File

@@ -1,7 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetAuthorizerClientUserOpenIdResponse : ResponseBase
{
public wechat_access_token AccessToken { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetAuthorizerInfoResponse : ResponseBase
{
public authorizer_info authorizer_info { get; set; }
public authorization_info authorization_info { get; set; }
public string content { get; set; }
}
}

View File

@@ -1,32 +0,0 @@
namespace Hncore.Wx.Open
{
// {
//"authorization_info":
//{
//"authorizer_appid": "wxf8b4f85f3a794e77",
//"authorizer_access_token": "QXjUqNqfYVH0yBE1iI_7vuN_9gQbpjfK7hYwJ3P7xOa88a89-Aga5x1NMYJyB8G2yKt1KCl0nPC3W9GJzw0Zzq_dBxc8pxIGUNi_bFes0qM",
//"expires_in": 7200,
//"authorizer_refresh_token": "dTo-YCXPL4llX-u1W1pPpnp8Hgm4wpJtlR6iV0doKdY",
//"func_info":
// [
//{"funcscope_category": {"id": 1}},
//{"funcscope_category": {"id": 2}},
//{"funcscope_category": {"id": 3}}
//]
//}
//}
/// <summary>
/// 授权码换取访问令牌结果类
/// <see cref="GetAuthorizerInvokeAccessTokenRequest"/>
/// </summary>
///
public class GetAuthorizerInvokeAccessTokenResponse:ResponseBase
{
/// <summary>
/// 授权信息对象
/// </summary>
public authorization_info authorization_info { get; set; }
}
}

View File

@@ -1,18 +0,0 @@
namespace Hncore.Wx.Open
{
// {
//"component_access_token":"61W3mEpU66027wgNZ_MhGHNQDHnFATkDa9-2llqrMBjUwxRSNPbVsMmyD-yq8wZETSoE5NQgecigDrSHkPtIYA",
//"expires_in":7200
//}
/// <summary>
/// <see cref="GetComponentAccessTokenRequest"/>
/// </summary>
public class GetComponentAccessTokenResponse : ResponseBase
{
public string component_access_token { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Hncore.Wx.Open
{
/// <summary>
/// <see cref="GetComponentVerifyTicketRequest"/>
/// </summary>
public class GetComponentVerifyTicketResponse:ResponseBase
{
public string ComponentVerifyTicket { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetGetWebAccessTokenResponse : ResponseBase
{
public string access_token { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
using Hncore.Wx.Open;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.MsgCenter.WxOpen.Response
{
public class GetJsApiTicketResponse : ResponseBase
{
public string ticket { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
namespace Hncore.Wx.Open
{
//{"access_token":"ACCESS_TOKEN","expires_in":7200}
/// <summary>
/// <see cref=" GetPreAuthCodeRequest"/>
/// </summary>
public class GetAccessTokenResponse : ResponseBase
{
public string access_token { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
namespace Hncore.Wx.Open
{
// {
//"pre_auth_code":"Cx_Dk6qiBE0Dmx4EmlT3oRfArPvwSQ-oa3NL_fwHM7VI08r52wazoZX2Rhpz1dEw",
//"expires_in":600
//}
/// <summary>
/// <see cref=" GetPreAuthCodeRequest"/>
/// </summary>
public class GetPreAuthCodeResponse:ResponseBase
{
public string pre_auth_code { get; set; }
}
}

View File

@@ -1,6 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetSavedAuthorizerInfoResponse:ResponseBase
{
}
}

View File

@@ -1,18 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class GetTagsResponse : ResponseBase
{
public List<TagItem> tags { get; set; }
}
public class TagItem
{
public int id { get; set; }
public string name { get; set; }
public int count { get; set; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Hncore.Wx.Open
{
public class GetTemplateResponse : ResponseBase
{
public string template_id { get; set; }
}
}

View File

@@ -1,20 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class GetTempleteListResponse : ResponseBase
{
public List<TempleteItem> template_list { get; set; }
}
public class TempleteItem
{
public string template_id { get; set; }
public string title { get; set; }
public string primary_industry { get; set; }
public string deputy_industry { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class GetUserinfoResponse : ResponseBase
{
public string openid { get; set; }
public string nickname { get; set; }
public string sex { get; set; }
public string province { get; set; }
public string city { get; set; }
public string country { get; set; }
public string headimgurl { get; set; }
public List<string> privilege { get; set; }
public string unionid { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Hncore.Wx.Open
{
/// <summary>
/// <see cref=" GetWechatTicketRequest"/>
/// </summary>
public class GetWechatTicketResponse:ResponseBase
{
public string Ticket { get; set; }
}
}

View File

@@ -1,17 +0,0 @@
namespace Hncore.Wx.Open
{
// {
//"authorizer_access_token": "aaUl5s6kAByLwgV0BhXNuIFFUqfrR8vTATsoSHukcIGqJgrc4KmMJ-JlKoC_-NKCLBvuU1cWPv4vDcLN8Z0pn5I45mpATruU0b51hzeT1f8",
//"expires_in": 7200,
//"authorizer_refresh_token": "BstnRqgTJBXb9N2aJq6L5hzfJwP406tpfahQeLNxX0w"
//}
/// <summary>
/// <see cref="RefreshAuthorizerInvokeAccessTokenRequest"/>
/// </summary>
public class GetAuthorizerAccessTokenResponse : ResponseBase
{
public string authorizer_access_token { get; set; }
public string authorizer_refresh_token { get; set; }
}
}

View File

@@ -1,7 +0,0 @@
namespace Hncore.Wx.Open
{
public class SaveAuthorizerInfoResponse : ResponseBase
{
}
}

View File

@@ -1,7 +0,0 @@
namespace Hncore.Wx.Open
{
public class SaveWechatAppMenuResponse : ResponseBase
{
}
}

View File

@@ -1,12 +0,0 @@
namespace Hncore.Wx.Open
{
/// <summary>
/// <see cref=" UpdateWechatTicketRequest"/>
/// </summary>
public class UpdateWechatTicketResponse : ResponseBase
{
public UpdateWechatTicketResponse() {
}
}
}

View File

@@ -1,20 +0,0 @@
namespace Hncore.Wx.Open
{
public class UploadMediaResponse:ResponseBase
{
public string type { get; set; }
public string media_id { get; set; }
public int created_at { get; set; }
}
public class UploadImageMediaResponse : ResponseBase
{
public string url { get; set; }
public string media_id { get; set; }
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class WechatNotificationTemplate
{
public string template_id { get; set; }
public string title { get; set; }
public string primary_industry { get; set; }
public string deputy_industry { get; set; }
public string content { get; set; }
public string example { get; set; }
}
public class GetAllPrivateTemplateResponse : ResponseBase
{
public List<WechatNotificationTemplate> template_list { get; set; }
}
public class WechatAddNotificationTemplateResponse : ResponseBase
{
public string template_id { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Hncore.Infrastructure.Extension;
using System;
namespace Hncore.Wx.Open
{
public class ResponseBase
{
public int errcode { get; set; }
public string errmsg { get; set; }
public int expires_in { get; set; }
public long create_from { get; set; }
public virtual bool need_to_refresh_token
{
get
{
var timespan = (DateTime.Now.TimestampFrom19700101() - create_from);
//此处不应该等于0 errcode=0表明微信返回的token有错误 需要刷新 ==0是正确的
//提前10分钟过期
return errcode != 0 || timespan < 0 || timespan > expires_in-10*60;
}
}
}
}

View File

@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
public class SendResult
{
public int errcode { get; set; }
public string errmsg { get; set; }
public long msgid { get; set; }
}
}

View File

@@ -1,266 +0,0 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.MsgCenter.Constant;
using Hncore.Pass.MsgCenter.Util;
using Hncore.Wx.Open.Enums;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Wx.Open
{
public static class TemplateApi
{
private static IHttpClientFactory _HttpClientFactory;
public static void Init(IHttpClientFactory HttpClientFactory)
{
_HttpClientFactory = HttpClientFactory;
}
private static HttpClient GetHttpClient()
{
return _HttpClientFactory.CreateClient("WxOpen");
}
/// <summary>
/// 开放平台或者公众平台或者小程序发送模板消息
/// </summary>
/// <param name="appId">公众号appid</param>
/// <param name="templateId">模板id</param>
/// <param name="to">openid ,号分割</param>
/// <param name="tData">数据</param>
/// <returns></returns>
public static async Task<SendResult> SendTemplateMessageAsync(string appId, string to, ChannelType chennel, TemplateBaseModel tData)
{
var wxAppSecret = WxOpenApi.GetWxAppSecret(appId);
var access_token = "";
if (!string.IsNullOrWhiteSpace(wxAppSecret))//公众平台或者小程序直接发送模板消息
{
access_token = await WxOpenApi.GetAccessToken(appId, wxAppSecret);
}
else//开放平台代公众平台发送模板消息
{
access_token = await WxOpenApi.GetAuthorizerAccessToken(appId);
}
var tplId =await GetTemplateIdAsync(appId, tData.template_id);
if (string.IsNullOrWhiteSpace(tplId))
{
LogHelper.Error("没有找到对应的模板Id", $"appid={appId},tpl={tData.template_id}");
return new SendResult()
{
errcode = 10001,
errmsg = "没有对应的模板"
};
}
tData.template_id = tplId;
var userList = to.Split(',');
foreach (var touser in userList)
{
tData.touser = touser;
var reqData = tData.ToData();
if (chennel == ChannelType.MP)
{
mp_send(access_token, reqData);
}
else if (chennel == ChannelType.MiniApp)
{
miniapp_send(access_token, reqData);
}
}
return new SendResult();
}
/// <summary>
/// 发送小程序订阅消息
/// </summary>
/// <param name="appId">小程序appid</param>
/// <param name="templateId">模板id</param>
/// <param name="to">openid ,号分割</param>
/// <param name="tData">数据</param>
/// <returns></returns>
public static async Task<SendResult> SendSubscribeMessageAsync(string appId, string to, TemplateBaseModel tData)
{
var wxAppSecret = WxOpenApi.GetWxAppSecret(appId);
var access_token = await WxOpenApi.GetAccessToken(appId, wxAppSecret);
var userList = to.Split(',');
foreach (var touser in userList)
{
tData.touser = touser;
var reqData = tData.ToData();
miniapp_subscribe_send(access_token, reqData);
}
return new SendResult();
}
/// <summary>
/// 根据短模板编号得到对应的模板id
/// </summary>
/// <param name="appId"></param>
/// <param name="short_tpl_id"></param>
/// <returns></returns>
public static async Task<string> GetTemplateIdAsync(string appId, string short_tpl_id)
{
if (!short_tpl_id.StartsWith("OPENTM") && !short_tpl_id.StartsWith("TM")&& !short_tpl_id.StartsWith("ETOR"))
{
return short_tpl_id;
}
var key = string.Format(ConstantConfig.Redis_TempleteId_Key, appId, short_tpl_id);
var templete_id = await RedisHelper.GetAsync(key);
if (!string.IsNullOrWhiteSpace(templete_id))
{
return templete_id;
}
var access_token = await WxOpenApi.GetAuthorizerAccessToken(appId);
var ret = await get_tpl(access_token, short_tpl_id);
if (ret.errcode == 0)
{
await RedisHelper.SetAsync(key, ret.template_id);
return ret.template_id;
}
return "";
}
public static async Task<SendResult> mp_send(string access_token, object reqData)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new SendResult()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
string urlFormat = $"cgi-bin/message/template/send?access_token={access_token}";
LogHelper.Debug("mp_send_req", reqData.ToJson());
var respJson = await GetHttpClient().PostAsJsonGetString(urlFormat, reqData);
var response = respJson.FromJsonToOrDefault<SendResult>();
if (response.errcode > 0)
{
LogHelper.Error("mp_send_respJson", respJson);
return response;
}
return response;
}
public static async Task<SendResult> miniapp_send(string access_token, object reqData)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new SendResult()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
string urlFormat = $"cgi-bin/message/wxopen/template/send?access_token={access_token}";
LogHelper.Debug("mp_send_req", reqData.ToJson());
var respJson = await GetHttpClient().PostAsJsonGetString(urlFormat, reqData);
var response = respJson.FromJsonToOrDefault<SendResult>();
if (response.errcode > 0)
{
LogHelper.Error("miniapp_send_respJson", respJson);
return response;
}
return response;
}
//小程序订阅消息
public static async Task<SendResult> miniapp_subscribe_send(string access_token, object reqData)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new SendResult()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
string urlFormat = $"cgi-bin/message/subscribe/send?access_token={access_token}";
LogHelper.Debug("miniapp_subscribe_send", reqData.ToJson());
var respJson = await GetHttpClient().PostAsJsonGetString(urlFormat, reqData);
var response = respJson.FromJsonToOrDefault<SendResult>();
if (response.errcode > 0)
{
LogHelper.Error("miniapp_subscribe_send", respJson);
return response;
}
return response;
}
public static async Task<SendResult> uniform_send(string access_token, object reqData)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new SendResult()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
string urlFormat = $"cgi-bin/message/wxopen/template/uniform_send?access_token={access_token}";
LogHelper.Debug("SendTemplateMessageAsync_Req", reqData.ToJson());
var respJson = await GetHttpClient().PostAsJsonGetString(urlFormat, reqData);
var response = respJson.FromJsonToOrDefault<SendResult>();
if (response.errcode > 0)
{
LogHelper.Debug("SendTemplateMessageAsync_respJson", respJson);
return response;
}
return new SendResult();
}
public static async Task<GetTemplateResponse> get_tpl(string access_token, string short_tpl_id)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new GetTemplateResponse()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
var reqData = new
{
template_id_short = short_tpl_id
};
string urlFormat = $"cgi-bin/template/api_add_template?access_token={access_token}";
LogHelper.Debug("get_tpl", reqData.ToJson());
var respJson = await GetHttpClient().PostAsJsonGetString(urlFormat, reqData);
var response = respJson.FromJsonToOrDefault<GetTemplateResponse>();
if (response.errcode > 0)
{
LogHelper.Error("get_tpl_respJson", respJson);
return response;
}
return response;
}
private static async Task<GetTempleteListResponse> get_tpl_list(string access_token)
{
if (string.IsNullOrWhiteSpace(access_token))
{
return new GetTempleteListResponse()
{
errcode = 1000,
errmsg = "access_token 不存在"
};
}
string urlFormat = $"cgi-bin/template/get_all_private_template?access_token={access_token}";
var respJson = await GetHttpClient().GetStringAsync(urlFormat);
var response = respJson.FromJsonToOrDefault<GetTempleteListResponse>();
if (response.errcode > 0)
{
LogHelper.Error("get_tpl_respJson", respJson);
return response;
}
return response;
}
}
}

View File

@@ -1,129 +0,0 @@
using System;
using System.Collections.Generic;
namespace Hncore.Wx.Open
{
public class TemplateBaseModel
{
public string touser { get; set; }
public string template_id { get; set; }
public List<TemplateDataItem> Items { get; set; } = new List<TemplateDataItem>();
//{
// "touser":"touser",
// "template_id": "TEMPLATE_ID",
// "data": {
// "keyword1": {
// "value": "339208499"
// },
// "keyword2": {
// "value": "2015年01月05日 12:30"
// },
// "keyword3": {
// "value": "腾讯微信总部"
// } ,
// "keyword4": {
// "value": "广州市海珠区新港中路397号"
// }
// }
//}
public virtual Dictionary<string, Object> ToData()
{
var data = new Dictionary<string, Object>() {
{ "touser",touser},
{"template_id",template_id}
};
var index = 1;
var dataItems = new Dictionary<string, Object>() { };
Items.ForEach(m =>
{
dataItems[$"keyword{index}"] = m;
index++;
});
data["data"] = dataItems;
return data;
}
}
public class TemplateMPModel: TemplateBaseModel
{
public string Url { get; set; }
public string MiniAppId { get; set; }
public TemplateDataItem first { get; set; }
public TemplateDataItem remark { get; set; }
public override Dictionary<string, Object> ToData()
{
var ret = base.ToData();
var data = ret ["data"] as Dictionary<string, Object>;
if (first != null) data["first"] = first;
if (remark != null) data["remark"] = remark;
if (!string.IsNullOrWhiteSpace(Url)) ret["url"] = Url;
if (!string.IsNullOrWhiteSpace(MiniAppId)) ret["miniprogram"] = new
{
appid = MiniAppId,
pagepath = Url
};
return ret;
}
}
public class TemplateMiniAppModel : TemplateBaseModel
{
public string page { get; set; }
public string form_id { get; set; }
public string emphasis_keyword { get; set; }
public override Dictionary<string, Object> ToData()
{
var ret = base.ToData();
if (!string.IsNullOrWhiteSpace(page)) ret["page"] = page;
if (!string.IsNullOrWhiteSpace(form_id)) ret["form_id"] = form_id;
if (!string.IsNullOrWhiteSpace(emphasis_keyword)) ret["emphasis_keyword"] = emphasis_keyword;
return ret;
}
}
public class TemplateDataItem
{
public TemplateDataItem(string v, string c = "#173177")
{
value = v;
color = c;
}
public string name { get; set; }
public string value { get; set; }
//
// 摘要:
// 16进制颜色代码#FF0000
public string color { get; set; }
}
/// <summary>
/// 小程序订阅消息
/// </summary>
public class SubscribeMiniAppModel : TemplateBaseModel
{
public string page { get; set; }
public override Dictionary<string, Object> ToData()
{
var ret = base.ToData();
var data = new Dictionary<string, Object>() {
{ "touser",touser},
{"template_id",template_id}
};
var index = 1;
var dataItems = new Dictionary<string, Object>() { };
Items.ForEach(m =>
{
var num = index.ToString().PadLeft(2, '0');
dataItems[m.name] = new { value = m.value };
index++;
});
data["data"] = dataItems;
if (!string.IsNullOrWhiteSpace(page)) ret["page"] = page;
return data;
}
}
}

View File

@@ -1,106 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.MsgCenter.Constant
{
public class ConstantConfig
{
/// <summary>
/// 微信开放平台定期推送的ticket 标识
/// </summary>
public const string Redis_Psipwechat_Ticket_Key = "psipwechat_ticket";
/// <summary>
/// 微信开放平台AccessToken 标识
/// </summary>
public const string Redis_ComponentAccessToken_Key = "WEIXIN:{0}_wx_component_token.json";
/// <summary>
/// 微信开放平台accessToken 标识{authorizer_appid}
/// </summary>
public const string Redis_AuthorizerAccessToken_Key = "WEIXIN:wx_authorizer_token_{0}";
/// <summary>
/// 微信开放平台refresh_authorizer_token 标识{authorizer_appid}
/// </summary>
public const string Redis_Refresh_AuthorizerAccessToken_Key = "WEIXIN:wx_refresh_authorizer_token_{0}";
/// <summary>
/// 微信公众平台 mp_access_token 标识{appid}
/// </summary>
public const string Redis_MP_AccessToken_Key = "WEIXIN:wx_mp_access_token_{0}";
/// <summary>
/// 微信公众平台 mp_access_token 标识{openid}
/// </summary>
public const string Redis_MP_GetUserinfoByWebAccessToken_Key = "WEIXIN:userinfo_by_web_accesstoken_{0}";
/// <summary>
/// 微信公众平台 mp_access_token 标识{openid}
/// </summary>
public const string Redis_MP_GetUserUnionIDInfo_Key = "WEIXIN:userinfo_uniono_info_{0}";
/// <summary>
/// 微信公众平台 mp_access_token 标识{openid}
/// </summary>
public const string Redis_MP_GetUserOpenIdInfo_Key = "WEIXIN:userinfo_openid_info_{0}";
/// <summary>
/// 公众号模板key {appid}_{tplId}
/// </summary>
public const string Redis_TempleteId_Key = "WEIXIN:TempleteId_{0}_{1}";
/// <summary>
/// 公众号的基本信息{公众号appid}
/// </summary>
public const string Redis_MP_Info_Key = "WEIXIN:mp_info_{0}";
/// <summary>
/// 发送消息公众号模板消息标识
/// </summary>
public const string RabbitMQ_Send_Message_Key = "msgcenter_send_msg_{0}";
/// <summary>
/// 发送消息公众号模板消息标识
/// </summary>
public const string RabbitMQ_Send_Message_MP_Key = "msgcenter_send_msg_1";
/// <summary>
/// 送消息小程序模板消息标识
/// </summary>
public const string RabbitMQ_Send_Message_MiniApp_Key = "msgcenter_send_msg_2";
/// <summary>
/// 送消息短信模板消息标识
/// </summary>
public const string RabbitMQ_Send_Message_Sms_Key = "msgcenter_send_msg_3";
/// <summary>
/// 送消小程序订阅消息标识
/// </summary>
public const string RabbitMQ_Send_Message_Subscribe_Key = "msgcenter_send_msg_4";
public const string RabbitMQ_Send_Message_Test_Key = "msgcenter_send_msg_4";
/// <summary>
/// 发email消息
/// </summary>
public const string RabbitMQ_Send_Message_Email = "Etor.PSIP.Msgcenter.SendEmail";
/// <summary>
/// 公众号模板key {uuid}
/// </summary>
public const string Redis_WxScanWait_Key = "WEIXIN:WxScanWait_{0}";
public const string Redis_MP_Js_Ticket_Key = "WEIXIN:mp_js_ticket_{0}";
}
}

View File

@@ -1,18 +0,0 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Hncore.Pass.MsgCenter.Util
{
public class HostContext
{
public static IConfiguration Configuration { get; set; }
public static IHttpClientFactory HttpClientFactory { get; set; }
}
}

View File

@@ -1,33 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Hncore.Pass.MsgCenter.Util
{
public class ServiceContext
{
private static IServiceProvider _serviceProvider;
public static void Initialize(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <summary>
/// 构建实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Resolve<T>() where T : class
{
return _serviceProvider.GetService<T>();
}
/// <summary>
/// 构建类型
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object Resolve(Type type)
{
return _serviceProvider.GetService(type);
}
}
}

View File

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.MsgCenter.Util
{
public class UrlHelper
{
public static UrlMethodModel ParseUrl(string data)
{
var index = data.IndexOf('/');
if (index != -1)
{
data = data.Substring(index + 1);
}
UrlMethodModel model = new UrlMethodModel();
var token = data.Split('?');
if (token.Length > 0)
{
model.Method = token[0];
}
if (token.Length > 1)
{
var kvs = token[1].Split('&');
foreach (var item in kvs)
{
var kv = item.Split('=');
if (kv.Length > 1)
{
var key = kv[0].ToLower();
var value = kv[1];
model.Args[key] = value;
}
}
}
return model;
}
}
public class UrlMethodModel
{
public string Method { get; set; } = "";
public Dictionary<string, string> Args { get; set; } = new Dictionary<string, string>();
}
}

View File

@@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nito.AsyncEx" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hncore.Infrastructure\Hncore.Infrastructure.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,30 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
namespace Hncore.Wx.Open
{
public static class WxApiExt
{
public static void AddWxApi(this IServiceCollection services)
{
services.AddHttpClient("WxOpen", client =>
{
client.BaseAddress = new Uri("https://api.weixin.qq.com/");
client.Timeout = TimeSpan.FromSeconds(10);
});
}
public static void UseWxApi(this IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var configuration = serviceProvider.GetService<IConfiguration>();
var httpFactory = serviceProvider.GetService<IHttpClientFactory>();
WxOpenApi.Init(configuration, httpFactory);
TemplateApi.Init(httpFactory);
}
}
}

View File

@@ -1,759 +0,0 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.MsgCenter.Constant;
using Hncore.Pass.MsgCenter.Util;
using Hncore.Pass.MsgCenter.WxOpen.Response;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
namespace Hncore.Wx.Open
{
public class WxOpenApi
{
private static readonly AsyncLock _mutex1 = new AsyncLock();
private static readonly AsyncLock _mutex2 = new AsyncLock();
private static readonly AsyncLock _mutex4 = new AsyncLock();
private static Dictionary<string, string> WxAppMap = new Dictionary<string, string>();
private static IHttpClientFactory _HttpClientFactory;
public static void Init(IConfiguration config, IHttpClientFactory HttpClientFactory)
{
_HttpClientFactory = HttpClientFactory;
var key = config[$"WxApps:AppID"];
WxAppMap[key] = config[$"WxApps:AppSecret"];
//var WxMpApps = config.GetSection("WxApps");
//var nodes = WxMpApps.GetChildren();
//for (var i = 0; i < nodes.Count(); i++)
//{
// var key = config[$"WxApps:{i}:AppID"];
// var value = config[$"WxApps:{i}:AppSecret"];
// if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
// WxAppMap[key] = value;
//}
}
public static string GetWxAppSecret(string appid)
{
if (WxAppMap.ContainsKey(appid))
return WxAppMap[appid];
else return "";
}
private static HttpClient GetHttpClient()
{
return _HttpClientFactory.CreateClient("WxOpen");
}
public static async Task<string> GetComponentTicket()
{
return await RedisHelper.GetAsync(ConstantConfig.Redis_Psipwechat_Ticket_Key);
}
public static async Task<bool> SetComponentTicket(string ticket)
{
return await RedisHelper.SetAsync(ConstantConfig.Redis_Psipwechat_Ticket_Key, ticket);
}
/// <summary>
/// 开放平台:得到开放平台的accessToken
/// </summary>
/// <returns></returns>
public static async Task<string> GetComponentAccessToken()
{
var component_appid = HostContext.Configuration["WxOpen:AppID"];
var key =string.Format(ConstantConfig.Redis_ComponentAccessToken_Key, component_appid);
var tokenJson = await RedisHelper.GetAsync(key);
var token = tokenJson.FromJsonToOrDefault<GetComponentAccessTokenResponse>();
if (token == null || token.need_to_refresh_token)
{
using (await _mutex1.LockAsync())
{
tokenJson = await RedisHelper.GetAsync(key);
token = tokenJson.FromJsonToOrDefault<GetComponentAccessTokenResponse>();
if (token != null && !token.need_to_refresh_token)
{
return token.component_access_token;
}
//重新去微信获取
var ticket =await GetComponentTicket();
token = await get_component_access_token(ticket);
if (token.errcode == 0)
{
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
return token.component_access_token;
}
else
{
return "";
}
}
}
return token.component_access_token;
}
/// <summary>
/// 开放平台:得到公众平台的AccessToken
/// </summary>
/// <returns></returns>
public static async Task<string> GetAuthorizerAccessToken(string authorizer_appid)
{
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
var tokenJson = await RedisHelper.GetAsync(key);
var token = tokenJson.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
if (token == null || token.need_to_refresh_token)
{
using (await _mutex2.LockAsync())
{
tokenJson = await RedisHelper.GetAsync(key);
token = tokenJson.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
if (token != null && !token.need_to_refresh_token)
{
return token.authorizer_access_token;
}
var authorizer_refresh_token = await RedisHelper.GetAsync(refresh_key);
var component_access_token = await GetComponentAccessToken();
token = await get_authorizer_access_token_by_refresh(authorizer_appid, authorizer_refresh_token, component_access_token);
if (token.errcode == 0)
{
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
await RedisHelper.SetAsync(refresh_key, token.authorizer_refresh_token,60*60*24*30);
return token.authorizer_access_token;
}
else
{
return "";
}
}
}
return token.authorizer_access_token;
}
public static async Task ReFreshAccessToken(string authorizer_appid, string component_access_token)
{
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
var authorizer_refresh_token = await RedisHelper.GetAsync(refresh_key);
using (await _mutex4.LockAsync())
{
var token = await get_authorizer_access_token_by_refresh(authorizer_appid, authorizer_refresh_token, component_access_token);
if (token.errcode == 0)
{
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
await RedisHelper.SetAsync(refresh_key, token.authorizer_refresh_token,60 * 60 * 24 * 30);
}
}
}
/// <summary>
///开放平台: 通过回调返回授权码的方式获得公众号的accesstoken
/// </summary>
/// <param name="authorization_code"></param>
/// <returns></returns>
public static async Task<string> GetAuthorizerAccessTokenByCode(string authorization_code,Func<authorization_info, Task<string>> callback)
{
var component_access_token = await GetComponentAccessToken();
var ret = await get_authorizer_access_token_by_callback(authorization_code, component_access_token);
var authorizer_appid = ret.authorization_info.authorizer_appid;
//存access_token的key
var key = string.Format(ConstantConfig.Redis_AuthorizerAccessToken_Key, authorizer_appid);
//存refresh_access_token的key
var refresh_key = string.Format(ConstantConfig.Redis_Refresh_AuthorizerAccessToken_Key, authorizer_appid);
var info = new GetAuthorizerAccessTokenResponse()
{
authorizer_access_token = ret.authorization_info.authorizer_access_token,
authorizer_refresh_token = ret.authorization_info.authorizer_refresh_token,
expires_in = ret.authorization_info.expires_in,
create_from = DateTime.Now.TimestampFrom19700101()
};
await RedisHelper.SetAsync(key, info.ToJson(), info.expires_in);
await RedisHelper.SetAsync(refresh_key, info.authorizer_refresh_token);
if (callback != null)
{
return await callback(ret.authorization_info);
}
return info.authorizer_access_token;
}
/// <summary>
///开放平台: 得到开放平台的预授权码
/// </summary>
/// <returns></returns>
public static async Task<string> GetPreAuthCode()
{
var component_access_token = await GetComponentAccessToken();
var ret = await get_pre_auth_Code(component_access_token);
return ret.pre_auth_code;
}
/// <summary>
///开放平台: 代公众号获取用户在公众号的OpenId以及AccessToken 信息
/// </summary>
/// <param name="req"></param>
/// <returns>结果对象,里边包含了授权令牌信息</returns>
public static async Task<wechat_access_token> GetAuthorizerClientUserOpenIdInfo(string appid, string code)
{
var component_access_token = await GetComponentAccessToken();
var ret = await get_authorizer_user_openIdifno(appid, code, component_access_token);
return ret;
}
/// <summary>
/// 开放平台:为公众平台授权的url
/// </summary>
/// <returns></returns>
public static async Task<string> GetAuthorizationUrl(string callback_url)
{
var appID = HostContext.Configuration["WxOpen:AppID"]; ;
var pre_auth_code = await GetPreAuthCode();
var baseUrl = HostContext.Configuration["BaseInfoUrl"];
callback_url = $"{baseUrl}/{callback_url}";//回调地址
callback_url = HttpUtility.UrlEncode(callback_url);
//开放平台授权地址
var url = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?" +
$"component_appid={appID}" +
$"&pre_auth_code={pre_auth_code}" +
$"&redirect_uri={callback_url}";
return url;
}
private static readonly AsyncLock _mutex3 = new AsyncLock();
/// <summary>
/// 【公众平台、小程序】:得到公众平台、小程序的accessToken
/// </summary>
/// <returns></returns>
public static async Task<string> GetAccessToken(string appid, string secret)
{
var key = string.Format(ConstantConfig.Redis_MP_AccessToken_Key, appid);
var tokenJson = await RedisHelper.GetAsync(key);
var token = tokenJson.FromJsonToOrDefault<GetAccessTokenResponse>();
if (token == null || token.need_to_refresh_token)
{
using (await _mutex3.LockAsync())
{
tokenJson = await RedisHelper.GetAsync(key);
token = tokenJson.FromJsonToOrDefault<GetAccessTokenResponse>();
if (token != null && !token.need_to_refresh_token)
{
return token.access_token;
}
token = await get_access_token(appid, secret);
if (token.errcode == 0)
{
await RedisHelper.SetAsync(key, token.ToJson(), token.expires_in);
return token.access_token;
}
return "";
}
}
return token.access_token;
}
/// <summary>
/// 公众平台通过code换取网页授权access_token
/// </summary>
/// <param name="appid"></param>
/// <param name="secret"></param>
/// <returns></returns>
public static async Task<GetGetWebAccessTokenResponse> GetWebAccessToken(string appid, string code)
{
var secret = GetWxAppSecret(appid);
if (string.IsNullOrWhiteSpace(secret))
{
LogHelper.Error("GetWebAccessToken", $"appid={appid} 没有配置");
return null;
}
return await get_web_access_token(appid, secret, code);
}
/// <summary>
/// 通过access_token和openid拉取用户信息
/// </summary>
/// <param name="appid"></param>
/// <param name="code"></param>
/// <returns></returns>
public static async Task<GetUserinfoResponse> GetUserinfoByWebAccessToken(string access_token, string openid)
{
var key = string.Format(ConstantConfig.Redis_MP_GetUserinfoByWebAccessToken_Key, openid);
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
if (userInfo == null)
{
userInfo = await get_userinfo_by_web_access_token(access_token, openid);
if (userInfo.errcode == 0)
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
}
return userInfo;
}
/// <summary>
/// 开放平台获得获取用户基本信息(UnionID机制)
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
public static async Task<GetUserinfoResponse> GetUserUnionIDinfo(string appid, string openid)
{
var key = string.Format(ConstantConfig.Redis_MP_GetUserUnionIDInfo_Key, openid);
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
if (userInfo == null)
{
var access_token = await GetAuthorizerAccessToken(appid);
userInfo = await get_user_openid_info(access_token, openid);
if (userInfo.errcode == 0)
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
}
return userInfo;
}
/// <summary>
/// 公众平台获得获取用户基本信息()
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
public static async Task<GetUserinfoResponse> GetUserinfoByOpenId(string appid, string openid)
{
var key = string.Format(ConstantConfig.Redis_MP_GetUserOpenIdInfo_Key, openid);
var userInfo = await RedisHelper.GetAsync<GetUserinfoResponse>(key);
if (userInfo == null)
{
var access_token = await GetAccessToken(appid,GetWxAppSecret(appid));
userInfo = await get_user_openid_info(access_token, openid);
if (userInfo.errcode == 0)
await RedisHelper.SetAsync(key, userInfo.ToJson(), 2 * 60 * 60);
}
return userInfo;
}
/// <summary>
/// 通过开放平台获得公众号的信息
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
public static async Task<authorizer_info> GetMpInfo(string authorizer_appid)
{
var key = string.Format(ConstantConfig.Redis_MP_Info_Key, authorizer_appid);
var mpInfo = await RedisHelper.GetAsync<GetAuthorizerInfoResponse>(key);
if (mpInfo == null)
{
var component_token = await GetComponentAccessToken();
mpInfo = await get_mp_info(component_token, authorizer_appid);
if (mpInfo.errcode == 0)
await RedisHelper.SetAsync(key, mpInfo.ToJson(), 1 * 60 * 60);
}
return mpInfo.authorizer_info;
}
/// <summary>
/// 为公众平台创建菜单
/// </summary>
/// <param name="authorizer_appid"></param>
/// <returns></returns>
public static async Task<bool> CreateMPMenu(string access_token, object menu)
{
var ret = await create_mp_menu(access_token, menu);
return ret.errcode == 0;
}
/// <summary>
/// 为公众平台粉丝添加标签
/// </summary>
/// <param name="authorizer_appid"></param>
/// <returns></returns>
public static async Task AddTag(string appid, List<string> openIds, string tagId)
{
var access_token = await GetAuthorizerAccessToken(appid);
await add_tag(access_token, openIds, int.Parse(tagId));
}
/// <summary>
/// 得到公众平台所有标签
/// </summary>
/// <param name="authorizer_appid"></param>
/// <returns></returns>
public static async Task<GetTagsResponse> GetTags(string appid)
{
var access_token = await GetAuthorizerAccessToken(appid);
return await get_tags(access_token);
}
/// <summary>
/// 得到公众平台jsapi ticket
///</summary>
/// <param name="authorizer_appid"></param>
/// <returns></returns>
public static async Task<GetJsApiTicketResponse> GetJsTicket(string authorizer_appid)
{
var key = string.Format(ConstantConfig.Redis_MP_Js_Ticket_Key, authorizer_appid);
var ticketInfo = await RedisHelper.GetAsync<GetJsApiTicketResponse>(key);
if (ticketInfo == null)
{
var access_token = await GetAuthorizerAccessToken(authorizer_appid);
ticketInfo = await get_jsapi_ticket(access_token);
if (ticketInfo.errcode == 0)
await RedisHelper.SetAsync(key, ticketInfo.ToJson(), 1 * 60 * 60);
}
return ticketInfo;
}
/// <summary>
/// 为公众平台创建二维码
/// </summary>
/// <param name="authorizer_appid"></param>
/// <returns></returns>
public static async Task<CreateQrcodeResponse> CreatePermanentQrcode(string appid, string scene_str)
{
var access_token = await GetAuthorizerAccessToken(appid);
return await create_permanent_qrcode(access_token, scene_str);
}
#region
/// <summary>
/// 开放平台:得到access_token
/// </summary>
/// <param name="ticket"></param>
/// <returns></returns>
private static async Task<GetComponentAccessTokenResponse> get_component_access_token(string ticket)
{
string url = "cgi-bin/component/api_component_token";
var reqData = new
{
component_appid = HostContext.Configuration["WxOpen:AppID"],
component_appsecret = HostContext.Configuration["WxOpen:AppSecret"],
component_verify_ticket = ticket,
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonTo<GetComponentAccessTokenResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_component_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_component_access_token", respData);
return ret;
}
/// <summary>
///开放平台:通过刷新的方式获得公众平台的accesstoken
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private static async Task<GetAuthorizerAccessTokenResponse> get_authorizer_access_token_by_refresh(string authorizer_appid, string authorizer_refresh_token,string component_access_token)
{
string url = $"cgi-bin/component/api_authorizer_token?component_access_token={component_access_token}";
var reqData = new
{
component_appid = HostContext.Configuration["WxOpen:AppID"],
authorizer_appid,
authorizer_refresh_token,
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<GetAuthorizerAccessTokenResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_authorizer_access_token_by_refresh", $"errcode={ret.errcode},errmsg={ret.errmsg},authorizer_appid={authorizer_appid}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_authorizer_access_token_by_callback", respData);
return ret;
}
/// <summary>
///开放平台: 通过授权码回调方式获得公众平台的accesstoken
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private static async Task<GetAuthorizerInvokeAccessTokenResponse> get_authorizer_access_token_by_callback(string authorization_code,string component_access_token)
{
string url = $"cgi-bin/component/api_query_auth?component_access_token={component_access_token}";
var reqData = new
{
component_appid = HostContext.Configuration["WxOpen:AppID"],
authorization_code,
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<GetAuthorizerInvokeAccessTokenResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_authorizer_access_token_by_callback", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_authorizer_access_token_by_callback", respData);
return ret;
}
/// <summary>
///开放平台: 获取开放平台预授权代码 用于生成授权url
/// </summary>
private static async Task<GetPreAuthCodeResponse> get_pre_auth_Code(string component_access_token)
{
string url = $"cgi-bin/component/api_create_preauthcode?component_access_token={component_access_token}";
var reqData = new
{
component_appid = HostContext.Configuration["WxOpen:AppID"],
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<GetPreAuthCodeResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_pre_auth_Code", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_pre_auth_Code", respData);
return ret;
}
/// <summary>
/// 开放平台:获得公众平台用户openid信息
/// </summary>
/// <param name="appid"></param>
/// <param name="code"></param>
/// <param name="component_access_token"></param>
/// <returns></returns>
private static async Task<wechat_access_token> get_authorizer_user_openIdifno(string appid, string code, string component_access_token)
{
LogHelper.Debug("get_authorizer_user_openIdifno_params", $"{appid},{code}");
var component_appid = HostContext.Configuration["WxOpen:AppID"];
string url = $"sns/oauth2/component/access_token?appid={appid}&code={code}&grant_type=authorization_code&component_appid={component_appid}&component_access_token={component_access_token}";
LogHelper.Debug("get_authorizer_user_openIdifno-url", url);
var resp = await GetHttpClient().GetStringAsync(url);
var respData = resp.FromJsonToOrDefault<wechat_access_token>();
LogHelper.Debug("get_authorizer_user_openIdifno", resp);
return respData;
}
/// <summary>
///公众平台,小程序: 直接获得公众平台小程序的accesstoken
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private static async Task<GetAccessTokenResponse> get_access_token(string appid, string secret)
{
string url = $"cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetAccessTokenResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_mp_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_mp_access_token", respData);
return ret;
}
/// <summary>
///公众平台通过code换取网页授权access_token
///这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token该access_token用于调用其他接口不同
///https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
private static async Task<GetGetWebAccessTokenResponse> get_web_access_token(string appid, string secret,string code)
{
string url = $"sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetGetWebAccessTokenResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_web_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
ret.create_from = DateTime.Now.TimestampFrom19700101();
LogHelper.Debug("get_web_access_token", respData);
return ret;
}
/// <summary>
/// 如果网页授权作用域为snsapi_userinfo则此时开发者可以通过access_token和openid拉取用户信息了。
/// https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
/// </summary>
/// <param name="access_token">网页授权接口调用凭证,注意此access_token与基础支持的access_token不同</param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<GetUserinfoResponse> get_userinfo_by_web_access_token(string access_token, string openid)
{
string url = $"sns/userinfo?access_token={access_token}&openid={openid}&lang=zh_CN";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetUserinfoResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_userinfo_by_web_access_token", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("get_userinfo_by_web_access_token", respData);
return ret;
}
private static async Task<GetUserinfoResponse> get_user_openid_info(string access_token, string openid)
{
string url = $"cgi-bin/user/info?access_token={access_token}&openid={openid}&lang=zh_CN";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetUserinfoResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_user_openid_info", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("get_user_openid_info", respData);
return ret;
}
/// <summary>
/// 通过开放平台得到公众号的信息,主要是 authorizer_info
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<GetAuthorizerInfoResponse> get_mp_info(string component_token, string authorizer_appid)
{
string url = $"cgi-bin/component/api_get_authorizer_info?component_access_token={component_token}";
var reqData = new
{
authorizer_appid,
component_appid = HostContext.Configuration["WxOpen:AppID"],
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<GetAuthorizerInfoResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_mp_info_resp", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("get_mp_info_resp", respData);
return ret;
}
/// <summary>
/// 为公众平台创建菜单
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<ResponseBase> create_mp_menu(string access_token, object menu)
{
string url = $"cgi-bin/menu/create?access_token={access_token}";
var respData = await GetHttpClient().PostAsJsonGetString(url, menu);
var ret = respData.FromJsonToOrDefault<ResponseBase>();
if (ret.errcode > 0)
{
LogHelper.Error("create_mp_menu", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("create_mp_menu", respData);
return ret;
}
/// <summary>
/// 为公众号粉丝打标签
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<ResponseBase> add_tag(string access_token, List<string> openIds,int tagId)
{
string url = $"cgi-bin/tags/members/batchtagging?access_token={access_token}";
var reqData = new
{
openid_list = openIds,
tagid = tagId
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<ResponseBase>();
if (ret.errcode > 0)
{
LogHelper.Error("add_tag", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("add_tag", respData);
return ret;
}
/// <summary>
/// 创建公众号二维码
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<GetTagsResponse> get_tags(string access_token)
{
string url = $"cgi-bin/tags/get?access_token={access_token}";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetTagsResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_tags", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("get_tags", respData);
return ret;
}
/// <summary>
/// 创建公众号二维码
/// </summary>
/// <param name="access_token"></param>
/// <param name="openid"></param>
/// <returns></returns>
private static async Task<CreateQrcodeResponse> create_permanent_qrcode(string access_token,string scene_str)
{
string url = $"cgi-bin/qrcode/create?access_token={access_token}";
//{ "action_name": "QR_LIMIT_STR_SCENE", "action_info": { "scene": { "scene_str": "test"} } }
var reqData = new
{
action_name = "QR_LIMIT_STR_SCENE",
action_info = new
{
scene = new
{
scene_str
}
}
};
var respData = await GetHttpClient().PostAsJsonGetString(url, reqData);
var ret = respData.FromJsonToOrDefault<CreateQrcodeResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("create_permanent_qrcode", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("create_permanent_qrcode", respData);
return ret;
}
public static async Task<GetJsApiTicketResponse> get_jsapi_ticket(string access_token)
{
string url = $"cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";
var respData = await GetHttpClient().GetStringAsync(url);
var ret = respData.FromJsonToOrDefault<GetJsApiTicketResponse>();
if (ret.errcode > 0)
{
LogHelper.Error("get_jsapi_ticket", $"errcode={ret.errcode},errmsg={ret.errmsg}");
}
LogHelper.Debug("get_jsapi_ticket", respData);
return ret;
}
#endregion
}
}

View File

@@ -1,222 +0,0 @@
using System;
using System.Collections;
//using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Tencent;
//-40001 签名验证错误
//-40002 : xml解析失败
//-40003 : sha加密生成签名失败
//-40004 : AESKey 非法
//-40005 : appid 校验错误
//-40006 : AES 加密失败
//-40007 AES 解密失败
//-40008 解密后得到的buffer非法
//-40009 : base64加密异常
//-40010 : base64解密异常
namespace Hncore.Wx.Open
{
public class WxOpenCrypt
{
string m_sToken;
string m_sEncodingAESKey;
string m_sAppID;
enum WXBizMsgCryptErrorCode
{
WXBizMsgCrypt_OK = 0,
WXBizMsgCrypt_ValidateSignature_Error = -40001,
WXBizMsgCrypt_ParseXml_Error = -40002,
WXBizMsgCrypt_ComputeSignature_Error = -40003,
WXBizMsgCrypt_IllegalAesKey = -40004,
WXBizMsgCrypt_ValidateAppid_Error = -40005,
WXBizMsgCrypt_EncryptAES_Error = -40006,
WXBizMsgCrypt_DecryptAES_Error = -40007,
WXBizMsgCrypt_IllegalBuffer = -40008,
WXBizMsgCrypt_EncodeBase64_Error = -40009,
WXBizMsgCrypt_DecodeBase64_Error = -40010
};
//构造函数
// @param sToken: 公众平台上开发者设置的Token
// @param sEncodingAESKey: 公众平台上开发者设置的EncodingAESKey
// @param sAppID: 公众帐号的appid
public WxOpenCrypt(string sToken, string sEncodingAESKey, string sAppID)
{
m_sToken = sToken;
m_sAppID = sAppID;
m_sEncodingAESKey = sEncodingAESKey;
}
// 检验消息的真实性,并且获取解密后的明文
// @param sMsgSignature: 签名串对应URL参数的msg_signature
// @param sTimeStamp: 时间戳对应URL参数的timestamp
// @param sNonce: 随机串对应URL参数的nonce
// @param sPostData: 密文对应POST请求的数据
// @param sMsg: 解密后的原文当return返回0时有效
// @return: 成功0失败返回对应的错误码
public int DecryptMsg(string sMsgSignature, string sTimeStamp, string sNonce, string sPostData, ref string sMsg)
{
if (m_sEncodingAESKey.Length!=43)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_IllegalAesKey;
}
XmlDocument doc = new XmlDocument();
XmlNode root;
string sEncryptMsg;
try
{
doc.LoadXml(sPostData);
root = doc.FirstChild;
sEncryptMsg = root["Encrypt"].InnerText;
}
catch (Exception)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_ParseXml_Error;
}
//verify signature
int ret = 0;
ret = VerifySignature(m_sToken, sTimeStamp, sNonce, sEncryptMsg, sMsgSignature);
if (ret != 0)
return ret;
//decrypt
string cpid = "";
try
{
sMsg= Cryptography.AES_decrypt(sEncryptMsg, m_sEncodingAESKey, ref cpid);
// sMsg = SecurityHelper.Decrypt(sEncryptMsg, m_sEncodingAESKey);
}
catch (FormatException)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_DecodeBase64_Error;
}
catch (Exception)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_DecryptAES_Error;
}
if (cpid != m_sAppID)
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_ValidateAppid_Error;
return 0;
}
//将企业号回复用户的消息加密打包
// @param sReplyMsg: 企业号待回复用户的消息xml格式的字符串
// @param sTimeStamp: 时间戳可以自己生成也可以用URL参数的timestamp
// @param sNonce: 随机串可以自己生成也可以用URL参数的nonce
// @param sEncryptMsg: 加密后的可以直接回复用户的密文包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,
// 当return返回0时有效
// return成功0失败返回对应的错误码
public int EncryptMsg(string sReplyMsg, string sTimeStamp, string sNonce, ref string sEncryptMsg)
{
if (m_sEncodingAESKey.Length!=43)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_IllegalAesKey;
}
string raw = "";
try
{
raw= Cryptography.AES_encrypt(sReplyMsg, m_sEncodingAESKey, m_sAppID);
//raw = SecurityHelper.AESEncrypt(sReplyMsg, m_sEncodingAESKey);
}
catch (Exception)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_EncryptAES_Error;
}
string MsgSigature = "";
int ret = 0;
ret = GenarateSinature(m_sToken, sTimeStamp, sNonce, raw, ref MsgSigature);
if (0 != ret)
return ret;
sEncryptMsg = "";
string EncryptLabelHead = "<Encrypt><![CDATA[";
string EncryptLabelTail = "]]></Encrypt>";
string MsgSigLabelHead = "<MsgSignature><![CDATA[";
string MsgSigLabelTail = "]]></MsgSignature>";
string TimeStampLabelHead = "<TimeStamp><![CDATA[";
string TimeStampLabelTail = "]]></TimeStamp>";
string NonceLabelHead = "<Nonce><![CDATA[";
string NonceLabelTail = "]]></Nonce>";
sEncryptMsg = sEncryptMsg + "<xml>" + EncryptLabelHead + raw + EncryptLabelTail;
sEncryptMsg = sEncryptMsg + MsgSigLabelHead + MsgSigature + MsgSigLabelTail;
sEncryptMsg = sEncryptMsg + TimeStampLabelHead + sTimeStamp + TimeStampLabelTail;
sEncryptMsg = sEncryptMsg + NonceLabelHead + sNonce + NonceLabelTail;
sEncryptMsg += "</xml>";
return 0;
}
public class DictionarySort : System.Collections.IComparer
{
public int Compare(object oLeft, object oRight)
{
string sLeft = oLeft as string;
string sRight = oRight as string;
int iLeftLength = sLeft.Length;
int iRightLength = sRight.Length;
int index = 0;
while (index < iLeftLength && index < iRightLength)
{
if (sLeft[index] < sRight[index])
return -1;
else if (sLeft[index] > sRight[index])
return 1;
else
index++;
}
return iLeftLength - iRightLength;
}
}
//Verify Signature
public static int VerifySignature(string sToken, string sTimeStamp, string sNonce, string sMsgEncrypt, string sSigture)
{
string hash = "";
int ret = 0;
ret = GenarateSinature(sToken, sTimeStamp, sNonce, sMsgEncrypt, ref hash);
if (ret != 0)
return ret;
//System.Console.WriteLine(hash);
if (hash == sSigture)
return 0;
else
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_ValidateSignature_Error;
}
}
public static int GenarateSinature(string sToken, string sTimeStamp, string sNonce, string sMsgEncrypt ,ref string sMsgSignature)
{
ArrayList AL = new ArrayList();
AL.Add(sToken);
AL.Add(sTimeStamp);
AL.Add(sNonce);
AL.Add(sMsgEncrypt);
AL.Sort(new DictionarySort());
string raw = "";
for (int i = 0; i < AL.Count; ++i)
{
raw += AL[i];
}
SHA1 sha;
ASCIIEncoding enc;
string hash = "";
try
{
sha = new SHA1CryptoServiceProvider();
enc = new ASCIIEncoding();
byte[] dataToHash = enc.GetBytes(raw);
byte[] dataHashed = sha.ComputeHash(dataToHash);
hash = BitConverter.ToString(dataHashed).Replace("-", "");
hash = hash.ToLower();
}
catch (Exception)
{
return (int)WXBizMsgCryptErrorCode.WXBizMsgCrypt_ComputeSignature_Error;
}
sMsgSignature = hash;
return 0;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwConfigExceptions="true"
internalLogLevel="Info"
internalLogToTrace="true">
<targets>
<target xsi:type="Null" name="blackhole" />
<target name="LOG_FILE"
xsi:type="File"
layout="[${longdate}] ${pad:padding=-5:inner=${level:uppercase=true}}${newline}${message}${newline}"
encoding="utf-8"
fileName="Logs/${date:format=yyyyMMdd}/${filesystem-normalize:inner=${level}}.log" />
</targets>
<rules>
<logger name="UserLog" minlevel="Trace" writeTo="LOG_FILE" />
</rules>
</nlog>

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwConfigExceptions="true"
internalLogLevel="Info"
internalLogToTrace="true">
<targets>
<target xsi:type="Null" name="blackhole" />
<target name="LOG_FILE"
xsi:type="File"
layout="[${longdate}] ${pad:padding=-5:inner=${level:uppercase=true}}${newline}${message}${newline}"
encoding="utf-8"
fileName="Logs/${date:format=yyyyMMdd}/${filesystem-normalize:inner=${level}}.log" />
</targets>
<rules>
<logger name="UserLog" minlevel="Trace" writeTo="LOG_FILE" />
</rules>
</nlog>

View File

@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]

View File

@@ -1,16 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 由 MSBuild WriteCodeFragment 类生成。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("WxApi")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("WxApi")]
[assembly: System.Reflection.AssemblyTitleAttribute("WxApi")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +0,0 @@
50ee643c1be81eee3d2a3b0e57b12fc7c62301f4

View File

@@ -1 +0,0 @@
6b3f33715abe0269f77cd40383ea936f6217a6a6

View File

@@ -1,26 +0,0 @@
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\nlog.config
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.deps.json
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.dll
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.pdb
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\Hncore.Infrastructure.dll
D:\test\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\Hncore.Infrastructure.pdb
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csprojAssemblyReference.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csproj.CoreCompileInputs.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.AssemblyInfoInputs.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.AssemblyInfo.cs
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csproj.CopyComplete
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.dll
D:\test\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\nlog.config
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.deps.json
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.dll
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\Hncore.Infrastructure.dll
D:\www\juipnet\Infrastructure\WxApi\bin\Debug\netstandard2.0\Hncore.Infrastructure.pdb
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csproj.CoreCompileInputs.cache
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.AssemblyInfoInputs.cache
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.AssemblyInfo.cs
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csproj.CopyComplete
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.dll
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\obj\Debug\netstandard2.0\WxApi.csprojAssemblyReference.cache

View File

@@ -1,16 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 由 MSBuild WriteCodeFragment 类生成。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("WxApi")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("WxApi")]
[assembly: System.Reflection.AssemblyTitleAttribute("WxApi")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +0,0 @@
b4f297fc92d883d4bae5398abea18832d9d585d3

View File

@@ -1 +0,0 @@
d40c72a01d234d5033f74afbe587ff310d84227b

View File

@@ -1,26 +0,0 @@
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\nlog.config
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.deps.json
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.dll
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.pdb
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\Hncore.Infrastructure.dll
D:\test\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\Hncore.Infrastructure.pdb
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csprojAssemblyReference.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csproj.CoreCompileInputs.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.AssemblyInfoInputs.cache
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.AssemblyInfo.cs
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csproj.CopyComplete
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.dll
D:\test\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\nlog.config
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.deps.json
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.dll
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\Hncore.Infrastructure.dll
D:\www\juipnet\Infrastructure\WxApi\bin\Release\netstandard2.0\Hncore.Infrastructure.pdb
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csproj.CoreCompileInputs.cache
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.AssemblyInfoInputs.cache
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.AssemblyInfo.cs
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csproj.CopyComplete
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.dll
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.pdb
D:\www\juipnet\Infrastructure\WxApi\obj\Release\netstandard2.0\WxApi.csprojAssemblyReference.cache

Some files were not shown because too many files have changed in this diff Show More