From d16d6d4671a56a5774e0edb0d7d52b4c0bed5c4f Mon Sep 17 00:00:00 2001 From: callmeyan Date: Mon, 10 Mar 2025 16:46:47 +0800 Subject: [PATCH] =?UTF-8?q?fixed:=20=E2=9C=A8=EF=B8=8F=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=85=B3=E9=97=AD=E5=90=8E=E5=86=8D=E6=AC=A1?= =?UTF-8?q?=E6=89=93=E5=BC=80=E5=B1=95=E7=A4=BA=E5=A4=9A=E4=B8=AA=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AIProofread/AIProofread.csproj | 6 ++++ AIProofread/Bridge.cs | 31 ++++++++++++++-- AIProofread/Config.cs | 6 ++-- AIProofread/Controls/FormLogin.cs | 3 +- AIProofread/Model/DocumentInfo.cs | 5 +-- AIProofread/Model/ExportDataItem.cs | 30 +++++++++------- AIProofread/Properties/AssemblyInfo.cs | 10 +++--- AIProofread/ThisAddIn.cs | 48 +++++++++++++++++++------ AIProofread/core/DocumentUtil.cs | 12 +++++-- AIProofread/favicon.ico | Bin 0 -> 10022 bytes updater/Form1.cs | 4 +-- 11 files changed, 113 insertions(+), 42 deletions(-) create mode 100644 AIProofread/favicon.ico diff --git a/AIProofread/AIProofread.csproj b/AIProofread/AIProofread.csproj index 46ddc81..e08abca 100644 --- a/AIProofread/AIProofread.csproj +++ b/AIProofread/AIProofread.csproj @@ -558,6 +558,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) @@ -585,6 +588,9 @@ AnyCPU 7.3 + + favicon.ico + diff --git a/AIProofread/Bridge.cs b/AIProofread/Bridge.cs index eb585cf..0449052 100644 --- a/AIProofread/Bridge.cs +++ b/AIProofread/Bridge.cs @@ -7,6 +7,7 @@ using Microsoft.Office.Tools.Word; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.WinForms; using Newtonsoft.Json; +using NPOI.SS.Formula; using NPOI.XSSF.UserModel; using NPOI.XWPF.UserModel; using Org.BouncyCastle.Asn1.Crmf; @@ -377,6 +378,22 @@ namespace AIProofread return Tools.GetJSONString(data); } + public string GetDocumentInfo(int documentId) + { + Dictionary data = new Dictionary(); + var documentInfo = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument; + var doc = documentInfo.CurrentDocument; + data.Add("code", 0); + data.Add("message", "success"); + data.Add("name", doc.Name); + //data.Add("documentId", Globals.ThisAddIn.ActiveDocument.Id); + data.Add("fullName", doc.FullName); + data.Add("documentId", GeIdBytDocument(doc)); + data.Add("wordsCount", doc.Words.Count); + data.Add("charactersCount", doc.Characters.Count); + return Tools.GetJSONString(data); + } + /// /// 根据位置获取文档区域文本 /// @@ -514,11 +531,21 @@ namespace AIProofread public void ClearCurrentDocumentMarks() => Globals.ThisAddIn.ActiveDocument?.ClearAllProofreadMark(); public void removeBookmark(string markId) => DocumentUtil.RemoveBookmark(markId); + /// + /// 获取设备ID + /// + /// public string GetDeviceId() { return Config.DeviceId; } + /// + /// 设置帮助文档地址 + /// + /// + public void SetHelpUrl(string url) => Config.USER_MANUAL_URL = url; + public string getAllBookmark() { return ToJSON(DocumentUtil.GetAllBookmark()); @@ -715,11 +742,11 @@ namespace AIProofread /// 导出勘误表 /// /// - public string ExportProofreadResult() + public string ExportProofreadResult(string modelType) { try { - Globals.ThisAddIn.ActiveDocument.ExportResult(); + Globals.ThisAddIn.ActiveDocument.ExportResult(modelType); return BridgeResult.Success(); } catch (Exception ex) diff --git a/AIProofread/Config.cs b/AIProofread/Config.cs index 6013db3..d4a1ff1 100644 --- a/AIProofread/Config.cs +++ b/AIProofread/Config.cs @@ -12,12 +12,12 @@ namespace AIProofread public class Config { public static readonly string APP_NAME = "AI校对王"; - public static readonly string APP_VERSION = "2.2.0"; + public static readonly string APP_VERSION = "2.2.1"; public static bool IS_WPS = false; public static bool UpgradeForcedNotice = false; public static readonly string APP_BASE_DIR = AppDomain.CurrentDomain.BaseDirectory; public static readonly string CONFIG_FILE = AppDomain.CurrentDomain.BaseDirectory + "app.json"; - public static readonly string USER_MANUAL_URL = "https://doc.weixin.qq.com/doc/w3_AMYAMAaTAKQFkUi5WkYT1OPSXFD17?scode=ACQARAe_AAsF7LbNrM"; + public static string USER_MANUAL_URL = "https://aiprhelp.guomai.cn/"; /// /// 文本背景色 /// @@ -31,7 +31,7 @@ namespace AIProofread public static bool RUN_IN_DEBUG = true; public static AppEnvironment APP_ENV = AppEnvironment.Dev; #else - public static string WEB_PATH = "http://gm2-plugin.zverse.group/"; // gm-plugin.gachafun.com pre-gm-plugin.gachafun.com + public static string WEB_PATH = "https://gm-plugin.gachafun.com/"; // gm-plugin.gachafun.com pre-gm-plugin.gachafun.com public static bool RUN_IN_DEBUG = false; public static AppEnvironment APP_ENV = AppEnvironment.Prod; #endif diff --git a/AIProofread/Controls/FormLogin.cs b/AIProofread/Controls/FormLogin.cs index 803d46e..2d003bd 100644 --- a/AIProofread/Controls/FormLogin.cs +++ b/AIProofread/Controls/FormLogin.cs @@ -31,7 +31,8 @@ namespace AIProofread.Controls private void FormLogin_Load(object sender, EventArgs e) { //this.web.Source = new Uri(Config.WebPath("#login")); - InitWebView(web, Config.WebPath("login?action=" + this.action), "login"); + var r = new FormLogin(); + InitWebView(web, Config.WebPath("login?action=" + this.action + "&version=" + Config.APP_VERSION + "&t=" + DateTime.Now.Ticks), "login"); } diff --git a/AIProofread/Model/DocumentInfo.cs b/AIProofread/Model/DocumentInfo.cs index 618cfcf..14d5e56 100644 --- a/AIProofread/Model/DocumentInfo.cs +++ b/AIProofread/Model/DocumentInfo.cs @@ -211,6 +211,7 @@ namespace AIProofread.Model { try { + if(TaskPane.Control.IsDisposed) return; ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control; control.ResetWeb(); @@ -903,11 +904,11 @@ namespace AIProofread.Model } } - public void ExportResult() + public void ExportResult(string modelType) { TaskPane.Control.BeginInvoke(new Action(() => { - DocumentUtil.ExportProofreadResult(); + DocumentUtil.ExportProofreadResult(modelType); })); } diff --git a/AIProofread/Model/ExportDataItem.cs b/AIProofread/Model/ExportDataItem.cs index fd74d96..df15677 100644 --- a/AIProofread/Model/ExportDataItem.cs +++ b/AIProofread/Model/ExportDataItem.cs @@ -1,4 +1,5 @@ using Microsoft.Office.Interop.Word; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; @@ -32,21 +33,24 @@ namespace AIProofread.Model return sentence; } // 截取中间位置 - var middlePosition = MAX_WORD_LENGTH / 2; - var cutStart = item.content.Start - middlePosition; - // 越界了 - if(cutStart < 0) + try { - cutStart = 0; - } - var originText = sentence.Substring(cutStart, MAX_WORD_LENGTH); - Debug.WriteLine($"{cutStart} {originText}"); - if (!isInsert) - { - item.content.Start = item.content.Start - cutStart; - item.content.End = item.content.End - cutStart; - return originText; + var middlePosition = MAX_WORD_LENGTH / 2; + var cutStart = item.content.Start - middlePosition; + // 越界了 + if (cutStart < 0) + { + cutStart = 0; + } + var originText = sentence.Substring(cutStart, Math.Min(sentence.Length, MAX_WORD_LENGTH)); + if (!isInsert) + { + item.content.Start = item.content.Start - cutStart; + item.content.End = item.content.End - cutStart; + return originText; + } } + catch (Exception ex) { } var range = item.mark.Range; // 获取range所在句子 diff --git a/AIProofread/Properties/AssemblyInfo.cs b/AIProofread/Properties/AssemblyInfo.cs index ceed13f..a31bd9c 100644 --- a/AIProofread/Properties/AssemblyInfo.cs +++ b/AIProofread/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ using System.Security; // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("AI校对王")] -[assembly: AssemblyDescription("AI校对王 2.1.2")] +[assembly: AssemblyDescription("AI校对王 2.2.1")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("果麦文化")] -[assembly: AssemblyProduct("AI校对王 2.1.2")] -[assembly: AssemblyCopyright("Copyright © GuoMai 2024")] +[assembly: AssemblyCompany("果麦文化传媒股份有限公司")] +[assembly: AssemblyProduct("AI校对王 2.2.1")] +[assembly: AssemblyCopyright("Copyright © 果麦文化传媒股份有限公司 2025")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -34,5 +34,5 @@ using System.Security; // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("2.0")] -[assembly: AssemblyFileVersion("2.1.2.0")] +[assembly: AssemblyFileVersion("2.2.1.0")] diff --git a/AIProofread/ThisAddIn.cs b/AIProofread/ThisAddIn.cs index 2416803..e6263a9 100644 --- a/AIProofread/ThisAddIn.cs +++ b/AIProofread/ThisAddIn.cs @@ -92,9 +92,9 @@ namespace AIProofread formCommonsenseDetection = null; } - private void ProcessApplicationException(object sender,UnhandledExceptionEventArgs e) + private void ProcessApplicationException(object sender, UnhandledExceptionEventArgs e) { - Logger.Log("UnhandledException",e.ExceptionObject as Exception); + Logger.Log("UnhandledException", e.ExceptionObject as Exception); } private void ProcessApplicationFormException(object sender, System.Threading.ThreadExceptionEventArgs e) @@ -167,15 +167,15 @@ namespace AIProofread } }); } - + public void CheckDocumentClosed(object sender, System.Timers.ElapsedEventArgs e) { var existsList = new List(); - //Logger.Log("检测文档是否关闭 ..."); + Logger.Log("检测文档是否关闭 ..."); try { - if (documentList.Count == 0 || CurrentWordApplication.Documents.Count == documentList.Count) return; + if (documentList.Count == 0) return; existsList.Clear(); @@ -184,12 +184,32 @@ namespace AIProofread existsList.Add(item.FullName); } // 检测文档是否关闭 - foreach (var item in documentList.documentList) + for (int i = documentList.documentList.Count - 1; i >= 0; i--) { + var item = documentList.documentList[i]; if (!existsList.Contains(item.fileName)) { Logger.Log("检测到文档关闭,已移除:" + item.fileName); - documentList.Remove(item); + try + { + item.RunInMainThread(() => + { + item.Dispose(); + }); + } + catch (Exception ext) + { + Logger.Log(ext); + } + + try + { + documentList.Remove(item); + } + catch (Exception ext) + { + Logger.Log(ext); + } } } } @@ -320,6 +340,7 @@ namespace AIProofread // 设置当前文档 ActiveDocument = documentList.SetActiveDocument(CurrentWordApplication.ActiveDocument); ActiveDocument.CheckBtnStatus(); + CheckDocumentClosed(null,null); Logger.Log("Application_DocumentChange -- " + ActiveDocument.fileName); } @@ -378,6 +399,11 @@ namespace AIProofread /// private void Application_DocumentBeforeClose(Document currentDoc, ref bool Cancel) { + var doc = documentList.Get(currentDoc); + if (doc != null) + { + doc.HidePane(); + } Logger.Log("DocumentBeforeClose", currentDoc.FullName); //if (allMarks.ContainsKey(currentDoc)) //{ @@ -531,7 +557,7 @@ namespace AIProofread System.Windows.Forms.Application.ThreadException -= ProcessApplicationFormException; Logger.Log("shutdown"); documentList.Clear(); - if(_timer != null) + if (_timer != null) { _timer.Stop(); } @@ -586,8 +612,8 @@ namespace AIProofread } - //public string LoadCacheByPath() - //{ + //public string LoadCacheByPath() + //{ //} @@ -603,7 +629,7 @@ namespace AIProofread /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// - private void InternalStartup() + private void InternalStartup() { this.Startup += new System.EventHandler(ThisAddIn_Startup); this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); diff --git a/AIProofread/core/DocumentUtil.cs b/AIProofread/core/DocumentUtil.cs index 09ebf0f..c336de6 100644 --- a/AIProofread/core/DocumentUtil.cs +++ b/AIProofread/core/DocumentUtil.cs @@ -113,7 +113,8 @@ namespace AIProofread try { // feat(20250305): 清除批注的时候,如果监测到书签位置是空格,把空格给删了吧(无缓冲记录时) - if (mark.Range.Text.Trim().Length == 0) + string text = mark.Range.Text; + if (text != null && text.Trim().Length == 0) { mark.Range.Text = ""; } @@ -576,14 +577,15 @@ namespace AIProofread } - public static void ExportProofreadResult() + public static void ExportProofreadResult(string modelType) { string currentName = Globals.ThisAddIn.Application.ActiveDocument.Name; // 去掉文件名后缀 currentName = currentName.Substring(0, currentName.LastIndexOf(".")); SaveFileDialog sfd = new SaveFileDialog(); + modelType = modelType == "full" ? "查全" : "查准"; // 设置默认文件名 - sfd.FileName = currentName + "_勘误表.xlsx"; + sfd.FileName = currentName + $"_勘误表_优先{modelType}.xlsx"; sfd.Filter = "Excel文件|*.xlsx"; var result = sfd.ShowDialog(); // 如果用户取消选择,则返回 @@ -846,6 +848,10 @@ namespace AIProofread { tag = "黑名单"; } + else if(it.Type == "fallen_officers") + { + tag = "落马官员"; + } else if (it.Tag == "i") { startIndex = it.Text.Length + 1; diff --git a/AIProofread/favicon.ico b/AIProofread/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cfe55e5a83562057597d33caebb5e0893a66a0ee GIT binary patch literal 10022 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