添加讯飞

This commit is contained in:
yzx 2024-11-05 10:29:47 +08:00
parent 67f36bcc4d
commit 8517865d78
17 changed files with 433 additions and 114 deletions

View File

@ -8,20 +8,17 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="0ae961c9-2aa8-4465-9e53-e04d62044e0d" name="更改" comment=""> <list default="true" id="0ae961c9-2aa8-4465-9e53-e04d62044e0d" name="更改" comment="">
<change afterPath="$PROJECT_DIR$/ToolsForm/Manager/SparkWebSDK.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.ToolsForm/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.ToolsForm/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.ToolsForm/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.ToolsForm/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/App.axaml" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/App.axaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/ViewModels/ImageAlignmentConverter.cs" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/ViewModels/ImageAlignmentConverter.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.dll" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.dll" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.exe" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.exe" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.exe" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.exe" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.pdb" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/bin/Debug/net8.0/ToolsForm.pdb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.dll" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.dll" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.pdb" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/ToolsForm.pdb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/resources" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/Avalonia/resources" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfo.cs" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfo.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfo.cs" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfo.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfoInputs.cache" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfoInputs.cache" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfoInputs.cache" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.AssemblyInfoInputs.cache" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.csproj.FileListAbsolute.txt" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.csproj.FileListAbsolute.txt" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.csproj.CoreCompileInputs.cache" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.csproj.CoreCompileInputs.cache" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.dll" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.dll" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.dll" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.pdb" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.pdb" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/ToolsForm.pdb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/apphost.exe" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/apphost.exe" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/apphost.exe" beforeDir="false" afterPath="$PROJECT_DIR$/ToolsForm/obj/Debug/net8.0/apphost.exe" afterDir="false" />
@ -41,6 +38,7 @@
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component> </component>
<component name="HighlightingSettingsPerFile"> <component name="HighlightingSettingsPerFile">
<setting file="file://$USER_HOME$/AppData/Local/Symbols/src/dotnet/runtime/2d7eea252964e69be94cb9c847b371b23e4dd470/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/0a/c70ccf06/Window.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/0a/c70ccf06/Window.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/57/f4b4f129/ToggleButton.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/57/f4b4f129/ToggleButton.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/fc/1180e23f/TextBlock.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/00f3784ef64d4453a2630f8508a23171f9200/fc/1180e23f/TextBlock.cs" root0="SKIP_HIGHLIGHTING" />
@ -51,10 +49,14 @@
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/ceb1c14a2cad4d38a6c5bf90e72339c81cc000/c9/cb82c5be/FormattedText.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/ceb1c14a2cad4d38a6c5bf90e72339c81cc000/c9/cb82c5be/FormattedText.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/de3edec1170e48a0a2478d8743508635c8e910/7e/a675f6db/SafeFileHandle.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/de3edec1170e48a0a2478d8743508635c8e910/7e/a675f6db/SafeFileHandle.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/2d9e48c78990cecd83446d724e6becca8372160e7da83528c0b6efca8ffb7/Button.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/2d9e48c78990cecd83446d724e6becca8372160e7da83528c0b6efca8ffb7/Button.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/2e49d31c49913769929208c70c15e8493f19d1ac876bcf8b11123d7bfb66b/RequestMessage{T}.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/57361bc4e5442f644ff63ec7e745da2eb4bbb6c769d1fb683bab5f6f952b1ab/Control.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/57361bc4e5442f644ff63ec7e745da2eb4bbb6c769d1fb683bab5f6f952b1ab/Control.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/e19a3561362418612f26d627aeb21e9f2065cf15b9986a129ec586d68de23de/Viewbox.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/SourcesCache/e19a3561362418612f26d627aeb21e9f2065cf15b9986a129ec586d68de23de/Viewbox.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/../../ICT_IntelligentICTVirtualSimulation/U.P.A/Assets/Runtime/UnityMainThreadDispatcher.cs" root0="SKIP_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/../../ICT_IntelligentICTVirtualSimulation/U.P.A/Assets/Runtime/UnityMainThreadDispatcher.cs" root0="SKIP_HIGHLIGHTING" />
</component> </component>
<component name="PerforceDirect.Settings">
<option name="CHARSET" value="无" />
</component>
<component name="ProjectColorInfo">{ <component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;, &quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 1 &quot;associatedIndex&quot;: 1
@ -67,32 +69,32 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;.NET 项目.ToolsForm.executor&quot;: &quot;Run&quot;, ".NET 项目.ToolsForm.executor": "Run",
&quot;ASKED_ADD_EXTERNAL_FILES&quot;: &quot;true&quot;, "ASKED_ADD_EXTERNAL_FILES": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;XThreadsFramesViewSplitterKey&quot;: &quot;0.5078125&quot;, "XThreadsFramesViewSplitterKey": "0.5078125",
&quot;git-widget-placeholder&quot;: &quot;main&quot;, "git-widget-placeholder": "main",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "nodejs_package_manager_path": "npm",
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;, "settings.editor.selected.configurable": "preferences.pluginManager",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;, "vue.rearranger.settings.migration": "true",
&quot;发布到文件夹.Publish ToolsForm to folder (1).executor&quot;: &quot;Run&quot;, "发布到文件夹.Publish ToolsForm to folder (1).executor": "Run",
&quot;发布到文件夹.Publish ToolsForm to folder (2).executor&quot;: &quot;Run&quot;, "发布到文件夹.Publish ToolsForm to folder (2).executor": "Run",
&quot;发布到文件夹.Publish ToolsForm to folder.executor&quot;: &quot;Run&quot; "发布到文件夹.Publish ToolsForm to folder.executor": "Run"
}, },
&quot;keyToStringList&quot;: { "keyToStringList": {
&quot;rider.external.source.directories&quot;: [ "rider.external.source.directories": [
&quot;C:\\Users\\PC\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\DecompilerCache&quot;, "C:\\Users\\PC\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\DecompilerCache",
&quot;C:\\Users\\PC\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\SourcesCache&quot;, "C:\\Users\\PC\\AppData\\Roaming\\JetBrains\\Rider2024.1\\resharper-host\\SourcesCache",
&quot;C:\\Users\\PC\\AppData\\Local\\Symbols\\src&quot; "C:\\Users\\PC\\AppData\\Local\\Symbols\\src"
] ]
} }
}</component> }]]></component>
<component name="RunManager" selected=".NET 项目.ToolsForm"> <component name="RunManager" selected=".NET 项目.ToolsForm">
<configuration name="Publish ToolsForm to folder (1)" type="DotNetFolderPublish" factoryName="Publish to folder"> <configuration name="Publish ToolsForm to folder (1)" type="DotNetFolderPublish" factoryName="Publish to folder">
<riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" runtime="win-x64" self_contained="true" target_folder="$PROJECT_DIR$/ToolsForm/bin/Release/net8.0/win-x64/publish" target_framework="net8.0" uuid_high="8004843969109443341" uuid_low="-5534705942332332484" /> <riderPublish configuration="Release" platform="Any CPU" produce_single_file="true" runtime="win-x64" self_contained="true" target_folder="$PROJECT_DIR$/ToolsForm/bin/Release/net8.0/win-x64/publish" target_framework="net8.0" uuid_high="8004843969109443341" uuid_low="-5534705942332332484" />
@ -147,7 +149,7 @@
<workItem from="1730270228361" duration="42741000" /> <workItem from="1730270228361" duration="42741000" />
<workItem from="1730681938757" duration="3441000" /> <workItem from="1730681938757" duration="3441000" />
<workItem from="1730699973923" duration="388000" /> <workItem from="1730699973923" duration="388000" />
<workItem from="1730713065050" duration="2110000" /> <workItem from="1730713065050" duration="7318000" />
</task> </task>
<servers /> <servers />
</component> </component>
@ -225,32 +227,6 @@
</properties> </properties>
<option name="timeStamp" value="8" /> <option name="timeStamp" value="8" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="DotNet Breakpoints">
<url>file://$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs</url>
<line>49</line>
<properties documentPath="E:\Unity Projects\GitLab\2024\ICT_ToolsForm\ToolsForm\ToolsForm\Views\AIWindow.axaml.cs" containingFunctionPresentation="方法 'OnSendButtonClick'">
<startOffsets>
<option value="1957" />
</startOffsets>
<endOffsets>
<option value="1990" />
</endOffsets>
</properties>
<option name="timeStamp" value="9" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DotNet Breakpoints">
<url>file://$PROJECT_DIR$/ToolsForm/Views/AIWindow.axaml.cs</url>
<line>23</line>
<properties documentPath="E:\Unity Projects\GitLab\2024\ICT_ToolsForm\ToolsForm\ToolsForm\Views\AIWindow.axaml.cs" containingFunctionPresentation="构造函数 'AIWindow'">
<startOffsets>
<option value="908" />
</startOffsets>
<endOffsets>
<option value="936" />
</endOffsets>
</properties>
<option name="timeStamp" value="10" />
</line-breakpoint>
</breakpoints> </breakpoints>
</breakpoint-manager> </breakpoint-manager>
</component> </component>

