diff --git a/dp2weixin.service/ApiResult.cs b/dp2Command.Server/ApiResult.cs similarity index 94% rename from dp2weixin.service/ApiResult.cs rename to dp2Command.Server/ApiResult.cs index bd72b31d..89536537 100644 --- a/dp2weixin.service/ApiResult.cs +++ b/dp2Command.Server/ApiResult.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace dp2weixin.service +namespace dp2Command.Service { // API返回结果 public class ApiResult diff --git a/dp2Command.Server/MsgQueue.cs b/dp2Command.Server/MsgQueue.cs deleted file mode 100644 index 43449e7b..00000000 --- a/dp2Command.Server/MsgQueue.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dp2Command.Service -{ - public class MsgQueue:Queue - { - /* - /// - /// 处理过的消息队列,用于消息查重 - /// - private Queue msgQueue = new Queue(); - - /// - /// 查重,检查消息是否已经处理过 - /// - /// - public bool Contains(string msgId) - { - return msgQueue.Contains(msgId); - } - */ - /// - /// 把处理过的消息加到队列里 - /// - /// - public void AddMsgToQueue(string msgId) - { - // todo 如果队列超过100,删除100前面的 - if (this.Count > 5) - { - while (this.Count == 5) - { - this.Dequeue(); - } - } - - //加到队列 - this.Enqueue(msgId); - } - } -} diff --git a/dp2Command.Server/WxMsgThread.cs b/dp2Command.Server/WxMsgThread.cs deleted file mode 100644 index d3041c9e..00000000 --- a/dp2Command.Server/WxMsgThread.cs +++ /dev/null @@ -1,33 +0,0 @@ -using DigitalPlatform; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace dp2Command.Service -{ - - /// - /// 用于搜集 dp2library 通知消息并发送给 dp2mserver 的线程 - /// - public class WxMsgThread : ThreadBase - { - public dp2CmdService2 Container = null; - - public WxMsgThread() - { - this.PerTime = 60 * 1000; - } - - // 工作线程每一轮循环的实质性工作 - public override void Worker() - { - if (this.Stopped == true) - return; - - Container.DoLoadMessage(); - } - } - -} diff --git a/dp2Command.Server/delete.txt b/dp2Command.Server/delete.txt new file mode 100644 index 00000000..ad0ff18c --- /dev/null +++ b/dp2Command.Server/delete.txt @@ -0,0 +1,512 @@ + #region 消息处理 + + // 被1分钟轮循一次的工作线程调用 + public async void DoLoadMessage() + { + string strGroupName = "_patronNotify";//""; + + string strError = ""; + var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); + + CancellationToken cancel_token = new CancellationToken(); + string id = Guid.NewGuid().ToString(); + GetMessageRequest request = new GetMessageRequest(id, + "", + strGroupName, // "" 表示默认群组 + "", + "", + 0, + -1); + try + { + MessageConnection connection = await this._channels.GetConnectionAsync( + this.dp2MServerUrl, + this.userName); //todo这里用本方还是远方的账号,好像都可以,主要是确定在patronNotify + MessageResult result = await connection.GetMessageAsync( + request, + OutputMessage, + new TimeSpan(0, 1, 0), + cancel_token); + } + catch (AggregateException ex) + { + strError = MessageConnection.GetExceptionText(ex); + goto ERROR1; + } + catch (Exception ex) + { + strError = ex.Message; + goto ERROR1; + } + return; + + ERROR1: + + this.WriteErrorLog(strError); + //CustomApi.SendText(accessToken, openId, "error"); + + } + + void OutputMessage(long totalCount, + long start, + IList records, + string errorInfo, + string errorCode) + { + if (totalCount == -1) // todo 什么情况下-1 + { + StringBuilder text = new StringBuilder(); + text.Append("***\r\n"); + text.Append("totalCount=" + totalCount + "\r\n"); + text.Append("errorInfo=" + errorInfo + "\r\n"); + text.Append("errorCode=" + errorCode + "\r\n"); + this.WriteErrorLog(text.ToString()); + return; + } + + if (records != null && records.Count>0) + { + DoMessage(records); + } + } + + //已处理过的消息队列 + MsgQueue msgQueue = new MsgQueue(); + + // 处理消息锁 + private object msgLocker = new object(); + + /// + /// 实际处理通知消息 + /// + /// + private void DoMessage(IList records) + { + // getMessage与addMessage得到消息,都会走到处理消息的里,加锁让2个线程排队 + lock (msgLocker) + { + try + { + if (records == null || records.Count == 0) + return; + + List delIds = new List(); + foreach (MessageRecord record in records) + { + // 从已处理消息队列里查重,如果是前面处理过的,则不再处理 + bool bSended = this.msgQueue.Contains(record.id); + if (bSended == true) + continue; + + bool bPatronNotifyGroup = this.CheckIsNotifyGroup(record.groups); + if (bPatronNotifyGroup == false) + continue; + + + string id = record.id; + string data = record.data; + string[] group = record.groups; + string create = record.creator; + + + // + // patronNotify + // R0000001@LUID:62637a12-1965-4876-af3a-fc1d3009af8a + // xml + // ... + // + XmlDocument dataDom = new XmlDocument(); + try + { + dataDom.LoadXml(data); + } + catch (Exception ex) + { + throw new Exception("加载消息返回的data到xml出错:" + ex.Message); + } + + XmlNode nodeType = dataDom.DocumentElement.SelectSingleNode("type"); + if (nodeType == null) + continue; + + string type = DomUtil.GetNodeText(nodeType); + if (type != "patronNotify") //只处理通知消息 + continue; + + XmlNode nodeBody = dataDom.DocumentElement.SelectSingleNode("body"); + if (nodeBody == null) + throw new Exception("返回的data中不存在body节点"); + + /* + body元素里面是预约到书通知记录(注意这是一个字符串,需要另行装入一个XmlDocument解析),其格式如下: + + + 预约到书通知 + 0000001 + + /book.aspx?barcode=0000001 + 2天 + 2016/5/17 10:10:59 + 船舶柴油机 / 聂云超主编. -- ISBN 7-... + 张三 + + R0000001 + 本科生 + 张三 + be13ecc5-6a9c-4400-9453-a072c50cede1 + 数学系 +
address
+ C12345 + 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76 + email:xietao@dp2003.com,weixinid:testwx2 + 13641016400 + 1234567890123 +
+
0) + { + string strError = ""; + int nRet = this.DeleteMessage(delIds, out strError); + if (nRet == -1) + throw new Exception(strError); + } + } + catch (Exception ex) + { + this.WriteErrorLog(ex.Message); + } + } + } + + /// + /// 检查是否属于通知组的消息 + /// + /// + /// + private bool CheckIsNotifyGroup(string[] array) + { + foreach (string s in array) + { + if (s == "_patronNotify" || s == "gn:_patronNotify") + return true; + } + + return false; + } + + /// + /// 删除消息 + /// + /// + /// + /// + int DeleteMessage(List idList, out string strError) + { + strError = ""; + if (idList.Count == 0) + return 0; + + string strGroupName = "gn:_patronNotify"; + + List records = new List(); + for (int i = 0; i < idList.Count; i++) + { + if (idList[i].Trim() == "") + continue; + + MessageRecord record = new MessageRecord(); + record.groups = strGroupName.Split(new char[] { ',' }); + record.id = idList[i].Trim(); + records.Add(record); + } + + SetMessageRequest param = new SetMessageRequest("delete", + "", + records); + + try + { + MessageConnection connection = this._channels.GetConnectionAsync( + this.dp2MServerUrl, + "").Result; + + SetMessageResult result = connection.SetMessageAsync(param).Result; + if (result.Value == -1) + { + strError = result.ErrorInfo; + return -1; + } + + return 0; + } + catch (AggregateException ex) + { + strError = MessageConnection.GetExceptionText(ex); + goto ERROR1; + } + catch (Exception ex) + { + strError = ex.Message; + goto ERROR1; + } + + ERROR1: + return -1; + } + + /// + /// 发送预约通知 + /// + /// + public void SendArrived(XmlDocument bodyDom) + { + /* + body元素里面是预约到书通知记录(注意这是一个字符串,需要另行装入一个XmlDocument解析),其格式如下: + + + 预约到书通知 + 0000001 + + /book.aspx?barcode=0000001 + 2天 + 2016/5/17 10:10:59 + 船舶柴油机 / 聂云超主编. -- ISBN 7-... + 张三 + + R0000001 + 本科生 + 张三 + be13ecc5-6a9c-4400-9453-a072c50cede1 + 数学系 +
address
+ C12345 + 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76 + email:xietao@dp2003.com,weixinid:testwx2 + 13641016400 + 1234567890123 +
+
2天 + // 2016/5/17 10:10:59 + // 取出预约消息 + XmlNode nodeSummary = root.SelectSingleNode("summary"); + if (nodeSummary == null) + throw new Exception("尚未定义节点"); + string summary = DomUtil.GetNodeText(nodeSummary); + + XmlNode nodeReserveTime = root.SelectSingleNode("reserveTime"); + if (nodeReserveTime == null) + throw new Exception("尚未定义节点"); + string reserveTime = DomUtil.GetNodeText(nodeReserveTime); + + XmlNode nodeToday = root.SelectSingleNode("today"); + if (nodeToday == null) + throw new Exception("尚未定义节点"); + string today = DomUtil.GetNodeText(nodeToday); + + string patronName = ""; + List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName); + foreach (string weiXinId in weiXinIdList) + { + var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); + + //{{first.DATA}} + //图书书名:{{keyword1.DATA}} + //到书日期:{{keyword2.DATA}} + //保留期限:{{keyword3.DATA}} + //{{remark.DATA}} + var msgData = new ArrivedTemplateData() + { + first = new TemplateDataItem("尊敬的读者:您预约的图书已经到书,请尽快来图书馆办理借书手续。", "#000000"), + keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"), + keyword2 = new TemplateDataItem(today, "#000000"), + keyword3 = new TemplateDataItem("保留" + reserveTime, "#000000"), + remark = new TemplateDataItem("\n如果您未能在保留期限内来馆办理借阅手续,图书馆将把优先借阅权转给后面排队等待的预约者,或做归架处理。", "#CCCCCC") + }; + + // 发送预约模板消息 + //string detailUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx57aa3682c59d16c2&redirect_uri=http%3a%2f%2fdp2003.com%2fdp2weixin%2fPatron%2fIndex&response_type=code&scope=snsapi_base&state=dp2weixin#wechat_redirect"; + var result1 = TemplateApi.SendTemplateMessage(accessToken, + weiXinId, + dp2CmdService2.C_Template_Arrived, + "#FF0000", + "",//不出现详细了 + msgData); + } + } + + /// + /// 发送超期通知 + /// + /// + public void SendCaoQi(XmlDocument bodyDom) + { + /* + + 超期通知 + + + + 您借阅的下列书刊: +船舶柴油机 / 聂云超主编. -- ISBN 7-... 应还日期: 2016/5/18 已超期 31 天 + + ... + + + + */ + + // 得到绑定的微信id + string patronName = ""; + List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName); + if (weiXinIdList.Count == 0) + return; + + XmlNode root = bodyDom.DocumentElement; + + // 取出册列表 + XmlNode nodeItems = root.SelectSingleNode("items"); + string overdueCount = DomUtil.GetAttr(nodeItems, "overdueCount"); + + XmlNodeList nodeList = nodeItems.SelectNodes("item"); + // 一册一个通知 + foreach (XmlNode item in nodeList) + { + string summary = DomUtil.GetAttr(item, "summary"); + string timeReturning = DomUtil.GetAttr(item, "timeReturning"); + string overdue = DomUtil.GetAttr(item, "overdue"); + + + foreach (string weiXinId in weiXinIdList) + { + var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); + + //{{first.DATA}} + //图书书名:{{keyword1.DATA}} + //应还日期:{{keyword2.DATA}} + //超期天数:{{keyword3.DATA}} + //{{remark.DATA}} + var msgData = new ArrivedTemplateData() + { + first = new TemplateDataItem("尊敬的" + patronName + " 您好!您借阅的图书已超期,请尽快归还。", "#000000"), + keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"), + keyword2 = new TemplateDataItem(timeReturning, "#000000"), + keyword3 = new TemplateDataItem(overdue, "#000000"), + remark = new TemplateDataItem("\n点击下方”详情“查看个人详细信息。", "#CCCCCC") + }; + + string detailUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx57aa3682c59d16c2&redirect_uri=http%3a%2f%2fdp2003.com%2fdp2weixin%2fPatron%2fIndex&response_type=code&scope=snsapi_base&state=dp2weixin#wechat_redirect"; + var result1 = TemplateApi.SendTemplateMessage(accessToken, + weiXinId, + dp2CmdService2.C_Template_CaoQi, + "#FF0000", + detailUrl,//不出现详细了 + msgData); + if (result1.errcode != 0) + throw new Exception(result1.errmsg); + } + } + } + + /// + /// 获取读者记录中绑定的微信id,返回数组 + /// + /// + /// + /// + public List GetWeiXinIds(XmlDocument bodyDom, out string patronName) + { + patronName = ""; + + XmlNode root = bodyDom.DocumentElement; + XmlNode patronRecordNode = root.SelectSingleNode("patronRecord"); + if (patronRecordNode == null) + throw new Exception("尚未定义节点"); + patronName = DomUtil.GetNodeText(patronRecordNode.SelectSingleNode("name")); + XmlNode emailNode = patronRecordNode.SelectSingleNode("email"); + if (emailNode == null) + throw new Exception("尚未定义节点"); + string email = DomUtil.GetNodeText(emailNode); + //test@163.com,123,weixinid:o4xvUviTxj2HbRqbQb9W2nMl4fGg,weixinid:o4xvUvnLTg6NnflbYdcS-sxJCGFo,weixinid:testid + string[] emailList = email.Split(new char[] { ',' }); + List weiXinIdList = new List(); + for (int i = 0; i < emailList.Length; i++) + { + string oneEmail = emailList[i].Trim(); + if (oneEmail.Length > 9 && oneEmail.Substring(0, 9) == dp2CommandUtility.C_WeiXinIdPrefix) + { + string weiwinId = oneEmail.Substring(9).Trim(); + if (weiwinId != "") + weiXinIdList.Add(weiwinId); + } + } + return weiXinIdList; + } + + + /// + /// 绑定的消息事件 + /// + /// + /// + void _channels_AddMessage(object sender, AddMessageEventArgs e) + { + if (e.Action != "create") + { + return; + } + + if (e.Records != null) + { + DoMessage(e.Records); + } + } + + #endregion \ No newline at end of file diff --git a/dp2Command.Server/dp2CmdService2.cs b/dp2Command.Server/dp2CmdService2.cs index d82650a4..072a85cd 100644 --- a/dp2Command.Server/dp2CmdService2.cs +++ b/dp2Command.Server/dp2CmdService2.cs @@ -34,7 +34,14 @@ public class dp2CmdService2 : dp2BaseCommandService - MessageConnectionCollection _channels = new MessageConnectionCollection(); + MessageConnectionCollection _channels = new MessageConnectionCollection(); + public MessageConnectionCollection Channels + { + get + { + return this._channels; + } + } // 配置文件 public string _cfgFile = ""; @@ -51,7 +58,8 @@ public class dp2CmdService2 : dp2BaseCommandService // 背景图管理器 public string TodayUrl = ""; - WxMsgThread _wxMsgThread = null; + // dp2消息处理类 + private dp2MsgHandler _dp2MsgHandler = null; //================= // 设为单一实例 @@ -134,14 +142,11 @@ public void Init(string dataDir) //全局只需注册一次 AccessTokenContainer.Register(this.weiXinAppId, this.weiXinSecret); - _channels.Login += _channels_Login; - _channels.AddMessage += _channels_AddMessage; - // 启一个线程取消息 - this._wxMsgThread = new WxMsgThread(); - this._wxMsgThread.Container = this; - this._wxMsgThread.BeginThread(); // TODO: 应该在 MessagWorkereConnection 第一次连接成功以后,再启动这个线程比较好 + // dp2消息处理类 + this._dp2MsgHandler = new dp2MsgHandler(this._channels, this.dp2MServerUrl, this.weiXinAppId); + } #region 短信接口 @@ -270,519 +275,7 @@ string GetPassword() #endregion - #region 消息处理 - - // 被1分钟轮循一次的工作线程调用 - public async void DoLoadMessage() - { - string strGroupName = "_patronNotify";//""; - - string strError = ""; - var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); - - CancellationToken cancel_token = new CancellationToken(); - string id = Guid.NewGuid().ToString(); - GetMessageRequest request = new GetMessageRequest(id, - "", - strGroupName, // "" 表示默认群组 - "", - "", - 0, - -1); - try - { - MessageConnection connection = await this._channels.GetConnectionAsync( - this.dp2MServerUrl, - this.userName); //todo这里用本方还是远方的账号,好像都可以,主要是确定在patronNotify - MessageResult result = await connection.GetMessageAsync( - request, - OutputMessage, - new TimeSpan(0, 1, 0), - cancel_token); - } - catch (AggregateException ex) - { - strError = MessageConnection.GetExceptionText(ex); - goto ERROR1; - } - catch (Exception ex) - { - strError = ex.Message; - goto ERROR1; - } - return; - - ERROR1: - - this.WriteErrorLog(strError); - //CustomApi.SendText(accessToken, openId, "error"); - - } - - void OutputMessage(long totalCount, - long start, - IList records, - string errorInfo, - string errorCode) - { - if (totalCount == -1) // todo 什么情况下-1 - { - StringBuilder text = new StringBuilder(); - text.Append("***\r\n"); - text.Append("totalCount=" + totalCount + "\r\n"); - text.Append("errorInfo=" + errorInfo + "\r\n"); - text.Append("errorCode=" + errorCode + "\r\n"); - this.WriteErrorLog(text.ToString()); - return; - } - - if (records != null && records.Count>0) - { - DoMessage(records); - } - } - - //已处理过的消息队列 - MsgQueue msgQueue = new MsgQueue(); - // 处理消息锁 - private object msgLocker = new object(); - - /// - /// 实际处理通知消息 - /// - /// - private void DoMessage(IList records) - { - // getMessage与addMessage得到消息,都会走到处理消息的里,加锁让2个线程排队 - lock (msgLocker) - { - try - { - if (records == null || records.Count == 0) - return; - - List delIds = new List(); - foreach (MessageRecord record in records) - { - // 从已处理消息队列里查重,如果是前面处理过的,则不再处理 - bool bSended = this.msgQueue.Contains(record.id); - if (bSended == true) - continue; - - bool bPatronNotifyGroup = this.CheckIsNotifyGroup(record.groups); - if (bPatronNotifyGroup == false) - continue; - - - string id = record.id; - string data = record.data; - string[] group = record.groups; - string create = record.creator; - - - // - // patronNotify - // R0000001@LUID:62637a12-1965-4876-af3a-fc1d3009af8a - // xml - // ... - // - XmlDocument dataDom = new XmlDocument(); - try - { - dataDom.LoadXml(data); - } - catch (Exception ex) - { - throw new Exception("加载消息返回的data到xml出错:" + ex.Message); - } - - XmlNode nodeType = dataDom.DocumentElement.SelectSingleNode("type"); - if (nodeType == null) - continue; - - string type = DomUtil.GetNodeText(nodeType); - if (type != "patronNotify") //只处理通知消息 - continue; - - XmlNode nodeBody = dataDom.DocumentElement.SelectSingleNode("body"); - if (nodeBody == null) - throw new Exception("返回的data中不存在body节点"); - - /* - body元素里面是预约到书通知记录(注意这是一个字符串,需要另行装入一个XmlDocument解析),其格式如下: - - - 预约到书通知 - 0000001 - - /book.aspx?barcode=0000001 - 2天 - 2016/5/17 10:10:59 - 船舶柴油机 / 聂云超主编. -- ISBN 7-... - 张三 - - R0000001 - 本科生 - 张三 - be13ecc5-6a9c-4400-9453-a072c50cede1 - 数学系 -
address
- C12345 - 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76 - email:xietao@dp2003.com,weixinid:testwx2 - 13641016400 - 1234567890123 -
-
0) - { - string strError = ""; - int nRet = this.DeleteMessage(delIds, out strError); - if (nRet == -1) - throw new Exception(strError); - } - } - catch (Exception ex) - { - this.WriteErrorLog(ex.Message); - } - } - - } - - /// - /// 检查是否属于通知组的消息 - /// - /// - /// - private bool CheckIsNotifyGroup(string[] array) - { - foreach (string s in array) - { - if (s == "_patronNotify" || s == "gn:_patronNotify") - return true; - } - - return false; - } - - /// - /// 删除消息 - /// - /// - /// - /// - int DeleteMessage(List idList, out string strError) - { - strError = ""; - if (idList.Count == 0) - return 0; - - string strGroupName = "gn:_patronNotify"; - - List records = new List(); - for (int i = 0; i < idList.Count; i++) - { - if (idList[i].Trim() == "") - continue; - - MessageRecord record = new MessageRecord(); - record.groups = strGroupName.Split(new char[] { ',' }); - record.id = idList[i].Trim(); - records.Add(record); - } - - SetMessageRequest param = new SetMessageRequest("delete", - "", - records); - - try - { - MessageConnection connection = this._channels.GetConnectionAsync( - this.dp2MServerUrl, - "").Result; - - SetMessageResult result = connection.SetMessageAsync(param).Result; - if (result.Value == -1) - { - strError = result.ErrorInfo; - return -1; - } - - return 0; - } - catch (AggregateException ex) - { - strError = MessageConnection.GetExceptionText(ex); - goto ERROR1; - } - catch (Exception ex) - { - strError = ex.Message; - goto ERROR1; - } - - ERROR1: - return -1; - } - - /// - /// 发送预约通知 - /// - /// - public void SendArrived(XmlDocument bodyDom) - { - /* - body元素里面是预约到书通知记录(注意这是一个字符串,需要另行装入一个XmlDocument解析),其格式如下: - - - 预约到书通知 - 0000001 - - /book.aspx?barcode=0000001 - 2天 - 2016/5/17 10:10:59 - 船舶柴油机 / 聂云超主编. -- ISBN 7-... - 张三 - - R0000001 - 本科生 - 张三 - be13ecc5-6a9c-4400-9453-a072c50cede1 - 数学系 -
address
- C12345 - 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76 - email:xietao@dp2003.com,weixinid:testwx2 - 13641016400 - 1234567890123 -
-
2天
- // 2016/5/17 10:10:59 - // 取出预约消息 - XmlNode nodeSummary = root.SelectSingleNode("summary"); - if (nodeSummary == null) - throw new Exception("尚未定义节点"); - string summary = DomUtil.GetNodeText(nodeSummary); - - XmlNode nodeReserveTime = root.SelectSingleNode("reserveTime"); - if (nodeReserveTime == null) - throw new Exception("尚未定义节点"); - string reserveTime = DomUtil.GetNodeText(nodeReserveTime); - - XmlNode nodeToday = root.SelectSingleNode("today"); - if (nodeToday == null) - throw new Exception("尚未定义节点"); - string today = DomUtil.GetNodeText(nodeToday); - - string patronName = ""; - List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName); - foreach (string weiXinId in weiXinIdList) - { - var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); - - //{{first.DATA}} - //图书书名:{{keyword1.DATA}} - //到书日期:{{keyword2.DATA}} - //保留期限:{{keyword3.DATA}} - //{{remark.DATA}} - var msgData = new ArrivedTemplateData() - { - first = new TemplateDataItem("尊敬的读者:您预约的图书已经到书,请尽快来图书馆办理借书手续。", "#000000"), - keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"), - keyword2 = new TemplateDataItem(today, "#000000"), - keyword3 = new TemplateDataItem("保留" + reserveTime, "#000000"), - remark = new TemplateDataItem("\n如果您未能在保留期限内来馆办理借阅手续,图书馆将把优先借阅权转给后面排队等待的预约者,或做归架处理。", "#CCCCCC") - }; - - // 发送预约模板消息 - //string detailUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx57aa3682c59d16c2&redirect_uri=http%3a%2f%2fdp2003.com%2fdp2weixin%2fPatron%2fIndex&response_type=code&scope=snsapi_base&state=dp2weixin#wechat_redirect"; - var result1 = TemplateApi.SendTemplateMessage(accessToken, - weiXinId, - dp2CmdService2.C_Template_Arrived, - "#FF0000", - "",//不出现详细了 - msgData); - } - } - - /// - /// 发送超期通知 - /// - /// - public void SendCaoQi(XmlDocument bodyDom) - { - /* - - 超期通知 - - - - 您借阅的下列书刊: -船舶柴油机 / 聂云超主编. -- ISBN 7-... 应还日期: 2016/5/18 已超期 31 天 - - ... - - - - */ - - // 得到绑定的微信id - string patronName = ""; - List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName); - if (weiXinIdList.Count == 0) - return; - - XmlNode root = bodyDom.DocumentElement; - - // 取出册列表 - XmlNode nodeItems = root.SelectSingleNode("items"); - string overdueCount = DomUtil.GetAttr(nodeItems, "overdueCount"); - - XmlNodeList nodeList = nodeItems.SelectNodes("item"); - // 一册一个通知 - foreach (XmlNode item in nodeList) - { - string summary = DomUtil.GetAttr(item, "summary"); - string timeReturning = DomUtil.GetAttr(item, "timeReturning"); - string overdue = DomUtil.GetAttr(item, "overdue"); - - - foreach (string weiXinId in weiXinIdList) - { - var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId); - - //{{first.DATA}} - //图书书名:{{keyword1.DATA}} - //应还日期:{{keyword2.DATA}} - //超期天数:{{keyword3.DATA}} - //{{remark.DATA}} - var msgData = new ArrivedTemplateData() - { - first = new TemplateDataItem("尊敬的" + patronName + " 您好!您借阅的图书已超期,请尽快归还。", "#000000"), - keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"), - keyword2 = new TemplateDataItem(timeReturning, "#000000"), - keyword3 = new TemplateDataItem(overdue, "#000000"), - remark = new TemplateDataItem("\n点击下方”详情“查看个人详细信息。", "#CCCCCC") - }; - - string detailUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx57aa3682c59d16c2&redirect_uri=http%3a%2f%2fdp2003.com%2fdp2weixin%2fPatron%2fIndex&response_type=code&scope=snsapi_base&state=dp2weixin#wechat_redirect"; - var result1 = TemplateApi.SendTemplateMessage(accessToken, - weiXinId, - dp2CmdService2.C_Template_CaoQi, - "#FF0000", - detailUrl,//不出现详细了 - msgData); - if (result1.errcode != 0) - throw new Exception(result1.errmsg); - } - } - } - - /// - /// 获取读者记录中绑定的微信id,返回数组 - /// - /// - /// - /// - public List GetWeiXinIds(XmlDocument bodyDom, out string patronName) - { - patronName = ""; - - XmlNode root = bodyDom.DocumentElement; - XmlNode patronRecordNode = root.SelectSingleNode("patronRecord"); - if (patronRecordNode == null) - throw new Exception("尚未定义节点"); - patronName = DomUtil.GetNodeText(patronRecordNode.SelectSingleNode("name")); - XmlNode emailNode = patronRecordNode.SelectSingleNode("email"); - if (emailNode == null) - throw new Exception("尚未定义节点"); - string email = DomUtil.GetNodeText(emailNode); - //test@163.com,123,weixinid:o4xvUviTxj2HbRqbQb9W2nMl4fGg,weixinid:o4xvUvnLTg6NnflbYdcS-sxJCGFo,weixinid:testid - string[] emailList = email.Split(new char[] { ',' }); - List weiXinIdList = new List(); - for (int i = 0; i < emailList.Length; i++) - { - string oneEmail = emailList[i].Trim(); - if (oneEmail.Length > 9 && oneEmail.Substring(0, 9) == dp2CommandUtility.C_WeiXinIdPrefix) - { - string weiwinId = oneEmail.Substring(9).Trim(); - if (weiwinId != "") - weiXinIdList.Add(weiwinId); - } - } - return weiXinIdList; - } - - - /// - /// 绑定的消息事件 - /// - /// - /// - void _channels_AddMessage(object sender, AddMessageEventArgs e) - { - if (e.Action != "create") - { - return; - } - - if (e.Records != null) - { - DoMessage(e.Records); - } - } - - #endregion #region 绑定解绑 @@ -2107,4 +1600,6 @@ public void SendCustomerMsg(string openId, string text) } } + + } diff --git a/dp2Command.Server/dp2Command.Service.csproj b/dp2Command.Server/dp2Command.Service.csproj index e56152da..71665d1c 100644 --- a/dp2Command.Server/dp2Command.Service.csproj +++ b/dp2Command.Server/dp2Command.Service.csproj @@ -56,6 +56,7 @@ + @@ -64,12 +65,11 @@ + - - @@ -111,6 +111,9 @@ DigitalPlatform.Xml + + +