diff --git a/backend/IMTest/Service/AuthServiceTest.cs b/backend/IMTest/Service/AuthServiceTest.cs index 2f26b6f..8bf0142 100644 --- a/backend/IMTest/Service/AuthServiceTest.cs +++ b/backend/IMTest/Service/AuthServiceTest.cs @@ -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 { diff --git a/backend/IMTest/Service/FriendServiceTest.cs b/backend/IMTest/Service/FriendServiceTest.cs index 4a3ac23..5096971 100644 --- a/backend/IMTest/Service/FriendServiceTest.cs +++ b/backend/IMTest/Service/FriendServiceTest.cs @@ -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; diff --git a/backend/IMTest/Service/UserServiceTest.cs b/backend/IMTest/Service/UserServiceTest.cs index ca00e60..9df831d 100644 --- a/backend/IMTest/Service/UserServiceTest.cs +++ b/backend/IMTest/Service/UserServiceTest.cs @@ -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 { diff --git a/backend/IMTest/bin/Debug/net8.0/IMTest.dll b/backend/IMTest/bin/Debug/net8.0/IMTest.dll index 697ced0..0b2a470 100644 Binary files a/backend/IMTest/bin/Debug/net8.0/IMTest.dll and b/backend/IMTest/bin/Debug/net8.0/IMTest.dll differ diff --git a/backend/IMTest/bin/Debug/net8.0/IMTest.pdb b/backend/IMTest/bin/Debug/net8.0/IMTest.pdb index fd1edfb..6bac1a3 100644 Binary files a/backend/IMTest/bin/Debug/net8.0/IMTest.pdb and b/backend/IMTest/bin/Debug/net8.0/IMTest.pdb differ diff --git a/backend/IMTest/bin/Debug/net8.0/IM_API.dll b/backend/IMTest/bin/Debug/net8.0/IM_API.dll index 40f617b..3da801b 100644 Binary files a/backend/IMTest/bin/Debug/net8.0/IM_API.dll and b/backend/IMTest/bin/Debug/net8.0/IM_API.dll differ diff --git a/backend/IMTest/bin/Debug/net8.0/IM_API.exe b/backend/IMTest/bin/Debug/net8.0/IM_API.exe index 586f6e8..65fde7e 100644 Binary files a/backend/IMTest/bin/Debug/net8.0/IM_API.exe and b/backend/IMTest/bin/Debug/net8.0/IM_API.exe differ diff --git a/backend/IMTest/bin/Debug/net8.0/IM_API.pdb b/backend/IMTest/bin/Debug/net8.0/IM_API.pdb index df4373c..e74275f 100644 Binary files a/backend/IMTest/bin/Debug/net8.0/IM_API.pdb and b/backend/IMTest/bin/Debug/net8.0/IM_API.pdb differ diff --git a/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfo.cs b/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfo.cs index dfe6178..ffdca41 100644 --- a/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfo.cs +++ b/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfo.cs @@ -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")] diff --git a/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache b/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache index 937da7a..44b9dd3 100644 --- a/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache +++ b/backend/IMTest/obj/Debug/net8.0/IMTest.AssemblyInfoInputs.cache @@ -1 +1 @@ -495895405696fa7fe9836aaaa2da1791d39c26be9cfe301758e0fe7d7c9164b6 +ee1fc45f192938903a153f1c2e3b53f60a2184cb806b87d9b57b487095b98264 diff --git a/backend/IMTest/obj/Debug/net8.0/IMTest.csproj.AssemblyReference.cache b/backend/IMTest/obj/Debug/net8.0/IMTest.csproj.AssemblyReference.cache index bfc429b..be9dd6e 100644 Binary files a/backend/IMTest/obj/Debug/net8.0/IMTest.csproj.AssemblyReference.cache and b/backend/IMTest/obj/Debug/net8.0/IMTest.csproj.AssemblyReference.cache differ diff --git a/backend/IMTest/obj/Debug/net8.0/IMTest.dll b/backend/IMTest/obj/Debug/net8.0/IMTest.dll index 697ced0..0b2a470 100644 Binary files a/backend/IMTest/obj/Debug/net8.0/IMTest.dll and b/backend/IMTest/obj/Debug/net8.0/IMTest.dll differ diff --git a/backend/IMTest/obj/Debug/net8.0/IMTest.pdb b/backend/IMTest/obj/Debug/net8.0/IMTest.pdb index fd1edfb..6bac1a3 100644 Binary files a/backend/IMTest/obj/Debug/net8.0/IMTest.pdb and b/backend/IMTest/obj/Debug/net8.0/IMTest.pdb differ diff --git a/backend/IMTest/obj/Debug/net8.0/ref/IMTest.dll b/backend/IMTest/obj/Debug/net8.0/ref/IMTest.dll index dc8e36e..8cd8d14 100644 Binary files a/backend/IMTest/obj/Debug/net8.0/ref/IMTest.dll and b/backend/IMTest/obj/Debug/net8.0/ref/IMTest.dll differ diff --git a/backend/IMTest/obj/Debug/net8.0/refint/IMTest.dll b/backend/IMTest/obj/Debug/net8.0/refint/IMTest.dll index dc8e36e..8cd8d14 100644 Binary files a/backend/IMTest/obj/Debug/net8.0/refint/IMTest.dll and b/backend/IMTest/obj/Debug/net8.0/refint/IMTest.dll differ diff --git a/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddConversationHandler.cs b/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddConversationHandler.cs index 929deae..e621e48 100644 --- a/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddConversationHandler.cs +++ b/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddConversationHandler.cs @@ -6,21 +6,18 @@ namespace IM_API.Application.EventHandlers.FriendAddHandler { public class FriendAddConversationHandler : IConsumer { - 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 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); + } } } diff --git a/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddDBHandler.cs b/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddDBHandler.cs new file mode 100644 index 0000000..052cdd5 --- /dev/null +++ b/backend/IM_API/Application/EventHandlers/FriendAddHandler/FriendAddDBHandler.cs @@ -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 + { + private readonly IFriendSerivce _friendService; + private readonly ILogger _logger; + public FriendAddDBHandler(IFriendSerivce friendService, ILogger logger) + { + _friendService = friendService; + _logger = logger; + } + + public async Task Consume(ConsumeContext context) + { + var @event = context.Message; + + //为请求发起人添加好友记录 + await _friendService.MakeFriendshipAsync( + @event.RequestUserId, @event.ResponseUserId, @event.RequestInfo.RemarkName); + //为接收人添加好友记录 + await _friendService.MakeFriendshipAsync( + @event.ResponseUserId, @event.RequestUserId, @event.requestUserRemarkname); + } + } +} diff --git a/backend/IM_API/Application/EventHandlers/GroupRequestHandler/GroupRequestSignalRHandler.cs b/backend/IM_API/Application/EventHandlers/GroupRequestHandler/GroupRequestSignalRHandler.cs new file mode 100644 index 0000000..8fd19ec --- /dev/null +++ b/backend/IM_API/Application/EventHandlers/GroupRequestHandler/GroupRequestSignalRHandler.cs @@ -0,0 +1,13 @@ +using IM_API.Domain.Events; +using MassTransit; + +namespace IM_API.Application.EventHandlers.GroupRequestHandler +{ + public class GroupRequestSignalRHandler : IConsumer + { + Task IConsumer.Consume(ConsumeContext context) + { + throw new NotImplementedException(); + } + } +} diff --git a/backend/IM_API/Application/EventHandlers/RequestFriendHandler/RequestFriendSignalRHandler.cs b/backend/IM_API/Application/EventHandlers/RequestFriendHandler/RequestFriendSignalRHandler.cs index 35053d1..e39be9d 100644 --- a/backend/IM_API/Application/EventHandlers/RequestFriendHandler/RequestFriendSignalRHandler.cs +++ b/backend/IM_API/Application/EventHandlers/RequestFriendHandler/RequestFriendSignalRHandler.cs @@ -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; diff --git a/backend/IM_API/Configs/MQConfig.cs b/backend/IM_API/Configs/MQConfig.cs index 70c8d9e..b694705 100644 --- a/backend/IM_API/Configs/MQConfig.cs +++ b/backend/IM_API/Configs/MQConfig.cs @@ -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(); x.AddConsumer(); - x.AddConsumer(); + x.AddConsumer(); x.AddConsumer(); + x.AddConsumer(); + x.AddConsumer(); x.UsingRabbitMq((ctx,cfg) => { @@ -22,6 +25,7 @@ namespace IM_API.Configs h.Username(options.Username); h.Password(options.Password); }); + cfg.ConfigureEndpoints(ctx); }); }); diff --git a/backend/IM_API/Configs/MapperConfig.cs b/backend/IM_API/Configs/MapperConfig.cs index 09eb2c1..a117a54 100644 --- a/backend/IM_API/Configs/MapperConfig.cs +++ b/backend/IM_API/Configs/MapperConfig.cs @@ -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() .ForMember(dest => dest.TargetAvatar, opt => opt.MapFrom(src => src.Avatar)) .ForMember(dest => dest.TargetName, opt => opt.MapFrom(src => src.Name)); + + + //群模型转换 + CreateMap() + .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() + .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)); } } } diff --git a/backend/IM_API/Controllers/AuthController.cs b/backend/IM_API/Controllers/AuthController.cs index 612e647..a9fbf3a 100644 --- a/backend/IM_API/Controllers/AuthController.cs +++ b/backend/IM_API/Controllers/AuthController.cs @@ -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; diff --git a/backend/IM_API/Controllers/ConversationController.cs b/backend/IM_API/Controllers/ConversationController.cs index 61c98fd..311b106 100644 --- a/backend/IM_API/Controllers/ConversationController.cs +++ b/backend/IM_API/Controllers/ConversationController.cs @@ -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; diff --git a/backend/IM_API/Controllers/FriendController.cs b/backend/IM_API/Controllers/FriendController.cs index e077d54..ea8c53f 100644 --- a/backend/IM_API/Controllers/FriendController.cs +++ b/backend/IM_API/Controllers/FriendController.cs @@ -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 /// [HttpPost] public async Task HandleRequest( - [FromRoute]int id, [FromBody]FriendRequestHandleDto dto + [FromQuery]int id, [FromBody]FriendRequestHandleDto dto ) { await _friendService.HandleFriendRequestAsync(new HandleFriendRequestDto() diff --git a/backend/IM_API/Controllers/UserController.cs b/backend/IM_API/Controllers/UserController.cs index 074a9ca..6b8587e 100644 --- a/backend/IM_API/Controllers/UserController.cs +++ b/backend/IM_API/Controllers/UserController.cs @@ -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; diff --git a/backend/IM_API/Domain/Events/FriendAddEvent.cs b/backend/IM_API/Domain/Events/FriendAddEvent.cs index 2ed471a..d2e6378 100644 --- a/backend/IM_API/Domain/Events/FriendAddEvent.cs +++ b/backend/IM_API/Domain/Events/FriendAddEvent.cs @@ -1,4 +1,4 @@ -using IM_API.Dtos; +using IM_API.Dtos.Friend; namespace IM_API.Domain.Events { diff --git a/backend/IM_API/Domain/Events/GroupInviteEvent.cs b/backend/IM_API/Domain/Events/GroupInviteEvent.cs new file mode 100644 index 0000000..b4bc47c --- /dev/null +++ b/backend/IM_API/Domain/Events/GroupInviteEvent.cs @@ -0,0 +1,10 @@ +namespace IM_API.Domain.Events +{ + public record GroupInviteEvent : DomainEvent + { + public override string EventType => "IM.GROUPS_GROUP_INVITE"; + public required List Ids { get; init; } + public int GroupId { get; init; } + public int UserId { get; init; } + } +} diff --git a/backend/IM_API/Domain/Events/GroupRequestEvent.cs b/backend/IM_API/Domain/Events/GroupRequestEvent.cs new file mode 100644 index 0000000..8c65739 --- /dev/null +++ b/backend/IM_API/Domain/Events/GroupRequestEvent.cs @@ -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; } + + } +} diff --git a/backend/IM_API/Dtos/AuthDto.cs b/backend/IM_API/Dtos/Auth/AuthDto.cs similarity index 64% rename from backend/IM_API/Dtos/AuthDto.cs rename to backend/IM_API/Dtos/Auth/AuthDto.cs index 73f6d74..27b95a7 100644 --- a/backend/IM_API/Dtos/AuthDto.cs +++ b/backend/IM_API/Dtos/Auth/AuthDto.cs @@ -1,4 +1,4 @@ -namespace IM_API.Dtos +namespace IM_API.Dtos.Auth { public record RefreshDto(string refreshToken); } diff --git a/backend/IM_API/Dtos/LoginDto.cs b/backend/IM_API/Dtos/Auth/LoginDto.cs similarity index 70% rename from backend/IM_API/Dtos/LoginDto.cs rename to backend/IM_API/Dtos/Auth/LoginDto.cs index bf29b7d..ce9f9dd 100644 --- a/backend/IM_API/Dtos/LoginDto.cs +++ b/backend/IM_API/Dtos/Auth/LoginDto.cs @@ -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; } } } diff --git a/backend/IM_API/Dtos/LoginRequestDto.cs b/backend/IM_API/Dtos/Auth/LoginRequestDto.cs similarity index 95% rename from backend/IM_API/Dtos/LoginRequestDto.cs rename to backend/IM_API/Dtos/Auth/LoginRequestDto.cs index 16cd470..f4d7e0f 100644 --- a/backend/IM_API/Dtos/LoginRequestDto.cs +++ b/backend/IM_API/Dtos/Auth/LoginRequestDto.cs @@ -1,7 +1,7 @@ using IM_API.Tools; using System.ComponentModel.DataAnnotations; -namespace IM_API.Dtos +namespace IM_API.Dtos.Auth { public class LoginRequestDto { diff --git a/backend/IM_API/Dtos/RegisterRequestDto.cs b/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs similarity index 96% rename from backend/IM_API/Dtos/RegisterRequestDto.cs rename to backend/IM_API/Dtos/Auth/RegisterRequestDto.cs index 83aaea4..c32dd87 100644 --- a/backend/IM_API/Dtos/RegisterRequestDto.cs +++ b/backend/IM_API/Dtos/Auth/RegisterRequestDto.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace IM_API.Dtos +namespace IM_API.Dtos.Auth { public class RegisterRequestDto { diff --git a/backend/IM_API/Dtos/ClearConversationsDto.cs b/backend/IM_API/Dtos/Conversation/ClearConversationsDto.cs similarity index 93% rename from backend/IM_API/Dtos/ClearConversationsDto.cs rename to backend/IM_API/Dtos/Conversation/ClearConversationsDto.cs index 34cb3df..fe1067d 100644 --- a/backend/IM_API/Dtos/ClearConversationsDto.cs +++ b/backend/IM_API/Dtos/Conversation/ClearConversationsDto.cs @@ -1,4 +1,4 @@ -namespace IM_API.Dtos +namespace IM_API.Dtos.Conversation { public class ClearConversationsDto { diff --git a/backend/IM_API/Dtos/ConversationDto.cs b/backend/IM_API/Dtos/Conversation/ConversationDto.cs similarity index 97% rename from backend/IM_API/Dtos/ConversationDto.cs rename to backend/IM_API/Dtos/Conversation/ConversationDto.cs index 585bde6..0efcf36 100644 --- a/backend/IM_API/Dtos/ConversationDto.cs +++ b/backend/IM_API/Dtos/Conversation/ConversationDto.cs @@ -1,6 +1,6 @@ using IM_API.Models; -namespace IM_API.Dtos +namespace IM_API.Dtos.Conversation { public class ConversationDto { diff --git a/backend/IM_API/Dtos/FriendDto.cs b/backend/IM_API/Dtos/Friend/FriendDto.cs similarity index 90% rename from backend/IM_API/Dtos/FriendDto.cs rename to backend/IM_API/Dtos/Friend/FriendDto.cs index 55ed3c7..8f2ecb5 100644 --- a/backend/IM_API/Dtos/FriendDto.cs +++ b/backend/IM_API/Dtos/Friend/FriendDto.cs @@ -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 { diff --git a/backend/IM_API/Dtos/FriendRequestDto.cs b/backend/IM_API/Dtos/Friend/FriendRequestDto.cs similarity index 94% rename from backend/IM_API/Dtos/FriendRequestDto.cs rename to backend/IM_API/Dtos/Friend/FriendRequestDto.cs index 106117b..fdef132 100644 --- a/backend/IM_API/Dtos/FriendRequestDto.cs +++ b/backend/IM_API/Dtos/Friend/FriendRequestDto.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace IM_API.Dtos +namespace IM_API.Dtos.Friend { public class FriendRequestDto { diff --git a/backend/IM_API/Dtos/FriendRequestResDto.cs b/backend/IM_API/Dtos/Friend/FriendRequestResDto.cs similarity index 96% rename from backend/IM_API/Dtos/FriendRequestResDto.cs rename to backend/IM_API/Dtos/Friend/FriendRequestResDto.cs index 1fbf76d..45e94dd 100644 --- a/backend/IM_API/Dtos/FriendRequestResDto.cs +++ b/backend/IM_API/Dtos/Friend/FriendRequestResDto.cs @@ -1,6 +1,6 @@ using IM_API.Models; -namespace IM_API.Dtos +namespace IM_API.Dtos.Friend { public class FriendRequestResDto { diff --git a/backend/IM_API/Dtos/HandleFriendRequestDto.cs b/backend/IM_API/Dtos/Friend/HandleFriendRequestDto.cs similarity index 95% rename from backend/IM_API/Dtos/HandleFriendRequestDto.cs rename to backend/IM_API/Dtos/Friend/HandleFriendRequestDto.cs index 3b90c04..afd2d00 100644 --- a/backend/IM_API/Dtos/HandleFriendRequestDto.cs +++ b/backend/IM_API/Dtos/Friend/HandleFriendRequestDto.cs @@ -1,4 +1,4 @@ -namespace IM_API.Dtos +namespace IM_API.Dtos.Friend { public class HandleFriendRequestDto { diff --git a/backend/IM_API/Dtos/Group/GroupCreateDto.cs b/backend/IM_API/Dtos/Group/GroupCreateDto.cs new file mode 100644 index 0000000..208371c --- /dev/null +++ b/backend/IM_API/Dtos/Group/GroupCreateDto.cs @@ -0,0 +1,17 @@ +using IM_API.Models; + +namespace IM_API.Dtos.Group +{ + public class GroupCreateDto + { + /// + /// 群聊名称 + /// + public string Name { get; set; } = null!; + + /// + /// 群头像 + /// + public string Avatar { get; set; } = null!; + } +} diff --git a/backend/IM_API/Dtos/Group/GroupInfoDto.cs b/backend/IM_API/Dtos/Group/GroupInfoDto.cs new file mode 100644 index 0000000..c9d8d9c --- /dev/null +++ b/backend/IM_API/Dtos/Group/GroupInfoDto.cs @@ -0,0 +1,51 @@ +using IM_API.Models; + +namespace IM_API.Dtos.Group +{ + public class GroupInfoDto + { + public int Id { get; set; } + + /// + /// 群聊名称 + /// + public string Name { get; set; } = null!; + + /// + /// 群主 + /// + public int GroupMaster { get; set; } + + /// + /// 群权限 + /// (0:需管理员同意,1:任意人可加群,2:不允许任何人加入) + /// + public GroupAuhority Auhority { get; set; } + + /// + /// 全员禁言(0允许发言,2全员禁言) + /// + public GroupAllMembersBanned AllMembersBanned { get; set; } + + /// + /// 群聊状态 + /// (1:正常,2:封禁) + /// + public GroupStatus Status { get; set; } + + /// + /// 群公告 + /// + public string? Announcement { get; set; } + + /// + /// 群聊创建时间 + /// + public DateTime Created { get; set; } + + /// + /// 群头像 + /// + public string Avatar { get; set; } = null!; + } +} diff --git a/backend/IM_API/Dtos/UpdateUserDto.cs b/backend/IM_API/Dtos/User/UpdateUserDto.cs similarity index 90% rename from backend/IM_API/Dtos/UpdateUserDto.cs rename to backend/IM_API/Dtos/User/UpdateUserDto.cs index e7949e7..4ac40f2 100644 --- a/backend/IM_API/Dtos/UpdateUserDto.cs +++ b/backend/IM_API/Dtos/User/UpdateUserDto.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace IM_API.Dtos +namespace IM_API.Dtos.User { public class UpdateUserDto { diff --git a/backend/IM_API/Dtos/UserDto.cs b/backend/IM_API/Dtos/User/UserDto.cs similarity index 95% rename from backend/IM_API/Dtos/UserDto.cs rename to backend/IM_API/Dtos/User/UserDto.cs index 655d1a1..d8a1a57 100644 --- a/backend/IM_API/Dtos/UserDto.cs +++ b/backend/IM_API/Dtos/User/UserDto.cs @@ -1,7 +1,7 @@ using IM_API.Models; using System.ComponentModel.DataAnnotations; -namespace IM_API.Dtos +namespace IM_API.Dtos.User { public record PasswordResetDto { diff --git a/backend/IM_API/Dtos/UserInfoDto.cs b/backend/IM_API/Dtos/User/UserInfoDto.cs similarity index 97% rename from backend/IM_API/Dtos/UserInfoDto.cs rename to backend/IM_API/Dtos/User/UserInfoDto.cs index c5deba6..f77bb24 100644 --- a/backend/IM_API/Dtos/UserInfoDto.cs +++ b/backend/IM_API/Dtos/User/UserInfoDto.cs @@ -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 { diff --git a/backend/IM_API/IM_API.csproj b/backend/IM_API/IM_API.csproj index 92d775a..b47084f 100644 --- a/backend/IM_API/IM_API.csproj +++ b/backend/IM_API/IM_API.csproj @@ -31,4 +31,8 @@ + + + + diff --git a/backend/IM_API/Interface/Services/IAuthService.cs b/backend/IM_API/Interface/Services/IAuthService.cs index 1c4ce71..be275d6 100644 --- a/backend/IM_API/Interface/Services/IAuthService.cs +++ b/backend/IM_API/Interface/Services/IAuthService.cs @@ -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 diff --git a/backend/IM_API/Interface/Services/IConversationService.cs b/backend/IM_API/Interface/Services/IConversationService.cs index 474bb16..dfc3642 100644 --- a/backend/IM_API/Interface/Services/IConversationService.cs +++ b/backend/IM_API/Interface/Services/IConversationService.cs @@ -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 /// /// Task ClearUnreadCountAsync(int userId, int conversationId); + /// + /// 为用户创建会话 + /// + /// + /// + /// + /// + Task MakeConversationAsync(int userAId, int userBId, ChatType chatType); } } diff --git a/backend/IM_API/Interface/Services/IFriendSerivce.cs b/backend/IM_API/Interface/Services/IFriendSerivce.cs index b4d96a8..b4e29d3 100644 --- a/backend/IM_API/Interface/Services/IFriendSerivce.cs +++ b/backend/IM_API/Interface/Services/IFriendSerivce.cs @@ -1,4 +1,4 @@ -using IM_API.Dtos; +using IM_API.Dtos.Friend; using IM_API.Models; namespace IM_API.Interface.Services diff --git a/backend/IM_API/Interface/Services/IGroupService.cs b/backend/IM_API/Interface/Services/IGroupService.cs new file mode 100644 index 0000000..b337df8 --- /dev/null +++ b/backend/IM_API/Interface/Services/IGroupService.cs @@ -0,0 +1,39 @@ +using IM_API.Dtos.Group; + +namespace IM_API.Interface.Services +{ + public interface IGroupService + { + /// + /// 邀请好友入群 + /// + /// 操作者ID + /// 群ID + /// 邀请的用户列表 + /// + Task InviteUsers(int userId,int groupId, List userIds); + /// + /// 加入群聊 + /// + /// 操作者ID + /// 群ID + /// + Task JoinGroup(int userId,int groupId); + /// + /// 创建群聊 + /// + /// 操作者ID + /// 群信息 + /// 邀请用户列表 + /// + Task CreateGroup(int userId, GroupCreateDto groupCreateDto, List userIds); + /// + /// 删除群 + /// + /// 操作者ID + /// 群ID + /// + Task DeleteGroup(int userId, int groupId); + //Task UpdateGroupAuthori + } +} diff --git a/backend/IM_API/Interface/Services/IUserService.cs b/backend/IM_API/Interface/Services/IUserService.cs index 698606f..147ae9a 100644 --- a/backend/IM_API/Interface/Services/IUserService.cs +++ b/backend/IM_API/Interface/Services/IUserService.cs @@ -1,4 +1,4 @@ -using IM_API.Dtos; +using IM_API.Dtos.User; using IM_API.Models; namespace IM_API.Interface.Services diff --git a/backend/IM_API/Models/Group.cs b/backend/IM_API/Models/Group.cs index 86522af..d58e0aa 100644 --- a/backend/IM_API/Models/Group.cs +++ b/backend/IM_API/Models/Group.cs @@ -53,5 +53,7 @@ public partial class Group public virtual User GroupMasterNavigation { get; set; } = null!; + public virtual ICollection GroupMembers { get; set; } = new List(); + public virtual ICollection GroupRequests { get; set; } = new List(); } diff --git a/backend/IM_API/Models/Groupmember.cs b/backend/IM_API/Models/Groupmember.cs index 849ea37..e28b91b 100644 --- a/backend/IM_API/Models/Groupmember.cs +++ b/backend/IM_API/Models/Groupmember.cs @@ -27,7 +27,7 @@ public partial class GroupMember /// 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!; } diff --git a/backend/IM_API/Models/ImContext.cs b/backend/IM_API/Models/ImContext.cs index a112714..aeae98b 100644 --- a/backend/IM_API/Models/ImContext.cs +++ b/backend/IM_API/Models/ImContext.cs @@ -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"); diff --git a/backend/IM_API/Models/User.cs b/backend/IM_API/Models/User.cs index c390560..0e91c99 100644 --- a/backend/IM_API/Models/User.cs +++ b/backend/IM_API/Models/User.cs @@ -73,9 +73,7 @@ public partial class User public virtual ICollection GroupInviteInvitedUserNavigations { get; set; } = new List(); - public virtual ICollection GroupMemberGroups { get; set; } = new List(); - - public virtual ICollection GroupMemberUsers { get; set; } = new List(); + public virtual ICollection GroupMembers { get; set; } = new List(); public virtual ICollection GroupRequests { get; set; } = new List(); diff --git a/backend/IM_API/Services/AuthService.cs b/backend/IM_API/Services/AuthService.cs index d4fd6b4..a387c36 100644 --- a/backend/IM_API/Services/AuthService.cs +++ b/backend/IM_API/Services/AuthService.cs @@ -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; diff --git a/backend/IM_API/Services/ConversationService.cs b/backend/IM_API/Services/ConversationService.cs index 9cfb3cc..9d93669 100644 --- a/backend/IM_API/Services/ConversationService.cs +++ b/backend/IM_API/Services/ConversationService.cs @@ -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(); + } } } \ No newline at end of file diff --git a/backend/IM_API/Services/FriendService.cs b/backend/IM_API/Services/FriendService.cs index 9511525..692294b 100644 --- a/backend/IM_API/Services/FriendService.cs +++ b/backend/IM_API/Services/FriendService.cs @@ -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(friendRequest), requestUserRemarkname = requestDto.RemarkName, + RequestUserId = friendRequest.RequestUser, + ResponseUserId = friendRequest.ResponseUser }); break; diff --git a/backend/IM_API/Services/GroupService.cs b/backend/IM_API/Services/GroupService.cs new file mode 100644 index 0000000..b05ed05 --- /dev/null +++ b/backend/IM_API/Services/GroupService.cs @@ -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 _logger; + private readonly IPublishEndpoint _endPoint; + public GroupService(ImContext context, IMapper mapper, ILogger logger, IPublishEndpoint publishEndpoint) + { + _context = context; + _mapper = mapper; + _logger = logger; + _endPoint = publishEndpoint; + } + + private async Task> GetGroupInvites(int userId, int groupId, List 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 CreateGroup(int userId, GroupCreateDto groupCreateDto, List userIds) + { + using var transaction = await _context.Database.BeginTransactionAsync(); + try + { + //先创建群 + DateTime dateTime = DateTime.UtcNow; + Group group = _mapper.Map(groupCreateDto); + group.GroupMaster = userId; + _context.Groups.Add(group); + await _context.SaveChangesAsync(); + var groupInvites = new List(); + 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(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 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(); + } + } +} diff --git a/backend/IM_API/Services/UserService.cs b/backend/IM_API/Services/UserService.cs index 0608268..dc1e797 100644 --- a/backend/IM_API/Services/UserService.cs +++ b/backend/IM_API/Services/UserService.cs @@ -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; diff --git a/frontend/web/.env b/frontend/web/.env index 4651767..d3d8fa0 100644 --- a/frontend/web/.env +++ b/frontend/web/.env @@ -1,4 +1,4 @@ -VITE_API_BASE_URL = http://localhost:5202/api -VITE_SIGNALR_BASE_URL = http://localhost:5202/chat/ -#VITE_API_BASE_URL = https://im.test.nxsir.cn/api -#VITE_SIGNALR_BASE_URL = https://im.test.nxsir.cn/chat/ \ No newline at end of file +#VITE_API_BASE_URL = http://localhost:5202/api +#VITE_SIGNALR_BASE_URL = http://localhost:5202/chat/ +VITE_API_BASE_URL = https://im.test.nxsir.cn/api +VITE_SIGNALR_BASE_URL = https://im.test.nxsir.cn/chat/ \ No newline at end of file diff --git a/frontend/web/src/components/addMenu.vue b/frontend/web/src/components/addMenu.vue index c35642e..66a61b2 100644 --- a/frontend/web/src/components/addMenu.vue +++ b/frontend/web/src/components/addMenu.vue @@ -67,12 +67,12 @@ const vClickOutside = { \ No newline at end of file diff --git a/frontend/web/src/components/contacts/contactShow.vue b/frontend/web/src/components/contacts/contactShow.vue new file mode 100644 index 0000000..78b3790 --- /dev/null +++ b/frontend/web/src/components/contacts/contactShow.vue @@ -0,0 +1,82 @@ + + + + + \ No newline at end of file diff --git a/frontend/web/src/components/groups/CreateGroup.vue b/frontend/web/src/components/groups/CreateGroup.vue new file mode 100644 index 0000000..6a4dd93 --- /dev/null +++ b/frontend/web/src/components/groups/CreateGroup.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/frontend/web/src/components/groups/groupsShow.vue b/frontend/web/src/components/groups/groupsShow.vue new file mode 100644 index 0000000..7095cf4 --- /dev/null +++ b/frontend/web/src/components/groups/groupsShow.vue @@ -0,0 +1,81 @@ + + + + + \ No newline at end of file diff --git a/frontend/web/src/components/user/SearchUser.vue b/frontend/web/src/components/user/SearchUser.vue index 2312c39..4b72ac4 100644 --- a/frontend/web/src/components/user/SearchUser.vue +++ b/frontend/web/src/components/user/SearchUser.vue @@ -1,399 +1,175 @@ - - + + \ No newline at end of file diff --git a/frontend/web/src/constants/friendAction.js b/frontend/web/src/constants/friendAction.js new file mode 100644 index 0000000..7832eab --- /dev/null +++ b/frontend/web/src/constants/friendAction.js @@ -0,0 +1,17 @@ +export const FRIEND_ACTIONS = Object.freeze({ + /**接受 */ + Accept: 'Accept', + /**拒绝 */ + Reject: 'Reject' +}); + +export const FRIEND_REQUEST_STATUS = Object.freeze({ + /**待处理 */ + Pending: 'Pending', + /**通过 */ + Passed: 'Passed', + /**已拒绝 */ + Declined: 'Declined', + /**已拉黑 */ + Blocked: 'Blocked' +}) \ No newline at end of file diff --git a/frontend/web/src/constants/systemBaseStatus.js b/frontend/web/src/constants/systemBaseStatus.js new file mode 100644 index 0000000..7344a9d --- /dev/null +++ b/frontend/web/src/constants/systemBaseStatus.js @@ -0,0 +1,3 @@ +export const SYSTEM_BASE_STATUS = Object.freeze({ + SUCCESS: 0 +}); \ No newline at end of file diff --git a/frontend/web/src/services/friend.js b/frontend/web/src/services/friend.js index 90b8788..3eb7e67 100644 --- a/frontend/web/src/services/friend.js +++ b/frontend/web/src/services/friend.js @@ -1,4 +1,5 @@ import { request } from "./api"; +import { FRIEND_ACTIONS } from "@/constants/friendAction"; export const friendService = { @@ -28,5 +29,16 @@ export const friendService = { * @param {*} limit * @returns */ - getFriendRequests: (page = 1, limit = 100) => request.get(`/friend/requests?page=${page}&limit=${limit}`) + getFriendRequests: (page = 1, limit = 100) => request.get(`/friend/requests?page=${page}&limit=${limit}`), + + /** + * 处理好友请求 + * @param {*} friendRequestId + * @param {typeof FRIEND_ACTIONS[keyof typeof FRIEND_ACTIONS]} action + * @returns + */ + handleFriendRequest: (friendRequestId, action, remarkname) => request.post(`/Friend/HandleRequest?id=${friendRequestId}`, { + remarkName: remarkname, + action: action + }) } \ No newline at end of file diff --git a/frontend/web/src/utils/db/baseDb.js b/frontend/web/src/utils/db/baseDb.js index b28674a..493184c 100644 --- a/frontend/web/src/utils/db/baseDb.js +++ b/frontend/web/src/utils/db/baseDb.js @@ -5,7 +5,7 @@ const STORE_NAME = 'messages'; const CONVERSARION_STORE_NAME = 'conversations'; const CONTACT_STORE_NAME = 'contacts'; -export const dbPromise = openDB(DBNAME, 4, { +export const dbPromise = openDB(DBNAME, 5, { upgrade(db) { if (!db.objectStoreNames.contains(STORE_NAME)) { const store = db.createObjectStore(STORE_NAME, { keyPath: 'msgId' }); @@ -21,6 +21,7 @@ export const dbPromise = openDB(DBNAME, 4, { const store = db.createObjectStore(CONTACT_STORE_NAME, { keyPath: 'id' }); store.createIndex('by-id', 'id'); store.createIndex('by-username', 'username'); + store.createIndex('by-friendId', 'friendId', { unique: true }); } } }) \ No newline at end of file diff --git a/frontend/web/src/views/contact/ContactList.vue b/frontend/web/src/views/contact/ContactList.vue index 56adb59..13cb7ad 100644 --- a/frontend/web/src/views/contact/ContactList.vue +++ b/frontend/web/src/views/contact/ContactList.vue @@ -23,18 +23,13 @@
标签
- -
我的好友
-
- -
-
{{ c.remarkName }}
-
+
+ +
+ + +
@@ -54,14 +49,36 @@ import GroupChatModal from '@/components/groups/GroupChatModal.vue' import feather from 'feather-icons'; import { useContactStore } from '@/stores/contact'; import { useRouter } from 'vue-router'; +import contactShow from '@/components/contacts/contactShow.vue'; +import groupsShow from '@/components/groups/groupsShow.vue'; -const router = useRouter(); const searchQuery = ref('') -const activeContactId = ref(null) const contactStore = useContactStore(); const groupModal = ref(false); +const contactTab = ref(0); + +const myGroups = ref([ + { + id: 1, + name: "产品设计交流群", + avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=1", + lastMessage: "那个UI设计的初稿已经发在群文件了,大家记得看下。", + lastTime: "14:20", + unread: 3, + online: true + }, + { + id: 2, + name: "周五羽毛球小分队", + avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=2", + lastMessage: "这周五晚上 8 点,老地方见!", + lastTime: "昨天", + unread: 0, + online: false + } +]); const filteredContacts = computed(() => { @@ -82,10 +99,7 @@ const filteredContacts = computed(() => { }) }) -const routeUserInfo = (id) => { - router.push(`/contacts/info/${id}`); - activeContactId.value = id; -} + // 发送事件给父组件(用于切换回聊天Tab并打开会话) const emit = defineEmits(['start-chat']) @@ -95,6 +109,7 @@ const showGroupList = () => { } + onMounted(async () => { await contactStore.loadContactList(); }) @@ -145,11 +160,38 @@ onMounted(async () => { } .group-title { - padding: 8px 12px; + width: 40%; + padding: 5px 14px; font-size: 12px; - color: #999; + margin: 5px; + border: none; + background-color: #e0e0e0; + border-radius: 4px; } +.group-title:hover { + color: #8e8e8e; +} + +.group-title-active { + background-color: white; + color: rgb(78, 78, 249); +} + +.fixed-entries { + margin-bottom: 15px; + border-bottom: 1px solid #dcdcdc; +} + +.contactTab { + width: 90%; + margin: 10px auto; + background: #e0e0e0; + display: flex; + align-content: center; + justify-content: center; + border-radius: 4px; +} .list-item { display: flex; padding: 10px 12px; diff --git a/frontend/web/src/views/contact/FriendRequestList.vue b/frontend/web/src/views/contact/FriendRequestList.vue index 7915d83..560641a 100644 --- a/frontend/web/src/views/contact/FriendRequestList.vue +++ b/frontend/web/src/views/contact/FriendRequestList.vue @@ -17,20 +17,20 @@
- @@ -49,6 +59,8 @@ import { friendService } from '@/services/friend'; import { useMessage } from '@/components/messages/useAlert'; import { formatDate } from '@/utils/formatDate'; import { useAuthStore } from '@/stores/auth'; +import { FRIEND_ACTIONS, FRIEND_REQUEST_STATUS } from '@/constants/friendAction'; +import { SYSTEM_BASE_STATUS } from '@/constants/systemBaseStatus'; const message = useMessage(); const authStore = useAuthStore(); @@ -64,6 +76,50 @@ const loadFriendRequests = async () => { requests.value = res.data; } +const showDialog = ref(false); +const remarkName = ref(''); +const activeItem = ref(null); + +const handleOpenDialog = (item) => { + activeItem.value = item; + remarkName.value = item.nickName; // 默认备注为昵称 + showDialog.value = true; +}; + +const confirmAccept = async () => { + if (!activeItem.value) return; + await handleFriendRequest(FRIEND_ACTIONS.Accept) + activeItem.value.state = FRIEND_REQUEST_STATUS.Passed; + showDialog.value = false; +}; + +const confirmReject = async (item) => { + if(!item) return; + activeItem.value = item; + await handleFriendRequest(FRIEND_ACTIONS.Reject); + activeItem.value.state = FRIEND_REQUEST_STATUS.Declined; +} + +const handleFriendRequest = async (action) => { + const res = await friendService.handleFriendRequest(activeItem.value.id,action,activeItem.value.remarkName); + if(res.code == SYSTEM_BASE_STATUS.SUCCESS){ + switch(action){ + case FRIEND_ACTIONS.Accept: + message.show('添加好友成功'); + break; + case FRIEND_ACTIONS.Reject: + message.show('已拒绝'); + break; + default: + message.error('无效的操作'); + break; + } + }else{ + message.error(res.message); + console.log('好友请求处理异常:', res); + } +} + onMounted(async () => { await loadFriendRequests(); }) @@ -79,6 +135,7 @@ onMounted(async () => { display: flex; justify-content: center; overflow-y: auto; + position: relative; } .content-limit { @@ -197,4 +254,70 @@ onMounted(async () => { color: #d2d2d7; padding: 0 12px; } + +/* 弹窗遮罩:毛玻璃效果 */ +.modal-mask { + position: absolute; + inset: 0; + background: rgba(255, 255, 255, 0.4); + backdrop-filter: blur(10px); + display: flex; + align-items: center; + justify-content: center; + z-index: 999; +} + +/* 弹窗主体:延续你的极简白 */ +.modal-box { + background: #fff; + width: 280px; + padding: 24px; + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0,0,0,0.05); + text-align: center; +} + +.modal-header { + font-size: 16px; + font-weight: 600; + margin-bottom: 16px; +} + +/* 输入框:延续你的微灰色调 */ +.modal-input { + width: 100%; + padding: 10px; + border: none; + background: #f5f5f7; + border-radius: 8px; + margin-bottom: 20px; + outline: none; + box-sizing: border-box; +} + +.modal-footer { + display: flex; + gap: 12px; +} + +/* 按钮:完全复用你原本的 btn-text 逻辑 */ +.modal-btn-cancel { + flex: 1; + padding: 10px; + border: none; + background: #f5f5f7; + border-radius: 10px; + color: #86868b; + cursor: pointer; +} + +.modal-btn-confirm { + flex: 1; + padding: 10px; + border: none; + background: #007aff; + color: white; + border-radius: 10px; + cursor: pointer; +} \ No newline at end of file diff --git a/frontend/web/src/views/messages/MessageContent.vue b/frontend/web/src/views/messages/MessageContent.vue index 5bb6cdc..d1632a5 100644 --- a/frontend/web/src/views/messages/MessageContent.vue +++ b/frontend/web/src/views/messages/MessageContent.vue @@ -59,6 +59,7 @@ import { generateSessionId } from '@/utils/sessionIdTools'; import { useSignalRStore } from '@/stores/signalr'; import { useConversationStore } from '@/stores/conversation'; import feather from 'feather-icons'; +import { onBeforeRouteUpdate } from 'vue-router'; const props = defineProps({ id:{ @@ -142,13 +143,22 @@ async function loadConversation(conversationId) { conversationInfo.value = conversationStore.conversations.find(x => x.id == Number(conversationId)); } -// 初始化时滚动到底部 -onMounted(async () => { - await loadConversation(props.id); +const initChat = async (newId) => { + await loadConversation(newId); const sessionid = generateSessionId(conversationInfo.value.userId, conversationInfo.value.targetId) - await chatStore.swtichSession(sessionid,props.id); + await chatStore.swtichSession(sessionid,newId); scrollToBottom(); -}); +} + +// 监听路由参数 +watch( + () => props.id, + async (newId) => { + await initChat(newId) + }, + { immediate: true } // 组件第一次挂载(刷新页面进入)时会立即执行一次 +) + \ No newline at end of file