Merge branch 'feature-nxdev' of https://gitea.nxsir.cn/code/IM into feature-nxdev

This commit is contained in:
2026-02-03 22:46:34 +08:00
73 changed files with 1342 additions and 484 deletions
+2 -1
View File
@@ -4,13 +4,14 @@ using Moq;
using AutoMapper;
using IM_API.Services;
using IM_API.Models;
using IM_API.Dtos;
using IM_API.Exceptions;
using IM_API.Tools;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using IM_API.Dtos.Auth;
using IM_API.Dtos.User;
public class AuthServiceTests
{
+1 -1
View File
@@ -1,6 +1,6 @@
using AutoMapper;
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Dtos.Friend;
using IM_API.Exceptions;
using IM_API.Models;
using IM_API.Services;
+1 -1
View File
@@ -4,12 +4,12 @@ using Moq;
using AutoMapper;
using IM_API.Services;
using IM_API.Models;
using IM_API.Dtos;
using IM_API.Exceptions;
using IM_API.Tools;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using IM_API.Dtos.User;
public class UserServiceTests
{
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+83be063e7fbdba82984ef3beb231bd8a0a983c2f")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+22038345c32db146ffb78173c5410f954daa64e0")]
[assembly: System.Reflection.AssemblyProductAttribute("IMTest")]
[assembly: System.Reflection.AssemblyTitleAttribute("IMTest")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
@@ -1 +1 @@
495895405696fa7fe9836aaaa2da1791d39c26be9cfe301758e0fe7d7c9164b6
ee1fc45f192938903a153f1c2e3b53f60a2184cb806b87d9b57b487095b98264
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,21 +6,18 @@ namespace IM_API.Application.EventHandlers.FriendAddHandler
{
public class FriendAddConversationHandler : IConsumer<FriendAddEvent>
{
private readonly IFriendSerivce _friendService;
public FriendAddConversationHandler(IFriendSerivce friendService)
private readonly IConversationService _cService;
public FriendAddConversationHandler(IConversationService cService)
{
_friendService = friendService;
_cService = cService;
}
public async Task Consume(ConsumeContext<FriendAddEvent> context)
{
var @event = context.Message;
//为请求发起人添加好友记录
await _friendService.MakeFriendshipAsync(
@event.RequestUserId, @event.ResponseUserId, @event.RequestInfo.RemarkName);
//为接收人添加好友记录
await _friendService.MakeFriendshipAsync(
@event.ResponseUserId, @event.RequestUserId, @event.requestUserRemarkname);
await _cService.MakeConversationAsync(@event.RequestUserId, @event.ResponseUserId, Models.ChatType.PRIVATE);
await _cService.MakeConversationAsync(@event.ResponseUserId, @event.RequestUserId, Models.ChatType.PRIVATE);
}
}
}
@@ -0,0 +1,29 @@
using IM_API.Domain.Events;
using IM_API.Interface.Services;
using MassTransit;
namespace IM_API.Application.EventHandlers.FriendAddHandler
{
public class FriendAddDBHandler : IConsumer<FriendAddEvent>
{
private readonly IFriendSerivce _friendService;
private readonly ILogger<FriendAddDBHandler> _logger;
public FriendAddDBHandler(IFriendSerivce friendService, ILogger<FriendAddDBHandler> logger)
{
_friendService = friendService;
_logger = logger;
}
public async Task Consume(ConsumeContext<FriendAddEvent> context)
{
var @event = context.Message;
//为请求发起人添加好友记录
await _friendService.MakeFriendshipAsync(
@event.RequestUserId, @event.ResponseUserId, @event.RequestInfo.RemarkName);
//为接收人添加好友记录
await _friendService.MakeFriendshipAsync(
@event.ResponseUserId, @event.RequestUserId, @event.requestUserRemarkname);
}
}
}
@@ -0,0 +1,13 @@
using IM_API.Domain.Events;
using MassTransit;
namespace IM_API.Application.EventHandlers.GroupRequestHandler
{
public class GroupRequestSignalRHandler : IConsumer<GroupRequestEvent>
{
Task IConsumer<GroupRequestEvent>.Consume(ConsumeContext<GroupRequestEvent> context)
{
throw new NotImplementedException();
}
}
}
@@ -1,5 +1,6 @@
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Dtos.Friend;
using IM_API.Hubs;
using IM_API.Interface.Services;
using MassTransit;
+5 -1
View File
@@ -1,5 +1,6 @@
using IM_API.Application.EventHandlers.FriendAddHandler;
using IM_API.Application.EventHandlers.MessageCreatedHandler;
using IM_API.Application.EventHandlers.RequestFriendHandler;
using MassTransit;
namespace IM_API.Configs
@@ -12,8 +13,10 @@ namespace IM_API.Configs
{
x.AddConsumer<ConversationEventHandler>();
x.AddConsumer<SignalREventHandler>();
x.AddConsumer<FriendAddConversationHandler>();
x.AddConsumer<FriendAddDBHandler>();
x.AddConsumer<FriendAddSignalRHandler>();
x.AddConsumer<RequestFriendSignalRHandler>();
x.AddConsumer<FriendAddConversationHandler>();
x.UsingRabbitMq((ctx,cfg) =>
{
@@ -22,6 +25,7 @@ namespace IM_API.Configs
h.Username(options.Username);
h.Password(options.Password);
});
cfg.ConfigureEndpoints(ctx);
});
});
+20
View File
@@ -1,6 +1,11 @@
using AutoMapper;
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Dtos.Auth;
using IM_API.Dtos.Conversation;
using IM_API.Dtos.Friend;
using IM_API.Dtos.Group;
using IM_API.Dtos.User;
using IM_API.Models;
namespace IM_API.Configs
@@ -131,6 +136,21 @@ namespace IM_API.Configs
CreateMap<Group, ConversationDto>()
.ForMember(dest => dest.TargetAvatar, opt => opt.MapFrom(src => src.Avatar))
.ForMember(dest => dest.TargetName, opt => opt.MapFrom(src => src.Name));
//群模型转换
CreateMap<Group, GroupInfoDto>()
.ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.StatusEnum))
.ForMember(dest => dest.AllMembersBanned, opt => opt.MapFrom(src => src.AllMembersBannedEnum))
.ForMember(dest => dest.Auhority, opt => opt.MapFrom(src => src.AuhorityEnum));
CreateMap<GroupCreateDto, Group>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
.ForMember(dest => dest.Avatar, opt => opt.MapFrom(src => src.Avatar))
.ForMember(dest => dest.Created, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dest => dest.AllMembersBannedEnum, opt => opt.MapFrom(src => GroupAllMembersBanned.ALLOWED))
.ForMember(dest => dest.AuhorityEnum, opt => opt.MapFrom(src => GroupAuhority.REQUIRE_CONSENT))
.ForMember(dest => dest.StatusEnum, opt => opt.MapFrom(src => GroupStatus.Normal));
}
}
}
@@ -1,5 +1,7 @@
using AutoMapper;
using IM_API.Dtos;
using IM_API.Dtos.Auth;
using IM_API.Dtos.User;
using IM_API.Interface.Services;
using IM_API.Tools;
using Microsoft.AspNetCore.Http;
@@ -1,4 +1,5 @@
using IM_API.Dtos;
using IM_API.Dtos.Conversation;
using IM_API.Interface.Services;
using IM_API.Models;
using Microsoft.AspNetCore.Authorization;
@@ -1,4 +1,5 @@
using IM_API.Dtos;
using IM_API.Dtos.Friend;
using IM_API.Interface.Services;
using IM_API.Models;
using Microsoft.AspNetCore.Authorization;
@@ -60,7 +61,7 @@ namespace IM_API.Controllers
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> HandleRequest(
[FromRoute]int id, [FromBody]FriendRequestHandleDto dto
[FromQuery]int id, [FromBody]FriendRequestHandleDto dto
)
{
await _friendService.HandleFriendRequestAsync(new HandleFriendRequestDto()
@@ -1,4 +1,5 @@
using IM_API.Dtos;
using IM_API.Dtos.User;
using IM_API.Interface.Services;
using IM_API.Tools;
using Microsoft.AspNetCore.Authorization;
@@ -1,4 +1,4 @@
using IM_API.Dtos;
using IM_API.Dtos.Friend;
namespace IM_API.Domain.Events
{
@@ -0,0 +1,10 @@
namespace IM_API.Domain.Events
{
public record GroupInviteEvent : DomainEvent
{
public override string EventType => "IM.GROUPS_GROUP_INVITE";
public required List<int> Ids { get; init; }
public int GroupId { get; init; }
public int UserId { get; init; }
}
}
@@ -0,0 +1,13 @@
using IM_API.Dtos.Group;
namespace IM_API.Domain.Events
{
public record GroupRequestEvent : DomainEvent
{
public override string EventType => "IM.GROUPS_GROUP_REQUEST";
public int GroupId { get; init; }
public int UserId { get; set; }
public string Description { get; set; }
}
}
@@ -1,4 +1,4 @@
namespace IM_API.Dtos
namespace IM_API.Dtos.Auth
{
public record RefreshDto(string refreshToken);
}
@@ -1,4 +1,6 @@
namespace IM_API.Dtos
using IM_API.Dtos.User;
namespace IM_API.Dtos.Auth
{
public class LoginDto
{
@@ -8,9 +10,9 @@
public DateTime ExpireAt { get; set; }
public LoginDto(UserInfoDto userInfo,string token, string refreshToken, DateTime expireAt) {
this.userInfo = userInfo;
this.Token = token;
this.RefreshToken = refreshToken;
this.ExpireAt = expireAt;
Token = token;
RefreshToken = refreshToken;
ExpireAt = expireAt;
}
}
}
@@ -1,7 +1,7 @@
using IM_API.Tools;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.Auth
{
public class LoginRequestDto
{
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.Auth
{
public class RegisterRequestDto
{
@@ -1,4 +1,4 @@
namespace IM_API.Dtos
namespace IM_API.Dtos.Conversation
{
public class ClearConversationsDto
{
@@ -1,6 +1,6 @@
using IM_API.Models;
namespace IM_API.Dtos
namespace IM_API.Dtos.Conversation
{
public class ConversationDto
{
@@ -1,7 +1,8 @@
using IM_API.Models;
using IM_API.Dtos.User;
using IM_API.Models;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.Friend
{
public record FriendInfoDto
{
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.Friend
{
public class FriendRequestDto
{
@@ -1,6 +1,6 @@
using IM_API.Models;
namespace IM_API.Dtos
namespace IM_API.Dtos.Friend
{
public class FriendRequestResDto
{
@@ -1,4 +1,4 @@
namespace IM_API.Dtos
namespace IM_API.Dtos.Friend
{
public class HandleFriendRequestDto
{
@@ -0,0 +1,17 @@
using IM_API.Models;
namespace IM_API.Dtos.Group
{
public class GroupCreateDto
{
/// <summary>
/// 群聊名称
/// </summary>
public string Name { get; set; } = null!;
/// <summary>
/// 群头像
/// </summary>
public string Avatar { get; set; } = null!;
}
}
+51
View File
@@ -0,0 +1,51 @@
using IM_API.Models;
namespace IM_API.Dtos.Group
{
public class GroupInfoDto
{
public int Id { get; set; }
/// <summary>
/// 群聊名称
/// </summary>
public string Name { get; set; } = null!;
/// <summary>
/// 群主
/// </summary>
public int GroupMaster { get; set; }
/// <summary>
/// 群权限
/// (0:需管理员同意,1:任意人可加群,2:不允许任何人加入)
/// </summary>
public GroupAuhority Auhority { get; set; }
/// <summary>
/// 全员禁言(0允许发言,2全员禁言)
/// </summary>
public GroupAllMembersBanned AllMembersBanned { get; set; }
/// <summary>
/// 群聊状态
/// (1:正常,2:封禁)
/// </summary>
public GroupStatus Status { get; set; }
/// <summary>
/// 群公告
/// </summary>
public string? Announcement { get; set; }
/// <summary>
/// 群聊创建时间
/// </summary>
public DateTime Created { get; set; }
/// <summary>
/// 群头像
/// </summary>
public string Avatar { get; set; } = null!;
}
}
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.User
{
public class UpdateUserDto
{
@@ -1,7 +1,7 @@
using IM_API.Models;
using System.ComponentModel.DataAnnotations;
namespace IM_API.Dtos
namespace IM_API.Dtos.User
{
public record PasswordResetDto
{
@@ -2,7 +2,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace IM_API.Dtos
namespace IM_API.Dtos.User
{
public class UserInfoDto
{
+4
View File
@@ -31,4 +31,8 @@
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.14.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Application\EventHandlers\GroupInviteHandler\" />
</ItemGroup>
</Project>
@@ -1,4 +1,5 @@
using IM_API.Dtos;
using IM_API.Dtos.Auth;
using IM_API.Dtos.User;
using IM_API.Models;
namespace IM_API.Interface.Services
@@ -1,4 +1,4 @@
using IM_API.Dtos;
using IM_API.Dtos.Conversation;
using IM_API.Models;
namespace IM_API.Interface.Services
@@ -42,5 +42,13 @@ namespace IM_API.Interface.Services
/// <param name="conversationId"></param>
/// <returns></returns>
Task<bool> ClearUnreadCountAsync(int userId, int conversationId);
/// <summary>
/// 为用户创建会话
/// </summary>
/// <param name="userAId"></param>
/// <param name="userBId"></param>
/// <param name="chatType"></param>
/// <returns></returns>
Task MakeConversationAsync(int userAId, int userBId, ChatType chatType);
}
}
@@ -1,4 +1,4 @@
using IM_API.Dtos;
using IM_API.Dtos.Friend;
using IM_API.Models;
namespace IM_API.Interface.Services
@@ -0,0 +1,39 @@
using IM_API.Dtos.Group;
namespace IM_API.Interface.Services
{
public interface IGroupService
{
/// <summary>
/// 邀请好友入群
/// </summary>
/// <param name="userId">操作者ID</param>
/// <param name="groupId">群ID</param>
/// <param name="userIds">邀请的用户列表</param>
/// <returns></returns>
Task InviteUsers(int userId,int groupId, List<int> userIds);
/// <summary>
/// 加入群聊
/// </summary>
/// <param name="userId">操作者ID</param>
/// <param name="groupId">群ID</param>
/// <returns></returns>
Task JoinGroup(int userId,int groupId);
/// <summary>
/// 创建群聊
/// </summary>
/// <param name="userId">操作者ID</param>
/// <param name="groupCreateDto">群信息</param>
/// <param name="userIds">邀请用户列表</param>
/// <returns></returns>
Task<GroupInfoDto> CreateGroup(int userId, GroupCreateDto groupCreateDto, List<int> userIds);
/// <summary>
/// 删除群
/// </summary>
/// <param name="userId">操作者ID</param>
/// <param name="groupId">群ID</param>
/// <returns></returns>
Task DeleteGroup(int userId, int groupId);
//Task UpdateGroupAuthori
}
}
@@ -1,4 +1,4 @@
using IM_API.Dtos;
using IM_API.Dtos.User;
using IM_API.Models;
namespace IM_API.Interface.Services
+2
View File
@@ -53,5 +53,7 @@ public partial class Group
public virtual User GroupMasterNavigation { get; set; } = null!;
public virtual ICollection<GroupMember> GroupMembers { get; set; } = new List<GroupMember>();
public virtual ICollection<GroupRequest> GroupRequests { get; set; } = new List<GroupRequest>();
}
+1 -1
View File
@@ -27,7 +27,7 @@ public partial class GroupMember
/// </summary>
public DateTime Created { get; set; }
public virtual User Group { get; set; } = null!;
public virtual Group Group { get; set; } = null!;
public virtual User User { get; set; } = null!;
}
+2 -2
View File
@@ -432,12 +432,12 @@ public partial class ImContext : DbContext
.HasComment("用户编号")
.HasColumnType("int(11)");
entity.HasOne(d => d.Group).WithMany(p => p.GroupMemberGroups)
entity.HasOne(d => d.Group).WithMany(p => p.GroupMembers)
.HasForeignKey(d => d.GroupId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("group_member_ibfk_2");
entity.HasOne(d => d.User).WithMany(p => p.GroupMemberUsers)
entity.HasOne(d => d.User).WithMany(p => p.GroupMembers)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("group_member_ibfk_1");
+1 -3
View File
@@ -73,9 +73,7 @@ public partial class User
public virtual ICollection<GroupInvite> GroupInviteInvitedUserNavigations { get; set; } = new List<GroupInvite>();
public virtual ICollection<GroupMember> GroupMemberGroups { get; set; } = new List<GroupMember>();
public virtual ICollection<GroupMember> GroupMemberUsers { get; set; } = new List<GroupMember>();
public virtual ICollection<GroupMember> GroupMembers { get; set; } = new List<GroupMember>();
public virtual ICollection<GroupRequest> GroupRequests { get; set; } = new List<GroupRequest>();
+2 -1
View File
@@ -1,5 +1,6 @@
using AutoMapper;
using IM_API.Dtos;
using IM_API.Dtos.Auth;
using IM_API.Dtos.User;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
+23 -1
View File
@@ -1,5 +1,5 @@
using AutoMapper;
using IM_API.Dtos;
using IM_API.Dtos.Conversation;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
@@ -134,5 +134,27 @@ namespace IM_API.Services
return true;
}
public async Task MakeConversationAsync(int userAId, int userBId, ChatType chatType)
{
var userAcExist = await _context.Conversations.AnyAsync(x => x.UserId == userAId && x.TargetId == userBId);
if (userAcExist) return;
var streamKey = chatType == ChatType.PRIVATE ?
StreamKeyBuilder.Private(userAId, userBId) : StreamKeyBuilder.Group(userBId);
var conversation = new Conversation()
{
ChatType = (int)chatType,
LastMessage = "",
LastMessageTime = DateTime.UtcNow,
LastReadMessageId = -1,
StreamKey = streamKey,
TargetId = userBId,
UnreadCount = 0,
UserId = userAId
};
_context.Conversations.Add(conversation);
await _context.SaveChangesAsync();
}
}
}
+4 -5
View File
@@ -1,6 +1,6 @@
using AutoMapper;
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Dtos.Friend;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
@@ -117,15 +117,12 @@ namespace IM_API.Services
var friend = await _context.Friends.FirstOrDefaultAsync(
x => x.UserId == friendRequest.RequestUser && x.FriendId == friendRequest.ResponseUser
);
if (friend is null) throw new BaseException(CodeDefine.FRIEND_RELATION_NOT_FOUND);
if (friend.StatusEnum != FriendStatus.Pending) throw new BaseException(CodeDefine.FRIEND_REQUEST_EXISTS);
if (friend != null) throw new BaseException(CodeDefine.ALREADY_FRIENDS);
//处理好友请求操作
switch (requestDto.Action)
{
//拒绝后标记
case HandleFriendRequestAction.Reject:
friend.StatusEnum = FriendStatus.Declined;
friendRequest.StateEnum = FriendRequestState.Declined;
break;
@@ -141,6 +138,8 @@ namespace IM_API.Services
OperatorId = friendRequest.ResponseUser,
RequestInfo = _mapper.Map<FriendRequestDto>(friendRequest),
requestUserRemarkname = requestDto.RemarkName,
RequestUserId = friendRequest.RequestUser,
ResponseUserId = friendRequest.ResponseUser
});
break;
+110
View File
@@ -0,0 +1,110 @@
using AutoMapper;
using IM_API.Domain.Events;
using IM_API.Dtos.Group;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
using IM_API.Tools;
using MassTransit;
using Microsoft.EntityFrameworkCore;
using System;
namespace IM_API.Services
{
public class GroupService : IGroupService
{
private readonly ImContext _context;
private readonly IMapper _mapper;
private readonly ILogger<GroupService> _logger;
private readonly IPublishEndpoint _endPoint;
public GroupService(ImContext context, IMapper mapper, ILogger<GroupService> logger, IPublishEndpoint publishEndpoint)
{
_context = context;
_mapper = mapper;
_logger = logger;
_endPoint = publishEndpoint;
}
private async Task<List<GroupInvite>> GetGroupInvites(int userId, int groupId, List<int> ids)
{
DateTime dateTime = DateTime.UtcNow;
//验证被邀请用户是否为好友
var validFriendIds = await _context.Friends
.Where(f => f.UserId == userId && ids.Contains(f.FriendId))
.Select(f => f.FriendId)
.ToListAsync();
//创建群成员对象
return validFriendIds.Select(fid => new GroupInvite
{
Created = dateTime,
GroupId = groupId,
InvitedUser = fid,
StateEnum = GroupInviteState.Pending,
InviteUser = userId
}).ToList();
}
public async Task<GroupInfoDto> CreateGroup(int userId, GroupCreateDto groupCreateDto, List<int> userIds)
{
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
//先创建群
DateTime dateTime = DateTime.UtcNow;
Group group = _mapper.Map<Group>(groupCreateDto);
group.GroupMaster = userId;
_context.Groups.Add(group);
await _context.SaveChangesAsync();
var groupInvites = new List<GroupInvite>();
if (userIds.Count > 0)
{
groupInvites = await GetGroupInvites(userId,group.Id, userIds);
_context.GroupInvites.AddRange(groupInvites);
}
var groupMember = new GroupMember
{
UserId = userId,
Created = dateTime,
RoleEnum = GroupMemberRole.Master,
GroupId = group.Id
};
_context.GroupMembers.Add(groupMember);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
await _endPoint.Publish(new GroupInviteEvent
{
AggregateId = userId.ToString(),
GroupId = group.Id,
EventId = Guid.NewGuid(),
OccurredAt = dateTime,
Ids = groupInvites.Select(x => x.Id).ToList(),
OperatorId = userId,
UserId = userId
});
return _mapper.Map<GroupInfoDto>(group);
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
public Task DeleteGroup(int userId, int groupId)
{
throw new NotImplementedException();
}
public async Task InviteUsers(int userId, int groupId, List<int> userIds)
{
var group = await _context.Groups.FirstOrDefaultAsync(
x => x.Id == groupId) ?? throw new BaseException(CodeDefine.GROUP_NOT_FOUND);
}
public Task JoinGroup(int userId, int groupId)
{
throw new NotImplementedException();
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
using AutoMapper;
using IM_API.Dtos;
using IM_API.Dtos.User;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;