diff --git a/STranslate.Model/Enums.cs b/STranslate.Model/Enums.cs index cdac6943..fa335a7e 100644 --- a/STranslate.Model/Enums.cs +++ b/STranslate.Model/Enums.cs @@ -110,6 +110,7 @@ public enum ServiceType NiutransService, CaiyunService, VolcengineService, + STranslateService, } /// diff --git a/STranslate.Style/Styles/Themes/ColorDark.xaml b/STranslate.Style/Styles/Themes/ColorDark.xaml index 5bc8d27c..4edd28bb 100644 --- a/STranslate.Style/Styles/Themes/ColorDark.xaml +++ b/STranslate.Style/Styles/Themes/ColorDark.xaml @@ -80,4 +80,5 @@ #e6c619 + #7CCD7C \ No newline at end of file diff --git a/STranslate.Style/Styles/Themes/ColorLight.xaml b/STranslate.Style/Styles/Themes/ColorLight.xaml index 9e9021db..54d52a9a 100644 --- a/STranslate.Style/Styles/Themes/ColorLight.xaml +++ b/STranslate.Style/Styles/Themes/ColorLight.xaml @@ -80,4 +80,5 @@ #e6c619 + #7CCD7C \ No newline at end of file diff --git a/STranslate.Util/Volcengine.cs b/STranslate.Util/GoUtil.cs similarity index 85% rename from STranslate.Util/Volcengine.cs rename to STranslate.Util/GoUtil.cs index 4537957e..49e54923 100644 --- a/STranslate.Util/Volcengine.cs +++ b/STranslate.Util/GoUtil.cs @@ -1,17 +1,18 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; namespace STranslate.Util { - public class Volcengine + public class GoUtil { [DllImport("volcengine.dll", EntryPoint = "Execute", CallingConvention = CallingConvention.Cdecl)] public static extern GoTuple Execute(byte[] appid, byte[] appkey, byte[] source, byte[] target, byte[] content); + [DllImport("zstranslator.dll", EntryPoint = "Execute", CallingConvention = CallingConvention.Cdecl)] + public static extern GoString Execute(byte[] source, byte[] target, byte[] content); + + public struct GoTuple { public int intValue; diff --git a/STranslate.Util/STranslate.Util.csproj b/STranslate.Util/STranslate.Util.csproj index ca83cacf..6ae12d68 100644 --- a/STranslate.Util/STranslate.Util.csproj +++ b/STranslate.Util/STranslate.Util.csproj @@ -13,6 +13,7 @@ + @@ -31,6 +32,9 @@ PreserveNewest + + PreserveNewest + diff --git a/STranslate.Util/zstranslator.dll b/STranslate.Util/zstranslator.dll new file mode 100644 index 00000000..8af29d95 Binary files /dev/null and b/STranslate.Util/zstranslator.dll differ diff --git a/STranslate/Helper/ConfigHelper.cs b/STranslate/Helper/ConfigHelper.cs index 8360892d..552a4540 100644 --- a/STranslate/Helper/ConfigHelper.cs +++ b/STranslate/Helper/ConfigHelper.cs @@ -276,8 +276,9 @@ private ConfigModel InitialConfig() TargetLanguage = LanguageEnum.AUTO.GetDescription(), Services = [ - new TranslatorApi(Guid.NewGuid(), "https://deeplx.deno.dev/translate", "DeepL"), - new TranslatorApi(Guid.NewGuid(), "https://googlet.deno.dev/translate", "Google", IconType.Google, isEnabled: true), + new TranslatorSTranslate(Guid.NewGuid(), "", "STranslate", IconType.STranslate), + new TranslatorApi(Guid.NewGuid(), "https://googlet.deno.dev/translate", "Google", IconType.Google), + new TranslatorApi(Guid.NewGuid(), "https://deeplx.deno.dev/translate", "DeepL", IconType.DeepL), new TranslatorApi(Guid.NewGuid(), "https://iciba.deno.dev/translate", "爱词霸", IconType.Iciba, isEnabled: false) ] }; @@ -320,6 +321,7 @@ JsonSerializer serializer ITranslator translator = type switch { + (int)ServiceType.STranslateService => new TranslatorSTranslate(), (int)ServiceType.ApiService => new TranslatorApi(), (int)ServiceType.BaiduService => new TranslatorBaidu(), (int)ServiceType.MicrosoftService => new TranslatorMicrosoft(), diff --git a/STranslate/ViewModels/InputViewModel.cs b/STranslate/ViewModels/InputViewModel.cs index 990c44ea..867a9357 100644 --- a/STranslate/ViewModels/InputViewModel.cs +++ b/STranslate/ViewModels/InputViewModel.cs @@ -465,6 +465,7 @@ public override ITranslator ReadJson(JsonReader reader, Type objectType, ITransl translators.FirstOrDefault(x => x.Identify.ToString() == identify) ?? type switch { + (int)ServiceType.STranslateService => new TranslatorSTranslate(), (int)ServiceType.BaiduService => new TranslatorBaidu(), (int)ServiceType.MicrosoftService => new TranslatorMicrosoft(), (int)ServiceType.OpenAIService => new TranslatorOpenAI(), diff --git a/STranslate/ViewModels/Preference/History/HistoryContentViewModel.cs b/STranslate/ViewModels/Preference/History/HistoryContentViewModel.cs index f2eb50bc..14802ecd 100644 --- a/STranslate/ViewModels/Preference/History/HistoryContentViewModel.cs +++ b/STranslate/ViewModels/Preference/History/HistoryContentViewModel.cs @@ -78,6 +78,7 @@ public override ITranslator ReadJson(JsonReader reader, Type objectType, ITransl ITranslator translator = type switch { + (int)ServiceType.STranslateService => new TranslatorSTranslate(), (int)ServiceType.ApiService => new TranslatorApi(), (int)ServiceType.BaiduService => new TranslatorBaidu(), (int)ServiceType.MicrosoftService => new TranslatorMicrosoft(), diff --git a/STranslate/ViewModels/Preference/ServiceViewModel.cs b/STranslate/ViewModels/Preference/ServiceViewModel.cs index 4fa07198..f663756b 100644 --- a/STranslate/ViewModels/Preference/ServiceViewModel.cs +++ b/STranslate/ViewModels/Preference/ServiceViewModel.cs @@ -22,6 +22,7 @@ public ServiceViewModel() { //添加默认支持服务 //TODO: 新接口需要适配 + TransServices.Add(new TranslatorSTranslate()); TransServices.Add(new TranslatorApi()); TransServices.Add(new TranslatorOpenAI()); TransServices.Add(new TranslatorGemini()); @@ -90,6 +91,7 @@ private void TogglePage(ITranslator service) //TODO: 新接口需要适配 var name = service.Type switch { + ServiceType.STranslateService => string.Format("{0}TextSTranslateServicesPage", head), ServiceType.ApiService => string.Format("{0}TextApiServicePage", head), ServiceType.BaiduService => string.Format("{0}TextBaiduServicesPage", head), ServiceType.MicrosoftService => string.Format("{0}TextMicrosoftServicesPage", head), @@ -121,6 +123,7 @@ private void Add(List list) //TODO: 新接口需要适配 CurTransServiceList.Add(service switch { + TranslatorSTranslate stranslate => stranslate.DeepClone(), TranslatorApi api => api.DeepClone(), TranslatorBaidu baidu => baidu.DeepClone(), TranslatorMicrosoft bing => bing.DeepClone(), diff --git a/STranslate/ViewModels/Preference/Services/TranslatorSTranslate.cs b/STranslate/ViewModels/Preference/Services/TranslatorSTranslate.cs new file mode 100644 index 00000000..377a1f47 --- /dev/null +++ b/STranslate/ViewModels/Preference/Services/TranslatorSTranslate.cs @@ -0,0 +1,148 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using STranslate.Model; +using STranslate.Util; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace STranslate.ViewModels.Preference.Services +{ + public partial class TranslatorSTranslate : ObservableObject, ITranslator + { + public TranslatorSTranslate() + : this(Guid.NewGuid(), "", "STranslate") { } + + public TranslatorSTranslate( + Guid guid, + string url, + string name = "", + IconType icon = IconType.STranslate, + string appID = "", + string appKey = "", + bool isEnabled = true, + ServiceType type = ServiceType.STranslateService + ) + { + Identify = guid; + Url = url; + Name = name; + Icon = icon; + AppID = appID; + AppKey = appKey; + IsEnabled = isEnabled; + Type = type; + } + + [ObservableProperty] + private Guid _identify = Guid.Empty; + + [JsonIgnore] + [ObservableProperty] + private ServiceType _type = 0; + + [JsonIgnore] + [ObservableProperty] + public bool _isEnabled = true; + + [JsonIgnore] + [ObservableProperty] + private string _name = string.Empty; + + [JsonIgnore] + [ObservableProperty] + private IconType _icon = IconType.STranslate; + + [JsonIgnore] + [ObservableProperty] + public string _url = string.Empty; + + [JsonIgnore] + [ObservableProperty] + public string _AppID = string.Empty; + + [JsonIgnore] + [ObservableProperty] + public string _appKey = string.Empty; + + [JsonIgnore] + [ObservableProperty] + [property: JsonIgnore] + public TranslationResult _data = TranslationResult.Reset; + + [JsonIgnore] + public List Icons { get; private set; } = Enum.GetValues(typeof(IconType)).OfType().ToList(); + + [JsonIgnore] + public string Tips { get; set; } = "本地服务,无需配置"; + + #region Show/Hide Encrypt Info + + [JsonIgnore] + [ObservableProperty] + [property: JsonIgnore] + private bool _idHide = true; + + [JsonIgnore] + [ObservableProperty] + [property: JsonIgnore] + private bool _keyHide = true; + + private void ShowEncryptInfo(string? obj) + { + if (obj == null) + return; + + if (obj.Equals(nameof(AppID))) + { + IdHide = !IdHide; + } + else if (obj.Equals(nameof(AppKey))) + { + KeyHide = !KeyHide; + } + } + + private RelayCommand? showEncryptInfoCommand; + + [JsonIgnore] + public IRelayCommand ShowEncryptInfoCommand => showEncryptInfoCommand ??= new RelayCommand(new Action(ShowEncryptInfo)); + + #endregion Show/Hide Encrypt Info + + public async Task TranslateAsync(object request, CancellationToken token) + { + if (request is RequestModel req) + { + //https://github.com/Baozisoftware/go-dll/wiki/C%23%E8%B0%83%E7%94%A8Go%E7%89%88DLL#%E5%85%B3%E4%BA%8Ego%E7%9A%84%E6%95%B0%E7%BB%84%E5%88%87%E7%89%87%E8%BF%94%E5%9B%9E%E9%97%AE%E9%A2%98 + //加入这个就不崩溃了 + Environment.SetEnvironmentVariable("GODEBUG", "cgocheck=0"); + var sourceBytes = Encoding.UTF8.GetBytes(req.SourceLang); + var targetBytes = Encoding.UTF8.GetBytes(req.TargetLang); + var contentBytes = Encoding.UTF8.GetBytes(req.Text); + var result = await Task.Run(() => GoUtil.Execute(sourceBytes, targetBytes, contentBytes)); + var resp = GoUtil.GoStringToCSharpString(result); + + // 解析JSON数据 + var parsedData = JsonConvert.DeserializeObject(resp ?? throw new Exception("请求结果为空")) ?? throw new Exception($"反序列化失败: {resp}"); + + // 提取content的值 + var data = parsedData["data"]?.ToString() ?? throw new Exception("未获取到结果"); + + return string.IsNullOrEmpty(data) ? TranslationResult.Fail("获取结果为空") : TranslationResult.Success(data); + } + + throw new Exception($"请求数据出错: {request}"); + } + + public Task TranslateAsync(object request, Action OnDataReceived, CancellationToken token) + { + throw new NotImplementedException(); + } + } +} diff --git a/STranslate/ViewModels/Preference/Services/TranslatorVolcengine.cs b/STranslate/ViewModels/Preference/Services/TranslatorVolcengine.cs index cb9d79a4..79ea68f7 100644 --- a/STranslate/ViewModels/Preference/Services/TranslatorVolcengine.cs +++ b/STranslate/ViewModels/Preference/Services/TranslatorVolcengine.cs @@ -125,8 +125,8 @@ public async Task TranslateAsync(object request, Cancellation var sourceBytes = Encoding.UTF8.GetBytes(req.SourceLang.ToLower()); var targetBytes = Encoding.UTF8.GetBytes(req.TargetLang.ToLower()); var contentBytes = Encoding.UTF8.GetBytes(req.Text); - var result = await Task.Run(() => Volcengine.Execute(accessKeyBytes, secretKeyBytes, sourceBytes, targetBytes, contentBytes)); - var tuple = Volcengine.GoTupleToCSharpTuple(result); + var result = await Task.Run(() => GoUtil.Execute(accessKeyBytes, secretKeyBytes, sourceBytes, targetBytes, contentBytes)); + var tuple = GoUtil.GoTupleToCSharpTuple(result); var resp = tuple.Item2; if (tuple.Item1 != 200) throw new Exception(resp); diff --git a/STranslate/Views/Preference/Service/TextApiServicePage.xaml b/STranslate/Views/Preference/Service/TextApiServicePage.xaml index 844966e1..ff396086 100644 --- a/STranslate/Views/Preference/Service/TextApiServicePage.xaml +++ b/STranslate/Views/Preference/Service/TextApiServicePage.xaml @@ -26,7 +26,7 @@ diff --git a/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml b/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml new file mode 100644 index 00000000..9cc861f8 --- /dev/null +++ b/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml.cs b/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml.cs new file mode 100644 index 00000000..e48eaa3b --- /dev/null +++ b/STranslate/Views/Preference/Service/TextSTranslateServicesPage.xaml.cs @@ -0,0 +1,26 @@ +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using STranslate.Model; + +namespace STranslate.Views.Preference.Service +{ + public partial class TextSTranslateServicesPage : UserControl + { + public TextSTranslateServicesPage(ITranslator vm) + { + InitializeComponent(); + + DataContext = vm; + } + + /// + /// 通过缓存加载View时刷新ViewModel + /// + /// + public void UpdateVM(ITranslator vm) + { + DataContext = vm; + } + } +}