View File

@ -0,0 +1,323 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace ToolsForm.Models;
public class Header
{
/// <summary>
///
/// </summary>
public int code { get; set; }
/// <summary>
///
/// </summary>
public string message { get; set; }
/// <summary>
///
/// </summary>
public string sid { get; set; }
/// <summary>
///
/// </summary>
public int status { get; set; }
}
public class TextItem
{
/// <summary>
/// 我可以帮助你的吗?
/// </summary>
public string content { get; set; }
/// <summary>
///
/// </summary>
public string role { get; set; }
/// <summary>
///
/// </summary>
public int index { get; set; }
}
public class Choices
{
/// <summary>
///
/// </summary>
public int status { get; set; }
/// <summary>
///
/// </summary>
public int seq { get; set; }
/// <summary>
///
/// </summary>
public List<TextItem> text { get; set; }
}
public class Text
{
/// <summary>
///
/// </summary>
public int question_tokens { get; set; }
/// <summary>
///
/// </summary>
public int prompt_tokens { get; set; }
/// <summary>
///
/// </summary>
public int completion_tokens { get; set; }
/// <summary>
///
/// </summary>
public int total_tokens { get; set; }
}
public class Usage
{
/// <summary>
///
/// </summary>
public Text text { get; set; }
}
public class Payload
{
/// <summary>
///
/// </summary>
public Choices choices { get; set; }
/// <summary>
///
/// </summary>
public Usage usage { get; set; }
}
public class ResponseDatas
{
/// <summary>
///
/// </summary>
public Header header { get; set; }
/// <summary>
///
/// </summary>
public Payload payload { get; set; }
}
public class SparkWebSDK
{
string wsChatUrl = "ws://spark-api.xf-yun.com/v1.1/chat";
string chat_appid = "a83ddb30";
string chat_key = "df2f1b36593607691d184c2282977959";
string chat_secret = "ZDUwMjczZjM2YTI2YTVhZDU2MjljZDI4";
string clientId = System.Guid.NewGuid().ToString("N");
CancellationToken cancellation;
private ClientWebSocket _webSocketClient;
private string GetAuthUrl()
{
//当前时间戳RFC1123格式
string date = DateTime.UtcNow.ToString("r");
//string date = "Thu, 15 Jun 2023 02:32:41 GMT";
string host = wsChatUrl.Split("://")[1].Split('/')[0];
string localPath = wsChatUrl.Split(host)[1];
string str = "host: " + host + "\n" + "date: " + date + "\n" + "GET " + localPath + " HTTP/1.1";
//hmac-sha256计算签名
string sha = HMACsha256(chat_secret, str);
//授权api_key授权算法头部签名
//authorization格式api_key="$api_key",algorithm="hmac-sha256",headers="host date request-line",signature="$signature"
string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", chat_key, "hmac-sha256", "host date request-line", sha);
//System.Web.HttpUtility.UrlEncode
//鉴权参数host,data,authorization
//authorization使用base64编码的签名相关信息(签名基于hmac-sha256计算)
string path1 = "authorization" + "=" + Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization));
date = date.Replace(" ", "%20").Replace(":", "%3A").Replace(",", "%2C");
string path2 = "date" + "=" + date;
string path3 = "host" + "=" + host;
string newurl = wsChatUrl + "?" + path1 + "&" + path2 + "&" + path3;
return newurl;
}
private string HMACsha256(string apiSecretIsKey, string buider)
{
byte[] bytes = Encoding.UTF8.GetBytes(apiSecretIsKey);
System.Security.Cryptography.HMACSHA256 hMACSHA256 = new System.Security.Cryptography.HMACSHA256(bytes);
byte[] date = Encoding.UTF8.GetBytes(buider);
date = hMACSHA256.ComputeHash(date);
hMACSHA256.Clear();
return Convert.ToBase64String(date);
}
// 接收消息方法,改为异步
async Task<string> ReciceChatAsync(ClientWebSocket ws, CancellationToken cancellationToken)
{
string msgRecive = "";
// 全部消息容器
List<byte> bs = new List<byte>();
// 缓冲区
var buffer = new byte[1024 * 4];
while (ws.State == WebSocketState.Open)
{
// 等待接收消息
var result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
// 如果关闭了连接
if (result.CloseStatus.HasValue)
{
Console.WriteLine("接收关闭");
break;
}
if (result.MessageType == WebSocketMessageType.Text)
{
bs.AddRange(buffer.Take(result.Count));
// 判断消息是否已接收完全
if (result.EndOfMessage)
{
// 发送过来的消息
string userMsg = Encoding.UTF8.GetString(bs.ToArray(), 0, bs.Count);
bs = new List<byte>();
JObject jb = JObject.Parse(userMsg);
int code = jb["header"]["code"].ToObject<int>();
string sid = jb["header"]["sid"].ToString();
int status = jb["header"]["status"].ToObject<int>();
string message = jb["header"]["message"].ToString();
if (code == 0)
{
// 正常消息处理
JToken[] ja = jb["payload"]["choices"]["text"].ToArray();
foreach (var item in ja)
{
msgRecive += item["content"].ToString();
}
if (status == 2)
{
// 完成
Console.WriteLine("最后一条");
break;
}
}
else
{
// 出错
Console.WriteLine(message);
break;
}
}
}
}
Console.WriteLine("退出接收");
return msgRecive;
}
// 异步调用 API 方法
public async Task<string> CallapiForChatAsync(JArray text, CancellationToken cancellationToken)
{
string response = null;
string url = GetAuthUrl();
using (var ws = new ClientWebSocket())
{
await ws.ConnectAsync(new Uri(url), cancellationToken);
if (ws.State == WebSocketState.Open)
{
// 发送消息
JObject data = new JObject();
JObject header = new JObject();
JObject parameter = new JObject();
JObject payload = new JObject();
data.Add("header", header);
data.Add("parameter", parameter);
data.Add("payload", payload);
header.Add("app_id", chat_appid);
header.Add("uid", clientId);
JObject chat = new JObject();
parameter.Add("chat", chat);
chat.Add("domain", "general");
chat.Add("max_tokens", 2048);
chat.Add("auditing", "default");
JObject message = new JObject();
payload.Add("message", message);
message.Add("text", text);
string da = data.ToString();
var frameData = Encoding.UTF8.GetBytes(da);
// 发送数据
await ws.SendAsync(new ArraySegment<byte>(frameData), WebSocketMessageType.Text, true, cancellationToken);
// 接收响应
string msgRecive = await ReciceChatAsync(ws, cancellationToken);
response = msgRecive;
}
else
{
response = "连接失败";
}
}
return response;
}
async Task<string> ReciceChatAsync(ClientWebSocket ws)
{
var buffer = new byte[1024];
var timeoutTask = Task.Delay(2000); // 超过2秒就超时
var receiveTask = ws.ReceiveAsync(new ArraySegment<byte>(buffer), cancellation);
// 等待接收数据或超时,先完成的任务会继续
var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
if (completedTask == timeoutTask)
{
Console.WriteLine("接收超时");
return null; // 或者处理超时逻辑
}
var result = await receiveTask; // 确保完成后再处理接收到的数据
return Encoding.UTF8.GetString(buffer, 0, result.Count);
}
}

