using LYFZ.Weixin.SDK; using LYFZ.WXLibrary; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; namespace LYFZ.WeixinServers.WeiXinAPP.Api { /// /// WeiXinService 的摘要说明 /// public class WeiXinService : IHttpHandler { public void ProcessRequest(HttpContext context) { bool bSignature = CheckSignature(context); string temp = ""; if(LYFZ.WXLibrary.CommonHandleClass.MicroLetterEventList.Count==0) { Global.InitializationMicroLetterEventList(); } foreach (string key in LYFZ.WXLibrary.CommonHandleClass.MicroLetterEventList) { if (!string.IsNullOrEmpty(temp)) { temp += "\r\n\t"; } temp += key; } WriteLog(context, temp, "EventList" + DateTime.Now.ToString("yyyyMMddHHmmssffff")); /*string[] keys = context.Request.Form.AllKeys; foreach(string key in keys) { if (!string.IsNullOrEmpty(temp)) { temp += "&"; } temp += key + "=" + context.Request.Form[key]; } WriteLog(context, temp, "Form"+DateTime.Now.ToString("yyyyMMddHHmmssffff")); keys = context.Request.QueryString.AllKeys; foreach (string key in keys) { if (!string.IsNullOrEmpty(temp)) { temp += "&"; } temp += key + "=" + context.Request.QueryString[key]; } WriteLog(context, temp, "QueryString" + DateTime.Now.ToString("yyyyMMddHHmmssffff")); HttpRequest request = context.Request; Stream stream = request.InputStream; string xml = string.Empty; string responseJson = string.Empty; if (stream.Length != 0) { StreamReader streamReader = new StreamReader(stream); xml = streamReader.ReadToEnd(); } WriteLog(context, xml, "Stream" + DateTime.Now.ToString("yyyyMMddHHmmssffff"));*/ if (!string.IsNullOrEmpty(context.Request["echostr"])) { if (bSignature) { Print(context, context.Request["echostr"]); } else { Print(context, "签名检查出现异常!"); } } else { string xml = GetHttpRequestData(context); WriteLog(context, "获取XML:" + xml, DateTime.Now.ToString("ddHHmmss")); var safeMode = context.Request.QueryString.Get("encrypt_type") == "aes"; WeixinMessage wxMessage = MessageSignature(context, safeMode, xml); WriteLog(context, "进入数据操作功能", wxMessage.Body.CreateTime.Value.ToString()); string openId = wxMessage.Body.FromUserName.Value.ToString(); string myUserName = wxMessage.Body.ToUserName.Value.ToString(); if (bSignature) { //GetWeiXinNoticEvent(context); string appid =string.IsNullOrEmpty( context.Request["appid"])?"": context.Request["appid"].ToString().Trim().Trim('/'); WriteLog(context, "进入关键字获取", wxMessage.Body.CreateTime.Value.ToString()); SendMessageDataToWeiXin(wxMessage, appid, context); } else { // Print(context, "签名检查出现异常!"); Print(context, WxMessageControl.TextMessageData(openId, myUserName, "签名检查出现异常!"), "application/x-www-form-urlencoded"); } // Print(context, WxMessageControl.TextMessageData("oA8kg0yGUHE8ivlK_9HH7Pg4wDbA", "gh_0c52155c0592", "信息自动反馈"), "application/x-www-form-urlencoded"); } } public bool GetWeiXinNoticEvent(HttpContext context) { string xml = GetHttpRequestData(context); var safeMode = context.Request.QueryString.Get("encrypt_type") == "aes"; WeixinMessage wxMessage = MessageSignature(context, safeMode, xml); string appid = context.Request["appid"].ToString().Trim().Trim('/'); SendMessageDataToWeiXin(wxMessage, appid, context); /*System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.LoadXml(xml); string ToUserName = doc.DocumentElement.GetElementsByTagName("ToUserName")[0].InnerText; string FromUserName = doc.DocumentElement.GetElementsByTagName("FromUserName")[0].InnerText; string Event = doc.DocumentElement.GetElementsByTagName("Event")[0].InnerText; string EventKey = doc.DocumentElement.GetElementsByTagName("EventKey")[0].InnerText;*/ return true; } void SendMessageDataToWeiXin(WeixinMessage message, string appid, HttpContext context) { string openId = message.Body.FromUserName.Value.ToString(); string myUserName = message.Body.ToUserName.Value.ToString(); string executeData = new LYFZ.WXLibrary.WeixinExecutor().ServiceExecute(message).ToLower().Trim(); WriteLog(context, "获取数据操作关键字数据:" + executeData, message.Body.CreateTime.Value.ToString()); LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel; if (!string.IsNullOrEmpty(appid)) { cusModel = Global.GetCustomerModelByWxAppId(appid); } else { cusModel = Global.GetCustomerModelByWxNumber(myUserName); } string cShellDomainName = ""; string requestUrl = ""; if (cusModel != null && cusModel.ID > 0) { WriteLog(context, "数据集合:" +Newtonsoft.Json.JsonConvert.SerializeObject(cusModel), message.Body.CreateTime.Value.ToString()); if (cusModel.ShellDomainName.Trim().Length > 1) { cShellDomainName = cusModel.ShellDomainName.Trim(); requestUrl = (LYFZ.WXLibrary.CommonHandleClass.GetNetUrl(cShellDomainName, cusModel.PortNumber) + "/WeiXinAPP/Api/WeiXinService.ashx"); } string replayMsg = ""; if (LYFZ.WXLibrary.CommonHandleClass.MicroLetterEventList.Contains(executeData)) { try { System.Data.DataRow[] dataRows = Global.KeywordDaTable.Select("Keyword='" + executeData + "'"); if (dataRows.Length > 0) { executeData = dataRows[0]["FunctionCode"].ToString(); } WriteLog(context, "进入关键字获功能" + executeData, message.Body.CreateTime.Value.ToString()); WeiXinMessageData(message, executeData, appid, cusModel, context); } catch(Exception e) { WriteLog(context, "数据异常" + e.Message, message.Body.CreateTime.Value.ToString()); Print(context, WxMessageControl.TextMessageData(openId, myUserName, "数据异常"), "application/x-www-form-urlencoded"); } } else if (OpenPlatformConfig.IsTransmitService(executeData)) { replayMsg = ReplayPassiveMessageAPI.TransmitService(openId, myUserName); //LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "的信息已转到多客服:" + response, JMGDomainName, Global.LogsDongleDomainList); } else { replayMsg = "";//ReplayPassiveMessageAPI.RepayText(openId, myUserName, "收到的信息:" + response); //LYFZ.WXLibrary.CommonHandleClass.WriteLog("非法指令请求 公众号AppID:" + appid + "对应的加密锁域名:" + cusModel.JMGDomainName + "收到的信息:" + executeData, "-2", Global.LogsDongleDomainList); Print(context, WxMessageControl.TextMessageData(openId, myUserName, "非法指令请求 公众号AppID:" + appid + "对应的加密锁域名:" + cusModel.JMGDomainName + "收到的信息:" + executeData), "application/x-www-form-urlencoded"); } } else { Print(context, WxMessageControl.TextMessageData(openId, myUserName, "无法查询到相应的数据绑定!"), "application/x-www-form-urlencoded"); } } public void WeiXinMessageData(WeixinMessage message, string executeData, string appid, LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { string openId = message.Body.FromUserName.Value.ToString(); //if(message.Body.MsgType=="event"&&message.Body.Event=="CLICK") //{ //string eventKey = message.Body.EventKey; cusModel.ShellDomainName = "http://" + cusModel.ShellDomainName; switch (executeData) { case "AccountBinding": WriteLog(context, "进入绑定账号功能" + executeData, message.Body.CreateTime.Value.ToString()); CheckAccountBinding(openId, cusModel, context); return; // break; case "UserBinding": WriteLog(context, "进入绑定账号功能" + executeData, message.Body.CreateTime.Value.ToString()); CheckUserBinding(openId, cusModel, context); return; // break; case "AccountUnbind": WriteLog(context, "进入解除绑定账号功能" + executeData, message.Body.CreateTime.Value.ToString()); CustomerAccountUnbind(openId, cusModel, context); return; // break; case "OrderQuery": WriteLog(context, "进入订单查询功能" + executeData, message.Body.CreateTime.Value.ToString()); CustomerOrderQuery(openId, cusModel, context); return; // break; case "MemberQuery": WriteLog(context, "进入会员查询功能" + executeData, message.Body.CreateTime.Value.ToString()); CustomerMemberQuery(openId, cusModel, context); return; // break; case "FinancialBriefing": WriteLog(context, "进入今日财务功能" + executeData, message.Body.CreateTime.Value.ToString()); SearchFinanceToday(openId, cusModel, context); return; // break; } //} string myUserName = message.Body.ToUserName.Value.ToString(); WriteLog(context, "进入绑定账号功能" + executeData, message.Body.CreateTime.Value.ToString()); // Print(context, WxMessageControl.TextMessageData(openId, myUserName, "无相应功能进行操作!!"), "application/x-www-form-urlencoded"); Print(context, ""); } private void CheckUserBinding(string openId, WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/CheckWXCustomerAccount?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/CheckWXUserAccount?openid=" + openId); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content=""; if(code.Equals("200")) { content = "账号已绑定,无需重复绑定!"; } else { content = "账号未绑定,需要绑定对账号进行数据绑定!\n绑定账号"; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret,content), "application/x-www-form-urlencoded"); } /// /// 财务数据 /// /// /// /// private void SearchFinanceToday(string openId, WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/SearchFinanceToday?openid=" + openId); WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/SearchFinanceToday?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content = ""; if (code.Equals("200")) { content = jobject.GetValue("data").ToString(); } else { content = "账号绑定解除失败,失败原因:" + jobject.GetValue("data").ToString() + ""; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret, content), "application/x-www-form-urlencoded"); } private void CustomerMemberQuery(string openId, WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/SearchCustomerData?openid=" + openId); WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/SearchCustomerData?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content = ""; if (code.Equals("200")) { Newtonsoft.Json.Linq.JArray array = (Newtonsoft.Json.Linq.JArray)jobject.GetValue("data"); ///发送模板数据 if(array.Count>0) { Newtonsoft.Json.Linq.JObject cusObject = (Newtonsoft.Json.Linq.JObject)array[0]; content += "姓名:"+cusObject.GetValue("持卡人")+"\n"; content += "电话:" + cusObject.GetValue("电话") + "\n"; content += "性别:" + (cusObject.GetValue("性别").ToString() == "0" ? "男" : "女") + "\n"; content += "会员卡号:" + (string.IsNullOrEmpty((string)cusObject.GetValue("会员卡号")) ? "未办理" : (string)cusObject.GetValue("会员卡号")) + "\n"; content += "积分:" + cusObject.GetValue("积分") + "\n"; content += "欠款:" + cusObject.GetValue("欠款") + "\n"; content += "金额:" + cusObject.GetValue("金额") + "\n"; content += "折扣:" + cusObject.GetValue("折扣") + "\n"; } else { content = "当前客户没有数据"; } } else { content = "账号绑定解除失败,失败原因:" + jobject.GetValue("data").ToString() + ""; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret, content), "application/x-www-form-urlencoded"); } void CustomerOrderQuery(string openId, LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/SearchCustomerOrder?openid=" + openId); WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/SearchCustomerOrder?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content = ""; if (code.Equals("200")) { WriteLog(context, "数据" + getText, DateTime.Now.ToString("ddHHmmss")); content = jobject.GetValue("data").ToString(); ///发送模板数据 } else { content = "账号绑定解除失败,失败原因:" + jobject.GetValue("data").ToString() + ""; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret, content), "application/x-www-form-urlencoded"); } void CheckAccountBinding(string openId, LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/CheckWXCustomerAccount?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/CheckWXCustomerAccount?openid=" + openId); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content=""; if(code.Equals("200")) { content = "账号已绑定,无需重复绑定!"; } else { content = "账号未绑定,需要绑定对账号进行数据绑定!\n绑定账号"; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret,content), "application/x-www-form-urlencoded"); } void CustomerAccountUnbind(string openId, LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel, HttpContext context) { string getText = LYFZ.WinAPI.HttpClientHelper.GetResponse(cusModel.ShellDomainName + "/api/WXApi.ashx/UnBindWXCustomerAccount?openid=" + openId+"&type=customer"); WriteLog(context, "数据URL" + cusModel.ShellDomainName + "/api/WXApi.ashx/UnBindWXCustomerAccount?openid=" + openId, DateTime.Now.ToString("ddHHmmss")); Newtonsoft.Json.Linq.JObject jobject = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(getText); string code = jobject.GetValue("code").ToString(); string content = ""; if (code.Equals("200")) { content = "账号绑定已解除"; } else { content = "账号绑定解除失败,失败原因:" + jobject.GetValue("data").ToString() + ""; } Print(context, WxMessageControl.TextMessageData(openId, cusModel.AppSecret, content), "application/x-www-form-urlencoded"); } public WeixinMessage MessageSignature(HttpContext context, bool safeMode, string xml) { WeixinMessage message = null; string signature = context.Request["signature"]; string timestamp = context.Request["timestamp"]; string nonce = context.Request["nonce"]; string decryptMsg = ""; if (safeMode) { var msg_signature = context.Request.QueryString.Get("msg_signature"); var wxBizMsgCrypt = new Tencent.WXBizMsgCrypt(OpenPlatformConfig.OpenToken, OpenPlatformConfig.OpenEncodingAESKey, OpenPlatformConfig.OpenAppID); var ret = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, xml, ref decryptMsg); if (ret != 0)//解密失败 { //TODO:开发者解密失败的业务处理逻辑 LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("新版开放平台接口解密失败,解密消息返回{0},密文为:{1}", ret, xml)); } } else { decryptMsg = xml; } try { message = AcceptMessageAPI.Parse(decryptMsg); } catch { } return message; } public string GetHttpRequestData(HttpContext context) { HttpRequest request = context.Request; Stream stream = request.InputStream; string xml = string.Empty; string responseJson = string.Empty; if (stream.Length != 0) { StreamReader streamReader = new StreamReader(stream); xml = streamReader.ReadToEnd(); } return xml; } /// /// 检查签名 /// /// /// public bool CheckSignature(HttpContext context ) { try { string signature = context.Request["signature"]; string timestamp = context.Request["timestamp"];// yyyyMMddhhmmss string nonce = context.Request["nonce"]; string ent = ""; bool b = LYFZ.Weixin.SDK.BasicAPI.CheckSignature(signature, timestamp, nonce, OpenPlatformConfig.OpenToken, out ent); WriteLog(context, ent, "Ent" + DateTime.Now.ToString("yyyyMMddHHmmssffff")); return b; } catch { } finally { } return false; } public void WriteLog(HttpContext context,string content,string filename="" ) { LYFZ.WXLibrary.CommonHandleClass.WriteLog(content, "-2", Global.LogsDongleDomainList); /* if(string.IsNullOrEmpty(filename)) { filename = DateTime.Now.ToString("yyyyMMddHHmmssffff"); } string dirPath=context.Server.MapPath("/")+"/WeiXinDir/"; if(!System.IO.Directory.Exists(dirPath)) { System.IO.Directory.CreateDirectory(dirPath); } System.IO.File.AppendAllText(dirPath + "/" + filename + ".txt", content+"\r\n"); */ } public void Print(HttpContext context, string content, string ContentType = "text/plain") { context.Response.ContentType = ContentType; context.Response.Write(content); } public bool IsReusable { get { return false; } } } }