diff --git a/README.md b/README.md index 577b037..4e31f88 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ - [x] 添加语音合成 - [x] 添加离线截图翻译 - [x] 添加检查更新 -- [ ] 添加翻译记录缓存功能 +- [x] 添加翻译记录缓存功能 ## 使用 @@ -66,6 +66,8 @@ ## 开发历史 +- 2023-01-17 0.20 添加翻译记录缓存功能,重复翻译从本地数据库获取,本地记录数量上限可调整 + - 2023-01-12 0.18 优化 GC 后台静默运行内存占用保持 4MB 左右 - 2023-01-12 0.17 添加检查更新功能 diff --git a/STranslate/Helper/SqliteHelper.cs b/STranslate/Helper/SqliteHelper.cs new file mode 100644 index 0000000..ae59ac0 --- /dev/null +++ b/STranslate/Helper/SqliteHelper.cs @@ -0,0 +1,97 @@ +using SQLite; +using STranslate.Model; +using STranslate.ViewModel; +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace STranslate.Helper +{ + public class SqliteHelper : IDisposable + { + public SqliteHelper() + { + _sqlDB = new SQLiteConnection(_dbName); + _sqlDB.CreateTable(); + } + + public void Insert(DateTime time, string source, string target, LanguageEnum sourceLang, LanguageEnum targetLang, string api) + { + try + { + var model = new SqliteModel + { + Time = time, + SourceText = source, + TargetText = target, + SourceLang = sourceLang.ToString(), + TargetLang = targetLang.ToString(), + Api = api, + }; + + //查询最大数量 + var count = _sqlDB.Table().Count(); + if (count >= SettingsVM.Instance.MaxHistoryCount) + { + _sqlDB.Execute("delete from histories where id in (select id from histories limit (?))" + , count + 1 - SettingsVM.Instance.MaxHistoryCount); + } + //手动切换目标语言强制插入替换 + _sqlDB.Table() + .Where(x => x.SourceText.Equals(model.SourceText)) + .ToList().ForEach(x => + { + _sqlDB.Delete(x); + }); + _sqlDB.Insert(model); + } + catch (Exception ex) + { + System.Windows.MessageBox.Show($"本地记录插入错误\n{ex.Message}"); + } + } + + /// + /// 查询记录 + /// + /// + /// + public string Query(string str) + { + var query = _sqlDB.Table().Where(x => x.SourceText.Equals(str)); + if (query.Count() <= 0) + { + return string.Empty; + } + else//如果超过一个删除多余的 + { + var tmp = query.ToList(); + for (int i = 1; i < tmp.Count; i++) + { + _sqlDB.Delete(tmp[i]); + } + return query.First().TargetText; + } + } + + public void Dispose() + { + _sqlDB.Close(); + } + + private readonly SQLiteConnection _sqlDB; + + /// + /// 数据文件 + /// + private static string _dbName => $"{_ApplicationData}\\{_AppName.ToLower()}.db"; + + /// + /// C:\Users\user\AppData\Local\STranslate + /// + private static string _ApplicationData => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\{_AppName}"; + private static readonly string _AppName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location); + } +} diff --git a/STranslate/Model/ConfigModel.cs b/STranslate/Model/ConfigModel.cs index 3ca9d35..b3b43b8 100644 --- a/STranslate/Model/ConfigModel.cs +++ b/STranslate/Model/ConfigModel.cs @@ -17,6 +17,7 @@ namespace STranslate.Model { return new ConfigModel { + MaxHistoryCount = 100, AutoScale = 0.8, WordPickupInterval = 200, IsBright = true, @@ -44,6 +45,11 @@ namespace STranslate.Model }; } + /// + /// 最大历史记录数量 + /// + [JsonProperty("maxHistoryCount")] + public int MaxHistoryCount { get; set; } /// /// 自动识别语种标度 /// diff --git a/STranslate/Model/SqliteModel.cs b/STranslate/Model/SqliteModel.cs new file mode 100644 index 0000000..66624cc --- /dev/null +++ b/STranslate/Model/SqliteModel.cs @@ -0,0 +1,38 @@ +using SQLite; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace STranslate.Model +{ + [Table("Histories")] + public class SqliteModel + { + [PrimaryKey, AutoIncrement] + [Column("id")] + public int Id { get; set; } + + [Column("time")] + public DateTime Time { get; set; } + + [Column("source_lang")] + public string SourceLang { get; set; } + + [Column("target_lang")] + public string TargetLang { get; set; } + + [Column("source_text")] + public string SourceText { get; set; } + + [Column("target_text")] + public string TargetText { get; set; } + + [Column("api")] + public string Api { get; set; } + + [Column("remark")] + public string Remark { get; set; } + } +} diff --git a/STranslate/Properties/AssemblyInfo.cs b/STranslate/Properties/AssemblyInfo.cs index f3795bf..8928f40 100644 --- a/STranslate/Properties/AssemblyInfo.cs +++ b/STranslate/Properties/AssemblyInfo.cs @@ -47,6 +47,6 @@ using System.Windows; //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.9.0")] -[assembly: AssemblyFileVersion("0.1.9.0")] +[assembly: AssemblyVersion("0.2.0.0")] +[assembly: AssemblyFileVersion("0.2.0.0")] [assembly: Guid("CE252DD8-179F-4544-9989-453F5DEA378D")] \ No newline at end of file diff --git a/STranslate/STranslate.csproj b/STranslate/STranslate.csproj index 8485ea9..ffc4022 100644 --- a/STranslate/STranslate.csproj +++ b/STranslate/STranslate.csproj @@ -59,9 +59,37 @@ ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\sqlite-net-pcl.1.8.116\lib\netstandard2.0\SQLite-net.dll + + + ..\packages\SQLitePCLRaw.bundle_green.2.0.4\lib\net461\SQLitePCLRaw.batteries_v2.dll + + + ..\packages\SQLitePCLRaw.core.2.0.4\lib\netstandard2.0\SQLitePCLRaw.core.dll + + + ..\packages\SQLitePCLRaw.bundle_green.2.0.4\lib\net461\SQLitePCLRaw.nativelibrary.dll + + + ..\packages\SQLitePCLRaw.provider.dynamic_cdecl.2.0.4\lib\netstandard2.0\SQLitePCLRaw.provider.dynamic_cdecl.dll + + + ..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + @@ -95,8 +123,10 @@ + + True @@ -230,5 +260,7 @@ 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + \ No newline at end of file diff --git a/STranslate/View/SettingsWindow.xaml b/STranslate/View/SettingsWindow.xaml index c49c1f7..f88cc95 100644 --- a/STranslate/View/SettingsWindow.xaml +++ b/STranslate/View/SettingsWindow.xaml @@ -80,6 +80,21 @@ + + + + + + + + diff --git a/STranslate/ViewModel/MainVM.cs b/STranslate/ViewModel/MainVM.cs index 735538b..cbee5b9 100644 --- a/STranslate/ViewModel/MainVM.cs +++ b/STranslate/ViewModel/MainVM.cs @@ -25,6 +25,7 @@ namespace STranslate.ViewModel InputCombo = LanguageEnumDict.Keys.ToList(); OutputCombo = LanguageEnumDict.Keys.ToList(); + _sqlHelper = new SqliteHelper(); #endregion #region Common @@ -209,6 +210,8 @@ namespace STranslate.ViewModel Util.Util.FlushMemory(); Mainwin.NotifyIcon.Dispose(); Mainwin.Close(); + //关闭数据库 + _sqlHelper.Dispose(); //语音合成销毁 _speech.Dispose(); //注销快捷键 @@ -231,6 +234,10 @@ namespace STranslate.ViewModel { _globalConfig = ConfigHelper.Instance.ReadConfig(); + //读取历史记录数量 + var count = _globalConfig.MaxHistoryCount; + SettingsVM.Instance.MaxHistoryCount = (count <= 0 || count >= 1000) ? 100 : count; + //读取自动识别语种比例 var scale = _globalConfig.AutoScale; SettingsVM.Instance.AutoScale = (scale <= 0 || scale >= 1) ? 0.8 : scale; @@ -275,6 +282,7 @@ namespace STranslate.ViewModel { ConfigHelper.Instance.WriteConfig(new ConfigModel { + MaxHistoryCount = SettingsVM.Instance.MaxHistoryCount, AutoScale = SettingsVM.Instance.AutoScale, WordPickupInterval = SettingsVM.Instance.WordPickupInterval, IsBright = Application.Current.Resources.MergedDictionaries[0].Source.ToString() == ThemeDefault ? true : false, @@ -330,7 +338,8 @@ namespace STranslate.ViewModel { try { - if (string.IsNullOrEmpty(InputTxt.Trim())) throw new Exception("输入值为空!"); + if (string.IsNullOrEmpty(InputTxt.Trim())) + throw new Exception("输入值为空!"); var isEng = string.Empty; IdentifyLanguage = string.Empty; OutputTxt = "翻译中..."; @@ -342,6 +351,13 @@ namespace STranslate.ViewModel //自动选择目标语言 if (OutputComboSelected == LanguageEnum.AUTO.GetDescription()) { + //只有在自动的模式下读取 + var resp = _sqlHelper.Query(InputTxt); + if (!string.IsNullOrEmpty(resp)) + { + OutputTxt = resp; + return; + } var autoRet = AutomaticLanguageRecognition(InputTxt); IdentifyLanguage = autoRet.Item1; isEng = autoRet.Item2; @@ -361,6 +377,16 @@ namespace STranslate.ViewModel } OutputTxt = _translateResp; + await Task.Run(() => + { + _sqlHelper.Insert(DateTime.Now, + InputTxt, + OutputTxt, + LanguageEnumDict[string.IsNullOrEmpty(IdentifyLanguage) ? InputComboSelected : IdentifyLanguage], + LanguageEnumDict[string.IsNullOrEmpty(isEng) ? OutputComboSelected : isEng], + SelectedTranslationInterface.Api); + }); + //如果目标语言不是英文则不进行转换 //1. 自动判断语种:Tuple item2 不为 EN //2. 非自动判断语种,目标语种不为 EN @@ -390,6 +416,7 @@ namespace STranslate.ViewModel #endregion handle #region Params + private readonly SqliteHelper _sqlHelper; private string _translateResp; public ICommand MouseLeftDownCmd { get; set; } public ICommand DeactivatedCmd { get; set; } diff --git a/STranslate/ViewModel/SettingsVM.cs b/STranslate/ViewModel/SettingsVM.cs index 4d7a44b..ded2b15 100644 --- a/STranslate/ViewModel/SettingsVM.cs +++ b/STranslate/ViewModel/SettingsVM.cs @@ -136,5 +136,11 @@ namespace STranslate.ViewModel private double _wordPickupInterval; public double WordPickupInterval { get => _wordPickupInterval; set => UpdateProperty(ref _wordPickupInterval, value); } + /// + /// 最大历史记录数量 + /// + private int _maxHistoryCount; + public int MaxHistoryCount { get => _maxHistoryCount; set => UpdateProperty(ref _maxHistoryCount, value); } + } } diff --git a/STranslate/packages.config b/STranslate/packages.config index d6aaa03..43d68aa 100644 --- a/STranslate/packages.config +++ b/STranslate/packages.config @@ -2,6 +2,15 @@ + + + + + + + + + \ No newline at end of file