忽略dll文件git
This commit is contained in:
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class MessageHandler
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Etor.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// 从微信推送的消息内拉取ticket
|
||||
/// </summary>
|
||||
public class GetComponentVerifyTicketRequest
|
||||
{
|
||||
public string TicketSourceServerUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Etor.Wx.Open
|
||||
{
|
||||
public class GetSavedAuthorizerInfoRequest
|
||||
{
|
||||
public string DomainUrl { get; set; }
|
||||
public string AppId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Etor.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取wechat推送的ticket
|
||||
/// </summary>
|
||||
public class GetWechatTicketRequest
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class SaveWechatAppMenuRequest
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Etor.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新微信推送的票据
|
||||
/// </summary>
|
||||
public class UpdateWechatTicketRequest
|
||||
{
|
||||
public string NewTicket { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Etor.Wx.Open
|
||||
{
|
||||
public class UploadWxMediaRequest
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class GetAuthenticationUrlResponse : ResponseBase
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class GetAuthorizerClientUserOpenIdResponse : ResponseBase
|
||||
{
|
||||
public wechat_access_token AccessToken { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="GetComponentVerifyTicketRequest"/>
|
||||
/// </summary>
|
||||
public class GetComponentVerifyTicketResponse:ResponseBase
|
||||
{
|
||||
public string ComponentVerifyTicket { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class GetSavedAuthorizerInfoResponse:ResponseBase
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class GetTemplateResponse : ResponseBase
|
||||
{
|
||||
public string template_id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref=" GetWechatTicketRequest"/>
|
||||
/// </summary>
|
||||
public class GetWechatTicketResponse:ResponseBase
|
||||
{
|
||||
public string Ticket { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class SaveAuthorizerInfoResponse : ResponseBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
public class SaveWechatAppMenuResponse : ResponseBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Hncore.Wx.Open
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref=" UpdateWechatTicketRequest"/>
|
||||
/// </summary>
|
||||
public class UpdateWechatTicketResponse : ResponseBase
|
||||
{
|
||||
public UpdateWechatTicketResponse() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}";
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
|
||||
@@ -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")]
|
||||
@@ -1 +0,0 @@
|
||||
50ee643c1be81eee3d2a3b0e57b12fc7c62301f4
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
6b3f33715abe0269f77cd40383ea936f6217a6a6
|
||||
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
@@ -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")]
|
||||
@@ -1 +0,0 @@
|
||||
b4f297fc92d883d4bae5398abea18832d9d585d3
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
d40c72a01d234d5033f74afbe587ff310d84227b
|
||||
@@ -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
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user