前端:
1、会话列表、消息界面展示与后端打通 后端: 1、修复会话和消息服务现存问题 2、会话对象不再返回Message对象,而是使用MessageBaseDto替代 3、修改查询会话列表和会话信息的逻辑 4、新增消息列表查询 文档: 后端代码规范文档新增从数据库同步到模型的命令
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -14,7 +14,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("IMTest")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5274f0d22d4fe646d03a3bc0ea6621d299074816")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d855c8f8fb8edc48b6c55f08ee2ebf74415cc5ea")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("IMTest")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("IMTest")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
7390b702e3c578dad3a8fa4fa4cc93b25ccd34a9b353beca60372a7182717d73
|
||||
0e2c3a5367325662a3e7db912bec1cd772d661d101def6cb95abbceb77be09ff
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -54,6 +54,7 @@ namespace IM_API.Configs
|
||||
.ForMember(dest => dest.ReceiverId, opt => opt.MapFrom(src => src.Recipient))
|
||||
.ForMember(dest => dest.Content, opt => opt.MapFrom(src => src.Content))
|
||||
.ForMember(dest => dest.TimeStamp, opt => opt.MapFrom(src => src.Created))
|
||||
.ForMember(dest => dest.GroupMemberId , opt => opt.MapFrom(src => src.GroupMemberId))
|
||||
;
|
||||
CreateMap<MessageBaseDto, Message>()
|
||||
.ForMember(dest => dest.Sender, opt => opt.MapFrom(src => src.SenderId))
|
||||
@@ -64,6 +65,7 @@ namespace IM_API.Configs
|
||||
.ForMember(dest => dest.Recipient, opt => opt.MapFrom(src => src.ReceiverId))
|
||||
.ForMember(dest => dest.StreamKey, opt => opt.Ignore() )
|
||||
.ForMember(dest => dest.StateEnum, opt => opt.MapFrom(src => MessageState.Sent))
|
||||
.ForMember(dest => dest.GroupMemberId, opt => opt.MapFrom(src => src.GroupMemberId))
|
||||
.ForMember(dest => dest.ChatType, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.MsgType, opt => opt.Ignore())
|
||||
;
|
||||
@@ -102,6 +104,27 @@ namespace IM_API.Configs
|
||||
.ForMember(dest => dest.LastMessageTime, opt => opt.MapFrom(src => DateTime.Now))
|
||||
;
|
||||
|
||||
//创建会话对象
|
||||
CreateMap<Conversation, ConversationDto>()
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.LastMessage, opt => opt.MapFrom(src => src.LastMessage))
|
||||
.ForMember(dest => dest.LastReadMessage, opt => opt.MapFrom(src => src.LastReadMessage))
|
||||
.ForMember(dest => dest.LastReadMessageId, opt => opt.MapFrom(src => src.LastReadMessageId))
|
||||
.ForMember(dest => dest.ChatType, opt => opt.MapFrom(src => src.ChatType))
|
||||
.ForMember(dest => dest.DateTime, opt => opt.MapFrom(src => src.LastMessageTime))
|
||||
.ForMember(dest => dest.TargetId, opt => opt.MapFrom(src => src.TargetId))
|
||||
.ForMember(dest => dest.UnreadCount, opt => opt.MapFrom(src => src.UnreadCount))
|
||||
.ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.UserId));
|
||||
|
||||
CreateMap<Friend, ConversationDto>()
|
||||
.ForMember(dest => dest.TargetAvatar, opt => opt.MapFrom(src => src.Avatar))
|
||||
.ForMember(dest => dest.TargetName, opt => opt.MapFrom(src => src.RemarkName));
|
||||
|
||||
CreateMap<Group, ConversationDto>()
|
||||
.ForMember(dest => dest.TargetAvatar, opt => opt.MapFrom(src => src.Avatar))
|
||||
.ForMember(dest => dest.TargetName, opt => opt.MapFrom(src => src.Name));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,14 @@ namespace IM_API.Controllers
|
||||
var res = new BaseResponse<List<ConversationDto>>(list);
|
||||
return Ok(res);
|
||||
}
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get([FromQuery]int conversationId)
|
||||
{
|
||||
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var conversation = await _conversationSerivice.GetConversationByIdAsync(int.Parse(userIdStr), conversationId);
|
||||
var res = new BaseResponse<ConversationDto>(conversation);
|
||||
return Ok(res);
|
||||
}
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> Clear()
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using IM_API.Interface.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace IM_API.Controllers
|
||||
@@ -33,5 +34,13 @@ namespace IM_API.Controllers
|
||||
await _messageService.SendGroupMessageAsync(int.Parse(userIdstr), dto.ReceiverId, dto);
|
||||
return Ok(new BaseResponse<object?>());
|
||||
}
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetMessageList([Required]int conversationId, int? msgId, int? pageSize)
|
||||
{
|
||||
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var msgList = await _messageService.GetMessagesAsync(int.Parse(userIdStr), conversationId, msgId, pageSize, false);
|
||||
var res = new BaseResponse<List<MessageBaseDto>>(msgList);
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,6 @@ namespace IM_API.Dtos
|
||||
/// 对方头像
|
||||
/// </summary>
|
||||
public string? TargetAvatar { get; set; }
|
||||
public virtual Message? LastReadMessage { get; set; }
|
||||
public MessageBaseDto? LastReadMessage { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
namespace IM_API.Dtos
|
||||
{
|
||||
public record MessageBaseDto(
|
||||
string Type,string ChatType, string? MsgId,int SenderId,int ReceiverId,string Content,DateTime TimeStamp);
|
||||
public record MessageBaseDto
|
||||
{
|
||||
// 使用 { get; init; } 确保对象创建后不可修改,且支持无参构造
|
||||
public string Type { get; init; } = default!;
|
||||
public string ChatType { get; init; } = default!;
|
||||
public string? MsgId { get; init; }
|
||||
public int SenderId { get; init; }
|
||||
public int ReceiverId { get; init; }
|
||||
public int? GroupMemberId { get; init; }
|
||||
public string Content { get; init; } = default!;
|
||||
public DateTime TimeStamp { get; init; }
|
||||
public MessageBaseDto() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,5 +29,11 @@ namespace IM_API.Interface.Services
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<string>> GetUserAllStreamKeyAsync(int userId);
|
||||
/// <summary>
|
||||
/// 获取单个conversation信息
|
||||
/// </summary>
|
||||
/// <param name="conversationId"></param>
|
||||
/// <returns></returns>
|
||||
Task<ConversationDto> GetConversationByIdAsync(int userId, int conversationId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,24 +21,14 @@ namespace IM_API.Interface.Services
|
||||
/// <returns></returns>
|
||||
Task<bool> SendGroupMessageAsync(int senderId,int groupId,MessageBaseDto dto);
|
||||
/// <summary>
|
||||
/// 获取私聊消息列表
|
||||
/// 获取消息列表
|
||||
/// </summary>
|
||||
/// <param name="userAId"></param>
|
||||
/// <param name="userBId"></param>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="conversationId">会话id(用于获取指定用户间聊天消息)</param>
|
||||
/// <param name="msgId">消息id</param>
|
||||
/// <param name="pageSize">获取消息数量</param>
|
||||
/// <param name="desc"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<MessageBaseDto>> GetPrivateMessagesAsync(int userAId,int userBId,int page,int pageSize,bool desc);
|
||||
/// <summary>
|
||||
/// 获取群聊消息列表
|
||||
/// </summary>
|
||||
/// <param name="groupId"></param>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="desc"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<MessageBaseDto>> GetGroupMessagesAsync(int groupId, int page, int pageSize, bool desc);
|
||||
Task<List<MessageBaseDto>> GetMessagesAsync(int userId, int conversationId,int? msgId,int? pageSize,bool desc);
|
||||
/// <summary>
|
||||
/// 获取未读消息数
|
||||
/// </summary>
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal;
|
||||
|
||||
namespace IM_API.Models;
|
||||
|
||||
public partial class ImContext : DbContext
|
||||
{
|
||||
public ImContext()
|
||||
{
|
||||
}
|
||||
|
||||
public ImContext(DbContextOptions<ImContext> options)
|
||||
: base(options)
|
||||
{
|
||||
@@ -50,10 +45,6 @@ public partial class ImContext : DbContext
|
||||
|
||||
public virtual DbSet<User> Users { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||
=> optionsBuilder.UseMySql("server=frp-era.com;port=26582;database=IM;user=product;password=12345678", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.44-mysql"));
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
@@ -547,6 +538,9 @@ public partial class ImContext : DbContext
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("发送时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.GroupMemberId)
|
||||
.HasComment("若为群消息则表示具体的成员id")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.MsgType)
|
||||
.HasComment("消息类型\r\n(0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
|
||||
@@ -1,732 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Pomelo.EntityFrameworkCore.MySql.Scaffolding.Internal;
|
||||
|
||||
namespace IM_API.Models;
|
||||
|
||||
public partial class ImDbContext : DbContext
|
||||
{
|
||||
public ImDbContext()
|
||||
{
|
||||
}
|
||||
|
||||
public ImDbContext(DbContextOptions<ImDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual DbSet<Admin> Admins { get; set; }
|
||||
|
||||
public virtual DbSet<Conversation> Conversations { get; set; }
|
||||
|
||||
public virtual DbSet<Device> Devices { get; set; }
|
||||
|
||||
public virtual DbSet<File> Files { get; set; }
|
||||
|
||||
public virtual DbSet<Friend> Friends { get; set; }
|
||||
|
||||
public virtual DbSet<FriendRequest> FriendRequests { get; set; }
|
||||
|
||||
public virtual DbSet<Group> Groups { get; set; }
|
||||
|
||||
public virtual DbSet<GroupInvite> GroupInvites { get; set; }
|
||||
|
||||
public virtual DbSet<GroupMember> GroupMembers { get; set; }
|
||||
|
||||
public virtual DbSet<GroupRequest> GroupRequests { get; set; }
|
||||
|
||||
public virtual DbSet<LoginLog> LoginLogs { get; set; }
|
||||
|
||||
public virtual DbSet<Message> Messages { get; set; }
|
||||
|
||||
public virtual DbSet<Notification> Notifications { get; set; }
|
||||
|
||||
public virtual DbSet<Permission> Permissions { get; set; }
|
||||
|
||||
public virtual DbSet<Permissionarole> Permissionaroles { get; set; }
|
||||
|
||||
public virtual DbSet<Role> Roles { get; set; }
|
||||
|
||||
public virtual DbSet<User> Users { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||
=> optionsBuilder.UseMySql("server=frp-era.com;port=26582;database=IM;user=product;password=12345678", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.7.44-mysql"));
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.UseCollation("latin1_swedish_ci")
|
||||
.HasCharSet("latin1");
|
||||
|
||||
modelBuilder.Entity<Admin>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("admins")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.RoleId, "RoleId");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Password)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("密码");
|
||||
entity.Property(e => e.RoleId)
|
||||
.HasComment("角色")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("状态(0:正常,2:封禁) ")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Updated)
|
||||
.HasComment("更新时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Username)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("用户名");
|
||||
|
||||
entity.HasOne(d => d.Role).WithMany(p => p.Admins)
|
||||
.HasForeignKey(d => d.RoleId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("admins_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Conversation>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("conversations")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "Userid");
|
||||
|
||||
entity.HasIndex(e => e.LastReadMessageId, "lastReadMessageId");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.ChatType).HasColumnType("int(11)");
|
||||
entity.Property(e => e.LastReadMessageId)
|
||||
.HasComment("最后一条已读消息ID ")
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("lastMessageId");
|
||||
entity.Property(e => e.StreamKey)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("消息推送唯一标识符");
|
||||
entity.Property(e => e.TargetId)
|
||||
.HasComment("对方ID(群聊为群聊ID,单聊为单聊ID) ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.UnreadCount)
|
||||
.HasComment("未读消息数 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("用户")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.Conversations)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("conversations_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Device>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("devices")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "Userid");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Dtype)
|
||||
.HasComment("设备类型(\r\n0:Android,1:Ios,2:PC,3:Pad,4:未知)")
|
||||
.HasColumnType("tinyint(4)")
|
||||
.HasColumnName("DType");
|
||||
entity.Property(e => e.LastLogin)
|
||||
.HasComment("最后一次登录 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("设备所属用户 ")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.Devices)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("devices_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<File>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("files")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.MessageId, "Messageld");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.MessageId)
|
||||
.HasComment("关联消息ID ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("文件名 ");
|
||||
entity.Property(e => e.Size)
|
||||
.HasComment("文件大小(单位:KB) ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Type)
|
||||
.HasMaxLength(10)
|
||||
.HasComment("文件类型 ");
|
||||
entity.Property(e => e.Url)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("文件储存URL ")
|
||||
.HasColumnName("URL");
|
||||
|
||||
entity.HasOne(d => d.Message).WithMany(p => p.Files)
|
||||
.HasForeignKey(d => d.MessageId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("files_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Friend>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("friends")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.Id, "ID");
|
||||
|
||||
entity.HasIndex(e => new { e.UserId, e.FriendId }, "Userld");
|
||||
|
||||
entity.HasIndex(e => e.FriendId, "用户2id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Avatar)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("好友头像");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("好友关系创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.FriendId)
|
||||
.HasComment("用户2ID")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.RemarkName)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("好友备注名");
|
||||
entity.Property(e => e.Status)
|
||||
.HasComment("当前好友关系状态\r\n(0:待通过,1:已添加,2:已拒绝,3:已拉黑)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("用户ID")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.FriendNavigation).WithMany(p => p.FriendFriendNavigations)
|
||||
.HasForeignKey(d => d.FriendId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("用户2id");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.FriendUsers)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("用户id");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<FriendRequest>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("friend_request")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.RequestUser, "RequestUser");
|
||||
|
||||
entity.HasIndex(e => e.ResponseUser, "ResponseUser");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("申请时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Description)
|
||||
.HasComment("申请附言 ")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.RequestUser)
|
||||
.HasComment("申请人 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.ResponseUser)
|
||||
.HasComment("被申请人 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("申请状态(0:待通过,1:拒绝,2:同意,3:拉黑) ")
|
||||
.HasColumnType("tinyint(4)");
|
||||
|
||||
entity.HasOne(d => d.RequestUserNavigation).WithMany(p => p.FriendRequestRequestUserNavigations)
|
||||
.HasForeignKey(d => d.RequestUser)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("friend_request_ibfk_1");
|
||||
|
||||
entity.HasOne(d => d.ResponseUserNavigation).WithMany(p => p.FriendRequestResponseUserNavigations)
|
||||
.HasForeignKey(d => d.ResponseUser)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("friend_request_ibfk_2");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Group>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("groups")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.GroupMaster, "GroupMaster");
|
||||
|
||||
entity.HasIndex(e => e.Id, "ID");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.AllMembersBanned)
|
||||
.HasComment("全员禁言(0允许发言,2全员禁言)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Announcement)
|
||||
.HasComment("群公告")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.Auhority)
|
||||
.HasComment("群权限\r\n(0:需管理员同意,1:任意人可加群,2:不允许任何人加入)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("群聊创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.GroupMaster)
|
||||
.HasComment("群主")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("群聊名称");
|
||||
entity.Property(e => e.Status)
|
||||
.HasComment("群聊状态\r\n(1:正常,2:封禁)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
|
||||
entity.HasOne(d => d.GroupMasterNavigation).WithMany(p => p.Groups)
|
||||
.HasForeignKey(d => d.GroupMaster)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("groups_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<GroupInvite>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("group_invite")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.GroupId, "GroupId");
|
||||
|
||||
entity.HasIndex(e => e.InviteUser, "InviteUser");
|
||||
|
||||
entity.HasIndex(e => e.InvitedUser, "InvitedUser");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.GroupId)
|
||||
.HasComment("群聊编号")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.InviteUser)
|
||||
.HasComment("邀请用户")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.InvitedUser)
|
||||
.HasComment("被邀请用户")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("当前状态(0:待被邀请人同意\r\n1:被邀请人已同意)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
|
||||
entity.HasOne(d => d.Group).WithMany(p => p.GroupInvites)
|
||||
.HasForeignKey(d => d.GroupId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("group_invite_ibfk_2");
|
||||
|
||||
entity.HasOne(d => d.InviteUserNavigation).WithMany(p => p.GroupInviteInviteUserNavigations)
|
||||
.HasForeignKey(d => d.InviteUser)
|
||||
.HasConstraintName("group_invite_ibfk_1");
|
||||
|
||||
entity.HasOne(d => d.InvitedUserNavigation).WithMany(p => p.GroupInviteInvitedUserNavigations)
|
||||
.HasForeignKey(d => d.InvitedUser)
|
||||
.HasConstraintName("group_invite_ibfk_3");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<GroupMember>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("group_member")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.GroupId, "Groupld");
|
||||
|
||||
entity.HasIndex(e => e.Id, "ID");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "Userld");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasDefaultValueSql("'1970-01-01 00:00:00'")
|
||||
.HasComment("加入群聊时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.GroupId)
|
||||
.HasComment("群聊编号")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Role)
|
||||
.HasComment("成员角色(0:普通成员,1:管理员,2:群主)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("用户编号")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.Group).WithMany(p => p.GroupMemberGroups)
|
||||
.HasForeignKey(d => d.GroupId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("group_member_ibfk_2");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.GroupMemberUsers)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("group_member_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<GroupRequest>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("group_request")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.GroupId, "GroupId");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Description)
|
||||
.HasComment("入群附言")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.GroupId)
|
||||
.HasComment("群聊编号\r\n")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("申请状态(0:待管理员同意,1:已拒绝,2:已同意)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("申请人 ")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.Group).WithMany(p => p.GroupRequests)
|
||||
.HasForeignKey(d => d.GroupId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("group_request_ibfk_1");
|
||||
|
||||
entity.HasOne(d => d.GroupNavigation).WithMany(p => p.GroupRequests)
|
||||
.HasForeignKey(d => d.GroupId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("group_request_ibfk_2");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<LoginLog>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("login_log")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "Userld");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Dtype)
|
||||
.HasComment("设备类型(通Devices/DType) ")
|
||||
.HasColumnType("tinyint(4)")
|
||||
.HasColumnName("DType");
|
||||
entity.Property(e => e.Logined)
|
||||
.HasComment("登录时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("登录状态(0:登陆成功,1:未验证,2:已被拒绝) ")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("登录用户 ")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.LoginLogs)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("login_log_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Message>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("messages")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.Sender, "Sender");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.ChatType)
|
||||
.HasComment("聊天类型\r\n(0:私聊,1:群聊)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Content)
|
||||
.HasComment("消息内容 ")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("发送时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.MsgType)
|
||||
.HasComment("消息类型\r\n(0:文本,1:图片,2:语音,3:视频,4:文件,5:语音聊天,6:视频聊天)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Recipient)
|
||||
.HasComment("接收者(私聊为用户ID,群聊为群聊ID) ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Sender)
|
||||
.HasComment("发送者 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.State)
|
||||
.HasComment("消息状态(0:已发送,1:已撤回) ")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.StreamKey)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("消息推送唯一标识符");
|
||||
|
||||
entity.HasOne(d => d.SenderNavigation).WithMany(p => p.Messages)
|
||||
.HasForeignKey(d => d.Sender)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("messages_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Notification>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("notifications")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.UserId, "Userld");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Content)
|
||||
.HasComment("通知内容")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Ntype)
|
||||
.HasComment("通知类型(0:文本)")
|
||||
.HasColumnType("tinyint(4)")
|
||||
.HasColumnName("NType");
|
||||
entity.Property(e => e.Title)
|
||||
.HasMaxLength(40)
|
||||
.HasComment("通知标题");
|
||||
entity.Property(e => e.UserId)
|
||||
.HasComment("接收人(为空为全体通知)")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.User).WithMany(p => p.Notifications)
|
||||
.HasForeignKey(d => d.UserId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("notifications_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Permission>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("permissions")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Code)
|
||||
.HasComment("权限编码 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("权限名称 ");
|
||||
entity.Property(e => e.Ptype)
|
||||
.HasComment("权限类型(0:增,1:删,2:改,3:查) ")
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("PType");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Permissionarole>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("permissionarole")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.PermissionId, "Permissionld");
|
||||
|
||||
entity.HasIndex(e => e.RoleId, "Roleld");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.ValueGeneratedNever()
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.PermissionId)
|
||||
.HasComment("权限 ")
|
||||
.HasColumnType("int(11)");
|
||||
entity.Property(e => e.RoleId)
|
||||
.HasComment("角色 ")
|
||||
.HasColumnType("int(11)");
|
||||
|
||||
entity.HasOne(d => d.Permission).WithMany(p => p.Permissionaroles)
|
||||
.HasForeignKey(d => d.PermissionId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("permissionarole_ibfk_2");
|
||||
|
||||
entity.HasOne(d => d.Role).WithMany(p => p.Permissionaroles)
|
||||
.HasForeignKey(d => d.RoleId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("permissionarole_ibfk_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Role>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("roles")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Created)
|
||||
.HasComment("创建时间 ")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Description)
|
||||
.HasComment("角色描述 ")
|
||||
.HasColumnType("text");
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("角色名称 ");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<User>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PRIMARY");
|
||||
|
||||
entity
|
||||
.ToTable("users")
|
||||
.HasCharSet("utf8mb4")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
entity.HasIndex(e => e.Id, "ID");
|
||||
|
||||
entity.HasIndex(e => e.Username, "Username").IsUnique();
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int(11)")
|
||||
.HasColumnName("ID");
|
||||
entity.Property(e => e.Avatar)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("用户头像链接");
|
||||
entity.Property(e => e.Created)
|
||||
.HasDefaultValueSql("'1970-01-01 00:00:00'")
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.IsDeleted)
|
||||
.HasComment("软删除标识\r\n0:账号正常\r\n1:账号已删除")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.NickName)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("用户昵称");
|
||||
entity.Property(e => e.OnlineStatus)
|
||||
.HasComment("用户在线状态\r\n0(默认):不在线\r\n1:在线")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Password)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("密码");
|
||||
entity.Property(e => e.Status)
|
||||
.HasDefaultValueSql("'1'")
|
||||
.HasComment("账户状态\r\n(0:未激活,1:正常,2:封禁)")
|
||||
.HasColumnType("tinyint(4)");
|
||||
entity.Property(e => e.Updated)
|
||||
.HasComment("修改时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.Username)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("唯一用户名");
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
}
|
||||
@@ -49,6 +49,11 @@ public partial class Message
|
||||
/// </summary>
|
||||
public string StreamKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 若为群消息则表示具体的成员id
|
||||
/// </summary>
|
||||
public int? GroupMemberId { get; set; }
|
||||
|
||||
public virtual ICollection<Conversation> Conversations { get; set; } = new List<Conversation>();
|
||||
|
||||
public virtual ICollection<File> Files { get; set; } = new List<File>();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using IM_API.Dtos;
|
||||
using AutoMapper;
|
||||
using IM_API.Dtos;
|
||||
using IM_API.Exceptions;
|
||||
using IM_API.Interface.Services;
|
||||
using IM_API.Models;
|
||||
@@ -10,9 +11,11 @@ namespace IM_API.Services
|
||||
public class ConversationService : IConversationService
|
||||
{
|
||||
private readonly ImContext _context;
|
||||
public ConversationService(ImContext context)
|
||||
private readonly IMapper _mapper;
|
||||
public ConversationService(ImContext context, IMapper mapper)
|
||||
{
|
||||
_context = context;
|
||||
_mapper = mapper;
|
||||
}
|
||||
#region 删除用户会话
|
||||
public async Task<bool> ClearConversationsAsync(int userId)
|
||||
@@ -26,47 +29,41 @@ namespace IM_API.Services
|
||||
#region 获取用户会话列表
|
||||
public async Task<List<ConversationDto>> GetConversationsAsync(int userId)
|
||||
{
|
||||
var privateQuery = from c in _context.Conversations
|
||||
join f in _context.Friends on new { c.UserId, c.TargetId}
|
||||
equals new { UserId = f.UserId, TargetId = f.FriendId}
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.PRIVATE
|
||||
select new ConversationDto
|
||||
{
|
||||
Id = c.Id,
|
||||
UserId = c.UserId,
|
||||
TargetId = c.TargetId,
|
||||
LastReadMessageId = c.LastReadMessageId,
|
||||
LastReadMessage = c.LastReadMessage,
|
||||
UnreadCount = c.UnreadCount,
|
||||
ChatType = c.ChatType,
|
||||
LastMessage = c.LastMessage,
|
||||
TargetAvatar = f.Avatar,
|
||||
TargetName = f.RemarkName,
|
||||
DateTime = c.LastMessageTime
|
||||
// 1. 获取私聊会话
|
||||
var privateList = await (from c in _context.Conversations
|
||||
join f in _context.Friends on new { c.UserId, c.TargetId }
|
||||
equals new { UserId = f.UserId, TargetId = f.FriendId }
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.PRIVATE
|
||||
select new { c, f.Avatar, f.RemarkName })
|
||||
.ToListAsync();
|
||||
|
||||
};
|
||||
// 2. 获取群聊会话
|
||||
var groupList = await (from c in _context.Conversations
|
||||
join g in _context.Groups on c.TargetId equals g.Id
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.GROUP
|
||||
select new { c, g.Avatar, g.Name })
|
||||
.ToListAsync();
|
||||
|
||||
var groupQuery = from c in _context.Conversations
|
||||
join g in _context.Groups on c.TargetId equals g.Id
|
||||
where c.UserId == userId && c.ChatType == (int)ChatType.GROUP
|
||||
select new ConversationDto
|
||||
{
|
||||
Id = c.Id,
|
||||
UserId = c.UserId,
|
||||
TargetId = c.TargetId,
|
||||
LastReadMessageId = c.LastReadMessageId,
|
||||
LastReadMessage = c.LastReadMessage,
|
||||
UnreadCount = c.UnreadCount,
|
||||
ChatType = c.ChatType,
|
||||
LastMessage = c.LastMessage,
|
||||
TargetAvatar = g.Avatar,
|
||||
TargetName = g.Name,
|
||||
DateTime = c.LastMessageTime
|
||||
};
|
||||
return await privateQuery
|
||||
.Concat(groupQuery)
|
||||
.OrderByDescending(x => x.DateTime)
|
||||
.ToListAsync();
|
||||
var privateDtos = privateList.Select(x =>
|
||||
{
|
||||
var dto = _mapper.Map<ConversationDto>(x.c);
|
||||
dto.TargetAvatar = x.Avatar;
|
||||
dto.TargetName = x.RemarkName;
|
||||
return dto;
|
||||
});
|
||||
|
||||
var groupDtos = groupList.Select(x =>
|
||||
{
|
||||
var dto = _mapper.Map<ConversationDto>(x.c);
|
||||
dto.TargetAvatar = x.Avatar;
|
||||
dto.TargetName = x.Name;
|
||||
return dto;
|
||||
});
|
||||
|
||||
// 4. 合并并排序
|
||||
return privateDtos.Concat(groupDtos)
|
||||
.OrderByDescending(x => x.DateTime)
|
||||
.ToList();
|
||||
}
|
||||
#endregion
|
||||
#region 删除单个会话
|
||||
@@ -81,6 +78,7 @@ namespace IM_API.Services
|
||||
|
||||
|
||||
#endregion
|
||||
#region 获取用户所有统一聊天凭证
|
||||
public async Task<List<string>> GetUserAllStreamKeyAsync(int userId)
|
||||
{
|
||||
return await _context.Conversations.Where(x => x.UserId == userId)
|
||||
@@ -88,5 +86,37 @@ namespace IM_API.Services
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取单个会话信息
|
||||
public async Task<ConversationDto> GetConversationByIdAsync(int userId, int conversationId)
|
||||
{
|
||||
var conversation = await _context.Conversations
|
||||
.Include(x => x.LastReadMessage)
|
||||
.FirstOrDefaultAsync(
|
||||
x => x.UserId == userId && x.Id == conversationId
|
||||
);
|
||||
if (conversation is null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
|
||||
var dto = _mapper.Map<ConversationDto>(conversation);
|
||||
//dto.LastReadMessage = _mapper.Map<MessageBaseDto>(conversation);
|
||||
if(conversation.ChatType == (int)ChatType.PRIVATE)
|
||||
{
|
||||
var friendInfo = await _context.Friends.FirstOrDefaultAsync(
|
||||
x => x.UserId == userId && x.FriendId == conversation.TargetId
|
||||
);
|
||||
if (friendInfo is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND);
|
||||
_mapper.Map(friendInfo,dto);
|
||||
}
|
||||
if(conversation.ChatType == (int)ChatType.GROUP)
|
||||
{
|
||||
var groupInfo = await _context.Groups.FirstOrDefaultAsync(
|
||||
x => x.Id == conversation.TargetId
|
||||
);
|
||||
if (groupInfo is null) throw new BaseException(CodeDefine.GROUP_NOT_FOUND);
|
||||
_mapper.Map(groupInfo, dto);
|
||||
}
|
||||
return dto;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,38 @@ namespace IM_API.Services
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public Task<List<MessageBaseDto>> GetGroupMessagesAsync(int groupId, int page, int pageSize, bool desc)
|
||||
public async Task<List<MessageBaseDto>> GetMessagesAsync(int userId, int conversationId, int? msgId, int? pageSize, bool desc)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<List<MessageBaseDto>> GetPrivateMessagesAsync(int userAId, int userBId, int page, int pageSize, bool desc)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//获取会话信息,用于获取双方聊天的唯一标识streamkey
|
||||
Conversation? conversation = await _context.Conversations.FirstOrDefaultAsync(
|
||||
x => x.Id == conversationId && x.UserId == userId
|
||||
);
|
||||
if (conversation is null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
|
||||
var query = _context.Messages.AsQueryable();
|
||||
if(msgId != null)
|
||||
{
|
||||
query = query.Where(
|
||||
x => x.StreamKey == conversation.StreamKey && x.Id < msgId.Value
|
||||
)
|
||||
.OrderByDescending(x => x.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.Where(
|
||||
x => x.StreamKey == conversation.StreamKey && x.Id > conversation.LastReadMessageId
|
||||
);
|
||||
}
|
||||
if(pageSize != null)
|
||||
{
|
||||
query = query.Take(pageSize.Value);
|
||||
}
|
||||
var msgList = await query
|
||||
.ToListAsync();
|
||||
msgList = msgList
|
||||
.OrderBy(x => x.Created)
|
||||
.ThenBy(t => t.Id)
|
||||
.ToList();
|
||||
return _mapper.Map<List<MessageBaseDto>>(msgList);
|
||||
}
|
||||
|
||||
public Task<int> GetUnreadCountAsync(int userId)
|
||||
|
||||
Reference in New Issue
Block a user