diff --git a/dp2-v3.sln b/dp2-v3.sln
index 3f036df5..042eb21f 100644
--- a/dp2-v3.sln
+++ b/dp2-v3.sln
@@ -25,10 +25,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalPlatform.IO", "Digit
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalPlatform.LibraryRestClient", "DigitalPlatform.LibraryRestClient\DigitalPlatform.LibraryRestClient.csproj", "{1B74D69A-530F-4275-845B-8CA6D1463BDD}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dp2Command.Service", "dp2Command.Server\dp2Command.Service.csproj", "{A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dp2weixin", "dp2weixin\dp2weixin.csproj", "{2BD6F79E-A776-4A08-B972-C61F70F78BD5}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ilovelibrary", "ilovelibrary\ilovelibrary.csproj", "{7C31EA17-404D-4CE6-8401-71808BEB5883}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ilovelibrary.Server", "ilovelibrary.Server\ilovelibrary.Server.csproj", "{159E08AE-5C0F-4DA7-9F73-AF07791247CE}"
@@ -47,7 +43,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalPlatform.LibraryClie
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalPlatform.ServiceProcess", "DigitalPlatform.ServiceProcess\DigitalPlatform.ServiceProcess.csproj", "{696B2B7F-D5F6-47AE-8113-C0CD27FAD21E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dp2weixinP2P", "dp2weixinP2P\dp2weixinP2P.csproj", "{95CB7353-995B-4B82-8DFF-41C0133FFF78}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dp2weixinWeb", "dp2weixinP2P\dp2weixinWeb.csproj", "{95CB7353-995B-4B82-8DFF-41C0133FFF78}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dp2weixin.service", "dp2weixin.service\dp2weixin.service.csproj", "{50E36C13-A3DE-4638-BE87-E5E254EEC386}"
EndProject
@@ -135,18 +131,6 @@ Global
{1B74D69A-530F-4275-845B-8CA6D1463BDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B74D69A-530F-4275-845B-8CA6D1463BDD}.Release|Any CPU.Build.0 = Release|Any CPU
{1B74D69A-530F-4275-845B-8CA6D1463BDD}.Release|x86.ActiveCfg = Release|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Release|Any CPU.Build.0 = Release|Any CPU
- {A77B8A4A-3AE8-4BD7-B09A-BF8D92FE802D}.Release|x86.ActiveCfg = Release|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Release|Any CPU.Build.0 = Release|Any CPU
- {2BD6F79E-A776-4A08-B972-C61F70F78BD5}.Release|x86.ActiveCfg = Release|Any CPU
{7C31EA17-404D-4CE6-8401-71808BEB5883}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C31EA17-404D-4CE6-8401-71808BEB5883}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C31EA17-404D-4CE6-8401-71808BEB5883}.Debug|x86.ActiveCfg = Debug|Any CPU
diff --git a/dp2Command.Server/dp2BaseCommandService.cs b/dp2Command.Server/dp2BaseCommandService.cs
index e07ec736..dc6da58c 100644
--- a/dp2Command.Server/dp2BaseCommandService.cs
+++ b/dp2Command.Server/dp2BaseCommandService.cs
@@ -160,7 +160,7 @@ public virtual int GetMyInfo(string remoteUserName,
///
///
///
- public string GetContactString(XmlDocument dom)
+ public static string GetContactString(XmlDocument dom)
{
string strTel = DomUtil.GetElementText(dom.DocumentElement, "tel");
string strEmail = DomUtil.GetElementText(dom.DocumentElement, "email");
diff --git a/dp2weixin.service/ApiResult.cs b/dp2weixin.service/ApiResult.cs
new file mode 100644
index 00000000..77dce5b1
--- /dev/null
+++ b/dp2weixin.service/ApiResult.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2weixin.service
+{
+ // API返回结果
+ public class ApiResult
+ {
+ public string errorInfo = "";
+
+ ///
+ /// -1:表示出错
+ ///
+ public int errorCode = 0;
+ }
+
+ public class WxUserResult
+ {
+ public WxUserItem userItem { get; set; }
+ public ApiResult apiResult { get; set; }
+ }
+}
diff --git a/dp2weixin.service/Command/BaseCommand.cs b/dp2weixin.service/Command/BaseCommand.cs
new file mode 100644
index 00000000..8e7851c6
--- /dev/null
+++ b/dp2weixin.service/Command/BaseCommand.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2Command.Service
+{
+ public class BaseCommand
+ {
+ public string CommandName { get;set;}
+ }
+}
diff --git a/dp2weixin.service/Command/BindingCommand.cs b/dp2weixin.service/Command/BindingCommand.cs
new file mode 100644
index 00000000..d9d8a096
--- /dev/null
+++ b/dp2weixin.service/Command/BindingCommand.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2Command.Service
+{
+ public class BindingCommand:BaseCommand
+ {
+ public string ReaderBarcode = "";
+ public string Password = "";
+ }
+}
diff --git a/dp2weixin.service/Command/CommandContainer.cs b/dp2weixin.service/Command/CommandContainer.cs
new file mode 100644
index 00000000..57f9ca1e
--- /dev/null
+++ b/dp2weixin.service/Command/CommandContainer.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2Command.Service
+{
+ public class CommandContainer
+ {
+ public Dictionary CmdDict = null;
+
+ public CommandContainer()
+ {
+ CmdDict = new Dictionary();
+ }
+
+ public BaseCommand GetCommand(string cmdName)
+ {
+ if (CmdDict.ContainsKey(cmdName))
+ {
+ return CmdDict[cmdName];
+ }
+
+ // 不存在自动创建
+ BaseCommand command = null;
+ if (cmdName == dp2CommandUtility.C_Command_Search)
+ {
+ command = new SearchCommand();
+ }
+ else if (cmdName == dp2CommandUtility.C_Command_Binding)
+ {
+ command = new BindingCommand();
+ }
+ else
+ {
+ command = new BaseCommand();
+ }
+ command.CommandName = cmdName;
+ CmdDict[cmdName] = command;
+ return command;
+ }
+
+ }
+}
diff --git a/dp2weixin.service/Command/SearchCommand.cs b/dp2weixin.service/Command/SearchCommand.cs
new file mode 100644
index 00000000..fbe7b355
--- /dev/null
+++ b/dp2weixin.service/Command/SearchCommand.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2Command.Service
+{
+ public class SearchCommand:BaseCommand
+ {
+
+ ///
+ /// 书目检索结果集,存路径
+ ///
+ public List BiblioResultPathList { get; set; }
+
+ ///
+ /// 是否继续输入n翻页
+ ///
+ public bool IsCanNextPage = false;
+
+ ///
+ /// 下一步开始序号
+ ///
+ public long ResultNextStart = -1;
+
+ ///
+ /// 获取下一页检索结果
+ ///
+ ///
+ ///
+ ///
+ public bool GetNextPage(out string strText,
+ out string strError)
+ {
+ strText = "";
+ strError = "";
+
+ if (this.IsCanNextPage == false)
+ {
+ strError = "已到末页。";
+ return false;
+ }
+
+ long lTotalCount = this.BiblioResultPathList.Count;
+ if (this.ResultNextStart >= lTotalCount)
+ {
+ strError = "内部错误,下页起始序号>=总记录数了";
+ return false;
+ }
+
+ // 本页显示的最大序号
+ long nMaxIndex = this.ResultNextStart + dp2CommandUtility.C_ViewCount_OnePage;
+ if (nMaxIndex > lTotalCount)
+ {
+ nMaxIndex = lTotalCount;
+ }
+
+ string strPreMessage = "";
+ if (nMaxIndex < dp2CommandUtility.C_ViewCount_OnePage
+ || (this.ResultNextStart == 0 && nMaxIndex == lTotalCount))
+ {
+ // 没有下页了
+ this.IsCanNextPage = false;
+ strPreMessage = "命中'" + lTotalCount + "'条书目记录。您可以回复序列查看详细信息。\r\n";
+ }
+ else if (nMaxIndex < lTotalCount)
+ {
+ // 有下页
+ this.IsCanNextPage = true;
+ strPreMessage = "命中'" + lTotalCount + "'条书目记录。本次显示第" + (this.ResultNextStart + 1).ToString() + "-" + nMaxIndex + "条,您可以回复N继续显示下一页,或者回复序列查看详细信息。\r\n";
+ }
+ else if (nMaxIndex == lTotalCount)
+ {
+ //无下页
+ this.IsCanNextPage = false;
+ strPreMessage = "命中'" + lTotalCount + "'条书目记录。本次显示第" + (this.ResultNextStart + 1).ToString() + "-" + nMaxIndex + "条,已到末页。您可以回复序列查看详细信息。\r\n";
+ }
+
+ string strBrowse = "";
+ for (long i = this.ResultNextStart; i < nMaxIndex; i++)
+ {
+ if (strBrowse != "")
+ strBrowse += "\n";
+
+ string text = this.BiblioResultPathList[(int)i];
+ int index = text.IndexOf("*");
+ if (index >= 0)
+ text = text.Substring(index + 1);
+ strBrowse += (i + 1).ToString().PadRight(5, ' ') + text;
+ }
+
+ // 设置下页索引
+ this.ResultNextStart = nMaxIndex;
+
+ //返回结果
+ strText = strPreMessage + strBrowse;
+
+ return true;
+ }
+ }
+}
diff --git a/dp2weixin.service/Command/dp2CommandUtility.cs b/dp2weixin.service/Command/dp2CommandUtility.cs
new file mode 100644
index 00000000..c9560a27
--- /dev/null
+++ b/dp2weixin.service/Command/dp2CommandUtility.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace dp2Command.Service
+{
+ public class dp2CommandUtility
+ {
+ // 2016/2/20 选择图书馆
+ public const string C_Command_SelectLib = "selectlib";
+ // 切换读者,用于微信用户绑定多个读者的情况
+ public const string C_Command_ChangePatron = "changepatron";
+
+
+ public const string C_Command_Binding = "binding";
+ public const string C_Command_Unbinding = "unbinding";
+ public const string C_Command_MyInfo = "myinfo";
+ public const string C_Command_BorrowInfo = "borrowinfo";
+ public const string C_Command_Renew = "renew";
+ public const string C_Command_Search = "search";
+ public const string C_Command_SearchDetail = "search-detail";
+ // 公共信息
+ public const string C_Command_BookRecommend = "bookrecommend";
+ public const string C_Command_Notice = "notice";//Notice
+ // 检索每页显示记录数
+ public const int C_ViewCount_OnePage = 20;
+
+
+ public const String C_WeiXinIdPrefix = "weixinid:";
+
+ ///
+ /// 校验字符串是否是命令
+ ///
+ ///
+ ///
+ public static bool CheckIsCommand(string strText)
+ {
+ strText = strText.ToLower();
+ if (strText == C_Command_Search
+ || strText == C_Command_Binding
+ || strText == C_Command_Unbinding
+ || strText == C_Command_MyInfo
+ || strText == C_Command_BorrowInfo
+ || strText == C_Command_Renew
+ || strText == C_Command_BookRecommend
+ || strText == C_Command_Notice
+ || strText == C_Command_SelectLib
+ || strText == C_Command_ChangePatron
+ )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/dp2weixin.service/Interface/MessageInterface.cs b/dp2weixin.service/Interface/MessageInterface.cs
new file mode 100644
index 00000000..aff8574b
--- /dev/null
+++ b/dp2weixin.service/Interface/MessageInterface.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DigitalPlatform.Interfaces
+{
+ // 一个扩展消息接口
+ public class MessageInterface
+ {
+ public string Type = "";
+ public Assembly Assembly = null;
+ public ExternalMessageHost HostObj = null;
+ }
+}
diff --git a/dp2weixin.service/Interface/ScriptManager.cs b/dp2weixin.service/Interface/ScriptManager.cs
new file mode 100644
index 00000000..f717ccda
--- /dev/null
+++ b/dp2weixin.service/Interface/ScriptManager.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DigitalPlatform.Interfaces
+{
+ public class ScriptManager
+ {
+ // 获得从指定类或者接口派生的类
+ public static Type GetDerivedClassType(Assembly assembly,
+ string strBaseTypeFullName)
+ {
+ if (assembly == null)
+ return null;
+
+ Type[] types = assembly.GetTypes();
+ foreach (Type type in types)
+ {
+ if (type.IsClass == false)
+ continue;
+
+ // 2015/5/28
+ Type[] interfaces = type.GetInterfaces();
+ foreach (Type inter in interfaces)
+ {
+ if (inter.FullName == strBaseTypeFullName)
+ return type;
+ }
+
+ if (IsDerivedFrom(type,
+ strBaseTypeFullName) == true)
+ return type;
+ }
+
+ return null;
+ }
+
+ // 观察type的基类中是否有类名为strBaseTypeFullName的类。
+ public static bool IsDerivedFrom(Type type,
+ string strBaseTypeFullName)
+ {
+ Type curType = type;
+ for (; ; )
+ {
+ if (curType == null
+ || curType.FullName == "System.Object")
+ return false;
+
+ if (curType.FullName == strBaseTypeFullName)
+ return true;
+
+ curType = curType.BaseType;
+ }
+
+ }
+ }
+}
diff --git a/dp2weixin.service/LibDatabase.cs b/dp2weixin.service/LibDatabase.cs
new file mode 100644
index 00000000..807a3344
--- /dev/null
+++ b/dp2weixin.service/LibDatabase.cs
@@ -0,0 +1,289 @@
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2weixin.service
+{
+
+
+ ///
+ /// 用户数据库
+ ///
+ public sealed class LibDatabase
+ {
+ // 饿汉模式
+ private static readonly LibDatabase repo = new LibDatabase();
+ public static LibDatabase Current
+ {
+ get
+ {
+ return repo;
+ }
+ }
+
+
+ MongoClient _mongoClient = null;
+ IMongoDatabase _database = null;
+ string _libDbName = "";
+
+ IMongoCollection _libCollection = null;
+ public IMongoCollection LibCollection
+ {
+ get
+ {
+ return this._libCollection;
+ }
+ }
+
+ // 初始化
+ public void Open(
+ string strMongoDbConnStr,
+ string strInstancePrefix)
+ {
+ if (string.IsNullOrEmpty(strMongoDbConnStr) == true)
+ throw new ArgumentException("strMongoDbConnStr 参数值不应为空");
+
+ if (string.IsNullOrEmpty(strInstancePrefix) == false)
+ strInstancePrefix = strInstancePrefix + "_";
+ _libDbName = strInstancePrefix + "lib";
+
+ this._mongoClient = new MongoClient(strMongoDbConnStr);
+ this._database = this._mongoClient.GetDatabase(this._libDbName);
+
+ //图书馆点对点账号
+ _libCollection = this._database.GetCollection("item");
+
+ /*
+ // todo 创建索引
+ bool bExist = false;
+ var indexes = _libCollection.Indexes.ListAsync().Result.ToListAsync().Result;
+ foreach (BsonDocument doc in indexes)
+ {
+ }
+ // _logCollection.DropAllIndexes();
+ if (bExist == false)
+ {
+ //await CreateIndex();
+ }
+ */
+ }
+
+ // 创建索引
+ public async Task CreateIndex()
+ {
+ /*
+ var options = new CreateIndexOptions() { Unique = true };
+ await _libCollection.Indexes.CreateOneAsync(
+ Builders.IndexKeys.Ascending("libCode"),
+ options);
+ */
+ }
+
+ // 清除集合内的全部内容
+ public async Task Clear()
+ {
+ if (_libCollection == null)
+ {
+ throw new Exception("访问日志 mongodb 集合尚未初始化");
+ }
+
+ // https://docs.mongodb.org/getting-started/csharp/remove/
+ var filter = new BsonDocument();
+ await _libCollection.DeleteManyAsync(filter);
+ //await CreateIndex();
+ }
+
+ public LibItem GetLibById(string id)
+ {
+ var filter = Builders.Filter.Eq("id", id);
+
+ var list = this.LibCollection.Find(new BsonDocument("id", id)).ToListAsync().Result;
+ if (list.Count > 0)
+ return list[0];
+
+ return null;
+ }
+ public LibItem GetLibByLibCode(string libCode)
+ {
+ var filter = Builders.Filter.Eq("libCode", libCode);
+ List list = this.LibCollection.Find(filter).ToList();
+ if (list.Count > 0)
+ return list[0];
+
+ return null;
+ }
+
+ public List GetLibs()
+ {
+ return this.LibCollection.Find(new BsonDocument()).ToListAsync().Result;
+ }
+
+ ///
+ /// 根据libCode获得图书馆对象
+ ///
+ /// *获取全部
+ /// 0
+ /// -1
+ ///
+ public async Task> GetLibs(string libCode,
+ int start,
+ int count)
+ {
+ IMongoCollection collection = this.LibCollection;
+
+ List results = new List();
+
+ var filter = Builders.Filter.Eq("libCode", libCode);
+ var index = 0;
+ using (var cursor = await collection.FindAsync(
+ libCode == "*" ? new BsonDocument() : filter
+ ))
+ {
+ while (await cursor.MoveNextAsync())
+ {
+ var batch = cursor.Current;
+ foreach (var document in batch)
+ {
+ if (count != -1 && index - start >= count)
+ break;
+ if (index >= start)
+ results.Add(document);
+ index++;
+ }
+ }
+ }
+ return results;
+ }
+
+ public LibItem Add(LibItem item)
+ {
+ item.OperTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
+
+ this.LibCollection.InsertOne(item);
+
+ return item;
+ }
+
+ // 更新
+ public async Task Update(LibItem item)
+ {
+ IMongoCollection collection = this.LibCollection;
+
+ var filter = Builders.Filter.Eq("id", item.id);
+ //var filter = Builders.Filter.Eq("libCode", item.libCode);
+ var update = Builders.Update
+ .Set("libCode", item.libCode)
+ .Set("libName", item.libName)
+ .Set("libP2PAccount", item.libUserName)
+ .Set("comment", item.comment)
+ .Set("OperTime", item.OperTime);
+
+ UpdateResult ret = await collection.UpdateOneAsync(filter, update);
+ return ret.ModifiedCount;
+ }
+
+
+ ///
+ /// 删除
+ ///
+ ///
+ public void Delete(String id)
+ {
+ IMongoCollection collection = this.LibCollection;
+
+ var filter = Builders.Filter.Eq("id", id);
+ //var filter = Builders.Filter.Eq("libCode", item.libCode);
+
+ collection.DeleteOne(filter);
+ }
+
+ }
+
+ public class LibItem
+ {
+ [BsonId]
+ [BsonRepresentation(BsonType.ObjectId)]
+ public string id { get; private set; }
+
+ public string libCode { get; set; }
+ public string libName { get; set; }
+ public string libUserName { get; set; }
+
+
+ public string comment { get; set; } // 注释
+
+ public string OperTime { get; set; } // 操作时间
+
+ }
+ /*
+ public class LibraryRespository
+ {
+ private static LibraryRespository repo = new LibraryRespository();
+
+ public static LibraryRespository Current
+ {
+ get
+ {
+ return repo;
+ }
+ }
+
+ private List data = new List {
+ new LibItem {
+ id="001", libCode = "lib1", libName = "图书馆1", libP2PAccount = "a1"},
+ new LibItem {
+ id="002",libCode = "lib2", libName = "图书馆2", libP2PAccount = "a2"},
+ new LibItem {
+ id="003",libCode = "lib3", libName = "图书馆3", libP2PAccount = "a3"},
+ };
+
+ public IEnumerable GetAll()
+ {
+ return data;
+ }
+
+ public LibItem Get(string libId)
+ {
+ return data.Where(r => r.id == libId).FirstOrDefault();
+ }
+
+ public LibItem Add(LibItem item)
+ {
+ // id取guid todo
+ item.id = Guid.NewGuid().ToString();
+
+ data.Add(item);
+ return item;
+ }
+
+ public void Remove(string libId)
+ {
+ LibItem item = Get(libId);
+ if (item != null)
+ {
+ data.Remove(item);
+ }
+ }
+
+ public bool Update(LibItem item)
+ {
+ LibItem storedItem = Get(item.libCode);
+ if (storedItem != null)
+ {
+ storedItem.libName = item.libName;
+ storedItem.libP2PAccount = item.libP2PAccount;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ */
+}
diff --git a/dp2weixin.service/MsgRouter.cs b/dp2weixin.service/MsgRouter.cs
new file mode 100644
index 00000000..23051bc3
--- /dev/null
+++ b/dp2weixin.service/MsgRouter.cs
@@ -0,0 +1,288 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Collections;
+
+using DigitalPlatform;
+using DigitalPlatform.MessageClient;
+using DigitalPlatform.Message;
+
+namespace dp2weixin.service
+{
+ public class MsgRouter : ThreadBase
+ {
+ public event SendMessageEventHandler SendMessageEvent = null;
+
+ // 这里是引用外部的对象,不负责创建和销毁
+ public MessageConnectionCollection Channels = null;
+
+ public string Url { get; set; }
+ public string GroupName { get; set; }
+
+ // 存储从 AddMessage() 得到的消息
+ List _messageList = new List();
+ private static readonly Object _syncRoot_messageList = new Object();
+
+ // 记忆已经发送过的消息,避免重复发送
+ Hashtable _sendedTable = new Hashtable();
+
+ public MsgRouter()
+ {
+ this.PerTime = 60 * 1000; // 60 * 1000
+ }
+
+ public void Start(MessageConnectionCollection channels,
+ string url,
+ string groupName)
+ {
+ this.Url = url;
+ this.GroupName = groupName;
+ this.Channels = channels;
+
+ //Channels.Login += _channels_Login;
+ Channels.AddMessage -= _channels_AddMessage;
+ Channels.AddMessage += _channels_AddMessage;
+
+ Channels.ConnectionStateChange -= _channels_ConnectionStateChange;
+ Channels.ConnectionStateChange += _channels_ConnectionStateChange;
+
+ this.BeginThread();
+ }
+
+ public void Stop()
+ {
+ Channels.AddMessage -= _channels_AddMessage;
+ Channels.ConnectionStateChange -= _channels_ConnectionStateChange;
+
+ this.StopThread(false);
+ }
+
+ void _channels_ConnectionStateChange(object sender, ConnectionEventArgs e)
+ {
+ if (e.Action == "Reconnected"
+ || e.Action == "Connected")
+ {
+ this.Activate();//激活线程
+ }
+ }
+
+ void _channels_AddMessage(object sender, AddMessageEventArgs e)
+ {
+ if (e.Action != "create")
+ return;
+
+ lock (_syncRoot_messageList)
+ {
+ // 累积太多了就不送入 list 了,只是激活线程等 GetMessage() 慢慢一百条地处理
+ if (this._messageList.Count < 10000)
+ this._messageList.AddRange(e.Records);
+ }
+ this.Activate();
+ }
+
+ // 工作线程每一轮循环的实质性工作
+ public override void Worker()
+ {
+ //this.WriteLog("走到worker1");
+ List records = GetMessage();
+ if (records.Count > 0)
+ {
+ lock (_syncRoot_messageList)
+ {
+ this._messageList.AddRange(records);
+ }
+ }
+ //this.WriteErrorLog("走到worker2:" +records.Count);
+
+ if (this._messageList.Count > 0)
+ {
+ // 取出前面 100 个加以处理
+ // 这样锁定的时间很短
+ List temp_records = new List();
+ lock (_syncRoot_messageList)
+ {
+ int i = 0;
+ foreach(MessageRecord record in this._messageList)
+ {
+ if (i >= 100)
+ break;
+ temp_records.Add(record);
+ i++;
+ }
+ this._messageList.RemoveRange(0, temp_records.Count);
+ }
+
+ //this.WriteErrorLog("走到worker3:" + temp_records.Count);
+
+ // 发送消息给下游模块
+ SendMessage(temp_records);
+
+ //this.WriteErrorLog("走到worker4:");
+
+ // 从 dp2mserver 中删除这些消息
+ DeleteMessage(temp_records, this.GroupName);
+
+ //this.WriteErrorLog("走到worker5:");
+ }
+
+ // 如果本轮主动获得过消息,就要连续激活线程,让线程下次继续处理。只有本轮发现没有新消息了,才会进入休眠期
+ if (records.Count > 0)
+ this.Activate();
+
+ CleanSendedTable(); // TODO: 可以改进为判断间隔至少 5 分钟才做一次
+ }
+
+ // 将消息发送给下游模块
+ void SendMessage(List records)
+ {
+ SendMessageEventHandler handler = this.SendMessageEvent;
+
+ foreach (MessageRecord record in records)
+ {
+ if (this._sendedTable.ContainsKey(record.id))
+ continue;
+
+ this.WriteLog("开始处理:" + record.id);
+
+ // 发送
+ if (handler != null)
+ {
+ SendMessageEventArgs e = new SendMessageEventArgs();
+ e.Message = record;
+ handler(this, e);
+ }
+
+ this.WriteLog("处理结束:" + record.id);
+
+ this._sendedTable[record.id] = DateTime.Now;
+ }
+ }
+
+ // 清理超过一定时间的“已发送”记忆事项
+ void CleanSendedTable()
+ {
+ DateTime now = DateTime.Now;
+ TimeSpan delta = new TimeSpan(0, 30, 0);
+ List delete_keys = new List();
+ foreach (string key in this._sendedTable.Keys)
+ {
+ var time = (DateTime)this._sendedTable[key];
+ if (time - now > delta)
+ delete_keys.Add(key);
+ }
+
+ foreach (string key in delete_keys)
+ {
+ this._sendedTable.Remove(key);
+ }
+ }
+
+ void WriteLog(string strText)
+ {
+ dp2WeiXinService.Instance.WriteLog(strText);
+ //MessageRecord record = new MessageRecord();
+ //record.data = "*** error *** " + strText;
+ //SendMessageEventArgs e = new SendMessageEventArgs();
+ //e.Message = record;
+ //this.SendMessageEvent(this, e);
+ }
+
+ // 从 dp2mserver 获得消息
+ // 每次最多获得 100 条
+ List GetMessage()
+ {
+ string strError = "";
+ CancellationToken cancel_token = new CancellationToken();
+
+ string id = Guid.NewGuid().ToString();
+ GetMessageRequest request = new GetMessageRequest(id,
+ "",
+ this.GroupName, // "" 表示默认群组
+ "",
+ "", // strTimeRange,
+ 0,
+ 100);
+ try
+ {
+ MessageConnection connection = this.Channels.GetConnectionAsync(
+ this.Url,
+ "").Result;
+ GetMessageResult result = connection.GetMessageAsync(
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ if (result.Value == -1)
+ goto ERROR1;
+ return result.Results;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+ ERROR1:
+ this.WriteLog("GetMessage() error: " + strError);
+ return new List();
+ }
+
+ void DeleteMessage(List records,
+ string strGroupName)
+ {
+ List delete_records = new List();
+
+ foreach (MessageRecord source in records)
+ {
+ MessageRecord record = new MessageRecord();
+ record.groups = strGroupName.Split(new char[] { ',' });
+ record.id = source.id;
+ delete_records.Add(record);
+ }
+
+ string strError = "";
+
+ // CancellationToken cancel_token = new CancellationToken();
+
+ try
+ {
+ MessageConnection connection = this.Channels.GetConnectionAsync(
+ this.Url,
+ "").Result;
+ SetMessageRequest param = new SetMessageRequest("expire",
+ "dontNotifyMe",
+ records);
+
+ SetMessageResult result = connection.SetMessageAsync(param).Result;
+ if (result.Value == -1)
+ goto ERROR1;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+ return;
+ ERROR1:
+ this.WriteLog("DeleteMessage() error : " + strError);
+ }
+ }
+
+ public delegate void SendMessageEventHandler(object sender,
+ SendMessageEventArgs e);
+
+ public class SendMessageEventArgs : EventArgs
+ {
+ public MessageRecord Message = null;
+ }
+}
diff --git a/dp2weixin.service/Patron.cs b/dp2weixin.service/Patron.cs
index 89490569..e1828c55 100644
--- a/dp2weixin.service/Patron.cs
+++ b/dp2weixin.service/Patron.cs
@@ -12,7 +12,7 @@ public class PatronInfo
public Patron patron { get; set; }
// 在借册
- public List borrowList { get; set; }
+ public List borrowList { get; set; }
// 违约/交费信息
public List overdueList { get; set; }
@@ -79,7 +79,7 @@ public class OverdueInfo
}
- public class BorrowInfo
+ public class BorrowInfo2
{
public string barcode { get; set; }
public string renewNo { get; set; }
diff --git a/dp2weixin.service/SearchBiblioResult.cs b/dp2weixin.service/SearchBiblioResult.cs
new file mode 100644
index 00000000..b1a4cf7b
--- /dev/null
+++ b/dp2weixin.service/SearchBiblioResult.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2weixin.service
+{
+ public class SearchBiblioResult
+ {
+ public ApiResult apiResult { get; set; }
+
+ // 在借册
+ public List records { get; set; }
+
+ public long resultCount = 0;
+
+ public bool isCanNext { get; set; }
+ }
+
+ public class BiblioRecord
+ {
+ public string no = "";
+ public string recPath = "";
+ public string name = "";
+ public string libUserName = "";
+ }
+
+ public class BiblioRecordResult : ApiResult
+ {
+ public string biblioPath { get; set; }
+
+ public string summary { get; set; }
+ public List itemList { get; set; }
+ }
+
+ public class BiblioItem
+ {
+ /*
+册条码
+状态
+卷册
+馆藏地
+价格
+
+在借情况
+册记录路径
+ */
+
+ public string barcode { get; set; }
+ public string state { get; set; }
+ public string volumn { get; set; }
+ public string location { get; set; }
+ public string price { get; set; }
+
+ // 索引号
+ public string accessNo { get; set; }
+ // 出版日期
+ public string publishTime { get; set; }
+ public string borrowInfo { get; set; }
+ // 备注
+ public string comment { get; set; }
+
+ }
+}
diff --git a/dp2weixin.service/TemplateData.cs b/dp2weixin.service/TemplateData.cs
new file mode 100644
index 00000000..7b17dcd0
--- /dev/null
+++ b/dp2weixin.service/TemplateData.cs
@@ -0,0 +1,178 @@
+using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2weixin.service
+{
+//{{first.DATA}}
+//图书书名:{{keyword1.DATA}}
+//册条码号:{{keyword2.DATA}}
+//借阅日期:{{keyword3.DATA}}
+//借阅期限:{{keyword4.DATA}}
+//应还日期:{{keyword5.DATA}}
+//{{remark.DATA}}
+
+//尊敬的XXX,恭喜您借书成功。
+//图书书名:C#开发教程
+//册条码号:C0000001
+//借阅日期:2016-5-27
+//借阅期限:31
+//应还日期:2016-6-27
+//祝您阅读愉快,欢迎再借。
+ public class BorrowTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem keyword4 { get; set; }
+ public TemplateDataItem keyword5 { get; set; }
+ public TemplateDataItem remark { get; set; }
+ }
+
+
+//{{first.DATA}}
+//书名:{{keyword1.DATA}}
+//归还时间:{{keyword2.DATA}}
+//借阅人:{{keyword3.DATA}}
+//{{remark.DATA}}
+//您好,你借阅的图书已确认归还.
+//书名:算法导论
+//归还时间:2015-10-10 12:14
+//借阅人:李明
+//欢迎继续借书!
+ public class ReturnTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem remark { get; set; }
+ }
+
+
+
+//{{first.DATA}}
+//订单号:{{keyword1.DATA}}
+//缴费人:{{keyword2.DATA}}
+//缴费金额:{{keyword3.DATA}}
+//费用类型:{{keyword4.DATA}}
+//缴费时间:{{keyword5.DATA}}
+//{{remark.DATA}}
+//您好,您已缴费成功!
+//订单号:书名(册条码号)
+//缴费人:张三
+//缴费金额:¥100.00
+//费用类型:违约
+//缴费时间:2015-12-27 13:15
+//如有疑问,请联系学校管理员,感谢您的使用!
+ public class PayTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem keyword4 { get; set; }
+ public TemplateDataItem keyword5 { get; set; }
+ public TemplateDataItem remark { get; set; }
+ }
+
+//{{first.DATA}}
+//退款原因:{{reason.DATA}}
+//退款金额:{{refund.DATA}}
+//{{remark.DATA}}
+//您好,您对微信数据容灾服务的抢购未成功,已退款。
+//退款原因:未抢购成功
+//退款金额:2570元
+//备注:如有疑问,请致电13912345678联系我们,或回复M来了解详情。
+ public class ReturnPayTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem reason { get; set; }
+ public TemplateDataItem refund { get; set; }
+ public TemplateDataItem remark { get; set; }
+ }
+
+
+//{{first.DATA}}
+//标题:{{keyword1.DATA}}
+//时间:{{keyword2.DATA}}
+//内容:{{keyword3.DATA}}
+//{{remark.DATA}}
+//您好,您有新的消息!
+//标题:车辆剩余油量过少
+//时间:2015年8月20日
+//内容:您的车辆剩余测量过少,请注意加油
+//感谢您使用车管家!
+ public class MessageTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem remark { get; set; }
+ }
+
+
+//{{first.DATA}}
+//图书书名:{{keyword1.DATA}}
+//应还日期:{{keyword2.DATA}}
+//超期天数:{{keyword3.DATA}}
+//{{remark.DATA}}
+ public class CaoQiTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem remark { get; set; }
+
+ }
+
+ //{{first.DATA}}
+ //图书书名:{{keyword1.DATA}}
+ //到书日期:{{keyword2.DATA}}
+ //保留期限:{{keyword3.DATA}}
+ //{{remark.DATA}}
+ public class ArrivedTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem keyword3 { get; set; }
+ public TemplateDataItem remark { get; set; }
+
+ }
+
+
+ //{{first.DATA}}
+ //绑定帐号:{{keyword1.DATA}}
+ //绑定说明:{{keyword2.DATA}}
+ //{{remark.DATA}}
+ public class BindTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem remark { get; set; }
+
+ }
+
+
+
+//{{first.DATA}}
+//解绑帐号:{{keyword1.DATA}}
+//解绑说明:{{keyword2.DATA}}
+//{{remark.DATA}}
+ public class UnBindTemplateData
+ {
+ public TemplateDataItem first { get; set; }
+ public TemplateDataItem keyword1 { get; set; }
+ public TemplateDataItem keyword2 { get; set; }
+ public TemplateDataItem remark { get; set; }
+
+ }
+}
diff --git a/dp2weixin.service/WxUserDatabase.cs b/dp2weixin.service/WxUserDatabase.cs
new file mode 100644
index 00000000..08a5c53f
--- /dev/null
+++ b/dp2weixin.service/WxUserDatabase.cs
@@ -0,0 +1,354 @@
+using DigitalPlatform.IO;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Driver;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace dp2weixin.service
+{
+ ///
+ /// 用户数据库
+ ///
+ public sealed class WxUserDatabase
+ {
+ private static readonly WxUserDatabase _db = new WxUserDatabase();
+ public static WxUserDatabase Current
+ {
+ get
+ {
+ return _db;
+ }
+ }
+
+ MongoClient _mongoClient = null;
+ IMongoDatabase _database = null;
+ string _wxUserDbName = "";
+
+ IMongoCollection _wxUserCollection = null;
+ public IMongoCollection wxUserCollection
+ {
+ get
+ {
+ return this._wxUserCollection;
+ }
+ }
+
+ // 初始化
+ public void Open(
+ string strMongoDbConnStr,
+ string strInstancePrefix)
+ {
+ if (string.IsNullOrEmpty(strMongoDbConnStr) == true)
+ throw new ArgumentException("strMongoDbConnStr 参数值不应为空");
+
+ if (string.IsNullOrEmpty(strInstancePrefix) == false)
+ strInstancePrefix = strInstancePrefix + "_";
+ _wxUserDbName = strInstancePrefix + "user";
+
+ this._mongoClient = new MongoClient(strMongoDbConnStr);
+ this._database = this._mongoClient.GetDatabase(this._wxUserDbName);
+
+ //图书馆点对点账号
+ _wxUserCollection = this._database.GetCollection("item");
+
+ // todo 创建索引
+ bool bExist = false;
+ var indexes = _wxUserCollection.Indexes.ListAsync().Result.ToListAsync().Result;
+ foreach (BsonDocument doc in indexes)
+ {
+ }
+ // _logCollection.DropAllIndexes();
+ if (bExist == false)
+ {
+ CreateIndex();
+ }
+
+ }
+
+ // 创建索引
+ public void CreateIndex()
+ {
+ var options = new CreateIndexOptions() { Unique = false }; //不唯一,一个微信用户可能对应多个读者
+ _wxUserCollection.Indexes.CreateOne(
+ Builders.IndexKeys.Ascending("weixinId"),
+ options);
+
+ }
+
+ // 清除集合内的全部内容
+ public async Task Clear()
+ {
+ if (_wxUserCollection == null)
+ {
+ throw new Exception("访问日志 mongodb 集合尚未初始化");
+ }
+
+ // https://docs.mongodb.org/getting-started/csharp/remove/
+ var filter = new BsonDocument();
+ await _wxUserCollection.DeleteManyAsync(filter);
+ CreateIndex();
+ }
+
+ /*
+ ///
+ /// 根据微信号与图书馆代码查
+ ///
+ ///
+ ///
+ ///
+ public WxUserItem GetActive(string weixinId,string libCode)
+ {
+ var filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("libCode", libCode)
+ & Builders.Filter.Eq("isActive", 1);
+
+ List list = this.wxUserCollection .Find(filter).ToList();
+ if (list.Count > 0)
+ return list[0];
+
+ return null;
+ }
+ */
+ public WxUserItem GetActiveOrFirst(string weixinId, string libCode)
+ {
+ // 先查active的
+ var filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("libCode", libCode)
+ & Builders.Filter.Eq("isActive", 1);
+
+ List list = this.wxUserCollection.Find(filter).ToList();
+ if (list.Count > 0)
+ return list[0];
+
+ // 没有查first
+ filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("libCode", libCode);
+
+ list = this.wxUserCollection.Find(filter).ToList();
+ if (list.Count > 0)
+ return list[0];
+
+ return null;
+ }
+
+ public WxUserItem GetOneOrEmptyPatron(string weixinId, string libCode,string readerBarcode)
+ {
+ // 先查到weixinId+libCode+readerBarcode唯一的记录
+ var filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("libCode", libCode)
+ & Builders.Filter.Eq("readerBarcode", readerBarcode);
+ List list = this.wxUserCollection.Find(filter).ToList();
+ if (list.Count >= 1)
+ return list[0];
+
+ // 未找到查weixinId+libCode,readerBarcoe为空的记录
+ filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("libCode", libCode)
+ & Builders.Filter.Eq("readerBarcode", "");
+ list = this.wxUserCollection.Find(filter).ToList();
+ if (list.Count >= 1)
+ return list[0];
+
+
+ return null;
+ }
+
+ public WxUserItem GetActive(string weixinId)
+ {
+ var filter = Builders.Filter.Eq("weixinId", weixinId)
+ & Builders.Filter.Eq("isActive", 1);
+
+ List list= this.wxUserCollection.Find(filter).ToList();//.ToListAsync().Result;
+ if (list.Count > 1)
+ throw new Exception("程序异常:微信号活动读者数量有" +list.Count+"个");
+
+ if (list.Count == 1)
+ return list[0];
+
+ return null;
+ }
+
+ public List GetByWeixinId(string weixinId)
+ {
+ var filter = Builders.Filter.Eq("weixinId", weixinId);
+
+ return this.wxUserCollection.Find(filter).ToList();//.ToListAsync().Result;
+ }
+
+ public WxUserItem GetOneByWeixinId(string weixinId)
+ {
+ var filter = Builders.Filter.Eq("weixinId", weixinId);
+
+ Listlist= this.wxUserCollection.Find(filter).ToList();//.ToListAsync().Result;
+ if (list.Count > 0)
+ return list[0];
+
+ return null;
+ }
+
+ ///
+ /// 查找所有用户
+ ///
+ ///
+ public List GetUsers()
+ {
+ IFindFluent f = this.wxUserCollection.Find(new BsonDocument());
+ if (f != null)
+ return f.ToList();
+
+ return null;
+ }
+
+
+
+ public WxUserItem Add(WxUserItem item)
+ {
+ //item.CreateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
+
+ this.wxUserCollection.InsertOne(item);
+
+ return item;
+ }
+
+ // 更新
+ public long Update(WxUserItem item)
+ {
+ IMongoCollection collection = this.wxUserCollection;
+
+ var filter = Builders.Filter.Eq("id", item.id);
+ var update = Builders.Update
+ .Set("weixinId", item.weixinId)
+ .Set("readerBarcode", item.readerBarcode)
+ .Set("readerName", item.readerName)
+ .Set("libCode", item.libCode)
+ .Set("libUserName", item.libUserName)
+ .Set("libName", item.libName)
+ .Set("createTime", item.createTime)
+ .Set("updateTime", item.updateTime)
+ .Set("xml", item.xml)
+ .Set("refID", item.refID)
+ .Set("isActive", item.isActive);
+
+ UpdateResult ret = collection.UpdateOne(filter, update);
+ return ret.ModifiedCount;
+ }
+
+ public WxUserItem GetById(String id)
+ {
+ if (string.IsNullOrEmpty(id) == true || id == "null")
+ return null;
+ IMongoCollection collection = this.wxUserCollection;
+ var filter = Builders.Filter.Eq("id", id);
+ List list = this.wxUserCollection.Find(filter).ToList();
+ if (list.Count > 0)
+ {
+ return list[0];
+ }
+ return null;
+ }
+
+
+ ///
+ /// 删除
+ ///
+ ///
+ public void Delete(String id)
+ {
+ if (string.IsNullOrEmpty(id) == true || id=="null")
+ return;
+
+
+
+ IMongoCollection collection = this.wxUserCollection;
+ var filter = Builders.Filter.Eq("id", id);
+
+ // 检查一下是否被删除读者是否为默认读者,如果是,把自动将默认值设了第一个读者上。
+ List list = this.wxUserCollection.Find(filter).ToList();
+ string weixinId = "";
+ if (list.Count > 0)
+ {
+ weixinId = list[0].weixinId;
+ }
+
+ // 先删除
+ collection.DeleteOne(filter);
+
+ // 自动将第一个设为默认的
+ WxUserItem newUserItem = this.GetOneByWeixinId(weixinId);
+ if (newUserItem != null)
+ this.SetActive(newUserItem);
+ }
+
+ public void SetActive(WxUserItem item)
+ {
+ this.SetActive(item.weixinId, item.id);
+ }
+
+ public void SetActive(string weixinId,string id)
+ {
+ if (string.IsNullOrEmpty(weixinId) == true || weixinId=="null")
+ return;
+
+ if (string.IsNullOrEmpty(weixinId) == true || id=="null")
+ return;
+
+ IMongoCollection collection = this.wxUserCollection;
+
+ // 先将该微信用户的所有绑定读者都设为非活动
+ var filter = Builders.Filter.Eq("weixinId", weixinId);
+ var update = Builders.Update
+ .Set("isActive", 0)
+ .Set("updateTime", DateTimeUtil.DateTimeToString(DateTime.Now));
+ UpdateResult ret = collection.UpdateMany(filter, update);
+
+ // 再将参数传入的记录设为活动状态
+ filter = Builders.Filter.Eq("id",id);
+ update = Builders.Update
+ .Set("isActive", 1)
+ .Set("updateTime", DateTimeUtil.DateTimeToString(DateTime.Now));
+ ret = collection.UpdateMany(filter, update);
+ }
+
+
+
+
+
+ }
+ public class WxUserItem
+ {
+ [BsonId]
+ [BsonRepresentation(BsonType.ObjectId)]
+ public string id { get; private set; }
+
+ public string weixinId { get; set; } // 绑定必备
+ public string readerBarcode { get; set; }
+ public string readerName { get; set; }
+
+ public string libCode { get; set; } // 绑定必备
+ public string libUserName { get; set; }// 绑定必备
+ public string libName { get; set; }// 绑定必备
+
+ public string createTime { get; set; } // 创建时间
+ public string updateTime { get; set; } // 更校报时间
+
+
+ public string xml { get; set; }
+ public string refID { get; set; }
+
+ public int isActive = 0;
+
+
+ // 绑定必备
+ public string prefix { get; set; } //必须设为属性,才能在前端传值。
+ public string word { get; set; }
+ public string password { get; set; }
+
+ public string fullWord { get; set; } // 服务器用fullWord将strPrefix:strWord存在一起
+ }
+
+
+}
diff --git a/dp2weixin.service/app.config b/dp2weixin.service/app.config
index f3940287..fdc9c16f 100644
--- a/dp2weixin.service/app.config
+++ b/dp2weixin.service/app.config
@@ -1,19 +1,19 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
diff --git a/dp2weixin.service/dp2CmdService2.cs b/dp2weixin.service/dp2CmdService2.cs
new file mode 100644
index 00000000..d14fc8ae
--- /dev/null
+++ b/dp2weixin.service/dp2CmdService2.cs
@@ -0,0 +1,3082 @@
+using DigitalPlatform.Interfaces;
+using DigitalPlatform.IO;
+using DigitalPlatform.Message;
+using DigitalPlatform.MessageClient;
+using DigitalPlatform.Text;
+using DigitalPlatform.Xml;
+using Senparc.Weixin;
+using Senparc.Weixin.MP.AdvancedAPIs;
+using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
+using Senparc.Weixin.MP.CommonAPIs;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace dp2weixin.service
+{
+ public class dp2WeiXinService
+ {
+ public static string EncryptKey = "dp2weixinPassword";
+ public const String C_WeiXinIdPrefix = "weixinid:";
+
+ // 检索限制最大命中数常量
+ public const int C_Search_MaxCount = 200;
+ public const int C_OnePage_Count = 10;
+
+ // 微信web程序url
+ public string weiXinUrl = "";
+ // 微信目录
+ public string weiXinDataDir = "";
+ public string weiXinLogDir = "";
+
+ #region 模板消息
+
+ //微信绑定通知
+ public const string C_Template_Bind = "hFmNH7on2FqSOAiYPZVJN-FcXBv4xpVLBvHsfpLLQKU";
+ // 微信解绑通知 overdues
+ public const string C_Template_UnBind = "1riAKkt2W0AOtkx5rx-Lwa0RKRydDTHaMjSoUBGuHog";
+ //预约到书通知
+ public const string C_Template_Arrived = "Wm-7-0HJay4yloWEgGG9HXq9eOF5cL8Qm2aAUy-isoM";
+ //图书超期提醒
+ public const string C_Template_CaoQi = "QcS3LoLHk37Jh0rgKJId2o93IZjulr5XxgshzlW5VkY";
+ //图书到期提醒
+ public const string C_Template_DaoQi = "Q6O3UFPxPnq0rSz82r9P9be41tqEPaJVPD3U0PU8XOU";
+
+ //借阅成功通知
+ public const string C_Template_Borrow = "_F9kVyDWhunqM5ijvcwm6HwzVCnwbkeZl6GV6awB_fc";
+ //图书归还通知
+ public const string C_Template_Return = "86Ee0NevuLIVGZE4Xu0uzDdmg0T3xnRMOJ5tREIEG_w";
+ //缴费成功通知
+ public const string C_Template_Pay = "4HNhEfLcroEMdX0Pr6aFo_n7_aHuvAzD8_6lzABHkiM";
+ //退款通知
+ public const string C_Template_ReturnPay = "sIzSJJ-VRbFUFrDHszxCqwiIYjr9IyyqEqLr95iJVTs";
+ //个人消息通知
+ public const string C_Template_Message = "rtAx0BoUAwZ3npbNIO8Y9eIbdWO-weLGE2iOacGqN_s";
+
+ #endregion
+
+ MessageConnectionCollection _channels = new MessageConnectionCollection();
+ public MessageConnectionCollection Channels
+ {
+ get
+ {
+ return this._channels;
+ }
+ }
+
+ // 配置文件
+ public string _cfgFile = "";
+
+ // dp2服务器地址与代理账号
+ public string dp2MServerUrl = "";
+ public string userName = "";
+ public string password = "";
+
+ // 微信信息
+ public string weiXinAppId { get; set; }
+ public string weiXinSecret { get; set; }
+ public bool bTrace = false;
+
+ // 背景图管理器
+ public string TodayUrl = "";
+
+ // dp2消息处理类
+ MsgRouter _msgRouter = new MsgRouter();
+
+ //=================
+ // 设为单一实例
+ static dp2WeiXinService _instance;
+ private dp2WeiXinService()
+ {
+ }
+ private static object _lock = new object();
+ static public dp2WeiXinService Instance
+ {
+ get
+ {
+ if (null == _instance)
+ {
+ lock (_lock) //线程安全的
+ {
+ _instance = new dp2WeiXinService();
+ }
+ }
+ return _instance;
+ }
+ }
+ //===========
+
+ public void Init(string dataDir)
+ {
+ this.weiXinDataDir = dataDir;
+
+ this._cfgFile = this.weiXinDataDir + "\\" + "weixin.xml";
+ if (File.Exists(this._cfgFile) == false)
+ {
+ throw new Exception("配置文件" + this._cfgFile + "不存在。");
+ }
+
+ // 日志目录
+ this.weiXinLogDir = this.weiXinDataDir + "/log";
+ if (!Directory.Exists(weiXinLogDir))
+ {
+ Directory.CreateDirectory(weiXinLogDir);
+ }
+
+
+ XmlDocument dom = new XmlDocument();
+ dom.Load(this._cfgFile);
+ XmlNode root = dom.DocumentElement;
+
+ // 取出mserver服务器配置信息
+ XmlNode nodeDp2mserver = root.SelectSingleNode("dp2mserver");
+ this.dp2MServerUrl = DomUtil.GetAttr(nodeDp2mserver, "url");// WebConfigurationManager.AppSettings["dp2MServerUrl"];
+ this.userName = DomUtil.GetAttr(nodeDp2mserver, "username");//WebConfigurationManager.AppSettings["userName"];
+ this.password = DomUtil.GetAttr(nodeDp2mserver, "password");//WebConfigurationManager.AppSettings["password"];
+ if (string.IsNullOrEmpty(this.password) == false)// 解密
+ this.password = Cryptography.Decrypt(this.password, dp2WeiXinService.EncryptKey);
+
+ // 取出微信配置信息
+ XmlNode nodeDp2weixin = root.SelectSingleNode("dp2weixin");
+ this.weiXinUrl = DomUtil.GetAttr(nodeDp2weixin, "url"); //WebConfigurationManager.AppSettings["weiXinUrl"];
+ this.weiXinAppId = DomUtil.GetAttr(nodeDp2weixin, "AppId"); //WebConfigurationManager.AppSettings["weiXinAppId"];
+ this.weiXinSecret = DomUtil.GetAttr(nodeDp2weixin, "Secret"); //WebConfigurationManager.AppSettings["weiXinSecret"];
+ string trace = DomUtil.GetAttr(nodeDp2weixin, "trace");
+ if (trace.ToLower() == "true")
+ this.bTrace = true;
+
+
+ // mongo配置
+ XmlNode nodeMongoDB = root.SelectSingleNode("mongoDB");
+ string connectionString = DomUtil.GetAttr(nodeMongoDB, "connectionString");
+ if (String.IsNullOrEmpty(connectionString) == true)
+ {
+ throw new Exception("尚未配置mongoDB节点的connectionString属性");
+ }
+ string instancePrefix = DomUtil.GetAttr(nodeMongoDB, "instancePrefix");
+ // 打开图书馆账号库与用户库
+ WxUserDatabase.Current.Open(connectionString, instancePrefix);
+ LibDatabase.Current.Open(connectionString, instancePrefix);
+
+ // 初始化接口类
+ string strError = "";
+ int nRet = this.InitialExternalMessageInterfaces(dom, out strError);
+ if (nRet == -1)
+ throw new Exception("初始化接口配置信息出错:" + strError);
+
+
+ //全局只需注册一次
+ AccessTokenContainer.Register(this.weiXinAppId, this.weiXinSecret);
+
+
+ _channels.Login -= _channels_Login;
+ _channels.Login += _channels_Login;
+
+ if (bTrace == true)
+ {
+ if (this.Channels.TraceWriter != null)
+ this.Channels.TraceWriter.Close();
+ StreamWriter sw = new StreamWriter(Path.Combine(this.weiXinDataDir, "trace.txt"));
+ sw.AutoFlush = true;
+ _channels.TraceWriter = sw;
+ }
+
+ // 消息处理类
+ this._msgRouter.SendMessageEvent -= _msgRouter_SendMessageEvent;
+ this._msgRouter.SendMessageEvent += _msgRouter_SendMessageEvent;
+ this._msgRouter.Start(this._channels,
+ this.dp2MServerUrl,
+ "_patronNotify");
+
+ }
+
+ public void Close()
+ {
+ if (this._msgRouter != null)
+ {
+ this._msgRouter.SendMessageEvent -= _msgRouter_SendMessageEvent;
+ this._msgRouter.Stop();
+ }
+ if (this.Channels != null)
+ {
+ this.Channels.Login -= _channels_Login;
+ if (this.Channels.TraceWriter != null)
+ this.Channels.TraceWriter.Close();
+ }
+
+ this.WriteLog("走到close()");
+ }
+
+ public void SetDp2mserverInfo(string dp2mserverUrl,
+ string userName,
+ string password)
+ {
+ XmlDocument dom = new XmlDocument();
+ dom.Load(this._cfgFile);
+ XmlNode root = dom.DocumentElement;
+
+ // 设置mserver服务器配置信息
+ XmlNode nodeDp2mserver = root.SelectSingleNode("dp2mserver");
+ if (nodeDp2mserver == null)
+ {
+ nodeDp2mserver = dom.CreateElement("dp2mserver");
+ root.AppendChild(nodeDp2mserver);
+ }
+ DomUtil.SetAttr(nodeDp2mserver, "url", dp2mserverUrl);
+ DomUtil.SetAttr(nodeDp2mserver, "username", userName);
+ string encryptPassword = Cryptography.Encrypt(password, dp2WeiXinService.EncryptKey);
+ DomUtil.SetAttr(nodeDp2mserver, "password", encryptPassword);
+ dom.Save(this._cfgFile);
+
+ // 更新内存的信息
+ this.dp2MServerUrl = dp2mserverUrl;
+ this.userName = userName;
+ this.password = password;
+ }
+
+ public void GetDp2mserverInfo(out string dp2mserverUrl,
+ out string userName,
+ out string password)
+ {
+ dp2mserverUrl = "";
+ userName = "";
+ password = "";
+
+ XmlDocument dom = new XmlDocument();
+ dom.Load(this._cfgFile);
+ XmlNode root = dom.DocumentElement;
+
+ // 设置mserver服务器配置信息
+ XmlNode nodeDp2mserver = root.SelectSingleNode("dp2mserver");
+ if (nodeDp2mserver != null)
+ {
+ dp2mserverUrl = DomUtil.GetAttr(nodeDp2mserver, "url");
+ userName = DomUtil.GetAttr(nodeDp2mserver, "username");
+ password = DomUtil.GetAttr(nodeDp2mserver, "password");
+ if (string.IsNullOrEmpty(password) == false)// 解密
+ password = Cryptography.Decrypt(this.password, dp2WeiXinService.EncryptKey);
+ }
+ }
+
+ #region 消息处理
+
+ // 处理收到的消息
+ void _msgRouter_SendMessageEvent(object sender, SendMessageEventArgs e)
+ {
+ MessageRecord record = e.Message;
+ if (record == null)
+ {
+ this.WriteErrorLog("传过来的e.Message为null");
+ return;
+ }
+
+ //this.WriteErrorLog("走进_msgRouter_SendMessageEvent");
+
+ try
+ {
+ string strError = "";
+ ///
+ /// -1 不符合条件,不处理
+ /// 0 未绑定微信id,未处理
+ /// 1 成功
+ ///
+ int nRet = this.InternalDoMessage(record, out strError);
+ if (nRet == -1)
+ {
+ this.WriteErrorLog("[" + record.id + "]未发送成功:" + strError);
+ }
+ else if (nRet == 0)
+ {
+ this.WriteErrorLog("[" + record.id + "]未发送成功:未绑定微信id。");
+ }
+ else
+ {
+ this.WriteErrorLog("[" + record.id + "]发送成功。");
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("[" + record.id + "]异常:"+ex.Message);
+
+ }
+ }
+
+ ///
+ /// 内部处理消息
+ ///
+ ///
+ ///
+ ///
+ /// -1 不符合条件,不处理
+ /// 0 未绑定微信id,未处理
+ /// 1 成功
+ ///
+ public int InternalDoMessage(MessageRecord record, out string strError)
+ {
+ strError = "";
+
+ 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)
+ {
+ strError = "加载消息返回的data到xml出错:" + ex.Message;
+ return -1;
+ }
+
+ XmlNode nodeType = dataDom.DocumentElement.SelectSingleNode("type");
+ if (nodeType == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string type = DomUtil.GetNodeText(nodeType);
+ if (type != "patronNotify") //只处理通知消息
+ {
+ strError = "节点值不是patronNotify。";
+ return -1;
+ }
+
+ XmlNode nodeBody = dataDom.DocumentElement.SelectSingleNode("body");
+ if (nodeBody == null)
+ {
+ strError = "data中不存在body节点";
+ return -1;
+ }
+
+ /*
+ 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
+
+
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendMessageMsg(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+ /*
+
+ 以停代金到期
+…
+
+根元素下的items元素下,有一个或者多个overdue元素,记载了刚到期的以停代金事项信息。
+在patronRecord的下级元素overdues下,可以看到若干overdue元素,这是当前还未到期或者交费的事项。只要还有这样的事项,读者就不被允许借书,只能还书。所以通知消息文字组织的时候,可以考虑提醒尚余多少违约事项,这样可以避免读者空高兴一场以为马上可以借书了
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ XmlNode nodeOperTime = root.SelectSingleNode("operTime");
+ if (nodeOperTime == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string operTime = DomUtil.GetNodeText(nodeOperTime);
+ operTime = DateTimeUtil.ToLocalTime(operTime, "yyyy/MM/dd");
+
+
+ XmlNodeList listOverdue = root.SelectNodes("items/overdue");
+ string barcodes = "";
+ double totalPrice = 0;
+ foreach (XmlNode node in listOverdue)
+ {
+ string oneBarcode = DomUtil.GetAttr(node, "barcode");
+ if (barcodes != "")
+ barcodes += ",";
+ barcodes += oneBarcode;
+
+ string price = DomUtil.GetAttr(node, "price");
+ if (String.IsNullOrEmpty(price) == false && price.Length > 3)
+ {
+ double dPrice = Convert.ToDouble(price.Substring(3));
+ totalPrice += dPrice;
+ }
+ }
+
+ string strText = "您有["+barcodes + "]项违约以停代金到期了,";
+ XmlNodeList listOverdue1 = root.SelectNodes("patronRecord/overdues/overdue");
+ if (listOverdue1.Count > 0)
+ {
+ strText += "您还有" + listOverdue1.Count.ToString() + "项违约未到期,还不能借书。";
+ }
+ else
+ {
+ strText += "您可以继续借书了。";
+ }
+
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //标题:{{keyword1.DATA}}
+ //时间:{{keyword2.DATA}}
+ //内容:{{keyword3.DATA}}
+ //{{remark.DATA}}
+ var msgData = new BorrowTemplateData()
+ {
+ first = new TemplateDataItem("〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓", "#9400D3"),// dark violet //this._msgFirstLeft + "您的停借期限到期了。" //$$$$$$$$$$$$$$$$
+ keyword1 = new TemplateDataItem("以停代金到期", "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(operTime, "#000000"),
+ keyword3 = new TemplateDataItem(strText, "#000000"),
+ remark = new TemplateDataItem(this._msgRemark, "#CCCCCC")
+ };
+
+ // 发送模板消息
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ weiXinId,
+ dp2WeiXinService.C_Template_Message,
+ "#FF0000",
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送'以停代金到期'通知异常:" + ex.Message);
+ }
+ }
+
+
+ return 1;
+ }
+
+ ///
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendReturnPayMsg(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+ /*
+
+
+ 撤销交费
+
+ amerce
+ undo
+ R0000001
+ supervisor
+ Sun, 22 May 2016 19:15:54 +0800
+ ::1
+ 1.02
+
+ R0000001
+ 本科生
+ 张三
+ be13ecc5-6a9c-4400-9453-a072c50cede1
+ /
+ address
+ C12345
+
+
+
+ 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76
+ email:xietao@dp2003.com,weixinid:testwx2,testid:123456
+ 1234567890123
+ 13641016400
+
+
+
+
+
+
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ XmlNode nodeOperTime = root.SelectSingleNode("operTime");
+ if (nodeOperTime == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string operTime = DomUtil.GetNodeText(nodeOperTime);
+ operTime = DateTimeUtil.ToLocalTime(operTime, "yyyy/MM/dd");
+
+
+ XmlNodeList listOverdue = root.SelectNodes("items/overdue");
+ string barcodes = "";
+ double totalPrice = 0;
+ foreach (XmlNode node in listOverdue)
+ {
+ string oneBarcode = DomUtil.GetAttr(node, "barcode");
+ if (barcodes != "")
+ barcodes += ",";
+ barcodes += oneBarcode;
+
+ string price = DomUtil.GetAttr(node, "price");
+ if (String.IsNullOrEmpty(price) == false && price.Length > 3)
+ {
+ double dPrice = Convert.ToDouble(price.Substring(3));
+ totalPrice += dPrice;
+ }
+ }
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //退款原因:{{reason.DATA}}
+ //退款金额:{{refund.DATA}}
+ //{{remark.DATA}}
+ var msgData = new ReturnPayTemplateData()
+ {
+ first = new TemplateDataItem("━━━━━━$━━━━━━", "#B8860B"), // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ dark golden rod//this._msgFirstLeft + "撤消交费成功!"
+ reason = new TemplateDataItem("撤消[" + barcodes + "]交费。", "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ refund = new TemplateDataItem("CNY" + totalPrice, "#000000"),
+ remark = new TemplateDataItem(this._msgRemark, "#CCCCCC")
+ };
+
+ // 发送模板消息
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ weiXinId,
+ dp2WeiXinService.C_Template_ReturnPay,
+ "#FF0000",
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送'撤消交费成功'通知异常:" + ex.Message);
+ }
+ }
+
+
+ return 1;
+ }
+
+ ///
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendPayMsg(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+ /*
+
+
+ 交费
+
+ amerce
+ amerce
+ R0000001
+ supervisor
+ Sun, 22 May 2016 19:28:52 +0800
+ ::1
+ 1.02
+
+ R0000001
+ 本科生
+ 张三
+ be13ecc5-6a9c-4400-9453-a072c50cede1
+ /
+ address
+ C12345
+ 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76
+ email:xietao@dp2003.com,weixinid:testwx2,testid:123456
+ 1234567890123
+ 13641016400
+
+
+
+
+
+
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ XmlNode nodeOperTime = root.SelectSingleNode("operTime");
+ if (nodeOperTime == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string operTime = DomUtil.GetNodeText(nodeOperTime);
+ operTime = DateTimeUtil.ToLocalTime(operTime, "yyyy/MM/dd");
+
+
+ XmlNodeList listOverdue = root.SelectNodes("items/overdue");
+ string barcodes = "";
+ double totalPrice = 0;
+ string reasons = "";
+ foreach (XmlNode node in listOverdue)
+ {
+ string oneBarcode = DomUtil.GetAttr(node, "barcode");
+ if (barcodes != "")
+ barcodes += ",";
+ barcodes += oneBarcode;
+
+ string price = DomUtil.GetAttr(node, "price");
+ if (String.IsNullOrEmpty(price) == false && price.Length > 3)
+ {
+ double dPrice = Convert.ToDouble(price.Substring(3));
+ totalPrice += dPrice;
+ }
+
+ string oneReason = DomUtil.GetAttr(node, "reason");
+ if (reasons != "")
+ reasons += ",";
+ reasons += oneReason;
+ }
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //订单号:{{keyword1.DATA}}
+ //缴费人:{{keyword2.DATA}}
+ //缴费金额:{{keyword3.DATA}}
+ //费用类型:{{keyword4.DATA}}
+ //缴费时间:{{keyword5.DATA}}
+ //{{remark.DATA}}
+ //您好,您已缴费成功!
+ //订单号:书名(册条码号)
+ //缴费人:张三
+ //缴费金额:¥100.00
+ //费用类型:违约
+ //缴费时间:2015-12-27 13:15
+ //如有疑问,请联系学校管理员,感谢您的使用!、
+ var msgData = new PayTemplateData()
+ {
+ first = new TemplateDataItem("++++++$++++++", "#556B2F"),//★★★★★★★★★★★★★★★ dark olive green//this._msgFirstLeft+"您已交费成功!"
+ keyword1 = new TemplateDataItem(barcodes, "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(patronName, "#000000"),
+ keyword3 = new TemplateDataItem("CNY" + totalPrice, "#000000"),
+ keyword4 = new TemplateDataItem(reasons, "#000000"),
+ keyword5 = new TemplateDataItem(operTime, "#000000"),
+ remark = new TemplateDataItem(this._msgRemark, "#CCCCCC")
+ };
+
+ // 发送模板消息
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ weiXinId,
+ dp2WeiXinService.C_Template_Pay,
+ "#FF0000",
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送交费成功通知异常:" + ex.Message);
+ }
+ }
+
+
+ return 1;
+ }
+
+ ///
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendReturnMsg(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+ /*
+
+
+ 还书成功
+
+ return
+ return
+ 0000001
+ R0000001
+ supervisor
+ Sun, 22 May 2016 13:11:33 +0800
+ ::1
+ 1.02
+ 4a9730b1-a6d7-4fd5-9e6f-57c074f73661
+
+ R0000001
+ 本科生
+ 张三
+
+
+ be13ecc5-6a9c-4400-9453-a072c50cede1
+
+
+ /
+ address
+ C12345
+
+
+ 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76
+ email:xietao@dp2003.com,weixinid:testwx2,testid:123456
+ 1234567890123
+ 13641016400
+
+
+
+ 602
+ 59b613c6-fe09-4280-8884-43f2b045c41c
+ 0000001
+ 流通库
+ $4.65
+ 普通
+ U664.121/N590
+ 船舶柴油机 / 聂云超主编. -- ISBN 7-81007-115-7 : $4.65
+
+
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ //0000001
+ //Sun, 22 May 2016 19:48:01 +0800
+ //31day
+ //Wed, 22 Jun 2016 12:00:00 +0800
+ XmlNode nodeItemBarcode = root.SelectSingleNode("itemBarcode");
+ if (nodeItemBarcode == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string itemBarcode = DomUtil.GetNodeText(nodeItemBarcode);
+
+ XmlNode nodeOperTime = root.SelectSingleNode("operTime");
+ if (nodeOperTime == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string operTime = DomUtil.GetNodeText(nodeOperTime);
+ operTime = DateTimeUtil.ToLocalTime(operTime, "yyyy/MM/dd");
+
+
+ XmlNode nodeSummary = root.SelectSingleNode("itemRecord/summary");
+ if (nodeSummary == null)
+ {
+ strError = "尚未定义itemRecord/summary节点";
+ return -1;
+ }
+ string summary = DomUtil.GetNodeText(nodeSummary);
+
+ // 检查是否有超期信息
+ string remark = "\n" + patronName + ",感谢及时归还,欢迎继续借书。";
+ XmlNodeList listOverdue = root.SelectNodes("patronRecord/overdues/overdue");
+ if (listOverdue.Count > 0)
+ {
+ remark = "\n"+patronName+",您有" + listOverdue.Count + "笔超期违约记录,请履行超期手续。";
+ }
+
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //书名:{{keyword1.DATA}}
+ //归还时间:{{keyword2.DATA}}
+ //借阅人:{{keyword3.DATA}}
+ //{{remark.DATA}}
+ //您好,你借阅的图书已确认归还.
+ //书名:算法导论
+ //归还时间:2015-10-10 12:14
+ //借阅人:李明
+ //欢迎继续借书!
+ var msgData = new ReturnTemplateData()
+ {
+ first = new TemplateDataItem("▉▊▋▍▎▉▊▋▍▎▉▊▋▍▎", "#00008B"), // dark blue//this._msgFirstLeft + "您借出的图书已确认归还。"
+ keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(operTime, "#000000"),
+ keyword3 = new TemplateDataItem(patronName, "#000000"),
+ remark = new TemplateDataItem(remark, "#CCCCCC")
+ };
+
+ // 发送模板消息
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ weiXinId,
+ dp2WeiXinService.C_Template_Return,
+ "#00008B",
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送还书成功通知异常:" + ex.Message);
+ }
+ }
+
+
+ return 1;
+ }
+
+ ///
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendBorrowMsg(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+ /*
+
+ 借书成功
+
+ borrow
+ borrow
+ R0000001
+ 0000001
+ Sun, 22 May 2016 19:48:01 +0800
+ 31day
+ Wed, 22 Jun 2016 12:00:00 +0800
+ $4.65
+ 0
+ 普通
+ supervisor
+ Sun, 22 May 2016 19:48:01 +0800
+ ::1
+ 1.02
+ 062724d8-80c1-4752-979a-b1cd548466be
+
+ R0000001
+ 本科生
+ 张三
+
+
+
+ be13ecc5-6a9c-4400-9453-a072c50cede1
+ /
+ address
+ C12345
+ 8aa41a9a-fb42-48c0-b9b9-9d6656dbeb76
+ email:xietao@dp2003.com,weixinid:testwx2,testid:123456
+ 1234567890123
+ 13641016400
+
+
+
+ 602
+ 59b613c6-fe09-4280-8884-43f2b045c41c
+ 0000001
+ 流通库
+ $4.65
+ 普通
+ U664.121/N590
+ R0000001
+ 本科生
+ 读者/1
+ Sun, 22 May 2016 19:48:01 +0800
+ 31day
+ Wed, 22 Jun 2016 12:00:00 +0800
+ supervisor
+ 船舶柴油机 / 聂云超主编. -- ISBN 7-81007-115-7 : $4.65
+
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ //0000001
+ //Sun, 22 May 2016 19:48:01 +0800
+ //31day
+ //Wed, 22 Jun 2016 12:00:00 +0800
+ XmlNode nodeItemBarcode = root.SelectSingleNode("itemBarcode");
+ if (nodeItemBarcode == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string itemBarcode = DomUtil.GetNodeText(nodeItemBarcode);
+
+ XmlNode nodeBorrowDate = root.SelectSingleNode("borrowDate");
+ if (nodeBorrowDate == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string borrowDate = DomUtil.GetNodeText(nodeBorrowDate);
+ borrowDate=DateTimeUtil.ToLocalTime(borrowDate, "yyyy/MM/dd");
+
+ XmlNode nodeBorrowPeriod = root.SelectSingleNode("borrowPeriod");
+ if (nodeBorrowPeriod == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string borrowPeriod = DomUtil.GetNodeText(nodeBorrowPeriod);
+
+ XmlNode nodeReturningDate = root.SelectSingleNode("returningDate");
+ if (nodeReturningDate == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string returningDate = DomUtil.GetNodeText(nodeReturningDate);
+ returningDate = DateTimeUtil.ToLocalTime(returningDate, "yyyy/MM/dd");
+
+
+ XmlNode nodeSummary = root.SelectSingleNode("itemRecord/summary");
+ if (nodeSummary == null)
+ {
+ strError = "尚未定义itemRecord/summary节点";
+ return -1;
+ }
+ string summary = DomUtil.GetNodeText(nodeSummary);
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //尊敬的XXX,恭喜您借书成功。
+ //图书书名:C#开发教程
+ //册条码号:C0000001
+ //借阅日期:2016-5-27
+ //借阅期限:31
+ //应还日期:2016-6-27
+ //祝您阅读愉快,欢迎再借。
+ var msgData = new BorrowTemplateData()
+ {
+ first = new TemplateDataItem("▉▊▋▍▎▉▊▋▍▎▉▊▋▍▎", "#006400"), // dark green //this._msgFirstLeft + "恭喜您借书成功。"
+ keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(itemBarcode, "#000000"),
+ keyword3 = new TemplateDataItem(borrowDate, "#000000"),
+ keyword4 = new TemplateDataItem(borrowPeriod, "#000000"),
+ keyword5 = new TemplateDataItem(returningDate, "#000000"),
+ remark = new TemplateDataItem("\n"+patronName+",祝您阅读愉快,欢迎再借。", "#CCCCCC")
+ };
+
+ // 发送模板消息
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ weiXinId,
+ dp2WeiXinService.C_Template_Borrow,
+ "#006400", //FF0000
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送借书成功通知异常:" + ex.Message);
+ }
+ }
+ return 1;
+ }
+
+
+
+ ///
+ /// 发送预约通知
+ ///
+ ///
+ ///
+ ///
+ /// -1 出错,格式出错或者发送模板消息出错
+ /// 0 未绑定微信id
+ /// 1 成功
+ ///
+ private int SendArrived(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+
+
+
+ /*
+ body元素里面是预约到书通知记录(注意这是一个字符串,需要另行装入一个XmlDocument解析),其格式如下:
+
+
+ 预约到书通知
+ 0000001
+
+false
+ /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
+
+
+
+ */
+
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ XmlNode root = bodyDom.DocumentElement;
+ //false
+ // 2天
+ // 2016/5/17 10:10:59
+ // 取出预约消息
+ XmlNode nodeSummary = root.SelectSingleNode("summary");
+ if (nodeSummary == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string summary = DomUtil.GetNodeText(nodeSummary);
+
+ XmlNode nodeReserveTime = root.SelectSingleNode("reserveTime");
+ if (nodeReserveTime == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string reserveTime = DomUtil.GetNodeText(nodeReserveTime);
+
+ XmlNode nodeToday = root.SelectSingleNode("today");
+ if (nodeToday == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string today = DomUtil.GetNodeText(nodeToday);
+
+ // 是否在架
+ XmlNode nodeOnShelf = root.SelectSingleNode("onShelf");
+ if (nodeOnShelf == null)
+ {
+ strError = "尚未定义节点";
+ return -1;
+ }
+ string onShelf = DomUtil.GetNodeText(nodeOnShelf);
+ bool bOnShelf = false;
+ if (onShelf == "true")
+ bOnShelf = true;
+
+ //string first = this._msgFirstLeft+"我们很高兴地通知您,您预约的图书到了,请尽快来图书馆办理借书手续。";
+ string end = "\n" + patronName + ",您预约的图书到了,请尽快来图书馆办理借书手续,请尽快来图书馆办理借书手续。如果您未能在保留期限内来馆办理借阅手续,图书馆将把优先借阅权转给后面排队等待的预约者,或做归架处理。";
+ if (bOnShelf == true)
+ {
+ //first = this._msgFirstLeft + "我们很高兴地通知您,您预约的图书已经在架上,请尽快来图书馆办理借书手续。";
+ end = "\n" + patronName + ",您预约的图书已经在架上,请尽快来图书馆办理借书手续。如果您未能在保留期限内来馆办理借阅手续,图书馆将把优先借阅权转给后面排队等待的预约者,或允许其他读者借阅。";
+ }
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //图书书名:{{keyword1.DATA}}
+ //到书日期:{{keyword2.DATA}}
+ //保留期限:{{keyword3.DATA}}
+ //{{remark.DATA}}
+ var msgData = new ArrivedTemplateData()
+ {
+ first = new TemplateDataItem("▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉", "#FF8C00"),// dark orange yellow #FFFF00
+ keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(today, "#000000"),
+ keyword3 = new TemplateDataItem("保留" + reserveTime, "#000000"),
+ remark = new TemplateDataItem(end, "#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,
+ dp2WeiXinService.C_Template_Arrived,
+ "#FF0000",
+ "",//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者" + patronName + "发送预约到书通知异常:" + ex.Message);
+ }
+ }
+
+
+ return 1;
+ }
+
+ ///
+ /// 发送超期通知
+ ///
+ ///
+ private int SendCaoQi(XmlDocument bodyDom, out string strError)
+ {
+ strError = "";
+
+ /*
+
+ 超期通知
+
+
+
+ 您借阅的下列书刊:
+船舶柴油机 / 聂云超主编. -- ISBN 7-... 应还日期: 2016/5/18 已超期 31 天
+
+ ...
+
+
+
+//overdueType是超期类型,overdue表示超期,warning表示即将超期。
+ */
+
+ // 得到绑定的微信id
+ string patronName = "";
+ List weiXinIdList = this.GetWeiXinIds(bodyDom, out patronName);
+ if (weiXinIdList.Count == 0)
+ {
+ strError = "未绑定微信id";
+ return 0;
+ }
+
+ 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");
+
+ //overdueType是超期类型,overdue表示超期,warning表示即将超期。
+ string templateId = "";
+ string overdueType = DomUtil.GetAttr(item, "overdueType");
+ //string first = "";
+ string end = "";
+ if (overdueType == "overdue")
+ {
+ templateId = dp2WeiXinService.C_Template_CaoQi;
+ //first = this._msgFirstLeft+"您借出的图书已超期,请尽快归还。";
+ end = "\n"+patronName+",您借出的图书已超期,请尽快归还。";
+ }
+ else if (overdueType == "warning")
+ {
+ templateId = dp2WeiXinService.C_Template_DaoQi;
+ // first = this._msgFirstLeft+"您借出的图书即将到期,请注意不要超期,留意归还。";
+ end = "\n" + patronName + ",您借出的图书即将到期,请注意不要超期,留意归还。";
+ }
+ else
+ {
+ strError ="overdueType属性值[]不合法。";
+ return -1;//整个不处理 //continue;
+ }
+
+ foreach (string weiXinId in weiXinIdList)
+ {
+ try
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+
+ //{{first.DATA}}
+ //图书书名:{{keyword1.DATA}}
+ //应还日期:{{keyword2.DATA}}
+ //超期天数:{{keyword3.DATA}}
+ //{{remark.DATA}}
+
+ //{{first.DATA}}
+ //图书书名:{{keyword1.DATA}}
+ //归还日期:{{keyword2.DATA}}
+ //剩余天数:{{keyword3.DATA}}
+ //{{remark.DATA}}
+ //超期和到期格式一样,就不用再建一个TemplateData类了
+ var msgData = new ArrivedTemplateData()
+ {
+ first = new TemplateDataItem("▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉", "#FFFF00"), //yellow #
+
+ keyword1 = new TemplateDataItem(summary, "#000000"),//text.ToString()),// "请让我慢慢长大"),
+ keyword2 = new TemplateDataItem(timeReturning, "#000000"),
+ keyword3 = new TemplateDataItem(overdue, "#000000"),
+ remark = new TemplateDataItem(end, "#CCCCCC")//"\n点击下方”详情“查看个人详细信息。"
+ };
+
+ 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,
+ templateId,
+ "#FF0000",
+ detailUrl,//不出现详细了
+ msgData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+ }
+ catch (Exception ex)
+ {
+ this.WriteErrorLog("给读者"+patronName+"发送超期通知异常:"+ex.Message);
+ }
+ }
+ }
+
+ // 发送成功
+ return 1;
+ }
+
+ ///
+ /// 获取读者记录中绑定的微信id,返回数组
+ ///
+ ///
+ ///
+ ///
+ private 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) == dp2WeiXinService.C_WeiXinIdPrefix)
+ {
+ string weiwinId = oneEmail.Substring(9).Trim();
+ if (weiwinId != "")
+ weiXinIdList.Add(weiwinId);
+ }
+ }
+ return weiXinIdList;
+ }
+
+ #endregion
+
+ #region 短信接口
+
+ public List m_externalMessageInterfaces = null;
+
+ // 初始化扩展的消息接口
+ /*
+
+
+
+ */
+ // parameters:
+ // return:
+ // -1 出错
+ // 0 当前没有配置任何扩展消息接口
+ // 1 成功初始化
+ public int InitialExternalMessageInterfaces(XmlDocument dom, out string strError)
+ {
+ strError = "";
+
+ this.m_externalMessageInterfaces = null;
+ XmlNode root = dom.DocumentElement.SelectSingleNode("externalMessageInterface");
+ if (root == null)
+ {
+ strError = "在weixin.xml中没有找到元素";
+ return 0;
+ }
+
+ this.m_externalMessageInterfaces = new List();
+
+ XmlNodeList nodes = root.SelectNodes("interface");
+ foreach (XmlNode node in nodes)
+ {
+ string strType = DomUtil.GetAttr(node, "type");
+ if (String.IsNullOrEmpty(strType) == true)
+ {
+ strError = "元素未配置type属性值";
+ return -1;
+ }
+
+ string strAssemblyName = DomUtil.GetAttr(node, "assemblyName");
+ if (String.IsNullOrEmpty(strAssemblyName) == true)
+ {
+ strError = "元素未配置assemblyName属性值";
+ return -1;
+ }
+
+ MessageInterface message_interface = new MessageInterface();
+ message_interface.Type = strType;
+ message_interface.Assembly = Assembly.Load(strAssemblyName);
+ if (message_interface.Assembly == null)
+ {
+ strError = "名字为 '" + strAssemblyName + "' 的Assembly加载失败...";
+ return -1;
+ }
+
+ Type hostEntryClassType = ScriptManager.GetDerivedClassType(
+ message_interface.Assembly,
+ "DigitalPlatform.Interfaces.ExternalMessageHost");
+ if (hostEntryClassType == null)
+ {
+ strError = "名字为 '" + strAssemblyName + "' 的Assembly中未找到 DigitalPlatform.Interfaces.ExternalMessageHost类的派生类,初始化扩展消息接口失败...";
+ return -1;
+ }
+
+ message_interface.HostObj = (ExternalMessageHost)hostEntryClassType.InvokeMember(null,
+ BindingFlags.DeclaredOnly |
+ BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Instance | BindingFlags.CreateInstance, null, null,
+ null);
+ if (message_interface.HostObj == null)
+ {
+ strError = "创建 type 为 '" + strType + "' 的 DigitalPlatform.Interfaces.ExternalMessageHost 类的派生类的对象(构造函数)失败,初始化扩展消息接口失败...";
+ return -1;
+ }
+
+ message_interface.HostObj.App = this;
+
+ this.m_externalMessageInterfaces.Add(message_interface);
+ }
+
+ return 1;
+ }
+
+ public MessageInterface GetMessageInterface(string strType)
+ {
+ // 2012/3/29
+ if (this.m_externalMessageInterfaces == null)
+ return null;
+
+ foreach (MessageInterface message_interface in this.m_externalMessageInterfaces)
+ {
+ if (message_interface.Type == strType)
+ return message_interface;
+ }
+
+ return null;
+ }
+
+ #endregion
+
+ #region 本方账号登录
+ void _channels_Login(object sender, LoginEventArgs e)
+ {
+ MessageConnection connection = sender as MessageConnection;
+
+ e.UserName = GetUserName();
+ if (string.IsNullOrEmpty(e.UserName) == true)
+ throw new Exception("尚未指定用户名,无法进行登录");
+
+ e.Password = GetPassword();
+ e.Parameters = "";
+
+ // TODO: 登录如果失败,界面会有提示么?
+ }
+
+ string GetUserName()
+ {
+ return this.userName;
+ }
+ string GetPassword()
+ {
+ return this.password;
+ }
+
+ #endregion
+
+
+
+ #region 绑定解绑
+
+ public List GetBindInfo(string weixinId)
+ {
+ List list = new List();
+
+ // 目前只支持从数据库中查找
+ list = WxUserDatabase.Current.GetByWeixinId(weixinId);
+
+
+ return list;
+ }
+
+ public int ResetPassword(string remoteUserName,
+ string strLibraryCode,
+ string name,
+ string tel,
+ out string strError)
+ {
+ strError = "";
+ string resultXml = "";
+ string patronParam = "style=returnMessage,"
+ + "queryword=NB:" + name + "|,"
+ + "tel=" + tel + ","
+ + "name=" + name;
+ CancellationToken cancel_token = new CancellationToken();
+
+ string id = Guid.NewGuid().ToString();
+ CirculationRequest request = new CirculationRequest(id,
+ "resetPassword",
+ patronParam,
+ "",//this.textBox_circulation_item.Text,
+ "",//this.textBox_circulation_style.Text,
+ "",//this.textBox_circulation_patronFormatList.Text,
+ "",//this.textBox_circulation_itemFormatList.Text,
+ "");//this.textBox_circulation_biblioFormatList.Text);
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ "").Result;
+ CirculationResult result = connection.CirculationAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 10), // 10 秒
+ cancel_token).Result;
+ if (result.Value == -1)
+ {
+ strError = "出错:" + result.ErrorInfo;
+ return -1;
+ }
+
+ if (result.Value == 0)
+ {
+ if (result.String == "NotFound")
+ {
+ strError = "操作未成功:读者 " + name + " 尚未在图书馆账户中注册过手机号码,因此无法找回密码。请先去图书馆出纳台请工作人员帮助注册一下手机号码。";
+ }
+ else
+ {
+ strError = "操作未成功:" + result.ErrorInfo;
+ }
+
+ return 0;
+ }
+
+ resultXml = result.PatronBarcode;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+
+ // 发送短信
+ string strMessageTemplate = "";
+ MessageInterface external_interface = this.GetMessageInterface("sms");
+ if (string.IsNullOrEmpty(strMessageTemplate) == true)
+ {
+ //strMessageTemplate = "%name% 您好!\n您的读者帐户(证条码号为 %barcode%)已设临时密码 %temppassword%,在 %period% 内登录会成为正式密码";
+ strMessageTemplate = "%name% 您好!密码为 %temppassword%。一小时内有效。";
+ }
+ /*
+ DomUtil.SetElementText(node, "tel", strTelParam);
+ DomUtil.SetElementText(node, "barcode", strBarcode);
+ DomUtil.SetElementText(node, "name", strName);
+ DomUtil.SetElementText(node, "tempPassword", strReaderTempPassword);
+ DomUtil.SetElementText(node, "expireTime", expire.ToLongTimeString());
+ DomUtil.SetElementText(node, "period", "一小时");
+ DomUtil.SetElementText(node, "refID", strRefID);
+ */
+ /*
+
+
+ 13862157150
+ R00001
+ 任延华
+ 586284
+ 13:24:57
+ 一小时
+ 63aeb890-8936-4471-bfc5-8e72d5c7fe94
+
+
+ */
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(resultXml);
+ XmlNode nodePatron = dom.DocumentElement.SelectSingleNode("patron");
+ string strRefID = DomUtil.GetNodeText(nodePatron.SelectSingleNode("refID"));
+ string strTel = DomUtil.GetNodeText(nodePatron.SelectSingleNode("tel"));
+
+ string strBarcode = DomUtil.GetNodeText(nodePatron.SelectSingleNode("barcode"));
+ string strName = DomUtil.GetNodeText(nodePatron.SelectSingleNode("name"));
+ string strReaderTempPassword = DomUtil.GetNodeText(nodePatron.SelectSingleNode("tempPassword"));
+ string expireTime = DomUtil.GetNodeText(nodePatron.SelectSingleNode("expireTime"));
+ string period = DomUtil.GetNodeText(nodePatron.SelectSingleNode("period"));
+
+ string strBody = strMessageTemplate.Replace("%barcode%", strBarcode)
+ .Replace("%name%", strName)
+ .Replace("%temppassword%", strReaderTempPassword)
+ .Replace("%expiretime%", expireTime)
+ .Replace("%period%", period);
+ // string strBody = "读者(证条码号) " + strBarcode + " 的帐户密码已经被重设为 " + strReaderNewPassword + "";
+ int nRet = 0;
+ // 向手机号码发送短信
+ {
+ // 得到高级xml
+ string strXml = "" + strTel + "";
+ // 发送消息
+ try
+ {
+
+ // 发送一条消息
+ // parameters:
+ // strPatronBarcode 读者证条码号
+ // strPatronXml 读者记录XML字符串。如果需要除证条码号以外的某些字段来确定消息发送地址,可以从XML记录中取
+ // strMessageText 消息文字
+ // strError [out]返回错误字符串
+ // return:
+ // -1 发送失败
+ // 0 没有必要发送
+ // >=1 发送成功,返回实际发送的消息条数
+ nRet = external_interface.HostObj.SendMessage(
+ strBarcode,
+ strXml,
+ strBody,
+ strLibraryCode,
+ out strError);
+ if (nRet == -1 || nRet == 0)
+ return nRet;
+ }
+ catch (Exception ex)
+ {
+ strError = external_interface.Type + " 类型的外部消息接口Assembly中SendMessage()函数抛出异常: " + ex.Message;
+ nRet = -1;
+ }
+ if (nRet == -1)
+ {
+ strError = "向读者 '" + strBarcode + "' 发送" + external_interface.Type + " message时出错: " + strError;
+
+ this.WriteErrorLog(strError);
+ return -1;
+ }
+ }
+
+ return 1;
+
+ ERROR1:
+ return -1;
+ }
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// -1 出错
+ /// 0 成功
+ ///
+ public int Bind(string remoteUserName,
+ string libCode,
+ string strFullWord,
+ string strPassword,
+ string strWeiXinId,
+ out WxUserItem userItem,
+ out string strReaderBarcode,
+ out string strError)
+ {
+ userItem = null;
+ strError = "";
+ strReaderBarcode = "";
+ long lRet = -1;
+
+
+ CancellationToken cancel_token = new CancellationToken();
+
+ string fullWeixinId = dp2WeiXinService.C_WeiXinIdPrefix + strWeiXinId;
+ string id = Guid.NewGuid().ToString();
+ BindPatronRequest request = new BindPatronRequest(id,
+ "bind",
+ strFullWord,
+ strPassword,
+ fullWeixinId,
+ "multiple",//single
+ "xml");
+
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName).Result;
+
+
+ BindPatronResult result = connection.BindPatronAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+
+ if (result.Value == -1)
+ {
+ strError = result.ErrorInfo;
+ return -1;
+ }
+
+ string xml = result.Results[0];
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(xml);
+
+ // 绑定成功,把读者证条码记下来,用于续借 2015/11/7,不要用strbarcode变量,因为可能做的大小写转换
+ strReaderBarcode = DomUtil.GetNodeText(dom.DocumentElement.SelectSingleNode("barcode"));
+
+ // 将关系存到mongodb库
+ string name = "";
+ XmlNode node = dom.DocumentElement.SelectSingleNode("name");
+ if (node != null)
+ name = DomUtil.GetNodeText(node);
+ string refID = "";
+ node = dom.DocumentElement.SelectSingleNode("refID");
+ if (node != null)
+ refID = DomUtil.GetNodeText(node);
+
+ // 找到库中对应的记录
+ userItem = WxUserDatabase.Current.GetOneOrEmptyPatron(strWeiXinId, libCode, strReaderBarcode);
+ if (userItem == null)
+ {
+ LibItem lib = LibDatabase.Current.GetLibByLibCode(libCode);
+
+
+ userItem = new WxUserItem();
+ userItem.weixinId = strWeiXinId;
+ userItem.libCode = libCode;
+ userItem.libUserName = remoteUserName;
+ userItem.libName = lib.libName;
+ userItem.readerBarcode = strReaderBarcode;
+ userItem.readerName = name;
+ userItem.xml = xml;
+ userItem.refID = refID;
+ userItem.createTime = DateTimeUtil.DateTimeToString(DateTime.Now);
+ userItem.updateTime = userItem.createTime;
+ userItem.isActive = 1;
+ userItem.fullWord = strFullWord;
+ userItem.password = strPassword;
+ WxUserDatabase.Current.Add(userItem);
+ }
+ else
+ {
+ userItem.readerBarcode = strReaderBarcode;
+ userItem.readerName = name;
+ userItem.xml = xml;
+ userItem.refID = refID;
+ userItem.updateTime = DateTimeUtil.DateTimeToString(DateTime.Now);
+ userItem.isActive = 1;
+ userItem.fullWord = strFullWord;
+ userItem.password = strPassword;
+ lRet = WxUserDatabase.Current.Update(userItem);
+ }
+ // 置为活动状态
+ WxUserDatabase.Current.SetActive(userItem);
+
+ // 发送绑定成功的客服消息
+ string accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+ var testData = new BindTemplateData()
+ {
+ first = new TemplateDataItem("恭喜您!您已成功绑定图书馆账号。", "#000000"),
+ keyword1 = new TemplateDataItem(userItem.readerName + "(" + userItem.readerBarcode + ")", "#000000"),
+ keyword2 = new TemplateDataItem("图书馆[" + userItem.libName + "]", "#000000"),
+ remark = new TemplateDataItem("您可以直接通过微信公众号访问图书馆,进行信息查询,预约续借等功能。如需解绑,请在“绑定账号”菜单操作。", "#CCCCCC")
+ };
+
+ // 详细转到账户管理界面
+ string detailUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx57aa3682c59d16c2&redirect_uri=http%3a%2f%2fdp2003.com%2fdp2weixin%2fAccount%2fIndex&response_type=code&scope=snsapi_base&state=dp2weixin#wechat_redirect";
+ var result1 = TemplateApi.SendTemplateMessage(accessToken,
+ strWeiXinId,
+ dp2WeiXinService.C_Template_Bind,
+ "#FF0000",
+ detailUrl,//k"dp2003.com/dp2weixin/patron/index", // todo注意这里是否需要oauth接口,想着消息既然是从web发过来了,立即点进去还有session信息存在,但时间长了session失效就没有信息了
+ testData);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ return -1;
+ }
+
+ return 0;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+
+ ERROR1:
+ return -1;
+ }
+
+
+
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// -1 出错
+ /// 0 成功
+ ///
+ public int Unbind(string userId,
+ out string strError)
+ {
+ strError = "";
+
+ //string remoteUserName,
+ // string libCode,
+ // string strBarcode,
+ // string strWeiXinId,
+
+ WxUserItem userItem = WxUserDatabase.Current.GetById(userId);
+ if (userItem == null)
+ {
+ strError = "绑定账号未找到";
+ return -1;
+ }
+
+
+ // 调点对点解绑接口
+ string fullWeixinId = dp2WeiXinService.C_WeiXinIdPrefix + userItem.weixinId;
+ CancellationToken cancel_token = new CancellationToken();
+ string id = Guid.NewGuid().ToString();
+ BindPatronRequest request = new BindPatronRequest(id,
+ "unbind",
+ userItem.readerBarcode,
+ "",//password todo
+ fullWeixinId,
+ "multiple,null_password",
+ "xml");
+ try
+ {
+ // 得到连接
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ userItem.libUserName).Result;
+
+ BindPatronResult result = connection.BindPatronAsync(
+ userItem.libUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ if (result.Value == -1)
+ {
+ //strError = result.ErrorInfo;
+ //return -1;
+ }
+
+ // 删除mongodb库的记录
+ WxUserDatabase.Current.Delete(userId);
+
+ // 发送解绑消息
+ string accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+ var data = new UnBindTemplateData()
+ {
+ first = new TemplateDataItem("您已成功对图书馆账号解除绑定。", "#000000"),
+ keyword1 = new TemplateDataItem(userItem.readerName + "(" + userItem.readerBarcode + ")", "#000000"),
+ keyword2 = new TemplateDataItem("图书馆[" + userItem.libName + "]", "#000000"),
+ remark = new TemplateDataItem("\n您现在不能访问该图书馆信息了,如需访问,请重新绑定。", "#CCCCCC")
+ };
+ SendTemplateMessageResult result1 = TemplateApi.SendTemplateMessage(accessToken,
+ userItem.weixinId,
+ dp2WeiXinService.C_Template_UnBind,
+ "#FF0000",
+ "",//k"dp2003.com/dp2weixin/patron/index", // todo注意这里是否需要oauth接口,想着消息既然是从web发过来了,立即点进去还有session信息存在,但时间长了session失效就没有信息了
+ data);
+ if (result1.errcode != 0)
+ {
+ strError = result1.errmsg;
+ 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 long SearchOnePatronByWeiXinId(string remoteUserName,
+ string libCode,
+ string strWeiXinId,
+ out string strBarcode,
+ out string strError)
+ {
+ strError = "";
+ strBarcode = "";
+
+ // 从mongodb中检查是否绑定了用户
+ WxUserItem userItem = WxUserDatabase.Current.GetActiveOrFirst(strWeiXinId, libCode);
+ if (userItem == null)
+ {
+ strError = "异常的情况,未怎么图书馆时不应走到SearchPatronByWeiXinId函数。";
+ return -1;
+ }
+
+ // mongodb存在
+ if (String.IsNullOrEmpty(userItem.readerBarcode) == false)
+ {
+ strBarcode = userItem.readerBarcode;
+ return 1;
+ }
+
+ // 从远程dp2library中查
+ string strWord = dp2WeiXinService.C_WeiXinIdPrefix + strWeiXinId;
+ CancellationToken cancel_token = new CancellationToken();
+ string id = Guid.NewGuid().ToString();
+ SearchRequest request = new SearchRequest(id,
+ "searchPatron",
+ "<全部>",
+ strWord,
+ "email",
+ "left",
+ "wx-patron",
+ "id,cols",
+ 1000,
+ 0,
+ C_Search_MaxCount);
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName).Result;
+
+ SearchResult result = connection.SearchAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ if (result.ResultCount == -1)
+ {
+ strError = result.ErrorInfo;
+ return -1;
+ }
+ if (result.ResultCount == 0)
+ return 0;
+
+ // 找到对应的读者记录
+ if (result.ResultCount > 0)
+ {
+ LibItem libItem = LibDatabase.Current.GetLibByLibCode(libCode);
+ string libName = libItem.libName;
+ for (int i = 0; i < result.ResultCount; i++)
+ {
+ // 可能会检索出多笔记录,先取第一笔 todo
+ string strXml = result.Records[i].Data;
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(strXml);
+ string strTempBarcode = DomUtil.GetNodeText(dom.DocumentElement.SelectSingleNode("barcode"));
+
+ // 更新到mongodb库
+ string name = "";
+ XmlNode node = dom.DocumentElement.SelectSingleNode("name");
+ if (node != null)
+ name = DomUtil.GetNodeText(node);
+ string refID = "";
+ node = dom.DocumentElement.SelectSingleNode("refID");
+ if (node != null)
+ refID = DomUtil.GetNodeText(node);
+
+ if (i == 0)
+ {
+ userItem.readerBarcode = strTempBarcode;
+ userItem.readerName = name;
+ userItem.xml = strXml;
+ userItem.refID = refID;
+ userItem.updateTime = DateTimeUtil.DateTimeToString(DateTime.Now);
+ WxUserDatabase.Current.Update(userItem);
+ //将第一笔设为活动状态
+ WxUserDatabase.Current.SetActive(userItem);
+ //返回的strBarcode //todo refID
+ strBarcode = strTempBarcode;
+ }
+ else
+ {
+ userItem = new WxUserItem();
+ userItem.weixinId = strWeiXinId;
+ userItem.libCode = libCode;
+ userItem.libUserName = remoteUserName;
+ userItem.libName = libName;
+ userItem.readerBarcode = strTempBarcode;
+ userItem.readerName = name;
+ userItem.xml = strXml;
+ userItem.refID = refID;
+ userItem.createTime = DateTimeUtil.DateTimeToString(DateTime.Now);
+ userItem.updateTime = userItem.createTime;
+ WxUserDatabase.Current.Add(userItem);
+ }
+ }
+
+ return 1;
+ }
+
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+ ERROR1:
+ return -1;
+ }
+
+
+ #endregion
+
+ #region 检索书目
+
+ ///
+ /// 检索书目
+ ///
+ ///
+ ///
+ ///
+ ///
+ public long SearchBiblio(string remoteUserName,
+ string strFrom,
+ string strWord,
+ out List records,
+ out string strError)
+ {
+ strError = "";
+ records = new List();
+
+ long start = 0;
+ long count = 10;
+ int connIndex = 0;
+ try
+ {
+
+ CancellationToken cancel_token = new CancellationToken();
+ string id = Guid.NewGuid().ToString();
+ SearchRequest request = new SearchRequest(id,
+ "searchBiblio",
+ "",
+ strWord,
+ strFrom,
+ "middle",
+ "weixin",
+ "id,cols",
+ C_Search_MaxCount, //最大数量
+ start, //每次获取范围
+ count);
+
+ int tempNo = connIndex;// connIndex % 2;
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName).Result; //+ tempNo todo
+ connIndex++;
+
+ SearchResult result = connection.SearchAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ if (result.ResultCount == -1)
+ {
+ strError = "检索出错:" + result.ErrorInfo;
+ return -1;
+ }
+ if (result.ResultCount == 0)
+ {
+ strError = "未命中";
+ return 0;
+ }
+
+
+ List resultPathList = new List();
+ for (int i = 0; i < result.Records.Count; i++)
+ {
+ string xml = result.Records[i].Data;
+ /*请让我慢慢长大
+ * 吴蓓著
+ * 天津教育出版社
+ * 2009
+ * G61-53
+ * 儿童教育儿童教育
+ *
+ * 978-7-5309-5335-8*/
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(xml);
+ string name = DomUtil.GetNodeText(dom.DocumentElement.SelectSingleNode("col"));
+ string path = result.Records[i].RecPath;
+ int nIndex = path.IndexOf("@");
+ path = path.Substring(0, nIndex);
+
+ BiblioRecord record = new BiblioRecord();
+ record.recPath = path;
+ record.name = name;
+ record.no = (i+start + 1).ToString();//todo 注意下一页的时候
+ record.libUserName = remoteUserName;
+ records.Add(record);
+ }
+
+ if (result.Records.Count > 0 && start+result.Records.Count < result.ResultCount)
+ {
+ start += result.Records.Count;
+ //goto REDO1;
+ }
+
+ return records.Count;
+ }
+ catch (AggregateException ex)
+ {
+ strError = ex.Message;
+ return -1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ return -1;
+ }
+
+ }
+
+ public BiblioRecordResult GetBiblioDetail(string remoteUserName,
+ string biblioPath)
+ {
+ BiblioRecordResult result = new BiblioRecordResult();
+ result.errorCode = 0;
+ result.biblioPath = biblioPath;
+
+ DateTime start_time = DateTime.Now;
+
+ try
+ {
+ string strError="";
+ int nRet = 0;
+ TimeSpan time_length = DateTime.Now - start_time;
+ string logInfo = "";
+
+ // 取出summary
+ this.WriteLog("开始获取summary");
+ string strSummary = "";
+ nRet = this.GetBiblioSummary(remoteUserName, biblioPath, out strSummary, out strError);
+ if (nRet == -1 || nRet == 0)
+ {
+ result.errorCode = -1;
+ result.errorInfo = strError;
+ return result;
+ }
+ result.summary = strSummary;
+ time_length = DateTime.Now - start_time;
+ string info = "获取[" + biblioPath + "]的summary信息完毕 time span: " + time_length.TotalSeconds.ToString() + " secs";
+ this.WriteLog(info);
+
+ //Thread.Sleep(1000);
+
+ // 取item
+ this.WriteLog("开始获取items");
+ List itemList = null;
+ nRet = (int)this.GetItemInfo(remoteUserName, biblioPath, out itemList, out strError);
+ if (nRet == -1) //0的情况表示没有册,不是错误
+ {
+ result.errorCode = -1;
+ result.errorInfo = strError;
+ return result;
+ }
+
+ // 计算用了多少时间
+ time_length = DateTime.Now - start_time;
+ logInfo = "获取[" + biblioPath + "]的item信息完毕 time span: " + time_length.TotalSeconds.ToString() + " secs";
+ this.WriteLog(logInfo);
+
+ result.itemList = itemList;
+ result.errorCode = 1;
+ return result;
+ }
+ catch (Exception ex)
+ {
+ result.errorCode = -1;
+ result.errorInfo = ex.Message;
+ return result;
+ }
+
+
+
+ #region delete
+ /*
+ string strError = "";
+ CancellationToken cancel_token = new CancellationToken();
+ // 获取书目记录
+ string id1 = Guid.NewGuid().ToString();
+ SearchRequest request1 = new SearchRequest(id1,
+ "getBiblioInfo",
+ "<全部>",
+ biblioPath,
+ "",
+ "",
+ "",
+ "summary",
+ 1,
+ 0,
+ -1);
+ // 获取下属记录
+ string id2 = Guid.NewGuid().ToString();
+ SearchRequest request2 = new SearchRequest(id2,
+ "getItemInfo",
+ "entity",
+ biblioPath,
+ "",
+ "",
+ "",
+ "opac",
+ 50,
+ 0,
+ 10);
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName).Result;
+
+ Task task1 = connection.SearchAsync(
+ remoteUserName,
+ request1,
+ new TimeSpan(0, 1, 0),
+ cancel_token);
+
+ Task task2 = connection.SearchAsync(
+ remoteUserName,
+ request2,
+ new TimeSpan(0, 1, 0),
+ cancel_token);
+
+ Task[] tasks = new Task[2];
+ tasks[0] = task1;
+ tasks[1] = task2;
+ Task.WaitAll(tasks);
+
+ if (task1.Result.ResultCount == -1)
+ {
+ strError = "获取摘要出错:" + task1.Result.ErrorInfo;
+ goto ERROR1;
+ }
+ if (task1.Result.ResultCount == 0)
+ {
+ result.errorCode = 0;
+ result.errorInfo = "获取Summary时未命中";
+ return result;
+ }
+ result.summary = task1.Result.Records[0].Data;
+
+ if (task2.Result.ResultCount == -1)
+ {
+ strError = "获取册出错:" + task2.Result.ErrorInfo;
+ goto ERROR1;
+ }
+ // 没有册的情况,不算出错
+ //if (task2.Result.ResultCount == 0)
+ //{
+ // result.errorCode = 0;
+ // result.errorInfo = "获取册时未命中";
+ // return result;
+ //}
+
+ result.itemList = new List();
+ for (int i = 0; i < task2.Result.Records.Count; i++)
+ {
+ BiblioItem item = new BiblioItem();
+
+ string xml = task2.Result.Records[i].Data;
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(xml);
+
+ string strBarcode = DomUtil.GetElementText(dom.DocumentElement, "barcode");
+ string strRefID = DomUtil.GetElementText(dom.DocumentElement, "refID");
+ // 册条码号
+ string strViewBarcode = "";
+ if (string.IsNullOrEmpty(strBarcode) == false)
+ strViewBarcode = strBarcode;
+ else
+ strViewBarcode = "refID:" + strRefID; //"@refID:"
+ item.barcode = strViewBarcode;
+
+ //状态
+ item.state = DomUtil.GetElementText(dom.DocumentElement, "state");
+ // 馆藏地
+ item.location = DomUtil.GetElementText(dom.DocumentElement, "location");
+ // 索引号
+ item.accessNo = DomUtil.GetElementText(dom.DocumentElement, "accessNo");
+
+ // 出版日期
+ item.publishTime = DomUtil.GetElementText(dom.DocumentElement, "publishTime");
+ // 价格
+ item.price= DomUtil.GetElementText(dom.DocumentElement, "price");
+ // 注释
+ item.comment = DomUtil.GetElementText(dom.DocumentElement, "comment");
+
+ // 借阅情况
+ string strBorrowInfo = "借阅情况:在架";
+
+ // R00001
+ //教职工
+ //读者/1
+ //Sun, 17 Apr 2016 23:57:40 +0800
+ //31day
+ //Wed, 18 May 2016 12:00:00 +0800
+
+ string strBorrower = DomUtil.GetElementText(dom.DocumentElement, "borrower");
+ string borrowDate = DateTimeUtil.ToLocalTime(DomUtil.GetElementText(dom.DocumentElement,
+ "borrowDate"), "yyyy/MM/dd");
+ string borrowPeriod = DomUtil.GetElementText(dom.DocumentElement, "borrowPeriod");
+ if (string.IsNullOrEmpty(strBorrower) == false)
+ strBorrowInfo = "借阅者:*** 借阅时间:" + borrowDate + " 借期:" + borrowPeriod;
+ item.borrowInfo = strBorrower;
+
+ // 加到集合里
+ result.itemList.Add(item);
+ }
+
+ result.errorCode = 1;
+
+ return result;
+
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+
+ ERROR1:
+ result.errorCode = -1;
+ result.errorInfo = strError;
+ return result;
+ */
+
+ #endregion
+ }
+
+ private int GetBiblioSummary(string remoteUserName,
+ string biblioPath,
+ out string summary,
+ out string strError)
+ {
+ summary = "";
+ strError = "";
+
+ CancellationToken cancel_token = new CancellationToken();
+ string id = "1-summary";//Guid.NewGuid().ToString();
+ SearchRequest request = new SearchRequest(id,
+ "getBiblioInfo",
+ "<全部>",
+ biblioPath,
+ "",
+ "",
+ "",
+ "summary",
+ 1,
+ 0,
+ -1);
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName + "-1").Result;
+
+ SearchResult result = connection.SearchAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ if (result.ResultCount == -1)
+ {
+ strError = "检索出错:" + result.ErrorInfo;
+ return -1;
+ }
+ if (result.ResultCount == 0)
+ {
+ strError = "未命中";
+ return 0;
+ }
+
+ summary = result.Records[0].Data;
+
+
+ return 1;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+ ERROR1:
+ return -1;
+ }
+
+
+ private long GetItemInfo(string remoteUserName,
+ string biblioPath,
+ out List itemList,
+ out string strError)
+ {
+ itemList = new List();
+ strError = "";
+
+ CancellationToken cancel_token = new CancellationToken();
+ string id = "2-item";//Guid.NewGuid().ToString();
+ SearchRequest request = new SearchRequest(id,
+ "getItemInfo",
+ "entity",
+ biblioPath,
+ "",
+ "",
+ "",
+ "opac",
+ 10,
+ 0,
+ -1);
+ try
+ {
+ this.WriteLog("GetItemInfo1");
+
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName+"-2").Result;
+ this.WriteLog("GetItemInfo2");
+
+ //string strFilename = string.Format(this.weiXinLogDir + "/log_{0}.txt", DateTime.Now.ToString("yyyyMMdd"));
+ //connection.logFileName = strFilename;
+ SearchResult result = null;
+ try
+ {
+ result = connection.SearchAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+ }
+ catch (Exception ex)
+ {
+ strError = "检索出错:[SearchAsync异常]" + ex.Message;
+ return -1;
+ }
+
+ this.WriteLog("GetItemInfo3");
+ if (result.ResultCount == -1)
+ {
+ strError = "检索出错:" + result.ErrorInfo;
+ return -1;
+ }
+ if (result.ResultCount == 0)
+ {
+ strError = "未命中";
+ return 0;
+ }
+
+ this.WriteLog("GetItemInfo4");
+ for (int i = 0; i < result.Records.Count; i++)
+ {
+ BiblioItem item = new BiblioItem();
+
+ string xml = result.Records[i].Data;
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(xml);
+
+ string strBarcode = DomUtil.GetElementText(dom.DocumentElement, "barcode");
+ string strRefID = DomUtil.GetElementText(dom.DocumentElement, "refID");
+ // 册条码号
+ string strViewBarcode = "";
+ if (string.IsNullOrEmpty(strBarcode) == false)
+ strViewBarcode = strBarcode;
+ else
+ strViewBarcode = "refID:" + strRefID; //"@refID:"
+ item.barcode = strViewBarcode;
+
+ //状态
+ item.state = DomUtil.GetElementText(dom.DocumentElement, "state");
+ // 馆藏地
+ item.location = DomUtil.GetElementText(dom.DocumentElement, "location");
+ // 索引号
+ item.accessNo = DomUtil.GetElementText(dom.DocumentElement, "accessNo");
+
+ // 出版日期
+ item.publishTime = DomUtil.GetElementText(dom.DocumentElement, "publishTime");
+ // 价格
+ item.price = DomUtil.GetElementText(dom.DocumentElement, "price");
+ // 注释
+ item.comment = DomUtil.GetElementText(dom.DocumentElement, "comment");
+
+ // 借阅情况
+ string strBorrowInfo = "借阅情况:在架";
+ /*
+ R00001
+ 教职工
+ 读者/1
+ Sun, 17 Apr 2016 23:57:40 +0800
+ 31day
+ Wed, 18 May 2016 12:00:00 +0800
+ */
+ string strBorrower = DomUtil.GetElementText(dom.DocumentElement, "borrower");
+ string borrowDate = DateTimeUtil.ToLocalTime(DomUtil.GetElementText(dom.DocumentElement,
+ "borrowDate"), "yyyy/MM/dd");
+ string borrowPeriod = DomUtil.GetElementText(dom.DocumentElement, "borrowPeriod");
+ if (string.IsNullOrEmpty(strBorrower) == false)
+ strBorrowInfo = "借阅者:*** 借阅时间:" + borrowDate + " 借期:" + borrowPeriod;
+ item.borrowInfo = strBorrowInfo;
+
+ itemList.Add(item);
+ }
+
+ this.WriteLog("GetItemInfo5");
+ return result.Records.Count;
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+ ERROR1:
+ return -1;
+ }
+
+
+ #endregion
+
+ ///
+ /// -1 出错
+ /// 0 未查到对应记录
+ /// 1 成功
+ ///
+ public int GetMyInfo(string remoteUserName,
+ string strReaderBarcode,
+ out string strMyInfo,
+ out string strError)
+ {
+ strError = "";
+ strMyInfo = "";
+ Debug.Assert(String.IsNullOrEmpty(strReaderBarcode) == false);
+
+
+ // 得到高级xml
+ string strXml = "";
+ int nRet = this.GetPatronInfo(remoteUserName,
+ strReaderBarcode,
+ "xml",
+ out strXml,
+ out strError);
+ if (nRet == -1)
+ return -1;
+ if (nRet == 0)
+ {
+ strError = "从dp2library未找到证条码号为'" + strReaderBarcode + "'的记录"; //todo refID
+ return 0;
+ }
+
+ // 取出个人信息
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(strXml);
+ //string strReaderBarcode = DomUtil.GetElementText(dom.DocumentElement, "barcode");
+ string strName = DomUtil.GetElementText(dom.DocumentElement, "name");
+ string strDepartment = DomUtil.GetElementText(dom.DocumentElement, "department");
+ string strState = DomUtil.GetElementText(dom.DocumentElement, "state");
+ string strCreateDate = DateTimeUtil.ToLocalTime(DomUtil.GetElementText(dom.DocumentElement,
+ "createDate"), "yyyy/MM/dd");
+ string strExpireDate = DateTimeUtil.ToLocalTime(DomUtil.GetElementText(dom.DocumentElement,
+ "expireDate"), "yyyy/MM/dd");
+ string strReaderType = DomUtil.GetElementText(dom.DocumentElement,
+ "readerType");
+ string strComment = DomUtil.GetElementText(dom.DocumentElement,
+ "comment");
+
+ strMyInfo = "个人信息" + "\n"
+ + "姓名:" + strName + "\n"
+ + "证条码号:" + strReaderBarcode + "\n"
+ + "部门:" + strDepartment + "\n"
+ + "联系方式:\n" + GetContactString(dom) + "\n"
+ + "状态:" + strState + "\n"
+ + "有效期:" + strCreateDate + "~" + strExpireDate + "\n"
+ + "读者类别:" + strReaderType + "\n"
+ + "注释:" + strComment;
+ return 1;
+ }
+
+ ///
+ /// -1 出错
+ /// 0 未找到读者记录
+ /// 1 成功
+ ///
+ public int GetBorrowInfo(string remoteUserName,
+ string strReaderBarcode,
+ out string strBorrowInfo,
+ out string strError)
+ {
+ strError = "";
+ strBorrowInfo = "";
+
+
+ // 得到高级xml
+ string strXml = "";
+ long lRet = this.GetPatronInfo(remoteUserName,
+ strReaderBarcode,
+ "advancexml,advancexml_borrow_bibliosummary",
+ out strXml,
+ out strError);
+ if (lRet == -1)
+ return -1;
+
+ // 提取借书信息
+ lRet = this.GetBorrowsInfoInternal(strXml, out strBorrowInfo);
+ if (lRet == -1)
+ return -1;
+
+
+ return 1;
+
+ }
+
+ ///
+ /// 详细借阅信息
+ ///
+ ///
+ ///
+ ///
+ public int GetBorrowsInfoInternal(string strXml, out string strBorrowInfo)
+ {
+ strBorrowInfo = "";
+
+ XmlDocument dom = new XmlDocument();
+ dom.LoadXml(strXml);
+
+ /*
+
+
+ -
+ 基本日历
+
+
+
+''
+ */
+ string maxBorrowCount = "";
+ string curBorrowCount = "";
+ XmlNode nodeMax = dom.DocumentElement.SelectSingleNode("info/item[@name='可借总册数']");
+ if (nodeMax == null)
+ {
+ maxBorrowCount = "获取当前读者可借总册数出错:未找到对应节点。";
+ }
+ else
+ {
+ string maxCount = DomUtil.GetAttr(nodeMax, "value");
+ if (maxCount == "")
+ {
+ maxBorrowCount = "获取当前读者可借总册数出错:未设置对应值。";
+ }
+ else
+ {
+ maxBorrowCount = "最多可借:" + maxCount; ;
+ XmlNode nodeCurrent = dom.DocumentElement.SelectSingleNode("info/item[@name='当前还可借']");
+ if (nodeCurrent == null)
+ {
+ curBorrowCount = "获取当前还可借出错:未找到对应节点。";
+ }
+ else
+ {
+ curBorrowCount = "当前可借:" + DomUtil.GetAttr(nodeCurrent, "value");
+ }
+ }
+ }
+
+ strBorrowInfo = maxBorrowCount + " " + curBorrowCount + "\n";
+
+ XmlNodeList nodes = dom.DocumentElement.SelectNodes("borrows/borrow");
+ if (nodes.Count == 0)
+ {
+ strBorrowInfo += "无借阅记录";
+ return 0;
+ }
+
+ Dictionary borrowLit = new Dictionary();
+ int index = 1;
+ string books = "";
+ foreach (XmlElement borrow in nodes)
+ {
+ if (books != "")
+ books += "===============\n";
+
+ string overdueText = "";
+ string strIsOverdue = DomUtil.GetAttr(borrow, "isOverdue");
+ if (strIsOverdue == "yes")
+ overdueText = DomUtil.GetAttr(borrow, "overdueInfo1");
+ else
+ overdueText = "未超期";
+
+
+ string itemBarcode = DomUtil.GetAttr(borrow, "barcode");
+ borrowLit[index.ToString()] = itemBarcode; // 设到字典点,已变续借
+
+ /*
+ string bookName = DomUtil.GetAttr(borrow, "summary");//borrow.GetAttribute("summary")
+ int tempIndex = bookName.IndexOf('/');
+ if (tempIndex > 0)
+ {
+ bookName = bookName.Substring(0, tempIndex);
+ }
+ */
+ string summary = DomUtil.GetAttr(borrow, "summary");
+ books += "编号:" + index.ToString() + "\n"
+ + "册条码号:" + itemBarcode + "\n"
+ + "摘 要:" + summary + "\n"
+ + "借阅时间:" + DateTimeUtil.ToLocalTime(borrow.GetAttribute("borrowDate"), "yyyy-MM-dd HH:mm") + "\n"
+ + "借 期:" + DateTimeUtil.GetDisplayTimePeriodString(borrow.GetAttribute("borrowPeriod")) + "\n"
+ + "应还时间:" + DateTimeUtil.ToLocalTime(borrow.GetAttribute("returningDate"), "yyyy-MM-dd") + "\n"
+ + "是否超期:" + overdueText + "\n";
+
+
+ index++; //编号+1
+ }
+
+ strBorrowInfo += books;
+
+ // 设到用户上下文
+ //this.CurrentMessageContext.BorrowDict = borrowLit;
+
+ return nodes.Count;
+
+ }
+
+ ///
+ /// 获取读者信息
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public int GetPatronInfo(string remoteUserName,
+ string strReaderBarocde, //todo refID
+ string strFormat,
+ out string xml,
+ out string strError)
+ {
+ xml = "";
+ strError = "";
+
+ CancellationToken cancel_token = new CancellationToken();
+
+ string id = Guid.NewGuid().ToString();
+ SearchRequest request = new SearchRequest(id,
+ "getPatronInfo",
+ "",
+ strReaderBarocde,
+ "",
+ "",
+ "",
+ strFormat,
+ 1,
+ 0,
+ -1);
+
+ try
+ {
+ MessageConnection connection = this._channels.GetConnectionAsync(
+ this.dp2MServerUrl,
+ remoteUserName).Result;
+
+ SearchResult result = connection.SearchAsync(
+ remoteUserName,
+ request,
+ new TimeSpan(0, 1, 0),
+ cancel_token).Result;
+
+ if (result.ResultCount == -1)
+ {
+ strError = result.ErrorInfo;
+ return -1;
+ }
+
+ if (result.ResultCount == 0)
+ {
+ strError = result.ErrorInfo;
+ return -1;
+ }
+
+ xml = result.Records[0].Data;
+ return 1;
+
+ }
+ catch (AggregateException ex)
+ {
+ strError = MessageConnection.GetExceptionText(ex);
+ goto ERROR1;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ goto ERROR1;
+ }
+
+ ERROR1:
+ return -1;
+ }
+
+
+ ///
+ /// 根据code获取微信id
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public int GetWeiXinId(string code, string state, out string weiXinId,
+ out string strError)
+ {
+ strError = "";
+ weiXinId = "";
+
+ try
+ {
+ //可以传一个state用于校验
+ if (state != "dp2weixin")
+ {
+ strError = "验证失败!请从正规途径进入!";
+ return -1;
+ }
+
+ //用code换取access_token
+ var result = OAuthApi.GetAccessToken(this.weiXinAppId, this.weiXinSecret, code);
+ if (result.errcode != ReturnCode.请求成功)
+ {
+ strError = "获取微信id出错:" + result.errmsg;
+ return -1;
+ }
+
+ //下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存)
+ //如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的
+ //Session["OAuthAccessTokenStartTime"] = DateTime.Now;
+ //Session["OAuthAccessToken"] = result;
+
+ // 取出微信id
+ weiXinId = result.openid;
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ strError = ex.Message;
+ return -1;
+
+ }
+ }
+
+ ///
+ /// 发送客服消息
+ ///
+ ///
+ ///
+ public void SendCustomerMsg(string openId, string text)
+ {
+ var accessToken = AccessTokenContainer.GetAccessToken(this.weiXinAppId);
+ CustomApi.SendText(accessToken, openId, "error");
+ }
+
+ ///
+ /// 得到的读者的联系方式
+ ///
+ ///
+ ///
+ public static string GetContactString(XmlDocument dom)
+ {
+ string strTel = DomUtil.GetElementText(dom.DocumentElement, "tel");
+ string strEmail = DomUtil.GetElementText(dom.DocumentElement, "email");
+ string strAddress = DomUtil.GetElementText(dom.DocumentElement, "address");
+ List list = new List();
+ if (string.IsNullOrEmpty(strTel) == false)
+ list.Add(strTel);
+ if (string.IsNullOrEmpty(strEmail) == false)
+ {
+ //strEmail = JoinEmail(strEmail, "");
+ list.Add(strEmail);
+ }
+ if (string.IsNullOrEmpty(strAddress) == false)
+ list.Add(strAddress);
+ return StringUtil.MakePathList(list, "; ");
+ }
+
+ public int Renew(string remoteUserName,
+ string strReaderBarcode,
+ string strItemBarcode,
+ out BorrowInfo2 borrowInfo,
+ out string strError)
+ {
+ borrowInfo = null;
+ strError = "未实现";
+
+ return -1;
+ }
+ #region 错误日志
+
+ public void WriteErrorLog(string strText)
+ {
+ this.WriteLog("ERROR:" + strText);
+ }
+
+ public void WriteLog(string strText)
+ {
+ // todo 有空比对下谢老师写日志的代码
+ //DateTime now = DateTime.Now;
+ //// 每天一个日志文件
+ //string strFilename = Path.Combine(this.LogDir, "log_" + DateTimeUtil.DateTimeToString8(now) + ".txt");
+ //string strTime = now.ToString();
+ //FileUtil.WriteText(strFilename,
+ // strTime + " " + strText + "\r\n");
+
+ var logDir = this.weiXinLogDir;
+ string strFilename = string.Format(logDir + "/log_{0}.txt", DateTime.Now.ToString("yyyyMMdd"));
+ FileUtil.WriteLog(strFilename, strText, "dp2weixin");
+ }
+
+
+ ///
+ /// 获得异常信息
+ ///
+ /// 异常对象
+ ///
+ public static string GetExceptionMessage(Exception ex)
+ {
+ string strResult = ex.GetType().ToString() + ":" + ex.Message;
+ while (ex != null)
+ {
+ if (ex.InnerException != null)
+ strResult += "\r\n" + ex.InnerException.GetType().ToString() + ": " + ex.InnerException.Message;
+
+ ex = ex.InnerException;
+ }
+
+ return strResult;
+ }
+
+ #endregion
+ }
+}
diff --git a/dp2weixin.service/dp2MessageHandler/dp2weixinMessageHandler.cs b/dp2weixin.service/dp2MessageHandler/dp2weixinMessageHandler.cs
index 7ad2e175..dbc0298c 100644
--- a/dp2weixin.service/dp2MessageHandler/dp2weixinMessageHandler.cs
+++ b/dp2weixin.service/dp2MessageHandler/dp2weixinMessageHandler.cs
@@ -21,6 +21,7 @@
using Senparc.Weixin.MP.CommonAPIs;
using System.Web.Mvc.Async;
using System.Threading.Tasks;
+using dp2weixin.service;
using dp2Command.Service;
namespace dp2weixin
@@ -32,7 +33,7 @@ namespace dp2weixin
public partial class dp2weixinMessageHandler : MessageHandler
{
// 由外面传进来的CommandServer
- private dp2BaseCommandService CmdService = null;
+ private dp2WeiXinService CmdService = null;
// 公众号程序目录,用于获取新书推荐与公告配置文件的路径
private string Dp2WeiXinAppDir = "";
// 是否显示消息路径
@@ -49,7 +50,7 @@ public partial class dp2weixinMessageHandler : MessageHandler
///
///
- public dp2weixinMessageHandler(dp2BaseCommandService cmdServer,
+ public dp2weixinMessageHandler(dp2WeiXinService cmdServer,
Stream inputStream, PostModel postModel, int maxRecordCount = 0)
: base(inputStream, postModel, maxRecordCount)
{
@@ -308,6 +309,8 @@ public string getPatronList()
private IResponseMessageBase DoSelectLib(string strParam)
{
+ return this.CreateTextResponseMessage("未实现");
+ /*
// 设置当前命令
this.CurrentMessageContext.CurrentCmdName = dp2CommandUtility.C_Command_SelectLib;
long lRet = 0;
@@ -375,6 +378,7 @@ private IResponseMessageBase DoSelectLib(string strParam)
this.CurrentMessageContext.LibUserName = userItem.libUserName;
return this.CreateTextResponseMessage("您成功选择了图书馆[" + libCode + "]");
+ */
}
public string getLibList()
@@ -401,6 +405,8 @@ public string getLibList()
///
private IResponseMessageBase DoSearch(string strParam)
{
+ return this.CreateTextResponseMessage("未实现");
+ /*
// 设置当前命令
this.CurrentMessageContext.CurrentCmdName = dp2CommandUtility.C_Command_Search;
@@ -469,23 +475,10 @@ private IResponseMessageBase DoSearch(string strParam)
// 返回空
var responseMessage = CreateResponseMessage();
responseMessage.Content = "";
- return responseMessage;
+ return responseMessage;
-
- /*
- string strBiblioInfo = "";
- lRet = this.CmdService.GetDetailBiblioInfo(searchCmd, nBiblioIndex,
- out strBiblioInfo,
- out strError);
- if (lRet == -1 || lRet==0)
- {
- return this.CreateTextResponseMessage(strError);
- }
-
- // 输出详细信息
- return this.CreateTextResponseMessage(strBiblioInfo);
- */
}
+
}
// 检索
@@ -507,8 +500,10 @@ private IResponseMessageBase DoSearch(string strParam)
{
return this.CreateTextResponseMessage(strFirstPage);
}
+ */
}
+ /*
// 消息处理
public void SendBiblioDetail(SearchCommand searchCmd, int nBiblioIndex)
{
@@ -532,7 +527,7 @@ public void SendBiblioDetail(SearchCommand searchCmd, int nBiblioIndex)
((dp2CmdService2)this.CmdService).SendCustomerMsg(this.WeixinOpenId, strResult);
//this.SendCustomeMessage(strResult);
}
-
+ */
/*
// 消息处理
public void SendCustomeMessage(string strText)
@@ -561,8 +556,8 @@ public void SendCustomeMessage(string strText)
///
private IResponseMessageBase DoBinding(string strParam)
{
-
-
+ return this.CreateTextResponseMessage("目前不支持该命令!");
+ /*
// 设置当前命令
this.CurrentMessageContext.CurrentCmdName = dp2CommandUtility.C_Command_Binding;
@@ -618,6 +613,7 @@ private IResponseMessageBase DoBinding(string strParam)
// 设到当前读者变量上
this.CurrentMessageContext.ReaderBarcode = strReaderBarcode;
return this.CreateTextResponseMessage("绑定成功!");
+ */
}
///
@@ -626,6 +622,8 @@ private IResponseMessageBase DoBinding(string strParam)
///
private IResponseMessageBase DoUnbinding()
{
+ return this.CreateTextResponseMessage("不支持。");
+ /*
// 设置当前命令
this.CurrentMessageContext.CurrentCmdName = "";
@@ -658,6 +656,7 @@ private IResponseMessageBase DoUnbinding()
// 置空当前读者变量上
this.CurrentMessageContext.ReaderBarcode = "";
return this.CreateTextResponseMessage("解除绑定成功。");
+ */
}
///
@@ -782,8 +781,8 @@ private IResponseMessageBase DoRenew(string strParam)
// 目前只认作册条码,todo支持序号
- BorrowInfo borrowInfo = null;
- lRet = this.CmdService.Renew(this.CurrentMessageContext.LibUserName,
+ BorrowInfo2 borrowInfo = null;
+ lRet = this.CmdService.Renew(this.CurrentMessageContext.LibUserName,
this.CurrentMessageContext.ReaderBarcode,
strParam,
out borrowInfo,
@@ -794,7 +793,7 @@ private IResponseMessageBase DoRenew(string strParam)
}
// 显示续借成功信息信息
- string returnTime = DateTimeUtil.ToLocalTime(borrowInfo.LatestReturnTime, "yyyy/MM/dd");
+ string returnTime = DateTimeUtil.ToLocalTime(borrowInfo.returnDate, "yyyy/MM/dd");
string strText = strParam + "续借成功,还书日期为:" + returnTime + "。";
return this.CreateTextResponseMessage(strText);
}
@@ -852,6 +851,8 @@ private IResponseMessageBase CreateTextResponseMessage(string strText)
///
private bool CheckIsSelectLib()
{
+ return false;
+ /*
if (String.IsNullOrEmpty(this.CurrentMessageContext.LibCode1) == true)
{
// 从mongodb中查
@@ -865,6 +866,7 @@ private bool CheckIsSelectLib()
}
return true;
+ */
}
///
diff --git a/dp2weixin.service/dp2weixin.service.csproj b/dp2weixin.service/dp2weixin.service.csproj
index 1f30bb17..deb33a2e 100644
--- a/dp2weixin.service/dp2weixin.service.csproj
+++ b/dp2weixin.service/dp2weixin.service.csproj
@@ -35,6 +35,18 @@
..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
True
+
+ False
+ ..\packages\MongoDB.Bson.2.2.4\lib\net45\MongoDB.Bson.dll
+
+
+ False
+ ..\packages\MongoDB.Driver.2.2.4\lib\net45\MongoDB.Driver.dll
+
+
+ False
+ ..\packages\MongoDB.Driver.Core.2.2.4\lib\net45\MongoDB.Driver.Core.dll
+
..\packages\Senparc.Weixin.4.5.19\lib\net45\Senparc.Weixin.dll
True
@@ -77,19 +89,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {56eb94fd-45d0-4c82-ae8e-d398f1c4efcf}
+ DigitalPlatform.Common
+
+
+ {3c4f8133-8652-40b6-b37b-200b25c2b043}
+ DigitalPlatform.Interfaces
+
{441cb814-af78-4503-91ef-dce5f3269502}
DigitalPlatform.IO
@@ -98,6 +132,14 @@
{1b74d69a-530f-4275-845b-8ca6d1463bdd}
DigitalPlatform.LibraryRestClient
+
+ {e4b339d9-4843-40f1-a404-33043adcd6a3}
+ DigitalPlatform.MessageClient
+
+
+ {2fbb1294-0814-447d-b8c6-77e206417231}
+ DigitalPlatform.Message
+
{eeb5253b-ab62-4d06-896e-8f17e3ffd215}
DigitalPlatform.Text
@@ -106,10 +148,6 @@
{a62f763a-96ee-43ad-80c5-9ce57ecfeaf4}
DigitalPlatform.Xml
-
- {a77b8a4a-3ae8-4bd7-b09a-bf8d92fe802d}
- dp2Command.Service
-