using ArcGIS.Desktop.Core.Geoprocessing; using LinkToolAddin.client; using LinkToolAddin.host; using LinkToolAddin.host.llm; using LinkToolAddin.host.llm.entity; using LinkToolAddin.message; using LinkToolAddin.resource; using LinkToolAddin.server; using log4net; using log4net.Appender; using log4net.Config; using log4net.Layout; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Server; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Text.Json; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace LinkToolAddin.ui.dockpane { /// /// Interaction logic for DialogDockpaneView.xaml /// 显示消息列表、输入框和发送按钮 /// public partial class DialogDockpaneView : UserControl { private static ILog log = LogManager.GetLogger(typeof(DialogDockpaneView)); public DialogDockpaneView() { InitLogger(); InitializeComponent(); } private async void TestServer_OnClick(object sender, RoutedEventArgs e) { log.Info("TestServer Clicked"); } protected void InitLogger() { // 1. 创建控制台输出器(Appender) var consoleAppender = new ConsoleAppender { Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"), Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别 }; consoleAppender.ActivateOptions(); // 激活配置 // 2. 创建文件滚动输出器(按大小滚动) var fileAppender = new RollingFileAppender { File = Path.Combine("Logs", "D:\\linktool_app.log"), // 日志文件路径 AppendToFile = true, // 追加模式 RollingStyle = RollingFileAppender.RollingMode.Size, // 按文件大小滚动 MaxSizeRollBackups = 10, // 保留 10 个历史文件 MaximumFileSize = "1MB", // 单个文件最大 1MB StaticLogFileName = true, // 固定文件名(否则自动追加序号) Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"), Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别 }; fileAppender.ActivateOptions(); // 激活配置 // 3. 直接通过 BasicConfigurator 注册 Appender BasicConfigurator.Configure(consoleAppender, fileAppender); log = LogManager.GetLogger(typeof(DialogDockpaneView)); // 测试日志输出 log.Debug("Debug 日志(控制台可见)"); log.Info("Info 日志(控制台和文件可见)"); log.Error("Error 日志(严重问题)"); } private void Send_0nclick(object sender, RoutedEventArgs e) { string userInput = InputTextBox.Text.Trim(); if (string.IsNullOrEmpty(userInput)) return; var userMessage = new ChatMessageItem { id = Guid.NewGuid().ToString(), role = "user", content = userInput, type = MessageType.CHAT_MESSAGE }; // 使用统一方法显示消息 NewMessage(userMessage); // 清空输入框 InputTextBox.Clear(); Gateway.SendMessageStream(InputTextBox.Text, model: "qwen-max", gdbPath: "c: /user.gdb", NewMessage); } public void NewMessage(MessageListItem messagelistItem) { // 创建用于显示消息内容的 TextBlock TextBlock textBlock = new TextBlock(); textBlock.Text = InputTextBox.Text; textBlock.TextWrapping = TextWrapping.Wrap; // 自动换行 textBlock.VerticalAlignment = VerticalAlignment.Center; // 创建 Border 作为消息气泡容器 Border border = new Border(); border.Child = textBlock; border.CornerRadius = new CornerRadius(10); border.Padding = new Thickness(10); border.Margin = new Thickness(5); // 设置默认宽度限制 border.MaxWidth = 300; if (messagelistItem.role == "user") { // 浅蓝色背景,靠右 border.Background = new SolidColorBrush(Color.FromRgb(212, 229, 239)); // 浅蓝 border.HorizontalAlignment = HorizontalAlignment.Right; } else if (messagelistItem.role == "assistant") { // 浅灰背景,靠左 border.Background = new SolidColorBrush(Color.FromRgb(240, 240, 240)); // 浅灰 border.HorizontalAlignment = HorizontalAlignment.Left; if (messagelistItem.type == MessageType.TOOL_MESSAGE) { border.BorderBrush = new SolidColorBrush(Color.FromRgb(212, 220, 223)); // 灰蓝色边框 border.BorderThickness = new Thickness(1); } } // 把气泡添加到 MessageListView 显示 MessageListView.Items.Add(border); // 自动滚动到底部 MessageScrollViewer.ScrollToEnd(); } } }