优化登录逻辑,添加聊天界面。
This commit is contained in:
parent
20be6f6613
commit
253f766732
53
chatclient/Data/ChatDataModel.cs
Normal file
53
chatclient/Data/ChatDataModel.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace chatclient.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// 聊天消息类,表示一条消息的内容和显示属性
|
||||
/// </summary>
|
||||
public class ChatMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 发送者名称
|
||||
/// </summary>
|
||||
public required string Sender { get; set; }
|
||||
/// <summary>
|
||||
/// 消息类型(文本、图片、文件、系统消息等)
|
||||
/// </summary>
|
||||
public required MessageType Type { get; set; } = MessageType.Text;
|
||||
/// <summary>
|
||||
/// 消息发送者的头像图片
|
||||
/// </summary>
|
||||
public required BitmapImage Image { get; set; }
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public required string Content { get; set; }
|
||||
/// <summary>
|
||||
/// 消息发送时间
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
/// <summary>
|
||||
/// 消息在界面中的对齐方式(左/右)
|
||||
/// </summary>
|
||||
public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
|
||||
/// <summary>
|
||||
/// 发送者名称的显示颜色
|
||||
/// </summary>
|
||||
public Brush SenderColor { get; set; } = Brushes.Black;
|
||||
}
|
||||
public enum MessageType
|
||||
{
|
||||
Text,
|
||||
Image,//图片
|
||||
File,//文件
|
||||
System//系统信息
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
|
||||
namespace chatapi
|
||||
namespace chatclient.Data
|
||||
{
|
||||
internal class Server
|
||||
{
|
@ -6,9 +6,9 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Net.Sockets;
|
||||
using log4net;
|
||||
using chatapi;
|
||||
using System.Net.Http;
|
||||
using Microsoft.Win32;
|
||||
using chatclient.Data;
|
||||
|
||||
|
||||
namespace chatclient
|
||||
@ -126,7 +126,7 @@ namespace chatclient
|
||||
string SignJsonData = JsonSerializer.Serialize(SignData);
|
||||
byte[] dataBytes = Encoding.UTF8.GetBytes(SignJsonData);
|
||||
var content = new StringContent(SignJsonData, Encoding.UTF8, "application/json");
|
||||
var response = await MainWindow.HttpClient.PostAsync($"{chatapi.Server.ServerUrl}/api/register", content);
|
||||
var response = await MainWindow.HttpClient.PostAsync($"{Server.ServerUrl}/api/register", content);
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
log.Info($"注册请求已发送,响应内容: {responseBody}");
|
||||
var signresponse = JsonSerializer.Deserialize<SignResultData>(responseBody);
|
||||
|
@ -27,7 +27,72 @@
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
<Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 标题栏 -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 消息区域 -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 输入区域 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<materialDesign:Card Grid.Row="0" Padding="10" Margin="0,0,0,5">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="聊天室" FontSize="16" FontWeight="Bold"
|
||||
VerticalAlignment="Center" Margin="5,0" Cursor="Hand"/>
|
||||
<!--<Button x:Name="btnRefresh" Style="{StaticResource MaterialDesignIconButton}"
|
||||
ToolTip="刷新列表" Click="RefreshContacts_Click" Margin="5,0,10,0">
|
||||
<materialDesign:PackIcon Kind="Refresh"/>
|
||||
</Button>-->
|
||||
<!--<ComboBox x:Name="cmbContacts" Width="150" Margin="5,0"
|
||||
materialDesign:HintAssist.Hint="选择联系人"
|
||||
DisplayMemberPath="DisplayName"/>-->
|
||||
</StackPanel>
|
||||
</materialDesign:Card>
|
||||
|
||||
<!-- 消息区域 -->
|
||||
<ScrollViewer x:Name="messageScroller" Grid.Row="1" VerticalScrollBarVisibility="Auto"
|
||||
Padding="10" Background="{DynamicResource MaterialDesignPaper}">
|
||||
<ItemsControl x:Name="messageList">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:Card Margin="0,5" Padding="10"
|
||||
HorizontalAlignment="{Binding Alignment}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Sender}" FontWeight="Bold"
|
||||
Foreground="{Binding SenderColor}"/>
|
||||
<TextBlock Text="{Binding Content}" TextWrapping="Wrap"
|
||||
Margin="0,5,0,0"/>
|
||||
<TextBlock Text="{Binding Timestamp, StringFormat='HH:mm:ss'}"
|
||||
Foreground="Gray" FontSize="10"
|
||||
HorizontalAlignment="Right" Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</materialDesign:Card>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- 输入区域 -->
|
||||
<Grid Grid.Row="2" Margin="0,5,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox x:Name="txtMessage" Grid.Column="0" Margin="0,0,5,0"
|
||||
materialDesign:HintAssist.Hint="输入消息..."
|
||||
AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
|
||||
TextWrapping="Wrap" MinHeight="60" MaxHeight="120"
|
||||
KeyDown="MessageInput_KeyDown"/>
|
||||
|
||||
<Button x:Name="btnSend" Grid.Column="1" Content="发送" MinWidth="80"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
Click="SendMessage_Click"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem>
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
@ -17,11 +16,11 @@ using System.Security.Policy;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using System.Text.Json;
|
||||
using chatapi;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Interop;
|
||||
using ControlzEx.Standard;
|
||||
using chatclient.Data;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Threading;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
[assembly: XmlConfigurator(ConfigFile = "config/log4net.config", Watch = true)]
|
||||
namespace chatclient
|
||||
@ -38,7 +37,7 @@ namespace chatclient
|
||||
public static Socket? Client;
|
||||
public static readonly HttpClient HttpClient = new HttpClient();
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
private string? _Username;
|
||||
private string? _Username;
|
||||
public string? Username
|
||||
{
|
||||
get { return _Username; }
|
||||
@ -48,6 +47,10 @@ namespace chatclient
|
||||
Update("Username");
|
||||
}
|
||||
}
|
||||
// 消息列表
|
||||
public ObservableCollection<ChatMessage> Messages { get; } = new ObservableCollection<ChatMessage>();
|
||||
private ItemsControl MessageList => messageList;
|
||||
private ScrollViewer MessageScroller => messageScroller;
|
||||
private void Update(string UpdateName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(UpdateName));
|
||||
@ -72,8 +75,16 @@ namespace chatclient
|
||||
Login.Show();
|
||||
Thread th = new Thread(Receive);
|
||||
th.Start();
|
||||
MessageList.ItemsSource = Messages;
|
||||
((INotifyCollectionChanged)MessageList.Items).CollectionChanged += (s, e) =>
|
||||
{
|
||||
// 确保有足够的时间让UI更新
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
MessageScroller.ScrollToEnd();
|
||||
}), DispatcherPriority.ContextIdle);
|
||||
};
|
||||
}
|
||||
|
||||
static void Receive()
|
||||
{
|
||||
byte[] buffer = new byte[1024];
|
||||
@ -129,26 +140,41 @@ namespace chatclient
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (LoginResponse != null)
|
||||
{
|
||||
log.Warn($"登录失败: {LoginResponse.message}\nMsg:{msg}");
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
loginWindow!.LoginMsg = LoginResponse.message;
|
||||
}
|
||||
}
|
||||
else if (Type.type == "login_0")
|
||||
{
|
||||
if (LoginResponse != null)
|
||||
{
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
loginWindow!.LoginMsg = LoginResponse.message;
|
||||
}
|
||||
else
|
||||
{
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
loginWindow!.LoginMsg = "服务器返回错误";
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
if (loginWindow != null)
|
||||
{
|
||||
loginWindow.LoginMsg = LoginResponse != null ? LoginResponse.message : "服务器返回错误";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(Type.type == "login_0" && LoginResponse != null)
|
||||
{
|
||||
log.Warn($"登录失败: {LoginResponse.message}\nMsg:{msg}");
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
if (loginWindow != null)
|
||||
{
|
||||
loginWindow.LoginMsg = LoginResponse.message;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var loginWindow = Application.Current.Windows.OfType<LoginWindow>().FirstOrDefault();
|
||||
if (loginWindow != null)
|
||||
{
|
||||
loginWindow.LoginMsg = LoginResponse != null ? LoginResponse.message : "服务器返回错误";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
@ -160,5 +186,44 @@ namespace chatclient
|
||||
log.Error("处理响应时发生错误", ex);
|
||||
}
|
||||
}
|
||||
private void SendMessage_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SendMessage();
|
||||
}
|
||||
private void SendMessage()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtMessage.Text))
|
||||
return;
|
||||
|
||||
// 获取当前选中的联系人
|
||||
//var contact = cmbContacts.SelectedItem as Contact;
|
||||
// 判断是否为群组,若是则收件人设为“所有人”,否则为联系人显示名
|
||||
//string recipient = contact?.IsGroup == true ? "所有人" : contact?.DisplayName;
|
||||
|
||||
// 创建新消息
|
||||
var newMessage = new ChatMessage
|
||||
{
|
||||
Sender = "我",
|
||||
Type = MessageType.Text,
|
||||
Image = new BitmapImage(new Uri("pack://application:,,,/user.png", UriKind.Absolute)), // 默认头像
|
||||
Content = txtMessage.Text,
|
||||
Timestamp = DateTime.Now,
|
||||
Alignment = HorizontalAlignment.Right, // 自己发送的消息靠右
|
||||
SenderColor = new SolidColorBrush(Colors.Blue)
|
||||
};
|
||||
// 添加到消息列表
|
||||
Messages.Add(newMessage);
|
||||
// 清空输入框
|
||||
txtMessage.Clear();
|
||||
}
|
||||
// 消息输入框回车事件
|
||||
private void MessageInput_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter && Keyboard.Modifiers != ModifierKeys.Shift)
|
||||
{
|
||||
SendMessage();
|
||||
e.Handled = true; // 阻止换行
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user