// (派生类必须重载) // 比较两个记录, 看看和事项要害信息有关的字段是否发生了变化 // return: // 0 没有变化 // 1 有变化 public override int IsItemInfoChanged(XmlDocument domExist, XmlDocument domOldRec) { for (int i = 0; i < core_order_element_names.Length; i++) { /* * string strText1 = DomUtil.GetElementText(domExist.DocumentElement, * core_order_element_names[i]); * string strText2 = DomUtil.GetElementText(domOldRec.DocumentElement, * core_order_element_names[i]); * */ // 2009/10/24 changed string strText1 = DomUtil.GetElementOuterXml(domExist.DocumentElement, core_order_element_names[i]); string strText2 = DomUtil.GetElementOuterXml(domOldRec.DocumentElement, core_order_element_names[i]); if (strText1 != strText2) { return(1); } } return(0); }
// (派生类必须重载) // 比较两个记录, 看看和事项要害信息有关的字段是否发生了变化 // return: // 0 没有变化 // 1 有变化 public override int IsItemInfoChanged(XmlDocument domExist, XmlDocument domOldRec) { for (int i = 0; i < core_comment_element_names.Length; i++) { string strText1 = DomUtil.GetElementOuterXml(domExist.DocumentElement, core_comment_element_names[i]); string strText2 = DomUtil.GetElementOuterXml(domOldRec.DocumentElement, core_comment_element_names[i]); if (strText1 != strText2) { return(1); } } return(0); }
// parameters: // skips 要跳过的、不参与比较的元素名 // return: // 0 没有差异 // 1 有差异。differents数组里面返回了有差异的元素名 public int IsItemInfoChanged(XmlNode new_root, XmlNode oldrec_root, List <string> skips, out List <string> differents) { differents = new List <string>(); for (int i = 0; i < core_order_element_names.Length; i++) { string strElementName = core_order_element_names[i]; if (skips.IndexOf(strElementName) != -1) { continue; } if (DomUtil.IsEmptyElement(new_root, strElementName) == true && DomUtil.IsEmptyElement(oldrec_root, strElementName) == true) { continue; } string strText1 = DomUtil.GetElementOuterXml(new_root, strElementName); string strText2 = DomUtil.GetElementOuterXml(oldrec_root, strElementName); if (strText1 != strText2) { differents.Add(strText2 + "-->" + strText1); } } if (differents.Count > 0) { return(1); } return(0); }
// DoOperChange()和DoOperMove()的下级函数 // 合并新旧记录 // return: // -1 出错 // 0 正确 // 1 有部分修改没有兑现。说明在strError中 // 2 全部修改都没有兑现。说明在strError中 (2018/10/9) public override int MergeTwoItemXml( SessionInfo sessioninfo, XmlDocument domExist, XmlDocument domNew, out string strMergedXml, out string strError) { strMergedXml = ""; strError = ""; int nRet = 0; if (sessioninfo != null && sessioninfo.Account != null && sessioninfo.UserType == "reader") { strError = "订购库记录不允许读者进行修改"; return(-1); } // 算法的要点是, 把"新记录"中的要害字段, 覆盖到"已存在记录"中 bool bControlled = true; string strControlWarning = ""; // 不完全管辖的详情 if (sessioninfo.GlobalUser == false) { string strDistribute = DomUtil.GetElementText(domExist.DocumentElement, "distribute"); // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; strControlWarning = strError; } if (bControlled == true) { // 再看新内容是不是也全部在管辖之下 strDistribute = DomUtil.GetElementText(domNew.DocumentElement, "distribute"); // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; strControlWarning = strError; } } } if (bControlled == true || // 控制了全部用到的馆藏地点的情形 sessioninfo.GlobalUser == true) // 全局用户 { for (int i = 0; i < core_order_element_names.Length; i++) { // 2009/10/23 changed inner-->outer string strTextNew = DomUtil.GetElementOuterXml(domNew.DocumentElement, core_order_element_names[i]); DomUtil.SetElementOuterXml(domExist.DocumentElement, core_order_element_names[i], strTextNew); } } string strWarning = ""; bool bAllDenied = false; // 对字段的修改是否全部被拒绝 // 分馆用户要特意单独处理<distribute>元素 if (sessioninfo.GlobalUser == false && bControlled == false) { string strRefID = DomUtil.GetElementText(domNew.DocumentElement, "refID"); // 将两个订购XML片断合并 // parameters: // strLibraryCodeList 当前用户管辖的分馆代码列表 // return: // -1 出错 // 0 正常 // 1 发生了超越范围的修改 // 2 有部分修改需求没有兑现 // 3 全部修改都没有兑现 (2018/10/9) nRet = MergeOrderNode(domExist.DocumentElement, domNew.DocumentElement, sessioninfo.LibraryCodeList, out string strTempMergedXml, out strError); if (nRet == -1) { strError = "合并新旧记录时出错: " + strError; return(-1); } if (nRet == 1) { // 2018/8/30 也报出不完全管辖的理由 strError = "当前用户对不完全管辖(" + strControlWarning + ")的订购数据修改超过权限范围: " + strError; return(-1); } if (nRet == 2 || nRet == 3) { if (nRet == 3) { bAllDenied = true; } strWarning = strError; } domExist.DocumentElement.InnerXml = strTempMergedXml; } // 清除以前的<dprms:file>元素 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); nsmgr.AddNamespace("dprms", DpNs.dprms); XmlNodeList nodes = domExist.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlNode node in nodes) { node.ParentNode.RemoveChild(node); } // 兑现新记录中的 dprms:file 元素 nodes = domNew.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlElement node in nodes) { XmlDocumentFragment frag = domExist.CreateDocumentFragment(); frag.InnerXml = node.OuterXml; domExist.DocumentElement.AppendChild(frag); } strMergedXml = domExist.OuterXml; if (string.IsNullOrEmpty(strWarning) == false) { strError = strWarning; if (bAllDenied) { return(2); } return(1); } return(0); }
// DoOperChange()和DoOperMove()的下级函数 // 合并新旧记录 // return: // -1 出错 // 0 正确 // 1 有部分修改没有兑现。说明在strError中 public override int MergeTwoItemXml( SessionInfo sessioninfo, XmlDocument domExist, XmlDocument domNew, out string strMergedXml, out string strError) { strMergedXml = ""; strError = ""; int nRet = 0; if (sessioninfo != null && sessioninfo.Account != null && sessioninfo.UserType == "reader") { strError = "订购库记录不允许读者进行修改"; return(-1); } // 算法的要点是, 把"新记录"中的要害字段, 覆盖到"已存在记录"中 /* * // 要害元素名列表 * string[] element_names = new string[] { * "parent", // 父记录ID * "index", // 编号 * "state", // 状态 * "catalogNo", // 书目号 2008/8/31 * "seller", // 书商 * "source", // 2008/2/15 经费来源 * "range", // 订购的时间范围 * "issueCount", // 订购(时间范围内)跨越多少期? 以便算出总价 * "copy", // 复本数 * "price", // 册、期单价 * "totalPrice", // 总价 * "orderTime", // 订购时间 * "orderID", // 订单号 * "distribute", // 馆藏分配 * "class", // 类别 2008/8/31 * "comment", // 注释 * "batchNo", // 批次号 * }; * */ bool bControlled = true; if (sessioninfo.GlobalUser == false) { string strDistribute = DomUtil.GetElementText(domExist.DocumentElement, "distribute"); // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; } if (bControlled == true) { // 再看新内容是不是也全部在管辖之下 strDistribute = DomUtil.GetElementText(domNew.DocumentElement, "distribute"); // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; } } } if (bControlled == true || // 控制了全部用到的馆藏地点的情形 sessioninfo.GlobalUser == true) // 全局用户 { for (int i = 0; i < core_order_element_names.Length; i++) { /* * string strTextNew = DomUtil.GetElementText(domNew.DocumentElement, * core_order_element_names[i]); * * DomUtil.SetElementText(domExist.DocumentElement, * core_order_element_names[i], strTextNew); * */ // 2009/10/23 changed inner-->outer string strTextNew = DomUtil.GetElementOuterXml(domNew.DocumentElement, core_order_element_names[i]); DomUtil.SetElementOuterXml(domExist.DocumentElement, core_order_element_names[i], strTextNew); } } string strWarning = ""; // 分馆用户要特意单独处理<distribute>元素 if (sessioninfo.GlobalUser == false && bControlled == false) { string strRefID = DomUtil.GetElementText(domNew.DocumentElement, "refID"); string strTempMergedXml = ""; // 将两个订购XML片断合并 // parameters: // strLibraryCodeList 当前用户管辖的分馆代码列表 // return: // -1 出错 // 0 正常 // 1 发生了超越范围的修改 // 2 有部分修改需求没有兑现 nRet = MergeOrderNode(domExist.DocumentElement, domNew.DocumentElement, sessioninfo.LibraryCodeList, out strTempMergedXml, out strError); if (nRet == -1) { strError = "合并新旧记录时出错: " + strError; return(-1); } if (nRet == 1) { strError = "当前用户对不完全管辖的订购数据修改超过权限范围: " + strError; return(-1); } if (nRet == 2) { strWarning = strError; } domExist.DocumentElement.InnerXml = strTempMergedXml; } // 清除以前的<dprms:file>元素 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); nsmgr.AddNamespace("dprms", DpNs.dprms); XmlNodeList nodes = domExist.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlNode node in nodes) { node.ParentNode.RemoveChild(node); } // 兑现新记录中的 dprms:file 元素 nodes = domNew.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlElement node in nodes) { XmlDocumentFragment frag = domExist.CreateDocumentFragment(); frag.InnerXml = node.OuterXml; domExist.DocumentElement.AppendChild(frag); } strMergedXml = domExist.OuterXml; if (string.IsNullOrEmpty(strWarning) == false) { strError = strWarning; return(1); } return(0); }
// DoOperChange()和DoOperMove()的下级函数 // 合并新旧记录 // return: // -1 出错 // 0 正确 // 1 有部分修改没有兑现。说明在strError中 public override int MergeTwoItemXml( SessionInfo sessioninfo, XmlDocument domExist, XmlDocument domNew, out string strMergedXml, out string strError) { strMergedXml = ""; strError = ""; string[] element_table = core_comment_element_names; if (sessioninfo != null && sessioninfo.Account != null && sessioninfo.UserType == "reader") { // 2018/8/15 // 注意: 读者也可能具备修改 state 的能力,如果读者具备 managecomment 权限的话 bool bManager = false; if (string.IsNullOrEmpty(sessioninfo.UserID) == true || StringUtil.IsInList("managecomment", sessioninfo.RightsOrigin) == false) { bManager = false; } else { bManager = true; } // 对不具备管理 comment 权限的读者,降低修改字段的权限范围 if (bManager == false) { element_table = readerchangeable_comment_element_names; } } // 算法的要点是, 把"新记录"中的要害字段, 覆盖到"已存在记录"中 /* * // 要害元素名列表 * string[] element_names = new string[] { * "parent", // 父记录ID。也就是所从属的上一级评注记录的id * "index", // 编号 * "state", // 状态 * "title", // 标题 * "creator", // 创建者 * "createTime", // 创建时间 * "lastModifyTime", // 最后修改时间 * "root", // 根记录ID。也就是所从属的书目记录ID * "content", // 文字内容 * };*/ for (int i = 0; i < element_table.Length; i++) { /* * string strTextNew = DomUtil.GetElementText(domNew.DocumentElement, * core_comment_element_names[i]); * * DomUtil.SetElementText(domExist.DocumentElement, * core_comment_element_names[i], strTextNew); * */ string strTextNew = DomUtil.GetElementOuterXml(domNew.DocumentElement, element_table[i]); DomUtil.SetElementOuterXml(domExist.DocumentElement, element_table[i], strTextNew); } // 清除以前的<dprms:file>元素 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); nsmgr.AddNamespace("dprms", DpNs.dprms); XmlNodeList nodes = domExist.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlNode node in nodes) { node.ParentNode.RemoveChild(node); } // 兑现新记录中的 dprms:file 元素 nodes = domNew.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlElement node in nodes) { XmlDocumentFragment frag = domExist.CreateDocumentFragment(); frag.InnerXml = node.OuterXml; domExist.DocumentElement.AppendChild(frag); } /* * // 2012/10/3 * // 当前用户所管辖的馆代码 * DomUtil.SetElementText(domExist.DocumentElement, * "libraryCode", * sessioninfo.LibraryCodeList); * */ // 修改者不能改变最初的馆代码 strMergedXml = domExist.OuterXml; return(0); }
// DoOperChange()和DoOperMove()的下级函数 // 合并新旧记录 // return: // -1 出错 // 0 正确 // 1 有部分修改没有兑现。说明在strError中 public override int MergeTwoItemXml( SessionInfo sessioninfo, XmlDocument domExist, XmlDocument domNew, out string strMergedXml, out string strError) { strMergedXml = ""; strError = ""; int nRet = 0; if (sessioninfo != null && sessioninfo.Account != null && sessioninfo.UserType == "reader") { strError = "期库记录不允许读者进行修改"; return(-1); } // 算法的要点是, 把"新记录"中的要害字段, 覆盖到"已存在记录"中 /* * // 要害元素名列表 * string[] element_names = new string[] { * "parent", * "state", // 状态 * "publishTime", // 出版时间 * "issue", // 当年期号 * "zong", // 总期号 * "volume", // 卷号 * "orderInfo", // 订购信息 * "comment", // 注释 * "batchNo" // 批次号 * }; * */ bool bControlled = true; { XmlNode nodeExistRoot = domExist.DocumentElement.SelectSingleNode("orderInfo"); if (nodeExistRoot != null) { // 是否全部订购信息片断中的馆藏地点都在当前用户管辖之下? // return: // -1 出错 // 0 不是全部都在管辖范围内 // 1 都在管辖范围内 nRet = IsAllOrderControlled(nodeExistRoot, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; } } if (bControlled == true) { // 再看新内容是不是也全部在管辖之下 XmlNode nodeNewRoot = domNew.DocumentElement.SelectSingleNode("orderInfo"); if (nodeNewRoot != null) { // 是否全部订购信息片断中的馆藏地点都在当前用户管辖之下? // return: // -1 出错 // 0 不是全部都在管辖范围内 // 1 都在管辖范围内 nRet = IsAllOrderControlled(nodeNewRoot, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bControlled = false; } } } } if (bControlled == true || // 控制了全部用到的馆藏地点的情形,也可以修改基本字段。并且具有删除 <orderInfo> 中某些片断的能力,只要新记录中不包含这些片断,就等于删除了 sessioninfo.GlobalUser == true) // 只有全局用户才能修改基本字段 { for (int i = 0; i < core_issue_element_names.Length; i++) { /* * string strTextNew = DomUtil.GetElementText(domNew.DocumentElement, * element_names[i]); * * DomUtil.SetElementText(domExist.DocumentElement, * element_names[i], strTextNew); * */ // 2009/10/24 changed inner-->outer string strTextNew = DomUtil.GetElementOuterXml(domNew.DocumentElement, core_issue_element_names[i]); DomUtil.SetElementOuterXml(domExist.DocumentElement, core_issue_element_names[i], strTextNew); } } // 分馆用户要特意单独处理<orderInfo>元素 if (sessioninfo.GlobalUser == false && bControlled == false) { // 分馆用户提交的<orderInfo>元素内可能包含的<root>元素个数要较少,但并不意味着要删除多余的<root>元素 XmlNode nodeNewRoot = domNew.DocumentElement.SelectSingleNode("orderInfo"); XmlNode nodeExistRoot = domExist.DocumentElement.SelectSingleNode("orderInfo"); if (nodeNewRoot != null && nodeExistRoot == null) { //strError = "不允许分馆用户为期记录增补<orderInfo>元素"; // 必须以前的记录就存在<orderInfo>元素 //return -1; // 增补 nodeExistRoot = domExist.CreateElement("orderInfo"); domExist.DocumentElement.AppendChild(nodeExistRoot); } if (nodeNewRoot == null || nodeExistRoot == null) { goto END1; } // 在已经存在的记录中找出当前用户能管辖的订购片断 List <XmlNode> exists_overwriteable_nodes = new List <XmlNode>(); XmlNodeList exist_nodes = nodeExistRoot.SelectNodes("*"); foreach (XmlNode exist_node in exist_nodes) { string strRefID = DomUtil.GetElementText(exist_node, "refID"); if (string.IsNullOrEmpty(strRefID) == true) { continue; // 无法定位,所以跳过? } string strDistribute = DomUtil.GetElementText(exist_node, "distribute"); if (string.IsNullOrEmpty(strDistribute) == true) { continue; } // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 1) { exists_overwriteable_nodes.Add(exist_node); } } // 对新提交的记录中的每个订购片断进行循环 XmlNodeList new_nodes = nodeNewRoot.SelectNodes("*"); foreach (XmlNode new_node in new_nodes) { string strRefID = DomUtil.GetElementText(new_node, "refID"); if (string.IsNullOrEmpty(strRefID) == true) { // 前端提交的一个订购片断refid为空 strError = "期记录中的订购XML片断其<refID>元素内容不能为空"; return(-1); } XmlNode exist_node = nodeExistRoot.SelectSingleNode("*[./refID[text()='" + strRefID + "']]"); if (exist_node == null) { // 前端提交的一个订购片断匹配不上refid // 如果新增的XML片断,其中distribute字符串表明全部在管辖范围,还是允许新增 string strDistribute = DomUtil.GetElementText(new_node, "distribute"); if (string.IsNullOrEmpty(strDistribute) == false) { // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strDistribute, sessioninfo.LibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { strError = "受当前用户的分馆用户身份限制,期记录中不允许新增(包括了超出管辖范围馆代码的)订购XML片断。(refID='" + strRefID + "')"; return(-1); } } // 在domExit中追加 XmlNode new_frag = domExist.CreateElement("root"); new_frag.InnerXml = new_node.InnerXml; nodeExistRoot.AppendChild(new_frag); continue; } Debug.Assert(exist_node != null, ""); string strTempMergedXml = ""; // 将两个订购XML片断合并 // parameters: // strLibraryCodeList 当前用户管辖的分馆代码列表 // return: // -1 出错 // 0 正常 // 1 发生了超越范围的修改 nRet = MergeOrderNode(exist_node, new_node, sessioninfo.LibraryCodeList, out strTempMergedXml, out strError); if (nRet != 0) { strError = "对期记录中 refid 为 '" + strRefID + "' 的订购片断数据修改超过权限范围: " + strError; return(-1); } exist_node.InnerXml = strTempMergedXml; exists_overwriteable_nodes.Remove(exist_node); // 已经修改过的已存在节点,从数组中去掉 } // 删除那些在新记录中没有出现的,但当前用户实际上能管辖的节点 foreach (XmlNode node in exists_overwriteable_nodes) { node.ParentNode.RemoveChild(node); } } END1: // 清除以前的<dprms:file>元素 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); nsmgr.AddNamespace("dprms", DpNs.dprms); XmlNodeList nodes = domExist.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlNode node in nodes) { node.ParentNode.RemoveChild(node); } // 兑现新记录中的 dprms:file 元素 nodes = domNew.DocumentElement.SelectNodes("//dprms:file", nsmgr); foreach (XmlElement node in nodes) { XmlDocumentFragment frag = domExist.CreateDocumentFragment(); frag.InnerXml = node.OuterXml; domExist.DocumentElement.AppendChild(frag); } strMergedXml = domExist.OuterXml; return(0); }