From f36320283ddccad8164efa25148428c232129a2e Mon Sep 17 00:00:00 2001 From: xietao Date: Wed, 2 Aug 2023 22:37:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E4=B9=A6=E9=80=9A=E6=8A=A5=20docx=20?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=A2=9E=E5=8A=A0=E5=B0=81=E9=9D=A2=E5=9B=BE?= =?UTF-8?q?=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DigitalPlatform.Typography.csproj | 1 + DigitalPlatform.Typography/TypoUtility.cs | 189 +++++++++++++- dp2Circulation/FontSetting/MyForm.cs | 239 +++++++++++++++--- dp2Circulation/Issue/PrintBindingForm.cs | 1 + .../OperLogStatisForm_transfer.cs | 1 + dp2Circulation/Order/DistributeExcelFile.cs | 2 + dp2Circulation/Order/ExportExcelFile.cs | 1 + .../SearchForms/BiblioSearchForm.cs | 1 + .../SaveNewBookFileDialog.Designer.cs | 1 - .../SearchForms/SaveNewBookFileDialog.cs | 23 +- dp2Circulation/Utility.cs | 59 ++++- dp2Circulation/dp2Circulation.csproj | 7 +- dp2Circulation/packages.config | 1 + dp2LibraryConsole/Instance.cs | 7 +- 14 files changed, 480 insertions(+), 53 deletions(-) diff --git a/DigitalPlatform.Typography/DigitalPlatform.Typography.csproj b/DigitalPlatform.Typography/DigitalPlatform.Typography.csproj index 50a423d42..6cf79eb5f 100644 --- a/DigitalPlatform.Typography/DigitalPlatform.Typography.csproj +++ b/DigitalPlatform.Typography/DigitalPlatform.Typography.csproj @@ -6,6 +6,7 @@ + diff --git a/DigitalPlatform.Typography/TypoUtility.cs b/DigitalPlatform.Typography/TypoUtility.cs index 3cdbf7ea8..96641e466 100644 --- a/DigitalPlatform.Typography/TypoUtility.cs +++ b/DigitalPlatform.Typography/TypoUtility.cs @@ -8,6 +8,9 @@ using System.Text; using System.IO; +using A = DocumentFormat.OpenXml.Drawing; +using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing; +using PIC = DocumentFormat.OpenXml.Drawing.Pictures; using DocumentFormat.OpenXml.VariantTypes; using DocumentFormat.OpenXml; @@ -17,6 +20,8 @@ using DigitalPlatform.Text; using DigitalPlatform.Xml; +using System.Net.Http; +// using SixLabors.ImageSharp; namespace DigitalPlatform.Typography { @@ -112,7 +117,7 @@ public static void XmlToWord(string xmlFileName, static void AdjustTable(XmlDocument dom) { var nodes = dom.DocumentElement.SelectNodes("//table"); - foreach(XmlElement table in nodes) + foreach (XmlElement table in nodes) { if (IsParentTd(table) == false) continue; @@ -141,7 +146,7 @@ bool IsParentTd(XmlElement current) bool HasSiblingP(XmlElement current) { - foreach(XmlElement sibling in current.ParentNode.ChildNodes) + foreach (XmlElement sibling in current.ParentNode.ChildNodes) { if (sibling == null) continue; @@ -1205,6 +1210,49 @@ static void CreateTextStream( continue; } + if (child_node.Name == "img") + { + XmlElement e = child_node as XmlElement; + string src = e.GetAttribute("src"); + + HttpClient client = new HttpClient(); + var response = client.GetAsync(src).Result; + + var contentType = response.Content.Headers.ContentType?.MediaType; + + int width = 0; + int height = 0; + ImagePart imagePart = null; + using (var stream = response.Content.ReadAsStreamAsync().Result) + { + // Stream theStream = client.GetStreamAsync(src).Result; + + /* + var ext = Path.GetExtension(imageFileName); + ImagePartType type = ImagePartType.Jpeg; + Enum.TryParse(ext, true, out type); + */ + var type = GetImageType(contentType); + imagePart = doc.MainDocumentPart.AddImagePart(type); + + using (var image = SixLabors.ImageSharp.Image.Load(stream)) + { + width = image.Width; + height = image.Height; + } + } + + response = client.GetAsync(src).Result; + using (var stream = response.Content.ReadAsStreamAsync().Result) + { + imagePart.FeedData(stream); + } + var relationshipId = doc.MainDocumentPart.GetIdOfPart(imagePart); + var d = NewDrawing(relationshipId, width, height); + Run run = CreateParagraphIfNeed().AppendChild(new Run(d)); + continue; + } + if (child_node.Name == "br") { Run run = CreateParagraphIfNeed().AppendChild(new Run()); @@ -1995,5 +2043,142 @@ public static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument } #endregion + + + #region Image + + /* + public static void InsertAPicture( + MainDocumentPart mainPart, + string imageFileName) + { + ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg); + + using (FileStream stream = new FileStream(imageFileName, FileMode.Open)) + { + imagePart.FeedData(stream); + } + + AddImageToBody(mainPart, mainPart.GetIdOfPart(imagePart)); + } + */ + static ImagePartType GetImageType(string content_type) + { + var parts = StringUtil.ParseTwoPart(content_type, "/"); + string ext = parts[1]; + if (Enum.TryParse(ext, true, out ImagePartType type) == true) + return type; + if (ext.ToLower() == "jpeg" || ext.ToLower() == "jpg") + return ImagePartType.Jpeg; + if (ext.ToLower() == "x-png" || ext.ToLower() == "png") + return ImagePartType.Png; + throw new Exception($"无法识别 Content-Type '{content_type}' 的图像文件类型"); + } + + +#if REMOVED + static ImagePartType GetImageType(string imageFileName) + { + var ext = Path.GetExtension(imageFileName).Substring(1); + ImagePartType type = ImagePartType.Jpeg; + if (Enum.TryParse(ext, true, out type) == true) + return type; + if (ext.ToLower() == "jpeg" || ext.ToLower() == "jpg") + return ImagePartType.Jpeg; + throw new Exception($"无法识别文件 '{imageFileName}' 的图像文件类型"); + } +#endif + + // https://learn.microsoft.com/en-us/office/open-xml/how-to-insert-a-picture-into-a-word-processing-document + private static Drawing NewDrawing(// MainDocumentPart mainPart, + string relationshipId, + int w, + int h) + { + // https://riptutorial.com/openxml/example/29113/refer-to-the-image-in-the-word-document + Int64Value width = w * 9525; + Int64Value height = h * 9525; + + // Define the reference of the image. + var element = + new Drawing( + new DW.Inline( + new DW.Extent() { Cx = width/*990000L*/, Cy = height/*792000L*/ }, + new DW.EffectExtent() + { + LeftEdge = 0L, + TopEdge = 0L, + RightEdge = 0L, + BottomEdge = 0L + }, + new DW.DocProperties() + { + Id = (UInt32Value)1U, + Name = "Picture 1" + }, + new DW.NonVisualGraphicFrameDrawingProperties( + new A.GraphicFrameLocks() { NoChangeAspect = true }), + new A.Graphic( + new A.GraphicData( + new PIC.Picture( + new PIC.NonVisualPictureProperties( + new PIC.NonVisualDrawingProperties() + { + Id = (UInt32Value)0U, + Name = "New Bitmap Image.jpg" + }, + new PIC.NonVisualPictureDrawingProperties()), + new PIC.BlipFill( + new A.Blip( + new A.BlipExtensionList( + new A.BlipExtension() + { + Uri = + "{28A0092B-C50C-407E-A947-70E740481C1C}" + }) + ) + { + Embed = relationshipId, + CompressionState = + A.BlipCompressionValues.Print + }, + new A.Stretch( + new A.FillRectangle())), + new PIC.ShapeProperties( + new A.Transform2D( + new A.Offset() { X = 0L, Y = 0L }, + new A.Extents() { Cx = width/*990000L*/, Cy = height/*792000L*/ }), + new A.PresetGeometry( + new A.AdjustValueList() + ) + { Preset = A.ShapeTypeValues.Rectangle })) + ) + { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) + ) + { + DistanceFromTop = (UInt32Value)0U, + DistanceFromBottom = (UInt32Value)0U, + DistanceFromLeft = (UInt32Value)0U, + DistanceFromRight = (UInt32Value)0U, + EditId = "50D07946" + }); + + return element; + // Append the reference to body, the element should be in a Run. + // mainPart.Document.Body.AppendChild(new Paragraph(new Run(element))); + } + + #endregion } + + /* +DigitalPlatform.Typography + +因安装 SixLabors.ImageSharp 连带更新: + +System.Buffers.4.4.0 -> System.Buffers.4.5.1 +System.Memory.4.5.0 -> System.Memory.4.5.4 +System.Numerics.Vectors.4.4.0 -> System.Numerics.Vectors.4.5.0 +System.Runtime.CompilerServices.Unsafe.4.5.0 -> System.Runtime.CompilerServices.Unsafe.5.0.0 + * */ } diff --git a/dp2Circulation/FontSetting/MyForm.cs b/dp2Circulation/FontSetting/MyForm.cs index 9da20670a..abbf6ae72 100644 --- a/dp2Circulation/FontSetting/MyForm.cs +++ b/dp2Circulation/FontSetting/MyForm.cs @@ -3346,9 +3346,22 @@ public static string RemovePrefix(string type) return type; } + [Flags] + public enum ProcessParts + { + None = 0x00, + Basic = 0x01, + Evalue = 0x02, + } + + // 尝试获得一个列的内容值 + public delegate ProcessParts delegate_getColumnValue(Order.ColumnProperty property, out string value); + // 获得 table 格式,里面包含通过 javascript 脚本产生的列 // parameters: // style null 相当于 remove_prefix,remove_evalue + // remove_prefix 构造 format 名的时候,去掉 type 前方的 biblio_ 这样的部分 + // remove_evalue 在 GetBiblioInfos() 的 formats 列表中不包含 evalue 列名 // return: // -1 出错 // 0 没有找到 @@ -3358,6 +3371,7 @@ public int GetTable( // string strStyleList, List titles, string style, + delegate_getColumnValue func_getValue, out string strTableXml, out string strError) { @@ -3434,22 +3448,28 @@ public int GetTable( if (results.Length > 1) strBiblioXml = results[1]; - // 加入 javascript 创建的内容 - if (exists_evalue) { - int nRet = MarcUtil.Xml2Marc(strBiblioXml, + string strMarcSyntax = ""; + string strMARC = ""; + + // 加入 javascript 创建的内容 + if (exists_evalue) + { + int nRet = MarcUtil.Xml2Marc(strBiblioXml, true, null, - out string strMarcSyntax, - out string strMARC, + out strMarcSyntax, + out strMARC, out strError); - if (nRet == -1) - return -1; + if (nRet == -1) + return -1; + } - XmlDocument dom = new XmlDocument(); + // 源。table xml + XmlDocument source_dom = new XmlDocument(); try { - dom.LoadXml(string.IsNullOrEmpty(strTableXml) ? "" : strTableXml); + source_dom.LoadXml(string.IsNullOrEmpty(strTableXml) ? "
" : strTableXml); } catch (Exception ex) { @@ -3457,38 +3477,94 @@ public int GetTable( return -1; } + // 目标:处理后的 line 元素 + XmlDocument target_dom = new XmlDocument(); + target_dom.LoadXml("
"); + foreach (var column in titles) { - if (string.IsNullOrEmpty(column.Evalue)) - continue; - string type = column.Type; if (remove_prefix) type = RemovePrefix(type); + var existing_line = source_dom.DocumentElement + .SelectSingleNode($"line[@type='{type}']") as XmlElement; + + bool processed = false; + ProcessParts parts = ProcessParts.None; - var existing_line = dom.DocumentElement - .SelectSingleNode($"line[@type='{type}']") as XmlElement; string result = null; - if (existing_line != null) - result = existing_line.GetAttribute("value"); - result = AccountBookForm.RunBiblioScript( - result, - strMARC, - strMarcSyntax, - column.Evalue); - XmlElement line = existing_line; - if (line == null - || string.IsNullOrEmpty(column.Evalue) == false) // Evalue 列需要重新创建一个 line 元素 - line = dom.CreateElement("line"); - line.SetAttribute("type", type); // column.Type - line.SetAttribute("name", column.Caption); - line.SetAttribute("value", result); - if (string.IsNullOrEmpty(column.Evalue) == false) - line.SetAttribute("evalue", column.Evalue); - dom.DocumentElement.AppendChild(line); + string value = null; + if (func_getValue != null) + { + parts = func_getValue.Invoke(column, out value); + if ((parts & ProcessParts.Basic) == ProcessParts.Basic) + { + // func 已经处理过基本步骤 + result = value; + processed = true; + } + if ((parts & ProcessParts.Evalue) == ProcessParts.Evalue) + { + // func 已经处理过 Evalue 步骤 + result = value; + processed = true; + } + } + + // 本函数自行处理 Evalue 步骤 + if ((parts & ProcessParts.Evalue) != ProcessParts.Evalue + && string.IsNullOrEmpty(column.Evalue) == false) + { + if (existing_line != null) + result = existing_line.GetAttribute("value"); + result = AccountBookForm.RunBiblioScript( + result, + strMARC, + strMarcSyntax, + column.Evalue); + processed = true; + } + + // 写入 XML + if (processed) + { + /* + XmlElement line = existing_line; + if (line == null + || string.IsNullOrEmpty(column.Evalue) == false) // Evalue 列需要重新创建一个 line 元素 + { + line = source_dom.CreateElement("line"); + source_dom.DocumentElement.AppendChild(line); + } + line.SetAttribute("type", type); // column.Type + line.SetAttribute("name", column.Caption); + line.SetAttribute("value", result); + if (string.IsNullOrEmpty(column.Evalue) == false) + line.SetAttribute("evalue", column.Evalue); + */ + XmlElement line = target_dom.CreateElement("line"); + target_dom.DocumentElement.AppendChild(line); + line.SetAttribute("type", type); // column.Type + line.SetAttribute("name", column.Caption); + line.SetAttribute("value", result); + if (string.IsNullOrEmpty(column.Evalue) == false) + line.SetAttribute("evalue", column.Evalue); + } + else + { + // 没有经过处理的,原本从 table xml 中得到的行 + if (existing_line != null) + { + // 原样转移到 target_dom 中 + var fragment = target_dom.CreateDocumentFragment(); + fragment.InnerXml = existing_line.OuterXml; + target_dom.DocumentElement.AppendChild(fragment); + } + } } - strTableXml = dom.OuterXml; + // strTableXml = source_dom.OuterXml; + strTableXml = target_dom.OuterXml; } return 1; } @@ -4012,6 +4088,54 @@ internal NormalResult _saveToNewBookFile(List biblioRecPathList, strRecPath, biblio_title_list, "remove_prefix", // 不包含 remove_evalue + (Order.ColumnProperty c, out string v) => + { + v = null; + if (c.Type == "biblio_accessNo") + { + /* + // return: + // -1 出错 + // 0 没有找到 + // 1 成功 + var ret = Utility.GetSubRecords( + channel, + looping.Progress, + strRecPath, + "firstAccessNo", + out string strResult, + out string error); + */ + // return: + // -1 出错 + // 0 没有找到 + // 1 成功 + var ret = Utility.GetFirstAccessNo( + channel, + looping.Progress, + strRecPath, + out string strResult, + out string error); + v = strResult; + if (ret == -1) + v = "error:" + error; + return ProcessParts.Basic; + } + + if (c.Type == "biblio_recpath") + { + v = strRecPath; + return ProcessParts.Basic; + } + + if (c.Type == "biblio_items" + || c.Type == "items") + { + v = "placeholder"; + return ProcessParts.Basic; + } + return ProcessParts.None; + }, out string strXml, out strError); if (nRet == 0) @@ -4061,8 +4185,8 @@ internal NormalResult _saveToNewBookFile(List biblioRecPathList, } string content = BuildBiblioHtml( - channel, - looping.Progress, + //channel, + //looping.Progress, biblio_title_list, dom, strRecPath, @@ -4286,7 +4410,7 @@ string BuildItemsHtml( int line_count = 0; StringBuilder result = new StringBuilder(); if (format == "docx") - result.Append("
"); // cellMarginDefault='1pt,1pt,1pt,1pt' + result.Append("
"); // cellMarginDefault='1pt,1pt,1pt,1pt' else result.Append("
"); result.Append(BuildEntityTitle(entity_title_list, format)); @@ -4509,8 +4633,8 @@ static string BuildEntityTitle(List entity_title_list, * 自然段 * */ static string BuildBiblioHtml( - LibraryChannel channel, - Stop stop, + //LibraryChannel channel, + //Stop stop, List biblio_title_list, XmlDocument biblio_table_dom, string biblio_recpath, @@ -4535,7 +4659,7 @@ static string BuildBiblioHtml( if (layout_style == "独立表格") { if (format == "docx") - result.Append("
"); + result.Append("
"); else result.Append("
\r\n"); } @@ -4548,6 +4672,8 @@ string GetCaption(string type, string evalue = null) return biblio_title_list.Where(o => o.Type == "biblio_" + type && o.Evalue == evalue).FirstOrDefault()?.Caption; } + bool items_outputed = false; + XmlNodeList lines = biblio_table_dom.DocumentElement.SelectNodes("line"); foreach (XmlElement line in lines) { @@ -4583,10 +4709,34 @@ string GetCaption(string type, string evalue = null) OutputLineRaw($"biblio_{type}", "", $"封面图片"); continue; } + + if (type == "recpath") + { + if (string.IsNullOrEmpty(strOpacServerUrl) == false + && format != "docx") + { + string url = $"{strOpacServerUrl}book.aspx?BiblioRecPath={HttpUtility.UrlEncode(biblio_recpath)}"; + // result.AppendLine($""); + OutputLineRaw("biblio_recpath", "记录路径", $"{HttpUtility.HtmlEncode(biblio_recpath)}"); + } + else + OutputLine("biblio_recpath", GetCaption("recpath"), biblio_recpath); + continue; + } + + if (type == "items") + { + // items 占位 + result.AppendLine($"{{items}}"); + items_outputed = true; + continue; + } + // result.AppendLine($""); // style1='width:100pt;color:#aaaaaa;' OutputLine($"biblio_{type}", name, value); } + /* var display_accessNo = biblio_title_list.Where(o => o.Type == "biblio_accessNo").Any(); if (display_accessNo) { @@ -4606,10 +4756,18 @@ string GetCaption(string type, string evalue = null) accessNo = "error:" + strError; OutputLine("biblio_accessNo", GetCaption("accessNo"), accessNo); } + */ - // items 占位 - result.AppendLine($"{{items}}"); +#if REMOVED + // 如果没有明确占位,则输出到最后一项 + if (items_outputed == false) + { + // items 占位 + result.AppendLine($"{{items}}"); + } +#endif + /* var display_recpath = biblio_title_list.Where(o => o.Type == "biblio_recpath").Any(); if (display_recpath) { @@ -4623,6 +4781,7 @@ string GetCaption(string type, string evalue = null) else OutputLine("biblio_recpath", GetCaption("recpath"), biblio_recpath); } + */ if (layout_style == "独立表格") result.Append("
{HttpUtility.HtmlEncode("记录路径")}
{HttpUtility.HtmlEncode(name)}{HttpUtility.HtmlEncode(value)}
\r\n"); diff --git a/dp2Circulation/Issue/PrintBindingForm.cs b/dp2Circulation/Issue/PrintBindingForm.cs index aed958d53..c0f971d13 100644 --- a/dp2Circulation/Issue/PrintBindingForm.cs +++ b/dp2Circulation/Issue/PrintBindingForm.cs @@ -2327,6 +2327,7 @@ int PrintOneBinding( biblio_title_list, // "", null, + null, out string strTableXml, out strError); if (nRet == -1) diff --git a/dp2Circulation/OperLogStatis/OperLogStatisForm_transfer.cs b/dp2Circulation/OperLogStatis/OperLogStatisForm_transfer.cs index 4d5b458ec..7f39a736b 100644 --- a/dp2Circulation/OperLogStatis/OperLogStatisForm_transfer.cs +++ b/dp2Circulation/OperLogStatis/OperLogStatisForm_transfer.cs @@ -334,6 +334,7 @@ void WriteBiblioColumns( biblio_title_list, // styleList, null, + null, out strTableXml, out string strError1); if (nRet == -1) diff --git a/dp2Circulation/Order/DistributeExcelFile.cs b/dp2Circulation/Order/DistributeExcelFile.cs index 675ab6138..1ecbbcf72 100644 --- a/dp2Circulation/Order/DistributeExcelFile.cs +++ b/dp2Circulation/Order/DistributeExcelFile.cs @@ -299,6 +299,7 @@ GetOrderRecord procGetOrderRecord context.BiblioColList, // StringUtil.MakePathList(ColumnProperty.GetTypeList(context.BiblioColList)), null, + null, out strTableXml, out string strError); if (nRet == -1) @@ -440,6 +441,7 @@ public override void OutputDistributeInfo( context.BiblioColList, // StringUtil.MakePathList(ColumnProperty.GetTypeList(context.BiblioColList)), null, + null, out strTableXml, out string strError); if (nRet == -1) diff --git a/dp2Circulation/Order/ExportExcelFile.cs b/dp2Circulation/Order/ExportExcelFile.cs index 4ecb67820..dbb41db8c 100644 --- a/dp2Circulation/Order/ExportExcelFile.cs +++ b/dp2Circulation/Order/ExportExcelFile.cs @@ -157,6 +157,7 @@ public virtual void OutputDistributeInfo( context.BiblioColList, // StringUtil.MakePathList(ColumnProperty.GetTypeList(context.BiblioColList)), null, + null, out strTableXml, out string strError); if (nRet == -1) diff --git a/dp2Circulation/SearchForms/BiblioSearchForm.cs b/dp2Circulation/SearchForms/BiblioSearchForm.cs index ff02fc71f..ac2398e82 100644 --- a/dp2Circulation/SearchForms/BiblioSearchForm.cs +++ b/dp2Circulation/SearchForms/BiblioSearchForm.cs @@ -5046,6 +5046,7 @@ void menu_exportDetailExcelFile_1_Click(object sender, EventArgs e) strRecPath, biblio_title_list, null, + null, out strTableXml, out string strError1); if (nRet == -1) diff --git a/dp2Circulation/SearchForms/SaveNewBookFileDialog.Designer.cs b/dp2Circulation/SearchForms/SaveNewBookFileDialog.Designer.cs index fa9d02268..cd6f841b7 100644 --- a/dp2Circulation/SearchForms/SaveNewBookFileDialog.Designer.cs +++ b/dp2Circulation/SearchForms/SaveNewBookFileDialog.Designer.cs @@ -197,7 +197,6 @@ private void InitializeComponent() this.comboBox_items_style.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_items_style.FormattingEnabled = true; this.comboBox_items_style.Items.AddRange(new object[] { - "不输出", "没有册时不输出", "没有册时输出(无)"}); this.comboBox_items_style.Location = new System.Drawing.Point(23, 246); diff --git a/dp2Circulation/SearchForms/SaveNewBookFileDialog.cs b/dp2Circulation/SearchForms/SaveNewBookFileDialog.cs index fc1b216d0..33c622c2a 100644 --- a/dp2Circulation/SearchForms/SaveNewBookFileDialog.cs +++ b/dp2Circulation/SearchForms/SaveNewBookFileDialog.cs @@ -93,7 +93,7 @@ public string ItemsAreaStyle { string value = this.comboBox_items_style.Text; if (string.IsNullOrEmpty(value)) - return "不输出"; + return "没有册时输出(无)"; return value; } } @@ -258,9 +258,28 @@ public override List GetAllColumns(bool bDefault) var results = base.GetAllColumns(bDefault); if (bDefault == false) + { + { + Column column = new Column(); + column.Name = "biblio_accessNo -- 索取号"; + column.Caption = GetRightPart(column.Name); + column.MaxChars = -1; + results.Add(column); + } + + } + + { + Column column = new Column(); + column.Name = "biblio_coverimageurl -- 封面图像"; + column.Caption = GetRightPart(column.Name); + column.MaxChars = -1; + results.Insert(0, column); + } + { Column column = new Column(); - column.Name = "biblio_accessNo -- 索取号"; + column.Name = "biblio_items -- 册"; column.Caption = GetRightPart(column.Name); column.MaxChars = -1; results.Add(column); diff --git a/dp2Circulation/Utility.cs b/dp2Circulation/Utility.cs index c4432b59d..19fb5ea33 100644 --- a/dp2Circulation/Utility.cs +++ b/dp2Circulation/Utility.cs @@ -1,7 +1,5 @@ -using DigitalPlatform; -using DigitalPlatform.LibraryClient; -using DigitalPlatform.Text; -using DigitalPlatform.Xml; + +using Microsoft.CodeAnalysis.Operations; using System; using System.Collections.Generic; using System.Linq; @@ -9,10 +7,62 @@ using System.Threading.Tasks; using System.Xml; +using DigitalPlatform; +using DigitalPlatform.LibraryClient; +using DigitalPlatform.LibraryClient.localhost; +using DigitalPlatform.Text; +using DigitalPlatform.Xml; + namespace dp2Circulation { public static class Utility { + // 获得一个书目记录下属的所有册记录中第一个非空的索取号 + // return: + // -1 出错 + // 0 没有找到 + // 1 成功 + public static int GetFirstAccessNo( + LibraryChannel channel, + Stop stop, + string strRecPath, + out string strResult, + out string strError) + { + strError = ""; + strResult = ""; + + SubItemLoader sub_loader = new SubItemLoader(); + sub_loader.BiblioRecPath = strRecPath; + sub_loader.Channel = channel; + sub_loader.Stop = stop; + sub_loader.DbType = "item"; + + // sub_loader.Prompt + + foreach (EntityInfo info in sub_loader) + { + if (info.ErrorCode != ErrorCodeValue.NoError) + { + strError = "路径为 '" + info.OldRecPath + "' 的订购记录装载中发生错误: " + info.ErrorInfo; // NewRecPath + return -1; + } + + XmlDocument item_dom = new XmlDocument(); + item_dom.LoadXml(info.OldRecord); + string accessNo = DomUtil.GetElementText(item_dom.DocumentElement, + "accessNo"); + + if (string.IsNullOrEmpty(accessNo) == false) + { + strResult = accessNo; + return 1; + } + } + + return 0; + } + // 获得书目记录的下级记录 // parameters: // strDataName 数据名称。为 firstAccessNo subrecords 之一 @@ -31,6 +81,7 @@ public static int GetSubRecords( strError = ""; strResult = ""; + // 注: 最多获得 10 条册记录 long lRet = channel.GetBiblioInfos( stop, strRecPath, diff --git a/dp2Circulation/dp2Circulation.csproj b/dp2Circulation/dp2Circulation.csproj index 8492e0b1a..76b0d5920 100644 --- a/dp2Circulation/dp2Circulation.csproj +++ b/dp2Circulation/dp2Circulation.csproj @@ -23,7 +23,7 @@ true 8A609FAD04B89DDF14832D49A2DD957EC2628C66 数字平台(北京)软件有限责任公司苏州分公司.pfx - true + false true nei.ico v4.7.2 @@ -53,7 +53,7 @@ dp2 V3 true publish.htm - 412 + 415 3.78.0.%2a false true @@ -174,6 +174,9 @@ + + ..\packages\SixLabors.ImageSharp.1.0.0\lib\net472\SixLabors.ImageSharp.dll + ..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll diff --git a/dp2Circulation/packages.config b/dp2Circulation/packages.config index 2c0063098..3ea295c82 100644 --- a/dp2Circulation/packages.config +++ b/dp2Circulation/packages.config @@ -24,6 +24,7 @@ + diff --git a/dp2LibraryConsole/Instance.cs b/dp2LibraryConsole/Instance.cs index 7f805d8d7..133358954 100644 --- a/dp2LibraryConsole/Instance.cs +++ b/dp2LibraryConsole/Instance.cs @@ -849,8 +849,11 @@ static string ReadPassword() // TODO: 处理 backspace if (passwordChar == '\b') { - Console.Write("\b \b"); // 回退,覆盖一个空格,再次回退。起到抹掉最后一个字符的作用 - password.Remove(password.Length - 1, 1); + if (password.Length > 0) + { + Console.Write("\b \b"); // 回退,覆盖一个空格,再次回退。起到抹掉最后一个字符的作用 + password.Remove(password.Length - 1, 1); + } } else {