View File

@ -1,67 +1,87 @@
 using System.Linq; using System.Linq;
using Avalonia.Controls; using System.Threading;
using Avalonia.Input; using System.Threading.Tasks;
using Avalonia.Interactivity; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Input;
using ToolsForm.Models; // 引入模型命名空间 using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Newtonsoft.Json.Linq;
using ToolsForm.Models; // 引入模型命名空间
namespace ToolsForm.Views namespace ToolsForm.Views
{
public partial class AIWindow : Window
{ {
public partial class AIWindow : Window private DialogueModel dialogueModel;
private TextBox inputTextBox;
private ItemsControl dialogueItems;
private ScrollViewer dialogueScrollViewer;
private SparkWebSDK _sparkWebSdk;
public AIWindow()
{ {
private DialogueModel dialogueModel; InitializeComponent();
private TextBox inputTextBox; // 初始化控件
private ItemsControl dialogueItems; inputTextBox = this.FindControl<TextBox>("InputTextBox");
private ScrollViewer dialogueScrollViewer; dialogueItems = this.FindControl<ItemsControl>("DialogueItems");
public AIWindow() dialogueScrollViewer = this.FindControl<ScrollViewer>("DialogueScrollViewer");
{ dialogueModel = new DialogueModel(); // 创建模型实例
InitializeComponent(); DataContext = dialogueModel; // 将数据上下文设置为模型
// 初始化控件
inputTextBox = this.FindControl<TextBox>("InputTextBox");
dialogueItems = this.FindControl<ItemsControl>("DialogueItems");
dialogueScrollViewer= this.FindControl<ScrollViewer>("DialogueScrollViewer");
dialogueModel = new DialogueModel(); // 创建模型实例
DataContext = dialogueModel; // 将数据上下文设置为模型
}
private void OnInputTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter) // 检查是否按下 Enter 键
{
OnSendButtonClick(sender, e); // 调用发送按钮的点击事件处理程序
e.Handled = true; // 标记事件已处理,防止进一步处理
}
}
private void OnSendButtonClick(object sender, RoutedEventArgs e)
{
var userMessage = inputTextBox.Text;
if (!string.IsNullOrWhiteSpace(userMessage))
{
dialogueModel.AddUserMessage(userMessage);
inputTextBox.Clear();
// 发送 AI 回复
var aiResponse = GenerateAIResponse(userMessage);
dialogueModel.AddAIResponse(aiResponse);
// // 自动滚动到最新消息 _sparkWebSdk = new SparkWebSDK();
// dialogueItems.ScrollIntoView(dialogueModel.Dialogues.Last()); }
}
private void OnInputTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter) // 检查是否按下 Enter 键
{
OnSendButtonClick(sender, e); // 调用发送按钮的点击事件处理程序
e.Handled = true; // 标记事件已处理,防止进一步处理
}
}
private async void OnSendButtonClick(object sender, RoutedEventArgs e)
{
var userMessage = inputTextBox.Text;
if (!string.IsNullOrWhiteSpace(userMessage))
{
dialogueModel.AddUserMessage(userMessage);
inputTextBox.Clear();
// 发送 AI 回复并等待结果
var aiResponse = await GenerateAIResponse(userMessage);
dialogueModel.AddAIResponse(aiResponse);
// 自动滚动到最新消息
if (dialogueScrollViewer != null) if (dialogueScrollViewer != null)
{ {
dialogueScrollViewer.ScrollToEnd(); dialogueScrollViewer.ScrollToEnd();
} }
} }
private string GenerateAIResponse(string message)
{
// TODO: 这里实现AI生成回复的逻辑
return "这是AI的回复"; // 示例回复
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
} }
}
private async Task<string> GenerateAIResponse(string message)
{
string mess = "没有数据";
JArray text = new JArray();
JObject jb = new JObject();
jb.Add("role", "user");
jb.Add("content", message);
text.Add(jb);
// 直接等待 CallapiForChatAsync 返回结果
mess = await _sparkWebSdk.CallapiForChatAsync(text, CancellationToken.None);
return mess; // 返回 AI 回复
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("ToolsForm")] [assembly: System.Reflection.AssemblyCompanyAttribute("ToolsForm")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b5da1a7f7c82dcd20f0b21f742568b806e389d75")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+67f36bcc4da43ad28c0edee61033c6417823236c")]
[assembly: System.Reflection.AssemblyProductAttribute("ToolsForm")] [assembly: System.Reflection.AssemblyProductAttribute("ToolsForm")]
[assembly: System.Reflection.AssemblyTitleAttribute("ToolsForm")] [assembly: System.Reflection.AssemblyTitleAttribute("ToolsForm")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
7b96760f001b2471081ba691dfa0e836b351bee82672791a362c10b30535dedd b6d965a55222d82d427c73ab54d64fca1a5f960cb20160d77994e28bd488268d

View File

@ -1 +1 @@
bf3fd6b20c8cdf001539f535b65b0d319f4b4f7c5c43d09955e03b2516849197 9fb7436273386345ad7568271cc196a11cf18d5aadf391ba706c7b48ebe9b994