在 `ChatDataModel.cs` 中添加 `TimeFormatConverter` 类,用于格式化本地时间,并在 `MainWindow.xaml` 中应用该转换器。 在 `chatapi.cs` 中新增 `HistoryRequest` 和 `HistoryResponse` 类以处理历史记录请求和响应。 修改 `LoginWindow.xaml.cs` 中的数据发送方式,使用 `SendWithPrefix` 方法以支持数据压缩和长度前缀。 在 `MainWindow.xaml.cs` 中添加 `LoadHistoryMessages` 方法以加载历史消息,并在接收到响应时更新消息列表。 在 `Program.cs` 中实现数据压缩和解压缩方法,提升网络传输效率。 新增消息表和索引以支持消息存储和查询。 更新日志记录以提供更详细的操作信息和错误处理。
137 lines
4.4 KiB
C#
137 lines
4.4 KiB
C#
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;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Input;
|
||
using System.Globalization;
|
||
using System.Windows.Data;
|
||
|
||
namespace chatclient.Data
|
||
{
|
||
/// <summary>
|
||
/// 聊天消息类,表示一条消息的内容和显示属性
|
||
/// </summary>
|
||
public class ChatMessage
|
||
{
|
||
/// <summary>
|
||
/// 发送者名称
|
||
/// </summary>
|
||
public required string Sender { get; set; }
|
||
/// <summary>
|
||
/// 消息类型(文本、图片、文件、系统消息等)
|
||
/// </summary>
|
||
public required MessageType MsgType { 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//系统信息
|
||
}
|
||
/// <summary>
|
||
/// 临时账户信息类,包含用户名和密码
|
||
/// </summary>
|
||
public class Account
|
||
{
|
||
public string? UserName { get; set; }
|
||
public string? UserPassword { get; set; }
|
||
}
|
||
/// <summary>
|
||
/// 时间格式转换器类
|
||
/// </summary>
|
||
public class TimeFormatConverter : IValueConverter
|
||
{
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||
{
|
||
if (value is DateTime timestamp)
|
||
{
|
||
// 获取本地时区信息
|
||
TimeZoneInfo localTimeZone = TimeZoneInfo.Local;
|
||
bool isLocalTimeZoneUtcPlus8 = localTimeZone.BaseUtcOffset == TimeSpan.FromHours(8);
|
||
DateTime localTime;
|
||
if (timestamp.Kind == DateTimeKind.Utc)
|
||
{
|
||
localTime = timestamp.ToLocalTime();
|
||
}
|
||
else if (timestamp.Kind == DateTimeKind.Unspecified)
|
||
{
|
||
// 假设未指定时间是UTC时间(常见实践)
|
||
localTime = DateTime.SpecifyKind(timestamp, DateTimeKind.Utc).ToLocalTime();
|
||
}
|
||
else
|
||
{
|
||
localTime = timestamp;
|
||
}
|
||
|
||
var now = DateTime.Now;
|
||
var today = now.Date;
|
||
var yesterday = today.AddDays(-1);
|
||
var localTimeDate = localTime.Date;
|
||
|
||
// 格式化时间字符串
|
||
string formattedTime;
|
||
if (localTimeDate == today)
|
||
{
|
||
formattedTime = localTime.ToString("HH:mm:ss");
|
||
}
|
||
else if (localTimeDate == yesterday)
|
||
{
|
||
formattedTime = "昨天 " + localTime.ToString("HH:mm");
|
||
}
|
||
else if (localTime.Year == now.Year)
|
||
{
|
||
formattedTime = localTime.ToString("MM/dd HH:mm");
|
||
}
|
||
else
|
||
{
|
||
formattedTime = localTime.ToString("yy/MM/dd HH:mm");
|
||
}
|
||
|
||
// 仅在非UTC+8时区显示时区信息
|
||
if (!isLocalTimeZoneUtcPlus8)
|
||
{
|
||
// 获取原始时间的时区信息
|
||
string timeZoneInfo = timestamp.Kind == DateTimeKind.Utc
|
||
? "UTC"
|
||
: "UTC"+localTime.ToString("zzz");
|
||
|
||
return $"{timeZoneInfo} {formattedTime}";
|
||
}
|
||
return formattedTime;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
}
|
||
}
|