void ReturnChannel(LibraryChannel channel) { _stop.OnStop -= _stop_OnStop; channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); channel.Close(); _channel = null; }
void Channels_AfterLogin(object sender, AfterLoginEventArgs e) { LibraryChannel channel = (LibraryChannel)sender; dp2Server server = this.MainForm.Servers[channel.Url]; if (server == null) { // e.ErrorInfo = "没有找到 URL 为 " + channel.Url + " 的服务器对象"; return; } #if SN if (server.Verified == false && StringUtil.IsInList("serverlicensed", channel.Rights) == false) { string strError = ""; string strTitle = "修改密码窗需要先设置序列号才能访问服务器 " + server.Name + " " + server.Url; int nRet = this.MainForm.VerifySerialCode(strTitle, "", true, out strError); if (nRet == -1) { channel.Close(); e.ErrorInfo = strTitle; #if NO MessageBox.Show(this.MainForm, "修改密码窗需要先设置序列号才能使用"); API.PostMessage(this.Handle, API.WM_CLOSE, 0, 0); #endif return; } } server.Verified = true; #else server.Verified = true; #endif }
internal static int GetRemoteBiblioDbNames( string strUrl, string strUserName, string strPassword, out List<string> dbnames, out string strError) { strError = ""; dbnames = new List<string>(); string strValue = ""; LibraryChannel channel = new LibraryChannel(); channel.Url = strUrl; try { long lRet = channel.Login(strUserName, strPassword, "type=worker,client=dp2circulation|" + Program.ClientVersion, out strError); if (lRet != 1) { strError = "对服务器 '" + channel.Url + "' 以用户 '" + strUserName + "' 进行登录时发生错误: " + strError; return -1; } lRet = channel.GetSystemParameter(null, "system", "biblioDbGroup", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + channel.Url + " 获得书目库信息过程发生错误:" + strError; return -1; } } finally { channel.Close(); } { // 解析 XML XmlDocument dom = new XmlDocument(); dom.LoadXml("<root />"); try { dom.DocumentElement.InnerXml = strValue; } catch (Exception ex) { strError = "category=system,name=biblioDbGroup 所返回的 XML 片段在装入 InnerXml 时出错: " + ex.Message; return -1; } XmlNodeList nodes = dom.DocumentElement.SelectNodes("database"); foreach (XmlNode node in nodes) { string strDbName = DomUtil.GetAttr(node, "biblioDbName"); dbnames.Add(strDbName); } } return 0; }
// return: // -1 出错 // 0 中断 // 1 完成 int ProcessOperLogs(ServerReplicationStart breakpoint, bool bContinueWhenError, Delegate_saveBreakPoint func_saveBreakPoint, string strStyle, out string strError) { strError = ""; DateTime now = DateTime.Now; string strStartDate = breakpoint.Date; // +":" + breakpoint.Offset.ToString(); string strEndDate = DateTimeUtil.DateTimeToString8(now); List <string> filenames = null; string strWarning = ""; // 根据日期范围,发生日志文件名 // parameters: // strStartDate 起始日期。8字符 // strEndDate 结束日期。8字符 // return: // -1 错误 // 0 成功 int nRet = OperLogLoader.MakeLogFileNames(strStartDate, strEndDate, true, // true, out filenames, out strWarning, out strError); if (nRet == -1) { return(-1); } if (String.IsNullOrEmpty(strWarning) == false) { // 可能有超过当天日期的被舍弃 } #if NO if (filenames.Count > 0 && string.IsNullOrEmpty(strEndRange) == false) { filenames[filenames.Count - 1] = filenames[filenames.Count - 1] + ":" + strEndRange; } if (filenames.Count > 0 && string.IsNullOrEmpty(strStartRange) == false) { filenames[0] = filenames[0] + ":" + strStartRange; } #endif if (filenames.Count > 0 && breakpoint.Index > 0) { filenames[0] = filenames[0] + ":" + breakpoint.Index.ToString() + "-"; } string strTempFileName = ""; strTempFileName = this.App.GetTempFileName("attach"); #if NO LibraryChannel channel = new LibraryChannel(); channel.Timeout = TimeSpan.FromSeconds(30); channel.Url = this.m_strUrl; channel.BeforeLogin += new BeforeLoginEventHandle(Channel_BeforeLogin); #endif LibraryChannel channel = this.GetChannel(); _stop.BeginLoop(); try { DateTime lastSaveTime = DateTime.Now; TimeSpan delta = TimeSpan.FromMinutes(1); OperLogLoader loader = new OperLogLoader(); loader.Channel = channel; loader.Stop = this._stop; // loader.estimate = estimate; loader.Dates = filenames; loader.Level = 0; // 0 完整级别 loader.ReplicationLevel = true; loader.AutoCache = false; loader.CacheDir = ""; // loader.Filter = "borrow,return,setReaderInfo,setBiblioInfo,setEntity,setOrder,setIssue,setComment,amerce,passgate,getRes"; loader.LogType = LogType.OperLog; foreach (OperLogItem item in loader) { if (this.Stopped) { strError = "用户中断"; return(0); } string date = item.Date; // 处理 // this.AppendResultText("--" + date + "\r\n"); this.SetProgressText(date + ":" + item.Index.ToString()); Stream attachment = null; try { if (item.AttachmentLength != 0) { // return: // -1 出错 // 0 没有找到日志记录 // >0 附件总长度 long lRet = loader.DownloadAttachment(item, strTempFileName, out strError); if (lRet == -1 || lRet == 0) { strError = "做日志记录 " + item.Date + " " + (item.Index).ToString() + " 时,下载附件部分发生错误:" + strError; this.AppendResultText("*** " + strError + "\r\n"); if (// this.RecoverLevel == RecoverLevel.Logic && bContinueWhenError == false) { return(-1); } goto CONTINUE; } attachment = File.Open(strTempFileName, FileMode.Open); } nRet = this.DoOperLogRecord( this.RecoverLevel, item.Xml, attachment, strStyle, out strError); if (nRet == -1) { strError = "做日志记录 " + item.Date + " " + (item.Index).ToString() + " 时发生错误:" + strError; this.AppendResultText("*** " + strError + "\r\n"); // 2007/6/25 // 如果为纯逻辑恢复(并且 bContinueWhenError 为 false),遇到错误就停下来。这便于进行测试。 // 若不想停下来,可以选择“逻辑+快照”型,或者设置 bContinueWhenError 为 true if (// this.RecoverLevel == RecoverLevel.Logic && bContinueWhenError == false) { return(-1); } } } finally { if (attachment != null) { attachment.Close(); attachment = null; } } CONTINUE: breakpoint.Date = date; breakpoint.Index = item.Index + 1; // 中途记忆断点 if (DateTime.Now - lastSaveTime >= delta) { if (func_saveBreakPoint != null) { func_saveBreakPoint(breakpoint); } lastSaveTime = DateTime.Now; } } return(1); } catch (InterruptException) { strError = "用户中断"; return(0); } catch (ChannelException ex) { strError = "处理过程出错: " + ex.Message; return(-1); } catch (Exception ex) { strError = "ProcessOperLogs() 出现异常: " + ExceptionUtil.GetDebugText(ex); return(-1); } finally { if (File.Exists(strTempFileName)) { File.Delete(strTempFileName); } _stop.EndLoop(); #if NO channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); channel.Close(); #endif this.ReturnChannel(channel); } }
internal static int GetRemoteBiblioDbNames( string strUrl, string strUserName, string strPassword, out List <string> dbnames, out string strError) { strError = ""; dbnames = new List <string>(); string strValue = ""; LibraryChannel channel = new LibraryChannel(); channel.Url = strUrl; try { long lRet = channel.Login(strUserName, strPassword, "type=worker,client=dp2circulation|" + Program.ClientVersion, out strError); if (lRet != 1) { strError = "对服务器 '" + channel.Url + "' 以用户 '" + strUserName + "' 进行登录时发生错误: " + strError; return(-1); } lRet = channel.GetSystemParameter(null, "system", "biblioDbGroup", out strValue, out strError); if (lRet == -1) { strError = "针对服务器 " + channel.Url + " 获得书目库信息过程发生错误:" + strError; return(-1); } } finally { channel.Close(); } { // 解析 XML XmlDocument dom = new XmlDocument(); dom.LoadXml("<root />"); try { dom.DocumentElement.InnerXml = strValue; } catch (Exception ex) { strError = "category=system,name=biblioDbGroup 所返回的 XML 片段在装入 InnerXml 时出错: " + ex.Message; return(-1); } XmlNodeList nodes = dom.DocumentElement.SelectNodes("database"); foreach (XmlNode node in nodes) { string strDbName = DomUtil.GetAttr(node, "biblioDbName"); dbnames.Add(strDbName); } } return(0); }
// 上载书目记录 // parameters: // strAhtuString 身份鉴别字符串。一般是“用户名/密码”形态 // strAction 动作。为"new" "change" "delete" "onlydeletebiblio"之一。"delete"在删除书目记录的同时,会自动删除下属的实体记录。不过要求实体均未被借出才能删除。 // strRecPath 记录路径。如果是覆盖保存一条记录,路经则为类似“中文图书/100”这样的形式,斜杠左边是数据库名,右边是记录ID。如果是创建一条新记录,则路径为类似“中文图书/?”的形式。 // strFormat strRecord参数中的记录内容的格式。为 marcxchange marcxml 之一 // strRecord 要上载的书目记录内容。目前支持的格式有marcxchange和marcxml // strTimestamp 所上载的书目记录的时间戳字符串。如果是创建新记录,则时间戳字符串为空即可。 // 注:用Z39.50检索社科院联合编目中心所获得的MARC记录,其901字段中的$p子字段内容为该记录的路经,$t子字段内容为记录的时间戳字符串 // strOutputRecPath [out]返回上载保存后的记录路径。如果是创建新记录,则这里返回了该记录创建后的确定记录路径 // strOutputTimestamp [out]返回记录保存后的新时间戳字符串。保存操作会令时间戳更新。如果要继续进行保存操作,需要使用新的时间戳字符串来进行调用 // strError [out]返回出错信息 // return: // -2 登录不成功 // -1 出错 // 0 成功 public int UpdateRecord( string strAuthString, string strAction, string strRecPath, string strFormat, string strRecord, string strTimestamp, out string strOutputRecPath, out string strOutputTimestamp, out string strError) { strError = ""; strOutputRecPath = ""; strOutputTimestamp = ""; int nRet = 0; string strXml = ""; if (strAction != null) { strAction = strAction.ToLower(); } if (strAction == "delete") { // 保持strXml == ""; } else { if (strFormat != null) { strFormat = strFormat.ToLower(); } if (strFormat == "marcxchange" || strFormat == "info:lc/xmlns/marcxchange-v1") { nRet = MarcUtil.MarcXChangeToXml(strRecord, out strXml, out strError); if (nRet == -1) { strError = "在转换源记录格式的过程中发生错误: " + strError; return(-1); } } else if (strFormat == "marcxml") { strXml = strRecord; } else { strError = "未知的strFormat值 '" + strFormat + "'。目前仅支持 marcxchange marcxml 之一"; return(-1); } } // TODO: 是否要去除MARC中的字段901? 或者这个是前端的责任? nRet = InitialApplication(out strError); if (nRet == -1) { return(-1); } string strUserName = ""; string strPassword = ""; nRet = strAuthString.IndexOf("/"); if (nRet == -1) { strUserName = strAuthString.Trim(); } else { strUserName = strAuthString.Substring(0, nRet).Trim(); strPassword = strAuthString.Substring(nRet + 1).Trim(); } string strParameters = "location=#unioncatalog,client=dp2Catalog|"; LibraryChannel channel = new LibraryChannel(); try { channel.Url = app.WsUrl; long lRet = channel.Login(strUserName, strPassword, strParameters, out strError); if (lRet == -1) { strError = "登录过程发生错误: " + strError; return(-1); } if (lRet != 1) { strError = "登录失败: " + strError; return(-2); } byte[] baTimestamp = ByteArray.GetTimeStampByteArray(strTimestamp); byte [] baOutputTimestamp = null; lRet = channel.SetBiblioInfo(null, strAction, strRecPath, "xml", // strBiblioType, strXml, baTimestamp, "", // strComment out strOutputRecPath, out baOutputTimestamp, out strError); if (lRet == -1) { return(-1); } strOutputTimestamp = ByteArray.GetHexTimeStampString(baOutputTimestamp); } finally { channel.Close(); } return(0); }
public void ThreadFillSummaryMain() { m_bStopFilling = false; LibraryChannel channel = new LibraryChannel(); channel.Url = this.MainForm.LibraryServerUrl; channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); channel.BeforeLogin += new BeforeLoginEventHandle(Channel_BeforeLogin); try { #if NOOOOOOOOO Delegate_FillSummary d = new Delegate_FillSummary(FillSummary); this.Invoke(d, new object[] { this.listView_overdues, channel, COLUMN_AMERCING_ITEMBARCODE, COLUMN_AMERCING_BIBLIOSUMMARY }); if (m_bStopFilling == true) return; #endif /* FillSummary( this.listView_amerced, COLUMN_AMERCED_ITEMBARCODE, COLUMN_AMERCED_BIBLIOSUMMARY); * */ Delegate_FillSummary d = new Delegate_FillSummary(FillSummary); this.Invoke(d, new object[] { this.listView_amerced, channel, COLUMN_AMERCED_ITEMBARCODE, COLUMN_AMERCED_BIBLIOSUMMARY }); m_bStopFilling = true; } finally { channel.Close(); } }
/*public*/ void ThreadFillAmercingMain() { string strError = ""; m_bStopFillAmercing = false; LibraryChannel channel = new LibraryChannel(); channel.Url = this.MainForm.LibraryServerUrl; channel.BeforeLogin += new BeforeLoginEventHandle(Channel_BeforeLogin); try { Safe_clearList(this.listView_overdues); XmlDocument dom = new XmlDocument(); try { dom.LoadXml(this.FillAmercingParam.Xml); } catch (Exception ex) { strError = "读者XML记录装入XMLDOM时发生错误: " + ex.Message; goto ERROR1; } List<string> dup_ids = new List<string>(); // 选出所有<overdue>元素 XmlNodeList nodes = dom.DocumentElement.SelectNodes("overdues/overdue"); for (int i = 0; i < nodes.Count; i++) { if (this.m_bStopFillAmercing == true) { strError = "中断,列表不完整..."; goto ERROR1; } XmlNode node = nodes[i]; string strItemBarcode = DomUtil.GetAttr(node, "barcode"); string strItemRecPath = DomUtil.GetAttr(node, "recPath"); string strReason = DomUtil.GetAttr(node, "reason"); string strBorrowDate = DomUtil.GetAttr(node, "borrowDate"); strBorrowDate = DateTimeUtil.LocalTime(strBorrowDate, "u"); string strBorrowPeriod = DomUtil.GetAttr(node, "borrowPeriod"); string strReturnDate = DomUtil.GetAttr(node, "returnDate"); strReturnDate = DateTimeUtil.LocalTime(strReturnDate, "u"); string strID = DomUtil.GetAttr(node, "id"); string strPrice = DomUtil.GetAttr(node, "price"); string strComment = DomUtil.GetAttr(node, "comment"); string strBorrowOperator = DomUtil.GetAttr(node, "borrowOperator"); string strReturnOperator = DomUtil.GetAttr(node, "operator"); XmlNodeList dup_nodes = dom.DocumentElement.SelectNodes("overdues/overdue[@id='" + strID + "']"); if (dup_nodes.Count > 1) { dup_ids.Add(strID); } // TODO: 摘要建议异步作,或者在全部数据装载完成后单独扫描一遍做 string strSummary = ""; ListViewItem item = new ListViewItem(strItemBarcode); // 摘要 // item.SubItems.Add(strSummary); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_BIBLIOSUMMARY, strSummary); // 金额 // item.SubItems.Add(strPrice); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_PRICE, strPrice); // 注释 // item.SubItems.Add(strComment); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_COMMENT, strComment); // 违约原因 // item.SubItems.Add(strReason); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_REASON, strReason); // 借阅日期 // item.SubItems.Add(strBorrowDate); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_BORROWDATE, strBorrowDate); // 借阅时限 // item.SubItems.Add(strBorrowPeriod); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_BORROWPERIOD, strBorrowPeriod); // 还书日期 // item.SubItems.Add(strReturnDate); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_RETURNDATE, strReturnDate); // id // item.SubItems.Add(strID); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_ID, strID); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_BORROWOPERATOR, strBorrowOperator); ListViewUtil.ChangeItemText(item, COLUMN_AMERCING_RETURNOPERATOR, strReturnOperator); // 储存原始价格和注释备用 AmercingItemInfo info = new AmercingItemInfo(); info.Price = strPrice; info.Comment = strComment; info.Xml = node.OuterXml; item.Tag = info; Safe_addListItem(this.listView_overdues, item); } if (dup_ids.Count > 0) { StringUtil.RemoveDupNoSort(ref dup_ids); Debug.Assert(dup_ids.Count >= 1, ""); strError = "未交费用列表中发现下列ID出现了重复,这是一个严重错误,请系统管理员尽快排除。\r\n---\r\n" + StringUtil.MakePathList(dup_ids, "; "); goto ERROR1; } // 第二阶段,填充摘要 if (this.FillAmercingParam.FillSummary == true) { List<ListViewItem> items = Safe_getItemList(listView_overdues); for (int i = 0; i < items.Count; i++) { if (this.m_bStopFillAmercing == true) return; ListViewItem item = items[i]; string strSummary = ""; string strItemBarcode = ""; Safe_getBarcodeAndSummary(listView_overdues, item, out strItemBarcode, out strSummary); // 已经有内容了,就不刷新了 if (String.IsNullOrEmpty(strSummary) == false) continue; if (String.IsNullOrEmpty(strItemBarcode) == true /*&& String.IsNullOrEmpty(strItemRecPath) == true*/) continue; try { string strBiblioRecPath = ""; long lRet = channel.GetBiblioSummary( null, strItemBarcode, "", // strItemRecPath, null, out strBiblioRecPath, out strSummary, out strError); if (lRet == -1) { strSummary = strError; // 2009/3/13 changed // return -1; } } finally { } Safe_changeItemText(item, COLUMN_AMERCING_BIBLIOSUMMARY, strSummary); } } return; } finally { channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); channel.Close(); m_bStopFillAmercing = true; } ERROR1: Safe_setError(this.listView_overdues, strError); // Safe_errorBox(strError); }
/*public*/ void ThreadFillAmercedMain() { string strError = ""; m_bStopFillAmerced = false; LibraryChannel channel = new LibraryChannel(); channel.Url = this.MainForm.LibraryServerUrl; channel.BeforeLogin += new BeforeLoginEventHandle(Channel_BeforeLogin); channel.AfterLogin += new AfterLoginEventHandle(Channel_AfterLogin); try { string strResultSetName = ""; // 获得一些系统参数 string strDbName = "违约金"; string strQueryXml = ""; string strLang = "zh"; long lRet = Channel.GetSystemParameter( stop, "amerce", "dbname", out strDbName, out strError); if (lRet == -1) goto ERROR1; if (m_bStopFillAmerced == true) return; // 2010/12/16 change if (lRet == 0 || String.IsNullOrEmpty(strDbName) == true) { if (String.IsNullOrEmpty(strError) == true) strError = "违约金库名没有配置。"; goto ERROR1; } if (string.IsNullOrEmpty(this.FillAmercedParam.ReaderBarcode) == false) { Safe_clearList(this.listView_amerced); string strFrom = "读者证条码"; string strMatchStyle = "exact"; // 2007/4/5 改造 加上了 GetXmlStringSimple() strQueryXml = "<target list='" + strDbName + ":" + strFrom + "'><item><word>" + StringUtil.GetXmlStringSimple(this.FillAmercedParam.ReaderBarcode) + "</word><match>" + strMatchStyle + "</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + strLang + "</lang></target>"; strResultSetName = "amercing"; } // end of strReaderBarcode != "" else { if (this.FillAmercedParam.IDs == null || this.FillAmercedParam.IDs.Count == 0) { strError = "IDs 参数不能为空"; goto ERROR1; } string strFrom = "ID"; string strMatchStyle = "exact"; strQueryXml = "<target list='" + strDbName + ":" + strFrom + "'>"; for (int i = 0; i < this.FillAmercedParam.IDs.Count; i++) { string strID = this.FillAmercedParam.IDs[i]; if (i > 0) strQueryXml += "<operator value='OR' />"; strQueryXml += "<item><word>" + StringUtil.GetXmlStringSimple(strID) + "</word><match>" + strMatchStyle + "</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + strLang + "</lang>"; } strQueryXml += "</target>"; strResultSetName = "amerced"; } // 开始检索 lRet = channel.Search( stop, strQueryXml, strResultSetName, "", // strOutputStyle out strError); if (lRet == 0) { strError = "not found"; return; // not found } if (lRet == -1) goto ERROR1; if (m_bStopFillAmerced == true) return; long lHitCount = lRet; long lStart = 0; long lPerCount = Math.Min(50, lHitCount); Record[] searchresults = null; // 获得结果集,装入listview for (; ; ) { if (m_bStopFillAmerced == true) { strError = "中断,列表不完整..."; goto ERROR1; } // stop.SetMessage("正在装入浏览信息 " + (lStart + 1).ToString() + " - " + (lStart + lPerCount).ToString() + " (命中 " + lHitCount.ToString() + " 条记录) ..."); lRet = channel.GetSearchResult( stop, strResultSetName, // strResultSetName lStart, lPerCount, "id", // "id,cols" strLang, out searchresults, out strError); if (lRet == -1) goto ERROR1; if (lRet == 0) { strError = "未命中"; return; } // 处理浏览结果 for (int i = 0; i < searchresults.Length; i++) { if (m_bStopFillAmerced == true) { strError = "中断,列表不完整..."; goto ERROR1; } string strPath = searchresults[i].Path; byte[] timestamp = null; string strXml = ""; lRet = channel.GetRecord(stop, strPath, out timestamp, out strXml, out strError); if (lRet == -1) { if (channel.ErrorCode == ErrorCode.AccessDenied) continue; goto ERROR1; } int nRet = Safe_fillAmercedLine( stop, strXml, strPath, out strError); if (nRet == -1) goto ERROR1; } lStart += searchresults.Length; if (lStart >= lHitCount || lPerCount <= 0) break; } // 第二阶段,填充摘要 if (this.FillAmercedParam.FillSummary == true) { List<ListViewItem> items = Safe_getItemList(this.listView_amerced); for (int i = 0; i < items.Count; i++) { if (this.m_bStopFillAmerced == true) return; ListViewItem item = items[i]; string strSummary = ""; string strItemBarcode = ""; Safe_getBarcodeAndSummary(listView_amerced, item, out strItemBarcode, out strSummary); // 已经有内容了,就不刷新了 if (String.IsNullOrEmpty(strSummary) == false) continue; if (String.IsNullOrEmpty(strItemBarcode) == true /*&& String.IsNullOrEmpty(strItemRecPath) == true*/) continue; try { string strBiblioRecPath = ""; lRet = channel.GetBiblioSummary( null, strItemBarcode, "", // strItemRecPath, null, out strBiblioRecPath, out strSummary, out strError); if (lRet == -1) { strSummary = strError; // 2009/3/13 changed // return -1; } } finally { } Safe_changeItemText(item, COLUMN_AMERCING_BIBLIOSUMMARY, strSummary); } } return; } finally { channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); channel.AfterLogin -= new AfterLoginEventHandle(Channel_AfterLogin); channel.Close(); m_bStopFillAmerced = true; } ERROR1: Safe_setError(this.listView_amerced, strError); // Safe_errorBox(strError); }