Files
IM_NEW/MessageService.Domain/Entities/Message.cs

218 lines
8.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, Guid? fileId = null)
{
var content = new MessageContent("[图片]", new ImageBody(url, width, height, thumb, fileId));
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, Guid? fileId = null)
{
var content = new MessageContent("[视频]", new VideoBody(url, width, height, thumb, fileId));
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, Guid? fileId = null)
{
var content = new MessageContent("[音频]", new VoiceBody(url, duration, fileId));
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, Guid fileId, string? url,
string name, long size,
string format, long sequenceId)
{
var content = new MessageContent("[文件]", new FileBody(fileId, 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
)
};
}
}
}