添加项目文件。

This commit is contained in:
2026-05-09 17:06:30 +08:00
parent c60f5fe117
commit 720ef957d4
378 changed files with 14843 additions and 0 deletions
+217
View File
@@ -0,0 +1,217 @@
using IM.Commons.IntegrationEvents;
using IM.DomainCommons;
using MessageService.Domain.Enums;
using MessageService.Domain.Events;
using MessageService.Domain.KeyObjects;
using MessageService.Domain.Tools;
using System.Text.Json;
namespace MessageService.Domain.Entities
{
public class Message : AggregateRootEntity
{
/// <summary>
/// 聊天类型
/// 0:私聊,1:群聊)
/// </summary>
public ChatType ChatType { get; private set; }
/// <summary>
/// 消息类型
/// (0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)
/// </summary>
public MessageType MsgType { get; private set; }
public Guid ClientMsgId { get; private set; }
/// <summary>
/// 消息内容
/// </summary>
public MessageContent Content { get; private set; } = null!;
/// <summary>
/// 发送者
/// </summary>
public Guid SenderId { get; private set; }
/// <summary>
/// 接收者(私聊为用户ID,群聊为群聊ID)
/// </summary>
public Guid TargetId { get; private set; }
/// <summary>
/// 消息状态(0:已发送,1:已撤回)
/// </summary>
public MessageState State { get; private set; } = MessageState.Sent;
/// <summary>
/// 消息推送唯一标识符
/// </summary>
public string StreamKey { get; private set; }
/// <summary>
/// 消息排序标识
/// </summary>
public long SequenceId { get; private set; }
private Message() { }
private Message(MessageCreateContext ctx, long sequenceId, MessageType messageType
, MessageContent content
)
{
ChatType = ctx.ChatType;
SenderId = ctx.SenderId;
ClientMsgId = ctx.ClientMsgId;
TargetId = ctx.TargetId;
SequenceId = sequenceId;
MsgType = messageType;
StreamKey = ChatType == ChatType.GROUP ? StreamKeyBuilder.Group(ctx.TargetId) : StreamKeyBuilder.Private(ctx.SenderId, ctx.TargetId);
Content = content;
}
/// <summary>
/// 文本消息
/// </summary>
/// <param name="ctx"></param>
/// <param name="text">文本内容</param>
/// <param name="sequenceId"></param>
/// <returns></returns>
public static Message BuildTxt(MessageCreateContext ctx, string text, long sequenceId)
{
var content = new MessageContent(text, new TextBody(text));
return new Message(ctx, sequenceId, MessageType.Text, content);
}
/// <summary>
/// 图片消息
/// </summary>
/// <param name="ctx"></param>
/// <param name="url">相对路径</param>
/// <param name="width">宽度</param>
/// <param name="height">高度</param>
/// <param name="thumb">预览图</param>
/// <param name="sequenceId"></param>
/// <returns></returns>
public static Message BuildImg(MessageCreateContext ctx, string url,
int width, int height, string thumb, long sequenceId)
{
var content = new MessageContent("[图片]", new ImageBody(url, width, height, thumb));
return new Message(ctx, sequenceId, MessageType.Image, content);
}
/// <summary>
/// 视频消息
/// </summary>
/// <param name="ctx"></param>
/// <param name="url"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="thumb"></param>
/// <param name="sequenceId"></param>
/// <returns></returns>
public static Message BuildVideo(MessageCreateContext ctx, string url,
int width, int height, string thumb, long sequenceId)
{
var content = new MessageContent("[视频]", new VideoBody(url, width, height, thumb));
return new Message(ctx, sequenceId, MessageType.Video, content);
}
/// <summary>
/// 语音消息
/// </summary>
/// <param name="ctx"></param>
/// <param name="url"></param>
/// <param name="duration">持续时间</param>
/// <param name="sequenceId"></param>
/// <returns></returns>
public static Message BuildVoice(MessageCreateContext ctx, string url,
int duration, long sequenceId)
{
var content = new MessageContent("[音频]", new VoiceBody(url, duration));
return new Message(ctx, sequenceId, MessageType.Voice, content);
}
/// <summary>
/// 文件
/// </summary>
/// <param name="ctx"></param>
/// <param name="url">相对路径</param>
/// <param name="name">文件名</param>
/// <param name="size">文件大小(KB</param>
/// <param name="format">文件格式</param>
/// <param name="sequenceId"></param>
/// <returns></returns>
public static Message BuildFile(MessageCreateContext ctx, string url,
string name, long size,
string format, long sequenceId)
{
var content = new MessageContent("[文件]", new FileBody(url, name, size, format));
return new Message(ctx, sequenceId, MessageType.File, content);
}
/// <summary>
/// 添加扩展字段
/// </summary>
/// <param name="key">字段名</param>
/// <param name="value">值</param>
/// <returns></returns>
public Message WithExt(string key, string value)
{
var dic = new Dictionary<string, string>();
dic.Add(key, value);
Content.RawExt = JsonSerializer.Serialize(dic);
return this;
}
/// <summary>
/// 添加消息引用
/// </summary>
/// <param name="quote"></param>
/// <returns></returns>
public Message WithQuote(QuoteInfo quote)
{
this.Content.Quote = quote;
return this;
}
/// <summary>
/// 完成消息
/// </summary>
public void Send()
{
AddDomainEvent(new MessageCreatedDomainEvent(this));
}
public void Withdraw()
{
if (State != MessageState.Sent)
{
throw new DomainException("消息不可撤回");
}
State = MessageState.Withdrwan;
AddDomainEvent(new MessageWithdrawDomainEvent(this));
}
public MsgCreatedEvent ToIntegrationEvent()
{
return new MsgCreatedEvent
{
Id = this.Id,
ClientId = this.ClientMsgId, // 假设你有存发送端的设备ID
ChatType = this.ChatType.ToString(), // 比如 "private" 或 "group"
MsgType = this.MsgType.ToString() ?? MessageType.Text.ToString(), // 动态获取类型名,或从 Content 里的定义拿
SenderId = this.SenderId,
TargetId = this.TargetId,
State = State.ToString(),
StreamKey = this.StreamKey,
SequenceId = this.SequenceId,
// 核心载荷:利用计算属性触发反序列化,打包成 DTO
Content = new MsgContent(
this.Content.Fallback,
this.Content.Body, // 触发实体内部的反序列化逻辑
this.Content.Ext,
this.Content.Quote != null ? new QuoteInfoDto(
this.Content.Quote.MessageId,
this.Content.Quote.SenderId,
this.Content.Quote.SenderName,
this.Content.Quote.MessageType.ToString(),
this.Content.Quote.Preview
) : null
)
};
}
}
}